fix
This commit is contained in:
@@ -254,18 +254,20 @@ const gameOptions = computed(() => {
|
|||||||
</n-card>
|
</n-card>
|
||||||
<n-card v-if="bridge && isReady" title="Материалы" data-testid="game-materials">
|
<n-card v-if="bridge && isReady" title="Материалы" data-testid="game-materials">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-tag
|
<div class="server-actions">
|
||||||
role="status"
|
<n-tag
|
||||||
data-testid="game-selection-status"
|
role="status"
|
||||||
:type="selectedKey ? 'success' : 'error'"
|
data-testid="game-selection-status"
|
||||||
>
|
:type="selectedKey ? 'success' : 'error'"
|
||||||
{{ selectedKey ? 'Игра выбрана' : 'Игра не выбрана' }}
|
>
|
||||||
</n-tag>
|
{{ selectedKey ? 'Игра выбрана' : 'Игра не выбрана' }}
|
||||||
|
</n-tag>
|
||||||
|
<n-button v-if="selectedKey" size="small" :disabled="isBusy || state.busy || outputOpen" @click="emit('resetGame')">Сменить игру</n-button>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div class="connection-content">
|
<div class="connection-content">
|
||||||
<div v-if="selectedKey" class="current-game">
|
<div v-if="selectedKey" class="current-game">
|
||||||
<span data-testid="control-game">Текущая игра: {{ selectedName }}</span>
|
<span data-testid="control-game">Текущая игра: {{ selectedName }}</span>
|
||||||
<n-button :disabled="isBusy || state.busy || outputOpen" @click="emit('resetGame')">Сменить игру</n-button>
|
|
||||||
</div>
|
</div>
|
||||||
<template v-if="!selectedKey">
|
<template v-if="!selectedKey">
|
||||||
<span>Скачанные игры</span>
|
<span>Скачанные игры</span>
|
||||||
@@ -481,15 +483,21 @@ const gameOptions = computed(() => {
|
|||||||
</div>
|
</div>
|
||||||
</n-card>
|
</n-card>
|
||||||
<GameControlPanel v-if="bridge && isReady" :state="state" :is-busy="isBusy" :selected-key="selectedKey" :selected-name="selectedName" @action="run">
|
<GameControlPanel v-if="bridge && isReady" :state="state" :is-busy="isBusy" :selected-key="selectedKey" :selected-name="selectedName" @action="run">
|
||||||
<ScreenConnectionPanel :state="state" :is-busy="isBusy" @action="run">
|
<template #connection-actions>
|
||||||
<template v-if="state.authenticated">
|
<n-button
|
||||||
<n-button
|
v-if="state.authenticated && state.connection !== 'connected'"
|
||||||
v-if="state.connection !== 'connected'"
|
size="small"
|
||||||
:disabled="!canConnectCurrent || isBusy || state.busy"
|
:disabled="!canConnectCurrent || isBusy || state.busy"
|
||||||
@click="run({ action: 'connect' })"
|
@click="run({ action: 'connect' })"
|
||||||
>Подключиться</n-button>
|
>Подключиться</n-button>
|
||||||
</template>
|
<n-button
|
||||||
</ScreenConnectionPanel>
|
v-if="state.screenId"
|
||||||
|
size="small"
|
||||||
|
:disabled="isBusy || state.busy"
|
||||||
|
@click="run({ action: 'disconnect' })"
|
||||||
|
>Отключиться</n-button>
|
||||||
|
</template>
|
||||||
|
<ScreenConnectionPanel :state="state" :is-busy="isBusy" @action="run" />
|
||||||
</GameControlPanel>
|
</GameControlPanel>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -561,10 +569,6 @@ const gameOptions = computed(() => {
|
|||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
.current-game > button {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-selection {
|
.game-selection {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -279,13 +279,23 @@ onUnmounted(() => {
|
|||||||
/>
|
/>
|
||||||
<n-card v-if="bridge" title="Экран">
|
<n-card v-if="bridge" title="Экран">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-tag
|
<n-space align="center" :size="8">
|
||||||
role="status"
|
<n-tag
|
||||||
data-testid="display-connection-status"
|
role="status"
|
||||||
:type="host.displays.length ? 'success' : 'error'"
|
data-testid="display-connection-status"
|
||||||
>
|
:type="host.displays.length ? 'success' : 'error'"
|
||||||
{{ host.displays.length ? 'Подключён' : 'Не подключён' }}
|
>
|
||||||
</n-tag>
|
{{ host.displays.length ? 'Подключён' : 'Не подключён' }}
|
||||||
|
</n-tag>
|
||||||
|
<n-button
|
||||||
|
v-if="!state?.outputOpen"
|
||||||
|
size="small"
|
||||||
|
:disabled="display === null || isBusy"
|
||||||
|
@click="run(() => bridge!.show(display!))"
|
||||||
|
>Открыть показ</n-button>
|
||||||
|
<n-button v-else size="small" :disabled="isBusy" @click="run(() => bridge!.closeOutput())"
|
||||||
|
>Закрыть показ</n-button>
|
||||||
|
</n-space>
|
||||||
</template>
|
</template>
|
||||||
<div class="screen-grid">
|
<div class="screen-grid">
|
||||||
<div v-if="state" class="screen-preview">
|
<div v-if="state" class="screen-preview">
|
||||||
@@ -354,15 +364,6 @@ onUnmounted(() => {
|
|||||||
</svg>
|
</svg>
|
||||||
</n-button>
|
</n-button>
|
||||||
</n-space>
|
</n-space>
|
||||||
<div class="output-toggle">
|
|
||||||
<n-button
|
|
||||||
v-if="!state?.outputOpen"
|
|
||||||
:disabled="display === null || isBusy"
|
|
||||||
@click="run(() => bridge!.show(display!))"
|
|
||||||
>Открыть показ</n-button>
|
|
||||||
<n-button v-else :disabled="isBusy" @click="run(() => bridge!.closeOutput())"
|
|
||||||
>Закрыть показ</n-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</n-space>
|
</n-space>
|
||||||
</div>
|
</div>
|
||||||
@@ -373,10 +374,16 @@ onUnmounted(() => {
|
|||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-button
|
<n-button
|
||||||
v-if="!isPlanEditing"
|
v-if="!isPlanEditing"
|
||||||
|
:square="!!state.catalog.steps.length"
|
||||||
|
:aria-label="state.catalog.steps.length ? 'Редактировать' : 'Создать план'"
|
||||||
|
:title="state.catalog.steps.length ? 'Редактировать' : 'Создать план'"
|
||||||
:disabled="isBusy || isPlanSaving || planStatus.key !== state.catalog.key || !planStatus.editable"
|
:disabled="isBusy || isPlanSaving || planStatus.key !== state.catalog.key || !planStatus.editable"
|
||||||
@click="editPlan"
|
@click="editPlan"
|
||||||
>
|
>
|
||||||
{{ state.catalog.steps.length ? 'Редактировать' : 'Создать план' }}
|
<svg v-if="state.catalog.steps.length" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||||
|
<path d="m16 3 5 5M3 21l5-1L21 7a2.8 2.8 0 0 0-4-4L4 16z" />
|
||||||
|
</svg>
|
||||||
|
<span v-else>Создать план</span>
|
||||||
</n-button>
|
</n-button>
|
||||||
<n-space v-else>
|
<n-space v-else>
|
||||||
<n-button
|
<n-button
|
||||||
@@ -523,10 +530,6 @@ onUnmounted(() => {
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.output-toggle {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview {
|
.preview {
|
||||||
background: var(--brand-background);
|
background: var(--brand-background);
|
||||||
display: block;
|
display: block;
|
||||||
|
|||||||
@@ -49,19 +49,22 @@ function run(command: GameCommand) {
|
|||||||
<template #header>
|
<template #header>
|
||||||
<div class="game-heading">
|
<div class="game-heading">
|
||||||
<span>Игра</span>
|
<span>Игра</span>
|
||||||
<n-tag role="status" data-testid="game-state" :type="state.gameError ? 'warning' : status?.type ?? 'default'">
|
<n-tag role="status" data-testid="game-state" :type="state.gameError ? 'warning' : status?.type ?? 'info'">
|
||||||
{{ !selectedKey ? 'Игра не выбрана' : status?.label ?? (!state.authenticated ? 'Требуется вход' : state.gameError ? 'Нет данных' : 'Загрузка…') }}
|
{{ !selectedKey ? 'Игра не выбрана' : status?.label ?? (!state.authenticated ? 'Требуется вход' : state.gameError ? 'Нет данных' : 'Загрузка…') }}
|
||||||
</n-tag>
|
</n-tag>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-tag
|
<n-space align="center" :size="8">
|
||||||
role="status"
|
<n-tag
|
||||||
data-testid="game-connection-status"
|
role="status"
|
||||||
:type="state.connection === 'connected' ? 'success' : 'error'"
|
data-testid="game-connection-status"
|
||||||
>
|
:type="state.connection === 'connected' ? 'success' : 'error'"
|
||||||
{{ state.connection === 'connected' ? 'Подключено' : 'Не подключено' }}
|
>
|
||||||
</n-tag>
|
{{ state.connection === 'connected' ? 'Подключено' : 'Не подключено' }}
|
||||||
|
</n-tag>
|
||||||
|
<slot name="connection-actions" />
|
||||||
|
</n-space>
|
||||||
</template>
|
</template>
|
||||||
<div class="game-grid">
|
<div class="game-grid">
|
||||||
<n-space vertical>
|
<n-space vertical>
|
||||||
|
|||||||
@@ -133,7 +133,11 @@ function remove(trackId?: number) {
|
|||||||
<template>
|
<template>
|
||||||
<n-card title="План музыки" data-testid="music-plan">
|
<n-card title="План музыки" data-testid="music-plan">
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-button v-if="!isEditing" :disabled="isDisabled" @click="edit">Редактировать</n-button>
|
<n-button v-if="!isEditing" square aria-label="Редактировать" title="Редактировать" :disabled="isDisabled" @click="edit">
|
||||||
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||||
|
<path d="m16 3 5 5M3 21l5-1L21 7a2.8 2.8 0 0 0-4-4L4 16z" />
|
||||||
|
</svg>
|
||||||
|
</n-button>
|
||||||
<n-space v-else>
|
<n-space v-else>
|
||||||
<template v-if="isDirty || hasConflict">
|
<template v-if="isDirty || hasConflict">
|
||||||
<n-button
|
<n-button
|
||||||
@@ -380,7 +384,7 @@ function remove(trackId?: number) {
|
|||||||
<span>{{ track.name || `Трек ${index + 1}` }}</span>
|
<span>{{ track.name || `Трек ${index + 1}` }}</span>
|
||||||
<n-button
|
<n-button
|
||||||
data-testid="select-track"
|
data-testid="select-track"
|
||||||
:type="isCurrent(index) ? 'primary' : 'default'"
|
size="small"
|
||||||
:disabled="isBusy || isCurrent(index)"
|
:disabled="isBusy || isCurrent(index)"
|
||||||
@click="emit('command', { action: 'track', channel: 'music', trackIndex: index })"
|
@click="emit('command', { action: 'track', channel: 'music', trackIndex: index })"
|
||||||
>{{ isCurrent(index) ? 'Выбран' : 'Выбрать' }}</n-button
|
>{{ isCurrent(index) ? 'Выбран' : 'Выбрать' }}</n-button
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ function run(intent: OnlineIntent) {
|
|||||||
<template>
|
<template>
|
||||||
<section class="screen-connection" aria-label="Экран игры">
|
<section class="screen-connection" aria-label="Экран игры">
|
||||||
<span>Экран игры</span>
|
<span>Экран игры</span>
|
||||||
<slot />
|
|
||||||
<n-space v-if="state.screenId" align="center">
|
<n-space v-if="state.screenId" align="center">
|
||||||
<span>Экран №{{ state.screenId }}</span>
|
<span>Экран №{{ state.screenId }}</span>
|
||||||
<span role="status" data-testid="sound-assignment">
|
<span role="status" data-testid="sound-assignment">
|
||||||
@@ -25,11 +24,6 @@ function run(intent: OnlineIntent) {
|
|||||||
· Последнее состояние
|
· Последнее состояние
|
||||||
</template>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
<n-button
|
|
||||||
:disabled="isBusy || state.busy"
|
|
||||||
@click="run({ action: 'disconnect' })"
|
|
||||||
>Отключиться</n-button
|
|
||||||
>
|
|
||||||
</n-space>
|
</n-space>
|
||||||
<n-space v-if="state.screenId">
|
<n-space v-if="state.screenId">
|
||||||
<n-button
|
<n-button
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ function timerLabel(index: number) {
|
|||||||
>
|
>
|
||||||
<n-button
|
<n-button
|
||||||
data-testid="show-step"
|
data-testid="show-step"
|
||||||
:type="currentIndex === index ? 'primary' : 'default'"
|
size="small"
|
||||||
:disabled="isBusy || currentIndex === index"
|
:disabled="isBusy || currentIndex === index"
|
||||||
@click="emit('command', { action: 'step', index })"
|
@click="emit('command', { action: 'step', index })"
|
||||||
>{{ currentIndex === index ? 'Показан' : 'Показать' }}</n-button
|
>{{ currentIndex === index ? 'Показан' : 'Показать' }}</n-button
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { GameCommand, GameStatus } from '../types/online.js'
|
import type { GameCommand, GameStatus } from '../types/online.js'
|
||||||
|
|
||||||
export const gameStatuses = {
|
export const gameStatuses = {
|
||||||
draft: { label: 'Черновик', type: 'default' },
|
draft: { label: 'Черновик', type: 'info' },
|
||||||
run: { label: 'Идёт', type: 'success' },
|
run: { label: 'Идёт', type: 'success' },
|
||||||
pause: { label: 'Пауза', type: 'warning' },
|
pause: { label: 'Пауза', type: 'warning' },
|
||||||
finish: { label: 'Завершена', type: 'info' },
|
finish: { label: 'Завершена', type: 'info' },
|
||||||
|
|||||||
Reference in New Issue
Block a user