From 98136885fc06a0eb1949007457fcb95f9d199708 Mon Sep 17 00:00:00 2001 From: Elias Meire Date: Fri, 5 Jan 2024 12:26:59 +0100 Subject: [PATCH] Add "By Name" option for Sheets to Google Sheet node --- .../Google/Sheet/GoogleSheetsTrigger.node.ts | 23 ++++++------ .../nodes/Google/Sheet/v2/actions/router.ts | 20 +++++++---- .../Sheet/v2/actions/sheet/Sheet.resource.ts | 6 ++++ .../Google/Sheet/v2/helpers/GoogleSheet.ts | 35 +++++++++++-------- .../Sheet/v2/helpers/GoogleSheets.types.ts | 14 +++++++- .../Sheet/v2/helpers/GoogleSheets.utils.ts | 5 +++ .../Google/Sheet/v2/methods/loadOptions.ts | 17 +++++---- .../Sheet/v2/methods/resourceMapping.ts | 13 +++---- 8 files changed, 87 insertions(+), 46 deletions(-) diff --git a/packages/nodes-base/nodes/Google/Sheet/GoogleSheetsTrigger.node.ts b/packages/nodes-base/nodes/Google/Sheet/GoogleSheetsTrigger.node.ts index 6745b5f84ead8..5686e5dceb3dc 100644 --- a/packages/nodes-base/nodes/Google/Sheet/GoogleSheetsTrigger.node.ts +++ b/packages/nodes-base/nodes/Google/Sheet/GoogleSheetsTrigger.node.ts @@ -12,7 +12,7 @@ import { apiRequest } from './v2/transport'; import { sheetsSearch, spreadSheetsSearch } from './v2/methods/listSearch'; import { GoogleSheet } from './v2/helpers/GoogleSheet'; import { getSheetHeaderRowAndSkipEmpty } from './v2/methods/loadOptions'; -import type { ValueRenderOption } from './v2/helpers/GoogleSheets.types'; +import type { ResourceLocator, ValueRenderOption } from './v2/helpers/GoogleSheets.types'; import { arrayOfArraysToJson, @@ -399,11 +399,21 @@ export class GoogleSheetsTrigger implements INodeType { extractValue: true, }) as string; - let sheetId = this.getNodeParameter('sheetName', undefined, { + const sheetWithinDocument = this.getNodeParameter('sheetName', undefined, { extractValue: true, }) as string; + const { mode: sheetMode } = this.getNodeParameter('sheetName', 0) as { + mode: ResourceLocator; + }; - sheetId = sheetId === 'gid=0' ? '0' : sheetId; + const googleSheet = new GoogleSheet(documentId, this); + const { sheetId, title: sheetName } = await googleSheet.spreadsheetGetSheet( + this.getNode(), + sheetMode, + sheetWithinDocument, + ); + + const options = this.getNodeParameter('options') as IDataObject; // If the documentId or sheetId changed, reset the workflow static data if ( @@ -417,13 +427,6 @@ export class GoogleSheetsTrigger implements INodeType { workflowStaticData.lastIndexChecked = undefined; } - const googleSheet = new GoogleSheet(documentId, this); - const sheetName: string = await googleSheet.spreadsheetGetSheetNameById( - this.getNode(), - sheetId, - ); - const options = this.getNodeParameter('options') as IDataObject; - const previousRevision = workflowStaticData.lastRevision as number; const previousRevisionLink = workflowStaticData.lastRevisionLink as string; diff --git a/packages/nodes-base/nodes/Google/Sheet/v2/actions/router.ts b/packages/nodes-base/nodes/Google/Sheet/v2/actions/router.ts index b793e5a179149..591567c6f8ca8 100644 --- a/packages/nodes-base/nodes/Google/Sheet/v2/actions/router.ts +++ b/packages/nodes-base/nodes/Google/Sheet/v2/actions/router.ts @@ -29,17 +29,25 @@ export async function router(this: IExecuteFunctions): Promise item.properties.sheetId === +sheetId, - ); + const foundItem = response.sheets.find((item) => { + if (mode === 'name') return item.properties.title === value; + return item.properties.sheetId === getSheetId(value); + }); if (!foundItem?.properties?.title) { - throw new NodeOperationError(node, `Sheet with ID ${sheetId} not found`, { - level: 'warning', - }); + throw new NodeOperationError( + node, + `Sheet with ${mode === 'name' ? 'name' : 'ID'} ${value} not found`, + { level: 'warning' }, + ); } - return foundItem.properties.title; + return foundItem.properties; } /** diff --git a/packages/nodes-base/nodes/Google/Sheet/v2/helpers/GoogleSheets.types.ts b/packages/nodes-base/nodes/Google/Sheet/v2/helpers/GoogleSheets.types.ts index a55fc71ae4dd7..ef643d9953574 100644 --- a/packages/nodes-base/nodes/Google/Sheet/v2/helpers/GoogleSheets.types.ts +++ b/packages/nodes-base/nodes/Google/Sheet/v2/helpers/GoogleSheets.types.ts @@ -62,12 +62,24 @@ export type GoogleSheetsSheet = Entity; export type SpreadSheetProperties = PropertiesOf; export type SheetProperties = PropertiesOf; -export type ResourceLocator = 'id' | 'url' | 'list'; +export type ResourceLocator = 'id' | 'url' | 'list' | 'name'; export const ResourceLocatorUiNames = { id: 'By ID', url: 'By URL', list: 'From List', + name: 'By Name', +}; + +type SpreadSheetResponseSheet = { + properties: { + title: string; + sheetId: number; + }; +}; + +export type SpreadSheetResponse = { + sheets: SpreadSheetResponseSheet[]; }; export type SheetCellDecoded = { diff --git a/packages/nodes-base/nodes/Google/Sheet/v2/helpers/GoogleSheets.utils.ts b/packages/nodes-base/nodes/Google/Sheet/v2/helpers/GoogleSheets.utils.ts index 47cc9df9d5de4..be64a34e83e81 100644 --- a/packages/nodes-base/nodes/Google/Sheet/v2/helpers/GoogleSheets.utils.ts +++ b/packages/nodes-base/nodes/Google/Sheet/v2/helpers/GoogleSheets.utils.ts @@ -45,6 +45,11 @@ export function getSpreadsheetId( return value; } +export function getSheetId(value: string): number { + if (value === 'gid=0') return 0; + return parseInt(value); +} + // Convert number to Sheets / Excel column name export function getColumnName(colNumber: number): string { const baseChar = 'A'.charCodeAt(0); diff --git a/packages/nodes-base/nodes/Google/Sheet/v2/methods/loadOptions.ts b/packages/nodes-base/nodes/Google/Sheet/v2/methods/loadOptions.ts index a09f55b736576..90aa11cf90ab9 100644 --- a/packages/nodes-base/nodes/Google/Sheet/v2/methods/loadOptions.ts +++ b/packages/nodes-base/nodes/Google/Sheet/v2/methods/loadOptions.ts @@ -47,15 +47,18 @@ export async function getSheetHeaderRow( const spreadsheetId = getSpreadsheetId(this.getNode(), mode as ResourceLocator, value as string); const sheet = new GoogleSheet(spreadsheetId, this); - let sheetWithinDocument = this.getNodeParameter('sheetName', undefined, { + const sheetWithinDocument = this.getNodeParameter('sheetName', undefined, { extractValue: true, }) as string; - - if (sheetWithinDocument === 'gid=0') { - sheetWithinDocument = '0'; - } - - const sheetName = await sheet.spreadsheetGetSheetNameById(this.getNode(), sheetWithinDocument); + const { mode: sheetMode } = this.getNodeParameter('sheetName', 0) as { + mode: ResourceLocator; + }; + + const { title: sheetName } = await sheet.spreadsheetGetSheet( + this.getNode(), + sheetMode, + sheetWithinDocument, + ); const sheetData = await sheet.getData(`${sheetName}!1:1`, 'FORMATTED_VALUE'); if (sheetData === undefined) { diff --git a/packages/nodes-base/nodes/Google/Sheet/v2/methods/resourceMapping.ts b/packages/nodes-base/nodes/Google/Sheet/v2/methods/resourceMapping.ts index f29a2a7844949..40ae402a646a4 100644 --- a/packages/nodes-base/nodes/Google/Sheet/v2/methods/resourceMapping.ts +++ b/packages/nodes-base/nodes/Google/Sheet/v2/methods/resourceMapping.ts @@ -20,15 +20,16 @@ export async function getMappingColumns( const spreadsheetId = getSpreadsheetId(this.getNode(), mode as ResourceLocator, value as string); const sheet = new GoogleSheet(spreadsheetId, this); - let sheetWithinDocument = this.getNodeParameter('sheetName', undefined, { + const sheetWithinDocument = this.getNodeParameter('sheetName', undefined, { extractValue: true, }) as string; + const { mode: sheetMode } = this.getNodeParameter('sheetName', 0) as { mode: ResourceLocator }; - if (sheetWithinDocument === 'gid=0') { - sheetWithinDocument = '0'; - } - - const sheetName = await sheet.spreadsheetGetSheetNameById(this.getNode(), sheetWithinDocument); + const { title: sheetName } = await sheet.spreadsheetGetSheet( + this.getNode(), + sheetMode, + sheetWithinDocument, + ); const sheetData = await sheet.getData(`${sheetName}!1:1`, 'FORMATTED_VALUE'); const columns = sheet.testFilter(sheetData || [], 0, 0).filter((col) => col !== '');