@mongoosejs/studio 0.0.15 → 0.0.17
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/Model/getDocuments.js +1 -1
- package/frontend/index.js +7 -0
- package/frontend/public/images/failure.jpg +0 -0
- package/frontend/public/index.html +1 -0
- package/frontend/public/style.css +4 -0
- package/frontend/src/document/document.html +22 -7
- package/frontend/src/index.js +11 -1
- package/frontend/src/models/models.html +12 -2
- package/frontend/src/models/models.js +55 -17
- package/package.json +7 -1
- package/tailwind.config.js +29 -0
package/frontend/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { execSync, exec } = require('child_process');
|
|
3
4
|
const webpack = require('webpack');
|
|
4
5
|
|
|
5
6
|
module.exports = function(apiUrl, isLambda, options) {
|
|
@@ -27,7 +28,13 @@ module.exports = function(apiUrl, isLambda, options) {
|
|
|
27
28
|
}
|
|
28
29
|
console.log('Webpack compiled successfully');
|
|
29
30
|
});
|
|
31
|
+
|
|
32
|
+
const childProcess = exec('npm run tailwind:watch');
|
|
33
|
+
childProcess.stdout.on('data', data => console.log('[TAILWIND]', data));
|
|
34
|
+
childProcess.stderr.on('data', data => console.log('[TAILWIND]', data));
|
|
30
35
|
} else {
|
|
36
|
+
execSync('npm run tailwind');
|
|
37
|
+
|
|
31
38
|
return new Promise((resolve, reject) => {
|
|
32
39
|
compiler.run((err) => {
|
|
33
40
|
if (err) {
|
|
Binary file
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans"/>
|
|
9
9
|
<link rel="stylesheet" type="text/css" href="style.css"/>
|
|
10
10
|
<link rel="stylesheet" href="https://unpkg.com/prismjs@1.29.0/themes/prism.css"/>
|
|
11
|
+
<link rel="stylesheet" href="tw.css">
|
|
11
12
|
<link rel="stylesheet" href="vanillatoasts/vanillatoasts.css">
|
|
12
13
|
<script src="https://unpkg.com/vue@3.x"></script>
|
|
13
14
|
<script src="https://unpkg.com/vue-router@4.0.10"></script>
|
|
@@ -7,17 +7,32 @@
|
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
9
|
<div class="right">
|
|
10
|
-
<button
|
|
11
|
-
|
|
10
|
+
<button
|
|
11
|
+
v-if="!editting"
|
|
12
|
+
@click="editting = true"
|
|
13
|
+
type="button"
|
|
14
|
+
class="rounded-md bg-puerto-rico-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-puerto-rico-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-puerto-rico-600">
|
|
15
|
+
<img src="images/edit.svg" class="inline" /> Edit
|
|
12
16
|
</button>
|
|
13
|
-
<button
|
|
17
|
+
<button
|
|
18
|
+
v-if="editting"
|
|
19
|
+
@click="save"
|
|
20
|
+
type="button"
|
|
21
|
+
class="rounded-md bg-slate-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-slate-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-slate-600">
|
|
14
22
|
× Cancel
|
|
15
23
|
</button>
|
|
16
|
-
<button
|
|
17
|
-
|
|
24
|
+
<button
|
|
25
|
+
v-if="editting"
|
|
26
|
+
@click="save"
|
|
27
|
+
type="button"
|
|
28
|
+
class="rounded-md bg-green-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-green-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600">
|
|
29
|
+
<img src="images/save.svg" class="inline" /> Save
|
|
18
30
|
</button>
|
|
19
|
-
<button
|
|
20
|
-
|
|
31
|
+
<button
|
|
32
|
+
@click="remove"
|
|
33
|
+
type="button"
|
|
34
|
+
class="rounded-md bg-red-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600">
|
|
35
|
+
<img src="images/delete.svg" class="inline" /> Delete
|
|
21
36
|
</button>
|
|
22
37
|
</div>
|
|
23
38
|
</div>
|
package/frontend/src/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const vanillatoasts = require('vanillatoasts');
|
|
4
|
+
|
|
3
5
|
const app = Vue.createApp({
|
|
4
6
|
template: '<app-component />'
|
|
5
7
|
});
|
|
@@ -31,7 +33,15 @@ app.component('app-component', {
|
|
|
31
33
|
<router-view :key="$route.fullPath" />
|
|
32
34
|
</div>
|
|
33
35
|
</div>
|
|
34
|
-
|
|
36
|
+
`,
|
|
37
|
+
errorCaptured(err) {
|
|
38
|
+
vanillatoasts.create({
|
|
39
|
+
title: `Error: ${err.message}`,
|
|
40
|
+
icon: 'images/failure.jpg',
|
|
41
|
+
timeout: 10000,
|
|
42
|
+
positionClass: 'bottomRight'
|
|
43
|
+
});
|
|
44
|
+
}
|
|
35
45
|
});
|
|
36
46
|
|
|
37
47
|
const routes = require('./routes');
|
|
@@ -18,8 +18,18 @@
|
|
|
18
18
|
|
|
19
19
|
</div>
|
|
20
20
|
<div class="buttons">
|
|
21
|
-
<button
|
|
22
|
-
|
|
21
|
+
<button
|
|
22
|
+
@click="shouldShowExportModal = true"
|
|
23
|
+
type="button"
|
|
24
|
+
class="rounded bg-puerto-rico-600 px-2 py-1 text-sm font-semibold text-white shadow-sm hover:bg-puerto-rico-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-puerto-rico-600">
|
|
25
|
+
Export
|
|
26
|
+
</button>
|
|
27
|
+
<button
|
|
28
|
+
@click="shouldShowFieldModal = true"
|
|
29
|
+
type="button"
|
|
30
|
+
class="rounded bg-puerto-rico-600 px-2 py-1 text-sm font-semibold text-white shadow-sm hover:bg-puerto-rico-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-puerto-rico-600">
|
|
31
|
+
Fields
|
|
32
|
+
</button>
|
|
23
33
|
</div>
|
|
24
34
|
</div>
|
|
25
35
|
</div>
|
|
@@ -2,8 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
const api = require('../api');
|
|
4
4
|
const template = require('./models.html');
|
|
5
|
-
const EJSON = require('ejson');
|
|
6
5
|
const mpath = require('mpath');
|
|
6
|
+
const { BSON, EJSON } = require('bson');
|
|
7
|
+
|
|
8
|
+
const ObjectId = new Proxy(BSON.ObjectId, {
|
|
9
|
+
apply (target, thisArg, argumentsList) {
|
|
10
|
+
return new target(...argumentsList);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
7
13
|
|
|
8
14
|
const appendCSS = require('../appendCSS');
|
|
9
15
|
|
|
@@ -48,6 +54,7 @@ module.exports = app => app.component('models', {
|
|
|
48
54
|
if (this.currentModel == null && this.models.length > 0) {
|
|
49
55
|
this.currentModel = this.models[0];
|
|
50
56
|
}
|
|
57
|
+
|
|
51
58
|
this.query = Object.assign({}, this.$route.query); // important that this is here before the if statements
|
|
52
59
|
if (this.$route.query?.search) {
|
|
53
60
|
this.searchText = this.$route.query.search;
|
|
@@ -64,20 +71,28 @@ module.exports = app => app.component('models', {
|
|
|
64
71
|
if (this.currentModel != null) {
|
|
65
72
|
await this.getDocuments();
|
|
66
73
|
}
|
|
67
|
-
|
|
68
|
-
const hashUrl = window.location.hash.replace(/^#/, '');
|
|
69
|
-
if (hashUrl.indexOf('?') !== -1) {
|
|
70
|
-
const searchParams = new URLSearchParams(
|
|
71
|
-
hashUrl.slice(hashUrl.indexOf('?') + 1)
|
|
72
|
-
);
|
|
73
|
-
if (searchParams.has('fields')) {
|
|
74
|
-
this.filteredPaths = searchParams.get('fields').split(',').map(path => ({ path }));
|
|
75
|
-
}
|
|
76
|
-
}
|
|
74
|
+
this.applyQueryParams();
|
|
77
75
|
|
|
78
76
|
this.status = 'loaded';
|
|
79
77
|
},
|
|
80
78
|
methods: {
|
|
79
|
+
applyQueryParams() {
|
|
80
|
+
const hashUrl = window.location.hash.replace(/^#/, '');
|
|
81
|
+
if (hashUrl.indexOf('?') !== -1) {
|
|
82
|
+
const searchParams = new URLSearchParams(
|
|
83
|
+
hashUrl.slice(hashUrl.indexOf('?') + 1)
|
|
84
|
+
);
|
|
85
|
+
if (searchParams.has('fields')) {
|
|
86
|
+
const filter = searchParams.get('fields').split(',');
|
|
87
|
+
this.filteredPaths = this.filteredPaths.filter(x => filter.includes(x.path))
|
|
88
|
+
}
|
|
89
|
+
if (searchParams.has('search')) {
|
|
90
|
+
this.searchText = searchParams.get('search');
|
|
91
|
+
this.filter = eval(`(${this.searchText})`);
|
|
92
|
+
this.filter = EJSON.stringify(this.filter);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
81
96
|
async onScroll() {
|
|
82
97
|
if (this.status === 'loading' || this.loadedAllDocs) {
|
|
83
98
|
return;
|
|
@@ -114,20 +129,31 @@ module.exports = app => app.component('models', {
|
|
|
114
129
|
this.query.sort = `{${path}:${num}}`
|
|
115
130
|
this.$router.push({ query: this.query });
|
|
116
131
|
}
|
|
117
|
-
await this.
|
|
132
|
+
await this.loadMoreDocuments();
|
|
118
133
|
},
|
|
119
134
|
async search() {
|
|
120
135
|
if (this.searchText && Object.keys(this.searchText).length) {
|
|
121
136
|
this.filter = eval(`(${this.searchText})`);
|
|
122
137
|
this.filter = EJSON.stringify(this.filter);
|
|
123
138
|
this.query.search = this.searchText;
|
|
124
|
-
this.$router.push({ path: this.$route.path, query: this.query })
|
|
125
139
|
} else {
|
|
126
140
|
this.filter = {};
|
|
127
141
|
delete this.query.search;
|
|
128
|
-
this.$router.push({ path: this.$route.path, query: this.query });
|
|
129
142
|
}
|
|
130
|
-
|
|
143
|
+
|
|
144
|
+
const hashUrl = window.location.hash.replace(/^#/, '');
|
|
145
|
+
if (hashUrl.indexOf('?') === -1) {
|
|
146
|
+
window.history.pushState({}, '', window.location.pathname + '#' + hashUrl + '?search=' + this.query.search);
|
|
147
|
+
} else {
|
|
148
|
+
const searchParams = new URLSearchParams(
|
|
149
|
+
hashUrl.indexOf('?') === -1 ? '' : hashUrl.slice(hashUrl.indexOf('?') + 1)
|
|
150
|
+
);
|
|
151
|
+
const hashUrlWithoutSearchParams = hashUrl.slice(0, hashUrl.indexOf('?'));
|
|
152
|
+
|
|
153
|
+
searchParams.set('search', this.query.search);
|
|
154
|
+
window.history.pushState({}, '', window.location.pathname + '#' + hashUrlWithoutSearchParams + '?' + searchParams);
|
|
155
|
+
}
|
|
156
|
+
await this.loadMoreDocuments();
|
|
131
157
|
},
|
|
132
158
|
async getDocuments() {
|
|
133
159
|
const { docs, schemaPaths, numDocs } = await api.Model.getDocuments({
|
|
@@ -159,6 +185,18 @@ module.exports = app => app.component('models', {
|
|
|
159
185
|
this.filteredPaths = [...this.schemaPaths];
|
|
160
186
|
this.selectedPaths = [...this.schemaPaths];
|
|
161
187
|
},
|
|
188
|
+
async loadMoreDocuments() {
|
|
189
|
+
const { docs } = await api.Model.getDocuments({
|
|
190
|
+
model: this.currentModel,
|
|
191
|
+
filter: this.filter,
|
|
192
|
+
sort: this.sortBy,
|
|
193
|
+
limit
|
|
194
|
+
});
|
|
195
|
+
this.documents = docs;
|
|
196
|
+
if (docs.length < limit) {
|
|
197
|
+
this.loadedAllDocs = true;
|
|
198
|
+
}
|
|
199
|
+
},
|
|
162
200
|
addOrRemove(path) {
|
|
163
201
|
const exists = this.selectedPaths.findIndex(x => x.path == path.path);
|
|
164
202
|
if (exists > 0) { // remove
|
|
@@ -180,7 +218,7 @@ module.exports = app => app.component('models', {
|
|
|
180
218
|
this.filteredPaths = [...this.selectedPaths];
|
|
181
219
|
this.shouldShowFieldModal = false;
|
|
182
220
|
const selectedParams = this.filteredPaths.map(x => x.path).join(',');
|
|
183
|
-
|
|
221
|
+
// sets the query params
|
|
184
222
|
const hashUrl = window.location.hash.replace(/^#/, '');
|
|
185
223
|
if (hashUrl.indexOf('?') === -1) {
|
|
186
224
|
window.history.pushState({}, '', window.location.pathname + '#' + hashUrl + '?fields=' + selectedParams);
|
|
@@ -240,4 +278,4 @@ module.exports = app => app.component('models', {
|
|
|
240
278
|
this.edittingDoc = null;
|
|
241
279
|
}
|
|
242
280
|
}
|
|
243
|
-
});
|
|
281
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mongoosejs/studio",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"archetype": "0.13.0",
|
|
6
6
|
"csv-stringify": "6.3.0",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"vanillatoasts": "^1.6.0"
|
|
11
11
|
},
|
|
12
12
|
"peerDependencies": {
|
|
13
|
+
"bson": "^5.5.1",
|
|
13
14
|
"express": "4.x",
|
|
14
15
|
"mongoose": "7.x || 8.0.0-rc0 || 8.x"
|
|
15
16
|
},
|
|
@@ -18,7 +19,12 @@
|
|
|
18
19
|
"express": "4.x",
|
|
19
20
|
"mocha": "10.2.0",
|
|
20
21
|
"mongoose": "7.x",
|
|
22
|
+
"tailwindcss": "3.4.0",
|
|
21
23
|
"vue": "3.x",
|
|
22
24
|
"webpack": "5.75.0"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"tailwind": "tailwindcss -o ./frontend/public/tw.css",
|
|
28
|
+
"tailwind:watch": "tailwindcss -o ./frontend/public/tw.css --watch"
|
|
23
29
|
}
|
|
24
30
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
mode: 'jit',
|
|
5
|
+
content: ['./frontend/src/**/*.html', './frontend/src/**/*.js'],
|
|
6
|
+
corePlugins: {
|
|
7
|
+
container: true
|
|
8
|
+
},
|
|
9
|
+
plugins: [],
|
|
10
|
+
theme: {
|
|
11
|
+
extend: {
|
|
12
|
+
colors: {
|
|
13
|
+
'puerto-rico': {
|
|
14
|
+
'50': '#eefffb',
|
|
15
|
+
'100': '#c6fff3',
|
|
16
|
+
'200': '#8effe8',
|
|
17
|
+
'300': '#4dfbdb',
|
|
18
|
+
'400': '#15d4b7',
|
|
19
|
+
'500': '#00ccb0',
|
|
20
|
+
'600': '#00a491',
|
|
21
|
+
'700': '#038276',
|
|
22
|
+
'800': '#08675f',
|
|
23
|
+
'900': '#0c554e',
|
|
24
|
+
'950': '#003432',
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|