@mongoosejs/studio 0.0.33 → 0.0.35
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/deleteDashboard.js +19 -0
- package/backend/actions/Dashboard/index.js +1 -0
- package/backend/actions/Dashboard/updateDashboard.js +18 -2
- package/frontend/public/app.js +26 -10
- package/frontend/public/tw.css +52 -20
- package/frontend/src/api.js +13 -0
- package/frontend/src/dashboard/dashboard.html +3 -1
- package/frontend/src/dashboard/dashboard.js +6 -0
- package/frontend/src/dashboard/edit-dashboard/edit-dashboard.html +14 -4
- package/frontend/src/dashboard/edit-dashboard/edit-dashboard.js +9 -4
- package/frontend/src/dashboards/dashboards.html +19 -1
- package/frontend/src/dashboards/dashboards.js +17 -1
- package/frontend/src/document-details/document-details.css +5 -0
- package/frontend/src/document-details/document-details.html +30 -5
- package/frontend/src/document-details/document-details.js +6 -1
- package/frontend/src/edit-date/edit-date.html +2 -18
- package/frontend/src/edit-date/edit-date.js +7 -6
- package/package.json +1 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Archetype = require('archetype');
|
|
4
|
+
const vm = require('vm');
|
|
5
|
+
|
|
6
|
+
const DeleteDashboardParams = new Archetype({
|
|
7
|
+
dashboardId: {
|
|
8
|
+
$type: 'string',
|
|
9
|
+
$required: true
|
|
10
|
+
},
|
|
11
|
+
}).compile('DeleteDashboardParams');
|
|
12
|
+
|
|
13
|
+
module.exports = ({ db }) => async function deleteDashboard(params) {
|
|
14
|
+
const { dashboardId } = new DeleteDashboardParams(params);
|
|
15
|
+
const Dashboard = db.model('__Studio_Dashboard');
|
|
16
|
+
|
|
17
|
+
const result = await Dashboard.deleteOne({ _id: dashboardId }).orFail();
|
|
18
|
+
return { result };
|
|
19
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
exports.createDashboard = require('./createDashboard');
|
|
4
|
+
exports.deleteDashboard = require('./deleteDashboard');
|
|
4
5
|
exports.getDashboard = require('./getDashboard');
|
|
5
6
|
exports.getDashboards = require('./getDashboards');
|
|
6
7
|
exports.updateDashboard = require('./updateDashboard');
|
|
@@ -10,16 +10,32 @@ const UpdateDashboardParams = new Archetype({
|
|
|
10
10
|
code: {
|
|
11
11
|
$type: 'string',
|
|
12
12
|
$required: true
|
|
13
|
+
},
|
|
14
|
+
title: {
|
|
15
|
+
$type: 'string'
|
|
16
|
+
},
|
|
17
|
+
description: {
|
|
18
|
+
$type: 'string'
|
|
13
19
|
}
|
|
14
20
|
}).compile('UpdateDashboardParams');
|
|
15
21
|
|
|
16
22
|
module.exports = ({ db }) => async function updateDashboard(params) {
|
|
17
|
-
const { dashboardId, code } = new UpdateDashboardParams(params);
|
|
23
|
+
const { dashboardId, code, title, description } = new UpdateDashboardParams(params);
|
|
18
24
|
|
|
19
25
|
const Dashboard = db.models[`__Studio_Dashboard`];
|
|
20
26
|
|
|
27
|
+
const updateObj = { code };
|
|
28
|
+
|
|
29
|
+
if (title) {
|
|
30
|
+
updateObj.title = title;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (description) {
|
|
34
|
+
updateObj.description = description;
|
|
35
|
+
}
|
|
36
|
+
|
|
21
37
|
const doc = await Dashboard.
|
|
22
|
-
findByIdAndUpdate(dashboardId,
|
|
38
|
+
findByIdAndUpdate(dashboardId, updateObj, { sanitizeFilter: true, returnDocument: 'after', overwriteImmutable: true });
|
|
23
39
|
|
|
24
40
|
let result = null;
|
|
25
41
|
try {
|
package/frontend/public/app.js
CHANGED
|
@@ -28,6 +28,16 @@ if (typeof config__setAuthorizationHeaderFrom === 'string' && config__setAuthori
|
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
client.interceptors.response.use(
|
|
32
|
+
res => res,
|
|
33
|
+
err => {
|
|
34
|
+
if (typeof err.response.data === 'string') {
|
|
35
|
+
throw new Error(`Error in ${err.config?.method} ${err.config?.url}: ${err.response.data}`);
|
|
36
|
+
}
|
|
37
|
+
throw err;
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
|
|
31
41
|
if (false) {} else {
|
|
32
42
|
exports.Dashboard = {
|
|
33
43
|
createDashboard: function createDashboard(params) {
|
|
@@ -665,6 +675,11 @@ appendCSS(__webpack_require__(/*! ./document-details.css */ "./frontend/src/docu
|
|
|
665
675
|
|
|
666
676
|
module.exports = app => app.component('document-details', {
|
|
667
677
|
template,
|
|
678
|
+
data: function() {
|
|
679
|
+
return {
|
|
680
|
+
dateType: 'picker' // picker, iso
|
|
681
|
+
}
|
|
682
|
+
},
|
|
668
683
|
props: ['document', 'schemaPaths', 'editting', 'changes', 'invalid'],
|
|
669
684
|
methods: {
|
|
670
685
|
getComponentForPath(schemaPath) {
|
|
@@ -713,7 +728,7 @@ module.exports = app => app.component('document-details', {
|
|
|
713
728
|
}
|
|
714
729
|
|
|
715
730
|
return result;
|
|
716
|
-
}
|
|
731
|
+
},
|
|
717
732
|
}
|
|
718
733
|
})
|
|
719
734
|
|
|
@@ -917,13 +932,11 @@ const template = __webpack_require__(/*! ./edit-date.html */ "./frontend/src/edi
|
|
|
917
932
|
|
|
918
933
|
module.exports = app => app.component('edit-date', {
|
|
919
934
|
template: template,
|
|
920
|
-
props: ['value'],
|
|
935
|
+
props: ['value', 'format'],
|
|
921
936
|
emits: ['input'],
|
|
922
|
-
data:
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
}
|
|
926
|
-
},
|
|
937
|
+
data: () => ({
|
|
938
|
+
inputType: ''
|
|
939
|
+
}),
|
|
927
940
|
computed: {
|
|
928
941
|
valueAsLocalString() {
|
|
929
942
|
if (this.value == null) {
|
|
@@ -948,6 +961,9 @@ module.exports = app => app.component('edit-date', {
|
|
|
948
961
|
}
|
|
949
962
|
const date = new Date(this.value);
|
|
950
963
|
return date.toISOString();
|
|
964
|
+
},
|
|
965
|
+
dateSelection() {
|
|
966
|
+
return this.format;
|
|
951
967
|
}
|
|
952
968
|
}
|
|
953
969
|
});
|
|
@@ -2559,7 +2575,7 @@ module.exports = "<div>\n {{value}}\n</div>";
|
|
|
2559
2575
|
/***/ ((module) => {
|
|
2560
2576
|
|
|
2561
2577
|
"use strict";
|
|
2562
|
-
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}";
|
|
2578
|
+
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}";
|
|
2563
2579
|
|
|
2564
2580
|
/***/ }),
|
|
2565
2581
|
|
|
@@ -2570,7 +2586,7 @@ module.exports = ".document-details {\n width: 100%;\n}\n\n.document-details .v
|
|
|
2570
2586
|
/***/ ((module) => {
|
|
2571
2587
|
|
|
2572
2588
|
"use strict";
|
|
2573
|
-
module.exports = "<div class=\"document-details\">\n <div v-for=\"path in schemaPaths\" class=\"value\">\n <div class=\"path-key p-1\">\n {{path.path}}\n
|
|
2589
|
+
module.exports = "<div class=\"document-details\">\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 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>";
|
|
2574
2590
|
|
|
2575
2591
|
/***/ }),
|
|
2576
2592
|
|
|
@@ -2636,7 +2652,7 @@ module.exports = "<div class=\"edit-array\">\n <textarea\n ref=\"arrayEditor
|
|
|
2636
2652
|
/***/ ((module) => {
|
|
2637
2653
|
|
|
2638
2654
|
"use strict";
|
|
2639
|
-
module.exports = "<div>\n <
|
|
2655
|
+
module.exports = "<div>\n <input v-if=\"dateSelection == 'picker'\" class=\"w-64 h-8 border border-gray-300 outline-0\" type=\"datetime-local\" :value=\"valueAsLocalString\" @input=\"$emit('input', $event.target.value)\">\n <input v-if=\"dateSelection == 'iso'\" type=\"text\" class=\"w-64 h-8 border border-gray-300 outline-0\" :value=\"valueAsISOString\" @input=\"$emit('input', $event.target.value)\">\n</div>";
|
|
2640
2656
|
|
|
2641
2657
|
/***/ }),
|
|
2642
2658
|
|
package/frontend/public/tw.css
CHANGED
|
@@ -582,6 +582,10 @@ video {
|
|
|
582
582
|
position: fixed;
|
|
583
583
|
}
|
|
584
584
|
|
|
585
|
+
.absolute {
|
|
586
|
+
position: absolute;
|
|
587
|
+
}
|
|
588
|
+
|
|
585
589
|
.relative {
|
|
586
590
|
position: relative;
|
|
587
591
|
}
|
|
@@ -774,6 +778,10 @@ video {
|
|
|
774
778
|
flex-grow: 1;
|
|
775
779
|
}
|
|
776
780
|
|
|
781
|
+
.cursor-pointer {
|
|
782
|
+
cursor: pointer;
|
|
783
|
+
}
|
|
784
|
+
|
|
777
785
|
.list-disc {
|
|
778
786
|
list-style-type: disc;
|
|
779
787
|
}
|
|
@@ -790,8 +798,16 @@ video {
|
|
|
790
798
|
align-items: center;
|
|
791
799
|
}
|
|
792
800
|
|
|
793
|
-
.justify-
|
|
794
|
-
justify-content:
|
|
801
|
+
.justify-center {
|
|
802
|
+
justify-content: center;
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
.gap-1 {
|
|
806
|
+
gap: 0.25rem;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
.gap-1\.5 {
|
|
810
|
+
gap: 0.375rem;
|
|
795
811
|
}
|
|
796
812
|
|
|
797
813
|
.gap-2 {
|
|
@@ -828,6 +844,10 @@ video {
|
|
|
828
844
|
border-color: rgb(209 213 219 / var(--tw-divide-opacity));
|
|
829
845
|
}
|
|
830
846
|
|
|
847
|
+
.self-stretch {
|
|
848
|
+
align-self: stretch;
|
|
849
|
+
}
|
|
850
|
+
|
|
831
851
|
.overflow-auto {
|
|
832
852
|
overflow: auto;
|
|
833
853
|
}
|
|
@@ -862,22 +882,22 @@ video {
|
|
|
862
882
|
border-radius: 0px;
|
|
863
883
|
}
|
|
864
884
|
|
|
865
|
-
.rounded-
|
|
866
|
-
border-
|
|
867
|
-
border-bottom-left-radius: 0.375rem;
|
|
885
|
+
.rounded-xl {
|
|
886
|
+
border-radius: 0.75rem;
|
|
868
887
|
}
|
|
869
888
|
|
|
870
|
-
.rounded-
|
|
871
|
-
border-
|
|
872
|
-
border-bottom-right-radius: 0.375rem;
|
|
889
|
+
.rounded-sm {
|
|
890
|
+
border-radius: 0.125rem;
|
|
873
891
|
}
|
|
874
892
|
|
|
875
|
-
.rounded-
|
|
893
|
+
.rounded-l-md {
|
|
876
894
|
border-top-left-radius: 0.375rem;
|
|
895
|
+
border-bottom-left-radius: 0.375rem;
|
|
877
896
|
}
|
|
878
897
|
|
|
879
|
-
.rounded-
|
|
898
|
+
.rounded-r-md {
|
|
880
899
|
border-top-right-radius: 0.375rem;
|
|
900
|
+
border-bottom-right-radius: 0.375rem;
|
|
881
901
|
}
|
|
882
902
|
|
|
883
903
|
.border {
|
|
@@ -1096,6 +1116,10 @@ video {
|
|
|
1096
1116
|
vertical-align: middle;
|
|
1097
1117
|
}
|
|
1098
1118
|
|
|
1119
|
+
.font-\[\'Lato\'\] {
|
|
1120
|
+
font-family: 'Lato';
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1099
1123
|
.text-base {
|
|
1100
1124
|
font-size: 1rem;
|
|
1101
1125
|
line-height: 1.5rem;
|
|
@@ -1116,6 +1140,11 @@ video {
|
|
|
1116
1140
|
line-height: 1.75rem;
|
|
1117
1141
|
}
|
|
1118
1142
|
|
|
1143
|
+
.text-xs {
|
|
1144
|
+
font-size: 0.75rem;
|
|
1145
|
+
line-height: 1rem;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1119
1148
|
.font-bold {
|
|
1120
1149
|
font-weight: 700;
|
|
1121
1150
|
}
|
|
@@ -1128,10 +1157,18 @@ video {
|
|
|
1128
1157
|
font-weight: 600;
|
|
1129
1158
|
}
|
|
1130
1159
|
|
|
1160
|
+
.capitalize {
|
|
1161
|
+
text-transform: capitalize;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1131
1164
|
.leading-6 {
|
|
1132
1165
|
line-height: 1.5rem;
|
|
1133
1166
|
}
|
|
1134
1167
|
|
|
1168
|
+
.leading-tight {
|
|
1169
|
+
line-height: 1.25;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1135
1172
|
.text-black {
|
|
1136
1173
|
--tw-text-opacity: 1;
|
|
1137
1174
|
color: rgb(0 0 0 / var(--tw-text-opacity));
|
|
@@ -1152,11 +1189,6 @@ video {
|
|
|
1152
1189
|
color: rgb(55 65 81 / var(--tw-text-opacity));
|
|
1153
1190
|
}
|
|
1154
1191
|
|
|
1155
|
-
.text-gray-800 {
|
|
1156
|
-
--tw-text-opacity: 1;
|
|
1157
|
-
color: rgb(31 41 55 / var(--tw-text-opacity));
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
1192
|
.text-gray-900 {
|
|
1161
1193
|
--tw-text-opacity: 1;
|
|
1162
1194
|
color: rgb(17 24 39 / var(--tw-text-opacity));
|
|
@@ -1177,6 +1209,11 @@ video {
|
|
|
1177
1209
|
color: rgb(153 27 27 / var(--tw-text-opacity));
|
|
1178
1210
|
}
|
|
1179
1211
|
|
|
1212
|
+
.text-sky-600 {
|
|
1213
|
+
--tw-text-opacity: 1;
|
|
1214
|
+
color: rgb(2 132 199 / var(--tw-text-opacity));
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1180
1217
|
.text-sky-800 {
|
|
1181
1218
|
--tw-text-opacity: 1;
|
|
1182
1219
|
color: rgb(7 89 133 / var(--tw-text-opacity));
|
|
@@ -1272,11 +1309,6 @@ video {
|
|
|
1272
1309
|
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
|
1273
1310
|
}
|
|
1274
1311
|
|
|
1275
|
-
.hover\:bg-gray-200:hover {
|
|
1276
|
-
--tw-bg-opacity: 1;
|
|
1277
|
-
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
|
|
1278
|
-
}
|
|
1279
|
-
|
|
1280
1312
|
.hover\:bg-gray-300:hover {
|
|
1281
1313
|
--tw-bg-opacity: 1;
|
|
1282
1314
|
background-color: rgb(209 213 219 / var(--tw-bg-opacity));
|
package/frontend/src/api.js
CHANGED
|
@@ -18,6 +18,16 @@ if (typeof config__setAuthorizationHeaderFrom === 'string' && config__setAuthori
|
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
client.interceptors.response.use(
|
|
22
|
+
res => res,
|
|
23
|
+
err => {
|
|
24
|
+
if (typeof err.response.data === 'string') {
|
|
25
|
+
throw new Error(`Error in ${err.config?.method} ${err.config?.url}: ${err.response.data}`);
|
|
26
|
+
}
|
|
27
|
+
throw err;
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
|
|
21
31
|
if (config__isLambda) {
|
|
22
32
|
exports.Dashboard = {
|
|
23
33
|
createDashboard(params) {
|
|
@@ -64,6 +74,9 @@ if (config__isLambda) {
|
|
|
64
74
|
createDashboard: function createDashboard(params) {
|
|
65
75
|
return client.post('/Dashboard/createDashboard', params).then(res => res.data);
|
|
66
76
|
},
|
|
77
|
+
deleteDashboard: function deleteDashboard(params) {
|
|
78
|
+
return client.post('/Dashboard/deleteDashboard', params).then(res => res.data)
|
|
79
|
+
},
|
|
67
80
|
getDashboard: function getDashboard(params) {
|
|
68
81
|
return client.put('/Dashboard/getDashboard', params).then(res => res.data);
|
|
69
82
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div class="dashboard px-1">
|
|
2
2
|
<div v-if="dashboard" class="max-w-5xl mx-auto">
|
|
3
3
|
<div class="flex items-center w-full">
|
|
4
|
-
<h2 class="mt-4 mb-4 text-gray-900 font-semibold text-xl grow shrink">{{
|
|
4
|
+
<h2 class="mt-4 mb-4 text-gray-900 font-semibold text-xl grow shrink">{{title}}</h2>
|
|
5
5
|
<div>
|
|
6
6
|
<button
|
|
7
7
|
v-if="!showEditor"
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
<edit-dashboard
|
|
20
20
|
:dashboardId="dashboard._id"
|
|
21
21
|
:code="code"
|
|
22
|
+
:currentDescription="description"
|
|
23
|
+
:currentTitle="title"
|
|
22
24
|
@close="showEditor=false;"
|
|
23
25
|
@update="updateCode"></edit-dashboard>
|
|
24
26
|
</div>
|
|
@@ -10,6 +10,8 @@ module.exports = app => app.component('dashboard', {
|
|
|
10
10
|
return {
|
|
11
11
|
status: 'loading',
|
|
12
12
|
code: '',
|
|
13
|
+
title: '',
|
|
14
|
+
description: '',
|
|
13
15
|
showEditor: false,
|
|
14
16
|
dashboard: null,
|
|
15
17
|
result: null
|
|
@@ -21,6 +23,8 @@ module.exports = app => app.component('dashboard', {
|
|
|
21
23
|
},
|
|
22
24
|
async updateCode(update) {
|
|
23
25
|
this.code = update.doc.code;
|
|
26
|
+
this.title = update.doc.title;
|
|
27
|
+
this.description = update.doc.description;
|
|
24
28
|
this.result = update.result;
|
|
25
29
|
}
|
|
26
30
|
},
|
|
@@ -31,6 +35,8 @@ module.exports = app => app.component('dashboard', {
|
|
|
31
35
|
}
|
|
32
36
|
this.dashboard = dashboard;
|
|
33
37
|
this.code = this.dashboard.code;
|
|
38
|
+
this.title = this.dashboard.title;
|
|
39
|
+
this.description = this.dashboard.description ?? '';
|
|
34
40
|
this.result = result;
|
|
35
41
|
this.status = 'loaded';
|
|
36
42
|
}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
<div>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
<div class="p-4 bg-gray-100 rounded-lg shadow-lg">
|
|
2
|
+
<div>
|
|
3
|
+
<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"/>
|
|
4
|
+
</div>
|
|
5
|
+
<div>
|
|
6
|
+
<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>
|
|
7
|
+
</div>
|
|
8
|
+
<div>
|
|
9
|
+
<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>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="flex space-x-2">
|
|
12
|
+
<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>
|
|
13
|
+
<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>
|
|
14
|
+
</div>
|
|
5
15
|
</div>
|
|
@@ -5,11 +5,13 @@ const template = require('./edit-dashboard.html');
|
|
|
5
5
|
|
|
6
6
|
module.exports = app => app.component('edit-dashboard', {
|
|
7
7
|
template: template,
|
|
8
|
-
props: ['dashboardId', 'code'],
|
|
8
|
+
props: ['dashboardId', 'code', 'currentDescription', 'currentTitle'],
|
|
9
9
|
data: function() {
|
|
10
10
|
return {
|
|
11
11
|
status: 'loading',
|
|
12
12
|
editor: null,
|
|
13
|
+
title: '',
|
|
14
|
+
description: ''
|
|
13
15
|
}
|
|
14
16
|
},
|
|
15
17
|
methods: {
|
|
@@ -17,9 +19,12 @@ module.exports = app => app.component('edit-dashboard', {
|
|
|
17
19
|
this.$emit('close')
|
|
18
20
|
},
|
|
19
21
|
async updateCode() {
|
|
22
|
+
console.log('this.title', this.title, 'this.description', this.description)
|
|
20
23
|
const { doc, result } = await api.Dashboard.updateDashboard({
|
|
21
24
|
dashboardId: this.dashboardId,
|
|
22
|
-
code: this.editor.getValue()
|
|
25
|
+
code: this.editor.getValue(),
|
|
26
|
+
title: this.title,
|
|
27
|
+
description: this.description
|
|
23
28
|
});
|
|
24
29
|
this.$emit('update', { doc, result });
|
|
25
30
|
this.editor.setValue(doc.code);
|
|
@@ -45,7 +50,7 @@ module.exports = app => app.component('edit-dashboard', {
|
|
|
45
50
|
|
|
46
51
|
this.editor.focus();
|
|
47
52
|
// this.editor.refresh(); // if anything weird happens on load, this usually fixes it. However, this breaks it in this case.
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
this.description = this.currentDescription;
|
|
54
|
+
this.title = this.currentTitle;
|
|
50
55
|
}
|
|
51
56
|
});
|
|
@@ -59,6 +59,13 @@
|
|
|
59
59
|
View
|
|
60
60
|
</router-link>
|
|
61
61
|
</td>
|
|
62
|
+
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8">
|
|
63
|
+
<button
|
|
64
|
+
@click="showDeleteDashboardModal=dashboard"
|
|
65
|
+
class="text-teal-600 hover:text-teal-900">
|
|
66
|
+
Delete
|
|
67
|
+
</button>
|
|
68
|
+
</td>
|
|
62
69
|
</tr>
|
|
63
70
|
|
|
64
71
|
<!-- More people... -->
|
|
@@ -73,7 +80,18 @@
|
|
|
73
80
|
<template v-slot:body>
|
|
74
81
|
<div class="modal-exit" @click="showCreateDashboardModal = false;">×</div>
|
|
75
82
|
|
|
76
|
-
<create-dashboard></create-dashboard>
|
|
83
|
+
<create-dashboard @close="insertNewDashboard"></create-dashboard>
|
|
84
|
+
</template>
|
|
85
|
+
</modal>
|
|
86
|
+
|
|
87
|
+
<modal v-if="showDeleteDashboardModal">
|
|
88
|
+
<template v-slot:body>
|
|
89
|
+
<div class="modal-exit" @click="showDeleteDashboardModal = null;">×</div>
|
|
90
|
+
<h2>Are you sure you want to delete this dashboard titled {{showDeleteDashboardModal.title}}?</h2>
|
|
91
|
+
<div class="flex space-x-2">
|
|
92
|
+
<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>
|
|
93
|
+
<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>
|
|
94
|
+
</div>
|
|
77
95
|
</template>
|
|
78
96
|
</modal>
|
|
79
97
|
</div>
|
|
@@ -9,8 +9,24 @@ module.exports = app => app.component('dashboards', {
|
|
|
9
9
|
data: () => ({
|
|
10
10
|
status: 'loading',
|
|
11
11
|
dashboards: [],
|
|
12
|
-
showCreateDashboardModal: false
|
|
12
|
+
showCreateDashboardModal: false,
|
|
13
|
+
showDeleteDashboardModal: null
|
|
13
14
|
}),
|
|
15
|
+
methods: {
|
|
16
|
+
async deleteDashboard(dashboard) {
|
|
17
|
+
if (!dashboard) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
await api.Dashboard.deleteDashboard({ dashboardId: dashboard._id });
|
|
21
|
+
const removedDashboard = this.dashboards.findIndex(x => x._id.toString() === dashboard._id.toString());
|
|
22
|
+
this.dashboards.splice(removedDashboard, 1);
|
|
23
|
+
this.showDeleteDashboardModal = null;
|
|
24
|
+
},
|
|
25
|
+
insertNewDashboard(dashboard) {
|
|
26
|
+
this.dashboards.push(dashboard);
|
|
27
|
+
this.showCreateDashboardModal = false;
|
|
28
|
+
}
|
|
29
|
+
},
|
|
14
30
|
async mounted() {
|
|
15
31
|
const { dashboards } = await api.Dashboard.getDashboards();
|
|
16
32
|
this.dashboards = dashboards;
|
|
@@ -1,15 +1,40 @@
|
|
|
1
1
|
<div class="document-details">
|
|
2
2
|
<div v-for="path in schemaPaths" class="value">
|
|
3
|
-
<div class="path-key p-1">
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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>
|
|
8
32
|
</div>
|
|
9
33
|
<div v-if="editting && path.path !== '_id'" class="pl-1">
|
|
10
34
|
<component
|
|
11
35
|
:is="getEditComponentForPath(path)"
|
|
12
36
|
:value="getEditValueForPath(path)"
|
|
37
|
+
:format="dateType"
|
|
13
38
|
@input="changes[path.path] = $event; delete invalid[path.path];"
|
|
14
39
|
@error="invalid[path.path] = $event;"
|
|
15
40
|
>
|
|
@@ -9,6 +9,11 @@ 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
|
+
},
|
|
12
17
|
props: ['document', 'schemaPaths', 'editting', 'changes', 'invalid'],
|
|
13
18
|
methods: {
|
|
14
19
|
getComponentForPath(schemaPath) {
|
|
@@ -57,6 +62,6 @@ module.exports = app => app.component('document-details', {
|
|
|
57
62
|
}
|
|
58
63
|
|
|
59
64
|
return result;
|
|
60
|
-
}
|
|
65
|
+
},
|
|
61
66
|
}
|
|
62
67
|
})
|
|
@@ -1,20 +1,4 @@
|
|
|
1
1
|
<div>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
@click="inputType = 'picker'"
|
|
5
|
-
type="button"
|
|
6
|
-
class="relative inline-flex items-center rounded-none p-1 rounded-tl-md text-sm text-gray-800 ring-1 ring-inset ring-gray-300 hover:bg-gray-200 focus:z-10"
|
|
7
|
-
:class="inputType === 'picker' ? 'bg-gray-200' : 'bg-white'">
|
|
8
|
-
Date Picker
|
|
9
|
-
</button>
|
|
10
|
-
<button
|
|
11
|
-
@click="inputType = 'iso'"
|
|
12
|
-
type="button"
|
|
13
|
-
class="relative -ml-px inline-flex items-center p-1 rounded-none rounded-tr-md text-sm text-gray-800 ring-1 ring-inset ring-gray-300 hover:bg-gray-200 focus:z-10"
|
|
14
|
-
:class="inputType === 'iso' ? 'bg-gray-200' : 'bg-white'">
|
|
15
|
-
ISO String Input
|
|
16
|
-
</button>
|
|
17
|
-
</div>
|
|
18
|
-
<input v-if="inputType == 'picker'" class="w-64 h-8 border border-gray-300 outline-0" type="datetime-local" :value="valueAsLocalString" @input="$emit('input', $event.target.value)">
|
|
19
|
-
<input v-if="inputType == 'iso'" type="text" class="w-64 h-8 border border-gray-300 outline-0" :value="valueAsISOString" @input="$emit('input', $event.target.value)">
|
|
2
|
+
<input v-if="dateSelection == 'picker'" class="w-64 h-8 border border-gray-300 outline-0" type="datetime-local" :value="valueAsLocalString" @input="$emit('input', $event.target.value)">
|
|
3
|
+
<input v-if="dateSelection == 'iso'" type="text" class="w-64 h-8 border border-gray-300 outline-0" :value="valueAsISOString" @input="$emit('input', $event.target.value)">
|
|
20
4
|
</div>
|
|
@@ -4,13 +4,11 @@ const template = require('./edit-date.html');
|
|
|
4
4
|
|
|
5
5
|
module.exports = app => app.component('edit-date', {
|
|
6
6
|
template: template,
|
|
7
|
-
props: ['value'],
|
|
7
|
+
props: ['value', 'format'],
|
|
8
8
|
emits: ['input'],
|
|
9
|
-
data:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
},
|
|
9
|
+
data: () => ({
|
|
10
|
+
inputType: ''
|
|
11
|
+
}),
|
|
14
12
|
computed: {
|
|
15
13
|
valueAsLocalString() {
|
|
16
14
|
if (this.value == null) {
|
|
@@ -35,6 +33,9 @@ module.exports = app => app.component('edit-date', {
|
|
|
35
33
|
}
|
|
36
34
|
const date = new Date(this.value);
|
|
37
35
|
return date.toISOString();
|
|
36
|
+
},
|
|
37
|
+
dateSelection() {
|
|
38
|
+
return this.format;
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
});
|