Skip to content

Commit

Permalink
feat(Google Sheets Node): Add "By Name" option to selector for Sheets (
Browse files Browse the repository at this point in the history
…#8241)

Co-authored-by: Michael Kret <michael.k@radency.com>
  • Loading branch information
elsmr and michael-radency authored Jan 10, 2024
1 parent e796e7f commit dce28f9
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 46 deletions.
23 changes: 13 additions & 10 deletions packages/nodes-base/nodes/Google/Sheet/GoogleSheetsTrigger.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 (
Expand All @@ -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;

Expand Down
20 changes: 13 additions & 7 deletions packages/nodes-base/nodes/Google/Sheet/v2/actions/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,25 @@ export async function router(this: IExecuteFunctions): Promise<INodeExecutionDat
const googleSheet = new GoogleSheet(spreadsheetId, this);

let sheetId = '';
let sheetName = '';

if (operation !== 'create') {
sheetId = this.getNodeParameter('sheetName', 0, undefined, {
const sheetWithinDocument = this.getNodeParameter('sheetName', 0, undefined, {
extractValue: true,
}) as string;
}
const { mode: sheetMode } = this.getNodeParameter('sheetName', 0) as {
mode: ResourceLocator;
};

if (sheetId === 'gid=0') {
sheetId = '0';
const result = await googleSheet.spreadsheetGetSheet(
this.getNode(),
sheetMode,
sheetWithinDocument,
);
sheetId = result.sheetId.toString();
sheetName = result.title;
}

let sheetName = '';
switch (operation) {
case 'create':
sheetName = spreadsheetId;
Expand All @@ -50,8 +58,6 @@ export async function router(this: IExecuteFunctions): Promise<INodeExecutionDat
case 'remove':
sheetName = `${spreadsheetId}||${sheetId}`;
break;
default:
sheetName = await googleSheet.spreadsheetGetSheetNameById(this.getNode(), sheetId);
}

results = await sheet[googleSheets.operation].execute.call(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ export const descriptions: INodeProperties[] = [
},
],
},
{
displayName: 'By Name',
name: 'name',
type: 'string',
placeholder: 'Sheet1',
},
],
displayOptions: {
show: {
Expand Down
35 changes: 20 additions & 15 deletions packages/nodes-base/nodes/Google/Sheet/v2/helpers/GoogleSheet.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
import get from 'lodash/get';
import type {
IDataObject,
IExecuteFunctions,
ILoadOptionsFunctions,
IDataObject,
IPollFunctions,
INode,
IPollFunctions,
} from 'n8n-workflow';
import { ApplicationError, NodeOperationError } from 'n8n-workflow';
import { utils as xlsxUtils } from 'xlsx';
import get from 'lodash/get';
import { apiRequest } from '../transport';
import type {
ILookupValues,
ISheetUpdateData,
ResourceLocator,
SheetCellDecoded,
SheetRangeData,
SheetRangeDecoded,
SpreadSheetResponse,
ValueInputOption,
ValueRenderOption,
} from './GoogleSheets.types';
import { removeEmptyColumns } from './GoogleSheets.utils';
import { getSheetId, removeEmptyColumns } from './GoogleSheets.utils';

export class GoogleSheet {
id: string;
Expand Down Expand Up @@ -116,32 +118,35 @@ export class GoogleSheet {
}

/**
* Returns the name of a sheet from a sheet id
* Returns the sheet within a spreadsheet based on name or ID
*/
async spreadsheetGetSheetNameById(node: INode, sheetId: string) {
async spreadsheetGetSheet(node: INode, mode: ResourceLocator, value: string) {
const query = {
fields: 'sheets.properties',
};

const response = await apiRequest.call(
const response = (await apiRequest.call(
this.executeFunctions,
'GET',
`/v4/spreadsheets/${this.id}`,
{},
query,
);
)) as SpreadSheetResponse;

const foundItem = response.sheets.find(
(item: { properties: { sheetId: number } }) => 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;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,24 @@ export type GoogleSheetsSheet = Entity<GoogleSheetsMap, 'sheet'>;
export type SpreadSheetProperties = PropertiesOf<GoogleSheetsSpreadSheet>;
export type SheetProperties = PropertiesOf<GoogleSheetsSheet>;

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 = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
17 changes: 10 additions & 7 deletions packages/nodes-base/nodes/Google/Sheet/v2/methods/loadOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 !== '');
Expand Down

0 comments on commit dce28f9

Please sign in to comment.