react-os-shell 4.79.3 → 4.82.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 (68) hide show
  1. package/README.md +18 -0
  2. package/dist/{Browser-2DFSZ3RP.js → Browser-5FNVWP3Q.js} +7 -7
  3. package/dist/{Browser-2DFSZ3RP.js.map → Browser-5FNVWP3Q.js.map} +1 -1
  4. package/dist/{Calculator-PAPSDNSJ.js → Calculator-2FCNKTPN.js} +6 -6
  5. package/dist/{Calculator-PAPSDNSJ.js.map → Calculator-2FCNKTPN.js.map} +1 -1
  6. package/dist/{CurrencyConverter-VJQI2XVV.js → CurrencyConverter-KZU7MTWE.js} +6 -6
  7. package/dist/{CurrencyConverter-VJQI2XVV.js.map → CurrencyConverter-KZU7MTWE.js.map} +1 -1
  8. package/dist/{Documents-GIP67CHC.js → Documents-ZTK6SSDK.js} +7 -7
  9. package/dist/{Documents-GIP67CHC.js.map → Documents-ZTK6SSDK.js.map} +1 -1
  10. package/dist/{Files-JAE2LL65.js → Files-4PNE3MBV.js} +12 -12
  11. package/dist/{Files-JAE2LL65.js.map → Files-4PNE3MBV.js.map} +1 -1
  12. package/dist/{Notepad-SXHXJ6PC.js → Notepad-63JJ2WB5.js} +7 -7
  13. package/dist/{Notepad-SXHXJ6PC.js.map → Notepad-63JJ2WB5.js.map} +1 -1
  14. package/dist/{PomodoroTimer-GFL4L3XS.js → PomodoroTimer-SL372V3I.js} +7 -7
  15. package/dist/{PomodoroTimer-GFL4L3XS.js.map → PomodoroTimer-SL372V3I.js.map} +1 -1
  16. package/dist/{Preview-5HFE6MCG.js → Preview-QZL2BXLP.js} +9 -9
  17. package/dist/Preview-QZL2BXLP.js.map +1 -0
  18. package/dist/{Sidebar-B3LY5T2U.js → Sidebar-GFDPPC4X.js} +24 -6
  19. package/dist/Sidebar-GFDPPC4X.js.map +1 -0
  20. package/dist/{Spreadsheet-KZLORYAA.js → Spreadsheet-RCKDHL66.js} +8 -8
  21. package/dist/{Spreadsheet-KZLORYAA.js.map → Spreadsheet-RCKDHL66.js.map} +1 -1
  22. package/dist/{Stock-WZXVQX3G.js → Stock-YDCHLKSV.js} +6 -6
  23. package/dist/{Stock-WZXVQX3G.js.map → Stock-YDCHLKSV.js.map} +1 -1
  24. package/dist/{Weather-FQ7ZVXVR.js → Weather-HM3Y5LMI.js} +6 -6
  25. package/dist/{Weather-FQ7ZVXVR.js.map → Weather-HM3Y5LMI.js.map} +1 -1
  26. package/dist/{WorldClock-XAFQ5ZQF.js → WorldClock-RXKMY3YJ.js} +6 -6
  27. package/dist/{WorldClock-XAFQ5ZQF.js.map → WorldClock-RXKMY3YJ.js.map} +1 -1
  28. package/dist/apps/index.js +19 -19
  29. package/dist/{chunk-GO2LCDHS.js → chunk-26S2Q6GA.js} +3 -3
  30. package/dist/{chunk-GO2LCDHS.js.map → chunk-26S2Q6GA.js.map} +1 -1
  31. package/dist/{chunk-EWDYCO65.js → chunk-35RG2LD2.js} +3 -3
  32. package/dist/{chunk-EWDYCO65.js.map → chunk-35RG2LD2.js.map} +1 -1
  33. package/dist/{chunk-ZO4XGUZQ.js → chunk-3TSIRZUW.js} +3 -3
  34. package/dist/{chunk-ZO4XGUZQ.js.map → chunk-3TSIRZUW.js.map} +1 -1
  35. package/dist/{chunk-BLLINYDD.js → chunk-5TLIIDRZ.js} +186 -5
  36. package/dist/chunk-5TLIIDRZ.js.map +1 -0
  37. package/dist/chunk-6XQHH7D2.js +105 -0
  38. package/dist/chunk-6XQHH7D2.js.map +1 -0
  39. package/dist/{chunk-OQ7GRU7G.js → chunk-7RUYFI6O.js} +3 -3
  40. package/dist/{chunk-OQ7GRU7G.js.map → chunk-7RUYFI6O.js.map} +1 -1
  41. package/dist/{chunk-A42MTWLI.js → chunk-F54RMKRL.js} +5 -5
  42. package/dist/{chunk-A42MTWLI.js.map → chunk-F54RMKRL.js.map} +1 -1
  43. package/dist/{chunk-TT2WNTDS.js → chunk-IZ2FABWU.js} +3 -3
  44. package/dist/{chunk-TT2WNTDS.js.map → chunk-IZ2FABWU.js.map} +1 -1
  45. package/dist/chunk-KLSUJ46L.js +7 -0
  46. package/dist/{chunk-M2IJT4OA.js.map → chunk-KLSUJ46L.js.map} +1 -1
  47. package/dist/{chunk-YZVJCHXV.js → chunk-LEMEFL6U.js} +300 -194
  48. package/dist/chunk-LEMEFL6U.js.map +1 -0
  49. package/dist/{chunk-EXSEW5F3.js → chunk-MHUVU7ZX.js} +102 -16
  50. package/dist/chunk-MHUVU7ZX.js.map +1 -0
  51. package/dist/{chunk-QJS6RBH4.js → chunk-XWLEA4B7.js} +3 -3
  52. package/dist/{chunk-QJS6RBH4.js.map → chunk-XWLEA4B7.js.map} +1 -1
  53. package/dist/{chunk-WNLPTLT6.js → chunk-ZESNO4TZ.js} +2 -2
  54. package/dist/chunk-ZESNO4TZ.js.map +1 -0
  55. package/dist/{index-BjEcKEsJ.d.ts → index-D9ZuIsBe.d.ts} +130 -1
  56. package/dist/index.d.ts +53 -3
  57. package/dist/index.js +157 -56
  58. package/dist/index.js.map +1 -1
  59. package/dist/ui/index.d.ts +1 -1
  60. package/dist/ui/index.js +4 -3
  61. package/package.json +1 -1
  62. package/dist/Preview-5HFE6MCG.js.map +0 -1
  63. package/dist/Sidebar-B3LY5T2U.js.map +0 -1
  64. package/dist/chunk-BLLINYDD.js.map +0 -1
  65. package/dist/chunk-EXSEW5F3.js.map +0 -1
  66. package/dist/chunk-M2IJT4OA.js +0 -7
  67. package/dist/chunk-WNLPTLT6.js.map +0 -1
  68. package/dist/chunk-YZVJCHXV.js.map +0 -1
@@ -1,6 +1,6 @@
1
- import { useShellStrings, useIsMobile, useShellPrefs, PopupMenu, PopupMenuItem, PopupMenuDivider } from './chunk-BLLINYDD.js';
1
+ import { LoadingSpinner, Result, Button_default, useShellStrings, useIsMobile, useShellPrefs, PopupMenu, PopupMenuItem, PopupMenuDivider } from './chunk-5TLIIDRZ.js';
2
2
  import { confirm, runEscapeInterceptors } from './chunk-CDR2Q64Q.js';
3
- import { useShellAuth, navIcons } from './chunk-WNLPTLT6.js';
3
+ import { useShellAuth, navIcons } from './chunk-ZESNO4TZ.js';
4
4
  import { createContext, Component, useContext, useRef, useLayoutEffect, useState, useEffect, useCallback, useSyncExternalStore, useMemo, isValidElement, cloneElement, useReducer, useId, Suspense } from 'react';
5
5
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
6
6
  import { createPortal } from 'react-dom';
@@ -110,9 +110,13 @@ var RETRYABLE_CLIENT_STATUSES = /* @__PURE__ */ new Set([
110
110
  ]);
111
111
  var ENTITY_FETCH_MAX_RETRIES = 3;
112
112
  var ENTITY_REFETCH_INTERVAL_MS = 6e4;
113
- function isPermanentClientError(error) {
113
+ function entityFetchStatus(error) {
114
114
  const status = error?.response?.status;
115
- if (typeof status !== "number") return false;
115
+ return typeof status === "number" ? status : void 0;
116
+ }
117
+ function isPermanentClientError(error) {
118
+ const status = entityFetchStatus(error);
119
+ if (status == null) return false;
116
120
  return status >= 400 && status < 500 && !RETRYABLE_CLIENT_STATUSES.has(status);
117
121
  }
118
122
  function shouldRetryEntityFetch(failureCount, error) {
@@ -124,9 +128,65 @@ function entityRefetchInterval(error) {
124
128
  function entityDetailUrl(endpoint, entityId) {
125
129
  return `${endpoint}${encodeURIComponent(entityId)}/`;
126
130
  }
127
- function LoadingSpinner() {
131
+ function LoadingSpinner2() {
128
132
  return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center p-8 text-sm text-gray-400", children: "Loading..." });
129
133
  }
134
+ var FILL_CLASS = "flex-1 min-h-0";
135
+ function EntityWindowLoading() {
136
+ return /* @__PURE__ */ jsx(LoadingSpinner, { label: "Loading record\u2026", padding: "", className: FILL_CLASS });
137
+ }
138
+ function normaliseEntitySnapshot(snapshot) {
139
+ return snapshot ?? void 0;
140
+ }
141
+ function EntityWindowFallback({
142
+ isPending,
143
+ isFetching,
144
+ enabled = true,
145
+ error,
146
+ onRetry
147
+ }) {
148
+ if (isFetching || isPending && enabled) return /* @__PURE__ */ jsx(EntityWindowLoading, {});
149
+ if (error) {
150
+ const status = entityFetchStatus(error);
151
+ if (status === 401) {
152
+ return /* @__PURE__ */ jsx(
153
+ Result,
154
+ {
155
+ status: "warning",
156
+ title: "Sign in required",
157
+ subTitle: "Your session may have expired. Sign in again to open this record.",
158
+ className: FILL_CLASS
159
+ }
160
+ );
161
+ }
162
+ if (status === 403) {
163
+ return /* @__PURE__ */ jsx(Result, { status: "403", className: FILL_CLASS });
164
+ }
165
+ if (status === 404 || status === 410) {
166
+ return /* @__PURE__ */ jsx(Result, { status: "404", title: "Record not found", className: FILL_CLASS });
167
+ }
168
+ const canRetry = status == null || status === 408 || status === 429 || status >= 500;
169
+ return /* @__PURE__ */ jsx(
170
+ Result,
171
+ {
172
+ status: "500",
173
+ title: "Couldn't load record",
174
+ subTitle: canRetry ? "Check your connection and try again." : "The server rejected this request.",
175
+ extra: canRetry ? /* @__PURE__ */ jsx(Button_default, { variant: "secondary", size: "sm", onClick: onRetry, children: "Try again" }) : void 0,
176
+ className: FILL_CLASS
177
+ }
178
+ );
179
+ }
180
+ return /* @__PURE__ */ jsx(Result, { status: "404", title: "Record not found", className: FILL_CLASS });
181
+ }
182
+ function EntityWindowState({
183
+ entity,
184
+ children,
185
+ ...fallback
186
+ }) {
187
+ if (entity != null) return /* @__PURE__ */ jsx(Fragment, { children: children(entity) });
188
+ return /* @__PURE__ */ jsx(EntityWindowFallback, { ...fallback });
189
+ }
130
190
  var MinimizedContext = createContext({
131
191
  openWindows: [],
132
192
  openEntity: () => {
@@ -187,7 +247,7 @@ function PageWindow({ item, onClose, accentRgb }) {
187
247
  if (!raw || !isPageEntry(raw)) return null;
188
248
  const entry = raw;
189
249
  const Component2 = entry.component;
190
- return /* @__PURE__ */ jsx(Modal, { open: true, onClose, icon: navIcons[item.route], title: entry.label, size: entry.size || "2xl", dirty, allowPinOnTop: entry.allowPinOnTop, initialPosition: entry.initialPosition, widget: entry.widget, compact: entry.compact, appStyle: entry.appStyle, flushBody: entry.flushBody, autoHeight: entry.autoHeight, autoMinHeight: entry.autoMinHeight, dimensions: entry.dimensions, windowKey: item.id, openedFromKey: item.openedFrom, accentRgb, children: /* @__PURE__ */ jsx(WindowDirtyContext.Provider, { value: registerDirty, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx(LoadingSpinner, {}) }), children: /* @__PURE__ */ jsx(Component2, {}) }) }) });
250
+ return /* @__PURE__ */ jsx(Modal, { open: true, onClose, icon: navIcons[item.route], title: entry.label, size: entry.size || "2xl", dirty, allowPinOnTop: entry.allowPinOnTop, initialPosition: entry.initialPosition, widget: entry.widget, compact: entry.compact, appStyle: entry.appStyle, flushBody: entry.flushBody, autoHeight: entry.autoHeight, autoMinHeight: entry.autoMinHeight, dimensions: entry.dimensions, windowKey: item.id, openedFromKey: item.openedFrom, accentRgb, children: /* @__PURE__ */ jsx(WindowDirtyContext.Provider, { value: registerDirty, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx(LoadingSpinner2, {}) }), children: /* @__PURE__ */ jsx(Component2, {}) }) }) });
191
251
  }
192
252
  function DocFavStar({ entityType, entityId, label }) {
193
253
  const shellStrings = useShellStrings();
@@ -220,13 +280,14 @@ function RestoredRegistryModal({ item, onClose, onMinimize, accentRgb }) {
220
280
  const qkPrefix = entry.queryKey || entry.endpoint.replace(/^\/|\/$/g, "").split("/").pop() || item.entityType;
221
281
  const isDuplicate = item.entitySnapshot?._duplicate;
222
282
  const isDraft = typeof item.entityId === "string" && item.entityId.startsWith("new-");
223
- const { data: entity, isLoading, refetch } = useQuery({
283
+ const fetchesDetail = !entry.selfFetching && !isDuplicate && !isDraft && isShellApiClientConfigured();
284
+ const entityQuery = useQuery({
224
285
  queryKey: [qkPrefix, item.entityId],
225
286
  queryFn: () => client_default.get(entityDetailUrl(entry.endpoint, String(item.entityId))).then((r) => r.data),
226
- initialData: item.entitySnapshot,
287
+ initialData: normaliseEntitySnapshot(item.entitySnapshot),
227
288
  initialDataUpdatedAt: 0,
228
289
  // Treat snapshot as stale so query refetches immediately
229
- enabled: !entry.selfFetching && !isDuplicate && !isDraft && isShellApiClientConfigured(),
290
+ enabled: fetchesDetail,
230
291
  staleTime: 0,
231
292
  refetchOnWindowFocus: true,
232
293
  refetchOnMount: "always",
@@ -237,6 +298,8 @@ function RestoredRegistryModal({ item, onClose, onMinimize, accentRgb }) {
237
298
  refetchIntervalInBackground: false,
238
299
  retry: shouldRetryEntityFetch
239
300
  });
301
+ const entity = entityQuery.data;
302
+ const refetch = entityQuery.refetch;
240
303
  useEffect(() => {
241
304
  if (entry.selfFetching || isDuplicate || isDraft) return;
242
305
  const handler = () => {
@@ -259,9 +322,21 @@ function RestoredRegistryModal({ item, onClose, onMinimize, accentRgb }) {
259
322
  const footerContent = !entry.selfFetching && entity && entry.footer && !isDuplicate ? entry.footer(entity) : void 0;
260
323
  if (entry.rendersOwnModal) {
261
324
  if (entry.selfFetching) {
262
- return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingSpinner, {}), children: entry.render(entity ?? item.entitySnapshot, onClose, item.entityId, editing, setEditing) });
325
+ return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingSpinner2, {}), children: entry.render(entity ?? item.entitySnapshot, onClose, item.entityId, editing, setEditing) });
263
326
  }
264
- return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingSpinner, {}), children: isLoading && !entity ? /* @__PURE__ */ jsx(LoadingSpinner, {}) : entity ? entry.render(entity, onClose, item.entityId, editing, setEditing) : /* @__PURE__ */ jsx(Modal, { open: true, onClose, title: item.label, size: entry.size || "2xl", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 py-8 text-center", children: "Not found." }) }) });
327
+ if (entity != null) {
328
+ return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(Modal, { open: true, onClose, title: item.label, size: entry.size || "2xl", children: /* @__PURE__ */ jsx(EntityWindowLoading, {}) }), children: entry.render(entity, onClose, item.entityId, editing, setEditing) });
329
+ }
330
+ return /* @__PURE__ */ jsx(Modal, { open: true, onClose, title: item.label, size: entry.size || "2xl", children: /* @__PURE__ */ jsx(
331
+ EntityWindowFallback,
332
+ {
333
+ isPending: entityQuery.isPending,
334
+ isFetching: entityQuery.isFetching,
335
+ enabled: fetchesDetail,
336
+ error: entityQuery.error,
337
+ onRetry: refetch
338
+ }
339
+ ) });
265
340
  }
266
341
  return /* @__PURE__ */ jsx(
267
342
  Modal,
@@ -284,7 +359,18 @@ function RestoredRegistryModal({ item, onClose, onMinimize, accentRgb }) {
284
359
  appStyle: entry.appStyle,
285
360
  flushBody: entry.flushBody,
286
361
  accentRgb,
287
- children: /* @__PURE__ */ jsx(WindowDirtyContext.Provider, { value: registerDirty, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingSpinner, {}), children: entry.selfFetching ? entry.render(null, onClose, item.entityId, editing, setEditing) : isLoading && !entity ? /* @__PURE__ */ jsx(LoadingSpinner, {}) : entity ? entry.render(entity, onClose, item.entityId, editing, setEditing) : /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 py-8 text-center", children: "Not found." }) }) })
362
+ children: /* @__PURE__ */ jsx(WindowDirtyContext.Provider, { value: registerDirty, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(EntityWindowLoading, {}), children: entry.selfFetching ? entry.render(null, onClose, item.entityId, editing, setEditing) : /* @__PURE__ */ jsx(
363
+ EntityWindowState,
364
+ {
365
+ entity,
366
+ isPending: entityQuery.isPending,
367
+ isFetching: entityQuery.isFetching,
368
+ enabled: fetchesDetail,
369
+ error: entityQuery.error,
370
+ onRetry: refetch,
371
+ children: (current) => entry.render(current, onClose, item.entityId, editing, setEditing)
372
+ }
373
+ ) }) })
288
374
  }
289
375
  );
290
376
  }
@@ -742,7 +828,7 @@ function WindowManagerProvider({ children, windowAccentForRoute }) {
742
828
  route: route || window.location.pathname,
743
829
  entityType,
744
830
  entityId,
745
- entitySnapshot: snapshot,
831
+ entitySnapshot: normaliseEntitySnapshot(snapshot),
746
832
  openedFrom
747
833
  }];
748
834
  });
@@ -3229,6 +3315,6 @@ function useUndoableState(initial, opts) {
3229
3315
  return [value, setValue];
3230
3316
  }
3231
3317
 
3232
- export { CancelButton, CopyButton, DocFavStar, LoadingSpinner, MODAL_SUBMIT_SELECTOR, Modal, ModalActions, SIDEBAR_STRIP_W, UndoProvider, WINDOW_REGISTRY, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, beginWindowGesture, cancelWindowFront, client_default, commitExposeHighlight, drainPerfEvents, exitExposeMode, forgetMaximizedWindowBoxes, getActiveModalId, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, isShellApiClientConfigured, markMenuOpen, requestWindowFront, setExposeHighlight, setPerfCollecting, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useEnclosingModalId, useIsActiveWindow, useModalActive, useUndo, useUndoable, useUndoableState, useWidgetSettings, useWindowDirty, useWindowManager, useWindowMenuItem, useWindowTitle };
3233
- //# sourceMappingURL=chunk-EXSEW5F3.js.map
3234
- //# sourceMappingURL=chunk-EXSEW5F3.js.map
3318
+ export { CancelButton, CopyButton, DocFavStar, EntityWindowFallback, EntityWindowLoading, EntityWindowState, LoadingSpinner2 as LoadingSpinner, MODAL_SUBMIT_SELECTOR, Modal, ModalActions, SIDEBAR_STRIP_W, UndoProvider, WINDOW_REGISTRY, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, beginWindowGesture, cancelWindowFront, client_default, commitExposeHighlight, drainPerfEvents, exitExposeMode, forgetMaximizedWindowBoxes, getActiveModalId, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, isShellApiClientConfigured, markMenuOpen, requestWindowFront, setExposeHighlight, setPerfCollecting, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useEnclosingModalId, useIsActiveWindow, useModalActive, useUndo, useUndoable, useUndoableState, useWidgetSettings, useWindowDirty, useWindowManager, useWindowMenuItem, useWindowTitle };
3319
+ //# sourceMappingURL=chunk-MHUVU7ZX.js.map
3320
+ //# sourceMappingURL=chunk-MHUVU7ZX.js.map