feat(dashboard): add loading state for report assignment and truncate addresses

This commit is contained in:
2026-06-15 23:12:40 +02:00 Unverified
parent b6e7cc5b71
commit 107cb61ea4
2 changed files with 50 additions and 38 deletions
+7 -2
View File
@@ -9,6 +9,7 @@ interface Props {
actionVariant?: ActionVariant actionVariant?: ActionVariant
actionLabel?: string actionLabel?: string
showAssignee?: boolean showAssignee?: boolean
processingIds?: number[]
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
@@ -16,6 +17,7 @@ const props = withDefaults(defineProps<Props>(), {
actionVariant: 'open', actionVariant: 'open',
actionLabel: 'Open report', actionLabel: 'Open report',
showAssignee: false, showAssignee: false,
processingIds: () => [],
}) })
const emit = defineEmits<{ const emit = defineEmits<{
@@ -53,7 +55,8 @@ const reportHref = (report: Report) => `${props.detailBasePath}/${report.id}`
<td class="report-table-id">#{{ report.id }}</td> <td class="report-table-id">#{{ report.id }}</td>
<td class="text-nowrap">{{ report.category_name || '-' }}</td> <td class="text-nowrap">{{ report.category_name || '-' }}</td>
<td> <td>
<span class="report-address" :title="report.address"> <!-- Added inline-block, text-truncate (for ellipsis), and max-width 10ch -->
<span class="report-address d-inline-block text-truncate align-middle" style="max-width: 10ch;" :title="report.address">
{{ report.address || '-' }} {{ report.address || '-' }}
</span> </span>
</td> </td>
@@ -69,14 +72,16 @@ const reportHref = (report: Report) => `${props.detailBasePath}/${report.id}`
v-if="actionVariant === 'manage'" v-if="actionVariant === 'manage'"
type="button" type="button"
class="btn btn-primary btn-xs" class="btn btn-primary btn-xs"
:disabled="processingIds.includes(report.id)"
@click="emit('take', report.id)" @click="emit('take', report.id)"
> >
<span v-if="processingIds.includes(report.id)" class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span>
Prendi in carico Prendi in carico
</button> </button>
<NuxtLink <NuxtLink
v-else v-else
:to="reportHref(report)" :to="reportHref(report)"
class="btn btn-outline-primary btn-xs btn-icon" class="btn btn-outline-primary btn-xs btn-icon d-inline-flex align-items-center justify-content-center"
:aria-label="actionLabel" :aria-label="actionLabel"
:title="actionLabel" :title="actionLabel"
> >
@@ -4,11 +4,18 @@ const { getOpenReports, getAssignedReports, takeReport } = useOperator()
const { data: openReportsRes, refresh: refreshOpen } = useAsyncData('open-reports', () => getOpenReports({ per_page: 5 })) const { data: openReportsRes, refresh: refreshOpen } = useAsyncData('open-reports', () => getOpenReports({ per_page: 5 }))
const { data: assignedReportsRes, refresh: refreshAssigned } = useAsyncData('assigned-reports', () => getAssignedReports({ per_page: 5 })) const { data: assignedReportsRes, refresh: refreshAssigned } = useAsyncData('assigned-reports', () => getAssignedReports({ per_page: 5 }))
const processingIds = ref<number[]>([])
const handleTakeReport = async (id: number) => { const handleTakeReport = async (id: number) => {
processingIds.value.push(id)
try {
const res = await takeReport(id) const res = await takeReport(id)
if (res.ok) { if (res.ok) {
await Promise.all([refreshOpen(), refreshAssigned()]) await Promise.all([refreshOpen(), refreshAssigned()])
} }
} finally {
processingIds.value = processingIds.value.filter(pid => pid !== id)
}
} }
</script> </script>