Primo rilascio
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
<h2 mat-dialog-title>{{ title }}</h2>
|
||||
|
||||
<mat-dialog-content [formGroup]="shiftForm">
|
||||
<!-- Messaggio errore validatore custom -->
|
||||
<mat-error *ngIf="shiftForm.hasError('timeRange') && (shiftForm.get('start_time')?.touched || shiftForm.get('end_time')?.touched)">
|
||||
L'orario di fine deve essere successivo all'orario di inizio.
|
||||
</mat-error>
|
||||
|
||||
<div class="form-grid">
|
||||
|
||||
<mat-form-field appearance="fill" class="full-width-field">
|
||||
<mat-label>Nome Definizione Turno</mat-label>
|
||||
<input matInput formControlName="name" required>
|
||||
<mat-error *ngIf="shiftForm.get('name')?.hasError('required')">
|
||||
Il nome è obbligatorio.
|
||||
</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Orario Inizio</mat-label>
|
||||
<input matInput type="time" formControlName="start_time" required placeholder="HH:MM">
|
||||
<mat-error *ngIf="shiftForm.get('start_time')?.hasError('required')">Orario inizio obbligatorio.</mat-error>
|
||||
<mat-error *ngIf="shiftForm.get('start_time')?.hasError('pattern')">Formato ora non valido (HH:MM).</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Orario Fine</mat-label>
|
||||
<input matInput type="time" formControlName="end_time" required placeholder="HH:MM">
|
||||
<mat-error *ngIf="shiftForm.get('end_time')?.hasError('required')">Orario fine obbligatorio.</mat-error>
|
||||
<mat-error *ngIf="shiftForm.get('end_time')?.hasError('pattern')">Formato ora non valido (HH:MM).</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" class="full-width-field">
|
||||
<mat-label>Note</mat-label>
|
||||
<textarea matInput formControlName="notes" rows="3"></textarea>
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions align="end">
|
||||
<button mat-button (click)="onCancel()">Annulla</button>
|
||||
<button mat-raised-button color="primary" (click)="onSave()" [disabled]="!shiftForm.valid">
|
||||
{{ isEditMode ? 'Salva Modifiche' : 'Aggiungi' }}
|
||||
</button>
|
||||
</mat-dialog-actions>
|
||||
@@ -0,0 +1,43 @@
|
||||
/* Contenitore per la griglia */
|
||||
.form-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr; /* Default: una colonna */
|
||||
gap: 0 16px; /* Spazio tra colonne */
|
||||
}
|
||||
|
||||
/* Campi a larghezza piena */
|
||||
.form-grid .full-width-field {
|
||||
grid-column: 1 / -1;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* Media Query per schermi più larghi */
|
||||
@media (min-width: 600px) {
|
||||
.form-grid {
|
||||
grid-template-columns: 1fr 1fr; /* Due colonne */
|
||||
}
|
||||
/* Fai occupare tutta la larghezza ai campi che devono stare da soli */
|
||||
.form-grid mat-form-field:first-child, /* Nome */
|
||||
.form-grid mat-form-field:has(textarea) /* Textarea */
|
||||
{
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Stili generali per i campi */
|
||||
mat-form-field {
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Contenuto dialog scrollabile */
|
||||
mat-dialog-content {
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Stile per errore validatore custom */
|
||||
mat-dialog-content > mat-error {
|
||||
margin-bottom: 15px;
|
||||
display: block;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
||||
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule, ValidatorFn, AbstractControl, ValidationErrors } from '@angular/forms';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { ShiftDefinition } from '../../services/shift-definition.service'; // Importa l'interfaccia
|
||||
|
||||
// Validatore custom per assicurare che end_time sia dopo start_time
|
||||
export const timeRangeValidator: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
|
||||
const start = control.get('start_time');
|
||||
const end = control.get('end_time');
|
||||
|
||||
// Confronta solo se entrambi i valori sono presenti e sembrano orari validi (HH:MM o HH:MM:SS)
|
||||
const timeRegex = /^\d{2}:\d{2}(:\d{2})?$/;
|
||||
if (start?.value && end?.value && timeRegex.test(start.value) && timeRegex.test(end.value)) {
|
||||
// Confronto semplice delle stringhe funziona per HH:MM o HH:MM:SS
|
||||
return start.value < end.value ? null : { timeRange: true }; // Errore se start >= end
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-shift-definition-dialog',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
ReactiveFormsModule,
|
||||
MatDialogModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatButtonModule
|
||||
],
|
||||
templateUrl: './shift-definition-dialog.component.html',
|
||||
styleUrl: './shift-definition-dialog.component.scss'
|
||||
})
|
||||
export class ShiftDefinitionDialogComponent implements OnInit {
|
||||
shiftForm: FormGroup;
|
||||
isEditMode: boolean;
|
||||
title: string;
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<ShiftDefinitionDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: { shift?: ShiftDefinition },
|
||||
private fb: FormBuilder
|
||||
) {
|
||||
this.isEditMode = !!data?.shift;
|
||||
this.title = this.isEditMode ? 'Modifica Definizione Turno' : 'Aggiungi Nuova Definizione Turno';
|
||||
|
||||
// Validatore per formato HH:MM o HH:MM:SS
|
||||
const timePattern = Validators.pattern(/^([01]\d|2[0-3]):([0-5]\d)(:([0-5]\d))?$/);
|
||||
|
||||
this.shiftForm = this.fb.group({
|
||||
name: ['', Validators.required],
|
||||
start_time: ['', [Validators.required, timePattern]],
|
||||
end_time: ['', [Validators.required, timePattern]],
|
||||
notes: ['']
|
||||
}, { validators: timeRangeValidator }); // Applica validatore custom al gruppo
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.isEditMode && this.data.shift) {
|
||||
this.shiftForm.patchValue(this.data.shift);
|
||||
}
|
||||
}
|
||||
|
||||
onCancel(): void {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
onSave(): void {
|
||||
if (this.shiftForm.valid) {
|
||||
this.dialogRef.close(this.shiftForm.value);
|
||||
} else {
|
||||
console.log('Shift Form Invalid:', this.shiftForm.errors);
|
||||
Object.keys(this.shiftForm.controls).forEach(key => {
|
||||
const control = this.shiftForm.get(key);
|
||||
if (control && control.errors) {
|
||||
console.log(`Control Error - ${key}:`, control.errors);
|
||||
}
|
||||
});
|
||||
this.shiftForm.markAllAsTouched();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user