@mongoosejs/studio 0.0.22 → 0.0.24
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 +405 -29759
- package/frontend/public/index.html +3 -0
- package/frontend/public/tw.css +119 -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/confirm-changes/confirm-changes.html +18 -0
- package/frontend/src/document/confirm-changes/confirm-changes.js +24 -0
- package/frontend/src/document/document.html +11 -5
- package/frontend/src/document/document.js +7 -1
- 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 +3 -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/package.json +1 -6
- 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
|
}
|
|
@@ -846,6 +922,11 @@ video {
|
|
|
846
922
|
font-weight: 600;
|
|
847
923
|
}
|
|
848
924
|
|
|
925
|
+
.text-black {
|
|
926
|
+
--tw-text-opacity: 1;
|
|
927
|
+
color: rgb(0 0 0 / var(--tw-text-opacity));
|
|
928
|
+
}
|
|
929
|
+
|
|
849
930
|
.text-gray-400 {
|
|
850
931
|
--tw-text-opacity: 1;
|
|
851
932
|
color: rgb(156 163 175 / var(--tw-text-opacity));
|
|
@@ -861,11 +942,31 @@ video {
|
|
|
861
942
|
color: rgb(55 65 81 / var(--tw-text-opacity));
|
|
862
943
|
}
|
|
863
944
|
|
|
945
|
+
.text-gray-800 {
|
|
946
|
+
--tw-text-opacity: 1;
|
|
947
|
+
color: rgb(31 41 55 / var(--tw-text-opacity));
|
|
948
|
+
}
|
|
949
|
+
|
|
864
950
|
.text-gray-900 {
|
|
865
951
|
--tw-text-opacity: 1;
|
|
866
952
|
color: rgb(17 24 39 / var(--tw-text-opacity));
|
|
867
953
|
}
|
|
868
954
|
|
|
955
|
+
.text-red-400 {
|
|
956
|
+
--tw-text-opacity: 1;
|
|
957
|
+
color: rgb(248 113 113 / var(--tw-text-opacity));
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
.text-red-700 {
|
|
961
|
+
--tw-text-opacity: 1;
|
|
962
|
+
color: rgb(185 28 28 / var(--tw-text-opacity));
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
.text-red-800 {
|
|
966
|
+
--tw-text-opacity: 1;
|
|
967
|
+
color: rgb(153 27 27 / var(--tw-text-opacity));
|
|
968
|
+
}
|
|
969
|
+
|
|
869
970
|
.text-sky-800 {
|
|
870
971
|
--tw-text-opacity: 1;
|
|
871
972
|
color: rgb(7 89 133 / var(--tw-text-opacity));
|
|
@@ -882,6 +983,10 @@ video {
|
|
|
882
983
|
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
|
883
984
|
}
|
|
884
985
|
|
|
986
|
+
.outline-0 {
|
|
987
|
+
outline-width: 0px;
|
|
988
|
+
}
|
|
989
|
+
|
|
885
990
|
.outline-gray-300 {
|
|
886
991
|
outline-color: #d1d5db;
|
|
887
992
|
}
|
|
@@ -918,6 +1023,16 @@ video {
|
|
|
918
1023
|
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
|
919
1024
|
}
|
|
920
1025
|
|
|
1026
|
+
.hover\:bg-gray-200:hover {
|
|
1027
|
+
--tw-bg-opacity: 1;
|
|
1028
|
+
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
.hover\:bg-gray-300:hover {
|
|
1032
|
+
--tw-bg-opacity: 1;
|
|
1033
|
+
background-color: rgb(209 213 219 / var(--tw-bg-opacity));
|
|
1034
|
+
}
|
|
1035
|
+
|
|
921
1036
|
.hover\:bg-gray-50:hover {
|
|
922
1037
|
--tw-bg-opacity: 1;
|
|
923
1038
|
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
|
|
@@ -969,6 +1084,10 @@ video {
|
|
|
969
1084
|
outline-offset: 2px;
|
|
970
1085
|
}
|
|
971
1086
|
|
|
1087
|
+
.focus-visible\:outline-gray-300:focus-visible {
|
|
1088
|
+
outline-color: #d1d5db;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
972
1091
|
.focus-visible\:outline-green-600:focus-visible {
|
|
973
1092
|
outline-color: #16a34a;
|
|
974
1093
|
}
|
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
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<div>
|
|
2
|
+
<h2>
|
|
3
|
+
Are you sure you want to save the following changes?
|
|
4
|
+
</h2>
|
|
5
|
+
<pre><code ref="code" class="language-javascript" v-text="displayValue"></code></pre>
|
|
6
|
+
<div class="flex gap-2 mt-2">
|
|
7
|
+
<async-button
|
|
8
|
+
class="rounded-md bg-green-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-green-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600"
|
|
9
|
+
@click="startSave">
|
|
10
|
+
Confirm
|
|
11
|
+
</async-button>
|
|
12
|
+
<button
|
|
13
|
+
class="rounded-md bg-gray-200 px-2.5 py-1.5 text-sm font-semibold text-black shadow-sm hover:bg-gray-300 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-300"
|
|
14
|
+
@click="closeConfirm">
|
|
15
|
+
Cancel
|
|
16
|
+
</button>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const template = require('./confirm-changes.html');
|
|
4
|
+
|
|
5
|
+
module.exports = app => app.component('confirm-changes', {
|
|
6
|
+
template: template,
|
|
7
|
+
props: ['value'],
|
|
8
|
+
computed: {
|
|
9
|
+
displayValue() {
|
|
10
|
+
return JSON.stringify(this.value, null, ' ').trim();
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
methods: {
|
|
14
|
+
closeConfirm() {
|
|
15
|
+
this.$emit('close')
|
|
16
|
+
},
|
|
17
|
+
startSave() {
|
|
18
|
+
this.$emit('save');
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
mounted() {
|
|
22
|
+
Prism.highlightElement(this.$refs.code);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
@@ -16,14 +16,14 @@
|
|
|
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
|
|
23
23
|
</button>
|
|
24
24
|
<button
|
|
25
25
|
v-if="editting"
|
|
26
|
-
@click="
|
|
26
|
+
@click="shouldShowConfirmModal=true;"
|
|
27
27
|
type="button"
|
|
28
28
|
class="rounded-md bg-green-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-green-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600">
|
|
29
29
|
<img src="images/save.svg" class="inline" /> Save
|
|
@@ -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>
|
|
@@ -71,5 +71,11 @@
|
|
|
71
71
|
{{path.value}}
|
|
72
72
|
</div>
|
|
73
73
|
</div>
|
|
74
|
+
<modal v-if="shouldShowConfirmModal">
|
|
75
|
+
<template v-slot:body>
|
|
76
|
+
<div class="modal-exit" @click="shouldShowConfirmModal = false;">×</div>
|
|
77
|
+
<confirm-changes @close="shouldShowConfirmModal = false;" @save="save" :value="changes"></confirm-changes>
|
|
78
|
+
</template>
|
|
79
|
+
</modal>
|
|
74
80
|
</div>
|
|
75
81
|
</div>
|
|
@@ -17,8 +17,10 @@ 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: [],
|
|
23
|
+
shouldShowConfirmModal: false
|
|
22
24
|
}),
|
|
23
25
|
async mounted() {
|
|
24
26
|
window.pageState = this;
|
|
@@ -76,6 +78,9 @@ module.exports = app => app.component('document', {
|
|
|
76
78
|
this.editting = false;
|
|
77
79
|
},
|
|
78
80
|
async save() {
|
|
81
|
+
if (Object.keys(this.invalid).length > 0) {
|
|
82
|
+
throw new Error('Invalid paths: ' + Object.keys(this.invalid).join(', '));
|
|
83
|
+
}
|
|
79
84
|
const { doc } = await api.Model.updateDocument({
|
|
80
85
|
model: this.model,
|
|
81
86
|
_id: this.document._id,
|
|
@@ -84,6 +89,7 @@ module.exports = app => app.component('document', {
|
|
|
84
89
|
this.document = doc;
|
|
85
90
|
this.changes = {};
|
|
86
91
|
this.editting = false;
|
|
92
|
+
this.shouldShowConfirmModal = false;
|
|
87
93
|
},
|
|
88
94
|
async remove() {
|
|
89
95
|
const { doc } = await api.Model.deleteDocument({
|
|
@@ -103,4 +109,4 @@ module.exports = app => app.component('document', {
|
|
|
103
109
|
}
|
|
104
110
|
}
|
|
105
111
|
}
|
|
106
|
-
});
|
|
112
|
+
});
|
|
@@ -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>
|