generated from VLADIMIR/template_frontend
update editor
This commit is contained in:
+140
-54
@@ -1,7 +1,9 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { NDynamicInput, NInput, NInputGroup, NSpace, NSwitch } from 'naive-ui'
|
import { NDynamicInput, NInput, NInputGroup, NSpace, NSwitch } from 'naive-ui'
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
|
import { LockOutlined } from '@vicons/material'
|
||||||
|
import { Icon } from '@vicons/utils'
|
||||||
|
import { Key24Regular } from '@vicons/fluent'
|
||||||
import type { Application, Door, Key, Place } from '@/api/generated/crabs/evening_detective_server'
|
import type { Application, Door, Key, Place } from '@/api/generated/crabs/evening_detective_server'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -44,57 +46,66 @@ function onCreateKey(): Key {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div v-if="mode == 'mini-add'" class="place-block-hover show-editor-block" @click="updateMode('add')">
|
||||||
v-if="mode == 'mini-add'"
|
|
||||||
class="place-block-plus show-editor-block"
|
|
||||||
@click="updateMode('edit')"
|
|
||||||
>
|
|
||||||
<p class="place-image-plus">+</p>
|
<p class="place-image-plus">+</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div v-if="mode == 'add'" class="place-block">
|
||||||
v-if="mode == 'show-editor'"
|
<n-space vertical>
|
||||||
class="place-block show-editor-block"
|
<n-input-group>
|
||||||
@click="updateMode('edit')"
|
<n-input :style="{ width: '20%' }" v-model:value="props.place.code" type="text" placeholder="Ы-1" />
|
||||||
>
|
<n-input :style="{ width: '80%' }" v-model:value="props.place.name" type="text" placeholder="Дом №Ы" />
|
||||||
|
</n-input-group>
|
||||||
|
<slot></slot>
|
||||||
|
</n-space>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="mode == 'show-editor'" class="place-block-hover show-editor-block" @click="updateMode('edit')">
|
||||||
<p>[{{ props.place.code }}] - {{ props.place.name }}</p>
|
<p>[{{ props.place.code }}] - {{ props.place.name }}</p>
|
||||||
<div class="message-content">{{ props.place.text }}</div>
|
<div class="message-content">{{ props.place.text }}</div>
|
||||||
<p v-for="application in props.place.applications" v-bind:key="application.name">
|
|
||||||
{{ application.name }}
|
<div v-for="door in props.place.doors" v-bind:key="door.code" class="door-block">
|
||||||
|
{{ door.name }} <span v-for="key in door.keys" class="key-block">
|
||||||
|
<Icon class="lock-icon">
|
||||||
|
<LockOutlined />
|
||||||
|
</Icon> {{ key.name }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-for="application in props.place.applications" v-bind:key="application.name" class="application-block">
|
||||||
|
Приложение: {{ application.name }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="gray-block">
|
||||||
|
<span v-if="place.hidden">
|
||||||
|
Скрытая точка
|
||||||
|
</span>
|
||||||
|
<span v-for="key in place.keys" class="key-block">
|
||||||
|
<Icon class="lock-icon">
|
||||||
|
<Key24Regular />
|
||||||
|
</Icon> {{ key.name }}
|
||||||
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="mode == 'edit'" class="place-block">
|
<div v-if="mode == 'edit'" class="place-block">
|
||||||
<n-space vertical>
|
<n-space vertical>
|
||||||
<n-input-group>
|
<n-input-group>
|
||||||
<n-input
|
<n-input :style="{ width: '20%' }" v-model:value="props.place.code" type="text" placeholder="Ы-1" />
|
||||||
:style="{ width: '20%' }"
|
<n-input :style="{ width: '80%' }" v-model:value="props.place.name" type="text" placeholder="Дом №Ы" />
|
||||||
v-model:value="props.place.code"
|
|
||||||
type="text"
|
|
||||||
placeholder="Ы-1"
|
|
||||||
/>
|
|
||||||
<n-input
|
|
||||||
:style="{ width: '80%' }"
|
|
||||||
v-model:value="props.place.name"
|
|
||||||
type="text"
|
|
||||||
placeholder="Дом №Ы"
|
|
||||||
/>
|
|
||||||
</n-input-group>
|
</n-input-group>
|
||||||
<n-input
|
<n-input v-model:value="props.place.text" type="textarea" :autosize="{ minRows: 3 }"
|
||||||
v-model:value="props.place.text"
|
placeholder="В начале было слово..." />
|
||||||
type="textarea"
|
<n-switch v-model:value="props.place.hidden">
|
||||||
:autosize="{ minRows: 3 }"
|
<template #checked>
|
||||||
placeholder="В начале было слово..."
|
Скрытая точка
|
||||||
/>
|
</template>
|
||||||
<!-- <n-upload multiple directory-dnd :max="1" v-model:file-list="newPlaceFileList">
|
<template #unchecked>
|
||||||
<n-upload-dragger>
|
Обычная точка
|
||||||
<n-text style="font-size: 16px">
|
</template>
|
||||||
Щелкните или перетащите файл в эту область для загрузки
|
</n-switch>
|
||||||
</n-text>
|
|
||||||
</n-upload-dragger>
|
|
||||||
</n-upload> -->
|
|
||||||
<n-switch v-model:value="props.place.hidden" />
|
|
||||||
|
|
||||||
|
Улики
|
||||||
<n-dynamic-input v-model:value="props.place.applications" :on-create="onCreateApplication">
|
<n-dynamic-input v-model:value="props.place.applications" :on-create="onCreateApplication">
|
||||||
<template #create-button-default> Добавить улику </template>
|
<template #create-button-default> Добавить улику </template>
|
||||||
<template #default="{ value }">
|
<template #default="{ value }">
|
||||||
@@ -104,13 +115,26 @@ function onCreateKey(): Key {
|
|||||||
</template>
|
</template>
|
||||||
</n-dynamic-input>
|
</n-dynamic-input>
|
||||||
|
|
||||||
|
Действия
|
||||||
<n-dynamic-input v-model:value="props.place.doors" :on-create="onCreateDoor">
|
<n-dynamic-input v-model:value="props.place.doors" :on-create="onCreateDoor">
|
||||||
<template #create-button-default> Добавить действие </template>
|
<template #create-button-default> Добавить действие </template>
|
||||||
|
<template #action="{ index, create, remove }">
|
||||||
|
<div style="display: flex; flex-direction: column;">
|
||||||
|
<n-button @click="() => create(index)" class="plus-minus-buttons">+</n-button>
|
||||||
|
<n-button disabled @click="() => remove(index)" class="plus-minus-buttons">-</n-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template #default="{ value: door }">
|
<template #default="{ value: door }">
|
||||||
<div style="display: flex; align-items: center; width: 100%">
|
<div style="display: flex; flex-direction: column; width: 100%">
|
||||||
<n-input v-model:value="door.code" type="text" placeholder="Код" />
|
|
||||||
<n-input v-model:value="door.name" type="text" placeholder="Название" />
|
|
||||||
|
|
||||||
|
<div class="door-add-block">
|
||||||
|
<n-input-group>
|
||||||
|
<n-input :style="{ width: '30%' }" v-model:value="door.code" type="text" placeholder="Код" />
|
||||||
|
<n-input :style="{ width: '70%' }" v-model:value="door.name" type="text" placeholder="Название" />
|
||||||
|
</n-input-group>
|
||||||
|
|
||||||
|
<p class="need-keys-text">Требуемые ключи</p>
|
||||||
|
<div class="door-field">
|
||||||
<n-dynamic-input v-model:value="door.keys" :on-create="onCreateKey">
|
<n-dynamic-input v-model:value="door.keys" :on-create="onCreateKey">
|
||||||
<template #create-button-default> Добавить ключ </template>
|
<template #create-button-default> Добавить ключ </template>
|
||||||
<template #default="{ value: key }">
|
<template #default="{ value: key }">
|
||||||
@@ -120,9 +144,13 @@ function onCreateKey(): Key {
|
|||||||
</template>
|
</template>
|
||||||
</n-dynamic-input>
|
</n-dynamic-input>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</n-dynamic-input>
|
</n-dynamic-input>
|
||||||
|
|
||||||
|
Получаемые ключи
|
||||||
<n-dynamic-input v-model:value="props.place.keys" :on-create="onCreateKey">
|
<n-dynamic-input v-model:value="props.place.keys" :on-create="onCreateKey">
|
||||||
<template #create-button-default> Добавить ключ </template>
|
<template #create-button-default> Добавить ключ </template>
|
||||||
<template #default="{ value: key }">
|
<template #default="{ value: key }">
|
||||||
@@ -132,30 +160,23 @@ function onCreateKey(): Key {
|
|||||||
</template>
|
</template>
|
||||||
</n-dynamic-input>
|
</n-dynamic-input>
|
||||||
|
|
||||||
|
<div class="slot-block">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
</div>
|
||||||
</n-space>
|
</n-space>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.place-block-hover,
|
||||||
.place-block {
|
.place-block {
|
||||||
margin: 20px;
|
margin: 10px 5px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 1px solid #444;
|
border: 1px solid #444;
|
||||||
}
|
}
|
||||||
|
|
||||||
.place-block:hover {
|
.place-block-hover:hover {
|
||||||
color: #63e2b7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.place-block-plus {
|
|
||||||
margin: 20px;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: 1px solid #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.place-block-plus:hover {
|
|
||||||
color: #63e2b7;
|
color: #63e2b7;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,4 +194,69 @@ function onCreateKey(): Key {
|
|||||||
.message-content {
|
.message-content {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gray-block {
|
||||||
|
margin-top: 5px;
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.application-block {
|
||||||
|
margin-right: 5px;
|
||||||
|
color: burlywood;
|
||||||
|
}
|
||||||
|
|
||||||
|
.door-block {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 10px 5px 10px 0;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #222;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.door-add-block {
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #222;
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.key-block {
|
||||||
|
color: gold;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lock-icon {
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.door-field {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.need-keys-text {
|
||||||
|
color: gold;
|
||||||
|
margin: 15px 0 0 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slot-block {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plus-minus-buttons {
|
||||||
|
border: 1px solid #444;
|
||||||
|
padding: 0 13px;
|
||||||
|
margin: 0 0 10px 5px;
|
||||||
|
text-align: center;
|
||||||
|
color: #eee;
|
||||||
|
font-size: 25px;
|
||||||
|
border-radius: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plus-minus-buttons:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
color: #63e2b7;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -126,9 +126,37 @@ async function addPlace() {
|
|||||||
applications: undefined,
|
applications: undefined,
|
||||||
doors: undefined,
|
doors: undefined,
|
||||||
keys: undefined,
|
keys: undefined,
|
||||||
|
mode: 'add'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function addNotFoundDoors(scenario: Scenario, place: Place) {
|
||||||
|
place.doors?.forEach(async (door) => {
|
||||||
|
let place = scenario.story?.places?.find((place) => {
|
||||||
|
return place.code == door.code
|
||||||
|
})
|
||||||
|
if (place == undefined) {
|
||||||
|
const res = await client.AddScenarioPlace({
|
||||||
|
id: scenario.id,
|
||||||
|
place: {
|
||||||
|
code: door.code,
|
||||||
|
name: door.name,
|
||||||
|
text: undefined,
|
||||||
|
image: undefined,
|
||||||
|
hidden: undefined,
|
||||||
|
applications: undefined,
|
||||||
|
doors: undefined,
|
||||||
|
keys: undefined
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if (res.error != '') {
|
||||||
|
message.error(res.error!)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async function collapseAddPlace(place: Place) {
|
async function collapseAddPlace(place: Place) {
|
||||||
place.mode = 'mini-add'
|
place.mode = 'mini-add'
|
||||||
}
|
}
|
||||||
@@ -140,6 +168,7 @@ async function cancelUpdatePlace(place: Place) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function updatePlace(place: Place) {
|
async function updatePlace(place: Place) {
|
||||||
|
await addNotFoundDoors(scenario.value, place)
|
||||||
const res = await client.UpdateScenarioPlace({
|
const res = await client.UpdateScenarioPlace({
|
||||||
id: scenario.value.id,
|
id: scenario.value.id,
|
||||||
code: place.oldCode,
|
code: place.oldCode,
|
||||||
@@ -188,12 +217,8 @@ async function deletePlace(place: Place) {
|
|||||||
</n-flex>
|
</n-flex>
|
||||||
</PlaceBlock>
|
</PlaceBlock>
|
||||||
|
|
||||||
<PlaceBlock
|
<PlaceBlock :place="place" v-model:mode="place.mode" v-for="place in scenario.story?.places"
|
||||||
:place="place"
|
v-bind:key="place.code">
|
||||||
v-model:mode="place.mode"
|
|
||||||
v-for="place in scenario.story?.places"
|
|
||||||
v-bind:key="place.code"
|
|
||||||
>
|
|
||||||
<n-flex justify="end">
|
<n-flex justify="end">
|
||||||
<n-button @click="deletePlace(place)" type="error" ghost>Удалить</n-button>
|
<n-button @click="deletePlace(place)" type="error" ghost>Удалить</n-button>
|
||||||
<n-button @click="cancelUpdatePlace(place)">Отмена</n-button>
|
<n-button @click="cancelUpdatePlace(place)">Отмена</n-button>
|
||||||
@@ -205,39 +230,20 @@ async function deletePlace(place: Place) {
|
|||||||
|
|
||||||
<!-- Окно настроек сценария -->
|
<!-- Окно настроек сценария -->
|
||||||
<n-modal v-model:show="showSettingsScenarioModal">
|
<n-modal v-model:show="showSettingsScenarioModal">
|
||||||
<n-card
|
<n-card style="width: 600px" title="Настройки сценария" :bordered="false" size="huge" role="dialog"
|
||||||
style="width: 600px"
|
aria-modal="true">
|
||||||
title="Настройки сценария"
|
|
||||||
:bordered="false"
|
|
||||||
size="huge"
|
|
||||||
role="dialog"
|
|
||||||
aria-modal="true"
|
|
||||||
>
|
|
||||||
<template #header-extra>
|
<template #header-extra>
|
||||||
<n-button @click="showSettingsScenarioModal = false"> x </n-button>
|
<n-button @click="showSettingsScenarioModal = false"> x </n-button>
|
||||||
</template>
|
</template>
|
||||||
<n-space vertical>
|
<n-space vertical>
|
||||||
<p>Название</p>
|
<p>Название</p>
|
||||||
<n-input
|
<n-input v-model:value="scenario.name" type="text" placeholder='Дело №0 "Следствие ведут овечки"' />
|
||||||
v-model:value="scenario.name"
|
|
||||||
type="text"
|
|
||||||
placeholder='Дело №0 "Следствие ведут овечки"'
|
|
||||||
/>
|
|
||||||
|
|
||||||
<p class="settings-header">Описание</p>
|
<p class="settings-header">Описание</p>
|
||||||
<n-input
|
<n-input v-model:value="scenario.description" type="textarea" placeholder="Убийство пастуха..." />
|
||||||
v-model:value="scenario.description"
|
|
||||||
type="textarea"
|
|
||||||
placeholder="Убийство пастуха..."
|
|
||||||
/>
|
|
||||||
|
|
||||||
<p class="settings-header">Картинка</p>
|
<p class="settings-header">Картинка</p>
|
||||||
<n-input
|
<n-input v-model:value="scenario.image" type="text" placeholder="default_scenario.png" disabled />
|
||||||
v-model:value="scenario.image"
|
|
||||||
type="text"
|
|
||||||
placeholder="default_scenario.png"
|
|
||||||
disabled
|
|
||||||
/>
|
|
||||||
<n-upload multiple directory-dnd :max="1" v-model:file-list="fileList">
|
<n-upload multiple directory-dnd :max="1" v-model:file-list="fileList">
|
||||||
<n-upload-dragger>
|
<n-upload-dragger>
|
||||||
<n-text style="font-size: 16px">
|
<n-text style="font-size: 16px">
|
||||||
@@ -254,17 +260,9 @@ async function deletePlace(place: Place) {
|
|||||||
Введите название сценария
|
Введите название сценария
|
||||||
<n-text class="name-text" strong>{{ scenario.name }}</n-text> чтобы удалить его
|
<n-text class="name-text" strong>{{ scenario.name }}</n-text> чтобы удалить его
|
||||||
</p>
|
</p>
|
||||||
<n-input
|
<n-input v-model:value="deletedScenarioName" type="text" placeholder='Дело №0 "Следствие ведут овечки"' />
|
||||||
v-model:value="deletedScenarioName"
|
<n-button @click="deleteScenario(scenario.id!)" type="error" ghost
|
||||||
type="text"
|
:disabled="deletedScenarioName != scenario.name">
|
||||||
placeholder='Дело №0 "Следствие ведут овечки"'
|
|
||||||
/>
|
|
||||||
<n-button
|
|
||||||
@click="deleteScenario(scenario.id!)"
|
|
||||||
type="error"
|
|
||||||
ghost
|
|
||||||
:disabled="deletedScenarioName != scenario.name"
|
|
||||||
>
|
|
||||||
Удалить сценарий
|
Удалить сценарий
|
||||||
</n-button>
|
</n-button>
|
||||||
</n-space>
|
</n-space>
|
||||||
|
|||||||
Reference in New Issue
Block a user