Skip to content

Commit

Permalink
feat(frontend): redesign common Job creation form
Browse files Browse the repository at this point in the history
This commit makes the following changes to the Job creation form in the frontend:

- Jobs can now be created through the all-jobs page and the experiment -> job page.
- Entrypoint dropdown will be greyed out until experiment is selected, and will only show
  entrypoints that are linked to the selected experiment
- Queue dropdown will be greyed out until entrypoint is selected, and will only show queues that
  are linked to the selected entrypoint
- A message with link that opens a dialog box to update experiment/entrypoint associations is added
  under the Entrypoint dropdown
- A message with link that opens a dialog box to update entrypoint/queue associations is added under
  the Queue dropdown
- Returning to an unsaved form should give you the option to load previous values
  • Loading branch information
henrychoy authored and keithmanville committed Dec 23, 2024
1 parent d017c4f commit c404551
Show file tree
Hide file tree
Showing 5 changed files with 499 additions and 54 deletions.
125 changes: 125 additions & 0 deletions src/frontend/src/dialogs/AppendResource.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<template>
<DialogComponent
v-model="showDialog"
@emitSubmit="submit"
:hideDraftBtn="true"
>
<template #title>
<label id="modalTitle">
Assign {{ childResourceType }} for '{{ parentResourceObj.name }}'
</label>
</template>
<q-select
outlined
dense
v-model="childResourceObjs"
use-input
use-chips
multiple
option-label="name"
option-value="id"
input-debounce="100"
:options="childResourceOptions"
@filter="getChildResources"
>
<template v-slot:before>
<div class="field-label text-capitalize">{{ childResourceType }}:</div>
</template>
<template v-slot:selected>
<div>
<div
v-for="(resource, i) in childResourceObjs"
:key="resource.id"
:class="i > 0 ? 'q-mt-xs' : ''"
>
<q-chip
removable
color="secondary"
text-color="white"
class="q-ml-xs "
@remove="childResourceObjs.splice(i, 1)"
>
{{ resource.name }}
</q-chip>
</div>
</div>
</template>
</q-select>
</DialogComponent>
</template>

<script setup>
import { ref, watch, computed } from 'vue'
import DialogComponent from './DialogComponent.vue'
import * as api from '@/services/dataApi'
import * as notify from '../notify'
const props = defineProps(['parentResourceType', 'parentResourceObj', 'childResourceType' ])
const emit = defineEmits(['submit'])
const showDialog = defineModel()
const childResourceObjs = ref([])
const selectedChildIds = computed(() => {
return childResourceObjs.value.map((obj) => obj.id)
})
const childResourceOptions = ref([])
const originalChildIds = ref()
watch(showDialog, (newVal) => {
if(newVal) {
console.log('props = ', props.parentResourceObj)
childResourceObjs.value = JSON.parse(JSON.stringify(props.parentResourceObj[props.childResourceType]))
originalChildIds.value = JSON.parse(JSON.stringify(props.parentResourceObj[props.childResourceType].map((obj) => obj.id)))
}
})
async function submit() {
let childIdsToAdd = []
let childIdsToRemove = []
selectedChildIds.value.forEach((id) => {
if (!originalChildIds.value.includes(id)) {
childIdsToAdd.push(id)
}
})
originalChildIds.value.forEach((id) => {
if (!selectedChildIds.value.includes(id)) {
childIdsToRemove.push(id)
}
})
try {
if(childIdsToAdd.length > 0) {
await api.appendResource(props.parentResourceType, props.parentResourceObj.id, props.childResourceType, childIdsToAdd)
}
for(const id of childIdsToRemove) {
await api.removeResourceFromResource(props.parentResourceType, props.parentResourceObj.id, props.childResourceType, id)
}
notify.success(`Successfully updated ${props.childResourceType} for '${props.parentResourceObj.name}'`)
showDialog.value = false
emit('submit')
} catch (err) {
notify.error(err.message)
}
}
async function getChildResources(val = '', update) {
update(async () => {
try {
const res = await api.getData(props.childResourceType, {
search: val,
rowsPerPage: 0, // get all
index: 0
})
childResourceOptions.value = res.data.data.filter((ep) => !selectedChildIds.value.includes(ep.id))
} catch(err) {
notify.error(err.response.data.message)
}
})
}
</script>
4 changes: 4 additions & 0 deletions src/frontend/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ const router = createRouter({
path: '/experiments/:id/jobs/:jobId',
component: () => import('../views/CreateJob.vue')
},
{
path: '/jobs/new',
component: () => import('../views/CreateJob.vue')
},
{
path: '/experiments/:id',
component: () => import('../views/CreateExperiment.vue')
Expand Down
8 changes: 8 additions & 0 deletions src/frontend/src/services/dataApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,14 @@ export async function removePluginFromEntrypoint(entrypointId: string, pluginId:
return await axios.delete(`/api/entrypoints/${entrypointId}/plugins/${pluginId}`)
}

export async function appendResource<T extends ItemType>(parentResourceType: T, parentResourceId: number, childResourceType: T, ids: number[]) {
return await axios.post(`/api/${parentResourceType}/${parentResourceId}/${childResourceType}`, {ids})
}

export async function removeResourceFromResource<T extends ItemType>(parentResourceType: T, parentResourceId: number, childResourceType: T, id: number) {
return await axios.delete(`/api/${parentResourceType}/${parentResourceId}/${childResourceType}/${id}`)
}

export async function getVersions(id: string,) {
return await axios.get(`/api/models/${id}/versions`)
}
Expand Down
6 changes: 5 additions & 1 deletion src/frontend/src/views/AllJobsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
ref="tableRef"
:hideEditBtn="true"
@editTags="(row) => { editObjTags = row; showTagsDialog = true }"
:hideCreateBtn="true"
@create="router.push('/jobs/new')"
>
<template #body-cell-experiment="props">
{{ props.row.experiment.name }}
</template>
<template #body-cell-entrypoint="props">
{{ props.row.entrypoint.name }}
</template>
Expand Down Expand Up @@ -61,6 +64,7 @@
const columns = [
{ name: 'description', label: 'Description', align: 'left', field: 'description', sortable: true, },
{ name: 'id', label: 'Job ID', align: 'left', field: 'id', sortable: false, },
{ name: 'experiment', label: 'Experiment', align: 'left', field: 'experiment', sortable: false, },
{ name: 'entrypoint', label: 'Entrypoint', align: 'left', field: 'entrypoint', sortable: false, },
{ name: 'queue', label: 'Queue', align: 'left', field: 'queue', sortable: false, },
{ name: 'status', label: 'Status', align: 'left', field: 'status', sortable: true },
Expand Down
Loading

0 comments on commit c404551

Please sign in to comment.