mirror of
https://github.com/gotson/komga.git
synced 2026-05-06 03:27:08 +02:00
feat(webui): new server management screen with shutdown button
closes #416
This commit is contained in:
parent
8f5ba00f1a
commit
fd81e17ded
6 changed files with 154 additions and 2 deletions
88
komga-webui/src/components/dialogs/ServerStopDialog.vue
Normal file
88
komga-webui/src/components/dialogs/ServerStopDialog.vue
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<v-dialog v-model="modal"
|
||||||
|
max-width="450"
|
||||||
|
>
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>{{ $t('dialog.server_stop.dialog_title') }}</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<v-container fluid>
|
||||||
|
<v-row>
|
||||||
|
<v-col>{{ $t('dialog.server_stop.confirmation_message') }}</v-col>
|
||||||
|
</v-row>
|
||||||
|
</v-container>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer/>
|
||||||
|
<v-btn text @click="dialogCancel">{{ $t('dialog.server_stop.button_cancel') }}</v-btn>
|
||||||
|
<v-btn text color="error" @click="dialogConfirm">{{ $t('dialog.server_stop.button_confirm') }}</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
|
||||||
|
<v-snackbar
|
||||||
|
v-model="snackbar"
|
||||||
|
bottom
|
||||||
|
color="error"
|
||||||
|
>
|
||||||
|
{{ snackText }}
|
||||||
|
<v-btn
|
||||||
|
text
|
||||||
|
@click="snackbar = false"
|
||||||
|
>{{ $t('common.close') }}
|
||||||
|
</v-btn>
|
||||||
|
</v-snackbar>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
name: 'CollectionDeleteDialog',
|
||||||
|
data: () => {
|
||||||
|
return {
|
||||||
|
snackbar: false,
|
||||||
|
snackText: '',
|
||||||
|
modal: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
value: Boolean,
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value(val) {
|
||||||
|
this.modal = val
|
||||||
|
},
|
||||||
|
modal(val) {
|
||||||
|
!val && this.dialogCancel()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
dialogCancel() {
|
||||||
|
this.$emit('input', false)
|
||||||
|
},
|
||||||
|
dialogConfirm() {
|
||||||
|
this.stopServer()
|
||||||
|
this.$emit('input', false)
|
||||||
|
},
|
||||||
|
showSnack(message: string) {
|
||||||
|
this.snackText = message
|
||||||
|
this.snackbar = true
|
||||||
|
},
|
||||||
|
async stopServer() {
|
||||||
|
try {
|
||||||
|
await this.$actuator.shutdown()
|
||||||
|
} catch (e) {
|
||||||
|
this.showSnack(e.message)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -313,6 +313,12 @@
|
||||||
"field_repeat_password": "Repeat new password",
|
"field_repeat_password": "Repeat new password",
|
||||||
"field_repeat_password_error": "Passwords must be identical."
|
"field_repeat_password_error": "Passwords must be identical."
|
||||||
},
|
},
|
||||||
|
"server_stop": {
|
||||||
|
"button_cancel": "Cancel",
|
||||||
|
"button_confirm": "Stop",
|
||||||
|
"confirmation_message": "Are you sure you want to stop Komga?",
|
||||||
|
"dialog_title": "Shutdown server"
|
||||||
|
},
|
||||||
"shortcut_help": {
|
"shortcut_help": {
|
||||||
"label_description": "Description",
|
"label_description": "Description",
|
||||||
"label_key": "Key"
|
"label_key": "Key"
|
||||||
|
|
@ -417,6 +423,13 @@
|
||||||
"searchbox": {
|
"searchbox": {
|
||||||
"no_results": "No results"
|
"no_results": "No results"
|
||||||
},
|
},
|
||||||
|
"server": {
|
||||||
|
"server_management": {
|
||||||
|
"button_shutdown": "Shutdown",
|
||||||
|
"section_title": "Server Management"
|
||||||
|
},
|
||||||
|
"tab_title": "Server"
|
||||||
|
},
|
||||||
"server_settings": {
|
"server_settings": {
|
||||||
"server_settings": "Server Settings"
|
"server_settings": "Server Settings"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,13 @@ const router = new Router({
|
||||||
path: '/settings/analysis',
|
path: '/settings/analysis',
|
||||||
name: 'settings-analysis',
|
name: 'settings-analysis',
|
||||||
beforeEnter: adminGuard,
|
beforeEnter: adminGuard,
|
||||||
component: () => import(/* webpackChunkName: "settings-users" */ './views/SettingsMediaAnalysis.vue'),
|
component: () => import(/* webpackChunkName: "settings-analysis" */ './views/SettingsMediaAnalysis.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/settings/server',
|
||||||
|
name: 'settings-server',
|
||||||
|
beforeEnter: adminGuard,
|
||||||
|
component: () => import(/* webpackChunkName: "settings-server" */ './views/SettingsServer.vue'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { AxiosInstance } from 'axios'
|
import {AxiosInstance} from 'axios'
|
||||||
|
|
||||||
const API_ACTUATOR = '/actuator'
|
const API_ACTUATOR = '/actuator'
|
||||||
|
|
||||||
|
|
@ -20,4 +20,16 @@ export default class ActuatorService {
|
||||||
throw new Error(msg)
|
throw new Error(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async shutdown () {
|
||||||
|
try {
|
||||||
|
await this.http.post(`${API_ACTUATOR}/shutdown`)
|
||||||
|
} catch (e) {
|
||||||
|
let msg = 'An error occurred while trying to shutdown server'
|
||||||
|
if (e.response.data.message) {
|
||||||
|
msg += `: ${e.response.data.message}`
|
||||||
|
}
|
||||||
|
throw new Error(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
<v-tabs>
|
<v-tabs>
|
||||||
<v-tab :to="{name: 'settings-analysis'}">{{ $t('media_analysis.media_analysis') }}</v-tab>
|
<v-tab :to="{name: 'settings-analysis'}">{{ $t('media_analysis.media_analysis') }}</v-tab>
|
||||||
<v-tab :to="{name: 'settings-users'}">{{ $t('users.users') }}</v-tab>
|
<v-tab :to="{name: 'settings-users'}">{{ $t('users.users') }}</v-tab>
|
||||||
|
<v-tab :to="{name: 'settings-server'}">{{ $t('server.tab_title') }}</v-tab>
|
||||||
</v-tabs>
|
</v-tabs>
|
||||||
<router-view/>
|
<router-view/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
32
komga-webui/src/views/SettingsServer.vue
Normal file
32
komga-webui/src/views/SettingsServer.vue
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
<template>
|
||||||
|
<v-container fluid class="pa-6">
|
||||||
|
<v-row>
|
||||||
|
<v-col><span class="text-h5">{{ $t('server.server_management.section_title') }}</span></v-col>
|
||||||
|
</v-row>
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
<v-btn @click="modalStopServer = true"
|
||||||
|
color="error"
|
||||||
|
>{{ $t('server.server_management.button_shutdown') }}</v-btn>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
<server-stop-dialog v-model="modalStopServer"></server-stop-dialog>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue'
|
||||||
|
import ServerStopDialog from "@/components/dialogs/ServerStopDialog.vue";
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
name: 'SettingsServer',
|
||||||
|
components: {ServerStopDialog},
|
||||||
|
data: () => ({
|
||||||
|
modalStopServer: false,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
Loading…
Reference in a new issue