From 5198fdad55783045c1a7f05f749d33931a06ca33 Mon Sep 17 00:00:00 2001 From: Christoph Dyllick-Brenzinger Date: Mon, 29 Jan 2024 10:08:13 +0100 Subject: [PATCH] supporting big data backend with links and row create, update and delete --- .../nodes/SeaTable/SeaTable.node.ts | 2 +- .../nodes/SeaTable/v2/GenericFunctions.ts | 30 ++++++++++++++++ .../v2/actions/link/add/description.ts | 6 ++-- .../SeaTable/v2/actions/link/add/execute.ts | 19 +++++----- .../v2/actions/link/remove/description.ts | 5 ++- .../v2/actions/link/remove/execute.ts | 19 +++++----- .../v2/actions/row/create/description.ts | 18 ++++++++-- .../SeaTable/v2/actions/row/create/execute.ts | 35 +++++++++++++------ .../v2/actions/row/remove/description.ts | 1 + .../SeaTable/v2/actions/row/remove/execute.ts | 4 +-- .../v2/actions/row/update/description.ts | 7 ++-- .../SeaTable/v2/actions/row/update/execute.ts | 16 +++++---- .../nodes/SeaTable/v2/methods/loadOptions.ts | 16 ++++++--- 13 files changed, 127 insertions(+), 51 deletions(-) diff --git a/packages/nodes-base/nodes/SeaTable/SeaTable.node.ts b/packages/nodes-base/nodes/SeaTable/SeaTable.node.ts index c8d066736b..20985d3dc5 100644 --- a/packages/nodes-base/nodes/SeaTable/SeaTable.node.ts +++ b/packages/nodes-base/nodes/SeaTable/SeaTable.node.ts @@ -8,7 +8,7 @@ export class SeaTable extends VersionedNodeType { constructor() { const baseDescription: INodeTypeBaseDescription = { displayName: 'SeaTable', - name: 'seaTable', + name: 'seatable', icon: 'file:seatable.svg', group: ['output'], subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}', diff --git a/packages/nodes-base/nodes/SeaTable/v2/GenericFunctions.ts b/packages/nodes-base/nodes/SeaTable/v2/GenericFunctions.ts index 6f57e50efe..b473f1ba20 100644 --- a/packages/nodes-base/nodes/SeaTable/v2/GenericFunctions.ts +++ b/packages/nodes-base/nodes/SeaTable/v2/GenericFunctions.ts @@ -29,6 +29,9 @@ import type { IFile, } from './actions/Interfaces'; +// for date transformations +import moment from 'moment'; + // remove last backslash const userBaseUri = (uri?: string) => { if (uri === undefined) return uri; @@ -310,6 +313,33 @@ export function splitStringColumnsToArrays( row[column.name] = input.split(',').map((item) => item.trim()); } } + if (column.type == 'number') { + if (typeof row[column.name] === 'string') { + const input = row[column.name] as string; + row[column.name] = parseFloat(input); + } + } + if (column.type == 'rate' || column.type == 'duration') { + if (typeof row[column.name] === 'string') { + const input = row[column.name] as string; + row[column.name] = parseInt(input); + } + } + if (column.type == 'checkbox') { + if (typeof row[column.name] === 'string') { + const input = row[column.name] as string; + row[column.name] = false; + if (input === 'true' || input === 'on' || input === '1') { + row[column.name] = true; + } + } + } + if (column.type == 'date') { + if (typeof row[column.name] === 'string') { + const input = row[column.name] as string; + row[column.name] = moment(input, 'YYYY-mm-dd', true); + } + } }); return row; } diff --git a/packages/nodes-base/nodes/SeaTable/v2/actions/link/add/description.ts b/packages/nodes-base/nodes/SeaTable/v2/actions/link/add/description.ts index e82c1f6a46..e82e58cc7a 100644 --- a/packages/nodes-base/nodes/SeaTable/v2/actions/link/add/description.ts +++ b/packages/nodes-base/nodes/SeaTable/v2/actions/link/add/description.ts @@ -17,8 +17,7 @@ export const linkAddDescription: LinkProperties = [ }, }, default: '', - description: - 'The name of SeaTable table to access. Choose from the list, or specify a name using an expression.', + description: 'If you use an expression, provide it in the way ":::".', }, { displayName: 'Link column', @@ -36,7 +35,8 @@ export const linkAddDescription: LinkProperties = [ }, required: true, default: '', - description: 'Select the column to create a link.', + description: + 'If you use an expression, provide it in the way "::::::".', }, { displayName: 'Row ID from the source table', diff --git a/packages/nodes-base/nodes/SeaTable/v2/actions/link/add/execute.ts b/packages/nodes-base/nodes/SeaTable/v2/actions/link/add/execute.ts index 34fe83a8f0..d7c5286e38 100644 --- a/packages/nodes-base/nodes/SeaTable/v2/actions/link/add/execute.ts +++ b/packages/nodes-base/nodes/SeaTable/v2/actions/link/add/execute.ts @@ -7,18 +7,21 @@ export async function add(this: IExecuteFunctions, index: number): Promiseexpression.', + description: 'If you use an expression, provide it in the way ":::".', }, { displayName: 'Link column', @@ -36,7 +35,7 @@ export const linkRemoveDescription: LinkProperties = [ }, required: true, default: '', - description: 'Select the column to create a link.', + description: 'If you use an expression, provide it in the way "::::::".', }, { displayName: 'Row ID from the source table', diff --git a/packages/nodes-base/nodes/SeaTable/v2/actions/link/remove/execute.ts b/packages/nodes-base/nodes/SeaTable/v2/actions/link/remove/execute.ts index 0c9b7c9dfc..4f336dfca2 100644 --- a/packages/nodes-base/nodes/SeaTable/v2/actions/link/remove/execute.ts +++ b/packages/nodes-base/nodes/SeaTable/v2/actions/link/remove/execute.ts @@ -10,18 +10,21 @@ export async function remove( const linkColumnSourceId = this.getNodeParameter('linkColumnSourceId', index) as string; const linkColumnTargetId = this.getNodeParameter('linkColumnTargetId', index) as string; + const body = { + link_id: linkColumn.split(':::')[1], + table_id: tableName.split(':::')[1], + other_table_id: linkColumn.split(':::')[2], + other_rows_ids_map: { + [linkColumnSourceId]: [linkColumnTargetId], + }, + }; + const responseData = await seaTableApiRequest.call( this, {}, 'DELETE', - '/dtable-server/api/v1/dtables/{{dtable_uuid}}/links/', - { - link_id: linkColumn.split(':::')[1], - table_id: tableName.split(':::')[1], - table_row_id: linkColumnSourceId, - other_table_id: linkColumn.split(':::')[2], - other_table_row_id: linkColumnTargetId, - }, + '/dtable-db/api/v1/base/{{dtable_uuid}}/links/', + body, ); return this.helpers.returnJsonArray(responseData as IDataObject[]); diff --git a/packages/nodes-base/nodes/SeaTable/v2/actions/row/create/description.ts b/packages/nodes-base/nodes/SeaTable/v2/actions/row/create/description.ts index 895b3b9b8f..702676f638 100644 --- a/packages/nodes-base/nodes/SeaTable/v2/actions/row/create/description.ts +++ b/packages/nodes-base/nodes/SeaTable/v2/actions/row/create/description.ts @@ -80,7 +80,7 @@ export const rowCreateDescription: RowProperties = [ name: 'columnName', type: 'options', description: - 'Choose from the list, or specify an ID using an expression', + 'Choose from the list, or specify the column name using an expression', typeOptions: { loadOptionsDependsOn: ['tableName'], loadOptionsMethod: 'getTableUpdateAbleColumns', @@ -104,7 +104,21 @@ export const rowCreateDescription: RowProperties = [ }, }, default: {}, - description: 'Add destination column with its value', + description: + 'Add destination column with its value. Provide the value in this way:
Date: YYYY-MM-DD or YYYY-MM-DD hh:mm
Duration: time in seconds
Checkbox: true, on or 1
Multi-Select: comma separated list', + }, + { + displayName: 'Save to "Big Data" backend', + name: 'bigdata', + type: 'boolean', + displayOptions: { + show: { + resource: ['row'], + operation: ['create'], + }, + }, + default: false, + description: 'This requires the activation of the Big Data backend in the base.', }, { displayName: 'Hint: Link, files, images or digital signatures have to be added separately.', diff --git a/packages/nodes-base/nodes/SeaTable/v2/actions/row/create/execute.ts b/packages/nodes-base/nodes/SeaTable/v2/actions/row/create/execute.ts index 7ffef50455..756b3d203a 100644 --- a/packages/nodes-base/nodes/SeaTable/v2/actions/row/create/execute.ts +++ b/packages/nodes-base/nodes/SeaTable/v2/actions/row/create/execute.ts @@ -19,6 +19,7 @@ export async function create( const fieldsToSend = this.getNodeParameter('fieldsToSend', index) as | 'defineBelow' | 'autoMapInputData'; + const bigdata = this.getNodeParameter('bigdata', index) as string; const body = { table_name: tableName, @@ -48,15 +49,29 @@ export async function create( // string to array: multi-select and collaborators rowInput = splitStringColumnsToArrays(rowInput, tableColumns); - body.row = rowInput; + // save to big data backend + if (bigdata) { + body.rows = [rowInput]; + const responseData = await seaTableApiRequest.call( + this, + {}, + 'POST', + '/dtable-db/api/v1/insert-rows/{{dtable_uuid}}/', + body, + ); + return this.helpers.returnJsonArray(responseData as IDataObject[]); + } + // save to normal backend + else { + body.row = rowInput; - const responseData = await seaTableApiRequest.call( - this, - {}, - 'POST', - '/dtable-server/api/v1/dtables/{{dtable_uuid}}/rows/', - body, - ); - - return this.helpers.returnJsonArray(responseData as IDataObject[]); + const responseData = await seaTableApiRequest.call( + this, + {}, + 'POST', + '/dtable-server/api/v1/dtables/{{dtable_uuid}}/rows/', + body, + ); + return this.helpers.returnJsonArray(responseData as IDataObject[]); + } } diff --git a/packages/nodes-base/nodes/SeaTable/v2/actions/row/remove/description.ts b/packages/nodes-base/nodes/SeaTable/v2/actions/row/remove/description.ts index fca64f49dc..1a253ef2a0 100644 --- a/packages/nodes-base/nodes/SeaTable/v2/actions/row/remove/description.ts +++ b/packages/nodes-base/nodes/SeaTable/v2/actions/row/remove/description.ts @@ -36,5 +36,6 @@ export const rowRemoveDescription: RowProperties = [ }, }, default: '', + description: 'Remove any row from the normal or big data backend based on its unique row ID.', }, ]; diff --git a/packages/nodes-base/nodes/SeaTable/v2/actions/row/remove/execute.ts b/packages/nodes-base/nodes/SeaTable/v2/actions/row/remove/execute.ts index 62e5d0b684..d958b0e5ef 100644 --- a/packages/nodes-base/nodes/SeaTable/v2/actions/row/remove/execute.ts +++ b/packages/nodes-base/nodes/SeaTable/v2/actions/row/remove/execute.ts @@ -10,14 +10,14 @@ export async function remove( const requestBody: IDataObject = { table_name: tableName, - row_id: rowId, + row_ids: [rowId], }; const responseData = await seaTableApiRequest.call( this, {}, 'DELETE', - '/dtable-server/api/v1/dtables/{{dtable_uuid}}/rows/', + '/dtable-db/api/v1/delete-rows/{{dtable_uuid}}/', requestBody, ); diff --git a/packages/nodes-base/nodes/SeaTable/v2/actions/row/update/description.ts b/packages/nodes-base/nodes/SeaTable/v2/actions/row/update/description.ts index f61b64d5ff..29e0659cac 100644 --- a/packages/nodes-base/nodes/SeaTable/v2/actions/row/update/description.ts +++ b/packages/nodes-base/nodes/SeaTable/v2/actions/row/update/description.ts @@ -26,7 +26,7 @@ export const rowUpdateDescription: RowProperties = [ type: 'options', required: true, typeOptions: { - loadOptionsDependsOn: ['tableName'], + loadOptionsDependsOn: ['tableName'], loadOptionsMethod: 'getRowIds', }, displayOptions: { @@ -97,7 +97,7 @@ export const rowUpdateDescription: RowProperties = [ name: 'columnName', type: 'options', description: - 'Choose from the list, or specify an ID using an expression', + 'Choose from the list, or specify the column name using an expression', typeOptions: { loadOptionsDependsOn: ['tableName'], loadOptionsMethod: 'getTableUpdateAbleColumns', @@ -121,7 +121,8 @@ export const rowUpdateDescription: RowProperties = [ }, }, default: {}, - description: 'Add destination column with its value', + description: + 'Add destination column with its value. Provide the value in this way:
Date: YYYY-MM-DD or YYYY-MM-DD hh:mm
Duration: time in seconds
Checkbox: true, on or 1
Multi-Select: comma separated list', }, { displayName: 'Hint: Link, files, images or digital signatures have to be added separately.', diff --git a/packages/nodes-base/nodes/SeaTable/v2/actions/row/update/execute.ts b/packages/nodes-base/nodes/SeaTable/v2/actions/row/update/execute.ts index 37a7435789..1d19faffdb 100644 --- a/packages/nodes-base/nodes/SeaTable/v2/actions/row/update/execute.ts +++ b/packages/nodes-base/nodes/SeaTable/v2/actions/row/update/execute.ts @@ -21,10 +21,6 @@ export async function update( | 'autoMapInputData'; const rowId = this.getNodeParameter('rowId', index) as string; - const body = { - table_name: tableName, - row_id: rowId, - } as IDataObject; let rowInput = {} as IRowObject; // get rowInput, an object of key:value pairs like { Name: 'Promo Action 1', Status: "Draft" }. @@ -49,13 +45,21 @@ export async function update( // string to array: multi-select and collaborators rowInput = splitStringColumnsToArrays(rowInput, tableColumns); - body.row = rowInput; + const body = { + table_name: tableName, + updates: [ + { + row_id: rowId, + row: rowInput, + }, + ], + } as IDataObject; const responseData = await seaTableApiRequest.call( this, {}, 'PUT', - '/dtable-server/api/v1/dtables/{{dtable_uuid}}/rows/', + '/dtable-db/api/v1/update-rows/{{dtable_uuid}}/', body, ); diff --git a/packages/nodes-base/nodes/SeaTable/v2/methods/loadOptions.ts b/packages/nodes-base/nodes/SeaTable/v2/methods/loadOptions.ts index 9f6f0518f0..c9c12387fc 100644 --- a/packages/nodes-base/nodes/SeaTable/v2/methods/loadOptions.ts +++ b/packages/nodes-base/nodes/SeaTable/v2/methods/loadOptions.ts @@ -37,7 +37,7 @@ export async function getTableNameAndId( for (const table of tables) { returnData.push({ name: table.name, - value: table.name + ':::' + table._id, + value: table.name + ':::' + table['_id'], }); } return returnData; @@ -80,9 +80,11 @@ export async function getSearchableColumns( export async function getLinkColumns(this: ILoadOptionsFunctions): Promise { const returnData: INodePropertyOptions[] = []; - let tableName = this.getCurrentNodeParameter('tableName') as string; - tableName = tableName.split(':::')[0]; - //const tableId = (tableName.split(':::')[1] ? tableName.split(':::')[1] : ""); + const table = this.getCurrentNodeParameter('tableName') as string; + + const tableName = table.split(':::')[0]; + const tableId = table.split(':::')[1]; + if (tableName) { const columns = await seaTableApiRequest.call( this, @@ -94,9 +96,13 @@ export async function getLinkColumns(this: ILoadOptionsFunctions): Promise