Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { nocodbAuth } from '../../';
|
||||
import { createAction, DynamicPropsValue } from '@activepieces/pieces-framework';
|
||||
import { makeClient, nocodbCommon } from '../common';
|
||||
|
||||
export const createRecordAction = createAction({
|
||||
auth: nocodbAuth,
|
||||
name: 'nocodb-create-record',
|
||||
displayName: 'Create a Record',
|
||||
description: 'Creates a new record in the given table.',
|
||||
props: {
|
||||
workspaceId: nocodbCommon.workspaceId,
|
||||
baseId: nocodbCommon.baseId,
|
||||
tableId: nocodbCommon.tableId,
|
||||
tableColumns: nocodbCommon.tableColumns,
|
||||
},
|
||||
async run(context) {
|
||||
const { baseId, tableId, tableColumns } = context.propsValue;
|
||||
const recordInput: DynamicPropsValue = {};
|
||||
|
||||
Object.entries(tableColumns).forEach(([key, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
recordInput[key] = value.join(',');
|
||||
} else {
|
||||
recordInput[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
const client = makeClient(context.auth);
|
||||
return await client.createRecord(baseId, tableId, recordInput, context.auth.props.version || 3);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import { nocodbAuth } from '../../';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { makeClient, nocodbCommon } from '../common';
|
||||
|
||||
export const deleteRecordAction = createAction({
|
||||
auth: nocodbAuth,
|
||||
name: 'nocodb-delete-record',
|
||||
displayName: 'Delete a Record',
|
||||
description: 'Deletes a record with the given Record ID.',
|
||||
props: {
|
||||
workspaceId: nocodbCommon.workspaceId,
|
||||
baseId: nocodbCommon.baseId,
|
||||
tableId: nocodbCommon.tableId,
|
||||
recordId: Property.Number({
|
||||
displayName: 'Record ID',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { baseId, tableId, recordId } = context.propsValue;
|
||||
|
||||
const client = makeClient(context.auth);
|
||||
return await client.deleteRecord(baseId, tableId, recordId, context.auth.props.version || 3);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import { nocodbAuth } from '../../';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { makeClient, nocodbCommon } from '../common';
|
||||
|
||||
export const getRecordAction = createAction({
|
||||
auth: nocodbAuth,
|
||||
name: 'nocodb-get-record',
|
||||
displayName: 'Get a Record',
|
||||
description: 'Gets a record by the Record ID.',
|
||||
props: {
|
||||
workspaceId: nocodbCommon.workspaceId,
|
||||
baseId: nocodbCommon.baseId,
|
||||
tableId: nocodbCommon.tableId,
|
||||
recordId: Property.Number({
|
||||
displayName: 'Record ID',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { baseId, tableId, recordId } = context.propsValue;
|
||||
|
||||
const client = makeClient(context.auth);
|
||||
return await client.getRecord(baseId, tableId, recordId, context.auth.props.version || 3);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import { nocodbAuth } from '../../';
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { makeClient, nocodbCommon } from '../common';
|
||||
import { ListAPIResponse, ListAPIV3Response } from '../common/types';
|
||||
|
||||
export const searchRecordsAction = createAction({
|
||||
auth: nocodbAuth,
|
||||
name: 'nocodb-search-records',
|
||||
displayName: 'Search Records',
|
||||
description: 'Returns a list of records matching the where condition.',
|
||||
props: {
|
||||
workspaceId: nocodbCommon.workspaceId,
|
||||
baseId: nocodbCommon.baseId,
|
||||
tableId: nocodbCommon.tableId,
|
||||
columnId: nocodbCommon.columnId,
|
||||
whereCondition: Property.LongText({
|
||||
displayName: 'Where',
|
||||
required: false,
|
||||
description: `Enables you to define specific conditions for filtering records.See docs [here](https://docs.nocodb.com/0.109.7/developer-resources/rest-apis/#comparison-operators).`,
|
||||
}),
|
||||
limit: Property.Number({
|
||||
displayName: 'Limit',
|
||||
required: true,
|
||||
defaultValue: 10,
|
||||
description:
|
||||
'Enables you to set a limit on the number of records you want to retrieve.',
|
||||
}),
|
||||
sort: Property.LongText({
|
||||
displayName: 'Sort',
|
||||
required: false,
|
||||
description: `Comma separated field names without space.Example: **field1,-field2** will sort the records first by 'field1' in ascending order and then by 'field2' in descending order.`,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { baseId, tableId, columnId, limit, whereCondition, sort } =
|
||||
context.propsValue;
|
||||
|
||||
const client = makeClient(context.auth);
|
||||
const authVersion = context.auth.props.version || 3;
|
||||
const response = await client.listRecords(
|
||||
baseId,
|
||||
tableId,
|
||||
{
|
||||
fields: columnId ? columnId.join(',') : undefined,
|
||||
where: whereCondition,
|
||||
sort,
|
||||
offset: 0,
|
||||
limit,
|
||||
},
|
||||
authVersion
|
||||
);
|
||||
return authVersion === 4
|
||||
? (response as ListAPIV3Response<Record<string, unknown>>).records
|
||||
: (response as ListAPIResponse<Record<string, unknown>>).list;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,53 @@
|
||||
import { nocodbAuth } from '../../';
|
||||
import {
|
||||
createAction,
|
||||
DynamicPropsValue,
|
||||
Property,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { makeClient, nocodbCommon } from '../common';
|
||||
|
||||
export const updateRecordAction = createAction({
|
||||
auth: nocodbAuth,
|
||||
name: 'nocodb-update-record',
|
||||
displayName: 'Update a Record',
|
||||
description: 'Updates an existing record with the given Record ID.',
|
||||
props: {
|
||||
workspaceId: nocodbCommon.workspaceId,
|
||||
baseId: nocodbCommon.baseId,
|
||||
tableId: nocodbCommon.tableId,
|
||||
recordId: Property.Number({
|
||||
displayName: 'Record ID',
|
||||
required: true,
|
||||
}),
|
||||
tableColumns: nocodbCommon.tableColumns,
|
||||
},
|
||||
async run(context) {
|
||||
const { baseId, tableId, recordId, tableColumns } = context.propsValue;
|
||||
|
||||
const authVersion = context.auth.props.version || 3;
|
||||
let recordInput: DynamicPropsValue = {};
|
||||
if (authVersion === 4) {
|
||||
recordInput['id'] = recordId;
|
||||
recordInput['fields'] = {};
|
||||
} else {
|
||||
recordInput = {
|
||||
Id: recordId,
|
||||
};
|
||||
}
|
||||
|
||||
Object.entries(tableColumns).forEach(([key, value]) => {
|
||||
if(authVersion === 4) {
|
||||
recordInput['fields'][key] = value;
|
||||
} else {
|
||||
if (Array.isArray(value)) {
|
||||
recordInput[key] = value.join(',');
|
||||
} else {
|
||||
recordInput[key] = value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const client = makeClient(context.auth);
|
||||
return await client.updateRecord(baseId, tableId, recordInput, authVersion);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,266 @@
|
||||
import {
|
||||
HttpMessageBody,
|
||||
HttpMethod,
|
||||
QueryParams,
|
||||
httpClient,
|
||||
HttpRequest,
|
||||
} from '@activepieces/pieces-common';
|
||||
import {
|
||||
BaseResponse,
|
||||
DataOperationResponse,
|
||||
DataOperationV3Response,
|
||||
GetTableResponse,
|
||||
GetTableV3Response,
|
||||
ListAPIResponse,
|
||||
ListAPIV3Response,
|
||||
ListRecordsParams,
|
||||
TableResponse,
|
||||
WorkspaceResponse,
|
||||
} from './types';
|
||||
|
||||
export class NocoDBClient {
|
||||
constructor(private hostUrl: string, private apiToken: string) {}
|
||||
|
||||
async makeRequest<T extends HttpMessageBody>(
|
||||
method: HttpMethod,
|
||||
resourceUri: string,
|
||||
query?: Record<string, string | number | string[] | undefined>,
|
||||
body: Record<string, unknown> | undefined = undefined
|
||||
): Promise<T> {
|
||||
const baseUrl = this.hostUrl.replace(/\/$/, '');
|
||||
const params: QueryParams = {};
|
||||
if (query) {
|
||||
for (const [key, value] of Object.entries(query)) {
|
||||
if (value !== null && value !== undefined) {
|
||||
params[key] = String(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
const request: HttpRequest = {
|
||||
method: method,
|
||||
url: baseUrl + '/api' + resourceUri,
|
||||
headers: {
|
||||
'xc-token': this.apiToken,
|
||||
},
|
||||
queryParams: params,
|
||||
body: body,
|
||||
};
|
||||
const response = await httpClient.sendRequest<T>(request);
|
||||
return response.body;
|
||||
}
|
||||
|
||||
async listWorkspaces(): Promise<ListAPIResponse<WorkspaceResponse>> {
|
||||
return await this.makeRequest<ListAPIResponse<WorkspaceResponse>>(
|
||||
HttpMethod.GET,
|
||||
'/v1/workspaces/'
|
||||
);
|
||||
}
|
||||
|
||||
async listBases(
|
||||
workspaceId?: string,
|
||||
version = 3
|
||||
): Promise<ListAPIResponse<BaseResponse>> {
|
||||
if (workspaceId && workspaceId !== 'none') {
|
||||
// Cloud version
|
||||
const endpoint =
|
||||
version === 4
|
||||
? `/v3/meta/workspaces/${workspaceId}/bases/`
|
||||
: `/v1/workspaces/${workspaceId}/bases/`;
|
||||
return await this.makeRequest<ListAPIResponse<BaseResponse>>(
|
||||
HttpMethod.GET,
|
||||
endpoint
|
||||
);
|
||||
} else {
|
||||
// Self-hosted version
|
||||
const endpoint =
|
||||
version === 4
|
||||
? '/v3/meta/workspaces/nc/bases/'
|
||||
: version === 3
|
||||
? '/v2/meta/bases/'
|
||||
: '/v1/db/meta/projects/';
|
||||
|
||||
return await this.makeRequest<ListAPIResponse<BaseResponse>>(
|
||||
HttpMethod.GET,
|
||||
endpoint
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async listTables(
|
||||
baseId: string,
|
||||
version = 3
|
||||
): Promise<ListAPIResponse<TableResponse>> {
|
||||
const endpoint =
|
||||
version === 4
|
||||
? `/v3/meta/bases/${baseId}/tables`
|
||||
: version === 3
|
||||
? `/v2/meta/bases/${baseId}/tables`
|
||||
: `/v1/db/meta/projects/${baseId}/tables`;
|
||||
return await this.makeRequest<ListAPIResponse<TableResponse>>(
|
||||
HttpMethod.GET,
|
||||
endpoint
|
||||
);
|
||||
}
|
||||
|
||||
async getTable(
|
||||
_baseId: string,
|
||||
tableId: string,
|
||||
version = 3
|
||||
): Promise<GetTableResponse> {
|
||||
const endpoint =
|
||||
version === 3
|
||||
? `/v2/meta/tables/${tableId}/`
|
||||
: `/v1/db/meta/tables/${tableId}/`;
|
||||
return await this.makeRequest<GetTableResponse>(HttpMethod.GET, endpoint);
|
||||
}
|
||||
|
||||
async getTableV3(
|
||||
baseId: string,
|
||||
tableId: string,
|
||||
_version = 4
|
||||
): Promise<GetTableV3Response> {
|
||||
const endpoint = `/v3/meta/bases/${baseId}/tables/${tableId}`;
|
||||
return await this.makeRequest<GetTableV3Response>(HttpMethod.GET, endpoint);
|
||||
}
|
||||
|
||||
async createRecord(
|
||||
baseId: string,
|
||||
tableId: string,
|
||||
recordInput: Record<string, unknown>,
|
||||
version = 3
|
||||
) {
|
||||
const endpoint =
|
||||
version === 4
|
||||
? `/v3/data/${baseId}/${tableId}/records`
|
||||
: version === 3
|
||||
? `/v2/tables/${tableId}/records`
|
||||
: `/v1/db/data/noco/${tableId}`;
|
||||
const response = await this.makeRequest<DataOperationResponse>(
|
||||
HttpMethod.POST,
|
||||
endpoint,
|
||||
undefined,
|
||||
version === 4 ? { fields: recordInput } : recordInput
|
||||
);
|
||||
if (version === 4) {
|
||||
return (response as DataOperationV3Response).records?.[0] ?? response;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
async getRecord(
|
||||
baseId: string,
|
||||
tableId: string,
|
||||
recordId: number,
|
||||
version = 3
|
||||
) {
|
||||
const endpoint =
|
||||
version === 4
|
||||
? `/v3/data/${baseId}/${tableId}/records/${recordId}`
|
||||
: version === 3
|
||||
? `/v2/tables/${tableId}/records/${recordId}`
|
||||
: `/v1/db/data/noco/${tableId}/${recordId}`;
|
||||
return await this.makeRequest(HttpMethod.GET, endpoint);
|
||||
}
|
||||
|
||||
async updateRecord(
|
||||
baseId: string,
|
||||
tableId: string,
|
||||
recordInput: Record<string, unknown>,
|
||||
version = 3
|
||||
) {
|
||||
const endpoint =
|
||||
version === 4
|
||||
? `/v3/data/${baseId}/${tableId}/records`
|
||||
: version === 3
|
||||
? `/v2/tables/${tableId}/records/`
|
||||
: `/v1/db/data/noco/${tableId}`;
|
||||
|
||||
const response = await this.makeRequest<DataOperationResponse>(
|
||||
HttpMethod.PATCH,
|
||||
endpoint,
|
||||
undefined,
|
||||
recordInput
|
||||
);
|
||||
|
||||
if (version === 4) {
|
||||
return (response as DataOperationV3Response).records?.[0] ?? response;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
async deleteRecord(
|
||||
baseId: string,
|
||||
tableId: string,
|
||||
recordId: number,
|
||||
version = 3
|
||||
) {
|
||||
const endpoint =
|
||||
version === 4
|
||||
? `/v3/data/${baseId}/${tableId}/records/`
|
||||
: version === 3
|
||||
? `/v2/tables/${tableId}/records/`
|
||||
: `/v1/db/data/noco/${tableId}/${recordId}`;
|
||||
const body =
|
||||
version === 4
|
||||
? { id: recordId }
|
||||
: version === 3
|
||||
? { Id: recordId }
|
||||
: undefined;
|
||||
const response = await this.makeRequest<DataOperationResponse>(HttpMethod.DELETE, endpoint, undefined, body);
|
||||
|
||||
if (version === 4) {
|
||||
return (response as DataOperationV3Response).records?.[0] ?? response;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async listRecords(
|
||||
baseId: string,
|
||||
tableId: string,
|
||||
params: ListRecordsParams,
|
||||
version = 3
|
||||
): Promise<
|
||||
| ListAPIResponse<Record<string, unknown>>
|
||||
| ListAPIV3Response<Record<string, unknown>>
|
||||
> {
|
||||
const endpoint =
|
||||
version === 4
|
||||
? `/v3/data/${baseId}/${tableId}/records`
|
||||
: version === 3
|
||||
? `/v2/tables/${tableId}/records/`
|
||||
: `/v1/db/data/noco/${tableId}`;
|
||||
|
||||
if (version === 4 && params.sort && typeof params.sort === 'string') {
|
||||
const sortItems = params.sort.split(',');
|
||||
// format to v3
|
||||
params.sort = JSON.stringify(
|
||||
sortItems.map((item) => {
|
||||
if (item.startsWith('-')) {
|
||||
return {
|
||||
field: item.substring(1),
|
||||
direction: 'desc',
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
field: item,
|
||||
direction: 'asc',
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const makeRequest = async <T>() => {
|
||||
return await this.makeRequest<T>(HttpMethod.GET, endpoint, params);
|
||||
};
|
||||
if (version === 4) {
|
||||
return makeRequest<ListAPIV3Response<Record<string, unknown>>>();
|
||||
} else {
|
||||
return makeRequest<ListAPIResponse<Record<string, unknown>>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,370 @@
|
||||
import { nocodbAuth } from '../../';
|
||||
import {
|
||||
DynamicPropsValue,
|
||||
AppConnectionValueForAuthProperty,
|
||||
Property,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import { NocoDBClient } from './client';
|
||||
import {
|
||||
ColumnResponse,
|
||||
ColumnV3Response,
|
||||
GetTableResponse,
|
||||
GetTableV3Response,
|
||||
} from './types';
|
||||
|
||||
export function makeClient(auth: AppConnectionValueForAuthProperty<typeof nocodbAuth>) {
|
||||
return new NocoDBClient(auth.props.baseUrl, auth.props.apiToken);
|
||||
}
|
||||
|
||||
export const nocodbCommon = {
|
||||
workspaceId: Property.Dropdown({
|
||||
auth:nocodbAuth,
|
||||
displayName: 'Workspace ID',
|
||||
refreshers: [],
|
||||
required: false,
|
||||
description: 'For self-hosted instances,select "No Workspace".',
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const client = makeClient(
|
||||
auth
|
||||
);
|
||||
try {
|
||||
const response = await client.listWorkspaces();
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.list.map((workspace) => {
|
||||
return {
|
||||
label: workspace.title,
|
||||
value: workspace.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: false,
|
||||
options: [
|
||||
{
|
||||
label: 'No Workspace',
|
||||
value: 'none',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
},
|
||||
}),
|
||||
baseId: Property.Dropdown({
|
||||
auth:nocodbAuth,
|
||||
displayName: 'Base ID',
|
||||
refreshers: ['workspaceId'],
|
||||
required: true,
|
||||
options: async ({ auth, workspaceId }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const client = makeClient(
|
||||
auth
|
||||
);
|
||||
const response = await client.listBases(
|
||||
(workspaceId as string) || undefined,
|
||||
(auth).props.version || 3
|
||||
);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.list.map((base) => {
|
||||
return {
|
||||
label: base.title,
|
||||
value: base.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error fetching bases:', error);
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder:
|
||||
'Error fetching bases. Please check your connection and version.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
}),
|
||||
tableId: Property.Dropdown({
|
||||
auth:nocodbAuth,
|
||||
displayName: 'Table ID',
|
||||
refreshers: ['workspaceId', 'baseId'],
|
||||
required: true,
|
||||
options: async ({ auth, baseId }) => {
|
||||
if (!auth || !baseId) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first and select base.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const client = makeClient(
|
||||
auth
|
||||
);
|
||||
const response = await client.listTables(
|
||||
baseId as string,
|
||||
(auth ).props.version || 3
|
||||
);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.list.map((table) => {
|
||||
return {
|
||||
label: table.title,
|
||||
value: table.id,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
columnId: Property.MultiSelectDropdown({
|
||||
auth:nocodbAuth,
|
||||
displayName: 'Fields',
|
||||
description:
|
||||
'Allows you to specify the fields that you wish to include in your API response. By default, all the fields are included in the response.',
|
||||
refreshers: ['workspaceId', 'baseId', 'tableId'],
|
||||
required: false,
|
||||
options: async ({ auth, baseId, tableId }) => {
|
||||
if (!auth || !baseId || !tableId) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your account first and select base.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
const client = makeClient(
|
||||
auth
|
||||
);
|
||||
const authVersion =
|
||||
(auth ).props.version || 3;
|
||||
const response =
|
||||
authVersion === 4
|
||||
? await client.getTableV3(
|
||||
baseId as unknown as string,
|
||||
tableId as unknown as string,
|
||||
authVersion
|
||||
)
|
||||
: await client.getTable(
|
||||
baseId as unknown as string,
|
||||
tableId as unknown as string,
|
||||
authVersion
|
||||
);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options:
|
||||
authVersion === 4
|
||||
? (response as GetTableV3Response).fields.map((field) => {
|
||||
return {
|
||||
label: field.title,
|
||||
value: field.title,
|
||||
};
|
||||
})
|
||||
: (response as GetTableResponse).columns.map((column) => {
|
||||
return {
|
||||
label: column.title,
|
||||
value: column.title,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
}),
|
||||
tableColumns: Property.DynamicProperties({
|
||||
auth:nocodbAuth,
|
||||
displayName: 'Table Columns',
|
||||
refreshers: ['baseId', 'tableId'],
|
||||
required: true,
|
||||
props: async ({ auth, baseId, tableId }) => {
|
||||
if (!auth) return {};
|
||||
if (!baseId) return {};
|
||||
if (!tableId) return {};
|
||||
|
||||
const fields: DynamicPropsValue = {};
|
||||
|
||||
const client = makeClient(
|
||||
auth
|
||||
);
|
||||
const authVersion =
|
||||
(auth ).props.version || 3;
|
||||
const response =
|
||||
authVersion === 4
|
||||
? await client.getTableV3(
|
||||
baseId as unknown as string,
|
||||
tableId as unknown as string,
|
||||
authVersion
|
||||
)
|
||||
: await client.getTable(
|
||||
baseId as unknown as string,
|
||||
tableId as unknown as string,
|
||||
authVersion
|
||||
);
|
||||
|
||||
const columns =
|
||||
authVersion === 4
|
||||
? (response as GetTableV3Response).fields
|
||||
: (response as GetTableResponse).columns;
|
||||
|
||||
for (const column of (columns ?? [])) {
|
||||
const uidt =
|
||||
authVersion === 4
|
||||
? (column as ColumnV3Response).type
|
||||
: (column as ColumnResponse).uidt;
|
||||
|
||||
switch (uidt) {
|
||||
case 'SingleLineText':
|
||||
case 'PhoneNumber':
|
||||
case 'Email':
|
||||
case 'URL':
|
||||
fields[column.title] = Property.ShortText({
|
||||
displayName: column.title,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
case 'LongText':
|
||||
fields[column.title] = Property.LongText({
|
||||
displayName: column.title,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
case 'Number':
|
||||
case 'Decimal':
|
||||
case 'Percent':
|
||||
case 'Rating':
|
||||
case 'Currency':
|
||||
case 'Year':
|
||||
fields[column.title] = Property.Number({
|
||||
displayName: column.title,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
case 'Checkbox':
|
||||
fields[column.title] = Property.Checkbox({
|
||||
displayName: column.title,
|
||||
required: true,
|
||||
});
|
||||
break;
|
||||
case 'MultiSelect': {
|
||||
const getOptionsForAuthVersion4 = () => {
|
||||
const colOptions = (column as ColumnV3Response).options;
|
||||
return (colOptions?.['choices'] as any[])?.map((option) => {
|
||||
return {
|
||||
label: option.title,
|
||||
value: option.title,
|
||||
};
|
||||
});
|
||||
};
|
||||
const options =
|
||||
authVersion === 4
|
||||
? getOptionsForAuthVersion4()
|
||||
: (column as ColumnResponse).colOptions?.options?.map(
|
||||
(option) => {
|
||||
return {
|
||||
label: option.title,
|
||||
value: option.title,
|
||||
};
|
||||
}
|
||||
);
|
||||
fields[column.title] = Property.StaticMultiSelectDropdown({
|
||||
displayName: column.title,
|
||||
required: false,
|
||||
options: {
|
||||
disabled: false,
|
||||
options: options ?? [],
|
||||
},
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'SingleSelect': {
|
||||
const getOptionsForAuthVersion4 = () => {
|
||||
const colOptions = (column as ColumnV3Response).options;
|
||||
return (colOptions?.['choices'] as any[])?.map((option) => {
|
||||
return {
|
||||
label: option.title,
|
||||
value: option.title,
|
||||
};
|
||||
});
|
||||
};
|
||||
const options =
|
||||
authVersion === 4
|
||||
? getOptionsForAuthVersion4()
|
||||
: (column as ColumnResponse).colOptions?.options?.map(
|
||||
(option) => {
|
||||
return {
|
||||
label: option.title,
|
||||
value: option.title,
|
||||
};
|
||||
}
|
||||
);
|
||||
fields[column.title] = Property.StaticDropdown({
|
||||
displayName: column.title,
|
||||
required: false,
|
||||
options: {
|
||||
disabled: false,
|
||||
options: options ?? [],
|
||||
},
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'Date':{
|
||||
const columnMeta = authVersion === 4 ?
|
||||
(column as ColumnV3Response).options:
|
||||
(column as ColumnResponse).meta;
|
||||
fields[column.title] = Property.ShortText({
|
||||
displayName: column.title,
|
||||
required: false,
|
||||
description: columnMeta?.['date_format']
|
||||
? `Please provide date in ${columnMeta['date_format']} format.`
|
||||
: '',
|
||||
});
|
||||
break;}
|
||||
case 'Time':
|
||||
fields[column.title] = Property.ShortText({
|
||||
displayName: column.title,
|
||||
required: false,
|
||||
description: 'Please provide time in HH:mm:ss format.',
|
||||
});
|
||||
break;
|
||||
case 'DateTime':
|
||||
fields[column.title] = Property.DateTime({
|
||||
displayName: column.title,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
case 'JSON':
|
||||
fields[column.title] = Property.Json({
|
||||
displayName: column.title,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
fields[column.title] = Property.ShortText({
|
||||
displayName: column.title,
|
||||
required: false,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return fields;
|
||||
},
|
||||
}),
|
||||
};
|
||||
@@ -0,0 +1,150 @@
|
||||
export interface ListAPIV3Response<T> {
|
||||
records: T[];
|
||||
next?: string;
|
||||
prev?: string;
|
||||
}
|
||||
|
||||
export interface ListAPIResponse<T> {
|
||||
list: T[];
|
||||
pageInfo: {
|
||||
totalRows: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
isFirstPage: boolean;
|
||||
isLastPage: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export interface WorkspaceResponse {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
deleted: boolean;
|
||||
deleted_at: string;
|
||||
status: number;
|
||||
order: number;
|
||||
}
|
||||
|
||||
export interface BaseResponse {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
deleted: boolean;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
status: number;
|
||||
order: number;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface TableResponse {
|
||||
id: string;
|
||||
source_id: string;
|
||||
description: string;
|
||||
base_id: string;
|
||||
table_name: string;
|
||||
title: string;
|
||||
type: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
order: number;
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
type ColumnType =
|
||||
| 'Attachment'
|
||||
| 'AutoNumber'
|
||||
| 'Barcode'
|
||||
| 'Button'
|
||||
| 'Checkbox'
|
||||
| 'Collaborator'
|
||||
| 'Count'
|
||||
| 'CreatedTime'
|
||||
| 'Currency'
|
||||
| 'Date'
|
||||
| 'DateTime'
|
||||
| 'Decimal'
|
||||
| 'Duration'
|
||||
| 'Email'
|
||||
| 'Formula'
|
||||
| 'ForeignKey'
|
||||
| 'GeoData'
|
||||
| 'Geometry'
|
||||
| 'ID'
|
||||
| 'JSON'
|
||||
| 'LastModifiedTime'
|
||||
| 'LongText'
|
||||
| 'LinkToAnotherRecord'
|
||||
| 'Lookup'
|
||||
| 'MultiSelect'
|
||||
| 'Number'
|
||||
| 'Percent'
|
||||
| 'PhoneNumber'
|
||||
| 'Rating'
|
||||
| 'Rollup'
|
||||
| 'SingleLineText'
|
||||
| 'SingleSelect'
|
||||
| 'SpecificDBType'
|
||||
| 'Time'
|
||||
| 'URL'
|
||||
| 'Year'
|
||||
| 'QrCode'
|
||||
| 'Links'
|
||||
| 'User'
|
||||
| 'CreatedBy'
|
||||
| 'LastModifiedBy';
|
||||
|
||||
export interface ColumnResponse {
|
||||
id: string;
|
||||
title: string;
|
||||
column_name: string;
|
||||
uidt: ColumnType;
|
||||
colOptions?: {
|
||||
options: Array<{ title: string; id: string }>;
|
||||
};
|
||||
meta: Record<string, unknown> | null;
|
||||
}
|
||||
|
||||
export interface ColumnV3Response {
|
||||
id: string;
|
||||
title: string;
|
||||
type: ColumnType;
|
||||
options: Record<string, unknown> | null;
|
||||
}
|
||||
|
||||
export interface GetTableV3Response {
|
||||
id: string;
|
||||
title: string;
|
||||
fields: Array<ColumnV3Response>;
|
||||
}
|
||||
export interface GetTableResponse {
|
||||
id: string;
|
||||
source_id: string;
|
||||
table_name: string;
|
||||
title: string;
|
||||
type: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
order: number;
|
||||
enabled: boolean;
|
||||
columns: Array<ColumnResponse>;
|
||||
}
|
||||
|
||||
export interface ListRecordsParams
|
||||
extends Record<string, string | number | string[] | undefined> {
|
||||
fields?: string;
|
||||
sort?: string;
|
||||
where?: string;
|
||||
offset: number;
|
||||
limit: number;
|
||||
viewId?: string;
|
||||
filter?: string;
|
||||
}
|
||||
|
||||
export interface DataOperationV3Response {
|
||||
records: { id?: string | number; fields: Record<string, unknown> }[];
|
||||
}
|
||||
|
||||
export type DataOperationResponse =
|
||||
| Record<string, unknown>
|
||||
| DataOperationV3Response;
|
||||
Reference in New Issue
Block a user