This commit is contained in:
2026-10-04 15:13:42 +07:00
parent 5695748a3e
commit 8ea7ba3062
+60 -9
View File
@@ -113,6 +113,9 @@ const screenPlanDraft = ref<ScreenPlanStep[]>([])
const screenPlanDirty = ref(false) const screenPlanDirty = ref(false)
const screenPlanSaving = ref(false) const screenPlanSaving = ref(false)
const screenPlanMode = ref<'use' | 'edit'>('use') const screenPlanMode = ref<'use' | 'edit'>('use')
let screenPlanRequestVersion = 0
const screenPlanStepKeys = new WeakMap<ScreenPlanStep, number>()
let nextScreenPlanStepKey = 0
const previewQuestions = ref<ResultsQuestion[]>([]) const previewQuestions = ref<ResultsQuestion[]>([])
const previewTeams = ref<TeamResult[]>([]) const previewTeams = ref<TeamResult[]>([])
const mapItems = ref<MapItem[]>([]) const mapItems = ref<MapItem[]>([])
@@ -189,8 +192,15 @@ function isScreenPlanEditing() {
async function getScreenPlan() { async function getScreenPlan() {
if (isScreenPlanEditing() || screenPlanDirty.value) return if (isScreenPlanEditing() || screenPlanDirty.value) return
const requestVersion = ++screenPlanRequestVersion
const res = await client.GetScreenPlan({ gameID: Number(gameId) }) const res = await client.GetScreenPlan({ gameID: Number(gameId) })
if (isScreenPlanEditing() || screenPlanDirty.value) return if (
requestVersion !== screenPlanRequestVersion ||
isScreenPlanEditing() ||
screenPlanDirty.value
) {
return
}
screenPlan.value = res.plan screenPlan.value = res.plan
screenPlanDraft.value = res.plan?.steps?.map((step) => ({ ...step })) || [] screenPlanDraft.value = res.plan?.steps?.map((step) => ({ ...step })) || []
} }
@@ -237,8 +247,18 @@ function markScreenPlanDirty() {
screenPlanDirty.value = true screenPlanDirty.value = true
} }
function getScreenPlanStepKey(step: ScreenPlanStep) {
let key = screenPlanStepKeys.get(step)
if (key === undefined) {
key = nextScreenPlanStepKey++
screenPlanStepKeys.set(step, key)
}
return key
}
async function saveScreenPlan() { async function saveScreenPlan() {
if (screenPlanSaving.value) return if (screenPlanSaving.value) return
screenPlanRequestVersion += 1
screenPlanSaving.value = true screenPlanSaving.value = true
try { try {
const currentStep = Math.min( const currentStep = Math.min(
@@ -942,8 +962,16 @@ useSimplePolling(() => {
<n-button size="small" @click="editScreenPlan">Редактировать</n-button> <n-button size="small" @click="editScreenPlan">Редактировать</n-button>
</template> </template>
<template v-if="screenPlanMode === 'edit'"> <template v-if="screenPlanMode === 'edit'">
<n-button size="small" @click="cancelScreenPlanEdit">Отменить</n-button> <n-button size="small" :disabled="screenPlanSaving" @click="cancelScreenPlanEdit">
<n-button size="small" type="primary" :loading="screenPlanSaving" @click="saveScreenPlan"> Отменить
</n-button>
<n-button
size="small"
type="primary"
:loading="screenPlanSaving"
:disabled="screenPlanSaving"
@click="saveScreenPlan"
>
Сохранить план Сохранить план
</n-button> </n-button>
</template> </template>
@@ -951,11 +979,12 @@ useSimplePolling(() => {
</n-flex> </n-flex>
<p v-if="!screenPlan && screenPlanMode === 'use'" class="screen-empty">План экранов ещё не создан.</p> <p v-if="!screenPlan && screenPlanMode === 'use'" class="screen-empty">План экранов ещё не создан.</p>
<template v-else-if="screenPlanMode === 'edit'"> <template v-else-if="screenPlanMode === 'edit'">
<n-space v-for="(step, index) in screenPlanDraft" :key="index" align="center" wrap> <n-space v-for="(step, index) in screenPlanDraft" :key="getScreenPlanStepKey(step)" align="center" wrap>
<n-text>{{ index + 1 }}</n-text> <n-text>{{ index + 1 }}</n-text>
<n-select <n-select
v-model:value="step.mode" v-model:value="step.mode"
:options="screenPlanModeOptions" :options="screenPlanModeOptions"
:disabled="screenPlanSaving"
size="small" size="small"
style="width: 180px" style="width: 180px"
@update:value="markScreenPlanDirty" @update:value="markScreenPlanDirty"
@@ -963,6 +992,7 @@ useSimplePolling(() => {
<n-input <n-input
v-if="step.mode === 'SCREEN_MODE_TEXT'" v-if="step.mode === 'SCREEN_MODE_TEXT'"
v-model:value="step.text" v-model:value="step.text"
:disabled="screenPlanSaving"
size="small" size="small"
placeholder="Текст экрана" placeholder="Текст экрана"
style="min-width: 240px" style="min-width: 240px"
@@ -971,6 +1001,7 @@ useSimplePolling(() => {
<template v-if="step.mode === 'SCREEN_MODE_TIMER'"> <template v-if="step.mode === 'SCREEN_MODE_TIMER'">
<n-input <n-input
v-model:value="step.timerLabel" v-model:value="step.timerLabel"
:disabled="screenPlanSaving"
size="small" size="small"
placeholder="Надпись таймера" placeholder="Надпись таймера"
@update:value="markScreenPlanDirty" @update:value="markScreenPlanDirty"
@@ -979,26 +1010,46 @@ useSimplePolling(() => {
v-model:value="step.timerDurationSeconds" v-model:value="step.timerDurationSeconds"
:min="1" :min="1"
:max="86400" :max="86400"
:disabled="screenPlanSaving"
size="small" size="small"
placeholder="Секунды" placeholder="Секунды"
@update:value="markScreenPlanDirty" @update:value="markScreenPlanDirty"
/> />
</template> </template>
<n-button size="small" :disabled="index === 0" @click="moveScreenPlanStep(index, -1)">↑</n-button>
<n-button <n-button
size="small" size="small"
:disabled="index === screenPlanDraft.length - 1" :disabled="screenPlanSaving || index === 0"
@click="moveScreenPlanStep(index, -1)"
>
↑
</n-button>
<n-button
size="small"
:disabled="screenPlanSaving || index === screenPlanDraft.length - 1"
@click="moveScreenPlanStep(index, 1)" @click="moveScreenPlanStep(index, 1)"
> >
↓ ↓
</n-button> </n-button>
<n-button size="small" type="error" ghost @click="removeScreenPlanStep(index)"> <n-button
size="small"
type="error"
ghost
:disabled="screenPlanSaving"
@click="removeScreenPlanStep(index)"
>
Удалить Удалить
</n-button> </n-button>
</n-space> </n-space>
<n-space> <n-space>
<n-button size="small" @click="addScreenPlanStep">Добавить шаг</n-button> <n-button size="small" :disabled="screenPlanSaving" @click="addScreenPlanStep">
<n-button v-if="screenPlanDraft.length" size="small" @click="screenPlanDraft = []; markScreenPlanDirty()"> Добавить шаг
</n-button>
<n-button
v-if="screenPlanDraft.length"
size="small"
:disabled="screenPlanSaving"
@click="screenPlanDraft = []; markScreenPlanDirty()"
>
Удалить план Удалить план
</n-button> </n-button>
</n-space> </n-space>