diff --git a/.yarn/versions/6bd55107.yml b/.yarn/versions/6bd55107.yml
new file mode 100644
index 0000000..85ee0e5
--- /dev/null
+++ b/.yarn/versions/6bd55107.yml
@@ -0,0 +1,3 @@
+releases:
+ "@aoi-js/frontend": patch
+ "@aoi-js/server": patch
diff --git a/apps/frontend/src/components/problem/DataUpload.vue b/apps/frontend/src/components/problem/DataUpload.vue
index 29d4fbe..5b57987 100644
--- a/apps/frontend/src/components/problem/DataUpload.vue
+++ b/apps/frontend/src/components/problem/DataUpload.vue
@@ -2,21 +2,29 @@
-
-
+
+
{{ t('term.config') }}
{{ t('action.upload') }}
+
+
+
+ {{ t('simple-mode') }}
+
+
+ {{ t('advanced-mode') }}
+
+
@@ -48,12 +56,18 @@ const emit = defineEmits<{
const { t } = useI18n()
-const { uploadFileTask, uploadInfo } = useDataUpload(props.problem._id, () => emit('updated'))
+const { uploadFileTask, uploadInfo, advanced } = useDataUpload(props.problem._id, () =>
+ emit('updated')
+)
en:
create-data-version: Create data version
+ simple-mode: Simple mode
+ advanced-mode: Advanced mode
zh-Hans:
create-data-version: 创建数据版本
+ simple-mode: 简单模式
+ advanced-mode: 高级模式
diff --git a/apps/frontend/src/components/utils/JsonViewer.vue b/apps/frontend/src/components/utils/JsonViewer.vue
index d3b876b..b1dfdb0 100644
--- a/apps/frontend/src/components/utils/JsonViewer.vue
+++ b/apps/frontend/src/components/utils/JsonViewer.vue
@@ -36,6 +36,7 @@ import { useI18n } from 'vue-i18n'
import MonacoEditor from './MonacoEditor.vue'
import AsyncState from './AsyncState.vue'
import ky from 'ky'
+import { watch } from 'vue'
const props = defineProps<{
endpoint?: string
@@ -64,6 +65,8 @@ const data = useAsyncState(async () => {
const json = await ky.get(url).json()
return json
}, null)
+
+watch([() => props.endpoint, () => props.url, () => props.rawString], () => data.execute())
en:
diff --git a/apps/frontend/src/components/utils/SettingsEditor.vue b/apps/frontend/src/components/utils/SettingsEditor.vue
index 5d837cb..69b0b66 100644
--- a/apps/frontend/src/components/utils/SettingsEditor.vue
+++ b/apps/frontend/src/components/utils/SettingsEditor.vue
@@ -23,6 +23,7 @@ import { useAsyncState } from '@vueuse/core'
import { useI18n } from 'vue-i18n'
import AsyncState from './AsyncState.vue'
import { nextTick } from 'vue'
+import { watch } from 'vue'
const props = defineProps<{
endpoint: string
@@ -41,6 +42,12 @@ const settings = useAsyncState(
null,
{ shallow: false }
)
+
+watch(
+ () => props.endpoint,
+ () => settings.execute()
+)
+
const patchSettings = useAsyncTask(async () => {
await http.patch(props.endpoint, {
json: settings.state.value
diff --git a/apps/frontend/src/pages/org/[orgId]/contest/[contestId]/ranklist/[ranklistKey].vue b/apps/frontend/src/pages/org/[orgId]/contest/[contestId]/ranklist/[ranklistKey].vue
index 6d3844b..19e1ef9 100644
--- a/apps/frontend/src/pages/org/[orgId]/contest/[contestId]/ranklist/[ranklistKey].vue
+++ b/apps/frontend/src/pages/org/[orgId]/contest/[contestId]/ranklist/[ranklistKey].vue
@@ -14,6 +14,7 @@
`contest/${props.contestId}/ranklist/${encodeURIComponent(props.ranklistKey)}/url`
+)
+
en:
ranklist-settings: Ranklist Settings
diff --git a/apps/frontend/src/utils/problem/data.ts b/apps/frontend/src/utils/problem/data.ts
index ae008d4..cc54c2a 100644
--- a/apps/frontend/src/utils/problem/data.ts
+++ b/apps/frontend/src/utils/problem/data.ts
@@ -1,5 +1,5 @@
import zip from 'jszip'
-import { reactive, watch } from 'vue'
+import { reactive, ref, watch } from 'vue'
import { computeSHA256 } from '../files'
import { http } from '../http'
import { useToast } from 'vue-toastification'
@@ -7,6 +7,7 @@ import { useAsyncTask } from '../async'
export function useDataUpload(problemId: string, updated: () => void) {
const toast = useToast()
+ const advanced = ref(false)
const uploadInfo = reactive({
file: [] as File[],
@@ -33,13 +34,17 @@ export function useDataUpload(problemId: string, updated: () => void) {
async function handleFile() {
const file = uploadInfo.file[0]
try {
- uploadInfo.hash = await computeSHA256(file)
- const result = await zip.loadAsync(file)
- const content = await result.file('problem.json')?.async('string')
- if (content) {
- uploadInfo.configJson = content
+ if (advanced.value) {
+ toast.warning('Advanced mode is on, you need to manually fill in the hash and config')
} else {
- toast.warning('problem.json not found in zip file, please check your file')
+ uploadInfo.hash = await computeSHA256(file)
+ const result = await zip.loadAsync(file)
+ const content = await result.file('problem.json')?.async('string')
+ if (content) {
+ uploadInfo.configJson = content
+ } else {
+ toast.warning('problem.json not found in zip file, please check your file')
+ }
}
} catch (err) {
toast.error('Failed to parse problem data, is it a zip file?')
@@ -63,5 +68,5 @@ export function useDataUpload(problemId: string, updated: () => void) {
updated()
})
- return { uploadInfo, uploadFileTask }
+ return { uploadInfo, uploadFileTask, advanced }
}
diff --git a/apps/server/src/routes/runner/ranklist.ts b/apps/server/src/routes/runner/ranklist.ts
index 8a8c114..b1e3ad8 100644
--- a/apps/server/src/routes/runner/ranklist.ts
+++ b/apps/server/src/routes/runner/ranklist.ts
@@ -57,19 +57,21 @@ const runnerRanklistTaskRoutes = defineRoutes(async (s) => {
const { modifiedCount } = await contests.updateOne(
{ _id: ctx._contestId, ranklistTaskId: ctx._taskId },
- {
- $addFields: {
- ranklistState: {
- $cond: {
- if: {
- $eq: ['$ranklistUpdatedAt', req.body.ranklistUpdatedAt]
- },
- then: ContestRanklistState.VALID,
- else: ContestRanklistState.INVALID
+ [
+ {
+ $addFields: {
+ ranklistState: {
+ $cond: {
+ if: {
+ $eq: ['$ranklistUpdatedAt', req.body.ranklistUpdatedAt]
+ },
+ then: ContestRanklistState.VALID,
+ else: ContestRanklistState.INVALID
+ }
}
}
}
- }
+ ]
)
if (modifiedCount === 0) return rep.notFound()
return {}