@trops/dash-core 0.1.595 → 0.1.596

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.
package/dist/index.js CHANGED
@@ -60515,24 +60515,40 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
60515
60515
 
60516
60516
  // ─── Unsaved-changes guard (Phase 2B) ────────────────────────────
60517
60517
  // Single source of truth for "is the user mid-edit with un-saved
60518
- // work?". Edit mode (`previewMode === false`) is necessary; a
60519
- // populated `currentWorkspaceRef` is sufficient the layout
60520
- // builder mutates that ref on every drag/drop/widget change.
60518
+ // work?". A state variable NOT a derived ref check — because the
60519
+ // useEffect that mirrors this to `globalThis.__dashboardIsDirty`
60520
+ // must re-run when the value changes, and `useRef` mutations don't
60521
+ // trigger re-renders.
60521
60522
  //
60522
- // The flag is mirrored to `globalThis.__dashboardIsDirty` so the
60523
- // Electron main process can poll it synchronously during window
60524
- // close + app-quit handlers without an IPC round-trip.
60523
+ // Mutations that flip it true:
60524
+ // - LayoutBuilder.onWorkspaceChange (widget drag/drop/swap/delete)
60525
+ // via `handleWorkspaceChange`
60526
+ // - Header title rename via `handleWorkspaceNameChange`
60527
+ // - Folder / theme changes via `handleWorkspaceFolderChange`,
60528
+ // `handleWorkspaceThemeChange`
60529
+ //
60530
+ // Mutations that reset to false:
60531
+ // - Successful save (`handleSaveWorkspaceComplete`)
60532
+ // - Cancel/discard (`performCancelEdit` + the discard modal path)
60533
+ // - Re-entering edit mode (`handleToggleEditMode` enter branch)
60534
+ //
60535
+ // Mirrored to `globalThis.__dashboardIsDirty` so the Electron main
60536
+ // process can poll synchronously during window close + app-quit
60537
+ // handlers without an IPC round-trip.
60525
60538
  //
60526
60539
  // A `pendingNavigation` object captures a navigation request that
60527
60540
  // arrived while dirty so the user can choose to discard or keep
60528
60541
  // editing. Shapes:
60529
60542
  // { kind: "open-workspace", workspace } — sidebar switch
60530
60543
  // { kind: "cancel-edit" } — Cancel button
60531
- var _useState57 = React.useState(null),
60544
+ var _useState57 = React.useState(false),
60532
60545
  _useState58 = _slicedToArray(_useState57, 2),
60533
- pendingNavigation = _useState58[0],
60534
- setPendingNavigation = _useState58[1];
60535
- var isDirty = previewMode === false && currentWorkspaceRef.current !== null;
60546
+ isDirty = _useState58[0],
60547
+ setIsDirty = _useState58[1];
60548
+ var _useState59 = React.useState(null),
60549
+ _useState60 = _slicedToArray(_useState59, 2),
60550
+ pendingNavigation = _useState60[0],
60551
+ setPendingNavigation = _useState60[1];
60536
60552
  React.useEffect(function () {
60537
60553
  if (typeof globalThis !== "undefined") {
60538
60554
  globalThis.__dashboardIsDirty = isDirty;
@@ -60630,10 +60646,10 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
60630
60646
  // We record the requested ID and open it once it appears in
60631
60647
  // workspaceConfig — handles the case where the workspace was just
60632
60648
  // created and the config reload is still in flight.
60633
- var _useState59 = React.useState(null),
60634
- _useState60 = _slicedToArray(_useState59, 2),
60635
- pendingOpenWorkspaceId = _useState60[0],
60636
- setPendingOpenWorkspaceId = _useState60[1];
60649
+ var _useState61 = React.useState(null),
60650
+ _useState62 = _slicedToArray(_useState61, 2),
60651
+ pendingOpenWorkspaceId = _useState62[0],
60652
+ setPendingOpenWorkspaceId = _useState62[1];
60637
60653
  React.useEffect(function () {
60638
60654
  var handler = function handler(e) {
60639
60655
  var _e$detail2;
@@ -61054,6 +61070,9 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
61054
61070
  setPreviewMode(function () {
61055
61071
  return false;
61056
61072
  });
61073
+ // LayoutBuilder fired a mutation (widget drag/drop/swap/delete).
61074
+ // Mark the workspace dirty so the navigation + close guards fire.
61075
+ setIsDirty(true);
61057
61076
 
61058
61077
  // Update the tab's workspace reference
61059
61078
  if (activeTabId) {
@@ -61257,10 +61276,10 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
61257
61276
  }
61258
61277
 
61259
61278
  // ─── Page State ──────────────────────────────────────────────────
61260
- var _useState61 = React.useState(null),
61261
- _useState62 = _slicedToArray(_useState61, 2),
61262
- activePageId = _useState62[0],
61263
- setActivePageId = _useState62[1];
61279
+ var _useState63 = React.useState(null),
61280
+ _useState64 = _slicedToArray(_useState63, 2),
61281
+ activePageId = _useState64[0],
61282
+ setActivePageId = _useState64[1];
61264
61283
 
61265
61284
  // Page history stack for goBack() — pushes the previous page id
61266
61285
  // whenever a navigation happens through navigateToPage().
@@ -61656,12 +61675,15 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
61656
61675
  }
61657
61676
  currentWorkspaceRef.current = null;
61658
61677
  originalWorkspaceRef.current = null;
61678
+ setIsDirty(false);
61659
61679
  setPreviewMode(true);
61660
61680
  }
61661
61681
  function handleToggleEditMode() {
61662
61682
  if (previewMode) {
61663
- // Entering edit mode — snapshot the current workspace
61683
+ // Entering edit mode — snapshot the current workspace and
61684
+ // reset the dirty flag so we start from a clean slate.
61664
61685
  originalWorkspaceRef.current = DashReact.deepCopy(workspaceSelected);
61686
+ setIsDirty(false);
61665
61687
  setPreviewMode(false);
61666
61688
  return;
61667
61689
  }
@@ -61683,6 +61705,9 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
61683
61705
 
61684
61706
  // Update the tab name and workspace reference
61685
61707
  updateTabWorkspace(tempWorkspace);
61708
+ // Header rename counts as a workspace mutation; mark dirty so
61709
+ // navigation + close guards fire.
61710
+ setIsDirty(true);
61686
61711
  }
61687
61712
  function handleWorkspaceFolderChange(menuId) {
61688
61713
  if (!workspaceSelected) return;
@@ -61846,6 +61871,7 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
61846
61871
  // Clear edit-mode refs — edits are now persisted
61847
61872
  currentWorkspaceRef.current = null;
61848
61873
  originalWorkspaceRef.current = null;
61874
+ setIsDirty(false);
61849
61875
  setPreviewMode(function () {
61850
61876
  return true;
61851
61877
  });
@@ -62362,10 +62388,11 @@ var DashboardStageInner = function DashboardStageInner(_ref3) {
62362
62388
  if (pending.kind === "cancel-edit") {
62363
62389
  performCancelEdit();
62364
62390
  } else if (pending.kind === "open-workspace") {
62365
- // Clear edit refs before navigating so the new workspace
62366
- // mount doesn't inherit dirty state.
62391
+ // Clear edit refs + dirty flag before navigating so the
62392
+ // new workspace mount doesn't inherit dirty state.
62367
62393
  currentWorkspaceRef.current = null;
62368
62394
  originalWorkspaceRef.current = null;
62395
+ setIsDirty(false);
62369
62396
  setPreviewMode(true);
62370
62397
  handleOpenTab(pending.workspace);
62371
62398
  }