Refactor page titles and dialog close buttons across multiple views

- Replaced instances of `DialogCloseBtn` with `VDialogCloseBtn` in TransferHistoryView, AccountSettingAbout, AccountSettingSystem, and UserProfileView for consistency.
- Introduced a new component `PageContentTitle` to standardize page titles in SiteCardListView, SubscribeListView, UserListView, and WorkflowListView, improving layout and readability.
- Added keyword filtering functionality in SubscribeListView and SubscribeShareView to enhance user experience during searches.
- Added a new site logo image to the assets.
This commit is contained in:
jxxghp
2025-04-15 13:23:56 +08:00
parent 65ebdb61d0
commit e97d815dc3
63 changed files with 347 additions and 232 deletions

View File

@@ -95,7 +95,7 @@ function onClose() {
<VIcon class="cursor-move" icon="mdi-drag" />
</IconBtn>
</span>
<DialogCloseBtn @click="onClose" />
<VDialogCloseBtn @click="onClose" />
<VCardText class="flex justify-space-between align-center gap-3">
<div class="align-self-start">
<h5 class="text-h6 mb-1">{{ props.rule.name }}</h5>
@@ -106,7 +106,7 @@ function onClose() {
</VCard>
<VDialog v-if="ruleInfoDialog" v-model="ruleInfoDialog" scrollable max-width="40rem" persistent>
<VCard :title="`${props.rule.id} - 配置`" class="rounded-t">
<DialogCloseBtn v-model="ruleInfoDialog" />
<VDialogCloseBtn v-model="ruleInfoDialog" />
<VDivider />
<VCardText>
<VForm>

View File

@@ -175,7 +175,7 @@ watch(
<template>
<VCard variant="tonal" :width="props.width" :height="props.height">
<DialogCloseBtn @click="onClose" />
<VDialogCloseBtn @click="onClose" />
<VCardItem>
<VTextField
v-model="props.directory.name"

View File

@@ -150,7 +150,7 @@ onUnmounted(() => {
@click="openDownloaderInfoDialog"
:class="{ 'transition transform-cpu duration-300 -translate-y-1': hover.isHovering }"
>
<DialogCloseBtn @click="onClose" />
<VDialogCloseBtn @click="onClose" />
<span class="absolute top-3 right-12">
<IconBtn>
<VIcon class="cursor-move" icon="mdi-drag" />
@@ -181,7 +181,7 @@ onUnmounted(() => {
</VHover>
<VDialog v-if="downloaderInfoDialog" v-model="downloaderInfoDialog" scrollable max-width="40rem" persistent>
<VCard :title="`${props.downloader.name} - 配置`" class="rounded-t">
<DialogCloseBtn v-model="downloaderInfoDialog" />
<VDialogCloseBtn v-model="downloaderInfoDialog" />
<VDivider />
<VCardText>
<VForm>

View File

@@ -47,7 +47,7 @@ onMounted(() => {
<VIcon class="cursor-move" icon="mdi-drag" />
</IconBtn>
</span>
<DialogCloseBtn @click="onClose" />
<VDialogCloseBtn @click="onClose" />
<VCardItem>
<VCardTitle>优先级 {{ props.pri }}</VCardTitle>
<VRow>

View File

@@ -208,7 +208,7 @@ function onClose() {
<VIcon class="cursor-move" icon="mdi-drag" />
</IconBtn>
</span>
<DialogCloseBtn @click="onClose" />
<VDialogCloseBtn @click="onClose" />
<VCardText class="flex justify-space-between align-center gap-3">
<div class="align-self-start">
<h5 class="text-h6 mb-1">{{ props.group.name }}</h5>
@@ -222,7 +222,7 @@ function onClose() {
</VCard>
<VDialog v-if="groupInfoDialog" v-model="groupInfoDialog" scrollable max-width="80rem" persistent>
<VCard :title="`${props.group.name} - 配置`" class="rounded-t">
<DialogCloseBtn v-model="groupInfoDialog" />
<VDialogCloseBtn v-model="groupInfoDialog" />
<VDivider />
<VCardItem class="pt-1">
<VRow class="mt-1">

View File

@@ -175,7 +175,7 @@ onMounted(() => {
<template>
<div>
<VCard variant="tonal" @click="openMediaServerInfoDialog">
<DialogCloseBtn @click="onClose" />
<VDialogCloseBtn @click="onClose" />
<VCardText class="flex justify-space-between align-center gap-3">
<div class="align-self-start flex-1">
<div class="text-h6 mb-1">{{ mediaserver.name }}</div>
@@ -190,7 +190,7 @@ onMounted(() => {
</VCard>
<VDialog v-if="mediaServerInfoDialog" v-model="mediaServerInfoDialog" scrollable max-width="40rem" persistent>
<VCard :title="`${props.mediaserver.name} - 配置`" class="rounded-t">
<DialogCloseBtn v-model="mediaServerInfoDialog" />
<VDialogCloseBtn v-model="mediaServerInfoDialog" />
<VDivider />
<VCardText>
<VForm>
@@ -313,19 +313,10 @@ onMounted(() => {
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="mediaServerInfo.config.username"
label="用户名"
active
/>
<VTextField v-model="mediaServerInfo.config.username" label="用户名" active />
</VCol>
<VCol cols="12" md="6">
<VTextField
type="password"
v-model="mediaServerInfo.config.password"
label="密码"
active
/>
<VTextField type="password" v-model="mediaServerInfo.config.password" label="密码" active />
</VCol>
</VRow>
<VRow v-if="mediaServerInfo.type == 'plex'">

View File

@@ -119,7 +119,7 @@ function onClose() {
<VIcon class="cursor-move" icon="mdi-drag" />
</IconBtn>
</span>
<DialogCloseBtn @click="onClose" />
<VDialogCloseBtn @click="onClose" />
<VCardText class="flex justify-space-between align-center gap-3">
<div class="align-self-start">
<div class="flex items-center">
@@ -133,7 +133,7 @@ function onClose() {
</VCard>
<VDialog v-if="notificationInfoDialog" v-model="notificationInfoDialog" scrollable max-width="40rem" persistent>
<VCard :title="`${props.notification.name} - 配置`" class="rounded-t">
<DialogCloseBtn v-model="notificationInfoDialog" />
<VDialogCloseBtn v-model="notificationInfoDialog" />
<VDivider />
<VCardText>
<VForm>

View File

@@ -227,7 +227,7 @@ const dropdownItems = ref([
<!-- 更新日志 -->
<VDialog v-if="releaseDialog" v-model="releaseDialog" width="600" scrollable>
<VCard :title="`${props.plugin?.plugin_name} 更新说明`">
<DialogCloseBtn @click="releaseDialog = false" />
<VDialogCloseBtn @click="releaseDialog = false" />
<VDivider />
<VersionHistory :history="props.plugin?.history" />
</VCard>
@@ -235,7 +235,7 @@ const dropdownItems = ref([
<!-- 插件详情-->
<VDialog v-if="detailDialog" v-model="detailDialog" max-width="30rem">
<VCard>
<DialogCloseBtn @click="detailDialog = false" />
<VDialogCloseBtn @click="detailDialog = false" />
<VCardText>
<VCol>
<div class="d-flex justify-space-between flex-wrap flex-md-nowrap flex-column flex-md-row">

View File

@@ -441,7 +441,7 @@ watch(
<!-- 更新日志 -->
<VDialog v-if="releaseDialog" v-model="releaseDialog" width="600" scrollable>
<VCard :title="`${props.plugin?.plugin_name} 更新说明`">
<DialogCloseBtn @click="releaseDialog = false" />
<VDialogCloseBtn @click="releaseDialog = false" />
<VDivider />
<VersionHistory :history="props.plugin?.history" />
<VDivider />

View File

@@ -1,5 +1,6 @@
<script lang="ts" setup>
import type { PropType } from 'vue'
import noImage from '@images/logos/site.webp'
import { useToast } from 'vue-toast-notification'
import SiteAddEditDialog from '../dialog/SiteAddEditDialog.vue'
import SiteUserDataDialog from '../dialog/SiteUserDataDialog.vue'
@@ -54,6 +55,9 @@ const siteStats = ref<SiteStatistic>({})
async function getSiteIcon() {
try {
siteIcon.value = (await api.get(`site/icon/${cardProps.site?.id}`)).data.icon
if (!siteIcon.value) {
siteIcon.value = noImage
}
} catch (error) {
console.error(error)
}
@@ -212,16 +216,19 @@ onMounted(() => {
<!-- 顶部图标和站点名称 -->
<div class="flex items-center mb-1">
<!-- 站点图标 -->
<div class="site-icon-container mr-2.5" @click.stop="siteEditDialog = true">
<img :src="siteIcon" class="site-icon" :alt="cardProps.site?.name" />
<div class="site-icon-container mr-2.5">
<VImg :src="siteIcon" class="site-icon" :alt="cardProps.site?.name">
<template #placeholder>
<div class="w-full h-full">
<VSkeletonLoader class="object-cover aspect-w-1 aspect-h-1" />
</div>
</template>
</VImg>
<div class="site-icon-edit-overlay">
<VIcon icon="mdi-pencil" color="white" size="16" />
<VIcon icon="mdi-drag" color="white" size="24" class="cursor-move" />
</div>
</div>
<!-- 拖动图标 -->
<VIcon icon="mdi-drag" size="20" class="drag-handle cursor-move opacity-40 mr-1.5 z-10" />
<!-- 站点名称和特性图标 -->
<div class="flex-1 min-w-0 flex items-center">
<h3 class="site-title truncate">{{ cardProps.site?.name }}</h3>
@@ -245,7 +252,7 @@ onMounted(() => {
</div>
<!-- 中间部分网址 -->
<div class="site-meta mb-1.5">
<div class="site-meta my-3">
<div class="site-url truncate" @click.stop="openSitePage">
{{ cardProps.site?.url }}
</div>
@@ -366,7 +373,6 @@ onMounted(() => {
.site-card {
position: relative;
overflow: hidden;
border: 1px solid rgba(var(--v-theme-on-surface), 0.09);
border-radius: 10px;
background: rgba(var(--v-theme-surface), 0.95);
cursor: pointer;
@@ -374,7 +380,7 @@ onMounted(() => {
}
.site-card:hover {
border-color: rgba(var(--v-theme-primary), 0.2);
border: 1px solid rgba(var(--v-theme-primary), 0.2);
box-shadow: 0 3px 12px -6px rgba(0, 0, 0, 10%);
transform: translateY(-4px);
}
@@ -393,7 +399,7 @@ onMounted(() => {
.site-status-indicator {
position: absolute;
z-index: 1;
block-size: 2px;
block-size: 4px;
inset-block-start: 0;
inset-inline: 0;
opacity: 0.5;
@@ -643,7 +649,6 @@ onMounted(() => {
/* 数据统计 */
.site-stats {
margin-block-start: auto;
padding-block-start: 1rem;
}
.site-data-values {

View File

@@ -288,7 +288,6 @@ onUnmounted(() => {
}
.user-card-admin {
border: 2px solid transparent;
background-clip: content-box, border-box;
background-image: linear-gradient(rgb(var(--v-theme-surface)), rgb(var(--v-theme-surface))),
linear-gradient(120deg, rgba(var(--v-theme-warning), 0.5), rgba(var(--v-theme-error), 0.5));
@@ -318,7 +317,7 @@ onUnmounted(() => {
align-items: center;
inset-block-start: 0;
inset-inline: 0;
padding-block: 4px;
padding-block: 8px;
padding-inline: 12px;
}