react-os-shell 3.14.0 → 3.15.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 (54) hide show
  1. package/dist/Browser-MGPP32VZ.js +7 -0
  2. package/dist/{Browser-YLQ2YMKS.js.map → Browser-MGPP32VZ.js.map} +1 -1
  3. package/dist/{Calculator-W6CGJ5J2.js → Calculator-V7OU5TSD.js} +4 -4
  4. package/dist/{Calculator-W6CGJ5J2.js.map → Calculator-V7OU5TSD.js.map} +1 -1
  5. package/dist/{CurrencyConverter-FRZSFWEJ.js → CurrencyConverter-SUSY6HRW.js} +4 -4
  6. package/dist/{CurrencyConverter-FRZSFWEJ.js.map → CurrencyConverter-SUSY6HRW.js.map} +1 -1
  7. package/dist/{Documents-B6SNVML3.js → Documents-GUAZ2I6C.js} +4 -4
  8. package/dist/{Documents-B6SNVML3.js.map → Documents-GUAZ2I6C.js.map} +1 -1
  9. package/dist/Files-4OWK6XKC.js +12 -0
  10. package/dist/{Files-EL3EAFQF.js.map → Files-4OWK6XKC.js.map} +1 -1
  11. package/dist/{Notepad-IUAI2IFA.js → Notepad-DTOSYSHN.js} +4 -4
  12. package/dist/{Notepad-IUAI2IFA.js.map → Notepad-DTOSYSHN.js.map} +1 -1
  13. package/dist/{PomodoroTimer-Y3TUMOZE.js → PomodoroTimer-KCKA254T.js} +5 -5
  14. package/dist/{PomodoroTimer-Y3TUMOZE.js.map → PomodoroTimer-KCKA254T.js.map} +1 -1
  15. package/dist/Preview-XSJH2DJX.js +8 -0
  16. package/dist/{Preview-WVGY2LMZ.js.map → Preview-XSJH2DJX.js.map} +1 -1
  17. package/dist/Spreadsheet-M552BN3Q.js +7 -0
  18. package/dist/{Spreadsheet-OIGYKDLZ.js.map → Spreadsheet-M552BN3Q.js.map} +1 -1
  19. package/dist/{Stock-U25A2SLN.js → Stock-YRQMQXTG.js} +4 -4
  20. package/dist/{Stock-U25A2SLN.js.map → Stock-YRQMQXTG.js.map} +1 -1
  21. package/dist/{Weather-MZI5GW2G.js → Weather-RWEAJS36.js} +4 -4
  22. package/dist/{Weather-MZI5GW2G.js.map → Weather-RWEAJS36.js.map} +1 -1
  23. package/dist/{WorldClock-QSWYLWCM.js → WorldClock-E6MSOW5A.js} +4 -4
  24. package/dist/{WorldClock-QSWYLWCM.js.map → WorldClock-E6MSOW5A.js.map} +1 -1
  25. package/dist/apps/index.d.ts +13 -14
  26. package/dist/apps/index.js +19 -19
  27. package/dist/{chunk-D7FFAGRL.js → chunk-72RLGQXP.js} +4 -4
  28. package/dist/{chunk-D7FFAGRL.js.map → chunk-72RLGQXP.js.map} +1 -1
  29. package/dist/{chunk-HIUR2WUX.js → chunk-BK3ZZRRD.js} +4 -4
  30. package/dist/{chunk-HIUR2WUX.js.map → chunk-BK3ZZRRD.js.map} +1 -1
  31. package/dist/{chunk-EAC7TTAV.js → chunk-CTEIE7ZI.js} +4 -4
  32. package/dist/{chunk-EAC7TTAV.js.map → chunk-CTEIE7ZI.js.map} +1 -1
  33. package/dist/{chunk-M5WLDSTN.js → chunk-DARFRWON.js} +5 -5
  34. package/dist/{chunk-M5WLDSTN.js.map → chunk-DARFRWON.js.map} +1 -1
  35. package/dist/{chunk-IAEYNTKR.js → chunk-F4YQYEJQ.js} +4 -4
  36. package/dist/{chunk-IAEYNTKR.js.map → chunk-F4YQYEJQ.js.map} +1 -1
  37. package/dist/{chunk-TESUY2IF.js → chunk-H564CUGN.js} +3 -3
  38. package/dist/{chunk-TESUY2IF.js.map → chunk-H564CUGN.js.map} +1 -1
  39. package/dist/{chunk-CBEY5OLZ.js → chunk-KHKPAF5R.js} +3 -3
  40. package/dist/{chunk-CBEY5OLZ.js.map → chunk-KHKPAF5R.js.map} +1 -1
  41. package/dist/{chunk-CN5BCCHQ.js → chunk-Q2T2FDU3.js} +4 -4
  42. package/dist/{chunk-CN5BCCHQ.js.map → chunk-Q2T2FDU3.js.map} +1 -1
  43. package/dist/{chunk-MINBK6VB.js → chunk-ZGLERMDX.js} +27 -14
  44. package/dist/chunk-ZGLERMDX.js.map +1 -0
  45. package/dist/index.d.ts +107 -87
  46. package/dist/index.js +128 -50
  47. package/dist/index.js.map +1 -1
  48. package/dist/{types-BHVq95fp.d.ts → types-CVECHskm.d.ts} +1 -1
  49. package/package.json +1 -1
  50. package/dist/Browser-YLQ2YMKS.js +0 -7
  51. package/dist/Files-EL3EAFQF.js +0 -12
  52. package/dist/Preview-WVGY2LMZ.js +0 -8
  53. package/dist/Spreadsheet-OIGYKDLZ.js +0 -7
  54. package/dist/chunk-MINBK6VB.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,22 +1,22 @@
1
- import { subscribePomo, getPomoSnapshot } from './chunk-CBEY5OLZ.js';
2
- export { setShellTodoProvider } from './chunk-CBEY5OLZ.js';
3
- import { PREVIEW_OPENED_EVENT, publishDesktopFolders, requestFilesTrashView, FolderGlyph, openPreviewFile, requestFilesDesktopFolderView, FileIconTile, hashGradient } from './chunk-D7FFAGRL.js';
4
- export { Breadcrumbs } from './chunk-D7FFAGRL.js';
1
+ import { subscribePomo, getPomoSnapshot } from './chunk-KHKPAF5R.js';
2
+ export { setShellTodoProvider } from './chunk-KHKPAF5R.js';
3
+ import { PREVIEW_OPENED_EVENT, publishDesktopFolders, requestFilesTrashView, FolderGlyph, openPreviewFile, requestFilesDesktopFolderView, FileIconTile, hashGradient } from './chunk-72RLGQXP.js';
4
+ export { Breadcrumbs } from './chunk-72RLGQXP.js';
5
5
  import { SidebarLayout } from './chunk-YG45DAUT.js';
6
6
  export { SidebarLayout } from './chunk-YG45DAUT.js';
7
7
  import { playNotification, playStartup, soundsEnabled, getSoundConfig, SOUND_PACK_KEYS, SOUND_PACKS, SOUND_TYPES, SOUND_TYPE_LABELS, setSoundForType, previewSound, setAllSounds, playLogout } from './chunk-D7PYW2QS.js';
8
- import { setPdfPreview } from './chunk-IAEYNTKR.js';
9
- export { ImageAnnotator_default as ImageAnnotator } from './chunk-IAEYNTKR.js';
8
+ import { setPdfPreview } from './chunk-F4YQYEJQ.js';
9
+ export { ImageAnnotator_default as ImageAnnotator } from './chunk-F4YQYEJQ.js';
10
10
  import { toast_default } from './chunk-VENYVK3L.js';
11
11
  export { toast_default as toast } from './chunk-VENYVK3L.js';
12
- import { EditableGrid } from './chunk-HIUR2WUX.js';
13
- export { EditableGrid } from './chunk-HIUR2WUX.js';
12
+ import { EditableGrid } from './chunk-BK3ZZRRD.js';
13
+ export { EditableGrid } from './chunk-BK3ZZRRD.js';
14
14
  import { useAuth, useShellAuth } from './chunk-ADJ3CERD.js';
15
15
  export { ShellAuthProvider, setShellAuthBridge, useShellAuth } from './chunk-ADJ3CERD.js';
16
- import { APP_VERSION, VERSION } from './chunk-CN5BCCHQ.js';
17
- export { VERSION } from './chunk-CN5BCCHQ.js';
18
- import { useWindowManager, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, WINDOW_REGISTRY, isPageEntry, Modal, useShellPrefs, useIsMobile, ModalActions, useModalActive, client_default, LoadingSpinner, CancelButton, setWindowPosition, ThumbCard, activateModal } from './chunk-MINBK6VB.js';
19
- export { CancelButton, CopyButton, DocFavStar, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, ShellPrefsProvider, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, commitExposeHighlight, exitExposeMode, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, registerModalEscapeInterceptor, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useLocalStoragePrefs, useModalActive, useShellPrefs, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-MINBK6VB.js';
16
+ import { APP_VERSION, VERSION } from './chunk-Q2T2FDU3.js';
17
+ export { VERSION } from './chunk-Q2T2FDU3.js';
18
+ import { useWindowManager, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, WINDOW_REGISTRY, isPageEntry, Modal, useShellPrefs, useIsMobile, ModalActions, useModalActive, client_default, LoadingSpinner, CancelButton, setWindowPosition, ThumbCard, activateModal } from './chunk-ZGLERMDX.js';
19
+ export { CancelButton, CopyButton, DocFavStar, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, ShellPrefsProvider, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, commitExposeHighlight, exitExposeMode, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, registerModalEscapeInterceptor, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useLocalStoragePrefs, useModalActive, useShellPrefs, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-ZGLERMDX.js';
20
20
  export { ConfirmProvider, confirm, confirmDestructive, prompt } from './chunk-UBN4IUDE.js';
21
21
  import { glassStyle, startMenuCategories, navSections, isSection, GLASS_INPUT_BG, navIcons, sectionIcons } from './chunk-ZF6AYO4G.js';
22
22
  export { GLASS_DIVIDER, GLASS_INPUT_BG, glassStyle, setShellNavIcons } from './chunk-ZF6AYO4G.js';
@@ -5907,8 +5907,13 @@ function EntityList(props) {
5907
5907
  footerExtra,
5908
5908
  sentinelRef,
5909
5909
  isFetchingNextPage,
5910
- saveDefaultPerms
5910
+ saveDefaultPerms,
5911
+ exportEndpoint,
5912
+ exportFilename = "export.csv",
5913
+ contextActions
5911
5914
  } = props;
5915
+ const [menu, setMenu] = useState(null);
5916
+ const hasMenu = !!exportEndpoint || !!contextActions;
5912
5917
  const toggleItem = (item) => {
5913
5918
  setSelected((prev) => {
5914
5919
  const next = new Set(prev);
@@ -5929,6 +5934,48 @@ function EntityList(props) {
5929
5934
  });
5930
5935
  };
5931
5936
  const focusIdx = useTableNav(items, onRowClick, toggleItem, toggleAll, selectRange);
5937
+ const handleRowContextMenu = (e, item) => {
5938
+ if (!hasMenu) return;
5939
+ e.preventDefault();
5940
+ const id = getRowId(item);
5941
+ if (!selected.has(id)) setSelected(/* @__PURE__ */ new Set([id]));
5942
+ setMenu({ x: e.clientX, y: e.clientY });
5943
+ };
5944
+ const selectedItems = items.filter((i) => selected.has(getRowId(i)));
5945
+ const colsParam = () => {
5946
+ const labelByKey = new Map(columns.map((c) => [c.key, c.label]));
5947
+ try {
5948
+ const raw = localStorage.getItem(`col-config-${tableId}`);
5949
+ if (raw) {
5950
+ const parsed = JSON.parse(raw);
5951
+ const cols = parsed.filter((c) => !c.hidden && c.key !== "_select" && labelByKey.has(c.key)).map((c) => `${c.key}|${labelByKey.get(c.key)}`);
5952
+ if (cols.length) return cols.join(",");
5953
+ }
5954
+ } catch {
5955
+ }
5956
+ return columns.filter((c) => !c.defaultHidden).map((c) => `${c.key}|${c.label}`).join(",");
5957
+ };
5958
+ const exportSelected = async () => {
5959
+ setMenu(null);
5960
+ const ids = [...selected];
5961
+ if (!ids.length || !exportEndpoint) return;
5962
+ const p = new URLSearchParams({ ids: ids.join(",") });
5963
+ const cols = colsParam();
5964
+ if (cols) p.set("cols", cols);
5965
+ const sep = exportEndpoint.includes("?") ? "&" : "?";
5966
+ try {
5967
+ const res = await client_default.get(`${exportEndpoint}${sep}${p}`, { responseType: "blob" });
5968
+ const url = window.URL.createObjectURL(new Blob([res.data], { type: "text/csv" }));
5969
+ const a = document.createElement("a");
5970
+ a.href = url;
5971
+ a.download = exportFilename;
5972
+ a.click();
5973
+ window.URL.revokeObjectURL(url);
5974
+ toast_default.success(`Exported ${ids.length} ${ids.length === 1 ? "row" : "rows"}.`);
5975
+ } catch {
5976
+ toast_default.error("CSV export failed.");
5977
+ }
5978
+ };
5932
5979
  if (isLoading) return /* @__PURE__ */ jsx(LoadingSpinner, {});
5933
5980
  if (items.length === 0) return /* @__PURE__ */ jsx(Fragment, { children: emptyState });
5934
5981
  const allSelected = items.length > 0 && selected.size === items.length;
@@ -5965,44 +6012,75 @@ function EntityList(props) {
5965
6012
  /* @__PURE__ */ jsx("div", { ref: sentinelRef }),
5966
6013
  isFetchingNextPage && /* @__PURE__ */ jsx("div", { className: "text-center py-3", children: /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500", children: "Loading more..." }) })
5967
6014
  ] }) : void 0;
5968
- return /* @__PURE__ */ jsx("div", { className: "flex-1 flex flex-col mb-1 bg-white rounded-lg shadow overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 flex flex-col", children: /* @__PURE__ */ jsx(
5969
- ResizableTable,
5970
- {
5971
- tableId,
5972
- columns: fullColumns,
5973
- sort,
5974
- onSort,
5975
- footer,
5976
- afterBody,
5977
- saveDefaultPerms,
5978
- children: (cols) => /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-gray-100", children: items.map((item, rowIdx) => {
5979
- const id = getRowId(item);
5980
- return /* @__PURE__ */ jsx(
5981
- "tr",
6015
+ const actions = menu && contextActions ? contextActions(selectedItems) : [];
6016
+ return /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col mb-1 bg-white rounded-lg shadow overflow-hidden", children: [
6017
+ /* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 flex flex-col", children: /* @__PURE__ */ jsx(
6018
+ ResizableTable,
6019
+ {
6020
+ tableId,
6021
+ columns: fullColumns,
6022
+ sort,
6023
+ onSort,
6024
+ footer,
6025
+ afterBody,
6026
+ saveDefaultPerms,
6027
+ children: (cols) => /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-gray-100", children: items.map((item, rowIdx) => {
6028
+ const id = getRowId(item);
6029
+ return /* @__PURE__ */ jsx(
6030
+ "tr",
6031
+ {
6032
+ "data-row-idx": rowIdx,
6033
+ className: `cursor-pointer ${focusIdx === rowIdx ? "bg-blue-50 ring-1 ring-inset ring-blue-300" : selected.has(id) ? "bg-blue-50 hover:bg-blue-100" : "hover:bg-gray-50"} ${getRowClassName?.(item) ?? ""}`,
6034
+ onClick: () => onRowClick(item),
6035
+ onContextMenu: hasMenu ? (e) => handleRowContextMenu(e, item) : void 0,
6036
+ onMouseEnter: onRowHover ? () => onRowHover(item) : void 0,
6037
+ children: cols.map((col) => /* @__PURE__ */ jsx("td", { className: "px-4 py-3 whitespace-nowrap text-sm overflow-hidden", children: col.key === "_select" ? /* @__PURE__ */ jsx(
6038
+ "input",
6039
+ {
6040
+ type: "checkbox",
6041
+ checked: selected.has(id),
6042
+ onClick: (e) => {
6043
+ e.stopPropagation();
6044
+ toggleItem(item);
6045
+ },
6046
+ readOnly: true,
6047
+ className: "h-3.5 w-3.5 rounded border-gray-300 text-blue-600"
6048
+ }
6049
+ ) : renderCell(item, col.key) }, col.key))
6050
+ },
6051
+ id
6052
+ );
6053
+ }) })
6054
+ }
6055
+ ) }),
6056
+ menu && /* @__PURE__ */ jsxs(PopupMenu, { portal: true, style: { left: menu.x, top: menu.y }, onClose: () => setMenu(null), minWidth: 210, children: [
6057
+ /* @__PURE__ */ jsxs(PopupMenuLabel, { children: [
6058
+ selected.size,
6059
+ " selected"
6060
+ ] }),
6061
+ exportEndpoint && /* @__PURE__ */ jsx(PopupMenuItem, { onClick: exportSelected, children: "Export selected to CSV" }),
6062
+ actions.map((a, i) => /* @__PURE__ */ jsxs("div", { children: [
6063
+ a.divider && /* @__PURE__ */ jsx(PopupMenuDivider, {}),
6064
+ /* @__PURE__ */ jsx(
6065
+ PopupMenuItem,
5982
6066
  {
5983
- "data-row-idx": rowIdx,
5984
- className: `cursor-pointer ${focusIdx === rowIdx ? "bg-blue-50 ring-1 ring-inset ring-blue-300" : selected.has(id) ? "bg-blue-50 hover:bg-blue-100" : "hover:bg-gray-50"} ${getRowClassName?.(item) ?? ""}`,
5985
- onClick: () => onRowClick(item),
5986
- onMouseEnter: onRowHover ? () => onRowHover(item) : void 0,
5987
- children: cols.map((col) => /* @__PURE__ */ jsx("td", { className: "px-4 py-3 whitespace-nowrap text-sm overflow-hidden", children: col.key === "_select" ? /* @__PURE__ */ jsx(
5988
- "input",
5989
- {
5990
- type: "checkbox",
5991
- checked: selected.has(id),
5992
- onClick: (e) => {
5993
- e.stopPropagation();
5994
- toggleItem(item);
5995
- },
5996
- readOnly: true,
5997
- className: "h-3.5 w-3.5 rounded border-gray-300 text-blue-600"
5998
- }
5999
- ) : renderCell(item, col.key) }, col.key))
6000
- },
6001
- id
6002
- );
6003
- }) })
6004
- }
6005
- ) }) });
6067
+ danger: a.danger,
6068
+ disabled: a.disabled,
6069
+ onClick: () => {
6070
+ setMenu(null);
6071
+ a.onClick(selectedItems);
6072
+ },
6073
+ children: a.label
6074
+ }
6075
+ )
6076
+ ] }, i)),
6077
+ /* @__PURE__ */ jsx(PopupMenuDivider, {}),
6078
+ /* @__PURE__ */ jsx(PopupMenuItem, { onClick: () => {
6079
+ setMenu(null);
6080
+ setSelected(/* @__PURE__ */ new Set());
6081
+ }, children: "Clear selection" })
6082
+ ] })
6083
+ ] });
6006
6084
  }
6007
6085
  function Kanban({
6008
6086
  items,