fix: separa lavagna chiamate e filtra interni
This commit is contained in:
parent
236aef53cd
commit
ab7b804d08
|
|
@ -68,8 +68,8 @@ public function mount(): void
|
|||
$focus = (int) request()->query('focus_post_it', 0);
|
||||
$this->focusPostItId = $focus > 0 ? $focus : null;
|
||||
|
||||
if (request()->query('tab') === 'storico') {
|
||||
$this->activeTab = 'storico';
|
||||
if (in_array((string) request()->query('tab'), ['storico', 'lavagna'], true)) {
|
||||
$this->activeTab = (string) request()->query('tab');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -232,45 +232,67 @@ public function getRecentiProperty()
|
|||
$query->orderByRaw('CASE WHEN id = ? THEN 0 ELSE 1 END', [$this->focusPostItId]);
|
||||
}
|
||||
|
||||
return $query->limit(50)->get();
|
||||
return $query->limit(80)->get();
|
||||
} catch (QueryException) {
|
||||
return collect();
|
||||
}
|
||||
}
|
||||
|
||||
public function getRecentiVisibiliProperty()
|
||||
{
|
||||
return $this->recenti
|
||||
->filter(fn(ChiamataPostIt $postIt): bool => ! $this->isInternalPostIt($postIt))
|
||||
->values();
|
||||
}
|
||||
|
||||
public function getRecentiRaggruppatiProperty()
|
||||
{
|
||||
$groups = [];
|
||||
|
||||
foreach ($this->recenti as $postIt) {
|
||||
foreach ($this->recentiVisibili as $postIt) {
|
||||
if ($this->isInternalPostIt($postIt)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$groupKey = $this->buildGroupedPostItKey($postIt);
|
||||
$lastIndex = count($groups) - 1;
|
||||
|
||||
if ($lastIndex >= 0 && $groups[$lastIndex]['key'] === $groupKey) {
|
||||
$groups[$lastIndex]['items'][] = $postIt;
|
||||
$groups[$lastIndex]['count']++;
|
||||
$groups[$lastIndex]['last_at'] = optional($postIt->chiamata_il)->format('d/m/Y H:i') ?: '-';
|
||||
if (isset($groups[$groupKey])) {
|
||||
$groups[$groupKey]['items'][] = $postIt;
|
||||
$groups[$groupKey]['count']++;
|
||||
$groups[$groupKey]['last_at'] = optional($postIt->chiamata_il)->format('d/m/Y H:i') ?: '-';
|
||||
$groups[$groupKey]['latest'] = $this->resolveLatestGroupedPostIt($groups[$groupKey]['items']);
|
||||
$groups[$groupKey]['caller_label'] = $this->resolveGroupedCallerLabel($groups[$groupKey]['items']);
|
||||
continue;
|
||||
}
|
||||
|
||||
$groups[] = [
|
||||
$groups[$groupKey] = [
|
||||
'key' => $groupKey,
|
||||
'items' => [$postIt],
|
||||
'count' => 1,
|
||||
'latest' => $postIt,
|
||||
'caller_label' => $postIt->nome_chiamante ?: 'Chiamante non identificato',
|
||||
'phone' => (string) ($postIt->telefono ?? ''),
|
||||
'route_label' => $this->resolvePostItRouteLabel($postIt),
|
||||
'first_at' => optional($postIt->chiamata_il)->format('d/m/Y H:i') ?: '-',
|
||||
'last_at' => optional($postIt->chiamata_il)->format('d/m/Y H:i') ?: '-',
|
||||
];
|
||||
}
|
||||
|
||||
return collect($groups);
|
||||
return collect(array_values($groups))
|
||||
->map(function (array $group): array {
|
||||
usort($group['items'], function (ChiamataPostIt $left, ChiamataPostIt $right): int {
|
||||
return ($right->chiamata_il?->getTimestamp() ?? 0) <=> ($left->chiamata_il?->getTimestamp() ?? 0);
|
||||
});
|
||||
|
||||
$group['latest'] = $this->resolveLatestGroupedPostIt($group['items']);
|
||||
$oldest = collect($group['items'])
|
||||
->sortBy(fn(ChiamataPostIt $item) => $item->chiamata_il?->getTimestamp() ?? 0)
|
||||
->first();
|
||||
$group['first_at'] = optional($oldest?->chiamata_il)->format('d/m/Y H:i') ?: '-';
|
||||
$group['last_at'] = optional($group['latest']->chiamata_il)->format('d/m/Y H:i') ?: '-';
|
||||
|
||||
return $group;
|
||||
})
|
||||
->sortByDesc(fn(array $group) => $group['latest']->chiamata_il?->getTimestamp() ?? 0)
|
||||
->values();
|
||||
}
|
||||
|
||||
public function getChiamateTecnicheProperty()
|
||||
|
|
@ -563,28 +585,12 @@ private function buildTicketDescriptionFromPostIt(int $postItId, ChiamataPostIt
|
|||
|
||||
private function buildGroupedPostItKey(ChiamataPostIt $postIt): string
|
||||
{
|
||||
$phone = preg_replace('/\D+/', '', (string) ($postIt->telefono ?? '')) ?: '';
|
||||
$caller = mb_strtolower(trim((string) ($postIt->nome_chiamante ?? '')));
|
||||
$route = mb_strtolower($this->resolvePostItRouteLabel($postIt));
|
||||
|
||||
return implode('|', [$phone, $caller, $route, (string) $postIt->direzione]);
|
||||
}
|
||||
|
||||
private function resolvePostItRouteLabel(ChiamataPostIt $postIt): string
|
||||
{
|
||||
$message = $this->resolveMessageFromPostIt($postIt);
|
||||
if ($message instanceof CommunicationMessage) {
|
||||
$line = trim((string) ($message->target_extension ?: data_get($message->metadata, 'smdr.co', '')));
|
||||
if ($line !== '') {
|
||||
return $line;
|
||||
}
|
||||
$phone = $this->normalizeGroupedPhone((string) ($postIt->telefono ?? ''));
|
||||
if ($phone !== '') {
|
||||
return 'phone:' . $phone;
|
||||
}
|
||||
|
||||
if (preg_match('/linea\s+([^\n]+)/i', (string) ($postIt->oggetto ?? ''), $matches) === 1) {
|
||||
return trim((string) $matches[1]);
|
||||
}
|
||||
|
||||
return '-';
|
||||
return 'caller:' . mb_strtolower(trim((string) ($postIt->nome_chiamante ?? 'sconosciuto')));
|
||||
}
|
||||
|
||||
private function isInternalPostIt(ChiamataPostIt $postIt): bool
|
||||
|
|
@ -614,6 +620,38 @@ private function resolveMessageFromPostIt(ChiamataPostIt $postIt): ?Communicatio
|
|||
return $message;
|
||||
}
|
||||
|
||||
private function normalizeGroupedPhone(string $phone): string
|
||||
{
|
||||
return preg_replace('/\D+/', '', $phone) ?: '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int,ChiamataPostIt> $items
|
||||
*/
|
||||
private function resolveLatestGroupedPostIt(array $items): ChiamataPostIt
|
||||
{
|
||||
usort($items, function (ChiamataPostIt $left, ChiamataPostIt $right): int {
|
||||
return ($right->chiamata_il?->getTimestamp() ?? 0) <=> ($left->chiamata_il?->getTimestamp() ?? 0);
|
||||
});
|
||||
|
||||
return $items[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int,ChiamataPostIt> $items
|
||||
*/
|
||||
private function resolveGroupedCallerLabel(array $items): string
|
||||
{
|
||||
foreach ($items as $item) {
|
||||
$label = trim((string) ($item->nome_chiamante ?? ''));
|
||||
if ($label !== '') {
|
||||
return $label;
|
||||
}
|
||||
}
|
||||
|
||||
return 'Chiamante non identificato';
|
||||
}
|
||||
|
||||
public function richiediClickToCallDaMessaggio(int $messageId): void
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@
|
|||
<button type="button" wire:click="$set('activeTab', 'storico')" class="rounded-md px-3 py-1.5 text-xs font-medium {{ $activeTab === 'storico' ? 'bg-indigo-700 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200' }}">
|
||||
Storico Post-it
|
||||
</button>
|
||||
<button type="button" wire:click="$set('activeTab', 'lavagna')" class="rounded-md px-3 py-1.5 text-xs font-medium {{ $activeTab === 'lavagna' ? 'bg-amber-600 text-white' : 'bg-amber-50 text-amber-900 hover:bg-amber-100' }}">
|
||||
Lavagna chiamate
|
||||
</button>
|
||||
<button type="button" wire:click="$set('activeTab', 'smdr')" class="rounded-md px-3 py-1.5 text-xs font-medium {{ $activeTab === 'smdr' ? 'bg-indigo-700 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200' }}">
|
||||
Chiamate Tecniche SMDR
|
||||
</button>
|
||||
|
|
@ -33,62 +36,8 @@
|
|||
<div class="rounded-xl border bg-white p-4">
|
||||
<h2 class="mb-3 text-base font-semibold">Storico chiamate recenti</h2>
|
||||
|
||||
<div class="mb-5">
|
||||
<div class="mb-2 flex items-center justify-between gap-2">
|
||||
<div>
|
||||
<div class="text-sm font-semibold text-slate-800">Box chiamate raggruppate</div>
|
||||
<div class="text-xs text-slate-500">Le comunicazioni interne non compaiono qui. Le chiamate consecutive dello stesso numero restano nello stesso box finche non interviene un altro chiamante.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-3 md:grid-cols-2 xl:grid-cols-3">
|
||||
@forelse($this->recentiRaggruppati as $gruppo)
|
||||
@php($box = $gruppo['latest'])
|
||||
<div class="rounded-xl border border-slate-200 bg-slate-50 p-4">
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<div class="font-semibold text-slate-900">{{ $gruppo['caller_label'] }}</div>
|
||||
<div class="text-sm text-slate-600">
|
||||
{{ $gruppo['phone'] !== '' ? $gruppo['phone'] : 'Numero non disponibile' }}
|
||||
@if($gruppo['route_label'] !== '-')
|
||||
· verso {{ $gruppo['route_label'] }}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<span class="rounded-full bg-indigo-100 px-2.5 py-1 text-xs font-semibold text-indigo-800">{{ $gruppo['count'] }} tentativi</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 text-xs text-slate-500">{{ $gruppo['last_at'] }}{{ $gruppo['count'] > 1 ? ' · gruppo consecutivo' : '' }}</div>
|
||||
<div class="mt-2 text-sm text-slate-700">{{ $box->oggetto ?: 'Senza oggetto' }}</div>
|
||||
|
||||
<div class="mt-3 flex flex-wrap gap-2 text-[11px]">
|
||||
<span class="rounded-md bg-white px-2 py-1 text-slate-700">{{ $box->stato }}</span>
|
||||
@if($box->assegnazione_tipo)
|
||||
<span class="rounded-md bg-amber-100 px-2 py-1 text-amber-800">{{ ucfirst(str_replace('_', ' ', (string) $box->assegnazione_tipo)) }}</span>
|
||||
@endif
|
||||
@if($box->assegnatoAUser)
|
||||
<span class="rounded-md bg-emerald-100 px-2 py-1 text-emerald-800">{{ $box->assegnatoAUser->name }}</span>
|
||||
@endif
|
||||
@if($box->assegnatoAFornitore)
|
||||
<span class="rounded-md bg-emerald-100 px-2 py-1 text-emerald-800">{{ $box->assegnatoAFornitore->ragione_sociale ?: trim(($box->assegnatoAFornitore->nome ?? '') . ' ' . ($box->assegnatoAFornitore->cognome ?? '')) }}</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="mt-4 flex flex-wrap gap-2">
|
||||
<a href="{{ $this->getPostItPageUrl((int) $box->id) }}" class="inline-flex items-center rounded-md bg-indigo-700 px-3 py-1.5 text-xs font-medium text-white hover:bg-indigo-600">Apri Post-it</a>
|
||||
@if($box->ticket_id)
|
||||
<a href="{{ \App\Filament\Pages\Supporto\TicketGestione::getUrl(panel: 'admin-filament') }}#ticket-{{ (int) $box->ticket_id }}" class="inline-flex items-center rounded-md border px-3 py-1.5 text-xs">Apri ticket</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="rounded-lg border border-dashed p-4 text-sm text-gray-500 md:col-span-2 xl:col-span-3">Nessuna chiamata esterna raggruppabile disponibile.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="space-y-3">
|
||||
@forelse($this->recenti as $riga)
|
||||
@forelse($this->recentiVisibili as $riga)
|
||||
<div @class([
|
||||
'rounded-lg border p-3',
|
||||
'border-emerald-400 bg-emerald-50/60 ring-1 ring-emerald-200' => (int) ($this->focusPostItId ?? 0) === (int) $riga->id,
|
||||
|
|
@ -159,6 +108,70 @@
|
|||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
@elseif($activeTab === 'lavagna')
|
||||
<div class="rounded-xl border border-amber-200 bg-amber-50/40 p-4">
|
||||
<div class="mb-4">
|
||||
<h2 class="text-base font-semibold text-amber-900">Lavagna chiamate raggruppate</h2>
|
||||
<p class="text-sm text-amber-800">Qui vedi i Post-it raggruppati per numero chiamante. Le chiamate interne restano nel database ma non vengono visualizzate.</p>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
|
||||
@forelse($this->recentiRaggruppati as $gruppo)
|
||||
@php($box = $gruppo['latest'])
|
||||
<article class="rounded-2xl border border-amber-200 bg-[#fff4b8] p-4 shadow-sm">
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<div class="text-sm font-semibold uppercase tracking-wide text-amber-900">{{ $box->oggetto ?: 'Post-it chiamate' }}</div>
|
||||
<div class="mt-1 text-sm text-amber-950">
|
||||
{{ $gruppo['caller_label'] }}
|
||||
@if($gruppo['phone'] !== '')
|
||||
- {{ $gruppo['phone'] }}
|
||||
@endif
|
||||
</div>
|
||||
@php($rubricaUrlGrouped = $this->getRubricaUrlByPhone((string) $gruppo['phone']))
|
||||
@if($rubricaUrlGrouped)
|
||||
<a href="{{ $rubricaUrlGrouped }}" class="mt-1 inline-flex text-xs font-medium text-indigo-700 hover:underline">Apri scheda rubrica</a>
|
||||
@endif
|
||||
</div>
|
||||
<span class="rounded-full bg-amber-200 px-2.5 py-1 text-xs font-semibold text-amber-900">{{ $gruppo['count'] }} chiamate</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 text-xs text-amber-900">
|
||||
Aperto dal {{ $gruppo['first_at'] }} al {{ $gruppo['last_at'] }}
|
||||
</div>
|
||||
|
||||
<div class="mt-4 space-y-3 border-t border-amber-300 pt-3">
|
||||
@foreach($gruppo['items'] as $item)
|
||||
<div class="rounded-xl border border-amber-300 bg-amber-50/70 p-3">
|
||||
<div class="flex items-start justify-between gap-3">
|
||||
<div>
|
||||
<div class="text-sm font-medium text-amber-950">{{ $item->oggetto ?: 'Senza oggetto' }}</div>
|
||||
<div class="text-xs text-amber-800">{{ optional($item->chiamata_il)->format('d/m/Y H:i') }}</div>
|
||||
</div>
|
||||
<span class="rounded-md bg-white/70 px-2 py-1 text-[11px] text-amber-900">{{ $item->stato }}</span>
|
||||
</div>
|
||||
|
||||
@if($item->stabile)
|
||||
<div class="mt-1 text-xs text-amber-900">{{ $item->stabile->denominazione ?: ('Stabile #' . $item->stabile->id) }}</div>
|
||||
@endif
|
||||
|
||||
<div class="mt-2 whitespace-pre-wrap text-xs text-amber-950">{{ $item->nota }}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="mt-4 flex flex-wrap gap-2">
|
||||
<a href="{{ $this->getPostItPageUrl((int) $box->id) }}" class="inline-flex items-center rounded-md bg-amber-700 px-3 py-1.5 text-xs font-medium text-white hover:bg-amber-600">Apri Post-it</a>
|
||||
@if($box->ticket_id)
|
||||
<a href="{{ \App\Filament\Pages\Supporto\TicketGestione::getUrl(panel: 'admin-filament') }}#ticket-{{ (int) $box->ticket_id }}" class="inline-flex items-center rounded-md border border-amber-400 bg-white/70 px-3 py-1.5 text-xs text-amber-900">Apri ticket</a>
|
||||
@endif
|
||||
</div>
|
||||
</article>
|
||||
@empty
|
||||
<div class="rounded-lg border border-dashed border-amber-300 bg-white/70 p-4 text-sm text-amber-900 md:col-span-2 xl:col-span-3">Nessuna chiamata esterna disponibile per la lavagna.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
@elseif(in_array($activeTab, ['smdr', 'csta'], true))
|
||||
<div class="rounded-xl border bg-white p-4">
|
||||
@php($isCstaTab = $activeTab === 'csta')
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user