Human Resources Business Intelligence System - Dedica / Ringraziamenti (opzionale) - in SUPSI Tesi
←
→
Trascrizione del contenuto della pagina
Se il tuo browser non visualizza correttamente la pagina, ti preghiamo di leggere il contenuto della pagina quaggiù
Human Resources Business Intelligence System Studente/i Relatore - Eric Palmas - Vanni Galli Correlatore - Committente - Gianluca Ugolini Corso di laurea Modulo - Ingegneria informatica - Progetto di semestre Anno - 2019/2020 Dedica / Ringraziamenti (opzionale) Data -
2/40 Indice generale Abstract ............................................................................................................................................. 4 1 Stato dell’arte .................................................................................................................................. 6 1.1 La situazione attuale ................................................................................................................ 6 2 Progetto assegnato ......................................................................................................................... 7 2.1 La soluzione richiesta ............................................................................................................... 7 3 Tecnologie utilizzate ........................................................................................................................ 8 3.1 Node.js .................................................................................................................................... 8 3.2 Back-end ................................................................................................................................. 9 3.3 Front-end ................................................................................................................................. 9 3.4 Database ............................................................................................................................... 10 3.5 Altri strumenti: ........................................................................................................................ 10 3.5.1 Trello .............................................................................................................................. 10 3.5.2 Postman ......................................................................................................................... 11 3.5.3 GitHub ............................................................................................................................ 12 4 Pattern utilizzati............................................................................................................................. 13 4.1 Redux .................................................................................................................................... 13 4.2 Come funziona ....................................................................................................................... 13 4.3 Actions................................................................................................................................... 14 4.4 Reducers ............................................................................................................................... 15 4.5 Store ...................................................................................................................................... 16 4.6 Redux e React ....................................................................................................................... 17 5 Progettazione del database ........................................................................................................... 19 5.1 Descrizione ............................................................................................................................ 19 6 Implementazione ........................................................................................................................... 21 6.1 Creazione del progetto ........................................................................................................... 21 6.2 Server .................................................................................................................................... 23 6.3 Client ..................................................................................................................................... 25 7 Piani di Lavoro .............................................................................................................................. 36 7.1 Descrizione delle fasi ............................................................................................................. 36 7.2 Metodologia AGILE ................................................................................................................ 36 8 Conclusioni ................................................................................................................................... 38 8.1 Risultati .................................................................................................................................. 38 8.2 Sensazioni personali .............................................................................................................. 38 8.3 Sviluppi futuri ......................................................................................................................... 38 Bibliografia ....................................................................................................................................... 39 Allegati ............................................................................................................................................. 40 HuRBIS
3/40 Indice delle figure Figura 1 Estratto di un foglio excel (sena i dati aziendali) .................................................................... 6 Figura 2 nodejs .................................................................................................................................. 8 Figura 3 Trello.................................................................................................................................. 11 Figura 4 Postman............................................................................................................................. 11 Figura 5 GitHub................................................................................................................................ 12 Figura 6 Redux pattern..................................................................................................................... 13 Figura 7 Database ........................................................................................................................... 19 Figura 8 MySQL Workbench ............................................................................................................ 20 Figura 9 Home page ........................................................................................................................ 25 Figura 10 Qualifiche ......................................................................................................................... 26 Figura 11 Inserimento qualifica......................................................................................................... 26 Figura 12 Rimozione qualifiche ........................................................................................................ 27 Figura 13 Corsi ................................................................................................................................ 27 Figura 14 Aggiunta corsi .................................................................................................................. 28 Figura 15 Rimozione corsi ................................................................................................................ 28 Figura 16 Scheda collaboratore........................................................................................................ 29 Figura 17 Modifica corso .................................................................................................................. 30 Figura 18 Assegnamento corsi ......................................................................................................... 31 Figura 19 Rimozione corsi assegnati ................................................................................................ 31 Figura 20 Assegnamento qualifiche.................................................................................................. 32 Figura 21 Rimozione qualifiche assegnate ....................................................................................... 32 Figura 22 file pdf espotato ................................................................................................................ 33 Figura 23 Pagina di riepilogo ............................................................................................................ 34 Figura 24 Rimozione colonne ........................................................................................................... 34 Figura 25 file esportato in excel ........................................................................................................ 35 Figura 26 Calendario delle scadenze ............................................................................................... 35 Figura 27 Metodologia AGILE .......................................................................................................... 37 HuRBIS
4/40 Abstract Italiano Il progetto HuRBIS è stato fatto per la Tre Valli Soccorso, e il suo obiettivo è quello di fornire all'azienda uno strumento per la gestione dei corsi di formazione. Questo strumento deve dare la possibilità di assegnare corsi e qualifiche ai dipendenti, ma anche di effettuare eventuali modifiche alle date di certificazione e scadenza dei corsi. Come appena accennato ogni corso ha una data di certificazione (la data in cui il collaboratore ottiene la licenza) e una data di scadenza (ossia la data in cui il corso perde di validità e se necessario deve essere rinnovato). L'applicativo permette di gestire il rinnovo dei corsi e fornisce una sorta di notifica quando uno di questi è prossimo alla scadenza. Tramite le varie pagine web è inoltre possibile raccogliere moltissime informazioni sulle qualifiche, sui corsi e sui collaboratori e in alcuni casi è anche possibile esportarle in formati pdf o excel. HuRBIS
5/40 English The HuRBIS project was made for Tre Valli Soccorso, and its goal is to provide the company a tool for managing training courses. This tool gives the possibility to assign courses and qualifications to employees, but also to make any changes to the certification dates and expiration of the courses. As just mentioned, each course has a certification date (the date on which the collaborator obtains the license) and an expiration date (the date on which the course loses its validity and if necessary must be renewed). The application allows you to manage the renewal of courses and provides a notification when one of these is about to expire. Through the various web pages it is also possible to collect a lot of information on qualifications, courses and collaborators and in some cases it is also possible to export them in pdf or excel formats. HuRBIS
6/40 1 Stato dell’arte 1.1 La situazione attuale Questo progetto vuole dare all’azienda uno strumento per la gestione dei corsi di formazione, perchè al momento la soluzione attuale non garantisce loro affidabilità e comporta un alto rischio di errori, perdite di dati e analisi non conformi. La soluzione attuale si basa sull’utilizzo di fogli excel in cui vengono inseriti tutti I dati dei collaboratori. Il problema di questa soluzione però è che è molto instabile in quanto è facile sbagliare le celle in cui sto inserendo I dati, e anche in caso di rimozione di un collaboratore, di una qualifica o di un corso bisogna assicurarsi di propagare correttamente le modifiche effettuate in ogni cella di tutti I fogli excel. Figura 1 Estratto di un foglio excel (sena i dati aziendali) Come mostrato nella figura sopra riportata, si può vedere quanto è confusionaria la gestione di solo un foglio (e per giunta in questo screen è stata tagliata gran parte della tabella ,in quanto raffigurare tutti i corsi in un immagine è impossibile), immaginiamo ad esempio di dover rimuovere un collaboratore e che questo sia presente in altri quattro fogli excel, se ci dimenticassimo di rimuovere una riga in cui esso è presente si creerebbero delle inconsistenze, la stessa cosa accadrebbe se aggiungessimo un nuovo collaboratore dimenticandoci di aggiungerlo in un uno degli altri fogli. Quello che si vuole fare è quindi creare un sistema che gestisca in modo automatico tutte queste dipendenze. HuRBIS
7/40 2 Progetto assegnato 2.1 La soluzione richiesta Inizialmente il progetto consisteva nello sviluppo di un software adibito alla valutazione dei collaboratori, ma dopo aver parlato con l’azienda è emersa un’esigenza maggiore in un altro ambito. Il progetto è infatti mutato in un applicativo adibito alla gestione dei corsi di formazione dei lavoratori. L’obiettivo del progetto è quello fornire alla Tre Valli Soccorso (TVS), un software amministrativo in grado di fornire una gestione ottimale dei corsi di formazione, dando la possibilità ad un utente amministratore di assegnare corsi ad un dipendente e di rimuoverli. Si cerca una soluzione molto flessibile che permetta di apportare modifiche alle date di certificazione e alle date di scadenza dei corsi, spesso infatti come riferitomi dall’azienda può essere necessario posticipare delle scadenze, o persino rinnovare dei corsi prima che questi scadano. Per facilitare quest’ultimo aspetto è inoltre utile introdurre un sistema di notifica (non troppo invasivo) che faccia capire all’amministratore quando un corso è in scadenza. Sarà inoltre possibile assegnare delle qualifiche ai vari dipendenti, e quest’ultime necessiteranno per l’appunto di corsi specifici, infatti andando sul profilo di un dipendente si potranno vedere i corsi necessari per quel collaboratore in base alle sue qualifiche. Oltre che a svolgere i corsi necessari per le sue qualifiche un dipendente può anche svolgere corsi non pertinenti con quella che è la sua qualifica, è quindi importante che questa possibilità venga presa in considerazione. Tra le altre funzionalità richieste c’è il reperimento delle informazioni, quest’ultime possono riguardare corsi, qualifiche e collaboratori, e soprattutto come queste sono legate tra loro, ad esempio se volessimo sapere quali collaboratori seguono un determinato corso questa operazione sarebbe utilissima in quanto velocizzerebbe moltissimo le ricerche, stessa per quanto riguarda le qualifiche. Sempre per velocizzare queste ricerche potrebbe essere utile implementare caselle di ricerca per cercare elementi ben precisi, o filtri di ordinamento. A volte può anche essere utile esportare file con le informazioni ricavate da queste ricerche, ad esempio in formato excel o pdf. Un’ultima funzionalità richiesta potrebbe essere l’inserimento di un calendario tramite il quale poter vedere le date di scadenza dei corsi, in modo più figurato. Quest’ultima funzionalità è stata richiesta in quanto uno dei fogli excel utilizzati dall’azienda rappresentava delle date e associate a queste delle date di scadenza. La cosa importante richiesta per questo applicativo è che sia flessibile, un amministratore deve essere in grado di apportare modifiche a qualunque cosa. HuRBIS
8/40 3 Tecnologie utilizzate 3.1 Node.js Node.js è il framework principale sul quale è costruito questo progetto, quest’ultimo viene utilizzato per scrivere applicazioni in Javascript lato server. Questo nome ha visto luce nel 2009 e ha avuto un buon successo tra aziende di un certo spessore che hanno deciso di utilizzarlo per i propri progetti, merito anche della presenza di Google nella sua creazione. Node.js garantisce la creazione di web applications veloci e scalabili, e questo avviene grazie al fatto che è basato su un modello I/O asincrono che opera sugli eventi. Node richiede al sistema operativo di ricevere notifiche al verificarsi di determinati eventi, e rimane quindi in sleep fino alla notifica stessa: solo in tale momento torna attivo per eseguire le istruzioni previste nella funzione di callback, così chiamata perché da eseguire una volta ricevuta la notifica che il risultato dell’elaborazione del sistema operativo è disponibile. La programmazione a eventi di Node consente al processo di ottenere una fluidità diversa da ciò che, ad esempio, è stato scritto in PHP. In questo caso l’esecuzione delle istruzioni segue percorsi fissi, con frequenti chiamate esterne che strozzano la procedura. Il server deve aspettare che ciò si sblocchi per procedere, ma con la programmazione event-driver si riesce a personalizzare le azioni di default legate a un evento. Caratteristiche principali • Asynchronous and Event Driven: Tutte le API delle librerie di Node.js sono asincrone, questo significa che sono non-blocking. Essenzialmente significa che un server basato su Node.js, non attende mai che un API restituisca i dati. Il server passa all'API successiva e un meccanismo di notifica ad eventi aiuta il server ad ottenere la risposta dalla chiamata API precedente. • Very Fast: Essendo basato sul motore JavaScript V8 di Google Chrome, Node.js è molto veloce nell’esecuzione del codice. • Single Threaded but Highly Scalable: Node.js utilizza un modello a singolo trhead con un loop di eventi. Il meccanismo degli eventi aiuta il server a rispondere in modo non-blocking e rende il server altamente scalabile rispetto ai server tradizionali che creano thread limitati per gestire le richieste. • No Buffering: Le applicazioni Node.js non bufferizzano mai alcun dato. Queste applicazioni generano semplicemente i dati in blocchi. • Licence: Node.js è rilasciato sotto licenza MIT. Figura 2 nodejs HuRBIS
9/40 3.2 Back-end ExpressJS è un framework per applicazioni Web che offre un API semplice per creare siti Web, web App e back-end. Con ExpressJS inoltre, non devi preoccuparti di meccanismi di basso livello quali protocolli e processi. Express fornisce un'interfaccia minima per creare le nostre applicazioni. Ci fornisce gli strumenti necessari per creare la nostra app. È inoltre molto flessibile in quanto vi sono numerosi moduli disponibili su npm, che possono essere direttamente collegati a Express. Attraverso questo strumento ho creato il server del progetto, ho quindi definito gli end point dai quali prelevare i dati e ho messo il server in ascolto sulla porta 5000. 3.3 Front-end Per quanto riguarda il front-end ho deciso di utilizzare React, una libreria Javascript open source, usata per costruire interfacce utente. Sviluppata da Facebook, è stata utilizzata per la realizzazione del news feed all'interno del social network e per costruire la versione web di Instagram. Tra i vantaggi che React garantisce troviamo: la semplificazione della realizzazione di applicazioni web dinamiche a singola pagina (single-page web application) rendendo il loro sviluppo estremamente semplice e veloce. React può essere usata sia per creare applicazioni web partendo da zero che per essere integrata all'interno di un progetto già esistente. Al contrario di altri framework client-side, React offre anche la possibilità di effettuare il rendering delle pagine direttamente sul server, per poi inviare al browser il codice HTML che rappresenta lo stato iniziale dell'applicazione. Nel caso di altri framework, infatti, quando il browser si collega per la prima volta ad un determinato indirizzo (es. my-app.it), scarica il codice HTML di base che funge da contenitore per la web app. Sarà, quindi, compito del codice Javascript completare la creazione e inizializzazione del resto del DOM. React utilizza un approccio dichiarativo e semplifica la creazione di applicazioni single-page dinamiche (Single Page Applications o SPA). Un'applicazione web viene strutturata in diversi componenti (React Components). In maniera approssimativa, possiamo dire che un'applicazione realizzata con React è composta da tanti componenti quanti sono i vari elementi che compongono l'interfaccia. È nostro compito decidere quali componenti creare e come strutturarli. In React, i componenti sono componibili. Ciò vuol dire che un componente può contenere al suo interno altri componenti. Non tutti i componenti sono uguali, nel senso che, all'interno della nostra applicazione, potremmo avere componenti che svolgono un ruolo più importante di altri. I componenti possono mantenere uno stato interno e possono "comunicare" tra di loro. un componente è un blocco autonomo e riutilizzabile che ad un determinato istante mostra a video qualcosa, per esempio dei dati o un'immagine, e con cui un utente può interagire (Un componente può essere programmato per eseguire una certa azione in seguito al click del mouse da parte dell'utente). Parleremo di Rendering di un componente per indicare l'atto di creazione o aggiornamento delle informazioni in esso contenute da parte della libreria React. Sarà nostro compito specificare cosa vogliamo che venga mostrato da ciascun componente. Sarà, invece, la libreria React a occuparsi di creare e aggiornare il componente in seguito all'interazione di un utente o alla variazione dei dati contenuti nel componente stesso (Per esempio quando viene prelevata da un server una versione aggiornata delle informazioni contenute in un componente). Per far ciò, React utilizza il Virtual DOM invece di operare direttamente sul DOM reale. Il Virtual DOM è un'astrazione del DOM. Si tratta di una rappresentazione in memoria del DOM. È veloce e indipendente dalle specifiche implementazioni del browser. Possiamo pensare al Virtual DOM come una copia in memoria del DOM reale. Quando avviene una variazione dei dati all'interno dell'applicazione (per esempio cambia lo stato e le informazioni contenute in un componente), React effettua le modifiche sul Virtual DOM e lo aggiorna per rispecchiare i cambiamenti avvenuti. React calcola poi la differenza tra le due rappresentazioni del Virtual DOM, ovvero fra la rappresentazione del Virtual DOM prima che i dati venissero modificati e l'attuale rappresentazione del Virtual DOM (dopo la modifica dei dati all'interno dell'applicazione). La differenza tra le due rappresentazioni del Virtual DOM, è ciò che deve essere cambiato nel DOM reale. HuRBIS
10/40 A questo punto, React effettua le modifiche nel DOM reale, aggiornando solo ed esclusivamente quello che deve essere cambiato. Utilizzando questa tecnica, si riescono a ottenere prestazioni elevate che permettono alla nostra applicazione di funzionare in maniera veloce. 3.4 Database Il database è una delle parti più importanti del progetto, in quanto tutto si regge su quest’ultimo, una buona progettazione consente la facilitazione di moltissime operazioni in futuro. La tecnologia che ho deciso di utilizzare è mySQL, in quanto già utilizzata dall’azienda in un altro loro applicativo. MySQL è un sistema di gestione open source per database relazionali (RDBMS) supportato da Oracle e basato su Structured Query Language (SQL). MySQL funziona praticamente su tutte le piattaforme, inclusi Linux, UNIX e Windows. Sebbene possa essere utilizzato in una vasta gamma di applicazioni, MySQL è spesso associato ad applicazioni Web e a pubblicazioni online. Un database relazionale memorizza i dati in tabelle separate anziché metterli tutti i dati in un grande magazzino. Le strutture del database sono organizzate in file fisici in modo che ottimizzino la velocità delle operazioni. Il modello logico, attraverso oggetti come database, tabelle, viste, righe e colonne, offre un ambiente di programmazione flessibile. È possibile impostare regole che governano le relazioni tra diversi campi di dati e tra diverse tabelle. Il database applica queste regole, in modo che progettandolo nel giusto modo, l'applicazione non visualizzi mai dati incoerenti, duplicati, obsoleti o mancanti. La parte “SQL” di "MySQL" sta per "Structured Query Language". SQL è il linguaggio standardizzato più utilizzato per accedere ai database. A seconda dell'ambiente di programmazione, è possibile immettere direttamente codice SQL, incorporare istruzioni SQL nel codice scrivendolo in un altro linguaggio o utilizzare un'API specifica del linguaggio che nasconde la sintassi SQL. 3.5 Altri strumenti: 3.5.1 Trello Trello è un software gestionale in stile Kanban basato sul web. Originariamente prodotto da Fog Creek Software nel 2011, è stato trasferito ad una società separata nel 2014, per essere successivamente venduto ad Atlassian nel gennaio 2017. Gli utenti possono creare le loro schede attività con più colonne e scambiare le attività tra di loro. In genere le colonne sono organizzate in stati dell'attività: Da fare, In corso, Fatto. Il software ha una vasta possibilità di impiego, come la gestione immobiliare, la gestione di progetti software, i bollettini scolastici, la pianificazione delle lezioni, la contabilità, il web design, i giochi e la gestione dei casi legali. HuRBIS
11/40 Figura 3 Trello 3.5.2 Postman Postman è un’applicazione del browser Google Chrome che consente di costruire, testare e documentare API più velocemente. Tramite Postman è possibile effettuare delle chiamate API senza dover mettere mano al codice dell’applicazione, consentendo di effettuare le chiamate tramite questo plugin che fornisce un’utile interfaccia grafica. Le richieste possono essere effettuate sia verso un server locale che verso un server online impostando tutti i dati di una tipica chiamata API, dagli headers al body. Figura 4 Postman HuRBIS
12/40 3.5.3 GitHub GitHub è un sito Web e servizio basato su cloud che aiuta gli sviluppatori a memorizzare e gestire il proprio codice, nonché a tenere traccia e controllare le modifiche al proprio codice. E’ uno strumento che utilizzo fondamentale in ogni progetto. Figura 5 GitHub HuRBIS
13/40 4 Pattern utilizzati 4.1 Redux Poiché i requisiti per le applicazioni JavaScript single-page sono diventati sempre più complicati, il nostro codice deve gestire sempre più stati che mai. Questi stati possono includere le risposte del server e i dati memorizzati nella cache, nonché i dati creati localmente che non sono ancora stati messi sul server. Anche lo stato dell'interfaccia utente sta aumentando in termini di complessità, poiché è necessario gestire active routes, tabs, spinners, controlli di impaginazione e così via. Gestire questo stato in continua evoluzione è difficile. Se un modello può aggiornare un altro modello, una view può aggiornare un modello, che aggiorna un altro modello e questo, a sua volta, potrebbe causare l'aggiornamento di un'altra view. Ad un certo punto, non capisci più cosa succede nella tua app poiché hai perso il controllo del suo stato. Quando un sistema è opaco e non deterministico, è difficile riprodurre bug o aggiungere nuove funzionalità. Come se ciò non bastasse, bisogna considerare i nuovi requisiti diventati comuni nello sviluppo del front-end. Come sviluppatori, ci si aspetta di gestire optimistic updates, server-side rendering, il recupero dei dati prima di eseguire le route transitions e così via. Ci troviamo quindi a gestire una complessità con cui non abbiamo mai avuto a che fare prima, e inevitabilmente ci poniamo la domanda: è tempo di arrendersi? La risposta è no. 4.2 Come funziona Il vantaggio principale di Redux è l'efficienza che offre. Redux ti consente di memorizzare lo stato dell’applicazione in quello che viene chiamato "Redux Store" e utilizza le actions per chiamare i reducers, che a loro volta manipoleranno lo stato nel modo opportuno. Ad esempio, immaginiamo di dover andare in un negozio di alimentari, di dover chiedere al vicino E, di chiedere al vicino D, di chiedere al vicino C, di chiedere al vicino B, di chiedere al vicino A, se puoi avere un po 'del loro pane. Funziona ... ma è piuttosto scomodo. E se ci fosse un modo per farti consegnare il pane direttamente a te? È qui che brilla Redux. con l'uso del Redux Store, quel pane è sempre disponibile ogni volta che ne hai bisogno. Nessuna props da passare, niente discorsi con i vicini, basta semplicemente comunicare con lo store e ottenere ciò di cui hai bisogno. Figura 6 Redux pattern HuRBIS
14/40 4.3 Actions Le Actions sono dei semplici oggetti javascript utilizzati per inviare informazioni allo Store. Si tratta dell'unico mezzo attraverso il quale si può richiedere l'aggiornamento delle informazioni presenti nello Store, che è l'oggetto che mantiene lo stato dell'intera applicazione. L'unico requisito delle Action è che siano degli oggetti contenenti una proprietà type, la sola proprietà necessaria affinché un oggetto possa definirsi un'Action. Oltre alla proprietà type, possiamo aggiungere altre proprietà, a seconda delle necessità e delle informazioni che vogliamo passare ai Reducer che sono i destinatari finali delle Action. Per prima cosa creeremo un file denominato actionTypes.js, in cui defineremo i nomi delle diverse Action. È opportuno definire i nomi delle diverse Action come costanti all'interno di un file per evitare errori nella scrittura e semplificare lo sviluppo delle applicazioni. Questo accorgimento può salvare tempo soprattutto quando si realizzano applicazioni più complicate. A questo punto definiamo le diverse Action in un file che chiameremo collaboratorAction.js. Potremmo creare un semplice oggetto come il seguente. A questo punto possiamo aggiungere un'altra proprietà, attraverso la quale selezioneremo un elemento ben preciso, in questo caso la lista dei collaboratori. Risulta allora evidente la necessità di utilizzare delle funzioni per creare le Action in maniera dinamica. All'interno del file collaboratorAction.js inseriremo quelli che Redux definisce Action creators. Si tratta di funzioni che restituiscono un'azione. Definiamo allora una funzione fetchCollaborators (). HuRBIS
15/40 4.4 Reducers I Reducer sono le uniche funzioni autorizzate ad aggiornare le informazioni contenute nello Store il quale è l'oggetto predisposto a mantenere lo stato dell'intera applicazione. È importante sottolineare che le funzioni Reducer non modificano l'oggetto State, ricevono in ingresso l'oggetto State corrente e restituiscono un nuovo oggetto State. A tal fine, nel caso si debba lavorare con oggetti o array, può essere utile usare la funzione Object.assign() e l'operatore spread (...). Dati gli argomenti in ingresso, una funzione Reducer deve calcolare il prossimo valore dell'oggetto State e restituirlo. I Reducer, essendo funzioni pure, non devono mai modificare l'oggetto State, verrà sempre restituito un nuovo oggetto. Una volta definito quale sarà l'oggetto State che rappresenta lo stato globale dell'applicazione, possiamo definire la funzione Reducer che potrà aggiornarlo. Possiamo usare due approcci. Creare un Reducer e poi eventualmente riorganizzare il codice e scomporre tale Reducer in più funzioni. Oppure creare una funzione Reducer per ogni pezzo dell'oggetto State e poi combinare tali funzioni in un'unico Reducer. Per ogni proprietà dell'oggetto State che vogliamo aggiornare, definiamo una funzione Reducer che avrà l'incarico di gestire solo quella singola parte dell'intero oggetto State. In questo particolare caso, creiamo un Reducer per ogni proprietà, per mostrare come sia possibile combinarli insieme per creare un unico Reducer. Alla fine ciò che dovrà essere creato è un singolo Reducer (chiameremo questo Reducer col nome rootReducer) che si occuperà di aggiornare l'intero oggetto State dell'applicazione e che verrà passato alla funzione createStore(rootReducer) per creare lo Store. HuRBIS
16/40 Quando collaboratorReducer riceve un Action con proprietà type uguale a 'ADD_COLLABORATOR', usiamo l'operatore spread (...) per restituire un nuovo array, composto da tutti i valori presenti nel vecchio array a cui abbiamo concatenato il nuovo elemento da aggiungere. Dobbiamo creare un Reducer che gestisca l'intero oggetto State. Possiamo farlo combinando le funzioni create. Possiamo usare la funzione combineReducers, definita nel modulo redux che possiamo scaricare con NPM. La funzione combineReducers riceve come argomento un oggetto in cui ogni proprietà ha come valore un riferimento a una funzione Reducer e restituisce una funzione Reducer che a sua volta ha come valore di ritorno un altro oggetto. Quest'ultimo avrà delle proprietà che hanno lo stesso nome di quelle dell'oggetto passato come argomento a combineReducers e per valore il risultato dell'esecuzione di quelle funzioni. L'oggetto restituito dal Reducer complessivo costituirà l'oggetto State dell'applicazione. Vediamo un esempio per comprendere meglio il comportamento della funzione combineReducers. 4.5 Store L'ultimo elemento essenziale di Redux è lo Store che è l'oggetto che mantiene l'oggetto State dell'applicazione e fornisce alcuni metodi come getState() che restituisce l'oggetto State dell'applicazione e dispatch(action) che serve per lanciare un'Action. Store ha inoltre una funzione subscribe(listener) che serve per registrare una funzione che verrà invocata ogni volta che un'Action verrà lanciata da dispatch(action). Per creare lo Store useremo la funzione createStore(rootReducer) fornita da Redux. La funzione createStore riceve altri argomenti che per ora trascuriamo. Il primo argomento da passare a createStore è il Reducer "complessivo" che restituisce l'oggetto State aggiornato. Nel nostro caso dovremo passare rootReducer. Notate che la funzione subscribe() restituisce una funzione (che chiameremo unsubscribe()) che, se invocata, permette di rimuovere newListener dall'array delle funzioni che verranno invocate ogni volta che viene eseguita la funzione dispatch(). Viene inoltre invocata (subito prima del return) la funzione dispatch() passando un'Action che è un oggetto vuoto. In questo modo viene inizializzato l'oggetto State con il valore iniziale restituito dalla chiamata alla funzione rootReducer(undefined, {}). Un altro elemento importante in questo contesto è il middleware, il modo suggerito per estendere Redux con funzionalità personalizzate. Un middleware ti consente di “wrappare” il metodo dispatch dello store. La caratteristica chiave del middleware è che sia componibile. È possibile combinare più middleware in cui ognuno di questi non richiede alcuna conoscenza di ciò che avviene prima o dopo nella catena. Il caso d'uso più comune del middleware è quello di supportare le azioni asincrone. Lo fa consentendo di inviare azioni asincrone oltre alle azioni normali. Ad esempio, redux-thunk consente agli action creators di invertire il controllo inviando funzioni (dispatch). Ricevono il dispatch come argomento e possono chiamarlo in modo asincrono. Tali funzioni sono chiamate thunk. Un altro esempio di middleware è redux-promise. Consente di inviare una promise async action e inviare un’action normale quando la promise viene effettuata. HuRBIS
17/40 Il middleware non è integrato in createStore e non è una parte fondamentale dell'architettura Redux, ma è considerato abbastanza utile da essere supportato con facilità. 4.6 Redux e React Spesso Redux viene associato a React, libreria di cui abbiamo discusso in precedenza. Molti sviluppatori pensano che questo connubio sia indissolubile, ovvero che se usi React devi necessariamente usare Redux (e viceversa). In realtà le due librerie sono totalmente scollegate: è possibile usare React senza Redux, come è pure possibile usare Redux con JavaScript puro o con altre librerie e framework come Angular o jQuery. Il motivo per cui spesso si tende ad accoppiare Redux con React dipende probabilmente dalla natura dei componenti di React: elementi il cui rendering visivo deriva dalle variazioni di stato. Questo reagire alle variazioni di stato si presta bene ad essere interfacciato con il modello publisher/subscriber proposto da Redux In altre parole, possiamo registrare un componente React tramite store.subscribe() in modo che venga avvertito quando si verifica un cambio di stato in Redux per effettuare il rendering automatico sulla base della nuova situazione. Naturalmente non c’è nulla di particolarmente complesso in questo, che potrebbe quindi essere un approccio praticabile. Ma se vogliamo sfruttare al meglio le prestazioni di React dovremmo effettuare alcune analisi delle condizioni dello stato attuale dello store di Redux prima di avviare il rendering. Si pensi, ad esempio, al caso in cui lo stato di Redux ha subito una modifica, ma nessuno dei dati che interessano il nostro componente è stato cambiato. In questa situazione rischieremmo di fare dei rendering inutili che possono avere un impatto non indifferente sulla nostra applicazione. Per evitare di fare manualmente queste analisi possiamo ricorrere a React Redux, la libreria ufficiale per il binding ottimizzato tra componenti React e lo store di Redux. Per installarla in un ambiente di sviluppo basato su Node.js, come nel mio caso, è sufficiente lanciare il comando: npm install --save react-redux HuRBIS
18/40 Una volta installata la libreria, la prima cosa da fare è rendere disponibile lo store di Redux ai componenti dell’applicazione React Nei componenti vediamo l’importanza della funzione connect() ed il suo utilizzo come decorator. La funzione prevede due parametri ed il risultato finale dell’applicazione sul nostro componente è il componente stesso arricchito di props che consentono indirettamente di interagire con lo store di Redux. La prima funzione riceve lo stato corrente di Redux e restituisce un oggetto sulle cui proprietà sono mappati i valori dello stato rilevanti per il componente corrente. La seconda funzione riceve come parametro la funzione dispatch() di Redux e restituisce un oggetto con dei metodi che interagiscono con lo stato di Redux. In sintesi, la prima funzione consente di ricevere la porzione di stato a cui il nostro componente è interessato, la seconda funzione consente invece di apportare modifiche allo stato tramite il dispatching di un’azione. Come risultato di questi mapping avremo che il componente Collaborator avrà tra le sue props collaboratorInfos, potendo quindi effettuare il rendering di variazioni di stato e di richiedere variazioni dello stato di Redux. HuRBIS
19/40 5 Progettazione del database 5.1 Descrizione Per quanto riguarda la fase di progettazione del database, ho definito le tabelle collaborator, qualification e courses che ho collagato tra di loro tramite delle relazioni n a m, dopodichè ho collegato a collaborator history courses con relazione 1 a n. Courses è definito da un nome e da un flag che indica se sia stato rimosso o meno. Un collaborator è definito da un nome, un cognome, dall’anno di nascita e pure lui da un flag che indica se sia stato rimosso o meno, ho scelto di utilizzare questa tipologia di rimozione per avere la possibilità di recapitare un elemento anche dopo la rimozione. Le informazioni relative alla durata del corso (certification_date e expiration_date) le ho salvate all’interno della tabella che collega i corsi ai collaboratori, questo perché sono informazioni riguardanti sia il collaboratore che il corso, e la stessa cosa l’ho fatta con il flag instructor, che indica se durante il corso ha svolto il ruolo di istruttore o meno. In history_courses ho inserito tutti i corsi di un collaboratore con data di scadenza minore della data corrente, in questo modo riesco ad avere uno storico di tutti i corsi svolti da ogni dipendente, sia che quest’ultimi siano stati rimossi o meno dal database. Figura 7 Database HuRBIS
20/40 Una volta definito il database e iniziato a lavorare sull’applicativo è emersa la necessità di caricare dal database determinate porzioni di dati. Quello che ho fatto su SQL Workbench, è stato quindi testare le query necessarie per prelevare queste porzioni di dati, per poi trasportare quest’ultime nei relativi end points dell’applicativo, come mostrato nell’esempio in seguito. Figura 8 MySQL Workbench HuRBIS
21/40 6 Implementazione 6.1 Creazione del progetto Come prima cosa ho creato la cartella del progetto e dentro a questa ho lanciato il comando: npm init Attraverso questo comando viene creato il file package.json dell’applicazione, che contiene tutte le informazioni relative al progetto come il nome, la versione, gli scripts, le dipendenze ecc. Quando lanciamo questo comando infatti vengono richieste una serie di cose, tra cui il nome, la versione dell’applicazione e l’entry point del file. A questo punto già installare le librerie sottocitate. npm i express concurrently npm i nodemon –save-dev Con il primo comando installiamo express (framework citato nelle pagine precedenti) e concurrently, libreria adibita al lancio di comandi in parallelo. Con il secondo comando installiamo nodemon, strumento che aiuta a sviluppare applicazioni basate su node.js riavviando automaticamente l'applicazione nodo quando vengono rilevate modifiche ai file nella directory. Nodemon è un wrapper sostitutivo per node, per utilizzarlo è sufficiente rimpiazzare nella linea di comando nodemon al posto di node ogniqualvolta che eseguiamo uno script. Come si può notare viene installato in dev, in questo modo ne usufruiamo solamente in fase di development, perché quando il progetto viene mandato in produzione non è necessario, in quanto non ci capiterà più di dover modificare il codice. A questo punto creiamo un file server.js e andiamo nel file package.json ad aggiungere i seguenti elementi a scripts: Con questo passaggio saremo in grado lanciare il server con il comando npm run server Ora creiamo l’applicazione attraverso il comando npm i -g create-react-app HuRBIS
22/40 npx create-react-app client Attraverso questi comandi verrà creata l’applicazione in modo da poter utilizzare react nella parte frontend. Andiamo quindi nella cartella client appena creata e lanciamo il comando npm start Così facendo si potrà già lanciare il client in modo concorrente rispetto al server. Per dire al server di sviluppo di delegare eventuali richieste sconosciute al server API in fase di sviluppo, ho poi aggiunto un campo proxy al file package.json del client In questo modo, quando recuperi ('/collaborators') in fase di sviluppo, il server riconoscerà che non si tratta di una risorsa statica e eseguirà il proxy della richiesta a http://localhost:5000/collaborators come fallback. Bisogna però tenere presente che il proxy ha effetto solamente durante lo sviluppo (con npm start) e spetta al programmatore assicurarsi che l’URL /collaborators punti al giusto indirizzo. Qualsiasi richiesta senza un’intestazione accetterà text/html e verrà reindirizzata al proxy specificato. L’opzione proxy supporta le connessioni HTTP, HTTPS e WebSocket. Ho inoltre fatto un’ultima modifica agli script di package.json del server per velocizzare il lavoro in modo da lanciare in modo concorrente sia il server che il client. In conclusione, dopo tutti questi passaggi sono in grado di lanciare client e server con il comando npm run dev ma senza doverli rilanciare ogniqualvolta viene fatta una modifica al codice, infatti sarà sufficiente salvare il documento modificato per rilanciare automaticamente entrambi. HuRBIS
23/40 6.2 Server La prima cosa fatta una volta iniziata la fase implementativa è stata andare a lavorare sulla parte server. Ho quindi importato express e body-parser, quest’ultimo è un middleware che ha l’obiettivo di convertire oggetti JSON in arrivo. Dopodiché ho istanziato una variabile app, tramite questa ho avviato un server e l’ho messo in ascolto sulla porta 5000. Ora abbiamo un server a tutti gli effetti che risponde alle richieste degli URL specificati, ad ogni altro percorso risponderà invece con un 404 not found. Quando io chiamo app.use passo come primo parametro l’URL e come secondo la routes relativa a quell’URL. Tutte queste routes sono salvate dentro una cartella routes dove vengono gestite in file separati attraverso la classe express.Router, Questa classe permette di creare handler di route modulari, montabili. Un’istanza Router è un middleware e un sistema di routing completo; per questa ragione, spesso si definisce “mini-app”. Nel seguente esempio si crea un router come modulo, si carica al suo interno una funzione middleware, si definiscono alcune route e si monta un modulo router su un percorso nell’app principale. Qui di seguito è mostrato come viene gestita la route di collaborator. HuRBIS
24/40 Dove mysqlConnection è la connessione vera e propria e viene esportata da un altro file che comprende tutte le informazioni relative al database a cui ci vogliamo connetterci, denominato connection.js HuRBIS
25/40 Solo all’interno di questo file viene importato mysql, in questo modo riesco a separare bene la logica all’interno dell’applicazione. A questo punto possiamo creare una connessione passando come parametri host, user, password e il database a cui voglio connettermi. Il flag multiStatements che ho settato a true consente di inviare più di una query al server, separate da ';'. 6.3 Client Una volta definito il server possiamo iniziare a lavorare sul client, andiamo quindi nella cartella client e creiamo una cartella components dove andremo andremo ad inserire tutti i componenti rappresentanti pagine, modals e altri elementi utilizzati nel progetto. Iniziamo quindi con la creazione del componente collaborator.js, in questo file andremo semplicemente a caricare la lista di tutti i collaboratori presenti nel database. Figura 9 Home page In questa pagina possiamo vedere le informazioni anagrafiche dei collaboratori, le qualifiche e i corsi che sta svolgendo. È possibile ricercare i collaboratori più velocemente attraverso la casella di ricerca e ordinare il collaboratore in ordine alfabetico, e anche in ordine di scadenza di contratto. Da questa pagina è inoltre possibile accedere alla scheda di tutti i collaboratori, inserire e rimuovere collaboratori attraverso a dei pulsanti infondo alla pagina. Possiamo vedere se un collaboratore è in scadenza tramite il bollino giallo alla sinistra del suo cognome, ossia se ha una data di scadenza tra i suoi corsi minore di un anno, altrimenti il bollino è verde. HuRBIS
26/40 Nella parte superiore di questa pagina possiamo notare una barra di navigazione, questa è definita come componente separato, in quanto riutilizzabile in altre pagine. Un’altra pagina che ho implementato è quella delle qualifiche. Figura 10 Qualifiche In questa pagina è possibile, cosi come fatto similmente con i collaboratori, avere una lista di tutte le qualifiche presenti nel database, con i relativi collaboratori possedenti quella qualifica e i corsi ad esso associati. Attraverso i due pulsanti è possibile inserire nuove qualifiche, con i corsi necessari per quest’ultima o rimuovere delle qualifiche. Figura 11 Inserimento qualifica HuRBIS
27/40 Figura 12 Rimozione qualifiche In questa pagina è invece possibile avere la lista di tutti i corsi, con i collaboratori che svolgono quest’ultimi, e le qualifiche che necessitano questi corsi. Figura 13 Corsi HuRBIS
28/40 In questa pagina come in quelle precedenti sono presenti la casella di ricerca e il filtro di ordinamento. È possibile inserire dei nuovi corsi come mostrato nell’immagine sotto. Figura 14 Aggiunta corsi E rimuovere dei corsi Figura 15 Rimozione corsi HuRBIS
29/40 Ho poi lavorato alla scheda di un certo collaboratore. Figura 16 Scheda collaboratore Nella figura sopra riportata possiamo vedere le informazioni anagrafiche del dipendente, i corsi che sta svolgendo, ovvero quelli con la data corrente compresa tra la data di certificazione e la data di scadenza, i corsi che deve svolgere in futuro in base alle sue qualifiche e quelli che ha svolto in passato. Come si può vedere di fianco ad ogni corso è presente un bollino, questo rappresenta lo stato del corso. Il bollino verde indica che manca un anno alla scadenza del corso, il bollino giallo indica che manca meno di un anno alla scadenza, il simbolo della persona indica che il collaboratore è l’istruttore di quel corso e il bollino grigio che indica un corso non ancora iniziato. A fianco dei corsi possiamo vedere le date che tra l’altro è anche possibile modificare tramite il pulsante modifica corso. HuRBIS
30/40 Figura 17 Modifica corso Ad esempio, se volessimo prolungare la data di scadenza del corso CIR-2 Ricerca soluzioni da 31/05/2020 a 31/05/2022 come mostrato in figura noteremmo subito che il bollino a fianco passerebbe da giallo a verde. Se invece modificassimo la data di certificazione e la data di scadenza di un corso non ancora in svolgimento, e aggiungessimo delle date comprendenti la data corrente, il corso verrebbe spostato tra i corsi in svolgimento. Chiaramente questo passaggio di spostare i corsi da una tabella all’altra viene fatto automaticamente, appena un corso supera la scadenza finirà tra i corsi svolti, in questo modo è possibile avere uno storico di tutti i corsi svolti. Con il pulsante di modifica è inoltre possibile assegnare il ruolo di istruttore ad un corso. HuRBIS
31/40 Da questa pagina è possibile aggiungere corsi ad un dipendente come mostrato sotto. Figura 18 Assegnamento corsi O rimuovere dei corsi assegnati. Figura 19 Rimozione corsi assegnati HuRBIS
32/40 Si possono aggiungere qualifiche ai dipendenti premendo su aggiungi qualifica. Figura 20 Assegnamento qualifiche O rimuovere le qualifiche Figura 21 Rimozione qualifiche assegnate HuRBIS
33/40 Un’altra feature che mi è stata richiesta dall’azienda è stata quella di poter scaricare in formato pdf la scheda di un collaboratore, per fare questo è sufficiente premere sul pulsante “Scarica scheda collaboratore”. Figura 22 file pdf espotato HuRBIS
34/40 Ho poi creato una pagina riassuntiva in cui è possibile vedere tutti i collaboratori, con le date di certificazione più recenti rispetto ai corsi che segue. Figura 23 Pagina di riepilogo Da questa pagina è inoltre possibile rimuovere delle colonne premendo il pulsante “nascondi colonne” ed esportare la tabella in formato excel (chiaramente anche nel formato excel saranno nascoste le colonne rimosse). Figura 24 Rimozione colonne Rimuovendo i campi selezionati ed esportando la tabella in formato excel otteniamo come risultato il file riportato nell’immagine di seguito. HuRBIS
35/40 Figura 25 file esportato in excel Infine, l’ultima pagina è quella dove viene mostrato il calendario con le date di scadenza dei corsi. Figura 26 Calendario delle scadenze Premendo sul giorno cerchiato si viene reindirizzati nella pagina del collaboratore con il corso con quella data di scadenza. HuRBIS
36/40 7 Piani di Lavoro 7.1 Descrizione delle fasi Per quanto riguarda il piano di lavoro, ho deciso di utilizzare Trello, uno strumento per la gestione di progetti. Inizialmente ho occupato il mio tempo con lo studio di tutte le tecnologie necessarie al progetto (React, Nodejs, express, Redux, mysql ecc.). Dopodichè ho iniziato a configurare il progetto, installando le librerie necessarie per poter fare partire il progetto, collegando inoltre quest’ultimo a GitHub. Dopo ho iniziato con la creazione del front-end, visto che non avevo l’accesso ai dati dell’azienda. Chiaramente quando ho creato tutti i componenti ho utilizzato dei dati fittizi, e solo una volta ricevuti i dati dell’azienda ho potuto iniziare con la creazione del database. Ho quindi creato tutte le tabelle del progetto, ristrutturando il database diverse volte in quanto non convinto dalle soluzioni precedenti. Una volta convinto della mia soluzione ho deciso di rappresentare sui componenti creati nel front-end i dati presenti nel database, prima di fare questo però ho dovuto creare gli endpoints per prelevare i dati. Ho iniziato perciò a lavorare con express alla parte riguardante il back-end, in questa fase ho inserito le informazioni necessarie per l’accesso al database, e creato gli endpoints come citato in precendenza, e all’interno di questi ho inserito le necessarie query. Per testare la funzionalità del server ho utilizzato Postman, strumento grazie al quale è possibile rappresentare le informazioni prelevate dal database anche in mancanza di un front-end (pur avendolo già creato ho deciso di fare in questo modo, perché credo che sia giusto poter lavorare a tutte le fasi del progetto in modo separato). Una volta verificato il corretto funzionamento degli endpoints ho posto delle modifche al front-end, facendo in modo di prelevare le informazioni da questi. Per fare questo, quando ho potuto, ho cercato di utilizzare il pattern Redux. Infine, ho testato il corretto funzionamento dell’applicativo cercando eventuali bug, una volta fatto ciò sono partito con la scrittura di documentazione e poster. 7.2 Metodologia AGILE I principi che devono essere rispettati affinché un metodo possa definirsi Agile sono: 1. Gli individui e le interazioni più che i processi e gli strumenti. 2. Il software funzionante più che la documentazione esaustiva. 3. La collaborazione col cliente più che la negoziazione dei contratti. 4. Rispondere al cambiamento più che seguire un piano. HuRBIS
37/40 Figura 27 Metodologia AGILE L’idea del Metodo Agile non si basa sull’approccio classico e lineare di progettazione, ma sulla possibilità di realizzare un progetto per fasi, chiamate “sprint”. Ad ogni sprint corrisponde una nuova funzionalità e viene verificata la soddisfazione del cliente, al quale viene mostrato il lavoro svolto fino a quel punto. Un sistema iterativo (ed interattivo) che consente di apportare agilmente modifiche al progetto, di abbattere i costi di produzione e, soprattutto, di evitare effort inutili ed un eventuale fallimento del progetto. È stato infatti fondamentale per la buona uscita del progetto, avere dei ricorrenti incontri con il committente, in modo da sviluppare un progetto sempre più in linea con quelle che sono le sue idee. Spesso e volentieri inoltre, un cliente non sa veramente quello che vuole, quello che vorrebbe è vedere una soluzione che risolva le sue problematiche, e utilizzando un’approccio AGILE è molto più semplice andare in contro a questa evenienza. HuRBIS
38/40 8 Conclusioni 8.1 Risultati In conclusione, l’applicativo possiede le funzionalità richieste dall’azienda e quindi mi ritengo soddisfatto del lavoro fatto. Ho inoltre imparato ad utilizzare moltissimi strumenti come React, Redux e Nodejs, molto utili nella realizzazione di progetti di questo tipo, e approfondito l’utilizzo di molti strumenti già utilizzati come mySQL. 8.2 Sensazioni personali Tramite questo progetto ho inoltre imparato ad approcciarmi con un’azienda in modo professionale e a gestire dei meeting. Questo progetto mi ha aiutato a capire quanto può essere difficile capire le tempistiche di un progetto, spesso infatti mi sono ritrovato a non sapere quanto ci volesse per realizzare determinate funzionalità e ho dovuto tirare delle stime. 8.3 Sviluppi futuri In futuro sarà facilmente possibile introdurre funzionalità relative ai costi dei corsi e la possibilità di autenticarsi. HuRBIS
39/40 Bibliografia [1] http://www.datrevo.com/postman-per-testare-le-api/. [2] https://blog.serverplan.com/2018/05/10/node-js/. [3] https://create-react-app.dev/docs/proxying-api-requests-in-development/. [4] https://dev.mysql.com/doc/internals/en/multi-statement.html. [5] https://dev.mysql.com/doc/refman/8.0/en/what-is-mysql.html. [6] https://dev.to/dylanmesty/redux-basics-explained-from-a-beginner-s-perspective-abm. [7] https://expressjs.com/en/starter/hello-world.html. [8] https://expressjs.com/it/guide/routing.html. [9] https://glue-labs.com/articoli/react-una-libreria-javascript-facebook-per-il-nuovo-web-ui. [10] https://nodejs.org/it/about/. [11] https://ordergroup.co/en/blog/best-backend-technologies-2019/. [12] https://redux.js.org/api/applymiddleware. [13] https://redux.js.org/introduction/motivation. [14] https://searchoracle.techtarget.com/definition/MySQL. [15] https://www.html.it/pag/69090/redux-e-react/. [16] https://www.mrwebmaster.it/javascript/introduzione-react_12363.html. [17] https://www.mrwebmaster.it/javascript/redux-come-funziona_12410.html. [18] https://www.tutorialspoint.com/expressjs/expressjs_overview.htm. [19] https://www.tutorialspoint.com/nodejs/nodejs_introduction.htm. [20] https://hubstrat.it/metodo-agile-scrum-vantaggi-azienda/ HuRBIS
40/40 Allegati ProgettoDipl\Info\Palmas Eric | |____Poster | |_____ POSTER_PALMAS |____ Presentazione | |_____ PRES_ PALMAS |____ Rapporto | |_____ DOC_PALMAS | |_____Codice progetto (https://github.com/ericpalmas/HuRBIS) HuRBIS
Puoi anche leggere