mirror of
https://github.com/gotson/komga.git
synced 2025-12-26 10:24:04 +01:00
feat(webui): add server port and context path to the server settings screen
Closes: #1264
This commit is contained in:
parent
3f390371f7
commit
4196f08057
3 changed files with 102 additions and 11 deletions
|
|
@ -851,6 +851,7 @@
|
|||
"tab_title": "Server"
|
||||
},
|
||||
"server_settings": {
|
||||
"config_precedence": "Takes precedence over the configuration file",
|
||||
"dialog_regenerate_thumbnails": {
|
||||
"body": "Thumbnails size has changed. Do you want to regenerate book thumbnails?",
|
||||
"btn_alternate": "Yes, all books",
|
||||
|
|
@ -861,6 +862,8 @@
|
|||
"label_delete_empty_collections": "Delete empty collections after scan",
|
||||
"label_delete_empty_readlists": "Delete empty read lists after scan",
|
||||
"label_rememberme_duration": "Remember me duration (in days)",
|
||||
"label_server_context_path": "Base URL",
|
||||
"label_server_port": "Server Port",
|
||||
"label_task_pool_size": "Task threads",
|
||||
"label_thumbnail_size": "Thumbnails size",
|
||||
"requires_restart": "Requires restart to take effect",
|
||||
|
|
@ -917,7 +920,9 @@
|
|||
"users": "Users"
|
||||
},
|
||||
"validation": {
|
||||
"context_path": "Must start with '/', not end with '/-_', and contain only '/-_a-z0-9'",
|
||||
"one_or_more": "Must be 1 or more",
|
||||
"tcp_port": "Must be between 1 and 65535",
|
||||
"zero_or_more": "Must be 0 or more"
|
||||
},
|
||||
"welcome": {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,14 @@ export interface SettingsDto {
|
|||
rememberMeDurationDays: number,
|
||||
thumbnailSize: ThumbnailSizeDto,
|
||||
taskPoolSize: number,
|
||||
serverPort: SettingMultiSource<number>,
|
||||
serverContextPath: SettingMultiSource<string>,
|
||||
}
|
||||
|
||||
export interface SettingMultiSource<T> {
|
||||
configurationSource?: T,
|
||||
databaseSource?: T,
|
||||
effectiveValue?: T,
|
||||
}
|
||||
|
||||
export interface SettingsUpdateDto {
|
||||
|
|
@ -13,6 +21,8 @@ export interface SettingsUpdateDto {
|
|||
renewRememberMeKey?: boolean,
|
||||
thumbnailSize?: ThumbnailSizeDto,
|
||||
taskPoolSize?: number,
|
||||
serverPort?: number,
|
||||
serverContextPath?: string,
|
||||
}
|
||||
|
||||
export enum ThumbnailSizeDto {
|
||||
|
|
|
|||
|
|
@ -53,6 +53,59 @@
|
|||
persistent-hint
|
||||
:hint="$t('server_settings.requires_restart')"
|
||||
/>
|
||||
|
||||
<v-text-field
|
||||
v-model="form.serverPort"
|
||||
@input="$v.form.serverPort.$touch()"
|
||||
@blur="$v.form.serverPort.$touch()"
|
||||
:error-messages="serverPortErrors"
|
||||
:placeholder="existingSettings.serverPort?.configurationSource?.toString()"
|
||||
:persistent-placeholder="!!existingSettings.serverPort?.configurationSource"
|
||||
:hint="$t('server_settings.requires_restart')"
|
||||
persistent-hint
|
||||
clearable
|
||||
:label="$t('server_settings.label_server_port')"
|
||||
type="number"
|
||||
min="1"
|
||||
max="65535"
|
||||
class="mt-4"
|
||||
>
|
||||
<template v-slot:append v-if="!!existingSettings.serverPort?.configurationSource">
|
||||
<v-tooltip bottom>
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-icon v-on="on">
|
||||
mdi-information-outline
|
||||
</v-icon>
|
||||
</template>
|
||||
{{ $t('server_settings.config_precedence') }}
|
||||
</v-tooltip>
|
||||
</template>
|
||||
</v-text-field>
|
||||
|
||||
<v-text-field
|
||||
v-model="form.serverContextPath"
|
||||
@input="$v.form.serverContextPath.$touch()"
|
||||
@blur="$v.form.serverContextPath.$touch()"
|
||||
:error-messages="serverContextPathErrors"
|
||||
:placeholder="existingSettings.serverContextPath?.configurationSource"
|
||||
:persistent-placeholder="!!existingSettings.serverContextPath?.configurationSource"
|
||||
:hint="$t('server_settings.requires_restart')"
|
||||
persistent-hint
|
||||
clearable
|
||||
:label="$t('server_settings.label_server_context_path')"
|
||||
class="mt-4"
|
||||
>
|
||||
<template v-slot:append v-if="!!existingSettings.serverContextPath?.configurationSource">
|
||||
<v-tooltip bottom>
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-icon v-on="on">
|
||||
mdi-information-outline
|
||||
</v-icon>
|
||||
</template>
|
||||
{{ $t('server_settings.config_precedence') }}
|
||||
</v-tooltip>
|
||||
</template>
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
|
|
@ -85,11 +138,13 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {ThumbnailSizeDto} from '@/types/komga-settings'
|
||||
import {SettingsDto, ThumbnailSizeDto} from '@/types/komga-settings'
|
||||
import Vue from 'vue'
|
||||
import {minValue, required} from 'vuelidate/lib/validators'
|
||||
import {helpers, maxValue, minValue, required} from 'vuelidate/lib/validators'
|
||||
import ConfirmationDialog from '@/components/dialogs/ConfirmationDialog.vue'
|
||||
|
||||
const contextPath = helpers.regex('contextPath', /^\/[-a-zA-Z0-9_\/]*[a-zA-Z0-9]$/)
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'ServerSettings',
|
||||
components: {ConfirmationDialog},
|
||||
|
|
@ -100,16 +155,11 @@ export default Vue.extend({
|
|||
rememberMeDurationDays: 365,
|
||||
renewRememberMeKey: false,
|
||||
thumbnailSize: ThumbnailSizeDto.DEFAULT,
|
||||
taskPoolSize: 8,
|
||||
},
|
||||
existingSettings: {
|
||||
deleteEmptyCollections: false,
|
||||
deleteEmptyReadLists: false,
|
||||
rememberMeDurationDays: 365,
|
||||
renewRememberMeKey: false,
|
||||
thumbnailSize: ThumbnailSizeDto.DEFAULT,
|
||||
taskPoolSize: 8,
|
||||
taskPoolSize: 1,
|
||||
serverPort: 25600,
|
||||
serverContextPath: '',
|
||||
},
|
||||
existingSettings: {} as SettingsDto,
|
||||
dialogRegenerateThumbnails: false,
|
||||
}),
|
||||
validations: {
|
||||
|
|
@ -126,6 +176,13 @@ export default Vue.extend({
|
|||
minValue: minValue(1),
|
||||
required,
|
||||
},
|
||||
serverPort: {
|
||||
minValue: minValue(1),
|
||||
maxValue: maxValue(65535),
|
||||
},
|
||||
serverContextPath: {
|
||||
contextPath,
|
||||
},
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
|
@ -152,6 +209,18 @@ export default Vue.extend({
|
|||
!this.$v?.form?.taskPoolSize?.required && errors.push(this.$t('common.required').toString())
|
||||
return errors
|
||||
},
|
||||
serverPortErrors(): string[] {
|
||||
const errors = [] as string[]
|
||||
if (!this.$v.form?.serverPort?.$dirty) return errors;
|
||||
(!this.$v?.form?.serverPort?.minValue || !this.$v?.form?.serverPort?.maxValue) && errors.push(this.$t('validation.tcp_port').toString())
|
||||
return errors
|
||||
},
|
||||
serverContextPathErrors(): string[] {
|
||||
const errors = [] as string[]
|
||||
if (!this.$v.form?.serverContextPath?.$dirty) return errors
|
||||
!this.$v?.form?.serverContextPath?.contextPath && errors.push(this.$t('validation.context_path').toString())
|
||||
return errors
|
||||
},
|
||||
saveDisabled(): boolean {
|
||||
return this.$v.form.$invalid || !this.$v.form.$anyDirty
|
||||
},
|
||||
|
|
@ -163,6 +232,8 @@ export default Vue.extend({
|
|||
async refreshSettings() {
|
||||
const settings = await (this.$komgaSettings.getSettings())
|
||||
this.$_.merge(this.form, settings)
|
||||
this.form.serverPort = settings.serverPort.databaseSource
|
||||
this.form.serverContextPath = settings.serverContextPath.databaseSource
|
||||
this.$_.merge(this.existingSettings, settings)
|
||||
this.$v.form.$reset()
|
||||
},
|
||||
|
|
@ -183,6 +254,11 @@ export default Vue.extend({
|
|||
}
|
||||
if (this.$v.form?.taskPoolSize?.$dirty)
|
||||
this.$_.merge(newSettings, {taskPoolSize: this.form.taskPoolSize})
|
||||
if (this.$v.form?.serverPort?.$dirty)
|
||||
this.$_.merge(newSettings, {serverPort: this.form.serverPort})
|
||||
if (this.$v.form?.serverContextPath?.$dirty)
|
||||
// coerce empty string to null
|
||||
this.$_.merge(newSettings, {serverContextPath: this.form.serverContextPath || null})
|
||||
|
||||
await this.$komgaSettings.updateSettings(newSettings)
|
||||
await this.refreshSettings()
|
||||
|
|
|
|||
Loading…
Reference in a new issue