@nivaro/react 0.1.236 → 0.1.237

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,14 @@ 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
+ }
2326
+
2327
+ declare interface LockQueueEntry {
2328
+ user: string;
2329
+ name: string | null;
2330
+ requested_at: string;
2285
2331
  }
2286
2332
 
2287
2333
  export declare interface M2MStagingCtx {
@@ -2579,6 +2625,159 @@ export declare function NivaroProvider({ client, children }: {
2579
2625
  */
2580
2626
  export declare function normalizeFieldType(rawType: string, iface: string | null, relation: FormFieldDescriptor['relation']): FormFieldType;
2581
2627
 
2628
+ export declare function NotificationActions({ actions, notificationId, onDone, onError, size, className }: NotificationActionsProps): JSX.Element | null;
2629
+
2630
+ /** An inline action the server says is safe to fire from a click. */
2631
+ export declare interface NotificationActionSpec {
2632
+ key: string;
2633
+ label: string;
2634
+ method: 'POST' | 'PATCH';
2635
+ endpoint: string;
2636
+ body?: Record<string, unknown>;
2637
+ mark_read?: boolean;
2638
+ /** The action takes a line of text (a reply, a note): render an input and
2639
+ * send its value as body[field]. */
2640
+ input?: {
2641
+ field: string;
2642
+ placeholder: string;
2643
+ submit_label?: string;
2644
+ };
2645
+ }
2646
+
2647
+ /**
2648
+ * The inline action pills a notification row offers (server-described:
2649
+ * endpoint + body, domain-blind). One-click actions fire straight away;
2650
+ * actions carrying `input` (Reply, Comment on this) open an inline text box
2651
+ * under the row and send its value as body[field]. Marks the row read when
2652
+ * the action says so, then invalidates the notification queries.
2653
+ */
2654
+ declare interface NotificationActionsProps {
2655
+ actions: NotificationActionSpec[];
2656
+ notificationId: number;
2657
+ /** Called after any successful action (hosts refresh their own lists). */
2658
+ onDone?: () => void;
2659
+ onError?: (message: string) => void;
2660
+ size?: 'sm' | 'xs';
2661
+ className?: string;
2662
+ }
2663
+
2664
+ export declare function NotificationAnalyticsView({ className }: {
2665
+ className?: string;
2666
+ }): JSX.Element;
2667
+
2668
+ /**
2669
+ * The Nivaro notification bell — the same setup the admin uses: badge that
2670
+ * counts what NEEDS YOU (Critical + Needs-you lanes, never FYI), lane tabs,
2671
+ * rows grouped by record (five updates on one workflow read as one story),
2672
+ * group-level open + mark-read, inline server-approved actions including
2673
+ * reply boxes, per-row delivery chips (where did this go?), and
2674
+ * click-through routing via the shared notification-target resolver. Needs
2675
+ * `<NivaroProvider>`.
2676
+ */
2677
+ export declare function NotificationBell({ routes, onNavigate, app, subscribe, buttonClassName, panelClassName, beforeList, extraBadge, mailLogUrl, renderTrigger, allPath, onActionError, panelPlacement }: NotificationBellProps): JSX.Element;
2678
+
2679
+ export declare interface NotificationBellProps {
2680
+ /** Where each notification kind lands in the host app. */
2681
+ routes: NotificationRouteMap;
2682
+ /** Host router push — the bell never imports a router itself. */
2683
+ onNavigate: (path: string) => void;
2684
+ /** Which app's routes the server should resolve fallback urls for (?app=…). */
2685
+ app?: 'portal' | 'admin';
2686
+ /**
2687
+ * Realtime hookup: invoke the callback whenever a notification arrives and
2688
+ * return an unsubscribe. The bell refreshes its queries; anything else
2689
+ * (sounds, toasts) stays in the host's handler.
2690
+ */
2691
+ subscribe?: (onNew: () => void) => () => void;
2692
+ /** Extra classes for the trigger button (host header styling). */
2693
+ buttonClassName?: string;
2694
+ /** Extra classes for the popup panel (position/size overrides). */
2695
+ panelClassName?: string;
2696
+ /** Rendered above the tab strip inside the panel (host strips such as
2697
+ * "3 access requests waiting on an admin"). */
2698
+ beforeList?: ReactNode;
2699
+ /** Added to the badge count (host-side items the inbox does not hold). */
2700
+ extraBadge?: number;
2701
+ /** Host route for a mail-log row — turns the email delivery chip into a
2702
+ * link. Absent = chips are plain. */
2703
+ mailLogUrl?: (mailLogId: number) => string | null;
2704
+ /** Replace the trigger button entirely (the popup still positions against
2705
+ * the wrapper). */
2706
+ renderTrigger?: (state: {
2707
+ open: boolean;
2708
+ badge: number;
2709
+ toggle: () => void;
2710
+ }) => ReactNode;
2711
+ /** Path of the full notifications page — renders a "See all" footer link. */
2712
+ allPath?: string | null;
2713
+ /** Called with an error message when an inline action fails. */
2714
+ onActionError?: (message: string) => void;
2715
+ /** Where the panel opens relative to the trigger. 'below' (default) keeps
2716
+ * it inside the trigger's tree; 'right' portals it to document.body and
2717
+ * positions it beside the trigger — for a sidebar rail whose overflow
2718
+ * would clip an inline panel. */
2719
+ panelPlacement?: 'below' | 'right';
2720
+ }
2721
+
2722
+ export declare function NotificationCenterView({ routes, onNavigate, app, mailLogUrl, onNotice, onError, className }: NotificationCenterViewProps): JSX.Element;
2723
+
2724
+ export declare interface NotificationCenterViewProps {
2725
+ routes: NotificationRouteMap;
2726
+ onNavigate: (path: string) => void;
2727
+ app?: 'portal' | 'admin';
2728
+ mailLogUrl?: (mailLogId: number) => string | null;
2729
+ /** Toast hooks — hosts wire their own toaster. */
2730
+ onNotice?: (message: string) => void;
2731
+ onError?: (message: string) => void;
2732
+ className?: string;
2733
+ }
2734
+
2735
+ /** Per-channel delivery outcome recorded on the row (GET /notifications
2736
+ * `delivery`). Rows from before delivery tracking carry only in-app. */
2737
+ export declare interface NotificationDeliveryRecord {
2738
+ inapp?: {
2739
+ status: 'delivered' | 'skipped';
2740
+ reason?: string;
2741
+ };
2742
+ push?: {
2743
+ status: 'sent' | 'no_subscription' | 'skipped' | 'failed';
2744
+ reason?: string;
2745
+ at?: string;
2746
+ };
2747
+ email?: {
2748
+ status: 'sent' | 'deferred' | 'dropped' | 'failed' | 'off' | 'not_requested' | 'no_address' | 'unconfigured';
2749
+ reason?: string;
2750
+ mail_log_id?: number | null;
2751
+ at?: string;
2752
+ };
2753
+ sms?: {
2754
+ status: 'sent' | 'failed' | 'skipped' | 'not_requested';
2755
+ reason?: string;
2756
+ };
2757
+ escalation?: {
2758
+ push_at?: string;
2759
+ email_at?: string;
2760
+ email_log_id?: number | null;
2761
+ };
2762
+ }
2763
+
2764
+ /** Inbox lane — Critical and Needs-you are what the badge counts. */
2765
+ export declare type NotificationLane = 'critical' | 'needs_you' | 'fyi';
2766
+
2767
+ /** The notification row shape every surface receives (GET /notifications). */
2768
+ export declare interface NotificationLike {
2769
+ collection?: string | null;
2770
+ item?: string | null;
2771
+ target?: NotificationTargetSpec | null;
2772
+ /** Server-resolved URL for the recipient's app — the fallback when this
2773
+ * host has no route for the kind (opens in a new tab when foreign). */
2774
+ url?: string | null;
2775
+ actions?: NotificationActionSpec[] | null;
2776
+ lane?: NotificationLane | null;
2777
+ category?: string | null;
2778
+ delivery?: NotificationDeliveryRecord | null;
2779
+ }
2780
+
2582
2781
  /**
2583
2782
  * Every in-app notification must land somewhere meaningful — this is the ONE
2584
2783
  * resolver both bells, the notifications page, and My Work use to decide what
@@ -2603,6 +2802,11 @@ export declare interface NotificationRouteMap {
2603
2802
  alerts?: () => string | null;
2604
2803
  imports?: () => string | null;
2605
2804
  issues?: () => string | null;
2805
+ /** Task list (a task-kind row); hosts without one fall back to my_work / url. */
2806
+ tasks?: (id?: string | null) => string | null;
2807
+ approvals?: () => string | null;
2808
+ access_requests?: () => string | null;
2809
+ my_work?: () => string | null;
2606
2810
  }
2607
2811
 
2608
2812
  export declare function NotificationRulesCard(): JSX.Element;
@@ -2644,8 +2848,37 @@ export declare type NotificationTarget = {
2644
2848
  } | {
2645
2849
  type: 'chat';
2646
2850
  room: string;
2851
+ } | {
2852
+ type: 'external';
2853
+ url: string;
2647
2854
  } | null;
2648
2855
 
2856
+ /** Server-side target spec (services/notification-target.ts) — what the
2857
+ * notification is about and what a click should offer. */
2858
+ export declare interface NotificationTargetSpec {
2859
+ kind: 'record' | 'task' | 'approval' | 'access_request' | 'sla' | 'chat' | 'queue' | 'report' | 'alerts' | 'issue' | 'import' | 'dashboard' | 'my_work' | 'home' | 'external';
2860
+ collection?: string | null;
2861
+ id?: string | number | null;
2862
+ room?: string | null;
2863
+ query?: string | null;
2864
+ focus?: string | null;
2865
+ tab?: string | null;
2866
+ url?: string | null;
2867
+ action?: 'open' | 'complete' | 'acknowledge' | 'review' | 'approve' | 'reply';
2868
+ task_id?: string | number | null;
2869
+ instance_id?: string | number | null;
2870
+ }
2871
+
2872
+ export declare function NotificationTemplatesView({ onNotice, onError, className, embedded }: NotificationTemplatesViewProps): JSX.Element;
2873
+
2874
+ declare interface NotificationTemplatesViewProps {
2875
+ onNotice?: (message: string) => void;
2876
+ onError?: (message: string) => void;
2877
+ className?: string;
2878
+ /** Embedded inside another page (no page header). */
2879
+ embedded?: boolean;
2880
+ }
2881
+
2649
2882
  export declare function NumberField({ field, value, onChange, error, disabled, readOnly, inputId, errorId }: FieldComponentProps): JSX.Element;
2650
2883
 
2651
2884
  /** Intl options for a numeric field, honoring its configured precision. */
@@ -2847,12 +3080,14 @@ declare type PipelineOwnerDimension = {
2847
3080
  cascade?: DimensionCascadeRule[] | null;
2848
3081
  };
2849
3082
 
2850
- export declare function PipelinePanel({ collection, item, defaultExpanded, title, showApprovalChain, hideActionsCollapsed, hideActionsExpanded, onBeforeTransition, addendumPending, addendumView }: {
3083
+ export declare function PipelinePanel({ collection, item, defaultExpanded, title, showApprovalChain, hideActionsCollapsed, hideActionsExpanded, onBeforeTransition, addendumPending, addendumView, asRole }: {
2851
3084
  collection: string;
2852
3085
  item: string;
2853
3086
  defaultExpanded?: boolean;
2854
3087
  title?: string;
2855
3088
  showApprovalChain?: boolean;
3089
+ /** Admin "view as role" (#8): evaluate available transitions for this role instead of the caller. */
3090
+ asRole?: string | null;
2856
3091
  /** Layout-configurable: suppress the transition buttons inside the slot
2857
3092
  * (collapsed header row / expanded body) — redundant when the record header
2858
3093
  * already renders PipelineTransitionButtons. */
@@ -3450,9 +3685,11 @@ export declare interface RealtimeAdapter {
3450
3685
 
3451
3686
  export declare const RealtimeContext: Context<RealtimeAdapter | null>;
3452
3687
 
3453
- export declare function RecordChatActions({ collection, itemDraft }: {
3688
+ export declare function RecordChatActions({ collection, itemDraft, compact }: {
3454
3689
  collection: string;
3455
3690
  itemDraft: Record<string, unknown>;
3691
+ /** Icon-only, borderless — for the record header's tool group. */
3692
+ compact?: boolean;
3456
3693
  }): JSX.Element | null;
3457
3694
 
3458
3695
  export declare function RecordDrilldownSheet({ collection, itemId, layoutId, rootLayoutSlug, width, title, stack: controlledStack, onPush, onPop, onClose }: {
@@ -3554,10 +3791,12 @@ export declare function RecordGridWidgetBody({ widget }: {
3554
3791
  widget: PageRendererWidget;
3555
3792
  }): JSX.Element;
3556
3793
 
3557
- export declare function RecordReadView({ collection, itemId, layoutData }: {
3794
+ export declare function RecordReadView({ collection, itemId, layoutData, flush }: {
3558
3795
  collection: string;
3559
3796
  itemId: string;
3560
3797
  layoutData: ReadViewLayout;
3798
+ /** Host already pads and scrolls the body (the record form's read mode). */
3799
+ flush?: boolean;
3561
3800
  }): JSX.Element;
3562
3801
 
3563
3802
  /**
@@ -3588,10 +3827,12 @@ export declare function RecordRecapStrip({ collection, itemId }: {
3588
3827
  * Transitions never fire the items-service update hook (state mirrors are raw
3589
3828
  * writes), so the two rows can't double-notify.
3590
3829
  */
3591
- export declare function RecordSubscribeButton({ collection, itemId, recordLabel }: {
3830
+ export declare function RecordSubscribeButton({ collection, itemId, recordLabel, compact }: {
3592
3831
  collection: string;
3593
3832
  itemId: string;
3594
3833
  recordLabel?: string;
3834
+ /** Icon-only, borderless — for the record header's tool group. */
3835
+ compact?: boolean;
3595
3836
  }): JSX.Element;
3596
3837
 
3597
3838
  /** Register a detail opener for a catalog collection. Returns an unregister
@@ -3726,6 +3967,15 @@ export declare function resolveCollectionIcon(iconName: string | null | undefine
3726
3967
 
3727
3968
  export declare function resolveNotificationTarget(collection: string | null | undefined, item: string | null | undefined, routes: NotificationRouteMap): NotificationTarget;
3728
3969
 
3970
+ /**
3971
+ * Structured resolution: the server's target spec mapped onto THIS host's
3972
+ * routes (kind by kind), falling back to the server-resolved `url` — same
3973
+ * origin → in-app path, foreign origin → external (new tab) — and finally to
3974
+ * the legacy collection + item resolution. A row still resolving to null
3975
+ * renders as plain text.
3976
+ */
3977
+ export declare function resolveNotificationTargetFor(n: NotificationLike, routes: NotificationRouteMap): NotificationTarget;
3978
+
3729
3979
  declare type ReviewListColumnFormat = 'currency' | 'number' | 'date' | 'datetime' | 'flag';
3730
3980
 
3731
3981
  declare interface ReviewListColumnSpec {
@@ -3825,11 +4075,13 @@ declare interface ReviewListWidgetProps {
3825
4075
  emptyLabel?: string;
3826
4076
  }
3827
4077
 
3828
- export declare function RevisionsPanel({ collection, item, onRollback, triggerClassName, inlineTableFields, open, onOpenChange }: {
4078
+ export declare function RevisionsPanel({ collection, item, onRollback, triggerClassName, inlineTableFields, open, onOpenChange, compact }: {
3829
4079
  collection: string;
3830
4080
  item: string;
3831
4081
  onRollback?: () => void;
3832
4082
  triggerClassName?: string;
4083
+ /** Icon-only, borderless trigger — for the record header's tool group. */
4084
+ compact?: boolean;
3833
4085
  inlineTableFields?: O2MFieldInfo[];
3834
4086
  /** Controlled mode (no trigger button) — open the sheet programmatically,
3835
4087
  * e.g. from a row Actions menu. */
@@ -4010,7 +4262,8 @@ declare interface RowRule {
4010
4262
  /** Route-change timing: from the navigation to a settled double-rAF frame. */
4011
4263
  export declare function rumRouteChange(pathname: string): void;
4012
4264
 
4013
- /** Convenience: run a resolved target (navigate or open the chat room). */
4265
+ /** Convenience: run a resolved target (navigate, open the chat room, or open
4266
+ * a foreign-app URL in a new tab). */
4014
4267
  export declare function runNotificationTarget(target: NotificationTarget, navigate: (path: string) => void): boolean;
4015
4268
 
4016
4269
  declare interface ScopeDimensionLite {
@@ -4316,6 +4569,20 @@ export declare function translateScopeValues(client: {
4316
4569
  target_collection: string;
4317
4570
  }, ids: Array<string | number>, valueField?: string): Promise<Array<string | number>>;
4318
4571
 
4572
+ /** What is unsaved right now — the leave-page prompt, the changes tray and
4573
+ * the host's own dirty indicator all read this one breakdown. */
4574
+ declare interface UnsavedSummary {
4575
+ fields: string[];
4576
+ rows: number;
4577
+ edits: number;
4578
+ deletes: number;
4579
+ links: number;
4580
+ unlinks: number;
4581
+ total: number;
4582
+ /** "2 fields, 3 lines, 1 link" — empty when clean. */
4583
+ text: string;
4584
+ }
4585
+
4319
4586
  /**
4320
4587
  * Base URL + auth for the few raw `fetch` calls (widgets, PDF blobs) that
4321
4588
  * can't go through `client.request`. Derives everything from the ambient
@@ -4508,6 +4775,13 @@ export declare function useItemLock(collection: string | undefined, item: string
4508
4775
  isAdmin: boolean;
4509
4776
  requestLock: () => Promise<void>;
4510
4777
  requesting: boolean;
4778
+ queue: LockQueueEntry[];
4779
+ myPosition: number | null;
4780
+ joinQueue: () => Promise<void>;
4781
+ leaveQueue: () => Promise<void>;
4782
+ joining: boolean;
4783
+ myNote: string;
4784
+ saveNote: (note: string) => Promise<void>;
4511
4785
  };
4512
4786
 
4513
4787
  /** Resolved item-link helpers honoring the host's itemUrl/openItem overrides. */