@mongoosejs/studio 0.2.13 → 0.3.1
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 +4 -1
- package/backend/actions/ChatThread/streamChatMessage.js +4 -2
- package/backend/actions/Dashboard/updateDashboard.js +2 -2
- package/backend/actions/Task/getTaskOverview.js +102 -0
- package/backend/actions/Task/getTasks.js +85 -45
- package/backend/actions/Task/index.js +1 -0
- package/eslint.config.js +4 -1
- package/frontend/public/app.js +25025 -762
- 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 +348 -213
- package/frontend/src/_util/dateRange.js +82 -0
- package/frontend/src/ace-editor/ace-editor.html +4 -0
- package/frontend/src/ace-editor/ace-editor.js +95 -0
- package/frontend/src/aceEditor.js +69 -0
- package/frontend/src/api.js +6 -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 +54 -42
- package/frontend/src/chat/chat-message-script/chat-message-script.js +6 -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 +21 -4
- package/frontend/src/dashboard/edit-dashboard/edit-dashboard.html +13 -7
- package/frontend/src/dashboard/edit-dashboard/edit-dashboard.js +16 -23
- 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/dashboard-result/dashboard-result.js +3 -0
- package/frontend/src/dashboard-result/dashboard-table/dashboard-table.html +34 -0
- package/frontend/src/dashboard-result/dashboard-table/dashboard-table.js +37 -0
- 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 +116 -7
- 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-by-name/task-by-name.html +77 -7
- package/frontend/src/task-by-name/task-by-name.js +84 -9
- 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 +43 -43
- package/frontend/src/tasks/task-details/task-details.js +9 -3
- package/frontend/src/tasks/tasks.html +36 -35
- package/frontend/src/tasks/tasks.js +27 -143
- 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 +3 -1
- package/tailwind.config.js +75 -11
|
@@ -1,41 +1,41 @@
|
|
|
1
1
|
<div class="p-4 space-y-6">
|
|
2
2
|
<div>
|
|
3
|
-
<h1 class="text-2xl font-bold text-
|
|
3
|
+
<h1 class="text-2xl font-bold text-content-secondary mb-4">Task Overview</h1>
|
|
4
4
|
<div v-if="status == 'init'">
|
|
5
5
|
<img src="images/loader.gif" />
|
|
6
6
|
</div>
|
|
7
7
|
<!-- Task List -->
|
|
8
|
-
<div class="bg-
|
|
8
|
+
<div class="bg-surface p-4 rounded-lg shadow" v-if="status == 'loaded'">
|
|
9
9
|
<div class="mb-4">
|
|
10
|
-
<label class="block text-sm font-medium text-
|
|
11
|
-
<select v-model="selectedRange" @change="updateDateRange" class="border-
|
|
10
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Filter by Date:</label>
|
|
11
|
+
<select v-model="selectedRange" @change="updateDateRange" class="border-edge-strong rounded-md shadow-sm w-full p-2">
|
|
12
12
|
<option v-for="option in dateFilters" :key="option.value" :value="option.value">
|
|
13
13
|
{{ option.label }}
|
|
14
14
|
</option>
|
|
15
15
|
</select>
|
|
16
16
|
</div>
|
|
17
17
|
<div class="mb-4">
|
|
18
|
-
<label class="block text-sm font-medium text-
|
|
19
|
-
<select v-model="selectedStatus" @change="getTasks" class="border-
|
|
18
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Filter by Status:</label>
|
|
19
|
+
<select v-model="selectedStatus" @change="getTasks" class="border-edge-strong rounded-md shadow-sm w-full p-2">
|
|
20
20
|
<option v-for="option in statusFilters" :key="option.value" :value="option.value">
|
|
21
21
|
{{ option.label }}
|
|
22
22
|
</option>
|
|
23
23
|
</select>
|
|
24
24
|
</div>
|
|
25
25
|
<div class="mb-4">
|
|
26
|
-
<label class="block text-sm font-medium text-
|
|
26
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Search by Task Name:</label>
|
|
27
27
|
<input
|
|
28
28
|
v-model="searchQuery"
|
|
29
29
|
type="text"
|
|
30
30
|
@input="onSearchInput"
|
|
31
|
-
class="border-
|
|
31
|
+
class="border-edge-strong rounded-md shadow-sm w-full p-2"
|
|
32
32
|
placeholder="Enter task name to search..."
|
|
33
33
|
>
|
|
34
34
|
</div>
|
|
35
35
|
<div class="mb-4">
|
|
36
36
|
<button
|
|
37
37
|
@click="resetFilters"
|
|
38
|
-
class="w-full bg-gray-200 text-
|
|
38
|
+
class="w-full bg-gray-200 text-content-secondary hover:bg-gray-300 font-medium py-2 px-4 rounded-md transition"
|
|
39
39
|
>
|
|
40
40
|
Reset Filters
|
|
41
41
|
</button>
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
<div class="mb-6">
|
|
44
44
|
<button
|
|
45
45
|
@click="openCreateTaskModal"
|
|
46
|
-
class="w-full bg-
|
|
46
|
+
class="w-full bg-primary text-primary-text hover:bg-primary-hover font-medium py-2 px-4 rounded-md transition"
|
|
47
47
|
>
|
|
48
48
|
Create New Task
|
|
49
49
|
</button>
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
</button>
|
|
74
74
|
<button
|
|
75
75
|
@click="setStatusFilter('cancelled')"
|
|
76
|
-
:class="getStatusColor('cancelled') + ' p-4 rounded-lg shadow-lg hover:shadow-xl transform hover:-translate-y-1 transition-all duration-200 cursor-pointer border-2 border-
|
|
76
|
+
:class="getStatusColor('cancelled') + ' p-4 rounded-lg shadow-lg hover:shadow-xl transform hover:-translate-y-1 transition-all duration-200 cursor-pointer border-2 border-edge hover:border-edge-strong'"
|
|
77
77
|
>
|
|
78
78
|
<div class="text-sm">Cancelled</div>
|
|
79
79
|
<div class="text-2xl font-bold">{{cancelledCount}}</div>
|
|
@@ -82,23 +82,23 @@
|
|
|
82
82
|
|
|
83
83
|
<!-- Grouped Task List -->
|
|
84
84
|
<div class="mt-6">
|
|
85
|
-
<h2 class="text-lg font-semibold text-
|
|
85
|
+
<h2 class="text-lg font-semibold text-content-secondary mb-4">Tasks by Name</h2>
|
|
86
86
|
<ul class="divide-y divide-gray-200">
|
|
87
87
|
<li v-for="group in tasksByName" :key="group.name" class="p-4 group hover:border hover:rounded-lg hover:shadow-xl transform hover:-translate-y-1 transition-all duration-200">
|
|
88
88
|
<div class="flex items-center justify-between mb-3 ">
|
|
89
89
|
<div class="flex-1 cursor-pointer" @click="openTaskGroupDetails(group)">
|
|
90
90
|
<div class="flex items-center gap-2">
|
|
91
|
-
<div class="font-medium text-lg group-hover:text-
|
|
92
|
-
<svg class="w-4 h-4 text-gray-400 group-hover:text-
|
|
91
|
+
<div class="font-medium text-lg group-hover:text-primary transition-colors">{{ group.name }}</div>
|
|
92
|
+
<svg class="w-4 h-4 text-gray-400 group-hover:text-primary transition-colors" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
93
93
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
|
|
94
94
|
</svg>
|
|
95
95
|
</div>
|
|
96
|
-
<div class="text-sm text-
|
|
97
|
-
<div class="text-xs text-
|
|
96
|
+
<div class="text-sm text-content-tertiary group-hover:text-content-secondary transition-colors">Total: {{ group.totalCount }} tasks</div>
|
|
97
|
+
<div class="text-xs text-primary opacity-0 group-hover:opacity-100 transition-opacity mt-1">
|
|
98
98
|
Click to view details
|
|
99
99
|
</div>
|
|
100
100
|
</div>
|
|
101
|
-
<div class="text-sm text-
|
|
101
|
+
<div class="text-sm text-content-tertiary">
|
|
102
102
|
Last run: {{ group.lastRun ? new Date(group.lastRun).toLocaleString() : 'Never' }}
|
|
103
103
|
</div>
|
|
104
104
|
</div>
|
|
@@ -128,10 +128,10 @@
|
|
|
128
128
|
</button>
|
|
129
129
|
<button
|
|
130
130
|
@click.stop="openTaskGroupDetailsWithFilter(group, 'cancelled')"
|
|
131
|
-
class="bg-
|
|
131
|
+
class="bg-page border border-edge rounded-md p-2 text-center shadow-sm hover:shadow-md transform hover:-translate-y-1 transition-all duration-200 cursor-pointer hover:border-edge-strong"
|
|
132
132
|
>
|
|
133
133
|
<div class="text-xs text-gray-600 font-medium">Cancelled</div>
|
|
134
|
-
<div class="text-lg font-bold text-
|
|
134
|
+
<div class="text-lg font-bold text-content-secondary">{{ group.statusCounts.cancelled || 0 }}</div>
|
|
135
135
|
</button>
|
|
136
136
|
</div>
|
|
137
137
|
</li>
|
|
@@ -145,59 +145,60 @@
|
|
|
145
145
|
<template #body>
|
|
146
146
|
<div class="absolute font-mono right-1 top-1 cursor-pointer text-xl" @click="closeCreateTaskModal" role="button" aria-label="Close modal">×</div>
|
|
147
147
|
<div class="space-y-4">
|
|
148
|
-
<h3 class="text-lg font-semibold text-
|
|
148
|
+
<h3 class="text-lg font-semibold text-content-secondary mb-4">Create New Task</h3>
|
|
149
149
|
|
|
150
150
|
<div>
|
|
151
|
-
<label class="block text-sm font-medium text-
|
|
151
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Task Name:</label>
|
|
152
152
|
<input
|
|
153
153
|
v-model="newTask.name"
|
|
154
154
|
type="text"
|
|
155
|
-
class="w-full border border-
|
|
155
|
+
class="w-full border border-edge-strong rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"
|
|
156
156
|
placeholder="Enter task name"
|
|
157
157
|
>
|
|
158
158
|
</div>
|
|
159
159
|
|
|
160
160
|
<div>
|
|
161
|
-
<label class="block text-sm font-medium text-
|
|
161
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Scheduled Time:</label>
|
|
162
162
|
<input
|
|
163
163
|
v-model="newTask.scheduledAt"
|
|
164
164
|
type="datetime-local"
|
|
165
|
-
class="w-full border border-
|
|
165
|
+
class="w-full border border-edge-strong rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"
|
|
166
166
|
>
|
|
167
167
|
</div>
|
|
168
168
|
|
|
169
169
|
<div>
|
|
170
|
-
<label class="block text-sm font-medium text-
|
|
171
|
-
<
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
170
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Parameters (JSON):</label>
|
|
171
|
+
<ace-editor
|
|
172
|
+
v-model="newTask.parameters"
|
|
173
|
+
mode="json"
|
|
174
|
+
:line-numbers="true"
|
|
175
|
+
class="min-h-[120px]"
|
|
176
|
+
/>
|
|
176
177
|
</div>
|
|
177
178
|
|
|
178
179
|
<div>
|
|
179
|
-
<label class="block text-sm font-medium text-
|
|
180
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Repeat Interval (ms):</label>
|
|
180
181
|
<input
|
|
181
182
|
v-model="newTask.repeatInterval"
|
|
182
183
|
type="number"
|
|
183
184
|
min="0"
|
|
184
185
|
step="1000"
|
|
185
|
-
class="w-full border border-
|
|
186
|
+
class="w-full border border-edge-strong rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-primary"
|
|
186
187
|
placeholder="0 for no repetition"
|
|
187
188
|
>
|
|
188
|
-
<p class="text-xs text-
|
|
189
|
+
<p class="text-xs text-content-tertiary mt-1">Enter 0 or leave empty for no repetition. Use 1000 for 1 second, 60000 for 1 minute, etc.</p>
|
|
189
190
|
</div>
|
|
190
191
|
|
|
191
192
|
<div class="flex gap-2 pt-4">
|
|
192
193
|
<button
|
|
193
194
|
@click="createTask"
|
|
194
|
-
class="flex-1 bg-
|
|
195
|
+
class="flex-1 bg-primary text-primary-text px-4 py-2 rounded-md hover:bg-primary-hover"
|
|
195
196
|
>
|
|
196
197
|
Create Task
|
|
197
198
|
</button>
|
|
198
199
|
<button
|
|
199
200
|
@click="closeCreateTaskModal"
|
|
200
|
-
class="flex-1 bg-gray-300 text-
|
|
201
|
+
class="flex-1 bg-gray-300 text-content-secondary px-4 py-2 rounded-md hover:bg-gray-400"
|
|
201
202
|
>
|
|
202
203
|
Cancel
|
|
203
204
|
</button>
|
|
@@ -2,25 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
const template = require('./tasks.html');
|
|
4
4
|
const api = require('../api');
|
|
5
|
+
const { DATE_FILTERS, getDateRangeForRange } = require('../_util/dateRange');
|
|
5
6
|
|
|
6
7
|
module.exports = app => app.component('tasks', {
|
|
7
8
|
data: () => ({
|
|
8
9
|
status: 'init',
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
statusCounts: { pending: 0, succeeded: 0, failed: 0, cancelled: 0 },
|
|
11
|
+
tasksByName: [],
|
|
11
12
|
selectedRange: 'last_hour',
|
|
12
13
|
start: null,
|
|
13
14
|
end: null,
|
|
14
|
-
dateFilters:
|
|
15
|
-
{ value: 'all', label: 'All Time' },
|
|
16
|
-
{ value: 'last_hour', label: 'Last Hour' },
|
|
17
|
-
{ value: 'today', label: 'Today' },
|
|
18
|
-
{ value: 'yesterday', label: 'Yesterday' },
|
|
19
|
-
{ value: 'thisWeek', label: 'This Week' },
|
|
20
|
-
{ value: 'lastWeek', label: 'Last Week' },
|
|
21
|
-
{ value: 'thisMonth', label: 'This Month' },
|
|
22
|
-
{ value: 'lastMonth', label: 'Last Month' }
|
|
23
|
-
],
|
|
15
|
+
dateFilters: DATE_FILTERS,
|
|
24
16
|
selectedStatus: 'all',
|
|
25
17
|
statusFilters: [
|
|
26
18
|
{ label: 'All', value: 'all' },
|
|
@@ -39,8 +31,7 @@ module.exports = app => app.component('tasks', {
|
|
|
39
31
|
scheduledAt: '',
|
|
40
32
|
parameters: '',
|
|
41
33
|
repeatInterval: ''
|
|
42
|
-
}
|
|
43
|
-
parametersEditor: null
|
|
34
|
+
}
|
|
44
35
|
}),
|
|
45
36
|
methods: {
|
|
46
37
|
async getTasks() {
|
|
@@ -51,26 +42,31 @@ module.exports = app => app.component('tasks', {
|
|
|
51
42
|
params.status = this.selectedStatus;
|
|
52
43
|
}
|
|
53
44
|
|
|
54
|
-
if (this.start && this.end) {
|
|
55
|
-
params.start = this.start;
|
|
56
|
-
params.end = this.end;
|
|
57
|
-
} else if (this.start) {
|
|
58
|
-
params.start = this.start;
|
|
45
|
+
if (this.start != null && this.end != null) {
|
|
46
|
+
params.start = this.start instanceof Date ? this.start.toISOString() : this.start;
|
|
47
|
+
params.end = this.end instanceof Date ? this.end.toISOString() : this.end;
|
|
48
|
+
} else if (this.start != null) {
|
|
49
|
+
params.start = this.start instanceof Date ? this.start.toISOString() : this.start;
|
|
59
50
|
}
|
|
60
51
|
|
|
61
52
|
if (this.searchQuery.trim()) {
|
|
62
53
|
params.name = this.searchQuery.trim();
|
|
63
54
|
}
|
|
64
55
|
|
|
65
|
-
const {
|
|
66
|
-
this.
|
|
67
|
-
this.
|
|
56
|
+
const { statusCounts, tasksByName } = await api.Task.getTaskOverview(params);
|
|
57
|
+
this.statusCounts = statusCounts || this.statusCounts;
|
|
58
|
+
this.tasksByName = tasksByName || [];
|
|
68
59
|
},
|
|
69
60
|
openTaskGroupDetails(group) {
|
|
70
|
-
|
|
61
|
+
const query = { dateRange: this.selectedRange || 'last_hour' };
|
|
62
|
+
if (this.selectedStatus && this.selectedStatus !== 'all') query.status = this.selectedStatus;
|
|
63
|
+
this.$router.push({ path: `/tasks/${encodeURIComponent(group.name || '')}`, query });
|
|
71
64
|
},
|
|
72
65
|
openTaskGroupDetailsWithFilter(group, status) {
|
|
73
|
-
|
|
66
|
+
const query = { dateRange: this.selectedRange || 'last_hour' };
|
|
67
|
+
if (status) query.status = status;
|
|
68
|
+
else if (this.selectedStatus && this.selectedStatus !== 'all') query.status = this.selectedStatus;
|
|
69
|
+
this.$router.push({ path: `/tasks/${encodeURIComponent(group.name || '')}`, query });
|
|
74
70
|
},
|
|
75
71
|
async onTaskCreated() {
|
|
76
72
|
// Refresh the task data when a new task is created
|
|
@@ -83,7 +79,7 @@ module.exports = app => app.component('tasks', {
|
|
|
83
79
|
async createTask() {
|
|
84
80
|
try {
|
|
85
81
|
let parameters = {};
|
|
86
|
-
const parametersText = this.
|
|
82
|
+
const parametersText = this.newTask.parameters || '';
|
|
87
83
|
if (parametersText.trim()) {
|
|
88
84
|
try {
|
|
89
85
|
parameters = JSON.parse(parametersText);
|
|
@@ -160,9 +156,6 @@ module.exports = app => app.component('tasks', {
|
|
|
160
156
|
parameters: '',
|
|
161
157
|
repeatInterval: ''
|
|
162
158
|
};
|
|
163
|
-
if (this.parametersEditor) {
|
|
164
|
-
this.parametersEditor.setValue('');
|
|
165
|
-
}
|
|
166
159
|
},
|
|
167
160
|
setDefaultCreateTaskValues() {
|
|
168
161
|
// Set default scheduled time to 1 hour from now
|
|
@@ -175,21 +168,8 @@ module.exports = app => app.component('tasks', {
|
|
|
175
168
|
this.resetCreateTaskForm();
|
|
176
169
|
this.setDefaultCreateTaskValues();
|
|
177
170
|
},
|
|
178
|
-
initializeParametersEditor() {
|
|
179
|
-
if (this.$refs.parametersEditor && !this.parametersEditor) {
|
|
180
|
-
this.parametersEditor = CodeMirror.fromTextArea(this.$refs.parametersEditor, {
|
|
181
|
-
mode: 'javascript',
|
|
182
|
-
lineNumbers: true,
|
|
183
|
-
smartIndent: false,
|
|
184
|
-
theme: 'default'
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
},
|
|
188
171
|
openCreateTaskModal() {
|
|
189
172
|
this.showCreateTaskModal = true;
|
|
190
|
-
this.$nextTick(() => {
|
|
191
|
-
this.initializeParametersEditor();
|
|
192
|
-
});
|
|
193
173
|
},
|
|
194
174
|
getStatusColor(status) {
|
|
195
175
|
if (status === 'succeeded') {
|
|
@@ -230,114 +210,24 @@ module.exports = app => app.component('tasks', {
|
|
|
230
210
|
}, 300);
|
|
231
211
|
},
|
|
232
212
|
async updateDateRange() {
|
|
233
|
-
const
|
|
234
|
-
let start, end;
|
|
235
|
-
|
|
236
|
-
switch (this.selectedRange) {
|
|
237
|
-
case 'last_hour':
|
|
238
|
-
start = new Date();
|
|
239
|
-
start.setHours(start.getHours() - 1);
|
|
240
|
-
end = new Date();
|
|
241
|
-
break;
|
|
242
|
-
case 'today':
|
|
243
|
-
start = new Date();
|
|
244
|
-
start.setHours(0, 0, 0, 0);
|
|
245
|
-
end = new Date();
|
|
246
|
-
end.setHours(23, 59, 59, 999);
|
|
247
|
-
break;
|
|
248
|
-
case 'yesterday':
|
|
249
|
-
start = new Date();
|
|
250
|
-
start.setDate(start.getDate() - 1);
|
|
251
|
-
start.setHours(0, 0, 0, 0);
|
|
252
|
-
end = new Date();
|
|
253
|
-
break;
|
|
254
|
-
case 'thisWeek':
|
|
255
|
-
start = new Date(now.getTime() - (7 * 86400000));
|
|
256
|
-
start.setHours(0, 0, 0, 0);
|
|
257
|
-
end = new Date();
|
|
258
|
-
end.setHours(23, 59, 59, 999);
|
|
259
|
-
break;
|
|
260
|
-
case 'lastWeek':
|
|
261
|
-
start = new Date(now.getTime() - (14 * 86400000));
|
|
262
|
-
start.setHours(0, 0, 0, 0);
|
|
263
|
-
end = new Date(now.getTime() - (7 * 86400000));
|
|
264
|
-
end.setHours(23, 59, 59, 999);
|
|
265
|
-
break;
|
|
266
|
-
case 'thisMonth':
|
|
267
|
-
start = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
268
|
-
end = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999);
|
|
269
|
-
break;
|
|
270
|
-
case 'lastMonth':
|
|
271
|
-
start = new Date(now.getFullYear(), now.getMonth() - 1, 1);
|
|
272
|
-
end = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59, 999);
|
|
273
|
-
break;
|
|
274
|
-
case 'all':
|
|
275
|
-
default:
|
|
276
|
-
this.start = null;
|
|
277
|
-
this.end = null;
|
|
278
|
-
break;
|
|
279
|
-
}
|
|
280
|
-
|
|
213
|
+
const { start, end } = getDateRangeForRange(this.selectedRange);
|
|
281
214
|
this.start = start;
|
|
282
215
|
this.end = end;
|
|
283
|
-
|
|
284
216
|
await this.getTasks();
|
|
285
217
|
}
|
|
286
218
|
},
|
|
287
219
|
computed: {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
// Process tasks from groupedTasks to create name-based groups
|
|
292
|
-
Object.entries(this.groupedTasks).forEach(([status, tasks]) => {
|
|
293
|
-
tasks.forEach(task => {
|
|
294
|
-
if (!groups[task.name]) {
|
|
295
|
-
groups[task.name] = {
|
|
296
|
-
name: task.name,
|
|
297
|
-
tasks: [],
|
|
298
|
-
statusCounts: {
|
|
299
|
-
pending: 0,
|
|
300
|
-
succeeded: 0,
|
|
301
|
-
failed: 0,
|
|
302
|
-
cancelled: 0
|
|
303
|
-
},
|
|
304
|
-
totalCount: 0,
|
|
305
|
-
lastRun: null
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
groups[task.name].tasks.push(task);
|
|
310
|
-
groups[task.name].totalCount++;
|
|
311
|
-
|
|
312
|
-
// Count status using the status from groupedTasks
|
|
313
|
-
if (groups[task.name].statusCounts.hasOwnProperty(status)) {
|
|
314
|
-
groups[task.name].statusCounts[status]++;
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Track last run time
|
|
318
|
-
const taskTime = new Date(task.scheduledAt || task.createdAt || 0);
|
|
319
|
-
if (!groups[task.name].lastRun || taskTime > new Date(groups[task.name].lastRun)) {
|
|
320
|
-
groups[task.name].lastRun = taskTime;
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
// Convert to array and sort alphabetically by name
|
|
326
|
-
return Object.values(groups).sort((a, b) => {
|
|
327
|
-
return a.name.localeCompare(b.name);
|
|
328
|
-
});
|
|
220
|
+
pendingCount() {
|
|
221
|
+
return this.statusCounts.pending || 0;
|
|
329
222
|
},
|
|
330
223
|
succeededCount() {
|
|
331
|
-
return this.
|
|
224
|
+
return this.statusCounts.succeeded || 0;
|
|
332
225
|
},
|
|
333
226
|
failedCount() {
|
|
334
|
-
return this.
|
|
227
|
+
return this.statusCounts.failed || 0;
|
|
335
228
|
},
|
|
336
229
|
cancelledCount() {
|
|
337
|
-
return this.
|
|
338
|
-
},
|
|
339
|
-
pendingCount() {
|
|
340
|
-
return this.groupedTasks.pending ? this.groupedTasks.pending.length : 0;
|
|
230
|
+
return this.statusCounts.cancelled || 0;
|
|
341
231
|
}
|
|
342
232
|
},
|
|
343
233
|
mounted: async function() {
|
|
@@ -346,11 +236,5 @@ module.exports = app => app.component('tasks', {
|
|
|
346
236
|
this.status = 'loaded';
|
|
347
237
|
this.setDefaultCreateTaskValues();
|
|
348
238
|
},
|
|
349
|
-
beforeDestroy() {
|
|
350
|
-
if (this.parametersEditor) {
|
|
351
|
-
this.parametersEditor.toTextArea();
|
|
352
|
-
}
|
|
353
|
-
},
|
|
354
|
-
|
|
355
239
|
template: template
|
|
356
240
|
});
|
|
@@ -5,33 +5,33 @@
|
|
|
5
5
|
</div>
|
|
6
6
|
|
|
7
7
|
<div>
|
|
8
|
-
<label for="githubUsername" class="block text-sm/6 font-medium text-
|
|
8
|
+
<label for="githubUsername" class="block text-sm/6 font-medium text-content">GitHub Username</label>
|
|
9
9
|
<div class="mt-2">
|
|
10
|
-
<input type="githubUsername" name="githubUsername" id="githubUsername" v-model="githubUsername" class="block w-full rounded-md bg-
|
|
10
|
+
<input type="githubUsername" name="githubUsername" id="githubUsername" v-model="githubUsername" class="block w-full rounded-md bg-surface px-3 py-1.5 text-base text-content outline outline-1 -outline-offset-1 outline-edge-strong placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-primary sm:text-sm/6" placeholder="johnsmith12">
|
|
11
11
|
</div>
|
|
12
12
|
</div>
|
|
13
13
|
|
|
14
14
|
<div>
|
|
15
|
-
<label for="email" class="block text-sm/6 font-medium text-
|
|
15
|
+
<label for="email" class="block text-sm/6 font-medium text-content">Email (Optional)</label>
|
|
16
16
|
<div class="mt-2">
|
|
17
|
-
<input type="email" name="email" id="email" v-model="email" class="block w-full rounded-md bg-
|
|
17
|
+
<input type="email" name="email" id="email" v-model="email" class="block w-full rounded-md bg-surface px-3 py-1.5 text-base text-content outline outline-1 -outline-offset-1 outline-edge-strong placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-primary sm:text-sm/6" placeholder="you@example.com">
|
|
18
18
|
</div>
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
<div>
|
|
22
|
-
<label for="location" class="block text-sm/6 font-medium text-
|
|
22
|
+
<label for="location" class="block text-sm/6 font-medium text-content">Role</label>
|
|
23
23
|
<div class="mt-2 grid grid-cols-1">
|
|
24
|
-
<select id="role" :disabled="tier == null" name="role" v-model="role" class="col-start-1 row-start-1 w-full appearance-none rounded-md bg-
|
|
24
|
+
<select id="role" :disabled="tier == null" name="role" v-model="role" class="col-start-1 row-start-1 w-full appearance-none rounded-md bg-surface py-1.5 pl-3 pr-8 text-base text-content outline outline-1 -outline-offset-1 outline-edge-strong focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
|
|
25
25
|
<option value="admin">Admin</option>
|
|
26
26
|
<option value="member">Member</option>
|
|
27
27
|
<option value="readonly">Read-only</option>
|
|
28
28
|
<option value="dashboards">Dashboards Only</option>
|
|
29
29
|
</select>
|
|
30
|
-
<svg class="pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-
|
|
30
|
+
<svg class="pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-content-tertiary sm:size-4" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" data-slot="icon">
|
|
31
31
|
<path fill-rule="evenodd" d="M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
|
|
32
32
|
</svg>
|
|
33
33
|
</div>
|
|
34
|
-
<div v-if="tier == null" class="text-sm text-
|
|
34
|
+
<div v-if="tier == null" class="text-sm text-content-secondary">
|
|
35
35
|
You can only invite "Dashboards Only" users until you set up a subscription.
|
|
36
36
|
</div>
|
|
37
37
|
</div>
|