mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-07 00:36:41 +08:00
重构 DirectoryCard 组件,替换 VPathField 为 PathInput;删除不再使用的 PathField 组件;更新 CronInput 组件以支持 v-model 绑定;添加 CronField 组件以简化 CRON 表达式输入
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { TransferDirectoryConf } from '@/api/types'
|
import type { TransferDirectoryConf } from '@/api/types'
|
||||||
import { VDivider, VSpacer, VTextField } from 'vuetify/lib/components/index.mjs'
|
import PathInput from '@/components/input/PathInput.vue'
|
||||||
import api from '@/api'
|
import api from '@/api'
|
||||||
import { nextTick } from 'vue'
|
import { nextTick } from 'vue'
|
||||||
import { storageOptions } from '@/api/constants'
|
import { storageOptions } from '@/api/constants'
|
||||||
@@ -210,7 +210,7 @@ watch(
|
|||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="8">
|
<VCol cols="8">
|
||||||
<VPathField v-model="props.directory.download_path" :storage="props.directory.storage">
|
<PathInput v-model="props.directory.download_path" :storage="props.directory.storage">
|
||||||
<template #activator="{ menuprops }">
|
<template #activator="{ menuprops }">
|
||||||
<VTextField
|
<VTextField
|
||||||
:model-value="props.directory.download_path"
|
:model-value="props.directory.download_path"
|
||||||
@@ -219,7 +219,7 @@ watch(
|
|||||||
label="下载目录/源目录"
|
label="下载目录/源目录"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</VPathField>
|
</PathInput>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="6" v-if="!props.directory.media_type || props.directory.media_type === ''">
|
<VCol cols="6" v-if="!props.directory.media_type || props.directory.media_type === ''">
|
||||||
<VSwitch v-model="props.directory.download_type_folder" label="按类型分类"></VSwitch>
|
<VSwitch v-model="props.directory.download_type_folder" label="按类型分类"></VSwitch>
|
||||||
@@ -257,7 +257,7 @@ watch(
|
|||||||
/>
|
/>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="8">
|
<VCol cols="8">
|
||||||
<VPathField v-model="props.directory.library_path" :storage="props.directory.library_storage">
|
<PathInput v-model="props.directory.library_path" :storage="props.directory.library_storage">
|
||||||
<template #activator="{ menuprops }">
|
<template #activator="{ menuprops }">
|
||||||
<VTextField
|
<VTextField
|
||||||
:modelValue="props.directory.library_path"
|
:modelValue="props.directory.library_path"
|
||||||
@@ -266,7 +266,7 @@ watch(
|
|||||||
label="媒体库目录"
|
label="媒体库目录"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</VPathField>
|
</PathInput>
|
||||||
</VCol>
|
</VCol>
|
||||||
<VCol cols="4">
|
<VCol cols="4">
|
||||||
<VSelect
|
<VSelect
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import CronInput from '@/components/input/CronInput.vue'
|
||||||
|
|
||||||
|
const attrs = useAttrs()
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: '* * * * *',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
|
const innerValue = ref(props.modelValue)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
value => {
|
||||||
|
innerValue.value = value
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
const propsWithoutModelValue = computed(() => {
|
||||||
|
const { modelValue, ...rest } = props
|
||||||
|
return { ...rest, ...attrs }
|
||||||
|
})
|
||||||
|
|
||||||
|
function updateModelValue(value: string) {
|
||||||
|
innerValue.value = value
|
||||||
|
emit('update:modelValue', value)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<CronInput v-model="innerValue" @update:modelValue="updateModelValue">
|
||||||
|
<template #activator="{ menuprops }">
|
||||||
|
<VTextField
|
||||||
|
:modelValue="innerValue"
|
||||||
|
@update:modelValue="updateModelValue"
|
||||||
|
v-bind="{ ...menuprops, ...propsWithoutModelValue }"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</CronInput>
|
||||||
|
</template>
|
||||||
@@ -3,7 +3,7 @@ import api from '@/api'
|
|||||||
import { FileItem } from '@/api/types'
|
import { FileItem } from '@/api/types'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
cron: {
|
modelValue: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '* * * * *',
|
default: '* * * * *',
|
||||||
},
|
},
|
||||||
@@ -14,8 +14,15 @@ const emit = defineEmits(['update:modelValue'])
|
|||||||
const currentCron = ref(props.cron)
|
const currentCron = ref(props.cron)
|
||||||
|
|
||||||
watch(currentCron, newVal => {
|
watch(currentCron, newVal => {
|
||||||
emit('update:modelValue', currentCron.value)
|
emit('update:modelValue', newVal)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
value => {
|
||||||
|
currentCron.value = value
|
||||||
|
},
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -24,7 +31,11 @@ watch(currentCron, newVal => {
|
|||||||
<template v-slot:activator="{ props }">
|
<template v-slot:activator="{ props }">
|
||||||
<slot name="activator" :menuprops="props" />
|
<slot name="activator" :menuprops="props" />
|
||||||
</template>
|
</template>
|
||||||
<VCronVuetify v-model="currentCron" locale="zh-CN" :chip-props="{ color: 'success' }" class="mt-1" />
|
<VList>
|
||||||
|
<VListItem>
|
||||||
|
<VCronVuetify v-model="currentCron" locale="zh-CN" :chip-props="{ color: 'success' }" class="mt-1" />
|
||||||
|
</VListItem>
|
||||||
|
</VList>
|
||||||
</VMenu>
|
</VMenu>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ const renderComponent = (config: any, model: any, slotScope: any = {}) => {
|
|||||||
<template>
|
<template>
|
||||||
<!-- 调用递归渲染函数 -->
|
<!-- 调用递归渲染函数 -->
|
||||||
<div>
|
<div>
|
||||||
<component :is="renderComponent(config, model)" />
|
<Component v-if="config.html" :is="config.component" v-bind="config.props" v-html="config.html" />
|
||||||
|
<Component v-else :is="renderComponent(config, model)" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
+10
-12
@@ -3,6 +3,14 @@ import '@/@core/utils/compatibility'
|
|||||||
import '@/@iconify/icons-bundle'
|
import '@/@iconify/icons-bundle'
|
||||||
import '@/plugins/webfontloader'
|
import '@/plugins/webfontloader'
|
||||||
|
|
||||||
|
import { createApp } from 'vue'
|
||||||
|
import { VAceEditor } from 'vue3-ace-editor'
|
||||||
|
import { PerfectScrollbarPlugin } from 'vue3-perfect-scrollbar'
|
||||||
|
import { CronVuetify } from '@vue-js-cron/vuetify'
|
||||||
|
import { removeEl } from './@core/utils/dom'
|
||||||
|
import { fetchGlobalSettings } from './api'
|
||||||
|
import { isPWA } from './@core/utils/navigator'
|
||||||
|
|
||||||
import App from '@/App.vue'
|
import App from '@/App.vue'
|
||||||
import vuetify from '@/plugins/vuetify'
|
import vuetify from '@/plugins/vuetify'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
@@ -18,16 +26,7 @@ import PersonCard from './components/cards/PersonCard.vue'
|
|||||||
import MediaInfoCard from './components/cards/MediaInfoCard.vue'
|
import MediaInfoCard from './components/cards/MediaInfoCard.vue'
|
||||||
import TorrentCard from './components/cards/TorrentCard.vue'
|
import TorrentCard from './components/cards/TorrentCard.vue'
|
||||||
import MediaIdSelector from './components/misc/MediaIdSelector.vue'
|
import MediaIdSelector from './components/misc/MediaIdSelector.vue'
|
||||||
import PathField from './components/input/PathField.vue'
|
import CronField from './components/field/CronField.vue'
|
||||||
import CronInput from './components/input/CronInput.vue'
|
|
||||||
|
|
||||||
import { createApp } from 'vue'
|
|
||||||
import { VAceEditor } from 'vue3-ace-editor'
|
|
||||||
import { PerfectScrollbarPlugin } from 'vue3-perfect-scrollbar'
|
|
||||||
import { CronVuetify } from '@vue-js-cron/vuetify'
|
|
||||||
import { removeEl } from './@core/utils/dom'
|
|
||||||
import { fetchGlobalSettings } from './api'
|
|
||||||
import { isPWA } from './@core/utils/navigator'
|
|
||||||
|
|
||||||
import '@core/scss/template/index.scss'
|
import '@core/scss/template/index.scss'
|
||||||
import '@layouts/styles/index.scss'
|
import '@layouts/styles/index.scss'
|
||||||
@@ -70,8 +69,7 @@ initializeApp().then(() => {
|
|||||||
.component('VMediaInfoCard', MediaInfoCard)
|
.component('VMediaInfoCard', MediaInfoCard)
|
||||||
.component('VTorrentCard', TorrentCard)
|
.component('VTorrentCard', TorrentCard)
|
||||||
.component('VMediaIdSelector', MediaIdSelector)
|
.component('VMediaIdSelector', MediaIdSelector)
|
||||||
.component('VPathField', PathField)
|
.component('VCronField', CronField)
|
||||||
.component('VCronInput', CronInput)
|
|
||||||
|
|
||||||
// 注册插件
|
// 注册插件
|
||||||
app
|
app
|
||||||
|
|||||||
Reference in New Issue
Block a user