Skip to content

Latest commit

Β 

History

26 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

WorkActivityTracker

Version Platform .NET License

A Windows desktop application for tracking daily work activities, built with .NET MAUI Blazor Hybrid and SQL Server. Designed for software teams: log work sessions, associate them with clients and software versions, track SVN/Git changesets, and manage deployments across frozen environments (test/production).

WorkActivityTracker Γ¨ un'applicazione desktop Windows per il tracciamento delle attivitΓ  lavorative giornaliere. Costruita con .NET MAUI Blazor Hybrid, utilizza una WebView interna per renderizzare un'interfaccia Bootstrap 5.

L'applicazione permette a uno o piΓΉ utenti (identificati dal login Windows) di registrare le proprie attivitΓ , associarle a clienti e versioni software, tracciare i changeset SVN/Git coinvolti e gestire il riporto delle modifiche sui congelati (ambienti di test/collaudo/produzione).


Screenshot

Interfaccia principale

Griglia delle attivitΓ  con filtri per anno/mese/giorno e form di inserimento/modifica con editor Note, Changeset, congelati e barra di stato in fondo.

Interfaccia principale


Segnalazioni Bug / Richieste di Modifica

Modale per inviare segnalazioni agli altri utenti, con griglia riepilogativa, filtri per stato e utente, e funzionalitΓ  di risposta.

Segnalazioni


Appunti / Knowledge Base

Modale per gestire una base di conoscenza personale: lista appunti con tag, editor ricco con toolbar di formattazione e filtro per tag.

Appunti


TODO List

Modale per la gestione dei TODO: griglia con stato, prioritΓ  e scadenza, form per aggiungere nuovi elementi e integrazione con il rilevamento TODO nelle attivitΓ .

TODO List


Ricerca Avanzata

Modale di ricerca full-text su tutti i campi delle attivitΓ , con anteprima del dettaglio e possibilitΓ  di selezionare direttamente l'attivitΓ  trovata.

Ricerca Avanzata


Panoramica


Setup e Requisiti

Requisiti di sistema

  • Visual Studio 2022 (17.8+) con workload:
    • Sviluppo .NET Multi-platform App UI (.NET MAUI)
    • Sviluppo ASP.NET e Web
  • .NET 10 SDK con workload MAUI: dotnet workload install maui
  • SQL Server (Express, Developer o Standard)

Setup Database

  1. Esegui Database/CreateDatabase.sql in SSMS per creare il database iniziale
  2. Applica in ordine tutti gli script MigrateToVX.Y.sql fino all'ultimo disponibile
  3. Crea il file appsettings.json nella root del progetto (non Γ¨ incluso nel repository) e configura la connection string:
{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=NOME_SERVER;Initial Catalog=WorkActivityTracker;Integrated Security=True;TrustServerCertificate=True"
  },
  "AppSettings": {
    "AppName": "Work Activity Tracker",
    "Version": "5.5",
    "NumeroMesiMantenimentoHistory": 3,
    "MostraModalitaAdmin": true,
    "PrivacyMode": false,
    "NomeProgramma": "MyProgram",
    "NomeCompagnia": "MyCompany",
    "TmpPatchDir": "C:\\TmpPatch\\",
    "GiorniPreavvisoScadenzaArancione": 5,
    "GiorniPreavvisoScadenzaRosso": 2,
    "EsportaAttivitaCollegateInPdf": true,
    "TimeoutQuerySecondi": 120
  }
}

NumeroMesiMantenimentoHistory (default 3): all'avvio le voci dello storico modifiche (EditorHistory) piΓΉ vecchie di questo numero di mesi vengono eliminate automaticamente in background. Un valore 0 o negativo disattiva la pulizia.

NomeProgramma / NomeCompagnia / TmpPatchDir (v5.2): usati dalle funzioni "Autoprepara struttura patch" e "Inserisci files Readme". NomeProgramma/NomeCompagnia sono i segnaposto ({NOMEPROGRAMMA}/{NOMECOMPAGNIA}) sostituiti nei nomi cartella e nei testi readme; TmpPatchDir (default C:\TmpPatch\) Γ¨ la cartella radice dove viene creata la struttura patch.

GiorniPreavvisoScadenzaArancione (default 5) / GiorniPreavvisoScadenzaRosso (default 2) (v5.3): giorni di preavviso entro i quali una riga della griglia con "Scadenza ticket" valorizzata viene evidenziata in arancione chiaro o in rosso. Le scadenze giΓ  passate usano un rosso piΓΉ marcato. Un valore 0 o negativo disattiva il livello corrispondente.

EsportaAttivitaCollegateInPdf (default true) (v5.3): se true, l'export PDF di una singola attivitΓ  include anche le attivitΓ  collegate dalla catena "Proseguo l'attivitΓ "; se false esporta la sola attivitΓ  selezionata.

TimeoutQuerySecondi (default 30) (v5.5): timeout in secondi dei comandi SQL. Il valore predefinito di SqlClient Γ¨ 30 secondi e sugli archivi grandi la ricerca puΓ² superarlo. Viene letto all'avvio: per renderlo effettivo occorre riavviare l'applicazione.

Eseguire l'applicazione

Da Visual Studio: apri WorkActivityTracker.csproj, seleziona Windows Machine, premi F5.


FunzionalitΓ  Principali

1. Gestione AttivitΓ  Lavorative

Ogni attivitΓ  registrata contiene:

Campo Tipo Descrizione
TipoAttivita string Lavoro / Permesso / Ferie
Data DateTime Data dell'attivitΓ 
Descrizione string Titolo breve obbligatorio (in grassetto)
OreLavorate decimal Ore dedicate (step 0.5)
Cliente FK Cliente associato
Versione string Versione software sviluppata (es: 3.2.61)
UrlTicket string URL ticket, CR, backlog (multiriga)
Vedere string Riferimenti esterni (email, Teams, ecc.)
CartellaDocumentazione string Path cartella locale con doc
Note HTML Descrizione dettagliata del lavoro (con grassetto)
TestoCheckIn string Testo del messaggio di check-in SCM (in grassetto)
ChangesetCoinvolti HTML Elenco changeset/commit coinvolti (con grassetto)
NumeroTicket string Numero/i del ticket (separati da virgola se piΓΉ di uno)
UrlPatchRilasci string URL patch/pacchetto nei rilasci (NVARCHAR(MAX), puΓ² contenere piΓΉ URL)
AmbientiSelezionatiIds List<int> Congelati su cui Γ¨ riportata la modifica
AmbientiRilascioNomi string? Nomi ambienti rilascio separati da virgola (solo lettura, per griglia)

Per i tipi Permesso e Ferie, vengono mostrati solo i campi Data, Ore, Descrizione e Note; gli altri campi vengono nascosti nell'interfaccia.

2. Griglia AttivitΓ 

  • Tabella con scroll verticale (max-height 300px) con sticky header.
  • Filtri: Anno / Mese / Giorno + ricerca testuale full-text + checkbox "Solo TODO".
    • All'avvio: Anno e Mese impostati al mese corrente, Giorno = "Tutti".
    • Bottone "πŸ“… Oggi" accanto al filtro Giorno: imposta automaticamente Anno/Mese/Giorno alla data odierna.
    • Combo Giorno con nomi ed emoji: quando Anno e Mese sono selezionati, ogni opzione mostra il numero + il giorno della settimana abbreviato in italiano (es. "1 - lun"). Vengono nascosti i giorni non validi per il mese selezionato. Emoji prefisso: 🟒 per il giorno odierno (ha la precedenza), 🟠 per sabato e domenica.
  • Rilevamento TODO preciso: regex (?<![a-zA-Z])TODO(?![a-zA-Z]) (word boundary, case-insensitive).
  • Evidenziazione TODO: riga rossa se TODO Γ¨ in Descrizione, Note, ChangesetCoinvolti, UrlTicket.
  • Riga selezionata: colore giallo vivace (#ffe066). Se riga TODO+selezionata: arancione.
  • Riga totale ore: footer con la somma delle ore delle attivitΓ  visibili, allineata sotto la colonna Ore.
  • Colonna Ambienti: mostra i nomi degli ambienti di rilascio compilati, separati da virgola (es. "Test, Produzione"), senza numero di versione. Calcolato da una query batch in ActivityService.GetActivitiesAsync() e salvato in WorkActivityDto.AmbientiRilascioNomi. Vuota se nessun ambiente Γ¨ stato associato.
  • Colonna Patch: mostra βœ” verde se il campo "URL Patch/Pacchetto nei rilasci" (UrlPatchRilasci) Γ¨ compilato.
  • Colonna Azioni: pulsanti Copia (πŸ“„), Esporta TXT (πŸ’Ύ), Duplica (πŸ“‹), Elimina (πŸ—‘οΈ).
    • πŸ“„ Copia: genera testo plain dell'attivitΓ  (HTML stripped) e lo copia negli appunti.
    • πŸ’Ύ Esporta TXT: salva il dettaglio dell'attivitΓ  come file .txt nella cartella Export/.
    • πŸ“‹ Duplica: copia tutti i campi tranne la data (incluso NumeroTicket e ChangesetCoinvolti). La Descrizione dettagliata lavoro svolto (Note) NON viene copiata: al suo posto viene inserito un header puntatore **** Proseguo l'attivitΓ  [Id]-[Descrizione]-[NumeroTicket] del [Data] **** riferito all'attivitΓ  di origine (evita di gonfiare il record su lavorazioni multi-giorno). Il lavoro dei giorni precedenti resta consultabile col pulsante "Mostra la descrizione del lavoro svolto nei giorni precedenti" (vedi Β§5).
    • πŸ—‘οΈ Elimina: mostra una modale Blazor custom centrata per la conferma.
  • Pulsanti export sotto la griglia (visibili se ci sono attivitΓ ):
    • πŸ“Š Esporta XLSX: esporta la griglia visualizzata in Excel (ElencoAttivitΓ Al[timestamp].xlsx).
    • πŸ“„ Esporta dettagli TXT: esporta tutte le attivitΓ  visibili in un TXT (DettaglioTutteLeAttivitΓ _[dal]_[al]_[timestamp].txt).
    • πŸ“ Apri Export: apre la cartella Export/ in Esplora Risorse.
  • Dopo il salvataggio, l'attivitΓ  appena salvata rimane selezionata nella griglia.

3. Form di Inserimento/Modifica

La testata (header blu) contiene bottoni rapidi Nuova / Salva (Ctrl+S) / Annulla replicati in piccolo. I bottoni principali sono anche nel footer del form.

Shortcut Ctrl+S: salva l'attivitΓ  corrente in qualsiasi momento (registrato via registraCtrlS JS + [JSInvokable] SalvaViaShortcut()).

Il campo Cliente ha un bottone ✏️ che apre la modale ClientiEditorModal per gestire la lista clienti (con log delle modifiche in Clienti_Log).

4. Ambienti di Rilascio (Form, v4.1)

Visibili nel form solo quando TipoAttivita == Lavoro e il cliente selezionato Γ¨ diverso da "Sviluppo". Comprendono 3 coppie (Tipo ambiente / Versione) disposte orizzontalmente:

  • Tipo ambiente: <input list> con <datalist> alimentato da TipiAmbientiRilascio (es. Test, QualitΓ , Pre-produzione, Produzione).
  • Versione: <input list> con <datalist> alimentato da VersioniRilascio (es. 3.2.50, 4.1.10).
  • I valori nuovi digitati vengono aggiunti automaticamente ai rispettivi lookup al salvataggio (EnsureTipoExistsAsync, EnsureVersioneExistsAsync).
  • Dati persistiti in AttivitaAmbientiRilascio (con Posizione 1-3). Caricati in SelezionaAttivita() tramite AmbientiRilascioService.GetAmbientiRilascioAsync().
  • Il DTO WorkActivityDto.AmbientiRilascio contiene sempre 3 coppie AmbienteRilascioDto (Posizione, TipoAmbiente, Versione). Il campo AmbientiRilascioNomi (string?) Γ¨ calcolato da ActivityService.GetActivitiesAsync() per la colonna della griglia.

5. Editor "Descrizione dettagliata lavoro svolto" (Note)

Campo contenteditable (non textarea) con toolbar di editing:

  • β‡₯ β†’ / ⇀ ←: indentazione destra/sinistra delle righe selezionate.
  • G (Grassetto): applica/rimuove bold con document.execCommand('bold').
  • A giallo / A arancione / A verde: evidenziatura del testo selezionato (hiliteColor).
  • S barrato / S sottolineato: formattazione barrato e sottolineato.
  • A rosso: colora il testo in rosso.
  • βœ•: rimuove tutta la formattazione (bold, colore, highlight, sottolineato, ecc.).
  • β—€ / πŸ“‹ / β–Ά: Undo / Storico versioni / Redo (overlay in basso a destra dell'editor, sopra le scrollbar).
  • ⊟: rimuove le righe vuote dal contenuto dell'editor.
  • TODO: sostituisce ogni occorrenza di "TODO" (parola isolata) con --, preservando tutta la formattazione HTML.
  • Altezza: min 200px, max 500px con scroll verticale.
  • Font: Segoe UI, white-space: pre-wrap.
  • Bordo rosso se il campo contiene TODO.
  • Salva/carica HTML (innerHTML) per persistere il grassetto nel database.
  • La sincronizzazione avviene via noteEditorHelper (JS): setContent, getHtml, getText, indent, rimuoviRigheVuote.

Lavoro dei giorni precedenti (catena "Proseguo l'attivitΓ ", v5.1): quando la Note inizia con l'header **** Proseguo l'attivitΓ  [Id]... **** (generato dalla Duplica), sopra la label compare il pulsante "Mostra la descrizione del lavoro svolto nei giorni precedenti". Al click viene ricostruita on-demand la catena delle attivitΓ  collegate β€” seguendo i puntatori Id nelle Note, di attivitΓ  in attivitΓ  β€” e il risultato Γ¨ mostrato in un riquadro di sola lettura (stessa altezza dell'editor) che renderizza l'HTML: quindi screenshot, grassetti ed evidenziazioni delle Note precedenti sono visibili (Γ¨ un div con MarkupString, non una textarea che mostrerebbe solo testo). Le sezioni sono in ordine cronologico (dalla data piΓΉ vecchia alla piΓΉ recente), ciascuna intestata ====== [Id]-[Descrizione]-[NumeroTicket] del [Data] ======, con la riga "Proseguo" rimossa perchΓ© ridondante. Il pulsante diventa "Nascondi...". Nessun dato viene duplicato nel DB: la cronologia Γ¨ ricostruita seguendo i rimandi. Il caricamento Γ¨ on-demand con cache per-selezione: la catena viene letta dal database solo al primo click, poi i successivi "Mostra/Nascondi" sono istantanei finchΓ© non si cambia attivitΓ .

6. Congelati (Ambienti di Rilascio)

La sezione "Modifica riportata sui congelati" mostra una tabella checkbox con:

  • Sviluppo (riga virtuale): versione di sviluppo corrente.
  • Ambienti dal DB: Codice, Versione, Data congelamento.

Quando si spunta un congelato: viene aggiunto automaticamente un blocco nell'editor Changeset (se non giΓ  presente):

NomeCongelato (Versione):
Changeset XXX: [Testo del check-in]

7. Editor "Elenco Changeset e lista files coinvolti"

div con contenteditable="true" con toolbar di editing:

  • β‡₯ β†’ / ⇀ ←: indentazione (cursore rimane sulla stessa riga dopo l'operazione).
  • G (Grassetto): applica/rimuove bold.
  • A giallo / A arancione / A verde: evidenziatura del testo selezionato (hiliteColor).
  • S barrato / S sottolineato: formattazione barrato e sottolineato.
  • A rosso: colora il testo in rosso.
  • βœ•: rimuove tutta la formattazione (bold, colore, highlight, sottolineato, ecc.).
  • β—€ / πŸ“‹ / β–Ά: Undo / Storico versioni / Redo (overlay in basso a destra dell'editor, sopra le scrollbar).
  • ⊟: rimuove le righe vuote dal contenuto dell'editor.
  • TODO: sostituisce ogni occorrenza di "TODO" (parola isolata) con --, preservando tutta la formattazione HTML.
  • Altezza: min 200px, max 350px, scroll verticale e orizzontale.
  • Font monospace (Consolas), white-space: pre.
  • Salva/carica HTML (innerHTML) per persistere il grassetto.
  • Sincronizzazione via changesetEditorHelper (JS): setContent, getHtml, getText, indent, rimuoviRigheVuote.
  • AggiungiBloccoCongelato(): usa HtmlToPlainText() per i confronti stringa, poi appende il nuovo blocco come HTML (<strong>heading</strong><br>Changeset XXX: testo) preservando la formattazione esistente.

8. TODO List (Modale)

Modale separata per gestire TODO personali. Ogni TODO: Titolo, Descrizione, Data inserimento, Urgenza (1-5), Completato. Badge con contatore nel pulsante in alto. Pulsante πŸ“₯ Export MD nel footer per esportare la lista in formato Markdown (tabella GFM) nella cartella Export/.

Nota di completamento (v5.4): accanto alla spunta "Completato" c'Γ¨ una textarea "Nota di completamento", disabilitata finchΓ© il TODO Γ¨ aperto e obbligatoria per salvarlo come completato. Per questo la checkbox nella griglia non chiude piΓΉ il TODO al volo: selezionandola il TODO viene aperto nel form con la spunta giΓ  messa, in attesa della nota (riaprire un TODO resta invece immediato). Togliendo la spunta la nota viene azzerata. La nota compare come colonna in griglia e nell'Export MD.

9. Appunti / Knowledge Base (Modale)

Modale per note rapide con sistema di tag (Titolo, Descrizione, Tag multi-valore). Badge con contatore nel pulsante in alto.

10. Editor Clienti (Modale)

Modale ClientiEditorModal aperta dal pulsante ✏️ accanto al campo Cliente:

  • CRUD completo: aggiungi, modifica, disattiva cliente.
  • Lingua struttura patch (v5.2): select Italiano/Inglese (Clienti.Lingua, default IT) che determina la lingua dei nomi cartella nella funzione "Autoprepara struttura patch" e i readme proposti. Colonna "Lingua" mostrata anche nella griglia.
  • Ogni modifica Γ¨ tracciata in Clienti_Log: NomeUtente, AzioneSvolta (Nuovo/Modifica/Elimina), VecchioValore, NuovoValore, Timestamp.

11. Editor Congelati (Modale)

Modale CongelatiEditorModal aperta dal pulsante "✏️ Modifica lista" sotto la tabella congelati. Log in Ambienti_Log.

  • Campi: Codice, Versione, Data Congelamento, Data Dismissione, Attivo, Note (v5.4).
  • πŸ“‹ Esporta MD: esporta la griglia in formato Markdown (tabella GFM) nella cartella Export/ (Congelati_[timestamp].md).
  • Data Dismissione: obbligatoria quando la checkbox "Attivo" viene deselezionata; il form mostra un errore di validazione se mancante. Mostrata come colonna nella griglia.
  • Note (v5.4): testo libero per descrivere il Codice (a cosa serve, particolaritΓ , riferimenti). Presente nel form, come colonna in griglia (troncata, testo completo nel tooltip) e nell'export MD.
  • Il log Ambienti_Log include DataDismissione nei campi VecchioValore e NuovoValore per tracciabilitΓ  completa; le Note vi entrano troncate a 100 caratteri, per non gonfiare la tabella di log a ogni modifica.

12. Ricerca Avanzata (Modale)

Ricerca full-text su tutte le attivitΓ  (senza filtri data) con griglia risultati, navigazione frecce, evidenziazione rossa, selezione attivitΓ  nel form.

Ricerca lato server (v5.2): la finestra non precarica piΓΉ l'intero storico (che con Note ricche di screenshot base64 poteva richiedere 30–60 secondi ad aprirsi). La ricerca Γ¨ eseguita su SQL Server (ActivityService.RicercaAvanzataAsync, EF.Functions.Like sui soli campi selezionati) e restituisce risultati leggeri (senza Note/Changeset); il contenuto completo della voce selezionata viene caricato on-demand (con cache). L'apertura Γ¨ cosΓ¬ istantanea anche su archivi grandi.

Spazi come jolly (v5.3): ogni sequenza di spazi, tabulazioni o a capo nel testo cercato diventa un jolly % nel LIKE. Serve perché con la ricerca su SQL un testo salvato con doppio spazio (o mandato a capo) non veniva più trovato scrivendolo con spazio singolo — LIKE non sa esprimere "uno o più spazi". Effetto collaterale accettato: tra due parole può comparire altro testo. La collation Latin1_General_CI_AS rende la ricerca accent-sensitive: sigre non trova sigrè.

Colonna "NΒ° Ticket" e stato di attesa (v5.3/v5.4): la griglia dei risultati mostra il numero del ticket dopo la data. Durante l'esecuzione della query compare "Ricerca in corso, attendere…" con rotellina, e il pulsante Cerca si disabilita: prima, per tutta la durata della ricerca, veniva mostrato "Nessun risultato trovato".

13. Segnalazioni (Modale)

Pulsante "πŸ› Segnala" nella barra superiore (sempre visibile, indipendente dalla modalitΓ  admin), apre la modale SegnalazioniModal:

  • Form invio: combo utente (auto-seleziona utente corrente) + textarea + bottone "Invia Segnalazione".
  • Griglia segnalazioni: Utente, Testo (troncato), Data, Stato con badge colorati. Pulsante "πŸ’¬ Rispondi" sempre visibile (anche per chi ha originato la segnalazione).
  • Dettaglio segnalazione selezionata: testo formattato readonly con Utente, Data, Testo, Stato, storico risposte.
  • Form risposta: textarea + combo stato + bottone "Invia Risposta".
  • Stati disponibili: In attesa di risposta, Risposta, Richiesta accettata, Richiesta rifiutata, Modifica proposta accettata, Risolto.

14. ModalitΓ  Admin

Attivabile tramite checkbox (configurabile in appsettings.json con MostraModalitaAdmin):

  • Mostra le attivitΓ  di tutti gli utenti (eccetto quelli con PrivacyMode: true).
  • Impedisce la modifica di attivitΓ  altrui.

15. Avviso Modifiche Non Salvate

Quando si tenta di chiudere la finestra con il form in modifica, viene mostrato un dialogo di conferma. Implementato via UnsavedChangesService (singleton) + AppWindow.Closing (WinUI nativo) in App.xaml.cs.

16. Export AttivitΓ 

  • File salvati nella sottocartella Export/ nella directory dell'eseguibile (creata automaticamente).
  • Naming convention: ElencoAttivitΓ Al[yyyyMMdd_HHmmss].xlsx, DettaglioTutteLeAttivitΓ _[dal]_[al]_[timestamp].txt, DettaglioAttivitΓ _[data]_[descrizione]_[timestamp].txt.
  • I campi HTML (Note, ChangesetCoinvolti) vengono convertiti in testo plain via HtmlToPlainText() prima dell'export.
  • L'ultimo file esportato viene mostrato nella barra di stato.
  • XLSX generato con ClosedXML (pacchetto NuGet 0.102.2).

17. Barra di Stato

Barra fissa in fondo alla finestra:

  • πŸ’Ύ Ultimo salvataggio: orario HH:mm:ss dell'ultimo salvataggio riuscito.
  • πŸ“€ Export: nome dell'ultimo file esportato (con tooltip percorso completo).
  • πŸ” ModalitΓ  Admin attiva: badge in admin mode.
  • πŸ”’ Privacy attiva: badge se PrivacyMode: true.
  • Versione app: numero da appsettings.json.

18. Privacy Mode

ProprietΓ  booleana PrivacyMode in appsettings.json. Se true: le attivitΓ  dell'utente non sono visibili ad altri utenti in modalitΓ  Admin. Nessuna UI per modificarla.

19. Colonna "Cart. Doc." nella Griglia (v4.5)

La colonna Cart. Doc. Γ¨ stata aggiunta alla griglia delle attivitΓ  (tra "Patch" e "Azioni"). Mostra l'icona πŸ“ verde quando il campo CartellaDocumentazione Γ¨ compilato; il tooltip riporta il percorso completo. Se il campo Γ¨ vuoto la cella Γ¨ vuota.

20. Storico Versioni Editor β€” Undo/Redo (v4.5)

Ogni volta che un'attivitΓ  viene salvata, il contenuto HTML dei campi Note e ChangesetCoinvolti viene registrato nella tabella EditorHistory (storico infinito, associato all'utente e all'attivitΓ ).

Tre pulsanti sono posizionati come overlay nell'angolo in basso a destra di ciascuna textarea editor (non nella toolbar):

Pulsante Azione
← Torna alla versione precedente salvata (Undo)
πŸ“‹ Apre la modale EditorHistoryModal con la lista completa delle versioni
β†’ Avanza alla versione successiva salvata (Redo)

I pulsanti sono disabilitati finchΓ© l'attivitΓ  non Γ¨ stata salvata almeno una volta. Il campo viene registrato nello storico solo se non Γ¨ vuoto (verifica tramite HtmlToPlainText) e solo se il contenuto Γ¨ diverso dall'ultimo salvataggio (evita duplicati consecutivi in EditorHistory).

Logica navigazione:

  • Indice -1 = contenuto corrente non ancora salvato (stato iniziale).
  • Al primo Undo: il contenuto corrente viene memorizzato in memoria, viene caricata la lista storico da DB e viene mostrata la versione 0 (piΓΉ recente).
  • Undo successivi: incrementa l'indice (va a versioni piΓΉ vecchie, fino all'ultima).
  • Redo da indice 0: ripristina il contenuto memorizzato (torna all'indice -1).
  • Redo da indice >0: decrementa l'indice (torna a versioni piΓΉ recenti).
  • Il cache storico viene azzerato ad ogni salvataggio e quando si seleziona un'altra attivitΓ .

Modale EditorHistoryModal.razor:

  • Griglia con data salvataggio (dd/MM/yyyy HH:mm:ss) e anteprima testo (primi 100 caratteri, HTML strippato).
  • Riga selezionata evidenziata in giallo (table-warning).
  • Pulsanti ↑ ↓ per navigare le righe con contatore "N di Totale".
  • Div di anteprima dettagliato con HTML renderizzato (readonly).
  • Bottoni "Annulla" (chiude senza modifiche) e "βœ” Seleziona" (chiude e applica la versione all'editor).

Pulizia automatica (v5.1): all'avvio dell'applicazione, in background, le voci di EditorHistory piΓΉ vecchie di NumeroMesiMantenimentoHistory mesi (impostazione in appsettings.json, default 3) vengono eliminate automaticamente (EditorHistoryService.EliminaVecchieAsync), evitando la crescita illimitata della tabella. Se qualche voce viene eliminata, in testa al form appare un avviso informativo (che scompare dopo qualche secondo): "L'History delle modifiche piΓΉ vecchie di X mesi Γ¨ stata eliminata. (Vedere il file appsetting per modificare questo automatismo)". Un valore 0 o negativo disattiva la pulizia.

21. Export PDF delle AttivitΓ  (v5.2)

Oltre a TXT/XLSX, le attivitΓ  possono essere esportate in PDF mantenendo le immagini incollate nei campi HTML (Descrizione dettagliata, Elenco Changeset):

  • 🧾 per riga: esporta la singola attivitΓ .
  • 🧾 Esporta dettagli PDF (sotto la griglia): esporta tutte le attivitΓ  filtrate, una per pagina.

Implementato in PdfExportService: costruisce un documento HTML (Note/Changeset inseriti come HTML grezzo, immagini incluse) e lo stampa in PDF via WebView2 (CoreWebView2CompositionController.PrintToPdfAsync), riusando l'environment WebView2 di BlazorWebView catturato in MainPage. I file finiscono in Export/.

22. Autoprepara Struttura Patch (v5.2)

Accanto al campo "πŸ“¦ URL Patch/Pacchetto nei rilasci" due pulsanti:

  • πŸ›  Autoprepara struttura patch: crea in TmpPatchDir (default C:\TmpPatch\) la cartella del rilascio {Cliente}\{AAAA-MM-GG}_{NOMEPROGRAMMA}_{VERSIONE}_{AMBIENTI}_{TICKET}\ (versione X.Y.Z β†’ X.Y_SPZ; nomi senza spazi/accenti; ticket con virgole β†’ _) e l'intera struttura di sottocartelle (Prerequisiti, Database Server, Application Server β†’ Componenti Server / Setup Web, Client). È idempotente: se la cartella esiste giΓ  non viene toccata.
  • πŸ“: apre in Esplora Risorse tutte le cartelle patch create, una finestra per versione.

I nomi delle sottocartelle sono in italiano o inglese in base alla lingua del cliente (Clienti.Lingua): es. 00_PREREQUISITI/00_PREREQUISITES, 01_COMPONENTI_SERVER/01_SERVER_COMPONENTS.

Una cartella per versione (v5.3): gli ambienti di rilascio che condividono la stessa versione vengono accorpati in un'unica cartella (..._Test_Produzione_...); se le versioni sono diverse viene creata una cartella separata per ciascuna, es. 2026-09-04_PROGRAMMA_3.2_SP50_Debug_1010C e 2026-09-04_PROGRAMMA_3.2_SP60_Produzione_1010C. Il raggruppamento avviene sulla versione già normalizzata, così due scritture equivalenti non generano cartelle doppie.

23. Inserisci files Readme (v5.2)

Pulsante TXT (tooltip "Inserisci files Readme") accanto ai pulsanti patch. Apre una popup (ReadmeTemplatesModal) con i modelli di istruzioni d'installazione filtrati per la lingua del cliente. I modelli sono definiti in ReadmeTmplates.json (root del progetto): array di voci {Titolo, Lingua, Descrizione, DirectoryDiSalvataggio}. Selezionando le voci e premendo Inserisci, viene creato un unico Readme.txt per ciascuna cartella di destinazione (sezioni separate da una linea === con il titolo di ciascun readme); i file giΓ  presenti non vengono sovrascritti. I segnaposto {NOMEPROGRAMMA}, {NOMECOMPAGNIA}, {CLIENTE}, {VERSIONE} vengono sostituiti (anche nel titolo). Richiede di aver prima premuto "Autoprepara struttura patch".

Readme in tutte le strutture (v5.3): quando gli ambienti hanno versioni diverse e sono state create piΓΉ cartelle patch, i readme selezionati vengono scritti in ognuna di esse. Il segnaposto {VERSIONE} Γ¨ risolto per cartella, quindi ogni Readme.txt riporta la versione della propria struttura.

24. Auto-compilazione Numero Ticket + Autocompila Check-in (v5.2)

  • Numero ticket dai link: uscendo dal campo "URL Ticket", i numeri dei ticket presenti nei link (ServiceDesk HDAPortal e TFS) vengono estratti e aggiunti in coda al campo "Numero del ticket" (solo i mancanti, senza duplicati).
  • ✨ Autocompila (Testo del check-in): pulsante accanto a β¬‡οΈπŸ“‹ che compila il check-in come Numero ticket - Descrizione.

25. Scadenza dei Ticket (v5.3)

Campo facoltativo "Scadenza ticket" accanto a "Numero del ticket". Quando Γ¨ valorizzato, la riga in griglia viene evidenziata in base ai giorni mancanti:

Situazione Colore riga
Scadenza giΓ  passata Rosso marcato, testo in grassetto
Entro GiorniPreavvisoScadenzaRosso giorni (default 2) Rosso
Entro GiorniPreavvisoScadenzaArancione giorni (default 5) Arancione chiaro

L'evidenziazione ha la precedenza sul colore delle righe TODO (altrimenti sarebbe invisibile proprio nel caso d'uso principale); la riga selezionata resta comunque distinguibile. Nella colonna "N° Ticket" compare anche la data di scadenza con l'icona ⏳.

Filtro "⏳ Visualizza ticket in scadenza": spunta accanto a "Visualizza solo TODO". Attivandola viene spuntata automaticamente anche "solo TODO" e la griglia mostra le sole attività con TODO e con scadenza valorizzata, ordinate dalla scadenza più vicina in cima. Togliendo "solo TODO" si disattiva anche questo filtro.

26. Autocompila Ambienti di Rilascio (v5.3)

Pulsante "✨ Ultimo ticket" a destra delle tre coppie ambiente/versione. Compila ambienti e versioni copiandoli dall'ultimo ticket lavorato per lo stesso cliente che abbia almeno una coppia valorizzata. La ricerca spazia su tutti gli utenti (come in modalità admin) indipendentemente dalla spunta admin, escludendo però le attività degli utenti in PrivacyMode. L'attività aperta è esclusa, così il pulsante non ricopia sé stessa. Un messaggio riporta quante coppie sono state compilate e da quale ticket.

27. Bozza di Emergenza su File (v5.3)

Pensata per chi accede al database tramite VPN: se la connessione cade mentre si compila un'attivitΓ , il salvataggio fallisce e il lavoro β€” comprese le Note con gli screenshot β€” andrebbe perso.

  • Quando il salvataggio a database fallisce, l'intero contenuto del form viene serializzato in Bozze\bozza_attivita.json e il messaggio d'errore riporta il percorso.
  • Ripremendo πŸ’Ύ Salva a connessione ripristinata, l'attivitΓ  viene scritta nel database e il file eliminato automaticamente.
  • Se l'applicazione viene chiusa nel frattempo, al riavvio compare in testa al form un banner "È presente una bozza non salvata del …" con i pulsanti ♻️ Ripristina e πŸ—‘οΈ Elimina. Il rilevamento avviene prima della connessione al database, quindi il banner compare anche a DB ancora irraggiungibile.
  • Ripristinare non cancella il file: solo un salvataggio riuscito lo fa, cosΓ¬ un secondo tentativo fallito non lascia scoperti.

28. Icone e Navigazione TODO negli Editor (v5.3)

Nelle toolbar di "Descrizione dettagliata lavoro svolto" e "Elenco Changeset" (sia sopra sia sotto ogni editor):

  • 😊 Pannello icone: apre un pannello con le icone raggruppate per categoria (Stati ed esiti, Frecce e flusso, Sviluppo e sistemi, Tempo, Persone, Analisi, Faccine). Il click inserisce l'icona direttamente nel punto del cursore β€” niente passaggio dagli appunti β€” e il pannello resta aperto per inserirne altre. Una riga "Usate di recente" (max 12) Γ¨ condivisa fra tutti i pannelli.
  • β—€ β–Ά Navigazione TODO: salta da un TODO all'altro dentro il testo senza scorrerlo a mano, selezionando l'occorrenza e scrollando l'editor. Un badge mostra n/tot (o "nessun TODO"). Il contenuto non viene modificato: la ricerca avviene sui nodi di testo, senza inserire marcatori nell'HTML che finirebbe nel database. Il conteggio Γ¨ ricalcolato a ogni salto, quindi resta corretto anche mentre si scrive.

29. Export PDF: ambienti e attivitΓ  collegate (v5.3)

  • Il PDF di un'attivitΓ  include ora la voce "πŸš€ Ambienti di rilascio" con le coppie Ambiente β€” Versione.
  • L'etichetta "Versione" Γ¨ stata rinominata in "Versione attualmente in Sviluppo" (anche negli export TXT).
  • Se EsportaAttivitaCollegateInPdf Γ¨ true, l'export di una singola attivitΓ  include anche tutte le attivitΓ  collegate dalla catena "**** Proseguo l'attivitΓ  … ****", in ordine cronologico crescente e una per pagina: il documento si legge come la progressione del lavoro. Vale solo per l'export della singola attivitΓ , dato che in "Esporta dettagli PDF" le attivitΓ  ci sono giΓ  tutte.

30. Indicatore di avanzamento negli Export (v5.3)

Tutti gli export (XLSX, dettagli TXT/PDF, singola attivitΓ  TXT/PDF) mostrano "Generazione … in corso…" con rotellina accanto a πŸ“ Apri Export, e una rotellina al posto dell'icona sul pulsante della riga da cui Γ¨ partito l'export. Gli altri pulsanti export si disabilitano: un export alla volta. Il lavoro pesante (generazione XLSX, composizione dell'HTML con gli screenshot in base64) gira su un thread di background, cosΓ¬ l'interfaccia resta reattiva invece di apparire bloccata.


Modello Dati

Tabelle

Utenti              β€” Utenti identificati da WindowsUsername
Clienti             β€” Clienti (Es: Sviluppo, Cattolica, Aviva)
Clienti_Log         β€” Log modifiche alla lista clienti
Ambienti            β€” Congelati (Codice, Versione/Descrizione, DataCongelamento, DataDismissione, Note)
Ambienti_Log        β€” Log modifiche agli ambienti/congelati
Attivita            β€” AttivitΓ  lavorative principali
AttivitaAmbienti    β€” Relazione N:N tra Attivita e Ambienti
TodoItems           β€” Elementi TODO List per utente
Appunti             β€” Appunti/Knowledge Base per utente
AppuntiTags         β€” Tag associati agli appunti
Segnalazioni        β€” Segnalazioni bug / richieste di modifica
Segnalazioni_Risposte β€” Risposte alle segnalazioni
TipiAmbientiRilascio  β€” Lookup tipi di ambiente (Test, QualitΓ , Produzione, ecc.) (v4.1)
VersioniRilascio      β€” Lookup versioni di rilascio (v4.1)
AttivitaAmbientiRilascio β€” Relazione N:N tra Attivita e ambienti di rilascio (v4.1)
TipiAttivita          β€” Tipi attivitΓ  configurabili (Lavoro/Permesso/Ferie + custom) (v4.2)
TipiAttivita_Log      β€” Log modifiche ai tipi attivitΓ  (v4.2)
EventiCalendario      β€” Eventi del calendario con scadenza e stato risolto (v4.2)
EditorHistory         β€” Storico versioni HTML dei campi Note e ChangesetCoinvolti (v4.5)

Tipo AttivitΓ 

Valori del campo TipoAttivita (NVARCHAR(20)):

  • Lavoro β€” attivitΓ  lavorativa (default)
  • Permesso β€” assenza per permesso
  • Ferie β€” assenza per ferie

Architettura Software

UI (Blazor Razor)
    ↓ @inject / EventCallback
Service Layer (ActivityService, ClienteService, SegnalazioneService, ...)
    ↓ IDbContextFactory<AppDbContext>
EF Core DbContext
    ↓ SQL Server Provider
SQL Server Database
  • Single Page Application: Components/Pages/Home.razor (~2700 righe).
  • Modali come componenti Blazor separati in Components/.
  • JS Interop: script in wwwroot/index.html per gli editor contenteditable e Ctrl+S.
  • Nessuna EF Migration: aggiornamenti schema tramite script SQL manuali in Database/.
  • HTML storage: i campi Note e ChangesetCoinvolti salvano HTML nel DB per persistere il grassetto. HtmlToPlainText() viene chiamato per export, clipboard e confronti stringa.

Servizi registrati in MauiProgram.cs

Servizio Lifetime Scopo
ActivityService Scoped CRUD attivitΓ 
UserService Scoped Gestione utente Windows
AmbienteService Scoped CRUD congelati + log
ClienteService Scoped CRUD clienti + log
TodoService Scoped CRUD TODO List
AppuntiService Scoped CRUD Appunti/Knowledge Base
SegnalazioneService Scoped CRUD segnalazioni + risposte
AppConfigService Singleton Lettura appsettings.json
UnsavedChangesService Singleton Stato modifiche non salvate (chiusura app)
AmbientiRilascioService Scoped CRUD tipi ambienti e versioni di rilascio (v4.1)
TipiAttivitaService Scoped CRUD tipi attivitΓ  dinamici (v4.2)
CalendarioService Scoped CRUD eventi calendario + eventi imminenti (v4.2)
EditorHistoryService Scoped Salvataggio e recupero storico versioni editor Note/Changeset (v4.5)
PdfExportService Singleton Export PDF delle attivitΓ  via WebView2 composition controller (v5.2)
ReadmeTemplateService Singleton Carica i template readme da ReadmeTmplates.json (v5.2)
BozzaAttivitaService Singleton Salvataggio di emergenza dell'attivitΓ  su file quando il DB non risponde (v5.3)
HtmlTextHelper statico Conversione HTML β†’ testo semplice, condivisa fra UI e servizi (v5.5)

Script JS in wwwroot/index.html

Funzione/Helper Scopo
registraCtrlS(dotNetRef) Registra Ctrl+S globale con callback a [JSInvokable] SalvaViaShortcut()
eseguiBold(el) Applica/rimuove grassetto con document.execCommand('bold')
changesetEditorHelper.setContent(el, val) Imposta contenuto (rileva HTML vs plain text)
changesetEditorHelper.getHtml(el) Restituisce innerHTML per salvataggio DB
changesetEditorHelper.getText(el) Restituisce innerText per operazioni stringa C#
changesetEditorHelper.indent(el, right) Indenta le righe selezionate (β‡₯/⇀), cursore stabile
noteEditorHelper.setContent(el, val) Imposta contenuto Note (rileva HTML vs plain text)
noteEditorHelper.getHtml(el) Restituisce innerHTML per salvataggio DB
noteEditorHelper.getText(el) Restituisce innerText
noteEditorHelper.indent(el, right) Indenta le righe selezionate nelle Note
sostituisciTodoNeiNodi(el) Traversa i text node dell'editor e sostituisce TODO (parola isolata) con --, preservando HTML
copyToClipboard(text) Copia testo negli appunti con fallback execCommand per MAUI

Script di Migrazione Database

Gli script SQL si trovano in Database/ e vanno eseguiti in ordine:

File Contenuto
CreateDatabase.sql Schema iniziale completo
MigrateToV3.sql Prima migrazione
MigrateToV3.2.sql Aggiunta congelati
MigrateToV3.3.sql Aggiunta log congelati
MigrateToV3.4.sql Aggiunta TodoItems
MigrateToV3.5.sql Aggiunta URL Patch Rilasci
MigrateToV3.6.sql Aggiunta CartDoc, TODO Titolo, Data congelamento
MigrateToV3.7.sql Aggiunta Appunti/AppuntiTags
MigrateToV3.8.sql Aggiunta TipoAttivita (Lavoro/Permesso/Ferie)
MigrateToV3.9.sql Aggiunta PrivacyMode in Utenti; VecchioValore+NuovoValore in Ambienti_Log
MigrateToV4.0.sql Aggiunta Clienti_Log, Segnalazioni, Segnalazioni_Risposte
MigrateToV4.1.sql Aggiunta TipiAmbientiRilascio, VersioniRilascio, AttivitaAmbientiRilascio + log
MigrateToV4.2.sql Aggiunta TipiAttivita, TipiAttivita_Log, EventiCalendario
MigrateToV4.3.sql Aggiunta NumeroTicket in Attivita
MigrateToV4.4.sql UrlPatchRilasci β†’ NVARCHAR(MAX); aggiunta DataDismissione in Ambienti
MigrateToV4.5.sql Aggiunta tabella EditorHistory per storico versioni Note/Changeset
MigrateToV4.7.sql Aggiunta tabelle ClientiAmbienti, ClientiAmbienti_Log
MigrateToV4.8.sql Aggiunta DatiAmbiente, DirectoryInstallazione, InformazioniPool in ClientiAmbienti
MigrateToV4.9.sql Aggiunta Descrizione4, Descrizione5 in Ambienti; TipoVersione, NumeroVersione in ClientiAmbienti
MigrateToV5.0.sql Indici performance: IX_Attivita_UtenteId_Data, IX_EditorHistory_Attivita_Campo, IX_AttivitaAmbientiRilascio_AttivitaId
(v5.1) Nessuna modifica allo schema
MigrateToV5.2.sql Aggiunta colonna Lingua (IT/EN, default IT) in Clienti
MigrateToV5.3.sql Aggiunta DataScadenzaTicket in Attivita (+ indice filtrato IX_Attivita_DataScadenzaTicket) e NotaCompletamento in TodoItems
MigrateToV5.4.sql Aggiunta colonna Note (NVARCHAR(MAX)) in Ambienti
MigrateToV5.5.sql Aggiunta NoteTesto e ChangesetTesto in Attivita (+ indice filtrato IX_Attivita_NoteTesto_DaConvertire)
(script una tantum) PuliziaLogClientiAmbienti.sql β€” non Γ¨ una migration: accorcia le righe giΓ  presenti in ClientiAmbienti_Log, dove veniva salvato "Come collegarsi" per intero

Note di Sviluppo

  • @bind in Blazor crea dipendenza bidirezionale. I campi contenteditable (Note, Changeset) non usano @bind: il valore viene sincronizzato via JS interop su @onblur e prima del salvataggio.
  • noteEditorNeedsUpdate e changesetEditorNeedsUpdate: flag che forzano l'aggiornamento degli editor in OnAfterRenderAsync, solo quando non sono in focus.
  • HtmlToPlainText(): helper statico che stripa i tag HTML e decodifica entitΓ  di base. Usato in: ContieneTodo(), CampoHaTodo(), AggiungiBloccoCongelato(), GeneraTestoAttivita(), GeneraTestoAttivitaPlain().
  • AggiungiBloccoCongelato(): prima di confrontare le righe del testo Changeset, chiama HtmlToPlainText() perchΓ© il campo ora puΓ² contenere HTML.
  • L'eliminazione usa ConfermaEliminaAttivita() β†’ modale custom centrata β†’ ConfermaElimina().
  • La versione di sviluppo successiva Γ¨ calcolata automaticamente dal primo ambiente (+1 al patch).
  • Il filtro "Solo TODO" Γ¨ applicato sia alla lista principale che alla lista per la ricerca avanzata.
  • UnsavedChangesService: singleton condiviso tra il layer MAUI (App.xaml.cs) e il layer Blazor (Home.razor). App.xaml.cs intercetta AppWindow.Closing (cancellabile), controlla il servizio e mostra DisplayAlert.
  • DotNetObjectReference<Home> per il callback Ctrl+S: creato in OnAfterRenderAsync al first render, disposto in Dispose() (il componente implementa IDisposable).
  • Export XLSX usa ClosedXML (ClosedXML 0.102.2 nel .csproj). I file vengono salvati in Export/ nella directory dell'eseguibile.

Changelog

v5.5

  • ⚑ Gestione Clienti si apre subito: la griglia non carica piΓΉ "Come collegarsi" e "Dati ambiente" (i campi con gli screenshot in base64) per tutte le righe. Erano decine di MB trasferiti a ogni apertura β€” su database raggiunto via VPN, i 30-60 secondi di attesa prima di vedere l'elenco. I campi ricchi vengono letti on-demand solo per la riga selezionata, e per il solo cliente esportato in caso di PDF.
  • ⚑ Ricerca molto piΓΉ veloce: nuove colonne Attivita.NoteTesto e ChangesetTesto con Note e Changeset ripuliti da tag e immagini. La ricerca e il calcolo del flag TODO girano su queste invece che sull'HTML: misurato, circa il 99% del volume da scandire erano screenshot. Un indice tradizionale non era applicabile β€” NVARCHAR(MAX) non puΓ² essere colonna chiave di un indice.
  • πŸ”„ Conversione dei dati esistenti automatica: al primo avvio parte in background, a lotti e riprendibile fra un avvio e l'altro, con un banner di avanzamento. Durante la conversione la ricerca ricade sulle colonne originali, quindi nessun risultato viene perso.
  • ⏱️ Timeout SQL configurabile con la nuova chiave TimeoutQuerySecondi (default 30, impostata a 120): prima era fisso al valore predefinito di SqlClient e la ricerca sugli archivi grandi ci sbatteva contro.
  • πŸ› Ricerca Avanzata, errori visibili: un timeout della query veniva intercettato fuori dalla finestra, che mostrava "Nessun risultato trovato" mentre l'errore vero compariva dietro, leggibile solo chiudendo. Ora l'errore Γ¨ mostrato dentro la finestra, con i suggerimenti per rimediare.
  • 🧹 Log ambienti cliente piΓΉ leggero: "Come collegarsi" non viene piΓΉ scritto per intero nel log a ogni salvataggio, duplicando tutti gli screenshot. Per le righe giΓ  presenti c'Γ¨ lo script una tantum PuliziaLogClientiAmbienti.sql.
  • 🧼 Build senza warning: DisplayAlert obsoleto sostituito con DisplayAlertAsync, rotellina di caricamento collegata in Appunti, rimosso un campo inutilizzato nel Calendario.
  • πŸ†• Nuovo helper condiviso Services/HtmlTextHelper.cs: HtmlToPlainText esisteva in due copie leggermente diverse, ora Γ¨ una sola.
  • πŸ†• Nuova migrazione DB: MigrateToV5.5.sql.

v5.4

  • ⏰ Scadenza dei ticket: nuovo campo facoltativo "Scadenza ticket" nel form. Le righe della griglia si colorano all'avvicinarsi della scadenza (arancione entro 5 giorni, rosso entro 2, rosso marcato se giΓ  passata; soglie configurabili in appsettings.json). Nuova spunta "⏳ Visualizza ticket in scadenza" che mostra i soli TODO con scadenza valorizzata, ordinati dalla scadenza piΓΉ vicina.
  • πŸ’Ύ Bozza di emergenza su file: se il database non risponde (tipicamente per una caduta della VPN) il contenuto del form β€” Note e Changeset con gli screenshot inclusi β€” viene salvato in Bozze\bozza_attivita.json e cancellato al primo salvataggio riuscito. Se l'applicazione viene chiusa nel frattempo, al riavvio un banner permette di ripristinare la bozza.
  • 😊 Pannello icone (emoji) nelle toolbar di "Descrizione dettagliata" ed "Elenco Changeset": icone per categoria, inserimento diretto al cursore, sezione "usate di recente".
  • β—€β–Ά Navigazione TODO negli editor: frecce per saltare da un TODO all'altro con contatore n/tot, senza scorrere il testo e senza alterare il contenuto.
  • πŸ” Fix ricerca: gli spazi del termine cercato diventano jolly, cosΓ¬ un testo salvato con spazi doppi o mandato a capo torna a essere trovato (regressione introdotta in v5.2 spostando la ricerca su SQL). In Ricerca Avanzata: nuova colonna "NΒ° Ticket" e messaggio "Ricerca in corso" durante la query, al posto di "Nessun risultato trovato".
  • ⏳ Rotellina su tutti gli export e lavoro pesante spostato in background: l'interfaccia non appare piΓΉ bloccata durante le generazioni lunghe.
  • 🧾 PDF piΓΉ completi: gli export includono gli ambienti di rilascio; l'export di una singola attivitΓ  puΓ² includere anche le attivitΓ  collegate dalla catena "Proseguo l'attivitΓ " (configurabile). L'etichetta "Versione" Γ¨ diventata "Versione attualmente in Sviluppo".
  • πŸ“¦ Struttura patch per versione: ambienti con versioni diverse generano cartelle separate (accorpate solo a paritΓ  di versione) e i file readme vengono creati in tutte le strutture. Il pulsante πŸ“ apre tutte le cartelle create.
  • ✨ Autocompila ambienti di rilascio dall'ultimo ticket lavorato per lo stesso cliente, cercando fra le attivitΓ  di tutti gli utenti.
  • 🏒 Gestione Clienti: export PDF per cliente (con "Come collegarsi" e relativi screenshot), export elenco XLSX, pulsante "Apri Export"; messaggi spostati nel footer sempre visibile; griglia ordinata per nome cliente.
  • 🧊 Congelati: nuovo campo "Note" libero per descrivere il Codice, presente in griglia, form ed export MD.
  • βœ… TODO List: "Nota di completamento" obbligatoria per chiudere un TODO (la spunta in griglia porta al form invece di completare al volo), inclusa nell'Export MD.
  • πŸ”„ "Reset Filtri" torna al mese corrente invece che all'anno intero; nuovo pulsante βœ– per svuotare il campo Ricerca.
  • πŸ†• Nuovo servizio BozzaAttivitaService, nuovo componente EmojiPicker.razor.
  • πŸ†• Nuove migrazioni DB: MigrateToV5.3.sql (scadenza ticket, nota di completamento TODO) e MigrateToV5.4.sql (note sui congelati).

v5.2

  • πŸ“„ Export PDF delle attivitΓ  (con immagini): nuovo pulsante 🧾 in ogni riga della griglia e "🧾 Esporta dettagli PDF" sotto la griglia. A differenza dell'export TXT, le immagini incollate nei campi HTML (Descrizione dettagliata, Elenco Changeset) vengono renderizzate nel PDF. Implementato con PdfExportService che stampa un documento HTML via WebView2 (CoreWebView2CompositionController.PrintToPdfAsync), riusando l'environment WebView2 di BlazorWebView catturato in MainPage.
  • ⚑ Ricerca avanzata lato server: la modale di Ricerca Avanzata non precarica piΓΉ tutto lo storico (che con Note ricche di screenshot base64 poteva richiedere 30–60s); ora filtra su SQL Server (ActivityService.RicercaAvanzataAsync) e restituisce risultati leggeri, caricando il contenuto completo solo della voce selezionata. Apertura istantanea anche su archivi grandi.
  • 🎫 Auto-compilazione "Numero del ticket": incollando i link nel campo URL Ticket, i numeri dei ticket (ServiceDesk HDAPortal e TFS) vengono estratti automaticamente e accodati al campo Numero (solo i mancanti, senza duplicati).
  • ✨ Autocompila Testo del check-in: nuovo pulsante ✨ accanto a β¬‡οΈπŸ“‹ che compone Numero ticket - Descrizione.
  • πŸ”Ž Descrizione in griglia troncata a 100 caratteri (era 50) con tooltip del testo completo.
  • πŸ› οΈ Autoprepara struttura patch: nuovi pulsanti πŸ› /πŸ“ accanto al campo "URL Patch". Crea in TmpPatch la cartella del rilascio (AAAA-MM-GG_PROGRAMMA_VERSIONE_AMBIENTI_TICKET) con l'intera struttura di sottocartelle. Idempotente. Config in appsettings.json: TmpPatchDir, NomeProgramma, NomeCompagnia.
  • 🌐 Lingua struttura patch per cliente: nuova colonna Clienti.Lingua (IT/EN, default IT) impostabile nell'editor clienti; la struttura patch usa i nomi cartella in italiano o inglese di conseguenza.
  • πŸ“„ Inserisci files Readme: nuovo pulsante TXT che apre una popup con 13 modelli di istruzioni d'installazione (IT/EN, in ReadmeTmplates.json), filtrati per la lingua del cliente. Genera un unico Readme.txt per cartella con i segnaposto sostituiti ({NOMEPROGRAMMA}, {NOMECOMPAGNIA}, {CLIENTE}, {VERSIONE}, anche nel titolo).
  • πŸ†• Nuovi servizi: PdfExportService, ReadmeTemplateService. Nuova modale: ReadmeTemplatesModal. Nuovo file: ReadmeTmplates.json.
  • πŸ†• Nuova migrazione DB: MigrateToV5.2.sql (colonna Clienti.Lingua).

v5.1

  • 🧹 Pulizia automatica storico modifiche: nuovo parametro NumeroMesiMantenimentoHistory (default 3) in appsettings.json. All'avvio, in background, le voci di EditorHistory piΓΉ vecchie del numero di mesi indicato vengono eliminate (EditorHistoryService.EliminaVecchieAsync via ExecuteDeleteAsync); se ne vengono eliminate, un avviso compare in testa al form e scompare dopo qualche secondo. Un valore 0/negativo disattiva la pulizia.
  • πŸͺΆ Duplica attivitΓ  piΓΉ leggera: la Descrizione dettagliata lavoro svolto (Note) non viene piΓΉ copiata; al suo posto un header puntatore **** Proseguo l'attivitΓ  [Id]-[Descrizione]-[NumeroTicket] del [Data] ****. Evita di gonfiare il record (e rallentare il caricamento) su lavorazioni che durano piΓΉ giorni. ChangesetCoinvolti continua a essere copiato.
  • πŸ”Ž "Mostra/Nascondi la descrizione del lavoro svolto nei giorni precedenti": nuovo pulsante sopra l'editor Note (visibile solo quando la Note contiene l'header "Proseguo"). Ricostruisce on-demand la catena delle attivitΓ  collegate seguendo i puntatori nelle Note e mostra il lavoro precedente in un riquadro di sola lettura che renderizza l'HTML (screenshot e formattazione delle Note precedenti inclusi β€” div/MarkupString, non textarea), in ordine cronologico, con intestazioni ====== Id-Descrizione-Ticket del Data ======. Caricamento on-demand con cache per-selezione (catena letta dal DB solo al primo click). Protezione anti-loop. Nessun dato duplicato nel DB.
  • πŸ“ Nessuna modifica allo schema DB.

v5.0

  • ⚑ Performance griglia/ricerca: la griglia non carica piΓΉ i campi pesanti Note e ChangesetCoinvolti (HTML con screenshot base64). I contenuti vengono caricati on-demand alla selezione della riga, alla copia (πŸ“„), alla duplicazione (πŸ“‹) e all'export TXT. Il ricaricamento dopo il salvataggio e la ricerca rapida risultano molto piΓΉ veloci anche con molte immagini.
  • ⚑ Ricerca rapida lato SQL: la ricerca testuale della griglia Γ¨ spostata su SQL (LIKE), cosΓ¬ cerca anche dentro Note/Changeset senza trasferirli. La normalizzazione degli spazi multipli resta attiva nella Ricerca avanzata (modale), che continua a caricare i contenuti completi.
  • ⚑ Filtro data SARGable: il filtro Anno/Mese/Giorno usa un intervallo di date (>= inizio AND < fine) invece di YEAR()/MONTH(), cosΓ¬ l'indice su Data puΓ² essere sfruttato.
  • ⚑ Nuovi indici DB (MigrateToV5.0.sql): IX_Attivita_UtenteId_Data (filtro utente + ordinamento data), IX_EditorHistory_Attivita_Campo (storico editor, letto a ogni salvataggio), IX_AttivitaAmbientiRilascio_AttivitaId (colonna "Ambienti").
  • πŸ†• WorkActivityDto.HasTodo: flag calcolato lato DB (LIKE word-boundary) per evidenziare e filtrare i TODO nella griglia senza caricare le Note.
  • πŸ• Tasto data/ora: il pulsante πŸ• negli editor (Note, Changeset e Gestione Clienti) ora inserisce data + ora nel formato dd-MM-yyyy HH:mm:ss (prima solo HH:mm:ss).
  • 🎨 Editor "Descrizione dettagliata lavoro svolto": altezza aumentata (min 200px, max 500px).
  • 🎨 Gestione Clienti: gli editor "Come collegarsi" e "Dati recuperati dall'ambiente del cliente" hanno ora la toolbar di formattazione sopra e sotto (come nel form principale) e caselle piΓΉ alte (min 320px, max 600px).

v4.9

  • πŸ†• Export XLSX β€” colonna "Ticket": aggiunta la colonna Ticket (campo NumeroTicket) prima di Descrizione nell'export della griglia attivitΓ  (πŸ“Š Esporta XLSX)
  • πŸ†• TODO List β€” campo "Cerca": nuova casella di ricerca live in cima alla modale (sopra la griglia "Elenco TODO"), filtra case-insensitive su Titolo + Descrizione; bottone βœ• per pulire la ricerca
  • πŸ†• Congelati β€” Versione 4 e Versione 5: nuove colonne Descrizione4 e Descrizione5 nella tabella Ambienti (NVARCHAR(100) NULL), visibili nella griglia "Modifica riportata sui congelati" del form principale e gestibili dall'editor Congelati (✏️ Modifica lista)
  • πŸ†• Gestione Clienti β€” Tipo + Numero della versione: nuovi campi TipoVersione (Versione / Versione4 / Versione5) e NumeroVersione sulla tabella ClientiAmbienti. Il campo "Numero della versione" Γ¨ un input con <datalist> popolato dai congelati attivi filtrati per il tipo selezionato (suggerimenti distinti, non vincolante)
  • πŸ†• Gestione Clienti β€” nuove colonne in griglia: Versione (prefisso V / V4 / V5 + numero), Data ultimo aggiornamento (da DataModifica) e Utente (da ClientiAmbienti_Log, ultimo utente che ha modificato la riga)
  • πŸ†• Home β€” filtro Settimana (ISO 8601): nuova combo "Settimana" tra Mese e Giorno con opzioni W1..W53 (limitate per l'anno selezionato tramite ISOWeek.GetWeeksInYear). Bottone affiancato che imposta automaticamente la settimana ISO corrente (con l'anno ISO corretto). Filtro applicato in memoria dopo la query base, poichΓ© EF non traduce ISOWeek
  • πŸ†• Form attivitΓ  β€” pulsante "πŸ” Ricerca": bottone accanto al campo Descrizione che azzera i filtri, copia la descrizione nel campo Ricerca ed esegue la ricerca
  • 🎨 Feedback salvataggio esteso a 4 s: il lampeggio verde sulla status bar ora dura 4 secondi (era 1,5 s), con plateau di colore pieno tra il 10% e l'85% dell'animazione
  • πŸ†• Gestione Clienti β€” indicatore + mini status bar: nuova "lucina" verde accanto al titolo 🏒 Gestione Clienti (lampeggia 4 s ad ogni salvataggio) + mini status bar sopra il footer che mostra l'orario dell'ultimo salvataggio con la stessa animazione della Home
  • πŸ†• Nuova migrazione DB: MigrateToV4.9.sql
  • πŸ”§ ActivityService.GetActivitiesAsync: nuovo parametro opzionale int? settimana
  • 🎨 CSS: @keyframes pulse-save rivisto a 4 s, nuove classi .save-indicator / .save-indicator-on (@keyframes pulse-dot) e .modal-status-bar

v4.8

  • πŸ”’ Gestione Clienti β€” avviso dati sensibili: il banner informativo ora avvisa esplicitamente di non inserire dati sensibili nei campi e di utilizzare esclusivamente 1Password per quelli riservati
  • ⌨️ Gestione Clienti β€” Ctrl+S: il tasto Ctrl+S salva il record corrente anche quando la finestra Gestione Clienti Γ¨ aperta (registra un callback [JSInvokable] sul modale, con prioritΓ  rispetto al Ctrl+S del form principale; si deregistra alla chiusura)
  • πŸ†• Gestione Clienti β€” editor "Dati recuperati dall'ambiente": nuovo editor HTML rich (sotto "Come collegarsi") con toolbar completa (grassetto, evidenziazioni giallo/arancione/verde, barrato, sottolineato, rosso, timestamp, separatori, rimuovi righe vuote). Campo DatiAmbiente (NVARCHAR(MAX)) nella tabella ClientiAmbienti
  • πŸ†• Gestione Clienti β€” Directory di installazione: nuovo campo testo (col-md-8) per la directory di installazione di xxx (es. c:\inetpub\wwwroot\xxx). Campo DirectoryInstallazione (NVARCHAR(MAX)) nella tabella ClientiAmbienti
  • πŸ†• Gestione Clienti β€” Informazioni sul pool: nuovo campo testo affiancato (col-md-4) per le informazioni sul pool applicativo (32bit / 64bit, identity, ecc.). Campo InformazioniPool (NVARCHAR(1000)) nella tabella ClientiAmbienti
  • 🎨 Form principale β€” prima riga in grassetto: i campi della prima riga "Nuova AttivitΓ " (Tipo AttivitΓ , Data, Cliente, Ore Lavorate, Versione di sviluppo) mostrano label e valori in grassetto per una maggiore leggibilitΓ 
  • πŸ†• Nuova migrazione DB: MigrateToV4.8.sql
  • πŸ†• Nuovo JS helper: datiAmbienteEditorHelper in wwwroot/index.html (alias di collegamentoEditorHelper)
  • πŸ”§ registraCtrlSModal / deregistraCtrlSModal in wwwroot/index.html: supporto Ctrl+S a livello di modale con prioritΓ  sul form principale

v4.7

  • πŸ†• Gestione Clienti (finestra dedicata): nuovo pulsante toolbar "🏒 Gestione Clienti" accanto ad "Appunti". Gestisce configurazioni per-ambiente (cliente + ambiente) con campi Application Server, Database Server, Persone di riferimento, Directory di installazione xxx, Informazioni pool e "Come collegarsi" (editor HTML rich con toolbar completa). Dati condivisi tra tutti gli utenti (banner informativo con avviso dati sensibili β†’ usare 1Password), con log di ogni modifica (Nuovo / Modifica / Elimina) tracciato per NomeUtente
  • πŸ†• Clona ambiente cliente: il pulsante πŸ— in griglia popola il form con una copia del record (Id=0); l'utente modifica l'ambiente e preme Salva per creare un nuovo record β€” non salva automaticamente per evitare duplicati
  • πŸ”§ Fix Reset filtri β€” anno corrente: ResetFiltri() ora mantiene l'anno corrente (invece di azzerarlo), cosΓ¬ il focus sull'anno di lavoro non viene perso
  • πŸ†• Feedback visivo salvataggio: dopo ogni salvataggio la status bar lampeggia in verde per ~1.5 secondi (utile quando si usa Ctrl+S su pagine lunghe e il cambio di orario Γ¨ difficile da notare). Animazione CSS @keyframes pulse-save / classe .status-bar-pulse
  • πŸ†• Nuovo servizio: ClienteAmbienteService
  • πŸ†• Nuove tabelle DB: ClientiAmbienti, ClientiAmbienti_Log
  • πŸ†• Nuova modale: GestioneClientiModal.razor
  • πŸ†• Nuovo JS helper: collegamentoEditorHelper in wwwroot/index.html (stessa interfaccia di noteEditorHelper)
  • πŸ†• Nuova migrazione DB: MigrateToV4.7.sql

v4.6

  • πŸ”§ Fix Duplica attivitΓ  β€” Ambienti di rilascio: DuplicaAttivita() ora carica gli ambienti di rilascio dal DB prima di copiarli, risolvendo il problema per cui gli ambienti risultavano vuoti nell'attivitΓ  duplicata
  • πŸ†• TODO List β€” Export Markdown: nuovo pulsante "πŸ“₯ Export MD" nel footer della modale TODO; esporta la lista in formato Markdown (tabella GFM con colonne Stato, Urgenza, Data Ins., Titolo, Descrizione, Data Compl.) nella cartella Export/
  • πŸ”§ Fix griglia β€” riga totale ore: corretto il colspan nel footer della tabella attivitΓ ; lo sfondo table-secondary ora copre tutte le colonne fino ad Azioni
  • πŸ”§ Fix FormattaVersioneCongelato β€” versioni negative: la versione secondaria 4.1.X viene mostrata solo quando il patch Γ¨ >= 50; per versioni inferiori (es. 3.2.41) viene mostrata solo la versione base senza suffisso

v4.5

  • πŸ†• Griglia β€” colonna "Cart. Doc.": icona πŸ“ verde nella griglia quando il campo CartellaDocumentazione Γ¨ compilato; tooltip con il percorso completo
  • πŸ†• Storico versioni editor Note e Changeset: ogni salvataggio registra una voce nella nuova tabella EditorHistory (solo se il campo non Γ¨ vuoto e il contenuto Γ¨ cambiato rispetto all'ultimo salvataggio); pulsanti ← πŸ“‹ β†’ come overlay nell'angolo in basso a destra di ciascuna textarea per navigare lo storico (Undo/Redo basato su versioni salvate) e aprire la modale di navigazione EditorHistoryModal
  • πŸ†• EditorHistoryModal: nuova modale con griglia versioni (data + anteprima), navigazione ↑↓, anteprima HTML dettagliata e azione "βœ” Seleziona" per ripristinare la versione scelta nell'editor
  • πŸ†• Nuovo servizio: EditorHistoryService
  • πŸ†• Nuova migrazione DB: MigrateToV4.5.sql

v4.4 (patch UI)

  • πŸ†• Griglia β€” colonna "Ambienti": mostra i nomi degli ambienti di rilascio compilati (es. "Test, Produzione"), senza versione; calcolato tramite query batch in ActivityService.GetActivitiesAsync() e salvato in WorkActivityDto.AmbientiRilascioNomi
  • πŸ†• Griglia β€” colonna "Patch": indicatore βœ” verde se UrlPatchRilasci Γ¨ compilato
  • πŸ†• Combo Giorno β€” emoji weekend/oggi: prefisso 🟠 per sabato e domenica, 🟒 per il giorno corrente (ha la precedenza sul weekend)

v4.4

  • πŸ”§ Fix editor Changeset β€” formattazione preservata: SincronizzaTestoEditorAsync() ora salva HTML (non plain text); AggiungiBloccoCongelato() appende il nuovo blocco come HTML preservando bold/highlight/colori esistenti; ToggleAmbiente aggiorna correttamente il DOM editor dopo l'aggiunta del blocco
  • πŸ”§ Fix Tab/indent in editor: la funzione indent JS ora filtra i text node e BR quando il cursore Γ¨ su contenuto BR-based, evitando il bug "undefined" nell'innerHTML
  • πŸ”§ Fix rimuoviRigheVuote: rimossa la modalitΓ  selezione (causa corruzione HTML con extractContents); la funzione opera sempre sull'intero editor
  • πŸ”§ Fix URL Patch errore DB: rimosso [MaxLength(500)] da UrlPatchRilasci β†’ ora NVARCHAR(MAX) per supportare URL multipli lunghi
  • πŸ”§ Fix Duplica attivitΓ : NumeroTicket ora viene copiato correttamente in DuplicaAttivita()
  • πŸ†• Combo Giorno con nomi: quando Anno e Mese sono selezionati, la combo mostra il numero del giorno + il nome abbreviato italiano (es. "1 - lun"); i giorni non validi per il mese sono nascosti
  • πŸ†• Bottone TODOβ†’"--": aggiunto in tutte e 4 le toolbar (sopra/sotto Note, sopra/sotto Changeset); sostituisce le occorrenze di TODO (parola isolata) con -- preservando la formattazione HTML; funzione JS sostituisciTodoNeiNodi(el) che opera sui text node
  • πŸ†• Data Dismissione nei Congelati: nuovo campo DataDismissione (obbligatorio quando Attivo = false); colonna nella griglia, campo nel form con validazione; incluso nel log Ambienti_Log (VecchioValore/NuovoValore)
  • πŸ†• Nuova migrazione DB: MigrateToV4.4.sql

v4.3

  • πŸ†• NumeroTicket: nuovo campo NVARCHAR(200) affiancato al campo URL Ticket nel form; tooltip "Inserire il numero del ticket, usare la virgola se sono piΓΉ di uno"; incluso nella ricerca full-text; copiato correttamente da "Duplica attivitΓ "
  • πŸ”§ VisibilitΓ  campi per tipo attivitΓ : URL Ticket, Numero Ticket, Cartella Documentazione e Vedere ora visibili anche per i tipi personalizzati (custom); nascosti solo per Permesso e Ferie
  • πŸ†• GetTipoBadge(): badge grigio πŸ“Œ {tipo} per i tipi personalizzati (usa HtmlEncode per sicurezza)

v4.2

  • πŸ†• Tipi AttivitΓ  dinamici: nuova tabella TipiAttivita + TipiAttivita_Log; dropdown caricato da DB via TipiAttivitaService; pulsante ✏️ accanto alla combo apre TipiAttivitaEditorModal; EnsureTipiBaseAsync() garantisce Lavoro/Permesso/Ferie all'avvio; i tipi base non possono essere rinominati nΓ© eliminati
  • πŸ†• Calendario eventi: nuova tabella EventiCalendario; servizio CalendarioService; icona πŸ“… accanto al campo Data apre CalendarioModal (griglia mensile con navigazione e form evento); barra colorata in cima alla pagina mostra l'evento piΓΉ urgente non risolto (verde/arancione/rosso/grigio per distanza in giorni)
  • πŸ†• Popup errore DB: MostraMessaggioConPopup() in Home.razor mostra modale con OK per errori critici (connessione all'avvio, salvataggio)
  • πŸ†• Nuove tabelle DB: TipiAttivita, TipiAttivita_Log, EventiCalendario
  • πŸ†• Nuovi servizi: TipiAttivitaService, CalendarioService

v4.1

  • πŸ†• Ambienti di rilascio: nel form (visibili quando cliente β‰  "Sviluppo") compaiono 3 coppie (Tipo ambiente / Versione) con <input list> e autocompletamento; i valori nuovi vengono aggiunti automaticamente ai lookup al salvataggio
  • πŸ†• Colonna Ambienti in griglia: mostra i nomi degli ambienti di rilascio compilati, separati da virgola (es. "Test, Produzione"), senza versione
  • πŸ†• Colonna Patch in griglia: indicatore βœ” verde se UrlPatchRilasci Γ¨ compilato
  • πŸ†• Nuove tabelle DB: TipiAmbientiRilascio, VersioniRilascio, AttivitaAmbientiRilascio + log per entrambe
  • πŸ†• Nuovo servizio: AmbientiRilascioService

v4.0

  • πŸ†• Editor Note con indent + bold: "Descrizione dettagliata lavoro svolto" convertita da textarea a contenteditable div con toolbar (β‡₯β†’, ⇀←, G grassetto)
  • πŸ†• Bold nel Changeset editor: aggiunto bottone G alla toolbar esistente
  • πŸ†• HTML storage: Note e ChangesetCoinvolti salvano HTML nel DB per persistere il grassetto. HtmlToPlainText() per export/clipboard/confronti
  • πŸ†• Ctrl+S: shortcut globale per salvare (tooltip aggiornato su entrambi i bottoni Salva)
  • πŸ†• Bottone "πŸ“… Oggi": accanto al filtro Giorno, imposta la data odierna e ricarica
  • πŸ†• Editor Clienti: pulsante ✏️ accanto al campo Cliente apre modale CRUD con log in Clienti_Log
  • πŸ†• "Elenco Changeset e lista files coinvolti": label rinominata da "Elenco Changeset coinvolti"
  • πŸ†• Export XLSX: esporta la griglia visualizzata in Excel (ClosedXML)
  • πŸ†• Export TXT dettagli: esporta tutte le attivitΓ  visibili in un file TXT
  • πŸ†• Export TXT per riga: bottone πŸ’Ύ in ogni riga della griglia per esportare la singola attivitΓ 
  • πŸ†• Apri Export: pulsante per aprire la cartella Export in Esplora Risorse
  • πŸ†• Avviso chiusura: dialogo se ci sono modifiche non salvate (WinUI AppWindow.Closing + UnsavedChangesService)
  • πŸ†• Segnalazioni: pulsante "πŸ› Segnala" sempre visibile, modale con invio segnalazioni, griglia, risposte e cambio stato
  • πŸ†• Barra di stato: aggiunto nome dell'ultimo file esportato
  • πŸ†• Nuove tabelle DB: Clienti_Log, Segnalazioni, Segnalazioni_Risposte
  • πŸ†• Nuovi servizi: ClienteService, SegnalazioneService, UnsavedChangesService

v3.9

  • πŸ†• PrivacyMode: campo PrivacyMode (BIT) aggiunto a tabella Utenti; sincronizzato al login dall'appsettings.json
  • πŸ†• Ambienti_Log: aggiunto VecchioValore e NuovoValore (NVARCHAR MAX) per tracciare i valori prima/dopo la modifica
  • πŸ†• Admin mode: filtra utenti con PrivacyMode = true (tranne l'utente corrente)

v3.8

  • πŸ†• TipoAttivita: campo Lavoro/Permesso/Ferie
  • πŸ†• Per Permesso e Ferie vengono nascosti i campi non pertinenti (Cliente, Versione, Ticket, Congelati, Changeset)
  • πŸ†• Etichette e placeholder adattate al tipo selezionato

v3.7

  • πŸ†• Appunti (Knowledge Base personale): modale con CRUD, tag, ricerca con evidenziazione, navigazione frecce, modalitΓ  admin
  • πŸ†• Nuove tabelle: Appunti, AppuntiTags
  • πŸ”§ "Dettagli ricerca" β†’ "Ricerca avanzata" (sempre attivo)

v3.6

  • πŸ†• TODO List: campo Titolo, data inserimento editabile
  • πŸ†• Congelati: colonna "Data Cong." nella tabella + Editor Congelati (modale CRUD)
  • πŸ†• TracciabilitΓ  congelati: tabella Ambienti_Log
  • πŸ†• MostraModalitaAdmin: configurabile in appsettings.json

v3.5

  • πŸ†• Nuovo campo "URL Patch/Pacchetto nei rilasci" (multiriga, ricercabile)
  • πŸ†• Filtro "Visualizza solo TODO" con badge "Filtro attivo"

v3.4

  • πŸ†• TODO List: modale con urgenza 1-5, CRUD, completamento, isolamento per utente

v3.3

  • πŸ†• Cliente "Sviluppo" auto-selezionato per nuove attivitΓ 
  • πŸ†• Nuovo campo "Testo del check-in" con pulsante β¬‡οΈπŸ“‹ per copiarlo in Descrizione
  • πŸ†• Auto-compilazione blocchi Changeset alla selezione congelati
  • πŸ†• Ricerca avanzata: auto-scroll + navigazione occorrenze (Precedente/Prossimo)

v3.2

  • πŸ†• Connection string in appsettings.json
  • πŸ†• Font form 13px
  • πŸ†• Regex TODO word boundary + evidenziazione righe + badge
  • πŸ†• Pulsante Duplica (πŸ“‹) nella griglia
  • πŸ†• Auto-completamento versione di sviluppo (+1 patch)

v3.0 β€” v3.1

  • Campo "URL Ticket" multilinea, cartella documentazione con folder picker
  • Congelati con tabella Nome/Versione; "Elenco Changeset coinvolti" (contenteditable)
  • Modale ricerca avanzata con evidenziazione e selezione diretta

v2.0

  • Changeset coinvolti, ModalitΓ  Admin, filtri inizializzati a oggi, ricerca estesa

v1.0

  • Prima versione con funzionalitΓ  base

Struttura del Progetto

WorkActivityTracker/
β”œβ”€β”€ appsettings.json                      # Connection string + config (NON in repo)
β”œβ”€β”€ ReadmeTmplates.json                    # Template readme patch IT/EN (v5.2)
β”œβ”€β”€ Components/
β”‚   β”œβ”€β”€ Pages/
β”‚   β”‚   └── Home.razor                    # Pagina principale (~2700 righe)
β”‚   β”œβ”€β”€ SearchModal.razor                 # Ricerca avanzata
β”‚   β”œβ”€β”€ TodoListModal.razor               # TODO List
β”‚   β”œβ”€β”€ AppuntiModal.razor                # Appunti / Knowledge Base
β”‚   β”œβ”€β”€ CongelatiEditorModal.razor        # Editor congelati
β”‚   β”œβ”€β”€ ClientiEditorModal.razor          # Editor clienti (v4.0)
β”‚   β”œβ”€β”€ SegnalazioniModal.razor           # Segnalazioni bug/richieste (v4.0)
β”‚   β”œβ”€β”€ TipiAttivitaEditorModal.razor     # Editor tipi attivitΓ  dinamici (v4.2)
β”‚   β”œβ”€β”€ CalendarioModal.razor             # Calendario eventi (v4.2)
β”‚   β”œβ”€β”€ ReadmeTemplatesModal.razor        # Popup "Inserisci files Readme" (v5.2)
β”‚   β”œβ”€β”€ GestioneClientiModal.razor        # Ambienti per cliente (v4.7)
β”‚   β”œβ”€β”€ EmojiPicker.razor                 # Pannello icone per gli editor (v5.3)
β”‚   β”œβ”€β”€ _Imports.razor
β”‚   └── Routes.razor
β”œβ”€β”€ Data/
β”‚   └── AppDbContext.cs                   # EF Core DbContext
β”œβ”€β”€ Database/
β”‚   β”œβ”€β”€ CreateDatabase.sql
β”‚   β”œβ”€β”€ MigrateToV3.sql ... MigrateToV3.9.sql
β”‚   β”œβ”€β”€ MigrateToV4.0.sql                # (v4.0) Clienti_Log, Segnalazioni, Segnalazioni_Risposte
β”‚   β”œβ”€β”€ MigrateToV4.1.sql                # (v4.1) AmbientiRilascio
β”‚   β”œβ”€β”€ MigrateToV4.2.sql                # (v4.2) TipiAttivita, EventiCalendario
β”‚   β”œβ”€β”€ MigrateToV4.3.sql                # (v4.3) NumeroTicket
β”‚   └── MigrateToV4.4.sql                # (v4.4) UrlPatchRilasci β†’ MAX, DataDismissione in Ambienti
β”œβ”€β”€ Models/
β”‚   └── WorkActivity.cs                   # Tutti i modelli EF Core + DTO + static classes
β”œβ”€β”€ Services/
β”‚   β”œβ”€β”€ ActivityService.cs
β”‚   β”œβ”€β”€ AmbienteService.cs
β”‚   β”œβ”€β”€ AppConfigService.cs
β”‚   β”œβ”€β”€ AppuntiService.cs
β”‚   β”œβ”€β”€ ClienteService.cs                 # (v4.0) CRUD clienti + Clienti_Log
β”‚   β”œβ”€β”€ SegnalazioneService.cs            # (v4.0) CRUD segnalazioni + risposte
β”‚   β”œβ”€β”€ TodoService.cs
β”‚   β”œβ”€β”€ UnsavedChangesService.cs          # (v4.0) Singleton flag modifiche non salvate
β”‚   β”œβ”€β”€ UserService.cs
β”‚   β”œβ”€β”€ AmbientiRilascioService.cs        # (v4.1) CRUD tipi ambienti + versioni rilascio
β”‚   β”œβ”€β”€ TipiAttivitaService.cs            # (v4.2) CRUD tipi attivitΓ  dinamici
β”‚   β”œβ”€β”€ CalendarioService.cs              # (v4.2) CRUD eventi calendario
β”‚   β”œβ”€β”€ PdfExportService.cs               # (v5.2) Export PDF via WebView2
β”‚   β”œβ”€β”€ ReadmeTemplateService.cs          # (v5.2) Carica ReadmeTmplates.json
β”‚   β”œβ”€β”€ BozzaAttivitaService.cs           # (v5.3) Bozza di emergenza su file (VPN caduta)
β”‚   └── HtmlTextHelper.cs                 # (v5.5) HTML β†’ testo semplice (unica implementazione)
β”œβ”€β”€ wwwroot/
β”‚   β”œβ”€β”€ css/app.css                       # Stili custom (font 13px, TODO, editor toolbar)
β”‚   └── index.html                        # Entry point HTML + script JS custom
β”œβ”€β”€ App.xaml.cs                           # Finestra MAUI + avviso chiusura (v4.0)
β”œβ”€β”€ MauiProgram.cs                        # Composizione DI
└── WorkActivityTracker.csproj            # ClosedXML 0.102.2 (v4.0)

Contributing

Le segnalazioni di bug e le richieste di nuove funzionalitΓ  sono benvenute tramite le Issues di GitHub.

Per contribuire al codice:

  1. Fai un fork del repository
  2. Crea un branch per la tua modifica (git checkout -b feature/nome-funzionalita)
  3. Esegui il commit delle modifiche
  4. Apri una Pull Request descrivendo cosa hai cambiato e perchΓ©

Prima di proporre modifiche strutturali al database, consulta la sezione Script di Migrazione Database: le migration sono manuali (script SQL in Database/), non usa EF Migrations.


Licenza

Distribuito sotto licenza MIT. Consulta il file LICENSE per i dettagli.

About

Daily work activity logger for .NET dev teams. Tracks clients, versions, SVN/Git changesets and deployment environments. Built with .NET MAUI Blazor Hybrid + SQL Server.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages