Compare commits

...

3 Commits

4 changed files with 293 additions and 328 deletions

View File

@ -29,7 +29,7 @@ export interface StrutturePubblicheControllerFindManyStrutture$Params {
/** /**
* Regione * Regione
*/ */
regione: string; regione?: string;
/** /**
* Sigla Provincia * Sigla Provincia

View File

@ -1,148 +1,114 @@
@let vm = (model$ | async)!; @let vm = (model$ | async)!;
<div <div class="bg-surface-0 dark:bg-surface-950 p-6 md:p-12 lg:p-15 flex flex-col gap-8">
class="bg-surface-0 dark:bg-surface-950 p-6 md:p-12 lg:p-15 flex flex-col gap-8" <div class="flex flex-col md:flex-row justify-between items-center md:items-end gap-4 md:gap-6">
>
<div
class="flex flex-col md:flex-row justify-between items-center md:items-end gap-4 md:gap-6"
>
<div> <div>
<img <img src="assets/images/MUSA/logo.png"
src="assets/images/MUSA/logo.png" alt="logo-consorzio-musa"
alt="logo-consorzio-musa" class="block mx-auto"
class="block mx-auto" style="height: 50px" />
style="height: 50px"
/>
</div> </div>
<div class="flex-1 flex flex-col text-center md:text-left"> <div class="flex-1 flex flex-col text-center md:text-left">
<h1 <h1 class="text-surface-900 dark:text-surface-0 text-2xl font-semibold leading-tight">
class="text-surface-900 dark:text-surface-0 text-2xl font-semibold leading-tight"
>
Consorzio Mu.Sa. Consorzio Mu.Sa.
</h1> </h1>
<h2 <h2 class="text-surface-500 dark:text-surface-200 text-xl font-normal leading-tight">
class="text-surface-500 dark:text-surface-200 text-xl font-normal leading-tight"
>
Cerca strutture convenzionate Cerca strutture convenzionate
</h2> </h2>
</div> </div>
</div> </div>
<p-divider class="w-full my-0!"></p-divider> <p-divider class="w-full my-0!"></p-divider>
<form [formGroup]="cercaStruttureForm" (ngSubmit)="getStrutture()"> <form [formGroup]="cercaStruttureForm"
(ngSubmit)="getStrutture()">
<div class="flex flex-wrap gap-8 md:gap-6 items-start"> <div class="flex flex-wrap gap-8 md:gap-6 items-start">
<div <div
class="flex-3 bg-surface-0 dark:bg-surface-950 flex flex-col justify-start items-start gap-8 md:gap-12 w-full" class="flex-3 bg-surface-0 dark:bg-surface-950 flex flex-col justify-start items-start gap-8 md:gap-12 w-full">
>
<div class="self-stretch flex flex-col justify-start items-start gap-6"> <div class="self-stretch flex flex-col justify-start items-start gap-6">
<div <div class="self-stretch flex flex-col justify-start items-start gap-6">
class="self-stretch flex flex-col justify-start items-start gap-6"
>
<div <div
class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-lg md:text-xl font-semibold leading-tight" class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-lg md:text-xl font-semibold leading-tight">
>
Strutture Convenzionate Strutture Convenzionate
</div> </div>
<div <div class="self-stretch flex flex-col justify-start items-start gap-4">
class="self-stretch flex flex-col justify-start items-start gap-4" <div class="self-stretch flex flex-col justify-start items-start gap-2">
> <div id="tipoStruttura"
<div class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight">
class="self-stretch flex flex-col justify-start items-start gap-2"
>
<div
id="tipoStruttura"
class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight"
>
Tipologia struttura Tipologia struttura
</div> </div>
<p-select <p-select [options]="vm.tipologieStrutture"
[options]="vm.tipologieStrutture" class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0"
class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0" name="tiplogiaStruttura"
name="tiplogiaStruttura" appendTo="body"
appendTo="body" formControlName="tipologiaStruttura"
formControlName="tipologiaStruttura" placeholder="Seleziona il tipo struttura"
placeholder="Seleziona il tipo struttura" showClear="true"
showClear="true" optionLabel="descrizione"
optionLabel="descrizione" optionValue="codice"
optionValue="codice" ariaLabelledBy="tipoStruttura"
ariaLabelledBy="tipoStruttura" emptyFilterMessage="Nessuna tipologia struttura trovata"
emptyFilterMessage="Nessuna tipologia struttura trovata" emptyMessage="Nessuna tipologia struttura trovata"
emptyMessage="Nessuna tipologia struttura trovata" [loading]="vm.tipologieStruttureAreLoading"
[loading]="vm.tipologieStruttureAreLoading" [filter]="true"></p-select>
[filter]="true"
></p-select>
</div> </div>
</div> </div>
<div <div class="self-stretch flex flex-col md:flex-row justify-start items-start gap-4">
class="self-stretch flex flex-col md:flex-row justify-start items-start gap-4" <div class="flex-1 flex flex-col justify-start items-start gap-2 w-full hidden">
> <div id="stato"
<div class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight">
class="flex-1 flex flex-col justify-start items-start gap-2 w-full" Stato<small class="text-red-600">*
>
<div
id="stato"
class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight"
>
Stato<small class="text-red-600"
>*
@if ( @if (
cercaStruttureForm.controls.stato.errors?.['required'] && cercaStruttureForm.controls.stato.errors?.['required'] &&
vm.cercaStruttureFormSubmitted vm.cercaStruttureFormSubmitted
) { ) {
Stato obbligatorio Stato obbligatorio
} }
</small> </small>
</div> </div>
<p-select <p-select [options]="vm.stati"
[options]="vm.stati" class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0"
class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0" [ngClass]="{
[ngClass]="{
'ng-invalid ng-dirty': 'ng-invalid ng-dirty':
cercaStruttureForm.controls.stato.errors?.['required'] && cercaStruttureForm.controls.stato.errors?.['required'] &&
vm.cercaStruttureFormSubmitted, vm.cercaStruttureFormSubmitted,
}" }"
name="stato" name="stato"
appendTo="body" appendTo="body"
formControlName="stato" formControlName="stato"
placeholder="Seleziona lo stato" placeholder="Seleziona lo stato"
showClear="true" showClear="true"
optionLabel="stato" optionLabel="stato"
ariaLabelledBy="stato" ariaLabelledBy="stato"
emptyFilterMessage="Nessuno Stato trovato" emptyFilterMessage="Nessuno Stato trovato"
emptyMessage="Nessuno Stato trovato" emptyMessage="Nessuno Stato trovato"
[loading]="vm.statiAreLoading" [loading]="vm.statiAreLoading"
[filter]="true" [filter]="true">
> <ng-template #selectedItem
<ng-template #selectedItem let-selectedOption> let-selectedOption>
<div class="flex items-center gap-2" *ngIf="selectedOption"> <div class="flex items-center gap-2"
<img *ngIf="selectedOption">
src="./assets/images/flags/{{ <img src="./assets/images/flags/{{
selectedOption.codiceStato | lowercase selectedOption.codiceStato | lowercase
}}.png" }}.png"
style="width: 18px; vertical-align: middle" style="width: 18px; vertical-align: middle"
onerror="this.style.display='none'" onerror="this.style.display='none'" />
/>
<div>{{ selectedOption.stato }}</div> <div>{{ selectedOption.stato }}</div>
</div> </div>
</ng-template> </ng-template>
<ng-template let-stato #item> <ng-template let-stato
#item>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<img <img src="./assets/images/flags/{{
src="./assets/images/flags/{{
stato.codiceStato | lowercase stato.codiceStato | lowercase
}}.png" }}.png"
style="width: 18px; vertical-align: middle" style="width: 18px; vertical-align: middle"
onerror="this.style.display='none'" onerror="this.style.display='none'" />
/>
<div>{{ stato.stato }}</div> <div>{{ stato.stato }}</div>
</div> </div>
</ng-template> </ng-template>
<ng-template #dropdownicon> <ng-template #dropdownicon>
<i class="pi pi-map"></i> <i class="pi pi-map"></i>
</ng-template> </ng-template>
<ng-template #header>
<div class="font-medium p-3">Stati</div>
</ng-template>
</p-select> </p-select>
<!-- <p-autoComplete #acSt <!-- <p-autoComplete #acSt
formControlName="luogo" formControlName="luogo"
@ -234,124 +200,100 @@
</ng-template> </ng-template>
</p-autoComplete> --> </p-autoComplete> -->
</div> </div>
<div <div *ngIf="
*ngIf="cercaStruttureForm.controls.stato.value" cercaStruttureForm.controls.stato.value &&
class="flex-1 flex flex-col justify-start items-start gap-2 w-full" cercaStruttureForm.controls.stato.value.codiceStato === 'ITA'
> "
<div class="flex-1 flex flex-col justify-start items-start gap-2 w-full">
id="regione" <div id="regione"
class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight" class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight">
> Regione<small class="text-red-600">*
Regione<small class="text-red-600"
>*
@if ( @if (
cercaStruttureForm.controls.regione.errors?.[ cercaStruttureForm.controls.regione.errors?.[
'required' 'required'
] && vm.cercaStruttureFormSubmitted ] && vm.cercaStruttureFormSubmitted
) { ) {
Regione obbligatorio Regione obbligatorio
} }
</small> </small>
</div> </div>
<p-select <p-select [options]="vm.regioni"
[options]="vm.regioni" class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0"
class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0" [ngClass]="{
[ngClass]="{
'ng-dirty ng-invalid': 'ng-dirty ng-invalid':
cercaStruttureForm.controls.regione.errors?.[ cercaStruttureForm.controls.regione.errors?.[
'required' 'required'
] && vm.cercaStruttureFormSubmitted, ] && vm.cercaStruttureFormSubmitted,
}" }"
name="regione" name="regione"
appendTo="body" appendTo="body"
formControlName="regione" formControlName="regione"
placeholder="Seleziona la regione" placeholder="Seleziona la regione"
showClear="true" showClear="true"
optionLabel="regione" optionLabel="regione"
ariaLabelledBy="regione" ariaLabelledBy="regione"
emptyFilterMessage="Nessuna Regione trovata" emptyFilterMessage="Nessuna Regione trovata"
emptyMessage="Nessuna Regione trovata" emptyMessage="Nessuna Regione trovata"
[loading]="vm.regioniAreLoading" [loading]="vm.regioniAreLoading"
[filter]="true" [filter]="true" />
/>
</div> </div>
<div <div *ngIf="cercaStruttureForm.controls.regione.value"
*ngIf="cercaStruttureForm.controls.regione.value" class="flex-1 flex flex-col justify-start items-start gap-2 w-full">
class="flex-1 flex flex-col justify-start items-start gap-2 w-full" <div id="provincia"
> class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight">
<div
id="provincia"
class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight"
>
Provincia Provincia
</div> </div>
<p-select <p-select [options]="vm.province"
[options]="vm.province" class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0"
class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0" name="provincia"
name="provincia" appendTo="body"
appendTo="body" formControlName="provincia"
formControlName="provincia" placeholder="Seleziona la provincia"
placeholder="Seleziona la provincia" showClear="true"
showClear="true" optionLabel="provincia"
optionLabel="provincia" ariaLabelledBy="provincia"
ariaLabelledBy="provincia" emptyFilterMessage="Nessuna Provincia trovata"
emptyFilterMessage="Nessuna Provincia trovata" emptyMessage="Nessuna Provincia trovata"
emptyMessage="Nessuna Provincia trovata" [loading]="vm.provinceAreLoading"
[loading]="vm.provinceAreLoading" [filter]="true">
[filter]="true"
>
</p-select> </p-select>
</div> </div>
<div <div *ngIf="cercaStruttureForm.controls.provincia.value"
*ngIf="cercaStruttureForm.controls.provincia.value" class="flex-1 flex flex-col justify-start items-start gap-2 w-full">
class="flex-1 flex flex-col justify-start items-start gap-2 w-full" <div id="citta"
> class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight">
<div
id="citta"
class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight"
>
Città Città
</div> </div>
<p-select <p-select [options]="vm.citta"
[options]="vm.citta" class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0"
class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0" name="citta"
name="citta" appendTo="body"
appendTo="body" formControlName="citta"
formControlName="citta" placeholder="Seleziona la città"
placeholder="Seleziona la città" showClear="true"
showClear="true" optionLabel="comune"
optionLabel="comune" ariaLabelledBy="citta"
ariaLabelledBy="citta" emptyFilterMessage="Nessuna Città trovata"
emptyFilterMessage="Nessuna Città trovata" emptyMessage="Nessuna Città trovata"
emptyMessage="Nessuna Città trovata" [loading]="vm.cittaAreLoading"
[loading]="vm.cittaAreLoading" [filter]="true">
[filter]="true"
>
</p-select> </p-select>
</div> </div>
</div> </div>
</div> </div>
<div <div class="self-stretch flex flex-col justify-start items-start gap-6">
class="self-stretch flex flex-col justify-start items-start gap-6" <div class="flex-1 flex flex-col justify-start items-start gap-2 w-full">
> <div id="indirizzo"
<div class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight">
class="flex-1 flex flex-col justify-start items-start gap-2 w-full"
>
<div
id="indirizzo"
class="self-stretch justify-start text-surface-900 dark:text-surface-0 text-base font-normal leading-tight"
>
Indirizzo Indirizzo
</div> </div>
<input <input type="text"
type="text" class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0"
class="flex-auto lg:flex-1 lg:mt-0 w-full mr-0 lg:mr-1 text-surface-900 dark:text-surface-0" formControlName="indirizzo"
formControlName="indirizzo" pInputText
pInputText aria-labelledby="indirizzo"
aria-labelledby="indirizzo" placeholder="Inserisci l'indirizzo" />
placeholder="Inserisci l'indirizzo"
/>
</div> </div>
</div> </div>
<!-- <div class="self-stretch flex flex-col md:flex-row justify-end items-center gap-4"> <!-- <div class="self-stretch flex flex-col md:flex-row justify-end items-center gap-4">
@ -452,140 +394,124 @@
</div> </div>
</div> --> </div> -->
<div <div class="self-stretch flex flex-col md:flex-row justify-end items-center gap-4">
class="self-stretch flex flex-col md:flex-row justify-end items-center gap-4" <button pButton
> severity="secondary"
<button class="w-full md:w-auto"
pButton (click)="cercaStruttureForm.reset()"
severity="secondary" [outlined]="true">
class="w-full md:w-auto"
(click)="cercaStruttureForm.reset()"
[outlined]="true"
>
<span pButtonLabel>Annulla filtri</span> <span pButtonLabel>Annulla filtri</span>
</button> </button>
<button <button pButton
pButton type="submit"
type="submit" [disabled]="vm.isSearching"
[disabled]="vm.isSearching" [loading]="vm.isSearching"
[loading]="vm.isSearching" icon="pi pi-search"
icon="pi pi-search" [label]="
[label]="
vm.isSearching ? 'Ricerca in corso...' : 'Cerca strutture' vm.isSearching ? 'Ricerca in corso...' : 'Cerca strutture'
" "
severity="primary" severity="primary"
class="w-full md:w-auto" class="w-full md:w-auto"></button>
></button>
</div> </div>
</div> </div>
</div> </div>
<div <div
class="flex-auto lg:flex-2 bg-surface-50 dark:bg-surface-900 rounded-2xl border-2 border-dashed border-surface-200 dark:border-surface-700 h-[343px] w-full lg:1/2" class="flex-auto lg:flex-2 bg-surface-50 dark:bg-surface-900 rounded-2xl border-2 border-dashed border-surface-200 dark:border-surface-700 h-[343px] w-full lg:1/2">
> <google-map #gmap
<google-map #gmap height="100%" width="100%" [options]="options"> height="100%"
<map-marker width="100%"
#marker="mapMarker" [options]="options">
*ngFor="let markerOption of markerOptions; let i = index" <map-marker #marker="mapMarker"
[options]="markerOption" *ngFor="let markerOption of markerOptions; let i = index"
(mapClick)="openInfoWindow(marker, i)" [options]="markerOption"
></map-marker> (mapClick)="openInfoWindow(marker, i)"></map-marker>
<map-info-window></map-info-window> <map-info-window></map-info-window>
</google-map> </google-map>
</div> </div>
</div> </div>
</form> </form>
<p-table <p-table #struttureTable
#struttureTable *ngIf="vm.strutture !== undefined"
*ngIf="vm.strutture !== undefined" [totalRecords]="vm.strutture.length"
[totalRecords]="vm.strutture.length" dataKey="id"
dataKey="id" [loading]="vm.struttureAreLoading"
[loading]="vm.struttureAreLoading" [value]="vm.strutture"
[value]="vm.strutture" [columns]="cols"
[columns]="cols" [showCurrentPageReport]="!vm.struttureAreLoading"
[showCurrentPageReport]="!vm.struttureAreLoading" responsiveLayout="scroll"
responsiveLayout="scroll" currentPageReportTemplate="Strutture {first} - {last} di {totalRecords}"
currentPageReportTemplate="Strutture {first} - {last} di {totalRecords}" [paginator]="true"
[paginator]="true" [rows]="10"
[rows]="10" [autoLayout]="false"
[autoLayout]="false" responsiveLayout="stack"
responsiveLayout="stack" scrollHeight="400px"
scrollHeight="400px" [rowsPerPageOptions]="[10, 50, 100]"
[rowsPerPageOptions]="[10, 50, 100]" [globalFilterFields]="[
[globalFilterFields]="[
'struttura.nome', 'struttura.nome',
'struttura.struttureTipiStrutture', 'struttura.struttureTipiStrutture',
]" ]">
>
<ng-template #caption> <ng-template #caption>
<div class="flex"> <div class="flex">
<p-iconfield iconPosition="left" class="ml-auto"> <p-iconfield iconPosition="left"
class="ml-auto">
<p-inputicon> <p-inputicon>
<i class="pi pi-search"></i> <i class="pi pi-search"></i>
</p-inputicon> </p-inputicon>
<input <input pInputText
pInputText type="text"
type="text" aria-label="Filtra strutture"
aria-label="Filtra strutture" (input)="applyFilterGlobal($event, 'contains')"
(input)="applyFilterGlobal($event, 'contains')" placeholder="Filtra strutture" />
placeholder="Filtra strutture"
/>
</p-iconfield> </p-iconfield>
</div> </div>
</ng-template> </ng-template>
<ng-template pTemplate="header" let-columns> <ng-template pTemplate="header"
let-columns>
<tr> <tr>
<th <th *ngFor="let col of cols"
*ngFor="let col of cols" pResizableColumn
pResizableColumn [pSortableColumn]="col.sortField ?? ''"
[pSortableColumn]="col.sortField ?? ''" class="p-table-scrollable-header">
class="p-table-scrollable-header"
>
<div style="display: flex; align-items: center; text-wrap: nowrap"> <div style="display: flex; align-items: center; text-wrap: nowrap">
<div> <div>
{{ col.header }} {{ col.header }}
<p-sortIcon <p-sortIcon *ngIf="col.sortField"
*ngIf="col.sortField" [field]="col.sortField"></p-sortIcon>
[field]="col.sortField"
></p-sortIcon>
</div> </div>
</div> </div>
</th> </th>
</tr> </tr>
</ng-template> </ng-template>
<ng-template pTemplate="body" let-row let-rowIndex="rowIndex"> <ng-template pTemplate="body"
let-row
let-rowIndex="rowIndex">
<tr> <tr>
<ng-container *ngFor="let col of cols" [ngSwitch]="col.field"> <ng-container *ngFor="let col of cols"
[ngSwitch]="col.field">
<td *ngSwitchCase="'struttura.struttureTipiStrutture'"> <td *ngSwitchCase="'struttura.struttureTipiStrutture'">
<div> <div>
<ng-container <ng-container *ngFor="
*ngFor="
let item of row.struttura.struttureTipiStrutture.split(',') let item of row.struttura.struttureTipiStrutture.split(',')
" ">
> <span class="font-light">{{ item.trim() }}</span><br />
<span class="font-light">{{ item.trim() }}</span
><br />
</ng-container> </ng-container>
</div> </div>
</td> </td>
<td *ngSwitchCase="'struttura.nome'"> <td *ngSwitchCase="'struttura.nome'">
<div> <div>
<p-rating <p-rating *ngIf="row.struttura.stelline.length"
*ngIf="row.struttura.stelline.length" [(ngModel)]="row.struttura.stelline.length"
[(ngModel)]="row.struttura.stelline.length" [readonly]="true" />
[readonly]="true"
/>
<p> <p>
<b>{{ row.struttura.nome }}</b> <b>{{ row.struttura.nome }}</b>
</p> </p>
</div> </div>
<div *ngIf="row.struttura.sitoWeb" class="mt-4 ont-light"> <div *ngIf="row.struttura.sitoWeb"
<a class="mt-4 ont-light">
class="cursor-pointer hover:underline text-primary-700" <a class="cursor-pointer hover:underline text-primary-700"
(click)="externalLink(row.struttura.sitoWeb)" (click)="externalLink(row.struttura.sitoWeb)">Sito Web</a>
>Sito Web</a
>
</div> </div>
</td> </td>
<td *ngSwitchCase="'indirizzo'"> <td *ngSwitchCase="'indirizzo'">
@ -593,56 +519,46 @@
<p> <p>
{{ row.struttura.indirizzo {{ row.struttura.indirizzo
}}{{ }}{{
row.struttura.numeroCivico row.struttura.numeroCivico
? ', ' + row.struttura.numeroCivico ? ', ' + row.struttura.numeroCivico
: '' : ''
}} }}
</p> </p>
<p> <p>
{{ row.struttura.cap }} {{ row.struttura.cap }}
{{ {{
row.struttura.codiceLuogo row.struttura.codiceLuogo
? row.struttura.codiceLuogo.comune + ? row.struttura.codiceLuogo.comune +
' (' + ' (' +
row.struttura.codiceLuogo.siglaProvincia + row.struttura.codiceLuogo.siglaProvincia +
')' ')'
: '' : ''
}} }}
</p> </p>
<div class="text-sm" *ngIf="row.struttura.cupPubblico"> <div class="text-sm"
*ngIf="row.struttura.cupPubblico">
CUP Pubblico: CUP Pubblico:
<a <a class="cursor-pointer hover:underline text-primary-700"
class="cursor-pointer hover:underline text-primary-700" href="tel:{{ row.struttura.cupPubblico }}">{{ row.struttura.cupPubblico }}</a>
href="tel:{{ row.struttura.cupPubblico }}"
>{{ row.struttura.cupPubblico }}</a
>
</div> </div>
<div *ngIf="row.struttura.cupPrivato" class="text-sm"> <div *ngIf="row.struttura.cupPrivato"
class="text-sm">
CUP Privato: CUP Privato:
<a <a class="cursor-pointer hover:underline text-primary-700"
class="cursor-pointer hover:underline text-primary-700" href="tel:{{ row.struttura.cupPrivato }}">{{ row.struttura.cupPrivato }}</a>
href="tel:{{ row.struttura.cupPrivato }}"
>{{ row.struttura.cupPrivato }}</a
>
</div> </div>
<ng-container <ng-container *ngIf="!row.struttura.cupPubblico && !row.struttura.cupPrivato">
*ngIf="!row.struttura.cupPubblico && !row.struttura.cupPrivato" <div *ngIf="row.struttura.telefono1"
> class="text-sm">
<div *ngIf="row.struttura.telefono1" class="text-sm">
tel: tel:
<a <a class="cursor-pointer hover:underline text-primary-700"
class="cursor-pointer hover:underline text-primary-700" href="tel:{{ row.struttura.telefono1 }}">{{ row.struttura.telefono1 }}</a>
href="tel:{{ row.struttura.telefono1 }}"
>{{ row.struttura.telefono1 }}</a
>
</div> </div>
<div *ngIf="row.struttura.telefono2" class="text-sm"> <div *ngIf="row.struttura.telefono2"
class="text-sm">
tel: tel:
<a <a class="cursor-pointer hover:underline text-primary-700"
class="cursor-pointer hover:underline text-primary-700" href="tel:{{ row.struttura.telefono2 }}">{{ row.struttura.telefono2 }}</a>
href="tel:{{ row.struttura.telefono2 }}"
>{{ row.struttura.telefono2 }}</a
>
</div> </div>
</ng-container> </ng-container>
</span> </span>
@ -650,14 +566,12 @@
<td *ngSwitchCase="'posizione'"> <td *ngSwitchCase="'posizione'">
<div class="flex align-items-center"> <div class="flex align-items-center">
<p-button <p-button icon="pi pi-map-marker"
icon="pi pi-map-marker" label="Apri in Google Maps"
label="Apri in Google Maps" [rounded]="true"
[rounded]="true" styleClass="hover:underline text-primary-700"
styleClass="hover:underline text-primary-700" (onClick)="calculateMapsLink(row)"
(onClick)="calculateMapsLink(row)" [text]="true" />
[text]="true"
/>
</div> </div>
</td> </td>
</ng-container> </ng-container>

View File

@ -224,6 +224,10 @@ export class StrutturePubblicheComponent {
const fetchStati$ = this.strutturePubblicheService.getStati().pipe( const fetchStati$ = this.strutturePubblicheService.getStati().pipe(
tap(() => this.state.set({ statiAreLoading: true })), tap(() => this.state.set({ statiAreLoading: true })),
map((stati) => ({ stati })), map((stati) => ({ stati })),
tap((stati) => {
if (stati)
this.cercaStruttureForm.get('stato')?.setValue(stati.stati[0]);
}),
catchError(() => { catchError(() => {
this.messageService.add({ this.messageService.add({
severity: 'error', severity: 'error',
@ -241,6 +245,34 @@ export class StrutturePubblicheComponent {
const fetchRegioni$ = const fetchRegioni$ =
this.cercaStruttureForm.controls.stato.valueChanges.pipe( this.cercaStruttureForm.controls.stato.valueChanges.pipe(
tap(() => this.state.set({ regioniAreLoading: true })), tap(() => this.state.set({ regioniAreLoading: true })),
tap((stato) => {
const isITA = stato?.codiceStato === 'ITA';
if (!isITA) {
// Reset completo
this.resetLocation('stato');
// Disable cascata
this.cercaStruttureForm.get('regione')?.disable();
this.cercaStruttureForm.get('provincia')?.disable();
this.cercaStruttureForm.get('citta')?.disable();
// Rimuovo il required da regione (non serve più)
this.cercaStruttureForm.get('regione')?.clearValidators();
this.cercaStruttureForm.get('regione')?.updateValueAndValidity();
return;
}
// Se ITA → abilita tutto e rimetti validatori
this.cercaStruttureForm.get('regione')?.enable();
this.cercaStruttureForm.get('provincia')?.enable();
this.cercaStruttureForm.get('citta')?.enable();
this.cercaStruttureForm
.get('regione')
?.setValidators([Validators.required]);
this.cercaStruttureForm.get('regione')?.updateValueAndValidity();
}),
filter((stato) => !!stato), filter((stato) => !!stato),
switchMap((stato) => switchMap((stato) =>
this.strutturePubblicheService.getRegioni(stato.codiceStato).pipe( this.strutturePubblicheService.getRegioni(stato.codiceStato).pipe(
@ -255,6 +287,7 @@ export class StrutturePubblicheComponent {
const fetchProvince$ = const fetchProvince$ =
this.cercaStruttureForm.controls.regione.valueChanges.pipe( this.cercaStruttureForm.controls.regione.valueChanges.pipe(
tap(() => this.state.set({ provinceAreLoading: true })), tap(() => this.state.set({ provinceAreLoading: true })),
tap(() => this.resetLocation('regione')),
filter((regione) => !!regione), filter((regione) => !!regione),
switchMap((regione) => switchMap((regione) =>
this.strutturePubblicheService this.strutturePubblicheService
@ -271,6 +304,7 @@ export class StrutturePubblicheComponent {
const fetchCitta$ = const fetchCitta$ =
this.cercaStruttureForm.controls.provincia.valueChanges.pipe( this.cercaStruttureForm.controls.provincia.valueChanges.pipe(
tap(() => this.state.set({ cittaAreLoading: true })), tap(() => this.state.set({ cittaAreLoading: true })),
tap(() => this.resetLocation('provincia')),
filter((provincia) => !!provincia), filter((provincia) => !!provincia),
switchMap((provincia) => switchMap((provincia) =>
this.strutturePubblicheService this.strutturePubblicheService
@ -327,6 +361,23 @@ export class StrutturePubblicheComponent {
this.state.connect(fetchCities$); this.state.connect(fetchCities$);
} }
private resetLocation(level: 'stato' | 'regione' | 'provincia') {
if (level === 'stato') {
this.cercaStruttureForm.get('regione')?.reset();
this.cercaStruttureForm.get('provincia')?.reset();
this.cercaStruttureForm.get('citta')?.reset();
}
if (level === 'regione') {
this.cercaStruttureForm.get('provincia')?.reset();
this.cercaStruttureForm.get('citta')?.reset();
}
if (level === 'provincia') {
this.cercaStruttureForm.get('citta')?.reset();
}
}
getStrutture() { getStrutture() {
this.state.set({ this.state.set({
cercaStruttureFormSubmitted: true, cercaStruttureFormSubmitted: true,
@ -342,7 +393,7 @@ export class StrutturePubblicheComponent {
indirizzo: _form.indirizzo, indirizzo: _form.indirizzo,
tipoStruttura: _form.tipologiaStruttura, tipoStruttura: _form.tipologiaStruttura,
codiceStato: _form.stato!.codiceStato, codiceStato: _form.stato!.codiceStato,
regione: _form.regione!.regione, regione: _form.regione?.regione,
siglaProvincia: _form.provincia?.siglaProvincia, siglaProvincia: _form.provincia?.siglaProvincia,
comune: _form.citta?.comune, comune: _form.citta?.comune,
}; };
@ -537,7 +588,7 @@ export class StrutturePubblicheComponent {
? ', ' + struttura.struttura.numeroCivico ? ', ' + struttura.struttura.numeroCivico
: '' : ''
}`; }`;
address += `${struttura.struttura.cap} ${struttura.struttura.codiceLuogo.comune}(${struttura.struttura.codiceLuogo.siglaProvincia})`; address += ` ${struttura.struttura.cap} ${struttura.struttura.codiceLuogo.comune}(${struttura.struttura.codiceLuogo.siglaProvincia})`;
// address += `${struttura.struttura.codiceLuogo.provincia ? '(' + struttura.struttura.codiceLuogo.siglaProvincia + ')' : ''}`; // address += `${struttura.struttura.codiceLuogo.provincia ? '(' + struttura.struttura.codiceLuogo.siglaProvincia + ')' : ''}`;
const destination = encodeURIComponent( const destination = encodeURIComponent(