mirror of
https://github.com/gotson/komga.git
synced 2025-12-30 04:12:51 +01:00
feat(webui): split account settings into different views
This commit is contained in:
parent
c36e10d93d
commit
169c47e701
7 changed files with 166 additions and 115 deletions
|
|
@ -1,84 +1,89 @@
|
|||
<template>
|
||||
<div style="position: relative">
|
||||
<div v-if="apiKeys.length > 0">
|
||||
<v-list elevation="3"
|
||||
three-line
|
||||
>
|
||||
<div v-for="(apiKey, index) in apiKeys" :key="apiKey.id">
|
||||
<v-list-item>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ apiKey.comment }}</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
{{
|
||||
$t('account_settings.api_key.created_date', {
|
||||
date:
|
||||
new Intl.DateTimeFormat($i18n.locale, {
|
||||
dateStyle: 'medium',
|
||||
timeStyle: 'short'
|
||||
}).format(apiKey.createdDate)
|
||||
})
|
||||
}}
|
||||
</v-list-item-subtitle>
|
||||
<v-list-item-subtitle v-if="apiKeyLastActivity[apiKey.id] !== undefined">
|
||||
{{
|
||||
$t('settings_user.latest_activity', {
|
||||
date:
|
||||
new Intl.DateTimeFormat($i18n.locale, {
|
||||
dateStyle: 'medium',
|
||||
timeStyle: 'short'
|
||||
}).format(apiKeyLastActivity[apiKey.id])
|
||||
})
|
||||
}}
|
||||
</v-list-item-subtitle>
|
||||
<v-list-item-subtitle v-else>{{ $t('settings_user.no_recent_activity') }}</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<div v-if="apiKeys">
|
||||
<div v-if="apiKeys.length > 0">
|
||||
<v-list elevation="3"
|
||||
three-line
|
||||
>
|
||||
<div v-for="(apiKey, index) in apiKeys" :key="apiKey.id">
|
||||
<v-list-item>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ apiKey.comment }}</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
{{
|
||||
$t('account_settings.api_key.created_date', {
|
||||
date:
|
||||
new Intl.DateTimeFormat($i18n.locale, {
|
||||
dateStyle: 'medium',
|
||||
timeStyle: 'short'
|
||||
}).format(apiKey.createdDate)
|
||||
})
|
||||
}}
|
||||
</v-list-item-subtitle>
|
||||
<v-list-item-subtitle v-if="apiKeyLastActivity[apiKey.id] !== undefined">
|
||||
{{
|
||||
$t('settings_user.latest_activity', {
|
||||
date:
|
||||
new Intl.DateTimeFormat($i18n.locale, {
|
||||
dateStyle: 'medium',
|
||||
timeStyle: 'short'
|
||||
}).format(apiKeyLastActivity[apiKey.id])
|
||||
})
|
||||
}}
|
||||
</v-list-item-subtitle>
|
||||
<v-list-item-subtitle v-else>{{ $t('settings_user.no_recent_activity') }}</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
|
||||
<v-list-item-action>
|
||||
<v-tooltip bottom>
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-btn icon @click="promptSyncPointDelete(apiKey)" v-on="on">
|
||||
<v-icon>mdi-book-refresh</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<span>{{ $t('account_settings.api_key.force_kobo_sync') }}</span>
|
||||
</v-tooltip>
|
||||
</v-list-item-action>
|
||||
<v-list-item-action>
|
||||
<v-tooltip bottom>
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-btn icon @click="promptSyncPointDelete(apiKey)" v-on="on">
|
||||
<v-icon>mdi-book-refresh</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<span>{{ $t('account_settings.api_key.force_kobo_sync') }}</span>
|
||||
</v-tooltip>
|
||||
</v-list-item-action>
|
||||
|
||||
<v-list-item-action>
|
||||
<v-btn icon @click="promptDeleteApiKey(apiKey)">
|
||||
<v-icon>mdi-delete</v-icon>
|
||||
<v-list-item-action>
|
||||
<v-btn icon @click="promptDeleteApiKey(apiKey)">
|
||||
<v-icon>mdi-delete</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
|
||||
<v-divider v-if="index !== apiKeys.length-1"/>
|
||||
</div>
|
||||
</v-list>
|
||||
|
||||
<v-btn fab absolute bottom color="primary"
|
||||
:right="!$vuetify.rtl"
|
||||
:left="$vuetify.rtl"
|
||||
class="mx-6"
|
||||
small
|
||||
@click="generateApiKey"
|
||||
>
|
||||
<v-icon>mdi-plus</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<v-container fluid class="pa-0">
|
||||
<v-row>
|
||||
<v-col>{{ $t('account_settings.api_key.no_keys') }}</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-btn color="primary" @click="generateApiKey">{{
|
||||
$t('account_settings.api_key.generate_api_key')
|
||||
}}
|
||||
</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
</v-col>
|
||||
|
||||
<v-divider v-if="index !== apiKeys.length-1"/>
|
||||
</div>
|
||||
</v-list>
|
||||
</v-row>
|
||||
|
||||
<v-btn fab absolute bottom color="primary"
|
||||
:right="!$vuetify.rtl"
|
||||
:left="$vuetify.rtl"
|
||||
class="mx-6"
|
||||
small
|
||||
@click="generateApiKey"
|
||||
>
|
||||
<v-icon>mdi-plus</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<v-container fluid class="pa-0">
|
||||
<v-row>
|
||||
<v-col>{{ $t('account_settings.api_key.no_keys') }}</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-btn color="primary" @click="generateApiKey">{{ $t('account_settings.api_key.generate_api_key') }}</v-btn>
|
||||
</v-col>
|
||||
|
||||
</v-row>
|
||||
|
||||
</v-container>
|
||||
</v-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<confirmation-dialog
|
||||
|
|
@ -120,7 +125,7 @@ export default Vue.extend({
|
|||
components: {ApiKeyAddDialog, ConfirmationDialog},
|
||||
data: () => {
|
||||
return {
|
||||
apiKeys: [] as ApiKeyDto[],
|
||||
apiKeys: undefined as ApiKeyDto[],
|
||||
apiKeyToDelete: {} as ApiKeyDto,
|
||||
apiKeySyncPointsToDelete: {} as ApiKeyDto,
|
||||
modalDeleteApiKey: false,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@
|
|||
"generate_api_key": "Generate API key",
|
||||
"no_keys": "No API Keys created yet"
|
||||
},
|
||||
"change_password": "change password"
|
||||
"change_password": "change password",
|
||||
"details": "Details",
|
||||
"my_account": "My Account"
|
||||
},
|
||||
"announcements": {
|
||||
"mark_all_read": "Mark all as read",
|
||||
|
|
|
|||
|
|
@ -135,11 +135,20 @@ const router = new Router({
|
|||
name: 'history',
|
||||
component: () => import(/* webpackChunkName: "history" */ './views/HistoryView.vue'),
|
||||
},
|
||||
|
||||
{
|
||||
path: '/account',
|
||||
name: 'account',
|
||||
component: () => import(/* webpackChunkName: "account" */ './views/AccountSettings.vue'),
|
||||
path: '/account/me',
|
||||
name: 'account-me',
|
||||
component: () => import(/* webpackChunkName: "account-me" */ './views/AccountView.vue'),
|
||||
},
|
||||
{
|
||||
path: '/account/api-keys',
|
||||
name: 'account-api-keys',
|
||||
component: () => import(/* webpackChunkName: "account-api-keys" */ './views/ApiKeys.vue'),
|
||||
},
|
||||
{
|
||||
path: '/account/authentication-activity',
|
||||
name: 'account-activity',
|
||||
component: () => import(/* webpackChunkName: "account-activity" */ './views/SelfAuthenticationActivity.vue'),
|
||||
},
|
||||
{
|
||||
path: '/libraries/:libraryId?',
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
<template>
|
||||
<v-container fluid class="pa-6">
|
||||
<v-row>
|
||||
<v-col class="text-h5">{{ $t('account_settings.account_settings') }}</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row align="center">
|
||||
<v-col cols="12" md="8" lg="6" xl="4">
|
||||
<span class="text-capitalize">{{ $t('common.email') }}</span>
|
||||
|
|
@ -34,26 +30,6 @@
|
|||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="text-h5">{{ $t('users.api_keys') }}</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" md="10" lg="8" xl="4">
|
||||
<api-key-table/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col class="text-h5">{{ $t('users.authentication_activity') }}</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row>
|
||||
<v-col>
|
||||
<authentication-activity-table for-me/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<password-change-dialog v-model="modalPasswordChange"
|
||||
:user="me"
|
||||
/>
|
||||
|
|
@ -64,13 +40,11 @@
|
|||
<script lang="ts">
|
||||
import PasswordChangeDialog from '@/components/dialogs/PasswordChangeDialog.vue'
|
||||
import Vue from 'vue'
|
||||
import AuthenticationActivityTable from '@/components/AuthenticationActivityTable.vue'
|
||||
import {UserDto} from '@/types/komga-users'
|
||||
import ApiKeyTable from '@/components/ApiKeyTable.vue'
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'AccountSettings',
|
||||
components: {ApiKeyTable, AuthenticationActivityTable, PasswordChangeDialog},
|
||||
components: {PasswordChangeDialog},
|
||||
data: () => {
|
||||
return {
|
||||
modalPasswordChange: false,
|
||||
23
komga-webui/src/views/ApiKeys.vue
Normal file
23
komga-webui/src/views/ApiKeys.vue
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<template>
|
||||
<v-container fluid class="pa-6">
|
||||
<v-row>
|
||||
<v-col cols="12" md="10" lg="8" xl="4">
|
||||
<api-key-table/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import ApiKeyTable from '@/components/ApiKeyTable.vue'
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'ApiKeys',
|
||||
components: {ApiKeyTable},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
|
@ -234,14 +234,27 @@
|
|||
</v-list-item>
|
||||
</v-list-group>
|
||||
|
||||
<v-list-item :to="{name: 'account'}">
|
||||
<v-list-item-action>
|
||||
<v-icon>mdi-account</v-icon>
|
||||
</v-list-item-action>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ $t('account_settings.account_settings') }}</v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<!-- ACCOUNT -->
|
||||
<v-list-group prepend-icon="mdi-account"
|
||||
no-action
|
||||
v-model="expandAccount"
|
||||
>
|
||||
<template v-slot:activator>
|
||||
<v-list-item-title>{{ $t('account_settings.my_account') }}</v-list-item-title>
|
||||
</template>
|
||||
|
||||
<v-list-item :to="{name: 'account-me'}">
|
||||
<v-list-item-title>{{ $t('account_settings.details') }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item :to="{name: 'account-api-keys'}">
|
||||
<v-list-item-title>{{ $t('users.api_keys') }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item :to="{name: 'account-activity'}">
|
||||
<v-list-item-title>{{ $t('users.authentication_activity') }}</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list-group>
|
||||
|
||||
<v-list-item @click="logout">
|
||||
<v-list-item-icon>
|
||||
|
|
@ -332,6 +345,7 @@ export default Vue.extend({
|
|||
expandDuplicatePages: false,
|
||||
expandMediaManagement: false,
|
||||
expandImport: false,
|
||||
expandAccount: false,
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
|
|
@ -416,6 +430,7 @@ export default Vue.extend({
|
|||
this.expandMediaManagement = to.path.includes('/media-management/')
|
||||
this.expandImport = to.path.includes('/import/')
|
||||
this.expandDuplicatePages = to.path.includes('/duplicate-pages/')
|
||||
this.expandAccount = to.path.includes('/account/')
|
||||
},
|
||||
toggleDrawer() {
|
||||
this.drawerVisible = !this.drawerVisible
|
||||
|
|
|
|||
23
komga-webui/src/views/SelfAuthenticationActivity.vue
Normal file
23
komga-webui/src/views/SelfAuthenticationActivity.vue
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<template>
|
||||
<v-container fluid class="pa-6">
|
||||
<v-row>
|
||||
<v-col>
|
||||
<authentication-activity-table for-me/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue'
|
||||
import AuthenticationActivityTable from '@/components/AuthenticationActivityTable.vue'
|
||||
|
||||
export default Vue.extend({
|
||||
name: 'SelfAuthenticationActivity',
|
||||
components: {AuthenticationActivityTable},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Loading…
Reference in a new issue