mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-09 09:46:44 +08:00
fix(transfer): improve manual review dialog on mobile
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import { useDisplay } from 'vuetify'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useToast } from 'vue-toastification'
|
||||
import api from '@/api'
|
||||
@@ -16,6 +17,8 @@ const emit = defineEmits<{
|
||||
|
||||
const { t } = useI18n()
|
||||
const toast = useToast()
|
||||
// 小屏详情弹窗占满可用屏幕,避免长提示和操作区被裁切。
|
||||
const display = useDisplay()
|
||||
|
||||
const reason = ref('')
|
||||
const submittingDecision = ref<TransferManualReviewDecision | null>(null)
|
||||
@@ -90,15 +93,19 @@ async function resolveManualReview(decision: TransferManualReviewDecision) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VDialog scrollable max-width="52rem">
|
||||
<VDialog scrollable max-width="52rem" :fullscreen="!display.mdAndUp.value">
|
||||
<VCard class="manual-review-dialog" width="100%">
|
||||
<VCardItem>
|
||||
<VCardItem class="manual-review-dialog__header">
|
||||
<VDialogCloseBtn @click="emit('close')" />
|
||||
<template #prepend>
|
||||
<VIcon icon="mdi-help-circle-outline" color="warning" size="28" class="me-2" />
|
||||
</template>
|
||||
<VCardTitle>{{ t('dialog.transferQueue.manualReviewTitle') }}</VCardTitle>
|
||||
<VCardSubtitle>{{ t('dialog.transferQueue.manualReviewHint') }}</VCardSubtitle>
|
||||
<VCardTitle class="manual-review-dialog__title">
|
||||
{{ t('dialog.transferQueue.manualReviewTitle') }}
|
||||
</VCardTitle>
|
||||
<VCardSubtitle class="manual-review-dialog__subtitle">
|
||||
{{ t('dialog.transferQueue.manualReviewHint') }}
|
||||
</VCardSubtitle>
|
||||
</VCardItem>
|
||||
|
||||
<VDivider />
|
||||
@@ -203,10 +210,35 @@ async function resolveManualReview(decision: TransferManualReviewDecision) {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
max-block-size: min(70vh, 42rem);
|
||||
min-block-size: 0;
|
||||
min-inline-size: 0;
|
||||
overflow-y: auto;
|
||||
padding: 1.5rem !important;
|
||||
}
|
||||
|
||||
.manual-review-dialog__header :deep(.v-card-item__content) {
|
||||
min-inline-size: 0;
|
||||
overflow: visible;
|
||||
padding-inline-end: 2.5rem;
|
||||
}
|
||||
|
||||
.manual-review-dialog :deep(.manual-review-dialog__title),
|
||||
.manual-review-dialog :deep(.manual-review-dialog__subtitle) {
|
||||
overflow: visible;
|
||||
overflow-wrap: anywhere;
|
||||
text-overflow: clip;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.manual-review-dialog :deep(.manual-review-dialog__title) {
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.manual-review-dialog :deep(.manual-review-dialog__subtitle) {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.manual-review-dialog__summary {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -250,15 +282,28 @@ async function resolveManualReview(decision: TransferManualReviewDecision) {
|
||||
font-size: 0.84rem;
|
||||
gap: 0.5rem;
|
||||
line-height: 1.5;
|
||||
min-inline-size: 0;
|
||||
padding-block-start: 0.75rem;
|
||||
}
|
||||
|
||||
.manual-review-dialog__error > span {
|
||||
min-inline-size: 0;
|
||||
overflow-wrap: anywhere;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.manual-review-dialog__notice {
|
||||
inline-size: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.manual-review-dialog__evidence {
|
||||
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
||||
.manual-review-dialog__notice :deep(.v-alert__content) {
|
||||
min-inline-size: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: anywhere;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.manual-review-dialog__evidence pre {
|
||||
|
||||
@@ -5,6 +5,14 @@ import { renderWithProviders } from '@tests/support/render'
|
||||
import { flushPromises } from '@vue/test-utils'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { cwd } from 'node:process'
|
||||
|
||||
const transferManualReviewSource = readFileSync(
|
||||
resolve(cwd(), 'src/components/dialog/TransferManualReviewDialog.vue'),
|
||||
'utf8',
|
||||
)
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
apiPost: vi.fn(),
|
||||
@@ -64,6 +72,13 @@ describe('TransferManualReviewDialog', () => {
|
||||
mocks.apiPost.mockResolvedValue({})
|
||||
})
|
||||
|
||||
it('uses mobile fullscreen and keeps long review content readable', () => {
|
||||
expect(transferManualReviewSource).toContain(':fullscreen="!display.mdAndUp.value"')
|
||||
expect(transferManualReviewSource).toContain('.manual-review-dialog__error > span')
|
||||
expect(transferManualReviewSource).toContain('.manual-review-dialog__notice :deep(.v-alert__content)')
|
||||
expect(transferManualReviewSource).not.toMatch(/\.manual-review-dialog__evidence\s*\{[^}]*border:/s)
|
||||
})
|
||||
|
||||
it('requires review notes before submitting a decision', async () => {
|
||||
const user = userEvent.setup()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user