diff --git a/sites/scouting/src/matrix.js b/sites/scouting/src/matrix.js index 0236cec..90c0fb7 100644 --- a/sites/scouting/src/matrix.js +++ b/sites/scouting/src/matrix.js @@ -251,6 +251,24 @@ const a1 = (sheetTitle, col, row) => `'${sheetTitle.replace(/'/g, "''")}'!${colL /* ---- Row/column value builders ---- */ +// The template's own "Disposition Matrix" section (Template!B32, header + +// B33:H37) color-codes each of the 5 canonical ITC dispositions — same +// spelling/order as CANONICAL_DISPOSITIONS in main.js. Read directly from +// the template's actual cell fill colors (XLSX export, since the Sheets +// API's formatting isn't visible via CSV) rather than guessed. +const DISPOSITION_COLORS = { + "Purge the Foe": "E06666", + "Take and Hold": "93C47D", + "Priority Assets": "FFD966", + "Disruption": "4A86E8", + "Reconnaissance": "76A5AF", +}; + +function hexToRgbColor(hex) { + const n = parseInt(hex, 16); + return { red: ((n >> 16) & 255) / 255, green: ((n >> 8) & 255) / 255, blue: (n & 255) / 255 }; +} + // fullName() takes the nested BCP user object ({firstName, lastName}), not // the roster/teamplayer entry itself — same convention main.js's own // playerRowHTML() uses, matched here. @@ -305,7 +323,7 @@ export async function generateMatrix({ event, ourTeam, opposingTeams, careerReco const size = sizes.find(s => s >= Math.max(oppTeam.members.length, ourTeam.members.length)) || sizes[sizes.length - 1]; const template = templates.get(size); - let title; + let title, newSheetId; try { const dup = await batchUpdate(token, copy.id, [{ duplicateSheet: { @@ -313,12 +331,35 @@ export async function generateMatrix({ event, ourTeam, opposingTeams, careerReco newSheetName: oppTeam.name.slice(0, 100), }, }]); - title = dup.replies[0].duplicateSheet.properties.title; + ({ title, sheetId: newSheetId } = dup.replies[0].duplicateSheet.properties); } catch (err) { skipped.push({ team: oppTeam.name, reason: `Couldn't duplicate tab: ${err.message}` }); continue; } + // Color each opponent's whole column (list/faction/name rows) by their + // disposition, matching the template's own Disposition Matrix colors — + // a separate batchUpdate since it needs newSheetId, only known now. + const colorRequests = oppTeam.members.map((member, i) => { + const col = template.opponentCols[i]; + const color = col != null ? DISPOSITION_COLORS[member.subFaction?.name] : null; + if (!color) return null; + return { + repeatCell: { + range: { sheetId: newSheetId, startRowIndex: template.listRow, endRowIndex: template.opponentRow + 1, startColumnIndex: col, endColumnIndex: col + 1 }, + cell: { userEnteredFormat: { backgroundColor: hexToRgbColor(color) } }, + fields: "userEnteredFormat.backgroundColor", + }, + }; + }).filter(Boolean); + if (colorRequests.length) { + try { + await batchUpdate(token, copy.id, colorRequests); + } catch (err) { + skipped.push({ team: oppTeam.name, reason: `Tab created but couldn't apply disposition colors: ${err.message}` }); + } + } + const data = []; ourTeam.members.forEach((member, i) => { const row = template.playerRows[i];