@mongoosejs/studio 0.0.115 → 0.0.116
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 +59 -20
- package/frontend/public/tw.css +25 -0
- package/frontend/src/chat/chat-message/chat-message.html +3 -3
- package/frontend/src/chat/chat-message/chat-message.js +33 -1
- package/frontend/src/chat/chat-message-script/chat-message-script.html +5 -0
- package/frontend/src/chat/chat-message-script/chat-message-script.js +7 -2
- package/frontend/src/chat/chat.html +2 -1
- package/frontend/src/chat/chat.js +4 -2
- package/frontend/src/dashboard/dashboard.html +7 -10
- package/frontend/src/dashboard/dashboard.js +0 -3
- package/frontend/src/dashboard-result/dashboard-chart/dashboard-chart.html +21 -5
- package/frontend/src/dashboard-result/dashboard-chart/dashboard-chart.js +4 -2
- package/frontend/src/dashboard-result/dashboard-result.html +4 -2
- package/frontend/src/dashboard-result/dashboard-result.js +2 -1
- package/frontend/src/models/models.js +2 -2
- package/package.json +1 -1
package/frontend/public/app.js
CHANGED
|
@@ -336,6 +336,7 @@ const vanillatoasts = __webpack_require__(/*! vanillatoasts */ "./node_modules/v
|
|
|
336
336
|
module.exports = app => app.component('chat-message-script', {
|
|
337
337
|
template,
|
|
338
338
|
props: ['message', 'script', 'language'],
|
|
339
|
+
emits: ['copyMessage'],
|
|
339
340
|
data() {
|
|
340
341
|
return {
|
|
341
342
|
activeTab: 'code',
|
|
@@ -411,9 +412,13 @@ module.exports = app => app.component('chat-message-script', {
|
|
|
411
412
|
this.$router.push('/dashboard/' + dashboard._id);
|
|
412
413
|
},
|
|
413
414
|
async copyOutput() {
|
|
414
|
-
|
|
415
|
+
let output = this.message.executionResult.output;
|
|
416
|
+
if (output != null && typeof output === 'object') {
|
|
417
|
+
output = JSON.stringify(output, null, 2);
|
|
418
|
+
}
|
|
419
|
+
await navigator.clipboard.writeText(output);
|
|
415
420
|
vanillatoasts.create({
|
|
416
|
-
title: '
|
|
421
|
+
title: 'Code output copied!',
|
|
417
422
|
type: 'success',
|
|
418
423
|
timeout: 3000,
|
|
419
424
|
icon: 'images/success.png',
|
|
@@ -457,6 +462,7 @@ module.exports = app => app.component('chat-message-script', {
|
|
|
457
462
|
|
|
458
463
|
const api = __webpack_require__(/*! ../../api */ "./frontend/src/api.js");
|
|
459
464
|
const marked = (__webpack_require__(/*! marked */ "./node_modules/marked/lib/marked.cjs").marked);
|
|
465
|
+
const vanillatoasts = __webpack_require__(/*! vanillatoasts */ "./node_modules/vanillatoasts/vanillatoasts.js");
|
|
460
466
|
const template = __webpack_require__(/*! ./chat-message.html */ "./frontend/src/chat/chat-message/chat-message.html");
|
|
461
467
|
|
|
462
468
|
module.exports = app => app.component('chat-message', {
|
|
@@ -464,7 +470,7 @@ module.exports = app => app.component('chat-message', {
|
|
|
464
470
|
props: ['message'],
|
|
465
471
|
computed: {
|
|
466
472
|
styleForMessage() {
|
|
467
|
-
return this.message.role === 'user' ? 'bg-gray-100' : '';
|
|
473
|
+
return this.message.role === 'user' ? 'p-3 bg-gray-100' : 'py-3 pr-3';
|
|
468
474
|
},
|
|
469
475
|
contentSplitByScripts() {
|
|
470
476
|
const content = this.message.content;
|
|
@@ -516,6 +522,37 @@ module.exports = app => app.component('chat-message', {
|
|
|
516
522
|
});
|
|
517
523
|
message.executionResult = chatMessage.executionResult;
|
|
518
524
|
console.log(message);
|
|
525
|
+
},
|
|
526
|
+
async copyMessage() {
|
|
527
|
+
const parts = this.contentSplitByScripts;
|
|
528
|
+
let output = '';
|
|
529
|
+
for (const part of parts) {
|
|
530
|
+
if (part.type === 'text') {
|
|
531
|
+
output += part.content + '\n';
|
|
532
|
+
} else if (part.type === 'code') {
|
|
533
|
+
let result = this.message.executionResult?.output;
|
|
534
|
+
if (result != null && typeof result === 'object') {
|
|
535
|
+
result = JSON.stringify(result, null, 2);
|
|
536
|
+
}
|
|
537
|
+
if (result) {
|
|
538
|
+
let executionOutput = this.message.executionResult?.output;
|
|
539
|
+
if (executionOutput != null && typeof executionOutput === 'object') {
|
|
540
|
+
executionOutput = JSON.stringify(executionOutput, null, 2);
|
|
541
|
+
}
|
|
542
|
+
if (executionOutput) {
|
|
543
|
+
output += '```\n' + executionOutput + '\n```\n';
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
await navigator.clipboard.writeText(output.trim());
|
|
549
|
+
vanillatoasts.create({
|
|
550
|
+
title: 'Message output copied!',
|
|
551
|
+
type: 'success',
|
|
552
|
+
timeout: 3000,
|
|
553
|
+
icon: 'images/success.png',
|
|
554
|
+
positionClass: 'bottomRight'
|
|
555
|
+
});
|
|
519
556
|
}
|
|
520
557
|
}
|
|
521
558
|
});
|
|
@@ -553,6 +590,8 @@ module.exports = app => app.component('chat', {
|
|
|
553
590
|
async sendMessage() {
|
|
554
591
|
this.sendingMessage = true;
|
|
555
592
|
try {
|
|
593
|
+
const content = this.newMessage;
|
|
594
|
+
this.newMessage = '';
|
|
556
595
|
if (!this.chatThreadId) {
|
|
557
596
|
const { chatThread } = await api.ChatThread.createChatThread();
|
|
558
597
|
this.chatThreads.unshift(chatThread);
|
|
@@ -561,7 +600,7 @@ module.exports = app => app.component('chat', {
|
|
|
561
600
|
}
|
|
562
601
|
|
|
563
602
|
this.chatMessages.push({
|
|
564
|
-
content
|
|
603
|
+
content,
|
|
565
604
|
role: 'user'
|
|
566
605
|
});
|
|
567
606
|
|
|
@@ -573,7 +612,7 @@ module.exports = app => app.component('chat', {
|
|
|
573
612
|
|
|
574
613
|
const { chatMessages, chatThread } = await api.ChatThread.createChatMessage({
|
|
575
614
|
chatThreadId: this.chatThreadId,
|
|
576
|
-
content
|
|
615
|
+
content
|
|
577
616
|
});
|
|
578
617
|
this.chatMessages.push(chatMessages[1]);
|
|
579
618
|
for (const thread of this.chatThreads) {
|
|
@@ -904,9 +943,11 @@ const template = __webpack_require__(/*! ./dashboard-chart.html */ "./frontend/s
|
|
|
904
943
|
|
|
905
944
|
module.exports = app => app.component('dashboard-chart', {
|
|
906
945
|
template: template,
|
|
907
|
-
props: ['value', '
|
|
946
|
+
props: ['value', 'fullscreen'],
|
|
947
|
+
emits: ['fullscreen'],
|
|
908
948
|
data: () => ({
|
|
909
|
-
chart: null
|
|
949
|
+
chart: null,
|
|
950
|
+
showDetailModal: false
|
|
910
951
|
}),
|
|
911
952
|
mounted() {
|
|
912
953
|
const ctx = this.$refs.chart.getContext('2d');
|
|
@@ -1074,7 +1115,8 @@ const template = __webpack_require__(/*! ./dashboard-result.html */ "./frontend/
|
|
|
1074
1115
|
|
|
1075
1116
|
module.exports = app => app.component('dashboard-result', {
|
|
1076
1117
|
template: template,
|
|
1077
|
-
props: ['result', 'finishedEvaluatingAt'],
|
|
1118
|
+
props: ['result', 'finishedEvaluatingAt', 'fullscreen'],
|
|
1119
|
+
emits: ['fullscreen'],
|
|
1078
1120
|
mounted: async function() {
|
|
1079
1121
|
},
|
|
1080
1122
|
methods: {
|
|
@@ -1180,9 +1222,6 @@ module.exports = app => app.component('dashboard', {
|
|
|
1180
1222
|
} finally {
|
|
1181
1223
|
this.status = 'loaded';
|
|
1182
1224
|
}
|
|
1183
|
-
},
|
|
1184
|
-
openDetailModal() {
|
|
1185
|
-
this.showDetailModal = true;
|
|
1186
1225
|
}
|
|
1187
1226
|
},
|
|
1188
1227
|
computed: {
|
|
@@ -2671,13 +2710,13 @@ module.exports = app => app.component('models', {
|
|
|
2671
2710
|
this.query.search = this.searchText;
|
|
2672
2711
|
const query = this.query;
|
|
2673
2712
|
const newUrl = this.$router.resolve({ query }).href;
|
|
2674
|
-
|
|
2713
|
+
this.$router.push({ query });
|
|
2675
2714
|
} else {
|
|
2676
2715
|
this.filter = {};
|
|
2677
2716
|
delete this.query.search;
|
|
2678
2717
|
const query = this.query;
|
|
2679
2718
|
const newUrl = this.$router.resolve({ query }).href;
|
|
2680
|
-
|
|
2719
|
+
this.$router.push({ query });
|
|
2681
2720
|
}
|
|
2682
2721
|
this.documents = [];
|
|
2683
2722
|
this.status = 'loading';
|
|
@@ -4169,7 +4208,7 @@ module.exports = "<button v-bind=\"attrsToBind\" :disabled=\"isDisabled\" @click
|
|
|
4169
4208
|
/***/ ((module) => {
|
|
4170
4209
|
|
|
4171
4210
|
"use strict";
|
|
4172
|
-
module.exports = "<div class=\"relative border rounded bg-gray-100 text-black text-sm overflow-hidden\">\n <div class=\"flex border-b pt-[1px] text-xs font-medium bg-gray-200\">\n <button\n class=\"px-3 py-1 border-r border-gray-300 hover:bg-green-300\"\n :class=\"{'bg-gray-300': activeTab === 'code', 'bg-green-300': activeTab === 'code'}\"\n @click=\"activeTab = 'code'\">\n Code\n </button>\n <button\n class=\"px-3 py-1 hover:bg-green-300\"\n :class=\"{'bg-green-300': activeTab === 'output'}\"\n @click=\"activeTab = 'output'\">\n Output\n </button>\n <div class=\"ml-auto mr-1 flex\">\n <button\n v-if=\"activeTab === 'output'\"\n class=\"px-2 py-1 mr-1 text-xs bg-gray-500 text-white border-none rounded cursor-pointer hover:bg-gray-600 transition-colors flex items-center\"\n @click=\"copyOutput\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3\" />\n </svg>\n </button>\n <button\n v-if=\"activeTab === 'output'\"\n class=\"px-2 py-1 mr-1 text-xs bg-blue-500 text-white border-none rounded cursor-pointer hover:bg-blue-600 transition-colors flex items-center\"\n @click=\"openDetailModal\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 1v4m0 0h-4m4 0l-5-5\" />\n </svg>\n </button>\n <async-button\n class=\"px-2 py-1 text-xs bg-green-500 text-white border-none rounded cursor-pointer hover:bg-green-600 transition-colors disabled:bg-gray-400\"\n @click=\"executeScript(message, script)\">\n Execute\n </async-button>\n <div class=\"relative ml-1\" ref=\"dropdown\">\n <button\n @click.stop=\"toggleDropdown\"\n class=\"px-1 py-1 text-xs hover:bg-gray-300 rounded flex items-center\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M10 6a2 2 0 110-4 2 2 0 010 4zm0 6a2 2 0 110-4 2 2 0 010 4zm0 6a2 2 0 110-4 2 2 0 010 4z\" />\n </svg>\n </button>\n <div\n v-if=\"showDropdown\"\n class=\"absolute right-0 z-10 mt-1 w-64 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black/5\">\n <button\n class=\"block w-full text-left px-4 py-2 text-xs text-gray-700 hover:bg-gray-100\"\n @click=\"openCreateDashboardModal(); showDropdown = false\">\n Create Dashboard\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <pre class=\"p-3 whitespace-pre-wrap max-h-[50vh] max-w-[calc(100vw-4rem)] lg:max-w-[calc(100vw-20rem)] overflow-y-auto\" v-show=\"activeTab === 'code'\"><code v-text=\"script\" ref=\"code\" :class=\"'language-' + language\"></code></pre>\n\n <div class=\"p-3 whitespace-pre-wrap max-h-[50vh] overflow-y-auto bg-white border-t max-w-[calc(100vw-4rem)] lg:max-w-[calc(100vw-20rem)] relative\" v-show=\"activeTab === 'output'\">\n <dashboard-chart v-if=\"message.executionResult?.output?.$chart\" :value=\"message.executionResult?.output\" />\n <dashboard-map v-else-if=\"message.executionResult?.output?.$featureCollection\" :value=\"message.executionResult?.output\" />\n <pre v-else>{{ message.executionResult?.output || 'No output' }}</pre>\n </div>\n\n <modal ref=\"outputModal\" v-if=\"showDetailModal\" containerClass=\"!h-[90vh] !w-[90vw]\">\n <template #body>\n <div class=\"absolute font-mono right-1 top-1 cursor-pointer text-xl\" @click=\"showDetailModal = false;\">×</div>\n <div class=\"h-full overflow-auto\">\n <dashboard-chart v-if=\"message.executionResult?.output?.$chart\" :value=\"message.executionResult?.output\" :responsive=\"true\" />\n <pre v-else class=\"whitespace-pre-wrap\">{{ message.executionResult?.output || 'No output' }}</pre>\n </div>\n </template>\n </modal>\n <modal v-if=\"showCreateDashboardModal\">\n <template #body>\n <div class=\"modal-exit\" @click=\"showCreateDashboardModal = false\">×</div>\n <div>\n <div class=\"mt-4 text-gray-900 font-semibold\">Create Dashboard</div>\n <div class=\"mt-4\">\n <label class=\"block text-sm font-medium leading-6 text-gray-900\">Title</label>\n <div class=\"mt-2\">\n <div class=\"w-full flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-teal-600\">\n <input type=\"text\" v-model=\"newDashboardTitle\" class=\"outline-none block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6\" placeholder=\"My Dashboard\">\n </div>\n </div>\n </div>\n <div class=\"my-4\">\n <label class=\"block text-sm font-medium leading-6 text-gray-900\">Code</label>\n <div class=\"border border-gray-200\">\n <textarea class=\"p-2 h-[300px] w-full\" ref=\"dashboardCodeEditor\"></textarea>\n </div>\n </div>\n <async-button\n @click=\"createDashboardFromScript\"\n class=\"rounded-md bg-teal-600 px-2.5 py-1.5 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 Submit\n </async-button>\n <div v-if=\"createErrors.length > 0\" class=\"rounded-md bg-red-50 p-4 mt-1\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <svg class=\"h-5 w-5 text-red-400\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z\" clip-rule=\"evenodd\" />\n </svg>\n </div>\n <div class=\"ml-3\">\n <h3 class=\"text-sm font-medium text-red-800\">Error</h3>\n <div class=\"mt-2 text-sm text-red-700\">\n {{createError}}\n </div>\n </div>\n </div>\n </div>\n </div>\n </template>\n </modal>\n</div>\n";
|
|
4211
|
+
module.exports = "<div class=\"relative border rounded bg-gray-100 text-black text-sm overflow-hidden\">\n <div class=\"flex border-b pt-[1px] text-xs font-medium bg-gray-200\">\n <button\n class=\"px-3 py-1 border-r border-gray-300 hover:bg-green-300\"\n :class=\"{'bg-gray-300': activeTab === 'code', 'bg-green-300': activeTab === 'code'}\"\n @click=\"activeTab = 'code'\">\n Code\n </button>\n <button\n class=\"px-3 py-1 hover:bg-green-300\"\n :class=\"{'bg-green-300': activeTab === 'output'}\"\n @click=\"activeTab = 'output'\">\n Output\n </button>\n <div class=\"ml-auto mr-1 flex\">\n <button\n v-if=\"activeTab === 'output'\"\n class=\"px-2 py-1 mr-1 text-xs bg-gray-500 text-white border-none rounded cursor-pointer hover:bg-gray-600 transition-colors flex items-center\"\n @click=\"copyOutput\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3\" />\n </svg>\n </button>\n <button\n v-if=\"activeTab === 'output'\"\n class=\"px-2 py-1 mr-1 text-xs bg-blue-500 text-white border-none rounded cursor-pointer hover:bg-blue-600 transition-colors flex items-center\"\n @click=\"openDetailModal\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 1v4m0 0h-4m4 0l-5-5\" />\n </svg>\n </button>\n <async-button\n class=\"px-2 py-1 text-xs bg-green-500 text-white border-none rounded cursor-pointer hover:bg-green-600 transition-colors disabled:bg-gray-400\"\n @click=\"executeScript(message, script)\">\n Execute\n </async-button>\n <div class=\"relative ml-1\" ref=\"dropdown\">\n <button\n @click.stop=\"toggleDropdown\"\n class=\"px-1 py-1 text-xs hover:bg-gray-300 rounded flex items-center\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path d=\"M10 6a2 2 0 110-4 2 2 0 010 4zm0 6a2 2 0 110-4 2 2 0 010 4zm0 6a2 2 0 110-4 2 2 0 010 4z\" />\n </svg>\n </button>\n <div\n v-if=\"showDropdown\"\n class=\"absolute right-0 z-10 mt-1 w-64 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black/5\">\n <button\n class=\"block w-full text-left px-4 py-2 text-xs text-gray-700 hover:bg-gray-100\"\n @click=\"openCreateDashboardModal(); showDropdown = false\">\n Create Dashboard\n </button>\n <button\n class=\"block w-full text-left px-4 py-2 text-xs text-gray-700 hover:bg-gray-100\"\n @click=\"$emit('copyMessage'); showDropdown = false\">\n Copy Full Message\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <pre class=\"p-3 whitespace-pre-wrap max-h-[50vh] max-w-[calc(100vw-4rem)] lg:max-w-[calc(100vw-20rem)] overflow-y-auto\" v-show=\"activeTab === 'code'\"><code v-text=\"script\" ref=\"code\" :class=\"'language-' + language\"></code></pre>\n\n <div class=\"p-3 whitespace-pre-wrap max-h-[50vh] overflow-y-auto bg-white border-t max-w-[calc(100vw-4rem)] lg:max-w-[calc(100vw-20rem)] relative\" v-show=\"activeTab === 'output'\">\n <dashboard-chart v-if=\"message.executionResult?.output?.$chart\" :value=\"message.executionResult?.output\" />\n <dashboard-map v-else-if=\"message.executionResult?.output?.$featureCollection\" :value=\"message.executionResult?.output\" />\n <pre v-else>{{ message.executionResult?.output || 'No output' }}</pre>\n </div>\n\n <modal ref=\"outputModal\" v-if=\"showDetailModal\" containerClass=\"!h-[90vh] !w-[90vw]\">\n <template #body>\n <div class=\"absolute font-mono right-1 top-1 cursor-pointer text-xl\" @click=\"showDetailModal = false;\">×</div>\n <div class=\"h-full overflow-auto\">\n <dashboard-chart v-if=\"message.executionResult?.output?.$chart\" :value=\"message.executionResult?.output\" :responsive=\"true\" />\n <pre v-else class=\"whitespace-pre-wrap\">{{ message.executionResult?.output || 'No output' }}</pre>\n </div>\n </template>\n </modal>\n <modal v-if=\"showCreateDashboardModal\">\n <template #body>\n <div class=\"modal-exit\" @click=\"showCreateDashboardModal = false\">×</div>\n <div>\n <div class=\"mt-4 text-gray-900 font-semibold\">Create Dashboard</div>\n <div class=\"mt-4\">\n <label class=\"block text-sm font-medium leading-6 text-gray-900\">Title</label>\n <div class=\"mt-2\">\n <div class=\"w-full flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-teal-600\">\n <input type=\"text\" v-model=\"newDashboardTitle\" class=\"outline-none block flex-1 border-0 bg-transparent py-1.5 pl-1 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6\" placeholder=\"My Dashboard\">\n </div>\n </div>\n </div>\n <div class=\"my-4\">\n <label class=\"block text-sm font-medium leading-6 text-gray-900\">Code</label>\n <div class=\"border border-gray-200\">\n <textarea class=\"p-2 h-[300px] w-full\" ref=\"dashboardCodeEditor\"></textarea>\n </div>\n </div>\n <async-button\n @click=\"createDashboardFromScript\"\n class=\"rounded-md bg-teal-600 px-2.5 py-1.5 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 Submit\n </async-button>\n <div v-if=\"createErrors.length > 0\" class=\"rounded-md bg-red-50 p-4 mt-1\">\n <div class=\"flex\">\n <div class=\"flex-shrink-0\">\n <svg class=\"h-5 w-5 text-red-400\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\n <path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z\" clip-rule=\"evenodd\" />\n </svg>\n </div>\n <div class=\"ml-3\">\n <h3 class=\"text-sm font-medium text-red-800\">Error</h3>\n <div class=\"mt-2 text-sm text-red-700\">\n {{createError}}\n </div>\n </div>\n </div>\n </div>\n </div>\n </template>\n </modal>\n</div>\n";
|
|
4173
4212
|
|
|
4174
4213
|
/***/ }),
|
|
4175
4214
|
|
|
@@ -4180,7 +4219,7 @@ module.exports = "<div class=\"relative border rounded bg-gray-100 text-black te
|
|
|
4180
4219
|
/***/ ((module) => {
|
|
4181
4220
|
|
|
4182
4221
|
"use strict";
|
|
4183
|
-
module.exports = "<div class=\"relative flex items-start\" :class=\"{'justify-end': message.role === 'user'}\">\n <div\n class=\"min-w-0 max-w-[calc(100vw-
|
|
4222
|
+
module.exports = "<div class=\"relative flex items-start\" :class=\"{'justify-end': message.role === 'user'}\">\n <div\n class=\"min-w-0 max-w-[calc(100vw-3rem)] lg:max-w-[calc(100vw-15rem)]\"\n :class=\"{'text-right': message.role === 'user'}\">\n\n <div class=\"text-sm text-gray-900 rounded-md inline-block relative\" :class=\"styleForMessage\">\n <div v-for=\"part in contentSplitByScripts\">\n <div v-if=\"part.type === 'text'\" v-html=\"marked(part.content)\">\n </div>\n <div v-else-if=\"part.type === 'code'\">\n <chat-message-script :message=\"message\" :script=\"part.content\" :language=\"part.language\" @copyMessage=\"copyMessage\"></chat-message-script>\n </div>\n </div>\n </div>\n </div>\n</div>\n";
|
|
4184
4223
|
|
|
4185
4224
|
/***/ }),
|
|
4186
4225
|
|
|
@@ -4191,7 +4230,7 @@ module.exports = "<div class=\"relative flex items-start\" :class=\"{'justify-en
|
|
|
4191
4230
|
/***/ ((module) => {
|
|
4192
4231
|
|
|
4193
4232
|
"use strict";
|
|
4194
|
-
module.exports = "<div class=\"flex\" style=\"height: calc(100vh - 55px); height: calc(100dvh - 55px)\">\n <div class=\"fixed top-[65px] cursor-pointer bg-gray-100 rounded-r-md z-10\" @click=\"hideSidebar = false\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"h-5 w-5\" viewBox=\"0 -960 960 960\" class=\"w-5\" fill=\"#5f6368\"><path d=\"M360-120v-720h80v720h-80Zm160-160v-400l200 200-200 200Z\"/></svg>\n </div>\n <button\n class=\"fixed top-[65px] right-4 z-10 p-2 rounded-md shadow bg-white\"\n :class=\"hasWorkspace ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 cursor-not-allowed bg-gray-50'\"\n @click=\"toggleShareThread\"\n :disabled=\"!hasWorkspace || !chatThreadId || sharingThread\"\n aria-label=\"Share thread with workspace\"\n title=\"Share thread with workspace\"\n >\n <svg v-if=\"hasWorkspace\" xmlns=\"http://www.w3.org/2000/svg\" class=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7a2.48 2.48 0 0 0 0-1.39l7.02-4.11a2.5 2.5 0 1 0-.87-1.37L8.04 9.94a2.5 2.5 0 1 0 0 4.12l7.12 4.16a2.5 2.5 0 1 0 .84-1.34l-7.05-4.12c-.04-.02-.08-.05-.11-.07a2.48 2.48 0 0 0 0-1.39c.03-.02.07-.04.11-.07l7.11-4.16c.52.47 1.2.76 1.94.76a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0-1.94.94L7.97 8.43a2.5 2.5 0 1 0 0 7.14l9.09 5.3c.52-.47 1.2-.76 1.94-.76a2.5 2.5 0 1 0 0-5z\"/></svg>\n <svg v-else xmlns=\"http://www.w3.org/2000/svg\" class=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M12 1a5 5 0 00-5 5v3H6a2 2 0 00-2 2v9a2 2 0 002 2h12a2 2 0 002-2v-9a2 2 0 00-2-2h-1V6a5 5 0 00-5-5zm-3 8V6a3 3 0 016 0v3H9zm9 2v9H6v-9h12z\"/></svg>\n </button>\n <!-- Sidebar: Chat Threads -->\n <aside class=\"bg-gray-50 border-r overflow-y-auto overflow-x-hidden h-full transition-all duration-300 ease-in-out z-20 w-0 lg:w-64 fixed lg:relative\" :class=\"hideSidebar === true ? '!w-0' : hideSidebar === false ? '!w-64' : ''\">\n <div class=\"flex items-center border-b border-gray-100 w-64 overflow-x-hidden\">\n <div class=\"p-4 font-bold text-lg\">Chat Threads</div>\n <button\n @click=\"hideSidebar = true\"\n class=\"ml-auto mr-2 p-2 rounded hover:bg-gray-200 focus:outline-none\"\n aria-label=\"Close sidebar\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"h-5 w-5\" viewBox=\"0 -960 960 960\" class=\"w-5\" fill=\"currentColor\"><path d=\"M660-320v-320L500-480l160 160ZM200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm120-80v-560H200v560h120Zm80 0h360v-560H400v560Zm-80 0H200h120Z\"/></svg>\n </button>\n </div>\n <div class=\"p-4 w-64\">\n <async-button\n @click=\"createNewThread\"\n class=\"w-full bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700\"\n >\n Create New Thread\n </async-button>\n </div>\n <div v-if=\"status === 'loaded' && chatThreads.length === 0\" class=\"p-4 text-sm text-gray-700\">\n No threads yet\n </div>\n <ul v-if=\"status === 'loaded'\" class=\"w-64\">\n <li\n v-for=\"thread in chatThreads\"\n :key=\"thread._id\"\n @click=\"selectThread(thread._id)\"\n class=\"p-4 hover:bg-gray-200 cursor-pointer w-64\"\n :class=\"{ 'bg-gray-300': thread._id === chatThreadId }\"\n >\n {{ thread.title || 'Untitled Thread' }}\n </li>\n </ul>\n </aside>\n\n <!-- Main Chat Area -->\n <main class=\"flex-1 flex flex-col\">\n <div class=\"flex-1 overflow-y-auto p-6 space-y-4\" ref=\"messagesContainer\">\n <ul role=\"list\" class=\"space-y-4\">\n <div v-if=\"true\">\n <div class=\"flex items-center justify-center py-3 mb-4\">\n <div class=\"bg-gray-300 h-px flex-grow max-w-xs\"></div>\n <p class=\"mx-4 text-sm font-medium text-gray-500\">This is the beginning of the message thread</p>\n <div class=\"bg-gray-300 h-px flex-grow max-w-xs\"></div>\n </div>\n </div>\n <li v-for=\"message in chatMessages\" :key=\"message._id\">\n <chat-message :message=\"message\"></chat-message>\n </li>\n </ul>\n </div>\n\n\n <!-- Input Area -->\n <div class=\"border-t p-4\">\n <form @submit.prevent=\"sendMessage\" :disabled=\"sendingMessage\" class=\"flex gap-2 items-end justify-end\">\n <textarea\n v-model=\"newMessage\"\n placeholder=\"Ask something
|
|
4233
|
+
module.exports = "<div class=\"flex\" style=\"height: calc(100vh - 55px); height: calc(100dvh - 55px)\">\n <div class=\"fixed top-[65px] cursor-pointer bg-gray-100 rounded-r-md z-10\" @click=\"hideSidebar = false\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"h-5 w-5\" viewBox=\"0 -960 960 960\" class=\"w-5\" fill=\"#5f6368\"><path d=\"M360-120v-720h80v720h-80Zm160-160v-400l200 200-200 200Z\"/></svg>\n </div>\n <button\n class=\"fixed top-[65px] right-4 z-10 p-2 rounded-md shadow bg-white\"\n :class=\"hasWorkspace ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 cursor-not-allowed bg-gray-50'\"\n @click=\"toggleShareThread\"\n :disabled=\"!hasWorkspace || !chatThreadId || sharingThread\"\n aria-label=\"Share thread with workspace\"\n title=\"Share thread with workspace\"\n >\n <svg v-if=\"hasWorkspace\" xmlns=\"http://www.w3.org/2000/svg\" class=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7a2.48 2.48 0 0 0 0-1.39l7.02-4.11a2.5 2.5 0 1 0-.87-1.37L8.04 9.94a2.5 2.5 0 1 0 0 4.12l7.12 4.16a2.5 2.5 0 1 0 .84-1.34l-7.05-4.12c-.04-.02-.08-.05-.11-.07a2.48 2.48 0 0 0 0-1.39c.03-.02.07-.04.11-.07l7.11-4.16c.52.47 1.2.76 1.94.76a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0-1.94.94L7.97 8.43a2.5 2.5 0 1 0 0 7.14l9.09 5.3c.52-.47 1.2-.76 1.94-.76a2.5 2.5 0 1 0 0-5z\"/></svg>\n <svg v-else xmlns=\"http://www.w3.org/2000/svg\" class=\"w-5 h-5\" fill=\"currentColor\" viewBox=\"0 0 24 24\"><path d=\"M12 1a5 5 0 00-5 5v3H6a2 2 0 00-2 2v9a2 2 0 002 2h12a2 2 0 002-2v-9a2 2 0 00-2-2h-1V6a5 5 0 00-5-5zm-3 8V6a3 3 0 016 0v3H9zm9 2v9H6v-9h12z\"/></svg>\n </button>\n <!-- Sidebar: Chat Threads -->\n <aside class=\"bg-gray-50 border-r overflow-y-auto overflow-x-hidden h-full transition-all duration-300 ease-in-out z-20 w-0 lg:w-64 fixed lg:relative\" :class=\"hideSidebar === true ? '!w-0' : hideSidebar === false ? '!w-64' : ''\">\n <div class=\"flex items-center border-b border-gray-100 w-64 overflow-x-hidden\">\n <div class=\"p-4 font-bold text-lg\">Chat Threads</div>\n <button\n @click=\"hideSidebar = true\"\n class=\"ml-auto mr-2 p-2 rounded hover:bg-gray-200 focus:outline-none\"\n aria-label=\"Close sidebar\"\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"h-5 w-5\" viewBox=\"0 -960 960 960\" class=\"w-5\" fill=\"currentColor\"><path d=\"M660-320v-320L500-480l160 160ZM200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Zm120-80v-560H200v560h120Zm80 0h360v-560H400v560Zm-80 0H200h120Z\"/></svg>\n </button>\n </div>\n <div class=\"p-4 w-64\">\n <async-button\n @click=\"createNewThread\"\n class=\"w-full bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700\"\n >\n Create New Thread\n </async-button>\n </div>\n <div v-if=\"status === 'loaded' && chatThreads.length === 0\" class=\"p-4 text-sm text-gray-700\">\n No threads yet\n </div>\n <ul v-if=\"status === 'loaded'\" class=\"w-64\">\n <li\n v-for=\"thread in chatThreads\"\n :key=\"thread._id\"\n @click=\"selectThread(thread._id)\"\n class=\"p-4 hover:bg-gray-200 cursor-pointer w-64\"\n :class=\"{ 'bg-gray-300': thread._id === chatThreadId }\"\n >\n {{ thread.title || 'Untitled Thread' }}\n </li>\n </ul>\n </aside>\n\n <!-- Main Chat Area -->\n <main class=\"flex-1 flex flex-col\">\n <div class=\"flex-1 overflow-y-auto p-6 space-y-4\" ref=\"messagesContainer\">\n <ul role=\"list\" class=\"space-y-4\">\n <div v-if=\"true\">\n <div class=\"flex items-center justify-center py-3 mb-4\">\n <div class=\"bg-gray-300 h-px flex-grow max-w-xs\"></div>\n <p class=\"mx-4 text-sm font-medium text-gray-500\">This is the beginning of the message thread</p>\n <div class=\"bg-gray-300 h-px flex-grow max-w-xs\"></div>\n </div>\n </div>\n <li v-for=\"message in chatMessages\" :key=\"message._id\">\n <chat-message :message=\"message\"></chat-message>\n </li>\n </ul>\n </div>\n\n\n <!-- Input Area -->\n <div class=\"border-t p-4\">\n <form @submit.prevent=\"sendMessage\" :disabled=\"sendingMessage\" class=\"flex gap-2 items-end justify-end\">\n <textarea\n v-model=\"newMessage\"\n :placeholder=\"sendingMessage ? 'Sending...' : 'Ask something...'\"\n class=\"flex-1 border rounded px-4 py-2 resize-none overflow-y-auto\"\n :disabled=\"sendingMessage\"\n rows=\"1\"\n ref=\"messageInput\"\n @input=\"adjustTextareaHeight\"\n @keydown.enter.exact.prevent=\"handleEnter\"\n ></textarea>\n <button class=\"bg-blue-600 text-white px-4 h-[42px] rounded disabled:bg-gray-600\" :disabled=\"sendingMessage\">\n <svg v-if=\"sendingMessage\" style=\"height: 1em\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <g>\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" opacity=\"0.3\" />\n <path d=\"M12 2a10 10 0 0 1 10 10\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 12 12\" to=\"360 12 12\" dur=\"1s\" repeatCount=\"indefinite\" />\n </path>\n </g>\n </svg>\n <span v-else>Send</span>\n </button>\n </form>\n </div>\n </main>\n</div>\n";
|
|
4195
4234
|
|
|
4196
4235
|
/***/ }),
|
|
4197
4236
|
|
|
@@ -4257,7 +4296,7 @@ module.exports = "<div>\n <div class=\"mb-2\">\n <textarea class=\"border bo
|
|
|
4257
4296
|
/***/ ((module) => {
|
|
4258
4297
|
|
|
4259
4298
|
"use strict";
|
|
4260
|
-
module.exports = "<div :class=\"responsive ? 'h-full' : ''\">\n <div v-if=\"header\" class=\"border-b border-gray-100 px-2 pb-2 flex items-center\">\n <div class=\"text-xl font-bold\">{{header}}</div>\n <button\n class=\"ml-auto px-2 py-1 text-xs bg-ultramarine-600 text-white border-none rounded cursor-pointer hover:bg-ultramarine-500 transition-colors\"\n @click=\"exportPNG\"\n title=\"Export PNG\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"height: 1.5em;\" viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M280-280h400v-80H280v80Zm200-120 160-160-56-56-64 62v-166h-80v166l-64-62-56 56 160 160Zm0 320q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z\"/></svg>\n </button>\n </div>\n <div v-else class=\"border-b border-gray-100 px-2 pb-2 text-right\">\n <button\n class=\"
|
|
4299
|
+
module.exports = "<div :class=\"responsive ? 'h-full' : ''\">\n <div v-if=\"header && !fullscreen\" class=\"border-b border-gray-100 px-2 pb-2 flex items-center gap-1\">\n <div class=\"text-xl font-bold\">{{header}}</div>\n <button\n class=\"ml-auto px-2 py-1 text-xs bg-ultramarine-600 text-white border-none rounded cursor-pointer hover:bg-ultramarine-500 transition-colors\"\n @click=\"exportPNG\"\n title=\"Export PNG\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"height: 1.5em;\" viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M280-280h400v-80H280v80Zm200-120 160-160-56-56-64 62v-166h-80v166l-64-62-56 56 160 160Zm0 320q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z\"/></svg>\n </button>\n <button\n class=\"px-2 py-1 text-xs bg-ultramarine-600 text-white border-none rounded cursor-pointer hover:bg-ultramarine-500 transition-colors flex items-center\"\n @click=\"$emit('fullscreen')\"\n aria-label=\"Expand dashboard result\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"height: 1.5em\" class=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 1v4m0 0h-4m4 0l-5-5\" />\n </svg>\n </button>\n </div>\n <div v-else-if=\"!fullscreen\" class=\"pt-1 border-b border-gray-100 px-2 pb-2 text-right flex items-center justify-end gap-1 w-full\">\n <button\n class=\"px-2 py-1 text-xs bg-ultramarine-600 text-white border-none rounded cursor-pointer hover:bg-ultramarine-500 transition-colors\"\n @click=\"exportPNG\"\n title=\"Export PNG\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"height: 1.5em;\" viewBox=\"0 -960 960 960\" fill=\"currentColor\"><path d=\"M280-280h400v-80H280v80Zm200-120 160-160-56-56-64 62v-166h-80v166l-64-62-56 56 160 160Zm0 320q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z\"/></svg>\n </button>\n <button\n class=\"px-2 py-1 text-xs bg-ultramarine-600 text-white border-none rounded cursor-pointer hover:bg-ultramarine-500 transition-colors flex items-center\"\n @click=\"$emit('fullscreen')\"\n aria-label=\"Expand dashboard result\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" style=\"height: 1.5em\" class=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 1v4m0 0h-4m4 0l-5-5\" />\n </svg>\n </button>\n </div>\n <div :class=\"responsive ? 'relative h-full min-h-0' : ''\">\n <canvas ref=\"chart\" class=\"block w-full h-full\"></canvas>\n </div>\n</div>\n";
|
|
4261
4300
|
|
|
4262
4301
|
/***/ }),
|
|
4263
4302
|
|
|
@@ -4301,7 +4340,7 @@ module.exports = "<div class=\"py-2\">\n <div v-if=\"header\" class=\"border-b
|
|
|
4301
4340
|
/***/ ((module) => {
|
|
4302
4341
|
|
|
4303
4342
|
"use strict";
|
|
4304
|
-
module.exports = "<div>\n <div v-if=\"Array.isArray(result)\">\n <div v-for=\"el in result\" :key=\"el._id || el.finishedEvaluatingAt\">\n <component\n class=\"bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl\"\n :is=\"getComponentForValue(el)\"\n :value=\"el\">\n </component>\n </div>\n </div>\n <div v-else>\n <component\n class=\"bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl\"\n :is=\"getComponentForValue(result)\"\n :value=\"result\">\n </component>\n </div>\n <div class=\"text-right text-sm text-gray-700 mt-1\" v-if=\"finishedEvaluatingAt\">\n Last Evaluated: {{ format.isoToLongDateTime(finishedEvaluatingAt) }}\n </div>\n</div>\n";
|
|
4343
|
+
module.exports = "<div>\n <div v-if=\"Array.isArray(result)\">\n <div v-for=\"el in result\" :key=\"el._id || el.finishedEvaluatingAt\">\n <component\n class=\"bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl\"\n :is=\"getComponentForValue(el)\"\n :value=\"el\">\n </component>\n </div>\n </div>\n <div v-else>\n <component\n class=\"bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl\"\n :is=\"getComponentForValue(result)\"\n :value=\"result\"\n :fullscreen=\"fullscreen\"\n @fullscreen=\"$emit('fullscreen')\">\n </component>\n </div>\n <div class=\"text-right text-sm text-gray-700 mt-1\" v-if=\"finishedEvaluatingAt && !fullscreen\">\n Last Evaluated: {{ format.isoToLongDateTime(finishedEvaluatingAt) }}\n </div>\n</div>\n";
|
|
4305
4344
|
|
|
4306
4345
|
/***/ }),
|
|
4307
4346
|
|
|
@@ -4323,7 +4362,7 @@ module.exports = "<div class=\"py-2\">\n <div v-if=\"header\" class=\"border-b
|
|
|
4323
4362
|
/***/ ((module) => {
|
|
4324
4363
|
|
|
4325
4364
|
"use strict";
|
|
4326
|
-
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 <
|
|
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\">×</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";
|
|
4327
4366
|
|
|
4328
4367
|
/***/ }),
|
|
4329
4368
|
|
|
@@ -14837,7 +14876,7 @@ var bson = /*#__PURE__*/Object.freeze({
|
|
|
14837
14876
|
/***/ ((module) => {
|
|
14838
14877
|
|
|
14839
14878
|
"use strict";
|
|
14840
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@mongoosejs/studio","version":"0.0.
|
|
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"}}');
|
|
14841
14880
|
|
|
14842
14881
|
/***/ })
|
|
14843
14882
|
|
package/frontend/public/tw.css
CHANGED
|
@@ -642,6 +642,10 @@ video {
|
|
|
642
642
|
top: 90%;
|
|
643
643
|
}
|
|
644
644
|
|
|
645
|
+
.bottom-0 {
|
|
646
|
+
bottom: 0px;
|
|
647
|
+
}
|
|
648
|
+
|
|
645
649
|
.isolate {
|
|
646
650
|
isolation: isolate;
|
|
647
651
|
}
|
|
@@ -882,6 +886,10 @@ video {
|
|
|
882
886
|
height: 32px;
|
|
883
887
|
}
|
|
884
888
|
|
|
889
|
+
.h-\[40vh\] {
|
|
890
|
+
height: 40vh;
|
|
891
|
+
}
|
|
892
|
+
|
|
885
893
|
.h-\[42px\] {
|
|
886
894
|
height: 42px;
|
|
887
895
|
}
|
|
@@ -898,6 +906,10 @@ video {
|
|
|
898
906
|
max-height: 50vh;
|
|
899
907
|
}
|
|
900
908
|
|
|
909
|
+
.min-h-0 {
|
|
910
|
+
min-height: 0px;
|
|
911
|
+
}
|
|
912
|
+
|
|
901
913
|
.\!w-0 {
|
|
902
914
|
width: 0px !important;
|
|
903
915
|
}
|
|
@@ -978,6 +990,10 @@ video {
|
|
|
978
990
|
max-width: 20rem;
|
|
979
991
|
}
|
|
980
992
|
|
|
993
|
+
.max-w-\[calc\(100vw-3rem\)\] {
|
|
994
|
+
max-width: calc(100vw - 3rem);
|
|
995
|
+
}
|
|
996
|
+
|
|
981
997
|
.flex-1 {
|
|
982
998
|
flex: 1 1 0%;
|
|
983
999
|
}
|
|
@@ -2069,6 +2085,11 @@ video {
|
|
|
2069
2085
|
color: rgb(10 87 87 / var(--tw-text-opacity));
|
|
2070
2086
|
}
|
|
2071
2087
|
|
|
2088
|
+
.hover\:text-gray-600:hover {
|
|
2089
|
+
--tw-text-opacity: 1;
|
|
2090
|
+
color: rgb(75 85 99 / var(--tw-text-opacity));
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2072
2093
|
.focus\:z-10:focus {
|
|
2073
2094
|
z-index: 10;
|
|
2074
2095
|
}
|
|
@@ -2374,6 +2395,10 @@ video {
|
|
|
2374
2395
|
max-width: calc(100vw - 20rem);
|
|
2375
2396
|
}
|
|
2376
2397
|
|
|
2398
|
+
.lg\:max-w-\[calc\(100vw-15rem\)\] {
|
|
2399
|
+
max-width: calc(100vw - 15rem);
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2377
2402
|
.lg\:px-8 {
|
|
2378
2403
|
padding-left: 2rem;
|
|
2379
2404
|
padding-right: 2rem;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<div class="relative flex items-start" :class="{'justify-end': message.role === 'user'}">
|
|
2
2
|
<div
|
|
3
|
-
class="min-w-0 max-w-[calc(100vw-
|
|
3
|
+
class="min-w-0 max-w-[calc(100vw-3rem)] lg:max-w-[calc(100vw-15rem)]"
|
|
4
4
|
:class="{'text-right': message.role === 'user'}">
|
|
5
5
|
|
|
6
|
-
<div class="text-sm text-gray-900
|
|
6
|
+
<div class="text-sm text-gray-900 rounded-md inline-block relative" :class="styleForMessage">
|
|
7
7
|
<div v-for="part in contentSplitByScripts">
|
|
8
8
|
<div v-if="part.type === 'text'" v-html="marked(part.content)">
|
|
9
9
|
</div>
|
|
10
10
|
<div v-else-if="part.type === 'code'">
|
|
11
|
-
<chat-message-script :message="message" :script="part.content" :language="part.language"></chat-message-script>
|
|
11
|
+
<chat-message-script :message="message" :script="part.content" :language="part.language" @copyMessage="copyMessage"></chat-message-script>
|
|
12
12
|
</div>
|
|
13
13
|
</div>
|
|
14
14
|
</div>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const api = require('../../api');
|
|
4
4
|
const marked = require('marked').marked;
|
|
5
|
+
const vanillatoasts = require('vanillatoasts');
|
|
5
6
|
const template = require('./chat-message.html');
|
|
6
7
|
|
|
7
8
|
module.exports = app => app.component('chat-message', {
|
|
@@ -9,7 +10,7 @@ module.exports = app => app.component('chat-message', {
|
|
|
9
10
|
props: ['message'],
|
|
10
11
|
computed: {
|
|
11
12
|
styleForMessage() {
|
|
12
|
-
return this.message.role === 'user' ? 'bg-gray-100' : '';
|
|
13
|
+
return this.message.role === 'user' ? 'p-3 bg-gray-100' : 'py-3 pr-3';
|
|
13
14
|
},
|
|
14
15
|
contentSplitByScripts() {
|
|
15
16
|
const content = this.message.content;
|
|
@@ -61,6 +62,37 @@ module.exports = app => app.component('chat-message', {
|
|
|
61
62
|
});
|
|
62
63
|
message.executionResult = chatMessage.executionResult;
|
|
63
64
|
console.log(message);
|
|
65
|
+
},
|
|
66
|
+
async copyMessage() {
|
|
67
|
+
const parts = this.contentSplitByScripts;
|
|
68
|
+
let output = '';
|
|
69
|
+
for (const part of parts) {
|
|
70
|
+
if (part.type === 'text') {
|
|
71
|
+
output += part.content + '\n';
|
|
72
|
+
} else if (part.type === 'code') {
|
|
73
|
+
let result = this.message.executionResult?.output;
|
|
74
|
+
if (result != null && typeof result === 'object') {
|
|
75
|
+
result = JSON.stringify(result, null, 2);
|
|
76
|
+
}
|
|
77
|
+
if (result) {
|
|
78
|
+
let executionOutput = this.message.executionResult?.output;
|
|
79
|
+
if (executionOutput != null && typeof executionOutput === 'object') {
|
|
80
|
+
executionOutput = JSON.stringify(executionOutput, null, 2);
|
|
81
|
+
}
|
|
82
|
+
if (executionOutput) {
|
|
83
|
+
output += '```\n' + executionOutput + '\n```\n';
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
await navigator.clipboard.writeText(output.trim());
|
|
89
|
+
vanillatoasts.create({
|
|
90
|
+
title: 'Message output copied!',
|
|
91
|
+
type: 'success',
|
|
92
|
+
timeout: 3000,
|
|
93
|
+
icon: 'images/success.png',
|
|
94
|
+
positionClass: 'bottomRight'
|
|
95
|
+
});
|
|
64
96
|
}
|
|
65
97
|
}
|
|
66
98
|
});
|
|
@@ -50,6 +50,11 @@
|
|
|
50
50
|
@click="openCreateDashboardModal(); showDropdown = false">
|
|
51
51
|
Create Dashboard
|
|
52
52
|
</button>
|
|
53
|
+
<button
|
|
54
|
+
class="block w-full text-left px-4 py-2 text-xs text-gray-700 hover:bg-gray-100"
|
|
55
|
+
@click="$emit('copyMessage'); showDropdown = false">
|
|
56
|
+
Copy Full Message
|
|
57
|
+
</button>
|
|
53
58
|
</div>
|
|
54
59
|
</div>
|
|
55
60
|
</div>
|
|
@@ -7,6 +7,7 @@ const vanillatoasts = require('vanillatoasts');
|
|
|
7
7
|
module.exports = app => app.component('chat-message-script', {
|
|
8
8
|
template,
|
|
9
9
|
props: ['message', 'script', 'language'],
|
|
10
|
+
emits: ['copyMessage'],
|
|
10
11
|
data() {
|
|
11
12
|
return {
|
|
12
13
|
activeTab: 'code',
|
|
@@ -82,9 +83,13 @@ module.exports = app => app.component('chat-message-script', {
|
|
|
82
83
|
this.$router.push('/dashboard/' + dashboard._id);
|
|
83
84
|
},
|
|
84
85
|
async copyOutput() {
|
|
85
|
-
|
|
86
|
+
let output = this.message.executionResult.output;
|
|
87
|
+
if (output != null && typeof output === 'object') {
|
|
88
|
+
output = JSON.stringify(output, null, 2);
|
|
89
|
+
}
|
|
90
|
+
await navigator.clipboard.writeText(output);
|
|
86
91
|
vanillatoasts.create({
|
|
87
|
-
title: '
|
|
92
|
+
title: 'Code output copied!',
|
|
88
93
|
type: 'success',
|
|
89
94
|
timeout: 3000,
|
|
90
95
|
icon: 'images/success.png',
|
|
@@ -72,8 +72,9 @@
|
|
|
72
72
|
<form @submit.prevent="sendMessage" :disabled="sendingMessage" class="flex gap-2 items-end justify-end">
|
|
73
73
|
<textarea
|
|
74
74
|
v-model="newMessage"
|
|
75
|
-
placeholder="Ask something..."
|
|
75
|
+
:placeholder="sendingMessage ? 'Sending...' : 'Ask something...'"
|
|
76
76
|
class="flex-1 border rounded px-4 py-2 resize-none overflow-y-auto"
|
|
77
|
+
:disabled="sendingMessage"
|
|
77
78
|
rows="1"
|
|
78
79
|
ref="messageInput"
|
|
79
80
|
@input="adjustTextareaHeight"
|
|
@@ -21,6 +21,8 @@ module.exports = app => app.component('chat', {
|
|
|
21
21
|
async sendMessage() {
|
|
22
22
|
this.sendingMessage = true;
|
|
23
23
|
try {
|
|
24
|
+
const content = this.newMessage;
|
|
25
|
+
this.newMessage = '';
|
|
24
26
|
if (!this.chatThreadId) {
|
|
25
27
|
const { chatThread } = await api.ChatThread.createChatThread();
|
|
26
28
|
this.chatThreads.unshift(chatThread);
|
|
@@ -29,7 +31,7 @@ module.exports = app => app.component('chat', {
|
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
this.chatMessages.push({
|
|
32
|
-
content
|
|
34
|
+
content,
|
|
33
35
|
role: 'user'
|
|
34
36
|
});
|
|
35
37
|
|
|
@@ -41,7 +43,7 @@ module.exports = app => app.component('chat', {
|
|
|
41
43
|
|
|
42
44
|
const { chatMessages, chatThread } = await api.ChatThread.createChatMessage({
|
|
43
45
|
chatThreadId: this.chatThreadId,
|
|
44
|
-
content
|
|
46
|
+
content
|
|
45
47
|
});
|
|
46
48
|
this.chatMessages.push(chatMessages[1]);
|
|
47
49
|
for (const thread of this.chatThreads) {
|
|
@@ -41,18 +41,13 @@
|
|
|
41
41
|
</div>
|
|
42
42
|
<div v-else>
|
|
43
43
|
<div class="relative">
|
|
44
|
-
<button
|
|
45
|
-
class="absolute top-2 right-2 px-2 py-1 text-xs bg-blue-500 text-white border-none rounded cursor-pointer hover:bg-blue-600 transition-colors flex items-center"
|
|
46
|
-
@click="openDetailModal"
|
|
47
|
-
aria-label="Expand dashboard result">
|
|
48
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
49
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 1v4m0 0h-4m4 0l-5-5" />
|
|
50
|
-
</svg>
|
|
51
|
-
</button>
|
|
52
44
|
<dashboard-result
|
|
53
45
|
:key="dashboardResult.finishedEvaluatingAt"
|
|
54
46
|
:result="dashboardResult.result"
|
|
55
|
-
:finishedEvaluatingAt="dashboardResult.finishedEvaluatingAt"
|
|
47
|
+
:finishedEvaluatingAt="dashboardResult.finishedEvaluatingAt"
|
|
48
|
+
@fullscreen="showDetailModal = true"
|
|
49
|
+
class="h-[40vh]"
|
|
50
|
+
>
|
|
56
51
|
</dashboard-result>
|
|
57
52
|
</div>
|
|
58
53
|
</div>
|
|
@@ -98,7 +93,9 @@
|
|
|
98
93
|
<dashboard-result
|
|
99
94
|
v-if="dashboardResult"
|
|
100
95
|
:result="dashboardResult.result"
|
|
101
|
-
:finishedEvaluatingAt="dashboardResult.finishedEvaluatingAt"
|
|
96
|
+
:finishedEvaluatingAt="dashboardResult.finishedEvaluatingAt"
|
|
97
|
+
:fullscreen="true"
|
|
98
|
+
:responsive="true">
|
|
102
99
|
</dashboard-result>
|
|
103
100
|
</div>
|
|
104
101
|
</template>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<div :class="responsive ? 'h-full' : ''">
|
|
2
|
-
<div v-if="header" class="border-b border-gray-100 px-2 pb-2 flex items-center">
|
|
2
|
+
<div v-if="header && !fullscreen" class="border-b border-gray-100 px-2 pb-2 flex items-center gap-1">
|
|
3
3
|
<div class="text-xl font-bold">{{header}}</div>
|
|
4
4
|
<button
|
|
5
5
|
class="ml-auto px-2 py-1 text-xs bg-ultramarine-600 text-white border-none rounded cursor-pointer hover:bg-ultramarine-500 transition-colors"
|
|
@@ -7,16 +7,32 @@
|
|
|
7
7
|
title="Export PNG">
|
|
8
8
|
<svg xmlns="http://www.w3.org/2000/svg" style="height: 1.5em;" viewBox="0 -960 960 960" fill="currentColor"><path d="M280-280h400v-80H280v80Zm200-120 160-160-56-56-64 62v-166h-80v166l-64-62-56 56 160 160Zm0 320q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>
|
|
9
9
|
</button>
|
|
10
|
+
<button
|
|
11
|
+
class="px-2 py-1 text-xs bg-ultramarine-600 text-white border-none rounded cursor-pointer hover:bg-ultramarine-500 transition-colors flex items-center"
|
|
12
|
+
@click="$emit('fullscreen')"
|
|
13
|
+
aria-label="Expand dashboard result">
|
|
14
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="height: 1.5em" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
15
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 1v4m0 0h-4m4 0l-5-5" />
|
|
16
|
+
</svg>
|
|
17
|
+
</button>
|
|
10
18
|
</div>
|
|
11
|
-
<div v-else class="border-b border-gray-100 px-2 pb-2 text-right">
|
|
19
|
+
<div v-else-if="!fullscreen" class="pt-1 border-b border-gray-100 px-2 pb-2 text-right flex items-center justify-end gap-1 w-full">
|
|
12
20
|
<button
|
|
13
|
-
class="
|
|
21
|
+
class="px-2 py-1 text-xs bg-ultramarine-600 text-white border-none rounded cursor-pointer hover:bg-ultramarine-500 transition-colors"
|
|
14
22
|
@click="exportPNG"
|
|
15
23
|
title="Export PNG">
|
|
16
24
|
<svg xmlns="http://www.w3.org/2000/svg" style="height: 1.5em;" viewBox="0 -960 960 960" fill="currentColor"><path d="M280-280h400v-80H280v80Zm200-120 160-160-56-56-64 62v-166h-80v166l-64-62-56 56 160 160Zm0 320q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>
|
|
17
25
|
</button>
|
|
26
|
+
<button
|
|
27
|
+
class="px-2 py-1 text-xs bg-ultramarine-600 text-white border-none rounded cursor-pointer hover:bg-ultramarine-500 transition-colors flex items-center"
|
|
28
|
+
@click="$emit('fullscreen')"
|
|
29
|
+
aria-label="Expand dashboard result">
|
|
30
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="height: 1.5em" class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
31
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 1v4m0 0h-4m4 0l-5-5" />
|
|
32
|
+
</svg>
|
|
33
|
+
</button>
|
|
18
34
|
</div>
|
|
19
|
-
<div
|
|
20
|
-
<canvas ref="chart"></canvas>
|
|
35
|
+
<div :class="responsive ? 'relative h-full min-h-0' : ''">
|
|
36
|
+
<canvas ref="chart" class="block w-full h-full"></canvas>
|
|
21
37
|
</div>
|
|
22
38
|
</div>
|
|
@@ -4,9 +4,11 @@ const template = require('./dashboard-chart.html');
|
|
|
4
4
|
|
|
5
5
|
module.exports = app => app.component('dashboard-chart', {
|
|
6
6
|
template: template,
|
|
7
|
-
props: ['value', '
|
|
7
|
+
props: ['value', 'fullscreen'],
|
|
8
|
+
emits: ['fullscreen'],
|
|
8
9
|
data: () => ({
|
|
9
|
-
chart: null
|
|
10
|
+
chart: null,
|
|
11
|
+
showDetailModal: false
|
|
10
12
|
}),
|
|
11
13
|
mounted() {
|
|
12
14
|
const ctx = this.$refs.chart.getContext('2d');
|
|
@@ -12,10 +12,12 @@
|
|
|
12
12
|
<component
|
|
13
13
|
class="bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl"
|
|
14
14
|
:is="getComponentForValue(result)"
|
|
15
|
-
:value="result"
|
|
15
|
+
:value="result"
|
|
16
|
+
:fullscreen="fullscreen"
|
|
17
|
+
@fullscreen="$emit('fullscreen')">
|
|
16
18
|
</component>
|
|
17
19
|
</div>
|
|
18
|
-
<div class="text-right text-sm text-gray-700 mt-1" v-if="finishedEvaluatingAt">
|
|
20
|
+
<div class="text-right text-sm text-gray-700 mt-1" v-if="finishedEvaluatingAt && !fullscreen">
|
|
19
21
|
Last Evaluated: {{ format.isoToLongDateTime(finishedEvaluatingAt) }}
|
|
20
22
|
</div>
|
|
21
23
|
</div>
|
|
@@ -7,7 +7,8 @@ const template = require('./dashboard-result.html');
|
|
|
7
7
|
|
|
8
8
|
module.exports = app => app.component('dashboard-result', {
|
|
9
9
|
template: template,
|
|
10
|
-
props: ['result', 'finishedEvaluatingAt'],
|
|
10
|
+
props: ['result', 'finishedEvaluatingAt', 'fullscreen'],
|
|
11
|
+
emits: ['fullscreen'],
|
|
11
12
|
mounted: async function() {
|
|
12
13
|
},
|
|
13
14
|
methods: {
|
|
@@ -194,13 +194,13 @@ module.exports = app => app.component('models', {
|
|
|
194
194
|
this.query.search = this.searchText;
|
|
195
195
|
const query = this.query;
|
|
196
196
|
const newUrl = this.$router.resolve({ query }).href;
|
|
197
|
-
|
|
197
|
+
this.$router.push({ query });
|
|
198
198
|
} else {
|
|
199
199
|
this.filter = {};
|
|
200
200
|
delete this.query.search;
|
|
201
201
|
const query = this.query;
|
|
202
202
|
const newUrl = this.$router.resolve({ query }).href;
|
|
203
|
-
|
|
203
|
+
this.$router.push({ query });
|
|
204
204
|
}
|
|
205
205
|
this.documents = [];
|
|
206
206
|
this.status = 'loading';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mongoosejs/studio",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.116",
|
|
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": {
|