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
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.DS_Store
.DS_Store

# Claude
CLAUDE.md
.claude/
6 changes: 6 additions & 0 deletions cogs-plugin-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
"value": {
"type": "string"
}
},
{
"name": "Add to existing Row with column",
"value": {
"type": "string"
}
}
],
"toCogs:": []
Expand Down
84 changes: 84 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ function columnIndexToLetter(index: number): string {
return column;
}

function letterToColumnIndex(letters: string): number {
let index = 0;
for (let i = 0; i < letters.length; i++) {
index = index * 26 + (letters.toUpperCase().charCodeAt(i) - 64);
}
return index - 1;
}

export default function App() {
const connection = useCogsConnection<{
config: {
Expand All @@ -33,6 +41,7 @@ export default function App() {
inputEvents: {
"Append Row": string;
"Add to existing Row": string;
"Add to existing Row with column": string;
};
}>();
const isConnected = useIsConnected(connection);
Expand Down Expand Up @@ -165,8 +174,83 @@ export default function App() {
[spreadsheetId, tabName, googleApi]
);

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

if (row.length < 2) {
console.warn("Input must contain at least ID and column (e.g., 'ID,C,value1,value2')");
return;
}

const key = row[0];
const startColumnLetter = row[1];
const valuesToWrite = row.slice(2);
console.log("Append to row with key:", key, "starting at column:", startColumnLetter, "values:", valuesToWrite);

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

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

const keyColumn = keyColumnResponse.result.values || [];
const rowIndex = keyColumn.findIndex((rowData) => rowData[0] === key);
const startColumnIndex = letterToColumnIndex(startColumnLetter);
const endColumnLetter = columnIndexToLetter(startColumnIndex + valuesToWrite.length - 1);

if (rowIndex !== -1) {
// Key found - write values at the specified column
const rowNumber = rowIndex + 1;

const updateResponse = await googleApi.client.sheets.spreadsheets.values.update({
spreadsheetId: spreadsheetId,
range: `${tabName}!${startColumnLetter.toUpperCase()}${rowNumber}:${endColumnLetter}${rowNumber}`,
resource: {
values: [valuesToWrite],
},
valueInputOption: "USER_ENTERED",
});
console.log(
`${updateResponse.result.updatedCells} cells updated in row ${rowNumber}.`
);
} else {
// Key not found - create new row with key in A and values at specified column
// Build a row with key in first position and values at the right offset
const newRow: string[] = [key];
for (let i = 1; i < startColumnIndex; i++) {
newRow.push('');
}
newRow.push(...valuesToWrite);

const appendResponse = await googleApi.client.sheets.spreadsheets.values.append({
spreadsheetId: spreadsheetId,
range: `${tabName}!A1`,
resource: {
values: [newRow],
},
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 with column:", error);
}
},
[spreadsheetId, tabName, googleApi]
);

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

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