mirror of
https://github.com/gotson/komga.git
synced 2025-12-14 20:43:10 +01:00
stuff for users page
This commit is contained in:
parent
e69ee0aed1
commit
0af88c664c
4 changed files with 120 additions and 4 deletions
|
|
@ -4,6 +4,7 @@ import { releasesHandlers } from '@/mocks/api/handlers/releases'
|
|||
import { HttpResponse } from 'msw'
|
||||
import { librariesHandlers } from '@/mocks/api/handlers/libraries'
|
||||
import { referentialHandlers } from '@/mocks/api/handlers/referential'
|
||||
import { usersHandlers } from '@/mocks/api/handlers/users'
|
||||
|
||||
export const handlers = [
|
||||
...librariesHandlers,
|
||||
|
|
@ -11,6 +12,7 @@ export const handlers = [
|
|||
...actuatorHandlers,
|
||||
...announcementHandlers,
|
||||
...releasesHandlers,
|
||||
...usersHandlers,
|
||||
]
|
||||
|
||||
export const response401Unauthorized = () =>
|
||||
|
|
|
|||
45
next-ui/src/mocks/api/handlers/users.ts
Normal file
45
next-ui/src/mocks/api/handlers/users.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { httpTyped } from '@/mocks/api/httpTyped'
|
||||
|
||||
export const users = [
|
||||
{
|
||||
id: '0JEDA00AV4Z7G',
|
||||
email: 'admin@example.org',
|
||||
roles: ['ADMIN', 'FILE_DOWNLOAD', 'KOBO_SYNC', 'KOREADER_SYNC', 'PAGE_STREAMING', 'USER'],
|
||||
sharedAllLibraries: true,
|
||||
sharedLibrariesIds: [],
|
||||
labelsAllow: [],
|
||||
labelsExclude: [],
|
||||
ageRestriction: null,
|
||||
},
|
||||
{
|
||||
id: '0JEDA00AZ4QXH',
|
||||
email: 'user@example.org',
|
||||
roles: ['KOBO_SYNC', 'PAGE_STREAMING', 'USER'],
|
||||
sharedAllLibraries: true,
|
||||
sharedLibrariesIds: [],
|
||||
labelsAllow: [],
|
||||
labelsExclude: ['book'],
|
||||
ageRestriction: null,
|
||||
},
|
||||
]
|
||||
|
||||
const latestActivity = {
|
||||
userId: '0JEDA00AV4Z7G',
|
||||
email: 'admin@example.org',
|
||||
apiKeyId: null,
|
||||
apiKeyComment: null,
|
||||
ip: '127.0.0.1',
|
||||
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:139.0) Gecko/20100101 Firefox/139.0',
|
||||
success: true,
|
||||
error: null,
|
||||
dateTime: new Date('2025-06-30T06:56:33Z'),
|
||||
source: 'Password',
|
||||
}
|
||||
|
||||
export const usersHandlers = [
|
||||
httpTyped.get('/api/v2/users/me', ({ response }) => response(200).json(users[0])),
|
||||
httpTyped.get('/api/v2/users', ({ response }) => response(200).json(users)),
|
||||
httpTyped.get('/api/v2/users/{userId}/authentication-activity/latest', ({ response }) =>
|
||||
response(200).json(latestActivity),
|
||||
),
|
||||
]
|
||||
44
next-ui/src/pages/server/users.stories.ts
Normal file
44
next-ui/src/pages/server/users.stories.ts
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import type { Meta, StoryObj } from '@storybook/vue3-vite'
|
||||
|
||||
import users from './users.vue'
|
||||
import { http, delay } from 'msw'
|
||||
|
||||
import { response401Unauthorized } from '@/mocks/api/handlers'
|
||||
|
||||
const meta = {
|
||||
component: users,
|
||||
render: (args: object) => ({
|
||||
components: { users },
|
||||
setup() {
|
||||
return { args }
|
||||
},
|
||||
template: '<users />',
|
||||
}),
|
||||
parameters: {
|
||||
// More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
|
||||
},
|
||||
args: {},
|
||||
} satisfies Meta<typeof users>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Default: Story = {
|
||||
args: {},
|
||||
}
|
||||
|
||||
export const Loading: Story = {
|
||||
parameters: {
|
||||
msw: {
|
||||
handlers: [http.all('*', async () => await delay(5_000))],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export const Error: Story = {
|
||||
parameters: {
|
||||
msw: {
|
||||
handlers: [http.all('*', response401Unauthorized)],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -51,27 +51,34 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<template #[`item.activity`]="{ value }">
|
||||
{{ $formatDate(value, { dateStyle: 'medium', timeStyle: 'short' }) }}
|
||||
</template>
|
||||
|
||||
<template #[`item.actions`]="{ item: user }">
|
||||
<div class="d-flex ga-1 justify-end">
|
||||
<v-icon-btn
|
||||
v-tooltip:bottom="'Change password'"
|
||||
v-tooltip:bottom="$formatMessage(messages.changePassword)"
|
||||
icon="i-mdi:lock-reset"
|
||||
@click="showDialog(ACTION.PASSWORD, user)"
|
||||
@mouseenter="dialogConfirmEdit.activator = $event.currentTarget"
|
||||
:aria-label="$formatMessage(messages.changePassword)"
|
||||
/>
|
||||
<v-icon-btn
|
||||
v-tooltip:bottom="'Edit user'"
|
||||
v-tooltip:bottom="$formatMessage(messages.editUser)"
|
||||
icon="i-mdi:pencil"
|
||||
:disabled="me?.id == user.id"
|
||||
@click="showDialog(ACTION.EDIT, user)"
|
||||
@mouseenter="dialogConfirmEdit.activator = $event.currentTarget"
|
||||
:aria-label="$formatMessage(messages.editUser)"
|
||||
/>
|
||||
<v-icon-btn
|
||||
v-tooltip:bottom="'Delete user'"
|
||||
v-tooltip:bottom="$formatMessage(messages.deleteUser)"
|
||||
icon="i-mdi:delete"
|
||||
:disabled="me?.id == user.id"
|
||||
@click="showDialog(ACTION.DELETE, user)"
|
||||
@mouseenter="dialogConfirm.activator = $event.currentTarget"
|
||||
:aria-label="$formatMessage(messages.deleteUser)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -96,7 +103,7 @@ import { commonMessages } from '@/utils/i18n/common-messages'
|
|||
import { storeToRefs } from 'pinia'
|
||||
import { useDialogsStore } from '@/stores/dialogs'
|
||||
import { useMessagesStore } from '@/stores/messages'
|
||||
import { useIntl } from 'vue-intl'
|
||||
import { defineMessage, useIntl } from 'vue-intl'
|
||||
import { useDisplay } from 'vuetify'
|
||||
import UserDeletionWarning from '@/components/user/DeletionWarning.vue'
|
||||
import UserFormCreateEdit from '@/fragments/fragment/user/form/CreateEdit.vue'
|
||||
|
|
@ -348,6 +355,24 @@ function handleDialogConfirmation(
|
|||
setLoading(false)
|
||||
})
|
||||
}
|
||||
|
||||
const messages = {
|
||||
deleteUser: defineMessage({
|
||||
description: 'Tooltip for the delete user button in the users table',
|
||||
defaultMessage: 'Delete user',
|
||||
id: 'r6CqyT',
|
||||
}),
|
||||
editUser: defineMessage({
|
||||
description: 'Tooltip for the edit user button in the users table',
|
||||
defaultMessage: 'Edit user',
|
||||
id: 'K40g4r',
|
||||
}),
|
||||
changePassword: defineMessage({
|
||||
description: 'Tooltip for the change password button in the users table',
|
||||
defaultMessage: 'Change password',
|
||||
id: 'r7xCeA',
|
||||
}),
|
||||
}
|
||||
</script>
|
||||
|
||||
<route lang="yaml">
|
||||
|
|
|
|||
Loading…
Reference in a new issue