mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-06-03 14:50:21 +08:00
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:
1
components.d.ts
vendored
1
components.d.ts
vendored
@@ -12,6 +12,7 @@ declare module 'vue' {
|
|||||||
ExistIcon: typeof import('./src/@core/components/ExistIcon.vue')['default']
|
ExistIcon: typeof import('./src/@core/components/ExistIcon.vue')['default']
|
||||||
LoadingBanner: typeof import('./src/@core/components/LoadingBanner.vue')['default']
|
LoadingBanner: typeof import('./src/@core/components/LoadingBanner.vue')['default']
|
||||||
MoreBtn: typeof import('./src/@core/components/MoreBtn.vue')['default']
|
MoreBtn: typeof import('./src/@core/components/MoreBtn.vue')['default']
|
||||||
|
PageContentTitle: typeof import('./src/@core/components/PageContentTitle.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
ScrollToTopBtn: typeof import('./src/@core/components/ScrollToTopBtn.vue')['default']
|
ScrollToTopBtn: typeof import('./src/@core/components/ScrollToTopBtn.vue')['default']
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ onMounted(() => {
|
|||||||
<VIcon icon="mdi-palette" class="me-2" />
|
<VIcon icon="mdi-palette" class="me-2" />
|
||||||
自定义主题风格
|
自定义主题风格
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<DialogCloseBtn @click="cssDialog = false" />
|
<VDialogCloseBtn @click="cssDialog = false" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VAceEditor
|
<VAceEditor
|
||||||
|
|||||||
BIN
src/assets/images/logos/site.webp
Normal file
BIN
src/assets/images/logos/site.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.6 KiB |
@@ -95,7 +95,7 @@ function onClose() {
|
|||||||
<VIcon class="cursor-move" icon="mdi-drag" />
|
<VIcon class="cursor-move" icon="mdi-drag" />
|
||||||
</IconBtn>
|
</IconBtn>
|
||||||
</span>
|
</span>
|
||||||
<DialogCloseBtn @click="onClose" />
|
<VDialogCloseBtn @click="onClose" />
|
||||||
<VCardText class="flex justify-space-between align-center gap-3">
|
<VCardText class="flex justify-space-between align-center gap-3">
|
||||||
<div class="align-self-start">
|
<div class="align-self-start">
|
||||||
<h5 class="text-h6 mb-1">{{ props.rule.name }}</h5>
|
<h5 class="text-h6 mb-1">{{ props.rule.name }}</h5>
|
||||||
@@ -106,7 +106,7 @@ function onClose() {
|
|||||||
</VCard>
|
</VCard>
|
||||||
<VDialog v-if="ruleInfoDialog" v-model="ruleInfoDialog" scrollable max-width="40rem" persistent>
|
<VDialog v-if="ruleInfoDialog" v-model="ruleInfoDialog" scrollable max-width="40rem" persistent>
|
||||||
<VCard :title="`${props.rule.id} - 配置`" class="rounded-t">
|
<VCard :title="`${props.rule.id} - 配置`" class="rounded-t">
|
||||||
<DialogCloseBtn v-model="ruleInfoDialog" />
|
<VDialogCloseBtn v-model="ruleInfoDialog" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm>
|
<VForm>
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ watch(
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VCard variant="tonal" :width="props.width" :height="props.height">
|
<VCard variant="tonal" :width="props.width" :height="props.height">
|
||||||
<DialogCloseBtn @click="onClose" />
|
<VDialogCloseBtn @click="onClose" />
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VTextField
|
<VTextField
|
||||||
v-model="props.directory.name"
|
v-model="props.directory.name"
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ onUnmounted(() => {
|
|||||||
@click="openDownloaderInfoDialog"
|
@click="openDownloaderInfoDialog"
|
||||||
:class="{ 'transition transform-cpu duration-300 -translate-y-1': hover.isHovering }"
|
:class="{ 'transition transform-cpu duration-300 -translate-y-1': hover.isHovering }"
|
||||||
>
|
>
|
||||||
<DialogCloseBtn @click="onClose" />
|
<VDialogCloseBtn @click="onClose" />
|
||||||
<span class="absolute top-3 right-12">
|
<span class="absolute top-3 right-12">
|
||||||
<IconBtn>
|
<IconBtn>
|
||||||
<VIcon class="cursor-move" icon="mdi-drag" />
|
<VIcon class="cursor-move" icon="mdi-drag" />
|
||||||
@@ -181,7 +181,7 @@ onUnmounted(() => {
|
|||||||
</VHover>
|
</VHover>
|
||||||
<VDialog v-if="downloaderInfoDialog" v-model="downloaderInfoDialog" scrollable max-width="40rem" persistent>
|
<VDialog v-if="downloaderInfoDialog" v-model="downloaderInfoDialog" scrollable max-width="40rem" persistent>
|
||||||
<VCard :title="`${props.downloader.name} - 配置`" class="rounded-t">
|
<VCard :title="`${props.downloader.name} - 配置`" class="rounded-t">
|
||||||
<DialogCloseBtn v-model="downloaderInfoDialog" />
|
<VDialogCloseBtn v-model="downloaderInfoDialog" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm>
|
<VForm>
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ onMounted(() => {
|
|||||||
<VIcon class="cursor-move" icon="mdi-drag" />
|
<VIcon class="cursor-move" icon="mdi-drag" />
|
||||||
</IconBtn>
|
</IconBtn>
|
||||||
</span>
|
</span>
|
||||||
<DialogCloseBtn @click="onClose" />
|
<VDialogCloseBtn @click="onClose" />
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>优先级 {{ props.pri }}</VCardTitle>
|
<VCardTitle>优先级 {{ props.pri }}</VCardTitle>
|
||||||
<VRow>
|
<VRow>
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ function onClose() {
|
|||||||
<VIcon class="cursor-move" icon="mdi-drag" />
|
<VIcon class="cursor-move" icon="mdi-drag" />
|
||||||
</IconBtn>
|
</IconBtn>
|
||||||
</span>
|
</span>
|
||||||
<DialogCloseBtn @click="onClose" />
|
<VDialogCloseBtn @click="onClose" />
|
||||||
<VCardText class="flex justify-space-between align-center gap-3">
|
<VCardText class="flex justify-space-between align-center gap-3">
|
||||||
<div class="align-self-start">
|
<div class="align-self-start">
|
||||||
<h5 class="text-h6 mb-1">{{ props.group.name }}</h5>
|
<h5 class="text-h6 mb-1">{{ props.group.name }}</h5>
|
||||||
@@ -222,7 +222,7 @@ function onClose() {
|
|||||||
</VCard>
|
</VCard>
|
||||||
<VDialog v-if="groupInfoDialog" v-model="groupInfoDialog" scrollable max-width="80rem" persistent>
|
<VDialog v-if="groupInfoDialog" v-model="groupInfoDialog" scrollable max-width="80rem" persistent>
|
||||||
<VCard :title="`${props.group.name} - 配置`" class="rounded-t">
|
<VCard :title="`${props.group.name} - 配置`" class="rounded-t">
|
||||||
<DialogCloseBtn v-model="groupInfoDialog" />
|
<VDialogCloseBtn v-model="groupInfoDialog" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardItem class="pt-1">
|
<VCardItem class="pt-1">
|
||||||
<VRow class="mt-1">
|
<VRow class="mt-1">
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ onMounted(() => {
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<VCard variant="tonal" @click="openMediaServerInfoDialog">
|
<VCard variant="tonal" @click="openMediaServerInfoDialog">
|
||||||
<DialogCloseBtn @click="onClose" />
|
<VDialogCloseBtn @click="onClose" />
|
||||||
<VCardText class="flex justify-space-between align-center gap-3">
|
<VCardText class="flex justify-space-between align-center gap-3">
|
||||||
<div class="align-self-start flex-1">
|
<div class="align-self-start flex-1">
|
||||||
<div class="text-h6 mb-1">{{ mediaserver.name }}</div>
|
<div class="text-h6 mb-1">{{ mediaserver.name }}</div>
|
||||||
@@ -190,7 +190,7 @@ onMounted(() => {
|
|||||||
</VCard>
|
</VCard>
|
||||||
<VDialog v-if="mediaServerInfoDialog" v-model="mediaServerInfoDialog" scrollable max-width="40rem" persistent>
|
<VDialog v-if="mediaServerInfoDialog" v-model="mediaServerInfoDialog" scrollable max-width="40rem" persistent>
|
||||||
<VCard :title="`${props.mediaserver.name} - 配置`" class="rounded-t">
|
<VCard :title="`${props.mediaserver.name} - 配置`" class="rounded-t">
|
||||||
<DialogCloseBtn v-model="mediaServerInfoDialog" />
|
<VDialogCloseBtn v-model="mediaServerInfoDialog" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm>
|
<VForm>
|
||||||
@@ -313,19 +313,10 @@ onMounted(() => {
|
|||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VTextField
|
<VTextField v-model="mediaServerInfo.config.username" label="用户名" active />
|
||||||
v-model="mediaServerInfo.config.username"
|
|
||||||
label="用户名"
|
|
||||||
active
|
|
||||||
/>
|
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VTextField
|
<VTextField type="password" v-model="mediaServerInfo.config.password" label="密码" active />
|
||||||
type="password"
|
|
||||||
v-model="mediaServerInfo.config.password"
|
|
||||||
label="密码"
|
|
||||||
active
|
|
||||||
/>
|
|
||||||
</VCol>
|
</VCol>
|
||||||
</VRow>
|
</VRow>
|
||||||
<VRow v-if="mediaServerInfo.type == 'plex'">
|
<VRow v-if="mediaServerInfo.type == 'plex'">
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ function onClose() {
|
|||||||
<VIcon class="cursor-move" icon="mdi-drag" />
|
<VIcon class="cursor-move" icon="mdi-drag" />
|
||||||
</IconBtn>
|
</IconBtn>
|
||||||
</span>
|
</span>
|
||||||
<DialogCloseBtn @click="onClose" />
|
<VDialogCloseBtn @click="onClose" />
|
||||||
<VCardText class="flex justify-space-between align-center gap-3">
|
<VCardText class="flex justify-space-between align-center gap-3">
|
||||||
<div class="align-self-start">
|
<div class="align-self-start">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
@@ -133,7 +133,7 @@ function onClose() {
|
|||||||
</VCard>
|
</VCard>
|
||||||
<VDialog v-if="notificationInfoDialog" v-model="notificationInfoDialog" scrollable max-width="40rem" persistent>
|
<VDialog v-if="notificationInfoDialog" v-model="notificationInfoDialog" scrollable max-width="40rem" persistent>
|
||||||
<VCard :title="`${props.notification.name} - 配置`" class="rounded-t">
|
<VCard :title="`${props.notification.name} - 配置`" class="rounded-t">
|
||||||
<DialogCloseBtn v-model="notificationInfoDialog" />
|
<VDialogCloseBtn v-model="notificationInfoDialog" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm>
|
<VForm>
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ const dropdownItems = ref([
|
|||||||
<!-- 更新日志 -->
|
<!-- 更新日志 -->
|
||||||
<VDialog v-if="releaseDialog" v-model="releaseDialog" width="600" scrollable>
|
<VDialog v-if="releaseDialog" v-model="releaseDialog" width="600" scrollable>
|
||||||
<VCard :title="`${props.plugin?.plugin_name} 更新说明`">
|
<VCard :title="`${props.plugin?.plugin_name} 更新说明`">
|
||||||
<DialogCloseBtn @click="releaseDialog = false" />
|
<VDialogCloseBtn @click="releaseDialog = false" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VersionHistory :history="props.plugin?.history" />
|
<VersionHistory :history="props.plugin?.history" />
|
||||||
</VCard>
|
</VCard>
|
||||||
@@ -235,7 +235,7 @@ const dropdownItems = ref([
|
|||||||
<!-- 插件详情-->
|
<!-- 插件详情-->
|
||||||
<VDialog v-if="detailDialog" v-model="detailDialog" max-width="30rem">
|
<VDialog v-if="detailDialog" v-model="detailDialog" max-width="30rem">
|
||||||
<VCard>
|
<VCard>
|
||||||
<DialogCloseBtn @click="detailDialog = false" />
|
<VDialogCloseBtn @click="detailDialog = false" />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VCol>
|
<VCol>
|
||||||
<div class="d-flex justify-space-between flex-wrap flex-md-nowrap flex-column flex-md-row">
|
<div class="d-flex justify-space-between flex-wrap flex-md-nowrap flex-column flex-md-row">
|
||||||
|
|||||||
@@ -441,7 +441,7 @@ watch(
|
|||||||
<!-- 更新日志 -->
|
<!-- 更新日志 -->
|
||||||
<VDialog v-if="releaseDialog" v-model="releaseDialog" width="600" scrollable>
|
<VDialog v-if="releaseDialog" v-model="releaseDialog" width="600" scrollable>
|
||||||
<VCard :title="`${props.plugin?.plugin_name} 更新说明`">
|
<VCard :title="`${props.plugin?.plugin_name} 更新说明`">
|
||||||
<DialogCloseBtn @click="releaseDialog = false" />
|
<VDialogCloseBtn @click="releaseDialog = false" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VersionHistory :history="props.plugin?.history" />
|
<VersionHistory :history="props.plugin?.history" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { PropType } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
|
import noImage from '@images/logos/site.webp'
|
||||||
import { useToast } from 'vue-toast-notification'
|
import { useToast } from 'vue-toast-notification'
|
||||||
import SiteAddEditDialog from '../dialog/SiteAddEditDialog.vue'
|
import SiteAddEditDialog from '../dialog/SiteAddEditDialog.vue'
|
||||||
import SiteUserDataDialog from '../dialog/SiteUserDataDialog.vue'
|
import SiteUserDataDialog from '../dialog/SiteUserDataDialog.vue'
|
||||||
@@ -54,6 +55,9 @@ const siteStats = ref<SiteStatistic>({})
|
|||||||
async function getSiteIcon() {
|
async function getSiteIcon() {
|
||||||
try {
|
try {
|
||||||
siteIcon.value = (await api.get(`site/icon/${cardProps.site?.id}`)).data.icon
|
siteIcon.value = (await api.get(`site/icon/${cardProps.site?.id}`)).data.icon
|
||||||
|
if (!siteIcon.value) {
|
||||||
|
siteIcon.value = noImage
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
@@ -212,16 +216,19 @@ onMounted(() => {
|
|||||||
<!-- 顶部:图标和站点名称 -->
|
<!-- 顶部:图标和站点名称 -->
|
||||||
<div class="flex items-center mb-1">
|
<div class="flex items-center mb-1">
|
||||||
<!-- 站点图标 -->
|
<!-- 站点图标 -->
|
||||||
<div class="site-icon-container mr-2.5" @click.stop="siteEditDialog = true">
|
<div class="site-icon-container mr-2.5">
|
||||||
<img :src="siteIcon" class="site-icon" :alt="cardProps.site?.name" />
|
<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">
|
<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>
|
||||||
</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">
|
<div class="flex-1 min-w-0 flex items-center">
|
||||||
<h3 class="site-title truncate">{{ cardProps.site?.name }}</h3>
|
<h3 class="site-title truncate">{{ cardProps.site?.name }}</h3>
|
||||||
@@ -245,7 +252,7 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 中间部分:网址 -->
|
<!-- 中间部分:网址 -->
|
||||||
<div class="site-meta mb-1.5">
|
<div class="site-meta my-3">
|
||||||
<div class="site-url truncate" @click.stop="openSitePage">
|
<div class="site-url truncate" @click.stop="openSitePage">
|
||||||
{{ cardProps.site?.url }}
|
{{ cardProps.site?.url }}
|
||||||
</div>
|
</div>
|
||||||
@@ -366,7 +373,6 @@ onMounted(() => {
|
|||||||
.site-card {
|
.site-card {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: 1px solid rgba(var(--v-theme-on-surface), 0.09);
|
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: rgba(var(--v-theme-surface), 0.95);
|
background: rgba(var(--v-theme-surface), 0.95);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@@ -374,7 +380,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.site-card:hover {
|
.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%);
|
box-shadow: 0 3px 12px -6px rgba(0, 0, 0, 10%);
|
||||||
transform: translateY(-4px);
|
transform: translateY(-4px);
|
||||||
}
|
}
|
||||||
@@ -393,7 +399,7 @@ onMounted(() => {
|
|||||||
.site-status-indicator {
|
.site-status-indicator {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
block-size: 2px;
|
block-size: 4px;
|
||||||
inset-block-start: 0;
|
inset-block-start: 0;
|
||||||
inset-inline: 0;
|
inset-inline: 0;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
@@ -643,7 +649,6 @@ onMounted(() => {
|
|||||||
/* 数据统计 */
|
/* 数据统计 */
|
||||||
.site-stats {
|
.site-stats {
|
||||||
margin-block-start: auto;
|
margin-block-start: auto;
|
||||||
padding-block-start: 1rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-data-values {
|
.site-data-values {
|
||||||
|
|||||||
@@ -288,7 +288,6 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.user-card-admin {
|
.user-card-admin {
|
||||||
border: 2px solid transparent;
|
|
||||||
background-clip: content-box, border-box;
|
background-clip: content-box, border-box;
|
||||||
background-image: linear-gradient(rgb(var(--v-theme-surface)), rgb(var(--v-theme-surface))),
|
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));
|
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;
|
align-items: center;
|
||||||
inset-block-start: 0;
|
inset-block-start: 0;
|
||||||
inset-inline: 0;
|
inset-inline: 0;
|
||||||
padding-block: 4px;
|
padding-block: 8px;
|
||||||
padding-inline: 12px;
|
padding-inline: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ onMounted(() => {
|
|||||||
<span v-if="title">{{ torrent?.site_name }} - {{ title }}</span>
|
<span v-if="title">{{ torrent?.site_name }} - {{ title }}</span>
|
||||||
<span v-else>确认下载</span>
|
<span v-else>确认下载</span>
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VList lines="one">
|
<VList lines="one">
|
||||||
<VListItem>
|
<VListItem>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ async function savaAlistConfig() {
|
|||||||
<template>
|
<template>
|
||||||
<VDialog width="50rem" scrollable max-height="85vh">
|
<VDialog width="50rem" scrollable max-height="85vh">
|
||||||
<VCard title="AList配置" class="rounded-t">
|
<VCard title="AList配置" class="rounded-t">
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VRow>
|
<VRow>
|
||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ onUnmounted(() => {
|
|||||||
<template>
|
<template>
|
||||||
<VDialog width="40rem" scrollable max-height="85vh">
|
<VDialog width="40rem" scrollable max-height="85vh">
|
||||||
<VCard title="阿里云盘登录" class="rounded-t">
|
<VCard title="阿里云盘登录" class="rounded-t">
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VCardText class="pt-2 flex flex-col items-center">
|
<VCardText class="pt-2 flex flex-col items-center">
|
||||||
<div class="my-6 shadow-lg rounded text-center p-3 border">
|
<div class="my-6 shadow-lg rounded text-center p-3 border">
|
||||||
<VImg class="mx-auto" :src="qrCodeUrl" width="200" height="200">
|
<VImg class="mx-auto" :src="qrCodeUrl" width="200" height="200">
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ onMounted(() => {
|
|||||||
<template>
|
<template>
|
||||||
<VDialog max-width="40rem" scrollable>
|
<VDialog max-width="40rem" scrollable>
|
||||||
<VCard>
|
<VCard>
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VCol>
|
<VCol>
|
||||||
<div class="d-flex justify-space-between flex-wrap flex-md-nowrap flex-column flex-md-row">
|
<div class="d-flex justify-space-between flex-wrap flex-md-nowrap flex-column flex-md-row">
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ function handleImport() {
|
|||||||
<template>
|
<template>
|
||||||
<VDialog width="40rem" scrollable max-height="85vh" persistent>
|
<VDialog width="40rem" scrollable max-height="85vh" persistent>
|
||||||
<VCard :title="props.title" class="rounded-t">
|
<VCard :title="props.title" class="rounded-t">
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VCardText class="pt-2">
|
<VCardText class="pt-2">
|
||||||
<VTextarea v-model="codeString" />
|
<VTextarea v-model="codeString" />
|
||||||
</VCardText>
|
</VCardText>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const emit = defineEmits(['close'])
|
|||||||
<template>
|
<template>
|
||||||
<VDialog max-width="50rem">
|
<VDialog max-width="50rem">
|
||||||
<VCard>
|
<VCard>
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<MediaInfoCard :context="context" />
|
<MediaInfoCard :context="context" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ onBeforeMount(async () => {
|
|||||||
<template>
|
<template>
|
||||||
<VDialog scrollable max-width="60rem" :fullscreen="!display.mdAndUp.value">
|
<VDialog scrollable max-width="60rem" :fullscreen="!display.mdAndUp.value">
|
||||||
<VCard :title="`${props.plugin?.plugin_name} - 配置`" class="rounded-t">
|
<VCard :title="`${props.plugin?.plugin_name} - 配置`" class="rounded-t">
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText v-if="isRefreshed">
|
<VCardText v-if="isRefreshed">
|
||||||
<FormRender v-for="(item, index) in pluginFormItems" :key="index" :config="item" :model="pluginConfigForm" />
|
<FormRender v-for="(item, index) in pluginFormItems" :key="index" :config="item" :model="pluginConfigForm" />
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ onMounted(() => {
|
|||||||
<template>
|
<template>
|
||||||
<VDialog scrollable max-width="80rem" :fullscreen="!display.mdAndUp.value">
|
<VDialog scrollable max-width="80rem" :fullscreen="!display.mdAndUp.value">
|
||||||
<VCard :title="`${props.plugin?.plugin_name}`" class="rounded-t">
|
<VCard :title="`${props.plugin?.plugin_name}`" class="rounded-t">
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<LoadingBanner v-if="!isRefreshed" class="mt-5" />
|
<LoadingBanner v-if="!isRefreshed" class="mt-5" />
|
||||||
<VCardText v-else class="min-h-40">
|
<VCardText v-else class="min-h-40">
|
||||||
<PageRender @action="loadPluginPage" v-for="(item, index) in pluginPageItems" :key="index" :config="item" />
|
<PageRender @action="loadPluginPage" v-for="(item, index) in pluginPageItems" :key="index" :config="item" />
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ onMounted(() => {
|
|||||||
<VIcon icon="mdi-store-cog" class="me-2" />
|
<VIcon icon="mdi-store-cog" class="me-2" />
|
||||||
插件仓库设置
|
插件仓库设置
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText class="pt-2">
|
<VCardText class="pt-2">
|
||||||
<VTextarea
|
<VTextarea
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ async function savaRcloneConfig() {
|
|||||||
<template>
|
<template>
|
||||||
<VDialog width="50rem" scrollable max-height="85vh">
|
<VDialog width="50rem" scrollable max-height="85vh">
|
||||||
<VCard title="RClone配置" class="rounded-t">
|
<VCard title="RClone配置" class="rounded-t">
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VRow>
|
<VRow>
|
||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ onUnmounted(() => {
|
|||||||
<template>
|
<template>
|
||||||
<VDialog scrollable max-width="45rem" :fullscreen="!display.mdAndUp.value">
|
<VDialog scrollable max-width="45rem" :fullscreen="!display.mdAndUp.value">
|
||||||
<VCard :title="dialogTitle" class="rounded-t">
|
<VCard :title="dialogTitle" class="rounded-t">
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ onMounted(async () => {
|
|||||||
:title="`${props.oper === 'add' ? '新增' : '编辑'}站点${props.oper !== 'add' ? ` - ${siteForm.name}` : ''}`"
|
:title="`${props.oper === 'add' ? '新增' : '编辑'}站点${props.oper !== 'add' ? ` - ${siteForm.name}` : ''}`"
|
||||||
class="rounded-t"
|
class="rounded-t"
|
||||||
>
|
>
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ async function updateSiteCookie() {
|
|||||||
<VDialog max-width="30rem">
|
<VDialog max-width="30rem">
|
||||||
<!-- Dialog Content -->
|
<!-- Dialog Content -->
|
||||||
<VCard title="更新站点Cookie & UA">
|
<VCard title="更新站点Cookie & UA">
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ onBeforeMount(async () => {
|
|||||||
>{{ `数据 - ${props.site?.name}` }}
|
>{{ `数据 - ${props.site?.name}` }}
|
||||||
<IconBtn @click.stop="refreshSiteData" color="info"><VIcon icon="mdi-refresh" /></IconBtn>
|
<IconBtn @click.stop="refreshSiteData" color="info"><VIcon icon="mdi-refresh" /></IconBtn>
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText class="pt-5">
|
<VCardText class="pt-5">
|
||||||
|
|||||||
@@ -370,7 +370,7 @@ onMounted(() => {
|
|||||||
class="rounded-t"
|
class="rounded-t"
|
||||||
>
|
>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<VTabs v-model="activeTab" show-arrows>
|
<VTabs v-model="activeTab" show-arrows>
|
||||||
<VTab value="basic">
|
<VTab value="basic">
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ onBeforeMount(() => {
|
|||||||
<VDialog scrollable max-width="80rem" :fullscreen="!display.mdAndUp.value">
|
<VDialog scrollable max-width="80rem" :fullscreen="!display.mdAndUp.value">
|
||||||
<VCard class="rounded-t">
|
<VCard class="rounded-t">
|
||||||
<VCardItem class="my-2">
|
<VCardItem class="my-2">
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<div class="media-page">
|
<div class="media-page">
|
||||||
@@ -237,7 +237,7 @@ onBeforeMount(() => {
|
|||||||
.media-overview {
|
.media-overview {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding-block: 1rem 1rem;
|
padding-block: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (width >= 1024px) {
|
@media (width >= 1024px) {
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ const dropdownItems = ref([
|
|||||||
<VCardTitle>{{ props.type + '订阅历史' }}</VCardTitle>
|
<VCardTitle>{{ props.type + '订阅历史' }}</VCardTitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VList lines="two">
|
<VList lines="two">
|
||||||
<VInfiniteScroll mode="intersect" side="end" :items="historyList" class="overflow-hidden" @load="loadHistory">
|
<VInfiniteScroll mode="intersect" side="end" :items="historyList" class="overflow-hidden" @load="loadHistory">
|
||||||
<template #loading>
|
<template #loading>
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ onMounted(async () => {
|
|||||||
<template>
|
<template>
|
||||||
<VBottomSheet inset scrollable>
|
<VBottomSheet inset scrollable>
|
||||||
<VCard class="rounded-t">
|
<VCard class="rounded-t">
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle class="pe-10"> 订阅 - {{ props.media?.title }} </VCardTitle>
|
<VCardTitle class="pe-10"> 订阅 - {{ props.media?.title }} </VCardTitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ const $toast = useToast()
|
|||||||
class="rounded-t"
|
class="rounded-t"
|
||||||
>
|
>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VForm @submit.prevent="() => {}" class="pt-2">
|
<VForm @submit.prevent="() => {}" class="pt-2">
|
||||||
<VRow>
|
<VRow>
|
||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ onUnmounted(() => {
|
|||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle>整理队列</VCardTitle>
|
<VCardTitle>整理队列</VCardTitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VProgressLinear
|
<VProgressLinear
|
||||||
v-if="dataList.length > 0 && progressValue > 0"
|
v-if="dataList.length > 0 && progressValue > 0"
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ onUnmounted(() => {
|
|||||||
<template>
|
<template>
|
||||||
<VDialog width="40rem" scrollable max-height="85vh">
|
<VDialog width="40rem" scrollable max-height="85vh">
|
||||||
<VCard title="115网盘登录" class="rounded-t">
|
<VCard title="115网盘登录" class="rounded-t">
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VCardText class="pt-2 flex flex-col items-center">
|
<VCardText class="pt-2 flex flex-col items-center">
|
||||||
<div class="my-6 shadow-lg rounded text-center p-3 border">
|
<div class="my-6 shadow-lg rounded text-center p-3 border">
|
||||||
<QrcodeVue class="mx-auto" :value="qrCodeContent" :size="200" />
|
<QrcodeVue class="mx-auto" :value="qrCodeContent" :size="200" />
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ onMounted(() => {
|
|||||||
:title="`${props.oper === 'add' ? '新增' : '编辑'}用户${props.oper !== 'add' ? ` - ${userName}` : ''}`"
|
:title="`${props.oper === 'add' ? '新增' : '编辑'}用户${props.oper !== 'add' ? ` - ${userName}` : ''}`"
|
||||||
class="rounded-t"
|
class="rounded-t"
|
||||||
>
|
>
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<!-- 👉 Avatar -->
|
<!-- 👉 Avatar -->
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ onMounted(async () => {
|
|||||||
<template>
|
<template>
|
||||||
<VDialog width="40rem" max-height="85vh">
|
<VDialog width="40rem" max-height="85vh">
|
||||||
<VCard title="用户认证" class="rounded-t">
|
<VCard title="用户认证" class="rounded-t">
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VRow>
|
<VRow>
|
||||||
<VCol cols="12">
|
<VCol cols="12">
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ async function editWorkflow() {
|
|||||||
<template>
|
<template>
|
||||||
<VDialog scrollable :close-on-back="false" eager max-width="30rem" :fullscreen="!display.mdAndUp.value">
|
<VDialog scrollable :close-on-back="false" eager max-width="30rem" :fullscreen="!display.mdAndUp.value">
|
||||||
<VCard :title="`${title}任务`" class="rounded-t">
|
<VCard :title="`${title}任务`" class="rounded-t">
|
||||||
<DialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
|
|||||||
@@ -688,7 +688,7 @@ onMounted(() => {
|
|||||||
<!-- 重命名弹窗 -->
|
<!-- 重命名弹窗 -->
|
||||||
<VDialog v-if="renamePopper" v-model="renamePopper" max-width="35rem">
|
<VDialog v-if="renamePopper" v-model="renamePopper" max-width="35rem">
|
||||||
<VCard title="重命名">
|
<VCard title="重命名">
|
||||||
<DialogCloseBtn @click="renamePopper = false" />
|
<VDialogCloseBtn @click="renamePopper = false" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VRow>
|
<VRow>
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ const sortIcon = computed(() => {
|
|||||||
</IconBtn>
|
</IconBtn>
|
||||||
</template>
|
</template>
|
||||||
<VCard title="新建文件夹">
|
<VCard title="新建文件夹">
|
||||||
<DialogCloseBtn @click="newFolderPopper = false" />
|
<VDialogCloseBtn @click="newFolderPopper = false" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VTextField v-model="newFolderName" label="名称" />
|
<VTextField v-model="newFolderName" label="名称" />
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ onMounted(() => {
|
|||||||
@keydown.enter="searchMedias"
|
@keydown.enter="searchMedias"
|
||||||
/>
|
/>
|
||||||
</VToolbar>
|
</VToolbar>
|
||||||
<DialogCloseBtn
|
<VDialogCloseBtn
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
emit('close')
|
emit('close')
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ onUnmounted(() => {
|
|||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
background-color: rgba(var(--v-theme-background), 0.8);
|
background-color: rgba(var(--v-theme-background), 0.8);
|
||||||
border-block-end: 1px solid rgba(var(--v-theme-on-surface), 0.05);
|
border-block-end: 1px solid rgba(var(--v-theme-on-surface), 0.05);
|
||||||
gap: 16px; // 为按钮留出空间
|
|
||||||
inset-block-start: 0;
|
inset-block-start: 0;
|
||||||
margin-block-end: 16px;
|
margin-block-end: 16px;
|
||||||
padding-block: 8px;
|
padding-block: 8px;
|
||||||
|
|||||||
18
src/layouts/components/PageContentTitle.vue
Normal file
18
src/layouts/components/PageContentTitle.vue
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
defineProps({
|
||||||
|
// 标题
|
||||||
|
title: String,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div v-if="title" class="my-3 md:flex md:items-center md:justify-between">
|
||||||
|
<div class="min-w-0 flex-1 mx-0">
|
||||||
|
<h2
|
||||||
|
class="ms-1 truncate text-2xl font-bold leading-7 text-gray-100 sm:overflow-visible sm:text-3xl sm:leading-9 md:mb-0"
|
||||||
|
data-testid="page-header"
|
||||||
|
>
|
||||||
|
<span class="text-moviepilot">{{ title }}</span>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -210,7 +210,7 @@ onMounted(() => {
|
|||||||
<VIcon icon="mdi-text-recognition" class="me-2" />
|
<VIcon icon="mdi-text-recognition" class="me-2" />
|
||||||
名称识别测试
|
名称识别测试
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<DialogCloseBtn @click="nameTestDialog = false" />
|
<VDialogCloseBtn @click="nameTestDialog = false" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
@@ -226,7 +226,7 @@ onMounted(() => {
|
|||||||
<VIcon icon="mdi-network" class="me-2" />
|
<VIcon icon="mdi-network" class="me-2" />
|
||||||
网速连通性测试
|
网速连通性测试
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<DialogCloseBtn @click="netTestDialog = false" />
|
<VDialogCloseBtn @click="netTestDialog = false" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
@@ -243,7 +243,7 @@ onMounted(() => {
|
|||||||
:fullscreen="!display.mdAndUp.value"
|
:fullscreen="!display.mdAndUp.value"
|
||||||
>
|
>
|
||||||
<VCard>
|
<VCard>
|
||||||
<DialogCloseBtn @click="loggingDialog = false" />
|
<VDialogCloseBtn @click="loggingDialog = false" />
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<VCardTitle class="inline-flex">
|
<VCardTitle class="inline-flex">
|
||||||
<VIcon icon="mdi-file-document" class="me-2" />
|
<VIcon icon="mdi-file-document" class="me-2" />
|
||||||
@@ -272,7 +272,7 @@ onMounted(() => {
|
|||||||
<VIcon icon="mdi-filter-cog" class="me-2" />
|
<VIcon icon="mdi-filter-cog" class="me-2" />
|
||||||
规则测试
|
规则测试
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<DialogCloseBtn @click="ruleTestDialog = false" />
|
<VDialogCloseBtn @click="ruleTestDialog = false" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
@@ -288,7 +288,7 @@ onMounted(() => {
|
|||||||
<VIcon icon="mdi-cog" class="me-2" />
|
<VIcon icon="mdi-cog" class="me-2" />
|
||||||
系统健康检查
|
系统健康检查
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<DialogCloseBtn @click="systemTestDialog = false" />
|
<VDialogCloseBtn @click="systemTestDialog = false" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
@@ -310,7 +310,7 @@ onMounted(() => {
|
|||||||
<VIcon icon="mdi-message" class="me-2" />
|
<VIcon icon="mdi-message" class="me-2" />
|
||||||
消息中心
|
消息中心
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<DialogCloseBtn @click="messageDialog = false" />
|
<VDialogCloseBtn @click="messageDialog = false" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText ref="chatContainer">
|
<VCardText ref="chatContainer">
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ const userLevel = computed(() => userStore.level)
|
|||||||
<VBtn variant="elevated" color="error" @click="restart" prepend-icon="mdi-restart" class="px-5"> 确定 </VBtn>
|
<VBtn variant="elevated" color="error" @click="restart" prepend-icon="mdi-restart" class="px-5"> 确定 </VBtn>
|
||||||
<VBtn variant="tonal" color="secondary" class="px-5" @click="restartDialog = false">取消</VBtn>
|
<VBtn variant="tonal" color="secondary" class="px-5" @click="restartDialog = false">取消</VBtn>
|
||||||
</VCardActions>
|
</VCardActions>
|
||||||
<DialogCloseBtn @click="restartDialog = false" />
|
<VDialogCloseBtn @click="restartDialog = false" />
|
||||||
</VCard>
|
</VCard>
|
||||||
</VDialog>
|
</VDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import MediaIdSelector from './components/misc/MediaIdSelector.vue'
|
|||||||
import CronField from './components/field/CronField.vue'
|
import CronField from './components/field/CronField.vue'
|
||||||
import PathField from './components/field/PathField.vue'
|
import PathField from './components/field/PathField.vue'
|
||||||
import HeaderTab from './layouts/components/HeaderTab.vue'
|
import HeaderTab from './layouts/components/HeaderTab.vue'
|
||||||
|
import PageContentTitle from './layouts/components/PageContentTitle.vue'
|
||||||
|
|
||||||
// 7. 样式文件
|
// 7. 样式文件
|
||||||
import '@core/scss/template/libs/vuetify/index.scss'
|
import '@core/scss/template/libs/vuetify/index.scss'
|
||||||
@@ -95,6 +96,7 @@ initializeApp().then(() => {
|
|||||||
.component('VCronField', CronField)
|
.component('VCronField', CronField)
|
||||||
.component('VPathField', PathField)
|
.component('VPathField', PathField)
|
||||||
.component('VHeaderTab', HeaderTab)
|
.component('VHeaderTab', HeaderTab)
|
||||||
|
.component('VPageContentTitle', PageContentTitle)
|
||||||
|
|
||||||
// 5. 注册其他插件
|
// 5. 注册其他插件
|
||||||
app
|
app
|
||||||
|
|||||||
@@ -27,16 +27,7 @@ function getApiPath(paths: string[] | string) {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="title" class="my-3 md:flex md:items-center md:justify-between">
|
<VPageContentTitle :title="title" />
|
||||||
<div class="min-w-0 flex-1 mx-0">
|
|
||||||
<h2
|
|
||||||
class="ms-1 truncate text-2xl font-bold leading-7 text-gray-100 sm:overflow-visible sm:text-3xl sm:leading-9 md:mb-0"
|
|
||||||
data-testid="page-header"
|
|
||||||
>
|
|
||||||
<span class="text-moviepilot">{{ title }}</span>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<PersonCardListView v-if="type === 'person'" :apipath="getApiPath(props.paths || '')" :params="route.query" />
|
<PersonCardListView v-if="type === 'person'" :apipath="getApiPath(props.paths || '')" :params="route.query" />
|
||||||
<MediaCardListView v-else :apipath="getApiPath(props.paths || '')" :params="route.query" />
|
<MediaCardListView v-else :apipath="getApiPath(props.paths || '')" :params="route.query" />
|
||||||
<VScrollToTopBtn />
|
<VScrollToTopBtn />
|
||||||
|
|||||||
@@ -18,26 +18,14 @@ const type = route.query?.type?.toString()
|
|||||||
|
|
||||||
// 计算API路径
|
// 计算API路径
|
||||||
function getApiPath(paths: string[] | string) {
|
function getApiPath(paths: string[] | string) {
|
||||||
if (Array.isArray(paths))
|
if (Array.isArray(paths)) return paths.join('/')
|
||||||
return paths.join('/')
|
else return paths
|
||||||
else
|
|
||||||
return paths
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div v-if="title" class="mt-3 md:flex md:items-center md:justify-between">
|
<VPageContentTitle :title="title" />
|
||||||
<div class="min-w-0 flex-1 mx-0">
|
<PersonCardListView :apipath="getApiPath(props.paths || '')" :params="route.query" :type="type" />
|
||||||
<h2 class="mb-4 truncate text-2xl font-bold leading-7 text-gray-100 sm:overflow-visible sm:text-4xl sm:leading-9 md:mb-0" data-testid="page-header">
|
|
||||||
<span class="text-moviepilot">{{ title }}</span>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<PersonCardListView
|
|
||||||
:apipath="getApiPath(props.paths || '')"
|
|
||||||
:params="route.query"
|
|
||||||
:type="type"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ onDeactivated(() => {
|
|||||||
<VIcon icon="mdi-tune" size="small" class="me-2" />
|
<VIcon icon="mdi-tune" size="small" class="me-2" />
|
||||||
设置仪表板
|
设置仪表板
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<DialogCloseBtn @click="dialog = false" />
|
<VDialogCloseBtn @click="dialog = false" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ onActivated(async () => {
|
|||||||
<VBtn
|
<VBtn
|
||||||
icon="mdi-order-alphabetical-ascending"
|
icon="mdi-order-alphabetical-ascending"
|
||||||
variant="text"
|
variant="text"
|
||||||
color="primary"
|
color="grey"
|
||||||
size="default"
|
size="default"
|
||||||
class="settings-icon-button"
|
class="settings-icon-button"
|
||||||
@click="orderConfigDialog = true"
|
@click="orderConfigDialog = true"
|
||||||
@@ -181,7 +181,7 @@ onActivated(async () => {
|
|||||||
<VIcon icon="mdi-order-alphabetical-ascending" size="small" class="me-2" />
|
<VIcon icon="mdi-order-alphabetical-ascending" size="small" class="me-2" />
|
||||||
设置标签顺序
|
设置标签顺序
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<DialogCloseBtn @click="orderConfigDialog = false" />
|
<VDialogCloseBtn @click="orderConfigDialog = false" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ onActivated(async () => {
|
|||||||
<VBtn
|
<VBtn
|
||||||
icon="mdi-tune"
|
icon="mdi-tune"
|
||||||
variant="text"
|
variant="text"
|
||||||
color="primary"
|
color="grey"
|
||||||
size="default"
|
size="default"
|
||||||
class="settings-icon-button"
|
class="settings-icon-button"
|
||||||
@click="dialog = true"
|
@click="dialog = true"
|
||||||
@@ -234,7 +234,7 @@ onActivated(async () => {
|
|||||||
<VIcon icon="mdi-tune" size="small" class="me-2" />
|
<VIcon icon="mdi-tune" size="small" class="me-2" />
|
||||||
自定义内容
|
自定义内容
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<DialogCloseBtn @click="dialog = false" />
|
<VDialogCloseBtn @click="dialog = false" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
|
|||||||
@@ -12,17 +12,30 @@ const subType = route.meta.subType?.toString()
|
|||||||
const subId = ref(route.query.id as string)
|
const subId = ref(route.query.id as string)
|
||||||
const activeTab = ref(route.query.tab)
|
const activeTab = ref(route.query.tab)
|
||||||
const shareViewKey = ref(0)
|
const shareViewKey = ref(0)
|
||||||
|
const subscribeViewKey = ref(0)
|
||||||
|
|
||||||
// 默认订阅设置弹窗
|
// 默认订阅设置弹窗
|
||||||
const subscribeEditDialog = ref(false)
|
const subscribeEditDialog = ref(false)
|
||||||
|
|
||||||
|
// 订阅过滤弹窗
|
||||||
|
const filterSubscribeDialog = ref(false)
|
||||||
|
|
||||||
// 搜索订阅分享弹窗
|
// 搜索订阅分享弹窗
|
||||||
const searchShareDialog = ref(false)
|
const searchShareDialog = ref(false)
|
||||||
|
|
||||||
// 分享订阅过滤词
|
// 订阅过滤词
|
||||||
const shareFilter = ref('')
|
const subscribeFilter = ref('')
|
||||||
|
|
||||||
// 触发搜索订阅
|
// 分享搜索词
|
||||||
|
const shareKeyword = ref('')
|
||||||
|
|
||||||
|
// 过滤订阅
|
||||||
|
const filterSubscribes = () => {
|
||||||
|
filterSubscribeDialog.value = false
|
||||||
|
subscribeViewKey.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
// 搜索分享
|
||||||
const searchShares = () => {
|
const searchShares = () => {
|
||||||
searchShareDialog.value = false
|
searchShareDialog.value = false
|
||||||
shareViewKey.value++
|
shareViewKey.value++
|
||||||
@@ -33,26 +46,50 @@ const searchShares = () => {
|
|||||||
<div>
|
<div>
|
||||||
<VHeaderTab :items="subType == '电影' ? SubscribeMovieTabs : SubscribeTvTabs" v-model="activeTab">
|
<VHeaderTab :items="subType == '电影' ? SubscribeMovieTabs : SubscribeTvTabs" v-model="activeTab">
|
||||||
<template #append>
|
<template #append>
|
||||||
<VBtn
|
<VMenu
|
||||||
v-if="activeTab === '我的订阅'"
|
v-if="activeTab === '我的订阅'"
|
||||||
icon="mdi-clipboard-edit-outline"
|
v-model="filterSubscribeDialog"
|
||||||
variant="text"
|
width="25rem"
|
||||||
color="primary"
|
:close-on-content-click="false"
|
||||||
size="default"
|
>
|
||||||
class="settings-icon-button"
|
<template #activator="{ props }">
|
||||||
@click="subscribeEditDialog = true"
|
<VBtn
|
||||||
/>
|
icon="mdi-filter-cog-outline"
|
||||||
|
variant="text"
|
||||||
|
:color="subscribeFilter ? 'primary' : 'gray'"
|
||||||
|
size="default"
|
||||||
|
class="settings-icon-button"
|
||||||
|
v-bind="props"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<VCard>
|
||||||
|
<VCardItem>
|
||||||
|
<VCardTitle>
|
||||||
|
<VIcon icon="mdi-filter-cog-outline" class="mr-2" />
|
||||||
|
筛选订阅
|
||||||
|
</VCardTitle>
|
||||||
|
<VDialogCloseBtn @click="filterSubscribeDialog = false" />
|
||||||
|
</VCardItem>
|
||||||
|
<VCardText>
|
||||||
|
<VTextField v-model="subscribeFilter" label="名称" clearable density="comfortable">
|
||||||
|
<template #append>
|
||||||
|
<VBtn prepend-icon="mdi-check" color="primary" @click="filterSubscribes">确定</VBtn>
|
||||||
|
</template>
|
||||||
|
</VTextField>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</VMenu>
|
||||||
<VMenu
|
<VMenu
|
||||||
v-if="activeTab === '订阅分享'"
|
v-if="activeTab === '订阅分享'"
|
||||||
v-model="searchShareDialog"
|
v-model="searchShareDialog"
|
||||||
width="35rem"
|
width="25rem"
|
||||||
:close-on-content-click="false"
|
:close-on-content-click="false"
|
||||||
>
|
>
|
||||||
<template #activator="{ props }">
|
<template #activator="{ props }">
|
||||||
<VBtn
|
<VBtn
|
||||||
icon="mdi-movie-search-outline"
|
icon="mdi-movie-search-outline"
|
||||||
variant="text"
|
variant="text"
|
||||||
color="primary"
|
:color="shareKeyword ? 'primary' : 'gray'"
|
||||||
size="default"
|
size="default"
|
||||||
class="settings-icon-button"
|
class="settings-icon-button"
|
||||||
v-bind="props"
|
v-bind="props"
|
||||||
@@ -64,10 +101,10 @@ const searchShares = () => {
|
|||||||
<VIcon icon="mdi-movie-search-outline" class="mr-2" />
|
<VIcon icon="mdi-movie-search-outline" class="mr-2" />
|
||||||
搜索订阅分享
|
搜索订阅分享
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<DialogCloseBtn @click="searchShareDialog = false" />
|
<VDialogCloseBtn @click="searchShareDialog = false" />
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VTextField v-model="shareFilter" label="搜索关键词" clearable>
|
<VTextField v-model="shareKeyword" label="关键词" clearable density="comfortable">
|
||||||
<template #append>
|
<template #append>
|
||||||
<VBtn prepend-icon="mdi-magnify" color="primary" @click="searchShares">搜索</VBtn>
|
<VBtn prepend-icon="mdi-magnify" color="primary" @click="searchShares">搜索</VBtn>
|
||||||
</template>
|
</template>
|
||||||
@@ -75,14 +112,23 @@ const searchShares = () => {
|
|||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
</VMenu>
|
</VMenu>
|
||||||
|
<VBtn
|
||||||
|
v-if="activeTab === '我的订阅'"
|
||||||
|
icon="mdi-clipboard-edit-outline"
|
||||||
|
variant="text"
|
||||||
|
color="gray"
|
||||||
|
size="default"
|
||||||
|
class="settings-icon-button"
|
||||||
|
@click="subscribeEditDialog = true"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</VHeaderTab>
|
</VHeaderTab>
|
||||||
|
|
||||||
<VWindow v-model="activeTab" class="disable-tab-transition" :touch="false">
|
<VWindow v-model="activeTab" class="disable-tab-transition" :touch="false">
|
||||||
<VWindowItem value="我的订阅">
|
<VWindowItem value="我的订阅">
|
||||||
<transition name="fade-slide" appear>
|
<transition name="fade-slide" appear>
|
||||||
<div class="mt-4">
|
<div>
|
||||||
<SubscribeListView :type="subType" :subid="subId" />
|
<SubscribeListView :type="subType" :subid="subId" :key="subscribeViewKey" :keyword="subscribeFilter" />
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
@@ -96,7 +142,7 @@ const searchShares = () => {
|
|||||||
<VWindowItem value="订阅分享">
|
<VWindowItem value="订阅分享">
|
||||||
<transition name="fade-slide" appear>
|
<transition name="fade-slide" appear>
|
||||||
<div>
|
<div>
|
||||||
<SubscribeShareView :keyword="shareFilter" :key="shareViewKey" />
|
<SubscribeShareView :keyword="shareKeyword" :key="shareViewKey" />
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</VWindowItem>
|
</VWindowItem>
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ html {
|
|||||||
|
|
||||||
.backdrop-blur {
|
.backdrop-blur {
|
||||||
--tw-backdrop-blur: blur(8px)!important;
|
--tw-backdrop-blur: blur(8px)!important;
|
||||||
|
|
||||||
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important;
|
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,3 +320,8 @@ html {
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
min-inline-size: auto;
|
min-inline-size: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.v-infinite-scroll__side {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ const loading = ref(false)
|
|||||||
// 已安装插件列表
|
// 已安装插件列表
|
||||||
const dataList = ref<Plugin[]>([])
|
const dataList = ref<Plugin[]>([])
|
||||||
|
|
||||||
|
// 过滤后的已安装插件列表
|
||||||
|
const filteredDataList = ref<Plugin[]>([])
|
||||||
|
|
||||||
// 未安装插件列表
|
// 未安装插件列表
|
||||||
const uninstalledList = ref<Plugin[]>([])
|
const uninstalledList = ref<Plugin[]>([])
|
||||||
|
|
||||||
@@ -101,6 +104,25 @@ const filterForm = reactive({
|
|||||||
repo: [] as string[],
|
repo: [] as string[],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 计算过滤表单是否全部为空
|
||||||
|
const isFilterFormEmpty = computed(() => {
|
||||||
|
return (
|
||||||
|
filterForm.name === '' &&
|
||||||
|
filterForm.author.length === 0 &&
|
||||||
|
filterForm.label.length === 0 &&
|
||||||
|
filterForm.repo.length === 0
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 插件过滤条件
|
||||||
|
const installedFilter = ref('')
|
||||||
|
|
||||||
|
// 已安装插件过滤窗口
|
||||||
|
const filterInstalledPluginDialog = ref(false)
|
||||||
|
|
||||||
|
// 插件市场过滤窗口
|
||||||
|
const filterMarketPluginDialog = ref(false)
|
||||||
|
|
||||||
// 作者过滤项
|
// 作者过滤项
|
||||||
const authorFilterOptions = ref<string[]>([])
|
const authorFilterOptions = ref<string[]>([])
|
||||||
// 标签过滤项
|
// 标签过滤项
|
||||||
@@ -380,6 +402,13 @@ function handleRepoUrl(url: string | undefined) {
|
|||||||
return url.replace('https://github.com/', '').replace('https://raw.githubusercontent.com/', '')
|
return url.replace('https://github.com/', '').replace('https://raw.githubusercontent.com/', '')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 监测dataList变化或installedFilter变化时更新filteredDataList
|
||||||
|
watch([dataList, installedFilter], () => {
|
||||||
|
filteredDataList.value = dataList.value.filter(item => {
|
||||||
|
return item.plugin_name?.toLowerCase().includes(installedFilter.value.toLowerCase())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// 加载时获取数据
|
// 加载时获取数据
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await loadPluginOrderConfig()
|
await loadPluginOrderConfig()
|
||||||
@@ -399,10 +428,112 @@ onMounted(async () => {
|
|||||||
<div>
|
<div>
|
||||||
<VHeaderTab :items="PluginTabs" v-model="activeTab">
|
<VHeaderTab :items="PluginTabs" v-model="activeTab">
|
||||||
<template #append>
|
<template #append>
|
||||||
|
<VMenu
|
||||||
|
v-if="activeTab === '我的插件'"
|
||||||
|
v-model="filterInstalledPluginDialog"
|
||||||
|
width="20rem"
|
||||||
|
:close-on-content-click="false"
|
||||||
|
>
|
||||||
|
<template #activator="{ props }">
|
||||||
|
<VBtn
|
||||||
|
icon="mdi-filter-cog-outline"
|
||||||
|
variant="text"
|
||||||
|
:color="installedFilter ? 'primary' : 'gray'"
|
||||||
|
size="default"
|
||||||
|
class="settings-icon-button"
|
||||||
|
v-bind="props"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<VCard>
|
||||||
|
<VCardItem>
|
||||||
|
<VCardTitle>
|
||||||
|
<VIcon icon="mdi-filter-cog-outline" class="mr-2" />
|
||||||
|
筛选插件
|
||||||
|
</VCardTitle>
|
||||||
|
<VDialogCloseBtn @click="filterInstalledPluginDialog = false" />
|
||||||
|
</VCardItem>
|
||||||
|
<VCardText>
|
||||||
|
<VTextField v-model="installedFilter" label="名称" density="comfortable" clearable />
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</VMenu>
|
||||||
|
<VMenu
|
||||||
|
v-if="activeTab === '插件市场'"
|
||||||
|
v-model="filterMarketPluginDialog"
|
||||||
|
width="25rem"
|
||||||
|
:close-on-content-click="false"
|
||||||
|
>
|
||||||
|
<template #activator="{ props }">
|
||||||
|
<VBtn
|
||||||
|
icon="mdi-filter-cog-outline"
|
||||||
|
variant="text"
|
||||||
|
:color="isFilterFormEmpty ? 'gray' : 'primary'"
|
||||||
|
size="default"
|
||||||
|
class="settings-icon-button"
|
||||||
|
v-bind="props"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<VCard>
|
||||||
|
<VCardItem>
|
||||||
|
<VCardTitle>
|
||||||
|
<VIcon icon="mdi-filter-cog-outline" class="mr-2" />
|
||||||
|
筛选插件
|
||||||
|
</VCardTitle>
|
||||||
|
<VDialogCloseBtn @click="filterMarketPluginDialog = false" />
|
||||||
|
</VCardItem>
|
||||||
|
<VCardText>
|
||||||
|
<!-- 过滤表单 -->
|
||||||
|
<div v-if="isAppMarketLoaded">
|
||||||
|
<VRow>
|
||||||
|
<VCol cols="12" md="6">
|
||||||
|
<VTextField v-model="filterForm.name" density="comfortable" label="名称" clearable />
|
||||||
|
</VCol>
|
||||||
|
<VCol v-if="authorFilterOptions.length > 0" cols="12" md="6">
|
||||||
|
<VSelect
|
||||||
|
v-model="filterForm.author"
|
||||||
|
:items="authorFilterOptions"
|
||||||
|
density="comfortable"
|
||||||
|
chips
|
||||||
|
label="作者"
|
||||||
|
multiple
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
<VCol v-if="labelFilterOptions.length > 0" cols="12" md="6">
|
||||||
|
<VSelect
|
||||||
|
v-model="filterForm.label"
|
||||||
|
:items="labelFilterOptions"
|
||||||
|
density="comfortable"
|
||||||
|
chips
|
||||||
|
label="标签"
|
||||||
|
multiple
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
<VCol v-if="repoFilterOptions.length > 0" cols="12" md="6">
|
||||||
|
<VSelect
|
||||||
|
v-model="filterForm.repo"
|
||||||
|
:items="repoFilterOptions"
|
||||||
|
density="comfortable"
|
||||||
|
chips
|
||||||
|
label="插件库"
|
||||||
|
multiple
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
<VCol v-if="repoFilterOptions.length > 0" cols="12" md="6">
|
||||||
|
<VSelect v-model="activeSort" :items="sortOptions" density="comfortable" label="排序" />
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
</div>
|
||||||
|
</VCardText>
|
||||||
|
</VCard>
|
||||||
|
</VMenu>
|
||||||
<VBtn
|
<VBtn
|
||||||
|
v-if="activeTab === '插件市场'"
|
||||||
icon="mdi-store-cog"
|
icon="mdi-store-cog"
|
||||||
variant="text"
|
variant="text"
|
||||||
color="primary"
|
color="gray"
|
||||||
size="default"
|
size="default"
|
||||||
class="settings-icon-button"
|
class="settings-icon-button"
|
||||||
@click="MarketSettingDialog = true"
|
@click="MarketSettingDialog = true"
|
||||||
@@ -415,10 +546,11 @@ onMounted(async () => {
|
|||||||
<VWindowItem value="我的插件">
|
<VWindowItem value="我的插件">
|
||||||
<transition name="fade-slide" appear>
|
<transition name="fade-slide" appear>
|
||||||
<div>
|
<div>
|
||||||
|
<VPageContentTitle v-if="installedFilter" :title="`筛选:${installedFilter}`" />
|
||||||
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||||
<draggable
|
<draggable
|
||||||
v-if="dataList.length > 0"
|
v-if="filteredDataList.length > 0"
|
||||||
v-model="dataList"
|
v-model="filteredDataList"
|
||||||
@end="savePluginOrder"
|
@end="savePluginOrder"
|
||||||
handle=".cursor-move"
|
handle=".cursor-move"
|
||||||
item-key="id"
|
item-key="id"
|
||||||
@@ -437,10 +569,12 @@ onMounted(async () => {
|
|||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
<NoDataFound
|
<NoDataFound
|
||||||
v-if="dataList.length === 0 && isRefreshed"
|
v-if="filteredDataList.length === 0 && isRefreshed"
|
||||||
error-code="404"
|
error-code="404"
|
||||||
error-title="没有安装插件"
|
error-title="没有数据"
|
||||||
error-description="点击右下角按钮,前往插件市场安装插件。"
|
:error-description="
|
||||||
|
installedFilter ? '没有搜索到相关内容,请更换搜索关键词。' : '请先前往插件市场安装插件。'
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
@@ -450,50 +584,6 @@ onMounted(async () => {
|
|||||||
<transition name="fade-slide" appear>
|
<transition name="fade-slide" appear>
|
||||||
<div>
|
<div>
|
||||||
<LoadingBanner v-if="!isAppMarketLoaded" class="mt-12" />
|
<LoadingBanner v-if="!isAppMarketLoaded" class="mt-12" />
|
||||||
<!-- 过滤表单 -->
|
|
||||||
<div v-if="isAppMarketLoaded" class="bg-transparent mb-3 shadow-none">
|
|
||||||
<VRow>
|
|
||||||
<VCol cols="6" md="">
|
|
||||||
<VTextField v-model="filterForm.name" density="compact" label="名称" clearable />
|
|
||||||
</VCol>
|
|
||||||
<VCol v-if="authorFilterOptions.length > 0" cols="6" md="">
|
|
||||||
<VSelect
|
|
||||||
v-model="filterForm.author"
|
|
||||||
:items="authorFilterOptions"
|
|
||||||
density="compact"
|
|
||||||
chips
|
|
||||||
label="作者"
|
|
||||||
multiple
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol v-if="labelFilterOptions.length > 0" cols="6" md="">
|
|
||||||
<VSelect
|
|
||||||
v-model="filterForm.label"
|
|
||||||
:items="labelFilterOptions"
|
|
||||||
density="compact"
|
|
||||||
chips
|
|
||||||
label="标签"
|
|
||||||
multiple
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol v-if="repoFilterOptions.length > 0" cols="6" md="">
|
|
||||||
<VSelect
|
|
||||||
v-model="filterForm.repo"
|
|
||||||
:items="repoFilterOptions"
|
|
||||||
density="compact"
|
|
||||||
chips
|
|
||||||
label="插件库"
|
|
||||||
multiple
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</VCol>
|
|
||||||
<VCol v-if="repoFilterOptions.length > 0" cols="6" md="">
|
|
||||||
<VSelect v-model="activeSort" :items="sortOptions" density="compact" label="排序" />
|
|
||||||
</VCol>
|
|
||||||
</VRow>
|
|
||||||
</div>
|
|
||||||
<div v-if="isAppMarketLoaded" class="grid gap-4 grid-plugin-card">
|
<div v-if="isAppMarketLoaded" class="grid gap-4 grid-plugin-card">
|
||||||
<template v-for="(data, index) in sortedUninstalledList" :key="`${data.id}_v${data.plugin_version}`">
|
<template v-for="(data, index) in sortedUninstalledList" :key="`${data.id}_v${data.plugin_version}`">
|
||||||
<PluginAppCard :plugin="data" :count="PluginStatistics[data.id || '0']" @install="pluginInstalled" />
|
<PluginAppCard :plugin="data" :count="PluginStatistics[data.id || '0']" @install="pluginInstalled" />
|
||||||
@@ -555,7 +645,7 @@ onMounted(async () => {
|
|||||||
class="mx-1"
|
class="mx-1"
|
||||||
/>
|
/>
|
||||||
</VToolbar>
|
</VToolbar>
|
||||||
<DialogCloseBtn @click="closeSearchDialog" />
|
<VDialogCloseBtn @click="closeSearchDialog" />
|
||||||
<VList v-if="filterPlugins.length > 0" lines="three">
|
<VList v-if="filterPlugins.length > 0" lines="three">
|
||||||
<VVirtualScroll :items="filterPlugins">
|
<VVirtualScroll :items="filterPlugins">
|
||||||
<template #default="{ item }">
|
<template #default="{ item }">
|
||||||
|
|||||||
@@ -690,7 +690,7 @@ onMounted(fetchData)
|
|||||||
<!-- 底部弹窗 -->
|
<!-- 底部弹窗 -->
|
||||||
<VBottomSheet v-model="deleteConfirmDialog" inset>
|
<VBottomSheet v-model="deleteConfirmDialog" inset>
|
||||||
<VCard class="text-center rounded-t">
|
<VCard class="text-center rounded-t">
|
||||||
<DialogCloseBtn @click="deleteConfirmDialog = false" />
|
<VDialogCloseBtn @click="deleteConfirmDialog = false" />
|
||||||
<VCardTitle class="pe-10">
|
<VCardTitle class="pe-10">
|
||||||
{{ confirmTitle }}
|
{{ confirmTitle }}
|
||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
|
|||||||
@@ -258,7 +258,7 @@ onMounted(() => {
|
|||||||
<VDialog v-if="releaseDialog" v-model="releaseDialog" width="600" scrollable>
|
<VDialog v-if="releaseDialog" v-model="releaseDialog" width="600" scrollable>
|
||||||
<VCard>
|
<VCard>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<DialogCloseBtn @click="releaseDialog = false" />
|
<VDialogCloseBtn @click="releaseDialog = false" />
|
||||||
<VCardTitle>{{ releaseDialogTitle }} 变更日志</VCardTitle>
|
<VCardTitle>{{ releaseDialogTitle }} 变更日志</VCardTitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText v-html="releaseDialogBody" />
|
<VCardText v-html="releaseDialogBody" />
|
||||||
|
|||||||
@@ -554,7 +554,7 @@ onDeactivated(() => {
|
|||||||
<VDialog v-if="advancedDialog" v-model="advancedDialog" scrollable max-width="60rem" persistent>
|
<VDialog v-if="advancedDialog" v-model="advancedDialog" scrollable max-width="60rem" persistent>
|
||||||
<VCard>
|
<VCard>
|
||||||
<VCardItem>
|
<VCardItem>
|
||||||
<DialogCloseBtn @click="advancedDialog = false" />
|
<VDialogCloseBtn @click="advancedDialog = false" />
|
||||||
<VCardTitle>高级设置</VCardTitle>
|
<VCardTitle>高级设置</VCardTitle>
|
||||||
<VCardSubtitle>系统进阶设置,特殊情况下才需要调整</VCardSubtitle>
|
<VCardSubtitle>系统进阶设置,特殊情况下才需要调整</VCardSubtitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
|
|||||||
@@ -89,16 +89,7 @@ onActivated(() => {
|
|||||||
<template>
|
<template>
|
||||||
<div class="card-list-container">
|
<div class="card-list-container">
|
||||||
<!-- 页面标题 -->
|
<!-- 页面标题 -->
|
||||||
<div class="my-3 md:flex md:items-center md:justify-between">
|
<VPageContentTitle title="站点管理" />
|
||||||
<div class="min-w-0 flex-1 mx-0 flex align-middle">
|
|
||||||
<h2
|
|
||||||
class="mb-3 ms-2 truncate text-2xl font-bold leading-7 text-gray-100 sm:overflow-visible sm:text-3xl sm:leading-9 md:mb-0"
|
|
||||||
data-testid="page-header"
|
|
||||||
>
|
|
||||||
<span class="text-moviepilot">站点管理</span>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||||
<draggable
|
<draggable
|
||||||
v-if="siteList.length > 0"
|
v-if="siteList.length > 0"
|
||||||
|
|||||||
@@ -19,11 +19,15 @@ const userStore = useUserStore()
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
subid: String,
|
subid: String,
|
||||||
|
keyword: String,
|
||||||
})
|
})
|
||||||
|
|
||||||
// 是否刷新过
|
// 是否刷新过
|
||||||
let isRefreshed = ref(false)
|
let isRefreshed = ref(false)
|
||||||
|
|
||||||
|
// 搜索关键字
|
||||||
|
const keyword = ref(props.keyword || '')
|
||||||
|
|
||||||
// 顺序存储键值
|
// 顺序存储键值
|
||||||
const localOrderKey = props.type === '电影' ? 'MP_SUBSCRIBE_MOVIE_ORDER' : 'MP_SUBSCRIBE_TV_ORDER'
|
const localOrderKey = props.type === '电影' ? 'MP_SUBSCRIBE_MOVIE_ORDER' : 'MP_SUBSCRIBE_TV_ORDER'
|
||||||
const orderRequestKey = props.type === '电影' ? 'SubscribeMovieOrder' : 'SubscribeTvOrder'
|
const orderRequestKey = props.type === '电影' ? 'SubscribeMovieOrder' : 'SubscribeTvOrder'
|
||||||
@@ -50,6 +54,10 @@ watch(dataList, () => {
|
|||||||
const userName = userStore.userName
|
const userName = userStore.userName
|
||||||
if (superUser) displayList.value = dataList.value.filter(data => data.type === props.type)
|
if (superUser) displayList.value = dataList.value.filter(data => data.type === props.type)
|
||||||
else displayList.value = dataList.value.filter(data => data.type === props.type && data.username === userName)
|
else displayList.value = dataList.value.filter(data => data.type === props.type && data.username === userName)
|
||||||
|
// 过滤关键字
|
||||||
|
if (keyword.value) {
|
||||||
|
displayList.value = displayList.value.filter(data => data.name.toLowerCase().includes(keyword.value.toLowerCase()))
|
||||||
|
}
|
||||||
// 排序
|
// 排序
|
||||||
sortSubscribeOrder()
|
sortSubscribeOrder()
|
||||||
})
|
})
|
||||||
@@ -139,6 +147,7 @@ onActivated(async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<VPageContentTitle v-if="keyword" :title="`筛选:${keyword}`" />
|
||||||
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||||
<draggable
|
<draggable
|
||||||
v-if="displayList.length > 0"
|
v-if="displayList.length > 0"
|
||||||
@@ -156,8 +165,8 @@ onActivated(async () => {
|
|||||||
<NoDataFound
|
<NoDataFound
|
||||||
v-if="displayList.length === 0 && isRefreshed"
|
v-if="displayList.length === 0 && isRefreshed"
|
||||||
error-code="404"
|
error-code="404"
|
||||||
error-title="没有订阅"
|
error-title="没有数据"
|
||||||
error-description="请通过搜索添加电影、电视剧订阅。"
|
:error-description="keyword ? '没有搜索到相关内容,请更换搜索关键词。' : '请通过搜索添加电影、电视剧订阅。'"
|
||||||
/>
|
/>
|
||||||
<!-- 底部操作按钮 -->
|
<!-- 底部操作按钮 -->
|
||||||
<div v-if="isRefreshed">
|
<div v-if="isRefreshed">
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ const apipath = 'subscribe/shares'
|
|||||||
// 当前页码
|
// 当前页码
|
||||||
const page = ref(1)
|
const page = ref(1)
|
||||||
|
|
||||||
|
// 搜索关键字
|
||||||
|
const keyword = ref(props.keyword)
|
||||||
|
|
||||||
// 是否加载中
|
// 是否加载中
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|
||||||
@@ -36,7 +39,7 @@ function getParams() {
|
|||||||
let params = {
|
let params = {
|
||||||
page: page.value,
|
page: page.value,
|
||||||
count: 30,
|
count: 30,
|
||||||
name: props.keyword,
|
name: keyword.value,
|
||||||
}
|
}
|
||||||
return params
|
return params
|
||||||
}
|
}
|
||||||
@@ -112,6 +115,7 @@ function removeData(id: number) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<VPageContentTitle v-if="keyword" :title="`搜索:${keyword}`" />
|
||||||
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||||
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-hidden" @load="fetchData">
|
<VInfiniteScroll mode="intersect" side="end" :items="dataList" class="overflow-hidden" @load="fetchData">
|
||||||
<template #loading />
|
<template #loading />
|
||||||
@@ -126,7 +130,7 @@ function removeData(id: number) {
|
|||||||
error-code="404"
|
error-code="404"
|
||||||
error-title="没有数据"
|
error-title="没有数据"
|
||||||
:error-description="
|
:error-description="
|
||||||
keyword ? '没有搜索到相关内容,请更换搜索关键词' : '未获取到分享订阅数据,未开启数据分享或服务器无法连接。'
|
keyword ? '没有搜索到相关内容,请更换搜索关键词。' : '未获取到分享订阅数据,未开启数据分享或服务器无法连接。'
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</VInfiniteScroll>
|
</VInfiniteScroll>
|
||||||
|
|||||||
@@ -54,22 +54,11 @@ onActivated(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<!-- 页面标题 -->
|
||||||
|
<VPageContentTitle title="用户管理" />
|
||||||
<div class="card-list-container">
|
<div class="card-list-container">
|
||||||
<!-- 页面标题 -->
|
|
||||||
<div class="my-3 md:flex md:items-center md:justify-between">
|
|
||||||
<div class="min-w-0 flex-1 mx-0 flex align-middle">
|
|
||||||
<h2
|
|
||||||
class="mb-3 ms-2 truncate text-2xl font-bold leading-7 text-gray-100 sm:overflow-visible sm:text-3xl sm:leading-9 md:mb-0"
|
|
||||||
data-testid="page-header"
|
|
||||||
>
|
|
||||||
<span class="text-moviepilot">用户管理</span>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 加载中提示 -->
|
<!-- 加载中提示 -->
|
||||||
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||||
|
|
||||||
<!-- 用户卡片网格 -->
|
<!-- 用户卡片网格 -->
|
||||||
<div v-if="allUsers.length > 0 && isRefreshed" class="grid gap- grid-user-card">
|
<div v-if="allUsers.length > 0 && isRefreshed" class="grid gap- grid-user-card">
|
||||||
<!-- 普通用户卡片 -->
|
<!-- 普通用户卡片 -->
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ const accountInfo = ref<User>({
|
|||||||
is_otp: false,
|
is_otp: false,
|
||||||
permissions: {},
|
permissions: {},
|
||||||
settings: {},
|
settings: {},
|
||||||
nickname: ''
|
nickname: '',
|
||||||
})
|
})
|
||||||
|
|
||||||
// 二维码信息
|
// 二维码信息
|
||||||
@@ -135,15 +135,15 @@ async function saveAccountInfo() {
|
|||||||
}
|
}
|
||||||
accountInfo.value.password = newPassword.value
|
accountInfo.value.password = newPassword.value
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将nickname保存到settings中,后端可以直接处理JSON对象
|
// 将nickname保存到settings中,后端可以直接处理JSON对象
|
||||||
if (accountInfo.value.nickname) {
|
if (accountInfo.value.nickname) {
|
||||||
if (!accountInfo.value.settings) {
|
if (!accountInfo.value.settings) {
|
||||||
accountInfo.value.settings = {};
|
accountInfo.value.settings = {}
|
||||||
}
|
}
|
||||||
accountInfo.value.settings.nickname = accountInfo.value.nickname;
|
accountInfo.value.settings.nickname = accountInfo.value.nickname
|
||||||
}
|
}
|
||||||
|
|
||||||
const oldUserName = accountInfo.value.name
|
const oldUserName = accountInfo.value.name
|
||||||
const oldAvatar = accountInfo.value.avatar
|
const oldAvatar = accountInfo.value.avatar
|
||||||
accountInfo.value.avatar = currentAvatar.value
|
accountInfo.value.avatar = currentAvatar.value
|
||||||
@@ -151,10 +151,10 @@ async function saveAccountInfo() {
|
|||||||
isSaving.value = true
|
isSaving.value = true
|
||||||
try {
|
try {
|
||||||
// 创建一个临时对象来保存用户数据,确保所有字段都会发送
|
// 创建一个临时对象来保存用户数据,确保所有字段都会发送
|
||||||
const userData = { ...accountInfo.value };
|
const userData = { ...accountInfo.value }
|
||||||
|
|
||||||
const result: { [key: string]: any } = await api.put('user/', userData)
|
const result: { [key: string]: any } = await api.put('user/', userData)
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
if (oldUserName !== currentUserName.value) {
|
if (oldUserName !== currentUserName.value) {
|
||||||
$toast.success(`【${oldUserName}】更名【${currentUserName.value}】,用户信息保存成功!`)
|
$toast.success(`【${oldUserName}】更名【${currentUserName.value}】,用户信息保存成功!`)
|
||||||
@@ -312,12 +312,7 @@ watch(
|
|||||||
<VForm class="mt-6">
|
<VForm class="mt-6">
|
||||||
<VRow>
|
<VRow>
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VTextField
|
<VTextField v-model="currentUserName" density="comfortable" readonly label="用户名" />
|
||||||
v-model="currentUserName"
|
|
||||||
density="comfortable"
|
|
||||||
readonly
|
|
||||||
label="用户名"
|
|
||||||
/>
|
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VTextField v-model="accountInfo.email" density="comfortable" clearable label="邮箱" type="email" />
|
<VTextField v-model="accountInfo.email" density="comfortable" clearable label="邮箱" type="email" />
|
||||||
@@ -430,7 +425,7 @@ watch(
|
|||||||
<VDialog v-if="otpDialog" v-model="otpDialog" max-width="45rem" scrollable>
|
<VDialog v-if="otpDialog" v-model="otpDialog" max-width="45rem" scrollable>
|
||||||
<!-- 开启双重验证弹窗内容 -->
|
<!-- 开启双重验证弹窗内容 -->
|
||||||
<VCard>
|
<VCard>
|
||||||
<DialogCloseBtn @click="otpDialog = false" />
|
<VDialogCloseBtn @click="otpDialog = false" />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<h4 class="text-h4 text-center mb-6 mt-5">登录双重验证</h4>
|
<h4 class="text-h4 text-center mb-6 mt-5">登录双重验证</h4>
|
||||||
<h5 class="text-h5 font-weight-medium mb-2">身份验证器</h5>
|
<h5 class="text-h5 font-weight-medium mb-2">身份验证器</h5>
|
||||||
|
|||||||
@@ -46,17 +46,8 @@ onActivated(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<!-- 页面标题 -->
|
|
||||||
<div class="my-3 md:flex md:items-center md:justify-between">
|
<VPageContentTitle title="工作流" />
|
||||||
<div class="min-w-0 flex-1 mx-0 flex align-middle">
|
|
||||||
<h2
|
|
||||||
class="mb-3 ms-2 truncate text-2xl font-bold leading-7 text-gray-100 sm:overflow-visible sm:text-3xl sm:leading-9 md:mb-0"
|
|
||||||
data-testid="page-header"
|
|
||||||
>
|
|
||||||
<span class="text-moviepilot">工作流</span>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
<LoadingBanner v-if="!isRefreshed" class="mt-12" />
|
||||||
<VRow v-if="workflowList.length > 0" class="match-height">
|
<VRow v-if="workflowList.length > 0" class="match-height">
|
||||||
<VCol cols="12" md="6" lg="4" v-for="item in workflowList" :key="item.id">
|
<VCol cols="12" md="6" lg="4" v-for="item in workflowList" :key="item.id">
|
||||||
|
|||||||
Reference in New Issue
Block a user