From c7fe8ac18e2da416e561e8969e319621dea3d1bb Mon Sep 17 00:00:00 2001 From: mcbalaam <104003807+mcbalaam@users.noreply.github.com> Date: Thu, 28 May 2026 07:42:04 +0700 Subject: [PATCH] feat: Vote panel UI cleanup; auto-close fix (#96166) (conflict resolved) --- tgui/packages/tgui/interfaces/VotePanel.tsx | 403 ++++++++++---------- 1 file changed, 198 insertions(+), 205 deletions(-) diff --git a/tgui/packages/tgui/interfaces/VotePanel.tsx b/tgui/packages/tgui/interfaces/VotePanel.tsx index 4b4ca56bf69..086f1c5f945 100644 --- a/tgui/packages/tgui/interfaces/VotePanel.tsx +++ b/tgui/packages/tgui/interfaces/VotePanel.tsx @@ -216,217 +216,210 @@ const ChoicesPanel = (props) => { const { currentVote, user } = data; return ( - -
- {currentVote && currentVote.countMethod === VoteSystem.VOTE_SINGLE ? ( - Select one option - ) : null} - {currentVote && - currentVote.choices.length !== 0 && - currentVote.countMethod === VoteSystem.VOTE_SINGLE ? ( - - {currentVote.choices.map((choice) => ( - - c.toUpperCase())} - textAlign="right" - buttons={ - - } - > - {user.singleSelection && - choice.name === user.singleSelection && ( + <> + {currentVote && currentVote.countMethod === VoteSystem.VOTE_SINGLE ? ( + Select one option + ) : null} + {currentVote && + currentVote.choices.length !== 0 && + currentVote.countMethod === VoteSystem.VOTE_SINGLE ? ( + + {currentVote.choices.map((choice) => ( + + c.toUpperCase())} + textAlign="right" + buttons={ + + } + > + {user.singleSelection && + choice.name === user.singleSelection && ( )} - {currentVote.displayStatistics || user.isLowerAdmin /* SKYRAT EDIT*/ ? `${choice.votes} Votes` : null} - - - - ))} - - ) : null} - {currentVote && currentVote.countMethod === VoteSystem.VOTE_MULTI ? ( - Select any number of options - ) : null} - {currentVote && - currentVote.choices.length !== 0 && - currentVote.countMethod === VoteSystem.VOTE_MULTI ? ( - - {currentVote.choices.map((choice) => ( - - c.toUpperCase())} - textAlign="right" - buttons={ - - } - > - {user.multiSelection && - // BUBBER EDIT CHANGE - Original: [user.ckey.concat(choice.name)] - user.multiSelection[`${user.ckey}_${choice.name}`] === 1 ? ( - - ) : null} - { - user.isLowerAdmin - ? `${choice.votes} Votes` - : '' /* SKYRAT EDIT*/ - } - - - - ))} - - ) : null} - {/* BUBBER EDIT ADDITION - Ranked Choice Voting */} - {currentVote && currentVote.countMethod === VoteSystem.VOTE_RANKED ? ( - - Click options to rank them in order of preference. Click again to - remove. - - ) : null} - {currentVote && - currentVote.choices.length !== 0 && - currentVote.countMethod === VoteSystem.VOTE_RANKED ? ( - - {currentVote.choices - .map((choice) => { - // Get all current ranks for this user - const userRanks: Record = {}; - let maxRank = 0; - currentVote.choices.forEach((c) => { - const rankKey = `${user.ckey}_${c.name}`; - const rank = user.multiSelection?.[rankKey] || 0; - if (rank > 0) { - userRanks[c.name] = rank; - maxRank = Math.max(maxRank, rank); - } - }); - - // Get this choice's current rank - const rankKey = `${user.ckey}_${choice.name}`; - const currentRank = user.multiSelection?.[rankKey] || 0; - - return { - choice, - currentRank, - userRanks, - maxRank, - }; - }) - // Sort by rank (unranked at bottom) - .sort((a, b) => { - if (a.currentRank === 0 && b.currentRank === 0) { - // If both unranked, sort alphabetically - return a.choice.name.localeCompare(b.choice.name); + {currentVote.displayStatistics ? `${choice.votes} Votes` : null} + + + + ))} + + ) : null} + {currentVote && currentVote.countMethod === VoteSystem.VOTE_MULTI ? ( + Select any number of options + ) : null} + {currentVote && + currentVote.choices.length !== 0 && + currentVote.countMethod === VoteSystem.VOTE_MULTI ? ( + + {currentVote.choices.map((choice) => ( + + c.toUpperCase())} + textAlign="right" + buttons={ + } - if (a.currentRank === 0) return 1; // a is unranked, move to bottom - if (b.currentRank === 0) return -1; // b is unranked, move to bottom - return a.currentRank - b.currentRank; // sort by rank - }) - .map(({ choice, currentRank, userRanks, maxRank }) => { - // Function to get button text - const getButtonText = () => { - if (currentRank === 0) { - return 'Vote'; - } - return `Choice #${currentRank}`; - }; + > + {user.multiSelection && + user.multiSelection[user.ckey.concat(choice.name)] === 1 ? ( + + ) : null} + {choice.votes} Votes + + + + ))} + + ) : null} + {/* BUBBER EDIT ADDITION - Ranked Choice Voting */} + {currentVote && currentVote.countMethod === VoteSystem.VOTE_RANKED ? ( + + Click options to rank them in order of preference. Click again to + remove. + + ) : null} + {currentVote && + currentVote.choices.length !== 0 && + currentVote.countMethod === VoteSystem.VOTE_RANKED ? ( + + {currentVote.choices + .map((choice) => { + // Get all current ranks for this user + const userRanks: Record = {}; + let maxRank = 0; + currentVote.choices.forEach((c) => { + const rankKey = `${user.ckey}_${c.name}`; + const rank = user.multiSelection?.[rankKey] || 0; + if (rank > 0) { + userRanks[c.name] = rank; + maxRank = Math.max(maxRank, rank); + } + }); - // Function to handle vote click - const handleVoteClick = () => { - if (currentRank > 0) { - // Remove this rank and shift others up - const newRanks: Record = {}; - Object.entries(userRanks).forEach( - ([name, rank]: [string, number]) => { - if (name === choice.name) { - return; // Skip this one as we're removing it - } - if (rank > currentRank) { - newRanks[name] = rank - 1; // Shift up - } else { - newRanks[name] = rank; // Keep same - } - }, - ); - // Send all rank updates - Object.entries(newRanks).forEach( - ([name, newRank]: [string, number]) => { - act('voteRanked', { - voteOption: name, - voteRank: newRank, - }); - }, - ); - // Remove this rank - act('voteRanked', { - voteOption: choice.name, - voteRank: 0, - }); - } else { - // Add as next rank - act('voteRanked', { - voteOption: choice.name, - voteRank: maxRank + 1, - }); - } - }; + // Get this choice's current rank + const rankKey = `${user.ckey}_${choice.name}`; + const currentRank = user.multiSelection?.[rankKey] || 0; - return ( - - c.toUpperCase())} - textAlign="right" - buttons={ - + return { + choice, + currentRank, + userRanks, + maxRank, + }; + }) + // Sort by rank (unranked at bottom) + .sort((a, b) => { + if (a.currentRank === 0 && b.currentRank === 0) { + // If both unranked, sort alphabetically + return a.choice.name.localeCompare(b.choice.name); + } + if (a.currentRank === 0) return 1; // a is unranked, move to bottom + if (b.currentRank === 0) return -1; // b is unranked, move to bottom + return a.currentRank - b.currentRank; // sort by rank + }) + .map(({ choice, currentRank, userRanks, maxRank }) => { + // Function to get button text + const getButtonText = () => { + if (currentRank === 0) { + return 'Vote'; + } + return `Choice #${currentRank}`; + }; + + // Function to handle vote click + const handleVoteClick = () => { + if (currentRank > 0) { + // Remove this rank and shift others up + const newRanks: Record = {}; + Object.entries(userRanks).forEach( + ([name, rank]: [string, number]) => { + if (name === choice.name) { + return; // Skip this one as we're removing it } - > - {currentVote.displayStatistics || user.isLowerAdmin - ? `${choice.votes} Votes` - : null} - - - - ); - })} - - ) : null} - {/* BUBBER EDIT ADDITION END */} - {currentVote ? null : No vote active!} -
-
+ if (rank > currentRank) { + newRanks[name] = rank - 1; // Shift up + } else { + newRanks[name] = rank; // Keep same + } + }, + ); + // Send all rank updates + Object.entries(newRanks).forEach( + ([name, newRank]: [string, number]) => { + act('voteRanked', { + voteOption: name, + voteRank: newRank, + }); + }, + ); + // Remove this rank + act('voteRanked', { + voteOption: choice.name, + voteRank: 0, + }); + } else { + // Add as next rank + act('voteRanked', { + voteOption: choice.name, + voteRank: maxRank + 1, + }); + } + }; + + return ( + + c.toUpperCase())} + textAlign="right" + buttons={ + + } + > + {currentVote.displayStatistics || user.isLowerAdmin + ? `${choice.votes} Votes` + : null} + + + + ); + })} + + ) : null} + {/* BUBBER EDIT ADDITION END */} + {currentVote ? null : No vote active!} + ); };