react-os-shell 0.2.68 → 0.3.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 (69) hide show
  1. package/README.md +35 -15
  2. package/dist/{Browser-UGZQMWKW.js → Browser-H5KDP5OH.js} +3 -3
  3. package/dist/{Browser-UGZQMWKW.js.map → Browser-H5KDP5OH.js.map} +1 -1
  4. package/dist/{Calculator-3ZXNXWDH.js → Calculator-QQ7NF53Q.js} +4 -4
  5. package/dist/{Calculator-3ZXNXWDH.js.map → Calculator-QQ7NF53Q.js.map} +1 -1
  6. package/dist/{Calendar-ON4AQ54T.js → Calendar-J6L7FGHS.js} +175 -108
  7. package/dist/Calendar-J6L7FGHS.js.map +1 -0
  8. package/dist/{CurrencyConverter-ACTLK72N.js → CurrencyConverter-YHOGBUPH.js} +4 -4
  9. package/dist/{CurrencyConverter-ACTLK72N.js.map → CurrencyConverter-YHOGBUPH.js.map} +1 -1
  10. package/dist/{Documents-STDXQ7I4.js → Documents-6DYALASM.js} +3 -3
  11. package/dist/{Documents-STDXQ7I4.js.map → Documents-6DYALASM.js.map} +1 -1
  12. package/dist/Email-U2U5Z4DL.js +475 -0
  13. package/dist/Email-U2U5Z4DL.js.map +1 -0
  14. package/dist/Files-T62M4V5I.js +11 -0
  15. package/dist/{Files-ASKLEUNU.js.map → Files-T62M4V5I.js.map} +1 -1
  16. package/dist/{Minesweeper-CZNIO75H.js → Minesweeper-S2JHXYLX.js} +3 -3
  17. package/dist/{Minesweeper-CZNIO75H.js.map → Minesweeper-S2JHXYLX.js.map} +1 -1
  18. package/dist/{Notepad-ZYYH4ZXN.js → Notepad-2YF7X3XO.js} +3 -3
  19. package/dist/{Notepad-ZYYH4ZXN.js.map → Notepad-2YF7X3XO.js.map} +1 -1
  20. package/dist/{PomodoroTimer-2MNIEAUM.js → PomodoroTimer-3J7Z3NVQ.js} +4 -4
  21. package/dist/{PomodoroTimer-2MNIEAUM.js.map → PomodoroTimer-3J7Z3NVQ.js.map} +1 -1
  22. package/dist/Preview-WM6ZP5PZ.js +8 -0
  23. package/dist/{Preview-U72UL74H.js.map → Preview-WM6ZP5PZ.js.map} +1 -1
  24. package/dist/Spreadsheet-ZIE2SXAF.js +6 -0
  25. package/dist/{Spreadsheet-T7Y7PRD6.js.map → Spreadsheet-ZIE2SXAF.js.map} +1 -1
  26. package/dist/{TodoList-7JZ2SLDI.js → TodoList-QGXCDEIE.js} +18 -204
  27. package/dist/TodoList-QGXCDEIE.js.map +1 -0
  28. package/dist/{Weather-DYCTCB6T.js → Weather-2GFPSZ5V.js} +4 -4
  29. package/dist/{Weather-DYCTCB6T.js.map → Weather-2GFPSZ5V.js.map} +1 -1
  30. package/dist/{WorldClock-XL4OMFOY.js → WorldClock-P4JR5I6X.js} +4 -4
  31. package/dist/{WorldClock-XL4OMFOY.js.map → WorldClock-P4JR5I6X.js.map} +1 -1
  32. package/dist/apps/index.d.ts +2 -5
  33. package/dist/apps/index.js +23 -26
  34. package/dist/apps/index.js.map +1 -1
  35. package/dist/chunk-57B3WALN.js +114 -0
  36. package/dist/chunk-57B3WALN.js.map +1 -0
  37. package/dist/{chunk-4SHZ7BZO.js → chunk-62FC2FHC.js} +92 -21
  38. package/dist/chunk-62FC2FHC.js.map +1 -0
  39. package/dist/{chunk-FXAOT23O.js → chunk-ATQVRDDQ.js} +3 -3
  40. package/dist/{chunk-FXAOT23O.js.map → chunk-ATQVRDDQ.js.map} +1 -1
  41. package/dist/{chunk-GP4Y3VCB.js → chunk-KMGWSDEI.js} +480 -4
  42. package/dist/chunk-KMGWSDEI.js.map +1 -0
  43. package/dist/{chunk-SU6XVJND.js → chunk-O6FJZAFM.js} +3 -3
  44. package/dist/{chunk-SU6XVJND.js.map → chunk-O6FJZAFM.js.map} +1 -1
  45. package/dist/{chunk-YL47AVBA.js → chunk-SEV7UXGN.js} +4 -4
  46. package/dist/{chunk-YL47AVBA.js.map → chunk-SEV7UXGN.js.map} +1 -1
  47. package/dist/{chunk-L2AFKNSQ.js → chunk-ZBRFMK3E.js} +4 -4
  48. package/dist/{chunk-L2AFKNSQ.js.map → chunk-ZBRFMK3E.js.map} +1 -1
  49. package/dist/index.d.ts +55 -1
  50. package/dist/index.js +241 -135
  51. package/dist/index.js.map +1 -1
  52. package/package.json +12 -6
  53. package/dist/Calendar-ON4AQ54T.js.map +0 -1
  54. package/dist/Email-5WL3TWC6.js +0 -1883
  55. package/dist/Email-5WL3TWC6.js.map +0 -1
  56. package/dist/Files-ASKLEUNU.js +0 -12
  57. package/dist/GeminiChat-XTEBZIVK.js +0 -184
  58. package/dist/GeminiChat-XTEBZIVK.js.map +0 -1
  59. package/dist/Preview-U72UL74H.js +0 -8
  60. package/dist/Spreadsheet-T7Y7PRD6.js +0 -7
  61. package/dist/TodoList-7JZ2SLDI.js.map +0 -1
  62. package/dist/chunk-4SHZ7BZO.js.map +0 -1
  63. package/dist/chunk-5VXRBUEH.js +0 -104
  64. package/dist/chunk-5VXRBUEH.js.map +0 -1
  65. package/dist/chunk-GP4Y3VCB.js.map +0 -1
  66. package/dist/chunk-MUXDKEOC.js +0 -485
  67. package/dist/chunk-MUXDKEOC.js.map +0 -1
  68. package/dist/chunk-MVWEL34Y.js +0 -209
  69. package/dist/chunk-MVWEL34Y.js.map +0 -1
@@ -0,0 +1,114 @@
1
+ import axios from 'axios';
2
+ import { useState, useEffect, useCallback } from 'react';
3
+
4
+ // src/api/mailClient.ts
5
+ var DEFAULT_BASE_URL = "http://localhost:3001";
6
+ var _client = null;
7
+ var _baseUrl = DEFAULT_BASE_URL;
8
+ function setShellMailServer(input) {
9
+ if (typeof input === "string") {
10
+ _baseUrl = input;
11
+ _client = axios.create({ baseURL: input, withCredentials: true, timeout: 6e4 });
12
+ } else {
13
+ _client = input;
14
+ }
15
+ }
16
+ function getMailClient() {
17
+ if (!_client) {
18
+ _client = axios.create({ baseURL: _baseUrl, withCredentials: true, timeout: 6e4 });
19
+ }
20
+ return _client;
21
+ }
22
+ var SESSION_FLAG = "mail_session_known";
23
+ var listeners = /* @__PURE__ */ new Set();
24
+ var cached = {
25
+ user: null,
26
+ capabilities: null,
27
+ checked: false,
28
+ serverReachable: null
29
+ };
30
+ function broadcast() {
31
+ listeners.forEach((fn) => fn());
32
+ }
33
+ async function fetchMe() {
34
+ const client = getMailClient();
35
+ try {
36
+ const res = await client.get("/api/auth/me");
37
+ cached = { user: res.data.user, capabilities: res.data.capabilities, checked: true, serverReachable: true };
38
+ } catch (err) {
39
+ const status = err?.response?.status;
40
+ if (status === 401) {
41
+ localStorage.removeItem(SESSION_FLAG);
42
+ cached = { user: null, capabilities: null, checked: true, serverReachable: true };
43
+ } else {
44
+ cached = { user: null, capabilities: null, checked: true, serverReachable: false };
45
+ }
46
+ }
47
+ broadcast();
48
+ }
49
+ function useMailAuth() {
50
+ const [, force] = useState(0);
51
+ const [loading, setLoading] = useState(false);
52
+ const [error, setError] = useState(null);
53
+ useEffect(() => {
54
+ const sub = () => force((n) => n + 1);
55
+ listeners.add(sub);
56
+ if (!cached.checked && localStorage.getItem(SESSION_FLAG) === "true") {
57
+ fetchMe();
58
+ } else if (!cached.checked) {
59
+ cached.checked = true;
60
+ cached.serverReachable = null;
61
+ broadcast();
62
+ }
63
+ return () => {
64
+ listeners.delete(sub);
65
+ };
66
+ }, []);
67
+ const login = useCallback(async (payload) => {
68
+ setLoading(true);
69
+ setError(null);
70
+ try {
71
+ const client = getMailClient();
72
+ const res = await client.post("/api/auth/login", payload);
73
+ localStorage.setItem(SESSION_FLAG, "true");
74
+ cached = { user: res.data.user, capabilities: res.data.capabilities, checked: true, serverReachable: true };
75
+ broadcast();
76
+ } catch (err) {
77
+ const msg = err?.response?.data?.error || err?.message || "Login failed";
78
+ setError(msg);
79
+ throw err;
80
+ } finally {
81
+ setLoading(false);
82
+ }
83
+ }, []);
84
+ const logout = useCallback(async () => {
85
+ setLoading(true);
86
+ try {
87
+ const client = getMailClient();
88
+ await client.post("/api/auth/logout").catch(() => void 0);
89
+ } finally {
90
+ localStorage.removeItem(SESSION_FLAG);
91
+ cached = { user: null, capabilities: null, checked: true, serverReachable: cached.serverReachable };
92
+ setLoading(false);
93
+ broadcast();
94
+ }
95
+ }, []);
96
+ const refresh = useCallback(async () => {
97
+ await fetchMe();
98
+ }, []);
99
+ return {
100
+ loading,
101
+ serverReachable: cached.serverReachable,
102
+ isConnected: !!cached.user,
103
+ user: cached.user,
104
+ capabilities: cached.capabilities,
105
+ error,
106
+ login,
107
+ logout,
108
+ refresh
109
+ };
110
+ }
111
+
112
+ export { getMailClient, setShellMailServer, useMailAuth };
113
+ //# sourceMappingURL=chunk-57B3WALN.js.map
114
+ //# sourceMappingURL=chunk-57B3WALN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api/mailClient.ts","../src/hooks/useMailAuth.ts"],"names":[],"mappings":"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","file":"chunk-57B3WALN.js","sourcesContent":["import axios, { type AxiosInstance } from 'axios';\n\nconst DEFAULT_BASE_URL = 'http://localhost:3001';\nlet _client: AxiosInstance | null = null;\nlet _baseUrl: string = DEFAULT_BASE_URL;\n\nexport function setShellMailServer(input: string | AxiosInstance): void {\n if (typeof input === 'string') {\n _baseUrl = input;\n _client = axios.create({ baseURL: input, withCredentials: true, timeout: 60_000 });\n } else {\n _client = input;\n }\n}\n\nexport function getMailClient(): AxiosInstance {\n if (!_client) {\n _client = axios.create({ baseURL: _baseUrl, withCredentials: true, timeout: 60_000 });\n }\n return _client;\n}\n\nexport function getMailServerBaseUrl(): string {\n return _baseUrl;\n}\n","import { useCallback, useEffect, useState } from 'react';\nimport { getMailClient } from '../api/mailClient';\n\nconst SESSION_FLAG = 'mail_session_known';\n\nexport interface MailUser {\n email: string;\n displayName: string;\n}\n\nexport interface MailCapabilities {\n imap: { thread: boolean; condstore: boolean; idle: boolean };\n smtp: boolean;\n caldav: boolean;\n}\n\nexport interface LoginPayload {\n imap: { host: string; port: number; secure: boolean; user: string; pass: string };\n smtp: { host: string; port: number; secure: boolean; user: string; pass: string };\n caldav?: { serverUrl: string; user: string; pass: string };\n}\n\ninterface MailAuthState {\n loading: boolean;\n serverReachable: boolean | null;\n isConnected: boolean;\n user: MailUser | null;\n capabilities: MailCapabilities | null;\n error: string | null;\n login: (payload: LoginPayload) => Promise<void>;\n logout: () => Promise<void>;\n refresh: () => Promise<void>;\n}\n\nconst listeners = new Set<() => void>();\nlet cached: { user: MailUser | null; capabilities: MailCapabilities | null; checked: boolean; serverReachable: boolean | null } = {\n user: null,\n capabilities: null,\n checked: false,\n serverReachable: null,\n};\n\nfunction broadcast(): void {\n listeners.forEach(fn => fn());\n}\n\nasync function fetchMe(): Promise<void> {\n const client = getMailClient();\n try {\n const res = await client.get('/api/auth/me');\n cached = { user: res.data.user, capabilities: res.data.capabilities, checked: true, serverReachable: true };\n } catch (err) {\n const status = (err as { response?: { status?: number } })?.response?.status;\n if (status === 401) {\n localStorage.removeItem(SESSION_FLAG);\n cached = { user: null, capabilities: null, checked: true, serverReachable: true };\n } else {\n cached = { user: null, capabilities: null, checked: true, serverReachable: false };\n }\n }\n broadcast();\n}\n\nexport default function useMailAuth(): MailAuthState {\n const [, force] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const sub = () => force(n => n + 1);\n listeners.add(sub);\n if (!cached.checked && localStorage.getItem(SESSION_FLAG) === 'true') {\n fetchMe();\n } else if (!cached.checked) {\n cached.checked = true;\n cached.serverReachable = null;\n broadcast();\n }\n return () => {\n listeners.delete(sub);\n };\n }, []);\n\n const login = useCallback(async (payload: LoginPayload) => {\n setLoading(true);\n setError(null);\n try {\n const client = getMailClient();\n const res = await client.post('/api/auth/login', payload);\n localStorage.setItem(SESSION_FLAG, 'true');\n cached = { user: res.data.user, capabilities: res.data.capabilities, checked: true, serverReachable: true };\n broadcast();\n } catch (err) {\n const msg = (err as { response?: { data?: { error?: string } }; message?: string })?.response?.data?.error\n || (err as { message?: string })?.message\n || 'Login failed';\n setError(msg);\n throw err;\n } finally {\n setLoading(false);\n }\n }, []);\n\n const logout = useCallback(async () => {\n setLoading(true);\n try {\n const client = getMailClient();\n await client.post('/api/auth/logout').catch(() => undefined);\n } finally {\n localStorage.removeItem(SESSION_FLAG);\n cached = { user: null, capabilities: null, checked: true, serverReachable: cached.serverReachable };\n setLoading(false);\n broadcast();\n }\n }, []);\n\n const refresh = useCallback(async () => {\n await fetchMe();\n }, []);\n\n return {\n loading,\n serverReachable: cached.serverReachable,\n isConnected: !!cached.user,\n user: cached.user,\n capabilities: cached.capabilities,\n error,\n login,\n logout,\n refresh,\n };\n}\n"]}
@@ -371,6 +371,24 @@ function _savePositionsDebounced() {
371
371
  }
372
372
  }, 500);
373
373
  }
374
+ var AO_KEY = "erp_activation_order";
375
+ var _activationOrderKeys = [];
376
+ try {
377
+ const stored = localStorage.getItem(AO_KEY);
378
+ const parsed = stored ? JSON.parse(stored) : null;
379
+ if (Array.isArray(parsed) && parsed.every((k) => typeof k === "string")) _activationOrderKeys = parsed;
380
+ } catch {
381
+ }
382
+ var _saveOrderTimer = null;
383
+ function _saveOrderDebounced() {
384
+ if (_saveOrderTimer) clearTimeout(_saveOrderTimer);
385
+ _saveOrderTimer = setTimeout(() => {
386
+ try {
387
+ localStorage.setItem(AO_KEY, JSON.stringify(_activationOrderKeys));
388
+ } catch {
389
+ }
390
+ }, 500);
391
+ }
374
392
  function setWindowDefaultPosition(key, pos) {
375
393
  if (_windowPositions[key]) return;
376
394
  _windowPositions[key] = pos;
@@ -385,10 +403,66 @@ var sizeDefaults = {
385
403
  };
386
404
  var activationOrder = [];
387
405
  var activeListeners = /* @__PURE__ */ new Set();
406
+ var _modalIdByKey = /* @__PURE__ */ new Map();
407
+ var _keyByModalId = /* @__PURE__ */ new Map();
408
+ function _insertModalIdForKey(modalId, key) {
409
+ const savedIdx = _activationOrderKeys.indexOf(key);
410
+ if (savedIdx === -1) {
411
+ activationOrder.push(modalId);
412
+ return;
413
+ }
414
+ let insertAt = activationOrder.length;
415
+ for (let i = 0; i < activationOrder.length; i++) {
416
+ const otherKey = _keyByModalId.get(activationOrder[i]);
417
+ if (!otherKey) continue;
418
+ const otherIdx = _activationOrderKeys.indexOf(otherKey);
419
+ if (otherIdx > savedIdx) {
420
+ insertAt = i;
421
+ break;
422
+ }
423
+ }
424
+ activationOrder.splice(insertAt, 0, modalId);
425
+ }
426
+ function mountModal(modalId, key) {
427
+ if (!key) {
428
+ activationOrder.push(modalId);
429
+ } else {
430
+ _modalIdByKey.set(key, modalId);
431
+ _keyByModalId.set(modalId, key);
432
+ _insertModalIdForKey(modalId, key);
433
+ if (_activationOrderKeys.indexOf(key) === -1) {
434
+ _activationOrderKeys.push(key);
435
+ _saveOrderDebounced();
436
+ }
437
+ }
438
+ activeListeners.forEach((fn) => fn());
439
+ window.dispatchEvent(new CustomEvent("modal-reorder"));
440
+ }
388
441
  function activateModal(id) {
389
442
  const idx = activationOrder.indexOf(id);
390
443
  if (idx !== -1) activationOrder.splice(idx, 1);
391
444
  activationOrder.push(id);
445
+ const key = _keyByModalId.get(id);
446
+ if (key) {
447
+ const kidx = _activationOrderKeys.indexOf(key);
448
+ if (kidx !== -1) _activationOrderKeys.splice(kidx, 1);
449
+ _activationOrderKeys.push(key);
450
+ _saveOrderDebounced();
451
+ }
452
+ activeListeners.forEach((fn) => fn());
453
+ window.dispatchEvent(new CustomEvent("modal-reorder"));
454
+ }
455
+ function _minimizeModal(modalId) {
456
+ const idx = activationOrder.indexOf(modalId);
457
+ if (idx !== -1) activationOrder.splice(idx, 1);
458
+ const key = _keyByModalId.get(modalId);
459
+ if (key) {
460
+ const kidx = _activationOrderKeys.indexOf(key);
461
+ if (kidx !== -1) {
462
+ _activationOrderKeys.splice(kidx, 1);
463
+ _saveOrderDebounced();
464
+ }
465
+ }
392
466
  activeListeners.forEach((fn) => fn());
393
467
  window.dispatchEvent(new CustomEvent("modal-reorder"));
394
468
  }
@@ -397,6 +471,11 @@ function deactivateAllModals() {
397
471
  for (let i = activationOrder.length - 1; i >= 0; i--) {
398
472
  if (!widgetIds.has(activationOrder[i])) activationOrder.splice(i, 1);
399
473
  }
474
+ _activationOrderKeys = _activationOrderKeys.filter((k) => {
475
+ const mid = _modalIdByKey.get(k);
476
+ return mid != null && widgetIds.has(mid);
477
+ });
478
+ _saveOrderDebounced();
400
479
  activeListeners.forEach((fn) => fn());
401
480
  window.dispatchEvent(new CustomEvent("modal-reorder"));
402
481
  }
@@ -875,9 +954,10 @@ function Modal({ open, onClose, title, icon, copyText, size = "lg", dirty = fals
875
954
  }, [size]);
876
955
  const interceptedRef = useRef(false);
877
956
  if (!open) interceptedRef.current = false;
957
+ const boxKey = windowKey || copyText || null;
878
958
  useEffect(() => {
879
959
  if (!open) return;
880
- activateModal(modalId);
960
+ mountModal(modalId, boxKey);
881
961
  isNested.current = false;
882
962
  setZIndex(getZForModal(modalId));
883
963
  const onReorder = () => {
@@ -923,14 +1003,18 @@ function Modal({ open, onClose, title, icon, copyText, size = "lg", dirty = fals
923
1003
  activationOrder.splice(aidx, 1);
924
1004
  activeListeners.forEach((fn) => fn());
925
1005
  }
1006
+ const cleanupKey = _keyByModalId.get(modalId);
1007
+ if (cleanupKey) {
1008
+ _keyByModalId.delete(modalId);
1009
+ _modalIdByKey.delete(cleanupKey);
1010
+ }
926
1011
  window.removeEventListener("modal-reorder", onReorder);
927
1012
  window.removeEventListener("modal-split-view", onSplitView);
928
1013
  window.removeEventListener("modal-center", onCenter);
929
1014
  window.removeEventListener("modal-context-menu", onCtxMenu);
930
1015
  window.dispatchEvent(new CustomEvent("modal-reorder"));
931
1016
  };
932
- }, [open, modalId, calcMaximized]);
933
- const boxKey = windowKey || copyText || null;
1017
+ }, [open, modalId, boxKey, calcMaximized]);
934
1018
  const [box, setBox] = useState(() => {
935
1019
  if (boxKey && _windowPositions[boxKey]) {
936
1020
  const saved = { ..._windowPositions[boxKey] };
@@ -1416,12 +1500,7 @@ function Modal({ open, onClose, title, icon, copyText, size = "lg", dirty = fals
1416
1500
  children: /* @__PURE__ */ jsx("svg", { className: "h-3 w-3", fill: pinnedOnTop ? "currentColor" : "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M16.5 3.75V16.5L12 14.25 7.5 16.5V3.75m9 0H18A2.25 2.25 0 0120.25 6v12A2.25 2.25 0 0118 20.25H6A2.25 2.25 0 013.75 18V6A2.25 2.25 0 016 3.75h1.5m9 0h-9" }) })
1417
1501
  }
1418
1502
  ),
1419
- /* @__PURE__ */ jsx("button", { onClick: () => {
1420
- const idx = activationOrder.indexOf(modalId);
1421
- if (idx !== -1) activationOrder.splice(idx, 1);
1422
- activeListeners.forEach((fn) => fn());
1423
- window.dispatchEvent(new CustomEvent("modal-reorder"));
1424
- }, title: "Minimize", className: "text-gray-400 hover:text-gray-600 px-1 py-0.5 rounded hover:bg-gray-200 text-xs leading-none", children: "\u2500" }),
1503
+ /* @__PURE__ */ jsx("button", { onClick: () => _minimizeModal(modalId), title: "Minimize", className: "text-gray-400 hover:text-gray-600 px-1 py-0.5 rounded hover:bg-gray-200 text-xs leading-none", children: "\u2500" }),
1425
1504
  !alwaysMaximized && /* @__PURE__ */ jsx("button", { onClick: () => {
1426
1505
  if (maximized) {
1427
1506
  setMaximized(false);
@@ -1462,12 +1541,7 @@ function Modal({ open, onClose, title, icon, copyText, size = "lg", dirty = fals
1462
1541
  children: /* @__PURE__ */ jsx("svg", { className: "h-3.5 w-3.5", fill: pinnedOnTop ? "currentColor" : "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M16.5 3.75V16.5L12 14.25 7.5 16.5V3.75m9 0H18A2.25 2.25 0 0120.25 6v12A2.25 2.25 0 0118 20.25H6A2.25 2.25 0 013.75 18V6A2.25 2.25 0 016 3.75h1.5m9 0h-9" }) })
1463
1542
  }
1464
1543
  ),
1465
- /* @__PURE__ */ jsx("button", { onClick: () => {
1466
- const idx = activationOrder.indexOf(modalId);
1467
- if (idx !== -1) activationOrder.splice(idx, 1);
1468
- activeListeners.forEach((fn) => fn());
1469
- window.dispatchEvent(new CustomEvent("modal-reorder"));
1470
- }, title: "Minimize", className: "text-gray-400 hover:text-gray-600 text-xs px-2 py-1 rounded hover:bg-gray-200", children: "\u2500" }),
1544
+ /* @__PURE__ */ jsx("button", { onClick: () => _minimizeModal(modalId), title: "Minimize", className: "text-gray-400 hover:text-gray-600 text-xs px-2 py-1 rounded hover:bg-gray-200", children: "\u2500" }),
1471
1545
  !alwaysMaximized && /* @__PURE__ */ jsx("button", { onClick: () => {
1472
1546
  if (maximized) {
1473
1547
  setMaximized(false);
@@ -1589,10 +1663,7 @@ function Modal({ open, onClose, title, icon, copyText, size = "lg", dirty = fals
1589
1663
  const windowMenuEl = windowMenu && /* @__PURE__ */ jsxs(PopupMenu, { style: { left: windowMenu.x, top: windowMenu.y }, onClose: () => setWindowMenu(null), minWidth: 160, children: [
1590
1664
  !widget && !compact && /* @__PURE__ */ jsxs(Fragment, { children: [
1591
1665
  /* @__PURE__ */ jsxs(PopupMenuItem, { onClick: () => {
1592
- const idx = activationOrder.indexOf(modalId);
1593
- if (idx !== -1) activationOrder.splice(idx, 1);
1594
- activeListeners.forEach((fn) => fn());
1595
- window.dispatchEvent(new CustomEvent("modal-reorder"));
1666
+ _minimizeModal(modalId);
1596
1667
  setWindowMenu(null);
1597
1668
  }, children: [
1598
1669
  /* @__PURE__ */ jsx("svg", { className: "h-4 w-4 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 1.5, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M19.5 12h-15" }) }),
@@ -2273,5 +2344,5 @@ function WindowManagerProvider({ children }) {
2273
2344
  }
2274
2345
 
2275
2346
  export { CancelButton, CopyButton, DocFavStar, LoadingSpinner, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, ThumbCard, WINDOW_REGISTRY, WindowManagerProvider, WindowTitle, activateModal, client_default, commitExposeHighlight, exitExposeMode, getActiveModalId, getActiveWindowRoute, getExposeHighlight, isEntityEntry, isPageEntry, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, subscribeExposeHighlight, toggleExposeMode, useIsMobile, useModalActive, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle };
2276
- //# sourceMappingURL=chunk-4SHZ7BZO.js.map
2277
- //# sourceMappingURL=chunk-4SHZ7BZO.js.map
2347
+ //# sourceMappingURL=chunk-62FC2FHC.js.map
2348
+ //# sourceMappingURL=chunk-62FC2FHC.js.map