@mongoosejs/studio 0.0.60 → 0.0.61
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/frontend/public/app.js +63 -14
- package/frontend/public/style.css +0 -4
- package/frontend/public/tw.css +124 -24
- package/frontend/src/modal/modal.css +4 -0
- package/frontend/src/models/models.html +11 -10
- package/frontend/src/models/models.js +18 -1
- package/frontend/src/mothership.js +10 -2
- package/frontend/src/navbar/navbar.html +1 -1
- package/frontend/src/team/team.html +94 -18
- package/frontend/src/team/team.js +17 -1
- package/package.json +1 -1
package/frontend/public/app.js
CHANGED
|
@@ -1794,8 +1794,25 @@ module.exports = app => app.component('models', {
|
|
|
1794
1794
|
}).map(key => this.selectedPaths[key]);
|
|
1795
1795
|
}
|
|
1796
1796
|
},
|
|
1797
|
+
openFieldSelection() {
|
|
1798
|
+
if (this.$route.query?.fields) {
|
|
1799
|
+
this.selectedPaths.length = 0;
|
|
1800
|
+
console.log('there are fields in play', this.$route.query.fields)
|
|
1801
|
+
const fields = this.$route.query.fields.split(',');
|
|
1802
|
+
for (let i = 0; i < fields.length; i++) {
|
|
1803
|
+
this.selectedPaths.push({ path: fields[i] });
|
|
1804
|
+
}
|
|
1805
|
+
} else {
|
|
1806
|
+
this.selectedPaths = [{ path: '_id' }];
|
|
1807
|
+
}
|
|
1808
|
+
this.shouldShowFieldModal = true;
|
|
1809
|
+
},
|
|
1797
1810
|
filterDocuments() {
|
|
1798
|
-
this.
|
|
1811
|
+
if (this.selectedPaths.length > 0) {
|
|
1812
|
+
this.filteredPaths = [...this.selectedPaths];
|
|
1813
|
+
} else {
|
|
1814
|
+
this.filteredPaths.length = 0;
|
|
1815
|
+
}
|
|
1799
1816
|
this.shouldShowFieldModal = false;
|
|
1800
1817
|
const selectedParams = this.filteredPaths.map(x => x.path).join(',');
|
|
1801
1818
|
this.query.fields = selectedParams;
|
|
@@ -1864,10 +1881,10 @@ module.exports = app => app.component('models', {
|
|
|
1864
1881
|
|
|
1865
1882
|
const axios = __webpack_require__(/*! axios */ "./node_modules/axios/dist/browser/axios.cjs");
|
|
1866
1883
|
const client = axios.create({
|
|
1867
|
-
baseURL: '
|
|
1884
|
+
baseURL: 'https://mongoose-js.netlify.app/.netlify/functions'
|
|
1868
1885
|
});
|
|
1869
1886
|
|
|
1870
|
-
client.hasAPIKey = !!'
|
|
1887
|
+
client.hasAPIKey = !!'https://mongoose-js.netlify.app/.netlify/functions';
|
|
1871
1888
|
|
|
1872
1889
|
client.interceptors.request.use(req => {
|
|
1873
1890
|
const accessToken = window.localStorage.getItem('_mongooseStudioAccessToken') || null;
|
|
@@ -1883,19 +1900,27 @@ exports.githubLogin = function githubLogin() {
|
|
|
1883
1900
|
};
|
|
1884
1901
|
|
|
1885
1902
|
exports.getWorkspaceTeam = function getWorkspaceTeam() {
|
|
1886
|
-
return client.post('/getWorkspaceTeam', { workspaceId: {"_id":"67a5366c745bb0e6735950dc","ownerId":"679ba73e4cc3ddc28f6ef6af","baseUrl":"https://web.zevo.io","members":[{"userId":"679ba73e4cc3ddc28f6ef6af","roles":["owner"]}
|
|
1903
|
+
return client.post('/getWorkspaceTeam', { workspaceId: {"_id":"67a5366c745bb0e6735950dc","ownerId":"679ba73e4cc3ddc28f6ef6af","baseUrl":"https://web.zevo.io","members":[{"userId":"679ba73e4cc3ddc28f6ef6af","roles":["owner"]}],"createdAt":"2025-02-06T22:23:40.903Z","updatedAt":"2025-02-17T21:53:20.548Z","__v":2,"name":"Zevo DEV","subscriptionTier":"pro","stripeCustomerId":"cus_RnCdSdRYLJQl4Z","stripeSubscriptionId":"sub_1QtcEgIIV4Jx8vgxY7z8cKeC"}._id }).then(res => res.data);
|
|
1887
1904
|
};
|
|
1888
1905
|
|
|
1889
|
-
exports.
|
|
1890
|
-
return client.post('/
|
|
1906
|
+
exports.getWorkspaceCustomerPortalLink = function getWorkspaceCustomerPortalLink(params) {
|
|
1907
|
+
return client.post('/getWorkspaceCustomerPortalLink', { workspaceId: {"_id":"67a5366c745bb0e6735950dc","ownerId":"679ba73e4cc3ddc28f6ef6af","baseUrl":"https://web.zevo.io","members":[{"userId":"679ba73e4cc3ddc28f6ef6af","roles":["owner"]}],"createdAt":"2025-02-06T22:23:40.903Z","updatedAt":"2025-02-17T21:53:20.548Z","__v":2,"name":"Zevo DEV","subscriptionTier":"pro","stripeCustomerId":"cus_RnCdSdRYLJQl4Z","stripeSubscriptionId":"sub_1QtcEgIIV4Jx8vgxY7z8cKeC"}._id, ...params }).then(res => res.data);
|
|
1891
1908
|
};
|
|
1892
1909
|
|
|
1893
1910
|
exports.github = function github(code) {
|
|
1894
|
-
return client.post('/github', { code, workspaceId: {"_id":"67a5366c745bb0e6735950dc","ownerId":"679ba73e4cc3ddc28f6ef6af","baseUrl":"https://web.zevo.io","members":[{"userId":"679ba73e4cc3ddc28f6ef6af","roles":["owner"]}
|
|
1911
|
+
return client.post('/github', { code, workspaceId: {"_id":"67a5366c745bb0e6735950dc","ownerId":"679ba73e4cc3ddc28f6ef6af","baseUrl":"https://web.zevo.io","members":[{"userId":"679ba73e4cc3ddc28f6ef6af","roles":["owner"]}],"createdAt":"2025-02-06T22:23:40.903Z","updatedAt":"2025-02-17T21:53:20.548Z","__v":2,"name":"Zevo DEV","subscriptionTier":"pro","stripeCustomerId":"cus_RnCdSdRYLJQl4Z","stripeSubscriptionId":"sub_1QtcEgIIV4Jx8vgxY7z8cKeC"}._id }).then(res => res.data);
|
|
1912
|
+
};
|
|
1913
|
+
|
|
1914
|
+
exports.inviteToWorkspace = function inviteToWorkspace(params) {
|
|
1915
|
+
return client.post('/inviteToWorkspace', { workspaceId: {"_id":"67a5366c745bb0e6735950dc","ownerId":"679ba73e4cc3ddc28f6ef6af","baseUrl":"https://web.zevo.io","members":[{"userId":"679ba73e4cc3ddc28f6ef6af","roles":["owner"]}],"createdAt":"2025-02-06T22:23:40.903Z","updatedAt":"2025-02-17T21:53:20.548Z","__v":2,"name":"Zevo DEV","subscriptionTier":"pro","stripeCustomerId":"cus_RnCdSdRYLJQl4Z","stripeSubscriptionId":"sub_1QtcEgIIV4Jx8vgxY7z8cKeC"}._id, ...params }).then(res => res.data);
|
|
1895
1916
|
};
|
|
1896
1917
|
|
|
1897
1918
|
exports.me = function me() {
|
|
1898
|
-
return client.post('/me', { workspaceId: {"_id":"67a5366c745bb0e6735950dc","ownerId":"679ba73e4cc3ddc28f6ef6af","baseUrl":"https://web.zevo.io","members":[{"userId":"679ba73e4cc3ddc28f6ef6af","roles":["owner"]}
|
|
1919
|
+
return client.post('/me', { workspaceId: {"_id":"67a5366c745bb0e6735950dc","ownerId":"679ba73e4cc3ddc28f6ef6af","baseUrl":"https://web.zevo.io","members":[{"userId":"679ba73e4cc3ddc28f6ef6af","roles":["owner"]}],"createdAt":"2025-02-06T22:23:40.903Z","updatedAt":"2025-02-17T21:53:20.548Z","__v":2,"name":"Zevo DEV","subscriptionTier":"pro","stripeCustomerId":"cus_RnCdSdRYLJQl4Z","stripeSubscriptionId":"sub_1QtcEgIIV4Jx8vgxY7z8cKeC"}._id }).then(res => res.data);
|
|
1920
|
+
};
|
|
1921
|
+
|
|
1922
|
+
exports.removeFromWorkspace = function removeFromWorkspace(params) {
|
|
1923
|
+
return client.post('/removeFromWorkspace', { workspaceId: {"_id":"67a5366c745bb0e6735950dc","ownerId":"679ba73e4cc3ddc28f6ef6af","baseUrl":"https://web.zevo.io","members":[{"userId":"679ba73e4cc3ddc28f6ef6af","roles":["owner"]}],"createdAt":"2025-02-06T22:23:40.903Z","updatedAt":"2025-02-17T21:53:20.548Z","__v":2,"name":"Zevo DEV","subscriptionTier":"pro","stripeCustomerId":"cus_RnCdSdRYLJQl4Z","stripeSubscriptionId":"sub_1QtcEgIIV4Jx8vgxY7z8cKeC"}._id, ...params }).then(res => res.data);
|
|
1899
1924
|
};
|
|
1900
1925
|
|
|
1901
1926
|
exports.hasAPIKey = client.hasAPIKey;
|
|
@@ -2042,7 +2067,7 @@ module.exports = app => app.component('splash', {
|
|
|
2042
2067
|
data: () => ({ error: null }),
|
|
2043
2068
|
computed: {
|
|
2044
2069
|
workspaceName() {
|
|
2045
|
-
return {"_id":"67a5366c745bb0e6735950dc","ownerId":"679ba73e4cc3ddc28f6ef6af","baseUrl":"https://web.zevo.io","members":[{"userId":"679ba73e4cc3ddc28f6ef6af","roles":["owner"]}
|
|
2070
|
+
return {"_id":"67a5366c745bb0e6735950dc","ownerId":"679ba73e4cc3ddc28f6ef6af","baseUrl":"https://web.zevo.io","members":[{"userId":"679ba73e4cc3ddc28f6ef6af","roles":["owner"]}],"createdAt":"2025-02-06T22:23:40.903Z","updatedAt":"2025-02-17T21:53:20.548Z","__v":2,"name":"Zevo DEV","subscriptionTier":"pro","stripeCustomerId":"cus_RnCdSdRYLJQl4Z","stripeSubscriptionId":"sub_1QtcEgIIV4Jx8vgxY7z8cKeC"}.name;
|
|
2046
2071
|
}
|
|
2047
2072
|
},
|
|
2048
2073
|
async mounted() {
|
|
@@ -2119,7 +2144,8 @@ module.exports = app => app.component('team', {
|
|
|
2119
2144
|
workspace: null,
|
|
2120
2145
|
users: null,
|
|
2121
2146
|
invitations: null,
|
|
2122
|
-
showNewInvitationModal: false
|
|
2147
|
+
showNewInvitationModal: false,
|
|
2148
|
+
showRemoveModal: null
|
|
2123
2149
|
}),
|
|
2124
2150
|
async mounted() {
|
|
2125
2151
|
const { workspace, users, invitations } = await mothership.getWorkspaceTeam();
|
|
@@ -2127,9 +2153,32 @@ module.exports = app => app.component('team', {
|
|
|
2127
2153
|
this.users = users;
|
|
2128
2154
|
this.invitations = invitations;
|
|
2129
2155
|
},
|
|
2156
|
+
computed: {
|
|
2157
|
+
paymentLink() {
|
|
2158
|
+
return 'https://buy.stripe.com/test_eVaeYa2jC7565Lq7ss?client_reference_id=' + this.workspace?._id;
|
|
2159
|
+
}
|
|
2160
|
+
},
|
|
2130
2161
|
methods: {
|
|
2131
2162
|
getRolesForUser(user) {
|
|
2132
2163
|
return this.workspace.members.find(member => member.userId === user._id)?.roles ?? [];
|
|
2164
|
+
},
|
|
2165
|
+
async removeFromWorkspace() {
|
|
2166
|
+
const { workspace, users } = await mothership.removeFromWorkspace({ userId: this.showRemoveModal._id });
|
|
2167
|
+
this.workspace = workspace;
|
|
2168
|
+
this.users = users;
|
|
2169
|
+
this.showRemoveModal = false;
|
|
2170
|
+
},
|
|
2171
|
+
async getWorkspaceCustomerPortalLink() {
|
|
2172
|
+
const { url } = await mothership.getWorkspaceCustomerPortalLink();
|
|
2173
|
+
window.open(url, '_blank');
|
|
2174
|
+
|
|
2175
|
+
const interval = setInterval(async () => {
|
|
2176
|
+
const { workspace } = await mothership.getWorkspaceTeam();
|
|
2177
|
+
if (workspace.subscriptionTier) {
|
|
2178
|
+
this.workspace = workspace;
|
|
2179
|
+
clearInterval(interval);
|
|
2180
|
+
}
|
|
2181
|
+
}, 15000);
|
|
2133
2182
|
}
|
|
2134
2183
|
}
|
|
2135
2184
|
});
|
|
@@ -3206,7 +3255,7 @@ module.exports = "<div class=\"list-subdocument tooltip\">\n <pre>\n <code r
|
|
|
3206
3255
|
/***/ ((module) => {
|
|
3207
3256
|
|
|
3208
3257
|
"use strict";
|
|
3209
|
-
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";
|
|
3258
|
+
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\n.modal-container .modal-exit:hover {\n background-color: #f1f5ff;\n}\n";
|
|
3210
3259
|
|
|
3211
3260
|
/***/ }),
|
|
3212
3261
|
|
|
@@ -3239,7 +3288,7 @@ module.exports = ".models {\n position: relative;\n display: flex;\n flex-dir
|
|
|
3239
3288
|
/***/ ((module) => {
|
|
3240
3289
|
|
|
3241
3290
|
"use strict";
|
|
3242
|
-
module.exports = "<div class=\"models\">\n <div>\n <div class=\"flex grow flex-col gap-y-5 overflow-auto border-r border-gray-200 bg-white px-2 h-[calc(100vh-55px)] w-48\">\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 truncate 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 class=\"relative h-[42px]\">\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 focus:ring-1 focus:ring-ultramarine-200 focus:ring-offset-0 focus:outline-none\" 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=\"
|
|
3291
|
+
module.exports = "<div class=\"models\">\n <div>\n <div class=\"flex grow flex-col gap-y-5 overflow-auto border-r border-gray-200 bg-white px-2 h-[calc(100vh-55px)] w-48\">\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 truncate 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 class=\"relative h-[42px]\">\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 border border-gray-300 outline-gray-300 text-lg focus:ring-1 focus:ring-ultramarine-200 focus:ring-offset-0 focus:outline-none\" 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=\"openFieldSelection\"\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 relative\">\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 </div>\n\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\" class=\"w-5 flex items-center\">\n <input class=\"mt-0 h-4 w-4 rounded border-gray-300 text-sky-600 focus:ring-sky-600 accent-sky-600\" type=\"checkbox\" :id=\"'path.path'+index\" @change=\"addOrRemove(path)\" :value=\"path.path\" :checked=\"isSelected(path.path)\" />\n <div class=\"ml-2 text-gray-700 grow shrink text-left\">\n <label :for=\"'path' + index\">{{path.path}}</label>\n </div>\n </div>\n <div class=\"mt-4 flex gap-2\">\n <button type=\"submit\" @click=\"filterDocuments()\" 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\">Filter Selection</button>\n <button type=\"submit\" @click=\"deselectAll()\" 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\">Deselect All</button>\n <button type=\"submit\" @click=\"resetDocuments()\" class=\"rounded-md bg-gray-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-gray-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600\" >Cancel</button>\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";
|
|
3243
3292
|
|
|
3244
3293
|
/***/ }),
|
|
3245
3294
|
|
|
@@ -3261,7 +3310,7 @@ module.exports = ".navbar {\n width: 100%;\n background-color: #eee;\n}\n\n.ac
|
|
|
3261
3310
|
/***/ ((module) => {
|
|
3262
3311
|
|
|
3263
3312
|
"use strict";
|
|
3264
|
-
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-[90%] 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 <router-link to=\"team\" v-if=\"canViewTeam\" @click=\"showFlyout = false\" 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\">Team</router-link>\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";
|
|
3313
|
+
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-[90%] 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 <router-link to=\"/team\" v-if=\"canViewTeam\" @click=\"showFlyout = false\" 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\">Team</router-link>\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";
|
|
3265
3314
|
|
|
3266
3315
|
/***/ }),
|
|
3267
3316
|
|
|
@@ -3294,7 +3343,7 @@ module.exports = "<div class=\"p-1\">\n <form class=\"space-y-4\">\n <div cl
|
|
|
3294
3343
|
/***/ ((module) => {
|
|
3295
3344
|
|
|
3296
3345
|
"use strict";
|
|
3297
|
-
module.exports = "<div class=\"mx-auto max-w-5xl py-6 px-2\">\n <div class=\"text-xl font-bold\">\n
|
|
3346
|
+
module.exports = "<div class=\"mx-auto max-w-5xl py-6 px-2 flex flex-col gap-8\">\n <div>\n <div class=\"text-xl font-bold\">\n Subscription Details\n </div>\n <div v-if=\"workspace && workspace.subscriptionTier\" class=\"mt-4 flex justify-between items-center\">\n <div>\n <span class=\"font-bold\">Tier:</span> {{workspace.subscriptionTier ?? 'No subscription'}}\n </div>\n <div>\n <async-button\n type=\"submit\"\n @click=\"getWorkspaceCustomerPortalLink\"\n class=\"inline-flex items-center justify-center rounded-md border border-transparent bg-ultramarine-600 py-1 px-2 text-sm font-medium text-white shadow-sm hover:bg-ultramarine-500 focus:outline-none focus:ring-2 focus:ring-forest-green-500 focus:ring-offset-2\">\n View in Stripe\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-4 h-4 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </async-button>\n </div>\n </div>\n <div v-if=\"workspace && !workspace.subscriptionTier\" class=\"mt-4 flex justify-between items-center\">\n <div>\n <span class=\"font-bold\">No active subscription</span>\n <div class=\"text-sm text-gray-700\">\n You won't be able to invite your team until you activate a subscription\n </div>\n </div>\n <div>\n <a\n :href=\"paymentLink\"\n target=\"_blank\"\n class=\"inline-flex items-center justify-center rounded-md border border-transparent bg-ultramarine-600 py-1 px-2 text-sm font-medium text-white shadow-sm hover:bg-ultramarine-500 focus:outline-none focus:ring-2 focus:ring-ultramarine-500 focus:ring-offset-2\">\n Subscribe With Stripe\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"w-4 h-4 ml-1\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25\" />\n </svg>\n </a>\n </div>\n </div>\n </div>\n <div>\n <div class=\"text-xl font-bold\">\n Current Members\n </div>\n <ul role=\"list\" class=\"divide-y divide-gray-100\">\n <li class=\"flex justify-between gap-x-6 py-5\" v-for=\"user in users\">\n <div class=\"flex min-w-0 gap-x-4\">\n <img class=\"size-12 flex-none rounded-full bg-gray-50\" :src=\"user.picture ?? 'images/logo.svg'\" alt=\"\">\n <div class=\"min-w-0 flex-auto\">\n <p class=\"text-sm/6 font-semibold text-gray-900\">\n {{user.name}}\n <span v-if=\"user.isFreeUser\" class=\"inline-flex items-center rounded-md bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20\">Free</span>\n </p>\n <p class=\"mt-1 truncate text-xs/5 text-gray-500\">{{user.email ?? 'No Email'}}</p>\n </div>\n </div>\n <div class=\"hidden shrink-0 sm:flex sm:flex-col sm:items-end\">\n <p class=\"text-sm/6 text-gray-900 capitalize\">{{getRolesForUser(user).join(', ')}}</p>\n <div class=\"flex gap-3\">\n <p class=\"mt-1 text-xs/5 text-gray-500 cursor-pointer\">\n Edit\n </p>\n <p class=\"mt-1 text-xs/5 text-valencia-500 cursor-pointer\" @click=\"showRemoveModal = user\">\n Remove\n </p>\n </div>\n </div>\n </li>\n </ul>\n </div>\n <div>\n <div class=\"flex items-center justify-between\">\n <div class=\"text-xl font-bold\">\n Invitations\n </div>\n <div class=\"mt-4 sm:ml-16 sm:mt-0 sm:flex-none\">\n <button\n type=\"button\"\n @click=\"showNewInvitationModal = true\"\n :disabled=\"workspace && !workspace.subscriptionTier\"\n class=\"block rounded-md bg-ultramarine-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 disabled:bg-gray-500 disabled:cursor-not-allowed focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600\">\n New Invitation\n <svg class=\"inline w-4 h-4 ml-1\" v-if=\"workspace && !workspace.subscriptionTier\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path fill-rule=\"evenodd\" d=\"M12 1.5a5.25 5.25 0 00-5.25 5.25v3a3 3 0 00-3 3v6.75a3 3 0 003 3h10.5a3 3 0 003-3v-6.75a3 3 0 00-3-3v-3c0-2.9-2.35-5.25-5.25-5.25zm3.75 8.25v-3a3.75 3.75 0 10-7.5 0v3h7.5z\" clip-rule=\"evenodd\" />\n </svg>\n </button>\n </div>\n </div>\n <div class=\"mt-8 flow-root\" v-if=\"invitations?.length > 0\">\n <div class=\"-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8\">\n <div class=\"inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8\">\n <table class=\"min-w-full divide-y divide-gray-300\">\n <thead>\n <tr>\n <th scope=\"col\" class=\"py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-0\">GitHub Username</th>\n <th scope=\"col\" class=\"px-3 py-3.5 text-left text-sm font-semibold text-gray-900\">Email</th>\n <th scope=\"col\" class=\"px-3 py-3.5 text-left text-sm font-semibold text-gray-900\">Status</th>\n <th scope=\"col\" class=\"px-3 py-3.5 text-left text-sm font-semibold text-gray-900\">Role</th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr v-for=\"invitation in invitations\">\n <td class=\"whitespace-nowrap py-5 pl-4 pr-3 text-sm sm:pl-0\">\n {{invitation.githubUsername}}\n </td>\n <td class=\"whitespace-nowrap px-3 py-5 text-sm text-gray-500\">\n {{invitation.email}}\n </td>\n <td class=\"whitespace-nowrap px-3 py-5 text-sm text-gray-500\">\n <span class=\"inline-flex items-center rounded-md bg-gray-50 px-2 py-1 text-xs font-medium text-gray-700 ring-1 ring-inset ring-gray-600/20\">\n Pending\n </span>\n </td>\n <td class=\"whitespace-nowrap px-3 py-5 text-sm text-gray-500\">\n {{invitation.roles.join(', ')}}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n\n <div v-if=\"invitations?.length === 0\" class=\"mt-4\">\n <div class=\"text-center\">\n <svg class=\"mx-auto size-12 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path vector-effect=\"non-scaling-stroke\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z\" />\n </svg>\n <h3 class=\"mt-2 text-sm font-semibold text-gray-900\">No invitations</h3>\n <p class=\"mt-1 text-sm text-gray-500\">You have no outstanding invitations</p>\n </div>\n </div>\n </div>\n\n <modal v-if=\"showNewInvitationModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"showNewInvitationModal = false\">×</div>\n <new-invitation @close=\"showNewInvitationModal = false\" @invitationCreated=\"invitations.push($event.invitation)\"></new-invitation>\n </template>\n </modal>\n\n <modal v-if=\"showRemoveModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"showRemoveModal = false\">×</div>\n <div>\n Are you sure you want to remove user <span class=\"font-bold\">{{showRemoveModal.githubUsername}}</span> from this workspace?\n </div>\n <div class=\"mt-6 grid grid-cols-2 gap-4\">\n <async-button\n @click=\"removeFromWorkspace(showConfirmDeleteModal)\"\n class=\"border-0 mt-0 flex w-full items-center justify-center gap-3 rounded-md bg-valencia-500 hover:bg-valencia-400 px-3 py-1.5 text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-orange-400\">\n <span class=\"text-sm font-semibold leading-6\">Yes, Remove</span>\n </async-button>\n\n <span @click=\"showRemoveModal = null\" class=\"cursor-pointer flex w-full items-center justify-center gap-3 rounded-md bg-slate-500 hover:bg-slate-400 px-3 py-1.5 text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-slate-400\">\n <span class=\"text-sm font-semibold leading-6\">Cancel</span>\n </span>\n </div>\n </template>\n </modal>\n</div>\n";
|
|
3298
3347
|
|
|
3299
3348
|
/***/ }),
|
|
3300
3349
|
|
package/frontend/public/tw.css
CHANGED
|
@@ -686,6 +686,14 @@ video {
|
|
|
686
686
|
margin-bottom: 1rem;
|
|
687
687
|
}
|
|
688
688
|
|
|
689
|
+
.ml-1 {
|
|
690
|
+
margin-left: 0.25rem;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
.ml-2 {
|
|
694
|
+
margin-left: 0.5rem;
|
|
695
|
+
}
|
|
696
|
+
|
|
689
697
|
.ml-3 {
|
|
690
698
|
margin-left: 0.75rem;
|
|
691
699
|
}
|
|
@@ -702,6 +710,10 @@ video {
|
|
|
702
710
|
margin-right: 0.5rem;
|
|
703
711
|
}
|
|
704
712
|
|
|
713
|
+
.mt-0 {
|
|
714
|
+
margin-top: 0px;
|
|
715
|
+
}
|
|
716
|
+
|
|
705
717
|
.mt-1 {
|
|
706
718
|
margin-top: 0.25rem;
|
|
707
719
|
}
|
|
@@ -777,6 +789,10 @@ video {
|
|
|
777
789
|
height: 2rem;
|
|
778
790
|
}
|
|
779
791
|
|
|
792
|
+
.h-4 {
|
|
793
|
+
height: 1rem;
|
|
794
|
+
}
|
|
795
|
+
|
|
780
796
|
.h-48 {
|
|
781
797
|
height: 12rem;
|
|
782
798
|
}
|
|
@@ -813,6 +829,10 @@ video {
|
|
|
813
829
|
max-height: 50vh;
|
|
814
830
|
}
|
|
815
831
|
|
|
832
|
+
.w-4 {
|
|
833
|
+
width: 1rem;
|
|
834
|
+
}
|
|
835
|
+
|
|
816
836
|
.w-48 {
|
|
817
837
|
width: 12rem;
|
|
818
838
|
}
|
|
@@ -833,10 +853,6 @@ video {
|
|
|
833
853
|
width: 100%;
|
|
834
854
|
}
|
|
835
855
|
|
|
836
|
-
.w-72 {
|
|
837
|
-
width: 18rem;
|
|
838
|
-
}
|
|
839
|
-
|
|
840
856
|
.min-w-0 {
|
|
841
857
|
min-width: 0px;
|
|
842
858
|
}
|
|
@@ -903,6 +919,10 @@ video {
|
|
|
903
919
|
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
904
920
|
}
|
|
905
921
|
|
|
922
|
+
.grid-cols-2 {
|
|
923
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
924
|
+
}
|
|
925
|
+
|
|
906
926
|
.flex-row {
|
|
907
927
|
flex-direction: row;
|
|
908
928
|
}
|
|
@@ -935,10 +955,18 @@ video {
|
|
|
935
955
|
gap: 0.5rem;
|
|
936
956
|
}
|
|
937
957
|
|
|
958
|
+
.gap-3 {
|
|
959
|
+
gap: 0.75rem;
|
|
960
|
+
}
|
|
961
|
+
|
|
938
962
|
.gap-4 {
|
|
939
963
|
gap: 1rem;
|
|
940
964
|
}
|
|
941
965
|
|
|
966
|
+
.gap-8 {
|
|
967
|
+
gap: 2rem;
|
|
968
|
+
}
|
|
969
|
+
|
|
942
970
|
.gap-x-4 {
|
|
943
971
|
-moz-column-gap: 1rem;
|
|
944
972
|
column-gap: 1rem;
|
|
@@ -1016,10 +1044,6 @@ video {
|
|
|
1016
1044
|
overflow-x: auto;
|
|
1017
1045
|
}
|
|
1018
1046
|
|
|
1019
|
-
.overflow-y-auto {
|
|
1020
|
-
overflow-y: auto;
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
1047
|
.truncate {
|
|
1024
1048
|
overflow: hidden;
|
|
1025
1049
|
text-overflow: ellipsis;
|
|
@@ -1143,11 +1167,21 @@ video {
|
|
|
1143
1167
|
background-color: rgb(107 114 128 / var(--tw-bg-opacity));
|
|
1144
1168
|
}
|
|
1145
1169
|
|
|
1170
|
+
.bg-gray-600 {
|
|
1171
|
+
--tw-bg-opacity: 1;
|
|
1172
|
+
background-color: rgb(75 85 99 / var(--tw-bg-opacity));
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1146
1175
|
.bg-gray-800 {
|
|
1147
1176
|
--tw-bg-opacity: 1;
|
|
1148
1177
|
background-color: rgb(31 41 55 / var(--tw-bg-opacity));
|
|
1149
1178
|
}
|
|
1150
1179
|
|
|
1180
|
+
.bg-green-50 {
|
|
1181
|
+
--tw-bg-opacity: 1;
|
|
1182
|
+
background-color: rgb(240 253 244 / var(--tw-bg-opacity));
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1151
1185
|
.bg-green-600 {
|
|
1152
1186
|
--tw-bg-opacity: 1;
|
|
1153
1187
|
background-color: rgb(22 163 74 / var(--tw-bg-opacity));
|
|
@@ -1173,6 +1207,11 @@ video {
|
|
|
1173
1207
|
background-color: rgb(241 245 249 / var(--tw-bg-opacity));
|
|
1174
1208
|
}
|
|
1175
1209
|
|
|
1210
|
+
.bg-slate-500 {
|
|
1211
|
+
--tw-bg-opacity: 1;
|
|
1212
|
+
background-color: rgb(100 116 139 / var(--tw-bg-opacity));
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1176
1215
|
.bg-slate-600 {
|
|
1177
1216
|
--tw-bg-opacity: 1;
|
|
1178
1217
|
background-color: rgb(71 85 105 / var(--tw-bg-opacity));
|
|
@@ -1197,6 +1236,11 @@ video {
|
|
|
1197
1236
|
background-color: rgb(24 35 255 / var(--tw-bg-opacity));
|
|
1198
1237
|
}
|
|
1199
1238
|
|
|
1239
|
+
.bg-valencia-500 {
|
|
1240
|
+
--tw-bg-opacity: 1;
|
|
1241
|
+
background-color: rgb(220 73 73 / var(--tw-bg-opacity));
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1200
1244
|
.bg-valencia-600 {
|
|
1201
1245
|
--tw-bg-opacity: 1;
|
|
1202
1246
|
background-color: rgb(202 56 56 / var(--tw-bg-opacity));
|
|
@@ -1441,6 +1485,11 @@ video {
|
|
|
1441
1485
|
color: rgb(17 24 39 / var(--tw-text-opacity));
|
|
1442
1486
|
}
|
|
1443
1487
|
|
|
1488
|
+
.text-green-700 {
|
|
1489
|
+
--tw-text-opacity: 1;
|
|
1490
|
+
color: rgb(21 128 61 / var(--tw-text-opacity));
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1444
1493
|
.text-red-400 {
|
|
1445
1494
|
--tw-text-opacity: 1;
|
|
1446
1495
|
color: rgb(248 113 113 / var(--tw-text-opacity));
|
|
@@ -1456,6 +1505,11 @@ video {
|
|
|
1456
1505
|
color: rgb(153 27 27 / var(--tw-text-opacity));
|
|
1457
1506
|
}
|
|
1458
1507
|
|
|
1508
|
+
.text-sky-600 {
|
|
1509
|
+
--tw-text-opacity: 1;
|
|
1510
|
+
color: rgb(2 132 199 / var(--tw-text-opacity));
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1459
1513
|
.text-sky-800 {
|
|
1460
1514
|
--tw-text-opacity: 1;
|
|
1461
1515
|
color: rgb(7 89 133 / var(--tw-text-opacity));
|
|
@@ -1466,11 +1520,20 @@ video {
|
|
|
1466
1520
|
color: rgb(0 168 165 / var(--tw-text-opacity));
|
|
1467
1521
|
}
|
|
1468
1522
|
|
|
1523
|
+
.text-valencia-500 {
|
|
1524
|
+
--tw-text-opacity: 1;
|
|
1525
|
+
color: rgb(220 73 73 / var(--tw-text-opacity));
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1469
1528
|
.text-white {
|
|
1470
1529
|
--tw-text-opacity: 1;
|
|
1471
1530
|
color: rgb(255 255 255 / var(--tw-text-opacity));
|
|
1472
1531
|
}
|
|
1473
1532
|
|
|
1533
|
+
.accent-sky-600 {
|
|
1534
|
+
accent-color: #0284c7;
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1474
1537
|
.shadow-lg {
|
|
1475
1538
|
--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
|
|
1476
1539
|
--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
|
|
@@ -1535,6 +1598,10 @@ video {
|
|
|
1535
1598
|
--tw-ring-color: rgb(17 24 39 / 0.05);
|
|
1536
1599
|
}
|
|
1537
1600
|
|
|
1601
|
+
.ring-green-600\/20 {
|
|
1602
|
+
--tw-ring-color: rgb(22 163 74 / 0.2);
|
|
1603
|
+
}
|
|
1604
|
+
|
|
1538
1605
|
.filter {
|
|
1539
1606
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
1540
1607
|
}
|
|
@@ -1597,6 +1664,11 @@ video {
|
|
|
1597
1664
|
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
|
|
1598
1665
|
}
|
|
1599
1666
|
|
|
1667
|
+
.hover\:bg-gray-500:hover {
|
|
1668
|
+
--tw-bg-opacity: 1;
|
|
1669
|
+
background-color: rgb(107 114 128 / var(--tw-bg-opacity));
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1600
1672
|
.hover\:bg-gray-600:hover {
|
|
1601
1673
|
--tw-bg-opacity: 1;
|
|
1602
1674
|
background-color: rgb(75 85 99 / var(--tw-bg-opacity));
|
|
@@ -1612,6 +1684,11 @@ video {
|
|
|
1612
1684
|
background-color: rgb(220 38 38 / var(--tw-bg-opacity));
|
|
1613
1685
|
}
|
|
1614
1686
|
|
|
1687
|
+
.hover\:bg-slate-400:hover {
|
|
1688
|
+
--tw-bg-opacity: 1;
|
|
1689
|
+
background-color: rgb(148 163 184 / var(--tw-bg-opacity));
|
|
1690
|
+
}
|
|
1691
|
+
|
|
1615
1692
|
.hover\:bg-slate-500:hover {
|
|
1616
1693
|
--tw-bg-opacity: 1;
|
|
1617
1694
|
background-color: rgb(100 116 139 / var(--tw-bg-opacity));
|
|
@@ -1637,6 +1714,11 @@ video {
|
|
|
1637
1714
|
background-color: rgb(63 83 255 / var(--tw-bg-opacity));
|
|
1638
1715
|
}
|
|
1639
1716
|
|
|
1717
|
+
.hover\:bg-valencia-400:hover {
|
|
1718
|
+
--tw-bg-opacity: 1;
|
|
1719
|
+
background-color: rgb(235 126 126 / var(--tw-bg-opacity));
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1640
1722
|
.hover\:bg-valencia-500:hover {
|
|
1641
1723
|
--tw-bg-opacity: 1;
|
|
1642
1724
|
background-color: rgb(220 73 73 / var(--tw-bg-opacity));
|
|
@@ -1681,25 +1763,21 @@ video {
|
|
|
1681
1763
|
outline-color: #1823ff;
|
|
1682
1764
|
}
|
|
1683
1765
|
|
|
1684
|
-
.focus\:outline-ultramarine-50:focus {
|
|
1685
|
-
outline-color: #f1f5ff;
|
|
1686
|
-
}
|
|
1687
|
-
|
|
1688
1766
|
.focus\:ring-0:focus {
|
|
1689
1767
|
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
1690
1768
|
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
1691
1769
|
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
1692
1770
|
}
|
|
1693
1771
|
|
|
1694
|
-
.focus\:ring-
|
|
1772
|
+
.focus\:ring-1:focus {
|
|
1695
1773
|
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
1696
|
-
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(
|
|
1774
|
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
1697
1775
|
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
1698
1776
|
}
|
|
1699
1777
|
|
|
1700
|
-
.focus\:ring-
|
|
1778
|
+
.focus\:ring-2:focus {
|
|
1701
1779
|
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
1702
|
-
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(
|
|
1780
|
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
1703
1781
|
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
1704
1782
|
}
|
|
1705
1783
|
|
|
@@ -1728,29 +1806,34 @@ video {
|
|
|
1728
1806
|
--tw-ring-color: rgb(239 68 68 / var(--tw-ring-opacity));
|
|
1729
1807
|
}
|
|
1730
1808
|
|
|
1731
|
-
.focus\:ring-
|
|
1809
|
+
.focus\:ring-sky-600:focus {
|
|
1732
1810
|
--tw-ring-opacity: 1;
|
|
1733
|
-
--tw-ring-color: rgb(
|
|
1811
|
+
--tw-ring-color: rgb(2 132 199 / var(--tw-ring-opacity));
|
|
1734
1812
|
}
|
|
1735
1813
|
|
|
1736
|
-
.focus\:ring-ultramarine-
|
|
1814
|
+
.focus\:ring-ultramarine-200:focus {
|
|
1737
1815
|
--tw-ring-opacity: 1;
|
|
1738
|
-
--tw-ring-color: rgb(
|
|
1816
|
+
--tw-ring-color: rgb(206 218 255 / var(--tw-ring-opacity));
|
|
1739
1817
|
}
|
|
1740
1818
|
|
|
1741
|
-
.focus\:ring-ultramarine-
|
|
1819
|
+
.focus\:ring-ultramarine-500:focus {
|
|
1742
1820
|
--tw-ring-opacity: 1;
|
|
1743
|
-
--tw-ring-color: rgb(
|
|
1821
|
+
--tw-ring-color: rgb(63 83 255 / var(--tw-ring-opacity));
|
|
1744
1822
|
}
|
|
1745
1823
|
|
|
1746
|
-
.focus\:ring-
|
|
1747
|
-
--tw-ring-
|
|
1824
|
+
.focus\:ring-white:focus {
|
|
1825
|
+
--tw-ring-opacity: 1;
|
|
1826
|
+
--tw-ring-color: rgb(255 255 255 / var(--tw-ring-opacity));
|
|
1748
1827
|
}
|
|
1749
1828
|
|
|
1750
1829
|
.focus\:ring-offset-0:focus {
|
|
1751
1830
|
--tw-ring-offset-width: 0px;
|
|
1752
1831
|
}
|
|
1753
1832
|
|
|
1833
|
+
.focus\:ring-offset-2:focus {
|
|
1834
|
+
--tw-ring-offset-width: 2px;
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1754
1837
|
.focus\:ring-offset-gray-800:focus {
|
|
1755
1838
|
--tw-ring-offset-color: #1f2937;
|
|
1756
1839
|
}
|
|
@@ -1775,10 +1858,18 @@ video {
|
|
|
1775
1858
|
outline-color: #16a34a;
|
|
1776
1859
|
}
|
|
1777
1860
|
|
|
1861
|
+
.focus-visible\:outline-orange-400:focus-visible {
|
|
1862
|
+
outline-color: #fb923c;
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1778
1865
|
.focus-visible\:outline-red-600:focus-visible {
|
|
1779
1866
|
outline-color: #dc2626;
|
|
1780
1867
|
}
|
|
1781
1868
|
|
|
1869
|
+
.focus-visible\:outline-slate-400:focus-visible {
|
|
1870
|
+
outline-color: #94a3b8;
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1782
1873
|
.focus-visible\:outline-slate-600:focus-visible {
|
|
1783
1874
|
outline-color: #475569;
|
|
1784
1875
|
}
|
|
@@ -1791,6 +1882,15 @@ video {
|
|
|
1791
1882
|
outline-color: #1823ff;
|
|
1792
1883
|
}
|
|
1793
1884
|
|
|
1885
|
+
.disabled\:cursor-not-allowed:disabled {
|
|
1886
|
+
cursor: not-allowed;
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
.disabled\:bg-gray-500:disabled {
|
|
1890
|
+
--tw-bg-opacity: 1;
|
|
1891
|
+
background-color: rgb(107 114 128 / var(--tw-bg-opacity));
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1794
1894
|
@media (min-width: 640px) {
|
|
1795
1895
|
.sm\:-mx-6 {
|
|
1796
1896
|
margin-left: -1.5rem;
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
<div class="documents-menu">
|
|
29
29
|
<div class="flex flex-row items-center w-full gap-2">
|
|
30
30
|
<form @submit.prevent="search" class="flex-grow m-0">
|
|
31
|
-
<input class="w-full rounded-md p-1 outline-gray-300 text-lg focus:ring-1 focus:ring-ultramarine-200 focus:ring-offset-0 focus:outline-none" type="text" placeholder="Filter or text" v-model="searchText" />
|
|
31
|
+
<input class="w-full rounded-md p-1 border border-gray-300 outline-gray-300 text-lg focus:ring-1 focus:ring-ultramarine-200 focus:ring-offset-0 focus:outline-none" type="text" placeholder="Filter or text" v-model="searchText" />
|
|
32
32
|
</form>
|
|
33
33
|
<div>
|
|
34
34
|
<span v-if="status === 'loading'">Loading ...</span>
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
Create
|
|
48
48
|
</button>
|
|
49
49
|
<button
|
|
50
|
-
@click="
|
|
50
|
+
@click="openFieldSelection"
|
|
51
51
|
type="button"
|
|
52
52
|
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">
|
|
53
53
|
Fields
|
|
@@ -121,15 +121,16 @@
|
|
|
121
121
|
<modal v-if="shouldShowFieldModal">
|
|
122
122
|
<template v-slot:body>
|
|
123
123
|
<div class="modal-exit" @click="shouldShowFieldModal = false; selectedPaths = [...filteredPaths];">×</div>
|
|
124
|
-
<div v-for="(path, index) in schemaPaths" :key="index"
|
|
125
|
-
<input type="checkbox" :id="'path.path'+index" @change="addOrRemove(path)" :value="path.path" :checked="isSelected(path.path)" />
|
|
126
|
-
<
|
|
124
|
+
<div v-for="(path, index) in schemaPaths" :key="index" class="w-5 flex items-center">
|
|
125
|
+
<input class="mt-0 h-4 w-4 rounded border-gray-300 text-sky-600 focus:ring-sky-600 accent-sky-600" type="checkbox" :id="'path.path'+index" @change="addOrRemove(path)" :value="path.path" :checked="isSelected(path.path)" />
|
|
126
|
+
<div class="ml-2 text-gray-700 grow shrink text-left">
|
|
127
|
+
<label :for="'path' + index">{{path.path}}</label>
|
|
128
|
+
</div>
|
|
127
129
|
</div>
|
|
128
|
-
<div
|
|
129
|
-
<button type="submit" @click="filterDocuments()"
|
|
130
|
-
<button type="submit" @click="deselectAll()" class="
|
|
131
|
-
<button type="submit" @click="resetDocuments()" class="gray">Cancel</button>
|
|
132
|
-
|
|
130
|
+
<div class="mt-4 flex gap-2">
|
|
131
|
+
<button type="submit" @click="filterDocuments()" 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">Filter Selection</button>
|
|
132
|
+
<button type="submit" @click="deselectAll()" 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">Deselect All</button>
|
|
133
|
+
<button type="submit" @click="resetDocuments()" class="rounded-md bg-gray-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-gray-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600" >Cancel</button>
|
|
133
134
|
</div>
|
|
134
135
|
</template>
|
|
135
136
|
</modal>
|
|
@@ -211,8 +211,25 @@ module.exports = app => app.component('models', {
|
|
|
211
211
|
}).map(key => this.selectedPaths[key]);
|
|
212
212
|
}
|
|
213
213
|
},
|
|
214
|
+
openFieldSelection() {
|
|
215
|
+
if (this.$route.query?.fields) {
|
|
216
|
+
this.selectedPaths.length = 0;
|
|
217
|
+
console.log('there are fields in play', this.$route.query.fields)
|
|
218
|
+
const fields = this.$route.query.fields.split(',');
|
|
219
|
+
for (let i = 0; i < fields.length; i++) {
|
|
220
|
+
this.selectedPaths.push({ path: fields[i] });
|
|
221
|
+
}
|
|
222
|
+
} else {
|
|
223
|
+
this.selectedPaths = [{ path: '_id' }];
|
|
224
|
+
}
|
|
225
|
+
this.shouldShowFieldModal = true;
|
|
226
|
+
},
|
|
214
227
|
filterDocuments() {
|
|
215
|
-
this.
|
|
228
|
+
if (this.selectedPaths.length > 0) {
|
|
229
|
+
this.filteredPaths = [...this.selectedPaths];
|
|
230
|
+
} else {
|
|
231
|
+
this.filteredPaths.length = 0;
|
|
232
|
+
}
|
|
216
233
|
this.shouldShowFieldModal = false;
|
|
217
234
|
const selectedParams = this.filteredPaths.map(x => x.path).join(',');
|
|
218
235
|
this.query.fields = selectedParams;
|
|
@@ -24,16 +24,24 @@ exports.getWorkspaceTeam = function getWorkspaceTeam() {
|
|
|
24
24
|
return client.post('/getWorkspaceTeam', { workspaceId: config__workspace._id }).then(res => res.data);
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
exports.
|
|
28
|
-
return client.post('/
|
|
27
|
+
exports.getWorkspaceCustomerPortalLink = function getWorkspaceCustomerPortalLink(params) {
|
|
28
|
+
return client.post('/getWorkspaceCustomerPortalLink', { workspaceId: config__workspace._id, ...params }).then(res => res.data);
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
exports.github = function github(code) {
|
|
32
32
|
return client.post('/github', { code, workspaceId: config__workspace._id }).then(res => res.data);
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
exports.inviteToWorkspace = function inviteToWorkspace(params) {
|
|
36
|
+
return client.post('/inviteToWorkspace', { workspaceId: config__workspace._id, ...params }).then(res => res.data);
|
|
37
|
+
};
|
|
38
|
+
|
|
35
39
|
exports.me = function me() {
|
|
36
40
|
return client.post('/me', { workspaceId: config__workspace._id }).then(res => res.data);
|
|
37
41
|
};
|
|
38
42
|
|
|
43
|
+
exports.removeFromWorkspace = function removeFromWorkspace(params) {
|
|
44
|
+
return client.post('/removeFromWorkspace', { workspaceId: config__workspace._id, ...params }).then(res => res.data);
|
|
45
|
+
};
|
|
46
|
+
|
|
39
47
|
exports.hasAPIKey = client.hasAPIKey;
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
</div>
|
|
37
37
|
|
|
38
38
|
<div v-if="showFlyout" class="absolute right-0 z-10 top-[90%] 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">
|
|
39
|
-
<router-link to="team" v-if="canViewTeam" @click="showFlyout = false" 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">Team</router-link>
|
|
39
|
+
<router-link to="/team" v-if="canViewTeam" @click="showFlyout = false" 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">Team</router-link>
|
|
40
40
|
<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>
|
|
41
41
|
</div>
|
|
42
42
|
</div>
|
|
@@ -1,23 +1,75 @@
|
|
|
1
|
-
<div class="mx-auto max-w-5xl py-6 px-2">
|
|
2
|
-
<div
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
<
|
|
7
|
-
<div
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
<div class="mx-auto max-w-5xl py-6 px-2 flex flex-col gap-8">
|
|
2
|
+
<div>
|
|
3
|
+
<div class="text-xl font-bold">
|
|
4
|
+
Subscription Details
|
|
5
|
+
</div>
|
|
6
|
+
<div v-if="workspace && workspace.subscriptionTier" class="mt-4 flex justify-between items-center">
|
|
7
|
+
<div>
|
|
8
|
+
<span class="font-bold">Tier:</span> {{workspace.subscriptionTier ?? 'No subscription'}}
|
|
9
|
+
</div>
|
|
10
|
+
<div>
|
|
11
|
+
<async-button
|
|
12
|
+
type="submit"
|
|
13
|
+
@click="getWorkspaceCustomerPortalLink"
|
|
14
|
+
class="inline-flex items-center justify-center rounded-md border border-transparent bg-ultramarine-600 py-1 px-2 text-sm font-medium text-white shadow-sm hover:bg-ultramarine-500 focus:outline-none focus:ring-2 focus:ring-forest-green-500 focus:ring-offset-2">
|
|
15
|
+
View in Stripe
|
|
16
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 ml-1">
|
|
17
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" />
|
|
18
|
+
</svg>
|
|
19
|
+
</async-button>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
<div v-if="workspace && !workspace.subscriptionTier" class="mt-4 flex justify-between items-center">
|
|
23
|
+
<div>
|
|
24
|
+
<span class="font-bold">No active subscription</span>
|
|
25
|
+
<div class="text-sm text-gray-700">
|
|
26
|
+
You won't be able to invite your team until you activate a subscription
|
|
12
27
|
</div>
|
|
13
28
|
</div>
|
|
14
|
-
<div
|
|
15
|
-
<
|
|
16
|
-
|
|
29
|
+
<div>
|
|
30
|
+
<a
|
|
31
|
+
:href="paymentLink"
|
|
32
|
+
target="_blank"
|
|
33
|
+
class="inline-flex items-center justify-center rounded-md border border-transparent bg-ultramarine-600 py-1 px-2 text-sm font-medium text-white shadow-sm hover:bg-ultramarine-500 focus:outline-none focus:ring-2 focus:ring-ultramarine-500 focus:ring-offset-2">
|
|
34
|
+
Subscribe With Stripe
|
|
35
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4 ml-1">
|
|
36
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" />
|
|
37
|
+
</svg>
|
|
38
|
+
</a>
|
|
17
39
|
</div>
|
|
18
|
-
</
|
|
19
|
-
</
|
|
20
|
-
<div
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
<div>
|
|
43
|
+
<div class="text-xl font-bold">
|
|
44
|
+
Current Members
|
|
45
|
+
</div>
|
|
46
|
+
<ul role="list" class="divide-y divide-gray-100">
|
|
47
|
+
<li class="flex justify-between gap-x-6 py-5" v-for="user in users">
|
|
48
|
+
<div class="flex min-w-0 gap-x-4">
|
|
49
|
+
<img class="size-12 flex-none rounded-full bg-gray-50" :src="user.picture ?? 'images/logo.svg'" alt="">
|
|
50
|
+
<div class="min-w-0 flex-auto">
|
|
51
|
+
<p class="text-sm/6 font-semibold text-gray-900">
|
|
52
|
+
{{user.name}}
|
|
53
|
+
<span v-if="user.isFreeUser" class="inline-flex items-center rounded-md bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-600/20">Free</span>
|
|
54
|
+
</p>
|
|
55
|
+
<p class="mt-1 truncate text-xs/5 text-gray-500">{{user.email ?? 'No Email'}}</p>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
<div class="hidden shrink-0 sm:flex sm:flex-col sm:items-end">
|
|
59
|
+
<p class="text-sm/6 text-gray-900 capitalize">{{getRolesForUser(user).join(', ')}}</p>
|
|
60
|
+
<div class="flex gap-3">
|
|
61
|
+
<p class="mt-1 text-xs/5 text-gray-500 cursor-pointer">
|
|
62
|
+
Edit
|
|
63
|
+
</p>
|
|
64
|
+
<p class="mt-1 text-xs/5 text-valencia-500 cursor-pointer" @click="showRemoveModal = user">
|
|
65
|
+
Remove
|
|
66
|
+
</p>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</li>
|
|
70
|
+
</ul>
|
|
71
|
+
</div>
|
|
72
|
+
<div>
|
|
21
73
|
<div class="flex items-center justify-between">
|
|
22
74
|
<div class="text-xl font-bold">
|
|
23
75
|
Invitations
|
|
@@ -26,8 +78,12 @@
|
|
|
26
78
|
<button
|
|
27
79
|
type="button"
|
|
28
80
|
@click="showNewInvitationModal = true"
|
|
29
|
-
|
|
81
|
+
:disabled="workspace && !workspace.subscriptionTier"
|
|
82
|
+
class="block rounded-md bg-ultramarine-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 disabled:bg-gray-500 disabled:cursor-not-allowed focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600">
|
|
30
83
|
New Invitation
|
|
84
|
+
<svg class="inline w-4 h-4 ml-1" v-if="workspace && !workspace.subscriptionTier" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
|
85
|
+
<path fill-rule="evenodd" d="M12 1.5a5.25 5.25 0 00-5.25 5.25v3a3 3 0 00-3 3v6.75a3 3 0 003 3h10.5a3 3 0 003-3v-6.75a3 3 0 00-3-3v-3c0-2.9-2.35-5.25-5.25-5.25zm3.75 8.25v-3a3.75 3.75 0 10-7.5 0v3h7.5z" clip-rule="evenodd" />
|
|
86
|
+
</svg>
|
|
31
87
|
</button>
|
|
32
88
|
</div>
|
|
33
89
|
</div>
|
|
@@ -83,4 +139,24 @@
|
|
|
83
139
|
<new-invitation @close="showNewInvitationModal = false" @invitationCreated="invitations.push($event.invitation)"></new-invitation>
|
|
84
140
|
</template>
|
|
85
141
|
</modal>
|
|
142
|
+
|
|
143
|
+
<modal v-if="showRemoveModal">
|
|
144
|
+
<template v-slot:body>
|
|
145
|
+
<div class="modal-exit" @click="showRemoveModal = false">×</div>
|
|
146
|
+
<div>
|
|
147
|
+
Are you sure you want to remove user <span class="font-bold">{{showRemoveModal.githubUsername}}</span> from this workspace?
|
|
148
|
+
</div>
|
|
149
|
+
<div class="mt-6 grid grid-cols-2 gap-4">
|
|
150
|
+
<async-button
|
|
151
|
+
@click="removeFromWorkspace(showConfirmDeleteModal)"
|
|
152
|
+
class="border-0 mt-0 flex w-full items-center justify-center gap-3 rounded-md bg-valencia-500 hover:bg-valencia-400 px-3 py-1.5 text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-orange-400">
|
|
153
|
+
<span class="text-sm font-semibold leading-6">Yes, Remove</span>
|
|
154
|
+
</async-button>
|
|
155
|
+
|
|
156
|
+
<span @click="showRemoveModal = null" class="cursor-pointer flex w-full items-center justify-center gap-3 rounded-md bg-slate-500 hover:bg-slate-400 px-3 py-1.5 text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-slate-400">
|
|
157
|
+
<span class="text-sm font-semibold leading-6">Cancel</span>
|
|
158
|
+
</span>
|
|
159
|
+
</div>
|
|
160
|
+
</template>
|
|
161
|
+
</modal>
|
|
86
162
|
</div>
|
|
@@ -9,7 +9,8 @@ module.exports = app => app.component('team', {
|
|
|
9
9
|
workspace: null,
|
|
10
10
|
users: null,
|
|
11
11
|
invitations: null,
|
|
12
|
-
showNewInvitationModal: false
|
|
12
|
+
showNewInvitationModal: false,
|
|
13
|
+
showRemoveModal: null
|
|
13
14
|
}),
|
|
14
15
|
async mounted() {
|
|
15
16
|
const { workspace, users, invitations } = await mothership.getWorkspaceTeam();
|
|
@@ -17,9 +18,24 @@ module.exports = app => app.component('team', {
|
|
|
17
18
|
this.users = users;
|
|
18
19
|
this.invitations = invitations;
|
|
19
20
|
},
|
|
21
|
+
computed: {
|
|
22
|
+
paymentLink() {
|
|
23
|
+
return 'https://buy.stripe.com/test_eVaeYa2jC7565Lq7ss?client_reference_id=' + this.workspace?._id;
|
|
24
|
+
}
|
|
25
|
+
},
|
|
20
26
|
methods: {
|
|
21
27
|
getRolesForUser(user) {
|
|
22
28
|
return this.workspace.members.find(member => member.userId === user._id)?.roles ?? [];
|
|
29
|
+
},
|
|
30
|
+
async removeFromWorkspace() {
|
|
31
|
+
const { workspace, users } = await mothership.removeFromWorkspace({ userId: this.showRemoveModal._id });
|
|
32
|
+
this.workspace = workspace;
|
|
33
|
+
this.users = users;
|
|
34
|
+
this.showRemoveModal = false;
|
|
35
|
+
},
|
|
36
|
+
async getWorkspaceCustomerPortalLink() {
|
|
37
|
+
const { url } = await mothership.getWorkspaceCustomerPortalLink();
|
|
38
|
+
window.open(url, '_self');
|
|
23
39
|
}
|
|
24
40
|
}
|
|
25
41
|
});
|