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
64 changes: 56 additions & 8 deletions src/lib/components/SubmissionStatus/UpdatingDropdown.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
// Component
<button
type="button"
onclick={() => updatingDropdown.toggle()} // Open / close the dropdown.
onclick={(event) => updatingDropdown.toggle(event)} // Open / close the dropdown.
>

<UpdatingDropdown bind:this={updatingDropdown} {taskResult} {isLoggedIn} {onupdate} />
Expand All @@ -30,6 +30,7 @@
import { enhance } from '$app/forms';

import { Dropdown, DropdownUl, DropdownLi, uiHelpers } from 'svelte-5-ui-lib';
import Check from 'lucide-svelte/icons/check';

import type { TaskResult } from '$lib/types/task';

Expand All @@ -55,15 +56,49 @@
let dropdownStatus = $state(false);
let closeDropdown = dropdown.close;

let dropdownX = $state(0);
let dropdownY = $state(0);
let isLowerHalfInScreen = $state(false);

$effect(() => {
activeUrl = $page.url.pathname;
dropdownStatus = dropdown.isOpen;

if (dropdownStatus) {
document.documentElement.style.setProperty('--dropdown-x', `${dropdownX}px`);
document.documentElement.style.setProperty('--dropdown-y', `${dropdownY}px`);
}
});

export function toggle(): void {
export function toggle(event?: MouseEvent): void {
if (event) {
getDropdownPosition(event);
}

dropdown.toggle();
}

function getDropdownPosition(event: MouseEvent): void {
const rect = (event.currentTarget as HTMLElement).getBoundingClientRect();

dropdownX = rect.right;
dropdownY = rect.bottom;

isLowerHalfInScreen = rect.top > window.innerHeight / 2;
}

function getDropdownClasses(isLower: boolean): string {
let classes =
'absolute w-32 z-[999] shadow-lg pointer-events-auto left-[var(--dropdown-x)] transform -translate-x-full ';

if (isLower) {
classes += 'bottom-[calc(100vh-var(--dropdown-y))] mb-5';
} else {
classes += 'top-[var(--dropdown-y)] mt-1';
}
return classes;
}

let selectedSubmissionStatus = $state<SubmissionStatus>();
let showForm = $state(false);

Expand Down Expand Up @@ -175,19 +210,17 @@
});
</script>

<div class="relative">
<div class="fixed inset-0 pointer-events-none z-50 w-full h-full">
<Dropdown
{activeUrl}
{dropdownStatus}
{closeDropdown}
class="absolute w-32 z-20 left-auto right-0 mt-8"
class={getDropdownClasses(isLowerHalfInScreen)}
>
<DropdownUl>
<DropdownUl class="border rounded-lg shadow">
{#if isLoggedIn}
{#each submissionStatusOptions as submissionStatus}
<DropdownLi href="javascript:void(0)" onclick={() => handleClick(submissionStatus)}>
{submissionStatus.labelName}
</DropdownLi>
{@render dropdownListForSubmissionStatus(taskResult, submissionStatus)}
{/each}
{:else}
<DropdownLi href={SIGNUP_PAGE}>アカウント作成</DropdownLi>
Expand All @@ -201,6 +234,21 @@
{/if}
</div>

{#snippet dropdownListForSubmissionStatus(
taskResult: TaskResult,
submissionStatus: SubmissionStatus,
)}
<DropdownLi href="javascript:void(0)" onclick={() => handleClick(submissionStatus)}>
<div class="flex items-center justify-between">
{submissionStatus.labelName}

{#if taskResult.status_name === submissionStatus.innerName}
<Check class="w-4 h-4 text-primary-600 dark:text-gray-300" strokeWidth={3} />
{/if}
</div>
</DropdownLi>
{/snippet}

{#snippet submissionStatusForm(selectedTaskResult: TaskResult, submissionStatus: SubmissionStatus)}
<form
id="submissionStatusForm"
Expand Down
20 changes: 10 additions & 10 deletions src/lib/components/TaskTables/TaskTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
}

function getBodyCellClasses(contestId: string, taskIndex: string): string {
const baseClasses = 'w-1/2 xs:w-1/3 sm:w-1/4 md:w-1/5 lg:w-1/6 px-1 py-1 border';
const baseClasses = 'w-1/2 xs:w-1/3 sm:w-1/4 md:w-1/5 lg:w-1/6 px-1 py-1';
const backgroundColor = getBackgroundColor(taskTable[contestId][taskIndex]);

return `${baseClasses} ${backgroundColor}`;
Expand Down Expand Up @@ -129,34 +129,34 @@
</Heading>

<!-- TODO: ページネーションを実装 -->
<!-- TODO: ヘッダーを固定できるようにする。-->
<!-- HACK: Flowbite と tailwindcss の相性が悪いのかもしれない。tailwindcss のクラス指定、raw HTML & CSS を試したが、いずれも実現できず。 -->
<!-- See: -->
<!-- https://github.com/kenkoooo/AtCoderProblems/blob/master/atcoder-problems-frontend/src/pages/TablePage/AtCoderRegularTable.tsx -->
<!-- https://github.com/birdou/atcoder-blogs/blob/main/app/atcoder-blogs-frontend/src/pages/BlogTablePage/BlogTablePage.tsx -->
<!-- https://tailwindcss.com/docs/position#sticky-positioning-elements -->
<div class="container w-full overflow-hidden rounded-md border border-gray-100 shadow-sm">
<div class="w-full overflow-auto">
<div class="container w-full rounded-md border shadow-sm">
<div class="w-full sticky top-0 z-20 border-b">
<Table id="task-table" class="text-md table-fixed w-full" aria-label="Task table">
<TableHead class="text-sm bg-gray-100">
<TableHeadCell class="w-full xl:w-16 px-2 text-center border" scope="col">
Round
</TableHeadCell>
<TableHeadCell class="w-full xl:w-16 px-2 text-center" scope="col">Round</TableHeadCell>

{#if taskTableHeaderIds.length}
{#each taskTableHeaderIds as taskTableHeaderId}
<TableHeadCell class="text-center border" scope="col">
<TableHeadCell class="text-center" scope="col">
{taskTableHeaderId}
</TableHeadCell>
{/each}
{/if}
</TableHead>
</Table>
</div>

<div class="w-full overflow-auto max-h-[calc(80vh-56px)]">
<Table id="task-table" class="text-md table-fixed w-full" aria-label="Task table">
<TableBody class="divide-y">
{#if contestIds.length && taskTableHeaderIds.length}
{#each contestIds as contestId}
<TableBodyRow class="flex flex-wrap xl:table-row">
<TableBodyCell class="w-full xl:w-16 truncate px-2 py-2 text-center border">
<TableBodyCell class="w-full xl:w-16 truncate px-2 py-2 text-center">
{getContestRoundLabel(provider, contestId)}
</TableBodyCell>

Expand Down
12 changes: 7 additions & 5 deletions src/lib/components/TaskTables/TaskTableBodyCell.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import EllipsisVertical from 'lucide-svelte/icons/ellipsis-vertical';
import ChevronDown from 'lucide-svelte/icons/chevron-down';

import type { TaskResult } from '$lib/types/task';

Expand All @@ -20,10 +20,12 @@
let updatingDropdown: UpdatingDropdown;
</script>

<div class="flex items-center w-full space-x-1 text-left text-sm sm:text-md">
<div
class="flex items-center w-full pl-0 lg:pl-1 space-x-1 lg:space-x-2 text-left text-sm sm:text-md"
>
{@render taskGradeLabel(taskResult)}

<div class="flex justify-between w-full min-w-0">
<div class="flex items-center justify-between w-full min-w-0">
{@render taskTitleAndExternalLink(taskResult)}
{@render submissionUpdaterAndLinksOfTaskDetailPage(taskResult)}
</div>
Expand Down Expand Up @@ -59,10 +61,10 @@
<button
type="button"
class="flex-shrink-0 w-6 ml-auto"
onclick={() => updatingDropdown.toggle()}
onclick={(event) => updatingDropdown.toggle(event)}
aria-label="Update submission for {selectedTaskResult.title}"
>
<EllipsisVertical class="w-4 h-4 mx-auto" />
<ChevronDown class="w-4 h-4 mx-auto" />
</button>

<UpdatingDropdown bind:this={updatingDropdown} {taskResult} {isLoggedIn} {onupdate} />
Expand Down
Loading