@mongoosejs/studio 0.0.22 → 0.0.23
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/Dashboard/getDashboard.js +18 -0
- package/backend/actions/Dashboard/index.js +3 -1
- package/backend/actions/Dashboard/updateDashboard.js +25 -0
- package/backend/index.js +6 -2
- package/frontend/public/app.js +357 -29758
- package/frontend/public/index.html +3 -0
- package/frontend/public/tw.css +105 -0
- package/frontend/src/api.js +12 -0
- package/frontend/src/create-document/create-document.html +20 -1
- package/frontend/src/create-document/create-document.js +13 -27
- package/frontend/src/dashboard/dashboard.html +13 -4
- package/frontend/src/dashboard/dashboard.js +25 -11
- package/frontend/src/dashboard/edit-dashboard/edit-dashboard.html +5 -0
- package/frontend/src/dashboard/edit-dashboard/edit-dashboard.js +48 -0
- package/frontend/src/dashboards/dashboards.html +5 -0
- package/frontend/src/dashboards/dashboards.js +20 -0
- package/frontend/src/document/document.html +4 -4
- package/frontend/src/document/document.js +4 -0
- package/frontend/src/edit-array/edit-array.html +1 -7
- package/frontend/src/edit-array/edit-array.js +27 -9
- package/frontend/src/edit-default/edit-default.html +1 -1
- package/frontend/src/index.js +2 -1
- package/frontend/src/models/models.css +0 -2
- package/frontend/src/models/models.js +0 -4
- package/frontend/src/routes.js +5 -0
- package/mongoosejs-studio-0.0.16.tgz +0 -0
- package/package.json +1 -6
- package/frontend/dist/app.js +0 -160
- package/frontend/dist/tw.css +0 -595
- package/frontend/src/dashboard-details/dashboard-details.html +0 -8
- package/frontend/src/dashboard-details/dashboard-details.js +0 -10
- package/logs/COUNT_20230524-154120-151469/operation.log +0 -8
- package/logs/COUNT_20230524-154408-077670/operation.log +0 -22
- package/logs/COUNT_20230524-154414-431706/operation.log +0 -8
- package/logs/COUNT_20230524-155000-297076/operation.log +0 -8
- package/logs/LOAD_20230524-155832-351763/checkpoint.csv +0 -1
- package/logs/LOAD_20230524-155832-351763/operation.log +0 -23
|
@@ -10,9 +10,12 @@
|
|
|
10
10
|
<link rel="stylesheet" href="https://unpkg.com/prismjs@1.29.0/themes/prism.css"/>
|
|
11
11
|
<link rel="stylesheet" href="tw.css">
|
|
12
12
|
<link rel="stylesheet" href="vanillatoasts/vanillatoasts.css">
|
|
13
|
+
<link rel="stylesheet" href="https://unpkg.com/codemirror@5.65.16/lib/codemirror.css">
|
|
13
14
|
<script src="https://unpkg.com/vue@3.x"></script>
|
|
14
15
|
<script src="https://unpkg.com/vue-router@4.0.10"></script>
|
|
15
16
|
<script src="https://unpkg.com/chart.js@4.2.0/dist/chart.umd.js"></script>
|
|
17
|
+
<script src="https://unpkg.com/codemirror@5.65.16/lib/codemirror.js"></script>
|
|
18
|
+
<script src="https://unpkg.com/codemirror@5.65.16/mode/javascript/javascript.js"></script>
|
|
16
19
|
</head>
|
|
17
20
|
|
|
18
21
|
<body>
|
package/frontend/public/tw.css
CHANGED
|
@@ -578,6 +578,10 @@ video {
|
|
|
578
578
|
}
|
|
579
579
|
}
|
|
580
580
|
|
|
581
|
+
.fixed {
|
|
582
|
+
position: fixed;
|
|
583
|
+
}
|
|
584
|
+
|
|
581
585
|
.relative {
|
|
582
586
|
position: relative;
|
|
583
587
|
}
|
|
@@ -602,6 +606,22 @@ video {
|
|
|
602
606
|
margin-bottom: 0.5rem;
|
|
603
607
|
}
|
|
604
608
|
|
|
609
|
+
.mb-\[-1px\] {
|
|
610
|
+
margin-bottom: -1px;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
.ml-3 {
|
|
614
|
+
margin-left: 0.75rem;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
.mt-1 {
|
|
618
|
+
margin-top: 0.25rem;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
.mt-2 {
|
|
622
|
+
margin-top: 0.5rem;
|
|
623
|
+
}
|
|
624
|
+
|
|
605
625
|
.mt-4 {
|
|
606
626
|
margin-top: 1rem;
|
|
607
627
|
}
|
|
@@ -630,6 +650,14 @@ video {
|
|
|
630
650
|
height: 1.25rem;
|
|
631
651
|
}
|
|
632
652
|
|
|
653
|
+
.h-8 {
|
|
654
|
+
height: 2rem;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
.h-\[300px\] {
|
|
658
|
+
height: 300px;
|
|
659
|
+
}
|
|
660
|
+
|
|
633
661
|
.h-\[calc\(100vh-55px\)\] {
|
|
634
662
|
height: calc(100vh - 55px);
|
|
635
663
|
}
|
|
@@ -642,6 +670,10 @@ video {
|
|
|
642
670
|
width: 1.25rem;
|
|
643
671
|
}
|
|
644
672
|
|
|
673
|
+
.w-64 {
|
|
674
|
+
width: 16rem;
|
|
675
|
+
}
|
|
676
|
+
|
|
645
677
|
.w-full {
|
|
646
678
|
width: 100%;
|
|
647
679
|
}
|
|
@@ -650,6 +682,10 @@ video {
|
|
|
650
682
|
flex: 1 1 0%;
|
|
651
683
|
}
|
|
652
684
|
|
|
685
|
+
.flex-shrink-0 {
|
|
686
|
+
flex-shrink: 0;
|
|
687
|
+
}
|
|
688
|
+
|
|
653
689
|
.flex-grow {
|
|
654
690
|
flex-grow: 1;
|
|
655
691
|
}
|
|
@@ -658,6 +694,10 @@ video {
|
|
|
658
694
|
flex-grow: 1;
|
|
659
695
|
}
|
|
660
696
|
|
|
697
|
+
.list-disc {
|
|
698
|
+
list-style-type: disc;
|
|
699
|
+
}
|
|
700
|
+
|
|
661
701
|
.flex-row {
|
|
662
702
|
flex-direction: row;
|
|
663
703
|
}
|
|
@@ -670,6 +710,10 @@ video {
|
|
|
670
710
|
align-items: center;
|
|
671
711
|
}
|
|
672
712
|
|
|
713
|
+
.justify-end {
|
|
714
|
+
justify-content: flex-end;
|
|
715
|
+
}
|
|
716
|
+
|
|
673
717
|
.gap-2 {
|
|
674
718
|
gap: 0.5rem;
|
|
675
719
|
}
|
|
@@ -682,6 +726,12 @@ video {
|
|
|
682
726
|
row-gap: 1.75rem;
|
|
683
727
|
}
|
|
684
728
|
|
|
729
|
+
.space-y-1 > :not([hidden]) ~ :not([hidden]) {
|
|
730
|
+
--tw-space-y-reverse: 0;
|
|
731
|
+
margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));
|
|
732
|
+
margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
|
|
733
|
+
}
|
|
734
|
+
|
|
685
735
|
.overflow-y-auto {
|
|
686
736
|
overflow-y: auto;
|
|
687
737
|
}
|
|
@@ -708,6 +758,14 @@ video {
|
|
|
708
758
|
border-bottom-right-radius: 0.375rem;
|
|
709
759
|
}
|
|
710
760
|
|
|
761
|
+
.rounded-tl-md {
|
|
762
|
+
border-top-left-radius: 0.375rem;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
.rounded-tr-md {
|
|
766
|
+
border-top-right-radius: 0.375rem;
|
|
767
|
+
}
|
|
768
|
+
|
|
711
769
|
.border {
|
|
712
770
|
border-width: 1px;
|
|
713
771
|
}
|
|
@@ -725,6 +783,11 @@ video {
|
|
|
725
783
|
border-color: rgb(229 231 235 / var(--tw-border-opacity));
|
|
726
784
|
}
|
|
727
785
|
|
|
786
|
+
.border-gray-300 {
|
|
787
|
+
--tw-border-opacity: 1;
|
|
788
|
+
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
|
789
|
+
}
|
|
790
|
+
|
|
728
791
|
.border-teal-500 {
|
|
729
792
|
--tw-border-opacity: 1;
|
|
730
793
|
border-color: rgb(0 208 201 / var(--tw-border-opacity));
|
|
@@ -744,6 +807,11 @@ video {
|
|
|
744
807
|
background-color: rgb(22 163 74 / var(--tw-bg-opacity));
|
|
745
808
|
}
|
|
746
809
|
|
|
810
|
+
.bg-red-50 {
|
|
811
|
+
--tw-bg-opacity: 1;
|
|
812
|
+
background-color: rgb(254 242 242 / var(--tw-bg-opacity));
|
|
813
|
+
}
|
|
814
|
+
|
|
747
815
|
.bg-red-600 {
|
|
748
816
|
--tw-bg-opacity: 1;
|
|
749
817
|
background-color: rgb(220 38 38 / var(--tw-bg-opacity));
|
|
@@ -782,6 +850,10 @@ video {
|
|
|
782
850
|
padding: 0.5rem;
|
|
783
851
|
}
|
|
784
852
|
|
|
853
|
+
.p-4 {
|
|
854
|
+
padding: 1rem;
|
|
855
|
+
}
|
|
856
|
+
|
|
785
857
|
.px-1 {
|
|
786
858
|
padding-left: 0.25rem;
|
|
787
859
|
padding-right: 0.25rem;
|
|
@@ -816,6 +888,10 @@ video {
|
|
|
816
888
|
padding-left: 0.5rem;
|
|
817
889
|
}
|
|
818
890
|
|
|
891
|
+
.pl-5 {
|
|
892
|
+
padding-left: 1.25rem;
|
|
893
|
+
}
|
|
894
|
+
|
|
819
895
|
.pr-2 {
|
|
820
896
|
padding-right: 0.5rem;
|
|
821
897
|
}
|
|
@@ -861,11 +937,31 @@ video {
|
|
|
861
937
|
color: rgb(55 65 81 / var(--tw-text-opacity));
|
|
862
938
|
}
|
|
863
939
|
|
|
940
|
+
.text-gray-800 {
|
|
941
|
+
--tw-text-opacity: 1;
|
|
942
|
+
color: rgb(31 41 55 / var(--tw-text-opacity));
|
|
943
|
+
}
|
|
944
|
+
|
|
864
945
|
.text-gray-900 {
|
|
865
946
|
--tw-text-opacity: 1;
|
|
866
947
|
color: rgb(17 24 39 / var(--tw-text-opacity));
|
|
867
948
|
}
|
|
868
949
|
|
|
950
|
+
.text-red-400 {
|
|
951
|
+
--tw-text-opacity: 1;
|
|
952
|
+
color: rgb(248 113 113 / var(--tw-text-opacity));
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
.text-red-700 {
|
|
956
|
+
--tw-text-opacity: 1;
|
|
957
|
+
color: rgb(185 28 28 / var(--tw-text-opacity));
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
.text-red-800 {
|
|
961
|
+
--tw-text-opacity: 1;
|
|
962
|
+
color: rgb(153 27 27 / var(--tw-text-opacity));
|
|
963
|
+
}
|
|
964
|
+
|
|
869
965
|
.text-sky-800 {
|
|
870
966
|
--tw-text-opacity: 1;
|
|
871
967
|
color: rgb(7 89 133 / var(--tw-text-opacity));
|
|
@@ -882,6 +978,10 @@ video {
|
|
|
882
978
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
|
883
979
|
}
|
|
884
980
|
|
|
981
|
+
.outline-0 {
|
|
982
|
+
outline-width: 0px;
|
|
983
|
+
}
|
|
984
|
+
|
|
885
985
|
.outline-gray-300 {
|
|
886
986
|
outline-color: #d1d5db;
|
|
887
987
|
}
|
|
@@ -918,6 +1018,11 @@ video {
|
|
|
918
1018
|
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
|
919
1019
|
}
|
|
920
1020
|
|
|
1021
|
+
.hover\:bg-gray-200:hover {
|
|
1022
|
+
--tw-bg-opacity: 1;
|
|
1023
|
+
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
|
|
1024
|
+
}
|
|
1025
|
+
|
|
921
1026
|
.hover\:bg-gray-50:hover {
|
|
922
1027
|
--tw-bg-opacity: 1;
|
|
923
1028
|
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
|
package/frontend/src/api.js
CHANGED
|
@@ -20,8 +20,14 @@ if (typeof config__setAuthorizationHeaderFrom === 'string' && config__setAuthori
|
|
|
20
20
|
|
|
21
21
|
if (config__isLambda) {
|
|
22
22
|
exports.Dashboard = {
|
|
23
|
+
getDashboard(params) {
|
|
24
|
+
return client.post('', { action: 'Dashboard.getDashboard', ...params }).then(res => res.data);
|
|
25
|
+
},
|
|
23
26
|
getDashboards(params) {
|
|
24
27
|
return client.post('', { action: 'Dashboard.getDashboards', ...params }).then(res => res.data);
|
|
28
|
+
},
|
|
29
|
+
updateDashboard(params) {
|
|
30
|
+
return client.post('', { action: 'Dashboard.updateDashboard', ...params}).then(res => res.data);
|
|
25
31
|
}
|
|
26
32
|
}
|
|
27
33
|
exports.Model = {
|
|
@@ -52,9 +58,15 @@ if (config__isLambda) {
|
|
|
52
58
|
};
|
|
53
59
|
} else {
|
|
54
60
|
exports.Dashboard = {
|
|
61
|
+
getDashboard: function getDashboard(params) {
|
|
62
|
+
return client.get('/Dashboard/getDashboard', params).then(res => res.data);
|
|
63
|
+
},
|
|
55
64
|
getDashboards: function getDashboards(params) {
|
|
56
65
|
return client.get('/Dashboard/getDashboards', params).then(res => res.data);
|
|
57
66
|
},
|
|
67
|
+
updateDashboard: function updateDashboard(params) {
|
|
68
|
+
return client.post('/Dashboard/updateDashboard', params).then(res => res.data);
|
|
69
|
+
}
|
|
58
70
|
}
|
|
59
71
|
exports.Model = {
|
|
60
72
|
createChart: function (params) {
|
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
<div>
|
|
2
2
|
<div class="mb-2">
|
|
3
|
-
<textarea class="border border-gray-200 p-2" ref="codeEditor"
|
|
3
|
+
<textarea class="border border-gray-200 p-2 h-[300px] w-full" ref="codeEditor"></textarea>
|
|
4
4
|
</div>
|
|
5
5
|
<button @click="createDocument()" 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">Submit</button>
|
|
6
|
+
<div v-if="errors.length > 0" class="rounded-md bg-red-50 p-4 mt-1">
|
|
7
|
+
<div class="flex">
|
|
8
|
+
<div class="flex-shrink-0">
|
|
9
|
+
<svg class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
|
10
|
+
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z" clip-rule="evenodd" />
|
|
11
|
+
</svg>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="ml-3">
|
|
14
|
+
<h3 class="text-sm font-medium text-red-800">There were {{errors.length}} errors with your submission</h3>
|
|
15
|
+
<div class="mt-2 text-sm text-red-700">
|
|
16
|
+
<ul role="list" class="list-disc space-y-1 pl-5">
|
|
17
|
+
<li v-for="error in errors">
|
|
18
|
+
{{error}}
|
|
19
|
+
</li>
|
|
20
|
+
</ul>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
6
25
|
</div>
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const api = require('../api');
|
|
4
|
-
const { EditorState } = require('@codemirror/state');
|
|
5
|
-
const { lineNumbers } = require('@codemirror/view')
|
|
6
|
-
const { EditorView, basicSetup } = require('codemirror');
|
|
7
|
-
const { javascript } = require('@codemirror/lang-javascript');
|
|
8
4
|
|
|
9
5
|
const { BSON, EJSON } = require('bson');
|
|
10
6
|
|
|
@@ -26,23 +22,29 @@ module.exports = app => app.component('create-document', {
|
|
|
26
22
|
data: function() {
|
|
27
23
|
return {
|
|
28
24
|
documentData: '',
|
|
29
|
-
editor: null
|
|
25
|
+
editor: null,
|
|
26
|
+
errors: []
|
|
30
27
|
}
|
|
31
28
|
},
|
|
32
29
|
methods: {
|
|
33
30
|
async createDocument() {
|
|
34
|
-
const data = EJSON.serialize(eval(`(${this.
|
|
31
|
+
const data = EJSON.serialize(eval(`(${this.editor.getValue()})`));
|
|
35
32
|
const { doc } = await api.Model.createDocument({ model: this.currentModel, data }).catch(err => {
|
|
36
33
|
if (err.response?.data?.message) {
|
|
34
|
+
console.log(err.response.data);
|
|
35
|
+
const message = err.response.data.message.split(": ").slice(1).join(": ");
|
|
36
|
+
this.errors = message.split(',').map(error => {
|
|
37
|
+
return error.split(': ').slice(1).join(': ').trim();
|
|
38
|
+
})
|
|
37
39
|
throw new Error(err.response?.data?.message);
|
|
38
40
|
}
|
|
39
41
|
throw err;
|
|
40
42
|
});
|
|
43
|
+
this.errors.length = 0;
|
|
41
44
|
this.$emit('close', doc);
|
|
42
45
|
},
|
|
43
46
|
},
|
|
44
47
|
mounted: function() {
|
|
45
|
-
console.log(this.currentModel, this.paths);
|
|
46
48
|
const requiredPaths = this.paths.filter(x => x.required);
|
|
47
49
|
this.documentData = `{\n`;
|
|
48
50
|
for (let i = 0; i < requiredPaths.length; i++) {
|
|
@@ -50,26 +52,10 @@ module.exports = app => app.component('create-document', {
|
|
|
50
52
|
this.documentData += ` ${requiredPaths[i].path}: ${isLast ? '': ','}\n`
|
|
51
53
|
}
|
|
52
54
|
this.documentData += '}';
|
|
53
|
-
|
|
54
|
-
this.editor =
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
extensions: [
|
|
58
|
-
basicSetup,
|
|
59
|
-
javascript(),
|
|
60
|
-
// history(),
|
|
61
|
-
EditorView.updateListener.of((v) => {
|
|
62
|
-
// Your update logic here
|
|
63
|
-
}),
|
|
64
|
-
// keymap.of(historyKeymap)
|
|
65
|
-
]
|
|
66
|
-
}),
|
|
67
|
-
parent: this.$refs.codeEditor
|
|
55
|
+
this.$refs.codeEditor.value = this.documentData;
|
|
56
|
+
this.editor = CodeMirror.fromTextArea(this.$refs.codeEditor, {
|
|
57
|
+
mode: 'javascript',
|
|
58
|
+
lineNumbers: true
|
|
68
59
|
});
|
|
69
60
|
},
|
|
70
|
-
beforeDestroy() {
|
|
71
|
-
if (this.editor) {
|
|
72
|
-
this.editor.toTextArea();
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
61
|
})
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
<div class="dashboard">
|
|
2
|
-
<div v-if="
|
|
3
|
-
<div
|
|
4
|
-
{{
|
|
2
|
+
<div v-if="dashboard">
|
|
3
|
+
<div>
|
|
4
|
+
<h2>{{name}}</h2>
|
|
5
5
|
</div>
|
|
6
|
+
<div>
|
|
7
|
+
<pre>{{code}}</pre>
|
|
8
|
+
<button v-if="!showEditor" @click="toggleEditor" style="color: black;margin-right: 0.5em">Edit</button>
|
|
9
|
+
</div>
|
|
10
|
+
<div v-if="showEditor">
|
|
11
|
+
<edit-dashboard :dashboardId="dashboard._id" :code="code" @close="showEditor=false;" @update="updateCode"></edit-dashboard>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
<div v-if="!dashboard && status === 'loaded'">
|
|
15
|
+
No dashboard with the given id could be found.
|
|
6
16
|
</div>
|
|
7
|
-
<dashboard-details v-if="dashboard" :dashboard="dashboard"></dashboard-details>
|
|
8
17
|
</div>
|
|
@@ -3,20 +3,34 @@
|
|
|
3
3
|
const api = require('../api');
|
|
4
4
|
const template = require('./dashboard.html');
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
module.exports = app => app.component('dashboard', {
|
|
8
7
|
template: template,
|
|
9
|
-
data: ()
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
data: function() {
|
|
9
|
+
return {
|
|
10
|
+
status: 'loading',
|
|
11
|
+
code: '',
|
|
12
|
+
name: '',
|
|
13
|
+
showEditor: false,
|
|
14
|
+
dashboard: null
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
methods: {
|
|
18
|
+
toggleEditor() {
|
|
19
|
+
this.showEditor = !this.showEditor;
|
|
20
|
+
},
|
|
21
|
+
async updateCode(update) {
|
|
22
|
+
this.code = update;
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
mounted: async function() {
|
|
26
|
+
const dashboardId = this.$route.query.dashboardId;
|
|
27
|
+
const { dashboard } = await api.Dashboard.getDashboard({ params: { dashboardId: dashboardId } });
|
|
28
|
+
if (!dashboard) {
|
|
17
29
|
return;
|
|
18
30
|
}
|
|
19
|
-
this.dashboard =
|
|
31
|
+
this.dashboard = dashboard;
|
|
32
|
+
this.name = this.dashboard.name;
|
|
33
|
+
this.code = this.dashboard.code;
|
|
20
34
|
this.status = 'loaded';
|
|
21
|
-
}
|
|
35
|
+
}
|
|
22
36
|
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const api = require('../../api');
|
|
4
|
+
const template = require('./edit-dashboard.html');
|
|
5
|
+
|
|
6
|
+
module.exports = app => app.component('edit-dashboard', {
|
|
7
|
+
template: template,
|
|
8
|
+
props: ['dashboardId', 'code'],
|
|
9
|
+
data: function() {
|
|
10
|
+
return {
|
|
11
|
+
status: 'loading',
|
|
12
|
+
editor: null,
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
methods: {
|
|
16
|
+
closeEditor() {
|
|
17
|
+
this.$emit('close')
|
|
18
|
+
},
|
|
19
|
+
async updateCode() {
|
|
20
|
+
const { doc } = await api.Dashboard.updateDashboard({ dashboardId: this.dashboardId, code: this.editor.getValue() });
|
|
21
|
+
this.$emit('update', doc.code);
|
|
22
|
+
this.editor.setValue(doc.code);
|
|
23
|
+
this.closeEditor();
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
mounted: async function() {
|
|
27
|
+
this.editor = CodeMirror.fromTextArea(this.$refs.codeEditor, {
|
|
28
|
+
mode: 'javascript',
|
|
29
|
+
lineNumbers: true,
|
|
30
|
+
indentUnit: 4,
|
|
31
|
+
smartIndent: true,
|
|
32
|
+
tabsize: 4,
|
|
33
|
+
indentWithTabs: true,
|
|
34
|
+
cursorBlinkRate: 300,
|
|
35
|
+
lineWrapping: true,
|
|
36
|
+
showCursorWhenSelecting: true,
|
|
37
|
+
});
|
|
38
|
+
// this.editor.setValue(this.code);
|
|
39
|
+
// this.editor.setSize(300, 300); // Ensure the editor has a fixed height
|
|
40
|
+
|
|
41
|
+
// this.editor.setCursor(this.editor.lineCount() - 1, this.editor.getLine(this.editor.lineCount() - 1).length);
|
|
42
|
+
|
|
43
|
+
this.editor.focus();
|
|
44
|
+
// this.editor.refresh(); // if anything weird happens on load, this usually fixes it. However, this breaks it in this case.
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const api = require('../api');
|
|
4
|
+
const template = require('./dashboards.html');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module.exports = app => app.component('dashboards', {
|
|
8
|
+
template: template,
|
|
9
|
+
data: () => ({
|
|
10
|
+
dashboards: [],
|
|
11
|
+
}),
|
|
12
|
+
async mounted() {
|
|
13
|
+
const { dashboards } = await api.Dashboard.getDashboards();
|
|
14
|
+
this.dashboards = dashboards;
|
|
15
|
+
if (!this.$route.query.dashboardId) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
this.status = 'loaded';
|
|
19
|
+
},
|
|
20
|
+
});
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
</button>
|
|
17
17
|
<button
|
|
18
18
|
v-if="editting"
|
|
19
|
-
@click="
|
|
19
|
+
@click="editting = false"
|
|
20
20
|
type="button"
|
|
21
21
|
class="rounded-md bg-slate-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-slate-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-slate-600">
|
|
22
22
|
× Cancel
|
|
@@ -42,14 +42,14 @@
|
|
|
42
42
|
{{path.path}}
|
|
43
43
|
<span class="path-type">
|
|
44
44
|
({{(path.instance || 'unknown').toLowerCase()}})
|
|
45
|
-
</span>
|
|
46
|
-
|
|
45
|
+
</span>
|
|
47
46
|
</div>
|
|
48
47
|
<div v-if="editting && path.path !== '_id'">
|
|
49
48
|
<component
|
|
50
49
|
:is="getEditComponentForPath(path)"
|
|
51
50
|
:value="getEditValueForPath(path)"
|
|
52
|
-
@input="changes[path.path] = $event;"
|
|
51
|
+
@input="changes[path.path] = $event; delete invalid[path.path];"
|
|
52
|
+
@error="invalid[path.path] = $event;"
|
|
53
53
|
>
|
|
54
54
|
</component>
|
|
55
55
|
</div>
|
|
@@ -17,6 +17,7 @@ module.exports = app => app.component('document', {
|
|
|
17
17
|
status: 'init',
|
|
18
18
|
document: null,
|
|
19
19
|
changes: {},
|
|
20
|
+
invalid: {},
|
|
20
21
|
editting: false,
|
|
21
22
|
virtuals: [],
|
|
22
23
|
}),
|
|
@@ -76,6 +77,9 @@ module.exports = app => app.component('document', {
|
|
|
76
77
|
this.editting = false;
|
|
77
78
|
},
|
|
78
79
|
async save() {
|
|
80
|
+
if (Object.keys(this.invalid).length > 0) {
|
|
81
|
+
throw new Error('Invalid paths: ' + Object.keys(this.invalid).join(', '));
|
|
82
|
+
}
|
|
79
83
|
const { doc } = await api.Model.updateDocument({
|
|
80
84
|
model: this.model,
|
|
81
85
|
_id: this.document._id,
|
|
@@ -1,9 +1,3 @@
|
|
|
1
1
|
<div class="edit-array">
|
|
2
|
-
<
|
|
3
|
-
<input type="text" :value="el" @input="currentValue[i] = $event.target.value; onUpdate()">
|
|
4
|
-
<span style="cursor: pointer; color: #880000; font-weight: bold;" @click="removeValue(i)">×</span>
|
|
5
|
-
</div>
|
|
6
|
-
<div>
|
|
7
|
-
<button @click="currentValue.push(''); onUpdate();">Add</button>
|
|
8
|
-
</div>
|
|
2
|
+
<textarea ref="arrayEditor" v-model="currentValue" class="w-full border border-gray-300 p-1 h-[300px]"></textarea>
|
|
9
3
|
</div>
|
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
const template = require('./edit-array.html');
|
|
4
4
|
|
|
5
|
+
const { BSON, EJSON } = require('bson');
|
|
6
|
+
|
|
7
|
+
const ObjectId = new Proxy(BSON.ObjectId, {
|
|
8
|
+
apply (target, thisArg, argumentsList) {
|
|
9
|
+
return new target(...argumentsList);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
|
|
5
13
|
const appendCSS = require('../appendCSS');
|
|
6
14
|
appendCSS(require('./edit-array.css'));
|
|
7
15
|
|
|
@@ -10,16 +18,26 @@ module.exports = app => app.component('edit-array', {
|
|
|
10
18
|
props: ['value'],
|
|
11
19
|
data: () => ({ currentValue: null }),
|
|
12
20
|
mounted() {
|
|
13
|
-
this.currentValue = this.value;
|
|
21
|
+
this.currentValue = JSON.stringify(this.value, null, ' ').trim();
|
|
22
|
+
this.$refs.arrayEditor.value = this.currentValue;
|
|
23
|
+
this.editor = CodeMirror.fromTextArea(this.$refs.arrayEditor, {
|
|
24
|
+
mode: 'javascript',
|
|
25
|
+
lineNumbers: true
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
watch: {
|
|
29
|
+
currentValue() {
|
|
30
|
+
try {
|
|
31
|
+
this.$emit('input', eval(this.currentValue));
|
|
32
|
+
} catch (err) {
|
|
33
|
+
this.$emit('error', err);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
14
36
|
},
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
this
|
|
18
|
-
},
|
|
19
|
-
removeValue(i) {
|
|
20
|
-
this.currentValue.splice(i, 1);
|
|
21
|
-
this.$emit('input', this.currentValue);
|
|
37
|
+
beforeDestroy() {
|
|
38
|
+
if (this.editor) {
|
|
39
|
+
this.editor.toTextArea();
|
|
22
40
|
}
|
|
23
41
|
},
|
|
24
|
-
emits: ['input']
|
|
42
|
+
emits: ['input', 'error']
|
|
25
43
|
});
|
package/frontend/src/index.js
CHANGED
|
@@ -9,8 +9,9 @@ const app = Vue.createApp({
|
|
|
9
9
|
require('./async-button/async-button')(app);
|
|
10
10
|
require('./charts/charts')(app);
|
|
11
11
|
require('./create-document/create-document')(app);
|
|
12
|
+
require('./dashboards/dashboards')(app);
|
|
12
13
|
require('./dashboard/dashboard')(app);
|
|
13
|
-
require('./dashboard-
|
|
14
|
+
require('./dashboard/edit-dashboard/edit-dashboard')(app)
|
|
14
15
|
require('./detail-array/detail-array')(app);
|
|
15
16
|
require('./detail-default/detail-default')(app);
|
|
16
17
|
require('./document/document')(app);
|
|
@@ -5,10 +5,6 @@ const template = require('./models.html');
|
|
|
5
5
|
const mpath = require('mpath');
|
|
6
6
|
const { BSON, EJSON } = require('bson');
|
|
7
7
|
|
|
8
|
-
const { EditorState } = require('@codemirror/state');
|
|
9
|
-
const { lineNumbers } = require('@codemirror/view')
|
|
10
|
-
const { EditorView, basicSetup } = require('codemirror');
|
|
11
|
-
const { javascript } = require('@codemirror/lang-javascript');
|
|
12
8
|
|
|
13
9
|
|
|
14
10
|
const ObjectId = new Proxy(BSON.ObjectId, {
|
package/frontend/src/routes.js
CHANGED
|
Binary file
|