Skip to content

Commit 785cc4a

Browse files
PrajwalLokhande2003michelle0927coderabbitai[bot]
authored
Added 6 new actions to support advanced cell formatting, data validation, and protection (#18995)
* Added 6 new actions to support advanced cell formatting, data validation, and protection * resolve PR comment * Update components/google_sheets/actions/add-conditional-format-rule/add-conditional-format-rule.mjs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update components/google_sheets/actions/set-data-validation/set-data-validation.mjs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * add-conditional-format-rule updates * add-protected-range updates * delete-conditional-format-rule update * merge-cells update * set-data-validation update * update-conditional-format-rule updates --------- Co-authored-by: michelle0927 <michelle0927@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Michelle Bergeron <michelle.bergeron@gmail.com>
1 parent 7c3a310 commit 785cc4a

File tree

7 files changed

+849
-1
lines changed

7 files changed

+849
-1
lines changed
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
import googleSheets from "../../google_sheets.app.mjs";
2+
import { ConfigurationError } from "@pipedream/platform";
3+
4+
export default {
5+
key: "google_sheets-add-conditional-format-rule",
6+
name: "Add Conditional Format Rule",
7+
description: "Create conditional formatting with color scales or custom formulas. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#AddConditionalFormatRuleRequest)",
8+
version: "0.0.1",
9+
type: "action",
10+
annotations: {
11+
destructiveHint: false,
12+
openWorldHint: true,
13+
readOnlyHint: false,
14+
},
15+
props: {
16+
googleSheets,
17+
drive: {
18+
propDefinition: [
19+
googleSheets,
20+
"watchedDrive",
21+
],
22+
},
23+
sheetId: {
24+
propDefinition: [
25+
googleSheets,
26+
"sheetID",
27+
(c) => ({
28+
driveId: googleSheets.methods.getDriveId(c.drive),
29+
}),
30+
],
31+
},
32+
worksheetId: {
33+
propDefinition: [
34+
googleSheets,
35+
"worksheetIDs",
36+
(c) => ({
37+
sheetId: c.sheetId,
38+
}),
39+
],
40+
},
41+
range: {
42+
propDefinition: [
43+
googleSheets,
44+
"range",
45+
],
46+
description: "The range of cells to format (e.g., `A1:A10`)",
47+
},
48+
conditionType: {
49+
type: "string",
50+
label: "Validation Type",
51+
description: "The type of data condition",
52+
options: [
53+
"ONE_OF_LIST",
54+
"NUMBER_GREATER",
55+
"NUMBER_LESS",
56+
"DATE_BEFORE",
57+
"DATE_AFTER",
58+
"TEXT_CONTAINS",
59+
"TEXT_IS_EMAIL",
60+
"TEXT_IS_URL",
61+
"BOOLEAN",
62+
],
63+
},
64+
conditionValues: {
65+
type: "string[]",
66+
label: "Condition Values",
67+
description: "Values for condition (e.g., color scales or custom formulas)",
68+
},
69+
formattingType: {
70+
type: "string",
71+
label: "Formatting Type",
72+
description: "Choose between boolean condition or gradient color scale",
73+
options: [
74+
"BOOLEAN_RULE",
75+
"GRADIENT_RULE",
76+
],
77+
default: "BOOLEAN_RULE",
78+
},
79+
rgbColor: {
80+
type: "object",
81+
label: "RGB Color",
82+
description: "The RGB color value (e.g., {\"red\": 1.0, \"green\": 0.5, \"blue\": 0.2})",
83+
optional: true,
84+
},
85+
textFormat: {
86+
type: "object",
87+
label: "Text Format",
88+
description: "The text format options",
89+
optional: true,
90+
},
91+
bold: {
92+
type: "boolean",
93+
label: "Bold",
94+
description: "Whether the text is bold",
95+
optional: true,
96+
},
97+
italic: {
98+
type: "boolean",
99+
label: "Italic",
100+
description: "Whether the text is italic",
101+
optional: true,
102+
},
103+
strikethrough: {
104+
type: "boolean",
105+
label: "Strikethrough",
106+
description: "Whether the text is strikethrough",
107+
optional: true,
108+
},
109+
interpolationPointType: {
110+
type: "string",
111+
label: "Interpolation Point Type",
112+
description: "The interpolation point type",
113+
options: [
114+
"MIN",
115+
"MAX",
116+
"NUMBER",
117+
"PERCENT",
118+
"PERCENTILE",
119+
],
120+
optional: true,
121+
},
122+
index: {
123+
type: "integer",
124+
label: "Index",
125+
description: "The zero-based index of the rule",
126+
},
127+
},
128+
async run({ $ }) {
129+
const {
130+
startCol,
131+
endCol,
132+
startRow,
133+
endRow,
134+
} = this.googleSheets._parseRangeString(`${this.worksheetId}!${this.range}`);
135+
136+
const rule = {
137+
ranges: [
138+
{
139+
sheetId: this.worksheetId,
140+
startRowIndex: startRow,
141+
endRowIndex: endRow,
142+
startColumnIndex: startCol.charCodeAt(0) - 65,
143+
endColumnIndex: endCol.charCodeAt(0) - 64,
144+
},
145+
],
146+
};
147+
148+
const parseRgbColor = (rgbColor = {}) => {
149+
if (typeof rgbColor === "string") {
150+
try {
151+
rgbColor = JSON.parse(rgbColor);
152+
} catch {
153+
throw new ConfigurationError("Could not parse RGB Color. Please provide a valid JSON object.");
154+
}
155+
}
156+
return rgbColor;
157+
};
158+
159+
this.formattingType === "GRADIENT_RULE" ?
160+
rule.gradientRule = {
161+
minpoint: {
162+
colorStyle: {
163+
rgbColor: parseRgbColor(this.rgbColor),
164+
},
165+
type: this.interpolationPointType,
166+
value: "MIN",
167+
},
168+
midpoint: {
169+
colorStyle: {
170+
rgbColor: parseRgbColor(this.rgbColor),
171+
},
172+
type: this.interpolationPointType,
173+
value: "MID",
174+
},
175+
maxpoint: {
176+
colorStyle: {
177+
rgbColor: parseRgbColor(this.rgbColor),
178+
},
179+
type: this.interpolationPointType,
180+
value: "MAX",
181+
},
182+
} :
183+
rule.booleanRule = {
184+
condition: {
185+
type: this.conditionType,
186+
values: this.conditionValues?.map((v) => ({
187+
userEnteredValue: v,
188+
})) || [],
189+
},
190+
format: {
191+
backgroundColorStyle: {
192+
rgbColor: parseRgbColor(this.rgbColor),
193+
},
194+
textFormat: {
195+
...this.textFormat,
196+
foregroundColorStyle: {
197+
rgbColor: parseRgbColor(this.rgbColor),
198+
},
199+
bold: this.bold,
200+
italic: this.italic,
201+
strikethrough: this.strikethrough,
202+
},
203+
},
204+
};
205+
206+
const request = {
207+
spreadsheetId: this.sheetId,
208+
requestBody: {
209+
requests: [
210+
{
211+
addConditionalFormatRule: {
212+
rule,
213+
index: this.index,
214+
},
215+
},
216+
],
217+
},
218+
};
219+
const response = await this.googleSheets.batchUpdate(request);
220+
$.export("$summary", "Successfully added conditional format rule.");
221+
return response;
222+
},
223+
};
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import googleSheets from "../../google_sheets.app.mjs";
2+
3+
export default {
4+
key: "google_sheets-add-protected-range",
5+
name: "Add Protected Range",
6+
description: "Add edit protection to cell range with permissions. [See the documentation](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#AddProtectedRangeRequest)",
7+
version: "0.0.1",
8+
type: "action",
9+
annotations: {
10+
destructiveHint: false,
11+
openWorldHint: true,
12+
readOnlyHint: false,
13+
},
14+
props: {
15+
googleSheets,
16+
drive: {
17+
propDefinition: [
18+
googleSheets,
19+
"watchedDrive",
20+
],
21+
},
22+
sheetId: {
23+
propDefinition: [
24+
googleSheets,
25+
"sheetID",
26+
(c) => ({
27+
driveId: googleSheets.methods.getDriveId(c.drive),
28+
}),
29+
],
30+
},
31+
worksheetId: {
32+
propDefinition: [
33+
googleSheets,
34+
"worksheetIDs",
35+
(c) => ({
36+
sheetId: c.sheetId,
37+
}),
38+
],
39+
},
40+
protectedRangeId: {
41+
type: "integer",
42+
label: "Protected Range ID",
43+
description: "The ID of the protected range (required for update and delete operations). This is a unique identifier assigned by Google Sheets",
44+
optional: true,
45+
},
46+
range: {
47+
propDefinition: [
48+
googleSheets,
49+
"range",
50+
],
51+
description: "The range of cells to protect (e.g., `A1:A10`). Required for add and update operations",
52+
},
53+
description: {
54+
type: "string",
55+
label: "Description",
56+
description: "A description of the protected range",
57+
optional: true,
58+
},
59+
requestingUserCanEdit: {
60+
type: "boolean",
61+
label: "Requesting User Can Edit",
62+
description: "If true, the user making this request can edit the protected range",
63+
optional: true,
64+
default: false,
65+
},
66+
protectors: {
67+
type: "string[]",
68+
label: "Protectors",
69+
description: "Email addresses of users/groups who can edit the protected range (e.g., user@example.com)",
70+
optional: true,
71+
},
72+
},
73+
async run({ $ }) {
74+
const {
75+
startCol,
76+
endCol,
77+
startRow,
78+
endRow,
79+
} = this.googleSheets._parseRangeString(`${this.worksheetId}!${this.range}`);
80+
81+
const request = {
82+
spreadsheetId: this.sheetId,
83+
requestBody: {
84+
requests: [
85+
{
86+
addProtectedRange: {
87+
protectedRange: {
88+
protectedRangeId: this.protectedRangeId,
89+
range: {
90+
sheetId: this.worksheetId,
91+
startRowIndex: startRow,
92+
endRowIndex: endRow,
93+
startColumnIndex: startCol.charCodeAt(0) - 65,
94+
endColumnIndex: endCol.charCodeAt(0) - 64,
95+
},
96+
description: this.description,
97+
requestingUserCanEdit: this.requestingUserCanEdit,
98+
editors: {
99+
users: this.protectors || [],
100+
},
101+
},
102+
},
103+
},
104+
],
105+
},
106+
};
107+
const response = await this.googleSheets.batchUpdate(request);
108+
$.export("$summary", "Successfully added protected range.");
109+
return response;
110+
},
111+
};

0 commit comments

Comments
 (0)