@mongoosejs/studio 0.0.50 → 0.0.51
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/netlify.js +24 -3
- package/express.js +63 -3
- package/frontend/index.js +37 -4
- package/frontend/public/app.js +182 -19
- package/frontend/public/index.html +1 -1
- package/frontend/public/style.css +3 -26
- package/frontend/public/tw.css +145 -24
- package/frontend/src/api.js +7 -9
- package/frontend/src/create-document/create-document.html +2 -2
- package/frontend/src/document/document.html +6 -4
- package/frontend/src/index.js +33 -3
- package/frontend/src/modal/modal.css +10 -1
- package/frontend/src/models/models.css +9 -8
- package/frontend/src/models/models.html +7 -7
- package/frontend/src/mothership.js +31 -0
- package/frontend/src/navbar/navbar.html +26 -2
- package/frontend/src/navbar/navbar.js +38 -1
- package/frontend/src/splash/splash.html +35 -0
- package/frontend/src/splash/splash.js +34 -0
- package/package.json +1 -1
- package/tailwind.config.js +40 -14
package/backend/netlify.js
CHANGED
|
@@ -3,11 +3,32 @@
|
|
|
3
3
|
const Backend = require('./');
|
|
4
4
|
const { toNetlifyFunction } = require('extrovert');
|
|
5
5
|
|
|
6
|
-
module.exports = function netlify() {
|
|
6
|
+
module.exports = function netlify(options) {
|
|
7
7
|
const backend = Backend();
|
|
8
8
|
|
|
9
|
-
return toNetlifyFunction(function wrappedNetlifyFunction(params) {
|
|
9
|
+
return toNetlifyFunction(async function wrappedNetlifyFunction(params) {
|
|
10
10
|
const actionName = params?.action;
|
|
11
|
+
const authorization = params?.authorization;
|
|
12
|
+
if (options?.apiKey) {
|
|
13
|
+
if (!authorization) {
|
|
14
|
+
throw new Error('Not authorized');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const { user, roles } = await fetch(`${mothershipUrl}/me`, params)
|
|
18
|
+
.then(response => {
|
|
19
|
+
if (response.status < 200 || response.status >= 400) {
|
|
20
|
+
return response.json().then(data => {
|
|
21
|
+
throw new Error(`Mongoose Studio API Key Error ${response.status}: ${require('util').inspect(data)}`);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return response;
|
|
25
|
+
})
|
|
26
|
+
.then(res => res.json());
|
|
27
|
+
if (!user || !roles) {
|
|
28
|
+
throw new Error('Not authorized');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
11
32
|
if (typeof actionName !== 'string') {
|
|
12
33
|
throw new Error('No action specified');
|
|
13
34
|
}
|
|
@@ -25,4 +46,4 @@ module.exports = function netlify() {
|
|
|
25
46
|
|
|
26
47
|
return actionFn(params);
|
|
27
48
|
});
|
|
28
|
-
}
|
|
49
|
+
}
|
package/express.js
CHANGED
|
@@ -5,15 +5,75 @@ const express = require('express');
|
|
|
5
5
|
const frontend = require('./frontend');
|
|
6
6
|
const { toRoute, objectRouter } = require('extrovert');
|
|
7
7
|
|
|
8
|
-
module.exports = function(apiUrl, conn, options) {
|
|
8
|
+
module.exports = async function(apiUrl, conn, options) {
|
|
9
9
|
const router = express.Router();
|
|
10
10
|
|
|
11
|
+
const mothershipUrl = options?._mothershipUrl || 'https://mongoose-js.netlify.app/.netlify/functions';
|
|
12
|
+
let workspace = null;
|
|
13
|
+
if (options?.apiKey) {
|
|
14
|
+
({ workspace } = await fetch(`${mothershipUrl}/getWorkspace`, {
|
|
15
|
+
method: 'POST',
|
|
16
|
+
body: JSON.stringify({ apiKey: options.apiKey }),
|
|
17
|
+
headers: {
|
|
18
|
+
'Authorization': `Bearer ${options.apiKey}`,
|
|
19
|
+
'Content-Type': 'application/json'
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
.then(response => {
|
|
23
|
+
if (response.status < 200 || response.status >= 400) {
|
|
24
|
+
return response.json().then(data => {
|
|
25
|
+
throw new Error(`Mongoose Studio API Key Error ${response.status}: ${require('util').inspect(data)}`);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return response;
|
|
29
|
+
})
|
|
30
|
+
.then(res => res.json()));
|
|
31
|
+
}
|
|
32
|
+
|
|
11
33
|
apiUrl = apiUrl || '/admin/api';
|
|
12
34
|
const backend = Backend(conn);
|
|
13
35
|
|
|
14
|
-
router.use(
|
|
36
|
+
router.use(
|
|
37
|
+
'/api',
|
|
38
|
+
function authorize(req, res, next) {
|
|
39
|
+
if (!workspace) {
|
|
40
|
+
next();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const authorization = req.headers.authorization;
|
|
44
|
+
const params = {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
body: JSON.stringify({ workspaceId: workspace._id }),
|
|
47
|
+
headers: {
|
|
48
|
+
'Authorization': authorization,
|
|
49
|
+
'Content-Type': 'application/json'
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
fetch(`${mothershipUrl}/me`, params)
|
|
53
|
+
.then(response => {
|
|
54
|
+
if (response.status < 200 || response.status >= 400) {
|
|
55
|
+
return response.json().then(data => {
|
|
56
|
+
throw new Error(`Mongoose Studio API Key Error ${response.status}: ${require('util').inspect(data)}`);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return response;
|
|
60
|
+
})
|
|
61
|
+
.then(res => res.json())
|
|
62
|
+
.then(({ user, roles }) => {
|
|
63
|
+
if (!user || !roles) {
|
|
64
|
+
throw new Error('Not authorized');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
next();
|
|
68
|
+
})
|
|
69
|
+
.catch(err => next(err));
|
|
70
|
+
},
|
|
71
|
+
express.json(),
|
|
72
|
+
objectRouter(backend, toRoute)
|
|
73
|
+
);
|
|
15
74
|
|
|
16
|
-
|
|
75
|
+
console.log('Workspace', workspace);
|
|
76
|
+
frontend(apiUrl, false, options, workspace);
|
|
17
77
|
|
|
18
78
|
router.use(express.static(`${__dirname}/frontend/public`));
|
|
19
79
|
|
package/frontend/index.js
CHANGED
|
@@ -3,8 +3,28 @@
|
|
|
3
3
|
const { execSync, exec } = require('child_process');
|
|
4
4
|
const webpack = require('webpack');
|
|
5
5
|
|
|
6
|
-
module.exports = function(apiUrl, isLambda, options) {
|
|
7
|
-
|
|
6
|
+
module.exports = async function frontend(apiUrl, isLambda, options, workspace) {
|
|
7
|
+
if (workspace == null && options?.apiKey) {
|
|
8
|
+
({ workspace } = await fetch(`${mothershipUrl}/getWorkspace`, {
|
|
9
|
+
method: 'POST',
|
|
10
|
+
body: JSON.stringify({ apiKey: options.apiKey }),
|
|
11
|
+
headers: {
|
|
12
|
+
'Authorization': `Bearer ${options.apiKey}`,
|
|
13
|
+
'Content-Type': 'application/json'
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
.then(response => {
|
|
17
|
+
if (response.status < 200 || response.status >= 400) {
|
|
18
|
+
return response.json().then(data => {
|
|
19
|
+
throw new Error(`Mongoose Studio API Key Error ${response.status}: ${require('util').inspect(data)}`);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
return response;
|
|
23
|
+
})
|
|
24
|
+
.then(res => res.json()));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const config = { ...require('./webpack.config'), plugins: [] };
|
|
8
28
|
if (apiUrl != null) {
|
|
9
29
|
config.plugins = [
|
|
10
30
|
new webpack.DefinePlugin({
|
|
@@ -14,11 +34,24 @@ module.exports = function(apiUrl, isLambda, options) {
|
|
|
14
34
|
]
|
|
15
35
|
}
|
|
16
36
|
if (options?.setAuthorizationHeaderFrom) {
|
|
17
|
-
config.plugins = config.plugins || [];
|
|
18
37
|
config.plugins.push(new webpack.DefinePlugin({
|
|
19
38
|
config__setAuthorizationHeaderFrom: `'${options.setAuthorizationHeaderFrom}'`
|
|
20
39
|
}));
|
|
21
40
|
}
|
|
41
|
+
if (options?.apiKey) {
|
|
42
|
+
config.plugins.push(new webpack.DefinePlugin({
|
|
43
|
+
config__mothershipUrl: `'${options?._mothershipUrl}'` || '\'https://mongoose-js.netlify.app/.netlify/functions\''
|
|
44
|
+
}));
|
|
45
|
+
} else {
|
|
46
|
+
config.plugins.push(new webpack.DefinePlugin({
|
|
47
|
+
config__mothershipUrl: '\'\''
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const { apiKey, ...workspaceData } = workspace || {};
|
|
52
|
+
config.plugins.push(new webpack.DefinePlugin({
|
|
53
|
+
config__workspace: JSON.stringify(workspaceData)
|
|
54
|
+
}));
|
|
22
55
|
const compiler = webpack(config);
|
|
23
56
|
|
|
24
57
|
if (options && options.watch) {
|
|
@@ -44,4 +77,4 @@ module.exports = function(apiUrl, isLambda, options) {
|
|
|
44
77
|
});
|
|
45
78
|
});
|
|
46
79
|
}
|
|
47
|
-
};
|
|
80
|
+
};
|
package/frontend/public/app.js
CHANGED
|
@@ -17,16 +17,14 @@ const client = axios.create({
|
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
window.apiClient = client;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
20
|
+
client.interceptors.request.use(req => {
|
|
21
|
+
const accessToken = window.localStorage.getItem('_mongooseStudioAccessToken') || null;
|
|
22
|
+
if (accessToken) {
|
|
23
|
+
req.headers.authorization = accessToken;
|
|
24
|
+
}
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
26
|
+
return req;
|
|
27
|
+
});
|
|
30
28
|
|
|
31
29
|
client.interceptors.response.use(
|
|
32
30
|
res => res,
|
|
@@ -1852,6 +1850,48 @@ module.exports = app => app.component('models', {
|
|
|
1852
1850
|
});
|
|
1853
1851
|
|
|
1854
1852
|
|
|
1853
|
+
/***/ }),
|
|
1854
|
+
|
|
1855
|
+
/***/ "./frontend/src/mothership.js":
|
|
1856
|
+
/*!************************************!*\
|
|
1857
|
+
!*** ./frontend/src/mothership.js ***!
|
|
1858
|
+
\************************************/
|
|
1859
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
1860
|
+
|
|
1861
|
+
"use strict";
|
|
1862
|
+
|
|
1863
|
+
|
|
1864
|
+
const axios = __webpack_require__(/*! axios */ "./node_modules/axios/dist/browser/axios.cjs");
|
|
1865
|
+
const client = axios.create({
|
|
1866
|
+
baseURL: 'http://localhost:8888/.netlify/functions'
|
|
1867
|
+
});
|
|
1868
|
+
|
|
1869
|
+
client.hasAPIKey = !!'http://localhost:8888/.netlify/functions';
|
|
1870
|
+
|
|
1871
|
+
client.interceptors.request.use(req => {
|
|
1872
|
+
const accessToken = window.localStorage.getItem('_mongooseStudioAccessToken') || null;
|
|
1873
|
+
if (accessToken) {
|
|
1874
|
+
req.headers.authorization = accessToken;
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
return req;
|
|
1878
|
+
});
|
|
1879
|
+
|
|
1880
|
+
exports.githubLogin = function githubLogin() {
|
|
1881
|
+
return client.post('/githubLogin', { state: window.location.href }).then(res => res.data);
|
|
1882
|
+
};
|
|
1883
|
+
|
|
1884
|
+
exports.github = function github(code) {
|
|
1885
|
+
return client.post('/github', { code, workspaceId: {"_id":"679a83f5e1a8219e1aa0c195","ownerId":"67993a84c9988e44997ac98e","members":[{"userId":"67993a84c9988e44997ac98e","roles":["owner"]}],"createdAt":"2025-01-29T19:39:33.970Z","updatedAt":"2025-01-29T21:07:54.715Z","__v":0,"baseUrl":"https://web.zevo.io","name":"ZEVO Dev"}._id }).then(res => res.data);
|
|
1886
|
+
};
|
|
1887
|
+
|
|
1888
|
+
exports.me = function me() {
|
|
1889
|
+
return client.post('/me', { workspaceId: {"_id":"679a83f5e1a8219e1aa0c195","ownerId":"67993a84c9988e44997ac98e","members":[{"userId":"67993a84c9988e44997ac98e","roles":["owner"]}],"createdAt":"2025-01-29T19:39:33.970Z","updatedAt":"2025-01-29T21:07:54.715Z","__v":0,"baseUrl":"https://web.zevo.io","name":"ZEVO Dev"}._id }).then(res => res.data);
|
|
1890
|
+
};
|
|
1891
|
+
|
|
1892
|
+
exports.hasAPIKey = client.hasAPIKey;
|
|
1893
|
+
|
|
1894
|
+
|
|
1855
1895
|
/***/ }),
|
|
1856
1896
|
|
|
1857
1897
|
/***/ "./frontend/src/navbar/navbar.js":
|
|
@@ -1864,6 +1904,7 @@ module.exports = app => app.component('models', {
|
|
|
1864
1904
|
|
|
1865
1905
|
|
|
1866
1906
|
const api = __webpack_require__(/*! ../api */ "./frontend/src/api.js");
|
|
1907
|
+
const mothership = __webpack_require__(/*! ../mothership */ "./frontend/src/mothership.js");
|
|
1867
1908
|
const template = __webpack_require__(/*! ./navbar.html */ "./frontend/src/navbar/navbar.html");
|
|
1868
1909
|
|
|
1869
1910
|
const appendCSS = __webpack_require__(/*! ../appendCSS */ "./frontend/src/appendCSS.js");
|
|
@@ -1872,18 +1913,54 @@ appendCSS(__webpack_require__(/*! ./navbar.css */ "./frontend/src/navbar/navbar.
|
|
|
1872
1913
|
|
|
1873
1914
|
module.exports = app => app.component('navbar', {
|
|
1874
1915
|
template: template,
|
|
1875
|
-
|
|
1916
|
+
props: ['user'],
|
|
1917
|
+
data: () => ({ nodeEnv: null, showFlyout: false }),
|
|
1876
1918
|
computed: {
|
|
1877
1919
|
routeName() {
|
|
1878
1920
|
return this.$route.name;
|
|
1879
1921
|
},
|
|
1880
1922
|
warnEnv() {
|
|
1881
1923
|
return this.nodeEnv === 'prod' || this.nodeEnv === 'production';
|
|
1924
|
+
},
|
|
1925
|
+
hasAPIKey() {
|
|
1926
|
+
return mothership.hasAPIKey;
|
|
1882
1927
|
}
|
|
1883
1928
|
},
|
|
1884
1929
|
async mounted() {
|
|
1885
1930
|
const { nodeEnv } = await api.status();
|
|
1886
1931
|
this.nodeEnv = nodeEnv;
|
|
1932
|
+
},
|
|
1933
|
+
methods: {
|
|
1934
|
+
async loginWithGithub() {
|
|
1935
|
+
const { url } = await mothership.githubLogin();
|
|
1936
|
+
window.location.href = url;
|
|
1937
|
+
},
|
|
1938
|
+
hideFlyout() {
|
|
1939
|
+
this.showFlyout = false;
|
|
1940
|
+
},
|
|
1941
|
+
logout() {
|
|
1942
|
+
window.localStorage.setItem('_mongooseStudioAccessToken', '');
|
|
1943
|
+
window.location.reload();
|
|
1944
|
+
},
|
|
1945
|
+
},
|
|
1946
|
+
directives: {
|
|
1947
|
+
clickOutside: {
|
|
1948
|
+
beforeMount(el, binding, vnode) {
|
|
1949
|
+
el.clickOutsideEvent = (event) => {
|
|
1950
|
+
let isOutside = true;
|
|
1951
|
+
if (event.target === el || el.contains(event.target)) {
|
|
1952
|
+
isOutside = false;
|
|
1953
|
+
}
|
|
1954
|
+
if (isOutside) {
|
|
1955
|
+
binding.value.call();
|
|
1956
|
+
}
|
|
1957
|
+
};
|
|
1958
|
+
document.body.addEventListener('click', el.clickOutsideEvent);
|
|
1959
|
+
},
|
|
1960
|
+
unmounted(el) {
|
|
1961
|
+
document.body.removeEventListener('click', el.clickOutsideEvent);
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1887
1964
|
}
|
|
1888
1965
|
});
|
|
1889
1966
|
|
|
@@ -1927,6 +2004,51 @@ module.exports = [
|
|
|
1927
2004
|
}
|
|
1928
2005
|
];
|
|
1929
2006
|
|
|
2007
|
+
/***/ }),
|
|
2008
|
+
|
|
2009
|
+
/***/ "./frontend/src/splash/splash.js":
|
|
2010
|
+
/*!***************************************!*\
|
|
2011
|
+
!*** ./frontend/src/splash/splash.js ***!
|
|
2012
|
+
\***************************************/
|
|
2013
|
+
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
2014
|
+
|
|
2015
|
+
"use strict";
|
|
2016
|
+
|
|
2017
|
+
|
|
2018
|
+
const mothership = __webpack_require__(/*! ../mothership */ "./frontend/src/mothership.js");
|
|
2019
|
+
const template = __webpack_require__(/*! ./splash.html */ "./frontend/src/splash/splash.html");
|
|
2020
|
+
|
|
2021
|
+
module.exports = app => app.component('splash', {
|
|
2022
|
+
template,
|
|
2023
|
+
inject: ['state'],
|
|
2024
|
+
data: () => ({ error: null }),
|
|
2025
|
+
computed: {
|
|
2026
|
+
workspaceName() {
|
|
2027
|
+
return {"_id":"679a83f5e1a8219e1aa0c195","ownerId":"67993a84c9988e44997ac98e","members":[{"userId":"67993a84c9988e44997ac98e","roles":["owner"]}],"createdAt":"2025-01-29T19:39:33.970Z","updatedAt":"2025-01-29T21:07:54.715Z","__v":0,"baseUrl":"https://web.zevo.io","name":"ZEVO Dev"}.name;
|
|
2028
|
+
}
|
|
2029
|
+
},
|
|
2030
|
+
async mounted() {
|
|
2031
|
+
const href = window.location.href;
|
|
2032
|
+
if (href.match(/\?code=([a-zA-Z0-9]+)$/)) {
|
|
2033
|
+
const code = href.match(/\?code=([a-zA-Z0-9]+)$/)[1];
|
|
2034
|
+
const { accessToken, user, roles } = await mothership.github(code);
|
|
2035
|
+
if (roles == null) {
|
|
2036
|
+
this.error = 'You are not authorized to access this workspace';
|
|
2037
|
+
return;
|
|
2038
|
+
}
|
|
2039
|
+
this.state.user = user;
|
|
2040
|
+
window.localStorage.setItem('_mongooseStudioAccessToken', accessToken._id);
|
|
2041
|
+
}
|
|
2042
|
+
},
|
|
2043
|
+
methods: {
|
|
2044
|
+
async loginWithGithub() {
|
|
2045
|
+
const { url } = await mothership.githubLogin();
|
|
2046
|
+
window.location.href = url;
|
|
2047
|
+
}
|
|
2048
|
+
}
|
|
2049
|
+
});
|
|
2050
|
+
|
|
2051
|
+
|
|
1930
2052
|
/***/ }),
|
|
1931
2053
|
|
|
1932
2054
|
/***/ "./node_modules/mpath/index.js":
|
|
@@ -2569,7 +2691,7 @@ module.exports = "";
|
|
|
2569
2691
|
/***/ ((module) => {
|
|
2570
2692
|
|
|
2571
2693
|
"use strict";
|
|
2572
|
-
module.exports = "<div>\n <div class=\"mb-2\">\n <textarea class=\"border border-gray-200 p-2 h-[300px] w-full\" ref=\"codeEditor\"></textarea>\n </div>\n <button @click=\"createDocument()\" class=\"rounded-md bg-
|
|
2694
|
+
module.exports = "<div>\n <div class=\"mb-2\">\n <textarea class=\"border border-gray-200 p-2 h-[300px] w-full\" ref=\"codeEditor\"></textarea>\n </div>\n <button @click=\"createDocument()\" class=\"rounded-md bg-ultramarine-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">Submit</button>\n <div v-if=\"errors.length > 0\" class=\"rounded-md bg-red-50 p-4 mt-1\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <svg class=\"h-5 w-5 text-red-400\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z\" clip-rule=\"evenodd\" />\n </svg>\n </div>\n <div class=\"ml-3\">\n <h3 class=\"text-sm font-medium text-red-800\">There were {{errors.length}} errors with your submission</h3>\n <div class=\"mt-2 text-sm text-red-700\">\n <ul role=\"list\" class=\"list-disc space-y-1 pl-5\">\n <li v-for=\"error in errors\">\n {{error}}\n </li>\n </ul>\n </div>\n </div>\n </div>\n </div>\n</div>\n";
|
|
2573
2695
|
|
|
2574
2696
|
/***/ }),
|
|
2575
2697
|
|
|
@@ -2767,7 +2889,7 @@ module.exports = ".document {\n max-width: 1200px;\n margin-left: auto;\n mar
|
|
|
2767
2889
|
/***/ ((module) => {
|
|
2768
2890
|
|
|
2769
2891
|
"use strict";
|
|
2770
|
-
module.exports = "<div class=\"document\">\n <div class=\"document-menu\">\n <div class=\"left\">\n <button
|
|
2892
|
+
module.exports = "<div class=\"document\">\n <div class=\"document-menu\">\n <div class=\"left\">\n <button\n @click=\"$router.push('/model/' + this.model)\"\n class=\"rounded-md bg-gray-400 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\">\n ‹ Back\n </button>\n </div>\n\n <div class=\"right\">\n <button\n v-if=\"!editting\"\n @click=\"editting = true\"\n type=\"button\"\n class=\"rounded-md bg-ultramarine-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">\n <img src=\"images/edit.svg\" class=\"inline\" /> Edit\n </button>\n <button\n v-if=\"editting\"\n @click=\"editting = false\"\n type=\"button\"\n 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\">\n × Cancel\n </button>\n <button\n v-if=\"editting\"\n @click=\"shouldShowConfirmModal=true;\"\n type=\"button\"\n class=\"rounded-md bg-forest-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\">\n <img src=\"images/save.svg\" class=\"inline\" /> Save\n </button>\n <button\n @click=\"shouldShowDeleteModal=true;\"\n type=\"button\"\n class=\"rounded-md bg-valencia-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-valencia-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600\">\n <img src=\"images/delete.svg\" class=\"inline\" /> Delete\n </button>\n </div>\n </div>\n <div v-if=\"status === 'loaded'\">\n <document-details\n :document=\"document\"\n :schemaPaths=\"schemaPaths\"\n :editting=\"editting\"\n :changes=\"changes\"\n :invalid=\"invalid\"></document-details>\n <modal v-if=\"shouldShowConfirmModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowConfirmModal = false;\">×</div>\n <confirm-changes @close=\"shouldShowConfirmModal = false;\" @save=\"save\" :value=\"changes\"></confirm-changes>\n </template>\n </modal>\n <modal v-if=\"shouldShowDeleteModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowConfirmModal = false;\">×</div>\n <confirm-delete @close=\"shouldShowConfirmModal = false;\" @remove=\"remove\" :value=\"document\"></confirm-delete>\n </template>\n </modal>\n </div>\n</div>\n";
|
|
2771
2893
|
|
|
2772
2894
|
/***/ }),
|
|
2773
2895
|
|
|
@@ -2998,7 +3120,7 @@ module.exports = "<div class=\"list-subdocument tooltip\">\n <pre>\n <code r
|
|
|
2998
3120
|
/***/ ((module) => {
|
|
2999
3121
|
|
|
3000
3122
|
"use strict";
|
|
3001
|
-
module.exports = "/** Vue modal */\n\n.modal-mask {\n position: fixed;\n z-index: 9998;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.5);\n display: table;\n transition: opacity 0.3s ease;\n}\n\n.modal-wrapper {\n display: table-cell;\n vertical-align: middle;\n}\n\n.modal-container {\n width: 600px;\n margin: 0px auto;\n padding: 20px 30px;\n padding-bottom: 40px;\n background-color: #fff;\n border-radius: 2px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);\n transition: all 0.3s ease;\n font-family: Helvetica, Arial, sans-serif;\n position: relative;\n}\n\n.modal-header {\n margin-top: 0;\n font-size: 18px;\n font-weight: bold
|
|
3123
|
+
module.exports = "/** Vue modal */\n\n.modal-mask {\n position: fixed;\n z-index: 9998;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.5);\n display: table;\n transition: opacity 0.3s ease;\n}\n\n.modal-wrapper {\n display: table-cell;\n vertical-align: middle;\n}\n\n.modal-container {\n width: 600px;\n margin: 0px auto;\n padding: 20px 30px;\n padding-bottom: 40px;\n background-color: #fff;\n border-radius: 2px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);\n transition: all 0.3s ease;\n font-family: Helvetica, Arial, sans-serif;\n position: relative;\n}\n\n.modal-header {\n margin-top: 0;\n font-size: 18px;\n font-weight: bold;\n}\n\n.modal-header-success {\n color: #42b983;\n}\n\n.modal-header-error {\n color: #ff0000;\n}\n\n.modal-body {\n margin: 20px 0;\n max-height: calc(100vh - 40px - 60px - 10px);\n overflow: auto;\n}\n\n.modal__button--default {\n float: right;\n}\n\n/*\n * The following styles are auto-applied to elements with\n * transition=\"modal\" when their visibility is toggled\n * by Vue.js.\n *\n * You can easily play with the modal transition by editing\n * these styles.\n */\n\n.modal-enter {\n opacity: 0;\n}\n\n.modal-leave-active {\n opacity: 0;\n}\n\n.modal-enter .modal-container,\n.modal-leave-active .modal-container {\n -webkit-transform: scale(1.1);\n transform: scale(1.1);\n}\n\n.modal-container .modal-exit {\n position: absolute;\n right: 0.25em;\n top: 0.25em;\n cursor: pointer;\n font-size: 1.25em;\n height: 1.25em;\n width: 1.25em;\n border-radius: 100%;\n border: 1px solid #ddd;\n display: flex;\n align-items: center;\n justify-content: center;\n padding-bottom: 0.25em;\n}\n";
|
|
3002
3124
|
|
|
3003
3125
|
/***/ }),
|
|
3004
3126
|
|
|
@@ -3020,7 +3142,7 @@ module.exports = "<transition name=\"modal\">\n <div class=\"modal-mask\">\n
|
|
|
3020
3142
|
/***/ ((module) => {
|
|
3021
3143
|
|
|
3022
3144
|
"use strict";
|
|
3023
|
-
module.exports = ".models {\n position: relative;\n display: flex;\n flex-direction: row;\n min-height: calc(100% - 56px);\n}\n\n.models button.gray {\n color: black;\n background-color: #eee;\n}\n\n.models .model-selector {\n background-color: #eee;\n flex-grow: 0
|
|
3145
|
+
module.exports = ".models {\n position: relative;\n display: flex;\n flex-direction: row;\n min-height: calc(100% - 56px);\n}\n\n.models button.gray {\n color: black;\n background-color: #eee;\n}\n\n.models .model-selector {\n background-color: #eee;\n flex-grow: 0;\n padding: 15px;\n padding-top: 0px;\n}\n\n.models h1 {\n margin-top: 0px;\n}\n\n.models .documents {\n flex-grow: 1;\n overflow: scroll;\n max-height: calc(100vh - 56px);\n}\n\n.models .documents table {\n /* max-width: -moz-fit-content;\n max-width: fit-content; */\n width: 100%;\n table-layout: auto;\n font-size: small;\n padding: 0;\n margin-right: 1em;\n white-space: nowrap;\n z-index: -1;\n border-collapse: collapse;\n line-height: 1.5em;\n}\n\n.models .documents table th {\n position: sticky;\n top: 0px;\n background-color: white;\n z-index: 1;\n}\n\n.models .documents table th:after {\n content: \"\";\n position: absolute;\n left: 0;\n width: 100%;\n bottom: -1px;\n border-bottom: thin solid rgba(0, 0, 0, 0.12);\n}\n\n.models .documents table tr {\n color: black;\n border-spacing: 0px 0px;\n background-color: white;\n cursor: pointer;\n}\n\n.models .documents table tr:nth-child(even) {\n background-color: #f5f5f5;\n}\n\n.models .documents table tr:hover {\n background-color: #a7b9ff;\n}\n\n.models .documents table th,\ntd {\n border-bottom: thin solid rgba(0, 0, 0, 0.12);\n text-align: left;\n padding: 0 16px;\n height: 48px;\n}\n\n.models textarea {\n font-size: 1.2em;\n}\n\n.models .path-type {\n color: rgba(0, 0, 0, 0.36);\n font-size: 0.8em;\n}\n\n.models .documents-menu {\n display: flex;\n margin: 0.25em;\n width: calc(100vw - 220px);\n}\n\n.models .documents-menu .search-input {\n flex-grow: 1;\n align-items: center;\n}\n\n.models .search-input input {\n padding: 0.25em 0.5em;\n font-size: 1.1em;\n border: 1px solid #ddd;\n border-radius: 3px;\n width: calc(100% - 1em);\n}\n\n.models .sort-arrow {\n padding-left: 10px;\n padding-right: 10px;\n}\n\n.models .loader {\n width: 100%;\n text-align: center;\n}\n\n.models .loader img {\n height: 4em;\n}\n\n.models .documents .buttons {\n display: inline-flex;\n justify-content: space-around;\n align-items: center;\n}\n";
|
|
3024
3146
|
|
|
3025
3147
|
/***/ }),
|
|
3026
3148
|
|
|
@@ -3031,7 +3153,7 @@ module.exports = ".models {\n position: relative;\n display: flex;\n flex-dir
|
|
|
3031
3153
|
/***/ ((module) => {
|
|
3032
3154
|
|
|
3033
3155
|
"use strict";
|
|
3034
|
-
module.exports = "<div class=\"models\">\n <div>\n <div class=\"flex grow flex-col gap-y-5 overflow-y-auto border-r border-gray-200 bg-white px-2 h-[calc(100vh-55px)]\">\n <div class=\"flex font-bold font-xl mt-4 pl-2\">\n Models\n </div>\n <nav class=\"flex flex-1 flex-col\">\n <ul role=\"list\" class=\"flex flex-1 flex-col gap-y-7\">\n <li>\n <ul role=\"list\">\n <li v-for=\"model in models\">\n <router-link\n :to=\"'/model/' + model\"\n class=\"block rounded-md py-2 pr-2 pl-2 text-sm font-semibold text-gray-700\"\n :class=\"model === currentModel ? 'bg-
|
|
3156
|
+
module.exports = "<div class=\"models\">\n <div>\n <div class=\"flex grow flex-col gap-y-5 overflow-y-auto border-r border-gray-200 bg-white px-2 h-[calc(100vh-55px)]\">\n <div class=\"flex font-bold font-xl mt-4 pl-2\">\n Models\n </div>\n <nav class=\"flex flex-1 flex-col\">\n <ul role=\"list\" class=\"flex flex-1 flex-col gap-y-7\">\n <li>\n <ul role=\"list\">\n <li v-for=\"model in models\">\n <router-link\n :to=\"'/model/' + model\"\n class=\"block rounded-md py-2 pr-2 pl-2 text-sm font-semibold text-gray-700\"\n :class=\"model === currentModel ? 'bg-ultramarine-100 font-bold' : 'hover:bg-ultramarine-100'\">\n {{model}}\n </router-link>\n </li>\n </ul>\n </li>\n </ul>\n </nav>\n </div>\n\n </div>\n <div class=\"documents\" ref=\"documentsList\">\n <div>\n <div class=\"documents-menu\">\n <div class=\"flex flex-row items-center w-full gap-2\">\n <form @submit.prevent=\"search\" class=\"flex-grow m-0\">\n <input class=\"w-full rounded-md p-1 outline-gray-300 text-lg\" type=\"text\" placeholder=\"Filter or text\" v-model=\"searchText\" />\n </form>\n <div>\n <span v-if=\"status === 'loading'\">Loading ...</span>\n <span v-if=\"status === 'loaded'\">{{numDocuments === 1 ? numDocuments+ ' document' : numDocuments + ' documents'}}</span>\n </div>\n <button\n @click=\"shouldShowExportModal = true\"\n type=\"button\"\n class=\"rounded bg-ultramarine-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600\">\n Export\n </button>\n <button\n @click=\"shouldShowCreateModal = true;\"\n type=\"button\"\n class=\"rounded bg-ultramarine-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600\">\n Create\n </button>\n <button\n @click=\"shouldShowFieldModal = true\"\n type=\"button\"\n class=\"rounded bg-ultramarine-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600\">\n Fields\n </button>\n <span class=\"isolate inline-flex rounded-md shadow-sm\">\n <button\n @click=\"outputType = 'table'\"\n type=\"button\"\n class=\"relative inline-flex items-center rounded-none rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10\"\n :class=\"outputType === 'table' ? 'bg-gray-200' : 'bg-white'\">\n <img class=\"h-5 w-5\" src=\"images/table.svg\">\n </button>\n <button\n @click=\"outputType = 'json'\"\n type=\"button\"\n class=\"relative -ml-px inline-flex items-center rounded-none rounded-r-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10\"\n :class=\"outputType === 'json' ? 'bg-gray-200' : 'bg-white'\">\n <img class=\"h-5 w-5\" src=\"images/json.svg\">\n </button>\n </span>\n </div>\n </div>\n </div>\n <div class=\"documents-container\">\n <table v-if=\"outputType === 'table'\">\n <thead>\n <th v-for=\"path in filteredPaths\">\n {{path.path}}\n <span class=\"path-type\">\n ({{(path.instance || 'unknown')}})\n </span>\n <span class=\"sort-arrow\" @click=\"sortDocs(1, path.path)\">{{sortBy[path.path] == 1 ? 'X' : '↑'}}</span>\n <span class=\"sort-arrow\" @click=\"sortDocs(-1, path.path)\">{{sortBy[path.path] == -1 ? 'X' : '↓'}}</span>\n </th>\n </thead>\n <tbody>\n <tr v-for=\"document in documents\" @click=\"$router.push('/model/' + currentModel + '/document/' + document._id)\" :key=\"document._id\">\n <td v-for=\"schemaPath in filteredPaths\">\n <component\n :is=\"getComponentForPath(schemaPath)\"\n :value=\"getValueForPath(document, schemaPath.path)\"\n :allude=\"getReferenceModel(schemaPath)\">\n </component>\n </td>\n </tr>\n </tbody>\n </table>\n <div v-if=\"outputType === 'json'\">\n <div v-for=\"document in documents\" @click=\"$router.push('/model/' + currentModel + '/document/' + document._id)\" :key=\"document._id\">\n <list-json :value=\"filterDocument(document)\">\n </list-json>\n </div>\n </div>\n <div v-if=\"status === 'loading'\" class=\"loader\">\n <img src=\"images/loader.gif\">\n </div>\n </div>\n <modal v-if=\"shouldShowExportModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowExportModal = false\">×</div>\n <export-query-results\n :schemaPaths=\"schemaPaths\"\n :filter=\"filter\"\n :currentModel=\"currentModel\"\n @done=\"shouldShowExportModal = false\">\n </export-query-results>\n </template>\n </modal>\n <modal v-if=\"shouldShowFieldModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowFieldModal = false; selectedPaths = [...filteredPaths];\">×</div>\n <div v-for=\"(path, index) in schemaPaths\" :key=\"index\" style=\"margin-bottom: 0.5em\">\n <input type=\"checkbox\" :id=\"'path.path'+index\" @change=\"addOrRemove(path)\" :value=\"path.path\" :checked=\"isSelected(path.path)\" />\n <label :for=\"'path' + index\">{{path.path}}</label>\n </div>\n <div style=\"margin-top: 1em\">\n <button type=\"submit\" @click=\"filterDocuments()\" style=\"color: black;margin-right: 0.5em\">Filter Selection</button>\n <button type=\"submit\" @click=\"deselectAll()\" class=\"gray\" style=\"margin-right: 0.5em\">Deselect All</button>\n <button type=\"submit\" @click=\"resetDocuments()\" class=\"gray\">Cancel</button>\n\n </div>\n </template>\n </modal>\n <modal v-if=\"shouldShowCreateModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"shouldShowCreateModal = false;\">×</div>\n <create-document :currentModel=\"currentModel\" :paths=\"schemaPaths\" @close=\"closeCreationModal\"></create-document>\n </template>\n </modal>\n </div>\n</div>\n";
|
|
3035
3157
|
|
|
3036
3158
|
/***/ }),
|
|
3037
3159
|
|
|
@@ -3053,7 +3175,18 @@ module.exports = ".navbar {\n width: 100%;\n background-color: #eee;\n}\n\n.ac
|
|
|
3053
3175
|
/***/ ((module) => {
|
|
3054
3176
|
|
|
3055
3177
|
"use strict";
|
|
3056
|
-
module.exports = "<div class=\"navbar\">\n <div class=\"nav-left flex items-center gap-4 h-full\">\n <router-link to=\"/\">\n <img src=\"images/logo.svg\" alt=\"Mongoose Studio Logo\" />\n </router-link>\n <div v-if=\"!!nodeEnv\" class=\"inline-flex items-center rounded-md px-2 py-1 text-sm font-medium text-gray-900\" :class=\"warnEnv ? 'bg-red-300' : 'bg-yellow-300'\">\n {{nodeEnv}}\n </div>\n </div>\n <div class=\"nav-right h-full\">\n <div class=\"sm:ml-6 sm:flex sm:space-x-8 h-full\">\n <a\n href=\"#/\"\n class=\"inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium\"\n :class=\"routeName === 'root' ? 'text-gray-900 border-
|
|
3178
|
+
module.exports = "<div class=\"navbar\">\n <div class=\"nav-left flex items-center gap-4 h-full\">\n <router-link to=\"/\">\n <img src=\"images/logo.svg\" alt=\"Mongoose Studio Logo\" />\n </router-link>\n <div v-if=\"!!nodeEnv\" class=\"inline-flex items-center rounded-md px-2 py-1 text-sm font-medium text-gray-900\" :class=\"warnEnv ? 'bg-red-300' : 'bg-yellow-300'\">\n {{nodeEnv}}\n </div>\n </div>\n <div class=\"nav-right h-full\">\n <div class=\"sm:ml-6 sm:flex sm:space-x-8 h-full\">\n <a\n href=\"#/\"\n class=\"inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium\"\n :class=\"routeName === 'root' ? 'text-gray-900 border-ultramarine-500' : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700'\">Documents</a>\n <a\n href=\"#/dashboards\"\n class=\"inline-flex items-center border-b-2 px-1 pt-1 text-sm font-medium\"\n :class=\"routeName === 'dashboards' ? 'text-gray-900 border-ultramarine-500' : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700'\">Dashboards</a>\n\n <div class=\"h-full flex items-center\" v-if=\"!user && hasAPIKey\">\n <button\n type=\"button\"\n @click=\"loginWithGithub\"\n class=\"rounded bg-ultramarine-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600\">\n Login\n </button>\n </div>\n <div v-if=\"user && hasAPIKey\" class=\"h-full flex items-center relative\" v-clickOutside=\"hideFlyout\">\n <div>\n <button type=\"button\" @click=\"showFlyout = !showFlyout\" class=\"relative flex rounded-full bg-gray-800 text-sm focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800\" id=\"user-menu-button\" aria-expanded=\"false\" aria-haspopup=\"true\">\n <span class=\"absolute -inset-1.5\"></span>\n <span class=\"sr-only\">Open user menu</span>\n <img class=\"size-8 rounded-full\" :src=\"user.picture\" alt=\"\">\n </button>\n </div>\n\n <div v-if=\"showFlyout\" class=\"absolute right-0 z-10 top-[82%] w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black/5 focus:outline-none\" role=\"menu\" aria-orientation=\"vertical\" aria-labelledby=\"user-menu-button\" tabindex=\"-1\">\n <!-- Active: \"bg-gray-100 outline-none\", Not Active: \"\" -->\n <span @click=\"logout\" class=\"cursor-pointer block px-4 py-2 text-sm text-gray-700 hover:bg-ultramarine-200\" role=\"menuitem\" tabindex=\"-1\" id=\"user-menu-item-2\">Sign out</span>\n </div>\n </div>\n\n </div>\n </div>\n <div style=\"clear: both\"></div>\n</div>\n";
|
|
3179
|
+
|
|
3180
|
+
/***/ }),
|
|
3181
|
+
|
|
3182
|
+
/***/ "./frontend/src/splash/splash.html":
|
|
3183
|
+
/*!*****************************************!*\
|
|
3184
|
+
!*** ./frontend/src/splash/splash.html ***!
|
|
3185
|
+
\*****************************************/
|
|
3186
|
+
/***/ ((module) => {
|
|
3187
|
+
|
|
3188
|
+
"use strict";
|
|
3189
|
+
module.exports = "<div class=\"w-full h-full flex items-center justify-center\">\n <div class=\"text-center\">\n <div class=\"rounded-full bg-gray-100 p-6 inline-block\">\n <img src=\"images/logo.svg\" class=\"w-48 h-48\">\n </div>\n <div class=\"text-lg mt-2 font-bold\">\n Mongoose Studio\n </div>\n <div class=\"mt-2 text-gray-700\">\n {{workspaceName}}\n </div>\n <div class=\"mt-4\">\n <async-button\n type=\"button\"\n @click=\"loginWithGithub\"\n class=\"rounded bg-ultramarine-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600\">\n Login With GitHub\n </async-button>\n </div>\n <div class=\"mt-4\" v-if=\"error\">\n <div class=\"rounded-md bg-red-50 p-4\">\n <div class=\"flex\">\n <div class=\"shrink-0\">\n <svg class=\"size-5 text-red-400\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\" data-slot=\"icon\">\n <path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16ZM8.28 7.22a.75.75 0 0 0-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 1 0 1.06 1.06L10 11.06l1.72 1.72a.75.75 0 1 0 1.06-1.06L11.06 10l1.72-1.72a.75.75 0 0 0-1.06-1.06L10 8.94 8.28 7.22Z\" clip-rule=\"evenodd\" />\n </svg>\n </div>\n <div class=\"ml-3\">\n <h3 class=\"text-sm font-medium text-red-800\">{{error}}</h3>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n";
|
|
3057
3190
|
|
|
3058
3191
|
/***/ }),
|
|
3059
3192
|
|
|
@@ -10874,6 +11007,7 @@ if (typeof process === 'undefined') {
|
|
|
10874
11007
|
__webpack_require__.g.process = { env: {} }; // To make `util` package work
|
|
10875
11008
|
}
|
|
10876
11009
|
|
|
11010
|
+
const mothership = __webpack_require__(/*! ./mothership */ "./frontend/src/mothership.js");
|
|
10877
11011
|
const vanillatoasts = __webpack_require__(/*! vanillatoasts */ "./node_modules/vanillatoasts/vanillatoasts.js");
|
|
10878
11012
|
|
|
10879
11013
|
const app = Vue.createApp({
|
|
@@ -10913,13 +11047,19 @@ __webpack_require__(/*! ./list-subdocument/list-subdocument */ "./frontend/src/l
|
|
|
10913
11047
|
__webpack_require__(/*! ./modal/modal */ "./frontend/src/modal/modal.js")(app);
|
|
10914
11048
|
__webpack_require__(/*! ./models/models */ "./frontend/src/models/models.js")(app);
|
|
10915
11049
|
__webpack_require__(/*! ./navbar/navbar */ "./frontend/src/navbar/navbar.js")(app);
|
|
11050
|
+
__webpack_require__(/*! ./splash/splash */ "./frontend/src/splash/splash.js")(app);
|
|
10916
11051
|
|
|
10917
11052
|
app.component('app-component', {
|
|
10918
11053
|
template: `
|
|
10919
11054
|
<div>
|
|
10920
|
-
<
|
|
10921
|
-
|
|
10922
|
-
|
|
11055
|
+
<div v-if="hasAPIKey && user == null">
|
|
11056
|
+
<splash />
|
|
11057
|
+
</div>
|
|
11058
|
+
<div v-else-if="!hasAPIKey || user">
|
|
11059
|
+
<navbar :user="user" />
|
|
11060
|
+
<div class="view">
|
|
11061
|
+
<router-view :key="$route.fullPath" />
|
|
11062
|
+
</div>
|
|
10923
11063
|
</div>
|
|
10924
11064
|
</div>
|
|
10925
11065
|
`,
|
|
@@ -10930,6 +11070,29 @@ app.component('app-component', {
|
|
|
10930
11070
|
timeout: 10000,
|
|
10931
11071
|
positionClass: 'bottomRight'
|
|
10932
11072
|
});
|
|
11073
|
+
},
|
|
11074
|
+
computed: {
|
|
11075
|
+
hasAPIKey() {
|
|
11076
|
+
return mothership.hasAPIKey;
|
|
11077
|
+
}
|
|
11078
|
+
},
|
|
11079
|
+
async mounted() {
|
|
11080
|
+
window.$router = this.$router;
|
|
11081
|
+
|
|
11082
|
+
if (mothership.hasAPIKey) {
|
|
11083
|
+
const token = window.localStorage.getItem('_mongooseStudioAccessToken');
|
|
11084
|
+
if (token) {
|
|
11085
|
+
this.user = await mothership.me().then(res => res.user);
|
|
11086
|
+
}
|
|
11087
|
+
}
|
|
11088
|
+
},
|
|
11089
|
+
setup() {
|
|
11090
|
+
const user = Vue.ref(null);
|
|
11091
|
+
|
|
11092
|
+
const state = Vue.reactive({ user });
|
|
11093
|
+
Vue.provide('state', state);
|
|
11094
|
+
|
|
11095
|
+
return state;
|
|
10933
11096
|
}
|
|
10934
11097
|
});
|
|
10935
11098
|
|
|
@@ -2,45 +2,22 @@ body {
|
|
|
2
2
|
min-height: 100%;
|
|
3
3
|
margin: 0;
|
|
4
4
|
padding: 0;
|
|
5
|
-
font-family:
|
|
5
|
+
font-family: "Open Sans", Helvetica, Arial, FreeSans, sans-serif;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
a {
|
|
9
9
|
text-decoration: none;
|
|
10
|
-
color: #
|
|
10
|
+
color: #0e5887;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
.bold {
|
|
14
14
|
font-weight: bold !important;
|
|
15
15
|
}
|
|
16
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
17
|
input {
|
|
28
18
|
outline: #666 solid 1px;
|
|
29
19
|
}
|
|
30
20
|
|
|
31
|
-
button.green {
|
|
32
|
-
background-color: #58D415;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
button.grey {
|
|
36
|
-
color: black;
|
|
37
|
-
background-color: #ddd;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
button.red {
|
|
41
|
-
background-color: red;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
21
|
.tooltip {
|
|
45
22
|
position: relative;
|
|
46
23
|
display: inline-block;
|
|
@@ -58,7 +35,7 @@ button.red {
|
|
|
58
35
|
top: 100%;
|
|
59
36
|
left: 50%;
|
|
60
37
|
margin-left: -60px; /* Use half of the width (120/2 = 60), to center the tooltip */
|
|
61
|
-
|
|
38
|
+
|
|
62
39
|
/* Position the tooltip text - see examples below! */
|
|
63
40
|
position: absolute;
|
|
64
41
|
z-index: 1;
|