Skip to content

Commit

Permalink
feat(frontend): add button to sync entrypoint to last plugin snapshot
Browse files Browse the repository at this point in the history
This commit adds an indicator in the UI when an entrypoint is associated with an out-of-date plugin
snapshot. It adds a button to allow the user to sync an entrypoint to the latest plugin snapshot.
  • Loading branch information
henrychoy authored and keithmanville committed Feb 14, 2025
1 parent 755cff1 commit 9b76911
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 97 deletions.
96 changes: 57 additions & 39 deletions src/frontend/src/dialogs/AssignPluginsDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,42 @@
<div class="field-label">Plugins:</div>
</template>
<template v-slot:selected>
<q-chip
v-for="(plugin, i) in selectedPlugins"
:key="plugin.id"
removable
color="secondary"
text-color="white"
class="q-my-none q-ml-xs q-mr-none"
@remove="selectedPlugins.splice(i, 1)"
>
{{ plugin.name }}
</q-chip>
<div>
<div
v-for="(plugin, i) in selectedPlugins"
:key="plugin.id"
:class="i > 0 ? 'q-mt-xs' : ''"
>
<q-chip
removable
color="secondary"
text-color="white"
class="q-ml-xs "
@remove="selectedPlugins.splice(i, 1)"
>
{{ plugin.name }}
<q-badge
v-if="!plugin.latestSnapshot"
color="red"
label="outdated"
rounded
class="q-ml-xs"
/>
</q-chip>
<q-btn
v-if="!plugin.latestSnapshot"
round
color="red"
icon="sync"
size="sm"
@click.stop="syncPlugin(plugin.id, i)"
>
<q-tooltip>
Sync to latest version of plugin
</q-tooltip>
</q-btn>
</div>
</div>
</template>
</q-select>
</DialogComponent>
Expand Down Expand Up @@ -70,7 +95,7 @@
})
async function submitPlugins() {
let pluginsToAdd = []
let pluginsToAdd = [...pluginsToUpdate.value]
let pluginsToRemove = []
selectedPluginIds.value.forEach((plugin) => {
Expand All @@ -86,39 +111,20 @@
})
try {
// Wait for all add and remove operations to finish
const addPromise = (pluginsToAdd.length > 0) ? addPlugins(pluginsToAdd) : Promise.resolve()
const removePromises = pluginsToRemove.map(plugin => removePlugin(plugin))
await Promise.all([addPromise, ...removePromises]);
// Log after both operations are complete
emit('refreshTable')
if(pluginsToAdd.length > 0) {
await api.addPluginsToEntrypoint(props.editObj.id, pluginsToAdd)
}
for(const plugin of pluginsToRemove) {
await api.removePluginFromEntrypoint(props.editObj.id, plugin)
}
notify.success(`Successfully updated plugins for '${props.editObj.name}'`)
showDialog.value = false
emit('refreshTable')
} catch (err) {
notify.error("Error in processing plugins: " + err.message);
}
}
async function addPlugins(pluginsToAdd) {
try {
await api.addPluginsToEntrypoint(props.editObj.id, pluginsToAdd)
} catch(err) {
console.log('err = ', err)
notify.error(err.response.data.message);
}
}
async function removePlugin(plugin) {
try {
await api.removePluginFromEntrypoint(props.editObj.id, plugin)
} catch(err) {
notify.error(err.response.data.message);
}
}
async function getPlugins(val = '', update) {
update(async () => {
try {
Expand All @@ -127,11 +133,23 @@
rowsPerPage: 0, // get all
index: 0
})
pluginOptions.value = res.data.data
pluginOptions.value = res.data.data.filter((plugin) => !selectedPluginIds.value.includes(plugin.id))
} catch(err) {
notify.error(err.response.data.message)
}
})
}
const pluginsToUpdate = ref([])
async function syncPlugin(pluginID, index) {
try {
const res = await api.getItem('plugins', pluginID)
selectedPlugins.value.splice(index, 1, res.data)
pluginsToUpdate.value.push(pluginID)
} catch(err) {
console.warn(err)
}
}
</script>
2 changes: 1 addition & 1 deletion src/frontend/src/services/dataApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export async function getData<T extends ItemType>(type: T, pagination: Paginatio
Object.assign(obj, obj.payload)
})
}
console.log('getData = ', res)
console.log('getData = ', res.data.data)
return res
}

Expand Down
9 changes: 0 additions & 9 deletions src/frontend/src/views/ArtifactsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,6 @@
<div>{{ props.row.group.name }}</div>
</template>
<template #expandedSlot="{ row }">
<!-- <BasicTable
:columns="fileColumns"
:rows="row?.versions || []"
:hideSearch="true"
:hideEditTable="true"
class="q-mx-md"
:title="`${row.name} Versions`"
/> -->
</template>
</TableComponent>

Expand All @@ -48,7 +40,6 @@

<script setup>
import TableComponent from '@/components/TableComponent.vue'
import BasicTable from '@/components/BasicTable.vue'
import ArtifactsDialog from '@/dialogs/ArtifactsDialog.vue'
import DeleteDialog from '@/dialogs/DeleteDialog.vue'
import { ref, watch } from 'vue'
Expand Down
88 changes: 70 additions & 18 deletions src/frontend/src/views/CreateEntryPoint.vue
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,16 @@
<template v-slot:before>
<div class="field-label">Queues:</div>
</template>
<template v-slot:selected-item="scope">
<q-chip
:label="scope.opt.name"
removable
@remove="scope.removeAtIndex(scope.index)"
:tabindex="scope.tabindex"
color="primary"
text-color="white"
/>
</template>
</q-select>

<q-select
Expand All @@ -189,6 +199,44 @@
<div class="field-label">Plugins:</div>
</template>
</q-select>
<div class="row" v-if="route.params.id !== 'new' && entryPoint.plugins.length > 0">
<label class="field-label q-pt-xs">Plugins:</label>
<div
class="col"
style="border: 1px solid lightgray; border-radius: 4px; padding: 5px 8px; margin-left: 6px;"
>
<div
v-for="(plugin, i) in entryPoint.plugins"
:key="i"
>
<q-chip
:label="plugin.name"
color="secondary"
text-color="white"
>
<q-badge
v-if="!plugin.latestSnapshot"
color="red"
label="outdated"
rounded
class="q-ml-xs"
/>
</q-chip>
<q-btn
v-if="!plugin.latestSnapshot"
round
color="red"
icon="sync"
size="sm"
@click="syncPlugin(plugin.id, i)"
>
<q-tooltip>
Sync to latest version of plugin
</q-tooltip>
</q-btn>
</div>
</div>
</div>
</div>

<TableComponent
Expand Down Expand Up @@ -334,26 +382,16 @@
watch(() => entryPoint.value.plugins, () => {
tasks.value = []
entryPoint.value.plugins.forEach(async(plugin) => {
let pluginID = typeof plugin === 'object' ? plugin.id : plugin
try {
const res = await api.getFiles(pluginID, {
search: '',
rowsPerPage: 0, // get all
index: 0
entryPoint.value.plugins.forEach((plugin) => {
if(typeof plugin === 'number') return
const pluginName = plugin.name
plugin.files.forEach((file) => {
file.tasks.forEach((task) => {
tasks.value.push({ ...task, pluginName: pluginName })
})
console.log('res = ', res)
res.data.data.forEach((file) => {
file.tasks.forEach((task) => {
task.pluginName = file.plugin.name
tasks.value.push(task)
})
})
} catch(err) {
console.warn(err)
}
})
})
})
}, { deep: true })
const parameter = reactive({
name: '',
Expand Down Expand Up @@ -504,6 +542,7 @@
parameters: entryPoint.value.parameters,
queues: entryPoint.value.queues,
})
await api.addPluginsToEntrypoint(route.params.id, pluginsToUpdate.value)
notify.success(`Successfully updated '${entryPoint.value.name}'`)
}
} catch(err) {
Expand Down Expand Up @@ -628,4 +667,17 @@
confirmLeave.value = true
router.push(toPath.value)
}
const pluginsToUpdate = ref([])
async function syncPlugin(pluginID, index) {
try {
const res = await api.getItem('plugins', pluginID)
console.log('res = ', res)
entryPoint.value.plugins.splice(index, 1, res.data)
pluginsToUpdate.value.push(pluginID)
} catch(err) {
console.warn(err)
}
}
</script>
63 changes: 40 additions & 23 deletions src/frontend/src/views/EntryPointsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,33 +29,43 @@
EMPTY
</span>
</template>
<template #body-cell-parameterNames="props">
<label v-for="(param, i) in props.row.parameters" :key="i">
{{ param.name }} <br>
</label>
</template>
<template #body-cell-parameterTypes="props">
<label v-for="(param, i) in props.row.parameters" :key="i">
{{ param.parameterType }} <br>
</label>
</template>
<template #body-cell-defaultValues="props">
<label v-for="(param, i) in props.row.parameters" :key="i">
{{ param.defaultValue }} <br>
</label>
</template>
<template #expandedSlot="{ row }">
<CodeEditor v-model="row.taskGraph" language="yaml" :readOnly="true" />
</template>
<template #body-cell-plugins="props">
<q-chip
<span
v-for="(plugin, i) in props.row.plugins"
:key="i"
color="secondary"
text-color="white"
>
{{ plugin.name }}
</q-chip>
<q-chip
color="secondary"
text-color="white"
clickable
@click.stop="editEntrypoint = props.row; showAssignPluginsDialog = true"
>
{{ plugin.name }}
<q-badge
v-if="!plugin.latestSnapshot"
color="red"
label="outdated"
rounded
class="q-ml-xs"
/>
</q-chip>
<q-btn
v-if="!plugin.latestSnapshot"
round
color="red"
icon="sync"
size="sm"
@click.stop="syncPlugin(props.row.id, plugin.id, plugin.name)"
class="q-mr-md"
>
<q-tooltip>
Sync to latest version of plugin
</q-tooltip>
</q-btn>
</span>
<q-btn
round
size="sm"
Expand Down Expand Up @@ -113,9 +123,6 @@
{ name: 'name', label: 'Name', align: 'left', field: 'name', sortable: true, },
{ name: 'description', label: 'Description', align: 'left', field: 'description', sortable: true, },
{ name: 'taskGraph', label: 'Task Graph', align: 'left', field: 'taskGraph',sortable: false, },
{ name: 'parameterNames', label: 'Parameter Name(s)', align: 'left', sortable: false },
{ name: 'parameterTypes', label: 'Parameter Type(s)', align: 'left', field: 'parameterTypes', sortable: false },
{ name: 'defaultValues', label: 'Default Values', align: 'left', field: 'defaultValues', sortable: false },
{ name: 'tags', label: 'Tags', align: 'left', field: 'tags', sortable: false },
{ name: 'plugins', label: 'Plugins', align: 'left', field: 'plugins', sortable: false },
]
Expand Down Expand Up @@ -159,4 +166,14 @@
const editObjTags = ref({})
const showTagsDialog = ref(false)
async function syncPlugin(entrypointId, pluginId, pluginName) {
try {
await api.addPluginsToEntrypoint(entrypointId, [pluginId])
tableRef.value.refreshTable()
notify.success(`Successfully updated plugin '${pluginName}' to latest version`)
} catch(err) {
console.warn(err)
}
}
</script>
Loading

0 comments on commit 9b76911

Please sign in to comment.