Skip to content

Commit f1b6d5d

Browse files
Merge pull request #870 from gadget-inc/mill/wholeRecordInActionCallback
Include complete raw record in AutoTable callbacks
2 parents 8c675ca + bdf6449 commit f1b6d5d

File tree

5 files changed

+111
-18
lines changed

5 files changed

+111
-18
lines changed

packages/react/spec/auto/storybook/table/AutoTableActions.stories.jsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,35 @@ export const NoTriggerableActions = {
6161
},
6262
};
6363

64+
export const CustomCellRenderersWithCustomActions = {
65+
args: {
66+
model: api.autoTableTest,
67+
select: {
68+
id: true,
69+
str: true,
70+
num: true,
71+
email: true,
72+
createdAt: true,
73+
updatedAt: true,
74+
},
75+
columns: [
76+
"id",
77+
"str",
78+
{
79+
header: "custom cell renderer",
80+
render: ({ record }) => <p>{JSON.stringify(record)}</p>,
81+
},
82+
],
83+
actions: [
84+
{
85+
label: "console.log all records",
86+
promoted: true,
87+
action: (records) => console.log(`records:`, records),
88+
},
89+
],
90+
},
91+
};
92+
6493
const windowAlert = (message) => {
6594
// eslint-disable-next-line no-undef
6695
window.alert(message);

packages/react/src/auto/hooks/useTableBulkActions.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { type GadgetRecord } from "@gadgetinc/api-client-core";
12
import React, { useCallback, useEffect, useMemo } from "react";
23
import deepEqual from "react-fast-compare";
34
import type { ActionCallback, TableOptions, TableRow } from "../../use-table/types.js";
@@ -175,13 +176,26 @@ const getValidatedBulkModelActionOption = (gadgetModelActionsAsBulkActionOptions
175176
return modelAction;
176177
};
177178

178-
export const getBulkActionOptionCallback = (option: BulkActionOption, selectedRows: TableRow[], clearSelection: () => void) =>
179-
option.action
179+
export const getBulkActionOptionCallback = (props: {
180+
option: BulkActionOption;
181+
selectedRows: TableRow[];
182+
clearSelection: () => void;
183+
rawRecords: GadgetRecord<any>[] | null;
184+
}) => {
185+
const { option, selectedRows, clearSelection, rawRecords } = props;
186+
187+
const selectedRowsWithRawRecord = selectedRows.map((row) => ({
188+
...(rawRecords?.find((record) => record.id === row.id) ?? {}),
189+
...row,
190+
}));
191+
192+
return option.action
180193
? () => {
181-
option.action?.(selectedRows);
194+
option.action?.(selectedRowsWithRawRecord);
182195
clearSelection();
183196
}
184197
: option.selectModelAction ?? (() => undefined);
198+
};
185199

186200
export type AutoBulkActionModal = {
187201
model: any;

packages/react/src/auto/polaris/PolarisAutoTable.tsx

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,31 @@ const PolarisAutoTableComponent = <
174174
const selectedRows = (rows ?? []).filter((row) => selection.recordIds.includes(row.id as string));
175175

176176
const promotedBulkActions = useMemo(
177-
() => bulkActionOptions.filter((option) => option.promoted).map(bulkActionOptionMapper(selectedRows, selection.clearAll)),
178-
[bulkActionOptions, selectedRows]
177+
() =>
178+
bulkActionOptions
179+
.filter((option) => option.promoted)
180+
.map(
181+
bulkActionOptionMapper({
182+
rawRecords,
183+
selectedRows,
184+
clearSelection: selection.clearAll,
185+
})
186+
),
187+
[bulkActionOptions, selectedRows, rawRecords, selection.clearAll]
179188
);
180189

181190
const bulkActions = useMemo(
182-
() => bulkActionOptions.filter((option) => !option.promoted).map(bulkActionOptionMapper(selectedRows, selection.clearAll)),
183-
[bulkActionOptions, selectedRows]
191+
() =>
192+
bulkActionOptions
193+
.filter((option) => !option.promoted)
194+
.map(
195+
bulkActionOptionMapper({
196+
rawRecords,
197+
selectedRows,
198+
clearSelection: selection.clearAll,
199+
})
200+
),
201+
[bulkActionOptions, selectedRows, rawRecords, selection.clearAll]
184202
);
185203

186204
if (!error && ((fetching && !rows) || !columns)) {
@@ -308,11 +326,15 @@ const disablePaginatedSelectAllButton = {
308326
paginatedSelectAllActionText: "", // Empty string to hide the select all button. We only allow selections on the current page.
309327
};
310328

311-
const bulkActionOptionMapper = (selectedRows: TableRow[], clearSelection: () => void) => {
329+
const bulkActionOptionMapper = (props: {
330+
rawRecords: GadgetRecord<any>[] | null;
331+
selectedRows: TableRow[];
332+
clearSelection: () => void;
333+
}) => {
312334
return (option: BulkActionOption) => ({
313335
id: option.humanizedName,
314336
destructive: "isDeleter" in option ? option.isDeleter : false,
315337
content: option.humanizedName,
316-
onAction: getBulkActionOptionCallback(option, selectedRows, clearSelection),
338+
onAction: getBulkActionOptionCallback({ option, ...props }),
317339
});
318340
};

packages/react/src/auto/shadcn/ShadcnAutoTable.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,12 @@ export const makeAutoTable = (elements: ShadcnElements) => {
302302
<div className="ml-auto">
303303
<div className="flex flex-row ml-auto gap-2 items-center">
304304
<Label className="ml-2">{`${selection.recordIds.length} selected`}</Label>
305-
<ShadcnAutoTableBulkActionSelector bulkActionOptions={bulkActionOptions} selection={selection} rows={rows} />
305+
<ShadcnAutoTableBulkActionSelector
306+
bulkActionOptions={bulkActionOptions}
307+
selection={selection}
308+
rows={rows}
309+
rawRecords={rawRecords}
310+
/>
306311
</div>
307312
</div>
308313
)}

packages/react/src/auto/shadcn/table/ShadcnAutoTableBulkActionSelector.tsx

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { type GadgetRecord } from "@gadgetinc/api-client-core";
12
import { ChevronsUpDown } from "lucide-react";
23
import React, { useMemo } from "react";
34
import { type TableRow } from "../../../use-table/types.js";
@@ -12,8 +13,9 @@ export const makeShadcnAutoTableBulkActionSelector = (elements: ShadcnElements)
1213
nonPromotedActions: BulkActionOption[];
1314
selection: RecordSelection;
1415
rows: TableRow[];
16+
rawRecords: GadgetRecord<any>[] | null;
1517
}) {
16-
const { nonPromotedActions, selection, rows } = props;
18+
const { nonPromotedActions, selection, rows, rawRecords } = props;
1719
const selectedRows = rows.filter((row) => selection.recordIds.includes(row.id as string));
1820

1921
const [open, setOpen] = React.useState(false);
@@ -45,7 +47,12 @@ export const makeShadcnAutoTableBulkActionSelector = (elements: ShadcnElements)
4547
key={i}
4648
className={"bg-background"}
4749
onSelect={() => {
48-
getBulkActionOptionCallback(action, selectedRows, selection.clearAll)();
50+
getBulkActionOptionCallback({
51+
option: action,
52+
selectedRows,
53+
clearSelection: selection.clearAll,
54+
rawRecords,
55+
})();
4956
}}
5057
>
5158
{action.humanizedName}
@@ -59,8 +66,13 @@ export const makeShadcnAutoTableBulkActionSelector = (elements: ShadcnElements)
5966
);
6067
}
6168

62-
function PromotedActionsActionSelector(props: { promotedActions: BulkActionOption[]; selection: RecordSelection; rows: TableRow[] }) {
63-
const { promotedActions, selection, rows } = props;
69+
function PromotedActionsActionSelector(props: {
70+
promotedActions: BulkActionOption[];
71+
selection: RecordSelection;
72+
rows: TableRow[];
73+
rawRecords: GadgetRecord<any>[] | null;
74+
}) {
75+
const { promotedActions, selection, rows, rawRecords } = props;
6476

6577
const selectedRows = rows.filter((row) => selection.recordIds.includes(row.id as string));
6678

@@ -71,7 +83,12 @@ export const makeShadcnAutoTableBulkActionSelector = (elements: ShadcnElements)
7183
variant="outline"
7284
key={action.humanizedName}
7385
onClick={() => {
74-
getBulkActionOptionCallback(action, selectedRows, selection.clearAll)();
86+
getBulkActionOptionCallback({
87+
option: action,
88+
selectedRows,
89+
clearSelection: selection.clearAll,
90+
rawRecords,
91+
})();
7592
}}
7693
>
7794
{action.humanizedName}
@@ -84,8 +101,9 @@ export const makeShadcnAutoTableBulkActionSelector = (elements: ShadcnElements)
84101
bulkActionOptions: BulkActionOption[];
85102
selection: RecordSelection;
86103
rows: TableRow[];
104+
rawRecords: GadgetRecord<any>[] | null;
87105
}) {
88-
const { bulkActionOptions, selection, rows } = props;
106+
const { bulkActionOptions, selection, rows, rawRecords } = props;
89107

90108
const { promotedActions, nonPromotedActions } = useMemo(() => {
91109
const promotedActions = [];
@@ -104,8 +122,13 @@ export const makeShadcnAutoTableBulkActionSelector = (elements: ShadcnElements)
104122

105123
return (
106124
<>
107-
<PromotedActionsActionSelector promotedActions={promotedActions} selection={selection} rows={rows} />
108-
<NonPromotedActionsActionSelector nonPromotedActions={nonPromotedActions} selection={selection} rows={rows} />
125+
<PromotedActionsActionSelector promotedActions={promotedActions} selection={selection} rows={rows} rawRecords={rawRecords} />
126+
<NonPromotedActionsActionSelector
127+
nonPromotedActions={nonPromotedActions}
128+
selection={selection}
129+
rows={rows}
130+
rawRecords={rawRecords}
131+
/>
109132
</>
110133
);
111134
}

0 commit comments

Comments
 (0)