@mongoosejs/studio 0.0.83 → 0.0.85
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/astra.js +159 -0
- package/backend/actions/ChatMessage/executeScript.js +2 -2
- package/backend/actions/ChatThread/createChatMessage.js +3 -3
- package/backend/actions/ChatThread/createChatThread.js +2 -2
- package/backend/actions/ChatThread/getChatThread.js +3 -3
- package/backend/actions/ChatThread/listChatThreads.js +2 -2
- package/backend/actions/Model/deleteDocuments.js +38 -0
- package/backend/actions/Model/getDocuments.js +2 -2
- package/backend/actions/Model/index.js +2 -0
- package/backend/actions/Model/updateDocuments.js +46 -0
- package/backend/index.js +6 -7
- package/backend/netlify.js +2 -2
- package/express.js +1 -1
- package/frontend/public/app.js +6580 -6343
- package/frontend/public/tw.css +58 -0
- package/frontend/src/api.js +12 -0
- package/frontend/src/models/models.html +55 -4
- package/frontend/src/models/models.js +52 -0
- package/frontend/src/update-document/update-document.css +0 -0
- package/frontend/src/update-document/update-document.html +25 -0
- package/frontend/src/update-document/update-document.js +70 -0
- package/package.json +1 -1
package/frontend/public/tw.css
CHANGED
|
@@ -1235,6 +1235,16 @@ video {
|
|
|
1235
1235
|
border-color: rgb(63 83 255 / var(--tw-border-opacity));
|
|
1236
1236
|
}
|
|
1237
1237
|
|
|
1238
|
+
.border-red-500 {
|
|
1239
|
+
--tw-border-opacity: 1;
|
|
1240
|
+
border-color: rgb(239 68 68 / var(--tw-border-opacity));
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
.bg-blue-200 {
|
|
1244
|
+
--tw-bg-opacity: 1;
|
|
1245
|
+
background-color: rgb(191 219 254 / var(--tw-bg-opacity));
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1238
1248
|
.bg-blue-500 {
|
|
1239
1249
|
--tw-bg-opacity: 1;
|
|
1240
1250
|
background-color: rgb(59 130 246 / var(--tw-bg-opacity));
|
|
@@ -1330,6 +1340,11 @@ video {
|
|
|
1330
1340
|
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
|
1331
1341
|
}
|
|
1332
1342
|
|
|
1343
|
+
.bg-red-600 {
|
|
1344
|
+
--tw-bg-opacity: 1;
|
|
1345
|
+
background-color: rgb(220 38 38 / var(--tw-bg-opacity));
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1333
1348
|
.bg-slate-100 {
|
|
1334
1349
|
--tw-bg-opacity: 1;
|
|
1335
1350
|
background-color: rgb(241 245 249 / var(--tw-bg-opacity));
|
|
@@ -1384,6 +1399,11 @@ video {
|
|
|
1384
1399
|
background-color: rgb(253 224 71 / var(--tw-bg-opacity));
|
|
1385
1400
|
}
|
|
1386
1401
|
|
|
1402
|
+
.bg-ultramarine-500 {
|
|
1403
|
+
--tw-bg-opacity: 1;
|
|
1404
|
+
background-color: rgb(63 83 255 / var(--tw-bg-opacity));
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1387
1407
|
.p-1 {
|
|
1388
1408
|
padding: 0.25rem;
|
|
1389
1409
|
}
|
|
@@ -1726,6 +1746,12 @@ video {
|
|
|
1726
1746
|
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
1727
1747
|
}
|
|
1728
1748
|
|
|
1749
|
+
.ring-2 {
|
|
1750
|
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
1751
|
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
1752
|
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1729
1755
|
.ring-inset {
|
|
1730
1756
|
--tw-ring-inset: inset;
|
|
1731
1757
|
}
|
|
@@ -1751,6 +1777,16 @@ video {
|
|
|
1751
1777
|
--tw-ring-color: rgb(22 163 74 / 0.2);
|
|
1752
1778
|
}
|
|
1753
1779
|
|
|
1780
|
+
.ring-yellow-800 {
|
|
1781
|
+
--tw-ring-opacity: 1;
|
|
1782
|
+
--tw-ring-color: rgb(133 77 14 / var(--tw-ring-opacity));
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
.ring-yellow-300 {
|
|
1786
|
+
--tw-ring-opacity: 1;
|
|
1787
|
+
--tw-ring-color: rgb(253 224 71 / var(--tw-ring-opacity));
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1754
1790
|
.filter {
|
|
1755
1791
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
1756
1792
|
}
|
|
@@ -1854,6 +1890,11 @@ video {
|
|
|
1854
1890
|
background-color: rgb(22 163 74 / var(--tw-bg-opacity));
|
|
1855
1891
|
}
|
|
1856
1892
|
|
|
1893
|
+
.hover\:bg-red-500:hover {
|
|
1894
|
+
--tw-bg-opacity: 1;
|
|
1895
|
+
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1857
1898
|
.hover\:bg-red-600:hover {
|
|
1858
1899
|
--tw-bg-opacity: 1;
|
|
1859
1900
|
background-color: rgb(220 38 38 / var(--tw-bg-opacity));
|
|
@@ -1899,6 +1940,11 @@ video {
|
|
|
1899
1940
|
background-color: rgb(220 73 73 / var(--tw-bg-opacity));
|
|
1900
1941
|
}
|
|
1901
1942
|
|
|
1943
|
+
.hover\:bg-ultramarine-600:hover {
|
|
1944
|
+
--tw-bg-opacity: 1;
|
|
1945
|
+
background-color: rgb(24 35 255 / var(--tw-bg-opacity));
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1902
1948
|
.hover\:text-gray-700:hover {
|
|
1903
1949
|
--tw-text-opacity: 1;
|
|
1904
1950
|
color: rgb(55 65 81 / var(--tw-text-opacity));
|
|
@@ -2037,6 +2083,10 @@ video {
|
|
|
2037
2083
|
outline-color: #fb923c;
|
|
2038
2084
|
}
|
|
2039
2085
|
|
|
2086
|
+
.focus-visible\:outline-red-500:focus-visible {
|
|
2087
|
+
outline-color: #ef4444;
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2040
2090
|
.focus-visible\:outline-red-600:focus-visible {
|
|
2041
2091
|
outline-color: #dc2626;
|
|
2042
2092
|
}
|
|
@@ -2057,6 +2107,14 @@ video {
|
|
|
2057
2107
|
outline-color: #1823ff;
|
|
2058
2108
|
}
|
|
2059
2109
|
|
|
2110
|
+
.focus-visible\:outline-gray-600:focus-visible {
|
|
2111
|
+
outline-color: #4b5563;
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
.focus-visible\:outline-gray-500:focus-visible {
|
|
2115
|
+
outline-color: #6b7280;
|
|
2116
|
+
}
|
|
2117
|
+
|
|
2060
2118
|
.disabled\:cursor-not-allowed:disabled {
|
|
2061
2119
|
cursor: not-allowed;
|
|
2062
2120
|
}
|
package/frontend/src/api.js
CHANGED
|
@@ -75,6 +75,9 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
75
75
|
deleteDocument(params) {
|
|
76
76
|
return client.post('', { action: 'Model.deleteDocument', ...params}).then(res => res.data);
|
|
77
77
|
},
|
|
78
|
+
deleteDocuments(params) {
|
|
79
|
+
return client.post('', { action: 'Model.deleteDocuments', ...params}).then(res => res.data);
|
|
80
|
+
},
|
|
78
81
|
exportQueryResults(params) {
|
|
79
82
|
const accessToken = window.localStorage.getItem('_mongooseStudioAccessToken') || null;
|
|
80
83
|
|
|
@@ -113,6 +116,9 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
113
116
|
},
|
|
114
117
|
updateDocument: function updateDocument(params) {
|
|
115
118
|
return client.post('', { action: 'Model.updateDocument', ...params }).then(res => res.data);
|
|
119
|
+
},
|
|
120
|
+
updateDocuments: function updateDocuments(params) {
|
|
121
|
+
return client.post('', { action: 'Model.updateDocuments', ...params }).then(res => res.data);
|
|
116
122
|
}
|
|
117
123
|
};
|
|
118
124
|
} else {
|
|
@@ -165,6 +171,9 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
165
171
|
deleteDocument: function (params) {
|
|
166
172
|
return client.post('/Model/deleteDocument', params).then(res => res.data);
|
|
167
173
|
},
|
|
174
|
+
deleteDocuments: function(params) {
|
|
175
|
+
return client.post('/Model/deleteDocuments', params).then(res => res.data);
|
|
176
|
+
},
|
|
168
177
|
exportQueryResults(params) {
|
|
169
178
|
const accessToken = window.localStorage.getItem('_mongooseStudioAccessToken') || null;
|
|
170
179
|
|
|
@@ -206,6 +215,9 @@ if (window.MONGOOSE_STUDIO_CONFIG.isLambda) {
|
|
|
206
215
|
},
|
|
207
216
|
updateDocument: function updateDocument(params) {
|
|
208
217
|
return client.post('/Model/updateDocument', params).then(res => res.data);
|
|
218
|
+
},
|
|
219
|
+
updateDocuments: function updateDocument(params) {
|
|
220
|
+
return client.post('/Model/updateDocuments', params).then(res => res.data);
|
|
209
221
|
}
|
|
210
222
|
};
|
|
211
223
|
}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
<div class="documents-menu">
|
|
29
29
|
<div class="flex flex-row items-center w-full gap-2">
|
|
30
30
|
<form @submit.prevent="search" class="flex-grow m-0">
|
|
31
|
-
<input ref="searchInput" class="w-full font-mono rounded-md p-1 border border-gray-300 outline-gray-300 text-lg focus:ring-1 focus:ring-ultramarine-200 focus:ring-offset-0 focus:outline-none" type="text" placeholder="Filter
|
|
31
|
+
<input ref="searchInput" class="w-full font-mono rounded-md p-1 border border-gray-300 outline-gray-300 text-lg focus:ring-1 focus:ring-ultramarine-200 focus:ring-offset-0 focus:outline-none" type="text" placeholder="Filter" v-model="searchText" @click="initFilter" />
|
|
32
32
|
</form>
|
|
33
33
|
<div>
|
|
34
34
|
<span v-if="status === 'loading'">Loading ...</span>
|
|
@@ -37,24 +37,52 @@
|
|
|
37
37
|
<button
|
|
38
38
|
@click="shouldShowExportModal = true"
|
|
39
39
|
type="button"
|
|
40
|
+
v-show="!selectMultiple"
|
|
40
41
|
class="rounded bg-ultramarine-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600">
|
|
41
42
|
Export
|
|
42
43
|
</button>
|
|
44
|
+
<button
|
|
45
|
+
@click="stagingSelect"
|
|
46
|
+
type="button"
|
|
47
|
+
:class="{ 'bg-ultramarine-500 ring-inset ring-2 ring-gray-300 hover:bg-ultramarine-600': selectMultiple }"
|
|
48
|
+
class="rounded bg-ultramarine-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600"
|
|
49
|
+
>
|
|
50
|
+
Select
|
|
51
|
+
</button>
|
|
52
|
+
<button
|
|
53
|
+
v-show="selectMultiple"
|
|
54
|
+
@click="shouldShowUpdateMultipleModal=true;"
|
|
55
|
+
type="button"
|
|
56
|
+
class="rounded bg-green-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-green-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600"
|
|
57
|
+
>
|
|
58
|
+
Update
|
|
59
|
+
</button>
|
|
60
|
+
<button
|
|
61
|
+
@click="shouldShowDeleteMultipleModal=true;"
|
|
62
|
+
type="button"
|
|
63
|
+
v-show="selectMultiple"
|
|
64
|
+
class="rounded bg-red-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-500"
|
|
65
|
+
>
|
|
66
|
+
Delete
|
|
67
|
+
</button>
|
|
43
68
|
<button
|
|
44
69
|
@click="openIndexModal"
|
|
45
70
|
type="button"
|
|
71
|
+
v-show="!selectMultiple"
|
|
46
72
|
class="rounded bg-ultramarine-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600">
|
|
47
73
|
Indexes
|
|
48
74
|
</button>
|
|
49
75
|
<button
|
|
50
76
|
@click="shouldShowCreateModal = true;"
|
|
51
77
|
type="button"
|
|
78
|
+
v-show="!selectMultiple"
|
|
52
79
|
class="rounded bg-ultramarine-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600">
|
|
53
80
|
Create
|
|
54
81
|
</button>
|
|
55
82
|
<button
|
|
56
83
|
@click="openFieldSelection"
|
|
57
84
|
type="button"
|
|
85
|
+
v-show="!selectMultiple"
|
|
58
86
|
class="rounded bg-ultramarine-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600">
|
|
59
87
|
Fields
|
|
60
88
|
</button>
|
|
@@ -90,8 +118,8 @@
|
|
|
90
118
|
</th>
|
|
91
119
|
</thead>
|
|
92
120
|
<tbody>
|
|
93
|
-
<tr v-for="document in documents" @click="
|
|
94
|
-
<td v-for="schemaPath in filteredPaths">
|
|
121
|
+
<tr v-for="document in documents" @click="handleDocumentClick(document)" :key="document._id">
|
|
122
|
+
<td v-for="schemaPath in filteredPaths" :class="{ 'bg-blue-200': selectedDocuments.some(x => x._id.toString() === document._id.toString()) }">
|
|
95
123
|
<component
|
|
96
124
|
:is="getComponentForPath(schemaPath)"
|
|
97
125
|
:value="getValueForPath(document, schemaPath.path)"
|
|
@@ -102,7 +130,7 @@
|
|
|
102
130
|
</tbody>
|
|
103
131
|
</table>
|
|
104
132
|
<div v-if="outputType === 'json'">
|
|
105
|
-
<div v-for="document in documents" @click="
|
|
133
|
+
<div v-for="document in documents" @click="handleDocumentClick(document)" :key="document._id" :class="{ 'bg-blue-200': selectedDocuments.some(x => x._id.toString() === document._id.toString()) }">
|
|
106
134
|
<list-json :value="filterDocument(document)">
|
|
107
135
|
</list-json>
|
|
108
136
|
</div>
|
|
@@ -162,4 +190,27 @@
|
|
|
162
190
|
<create-document :currentModel="currentModel" :paths="schemaPaths" @close="closeCreationModal"></create-document>
|
|
163
191
|
</template>
|
|
164
192
|
</modal>
|
|
193
|
+
<modal v-if="shouldShowUpdateMultipleModal">
|
|
194
|
+
<template v-slot:body>
|
|
195
|
+
<div class="modal-exit" @click="shouldShowUpdateMultipleModal = false;">×</div>
|
|
196
|
+
<update-document :currentModel="currentModel" :document="selectedDocuments" :multiple="true" @update="updateDocuments" @close="shouldShowUpdateMultipleModal=false;"></update-document>
|
|
197
|
+
</template>
|
|
198
|
+
</modal>
|
|
199
|
+
<modal v-if="shouldShowDeleteMultipleModal">
|
|
200
|
+
<template v-slot:body>
|
|
201
|
+
<div class="modal-exit" @click="shouldShowDeleteMultipleModal = false;">×</div>
|
|
202
|
+
<h2>Are you sure you want to delete {{selectedDocuments.length}} documents?</h2>
|
|
203
|
+
<div>
|
|
204
|
+
<list-json :value="selectedDocuments"></list-json>
|
|
205
|
+
</div>
|
|
206
|
+
<div class="flex gap-4">
|
|
207
|
+
<async-button @click="deleteDocuments" class="rounded bg-red-500 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600">
|
|
208
|
+
Confirm
|
|
209
|
+
</async-button>
|
|
210
|
+
<button @click="shouldShowDeleteMultipleModal = false;" class="rounded bg-gray-400 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-gray-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-500">
|
|
211
|
+
Cancel
|
|
212
|
+
</button>
|
|
213
|
+
</div>
|
|
214
|
+
</template>
|
|
215
|
+
</modal>
|
|
165
216
|
</div>
|
|
@@ -38,11 +38,15 @@ module.exports = app => app.component('models', {
|
|
|
38
38
|
edittingDoc: null,
|
|
39
39
|
docEdits: null,
|
|
40
40
|
filter: null,
|
|
41
|
+
selectMultiple: false,
|
|
42
|
+
selectedDocuments: [],
|
|
41
43
|
searchText: '',
|
|
42
44
|
shouldShowExportModal: false,
|
|
43
45
|
shouldShowCreateModal: false,
|
|
44
46
|
shouldShowFieldModal: false,
|
|
45
47
|
shouldShowIndexModal: false,
|
|
48
|
+
shouldShowUpdateMultipleModal: false,
|
|
49
|
+
shouldShowDeleteMultipleModal: false,
|
|
46
50
|
shouldExport: {},
|
|
47
51
|
sortBy: {},
|
|
48
52
|
query: {},
|
|
@@ -89,6 +93,14 @@ module.exports = app => app.component('models', {
|
|
|
89
93
|
this.status = 'loaded';
|
|
90
94
|
},
|
|
91
95
|
methods: {
|
|
96
|
+
initFilter(ev) {
|
|
97
|
+
if (!this.searchText) {
|
|
98
|
+
this.searchText = '{}';
|
|
99
|
+
this.$nextTick(() => {
|
|
100
|
+
ev.target.setSelectionRange(1, 1);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
},
|
|
92
104
|
clickFilter(path) {
|
|
93
105
|
if (this.searchText) {
|
|
94
106
|
if (this.searchText.endsWith('}')) {
|
|
@@ -319,6 +331,46 @@ module.exports = app => app.component('models', {
|
|
|
319
331
|
this.documents[index] = res.doc;
|
|
320
332
|
}
|
|
321
333
|
this.edittingDoc = null;
|
|
334
|
+
},
|
|
335
|
+
handleDocumentClick(document) {
|
|
336
|
+
console.log(this.selectedDocuments);
|
|
337
|
+
if (this.selectMultiple) {
|
|
338
|
+
const exists = this.selectedDocuments.find(x => x._id.toString() == document._id.toString())
|
|
339
|
+
if (exists) {
|
|
340
|
+
const index = this.selectedDocuments.findIndex(x => x._id.toString() == document._id.toString());
|
|
341
|
+
if (index !== -1) {
|
|
342
|
+
this.selectedDocuments.splice(index, 1);
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
this.selectedDocuments.push(document);
|
|
346
|
+
}
|
|
347
|
+
} else {
|
|
348
|
+
this.$router.push('/model/' + this.currentModel + '/document/' + document._id)
|
|
349
|
+
}
|
|
350
|
+
},
|
|
351
|
+
async deleteDocuments() {
|
|
352
|
+
const documentIds = this.selectedDocuments.map(x => x._id);
|
|
353
|
+
await api.Model.deleteDocuments({
|
|
354
|
+
documentIds,
|
|
355
|
+
model: this.currentModel
|
|
356
|
+
});
|
|
357
|
+
await this.getDocuments();
|
|
358
|
+
this.selectedDocuments.length = 0;
|
|
359
|
+
this.shouldShowDeleteMultipleModal = false;
|
|
360
|
+
this.selectMultiple = false;
|
|
361
|
+
},
|
|
362
|
+
async updateDocuments() {
|
|
363
|
+
await this.getDocuments();
|
|
364
|
+
this.selectedDocuments.length = 0;
|
|
365
|
+
this.selectMultiple = false;
|
|
366
|
+
},
|
|
367
|
+
stagingSelect() {
|
|
368
|
+
if (this.selectMultiple) {
|
|
369
|
+
this.selectMultiple = false;
|
|
370
|
+
this.selectedDocuments.length = 0;
|
|
371
|
+
} else {
|
|
372
|
+
this.selectMultiple = true;
|
|
373
|
+
}
|
|
322
374
|
}
|
|
323
375
|
}
|
|
324
376
|
});
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<div>
|
|
2
|
+
<div class="mb-2">
|
|
3
|
+
<textarea class="border border-gray-200 p-2 h-[300px] w-full" ref="codeEditor"></textarea>
|
|
4
|
+
</div>
|
|
5
|
+
<button @click="updateDocument()" class="rounded-md bg-ultramarine-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600">Submit</button>
|
|
6
|
+
<div v-if="errors.length > 0" class="rounded-md bg-red-50 p-4 mt-1">
|
|
7
|
+
<div class="flex">
|
|
8
|
+
<div class="flex-shrink-0">
|
|
9
|
+
<svg class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
10
|
+
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z" clip-rule="evenodd" />
|
|
11
|
+
</svg>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="ml-3">
|
|
14
|
+
<h3 class="text-sm font-medium text-red-800">There were {{errors.length}} errors with your submission</h3>
|
|
15
|
+
<div class="mt-2 text-sm text-red-700">
|
|
16
|
+
<ul role="list" class="list-disc space-y-1 pl-5">
|
|
17
|
+
<li v-for="error in errors">
|
|
18
|
+
{{error}}
|
|
19
|
+
</li>
|
|
20
|
+
</ul>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const api = require('../api');
|
|
4
|
+
|
|
5
|
+
const { BSON, EJSON } = require('bson');
|
|
6
|
+
|
|
7
|
+
const ObjectId = new Proxy(BSON.ObjectId, {
|
|
8
|
+
apply (target, thisArg, argumentsList) {
|
|
9
|
+
return new target(...argumentsList);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const appendCSS = require('../appendCSS');
|
|
14
|
+
|
|
15
|
+
appendCSS(require('./update-document.css'));
|
|
16
|
+
|
|
17
|
+
const template = require('./update-document.html')
|
|
18
|
+
|
|
19
|
+
module.exports = app => app.component('update-document', {
|
|
20
|
+
props: ['currentModel', 'document', 'multiple'],
|
|
21
|
+
template,
|
|
22
|
+
data: function() {
|
|
23
|
+
return {
|
|
24
|
+
editor: null,
|
|
25
|
+
errors: []
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
methods: {
|
|
29
|
+
async updateDocument() {
|
|
30
|
+
const data = EJSON.serialize(eval(`(${this.editor.getValue()})`));
|
|
31
|
+
if (this.multiple) {
|
|
32
|
+
const ids = this.document.map(x => x._id);
|
|
33
|
+
await api.Model.updateDocuments({ model: this.currentModel, _id: ids, update: data }).catch(err => {
|
|
34
|
+
if (err.response?.data?.message) {
|
|
35
|
+
console.log(err.response.data);
|
|
36
|
+
const message = err.response.data.message.split(": ").slice(1).join(": ");
|
|
37
|
+
this.errors = message.split(',').map(error => {
|
|
38
|
+
return error.split(': ').slice(1).join(': ').trim();
|
|
39
|
+
})
|
|
40
|
+
throw new Error(err.response?.data?.message);
|
|
41
|
+
}
|
|
42
|
+
throw err;
|
|
43
|
+
});
|
|
44
|
+
} else {
|
|
45
|
+
await api.Model.updateDocument({ model: this.currentModel, _id: this.document._id, update: data }).catch(err => {
|
|
46
|
+
if (err.response?.data?.message) {
|
|
47
|
+
console.log(err.response.data);
|
|
48
|
+
const message = err.response.data.message.split(": ").slice(1).join(": ");
|
|
49
|
+
this.errors = message.split(',').map(error => {
|
|
50
|
+
return error.split(': ').slice(1).join(': ').trim();
|
|
51
|
+
})
|
|
52
|
+
throw new Error(err.response?.data?.message);
|
|
53
|
+
}
|
|
54
|
+
throw err;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
this.errors.length = 0;
|
|
58
|
+
this.$emit('update');
|
|
59
|
+
this.$emit('close');
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
mounted: function() {
|
|
63
|
+
this.$refs.codeEditor.value = `{\n \n}`
|
|
64
|
+
this.editor = CodeMirror.fromTextArea(this.$refs.codeEditor, {
|
|
65
|
+
mode: 'javascript',
|
|
66
|
+
lineNumbers: true,
|
|
67
|
+
smartIndent: false
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mongoosejs/studio",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.85",
|
|
4
4
|
"description": "A sleek, powerful MongoDB UI with built-in dashboarding and auth, seamlessly integrated with your Express, Vercel, or Netlify app.",
|
|
5
5
|
"homepage": "https://studio.mongoosejs.io/",
|
|
6
6
|
"repository": {
|