@mongoosejs/studio 0.0.28 → 0.0.30

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 (31) hide show
  1. package/backend/actions/Dashboard/createDashboard.js +22 -0
  2. package/backend/actions/Dashboard/getDashboard.js +41 -8
  3. package/backend/actions/Dashboard/index.js +1 -0
  4. package/backend/db/dashboardSchema.js +4 -1
  5. package/backend/index.js +1 -1
  6. package/frontend/public/app.js +381 -46
  7. package/frontend/public/index.html +1 -0
  8. package/frontend/public/tw.css +323 -0
  9. package/frontend/src/api.js +6 -0
  10. package/frontend/src/create-dashboard/create-dashboard.html +43 -0
  11. package/frontend/src/create-dashboard/create-dashboard.js +40 -0
  12. package/frontend/src/dashboard/dashboard.html +16 -7
  13. package/frontend/src/dashboard/dashboard.js +4 -4
  14. package/frontend/src/dashboard-result/dashboard-chart/dashboard-chart.html +8 -0
  15. package/frontend/src/dashboard-result/dashboard-chart/dashboard-chart.js +20 -0
  16. package/frontend/src/dashboard-result/dashboard-document/dashboard-document.html +8 -0
  17. package/frontend/src/dashboard-result/dashboard-document/dashboard-document.js +29 -0
  18. package/frontend/src/dashboard-result/dashboard-primitive/dashboard-primitive.html +8 -0
  19. package/frontend/src/dashboard-result/dashboard-primitive/dashboard-primitive.js +24 -0
  20. package/frontend/src/dashboard-result/dashboard-result.html +18 -0
  21. package/frontend/src/dashboard-result/dashboard-result.js +30 -0
  22. package/frontend/src/dashboards/dashboards.html +77 -3
  23. package/frontend/src/dashboards/dashboards.js +2 -3
  24. package/frontend/src/document/document.css +0 -16
  25. package/frontend/src/document/document.html +5 -34
  26. package/frontend/src/document/document.js +0 -34
  27. package/frontend/src/document-details/document-details.css +18 -0
  28. package/frontend/src/document-details/document-details.html +36 -0
  29. package/frontend/src/document-details/document-details.js +59 -0
  30. package/frontend/src/index.js +6 -0
  31. package/package.json +1 -1
@@ -0,0 +1,8 @@
1
+ <div class="py-2">
2
+ <div v-if="header" class="border-b border-gray-100 px-2 pb-2 text-xl font-bold">
3
+ {{header}}
4
+ </div>
5
+ <div class="text-xl pb-2">
6
+ <document-details :document="value.$document.document" :schemaPaths="schemaPaths" />
7
+ </div>
8
+ </div>
@@ -0,0 +1,29 @@
1
+
2
+
3
+ 'use strict';
4
+
5
+ const template = require('./dashboard-document.html');
6
+
7
+ module.exports = app => app.component('dashboard-document', {
8
+ template: template,
9
+ props: ['value'],
10
+ computed: {
11
+ header() {
12
+ if (this.value != null && this.value.$document.header) {
13
+ return this.value.$document.header;
14
+ }
15
+ return null;
16
+ },
17
+ schemaPaths() {
18
+ return Object.keys(this.value.$document.schemaPaths).sort((k1, k2) => {
19
+ if (k1 === '_id' && k2 !== '_id') {
20
+ return -1;
21
+ }
22
+ if (k1 !== '_id' && k2 === '_id') {
23
+ return 1;
24
+ }
25
+ return 0;
26
+ }).map(key => this.value.$document.schemaPaths[key]);
27
+ }
28
+ }
29
+ });
@@ -0,0 +1,8 @@
1
+ <div class="py-2">
2
+ <div v-if="header" class="border-b border-gray-100 px-2 pb-2 text-xl font-bold">
3
+ {{header}}
4
+ </div>
5
+ <div class="text-xl p-2">
6
+ {{displayValue}}
7
+ </div>
8
+ </div>
@@ -0,0 +1,24 @@
1
+
2
+
3
+ 'use strict';
4
+
5
+ const template = require('./dashboard-primitive.html');
6
+
7
+ module.exports = app => app.component('dashboard-primitive', {
8
+ template: template,
9
+ props: ['value'],
10
+ computed: {
11
+ header() {
12
+ if (this.value != null && this.value.$primitive.header) {
13
+ return this.value.$primitive.header;
14
+ }
15
+ return null;
16
+ },
17
+ displayValue() {
18
+ if (this.value != null && this.value.$primitive) {
19
+ return this.value.$primitive.value;
20
+ }
21
+ return this.value;
22
+ }
23
+ }
24
+ });
@@ -0,0 +1,18 @@
1
+ <div>
2
+ <div v-if="Array.isArray(result)">
3
+ <div v-for="el in result">
4
+ <component
5
+ class="bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl"
6
+ :is="getComponentForValue(res)"
7
+ :value="res">
8
+ </component>
9
+ </div>
10
+ </div>
11
+ <div v-else>
12
+ <component
13
+ class="bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl"
14
+ :is="getComponentForValue(result)"
15
+ :value="result">
16
+ </component>
17
+ </div>
18
+ </div>
@@ -0,0 +1,30 @@
1
+
2
+
3
+ 'use strict';
4
+
5
+ const api = require('../api');
6
+ const template = require('./dashboard-result.html');
7
+
8
+ module.exports = app => app.component('dashboard-result', {
9
+ template: template,
10
+ props: ['result'],
11
+ mounted: async function() {
12
+ },
13
+ methods: {
14
+ getComponentForValue(value) {
15
+ console.log('X', value);
16
+ if (typeof value !== 'object' || value == null) {
17
+ return 'dashboard-primitive';
18
+ }
19
+ if (value.$primitive) {
20
+ return 'dashboard-primitive';
21
+ }
22
+ if (value.$chart) {
23
+ return 'dashboard-chart';
24
+ }
25
+ if (value.$document) {
26
+ return 'dashboard-document';
27
+ }
28
+ }
29
+ }
30
+ });
@@ -1,5 +1,79 @@
1
- <div class="dashboards">
2
- <div v-for="dashboard in dashboards" :key="dashboard._id" @click="$router.push('dashboard?dashboardId=' + dashboard._id)">
3
- {{dashboard.name}}, ID: {{ dashboard._id }}
1
+ <div class="dashboards max-w-5xl mx-auto mt-8">
2
+ <div v-if="status === 'loaded' && dashboards.length === 0">
3
+ <div class="text-center">
4
+ <h3 class="mt-2 text-sm font-semibold text-gray-900">No dashboards yet</h3>
5
+ <p class="mt-1 text-sm text-gray-500">Get started by creating a new dashboard.</p>
6
+ <div class="mt-6">
7
+ <button type="button" class="inline-flex items-center rounded-md bg-teal-600 px-3 py-2 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">
8
+ <svg class="-ml-0.5 mr-1.5 h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
9
+ <path d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z" />
10
+ </svg>
11
+ New Dashboard
12
+ </button>
13
+ </div>
14
+ </div>
4
15
  </div>
16
+
17
+
18
+ <div class="px-4 sm:px-6 lg:px-8">
19
+ <div class="sm:flex sm:items-center">
20
+ <div class="sm:flex-auto">
21
+ <h1 class="text-base font-semibold leading-6 text-gray-900">Dashboards</h1>
22
+ </div>
23
+ <div class="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
24
+ <button
25
+ type="button"
26
+ @click="showCreateDashboardModal = true"
27
+ class="block rounded-md bg-teal-600 px-3 py-2 text-center 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">Create New Dashboard</button>
28
+ </div>
29
+ </div>
30
+ <div class="mt-8 flow-root">
31
+ <div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
32
+ <div class="inline-block min-w-full py-2 align-middle">
33
+ <table class="min-w-full divide-y divide-gray-300">
34
+ <thead>
35
+ <tr>
36
+ <th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg:pl-8">Title</th>
37
+ <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 w-[50%]">Description</th>
38
+ <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8">
39
+ </th>
40
+ <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8">
41
+ </th>
42
+ </tr>
43
+ </thead>
44
+ <tbody class="divide-y divide-gray-200 bg-white">
45
+ <tr v-for="dashboard in dashboards">
46
+ <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8">{{dashboard.title}}</td>
47
+ <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500 truncate w-[50%]">{{dashboard.description}}</td>
48
+ <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8">
49
+ <router-link
50
+ :to="'dashboard?edit=true&dashboardId=' + dashboard._id"
51
+ class="text-teal-600 hover:text-teal-900">
52
+ Edit
53
+ </router-link>
54
+ </td>
55
+ <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8">
56
+ <router-link
57
+ :to="'dashboard?edit=true&dashboardId=' + dashboard._id"
58
+ class="text-teal-600 hover:text-teal-900">
59
+ View
60
+ </router-link>
61
+ </td>
62
+ </tr>
63
+
64
+ <!-- More people... -->
65
+ </tbody>
66
+ </table>
67
+ </div>
68
+ </div>
69
+ </div>
70
+ </div>
71
+
72
+ <modal v-if="showCreateDashboardModal">
73
+ <template v-slot:body>
74
+ <div class="modal-exit" @click="showCreateDashboardModal = false;">&times;</div>
75
+
76
+ <create-dashboard></create-dashboard>
77
+ </template>
78
+ </modal>
5
79
  </div>
@@ -7,14 +7,13 @@ const template = require('./dashboards.html');
7
7
  module.exports = app => app.component('dashboards', {
8
8
  template: template,
9
9
  data: () => ({
10
+ status: 'loading',
10
11
  dashboards: [],
12
+ showCreateDashboardModal: false
11
13
  }),
12
14
  async mounted() {
13
15
  const { dashboards } = await api.Dashboard.getDashboards();
14
16
  this.dashboards = dashboards;
15
- if (!this.$route.query.dashboardId) {
16
- return;
17
- }
18
17
  this.status = 'loaded';
19
18
  },
20
19
  });
@@ -5,22 +5,6 @@
5
5
  padding-top: 25px;
6
6
  }
7
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
8
  .document .document-menu {
25
9
  display: flex;
26
10
  }
@@ -37,40 +37,11 @@
37
37
  </div>
38
38
  </div>
39
39
  <div v-if="status === 'loaded'">
40
- <div v-for="path in schemaPaths" class="value">
41
- <div class="path-key">
42
- {{path.path}}
43
- <span class="path-type">
44
- ({{(path.instance || 'unknown').toLowerCase()}})
45
- </span>
46
- </div>
47
- <div v-if="editting && path.path !== '_id'">
48
- <component
49
- :is="getEditComponentForPath(path)"
50
- :value="getEditValueForPath(path)"
51
- @input="changes[path.path] = $event; delete invalid[path.path];"
52
- @error="invalid[path.path] = $event;"
53
- >
54
- </component>
55
- </div>
56
- <div v-else>
57
- <component :is="getComponentForPath(path)" :value="getValueForPath(path.path)"></component>
58
- </div>
59
- </div>
60
- <div v-for="path in virtuals" class="mb-2">
61
- <div class="p-1 mb-1 bg-slate-100">
62
- {{path.name}}
63
- <span class="path-type">
64
- (virtual)
65
- </span>
66
- </div>
67
- <div v-if="path.value == null" class="text-sky-800">
68
- {{'' + path.value}}
69
- </div>
70
- <div v-else>
71
- {{path.value}}
72
- </div>
73
- </div>
40
+ <document-details
41
+ :document="document"
42
+ :schemaPaths="schemaPaths"
43
+ :editting="editting"
44
+ :changes="changes"></document-details>
74
45
  <modal v-if="shouldShowConfirmModal">
75
46
  <template v-slot:body>
76
47
  <div class="modal-exit" @click="shouldShowConfirmModal = false;">&times;</div>
@@ -36,43 +36,9 @@ module.exports = app => app.component('document', {
36
36
  }
37
37
  return 0;
38
38
  }).map(key => schemaPaths[key]);
39
- this.getVirtuals();
40
39
  this.status = 'loaded';
41
40
  },
42
41
  methods: {
43
- getComponentForPath(schemaPath) {
44
- if (schemaPath.instance === 'Array') {
45
- return 'detail-array';
46
- }
47
- return 'detail-default';
48
- },
49
- getEditComponentForPath(path) {
50
- if (path.instance == 'Date') {
51
- return 'edit-date';
52
- }
53
- if (path.instance == 'Number') {
54
- return 'edit-number';
55
- }
56
- if (path.instance === 'Array') {
57
- return 'edit-array';
58
- }
59
- return 'edit-default';
60
- },
61
- getValueForPath(path) {
62
- return mpath.get(path, this.document);
63
- },
64
- getEditValueForPath({ path }) {
65
- return path in this.changes ? this.changes[path] : mpath.get(path, this.document);
66
- },
67
- getVirtuals() {
68
- const exists = this.schemaPaths.map(x => x.path);
69
- const docKeys = Object.keys(this.document);
70
- for (let i = 0; i < docKeys.length; i++) {
71
- if (!exists.includes(docKeys[i])) {
72
- this.virtuals.push({ name: docKeys[i], value: this.document[docKeys[i]] });
73
- }
74
- }
75
- },
76
42
  cancelEdit() {
77
43
  this.changes = {};
78
44
  this.editting = false;
@@ -0,0 +1,18 @@
1
+ .document-details {
2
+ width: 100%;
3
+ }
4
+
5
+ .document-details .value {
6
+ padding-top: 10px;
7
+ padding-bottom: 10px;
8
+ }
9
+
10
+ .document-details .path-key {
11
+ background-color: #f0f0f0;
12
+ margin-bottom: 0.5em;
13
+ }
14
+
15
+ .document-details .path-type {
16
+ color: rgba(0,0,0,.36);
17
+ font-size: 0.8em;
18
+ }
@@ -0,0 +1,36 @@
1
+ <div class="document-details">
2
+ <div v-for="path in schemaPaths" class="value">
3
+ <div class="path-key p-1">
4
+ {{path.path}}
5
+ <span class="path-type">
6
+ ({{(path.instance || 'unknown').toLowerCase()}})
7
+ </span>
8
+ </div>
9
+ <div v-if="editting && path.path !== '_id'" class="pl-1">
10
+ <component
11
+ :is="getEditComponentForPath(path)"
12
+ :value="getEditValueForPath(path)"
13
+ @input="changes[path.path] = $event; delete invalid[path.path];"
14
+ @error="invalid[path.path] = $event;"
15
+ >
16
+ </component>
17
+ </div>
18
+ <div v-else class="pl-1">
19
+ <component :is="getComponentForPath(path)" :value="getValueForPath(path.path)"></component>
20
+ </div>
21
+ </div>
22
+ <div v-for="path in virtuals" class="mb-2">
23
+ <div class="p-1 mb-1 bg-slate-100">
24
+ {{path.name}}
25
+ <span class="path-type">
26
+ (virtual)
27
+ </span>
28
+ </div>
29
+ <div v-if="path.value == null" class="text-sky-800">
30
+ {{'' + path.value}}
31
+ </div>
32
+ <div v-else>
33
+ {{path.value}}
34
+ </div>
35
+ </div>
36
+ </div>
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ const mpath = require('mpath');
4
+ const template = require('./document-details.html')
5
+
6
+ const appendCSS = require('../appendCSS');
7
+
8
+ appendCSS(require('./document-details.css'));
9
+
10
+ module.exports = app => app.component('document-details', {
11
+ template,
12
+ props: ['document', 'schemaPaths', 'editting', 'changes'],
13
+ methods: {
14
+ getComponentForPath(schemaPath) {
15
+ if (schemaPath.instance === 'Array') {
16
+ return 'detail-array';
17
+ }
18
+ return 'detail-default';
19
+ },
20
+ getEditComponentForPath(path) {
21
+ if (path.instance == 'Date') {
22
+ return 'edit-date';
23
+ }
24
+ if (path.instance == 'Number') {
25
+ return 'edit-number';
26
+ }
27
+ if (path.instance === 'Array') {
28
+ return 'edit-array';
29
+ }
30
+ return 'edit-default';
31
+ },
32
+ getValueForPath(path) {
33
+ return mpath.get(path, this.document);
34
+ },
35
+ getEditValueForPath({ path }) {
36
+ if (!this.changes) {
37
+ return;
38
+ }
39
+ return path in this.changes ? this.changes[path] : mpath.get(path, this.document);
40
+ }
41
+ },
42
+ computed: {
43
+ virtuals() {
44
+ if (this.schemaPaths == null) {
45
+ return [];
46
+ }
47
+ const exists = this.schemaPaths.map(x => x.path);
48
+ const docKeys = Object.keys(this.document);
49
+ const result = [];
50
+ for (let i = 0; i < docKeys.length; i++) {
51
+ if (!exists.includes(docKeys[i])) {
52
+ result.push({ name: docKeys[i], value: this.document[docKeys[i]] });
53
+ }
54
+ }
55
+
56
+ return result;
57
+ }
58
+ }
59
+ })
@@ -12,14 +12,20 @@ const app = Vue.createApp({
12
12
 
13
13
  require('./async-button/async-button')(app);
14
14
  require('./charts/charts')(app);
15
+ require('./create-dashboard/create-dashboard')(app);
15
16
  require('./create-document/create-document')(app);
16
17
  require('./dashboards/dashboards')(app);
17
18
  require('./dashboard/dashboard')(app);
19
+ require('./dashboard-result/dashboard-result')(app);
20
+ require('./dashboard-result/dashboard-chart/dashboard-chart')(app);
21
+ require('./dashboard-result/dashboard-document/dashboard-document')(app);
22
+ require('./dashboard-result/dashboard-primitive/dashboard-primitive')(app);
18
23
  require('./dashboard/edit-dashboard/edit-dashboard')(app)
19
24
  require('./detail-array/detail-array')(app);
20
25
  require('./detail-default/detail-default')(app);
21
26
  require('./document/document')(app);
22
27
  require('./document/confirm-changes/confirm-changes')(app);
28
+ require('./document-details/document-details')(app);
23
29
  require('./edit-array/edit-array')(app);
24
30
  require('./edit-default/edit-default')(app);
25
31
  require('./edit-number/edit-number')(app);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mongoosejs/studio",
3
- "version": "0.0.28",
3
+ "version": "0.0.30",
4
4
  "dependencies": {
5
5
  "archetype": "0.13.0",
6
6
  "csv-stringify": "6.3.0",