Skip to content

Commit ad075b6

Browse files
committed
[ui] View to add a new task
Adds a view at '/datajobs/new' to display a list of ways to schedule a task. The modal to add a single repository is moved from the task list to this view. Signed-off-by: Eva Millán <[email protected]>
1 parent 76bdd3b commit ad075b6

File tree

8 files changed

+179
-62
lines changed

8 files changed

+179
-62
lines changed

ui/src/assets/main.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ a {
1616
color: #1f2328;
1717
font-weight: 500;
1818
text-decoration: none;
19-
}
19+
}

ui/src/components/TaskList/FormDialog.vue renamed to ui/src/components/FormDialog.vue

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
<template>
22
<v-dialog v-model="isOpen" max-width="600">
33
<template #activator="{ props: activatorProps }">
4-
<v-btn
5-
class="ml-auto"
6-
color="secondary"
7-
prepend-icon="mdi-plus"
8-
text="Add"
9-
variant="flat"
10-
v-bind="activatorProps"
11-
></v-btn>
4+
<slot name="activator" v-bind="{ props: activatorProps }">
5+
<v-btn
6+
class="ml-auto"
7+
color="secondary"
8+
prepend-icon="mdi-plus"
9+
text="Add"
10+
variant="flat"
11+
v-bind="activatorProps"
12+
></v-btn>
13+
</slot>
1214
</template>
1315

1416
<v-card title="Schedule task">
@@ -47,29 +49,10 @@
4749
</v-col>
4850
</v-row>
4951
<v-row>
50-
<v-col cols="6">
51-
<v-radio-group
52-
v-model="formData.scheduler.job_interval"
53-
density="comfortable"
54-
size="small"
55-
>
56-
<template #label>
57-
<span class="text-subtitle-2">Interval</span>
58-
</template>
59-
<v-radio :value="86400" label="Every day"></v-radio>
60-
<v-radio :value="604800" label="Every week"></v-radio>
61-
<v-radio value="custom" label="Custom"></v-radio>
62-
</v-radio-group>
63-
<v-text-field
64-
v-model="customInterval"
65-
class="ml-8"
66-
label="Every"
67-
type="number"
68-
suffix="seconds"
69-
hide-details
70-
required
71-
>
72-
</v-text-field>
52+
<v-col>
53+
<p class="text-subtitle-2 mb-4">Schedule</p>
54+
<interval-selector v-model="formData.scheduler.job_interval" density="comfortable">
55+
</interval-selector>
7356
</v-col>
7457
</v-row>
7558
</v-card-text>
@@ -83,8 +66,11 @@
8366
</v-dialog>
8467
</template>
8568
<script>
69+
import IntervalSelector from './IntervalSelector.vue'
70+
8671
export default {
8772
name: 'FormDialog',
73+
components: { IntervalSelector },
8874
emits: ['create'],
8975
data() {
9076
return {
@@ -99,7 +85,7 @@ export default {
9985
}
10086
},
10187
scheduler: {
102-
job_interval: 604800,
88+
job_interval: '604800',
10389
job_max_retries: 1
10490
}
10591
},
@@ -108,9 +94,6 @@ export default {
10894
},
10995
methods: {
11096
onSave() {
111-
if (this.formData.scheduler.job_interval === 'custom') {
112-
this.formData.scheduler.job_interval = this.customInterval
113-
}
11497
this.$emit('create', this.formData)
11598
this.isOpen = false
11699
}

ui/src/components/TaskList/TaskList.vue

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@
55
<v-chip class="ml-2" density="comfortable">
66
{{ count }}
77
</v-chip>
8-
<form-dialog @create="$emit('create', $event)" />
8+
<v-btn
9+
:to="{ name: 'newTask' }"
10+
class="ml-auto"
11+
color="secondary"
12+
prepend-icon="mdi-plus"
13+
text="Add"
14+
variant="flat"
15+
></v-btn>
916
</h1>
1017

1118
<task-list-item
@@ -35,13 +42,12 @@
3542
</div>
3643
</template>
3744
<script>
38-
import FormDialog from './FormDialog.vue'
3945
import TaskListItem from './TaskListItem.vue'
4046
4147
export default {
4248
name: 'TaskList',
43-
components: { FormDialog, TaskListItem },
44-
emits: ['create', 'delete', 'reschedule', 'update:page'],
49+
components: { TaskListItem },
50+
emits: ['delete', 'reschedule', 'update:page'],
4551
props: {
4652
tasks: {
4753
type: Array,

ui/src/components/TaskList/TaskListItem.vue

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,33 @@
1111
<v-row>
1212
<v-col>
1313
<v-card-title class="text-subtitle-2 pb-0 d-flex align-center">
14-
{{ id }}
15-
<v-chip :color="status.toLowerCase()" class="ml-3" density="compact" size="small">
16-
{{ status }}
17-
</v-chip>
18-
</v-card-title>
19-
<v-card-subtitle class="font-weight-medium">
20-
<v-icon :aria-label="backend" role="img" aria-hidden="false" size="small">
21-
{{ 'mdi-' + backend }}
22-
</v-icon>
23-
{{ category }}
24-
<v-tooltip v-if="uri" :text="uri" location="bottom" open-delay="200">
25-
<template #activator="{ props }">
26-
<span v-bind="props"> from {{ uri }} </span>
27-
</template>
28-
</v-tooltip>
29-
</v-card-subtitle>
14+
{{ id }}
15+
<v-chip :color="status.toLowerCase()" class="ml-3" density="compact" size="small">
16+
{{ status }}
17+
</v-chip>
18+
</v-card-title>
19+
<v-card-subtitle class="font-weight-medium">
20+
<v-icon :aria-label="backend" role="img" aria-hidden="false" size="small">
21+
{{ 'mdi-' + backend }}
22+
</v-icon>
23+
{{ category }}
24+
<v-tooltip v-if="uri" :text="uri" location="bottom" open-delay="200">
25+
<template #activator="{ props }">
26+
<span v-bind="props"> from {{ uri }} </span>
27+
</template>
28+
</v-tooltip>
29+
</v-card-subtitle>
3030
</v-col>
3131
<v-col class="px-0 py-md-6">
32-
<div class="d-flex flex-wrap justify-end ">
32+
<div class="d-flex flex-wrap justify-end">
3333
<v-tooltip
3434
v-for="job in jobs"
3535
:key="job.uuid"
3636
:text="`#${job.job_num} ${job.status}`"
3737
:eager="false"
3838
location="bottom"
3939
>
40-
<template v-slot:activator="{ props }">
40+
<template #activator="{ props }">
4141
<v-icon v-bind="props" :color="job.status"> mdi-square </v-icon>
4242
</template>
4343
</v-tooltip>

ui/src/plugins/vuetify.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,6 @@ export default createVuetify({
4141
VAlert: {
4242
variant: 'tonal'
4343
},
44-
VBtn: {
45-
variant: 'outlined',
46-
size: 'small'
47-
},
4844
VCombobox: {
4945
variant: 'outlined',
5046
density: 'comfortable'

ui/src/router/index.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,34 @@ const router = createRouter({
2626
name: 'taskList',
2727
component: () => import('../views/Task/ListView.vue')
2828
},
29+
{
30+
path: 'new',
31+
name: 'newTaskList',
32+
meta: {
33+
breadcrumb: {
34+
title: 'New task',
35+
to: { name: 'newTask' }
36+
}
37+
},
38+
children: [
39+
{
40+
path: '',
41+
name: 'newTask',
42+
component: () => import('../views/Task/NewTask.vue')
43+
},
44+
{
45+
path: 'sbom',
46+
name: 'loadSbom',
47+
meta: {
48+
breadcrumb: {
49+
title: 'Load SBoM',
50+
to: { name: 'loadSbom' }
51+
}
52+
},
53+
component: () => import('../views/Task/LoadSbom.vue')
54+
}
55+
]
56+
},
2957
{
3058
path: ':id',
3159
name: 'task',
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import FormDialog from '@/components/FormDialog.vue'
2+
3+
export default {
4+
title: 'Components/FormDialog',
5+
component: FormDialog,
6+
tags: ['autodocs']
7+
}
8+
9+
export const Default = {}

ui/src/views/Task/NewTask.vue

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<template>
2+
<v-container>
3+
<h1 class="text-h6 my-4">New task</h1>
4+
5+
<form-dialog @create="createTask($event)">
6+
<template #activator="{ props: activatorProps }">
7+
<v-card
8+
v-bind="activatorProps"
9+
title="Add a repository"
10+
subtitle="Collect data from a single git repository"
11+
prepend-icon="mdi-git"
12+
variant="outlined"
13+
></v-card>
14+
</template>
15+
</form-dialog>
16+
17+
<v-card
18+
:to="{ name: 'loadSbom' }"
19+
title="Load SPDX SBoM file"
20+
subtitle="Load repositories from an SBoM file in SPDX format"
21+
prepend-icon="mdi-file-upload-outline"
22+
variant="outlined"
23+
></v-card>
24+
25+
<v-snackbar v-model="snackbar.open" :color="snackbar.color">
26+
{{ snackbar.text }}
27+
</v-snackbar>
28+
</v-container>
29+
</template>
30+
<script>
31+
import { API } from '@/services/api'
32+
import FormDialog from '@/components/FormDialog.vue'
33+
34+
export default {
35+
name: 'NewTask',
36+
components: { FormDialog },
37+
data() {
38+
return {
39+
snackbar: {
40+
open: false,
41+
color: 'success',
42+
text: ''
43+
}
44+
}
45+
},
46+
methods: {
47+
async createTask(formData) {
48+
try {
49+
const response = await API.scheduler.create(formData)
50+
Object.assign(this.snackbar, {
51+
open: true,
52+
color: 'success',
53+
text: response.data.message
54+
})
55+
this.$router.push({ name: 'taskList' })
56+
} catch (error) {
57+
Object.assign(this.snackbar, {
58+
open: true,
59+
color: 'error',
60+
text: error.response?.data?.message || error
61+
})
62+
}
63+
}
64+
}
65+
}
66+
</script>
67+
<style lang="scss" scoped>
68+
@media (min-width: 1280px) {
69+
.v-container {
70+
max-width: 900px;
71+
}
72+
}
73+
:deep(.v-card) {
74+
background: rgb(var(--v-theme-surface));
75+
border: thin solid rgba(0, 0, 0, 0.08);
76+
margin-bottom: 12px;
77+
78+
.v-card-title {
79+
font-size: 1rem;
80+
}
81+
82+
.v-card-item__prepend {
83+
margin-inline-end: 1rem;
84+
background: #fff8f2;
85+
padding: 8px;
86+
border-radius: 4px;
87+
border: thin solid currentColor;
88+
color: rgb(var(--v-theme-secondary), 0.08);
89+
90+
.v-icon {
91+
color: rgb(var(--v-theme-secondary));
92+
}
93+
}
94+
}
95+
</style>

0 commit comments

Comments
 (0)