Passa al contenuto principale

Componenti UI — dominio job

🎯 Cosa fa

Sotto TrainingHub.BackOffice/Components/CRUD/job/ vivono i componenti Blazor CRUD per le 13 entità del dominio. Pattern generazione identico a inv, reg, edu: vedi componenti UI inv per dettagli generali.

🗺️ Entità e viste

CRUD standard

EntitàNote
WorkerForm ricco con cascade FK molteplici (company, companyLocation, role, department, riskLevel, academicQualification)
WorkerJobHistoryTipicamente in sola lettura, alimentato da logica di cambio mansione
WorkersJobAssociazione lavoratore-mansione
Job, JobGroup, JobSubcategoryAnagrafiche mansioni
Role, DepartmentAnagrafiche ruoli/reparti (reparti con tree view)
Risk, RiskLevelAnagrafiche rischi e livelli
AtecoCodeTree view gerarchica
AtecoCodeLegacyCRUD su atecoCodesLegacy. Esposto come admin tool per popolare/aggiornare il mapping versioni precedenti → codice corrente; non parte del flusso operativo utente. Alimenta la conversione automatica nell'import aziende (TrainingHub.Import/Engines/Company.cs ClearCompanyData).
CompaniesRisk, JobsRisk, WorkersRiskAssociazioni rischio per livello

Viste aggregate / analitiche

ComponenteRuolo
WorkersData.razorVista dati lavoratori con aggregazioni
JobsData.razorVista mansioni con statistiche
WorkerEffectiveRisk.razorVista calcolata dei rischi finali del lavoratore (cascade applicato)
WorkerComplianceSummary.razorCRUD auto-generato sulla view vw_workerComplianceSummary (read-only). Mostra rollup compliance per lavoratore: badge worstStatus + conteggi + giorni residui. Embed nello step "Conformità formativa" del wizard CompanyFormPopup con filtro companyId. Vedi pattern in Architettura — view → CRUD

WorkersData, JobsData e WorkerEffectiveRisk non sono CRUD: sono componenti custom che consumano dati da più tabelle. WorkerComplianceSummary invece è un CRUD a tutti gli effetti, ma la sua sorgente è una view read-only.

🧩 Pattern chiave job-specifici

Form Worker con molteplici FK

WorkerForm.razor contiene ~6 combobox cascade-oriented:

<EditComboBox Data="fk_companyId" ... />
<EditComboBox Data="fk_companyLocationId" ... /> <!-- filtrato per companyId -->
<EditComboBox Data="fk_departmentId" ... /> <!-- filtrato per companyId -->
<EditComboBox Data="fk_roleId" ... />
<EditComboBox Data="fk_riskLevelId" ... />
<EditComboBox Data="fk_academicQualificationId" ... />

Il filtro dinamico dei combobox "dipendenti" (companyLocation, department filtrati per company) è logica custom nel .razor.cs. Al cambio companyId, i combobox correlati vengono ricaricati con il nuovo filtro.

Vista WorkerEffectiveRisk

Componente custom che implementa il cascade rischi:

  1. Carica rischi azienda del lavoratore.
  2. Carica rischi mansioni attive del lavoratore (se jobs.inheritsCompanyRisks = 1, somma quelli azienda).
  3. Applica override / esclusioni da workersRisks.
  4. Restituisce la lista finale di rischi con livello effettivo.

Utile per:

  • Verifica manuale da parte del RSPP.
  • Generazione bozza DVR individuale.
  • Determinazione formazione richiesta (consumato da ITrainingExpirationService).

Tree view reparti gerarchici

Department.razor usa una tree view per rappresentare la gerarchia parentId → childrenIds. Drag-and-drop per riorganizzare? Da verificare nel codice.

Tree view ATECO

AtecoCode.razor simile: gerarchia parentCode → childrenCodes. Tipicamente i dati sono pre-popolati da sistema (codici ATECO ufficiali) e solo letti dall'utente. Da verificare se l'utente può modificare o se è read-only in UI.

Auto-calcolo dal codice fiscale

Nel WorkerForm.razor.cs, se è popolato fiscalCode valido:

  • Pulsante o trigger automatico → calcola birthDate, gender, birthPlace (se CF italiano valido).
  • Logica potenzialmente in un helper condiviso (libreria Luhn-like per CF italiano).

Implementazione da ispezionare per dettaglio.

📁 File chiave

  • Components/CRUD/job/Worker.razor.cs — code-behind principale
  • Components/CRUD/job/Forms/WorkerForm.razor{,.cs} — form con cascade FK e auto-calcolo CF
  • Components/CRUD/job/WorkerEffectiveRisk.razor — vista cascade rischi
  • Components/CRUD/job/Department.razor + tree view helper
  • Components/CRUD/job/AtecoCode.razor + tree view
  • Components/CRUD/job/_conf/*.dxgrid.conf.json — configurazione

🔌 Estensione tipica

Pattern generale come nei domini precedenti. Specificità job:

  • Aggiungere un campo worker. Molti campi esistenti richiedono logica custom nel .razor.cs (cascade FK); valutare se il nuovo campo necessita di logica o è "semplice" form field.
  • Aggiungere un livello di rischio. Inserire riga in riskLevel (PK int) con label. Gli override lato UI non servono se i combobox sono già dinamici.
  • Modificare cascade rischi. Logica centrale in IRiskInheritanceService: modifiche lì invece che nel UI.
  • Nuova vista analitica. Segui il pattern di WorkersData / WorkerEffectiveRisk: componente Razor custom non-CRUD con @page directive, inject dei service necessari.

⚠️ Debito tecnico

  • Cascade filtri combobox in WorkerForm. La logica di filtro dinamico (companyLocation per company, department per company) è duplicata tra form. Valutare helper condiviso.
  • WorkerEffectiveRisk senza test. Componente centrale per compliance, ma senza copertura automatica. Regressioni difficili da detect.
  • Vista JobsData / WorkersData. Non è chiaro se sono "live" o cachate. Performance su dataset grandi.
  • Tree view reparti e ATECO duplicati. Due componenti tree view non condividono codice comune. Estrarre TreeViewBase.
  • Pulsante auto-calcolo CF. Se esiste, verificarne uso reale: a volte pulsanti "fancy" restano unused perché utenti preferiscono digitare tutto a mano.

🔗 Vedi anche