@nivaro/react 0.1.250 → 0.1.252

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
@@ -131,7 +131,7 @@ export declare function AlertRuleDrawer({ open, definitions, editRule, preselect
131
131
  declare type AlertUnit = 'percent' | 'dollar' | 'count' | 'days';
132
132
 
133
133
  declare type AllocateDrawerConfig = {
134
- /** Option collection browsed in the drawer (e.g. workflow_line_items). */
134
+ /** Option collection browsed in the drawer (e.g. request_lines). */
135
135
  collection: string;
136
136
  /** Grid FK column that receives the picked option's id. */
137
137
  target_field: string;
@@ -151,7 +151,7 @@ declare type AllocateDrawerConfig = {
151
151
  width?: number;
152
152
  }>;
153
153
  /** Group option rows under collapsible headers by this (dotted) path —
154
- * EFP grouped allocation lines by workflow. Groups start collapsed;
154
+ * e.g. allocation lines grouped by their parent record. Groups start collapsed;
155
155
  * groups containing an existing allocation start expanded. */
156
156
  group_by?: string;
157
157
  /** Per-row allocation ceiling formula (same tokens as column formulas incl.
@@ -421,7 +421,7 @@ declare type CascadeRule = {
421
421
  * the `replace` columns from the parent's defaults (same entry shape as
422
422
  * pinned_options — `when` gates read parent fields only). The swap runs the
423
423
  * grid's row rules with the child field as the changed field, so every
424
- * downstream derivation (category type, oracle category, task…) follows. */
424
+ * downstream derivation (category type, ERP category, task…) follows. */
425
425
  declare type CascadeSwapConfig = {
426
426
  keep?: string[];
427
427
  replace: Record<string, PinnedCfg[]>;
@@ -527,7 +527,7 @@ export declare interface ChatConfig {
527
527
  /** Label for a non-global, non-dm room key (null = uppercased key). */
528
528
  roomLabel?: (room: string) => string | null;
529
529
  /** Host route for a resolved record (entity rooms' "Open record" action) —
530
- * admin passes /collections/:c/:id, efp-new /records/:c/:id. Absent = the
530
+ * admin passes /collections/:c/:id, a portal its own record route. Absent = the
531
531
  * admin shape; return null = hide the action. */
532
532
  recordUrl?: (collection: string, id: string | number) => string | null;
533
533
  /** Host route for a session replay (the online list's admin-only "watch
@@ -635,7 +635,7 @@ export declare interface ChatProviderProps {
635
635
  * which is per-user by nature. Live delivery comes from a host-provided
636
636
  * realtime adapter, with polling fallbacks baked into every query.
637
637
  *
638
- * Ported from the EFP implementation with its semantics preserved:
638
+ * Ported from the original host implementation with its semantics preserved:
639
639
  * - DM room keys are 'dm:<A>:<B>' with UPPERCASED sorted uuids (MSSQL returns
640
640
  * uuids uppercased — a casing mismatch forks a second room).
641
641
  * - Read watermarks are serialized per room (markInFlight) because the reads
@@ -831,7 +831,7 @@ export declare function CollectionImportPanel({ initialJobId, onJobOpen }: {
831
831
  }): JSX.Element;
832
832
 
833
833
  /**
834
- * Realtime sprint client contract. A HOST (admin, efp-new) owns the actual
834
+ * Realtime sprint client contract. A HOST (admin, a portal app) owns the actual
835
835
  * Socket.io connection and provides this to shared components; components
836
836
  * that render without it degrade to polling exactly as before — the context
837
837
  * is always optional.
@@ -1711,14 +1711,28 @@ export declare type GridFlushContextValue = {
1711
1711
  unregister: (key: string) => void;
1712
1712
  };
1713
1713
 
1714
+ /** Row-editor action: spread a remaining amount across a row's empty fields
1715
+ * (a forecast year's open months). `remaining` is a grid-token expression —
1716
+ * `{{$parent.amount}} - {{$sum.total}}` — evaluated with the row
1717
+ * being edited included in the sums, so spreading once lands the balance on
1718
+ * the target fields and a second click has nothing left. */
1719
+ declare interface GridSpreadConfig {
1720
+ fields: string[];
1721
+ remaining: string;
1722
+ label?: string;
1723
+ /** Fill only empty/zero targets (default true); false = overwrite all. */
1724
+ only_empty?: boolean;
1725
+ format?: 'currency' | 'number';
1726
+ }
1727
+
1714
1728
  /**
1715
1729
  * A one-click rewrite of every row in the grid, driven by an aggregate of a
1716
1730
  * related collection.
1717
1731
  *
1718
- * EFP's "Close Out Lines" is one instance of this shape: for each REQ line,
1719
- * sum `open_unbilled_amount` across the PO lines pointing at it and, where the
1720
- * line covers that remainder, subtract it. Expressed as config rather than
1721
- * EFP code so any collection can do the same:
1732
+ * A "Close Out Lines" action is one instance of this shape: for each request
1733
+ * line, sum `open_unbilled_amount` across the PO lines pointing at it and, where
1734
+ * the line covers that remainder, subtract it. Expressed as config rather than
1735
+ * host code so any collection can do the same:
1722
1736
  *
1723
1737
  * {label:'Close Out Lines', relation:'po_line_items',
1724
1738
  * aggregate:{field:'open_unbilled_amount', op:'sum'},
@@ -1735,7 +1749,7 @@ export declare type GridFlushContextValue = {
1735
1749
  */
1736
1750
  declare interface GridStatConfig {
1737
1751
  label: string;
1738
- /** Expression — `{{$parent.requisition_amount}} - {{$sum.total}}`. */
1752
+ /** Expression — `{{$parent.amount}} - {{$sum.total}}`. */
1739
1753
  value: string;
1740
1754
  format?: 'currency' | 'number';
1741
1755
  /** 'danger' paints a negative result red (the "over" state). */
@@ -1745,7 +1759,7 @@ declare interface GridStatConfig {
1745
1759
  declare interface GridSumCapConfig {
1746
1760
  /** Column summed over the grid (write-computed columns are derived per row). */
1747
1761
  field: string;
1748
- /** Expression for the ceiling — `{{$parent.requisition_amount}}`. */
1762
+ /** Expression for the ceiling — `{{$parent.amount}}`. */
1749
1763
  cap: string;
1750
1764
  format?: 'currency' | 'number';
1751
1765
  label?: string;
@@ -1970,7 +1984,7 @@ declare interface ImportValidationReport {
1970
1984
  /**
1971
1985
  * Inbound integrations — every caller that is not a person's browser session,
1972
1986
  * as cards, plus the request log scoped to the picked one. This is the
1973
- * dedicated "external API logs" view: MWF's file pushes, LinX/Nuvolo GraphQL
1987
+ * dedicated "external API logs" view: partner file pushes, legacy GraphQL
1974
1988
  * writes, named API keys — who called, how often, what failed, and the exact
1975
1989
  * response body the caller got back.
1976
1990
  */
@@ -1978,7 +1992,7 @@ export declare function InboundCallersView({ hours: initialHours }: {
1978
1992
  hours?: number;
1979
1993
  }): JSX.Element;
1980
1994
 
1981
- 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, stats, sumCap, submissionErrors, prefillParentId, parentFieldKey, readOnly, emptyLabel, editorMode }: {
1995
+ 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, stats, sumCap, spreadRemaining, submissionErrors, prefillParentId, parentFieldKey, readOnly, emptyLabel, editorMode }: {
1982
1996
  relatedCollection: string;
1983
1997
  manyField: string;
1984
1998
  parentId: string;
@@ -2021,12 +2035,12 @@ export declare function InlineTableField({ relatedCollection, manyField, parentI
2021
2035
  rowFilter?: Record<string, unknown>;
2022
2036
  /** Values seeded onto every NEW row created from this grid (e.g. {is_osp: true}). */
2023
2037
  rowDefaults?: Record<string, unknown>;
2024
- /** EFP-style allocate drawer: browse all eligible options, type amounts. */
2038
+ /** Allocate drawer: browse all eligible options, type amounts. */
2025
2039
  allocateDrawer?: AllocateDrawerConfig;
2026
2040
  autoAllocate?: AutoAllocateConfig;
2027
2041
  /** Toolbar buttons that rewrite EVERY row in one go from an aggregate of a
2028
- * related collection — the generic form of EFP's "Close Out Lines" (reduce
2029
- * each REQ line by the open unbilled amount across its PO lines). */
2042
+ * related collection — the generic form of a "Close Out Lines" action (reduce
2043
+ * each request line by the open unbilled amount across its PO lines). */
2030
2044
  rowBulkActions?: RowBulkActionConfig[];
2031
2045
  /** Import template NAME — renders that template's upload button in this
2032
2046
  * grid's toolbar (existing records; wired to ItemEditForm's reimport flow). */
@@ -2051,6 +2065,7 @@ export declare function InlineTableField({ relatedCollection, manyField, parentI
2051
2065
  * grid (this row's draft included) would exceed `cap` (same tokens as
2052
2066
  * stats). The client twin of the server's sum_cap validation rule. */
2053
2067
  sumCap?: GridSumCapConfig | null;
2068
+ spreadRemaining?: GridSpreadConfig | null;
2054
2069
  /** Flag rows a failed ERP push rejected (options.submission_errors) — the
2055
2070
  * latest failed nivaro_erp_submissions row for the PARENT record is parsed
2056
2071
  * for "LineNumber N: reason" entries and matching rows tint red with the
@@ -2478,8 +2493,8 @@ declare interface MatrixEditorConfig {
2478
2493
  value_label?: string;
2479
2494
  value_format?: 'currency' | 'number';
2480
2495
  /** Scope pickers. `filter` narrows a picker's options; '$scope.<field>'
2481
- * tokens resolve from the other scope values (EFP: sub types limited to the
2482
- * chosen project's linked sub types) — unresolved tokens drop the filter. */
2496
+ * tokens resolve from the other scope values (e.g. a child picker limited to
2497
+ * the chosen parent's linked options) — unresolved tokens drop the filter. */
2483
2498
  scope_fields: Array<{
2484
2499
  field: string;
2485
2500
  collection: string;
@@ -2487,8 +2502,8 @@ declare interface MatrixEditorConfig {
2487
2502
  filter?: Record<string, unknown>;
2488
2503
  }>;
2489
2504
  /** Third level: sub-group options WITHIN a group section by a template over
2490
- * the option record (EFP region → core category → Labor/Materials/Equipment:
2491
- * label_template '{{core_category.name}}', row_label_template
2505
+ * the option record (e.g. group → parent category → sub-category rows:
2506
+ * label_template '{{parent_category.name}}', row_label_template
2492
2507
  * '{{sub_category.name}}'). Sub-headers aggregate their children and
2493
2508
  * collapse independently. */
2494
2509
  option_section?: {
@@ -2507,7 +2522,7 @@ declare interface MatrixEditorConfig {
2507
2522
  * and use [n] (e.g. '$project.funding_years[0].funding_year'). */
2508
2523
  scope_seeds?: Record<string, string>;
2509
2524
  /** Auto-fill a scope picker from another scope record when empty, e.g.
2510
- * {project_sub_type: '$project.default_sub_type'} (EFP default sub type). */
2525
+ * {sub_type: '$parent.default_sub_type'} (a parent record's default). */
2511
2526
  scope_defaults?: Record<string, string>;
2512
2527
  /** Seeds copied from the GROUP record onto rows created in that section,
2513
2528
  * {targetField: groupField} — e.g. {division: 'division'} (allocation rows
@@ -3340,7 +3355,7 @@ declare interface QueryTableColumn {
3340
3355
  * the formula over the summed values — weighted, not averaged). */
3341
3356
  sum?: boolean;
3342
3357
  /** 'progress' renders the value with a bar underneath, filled to
3343
- * value / progress_max (EFP PUB'd-vs-budget style). Over 100% turns red. */
3358
+ * value / progress_max (spend-vs-budget style). Over 100% turns red. */
3344
3359
  display?: 'progress';
3345
3360
  /** Denominator for display 'progress': a row field name or a {{col}} formula. */
3346
3361
  progress_max?: string;
@@ -3348,7 +3363,7 @@ declare interface QueryTableColumn {
3348
3363
  * rows — group cells spanning their children ('Jan' over Fcst/Act) — and
3349
3364
  * alternating groups get a faint band so wide grids stay scannable. */
3350
3365
  group?: string;
3351
- /** Cell text color (any CSS color) — EFP forecast/actual column tinting.
3366
+ /** Cell text color (any CSS color) — e.g. forecast/actual column tinting.
3352
3367
  * color_dark overrides in dark mode (defaults to color). Either may be a
3353
3368
  * role name — accent | ink | muted | positive | negative | warning | info —
3354
3369
  * instead of a hex; roles follow the host theme (see COLOR_ROLES). */
@@ -3358,7 +3373,7 @@ declare interface QueryTableColumn {
3358
3373
  * negative — a Remaining Budget column reads green until it goes red. */
3359
3374
  color_negative?: string;
3360
3375
  /** Second field rendered as a stacked line under the main value in the SAME
3361
- * cell (EFP month cells: Fcst over Act — halves the column count). Toggles
3376
+ * cell (e.g. month cells: Fcst over Act — halves the column count). Toggles
3362
3377
  * hide individual lines; the column collapses when both lines hide. */
3363
3378
  stack?: string;
3364
3379
  stack_color?: string;
@@ -3397,14 +3412,14 @@ declare interface QueryTableConfig {
3397
3412
  tree_strip_section_prefix?: boolean;
3398
3413
  /** Per-row numeric format override: name of a row field holding
3399
3414
  * 'currency' | 'number' — lets unit-count rows sit alongside dollar rows
3400
- * (EFP forecasting grid). Falls back to the column format. */
3415
+ * (forecasting-style grids). Falls back to the column format. */
3401
3416
  row_format_field?: string;
3402
3417
  /** Pin the first column and the header row while the grid scrolls — wide
3403
3418
  * month grids keep their row labels in view. */
3404
3419
  sticky?: boolean;
3405
3420
  /** Render zeroes as an em dash — de-noises mostly-empty month grids. */
3406
3421
  zero_dash?: boolean;
3407
- /** Column show/hide toggle pills above the table (EFP Actuals / Forecasts /
3422
+ /** Column show/hide toggle pills above the table (e.g. Actuals / Forecasts /
3408
3423
  * Calendar Year). A toggle turned OFF hides columns matched by exact
3409
3424
  * `fields` or a field-name `suffix` — unless `hide_when_on` inverts it
3410
3425
  * (Calendar Year ON hides the Prior/Carryover columns). */
@@ -3423,7 +3438,7 @@ declare interface QueryTableConfig {
3423
3438
  * year — highlight_group is dropped unless it equals the current year. */
3424
3439
  highlight_year_param?: string;
3425
3440
  /** Tiny colored line-name legend under stacked-column headers, e.g.
3426
- * ['Fcst', 'Act'] (EFP listHeaderSubLabel). */
3441
+ * ['Fcst', 'Act']. */
3427
3442
  stack_legend?: [string, string];
3428
3443
  /** Pivot long rows into month columns BEFORE rendering. Rows sharing the
3429
3444
  * same key fields merge into one row with Jan…Dec (+ optional
@@ -3440,7 +3455,7 @@ declare interface QueryTableConfig {
3440
3455
  year_param?: string;
3441
3456
  /** Add a Total column summing every pivoted cell. */
3442
3457
  total?: boolean;
3443
- /** Render a Months/Quarters toggle above the table (EFP quarterly view).
3458
+ /** Render a Months/Quarters toggle above the table (quarterly view).
3444
3459
  * Quarter columns sum their three months — same drill/total math. */
3445
3460
  quarter_toggle?: boolean;
3446
3461
  /** Colour role/hex for the generated period + year columns, an optional
@@ -3481,8 +3496,8 @@ declare interface QueryWidgetConfig {
3481
3496
  }>;
3482
3497
  /** Toolbar action buttons running a (write) custom query — params support
3483
3498
  * the same tokens as sheets ('$filters.<param>' / '$param.<name>' /
3484
- * '$rows.<field>'); an unresolved param blocks the run with a message.
3485
- * EFP 'Run Reforecasting'. */
3499
+ * '$rows.<field>'); an unresolved param blocks the run with a message
3500
+ * (e.g. a "recalculate" stored-procedure button). */
3486
3501
  actions?: Array<{
3487
3502
  label: string;
3488
3503
  query_slug: string;
@@ -3502,7 +3517,7 @@ declare type QueryWidgetFilter = {
3502
3517
  /** Option fetch cap (default 500) — bump for big pick lists (projects). */
3503
3518
  limit?: number;
3504
3519
  /** Pre-selected values on load. '$current_year' resolves to the current
3505
- * calendar year (EFP default-funding-year behavior). */
3520
+ * calendar year (default-year behavior). */
3506
3521
  default_values?: Array<string | number>;
3507
3522
  };
3508
3523
 
@@ -3529,13 +3544,13 @@ declare interface QueryWidgetStat {
3529
3544
  };
3530
3545
  /** Card tint (any CSS color, e.g. '#f9fbd1'). */
3531
3546
  bg?: string;
3532
- /** Only sum rows matching these field values (equality AND) — EFP
3533
- * forecasting stats scope to the Workflow Forecast section. */
3547
+ /** Only sum rows matching these field values (equality AND) — e.g. scope a
3548
+ * stat to one tree section of the table. */
3534
3549
  row_match?: Record<string, unknown>;
3535
3550
  /** Delta stat: value = sum(field) − sum(field_subtract); positive values
3536
3551
  * render with a leading '+'. */
3537
3552
  field_subtract?: string;
3538
- /** EFP stat-card accent: colored top border + value (accent_dark in dark
3553
+ /** Stat-card accent: colored top border + value (accent_dark in dark
3539
3554
  * mode; accent_negative when a delta goes negative). Each may be a role name
3540
3555
  * — accent | positive | negative | info … — see QueryTable COLOR_ROLES. */
3541
3556
  accent?: string;
@@ -3864,7 +3879,7 @@ declare interface RecordGridEditorConfig {
3864
3879
  query_slug: string;
3865
3880
  params?: Record<string, unknown>;
3866
3881
  };
3867
- /** Nested map editors opened from toolbar buttons (EFP Manage Cost Tables) —
3882
+ /** Nested map editors opened from toolbar buttons (e.g. cost tables) —
3868
3883
  * receive the current scope; enabled once `require_scope` fields are set. */
3869
3884
  toolbar_editors?: Array<{
3870
3885
  button_label: string;
@@ -3880,7 +3895,7 @@ export declare function RecordGridWidgetBody({ widget }: {
3880
3895
  widget: PageRendererWidget;
3881
3896
  }): JSX.Element;
3882
3897
 
3883
- export declare function RecordReadView({ collection, itemId, layoutData, flush, renderSlot, integrityMarks, renderGrid, gridCounts }: {
3898
+ export declare function RecordReadView({ collection, itemId, layoutData, flush, renderSlot, integrityMarks, renderGrid, onEditSection, gridCounts }: {
3884
3899
  collection: string;
3885
3900
  itemId: string;
3886
3901
  layoutData: ReadViewLayout;
@@ -3889,11 +3904,15 @@ export declare function RecordReadView({ collection, itemId, layoutData, flush,
3889
3904
  /**
3890
3905
  * Page-slot sentinels (`__comments__`, `__tasks__`, …) the host wants to
3891
3906
  * keep LIVE inside the read view — Summary mode is read-only for the
3892
- * record's fields, but notes and tasks stay editable (Rob). Return null to
3907
+ * record's fields, but notes and tasks stay editable. Return null to
3893
3908
  * skip a slot. A slot placed in a section renders inside that card; the
3894
3909
  * rest render full-width under the cards, in layout order.
3895
3910
  */
3896
3911
  renderSlot?: (key: string, assignment: LayoutAssignment) => ReactNode;
3912
+ /** Summary-mode hosts: a pencil on every section header that hands back the
3913
+ * group key + its first field so the host can flip to Edit and land there
3914
+ * (whole-form flip + scroll was the only way in). */
3915
+ onEditSection?: (groupKey: string, firstField: string | null) => void;
3897
3916
  /**
3898
3917
  * Summary mode hides the data-integrity banner but must not hide the
3899
3918
  * problem: with this on, every field (or child grid) that carries a
@@ -3974,7 +3993,7 @@ export declare function RelationCombobox({ collection, value, onChange, disabled
3974
3993
  value: unknown;
3975
3994
  onChange: (v: unknown) => void;
3976
3995
  /** A "floating" option shown FIRST regardless of search or sort — the
3977
- * project's default CIFA for a materials line, say. Label = the option's
3996
+ * parent's default item for a materials line, say. Label = the option's
3978
3997
  * own display label; `tag` is the small badge beside it ("Default"). */
3979
3998
  pinned?: {
3980
3999
  id: unknown;
@@ -4129,7 +4148,7 @@ declare interface ReviewListConfig {
4129
4148
  /** POST this endpoint with {ids, status, note, workflow_id} instead of
4130
4149
  * per-row PATCHes — lets a deployment route decisions through an
4131
4150
  * endpoint that owns stamping, authorization, notes and notifications
4132
- * (EFP: /efp/invoice-approvals/decide). */
4151
+ * (e.g. an extension's /decide route). */
4133
4152
  action_endpoint?: string | null;
4134
4153
  };
4135
4154
  }
@@ -4267,8 +4286,8 @@ declare interface RowLint {
4267
4286
  * "Which related record is this row matched to, and if none, why not?"
4268
4287
  *
4269
4288
  * Config-driven (`options.row_match_panel` on an inline-table field): the
4270
- * O2M alias on the child that points at the matched records (a workflow
4271
- * line's `po_line_items`), the columns to show for a match, and — for the
4289
+ * O2M alias on the child that points at the matched records (a request
4290
+ * line's PO lines), the columns to show for a match, and — for the
4272
4291
  * unmatched case — how to find the nearest candidate among a filtered set
4273
4292
  * (the record's linked purchase orders) and which keys the match rule
4274
4293
  * compares. `useRowMatches` resolves this ONCE for every saved row of a
@@ -4276,7 +4295,7 @@ declare interface RowLint {
4276
4295
  * full panel with the reason a match fails.
4277
4296
  */
4278
4297
  declare interface RowMatchPanelConfig {
4279
- /** O2M alias on the child collection (e.g. workflow_line_items.po_line_items). */
4298
+ /** O2M alias on the child collection (e.g. request_lines.po_lines). */
4280
4299
  relation: string;
4281
4300
  /** Panel heading. Default "Match". */
4282
4301
  title?: string;
@@ -4792,7 +4811,7 @@ text: string;
4792
4811
  export declare function useElapsedLoading(loading: boolean, thresholdMs?: number): number | null;
4793
4812
 
4794
4813
  /**
4795
- * Resolves an entity room ('wf:CR26-76773') to the record's URL, host-routed
4814
+ * Resolves an entity room ('<prefix>:<token>') to the record's URL, host-routed
4796
4815
  * via cfg.recordUrl. The room-type registry maps the prefix to a collection +
4797
4816
  * match field; when the match field isn't the PK the record is looked up by
4798
4817
  * it (readable by construction — room visibility already required record