Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion client/platform/web-girder/views/Jobs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,33 @@ export default {

<template>
<v-container>
<JobList />
<JobList>
<template #jobwidget="{ item }">
<span>{{ item.statusText.replace('Inactive', 'Queued') }}</span>
<v-btn
x-small
:href="`http://localhost:8010/girder/#job/${item._id}`"
color="info"
outlined
class="mx-2"
>
Manage
</v-btn>
</template>
</JobList>
<v-card class="mt-4">
<v-card-title class="text-h6">
Job Runner Info
</v-card-title>
<v-card-text>
<p>
The job runner is shared between all users of this system and has
limited GPU capacity. Jobs in queue will be processed in the order in
which they are received. You can run your own server and job runner with Docker
using the instructions provided
<a href="https://github.com/VIAME/VIAME-Web/tree/master/docker">here</a>.
</p>
</v-card-text>
</v-card>
</v-container>
</template>
261 changes: 167 additions & 94 deletions client/viame-web-common/components/RunPipelineMenu.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import {
defineComponent, computed, PropType, ref, onBeforeMount,
defineComponent, computed, PropType, ref, onBeforeMount, reactive,
} from '@vue/composition-api';
import { Pipelines, Pipe, useApi } from 'viame-web-common/apispec';

Expand All @@ -16,9 +16,16 @@ export default defineComponent({
},
},

setup(props, { root }) {
setup(props) {
const { runPipeline, getPipelineList } = useApi();
const unsortedPipelines = ref({} as Pipelines);

const pipelineState = reactive({
selectedPipe: null as Pipe | null,
status: null as 'starting' | 'done' | 'error' | null,
error: null as null | unknown,
});

onBeforeMount(async () => {
unsortedPipelines.value = await getPipelineList();
});
Expand Down Expand Up @@ -50,21 +57,18 @@ export default defineComponent({
if (props.selectedDatasetIds.length === 0) {
throw new Error('No selected datasets to run on');
}

await Promise.all(
props.selectedDatasetIds.map((id) => runPipeline(id, pipeline)),
);
root.$snackbar({
text: `Started pipeline on ${props.selectedDatasetIds.length} clip${
props.selectedDatasetIds.length ? 's' : ''
}`,
timeout: 6000,
immediate: true,
button: 'View',
callback: () => {
root.$router.push({ name: 'jobs' });
},
});
pipelineState.status = 'starting';
pipelineState.selectedPipe = pipeline;
try {
await Promise.all(
props.selectedDatasetIds.map((id) => runPipeline(id, pipeline)),
);
pipelineState.status = 'done';
} catch (err) {
pipelineState.status = 'error';
pipelineState.error = err.response?.data?.message || err;
throw err;
}
}

function pipeTypeDisplay(pipeType: string) {
Expand All @@ -78,8 +82,16 @@ export default defineComponent({
}
}

function dismissLaunchDialog() {
pipelineState.selectedPipe = null;
pipelineState.status = null;
pipelineState.error = null;
}

return {
dismissLaunchDialog,
pipelines,
pipelineState,
pipelinesNotRunnable,
pipeTypeDisplay,
runPipelineOnSelectedItem,
Expand All @@ -89,90 +101,151 @@ export default defineComponent({
</script>

<template>
<v-menu
max-width="320"
offset-y
>
<template v-slot:activator="{ on: menuOn }">
<v-tooltip bottom>
<template #activator="{ on: tooltipOn }">
<v-btn
text
:small="small"
:disabled="pipelinesNotRunnable"
v-on="{ ...tooltipOn, ...menuOn }"
>
<v-icon color="accent">
mdi-pipe
</v-icon>
<span
v-show="!$vuetify.breakpoint.mdAndDown"
class="pl-1"
<div>
<v-menu
max-width="320"
offset-y
>
<template v-slot:activator="{ on: menuOn }">
<v-tooltip bottom>
<template #activator="{ on: tooltipOn }">
<v-btn
text
:small="small"
:disabled="pipelinesNotRunnable"
v-on="{ ...tooltipOn, ...menuOn }"
>
Run pipeline
</span>
</v-btn>
</template>
<span>Run CV algorithm pipelines on this data</span>
</v-tooltip>
</template>
<v-icon color="accent">
mdi-pipe
</v-icon>
<span
v-show="!$vuetify.breakpoint.mdAndDown"
class="pl-1"
>
Run pipeline
</span>
</v-btn>
</template>
<span>Run CV algorithm pipelines on this data</span>
</v-tooltip>
</template>

<template>
<v-card v-if="pipelines">
<v-card-title>
VIAME Pipelines
</v-card-title>
<template>
<v-card v-if="pipelines">
<v-card-title>
VIAME Pipelines
</v-card-title>

<v-card-text class="pb-0">
Choose a pipeline type. Check the
<a
href="https://viame.github.io/VIAME-Web/Pipeline-Documentation/"
target="_blank"
>docs</a>
for more information about these options.
</v-card-text>
<v-row class="px-3">
<v-col
v-for="(pipeType) in Object.keys(pipelines)"
:key="pipeType"
cols="6"
>
<v-menu
<v-card-text class="pb-0">
Choose a pipeline type. Check the
<a
href="https://viame.github.io/VIAME-Web/Pipeline-Documentation/"
target="_blank"
>docs</a>
for more information about these options.
</v-card-text>
<v-row class="px-3">
<v-col
v-for="(pipeType) in Object.keys(pipelines)"
:key="pipeType"
offset-y
cols="6"
>
<template v-slot:activator="{ on }">
<v-btn
depressed
block
v-on="on"
>
{{ pipeTypeDisplay(pipeType) }}
<v-icon
left
color="accent"
class="ml-0"
<v-menu
:key="pipeType"
offset-x
right
>
<template v-slot:activator="{ on }">
<v-btn
depressed
block
v-on="on"
>
mdi-menu-down
</v-icon>
</v-btn>
</template>
{{ pipeTypeDisplay(pipeType) }}
<v-icon
left
color="accent"
class="ml-0"
>
mdi-menu-right
</v-icon>
</v-btn>
</template>

<v-list>
<v-list-item
v-for="(pipeline) in pipelines[pipeType].pipes"
:key="`${pipeline.name}-${pipeline.pipe}`"
@click="runPipelineOnSelectedItem(pipeline)"
<v-list
dense
style="overflow-y:auto; max-height:85vh"
>
<v-list-item-title>
{{ pipeline.name }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-col>
</v-row>
<v-list-item
v-for="(pipeline) in pipelines[pipeType].pipes"
:key="`${pipeline.name}-${pipeline.pipe}`"
@click="runPipelineOnSelectedItem(pipeline)"
>
<v-list-item-title class="font-weight-regular">
{{ pipeline.name }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-col>
</v-row>
</v-card>
</template>
</v-menu>
<v-dialog
:value="pipelineState.status !== null"
@input="dismissLaunchDialog"
max-width="400"
>
<v-card outlined>
<v-card-title>
Pipeline Launch
</v-card-title>
<v-card-text
class="d-flex justify-center"
>
<v-progress-circular
v-if="pipelineState.status === 'starting'"
indeterminate
size="60"
width="9"
color="primary"
/>
<v-alert
v-if="pipelineState.status === 'error'"
type="error"
>
{{ pipelineState.error }}
</v-alert>
<v-alert
v-if="pipelineState.status === 'done' && pipelineState.selectedPipe"
dense
type="success"
>
Started {{ pipelineState.selectedPipe.name }}
on {{ selectedDatasetIds.length }} dataset(s).
</v-alert>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn
:to="{ name: 'jobs' }"
depressed
>
View All Jobs
<v-icon class="pl-1">
mdi-format-list-checks
</v-icon>
</v-btn>
<v-btn
color="primary"
:disabled="!(pipelineState.status !== 'starting')"
@click="dismissLaunchDialog"
>
Done
</v-btn>
</v-card-actions>
</v-card>
</template>
</v-menu>
</v-dialog>
</div>
</template>
Loading