mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-07-13 00:11:37 +08:00
feat(plugin): support responsive federated config controls (#521)
This commit is contained in:
@@ -46,6 +46,14 @@ const isRefreshed = ref(false)
|
||||
// 渲染模式: 'vuetify' 或 'vue'
|
||||
const renderMode = ref('vuetify')
|
||||
|
||||
// 插件未声明布局偏好时沿用标准配置弹窗宽度。
|
||||
const dialogMaxWidth = ref('60rem')
|
||||
|
||||
interface PluginConfigLayout {
|
||||
/** 插件配置界面期望的最大宽度,使用合法 CSS 尺寸。 */
|
||||
maxWidth?: string
|
||||
}
|
||||
|
||||
// Vue 模式:动态加载的组件
|
||||
const dynamicComponent = defineAsyncComponent({
|
||||
// 工厂函数
|
||||
@@ -89,6 +97,7 @@ async function loadPluginUIData() {
|
||||
pluginFormItems = []
|
||||
pluginConfigForm.value = {}
|
||||
renderMode.value = 'vuetify'
|
||||
dialogMaxWidth.value = '60rem'
|
||||
|
||||
try {
|
||||
// 获取UI定义
|
||||
@@ -123,6 +132,12 @@ function handleVueComponentSave(newConfig: Record<string, any>) {
|
||||
savePluginConf()
|
||||
}
|
||||
|
||||
// 联邦配置组件可按自身布局密度覆盖宿主弹窗宽度。
|
||||
function handleVueComponentLayout(layout?: PluginConfigLayout | null) {
|
||||
const maxWidth = typeof layout?.maxWidth === 'string' ? layout.maxWidth.trim() : ''
|
||||
dialogMaxWidth.value = maxWidth || '60rem'
|
||||
}
|
||||
|
||||
// 调用API保存配置数据
|
||||
async function savePluginConf() {
|
||||
// 显示等待提示框
|
||||
@@ -148,7 +163,7 @@ onBeforeMount(async () => {
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<VDialog scrollable max-width="60rem" :fullscreen="!display.mdAndUp.value">
|
||||
<VDialog scrollable :max-width="dialogMaxWidth" :fullscreen="!display.mdAndUp.value">
|
||||
<!-- Vuetify 渲染模式 -->
|
||||
<VCard v-if="renderMode === 'vuetify'" :title="`${props.plugin?.plugin_name} - ${t('dialog.pluginConfig.title')}`">
|
||||
<VDialogCloseBtn @click="emit('close')" />
|
||||
@@ -192,6 +207,7 @@ onBeforeMount(async () => {
|
||||
:initial-config="pluginConfigForm"
|
||||
:api="api"
|
||||
@save="handleVueComponentSave"
|
||||
@layout="handleVueComponentLayout"
|
||||
@switch="emit('switch')"
|
||||
@close="emit('close')"
|
||||
/>
|
||||
|
||||
@@ -8,6 +8,11 @@ const props = defineProps({
|
||||
type: String,
|
||||
default: '* * * * *',
|
||||
},
|
||||
/** 是否允许直接清空 CRON。 */
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
@@ -39,7 +44,6 @@ function updateModelValue(value: string) {
|
||||
:modelValue="innerValue"
|
||||
@update:modelValue="updateModelValue"
|
||||
v-bind="{ ...menuprops, ...propsWithoutModelValue }"
|
||||
clearable
|
||||
/>
|
||||
</template>
|
||||
</CronInput>
|
||||
|
||||
@@ -7,6 +7,7 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue'])
|
||||
const { locale } = useI18n()
|
||||
|
||||
const menu = ref(false)
|
||||
const currentCron = ref(props.modelValue)
|
||||
@@ -14,6 +15,27 @@ const menuRoot = ref<HTMLElement>()
|
||||
const instance = getCurrentInstance()
|
||||
const menuContentClass = `cron-input-menu-${instance?.uid ?? 'default'}`
|
||||
const menuContentSelector = `.${menuContentClass}`
|
||||
const normalizedLocale = computed(() => locale.value.toLowerCase().replace(/_/g, '-'))
|
||||
const cronLocale = computed(() => normalizedLocale.value.startsWith('zh') ? 'zh-cn' : 'en')
|
||||
// vue-js-cron 没有内置繁体中文,只需覆盖简体词典中会显示的 Cron 专有字词。
|
||||
const cronCustomLocale = computed(() => normalizedLocale.value === 'zh-tw' ? {
|
||||
'*': {
|
||||
day: {
|
||||
value: { text: '{{value.alt}}號' },
|
||||
range: { text: '{{start.alt}}號-{{end.alt}}號' },
|
||||
},
|
||||
dayOfWeek: { empty: { text: '一週的每一天' } },
|
||||
hour: { empty: { text: '每小時' } },
|
||||
minute: { empty: { text: '每分鐘' } },
|
||||
},
|
||||
hour: {
|
||||
text: '小時',
|
||||
minute: { '*': { suffix: '分鐘' } },
|
||||
},
|
||||
week: { text: '週' },
|
||||
'q-minute': { text: '分鐘' },
|
||||
'q-hour': { text: '小時' },
|
||||
} : undefined)
|
||||
|
||||
function isCronMenuTarget(target: EventTarget | null) {
|
||||
if (!(target instanceof Element)) return false
|
||||
@@ -72,7 +94,14 @@ watch(
|
||||
</template>
|
||||
<VList>
|
||||
<VListItem>
|
||||
<VCronVuetify v-model="currentCron" locale="zh-CN" :chip-props="{ color: 'success' }" class="mt-1" />
|
||||
<VCronVuetify
|
||||
:key="locale"
|
||||
v-model="currentCron"
|
||||
:chip-props="{ color: 'success' }"
|
||||
class="mt-1"
|
||||
:custom-locale="cronCustomLocale"
|
||||
:locale="cronLocale"
|
||||
/>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VMenu>
|
||||
|
||||
Reference in New Issue
Block a user