@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.
Files changed (54) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +2 -0
  3. package/backend/actions/Model/exportQueryResults.js +66 -0
  4. package/backend/actions/Model/getDocument.js +30 -0
  5. package/backend/actions/Model/getDocuments.js +47 -0
  6. package/backend/actions/Model/index.js +7 -0
  7. package/backend/actions/Model/listModels.js +5 -0
  8. package/backend/actions/Model/updateDocument.js +32 -0
  9. package/backend/actions/index.js +3 -0
  10. package/backend/index.js +12 -0
  11. package/backend/netlify.js +28 -0
  12. package/express.js +36 -0
  13. package/frontend/index.js +36 -0
  14. package/frontend/public/app.js +4012 -0
  15. package/frontend/public/images/mongoose.svg +35 -0
  16. package/frontend/public/index.html +21 -0
  17. package/frontend/public/style.css +34 -0
  18. package/frontend/src/api.js +52 -0
  19. package/frontend/src/appendCSS.js +11 -0
  20. package/frontend/src/async-button/async-button.html +3 -0
  21. package/frontend/src/async-button/async-button.js +39 -0
  22. package/frontend/src/detail-array/detail-array.html +3 -0
  23. package/frontend/src/detail-array/detail-array.js +16 -0
  24. package/frontend/src/detail-default/detail-default.html +3 -0
  25. package/frontend/src/detail-default/detail-default.js +19 -0
  26. package/frontend/src/document/document.css +39 -0
  27. package/frontend/src/document/document.html +42 -0
  28. package/frontend/src/document/document.js +63 -0
  29. package/frontend/src/edit-default/edit-default.html +3 -0
  30. package/frontend/src/edit-default/edit-default.js +20 -0
  31. package/frontend/src/export-query-results/export-query-results.css +0 -0
  32. package/frontend/src/export-query-results/export-query-results.html +11 -0
  33. package/frontend/src/export-query-results/export-query-results.js +34 -0
  34. package/frontend/src/index.js +43 -0
  35. package/frontend/src/list-array/list-array.css +8 -0
  36. package/frontend/src/list-array/list-array.html +3 -0
  37. package/frontend/src/list-array/list-array.js +23 -0
  38. package/frontend/src/list-default/list-default.html +3 -0
  39. package/frontend/src/list-default/list-default.js +19 -0
  40. package/frontend/src/list-subdocument/list-subdocument.html +3 -0
  41. package/frontend/src/list-subdocument/list-subdocument.js +9 -0
  42. package/frontend/src/modal/modal.css +75 -0
  43. package/frontend/src/modal/modal.html +12 -0
  44. package/frontend/src/modal/modal.js +10 -0
  45. package/frontend/src/models/models.css +108 -0
  46. package/frontend/src/models/models.html +53 -0
  47. package/frontend/src/models/models.js +107 -0
  48. package/frontend/src/navbar/navbar.css +162 -0
  49. package/frontend/src/navbar/navbar.html +10 -0
  50. package/frontend/src/navbar/navbar.js +11 -0
  51. package/frontend/src/routes.js +19 -0
  52. package/frontend/webpack.config.js +36 -0
  53. package/package.json +21 -0
  54. 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,3 @@
1
+ <button v-bind="attrsToBind" :disabled="isDisabled" @click="handleClick">
2
+ <slot></slot>
3
+ </button>
@@ -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,3 @@
1
+ <div class="detail-array">
2
+ <pre><code ref="code" class="language-javascript" v-text="displayValue"></code></pre>
3
+ </div>
@@ -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,3 @@
1
+ <div>
2
+ {{value}}
3
+ </div>
@@ -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
+ &lsaquo; Back
6
+ </button>
7
+ </div>
8
+
9
+ <div class="right">
10
+ <button v-if="!editting" @click="editting = true">
11
+ &#x270E; Edit
12
+ </button>
13
+ <button v-if="editting" class="grey" @click="editting = false">
14
+ &times; Cancel
15
+ </button>
16
+ <button v-if="editting" class="green" @click="save">
17
+ &check; 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,3 @@
1
+ <div>
2
+ <input type="text" :value="value" @input="$emit('input', $event.target.value)">
3
+ </div>
@@ -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
+ });
@@ -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,8 @@
1
+ .list-array pre {
2
+ max-height: 6.5em;
3
+ max-width: 60em;
4
+ }
5
+
6
+ .list-array pre.maximized {
7
+ max-height: auto;
8
+ }
@@ -0,0 +1,3 @@
1
+ <div class="list-array">
2
+ <pre><code ref="code" class="language-javascript" v-text="displayValue"></code></pre>
3
+ </div>
@@ -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,3 @@
1
+ <div>
2
+ {{value}}
3
+ </div>
@@ -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
+ });
@@ -0,0 +1,3 @@
1
+ <div>
2
+ {{JSON.stringify(value, null, ' ')}}
3
+ </div>
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ const api = require('../api');
4
+ const template = require('./list-subdocument.html');
5
+
6
+ module.exports = app => app.component('list-subdocument', {
7
+ template: template,
8
+ props: ['value']
9
+ });