@toclocoinc/lattice-grid 1.37.0 → 1.38.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 (69) hide show
  1. package/README.md +1 -1
  2. package/docs/API.html +182 -6
  3. package/docs/api-detail.html +44 -1
  4. package/lattice-grid.d.ts +350 -10
  5. package/lattice-grid.esm.min.js +693 -40
  6. package/lattice-grid.min.cjs +690 -40
  7. package/lattice-grid.min.css +1 -1
  8. package/lattice-grid.min.js +690 -40
  9. package/modules/angular.esm.min.js +2 -2
  10. package/modules/angular.min.cjs +2 -2
  11. package/modules/angular.min.js +2 -2
  12. package/modules/chart-alluvial.esm.min.js +1 -1
  13. package/modules/chart-arc.esm.min.js +1 -1
  14. package/modules/chart-bubblemap.esm.min.js +1 -1
  15. package/modules/chart-bump.esm.min.js +1 -1
  16. package/modules/chart-calendar.esm.min.js +1 -1
  17. package/modules/chart-decomposition.esm.min.js +1 -1
  18. package/modules/chart-diverging.esm.min.js +1 -1
  19. package/modules/chart-dumbbell.esm.min.js +1 -1
  20. package/modules/chart-fan.esm.min.js +1 -1
  21. package/modules/chart-hexbin.esm.min.js +1 -1
  22. package/modules/chart-hexmap.esm.min.js +1 -1
  23. package/modules/chart-icicle.esm.min.js +1 -1
  24. package/modules/chart-parallel.esm.min.js +1 -1
  25. package/modules/chart-ridgeline.esm.min.js +1 -1
  26. package/modules/chart-roc.esm.min.js +1 -1
  27. package/modules/chart-slope.esm.min.js +1 -1
  28. package/modules/chart-splom.esm.min.js +1 -1
  29. package/modules/chart-waffle.esm.min.js +1 -1
  30. package/modules/charts.esm.min.js +450 -7
  31. package/modules/charts.min.cjs +450 -7
  32. package/modules/charts.min.js +450 -7
  33. package/modules/data-router.esm.min.js +4 -4
  34. package/modules/data-router.min.cjs +4 -4
  35. package/modules/data-router.min.js +4 -4
  36. package/modules/devtools.esm.min.js +2 -2
  37. package/modules/devtools.min.cjs +2 -2
  38. package/modules/devtools.min.js +2 -2
  39. package/modules/dhtmlx-compat.esm.min.js +4 -4
  40. package/modules/dhtmlx-compat.min.cjs +4 -4
  41. package/modules/dhtmlx-compat.min.js +4 -4
  42. package/modules/gantt.esm.min.js +714 -16
  43. package/modules/gantt.min.cjs +712 -16
  44. package/modules/gantt.min.js +712 -16
  45. package/modules/htmx.esm.min.js +687 -40
  46. package/modules/htmx.min.cjs +687 -40
  47. package/modules/htmx.min.js +687 -40
  48. package/modules/kanban.esm.min.js +379 -5
  49. package/modules/kanban.min.cjs +379 -5
  50. package/modules/kanban.min.js +379 -5
  51. package/modules/kpi.esm.min.js +4 -4
  52. package/modules/kpi.min.cjs +4 -4
  53. package/modules/kpi.min.js +4 -4
  54. package/modules/mock-socket.esm.min.js +2 -2
  55. package/modules/mock-socket.min.cjs +2 -2
  56. package/modules/mock-socket.min.js +2 -2
  57. package/modules/react.esm.min.js +2 -2
  58. package/modules/react.min.cjs +2 -2
  59. package/modules/react.min.js +2 -2
  60. package/modules/svelte.esm.min.js +2 -2
  61. package/modules/svelte.min.cjs +2 -2
  62. package/modules/svelte.min.js +2 -2
  63. package/modules/vue.esm.min.js +2 -2
  64. package/modules/vue.min.cjs +2 -2
  65. package/modules/vue.min.js +2 -2
  66. package/modules/webcomponent.esm.min.js +690 -40
  67. package/modules/webcomponent.min.cjs +690 -40
  68. package/modules/webcomponent.min.js +690 -40
  69. package/package.json +1 -1
package/lattice-grid.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.37.0, type declarations
2
+ * Lattice Grid 1.38.0, type declarations
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -1890,6 +1890,24 @@ export interface GridConfig {
1890
1890
  * menu offers Paste, Clear and Fill down.
1891
1891
  */
1892
1892
  contextMenu?: boolean | ((p: CellMenuParams, defaults: MenuItem[]) => MenuItem[] | void);
1893
+ /**
1894
+ * Bringing rows in from a file, the clipboard or a drop (§14, the mirror of
1895
+ * export). `true` adds a "Import rows from CSV…" item to the cell menu, makes
1896
+ * the grid a drop target for `.csv`/`.tsv` files, and reads a pasted
1897
+ * spreadsheet block, each opening a preview the user confirms. An object tunes
1898
+ * the affordances. Off by default; the `grid.import` API is always present.
1899
+ * Import is a client-side data operation, so it applies to a memory grid.
1900
+ */
1901
+ import?: boolean | ImportSettings;
1902
+ /**
1903
+ * Enable the built-in row-delete gesture (§18.4, BACKLOG-0000968) — the
1904
+ * Delete/Backspace key on selected rows and a "Delete row" cell-menu item —
1905
+ * and the `grid.edit.deleteRows` API. Off by default, because deleting data
1906
+ * on a keystroke is destructive and opt-in. Every deletion flows through the
1907
+ * cancellable `beforeDelete` event, so a handler can confirm or veto it, on a
1908
+ * memory-source grid as well as a remote one.
1909
+ */
1910
+ rowDelete?: boolean;
1893
1911
  /**
1894
1912
  * The header's 3-dot menu, and the right-click menu on a column heading.
1895
1913
  * `false` suppresses both. A function supplies custom items, receiving the
@@ -2547,8 +2565,8 @@ export interface StatisticsApi {
2547
2565
  * verdict from nowhere. Non-numeric columns are returned under `skipped`.
2548
2566
  */
2549
2567
  anomalies(opts?: { columns?: string[];
2550
- method?: 'modifiedZScore' | 'iqr' | 'mahalanobis';
2551
- threshold?: number; k?: number; p?: number }): AnomalyReport;
2568
+ method?: 'modifiedZScore' | 'iqr' | 'mahalanobis' | 'rollingModifiedZScore' | 'rollingIqr';
2569
+ threshold?: number; k?: number; p?: number; windowLen?: number; minPeriods?: number }): AnomalyReport;
2552
2570
  /**
2553
2571
  * Which columns differ most between the filtered subset and the whole
2554
2572
  * population it was drawn from, ranked by effect size — never by a p-value.
@@ -2820,6 +2838,52 @@ export function mahalanobis(
2820
2838
  distances: (number | null)[]; squared: (number | null)[]; flags: boolean[];
2821
2839
  flagged: number } | null;
2822
2840
 
2841
+ /**
2842
+ * The rolling (windowed) anomaly methods (BACKLOG-0000954): the robust modified
2843
+ * z-score and Tukey's IQR fences, each computed over a trailing window rather
2844
+ * than the whole series, for live monitoring where a drift or a shifted regime
2845
+ * must not poison a global baseline.
2846
+ */
2847
+ export const ROLLING_ANOMALY_METHODS: readonly ('rollingModifiedZScore' | 'rollingIqr')[];
2848
+
2849
+ /**
2850
+ * Rolling (windowed) anomaly detection (BACKLOG-0000954): judge every reading
2851
+ * against a causal trailing window ending at it — the current point and the
2852
+ * `window − 1` before it — so a spike is caught against its recent neighbours and
2853
+ * a slow drift does not permanently poison the baseline. With a window at least
2854
+ * as long as the series (and `minPeriods` of 1) the last point's score equals the
2855
+ * static {@link modifiedZScores} score. A non-finite reading, a too-short window
2856
+ * (`minPeriods`) or a zero-MAD window yields a null score and no flag.
2857
+ */
2858
+ export function rollingAnomalies(
2859
+ values: ArrayLike<number>,
2860
+ opts?: {
2861
+ method?: 'rollingModifiedZScore' | 'rollingIqr';
2862
+ windowLen?: number; threshold?: number; k?: number; minPeriods?: number;
2863
+ },
2864
+ ): { method: string; windowLen: number; minPeriods: number; threshold: number; k: number;
2865
+ scores: (number | null)[]; flags: boolean[]; flagged: number };
2866
+
2867
+ /**
2868
+ * Build a Data Router alert condition from an anomaly detector (BACKLOG-0000954):
2869
+ * a `(rows) => signal` for the router's existing `router.alert(value, condition,
2870
+ * handler)` (BACKLOG-0000909), so live monitoring reuses the router's
2871
+ * partitioning, debounce and rising-edge re-arm rather than duplicating any of
2872
+ * it. Reads one numeric `field` off each row, runs the chosen detector, and
2873
+ * returns the flagged rows and scores when anything is anomalous or `false` when
2874
+ * nothing is. `orderBy` names the axis rolling methods window on; `latest` signals
2875
+ * only when the newest reading is the anomaly.
2876
+ */
2877
+ export function anomalyCondition(
2878
+ opts: {
2879
+ field: string;
2880
+ method?: 'modifiedZScore' | 'iqr' | 'rollingModifiedZScore' | 'rollingIqr';
2881
+ orderBy?: string; latest?: boolean;
2882
+ windowLen?: number; threshold?: number; k?: number; minPeriods?: number;
2883
+ },
2884
+ ): (rows: Iterable<Record<string, unknown>>) =>
2885
+ false | { method: string; field: string; flagged: { row: Record<string, unknown>; score: number | null }[] };
2886
+
2823
2887
  export type ShadowKind =
2824
2888
  | 'updates' | 'updatedAt' | 'sinceUpdate' | 'delta' | 'deltaPercent'
2825
2889
  | 'rate' | 'history' | 'firstValue' | 'streak'
@@ -3865,6 +3929,19 @@ export interface EditApi {
3865
3929
  * @returns the id the op is tracked under, or null when delete is not available
3866
3930
  */
3867
3931
  deleteRow(key: string): string | null;
3932
+ /**
3933
+ * Delete rows on a user gesture, through the cancellable `beforeDelete` event
3934
+ * (§18.4, BACKLOG-0000968) — what the built-in Delete-key and "Delete row"
3935
+ * gestures call. Unlike {@link deleteRow}, `beforeDelete` fires on a
3936
+ * memory-source grid too, so the row can be confirmed or vetoed there. Off
3937
+ * until `config.rowDelete` opts in; the keys default to the row selection.
3938
+ * Returns the keys removed (empty on a veto or when disabled), or a Promise of
3939
+ * them when a `beforeDelete` handler deferred.
3940
+ * @param keys the row keys; defaults to the current selection
3941
+ * @param opts `origin` names the provenance carried onto the events
3942
+ * @returns the removed keys, or a Promise of them on the async path
3943
+ */
3944
+ deleteRows(keys?: string | string[], opts?: { origin?: string }): string[] | Promise<string[]>;
3868
3945
  /**
3869
3946
  * Report the outcome of an optimistic structural write (§5.3), the counterpart
3870
3947
  * to {@link settle} for `edit.confirm: 'manual'` over a backend that
@@ -3914,6 +3991,65 @@ export interface ExportApi {
3914
3991
  print(): void;
3915
3992
  }
3916
3993
 
3994
+ /** How `config.import` tunes the DOM import affordances (§14). */
3995
+ export interface ImportSettings {
3996
+ /** Add the cell-menu item and open a file picker for CSV/TSV. Default true. */
3997
+ file?: boolean;
3998
+ /** Make the grid a drop target for `.csv`/`.tsv` files. Default true. */
3999
+ drop?: boolean;
4000
+ /** Read a pasted spreadsheet block into a preview. Default true. */
4001
+ paste?: boolean;
4002
+ /** How a confirmed import lands: append (default) or replace the dataset. */
4003
+ mode?: 'append' | 'replace';
4004
+ }
4005
+
4006
+ /** One source column as understood by the importer, after type inference (§14). */
4007
+ export interface ImportColumn {
4008
+ /** The heading as written in the file. */
4009
+ source: string;
4010
+ /** The column's position in each row. */
4011
+ index: number;
4012
+ /** The grid field this column maps onto; empty to exclude it from the import. */
4013
+ field: string;
4014
+ /** The inferred (or grid-dictated) type used to coerce the column's values. */
4015
+ type: string;
4016
+ /** A few non-blank sample values, for the preview. */
4017
+ samples: string[];
4018
+ /** Whether the heading matched one of the grid's own columns. */
4019
+ matched: boolean;
4020
+ }
4021
+
4022
+ /** What a preview carries — everything a confirm dialog needs (§14). */
4023
+ export interface ImportPreview {
4024
+ /** The delimiter that was used, detected or supplied. */
4025
+ delimiter: string;
4026
+ /** The source column headings. */
4027
+ header: string[];
4028
+ /** The per-column mapping and inference the user may edit before confirming. */
4029
+ columns: ImportColumn[];
4030
+ /** Every mapped, coerced record the import would add. */
4031
+ records: Record<string, unknown>[];
4032
+ /** The leading records, for a preview table. */
4033
+ sample: Record<string, unknown>[];
4034
+ /** How many data rows the file holds. */
4035
+ rowCount: number;
4036
+ /** Anything worth flagging before confirming — a ragged file, a bad quote. */
4037
+ warnings: string[];
4038
+ }
4039
+
4040
+ /** Bringing rows in — the mirror of {@link ExportApi} (§14, BACKLOG-0000949). */
4041
+ export interface ImportApi {
4042
+ /** Parse delimited text into a preview, changing nothing. */
4043
+ preview(text: string, opts?: object): ImportPreview;
4044
+ /** Parse delimited text into coerced records — the inverse of `export.csv`. */
4045
+ csv(text: string, opts?: object): Record<string, unknown>[];
4046
+ /** Add or replace the grid's rows from text, a preview or records. */
4047
+ apply(
4048
+ input: string | ImportPreview | Record<string, unknown>[],
4049
+ opts?: { mode?: 'append' | 'replace' },
4050
+ ): ChangeResult | null;
4051
+ }
4052
+
3917
4053
  export interface SavedView {
3918
4054
  id: string;
3919
4055
  name: string;
@@ -4709,6 +4845,8 @@ export interface Grid {
4709
4845
  readonly scroll: ScrollApi;
4710
4846
  /** CSV, Excel and clipboard. */
4711
4847
  readonly export: ExportApi;
4848
+ /** Bringing rows in from CSV/TSV text, a file, the clipboard or a drop. */
4849
+ readonly import: ImportApi;
4712
4850
  /** Everything the user arranged, as a serialisable object. */
4713
4851
  readonly state: StateApi;
4714
4852
  /** The loading, empty and error surfaces drawn over the grid. */
@@ -5621,22 +5759,82 @@ export interface ChartAxis {
5621
5759
  * placed against the wrong scale, and is written into the accessible table as a
5622
5760
  * sentence.
5623
5761
  */
5762
+ /**
5763
+ * A trend or forecast overlay method (BACKLOG-0000952). Each name has aliases:
5764
+ * `linear` (also `lr`, `ols`, `regression`); `movingAverage` (also `ma`, `sma`,
5765
+ * `rolling`); `exponential` (also `ewma`, `ses`, `holt`, `smoothing`).
5766
+ */
5767
+ export type ChartTrendMethod = 'linear' | 'movingAverage' | 'exponential'
5768
+ | 'lr' | 'ols' | 'regression' | 'ma' | 'sma' | 'rolling'
5769
+ | 'ewma' | 'ses' | 'holt' | 'smoothing';
5770
+
5771
+ /** One trend or forecast overlay (BACKLOG-0000952). */
5772
+ export interface ChartTrend {
5773
+ /** The overlay method; `linear` by default. */
5774
+ method?: ChartTrendMethod;
5775
+ /**
5776
+ * For the linear method, how many steps to project the line past the data as a
5777
+ * dashed forecast. Ignored by the moving-average and exponential methods,
5778
+ * which have no slope to extrapolate.
5779
+ */
5780
+ forecast?: number;
5781
+ /** For the moving-average method, the trailing window in points; 3 by default. */
5782
+ window?: number;
5783
+ /** An alias for `window`. */
5784
+ period?: number;
5785
+ /** For the exponential method, single smoothing (`ses`) or Holt's level+trend (`holt`). */
5786
+ kind?: 'ses' | 'holt';
5787
+ /** For the exponential method, the level factor in `[0, 1]`; omit to fit it. */
5788
+ alpha?: number;
5789
+ /** For Holt's exponential smoothing, the trend factor in `[0, 1]`; omit to fit it. */
5790
+ beta?: number;
5791
+ /** `false` suppresses the R² label on a linear trend. */
5792
+ label?: boolean;
5793
+ }
5794
+
5795
+ /**
5796
+ * One declarative annotation (BACKLOG-0000744, extended by BACKLOG-0000953). A
5797
+ * reference or target line, a shaded band, a callout, or an `event` marker. Its
5798
+ * value is a constant `value` (or `from`/`to` for a band), or a `compute`
5799
+ * reduction of the data it annotates — `mean`, `median`, `min`, `max`, or `p95`
5800
+ * for a percentile — so it follows the data as the grid is filtered. A band with
5801
+ * `orient: 'vertical'` shades an x-range instead — an event window, a
5802
+ * maintenance period — and an `event` marker is a labelled vertical rule with a
5803
+ * flag at a position on the x axis. Every annotation names the axis it reads,
5804
+ * which on a dual-axis chart is what stops it being placed against the wrong
5805
+ * scale, and is written into the accessible table as a sentence — a vertical
5806
+ * marker and an event stating the position they sit at, because a screen-reader
5807
+ * user needs where and when, not only that a marker exists.
5808
+ */
5624
5809
  export interface ChartAnnotation {
5625
- /** The default is a reference line. */
5626
- kind?: 'line' | 'target' | 'band' | 'callout';
5810
+ /**
5811
+ * The default is a reference line. `event` is a labelled vertical marker with
5812
+ * a flag at a position on the x axis, described into the accessible table with
5813
+ * that position stated (BACKLOG-0000953).
5814
+ */
5815
+ kind?: 'line' | 'target' | 'band' | 'callout' | 'event';
5627
5816
  /** A constant value, for a line, target or callout's measure position. */
5628
5817
  value?: number;
5629
5818
  /** A reduction of the annotated data instead of a constant. */
5630
5819
  compute?: 'mean' | 'avg' | 'median' | 'min' | 'max' | string;
5631
- /** A band's two edges, each a constant or (with `fromCompute`/`toCompute`) computed. */
5632
- from?: number;
5633
- to?: number;
5820
+ /**
5821
+ * A band's two edges. On a horizontal band each is a measure value, a constant
5822
+ * or (with `fromCompute`/`toCompute`) computed. On a vertical band (`orient:
5823
+ * 'vertical'`, BACKLOG-0000953) each is an x position — a category or a number
5824
+ * — and the band shades the x-range between them: an event window, a
5825
+ * maintenance period, a recession.
5826
+ */
5827
+ from?: number | string;
5828
+ to?: number | string;
5634
5829
  fromCompute?: string;
5635
5830
  toCompute?: string;
5636
- /** A vertical line's or callout's x position: a category or a number. */
5831
+ /** A vertical line's, event marker's or callout's x position: a category or a number. */
5637
5832
  x?: unknown;
5638
5833
  at?: unknown;
5639
- /** Force a line vertical rather than horizontal. */
5834
+ /**
5835
+ * Force a line vertical rather than horizontal, or shade a `band` across an
5836
+ * x-range rather than a measure range (BACKLOG-0000953).
5837
+ */
5640
5838
  orient?: 'horizontal' | 'vertical';
5641
5839
  /** Which measure axis the annotation reads. */
5642
5840
  axis?: 'left' | 'right' | 'y2';
@@ -5729,6 +5927,23 @@ export interface ChartSpec {
5729
5927
  * through the order they happened to be listed in.
5730
5928
  */
5731
5929
  fit?: boolean | 'line';
5930
+ /**
5931
+ * Trend and forecast overlays (BACKLOG-0000952): a least-squares line, a
5932
+ * trailing moving average, or exponential smoothing, drawn over a line, area
5933
+ * or scatter chart. `true` draws a single linear trend; a method name or a
5934
+ * {@link ChartTrend} object configures one; an array draws several.
5935
+ *
5936
+ * The maths matches the core stats engine to the last digit — the same
5937
+ * least-squares fit, rolling window and exponential recursions — but is
5938
+ * computed locally in the charts module rather than imported, because the
5939
+ * in-tree bundler does not tree-shake and the import would inline the whole
5940
+ * statistics closure; a test asserts the parity. A `forecast` count projects
5941
+ * the linear line that many steps past the data, drawn dashed so it never
5942
+ * reads as a reading; a moving average and a smoothed level have no slope to
5943
+ * project, so `forecast` is ignored for them and the fact is stated in the
5944
+ * accessible description rather than faked.
5945
+ */
5946
+ trend?: boolean | ChartTrendMethod | ChartTrend | Array<ChartTrendMethod | ChartTrend>;
5732
5947
  /**
5733
5948
  * A pointwise confidence band, drawn as a varying-width ribbon beneath the fit
5734
5949
  * line (BACKLOG-0000812). Fed by a fitted model's own interval — the `band`
@@ -6404,10 +6619,28 @@ declare module 'lattice-grid/modules/gantt' {
6404
6619
  assignee?: string | string[];
6405
6620
  assignees?: string[];
6406
6621
  owner?: string;
6622
+ /**
6623
+ * Explicit resource assignments with fractional units (BACKLOG-0000948):
6624
+ * `units` is a multiplier where 1 is a full-time booking. Use this when a
6625
+ * task books a resource at less (or more) than 100%; a bare `assignee` is
6626
+ * `units: 1`.
6627
+ */
6628
+ assignments?: Array<{ resource?: string; name?: string; id?: string; units?: number }>;
6629
+ /** Leveling priority: a higher value is delayed last (default 0). */
6630
+ priority?: number;
6407
6631
  /** An explicit row height (px) for the split view; applied to both panels. */
6408
6632
  height?: number;
6409
6633
  }
6410
6634
 
6635
+ /**
6636
+ * Resource capacities for over-allocation detection and leveling
6637
+ * (BACKLOG-0000948): either a list of resources with a capacity (max
6638
+ * concurrent units, default 1) or a name→capacity map.
6639
+ */
6640
+ export type GanttResourceSpec =
6641
+ | Array<{ id?: string; name?: string; resource?: string; capacity?: number; maxUnits?: number; max?: number; units?: number }>
6642
+ | Record<string, number>;
6643
+
6411
6644
  /**
6412
6645
  * A typed dependency between two tasks (by id), with optional lag/lead. `type`
6413
6646
  * defaults to `'FS'`; either endpoint may be a leaf or a summary.
@@ -6467,6 +6700,47 @@ declare module 'lattice-grid/modules/gantt' {
6467
6700
  conflicts?: GanttConflict[];
6468
6701
  /** Whether a working-time calendar was applied. */
6469
6702
  calendar?: boolean;
6703
+ /** The resource over-allocations for this schedule (BACKLOG-0000948). */
6704
+ overAllocations?: GanttOverAllocation[];
6705
+ /** The full resource-load report for this schedule (BACKLOG-0000948). */
6706
+ resourceLoad?: GanttResourceLoad;
6707
+ }
6708
+
6709
+ /** One contiguous load segment for a resource: how many units are booked over a span. */
6710
+ interface GanttResourceSegment {
6711
+ start: number;
6712
+ end: number;
6713
+ load: number;
6714
+ taskIds: string[];
6715
+ }
6716
+
6717
+ /** A resource booked beyond its capacity across concurrent tasks (BACKLOG-0000948). */
6718
+ interface GanttOverAllocation {
6719
+ resource: string;
6720
+ capacity: number;
6721
+ start: number;
6722
+ end: number;
6723
+ load: number;
6724
+ taskIds: string[];
6725
+ }
6726
+
6727
+ /** The per-resource load and the over-allocations across a schedule (BACKLOG-0000948). */
6728
+ interface GanttResourceLoad {
6729
+ ok: boolean;
6730
+ resources: Array<{ resource: string; capacity: number; peak: number; segments: GanttResourceSegment[] }>;
6731
+ overAllocations: GanttOverAllocation[];
6732
+ byResource: Map<string, { capacity: number; peak: number; segments: GanttResourceSegment[] }>;
6733
+ }
6734
+
6735
+ /** The result of resource leveling: the shifted tasks and what moved (BACKLOG-0000948). */
6736
+ interface GanttLevelResult {
6737
+ ok: boolean;
6738
+ resolved?: boolean;
6739
+ tasks?: GanttTask[];
6740
+ schedule?: GanttSchedule;
6741
+ moves?: Array<{ id: string; from: number; to: number; delay: number }>;
6742
+ remaining?: GanttOverAllocation[];
6743
+ error?: { code: string; message: string };
6470
6744
  }
6471
6745
 
6472
6746
  /** A placement violation flagged by `findViolations`. */
@@ -6507,13 +6781,43 @@ declare module 'lattice-grid/modules/gantt' {
6507
6781
  readonly conflicts: GanttConflict[];
6508
6782
  readonly autoSchedule: boolean;
6509
6783
  readonly grid: unknown;
6784
+ /** The over-allocations from the latest schedule (BACKLOG-0000948). */
6785
+ readonly overAllocations: GanttOverAllocation[];
6786
+ /** The latest resource-load report, or null before a successful schedule (BACKLOG-0000948). */
6787
+ readonly resourceLoad: GanttResourceLoad | null;
6510
6788
  setTasks(tasks: GanttTask[]): GanttSchedule;
6511
6789
  setDependencies(deps: GanttDependency[]): GanttSchedule;
6512
6790
  applyEdit(patch: { id: string | number; start?: number; end?: number; duration?: number }, editOpts?: { writeBack?: boolean }): GanttSchedule;
6513
6791
  compute(): GanttSchedule;
6514
6792
  findViolations(): GanttViolation[];
6793
+ /**
6794
+ * Compute the resource load and over-allocations on demand (BACKLOG-0000948),
6795
+ * optionally overriding the capacities for this call.
6796
+ */
6797
+ resources(loadOpts?: { resources?: GanttResourceSpec; defaultCapacity?: number }): GanttResourceLoad;
6798
+ /**
6799
+ * Resolve resource over-allocation by shifting tasks later — resource
6800
+ * leveling (BACKLOG-0000948). Honours the CPM dependencies and the
6801
+ * working-time calendar. Mutates the model unless `{ dryRun: true }`; with
6802
+ * `{ writeBack: true }` and a bound grid the moved tasks are pushed through
6803
+ * the grid's edit surface.
6804
+ */
6805
+ level(levelOpts?: {
6806
+ dryRun?: boolean;
6807
+ writeBack?: boolean;
6808
+ priorityField?: string;
6809
+ maxIterations?: number;
6810
+ resources?: GanttResourceSpec;
6811
+ defaultCapacity?: number;
6812
+ }): GanttLevelResult;
6515
6813
  /** Export the scheduled tasks as CSV; `{ dates: true }` writes ISO dates. */
6516
6814
  toCSV(csvOpts?: { dates?: boolean }): string;
6815
+ /**
6816
+ * Export the current plan as Microsoft Project (MSPDI) XML (BACKLOG-0000950):
6817
+ * tasks, dependencies, constraints, baseline, resources and assignments, plus
6818
+ * the working-time calendar, serialised with the computed schedule.
6819
+ */
6820
+ toMSPDI(xmlOpts?: { hoursPerDay?: number; projectName?: string }): string;
6517
6821
  /**
6518
6822
  * The live consumer surface, mirroring `grid.rows.apply`, so a Data Router
6519
6823
  * can drive the Gantt like any other view. Keyed by the controller's rowKey.
@@ -6612,6 +6916,10 @@ declare module 'lattice-grid/modules/gantt' {
6612
6916
  deadline?: number | string | Date;
6613
6917
  /** A working-time calendar: skip weekends/holidays, durations in working days. */
6614
6918
  calendar?: GanttCalendar | null;
6919
+ /** Resource capacities for over-allocation detection and leveling (BACKLOG-0000948). */
6920
+ resources?: GanttResourceSpec;
6921
+ /** The capacity for a resource with none stated (default 1 = one full-time booking). */
6922
+ defaultCapacity?: number;
6615
6923
  autoSchedule?: boolean;
6616
6924
  grid?: unknown;
6617
6925
  /** Map task fields to grid column ids to enable drag write-back. */
@@ -6622,6 +6930,38 @@ declare module 'lattice-grid/modules/gantt' {
6622
6930
  element?: unknown;
6623
6931
  }): Gantt;
6624
6932
  export default createGantt;
6933
+
6934
+ /** The model {@link importMSPDI} returns and {@link exportMSPDI} takes. */
6935
+ interface GanttMSPDIModel {
6936
+ tasks: GanttTask[];
6937
+ dependencies?: GanttDependency[];
6938
+ resources?: GanttResourceSpec;
6939
+ projectStart?: number | string | Date;
6940
+ calendar?: GanttCalendar | null;
6941
+ schedule?: GanttSchedule;
6942
+ }
6943
+
6944
+ /**
6945
+ * Import a Microsoft Project (MSPDI) XML document (BACKLOG-0000950) into the
6946
+ * module's model: the task tree, typed dependencies with lag, constraints,
6947
+ * baseline, %complete, resources with capacity, the resource assignments, and
6948
+ * the working-time calendar. The result is ready to pass to {@link createGantt}.
6949
+ */
6950
+ export function importMSPDI(xml: string, opts?: { hoursPerDay?: number }): {
6951
+ ok: boolean;
6952
+ error?: string;
6953
+ tasks: GanttTask[];
6954
+ dependencies: GanttDependency[];
6955
+ resources: Array<{ id: string; name: string; capacity: number }>;
6956
+ projectStart?: number;
6957
+ calendar?: null | { workdays: number[]; holidays: number[] };
6958
+ };
6959
+
6960
+ /**
6961
+ * Export a Gantt model to Microsoft Project (MSPDI) XML (BACKLOG-0000950). A
6962
+ * scheduled model may be passed so start/finish dates are the computed ones.
6963
+ */
6964
+ export function exportMSPDI(model: GanttMSPDIModel, opts?: { hoursPerDay?: number; projectName?: string }): string;
6625
6965
  }
6626
6966
 
6627
6967
  declare module 'lattice-grid/modules/webcomponent' {