🔨 Refactor(custom): use custom button components in upload task page

This commit is contained in:
Kuingsmile
2026-01-27 12:46:34 +08:00
parent 682e703c51
commit a5c07f2beb
3 changed files with 47 additions and 73 deletions

View File

@@ -11,6 +11,7 @@
</slot> </slot>
<slot> <slot>
<span <span
v-if="text"
:class="textClassVar" :class="textClassVar"
:data-active="active" :data-active="active"
class="[.primary] text-sm leading-[1.4] font-semibold text-secondary" class="[.primary] text-sm leading-[1.4] font-semibold text-secondary"
@@ -60,7 +61,7 @@ const textClassVar = computed(() => {
const classVar = computed(() => { const classVar = computed(() => {
switch (type) { switch (type) {
case 'primary': case 'primary':
return 'bg-accent text-white not-disabled:hover:bg-accent-hover! not-disabled:hover:-translate-y-px' return 'bg-accent text-white not-disabled:hover:bg-accent-hover not-disabled:hover:-translate-y-px'
case 'secondary': case 'secondary':
return 'border border-border bg-bg-secondary text-main not-disabled:hover:bg-accent/30! not-disabled:hover:text-white! not-disabled:hover:-translate-y-px' return 'border border-border bg-bg-secondary text-main not-disabled:hover:bg-accent/30! not-disabled:hover:text-white! not-disabled:hover:-translate-y-px'
case 'tab': case 'tab':

View File

@@ -294,75 +294,62 @@
class="flex flex-wrap items-center justify-between gap-4 border-b border-b-border px-5 py-4 max-md:flex-col max-md:items-stretch" class="flex flex-wrap items-center justify-between gap-4 border-b border-b-border px-5 py-4 max-md:flex-col max-md:items-stretch"
> >
<div class="flex flex-wrap items-center gap-2.5 max-md:w-full max-md:justify-center"> <div class="flex flex-wrap items-center gap-2.5 max-md:w-full max-md:justify-center">
<button <CustomButton
v-show="taskQueueStatus.tasks.length > 0" v-show="taskQueueStatus.tasks.length > 0"
class="flex cursor-pointer items-center justify-center gap-2 rounded-md bg-accent px-4 py-2.5 text-sm font-medium whitespace-nowrap text-white shadow-sm transition-all duration-fast ease-standard hover:-translate-y-[2px] hover:shadow-md" type="primary"
:icon="PlusIcon"
:text="t('pages.upload.taskQueue.addFiles')"
@click="addFilesToTask" @click="addFilesToTask"
> />
<PlusIcon :size="16" /> <CustomButton
<span>{{ t('pages.upload.taskQueue.addFiles') }}</span>
</button>
<button
v-if="!taskQueueStatus.config.isRunning && taskQueueStatus.stats.pending > 0" v-if="!taskQueueStatus.config.isRunning && taskQueueStatus.stats.pending > 0"
class="flex cursor-pointer items-center gap-2 rounded-md bg-success px-4 py-2.5 text-sm font-medium whitespace-nowrap text-white shadow-sm transition-all duration-fast ease-standard hover:-translate-y-[2px] hover:shadow-md" class="bg-success hover:bg-success!"
:icon="PlayIcon"
:text="t('pages.upload.taskQueue.start')"
@click="startTaskQueue" @click="startTaskQueue"
> />
<PlayIcon :size="16" /> <CustomButton
<span>{{ t('pages.upload.taskQueue.start') }}</span>
</button>
<button
v-if="taskQueueStatus.config.isRunning && !taskQueueStatus.config.isPaused" v-if="taskQueueStatus.config.isRunning && !taskQueueStatus.config.isPaused"
class="flex cursor-pointer items-center gap-2 rounded-md bg-warning px-4 py-2.5 text-sm font-medium whitespace-nowrap text-white shadow-sm transition-all duration-fast ease-standard hover:-translate-y-[2px] hover:shadow-md" class="bg-warning hover:bg-warning!"
:icon="PauseIcon"
:text="t('pages.upload.taskQueue.pause')"
@click="pauseTaskQueue" @click="pauseTaskQueue"
> />
<PauseIcon :size="16" /> <CustomButton
<span>{{ t('pages.upload.taskQueue.pause') }}</span>
</button>
<button
v-if="taskQueueStatus.config.isPaused" v-if="taskQueueStatus.config.isPaused"
class="flex cursor-pointer items-center gap-2 rounded-md bg-success px-4 py-2.5 text-sm font-medium whitespace-nowrap text-white shadow-sm transition-all duration-fast ease-standard hover:-translate-y-[2px] hover:shadow-md" class="bg-success hover:bg-success!"
:icon="PlayIcon"
:text="t('pages.upload.taskQueue.resume')"
@click="resumeTaskQueue" @click="resumeTaskQueue"
> />
<PlayIcon :size="16" />
<span>{{ t('pages.upload.taskQueue.resume') }}</span>
</button>
</div> </div>
<div class="flex flex-wrap items-center gap-2.5 max-md:w-full max-md:justify-center"> <div class="flex flex-wrap items-center gap-2.5 max-md:w-full max-md:justify-center">
<button <CustomButton
v-if="taskQueueStatus.stats.failed > 0" v-if="taskQueueStatus.stats.failed > 0"
class="flex cursor-pointer items-center gap-2 rounded-md bg-warning px-4 py-2.5 text-sm font-medium whitespace-nowrap text-white shadow-sm transition-all duration-fast ease-standard hover:-translate-y-[2px] hover:shadow-md" class="bg-warning hover:bg-warning!"
:icon="RefreshCwIcon"
:text="t('pages.upload.taskQueue.retryAllFailed')"
@click="retryAllFailedTasks" @click="retryAllFailedTasks"
> />
<RefreshCwIcon :size="16" /> <CustomButton
<span>{{ t('pages.upload.taskQueue.retryAllFailed') }}</span>
</button>
<button
v-if="taskQueueStatus.config.isRunning || taskQueueStatus.stats.pending > 0" v-if="taskQueueStatus.config.isRunning || taskQueueStatus.stats.pending > 0"
class="flex cursor-pointer items-center gap-2 rounded-md bg-danger px-4 py-2.5 text-sm font-medium whitespace-nowrap text-white shadow-sm transition-all duration-fast ease-standard hover:-translate-y-[2px] hover:shadow-md" class="bg-error hover:bg-error!"
:icon="XIcon"
:text="t('pages.upload.taskQueue.cancelAll')"
@click="cancelAllTasks" @click="cancelAllTasks"
> />
<XIcon :size="16" /> <CustomButton
<span>{{ t('pages.upload.taskQueue.cancelAll') }}</span>
</button>
<button
v-if=" v-if="
taskQueueStatus.stats.completed > 0 || taskQueueStatus.stats.completed > 0 ||
taskQueueStatus.stats.failed > 0 || taskQueueStatus.stats.failed > 0 ||
taskQueueStatus.stats.cancelled > 0 taskQueueStatus.stats.cancelled > 0
" "
class="flex cursor-pointer items-center gap-2 rounded-md bg-danger px-4 py-2.5 text-sm font-medium whitespace-nowrap text-white shadow-sm transition-all duration-fast ease-standard hover:-translate-y-[2px] hover:shadow-md" class="bg-danger hover:bg-danger!"
:icon="Trash2Icon"
:text="t('pages.upload.taskQueue.clearFinished')"
@click="clearFinishedTasks" @click="clearFinishedTasks"
> />
<Trash2Icon :size="16" /> <CustomButton type="primary" :icon="SettingsIcon" text="" @click="showTaskSettings = !showTaskSettings" />
<span>{{ t('pages.upload.taskQueue.clearFinished') }}</span>
</button>
<button
class="flex cursor-pointer items-center gap-2 rounded-md bg-accent px-4 py-2.5 text-sm font-medium whitespace-nowrap text-white shadow-sm transition-all duration-fast ease-standard hover:-translate-y-[2px] hover:shadow-md"
:class="{ active: showTaskSettings }"
@click="showTaskSettings = !showTaskSettings"
>
<SettingsIcon :size="16" />
</button>
</div> </div>
</div> </div>
@@ -486,22 +473,13 @@
/> />
</div> </div>
<div class="flex flex-wrap gap-2.5"> <div class="flex flex-wrap gap-2.5">
<button class="filter-tab" :class="{ active: taskFilter === 'all' }" @click="taskFilter = 'all'"> <CustomButton
{{ t('pages.upload.taskQueue.filterAll') }} v-for="status in ['all', 'pending', 'completed', 'failed']"
</button> :key="status"
<button class="filter-tab" :class="{ active: taskFilter === 'pending' }" @click="taskFilter = 'pending'"> :type="taskFilter === status ? 'primary' : 'secondary'"
{{ t('pages.upload.taskQueue.filterPending') }} :text="t(`pages.upload.taskQueue.filter${status.charAt(0).toUpperCase() + status.slice(1)}`)"
</button> @click="taskFilter = status"
<button />
class="filter-tab"
:class="{ active: taskFilter === 'completed' }"
@click="taskFilter = 'completed'"
>
{{ t('pages.upload.taskQueue.filterCompleted') }}
</button>
<button class="filter-tab" :class="{ active: taskFilter === 'failed' }" @click="taskFilter = 'failed'">
{{ t('pages.upload.taskQueue.filterFailed') }}
</button>
</div> </div>
</div> </div>
@@ -688,6 +666,7 @@ import { computed, onBeforeMount, onBeforeUnmount, reactive, ref, useTemplateRef
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import CustomButton from '@/components/common/CustomButton.vue'
import CustomModal from '@/components/common/CustomModal.vue' import CustomModal from '@/components/common/CustomModal.vue'
import ImageProcessSetting from '@/components/ImageProcessSetting.vue' import ImageProcessSetting from '@/components/ImageProcessSetting.vue'
import { usePicBed } from '@/hooks/useGlobal' import { usePicBed } from '@/hooks/useGlobal'
@@ -764,7 +743,7 @@ const fileInput = useTemplateRef('fileInput')
const uploadInterval = ref(1000) const uploadInterval = ref(1000)
const showTaskSettings = useStorage('upload-task-queue-show-settings', true) const showTaskSettings = useStorage('upload-task-queue-show-settings', true)
const taskSearchQuery = ref('') const taskSearchQuery = ref('')
const taskFilter = ref<'all' | 'pending' | 'completed' | 'failed'>('all') const taskFilter = ref<string>('all')
const autoStart = ref(false) const autoStart = ref(false)
const pauseOnError = ref(false) const pauseOnError = ref(false)
const maxRetryCount = ref(3) const maxRetryCount = ref(3)

View File

@@ -11,12 +11,6 @@
@apply relative flex flex-1 cursor-pointer items-center gap-2 rounded-lg border border-border-secondary bg-bg-secondary px-4 py-3.5 text-left font-[inherit] duration-medium ease-standard hover:-translate-y-[2px] hover:bg-accent/30 hover:shadow-md focus-visible:focus-ring max-xs:px-3.5 max-xs:py-3 ; @apply relative flex flex-1 cursor-pointer items-center gap-2 rounded-lg border border-border-secondary bg-bg-secondary px-4 py-3.5 text-left font-[inherit] duration-medium ease-standard hover:-translate-y-[2px] hover:bg-accent/30 hover:shadow-md focus-visible:focus-ring max-xs:px-3.5 max-xs:py-3 ;
} }
.filter-tab {
@apply cursor-pointer rounded-md border border-border-secondary bg-bg-secondary px-4 py-2 text-sm font-medium whitespace-nowrap text-secondary shadow-sm transition-all duration-fast ease-standard;
@apply hover:-translate-y-px hover:border-accent hover:text-main hover:shadow-md;
@apply [.active]:border-transparent [.active]:bg-accent [.active]:text-white [.active]:shadow-lg;
}
.task-icon-btn { .task-icon-btn {
@apply flex h-[32px] w-[32px] cursor-pointer items-center justify-center rounded-md border border-border bg-surface-elevated p-0 text-secondary transition-all duration-fast ease-standard; @apply flex h-[32px] w-[32px] cursor-pointer items-center justify-center rounded-md border border-border bg-surface-elevated p-0 text-secondary transition-all duration-fast ease-standard;
@apply hover:-translate-y-px hover:border-accent hover:bg-accent hover:text-white; @apply hover:-translate-y-px hover:border-accent hover:bg-accent hover:text-white;