@mongoosejs/studio 0.0.35 → 0.0.36
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 -12
- package/frontend/src/dashboard-result/dashboard-document/dashboard-document.js +1 -1
- package/frontend/src/document-details/document-details.html +6 -45
- 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 +47 -0
- package/frontend/src/document-details/document-property/document-property.js +56 -0
- package/frontend/src/index.js +1 -0
- package/package.json +1 -1
|
@@ -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=\"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\">{{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>";
|
|
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));
|
|
@@ -1229,6 +1247,12 @@ video {
|
|
|
1229
1247
|
color: rgb(255 255 255 / var(--tw-text-opacity));
|
|
1230
1248
|
}
|
|
1231
1249
|
|
|
1250
|
+
.shadow-lg {
|
|
1251
|
+
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
1252
|
+
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
|
|
1253
|
+
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1232
1256
|
.shadow-sm {
|
|
1233
1257
|
--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
|
1234
1258
|
--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
|
|
@@ -1309,6 +1333,11 @@ video {
|
|
|
1309
1333
|
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
|
1310
1334
|
}
|
|
1311
1335
|
|
|
1336
|
+
.hover\:bg-blue-600:hover {
|
|
1337
|
+
--tw-bg-opacity: 1;
|
|
1338
|
+
background-color: rgb(37 99 235 / var(--tw-bg-opacity));
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1312
1341
|
.hover\:bg-gray-300:hover {
|
|
1313
1342
|
--tw-bg-opacity: 1;
|
|
1314
1343
|
background-color: rgb(209 213 219 / var(--tw-bg-opacity));
|
|
@@ -1319,6 +1348,11 @@ video {
|
|
|
1319
1348
|
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
|
|
1320
1349
|
}
|
|
1321
1350
|
|
|
1351
|
+
.hover\:bg-gray-600:hover {
|
|
1352
|
+
--tw-bg-opacity: 1;
|
|
1353
|
+
background-color: rgb(75 85 99 / var(--tw-bg-opacity));
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1322
1356
|
.hover\:bg-green-500:hover {
|
|
1323
1357
|
--tw-bg-opacity: 1;
|
|
1324
1358
|
background-color: rgb(34 197 94 / var(--tw-bg-opacity));
|
|
@@ -1329,6 +1363,11 @@ video {
|
|
|
1329
1363
|
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
|
1330
1364
|
}
|
|
1331
1365
|
|
|
1366
|
+
.hover\:bg-red-600:hover {
|
|
1367
|
+
--tw-bg-opacity: 1;
|
|
1368
|
+
background-color: rgb(220 38 38 / var(--tw-bg-opacity));
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1332
1371
|
.hover\:bg-slate-500:hover {
|
|
1333
1372
|
--tw-bg-opacity: 1;
|
|
1334
1373
|
background-color: rgb(100 116 139 / var(--tw-bg-opacity));
|
|
@@ -1358,12 +1397,43 @@ video {
|
|
|
1358
1397
|
z-index: 10;
|
|
1359
1398
|
}
|
|
1360
1399
|
|
|
1400
|
+
.focus\:outline-none:focus {
|
|
1401
|
+
outline: 2px solid transparent;
|
|
1402
|
+
outline-offset: 2px;
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1361
1405
|
.focus\:ring-0:focus {
|
|
1362
1406
|
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
1363
1407
|
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
1364
1408
|
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
1365
1409
|
}
|
|
1366
1410
|
|
|
1411
|
+
.focus\:ring-2:focus {
|
|
1412
|
+
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
1413
|
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
1414
|
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
.focus\:ring-blue-500:focus {
|
|
1418
|
+
--tw-ring-opacity: 1;
|
|
1419
|
+
--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity));
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
.focus\:ring-gray-500:focus {
|
|
1423
|
+
--tw-ring-opacity: 1;
|
|
1424
|
+
--tw-ring-color: rgb(107 114 128 / var(--tw-ring-opacity));
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
.focus\:ring-gray-600:focus {
|
|
1428
|
+
--tw-ring-opacity: 1;
|
|
1429
|
+
--tw-ring-color: rgb(75 85 99 / var(--tw-ring-opacity));
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
.focus\:ring-red-500:focus {
|
|
1433
|
+
--tw-ring-opacity: 1;
|
|
1434
|
+
--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity));
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1367
1437
|
.focus-visible\:outline:focus-visible {
|
|
1368
1438
|
outline-style: solid;
|
|
1369
1439
|
}
|
|
@@ -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,49 +1,10 @@
|
|
|
1
1
|
<div class="document-details">
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
</span>
|
|
9
|
-
</div>
|
|
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>
|
|
46
|
-
</div>
|
|
2
|
+
<document-property
|
|
3
|
+
:document="document"
|
|
4
|
+
:schemaPaths="schemaPaths"
|
|
5
|
+
:editting="editting"
|
|
6
|
+
:changes="changes"
|
|
7
|
+
:invalid="invalid"></document-property>
|
|
47
8
|
<div v-for="path in virtuals" class="mb-2">
|
|
48
9
|
<div class="p-1 mb-1 bg-slate-100">
|
|
49
10
|
{{path.name}}
|
|
@@ -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,47 @@
|
|
|
1
|
+
<div>
|
|
2
|
+
<div v-for="path in schemaPaths" class="value">
|
|
3
|
+
<div class="relative path-key p-1 flex">
|
|
4
|
+
<div class="grow">
|
|
5
|
+
{{path.path}}
|
|
6
|
+
<span class="path-type">
|
|
7
|
+
({{(path.instance || 'unknown').toLowerCase()}})
|
|
8
|
+
</span>
|
|
9
|
+
</div>
|
|
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>
|
|
46
|
+
</div>
|
|
47
|
+
</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: ['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);
|