@nivaro/react 0.1.236 → 0.1.238

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.d.ts CHANGED
@@ -8,6 +8,7 @@ import { ImportTemplateSummary } from '@nivaro/sdk';
8
8
  import { JSX } from 'react';
9
9
  import { JSXElementConstructor } from 'react';
10
10
  import type { LucideIcon } from 'lucide-react';
11
+ import { ManagedUser } from '@nivaro/sdk';
11
12
  import { NivaroClient } from '@nivaro/sdk';
12
13
  import { default as React_2 } from 'react';
13
14
  import { ReactElement } from 'react';
@@ -1037,6 +1038,29 @@ export declare function DefinitionsPanel({ definitions, runCounts, isLoading }:
1037
1038
  isLoading?: boolean;
1038
1039
  }): JSX.Element;
1039
1040
 
1041
+ export declare function DelegationCard({ user, onSaved }: {
1042
+ user: ManagedUser;
1043
+ onSaved: () => void;
1044
+ }): JSX.Element;
1045
+
1046
+ export declare function DelegationConsoleView({ className, onNotice }: DelegationConsoleViewProps): JSX.Element;
1047
+
1048
+ export declare interface DelegationConsoleViewProps {
1049
+ className?: string;
1050
+ /** Host toast hook. */
1051
+ onNotice?: (message: string) => void;
1052
+ }
1053
+
1054
+ export declare function DeliveryChips({ delivery, mailLogUrl, onNavigate, className }: DeliveryChipsProps): JSX.Element;
1055
+
1056
+ declare interface DeliveryChipsProps {
1057
+ delivery: NotificationDeliveryRecord | null | undefined;
1058
+ /** Host route for a mail-log row (admin: /mail-log?id=N). Absent = no link. */
1059
+ mailLogUrl?: (mailLogId: number) => string | null;
1060
+ onNavigate?: (path: string) => void;
1061
+ className?: string;
1062
+ }
1063
+
1040
1064
  export declare function deriveGroupKey<T extends QueueGroupingRow>(row: T, attribute: string): string;
1041
1065
 
1042
1066
  export declare function describeCron(cron: string): string;
@@ -1879,10 +1903,14 @@ declare interface ImportValidationReport {
1879
1903
  truncated: boolean;
1880
1904
  }
1881
1905
 
1882
- export declare function InlineTableField({ relatedCollection, manyField, parentId, parentCollection, layoutId, showRowRevisions, rowComments, allowRevisionRestore, saveMode, showLineNumbers, enableReorder, parentCascades, rowRules, columnPresets, defaultPreset, drawerRelations, parentContextFields, uniqueBy, sortField, sortDir, sectionGroupBy, freezeFirstColumn, rowFilter, rowDefaults, allocateDrawer, autoAllocate, rowBulkActions, uploadTemplate, rowMatchPanel, lineSla, rowLints, submissionErrors, prefillParentId, parentFieldKey, readOnly, emptyLabel }: {
1906
+ export declare function InlineTableField({ relatedCollection, manyField, parentId, parentCollection, layoutId, showRowRevisions, rowComments, allowRevisionRestore, saveMode, showLineNumbers, enableReorder, parentCascades, rowRules, columnPresets, defaultPreset, drawerRelations, parentContextFields, uniqueBy, sortField, sortDir, sectionGroupBy, freezeFirstColumn, rowFilter, rowDefaults, allocateDrawer, autoAllocate, rowBulkActions, uploadTemplate, rowMatchPanel, lineSla, rowLints, submissionErrors, prefillParentId, parentFieldKey, readOnly, emptyLabel, editorMode }: {
1883
1907
  relatedCollection: string;
1884
1908
  manyField: string;
1885
1909
  parentId: string;
1910
+ /** options.editor_mode — where a row's editor renders: 'drawer' (under the
1911
+ * row, the default) or 'split' (docked below the table, arrow keys walk the
1912
+ * rows). A per-user toolbar toggle (localStorage) wins over this. */
1913
+ editorMode?: 'drawer' | 'split';
1886
1914
  /** Same table display, but no editing: hides the Add toolbar, + Add row,
1887
1915
  * row delete/undo, and blocks cell edit entry. */
1888
1916
  readOnly?: boolean;
@@ -1969,7 +1997,7 @@ export declare type ItemEditAuthContextValue = {
1969
1997
  userId: string;
1970
1998
  };
1971
1999
 
1972
- export declare function ItemEditForm({ collection, itemId: itemIdProp, layoutSlug, initialAddendumViewId, onAddendumViewChange, onBack, onSaved, onDeleted, showHeader, headerExtra, focusField, showItemActions, onDirtyChange, documentTitle, registerSaveHandler, onDuplicate, showRevisions, showClone, showPipeline, showWorkflow, showComments, showTasks, showLockBanner, className, headerClassName, renderField, extraTopContent, extraBottomContent, onHeaderWidgets, initialImportResult, initialValues, initialLinks, initialRows }: ItemEditFormProps): JSX.Element;
2000
+ export declare function ItemEditForm({ collection, itemId: itemIdProp, layoutSlug: layoutSlugProp, initialAddendumViewId, onAddendumViewChange, onBack, onSaved, onDeleted, showHeader, headerExtra, focusField, showItemActions, onDirtyChange, documentTitle, registerSaveHandler, onDuplicate, showRevisions, showClone, showPipeline, showWorkflow, showComments, showTasks, showLockBanner, className, headerClassName, renderField, extraTopContent, extraBottomContent, onHeaderWidgets, initialImportResult, initialValues, initialLinks, initialRows }: ItemEditFormProps): JSX.Element;
1973
2001
 
1974
2002
  export declare interface ItemEditFormProps {
1975
2003
  collection: string;
@@ -2004,7 +2032,8 @@ export declare interface ItemEditFormProps {
2004
2032
  */
2005
2033
  /** Fires whenever the form's dirty state flips — lets a host (workspace
2006
2034
  * tabs, close guards) track unsaved edits without reaching inside. */
2007
- onDirtyChange?: (dirty: boolean) => void;
2035
+ /** Dirty flag plus a breakdown of what is unsaved (fields, staged lines, links) — hosts render their own leave-page prompt from it. */
2036
+ onDirtyChange?: (dirty: boolean, summary?: UnsavedSummary) => void;
2008
2037
  /** false = skip the document.title side effect — a workspace-tab host keeps
2009
2038
  * several forms mounted and only the ACTIVE one may own the browser tab. */
2010
2039
  documentTitle?: boolean;
@@ -2064,13 +2093,18 @@ export declare type ItemLinkTarget = {
2064
2093
  prefill?: Record<string, unknown> | null;
2065
2094
  };
2066
2095
 
2067
- export declare function ItemLockBanner({ lockHolder, onTakeOver, takingOver, isAdmin, onRequestLock, requesting }: {
2096
+ export declare function ItemLockBanner({ lockHolder, onTakeOver, takingOver, isAdmin, onRequestLock, requesting, queue, myPosition, onJoinQueue, onLeaveQueue, joining }: {
2068
2097
  lockHolder: LockHolder | null;
2069
2098
  onTakeOver: () => void;
2070
2099
  takingOver: boolean;
2071
2100
  isAdmin?: boolean;
2072
2101
  onRequestLock?: () => void;
2073
2102
  requesting?: boolean;
2103
+ queue?: LockQueueEntry[];
2104
+ myPosition?: number | null;
2105
+ onJoinQueue?: () => void;
2106
+ onLeaveQueue?: () => void;
2107
+ joining?: boolean;
2074
2108
  }): JSX.Element | null;
2075
2109
 
2076
2110
  export declare function JsonMapEditor({ config, scope }: {
@@ -2211,6 +2245,10 @@ declare interface LayoutGroup {
2211
2245
  label: string;
2212
2246
  type: string | null;
2213
2247
  sort: number;
2248
+ id?: number;
2249
+ container_id?: number | null;
2250
+ is_collapsed?: boolean | number | null;
2251
+ visibility_mode?: string | null;
2214
2252
  }
2215
2253
 
2216
2254
  export declare type LayoutItem = FormGroupDescriptor | '__ungrouped__';
@@ -2282,6 +2320,16 @@ export declare function listFieldInterfaces(): string[];
2282
2320
  declare interface LockHolder {
2283
2321
  locked_by: string;
2284
2322
  locked_by_name: string | null;
2323
+ /** The holder's intent note (#10) — "editing lines ~15 min". */
2324
+ note?: string | null;
2325
+ /** Minutes since the holder last did anything (presence), when known. */
2326
+ idle_minutes?: number | null;
2327
+ }
2328
+
2329
+ declare interface LockQueueEntry {
2330
+ user: string;
2331
+ name: string | null;
2332
+ requested_at: string;
2285
2333
  }
2286
2334
 
2287
2335
  export declare interface M2MStagingCtx {
@@ -2579,6 +2627,159 @@ export declare function NivaroProvider({ client, children }: {
2579
2627
  */
2580
2628
  export declare function normalizeFieldType(rawType: string, iface: string | null, relation: FormFieldDescriptor['relation']): FormFieldType;
2581
2629
 
2630
+ export declare function NotificationActions({ actions, notificationId, onDone, onError, size, className }: NotificationActionsProps): JSX.Element | null;
2631
+
2632
+ /** An inline action the server says is safe to fire from a click. */
2633
+ export declare interface NotificationActionSpec {
2634
+ key: string;
2635
+ label: string;
2636
+ method: 'POST' | 'PATCH';
2637
+ endpoint: string;
2638
+ body?: Record<string, unknown>;
2639
+ mark_read?: boolean;
2640
+ /** The action takes a line of text (a reply, a note): render an input and
2641
+ * send its value as body[field]. */
2642
+ input?: {
2643
+ field: string;
2644
+ placeholder: string;
2645
+ submit_label?: string;
2646
+ };
2647
+ }
2648
+
2649
+ /**
2650
+ * The inline action pills a notification row offers (server-described:
2651
+ * endpoint + body, domain-blind). One-click actions fire straight away;
2652
+ * actions carrying `input` (Reply, Comment on this) open an inline text box
2653
+ * under the row and send its value as body[field]. Marks the row read when
2654
+ * the action says so, then invalidates the notification queries.
2655
+ */
2656
+ declare interface NotificationActionsProps {
2657
+ actions: NotificationActionSpec[];
2658
+ notificationId: number;
2659
+ /** Called after any successful action (hosts refresh their own lists). */
2660
+ onDone?: () => void;
2661
+ onError?: (message: string) => void;
2662
+ size?: 'sm' | 'xs';
2663
+ className?: string;
2664
+ }
2665
+
2666
+ export declare function NotificationAnalyticsView({ className }: {
2667
+ className?: string;
2668
+ }): JSX.Element;
2669
+
2670
+ /**
2671
+ * The Nivaro notification bell — the same setup the admin uses: badge that
2672
+ * counts what NEEDS YOU (Critical + Needs-you lanes, never FYI), lane tabs,
2673
+ * rows grouped by record (five updates on one workflow read as one story),
2674
+ * group-level open + mark-read, inline server-approved actions including
2675
+ * reply boxes, per-row delivery chips (where did this go?), and
2676
+ * click-through routing via the shared notification-target resolver. Needs
2677
+ * `<NivaroProvider>`.
2678
+ */
2679
+ export declare function NotificationBell({ routes, onNavigate, app, subscribe, buttonClassName, panelClassName, beforeList, extraBadge, mailLogUrl, renderTrigger, allPath, onActionError, panelPlacement }: NotificationBellProps): JSX.Element;
2680
+
2681
+ export declare interface NotificationBellProps {
2682
+ /** Where each notification kind lands in the host app. */
2683
+ routes: NotificationRouteMap;
2684
+ /** Host router push — the bell never imports a router itself. */
2685
+ onNavigate: (path: string) => void;
2686
+ /** Which app's routes the server should resolve fallback urls for (?app=…). */
2687
+ app?: 'portal' | 'admin';
2688
+ /**
2689
+ * Realtime hookup: invoke the callback whenever a notification arrives and
2690
+ * return an unsubscribe. The bell refreshes its queries; anything else
2691
+ * (sounds, toasts) stays in the host's handler.
2692
+ */
2693
+ subscribe?: (onNew: () => void) => () => void;
2694
+ /** Extra classes for the trigger button (host header styling). */
2695
+ buttonClassName?: string;
2696
+ /** Extra classes for the popup panel (position/size overrides). */
2697
+ panelClassName?: string;
2698
+ /** Rendered above the tab strip inside the panel (host strips such as
2699
+ * "3 access requests waiting on an admin"). */
2700
+ beforeList?: ReactNode;
2701
+ /** Added to the badge count (host-side items the inbox does not hold). */
2702
+ extraBadge?: number;
2703
+ /** Host route for a mail-log row — turns the email delivery chip into a
2704
+ * link. Absent = chips are plain. */
2705
+ mailLogUrl?: (mailLogId: number) => string | null;
2706
+ /** Replace the trigger button entirely (the popup still positions against
2707
+ * the wrapper). */
2708
+ renderTrigger?: (state: {
2709
+ open: boolean;
2710
+ badge: number;
2711
+ toggle: () => void;
2712
+ }) => ReactNode;
2713
+ /** Path of the full notifications page — renders a "See all" footer link. */
2714
+ allPath?: string | null;
2715
+ /** Called with an error message when an inline action fails. */
2716
+ onActionError?: (message: string) => void;
2717
+ /** Where the panel opens relative to the trigger. 'below' (default) keeps
2718
+ * it inside the trigger's tree; 'right' portals it to document.body and
2719
+ * positions it beside the trigger — for a sidebar rail whose overflow
2720
+ * would clip an inline panel. */
2721
+ panelPlacement?: 'below' | 'right';
2722
+ }
2723
+
2724
+ export declare function NotificationCenterView({ routes, onNavigate, app, mailLogUrl, onNotice, onError, className }: NotificationCenterViewProps): JSX.Element;
2725
+
2726
+ export declare interface NotificationCenterViewProps {
2727
+ routes: NotificationRouteMap;
2728
+ onNavigate: (path: string) => void;
2729
+ app?: 'portal' | 'admin';
2730
+ mailLogUrl?: (mailLogId: number) => string | null;
2731
+ /** Toast hooks — hosts wire their own toaster. */
2732
+ onNotice?: (message: string) => void;
2733
+ onError?: (message: string) => void;
2734
+ className?: string;
2735
+ }
2736
+
2737
+ /** Per-channel delivery outcome recorded on the row (GET /notifications
2738
+ * `delivery`). Rows from before delivery tracking carry only in-app. */
2739
+ export declare interface NotificationDeliveryRecord {
2740
+ inapp?: {
2741
+ status: 'delivered' | 'skipped';
2742
+ reason?: string;
2743
+ };
2744
+ push?: {
2745
+ status: 'sent' | 'no_subscription' | 'skipped' | 'failed';
2746
+ reason?: string;
2747
+ at?: string;
2748
+ };
2749
+ email?: {
2750
+ status: 'sent' | 'deferred' | 'dropped' | 'failed' | 'off' | 'not_requested' | 'no_address' | 'unconfigured';
2751
+ reason?: string;
2752
+ mail_log_id?: number | null;
2753
+ at?: string;
2754
+ };
2755
+ sms?: {
2756
+ status: 'sent' | 'failed' | 'skipped' | 'not_requested';
2757
+ reason?: string;
2758
+ };
2759
+ escalation?: {
2760
+ push_at?: string;
2761
+ email_at?: string;
2762
+ email_log_id?: number | null;
2763
+ };
2764
+ }
2765
+
2766
+ /** Inbox lane — Critical and Needs-you are what the badge counts. */
2767
+ export declare type NotificationLane = 'critical' | 'needs_you' | 'fyi';
2768
+
2769
+ /** The notification row shape every surface receives (GET /notifications). */
2770
+ export declare interface NotificationLike {
2771
+ collection?: string | null;
2772
+ item?: string | null;
2773
+ target?: NotificationTargetSpec | null;
2774
+ /** Server-resolved URL for the recipient's app — the fallback when this
2775
+ * host has no route for the kind (opens in a new tab when foreign). */
2776
+ url?: string | null;
2777
+ actions?: NotificationActionSpec[] | null;
2778
+ lane?: NotificationLane | null;
2779
+ category?: string | null;
2780
+ delivery?: NotificationDeliveryRecord | null;
2781
+ }
2782
+
2582
2783
  /**
2583
2784
  * Every in-app notification must land somewhere meaningful — this is the ONE
2584
2785
  * resolver both bells, the notifications page, and My Work use to decide what
@@ -2603,6 +2804,11 @@ export declare interface NotificationRouteMap {
2603
2804
  alerts?: () => string | null;
2604
2805
  imports?: () => string | null;
2605
2806
  issues?: () => string | null;
2807
+ /** Task list (a task-kind row); hosts without one fall back to my_work / url. */
2808
+ tasks?: (id?: string | null) => string | null;
2809
+ approvals?: () => string | null;
2810
+ access_requests?: () => string | null;
2811
+ my_work?: () => string | null;
2606
2812
  }
2607
2813
 
2608
2814
  export declare function NotificationRulesCard(): JSX.Element;
@@ -2644,8 +2850,37 @@ export declare type NotificationTarget = {
2644
2850
  } | {
2645
2851
  type: 'chat';
2646
2852
  room: string;
2853
+ } | {
2854
+ type: 'external';
2855
+ url: string;
2647
2856
  } | null;
2648
2857
 
2858
+ /** Server-side target spec (services/notification-target.ts) — what the
2859
+ * notification is about and what a click should offer. */
2860
+ export declare interface NotificationTargetSpec {
2861
+ kind: 'record' | 'task' | 'approval' | 'access_request' | 'sla' | 'chat' | 'queue' | 'report' | 'alerts' | 'issue' | 'import' | 'dashboard' | 'my_work' | 'home' | 'external';
2862
+ collection?: string | null;
2863
+ id?: string | number | null;
2864
+ room?: string | null;
2865
+ query?: string | null;
2866
+ focus?: string | null;
2867
+ tab?: string | null;
2868
+ url?: string | null;
2869
+ action?: 'open' | 'complete' | 'acknowledge' | 'review' | 'approve' | 'reply';
2870
+ task_id?: string | number | null;
2871
+ instance_id?: string | number | null;
2872
+ }
2873
+
2874
+ export declare function NotificationTemplatesView({ onNotice, onError, className, embedded }: NotificationTemplatesViewProps): JSX.Element;
2875
+
2876
+ declare interface NotificationTemplatesViewProps {
2877
+ onNotice?: (message: string) => void;
2878
+ onError?: (message: string) => void;
2879
+ className?: string;
2880
+ /** Embedded inside another page (no page header). */
2881
+ embedded?: boolean;
2882
+ }
2883
+
2649
2884
  export declare function NumberField({ field, value, onChange, error, disabled, readOnly, inputId, errorId }: FieldComponentProps): JSX.Element;
2650
2885
 
2651
2886
  /** Intl options for a numeric field, honoring its configured precision. */
@@ -2847,12 +3082,14 @@ declare type PipelineOwnerDimension = {
2847
3082
  cascade?: DimensionCascadeRule[] | null;
2848
3083
  };
2849
3084
 
2850
- export declare function PipelinePanel({ collection, item, defaultExpanded, title, showApprovalChain, hideActionsCollapsed, hideActionsExpanded, onBeforeTransition, addendumPending, addendumView }: {
3085
+ export declare function PipelinePanel({ collection, item, defaultExpanded, title, showApprovalChain, hideActionsCollapsed, hideActionsExpanded, onBeforeTransition, addendumPending, addendumView, asRole }: {
2851
3086
  collection: string;
2852
3087
  item: string;
2853
3088
  defaultExpanded?: boolean;
2854
3089
  title?: string;
2855
3090
  showApprovalChain?: boolean;
3091
+ /** Admin "view as role" (#8): evaluate available transitions for this role instead of the caller. */
3092
+ asRole?: string | null;
2856
3093
  /** Layout-configurable: suppress the transition buttons inside the slot
2857
3094
  * (collapsed header row / expanded body) — redundant when the record header
2858
3095
  * already renders PipelineTransitionButtons. */
@@ -3450,9 +3687,11 @@ export declare interface RealtimeAdapter {
3450
3687
 
3451
3688
  export declare const RealtimeContext: Context<RealtimeAdapter | null>;
3452
3689
 
3453
- export declare function RecordChatActions({ collection, itemDraft }: {
3690
+ export declare function RecordChatActions({ collection, itemDraft, compact }: {
3454
3691
  collection: string;
3455
3692
  itemDraft: Record<string, unknown>;
3693
+ /** Icon-only, borderless — for the record header's tool group. */
3694
+ compact?: boolean;
3456
3695
  }): JSX.Element | null;
3457
3696
 
3458
3697
  export declare function RecordDrilldownSheet({ collection, itemId, layoutId, rootLayoutSlug, width, title, stack: controlledStack, onPush, onPop, onClose }: {
@@ -3554,10 +3793,12 @@ export declare function RecordGridWidgetBody({ widget }: {
3554
3793
  widget: PageRendererWidget;
3555
3794
  }): JSX.Element;
3556
3795
 
3557
- export declare function RecordReadView({ collection, itemId, layoutData }: {
3796
+ export declare function RecordReadView({ collection, itemId, layoutData, flush }: {
3558
3797
  collection: string;
3559
3798
  itemId: string;
3560
3799
  layoutData: ReadViewLayout;
3800
+ /** Host already pads and scrolls the body (the record form's read mode). */
3801
+ flush?: boolean;
3561
3802
  }): JSX.Element;
3562
3803
 
3563
3804
  /**
@@ -3588,10 +3829,12 @@ export declare function RecordRecapStrip({ collection, itemId }: {
3588
3829
  * Transitions never fire the items-service update hook (state mirrors are raw
3589
3830
  * writes), so the two rows can't double-notify.
3590
3831
  */
3591
- export declare function RecordSubscribeButton({ collection, itemId, recordLabel }: {
3832
+ export declare function RecordSubscribeButton({ collection, itemId, recordLabel, compact }: {
3592
3833
  collection: string;
3593
3834
  itemId: string;
3594
3835
  recordLabel?: string;
3836
+ /** Icon-only, borderless — for the record header's tool group. */
3837
+ compact?: boolean;
3595
3838
  }): JSX.Element;
3596
3839
 
3597
3840
  /** Register a detail opener for a catalog collection. Returns an unregister
@@ -3726,6 +3969,15 @@ export declare function resolveCollectionIcon(iconName: string | null | undefine
3726
3969
 
3727
3970
  export declare function resolveNotificationTarget(collection: string | null | undefined, item: string | null | undefined, routes: NotificationRouteMap): NotificationTarget;
3728
3971
 
3972
+ /**
3973
+ * Structured resolution: the server's target spec mapped onto THIS host's
3974
+ * routes (kind by kind), falling back to the server-resolved `url` — same
3975
+ * origin → in-app path, foreign origin → external (new tab) — and finally to
3976
+ * the legacy collection + item resolution. A row still resolving to null
3977
+ * renders as plain text.
3978
+ */
3979
+ export declare function resolveNotificationTargetFor(n: NotificationLike, routes: NotificationRouteMap): NotificationTarget;
3980
+
3729
3981
  declare type ReviewListColumnFormat = 'currency' | 'number' | 'date' | 'datetime' | 'flag';
3730
3982
 
3731
3983
  declare interface ReviewListColumnSpec {
@@ -3825,11 +4077,13 @@ declare interface ReviewListWidgetProps {
3825
4077
  emptyLabel?: string;
3826
4078
  }
3827
4079
 
3828
- export declare function RevisionsPanel({ collection, item, onRollback, triggerClassName, inlineTableFields, open, onOpenChange }: {
4080
+ export declare function RevisionsPanel({ collection, item, onRollback, triggerClassName, inlineTableFields, open, onOpenChange, compact }: {
3829
4081
  collection: string;
3830
4082
  item: string;
3831
4083
  onRollback?: () => void;
3832
4084
  triggerClassName?: string;
4085
+ /** Icon-only, borderless trigger — for the record header's tool group. */
4086
+ compact?: boolean;
3833
4087
  inlineTableFields?: O2MFieldInfo[];
3834
4088
  /** Controlled mode (no trigger button) — open the sheet programmatically,
3835
4089
  * e.g. from a row Actions menu. */
@@ -4010,7 +4264,8 @@ declare interface RowRule {
4010
4264
  /** Route-change timing: from the navigation to a settled double-rAF frame. */
4011
4265
  export declare function rumRouteChange(pathname: string): void;
4012
4266
 
4013
- /** Convenience: run a resolved target (navigate or open the chat room). */
4267
+ /** Convenience: run a resolved target (navigate, open the chat room, or open
4268
+ * a foreign-app URL in a new tab). */
4014
4269
  export declare function runNotificationTarget(target: NotificationTarget, navigate: (path: string) => void): boolean;
4015
4270
 
4016
4271
  declare interface ScopeDimensionLite {
@@ -4316,6 +4571,20 @@ export declare function translateScopeValues(client: {
4316
4571
  target_collection: string;
4317
4572
  }, ids: Array<string | number>, valueField?: string): Promise<Array<string | number>>;
4318
4573
 
4574
+ /** What is unsaved right now — the leave-page prompt, the changes tray and
4575
+ * the host's own dirty indicator all read this one breakdown. */
4576
+ declare interface UnsavedSummary {
4577
+ fields: string[];
4578
+ rows: number;
4579
+ edits: number;
4580
+ deletes: number;
4581
+ links: number;
4582
+ unlinks: number;
4583
+ total: number;
4584
+ /** "2 fields, 3 lines, 1 link" — empty when clean. */
4585
+ text: string;
4586
+ }
4587
+
4319
4588
  /**
4320
4589
  * Base URL + auth for the few raw `fetch` calls (widgets, PDF blobs) that
4321
4590
  * can't go through `client.request`. Derives everything from the ambient
@@ -4508,6 +4777,13 @@ export declare function useItemLock(collection: string | undefined, item: string
4508
4777
  isAdmin: boolean;
4509
4778
  requestLock: () => Promise<void>;
4510
4779
  requesting: boolean;
4780
+ queue: LockQueueEntry[];
4781
+ myPosition: number | null;
4782
+ joinQueue: () => Promise<void>;
4783
+ leaveQueue: () => Promise<void>;
4784
+ joining: boolean;
4785
+ myNote: string;
4786
+ saveNote: (note: string) => Promise<void>;
4511
4787
  };
4512
4788
 
4513
4789
  /** Resolved item-link helpers honoring the host's itemUrl/openItem overrides. */