@mongoosejs/studio 0.2.12 → 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/backend/actions/Model/getEstimatedDocumentCounts.js +38 -0
- package/backend/actions/Model/index.js +1 -0
- package/backend/actions/Model/streamDocumentChanges.js +8 -7
- package/backend/actions/Task/getTasks.js +9 -6
- package/backend/authorize.js +1 -0
- package/backend/index.js +11 -3
- package/eslint.config.js +5 -1
- package/express.js +1 -0
- package/frontend/public/app.js +25235 -662
- 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 +461 -239
- 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/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 +51 -34
- package/frontend/src/chat/chat-message-script/chat-message-script.js +12 -55
- package/frontend/src/chat/chat.html +72 -37
- 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 +53 -27
- package/frontend/src/document/document.js +27 -1
- 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 -74
- package/frontend/src/models/models.js +142 -4
- package/frontend/src/navbar/navbar.html +157 -97
- package/frontend/src/navbar/navbar.js +32 -13
- package/frontend/src/routes.js +20 -4
- package/frontend/src/splash/splash.html +5 -5
- package/frontend/src/task-by-name/task-by-name.html +15 -0
- package/frontend/src/task-by-name/task-by-name.js +78 -0
- package/frontend/src/task-single/task-single.html +157 -0
- package/frontend/src/task-single/task-single.js +116 -0
- package/frontend/src/tasks/task-details/task-details.html +124 -73
- package/frontend/src/tasks/task-details/task-details.js +166 -10
- package/frontend/src/tasks/tasks.html +37 -48
- package/frontend/src/tasks/tasks.js +11 -50
- 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,53 +1,41 @@
|
|
|
1
1
|
<div class="p-4 space-y-6">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
v-if="showTaskDetails && selectedTaskGroup"
|
|
5
|
-
:task-group="selectedTaskGroup"
|
|
6
|
-
:current-filter="taskDetailsFilter"
|
|
7
|
-
@back="hideTaskDetails"
|
|
8
|
-
@task-created="onTaskCreated"
|
|
9
|
-
@task-cancelled="onTaskCancelled"
|
|
10
|
-
@update:current-filter="taskDetailsFilter = $event"
|
|
11
|
-
></task-details>
|
|
12
|
-
|
|
13
|
-
<!-- Main Tasks View -->
|
|
14
|
-
<div v-else>
|
|
15
|
-
<h1 class="text-2xl font-bold text-gray-700 mb-4">Task Overview</h1>
|
|
2
|
+
<div>
|
|
3
|
+
<h1 class="text-2xl font-bold text-content-secondary mb-4">Task Overview</h1>
|
|
16
4
|
<div v-if="status == 'init'">
|
|
17
5
|
<img src="images/loader.gif" />
|
|
18
6
|
</div>
|
|
19
7
|
<!-- Task List -->
|
|
20
|
-
<div class="bg-
|
|
8
|
+
<div class="bg-surface p-4 rounded-lg shadow" v-if="status == 'loaded'">
|
|
21
9
|
<div class="mb-4">
|
|
22
|
-
<label class="block text-sm font-medium text-
|
|
23
|
-
<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">
|
|
24
12
|
<option v-for="option in dateFilters" :key="option.value" :value="option.value">
|
|
25
13
|
{{ option.label }}
|
|
26
14
|
</option>
|
|
27
15
|
</select>
|
|
28
16
|
</div>
|
|
29
17
|
<div class="mb-4">
|
|
30
|
-
<label class="block text-sm font-medium text-
|
|
31
|
-
<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">
|
|
32
20
|
<option v-for="option in statusFilters" :key="option.value" :value="option.value">
|
|
33
21
|
{{ option.label }}
|
|
34
22
|
</option>
|
|
35
23
|
</select>
|
|
36
24
|
</div>
|
|
37
25
|
<div class="mb-4">
|
|
38
|
-
<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>
|
|
39
27
|
<input
|
|
40
28
|
v-model="searchQuery"
|
|
41
29
|
type="text"
|
|
42
30
|
@input="onSearchInput"
|
|
43
|
-
class="border-
|
|
31
|
+
class="border-edge-strong rounded-md shadow-sm w-full p-2"
|
|
44
32
|
placeholder="Enter task name to search..."
|
|
45
33
|
>
|
|
46
34
|
</div>
|
|
47
35
|
<div class="mb-4">
|
|
48
36
|
<button
|
|
49
37
|
@click="resetFilters"
|
|
50
|
-
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"
|
|
51
39
|
>
|
|
52
40
|
Reset Filters
|
|
53
41
|
</button>
|
|
@@ -55,7 +43,7 @@
|
|
|
55
43
|
<div class="mb-6">
|
|
56
44
|
<button
|
|
57
45
|
@click="openCreateTaskModal"
|
|
58
|
-
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"
|
|
59
47
|
>
|
|
60
48
|
Create New Task
|
|
61
49
|
</button>
|
|
@@ -85,7 +73,7 @@
|
|
|
85
73
|
</button>
|
|
86
74
|
<button
|
|
87
75
|
@click="setStatusFilter('cancelled')"
|
|
88
|
-
: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'"
|
|
89
77
|
>
|
|
90
78
|
<div class="text-sm">Cancelled</div>
|
|
91
79
|
<div class="text-2xl font-bold">{{cancelledCount}}</div>
|
|
@@ -94,23 +82,23 @@
|
|
|
94
82
|
|
|
95
83
|
<!-- Grouped Task List -->
|
|
96
84
|
<div class="mt-6">
|
|
97
|
-
<h2 class="text-lg font-semibold text-
|
|
85
|
+
<h2 class="text-lg font-semibold text-content-secondary mb-4">Tasks by Name</h2>
|
|
98
86
|
<ul class="divide-y divide-gray-200">
|
|
99
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">
|
|
100
88
|
<div class="flex items-center justify-between mb-3 ">
|
|
101
89
|
<div class="flex-1 cursor-pointer" @click="openTaskGroupDetails(group)">
|
|
102
90
|
<div class="flex items-center gap-2">
|
|
103
|
-
<div class="font-medium text-lg group-hover:text-
|
|
104
|
-
<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">
|
|
105
93
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
|
|
106
94
|
</svg>
|
|
107
95
|
</div>
|
|
108
|
-
<div class="text-sm text-
|
|
109
|
-
<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">
|
|
110
98
|
Click to view details
|
|
111
99
|
</div>
|
|
112
100
|
</div>
|
|
113
|
-
<div class="text-sm text-
|
|
101
|
+
<div class="text-sm text-content-tertiary">
|
|
114
102
|
Last run: {{ group.lastRun ? new Date(group.lastRun).toLocaleString() : 'Never' }}
|
|
115
103
|
</div>
|
|
116
104
|
</div>
|
|
@@ -140,10 +128,10 @@
|
|
|
140
128
|
</button>
|
|
141
129
|
<button
|
|
142
130
|
@click.stop="openTaskGroupDetailsWithFilter(group, 'cancelled')"
|
|
143
|
-
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"
|
|
144
132
|
>
|
|
145
133
|
<div class="text-xs text-gray-600 font-medium">Cancelled</div>
|
|
146
|
-
<div class="text-lg font-bold text-
|
|
134
|
+
<div class="text-lg font-bold text-content-secondary">{{ group.statusCounts.cancelled || 0 }}</div>
|
|
147
135
|
</button>
|
|
148
136
|
</div>
|
|
149
137
|
</li>
|
|
@@ -157,59 +145,60 @@
|
|
|
157
145
|
<template #body>
|
|
158
146
|
<div class="absolute font-mono right-1 top-1 cursor-pointer text-xl" @click="closeCreateTaskModal" role="button" aria-label="Close modal">×</div>
|
|
159
147
|
<div class="space-y-4">
|
|
160
|
-
<h3 class="text-lg font-semibold text-
|
|
148
|
+
<h3 class="text-lg font-semibold text-content-secondary mb-4">Create New Task</h3>
|
|
161
149
|
|
|
162
150
|
<div>
|
|
163
|
-
<label class="block text-sm font-medium text-
|
|
151
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Task Name:</label>
|
|
164
152
|
<input
|
|
165
153
|
v-model="newTask.name"
|
|
166
154
|
type="text"
|
|
167
|
-
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"
|
|
168
156
|
placeholder="Enter task name"
|
|
169
157
|
>
|
|
170
158
|
</div>
|
|
171
159
|
|
|
172
160
|
<div>
|
|
173
|
-
<label class="block text-sm font-medium text-
|
|
161
|
+
<label class="block text-sm font-medium text-content-secondary mb-1">Scheduled Time:</label>
|
|
174
162
|
<input
|
|
175
163
|
v-model="newTask.scheduledAt"
|
|
176
164
|
type="datetime-local"
|
|
177
|
-
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"
|
|
178
166
|
>
|
|
179
167
|
</div>
|
|
180
168
|
|
|
181
169
|
<div>
|
|
182
|
-
<label class="block text-sm font-medium text-
|
|
183
|
-
<
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
+
/>
|
|
188
177
|
</div>
|
|
189
178
|
|
|
190
179
|
<div>
|
|
191
|
-
<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>
|
|
192
181
|
<input
|
|
193
182
|
v-model="newTask.repeatInterval"
|
|
194
183
|
type="number"
|
|
195
184
|
min="0"
|
|
196
185
|
step="1000"
|
|
197
|
-
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"
|
|
198
187
|
placeholder="0 for no repetition"
|
|
199
188
|
>
|
|
200
|
-
<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>
|
|
201
190
|
</div>
|
|
202
191
|
|
|
203
192
|
<div class="flex gap-2 pt-4">
|
|
204
193
|
<button
|
|
205
194
|
@click="createTask"
|
|
206
|
-
class="flex-1 bg-
|
|
195
|
+
class="flex-1 bg-primary text-primary-text px-4 py-2 rounded-md hover:bg-primary-hover"
|
|
207
196
|
>
|
|
208
197
|
Create Task
|
|
209
198
|
</button>
|
|
210
199
|
<button
|
|
211
200
|
@click="closeCreateTaskModal"
|
|
212
|
-
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"
|
|
213
202
|
>
|
|
214
203
|
Cancel
|
|
215
204
|
</button>
|
|
@@ -8,11 +8,12 @@ module.exports = app => app.component('tasks', {
|
|
|
8
8
|
status: 'init',
|
|
9
9
|
tasks: [],
|
|
10
10
|
groupedTasks: {},
|
|
11
|
-
selectedRange: '
|
|
11
|
+
selectedRange: 'last_hour',
|
|
12
12
|
start: null,
|
|
13
13
|
end: null,
|
|
14
14
|
dateFilters: [
|
|
15
15
|
{ value: 'all', label: 'All Time' },
|
|
16
|
+
{ value: 'last_hour', label: 'Last Hour' },
|
|
16
17
|
{ value: 'today', label: 'Today' },
|
|
17
18
|
{ value: 'yesterday', label: 'Yesterday' },
|
|
18
19
|
{ value: 'thisWeek', label: 'This Week' },
|
|
@@ -31,10 +32,6 @@ module.exports = app => app.component('tasks', {
|
|
|
31
32
|
],
|
|
32
33
|
searchQuery: '',
|
|
33
34
|
searchTimeout: null,
|
|
34
|
-
// Task details view state
|
|
35
|
-
showTaskDetails: false,
|
|
36
|
-
selectedTaskGroup: null,
|
|
37
|
-
taskDetailsFilter: null,
|
|
38
35
|
// Create task modal state
|
|
39
36
|
showCreateTaskModal: false,
|
|
40
37
|
newTask: {
|
|
@@ -42,8 +39,7 @@ module.exports = app => app.component('tasks', {
|
|
|
42
39
|
scheduledAt: '',
|
|
43
40
|
parameters: '',
|
|
44
41
|
repeatInterval: ''
|
|
45
|
-
}
|
|
46
|
-
parametersEditor: null
|
|
42
|
+
}
|
|
47
43
|
}),
|
|
48
44
|
methods: {
|
|
49
45
|
async getTasks() {
|
|
@@ -70,28 +66,10 @@ module.exports = app => app.component('tasks', {
|
|
|
70
66
|
this.groupedTasks = groupedTasks;
|
|
71
67
|
},
|
|
72
68
|
openTaskGroupDetails(group) {
|
|
73
|
-
this.
|
|
74
|
-
this.showTaskDetails = true;
|
|
69
|
+
this.$router.push({ path: `/tasks/${encodeURIComponent(group.name || '')}` });
|
|
75
70
|
},
|
|
76
71
|
openTaskGroupDetailsWithFilter(group, status) {
|
|
77
|
-
|
|
78
|
-
const filteredGroup = {
|
|
79
|
-
...group,
|
|
80
|
-
tasks: group.tasks.filter(task => task.status === status),
|
|
81
|
-
filteredStatus: status
|
|
82
|
-
};
|
|
83
|
-
this.selectedTaskGroup = filteredGroup;
|
|
84
|
-
this.taskDetailsFilter = status;
|
|
85
|
-
this.showTaskDetails = true;
|
|
86
|
-
},
|
|
87
|
-
async onTaskCancelled() {
|
|
88
|
-
// Refresh the task data when a task is cancelled
|
|
89
|
-
await this.getTasks();
|
|
90
|
-
},
|
|
91
|
-
hideTaskDetails() {
|
|
92
|
-
this.showTaskDetails = false;
|
|
93
|
-
this.selectedTaskGroup = null;
|
|
94
|
-
this.taskDetailsFilter = null;
|
|
72
|
+
this.$router.push({ path: `/tasks/${encodeURIComponent(group.name || '')}`, query: status ? { status } : {} });
|
|
95
73
|
},
|
|
96
74
|
async onTaskCreated() {
|
|
97
75
|
// Refresh the task data when a new task is created
|
|
@@ -104,7 +82,7 @@ module.exports = app => app.component('tasks', {
|
|
|
104
82
|
async createTask() {
|
|
105
83
|
try {
|
|
106
84
|
let parameters = {};
|
|
107
|
-
const parametersText = this.
|
|
85
|
+
const parametersText = this.newTask.parameters || '';
|
|
108
86
|
if (parametersText.trim()) {
|
|
109
87
|
try {
|
|
110
88
|
parameters = JSON.parse(parametersText);
|
|
@@ -181,9 +159,6 @@ module.exports = app => app.component('tasks', {
|
|
|
181
159
|
parameters: '',
|
|
182
160
|
repeatInterval: ''
|
|
183
161
|
};
|
|
184
|
-
if (this.parametersEditor) {
|
|
185
|
-
this.parametersEditor.setValue('');
|
|
186
|
-
}
|
|
187
162
|
},
|
|
188
163
|
setDefaultCreateTaskValues() {
|
|
189
164
|
// Set default scheduled time to 1 hour from now
|
|
@@ -196,21 +171,8 @@ module.exports = app => app.component('tasks', {
|
|
|
196
171
|
this.resetCreateTaskForm();
|
|
197
172
|
this.setDefaultCreateTaskValues();
|
|
198
173
|
},
|
|
199
|
-
initializeParametersEditor() {
|
|
200
|
-
if (this.$refs.parametersEditor && !this.parametersEditor) {
|
|
201
|
-
this.parametersEditor = CodeMirror.fromTextArea(this.$refs.parametersEditor, {
|
|
202
|
-
mode: 'javascript',
|
|
203
|
-
lineNumbers: true,
|
|
204
|
-
smartIndent: false,
|
|
205
|
-
theme: 'default'
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
},
|
|
209
174
|
openCreateTaskModal() {
|
|
210
175
|
this.showCreateTaskModal = true;
|
|
211
|
-
this.$nextTick(() => {
|
|
212
|
-
this.initializeParametersEditor();
|
|
213
|
-
});
|
|
214
176
|
},
|
|
215
177
|
getStatusColor(status) {
|
|
216
178
|
if (status === 'succeeded') {
|
|
@@ -255,6 +217,11 @@ module.exports = app => app.component('tasks', {
|
|
|
255
217
|
let start, end;
|
|
256
218
|
|
|
257
219
|
switch (this.selectedRange) {
|
|
220
|
+
case 'last_hour':
|
|
221
|
+
start = new Date();
|
|
222
|
+
start.setHours(start.getHours() - 1);
|
|
223
|
+
end = new Date();
|
|
224
|
+
break;
|
|
258
225
|
case 'today':
|
|
259
226
|
start = new Date();
|
|
260
227
|
start.setHours(0, 0, 0, 0);
|
|
@@ -362,11 +329,5 @@ module.exports = app => app.component('tasks', {
|
|
|
362
329
|
this.status = 'loaded';
|
|
363
330
|
this.setDefaultCreateTaskValues();
|
|
364
331
|
},
|
|
365
|
-
beforeDestroy() {
|
|
366
|
-
if (this.parametersEditor) {
|
|
367
|
-
this.parametersEditor.toTextArea();
|
|
368
|
-
}
|
|
369
|
-
},
|
|
370
|
-
|
|
371
332
|
template: template
|
|
372
333
|
});
|
|
@@ -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>
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<async-button
|
|
15
15
|
type="submit"
|
|
16
16
|
@click="getWorkspaceCustomerPortalLink"
|
|
17
|
-
class="inline-flex items-center justify-center rounded-md border border-transparent bg-
|
|
17
|
+
class="inline-flex items-center justify-center rounded-md border border-transparent bg-primary py-1 px-2 text-sm font-medium text-primary-text shadow-sm hover:bg-primary-hover focus:outline-none focus:ring-2 focus:ring-forest-green-500 focus:ring-offset-2">
|
|
18
18
|
View in Stripe
|
|
19
19
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 ml-1">
|
|
20
20
|
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" />
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
<div v-else-if="workspace && !workspace.subscriptionTier" class="mt-4 flex justify-between items-center">
|
|
26
26
|
<div>
|
|
27
27
|
<span class="font-bold">No active subscription</span>
|
|
28
|
-
<div class="text-sm text-
|
|
28
|
+
<div class="text-sm text-content-secondary">
|
|
29
29
|
You won't be able to invite your team until you activate a subscription
|
|
30
30
|
</div>
|
|
31
31
|
</div>
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
<a
|
|
34
34
|
:href="paymentLink"
|
|
35
35
|
target="_blank"
|
|
36
|
-
class="inline-flex items-center justify-center rounded-md border border-transparent bg-
|
|
36
|
+
class="inline-flex items-center justify-center rounded-md border border-transparent bg-primary py-1 px-2 text-sm font-medium text-primary-text shadow-sm hover:bg-primary-hover focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2">
|
|
37
37
|
Subscribe With Stripe
|
|
38
38
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 ml-1">
|
|
39
39
|
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" />
|
|
@@ -52,21 +52,21 @@
|
|
|
52
52
|
<ul v-else role="list" class="divide-y divide-gray-100">
|
|
53
53
|
<li class="flex justify-between gap-x-6 py-5" v-for="user in users">
|
|
54
54
|
<div class="flex min-w-0 gap-x-4">
|
|
55
|
-
<img class="size-12 flex-none rounded-full bg-
|
|
55
|
+
<img class="size-12 flex-none rounded-full bg-page" :src="user.picture ?? 'images/logo.svg'" alt="">
|
|
56
56
|
<div class="min-w-0 flex-auto">
|
|
57
|
-
<p class="text-sm/6 font-semibold text-
|
|
57
|
+
<p class="text-sm/6 font-semibold text-content">
|
|
58
58
|
{{user.name || user.githubUsername}}
|
|
59
59
|
<span v-if="user.isFreeUser" class="ml-1 inline-flex items-center rounded-md bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20">Free</span>
|
|
60
60
|
</p>
|
|
61
|
-
<p class="mt-1 truncate text-xs/5 text-
|
|
61
|
+
<p class="mt-1 truncate text-xs/5 text-content-tertiary">{{user.email ?? 'No Email'}}</p>
|
|
62
62
|
</div>
|
|
63
63
|
</div>
|
|
64
64
|
<div class="hidden shrink-0 sm:flex sm:flex-col sm:items-end">
|
|
65
|
-
<p class="text-sm/6 text-
|
|
65
|
+
<p class="text-sm/6 text-content capitalize">{{getRolesForUser(user).join(', ')}}</p>
|
|
66
66
|
<div class="flex gap-3">
|
|
67
67
|
<button
|
|
68
68
|
type="button"
|
|
69
|
-
class="mt-1 text-xs/5 text-
|
|
69
|
+
class="mt-1 text-xs/5 text-content-tertiary cursor-pointer disabled:cursor-not-allowed disabled:text-gray-300"
|
|
70
70
|
:disabled="getRolesForUser(user).includes('owner')"
|
|
71
71
|
@click="openEditModal(user)">
|
|
72
72
|
Edit
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
@click="showNewInvitationModal = true"
|
|
94
94
|
:disabled="status === 'loading'"
|
|
95
95
|
:tier="workspace?.subscriptionTier"
|
|
96
|
-
class="block rounded-md bg-
|
|
96
|
+
class="block rounded-md bg-primary px-3 py-2 text-center text-sm font-semibold text-primary-text shadow-sm hover:bg-primary-hover disabled:bg-page0 disabled:cursor-not-allowed focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary">
|
|
97
97
|
New Invitation
|
|
98
98
|
<svg class="inline w-4 h-4 ml-1" v-if="workspace && !workspace.subscriptionTier" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
|
99
99
|
<path fill-rule="evenodd" d="M12 1.5a5.25 5.25 0 00-5.25 5.25v3a3 3 0 00-3 3v6.75a3 3 0 003 3h10.5a3 3 0 003-3v-6.75a3 3 0 00-3-3v-3c0-2.9-2.35-5.25-5.25-5.25zm3.75 8.25v-3a3.75 3.75 0 10-7.5 0v3h7.5z" clip-rule="evenodd" />
|
|
@@ -110,26 +110,26 @@
|
|
|
110
110
|
<table class="min-w-full divide-y divide-gray-300">
|
|
111
111
|
<thead>
|
|
112
112
|
<tr>
|
|
113
|
-
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-
|
|
114
|
-
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-
|
|
115
|
-
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-
|
|
116
|
-
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-
|
|
113
|
+
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-content sm:pl-0">GitHub Username</th>
|
|
114
|
+
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-content">Email</th>
|
|
115
|
+
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-content">Status</th>
|
|
116
|
+
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-content">Role</th>
|
|
117
117
|
</tr>
|
|
118
118
|
</thead>
|
|
119
|
-
<tbody class="divide-y divide-gray-200 bg-
|
|
119
|
+
<tbody class="divide-y divide-gray-200 bg-surface">
|
|
120
120
|
<tr v-for="invitation in invitations">
|
|
121
121
|
<td class="whitespace-nowrap py-5 pl-4 pr-3 text-sm sm:pl-0">
|
|
122
122
|
{{invitation.githubUsername}}
|
|
123
123
|
</td>
|
|
124
|
-
<td class="whitespace-nowrap px-3 py-5 text-sm text-
|
|
124
|
+
<td class="whitespace-nowrap px-3 py-5 text-sm text-content-tertiary">
|
|
125
125
|
{{invitation.email}}
|
|
126
126
|
</td>
|
|
127
|
-
<td class="whitespace-nowrap px-3 py-5 text-sm text-
|
|
128
|
-
<span class="inline-flex items-center rounded-md bg-
|
|
127
|
+
<td class="whitespace-nowrap px-3 py-5 text-sm text-content-tertiary">
|
|
128
|
+
<span class="inline-flex items-center rounded-md bg-page px-2 py-1 text-xs font-medium text-content-secondary ring-1 ring-inset ring-gray-600/20">
|
|
129
129
|
Pending
|
|
130
130
|
</span>
|
|
131
131
|
</td>
|
|
132
|
-
<td class="whitespace-nowrap px-3 py-5 text-sm text-
|
|
132
|
+
<td class="whitespace-nowrap px-3 py-5 text-sm text-content-tertiary">
|
|
133
133
|
{{invitation.roles.join(', ')}}
|
|
134
134
|
</td>
|
|
135
135
|
</tr>
|
|
@@ -143,8 +143,8 @@
|
|
|
143
143
|
<svg class="mx-auto size-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
|
|
144
144
|
<path vector-effect="non-scaling-stroke" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z" />
|
|
145
145
|
</svg>
|
|
146
|
-
<h3 class="mt-2 text-sm font-semibold text-
|
|
147
|
-
<p class="mt-1 text-sm text-
|
|
146
|
+
<h3 class="mt-2 text-sm font-semibold text-content">No invitations</h3>
|
|
147
|
+
<p class="mt-1 text-sm text-content-tertiary">You have no outstanding invitations</p>
|
|
148
148
|
</div>
|
|
149
149
|
</div>
|
|
150
150
|
</div>
|
|
@@ -165,32 +165,32 @@
|
|
|
165
165
|
</div>
|
|
166
166
|
|
|
167
167
|
<div>
|
|
168
|
-
<div class="text-sm/6 font-semibold text-
|
|
168
|
+
<div class="text-sm/6 font-semibold text-content">
|
|
169
169
|
{{showEditModal.user.name || showEditModal.user.githubUsername}}
|
|
170
170
|
</div>
|
|
171
|
-
<div class="text-xs/5 text-
|
|
171
|
+
<div class="text-xs/5 text-content-tertiary">
|
|
172
172
|
{{showEditModal.user.email ?? 'No Email'}}
|
|
173
173
|
</div>
|
|
174
174
|
</div>
|
|
175
175
|
|
|
176
176
|
<div>
|
|
177
|
-
<label for="editRole" class="block text-sm/6 font-medium text-
|
|
177
|
+
<label for="editRole" class="block text-sm/6 font-medium text-content">Role</label>
|
|
178
178
|
<div class="mt-2 grid grid-cols-1">
|
|
179
179
|
<select
|
|
180
180
|
id="editRole"
|
|
181
181
|
name="editRole"
|
|
182
182
|
v-model="showEditModal.role"
|
|
183
|
-
class="col-start-1 row-start-1 w-full appearance-none rounded-md bg-
|
|
183
|
+
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-primary sm:text-sm/6">
|
|
184
184
|
<option value="admin" :disabled="disableRoleOption('admin')">Admin</option>
|
|
185
185
|
<option value="member" :disabled="disableRoleOption('member')">Member</option>
|
|
186
186
|
<option value="readonly" :disabled="disableRoleOption('readonly')">Read-only</option>
|
|
187
187
|
<option value="dashboards" :disabled="disableRoleOption('dashboards')">Dashboards Only</option>
|
|
188
188
|
</select>
|
|
189
|
-
<svg class="pointer-events-none col-start-1 row-start-1 mr-2 size-5 self-center justify-self-end text-
|
|
189
|
+
<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">
|
|
190
190
|
<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" />
|
|
191
191
|
</svg>
|
|
192
192
|
</div>
|
|
193
|
-
<div v-if="!workspace?.subscriptionTier" class="mt-2 text-sm text-
|
|
193
|
+
<div v-if="!workspace?.subscriptionTier" class="mt-2 text-sm text-content-secondary">
|
|
194
194
|
You can only assign the "Dashboards Only" role until you activate a subscription.
|
|
195
195
|
</div>
|
|
196
196
|
</div>
|
|
@@ -199,7 +199,7 @@
|
|
|
199
199
|
<async-button
|
|
200
200
|
@click="updateWorkspaceMember"
|
|
201
201
|
:disabled="showEditModal.role === showEditModal.originalRole"
|
|
202
|
-
class="border-0 mt-0 flex w-full items-center justify-center gap-3 rounded-md bg-
|
|
202
|
+
class="border-0 mt-0 flex w-full items-center justify-center gap-3 rounded-md bg-primary hover:bg-primary-hover px-3 py-1.5 text-primary-text focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary">
|
|
203
203
|
<span class="text-sm font-semibold leading-6">Save</span>
|
|
204
204
|
</async-button>
|
|
205
205
|
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
<div>
|
|
2
2
|
<div class="mb-2">
|
|
3
|
-
<
|
|
3
|
+
<ace-editor
|
|
4
|
+
v-model="editorValue"
|
|
5
|
+
mode="javascript"
|
|
6
|
+
:line-numbers="true"
|
|
7
|
+
class="h-[300px] w-full"
|
|
8
|
+
/>
|
|
4
9
|
</div>
|
|
5
|
-
<button @click="updateDocument()" class="rounded-md bg-
|
|
10
|
+
<button @click="updateDocument()" class="rounded-md bg-primary px-2.5 py-1.5 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-teal-600">Submit</button>
|
|
6
11
|
<div v-if="errors.length > 0" class="rounded-md bg-red-50 p-4 mt-1">
|
|
7
12
|
<div class="flex">
|
|
8
13
|
<div class="flex-shrink-0">
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const api = require('../api');
|
|
4
|
-
|
|
5
4
|
const { BSON, EJSON } = require('mongodb/lib/bson');
|
|
6
5
|
|
|
7
6
|
const ObjectId = new Proxy(BSON.ObjectId, {
|
|
@@ -21,13 +20,13 @@ module.exports = app => app.component('update-document', {
|
|
|
21
20
|
template,
|
|
22
21
|
data: function() {
|
|
23
22
|
return {
|
|
24
|
-
|
|
23
|
+
editorValue: '{\n \n}',
|
|
25
24
|
errors: []
|
|
26
25
|
};
|
|
27
26
|
},
|
|
28
27
|
methods: {
|
|
29
28
|
async updateDocument() {
|
|
30
|
-
const data = EJSON.serialize(eval(`(${this.
|
|
29
|
+
const data = EJSON.serialize(eval(`(${this.editorValue})`));
|
|
31
30
|
try {
|
|
32
31
|
if (this.multiple) {
|
|
33
32
|
const ids = this.document.map(x => x._id);
|
|
@@ -52,13 +51,5 @@ module.exports = app => app.component('update-document', {
|
|
|
52
51
|
throw err;
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
|
-
},
|
|
56
|
-
mounted: function() {
|
|
57
|
-
this.$refs.codeEditor.value = '{\n \n}';
|
|
58
|
-
this.editor = CodeMirror.fromTextArea(this.$refs.codeEditor, {
|
|
59
|
-
mode: 'javascript',
|
|
60
|
-
lineNumbers: true,
|
|
61
|
-
smartIndent: false
|
|
62
|
-
});
|
|
63
54
|
}
|
|
64
55
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mongoosejs/studio",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A Mongoose-native MongoDB UI with schema-aware autocomplete, AI-assisted queries, and dashboards that understand your models - not just your data.",
|
|
5
5
|
"homepage": "https://mongoosestudio.app/",
|
|
6
6
|
"repository": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"@ai-sdk/anthropic": "2.x",
|
|
13
13
|
"@ai-sdk/google": "2.x",
|
|
14
14
|
"@ai-sdk/openai": "2.x",
|
|
15
|
+
"ace-builds": "^1.43.6",
|
|
15
16
|
"ai": "5.x",
|
|
16
17
|
"archetype": "0.13.1",
|
|
17
18
|
"csv-stringify": "6.3.0",
|
|
@@ -38,6 +39,7 @@
|
|
|
38
39
|
"eslint": "9.30.0",
|
|
39
40
|
"express": "4.x",
|
|
40
41
|
"mocha": "10.2.0",
|
|
42
|
+
"mongodb-memory-server": "^11.0.1",
|
|
41
43
|
"mongoose": "9.x",
|
|
42
44
|
"sinon": "^21.0.1"
|
|
43
45
|
},
|