+ {{ t('admin.documentDetail.remindersDescription') }} +
++ {{ t('admin.documentDetail.remindersSent') }} +
++ {{ reminderStats.totalSent }} +
++ {{ t('admin.documentDetail.toRemind') }} +
++ {{ reminderStats.pendingCount }} +
++ {{ t('admin.documentDetail.lastReminder') }} +
++ {{ formatDate(reminderStats.lastSentAt) }} +
++ {{ t('admin.documentDetail.emailServiceDisabled') }} +
++ {{ stats.signedCount }} / {{ stats.expectedCount }} {{ t('admin.dashboard.stats.signed').toLowerCase() }} +
+| + selectAllPending(e.target.checked)" + /> + | ++ {{ t('admin.documentDetail.reader') }} + | ++ {{ t('admin.documentDetail.status') }} + | ++ {{ t('admin.documentDetail.confirmedOn') }} + | ++ {{ t('common.actions') }} + | +
|---|---|---|---|---|
| + + | +
+
+
+ + {{ signer.userName || signer.name || signer.email }} + +{{ signer.email }} + |
+ + + {{ signer.hasSigned ? t('admin.documentDetail.statusConfirmed') : t('admin.documentDetail.statusPending') }} + + | ++ {{ formatDate(signer.signedAt) }} + | ++ + - + | +
+ {{ signer.userName || signer.name || signer.email }} +
+{{ signer.email }}
+{{ t('admin.documentDetail.noExpectedSigners') }}
++ {{ t('admin.documentDetail.unexpectedDescription') }} +
++ {{ sig.userName || sig.userEmail }} +
+{{ sig.userEmail }}
+{{ stats.signedCount }} / {{ stats.expectedCount }} {{ t('documentEdit.readers.confirmed') }}
-| - selectedEmails = e.target.checked ? expectedSigners.filter(s => !s.hasSigned).map(s => s.email) : []" /> - | -{{ t('documentEdit.readers.reader') }} | -{{ t('documentEdit.readers.status') }} | -{{ t('documentEdit.readers.confirmedOn') }} | -{{ t('common.actions') }} | -
|---|---|---|---|---|
| - - | -
-
-
- {{ signer.userName || signer.name || signer.email }} -{{ signer.email }} - |
- - - {{ signer.hasSigned ? t('documentEdit.readers.statusConfirmed') : t('documentEdit.readers.statusPending') }} - - | -- {{ signer.signedAt ? formatDate(signer.signedAt) : '-' }} - | -- - - - | -
{{ signer.userName || signer.name || signer.email }}
-{{ signer.email }}
-{{ t('documentEdit.readers.noReaders') }}
-{{ t('documentEdit.reminders.description') }}
-{{ t('documentEdit.reminders.sent') }}
-{{ reminderStats.totalSent }}
-{{ t('documentEdit.reminders.toRemind') }}
-{{ reminderStats.pendingCount }}
-{{ t('documentEdit.reminders.lastSent') }}
-{{ formatDate(reminderStats.lastSentAt) }}
-{{ t('documentEdit.reminders.emailDisabled') }}
-{{ csvError }}
+{{ t('admin.documentDetail.csvFormatHelp') }}
+{{ t('admin.documentDetail.validEntries') }}
+{{ signersToImport.length }}
+{{ t('admin.documentDetail.existingEntries') }}
+{{ csvPreview.existingEmails.length }}
+{{ t('admin.documentDetail.invalidEntries') }}
+{{ csvPreview.invalidCount }}
+| {{ t('admin.documentDetail.lineNumber') }} | +{{ t('admin.documentDetail.email') }} | +{{ t('admin.documentDetail.name') }} | +{{ t('admin.documentDetail.status') }} | +
|---|---|---|---|
| {{ signer.lineNumber }} | +{{ signer.email }} | +{{ signer.name || '-' }} | ++ + {{ getSignerStatus(signer) === 'exists' ? t('admin.documentDetail.statusExists') : t('admin.documentDetail.statusValid') }} + + | +
- {{ t('sign.external.description') }} + {{ currentDocument.url ? t('sign.external.descriptionWithUrl') : t('sign.external.description') }}
- -{{ t('sign.external.documentUrl') }}
+ + {{ currentDocument.url }} + +{{ t('sign.external.noUrl') }}
diff --git a/webapp/src/pages/admin/AdminDocumentDetail.vue b/webapp/src/pages/admin/AdminDocumentDetail.vue index cae88f4..1cf057a 100644 --- a/webapp/src/pages/admin/AdminDocumentDetail.vue +++ b/webapp/src/pages/admin/AdminDocumentDetail.vue @@ -19,22 +19,18 @@ import { } from '@/services/admin' import { extractError } from '@/services/http' import { useConfigStore } from '@/stores/config' +import SignersSection from '@/components/SignersSection.vue' +import RemindersSection from '@/components/RemindersSection.vue' import { ArrowLeft, - Users, CheckCircle, - Mail, - Plus, Loader2, Copy, - Clock, X, Trash2, - Upload, AlertTriangle, FileCheck, FileX, - Search, AlertCircle, ChevronRight, ExternalLink, @@ -44,6 +40,8 @@ import { Download, ScrollText, ShieldCheck, + Users, + Clock, } from 'lucide-vue-next' const route = useRoute() @@ -114,7 +112,6 @@ const savingMetadata = ref(false) // Expected signers form const signersEmails = ref('') const addingSigners = ref(false) -const signerFilter = ref('') // Reminders const sendMode = ref<'all' | 'selected'>('all') @@ -130,19 +127,10 @@ const shareLink = computed(() => { return documentStatus.value.shareLink }) -const stats = computed(() => documentStatus.value?.stats) +const stats = computed(() => documentStatus.value?.stats ?? null) const reminderStats = computed(() => documentStatus.value?.reminderStats) const smtpEnabled = computed(() => configStore.smtpEnabled) const expectedSigners = computed(() => documentStatus.value?.expectedSigners || []) -const filteredSigners = computed(() => { - const filter = signerFilter.value.toLowerCase().trim() - if (!filter) return expectedSigners.value - return expectedSigners.value.filter(signer => - signer.email.toLowerCase().includes(filter) || - (signer.name && signer.name.toLowerCase().includes(filter)) || - (signer.userName && signer.userName.toLowerCase().includes(filter)) - ) -}) const unexpectedSignatures = computed(() => documentStatus.value?.unexpectedSignatures || []) const documentMetadata = computed(() => documentStatus.value?.document) const documentTitle = computed(() => documentMetadata.value?.title || docId.value) @@ -294,9 +282,10 @@ function cancelRemoveSigner() { signerToRemove.value = '' } -function confirmSendReminders() { +function handleReminderSend(mode: 'all' | 'selected') { + sendMode.value = mode remindersMessage.value = - sendMode.value === 'all' + mode === 'all' ? t('admin.documentDetail.confirmSendReminders', { count: reminderStats.value?.pendingCount || 0 }) : t('admin.documentDetail.confirmSendRemindersSelected', { count: selectedEmails.value.length }) showSendRemindersModal.value = true @@ -369,15 +358,6 @@ function formatDate(dateString: string | undefined): string { }) } -function toggleEmailSelection(email: string) { - const index = selectedEmails.value.indexOf(email) - if (index > -1) { - selectedEmails.value.splice(index, 1) - } else { - selectedEmails.value.push(email) - } -} - async function handleDeleteDocument() { try { deletingDocument.value = true @@ -699,171 +679,27 @@ onMounted(() => {{{ stats.signedCount }} / {{ stats.expectedCount }} {{ t('admin.dashboard.stats.signed').toLowerCase() }}
-| - selectedEmails = e.target.checked ? expectedSigners.filter(s => !s.hasSigned).map(s => s.email) : []" /> - | -{{ t('admin.documentDetail.reader') }} | -{{ t('admin.documentDetail.status') }} | -{{ t('admin.documentDetail.confirmedOn') }} | -{{ t('common.actions') }} | -
|---|---|---|---|---|
| - - | -
-
-
- {{ signer.userName || signer.name || signer.email }} -{{ signer.email }} - |
- - - {{ signer.hasSigned ? t('admin.documentDetail.statusConfirmed') : t('admin.documentDetail.statusPending') }} - - | -- {{ signer.signedAt ? formatDate(signer.signedAt) : '-' }} - | -- - - - | -
{{ signer.userName || signer.name || signer.email }}
-{{ signer.email }}
-{{ t('admin.documentDetail.noExpectedSigners') }}
-{{ t('admin.documentDetail.unexpectedDescription') }}
-{{ sig.userName || sig.userEmail }}
-{{ sig.userEmail }}
-{{ t('admin.documentDetail.remindersDescription') }}
-{{ t('admin.documentDetail.remindersSent') }}
-{{ reminderStats.totalSent }}
-{{ t('admin.documentDetail.toRemind') }}
-{{ reminderStats.pendingCount }}
-{{ t('admin.documentDetail.lastReminder') }}
-{{ formatDate(reminderStats.lastSentAt) }}
-{{ t('admin.documentDetail.emailServiceDisabled') }}
-