@mongoosejs/studio 0.0.94 → 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.
Files changed (51) hide show
  1. package/.github/workflows/lint.yml +18 -0
  2. package/backend/actions/ChatThread/createChatMessage.js +1 -1
  3. package/backend/actions/ChatThread/createChatThread.js +2 -2
  4. package/backend/actions/Dashboard/getDashboards.js +1 -1
  5. package/backend/actions/Dashboard/updateDashboard.js +1 -1
  6. package/backend/actions/Model/createDocument.js +1 -1
  7. package/backend/actions/Model/deleteDocument.js +3 -3
  8. package/backend/actions/Model/deleteDocuments.js +2 -2
  9. package/backend/actions/Model/exportQueryResults.js +1 -1
  10. package/backend/actions/Model/getDocument.js +1 -1
  11. package/backend/actions/Model/getDocuments.js +2 -2
  12. package/backend/actions/Model/getIndexes.js +1 -1
  13. package/backend/actions/Model/index.js +1 -1
  14. package/backend/actions/Model/updateDocument.js +1 -1
  15. package/backend/actions/Model/updateDocuments.js +1 -1
  16. package/backend/authorize.js +1 -3
  17. package/backend/db/dashboardSchema.js +2 -2
  18. package/backend/helpers/removeSpecifiedPaths.js +1 -1
  19. package/backend/netlify.js +3 -3
  20. package/backend/next.js +1 -1
  21. package/eslint.config.js +46 -0
  22. package/frontend/index.js +1 -1
  23. package/frontend/public/app.js +128 -112
  24. package/frontend/public/tw.css +418 -31
  25. package/frontend/src/api.js +16 -16
  26. package/frontend/src/chat/chat-message/chat-message.html +1 -1
  27. package/frontend/src/chat/chat-message/chat-message.js +1 -1
  28. package/frontend/src/chat/chat-message-script/chat-message-script.html +2 -2
  29. package/frontend/src/chat/chat-message-script/chat-message-script.js +1 -2
  30. package/frontend/src/chat/chat.html +18 -6
  31. package/frontend/src/chat/chat.js +3 -2
  32. package/frontend/src/clone-document/clone-document.js +8 -8
  33. package/frontend/src/create-dashboard/create-dashboard.js +7 -7
  34. package/frontend/src/create-document/create-document.js +10 -10
  35. package/frontend/src/dashboard/dashboard.js +1 -1
  36. package/frontend/src/dashboard/edit-dashboard/edit-dashboard.js +3 -3
  37. package/frontend/src/dashboards/dashboards.js +1 -1
  38. package/frontend/src/document/confirm-changes/confirm-changes.js +2 -2
  39. package/frontend/src/document/confirm-delete/confirm-delete.js +2 -2
  40. package/frontend/src/document/document.js +2 -2
  41. package/frontend/src/document-details/document-details.js +3 -3
  42. package/frontend/src/document-details/document-property/document-property.js +3 -3
  43. package/frontend/src/edit-array/edit-array.js +1 -1
  44. package/frontend/src/edit-subdocument/edit-subdocument.js +1 -1
  45. package/frontend/src/list-default/list-default.js +3 -3
  46. package/frontend/src/models/models.js +11 -11
  47. package/frontend/src/navbar/navbar.css +0 -21
  48. package/frontend/src/navbar/navbar.html +62 -5
  49. package/frontend/src/navbar/navbar.js +19 -3
  50. package/frontend/src/update-document/update-document.js +25 -25
  51. package/package.json +4 -1
@@ -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>
@@ -3,7 +3,7 @@
3
3
  const api = require('../api');
4
4
  const mothership = require('../mothership');
5
5
  const template = require('./navbar.html');
6
- const { routes, hasAccess } = require('../routes');
6
+ const { routes, hasAccess } = require('../routes');
7
7
 
8
8
  const appendCSS = require('../appendCSS');
9
9
 
@@ -22,10 +22,26 @@ 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() {
28
- return routes.filter(x => x.name.startsWith('dashboard')).map(x => x.name).includes(this.$route.name)
44
+ return routes.filter(x => x.name.startsWith('dashboard')).map(x => x.name).includes(this.$route.name);
29
45
  },
30
46
  documentView() {
31
47
  return ['root', 'model', 'document'].includes(this.$route.name);
@@ -66,7 +82,7 @@ module.exports = app => app.component('navbar', {
66
82
  logout() {
67
83
  window.localStorage.setItem('_mongooseStudioAccessToken', '');
68
84
  window.location.reload();
69
- },
85
+ }
70
86
  },
71
87
  directives: {
72
88
  clickOutside: {
@@ -5,7 +5,7 @@ const api = require('../api');
5
5
  const { BSON, EJSON } = require('bson');
6
6
 
7
7
  const ObjectId = new Proxy(BSON.ObjectId, {
8
- apply (target, thisArg, argumentsList) {
8
+ apply(target, thisArg, argumentsList) {
9
9
  return new target(...argumentsList);
10
10
  }
11
11
  });
@@ -14,7 +14,7 @@ const appendCSS = require('../appendCSS');
14
14
 
15
15
  appendCSS(require('./update-document.css'));
16
16
 
17
- const template = require('./update-document.html')
17
+ const template = require('./update-document.html');
18
18
 
19
19
  module.exports = app => app.component('update-document', {
20
20
  props: ['currentModel', 'document', 'multiple'],
@@ -23,7 +23,7 @@ module.exports = app => app.component('update-document', {
23
23
  return {
24
24
  editor: null,
25
25
  errors: []
26
- }
26
+ };
27
27
  },
28
28
  methods: {
29
29
  async updateDocument() {
@@ -31,40 +31,40 @@ module.exports = app => app.component('update-document', {
31
31
  if (this.multiple) {
32
32
  const ids = this.document.map(x => x._id);
33
33
  await api.Model.updateDocuments({ model: this.currentModel, _id: ids, update: data }).catch(err => {
34
- if (err.response?.data?.message) {
35
- console.log(err.response.data);
36
- const message = err.response.data.message.split(": ").slice(1).join(": ");
37
- this.errors = message.split(',').map(error => {
38
- return error.split(': ').slice(1).join(': ').trim();
39
- })
40
- throw new Error(err.response?.data?.message);
41
- }
42
- throw err;
34
+ if (err.response?.data?.message) {
35
+ console.log(err.response.data);
36
+ const message = err.response.data.message.split(': ').slice(1).join(': ');
37
+ this.errors = message.split(',').map(error => {
38
+ return error.split(': ').slice(1).join(': ').trim();
39
+ });
40
+ throw new Error(err.response?.data?.message);
41
+ }
42
+ throw err;
43
43
  });
44
44
  } else {
45
45
  await api.Model.updateDocument({ model: this.currentModel, _id: this.document._id, update: data }).catch(err => {
46
- if (err.response?.data?.message) {
47
- console.log(err.response.data);
48
- const message = err.response.data.message.split(": ").slice(1).join(": ");
49
- this.errors = message.split(',').map(error => {
50
- return error.split(': ').slice(1).join(': ').trim();
51
- })
52
- throw new Error(err.response?.data?.message);
53
- }
54
- throw err;
46
+ if (err.response?.data?.message) {
47
+ console.log(err.response.data);
48
+ const message = err.response.data.message.split(': ').slice(1).join(': ');
49
+ this.errors = message.split(',').map(error => {
50
+ return error.split(': ').slice(1).join(': ').trim();
51
+ });
52
+ throw new Error(err.response?.data?.message);
53
+ }
54
+ throw err;
55
55
  });
56
56
  }
57
57
  this.errors.length = 0;
58
58
  this.$emit('update');
59
59
  this.$emit('close');
60
- },
60
+ }
61
61
  },
62
62
  mounted: function() {
63
- this.$refs.codeEditor.value = `{\n \n}`
63
+ this.$refs.codeEditor.value = '{\n \n}';
64
64
  this.editor = CodeMirror.fromTextArea(this.$refs.codeEditor, {
65
65
  mode: 'javascript',
66
66
  lineNumbers: true,
67
67
  smartIndent: false
68
68
  });
69
- },
70
- })
69
+ }
70
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mongoosejs/studio",
3
- "version": "0.0.94",
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": {
@@ -25,12 +25,15 @@
25
25
  "mongoose": "7.x || 8.x"
26
26
  },
27
27
  "devDependencies": {
28
+ "@masteringjs/eslint-config": "0.1.1",
28
29
  "axios": "1.2.2",
30
+ "eslint": "9.30.0",
29
31
  "express": "4.x",
30
32
  "mocha": "10.2.0",
31
33
  "mongoose": "8.x"
32
34
  },
33
35
  "scripts": {
36
+ "lint": "eslint .",
34
37
  "tailwind": "tailwindcss -o ./frontend/public/tw.css",
35
38
  "tailwind:watch": "tailwindcss -o ./frontend/public/tw.css --watch"
36
39
  }