mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-15 17:14:05 -08:00
supporting big data backend with links and row create, update and delete
This commit is contained in:
parent
787f33de4e
commit
5198fdad55
|
@ -8,7 +8,7 @@ export class SeaTable extends VersionedNodeType {
|
||||||
constructor() {
|
constructor() {
|
||||||
const baseDescription: INodeTypeBaseDescription = {
|
const baseDescription: INodeTypeBaseDescription = {
|
||||||
displayName: 'SeaTable',
|
displayName: 'SeaTable',
|
||||||
name: 'seaTable',
|
name: 'seatable',
|
||||||
icon: 'file:seatable.svg',
|
icon: 'file:seatable.svg',
|
||||||
group: ['output'],
|
group: ['output'],
|
||||||
subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}',
|
subtitle: '={{$parameter["resource"] + ": " + $parameter["operation"]}}',
|
||||||
|
|
|
@ -29,6 +29,9 @@ import type {
|
||||||
IFile,
|
IFile,
|
||||||
} from './actions/Interfaces';
|
} from './actions/Interfaces';
|
||||||
|
|
||||||
|
// for date transformations
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
// remove last backslash
|
// remove last backslash
|
||||||
const userBaseUri = (uri?: string) => {
|
const userBaseUri = (uri?: string) => {
|
||||||
if (uri === undefined) return uri;
|
if (uri === undefined) return uri;
|
||||||
|
@ -310,6 +313,33 @@ export function splitStringColumnsToArrays(
|
||||||
row[column.name] = input.split(',').map((item) => item.trim());
|
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;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,7 @@ export const linkAddDescription: LinkProperties = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description:
|
description: 'If you use an expression, provide it in the way "<table_name>:::<table_id>".',
|
||||||
'The name of SeaTable table to access. Choose from the list, or specify a name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Link column',
|
displayName: 'Link column',
|
||||||
|
@ -36,7 +35,8 @@ export const linkAddDescription: LinkProperties = [
|
||||||
},
|
},
|
||||||
required: true,
|
required: true,
|
||||||
default: '',
|
default: '',
|
||||||
description: 'Select the column to create a link.',
|
description:
|
||||||
|
'If you use an expression, provide it in the way "<column_name>:::<link_id>:::<other_table_id>".',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Row ID from the source table',
|
displayName: 'Row ID from the source table',
|
||||||
|
|
|
@ -7,18 +7,21 @@ export async function add(this: IExecuteFunctions, index: number): Promise<INode
|
||||||
const linkColumnSourceId = this.getNodeParameter('linkColumnSourceId', index) as string;
|
const linkColumnSourceId = this.getNodeParameter('linkColumnSourceId', index) as string;
|
||||||
const linkColumnTargetId = this.getNodeParameter('linkColumnTargetId', 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(
|
const responseData = await seaTableApiRequest.call(
|
||||||
this,
|
this,
|
||||||
{},
|
{},
|
||||||
'POST',
|
'POST',
|
||||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/links/',
|
'/dtable-db/api/v1/base/{{dtable_uuid}}/links/',
|
||||||
{
|
body,
|
||||||
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,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||||
|
|
|
@ -17,8 +17,7 @@ export const linkRemoveDescription: LinkProperties = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
description:
|
description: 'If you use an expression, provide it in the way "<table_name>:::<table_id>".',
|
||||||
'The name of SeaTable table to access. Choose from the list, or specify a name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>.',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Link column',
|
displayName: 'Link column',
|
||||||
|
@ -36,7 +35,7 @@ export const linkRemoveDescription: LinkProperties = [
|
||||||
},
|
},
|
||||||
required: true,
|
required: true,
|
||||||
default: '',
|
default: '',
|
||||||
description: 'Select the column to create a link.',
|
description: 'If you use an expression, provide it in the way "<column_name>:::<link_id>:::<other_table_id>".',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Row ID from the source table',
|
displayName: 'Row ID from the source table',
|
||||||
|
|
|
@ -10,18 +10,21 @@ export async function remove(
|
||||||
const linkColumnSourceId = this.getNodeParameter('linkColumnSourceId', index) as string;
|
const linkColumnSourceId = this.getNodeParameter('linkColumnSourceId', index) as string;
|
||||||
const linkColumnTargetId = this.getNodeParameter('linkColumnTargetId', 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(
|
const responseData = await seaTableApiRequest.call(
|
||||||
this,
|
this,
|
||||||
{},
|
{},
|
||||||
'DELETE',
|
'DELETE',
|
||||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/links/',
|
'/dtable-db/api/v1/base/{{dtable_uuid}}/links/',
|
||||||
{
|
body,
|
||||||
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,
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||||
|
|
|
@ -80,7 +80,7 @@ export const rowCreateDescription: RowProperties = [
|
||||||
name: 'columnName',
|
name: 'columnName',
|
||||||
type: 'options',
|
type: 'options',
|
||||||
description:
|
description:
|
||||||
'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
|
'Choose from the list, or specify the column name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
|
||||||
typeOptions: {
|
typeOptions: {
|
||||||
loadOptionsDependsOn: ['tableName'],
|
loadOptionsDependsOn: ['tableName'],
|
||||||
loadOptionsMethod: 'getTableUpdateAbleColumns',
|
loadOptionsMethod: 'getTableUpdateAbleColumns',
|
||||||
|
@ -104,7 +104,21 @@ export const rowCreateDescription: RowProperties = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: {},
|
default: {},
|
||||||
description: 'Add destination column with its value',
|
description:
|
||||||
|
'Add destination column with its value. Provide the value in this way:<br>Date: YYYY-MM-DD or YYYY-MM-DD hh:mm<br>Duration: time in seconds<br>Checkbox: true, on or 1<br>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.',
|
displayName: 'Hint: Link, files, images or digital signatures have to be added separately.',
|
||||||
|
|
|
@ -19,6 +19,7 @@ export async function create(
|
||||||
const fieldsToSend = this.getNodeParameter('fieldsToSend', index) as
|
const fieldsToSend = this.getNodeParameter('fieldsToSend', index) as
|
||||||
| 'defineBelow'
|
| 'defineBelow'
|
||||||
| 'autoMapInputData';
|
| 'autoMapInputData';
|
||||||
|
const bigdata = this.getNodeParameter('bigdata', index) as string;
|
||||||
|
|
||||||
const body = {
|
const body = {
|
||||||
table_name: tableName,
|
table_name: tableName,
|
||||||
|
@ -48,6 +49,20 @@ export async function create(
|
||||||
// string to array: multi-select and collaborators
|
// string to array: multi-select and collaborators
|
||||||
rowInput = splitStringColumnsToArrays(rowInput, tableColumns);
|
rowInput = splitStringColumnsToArrays(rowInput, tableColumns);
|
||||||
|
|
||||||
|
// 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;
|
body.row = rowInput;
|
||||||
|
|
||||||
const responseData = await seaTableApiRequest.call(
|
const responseData = await seaTableApiRequest.call(
|
||||||
|
@ -57,6 +72,6 @@ export async function create(
|
||||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/rows/',
|
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/rows/',
|
||||||
body,
|
body,
|
||||||
);
|
);
|
||||||
|
|
||||||
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
return this.helpers.returnJsonArray(responseData as IDataObject[]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,5 +36,6 @@ export const rowRemoveDescription: RowProperties = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
|
description: 'Remove any row from the normal or big data backend based on its unique row ID.',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -10,14 +10,14 @@ export async function remove(
|
||||||
|
|
||||||
const requestBody: IDataObject = {
|
const requestBody: IDataObject = {
|
||||||
table_name: tableName,
|
table_name: tableName,
|
||||||
row_id: rowId,
|
row_ids: [rowId],
|
||||||
};
|
};
|
||||||
|
|
||||||
const responseData = await seaTableApiRequest.call(
|
const responseData = await seaTableApiRequest.call(
|
||||||
this,
|
this,
|
||||||
{},
|
{},
|
||||||
'DELETE',
|
'DELETE',
|
||||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/rows/',
|
'/dtable-db/api/v1/delete-rows/{{dtable_uuid}}/',
|
||||||
requestBody,
|
requestBody,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ export const rowUpdateDescription: RowProperties = [
|
||||||
name: 'columnName',
|
name: 'columnName',
|
||||||
type: 'options',
|
type: 'options',
|
||||||
description:
|
description:
|
||||||
'Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
|
'Choose from the list, or specify the column name using an <a href="https://docs.n8n.io/code-examples/expressions/">expression</a>',
|
||||||
typeOptions: {
|
typeOptions: {
|
||||||
loadOptionsDependsOn: ['tableName'],
|
loadOptionsDependsOn: ['tableName'],
|
||||||
loadOptionsMethod: 'getTableUpdateAbleColumns',
|
loadOptionsMethod: 'getTableUpdateAbleColumns',
|
||||||
|
@ -121,7 +121,8 @@ export const rowUpdateDescription: RowProperties = [
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
default: {},
|
default: {},
|
||||||
description: 'Add destination column with its value',
|
description:
|
||||||
|
'Add destination column with its value. Provide the value in this way:<br>Date: YYYY-MM-DD or YYYY-MM-DD hh:mm<br>Duration: time in seconds<br>Checkbox: true, on or 1<br>Multi-Select: comma separated list',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Hint: Link, files, images or digital signatures have to be added separately.',
|
displayName: 'Hint: Link, files, images or digital signatures have to be added separately.',
|
||||||
|
|
|
@ -21,10 +21,6 @@ export async function update(
|
||||||
| 'autoMapInputData';
|
| 'autoMapInputData';
|
||||||
const rowId = this.getNodeParameter('rowId', index) as string;
|
const rowId = this.getNodeParameter('rowId', index) as string;
|
||||||
|
|
||||||
const body = {
|
|
||||||
table_name: tableName,
|
|
||||||
row_id: rowId,
|
|
||||||
} as IDataObject;
|
|
||||||
let rowInput = {} as IRowObject;
|
let rowInput = {} as IRowObject;
|
||||||
|
|
||||||
// get rowInput, an object of key:value pairs like { Name: 'Promo Action 1', Status: "Draft" }.
|
// 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
|
// string to array: multi-select and collaborators
|
||||||
rowInput = splitStringColumnsToArrays(rowInput, tableColumns);
|
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(
|
const responseData = await seaTableApiRequest.call(
|
||||||
this,
|
this,
|
||||||
{},
|
{},
|
||||||
'PUT',
|
'PUT',
|
||||||
'/dtable-server/api/v1/dtables/{{dtable_uuid}}/rows/',
|
'/dtable-db/api/v1/update-rows/{{dtable_uuid}}/',
|
||||||
body,
|
body,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ export async function getTableNameAndId(
|
||||||
for (const table of tables) {
|
for (const table of tables) {
|
||||||
returnData.push({
|
returnData.push({
|
||||||
name: table.name,
|
name: table.name,
|
||||||
value: table.name + ':::' + table._id,
|
value: table.name + ':::' + table['_id'],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return returnData;
|
return returnData;
|
||||||
|
@ -80,9 +80,11 @@ export async function getSearchableColumns(
|
||||||
|
|
||||||
export async function getLinkColumns(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
export async function getLinkColumns(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
|
||||||
const returnData: INodePropertyOptions[] = [];
|
const returnData: INodePropertyOptions[] = [];
|
||||||
let tableName = this.getCurrentNodeParameter('tableName') as string;
|
const table = this.getCurrentNodeParameter('tableName') as string;
|
||||||
tableName = tableName.split(':::')[0];
|
|
||||||
//const tableId = (tableName.split(':::')[1] ? tableName.split(':::')[1] : "");
|
const tableName = table.split(':::')[0];
|
||||||
|
const tableId = table.split(':::')[1];
|
||||||
|
|
||||||
if (tableName) {
|
if (tableName) {
|
||||||
const columns = await seaTableApiRequest.call(
|
const columns = await seaTableApiRequest.call(
|
||||||
this,
|
this,
|
||||||
|
@ -94,9 +96,13 @@ export async function getLinkColumns(this: ILoadOptionsFunctions): Promise<INode
|
||||||
);
|
);
|
||||||
for (const col of columns.columns) {
|
for (const col of columns.columns) {
|
||||||
if (col.type === 'link') {
|
if (col.type === 'link') {
|
||||||
|
// make sure that the "other table id" is returned and not the same table id again.
|
||||||
|
const otid =
|
||||||
|
tableId !== col.data.other_table_id ? col.data.other_table_id : col.data.table_id;
|
||||||
|
|
||||||
returnData.push({
|
returnData.push({
|
||||||
name: col.name,
|
name: col.name,
|
||||||
value: col.name + ':::' + col.data.link_id + ':::' + col.data.other_table_id,
|
value: col.name + ':::' + col.data.link_id + ':::' + otid,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue