Skip to content

Commit 37e585b

Browse files
caoxing9claude
andcommitted
fix(zapier): paginate the Record dropdown and label by primary field
The records dropdown ignored bundle.meta.page, so "Load more" couldn't reach records past the first page, and it labelled every option with the raw id. Page through the table via skip = page * 100, and use Teable's record `name` (the primary field value) as the label, falling back to the id. Adds `skip` support to listRecords; drops the now-unused isPrimary lookup. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent c291300 commit 37e585b

3 files changed

Lines changed: 19 additions & 16 deletions

File tree

packages/zapier/src/lib/records.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ interface ListRecordsOptions {
3030
tableId: string;
3131
viewId?: string;
3232
take?: number;
33+
skip?: number;
3334
}
3435

3536
// How many records each poll pulls. Teable can't sort by the system
@@ -43,9 +44,10 @@ const POLL_PAGE_SIZE = 600;
4344
const listRecords = async (
4445
z: ZObject,
4546
bundle: Bundle,
46-
{ tableId, viewId, take = POLL_PAGE_SIZE }: ListRecordsOptions,
47+
{ tableId, viewId, take = POLL_PAGE_SIZE, skip }: ListRecordsOptions,
4748
): Promise<IRecord[]> => {
4849
const params: Record<string, unknown> = { take, fieldKeyType: 'name' };
50+
if (skip) params.skip = skip;
4951
if (viewId) params.viewId = viewId;
5052
const response = await z.request<IRecordsVo>({
5153
url: apiUrl(bundle, `/table/${tableId}/record`),

packages/zapier/src/lib/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export interface TeableField {
1313
id: string;
1414
name: string;
1515
type: string;
16-
isPrimary?: boolean;
1716
options?: {
1817
choices?: Array<{ name: string }>;
1918
};

packages/zapier/src/triggers/records.ts

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,28 @@
11
import type { ZObject, Bundle } from 'zapier-platform-core';
22
import { listRecords } from '../lib/records';
3-
import { fetchFields } from '../lib/fields';
43
import type { DropdownItem } from '../lib/types';
54

5+
// How many records each dropdown page loads. Zapier calls perform again (with an
6+
// incremented bundle.meta.page) when the user clicks "Load more".
7+
const PAGE_SIZE = 100;
8+
69
// Hidden trigger powering the "Record" dropdown on actions/searches that take a
7-
// recordId (Update, Delete, Find Record by ID). Depends on a chosen tableId;
8-
// labels each record by its primary field value, falling back to the record id.
10+
// recordId (Update, Delete, Find Record by ID). Depends on a chosen tableId and
11+
// pages through the table so large tables stay reachable. Each record is
12+
// labelled by its primary field value (Teable's `name`), falling back to the id.
913
const perform = async (z: ZObject, bundle: Bundle): Promise<DropdownItem[]> => {
1014
const tableId = bundle.inputData.tableId as string | undefined;
1115
if (!tableId) return [];
12-
const [records, fields] = await Promise.all([
13-
listRecords(z, bundle, { tableId, take: 100 }),
14-
fetchFields(z, bundle, tableId),
15-
]);
16-
const primary = fields.find((f) => f.isPrimary);
17-
return records.map((r) => {
18-
const label = primary ? r.fields[primary.name] : undefined;
19-
return {
20-
id: r.id,
21-
name: label != null && label !== '' ? String(label) : r.id,
22-
};
16+
const page = (bundle.meta && (bundle.meta.page as number)) || 0;
17+
const records = await listRecords(z, bundle, {
18+
tableId,
19+
take: PAGE_SIZE,
20+
skip: page * PAGE_SIZE,
2321
});
22+
return records.map((r) => ({
23+
id: r.id,
24+
name: r.name && r.name !== '' ? r.name : r.id,
25+
}));
2426
};
2527

2628
export default {

0 commit comments

Comments
 (0)