@live-change/task-frontend 0.9.84 → 0.9.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/front/locales/en.js +4 -0
- package/front/src/components/Task.vue +12 -8
- package/front/src/components/TaskAdminCard.vue +85 -0
- package/front/src/components/TaskAdminDetails.vue +171 -0
- package/front/src/components/TaskRetry.vue +36 -0
- package/front/src/pages/TaskAdmin.vue +93 -0
- package/front/src/router.js +14 -0
- package/index.js +2 -1
- package/package.json +38 -38
package/front/locales/en.js
CHANGED
|
@@ -22,5 +22,9 @@ export const datetimeFormats = {
|
|
|
22
22
|
"long": {
|
|
23
23
|
"year": "numeric", "month": "short", "day": "numeric",
|
|
24
24
|
"weekday": "short", "hour": "numeric", "minute": "numeric"
|
|
25
|
+
},
|
|
26
|
+
"longWithSeconds": {
|
|
27
|
+
"year": "numeric", "month": "short", "day": "numeric",
|
|
28
|
+
"weekday": "short", "hour": "numeric", "minute": "numeric", "second": "numeric"
|
|
25
29
|
}
|
|
26
30
|
}
|
|
@@ -5,24 +5,23 @@
|
|
|
5
5
|
<i :class="['pi', icon, taskColor]" style="font-size: 1rem" />
|
|
6
6
|
<div :class="['ml-2']">{{ label }}</div>
|
|
7
7
|
</div>
|
|
8
|
-
<div v-if="
|
|
8
|
+
<div v-if="taskData?.progress && taskData?.state !== 'done'" class="w-32 mr-4 grow" style="max-width: 50vw">
|
|
9
9
|
<ProgressBar :value="Math.floor((100 * taskData.progress.current / taskData.progress.total))" />
|
|
10
10
|
</div>
|
|
11
|
-
<div v-if="
|
|
11
|
+
<div v-if="taskData?.retries?.length && taskData.retries.length < taskData.maxRetries" class="mr-4">
|
|
12
12
|
<i class="pi pi-replay" />
|
|
13
13
|
{{ taskData.retries.length }} / {{ taskData.maxRetries }}
|
|
14
14
|
</div>
|
|
15
|
-
<div>{{
|
|
15
|
+
<div>{{ taskData?.state !== 'done' ? (taskData?.progress?.action || taskData?.state) : 'done' }}</div>
|
|
16
16
|
</div>
|
|
17
|
-
<div v-for="retry in
|
|
17
|
+
<div v-for="retry in taskData?.retries" class="ml-6 flex flex-row justify-between text-red-800">
|
|
18
18
|
{{ retry.error }} at {{ d(retry.failedAt, 'shortestTime')}}
|
|
19
19
|
</div>
|
|
20
|
-
<!-- <pre>{{ taskData.progress }}</pre>-->
|
|
21
20
|
<div v-if="taskResultComponent && taskData.result" class="m-2">
|
|
22
|
-
<component :is="taskResultComponent" :task="
|
|
21
|
+
<component :is="taskResultComponent" :task="taskData" :result="taskData.result" :taskType="taskType" />
|
|
23
22
|
</div>
|
|
24
23
|
<div class="ml-6">
|
|
25
|
-
<Task v-for="task in childTasks" :key="
|
|
24
|
+
<Task v-for="task in childTasks" :key="taskId" :task="task" :tasks="allTasks" :taskTypes="taskTypes" />
|
|
26
25
|
</div>
|
|
27
26
|
</div>
|
|
28
27
|
</template>
|
|
@@ -70,7 +69,11 @@
|
|
|
70
69
|
|
|
71
70
|
const allTasks = computed(() => tasks.value || loadedTasks.value)
|
|
72
71
|
|
|
73
|
-
const taskData = computed(() =>
|
|
72
|
+
const taskData = computed(() =>
|
|
73
|
+
typeof task.value === 'object'
|
|
74
|
+
? task.value
|
|
75
|
+
: (allTasks.value && allTasks.value.find(m => (m.to ?? m.id) === taskId.value))
|
|
76
|
+
)
|
|
74
77
|
|
|
75
78
|
const taskType = computed(() => taskTypes.value[taskData.value?.type || taskData.value?.name] || {})
|
|
76
79
|
|
|
@@ -105,6 +108,7 @@
|
|
|
105
108
|
|
|
106
109
|
const taskColor = computed(() => {
|
|
107
110
|
console.log("TD", taskData.value, "AT", allTasks.value)
|
|
111
|
+
console.trace('taskColor', taskData.value)
|
|
108
112
|
switch(taskData.value?.state) {
|
|
109
113
|
case 'failed': return 'text-red-600'
|
|
110
114
|
default: {}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="bg-surface-0 dark:bg-surface-900 px-3 py-1 shadow">
|
|
3
|
+
<div class="flex flex-row justify-between items-center" v-if="taskData">
|
|
4
|
+
<div class="flex flex-row items-center">
|
|
5
|
+
<i :class="['pi', icon, taskColor]" style="font-size: 1rem" />
|
|
6
|
+
<div class="ml-2">{{ taskData.name }}</div>
|
|
7
|
+
<div v-if="taskData.state === 'failed'" class="ml-2 text-red-600 dark:text-red-400">
|
|
8
|
+
{{ taskData.retries[taskData.retries.length - 1]?.error }}
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="flex flex-row items-center gap-4">
|
|
12
|
+
<div v-if="taskData.retries?.length" >
|
|
13
|
+
<i class="pi pi-replay" />
|
|
14
|
+
{{ taskData.retries.length }} / {{ taskData.maxRetries }}
|
|
15
|
+
</div>
|
|
16
|
+
<time :datetime="taskData.createdAt">
|
|
17
|
+
{{ d(locale.localTime(new Date(taskData.createdAt)), 'shortTime') }}
|
|
18
|
+
</time>
|
|
19
|
+
<Button
|
|
20
|
+
:icon="isExpanded ? 'pi pi-chevron-up' : 'pi pi-chevron-down'"
|
|
21
|
+
@click="isExpanded = !isExpanded"
|
|
22
|
+
text
|
|
23
|
+
rounded
|
|
24
|
+
/>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<div v-if="isExpanded">
|
|
29
|
+
<TaskAdminDetails :task="task" :tasks="tasks" :taskTypes="taskTypes" />
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script setup>
|
|
35
|
+
import { ref, computed } from 'vue'
|
|
36
|
+
import Button from 'primevue/button'
|
|
37
|
+
import TaskAdminDetails from './TaskAdminDetails.vue'
|
|
38
|
+
|
|
39
|
+
import { useLocale } from "@live-change/vue3-components"
|
|
40
|
+
const locale = useLocale()
|
|
41
|
+
|
|
42
|
+
import { useI18n } from 'vue-i18n'
|
|
43
|
+
const { d } = useI18n()
|
|
44
|
+
|
|
45
|
+
const props = defineProps({
|
|
46
|
+
task: {
|
|
47
|
+
type: Object,
|
|
48
|
+
required: true
|
|
49
|
+
},
|
|
50
|
+
tasks: {
|
|
51
|
+
type: Array,
|
|
52
|
+
default: () => []
|
|
53
|
+
},
|
|
54
|
+
taskTypes: {
|
|
55
|
+
type: Object,
|
|
56
|
+
default: () => ({})
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const taskId = computed(() => props.task?.to || props.task?.id || props.task)
|
|
61
|
+
|
|
62
|
+
const taskData = computed(() => props.tasks.find(t => t.to === taskId.value || t.id === taskId.value))
|
|
63
|
+
|
|
64
|
+
const isExpanded = ref(false)
|
|
65
|
+
|
|
66
|
+
const icon = computed(() => {
|
|
67
|
+
switch(props.task?.state) {
|
|
68
|
+
case 'created': return 'pi-sparkles'
|
|
69
|
+
case 'waiting': return 'pi-hourglass pi-spin'
|
|
70
|
+
case 'running': return 'pi-play'
|
|
71
|
+
case 'working': return 'pi-spin pi-spinner'
|
|
72
|
+
case 'done': return 'pi-check'
|
|
73
|
+
case 'failed': return 'pi-exclamation-triangle'
|
|
74
|
+
case 'retrying': return 'pi-replay'
|
|
75
|
+
default: return 'pi-question'
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const taskColor = computed(() => {
|
|
80
|
+
switch(props.task?.state) {
|
|
81
|
+
case 'failed': return 'text-red-600'
|
|
82
|
+
default: return ''
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
</script>
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="mt-2">
|
|
3
|
+
<div v-if="taskData.progress" class="mb-2">
|
|
4
|
+
<ProgressBar :value="Math.floor((100 * taskData.progress.current / taskData.progress.total))" />
|
|
5
|
+
<div class="flex flex-row items-center justify-between">
|
|
6
|
+
<div class="text-sm text-gray-600 dark:text-gray-400">{{ taskData.progress.action }}</div>
|
|
7
|
+
<div class="text-sm text-gray-600 dark:text-gray-400">{{ taskData.progress.current }} / {{ taskData.progress.total }}</div>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-2 text-sm">
|
|
12
|
+
<div class="grid grid-cols-2 gap-2 text-sm">
|
|
13
|
+
<div>ID:</div>
|
|
14
|
+
<div>{{ taskData.id }}</div>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<div class="grid grid-cols-2 gap-2 text-sm">
|
|
18
|
+
<div>State:</div>
|
|
19
|
+
<div>{{ taskData.state }}</div>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div class="grid grid-cols-2 gap-2 text-sm">
|
|
23
|
+
<div>Created:</div>
|
|
24
|
+
<div>{{ d(taskData.createdAt, 'longWithSeconds') }}</div>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<div class="grid grid-cols-2 gap-2 text-sm">
|
|
28
|
+
<div>Started:</div>
|
|
29
|
+
<div>{{ d(taskData.startedAt, 'longWithSeconds') }}</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<div class="grid grid-cols-2 gap-2 text-sm" v-if="taskData.doneAt">
|
|
33
|
+
<div>Duration:</div>
|
|
34
|
+
<div>
|
|
35
|
+
{{ (new Date(taskData.doneAt).getTime() - new Date(taskData.startedAt).getTime()) / 1000 }}s
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
<div class="grid grid-cols-2 gap-2 text-sm" v-if="taskData.doneAt">
|
|
40
|
+
<div v-if="taskData.doneAt">Done:</div>
|
|
41
|
+
<div v-if="taskData.doneAt">{{ d(taskData.doneAt, 'longWithSeconds') }}</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div v-if="taskData.properties" class="mt-2">
|
|
46
|
+
<div class="font-semibold">Properties:</div>
|
|
47
|
+
<div class="relative">
|
|
48
|
+
<pre
|
|
49
|
+
:class="[
|
|
50
|
+
'text-sm bg-gray-100 dark:bg-gray-800 p-2 rounded overflow-x-auto whitespace-pre',
|
|
51
|
+
!isPropertiesExpanded && 'overflow-y-hidden'
|
|
52
|
+
]"
|
|
53
|
+
>{{ JSON.stringify(taskData.properties, null, 2).split('\n')
|
|
54
|
+
.slice(0, !isPropertiesExpanded ? 5 : undefined).join('\n') }}</pre>
|
|
55
|
+
|
|
56
|
+
<div v-if="!isPropertiesExpanded && hasPropertiesOverflow" class="absolute bottom-0 left-0 right-0 h-8 bg-gradient-to-t from-gray-100 dark:from-gray-800 to-transparent" />
|
|
57
|
+
</div>
|
|
58
|
+
<div
|
|
59
|
+
v-if="hasPropertiesOverflow"
|
|
60
|
+
class="mt-1 flex items-center ml-3"
|
|
61
|
+
@click="expandProperties"
|
|
62
|
+
>
|
|
63
|
+
<span class="text-sm text-slate-600 dark:text-slate-400 hover:text-slate-800 dark:hover:text-slate-200 cursor-pointer">
|
|
64
|
+
{{ isPropertiesExpanded ? 'show less' : 'show more' }}
|
|
65
|
+
</span>
|
|
66
|
+
<i :class="['pi', isPropertiesExpanded ? 'pi-chevron-up' : 'pi-chevron-down', 'text-sm cursor-pointer ml-2']" />
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<div v-if="taskData.retries?.length" class="mt-2">
|
|
71
|
+
<div class="font-semibold">Retries:</div>
|
|
72
|
+
<TaskRetry
|
|
73
|
+
v-for="(retry, index) in taskData.retries"
|
|
74
|
+
:key="index"
|
|
75
|
+
:retry="retry"
|
|
76
|
+
:index="index"
|
|
77
|
+
/>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
<div v-if="taskData.result" class="mt-2">
|
|
81
|
+
<div class="font-semibold">Result:</div>
|
|
82
|
+
<div class="relative">
|
|
83
|
+
<pre
|
|
84
|
+
:class="[
|
|
85
|
+
'text-sm bg-gray-100 dark:bg-gray-800 p-2 rounded overflow-x-auto whitespace-pre',
|
|
86
|
+
!isResultExpanded && 'overflow-y-hidden'
|
|
87
|
+
]"
|
|
88
|
+
>{{ JSON.stringify(taskData.result, null, 2).split('\n')
|
|
89
|
+
.slice(0, !isResultExpanded ? 5 : undefined).join('\n') }}</pre>
|
|
90
|
+
|
|
91
|
+
<div v-if="!isResultExpanded && hasOverflow" class="absolute bottom-0 left-0 right-0 h-8 bg-gradient-to-t from-gray-100 dark:from-gray-800 to-transparent" />
|
|
92
|
+
|
|
93
|
+
</div>
|
|
94
|
+
<div
|
|
95
|
+
v-if="hasOverflow"
|
|
96
|
+
class="mt-1 flex items-center ml-3"
|
|
97
|
+
@click="expandResult"
|
|
98
|
+
>
|
|
99
|
+
<span class="text-sm text-slate-600 dark:text-slate-400 hover:text-slate-800 dark:hover:text-slate-200 cursor-pointer">
|
|
100
|
+
{{ isResultExpanded ? 'show less' : 'show more' }}
|
|
101
|
+
</span>
|
|
102
|
+
<i :class="['pi', isResultExpanded ? 'pi-chevron-up' : 'pi-chevron-down', 'text-sm cursor-pointer ml-2']" />
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<div v-if="childTasks.length" class="mt-2">
|
|
107
|
+
<div class="font-semibold">Subtasks:</div>
|
|
108
|
+
<div v-for="subtask in childTasks" :key="subtask.id" class="mt-2">
|
|
109
|
+
<TaskAdminCard :task="subtask" :tasks="tasks" :taskTypes="taskTypes" />
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</template>
|
|
114
|
+
|
|
115
|
+
<script setup>
|
|
116
|
+
import { ref, computed } from 'vue'
|
|
117
|
+
import ProgressBar from 'primevue/progressbar'
|
|
118
|
+
import TaskAdminCard from './TaskAdminCard.vue'
|
|
119
|
+
import TaskRetry from './TaskRetry.vue'
|
|
120
|
+
|
|
121
|
+
import { useI18n } from 'vue-i18n'
|
|
122
|
+
const { d } = useI18n()
|
|
123
|
+
|
|
124
|
+
const props = defineProps({
|
|
125
|
+
task: {
|
|
126
|
+
type: Object,
|
|
127
|
+
required: true
|
|
128
|
+
},
|
|
129
|
+
tasks: {
|
|
130
|
+
type: Array,
|
|
131
|
+
default: () => []
|
|
132
|
+
},
|
|
133
|
+
taskTypes: {
|
|
134
|
+
type: Object,
|
|
135
|
+
default: () => ({})
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
const taskId = computed(() => props.task?.to || props.task?.id || props.task)
|
|
140
|
+
|
|
141
|
+
const taskData = computed(() => props.tasks.find(t => t.to === taskId.value || t.id === taskId.value))
|
|
142
|
+
|
|
143
|
+
const childTasks = computed(() => {
|
|
144
|
+
return props.tasks.filter(t => t.causeType === "task_Task" && t.cause === taskId.value)
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
const isResultExpanded = ref(false)
|
|
148
|
+
const isPropertiesExpanded = ref(false)
|
|
149
|
+
|
|
150
|
+
const hasOverflow = computed(() => {
|
|
151
|
+
if (!taskData.value?.result) return false
|
|
152
|
+
const jsonString = JSON.stringify(taskData.value.result, null, 2)
|
|
153
|
+
const lineCount = (jsonString.match(/\n/g) || []).length
|
|
154
|
+
return lineCount > 4
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
const hasPropertiesOverflow = computed(() => {
|
|
158
|
+
if (!taskData.value?.properties) return false
|
|
159
|
+
const jsonString = JSON.stringify(taskData.value.properties, null, 2)
|
|
160
|
+
const lineCount = (jsonString.match(/\n/g) || []).length
|
|
161
|
+
return lineCount > 4
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
const expandResult = () => {
|
|
165
|
+
isResultExpanded.value = !isResultExpanded.value
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const expandProperties = () => {
|
|
169
|
+
isPropertiesExpanded.value = !isPropertiesExpanded.value
|
|
170
|
+
}
|
|
171
|
+
</script>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="mt-0 ml-4">
|
|
3
|
+
<div class="flex flex-row items-center">
|
|
4
|
+
<div class="text-red-600 dark:text-red-400">
|
|
5
|
+
{{ index + 1 }}. {{ retry.error }}
|
|
6
|
+
<span class="text-gray-600 dark:text-gray-400">at {{ d(retry.failedAt, 'shortestTime') }}</span>
|
|
7
|
+
</div>
|
|
8
|
+
<i
|
|
9
|
+
v-if="retry.stack"
|
|
10
|
+
:class="['pi', isExpanded ? 'pi-chevron-up' : 'pi-chevron-down', 'text-sm cursor-pointer ml-2']"
|
|
11
|
+
@click="isExpanded = !isExpanded"
|
|
12
|
+
/>
|
|
13
|
+
</div>
|
|
14
|
+
<pre v-if="retry.stack && isExpanded" class="text-xs text-red-800 dark:text-red-300 bg-red-50 dark:bg-red-900/30 p-2 rounded mt-1 overflow-x-auto whitespace-pre">{{ retry.stack }}</pre>
|
|
15
|
+
</div>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script setup>
|
|
19
|
+
import { ref } from 'vue'
|
|
20
|
+
import { useI18n } from 'vue-i18n'
|
|
21
|
+
|
|
22
|
+
const { d } = useI18n()
|
|
23
|
+
|
|
24
|
+
const props = defineProps({
|
|
25
|
+
retry: {
|
|
26
|
+
type: Object,
|
|
27
|
+
required: true
|
|
28
|
+
},
|
|
29
|
+
index: {
|
|
30
|
+
type: Number,
|
|
31
|
+
required: true
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
const isExpanded = ref(false)
|
|
36
|
+
</script>
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="w-full">
|
|
3
|
+
<div class="bg-surface-0 dark:bg-surface-900 p-3 shadow mb-1">
|
|
4
|
+
<h2>Tasks</h2>
|
|
5
|
+
<!-- <pre>tasksNames = {{ tasksNames }}</pre>
|
|
6
|
+
<pre>taskStates = {{ taskStates }}</pre> -->
|
|
7
|
+
<div class="flex flex-wrap gap-3 mb-3">
|
|
8
|
+
<div class="flex-1">
|
|
9
|
+
<label for="task-name" class="block mb-2">Task Name</label>
|
|
10
|
+
<Select id="task-name" v-model="name" :options="['any', ...tasksNames]"
|
|
11
|
+
placeholder="Select Task Name" class="w-full" />
|
|
12
|
+
</div>
|
|
13
|
+
<div class="flex-1">
|
|
14
|
+
<label for="task-state" class="block mb-2">Task State</label>
|
|
15
|
+
<Select id="task-state" v-model="state" :options="['any', ...taskStates.map(s => ({label: s, value: s}))]"
|
|
16
|
+
placeholder="Select Task State" class="w-full" />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<!-- <pre>tasksPathConfig = {{ tasksPathConfig }}</pre> -->
|
|
22
|
+
|
|
23
|
+
<range-viewer :pathFunction="tasksPathFunction" :key="JSON.stringify(tasksPathConfig)"
|
|
24
|
+
:canLoadTop="false" canDropBottom
|
|
25
|
+
loadBottomSensorSize="4000px" dropBottomSensorSize="3000px">
|
|
26
|
+
<template #empty>
|
|
27
|
+
<div class="bg-surface-0 p-3 shadow text-center text-gray-500 text-lg">
|
|
28
|
+
No tasks found...
|
|
29
|
+
</div>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<template #default="{ item: task }">
|
|
33
|
+
<TaskAdminCard :task="task" :tasks="task.subTasks" class="mt-1" />
|
|
34
|
+
</template>
|
|
35
|
+
</range-viewer>
|
|
36
|
+
|
|
37
|
+
</div>
|
|
38
|
+
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<script setup>
|
|
42
|
+
|
|
43
|
+
import TaskAdminCard from '../components/TaskAdminCard.vue'
|
|
44
|
+
|
|
45
|
+
import Select from 'primevue/select'
|
|
46
|
+
|
|
47
|
+
import { ref, computed } from 'vue'
|
|
48
|
+
import { RangeViewer } from "@live-change/vue3-components"
|
|
49
|
+
|
|
50
|
+
import { inject } from 'vue'
|
|
51
|
+
const workingZone = inject('workingZone')
|
|
52
|
+
|
|
53
|
+
import { usePath, live, useClient, useActions, reverseRange, useApi } from '@live-change/vue3-ssr'
|
|
54
|
+
const path = usePath()
|
|
55
|
+
const client = useClient()
|
|
56
|
+
const actions = useActions()
|
|
57
|
+
const api = useApi()
|
|
58
|
+
|
|
59
|
+
const taskDefinition = computed(() => api.getServiceDefinition('task').models.Task)
|
|
60
|
+
const taskStates = computed(() => taskDefinition.value?.properties?.state?.enum)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
const state = ref('any')
|
|
64
|
+
const name = ref('any')
|
|
65
|
+
|
|
66
|
+
const tasksPathConfig = computed(() => {
|
|
67
|
+
return {
|
|
68
|
+
name: name.value === 'any' ? undefined : name.value,
|
|
69
|
+
state: state.value === 'any' ? undefined : state.value
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
const tasksPathFunction = computed(() => (range) =>
|
|
74
|
+
path.task.independentTasks({ ...tasksPathConfig.value, ...reverseRange(range) })
|
|
75
|
+
.with(task => path.task.tasksByRoot({
|
|
76
|
+
rootType: 'task_Task',
|
|
77
|
+
root: task.id//{ or: [task.to, task.id]}
|
|
78
|
+
}).bind('subTasks'))
|
|
79
|
+
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
const tasksNamesPath = path.task.taskNames({})
|
|
83
|
+
|
|
84
|
+
console.log("TASKS NAMES PATH", tasksNamesPath)
|
|
85
|
+
|
|
86
|
+
const [tasksNamesData] = await Promise.all([
|
|
87
|
+
live(tasksNamesPath)
|
|
88
|
+
])
|
|
89
|
+
const tasksNames = computed(() => tasksNamesData.value.map(task => task.id))
|
|
90
|
+
|
|
91
|
+
console.log("TASKS NAMES", tasksNames)
|
|
92
|
+
|
|
93
|
+
</script>
|
package/front/src/router.js
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
export function taskAdminRoutes(config = {}) {
|
|
2
|
+
const { prefix = '/', route = (r) => r } = config
|
|
3
|
+
return [
|
|
4
|
+
|
|
5
|
+
route({
|
|
6
|
+
name: 'task:admin', path: prefix, meta: { },
|
|
7
|
+
component: () => import("./pages/TaskAdmin.vue"),
|
|
8
|
+
props: true
|
|
9
|
+
}),
|
|
10
|
+
|
|
11
|
+
]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
1
15
|
import {
|
|
2
16
|
createMemoryHistory,
|
|
3
17
|
createRouter as _createRouter,
|
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/task-frontend",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.86",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"memDev": "tsx --inspect --expose-gc server/start.js memDev --enableSessions --initScript ./init.js --dbAccess",
|
|
6
6
|
"localDevInit": "tsx server/start.js localDev --enableSessions --initScript ./init.js --dbAccess",
|
|
@@ -37,41 +37,41 @@
|
|
|
37
37
|
"@codemirror/language": "6.10.1",
|
|
38
38
|
"@dotenvx/dotenvx": "0.27.0",
|
|
39
39
|
"@fortawesome/fontawesome-free": "^6.7.2",
|
|
40
|
-
"@live-change/access-control-frontend": "^0.9.
|
|
41
|
-
"@live-change/access-control-service": "^0.9.
|
|
42
|
-
"@live-change/backup-service": "^0.9.
|
|
43
|
-
"@live-change/blog-frontend": "^0.9.
|
|
44
|
-
"@live-change/blog-service": "^0.9.
|
|
45
|
-
"@live-change/cli": "^0.9.
|
|
46
|
-
"@live-change/content-frontend": "^0.9.
|
|
47
|
-
"@live-change/content-service": "^0.9.
|
|
48
|
-
"@live-change/dao": "^0.9.
|
|
49
|
-
"@live-change/dao-vue3": "^0.9.
|
|
50
|
-
"@live-change/dao-websocket": "^0.9.
|
|
51
|
-
"@live-change/db-client": "^0.9.
|
|
52
|
-
"@live-change/email-service": "^0.9.
|
|
53
|
-
"@live-change/framework": "^0.9.
|
|
54
|
-
"@live-change/frontend-auto-form": "^0.9.
|
|
55
|
-
"@live-change/frontend-base": "^0.9.
|
|
56
|
-
"@live-change/geoip-service": "^0.9.
|
|
57
|
-
"@live-change/image-frontend": "^0.9.
|
|
58
|
-
"@live-change/locale-settings-service": "^0.9.
|
|
59
|
-
"@live-change/password-authentication-service": "^0.9.
|
|
60
|
-
"@live-change/prosemirror-service": "^0.9.
|
|
61
|
-
"@live-change/secret-code-service": "^0.9.
|
|
62
|
-
"@live-change/secret-link-service": "^0.9.
|
|
63
|
-
"@live-change/session-service": "^0.9.
|
|
64
|
-
"@live-change/task-service": "^0.9.
|
|
65
|
-
"@live-change/upload-frontend": "^0.9.
|
|
66
|
-
"@live-change/url-frontend": "^0.9.
|
|
67
|
-
"@live-change/url-service": "^0.9.
|
|
68
|
-
"@live-change/user-frontend": "^0.9.
|
|
69
|
-
"@live-change/user-identification-service": "^0.9.
|
|
70
|
-
"@live-change/user-service": "^0.9.
|
|
71
|
-
"@live-change/vote-service": "^0.9.
|
|
72
|
-
"@live-change/vue3-components": "^0.9.
|
|
73
|
-
"@live-change/vue3-ssr": "^0.9.
|
|
74
|
-
"@live-change/wysiwyg-frontend": "^0.9.
|
|
40
|
+
"@live-change/access-control-frontend": "^0.9.86",
|
|
41
|
+
"@live-change/access-control-service": "^0.9.86",
|
|
42
|
+
"@live-change/backup-service": "^0.9.86",
|
|
43
|
+
"@live-change/blog-frontend": "^0.9.86",
|
|
44
|
+
"@live-change/blog-service": "^0.9.86",
|
|
45
|
+
"@live-change/cli": "^0.9.86",
|
|
46
|
+
"@live-change/content-frontend": "^0.9.86",
|
|
47
|
+
"@live-change/content-service": "^0.9.86",
|
|
48
|
+
"@live-change/dao": "^0.9.86",
|
|
49
|
+
"@live-change/dao-vue3": "^0.9.86",
|
|
50
|
+
"@live-change/dao-websocket": "^0.9.86",
|
|
51
|
+
"@live-change/db-client": "^0.9.86",
|
|
52
|
+
"@live-change/email-service": "^0.9.86",
|
|
53
|
+
"@live-change/framework": "^0.9.86",
|
|
54
|
+
"@live-change/frontend-auto-form": "^0.9.86",
|
|
55
|
+
"@live-change/frontend-base": "^0.9.86",
|
|
56
|
+
"@live-change/geoip-service": "^0.9.86",
|
|
57
|
+
"@live-change/image-frontend": "^0.9.86",
|
|
58
|
+
"@live-change/locale-settings-service": "^0.9.86",
|
|
59
|
+
"@live-change/password-authentication-service": "^0.9.86",
|
|
60
|
+
"@live-change/prosemirror-service": "^0.9.86",
|
|
61
|
+
"@live-change/secret-code-service": "^0.9.86",
|
|
62
|
+
"@live-change/secret-link-service": "^0.9.86",
|
|
63
|
+
"@live-change/session-service": "^0.9.86",
|
|
64
|
+
"@live-change/task-service": "^0.9.86",
|
|
65
|
+
"@live-change/upload-frontend": "^0.9.86",
|
|
66
|
+
"@live-change/url-frontend": "^0.9.86",
|
|
67
|
+
"@live-change/url-service": "^0.9.86",
|
|
68
|
+
"@live-change/user-frontend": "^0.9.86",
|
|
69
|
+
"@live-change/user-identification-service": "^0.9.86",
|
|
70
|
+
"@live-change/user-service": "^0.9.86",
|
|
71
|
+
"@live-change/vote-service": "^0.9.86",
|
|
72
|
+
"@live-change/vue3-components": "^0.9.86",
|
|
73
|
+
"@live-change/vue3-ssr": "^0.9.86",
|
|
74
|
+
"@live-change/wysiwyg-frontend": "^0.9.86",
|
|
75
75
|
"@vueuse/core": "^12.3.0",
|
|
76
76
|
"codeceptjs-assert": "^0.0.5",
|
|
77
77
|
"compression": "^1.7.5",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"vue3-scroll-border": "0.1.6"
|
|
94
94
|
},
|
|
95
95
|
"devDependencies": {
|
|
96
|
-
"@live-change/codeceptjs-helper": "^0.9.
|
|
96
|
+
"@live-change/codeceptjs-helper": "^0.9.86",
|
|
97
97
|
"codeceptjs": "^3.6.10",
|
|
98
98
|
"generate-password": "1.7.1",
|
|
99
99
|
"playwright": "1.49.1",
|
|
@@ -104,5 +104,5 @@
|
|
|
104
104
|
"author": "Michał Łaszczewski <michal@laszczewski.pl>",
|
|
105
105
|
"license": "ISC",
|
|
106
106
|
"description": "",
|
|
107
|
-
"gitHead": "
|
|
107
|
+
"gitHead": "7b0013ef101d9033402eeec45fd1be60e151aada"
|
|
108
108
|
}
|