Skip to content
Open
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
14 changes: 13 additions & 1 deletion src/features/tasks/components/contest-table/TaskTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import {
Heading,
Button,
Toggle,
Table,
TableBody,
TableBodyCell,
Expand Down Expand Up @@ -44,6 +45,8 @@

let { taskResults, isLoggedIn, isAtCoderVerified, voteResults }: Props = $props();

let showNeutralBadge = $state(true);

// Prepare contest table provider based on the active contest type.
let activeContestType: ContestTableProviderGroups = $derived(activeContestTypeStore.get());

Expand Down Expand Up @@ -192,7 +195,7 @@

<!-- See: -->
<!-- https://flowbite-svelte.com/docs/components/buttons -->
<div class="flex justify-center md:justify-start m-4">
<div class="flex flex-wrap justify-between items-center m-4 gap-2">
<div class="flex flex-wrap justify-start gap-1 shadow-none">
{#each Object.entries(contestTableProviderGroups) as [type, config] (type)}
<Button
Expand All @@ -210,6 +213,14 @@
</Button>
{/each}
</div>

<Toggle
bind:checked={showNeutralBadge}
class="text-sm text-gray-700 dark:text-gray-300"
aria-label="Toggle visibility of ±0 relative evaluation badge"
>
±0 を表示
</Toggle>
Comment on lines +217 to +223

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The implementation plan explicitly excluded tests for this change (pure UI state with no new logic). Adding Playwright E2E coverage for this toggle would require a seeded environment with tasks that have vote statistics — scope beyond this issue. Deferring to a future task if needed.

</div>

<!-- TODO: ページネーションを実装 -->
Expand Down Expand Up @@ -294,6 +305,7 @@
{isLoggedIn}
{isAtCoderVerified}
{voteResults}
{showNeutralBadge}
isShownTaskIndex={contestTable.displayConfig.isShownTaskIndex}
{taskLabel}
onupdate={(updatedTask: TaskResult) => handleUpdateTaskResult(updatedTask)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
isShownTaskIndex: boolean;
taskLabel?: string;
voteResults: VoteStatisticsMap;
showNeutralBadge?: boolean;
onupdate?: (updatedTask: TaskResult) => void; // Ensure to update task result in parent component.
}

Expand All @@ -26,6 +27,7 @@
isShownTaskIndex,
taskLabel,
voteResults,
showNeutralBadge = true,
onupdate = () => {},
}: Props = $props();

Expand Down Expand Up @@ -60,6 +62,7 @@
{isLoggedIn}
{isAtCoderVerified}
{estimatedGrade}
{showNeutralBadge}
defaultPadding={0.25}
defaultWidth={6}
reducedWidth={6}
Expand Down
13 changes: 11 additions & 2 deletions src/features/votes/components/VotableGrade.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
defaultPadding?: number;
defaultWidth?: number;
reducedWidth?: number;
showNeutralBadge?: boolean;
}

let {
Expand All @@ -48,6 +49,7 @@
defaultPadding = 1,
defaultWidth = 10,
reducedWidth = 8,
showNeutralBadge = true,
}: Props = $props();

// 表示用のグレード(投票後に画面リロードなしで差し替えるためのローカル状態)
Expand Down Expand Up @@ -83,6 +85,12 @@
return getRelativeEvaluationLabel(calcGradeDiff(taskResult.grade, latestMedianGrade));
});

// Whether to show the relative evaluation label (badge + sr-only text).
// Hidden only when showNeutralBadge is false and the label is exactly '±0'.
const shouldShowRelativeEvaluation = $derived(
showNeutralBadge || relativeEvaluationLabel !== '±0',
);

let isOpening = $state(false);
let votedGrade = $state<TaskGrade | null>(null);
let voteAbortController: AbortController | null = null;
Expand Down Expand Up @@ -191,14 +199,15 @@
onclick={() => onTriggerClick()}
>
<span class="sr-only">
Voted grade: {getTaskGradeLabel(displayGrade)}{relativeEvaluationLabel
Voted grade: {getTaskGradeLabel(displayGrade)}{relativeEvaluationLabel &&
shouldShowRelativeEvaluation
? `, relative evaluation: ${relativeEvaluationLabel}`
: ''}{isProvisional ? ', provisional' : ''}
</span>

<GradeLabel taskGrade={displayGrade} {defaultPadding} {defaultWidth} {reducedWidth} />

{#if taskResult.grade !== TaskGrade.PENDING && latestMedianGrade}
{#if taskResult.grade !== TaskGrade.PENDING && latestMedianGrade && shouldShowRelativeEvaluation}
<RelativeEvaluationBadge
officialGrade={taskResult.grade}
medianGrade={latestMedianGrade}
Expand Down
Loading