extract announcement card as component

This commit is contained in:
Gauthier Roebroeck 2025-06-26 14:02:08 +08:00
parent 8b997f400b
commit e2ac132fb0
5 changed files with 140 additions and 51 deletions

View file

@ -15,3 +15,7 @@ export default {
},
}
</script>
<style>
@import '../src/styles/global.scss';
</style>

View file

@ -8,6 +8,7 @@ export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
AnnouncementCard: typeof import('./components/announcement/Card.vue')['default']
AppFooter: typeof import('./components/AppFooter.vue')['default']
DialogConfirm: typeof import('./components/dialog/Confirm.vue')['default']
DialogConfirmEdit: typeof import('./components/dialog/ConfirmEdit.vue')['default']

View file

@ -0,0 +1,66 @@
import type { Meta, StoryObj } from '@storybook/vue3-vite'
import Card from './Card.vue'
import { expect, fn } from 'storybook/test'
const meta = {
component: Card,
render: (args: object) => ({
components: { Card },
setup() {
return { args }
},
template: '<Card :item="args.item"/>',
}),
parameters: {
// More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
},
args: {
onMarkRead: fn(),
},
} satisfies Meta<typeof Card>
export default meta
type Story = StoryObj<typeof meta>
export const Unread: Story = {
args: {
item: {
id: 'https://komga.org/blog/ebook-drop2',
url: 'https://komga.org/blog/ebook-drop2',
title: 'eBook drop 2',
summary: 'Version 1.9.0 contains the second feature drop for Ebooks support.',
content_html:
'<p>Version <a href="https://github.com/gotson/komga/releases/tag/1.9.0" target="_blank" rel="noopener noreferrer">1.9.0</a> contains the second feature drop for Ebooks support.</p>\n<p>It brings nice additions to the initial release, most notably the read progress will be kept when reading and restored, same as with other books.</p>\n<p>The analysis process of EPUB files was also revamped, and some EPUB files that were not analyzed before should be working fine now.</p>\n<p>While the first release forced all the EPUB files through the Epub Reader, this release brings back compatibility with the Divina Reader for pre-paginated EPUB files containing only images. This also restores support for the Pages API, and thus the compatibility with Tachiyomi, or any OPDS-PSE client.</p>\n<p>Head over to the <a href="https://github.com/gotson/komga/releases/tag/1.9.0" target="_blank" rel="noopener noreferrer">Release Notes</a> for more details on all the new features and fixes.</p>',
date_modified: new Date('2023-12-15T00:00:00Z'),
author: {
name: 'gotson',
url: 'https://github.com/gotson',
},
tags: ['upgrade', 'komga'],
_komga: {
read: false,
},
},
},
play: async ({ args, canvas, userEvent }) => {
await expect(canvas.getByRole('button')).toBeEnabled()
await userEvent.click(canvas.getByRole('button'))
await expect(args.onMarkRead).toHaveBeenCalledWith(args.item.id)
},
}
export const Read: Story = {
args: {
item: {
...Unread.args?.item,
_komga: {
read: true,
},
},
},
play: async ({ canvas }) => {
await expect(canvas.getByRole('button')).toBeDisabled()
},
}

View file

@ -0,0 +1,64 @@
<template>
<v-card>
<template #title>
<a
:href="item.url"
target="_blank"
class="text-h3 font-weight-medium link-underline"
>{{ item.title }}</a
>
</template>
<template #subtitle>
{{ $formatDate(item.date_modified, { dateStyle: 'long' }) }}
</template>
<template #text>
<!-- eslint-disable vue/no-v-html -->
<div
class="announcement"
v-html="item.content_html"
/>
<!-- eslint-enable vue/no-v-html -->
</template>
<template #actions>
<v-spacer />
<v-btn
:text="
$formatMessage({
description: 'Announcements view: mark as read button tooltip',
defaultMessage: 'Mark as read',
id: 'sUSVQS',
})
"
:disabled="item._komga?.read"
@click="emit('markRead', item.id)"
/>
</template>
</v-card>
</template>
<script setup lang="ts">
import type { components } from '@/generated/openapi/komga'
const { item } = defineProps<{
item: components['schemas']['ItemDto']
}>()
const emit = defineEmits<{
markRead: [id: string]
}>()
</script>
<style lang="scss">
.announcement p {
margin-bottom: 16px;
}
.announcement ul {
padding-left: 24px;
}
.announcement a {
color: var(--v-anchor-base);
}
</style>

View file

@ -16,43 +16,11 @@
v-for="(item, index) in announcements.items"
:key="index"
>
<v-card class="mb-4">
<template #title>
<a
:href="item.url"
target="_blank"
class="text-h3 font-weight-medium link-underline"
>{{ item.title }}</a
>
</template>
<template #subtitle>
{{ $formatDate(item.date_modified, { dateStyle: 'long' }) }}
</template>
<template #text>
<!-- eslint-disable vue/no-v-html -->
<div
class="announcement"
v-html="item.content_html"
/>
<!-- eslint-enable vue/no-v-html -->
</template>
<template #actions>
<v-spacer />
<v-btn
:text="
$formatMessage({
description: 'Announcements view: mark as read button tooltip',
defaultMessage: 'Mark as read',
id: 'sUSVQS',
})
"
:disabled="item._komga?.read"
@click="markRead(item.id)"
/>
</template>
</v-card>
<AnnouncementCard
class="mb-4"
:item="item"
@mark-read="markRead"
/>
<div
v-if="index == announcements.items.length - 1"
@ -105,20 +73,6 @@ function markRead(id: string) {
}
</script>
<style lang="scss">
.announcement p {
margin-bottom: 16px;
}
.announcement ul {
padding-left: 24px;
}
.announcement a {
color: var(--v-anchor-base);
}
</style>
<route lang="yaml">
meta:
requiresRole: ADMIN