@mongoosejs/studio 0.2.13 → 0.3.0
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/backend/actions/ChatMessage/executeScript.js +5 -1
- package/backend/actions/ChatThread/createChatMessage.js +2 -1
- package/backend/actions/ChatThread/streamChatMessage.js +2 -2
- package/eslint.config.js +4 -1
- package/frontend/public/app.js +24642 -543
- package/frontend/public/dark-theme.css +365 -0
- package/frontend/public/images/mongoose-studio.svg +4 -0
- package/frontend/public/index.html +21 -1
- package/frontend/public/style.css +5 -7
- package/frontend/public/theme-variables.css +294 -0
- package/frontend/public/tw.css +305 -252
- package/frontend/src/ace-editor/ace-editor.html +4 -0
- package/frontend/src/ace-editor/ace-editor.js +89 -0
- package/frontend/src/aceEditor.js +69 -0
- package/frontend/src/chat/chat-message/chat-message.html +1 -1
- package/frontend/src/chat/chat-message/chat-message.js +1 -1
- package/frontend/src/chat/chat-message-script/chat-message-script.html +51 -34
- package/frontend/src/chat/chat-message-script/chat-message-script.js +12 -55
- package/frontend/src/chat/chat.html +68 -39
- package/frontend/src/chat/chat.js +26 -2
- package/frontend/src/clone-document/clone-document.html +7 -2
- package/frontend/src/clone-document/clone-document.js +1 -8
- package/frontend/src/create-dashboard/create-dashboard.html +11 -6
- package/frontend/src/create-dashboard/create-dashboard.js +0 -7
- package/frontend/src/create-document/create-document.html +15 -9
- package/frontend/src/create-document/create-document.js +5 -12
- package/frontend/src/dashboard/dashboard.html +14 -12
- package/frontend/src/dashboard/dashboard.js +12 -4
- package/frontend/src/dashboard/edit-dashboard/edit-dashboard.html +13 -7
- package/frontend/src/dashboard/edit-dashboard/edit-dashboard.js +13 -21
- package/frontend/src/dashboard-result/dashboard-chart/dashboard-chart.html +19 -17
- package/frontend/src/dashboard-result/dashboard-chart/dashboard-chart.js +97 -2
- package/frontend/src/dashboard-result/dashboard-map/dashboard-map.js +27 -3
- package/frontend/src/dashboard-result/dashboard-result.html +3 -3
- package/frontend/src/dashboards/dashboards.html +101 -109
- package/frontend/src/dashboards/dashboards.js +25 -1
- package/frontend/src/detail-default/detail-default.html +2 -2
- package/frontend/src/detail-default/detail-default.js +24 -3
- package/frontend/src/document/confirm-changes/confirm-changes.html +1 -1
- package/frontend/src/document/confirm-delete/confirm-delete.html +1 -1
- package/frontend/src/document/document.css +1 -1
- package/frontend/src/document/document.html +28 -28
- package/frontend/src/document/execute-script/execute-script.html +20 -21
- package/frontend/src/document/execute-script/execute-script.js +1 -43
- package/frontend/src/document-details/document-details.css +4 -9
- package/frontend/src/document-details/document-details.html +34 -33
- package/frontend/src/document-details/document-details.js +2 -53
- package/frontend/src/document-details/document-property/document-property.html +12 -12
- package/frontend/src/edit-array/edit-array.html +7 -6
- package/frontend/src/edit-array/edit-array.js +10 -50
- package/frontend/src/edit-boolean/edit-boolean.html +12 -12
- package/frontend/src/edit-date/edit-date.html +2 -2
- package/frontend/src/edit-default/edit-default.html +1 -1
- package/frontend/src/edit-string/edit-string.html +3 -3
- package/frontend/src/edit-subdocument/edit-subdocument.html +5 -3
- package/frontend/src/edit-subdocument/edit-subdocument.js +1 -15
- package/frontend/src/export-query-results/export-query-results.html +3 -3
- package/frontend/src/json-node/json-node.html +3 -3
- package/frontend/src/list-json/json-node.html +1 -1
- package/frontend/src/models/document-search/document-search.html +3 -3
- package/frontend/src/models/model-switcher/model-switcher.html +53 -0
- package/frontend/src/models/model-switcher/model-switcher.js +123 -0
- package/frontend/src/models/models.css +3 -10
- package/frontend/src/models/models.html +146 -80
- package/frontend/src/models/models.js +108 -4
- package/frontend/src/navbar/navbar.html +157 -97
- package/frontend/src/navbar/navbar.js +31 -12
- package/frontend/src/routes.js +1 -1
- package/frontend/src/splash/splash.html +5 -5
- package/frontend/src/task-single/task-single.html +29 -29
- package/frontend/src/task-single/task-single.js +10 -10
- package/frontend/src/tasks/task-details/task-details.html +38 -38
- package/frontend/src/tasks/task-details/task-details.js +7 -2
- package/frontend/src/tasks/tasks.html +36 -35
- package/frontend/src/tasks/tasks.js +2 -25
- package/frontend/src/team/new-invitation/new-invitation.html +8 -8
- package/frontend/src/team/team.html +27 -27
- package/frontend/src/update-document/update-document.html +7 -2
- package/frontend/src/update-document/update-document.js +2 -11
- package/package.json +2 -1
- package/tailwind.config.js +75 -11
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div class="w-full h-full flex items-center justify-center">
|
|
2
2
|
<div class="text-center">
|
|
3
|
-
<div class="rounded-full bg-
|
|
4
|
-
<img src="images/
|
|
3
|
+
<div class="rounded-full bg-muted p-6 inline-block">
|
|
4
|
+
<img src="images/mongoose-studio.svg" class="w-48 h-48">
|
|
5
5
|
</div>
|
|
6
6
|
<div class="text-lg mt-2 font-bold">
|
|
7
7
|
Mongoose Studio
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<div v-if="loading" class="mt-2">
|
|
10
10
|
<img src="images/loader.gif" class="inline w-16 h-16">
|
|
11
11
|
</div>
|
|
12
|
-
<div class="mt-2 text-
|
|
12
|
+
<div class="mt-2 text-content-secondary" v-if="!loading">
|
|
13
13
|
{{workspaceName}}
|
|
14
14
|
</div>
|
|
15
15
|
<div class="mt-4 flex gap-4 justify-center" v-if="!loading">
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<async-button
|
|
18
18
|
type="button"
|
|
19
19
|
@click="loginWithGithub"
|
|
20
|
-
class="rounded bg-
|
|
20
|
+
class="rounded bg-primary px-2 py-2 text-sm font-semibold text-primary-text shadow-sm hover:bg-primary-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:bg-page0">
|
|
21
21
|
<svg viewBox="0 0 98 98" class="inline mr-1" height="1.5em" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" fill="#fff"/></svg>
|
|
22
22
|
Login With GitHub
|
|
23
23
|
</async-button>
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
<async-button
|
|
27
27
|
type="button"
|
|
28
28
|
@click="loginWithGoogle"
|
|
29
|
-
class="rounded bg-
|
|
29
|
+
class="rounded bg-primary px-2 py-2 text-sm font-semibold text-primary-text shadow-sm hover:bg-primary-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary disabled:bg-page0">
|
|
30
30
|
<svg class="inline" xmlns="http://www.w3.org/2000/svg" height="1.5em" viewBox="0 0 512 512"><path fill="#fff" d="M386 400c45-42 65-112 53-179H260v74h102c-4 24-18 44-38 57z"/><path fill="#fff" d="M90 341a192 192 0 0 0 296 59l-62-48c-53 35-141 22-171-60z"/><path fill="#fff" d="M153 292c-8-25-8-48 0-73l-63-49c-23 46-30 111 0 171z"/><path fill="#fff" d="M153 219c22-69 116-109 179-50l55-54c-78-75-230-72-297 55z"/></svg>
|
|
31
31
|
Login With Google
|
|
32
32
|
</async-button>
|
|
@@ -9,18 +9,18 @@
|
|
|
9
9
|
Task not found.
|
|
10
10
|
</div>
|
|
11
11
|
<div v-else-if="task" class="max-w-4xl">
|
|
12
|
-
<button @click="goBack" class="text-
|
|
12
|
+
<button @click="goBack" class="text-content-tertiary hover:text-content-secondary mb-4 flex items-center gap-1">
|
|
13
13
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
14
14
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
|
15
15
|
</svg>
|
|
16
16
|
Back to {{ task.name }}
|
|
17
17
|
</button>
|
|
18
|
-
<h1 class="text-2xl font-bold text-
|
|
19
|
-
<p class="text-
|
|
18
|
+
<h1 class="text-2xl font-bold text-content-secondary mb-1">{{ task.name }}</h1>
|
|
19
|
+
<p class="text-content-tertiary mb-6">Task details</p>
|
|
20
20
|
|
|
21
|
-
<div class="bg-
|
|
21
|
+
<div class="bg-surface rounded-lg shadow p-6 md:p-8">
|
|
22
22
|
<div class="flex items-center gap-3 mb-6">
|
|
23
|
-
<span class="text-sm font-medium text-
|
|
23
|
+
<span class="text-sm font-medium text-content">ID: {{ task.id }}</span>
|
|
24
24
|
<span
|
|
25
25
|
class="text-xs px-2 py-1 rounded-full font-medium"
|
|
26
26
|
:class="getStatusColor(task.status)"
|
|
@@ -31,41 +31,41 @@
|
|
|
31
31
|
|
|
32
32
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6">
|
|
33
33
|
<div>
|
|
34
|
-
<label class="block text-sm font-medium text-
|
|
35
|
-
<div class="text-sm text-
|
|
34
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Scheduled At</label>
|
|
35
|
+
<div class="text-sm text-content">{{ formatDate(task.scheduledAt) }}</div>
|
|
36
36
|
</div>
|
|
37
37
|
<div v-if="task?.startedAt">
|
|
38
|
-
<label class="block text-sm font-medium text-
|
|
39
|
-
<div class="text-sm text-
|
|
38
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Started At</label>
|
|
39
|
+
<div class="text-sm text-content">{{ formatDate(task.startedAt) }}</div>
|
|
40
40
|
</div>
|
|
41
41
|
<div v-if="task?.completedAt">
|
|
42
|
-
<label class="block text-sm font-medium text-
|
|
43
|
-
<div class="text-sm text-
|
|
42
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Completed At</label>
|
|
43
|
+
<div class="text-sm text-content">{{ formatDate(task.completedAt) }}</div>
|
|
44
44
|
</div>
|
|
45
45
|
</div>
|
|
46
46
|
|
|
47
47
|
<div v-if="task?.params" class="mb-6">
|
|
48
|
-
<label class="block text-sm font-medium text-
|
|
49
|
-
<div class="bg-
|
|
48
|
+
<label class="block text-sm font-medium text-content-secondary mb-2">Params</label>
|
|
49
|
+
<div class="bg-page rounded-md p-4">
|
|
50
50
|
<list-json :value="task.params"></list-json>
|
|
51
51
|
</div>
|
|
52
52
|
</div>
|
|
53
53
|
|
|
54
54
|
<div v-if="task?.result" class="mb-6">
|
|
55
|
-
<label class="block text-sm font-medium text-
|
|
56
|
-
<div class="bg-
|
|
55
|
+
<label class="block text-sm font-medium text-content-secondary mb-2">Result</label>
|
|
56
|
+
<div class="bg-page rounded-md p-4">
|
|
57
57
|
<list-json :value="task.result"></list-json>
|
|
58
58
|
</div>
|
|
59
59
|
</div>
|
|
60
60
|
|
|
61
61
|
<div v-if="task?.error" class="mb-6">
|
|
62
|
-
<label class="block text-sm font-medium text-
|
|
63
|
-
<div class="bg-
|
|
62
|
+
<label class="block text-sm font-medium text-content-secondary mb-2">Error</label>
|
|
63
|
+
<div class="bg-page rounded-md p-4">
|
|
64
64
|
<list-json :value="task.error"></list-json>
|
|
65
65
|
</div>
|
|
66
66
|
</div>
|
|
67
67
|
|
|
68
|
-
<div class="flex flex-wrap gap-3 pt-4 border-t border-
|
|
68
|
+
<div class="flex flex-wrap gap-3 pt-4 border-t border-edge">
|
|
69
69
|
<button
|
|
70
70
|
@click="showRescheduleConfirmation(task)"
|
|
71
71
|
class="flex items-center justify-center gap-2 bg-gradient-to-r from-blue-500 to-blue-600 text-white px-4 py-2 rounded-lg text-sm font-medium hover:from-blue-600 hover:to-blue-700 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
@@ -105,19 +105,19 @@
|
|
|
105
105
|
<template #body>
|
|
106
106
|
<div class="absolute font-mono right-1 top-1 cursor-pointer text-xl" @click="showRescheduleModal = false" role="button" aria-label="Close modal">×</div>
|
|
107
107
|
<div class="p-6">
|
|
108
|
-
<h3 class="text-lg font-medium text-
|
|
108
|
+
<h3 class="text-lg font-medium text-content mb-4">Reschedule Task</h3>
|
|
109
109
|
<p class="text-sm text-gray-600 mb-2">Reschedule task <strong>{{ selectedTask?.id }}</strong>?</p>
|
|
110
|
-
<p class="text-sm text-
|
|
111
|
-
<label for="newScheduledTime" class="block text-sm font-medium text-
|
|
110
|
+
<p class="text-sm text-content-tertiary mb-4">This will reset the task's status and schedule it to run again.</p>
|
|
111
|
+
<label for="newScheduledTime" class="block text-sm font-medium text-content-secondary mb-2">New Scheduled Time</label>
|
|
112
112
|
<input
|
|
113
113
|
id="newScheduledTime"
|
|
114
114
|
v-model="newScheduledTime"
|
|
115
115
|
type="datetime-local"
|
|
116
|
-
class="w-full px-3 py-2 border border-
|
|
116
|
+
class="w-full px-3 py-2 border border-edge-strong rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 mb-4"
|
|
117
117
|
/>
|
|
118
118
|
<div class="flex gap-3">
|
|
119
119
|
<button @click="confirmRescheduleTask" class="flex-1 bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 font-medium">Reschedule</button>
|
|
120
|
-
<button @click="showRescheduleModal = false" class="flex-1 bg-gray-300 text-
|
|
120
|
+
<button @click="showRescheduleModal = false" class="flex-1 bg-gray-300 text-content-secondary px-4 py-2 rounded-md hover:bg-gray-400 font-medium">Cancel</button>
|
|
121
121
|
</div>
|
|
122
122
|
</div>
|
|
123
123
|
</template>
|
|
@@ -128,12 +128,12 @@
|
|
|
128
128
|
<template #body>
|
|
129
129
|
<div class="absolute font-mono right-1 top-1 cursor-pointer text-xl" @click="showRunModal = false" role="button" aria-label="Close modal">×</div>
|
|
130
130
|
<div class="p-6">
|
|
131
|
-
<h3 class="text-lg font-medium text-
|
|
131
|
+
<h3 class="text-lg font-medium text-content mb-4">Run Task Now</h3>
|
|
132
132
|
<p class="text-sm text-gray-600 mb-2">Run task <strong>{{ selectedTask?.id }}</strong> immediately?</p>
|
|
133
|
-
<p class="text-sm text-
|
|
133
|
+
<p class="text-sm text-content-tertiary mb-4">This will execute the task right away, bypassing its scheduled time.</p>
|
|
134
134
|
<div class="flex gap-3">
|
|
135
135
|
<button @click="confirmRunTask" class="flex-1 bg-green-600 text-white px-4 py-2 rounded-md hover:bg-green-700 font-medium">Run Now</button>
|
|
136
|
-
<button @click="showRunModal = false" class="flex-1 bg-gray-300 text-
|
|
136
|
+
<button @click="showRunModal = false" class="flex-1 bg-gray-300 text-content-secondary px-4 py-2 rounded-md hover:bg-gray-400 font-medium">Cancel</button>
|
|
137
137
|
</div>
|
|
138
138
|
</div>
|
|
139
139
|
</template>
|
|
@@ -144,12 +144,12 @@
|
|
|
144
144
|
<template #body>
|
|
145
145
|
<div class="absolute font-mono right-1 top-1 cursor-pointer text-xl" @click="showCancelModal = false" role="button" aria-label="Close modal">×</div>
|
|
146
146
|
<div class="p-6">
|
|
147
|
-
<h3 class="text-lg font-medium text-
|
|
147
|
+
<h3 class="text-lg font-medium text-content mb-4">Cancel Task</h3>
|
|
148
148
|
<p class="text-sm text-gray-600 mb-2">Cancel task <strong>{{ selectedTask?.id }}</strong>?</p>
|
|
149
|
-
<p class="text-sm text-
|
|
149
|
+
<p class="text-sm text-content-tertiary mb-4">This will permanently cancel the task and it cannot be undone.</p>
|
|
150
150
|
<div class="flex gap-3">
|
|
151
151
|
<button @click="confirmCancelTask" class="flex-1 bg-red-600 text-white px-4 py-2 rounded-md hover:bg-red-700 font-medium">Cancel Task</button>
|
|
152
|
-
<button @click="showCancelModal = false" class="flex-1 bg-gray-300 text-
|
|
152
|
+
<button @click="showCancelModal = false" class="flex-1 bg-gray-300 text-content-secondary px-4 py-2 rounded-md hover:bg-gray-400 font-medium">Keep Task</button>
|
|
153
153
|
</div>
|
|
154
154
|
</div>
|
|
155
155
|
</template>
|
|
@@ -25,7 +25,7 @@ module.exports = app => app.component('task-single', {
|
|
|
25
25
|
const path = `/tasks/${encodeURIComponent(name || '')}`;
|
|
26
26
|
const query = this.$route.query?.status ? { status: this.$route.query.status } : {};
|
|
27
27
|
return { path, query };
|
|
28
|
-
}
|
|
28
|
+
}
|
|
29
29
|
},
|
|
30
30
|
watch: {
|
|
31
31
|
'$route.params': {
|
|
@@ -82,11 +82,11 @@ module.exports = app => app.component('task-single', {
|
|
|
82
82
|
async confirmRescheduleTask() {
|
|
83
83
|
if (!this.newScheduledTime) return;
|
|
84
84
|
await api.Task.rescheduleTask({ taskId: this.selectedTask.id, scheduledAt: this.newScheduledTime });
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
this.$toast.success({ title: 'Task Rescheduled', text: `Task ${this.selectedTask.id} has been rescheduled` });
|
|
86
|
+
this.showRescheduleModal = false;
|
|
87
|
+
this.selectedTask = null;
|
|
88
|
+
this.newScheduledTime = '';
|
|
89
|
+
await this.loadTask();
|
|
90
90
|
},
|
|
91
91
|
async confirmRunTask() {
|
|
92
92
|
await api.Task.runTask({ taskId: this.selectedTask.id });
|
|
@@ -104,10 +104,10 @@ module.exports = app => app.component('task-single', {
|
|
|
104
104
|
},
|
|
105
105
|
async confirmCancelTask() {
|
|
106
106
|
await api.Task.cancelTask({ taskId: this.selectedTask.id });
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
this.$toast.success({ title: 'Task Cancelled', text: `Task ${this.selectedTask.id} has been cancelled` });
|
|
108
|
+
this.showCancelModal = false;
|
|
109
|
+
this.selectedTask = null;
|
|
110
|
+
this.goBack();
|
|
111
111
|
}
|
|
112
112
|
},
|
|
113
113
|
mounted() {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<div class="p-4 space-y-6">
|
|
2
2
|
<div class="flex items-center justify-between">
|
|
3
3
|
<div>
|
|
4
|
-
<button @click="goBack" class="text-
|
|
4
|
+
<button @click="goBack" class="text-content-tertiary hover:text-content-secondary mb-2">
|
|
5
5
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
6
6
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"></path>
|
|
7
7
|
</svg>
|
|
8
8
|
{{ backLabel }}
|
|
9
9
|
</button>
|
|
10
|
-
<h1 class="text-2xl font-bold text-
|
|
11
|
-
<p class="text-
|
|
10
|
+
<h1 class="text-2xl font-bold text-content-secondary">{{ taskGroup.name }}</h1>
|
|
11
|
+
<p class="text-content-tertiary">Total: {{ taskGroup.totalCount }} tasks</p>
|
|
12
12
|
</div>
|
|
13
13
|
|
|
14
14
|
</div>
|
|
@@ -16,13 +16,13 @@
|
|
|
16
16
|
<!-- Status Summary -->
|
|
17
17
|
<div class="space-y-3">
|
|
18
18
|
<div class="flex items-center justify-between">
|
|
19
|
-
<span class="text-sm font-medium text-
|
|
19
|
+
<span class="text-sm font-medium text-content-secondary">Status</span>
|
|
20
20
|
<div class="flex rounded-md shadow-sm" role="group">
|
|
21
21
|
<button
|
|
22
22
|
type="button"
|
|
23
23
|
@click="statusView = 'summary'"
|
|
24
24
|
class="px-3 py-1.5 text-sm font-medium rounded-l-md border transition-colors"
|
|
25
|
-
:class="statusView === 'summary' ? 'bg-
|
|
25
|
+
:class="statusView === 'summary' ? 'bg-primary text-primary-text border-primary' : 'bg-surface text-content-secondary border-edge-strong hover:bg-page'"
|
|
26
26
|
>
|
|
27
27
|
Summary
|
|
28
28
|
</button>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
type="button"
|
|
31
31
|
@click="statusView = 'chart'"
|
|
32
32
|
class="px-3 py-1.5 text-sm font-medium rounded-r-md border border-l-0 transition-colors"
|
|
33
|
-
:class="statusView === 'chart' ? 'bg-
|
|
33
|
+
:class="statusView === 'chart' ? 'bg-primary text-primary-text border-primary' : 'bg-surface text-content-secondary border-edge-strong hover:bg-page'"
|
|
34
34
|
>
|
|
35
35
|
Chart
|
|
36
36
|
</button>
|
|
@@ -64,19 +64,19 @@
|
|
|
64
64
|
</button>
|
|
65
65
|
<button
|
|
66
66
|
@click="filterByStatus('cancelled')"
|
|
67
|
-
class="bg-
|
|
67
|
+
class="bg-page border border-edge rounded-md p-3 text-center hover:bg-muted transition-colors cursor-pointer"
|
|
68
68
|
:class="{ 'ring-2 ring-gray-400': currentFilter === 'cancelled' }"
|
|
69
69
|
>
|
|
70
70
|
<div class="text-xs text-gray-600 font-medium">Cancelled</div>
|
|
71
|
-
<div class="text-lg font-bold text-
|
|
71
|
+
<div class="text-lg font-bold text-content-secondary">{{ taskGroup.statusCounts.cancelled || 0 }}</div>
|
|
72
72
|
</button>
|
|
73
73
|
</div>
|
|
74
74
|
<!-- Chart view -->
|
|
75
|
-
<div v-show="statusView === 'chart'" class="flex flex-col items-center justify-center bg-
|
|
75
|
+
<div v-show="statusView === 'chart'" class="flex flex-col items-center justify-center bg-surface border border-edge rounded-lg p-4 gap-3" style="min-height: 280px;">
|
|
76
76
|
<div v-if="taskGroup.totalCount > 0" class="w-[240px] h-[240px] shrink-0">
|
|
77
77
|
<canvas ref="statusPieChart" width="240" height="240" class="block"></canvas>
|
|
78
78
|
</div>
|
|
79
|
-
<p v-else class="text-
|
|
79
|
+
<p v-else class="text-content-tertiary text-sm py-8">No tasks to display</p>
|
|
80
80
|
<!-- Selection labels: show which segment is selected (click to filter) -->
|
|
81
81
|
<div v-if="taskGroup.totalCount > 0" class="flex flex-wrap justify-center gap-2">
|
|
82
82
|
<button
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
:key="status"
|
|
85
85
|
type="button"
|
|
86
86
|
class="text-xs px-2 py-1 rounded-full font-medium transition-all cursor-pointer"
|
|
87
|
-
:class="currentFilter === status ? getStatusPillClass(status) : 'bg-
|
|
87
|
+
:class="currentFilter === status ? getStatusPillClass(status) : 'bg-muted text-content-tertiary hover:bg-muted'"
|
|
88
88
|
@click="filterByStatus(status)"
|
|
89
89
|
>
|
|
90
90
|
{{ statusLabel(status) }}
|
|
@@ -94,18 +94,18 @@
|
|
|
94
94
|
</div>
|
|
95
95
|
|
|
96
96
|
<!-- Task List -->
|
|
97
|
-
<div class="bg-
|
|
98
|
-
<div class="px-6 py-6 border-b border-
|
|
99
|
-
<h2 class="text-xl font-bold text-
|
|
97
|
+
<div class="bg-surface rounded-lg shadow">
|
|
98
|
+
<div class="px-6 py-6 border-b border-edge flex items-center justify-between bg-page">
|
|
99
|
+
<h2 class="text-xl font-bold text-content">
|
|
100
100
|
Individual Tasks
|
|
101
|
-
<span v-if="currentFilter" class="ml-3 text-base font-semibold text-
|
|
101
|
+
<span v-if="currentFilter" class="ml-3 text-base font-semibold text-primary">
|
|
102
102
|
(Filtered by {{ currentFilter }})
|
|
103
103
|
</span>
|
|
104
104
|
</h2>
|
|
105
105
|
<button
|
|
106
106
|
v-if="currentFilter"
|
|
107
107
|
@click="clearFilter"
|
|
108
|
-
class="text-sm font-semibold text-
|
|
108
|
+
class="text-sm font-semibold text-primary hover:text-primary"
|
|
109
109
|
>
|
|
110
110
|
Show All
|
|
111
111
|
</button>
|
|
@@ -115,11 +115,11 @@
|
|
|
115
115
|
<div class="flex items-start justify-between">
|
|
116
116
|
<div class="flex-1">
|
|
117
117
|
<div class="flex items-center gap-3 mb-2">
|
|
118
|
-
<span class="text-sm font-medium text-
|
|
118
|
+
<span class="text-sm font-medium text-content">Task ID: {{ task.id }}</span>
|
|
119
119
|
<router-link
|
|
120
120
|
v-if="backTo"
|
|
121
121
|
:to="taskDetailRoute(task)"
|
|
122
|
-
class="text-sm text-
|
|
122
|
+
class="text-sm text-primary hover:text-primary font-medium"
|
|
123
123
|
>
|
|
124
124
|
View details
|
|
125
125
|
</router-link>
|
|
@@ -133,27 +133,27 @@
|
|
|
133
133
|
|
|
134
134
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
|
135
135
|
<div>
|
|
136
|
-
<label class="block text-sm font-medium text-
|
|
137
|
-
<div class="text-sm text-
|
|
136
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Scheduled At</label>
|
|
137
|
+
<div class="text-sm text-content">{{ formatDate(task.scheduledAt) }}</div>
|
|
138
138
|
</div>
|
|
139
139
|
<div v-if="task.startedAt">
|
|
140
|
-
<label class="block text-sm font-medium text-
|
|
141
|
-
<div class="text-sm text-
|
|
140
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Started At</label>
|
|
141
|
+
<div class="text-sm text-content">{{ formatDate(task.startedAt) }}</div>
|
|
142
142
|
</div>
|
|
143
143
|
<div v-if="task.completedAt">
|
|
144
|
-
<label class="block text-sm font-medium text-
|
|
145
|
-
<div class="text-sm text-
|
|
144
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Completed At</label>
|
|
145
|
+
<div class="text-sm text-content">{{ formatDate(task.completedAt) }}</div>
|
|
146
146
|
</div>
|
|
147
147
|
<div v-if="task.error">
|
|
148
|
-
<label class="block text-sm font-medium text-
|
|
148
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Error</label>
|
|
149
149
|
<div class="text-sm text-red-600">{{ task.error }}</div>
|
|
150
150
|
</div>
|
|
151
151
|
</div>
|
|
152
152
|
|
|
153
153
|
<!-- Task Parameters -->
|
|
154
154
|
<div v-if="task.parameters && Object.keys(task.parameters).length > 0">
|
|
155
|
-
<label class="block text-sm font-medium text-
|
|
156
|
-
<div class="bg-
|
|
155
|
+
<label class="block text-sm font-medium text-content-secondary mb-2">Parameters</label>
|
|
156
|
+
<div class="bg-page rounded-md p-3">
|
|
157
157
|
<pre class="text-sm text-gray-800 whitespace-pre-wrap">{{ JSON.stringify(task.parameters, null, 2) }}</pre>
|
|
158
158
|
</div>
|
|
159
159
|
</div>
|
|
@@ -208,26 +208,26 @@
|
|
|
208
208
|
</svg>
|
|
209
209
|
</div>
|
|
210
210
|
<div class="ml-3">
|
|
211
|
-
<h3 class="text-lg font-medium text-
|
|
211
|
+
<h3 class="text-lg font-medium text-content">Reschedule Task</h3>
|
|
212
212
|
</div>
|
|
213
213
|
</div>
|
|
214
214
|
<div class="mb-4">
|
|
215
215
|
<p class="text-sm text-gray-600">
|
|
216
216
|
Are you sure you want to reschedule task <strong>{{ selectedTask?.id }}</strong>?
|
|
217
217
|
</p>
|
|
218
|
-
<p class="text-sm text-
|
|
218
|
+
<p class="text-sm text-content-tertiary mt-2">
|
|
219
219
|
This will reset the task's status and schedule it to run again.
|
|
220
220
|
</p>
|
|
221
221
|
|
|
222
222
|
<div class="mt-4">
|
|
223
|
-
<label for="newScheduledTime" class="block text-sm font-medium text-
|
|
223
|
+
<label for="newScheduledTime" class="block text-sm font-medium text-content-secondary mb-2">
|
|
224
224
|
New Scheduled Time
|
|
225
225
|
</label>
|
|
226
226
|
<input
|
|
227
227
|
id="newScheduledTime"
|
|
228
228
|
v-model="newScheduledTime"
|
|
229
229
|
type="datetime-local"
|
|
230
|
-
class="w-full px-3 py-2 border border-
|
|
230
|
+
class="w-full px-3 py-2 border border-edge-strong rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
|
|
231
231
|
required
|
|
232
232
|
/>
|
|
233
233
|
</div>
|
|
@@ -241,7 +241,7 @@
|
|
|
241
241
|
</button>
|
|
242
242
|
<button
|
|
243
243
|
@click="showRescheduleModal = false"
|
|
244
|
-
class="flex-1 bg-gray-300 text-
|
|
244
|
+
class="flex-1 bg-gray-300 text-content-secondary px-4 py-2 rounded-md hover:bg-gray-400 font-medium"
|
|
245
245
|
>
|
|
246
246
|
Cancel
|
|
247
247
|
</button>
|
|
@@ -262,14 +262,14 @@
|
|
|
262
262
|
</svg>
|
|
263
263
|
</div>
|
|
264
264
|
<div class="ml-3">
|
|
265
|
-
<h3 class="text-lg font-medium text-
|
|
265
|
+
<h3 class="text-lg font-medium text-content">Run Task Now</h3>
|
|
266
266
|
</div>
|
|
267
267
|
</div>
|
|
268
268
|
<div class="mb-4">
|
|
269
269
|
<p class="text-sm text-gray-600">
|
|
270
270
|
Are you sure you want to run task <strong>{{ selectedTask?.id }}</strong> immediately?
|
|
271
271
|
</p>
|
|
272
|
-
<p class="text-sm text-
|
|
272
|
+
<p class="text-sm text-content-tertiary mt-2">
|
|
273
273
|
This will execute the task right away, bypassing its scheduled time.
|
|
274
274
|
</p>
|
|
275
275
|
</div>
|
|
@@ -282,7 +282,7 @@
|
|
|
282
282
|
</button>
|
|
283
283
|
<button
|
|
284
284
|
@click="showRunModal = false"
|
|
285
|
-
class="flex-1 bg-gray-300 text-
|
|
285
|
+
class="flex-1 bg-gray-300 text-content-secondary px-4 py-2 rounded-md hover:bg-gray-400 font-medium"
|
|
286
286
|
>
|
|
287
287
|
Cancel
|
|
288
288
|
</button>
|
|
@@ -303,14 +303,14 @@
|
|
|
303
303
|
</svg>
|
|
304
304
|
</div>
|
|
305
305
|
<div class="ml-3">
|
|
306
|
-
<h3 class="text-lg font-medium text-
|
|
306
|
+
<h3 class="text-lg font-medium text-content">Cancel Task</h3>
|
|
307
307
|
</div>
|
|
308
308
|
</div>
|
|
309
309
|
<div class="mb-4">
|
|
310
310
|
<p class="text-sm text-gray-600">
|
|
311
311
|
Are you sure you want to cancel task <strong>{{ selectedTask?.id }}</strong>?
|
|
312
312
|
</p>
|
|
313
|
-
<p class="text-sm text-
|
|
313
|
+
<p class="text-sm text-content-tertiary mt-2">
|
|
314
314
|
This will permanently cancel the task and it cannot be undone.
|
|
315
315
|
</p>
|
|
316
316
|
</div>
|
|
@@ -323,7 +323,7 @@
|
|
|
323
323
|
</button>
|
|
324
324
|
<button
|
|
325
325
|
@click="showCancelModal = false"
|
|
326
|
-
class="flex-1 bg-gray-300 text-
|
|
326
|
+
class="flex-1 bg-gray-300 text-content-secondary px-4 py-2 rounded-md hover:bg-gray-400 font-medium"
|
|
327
327
|
>
|
|
328
328
|
Keep Task
|
|
329
329
|
</button>
|
|
@@ -80,7 +80,7 @@ module.exports = app => app.component('task-details', {
|
|
|
80
80
|
requestAnimationFrame(() => this.ensureStatusChart());
|
|
81
81
|
});
|
|
82
82
|
}
|
|
83
|
-
}
|
|
83
|
+
}
|
|
84
84
|
},
|
|
85
85
|
methods: {
|
|
86
86
|
destroyStatusChart() {
|
|
@@ -117,6 +117,10 @@ module.exports = app => app.component('task-details', {
|
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
119
|
try {
|
|
120
|
+
const isDark = typeof document !== 'undefined' && document.documentElement.classList.contains('dark');
|
|
121
|
+
const legendColor = isDark
|
|
122
|
+
? (getComputedStyle(document.documentElement).getPropertyValue('--studio-text-primary')?.trim() || 'rgba(255,255,255,0.9)')
|
|
123
|
+
: undefined;
|
|
120
124
|
this.statusChart = new Chart(canvas, {
|
|
121
125
|
type: 'doughnut',
|
|
122
126
|
data,
|
|
@@ -136,7 +140,8 @@ module.exports = app => app.component('task-details', {
|
|
|
136
140
|
plugins: {
|
|
137
141
|
legend: {
|
|
138
142
|
display: true,
|
|
139
|
-
position: 'bottom'
|
|
143
|
+
position: 'bottom',
|
|
144
|
+
...(legendColor && { labels: { color: legendColor } })
|
|
140
145
|
}
|
|
141
146
|
}
|
|
142
147
|
}
|