@mongoosejs/studio 0.0.95 → 0.0.96

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.
@@ -324,12 +324,11 @@ module.exports = app => app.component('async-button', {
324
324
 
325
325
 
326
326
  const api = __webpack_require__(/*! ../../api */ "./frontend/src/api.js");
327
- const marked = (__webpack_require__(/*! marked */ "./node_modules/marked/lib/marked.cjs").marked);
328
327
  const template = __webpack_require__(/*! ./chat-message-script.html */ "./frontend/src/chat/chat-message-script/chat-message-script.html");
329
328
  const vanillatoasts = __webpack_require__(/*! vanillatoasts */ "./node_modules/vanillatoasts/vanillatoasts.js");
330
329
 
331
330
  module.exports = app => app.component('chat-message-script', {
332
- template: template,
331
+ template,
333
332
  props: ['message', 'script', 'language'],
334
333
  data: () => ({ activeTab: 'code', showDetailModal: false }),
335
334
  computed: {
@@ -469,7 +468,8 @@ module.exports = app => app.component('chat', {
469
468
  newMessage: '',
470
469
  chatThreadId: null,
471
470
  chatThreads: [],
472
- chatMessages: []
471
+ chatMessages: [],
472
+ hideSidebar: null
473
473
  }),
474
474
  methods: {
475
475
  async sendMessage() {
@@ -2700,6 +2700,22 @@ module.exports = app => app.component('navbar', {
2700
2700
  this.$router.push({ name: firstAllowedRoute.name });
2701
2701
  }
2702
2702
  }
2703
+
2704
+ const mobileMenuMask = document.querySelector('#mobile-menu-mask');
2705
+ const mobileMenu = document.querySelector('#mobile-menu');
2706
+
2707
+ document.querySelector('#open-mobile-menu').addEventListener('click', (event) => {
2708
+ event.stopPropagation();
2709
+ mobileMenuMask.style.display = 'block';
2710
+ mobileMenu.classList.remove('translate-x-full');
2711
+ mobileMenu.classList.add('translate-x-0');
2712
+ });
2713
+
2714
+ document.querySelector('body').addEventListener('click', () => {
2715
+ mobileMenuMask.style.display = 'none';
2716
+ mobileMenu.classList.remove('translate-x-0');
2717
+ mobileMenu.classList.add('translate-x-full');
2718
+ });
2703
2719
  },
2704
2720
  computed: {
2705
2721
  dashboardView() {
@@ -3881,7 +3897,7 @@ module.exports = "<button v-bind=\"attrsToBind\" :disabled=\"isDisabled\" @click
3881
3897
  /***/ ((module) => {
3882
3898
 
3883
3899
  "use strict";
3884
- 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>\n </div>\n\n <pre class=\"p-3 whitespace-pre-wrap max-h-[30vh] max-w-[calc(100vw-25rem)] 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-[30vh] overflow-y-auto bg-white border-t max-w-[calc(100vw-25rem)] relative\" v-show=\"activeTab === 'output'\">\n <dashboard-chart v-if=\"message.executionResult?.output?.$chart\" :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;\">&times;</div>\n <div class=\"h-full overflow-auto\">\n <dashboard-chart v-if=\"message.executionResult?.output?.$chart\" :value=\"message.executionResult?.output\" />\n <pre v-else class=\"whitespace-pre-wrap\">{{ message.executionResult?.output || 'No output' }}</pre>\n </div>\n </template>\n </modal>\n</div>\n";
3900
+ 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>\n </div>\n\n <pre class=\"p-3 whitespace-pre-wrap max-h-[30vh] max-w-[calc(100vw-4rem)] 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-[30vh] overflow-y-auto bg-white border-t max-w-[calc(100vw-4rem)] relative\" v-show=\"activeTab === 'output'\">\n <dashboard-chart v-if=\"message.executionResult?.output?.$chart\" :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;\">&times;</div>\n <div class=\"h-full overflow-auto\">\n <dashboard-chart v-if=\"message.executionResult?.output?.$chart\" :value=\"message.executionResult?.output\" />\n <pre v-else class=\"whitespace-pre-wrap\">{{ message.executionResult?.output || 'No output' }}</pre>\n </div>\n </template>\n </modal>\n</div>\n";
3885
3901
 
3886
3902
  /***/ }),
3887
3903
 
@@ -3892,7 +3908,7 @@ module.exports = "<div class=\"relative border rounded bg-gray-100 text-black te
3892
3908
  /***/ ((module) => {
3893
3909
 
3894
3910
  "use strict";
3895
- module.exports = "<div class=\"relative flex items-start space-x-3\" :class=\"{'justify-end': message.role === 'user'}\">\n <div\n class=\"min-w-0 max-w-[calc(100%-6.5rem)]\"\n :class=\"{'text-right': message.role === 'user'}\">\n\n <div class=\"text-sm text-gray-900 p-3 rounded-md inline-block\" :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\"></chat-message-script>\n </div>\n </div>\n </div>\n </div>\n</div>\n";
3911
+ module.exports = "<div class=\"relative flex items-start space-x-3\" :class=\"{'justify-end': message.role === 'user'}\">\n <div\n class=\"min-w-0 max-w-[calc(100vw-4rem)]\"\n :class=\"{'text-right': message.role === 'user'}\">\n\n <div class=\"text-sm text-gray-900 p-3 rounded-md inline-block\" :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\"></chat-message-script>\n </div>\n </div>\n </div>\n </div>\n</div>\n";
3896
3912
 
3897
3913
  /***/ }),
3898
3914
 
@@ -3903,7 +3919,7 @@ module.exports = "<div class=\"relative flex items-start space-x-3\" :class=\"{'
3903
3919
  /***/ ((module) => {
3904
3920
 
3905
3921
  "use strict";
3906
- module.exports = "<div class=\"flex\" style=\"height: calc(100vh - 55px)\">\n <!-- Sidebar: Chat Threads -->\n <aside class=\"w-64 bg-gray-100 border-r overflow-y-auto h-full\">\n <div class=\"p-4 font-bold text-lg border-b\">Chat Threads</div>\n <div class=\"p-4\">\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 vif=\"status === 'loaded'\">\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\"\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\">\n <input\n v-model=\"newMessage\"\n placeholder=\"Ask something...\"\n class=\"flex-1 border rounded px-4 py-2\"\n />\n <button class=\"bg-blue-600 text-white px-4 py-2 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";
3922
+ module.exports = "<div class=\"flex\" style=\"height: calc(100vh - 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\" width=\"24px\" fill=\"#5f6368\"><path d=\"M360-120v-720h80v720h-80Zm160-160v-400l200 200-200 200Z\"/></svg>\n </div>\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 md:w-64 fixed md: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\" width=\"24px\" 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\">\n <input\n v-model=\"newMessage\"\n placeholder=\"Ask something...\"\n class=\"flex-1 border rounded px-4 py-2\"\n />\n <button class=\"bg-blue-600 text-white px-4 py-2 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";
3907
3923
 
3908
3924
  /***/ }),
3909
3925
 
@@ -4431,7 +4447,7 @@ module.exports = "<div class=\"models\">\n <div>\n <div class=\"flex grow fl
4431
4447
  /***/ ((module) => {
4432
4448
 
4433
4449
  "use strict";
4434
- module.exports = ".navbar {\n width: 100%;\n background-color: #eee;\n}\n\n.active {\n text-decoration: underline;\n}\n\n.spacing {\n margin-right: 10px;\n}\n\n.navbar .nav-left {\n float: left;\n line-height: 54px;\n font-size: 20px;\n padding-left: 20px;\n}\n\n.navbar .nav-left a {\n color: #232323;\n}\n\n.navbar {\n border-bottom: 1px solid #ddd;\n height: 55px;\n}\n\n.navbar .nav-left img {\n height: 32px;\n vertical-align: middle;\n margin-right: 0.5em;\n margin-top: 8px;\n}\n\n.navbar .nav-right {\n float: right;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n font-size: 16px;\n line-height: 54px;\n padding-right: 20px;\n}\n\n.navbar .nav-right .nav-item {\n flex-grow: 1;\n padding: 0px 12px;\n position: relative;\n z-index: 21000;\n}\n\n.navbar .nav-right .nav-item:hover {\n flex-grow: 1;\n padding: 0px 12px;\n border-bottom: 1px solid #E1B9A0;\n}\n\n.navbar .nav-right .nav-item.active {\n border-bottom: 1px solid #E1B9A0;\n}\n\n.navbar .nav-action {\n cursor: pointer;\n color: #E1B9A0;\n}\n\n.navbar .nav-action svg {\n height: 1em;\n vertical-align: middle;\n}\n\n.navbar .nav-right .nav-item .flyout {\n position: absolute;\n top: 55px;\n right: 0px;\n visibility: hidden;\n opacity: 0;\n transition: opacity .25s,visibility .25s,transform .25s;\n width: auto;\n box-shadow: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08);\n background-color: #393944;\n padding-left: 0.5em;\n padding-right: 0.5em;\n z-index: 1000;\n min-width: 192px;\n font-size: 0.9em;\n}\n\n.navbar .nav-right .nav-item:hover .flyout a {\n color: #E1B9A0;\n margin-top: 0.25em;\n margin-bottom: 0.25em;\n}\n\n.navbar .nav-right .nav-item:hover .flyout a:hover {\n color: #E1B9A0;\n}\n\n.navbar .nav-right .nav-item:hover .flyout .nav-action {\n color: #E1B9A0;\n margin-top: 0.25em;\n margin-bottom: 0.25em;\n}\n\n.navbar .nav-right .nav-item:hover .flyout .nav-action:hover {\n color: #E1B9A0;\n}\n\n.navbar .nav-right .nav-item:hover .flyout {\n visibility: visible;\n opacity: 1;\n}\n\n#bar-1 {\n\ttransform: translateY(-4px);\n}\n#bar-3 {\n\ttransform: translateY(4px);\n}\n.menu {\n display: none;\n}\n.menu {\n\twidth: 35px;\n\theight: 30px;\n\tmargin: 18px 2px 0px 0px;\n\tcursor: pointer;\n float: right;\n}\n.bar {\n\theight: 5px;\n\twidth: 100%;\n\tbackground-color: #fff;\n\tdisplay: block;\n\tborder-radius: 5px;\n\ttransition: 0.4s ease;\n}\n.change-icon #bar-1 {\n transform: translateY(4px) rotateZ(-405deg);\n}\n.change-icon #bar-2 {\n opacity: 0;\n}\n.change-icon #bar-3 {\n transform: translateY(-6px) rotateZ(405deg);\n}\n\n@media (max-width: 767px) {\n .menu {\n display: block;\n }\n\n .change-icon ~ div.nav-right {\n left: 0;\n }\n\n .navbar .nav-right {\n\t\tposition: fixed;\n\t\ttop: 55px;\n\t\tleft: -130%;\n\t\tbackground: #111;\n\t\theight: 100vh;\n\t\twidth: 100%;\n\t\ttext-align: center;\n\t\tdisplay: block;\n\t\ttransition: all 0.3s ease;\n z-index: 10000;\n\t}\n}\n";
4450
+ module.exports = ".active {\n text-decoration: underline;\n}\n\n.navbar .nav-left {\n float: left;\n line-height: 54px;\n font-size: 20px;\n padding-left: 20px;\n}\n\n.navbar .nav-left a {\n color: #232323;\n}\n\n.navbar .nav-right {\n float: right;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n font-size: 16px;\n line-height: 54px;\n padding-right: 20px;\n}\n\n.navbar .nav-right .nav-item {\n flex-grow: 1;\n padding: 0px 12px;\n position: relative;\n z-index: 21000;\n}\n\n.navbar .nav-right .nav-item:hover {\n flex-grow: 1;\n padding: 0px 12px;\n border-bottom: 1px solid #E1B9A0;\n}\n\n.navbar .nav-right .nav-item.active {\n border-bottom: 1px solid #E1B9A0;\n}\n\n.navbar .nav-action {\n cursor: pointer;\n color: #E1B9A0;\n}\n\n.navbar .nav-action svg {\n height: 1em;\n vertical-align: middle;\n}\n\n.navbar .nav-right .nav-item .flyout {\n position: absolute;\n top: 55px;\n right: 0px;\n visibility: hidden;\n opacity: 0;\n transition: opacity .25s,visibility .25s,transform .25s;\n width: auto;\n box-shadow: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08);\n background-color: #393944;\n padding-left: 0.5em;\n padding-right: 0.5em;\n z-index: 1000;\n min-width: 192px;\n font-size: 0.9em;\n}\n\n.navbar .nav-right .nav-item:hover .flyout a {\n color: #E1B9A0;\n margin-top: 0.25em;\n margin-bottom: 0.25em;\n}\n\n.navbar .nav-right .nav-item:hover .flyout a:hover {\n color: #E1B9A0;\n}\n\n.navbar .nav-right .nav-item:hover .flyout .nav-action {\n color: #E1B9A0;\n margin-top: 0.25em;\n margin-bottom: 0.25em;\n}\n\n.navbar .nav-right .nav-item:hover .flyout .nav-action:hover {\n color: #E1B9A0;\n}\n\n.navbar .nav-right .nav-item:hover .flyout {\n visibility: visible;\n opacity: 1;\n}\n\n#bar-1 {\n\ttransform: translateY(-4px);\n}\n#bar-3 {\n\ttransform: translateY(4px);\n}\n.menu {\n display: none;\n}\n.menu {\n\twidth: 35px;\n\theight: 30px;\n\tmargin: 18px 2px 0px 0px;\n\tcursor: pointer;\n float: right;\n}\n.bar {\n\theight: 5px;\n\twidth: 100%;\n\tbackground-color: #fff;\n\tdisplay: block;\n\tborder-radius: 5px;\n\ttransition: 0.4s ease;\n}\n.change-icon #bar-1 {\n transform: translateY(4px) rotateZ(-405deg);\n}\n.change-icon #bar-2 {\n opacity: 0;\n}\n.change-icon #bar-3 {\n transform: translateY(-6px) rotateZ(405deg);\n}\n\n@media (max-width: 767px) {\n .menu {\n display: block;\n }\n\n .change-icon ~ div.nav-right {\n left: 0;\n }\n\n .navbar .nav-right {\n\t\tposition: fixed;\n\t\ttop: 55px;\n\t\tleft: -130%;\n\t\tbackground: #111;\n\t\theight: 100vh;\n\t\twidth: 100%;\n\t\ttext-align: center;\n\t\tdisplay: block;\n\t\ttransition: all 0.3s ease;\n z-index: 10000;\n\t}\n}\n";
4435
4451
 
4436
4452
  /***/ }),
4437
4453
 
@@ -4442,7 +4458,7 @@ module.exports = ".navbar {\n width: 100%;\n background-color: #eee;\n}\n\n.ac
4442
4458
  /***/ ((module) => {
4443
4459
 
4444
4460
  "use strict";
4445
- module.exports = "<div class=\"navbar\">\n <div class=\"nav-left flex items-center gap-4 h-full\">\n <router-link :to=\"{ name: defaultRoute }\">\n <img src=\"images/logo.svg\" alt=\"Mongoose Studio Logo\" />\n </router-link>\n <div v-if=\"!!state.nodeEnv\" class=\"inline-flex items-center rounded-md px-2 py-1 text-sm font-medium text-gray-900\" :class=\"warnEnv ? 'bg-red-300' : 'bg-yellow-300'\">\n {{state.nodeEnv}}\n </div>\n </div>\n <div class=\"nav-right h-full\">\n <div class=\"sm:ml-6 sm:flex sm:space-x-8 h-full\">\n <a v-if=\"hasAccess(roles, 'root')\"\n href=\"#/\"\n class=\"inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium\"\n :class=\"documentView ? 'text-gray-900 border-ultramarine-500' : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700'\">Documents</a>\n <a v-if=\"hasAccess(roles, 'dashboards')\"\n href=\"#/dashboards\"\n class=\"inline-flex items-center border-b-2 px-1 pt-1 text-sm font-medium\"\n :class=\"dashboardView ? 'text-gray-900 border-ultramarine-500' : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700'\">Dashboards</a>\n <a v-if=\"hasAccess(roles, 'chat')\"\n href=\"#/chat\"\n class=\"inline-flex items-center border-b-2 px-1 pt-1 text-sm font-medium\"\n :class=\"chatView ? 'text-gray-900 border-ultramarine-500' : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700'\">Chat</a>\n\n <div class=\"h-full flex items-center\" v-if=\"!user && hasAPIKey\">\n <button\n type=\"button\"\n @click=\"loginWithGithub\"\n class=\"rounded bg-ultramarine-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600\">\n Login\n </button>\n </div>\n <div v-if=\"user && hasAPIKey\" class=\"h-full flex items-center relative\" v-clickOutside=\"hideFlyout\">\n <div>\n <button type=\"button\" @click=\"showFlyout = !showFlyout\" class=\"relative flex rounded-full bg-gray-800 text-sm focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800\" id=\"user-menu-button\" aria-expanded=\"false\" aria-haspopup=\"true\">\n <span class=\"absolute -inset-1.5\"></span>\n <span class=\"sr-only\">Open user menu</span>\n <img class=\"size-8 rounded-full\" :src=\"user.picture\" alt=\"\">\n </button>\n </div>\n\n <div v-if=\"showFlyout\" class=\"absolute right-0 z-10 top-[90%] w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black/5 focus:outline-none\" role=\"menu\" aria-orientation=\"vertical\" aria-labelledby=\"user-menu-button\" tabindex=\"-1\">\n <router-link to=\"/team\" v-if=\"hasAccess(roles, 'team')\" @click=\"showFlyout = false\" class=\"cursor-pointer block px-4 py-2 text-sm text-gray-700 hover:bg-ultramarine-200\" role=\"menuitem\" tabindex=\"-1\" id=\"user-menu-item-2\">Team</router-link>\n <span @click=\"logout\" class=\"cursor-pointer block px-4 py-2 text-sm text-gray-700 hover:bg-ultramarine-200\" role=\"menuitem\" tabindex=\"-1\" id=\"user-menu-item-2\">Sign out</span>\n </div>\n </div>\n\n </div>\n </div>\n <div style=\"clear: both\"></div>\n</div>\n";
4461
+ module.exports = "<div class=\"navbar w-full bg-gray-50 flex justify-between border-b border-gray-200 !h-[55px]\">\n <div class=\"flex items-center gap-4 h-full pl-4\">\n <router-link :to=\"{ name: defaultRoute }\">\n <img src=\"images/logo.svg\" class=\"h-[32px] mr-1\" alt=\"Mongoose Studio Logo\" />\n </router-link>\n <div v-if=\"!!state.nodeEnv\" class=\"inline-flex items-center rounded-md px-2 py-1 text-sm font-medium text-gray-900\" :class=\"warnEnv ? 'bg-red-300' : 'bg-yellow-300'\">\n {{state.nodeEnv}}\n </div>\n </div>\n <div class=\"h-full pr-4 hidden md:block\">\n <div class=\"sm:ml-6 sm:flex sm:space-x-8 h-full\">\n <a v-if=\"hasAccess(roles, 'root')\"\n href=\"#/\"\n class=\"inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium\"\n :class=\"documentView ? 'text-gray-900 border-ultramarine-500' : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700'\">Documents</a>\n <a v-if=\"hasAccess(roles, 'dashboards')\"\n href=\"#/dashboards\"\n class=\"inline-flex items-center border-b-2 px-1 pt-1 text-sm font-medium\"\n :class=\"dashboardView ? 'text-gray-900 border-ultramarine-500' : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700'\">Dashboards</a>\n <a v-if=\"hasAccess(roles, 'chat')\"\n href=\"#/chat\"\n class=\"inline-flex items-center border-b-2 px-1 pt-1 text-sm font-medium\"\n :class=\"chatView ? 'text-gray-900 border-ultramarine-500' : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700'\">Chat</a>\n\n <div class=\"h-full flex items-center\" v-if=\"!user && hasAPIKey\">\n <button\n type=\"button\"\n @click=\"loginWithGithub\"\n class=\"rounded bg-ultramarine-600 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600\">\n Login\n </button>\n </div>\n <div v-if=\"user && hasAPIKey\" class=\"h-full flex items-center relative\" v-clickOutside=\"hideFlyout\">\n <div>\n <button type=\"button\" @click=\"showFlyout = !showFlyout\" class=\"relative flex rounded-full bg-gray-800 text-sm focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800\" id=\"user-menu-button\" aria-expanded=\"false\" aria-haspopup=\"true\">\n <span class=\"absolute -inset-1.5\"></span>\n <span class=\"sr-only\">Open user menu</span>\n <img class=\"size-8 rounded-full\" :src=\"user.picture\" alt=\"\">\n </button>\n </div>\n\n <div v-if=\"showFlyout\" class=\"absolute right-0 z-10 top-[90%] w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black/5 focus:outline-none\" role=\"menu\" aria-orientation=\"vertical\" aria-labelledby=\"user-menu-button\" tabindex=\"-1\">\n <router-link to=\"/team\" v-if=\"hasAccess(roles, 'team')\" @click=\"showFlyout = false\" class=\"cursor-pointer block px-4 py-2 text-sm text-gray-700 hover:bg-ultramarine-200\" role=\"menuitem\" tabindex=\"-1\" id=\"user-menu-item-2\">Team</router-link>\n <span @click=\"logout\" class=\"cursor-pointer block px-4 py-2 text-sm text-gray-700 hover:bg-ultramarine-200\" role=\"menuitem\" tabindex=\"-1\" id=\"user-menu-item-2\">Sign out</span>\n </div>\n </div>\n\n </div>\n </div>\n <div class=\"md:hidden flex items-center\">\n <!-- Mobile menu toggle, controls the 'mobileMenuOpen' state. -->\n <button type=\"button\" id=\"open-mobile-menu\" class=\"-ml-2 rounded-md p-2 pr-4 text-gray-400\">\n <span class=\"sr-only\">Open menu</span>\n <svg class=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5\" />\n </svg>\n </button>\n </div>\n\n <!-- Mobile menu mask -->\n <div id=\"mobile-menu-mask\" class=\"fixed inset-0 bg-black bg-opacity-40 z-40 hidden\"></div>\n <!-- Mobile menu drawer -->\n <div id=\"mobile-menu\" class=\"fixed inset-0 bg-white shadow-lg z-50 transform translate-x-full transition-transform duration-200 ease-in-out flex flex-col\">\n <div class=\"flex items-center justify-between px-4 !h-[55px] border-b border-gray-200\">\n <router-link :to=\"{ name: defaultRoute }\">\n <img src=\"images/logo.svg\" class=\"h-[32px]\" alt=\"Mongoose Studio Logo\" />\n </router-link>\n <button type=\"button\" id=\"close-mobile-menu\" class=\"text-gray-400 p-2 rounded-md\">\n <span class=\"sr-only\">Close menu</span>\n <svg class=\"h-6 w-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n <nav class=\"flex-1 px-4 py-4 space-y-2\">\n <a v-if=\"hasAccess(roles, 'root')\"\n href=\"#/\"\n class=\"block px-3 py-2 rounded-md text-base font-medium\"\n :class=\"documentView ? 'text-ultramarine-700 bg-ultramarine-100' : 'text-gray-700 hover:bg-gray-100'\">Documents</a>\n <a v-if=\"hasAccess(roles, 'dashboards')\"\n href=\"#/dashboards\"\n class=\"block px-3 py-2 rounded-md text-base font-medium\"\n :class=\"dashboardView ? 'text-ultramarine-700 bg-ultramarine-100' : 'text-gray-700 hover:bg-gray-100'\">Dashboards</a>\n <a v-if=\"hasAccess(roles, 'chat')\"\n href=\"#/chat\"\n class=\"block px-3 py-2 rounded-md text-base font-medium\"\n :class=\"chatView ? 'text-ultramarine-700 bg-ultramarine-100' : 'text-gray-700 hover:bg-gray-100'\">Chat</a>\n <div v-if=\"!user && hasAPIKey\" class=\"mt-4\">\n <button\n type=\"button\"\n @click=\"loginWithGithub\"\n class=\"w-full rounded bg-ultramarine-600 px-3 py-2 text-base font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600\">\n Login\n </button>\n </div>\n <div v-if=\"user && hasAPIKey\" class=\"mt-4\">\n <div class=\"flex items-center gap-3 px-3 py-2 bg-gray-50 rounded-md\">\n <img class=\"size-8 rounded-full\" :src=\"user.picture\" alt=\"\">\n <span class=\"text-gray-900 font-medium\">{{ user.name }}</span>\n </div>\n <div class=\"mt-2 space-y-1\">\n <router-link to=\"/team\" v-if=\"hasAccess(roles, 'team')\" class=\"block px-3 py-2 rounded-md text-base text-gray-700 hover:bg-ultramarine-100\">Team</router-link>\n <span @click=\"logout\" class=\"block px-3 py-2 rounded-md text-base text-gray-700 hover:bg-ultramarine-100 cursor-pointer\">Sign out</span>\n </div>\n </div>\n </nav>\n </div>\n</div>\n";
4446
4462
 
4447
4463
  /***/ }),
4448
4464
 
@@ -594,6 +594,10 @@ video {
594
594
  pointer-events: none;
595
595
  }
596
596
 
597
+ .fixed {
598
+ position: fixed;
599
+ }
600
+
597
601
  .absolute {
598
602
  position: absolute;
599
603
  }
@@ -610,6 +614,15 @@ video {
610
614
  inset: -0.375rem;
611
615
  }
612
616
 
617
+ .inset-0 {
618
+ inset: 0px;
619
+ }
620
+
621
+ .inset-x-0 {
622
+ left: 0px;
623
+ right: 0px;
624
+ }
625
+
613
626
  .right-0 {
614
627
  right: 0px;
615
628
  }
@@ -626,6 +639,50 @@ video {
626
639
  top: 90%;
627
640
  }
628
641
 
642
+ .bottom-0 {
643
+ bottom: 0px;
644
+ }
645
+
646
+ .top-1\/2 {
647
+ top: 50%;
648
+ }
649
+
650
+ .top-full {
651
+ top: 100%;
652
+ }
653
+
654
+ .top-0 {
655
+ top: 0px;
656
+ }
657
+
658
+ .top-\[100px\] {
659
+ top: 100px;
660
+ }
661
+
662
+ .top-\[80px\] {
663
+ top: 80px;
664
+ }
665
+
666
+ .top-\[60px\] {
667
+ top: 60px;
668
+ }
669
+
670
+ .top-\[65px\] {
671
+ top: 65px;
672
+ }
673
+
674
+ .top-\[70px\] {
675
+ top: 70px;
676
+ }
677
+
678
+ .left-0 {
679
+ left: 0px;
680
+ }
681
+
682
+ .top-\[55px\] {
683
+ top: 55px;
684
+ }
685
+
629
686
  .isolate {
630
687
  isolation: isolate;
631
688
  }
@@ -634,6 +691,22 @@ video {
634
691
  z-index: 10;
635
692
  }
636
693
 
694
+ .z-40 {
695
+ z-index: 40;
696
+ }
697
+
698
+ .z-50 {
699
+ z-index: 50;
700
+ }
701
+
702
+ .z-20 {
703
+ z-index: 20;
704
+ }
705
+
706
+ .z-30 {
707
+ z-index: 30;
708
+ }
709
+
637
710
  .col-start-1 {
638
711
  grid-column-start: 1;
639
712
  }
@@ -646,6 +719,10 @@ video {
646
719
  margin: 0px;
647
720
  }
648
721
 
722
+ .-m-2 {
723
+ margin: -0.5rem;
724
+ }
725
+
649
726
  .-mx-4 {
650
727
  margin-left: -1rem;
651
728
  margin-right: -1rem;
@@ -751,6 +828,14 @@ video {
751
828
  margin-top: 2rem;
752
829
  }
753
830
 
831
+ .-ml-2 {
832
+ margin-left: -0.5rem;
833
+ }
834
+
835
+ .-ml-4 {
836
+ margin-left: -1rem;
837
+ }
838
+
754
839
  .block {
755
840
  display: block;
756
841
  }
@@ -838,6 +923,10 @@ video {
838
923
  height: 300px;
839
924
  }
840
925
 
926
+ .h-\[32px\] {
927
+ height: 32px;
928
+ }
929
+
841
930
  .h-\[42px\] {
842
931
  height: 42px;
843
932
  }
@@ -854,6 +943,34 @@ video {
854
943
  height: 1px;
855
944
  }
856
945
 
946
+ .\!h-\[55px\] {
947
+ height: 55px !important;
948
+ }
949
+
950
+ .h-6 {
951
+ height: 1.5rem;
952
+ }
953
+
954
+ .h-0 {
955
+ height: 0px;
956
+ }
957
+
958
+ .h-0\.5 {
959
+ height: 0.125rem;
960
+ }
961
+
962
+ .h-\[170px\] {
963
+ height: 170px;
964
+ }
965
+
966
+ .h-\[190px\] {
967
+ height: 190px;
968
+ }
969
+
970
+ .h-\[55px\] {
971
+ height: 55px;
972
+ }
973
+
857
974
  .max-h-\[30vh\] {
858
975
  max-height: 30vh;
859
976
  }
@@ -902,6 +1019,34 @@ video {
902
1019
  width: 100%;
903
1020
  }
904
1021
 
1022
+ .w-6 {
1023
+ width: 1.5rem;
1024
+ }
1025
+
1026
+ .w-\[170px\] {
1027
+ width: 170px;
1028
+ }
1029
+
1030
+ .w-\[200px\] {
1031
+ width: 200px;
1032
+ }
1033
+
1034
+ .w-0 {
1035
+ width: 0px;
1036
+ }
1037
+
1038
+ .w-\[255px\] {
1039
+ width: 255px;
1040
+ }
1041
+
1042
+ .\!w-0 {
1043
+ width: 0px !important;
1044
+ }
1045
+
1046
+ .\!w-64 {
1047
+ width: 16rem !important;
1048
+ }
1049
+
905
1050
  .min-w-0 {
906
1051
  min-width: 0px;
907
1052
  }
@@ -914,18 +1059,34 @@ video {
914
1059
  max-width: 64rem;
915
1060
  }
916
1061
 
917
- .max-w-\[70vw\] {
918
- max-width: 70vw;
919
- }
920
-
921
1062
  .max-w-\[calc\(100\%-6\.5rem\)\] {
922
1063
  max-width: calc(100% - 6.5rem);
923
1064
  }
924
1065
 
1066
+ .max-w-\[calc\(100vw-25rem\)\] {
1067
+ max-width: calc(100vw - 25rem);
1068
+ }
1069
+
925
1070
  .max-w-xs {
926
1071
  max-width: 20rem;
927
1072
  }
928
1073
 
1074
+ .max-w-7xl {
1075
+ max-width: 80rem;
1076
+ }
1077
+
1078
+ .max-w-\[100vw\] {
1079
+ max-width: 100vw;
1080
+ }
1081
+
1082
+ .max-w-\[calc\(100vw-6rem\)\] {
1083
+ max-width: calc(100vw - 6rem);
1084
+ }
1085
+
1086
+ .max-w-\[calc\(100vw-4rem\)\] {
1087
+ max-width: calc(100vw - 4rem);
1088
+ }
1089
+
929
1090
  .flex-1 {
930
1091
  flex: 1 1 0%;
931
1092
  }
@@ -962,6 +1123,21 @@ video {
962
1123
  transform-origin: top right;
963
1124
  }
964
1125
 
1126
+ .translate-x-0 {
1127
+ --tw-translate-x: 0px;
1128
+ 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));
1129
+ }
1130
+
1131
+ .-translate-x-full {
1132
+ --tw-translate-x: -100%;
1133
+ 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));
1134
+ }
1135
+
1136
+ .translate-x-full {
1137
+ --tw-translate-x: 100%;
1138
+ 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));
1139
+ }
1140
+
965
1141
  .transform {
966
1142
  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));
967
1143
  }
@@ -992,6 +1168,10 @@ video {
992
1168
  grid-template-columns: repeat(2, minmax(0, 1fr));
993
1169
  }
994
1170
 
1171
+ .grid-cols-5 {
1172
+ grid-template-columns: repeat(5, minmax(0, 1fr));
1173
+ }
1174
+
995
1175
  .flex-row {
996
1176
  flex-direction: row;
997
1177
  }
@@ -1044,6 +1224,10 @@ video {
1044
1224
  gap: 2rem;
1045
1225
  }
1046
1226
 
1227
+ .gap-16 {
1228
+ gap: 4rem;
1229
+ }
1230
+
1047
1231
  .gap-x-4 {
1048
1232
  -moz-column-gap: 1rem;
1049
1233
  column-gap: 1rem;
@@ -1086,6 +1270,18 @@ video {
1086
1270
  margin-bottom: calc(1rem * var(--tw-space-y-reverse));
1087
1271
  }
1088
1272
 
1273
+ .space-x-0 > :not([hidden]) ~ :not([hidden]) {
1274
+ --tw-space-x-reverse: 0;
1275
+ margin-right: calc(0px * var(--tw-space-x-reverse));
1276
+ margin-left: calc(0px * calc(1 - var(--tw-space-x-reverse)));
1277
+ }
1278
+
1279
+ .space-y-2 > :not([hidden]) ~ :not([hidden]) {
1280
+ --tw-space-y-reverse: 0;
1281
+ margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
1282
+ margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
1283
+ }
1284
+
1089
1285
  .divide-y > :not([hidden]) ~ :not([hidden]) {
1090
1286
  --tw-divide-y-reverse: 0;
1091
1287
  border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
@@ -1135,6 +1331,10 @@ video {
1135
1331
  overflow-y: auto;
1136
1332
  }
1137
1333
 
1334
+ .overflow-x-hidden {
1335
+ overflow-x: hidden;
1336
+ }
1337
+
1138
1338
  .truncate {
1139
1339
  overflow: hidden;
1140
1340
  text-overflow: ellipsis;
@@ -1235,11 +1435,6 @@ video {
1235
1435
  border-color: rgb(63 83 255 / var(--tw-border-opacity));
1236
1436
  }
1237
1437
 
1238
- .border-red-500 {
1239
- --tw-border-opacity: 1;
1240
- border-color: rgb(239 68 68 / var(--tw-border-opacity));
1241
- }
1242
-
1243
1438
  .bg-blue-200 {
1244
1439
  --tw-bg-opacity: 1;
1245
1440
  background-color: rgb(191 219 254 / var(--tw-bg-opacity));
@@ -1374,6 +1569,11 @@ video {
1374
1569
  background-color: rgb(229 234 255 / var(--tw-bg-opacity));
1375
1570
  }
1376
1571
 
1572
+ .bg-ultramarine-500 {
1573
+ --tw-bg-opacity: 1;
1574
+ background-color: rgb(63 83 255 / var(--tw-bg-opacity));
1575
+ }
1576
+
1377
1577
  .bg-ultramarine-600 {
1378
1578
  --tw-bg-opacity: 1;
1379
1579
  background-color: rgb(24 35 255 / var(--tw-bg-opacity));
@@ -1399,9 +1599,40 @@ video {
1399
1599
  background-color: rgb(253 224 71 / var(--tw-bg-opacity));
1400
1600
  }
1401
1601
 
1402
- .bg-ultramarine-500 {
1602
+ .bg-indigo-600 {
1403
1603
  --tw-bg-opacity: 1;
1404
- background-color: rgb(63 83 255 / var(--tw-bg-opacity));
1604
+ background-color: rgb(79 70 229 / var(--tw-bg-opacity));
1605
+ }
1606
+
1607
+ .bg-black {
1608
+ --tw-bg-opacity: 1;
1609
+ background-color: rgb(0 0 0 / var(--tw-bg-opacity));
1610
+ }
1611
+
1612
+ .bg-opacity-25 {
1613
+ --tw-bg-opacity: 0.25;
1614
+ }
1615
+
1616
+ .bg-opacity-40 {
1617
+ --tw-bg-opacity: 0.4;
1618
+ }
1619
+
1620
+ .bg-cover {
1621
+ background-size: cover;
1622
+ }
1623
+
1624
+ .bg-center {
1625
+ background-position: center;
1626
+ }
1627
+
1628
+ .object-cover {
1629
+ -o-object-fit: cover;
1630
+ object-fit: cover;
1631
+ }
1632
+
1633
+ .object-center {
1634
+ -o-object-position: center;
1635
+ object-position: center;
1405
1636
  }
1406
1637
 
1407
1638
  .p-1 {
@@ -1489,6 +1720,26 @@ video {
1489
1720
  padding-bottom: 1.5rem;
1490
1721
  }
1491
1722
 
1723
+ .px-\[10px\] {
1724
+ padding-left: 10px;
1725
+ padding-right: 10px;
1726
+ }
1727
+
1728
+ .py-10 {
1729
+ padding-top: 2.5rem;
1730
+ padding-bottom: 2.5rem;
1731
+ }
1732
+
1733
+ .py-\[10px\] {
1734
+ padding-top: 10px;
1735
+ padding-bottom: 10px;
1736
+ }
1737
+
1738
+ .px-1\.5 {
1739
+ padding-left: 0.375rem;
1740
+ padding-right: 0.375rem;
1741
+ }
1742
+
1492
1743
  .pb-2 {
1493
1744
  padding-bottom: 0.5rem;
1494
1745
  }
@@ -1537,6 +1788,14 @@ video {
1537
1788
  padding-top: 1px;
1538
1789
  }
1539
1790
 
1791
+ .pb-12 {
1792
+ padding-bottom: 3rem;
1793
+ }
1794
+
1795
+ .pt-5 {
1796
+ padding-top: 1.25rem;
1797
+ }
1798
+
1540
1799
  .text-left {
1541
1800
  text-align: left;
1542
1801
  }
@@ -1695,6 +1954,16 @@ video {
1695
1954
  color: rgb(255 255 255 / var(--tw-text-opacity));
1696
1955
  }
1697
1956
 
1957
+ .text-indigo-600 {
1958
+ --tw-text-opacity: 1;
1959
+ color: rgb(79 70 229 / var(--tw-text-opacity));
1960
+ }
1961
+
1962
+ .text-ultramarine-700 {
1963
+ --tw-text-opacity: 1;
1964
+ color: rgb(7 19 250 / var(--tw-text-opacity));
1965
+ }
1966
+
1698
1967
  .accent-sky-600 {
1699
1968
  accent-color: #0284c7;
1700
1969
  }
@@ -1703,6 +1972,14 @@ video {
1703
1972
  opacity: 0.5;
1704
1973
  }
1705
1974
 
1975
+ .opacity-0 {
1976
+ opacity: 0;
1977
+ }
1978
+
1979
+ .opacity-100 {
1980
+ opacity: 1;
1981
+ }
1982
+
1706
1983
  .shadow-lg {
1707
1984
  --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
1708
1985
  --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
@@ -1715,6 +1992,18 @@ video {
1715
1992
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
1716
1993
  }
1717
1994
 
1995
+ .shadow {
1996
+ --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
1997
+ --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
1998
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
1999
+ }
2000
+
2001
+ .shadow-xl {
2002
+ --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
2003
+ --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);
2004
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
2005
+ }
2006
+
1718
2007
  .outline-none {
1719
2008
  outline: 2px solid transparent;
1720
2009
  outline-offset: 2px;
@@ -1777,16 +2066,6 @@ video {
1777
2066
  --tw-ring-color: rgb(22 163 74 / 0.2);
1778
2067
  }
1779
2068
 
1780
- .ring-yellow-800 {
1781
- --tw-ring-opacity: 1;
1782
- --tw-ring-color: rgb(133 77 14 / var(--tw-ring-opacity));
1783
- }
1784
-
1785
- .ring-yellow-300 {
1786
- --tw-ring-opacity: 1;
1787
- --tw-ring-color: rgb(253 224 71 / var(--tw-ring-opacity));
1788
- }
1789
-
1790
2069
  .filter {
1791
2070
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
1792
2071
  }
@@ -1805,6 +2084,52 @@ video {
1805
2084
  transition-duration: 150ms;
1806
2085
  }
1807
2086
 
2087
+ .transition-opacity {
2088
+ transition-property: opacity;
2089
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
2090
+ transition-duration: 150ms;
2091
+ }
2092
+
2093
+ .transition-transform {
2094
+ transition-property: transform;
2095
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
2096
+ transition-duration: 150ms;
2097
+ }
2098
+
2099
+ .transition-all {
2100
+ transition-property: all;
2101
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
2102
+ transition-duration: 150ms;
2103
+ }
2104
+
2105
+ .duration-150 {
2106
+ transition-duration: 150ms;
2107
+ }
2108
+
2109
+ .duration-200 {
2110
+ transition-duration: 200ms;
2111
+ }
2112
+
2113
+ .duration-300 {
2114
+ transition-duration: 300ms;
2115
+ }
2116
+
2117
+ .ease-in {
2118
+ transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
2119
+ }
2120
+
2121
+ .ease-out {
2122
+ transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
2123
+ }
2124
+
2125
+ .ease-in-out {
2126
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
2127
+ }
2128
+
2129
+ .ease-linear {
2130
+ transition-timing-function: linear;
2131
+ }
2132
+
1808
2133
  .placeholder\:text-gray-400::-moz-placeholder {
1809
2134
  --tw-text-opacity: 1;
1810
2135
  color: rgb(156 163 175 / var(--tw-text-opacity));
@@ -1830,6 +2155,10 @@ video {
1830
2155
  --tw-ring-color: rgb(0 168 165 / var(--tw-ring-opacity));
1831
2156
  }
1832
2157
 
2158
+ .hover\:border-b:hover {
2159
+ border-bottom-width: 1px;
2160
+ }
2161
+
1833
2162
  .hover\:border-gray-300:hover {
1834
2163
  --tw-border-opacity: 1;
1835
2164
  border-color: rgb(209 213 219 / var(--tw-border-opacity));
@@ -1930,6 +2259,11 @@ video {
1930
2259
  background-color: rgb(63 83 255 / var(--tw-bg-opacity));
1931
2260
  }
1932
2261
 
2262
+ .hover\:bg-ultramarine-600:hover {
2263
+ --tw-bg-opacity: 1;
2264
+ background-color: rgb(24 35 255 / var(--tw-bg-opacity));
2265
+ }
2266
+
1933
2267
  .hover\:bg-valencia-400:hover {
1934
2268
  --tw-bg-opacity: 1;
1935
2269
  background-color: rgb(235 126 126 / var(--tw-bg-opacity));
@@ -1940,9 +2274,9 @@ video {
1940
2274
  background-color: rgb(220 73 73 / var(--tw-bg-opacity));
1941
2275
  }
1942
2276
 
1943
- .hover\:bg-ultramarine-600:hover {
2277
+ .hover\:bg-gray-100:hover {
1944
2278
  --tw-bg-opacity: 1;
1945
- background-color: rgb(24 35 255 / var(--tw-bg-opacity));
2279
+ background-color: rgb(243 244 246 / var(--tw-bg-opacity));
1946
2280
  }
1947
2281
 
1948
2282
  .hover\:text-gray-700:hover {
@@ -1955,6 +2289,16 @@ video {
1955
2289
  color: rgb(10 87 87 / var(--tw-text-opacity));
1956
2290
  }
1957
2291
 
2292
+ .hover\:text-black:hover {
2293
+ --tw-text-opacity: 1;
2294
+ color: rgb(0 0 0 / var(--tw-text-opacity));
2295
+ }
2296
+
2297
+ .hover\:text-gray-800:hover {
2298
+ --tw-text-opacity: 1;
2299
+ color: rgb(31 41 55 / var(--tw-text-opacity));
2300
+ }
2301
+
1958
2302
  .focus\:z-10:focus {
1959
2303
  z-index: 10;
1960
2304
  }
@@ -2075,6 +2419,10 @@ video {
2075
2419
  outline-color: #d1d5db;
2076
2420
  }
2077
2421
 
2422
+ .focus-visible\:outline-gray-500:focus-visible {
2423
+ outline-color: #6b7280;
2424
+ }
2425
+
2078
2426
  .focus-visible\:outline-green-600:focus-visible {
2079
2427
  outline-color: #16a34a;
2080
2428
  }
@@ -2107,14 +2455,6 @@ video {
2107
2455
  outline-color: #1823ff;
2108
2456
  }
2109
2457
 
2110
- .focus-visible\:outline-gray-600:focus-visible {
2111
- outline-color: #4b5563;
2112
- }
2113
-
2114
- .focus-visible\:outline-gray-500:focus-visible {
2115
- outline-color: #6b7280;
2116
- }
2117
-
2118
2458
  .disabled\:cursor-not-allowed:disabled {
2119
2459
  cursor: not-allowed;
2120
2460
  }
@@ -2157,6 +2497,10 @@ video {
2157
2497
  margin-top: 0px;
2158
2498
  }
2159
2499
 
2500
+ .sm\:mt-5 {
2501
+ margin-top: 1.25rem;
2502
+ }
2503
+
2160
2504
  .sm\:flex {
2161
2505
  display: flex;
2162
2506
  }
@@ -2174,6 +2518,15 @@ video {
2174
2518
  flex: none;
2175
2519
  }
2176
2520
 
2521
+ .sm\:translate-y-px {
2522
+ --tw-translate-y: 1px;
2523
+ 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));
2524
+ }
2525
+
2526
+ .sm\:transform {
2527
+ 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));
2528
+ }
2529
+
2177
2530
  .sm\:flex-col {
2178
2531
  flex-direction: column;
2179
2532
  }
@@ -2228,12 +2581,46 @@ video {
2228
2581
  }
2229
2582
  }
2230
2583
 
2584
+ @media (min-width: 768px) {
2585
+ .md\:relative {
2586
+ position: relative;
2587
+ }
2588
+
2589
+ .md\:block {
2590
+ display: block;
2591
+ }
2592
+
2593
+ .md\:hidden {
2594
+ display: none;
2595
+ }
2596
+
2597
+ .md\:w-64 {
2598
+ width: 16rem;
2599
+ }
2600
+ }
2601
+
2231
2602
  @media (min-width: 1024px) {
2232
2603
  .lg\:-mx-8 {
2233
2604
  margin-left: -2rem;
2234
2605
  margin-right: -2rem;
2235
2606
  }
2236
2607
 
2608
+ .lg\:block {
2609
+ display: block;
2610
+ }
2611
+
2612
+ .lg\:hidden {
2613
+ display: none;
2614
+ }
2615
+
2616
+ .lg\:flex-1 {
2617
+ flex: 1 1 0%;
2618
+ }
2619
+
2620
+ .lg\:self-stretch {
2621
+ align-self: stretch;
2622
+ }
2623
+
2237
2624
  .lg\:px-8 {
2238
2625
  padding-left: 2rem;
2239
2626
  padding-right: 2rem;
@@ -1,6 +1,6 @@
1
1
  <div class="relative flex items-start space-x-3" :class="{'justify-end': message.role === 'user'}">
2
2
  <div
3
- class="min-w-0 max-w-[calc(100%-6.5rem)]"
3
+ class="min-w-0 max-w-[calc(100vw-4rem)]"
4
4
  :class="{'text-right': message.role === 'user'}">
5
5
 
6
6
  <div class="text-sm text-gray-900 p-3 rounded-md inline-block" :class="styleForMessage">
@@ -37,9 +37,9 @@
37
37
  </div>
38
38
  </div>
39
39
 
40
- <pre class="p-3 whitespace-pre-wrap max-h-[30vh] max-w-[calc(100vw-25rem)] overflow-y-auto" v-show="activeTab === 'code'"><code v-text="script" ref="code" :class="'language-' + language"></code></pre>
40
+ <pre class="p-3 whitespace-pre-wrap max-h-[30vh] max-w-[calc(100vw-4rem)] overflow-y-auto" v-show="activeTab === 'code'"><code v-text="script" ref="code" :class="'language-' + language"></code></pre>
41
41
 
42
- <div class="p-3 whitespace-pre-wrap max-h-[30vh] overflow-y-auto bg-white border-t max-w-[calc(100vw-25rem)] relative" v-show="activeTab === 'output'">
42
+ <div class="p-3 whitespace-pre-wrap max-h-[30vh] overflow-y-auto bg-white border-t max-w-[calc(100vw-4rem)] relative" v-show="activeTab === 'output'">
43
43
  <dashboard-chart v-if="message.executionResult?.output?.$chart" :value="message.executionResult?.output" />
44
44
  <pre v-else>{{ message.executionResult?.output || 'No output' }}</pre>
45
45
  </div>
@@ -1,12 +1,11 @@
1
1
  'use strict';
2
2
 
3
3
  const api = require('../../api');
4
- const marked = require('marked').marked;
5
4
  const template = require('./chat-message-script.html');
6
5
  const vanillatoasts = require('vanillatoasts');
7
6
 
8
7
  module.exports = app => app.component('chat-message-script', {
9
- template: template,
8
+ template,
10
9
  props: ['message', 'script', 'language'],
11
10
  data: () => ({ activeTab: 'code', showDetailModal: false }),
12
11
  computed: {
@@ -1,8 +1,20 @@
1
1
  <div class="flex" style="height: calc(100vh - 55px)">
2
- <!-- Sidebar: Chat Threads -->
3
- <aside class="w-64 bg-gray-100 border-r overflow-y-auto h-full">
4
- <div class="p-4 font-bold text-lg border-b">Chat Threads</div>
5
- <div class="p-4">
2
+ <div class="fixed top-[65px] cursor-pointer bg-gray-100 rounded-r-md z-10" @click="hideSidebar = false">
3
+ <svg xmlns="http://www.w3.org/2000/svg" style="h-5 w-5" viewBox="0 -960 960 960" width="24px" fill="#5f6368"><path d="M360-120v-720h80v720h-80Zm160-160v-400l200 200-200 200Z"/></svg>
4
+ </div>
5
+ <!-- Sidebar: Chat Threads -->
6
+ <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 md:w-64 fixed md:relative" :class="hideSidebar === true ? '!w-0' : hideSidebar === false ? '!w-64' : ''">
7
+ <div class="flex items-center border-b border-gray-100 w-64 overflow-x-hidden">
8
+ <div class="p-4 font-bold text-lg">Chat Threads</div>
9
+ <button
10
+ @click="hideSidebar = true"
11
+ class="ml-auto mr-2 p-2 rounded hover:bg-gray-200 focus:outline-none"
12
+ aria-label="Close sidebar"
13
+ >
14
+ <svg xmlns="http://www.w3.org/2000/svg" style="h-5 w-5" viewBox="0 -960 960 960" width="24px" 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>
15
+ </button>
16
+ </div>
17
+ <div class="p-4 w-64">
6
18
  <async-button
7
19
  @click="createNewThread"
8
20
  class="w-full bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700"
@@ -13,12 +25,12 @@
13
25
  <div v-if="status === 'loaded' && chatThreads.length === 0" class="p-4 text-sm text-gray-700">
14
26
  No threads yet
15
27
  </div>
16
- <ul vif="status === 'loaded'">
28
+ <ul v-if="status === 'loaded'" class="w-64">
17
29
  <li
18
30
  v-for="thread in chatThreads"
19
31
  :key="thread._id"
20
32
  @click="selectThread(thread._id)"
21
- class="p-4 hover:bg-gray-200 cursor-pointer"
33
+ class="p-4 hover:bg-gray-200 cursor-pointer w-64"
22
34
  :class="{ 'bg-gray-300': thread._id === chatThreadId }"
23
35
  >
24
36
  {{ thread.title || 'Untitled Thread' }}
@@ -12,7 +12,8 @@ module.exports = app => app.component('chat', {
12
12
  newMessage: '',
13
13
  chatThreadId: null,
14
14
  chatThreads: [],
15
- chatMessages: []
15
+ chatMessages: [],
16
+ hideSidebar: null
16
17
  }),
17
18
  methods: {
18
19
  async sendMessage() {
@@ -1,16 +1,7 @@
1
- .navbar {
2
- width: 100%;
3
- background-color: #eee;
4
- }
5
-
6
1
  .active {
7
2
  text-decoration: underline;
8
3
  }
9
4
 
10
- .spacing {
11
- margin-right: 10px;
12
- }
13
-
14
5
  .navbar .nav-left {
15
6
  float: left;
16
7
  line-height: 54px;
@@ -22,18 +13,6 @@
22
13
  color: #232323;
23
14
  }
24
15
 
25
- .navbar {
26
- border-bottom: 1px solid #ddd;
27
- height: 55px;
28
- }
29
-
30
- .navbar .nav-left img {
31
- height: 32px;
32
- vertical-align: middle;
33
- margin-right: 0.5em;
34
- margin-top: 8px;
35
- }
36
-
37
16
  .navbar .nav-right {
38
17
  float: right;
39
18
  display: flex;
@@ -1,13 +1,13 @@
1
- <div class="navbar">
2
- <div class="nav-left flex items-center gap-4 h-full">
1
+ <div class="navbar w-full bg-gray-50 flex justify-between border-b border-gray-200 !h-[55px]">
2
+ <div class="flex items-center gap-4 h-full pl-4">
3
3
  <router-link :to="{ name: defaultRoute }">
4
- <img src="images/logo.svg" alt="Mongoose Studio Logo" />
4
+ <img src="images/logo.svg" class="h-[32px] mr-1" alt="Mongoose Studio Logo" />
5
5
  </router-link>
6
6
  <div v-if="!!state.nodeEnv" class="inline-flex items-center rounded-md px-2 py-1 text-sm font-medium text-gray-900" :class="warnEnv ? 'bg-red-300' : 'bg-yellow-300'">
7
7
  {{state.nodeEnv}}
8
8
  </div>
9
9
  </div>
10
- <div class="nav-right h-full">
10
+ <div class="h-full pr-4 hidden md:block">
11
11
  <div class="sm:ml-6 sm:flex sm:space-x-8 h-full">
12
12
  <a v-if="hasAccess(roles, 'root')"
13
13
  href="#/"
@@ -47,5 +47,62 @@
47
47
 
48
48
  </div>
49
49
  </div>
50
- <div style="clear: both"></div>
50
+ <div class="md:hidden flex items-center">
51
+ <!-- Mobile menu toggle, controls the 'mobileMenuOpen' state. -->
52
+ <button type="button" id="open-mobile-menu" class="-ml-2 rounded-md p-2 pr-4 text-gray-400">
53
+ <span class="sr-only">Open menu</span>
54
+ <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
55
+ <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
56
+ </svg>
57
+ </button>
58
+ </div>
59
+
60
+ <!-- Mobile menu mask -->
61
+ <div id="mobile-menu-mask" class="fixed inset-0 bg-black bg-opacity-40 z-40 hidden"></div>
62
+ <!-- Mobile menu drawer -->
63
+ <div id="mobile-menu" class="fixed inset-0 bg-white shadow-lg z-50 transform translate-x-full transition-transform duration-200 ease-in-out flex flex-col">
64
+ <div class="flex items-center justify-between px-4 !h-[55px] border-b border-gray-200">
65
+ <router-link :to="{ name: defaultRoute }">
66
+ <img src="images/logo.svg" class="h-[32px]" alt="Mongoose Studio Logo" />
67
+ </router-link>
68
+ <button type="button" id="close-mobile-menu" class="text-gray-400 p-2 rounded-md">
69
+ <span class="sr-only">Close menu</span>
70
+ <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
71
+ <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
72
+ </svg>
73
+ </button>
74
+ </div>
75
+ <nav class="flex-1 px-4 py-4 space-y-2">
76
+ <a v-if="hasAccess(roles, 'root')"
77
+ href="#/"
78
+ class="block px-3 py-2 rounded-md text-base font-medium"
79
+ :class="documentView ? 'text-ultramarine-700 bg-ultramarine-100' : 'text-gray-700 hover:bg-gray-100'">Documents</a>
80
+ <a v-if="hasAccess(roles, 'dashboards')"
81
+ href="#/dashboards"
82
+ class="block px-3 py-2 rounded-md text-base font-medium"
83
+ :class="dashboardView ? 'text-ultramarine-700 bg-ultramarine-100' : 'text-gray-700 hover:bg-gray-100'">Dashboards</a>
84
+ <a v-if="hasAccess(roles, 'chat')"
85
+ href="#/chat"
86
+ class="block px-3 py-2 rounded-md text-base font-medium"
87
+ :class="chatView ? 'text-ultramarine-700 bg-ultramarine-100' : 'text-gray-700 hover:bg-gray-100'">Chat</a>
88
+ <div v-if="!user && hasAPIKey" class="mt-4">
89
+ <button
90
+ type="button"
91
+ @click="loginWithGithub"
92
+ class="w-full rounded bg-ultramarine-600 px-3 py-2 text-base 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">
93
+ Login
94
+ </button>
95
+ </div>
96
+ <div v-if="user && hasAPIKey" class="mt-4">
97
+ <div class="flex items-center gap-3 px-3 py-2 bg-gray-50 rounded-md">
98
+ <img class="size-8 rounded-full" :src="user.picture" alt="">
99
+ <span class="text-gray-900 font-medium">{{ user.name }}</span>
100
+ </div>
101
+ <div class="mt-2 space-y-1">
102
+ <router-link to="/team" v-if="hasAccess(roles, 'team')" class="block px-3 py-2 rounded-md text-base text-gray-700 hover:bg-ultramarine-100">Team</router-link>
103
+ <span @click="logout" class="block px-3 py-2 rounded-md text-base text-gray-700 hover:bg-ultramarine-100 cursor-pointer">Sign out</span>
104
+ </div>
105
+ </div>
106
+ </nav>
107
+ </div>
51
108
  </div>
@@ -22,6 +22,22 @@ module.exports = app => app.component('navbar', {
22
22
  this.$router.push({ name: firstAllowedRoute.name });
23
23
  }
24
24
  }
25
+
26
+ const mobileMenuMask = document.querySelector('#mobile-menu-mask');
27
+ const mobileMenu = document.querySelector('#mobile-menu');
28
+
29
+ document.querySelector('#open-mobile-menu').addEventListener('click', (event) => {
30
+ event.stopPropagation();
31
+ mobileMenuMask.style.display = 'block';
32
+ mobileMenu.classList.remove('translate-x-full');
33
+ mobileMenu.classList.add('translate-x-0');
34
+ });
35
+
36
+ document.querySelector('body').addEventListener('click', () => {
37
+ mobileMenuMask.style.display = 'none';
38
+ mobileMenu.classList.remove('translate-x-0');
39
+ mobileMenu.classList.add('translate-x-full');
40
+ });
25
41
  },
26
42
  computed: {
27
43
  dashboardView() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mongoosejs/studio",
3
- "version": "0.0.95",
3
+ "version": "0.0.96",
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": {