From 052b3a654db27098a33edec91ae386b529d2adee 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) --- code/controllers/subsystem/vote.dm | 5 +- tgui/packages/tgui/interfaces/VotePanel.tsx | 454 +++++++++----------- 2 files changed, 211 insertions(+), 248 deletions(-) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 0d5678a4abe..bbc9d168d52 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -284,6 +284,7 @@ SUBSYSTEM_DEF(vote) log_admin("[key_name(toggle_initiator)] [text_verb] Dead Vote.") message_admins("[key_name_admin(toggle_initiator)] [text_verb] Dead Vote.") SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Dead Vote", text_verb)) + update_static_data_for_all_viewers() /datum/controller/subsystem/vote/ui_state() return GLOB.always_state @@ -312,8 +313,6 @@ SUBSYSTEM_DEF(vote) "multiSelection" = current_vote?.choices_by_ckey, ) - data["voting"]= is_lower_admin ? voting : list() - var/list/all_vote_data = list() for(var/vote_name in possible_votes) var/datum/vote/vote = possible_votes[vote_name] @@ -356,6 +355,7 @@ SUBSYSTEM_DEF(vote) /datum/controller/subsystem/vote/ui_static_data(mob/user) var/list/data = list() data["VoteCD"] = CONFIG_GET(number/vote_delay) + data["deadVoteEnabled"] = CONFIG_GET(flag/no_dead_vote) return data /datum/controller/subsystem/vote/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state) @@ -374,7 +374,6 @@ SUBSYSTEM_DEF(vote) voter.log_message("cancelled a vote.", LOG_ADMIN) message_admins("[key_name_admin(voter)] has cancelled the current vote.") - SStgui.close_uis(src) reset() return TRUE diff --git a/tgui/packages/tgui/interfaces/VotePanel.tsx b/tgui/packages/tgui/interfaces/VotePanel.tsx index fe3ef670dee..c04fd69e0c2 100644 --- a/tgui/packages/tgui/interfaces/VotePanel.tsx +++ b/tgui/packages/tgui/interfaces/VotePanel.tsx @@ -1,13 +1,14 @@ import { + BlockQuote, Box, Button, - Collapsible, Dimmer, Icon, LabeledList, NoticeBox, Section, Stack, + Tooltip, } from 'tgui-core/components'; import type { BooleanLike } from 'tgui-core/react'; @@ -60,18 +61,15 @@ type Data = { currentVote: ActiveVote; possibleVotes: Vote[]; user: UserData; - voting: string[]; LastVoteTime: number; VoteCD: number; + deadVoteEnabled: BooleanLike; }; export const VotePanel = (props) => { const { act, data } = useBackend(); const { currentVote, user, LastVoteTime, VoteCD } = data; - /** - * Adds the voting type to title if there is an ongoing vote. - */ let windowTitle = 'Vote'; if (currentVote) { windowTitle += @@ -84,37 +82,49 @@ export const VotePanel = (props) => { return ( - -
- -
- - + + +
+ + + + + act('toggleDeadVote')} + checked={!data.deadVoteEnabled} + color="primary" + > + Dead votes + + + + ) + } + > + +
+
+ +
+ +
+
+ +
+ +
+
@@ -137,239 +147,193 @@ const VoteOptionDimmer = (props) => { ); }; -/** - * The create vote options menu. Only upper admins can disable voting. - * @returns A section visible to everyone with vote options. - */ const VoteOptions = (props) => { const { act, data } = useBackend(); const { possibleVotes, user, LastVoteTime, VoteCD } = data; return ( - -
- {LastVoteTime + VoteCD > 0 && } - - {possibleVotes.map((option) => ( - - - {!!user.isLowerAdmin && ( - - - act('toggleVote', { - voteName: option.name, - }) - } - /> - - )} - -
-
+ + +
+ {option.name} Vote +
+
+
+ +
+ ))} + ); }; -/** - * View Voters by ckey. Admin only. - * @returns A collapsible list of voters - */ -const VotersList = (props) => { - const { data } = useBackend(); - - return ( - - -
- {data.voting.map((voter) => { - return {voter}; - })} -
-
-
- ); -}; - -/** - * The choices panel which displays all options in the list. - * @returns A section visible to all users. - */ const ChoicesPanel = (props) => { const { act, data } = useBackend(); 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.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={ - - } - > - {user.multiSelection && - user.multiSelection[user.ckey.concat(choice.name)] === 1 ? ( - - ) : null} - {choice.votes} Votes - - - - ))} - - ) : null} - {currentVote ? null : No vote active!} -
-
+ <> + {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 ? `${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 && + user.multiSelection[user.ckey.concat(choice.name)] === 1 ? ( + + ) : null} + {choice.votes} Votes + + + + ))} + + ) : null} + {currentVote ? null : No vote active!} + ); }; -/** - * Countdown timer at the bottom. Includes a cancel vote option for admins. - * @returns A section visible to everyone. - */ const TimePanel = (props) => { const { act, data } = useBackend(); const { currentVote, user } = data; return ( - -
- - - Time Remaining:  - {currentVote?.timeRemaining || 0}s - - {!!user.isLowerAdmin && ( - - - - - - - - - )} - -
+ + + + {currentVote + ? `Time remaining: ${currentVote.timeRemaining}s` + : 'No current vote'} + + {!!user.isLowerAdmin && ( + + + + + + + + + )} + ); };