整合文件选择工具栏

This commit is contained in:
2026-06-05 14:54:58 +08:00
parent d13cd91bd0
commit 63ef49195a
6 changed files with 188 additions and 89 deletions
+123 -80
View File
@@ -261,85 +261,86 @@
</div>
</section>
<section
v-if="tableData.length > 0"
class="theme-2026-card theme-2026-card-hover mb-4 flex flex-col gap-3 rounded-[30px] border px-4 py-3 shadow-md transition-all duration-200 hover:-translate-y-0.5 hover:shadow-lg sm:flex-row sm:items-center sm:justify-between"
:class="[panelClass, cardHoverClass]"
>
<label class="inline-flex items-center gap-2 text-sm" :class="[primaryTextClass]">
<input
type="checkbox"
class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
:checked="isAllCurrentPageSelected"
:disabled="isBatchActionRunning"
:indeterminate="isCurrentPagePartiallySelected"
@change="toggleCurrentPageSelection"
/>
<span>
{{
hasSelectedFiles
? t('fileManage.selectedCount', { count: selectedCount })
: t('fileManage.selectCurrentPage')
}}
</span>
</label>
<div class="flex flex-wrap items-center gap-2">
<BaseButton
v-if="hasSelectedFiles"
variant="outline"
size="sm"
:disabled="isBatchActionRunning"
@click="clearSelection"
>
<template #icon>
<XIcon class="mr-2 h-4 w-4" />
</template>
{{ t('fileManage.clearSelection') }}
</BaseButton>
<BaseButton
v-for="option in batchPolicyActionOptions"
:key="option.action"
variant="outline"
size="sm"
:title="option.description"
:disabled="!hasSelectedFiles || isBatchDeleting || isBatchUpdating"
:loading="isBatchPolicyActionRunning"
@click="applySelectedPolicyAction(option.action)"
>
<template #icon>
<component :is="getDetailPolicyActionIcon(option.action)" class="mr-2 h-4 w-4" />
</template>
{{ option.label }}
</BaseButton>
<BaseButton
variant="secondary"
size="sm"
:disabled="!hasSelectedFiles || isBatchDeleting || isBatchPolicyActionRunning"
:loading="isBatchUpdating"
@click="openBatchEditModal"
>
<template #icon>
<ClockIcon class="mr-2 h-4 w-4" />
</template>
{{ t('fileManage.batchEdit') }}
</BaseButton>
<BaseButton
variant="danger"
size="sm"
:disabled="!hasSelectedFiles || isBatchUpdating || isBatchPolicyActionRunning"
:loading="isBatchDeleting"
@click="deleteSelectedFiles"
>
<template #icon>
<TrashIcon class="mr-2 h-4 w-4" />
</template>
{{ t('fileManage.batchDelete') }}
</BaseButton>
</div>
</section>
<DataTable :title="t('fileManage.allFiles')" :headers="fileTableHeaders">
<template #toolbar>
<div
v-if="tableData.length > 0"
class="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between"
>
<label class="inline-flex items-center gap-2 text-sm" :class="[primaryTextClass]">
<input
type="checkbox"
class="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
:checked="isAllCurrentPageSelected"
:disabled="isBatchActionRunning"
:indeterminate="isCurrentPagePartiallySelected"
@change="toggleCurrentPageSelection"
/>
<span>
{{
hasSelectedFiles
? t('fileManage.selectedCount', { count: selectedCount })
: t('fileManage.selectCurrentPage')
}}
</span>
</label>
<div class="flex flex-wrap items-center gap-2">
<BaseButton
v-if="hasSelectedFiles"
variant="outline"
size="sm"
:disabled="isBatchActionRunning"
@click="clearSelection"
>
<template #icon>
<XIcon class="mr-2 h-4 w-4" />
</template>
{{ t('fileManage.clearSelection') }}
</BaseButton>
<BaseButton
v-for="option in batchPolicyActionOptions"
:key="option.action"
variant="outline"
size="sm"
:title="option.description"
:disabled="option.disabled || !hasSelectedFiles || isBatchDeleting || isBatchUpdating"
:loading="isBatchPolicyActionRunning"
@click="applySelectedPolicyAction(option.action)"
>
<template #icon>
<component :is="getDetailPolicyActionIcon(option.action)" class="mr-2 h-4 w-4" />
</template>
{{ option.label }}
</BaseButton>
<BaseButton
variant="secondary"
size="sm"
:disabled="!hasSelectedFiles || isBatchDeleting || isBatchPolicyActionRunning"
:loading="isBatchUpdating"
@click="openBatchEditModal"
>
<template #icon>
<ClockIcon class="mr-2 h-4 w-4" />
</template>
{{ t('fileManage.batchEdit') }}
</BaseButton>
<BaseButton
variant="danger"
size="sm"
:disabled="!hasSelectedFiles || isBatchUpdating || isBatchPolicyActionRunning"
:loading="isBatchDeleting"
@click="deleteSelectedFiles"
>
<template #icon>
<TrashIcon class="mr-2 h-4 w-4" />
</template>
{{ t('fileManage.batchDelete') }}
</BaseButton>
</div>
</div>
</template>
<template #body>
<tr v-if="isLoading">
<td :colspan="fileTableHeaders.length" class="px-6 py-12 text-center">
@@ -1218,12 +1219,12 @@
<p class="text-sm font-medium" :class="[primaryTextClass]">
{{ t('fileManage.batchEditMode') }}
</p>
<div class="grid gap-2 sm:grid-cols-3">
<div class="grid gap-2 sm:grid-cols-2 xl:grid-cols-4">
<button
v-for="option in batchEditModeOptions"
:key="option.value"
type="button"
class="flex min-h-12 items-center justify-center rounded-lg border px-3 py-2 text-sm font-medium transition-colors"
class="flex min-h-12 items-center justify-center rounded-[30px] border px-3 py-2 text-sm font-medium transition-colors"
:class="getBatchEditModeClass(option.value)"
:disabled="isBatchUpdating"
@click="batchEditForm.mode = option.value"
@@ -1240,6 +1241,42 @@
type="datetime-local"
:label="t('fileManage.batchEditExpiresAt')"
/>
<div v-else-if="batchEditForm.mode === 'relativeExpire'" class="grid gap-3 sm:grid-cols-[1fr_10rem]">
<FileEditField
v-model="batchEditForm.relative_expire_value"
type="number"
:label="t('fileManage.batchEditRelativeExpireValue')"
:placeholder="t('fileManage.batchEditRelativeExpirePlaceholder')"
/>
<div class="space-y-2 group">
<label
class="flex items-center space-x-2 text-sm font-medium transition-colors duration-200"
:class="[
isDarkMode
? 'text-gray-300 group-focus-within:text-indigo-400'
: 'text-gray-700 group-focus-within:text-indigo-600'
]"
>
<span>{{ t('fileManage.batchEditRelativeExpireUnit') }}</span>
<div
class="h-px flex-1 transition-colors duration-200"
:class="[
isDarkMode
? 'bg-gray-700 group-focus-within:bg-indigo-500/50'
: 'bg-gray-200 group-focus-within:bg-indigo-500/30'
]"
></div>
</label>
<select
v-model="batchEditForm.relative_expire_unit"
class="block min-h-12 w-full rounded-[30px] border px-4 py-2.5 text-sm font-medium transition-all duration-200 focus:outline-none focus:ring-2"
:class="fieldClass"
>
<option value="hours">{{ t('fileManage.batchEditRelativeExpireHours') }}</option>
<option value="days">{{ t('fileManage.batchEditRelativeExpireDays') }}</option>
</select>
</div>
</div>
<FileEditField
v-else-if="batchEditForm.mode === 'downloadLimit'"
v-model="batchEditForm.expired_count"
@@ -1377,6 +1414,7 @@ import {
RefreshCwIcon,
RotateCcwIcon,
SearchIcon,
TimerResetIcon,
TrashIcon,
XIcon
} from 'lucide-vue-next'
@@ -1815,6 +1853,11 @@ const batchEditModeOptions = computed<
label: t('fileManage.batchEditExpiresAt'),
icon: ClockIcon
},
{
value: 'relativeExpire',
label: t('fileManage.batchEditRelativeExpire'),
icon: TimerResetIcon
},
{
value: 'downloadLimit',
label: t('fileManage.batchEditDownloadLimit'),