mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 07:28:37 +08:00
refactor: implement collapsible side-by-side preview panel in ReorganizeDialog
This commit is contained in:
@@ -80,12 +80,12 @@ const progressSSE = ref<any>(null)
|
|||||||
// 预览加载状态
|
// 预览加载状态
|
||||||
const previewLoading = ref(false)
|
const previewLoading = ref(false)
|
||||||
|
|
||||||
|
// 预览面板显隐
|
||||||
|
const previewVisible = ref(false)
|
||||||
|
|
||||||
// 是否已加载预览
|
// 是否已加载预览
|
||||||
const previewLoaded = ref(false)
|
const previewLoaded = ref(false)
|
||||||
|
|
||||||
// 预览错误
|
|
||||||
const previewRequestError = ref('')
|
|
||||||
|
|
||||||
// 预览数据
|
// 预览数据
|
||||||
const previewData = ref<ManualTransferPreviewData>()
|
const previewData = ref<ManualTransferPreviewData>()
|
||||||
|
|
||||||
@@ -427,10 +427,18 @@ const previewNeedsWideLayout = computed(() => {
|
|||||||
// 弹窗宽度
|
// 弹窗宽度
|
||||||
const dialogMaxWidth = computed(() => {
|
const dialogMaxWidth = computed(() => {
|
||||||
if (!display.mdAndUp.value) return '100%'
|
if (!display.mdAndUp.value) return '100%'
|
||||||
const preferredWidth = previewLoaded.value && previewNeedsWideLayout.value ? '132rem' : '99rem'
|
|
||||||
|
if (!previewVisible.value) return 'min(45rem, calc(100vw - 2rem))'
|
||||||
|
|
||||||
|
const preferredWidth = previewNeedsWideLayout.value ? '126rem' : '110rem'
|
||||||
return `min(${preferredWidth}, calc(100vw - 2rem))`
|
return `min(${preferredWidth}, calc(100vw - 2rem))`
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 预览按钮图标
|
||||||
|
const previewToggleIcon = computed(() => {
|
||||||
|
return previewVisible.value ? 'mdi-eye-off-outline' : 'mdi-eye-outline'
|
||||||
|
})
|
||||||
|
|
||||||
// 构造整理请求
|
// 构造整理请求
|
||||||
function createTransferPayload(options: { item?: FileItem; logid?: number; preview?: boolean }) {
|
function createTransferPayload(options: { item?: FileItem; logid?: number; preview?: boolean }) {
|
||||||
const payload: ManualTransferPayload = {
|
const payload: ManualTransferPayload = {
|
||||||
@@ -464,6 +472,26 @@ function getDefaultPreviewData(): ManualTransferPreviewData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetPreviewState() {
|
||||||
|
previewData.value = undefined
|
||||||
|
previewLoaded.value = false
|
||||||
|
previewPage.value = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
function previewHasFailures(data?: ManualTransferPreviewData) {
|
||||||
|
if (!data) return false
|
||||||
|
|
||||||
|
return (data.summary.failed ?? 0) > 0 || (data.items ?? []).some(item => item.success === false)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPreviewFailureMessage(data?: ManualTransferPreviewData) {
|
||||||
|
return (
|
||||||
|
data?.items.find(item => item.success === false)?.message ||
|
||||||
|
data?.message ||
|
||||||
|
t('dialog.reorganize.previewRequestFailed')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// 合并多次预览结果
|
// 合并多次预览结果
|
||||||
function mergePreviewData(target: ManualTransferPreviewData, incoming?: ManualTransferPreviewData) {
|
function mergePreviewData(target: ManualTransferPreviewData, incoming?: ManualTransferPreviewData) {
|
||||||
if (!incoming) return
|
if (!incoming) return
|
||||||
@@ -485,31 +513,12 @@ function mergePreviewData(target: ManualTransferPreviewData, incoming?: ManualTr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendPreviewFailure(target: ManualTransferPreviewData, options: { source?: string; message?: string }) {
|
|
||||||
const message = options.message || t('dialog.reorganize.previewRequestFailed')
|
|
||||||
mergePreviewData(target, {
|
|
||||||
summary: {
|
|
||||||
total: 1,
|
|
||||||
success: 0,
|
|
||||||
failed: 1,
|
|
||||||
},
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
source: options.source,
|
|
||||||
success: false,
|
|
||||||
message,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
message,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 预览整理结果
|
// 预览整理结果
|
||||||
async function previewTransfer() {
|
async function previewTransfer() {
|
||||||
if (!props.logids && !props.items) return
|
if (!props.logids && !props.items) return
|
||||||
|
|
||||||
previewLoading.value = true
|
previewLoading.value = true
|
||||||
previewRequestError.value = ''
|
resetPreviewState()
|
||||||
|
|
||||||
const mergedPreviewData = getDefaultPreviewData()
|
const mergedPreviewData = getDefaultPreviewData()
|
||||||
|
|
||||||
@@ -523,15 +532,13 @@ async function previewTransfer() {
|
|||||||
const result = await requestManualTransfer<ManualTransferPreviewData>(
|
const result = await requestManualTransfer<ManualTransferPreviewData>(
|
||||||
createTransferPayload({ item, preview: true }),
|
createTransferPayload({ item, preview: true }),
|
||||||
)
|
)
|
||||||
if (result.success) {
|
if (!result.success) throw new Error(result.message || t('dialog.reorganize.previewRequestFailed'))
|
||||||
mergePreviewData(mergedPreviewData, result.data)
|
|
||||||
} else {
|
mergePreviewData(mergedPreviewData, result.data)
|
||||||
console.warn(`预览失败: ${result.message}`)
|
|
||||||
appendPreviewFailure(mergedPreviewData, { source: item.path, message: result.message })
|
|
||||||
}
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.warn(`预览请求异常: ${err?.message}`)
|
console.warn(`预览请求异常: ${err?.message}`)
|
||||||
appendPreviewFailure(mergedPreviewData, { source: item.path, message: err?.message })
|
const label = item.name || item.path
|
||||||
|
throw new Error(`${label}: ${err?.message || t('dialog.reorganize.previewRequestFailed')}`)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@@ -544,19 +551,12 @@ async function previewTransfer() {
|
|||||||
const result = await requestManualTransfer<ManualTransferPreviewData>(
|
const result = await requestManualTransfer<ManualTransferPreviewData>(
|
||||||
createTransferPayload({ logid, preview: true }),
|
createTransferPayload({ logid, preview: true }),
|
||||||
)
|
)
|
||||||
if (result.success) {
|
if (!result.success) throw new Error(result.message || t('dialog.reorganize.previewRequestFailed'))
|
||||||
mergePreviewData(mergedPreviewData, result.data)
|
|
||||||
} else {
|
mergePreviewData(mergedPreviewData, result.data)
|
||||||
console.warn(`预览失败: ${result.message}`)
|
|
||||||
appendPreviewFailure(mergedPreviewData, {
|
|
||||||
message: `历史记录 ${logid}: ${result.message || t('dialog.reorganize.previewRequestFailed')}`,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.warn(`预览请求异常: ${err?.message}`)
|
console.warn(`预览请求异常: ${err?.message}`)
|
||||||
appendPreviewFailure(mergedPreviewData, {
|
throw new Error(`历史记录 ${logid}: ${err?.message || t('dialog.reorganize.previewRequestFailed')}`)
|
||||||
message: `历史记录 ${logid}: ${err?.message || t('dialog.reorganize.previewRequestFailed')}`,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@@ -564,17 +564,34 @@ async function previewTransfer() {
|
|||||||
|
|
||||||
await Promise.all(tasks)
|
await Promise.all(tasks)
|
||||||
|
|
||||||
|
if (previewHasFailures(mergedPreviewData)) {
|
||||||
|
throw new Error(getPreviewFailureMessage(mergedPreviewData))
|
||||||
|
}
|
||||||
|
|
||||||
previewData.value = mergedPreviewData
|
previewData.value = mergedPreviewData
|
||||||
previewLoaded.value = true
|
previewLoaded.value = true
|
||||||
nextTick(() => updatePreviewPageSize())
|
nextTick(() => updatePreviewPageSize())
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
previewRequestError.value = error?.message || t('dialog.reorganize.previewRequestFailed')
|
previewVisible.value = false
|
||||||
$toast.error(t('dialog.reorganize.previewRequestFailed'))
|
resetPreviewState()
|
||||||
|
$toast.error(error?.message || t('dialog.reorganize.previewRequestFailed'))
|
||||||
} finally {
|
} finally {
|
||||||
previewLoading.value = false
|
previewLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function togglePreview() {
|
||||||
|
if (previewLoading.value) return
|
||||||
|
|
||||||
|
if (previewVisible.value) {
|
||||||
|
previewVisible.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
previewVisible.value = true
|
||||||
|
await previewTransfer()
|
||||||
|
}
|
||||||
|
|
||||||
// 根据可用高度自动计算每页条数,保持统一行高
|
// 根据可用高度自动计算每页条数,保持统一行高
|
||||||
function updatePreviewPageSize() {
|
function updatePreviewPageSize() {
|
||||||
const bodyHeight = previewFileBodyRef.value?.clientHeight ?? 0
|
const bodyHeight = previewFileBodyRef.value?.clientHeight ?? 0
|
||||||
@@ -603,19 +620,16 @@ function setupPreviewFileBodyObserver() {
|
|||||||
previewFileBodyResizeObserver.observe(previewFileBodyRef.value)
|
previewFileBodyResizeObserver.observe(previewFileBodyRef.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch([() => previewLoaded.value, () => previewVisible.value], ([loaded, visible]) => {
|
||||||
() => previewLoaded.value,
|
if (loaded && visible) {
|
||||||
loaded => {
|
nextTick(() => {
|
||||||
if (loaded) {
|
setupPreviewFileBodyObserver()
|
||||||
nextTick(() => {
|
updatePreviewPageSize()
|
||||||
setupPreviewFileBodyObserver()
|
})
|
||||||
updatePreviewPageSize()
|
} else {
|
||||||
})
|
previewFileBodyResizeObserver?.disconnect()
|
||||||
} else {
|
}
|
||||||
previewFileBodyResizeObserver?.disconnect()
|
})
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
// 整理文件
|
// 整理文件
|
||||||
async function handleTransfer(item: FileItem, background: boolean = false) {
|
async function handleTransfer(item: FileItem, background: boolean = false) {
|
||||||
@@ -729,8 +743,8 @@ onUnmounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VDialog scrollable :max-width="dialogMaxWidth" :fullscreen="!display.mdAndUp.value">
|
<VDialog :scrollable="!previewVisible || !display.mdAndUp.value" :max-width="dialogMaxWidth" :fullscreen="!display.mdAndUp.value">
|
||||||
<VCard class="reorganize-dialog-card">
|
<VCard class="reorganize-dialog-card" :class="{ 'reorganize-dialog-card--split': previewVisible && display.mdAndUp.value }">
|
||||||
<VCardItem class="py-2">
|
<VCardItem class="py-2">
|
||||||
<template #prepend> <VIcon icon="mdi-folder-move" class="me-2" /> </template>
|
<template #prepend> <VIcon icon="mdi-folder-move" class="me-2" /> </template>
|
||||||
<VCardTitle>{{ dialogTitle }}</VCardTitle>
|
<VCardTitle>{{ dialogTitle }}</VCardTitle>
|
||||||
@@ -738,8 +752,8 @@ onUnmounted(() => {
|
|||||||
</VCardItem>
|
</VCardItem>
|
||||||
<VDialogCloseBtn @click="emit('close')" />
|
<VDialogCloseBtn @click="emit('close')" />
|
||||||
<VDivider />
|
<VDivider />
|
||||||
<VCardText class="pa-0">
|
<VCardText class="pa-0 reorganize-dialog-card__body">
|
||||||
<div class="reorganize-main-row">
|
<div class="reorganize-main-row" :class="{ 'reorganize-main-row--preview-visible': previewVisible }">
|
||||||
<div class="reorganize-form-pane">
|
<div class="reorganize-form-pane">
|
||||||
<div class="reorganize-form-pane__content pa-6">
|
<div class="reorganize-form-pane__content pa-6">
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
@@ -938,10 +952,12 @@ onUnmounted(() => {
|
|||||||
</VForm>
|
</VForm>
|
||||||
<VCardActions class="reorganize-form-pane__actions pt-3 px-0 pb-0">
|
<VCardActions class="reorganize-form-pane__actions pt-3 px-0 pb-0">
|
||||||
<VBtn
|
<VBtn
|
||||||
color="primary"
|
color="info"
|
||||||
@click="previewTransfer"
|
:variant="previewVisible ? 'tonal' : 'text'"
|
||||||
prepend-icon="mdi-eye-outline"
|
@click="togglePreview"
|
||||||
|
:prepend-icon="previewToggleIcon"
|
||||||
class="reorganize-action-btn reorganize-action-btn--preview"
|
class="reorganize-action-btn reorganize-action-btn--preview"
|
||||||
|
:class="{ 'reorganize-action-btn--active': previewVisible }"
|
||||||
:loading="previewLoading"
|
:loading="previewLoading"
|
||||||
>
|
>
|
||||||
{{ t('dialog.reorganize.previewResult') }}
|
{{ t('dialog.reorganize.previewResult') }}
|
||||||
@@ -964,122 +980,119 @@ onUnmounted(() => {
|
|||||||
</VCardActions>
|
</VCardActions>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="reorganize-preview-pane">
|
<div v-show="previewVisible" class="reorganize-preview-pane">
|
||||||
<div class="reorganize-preview-pane__header">
|
<div class="reorganize-preview-pane__header">
|
||||||
<div class="reorganize-preview-pane__header-main">
|
<div class="reorganize-preview-pane__title-block">
|
||||||
<div class="reorganize-preview-pane__title-block">
|
<div class="reorganize-preview-pane__title-row">
|
||||||
<div class="reorganize-preview-pane__title-row">
|
<div class="text-h6">{{ t('dialog.reorganize.previewTitle') }}</div>
|
||||||
<div class="text-h6">{{ t('dialog.reorganize.previewTitle') }}</div>
|
<div v-if="previewLoaded" class="preview-title-stats">
|
||||||
<div v-if="previewLoaded" class="preview-title-stats">
|
<VChip color="primary" variant="tonal" size="small">
|
||||||
<VChip color="primary" variant="tonal" size="small">
|
{{ t('dialog.reorganize.previewTotal', { count: previewSummary.total }) }}
|
||||||
{{ t('dialog.reorganize.previewTotal', { count: previewSummary.total }) }}
|
</VChip>
|
||||||
</VChip>
|
<VChip color="success" variant="tonal" size="small">
|
||||||
<VChip color="success" variant="tonal" size="small">
|
{{ t('dialog.reorganize.previewSuccess', { count: previewSummary.success }) }}
|
||||||
{{ t('dialog.reorganize.previewSuccess', { count: previewSummary.success }) }}
|
</VChip>
|
||||||
</VChip>
|
<VChip color="error" variant="tonal" size="small">
|
||||||
<VChip color="error" variant="tonal" size="small">
|
{{ t('dialog.reorganize.previewFailed', { count: previewSummary.failed }) }}
|
||||||
{{ t('dialog.reorganize.previewFailed', { count: previewSummary.failed }) }}
|
</VChip>
|
||||||
</VChip>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="previewLoaded" class="reorganize-preview-pane__overview">
|
<div class="text-body-2 text-medium-emphasis mt-2">
|
||||||
<div class="preview-overview-card">
|
{{ t('dialog.reorganize.previewSubtitle') }}
|
||||||
<span class="preview-overview-card__label">{{ t('dialog.reorganize.previewMediaName') }}</span>
|
|
||||||
<span class="preview-overview-card__value">{{ previewMediaInfo.title }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="preview-overview-card">
|
|
||||||
<span class="preview-overview-card__label">{{ t('dialog.reorganize.previewMediaType') }}</span>
|
|
||||||
<span class="preview-overview-card__value">{{ previewMediaInfo.type }}</span>
|
|
||||||
</div>
|
|
||||||
<div v-if="!previewIsMovie" class="preview-overview-card">
|
|
||||||
<span class="preview-overview-card__label">{{ t('dialog.reorganize.previewSeasonLabel') }}</span>
|
|
||||||
<span class="preview-overview-card__value">{{ previewSeasonText }}</span>
|
|
||||||
</div>
|
|
||||||
<div v-if="!previewIsMovie" class="preview-overview-card">
|
|
||||||
<span class="preview-overview-card__label">{{ t('dialog.reorganize.previewEpisodeCount') }}</span>
|
|
||||||
<span class="preview-overview-card__value">{{ previewEpisodeCountText }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<VAlert v-if="previewRequestError" type="error" variant="tonal" class="mx-4 mb-4">
|
<div class="reorganize-preview-pane__body">
|
||||||
{{ previewRequestError }}
|
<div v-if="previewLoading" class="reorganize-preview-pane__loading">
|
||||||
</VAlert>
|
<VProgressCircular indeterminate color="info" />
|
||||||
<div v-if="previewLoading" class="reorganize-preview-pane__loading">
|
<div class="text-body-2 text-medium-emphasis mt-3">{{ t('dialog.reorganize.previewLoading') }}</div>
|
||||||
<VProgressCircular indeterminate color="primary" />
|
</div>
|
||||||
<div class="text-body-2 text-medium-emphasis mt-3">{{ t('dialog.reorganize.previewLoading') }}</div>
|
<template v-else-if="previewLoaded">
|
||||||
</div>
|
<div class="reorganize-preview-pane__scroll">
|
||||||
<template v-else-if="previewLoaded">
|
<div class="reorganize-preview-pane__summary">
|
||||||
<VAlert v-if="previewData?.message" type="info" variant="tonal" density="comfortable" class="mx-4 mb-4">
|
<div v-if="previewData?.message" class="preview-note">
|
||||||
{{ previewData.message }}
|
{{ previewData.message }}
|
||||||
</VAlert>
|
|
||||||
<div class="reorganize-preview-pane__scroll">
|
|
||||||
<div class="reorganize-preview-list">
|
|
||||||
<div class="preview-file-header">
|
|
||||||
<div class="preview-file-header__cell preview-file-header__cell--target">
|
|
||||||
{{ t('dialog.reorganize.previewAfterColumn') }}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="preview-file-header__cell preview-file-header__cell--source">
|
<div class="preview-summary-grid">
|
||||||
{{ t('dialog.reorganize.previewBeforeColumn') }}
|
<div class="preview-overview-card preview-overview-card--path">
|
||||||
</div>
|
<span class="preview-overview-card__label">{{ t('dialog.reorganize.previewSourcePath') }}</span>
|
||||||
</div>
|
<span class="preview-overview-card__value preview-overview-card__value--path">{{
|
||||||
<div v-if="pagedPreviewRows.length" ref="previewFileBodyRef" class="preview-file-body">
|
previewSourcePath
|
||||||
<div class="preview-file-panel preview-file-panel--target">
|
}}</span>
|
||||||
<div class="preview-file-panel__scroll">
|
|
||||||
<div class="preview-file-panel__content">
|
|
||||||
<div
|
|
||||||
v-for="(item, index) in pagedPreviewRows"
|
|
||||||
:key="`target-${item.source}-${index}`"
|
|
||||||
class="preview-file-row"
|
|
||||||
>
|
|
||||||
<span class="preview-file-text">{{ item.targetName }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="preview-overview-card preview-overview-card--path">
|
||||||
<div class="preview-file-panel preview-file-panel--source">
|
<span class="preview-overview-card__label">{{ t('dialog.reorganize.previewTargetPath') }}</span>
|
||||||
<div class="preview-file-panel__scroll">
|
<span class="preview-overview-card__value preview-overview-card__value--path">{{
|
||||||
<div class="preview-file-panel__content">
|
previewTargetPath
|
||||||
<div
|
}}</span>
|
||||||
v-for="(item, index) in pagedPreviewRows"
|
</div>
|
||||||
:key="`source-${item.source}-${index}`"
|
<div class="preview-overview-card">
|
||||||
class="preview-file-row"
|
<span class="preview-overview-card__label">{{ t('dialog.reorganize.previewMediaName') }}</span>
|
||||||
>
|
<span class="preview-overview-card__value">{{ previewMediaInfo.title }}</span>
|
||||||
<span class="preview-file-text">{{ item.sourceName }}</span>
|
</div>
|
||||||
</div>
|
<div class="preview-overview-card">
|
||||||
</div>
|
<span class="preview-overview-card__label">{{ t('dialog.reorganize.previewMediaType') }}</span>
|
||||||
|
<span class="preview-overview-card__value">{{ previewMediaInfo.type }}</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="!previewIsMovie" class="preview-overview-card">
|
||||||
|
<span class="preview-overview-card__label">{{
|
||||||
|
t('dialog.reorganize.previewSeasonLabel')
|
||||||
|
}}</span>
|
||||||
|
<span class="preview-overview-card__value">{{ previewSeasonText }}</span>
|
||||||
|
</div>
|
||||||
|
<div v-if="!previewIsMovie" class="preview-overview-card">
|
||||||
|
<span class="preview-overview-card__label">{{
|
||||||
|
t('dialog.reorganize.previewEpisodeCount')
|
||||||
|
}}</span>
|
||||||
|
<span class="preview-overview-card__value">{{ previewEpisodeCountText }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="reorganize-preview-list__empty">
|
<div class="reorganize-preview-list">
|
||||||
{{ t('dialog.reorganize.noPreviewData') }}
|
<div v-if="pagedPreviewRows.length" ref="previewFileBodyRef" class="preview-file-body">
|
||||||
|
<div
|
||||||
|
v-for="(item, index) in pagedPreviewRows"
|
||||||
|
:key="`${item.source}-${item.target}-${index}`"
|
||||||
|
class="preview-file-row"
|
||||||
|
>
|
||||||
|
<div class="preview-file-row__card preview-file-row__card--source">
|
||||||
|
<span class="preview-file-row__label">{{ t('dialog.reorganize.previewBeforeColumn') }}</span>
|
||||||
|
<span class="preview-file-row__name">{{ item.sourceName }}</span>
|
||||||
|
<span class="preview-file-row__path">{{ item.source || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="preview-file-row__arrow">
|
||||||
|
<VIcon icon="mdi-arrow-right" size="18" />
|
||||||
|
</div>
|
||||||
|
<div class="preview-file-row__card preview-file-row__card--target">
|
||||||
|
<span class="preview-file-row__label">{{ t('dialog.reorganize.previewAfterColumn') }}</span>
|
||||||
|
<span class="preview-file-row__name">{{ item.targetName }}</span>
|
||||||
|
<span class="preview-file-row__path">{{ item.target || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else class="reorganize-preview-list__empty">
|
||||||
|
{{ t('dialog.reorganize.noPreviewData') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="previewTotalPages > 1" class="reorganize-preview-pane__pagination">
|
||||||
|
<VBtn
|
||||||
|
size="x-small"
|
||||||
|
icon="mdi-chevron-left"
|
||||||
|
variant="text"
|
||||||
|
:disabled="previewPage <= 1"
|
||||||
|
@click="previewPage--"
|
||||||
|
/>
|
||||||
|
<span class="text-caption">{{ previewPage }} / {{ previewTotalPages }}</span>
|
||||||
|
<VBtn
|
||||||
|
size="x-small"
|
||||||
|
icon="mdi-chevron-right"
|
||||||
|
variant="text"
|
||||||
|
:disabled="previewPage >= previewTotalPages"
|
||||||
|
@click="previewPage++"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="previewTotalPages > 1" class="reorganize-preview-pane__pagination">
|
</template>
|
||||||
<VBtn
|
|
||||||
size="x-small"
|
|
||||||
icon="mdi-chevron-left"
|
|
||||||
variant="text"
|
|
||||||
:disabled="previewPage <= 1"
|
|
||||||
@click="previewPage--"
|
|
||||||
/>
|
|
||||||
<span class="text-caption">{{ previewPage }} / {{ previewTotalPages }}</span>
|
|
||||||
<VBtn
|
|
||||||
size="x-small"
|
|
||||||
icon="mdi-chevron-right"
|
|
||||||
variant="text"
|
|
||||||
:disabled="previewPage >= previewTotalPages"
|
|
||||||
@click="previewPage++"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div v-else class="reorganize-preview-pane__empty">
|
|
||||||
<div class="text-subtitle-1">{{ t('dialog.reorganize.previewEmptyTitle') }}</div>
|
|
||||||
<div class="text-body-2 text-medium-emphasis mt-2">
|
|
||||||
{{ t('dialog.reorganize.previewEmptyDescription') }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1106,32 +1119,73 @@ onUnmounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.reorganize-dialog-card {
|
||||||
|
max-block-size: min(92vh, 64rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reorganize-dialog-card__body {
|
||||||
|
min-block-size: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reorganize-dialog-card--split {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
block-size: min(92vh, 64rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reorganize-dialog-card--split .reorganize-dialog-card__body {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reorganize-dialog-card--split .reorganize-main-row {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
block-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.reorganize-main-row {
|
.reorganize-main-row {
|
||||||
display: grid;
|
display: grid;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
grid-template-columns: 45% 55%;
|
grid-template-columns: minmax(0, 1fr);
|
||||||
|
min-block-size: 0;
|
||||||
inline-size: 100%;
|
inline-size: 100%;
|
||||||
|
transition: grid-template-columns 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
@media (width <= 959px) {
|
.reorganize-main-row--preview-visible {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.reorganize-form-pane {
|
.reorganize-form-pane {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border-inline-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
min-block-size: 0;
|
||||||
max-inline-size: none;
|
max-inline-size: none;
|
||||||
min-inline-size: 0;
|
min-inline-size: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reorganize-main-row--preview-visible .reorganize-form-pane {
|
||||||
|
border-inline-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
||||||
|
}
|
||||||
|
|
||||||
.reorganize-form-pane__content {
|
.reorganize-form-pane__content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-block-size: 100%;
|
min-block-size: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reorganize-dialog-card--split .reorganize-form-pane,
|
||||||
|
.reorganize-dialog-card--split .reorganize-preview-pane {
|
||||||
|
block-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reorganize-dialog-card--split .reorganize-form-pane__content {
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reorganize-form-pane__actions {
|
.reorganize-form-pane__actions {
|
||||||
@@ -1146,10 +1200,16 @@ onUnmounted(() => {
|
|||||||
min-inline-size: 0;
|
min-inline-size: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reorganize-action-btn--active {
|
||||||
|
background: rgba(var(--v-theme-info), 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
.reorganize-preview-pane {
|
.reorganize-preview-pane {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
background: rgb(var(--v-theme-surface));
|
||||||
|
min-block-size: 0;
|
||||||
min-inline-size: 0;
|
min-inline-size: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1164,15 +1224,8 @@ onUnmounted(() => {
|
|||||||
padding-inline: 1.5rem;
|
padding-inline: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reorganize-preview-pane__header-main {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 0.875rem;
|
|
||||||
min-inline-size: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reorganize-preview-pane__title-block {
|
.reorganize-preview-pane__title-block {
|
||||||
|
flex: 1 1 auto;
|
||||||
min-inline-size: 0;
|
min-inline-size: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1183,11 +1236,12 @@ onUnmounted(() => {
|
|||||||
gap: 0.75rem 1rem;
|
gap: 0.75rem 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reorganize-preview-pane__overview {
|
.reorganize-preview-pane__body {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex: 1 1 auto;
|
||||||
gap: 0.75rem;
|
flex-direction: column;
|
||||||
min-inline-size: 0;
|
overflow: hidden;
|
||||||
|
min-block-size: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-title-stats {
|
.preview-title-stats {
|
||||||
@@ -1197,19 +1251,48 @@ onUnmounted(() => {
|
|||||||
min-inline-size: 0;
|
min-inline-size: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-overview-card {
|
.reorganize-preview-pane__summary {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1 1 12rem;
|
flex: 0 0 auto;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
gap: 0.875rem;
|
||||||
border-radius: 0.75rem;
|
padding-block-start: 1.25rem;
|
||||||
background: rgba(var(--v-theme-surface));
|
padding-inline: 1.5rem;
|
||||||
gap: 0.25rem;
|
}
|
||||||
min-inline-size: 0;
|
|
||||||
|
.preview-note {
|
||||||
|
border: 1px solid rgba(var(--v-theme-info), 0.16);
|
||||||
|
border-radius: 0.875rem;
|
||||||
|
background: rgba(var(--v-theme-info), 0.08);
|
||||||
|
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.5;
|
||||||
padding-block: 0.75rem;
|
padding-block: 0.75rem;
|
||||||
padding-inline: 0.875rem;
|
padding-inline: 0.875rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.preview-summary-grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.75rem;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-overview-card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
||||||
|
border-radius: 1rem;
|
||||||
|
background: rgb(var(--v-theme-surface));
|
||||||
|
gap: 0.375rem;
|
||||||
|
min-inline-size: 0;
|
||||||
|
padding-block: 0.875rem;
|
||||||
|
padding-inline: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-overview-card--path {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
|
||||||
.preview-overview-card__label {
|
.preview-overview-card__label {
|
||||||
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
|
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
@@ -1221,19 +1304,27 @@ onUnmounted(() => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: rgb(var(--v-theme-on-surface));
|
color: rgb(var(--v-theme-on-surface));
|
||||||
font-size: 0.9375rem;
|
font-size: 0.9375rem;
|
||||||
font-weight: 500;
|
font-weight: 600;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.preview-overview-card__value--path {
|
||||||
|
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
|
||||||
|
line-height: 1.5;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
text-overflow: clip;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
.reorganize-preview-pane__scroll {
|
.reorganize-preview-pane__scroll {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden auto;
|
overflow: hidden auto;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.75rem;
|
gap: 1rem;
|
||||||
min-block-size: 0;
|
min-block-size: 0;
|
||||||
padding-block-start: 0.75rem;
|
padding-block-end: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reorganize-preview-pane__pagination {
|
.reorganize-preview-pane__pagination {
|
||||||
@@ -1241,13 +1332,12 @@ onUnmounted(() => {
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border-block-start: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
|
||||||
gap: 0.25rem;
|
gap: 0.25rem;
|
||||||
padding-block: 0.5rem;
|
padding-block: 0 1rem;
|
||||||
|
padding-inline: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reorganize-preview-pane__loading,
|
.reorganize-preview-pane__loading {
|
||||||
.reorganize-preview-pane__empty {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -1258,118 +1348,101 @@ onUnmounted(() => {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.reorganize-preview-table {
|
|
||||||
padding-block: 0 1rem;
|
|
||||||
padding-inline: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reorganize-preview-list {
|
.reorganize-preview-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
overflow: visible;
|
||||||
flex: 1;
|
flex: 0 0 auto;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
||||||
|
border-radius: 1rem;
|
||||||
|
background: rgba(var(--v-theme-surface), 1);
|
||||||
|
margin-block-end: 1.5rem;
|
||||||
|
margin-inline: 1.5rem;
|
||||||
min-block-size: 0;
|
min-block-size: 0;
|
||||||
min-inline-size: 0;
|
min-inline-size: 0;
|
||||||
padding-block: 0 1rem;
|
|
||||||
padding-inline: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-file-header {
|
|
||||||
display: grid;
|
|
||||||
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
|
||||||
border-radius: 0.5rem 0.5rem 0 0;
|
|
||||||
background: rgba(var(--v-theme-surface));
|
|
||||||
border-block-end: none;
|
|
||||||
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
|
|
||||||
font-size: 0.875rem;
|
|
||||||
font-weight: 500;
|
|
||||||
grid-template-columns: 50% 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-file-header__cell {
|
|
||||||
padding-block: 0.75rem;
|
|
||||||
padding-inline: 0.75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-file-header__cell--target {
|
|
||||||
border-inline-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-file-body {
|
.preview-file-body {
|
||||||
display: grid;
|
|
||||||
overflow: hidden;
|
|
||||||
flex: 1 1 auto;
|
|
||||||
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
|
||||||
border-radius: 0 0 0.5rem 0.5rem;
|
|
||||||
grid-template-columns: 50% 50%;
|
|
||||||
min-block-size: 0;
|
|
||||||
min-inline-size: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-file-panel {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
overflow: visible;
|
||||||
|
flex: 0 0 auto;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
gap: 0.75rem;
|
||||||
min-block-size: 0;
|
min-block-size: 0;
|
||||||
min-inline-size: 0;
|
min-inline-size: 0;
|
||||||
}
|
padding-block: 1rem;
|
||||||
|
padding-inline: 1rem;
|
||||||
.preview-file-panel--target {
|
|
||||||
border-inline-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-file-panel__scroll {
|
|
||||||
overflow: auto hidden;
|
|
||||||
flex: 1 1 auto;
|
|
||||||
min-block-size: 0;
|
|
||||||
min-inline-size: 0;
|
|
||||||
scrollbar-color: rgba(var(--v-border-color), var(--v-border-opacity)) transparent;
|
|
||||||
scrollbar-width: thin;
|
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
block-size: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-track {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb {
|
|
||||||
border-radius: 2px;
|
|
||||||
background: rgba(var(--v-border-color), var(--v-border-opacity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-file-panel__content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
min-block-size: 100%;
|
|
||||||
min-inline-size: max-content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-file-row {
|
.preview-file-row {
|
||||||
display: flex;
|
display: grid;
|
||||||
box-sizing: border-box;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-block-size: 2.75rem;
|
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
||||||
min-inline-size: max-content;
|
border-radius: 0.95rem;
|
||||||
padding-block: 0.625rem;
|
background: rgb(var(--v-theme-surface));
|
||||||
padding-inline: 0.75rem;
|
gap: 0.875rem;
|
||||||
|
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
|
||||||
|
min-block-size: 5.25rem;
|
||||||
|
min-inline-size: 0;
|
||||||
|
padding-block: 0.875rem;
|
||||||
|
padding-inline: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-file-row + .preview-file-row {
|
.preview-file-row__card {
|
||||||
border-block-start: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
min-inline-size: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.preview-file-text {
|
.preview-file-row__label {
|
||||||
|
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-file-row__name {
|
||||||
|
overflow: hidden;
|
||||||
|
color: rgb(var(--v-theme-on-surface));
|
||||||
|
font-size: 0.95rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.preview-file-row__path {
|
||||||
|
overflow: hidden;
|
||||||
|
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
|
||||||
|
font-size: 0.8125rem;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-file-row__card--target .preview-file-row__name {
|
||||||
|
color: rgb(var(--v-theme-primary));
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-file-row__arrow {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(var(--v-border-color), 0.08);
|
||||||
|
block-size: 2rem;
|
||||||
|
color: rgb(var(--v-theme-info));
|
||||||
|
inline-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
.reorganize-preview-list__empty {
|
.reorganize-preview-list__empty {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
|
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
|
||||||
padding-block: 1rem;
|
padding-block: 2rem;
|
||||||
padding-inline: 0.5rem;
|
padding-inline: 1rem;
|
||||||
white-space: nowrap;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (width <= 1200px) {
|
@media (width <= 1200px) {
|
||||||
@@ -1377,9 +1450,47 @@ onUnmounted(() => {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.preview-summary-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-overview-card--path {
|
||||||
|
grid-column: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-file-row {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-file-row__arrow {
|
||||||
|
justify-self: start;
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (width <= 959px) {
|
@media (width <= 959px) {
|
||||||
|
.reorganize-dialog-card,
|
||||||
|
.reorganize-dialog-card--split {
|
||||||
|
max-block-size: none;
|
||||||
|
block-size: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reorganize-dialog-card--split .reorganize-dialog-card__body,
|
||||||
|
.reorganize-dialog-card--split .reorganize-form-pane__content {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reorganize-main-row,
|
||||||
|
.reorganize-main-row--preview-visible {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reorganize-main-row--preview-visible .reorganize-form-pane {
|
||||||
|
border-block-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
||||||
|
border-inline-end: none;
|
||||||
|
}
|
||||||
|
|
||||||
.reorganize-form-pane__actions {
|
.reorganize-form-pane__actions {
|
||||||
display: grid;
|
display: grid;
|
||||||
justify-content: stretch;
|
justify-content: stretch;
|
||||||
@@ -1390,6 +1501,15 @@ onUnmounted(() => {
|
|||||||
inline-size: 100%;
|
inline-size: 100%;
|
||||||
min-block-size: 2.75rem;
|
min-block-size: 2.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reorganize-preview-pane__summary {
|
||||||
|
padding-inline: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reorganize-preview-list {
|
||||||
|
margin-block-end: 1rem;
|
||||||
|
margin-inline: 1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (width <= 640px) {
|
@media (width <= 640px) {
|
||||||
@@ -1405,6 +1525,18 @@ onUnmounted(() => {
|
|||||||
.reorganize-action-btn--primary {
|
.reorganize-action-btn--primary {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reorganize-preview-pane__header {
|
||||||
|
padding-inline: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-file-body {
|
||||||
|
padding-inline: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-file-row {
|
||||||
|
padding-inline: 0.875rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (width <= 420px) {
|
@media (width <= 420px) {
|
||||||
|
|||||||
@@ -2495,8 +2495,8 @@ export default {
|
|||||||
fromHistoryOption: 'Reuse Historical Recognition Info',
|
fromHistoryOption: 'Reuse Historical Recognition Info',
|
||||||
fromHistoryHint: 'Use media info already recognized in historical organization records',
|
fromHistoryHint: 'Use media info already recognized in historical organization records',
|
||||||
previewTitle: 'Preview Result',
|
previewTitle: 'Preview Result',
|
||||||
previewSubtitle: 'The right panel shows the expected organization result without changing files.',
|
previewSubtitle: 'Click "Preview" to inspect the expected organization result without changing files.',
|
||||||
previewResult: 'Preview Result',
|
previewResult: 'Preview',
|
||||||
previewLoading: 'Generating preview result...',
|
previewLoading: 'Generating preview result...',
|
||||||
previewRequestFailed: 'Preview request failed',
|
previewRequestFailed: 'Preview request failed',
|
||||||
previewTotal: 'Total {count}',
|
previewTotal: 'Total {count}',
|
||||||
@@ -2514,7 +2514,7 @@ export default {
|
|||||||
previewBeforeColumn: 'Before',
|
previewBeforeColumn: 'Before',
|
||||||
previewFileNameColumn: 'Filename',
|
previewFileNameColumn: 'Filename',
|
||||||
previewEmptyTitle: 'No preview yet',
|
previewEmptyTitle: 'No preview yet',
|
||||||
previewEmptyDescription: 'Click "Preview Result" below to inspect target paths and failure reasons here.',
|
previewEmptyDescription: 'Click "Preview" to inspect the organization result here.',
|
||||||
noPreviewData: 'No preview data',
|
noPreviewData: 'No preview data',
|
||||||
noFailedPreviewData: 'No failed items',
|
noFailedPreviewData: 'No failed items',
|
||||||
copySuccess: 'Path copied',
|
copySuccess: 'Path copied',
|
||||||
|
|||||||
@@ -2450,8 +2450,8 @@ export default {
|
|||||||
fromHistoryOption: '复用历史识别信息',
|
fromHistoryOption: '复用历史识别信息',
|
||||||
fromHistoryHint: '使用历史整理记录中已识别的媒体信息',
|
fromHistoryHint: '使用历史整理记录中已识别的媒体信息',
|
||||||
previewTitle: '整理结果预览',
|
previewTitle: '整理结果预览',
|
||||||
previewSubtitle: '右侧显示本次整理的预计入库结果,不会实际改动文件',
|
previewSubtitle: '点击“预览”后可查看本次整理的预计入库结果,不会实际改动文件',
|
||||||
previewResult: '预览整理结果',
|
previewResult: '预览',
|
||||||
previewLoading: '正在生成预览结果...',
|
previewLoading: '正在生成预览结果...',
|
||||||
previewRequestFailed: '预览请求失败',
|
previewRequestFailed: '预览请求失败',
|
||||||
previewTotal: '总数 {count}',
|
previewTotal: '总数 {count}',
|
||||||
@@ -2469,7 +2469,7 @@ export default {
|
|||||||
previewBeforeColumn: '整理前',
|
previewBeforeColumn: '整理前',
|
||||||
previewFileNameColumn: '文件名',
|
previewFileNameColumn: '文件名',
|
||||||
previewEmptyTitle: '尚未生成预览',
|
previewEmptyTitle: '尚未生成预览',
|
||||||
previewEmptyDescription: '点击"预览整理结果"按钮后,在这里查看整理结果预览。',
|
previewEmptyDescription: '点击“预览”按钮后,在这里查看整理结果预览。',
|
||||||
noPreviewData: '暂无预览结果',
|
noPreviewData: '暂无预览结果',
|
||||||
noFailedPreviewData: '当前没有失败项',
|
noFailedPreviewData: '当前没有失败项',
|
||||||
copySuccess: '路径已复制',
|
copySuccess: '路径已复制',
|
||||||
|
|||||||
@@ -2452,8 +2452,8 @@ export default {
|
|||||||
fromHistoryOption: '復用歷史識別資訊',
|
fromHistoryOption: '復用歷史識別資訊',
|
||||||
fromHistoryHint: '使用歷史整理記錄中已識別的媒體資訊',
|
fromHistoryHint: '使用歷史整理記錄中已識別的媒體資訊',
|
||||||
previewTitle: '整理結果預覽',
|
previewTitle: '整理結果預覽',
|
||||||
previewSubtitle: '右側顯示本次整理的預計入庫結果,不會實際改動文件',
|
previewSubtitle: '點擊「預覽」後可查看本次整理的預計入庫結果,不會實際改動文件',
|
||||||
previewResult: '預覽整理結果',
|
previewResult: '預覽',
|
||||||
previewLoading: '正在生成預覽結果...',
|
previewLoading: '正在生成預覽結果...',
|
||||||
previewRequestFailed: '預覽請求失敗',
|
previewRequestFailed: '預覽請求失敗',
|
||||||
previewTotal: '總數 {count}',
|
previewTotal: '總數 {count}',
|
||||||
@@ -2471,7 +2471,7 @@ export default {
|
|||||||
previewBeforeColumn: '整理前',
|
previewBeforeColumn: '整理前',
|
||||||
previewFileNameColumn: '文件名',
|
previewFileNameColumn: '文件名',
|
||||||
previewEmptyTitle: '尚未生成預覽',
|
previewEmptyTitle: '尚未生成預覽',
|
||||||
previewEmptyDescription: '點擊下方「預覽整理結果」按鈕後,在這裡查看目標路徑和失敗原因。',
|
previewEmptyDescription: '點擊「預覽」按鈕後,在這裡查看整理結果預覽。',
|
||||||
noPreviewData: '暫無預覽結果',
|
noPreviewData: '暫無預覽結果',
|
||||||
noFailedPreviewData: '目前沒有失敗項',
|
noFailedPreviewData: '目前沒有失敗項',
|
||||||
copySuccess: '路徑已複製',
|
copySuccess: '路徑已複製',
|
||||||
|
|||||||
Reference in New Issue
Block a user