diff --git a/client/platform/web-girder/store/Jobs.ts b/client/platform/web-girder/store/Jobs.ts new file mode 100644 index 000000000..819765956 --- /dev/null +++ b/client/platform/web-girder/store/Jobs.ts @@ -0,0 +1,61 @@ +import { Store, Module } from 'vuex'; +import { GirderJob } from '@girder/components/src'; +import { all } from '@girder/components/src/components/Job/status'; +import Vue from 'vue'; + +import eventBus from 'platform/web-girder/eventBus'; +import girderRest from 'platform/web-girder/plugins/girder'; +import { RootState, JobState } from './types'; + + +const JobStatus = all(); +const NonRunningStates = [ + JobStatus.CANCELED.value, + JobStatus.ERROR.value, + JobStatus.SUCCESS.value, +]; + +const jobModule: Module = { + namespaced: true, + state: { + jobIds: {}, + datasetStatus: {}, + }, + getters: { + runningJobIds(state) { + return Object.values(state.jobIds).filter((v) => !NonRunningStates.includes(v)).length >= 1; + }, + datasetRunningState: (state) => (datasetId: string) => ( + datasetId in state.datasetStatus && !NonRunningStates.includes(state.datasetStatus[datasetId]) + ), + }, + mutations: { + setJobState(state, { jobId, value }: { jobId: string; value: number }) { + Vue.set(state.jobIds, jobId, value); + }, + setDatasetStatus(state, { datasetId, value }: { datasetId: string; value: number }) { + Vue.set(state.datasetStatus, datasetId, value); + }, + }, +}; + +export async function init(store: Store) { + const { data: runningJobs } = await girderRest.get('/job', { + params: { statuses: `[${JobStatus.RUNNING.value}]` }, + }); + + function updateJob(job: GirderJob) { + store.commit('Jobs/setJobState', { jobId: job._id, value: job.status }); + if (typeof job.dataset_id === 'string') { + store.commit('Jobs/setDatasetStatus', { datasetId: job.dataset_id, value: job.status }); + } + } + + runningJobs.forEach(updateJob); + girderRest.$on('message:job_status', ({ data: job }: { data: GirderJob }) => { + updateJob(job); + eventBus.$emit('refresh-data-browser'); + }); +} + +export default jobModule; diff --git a/client/platform/web-girder/store/index.ts b/client/platform/web-girder/store/index.ts index 19ea1c1af..a4b4c56d2 100644 --- a/client/platform/web-girder/store/index.ts +++ b/client/platform/web-girder/store/index.ts @@ -6,6 +6,7 @@ import { RootState } from './types'; import Location from './Location'; import Dataset from './Dataset'; import Brand from './Brand'; +import Jobs, { init as JobsInit } from './Jobs'; Vue.use(Vuex); @@ -14,6 +15,7 @@ const store = new Vuex.Store({ Brand, Location, Dataset, + Jobs, }, }); @@ -25,4 +27,6 @@ router.beforeEach((to, from, next) => { next(); }); +JobsInit(store); + export default store; diff --git a/client/platform/web-girder/store/types.ts b/client/platform/web-girder/store/types.ts index 1632ecdd7..52b7bffef 100644 --- a/client/platform/web-girder/store/types.ts +++ b/client/platform/web-girder/store/types.ts @@ -26,6 +26,11 @@ export interface BrandState { brandData: BrandData; } +export interface JobState { + jobIds: Record; + datasetStatus: Record; +} + export interface RootState { Location: LocationState; Dataset: DatasetState; diff --git a/client/platform/web-girder/views/DataBrowser.vue b/client/platform/web-girder/views/DataBrowser.vue index 20991e238..8dff2f3dd 100644 --- a/client/platform/web-girder/views/DataBrowser.vue +++ b/client/platform/web-girder/views/DataBrowser.vue @@ -5,7 +5,6 @@ import { import { GirderFileManager, getLocationType, GirderModel, } from '@girder/components/src'; -import { useGirderRest } from 'platform/web-girder/plugins/girder'; import { itemsPerPageOptions } from 'dive-common/constants'; import { clientSettings } from 'dive-common/store/settings'; import { useStore, LocationType } from '../store/types'; @@ -25,7 +24,6 @@ export default defineComponent({ const uploaderDialog = ref(false); const locationStore = store.state.Location; const { getters } = store; - const girderRest = useGirderRest(); function setLocation(location: LocationType) { store.dispatch('Location/setRouteFromLocation', location); @@ -55,10 +53,8 @@ export default defineComponent({ )); eventBus.$on('refresh-data-browser', handleNotification); - girderRest.$on('message:job_status', handleNotification); onBeforeUnmount(() => { eventBus.$off('refresh-data-browser', handleNotification); - girderRest.$off('message:job_status', handleNotification); }); return { @@ -125,6 +121,13 @@ export default defineComponent({