Skip to content

Commit 46e7530

Browse files
Refactor hasHeaders prop to common file, fix behavior with custom expressions for Google Sheets (#14452)
* Update update-row * Version bumps. * bump
1 parent f004dcb commit 46e7530

File tree

13 files changed

+183
-71
lines changed

13 files changed

+183
-71
lines changed

components/google_sheets/actions/add-multiple-rows/add-multiple-rows.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default {
1111
key: "google_sheets-add-multiple-rows",
1212
name: "Add Multiple Rows",
1313
description: "Add multiple rows of data to a Google Sheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append)",
14-
version: "0.2.8",
14+
version: "0.2.9",
1515
type: "action",
1616
props: {
1717
googleSheets,

components/google_sheets/actions/add-single-row/add-single-row.mjs

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import common from "../common/worksheet.mjs";
22
import { ConfigurationError } from "@pipedream/platform";
33
import { parseArray } from "../../common/utils.mjs";
4+
import { isDynamicExpression } from "../common/worksheet.mjs";
45

56
const { googleSheets } = common.props;
67

@@ -9,7 +10,7 @@ export default {
910
key: "google_sheets-add-single-row",
1011
name: "Add Single Row",
1112
description: "Add a single row of data to Google Sheets. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append)",
12-
version: "2.1.10",
13+
version: "2.1.11",
1314
type: "action",
1415
props: {
1516
googleSheets,
@@ -27,6 +28,7 @@ export default {
2728
driveId: googleSheets.methods.getDriveId(c.drive),
2829
}),
2930
],
31+
reloadProps: true,
3032
},
3133
worksheetId: {
3234
propDefinition: [
@@ -36,42 +38,81 @@ export default {
3638
sheetId: c.sheetId?.value || c.sheetId,
3739
}),
3840
],
39-
type: "string",
40-
label: "Worksheet ID",
41-
},
42-
hasHeaders: {
43-
type: "boolean",
44-
label: "Does the first row of the sheet have headers?",
45-
description: "If the first row of your document has headers, we'll retrieve them to make it easy to enter the value for each column. Please note, that if you are referencing a worksheet using a custom expression referencing data from another step, e.g. `{{steps.my_step.$return_value}}` this prop cannot be used. If you want to retrieve the header row, select both **Spreadsheet** and **Worksheet ID** from the dropdowns above.",
41+
description: "Select a worksheet or enter a custom expression. When referencing a spreadsheet dynamically, you must provide a custom expression for the worksheet.",
42+
async options({ sheetId }) {
43+
// If sheetId is a dynamic reference, don't load options
44+
if (isDynamicExpression(sheetId)) {
45+
return [];
46+
}
47+
48+
// Otherwise, call the original options function with the correct context
49+
const origOptions = googleSheets.propDefinitions.worksheetIDs.options;
50+
return origOptions.call(this, {
51+
sheetId,
52+
});
53+
},
4654
reloadProps: true,
4755
},
56+
hasHeaders: common.props.hasHeaders,
4857
},
4958
async additionalProps() {
5059
const {
5160
sheetId,
5261
worksheetId,
62+
hasHeaders,
5363
} = this;
5464

65+
// If using dynamic expressions for either sheetId or worksheetId, return only array input
66+
if (isDynamicExpression(sheetId) || isDynamicExpression(worksheetId)) {
67+
return {
68+
myColumnData: {
69+
type: "string[]",
70+
label: "Values",
71+
description: "Provide a value for each cell of the row. Google Sheets accepts strings, numbers and boolean values for each cell. To set a cell to an empty value, pass an empty string.",
72+
},
73+
};
74+
}
75+
5576
const props = {};
56-
if (this.hasHeaders) {
57-
const worksheet = await this.getWorksheetById(sheetId, worksheetId);
77+
if (hasHeaders) {
78+
try {
79+
const worksheet = await this.getWorksheetById(sheetId, worksheetId);
80+
const { values } = await this.googleSheets.getSpreadsheetValues(sheetId, `${worksheet?.properties?.title}!1:1`);
5881

59-
const { values } = await this.googleSheets.getSpreadsheetValues(sheetId, `${worksheet?.properties?.title}!1:1`);
60-
if (!values[0]?.length) {
61-
throw new ConfigurationError("Could not find a header row. Please either add headers and click \"Refresh fields\" or adjust the action configuration to continue.");
62-
}
63-
for (let i = 0; i < values[0]?.length; i++) {
64-
props[`col_${i.toString().padStart(4, "0")}`] = {
82+
if (!values?.[0]?.length) {
83+
throw new ConfigurationError("Could not find a header row. Please either add headers and click \"Refresh fields\" or set 'Does the first row of the sheet have headers?' to false.");
84+
}
85+
86+
for (let i = 0; i < values[0]?.length; i++) {
87+
props[`col_${i.toString().padStart(4, "0")}`] = {
88+
type: "string",
89+
label: values[0][i],
90+
optional: true,
91+
};
92+
}
93+
props.allColumns = {
6594
type: "string",
66-
label: values[0][i],
67-
optional: true,
95+
hidden: true,
96+
default: JSON.stringify(values),
97+
};
98+
} catch (err) {
99+
console.error("Error fetching headers:", err);
100+
// Fallback to basic column input if headers can't be fetched
101+
return {
102+
headerError: {
103+
type: "string",
104+
label: "Header Fetch Error",
105+
description: `Unable to fetch headers: ${err.message}. Using simple column input instead.`,
106+
optional: true,
107+
hidden: true,
108+
},
109+
myColumnData: {
110+
type: "string[]",
111+
label: "Values",
112+
description: "Provide a value for each cell of the row. Google Sheets accepts strings, numbers and boolean values for each cell. To set a cell to an empty value, pass an empty string.",
113+
},
68114
};
69115
}
70-
props.allColumns = {
71-
type: "string",
72-
hidden: true,
73-
default: JSON.stringify(values),
74-
};
75116
} else {
76117
props.myColumnData = {
77118
type: "string[]",
@@ -94,7 +135,11 @@ export default {
94135
const worksheet = await this.getWorksheetById(sheetId, worksheetId);
95136

96137
let cells;
97-
if (this.hasHeaders) {
138+
if (this.hasHeaders
139+
&& !isDynamicExpression(sheetId)
140+
&& !isDynamicExpression(worksheetId)
141+
&& this.allColumns
142+
) {
98143
const rows = JSON.parse(this.allColumns);
99144
const [
100145
headers,
@@ -103,10 +148,11 @@ export default {
103148
.map((_, i) => `col_${i.toString().padStart(4, "0")}`)
104149
.map((column) => this[column] ?? "");
105150
} else {
151+
// For dynamic references or no headers, use the array input
106152
cells = this.googleSheets.sanitizedArray(this.myColumnData);
107153
}
108154

109-
// validate input
155+
// Validate input
110156
if (!cells || !cells.length) {
111157
throw new ConfigurationError("Please enter an array of elements in `Cells / Column Values`.");
112158
}
@@ -118,15 +164,15 @@ export default {
118164
}
119165

120166
const {
121-
arr,
167+
arr: sanitizedCells,
122168
convertedIndexes,
123169
} = this.googleSheets.arrayValuesToString(cells);
124170

125171
const data = await this.googleSheets.addRowsToSheet({
126172
spreadsheetId: sheetId,
127173
range: worksheet?.properties?.title,
128174
rows: [
129-
arr,
175+
sanitizedCells,
130176
],
131177
});
132178

components/google_sheets/actions/clear-cell/clear-cell.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default {
77
key: "google_sheets-clear-cell",
88
name: "Clear Cell",
99
description: "Delete the content of a specific cell in a spreadsheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/clear)",
10-
version: "0.1.9",
10+
version: "0.1.10",
1111
type: "action",
1212
props: {
1313
googleSheets,

components/google_sheets/actions/clear-rows/clear-rows.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default {
77
key: "google_sheets-clear-rows",
88
name: "Clear Rows",
99
description: "Delete the content of a row or rows in a spreadsheet. Deleted rows will appear as blank rows. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/clear)",
10-
version: "0.1.7",
10+
version: "0.1.8",
1111
type: "action",
1212
props: {
1313
googleSheets,

components/google_sheets/actions/common/worksheet.mjs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
import googleSheets from "../../google_sheets.app.mjs";
22

3+
// Helper function to check if a value is a dynamic expression
4+
export const isDynamicExpression = (value) => {
5+
if (!value || typeof value !== "string") return false;
6+
return value.trim().startsWith("{{") && value.trim().endsWith("}}");
7+
};
8+
39
export default {
410
props: {
511
googleSheets,
12+
hasHeaders: {
13+
type: "boolean",
14+
label: "Does the first row of the sheet have headers?",
15+
description: "If the first row of your document has headers, we'll retrieve them to make it easy to enter the value for each column. Note: When using a dynamic reference for the worksheet ID (e.g. `{{steps.foo.$return_value}}`), this setting is ignored.",
16+
reloadProps: true,
17+
},
618
},
719
methods: {
820
async getWorksheetById(sheetId, worksheetId) {

components/google_sheets/actions/find-row/find-row.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default {
77
key: "google_sheets-find-row",
88
name: "Find Row",
99
description: "Find one or more rows by a column and value. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get)",
10-
version: "0.2.7",
10+
version: "0.2.8",
1111
type: "action",
1212
props: {
1313
googleSheets,

components/google_sheets/actions/get-cell/get-cell.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default {
77
key: "google_sheets-get-cell",
88
name: "Get Cell",
99
description: "Fetch the contents of a specific cell in a spreadsheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get)",
10-
version: "0.1.7",
10+
version: "0.1.8",
1111
type: "action",
1212
props: {
1313
googleSheets,

components/google_sheets/actions/get-values-in-range/get-values-in-range.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default {
77
key: "google_sheets-get-values-in-range",
88
name: "Get Values in Range",
99
description: "Get all values or values from a range of cells using A1 notation. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get)",
10-
version: "0.1.7",
10+
version: "0.1.8",
1111
type: "action",
1212
props: {
1313
googleSheets,

components/google_sheets/actions/update-cell/update-cell.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default {
77
key: "google_sheets-update-cell",
88
name: "Update Cell",
99
description: "Update a cell in a spreadsheet. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/update)",
10-
version: "0.1.7",
10+
version: "0.1.8",
1111
type: "action",
1212
props: {
1313
googleSheets,

components/google_sheets/actions/update-multiple-rows/update-multiple-rows.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export default {
99
key: "google_sheets-update-multiple-rows",
1010
name: "Update Multiple Rows",
1111
description: "Update multiple rows in a spreadsheet defined by a range. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/update)",
12-
version: "0.1.7",
12+
version: "0.1.8",
1313
type: "action",
1414
props: {
1515
googleSheets,

0 commit comments

Comments
 (0)