@morscherlab/mint-sdk 1.0.0-beta.6 → 1.0.0-rc.1

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 (48) hide show
  1. package/dist/__tests__/composables/useProtocolTemplates.test.d.ts +1 -0
  2. package/dist/__tests__/stores/settings.test.d.ts +1 -0
  3. package/dist/{auth-QQj2kkze.js → auth-CBG3bWEc.js} +50 -20
  4. package/dist/auth-CBG3bWEc.js.map +1 -0
  5. package/dist/components/SettingsModal.vue.d.ts +5 -0
  6. package/dist/components/index.js +2 -2
  7. package/dist/{components-DihbSJjU.js → components-5KSfsVqf.js} +49 -29
  8. package/dist/components-5KSfsVqf.js.map +1 -0
  9. package/dist/composables/index.js +3 -3
  10. package/dist/{composables-BcgZ6diz.js → composables-D4Myb30a.js} +3 -3
  11. package/dist/{composables-BcgZ6diz.js.map → composables-D4Myb30a.js.map} +1 -1
  12. package/dist/index.js +5 -5
  13. package/dist/install.js +2 -2
  14. package/dist/stores/index.js +1 -1
  15. package/dist/styles.css +16 -0
  16. package/dist/templates/index.js +1 -1
  17. package/dist/{templates-Cyt0Suwf.js → templates-BSlxwV2c.js} +12 -8
  18. package/dist/templates-BSlxwV2c.js.map +1 -0
  19. package/dist/{useExperimentData-CM6Y0u5L.js → useExperimentData-BbbdI5xT.js} +97 -25
  20. package/dist/useExperimentData-BbbdI5xT.js.map +1 -0
  21. package/package.json +1 -1
  22. package/src/__tests__/components/GroupAssigner.test.ts +18 -0
  23. package/src/__tests__/composables/useApi.test.ts +45 -0
  24. package/src/__tests__/composables/useAuth.test.ts +20 -0
  25. package/src/__tests__/composables/useProtocolTemplates.test.ts +64 -0
  26. package/src/__tests__/stores/settings.test.ts +78 -0
  27. package/src/components/AppAvatarMenu.vue +6 -3
  28. package/src/components/AppTopBar.vue +15 -10
  29. package/src/components/AuditTrail.vue +1 -1
  30. package/src/components/Calendar.vue +6 -2
  31. package/src/components/ConcentrationInput.vue +3 -2
  32. package/src/components/GroupAssigner.vue +8 -3
  33. package/src/components/NumberInput.vue +5 -3
  34. package/src/components/SampleHierarchyTree.vue +3 -2
  35. package/src/components/SettingsModal.vue +7 -0
  36. package/src/components/UnitInput.vue +6 -2
  37. package/src/components/WellPlate.vue +3 -3
  38. package/src/composables/useApi.ts +113 -16
  39. package/src/composables/useAutoGroup.ts +13 -8
  40. package/src/composables/useProtocolTemplates.ts +13 -1
  41. package/src/composables/useRackEditor.ts +3 -2
  42. package/src/stores/auth.ts +48 -23
  43. package/src/stores/settings.ts +10 -0
  44. package/src/styles/components/settings-modal.css +9 -0
  45. package/dist/auth-QQj2kkze.js.map +0 -1
  46. package/dist/components-DihbSJjU.js.map +0 -1
  47. package/dist/templates-Cyt0Suwf.js.map +0 -1
  48. package/dist/useExperimentData-CM6Y0u5L.js.map +0 -1
@@ -0,0 +1 @@
1
+ export {};
@@ -2,6 +2,7 @@ import { computed, ref, watch } from "vue";
2
2
  import { defineStore } from "pinia";
3
3
  //#region src/stores/settings.ts
4
4
  var STORAGE_KEY = "mint-settings";
5
+ var LEGACY_STORAGE_KEY = "mld-settings";
5
6
  function getDefaultServerHost() {
6
7
  if (typeof window !== "undefined" && window.location.hostname !== "localhost") return window.location.hostname;
7
8
  return "localhost";
@@ -51,6 +52,17 @@ function loadSettings() {
51
52
  ...parsed
52
53
  };
53
54
  }
55
+ const legacyStored = localStorage.getItem(LEGACY_STORAGE_KEY);
56
+ if (legacyStored) {
57
+ const parsed = JSON.parse(legacyStored);
58
+ const migrated = {
59
+ ...defaultSettings,
60
+ ...parsed
61
+ };
62
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(migrated));
63
+ localStorage.removeItem(LEGACY_STORAGE_KEY);
64
+ return migrated;
65
+ }
54
66
  } catch (e) {
55
67
  console.warn("Failed to load settings from localStorage:", e);
56
68
  }
@@ -190,7 +202,31 @@ var useSettingsStore = defineStore("mint-settings", () => {
190
202
  //#region src/stores/auth.ts
191
203
  var AUTH_TOKEN_KEY = "mint-auth-token";
192
204
  var AUTH_EXPIRES_KEY = "mint-auth-expires";
193
- var hasLocalStorage = typeof localStorage !== "undefined" && typeof localStorage.getItem === "function";
205
+ function getLocalStorage() {
206
+ try {
207
+ const storage = globalThis.localStorage;
208
+ return typeof storage?.getItem === "function" ? storage : null;
209
+ } catch {
210
+ return null;
211
+ }
212
+ }
213
+ function readStoredItem(key) {
214
+ try {
215
+ return getLocalStorage()?.getItem(key) ?? null;
216
+ } catch {
217
+ return null;
218
+ }
219
+ }
220
+ function writeStoredItem(key, value) {
221
+ try {
222
+ getLocalStorage()?.setItem(key, value);
223
+ } catch {}
224
+ }
225
+ function removeStoredItem(key) {
226
+ try {
227
+ getLocalStorage()?.removeItem(key);
228
+ } catch {}
229
+ }
194
230
  var useAuthStore = defineStore("mint-auth", () => {
195
231
  const token = ref(null);
196
232
  const tokenExpires = ref(null);
@@ -222,16 +258,14 @@ var useAuthStore = defineStore("mint-auth", () => {
222
258
  return authConfig.value.registrationEnabled;
223
259
  });
224
260
  function initialize() {
225
- if (hasLocalStorage) {
226
- const storedToken = localStorage.getItem(AUTH_TOKEN_KEY);
227
- const storedExpires = localStorage.getItem(AUTH_EXPIRES_KEY);
228
- if (storedToken) {
229
- token.value = storedToken;
230
- if (storedExpires) {
231
- const expires = new Date(storedExpires);
232
- if (expires > /* @__PURE__ */ new Date()) tokenExpires.value = expires;
233
- else clearToken();
234
- }
261
+ const storedToken = readStoredItem(AUTH_TOKEN_KEY);
262
+ const storedExpires = readStoredItem(AUTH_EXPIRES_KEY);
263
+ if (storedToken) {
264
+ token.value = storedToken;
265
+ if (storedExpires) {
266
+ const expires = new Date(storedExpires);
267
+ if (expires > /* @__PURE__ */ new Date()) tokenExpires.value = expires;
268
+ else clearToken();
235
269
  }
236
270
  }
237
271
  isInitialized.value = true;
@@ -240,20 +274,16 @@ var useAuthStore = defineStore("mint-auth", () => {
240
274
  token.value = accessToken;
241
275
  const expires = new Date(Date.now() + expiresIn * 1e3);
242
276
  tokenExpires.value = expires;
243
- if (hasLocalStorage) {
244
- localStorage.setItem(AUTH_TOKEN_KEY, accessToken);
245
- localStorage.setItem(AUTH_EXPIRES_KEY, expires.toISOString());
246
- }
277
+ writeStoredItem(AUTH_TOKEN_KEY, accessToken);
278
+ writeStoredItem(AUTH_EXPIRES_KEY, expires.toISOString());
247
279
  }
248
280
  function clearToken() {
249
281
  token.value = null;
250
282
  tokenExpires.value = null;
251
283
  username.value = null;
252
284
  userInfo.value = null;
253
- if (hasLocalStorage) {
254
- localStorage.removeItem(AUTH_TOKEN_KEY);
255
- localStorage.removeItem(AUTH_EXPIRES_KEY);
256
- }
285
+ removeStoredItem(AUTH_TOKEN_KEY);
286
+ removeStoredItem(AUTH_EXPIRES_KEY);
257
287
  }
258
288
  function setUserInfo(info) {
259
289
  userInfo.value = info;
@@ -301,4 +331,4 @@ var useAuthStore = defineStore("mint-auth", () => {
301
331
  //#endregion
302
332
  export { colorPalettes as n, useSettingsStore as r, useAuthStore as t };
303
333
 
304
- //# sourceMappingURL=auth-QQj2kkze.js.map
334
+ //# sourceMappingURL=auth-CBG3bWEc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-CBG3bWEc.js","names":[],"sources":["../src/stores/settings.ts","../src/stores/auth.ts"],"sourcesContent":["import { defineStore } from 'pinia'\nimport { ref, watch } from 'vue'\nimport type { ThemeMode, ColorPalette, TableDensity } from '../types'\n\ndeclare global {\n interface ImportMetaEnv {\n readonly VITE_API_PREFIX?: string\n }\n\n interface ImportMeta {\n readonly env: ImportMetaEnv\n }\n}\n\nexport interface SettingsState {\n serverHost: string\n serverPort: number\n requestTimeout: number\n wsAutoReconnect: boolean\n wsReconnectInterval: number\n theme: ThemeMode\n colorPalette: ColorPalette\n tableDensity: TableDensity\n}\n\nconst STORAGE_KEY = 'mint-settings'\nconst LEGACY_STORAGE_KEY = 'mld-settings'\n\nfunction getDefaultServerHost(): string {\n if (typeof window !== 'undefined' && window.location.hostname !== 'localhost') {\n return window.location.hostname\n }\n return 'localhost'\n}\n\nfunction getDefaultServerPort(): number {\n if (typeof window !== 'undefined') {\n if (window.location.port) {\n return parseInt(window.location.port, 10)\n }\n // Standard ports: 443 for HTTPS, 80 for HTTP (browser omits from location.port)\n return window.location.protocol === 'https:' ? 443 : 80\n }\n return 8000\n}\n\nconst defaultSettings: SettingsState = {\n serverHost: getDefaultServerHost(),\n serverPort: getDefaultServerPort(),\n requestTimeout: 120000,\n wsAutoReconnect: true,\n wsReconnectInterval: 5000,\n theme: 'system',\n colorPalette: 'default',\n tableDensity: 'normal',\n}\n\nexport const colorPalettes: Record<ColorPalette, { name: string; hues: [number, number] }> = {\n default: { name: 'Default (Cyan-Pink)', hues: [180, 320] },\n colorblind: { name: 'Colorblind-friendly', hues: [45, 260] },\n viridis: { name: 'Viridis', hues: [280, 80] },\n pastel: { name: 'Pastel', hues: [200, 340] },\n}\n\nfunction loadSettings(): SettingsState {\n try {\n const stored = localStorage.getItem(STORAGE_KEY)\n if (stored) {\n const parsed = JSON.parse(stored)\n return { ...defaultSettings, ...parsed }\n }\n\n const legacyStored = localStorage.getItem(LEGACY_STORAGE_KEY)\n if (legacyStored) {\n const parsed = JSON.parse(legacyStored)\n const migrated = { ...defaultSettings, ...parsed }\n localStorage.setItem(STORAGE_KEY, JSON.stringify(migrated))\n localStorage.removeItem(LEGACY_STORAGE_KEY)\n return migrated\n }\n } catch (e) {\n console.warn('Failed to load settings from localStorage:', e)\n }\n return { ...defaultSettings }\n}\n\nfunction saveSettings(settings: SettingsState): void {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(settings))\n } catch (e) {\n console.warn('Failed to save settings to localStorage:', e)\n }\n}\n\nfunction getSystemPrefersDark(): boolean {\n if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') return false\n return window.matchMedia('(prefers-color-scheme: dark)').matches\n}\n\nexport const useSettingsStore = defineStore('mint-settings', () => {\n // State\n const serverHost = ref(defaultSettings.serverHost)\n const serverPort = ref(defaultSettings.serverPort)\n const requestTimeout = ref(defaultSettings.requestTimeout)\n const wsAutoReconnect = ref(defaultSettings.wsAutoReconnect)\n const wsReconnectInterval = ref(defaultSettings.wsReconnectInterval)\n const theme = ref<ThemeMode>(defaultSettings.theme)\n const systemPrefersDark = ref(getSystemPrefersDark())\n const colorPalette = ref<ColorPalette>(defaultSettings.colorPalette)\n const tableDensity = ref<TableDensity>(defaultSettings.tableDensity)\n\n // API prefix - can be configured via env variable VITE_API_PREFIX\n const apiPrefix: string = (import.meta.env?.VITE_API_PREFIX as string | undefined) ?? '/api'\n\n function _isSameOrigin(): { same: boolean; currentHost: string; currentPort: string } {\n const currentHost = typeof window !== 'undefined' ? window.location.hostname : 'localhost'\n const currentPort = typeof window !== 'undefined' ? window.location.port : '8000'\n const effectivePort = currentPort || (window.location.protocol === 'https:' ? '443' : '80')\n const same =\n (serverHost.value === currentHost && String(serverPort.value) === effectivePort) ||\n (serverHost.value === 'localhost' && currentHost !== 'localhost')\n return { same, currentHost, currentPort }\n }\n\n function getApiBaseUrl(): string {\n const { same } = _isSameOrigin()\n if (same) return apiPrefix\n return `http://${serverHost.value}:${serverPort.value}${apiPrefix}`\n }\n\n function getWsBaseUrl(): string {\n const { same, currentHost, currentPort } = _isSameOrigin()\n const protocol = typeof window !== 'undefined' && window.location.protocol === 'https:' ? 'wss:' : 'ws:'\n if (same) return `${protocol}//${currentHost}${currentPort ? ':' + currentPort : ''}${apiPrefix}`\n return `ws://${serverHost.value}:${serverPort.value}${apiPrefix}`\n }\n\n let _initialized = false\n\n function initialize() {\n if (_initialized) return\n _initialized = true\n\n const loaded = loadSettings()\n serverHost.value = loaded.serverHost\n serverPort.value = loaded.serverPort\n requestTimeout.value = loaded.requestTimeout\n wsAutoReconnect.value = loaded.wsAutoReconnect\n wsReconnectInterval.value = loaded.wsReconnectInterval\n theme.value = loaded.theme\n colorPalette.value = loaded.colorPalette\n tableDensity.value = loaded.tableDensity\n\n applyTheme()\n }\n\n function applyTheme() {\n if (typeof document === 'undefined') return\n const dark = theme.value === 'system' ? systemPrefersDark.value : theme.value === 'dark'\n document.documentElement.classList.toggle('dark', dark)\n }\n\n watch(theme, () => {\n applyTheme()\n persistSettings()\n })\n\n if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') {\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (event) => {\n systemPrefersDark.value = event.matches\n if (theme.value === 'system') {\n applyTheme()\n }\n })\n }\n\n function persistSettings() {\n saveSettings({\n serverHost: serverHost.value,\n serverPort: serverPort.value,\n requestTimeout: requestTimeout.value,\n wsAutoReconnect: wsAutoReconnect.value,\n wsReconnectInterval: wsReconnectInterval.value,\n theme: theme.value,\n colorPalette: colorPalette.value,\n tableDensity: tableDensity.value,\n })\n }\n\n watch([serverHost, serverPort, requestTimeout, wsAutoReconnect, wsReconnectInterval, colorPalette, tableDensity], () => {\n persistSettings()\n })\n\n function resetToDefaults() {\n serverHost.value = defaultSettings.serverHost\n serverPort.value = defaultSettings.serverPort\n requestTimeout.value = defaultSettings.requestTimeout\n wsAutoReconnect.value = defaultSettings.wsAutoReconnect\n wsReconnectInterval.value = defaultSettings.wsReconnectInterval\n theme.value = defaultSettings.theme\n colorPalette.value = defaultSettings.colorPalette\n tableDensity.value = defaultSettings.tableDensity\n }\n\n function getPaletteHues(): [number, number] {\n return colorPalettes[colorPalette.value].hues\n }\n\n function isDark(): boolean {\n return theme.value === 'system' ? systemPrefersDark.value : theme.value === 'dark'\n }\n\n return {\n serverHost,\n serverPort,\n requestTimeout,\n wsAutoReconnect,\n wsReconnectInterval,\n theme,\n systemPrefersDark,\n colorPalette,\n tableDensity,\n initialize,\n applyTheme,\n persistSettings,\n resetToDefaults,\n getPaletteHues,\n isDark,\n getApiBaseUrl,\n getWsBaseUrl,\n }\n})\n","import { defineStore } from 'pinia'\nimport { ref, computed } from 'vue'\nimport type { AuthConfig, UserInfo } from '../types'\n\nconst AUTH_TOKEN_KEY = 'mint-auth-token'\nconst AUTH_EXPIRES_KEY = 'mint-auth-expires'\n\nfunction getLocalStorage(): Storage | null {\n try {\n const storage = globalThis.localStorage\n return typeof storage?.getItem === 'function' ? storage : null\n } catch {\n return null\n }\n}\n\nfunction readStoredItem(key: string): string | null {\n try {\n return getLocalStorage()?.getItem(key) ?? null\n } catch {\n return null\n }\n}\n\nfunction writeStoredItem(key: string, value: string): void {\n try {\n getLocalStorage()?.setItem(key, value)\n } catch {\n // Keep auth usable in-memory when browser storage is blocked.\n }\n}\n\nfunction removeStoredItem(key: string): void {\n try {\n getLocalStorage()?.removeItem(key)\n } catch {\n // Keep auth cleanup usable in-memory when browser storage is blocked.\n }\n}\n\nexport const useAuthStore = defineStore('mint-auth', () => {\n // State\n const token = ref<string | null>(null)\n const tokenExpires = ref<Date | null>(null)\n const username = ref<string | null>(null)\n const userInfo = ref<UserInfo | null>(null)\n const authConfig = ref<AuthConfig>({\n authRequired: true,\n passkeyEnabled: false,\n passkeyRegistered: false,\n registrationEnabled: false,\n databaseMode: 'none',\n })\n const isInitialized = ref(false)\n const isLoading = ref(false)\n const error = ref<string | null>(null)\n\n // Computed\n const isAuthenticated = computed(() => {\n if (!authConfig.value.authRequired) {\n return true\n }\n if (!token.value) {\n return false\n }\n if (tokenExpires.value && tokenExpires.value < new Date()) {\n return false\n }\n return true\n })\n\n const needsAuth = computed(() => {\n return authConfig.value.authRequired && !isAuthenticated.value\n })\n\n const isAdmin = computed(() => {\n return userInfo.value?.role === 'admin'\n })\n\n const canRegister = computed(() => {\n return authConfig.value.registrationEnabled\n })\n\n // Actions\n function initialize() {\n const storedToken = readStoredItem(AUTH_TOKEN_KEY)\n const storedExpires = readStoredItem(AUTH_EXPIRES_KEY)\n\n if (storedToken) {\n token.value = storedToken\n\n if (storedExpires) {\n const expires = new Date(storedExpires)\n if (expires > new Date()) {\n tokenExpires.value = expires\n } else {\n clearToken()\n }\n }\n }\n\n isInitialized.value = true\n }\n\n function setToken(accessToken: string, expiresIn: number) {\n token.value = accessToken\n const expires = new Date(Date.now() + expiresIn * 1000)\n tokenExpires.value = expires\n\n writeStoredItem(AUTH_TOKEN_KEY, accessToken)\n writeStoredItem(AUTH_EXPIRES_KEY, expires.toISOString())\n }\n\n function clearToken() {\n token.value = null\n tokenExpires.value = null\n username.value = null\n userInfo.value = null\n\n removeStoredItem(AUTH_TOKEN_KEY)\n removeStoredItem(AUTH_EXPIRES_KEY)\n }\n\n function setUserInfo(info: UserInfo) {\n userInfo.value = info\n username.value = info.username\n }\n\n function setAuthConfig(config: AuthConfig) {\n authConfig.value = config\n }\n\n function setUsername(name: string) {\n username.value = name\n }\n\n function setError(message: string | null) {\n error.value = message\n }\n\n function setLoading(loading: boolean) {\n isLoading.value = loading\n }\n\n function logout() {\n clearToken()\n }\n\n return {\n // State\n token,\n tokenExpires,\n username,\n userInfo,\n authConfig,\n isInitialized,\n isLoading,\n error,\n\n // Computed\n isAuthenticated,\n needsAuth,\n isAdmin,\n canRegister,\n\n // Actions\n initialize,\n setToken,\n clearToken,\n setAuthConfig,\n setUsername,\n setUserInfo,\n setError,\n setLoading,\n logout,\n }\n})\n"],"mappings":"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"}
@@ -21,6 +21,7 @@ interface Props {
21
21
  /** Optional dynamic enhancements (validators, dynamic options, callbacks). */
22
22
  enhancements?: FormEnhancements<Record<string, unknown>>;
23
23
  }
24
+ declare function handleClose(): void;
24
25
  declare function __VLS_template(): {
25
26
  attrs: Partial<{}>;
26
27
  slots: Partial<Record<`field:${string}`, (_: {
@@ -34,6 +35,10 @@ declare function __VLS_template(): {
34
35
  };
35
36
  }) => any>> & Partial<Record<`tab-${string}`, (_: {}) => any>> & {
36
37
  appearance?(_: {}): any;
38
+ footer?(_: {
39
+ values: Record<string, unknown>;
40
+ close: typeof handleClose;
41
+ }): any;
37
42
  };
38
43
  refs: {};
39
44
  rootEl: any;
@@ -1,3 +1,3 @@
1
- import { $ as Skeleton_default, A as ScheduleCalendar_default, B as PluginWorkspaceView_default, C as ProgressBar_default, D as DoseDesignWorkspaceView_default, E as AppContainer_default, F as PlateMapEditor_default, G as StepWizard_default, H as AppSidebar_default, I as SampleLegend_default, J as AppAvatarMenu_default, K as AppTopBar_default, L as WellPlate_default, M as AutoGroupModal_default, N as LoadingSpinner_default, O as ControlWorkspaceView_default, P as ReagentList_default, Q as EmptyState_default, R as ExperimentTimeline_default, S as Avatar_default, T as Divider_default, U as FormBuilder_default, V as AppLayout_default, W as FormActions_default, X as ExperimentSelectorModal_default, Y as PluginIcon_default, Z as ExperimentCodeBadge_default, _ as BioTemplateExperimentWorkspaceView_default, _t as BaseButton_default, a as ExperimentDataViewer_default, at as IconButton_default, b as Tooltip_default, c as ChemicalFormula_default, ct as FormField_default, d as SampleHierarchyTree_default, dt as DropdownButton_default, et as ExperimentPopover_default, f as ReagentEditor_default, ft as BasePill_default, g as BioTemplatePackWorkspaceView_default, gt as ColorSlider_default, h as BioTemplatePresetWorkspaceView_default, ht as BaseTabs_default, i as TimeRangeInput_default, it as ThemeToggle_default, j as SampleSelector_default, k as ComponentBindingRenderer_default, l as ScientificNumber_default, lt as DataFrame_default, m as RackEditor_default, mt as BaseModal_default, n as FitPanel_default, nt as SettingsModal_default, o as BatchProgressList_default, ot as AppToastContainer_default, p as GroupAssigner_default, pt as SegmentedControl_default, q as AppPluginSwitcher_default, r as ResourceCard_default, rt as CollapsibleCard_default, s as AuditTrail_default, st as AlertBox_default, tt as ConfirmDialog_default, u as ProtocolStepEditor_default, ut as Calendar_default, v as BioTemplateRenderer_default, w as StatusIndicator_default, x as Breadcrumb_default, y as ChartContainer_default, z as DoseCalculator_default } from "../components-DihbSJjU.js";
2
- import { Cr as BaseCheckbox_default, Dr as BaseInput_default, Er as BaseTextarea_default, Hn as SequenceInput_default, Jn as FileUploader_default, Rn as ConcentrationInput_default, Sr as BaseToggle_default, Vn as MoleculeInput_default, Wn as FormulaInput_default, Xn as TagsInput_default, Yn as NumberInput_default, Zn as TimePicker_default, br as BaseSlider_default, gr as MultiSelect_default, mr as DatePicker_default, qn as DateTimePicker_default, wr as BaseSelect_default, xr as BaseRadioGroup_default, zn as UnitInput_default } from "../templates-Cyt0Suwf.js";
1
+ import { $ as Skeleton_default, A as ScheduleCalendar_default, B as PluginWorkspaceView_default, C as ProgressBar_default, D as DoseDesignWorkspaceView_default, E as AppContainer_default, F as PlateMapEditor_default, G as StepWizard_default, H as AppSidebar_default, I as SampleLegend_default, J as AppAvatarMenu_default, K as AppTopBar_default, L as WellPlate_default, M as AutoGroupModal_default, N as LoadingSpinner_default, O as ControlWorkspaceView_default, P as ReagentList_default, Q as EmptyState_default, R as ExperimentTimeline_default, S as Avatar_default, T as Divider_default, U as FormBuilder_default, V as AppLayout_default, W as FormActions_default, X as ExperimentSelectorModal_default, Y as PluginIcon_default, Z as ExperimentCodeBadge_default, _ as BioTemplateExperimentWorkspaceView_default, _t as BaseButton_default, a as ExperimentDataViewer_default, at as IconButton_default, b as Tooltip_default, c as ChemicalFormula_default, ct as FormField_default, d as SampleHierarchyTree_default, dt as DropdownButton_default, et as ExperimentPopover_default, f as ReagentEditor_default, ft as BasePill_default, g as BioTemplatePackWorkspaceView_default, gt as ColorSlider_default, h as BioTemplatePresetWorkspaceView_default, ht as BaseTabs_default, i as TimeRangeInput_default, it as ThemeToggle_default, j as SampleSelector_default, k as ComponentBindingRenderer_default, l as ScientificNumber_default, lt as DataFrame_default, m as RackEditor_default, mt as BaseModal_default, n as FitPanel_default, nt as SettingsModal_default, o as BatchProgressList_default, ot as AppToastContainer_default, p as GroupAssigner_default, pt as SegmentedControl_default, q as AppPluginSwitcher_default, r as ResourceCard_default, rt as CollapsibleCard_default, s as AuditTrail_default, st as AlertBox_default, tt as ConfirmDialog_default, u as ProtocolStepEditor_default, ut as Calendar_default, v as BioTemplateRenderer_default, w as StatusIndicator_default, x as Breadcrumb_default, y as ChartContainer_default, z as DoseCalculator_default } from "../components-5KSfsVqf.js";
2
+ import { Cr as BaseCheckbox_default, Dr as BaseInput_default, Er as BaseTextarea_default, Hn as SequenceInput_default, Jn as FileUploader_default, Rn as ConcentrationInput_default, Sr as BaseToggle_default, Vn as MoleculeInput_default, Wn as FormulaInput_default, Xn as TagsInput_default, Yn as NumberInput_default, Zn as TimePicker_default, br as BaseSlider_default, gr as MultiSelect_default, mr as DatePicker_default, qn as DateTimePicker_default, wr as BaseSelect_default, xr as BaseRadioGroup_default, zn as UnitInput_default } from "../templates-BSlxwV2c.js";
3
3
  export { AlertBox_default as AlertBox, AppAvatarMenu_default as AppAvatarMenu, AppContainer_default as AppContainer, AppLayout_default as AppLayout, AppPluginSwitcher_default as AppPluginSwitcher, AppSidebar_default as AppSidebar, AppToastContainer_default as AppToastContainer, AppTopBar_default as AppTopBar, AuditTrail_default as AuditTrail, AutoGroupModal_default as AutoGroupModal, Avatar_default as Avatar, BaseButton_default as BaseButton, BaseCheckbox_default as BaseCheckbox, BaseInput_default as BaseInput, BaseModal_default as BaseModal, BasePill_default as BasePill, BaseRadioGroup_default as BaseRadioGroup, BaseSelect_default as BaseSelect, BaseSlider_default as BaseSlider, BaseTabs_default as BaseTabs, BaseTextarea_default as BaseTextarea, BaseToggle_default as BaseToggle, BatchProgressList_default as BatchProgressList, BioTemplateExperimentWorkspaceView_default as BioTemplateExperimentWorkspaceView, BioTemplatePackWorkspaceView_default as BioTemplatePackWorkspaceView, BioTemplatePresetWorkspaceView_default as BioTemplatePresetWorkspaceView, BioTemplateRenderer_default as BioTemplateRenderer, Breadcrumb_default as Breadcrumb, Calendar_default as Calendar, ChartContainer_default as ChartContainer, ChemicalFormula_default as ChemicalFormula, CollapsibleCard_default as CollapsibleCard, ColorSlider_default as ColorSlider, ComponentBindingRenderer_default as ComponentBindingRenderer, ConcentrationInput_default as ConcentrationInput, ConfirmDialog_default as ConfirmDialog, ControlWorkspaceView_default as ControlWorkspaceView, DataFrame_default as DataFrame, DatePicker_default as DatePicker, DateTimePicker_default as DateTimePicker, Divider_default as Divider, DoseCalculator_default as DoseCalculator, DoseDesignWorkspaceView_default as DoseDesignWorkspaceView, DropdownButton_default as DropdownButton, EmptyState_default as EmptyState, ExperimentCodeBadge_default as ExperimentCodeBadge, ExperimentDataViewer_default as ExperimentDataViewer, ExperimentPopover_default as ExperimentPopover, ExperimentSelectorModal_default as ExperimentSelectorModal, ExperimentTimeline_default as ExperimentTimeline, FileUploader_default as FileUploader, FitPanel_default as FitPanel, FormActions_default as FormActions, FormBuilder_default as FormBuilder, FormField_default as FormField, FormulaInput_default as FormulaInput, GroupAssigner_default as GroupAssigner, IconButton_default as IconButton, LoadingSpinner_default as LoadingSpinner, MoleculeInput_default as MoleculeInput, MultiSelect_default as MultiSelect, NumberInput_default as NumberInput, PlateMapEditor_default as PlateMapEditor, PluginIcon_default as PluginIcon, PluginWorkspaceView_default as PluginWorkspaceView, ProgressBar_default as ProgressBar, ProtocolStepEditor_default as ProtocolStepEditor, RackEditor_default as RackEditor, ReagentEditor_default as ReagentEditor, ReagentList_default as ReagentList, ResourceCard_default as ResourceCard, SampleHierarchyTree_default as SampleHierarchyTree, SampleLegend_default as SampleLegend, SampleSelector_default as SampleSelector, ScheduleCalendar_default as ScheduleCalendar, ScientificNumber_default as ScientificNumber, SegmentedControl_default as SegmentedControl, SequenceInput_default as SequenceInput, SettingsModal_default as SettingsModal, Skeleton_default as Skeleton, StatusIndicator_default as StatusIndicator, StepWizard_default as StepWizard, TagsInput_default as TagsInput, ThemeToggle_default as ThemeToggle, TimePicker_default as TimePicker, TimeRangeInput_default as TimeRangeInput, Tooltip_default as Tooltip, UnitInput_default as UnitInput, WellPlate_default as WellPlate };
@@ -1,6 +1,6 @@
1
- import { $n as compareTime, Bn as useConcentrationUnits, Bt as extractTemplateCollection, Cr as BaseCheckbox_default, Dn as defineDoseDesignControlModel, Dr as BaseInput_default, Er as BaseTextarea_default, Fn as useControlWorkspace, Hn as SequenceInput_default, In as getFieldRegistryEntry, Jn as FileUploader_default, Kn as useChemicalFormula, Mn as getDefaultControlView, Nn as mergeControlWorkspaceOptions, Rn as ConcentrationInput_default, Sn as controlsToViewItems, Sr as BaseToggle_default, Tr as normalizeOptionInput, Vn as MoleculeInput_default, Wn as FormulaInput_default, Xn as TagsInput_default, Yn as NumberInput_default, Zn as TimePicker_default, _ as toBioTemplateComponentPropsByComponent, _n as controlsToSectionFormSchemas, _r as useListSelection, br as BaseSlider_default, d as getBioTemplateComponentProps, er as durationMinutes, fn as controlValuesToComponentBindings, g as toBioTemplateComponentProps, gr as MultiSelect_default, hn as controlsToFormSchema, hr as useDropdownState, ir as formatTime, jn as getControlDefaults, m as toBioTemplateComponentBindingsById, mn as controlValuesToComponentProps, mr as DatePicker_default, p as toBioTemplateComponentBindings, pn as controlValuesToComponentBindingsById, qn as DateTimePicker_default, rr as formatDuration, v as toBioTemplateComponentPropsById, vn as controlsToSettingsSchema, wn as defineControlModel, wr as BaseSelect_default, xr as BaseRadioGroup_default, yn as controlsToSidebarPanels, yr as useEventListener, zn as UnitInput_default } from "./templates-Cyt0Suwf.js";
2
- import { $ as useTheme, A as useAutoGroup, B as DATE_PRESET_OPTIONS, C as useSampleGroups, D as DEFAULT_COLORS, F as usePlatformContext, H as EXPERIMENT_STATUS_OPTIONS, I as useExperimentSelector, J as getExperimentStatusVariant, K as formatExperimentDate, M as useDoseCalculator, N as APP_EXPERIMENT_KEY, P as useAppExperiment, S as useExpansionSet, W as SORT_OPTIONS, Z as useFormBuilder, at as useSortedItems, c as useRackEditor, et as useToast, i as DEFAULT_UNITS, j as useWellPlateEditor, k as parseCSV, l as useBioTemplatePresetWorkspace, n as useProtocolTemplates, o as useReagentSeries, q as formatExperimentStatus, r as DEFAULT_PRESETS, rt as useTextSearch, s as useGroupAssignment, t as useExperimentData, u as useBioTemplatePackWorkspace, x as useScheduleDrag, z as useApi } from "./useExperimentData-CM6Y0u5L.js";
3
- import { n as colorPalettes, r as useSettingsStore } from "./auth-QQj2kkze.js";
1
+ import { $n as compareTime, Bn as useConcentrationUnits, Bt as extractTemplateCollection, Cr as BaseCheckbox_default, Dn as defineDoseDesignControlModel, Dr as BaseInput_default, Er as BaseTextarea_default, Fn as useControlWorkspace, Hn as SequenceInput_default, In as getFieldRegistryEntry, Jn as FileUploader_default, Kn as useChemicalFormula, Mn as getDefaultControlView, Nn as mergeControlWorkspaceOptions, Rn as ConcentrationInput_default, Sn as controlsToViewItems, Sr as BaseToggle_default, Tr as normalizeOptionInput, Vn as MoleculeInput_default, Wn as FormulaInput_default, Xn as TagsInput_default, Yn as NumberInput_default, Zn as TimePicker_default, _ as toBioTemplateComponentPropsByComponent, _n as controlsToSectionFormSchemas, _r as useListSelection, br as BaseSlider_default, d as getBioTemplateComponentProps, er as durationMinutes, fn as controlValuesToComponentBindings, g as toBioTemplateComponentProps, gr as MultiSelect_default, hn as controlsToFormSchema, hr as useDropdownState, ir as formatTime, jn as getControlDefaults, m as toBioTemplateComponentBindingsById, mn as controlValuesToComponentProps, mr as DatePicker_default, p as toBioTemplateComponentBindings, pn as controlValuesToComponentBindingsById, qn as DateTimePicker_default, rr as formatDuration, v as toBioTemplateComponentPropsById, vn as controlsToSettingsSchema, wn as defineControlModel, wr as BaseSelect_default, xr as BaseRadioGroup_default, yn as controlsToSidebarPanels, yr as useEventListener, zn as UnitInput_default } from "./templates-BSlxwV2c.js";
2
+ import { $ as useTheme, A as useAutoGroup, B as DATE_PRESET_OPTIONS, C as useSampleGroups, D as DEFAULT_COLORS, F as usePlatformContext, H as EXPERIMENT_STATUS_OPTIONS, I as useExperimentSelector, J as getExperimentStatusVariant, K as formatExperimentDate, M as useDoseCalculator, N as APP_EXPERIMENT_KEY, P as useAppExperiment, S as useExpansionSet, W as SORT_OPTIONS, Z as useFormBuilder, at as useSortedItems, c as useRackEditor, et as useToast, i as DEFAULT_UNITS, j as useWellPlateEditor, k as parseCSV, l as useBioTemplatePresetWorkspace, n as useProtocolTemplates, o as useReagentSeries, q as formatExperimentStatus, r as DEFAULT_PRESETS, rt as useTextSearch, s as useGroupAssignment, t as useExperimentData, u as useBioTemplatePackWorkspace, x as useScheduleDrag, z as useApi } from "./useExperimentData-BbbdI5xT.js";
3
+ import { n as colorPalettes, r as useSettingsStore } from "./auth-CBG3bWEc.js";
4
4
  import { Fragment, Teleport, Transition, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createStaticVNode, createTextVNode, createVNode, defineComponent, effectScope, guardReactiveProps, h, inject, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onBeforeUnmount, onMounted, onScopeDispose, onUnmounted, openBlock, reactive, ref, renderList, renderSlot, resolveComponent, resolveDynamicComponent, shallowRef, toDisplayString, toRaw, unref, useSlots, vModelCheckbox, vModelSelect, vModelText, vShow, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
5
5
  //#region \0rolldown/runtime.js
6
6
  var __defProp = Object.defineProperty;
@@ -883,8 +883,9 @@ var Calendar_default = /* @__PURE__ */ defineComponent({
883
883
  const map = /* @__PURE__ */ new Map();
884
884
  for (const marker of props.markers) {
885
885
  const key = toDateKey(parseDate(marker.date));
886
- if (!map.has(key)) map.set(key, []);
887
- map.get(key).push(marker);
886
+ const markers = map.get(key);
887
+ if (markers) markers.push(marker);
888
+ else map.set(key, [marker]);
888
889
  }
889
890
  return map;
890
891
  });
@@ -2114,6 +2115,10 @@ var _hoisted_19$16 = ["onClick"];
2114
2115
  var _hoisted_20$15 = { class: "mint-settings-modal__section" };
2115
2116
  var _hoisted_21$13 = { class: "mint-settings-modal__option-group" };
2116
2117
  var _hoisted_22$11 = ["onClick"];
2118
+ var _hoisted_23$9 = {
2119
+ key: 0,
2120
+ class: "mint-settings-modal__footer"
2121
+ };
2117
2122
  var APPEARANCE_TAB_ID = "appearance";
2118
2123
  //#endregion
2119
2124
  //#region src/components/SettingsModal.vue
@@ -2374,7 +2379,10 @@ var SettingsModal_default = /* @__PURE__ */ defineComponent({
2374
2379
  "role",
2375
2380
  "aria-labelledby",
2376
2381
  "tabindex"
2377
- ]))], 2)]),
2382
+ ]))], 2), _ctx.$slots.footer ? (openBlock(), createElementBlock("div", _hoisted_23$9, [renderSlot(_ctx.$slots, "footer", {
2383
+ values: unref(builder).form.data,
2384
+ close: handleClose
2385
+ })])) : createCommentVNode("", true)]),
2378
2386
  _: 3
2379
2387
  }, 8, [
2380
2388
  "model-value",
@@ -3877,9 +3885,12 @@ var AppAvatarMenu_default = /* @__PURE__ */ defineComponent({
3877
3885
  const initials = computed(() => {
3878
3886
  if (props.userInitial) return props.userInitial.slice(0, 2).toUpperCase();
3879
3887
  if (props.userName) {
3880
- const parts = props.userName.trim().split(/\s+/);
3881
- if (parts.length >= 2) return (parts[0].charAt(0) + parts[1].charAt(0)).toUpperCase();
3882
- return parts[0].slice(0, 2).toUpperCase();
3888
+ const parts = props.userName.trim().split(/\s+/).filter(Boolean);
3889
+ const first = parts[0];
3890
+ if (!first) return "U";
3891
+ const second = parts[1];
3892
+ if (second) return (first.charAt(0) + second.charAt(0)).toUpperCase();
3893
+ return first.slice(0, 2).toUpperCase();
3883
3894
  }
3884
3895
  return "U";
3885
3896
  });
@@ -4224,7 +4235,13 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
4224
4235
  const { isIntegrated, plugin } = usePlatformContext();
4225
4236
  const isStandalone = computed(() => !isIntegrated.value);
4226
4237
  const appExperiment = inject(APP_EXPERIMENT_KEY, null);
4227
- const hasPluginIcon = computed(() => !!plugin.value?.icon);
4238
+ const pluginIcon = computed(() => {
4239
+ const currentPlugin = plugin.value;
4240
+ return currentPlugin?.icon ? {
4241
+ icon: currentPlugin.icon,
4242
+ color: currentPlugin.color
4243
+ } : null;
4244
+ });
4228
4245
  const profileInitial = computed(() => {
4229
4246
  if (props.userInitial) return props.userInitial;
4230
4247
  if (props.userName) return props.userName.charAt(0).toUpperCase();
@@ -4282,11 +4299,11 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
4282
4299
  key: 0,
4283
4300
  href: __props.homePath,
4284
4301
  class: "mint-topbar-home-link"
4285
- }, [renderSlot(_ctx.$slots, "icon", {}, () => [hasPluginIcon.value ? (openBlock(), createBlock(PluginIcon_default, {
4302
+ }, [renderSlot(_ctx.$slots, "icon", {}, () => [pluginIcon.value ? (openBlock(), createBlock(PluginIcon_default, {
4286
4303
  key: 0,
4287
4304
  class: "mint-topbar__plugin-icon",
4288
- icon: unref(plugin).icon,
4289
- tone: unref(plugin).color,
4305
+ icon: pluginIcon.value.icon,
4306
+ tone: pluginIcon.value.color,
4290
4307
  size: "md",
4291
4308
  variant: "solid"
4292
4309
  }, null, 8, ["icon", "tone"])) : renderSlot(_ctx.$slots, "logo", { key: 1 }, () => [__props.showLogo ? (openBlock(), createElementBlock("div", _hoisted_4$32, [..._cache[19] || (_cache[19] = [createElementVNode("div", { class: "mint-topbar__logo-icon" }, [createElementVNode("span", { class: "mint-topbar__logo-text" }, "M")], -1)])])) : createCommentVNode("", true)])])], 8, _hoisted_3$33)) : __props.homePath ? (openBlock(), createBlock(_component_router_link, {
@@ -4294,20 +4311,20 @@ var AppTopBar_default = /* @__PURE__ */ defineComponent({
4294
4311
  to: __props.homePath,
4295
4312
  class: "mint-topbar-home-link"
4296
4313
  }, {
4297
- default: withCtx(() => [renderSlot(_ctx.$slots, "icon", {}, () => [hasPluginIcon.value ? (openBlock(), createBlock(PluginIcon_default, {
4314
+ default: withCtx(() => [renderSlot(_ctx.$slots, "icon", {}, () => [pluginIcon.value ? (openBlock(), createBlock(PluginIcon_default, {
4298
4315
  key: 0,
4299
4316
  class: "mint-topbar__plugin-icon",
4300
- icon: unref(plugin).icon,
4301
- tone: unref(plugin).color,
4317
+ icon: pluginIcon.value.icon,
4318
+ tone: pluginIcon.value.color,
4302
4319
  size: "md",
4303
4320
  variant: "solid"
4304
4321
  }, null, 8, ["icon", "tone"])) : renderSlot(_ctx.$slots, "logo", { key: 1 }, () => [__props.showLogo ? (openBlock(), createElementBlock("div", _hoisted_5$30, [..._cache[20] || (_cache[20] = [createElementVNode("div", { class: "mint-topbar__logo-icon" }, [createElementVNode("span", { class: "mint-topbar__logo-text" }, "M")], -1)])])) : createCommentVNode("", true)])])]),
4305
4322
  _: 3
4306
- }, 8, ["to"])) : renderSlot(_ctx.$slots, "icon", { key: 2 }, () => [hasPluginIcon.value ? (openBlock(), createBlock(PluginIcon_default, {
4323
+ }, 8, ["to"])) : renderSlot(_ctx.$slots, "icon", { key: 2 }, () => [pluginIcon.value ? (openBlock(), createBlock(PluginIcon_default, {
4307
4324
  key: 0,
4308
4325
  class: "mint-topbar__plugin-icon",
4309
- icon: unref(plugin).icon,
4310
- tone: unref(plugin).color,
4326
+ icon: pluginIcon.value.icon,
4327
+ tone: pluginIcon.value.color,
4311
4328
  size: "md",
4312
4329
  variant: "solid"
4313
4330
  }, null, 8, ["icon", "tone"])) : renderSlot(_ctx.$slots, "logo", { key: 1 }, () => [__props.showLogo ? (openBlock(), createElementBlock("div", _hoisted_6$29, [..._cache[21] || (_cache[21] = [createElementVNode("div", { class: "mint-topbar__logo-icon" }, [createElementVNode("span", { class: "mint-topbar__logo-text" }, "M")], -1)])])) : createCommentVNode("", true)])])]),
@@ -7827,9 +7844,9 @@ var WellPlate_default = /* @__PURE__ */ defineComponent({
7827
7844
  }, [getWellLabel(well) ? (openBlock(), createElementBlock("span", _hoisted_12$13, toDisplayString(getWellLabel(well)), 1)) : getSampleTypeIndicator(well) ? (openBlock(), createElementBlock("span", _hoisted_13$13, toDisplayString(getSampleTypeIndicator(well)), 1)) : props.showWellIds ? (openBlock(), createElementBlock("span", _hoisted_14$12, toDisplayString(well.id), 1)) : createCommentVNode("", true), getWellBadge(well) ? (openBlock(), createElementBlock("span", {
7828
7845
  key: 3,
7829
7846
  class: "mint-well-plate__badge",
7830
- style: normalizeStyle({ backgroundColor: getWellBadge(well).color }),
7831
- title: getWellBadge(well).text === "+" ? "Custom method" : `${getWellBadge(well).text}x injections`
7832
- }, toDisplayString(getWellBadge(well).text), 13, _hoisted_15$11)) : createCommentVNode("", true)], 46, _hoisted_11$14)]);
7847
+ style: normalizeStyle({ backgroundColor: getWellBadge(well)?.color }),
7848
+ title: getWellBadge(well)?.text === "+" ? "Custom method" : `${getWellBadge(well)?.text ?? ""}x injections`
7849
+ }, toDisplayString(getWellBadge(well)?.text), 13, _hoisted_15$11)) : createCommentVNode("", true)], 46, _hoisted_11$14)]);
7833
7850
  }), 128))
7834
7851
  ]);
7835
7852
  }), 128))])
@@ -14003,9 +14020,11 @@ var GroupAssigner_default = /* @__PURE__ */ defineComponent({
14003
14020
  });
14004
14021
  const { unassignedGroups, zone1Groups, zone2Groups, zone1Count, zone2Count, validationMessage } = assignment;
14005
14022
  function handleDragStart(event, groupName) {
14023
+ const transfer = event.dataTransfer;
14024
+ if (!transfer) return;
14006
14025
  draggingGroup.value = groupName;
14007
- event.dataTransfer?.setData("groupName", groupName);
14008
- event.dataTransfer.effectAllowed = "move";
14026
+ transfer.setData("groupName", groupName);
14027
+ transfer.effectAllowed = "move";
14009
14028
  }
14010
14029
  function handleDragEnd() {
14011
14030
  draggingGroup.value = null;
@@ -14013,7 +14032,7 @@ var GroupAssigner_default = /* @__PURE__ */ defineComponent({
14013
14032
  }
14014
14033
  function handleDragOver(event, zone) {
14015
14034
  event.preventDefault();
14016
- event.dataTransfer.dropEffect = "move";
14035
+ if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
14017
14036
  dragOverZone.value = zone;
14018
14037
  }
14019
14038
  function handleDragLeave() {
@@ -14790,6 +14809,7 @@ var SampleHierarchyTree_default = /* @__PURE__ */ defineComponent({
14790
14809
  return isExpanded(node.id);
14791
14810
  }
14792
14811
  function renderNode(node, depth) {
14812
+ const children = node.children;
14793
14813
  const expanded = isExpanded(node.id);
14794
14814
  const canExpand = hasChildren(node);
14795
14815
  const showChildNodes = canShowChildren(node, depth);
@@ -14827,10 +14847,10 @@ var SampleHierarchyTree_default = /* @__PURE__ */ defineComponent({
14827
14847
  h("span", { class: "mint-sample-tree__label" }, node.label),
14828
14848
  badge !== void 0 ? h("span", { class: ["mint-sample-tree__badge", `mint-sample-tree__badge--${badgeVar}`] }, String(badge)) : null
14829
14849
  ]);
14830
- const childNodes = showChildNodes && node.children ? h(Transition, {
14850
+ const childNodes = showChildNodes && children ? h(Transition, {
14831
14851
  enterActiveClass: "mint-sample-tree__children--entering",
14832
14852
  leaveActiveClass: "mint-sample-tree__children--leaving"
14833
- }, () => h("div", { class: "mint-sample-tree__children" }, node.children.map((child) => renderNode(child, depth + 1)))) : null;
14853
+ }, () => h("div", { class: "mint-sample-tree__children" }, children.map((child) => renderNode(child, depth + 1)))) : null;
14834
14854
  return h("div", {
14835
14855
  key: node.id,
14836
14856
  class: [
@@ -15544,7 +15564,7 @@ var AuditTrail_default = /* @__PURE__ */ defineComponent({
15544
15564
  return Array.from(types);
15545
15565
  });
15546
15566
  const uniqueUsers = computed(() => {
15547
- const users = new Set(props.entries.filter((e) => e.user).map((e) => e.user));
15567
+ const users = new Set(props.entries.flatMap((e) => e.user ? [e.user] : []));
15548
15568
  return Array.from(users);
15549
15569
  });
15550
15570
  const filteredEntries = computed(() => {
@@ -16592,4 +16612,4 @@ var components_exports = /* @__PURE__ */ __exportAll({
16592
16612
  //#endregion
16593
16613
  export { Skeleton_default as $, ScheduleCalendar_default as A, PluginWorkspaceView_default as B, ProgressBar_default as C, DoseDesignWorkspaceView_default as D, AppContainer_default as E, PlateMapEditor_default as F, StepWizard_default as G, AppSidebar_default as H, SampleLegend_default as I, AppAvatarMenu_default as J, AppTopBar_default as K, WellPlate_default as L, AutoGroupModal_default as M, LoadingSpinner_default as N, ControlWorkspaceView_default as O, ReagentList_default as P, EmptyState_default as Q, ExperimentTimeline_default as R, Avatar_default as S, Divider_default as T, FormBuilder_default as U, AppLayout_default as V, FormActions_default as W, ExperimentSelectorModal_default as X, PluginIcon_default as Y, ExperimentCodeBadge_default as Z, BioTemplateExperimentWorkspaceView_default as _, BaseButton_default as _t, ExperimentDataViewer_default as a, IconButton_default as at, Tooltip_default as b, ChemicalFormula_default as c, FormField_default as ct, SampleHierarchyTree_default as d, DropdownButton_default as dt, ExperimentPopover_default as et, ReagentEditor_default as f, BasePill_default as ft, BioTemplatePackWorkspaceView_default as g, ColorSlider_default as gt, BioTemplatePresetWorkspaceView_default as h, BaseTabs_default as ht, TimeRangeInput_default as i, ThemeToggle_default as it, SampleSelector_default as j, ComponentBindingRenderer_default as k, ScientificNumber_default as l, DataFrame_default as lt, RackEditor_default as m, BaseModal_default as mt, FitPanel_default as n, SettingsModal_default as nt, BatchProgressList_default as o, AppToastContainer_default as ot, GroupAssigner_default as p, SegmentedControl_default as pt, AppPluginSwitcher_default as q, ResourceCard_default as r, CollapsibleCard_default as rt, AuditTrail_default as s, AlertBox_default as st, components_exports as t, ConfirmDialog_default as tt, ProtocolStepEditor_default as u, Calendar_default as ut, BioTemplateRenderer_default as v, StatusIndicator_default as w, Breadcrumb_default as x, ChartContainer_default as y, DoseCalculator_default as z };
16594
16614
 
16595
- //# sourceMappingURL=components-DihbSJjU.js.map
16615
+ //# sourceMappingURL=components-5KSfsVqf.js.map