feat(dashboard): add loading state for report assignment and truncate addresses
This commit is contained in:
@@ -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<{
|
||||||
@@ -38,53 +40,56 @@ const reportHref = (report: Report) => `${props.detailBasePath}/${report.id}`
|
|||||||
<div class="table-responsive report-table-wrapper">
|
<div class="table-responsive report-table-wrapper">
|
||||||
<table class="table table-hover report-table mb-0">
|
<table class="table table-hover report-table mb-0">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">ID</th>
|
<th scope="col">ID</th>
|
||||||
<th scope="col">Categoria</th>
|
<th scope="col">Categoria</th>
|
||||||
<th scope="col">Indirizzo</th>
|
<th scope="col">Indirizzo</th>
|
||||||
<th scope="col">Stato</th>
|
<th scope="col">Stato</th>
|
||||||
<th v-if="showAssignee" scope="col">Operatore</th>
|
<th v-if="showAssignee" scope="col">Operatore</th>
|
||||||
<th scope="col">Creazione</th>
|
<th scope="col">Creazione</th>
|
||||||
<th scope="col" class="text-end">Azioni</th>
|
<th scope="col" class="text-end">Azioni</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="report in reports" :key="report.id" class="align-middle">
|
<tr v-for="report in reports" :key="report.id" class="align-middle">
|
||||||
<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>
|
||||||
<td>
|
<td>
|
||||||
<StatusBadge :status="report.status" />
|
<StatusBadge :status="report.status" />
|
||||||
</td>
|
</td>
|
||||||
<td v-if="showAssignee" class="text-muted">
|
<td v-if="showAssignee" class="text-muted">
|
||||||
{{ report.assigned_operator_id ? `#${report.assigned_operator_id}` : '-' }}
|
{{ report.assigned_operator_id ? `#${report.assigned_operator_id}` : '-' }}
|
||||||
</td>
|
</td>
|
||||||
<td class="text-muted text-nowrap">{{ formatDate(report.created_at) }}</td>
|
<td class="text-muted text-nowrap">{{ formatDate(report.created_at) }}</td>
|
||||||
<td class="text-end">
|
<td class="text-end">
|
||||||
<button
|
<button
|
||||||
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)"
|
||||||
>
|
>
|
||||||
Prendi in carico
|
<span v-if="processingIds.includes(report.id)" class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"></span>
|
||||||
</button>
|
Prendi in carico
|
||||||
<NuxtLink
|
</button>
|
||||||
|
<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"
|
||||||
>
|
>
|
||||||
<BIIcon name="it-arrow-right" size="xs" />
|
<BIIcon name="it-arrow-right" size="xs" />
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -4,10 +4,17 @@ 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) => {
|
||||||
const res = await takeReport(id)
|
processingIds.value.push(id)
|
||||||
if (res.ok) {
|
try {
|
||||||
await Promise.all([refreshOpen(), refreshAssigned()])
|
const res = await takeReport(id)
|
||||||
|
if (res.ok) {
|
||||||
|
await Promise.all([refreshOpen(), refreshAssigned()])
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
processingIds.value = processingIds.value.filter(pid => pid !== id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user