Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One last tiny thing, could you remove this file? It's not a big deal but we just like to keep our repo so only necesary files are included.

Binary file not shown.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.DS_Store
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
- **Tab Name**: The tab name within the spreadsheet that you wish to add rows to. In a brand new spreadsheet this is usually "Sheet1"

You can now use the `Google Sheets: Append Row` action in your behaviours.
You can also use the `Google Sheets: Add to existing Row` action to add values to an existing row after already entered value. The way it works, is that the first column should be a common value (like an ID key). If this value already exists in your Google Sheets, all values you enter there will be added after the last non-empty column. If the ID does not exists, it will create it.

## Local development in a browser

Expand Down
8 changes: 7 additions & 1 deletion cogs-plugin-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,14 @@
"value": {
"type": "string"
}
},
{
"name": "Add to existing Row",
"value": {
"type": "string"
}
}
],
"toCogs:": []
}
}
}
87 changes: 87 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ const GOOGLE_API_DISCOVERY_DOCS = [
"https://sheets.googleapis.com/$discovery/rest?version=v4",
];

function columnIndexToLetter(index: number): string {
let column = '';
while (index >= 0) {
column = String.fromCharCode((index % 26) + 65) + column;
index = Math.floor(index / 26) - 1;
}
return column;
}

export default function App() {
const connection = useCogsConnection<{
config: {
Expand All @@ -23,6 +32,7 @@ export default function App() {
};
inputEvents: {
"Append Row": string;
"Add to existing Row": string;
};
}>();
const isConnected = useIsConnected(connection);
Expand Down Expand Up @@ -79,7 +89,84 @@ export default function App() {
[spreadsheetId, tabName, googleApi]
);

const appendToRow = useCallback(
async (rowString: string) => {
const row = parseRow(rowString);

if (row.length === 0) {
console.warn("Empty row provided");
return;
}

const key = row[0];
const valuesToAppend = row.slice(1); // Remove the key, keep only values to append
console.log("Append to row with key:", key, "values:", valuesToAppend);

if (!googleApi) {
console.warn("Google API not loaded yet");
return;
}

try {
// First, read only column A to find the key (more efficient)
const keyColumnResponse = await googleApi.client.sheets.spreadsheets.values.get({
spreadsheetId: spreadsheetId,
range: `${tabName}!A:A`, // Read only first column
});

const keyColumn = keyColumnResponse.result.values || [];

// Find the row index where the key matches (0-indexed in array)
const rowIndex = keyColumn.findIndex((rowData) => rowData[0] === key);

if (rowIndex !== -1) {
// Key found - now fetch only that specific row to determine where to append
const rowNumber = rowIndex + 1; // Convert to 1-indexed for Sheets API

const rowResponse = await googleApi.client.sheets.spreadsheets.values.get({
spreadsheetId: spreadsheetId,
range: `${tabName}!${rowNumber}:${rowNumber}`, // Read only the specific row
});

const existingRow = rowResponse.result.values?.[0] || [];
const lastColumnIndex = existingRow.length; // Next empty column
const startColumn = columnIndexToLetter(lastColumnIndex);

const appendResponse = await googleApi.client.sheets.spreadsheets.values.append({
spreadsheetId: spreadsheetId,
range: `${tabName}!${startColumn}${rowNumber}`,
resource: {
values: [valuesToAppend],
},
valueInputOption: "USER_ENTERED",
insertDataOption: "OVERWRITE",
});
console.log(
`${appendResponse.result.updates?.updatedCells} cells appended to row ${rowNumber}.`
);
} else {
// Key not found - create new row with key + values
const appendResponse = await googleApi.client.sheets.spreadsheets.values.append({
spreadsheetId: spreadsheetId,
range: `${tabName}!A1`,
resource: {
values: [row], // Include key + values
},
valueInputOption: "USER_ENTERED",
});
console.log(
`Key not found. ${appendResponse.result.updates?.updatedCells} cells appended as new row.`
);
}
} catch (error) {
console.error("Error appending to row:", error);
}
},
[spreadsheetId, tabName, googleApi]
);

useCogsEvent(connection, "Append Row", appendRow);
useCogsEvent(connection, "Add to existing Row", appendToRow);

return (
<div className="App">
Expand Down