mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 20:24:05 -08:00
✨ Add Sheet -> create/remove to GoogleSheets node(#1620)
* Add operation 'addSheet' to GoogleSheets node * lint fixes * ⚡ Improvements * ⚡ Move operations to "Sheet" Co-authored-by: dali <servfrdali@yahoo.fr> Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
parent
99bb6e40c1
commit
12838f26e3
|
@ -127,3 +127,19 @@ function getAccessToken(this: IExecuteFunctions | IExecuteSingleFunctions | ILoa
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
return this.helpers.request(options);
|
return this.helpers.request(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hex to RGB
|
||||||
|
export function hexToRgb(hex: string) {
|
||||||
|
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
|
||||||
|
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
||||||
|
hex = hex.replace(shorthandRegex, (m, r, g, b) => {
|
||||||
|
return r + r + g + g + b + b;
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||||
|
return result ? {
|
||||||
|
red: parseInt(result[1], 16),
|
||||||
|
green: parseInt(result[2], 16),
|
||||||
|
blue: parseInt(result[3], 16),
|
||||||
|
} : null;
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ import {
|
||||||
|
|
||||||
import {
|
import {
|
||||||
googleApiRequest,
|
googleApiRequest,
|
||||||
|
hexToRgb,
|
||||||
} from './GenericFunctions';
|
} from './GenericFunctions';
|
||||||
|
|
||||||
export class GoogleSheets implements INodeType {
|
export class GoogleSheets implements INodeType {
|
||||||
|
@ -121,6 +122,11 @@ export class GoogleSheets implements INodeType {
|
||||||
value: 'clear',
|
value: 'clear',
|
||||||
description: 'Clear data from a sheet',
|
description: 'Clear data from a sheet',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Create',
|
||||||
|
value: 'create',
|
||||||
|
description: 'Create a new sheet',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Delete',
|
name: 'Delete',
|
||||||
value: 'delete',
|
value: 'delete',
|
||||||
|
@ -136,6 +142,11 @@ export class GoogleSheets implements INodeType {
|
||||||
value: 'read',
|
value: 'read',
|
||||||
description: 'Read data from a sheet',
|
description: 'Read data from a sheet',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'Remove',
|
||||||
|
value: 'remove',
|
||||||
|
description: 'Remove a sheet',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Update',
|
name: 'Update',
|
||||||
value: 'update',
|
value: 'update',
|
||||||
|
@ -150,7 +161,7 @@ export class GoogleSheets implements INodeType {
|
||||||
// All
|
// All
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
{
|
{
|
||||||
displayName: 'Sheet ID',
|
displayName: 'Spreadsheet ID',
|
||||||
name: 'sheetId',
|
name: 'sheetId',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
displayOptions: {
|
displayOptions: {
|
||||||
|
@ -162,7 +173,7 @@ export class GoogleSheets implements INodeType {
|
||||||
},
|
},
|
||||||
default: '',
|
default: '',
|
||||||
required: true,
|
required: true,
|
||||||
description: 'The ID of the Google Sheet.<br />Found as part of the sheet URL https://docs.google.com/spreadsheets/d/{ID}/',
|
description: 'The ID of the Google Spreadsheet.<br />Found as part of the sheet URL https://docs.google.com/spreadsheets/d/{ID}/',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Range',
|
displayName: 'Range',
|
||||||
|
@ -176,7 +187,9 @@ export class GoogleSheets implements INodeType {
|
||||||
},
|
},
|
||||||
hide: {
|
hide: {
|
||||||
operation: [
|
operation: [
|
||||||
|
'create',
|
||||||
'delete',
|
'delete',
|
||||||
|
'remove',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -185,7 +198,6 @@ export class GoogleSheets implements INodeType {
|
||||||
description: 'The table range to read from or to append data to. See the Google <a href="https://developers.google.com/sheets/api/guides/values#writing">documentation</a> for the details.<br />If it contains multiple sheets it can also be<br />added like this: "MySheet!A:F"',
|
description: 'The table range to read from or to append data to. See the Google <a href="https://developers.google.com/sheets/api/guides/values#writing">documentation</a> for the details.<br />If it contains multiple sheets it can also be<br />added like this: "MySheet!A:F"',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
// Delete
|
// Delete
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
|
@ -392,8 +404,10 @@ export class GoogleSheets implements INodeType {
|
||||||
hide: {
|
hide: {
|
||||||
operation: [
|
operation: [
|
||||||
'append',
|
'append',
|
||||||
|
'create',
|
||||||
'clear',
|
'clear',
|
||||||
'delete',
|
'delete',
|
||||||
|
'remove',
|
||||||
],
|
],
|
||||||
rawData: [
|
rawData: [
|
||||||
true,
|
true,
|
||||||
|
@ -422,7 +436,9 @@ export class GoogleSheets implements INodeType {
|
||||||
hide: {
|
hide: {
|
||||||
operation: [
|
operation: [
|
||||||
'clear',
|
'clear',
|
||||||
|
'create',
|
||||||
'delete',
|
'delete',
|
||||||
|
'remove',
|
||||||
],
|
],
|
||||||
rawData: [
|
rawData: [
|
||||||
true,
|
true,
|
||||||
|
@ -596,7 +612,7 @@ export class GoogleSheets implements INodeType {
|
||||||
{
|
{
|
||||||
name: 'Formula',
|
name: 'Formula',
|
||||||
value: 'FORMULA',
|
value: 'FORMULA',
|
||||||
description: ' Values will not be calculated. The reply will include the formulas. For example, if A1 is 1.23 and A2 is =A1 and formatted as currency, then A2 would return "=A1".',
|
description: 'Values will not be calculated. The reply will include the formulas. For example, if A1 is 1.23 and A2 is =A1 and formatted as currency, then A2 would return "=A1".',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Unformatted Value',
|
name: 'Unformatted Value',
|
||||||
|
@ -793,6 +809,170 @@ export class GoogleSheets implements INodeType {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// sheet:create
|
||||||
|
// ----------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Simple',
|
||||||
|
name: 'simple',
|
||||||
|
type: 'boolean',
|
||||||
|
default: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'sheet',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'When set to true a simplify version of the response will be used else the raw data.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Options',
|
||||||
|
name: 'options',
|
||||||
|
type: 'collection',
|
||||||
|
placeholder: 'Add Option',
|
||||||
|
default: {},
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'sheet',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'create',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Grid Properties',
|
||||||
|
name: 'gridProperties',
|
||||||
|
type: 'collection',
|
||||||
|
placeholder: 'Add Property',
|
||||||
|
default: '',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
displayName: 'Column Count',
|
||||||
|
name: 'columnCount',
|
||||||
|
type: 'number',
|
||||||
|
default: 0,
|
||||||
|
description: 'The number of columns in the grid.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Column Group Control After',
|
||||||
|
name: 'columnGroupControlAfter',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'True if the column grouping control toggle is shown after the group.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Frozen Column Count',
|
||||||
|
name: 'frozenColumnCount',
|
||||||
|
type: 'number',
|
||||||
|
default: 0,
|
||||||
|
description: 'The number of columns that are frozen in the grid.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Frozen Row Count',
|
||||||
|
name: 'frozenRowCount',
|
||||||
|
type: 'number',
|
||||||
|
default: 0,
|
||||||
|
description: 'The number of rows that are frozen in the grid.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Hide Gridlines',
|
||||||
|
name: 'hideGridlines',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'True if the grid isn\'t showing gridlines in the UI.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Row Count',
|
||||||
|
name: 'rowCount',
|
||||||
|
type: 'number',
|
||||||
|
default: 0,
|
||||||
|
description: 'The number of rows in the grid.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Row Group Control After',
|
||||||
|
name: 'rowGroupControlAfter',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'True if the row grouping control toggle is shown after the group.',
|
||||||
|
},
|
||||||
|
|
||||||
|
],
|
||||||
|
description: 'The type of the sheet.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Hidden',
|
||||||
|
name: 'hidden',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'True if the sheet is hidden in the UI, false if it\'s visible.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Right To Left',
|
||||||
|
name: 'rightToLeft',
|
||||||
|
type: 'boolean',
|
||||||
|
default: false,
|
||||||
|
description: 'True if the sheet is an RTL sheet instead of an LTR sheet.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Sheet ID',
|
||||||
|
name: 'sheetId',
|
||||||
|
type: 'number',
|
||||||
|
default: 0,
|
||||||
|
description: 'The ID of the sheet. Must be non-negative. This field cannot be changed once set.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Sheet Index',
|
||||||
|
name: 'index',
|
||||||
|
type: 'number',
|
||||||
|
default: 0,
|
||||||
|
description: 'The index of the sheet within the spreadsheet.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Tab Color',
|
||||||
|
name: 'tabColor',
|
||||||
|
type: 'color',
|
||||||
|
default: '0aa55c',
|
||||||
|
description: 'The color of the tab in the UI.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
displayName: 'Title',
|
||||||
|
name: 'title',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
description: 'The Sheet name.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// sheet:remove
|
||||||
|
// ----------------------------------
|
||||||
|
{
|
||||||
|
displayName: 'Sheet ID',
|
||||||
|
name: 'id',
|
||||||
|
type: 'string',
|
||||||
|
default: '',
|
||||||
|
required: true,
|
||||||
|
displayOptions: {
|
||||||
|
show: {
|
||||||
|
resource: [
|
||||||
|
'sheet',
|
||||||
|
],
|
||||||
|
operation: [
|
||||||
|
'remove',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description: 'The ID of the sheet to delete.',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -840,7 +1020,7 @@ export class GoogleSheets implements INodeType {
|
||||||
const sheet = new GoogleSheet(spreadsheetId, this);
|
const sheet = new GoogleSheet(spreadsheetId, this);
|
||||||
|
|
||||||
let range = '';
|
let range = '';
|
||||||
if (operation !== 'delete') {
|
if (!['create', 'delete', 'remove'].includes(operation)) {
|
||||||
range = this.getNodeParameter('range', 0) as string;
|
range = this.getNodeParameter('range', 0) as string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -878,6 +1058,39 @@ export class GoogleSheets implements INodeType {
|
||||||
|
|
||||||
const items = this.getInputData();
|
const items = this.getInputData();
|
||||||
return this.prepareOutputData(items);
|
return this.prepareOutputData(items);
|
||||||
|
|
||||||
|
} else if (operation === 'create') {
|
||||||
|
const returnData: IDataObject[] = [];
|
||||||
|
|
||||||
|
let responseData;
|
||||||
|
for (let i = 0; i < this.getInputData().length; i++) {
|
||||||
|
const spreadsheetId = this.getNodeParameter('sheetId', i) as string;
|
||||||
|
const options = this.getNodeParameter('options', i, {}) as IDataObject;
|
||||||
|
const simple = this.getNodeParameter('simple', 0) as boolean;
|
||||||
|
const properties = { ...options };
|
||||||
|
|
||||||
|
if (options.tabColor) {
|
||||||
|
const { red, green, blue } = hexToRgb(options.tabColor as string)!;
|
||||||
|
properties.tabColor = { red: red / 255, green: green / 255, blue: blue / 255 };
|
||||||
|
}
|
||||||
|
|
||||||
|
const requests = [{
|
||||||
|
addSheet: {
|
||||||
|
properties,
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
|
||||||
|
responseData = await googleApiRequest.call(this, 'POST', `/v4/spreadsheets/${spreadsheetId}:batchUpdate`, { requests });
|
||||||
|
|
||||||
|
if (simple === true) {
|
||||||
|
Object.assign(responseData, responseData.replies[0].addSheet.properties);
|
||||||
|
delete responseData.replies;
|
||||||
|
}
|
||||||
|
returnData.push(responseData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [this.helpers.returnJsonArray(returnData)];
|
||||||
|
|
||||||
} else if (operation === 'delete') {
|
} else if (operation === 'delete') {
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
// delete
|
// delete
|
||||||
|
@ -976,6 +1189,27 @@ export class GoogleSheets implements INodeType {
|
||||||
returnData = [{}];
|
returnData = [{}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return [this.helpers.returnJsonArray(returnData)];
|
||||||
|
|
||||||
|
} else if (operation === 'remove') {
|
||||||
|
const returnData: IDataObject[] = [];
|
||||||
|
|
||||||
|
let responseData;
|
||||||
|
for (let i = 0; i < this.getInputData().length; i++) {
|
||||||
|
const sheetId = this.getNodeParameter('id', i) as string;
|
||||||
|
const spreadsheetId = this.getNodeParameter('sheetId', i) as string;
|
||||||
|
|
||||||
|
const requests = [{
|
||||||
|
deleteSheet: {
|
||||||
|
sheetId,
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
|
||||||
|
responseData = await googleApiRequest.call(this, 'POST', `/v4/spreadsheets/${spreadsheetId}:batchUpdate`, { requests });
|
||||||
|
delete responseData.replies;
|
||||||
|
returnData.push(responseData);
|
||||||
|
}
|
||||||
|
|
||||||
return [this.helpers.returnJsonArray(returnData)];
|
return [this.helpers.returnJsonArray(returnData)];
|
||||||
} else if (operation === 'update') {
|
} else if (operation === 'update') {
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
|
|
Loading…
Reference in a new issue