mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-04 23:18:44 +08:00
仪表板组件高度拉齐开关 && 无边框组件背景不拉平 && 修复多次定时问题
This commit is contained in:
@@ -42,7 +42,19 @@ onUnmounted(() => {
|
|||||||
<!-- 插件仪表板 -->
|
<!-- 插件仪表板 -->
|
||||||
<VHover v-else-if="!isNullOrEmptyObject(props.config)">
|
<VHover v-else-if="!isNullOrEmptyObject(props.config)">
|
||||||
<template #default="hover">
|
<template #default="hover">
|
||||||
<VCard v-bind="hover.props">
|
<!-- 无边框 -->
|
||||||
|
<div v-if="props.config?.attrs.border === false">
|
||||||
|
<VCard v-bind="hover.props">
|
||||||
|
<VCardText class="p-0">
|
||||||
|
<DashboardRender v-for="(item, index) in props.config?.elements" :key="index" :config="item" />
|
||||||
|
</VCardText>
|
||||||
|
<div v-if="hover.isHovering" class="absolute right-5 top-5">
|
||||||
|
<VIcon class="cursor-move">mdi-drag</VIcon>
|
||||||
|
</div>
|
||||||
|
</VCard>
|
||||||
|
</div>
|
||||||
|
<!-- 有边框 -->
|
||||||
|
<VCard v-else v-bind="hover.props">
|
||||||
<VCardItem v-if="props.config?.attrs.border !== false">
|
<VCardItem v-if="props.config?.attrs.border !== false">
|
||||||
<template #append>
|
<template #append>
|
||||||
<VIcon class="cursor-move" v-if="hover.isHovering">mdi-drag</VIcon>
|
<VIcon class="cursor-move" v-if="hover.isHovering">mdi-drag</VIcon>
|
||||||
@@ -52,12 +64,9 @@ onUnmounted(() => {
|
|||||||
</VCardTitle>
|
</VCardTitle>
|
||||||
<VCardSubtitle v-if="props.config?.attrs?.subtitle"> {{ props.config?.attrs?.subtitle }}</VCardSubtitle>
|
<VCardSubtitle v-if="props.config?.attrs?.subtitle"> {{ props.config?.attrs?.subtitle }}</VCardSubtitle>
|
||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VCardText :class="{ 'p-0': props.config?.attrs.border === false }">
|
<VCardText>
|
||||||
<DashboardRender v-for="(item, index) in props.config?.elements" :key="index" :config="item" />
|
<DashboardRender v-for="(item, index) in props.config?.elements" :key="index" :config="item" />
|
||||||
</VCardText>
|
</VCardText>
|
||||||
<div v-if="props.config?.attrs.border === false && hover.isHovering" class="absolute right-5 top-5">
|
|
||||||
<VIcon class="cursor-move">mdi-drag</VIcon>
|
|
||||||
</div>
|
|
||||||
</VCard>
|
</VCard>
|
||||||
</template>
|
</template>
|
||||||
</VHover>
|
</VHover>
|
||||||
|
|||||||
+75
-22
@@ -9,6 +9,20 @@ import DashboardElement from '@/components/misc/DashboardElement.vue'
|
|||||||
// 从Vuex Store中获取superuser信息
|
// 从Vuex Store中获取superuser信息
|
||||||
const superUser = store.state.auth.superUser
|
const superUser = store.state.auth.superUser
|
||||||
|
|
||||||
|
// 是否拉升高度
|
||||||
|
const isElevated = ref(true)
|
||||||
|
|
||||||
|
// 计算属性,控制是否拉升高度
|
||||||
|
const elevatedConf = controlledComputed(
|
||||||
|
() => isElevated.value,
|
||||||
|
() => ({
|
||||||
|
class: { 'match-height': isElevated.value },
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
// 所有组件刷新定时器的句柄
|
||||||
|
const refreshTimers = ref<{ [key: string]: NodeJS.Timeout }>({})
|
||||||
|
|
||||||
// 仪表板启用配置
|
// 仪表板启用配置
|
||||||
const enableConfig = ref<{ [key: string]: boolean }>({
|
const enableConfig = ref<{ [key: string]: boolean }>({
|
||||||
mediaStatistic: true,
|
mediaStatistic: true,
|
||||||
@@ -24,14 +38,14 @@ const enableConfig = ref<{ [key: string]: boolean }>({
|
|||||||
})
|
})
|
||||||
|
|
||||||
// 仪表板顺序配置
|
// 仪表板顺序配置
|
||||||
const orderConfig = ref<{ id: string, key: string }[]>([])
|
const orderConfig = ref<{ id: string; key: string }[]>([])
|
||||||
|
|
||||||
// 仪表板配置
|
// 仪表板配置
|
||||||
const dashboardConfigs = ref<DashboardItem[]>([
|
const dashboardConfigs = ref<DashboardItem[]>([
|
||||||
{
|
{
|
||||||
id: 'storage',
|
id: 'storage',
|
||||||
name: '存储空间',
|
name: '存储空间',
|
||||||
key: "",
|
key: '',
|
||||||
attrs: {},
|
attrs: {},
|
||||||
cols: { cols: 12, md: 4 },
|
cols: { cols: 12, md: 4 },
|
||||||
elements: [],
|
elements: [],
|
||||||
@@ -39,7 +53,7 @@ const dashboardConfigs = ref<DashboardItem[]>([
|
|||||||
{
|
{
|
||||||
id: 'mediaStatistic',
|
id: 'mediaStatistic',
|
||||||
name: '媒体统计',
|
name: '媒体统计',
|
||||||
key: "",
|
key: '',
|
||||||
attrs: {},
|
attrs: {},
|
||||||
cols: { cols: 12, md: 8 },
|
cols: { cols: 12, md: 8 },
|
||||||
elements: [],
|
elements: [],
|
||||||
@@ -47,7 +61,7 @@ const dashboardConfigs = ref<DashboardItem[]>([
|
|||||||
{
|
{
|
||||||
id: 'weeklyOverview',
|
id: 'weeklyOverview',
|
||||||
name: '最近入库',
|
name: '最近入库',
|
||||||
key: "",
|
key: '',
|
||||||
attrs: {},
|
attrs: {},
|
||||||
cols: { cols: 12, md: 4 },
|
cols: { cols: 12, md: 4 },
|
||||||
elements: [],
|
elements: [],
|
||||||
@@ -55,7 +69,7 @@ const dashboardConfigs = ref<DashboardItem[]>([
|
|||||||
{
|
{
|
||||||
id: 'speed',
|
id: 'speed',
|
||||||
name: '实时速率',
|
name: '实时速率',
|
||||||
key: "",
|
key: '',
|
||||||
attrs: {},
|
attrs: {},
|
||||||
cols: { cols: 12, md: 4 },
|
cols: { cols: 12, md: 4 },
|
||||||
elements: [],
|
elements: [],
|
||||||
@@ -63,7 +77,7 @@ const dashboardConfigs = ref<DashboardItem[]>([
|
|||||||
{
|
{
|
||||||
id: 'scheduler',
|
id: 'scheduler',
|
||||||
name: '后台任务',
|
name: '后台任务',
|
||||||
key: "",
|
key: '',
|
||||||
attrs: {},
|
attrs: {},
|
||||||
cols: { cols: 12, md: 4 },
|
cols: { cols: 12, md: 4 },
|
||||||
elements: [],
|
elements: [],
|
||||||
@@ -71,7 +85,7 @@ const dashboardConfigs = ref<DashboardItem[]>([
|
|||||||
{
|
{
|
||||||
id: 'cpu',
|
id: 'cpu',
|
||||||
name: 'CPU',
|
name: 'CPU',
|
||||||
key: "",
|
key: '',
|
||||||
attrs: {},
|
attrs: {},
|
||||||
cols: { cols: 12, md: 6 },
|
cols: { cols: 12, md: 6 },
|
||||||
elements: [],
|
elements: [],
|
||||||
@@ -79,7 +93,7 @@ const dashboardConfigs = ref<DashboardItem[]>([
|
|||||||
{
|
{
|
||||||
id: 'memory',
|
id: 'memory',
|
||||||
name: '内存',
|
name: '内存',
|
||||||
key: "",
|
key: '',
|
||||||
attrs: {},
|
attrs: {},
|
||||||
cols: { cols: 12, md: 6 },
|
cols: { cols: 12, md: 6 },
|
||||||
elements: [],
|
elements: [],
|
||||||
@@ -87,7 +101,7 @@ const dashboardConfigs = ref<DashboardItem[]>([
|
|||||||
{
|
{
|
||||||
id: 'library',
|
id: 'library',
|
||||||
name: '我的媒体库',
|
name: '我的媒体库',
|
||||||
key: "",
|
key: '',
|
||||||
attrs: {},
|
attrs: {},
|
||||||
cols: { cols: 12 },
|
cols: { cols: 12 },
|
||||||
elements: [],
|
elements: [],
|
||||||
@@ -95,7 +109,7 @@ const dashboardConfigs = ref<DashboardItem[]>([
|
|||||||
{
|
{
|
||||||
id: 'playing',
|
id: 'playing',
|
||||||
name: '继续观看',
|
name: '继续观看',
|
||||||
key: "",
|
key: '',
|
||||||
attrs: {},
|
attrs: {},
|
||||||
cols: { cols: 12 },
|
cols: { cols: 12 },
|
||||||
elements: [],
|
elements: [],
|
||||||
@@ -103,7 +117,7 @@ const dashboardConfigs = ref<DashboardItem[]>([
|
|||||||
{
|
{
|
||||||
id: 'latest',
|
id: 'latest',
|
||||||
name: '最近添加',
|
name: '最近添加',
|
||||||
key: "",
|
key: '',
|
||||||
attrs: {},
|
attrs: {},
|
||||||
cols: { cols: 12 },
|
cols: { cols: 12 },
|
||||||
elements: [],
|
elements: [],
|
||||||
@@ -143,6 +157,8 @@ async function loadDashboardConfig() {
|
|||||||
localStorage.setItem('MP_DASHBOARD_ORDER', JSON.stringify(orderConfig.value))
|
localStorage.setItem('MP_DASHBOARD_ORDER', JSON.stringify(orderConfig.value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 是否拉升高度
|
||||||
|
isElevated.value = localStorage.getItem('MP_DASHBOARD_ELEVATED') === 'true'
|
||||||
// 排序
|
// 排序
|
||||||
if (orderConfig.value) {
|
if (orderConfig.value) {
|
||||||
sortDashboardConfigs()
|
sortDashboardConfigs()
|
||||||
@@ -152,8 +168,12 @@ async function loadDashboardConfig() {
|
|||||||
// 按order的顺序对dashboardConfigs进行排序
|
// 按order的顺序对dashboardConfigs进行排序
|
||||||
function sortDashboardConfigs() {
|
function sortDashboardConfigs() {
|
||||||
dashboardConfigs.value.sort((a, b) => {
|
dashboardConfigs.value.sort((a, b) => {
|
||||||
const aIndex = orderConfig.value.findIndex((item: { id: string, key: string }) => item.id === a.id && item.key === a.key)
|
const aIndex = orderConfig.value.findIndex(
|
||||||
const bIndex = orderConfig.value.findIndex((item: { id: string, key: string }) => item.id === b.id && item.key === b.key)
|
(item: { id: string; key: string }) => item.id === a.id && item.key === a.key,
|
||||||
|
)
|
||||||
|
const bIndex = orderConfig.value.findIndex(
|
||||||
|
(item: { id: string; key: string }) => item.id === b.id && item.key === b.key,
|
||||||
|
)
|
||||||
return (aIndex === -1 ? 999 : aIndex) - (bIndex === -1 ? 999 : bIndex)
|
return (aIndex === -1 ? 999 : aIndex) - (bIndex === -1 ? 999 : bIndex)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -166,6 +186,8 @@ function saveDashboardConfig() {
|
|||||||
// 顺序配置,从dashboardConfigs中提取
|
// 顺序配置,从dashboardConfigs中提取
|
||||||
const order = JSON.stringify(dashboardConfigs.value.map(item => ({ id: item.id, key: item.key })))
|
const order = JSON.stringify(dashboardConfigs.value.map(item => ({ id: item.id, key: item.key })))
|
||||||
localStorage.setItem('MP_DASHBOARD_ORDER', order)
|
localStorage.setItem('MP_DASHBOARD_ORDER', order)
|
||||||
|
// 是否拉升高度
|
||||||
|
localStorage.setItem('MP_DASHBOARD_ELEVATED', isElevated.value.toString())
|
||||||
// 保存到服务端
|
// 保存到服务端
|
||||||
try {
|
try {
|
||||||
api.post('/user/config/Dashboard', data, {
|
api.post('/user/config/Dashboard', data, {
|
||||||
@@ -200,7 +222,7 @@ async function getPluginDashboardMeta() {
|
|||||||
try {
|
try {
|
||||||
if (!isNullOrEmptyObject(pluginDashboardMeta.value)) {
|
if (!isNullOrEmptyObject(pluginDashboardMeta.value)) {
|
||||||
// 下载插件仪表板配置
|
// 下载插件仪表板配置
|
||||||
pluginDashboardMeta.value.forEach(async (pluginDashboard: { id: string, key: string }) => {
|
pluginDashboardMeta.value.forEach(async (pluginDashboard: { id: string; key: string }) => {
|
||||||
const pluginDashboardId = buildPluginDashboardId(pluginDashboard.id, pluginDashboard.key)
|
const pluginDashboardId = buildPluginDashboardId(pluginDashboard.id, pluginDashboard.key)
|
||||||
// 初始化插件仪表板的刷新状态
|
// 初始化插件仪表板的刷新状态
|
||||||
pluginDashboardRefreshStatus.value[pluginDashboardId] = true
|
pluginDashboardRefreshStatus.value[pluginDashboardId] = true
|
||||||
@@ -219,10 +241,14 @@ async function getPluginDashboard(id: string, key: string) {
|
|||||||
api.get(url).then((res: any) => {
|
api.get(url).then((res: any) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
// 名称替换为元信息的名称
|
// 名称替换为元信息的名称
|
||||||
const meta = pluginDashboardMeta.value.find((item: { id: string, key: string }) => item.id === id && item.key === key)
|
const meta = pluginDashboardMeta.value.find(
|
||||||
|
(item: { id: string; key: string }) => item.id === id && item.key === key,
|
||||||
|
)
|
||||||
if (meta) res.name = meta.name
|
if (meta) res.name = meta.name
|
||||||
// 保存到仪表板配置中,如果已经存在则替换
|
// 保存到仪表板配置中,如果已经存在则替换
|
||||||
const index = dashboardConfigs.value.findIndex((item: { id: string, key: string }) => item.id === id && item.key === key)
|
const index = dashboardConfigs.value.findIndex(
|
||||||
|
(item: { id: string; key: string }) => item.id === id && item.key === key,
|
||||||
|
)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
dashboardConfigs.value[index] = res
|
dashboardConfigs.value[index] = res
|
||||||
} else {
|
} else {
|
||||||
@@ -232,10 +258,20 @@ async function getPluginDashboard(id: string, key: string) {
|
|||||||
}
|
}
|
||||||
const pluginDashboardId = buildPluginDashboardId(id, key)
|
const pluginDashboardId = buildPluginDashboardId(id, key)
|
||||||
// 定时刷新
|
// 定时刷新
|
||||||
if (res.attrs?.refresh && pluginDashboardRefreshStatus.value[pluginDashboardId] && enableConfig.value[pluginDashboardId]) {
|
if (
|
||||||
setTimeout(() => {
|
res.attrs?.refresh &&
|
||||||
|
pluginDashboardRefreshStatus.value[pluginDashboardId] &&
|
||||||
|
enableConfig.value[pluginDashboardId]
|
||||||
|
) {
|
||||||
|
// 清除之前的定时器
|
||||||
|
if (refreshTimers.value[pluginDashboardId]) {
|
||||||
|
clearTimeout(refreshTimers.value[pluginDashboardId])
|
||||||
|
}
|
||||||
|
// 设置新的定时器
|
||||||
|
let timer = setTimeout(() => {
|
||||||
getPluginDashboard(id, key)
|
getPluginDashboard(id, key)
|
||||||
}, res.attrs.refresh * 1000)
|
}, res.attrs.refresh * 1000)
|
||||||
|
refreshTimers.value[pluginDashboardId] = timer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -264,11 +300,14 @@ onBeforeMount(async () => {
|
|||||||
handle=".cursor-move"
|
handle=".cursor-move"
|
||||||
item-key="id"
|
item-key="id"
|
||||||
tag="VRow"
|
tag="VRow"
|
||||||
:component-data="{ 'class': 'match-height' }"
|
:component-data="elevatedConf"
|
||||||
>
|
>
|
||||||
<template #item="{ element }">
|
<template #item="{ element }">
|
||||||
<VCol v-if="enableConfig[buildPluginDashboardId(element.id, element.key)] && element.cols" v-bind:="element.cols">
|
<VCol v-if="enableConfig[buildPluginDashboardId(element.id, element.key)] && element.cols" v-bind:="element.cols">
|
||||||
<DashboardElement :config="element" v-model:refreshStatus="pluginDashboardRefreshStatus[buildPluginDashboardId(element.id, element.key)]" />
|
<DashboardElement
|
||||||
|
:config="element"
|
||||||
|
v-model:refreshStatus="pluginDashboardRefreshStatus[buildPluginDashboardId(element.id, element.key)]"
|
||||||
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
@@ -285,8 +324,22 @@ onBeforeMount(async () => {
|
|||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText>
|
<VCardText>
|
||||||
<VRow>
|
<VRow>
|
||||||
<VCol v-for="item in dashboardConfigs" :key="buildPluginDashboardId(item.id, item.key)" cols="6" md="4" sm="4">
|
<VCol
|
||||||
<VCheckbox v-model="enableConfig[buildPluginDashboardId(item.id, item.key)]" :label="item.attrs?.title ?? item.name" />
|
v-for="item in dashboardConfigs"
|
||||||
|
:key="buildPluginDashboardId(item.id, item.key)"
|
||||||
|
cols="6"
|
||||||
|
md="4"
|
||||||
|
sm="4"
|
||||||
|
>
|
||||||
|
<VCheckbox
|
||||||
|
v-model="enableConfig[buildPluginDashboardId(item.id, item.key)]"
|
||||||
|
:label="item.attrs?.title ?? item.name"
|
||||||
|
/>
|
||||||
|
</VCol>
|
||||||
|
</VRow>
|
||||||
|
<VRow>
|
||||||
|
<VCol cols="12" md="6">
|
||||||
|
<VSwitch v-model="isElevated" label="高度拉升" />
|
||||||
</VCol>
|
</VCol>
|
||||||
</VRow>
|
</VRow>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
|
|||||||
Reference in New Issue
Block a user