Skip to content
Snippets Groups Projects
Commit 855d22d4 authored by ml bonhomme's avatar ml bonhomme :bee: Committed by Erwan Rouchet
Browse files

Local worker run creation frontend

parent 7498f223
No related branches found
No related tags found
1 merge request!1584Local worker run creation frontend
......@@ -74,3 +74,9 @@ export const listUserWorkerRuns = unique(
async(params: PageNumberPaginationParameters): Promise<PageNumberPagination<WorkerRun>> =>
(await axios.get('/process/local/workers/', { params })).data
)
// Create a local worker run
export const createUserWorkerRun = unique(
async(versionId: UUID): Promise<WorkerRun> =>
(await axios.post('/process/local/workers/create/', { worker_version_id: versionId })).data
)
......@@ -45,6 +45,7 @@
<Row
:process-id="processId"
:selectable="selectable"
:local="local"
:key="version.id"
:version="version"
v-for="version in results"
......@@ -80,6 +81,14 @@ export default defineComponent({
type: Boolean,
default: false
},
/**
* If true, only worker versions that do not have a revision attached can be
* selected (for creating local worker runs).
*/
local: {
type: Boolean,
default: false
},
// Lists versions related to a specific worker
worker: {
type: Object as PropType<Worker>,
......
......@@ -38,10 +38,10 @@
<div class="has-text-centered">
<a
class="button is-success is-small"
:disabled="!isAvailable || null"
:disabled="!isSelectable || null"
v-on:click="addWorkerRun"
:class="{ 'is-loading': loading }"
:title="isAvailable ? 'Add this version to the process' : 'This version is not available'"
:title="selectTitle"
>
<i class="icon-plus"></i>
</a>
......@@ -71,6 +71,14 @@ export default {
type: Boolean,
default: false
},
/**
* If true, only worker versions that do not have a revision attached can be
* selected (for creating local worker runs).
*/
local: {
type: Boolean,
default: false
},
version: {
type: Object,
required: true
......@@ -85,8 +93,15 @@ export default {
}),
computed: {
...mapState('process', ['processWorkerRuns']),
isAvailable () {
return this.version.state === 'available'
isSelectable () {
return ((this.version.state === 'available' && !this.local) || (this.local && !this.version.revision))
},
selectTitle () {
if (this.local) {
if (this.isSelectable) return 'Select this worker version'
return 'Only worker versions without a revision attached can be selected'
} else if (this.isSelectable) return 'Add this version to the process'
return 'This version is not available'
}
},
methods: {
......@@ -96,7 +111,7 @@ export default {
return ago(new Date(date))
},
async addWorkerRun () {
if (!this.selectable || !this.isAvailable) return
if (!this.selectable || !this.isSelectable) return
this.$emit('selected-version', this.version)
if (this.loading || !this.processId) return
this.loading = true
......@@ -108,15 +123,12 @@ export default {
this.loading = false
}
},
refClass (type) {
return GIT_REF_COLORS[type]
},
stateClass (state) {
return REVISION_STATE_COLORS[state]
},
capitalize (value) {
if (!value) return ''
value = value.toString()
......
......@@ -23,7 +23,8 @@ import {
createWorker,
CreateWorkerVersionPayload,
createWorkerVersion,
listUserWorkerRuns
listUserWorkerRuns,
createUserWorkerRun
} from '@/api'
import { isAxiosError } from 'axios'
import { useNotificationStore } from './notification'
......@@ -191,6 +192,16 @@ export const useWorkerStore = defineStore('worker', {
...Object.fromEntries(resp.results.map(run => [run.id, run]))
}
return resp
},
async createUserWorkerRun (versionId: UUID) {
try {
const resp = await createUserWorkerRun(versionId)
this.workerRuns[resp.id] = resp
return resp
} catch (err) {
throw err
}
}
}
})
<template>
<main class="container is-fluid">
<button
type="button"
class="button is-info is-pulled-right mb-2"
v-on:click="workerVersionModal = true"
>
Create a worker run
</button>
<div class="title is-4">User worker runs</div>
<Paginator
......@@ -29,6 +37,30 @@
</tbody>
</table>
</Paginator>
<!-- Worker version selection modal -->
<Modal
v-model="workerVersionModal"
title="Select a worker version"
is-large
>
<div v-if="createdRunId" class="notification is-success">
Worker run successfully created with ID
<ItemId :item-id="createdRunId" />
</div>
<div v-else-if="existingRunId" class="notification is-info">
A local worker run with this worker version already exists with ID
<ItemId :item-id="existingRunId" />
</div>
<WorkerVersions
selectable
local
v-on:selected-version="workerRunCreate"
/>
<template v-slot:footer="{ close }">
<button class="button" v-on:click="close">Close</button>
</template>
</Modal>
</main>
</template>
......@@ -38,18 +70,27 @@ import { mapState, mapActions } from 'pinia'
import { useWorkerStore, useNotificationStore } from '@/stores'
import { errorParser } from '@/helpers'
import Paginator from '@/components/Paginator.vue'
import { PageNumberPagination, WorkerRun } from '@/types'
import { PageNumberPagination, UUID, WorkerRun } from '@/types'
import ItemId from '@/components/ItemId.vue'
import Modal from '@/components/Modal.vue'
import WorkerVersions from '@/views/Process/Workers/List.vue'
import { WorkerVersion } from '@/types/worker'
import { isAxiosError } from 'axios'
export default defineComponent({
components: {
Paginator,
ItemId
ItemId,
Modal,
WorkerVersions
},
data: () => ({
loading: false,
page: 1,
workerRunsPage: {} as PageNumberPagination<WorkerRun>
workerRunsPage: null as PageNumberPagination<WorkerRun> | null,
workerVersionModal: false,
createdRunId: null as UUID | null,
existingRunId: null as UUID | null
}),
mounted () {
this.getWorkerRuns()
......@@ -58,7 +99,7 @@ export default defineComponent({
...mapState(useWorkerStore, ['workerRuns'])
},
methods: {
...mapActions(useWorkerStore, ['listUserWorkerRuns']),
...mapActions(useWorkerStore, ['listUserWorkerRuns', 'createUserWorkerRun']),
...mapActions(useNotificationStore, ['notify']),
async getWorkerRuns () {
this.loading = true
......@@ -69,6 +110,27 @@ export default defineComponent({
} finally {
this.loading = false
}
},
async workerRunCreate (version: WorkerVersion) {
this.loading = true
// Reset createdRunId and existingRunId
this.createdRunId = ''
this.existingRunId = ''
try {
const createdRun = await this.createUserWorkerRun(version.id)
this.createdRunId = createdRun.id
} catch (err) {
if (!isAxiosError(err)) throw err
if (err.response?.status === 400 && err.response.data) {
if (err.response.data.id) this.existingRunId = err.response.data.id[0]
else if (err.response.data.worker_version_id) {
err.response.data.worker_version_id.forEach((message: string) => this.notify({ type: 'error', text: message }))
}
} else this.notify({ type: 'error', text: errorParser(err) })
} finally {
this.loading = false
this.getWorkerRuns()
}
}
}
})
......
......@@ -77,6 +77,7 @@
:worker="selectedWorker"
:process-id="processId"
:selectable="selectable"
:local="local"
v-on:selected-version="$emit('selected-version', $event)"
/>
<template v-if="!processId && !selectable">
......@@ -131,6 +132,15 @@ export default {
type: Boolean,
default: false
},
/**
* To be passed down to the worker versions list component.
* If true, only worker versions that do not have a revision attached can be
* selected (for creating local worker runs).
*/
local: {
type: Boolean,
default: false
},
/**
* If a process ID is defined, this component will automatically
* add the selected version to the process.
......
......@@ -514,5 +514,41 @@ describe('workers', () => {
})
})
})
describe('createUserWorkerRun', () => {
it('creates a local worker run', async () => {
store.workerRuns = {
workerRun1: workerRunsSample[0]
}
const response = {
id: 'local-worker-run-id',
parents: [],
worker_version: {
id: 'some-version-id'
},
process: {
name: 'My local process',
id: 'user-local-process-id'
},
configuration: null,
model_version: null,
summary: 'Worker version @ sea'
}
mock.onPost('/process/local/workers/create/', { worker_version_id: 'some-version-id' }).reply(201, response)
await store.createUserWorkerRun('some-version-id')
assert.deepStrictEqual(mock.history.all.map(req => pick(req, ['method', 'url'])), [
{
method: 'post',
url: '/process/local/workers/create/'
}
])
assert.deepStrictEqual(store.workerRuns, {
workerRun1: workerRunsSample[0],
'local-worker-run-id': response
})
})
})
})
})
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment