From 20e1f3eb2bb4c65d2ca4e207e8023f5e997781b3 Mon Sep 17 00:00:00 2001 From: Kato Hiroki Date: Sun, 23 Mar 2025 13:32:11 +0000 Subject: [PATCH 1/2] :art: Enable to update submission status from drop down in task list by grades and detailed workbook page (#1858) --- .../SubmissionStatusInTableBodyCell.svelte | 29 +++++++++++ .../SubmissionStatus/UpdatingDropdown.svelte | 21 ++++---- src/lib/components/TaskList.svelte | 41 ++++++++-------- .../TaskTables/TaskTableBodyCell.svelte | 8 ++- src/routes/workbooks/[slug]/+page.svelte | 49 ++++++++----------- 5 files changed, 88 insertions(+), 60 deletions(-) create mode 100644 src/lib/components/SubmissionStatus/SubmissionStatusInTableBodyCell.svelte diff --git a/src/lib/components/SubmissionStatus/SubmissionStatusInTableBodyCell.svelte b/src/lib/components/SubmissionStatus/SubmissionStatusInTableBodyCell.svelte new file mode 100644 index 000000000..1fc106631 --- /dev/null +++ b/src/lib/components/SubmissionStatus/SubmissionStatusInTableBodyCell.svelte @@ -0,0 +1,29 @@ + + + updatingDropdown.toggle()} +> +
+ +
+
+ + diff --git a/src/lib/components/SubmissionStatus/UpdatingDropdown.svelte b/src/lib/components/SubmissionStatus/UpdatingDropdown.svelte index 6b286cd96..95c341c22 100644 --- a/src/lib/components/SubmissionStatus/UpdatingDropdown.svelte +++ b/src/lib/components/SubmissionStatus/UpdatingDropdown.svelte @@ -9,9 +9,10 @@ taskResult: TaskResult; isLoggedIn: boolean; onupdate?: (updatedTask: TaskResult) => void; + dropdownClass?: string; } - let { taskResult, isLoggedIn, onupdate = () => {} }: Props = $props(); + let { taskResult, isLoggedIn, onupdate, dropdownClass = '' }: Props = $props(); let updatingDropdown: UpdatingDropdown; @@ -44,9 +45,10 @@ taskResult: TaskResult; isLoggedIn: boolean; onupdate: (updatedTask: TaskResult) => void; // Ensure to update task result in parent component. + dropdownClass?: string; } - let { taskResult, isLoggedIn, onupdate }: Props = $props(); + let { taskResult, isLoggedIn, onupdate, dropdownClass = '' }: Props = $props(); const { page } = getStores(); let activeUrl = $state($page.url.pathname); @@ -67,11 +69,7 @@ let selectedSubmissionStatus = $state(); let showForm = $state(false); - function handleClick(submissionStatus: { - innerId: string; - innerName: string; - labelName: string; - }): void { + function handleClick(submissionStatus: SubmissionStatus): void { selectedSubmissionStatus = submissionStatus; showForm = true; @@ -92,6 +90,7 @@ innerId: string; innerName: string; labelName: string; + imagePath: string; }; type EnhanceForSubmit = { @@ -158,8 +157,10 @@ ...taskResult, status_name: submissionStatus.innerName, status_id: submissionStatus.innerId, + submission_status_image_path: submissionStatus.imagePath, submission_status_label_name: submissionStatus.labelName, - is_ac: submissionStatus.innerName === 'ac', + is_ac: + submissionStatus.innerName === 'ac' || submissionStatus.innerName === 'ac_with_editorial', updated_at: new Date(), }; } @@ -170,17 +171,19 @@ innerId: status.id, innerName: status.status_name, labelName: status.label_name, + imagePath: status.image_path, }; return option; });
+ {#if isLoggedIn} diff --git a/src/lib/components/TaskList.svelte b/src/lib/components/TaskList.svelte index 60ded2770..36ab02663 100644 --- a/src/lib/components/TaskList.svelte +++ b/src/lib/components/TaskList.svelte @@ -13,10 +13,9 @@ import { type TaskResult, type TaskResults, TaskGrade } from '$lib/types/task'; import ThermometerProgressBar from '$lib/components/ThermometerProgressBar.svelte'; - import UpdatingModal from '$lib/components/SubmissionStatus/UpdatingModal.svelte'; - import SubmissionStatusImage from '$lib/components/SubmissionStatus/SubmissionStatusImage.svelte'; - import ExternalLinkWrapper from '$lib/components/ExternalLinkWrapper.svelte'; import AcceptedCounter from '$lib/components/SubmissionStatus/AcceptedCounter.svelte'; + import SubmissionStatusTableBodyCell from '$lib/components/SubmissionStatus/SubmissionStatusInTableBodyCell.svelte'; + import ExternalLinkWrapper from '$lib/components/ExternalLinkWrapper.svelte'; import { getBackgroundColorFrom } from '$lib/services/submission_status'; @@ -33,15 +32,18 @@ let { grade, gradeColor, taskResults, isAdmin, isLoggedIn }: Props = $props(); - // TODO: 他のコンポーネントでも利用できるようにする。 - let updatingModal: UpdatingModal | null = null; + function updateTaskResult(updatedTask: TaskResult): void { + const newTaskResults = [...taskResults]; + + const index = newTaskResults.findIndex( + (task: TaskResult) => task.task_id === updatedTask.task_id, + ); - function openModal(taskResult: TaskResult): void { - if (updatingModal) { - updatingModal.openModal(taskResult); - } else { - console.error('Failed to initialize UpdatingModal component.'); + if (index !== -1) { + newTaskResults[index] = updatedTask; } + + taskResults = newTaskResults; } @@ -66,7 +68,6 @@ {/snippet} -
@@ -90,14 +91,14 @@ id={taskResult.contest_id + '-' + taskResult.task_id} class={getBackgroundColorFrom(taskResult.status_name)} > - openModal(taskResult)} - > -
- -
-
+
+ updateTaskResult(updatedTask)} + /> +
+ - - diff --git a/src/lib/components/TaskTables/TaskTableBodyCell.svelte b/src/lib/components/TaskTables/TaskTableBodyCell.svelte index 5ae8e1e4b..a0cdd0c96 100644 --- a/src/lib/components/TaskTables/TaskTableBodyCell.svelte +++ b/src/lib/components/TaskTables/TaskTableBodyCell.svelte @@ -65,6 +65,12 @@ - +
{/snippet} diff --git a/src/routes/workbooks/[slug]/+page.svelte b/src/routes/workbooks/[slug]/+page.svelte index 1d6567617..1df4bb9f3 100644 --- a/src/routes/workbooks/[slug]/+page.svelte +++ b/src/routes/workbooks/[slug]/+page.svelte @@ -13,9 +13,8 @@ import PublicationStatusLabel from '$lib/components/WorkBooks/PublicationStatusLabel.svelte'; import CompletedTasks from '$lib/components/Trophies/CompletedTasks.svelte'; import HeadingOne from '$lib/components/HeadingOne.svelte'; - import UpdatingModal from '$lib/components/SubmissionStatus/UpdatingModal.svelte'; - import SubmissionStatusImage from '$lib/components/SubmissionStatus/SubmissionStatusImage.svelte'; import GradeLabel from '$lib/components/GradeLabel.svelte'; + import SubmissionStatusTableBodyCell from '$lib/components/SubmissionStatus/SubmissionStatusInTableBodyCell.svelte'; import ExternalLinkWrapper from '$lib/components/ExternalLinkWrapper.svelte'; import CommentAndHint from '$lib/components/WorkBook/CommentAndHint.svelte'; @@ -44,6 +43,17 @@ return taskResults?.get(taskId) as TaskResult; }; + const updateTaskResult = (updatedTask: TaskResult): void => { + const taskId = updatedTask.task_id; + + if (taskResults.has(taskId)) { + // Force to update the task result. + const newTaskResults = new Map(taskResults); + newTaskResults.set(taskId, updatedTask); + taskResults = newTaskResults; + } + }; + const getTaskGrade = (taskId: string): TaskGrade => { return getTaskResult(taskId)?.grade as TaskGrade; }; @@ -75,19 +85,6 @@ return getContestIdFrom(taskId) + '-' + taskId; }; - // HACK:: `updatingModal` is updated, but is not declared with `$state(...)`. Changing its value will not correctly trigger updates. - // eslint-disable-next-line svelte/valid-compile - let updatingModal: UpdatingModal | null = null; - - // HACK: clickを1回実行するとactionsが2回実行されてしまう。原因と修正方法が分かっていない。 - function handleClick(taskId: string) { - if (updatingModal) { - updatingModal.openModal(getTaskResult(taskId)); - } else { - console.error('Failed to initialize UpdatingModal component.'); - } - } - $effect(() => { if (taskResults && workBook && Array.isArray(workBook.workBookTasks)) { workBookTasks = workBook.workBookTasks; @@ -173,18 +170,14 @@
- - handleClick(workBookTask.taskId)} - > -
- -
-
+ +
+ updateTaskResult(updatedTask)} + /> +
@@ -219,8 +212,6 @@ - - {:else} {'問題を1問以上登録してください。'} {/if} From e6d18bbc9e632f0cf9469f8fcdc487f02d6aa27f Mon Sep 17 00:00:00 2001 From: Kato Hiroki Date: Sun, 23 Mar 2025 13:38:44 +0000 Subject: [PATCH 2/2] :boom: Remove modal to update submission status (#1858) --- .../SubmissionStatus/UpdatingModal.svelte | 102 ------------------ 1 file changed, 102 deletions(-) delete mode 100644 src/lib/components/SubmissionStatus/UpdatingModal.svelte diff --git a/src/lib/components/SubmissionStatus/UpdatingModal.svelte b/src/lib/components/SubmissionStatus/UpdatingModal.svelte deleted file mode 100644 index 38204b2fe..000000000 --- a/src/lib/components/SubmissionStatus/UpdatingModal.svelte +++ /dev/null @@ -1,102 +0,0 @@ - - -{#if isLoggedIn && selectedTaskResult} - -
- - - - -