@jielga/tmdatagrid 2.0.0-beta.12 → 2.0.0-beta.13
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 +18 -3
- package/dist/index.js +162 -151
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/appearance/SKILL.md +1 -1
- package/skills/cell-selection/SKILL.md +1 -1
- package/skills/columns/SKILL.md +1 -1
- package/skills/data/SKILL.md +1 -1
- package/skills/editing/SKILL.md +1 -1
- package/skills/filtering/SKILL.md +1 -1
- package/skills/getting-started/SKILL.md +1 -1
- package/skills/grouping/SKILL.md +1 -1
- package/skills/options/SKILL.md +1 -1
- package/skills/rows/SKILL.md +1 -1
- package/skills/server-side/SKILL.md +1 -1
- package/skills/testing/SKILL.md +1 -1
- package/src/tmdatagrid/components/TMDataGridEditColumn.tsx +1 -1
- package/src/tmdatagrid/core/editEngine.ts +68 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jielga/tmdatagrid",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.13",
|
|
4
4
|
"description": "A React data grid built on TanStack Table v9 and Mantine - always virtualized, with resizable, reorderable, sortable, filterable, hideable and pinnable columns.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -14,7 +14,7 @@ description: >
|
|
|
14
14
|
metadata:
|
|
15
15
|
type: core
|
|
16
16
|
library: '@jielga/tmdatagrid'
|
|
17
|
-
library_version: '2.0.0-beta.
|
|
17
|
+
library_version: '2.0.0-beta.13'
|
|
18
18
|
sources:
|
|
19
19
|
- 'Jielga/TMDataGrid:src/docs/cell-selection.md'
|
|
20
20
|
- 'Jielga/TMDataGrid:src/tmdatagrid/core/cellNavigation.ts'
|
package/skills/columns/SKILL.md
CHANGED
package/skills/data/SKILL.md
CHANGED
package/skills/editing/SKILL.md
CHANGED
package/skills/grouping/SKILL.md
CHANGED
package/skills/options/SKILL.md
CHANGED
|
@@ -14,7 +14,7 @@ description: >
|
|
|
14
14
|
metadata:
|
|
15
15
|
type: core
|
|
16
16
|
library: '@jielga/tmdatagrid'
|
|
17
|
-
library_version: '2.0.0-beta.
|
|
17
|
+
library_version: '2.0.0-beta.13'
|
|
18
18
|
sources:
|
|
19
19
|
- 'Jielga/TMDataGrid:src/docs/use-tm-data-grid.md'
|
|
20
20
|
- 'Jielga/TMDataGrid:src/tmdatagrid/useTMDataGrid.tsx'
|
package/skills/rows/SKILL.md
CHANGED
|
@@ -17,7 +17,7 @@ description: >
|
|
|
17
17
|
metadata:
|
|
18
18
|
type: core
|
|
19
19
|
library: '@jielga/tmdatagrid'
|
|
20
|
-
library_version: '2.0.0-beta.
|
|
20
|
+
library_version: '2.0.0-beta.13'
|
|
21
21
|
sources:
|
|
22
22
|
- 'Jielga/TMDataGrid:src/docs/row-selection.md'
|
|
23
23
|
- 'Jielga/TMDataGrid:src/docs/row-interaction.md'
|
|
@@ -11,7 +11,7 @@ description: >
|
|
|
11
11
|
metadata:
|
|
12
12
|
type: core
|
|
13
13
|
library: '@jielga/tmdatagrid'
|
|
14
|
-
library_version: '2.0.0-beta.
|
|
14
|
+
library_version: '2.0.0-beta.13'
|
|
15
15
|
sources:
|
|
16
16
|
- 'Jielga/TMDataGrid:src/docs/server-side.md'
|
|
17
17
|
- 'Jielga/TMDataGrid:src/tmdatagrid/useTMDataGrid.tsx'
|
package/skills/testing/SKILL.md
CHANGED
|
@@ -11,7 +11,7 @@ description: >
|
|
|
11
11
|
metadata:
|
|
12
12
|
type: core
|
|
13
13
|
library: '@jielga/tmdatagrid'
|
|
14
|
-
library_version: '2.0.0-beta.
|
|
14
|
+
library_version: '2.0.0-beta.13'
|
|
15
15
|
sources:
|
|
16
16
|
- 'Jielga/TMDataGrid:src/docs/testing.md'
|
|
17
17
|
- 'Jielga/TMDataGrid:src/tmdatagrid/components/TMDataGrid.tsx'
|
|
@@ -707,11 +707,26 @@ export type TMDataGridEditApi<
|
|
|
707
707
|
) => Promise<TMDataGridAddRowsResult>;
|
|
708
708
|
/**
|
|
709
709
|
* Deletes a row: `onRowDelete` straight away, or under `editing.draft` a
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
*
|
|
710
|
+
* mark in `deletedRowIds` - the row renders struck through until
|
|
711
|
+
* `saveDrafts` reports it. Idempotent: deleting a marked row again leaves
|
|
712
|
+
* it marked, and {@link restoreRow} is the undo. On an entry row,
|
|
713
|
+
* committed or not, it just discards the entry; an id the grid does not
|
|
714
|
+
* know is a no-op.
|
|
713
715
|
*/
|
|
714
716
|
deleteRow: (rowId: string) => void;
|
|
717
|
+
/**
|
|
718
|
+
* {@link deleteRow} for several rows in one call - one notification for
|
|
719
|
+
* the batch, for a bulk action over a selection. Because `deleteRow` is
|
|
720
|
+
* idempotent and ignores unknown ids, the list may be passed exactly as
|
|
721
|
+
* the selection stands - already-marked rows stay marked, duplicates and
|
|
722
|
+
* stale ids do nothing.
|
|
723
|
+
*/
|
|
724
|
+
deleteRows: (rowIds: ReadonlyArray<string>) => void;
|
|
725
|
+
/**
|
|
726
|
+
* Removes a row's deletion mark - the lane's Restore. A no-op on a row
|
|
727
|
+
* that is not marked, and outside `editing.draft`, where no marks exist.
|
|
728
|
+
*/
|
|
729
|
+
restoreRow: (rowId: string) => void;
|
|
715
730
|
/** Whether delete chrome makes sense - the lane's trash gate. */
|
|
716
731
|
canDeleteRows: () => boolean;
|
|
717
732
|
};
|
|
@@ -875,6 +890,7 @@ export function createEditEngine(
|
|
|
875
890
|
};
|
|
876
891
|
const forms = new Map<string, FormEntry>();
|
|
877
892
|
let newRowCounter = 0;
|
|
893
|
+
const NEW_ROW_ID_PREFIX = "__new__";
|
|
878
894
|
/** Lets `commit` tell a `saveDrafts` flush apart from a lone commit. */
|
|
879
895
|
let savingDrafts = false;
|
|
880
896
|
|
|
@@ -1428,6 +1444,11 @@ export function createEditEngine(
|
|
|
1428
1444
|
} finally {
|
|
1429
1445
|
entry.pendingCommit = null;
|
|
1430
1446
|
}
|
|
1447
|
+
// Dropped while the submit was in flight - cancel or deleteRow won the
|
|
1448
|
+
// race. The form is gone, so there is nothing to park or drop; marking
|
|
1449
|
+
// the row committed now would plant an id in `committedRowIds` that no
|
|
1450
|
+
// save or discard could ever clear.
|
|
1451
|
+
if (forms.get(rowId) !== entry) return true;
|
|
1431
1452
|
if (!entry.lastSubmitOk) {
|
|
1432
1453
|
// Snapshot before the caller closes the editor: the field errors go
|
|
1433
1454
|
// with it, and the row is about to be left carrying them.
|
|
@@ -1532,7 +1553,7 @@ export function createEditEngine(
|
|
|
1532
1553
|
|
|
1533
1554
|
const addRow = (values?: TMDataGridRowData): string => {
|
|
1534
1555
|
newRowCounter += 1;
|
|
1535
|
-
const tempId =
|
|
1556
|
+
const tempId = `${NEW_ROW_ID_PREFIX}${newRowCounter}`;
|
|
1536
1557
|
createForm(tempId, seedNewRow(values), true);
|
|
1537
1558
|
store.setState((prev) => ({
|
|
1538
1559
|
...prev,
|
|
@@ -1564,7 +1585,7 @@ export function createEditEngine(
|
|
|
1564
1585
|
batch(() => {
|
|
1565
1586
|
for (const values of rows) {
|
|
1566
1587
|
newRowCounter += 1;
|
|
1567
|
-
const tempId =
|
|
1588
|
+
const tempId = `${NEW_ROW_ID_PREFIX}${newRowCounter}`;
|
|
1568
1589
|
createForm(tempId, seedNewRow(values), true);
|
|
1569
1590
|
tempIds.push(tempId);
|
|
1570
1591
|
}
|
|
@@ -1599,13 +1620,26 @@ export function createEditEngine(
|
|
|
1599
1620
|
}
|
|
1600
1621
|
const context = getContext();
|
|
1601
1622
|
if (context.draft) {
|
|
1602
|
-
//
|
|
1603
|
-
store.setState((prev) =>
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1623
|
+
// Idempotent: a marked row stays marked - `restoreRow` is the undo.
|
|
1624
|
+
store.setState((prev) => {
|
|
1625
|
+
if (prev.deletedRowIds.includes(rowId)) return prev;
|
|
1626
|
+
// Only a consumer row can be marked. A deletion mark is what
|
|
1627
|
+
// `saveDrafts` reports to the server, so an id it cannot act on -
|
|
1628
|
+
// an engine temp id, a record gone from `data`, an id the grid
|
|
1629
|
+
// never knew - must not live on as a mark inflating the draft
|
|
1630
|
+
// count. Entry rows are dropped above, never marked; the prefix
|
|
1631
|
+
// check also catches one already dropped that a stale selection or
|
|
1632
|
+
// a double-fired handler names again, while the table's data still
|
|
1633
|
+
// shows it for one render. The core model, so a filtered-out row
|
|
1634
|
+
// still takes its mark.
|
|
1635
|
+
if (
|
|
1636
|
+
rowId.startsWith(NEW_ROW_ID_PREFIX) ||
|
|
1637
|
+
!(rowId in context.table.getCoreRowModel().rowsById)
|
|
1638
|
+
) {
|
|
1639
|
+
return prev;
|
|
1640
|
+
}
|
|
1641
|
+
return { ...prev, deletedRowIds: [...prev.deletedRowIds, rowId] };
|
|
1642
|
+
});
|
|
1609
1643
|
return;
|
|
1610
1644
|
}
|
|
1611
1645
|
const row = getRow(rowId);
|
|
@@ -1614,6 +1648,26 @@ export function createEditEngine(
|
|
|
1614
1648
|
void context.onRowDelete?.({ rowId, row });
|
|
1615
1649
|
};
|
|
1616
1650
|
|
|
1651
|
+
const deleteRows = (rowIds: ReadonlyArray<string>) => {
|
|
1652
|
+
// One notification for the batch - each id still goes through
|
|
1653
|
+
// `deleteRow`, so entry rows drop and everything else marks or no-ops
|
|
1654
|
+
// by the same rules.
|
|
1655
|
+
batch(() => {
|
|
1656
|
+
for (const rowId of rowIds) deleteRow(rowId);
|
|
1657
|
+
});
|
|
1658
|
+
};
|
|
1659
|
+
|
|
1660
|
+
const restoreRow = (rowId: string) => {
|
|
1661
|
+
store.setState((prev) =>
|
|
1662
|
+
prev.deletedRowIds.includes(rowId)
|
|
1663
|
+
? {
|
|
1664
|
+
...prev,
|
|
1665
|
+
deletedRowIds: prev.deletedRowIds.filter((id) => id !== rowId),
|
|
1666
|
+
}
|
|
1667
|
+
: prev,
|
|
1668
|
+
);
|
|
1669
|
+
};
|
|
1670
|
+
|
|
1617
1671
|
const canDeleteRows = (): boolean => {
|
|
1618
1672
|
const context = getContext();
|
|
1619
1673
|
if (context.draft) {
|
|
@@ -1903,6 +1957,8 @@ export function createEditEngine(
|
|
|
1903
1957
|
addRow,
|
|
1904
1958
|
addRows,
|
|
1905
1959
|
deleteRow,
|
|
1960
|
+
deleteRows,
|
|
1961
|
+
restoreRow,
|
|
1906
1962
|
canDeleteRows,
|
|
1907
1963
|
};
|
|
1908
1964
|
}
|