@mongoosejs/studio 0.0.1
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/LICENSE +201 -0
- package/README.md +2 -0
- package/backend/actions/Model/exportQueryResults.js +66 -0
- package/backend/actions/Model/getDocument.js +30 -0
- package/backend/actions/Model/getDocuments.js +47 -0
- package/backend/actions/Model/index.js +7 -0
- package/backend/actions/Model/listModels.js +5 -0
- package/backend/actions/Model/updateDocument.js +32 -0
- package/backend/actions/index.js +3 -0
- package/backend/index.js +12 -0
- package/backend/netlify.js +28 -0
- package/express.js +36 -0
- package/frontend/index.js +36 -0
- package/frontend/public/app.js +4012 -0
- package/frontend/public/images/mongoose.svg +35 -0
- package/frontend/public/index.html +21 -0
- package/frontend/public/style.css +34 -0
- package/frontend/src/api.js +52 -0
- package/frontend/src/appendCSS.js +11 -0
- package/frontend/src/async-button/async-button.html +3 -0
- package/frontend/src/async-button/async-button.js +39 -0
- package/frontend/src/detail-array/detail-array.html +3 -0
- package/frontend/src/detail-array/detail-array.js +16 -0
- package/frontend/src/detail-default/detail-default.html +3 -0
- package/frontend/src/detail-default/detail-default.js +19 -0
- package/frontend/src/document/document.css +39 -0
- package/frontend/src/document/document.html +42 -0
- package/frontend/src/document/document.js +63 -0
- package/frontend/src/edit-default/edit-default.html +3 -0
- package/frontend/src/edit-default/edit-default.js +20 -0
- package/frontend/src/export-query-results/export-query-results.css +0 -0
- package/frontend/src/export-query-results/export-query-results.html +11 -0
- package/frontend/src/export-query-results/export-query-results.js +34 -0
- package/frontend/src/index.js +43 -0
- package/frontend/src/list-array/list-array.css +8 -0
- package/frontend/src/list-array/list-array.html +3 -0
- package/frontend/src/list-array/list-array.js +23 -0
- package/frontend/src/list-default/list-default.html +3 -0
- package/frontend/src/list-default/list-default.js +19 -0
- package/frontend/src/list-subdocument/list-subdocument.html +3 -0
- package/frontend/src/list-subdocument/list-subdocument.js +9 -0
- package/frontend/src/modal/modal.css +75 -0
- package/frontend/src/modal/modal.html +12 -0
- package/frontend/src/modal/modal.js +10 -0
- package/frontend/src/models/models.css +108 -0
- package/frontend/src/models/models.html +53 -0
- package/frontend/src/models/models.js +107 -0
- package/frontend/src/navbar/navbar.css +162 -0
- package/frontend/src/navbar/navbar.html +10 -0
- package/frontend/src/navbar/navbar.js +11 -0
- package/frontend/src/routes.js +19 -0
- package/frontend/webpack.config.js +36 -0
- package/package.json +21 -0
- package/test.js +264 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
2
|
+
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" id="svg2" xml:space="preserve" width="1280" height="746.66669" viewBox="0 0 1280 746.66669" sodipodi:docname="mongoose.svg" inkscape:version="1.0.1 (1.0.1+r75)">
|
|
3
|
+
<metadata id="metadata8">
|
|
4
|
+
<rdf:RDF>
|
|
5
|
+
<cc:Work rdf:about="">
|
|
6
|
+
<dc:format>image/svg+xml</dc:format>
|
|
7
|
+
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
|
8
|
+
</cc:Work>
|
|
9
|
+
</rdf:RDF>
|
|
10
|
+
</metadata>
|
|
11
|
+
<defs id="defs6">
|
|
12
|
+
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath22">
|
|
13
|
+
<path d="M 0,560 H 960 V 0 H 0 Z" id="path20"/>
|
|
14
|
+
</clipPath>
|
|
15
|
+
</defs>
|
|
16
|
+
<sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="2227" inkscape:window-height="1205" id="namedview4" inkscape:document-rotation="0" showgrid="false" inkscape:zoom="0.85703125" inkscape:cx="528.80219" inkscape:cy="373.33334" inkscape:window-x="24" inkscape:window-y="132" inkscape:window-maximized="0" inkscape:current-layer="g18"/>
|
|
17
|
+
<g id="g10" inkscape:groupmode="layer" inkscape:label="FIVERRMONGOOSE" transform="matrix(2,0,0,-2,-340,1000)">
|
|
18
|
+
<g id="g12" transform="translate(439.8999,245.333)">
|
|
19
|
+
<path d="m 0,0 -23.9,37.117 v -66.45 h 46.403 l 1.597,1.636 v 64.814 z" style="fill:#880000;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path14"/>
|
|
20
|
+
</g>
|
|
21
|
+
<g id="g16">
|
|
22
|
+
<g id="g18" clip-path="url(#clipPath22)">
|
|
23
|
+
<g id="g24" transform="translate(662.1133,391.8979)">
|
|
24
|
+
<path
|
|
25
|
+
d="M 0 0 c -9.067 -0.676 -18.155 -1.376 -27.24 -1.429 c -5.592 -0.032 -11.28 0.698 -16.766 1.839 c -6.932 1.443 -12.758 4.878 -16.186 11.582 c -0.51 0.993 -2.217 1.565 -3.484 1.943 c -4.468 1.328 -8.986 2.485 -13.498 4.154 c 1.57 0.118 3.141 0.346 4.708 0.33 c 3.846 -0.038 7.735 0.142 11.522 -0.366 c 6.921 -0.928 13.787 -2.28 20.673 -3.475 c 3.924 -0.682 7.869 -1.296 11.761 -2.133 c 7.385 -1.589 14.744 -3.298 22.106 -4.989 C -1.539 6.339 3.315 5.182 8.168 4.007 M 1.769 -49.161 c -11.308 -3.485 -22.742 -6.62 -33.861 -10.63 c -6.961 -2.511 -13.502 -6.23 -20.12 -9.626 c -5.77 -2.958 -7.811 -8.009 -7.103 -14.28 c 0.457 -4.029 1.009 -8.047 1.371 -12.133 c -2.957 4.363 -5.141 9.082 -6.424 14.218 c -0.264 1.062 -0.515 2.128 -0.737 3.2 c -0.874 4.183 1.446 6.787 4.476 9.055 c 5.897 4.415 12.32 7.892 19.292 10.205 c 8.696 2.887 17.419 5.768 26.284 8.057 c 6.245 1.61 12.745 2.223 19.127 3.304 c 1.178 0.202 2.337 0.52 3.505 0.782 c 0.039 -0.16 0.079 -0.321 0.12 -0.481 c -1.977 -0.554 -3.97 -1.066 -5.93 -1.671 m -159.454 44.744 c -0.186 -0.182 -0.375 -0.362 -0.563 -0.542 c -5.042 3.677 -10.514 6.415 -16.51 8.003 c -0.168 -0.163 -0.332 -0.326 -0.496 -0.49 c 5.161 -6.048 10.323 -12.096 15.71 -18.404 c -3.607 1.18 -6.964 2.28 -10.322 3.379 c -0.143 -0.169 -0.284 -0.339 -0.428 -0.508 c 4.063 -6.694 9.353 -12.51 14.396 -19.22 c -8.768 4.979 -16.507 10.417 -23.731 16.595 c -9.916 8.481 -18.566 18.047 -25.046 29.439 c -2.669 4.694 -5.025 9.55 -5.529 15.043 c -0.113 1.226 -0.015 2.523 0.271 3.72 c 0.465 1.943 2.309 2.84 4.202 2.252 c 10.4 -3.233 20.622 -6.896 30.189 -12.211 c 9.056 -5.031 17.252 -11.153 24.303 -18.769 c 0.285 -0.308 0.496 -0.684 0.889 -1.236 c -5.521 2.516 -10.76 4.902 -16 7.289 c -0.177 -0.217 -0.353 -0.435 -0.532 -0.653 c 3.067 -4.562 6.132 -9.125 9.197 -13.687 m -315.372 -55.318 c -0.13 -0.353 0.276 -0.7 0.414 -1.049 c 2.156 0.453 4.293 1.045 6.47 1.339 c 0.568 0.075 1.136 0.147 1.705 0.223 c 8.034 2.863 16.264 5.112 24.762 6.31 c 12.011 1.691 24.463 3.936 36.722 3.87 c 11.648 -0.059 23.431 -1.843 34.828 -3.808 c 3.197 -0.55 6.336 -1.288 9.43 -2.158 c 8.326 -1.869 16.15 -5.203 23.182 -9.709 c 0.507 -0.242 1 -0.509 1.502 -0.763 c 9.998 -4.71 18.807 -11.639 25.763 -20.128 c 1.273 -1.409 3.492 -2.878 4.629 -4.42 c 2.396 -2.827 3.537 -5.839 7.537 -8.996 v 43.126 h 49.88 l 23.323 -43.036 l 23.392 43.036 h 51.405 v -83.351 l 8.509 5.611 c 0 0 9.33 24.806 52.556 28.289 l 49.544 1.602 c -7.642 15.819 -7.614 15.819 -3.929 20.591 c 3.649 4.722 31.792 7.818 36.742 10.771 l 72.297 14.587 c 0.17 0.556 0.363 -0.298 0.736 -0.181 c 1.799 0.567 3.663 0.924 6.233 1.529 l 16.35 3.979 c 1.064 0.599 2.331 0.836 3.504 1.242 c 7.64 2.652 14.321 6.068 18.018 14.208 c 3.6 7.93 8.421 15.296 10.169 24.018 c 0.551 2.759 0.076 5.157 -1.915 7.14 c -2.409 2.398 -5.516 3.428 -8.715 4.259 c -10.444 4.287 -20.85 8.676 -31.379 12.747 c -6.473 2.504 -13.114 4.582 -19.724 6.71 c -6.54 2.105 -13.117 4.092 -19.711 6.019 c -6.074 1.777 -12.185 3.429 -18.288 5.094 c -5.954 1.624 -11.9 3.295 -17.892 4.767 c -6.981 1.716 -14.01 3.243 -21.02 4.845 c -5.324 1.217 -10.628 2.519 -15.977 3.608 c -5.825 1.186 -11.687 2.206 -17.543 3.237 c -7.48 1.315 -14.944 2.773 -22.466 3.797 c -9.083 1.236 -18.224 2.036 -27.332 3.109 c -15.25 1.798 -30.54 2.28 -45.839 1.111 c -5.422 -0.414 -10.771 -1.788 -16.152 -2.722 c 5.7 -2.929 11.34 -5.298 16.903 -7.834 c 5.596 -2.551 10.813 -5.748 15.604 -9.607 c -6.269 2.4 -12.368 5.168 -18.655 7.413 c -13.121 4.684 -26.47 8.574 -40.333 10.45 c -6.781 0.917 -13.545 1.797 -20.32 -0.115 c -6.867 -1.938 -8.809 -4.486 -9.431 -11.377 c -1.03 -11.422 2.407 -22.016 6.972 -32.231 c 6.807 -15.232 16.728 -28.207 29.414 -39.057 c 9.714 -8.311 20.492 -14.861 32.398 -19.531 c 3.391 -1.33 6.815 -2.579 10.221 -3.866 c -0.077 -0.265 -0.154 -0.527 -0.231 -0.793 c -6.528 1.788 -13.221 3.128 -19.544 5.466 c -11.183 4.133 -21.183 10.447 -30.332 18.115 c -10.212 8.561 -18.699 18.566 -25.007 30.289 c -6.694 12.439 -10.525 25.73 -10.663 39.955"
|
|
26
|
+
style="fill:#880000;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
|
27
|
+
id="path26"/>
|
|
28
|
+
</g>
|
|
29
|
+
<g id="g28" transform="translate(189.0308,331.666)">
|
|
30
|
+
<path d="M 0,0 C 0,0 115.969,112 248.5,98.1" style="fill:#880000;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path30"/>
|
|
31
|
+
</g>
|
|
32
|
+
</g>
|
|
33
|
+
</g>
|
|
34
|
+
</g>
|
|
35
|
+
</svg>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<title>Mongoose Admin</title>
|
|
4
|
+
|
|
5
|
+
<meta content="width=device-width, initial-scale=1" name="viewport">
|
|
6
|
+
<meta name="msapplication-TileColor" />
|
|
7
|
+
<meta name="theme-color" content="#ffffff"/>
|
|
8
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans"/>
|
|
9
|
+
<link rel="stylesheet" type="text/css" href="style.css"/>
|
|
10
|
+
<link rel="stylesheet" href="https://unpkg.com/prismjs@1.29.0/themes/prism.css"/>
|
|
11
|
+
<script src="https://unpkg.com/vue@3.x"></script>
|
|
12
|
+
<script src="https://unpkg.com/vue-router@4.0.10"></script>
|
|
13
|
+
</head>
|
|
14
|
+
|
|
15
|
+
<body>
|
|
16
|
+
<div id="content"></div>
|
|
17
|
+
|
|
18
|
+
<script src="https://unpkg.com/prismjs@1.29.0/prism.js" data-manual="true"></script>
|
|
19
|
+
<script src="app.js"></script>
|
|
20
|
+
</body>
|
|
21
|
+
</html>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
body {
|
|
2
|
+
min-height: 100%;
|
|
3
|
+
margin: 0;
|
|
4
|
+
padding: 0;
|
|
5
|
+
font-family: 'Open Sans', Helvetica, Arial, FreeSans, sans-serif;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
a {
|
|
9
|
+
text-decoration: none;
|
|
10
|
+
color: #0E5887;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.bold {
|
|
14
|
+
font-weight: bold !important;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
button {
|
|
18
|
+
background-color: #15D4B7;
|
|
19
|
+
color: white;
|
|
20
|
+
padding: 0.25em 0.5em;
|
|
21
|
+
cursor: pointer;
|
|
22
|
+
border: 0;
|
|
23
|
+
border-radius: 4px;
|
|
24
|
+
font-size: 1.1em;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
button.green {
|
|
28
|
+
background-color: #58D415;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
button.grey {
|
|
32
|
+
color: black;
|
|
33
|
+
background-color: #ddd;
|
|
34
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const axios = require('axios');
|
|
4
|
+
|
|
5
|
+
const client = axios.create({
|
|
6
|
+
baseURL: config__baseURL
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
if (config__isLambda) {
|
|
10
|
+
exports.Model = {
|
|
11
|
+
exportQueryResults(params) {
|
|
12
|
+
return client.post('', { action: 'Model.exportQueryResults', ...params }).then(res => res.data);
|
|
13
|
+
},
|
|
14
|
+
getDocument: function getDocument(params) {
|
|
15
|
+
return client.post('', { action: 'Model.getDocument', ...params }).then(res => res.data);
|
|
16
|
+
},
|
|
17
|
+
getDocuments: function getDocuments(params) {
|
|
18
|
+
return client.post('', { action: 'Model.getDocuments', ...params }).then(res => res.data);
|
|
19
|
+
},
|
|
20
|
+
listModels: function listModels() {
|
|
21
|
+
return client.post('', { action: 'Model.listModels' }).then(res => res.data);
|
|
22
|
+
},
|
|
23
|
+
updateDocument: function updateDocument(params) {
|
|
24
|
+
return client.post('', { action: 'Model.updateDocument', ...params }).then(res => res.data);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
} else {
|
|
28
|
+
exports.Model = {
|
|
29
|
+
exportQueryResults(params) {
|
|
30
|
+
const anchor = document.createElement('a');
|
|
31
|
+
console.log('K', config__baseURL)
|
|
32
|
+
console.log('G', config__baseURL + '/Model/exportQueryResults?' + (new URLSearchParams(params)).toString());
|
|
33
|
+
anchor.href = config__baseURL + '/Model/exportQueryResults?' + (new URLSearchParams(params)).toString();
|
|
34
|
+
anchor.target = '_blank';
|
|
35
|
+
anchor.download = 'export.csv';
|
|
36
|
+
anchor.click();
|
|
37
|
+
return;
|
|
38
|
+
},
|
|
39
|
+
getDocument: function getDocument(params) {
|
|
40
|
+
return client.post('/Model/getDocument', params).then(res => res.data);
|
|
41
|
+
},
|
|
42
|
+
getDocuments: function getDocuments(params) {
|
|
43
|
+
return client.post('/Model/getDocuments', params).then(res => res.data);
|
|
44
|
+
},
|
|
45
|
+
listModels: function listModels() {
|
|
46
|
+
return client.post('/Model/listModels', {}).then(res => res.data);
|
|
47
|
+
},
|
|
48
|
+
updateDocument: function updateDocument(params) {
|
|
49
|
+
return client.post('/Model/updateDocument', params).then(res => res.data);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = function appendCSS(css) {
|
|
4
|
+
if (typeof document === 'undefined') {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const head = document.head || document.getElementsByTagName('head')[0];
|
|
8
|
+
const style = document.createElement('style');
|
|
9
|
+
head.appendChild(style);
|
|
10
|
+
style.appendChild(document.createTextNode(css));
|
|
11
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const template = require('./async-button.html');
|
|
4
|
+
|
|
5
|
+
module.exports = app => app.component('async-button', {
|
|
6
|
+
data: () => ({
|
|
7
|
+
status: 'init'
|
|
8
|
+
}),
|
|
9
|
+
inheritAttrs: false,
|
|
10
|
+
methods: {
|
|
11
|
+
async handleClick(ev) {
|
|
12
|
+
if (this.status === 'in_progress') {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
this.status = 'in_progress';
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
await this.$attrs.onClick(ev);
|
|
19
|
+
} catch (err) {
|
|
20
|
+
this.status = 'error';
|
|
21
|
+
throw err;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
this.status = 'success';
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
computed: {
|
|
28
|
+
attrsToBind() {
|
|
29
|
+
const attrs = { ...this.$attrs };
|
|
30
|
+
delete attrs.onClick;
|
|
31
|
+
delete attrs.disabled;
|
|
32
|
+
return attrs;
|
|
33
|
+
},
|
|
34
|
+
isDisabled() {
|
|
35
|
+
return this.status === 'in_progress' || this.$attrs.disabled;
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
template: template
|
|
39
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const template = require('./detail-array.html');
|
|
4
|
+
|
|
5
|
+
module.exports = app => app.component('detail-array', {
|
|
6
|
+
template: template,
|
|
7
|
+
props: ['value'],
|
|
8
|
+
computed: {
|
|
9
|
+
displayValue() {
|
|
10
|
+
return JSON.stringify(this.value, null, ' ').trim();
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
mounted() {
|
|
14
|
+
Prism.highlightElement(this.$refs.code);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const template = require('./detail-default.html');
|
|
4
|
+
|
|
5
|
+
module.exports = app => app.component('detail-default', {
|
|
6
|
+
template: template,
|
|
7
|
+
props: ['value'],
|
|
8
|
+
computed: {
|
|
9
|
+
displayValue() {
|
|
10
|
+
if (this.value === null) {
|
|
11
|
+
return 'null';
|
|
12
|
+
}
|
|
13
|
+
if (this.value === undefined) {
|
|
14
|
+
return 'undefined';
|
|
15
|
+
}
|
|
16
|
+
return this.value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
.document {
|
|
2
|
+
max-width: 1200px;
|
|
3
|
+
margin-left: auto;
|
|
4
|
+
margin-right: auto;
|
|
5
|
+
padding-top: 25px;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.document .value {
|
|
9
|
+
padding-top: 10px;
|
|
10
|
+
padding-bottom: 10px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.document .path-key {
|
|
14
|
+
background-color: #f0f0f0;
|
|
15
|
+
padding: 0.25em;
|
|
16
|
+
margin-bottom: 0.5em;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.document .path-type {
|
|
20
|
+
color: rgba(0,0,0,.36);
|
|
21
|
+
font-size: 0.8em;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.document .document-menu {
|
|
25
|
+
display: flex;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.document .document-menu .left {
|
|
29
|
+
flex-grow: 1;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.document .document-menu .right {
|
|
33
|
+
flex-grow: 1;
|
|
34
|
+
text-align: right;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.document .document-menu .right button:not(:last-child) {
|
|
38
|
+
margin-right: 0.5em;
|
|
39
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<div class="document">
|
|
2
|
+
<div class="document-menu">
|
|
3
|
+
<div class="left">
|
|
4
|
+
<button @click="$router.push('/model/' + this.model)">
|
|
5
|
+
‹ Back
|
|
6
|
+
</button>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<div class="right">
|
|
10
|
+
<button v-if="!editting" @click="editting = true">
|
|
11
|
+
✎ Edit
|
|
12
|
+
</button>
|
|
13
|
+
<button v-if="editting" class="grey" @click="editting = false">
|
|
14
|
+
× Cancel
|
|
15
|
+
</button>
|
|
16
|
+
<button v-if="editting" class="green" @click="save">
|
|
17
|
+
✓ Save
|
|
18
|
+
</button>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
<div v-if="status === 'loaded'">
|
|
22
|
+
<div v-for="path in schemaPaths" class="value">
|
|
23
|
+
<div class="path-key">
|
|
24
|
+
{{path.path}}
|
|
25
|
+
<span class="path-type">
|
|
26
|
+
({{path.instance.toLowerCase()}})
|
|
27
|
+
</span>
|
|
28
|
+
</div>
|
|
29
|
+
<div v-if="editting && path.path !== '_id'">
|
|
30
|
+
<component
|
|
31
|
+
:is="getEditComponentForPath(path)"
|
|
32
|
+
:value="getEditValueForPath(path)"
|
|
33
|
+
@input="changes[path.path] = $event;"
|
|
34
|
+
>
|
|
35
|
+
</component>
|
|
36
|
+
</div>
|
|
37
|
+
<div v-else>
|
|
38
|
+
<component :is="getComponentForPath(path)" :value="document[path.path]"></component>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const api = require('../api');
|
|
4
|
+
const template = require('./document.html');
|
|
5
|
+
|
|
6
|
+
const appendCSS = require('../appendCSS');
|
|
7
|
+
|
|
8
|
+
appendCSS(require('./document.css'));
|
|
9
|
+
|
|
10
|
+
module.exports = app => app.component('document', {
|
|
11
|
+
template: template,
|
|
12
|
+
props: ['model', 'documentId'],
|
|
13
|
+
data: () => ({
|
|
14
|
+
schemaPaths: [],
|
|
15
|
+
status: 'init',
|
|
16
|
+
document: null,
|
|
17
|
+
changes: {},
|
|
18
|
+
editting: false
|
|
19
|
+
}),
|
|
20
|
+
async mounted() {
|
|
21
|
+
const { doc, schemaPaths } = await api.Model.getDocument({ model: this.model, documentId: this.documentId });
|
|
22
|
+
this.document = doc;
|
|
23
|
+
this.schemaPaths = Object.keys(schemaPaths).sort((k1, k2) => {
|
|
24
|
+
if (k1 === '_id' && k2 !== '_id') {
|
|
25
|
+
return -1;
|
|
26
|
+
}
|
|
27
|
+
if (k1 !== '_id' && k2 === '_id') {
|
|
28
|
+
return 1;
|
|
29
|
+
}
|
|
30
|
+
return 0;
|
|
31
|
+
}).map(key => schemaPaths[key]);
|
|
32
|
+
|
|
33
|
+
this.status = 'loaded';
|
|
34
|
+
},
|
|
35
|
+
methods: {
|
|
36
|
+
getComponentForPath(schemaPath) {
|
|
37
|
+
if (schemaPath.instance === 'Array') {
|
|
38
|
+
return 'detail-array';
|
|
39
|
+
}
|
|
40
|
+
return 'detail-default';
|
|
41
|
+
},
|
|
42
|
+
getEditComponentForPath() {
|
|
43
|
+
return 'edit-default';
|
|
44
|
+
},
|
|
45
|
+
getEditValueForPath({ path }) {
|
|
46
|
+
return path in this.changes ? this.changes[path] : this.document[path];
|
|
47
|
+
},
|
|
48
|
+
cancelEdit() {
|
|
49
|
+
this.changes = {};
|
|
50
|
+
this.editting = false;
|
|
51
|
+
},
|
|
52
|
+
async save() {
|
|
53
|
+
const { doc } = await api.Model.updateDocument({
|
|
54
|
+
model: this.model,
|
|
55
|
+
_id: this.document._id,
|
|
56
|
+
update: this.changes
|
|
57
|
+
});
|
|
58
|
+
this.document = doc;
|
|
59
|
+
this.changes = {};
|
|
60
|
+
this.editting = false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const template = require('./edit-default.html');
|
|
4
|
+
|
|
5
|
+
module.exports = app => app.component('edit-default', {
|
|
6
|
+
template: template,
|
|
7
|
+
props: ['value'],
|
|
8
|
+
emits: ['input'],
|
|
9
|
+
computed: {
|
|
10
|
+
displayValue() {
|
|
11
|
+
if (this.value === null) {
|
|
12
|
+
return 'null';
|
|
13
|
+
}
|
|
14
|
+
if (this.value === undefined) {
|
|
15
|
+
return 'undefined';
|
|
16
|
+
}
|
|
17
|
+
return this.value;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
});
|
|
File without changes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<div class="export-query-results">
|
|
2
|
+
<h2>Export as CSV</h2>
|
|
3
|
+
<div>
|
|
4
|
+
Choose fields to export
|
|
5
|
+
</div>
|
|
6
|
+
<div v-for="schemaPath in schemaPaths">
|
|
7
|
+
<input type="checkbox" v-model="shouldExport[schemaPath.path]">
|
|
8
|
+
<span>{{schemaPath.path}}</span>
|
|
9
|
+
</div>
|
|
10
|
+
<async-button @click="exportQueryResults">Export</async-button>
|
|
11
|
+
</div>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const api = require('../api');
|
|
4
|
+
const template = require('./export-query-results.html');
|
|
5
|
+
|
|
6
|
+
const appendCSS = require('../appendCSS');
|
|
7
|
+
|
|
8
|
+
appendCSS(require('./export-query-results.css'));
|
|
9
|
+
|
|
10
|
+
module.exports = app => app.component('export-query-results', {
|
|
11
|
+
template: template,
|
|
12
|
+
props: ['schemaPaths', 'filter', 'currentModel'],
|
|
13
|
+
emits: ['done'],
|
|
14
|
+
data: () => ({
|
|
15
|
+
shouldExport: {}
|
|
16
|
+
}),
|
|
17
|
+
mounted() {
|
|
18
|
+
this.shouldExport = {};
|
|
19
|
+
for (const { path } of this.schemaPaths) {
|
|
20
|
+
this.shouldExport[path] = true;
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
methods: {
|
|
24
|
+
async exportQueryResults() {
|
|
25
|
+
await api.Model.exportQueryResults({
|
|
26
|
+
model: this.currentModel,
|
|
27
|
+
filter: this.filter,
|
|
28
|
+
propertiesToInclude: Object.keys(this.shouldExport).filter(key => this.shouldExport[key])
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
this.$emit('done');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const app = Vue.createApp({
|
|
4
|
+
template: '<app-component />'
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
require('./async-button/async-button')(app);
|
|
8
|
+
require('./detail-array/detail-array')(app);
|
|
9
|
+
require('./detail-default/detail-default')(app);
|
|
10
|
+
require('./document/document')(app);
|
|
11
|
+
require('./edit-default/edit-default')(app);
|
|
12
|
+
require('./export-query-results/export-query-results')(app);
|
|
13
|
+
require('./list-array/list-array')(app);
|
|
14
|
+
require('./list-default/list-default')(app);
|
|
15
|
+
require('./list-subdocument/list-subdocument')(app);
|
|
16
|
+
require('./modal/modal')(app);
|
|
17
|
+
require('./models/models')(app);
|
|
18
|
+
require('./navbar/navbar')(app);
|
|
19
|
+
|
|
20
|
+
app.component('app-component', {
|
|
21
|
+
template: `
|
|
22
|
+
<div>
|
|
23
|
+
<navbar />
|
|
24
|
+
<div class="view">
|
|
25
|
+
<router-view :key="$route.fullPath" />
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
`
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const routes = require('./routes');
|
|
32
|
+
const router = VueRouter.createRouter({
|
|
33
|
+
history: VueRouter.createWebHashHistory(),
|
|
34
|
+
routes: routes.map(route => ({
|
|
35
|
+
...route,
|
|
36
|
+
component: app.component(route.component),
|
|
37
|
+
props: (route) => route.params
|
|
38
|
+
}))
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
app.use(router);
|
|
42
|
+
|
|
43
|
+
app.mount('#content');
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const template = require('./list-array.html');
|
|
4
|
+
|
|
5
|
+
require('../appendCSS')(require('./list-array.css'));
|
|
6
|
+
|
|
7
|
+
module.exports = app => app.component('list-array', {
|
|
8
|
+
template: template,
|
|
9
|
+
props: ['value'],
|
|
10
|
+
computed: {
|
|
11
|
+
displayValue() {
|
|
12
|
+
return JSON.stringify(this.value, (key, value) => {
|
|
13
|
+
if (typeof value === 'string' && value.length > 30) {
|
|
14
|
+
return value.slice(0, 27) + '...';
|
|
15
|
+
}
|
|
16
|
+
return value;
|
|
17
|
+
}, ' ').trim();
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
mounted() {
|
|
21
|
+
Prism.highlightElement(this.$refs.code);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const template = require('./list-default.html');
|
|
4
|
+
|
|
5
|
+
module.exports = app => app.component('list-default', {
|
|
6
|
+
template: template,
|
|
7
|
+
props: ['value'],
|
|
8
|
+
computed: {
|
|
9
|
+
displayValue() {
|
|
10
|
+
if (this.value === null) {
|
|
11
|
+
return 'null';
|
|
12
|
+
}
|
|
13
|
+
if (this.value === undefined) {
|
|
14
|
+
return 'undefined';
|
|
15
|
+
}
|
|
16
|
+
return this.value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
});
|