@crisp-ui-kit/crisp 0.7.5 → 0.7.6
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.
|
@@ -394,6 +394,15 @@ function CreateRecordDialog({ open, onOpenChange, columns, entityLabel, onCreate
|
|
|
394
394
|
function RecordsTable({ labels, columns: columnsProp = exports.defaultColumns, rows: rowsProp = exports.defaultRows, selectedIds, onSelectionChange, showNew = true, allowAddColumn = true, onOpenRecord, onOpenRecordPage, avatarTone = "brand", className, }) {
|
|
395
395
|
const [cols, setCols] = React.useState(columnsProp);
|
|
396
396
|
const [data, setData] = React.useState(rowsProp);
|
|
397
|
+
// The table owns `cols`/`data` so it can rename a column, edit a cell, or
|
|
398
|
+
// append a record without a round trip. That state is seeded from the props,
|
|
399
|
+
// so without these it would be a mount-time SNAPSHOT: an app that renders
|
|
400
|
+
// `rows={[]}` and re-renders with fetched rows would show "No records yet"
|
|
401
|
+
// for ever. Re-seed whenever the caller hands us a new array -- caller wins,
|
|
402
|
+
// exactly as DataTable does for its columns. Local edits survive until then,
|
|
403
|
+
// because a caller passing a stable array never triggers this.
|
|
404
|
+
React.useEffect(() => setCols(columnsProp), [columnsProp]);
|
|
405
|
+
React.useEffect(() => setData(rowsProp), [rowsProp]);
|
|
397
406
|
// Attio's multi-criteria sort: an ordered list of {field, direction} rows.
|
|
398
407
|
const [sorts, setSorts] = React.useState([]);
|
|
399
408
|
const [dragSort, setDragSort] = React.useState(null);
|
|
@@ -607,7 +616,20 @@ function RecordsTable({ labels, columns: columnsProp = exports.defaultColumns, r
|
|
|
607
616
|
};
|
|
608
617
|
const allSelected = visibleRows.length > 0 && visibleRows.every((r) => selected.has(r.id));
|
|
609
618
|
const someSelected = selected.size > 0 && !allSelected;
|
|
610
|
-
|
|
619
|
+
// The header checkbox speaks for the rows you can SEE. Rebuilding the whole
|
|
620
|
+
// set from `visibleRows` would silently drop anything an active filter is
|
|
621
|
+
// hiding -- on a surface with a bulk Delete, that loses a selection the user
|
|
622
|
+
// made. Add/remove the visible rows and leave the rest of the set alone.
|
|
623
|
+
const toggleAll = () => {
|
|
624
|
+
const next = new Set(selected);
|
|
625
|
+
for (const r of visibleRows) {
|
|
626
|
+
if (allSelected)
|
|
627
|
+
next.delete(r.id);
|
|
628
|
+
else
|
|
629
|
+
next.add(r.id);
|
|
630
|
+
}
|
|
631
|
+
setSelected(next);
|
|
632
|
+
};
|
|
611
633
|
const toggleRow = (id) => {
|
|
612
634
|
const next = new Set(selected);
|
|
613
635
|
// shift-click → select the contiguous range from the anchor to this row
|
|
@@ -804,7 +826,7 @@ function RecordsTable({ labels, columns: columnsProp = exports.defaultColumns, r
|
|
|
804
826
|
URL.revokeObjectURL(url);
|
|
805
827
|
setOpenMenu(null);
|
|
806
828
|
};
|
|
807
|
-
const
|
|
829
|
+
const entityCol = cols.find((c) => c.type === "entity");
|
|
808
830
|
// "Add to list" → pin the selected rows (shows a ★ on the entity)
|
|
809
831
|
const addToList = () => {
|
|
810
832
|
setPinned((prev) => new Set([...prev, ...selected]));
|
|
@@ -814,7 +836,10 @@ function RecordsTable({ labels, columns: columnsProp = exports.defaultColumns, r
|
|
|
814
836
|
const sendEmail = () => {
|
|
815
837
|
const names = data
|
|
816
838
|
.filter((r) => selected.has(r.id))
|
|
817
|
-
|
|
839
|
+
// Pass the real column: `cellText` -> `rawText` reads `col.type` to pull
|
|
840
|
+
// an entity's `.name`, so a `{key, label}` stand-in with no `type` falls
|
|
841
|
+
// through to String(value) and yields "[object Object]".
|
|
842
|
+
.map((r) => (entityCol ? cellText(entityCol, r) : r.id));
|
|
818
843
|
window.open(`mailto:?subject=${encodeURIComponent(names.join(", "))}`);
|
|
819
844
|
};
|
|
820
845
|
// "Run workflow" → a demo automation: duplicate the selected records
|
|
@@ -356,6 +356,15 @@ function CreateRecordDialog({ open, onOpenChange, columns, entityLabel, onCreate
|
|
|
356
356
|
export function RecordsTable({ labels, columns: columnsProp = defaultColumns, rows: rowsProp = defaultRows, selectedIds, onSelectionChange, showNew = true, allowAddColumn = true, onOpenRecord, onOpenRecordPage, avatarTone = "brand", className, }) {
|
|
357
357
|
const [cols, setCols] = React.useState(columnsProp);
|
|
358
358
|
const [data, setData] = React.useState(rowsProp);
|
|
359
|
+
// The table owns `cols`/`data` so it can rename a column, edit a cell, or
|
|
360
|
+
// append a record without a round trip. That state is seeded from the props,
|
|
361
|
+
// so without these it would be a mount-time SNAPSHOT: an app that renders
|
|
362
|
+
// `rows={[]}` and re-renders with fetched rows would show "No records yet"
|
|
363
|
+
// for ever. Re-seed whenever the caller hands us a new array -- caller wins,
|
|
364
|
+
// exactly as DataTable does for its columns. Local edits survive until then,
|
|
365
|
+
// because a caller passing a stable array never triggers this.
|
|
366
|
+
React.useEffect(() => setCols(columnsProp), [columnsProp]);
|
|
367
|
+
React.useEffect(() => setData(rowsProp), [rowsProp]);
|
|
359
368
|
// Attio's multi-criteria sort: an ordered list of {field, direction} rows.
|
|
360
369
|
const [sorts, setSorts] = React.useState([]);
|
|
361
370
|
const [dragSort, setDragSort] = React.useState(null);
|
|
@@ -569,7 +578,20 @@ export function RecordsTable({ labels, columns: columnsProp = defaultColumns, ro
|
|
|
569
578
|
};
|
|
570
579
|
const allSelected = visibleRows.length > 0 && visibleRows.every((r) => selected.has(r.id));
|
|
571
580
|
const someSelected = selected.size > 0 && !allSelected;
|
|
572
|
-
|
|
581
|
+
// The header checkbox speaks for the rows you can SEE. Rebuilding the whole
|
|
582
|
+
// set from `visibleRows` would silently drop anything an active filter is
|
|
583
|
+
// hiding -- on a surface with a bulk Delete, that loses a selection the user
|
|
584
|
+
// made. Add/remove the visible rows and leave the rest of the set alone.
|
|
585
|
+
const toggleAll = () => {
|
|
586
|
+
const next = new Set(selected);
|
|
587
|
+
for (const r of visibleRows) {
|
|
588
|
+
if (allSelected)
|
|
589
|
+
next.delete(r.id);
|
|
590
|
+
else
|
|
591
|
+
next.add(r.id);
|
|
592
|
+
}
|
|
593
|
+
setSelected(next);
|
|
594
|
+
};
|
|
573
595
|
const toggleRow = (id) => {
|
|
574
596
|
const next = new Set(selected);
|
|
575
597
|
// shift-click → select the contiguous range from the anchor to this row
|
|
@@ -766,7 +788,7 @@ export function RecordsTable({ labels, columns: columnsProp = defaultColumns, ro
|
|
|
766
788
|
URL.revokeObjectURL(url);
|
|
767
789
|
setOpenMenu(null);
|
|
768
790
|
};
|
|
769
|
-
const
|
|
791
|
+
const entityCol = cols.find((c) => c.type === "entity");
|
|
770
792
|
// "Add to list" → pin the selected rows (shows a ★ on the entity)
|
|
771
793
|
const addToList = () => {
|
|
772
794
|
setPinned((prev) => new Set([...prev, ...selected]));
|
|
@@ -776,7 +798,10 @@ export function RecordsTable({ labels, columns: columnsProp = defaultColumns, ro
|
|
|
776
798
|
const sendEmail = () => {
|
|
777
799
|
const names = data
|
|
778
800
|
.filter((r) => selected.has(r.id))
|
|
779
|
-
|
|
801
|
+
// Pass the real column: `cellText` -> `rawText` reads `col.type` to pull
|
|
802
|
+
// an entity's `.name`, so a `{key, label}` stand-in with no `type` falls
|
|
803
|
+
// through to String(value) and yields "[object Object]".
|
|
804
|
+
.map((r) => (entityCol ? cellText(entityCol, r) : r.id));
|
|
780
805
|
window.open(`mailto:?subject=${encodeURIComponent(names.join(", "))}`);
|
|
781
806
|
};
|
|
782
807
|
// "Run workflow" → a demo automation: duplicate the selected records
|