@mongoosejs/studio 0.0.116 → 0.0.117

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.
@@ -41,14 +41,23 @@ module.exports = ({ db }) => async function getDashboard(params) {
41
41
  return { dashboard, error: { message: error.message } };
42
42
  }
43
43
 
44
- const { dashboardResult } = await startExec.then(({ dashboardResult }) => {
45
- if (!dashboardResult) {
46
- return;
47
- }
48
- return completeDashboardEvaluate(dashboardResult._id, $workspaceId, authorization, result);
49
- });
44
+ try {
45
+ const { dashboardResult } = await startExec.then(({ dashboardResult }) => {
46
+ if (!dashboardResult) {
47
+ return {};
48
+ }
49
+ return completeDashboardEvaluate(
50
+ dashboardResult._id,
51
+ $workspaceId,
52
+ authorization,
53
+ result
54
+ );
55
+ });
50
56
 
51
- return { dashboard, dashboardResult };
57
+ return { dashboard, dashboardResult };
58
+ } catch (error) {
59
+ return { dashboard, error: { message: error.message } };
60
+ }
52
61
  } else {
53
62
  const { dashboardResults } = await getDashboardResults(dashboardId, $workspaceId, authorization);
54
63
  return { dashboard, dashboardResults };
@@ -18,7 +18,7 @@ const dashboardSchema = new mongoose.Schema({
18
18
  });
19
19
 
20
20
  dashboardSchema.methods.evaluate = async function evaluate() {
21
- const context = vm.createContext({ db: this.constructor.db, setTimeout });
21
+ const context = vm.createContext({ db: this.constructor.db, setTimeout, ObjectId: mongoose.Types.ObjectId });
22
22
  let result = null;
23
23
  result = await vm.runInContext(formatFunction(this.code), context);
24
24
  if (result.$document?.constructor?.modelName) {
@@ -1209,16 +1209,19 @@ module.exports = app => app.component('dashboard', {
1209
1209
  },
1210
1210
  async evaluateDashboard() {
1211
1211
  this.status = 'evaluating';
1212
+ this.errorMessage = null;
1212
1213
  try {
1213
1214
  const { dashboard, dashboardResult, error } = await api.Dashboard.getDashboard({ dashboardId: this.dashboardId, evaluate: true });
1214
1215
  this.dashboard = dashboard;
1215
- if (error) {
1216
- this.errorMessage = error.message;
1217
- }
1218
1216
  this.code = this.dashboard.code;
1219
1217
  this.title = this.dashboard.title;
1220
1218
  this.description = this.dashboard.description ?? '';
1221
- this.dashboardResults.unshift(dashboardResult);
1219
+ if (dashboardResult) {
1220
+ this.dashboardResults.unshift(dashboardResult);
1221
+ }
1222
+ if (error) {
1223
+ this.errorMessage = error.message;
1224
+ }
1222
1225
  } finally {
1223
1226
  this.status = 'loaded';
1224
1227
  }
@@ -1265,6 +1268,7 @@ const template = __webpack_require__(/*! ./edit-dashboard.html */ "./frontend/sr
1265
1268
  module.exports = app => app.component('edit-dashboard', {
1266
1269
  template: template,
1267
1270
  props: ['dashboardId', 'code', 'currentDescription', 'currentTitle'],
1271
+ emits: ['close', 'clearError'],
1268
1272
  data: function() {
1269
1273
  return {
1270
1274
  status: 'loaded',
@@ -1278,6 +1282,7 @@ module.exports = app => app.component('edit-dashboard', {
1278
1282
  this.$emit('close');
1279
1283
  },
1280
1284
  async updateCode() {
1285
+ this.$emit('clearError');
1281
1286
  this.status = 'loading';
1282
1287
  try {
1283
1288
  const { doc, result, error } = await api.Dashboard.updateDashboard({
@@ -4362,7 +4367,7 @@ module.exports = "<div class=\"py-2\">\n <div v-if=\"header\" class=\"border-b
4362
4367
  /***/ ((module) => {
4363
4368
 
4364
4369
  "use strict";
4365
- module.exports = "<div class=\"dashboard px-1\">\n <div v-if=\"status === 'loading'\" class=\"max-w-5xl mx-auto text-center\">\n <img src=\"images/loader.gif\" class=\"inline mt-10\">\n </div>\n <div v-if=\"dashboard && status !== 'loading'\" class=\"max-w-5xl mx-auto\">\n <div class=\"flex items-center w-full\" v-if=\"!showEditor\">\n <h2 class=\"mt-4 mb-4 text-gray-900 font-semibold text-xl grow shrink\">{{title}}</h2>\n <div class=\"flex gap-2\">\n <button\n @click=\"showEditor = true\"\n type=\"button\"\n :disabled=\"status === 'evaluating'\"\n class=\"flex items-center 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-ultramarine-600 disabled:cursor-not-allowed disabled:bg-gray-600\">\n <img src=\"images/edit.svg\" class=\"inline h-[1.25em] mr-1\" /> Edit\n </button>\n\n <async-button\n @click=\"evaluateDashboard\"\n type=\"button\"\n :disabled=\"status === 'evaluating'\"\n class=\"flex items-center rounded-md bg-ultramarine-600 px-4 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-ultramarine-600 disabled:cursor-not-allowed disabled:bg-gray-600\"\n >\n <svg class=\"inline h-[1.25em] mr-1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"m670-140 160-100-160-100v200ZM240-600h480v-80H240v80ZM720-40q-83 0-141.5-58.5T520-240q0-83 58.5-141.5T720-440q83 0 141.5 58.5T920-240q0 83-58.5 141.5T720-40ZM120-80v-680q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v267q-19-9-39-15t-41-9v-243H200v562h243q5 31 15.5 59T486-86l-6 6-60-60-60 60-60-60-60 60-60-60-60 60Zm120-200h203q3-21 9-41t15-39H240v80Zm0-160h284q38-37 88.5-58.5T720-520H240v80Zm-40 242v-562 562Z\"/></svg>\n Evaluate\n </async-button>\n </div>\n </div>\n <div v-if=\"!showEditor\" class=\"mt-4 mb-4\">\n <div v-if=\"dashboardResults.length === 0\">\n <div class=\"flex flex-col items-center justify-center py-8\">\n <p class=\"text-gray-700 text-base mb-4\">This dashboard hasn't been evaluated yet.</p>\n <async-button\n @click=\"evaluateDashboard\"\n type=\"button\"\n :disabled=\"status === 'evaluating'\"\n class=\"rounded-md bg-ultramarine-600 px-4 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 disabled:cursor-not-allowed disabled:bg-gray-600\"\n >\n Evaluate Dashboard\n </async-button>\n </div>\n </div>\n <div v-else>\n <div class=\"relative\">\n <dashboard-result\n :key=\"dashboardResult.finishedEvaluatingAt\"\n :result=\"dashboardResult.result\"\n :finishedEvaluatingAt=\"dashboardResult.finishedEvaluatingAt\"\n @fullscreen=\"showDetailModal = true\"\n class=\"h-[40vh]\"\n >\n </dashboard-result>\n </div>\n </div>\n </div>\n <div v-if=\"showEditor\" class=\"mt-4\">\n <edit-dashboard\n :dashboardId=\"dashboard._id\"\n :code=\"code\"\n :currentDescription=\"description\"\n :currentTitle=\"title\"\n @close=\"showEditor=false;\"\n @update=\"updateCode\"></edit-dashboard>\n </div>\n <div v-if=\"errorMessage\" class=\"rounded-md bg-red-50 p-4 mt-4\">\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\" 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\">{{errorMessage}}</h3>\n </div>\n </div>\n </div>\n\n </div>\n <div v-if=\"!dashboard && status !== 'loading'\">\n No dashboard with the given id could be found.\n </div>\n</div>\n\n<modal\n v-if=\"showDetailModal\"\n containerClass=\"!h-[90vh] !w-[90vw]\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Dashboard Details\"\n>\n <template #body>\n <div class=\"absolute font-mono right-1 top-1 cursor-pointer text-xl\" @click=\"showDetailModal = false;\" role=\"button\" aria-label=\"Close modal\">&times;</div>\n <div class=\"h-full overflow-auto\">\n <dashboard-result\n v-if=\"dashboardResult\"\n :result=\"dashboardResult.result\"\n :finishedEvaluatingAt=\"dashboardResult.finishedEvaluatingAt\"\n :fullscreen=\"true\"\n :responsive=\"true\">\n </dashboard-result>\n </div>\n </template>\n</modal>\n";
4370
+ module.exports = "<div class=\"dashboard px-1\">\n <div v-if=\"status === 'loading'\" class=\"max-w-5xl mx-auto text-center\">\n <img src=\"images/loader.gif\" class=\"inline mt-10\">\n </div>\n <div v-if=\"dashboard && status !== 'loading'\" class=\"max-w-5xl mx-auto\">\n <div class=\"flex items-center w-full\" v-if=\"!showEditor\">\n <h2 class=\"mt-4 mb-4 text-gray-900 font-semibold text-xl grow shrink\">{{title}}</h2>\n <div class=\"flex gap-2\">\n <button\n @click=\"showEditor = true\"\n type=\"button\"\n :disabled=\"status === 'evaluating'\"\n class=\"flex items-center 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-ultramarine-600 disabled:cursor-not-allowed disabled:bg-gray-600\">\n <img src=\"images/edit.svg\" class=\"inline h-[1.25em] mr-1\" /> Edit\n </button>\n\n <async-button\n @click=\"evaluateDashboard\"\n type=\"button\"\n :disabled=\"status === 'evaluating'\"\n class=\"flex items-center rounded-md bg-ultramarine-600 px-4 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-ultramarine-600 disabled:cursor-not-allowed disabled:bg-gray-600\"\n >\n <svg class=\"inline h-[1.25em] mr-1\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"m670-140 160-100-160-100v200ZM240-600h480v-80H240v80ZM720-40q-83 0-141.5-58.5T520-240q0-83 58.5-141.5T720-440q83 0 141.5 58.5T920-240q0 83-58.5 141.5T720-40ZM120-80v-680q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v267q-19-9-39-15t-41-9v-243H200v562h243q5 31 15.5 59T486-86l-6 6-60-60-60 60-60-60-60 60-60-60-60 60Zm120-200h203q3-21 9-41t15-39H240v80Zm0-160h284q38-37 88.5-58.5T720-520H240v80Zm-40 242v-562 562Z\"/></svg>\n Evaluate\n </async-button>\n </div>\n </div>\n <div v-if=\"!showEditor\" class=\"mt-4 mb-4\">\n <div v-if=\"dashboardResults.length === 0\">\n <div class=\"flex flex-col items-center justify-center py-8\">\n <p class=\"text-gray-700 text-base mb-4\">This dashboard hasn't been evaluated yet.</p>\n <async-button\n @click=\"evaluateDashboard\"\n type=\"button\"\n :disabled=\"status === 'evaluating'\"\n class=\"rounded-md bg-ultramarine-600 px-4 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 disabled:cursor-not-allowed disabled:bg-gray-600\"\n >\n Evaluate Dashboard\n </async-button>\n </div>\n </div>\n <div v-else>\n <div class=\"relative\">\n <dashboard-result\n :key=\"dashboardResult.finishedEvaluatingAt\"\n :result=\"dashboardResult.result\"\n :finishedEvaluatingAt=\"dashboardResult.finishedEvaluatingAt\"\n @fullscreen=\"showDetailModal = true\"\n class=\"h-[40vh]\"\n >\n </dashboard-result>\n </div>\n </div>\n </div>\n <div v-if=\"showEditor\" class=\"mt-4\">\n <edit-dashboard\n :dashboardId=\"dashboard._id\"\n :code=\"code\"\n :currentDescription=\"description\"\n :currentTitle=\"title\"\n @close=\"showEditor=false;\"\n @update=\"updateCode\"\n @clearError=\"errorMessage = null\"></edit-dashboard>\n </div>\n <div v-if=\"errorMessage\" class=\"rounded-md bg-red-50 p-4 mt-4\">\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\" 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\">{{errorMessage}}</h3>\n </div>\n </div>\n </div>\n\n </div>\n <div v-if=\"!dashboard && status !== 'loading'\">\n No dashboard with the given id could be found.\n </div>\n</div>\n\n<modal\n v-if=\"showDetailModal\"\n containerClass=\"!h-[90vh] !w-[90vw]\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Dashboard Details\"\n>\n <template #body>\n <div class=\"absolute font-mono right-1 top-1 cursor-pointer text-xl\" @click=\"showDetailModal = false;\" role=\"button\" aria-label=\"Close modal\">&times;</div>\n <div class=\"h-full overflow-auto\">\n <dashboard-result\n v-if=\"dashboardResult\"\n :result=\"dashboardResult.result\"\n :finishedEvaluatingAt=\"dashboardResult.finishedEvaluatingAt\"\n :fullscreen=\"true\"\n :responsive=\"true\">\n </dashboard-result>\n </div>\n </template>\n</modal>\n";
4366
4371
 
4367
4372
  /***/ }),
4368
4373
 
@@ -4384,7 +4389,7 @@ module.exports = "<div class=\"p-4 bg-gray-100 rounded-lg shadow-lg\">\n <div
4384
4389
  /***/ ((module) => {
4385
4390
 
4386
4391
  "use strict";
4387
- module.exports = "<div class=\"dashboards max-w-5xl mx-auto mt-8\">\n <div v-if=\"status === 'loaded' && dashboards.length === 0\">\n <div class=\"text-center\">\n <h3 class=\"mt-2 text-sm font-semibold text-gray-900\">No dashboards yet</h3>\n <p class=\"mt-1 text-sm text-gray-500\">Get started by creating a new dashboard.</p>\n <div class=\"mt-6\">\n <button type=\"button\" class=\"inline-flex items-center rounded-md bg-teal-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">\n <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z\" />\n </svg>\n New Dashboard\n </button>\n </div>\n </div>\n </div>\n\n\n <div class=\"px-4 sm:px-6 lg:px-8\">\n <div class=\"sm:flex sm:items-center\">\n <div class=\"sm:flex-auto\">\n <h1 class=\"text-base font-semibold leading-6 text-gray-900\">Dashboards</h1>\n </div>\n <div class=\"mt-4 sm:ml-16 sm:mt-0 sm:flex-none\">\n <button\n type=\"button\"\n @click=\"showCreateDashboardModal = true\"\n class=\"block rounded-md bg-teal-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600\">Create New Dashboard</button>\n </div>\n </div>\n <div class=\"mt-8 flow-root\">\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\">\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-6 lg:pl-8\">Title</th>\n <th scope=\"col\" class=\"px-3 py-3.5 text-left text-sm font-semibold text-gray-900 w-[50%]\">Description</th>\n <th scope=\"col\" class=\"relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8\">\n </th>\n <th scope=\"col\" class=\"relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8\">\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr v-for=\"dashboard in dashboards\">\n <td class=\"whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8\">{{dashboard.title}}</td>\n <td class=\"whitespace-nowrap px-3 py-4 text-sm text-gray-500 truncate w-[50%]\">{{dashboard.description}}</td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <router-link\n :to=\"'/dashboard/' + dashboard._id + '?edit=true'\"\n class=\"text-teal-600 hover:text-teal-900\">\n Edit\n </router-link>\n </td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <router-link\n :to=\"'/dashboard/' + dashboard._id\"\n class=\"text-teal-600 hover:text-teal-900\">\n View\n </router-link>\n </td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <button\n @click=\"showDeleteDashboardModal=dashboard\"\n class=\"text-teal-600 hover:text-teal-900\">\n Delete\n </button>\n </td>\n </tr>\n \n <!-- More people... -->\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n\n <modal v-if=\"showCreateDashboardModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"showCreateDashboardModal = false;\">&times;</div>\n \n <create-dashboard @close=\"insertNewDashboard\"></create-dashboard>\n </template>\n </modal>\n\n <modal v-if=\"showDeleteDashboardModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"showDeleteDashboardModal = null;\">&times;</div>\n <h2>Are you sure you want to delete this dashboard titled {{showDeleteDashboardModal.title}}?</h2>\n <div class=\"flex space-x-2\">\n <button class=\"px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500\" @click=\"deleteDashboard(showDeleteDashboardModal)\">Yes, delete</button>\n <button class=\"px-4 py-2 bg-gray-500 text-white rounded-md hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-600\" @click=\"showDeleteDashboardModal=null;\">Cancel</button>\n </div>\n </template>\n </modal>\n</div>";
4392
+ module.exports = "<div class=\"dashboards max-w-5xl mx-auto mt-8\">\n <div v-if=\"status === 'loading'\" class=\"text-center mt-4\">\n <svg\n class=\"inline w-8 h-8 animate-spin text-ultramarine-600\"\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n >\n <circle\n class=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"4\"\n ></circle>\n <path\n class=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z\"\n ></path>\n </svg>\n </div>\n <div v-if=\"status === 'loaded' && dashboards.length === 0\">\n <div class=\"text-center\">\n <h3 class=\"mt-2 text-sm font-semibold text-gray-900\">No dashboards yet</h3>\n <p class=\"mt-1 text-sm text-gray-500\">Get started by creating a new dashboard.</p>\n <div class=\"mt-6\">\n <button type=\"button\" class=\"inline-flex items-center rounded-md bg-ultramarine-600 px-3 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 <svg class=\"-ml-0.5 mr-1.5 h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z\" />\n </svg>\n New Dashboard\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"px-4 sm:px-6 lg:px-8\">\n <div class=\"sm:flex sm:items-center\">\n <div class=\"sm:flex-auto\">\n <h1 class=\"text-base font-semibold leading-6 text-gray-900\">Dashboards</h1>\n </div>\n <div class=\"mt-4 sm:ml-16 sm:mt-0 sm:flex-none\">\n <button\n type=\"button\"\n @click=\"showCreateDashboardModal = true\"\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 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600\">Create New Dashboard</button>\n </div>\n </div>\n <div class=\"mt-8 flow-root\">\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\">\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-6 lg:pl-8\">Title</th>\n <th scope=\"col\" class=\"px-3 py-3.5 text-left text-sm font-semibold text-gray-900 w-[50%]\">Description</th>\n <th scope=\"col\" class=\"relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8\">\n </th>\n <th scope=\"col\" class=\"relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8\">\n </th>\n </tr>\n </thead>\n <tbody class=\"divide-y divide-gray-200 bg-white\">\n <tr v-for=\"dashboard in dashboards\">\n <td class=\"whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8\">{{dashboard.title}}</td>\n <td class=\"whitespace-nowrap px-3 py-4 text-sm text-gray-500 truncate w-[50%]\">{{dashboard.description}}</td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <router-link\n :to=\"'/dashboard/' + dashboard._id + '?edit=true'\"\n class=\"text-ultramarine-600 hover:text-ultramarine-900\">\n Edit\n </router-link>\n </td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <router-link\n :to=\"'/dashboard/' + dashboard._id\"\n class=\"text-ultramarine-600 hover:text-ultramarine-900\">\n View\n </router-link>\n </td>\n <td class=\"relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8\">\n <button\n @click=\"showDeleteDashboardModal=dashboard\"\n class=\"text-ultramarine-600 hover:text-ultramarine-900\">\n Delete\n </button>\n </td>\n </tr>\n\n <!-- More people... -->\n </tbody>\n </table>\n </div>\n </div>\n </div>\n </div>\n\n <modal v-if=\"showCreateDashboardModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"showCreateDashboardModal = false;\">&times;</div>\n\n <create-dashboard @close=\"insertNewDashboard\"></create-dashboard>\n </template>\n </modal>\n\n <modal v-if=\"showDeleteDashboardModal\">\n <template v-slot:body>\n <div class=\"modal-exit\" @click=\"showDeleteDashboardModal = null;\">&times;</div>\n <h2>Are you sure you want to delete this dashboard titled {{showDeleteDashboardModal.title}}?</h2>\n <div class=\"flex space-x-2\">\n <button class=\"px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500\" @click=\"deleteDashboard(showDeleteDashboardModal)\">Yes, delete</button>\n <button class=\"px-4 py-2 bg-gray-500 text-white rounded-md hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-600\" @click=\"showDeleteDashboardModal=null;\">Cancel</button>\n </div>\n </template>\n </modal>\n </div>\n</div>";
4388
4393
 
4389
4394
  /***/ }),
4390
4395
 
@@ -14876,7 +14881,7 @@ var bson = /*#__PURE__*/Object.freeze({
14876
14881
  /***/ ((module) => {
14877
14882
 
14878
14883
  "use strict";
14879
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@mongoosejs/studio","version":"0.0.116","description":"A sleek, powerful MongoDB UI with built-in dashboarding and auth, seamlessly integrated with your Express, Vercel, or Netlify app.","homepage":"https://studio.mongoosejs.io/","repository":{"type":"git","url":"https://github.com/mongoosejs/studio"},"dependencies":{"archetype":"0.13.1","csv-stringify":"6.3.0","ejson":"^2.2.3","extrovert":"0.0.26","marked":"15.0.12","node-inspect-extracted":"3.x","tailwindcss":"3.4.0","vanillatoasts":"^1.6.0","vue":"3.x","webpack":"5.x"},"peerDependencies":{"bson":"^5.5.1 || 6.x","express":"4.x","mongoose":"7.x || 8.x"},"devDependencies":{"@masteringjs/eslint-config":"0.1.1","axios":"1.2.2","dedent":"^1.6.0","eslint":"9.30.0","express":"4.x","mocha":"10.2.0","mongoose":"8.x"},"scripts":{"lint":"eslint .","tailwind":"tailwindcss -o ./frontend/public/tw.css","tailwind:watch":"tailwindcss -o ./frontend/public/tw.css --watch","test":"mocha test/*.test.js"}}');
14884
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@mongoosejs/studio","version":"0.0.117","description":"A sleek, powerful MongoDB UI with built-in dashboarding and auth, seamlessly integrated with your Express, Vercel, or Netlify app.","homepage":"https://studio.mongoosejs.io/","repository":{"type":"git","url":"https://github.com/mongoosejs/studio"},"dependencies":{"archetype":"0.13.1","csv-stringify":"6.3.0","ejson":"^2.2.3","extrovert":"0.0.26","marked":"15.0.12","node-inspect-extracted":"3.x","tailwindcss":"3.4.0","vanillatoasts":"^1.6.0","vue":"3.x","webpack":"5.x"},"peerDependencies":{"bson":"^5.5.1 || 6.x","express":"4.x","mongoose":"7.x || 8.x"},"devDependencies":{"@masteringjs/eslint-config":"0.1.1","axios":"1.2.2","dedent":"^1.6.0","eslint":"9.30.0","express":"4.x","mocha":"10.2.0","mongoose":"8.x"},"scripts":{"lint":"eslint .","tailwind":"tailwindcss -o ./frontend/public/tw.css","tailwind:watch":"tailwindcss -o ./frontend/public/tw.css --watch","test":"mocha test/*.test.js"}}');
14880
14885
 
14881
14886
  /***/ })
14882
14887
 
@@ -642,10 +642,6 @@ video {
642
642
  top: 90%;
643
643
  }
644
644
 
645
- .bottom-0 {
646
- bottom: 0px;
647
- }
648
-
649
645
  .isolate {
650
646
  isolation: isolate;
651
647
  }
@@ -982,6 +978,10 @@ video {
982
978
  max-width: 64rem;
983
979
  }
984
980
 
981
+ .max-w-\[calc\(100vw-3rem\)\] {
982
+ max-width: calc(100vw - 3rem);
983
+ }
984
+
985
985
  .max-w-\[calc\(100vw-4rem\)\] {
986
986
  max-width: calc(100vw - 4rem);
987
987
  }
@@ -990,10 +990,6 @@ video {
990
990
  max-width: 20rem;
991
991
  }
992
992
 
993
- .max-w-\[calc\(100vw-3rem\)\] {
994
- max-width: calc(100vw - 3rem);
995
- }
996
-
997
993
  .flex-1 {
998
994
  flex: 1 1 0%;
999
995
  }
@@ -1044,6 +1040,16 @@ video {
1044
1040
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
1045
1041
  }
1046
1042
 
1043
+ @keyframes spin {
1044
+ to {
1045
+ transform: rotate(360deg);
1046
+ }
1047
+ }
1048
+
1049
+ .animate-spin {
1050
+ animation: spin 1s linear infinite;
1051
+ }
1052
+
1047
1053
  .cursor-not-allowed {
1048
1054
  cursor: not-allowed;
1049
1055
  }
@@ -1800,6 +1806,11 @@ video {
1800
1806
  color: rgb(255 255 255 / var(--tw-text-opacity));
1801
1807
  }
1802
1808
 
1809
+ .text-ultramarine-600 {
1810
+ --tw-text-opacity: 1;
1811
+ color: rgb(24 35 255 / var(--tw-text-opacity));
1812
+ }
1813
+
1803
1814
  .accent-sky-600 {
1804
1815
  accent-color: #0284c7;
1805
1816
  }
@@ -1808,6 +1819,14 @@ video {
1808
1819
  opacity: 0.5;
1809
1820
  }
1810
1821
 
1822
+ .opacity-25 {
1823
+ opacity: 0.25;
1824
+ }
1825
+
1826
+ .opacity-75 {
1827
+ opacity: 0.75;
1828
+ }
1829
+
1811
1830
  .shadow {
1812
1831
  --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
1813
1832
  --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
@@ -2085,9 +2104,9 @@ video {
2085
2104
  color: rgb(10 87 87 / var(--tw-text-opacity));
2086
2105
  }
2087
2106
 
2088
- .hover\:text-gray-600:hover {
2107
+ .hover\:text-ultramarine-900:hover {
2089
2108
  --tw-text-opacity: 1;
2090
- color: rgb(75 85 99 / var(--tw-text-opacity));
2109
+ color: rgb(6 14 172 / var(--tw-text-opacity));
2091
2110
  }
2092
2111
 
2093
2112
  .focus\:z-10:focus {
@@ -2367,10 +2386,6 @@ video {
2367
2386
  .md\:hidden {
2368
2387
  display: none;
2369
2388
  }
2370
-
2371
- .md\:p-3 {
2372
- padding: 0.75rem;
2373
- }
2374
2389
  }
2375
2390
 
2376
2391
  @media (min-width: 1024px) {
@@ -2391,14 +2406,14 @@ video {
2391
2406
  width: 16rem;
2392
2407
  }
2393
2408
 
2394
- .lg\:max-w-\[calc\(100vw-20rem\)\] {
2395
- max-width: calc(100vw - 20rem);
2396
- }
2397
-
2398
2409
  .lg\:max-w-\[calc\(100vw-15rem\)\] {
2399
2410
  max-width: calc(100vw - 15rem);
2400
2411
  }
2401
2412
 
2413
+ .lg\:max-w-\[calc\(100vw-20rem\)\] {
2414
+ max-width: calc(100vw - 20rem);
2415
+ }
2416
+
2402
2417
  .lg\:px-8 {
2403
2418
  padding-left: 2rem;
2404
2419
  padding-right: 2rem;
@@ -59,7 +59,8 @@
59
59
  :currentDescription="description"
60
60
  :currentTitle="title"
61
61
  @close="showEditor=false;"
62
- @update="updateCode"></edit-dashboard>
62
+ @update="updateCode"
63
+ @clearError="errorMessage = null"></edit-dashboard>
63
64
  </div>
64
65
  <div v-if="errorMessage" class="rounded-md bg-red-50 p-4 mt-4">
65
66
  <div class="flex">
@@ -35,16 +35,19 @@ module.exports = app => app.component('dashboard', {
35
35
  },
36
36
  async evaluateDashboard() {
37
37
  this.status = 'evaluating';
38
+ this.errorMessage = null;
38
39
  try {
39
40
  const { dashboard, dashboardResult, error } = await api.Dashboard.getDashboard({ dashboardId: this.dashboardId, evaluate: true });
40
41
  this.dashboard = dashboard;
41
- if (error) {
42
- this.errorMessage = error.message;
43
- }
44
42
  this.code = this.dashboard.code;
45
43
  this.title = this.dashboard.title;
46
44
  this.description = this.dashboard.description ?? '';
47
- this.dashboardResults.unshift(dashboardResult);
45
+ if (dashboardResult) {
46
+ this.dashboardResults.unshift(dashboardResult);
47
+ }
48
+ if (error) {
49
+ this.errorMessage = error.message;
50
+ }
48
51
  } finally {
49
52
  this.status = 'loaded';
50
53
  }
@@ -6,6 +6,7 @@ const template = require('./edit-dashboard.html');
6
6
  module.exports = app => app.component('edit-dashboard', {
7
7
  template: template,
8
8
  props: ['dashboardId', 'code', 'currentDescription', 'currentTitle'],
9
+ emits: ['close', 'clearError'],
9
10
  data: function() {
10
11
  return {
11
12
  status: 'loaded',
@@ -19,6 +20,7 @@ module.exports = app => app.component('edit-dashboard', {
19
20
  this.$emit('close');
20
21
  },
21
22
  async updateCode() {
23
+ this.$emit('clearError');
22
24
  this.status = 'loading';
23
25
  try {
24
26
  const { doc, result, error } = await api.Dashboard.updateDashboard({
@@ -1,97 +1,119 @@
1
1
  <div class="dashboards max-w-5xl mx-auto mt-8">
2
- <div v-if="status === 'loaded' && dashboards.length === 0">
3
- <div class="text-center">
4
- <h3 class="mt-2 text-sm font-semibold text-gray-900">No dashboards yet</h3>
5
- <p class="mt-1 text-sm text-gray-500">Get started by creating a new dashboard.</p>
6
- <div class="mt-6">
7
- <button type="button" class="inline-flex items-center rounded-md bg-teal-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600">
8
- <svg class="-ml-0.5 mr-1.5 h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
9
- <path d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z" />
10
- </svg>
11
- New Dashboard
12
- </button>
2
+ <div v-if="status === 'loading'" class="text-center mt-4">
3
+ <svg
4
+ class="inline w-8 h-8 animate-spin text-ultramarine-600"
5
+ xmlns="http://www.w3.org/2000/svg"
6
+ fill="none"
7
+ viewBox="0 0 24 24"
8
+ >
9
+ <circle
10
+ class="opacity-25"
11
+ cx="12"
12
+ cy="12"
13
+ r="10"
14
+ stroke="currentColor"
15
+ stroke-width="4"
16
+ ></circle>
17
+ <path
18
+ class="opacity-75"
19
+ fill="currentColor"
20
+ d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"
21
+ ></path>
22
+ </svg>
23
+ </div>
24
+ <div v-if="status === 'loaded' && dashboards.length === 0">
25
+ <div class="text-center">
26
+ <h3 class="mt-2 text-sm font-semibold text-gray-900">No dashboards yet</h3>
27
+ <p class="mt-1 text-sm text-gray-500">Get started by creating a new dashboard.</p>
28
+ <div class="mt-6">
29
+ <button type="button" class="inline-flex items-center rounded-md bg-ultramarine-600 px-3 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">
30
+ <svg class="-ml-0.5 mr-1.5 h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
31
+ <path d="M10.75 4.75a.75.75 0 00-1.5 0v4.5h-4.5a.75.75 0 000 1.5h4.5v4.5a.75.75 0 001.5 0v-4.5h4.5a.75.75 0 000-1.5h-4.5v-4.5z" />
32
+ </svg>
33
+ New Dashboard
34
+ </button>
35
+ </div>
13
36
  </div>
14
37
  </div>
15
- </div>
16
-
17
38
 
18
- <div class="px-4 sm:px-6 lg:px-8">
19
- <div class="sm:flex sm:items-center">
20
- <div class="sm:flex-auto">
21
- <h1 class="text-base font-semibold leading-6 text-gray-900">Dashboards</h1>
22
- </div>
23
- <div class="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
24
- <button
25
- type="button"
26
- @click="showCreateDashboardModal = true"
27
- class="block rounded-md bg-teal-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-teal-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600">Create New Dashboard</button>
39
+ <div class="px-4 sm:px-6 lg:px-8">
40
+ <div class="sm:flex sm:items-center">
41
+ <div class="sm:flex-auto">
42
+ <h1 class="text-base font-semibold leading-6 text-gray-900">Dashboards</h1>
43
+ </div>
44
+ <div class="mt-4 sm:ml-16 sm:mt-0 sm:flex-none">
45
+ <button
46
+ type="button"
47
+ @click="showCreateDashboardModal = true"
48
+ 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 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600">Create New Dashboard</button>
49
+ </div>
28
50
  </div>
29
- </div>
30
- <div class="mt-8 flow-root">
31
- <div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
32
- <div class="inline-block min-w-full py-2 align-middle">
33
- <table class="min-w-full divide-y divide-gray-300">
34
- <thead>
35
- <tr>
36
- <th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg:pl-8">Title</th>
37
- <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 w-[50%]">Description</th>
38
- <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8">
39
- </th>
40
- <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8">
41
- </th>
42
- </tr>
43
- </thead>
44
- <tbody class="divide-y divide-gray-200 bg-white">
45
- <tr v-for="dashboard in dashboards">
46
- <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8">{{dashboard.title}}</td>
47
- <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500 truncate w-[50%]">{{dashboard.description}}</td>
48
- <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8">
49
- <router-link
50
- :to="'/dashboard/' + dashboard._id + '?edit=true'"
51
- class="text-teal-600 hover:text-teal-900">
52
- Edit
53
- </router-link>
54
- </td>
55
- <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8">
56
- <router-link
57
- :to="'/dashboard/' + dashboard._id"
58
- class="text-teal-600 hover:text-teal-900">
59
- View
60
- </router-link>
61
- </td>
62
- <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8">
63
- <button
64
- @click="showDeleteDashboardModal=dashboard"
65
- class="text-teal-600 hover:text-teal-900">
66
- Delete
67
- </button>
68
- </td>
69
- </tr>
70
-
71
- <!-- More people... -->
72
- </tbody>
73
- </table>
51
+ <div class="mt-8 flow-root">
52
+ <div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
53
+ <div class="inline-block min-w-full py-2 align-middle">
54
+ <table class="min-w-full divide-y divide-gray-300">
55
+ <thead>
56
+ <tr>
57
+ <th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg:pl-8">Title</th>
58
+ <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 w-[50%]">Description</th>
59
+ <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8">
60
+ </th>
61
+ <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6 lg:pr-8">
62
+ </th>
63
+ </tr>
64
+ </thead>
65
+ <tbody class="divide-y divide-gray-200 bg-white">
66
+ <tr v-for="dashboard in dashboards">
67
+ <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8">{{dashboard.title}}</td>
68
+ <td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500 truncate w-[50%]">{{dashboard.description}}</td>
69
+ <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8">
70
+ <router-link
71
+ :to="'/dashboard/' + dashboard._id + '?edit=true'"
72
+ class="text-ultramarine-600 hover:text-ultramarine-900">
73
+ Edit
74
+ </router-link>
75
+ </td>
76
+ <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8">
77
+ <router-link
78
+ :to="'/dashboard/' + dashboard._id"
79
+ class="text-ultramarine-600 hover:text-ultramarine-900">
80
+ View
81
+ </router-link>
82
+ </td>
83
+ <td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 lg:pr-8">
84
+ <button
85
+ @click="showDeleteDashboardModal=dashboard"
86
+ class="text-ultramarine-600 hover:text-ultramarine-900">
87
+ Delete
88
+ </button>
89
+ </td>
90
+ </tr>
91
+
92
+ <!-- More people... -->
93
+ </tbody>
94
+ </table>
95
+ </div>
74
96
  </div>
75
97
  </div>
76
98
  </div>
77
- </div>
78
99
 
79
- <modal v-if="showCreateDashboardModal">
80
- <template v-slot:body>
81
- <div class="modal-exit" @click="showCreateDashboardModal = false;">&times;</div>
82
-
83
- <create-dashboard @close="insertNewDashboard"></create-dashboard>
84
- </template>
85
- </modal>
100
+ <modal v-if="showCreateDashboardModal">
101
+ <template v-slot:body>
102
+ <div class="modal-exit" @click="showCreateDashboardModal = false;">&times;</div>
86
103
 
87
- <modal v-if="showDeleteDashboardModal">
88
- <template v-slot:body>
89
- <div class="modal-exit" @click="showDeleteDashboardModal = null;">&times;</div>
90
- <h2>Are you sure you want to delete this dashboard titled {{showDeleteDashboardModal.title}}?</h2>
91
- <div class="flex space-x-2">
92
- <button class="px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500" @click="deleteDashboard(showDeleteDashboardModal)">Yes, delete</button>
93
- <button class="px-4 py-2 bg-gray-500 text-white rounded-md hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-600" @click="showDeleteDashboardModal=null;">Cancel</button>
94
- </div>
95
- </template>
96
- </modal>
104
+ <create-dashboard @close="insertNewDashboard"></create-dashboard>
105
+ </template>
106
+ </modal>
107
+
108
+ <modal v-if="showDeleteDashboardModal">
109
+ <template v-slot:body>
110
+ <div class="modal-exit" @click="showDeleteDashboardModal = null;">&times;</div>
111
+ <h2>Are you sure you want to delete this dashboard titled {{showDeleteDashboardModal.title}}?</h2>
112
+ <div class="flex space-x-2">
113
+ <button class="px-4 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 focus:outline-none focus:ring-2 focus:ring-red-500" @click="deleteDashboard(showDeleteDashboardModal)">Yes, delete</button>
114
+ <button class="px-4 py-2 bg-gray-500 text-white rounded-md hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-gray-600" @click="showDeleteDashboardModal=null;">Cancel</button>
115
+ </div>
116
+ </template>
117
+ </modal>
118
+ </div>
97
119
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mongoosejs/studio",
3
- "version": "0.0.116",
3
+ "version": "0.0.117",
4
4
  "description": "A sleek, powerful MongoDB UI with built-in dashboarding and auth, seamlessly integrated with your Express, Vercel, or Netlify app.",
5
5
  "homepage": "https://studio.mongoosejs.io/",
6
6
  "repository": {