@mongoosejs/studio 0.2.12 → 0.3.0

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 (92) hide show
  1. package/backend/actions/ChatMessage/executeScript.js +5 -1
  2. package/backend/actions/ChatThread/createChatMessage.js +2 -1
  3. package/backend/actions/ChatThread/streamChatMessage.js +2 -2
  4. package/backend/actions/Model/getEstimatedDocumentCounts.js +38 -0
  5. package/backend/actions/Model/index.js +1 -0
  6. package/backend/actions/Model/streamDocumentChanges.js +8 -7
  7. package/backend/actions/Task/getTasks.js +9 -6
  8. package/backend/authorize.js +1 -0
  9. package/backend/index.js +11 -3
  10. package/eslint.config.js +5 -1
  11. package/express.js +1 -0
  12. package/frontend/public/app.js +25235 -662
  13. package/frontend/public/dark-theme.css +365 -0
  14. package/frontend/public/images/mongoose-studio.svg +4 -0
  15. package/frontend/public/index.html +21 -1
  16. package/frontend/public/style.css +5 -7
  17. package/frontend/public/theme-variables.css +294 -0
  18. package/frontend/public/tw.css +461 -239
  19. package/frontend/src/ace-editor/ace-editor.html +4 -0
  20. package/frontend/src/ace-editor/ace-editor.js +89 -0
  21. package/frontend/src/aceEditor.js +69 -0
  22. package/frontend/src/api.js +6 -0
  23. package/frontend/src/chat/chat-message/chat-message.html +1 -1
  24. package/frontend/src/chat/chat-message/chat-message.js +1 -1
  25. package/frontend/src/chat/chat-message-script/chat-message-script.html +51 -34
  26. package/frontend/src/chat/chat-message-script/chat-message-script.js +12 -55
  27. package/frontend/src/chat/chat.html +72 -37
  28. package/frontend/src/chat/chat.js +26 -2
  29. package/frontend/src/clone-document/clone-document.html +7 -2
  30. package/frontend/src/clone-document/clone-document.js +1 -8
  31. package/frontend/src/create-dashboard/create-dashboard.html +11 -6
  32. package/frontend/src/create-dashboard/create-dashboard.js +0 -7
  33. package/frontend/src/create-document/create-document.html +15 -9
  34. package/frontend/src/create-document/create-document.js +5 -12
  35. package/frontend/src/dashboard/dashboard.html +14 -12
  36. package/frontend/src/dashboard/dashboard.js +12 -4
  37. package/frontend/src/dashboard/edit-dashboard/edit-dashboard.html +13 -7
  38. package/frontend/src/dashboard/edit-dashboard/edit-dashboard.js +13 -21
  39. package/frontend/src/dashboard-result/dashboard-chart/dashboard-chart.html +19 -17
  40. package/frontend/src/dashboard-result/dashboard-chart/dashboard-chart.js +97 -2
  41. package/frontend/src/dashboard-result/dashboard-map/dashboard-map.js +27 -3
  42. package/frontend/src/dashboard-result/dashboard-result.html +3 -3
  43. package/frontend/src/dashboards/dashboards.html +101 -109
  44. package/frontend/src/dashboards/dashboards.js +25 -1
  45. package/frontend/src/detail-default/detail-default.html +2 -2
  46. package/frontend/src/detail-default/detail-default.js +24 -3
  47. package/frontend/src/document/confirm-changes/confirm-changes.html +1 -1
  48. package/frontend/src/document/confirm-delete/confirm-delete.html +1 -1
  49. package/frontend/src/document/document.css +1 -1
  50. package/frontend/src/document/document.html +53 -27
  51. package/frontend/src/document/document.js +27 -1
  52. package/frontend/src/document/execute-script/execute-script.html +20 -21
  53. package/frontend/src/document/execute-script/execute-script.js +1 -43
  54. package/frontend/src/document-details/document-details.css +4 -9
  55. package/frontend/src/document-details/document-details.html +34 -33
  56. package/frontend/src/document-details/document-details.js +2 -53
  57. package/frontend/src/document-details/document-property/document-property.html +12 -12
  58. package/frontend/src/edit-array/edit-array.html +7 -6
  59. package/frontend/src/edit-array/edit-array.js +10 -50
  60. package/frontend/src/edit-boolean/edit-boolean.html +12 -12
  61. package/frontend/src/edit-date/edit-date.html +2 -2
  62. package/frontend/src/edit-default/edit-default.html +1 -1
  63. package/frontend/src/edit-string/edit-string.html +3 -3
  64. package/frontend/src/edit-subdocument/edit-subdocument.html +5 -3
  65. package/frontend/src/edit-subdocument/edit-subdocument.js +1 -15
  66. package/frontend/src/export-query-results/export-query-results.html +3 -3
  67. package/frontend/src/json-node/json-node.html +3 -3
  68. package/frontend/src/list-json/json-node.html +1 -1
  69. package/frontend/src/models/document-search/document-search.html +3 -3
  70. package/frontend/src/models/model-switcher/model-switcher.html +53 -0
  71. package/frontend/src/models/model-switcher/model-switcher.js +123 -0
  72. package/frontend/src/models/models.css +3 -10
  73. package/frontend/src/models/models.html +146 -74
  74. package/frontend/src/models/models.js +142 -4
  75. package/frontend/src/navbar/navbar.html +157 -97
  76. package/frontend/src/navbar/navbar.js +32 -13
  77. package/frontend/src/routes.js +20 -4
  78. package/frontend/src/splash/splash.html +5 -5
  79. package/frontend/src/task-by-name/task-by-name.html +15 -0
  80. package/frontend/src/task-by-name/task-by-name.js +78 -0
  81. package/frontend/src/task-single/task-single.html +157 -0
  82. package/frontend/src/task-single/task-single.js +116 -0
  83. package/frontend/src/tasks/task-details/task-details.html +124 -73
  84. package/frontend/src/tasks/task-details/task-details.js +166 -10
  85. package/frontend/src/tasks/tasks.html +37 -48
  86. package/frontend/src/tasks/tasks.js +11 -50
  87. package/frontend/src/team/new-invitation/new-invitation.html +8 -8
  88. package/frontend/src/team/team.html +27 -27
  89. package/frontend/src/update-document/update-document.html +7 -2
  90. package/frontend/src/update-document/update-document.js +2 -11
  91. package/package.json +3 -1
  92. package/tailwind.config.js +75 -11
@@ -1,42 +1,107 @@
1
1
  <div class="models flex" style="height: calc(100vh - 55px); height: calc(100dvh - 55px)">
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" class="w-5" fill="#5f6368"><path d="M360-120v-720h80v720h-80Zm160-160v-400l200 200-200 200Z"/></svg>
4
- </div>
5
- <aside class="bg-white border-r overflow-y-auto overflow-x-hidden h-full transition-all duration-300 ease-in-out z-20 w-0 lg:w-48 fixed lg:relative shrink-0" :class="hideSidebar === true ? '!w-0' : hideSidebar === false ? '!w-48' : ''">
6
- <div class="flex items-center border-b border-gray-100 w-48 overflow-x-hidden">
7
- <div class="p-1 ml-2 font-bold">Models</div>
8
- <button
9
- @click="hideSidebar = true"
10
- class="ml-auto mr-2 p-2 rounded hover:bg-gray-200 focus:outline-none"
11
- aria-label="Close sidebar"
12
- >
13
- <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>
14
- </button>
2
+ <aside class="bg-page border-r overflow-hidden transition-all duration-300 ease-in-out z-20 w-0 lg:w-64 fixed lg:relative shrink-0 flex flex-col top-[55px] bottom-0 lg:top-auto lg:bottom-auto lg:h-full" :class="hideSidebar === true ? '!w-0' : hideSidebar === false ? '!w-64' : ''">
3
+ <!-- Search -->
4
+ <div class="p-3 shrink-0">
5
+ <div class="relative">
6
+ <svg class="absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
7
+ <path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" />
8
+ </svg>
9
+ <input
10
+ v-model="modelSearch"
11
+ type="text"
12
+ placeholder="Find model..."
13
+ @keydown.esc="modelSearch = ''"
14
+ class="w-full rounded-md border border-edge bg-surface py-1.5 pl-8 pr-3 text-sm text-content placeholder:text-gray-400 focus:border-edge-strong focus:outline-none focus:ring-1 focus:ring-gray-300"
15
+ />
16
+ </div>
15
17
  </div>
16
- <nav class="flex flex-1 flex-col">
17
- <ul role="list" class="flex flex-1 flex-col gap-y-7 p-1">
18
- <li>
19
- <ul role="list">
20
- <li v-for="model in models">
21
- <router-link
22
- :to="'/model/' + model"
23
- class="block truncate rounded-md py-2 pr-2 pl-2 text-sm text-gray-700"
24
- :class="model === currentModel ? 'bg-ultramarine-100 font-bold text-gray-900' : 'hover:bg-ultramarine-50'">
25
- {{model}}
26
- </router-link>
27
- </li>
28
- </ul>
18
+ <!-- Model list (scrollable) -->
19
+ <nav class="flex-1 overflow-y-auto px-2 pb-2">
20
+ <!-- Recently Viewed -->
21
+ <div v-if="filteredRecentModels.length > 0 && !modelSearch.trim()">
22
+ <div class="px-2 py-1 text-xs font-semibold text-gray-400 uppercase tracking-wider">Recently Viewed</div>
23
+ <ul role="list">
24
+ <li v-for="model in filteredRecentModels" :key="'recent-' + model">
25
+ <router-link
26
+ :to="'/model/' + model"
27
+ class="flex items-center rounded-md py-1.5 px-2 text-sm text-content-secondary"
28
+ :class="model === currentModel ? 'bg-gray-200 font-semibold text-content' : 'hover:bg-muted'">
29
+ <span class="truncate" v-html="highlightMatch(model)"></span>
30
+ <span
31
+ v-if="modelDocumentCounts && modelDocumentCounts[model] !== undefined && model !== currentModel"
32
+ class="ml-auto text-xs text-gray-400 bg-muted rounded px-1.5 py-[1px]"
33
+ >
34
+ {{formatCompactCount(modelDocumentCounts[model])}}
35
+ </span>
36
+ </router-link>
37
+ </li>
38
+ </ul>
39
+ <div class="border-b border-edge my-2"></div>
40
+ </div>
41
+ <!-- All Models / Search Results -->
42
+ <div class="px-2 py-1 text-xs font-semibold text-gray-400 uppercase tracking-wider">{{ modelSearch.trim() ? 'Search Results' : 'All Models' }}</div>
43
+ <ul role="list">
44
+ <li v-for="model in filteredModels" :key="'all-' + model">
45
+ <router-link
46
+ :to="'/model/' + model"
47
+ class="flex items-center rounded-md py-1.5 px-2 text-sm text-content-secondary"
48
+ :class="model === currentModel ? 'bg-gray-200 font-semibold text-content' : 'hover:bg-muted'">
49
+ <span class="truncate" v-html="highlightMatch(model)"></span>
50
+ <span
51
+ v-if="modelDocumentCounts && modelDocumentCounts[model] !== undefined && model !== currentModel"
52
+ class="ml-auto text-xs text-gray-400 bg-muted rounded px-1.5 py-[1px]"
53
+ >
54
+ {{formatCompactCount(modelDocumentCounts[model])}}
55
+ </span>
56
+ </router-link>
29
57
  </li>
30
58
  </ul>
31
- <div v-if="models.length === 0 && status === 'loaded'" class="p-2 bg-red-100">
59
+ <div v-if="filteredModels.length === 0 && modelSearch.trim()" class="px-2 py-2 text-sm text-content-tertiary">
60
+ No models match "{{modelSearch}}"
61
+ </div>
62
+ <div v-if="models.length === 0 && status === 'loaded'" class="p-2 bg-red-100 rounded-md">
32
63
  No models found
33
64
  </div>
34
65
  </nav>
66
+ <!-- Bottom toolbar -->
67
+ <div class="shrink-0 border-t border-edge bg-page px-2 py-1.5 flex items-center gap-1">
68
+ <button
69
+ type="button"
70
+ @click="hideSidebar = true"
71
+ class="rounded p-1.5 text-gray-400 hover:text-gray-600 hover:bg-muted"
72
+ title="Hide sidebar"
73
+ >
74
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
75
+ <path stroke-linecap="round" stroke-linejoin="round" d="m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5" />
76
+ </svg>
77
+ </button>
78
+ <button
79
+ type="button"
80
+ @click="openModelSwitcher"
81
+ class="rounded p-1.5 text-gray-400 hover:text-gray-600 hover:bg-muted"
82
+ title="Quick switch (Ctrl+P)"
83
+ >
84
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
85
+ <path stroke-linecap="round" stroke-linejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" />
86
+ </svg>
87
+ </button>
88
+ </div>
35
89
  </aside>
36
- <div class="documents bg-slate-50" ref="documentsList">
37
- <div class="relative h-[42px]" style="z-index: 1000">
90
+ <div class="documents bg-slate-50 min-w-0" ref="documentsList">
38
91
  <div class="documents-menu bg-slate-50">
39
92
  <div class="flex flex-row items-center w-full gap-2">
93
+ <button
94
+ v-if="hideSidebar === true || hideSidebar === null"
95
+ type="button"
96
+ @click="hideSidebar = false"
97
+ class="shrink-0 rounded-md p-1.5 text-gray-400 hover:text-gray-600 hover:bg-muted"
98
+ :class="hideSidebar === null ? 'lg:hidden' : ''"
99
+ title="Show sidebar"
100
+ >
101
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
102
+ <path stroke-linecap="round" stroke-linejoin="round" d="m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5" />
103
+ </svg>
104
+ </button>
40
105
  <document-search
41
106
  ref="documentSearch"
42
107
  :value="searchText"
@@ -51,8 +116,8 @@
51
116
  <button
52
117
  @click="stagingSelect"
53
118
  type="button"
54
- :class="{ 'bg-gray-500 ring-inset ring-2 ring-gray-300 hover:bg-gray-600': selectMultiple, 'bg-ultramarine-600 hover:bg-ultramarine-500' : !selectMultiple }"
55
- class="rounded px-2 py-2 text-sm font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600"
119
+ :class="{ 'bg-page0 ring-inset ring-2 ring-gray-300 hover:bg-gray-600': selectMultiple, 'bg-primary hover:bg-primary-hover' : !selectMultiple }"
120
+ class="rounded px-2 py-2 text-sm font-semibold text-primary-text shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary"
56
121
  >
57
122
  {{ selectMultiple ? 'Cancel' : 'Select' }}
58
123
  </button>
@@ -77,55 +142,55 @@
77
142
  @click="toggleActionsMenu"
78
143
  type="button"
79
144
  aria-label="More actions"
80
- class="rounded bg-white px-2 py-2 text-sm font-semibold text-gray-700 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600">
145
+ class="rounded bg-surface px-2 py-2 text-sm font-semibold text-content-secondary shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-page focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary">
81
146
  <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
82
147
  <path stroke-linecap="round" stroke-linejoin="round" d="M12 6.75a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5Zm0 6a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5Zm0 6a.75.75 0 1 1 0-1.5.75.75 0 0 1 0 1.5Z" />
83
148
  </svg>
84
149
  </button>
85
150
  <div
86
151
  v-if="showActionsMenu"
87
- class="absolute right-0 mt-2 w-48 origin-top-right rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none z-20"
152
+ class="absolute right-0 mt-2 w-48 origin-top-right rounded-md bg-surface shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none z-20"
88
153
  >
89
154
  <div class="py-1">
90
155
  <button
91
156
  @click="shouldShowExportModal = true; showActionsMenu = false"
92
157
  type="button"
93
- class="block w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100"
158
+ class="block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted"
94
159
  >
95
160
  Export
96
161
  </button>
97
162
  <button
98
163
  @click="shouldShowCreateModal = true; showActionsMenu = false"
99
164
  type="button"
100
- class="block w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100"
165
+ class="block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted"
101
166
  >
102
167
  Create
103
168
  </button>
104
169
  <button
105
170
  @click="openFieldSelection(); showActionsMenu = false"
106
171
  type="button"
107
- class="block w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100"
172
+ class="block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted"
108
173
  >
109
174
  Projection
110
175
  </button>
111
176
  <button
112
177
  @click="openIndexModal"
113
178
  type="button"
114
- class="block w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100"
179
+ class="block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted"
115
180
  >
116
181
  Indexes
117
182
  </button>
118
183
  <button
119
184
  @click="openCollectionInfo"
120
185
  type="button"
121
- class="block w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100"
186
+ class="block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted"
122
187
  >
123
188
  Collection Info
124
189
  </button>
125
190
  <button
126
191
  @click="findOldestDocument"
127
192
  type="button"
128
- class="block w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100"
193
+ class="block w-full px-4 py-2 text-left text-sm text-content-secondary hover:bg-muted"
129
194
  >
130
195
  Find oldest document
131
196
  </button>
@@ -136,15 +201,15 @@
136
201
  <button
137
202
  @click="setOutputType('table')"
138
203
  type="button"
139
- class="relative inline-flex items-center rounded-none rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10"
140
- :class="outputType === 'table' ? 'bg-gray-200' : 'bg-white'">
204
+ class="relative inline-flex items-center rounded-none rounded-l-md px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-page focus:z-10"
205
+ :class="outputType === 'table' ? 'bg-gray-200' : 'bg-surface'">
141
206
  <img class="h-5 w-5" src="images/table.svg">
142
207
  </button>
143
208
  <button
144
209
  @click="setOutputType('json')"
145
210
  type="button"
146
- class="relative -ml-px inline-flex items-center px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-gray-50 focus:z-10"
147
- :class="outputType === 'json' ? 'bg-gray-200' : 'bg-white'">
211
+ class="relative -ml-px inline-flex items-center px-2 py-2 text-gray-400 ring-1 ring-inset ring-gray-300 hover:bg-page focus:z-10"
212
+ :class="outputType === 'json' ? 'bg-gray-200' : 'bg-surface'">
148
213
  <img class="h-5 w-5" src="images/json.svg">
149
214
  </button>
150
215
  <button
@@ -154,8 +219,8 @@
154
219
  :title="geoJsonFields.length > 0 ? 'Map view' : 'No GeoJSON fields detected'"
155
220
  class="relative -ml-px inline-flex items-center rounded-none rounded-r-md px-2 py-2 ring-1 ring-inset ring-gray-300 focus:z-10"
156
221
  :class="[
157
- geoJsonFields.length === 0 ? 'text-gray-300 cursor-not-allowed bg-gray-100' : 'text-gray-400 hover:bg-gray-50',
158
- outputType === 'map' ? 'bg-gray-200' : (geoJsonFields.length > 0 ? 'bg-white' : '')
222
+ geoJsonFields.length === 0 ? 'text-gray-300 cursor-not-allowed bg-muted' : 'text-gray-400 hover:bg-page',
223
+ outputType === 'map' ? 'bg-gray-200' : (geoJsonFields.length > 0 ? 'bg-surface' : '')
159
224
  ]">
160
225
  <svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
161
226
  <path stroke-linecap="round" stroke-linejoin="round" d="M9 6.75V15m6-6v8.25m.503 3.498 4.875-2.437c.381-.19.622-.58.622-1.006V4.82c0-.836-.88-1.38-1.628-1.006l-3.869 1.934c-.317.159-.69.159-1.006 0L9.503 3.252a1.125 1.125 0 0 0-1.006 0L3.622 5.689C3.24 5.88 3 6.27 3 6.695V19.18c0 .836.88 1.38 1.628 1.006l3.869-1.934c.317-.159.69-.159 1.006 0l4.994 2.497c.317.158.69.158 1.006 0Z" />
@@ -164,7 +229,6 @@
164
229
  </span>
165
230
  </div>
166
231
  </div>
167
- </div>
168
232
  <div class="documents-container relative">
169
233
  <div v-if="error">
170
234
  <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 relative m-4 rounded-md" role="alert">
@@ -174,7 +238,7 @@
174
238
  </div>
175
239
  <table v-else-if="outputType === 'table'">
176
240
  <thead class="bg-slate-50">
177
- <th v-for="path in filteredPaths" @click="addPathFilter(path.path)" class="cursor-pointer p-3">
241
+ <th v-for="path in filteredPaths" @click="addPathFilter(path.path)" class="bg-slate-50 cursor-pointer p-3">
178
242
  {{path.path}}
179
243
  <span class="path-type">
180
244
  ({{(path.instance || 'unknown')}})
@@ -184,7 +248,7 @@
184
248
  </th>
185
249
  </thead>
186
250
  <tbody>
187
- <tr v-for="document in documents" @click="handleDocumentClick(document, $event)" :key="document._id" class="bg-white hover:bg-slate-50">
251
+ <tr v-for="document in documents" @click="handleDocumentClick(document, $event)" :key="document._id" class="bg-surface hover:bg-slate-50">
188
252
  <td v-for="schemaPath in filteredPaths" class="p-3 cursor-pointer" :class="{ 'bg-blue-200': selectedDocuments.some(x => x._id.toString() === document._id.toString()) }">
189
253
  <component
190
254
  :is="getComponentForPath(schemaPath)"
@@ -202,12 +266,12 @@
202
266
  @click="handleDocumentContainerClick(document, $event)"
203
267
  :class="[
204
268
  'group relative transition-colors rounded-md border border-slate-100',
205
- selectedDocuments.some(x => x._id.toString() === document._id.toString()) ? 'bg-blue-200' : 'hover:shadow-sm hover:border-slate-300 bg-white'
269
+ selectedDocuments.some(x => x._id.toString() === document._id.toString()) ? 'bg-blue-200' : 'hover:shadow-sm hover:border-slate-300 bg-surface'
206
270
  ]"
207
271
  >
208
272
  <button
209
273
  type="button"
210
- class="absolute top-2 right-2 z-10 inline-flex items-center rounded bg-ultramarine-600 px-2 py-1 text-xs font-semibold text-white shadow-sm transition-opacity duration-150 opacity-0 group-hover:opacity-100 focus-visible:opacity-100 hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600"
274
+ class="absolute top-2 right-2 z-10 inline-flex items-center rounded bg-primary px-2 py-1 text-xs font-semibold text-primary-text shadow-sm transition-opacity duration-150 opacity-0 group-hover:opacity-100 focus-visible:opacity-100 hover:bg-primary-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary"
211
275
  @click.stop="openDocument(document)"
212
276
  >
213
277
  Open this Document
@@ -217,12 +281,12 @@
217
281
  </div>
218
282
  </div>
219
283
  <div v-else-if="outputType === 'map'" class="flex flex-col h-full">
220
- <div class="p-2 bg-white border-b flex items-center gap-2">
221
- <label class="text-sm font-medium text-gray-700">GeoJSON Field:</label>
284
+ <div class="p-2 bg-surface border-b flex items-center gap-2">
285
+ <label class="text-sm font-medium text-content-secondary">GeoJSON Field:</label>
222
286
  <select
223
287
  :value="selectedGeoField"
224
288
  @change="setSelectedGeoField($event.target.value)"
225
- class="rounded-md border border-gray-300 py-1 px-2 text-sm focus:border-ultramarine-500 focus:ring-ultramarine-500"
289
+ class="rounded-md border border-edge-strong py-1 px-2 text-sm focus:border-primary focus:ring-primary"
226
290
  >
227
291
  <option v-for="field in geoJsonFields" :key="field.path" :value="field.path">
228
292
  {{ field.label }}
@@ -232,8 +296,8 @@
232
296
  @click="loadMoreDocuments"
233
297
  :disabled="loadedAllDocs"
234
298
  type="button"
235
- class="rounded px-2 py-1 text-xs font-semibold text-white shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ultramarine-600"
236
- :class="loadedAllDocs ? 'bg-gray-400 cursor-not-allowed' : 'bg-ultramarine-600 hover:bg-ultramarine-500'"
299
+ class="rounded px-2 py-1 text-xs font-semibold text-primary-text shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary"
300
+ :class="loadedAllDocs ? 'bg-gray-400 cursor-not-allowed' : 'bg-primary hover:bg-primary-hover'"
237
301
  >
238
302
  Load more
239
303
  </async-button>
@@ -265,7 +329,7 @@
265
329
  <div>
266
330
  <div class="font-bold flex items-center gap-2">
267
331
  <div>{{ index.name }}</div>
268
- <div v-if="isTTLIndex(index)" class="rounded-full bg-ultramarine-100 px-2 py-0.5 text-xs font-semibold text-ultramarine-700">
332
+ <div v-if="isTTLIndex(index)" class="rounded-full bg-primary-subtle px-2 py-0.5 text-xs font-semibold text-primary">
269
333
  TTL: {{ formatTTL(index.expireAfterSeconds) }}
270
334
  </div>
271
335
  </div>
@@ -290,33 +354,33 @@
290
354
  <div v-if="!collectionInfo" class="text-gray-600">Loading collection details...</div>
291
355
  <div v-else class="space-y-3">
292
356
  <div class="flex justify-between gap-4">
293
- <div class="font-semibold text-gray-700">Documents</div>
294
- <div class="text-gray-900">{{ formatNumber(collectionInfo.documentCount) }}</div>
357
+ <div class="font-semibold text-content-secondary">Documents</div>
358
+ <div class="text-content">{{ formatNumber(collectionInfo.documentCount) }}</div>
295
359
  </div>
296
360
  <div class="flex justify-between gap-4">
297
- <div class="font-semibold text-gray-700">Indexes</div>
298
- <div class="text-gray-900">{{ formatNumber(collectionInfo.indexCount) }}</div>
361
+ <div class="font-semibold text-content-secondary">Indexes</div>
362
+ <div class="text-content">{{ formatNumber(collectionInfo.indexCount) }}</div>
299
363
  </div>
300
364
  <div class="flex justify-between gap-4">
301
- <div class="font-semibold text-gray-700">Total Index Size</div>
302
- <div class="text-gray-900">{{ formatCollectionSize(collectionInfo.totalIndexSize) }}</div>
365
+ <div class="font-semibold text-content-secondary">Total Index Size</div>
366
+ <div class="text-content">{{ formatCollectionSize(collectionInfo.totalIndexSize) }}</div>
303
367
  </div>
304
368
  <div class="flex justify-between gap-4">
305
- <div class="font-semibold text-gray-700">Total Storage Size</div>
306
- <div class="text-gray-900">{{ formatCollectionSize(collectionInfo.size) }}</div>
369
+ <div class="font-semibold text-content-secondary">Total Storage Size</div>
370
+ <div class="text-content">{{ formatCollectionSize(collectionInfo.size) }}</div>
307
371
  </div>
308
372
  <div class="flex flex-col gap-1">
309
373
  <div class="flex justify-between gap-4">
310
- <div class="font-semibold text-gray-700">Collation</div>
311
- <div class="text-gray-900">{{ collectionInfo.hasCollation ? 'Yes' : 'No' }}</div>
374
+ <div class="font-semibold text-content-secondary">Collation</div>
375
+ <div class="text-content">{{ collectionInfo.hasCollation ? 'Yes' : 'No' }}</div>
312
376
  </div>
313
- <div v-if="collectionInfo.hasCollation" class="rounded bg-gray-100 p-3 text-sm text-gray-800 overflow-x-auto">
377
+ <div v-if="collectionInfo.hasCollation" class="rounded bg-muted p-3 text-sm text-gray-800 overflow-x-auto">
314
378
  <pre class="whitespace-pre-wrap">{{ JSON.stringify(collectionInfo.collation, null, 2) }}</pre>
315
379
  </div>
316
380
  </div>
317
381
  <div class="flex justify-between gap-4">
318
- <div class="font-semibold text-gray-700">Capped</div>
319
- <div class="text-gray-900">{{ collectionInfo.capped ? 'Yes' : 'No' }}</div>
382
+ <div class="font-semibold text-content-secondary">Capped</div>
383
+ <div class="text-content">{{ collectionInfo.capped ? 'Yes' : 'No' }}</div>
320
384
  </div>
321
385
  </div>
322
386
  </template>
@@ -325,16 +389,16 @@
325
389
  <template v-slot:body>
326
390
  <div class="modal-exit" @click="shouldShowFieldModal = false; selectedPaths = [...filteredPaths];">&times;</div>
327
391
  <div v-for="(path, index) in schemaPaths" :key="index" class="w-5 flex items-center">
328
- <input class="mt-0 h-4 w-4 rounded border-gray-300 text-sky-600 focus:ring-sky-600 accent-sky-600" type="checkbox" :id="'path.path'+index" @change="addOrRemove(path)" :value="path.path" :checked="isSelected(path.path)" />
329
- <div class="ml-2 text-gray-700 grow shrink text-left">
392
+ <input class="mt-0 h-4 w-4 rounded border-edge-strong text-sky-600 focus:ring-sky-600 accent-sky-600" type="checkbox" :id="'path.path'+index" @change="addOrRemove(path)" :value="path.path" :checked="isSelected(path.path)" />
393
+ <div class="ml-2 text-content-secondary grow shrink text-left">
330
394
  <label :for="'path.path' + index">{{path.path}}</label>
331
395
  </div>
332
396
  </div>
333
397
  <div class="mt-4 flex gap-2">
334
- <button type="button" @click="filterDocuments()" class="rounded-md bg-ultramarine-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-ultramarine-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600">Filter Selection</button>
398
+ <button type="button" @click="filterDocuments()" class="rounded-md bg-primary px-2.5 py-1.5 text-sm font-semibold text-primary-text shadow-sm hover:bg-primary-hover focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-teal-600">Filter Selection</button>
335
399
  <button type="button" @click="selectAll()" class="rounded-md bg-forest-green-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-green-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600">Select All</button>
336
400
  <button type="button" @click="deselectAll()" class="rounded-md bg-valencia-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-valencia-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600">Deselect All</button>
337
- <button type="button" @click="resetDocuments()" class="rounded-md bg-gray-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-gray-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600" >Cancel</button>
401
+ <button type="button" @click="resetDocuments()" class="rounded-md bg-gray-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-page0 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600" >Cancel</button>
338
402
  </div>
339
403
  </template>
340
404
  </modal>
@@ -361,10 +425,18 @@
361
425
  <async-button @click="deleteDocuments" class="rounded bg-red-500 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600">
362
426
  Confirm
363
427
  </async-button>
364
- <button @click="shouldShowDeleteMultipleModal = false;" class="rounded bg-gray-400 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-gray-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-500">
428
+ <button @click="shouldShowDeleteMultipleModal = false;" class="rounded bg-gray-400 px-2 py-2 text-sm font-semibold text-white shadow-sm hover:bg-page0 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-500">
365
429
  Cancel
366
430
  </button>
367
431
  </div>
368
432
  </template>
369
433
  </modal>
434
+ <model-switcher
435
+ :show="showModelSwitcher"
436
+ :models="models"
437
+ :recently-viewed-models="recentlyViewedModels"
438
+ :model-document-counts="modelDocumentCounts"
439
+ @close="showModelSwitcher = false"
440
+ @select="selectSwitcherModel"
441
+ ></model-switcher>
370
442
  </div>