generated from VLADIMIR/template_frontend
add change status buttons
This commit is contained in:
+113
-66
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+2
-2
@@ -5,8 +5,8 @@
|
|||||||
<link rel="icon" href="/favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Вечерний детектив</title>
|
<title>Вечерний детектив</title>
|
||||||
<script type="module" crossorigin src="/assets/index-CGIEdu3F.js"></script>
|
<script type="module" crossorigin src="/assets/index-Cse9kYPG.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-RcOLieKE.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-DwS7oaRt.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|||||||
+43
-4
@@ -240,6 +240,28 @@ service EveningDetectiveServer {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpc PublicScenario(PublicScenarioReq) returns (PublicScenarioRsp) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
put : "/api/scenarios/{id}/public"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||||
|
tags : "Сценарии";
|
||||||
|
summary: "Опубликовать сценарий";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc DraftScenario(DraftScenarioReq) returns (DraftScenarioRsp) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
put : "/api/scenarios/{id}/draft"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||||
|
tags : "Сценарии";
|
||||||
|
summary: "Снять с публикации сценарий";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
rpc DeleteScenario(DeleteScenarioReq) returns (DeleteScenarioRsp) {
|
rpc DeleteScenario(DeleteScenarioReq) returns (DeleteScenarioRsp) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
delete: "/api/scenarios/{id}"
|
delete: "/api/scenarios/{id}"
|
||||||
@@ -435,10 +457,11 @@ message Scenario {
|
|||||||
optional string description = 3;
|
optional string description = 3;
|
||||||
optional string image = 4;
|
optional string image = 4;
|
||||||
Story story = 5;
|
Story story = 5;
|
||||||
User author = 6;
|
string status = 6;
|
||||||
google.protobuf.Timestamp updated_at = 7;
|
User author = 7;
|
||||||
google.protobuf.Timestamp created_at = 8;
|
google.protobuf.Timestamp updated_at = 8;
|
||||||
google.protobuf.Timestamp published_at = 9;
|
google.protobuf.Timestamp created_at = 9;
|
||||||
|
google.protobuf.Timestamp published_at = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Story {
|
message Story {
|
||||||
@@ -482,6 +505,22 @@ message UpdateScenarioRsp {
|
|||||||
string error = 1;
|
string error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message PublicScenarioReq {
|
||||||
|
int32 id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PublicScenarioRsp {
|
||||||
|
string error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DraftScenarioReq {
|
||||||
|
int32 id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DraftScenarioRsp {
|
||||||
|
string error = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message DeleteScenarioReq {
|
message DeleteScenarioReq {
|
||||||
int32 id = 1;
|
int32 id = 1;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+4
-3
@@ -17,11 +17,12 @@
|
|||||||
--vt-c-text-dark-2: rgb(235 235 235 / 64%);
|
--vt-c-text-dark-2: rgb(235 235 235 / 64%);
|
||||||
|
|
||||||
/* Главный цвет */
|
/* Главный цвет */
|
||||||
--main-color: rgba(34, 50, 60, 1);
|
--main-color: rgb(34 50 60 / 100%);
|
||||||
|
|
||||||
/* --second-color: rgb(97, 74, 22); */
|
/* --second-color: rgb(97, 74, 22); */
|
||||||
--second-color: burlywood;
|
--second-color: burlywood;
|
||||||
--main-back-color: rgba(240, 240, 240, 1);
|
--main-back-color: rgb(240 240 240 / 100%);
|
||||||
--main-back-item-color: rgba(254, 254, 254, 1);
|
--main-back-item-color: rgb(254 254 254 / 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* semantic color variables for this project */
|
/* semantic color variables for this project */
|
||||||
|
|||||||
@@ -96,9 +96,7 @@ const openMenu = ref(false)
|
|||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 70px;
|
height: 70px;
|
||||||
|
|
||||||
background-color: #222;
|
background-color: #222;
|
||||||
|
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
background-image: url("@/assets/images/paper.jpg");
|
background-image: url("@/assets/images/paper.jpg");
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
display: flow-root;
|
display: flow-root;
|
||||||
box-shadow: 0px 0 5px black;
|
box-shadow: 0 0 5px black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-cloud-2,
|
.message-cloud-2,
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { NDynamicInput, NInput, NInputGroup, NSpace, NSwitch, NText, NUpload, NUploadDragger, NButton } from 'naive-ui'
|
import { Key24Regular } from '@vicons/fluent'
|
||||||
import type { PropType } from 'vue'
|
|
||||||
import { LockOutlined } from '@vicons/material'
|
import { LockOutlined } from '@vicons/material'
|
||||||
import { Icon } from '@vicons/utils'
|
import { Icon } from '@vicons/utils'
|
||||||
import { Key24Regular } from '@vicons/fluent'
|
import { NButton,NDynamicInput, NInput, NInputGroup, NSpace, NSwitch, NText, NUpload, NUploadDragger } from 'naive-ui'
|
||||||
|
import type { PropType } from 'vue'
|
||||||
|
|
||||||
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({
|
||||||
@@ -230,6 +231,7 @@ function onCreateKey(): Key {
|
|||||||
.hr {
|
.hr {
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
border: dashed 1px;
|
border: dashed 1px;
|
||||||
|
|
||||||
/* border-color: black; */
|
/* border-color: black; */
|
||||||
border-color: #eee;
|
border-color: #eee;
|
||||||
}
|
}
|
||||||
@@ -304,7 +306,7 @@ function onCreateKey(): Key {
|
|||||||
|
|
||||||
.need-keys-text {
|
.need-keys-text {
|
||||||
color: gold;
|
color: gold;
|
||||||
margin: 15px 0 0 0;
|
margin: 15px 0 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +337,7 @@ function onCreateKey(): Key {
|
|||||||
margin-right: 15px;
|
margin-right: 15px;
|
||||||
background-image: url("@/assets/images/paper_white.jpg");
|
background-image: url("@/assets/images/paper_white.jpg");
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
box-shadow: 0px 3px 15px rgb(98, 98, 98);
|
box-shadow: 0 3px 15px rgb(98 98 98);
|
||||||
transform: rotate(-3deg);
|
transform: rotate(-3deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { Settings } from '@vicons/carbon'
|
import { Settings } from '@vicons/carbon'
|
||||||
import { Icon } from '@vicons/utils'
|
import { Icon } from '@vicons/utils'
|
||||||
import { NButton, type UploadFileInfo, useMessage } from 'naive-ui'
|
import { NButton, type UploadFileInfo, useMessage } from 'naive-ui'
|
||||||
import { NCard, NFlex, NInput, NModal, NSpace, NText, NUpload, NUploadDragger } from 'naive-ui'
|
import { NCard, NFlex, NInput, NModal, NSpace, NText, NUpload, NUploadDragger, NAlert } from 'naive-ui'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
@@ -17,6 +17,7 @@ const route = useRoute()
|
|||||||
const scenarioId = route.params.id
|
const scenarioId = route.params.id
|
||||||
|
|
||||||
const showSettingsScenarioModal = ref(false)
|
const showSettingsScenarioModal = ref(false)
|
||||||
|
const statusScenarioName = ref('')
|
||||||
const deletedScenarioName = ref('')
|
const deletedScenarioName = ref('')
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
@@ -56,6 +57,30 @@ async function deleteScenario(id: number) {
|
|||||||
router.push('/scenarios')
|
router.push('/scenarios')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function publicScenario(id: number) {
|
||||||
|
const res = await client.PublicScenario({ id: id })
|
||||||
|
if (res.error != '') {
|
||||||
|
message.error(res.error!)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await getScenario(Number(scenarioId))
|
||||||
|
statusScenarioName.value = ''
|
||||||
|
showSettingsScenarioModal.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async function draftScenario(id: number) {
|
||||||
|
const res = await client.DraftScenario({ id: id })
|
||||||
|
if (res.error != '') {
|
||||||
|
message.error(res.error!)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await getScenario(Number(scenarioId))
|
||||||
|
statusScenarioName.value = ''
|
||||||
|
showSettingsScenarioModal.value = false
|
||||||
|
}
|
||||||
|
|
||||||
async function uploadFile(file: File | null, filename: string): Promise<string> {
|
async function uploadFile(file: File | null, filename: string): Promise<string> {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return ''
|
return ''
|
||||||
@@ -152,7 +177,7 @@ async function cancelAddPlace() {
|
|||||||
|
|
||||||
async function addNotFoundDoors(scenario: Scenario, place: Place) {
|
async function addNotFoundDoors(scenario: Scenario, place: Place) {
|
||||||
for (const door of place.doors || []) {
|
for (const door of place.doors || []) {
|
||||||
let place = scenario.story?.places?.find((place) => {
|
const place = scenario.story?.places?.find((place) => {
|
||||||
return place.code == door.code
|
return place.code == door.code
|
||||||
})
|
})
|
||||||
if (place == undefined) {
|
if (place == undefined) {
|
||||||
@@ -227,6 +252,11 @@ async function deletePlace(place: Place) {
|
|||||||
<template>
|
<template>
|
||||||
<div class="center-block-custom-big">
|
<div class="center-block-custom-big">
|
||||||
<div class="places-container">
|
<div class="places-container">
|
||||||
|
<n-alert v-if="scenario.status == 'public'" title="Сценарий опубликован" type="warning"
|
||||||
|
style="margin-bottom: 20px;">
|
||||||
|
Не рекомендуется редактировать сценарий когда он опубликован.
|
||||||
|
</n-alert>
|
||||||
|
|
||||||
<div class="settings-block">
|
<div class="settings-block">
|
||||||
Точек: {{ scenario.story?.places?.length }}
|
Точек: {{ scenario.story?.places?.length }}
|
||||||
<n-button quaternary @click="showSettingsScenarioModal = true" class="settings-button">
|
<n-button quaternary @click="showSettingsScenarioModal = true" class="settings-button">
|
||||||
@@ -282,6 +312,25 @@ async function deletePlace(place: Place) {
|
|||||||
|
|
||||||
<n-button @click="updateScenario()" ghost> Сохранить изменения </n-button>
|
<n-button @click="updateScenario()" ghost> Сохранить изменения </n-button>
|
||||||
|
|
||||||
|
<hr class="settings-hr" />
|
||||||
|
<p>Публикация</p>
|
||||||
|
<p>Статус:
|
||||||
|
<span v-if="scenario.status == 'public'">опубликовано</span>
|
||||||
|
<span v-if="scenario.status == 'draft'">в разработке</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Введите название сценария <n-text class="name-text" strong>{{ scenario.name }}</n-text>
|
||||||
|
</p>
|
||||||
|
<n-input v-model:value="statusScenarioName" type="text" placeholder='Дело №0 "Следствие ведут овечки"' />
|
||||||
|
<n-button v-if="scenario.status != 'public'" @click="publicScenario(scenario.id!)" ghost
|
||||||
|
:disabled="statusScenarioName != scenario.name">
|
||||||
|
Опубликовать сценарий
|
||||||
|
</n-button>
|
||||||
|
<n-button v-if="scenario.status != 'draft'" @click="draftScenario(scenario.id!)" ghost
|
||||||
|
:disabled="statusScenarioName != scenario.name">
|
||||||
|
Снять сценарий с публикации
|
||||||
|
</n-button>
|
||||||
|
|
||||||
<hr class="settings-hr" />
|
<hr class="settings-hr" />
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { NButton, NFlex,NSpace, NTag, useMessage } from 'naive-ui'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
import { getAuthClient } from '@/api/auth_client'
|
import { getAuthClient } from '@/api/auth_client'
|
||||||
import type { User } from '@/api/generated/crabs/evening_detective_server'
|
import type { User } from '@/api/generated/crabs/evening_detective_server'
|
||||||
import HeaderMenu from '@/components/HeaderMenu.vue'
|
import HeaderMenu from '@/components/HeaderMenu.vue'
|
||||||
import { useMessage, NTable, NButton, NTag, NSpace, NFlex } from 'naive-ui'
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
const client = getAuthClient()
|
const client = getAuthClient()
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
@@ -86,7 +87,7 @@ async function deleteRole(userId: number, role: string) {
|
|||||||
.user-block {
|
.user-block {
|
||||||
border: 1px solid #444;
|
border: 1px solid #444;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
margin: 0 0 20px 0;
|
margin: 0 0 20px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user