@mongoosejs/studio 0.1.17 → 0.1.18
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/Model/getCollectionInfo.js +49 -0
- package/backend/actions/Model/index.js +1 -0
- package/frontend/public/app.js +272 -79
- package/frontend/public/tw.css +6 -0
- package/frontend/src/api.js +7 -1
- package/frontend/src/chat/chat-message/chat-message.js +7 -0
- package/frontend/src/chat/chat-message-script/chat-message-script.js +21 -0
- package/frontend/src/chat/chat.js +22 -0
- package/frontend/src/clone-document/clone-document.js +14 -5
- package/frontend/src/create-dashboard/create-dashboard.js +8 -0
- package/frontend/src/create-document/create-document.js +14 -5
- package/frontend/src/dashboard/dashboard.js +8 -0
- package/frontend/src/dashboard/edit-dashboard/edit-dashboard.js +8 -0
- package/frontend/src/dashboards/dashboards.js +8 -0
- package/frontend/src/document/document.js +32 -20
- package/frontend/src/document-details/document-details.js +1 -13
- package/frontend/src/export-query-results/export-query-results.js +8 -1
- package/frontend/src/models/models.html +70 -7
- package/frontend/src/models/models.js +80 -1
- package/frontend/src/update-document/update-document.js +28 -27
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const api = require('../api');
|
|
4
4
|
const template = require('./models.html');
|
|
5
5
|
const mpath = require('mpath');
|
|
6
|
+
const vanillatoasts = require('vanillatoasts');
|
|
6
7
|
|
|
7
8
|
const appendCSS = require('../appendCSS');
|
|
8
9
|
appendCSS(require('./models.css'));
|
|
@@ -34,6 +35,7 @@ module.exports = app => app.component('models', {
|
|
|
34
35
|
shouldShowCreateModal: false,
|
|
35
36
|
shouldShowFieldModal: false,
|
|
36
37
|
shouldShowIndexModal: false,
|
|
38
|
+
shouldShowCollectionInfoModal: false,
|
|
37
39
|
shouldShowUpdateMultipleModal: false,
|
|
38
40
|
shouldShowDeleteMultipleModal: false,
|
|
39
41
|
shouldExport: {},
|
|
@@ -44,7 +46,9 @@ module.exports = app => app.component('models', {
|
|
|
44
46
|
outputType: 'table', // json, table
|
|
45
47
|
hideSidebar: null,
|
|
46
48
|
lastSelectedIndex: null,
|
|
47
|
-
error: null
|
|
49
|
+
error: null,
|
|
50
|
+
showActionsMenu: false,
|
|
51
|
+
collectionInfo: null
|
|
48
52
|
}),
|
|
49
53
|
created() {
|
|
50
54
|
this.currentModel = this.model;
|
|
@@ -53,12 +57,23 @@ module.exports = app => app.component('models', {
|
|
|
53
57
|
beforeDestroy() {
|
|
54
58
|
document.removeEventListener('scroll', this.onScroll, true);
|
|
55
59
|
window.removeEventListener('popstate', this.onPopState, true);
|
|
60
|
+
document.removeEventListener('click', this.onOutsideActionsMenuClick, true);
|
|
56
61
|
},
|
|
57
62
|
async mounted() {
|
|
58
63
|
this.onScroll = () => this.checkIfScrolledToBottom();
|
|
59
64
|
document.addEventListener('scroll', this.onScroll, true);
|
|
60
65
|
this.onPopState = () => this.initSearchFromUrl();
|
|
61
66
|
window.addEventListener('popstate', this.onPopState, true);
|
|
67
|
+
this.onOutsideActionsMenuClick = event => {
|
|
68
|
+
if (!this.showActionsMenu) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const actionsMenu = this.$refs.actionsMenuContainer;
|
|
72
|
+
if (actionsMenu && !actionsMenu.contains(event.target)) {
|
|
73
|
+
this.closeActionsMenu();
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
document.addEventListener('click', this.onOutsideActionsMenuClick, true);
|
|
62
77
|
const { models, readyState } = await api.Model.listModels();
|
|
63
78
|
this.models = models;
|
|
64
79
|
if (this.currentModel == null && this.models.length > 0) {
|
|
@@ -160,6 +175,13 @@ module.exports = app => app.component('models', {
|
|
|
160
175
|
async dropIndex(name) {
|
|
161
176
|
const { mongoDBIndexes } = await api.Model.dropIndex({ model: this.currentModel, name });
|
|
162
177
|
this.mongoDBIndexes = mongoDBIndexes;
|
|
178
|
+
vanillatoasts.create({
|
|
179
|
+
title: 'Index dropped!',
|
|
180
|
+
type: 'success',
|
|
181
|
+
timeout: 3000,
|
|
182
|
+
icon: 'images/success.png',
|
|
183
|
+
positionClass: 'bottomRight'
|
|
184
|
+
});
|
|
163
185
|
},
|
|
164
186
|
async closeCreationModal() {
|
|
165
187
|
this.shouldShowCreateModal = false;
|
|
@@ -232,11 +254,25 @@ module.exports = app => app.component('models', {
|
|
|
232
254
|
}
|
|
233
255
|
},
|
|
234
256
|
async openIndexModal() {
|
|
257
|
+
this.closeActionsMenu();
|
|
235
258
|
this.shouldShowIndexModal = true;
|
|
236
259
|
const { mongoDBIndexes, schemaIndexes } = await api.Model.getIndexes({ model: this.currentModel });
|
|
237
260
|
this.mongoDBIndexes = mongoDBIndexes;
|
|
238
261
|
this.schemaIndexes = schemaIndexes;
|
|
239
262
|
},
|
|
263
|
+
toggleActionsMenu() {
|
|
264
|
+
this.showActionsMenu = !this.showActionsMenu;
|
|
265
|
+
},
|
|
266
|
+
closeActionsMenu() {
|
|
267
|
+
this.showActionsMenu = false;
|
|
268
|
+
},
|
|
269
|
+
async openCollectionInfo() {
|
|
270
|
+
this.closeActionsMenu();
|
|
271
|
+
this.shouldShowCollectionInfoModal = true;
|
|
272
|
+
this.collectionInfo = null;
|
|
273
|
+
const { info } = await api.Model.getCollectionInfo({ model: this.currentModel });
|
|
274
|
+
this.collectionInfo = info;
|
|
275
|
+
},
|
|
240
276
|
isTTLIndex(index) {
|
|
241
277
|
return index != null && index.expireAfterSeconds != null;
|
|
242
278
|
},
|
|
@@ -269,6 +305,35 @@ module.exports = app => app.component('models', {
|
|
|
269
305
|
|
|
270
306
|
return parts.join(', ');
|
|
271
307
|
},
|
|
308
|
+
formatCollectionSize(size) {
|
|
309
|
+
if (typeof size !== 'number') {
|
|
310
|
+
return 'Unknown';
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const KB = 1024;
|
|
314
|
+
const MB = KB * 1024;
|
|
315
|
+
const GB = MB * 1024;
|
|
316
|
+
const TB = GB * 1024;
|
|
317
|
+
|
|
318
|
+
if (size >= TB) {
|
|
319
|
+
return `${(size / TB).toFixed(3)} TB`;
|
|
320
|
+
} else if (size >= GB) {
|
|
321
|
+
return `${(size / GB).toFixed(3)} GB`;
|
|
322
|
+
} else if (size >= MB) {
|
|
323
|
+
return `${(size / MB).toFixed(3)} MB`;
|
|
324
|
+
} else if (size >= KB) {
|
|
325
|
+
return `${(size / KB).toFixed(3)} KB`;
|
|
326
|
+
} else {
|
|
327
|
+
return `${size.toLocaleString()} bytes`;
|
|
328
|
+
}
|
|
329
|
+
},
|
|
330
|
+
formatNumber(value) {
|
|
331
|
+
if (typeof value !== 'number') {
|
|
332
|
+
return 'Unknown';
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return value.toLocaleString();
|
|
336
|
+
},
|
|
272
337
|
checkIndexLocation(indexName) {
|
|
273
338
|
if (this.schemaIndexes.find(x => x.name == indexName) && this.mongoDBIndexes.find(x => x.name == indexName)) {
|
|
274
339
|
return 'text-gray-500';
|
|
@@ -442,6 +507,13 @@ module.exports = app => app.component('models', {
|
|
|
442
507
|
this.documents[index] = res.doc;
|
|
443
508
|
}
|
|
444
509
|
this.edittingDoc = null;
|
|
510
|
+
vanillatoasts.create({
|
|
511
|
+
title: 'Document updated!',
|
|
512
|
+
type: 'success',
|
|
513
|
+
timeout: 3000,
|
|
514
|
+
icon: 'images/success.png',
|
|
515
|
+
positionClass: 'bottomRight'
|
|
516
|
+
});
|
|
445
517
|
},
|
|
446
518
|
handleDocumentClick(document, event) {
|
|
447
519
|
if (this.selectMultiple) {
|
|
@@ -505,6 +577,13 @@ module.exports = app => app.component('models', {
|
|
|
505
577
|
this.lastSelectedIndex = null;
|
|
506
578
|
this.shouldShowDeleteMultipleModal = false;
|
|
507
579
|
this.selectMultiple = false;
|
|
580
|
+
vanillatoasts.create({
|
|
581
|
+
title: 'Documents deleted!',
|
|
582
|
+
type: 'success',
|
|
583
|
+
timeout: 3000,
|
|
584
|
+
icon: 'images/success.png',
|
|
585
|
+
positionClass: 'bottomRight'
|
|
586
|
+
});
|
|
508
587
|
},
|
|
509
588
|
async updateDocuments() {
|
|
510
589
|
await this.getDocuments();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const api = require('../api');
|
|
4
|
+
const vanillatoasts = require('vanillatoasts');
|
|
4
5
|
|
|
5
6
|
const { BSON, EJSON } = require('mongodb/lib/bson');
|
|
6
7
|
|
|
@@ -28,35 +29,35 @@ module.exports = app => app.component('update-document', {
|
|
|
28
29
|
methods: {
|
|
29
30
|
async updateDocument() {
|
|
30
31
|
const data = EJSON.serialize(eval(`(${this.editor.getValue()})`));
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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;
|
|
32
|
+
try {
|
|
33
|
+
if (this.multiple) {
|
|
34
|
+
const ids = this.document.map(x => x._id);
|
|
35
|
+
await api.Model.updateDocuments({ model: this.currentModel, _id: ids, update: data });
|
|
36
|
+
} else {
|
|
37
|
+
await api.Model.updateDocument({ model: this.currentModel, _id: this.document._id, update: data });
|
|
38
|
+
}
|
|
39
|
+
this.errors.length = 0;
|
|
40
|
+
this.$emit('update');
|
|
41
|
+
this.$emit('close');
|
|
42
|
+
this.$nextTick(() => {
|
|
43
|
+
vanillatoasts.create({
|
|
44
|
+
title: this.multiple ? 'Documents updated!' : 'Document updated!',
|
|
45
|
+
type: 'success',
|
|
46
|
+
timeout: 3000,
|
|
47
|
+
icon: 'images/success.png',
|
|
48
|
+
positionClass: 'bottomRight'
|
|
49
|
+
});
|
|
55
50
|
});
|
|
51
|
+
} catch (err) {
|
|
52
|
+
if (err.response?.data?.message) {
|
|
53
|
+
console.log(err.response.data);
|
|
54
|
+
const message = err.response.data.message.split(': ').slice(1).join(': ');
|
|
55
|
+
this.errors = message.split(',').map(error => {
|
|
56
|
+
return error.split(': ').slice(1).join(': ').trim();
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
throw err;
|
|
56
60
|
}
|
|
57
|
-
this.errors.length = 0;
|
|
58
|
-
this.$emit('update');
|
|
59
|
-
this.$emit('close');
|
|
60
61
|
}
|
|
61
62
|
},
|
|
62
63
|
mounted: function() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mongoosejs/studio",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
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": {
|