diff --git a/.changes/optimize-problem.md b/.changes/optimize-problem.md new file mode 100644 index 0000000..96a26d8 --- /dev/null +++ b/.changes/optimize-problem.md @@ -0,0 +1,5 @@ +--- +"algohub": patch:feat +--- + +Optimize problem pages, including create and edit pages. diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 8323914..2dcdfe2 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -28,7 +28,7 @@ dependencies = [ [[package]] name = "algohub" -version = "0.1.1-alpha.8" +version = "0.1.1-alpha.9" dependencies = [ "reqwest", "serde", diff --git a/src/components/ProblemEditor.vue b/src/components/ProblemEditor.vue index e26dd2b..38bdb05 100644 --- a/src/components/ProblemEditor.vue +++ b/src/components/ProblemEditor.vue @@ -14,6 +14,7 @@ const accountStore = useAccountStore(); const props = defineProps<{ id?: string }>(); const loading = ref(props.id ? true : false); +const path = ref<{ label?: string, link?: string }[]>(props.id ? [] : [{ label: 'New Problem' }]) onMounted(async () => { if (props.id) { const res = await api.fetchProblem(props.id, accountStore.auth); @@ -30,6 +31,9 @@ onMounted(async () => { hint.value = data.hint || ''; testCases.splice(0, testCases.length); data.test_cases?.forEach(tc => testCases.push({ input: tc.input, output: tc.output })); + + path.value = [{ label: res.data?.owner.id, link: `/account/${res.data?.owner.id}` }, { label: title.value, link: `/problem/${props.id}` }, { label: 'Edit' }] + loading.value = false; } }) @@ -83,6 +87,12 @@ const validate = (form: ProblemForm): boolean => { const inProgress = ref(false); const onCreateProblem = async () => { + if (totalSizePercent.value !== 100) { + uploadingTestCases.value = true; + await uploadTestCases(() => { + uploadingTestCases.value = false; + }) + } const problem: ProblemForm = { title: title.value, description: description.value, @@ -90,7 +100,7 @@ const onCreateProblem = async () => { output: output.value || undefined, samples: samples.map(sample => ({ input: sample.input, output: sample.output })), hint: hint.value || undefined, - time_limit: timeLimit.value, + time_limit: timeLimit.value * 1024 * 1024, memory_limit: memoryLimit.value, test_cases: testCases.map(tc => ({ input: tc.input, output: tc.output })), owner: { @@ -106,17 +116,27 @@ const onCreateProblem = async () => { if (inProgress.value) return; inProgress.value = true; - const res = await api.createProblem({ - id: accountStore.account.id!, - token: accountStore.account.token!, - ...problem, - }); + let res; + if (props.id) { + res = await api.updateProblem(props.id, { + id: accountStore.account.id!, + token: accountStore.account.token!, + ...problem, + }); + } else { + res = await api.createProblem({ + id: accountStore.account.id!, + token: accountStore.account.token!, + ...problem, + }); + } if (!res.success) { inProgress.value = false; return toast.add({ severity: 'error', summary: 'Error', detail: res.message, life: 3000 }); } inProgress.value = false; - router.push(`/problem/${res.data!.id}`); + const id = res.data?.id ?? props.id; + router.push(`/problem/${id}`); } const totalSize = ref(0); @@ -155,9 +175,13 @@ const onSelectedFiles = (event: FileUploadSelectEvent) => { event.files.forEach((file: File) => { totalSize.value += parseInt(formatSize(file.size)); }); + + totalUploadedSize.value = 0; }; +const uploadingTestCases = ref(false); const uploadTestCases = async (callback: () => void) => { + uploadingTestCases.value = true; normalizedFiles.value.forEach(async (fileTuple) => { if (!fileTuple.input) { return toast.add({ severity: 'error', summary: 'Error', detail: 'Input file not found for ' + fileTuple.output?.name, life: 3000 }); @@ -192,6 +216,7 @@ const uploadTestCases = async (callback: () => void) => { output: outputRes.data!.id, }) normalizedFiles.value.splice(normalizedFiles.value.indexOf(fileTuple), 1); + uploadingTestCases.value = false; }); callback(); } @@ -253,8 +278,12 @@ const onRemoveTestCases = async (testCase: TestCase) => { - + diff --git a/src/scripts/api.ts b/src/scripts/api.ts index d5d1da9..393d6cb 100644 --- a/src/scripts/api.ts +++ b/src/scripts/api.ts @@ -123,6 +123,15 @@ export const createProblem = async (form: CreateProblem) => { } }; +export const updateProblem = async (id: string, form: CreateProblem) => { + try { + const response = await axios.post(`/problem/update/${id}`, form); + return response.data as Response; + } catch (error) { + return handleAxiosError(AxiosError.from(error)); + } +}; + export const fetchProblem = async (id: string, form?: Credentials) => { try { const response = await axios.post(`/problem/get/${id}`, form); diff --git a/src/views/problem/[id].vue b/src/views/problem/[id].vue index c043e97..d2ac9e6 100644 --- a/src/views/problem/[id].vue +++ b/src/views/problem/[id].vue @@ -34,7 +34,7 @@ const formatProblem = (problem: UserProblem) => { } hint && (formattedText += `## Hint\n\n${hint}\n\n`); - return formattedText.repeat(10); + return formattedText; } const code = ref(''); diff --git a/src/views/problem/create.vue b/src/views/problem/create.vue index 7d0e398..aa004f0 100644 --- a/src/views/problem/create.vue +++ b/src/views/problem/create.vue @@ -1,10 +1,5 @@ - -