@mongoosejs/studio 0.0.35 → 0.0.37
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/db/dashboardSchema.js +2 -2
- package/frontend/public/app.js +112 -27
- package/frontend/public/tw.css +82 -17
- package/frontend/src/dashboard/dashboard.html +5 -2
- package/frontend/src/dashboard-result/dashboard-document/dashboard-document.js +1 -1
- package/frontend/src/document-details/document-details.html +7 -43
- package/frontend/src/document-details/document-details.js +3 -37
- package/frontend/src/document-details/document-property/document-property.css +23 -0
- package/frontend/src/document-details/document-property/document-property.html +45 -0
- package/frontend/src/document-details/document-property/document-property.js +56 -0
- package/frontend/src/index.js +1 -0
- package/package.json +2 -2
|
@@ -21,9 +21,9 @@ dashboardSchema.methods.evaluate = async function evaluate() {
|
|
|
21
21
|
const context = vm.createContext({ db: this.constructor.db });
|
|
22
22
|
let result = null;
|
|
23
23
|
result = await vm.runInContext(formatFunction(this.code), context);
|
|
24
|
-
if (result.$document?.
|
|
24
|
+
if (result.$document?.constructor?.modelName) {
|
|
25
25
|
let schemaPaths = {};
|
|
26
|
-
const Model = this.constructor.db.model(result.$document?.
|
|
26
|
+
const Model = this.constructor.db.model(result.$document?.constructor?.modelName);
|
|
27
27
|
for (const path of Object.keys(Model.schema.paths)) {
|
|
28
28
|
schemaPaths[path] = {
|
|
29
29
|
instance: Model.schema.paths[path].instance,
|
package/frontend/public/app.js
CHANGED
|
@@ -43,6 +43,9 @@ if (false) {} else {
|
|
|
43
43
|
createDashboard: function createDashboard(params) {
|
|
44
44
|
return client.post('/Dashboard/createDashboard', params).then(res => res.data);
|
|
45
45
|
},
|
|
46
|
+
deleteDashboard: function deleteDashboard(params) {
|
|
47
|
+
return client.post('/Dashboard/deleteDashboard', params).then(res => res.data)
|
|
48
|
+
},
|
|
46
49
|
getDashboard: function getDashboard(params) {
|
|
47
50
|
return client.put('/Dashboard/getDashboard', params).then(res => res.data);
|
|
48
51
|
},
|
|
@@ -367,7 +370,7 @@ module.exports = app => app.component('dashboard-document', {
|
|
|
367
370
|
return null;
|
|
368
371
|
},
|
|
369
372
|
schemaPaths() {
|
|
370
|
-
return Object.keys(this.value.$document
|
|
373
|
+
return Object.keys(this.value.$document?.schemaPaths || {}).sort((k1, k2) => {
|
|
371
374
|
if (k1 === '_id' && k2 !== '_id') {
|
|
372
375
|
return -1;
|
|
373
376
|
}
|
|
@@ -477,6 +480,8 @@ module.exports = app => app.component('dashboard', {
|
|
|
477
480
|
return {
|
|
478
481
|
status: 'loading',
|
|
479
482
|
code: '',
|
|
483
|
+
title: '',
|
|
484
|
+
description: '',
|
|
480
485
|
showEditor: false,
|
|
481
486
|
dashboard: null,
|
|
482
487
|
result: null
|
|
@@ -488,6 +493,8 @@ module.exports = app => app.component('dashboard', {
|
|
|
488
493
|
},
|
|
489
494
|
async updateCode(update) {
|
|
490
495
|
this.code = update.doc.code;
|
|
496
|
+
this.title = update.doc.title;
|
|
497
|
+
this.description = update.doc.description;
|
|
491
498
|
this.result = update.result;
|
|
492
499
|
}
|
|
493
500
|
},
|
|
@@ -498,6 +505,8 @@ module.exports = app => app.component('dashboard', {
|
|
|
498
505
|
}
|
|
499
506
|
this.dashboard = dashboard;
|
|
500
507
|
this.code = this.dashboard.code;
|
|
508
|
+
this.title = this.dashboard.title;
|
|
509
|
+
this.description = this.dashboard.description ?? '';
|
|
501
510
|
this.result = result;
|
|
502
511
|
this.status = 'loaded';
|
|
503
512
|
}
|
|
@@ -520,11 +529,13 @@ const template = __webpack_require__(/*! ./edit-dashboard.html */ "./frontend/sr
|
|
|
520
529
|
|
|
521
530
|
module.exports = app => app.component('edit-dashboard', {
|
|
522
531
|
template: template,
|
|
523
|
-
props: ['dashboardId', 'code'],
|
|
532
|
+
props: ['dashboardId', 'code', 'currentDescription', 'currentTitle'],
|
|
524
533
|
data: function() {
|
|
525
534
|
return {
|
|
526
535
|
status: 'loading',
|
|
527
536
|
editor: null,
|
|
537
|
+
title: '',
|
|
538
|
+
description: ''
|
|
528
539
|
}
|
|
529
540
|
},
|
|
530
541
|
methods: {
|
|
@@ -532,9 +543,12 @@ module.exports = app => app.component('edit-dashboard', {
|
|
|
532
543
|
this.$emit('close')
|
|
533
544
|
},
|
|
534
545
|
async updateCode() {
|
|
546
|
+
console.log('this.title', this.title, 'this.description', this.description)
|
|
535
547
|
const { doc, result } = await api.Dashboard.updateDashboard({
|
|
536
548
|
dashboardId: this.dashboardId,
|
|
537
|
-
code: this.editor.getValue()
|
|
549
|
+
code: this.editor.getValue(),
|
|
550
|
+
title: this.title,
|
|
551
|
+
description: this.description
|
|
538
552
|
});
|
|
539
553
|
this.$emit('update', { doc, result });
|
|
540
554
|
this.editor.setValue(doc.code);
|
|
@@ -560,8 +574,8 @@ module.exports = app => app.component('edit-dashboard', {
|
|
|
560
574
|
|
|
561
575
|
this.editor.focus();
|
|
562
576
|
// this.editor.refresh(); // if anything weird happens on load, this usually fixes it. However, this breaks it in this case.
|
|
563
|
-
|
|
564
|
-
|
|
577
|
+
this.description = this.currentDescription;
|
|
578
|
+
this.title = this.currentTitle;
|
|
565
579
|
}
|
|
566
580
|
});
|
|
567
581
|
|
|
@@ -586,8 +600,24 @@ module.exports = app => app.component('dashboards', {
|
|
|
586
600
|
data: () => ({
|
|
587
601
|
status: 'loading',
|
|
588
602
|
dashboards: [],
|
|
589
|
-
showCreateDashboardModal: false
|
|
603
|
+
showCreateDashboardModal: false,
|
|
604
|
+
showDeleteDashboardModal: null
|
|
590
605
|
}),
|
|
606
|
+
methods: {
|
|
607
|
+
async deleteDashboard(dashboard) {
|
|
608
|
+
if (!dashboard) {
|
|
609
|
+
return;
|
|
610
|
+
}
|
|
611
|
+
await api.Dashboard.deleteDashboard({ dashboardId: dashboard._id });
|
|
612
|
+
const removedDashboard = this.dashboards.findIndex(x => x._id.toString() === dashboard._id.toString());
|
|
613
|
+
this.dashboards.splice(removedDashboard, 1);
|
|
614
|
+
this.showDeleteDashboardModal = null;
|
|
615
|
+
},
|
|
616
|
+
insertNewDashboard(dashboard) {
|
|
617
|
+
this.dashboards.push(dashboard);
|
|
618
|
+
this.showCreateDashboardModal = false;
|
|
619
|
+
}
|
|
620
|
+
},
|
|
591
621
|
async mounted() {
|
|
592
622
|
const { dashboards } = await api.Dashboard.getDashboards();
|
|
593
623
|
this.dashboards = dashboards;
|
|
@@ -674,6 +704,49 @@ const appendCSS = __webpack_require__(/*! ../appendCSS */ "./frontend/src/append
|
|
|
674
704
|
appendCSS(__webpack_require__(/*! ./document-details.css */ "./frontend/src/document-details/document-details.css"));
|
|
675
705
|
|
|
676
706
|
module.exports = app => app.component('document-details', {
|
|
707
|
+
template,
|
|
708
|
+
props: ['document', 'schemaPaths', 'editting', 'changes', 'invalid'],
|
|
709
|
+
computed: {
|
|
710
|
+
virtuals() {
|
|
711
|
+
if (this.schemaPaths == null) {
|
|
712
|
+
return [];
|
|
713
|
+
}
|
|
714
|
+
if (this.document == null) {
|
|
715
|
+
return [];
|
|
716
|
+
}
|
|
717
|
+
const exists = this.schemaPaths.map(x => x.path);
|
|
718
|
+
const docKeys = Object.keys(this.document);
|
|
719
|
+
const result = [];
|
|
720
|
+
for (let i = 0; i < docKeys.length; i++) {
|
|
721
|
+
if (!exists.includes(docKeys[i])) {
|
|
722
|
+
result.push({ name: docKeys[i], value: this.document[docKeys[i]] });
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
return result;
|
|
727
|
+
},
|
|
728
|
+
}
|
|
729
|
+
})
|
|
730
|
+
|
|
731
|
+
/***/ }),
|
|
732
|
+
|
|
733
|
+
/***/ "./frontend/src/document-details/document-property/document-property.js":
|
|
734
|
+
/*!******************************************************************************!*\
|
|
735
|
+
!*** ./frontend/src/document-details/document-property/document-property.js ***!
|
|
736
|
+
\******************************************************************************/
|
|
737
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
738
|
+
|
|
739
|
+
"use strict";
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
const mpath = __webpack_require__(/*! mpath */ "./node_modules/mpath/index.js");
|
|
743
|
+
const template = __webpack_require__(/*! ./document-property.html */ "./frontend/src/document-details/document-property/document-property.html")
|
|
744
|
+
|
|
745
|
+
const appendCSS = __webpack_require__(/*! ../../appendCSS */ "./frontend/src/appendCSS.js");
|
|
746
|
+
|
|
747
|
+
appendCSS(__webpack_require__(/*! ./document-property.css */ "./frontend/src/document-details/document-property/document-property.css"));
|
|
748
|
+
|
|
749
|
+
module.exports = app => app.component('document-property', {
|
|
677
750
|
template,
|
|
678
751
|
data: function() {
|
|
679
752
|
return {
|
|
@@ -704,31 +777,20 @@ module.exports = app => app.component('document-details', {
|
|
|
704
777
|
return 'edit-default';
|
|
705
778
|
},
|
|
706
779
|
getValueForPath(path) {
|
|
780
|
+
if (this.document == null) {
|
|
781
|
+
return undefined;
|
|
782
|
+
}
|
|
707
783
|
return mpath.get(path, this.document);
|
|
708
784
|
},
|
|
709
785
|
getEditValueForPath({ path }) {
|
|
710
786
|
if (!this.changes) {
|
|
711
787
|
return;
|
|
712
788
|
}
|
|
789
|
+
if (!this.document) {
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
713
792
|
return path in this.changes ? this.changes[path] : mpath.get(path, this.document);
|
|
714
793
|
}
|
|
715
|
-
},
|
|
716
|
-
computed: {
|
|
717
|
-
virtuals() {
|
|
718
|
-
if (this.schemaPaths == null) {
|
|
719
|
-
return [];
|
|
720
|
-
}
|
|
721
|
-
const exists = this.schemaPaths.map(x => x.path);
|
|
722
|
-
const docKeys = Object.keys(this.document);
|
|
723
|
-
const result = [];
|
|
724
|
-
for (let i = 0; i < docKeys.length; i++) {
|
|
725
|
-
if (!exists.includes(docKeys[i])) {
|
|
726
|
-
result.push({ name: docKeys[i], value: this.document[docKeys[i]] });
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
return result;
|
|
731
|
-
},
|
|
732
794
|
}
|
|
733
795
|
})
|
|
734
796
|
|
|
@@ -2520,7 +2582,7 @@ module.exports = "<div>\n <div v-if=\"Array.isArray(result)\">\n <div v-for=
|
|
|
2520
2582
|
/***/ ((module) => {
|
|
2521
2583
|
|
|
2522
2584
|
"use strict";
|
|
2523
|
-
module.exports = "<div class=\"dashboard px-1\">\n <div v-if=\"dashboard\" class=\"max-w-5xl mx-auto\">\n <div class=\"flex items-center w-full\">\n <h2 class=\"mt-4 mb-4 text-gray-900 font-semibold text-xl grow shrink\">{{
|
|
2585
|
+
module.exports = "<div class=\"dashboard px-1\">\n <div v-if=\"status === 'loading'\" class=\"max-w-5xl mx-auto text-center\">\n <img src=\"images/loader.gif\" class=\"inline\">\n </div>\n <div v-if=\"dashboard && status === 'loaded'\" class=\"max-w-5xl mx-auto\">\n <div class=\"flex items-center w-full\">\n <h2 class=\"mt-4 mb-4 text-gray-900 font-semibold text-xl grow shrink\">{{title}}</h2>\n <div>\n <button\n v-if=\"!showEditor\"\n @click=\"showEditor = true\"\n type=\"button\"\n class=\"rounded-md bg-teal-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">\n <img src=\"images/edit.svg\" class=\"inline h-[1em]\" /> Edit\n </button>\n </div>\n </div>\n <div v-if=\"!showEditor\" class=\"mt-4 mb-4\">\n <dashboard-result :result=\"result\"></dashboard-result>\n </div>\n <div v-if=\"showEditor\">\n <edit-dashboard\n :dashboardId=\"dashboard._id\"\n :code=\"code\"\n :currentDescription=\"description\"\n :currentTitle=\"title\"\n @close=\"showEditor=false;\"\n @update=\"updateCode\"></edit-dashboard>\n </div>\n \n </div>\n <div v-if=\"!dashboard && status === 'loaded'\">\n No dashboard with the given id could be found.\n </div>\n</div>\n";
|
|
2524
2586
|
|
|
2525
2587
|
/***/ }),
|
|
2526
2588
|
|
|
@@ -2531,7 +2593,7 @@ module.exports = "<div class=\"dashboard px-1\">\n <div v-if=\"dashboard\" clas
|
|
|
2531
2593
|
/***/ ((module) => {
|
|
2532
2594
|
|
|
2533
2595
|
"use strict";
|
|
2534
|
-
module.exports = "<div>\n <textarea ref=\"codeEditor\">{{code}}</textarea>\n <button @click=\"updateCode\"
|
|
2596
|
+
module.exports = "<div class=\"p-4 bg-gray-100 rounded-lg shadow-lg\">\n <div>\n <input v-model=\"title\" class=\"w-full p-2 mb-4 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\" placeholder=\"Title\"/>\n </div>\n <div>\n <textarea v-model=\"description\" class=\"w-full p-2 mb-4 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\" rows=\"4\" placeholder=\"Description\">{{description}}</textarea>\n </div>\n <div>\n <textarea ref=\"codeEditor\" class=\"w-full p-2 mb-4 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500\" rows=\"6\">{{code}}</textarea>\n </div>\n <div class=\"flex space-x-2\">\n <button @click=\"updateCode\" class=\"px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500\">Submit</button>\n <button @click=\"closeEditor\" class=\"px-4 py-2 bg-gray-500 text-white rounded-md hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-500\">Cancel</button>\n </div>\n</div>";
|
|
2535
2597
|
|
|
2536
2598
|
/***/ }),
|
|
2537
2599
|
|
|
@@ -2542,7 +2604,7 @@ module.exports = "<div>\n <textarea ref=\"codeEditor\">{{code}}</textarea>\n
|
|
|
2542
2604
|
/***/ ((module) => {
|
|
2543
2605
|
|
|
2544
2606
|
"use strict";
|
|
2545
|
-
module.exports = "<div class=\"dashboards max-w-5xl mx-auto mt-8\">\n <div v-if=\"status === 'loaded' && dashboards.length === 0\">\n <div class=\"text-center\">\n <h3 class=\"mt-2 text-sm font-semibold text-gray-900\">No dashboards yet</h3>\n <p class=\"mt-1 text-sm text-gray-500\">Get started by creating a new dashboard.</p>\n <div class=\"mt-6\">\n <button type=\"button\" class=\"inline-flex items-center rounded-md bg-teal-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z\" />\n </svg>\n New Dashboard\n </button>\n </div>\n </div>\n </div>\n\n\n <div class=\"px-4 sm:px-6 lg:px-8\">\n <div class=\"sm:flex sm:items-center\">\n <div class=\"sm:flex-auto\">\n <h1 class=\"text-base font-semibold leading-6 text-gray-900\">Dashboards</h1>\n </div>\n <div class=\"mt-4 sm:ml-16 sm:mt-0 sm:flex-none\">\n <button\n type=\"button\"\n @click=\"showCreateDashboardModal = true\"\n class=\"block rounded-md bg-teal-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">Create New Dashboard</button>\n </div>\n </div>\n <div class=\"mt-8 flow-root\">\n <div class=\"-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8\">\n <div class=\"inline-block min-w-full py-2 align-middle\">\n <table class=\"min-w-full divide-y divide-gray-300\">\n <thead>\n <tr>\n <th scope=\"col\" class=\"py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg:pl-8\">Title</th>\n <th scope=\"col\" class=\"px-3 py-3.5 text-left text-sm font-semibold text-gray-900 w-[50%]\">Description</th>\n <th scope=\"col\" class=\"relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8\">\n </th>\n <th scope=\"col\" class=\"relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8\">\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr v-for=\"dashboard in dashboards\">\n <td class=\"whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8\">{{dashboard.title}}</td>\n <td class=\"whitespace-nowrap px-3 py-4 text-sm text-gray-500 truncate w-[50%]\">{{dashboard.description}}</td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <router-link\n :to=\"'/dashboard/' + dashboard._id + '?edit=true'\"\n class=\"text-teal-600 hover:text-teal-900\">\n Edit\n </router-link>\n </td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <router-link\n :to=\"'/dashboard/' + dashboard._id\"\n class=\"text-teal-600 hover:text-teal-900\">\n View\n </router-link>\n </td>\n </tr>\n \n <!-- More people... -->\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n\n <modal v-if=\"showCreateDashboardModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"showCreateDashboardModal = false;\">×</div>\n \n <create-dashboard></create-dashboard>\n </template>\n </modal>\n</div>";
|
|
2607
|
+
module.exports = "<div class=\"dashboards max-w-5xl mx-auto mt-8\">\n <div v-if=\"status === 'loaded' && dashboards.length === 0\">\n <div class=\"text-center\">\n <h3 class=\"mt-2 text-sm font-semibold text-gray-900\">No dashboards yet</h3>\n <p class=\"mt-1 text-sm text-gray-500\">Get started by creating a new dashboard.</p>\n <div class=\"mt-6\">\n <button type=\"button\" class=\"inline-flex items-center rounded-md bg-teal-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z\" />\n </svg>\n New Dashboard\n </button>\n </div>\n </div>\n </div>\n\n\n <div class=\"px-4 sm:px-6 lg:px-8\">\n <div class=\"sm:flex sm:items-center\">\n <div class=\"sm:flex-auto\">\n <h1 class=\"text-base font-semibold leading-6 text-gray-900\">Dashboards</h1>\n </div>\n <div class=\"mt-4 sm:ml-16 sm:mt-0 sm:flex-none\">\n <button\n type=\"button\"\n @click=\"showCreateDashboardModal = true\"\n class=\"block rounded-md bg-teal-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">Create New Dashboard</button>\n </div>\n </div>\n <div class=\"mt-8 flow-root\">\n <div class=\"-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8\">\n <div class=\"inline-block min-w-full py-2 align-middle\">\n <table class=\"min-w-full divide-y divide-gray-300\">\n <thead>\n <tr>\n <th scope=\"col\" class=\"py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg:pl-8\">Title</th>\n <th scope=\"col\" class=\"px-3 py-3.5 text-left text-sm font-semibold text-gray-900 w-[50%]\">Description</th>\n <th scope=\"col\" class=\"relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8\">\n </th>\n <th scope=\"col\" class=\"relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8\">\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr v-for=\"dashboard in dashboards\">\n <td class=\"whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8\">{{dashboard.title}}</td>\n <td class=\"whitespace-nowrap px-3 py-4 text-sm text-gray-500 truncate w-[50%]\">{{dashboard.description}}</td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <router-link\n :to=\"'/dashboard/' + dashboard._id + '?edit=true'\"\n class=\"text-teal-600 hover:text-teal-900\">\n Edit\n </router-link>\n </td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <router-link\n :to=\"'/dashboard/' + dashboard._id\"\n class=\"text-teal-600 hover:text-teal-900\">\n View\n </router-link>\n </td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <button\n @click=\"showDeleteDashboardModal=dashboard\"\n class=\"text-teal-600 hover:text-teal-900\">\n Delete\n </button>\n </td>\n </tr>\n \n <!-- More people... -->\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n\n <modal v-if=\"showCreateDashboardModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"showCreateDashboardModal = false;\">×</div>\n \n <create-dashboard @close=\"insertNewDashboard\"></create-dashboard>\n </template>\n </modal>\n\n <modal v-if=\"showDeleteDashboardModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"showDeleteDashboardModal = null;\">×</div>\n <h2>Are you sure you want to delete this dashboard titled {{showDeleteDashboardModal.title}}?</h2>\n <div class=\"flex space-x-2\">\n <button class=\"px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500\" @click=\"deleteDashboard(showDeleteDashboardModal)\">Yes, delete</button>\n <button class=\"px-4 py-2 bg-gray-500 text-white rounded-md hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-600\" @click=\"showDeleteDashboardModal=null;\">Cancel</button>\n </div>\n </template>\n </modal>\n</div>";
|
|
2546
2608
|
|
|
2547
2609
|
/***/ }),
|
|
2548
2610
|
|
|
@@ -2586,7 +2648,29 @@ module.exports = ".document-details {\n width: 100%;\n}\n\n.document-details .v
|
|
|
2586
2648
|
/***/ ((module) => {
|
|
2587
2649
|
|
|
2588
2650
|
"use strict";
|
|
2589
|
-
module.exports = "<div class=\"document-details\">\n <
|
|
2651
|
+
module.exports = "<div class=\"document-details\">\n <document-property\n :document=\"document\"\n :schemaPaths=\"schemaPaths\"\n :editting=\"editting\"\n :changes=\"changes\"\n :invalid=\"invalid\"></document-property>\n <div v-for=\"path in virtuals\" class=\"mb-2\">\n <div class=\"p-1 mb-1 bg-slate-100\">\n {{path.name}}\n <span class=\"path-type\">\n (virtual)\n </span>\n </div>\n <div v-if=\"path.value == null\" class=\"text-sky-800\">\n {{'' + path.value}}\n </div>\n <div v-else>\n {{path.value}}\n </div>\n </div>\n</div>";
|
|
2652
|
+
|
|
2653
|
+
/***/ }),
|
|
2654
|
+
|
|
2655
|
+
/***/ "./frontend/src/document-details/document-property/document-property.css":
|
|
2656
|
+
/*!*******************************************************************************!*\
|
|
2657
|
+
!*** ./frontend/src/document-details/document-property/document-property.css ***!
|
|
2658
|
+
\*******************************************************************************/
|
|
2659
|
+
/***/ ((module) => {
|
|
2660
|
+
|
|
2661
|
+
"use strict";
|
|
2662
|
+
module.exports = ".document-details {\n width: 100%;\n }\n \n .document-details .value {\n padding-top: 10px;\n padding-bottom: 10px;\n }\n \n .document-details .path-key {\n background-color: #f0f0f0;\n margin-bottom: 0.5em;\n }\n \n .document-details .path-type {\n color: rgba(0,0,0,.36);\n font-size: 0.8em;\n }\n \n .document-details .date-position {\n float: right;\n margin-top: -7px;\n }";
|
|
2663
|
+
|
|
2664
|
+
/***/ }),
|
|
2665
|
+
|
|
2666
|
+
/***/ "./frontend/src/document-details/document-property/document-property.html":
|
|
2667
|
+
/*!********************************************************************************!*\
|
|
2668
|
+
!*** ./frontend/src/document-details/document-property/document-property.html ***!
|
|
2669
|
+
\********************************************************************************/
|
|
2670
|
+
/***/ ((module) => {
|
|
2671
|
+
|
|
2672
|
+
"use strict";
|
|
2673
|
+
module.exports = "<div>\n <div v-for=\"path in schemaPaths\" class=\"value\">\n <div class=\"relative path-key p-1 flex\">\n <div class=\"grow\">\n {{path.path}}\n <span class=\"path-type\">\n ({{(path.instance || 'unknown').toLowerCase()}})\n </span>\n </div>\n <div v-if=\"editting && path.instance === 'Date'\" class=\"flex gap-1.5\">\n <div\n @click=\"dateType = 'picker'\"\n :class=\"dateType === 'picker' ? 'bg-white' : ''\"\n class=\"self-stretch px-2 py-1 rounded-sm justify-center items-center gap-1.5 flex cursor-pointer\">\n <div\n :class=\"dateType === 'picker' ? 'text-sky-600' : 'text-black'\"\n class=\"text-xs font-medium font-['Lato'] capitalize leading-tight\">\n Date Picker\n </div>\n </div>\n <div\n @click=\"dateType = 'iso'\"\n :class=\"dateType === 'iso' ? 'bg-white' : ''\"\n class=\"self-stretch px-2 py-1 rounded-sm justify-center items-center gap-1.5 flex cursor-pointer\">\n <div\n :class=\"dateType === 'iso' ? 'text-sky-600' : 'text-black'\"\n class=\"text-xs font-medium font-['Lato'] capitalize leading-tight\">\n ISO String\n </div>\n </div>\n </div>\n </div>\n <div v-if=\"editting && path.path !== '_id'\" class=\"pl-1\">\n <component\n :is=\"getEditComponentForPath(path)\"\n :value=\"getEditValueForPath(path)\"\n :format=\"dateType\"\n @input=\"changes[path.path] = $event; delete invalid[path.path];\"\n @error=\"invalid[path.path] = $event;\"\n >\n </component>\n </div>\n <div v-else class=\"pl-1\">\n <component :is=\"getComponentForPath(path)\" :value=\"getValueForPath(path.path)\"></component>\n </div>\n </div>\n</div>";
|
|
2590
2674
|
|
|
2591
2675
|
/***/ }),
|
|
2592
2676
|
|
|
@@ -10577,6 +10661,7 @@ __webpack_require__(/*! ./detail-default/detail-default */ "./frontend/src/detai
|
|
|
10577
10661
|
__webpack_require__(/*! ./document/document */ "./frontend/src/document/document.js")(app);
|
|
10578
10662
|
__webpack_require__(/*! ./document/confirm-changes/confirm-changes */ "./frontend/src/document/confirm-changes/confirm-changes.js")(app);
|
|
10579
10663
|
__webpack_require__(/*! ./document-details/document-details */ "./frontend/src/document-details/document-details.js")(app);
|
|
10664
|
+
__webpack_require__(/*! ./document-details/document-property/document-property */ "./frontend/src/document-details/document-property/document-property.js")(app);
|
|
10580
10665
|
__webpack_require__(/*! ./edit-array/edit-array */ "./frontend/src/edit-array/edit-array.js")(app);
|
|
10581
10666
|
__webpack_require__(/*! ./edit-default/edit-default */ "./frontend/src/edit-default/edit-default.js")(app);
|
|
10582
10667
|
__webpack_require__(/*! ./edit-number/edit-number */ "./frontend/src/edit-number/edit-number.js")(app);
|
package/frontend/public/tw.css
CHANGED
|
@@ -582,10 +582,6 @@ video {
|
|
|
582
582
|
position: fixed;
|
|
583
583
|
}
|
|
584
584
|
|
|
585
|
-
.absolute {
|
|
586
|
-
position: absolute;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
585
|
.relative {
|
|
590
586
|
position: relative;
|
|
591
587
|
}
|
|
@@ -642,10 +638,6 @@ video {
|
|
|
642
638
|
margin-bottom: 1rem;
|
|
643
639
|
}
|
|
644
640
|
|
|
645
|
-
.mb-\[-1px\] {
|
|
646
|
-
margin-bottom: -1px;
|
|
647
|
-
}
|
|
648
|
-
|
|
649
641
|
.ml-3 {
|
|
650
642
|
margin-left: 0.75rem;
|
|
651
643
|
}
|
|
@@ -822,6 +814,12 @@ video {
|
|
|
822
814
|
row-gap: 1.75rem;
|
|
823
815
|
}
|
|
824
816
|
|
|
817
|
+
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
|
|
818
|
+
--tw-space-x-reverse: 0;
|
|
819
|
+
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
|
|
820
|
+
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
|
|
821
|
+
}
|
|
822
|
+
|
|
825
823
|
.space-y-1 > :not([hidden]) ~ :not([hidden]) {
|
|
826
824
|
--tw-space-y-reverse: 0;
|
|
827
825
|
margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));
|
|
@@ -874,6 +872,10 @@ video {
|
|
|
874
872
|
border-radius: 0.25rem;
|
|
875
873
|
}
|
|
876
874
|
|
|
875
|
+
.rounded-lg {
|
|
876
|
+
border-radius: 0.5rem;
|
|
877
|
+
}
|
|
878
|
+
|
|
877
879
|
.rounded-md {
|
|
878
880
|
border-radius: 0.375rem;
|
|
879
881
|
}
|
|
@@ -882,10 +884,6 @@ video {
|
|
|
882
884
|
border-radius: 0px;
|
|
883
885
|
}
|
|
884
886
|
|
|
885
|
-
.rounded-xl {
|
|
886
|
-
border-radius: 0.75rem;
|
|
887
|
-
}
|
|
888
|
-
|
|
889
887
|
.rounded-sm {
|
|
890
888
|
border-radius: 0.125rem;
|
|
891
889
|
}
|
|
@@ -944,11 +942,26 @@ video {
|
|
|
944
942
|
border-color: transparent;
|
|
945
943
|
}
|
|
946
944
|
|
|
945
|
+
.bg-blue-500 {
|
|
946
|
+
--tw-bg-opacity: 1;
|
|
947
|
+
background-color: rgb(59 130 246 / var(--tw-bg-opacity));
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
.bg-gray-100 {
|
|
951
|
+
--tw-bg-opacity: 1;
|
|
952
|
+
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
|
|
953
|
+
}
|
|
954
|
+
|
|
947
955
|
.bg-gray-200 {
|
|
948
956
|
--tw-bg-opacity: 1;
|
|
949
957
|
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
|
|
950
958
|
}
|
|
951
959
|
|
|
960
|
+
.bg-gray-500 {
|
|
961
|
+
--tw-bg-opacity: 1;
|
|
962
|
+
background-color: rgb(107 114 128 / var(--tw-bg-opacity));
|
|
963
|
+
}
|
|
964
|
+
|
|
952
965
|
.bg-green-600 {
|
|
953
966
|
--tw-bg-opacity: 1;
|
|
954
967
|
background-color: rgb(22 163 74 / var(--tw-bg-opacity));
|
|
@@ -959,6 +972,11 @@ video {
|
|
|
959
972
|
background-color: rgb(254 242 242 / var(--tw-bg-opacity));
|
|
960
973
|
}
|
|
961
974
|
|
|
975
|
+
.bg-red-500 {
|
|
976
|
+
--tw-bg-opacity: 1;
|
|
977
|
+
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
|
978
|
+
}
|
|
979
|
+
|
|
962
980
|
.bg-red-600 {
|
|
963
981
|
--tw-bg-opacity: 1;
|
|
964
982
|
background-color: rgb(220 38 38 / var(--tw-bg-opacity));
|
|
@@ -1209,11 +1227,6 @@ video {
|
|
|
1209
1227
|
color: rgb(153 27 27 / var(--tw-text-opacity));
|
|
1210
1228
|
}
|
|
1211
1229
|
|
|
1212
|
-
.text-sky-600 {
|
|
1213
|
-
--tw-text-opacity: 1;
|
|
1214
|
-
color: rgb(2 132 199 / var(--tw-text-opacity));
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
1230
|
.text-sky-800 {
|
|
1218
1231
|
--tw-text-opacity: 1;
|
|
1219
1232
|
color: rgb(7 89 133 / var(--tw-text-opacity));
|
|
@@ -1229,6 +1242,12 @@ video {
|
|
|
1229
1242
|
color: rgb(255 255 255 / var(--tw-text-opacity));
|
|
1230
1243
|
}
|
|
1231
1244
|
|
|
1245
|
+
.shadow-lg {
|
|
1246
|
+
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
1247
|
+
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
|
|
1248
|
+
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1232
1251
|
.shadow-sm {
|
|
1233
1252
|
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
1234
1253
|
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
|
|
@@ -1309,6 +1328,11 @@ video {
|
|
|
1309
1328
|
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
|
1310
1329
|
}
|
|
1311
1330
|
|
|
1331
|
+
.hover\:bg-blue-600:hover {
|
|
1332
|
+
--tw-bg-opacity: 1;
|
|
1333
|
+
background-color: rgb(37 99 235 / var(--tw-bg-opacity));
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1312
1336
|
.hover\:bg-gray-300:hover {
|
|
1313
1337
|
--tw-bg-opacity: 1;
|
|
1314
1338
|
background-color: rgb(209 213 219 / var(--tw-bg-opacity));
|
|
@@ -1319,6 +1343,11 @@ video {
|
|
|
1319
1343
|
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
|
|
1320
1344
|
}
|
|
1321
1345
|
|
|
1346
|
+
.hover\:bg-gray-600:hover {
|
|
1347
|
+
--tw-bg-opacity: 1;
|
|
1348
|
+
background-color: rgb(75 85 99 / var(--tw-bg-opacity));
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1322
1351
|
.hover\:bg-green-500:hover {
|
|
1323
1352
|
--tw-bg-opacity: 1;
|
|
1324
1353
|
background-color: rgb(34 197 94 / var(--tw-bg-opacity));
|
|
@@ -1329,6 +1358,11 @@ video {
|
|
|
1329
1358
|
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
|
1330
1359
|
}
|
|
1331
1360
|
|
|
1361
|
+
.hover\:bg-red-600:hover {
|
|
1362
|
+
--tw-bg-opacity: 1;
|
|
1363
|
+
background-color: rgb(220 38 38 / var(--tw-bg-opacity));
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1332
1366
|
.hover\:bg-slate-500:hover {
|
|
1333
1367
|
--tw-bg-opacity: 1;
|
|
1334
1368
|
background-color: rgb(100 116 139 / var(--tw-bg-opacity));
|
|
@@ -1358,12 +1392,43 @@ video {
|
|
|
1358
1392
|
z-index: 10;
|
|
1359
1393
|
}
|
|
1360
1394
|
|
|
1395
|
+
.focus\:outline-none:focus {
|
|
1396
|
+
outline: 2px solid transparent;
|
|
1397
|
+
outline-offset: 2px;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1361
1400
|
.focus\:ring-0:focus {
|
|
1362
1401
|
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
1363
1402
|
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
1364
1403
|
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
1365
1404
|
}
|
|
1366
1405
|
|
|
1406
|
+
.focus\:ring-2:focus {
|
|
1407
|
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
1408
|
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
1409
|
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
.focus\:ring-blue-500:focus {
|
|
1413
|
+
--tw-ring-opacity: 1;
|
|
1414
|
+
--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity));
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
.focus\:ring-gray-500:focus {
|
|
1418
|
+
--tw-ring-opacity: 1;
|
|
1419
|
+
--tw-ring-color: rgb(107 114 128 / var(--tw-ring-opacity));
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
.focus\:ring-gray-600:focus {
|
|
1423
|
+
--tw-ring-opacity: 1;
|
|
1424
|
+
--tw-ring-color: rgb(75 85 99 / var(--tw-ring-opacity));
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
.focus\:ring-red-500:focus {
|
|
1428
|
+
--tw-ring-opacity: 1;
|
|
1429
|
+
--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity));
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1367
1432
|
.focus-visible\:outline:focus-visible {
|
|
1368
1433
|
outline-style: solid;
|
|
1369
1434
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
<div class="dashboard px-1">
|
|
2
|
-
<div v-if="
|
|
2
|
+
<div v-if="status === 'loading'" class="max-w-5xl mx-auto text-center">
|
|
3
|
+
<img src="images/loader.gif" class="inline mt-10">
|
|
4
|
+
</div>
|
|
5
|
+
<div v-if="dashboard && status === 'loaded'" class="max-w-5xl mx-auto">
|
|
3
6
|
<div class="flex items-center w-full">
|
|
4
7
|
<h2 class="mt-4 mb-4 text-gray-900 font-semibold text-xl grow shrink">{{title}}</h2>
|
|
5
8
|
<div>
|
|
@@ -29,4 +32,4 @@
|
|
|
29
32
|
<div v-if="!dashboard && status === 'loaded'">
|
|
30
33
|
No dashboard with the given id could be found.
|
|
31
34
|
</div>
|
|
32
|
-
</div>
|
|
35
|
+
</div>
|
|
@@ -15,7 +15,7 @@ module.exports = app => app.component('dashboard-document', {
|
|
|
15
15
|
return null;
|
|
16
16
|
},
|
|
17
17
|
schemaPaths() {
|
|
18
|
-
return Object.keys(this.value.$document
|
|
18
|
+
return Object.keys(this.value.$document?.schemaPaths || {}).sort((k1, k2) => {
|
|
19
19
|
if (k1 === '_id' && k2 !== '_id') {
|
|
20
20
|
return -1;
|
|
21
21
|
}
|
|
@@ -1,48 +1,12 @@
|
|
|
1
1
|
<div class="document-details">
|
|
2
2
|
<div v-for="path in schemaPaths" class="value">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<div v-if="editting && path.instance === 'Date'" class="flex gap-1.5">
|
|
11
|
-
<div
|
|
12
|
-
@click="dateType = 'picker'"
|
|
13
|
-
:class="dateType === 'picker' ? 'bg-white' : ''"
|
|
14
|
-
class="self-stretch px-2 py-1 rounded-sm justify-center items-center gap-1.5 flex cursor-pointer">
|
|
15
|
-
<div
|
|
16
|
-
:class="dateType === 'picker' ? 'text-sky-600' : 'text-black'"
|
|
17
|
-
class="text-xs font-medium font-['Lato'] capitalize leading-tight">
|
|
18
|
-
Date Picker
|
|
19
|
-
</div>
|
|
20
|
-
</div>
|
|
21
|
-
<div
|
|
22
|
-
@click="dateType = 'iso'"
|
|
23
|
-
:class="dateType === 'iso' ? 'bg-white' : ''"
|
|
24
|
-
class="self-stretch px-2 py-1 rounded-sm justify-center items-center gap-1.5 flex cursor-pointer">
|
|
25
|
-
<div
|
|
26
|
-
:class="dateType === 'iso' ? 'text-sky-600' : 'text-black'"
|
|
27
|
-
class="text-xs font-medium font-['Lato'] capitalize leading-tight">
|
|
28
|
-
ISO String
|
|
29
|
-
</div>
|
|
30
|
-
</div>
|
|
31
|
-
</div>
|
|
32
|
-
</div>
|
|
33
|
-
<div v-if="editting && path.path !== '_id'" class="pl-1">
|
|
34
|
-
<component
|
|
35
|
-
:is="getEditComponentForPath(path)"
|
|
36
|
-
:value="getEditValueForPath(path)"
|
|
37
|
-
:format="dateType"
|
|
38
|
-
@input="changes[path.path] = $event; delete invalid[path.path];"
|
|
39
|
-
@error="invalid[path.path] = $event;"
|
|
40
|
-
>
|
|
41
|
-
</component>
|
|
42
|
-
</div>
|
|
43
|
-
<div v-else class="pl-1">
|
|
44
|
-
<component :is="getComponentForPath(path)" :value="getValueForPath(path.path)"></component>
|
|
45
|
-
</div>
|
|
3
|
+
<document-property
|
|
4
|
+
:path="path"
|
|
5
|
+
:document="document"
|
|
6
|
+
:schemaPaths="schemaPaths"
|
|
7
|
+
:editting="editting"
|
|
8
|
+
:changes="changes"
|
|
9
|
+
:invalid="invalid"></document-property>
|
|
46
10
|
</div>
|
|
47
11
|
<div v-for="path in virtuals" class="mb-2">
|
|
48
12
|
<div class="p-1 mb-1 bg-slate-100">
|
|
@@ -9,49 +9,15 @@ appendCSS(require('./document-details.css'));
|
|
|
9
9
|
|
|
10
10
|
module.exports = app => app.component('document-details', {
|
|
11
11
|
template,
|
|
12
|
-
data: function() {
|
|
13
|
-
return {
|
|
14
|
-
dateType: 'picker' // picker, iso
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
12
|
props: ['document', 'schemaPaths', 'editting', 'changes', 'invalid'],
|
|
18
|
-
methods: {
|
|
19
|
-
getComponentForPath(schemaPath) {
|
|
20
|
-
if (schemaPath.instance === 'Array') {
|
|
21
|
-
return 'detail-array';
|
|
22
|
-
}
|
|
23
|
-
return 'detail-default';
|
|
24
|
-
},
|
|
25
|
-
getEditComponentForPath(path) {
|
|
26
|
-
if (path.instance == 'Date') {
|
|
27
|
-
return 'edit-date';
|
|
28
|
-
}
|
|
29
|
-
if (path.instance == 'Number') {
|
|
30
|
-
return 'edit-number';
|
|
31
|
-
}
|
|
32
|
-
if (path.instance === 'Array') {
|
|
33
|
-
return 'edit-array';
|
|
34
|
-
}
|
|
35
|
-
if (path.instance === 'Embedded') {
|
|
36
|
-
return 'edit-subdocument';
|
|
37
|
-
}
|
|
38
|
-
return 'edit-default';
|
|
39
|
-
},
|
|
40
|
-
getValueForPath(path) {
|
|
41
|
-
return mpath.get(path, this.document);
|
|
42
|
-
},
|
|
43
|
-
getEditValueForPath({ path }) {
|
|
44
|
-
if (!this.changes) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
return path in this.changes ? this.changes[path] : mpath.get(path, this.document);
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
13
|
computed: {
|
|
51
14
|
virtuals() {
|
|
52
15
|
if (this.schemaPaths == null) {
|
|
53
16
|
return [];
|
|
54
17
|
}
|
|
18
|
+
if (this.document == null) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
55
21
|
const exists = this.schemaPaths.map(x => x.path);
|
|
56
22
|
const docKeys = Object.keys(this.document);
|
|
57
23
|
const result = [];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
.document-details {
|
|
2
|
+
width: 100%;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.document-details .value {
|
|
6
|
+
padding-top: 10px;
|
|
7
|
+
padding-bottom: 10px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.document-details .path-key {
|
|
11
|
+
background-color: #f0f0f0;
|
|
12
|
+
margin-bottom: 0.5em;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.document-details .path-type {
|
|
16
|
+
color: rgba(0,0,0,.36);
|
|
17
|
+
font-size: 0.8em;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.document-details .date-position {
|
|
21
|
+
float: right;
|
|
22
|
+
margin-top: -7px;
|
|
23
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<div>
|
|
2
|
+
<div class="relative path-key p-1 flex">
|
|
3
|
+
<div class="grow">
|
|
4
|
+
{{path.path}}
|
|
5
|
+
<span class="path-type">
|
|
6
|
+
({{(path.instance || 'unknown').toLowerCase()}})
|
|
7
|
+
</span>
|
|
8
|
+
</div>
|
|
9
|
+
<div v-if="editting && path.instance === 'Date'" class="flex gap-1.5">
|
|
10
|
+
<div
|
|
11
|
+
@click="dateType = 'picker'"
|
|
12
|
+
:class="dateType === 'picker' ? 'bg-teal-600' : ''"
|
|
13
|
+
class="self-stretch px-2 py-1 rounded-sm justify-center items-center gap-1.5 flex cursor-pointer">
|
|
14
|
+
<div
|
|
15
|
+
:class="dateType === 'picker' ? 'text-white' : ''"
|
|
16
|
+
class="text-xs font-medium font-['Lato'] capitalize leading-tight">
|
|
17
|
+
Date Picker
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
<div
|
|
21
|
+
@click="dateType = 'iso'"
|
|
22
|
+
:class="dateType === 'iso' ? 'bg-teal-600' : ''"
|
|
23
|
+
class="self-stretch px-2 py-1 rounded-sm justify-center items-center gap-1.5 flex cursor-pointer">
|
|
24
|
+
<div
|
|
25
|
+
:class="dateType === 'iso' ? 'text-white' : ''"
|
|
26
|
+
class="text-xs font-medium font-['Lato'] capitalize leading-tight">
|
|
27
|
+
ISO String
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
<div v-if="editting && path.path !== '_id'" class="pl-1">
|
|
33
|
+
<component
|
|
34
|
+
:is="getEditComponentForPath(path)"
|
|
35
|
+
:value="getEditValueForPath(path)"
|
|
36
|
+
:format="dateType"
|
|
37
|
+
@input="changes[path.path] = $event; delete invalid[path.path];"
|
|
38
|
+
@error="invalid[path.path] = $event;"
|
|
39
|
+
>
|
|
40
|
+
</component>
|
|
41
|
+
</div>
|
|
42
|
+
<div v-else class="pl-1">
|
|
43
|
+
<component :is="getComponentForPath(path)" :value="getValueForPath(path.path)"></component>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const mpath = require('mpath');
|
|
4
|
+
const template = require('./document-property.html')
|
|
5
|
+
|
|
6
|
+
const appendCSS = require('../../appendCSS');
|
|
7
|
+
|
|
8
|
+
appendCSS(require('./document-property.css'));
|
|
9
|
+
|
|
10
|
+
module.exports = app => app.component('document-property', {
|
|
11
|
+
template,
|
|
12
|
+
data: function() {
|
|
13
|
+
return {
|
|
14
|
+
dateType: 'picker' // picker, iso
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
props: ['path', 'document', 'schemaPaths', 'editting', 'changes', 'invalid'],
|
|
18
|
+
methods: {
|
|
19
|
+
getComponentForPath(schemaPath) {
|
|
20
|
+
if (schemaPath.instance === 'Array') {
|
|
21
|
+
return 'detail-array';
|
|
22
|
+
}
|
|
23
|
+
return 'detail-default';
|
|
24
|
+
},
|
|
25
|
+
getEditComponentForPath(path) {
|
|
26
|
+
if (path.instance == 'Date') {
|
|
27
|
+
return 'edit-date';
|
|
28
|
+
}
|
|
29
|
+
if (path.instance == 'Number') {
|
|
30
|
+
return 'edit-number';
|
|
31
|
+
}
|
|
32
|
+
if (path.instance === 'Array') {
|
|
33
|
+
return 'edit-array';
|
|
34
|
+
}
|
|
35
|
+
if (path.instance === 'Embedded') {
|
|
36
|
+
return 'edit-subdocument';
|
|
37
|
+
}
|
|
38
|
+
return 'edit-default';
|
|
39
|
+
},
|
|
40
|
+
getValueForPath(path) {
|
|
41
|
+
if (this.document == null) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
return mpath.get(path, this.document);
|
|
45
|
+
},
|
|
46
|
+
getEditValueForPath({ path }) {
|
|
47
|
+
if (!this.changes) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (!this.document) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
return path in this.changes ? this.changes[path] : mpath.get(path, this.document);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
})
|
package/frontend/src/index.js
CHANGED
|
@@ -26,6 +26,7 @@ require('./detail-default/detail-default')(app);
|
|
|
26
26
|
require('./document/document')(app);
|
|
27
27
|
require('./document/confirm-changes/confirm-changes')(app);
|
|
28
28
|
require('./document-details/document-details')(app);
|
|
29
|
+
require('./document-details/document-property/document-property')(app);
|
|
29
30
|
require('./edit-array/edit-array')(app);
|
|
30
31
|
require('./edit-default/edit-default')(app);
|
|
31
32
|
require('./edit-number/edit-number')(app);
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mongoosejs/studio",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.37",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"archetype": "0.13.0",
|
|
6
6
|
"csv-stringify": "6.3.0",
|
|
7
7
|
"ejson": "^2.2.3",
|
|
8
8
|
"extrovert": "0.0.24",
|
|
9
9
|
"node-inspect-extracted": "3.x",
|
|
10
|
-
"openai": "3.
|
|
10
|
+
"openai": "3.x",
|
|
11
11
|
"vanillatoasts": "^1.6.0"
|
|
12
12
|
},
|
|
13
13
|
"peerDependencies": {
|