Compare commits

...

134 Commits

Author SHA1 Message Date
VANNEAU 32780292d9 Test 2 years ago
VANNEAU 36d5b9b5be docker 3 years ago
VANNEAU e6541acd07 Passage en version 12 + image docker OK 3 years ago
VANNEAU 86c6ae0734 Update material 3 years ago
VANNEAU 8d153cf4c1 Update core & cli 3 years ago
VANNEAU f07a3e6794 npm install 3 years ago
VANNEAU 747e345494 Ajout docker et nginx 3 years ago
Jimmy Boinembalome ef1754e8a1 Merge branch 'f_ajout_theme_sombre' into develop 3 years ago
Jimmy Boinembalome 1001965e99 Ajout thème sombre 3 years ago
Jimmy Boinembalome 5315ed8f8d Merge branch 'ajout_scss' into develop 3 years ago
Jimmy Boinembalome 07de763723 Migration css vers scss 3 years ago
Yanaël GRETTE 5b4ded0939 Implémentation de l'ajout, la modification et la suppression d'un commentaire assistant 4 years ago
Yanaël GRETTE 3c4f4df19d Affichage de certains onglets des détails d'un EP qu'en fonction du statut EP 4 years ago
Yanaël GRETTE 1c41609db7 affichage des demandes de formation d'un EP 4 years ago
Yanaël GRETTE 283663f9cb récupération de l'implémentation des demandes de formations 4 years ago
Yanaël GRETTE 9f348c1b7f Implémentation de la liste des engagements, des propositions de date et du choix des dates 4 years ago
jboinembalome 1fc5aa7752 Merge branch 'mat-table' into develop 4 years ago
jboinembalome fed808d26f Ajout du mat-tables pour les demandes de formation + Ajout du mat-dialog pour l'affiche du détail + Début de l'interface pour l'ajout d'une demande 4 years ago
jboinembalome 7543d6a953 Ajout du paramètre statutsEp dans getDemandesFormation et getDemandesFormationCount 4 years ago
jboinembalome ecd95a5545 demandeFormationDTO: Remplacement de FormationDTO par FormationDetailsDTO 4 years ago
jboinembalome c397fec93c Ajout de la fonction afficherEtatDemande 4 years ago
jboinembalome c64889cf85 Ajout de la fonction estEPEnCours 4 years ago
Yanaël GRETTE 09059dee66 Implémentation de l'affichage des commentaires assistants, de la liste des participants et de la demande de délégation 4 years ago
Yanaël GRETTE 1c228628f1 Récupération d'un EP par son id avec affichage des détails de l'EP et des objectifs 4 years ago
Yanaël GRETTE 2e6b60f5c0 Mise à jour suite à des modifications OpenApi 4 years ago
Yanaël GRETTE bdcb627d52 petit merge 4 years ago
Yanaël GRETTE 0a0966f398 Possibilité de ne récupérer que les EP obligatoires dans la page assistant 4 years ago
Yanaël GRETTE 68017679e1 Mise à jour globalement sur les paramètres des counts 4 years ago
Yanaël GRETTE c0097aac86 mise à jour de commentaires 4 years ago
Yanaël GRETTE 67216c5b80 mise en place de compodoc avec le script 'npm run compodoc' pour générer la documentation du projet 4 years ago
Yanaël GRETTE d6192d422f Début mplémentation visuelle des détails d'un EP 4 years ago
Yanaël GRETTE 155f773b97 affichage des EP signés et référents pour les collaborateurs et les commerciaux 4 years ago
Yanaël GRETTE 0838e86509 Mise à jour de l'architecture du module EP 4 years ago
Yanaël GRETTE de956f8bc3 Mise à jour du home commercial 4 years ago
Yanaël GRETTE ba121e4eec Mise à jour du home collaborateur 4 years ago
Yanaël GRETTE 2d8a0b2769 Mise à jour du nav-menu collaborateur 4 years ago
Yanaël GRETTE 2f8abd0f77 Mise à jour du nav-menu 'commercial' 4 years ago
Yanaël GRETTE 95b714bf96 Mise à jour du nav-menu assistant 4 years ago
Yanaël GRETTE 25cd7554c2 Mise à jour du nav-menu RH 4 years ago
Yanaël GRETTE 4cfc1c8a13 Affichage du prochain EP du collaborateur dans ses détails 4 years ago
Yanaël GRETTE c399bb14fa Possibilité d'accéder aux EP depuis la page des détails collaborateur et référent 4 years ago
Yanaël GRETTE 8a5398658e Mise à jour des détails collaborateur et référent pour afficher les EP en cours et les EP passés 4 years ago
jboinembalome f1bd81022f Merge branch 'mat-table' into develop 4 years ago
jboinembalome 9321c05fd1 Ajout du composant ParticipationsFormationTableComponent dans affichage-details-collaborateur 4 years ago
jboinembalome 85cd6c2b86 Déplacement du code dans ngOnChanges + ajout des filtres pour statut et intitulé 4 years ago
jboinembalome 3af7f2dda4 Ajout des colonnes intitulé et statut 4 years ago
Yanaël GRETTE 330eba64b9 Affichage de la liste des EP signés 4 years ago
Yanaël GRETTE f5af77ff30 Création de fonctions pour l'affichage et l'état des statuts EP avec mise à jour de l'affiche des EP 4 years ago
Yanaël GRETTE 35abb47e9b merge conflicts 4 years ago
Yanaël GRETTE f33056fd28 Mise à jour du fichier home des assistants pour faire afficher les Ep en cours 4 years ago
jboinembalome 79cb30e775 Merge branch 'rh' into develop 4 years ago
jboinembalome 58c98d78a1 Ajout du composant ParticipationsFormationTableComponent dans details-formation 4 years ago
jboinembalome ca19622837 Ajout du composant ParticipationsFormationTableComponent 4 years ago
Yanaël GRETTE 011bfd8814 Ajout dun module ep-table 4 years ago
Yanaël GRETTE fa5159a3a9 Merge branch 'develop' of https://gitea.ci.apside-top.fr/ygrette/Digitalisation_EPA_Client into develop 4 years ago
jboinembalome ca628f3e5f Résolution de conflits entre develop et rh 4 years ago
Yanaël GRETTE 87e0282c2c Ajout du bouton pour accéder aux demandes de délégation dans le nav-menu 4 years ago
jboinembalome 9e26cfc768 Résolution des conflits 4 years ago
jboinembalome 9e326fde54 Ajout du composant FormationsTableComponent dans homme-rh et formations 4 years ago
Yanaël GRETTE f09c3cb8cf Ajout d'un popup de validation suite à la réponse d'une demande de délégation 4 years ago
jboinembalome 92eb7861a4 Suppression d'un console.log 4 years ago
jboinembalome 0366a9b607 Importation du module FilterModule dans AppModule 4 years ago
jboinembalome 805c4f3992 Importation du module MatListModule 4 years ago
jboinembalome 29d1314805 Creation du composant FormationsTableComponent 4 years ago
jboinembalome 851ee9e637 Création des composants SelectFilter et CheckboxFilter 4 years ago
jboinembalome 56b19f8a0b MAJ du dummyClientSecret avec la réinstallation de keycloak 4 years ago
Yanaël GRETTE 69eaf38f25 implémentation de la réponse à une demande de délégation 4 years ago
Yanaël GRETTE eace2b936c Mise à jour du module des demandes de délégation avec affichage des demandes de délégations reçues 4 years ago
Yanaël GRETTE 7aca2a5165 Ajout du tri du tableau de la litse des notes 4 years ago
Yanaël GRETTE 9bb818d684 Implémentation de la suppresion d'une note 4 years ago
Yanaël GRETTE 1771dc67c2 Mise à jour des interfaces de l'ajout d'une note et des détails d'une note 4 years ago
Yanaël GRETTE 9752339376 Ajout de la modification d'une note 4 years ago
Yanaël GRETTE e3896087fc Affichage des détails d'une note 4 years ago
Yanaël GRETTE 2f62e3bbf3 Fonctionnement complet de l'ajout d'une nouvelle note 4 years ago
Yanaël GRETTE f28b2d34e1 Création de l'interface pour ajouter une nouvelle note 4 years ago
Yanaël GRETTE 7427957e9c Affichage de la liste des notes prises par l'utilisateur connecté 4 years ago
Yanaël GRETTE 6406c624c3 Récupération des notes de l'utilisateur connecté sur la page 4 years ago
Yanaël GRETTE a7e47f98d2 Ajout du module notes 4 years ago
Yanaël GRETTE 667b55fcf9 Suppressions de colonnes non utiles dans la table des engagements 4 years ago
Yanaël GRETTE 7e30f21ded Possibilité d'accéder aux détails du collaborateur, du référent et de l'EP concernés par l'engagement 4 years ago
Yanaël GRETTE 6e404274c3 Ajout d'un popup permettant d'affiche les détails d'un engagement de le valider ou bien le refuser 4 years ago
Yanaël GRETTE 43aac7cbfc Affichage de la liste des engagements 4 years ago
Yanaël GRETTE b340fd26ff Ajout et affichage du module engagement 4 years ago
Yanaël GRETTE e7516a2188 Implémentation de la table des engagements 4 years ago
Yanaël GRETTE c2ed6550f9 Ajout d'un accès aux détails d'un collaborateur depuis la liste des référents EP d'un référent 4 years ago
Yanaël GRETTE 053a0419e1 Ajout de la possibilité de mettre à jour les collaborateurs EP d'un référent depuis ses détails 4 years ago
Yanaël GRETTE 954f1613ef Ajout de la possibilité de changer le référent EP d'un collaborateur depuis ses détails 4 years ago
Yanaël GRETTE 06d13b43f9 Affichage de la liste des collaborateurs d'un référent depuis ses détails 4 years ago
Yanaël GRETTE 122cbc8116 Affichage de la liste des collaborateurs d'un référent depuis ses détails 4 years ago
Yanaël GRETTE 76b666ccdc Suppression de l'utilisateur en sessionStorage au moment de la déconnexion 4 years ago
Yanaël GRETTE 0a9d17741c Mise à jour des détails d'un référent et des détails d'un collaborateur avec utilisation d'un composant réutilisable 4 years ago
Yanaël GRETTE 86bd26152b Ajout du ngOnDestroy dans le composant d'assignation du référentEP 4 years ago
Yanaël GRETTE 7855d4fcc5 Finalisation de la fonctionnalité de l'assignation du référent EP pour un ou plusieurs collaborateurs 4 years ago
Yanaël GRETTE 9a1d43fd54 implémentation de la récupération des collaborateurs dont le référent doit être mise à jour 4 years ago
Yanaël GRETTE 2b1e0123f2 Sélection du référent lors de l'assignation du référent 4 years ago
Yanaël GRETTE 7254fe0677 Ajout et affichage du composant step-choix-referent 4 years ago
Yanaël GRETTE 11d2676efd Ajout d'un stepper pour gérer les différentes étapes de l'assignation 4 years ago
Yanaël GRETTE f42748a5f9 Ajout d'un composant pour gérer l'assignation de référents EP aux collaborateurs 4 years ago
Yanaël GRETTE 4166a9edcf Ajout d'un module pour gérer les mat-table réutilisables avec mise à jour de code de la liste des référents 4 years ago
Yanaël GRETTE b62273401a Utilisation du composant pour faire afficher la liste des collaborateurs 4 years ago
Yanaël GRETTE de1cc0fe11 Début création d'un composant réutilisable qui affichera la liste des collaborateurs 4 years ago
Yanaël GRETTE 6049ad5431 Suppression du fichier global pour conserver le collaborateur connecte par un sessionstorage 4 years ago
Yanaël GRETTE 8d91f16b86 Passage à la version 11.1.4 d'Angular et mise à jour des packages 4 years ago
Yanaël GRETTE 940cdd8801 Mise à jour de l'affichage de la liste des référents avec un fonctionnement similaire que celui de la page de la liste des collaborateurs 4 years ago
Yanaël GRETTE ef2ed5a0b6 Aucune requête n'est faite si aucune checkbox n'est cochée 4 years ago
Yanaël GRETTE 765d2aca26 Ajout de commentaires manquants pour le fichier collaborateurs.component.ts 4 years ago
Yanaël GRETTE 4f8360db34 Fonctionnement du tri en fonction des en-têtes du tableau 4 years ago
Yanaël GRETTE a937aeaafc ouvert de la page du référent d'un collaborateur à partir de la liste des collaborateurs 4 years ago
Yanaël GRETTE f558516a1a Ajout de deux datepicker pour récupérer les collaborateurs en fonction de leur date d'arrivée dans l'entreprise 4 years ago
Yanaël GRETTE 0a70fb0dbb Mise à jour de l'interface de la liste des collaborateurs : ajout des checkboxes des BU et d'une barre de recherche 4 years ago
Yanaël GRETTE 35126aeec8 Ajout d'une variable globale pour stocker les informations de l'utilisateur connecté 4 years ago
Yanaël GRETTE 1692adaf42 Merge branch 'develop' of https://gitea.ci.apside-top.fr/ygrette/Digitalisation_EPA_Client into develop 4 years ago
Yanaël GRETTE 56539b4556 changements mineurs 4 years ago
Yanaël GRETTE 559af3456f Correction d'un problème de fichiers entre les DTO formation et participationFormation 4 years ago
Yanaël GRETTE 4441911026 Mise à jour des services de l'api swagger 4 years ago
Yanaël GRETTE 08326f07ac Mise à jour des modèles de l'api swagger 4 years ago
jboinembalome 087463e3ff MAJ des commentaires 4 years ago
jboinembalome 22520add64 Authentification uniquement en Code Flow 4 years ago
jboinembalome f14bad4e3e Début de la gestion des autorisations par role 4 years ago
jboinembalome 198d440f97 Suppression du fichier silent-refresh.html 4 years ago
jboinembalome 485d5f111d Déplacement du module d'authentification 4 years ago
Yanaël GRETTE cbd9232269 Correction d'un bug qui empêchait d'afficher la valeur actuelle du statut, de l'origine, du type et du mode d'une formation lors de la modification de cette dernière 4 years ago
Yanaël GRETTE 44072ac899 Merge branch 'develop' into pagination 4 years ago
Yanaël GRETTE e374063f7b Pagination effectuée avec un length en dur 4 years ago
jboinembalome c7a7e0e87d Modification des commentaires dans authModuleConfig 4 years ago
jboinembalome af75811436 Ajout du module d'authentification avec angular-oauth-oidc 4 years ago
Yanaël GRETTE 26557be67a Test de la communication avec le serveur pour les formations : Liste OK Détails OK Suppression OK Modification OK Ajout KO 4 years ago
Yanaël GRETTE ffbac86dfc Ajout des commentaires manquants 4 years ago
Yanaël GRETTE f6e2c6ab79 Mise à jour du module formation (liste, ajout, modification) avec un problème de binding dans la modification 4 years ago
Yanaël GRETTE cad23074d6 Mise à jour de l'affichage de la liste des référents et des détails d'un référent 4 years ago
Yanaël GRETTE d06122909a Mise à jour de l'affichage des détails d'un collaborateur 4 years ago
Yanaël GRETTE 8b04b1ae08 Mise à jour de l'affichage de la liste des collaborateurs 4 years ago
Yanaël GRETTE d7b947c956 Mise à jour du home RH 4 years ago
Yanaël GRETTE 03cecbed1e Mise à jour de l'API, des DTO et de l'affichage du home assistante 4 years ago
  1. 0
      .browserslistrc
  2. 8
      .dockerignore
  3. 1
      .gitignore
  4. 27
      Dockerfile
  5. 23
      angular.json
  6. 2
      e2e/tsconfig.json
  7. 36
      nginx.conf
  8. 35103
      package-lock.json
  9. 70
      package.json
  10. 54
      src/app/app-routing.module.ts
  11. 0
      src/app/app.component.scss
  12. 2
      src/app/app.component.spec.ts
  13. 31
      src/app/app.component.ts
  14. 76
      src/app/app.module.ts
  15. 131
      src/app/app.theme.scss
  16. 24
      src/app/collaborateurs/collaborateurs.component.html
  17. 98
      src/app/collaborateurs/collaborateurs.component.ts
  18. 21
      src/app/collaborateurs/collaborateurs.module.ts
  19. 24
      src/app/collaborateurs/collaborateurs.routing.module.ts
  20. 41
      src/app/collaborateurs/details-collaborateur/details-collaborateur.component.html
  21. 78
      src/app/collaborateurs/details-collaborateur/details-collaborateur.component.ts
  22. 3
      src/app/collaborateurs/formations-collaborateur/details-evaluation/evaluation.component.ts
  23. 3
      src/app/collaborateurs/formations-collaborateur/edit-evaluation/edit-evaluation.component.ts
  24. 3
      src/app/collaborateurs/formations-collaborateur/formations-collaborateur.component.ts
  25. 42
      src/app/commun/affichage-details-collaboarteur/affichage-details-collaborateur.html
  26. 22
      src/app/commun/affichage-details-collaboarteur/affichage-details-collaborateur.module.ts
  27. 88
      src/app/commun/affichage-details-collaboarteur/affichage-details-collaborateur.ts
  28. 17
      src/app/commun/affichage-details-collaboarteur/dialog-assignation-rapide/dialog-assignation-rapide-collaborateurs.html
  29. 8
      src/app/commun/affichage-details-collaboarteur/dialog-assignation-rapide/dialog-assignation-rapide-referent.html
  30. 169
      src/app/commun/affichage-details-collaboarteur/dialog-assignation-rapide/dialog-assignation-rapide.component.ts
  31. 31
      src/app/commun/affichage-details-collaboarteur/prochain-ep/prochain-ep.component.html
  32. 51
      src/app/commun/affichage-details-collaboarteur/prochain-ep/prochain-ep.component.ts
  33. 23
      src/app/commun/auth/auth-config.ts
  34. 13
      src/app/commun/auth/auth-module-config.ts
  35. 45
      src/app/commun/auth/auth.guard.ts
  36. 61
      src/app/commun/auth/auth.module.ts
  37. 6
      src/app/commun/auth/auth.service.spec.ts
  38. 222
      src/app/commun/auth/auth.service.ts
  39. 45
      src/app/commun/commun-api.module.ts
  40. 165
      src/app/commun/commun-ui.module.ts
  41. 0
      src/app/commun/config/configuration.ts
  42. 0
      src/app/commun/config/encoder.ts
  43. 3
      src/app/commun/config/variables.ts
  44. 14
      src/app/commun/filter/checkbox-filter/checkbox-filter.html
  45. 0
      src/app/commun/filter/checkbox-filter/checkbox-filter.scss
  46. 118
      src/app/commun/filter/checkbox-filter/checkbox-filter.ts
  47. 24
      src/app/commun/filter/filter.module.ts
  48. 11
      src/app/commun/filter/select-filter/select-filter.html
  49. 4
      src/app/commun/filter/select-filter/select-filter.scss
  50. 116
      src/app/commun/filter/select-filter/select-filter.ts
  51. 11
      src/app/commun/filter/selected-element.ts
  52. 85
      src/app/commun/mat-tables/collaborateurs-table/collaborateurs.table.html
  53. 7
      src/app/commun/mat-tables/collaborateurs-table/collaborateurs.table.scss
  54. 332
      src/app/commun/mat-tables/collaborateurs-table/collaborateurs.table.ts
  55. 144
      src/app/commun/mat-tables/demandes-formation-table/demandes-formation.table.html
  56. 0
      src/app/commun/mat-tables/demandes-formation-table/demandes-formation.table.scss
  57. 379
      src/app/commun/mat-tables/demandes-formation-table/demandes-formation.table.ts
  58. 80
      src/app/commun/mat-tables/engagements-table/engagements-table.html
  59. 0
      src/app/commun/mat-tables/engagements-table/engagements-table.scss
  60. 204
      src/app/commun/mat-tables/engagements-table/engagements-table.ts
  61. 135
      src/app/commun/mat-tables/ep-table/ep-table.html
  62. 0
      src/app/commun/mat-tables/ep-table/ep-table.scss
  63. 322
      src/app/commun/mat-tables/ep-table/ep-table.ts
  64. 84
      src/app/commun/mat-tables/formations-table/formations.table.html
  65. 0
      src/app/commun/mat-tables/formations-table/formations.table.scss
  66. 258
      src/app/commun/mat-tables/formations-table/formations.table.ts
  67. 71
      src/app/commun/mat-tables/participations-formation-table/participations-formation.table.html
  68. 0
      src/app/commun/mat-tables/participations-formation-table/participations-formation.table.scss
  69. 129
      src/app/commun/mat-tables/participations-formation-table/participations-formation.table.ts
  70. 37
      src/app/commun/model/affichageNoteDTO.ts
  71. 17
      src/app/commun/model/agenceDTO.ts
  72. 33
      src/app/commun/model/augmentationSalaireDTO.ts
  73. 24
      src/app/commun/model/businessUnitDTO.ts
  74. 41
      src/app/commun/model/champDTO.ts
  75. 44
      src/app/commun/model/collaborateurDTO.ts
  76. 30
      src/app/commun/model/commentaireAssistantDTO.ts
  77. 43
      src/app/commun/model/demandeDelegationDTO.ts
  78. 40
      src/app/commun/model/demandeEPIDTO.ts
  79. 55
      src/app/commun/model/demandeFormationDTO.ts
  80. 43
      src/app/commun/model/detailsNoteDTO.ts
  81. 25
      src/app/commun/model/documentDTO.ts
  82. 45
      src/app/commun/model/engagementDTO.ts
  83. 81
      src/app/commun/model/epDTO.ts
  84. 40
      src/app/commun/model/epInformationDTO.ts
  85. 51
      src/app/commun/model/epSaisieDTO.ts
  86. 15
      src/app/commun/model/erreurDTO.ts
  87. 44
      src/app/commun/model/etatDemande.ts
  88. 36
      src/app/commun/model/etatEngagement.ts
  89. 35
      src/app/commun/model/evaluationDTO.ts
  90. 67
      src/app/commun/model/formationDTO.ts
  91. 49
      src/app/commun/model/formationDetailsDTO.ts
  92. 17
      src/app/commun/model/modeFormationDTO.ts
  93. 41
      src/app/commun/model/models.ts
  94. 17
      src/app/commun/model/objectifDTO.ts
  95. 31
      src/app/commun/model/objectifPrecedentDTO.ts
  96. 25
      src/app/commun/model/origineDemandeFormationDTO.ts
  97. 25
      src/app/commun/model/origineFormationDTO.ts
  98. 33
      src/app/commun/model/participationEPDTO.ts
  99. 43
      src/app/commun/model/participationFormationDTO.ts
  100. 35
      src/app/commun/model/prochainEPDTO.ts
  101. Some files were not shown because too many files have changed in this diff Show More

@ -0,0 +1,8 @@
.git
.editorconfig
/.vscode/*
/node_modules
/e2e
/docs
.gitignore
*.zip

1
.gitignore vendored

@ -30,6 +30,7 @@ speed-measure-plugin*.json
!.vscode/launch.json !.vscode/launch.json
!.vscode/extensions.json !.vscode/extensions.json
.history/* .history/*
.vs/*
# misc # misc
/.sass-cache /.sass-cache

@ -0,0 +1,27 @@
## STEP 1 BUILD ##
FROM node:16.13-alpine AS build
RUN mkdir -p /app
WORKDIR /app
RUN npm cache clean --force
COPY package*.json /app
RUN npm install
COPY . /app
RUN npm run build --prod
## STEP 2 DEPLOY ##
FROM nginx:1.21.3 AS ngi
COPY --from=build /app/dist/EPAClient /usr/share/nginx/html
COPY /nginx.conf /etc/nginx/conf.d/default.conf
COPY /nginx.conf /etc/nginx/nginx.conf
EXPOSE 4200
CMD ["nginx", "-g", "daemon off;"]

@ -18,16 +18,20 @@
"main": "src/main.ts", "main": "src/main.ts",
"polyfills": "src/polyfills.ts", "polyfills": "src/polyfills.ts",
"tsConfig": "tsconfig.app.json", "tsConfig": "tsconfig.app.json",
"aot": true,
"assets": [ "assets": [
"src/favicon.ico", "src/favicon.ico",
"src/assets" "src/assets"
], ],
"styles": [ "styles": [
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", "src/styles.scss"
"src/styles.css"
], ],
"scripts": [] "scripts": [],
"vendorChunk": true,
"extractLicenses": false,
"buildOptimizer": false,
"sourceMap": true,
"optimization": false,
"namedChunks": true
}, },
"configurations": { "configurations": {
"production": { "production": {
@ -40,7 +44,6 @@
"optimization": true, "optimization": true,
"outputHashing": "all", "outputHashing": "all",
"sourceMap": false, "sourceMap": false,
"extractCss": true,
"namedChunks": false, "namedChunks": false,
"extractLicenses": true, "extractLicenses": true,
"vendorChunk": false, "vendorChunk": false,
@ -58,7 +61,8 @@
} }
] ]
} }
} },
"defaultConfiguration": ""
}, },
"serve": { "serve": {
"builder": "@angular-devkit/build-angular:dev-server", "builder": "@angular-devkit/build-angular:dev-server",
@ -90,7 +94,7 @@
], ],
"styles": [ "styles": [
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css", "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
"src/styles.css" "src/styles.scss"
], ],
"scripts": [] "scripts": []
} }
@ -123,5 +127,10 @@
} }
} }
}, },
"schematics": {
"@schematics/angular:application": {
"strict": true
}
},
"defaultProject": "EPAClient" "defaultProject": "EPAClient"
} }

@ -3,7 +3,7 @@
"compilerOptions": { "compilerOptions": {
"outDir": "../out-tsc/e2e", "outDir": "../out-tsc/e2e",
"module": "commonjs", "module": "commonjs",
"target": "es5", "target": "es2018",
"types": [ "types": [
"jasmine", "jasmine",
"jasminewd2", "jasminewd2",

@ -0,0 +1,36 @@
worker_processes auto;
events { worker_connections 1024; }
http {
server {
listen 4200;
server_name digitepa_front;
#ssl_certificate /etc/nginx/ssl/www.epa.apside.com.crt;
#ssl_certificate_key /etc/nginx/ssl/www.epa.apside.com.key;
include /etc/nginx/mime.types;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://digitepa_keycloak:8080/;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_buffering off;
proxy_set_header Accept-Encoding "";
}
location /auth {
proxy_pass http://digitepa_back:44393/;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_buffering off;
proxy_set_header Accept-Encoding "";
}
}
}

35103
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -3,51 +3,51 @@
"version": "0.0.0", "version": "0.0.0",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "ng serve", "start": "ng serve --Host 0.0.0.0 --poll",
"build": "ng build", "build": "ng build",
"build-prod": "ng build --configuration production",
"test": "ng test", "test": "ng test",
"lint": "ng lint", "lint": "ng lint",
"e2e": "ng e2e", "e2e": "ng e2e",
"compodoc": "./node_modules/.bin/compodoc -p tsconfig.json" "compodoc": "npx compodoc -p tsconfig.compodoc.json src"
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular-material-components/datetime-picker": "^2.0.4", "@angular-material-components/datetime-picker": "^6.0.3",
"@angular/animations": "~9.1.9", "@angular/animations": "~12.2.12",
"@angular/cdk": "^9.2.4", "@angular/cdk": "^12.2.12",
"@angular/common": "~9.1.9", "@angular/common": "~12.2.12",
"@angular/compiler": "~9.1.9", "@angular/compiler": "~12.2.12",
"@angular/core": "~9.1.9", "@angular/core": "~12.2.12",
"@angular/forms": "~9.1.9", "@angular/forms": "~12.2.12",
"@angular/material": "^9.2.4", "@angular/material": "^12.2.12",
"@angular/platform-browser": "~9.1.9", "@angular/platform-browser": "~12.2.12",
"@angular/platform-browser-dynamic": "~9.1.9", "@angular/platform-browser-dynamic": "~12.2.12",
"@angular/router": "~9.1.9", "@angular/router": "~12.2.12",
"keycloak-angular": "^7.3.1", "angular-oauth2-oidc": "^10.0.3",
"keycloak-js": "^10.0.2", "rxjs": "~6.6.3",
"rxjs": "~6.5.4", "tslib": "^2.3.1",
"tslib": "^1.10.0", "zone.js": "~0.11.4"
"zone.js": "~0.10.2"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "~0.901.7", "@angular-devkit/build-angular": "~12.2.12",
"@angular/cli": "~9.1.7", "@angular/cli": "~12.2.12",
"@angular/compiler-cli": "~9.1.9", "@angular/compiler-cli": "~12.2.12",
"@compodoc/compodoc": "^1.1.11", "@compodoc/compodoc": "^1.1.15",
"@types/jasmine": "~3.5.0", "@types/jasmine": "~3.6.3",
"@types/jasminewd2": "~2.0.3", "@types/jasminewd2": "~2.0.8",
"@types/node": "^12.11.1", "@types/node": "^14.14.25",
"codelyzer": "^5.1.2", "codelyzer": "^6.0.1",
"jasmine-core": "~3.5.0", "jasmine-core": "~3.10.1",
"jasmine-spec-reporter": "~4.2.1", "jasmine-spec-reporter": "~6.0.0",
"karma": "~5.0.0", "karma": "~6.3.7",
"karma-chrome-launcher": "~3.1.0", "karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~2.1.0", "karma-coverage-istanbul-reporter": "~3.0.3",
"karma-jasmine": "~3.0.1", "karma-jasmine": "~4.0.1",
"karma-jasmine-html-reporter": "^1.4.2", "karma-jasmine-html-reporter": "^1.5.4",
"protractor": "~7.0.0", "protractor": "~7.0.0",
"ts-node": "~8.3.0", "ts-node": "~9.1.1",
"tslint": "~6.1.0", "tslint": "^6.1.3",
"typescript": "~3.8.3" "typescript": "~4.3.5"
} }
} }

@ -2,59 +2,81 @@ import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { Routes } from '@angular/router'; import { Routes } from '@angular/router';
import { AuthGuard } from './commun/auth/auth.guard';
import { paths_collaborateurs, paths_demandes_delegation, paths_demandes_formation, paths_ep, paths_saisie_ep, paths_formation, paths_referents, paths_engagements, paths_notes, paths_home } from './commun/utils/paths';
import { Role } from './commun/utils/roles';
import { HomeComponent } from './home/'; import { HomeComponent } from './home/';
import { KeycloakGuard } from '@shared/guards/keycloakguard';
import { paths_collaborateurs, paths_demandes_delegation, paths_demandes_formation,
paths_ep, paths_saisie_ep, paths_formation, paths_home, paths_referents } from '@shared/utils/paths';
/**
* L'ensemble des routes du client Angular
*/
const routes: Routes = [ const routes: Routes = [
{ //chargement des chemins du module collaborateur à partir du routing de ce module
path: '',
redirectTo: paths_home.path,
pathMatch: 'full'
},
{
path: paths_home.path,
component: HomeComponent,
canActivate: [KeycloakGuard],
pathMatch: 'full'
},
{ {
path: paths_collaborateurs.path, path: paths_collaborateurs.path,
loadChildren: () => import('./collaborateurs/collaborateurs.module').then(m=> m.CollaborateursModule) loadChildren: () => import('./collaborateurs/collaborateurs.module').then(m=> m.CollaborateursModule)
}, },
//chargement des chemins du module demandes délégation à partir du routing de ce module
{ {
path: paths_demandes_delegation.path, path: paths_demandes_delegation.path,
loadChildren: () => import('./demandes-delegation/demandes-delegation.module').then(m=> m.DemandesDelegationModule) loadChildren: () => import('./demandes-delegation/demandes-delegation.module').then(m=> m.DemandesDelegationModule)
}, },
//chargement des chemins du module demandes de formation à partir du routing de ce module
{ {
path: paths_demandes_formation.path, path: paths_demandes_formation.path,
loadChildren: () => import('./demandes-formation/demandes-formation.module').then(m=> m.DemandesFormationModule) loadChildren: () => import('./demandes-formation/demandes-formation.module').then(m=> m.DemandesFormationModule)
}, },
//chargement des chemins du module ep à partir du routing de ce module
{ {
path: paths_ep.path, path: paths_ep.path,
loadChildren: () => import('./ep/ep.module').then(m=> m.EpModule) loadChildren: () => import('./ep/ep.module').then(m=> m.EpModule)
}, },
//chargement des chemins du module saisie ep à partir du routing de ce module
{ {
path: paths_saisie_ep.path, path: paths_saisie_ep.path,
loadChildren: () => import('./ep-saisie/ep-saisie.module').then(m=> m.EpSaisieModule) loadChildren: () => import('./ep-saisie/ep-saisie.module').then(m=> m.EpSaisieModule)
}, },
//chargement des chemins du module formation à partir du routing de ce module
{ {
path: paths_formation.path, path: paths_formation.path,
loadChildren: () => import('./formations/formations.module').then(m=> m.FormationsModule) loadChildren: () => import('./formations/formations.module').then(m=> m.FormationsModule)
}, },
//chargement des chemins du module référent à partir du routing de ce module
{ {
path: paths_referents.path, path: paths_referents.path,
loadChildren: () => import('./referents/referents.module').then(m=> m.ReferentsModule) loadChildren: () => import('./referents/referents.module').then(m=> m.ReferentsModule)
},
//chargement des chemin du module engagement à partir du routing de ce module
{
path: paths_engagements.path,
loadChildren: () => import('./engagements/engagements.module').then(m => m.EngagementsModule)
},
{
path: paths_notes.path,
loadChildren: () => import('./notes/notes.module').then( m => m.NotesModule)
},
//Chemin du home
{
path: paths_home.path,
component: HomeComponent,
canActivate: [AuthGuard],
data: { roles: [Role.assistante, Role.commercial, Role.rh, Role.collaborateur] },
pathMatch: 'full'
},
//Redirection vers le home pour "/"
{
path: '',
redirectTo: paths_home.path,
pathMatch: 'full'
} }
]; ];
@NgModule({ @NgModule({
imports: [RouterModule.forRoot(routes)], imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],
exports: [RouterModule], exports: [RouterModule],
providers: [KeycloakGuard] providers: [AuthGuard]
}) })
export class AppRoutingModule {} export class AppRoutingModule {}

@ -1,4 +1,4 @@
import { TestBed, async } from '@angular/core/testing'; import { TestBed, waitForAsync } from '@angular/core/testing';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
/* /*

@ -1,14 +1,37 @@
import { Component } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { AuthService } from './commun/auth/auth.service';
import { CollaborateursService } from './commun/services/collaborateurs.service';
import { cles } from './commun/utils/cles';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
templateUrl: './app.component.html', templateUrl: './app.component.html',
styleUrls: ['./app.component.css'] styleUrls: ['./app.component.scss']
}) })
export class AppComponent {
export class AppComponent implements OnInit {
title = 'EPAClient'; title = 'EPAClient';
constructor() { subscriber: Subscription;
constructor(private collaborateursService: CollaborateursService,
private authService: AuthService ) {
}
ngOnInit(): void {
if(sessionStorage.getItem(cles.sessionKeyConnectee) == undefined) {
this.subscriber = this.collaborateursService.getCollaborateurByMail(this.authService.mail).subscribe(
collaborateur => sessionStorage.setItem(cles.sessionKeyConnectee, JSON.stringify(collaborateur))
);
}
}
ngOnDestroy(): void {
if(this.subscriber != undefined)
this.subscriber.unsubscribe();
} }
} }

@ -1,9 +1,7 @@
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule, DoBootstrap } from '@angular/core'; import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { KeycloakAngularModule, KeycloakService } from 'keycloak-angular';
import { RouterModule } from '@angular/router';
import { registerLocaleData } from '@angular/common'; import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr'; import localeFr from '@angular/common/locales/fr';
@ -13,58 +11,52 @@ registerLocaleData(localeFr, 'fr');
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { ApiModule } from '@shared/api-swagger'
import { HomeModule } from './home';
import { CollaborateursModule } from './collaborateurs'; import { CollaborateursModule } from './collaborateurs';
import { ReferentsModule } from './referents';
import { FormationsModule } from './formations';
import { DemandesFormationModule } from './demandes-formation';
import { DemandesDelegationModule } from './demandes-delegation';
import { EpSaisieModule } from "./ep-saisie";
import { EpModule } from "./ep"
import { environment } from '@env'; import { CommunUiModule } from './commun/commun-ui.module';
import { AuthModule } from './commun/auth/auth.module';
import { CommunApiModule } from './commun/commun-api.module';
import { CollaborateursService } from './commun/services/collaborateurs.service';
import { DemandesDelegationService } from './commun/services/demandesDelegation.service';
import { DemandesEPIService } from './commun/services/demandesEPI.service';
import { DemandesFormationService } from './commun/services/demandesformation.service';
import { EngagementsService } from './commun/services/engagements.service';
import { EpService } from './commun/services/ep.service';
import { FormationsService } from './commun/services/formations.service';
import { NotesService } from './commun/services/notes.service';
import { ParticipationsFormationsService } from './commun/services/participationsFormations.service';
import { ReferentsEPService } from './commun/services/referentsEP.service';
/**
* constante Keycloak qui pourra être utilisé dans tout le projet.
*/
let keycloakService: KeycloakService = new KeycloakService();
@NgModule({ @NgModule({
declarations: [ declarations: [
AppComponent AppComponent
], ],
imports: [ imports: [
BrowserModule, BrowserAnimationsModule, BrowserModule,
KeycloakAngularModule, AppRoutingModule, BrowserAnimationsModule,
HttpClientModule, ApiModule, AppRoutingModule,
HomeModule, CollaborateursModule, HttpClientModule,
ReferentsModule, FormationsModule, CollaborateursModule,
DemandesFormationModule, DemandesDelegationModule, CommunApiModule,
EpSaisieModule CommunUiModule,
AuthModule.forRoot()
], ],
providers: [ providers: [
{ CollaborateursService,
provide: KeycloakService, DemandesDelegationService,
useValue: keycloakService DemandesEPIService,
} DemandesFormationService,
EngagementsService,
EpService,
FormationsService,
NotesService,
ParticipationsFormationsService,
ReferentsEPService
], ],
entryComponents: [AppComponent] bootstrap: [AppComponent]
}) })
export class AppModule implements DoBootstrap { export class AppModule {
async ngDoBootstrap(app) {
const { keycloakConfig } = environment;
try {
await keycloakService.init({ config: keycloakConfig });
app.bootstrap(AppComponent);
} catch (error) {
console.error('Keycloak init failed', error);
}
}
} }

@ -0,0 +1,131 @@
// -----------------------------------------------------------------------------------------------------
@use '~@angular/material' as mat;
// @ Custom color maps
// -----------------------------------------------------------------------------------------------------
$black-87-opacity: rgba(black, 0.87);
$white-87-opacity: rgba(white, 0.87);
$navy-app-theme: (
50: #ECECEE,
100: #C5C6CB,
200: #9EA1A9,
300: #7D818C,
400: #5C616F,
500: #E89759,
600: #353A48,
700: #2D323E,
800: #262933,
900: #1E2129,
A100: #C5C6CB,
A200: #9EA1A9,
A400: #5C616F,
A700: #2D323E,
contrast: (
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: white,
500: white,
600: $white-87-opacity,
700: $white-87-opacity,
800: $white-87-opacity,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: white,
A700: $white-87-opacity,
)
);
$apside-primary-app-theme: (
50: #ECECEE,
100: #C5C6CB,
200: #9EA1A9,
300: #7D818C,
400: #5C616F,
500: #E89759,
600: #353A48,
700: #2D323E,
800: #262933,
900: #1E2129,
A100: #C5C6CB,
A200: #9EA1A9,
A400: #5C616F,
A700: #2D323E,
contrast: (
0: $black-87-opacity,
50: $black-87-opacity,
100: $black-87-opacity,
200: $black-87-opacity,
300: $black-87-opacity,
400: $black-87-opacity,
500: $black-87-opacity,
600: $white-87-opacity,
700: $white-87-opacity,
800: $white-87-opacity,
900: $white-87-opacity,
A100: $black-87-opacity,
A200: $black-87-opacity,
A400: $black-87-opacity,
A700: $white-87-opacity,
)
);
// -----------------------------------------------------------------------------------------------------
// @ Define the default theme
// -----------------------------------------------------------------------------------------------------
// Define the primary, accent and warn palettes
$default-primary-palette: mat.define-palette($navy-app-theme);
$default-accent-palette: mat.define-palette(mat.$light-blue-palette, 600, 400, 700);
$default-warn-palette: mat.define-palette(mat.$red-palette);
// Create the Material theme object
$theme: mat.define-light-theme($default-primary-palette, $default-accent-palette, $default-warn-palette);
// Add ".theme-default" class to the body to activate this theme.
// Class name must start with "theme-" !!!
.theme-default {
// Create an Angular Material theme from the $theme map
@include mat.all-component-themes($theme);
}
// -----------------------------------------------------------------------------------------------------
// @ Define a blue-gray dark theme
// -----------------------------------------------------------------------------------------------------
// Define the primary, accent and warn palettes
$blue-gray-dark-theme-primary-palette: mat.define-palette($navy-app-theme);
$blue-gray-dark-theme-accent-palette: mat.define-palette(mat.$blue-gray-palette);
$blue-gray-dark-theme-warn-palette: mat.define-palette(mat.$red-palette);
// Create the Material theme object
$blue-gray-dark-theme: mat.define-dark-theme($blue-gray-dark-theme-primary-palette, $blue-gray-dark-theme-accent-palette, $blue-gray-dark-theme-warn-palette);
// Add ".theme-blue-gray-dark" class to the body to activate this theme.
// Class name must start with "theme-" !!!
.theme-blue-gray-dark {
// Generate the Angular Material theme
@include mat.all-component-themes($blue-gray-dark-theme);
}
// -----------------------------------------------------------------------------------------------------
// @ Typography
// -----------------------------------------------------------------------------------------------------
// Angular Material typography
$typography: mat.define-typography-config(
$font-family: 'Muli, Helvetica Neue, Arial, sans-serif',
$title: mat.define-typography-level(20px, 32px, 600),
$body-2: mat.define-typography-level(14px, 24px, 600),
$button: mat.define-typography-level(14px, 14px, 600),
$input: mat.define-typography-level(16px, 1.125, 400) // line-height must be unitless !!!
);
// Setup the typography
@include mat.all-component-typographies($typography);

@ -1,27 +1,5 @@
<app-nav-menu></app-nav-menu> <app-nav-menu></app-nav-menu>
<h1> Liste des collaborateurs </h1> <h1> Liste des collaborateurs </h1>
<mat-table matSort [dataSource]="dataSource">
<ng-container matColumnDef="agence">
<mat-header-cell *matHeaderCellDef mat-sort-header>Agence</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.agence}}</mat-cell>
</ng-container>
<ng-container matColumnDef="collaborateur"> <collaborateurs-table [typeRecherche]="typeRecherche" [rechercherParBU]="rechercherParBU" [roles]="roles" [displayedColumns]="displayedColumns" (eventEmitter)="event($event)" ></collaborateurs-table>
<mat-header-cell *matHeaderCellDef mat-sort-header>Collabotareur</mat-header-cell>
<mat-cell *matCellDef="let row" [routerLink]="['/collaborateurs', row.id]">{{row.prenom}} {{row.nom}}</mat-cell>
</ng-container>
<ng-container matColumnDef="dateembauche">
<mat-header-cell *matHeaderCellDef mat-sort-header>Date embauche</mat-header-cell>
<mat-cell *matCellDef="let row">TODO AUSSI</mat-cell>
</ng-container>
<ng-container matColumnDef="referent">
<mat-header-cell *matHeaderCellDef mat-sort-header>Référent</mat-header-cell>
<mat-cell *matCellDef="let row">TODO</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>

@ -1,95 +1,53 @@
import { Component, OnInit, OnDestroy, ViewChild, ViewChildren } from '@angular/core'; import { Component } from '@angular/core';
import { Observable, Subscription } from 'rxjs'; import { Router } from '@angular/router';
import { collaborateurTypeRecherche } from 'app/commun/utils/cles';
import {MatTableDataSource} from '@angular/material/table';
import {MatPaginator} from '@angular/material/paginator';
import {MatSort} from '@angular/material/sort';
import { CollaborateursService } from "@shared/api-swagger/api/api";
import { CollaborateurModel } from "@shared/api-swagger/model/models";
import { DisplayCollaborateur } from "@shared/displayInfo/displays";
/** /**
* Composant qui sert à l'affichage de la liste des collaborateurs en fonction de l'agence de son utilitateur. * Composant qui sert à l'affichage de la liste des collaborateurs en fonction de l'agence de son utilitateur.
* Seuls les commerciaux, RH et assistantes pourront accéder à la liste des collaborateurs.
* Les données affichées : Agence-Nom Prénom-Date Embauche-Responsable Commercial-Date Prochain EP
*/ */
@Component({ @Component({
selector: 'app-collaborateurs', selector: 'app-collaborateurs',
templateUrl: './collaborateurs.component.html' templateUrl: './collaborateurs.component.html'
}) })
export class CollaborateursComponent implements OnInit { export class CollaborateursComponent {
collaborateursDisponibles : DisplayCollaborateur[];
collaborateursFiltre : DisplayCollaborateur[];
private collaborateursDisponiblesSubscription : Subscription;
displayedColumns : string[] = ["agence", "collaborateur", "dateembauche", "referent"];
dataSource : MatTableDataSource<DisplayCollaborateur>;
/** /**
* contenu de la recherche. * Type de la recherche à indiquer au composant fils qui affiche la liste des collaborateurs
*/ */
search = ""; typeRecherche: string = collaborateurTypeRecherche.collaborateurs;
/** /**
* Pagination du tableau. * Rôle des collaborateurs à récupérer via le service collaborateur, ici nous ne voulons que les collaborateurs (pour le moment...).
*/ */
@ViewChild(MatPaginator) paginator: MatPaginator; roles: string[] = ["Collaborateur"];
/** /**
* Tri par les éléments du tableau selon la colonne choisie. * Liste des colonnes du tableau à afficher.
*/ */
@ViewChild(MatSort) sort: MatSort; displayedColumns: string[] = ["businessunit", "collaborateur", "datearrivee", "referent"];
/** /**
* Spécifie si la liste des EP est en cours de chargement et d'écriture dans le tableau. * Indique si la recherche pas BU est activée ou non
*/ */
chargement = true; rechercherParBU: boolean = true;
constructor(private service: CollaborateursService) {}
ngOnInit() { constructor(private router: Router) {}
this. collaborateursDisponiblesSubscription = this.service.getCollaborateurs(undefined,undefined,undefined,1).subscribe(
collaborateurs => {
this.initCollaborateur(collaborateurs)
}
);
}
initCollaborateur(collaborateurs:CollaborateurModel[]) { /**
this.collaborateursDisponibles = []; * Fonction permettant d'ouvrir les détails d'un référent ou d'un collaborateur en fonction de la case cliquée
let collaborateurDisplay : DisplayCollaborateur; *
let today = new Date(); * @param event Evènement reçu par le composant enfant, contient le type du collaborateur reçu (référent, collaborateur) et les données collaborateur
console.log(collaborateurs); */
for(let c of collaborateurs) { event(event : any) {
collaborateurDisplay = new DisplayCollaborateur(); switch(event.type) {
collaborateurDisplay.id = c.id; case "collaborateur":
collaborateurDisplay.prenom = c.prenom; this.router.navigate(["/collaborateurs", event.collaborateur.id]);
collaborateurDisplay.nom = c.nom; break;
collaborateurDisplay.agence = c.businessUnit.nom; case "referent":
collaborateurDisplay.embauche = c.dateArrivee; this.router.navigate(["/referents", event.collaborateur.id]);
collaborateurDisplay.anciennete = this.setAnciennete(new Date(c.dateArrivee), today); break;
collaborateurDisplay.annee = Math.floor(collaborateurDisplay.anciennete / 31536000000);
collaborateurDisplay.mois = Math.floor(collaborateurDisplay.anciennete / 2629800000 % 12);
this.collaborateursDisponibles.push(collaborateurDisplay);
} }
this.collaborateursFiltre = this.collaborateursDisponibles;
this.dataSource = new MatTableDataSource(this.collaborateursFiltre);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
} }
setAnciennete(firstDate, secondDate) {
return Math.abs(firstDate-secondDate);
}
ngOnDestroy() {
if(this.collaborateursDisponiblesSubscription != undefined) {
this.collaborateursDisponiblesSubscription.unsubscribe();
}
}
} }

@ -1,25 +1,27 @@
import { NgModule } from "@angular/core"; import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common"; import { CommonModule } from "@angular/common";
import { FormsModule } from '@angular/forms'; import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import { MaterialModule } from "@shared/angular-material/angular-material.module";
import {NavMenuModule} from '@shared/nav-menu/nav-menu.module';
import { CollaborateursComponent } from "./collaborateurs.component"; import { CollaborateursComponent } from "./collaborateurs.component";
import { DetailsCollaborateurComponent } from "./details-collaborateur/details-collaborateur.component"; import { DetailsCollaborateurComponent } from "./details-collaborateur/details-collaborateur.component";
import { EvaluationComponent } from "./formations-collaborateur/details-evaluation/evaluation.component"; import { EvaluationComponent } from "./formations-collaborateur/details-evaluation/evaluation.component";
import { EditEvaluationComponent } from "./formations-collaborateur/edit-evaluation/edit-evaluation.component"; import { EditEvaluationComponent } from "./formations-collaborateur/edit-evaluation/edit-evaluation.component";
import { FormationsCollaboateurComponent } from "./formations-collaborateur/formations-collaborateur.component"; import { FormationsCollaboateurComponent } from "./formations-collaborateur/formations-collaborateur.component";
import { CollaborateursRoutingModule } from "./collaborateurs.routing.module"; import { CollaborateursRoutingModule } from "./collaborateurs.routing.module";
import { CommunUiModule } from "app/commun/commun-ui.module";
@NgModule({ @NgModule({
declarations: [ declarations: [
DetailsCollaborateurComponent, EvaluationComponent, EditEvaluationComponent, CollaborateursComponent,
CollaborateursComponent, FormationsCollaboateurComponent DetailsCollaborateurComponent,
DetailsCollaborateurComponent,
EvaluationComponent,
EditEvaluationComponent,
FormationsCollaboateurComponent
], ],
exports: [ exports: [
CollaborateursComponent CollaborateursComponent
@ -27,8 +29,9 @@ import { CollaborateursRoutingModule } from "./collaborateurs.routing.module";
imports: [ imports: [
//FormsModule, //FormsModule,
CommonModule, CommonModule,
MaterialModule, CommunUiModule,
NavMenuModule, FormsModule,
ReactiveFormsModule,
CollaborateursRoutingModule, CollaborateursRoutingModule,
RouterModule RouterModule
], ],

@ -1,24 +1,28 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { CollaborateursComponent } from "./collaborateurs.component"; import { CollaborateursComponent } from "./collaborateurs.component";
import { DetailsCollaborateurComponent } from "./details-collaborateur/details-collaborateur.component"; import { DetailsCollaborateurComponent } from "./details-collaborateur/details-collaborateur.component";
import { FormationsCollaboateurComponent } from "./formations-collaborateur/formations-collaborateur.component"; import { FormationsCollaboateurComponent } from "./formations-collaborateur/formations-collaborateur.component";
import { EvaluationComponent } from './formations-collaborateur/details-evaluation/evaluation.component'; import { EvaluationComponent } from './formations-collaborateur/details-evaluation/evaluation.component';
import { EditEvaluationComponent } from './formations-collaborateur/edit-evaluation/edit-evaluation.component'; import { EditEvaluationComponent } from './formations-collaborateur/edit-evaluation/edit-evaluation.component';
import { AuthGuard } from 'app/commun/auth/auth.guard';
import { paths_collaborateurs } from '@shared/utils/paths'; import { paths_collaborateurs } from 'app/commun/utils/paths';
import { Role } from 'app/commun/utils/roles';
import { KeycloakGuard } from '@shared/guards/keycloakguard';
const routes: Routes = [ const routes: Routes = [
{ path:'', component: CollaborateursComponent, pathMatch: 'full', canActivate: [KeycloakGuard] }, { path:paths_collaborateurs.formations, component: FormationsCollaboateurComponent, canActivate: [AuthGuard] },
{ path:paths_collaborateurs.formations, component: FormationsCollaboateurComponent, canActivate: [KeycloakGuard] }, { path:paths_collaborateurs.evaluation, component: EvaluationComponent, canActivate: [AuthGuard] },
{ path:paths_collaborateurs.evaluation, component: EvaluationComponent, canActivate: [KeycloakGuard] }, { path:paths_collaborateurs.edit, component: EditEvaluationComponent, canActivate: [AuthGuard] },
{ path:paths_collaborateurs.edit, component: EditEvaluationComponent, canActivate: [KeycloakGuard] }, { path:paths_collaborateurs.get, component: DetailsCollaborateurComponent, canActivate: [AuthGuard] },
{ path:paths_collaborateurs.get, component: DetailsCollaborateurComponent, canActivate: [KeycloakGuard] } {
path:'',
component: CollaborateursComponent,
canActivate: [AuthGuard],
data: { roles: [Role.assistante, Role.commercial, Role.rh] },
pathMatch: 'full'
}
]; ];

@ -1,42 +1,3 @@
<app-nav-menu></app-nav-menu> <app-nav-menu></app-nav-menu>
<ng-container *ngIf="collaborateur!=undefined">
<h2>{{ collaborateur.prenom }} {{ collaborateur.nom }} </h2>
<h3>Agence : {{ collaborateur.businessUnit.nom}}</h3> <affichage-details-collaborateur [idCollaborateur]="idCollaborateur"></affichage-details-collaborateur>
<h3>Date embauche : {{ collaborateur.dateArrivee}}</h3>
</ng-container>
<ng-container *ngIf="collaborateur==undefined || !eploaded">
<mat-spinner></mat-spinner>
</ng-container>
<ng-container *ngIf= "eploaded && epEffectues.length==0">
<h3> Aucun EP effectué encore </h3>
</ng-container>
<ng-container *ngIf= "eploaded && epEffectues.length!=0">
<h3>Liste des précédents EP</h3>
<mat-table [dataSource]="this.dataSource" matSort>
<ng-container matColumnDef="dateentretien">
<mat-header-cell *matHeaderCellDef mat-sort-header>Date entretient</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.dateentretien}}</mat-cell>
</ng-container>
<ng-container matColumnDef="referent">
<mat-header-cell *matHeaderCellDef mat-sort-header>Référent</mat-header-cell>
<mat-cell *matCellDef="let row"> {{ row.referent.prenom }} {{ row.referent.nom }}</mat-cell>
</ng-container>
<ng-container matColumnDef="type">
<mat-header-cell *matHeaderCellDef mat-sort-header>Type</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.type}}</mat-cell>
</ng-container>
<ng-container matColumnDef="details">
<mat-header-cell *matHeaderCellDef mat-sort-header></mat-header-cell>
<mat-cell *matCellDef="let row" [routerLink]="['/ep',row.id]"> Voir détails EP </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
</ng-container>

@ -1,86 +1,20 @@
import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core'; import { Component } from '@angular/core';
import { Observable, Subscription } from 'rxjs';
import {ActivatedRoute} from '@angular/router'; import {ActivatedRoute} from '@angular/router';
import {MatTableDataSource} from '@angular/material/table';
import {MatPaginator} from '@angular/material/paginator';
import {MatSort} from '@angular/material/sort';
import { CollaborateursService, EpService } from "@shared/api-swagger/api/api";
import { CollaborateurModel } from "@shared/api-swagger/model/collaborateurModel";
import { EpModel } from "@shared/api-swagger/model/epModel";
import { DisplayEP } from "@shared/displayInfo/displays";
/** /**
*/ * Composant pour gérer l'affichage des détails d'un collaborateur avec ses formations et ses EP
*/
@Component({ @Component({
selector: 'app-details-collaborateur', selector: 'app-details-collaborateur',
templateUrl: './details-collaborateur.component.html' templateUrl: './details-collaborateur.component.html'
}) })
export class DetailsCollaborateurComponent implements OnInit { export class DetailsCollaborateurComponent {
//epCollaborateurIdCollaborateurGet
collaborateur: CollaborateurModel;
private collaborateurSubscription : Subscription;
private epSubscription : Subscription;
epEffectues : DisplayEP[];
displayedColumns: string[] = ["dateentretien", "referent", "type", "details"];
dataSource : MatTableDataSource<DisplayEP>;
eploaded = false;
idCollaborateur: any;
/**
* Pagination du tableau.
*/
@ViewChild(MatPaginator) paginator: MatPaginator;
/** idCollaborateur: string;
* Tri par les éléments du tableau selon la colonne choisie.
*/
@ViewChild(MatSort) sort: MatSort;
constructor(private collaborateusrService:CollaborateursService, private epService:EpService, private route: ActivatedRoute) {} constructor(private route: ActivatedRoute) {
ngOnInit() {
this.idCollaborateur = this.route.snapshot.paramMap.get('id'); this.idCollaborateur = this.route.snapshot.paramMap.get('id');
this.collaborateurSubscription = this.collaborateusrService.getCollaborateurById(this.idCollaborateur).subscribe(
collaborateur => this.initCollaborateur(collaborateur[0]),
err => console.log(err)
);
}
initCollaborateur(collaborateur:CollaborateurModel) {
this.collaborateur = collaborateur;
this.epSubscription = this.epService.getEPByCollaborateur(this.idCollaborateur).subscribe(
ep => this.initEP(ep)
)
}
initEP(ep:EpModel[]) {
this.epEffectues = [];
let epDisplay : DisplayEP;
for(let un_ep of ep) {
epDisplay = new DisplayEP();
epDisplay.id = un_ep.id;
epDisplay.referent = un_ep.referent;
epDisplay.etat = un_ep.etat;
epDisplay.type = un_ep.type;
epDisplay.dateentretien = un_ep.dateEntretien;
this.epEffectues.push(epDisplay);
}
this.dataSource = new MatTableDataSource(this.epEffectues);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
this.eploaded = true;
}
ngOnDestroy() {
if(this.epSubscription!= undefined) {
this.epSubscription.unsubscribe();
}
if(this.collaborateurSubscription!= undefined) {
this.collaborateurSubscription.unsubscribe();
}
} }
} }

@ -1,7 +1,8 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
/** /**
*/ * Composant pour faire affhcier l'évaluation d'une formation d'un collaborateur.
*/
@Component({ @Component({
selector: 'app-evaluation ', selector: 'app-evaluation ',
templateUrl: './evaluation.component.html' templateUrl: './evaluation.component.html'

@ -1,7 +1,8 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
/** /**
*/ * Composant pour permettre à un collaborateur de faire l'évaluation d'une formation
*/
@Component({ @Component({
selector: 'app-edit-evaluation', selector: 'app-edit-evaluation',
templateUrl: './edit-evaluation.component.html' templateUrl: './edit-evaluation.component.html'

@ -1,7 +1,8 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
/** /**
*/ * Composant pour afficher la liste des formations auxquelles à participer le collaborateur.
*/
@Component({ @Component({
selector: 'app-formations-collaborateur', selector: 'app-formations-collaborateur',
templateUrl: './formations-collaborateur.component.html' templateUrl: './formations-collaborateur.component.html'

@ -0,0 +1,42 @@
<ng-container *ngIf="collaborateur != undefined">
<h2> {{ collaborateur.nom }} {{ collaborateur.prenom }} </h2>
<p><b>Agence : {{ collaborateur.businessUnit.nom}} ({{ collaborateur.businessUnit.agence.nom}}) </b></p>
<ng-container *ngIf="!estReferent">
<p *ngIf="collaborateur.referent == null"><b>Aucun référent</b></p>
<p *ngIf="collaborateur.referent != null"><b>Référent : {{ collaborateur.referent.nom }} {{ collaborateur.referent.prenom }} </b></p>
</ng-container>
<p *ngIf="!estReferent"><b>Date embauche : {{ collaborateur.dateArrivee | date: 'dd MMMM yyyy'}}</b></p>
<p *ngIf="!estReferent && collaborateur.dateDepart!=undefined"><b>Date départ : {{ collaborateur.dateDepart | date: 'dd MMMM yyyy'}}</b></p>
<button mat-raised-button color="primary" (click)="openDialog()"> {{ estReferent ? "Ajouter des collaborateurs EP" : "Mettre à jour le référent EP"}}</button>
<mat-tab-group mat-align-tabs="start">
<mat-tab *ngIf="!estReferent" label="Prochain EP">
<prochain-ep [idCollaborateur]="idCollaborateur"></prochain-ep>
</mat-tab>
<mat-tab *ngIf="!estReferent" label="Liste des EP effectués">
<ep-table [rechercherParBU]="false" [rechercherParDate]="true" [typeRechercheEP]="epTypeRecherche.RechercheEPCollaborateursSignes" [displayedColumns]="displayedColumnsEPCollaborateur" [idCollaborateur]="idCollaborateur" (eventEmitter)="ouvrirEP($event)" ></ep-table>
</mat-tab>
<mat-tab *ngIf="!estReferent" label="Liste des formations">
<!-- <participations-formation-table [participations]="participationsFormation" [displayedColumns]="this.displayedColumnsParticipationFormaton"></participations-formation-table>-->
</mat-tab>
<mat-tab *ngIf="estReferent" label="Liste des collaborateurs">
<collaborateurs-table [rechercherParBU]="rechercherParBU" [rechercherParDate]="rechercherParDate" [displayedColumns]="displayedColumnsCollaborateurs" [typeRecherche]="typeRecherche" [idReferent]="idCollaborateur" (eventEmitter)="ouvrirDetailsCollaborateur($event)" ></collaborateurs-table>
</mat-tab>
<mat-tab *ngIf="estReferent" label="Liste des EP en cours">
<ep-table [rechercherParBU]="false" [rechercherParDate]="true" [typeRechercheEP]="epTypeRecherche.RechercheEPReferentEnCours" [displayedColumns]="displayedColumnsEPReferent" [idCollaborateur]="idCollaborateur" (eventEmitter)="ouvrirEP($event)" ></ep-table>
</mat-tab>
<mat-tab *ngIf="estReferent" label="Liste des EP référent">
<ep-table [rechercherParBU]="false" [rechercherParDate]="true" [typeRechercheEP]="epTypeRecherche.RechercheEPReferentSignes" [displayedColumns]="displayedColumnsEPReferent" [idCollaborateur]="idCollaborateur" (eventEmitter)="ouvrirEP($event)" ></ep-table>
</mat-tab>
</mat-tab-group>
</ng-container>
<ng-container *ngIf="collaborateur == undefined">
<mat-spinner></mat-spinner>
</ng-container>

@ -0,0 +1,22 @@
import { NgModule } from "@angular/core";
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { AffichageDetailsCollaborateurComponent } from "app/commun/affichage-details-collaboarteur/affichage-details-collaborateur";
import { DialogAssignationRapideReferentComponent, DialogAssignationRapideCollaborateursComponent } from "./dialog-assignation-rapide/dialog-assignation-rapide.component";
import { ProchainEpComponent } from "./prochain-ep/prochain-ep.component";
import { RouterModule } from "@angular/router";
@NgModule({
declarations: [
],
imports: [
CommonModule,
FormsModule,
RouterModule
],
exports: []
})
export class AffichageDetailsCollaborateurModule {}

@ -0,0 +1,88 @@
import { Component, Input, OnInit } from "@angular/core";
import { Subscription } from "rxjs";
import { MatDialog } from "@angular/material/dialog";
import { DialogAssignationRapideReferentComponent, DialogAssignationRapideCollaborateursComponent } from "./dialog-assignation-rapide/dialog-assignation-rapide.component";
import { Router } from "@angular/router";
import { CollaborateurDTO } from "../model/collaborateurDTO";
import { ParticipationFormationDTO } from "../model/participationFormationDTO";
import { CollaborateursService } from "../services/collaborateurs.service";
import { ParticipationsFormationsService } from "../services/participationsFormations.service";
import { collaborateurTypeRecherche, epTypeRecherche } from "../utils/cles";
@Component({
selector: "affichage-details-collaborateur",
templateUrl: "affichage-details-collaborateur.html"
})
export class AffichageDetailsCollaborateurComponent implements OnInit{
@Input() idCollaborateur: string;
@Input() estReferent: boolean=false;
typeRecherche : string = collaborateurTypeRecherche.collaborateursEP;
epTypeRecherche : any = epTypeRecherche;
displayedColumnsCollaborateurs : string[] = ["businessunit", "collaborateur", "datearrivee"];
displayedColumnsEPReferent : string[] = ["agence", "collaborateur", "datearrivee", "typeep", "statutep", "dateentretien", "consultation" ];
displayedColumnsParticipationFormaton: string[]= ["intitule", "statut", "dateCreation", "ep", "evaluation"];
displayedColumnsEPCollaborateur: string[] = ["agence", "referent", "typeep", "statutep", "dateentretien", "consultation" ];
rechercherParBU: boolean = false;
rechercherParDate: boolean= false;
collaborateur: CollaborateurDTO = undefined;
participationsFormation: Array<ParticipationFormationDTO> = [];
private collaborateurSubscription: Subscription;
private participationFormationSubscription: Subscription;
constructor(private collaborateurService: CollaborateursService, private participationFormationService: ParticipationsFormationsService, private dialog: MatDialog, private router: Router) {}
ngOnInit() {
this.collaborateurSubscription = this.collaborateurService.getCollaborateurById(this.idCollaborateur).subscribe(
collab => this.collaborateur = collab,
err => console.log(err)
);
this.participationFormationSubscription = this.participationFormationService.getParticipationsByCollaborateur(this.idCollaborateur).subscribe(
participationsFormation => this.participationsFormation = participationsFormation,
err => console.log(err)
);
}
ngOnDestroy() {
if(this.collaborateurSubscription != undefined) {
this.collaborateurSubscription.unsubscribe();
}
if(this.participationFormationSubscription != undefined) {
this.participationFormationSubscription.unsubscribe();
}
}
ouvrirEP(event :any) {
if(event.type == "ep")
this.router.navigate(["/ep", event.ep.id]);
}
ouvrirDetailsCollaborateur(event) {
this.router.navigate(["/collaborateurs",event.collaborateur.id]);
}
openDialog() {
const datas = { data: this.collaborateur, width: "80%", height: '80%'};
let dialog;
if(this.estReferent) {
dialog = DialogAssignationRapideCollaborateursComponent;
}
else {
dialog = DialogAssignationRapideReferentComponent;
}
this.dialog.open(dialog, datas);
}
}

@ -0,0 +1,17 @@
<!--ASSIGNATION D'UN OU PLUSIEURS COLLABORATEURS A UN REFERENT-->
<ng-container *ngIf="collaborateursSelectionnes.length != 0">
<p> Collaborateurs sélectionnés :</p>
<mat-chip-list >
<mat-chip
*ngFor="let collaborateur of collaborateursSelectionnes"
[removable]="true"
(removed)="enleverCollaborateur(collaborateur)">
{{collaborateur.nom}} {{collaborateur.prenom}}
<mat-icon matChipRemove>cancel</mat-icon>
</mat-chip>
</mat-chip-list>
<button mat-raised-button color="primary" (click)="mettreAJourReferentEP()">Mettre à jour le référent des collaborateurs</button>
</ng-container>
<p *ngIf="collaborateursSelectionnes.length == 0">Veuillez sélectionner au moins un collaborateur</p>
<button mat-raised-button color="primary" (click)="annuler()">Annuler</button>
<collaborateurs-table [rechercherParBU]="rechercherParBU" [rechercherParDate]="rechercherParDate" [roles]="roles" [displayedColumns]="displayedColumns" [typeRecherche]="typeRecherche" (eventEmitter)="selectionnerCollaborateur($event)" [collaborateursEP]="collaborateursEP" [collaborateursAjouts]="collaborateursSelectionnes" ></collaborateurs-table>

@ -0,0 +1,8 @@
<!--ASSIGNATION D'UN REFERENT A UN COLLABORATEUR-->
<ng-container *ngIf="referentChoisi != undefined">
<p> {{referentChoisi.nom}} {{referentChoisi.prenom}} {{ estReferentActuel() ? "(Référent actuel)" : "" }} </p>
<button mat-raised-button color="primary" *ngIf="!estReferentActuel()" (click)="mettreAJourReferent()">Valider le changement du référent</button>
</ng-container>
<p *ngIf="referentChoisi == undefined"> Veuillez choisir un référent </p>
<button mat-raised-button color="primary" (click)="annuler()">Annuler</button>
<collaborateurs-table [rechercherParBU]="rechercherParBU" [rechercherParDate]="rechercherParDate" [roles]="roles" [displayedColumns]="displayedColumns" [typeRecherche]="typeRecherche" (eventEmitter)="selectionnerReferent($event)"></collaborateurs-table>

@ -0,0 +1,169 @@
import {Component, Inject, OnInit } from "@angular/core";
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
import { MatSnackBar } from "@angular/material/snack-bar";
import { CollaborateurDTO } from "app/commun/model/collaborateurDTO";
import { ReferentEPDTO } from "app/commun/model/referentEPDTO";
import { CollaborateursService } from "app/commun/services/collaborateurs.service";
import { ReferentsEPService } from "app/commun/services/referentsEP.service";
import { collaborateurTypeRecherche } from "app/commun/utils/cles";
import { Subscription } from "rxjs";
@Component({
selector: "dialog-assignation-rapide-referent",
templateUrl: "dialog-assignation-rapide-referent.html"
})
export class DialogAssignationRapideReferentComponent {
rechercherParDate: boolean = false;
rechercherParBU: boolean = true;
referentChoisi : CollaborateurDTO = undefined;
roles : string[] = ["Manager", "RA", "CP", "TL"];
typeRecherche: string = collaborateurTypeRecherche.referents;
displayedColumns : string[] = ["businessunit", "collaborateur"];
private referentEPSubscription: Subscription;
constructor(private dialogRef: MatDialogRef<DialogAssignationRapideReferentComponent>, private referentsEPService: ReferentsEPService,
@Inject(MAT_DIALOG_DATA) private data: CollaborateurDTO) {
this.referentChoisi = data.referent;
}
selectionnerReferent(event :any) {
this.referentChoisi = event.collaborateur;
}
mettreAJourReferent() {
const referentEPDTO: ReferentEPDTO = {
idReferent : this.referentChoisi.id,
idsCollaborateur : [this.data.id],
};
this.referentEPSubscription = this.referentsEPService.updateReferentCollaborateur(referentEPDTO, this.data.id).subscribe(
() => location.reload(),
err => console.log(err)
);
}
estReferentActuel() {
return this.referentChoisi != undefined && this.data.referent != undefined &&this.referentChoisi.id == this.data.referent.id;
}
annuler() {
this.dialogRef.close();
}
ngOnDestroy() {
if(this.referentEPSubscription != undefined) {
this.referentEPSubscription.unsubscribe();
}
}
}
@Component({
selector: "dialog-assignation-rapide-collaborateurs",
templateUrl: "dialog-assignation-rapide-collaborateurs.html"
})
export class DialogAssignationRapideCollaborateursComponent implements OnInit{
rechercherParDate: boolean = false;
rechercherParBU: boolean = true;
roles : string[] = ["Collaborateur"];
typeRecherche: string = collaborateurTypeRecherche.collaborateurs;
displayedColumns : string[] = ["businessunit", "collaborateur", "datearrivee", "referent"];
collaborateursEP: CollaborateurDTO[] = [];
collaborateursSelectionnes: CollaborateurDTO[] = [];
private collaborateurSubscription: Subscription;
private referentEPSubscription: Subscription;
constructor(private dialogRef: MatDialogRef<DialogAssignationRapideCollaborateursComponent>, private referentsEPService: ReferentsEPService,
private collaborateurService: CollaborateursService, @Inject(MAT_DIALOG_DATA) private data: CollaborateurDTO,
private snackBar: MatSnackBar) {
}
ngOnInit() {
this.collaborateurSubscription = this.collaborateurService.getCollaborateursByReferent(this.data.id).subscribe(
collaborateurs => this.collaborateursEP = collaborateurs,
err => console.log(err)
);
}
/**
* Permet de sélectionner un collaborateur et de l'ajouter ou l'enlever de la liste des collaborateurs à ajouter si il n'est pas déjà un collaborateur EP du référent
* @param event contient le collaborateur qui a é récupéré
*/
selectionnerCollaborateur(event:any) {
if(event.type != "collaborateur")
return;
if(event.collaborateur.id == this.data.id) {
this.openSnackBar("Un collaborateur ne peut pas être son propre référent");
return;
}
if(this.contientCollaborateur(this.collaborateursSelectionnes, event.collaborateur)){
this.enleverCollaborateur(event.collaborateur);
return;
}
if(this.contientCollaborateur(this.collaborateursEP, event.collaborateur)){
this.openSnackBar("Le référent choisi est déjà le référent EP du collaborateur sélectionné")
return;
}
this.collaborateursSelectionnes.push(event.collaborateur);
}
contientCollaborateur(listes: CollaborateurDTO[], collaborateur: CollaborateurDTO ) : boolean {
return listes.some(c => c.id == collaborateur.id);
}
enleverCollaborateur(collaborateur: CollaborateurDTO) {
this.collaborateursSelectionnes = this.collaborateursSelectionnes.filter(c => c.id != collaborateur.id);
}
mettreAJourReferentEP() {
const referentEP : ReferentEPDTO = {
idReferent: this.data.id,
idsCollaborateur: this.collaborateursSelectionnes.map( c => c.id)
};
this.referentEPSubscription = this.referentsEPService.updateCollaborateursReferent(referentEP, this.data.id).subscribe(
() => location.reload(),
err => console.log(err)
);
}
openSnackBar(message: string) {
this.snackBar.open(message,"", {
duration: 5000,
horizontalPosition: "center",
verticalPosition: "top",
});
}
annuler() {
this.dialogRef.close();
}
ngOnDestroy() {
if(this.referentEPSubscription != undefined) {
this.referentEPSubscription.unsubscribe();
}
if(this.collaborateurSubscription != undefined) {
this.collaborateurSubscription.unsubscribe();
}
}
}

@ -0,0 +1,31 @@
<ng-container *ngIf="chargement">
<mat-spinner></mat-spinner>
</ng-container>
<ng-container *ngIf="!chargement">
<ng-container *ngIf="prochainEP == undefined">
<p> Aucun prochain EP n'a été trouvé </p>
</ng-container>
<ng-container *ngIf="prochainEP != undefined">
<ng-container *ngIf="prochainEP.statut == statutEP.cree">
<p> Prochain {{prochainEP.type}} disponible pour saisie le {{ prochainEP.dateDisponibilite | date: "dd/MM/yyyy" }} </p>
</ng-container>
<ng-container *ngIf="prochainEP.statut != statutEP.cree">
<p> {{prochainEP.type}} : {{ afficherStatutEP(prochainEP.statut) }} </p>
<p> Disponible depuis le {{ prochainEP.dateDisponibilite | date : "dd/MM/yyyy" }}</p>
<p> Date d'entretien le {{ prochainEP.datePrevisionnelle | date : "dd/MM/yyyy" }}</p>
<ng-container *ngIf="prochainEP.referent != undefined">
<p> Référent EP : {{prochainEP.referent.nom}} {{prochainEP.referent.prenom}} </p>
</ng-container>
<ng-container *ngIf="prochainEP.referent == undefined">
<p> Il n'y a actuellement aucun référent pour cet EP </p>
</ng-container>
<button mat-stroked-button *ngIf="prochainEP.statut != statutEP.Disponible" [routerLink]="['/ep',prochainEP.id]">Accéder à l'EP</button>
</ng-container>
</ng-container>
</ng-container>

@ -0,0 +1,51 @@
import { Component, Input, OnInit } from "@angular/core"
import { affichageStatut, EpInformationDTO, StatutEp } from "app/commun/model/models";
import { EpService } from "app/commun/services/ep.service";
import { Subscription } from "rxjs";
@Component({
selector: "prochain-ep",
templateUrl: "./prochain-ep.component.html"
})
export class ProchainEpComponent implements OnInit {
statutEP : any = StatutEp;
@Input() idCollaborateur: string;
chargement: boolean = true;
prochainEP : EpInformationDTO;
epSubscription: Subscription;
constructor(private epService: EpService) {
}
ngOnInit() {
this.epSubscription = this.epService.getProchainEPCollaborateur(this.idCollaborateur).subscribe(
ep => {
console.log(ep);
this.prochainEP = ep;
this.chargement = false;
},
err => {
this.chargement = false;
console.log(err)
}
);
}
afficherStatutEP(statut: StatutEp) {
return affichageStatut(statut);
}
ngDestroy() {
if(this.epSubscription != undefined)
this.epSubscription.unsubscribe();
}
}

@ -0,0 +1,23 @@
import { AuthConfig } from 'angular-oauth2-oidc';
import { environment } from '@env';
/**
* Configuration du serveur Keycloak.
*/
export const authConfig: AuthConfig = {
issuer: environment.keycloakConfig.issuer,
clientId: environment.keycloakConfig.clientId,
dummyClientSecret: environment.keycloakConfig.dummyClientSecret,
responseType: environment.keycloakConfig.responseType,
redirectUri: environment.keycloakConfig.redirectUri,
silentRefreshRedirectUri: environment.keycloakConfig.silentRefreshRedirectUri,
scope: environment.keycloakConfig.scope,
useSilentRefresh: environment.keycloakConfig.useSilentRefresh,
silentRefreshTimeout: environment.keycloakConfig.silentRefreshTimeout,
timeoutFactor: environment.keycloakConfig.timeoutFactor,
sessionChecksEnabled: environment.keycloakConfig.sessionChecksEnabled,
showDebugInformation: environment.keycloakConfig.showDebugInformation,
clearHashAfterLogin: environment.keycloakConfig.clearHashAfterLogin,
nonceStateSeparator : environment.keycloakConfig.nonceStateSeparator
};

@ -0,0 +1,13 @@
import { OAuthModuleConfig } from 'angular-oauth2-oidc';
import { URL_API } from '../config/variables';
/**
* Liste des urls pour lesquelles les appels doivent être interceptés.
* Si la propriété sendAccessToken est défini sur true, l'access_token est envoyé dans le header.
*/
export const authModuleConfig: OAuthModuleConfig = {
resourceServer: {
allowedUrls: [URL_API],
sendAccessToken: true,
}
};

@ -0,0 +1,45 @@
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { AuthService } from './auth.service';
/**
* Guard permettant de gérer les autorisations au niveau des routes.
*/
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
return this.authService.canActivateProtectedRoutes$.pipe(tap(isLoggin => this.login(isLoggin,route)));
}
/**
* Vérifie si l'utilisateur est connecté et si l'utilisateur est autorisé à accéder à la route.
* @param isLoggin Booléen permettant de savoir si l'utilisateur est connecté ou non
* @param route Route à laquelle l'utilisateur souhaite accéder
*/
private login(isLoggin: boolean, route: ActivatedRouteSnapshot): boolean {
if (!isLoggin) {
this.authService.login();
}
const firstRole = this.authService.firstRole;
if (firstRole) {
// Vérifie si la route est restreinte par des rôles
if (route.data.roles && route.data.roles.indexOf(firstRole) === -1) {
// l'utisateur n'est pas autorisé alors on le redirige vers la page d'accueil
this.router.navigate(['/']);
return false;
}
// L'utilisateur est autorisé
return true;
}
}
}

@ -0,0 +1,61 @@
import { HttpClientModule } from '@angular/common/http';
import { ModuleWithProviders, NgModule, Optional, SkipSelf, APP_INITIALIZER } from '@angular/core';
import { AuthConfig, OAuthModule, OAuthModuleConfig, OAuthStorage } from 'angular-oauth2-oidc';
import { authConfig } from './auth-config';
import { AuthGuard } from './auth.guard';
import { authModuleConfig } from './auth-module-config';
import { AuthService } from './auth.service';
/**
* Utilisation du localstorage pour stocker le token
* Voir: https://manfredsteyer.github.io/angular-oauth2-oidc/docs/additional-documentation/configure-custom-oauthstorage.html
*/
export function storageFactory(): OAuthStorage {
return localStorage;
}
/**
* Fonction permettant d'appeler la méthode qui va démarrer la séquence de connexion initiale
* @param authService Service d'authentification
*/
export function init_app(authService: AuthService) {
return () => authService.runInitialLoginSequence();
}
/**
* Module d'authentification.
*/
@NgModule({
imports: [
HttpClientModule,
OAuthModule.forRoot(),
],
providers: [
AuthService,
AuthGuard,
],
})
export class AuthModule {
static forRoot(): ModuleWithProviders<AuthModule> {
return {
ngModule: AuthModule,
providers: [
{ provide: AuthConfig, useValue: authConfig },
{ provide: OAuthModuleConfig, useValue: authModuleConfig },
{ provide: OAuthStorage, useFactory: storageFactory },
{
provide: APP_INITIALIZER, // Gestion de l'authentification au démarrage de l'application
useFactory: init_app,
deps: [ AuthService ],
multi: true
}
]
};
}
constructor (@Optional() @SkipSelf() parentModule: AuthModule) {
if (parentModule) {
throw new Error("AuthModule est déjà chargé. Importez-le dans uniquement l'AppModule.");
}
}
}

@ -0,0 +1,6 @@
describe('AuthService', () => {
it('should pass', () => {
expect(true).toBeTruthy();
});
});

@ -0,0 +1,222 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { OAuthErrorEvent, OAuthService } from 'angular-oauth2-oidc';
import { BehaviorSubject, combineLatest, Observable, ReplaySubject } from 'rxjs';
import { filter, map } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class AuthService {
private isAuthenticatedSubject$ = new BehaviorSubject<boolean>(false);
private isDoneLoadingSubject$ = new ReplaySubject<boolean>();
/**
* Observable permettant de savoir si l'utilisateur est authentifié.
*/
public isAuthenticated$ = this.isAuthenticatedSubject$.asObservable();
/**
* Observable permettant de savoir si le chargement de la connexion initiale est terminé.
*/
public isDoneLoading$ = this.isDoneLoadingSubject$.asObservable();
/**
* Retourne "true" si et seulement si tous les appels asynchrones de la connexion initiale
* sont terminés (ou comportent une erreur), et si l'utilisateur
* a fini par être authentifié.
*
* En résumé, il combine:
*
* - Le dernier état connu indiquant si l'utilisateur est autorisé
* - Si les appels ajax pour la connexion initiale ont tous é effectués
*/
public canActivateProtectedRoutes$: Observable<boolean> = combineLatest([
this.isAuthenticated$, this.isDoneLoading$ ]).pipe(map(values => values.every(b => b)));
/**
* Navigue vers la page de connexion.
*/
private navigateToLoginPage() {
// Pour naviguer vers un composant
//this.router.navigateByUrl('/should-login');
// Pour naviguer vers la page de connexion du server Keycloak
this.login();
}
/**
* Constructeur du service d'authentification.
* @param oauthService Service d'authentification de la librairie angular-oauth2-oidc
* @param router Service permettant de naviguer et de manipuler les urls
*/
constructor(private oauthService: OAuthService, private router: Router) {
/*
// Utile pour le débogage:
this.oauthService.events.subscribe(event => {
if (event instanceof OAuthErrorEvent) {
console.error('OAuthErrorEvent Object:', event);
} else {
console.warn('OAuthEvent Object:', event);
}
});
*/
// Ajout un évènement afin de gérer l'acces_token dans le cas où l'application est ouverte dans deux onglets différents.
// TODO: Pour améliorer cette configuration. Voir: https://github.com/jeroenheijmans/sample-angular-oauth2-oidc-with-auth-guards/issues/2
window.addEventListener('storage', (event) => {
// La propriété "key" à la valeur "null" si l'événement a été causé par la méthode ".clear()".
if (event.key !== 'access_token' && event.key !== null) {
return;
}
//console.warn("Changements remarqués dans l'access_token (très probablement depuis un autre onglet). Mise à jour de l'observable isAuthenticated.") ;
this.isAuthenticatedSubject$.next(this.oauthService.hasValidAccessToken());
// Si l'acces_token n'est pas valide, on redirige l'utilisateur vers la page de connexion
if (!this.oauthService.hasValidAccessToken()) {
this.navigateToLoginPage();
}
});
// Met à jour l'observable lorsque l'access_token est valide
this.oauthService.events
.subscribe(_ => {
this.isAuthenticatedSubject$.next(this.oauthService.hasValidAccessToken());
});
// Charge le profil de l'utilisateur lorsque le token est reçu
this.oauthService.events
.pipe(filter(e => ['token_received'].includes(e.type)))
.subscribe(e => this.oauthService.loadUserProfile());
// Redirige l'utilisateur vers la page de connexion lorsque la session est terminée ou lorsque qu'il y a une erreur
this.oauthService.events
.pipe(filter(e => ['session_terminated', 'session_error'].includes(e.type)))
.subscribe(e => this.navigateToLoginPage());
// Mise en place d'un rafraîchissement silencieux lorsque le jeton est sur le point d'expirer
this.oauthService.setupAutomaticSilentRefresh();
}
/**
* Lance la séquence de connexion initiale.
*/
public runInitialLoginSequence(): Promise<void> {
// Charge la configuration de Keycloak et tente de se connecter
return this.oauthService.loadDiscoveryDocumentAndTryLogin()
.then(() => {
// Si l'acces token est valide alors tout est ok
if (this.oauthService.hasValidAccessToken()) {
return Promise.resolve();
}
// Renvoie l'utilisateur vers la page de connexion
this.navigateToLoginPage();
// Afficher un mesage d'avertissement:
//console.warn("Une interaction de l'utilisateur est nécessaire pour se connecter, l'utilisateur doit se connecter manuellement.");
return Promise.reject();
})
.then(() => {
// Met à jour de l'observable isDoneLoadingSubject
this.isDoneLoadingSubject$.next(true);
})
.catch(() => this.isDoneLoadingSubject$.next(true)); // Met à jour l'observable isDoneLoadingSubject même si il y a une erreur
}
/**
* Affiche la page de connexion.
* @param targetUrl Url de destination
*/
public login(targetUrl?: string) {
this.oauthService.initCodeFlow(targetUrl || this.router.url);
}
/**
* Supprime tous les tokens et déconnecte l'utilisateur.
*/
public logout() { this.oauthService.logOut(); }
/**
* Permet d'obtenir des nouveaux tokens quand/avant que les tokens existants expirent.
*/
public refresh() { this.oauthService.silentRefresh(); }
/**
* Vérifie si l'access_token est valide.
*/
public hasValidToken() { return this.oauthService.hasValidAccessToken(); }
/**
* Premier rôle dans la liste des rôles de l'utilisateur.
*/
public get firstRole() {
if(this.identityClaims != null)
return this.identityClaims['roles'][0];
else
return;
}
/**
* Liste des rôles de l'utilisateur.
*/
public get roles() {
if(this.identityClaims != null)
return this.identityClaims['roles'];
else
return;
}
/**
* Nom et prénom de l'utilisateur.
*/
public get userInfo() {
if(this.identityClaims != null)
return this.identityClaims['name'];
else
return;
}
/**
* mail de l'utilisateur
*/
public get mail() {
if(this.identityClaims != null)
return this.identityClaims['email'];
else
return;
}
// Normalement, ce genre de service ne les expose pas,
// mais pour le débogage, ça peut-être utile.
/**
* Access_token actuel.
*/
public get accessToken() { return this.oauthService.getAccessToken(); }
/**
* Refresh_Token actuel.
*/
public get refreshToken() { return this.oauthService.getRefreshToken(); }
/**
* Claims concernant l'utilisateur.
*/
public get identityClaims() { return this.oauthService.getIdentityClaims(); }
/**
* Id_token actuel.
*/
public get idToken() { return this.oauthService.getIdToken(); }
/**
* Url de déconnexion.
*/
public get logoutUrl() { return this.oauthService.logoutUrl; }
}

@ -0,0 +1,45 @@
import { NgModule, ModuleWithProviders, SkipSelf, Optional } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DemandesFormationService } from './services/demandesformation.service';
import { CollaborateursService } from './services/collaborateurs.service';
import { DemandesDelegationService } from './services/demandesDelegation.service';
import { DemandesEPIService } from './services/demandesEPI.service';
import { EngagementsService } from './services/engagements.service';
import { EpService } from './services/ep.service';
import { FormationsService } from './services/formations.service';
import { NotesService } from './services/notes.service';
import { ParticipationsFormationsService } from './services/participationsFormations.service';
import { ReferentsEPService } from './services/referentsEP.service';
import { Configuration } from './config/configuration';
import { HttpClient } from '@angular/common/http';
@NgModule({
imports: [
CommonModule
],
declarations: []
})
export class CommunApiModule {
public static forRoot(configurationFactory: () => Configuration): ModuleWithProviders<CommunApiModule> {
return {
ngModule: CommunApiModule,
providers: [
{ provide: Configuration, useFactory: configurationFactory },
CollaborateursService,
DemandesDelegationService,
DemandesEPIService,
DemandesFormationService,
EngagementsService,
EpService,
FormationsService,
NotesService,
ParticipationsFormationsService,
ReferentsEPService
]
};
}
}

@ -0,0 +1,165 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatCardModule } from '@angular/material/card';
import { MatButtonModule } from '@angular/material/button';
import { MatMenuModule } from '@angular/material/menu';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatIconModule } from '@angular/material/icon';
import { MatSortModule } from '@angular/material/sort';
import { MatInputModule } from '@angular/material/input';
import { MatTableModule } from '@angular/material/table';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatTabsModule } from '@angular/material/tabs';
import { NgxMatDatetimePickerModule, NgxMatNativeDateModule } from '@angular-material-components/datetime-picker';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatListModule } from '@angular/material/list';
import { MatNativeDateModule, MatOption, MatOptionModule } from '@angular/material/core';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatSelectModule } from '@angular/material/select';
import { MatStepperModule } from '@angular/material/stepper';
import { MatChipsModule } from '@angular/material/chips';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatRadioModule } from '@angular/material/radio';
import { CollaborateursTableComponent } from './mat-tables/collaborateurs-table/collaborateurs.table';
import { DemandesFormationTableComponent } from './mat-tables/demandes-formation-table/demandes-formation.table';
import { EngagementTableComponent } from './mat-tables/engagements-table/engagements-table';
import { EpTableComponent } from './mat-tables/ep-table/ep-table';
import { FormationsTableComponent } from './mat-tables/formations-table/formations.table';
import { ParticipationsFormationTableComponent } from './mat-tables/participations-formation-table/participations-formation.table';
import { FilterModule } from './filter/filter.module';
import { AuthModule } from './auth/auth.module';
import { NavMenuComponent } from './nav-menu/nav-menu.component';
import { NavMenuAssistanteComponent } from './nav-menu/nav-menu-assistante/nav-menu-assistante.component';
import { NavMenuCollaborateurComponent } from './nav-menu/nav-menu-collaborateur/nav-menu-collaborateur.component';
import { NavMenuCommercialComponent } from './nav-menu/nav-menu-commercial/nav-menu-commercial.component';
import { NavMenuRHComponent } from './nav-menu/nav-menu-rh/nav-menu-rh.component';
import { RouterModule } from '@angular/router';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CheckboxFilterComponent } from './filter/checkbox-filter/checkbox-filter';
import { SelectFilterComponent } from './filter/select-filter/select-filter';
import { AffichageDetailsCollaborateurComponent } from './affichage-details-collaboarteur/affichage-details-collaborateur';
import { DialogAssignationRapideReferentComponent, DialogAssignationRapideCollaborateursComponent } from './affichage-details-collaboarteur/dialog-assignation-rapide/dialog-assignation-rapide.component';
import { ProchainEpComponent } from './affichage-details-collaboarteur/prochain-ep/prochain-ep.component';
@NgModule({
imports: [
// Materials
MatCardModule,
MatButtonModule,
MatMenuModule,
MatIconModule,
MatPaginatorModule,
MatSortModule,
MatTableModule,
MatInputModule,
MatProgressSpinnerModule,
MatTabsModule,
MatFormFieldModule,
NgxMatDatetimePickerModule,
MatDatepickerModule,
NgxMatNativeDateModule,
MatNativeDateModule,
MatListModule,
MatCheckboxModule,
MatSelectModule,
MatStepperModule,
MatChipsModule,
MatSnackBarModule,
MatSlideToggleModule,
MatRadioModule,
MatOptionModule,
// Forms Angular
FormsModule,
ReactiveFormsModule,
// Common angular
CommonModule,
// Module commun
FilterModule,
RouterModule
],
exports: [
// Materials
MatCardModule,
MatButtonModule,
MatMenuModule,
MatIconModule,
MatPaginatorModule,
MatSortModule,
MatTableModule,
MatInputModule,
MatProgressSpinnerModule,
MatTabsModule,
MatFormFieldModule,
NgxMatDatetimePickerModule,
MatDatepickerModule,
NgxMatNativeDateModule,
MatNativeDateModule,
MatListModule,
MatCheckboxModule,
MatSelectModule,
MatStepperModule,
MatChipsModule,
MatSnackBarModule,
MatSlideToggleModule,
MatRadioModule,
MatOptionModule,
// Module commun
FilterModule,
// Component commun
NavMenuComponent,
ProchainEpComponent,
DialogAssignationRapideReferentComponent,
AffichageDetailsCollaborateurComponent,
// Table commun
CollaborateursTableComponent,
EngagementTableComponent,
FormationsTableComponent,
EpTableComponent,
ParticipationsFormationTableComponent,
DemandesFormationTableComponent
],
declarations: [
// Component commun
/// Filter
CheckboxFilterComponent,
SelectFilterComponent,
/// Nav menu
NavMenuComponent,
NavMenuAssistanteComponent,
NavMenuCollaborateurComponent,
NavMenuCommercialComponent,
NavMenuRHComponent,
/// Affichage collab
AffichageDetailsCollaborateurComponent,
DialogAssignationRapideReferentComponent,
DialogAssignationRapideCollaborateursComponent,
ProchainEpComponent,
// Table commun
CollaborateursTableComponent,
EngagementTableComponent,
FormationsTableComponent,
EpTableComponent,
ParticipationsFormationTableComponent,
DemandesFormationTableComponent,
],
entryComponents: [
NavMenuComponent,
DialogAssignationRapideReferentComponent
]
})
export class CommunUiModule { }

@ -7,3 +7,6 @@ export const COLLECTION_FORMATS = {
'ssv': ' ', 'ssv': ' ',
'pipes': '|' 'pipes': '|'
} }
export const URL_API = "https://localhost:44393/api";
export const URL_AUTH = "http://localhost:8080";

@ -0,0 +1,14 @@
<button (click)="$event.stopPropagation();" mat-icon-button [matMenuTriggerFor]="menu" aria-label="filter-button avec menu">
<mat-icon>filter_alt</mat-icon>
</button>
<mat-menu #menu="matMenu">
<mat-list role="list" (click)="$event.stopPropagation();">
<mat-list-item role="listitem">
<mat-checkbox (change)="selectedAllChecked($event.checked)" [checked]="checkedAll"> Tout sélectionner</mat-checkbox>
</mat-list-item>
<mat-list-item *ngFor="let data of dataSource" role="listitem">
<mat-checkbox *ngIf="isPropertyValueName" (change)="selectedChecked($event.checked,data)" [checked]="exists(data)"> {{data[propertyValueName]}}</mat-checkbox>
<mat-checkbox *ngIf="!isPropertyValueName" (change)="selectedChecked($event.checked,data)" [checked]="exists(data)"> {{data}}</mat-checkbox>
</mat-list-item>
</mat-list>
</mat-menu>

@ -0,0 +1,118 @@
import { Component, Input, Output, EventEmitter, OnInit, OnChanges } from "@angular/core";
import { SelectedElement } from "../selected-element";
@Component({
selector: "checkbox-filter",
templateUrl: "./checkbox-filter.html",
styleUrls: ["./checkbox-filter.scss"]
})
export class CheckboxFilterComponent<T> implements OnInit, OnChanges {
/**
* Liste des éléments sélectionnés
*/
elementsSelected: Array<T> = [];
/**
* Booléen permettant de determiner si la propriété "propertyValueName" contient une valeur ou non
*/
isPropertyValueName: boolean;
/**
* Coche toutes les cases à cocher
*/
@Input() checkedAll: boolean;
/**
* Source de données
*/
@Input() dataSource : Array<T>;
/**
* Nom de la propriété contenant la valeur à afficher
*/
@Input() propertyValueName: string;
/**
* Booléen permettant de savoir si toutes les cases sont cochées ou non
*/
@Output() isSelectedAllEvent = new EventEmitter<boolean>();
/**
* Elément sélectionné
*/
@Output() isSelectedEvent = new EventEmitter<SelectedElement<T>>();
constructor() {}
ngOnInit() {
this.isPropertyValueName = !this.propertyValueName ? false : true;
}
ngOnChanges() {
if (this.dataSource.length > 0) {
this.checkElementhasProperty();
this.selectedAllChecked(this.checkedAll);
}
}
/**
* Vérifie que tous les éléments de source de données possède la propriété "propertyValueName" lorsque cette dernière
* contient une valeur.
*/
checkElementhasProperty() {
if(this.propertyValueName && !this.dataSource.every(e => e.hasOwnProperty(this.propertyValueName)))
throw new Error("Il existe au moins un élément dans la source de données qui ne possède pas la propriété '"+this.propertyValueName+"'.");
}
/**
* Détermine si l'élément est présent dans la liste des éléments sélectionnés
* @param element
*/
exists(element) {
return this.elementsSelected.indexOf(element) > -1;
};
/**
* Met à jour la liste des éléments sélectionnés et met à jour l'EventEmitter "isSelectedAllEvent"
* @param event case "Tout Sélectionner" cochée ou décochée
*/
selectedAllChecked(event) {
this.isSelectedAllEvent.emit(event);
this.checkedAll = event;
this.elementsSelected = [];
if(event)
this.dataSource.map(data => this.elementsSelected.push(data));
}
/**
* Met à jour la liste des éléments sélectionnés et met à jour l'EventEmitter "isSelectedEvent"
* @param event case cochée ou décochée par l'utilisateur
* @param data Valeur de la case cochée ou décochée
*/
selectedChecked = (event: any, data: T) => {
this.isSelectedEvent.emit({isSelected: event, selectedElement: data});
// si la checkbox a été cochée
if(event)
this.elementsSelected.push(data);
else
this.elementsSelected = this.elementsSelected.filter(element => element != data);
// coche la case "Tout sélectionner" si tous les éléments sont cochés
this.elementsSelected.length == this.dataSource.length ? this.checkedAll = true: this.checkedAll = false;
}
/**
* Une fois la page fermée, il est nécessaire de se désabonner des Oberservable afin d'éviter les fuites mémoires.
*/
ngOnDestroy() {
}
}

@ -0,0 +1,24 @@
import { NgModule } from "@angular/core";
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule} from '@angular/forms';
import { RouterModule } from '@angular/router';
import { SelectFilterComponent } from "./select-filter/select-filter";
import { CheckboxFilterComponent } from "./checkbox-filter/checkbox-filter";
@NgModule({
declarations: [
],
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
RouterModule
],
exports: [
]
})
export class FilterModule {}

@ -0,0 +1,11 @@
<mat-form-field appearance="fill">
<mat-label>{{label}}</mat-label>
<mat-select [(value)]="elementsSelected" multiple>
<mat-checkbox class="mat-option" (change)="selectedAllChecked($event.checked)" [checked]="checkedAll"> Tout sélectionner</mat-checkbox>
<ng-container *ngFor="let data of dataSource">
<mat-option #matOption *ngIf="isPropertyValueName" (click)="selectedChecked(matOption.selected, data)" [value]="data">{{data[propertyValueName]}}</mat-option>
<mat-option #matOption *ngIf="!isPropertyValueName" (click)="selectedChecked(matOption.selected, data)" [value]="data">{{data}}</mat-option>
</ng-container>
</mat-select>
</mat-form-field>

@ -0,0 +1,4 @@
mat-select .mat-checkbox-layout,
mat-select .mat-checkbox-label {
width:100% !important;
}

@ -0,0 +1,116 @@
import { Component, Input, Output, EventEmitter, OnInit, OnChanges } from "@angular/core";
import { SelectedElement } from "../selected-element";
@Component({
selector: "select-filter",
templateUrl: "./select-filter.html",
styleUrls: ["./select-filter.scss"]
})
export class SelectFilterComponent<T> implements OnInit, OnChanges {
/**
* Liste des éléments sélectionnés
*/
elementsSelected: Array<T> = [];
/**
* Booléen permettant de determiner si la propriété "propertyValueName" contient une valeur ou non
*/
isPropertyValueName: boolean;
/**
* Libellé qui est affiché dans la liste déroulante lorsqu'aucune valeur n'est sélectionnée
*/
@Input() label: string;
/**
* Cocher toutes les cases à cocher
*/
@Input() checkedAll: boolean;
/**
* Source de données
*/
@Input() dataSource : Array<T>;
/**
* Nom de la propriété contenant la valeur à afficher
*/
@Input() propertyValueName: string;
/**
* Booléen permettant de savoir si toutes les cases sont cochées ou non
*/
@Output() isSelectedAllEvent = new EventEmitter<boolean>();
/**
* Elément sélectionné
*/
@Output() isSelectedEvent = new EventEmitter<SelectedElement<T>>();
constructor() {}
ngOnInit() {
this.isPropertyValueName = !this.propertyValueName ? false : true;
}
ngOnChanges() {
if (this.dataSource.length > 0) {
this.checkElementhasProperty();
this.selectedAllChecked(this.checkedAll);
}
}
/**
* Vérifie que tous les éléments de source de données possède la propriété "propertyValueName" lorsque cette dernière
* contient une valeur.
*/
checkElementhasProperty() {
if(this.propertyValueName && !this.dataSource.every(e => e.hasOwnProperty(this.propertyValueName)))
throw new Error("Il existe au moins un élément dans la source de données qui ne possède pas la propriété '"+this.propertyValueName+"'.");
}
/**
* Met à jour la liste des éléments sélectionnés et met à jour l'EventEmitter "isSelectedAllEvent"
* @param event case "Tout Sélectionner" cochée ou décochée
*/
selectedAllChecked(event) {
this.isSelectedAllEvent.emit(event);
this.checkedAll = event;
this.elementsSelected = [];
if(event)
this.dataSource.map(data => this.elementsSelected.push(data));
}
/**
* Met à jour la liste des éléments sélectionnés et met à jour l'EventEmitter "isSelectedEvent"
* @param isChecked case cochée ou décochée par l'utilisateur
* @param data Valeur de la case cochée ou décochée
*/
selectedChecked = (isChecked: boolean, data: T) => {
this.isSelectedEvent.emit({isSelected: isChecked, selectedElement: data});
if(isChecked) {
var index = this.elementsSelected.findIndex(element => element == data);
if (index === -1)
this.elementsSelected.push(data);
}
else {
this.elementsSelected = this.elementsSelected.filter(element => element != data);
}
// coche la case "Tout sélectionner" si tous les éléments sont cochés
this.elementsSelected.length == this.dataSource.length ? this.checkedAll = true: this.checkedAll = false;
}
/**
* Une fois la page fermée, il est nécessaire de se désabonner des Oberservable afin d'éviter les fuites mémoires.
*/
ngOnDestroy() {
}
}

@ -0,0 +1,11 @@
export interface SelectedElement<T> {
/**
* Détermine si l'élément est sélectionné ou non
*/
isSelected: boolean;
/**
* Element sélectionné
*/
selectedElement: T;
}

@ -0,0 +1,85 @@
<ng-container *ngIf="chargement">
<mat-spinner></mat-spinner>
</ng-container>
<ng-container *ngIf="!chargement">
<!-- Barre de recherche -->
<mat-form-field>
<mat-label>Rechercher un collaborateur</mat-label>
<input matInput type="text" [(ngModel)]="search" (keyup)="setSearch()">
<mat-button *ngIf="search" matSuffix mat-icon-button aria-label="Clear" (click)="resetSearch()">
<mat-icon>close</mat-icon>
</mat-button>
</mat-form-field>
<!--Checkboxes des BU-->
<ng-container *ngIf="rechercherParBU">
<mat-checkbox *ngFor="let bu of bus" (change)="updateCheckbox($event.checked,bu)" [checked]="true"> {{bu.nom}}</mat-checkbox>
</ng-container>
<ng-container *ngIf="rechercherParDate">
<!-- Datepicker début -->
<mat-form-field >
<mat-label>Date de début</mat-label>
<input [(ngModel)]="dateDebut" matInput [matDatepicker]="dateDebutPicker" [max]="dateFin" disabled (dateChange)="updateDonneesTableau()">
<mat-icon *ngIf="this.dateDebut != undefined" matDatepickerToggleIcon (click)="updateDateToUndefined(1)">clear</mat-icon>
<mat-datepicker-toggle matSuffix [for]="dateDebutPicker"></mat-datepicker-toggle>
<mat-datepicker touchUi #dateDebutPicker disabled="false"></mat-datepicker>
</mat-form-field>
<!-- Datepicker fin -->
<mat-form-field>
<mat-label>Date de fin</mat-label>
<input [(ngModel)]="dateFin" matInput [matDatepicker]="dateFinPicker" [min]="dateDebut" disabled (dateChange)="updateDonneesTableau()">
<mat-icon *ngIf="this.dateFin != undefined" matDatepickerToggleIcon (click)="updateDateToUndefined(2)">clear</mat-icon>
<mat-datepicker-toggle matSuffix [for]="dateFinPicker"></mat-datepicker-toggle>
<mat-datepicker touchUi #dateFinPicker disabled="false"></mat-datepicker>
</mat-form-field>
</ng-container>
<ng-container *ngIf="taille == 0">
<p>Aucun collaborateur à afficher</p>
</ng-container>
<ng-container *ngIf="taille != 0">
<!-- Affichage de la liste des collaborateurs -->
<mat-table matSort [dataSource]="dataSource" (matSortChange)="trierTableau($event)" matSortActive="{{this.tri}}" matSortDirection="asc" >
<ng-container matColumnDef="businessunit">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Agence</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.businessUnit.nom }}</mat-cell>
</ng-container>
<ng-container matColumnDef="collaborateur">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Collabotareur</mat-header-cell>
<mat-cell *matCellDef="let row" (click)="emitEvent(row,'collaborateur')">{{row.nom}} {{row.prenom}}</mat-cell>
</ng-container>
<ng-container matColumnDef="datearrivee">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Date embauche</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.dateArrivee | date:'dd/MM/yyyy'}}</mat-cell>
</ng-container>
<ng-container matColumnDef="referent">
<mat-header-cell *matHeaderCellDef >Référent</mat-header-cell>
<mat-cell *matCellDef="let row" >
<mat-cell *ngIf="row.referent" (click)="emitEvent(row.referent,'referent')"> {{ row.referent.nom }} {{ row.referent.prenom }} </mat-cell>
<mat-cell *ngIf="!row.referent">Aucun référent</mat-cell>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row [ngClass]="setClassCouleurLigne(row)" *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
<mat-paginator #paginator
[length] = "taille"
[pageIndex]="numPage-1"
[pageSize]="parPage"
[pageSizeOptions]="pageOption"
(page)="updatePaginationTableau($event)">
</mat-paginator>
</ng-container>
</ng-container>

@ -0,0 +1,7 @@
.collaborateurAjoute {
background-color: #5cb85c;
}
.dejaCollaborateurEP {
background-color: #337ab7;
}

@ -0,0 +1,332 @@
import { Component, Input, Output, EventEmitter, OnInit } from "@angular/core";
import { Subscription } from 'rxjs';
import {MatTableDataSource} from '@angular/material/table';
import { BusinessUnitDTO } from "app/commun/model/businessUnitDTO";
import { CollaborateurDTO } from "app/commun/model/collaborateurDTO";
import { CollaborateursService } from "app/commun/services/collaborateurs.service";
import { cles, collaborateurTypeRecherche } from "app/commun/utils/cles";
@Component({
selector: "collaborateurs-table",
templateUrl: "./collaborateurs.table.html",
styleUrls: ["./collaborateurs.table.scss"]
})
export class CollaborateursTableComponent implements OnInit {
/**
* Ordre de tri à envoyer au serveur (true : croissant, false : décroissantà).
*/
asc : boolean = true;
/**
* Numéro de la page à afficher dans le tableau.
*/
numPage: number = 1;
/**
* Nombre d'élément du tableau à affiche en une page.
*/
parPage: number = 15;
/**
* Observable pour faire des requêtes sur le service collaborateur.
*/
private collaborateursDisponiblesSubscription : Subscription;
/**
* Observable pour faire des requêtes sur le service collaborateur.
*/
private collaborateursDisponiblesCountSubscription : Subscription;
/**
* Liste des colonnes du tableau à afficher.
*/
//displayedColumns : string[] = ["businessunit", "collaborateur", "datearrivee", "referent"];
/**
* C'est dans cet objet que seront stockés les collaborateurs à afficher dans le Mat Table côté template.
*/
dataSource : MatTableDataSource<CollaborateurDTO>;
/**
* contenu de la recherche pour trouver un collaborateur.
*/
search: string = "";
/**
* Permet de savoir sur quelle attribut d'un CollaborateurDTO doit être trié le tableau.
*/
tri: string = "collaborateur";
/**
* Liste des business units du collaborateur connecté
*/
bus: Array<BusinessUnitDTO> = [];
/**
* Liste des id des business units des collaborateurs à afficher
*/
private busIds: Array<number> = [];
/**
* Nombre total d'élément du tableau
*/
taille: number = 0;
/**
* Options pour choisir le nombre de page à affiche
*/
pageOption = [ 5, 15, 20, 30, 50];
/**
* Spécifie si la liste des collaborateurs est en cours de chargement dans le tableau.
*/
chargement: boolean = true;
/**
* Date à partir de laquelle les collaborateurs doivent être récupérés en fonction de leur date d'arrivée
*/
dateDebut: Date = undefined;
/**
* Date jusqu'à laquelle les collaborateurs doivent être récupérés en fonction de leur date d'arrivée
*/
dateFin: Date = undefined;
@Input() idReferent: string;
/**
* Indiquer si il s'agit d'une recherche collaborateur, d'un recherche référentEP ou d'une recherche collaborateurEP d'un référent
*/
@Input() typeRecherche: string;
/**
* Indique si il s'agit d'une simple recherche pour afficher des informations ou d'une recherche pour ajouter un référent à un ou plusieurs collaborateurs
*/
@Input() changementReferentEP: boolean = false;
/**
* Indique si la recherche pas BU est activée ou non
*/
@Input() rechercherParBU: boolean = false;
/**
*
*/
@Input() rechercherParDate: boolean = true;
/**
* Liste des rôles des collaborateurs a affichés
*/
@Input() roles: string[] = [];
/**
* Liste des colonnes du tableau à afficher.
*/
@Input() displayedColumns : string[]; //["businessunit", "collaborateur", "datearrivee", "referent"]
/**
* Liste des collaborateursEP actuels du référent
*/
@Input() collaborateursEP: CollaborateurDTO[] = [];
/**
* Liste des collaborateurs ajoutés dont le référent sera mis à jour
*/
@Input() collaborateursAjouts: CollaborateurDTO[] =[];
/**
* Evenement emis lorsqu'une action doit être effectuée
*/
@Output() eventEmitter: EventEmitter<any> = new EventEmitter<any>();
private collaborateurConnecte : CollaborateurDTO;
constructor(private service: CollaborateursService) {}
emitEvent(collaborateur: CollaborateurDTO, type: string) {
const event = {
type : type,
collaborateur: collaborateur
}
this.eventEmitter.emit(event);
}
ngOnInit() {
this.setBUsId();
}
/**
* Mettre à jour les informations à afficher dans la tableau.
* Devra se faire à l'ouverture de la page, au changement de page ou du nombre d'éléments à afficher, au moment d'un tri ou encore lors de l'utilisation de la barre de recherche.
*/
updateDonneesTableau() {
switch(this.typeRecherche) {
case collaborateurTypeRecherche.collaborateurs:
case collaborateurTypeRecherche.referents:
this.updateCollaborateursOuReferents();
break;
case collaborateurTypeRecherche.collaborateursEP:
this.updateCollaborateursEP();
break;
}
}
/**
* Afficher les informations collaborateurs ou référents
*/
updateCollaborateursOuReferents() {
//ne rien afficher si aucune business unit n'est cochée
if(this.busIds.length == 0) {
this.taille = 0;
this.dataSource = new MatTableDataSource(undefined);
return;
}
this.collaborateursDisponiblesSubscription = this.service.getCollaborateurs(this.roles, this.busIds, this.asc, this.numPage, this.parPage, this.search, this.tri, this.dateDebut, this.dateFin).subscribe(
collaborateurs => { console.log(collaborateurs); this.dataSource = new MatTableDataSource(collaborateurs);},
err => console.log(err)
);
this.collaborateursDisponiblesCountSubscription = this.service.getCollaborateursCount(this.roles, this.busIds,this.search, this.dateDebut, this.dateFin).subscribe(
count => { console.log(count); this.taille=count;},
err => console.log(err)
);
}
/**
* Afficher les informations des collaborateursEP d'un référent
*/
updateCollaborateursEP() {
this.collaborateursDisponiblesSubscription = this.service.getCollaborateursByReferent(this.idReferent, this.asc, this.numPage, this.parPage, this.search, this.tri).subscribe(
collaborateurs => { console.log(collaborateurs); this.dataSource = new MatTableDataSource(collaborateurs);},
err => console.log(err)
);
this.collaborateursDisponiblesCountSubscription = this.service.getCollaborateursByReferentCount(this.idReferent, this.search).subscribe(
count => { console.log(count); this.taille=count;},
err => console.log(err)
);
}
/**
* Mettre à undefined la date de début ou la date de fin
* @param val Valeur pour inidiquer quel variable doit être mis à undefined
*/
updateDateToUndefined(val : number) {
if(val == 1)
this.dateDebut = undefined;
if(val == 2)
this.dateFin = undefined;
this.updateDonneesTableau();
}
/**
* Mettre à jour le nomre d'élément à afficher par page et le numéro de la page
* @param event évènement de la pagination
*/
updatePaginationTableau(event){
this.parPage = event.pageSize;
this.numPage = event.pageIndex+1;
this.updateDonneesTableau();
}
/**
* Remettre au début la liste lors d'une recherche via la barre de recherche
*/
setSearch() {
this.numPage = 1;
this.updateDonneesTableau();
}
/**
* Vider la barre de recherche et remettre le tableau à la première page
*/
resetSearch() {
this.search = "";
this.setSearch();
}
/**
* Trier le tableau en fonction de l'évènement de la colonne
* @param e évènement du tri
*/
trierTableau(e) {
this.tri = e.active;
switch(e.direction) {
case "asc":
this.asc = true;
break;
case "desc":
this.asc = false;
break;
}
this.updateDonneesTableau();
}
/**
* création de la liste des business unit du collaborateur connecté pour afficher les checkboxes
*/
setBUsId() {
if(sessionStorage.getItem(cles.sessionKeyConnectee) == undefined){
setTimeout( () => this.setBUsId(), 1000);
}
else {
this.collaborateurConnecte = JSON.parse(sessionStorage.getItem(cles.sessionKeyConnectee));
this.bus = this.collaborateurConnecte.businessUnit.agence.bu;
for(let bu of this.bus) {
this.busIds.push(bu.id);
}
this.updateDonneesTableau();
this.chargement = false;
}
}
/**
* Permettre d'ajouter une classe à la ligne afin de choisir la couleur de cette même ligne
*
* @param collaborateur le collaborateur de la ligne du tableau
*/
setClassCouleurLigne(collaborateur: CollaborateurDTO) {
if(this.contientCollaborateur(this.collaborateursAjouts,collaborateur)) {
return "collaborateurAjoute";
}
if(this.contientCollaborateur(this.collaborateursEP,collaborateur))
return "dejaCollaborateurEP"
return "";
}
contientCollaborateur(listes: CollaborateurDTO[], collaborateur: CollaborateurDTO ) : boolean {
return listes.some(c => c.id == collaborateur.id);
}
/**
* Mettre à jour la liste des
* @param event case cochée ou décochée
* @param bu business unit concerné par la checkbox cochée ou décochée
*/
updateCheckbox(event, bu) {
// si la checkbox a été cochée
if(event) {
this.busIds.push(bu.id)
}
else{
this.busIds = this.busIds.filter( (id) => id != bu.id);
}
this.numPage = 1;
this.updateDonneesTableau();
}
/**
* Une fois la page fermée, il est nécessaire de se désabonner des Oberservable afin d'éviter les fuites mémoires.
*/
ngOnDestroy() {
if(this.collaborateursDisponiblesSubscription != undefined) {
this.collaborateursDisponiblesSubscription.unsubscribe();
}
if(this.collaborateursDisponiblesCountSubscription != undefined) {
this.collaborateursDisponiblesCountSubscription.unsubscribe();
}
}
}

@ -0,0 +1,144 @@
<ng-container *ngIf="chargement">
<mat-spinner></mat-spinner>
</ng-container>
<ng-container *ngIf="!chargement">
<ng-container *ngIf="!estAffichageEP">
<!-- Barre de recherche -->
<mat-form-field>
<mat-label>Rechercher un collaborateur</mat-label>
<input matInput type="text" [(ngModel)]="search" (keyup)="setSearch()">
<button mat-button *ngIf="search" matSuffix mat-icon-button aria-label="Clear" (click)="resetSearch()">
<mat-icon>close</mat-icon>
</button>
</mat-form-field>
<!--Checkboxes des BU-->
<ng-container>
<select-filter
[dataSource]="bus"
[checkedAll]="true"
label="Business Unit"
propertyValueName="nom"
(isSelectedAllEvent)="updateAllBUs($event)"
(isSelectedEvent)="updateBUs($event.isSelected, $event.selectedElement)">
</select-filter>
</ng-container>
<!--Checkboxes des Etats engagement-->
<ng-container>
<select-filter
[dataSource]="etatsDemandesAffiches"
[checkedAll]="true"
label="Etats engagement"
(isSelectedAllEvent)="updateAllEtatsDemande($event)"
(isSelectedEvent)="updateEtatsDemande($event.isSelected, $event.selectedElement)">
</select-filter>
</ng-container>
<!--Checkboxes des Statuts d'EP-->
<ng-container>
<select-filter
[dataSource]="statutsEpAffiches"
[checkedAll]="true"
label="Statuts EP"
(isSelectedAllEvent)="updateAllStatutsEp($event)"
(isSelectedEvent)="updateStatutsEp($event.isSelected, $event.selectedElement)">
</select-filter>
</ng-container>
<ng-container>
<!-- Datepicker début -->
<mat-form-field >
<mat-label>Date de début</mat-label>
<input [(ngModel)]="dateDebut" matInput [matDatepicker]="dateDebutPicker" [max]="dateFin" disabled (dateChange)="updateDataSource()">
<mat-icon *ngIf="this.dateDebut != undefined" matDatepickerToggleIcon (click)="updateDateToUndefined(1)">clear</mat-icon>
<mat-datepicker-toggle matSuffix [for]="dateDebutPicker"></mat-datepicker-toggle>
<mat-datepicker touchUi #dateDebutPicker disabled="false"></mat-datepicker>
</mat-form-field>
<!-- Datepicker fin -->
<mat-form-field>
<mat-label>Date de fin</mat-label>
<input [(ngModel)]="dateFin" matInput [matDatepicker]="dateFinPicker" [min]="dateDebut" disabled (dateChange)="updateDataSource()">
<mat-icon *ngIf="this.dateFin != undefined" matDatepickerToggleIcon (click)="updateDateToUndefined(2)">clear</mat-icon>
<mat-datepicker-toggle matSuffix [for]="dateFinPicker"></mat-datepicker-toggle>
<mat-datepicker touchUi #dateFinPicker disabled="false"></mat-datepicker>
</mat-form-field>
</ng-container>
</ng-container>
<ng-container *ngIf="taille == 0">
<p>Aucune demande de formation à afficher</p>
</ng-container>
<ng-container *ngIf="taille != 0">
<mat-table matSort [dataSource]="dataSource" (matSortChange)="triTableau($event)" matSortActive="{{this.tri}}" matSortDirection="asc" >
<ng-container matColumnDef="businessunit">
<mat-header-cell *matHeaderCellDef mat-sort-header >Agence</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.ep.collaborateur.businessUnit.nom}}</mat-cell>
</ng-container>
<ng-container matColumnDef="collaborateur">
<mat-header-cell mat-header-cell *matHeaderCellDef mat-sort-header>Collabotareur</mat-header-cell>
<!-- Lien vers le détail du collaborateur -->
<mat-cell *matCellDef="let row">
{{row.collaborateur.nom}} {{row.collaborateur.prenom}}
</mat-cell>
</ng-container>
<ng-container matColumnDef="datedemande">
<mat-header-cell *matHeaderCellDef mat-sort-header>Date demande</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.dateDemande | date :'dd/MM/yyyy'}}</mat-cell>
</ng-container>
<ng-container matColumnDef="demanderh">
<mat-header-cell *matHeaderCellDef mat-sort-header>Demande RH</mat-header-cell>
<mat-cell *matCellDef="let row">{{afficherDemandeRH(row.demandeRH)}}</mat-cell>
</ng-container>
<ng-container matColumnDef="ep">
<mat-header-cell *matHeaderCellDef mat-sort-header>EP</mat-header-cell>
<ng-container *matCellDef="let row">
<!-- Lien vers l'EP -->
<mat-cell *ngIf="row.ep" [routerLink]="['/ep',row.ep.id]">
<p>Consulter EP</p>
</mat-cell>
</ng-container>
</ng-container>
<ng-container matColumnDef="libelle">
<mat-header-cell *matHeaderCellDef mat-sort-header>Libellé</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.libelle}}</mat-cell>
</ng-container>
<ng-container matColumnDef="description">
<mat-header-cell *matHeaderCellDef mat-sort-header>Description</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.description}}</mat-cell>
</ng-container>
<ng-container matColumnDef="etat">
<mat-header-cell *matHeaderCellDef mat-sort-header>Réponse</mat-header-cell>
<mat-cell *matCellDef="let row">{{afficherEtat(row.etatDemande)}}</mat-cell>
</ng-container>
<ng-container matColumnDef="datereponse">
<mat-header-cell *matHeaderCellDef mat-sort-header>Date réponse</mat-header-cell>
<ng-container *matCellDef="let row">
<mat-cell *ngIf="row.dateDerniereReponse">{{row.dateDerniereReponse | date :'dd/MM/yyyy'}}</mat-cell>
<mat-cell *ngIf="!row.dateDerniereReponse">{{row.dateDerniereReponse}}</mat-cell>
</ng-container>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" (click)="emitEvent(row)"></mat-row>
</mat-table>
<mat-paginator *ngIf="!estAffichageEP" #paginator
[length] = "taille"
[pageIndex]="numPage-1"
[pageSize]="parPage"
[pageSizeOptions]="pageOption"
(page)="updatePageInfo($event)">
</mat-paginator>
</ng-container>
</ng-container>

@ -0,0 +1,379 @@
import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core";
import { MatTableDataSource } from "@angular/material/table";
import { BusinessUnitDTO } from "app/commun/model/businessUnitDTO";
import { CollaborateurDTO } from "app/commun/model/collaborateurDTO";
import { DemandeFormationDTO } from "app/commun/model/demandeFormationDTO";
import { EtatDemande, afficherEtatDemande } from "app/commun/model/etatDemande";
import { StatutEp, estEPEnCours } from "app/commun/model/statutEp";
import { DemandesFormationService } from "app/commun/services/demandesformation.service";
import { cles } from "app/commun/utils/cles";
import { DemandesFormationsRoutingModule } from "app/demandes-formation/demandes-formation.routing.module";
import { Subscription } from "rxjs";
@Component({
selector: "demandes-formation-table",
templateUrl: "./demandes-formation.table.html"
})
export class DemandesFormationTableComponent implements OnInit {
chargement : boolean = true;
/**
* * Ordre de tri à envoyer au serveur (true : croissant, false : décroissantà).
*/
asc : boolean = true;
/**
* Numéro de la page à afficher dans le tableau.
*/
numPage: number = 1;
/**
* Nombre d'élément du tableau à affiche en une page.
*/
parPage: number = 15;
/**
* Nombre total d'élément du tableau
*/
taille: number = 0;
/**
* Liste des business units du collaborateur connecté
*/
bus: Array<BusinessUnitDTO> = [];
/**
* contenu de la recherche pour trouver un collaborateur.
*/
search: string = "";
/**
* Options pour choisir le nombre de page à affiche
*/
pageOption = [ 5, 15, 20, 30, 50];
/**
* Permet de savoir sur quelle attribut d'un CollaborateurDTO doit être trié le tableau.
*/
tri: string = "collaborateur";
/**
* Liste des id des business units des collaborateurs à afficher
*/
private busIds: Array<number> = [];
/**
* Liste des tous les états demandes
*/
etatsDemandes: Array<EtatDemande> = [
EtatDemande.EnAttente, EtatDemande.Validee,
EtatDemande.Rejetee
];
etatsDemandesAffiches: Array<EtatDemande> = [
EtatDemande.EnAttente, EtatDemande.Validee,
EtatDemande.Rejetee
];
/**
* Liste des tous les statuts d'EP
*/
allStatutsEp: Array<StatutEp> = [
StatutEp.Cree, StatutEp.Disponible,
StatutEp.Saisi, StatutEp.DatesProposees,
StatutEp.AttenteEntretien, StatutEp.Effectue,
StatutEp.SignatureReferent, StatutEp.Signe,
StatutEp.Rejete, StatutEp.Annule
];
statutsEp: Array<StatutEp> = [
StatutEp.Cree, StatutEp.Disponible,
StatutEp.Saisi, StatutEp.DatesProposees,
StatutEp.AttenteEntretien, StatutEp.Effectue,
StatutEp.SignatureReferent, StatutEp.Signe,
StatutEp.Rejete, StatutEp.Annule
];
statutsEpAffiches: Array<string> = [
'Annulé','En cours', 'Rejeté', 'Signé'
];
/**
* Date à partir de laquelle les demandes de formation doivent être récupérées en fonction de leur date de demande
*/
dateDebut: Date = undefined;
/**
* Date jusqu'à laquelle les demandes de formation doivent être récupérées en fonction de leur date de demande
*/
dateFin: Date = undefined;
/**
* Liste des colonnes du tableau à afficher.
*/
@Input() displayedColumns : string[] = [];
@Input() estAffichageEP: boolean = false;
@Input() demandesFormation: DemandeFormationDTO[] = [];
@Output() eventEmitter: EventEmitter<any> = new EventEmitter<any>();
dataSource: MatTableDataSource<DemandeFormationDTO>;
demandesFormationSubscription: Subscription;
demandesFormationCountSubscription: Subscription;
etatsDemandesSubscription: Subscription;
constructor(private demandeFormationService: DemandesFormationService) {}
ngOnInit() {
if(this.estAffichageEP) {
this.taille = this.demandesFormation.length;
this.parPage = this.taille;
this.dataSource = new MatTableDataSource(this.demandesFormation);
this.chargement = false;
}
else
this.setBUsId();
}
emitEvent(demande: DemandesFormationsRoutingModule) {
if(this.eventEmitter != null)
this.eventEmitter.emit(demande);
}
updateDataSource() {
if(this.busIds.length == 0 || this.etatsDemandes.length == 0 || this.statutsEp.length == 0) {
this.taille = 0;
this.dataSource = new MatTableDataSource(undefined);
return;
}
this.demandesFormationSubscription = this.demandeFormationService.getDemandesFormation(this.etatsDemandes, this.busIds, this.statutsEp, this.asc, this.numPage, this.parPage, this.search, this.tri, this.dateDebut, this.dateFin).subscribe(
demandesFormation => this.dataSource = new MatTableDataSource(demandesFormation),
err => console.log(err)
);
this.demandesFormationCountSubscription = this.demandeFormationService.getDemandesFormationCount(this.etatsDemandes, this.busIds, this.statutsEp, this.asc, this.numPage, this.parPage, this.search, this.tri, this.dateDebut, this.dateFin).subscribe(
count => this.taille = count,
err => console.log(err)
);
}
afficherDemandeRH(demandeRH: boolean) {
if (demandeRH)
return 'Oui';
else
return 'Non'
}
afficherEtat(etat: EtatDemande) {
return afficherEtatDemande(etat);
}
/**
* création de la liste des business unit du collaborateur connecté pour afficher les checkboxes
*/
setBUsId() {
if(sessionStorage.getItem(cles.sessionKeyConnectee) == undefined){
setTimeout( () => this.setBUsId(), 1000);
}
else {
const collaborateurConnecte : CollaborateurDTO = JSON.parse(sessionStorage.getItem(cles.sessionKeyConnectee));
this.bus = collaborateurConnecte.businessUnit.agence.bu;
for(let bu of this.bus) {
this.busIds.push(bu.id);
}
this.updateDataSource();
this.chargement = false;
}
}
setSearch() {
this.numPage = 1;
this.updateDataSource();
}
resetSearch() {
this.search = "";
this.setSearch();
}
/**
* Trier le tableau en fonction de l'évènement de la colonne
* @param e évènement du tri
*/
triTableau(e) {
this.tri = e.active;
switch(e.direction) {
case "asc":
this.asc = true;
break;
case "desc":
this.asc = false;
break;
}
this.updateDataSource();
}
/**
* Mettre à jour le nombre d'élément à afficher par page et le numéro de la page
* @param event évènement de la pagination
*/
updatePageInfo(event){
this.parPage = event.pageSize;
this.numPage = event.pageIndex+1;
this.updateDataSource();
}
/**
* Mettre à jour toutes les checkbox des états d'engagement
* @param event case cochée ou décochée
*/
updateAllEtatsDemande(event) {
this.etatsDemandes = [];
// si la checkbox a été cochée
if(event)
this.etatsDemandes = this.etatsDemandesAffiches.map(e => e);
else
this.etatsDemandes = [];
this.setSearch();
}
/**
* Mettre à jour la liste des etats de demande
* @param event
* @param etat
*/
updateEtatsDemande(event:boolean, etat:EtatDemande) {
if(event) {
this.etatsDemandes.push(etat);
}
else
this.etatsDemandes = this.etatsDemandes.filter( e => etat != e);
this.setSearch();
}
getStatutsEpEnCours() {
return [ StatutEp.AttenteEntretien, StatutEp.DatesProposees,
StatutEp.Disponible, StatutEp.Effectue,
StatutEp.Saisi, StatutEp.SignatureReferent ];
}
/**
* Mettre à jour toutes les checkbox des statuts d'EP
* @param event case cochée ou décochée
*/
updateAllStatutsEp(event) {
this.statutsEp = [];
// si la checkbox a été cochée
if(event)
this.statutsEp = this.allStatutsEp;
else
this.statutsEp = [];
this.setSearch();
}
/**
* Mettre à jour la liste des statuts d'EP
* @param event
* @param statutEpAffiche
*/
updateEt
updateStatutsEp(event:boolean, statutEpAffiche:string) {
if(event) {
this.addStatutsEp(statutEpAffiche);
}
else {
this.removeStatutsEp(statutEpAffiche);
}
this.setSearch();
}
addStatutsEp(statutEpAffiche:string) {
switch(statutEpAffiche) {
case "Annulé":
this.statutsEp.push(StatutEp.Annule);
break;
case "En cours":
const statutsEpEnCoursOuCree = this.allStatutsEp.filter(s => estEPEnCours(s) || s == StatutEp.Cree);
this.statutsEp = this.statutsEp.concat(statutsEpEnCoursOuCree);
break;
case "Rejeté":
this.statutsEp.push(StatutEp.Rejete);
break;
case "Signé":
this.statutsEp.push(StatutEp.Signe);
break;
}
}
removeStatutsEp(statutEpAffiche:string) {
switch(statutEpAffiche) {
case "Annulé":
this.statutsEp = this.statutsEp.filter(s => s != StatutEp.Annule)
break;
case "En cours":
this.statutsEp = this.statutsEp.filter(s => !estEPEnCours(s) && s != StatutEp.Cree)
break;
case "Rejeté":
this.statutsEp = this.statutsEp.filter(s => s != StatutEp.Rejete)
break;
case "Signé":
this.statutsEp = this.statutsEp.filter(s => s != StatutEp.Signe)
break;
}
}
/**
* Mettre à jour toutes les checkbox des BU
* @param event case cochée ou décochée
*/
updateAllBUs(event) {
this.busIds = [];
// si la checkbox a été cochée
if(event)
this.bus.map(bu => this.busIds.push(bu.id));
else
this.busIds = [];
this.setSearch();
}
updateBUs(event, bu) {
// si la checkbox a été cochée
if(event) {
this.busIds.push(bu.id)
}
else{
this.busIds = this.busIds.filter( (id) => id != bu.id);
}
this.setSearch();
}
/**
* Mettre à undefined la date de début ou la date de fin
* @param val Valeur pour indiquer quel variable doit être mis à undefined
*/
updateDateToUndefined(val : number) {
if(val == 1)
this.dateDebut = undefined;
if(val == 2)
this.dateFin = undefined;
this.updateDataSource();
}
ngOnDestroy() {
if(this.demandesFormationSubscription != undefined) {
this.demandesFormationSubscription.unsubscribe();
}
if(this.demandesFormationCountSubscription != undefined) {
this.demandesFormationCountSubscription.unsubscribe();
}
}
}

@ -0,0 +1,80 @@
<ng-container *ngIf="chargement">
<mat-spinner></mat-spinner>
</ng-container>
<ng-container *ngIf="!chargement">
<ng-container *ngIf="!estAffichageEP">
<!-- Barre de recherche -->
<mat-form-field>
<mat-label>Rechercher un collaborateur</mat-label>
<input matInput type="text" [(ngModel)]="search" (keyup)="setSearch()">
<mat-button *ngIf="search" matSuffix mat-icon-button aria-label="Clear" (click)="resetSearch()">
<mat-icon>close</mat-icon>
</mat-button>
</mat-form-field>
<!--Checkboxes des BU-->
<ng-container>
<mat-checkbox *ngFor="let bu of bus" (change)="updateBUs($event.checked,bu)" [checked]="true"> {{bu.nom}}</mat-checkbox>
</ng-container>
<!--Checkboxes des Etats engagement-->
<ng-container>
<mat-checkbox *ngFor="let etat of etatsEngagementsAffiches" (change)="updateEtatsEngagement($event.checked,etat)" [checked]="true"> {{afficherEtat(etat)}}</mat-checkbox>
</ng-container>
</ng-container>
<ng-container *ngIf="taille == 0">
<p>Aucun engagements à afficher</p>
</ng-container>
<ng-container *ngIf="taille != 0">
<mat-table [dataSource]="dataSource">
<ng-container matColumnDef="businessunit">
<mat-header-cell *matHeaderCellDef>Agence</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.ep.collaborateur.businessUnit.nom}}</mat-cell>
</ng-container>
<ng-container matColumnDef="collaborateur">
<mat-header-cell *matHeaderCellDef>Collaborateur</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.ep.collaborateur.nom}} {{row.ep.collaborateur.prenom}}</mat-cell>
</ng-container>
<ng-container matColumnDef="action">
<mat-header-cell *matHeaderCellDef>Action</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.action}}</mat-cell>
</ng-container>
<ng-container matColumnDef="dispositif">
<mat-header-cell *matHeaderCellDef>Dispositif</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.dispositif}}</mat-cell>
</ng-container>
<ng-container matColumnDef="modalite">
<mat-header-cell *matHeaderCellDef>Modalité</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.modalite}}</mat-cell>
</ng-container>
<ng-container matColumnDef="datelimite">
<mat-header-cell *matHeaderCellDef>Date limite</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.dateLimite | date :'dd/MM/yyyy'}}</mat-cell>
</ng-container>
<ng-container matColumnDef="etat">
<mat-header-cell *matHeaderCellDef>Etat engagement</mat-header-cell>
<mat-cell *matCellDef="let row">{{afficherEtat(row.etatEngagement)}}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;" (click)="emitEvent(row)"></mat-row>
</mat-table>
<mat-paginator *ngIf="!estAffichageEP" #paginator
[length] = "taille"
[pageIndex]="numPage-1"
[pageSize]="parPage"
[pageSizeOptions]="pageOption"
(page)="updatePaginationTableau($event)">
</mat-paginator>
</ng-container>
</ng-container>

@ -0,0 +1,204 @@
import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core";
import { MatTableDataSource } from "@angular/material/table";
import { BusinessUnitDTO } from "app/commun/model/businessUnitDTO";
import { CollaborateurDTO } from "app/commun/model/collaborateurDTO";
import { EngagementDTO } from "app/commun/model/engagementDTO";
import { EtatEngagement, afficherEtatEngagement } from "app/commun/model/etatEngagement";
import { EngagementsService } from "app/commun/services/engagements.service";
import { cles } from "app/commun/utils/cles";
import { EngagementsRoutingModule } from "app/engagements/engagements.routing.module";
import { Subscription } from "rxjs";
@Component({
selector: "engagements-table",
templateUrl: "./engagements-table.html"
})
export class EngagementTableComponent implements OnInit {
chargement : boolean = true;
/**
* * Ordre de tri à envoyer au serveur (true : croissant, false : décroissantà).
*/
asc : boolean = true;
/**
* Numéro de la page à afficher dans le tableau.
*/
numPage: number = 1;
/**
* Nombre d'élément du tableau à affiche en une page.
*/
parPage: number = 15;
/**
* Nombre total d'élément du tableau
*/
taille: number = 0;
/**
* Liste des business units du collaborateur connecté
*/
bus: Array<BusinessUnitDTO> = [];
/**
* contenu de la recherche pour trouver un collaborateur.
*/
search: string = "";
/**
* Options pour choisir le nombre de page à affiche
*/
pageOption = [ 5, 15, 20, 30, 50];
/**
* Permet de savoir sur quelle attribut d'un CollaborateurDTO doit être trié le tableau.
*/
tri: string = "collaborateur";
/**
* Liste des id des business units des collaborateurs à afficher
*/
private busIds: Array<number> = [];
/**
* Liste des tous les états engagements
*/
etatsEngagements: Array<EtatEngagement> = [
EtatEngagement.EnAttente, EtatEngagement.DateLimitePassee,
EtatEngagement.NonRealisable, EtatEngagement.Respecte
];
etatsEngagementsAffiches: Array<EtatEngagement> = [
EtatEngagement.EnAttente, EtatEngagement.DateLimitePassee,
EtatEngagement.NonRealisable, EtatEngagement.Respecte
];
/**
* Liste des colonnes du tableau à afficher.
*/
@Input() displayedColumns : string[] = [];
/**
* True si il s'agit d'une liste d'engagement affichés lors de la saisie EP référent ou de l'affichage des détails EP
*/
@Input() estAffichageEP: boolean = false;
@Input() engagementsSaisis: EngagementDTO[] = [];
@Output() eventEmitter: EventEmitter<any> = new EventEmitter<any>();
dataSource: MatTableDataSource<EngagementDTO>;
engagementSubscription: Subscription;
engagementCountSubscripton: Subscription;
etatsEngagementsSubscription: Subscription;
constructor(private engagementService: EngagementsService) {}
ngOnInit() {
if(this.estAffichageEP) {
this.taille = this.engagementsSaisis.length;
this.parPage = this.taille;
this.dataSource = new MatTableDataSource(this.engagementsSaisis);
this.chargement = false;
}
else
this.setBUsId();
}
emitEvent(engagement: EngagementsRoutingModule) {
if(this.eventEmitter != null)
this.eventEmitter.emit(engagement);
}
updateDonneesTableau() {
if(this.busIds.length == 0 || this.etatsEngagements.length == 0) {
this.taille = 0;
this.dataSource = new MatTableDataSource(undefined);
return;
}
this.engagementSubscription = this.engagementService.getEngagements(this.busIds, this.etatsEngagements,this.asc, this.numPage, this.parPage, this.search, this.tri).subscribe(
engagements => { console.log(engagements); this.dataSource = new MatTableDataSource(engagements); },
err => console.log(err)
);
this.engagementCountSubscripton = this.engagementService.getEngagementsCount(this.busIds, this.etatsEngagements, this.search).subscribe(
count => this.taille = count,
err => console.log(err)
);
}
afficherEtat(etat: EtatEngagement) {
return afficherEtatEngagement(etat);
}
/**
* création de la liste des business unit du collaborateur connecté pour afficher les checkboxes
*/
setBUsId() {
if(sessionStorage.getItem(cles.sessionKeyConnectee) == undefined){
setTimeout( () => this.setBUsId(), 1000);
}
else {
const collaborateurConnecte : CollaborateurDTO = JSON.parse(sessionStorage.getItem(cles.sessionKeyConnectee));
this.bus = collaborateurConnecte.businessUnit.agence.bu;
for(let bu of this.bus) {
this.busIds.push(bu.id);
}
this.updateDonneesTableau();
this.chargement = false;
}
}
setSearch() {
this.numPage = 1;
this.updateDonneesTableau();
}
resetSearch() {
this.search = "";
this.setSearch();
}
/**
* Mettre à jour le nomre d'élément à afficher par page et le numéro de la page
* @param event évènement de la pagination
*/
updatePaginationTableau(event){
this.parPage = event.pageSize;
this.numPage = event.pageIndex+1;
this.updateDonneesTableau();
}
updateEtatsEngagement(event:boolean, etat:EtatEngagement) {
if(event) {
this.etatsEngagements.push(etat);
}
else
this.etatsEngagements = this.etatsEngagements.filter( e => etat != e);
this.setSearch();
}
updateBUs(event, bu) {
// si la checkbox a été cochée
if(event) {
this.busIds.push(bu.id)
}
else{
this.busIds = this.busIds.filter( (id) => id != bu.id);
}
this.setSearch();
}
ngOnDestroy() {
if(this.engagementSubscription != undefined) {
this.engagementSubscription.unsubscribe();
}
if(this.engagementCountSubscripton != undefined) {
this.engagementCountSubscripton.unsubscribe();
}
}
}

@ -0,0 +1,135 @@
<ng-container *ngIf="chargement">
<mat-spinner></mat-spinner>
</ng-container>
<ng-container *ngIf="!chargement">
<mat-form-field>
<mat-label>Rechercher une un collaborateur</mat-label>
<input matInput type="text" [(ngModel)]="search" (keyup)="setSearch()">
<button mat-button *ngIf="search" matSuffix mat-icon-button aria-label="Clear" (click)="resetSearch()">
<mat-icon>close</mat-icon>
</button>
</mat-form-field>
<ng-container *ngIf="rechercherParBU">
<select-filter
[dataSource]="bus"
[checkedAll]="true"
label="BU"
propertyValueName="nom"
(isSelectedAllEvent)="updateAllCheckbox($event)"
(isSelectedEvent)="updateCheckbox($event.isSelected, $event.selectedElement)">
</select-filter>
<checkbox-filter
[dataSource]="bus"
[checkedAll]="true"
propertyValueName="nom"
(isSelectedAllEvent)="updateAllCheckbox($event)"
(isSelectedEvent)="updateCheckbox($event.isSelected, $event.selectedElement)">
</checkbox-filter>
</ng-container>
<ng-container *ngIf="rechercherParDate">
<!-- Datepicker début -->
<mat-form-field >
<mat-label>Date de début</mat-label>
<input [(ngModel)]="dateDebut" matInput [matDatepicker]="dateDebutPicker" [max]="dateFin" disabled (dateChange)="updateDonneesTableau()">
<mat-icon *ngIf="this.dateDebut != undefined" matDatepickerToggleIcon (click)="updateDateToUndefined(1)">clear</mat-icon>
<mat-datepicker-toggle matSuffix [for]="dateDebutPicker"></mat-datepicker-toggle>
<mat-datepicker touchUi #dateDebutPicker disabled="false"></mat-datepicker>
</mat-form-field>
<!-- Datepicker fin -->
<mat-form-field>
<mat-label>Date de fin</mat-label>
<input [(ngModel)]="dateFin" matInput [matDatepicker]="dateFinPicker" [min]="dateDebut" disabled (dateChange)="updateDonneesTableau()">
<mat-icon *ngIf="this.dateFin != undefined" matDatepickerToggleIcon (click)="updateDateToUndefined(2)">clear</mat-icon>
<mat-datepicker-toggle matSuffix [for]="dateFinPicker"></mat-datepicker-toggle>
<mat-datepicker touchUi #dateFinPicker disabled="false"></mat-datepicker>
</mat-form-field>
</ng-container>
<div>
<mat-slide-toggle *ngIf="typeRechercheEP == epTypeRecherche.EPEnCours " (change)="updateToggle($event)" color="primary" [checked]="epObligatoires">
EP obligatoires
</mat-slide-toggle>
</div>
<mat-table matSort [dataSource]="dataSource" (matSortChange)="trierTableau($event)" matSortDirection="asc">
<ng-container matColumnDef="agence">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>
Business Unit
<checkbox-filter
[dataSource]="bus"
[checkedAll]="true"
propertyValueName="nom"
(isSelectedAllEvent)="updateAllCheckbox($event)"
(isSelectedEvent)="updateCheckbox($event.isSelected, $event.selectedElement)">
</checkbox-filter>
</mat-header-cell>
<mat-cell *matCellDef="let row" > {{row.collaborateur.businessUnit.nom}} </mat-cell>
</ng-container>
<ng-container matColumnDef="collaborateur">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Collaborateur</mat-header-cell>
<mat-cell *matCellDef="let row" (click)="emitEvent('collaborateur', row)"> {{row.collaborateur.nom}} {{row.collaborateur.prenom}} </mat-cell>
</ng-container>
<ng-container matColumnDef="referent">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Référent</mat-header-cell>
<mat-cell *matCellDef="let row" (click)="emitEvent('referent', row)"> {{row.referent.nom}} {{row.referent.prenom}}</mat-cell>
</ng-container>
<ng-container matColumnDef="datearrivee">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Date d'embauche</mat-header-cell>
<mat-cell *matCellDef="let row"> {{row.collaborateur.dateArrivee | date : 'dd/MM/yyyy'}} </mat-cell>
</ng-container>
<ng-container matColumnDef="statutep">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Staut de l'EP</mat-header-cell>
<mat-cell *matCellDef="let row"> {{ afficherStatutEP(row.statut)}} </mat-cell>
</ng-container>
<ng-container matColumnDef="typeep">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Type EP</mat-header-cell>
<mat-cell *matCellDef="let row"> {{ row.type }}</mat-cell>
</ng-container>
<ng-container matColumnDef="dateentretien">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Date entretien</mat-header-cell>
<mat-cell *matCellDef="let row"> {{ row.datePrevisionnelle | date : 'dd/MM/yyyy'}} </mat-cell>
</ng-container>
<ng-container matColumnDef="datedisponibilite">
<mat-header-cell *matHeaderCellDef>Date disponibilité</mat-header-cell>
<mat-cell *matCellDef="let row"> {{ row.dateDisponibilite | date : 'dd/MM/yyyy'}} </mat-cell>
</ng-container>
<ng-container matColumnDef="consultation">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear></mat-header-cell>
<ng-container *matCellDef="let row" >
<mat-cell *ngIf="!EstEPEnAttente(row.statut)" (click)="emitEvent('ep', row)"> Consulter EP </mat-cell>
<mat-cell *ngIf="EstEPEnAttente(row.statut)"> EP indisponible </mat-cell>
</ng-container>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
<mat-paginator #paginator
[length] = "taille"
[pageIndex]="numPage-1"
[pageSize]="parPage"
[pageSizeOptions]="pageOption"
(page)="updatePaginationTableau($event)"
>
</mat-paginator>
</ng-container>

@ -0,0 +1,322 @@
import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core";
import { MatSlideToggleChange } from "@angular/material/slide-toggle";
import { MatTableDataSource } from "@angular/material/table";
import { BusinessUnitDTO } from "app/commun/model/businessUnitDTO";
import { CollaborateurDTO } from "app/commun/model/collaborateurDTO";
import { EpInformationDTO } from "app/commun/model/epInformationDTO";
import { StatutEp, affichageStatut, estEnAttente } from "app/commun/model/statutEp";
import { EpService } from "app/commun/services/ep.service";
import { epTypeRecherche, cles } from "app/commun/utils/cles";
import { Subscription } from "rxjs";
@Component({
selector: "ep-table",
templateUrl: "./ep-table.html"
})
export class EpTableComponent implements OnInit{
chargement: boolean = true;
epTypeRecherche :any = epTypeRecherche;
/**
* * Ordre de tri à envoyer au serveur (true : croissant, false : décroissantà).
*/
asc : boolean = true;
/**
* Numéro de la page à afficher dans le tableau.
*/
numPage: number = 1;
/**
* Nombre d'élément du tableau à affiche en une page.
*/
parPage: number = 15;
/**
* Nombre total d'élément du tableau
*/
taille: number = 0;
/**
* Liste des business units du collaborateur connecté
*/
bus: Array<BusinessUnitDTO> = [];
/**
* contenu de la recherche pour trouver un collaborateur.
*/
search: string = "";
/**
* Options pour choisir le nombre de page à affiche
*/
pageOption = [ 5, 15, 20, 30, 50];
/**
* Permet de savoir sur quelle attribut d'un CollaborateurDTO doit être trié le tableau.
*/
tri: string = "dateprevisionnelle";
/**
* Liste des id des business units des collaborateurs à afficher
*/
private busIds: Array<number> = [];
/**
* Permet d'indiquer si l'on ne récupère que les EP obligatoires ou non (lors de la récupération des EP en cours uniquement)
*/
epObligatoires: boolean = false;
dateDebut : Date;
dateFin: Date;
dataSource : MatTableDataSource<EpInformationDTO>;
@Input() idCollaborateur : string;
@Input() typeRechercheEP : string;
@Input() displayedColumns: string[];
@Input() rechercherParBU: boolean = true;
@Input() rechercherParDate: boolean = true;
@Output() eventEmitter: EventEmitter<any> = new EventEmitter<any>();
epSubscription: Subscription;
epCountSubscription: Subscription;
constructor(private epService: EpService) {}
ngOnInit() {
this.setBUsId();
}
emitEvent(type:string, ep: EpInformationDTO) {
this.eventEmitter.emit({
type: type,
ep: ep
});
}
updateDonneesTableau() {
switch(this.typeRechercheEP) {
case epTypeRecherche.EPEnCours:
this.getEPEnCours();
break;
case epTypeRecherche.EPSignes:
this.getEPSignes();
break;
case epTypeRecherche.RechercheEPReferentEnCours:
this.getEPEnCoursReferent();
break;
case epTypeRecherche.RechercheEPReferentSignes:
this.getEPSignesReferent();
break;
case epTypeRecherche.RechercheEPCollaborateursSignes:
this.getEpsignesCollaborateur();
break;
}
}
getEpsignesCollaborateur() {
this.epSubscription = this.epService.getEPSignesCollaborateur(this.idCollaborateur).subscribe(
eps => this.dataSource = new MatTableDataSource(eps),
err => console.log(err),
);
}
getEPSignesReferent() {
this.epSubscription = this.epService.getEPSignesReferent(this.idCollaborateur, this.asc, this.numPage, this.parPage, this.search, this.tri, this.dateDebut, this.dateFin).subscribe(
eps => {
this.dataSource = new MatTableDataSource(eps);
this.epCountSubscription = this.epService.getEPSignesReferentCount(this.idCollaborateur, this.search, this.dateDebut, this.dateFin).subscribe(
count => this.taille = count,
err => console.log(err)
);
},
err => console.log(err)
);
}
getEPEnCoursReferent() {
this.epSubscription = this.epService.getEPEnCoursReferent(this.idCollaborateur, this.asc, this.numPage, this.parPage, this.search, this.tri, this.dateDebut, this.dateFin ).subscribe(
eps => {
this.dataSource = new MatTableDataSource(eps);
this.epCountSubscription = this.epService.getEPSignesReferentCount(this.idCollaborateur, this.search, this.dateDebut, this.dateFin ).subscribe(
count => this.taille = count,
err => console.log(err)
);
},
err => console.log(err)
);
}
getEPEnCours() {
console.log(this.epObligatoires);
this.epSubscription = this.epService.getEPEnCours(this.busIds, this.asc, this.numPage, this.parPage, this.search, this.epObligatoires, this.tri, this.dateDebut, this.dateFin).subscribe(
eps => {
this.dataSource = new MatTableDataSource(eps);
this.epCountSubscription = this.epService.getEPEnCoursCount(this.busIds,this.search, this.epObligatoires, this.dateDebut, this.dateFin).subscribe(
count => {
console.log(count);
this.taille = count
},
err => console.log(err)
);
},
err => console.log(err)
);
}
afficherStatutEP(statut: StatutEp) {
return affichageStatut(statut);
}
EstEPEnAttente(statut: StatutEp) {
return estEnAttente(statut);
}
getEPSignes() {
this.epSubscription = this.epService.getEPSignes(this.busIds, this.asc, this.numPage, this.parPage, this.search, this.tri, this.dateDebut, this.dateFin).subscribe(
eps => {
console.log(eps);
this.dataSource = new MatTableDataSource(eps);
this.epCountSubscription = this.epService.getEPSignesCount(this.busIds, this.search, this.dateDebut, this.dateFin).subscribe(
count => this.taille = count,
err => console.log(err)
);
},
err => console.log(err)
);
}
updateToggle(event :MatSlideToggleChange) {
this.epObligatoires = event.checked;
this.updateDonneesTableau();
}
/**
* création de la liste des business unit du collaborateur connecté pour afficher les checkboxes
*/
setBUsId() {
if(sessionStorage.getItem(cles.sessionKeyConnectee) == undefined){
setTimeout( () => this.setBUsId(), 1000);
}
else {
const collaborateurConnecte : CollaborateurDTO = JSON.parse(sessionStorage.getItem(cles.sessionKeyConnectee));
this.bus = collaborateurConnecte.businessUnit.agence.bu;
/*for(let bu of this.bus) {
this.busIds.push(bu.id);
}*/
this.updateDonneesTableau();
this.chargement = false;
}
}
/**
* Mettre à undefined la date de début ou la date de fin
* @param val Valeur pour inidiquer quel variable doit être mis à undefined
*/
updateDateToUndefined(val : number) {
if(val == 1)
this.dateDebut = undefined;
if(val == 2)
this.dateFin = undefined;
this.updateDonneesTableau();
}
/**
* Mettre à jour le nomre d'élément à afficher par page et le numéro de la page
* @param event évènement de la pagination
*/
updatePaginationTableau(event){
this.parPage = event.pageSize;
this.numPage = event.pageIndex+1;
this.updateDonneesTableau();
}
/**
* Remettre au début la liste lors d'une recherche via la barre de recherche
*/
setSearch() {
this.numPage = 1;
this.updateDonneesTableau();
}
/**
* Vider la barre de recherche et remettre le tableau à la première page
*/
resetSearch() {
this.search = "";
this.setSearch();
}
/**
* Mettre à jour toutes les checkox
* @param event case cochée ou décochée
* */
updateAllCheckbox(event) {
this.busIds = [];
// si la checkbox a été cochée
if(event)
this.bus.map(statut => this.busIds.push(statut.id));
else
this.busIds = [];
this.numPage = 1;
this.updateDonneesTableau();
}
/**
* Mettre à jour la liste des
* @param event case cochée ou décochée
* @param bu business unit concerné par la checkbox cochée ou décochée
*/
updateCheckbox(event, bu) {
// si la checkbox a été cochée
if(event) {
this.busIds.push(bu.id)
}
else{
this.busIds = this.busIds.filter( (id) => id != bu.id);
}
this.numPage = 1;
this.updateDonneesTableau();
}
/**
* Trier le tableau en fonction de l'évènement de la colonne
* @param e évènement du tri
*/
trierTableau(e) {
this.tri = e.active;
switch(e.direction) {
case "asc":
this.asc = true;
break;
case "desc":
this.asc = false;
break;
}
this.updateDonneesTableau();
}
ngDestroy() {
if(!this.epSubscription != undefined) {
this.epSubscription.unsubscribe();
}
if(!this.epCountSubscription != undefined) {
this.epCountSubscription.unsubscribe();
}
}
}

@ -0,0 +1,84 @@
<ng-container *ngIf="chargement">
<mat-spinner></mat-spinner>
</ng-container>
<ng-container *ngIf="!chargement">
<!-- Barre de recherche -->
<mat-form-field>
<mat-label>Rechercher une formation</mat-label>
<input matInput type="text" [(ngModel)]="search" (keyup)="setSearch()">
<button mat-button *ngIf="search" matSuffix mat-icon-button aria-label="Clear" (click)="resetSearch()">
<mat-icon>close</mat-icon>
</button>
</mat-form-field>
<!--Checkboxes des statuts de formation-->
<select-filter
[dataSource]="statutsFormation"
[checkedAll]="false"
label="Statuts"
propertyValueName="libelle"
(isSelectedAllEvent)="updateAllCheckbox($event)"
(isSelectedEvent)="updateCheckbox($event.isSelected, $event.selectedElement)">
</select-filter>
<!-- Affichage de la liste des formations -->
<mat-table matSort [dataSource]="dataSource" (matSortChange)="trierTableau($event)" matSortActive="{{this.tri}}" matSortDirection="asc" >
<ng-container matColumnDef="intitule">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Intitulé</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.intitule }}</mat-cell>
</ng-container>
<ng-container matColumnDef=participants>
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Nb participants</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.nbParticipations }}</mat-cell>
</ng-container>
<ng-container matColumnDef="date">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Date prévisionnelle</mat-header-cell>
<mat-cell *matCellDef="let row">{{ row.dateDebut | date:'dd/MM/yyyy à hh:mm' }}</mat-cell>
</ng-container>
<ng-container matColumnDef="origine">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Origine</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.origine.libelle}}</mat-cell>
</ng-container>
<ng-container matColumnDef="statut">
<!--Checkboxes des statuts de formation-->
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Statut
<checkbox-filter
[dataSource]="statutsFormation"
[checkedAll]="false"
propertyValueName="libelle"
(isSelectedAllEvent)="updateAllCheckbox($event)"
(isSelectedEvent)="updateCheckbox($event.isSelected, $event.selectedElement)">
</checkbox-filter>
</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.statut.libelle}}</mat-cell>
</ng-container>
<ng-container matColumnDef="certification">
<mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Certifiée</mat-header-cell>
<mat-cell *matCellDef="let row">{{estCertifiee(row.estCertifiee)}}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<!-- Lien vers le détail d'une formation-->
<mat-row *matRowDef="let row; columns: displayedColumns;" [routerLink]="['/formations',row.id]"></mat-row>
</mat-table>
<!--[length]="taille"-->
<mat-paginator #paginator
[length] = "taille"
[pageIndex]="numPage-1"
[pageSize]="parPage"
[pageSizeOptions]="pageOption"
(page)="updatePaginationTableau($event)"
>
</mat-paginator>
</ng-container>

@ -0,0 +1,258 @@
import { Component, Input, OnInit } from "@angular/core";
import { Subscription } from 'rxjs';
import {MatTableDataSource} from '@angular/material/table';
import { CollaborateurDTO } from "app/commun/model/collaborateurDTO";
import { FormationDetailsDTO } from "app/commun/model/formationDetailsDTO";
import { StatutFormationDTO } from "app/commun/model/statutFormationDTO";
import { FormationsService } from "app/commun/services/formations.service";
import { cles } from "app/commun/utils/cles";
@Component({
selector: "formations-table",
templateUrl: "./formations.table.html",
styleUrls: ["./formations.table.scss"]
})
export class FormationsTableComponent implements OnInit {
/**
* Ordre de tri à envoyer au serveur (true : croissant, false : décroissantà).
*/
asc : boolean = true;
/**
* Numéro de la page à afficher dans le tableau.
*/
numPage: number = 1;
/**
* Nombre d'élément du tableau à affiche en une page.
*/
parPage: number = 15;
/**
* Observable pour faire des requêtes sur le service formation.
*/
private formationsDisponiblesSubscription : Subscription;
/**
* Observable pour faire des requêtes sur le service formation.
*/
private formationsDisponiblesCountSubscription : Subscription;
/**
* C'est dans cet objet que seront stockés les formations à afficher dans le Mat Table côté template.
*/
dataSource : MatTableDataSource<FormationDetailsDTO>;
/**
* contenu de la recherche pour trouver une formation.
*/
search: string = "";
/**
* Permet de savoir sur quelle attribut d'un FormationDetailsDTO doit être trié le tableau.
*/
tri: string = "intitule";
/**
* Id agence collaborateur connecté
*/
idAgence: number;
/**
* Liste des statuts de formation
*/
statutsFormation: Array<StatutFormationDTO> = [];
/**
* Liste des id statuts à afficher
*/
private idStatuts: Array<number> = [];
/**
* Spécifie si les checkbox des statuts de formation sont toutes cochées ou non.
*/
isStatutsSelectedAll: boolean = false;
/**
* Nombre total d'élément du tableau
*/
taille: number = 0;
/**
* Options pour choisir le nombre de page à affiche
*/
pageOption = [ 5, 15, 20, 30, 50];
/**
* Spécifie si la liste des formations est en cours de chargement dans le tableau.
*/
chargement: boolean = true;
/**
* Indique si la recherche par statut de formation est activée ou non
*/
@Input() rechercherParStatutFormation: boolean = false;
/**
* Liste des colonnes du tableau à afficher.
*/
@Input() displayedColumns : string[];
private collaborateurConnecte : CollaborateurDTO;
constructor(private formationsService: FormationsService) {}
ngOnInit() {
this.getStatutsFormation();
this.setCollaborateurConnecte();
}
/**
* Mettre à jour les informations à afficher dans la tableau.
* Devra se faire à l'ouverture de la page, au changement de page ou du nombre d'éléments à afficher, au moment d'un tri ou encore lors de l'utilisation de la barre de recherche.
*/
updateDonneesTableau() {
this.updateFormations();
}
/**
* Récupère les statuts de formation
*/
getStatutsFormation()
{
this.formationsService.getStatutsFormation().subscribe(
statuts => this.statutsFormation = statuts,
err => console.log(err)
);
}
/**
* Mettre à jour les informations à afficher dans la tableau.
* Devra se faire à l'ouverture de la page, au changement de page ou du nombre d'éléments à afficher, au moment d'un tri ou encore lors de l'utilisation de la barre de recherche.
*/
updateFormations() {
this.formationsDisponiblesSubscription = this.formationsService.getFormations(this.idAgence,this.idStatuts,this.asc, this.numPage, this.parPage, this.search, this.tri).subscribe(
formations => this.dataSource = new MatTableDataSource(formations),
err => console.log(err)
)
this.formationsDisponiblesCountSubscription = this.formationsService.getFormationsCount(this.idAgence,this.idStatuts, this.search).subscribe(
count => this.taille=count,
err => console.log(err)
);
}
estCertifiee(certifiee: boolean) {
if(certifiee)
return "Oui";
return "Non";
}
setCollaborateurConnecte()
{
if(sessionStorage.getItem(cles.sessionKeyConnectee) == undefined){
setTimeout( () => this.setCollaborateurConnecte(), 1000);
}
else {
this.collaborateurConnecte = JSON.parse(sessionStorage.getItem(cles.sessionKeyConnectee));
this.idAgence = this.collaborateurConnecte.businessUnit.agence.id;
this.updateDonneesTableau();
this.chargement = false;
}
}
/**
* Mettre à jour le nomre d'élément à afficher par page et le numéro de la page
* @param event évènement de la pagination
*/
updatePaginationTableau(event){
this.parPage = event.pageSize;
this.numPage = event.pageIndex+1;
this.updateDonneesTableau();
}
/**
* Remettre au début la liste lors d'une recherche via la barre de recherche
*/
setSearch() {
this.numPage = 1;
this.updateDonneesTableau();
}
/**
* Vider la barre de recherche et remettre le tableau à la première page
*/
resetSearch() {
this.search = "";
this.setSearch();
}
/**
* Trier le tableau en fonction de l'évènement de la colonne
* @param e évènement du tri
*/
trierTableau(e) {
this.tri = e.active;
switch(e.direction) {
case "asc":
this.asc = true;
break;
case "desc":
this.asc = false;
break;
}
this.updateDonneesTableau();
}
/**
* Mettre à jour toutes les checkox
* @param event case cochée ou décochée
*/
updateAllCheckbox(event) {
this.idStatuts = [];
// si la checkbox a été cochée
if(event)
this.statutsFormation.map(statut => this.idStatuts.push(statut.id));
else
this.idStatuts = [];
this.numPage = 1;
this.updateDonneesTableau();
}
/**
* Mettre à jour la liste des checkox
* @param event case cochée ou décochée
* @param statut statut concerné par la checkbox cochée ou décochée
*/
updateCheckbox(event, statut) {
// si la checkbox a été cochée
if(event) {
this.idStatuts.push(statut.id)
}
else{
this.idStatuts = this.idStatuts.filter(id => id != statut.id);
}
this.numPage = 1;
this.updateDonneesTableau();
}
/**
* Une fois la page fermée, il est nécessaire de se désabonner des Oberservable afin d'éviter les fuites mémoires.
*/
ngOnDestroy() {
if(this.formationsDisponiblesSubscription != undefined) {
this.formationsDisponiblesSubscription.unsubscribe();
}
if(this.formationsDisponiblesCountSubscription != undefined) {
this.formationsDisponiblesCountSubscription.unsubscribe();
}
}
}

@ -0,0 +1,71 @@
<ng-container>
<!-- Barre de recherche -->
<mat-form-field>
<mat-label>Rechercher </mat-label>
<input matInput type="text" [(ngModel)]="search" (keyup)="setSearch()">
<button mat-button *ngIf="search" matSuffix mat-icon-button aria-label="Clear" (click)="resetSearch()">
<mat-icon>close</mat-icon>
</button>
</mat-form-field>
<!-- Affichage de la liste des participations -->
<mat-table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="collaborateur">
<mat-header-cell mat-header-cell *matHeaderCellDef mat-sort-header>Collabotareur</mat-header-cell>
<!-- Lien vers le détail du collaborateur -->
<mat-cell *matCellDef="let row" [routerLink]="['/collaborateurs', row.collaborateur.id]">
{{row.collaborateur.nom}} {{row.collaborateur.prenom}}
</mat-cell>
</ng-container>
<ng-container matColumnDef="intitule">
<mat-header-cell mat-header-cell *matHeaderCellDef mat-sort-header>Intitulé</mat-header-cell>
<mat-cell *matCellDef="let row">
{{row.intitule}}
</mat-cell>
</ng-container>
<ng-container matColumnDef="statut">
<mat-header-cell mat-header-cell *matHeaderCellDef mat-sort-header>Statut</mat-header-cell>
<mat-cell *matCellDef="let row">
{{row.statut.libelle}}
</mat-cell>
</ng-container>
<ng-container matColumnDef="dateCreation">
<mat-header-cell mat-header-cell *matHeaderCellDef mat-sort-header>Inscrit le</mat-header-cell>
<mat-cell *matCellDef="let row">{{row.dateCreation | date :'dd/MM/yy à HH:mm'}}</mat-cell>
</ng-container>
<ng-container matColumnDef="ep">
<mat-header-cell mat-header-cell *matHeaderCellDef mat-sort-header>EP</mat-header-cell>
<ng-container *matCellDef="let row">
<!-- Lien vers l'EP -->
<mat-cell *ngIf="estEPDisponible(row.ep.statut)" [routerLink]="['/ep',row.ep.id]">
<p>Consulter EP</p>
</mat-cell>
<mat-cell *ngIf="estEnAttente(row.ep.statut)">
<p>Attente prochain EP</p>
</mat-cell>
</ng-container>
</ng-container>
<ng-container matColumnDef="evaluation">
<mat-header-cell mat-header-cell *matHeaderCellDef mat-sort-header>Evaluation</mat-header-cell>
<ng-container *matCellDef="let row">
<!-- Lien vers l'évaluation du collaborateur -->
<mat-cell *ngIf="row.estEvaluee" [routerLink]="['/collaborateurs',row.collaborateur.id,'formations','evaluation',row.id]">
<p>Voir évaluation</p>
</mat-cell>
<mat-cell *ngIf="!row.estEvaluee">
<p>Attente évaluation</p>
</mat-cell>
</ng-container>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
<mat-paginator [pageSizeOptions]="pageOption"></mat-paginator>
</ng-container>

@ -0,0 +1,129 @@
import { Component, Input, OnInit, OnChanges, ViewChild, AfterViewInit} from "@angular/core";
import {MatPaginator} from '@angular/material/paginator';
import {MatSort} from '@angular/material/sort';
import {MatTableDataSource} from '@angular/material/table';
import { DatePipe } from "@angular/common";
import { ParticipationFormationDTO } from "app/commun/model/participationFormationDTO";
import { StatutEp, estEnAttente, estEPDisponible } from "app/commun/model/statutEp";
@Component({
selector: "participations-formation-table",
templateUrl: "./participations-formation.table.html",
styleUrls: ["./participations-formation.table.scss"]
})
export class ParticipationsFormationTableComponent implements OnInit, OnChanges, AfterViewInit {
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
/**
* C'est dans cet objet que seront stockés les participations à afficher dans le Mat Table côté template.
*/
dataSource : MatTableDataSource<ParticipationFormationDTO>;
/**
* Liste des participations
*/
@Input() participations : ParticipationFormationDTO[];
/**
* contenu de la recherche pour trouver une formation.
*/
search: string = "";
/**
* Options pour choisir le nombre de page à affiche
*/
pageOption = [ 5, 15, 20, 30, 50];
/**
* DatePipe pour rechercher une date dans la barre de recherche
*/
pipe: DatePipe = new DatePipe('fr');
/**
* Liste des colonnes du tableau à afficher.
*/
@Input() displayedColumns : string[];
constructor() {
}
ngOnInit() {
}
ngOnChanges() {
if(this.participations.length > 0) {
this.dataSource = new MatTableDataSource(this.participations);
this.dataSource.sortingDataAccessor = (item, property) => {
switch(property) {
case 'collaborateur': return item.collaborateur.nom + " "+ item.collaborateur.prenom;
case 'ep': return item.ep.statut;
case 'evaluation': return item.estEvaluee;
case 'statut': return item.statut.libelle;
default: return item[property];
}
};
this.dataSource.filterPredicate = (data, filter) => {
const formatted=this.pipe.transform(data.dateCreation,'dd/MM/yyyy');
return formatted.indexOf(filter) >= 0 ||
data.collaborateur.nom.toLocaleLowerCase().includes(filter) ||
data.collaborateur.prenom.toLocaleLowerCase().includes(filter) ||
data.intitule.toLocaleLowerCase().includes(filter) ||
data.statut.libelle.toLocaleLowerCase().includes(filter);
};
}
}
ngAfterViewInit() {
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
estEnAttente (statut:StatutEp) {
return estEnAttente(statut);
}
estEPDisponible (statut:StatutEp) {
return estEPDisponible(statut);
}
setSearch() {
this.dataSource.filter = this.search.trim().toLowerCase();
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
/**
* Vider la barre de recherche et remettre le tableau à la première page
*/
resetSearch() {
this.search = "";
this.setSearch();
}
/**
* Une fois la page fermée, il est nécessaire de se désabonner des Oberservable afin d'éviter les fuites mémoires.
*/
ngOnDestroy() {
}
}

@ -0,0 +1,37 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* DTO concernant l'affichage d'une note dans un tableau.
*/
export interface AffichageNoteDTO {
/**
* Id de la note
*/
id: number;
/**
* Titre de la note
*/
titre: string;
/**
* Id du collaborateur concerné par la note
*/
idCollaborateur: string;
/**
* Nom et prénom du collaborateur concerné par la note
*/
collaborateur?: string;
/**
* Date à laquelle la note a é mise à jour pour la dernière fois
*/
dateMiseAJour: Date;
}

@ -2,17 +2,26 @@
* API du serveur de l'application de digitalisation des EP * API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire. * API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
* *
* OpenAPI spec version: 1.2.0 * OpenAPI spec version: 1.3.6
* *
* *
* NOTE: This class is auto generated by the swagger code generator program. * NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git * https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually. * Do not edit the class manually.
*/ */
import { DemandeFormationModel } from './demandeFormationModel'; import { BusinessUnitDTO } from './businessUnitDTO';
export interface ThemeModel { /**
* DTO contenant lagence à laquelle appartient le collaborateur.
*/
export interface AgenceDTO {
/**
* Id de l'agence
*/
id: number; id: number;
/**
* Nom de l'agence
*/
nom: string; nom: string;
demandesFormation: Array<DemandeFormationModel>; bu: Array<BusinessUnitDTO>;
} }

@ -0,0 +1,33 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* DTO lié à la demande d'augmentation du salaire effectuée lors d'un EP.
*/
export interface AugmentationSalaireDTO {
/**
* Id de l'augmentation du salaire
*/
id: number;
/**
* Pourcentage de l'augmentation du salaire
*/
augmentation: number;
/**
* Pourcentage de l'augmentation de la prime de mission
*/
augmentationPrimeMission?: number;
/**
* Message laissé par le référent suite à l'augmentation du salaire
*/
message?: string;
}

@ -2,22 +2,26 @@
* API du serveur de l'application de digitalisation des EP * API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire. * API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
* *
* OpenAPI spec version: 1.2.0 * OpenAPI spec version: 1.3.6
* *
* *
* NOTE: This class is auto generated by the swagger code generator program. * NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git * https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually. * Do not edit the class manually.
*/ */
import { BusinessUnitModel } from './businessUnitModel'; import { AgenceDTO } from './agenceDTO';
export interface CollaborateurModel { /**
id: string; * DTO contenant la Business Unit à laquelle appartient le collaborateur.
*/
export interface BusinessUnitDTO {
/**
* Id de la Business Unit
*/
id: number;
/**
* Nom de la Business Unit
*/
nom: string; nom: string;
prenom: string; agence?: AgenceDTO;
mailApside: string;
dateArrivee?: Date;
dateDepart?: Date;
businessUnit?: BusinessUnitModel;
referent: CollaborateurModel;
} }

@ -0,0 +1,41 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { TypeChamps } from './typeChamps';
import { TypeSaisie } from './typeSaisie';
/**
* DTO concernant les champs des documents.
*/
export interface ChampDTO {
/**
* Id du champ
*/
id: number;
/**
* Texte du champ
*/
texte: string;
/**
* Section à laquelle appartient le champ
*/
section: string;
/**
* Sous-section à laquelle appartient le champ
*/
soussection?: string;
/**
* Ordre du champ dans sa section ou sous-section
*/
ordre: number;
typeChamp: TypeChamps;
typeSaisie: TypeSaisie;
}

@ -0,0 +1,44 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { BusinessUnitDTO } from './businessUnitDTO';
/**
* DTO contenant les données du collaborateur.
*/
export interface CollaborateurDTO {
/**
* Id du collaborateur
*/
id: string;
/**
* Nom du collaborateur
*/
nom: string;
/**
* Prénom du collaborateur
*/
prenom: string;
/**
* Mail Apside du collaborateur
*/
mailApside: string;
/**
* Date à laquelle le collaborateur a é embauché
*/
dateArrivee: Date;
/**
* Date à laquelle le collaborateur a quitté l'entreprise
*/
dateDepart?: Date;
businessUnit?: BusinessUnitDTO;
referent?: CollaborateurDTO;
}

@ -0,0 +1,30 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.7
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* DTO contenant le commentaire d'un assistant sur l'EP.
*/
export interface CommentaireAssistantDTO {
/**
* Id du commentaire assistant
*/
id?: number;
/**
* Id de l'assistant qui a écrit le commentaire
*/
idAssistant: string;
assistant?: string;
/**
* Le commentaire de lassistant
*/
commentaire: string;
}

@ -0,0 +1,43 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { CollaborateurDTO } from './collaborateurDTO';
import { EpInformationDTO } from './epInformationDTO';
import { EtatDemande } from './etatDemande';
/**
* DTO pour la gestion des demandes de délégation.
*/
export interface DemandeDelegationDTO {
/**
* Id de le demande de délégation
*/
id?: number;
referent: CollaborateurDTO;
ep: EpInformationDTO;
/**
* Date à laquelle la demande de délégation a é effectuée
*/
dateDemande: Date;
/**
* Raison pour laquelle la demande a é effectuée
*/
raisonDemande: string;
etatDemande: EtatDemande;
/**
* Date à laquelle la réponse a é donnée
*/
dateReponse?: Date;
/**
* Raison pour laquelle la demande a é refusée
*/
raisonRefus?: string;
}

@ -0,0 +1,40 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { CollaborateurDTO } from './collaborateurDTO';
import { EpInformationDTO } from './epInformationDTO';
import { EtatDemande } from './etatDemande';
/**
* DTO pour afficher et gérer les demandes d'EPI.
*/
export interface DemandeEPIDTO {
/**
* Id de la demande d'EPI
*/
id?: number;
collaborateur: CollaborateurDTO;
referent?: CollaborateurDTO;
/**
* Date à laquelle la demande d'EPI a é effectué
*/
dateDemande: Date;
etatDemande: EtatDemande;
/**
* Date à laquelle le référent a répondu
*/
dateReponse?: Date;
/**
* Raison pour laquelle la demande d'EPI a é rejeté
*/
raisonRefus?: string;
ep?: EpInformationDTO;
}

@ -0,0 +1,55 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { CollaborateurDTO } from './collaborateurDTO';
import { EpInformationDTO } from './epInformationDTO';
import { EtatDemande } from './etatDemande';
import { FormationDetailsDTO } from './formationDetailsDTO';
import { OrigineDemandeFormationDTO } from './origineDemandeFormationDTO';
/**
* DTO permettant de gérer les demandes de formation.
*/
export interface DemandeFormationDTO {
/**
* Id de la demande de formation
*/
id?: number;
/**
* Libellé de la demande de formation
*/
libelle: string;
/**
* Description détaillée de la demande de formation
*/
description: string;
/**
* Indique s'il s'agit d'une demande de formation créée par une RH ou non
*/
demandeRH: boolean;
/**
* Date à laquelle la demande a é effectuée
*/
dateDemande: Date;
etatDemande: EtatDemande;
/**
* Commentaire expliquant la raison pour laquelle la demande de formation a é refusée
*/
commentaireRefus?: string;
/**
* Date à laquelle la demande de formation a reçu une réponse pour la dernière fois
*/
dateDerniereReponse?: Date;
origine?: OrigineDemandeFormationDTO;
collaborateur?: CollaborateurDTO;
ep?: EpInformationDTO;
formation?: FormationDetailsDTO;
}

@ -0,0 +1,43 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { CollaborateurDTO } from './collaborateurDTO';
/**
* DTO contenant le détail complet dune note.
*/
export interface DetailsNoteDTO {
/**
* Id de la note
*/
id?: number;
/**
* Titre de la note
*/
titre: string;
/**
* Contenu de la note
*/
texte: string;
/**
* Id du référent qui a écrit cette note
*/
idAuteur: string;
collaborateur: CollaborateurDTO;
/**
* Date à laquelle la note a é créée
*/
dateCreation: Date;
/**
* Date à laquelle la note a é mise à jour pour la dernière fois
*/
dateMiseAjour: Date;
}

@ -0,0 +1,25 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { SaisieDTO } from './saisieDTO';
import { TypeChamps } from './typeChamps';
/**
* DTO permettant de faire le lien entre les saisies (EPS ou EPA...) avec l'EP.
*/
export interface DocumentDTO {
/**
* Id du document
*/
id: number;
typeDocument: TypeChamps;
saisies: Array<SaisieDTO>;
}

@ -0,0 +1,45 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { EpInformationDTO } from './epInformationDTO';
import { EtatEngagement } from './etatEngagement';
/**
* DTO concernant les engagements pris par le référent lors de l'EP.
*/
export interface EngagementDTO {
/**
* Id de l'engagement
*/
id: number;
/**
* Action de l'engagement
*/
action: string;
/**
* Dispositif à mettre en place pour respecter l'engagement dans les temps
*/
dispositif: string;
/**
* Sur temps de travail ou Hors-temps
*/
modalite: string;
/**
* Date limite pour respecter l'engagement
*/
dateLimite: Date;
etatEngagement?: EtatEngagement;
/**
* Raison pour laquelle l'engagement ne sera pas respecté
*/
raisonNonRealisable?: string;
ep?: EpInformationDTO;
}

@ -0,0 +1,81 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { AugmentationSalaireDTO } from './augmentationSalaireDTO';
import { CollaborateurDTO } from './collaborateurDTO';
import { CommentaireAssistantDTO } from './commentaireAssistantDTO';
import { DemandeDelegationDTO } from './demandeDelegationDTO';
import { DemandeEPIDTO } from './demandeEPIDTO';
import { DemandeFormationDTO } from './demandeFormationDTO';
import { DocumentDTO } from './documentDTO';
import { EngagementDTO } from './engagementDTO';
import { ObjectifDTO } from './objectifDTO';
import { ObjectifPrecedentDTO } from './objectifPrecedentDTO';
import { ParticipationEPDTO } from './participationEPDTO';
import { RDVEntretienDTO } from './rDVEntretienDTO';
import { StatutEp } from './statutEp';
import { TypeEntretienDTO } from './typeEntretienDTO';
import { TypeEp } from './typeEp';
/**
* DTO contenant l'ensemble des informations d'un EP.
*/
export interface EpDTO {
/**
* Id de lEP
*/
id: number;
type: TypeEp;
/**
* Date à partir de laquelle l'EP peut être saisi
*/
dateDisponibilite: Date;
/**
* Date à laquelle l'EP est prévu, la date par défaut est celle de l'anniversaire du collaborateur (+6 mois pour EPS)
*/
datePrevisionnelle: Date;
/**
* Date à laquelle le collaborateur a signé l'EP
*/
dateSignatureCollaborateur?: Date;
/**
* Date à laquelle le référent a signé l'EP
*/
dateSignatureReferent?: Date;
/**
* Date à laquelle lEP a é saisi par le collaborateur
*/
dateSaisie?: Date;
statut: StatutEp;
/**
* Nom du CV Apside du collaborateur
*/
cv: string;
propositionsEntretien?: Array<RDVEntretienDTO>;
rdvEntretien?: RDVEntretienDTO;
choixTypeEntretien?: Array<TypeEntretienDTO>;
/**
* Indique si oui ou non l'EP doit obligatoirement être effectué
*/
obligatoire: boolean;
objectifs: Array<ObjectifDTO>;
objectifsPrecedent?: Array<ObjectifPrecedentDTO>;
collaborateur?: CollaborateurDTO;
referent?: CollaborateurDTO;
demandesFormation?: Array<DemandeFormationDTO>;
participants?: Array<ParticipationEPDTO>;
engagements?: Array<EngagementDTO>;
augmentationSalaire?: AugmentationSalaireDTO;
demandesDelegation?: DemandeDelegationDTO;
demandeEPI?: DemandeEPIDTO;
documents: Array<DocumentDTO>;
commentairesAssistant?: Array<CommentaireAssistantDTO>;
}

@ -0,0 +1,40 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { CollaborateurDTO } from './collaborateurDTO';
import { StatutEp } from './statutEp';
import { TypeEp } from './typeEp';
/**
* DTO permettant d'afficher les informations utiles d'un EP dans un tableau.
*/
export interface EpInformationDTO {
/**
* Id de l'EP
*/
id: number;
type: TypeEp;
statut: StatutEp;
/**
* Date à partir de laquelle l'EP peut être saisi
*/
dateDisponibilite: Date;
/**
* Date à laquelle l'EP est prévu, la date par défaut est celle de l'anniversaire du collaborateur (+6 mois pour EPS)
*/
datePrevisionnelle: Date;
/**
* Indique si oui ou non l'EP doit obligatoirement être effectué
*/
obligatoire: boolean;
collaborateur?: CollaborateurDTO;
referent?: CollaborateurDTO;
}

@ -0,0 +1,51 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { AugmentationSalaireDTO } from './augmentationSalaireDTO';
import { DocumentDTO } from './documentDTO';
import { EngagementDTO } from './engagementDTO';
import { ObjectifDTO } from './objectifDTO';
import { ObjectifPrecedentDTO } from './objectifPrecedentDTO';
import { TypeEntretienDTO } from './typeEntretienDTO';
import { TypeEp } from './typeEp';
/**
* DTO utilisé lors de la saisie du collaborateur ou du référent.
*/
export interface EpSaisieDTO {
/**
* Id de lEP
*/
id: number;
type: TypeEp;
/**
* Nom du CV Apside du collaborateur
*/
cv?: string;
choixEntretien?: TypeEntretienDTO;
/**
* Indique si oui ou non l'EP doit obligatoirement être effectué
*/
obligatoire: boolean;
objectifs?: Array<ObjectifDTO>;
objectifsPrecedent?: Array<ObjectifPrecedentDTO>;
/**
* Id du collaborateur qui passe son EP
*/
idCollaborateur?: string;
/**
* Id du référent actuel de l'EP
*/
idReferent?: string;
engagements?: Array<EngagementDTO>;
augmentationSalaire?: AugmentationSalaireDTO;
documents: Array<DocumentDTO>;
}

@ -2,7 +2,7 @@
* API du serveur de l'application de digitalisation des EP * API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire. * API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
* *
* OpenAPI spec version: 1.2.0 * OpenAPI spec version: 1.3.6
* *
* *
* NOTE: This class is auto generated by the swagger code generator program. * NOTE: This class is auto generated by the swagger code generator program.
@ -10,7 +10,16 @@
* Do not edit the class manually. * Do not edit the class manually.
*/ */
export interface ErreurModel { /**
code: string; * Classe pour la gestion et l'affichage des erreurs.
*/
export interface ErreurDTO {
/**
* Code Erreur
*/
code: number;
/**
* Message d'erreur
*/
message: string; message: string;
} }

@ -0,0 +1,44 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* Correspond à l'état d'une demande comme une demande de formation ou une demande de délégation: * `EnAttente` - Aucune réponse n'a encore é donnée * `Validee` - La demande a é acceptée * `Rejetee` - La demande a é rejeté
*/
export type EtatDemande = 'EnAttente' | 'Validee' | 'Rejetee';
export const EtatDemande = {
EnAttente: 'EnAttente' as EtatDemande,
Validee: 'Validee' as EtatDemande,
Rejetee: 'Rejetee' as EtatDemande
};
export function AfficherEtatDemandeDelegation(etat: EtatDemande) {
switch(etat) {
case EtatDemande.Rejetee :
return "Demande rejetée";
case EtatDemande.Validee:
return "Demande acceptée";
case EtatDemande.EnAttente:
return "Demande en attente";
}
}
export function afficherEtatDemande(etatDemande: EtatDemande) {
switch(etatDemande) {
case EtatDemande.Validee:
return "Validée";
case EtatDemande.Rejetee:
return "Rejetée";
case EtatDemande.EnAttente:
return "En attente";
}
}

@ -0,0 +1,36 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* Correspond à l'état d'un engagement pris: * `EnAttente` - Aucune réponse n'a encore été donnée * `Respecte` - L'engagement a é respecté dans les temps * `NonRealisable` - L'engagement ne sera pas réalisable dans les temps * `DateLimitePassee` - La date limite pour respecter l'engagement est passée
*/
export type EtatEngagement = 'EnAttente' | 'Respecte' | 'NonRealisable' | 'DateLimitePassee';
export const EtatEngagement = {
EnAttente: 'EnAttente' as EtatEngagement,
Respecte: 'Respecte' as EtatEngagement,
NonRealisable: 'NonRealisable' as EtatEngagement,
DateLimitePassee: 'DateLimitePassee' as EtatEngagement
};
export function afficherEtatEngagement(etatEngagement: EtatEngagement) {
switch(etatEngagement) {
case EtatEngagement.Respecte:
return "Respecté";
case EtatEngagement.NonRealisable:
return "Non réalisable";
case EtatEngagement.EnAttente:
return "En attente";
case EtatEngagement.DateLimitePassee:
return "Date limite passée";
}
}

@ -0,0 +1,35 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { SaisieDTO } from './saisieDTO';
/**
* DTO pour les évaluations concernant les formations.
*/
export interface EvaluationDTO {
/**
* Id de la participation à la formation
*/
id: number;
/**
* Intitulé de la formation
*/
intitule: string;
/**
* Date de début de la formation
*/
dateDebut: Date;
/**
* Indique si la formation est certifiée ou non
*/
estCertifiee: boolean;
saisies: Array<SaisieDTO>;
}

@ -0,0 +1,67 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { ParticipationFormationDTO } from './participationFormationDTO';
import { ModeFormationDTO } from './modeFormationDTO';
import { OrigineFormationDTO } from './origineFormationDTO';
import { StatutFormationDTO } from './statutFormationDTO';
import { TypeFormationDTO } from './typeFormationDTO';
/**
* DTO pour la gestion des formations.
*/
export interface FormationDTO {
/**
* Id de la formation
*/
id?: number;
/**
* Intitulé de la formation
*/
intitule: string;
origine: OrigineFormationDTO;
statut: StatutFormationDTO;
/**
* Id de l'agence de la RH qui a créé la formation
*/
idAgence: number;
/**
* Date de la première séance de la formation
*/
dateDebut: Date;
/**
* Date de la dernière séance de la formation
*/
dateFin: Date;
/**
* Nombre d'heures total de formation
*/
heure: number;
/**
* Nombre de jours total de formation
*/
jour: number;
/**
* Organisme en charge d'effectuer la formation
*/
organisme: string;
mode: ModeFormationDTO;
type: TypeFormationDTO;
/**
* Indique s'il s'agit d'une formation certifiée ou non
*/
estCertifiee: boolean;
/**
* Indique que la formation a bien é effectuée ou non
*/
estRealisee: boolean;
participations?: Array<ParticipationFormationDTO>;
}

@ -0,0 +1,49 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { OrigineFormationDTO } from './origineFormationDTO';
import { StatutFormationDTO } from './statutFormationDTO';
/**
* DTO pour l'affichage des détails d'une formation.
*/
export interface FormationDetailsDTO {
/**
* Id de la formation
*/
id: number;
/**
* Intitulé de la formation
*/
intitule: string;
statut: StatutFormationDTO;
/**
* Date de début de la formation
*/
dateDebut: Date;
/**
* Date de la dernière séance de la formation
*/
dateFin: Date;
/**
* Organisme en charge d'effectuer la formation
*/
organisme?: string;
/**
* Nombre de participants de la formation
*/
nbParticipations: number;
origine: OrigineFormationDTO;
/**
* Indique si la formation est certifiée ou non
*/
estCertifiee: boolean;
}

@ -2,17 +2,24 @@
* API du serveur de l'application de digitalisation des EP * API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire. * API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
* *
* OpenAPI spec version: 1.2.0 * OpenAPI spec version: 1.3.6
* *
* *
* NOTE: This class is auto generated by the swagger code generator program. * NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git * https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually. * Do not edit the class manually.
*/ */
import { EpModel } from './epModel';
export interface AugmentationSalaireModel { /**
* DTO concernant le mode d'une formation.
*/
export interface ModeFormationDTO {
/**
* Id du mode de formation
*/
id: number; id: number;
augmentation: number; /**
ep: EpModel; * Libellé du mode de formation
*/
libelle: string;
} }

@ -0,0 +1,41 @@
export * from './affichageNoteDTO';
export * from './agenceDTO';
export * from './augmentationSalaireDTO';
export * from './businessUnitDTO';
export * from './champDTO';
export * from './collaborateurDTO';
export * from './commentaireAssistantDTO';
export * from './demandeDelegationDTO';
export * from './demandeEPIDTO';
export * from './demandeFormationDTO';
export * from './detailsNoteDTO';
export * from './documentDTO';
export * from './engagementDTO';
export * from './epDTO';
export * from './epInformationDTO';
export * from './epSaisieDTO';
export * from './erreurDTO';
export * from './etatDemande';
export * from './etatEngagement';
export * from './evaluationDTO';
export * from './formationDTO';
export * from './formationDetailsDTO';
export * from './modeFormationDTO';
export * from './objectifDTO';
export * from './objectifPrecedentDTO';
export * from './origineDemandeFormationDTO';
export * from './origineFormationDTO';
export * from './participationEPDTO';
export * from './participationFormationDTO';
export * from './prochainEPDTO';
export * from './rDVEntretienDTO';
export * from './referentEPDTO';
export * from './saisieDTO';
export * from './statutEp';
export * from './statutFormationDTO';
export * from './statutObjectif';
export * from './typeChamps';
export * from './typeEntretienDTO';
export * from './typeEp';
export * from './typeFormationDTO';
export * from './typeSaisie';

@ -2,17 +2,24 @@
* API du serveur de l'application de digitalisation des EP * API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire. * API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
* *
* OpenAPI spec version: 1.2.0 * OpenAPI spec version: 1.3.6
* *
* *
* NOTE: This class is auto generated by the swagger code generator program. * NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git * https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually. * Do not edit the class manually.
*/ */
import { AgenceModel } from './agenceModel';
export interface BusinessUnitModel { /**
* DTO concernant un objectif du collaborateur.
*/
export interface ObjectifDTO {
/**
* Id de l'objectif
*/
id: number; id: number;
nom: string; /**
agence: AgenceModel; * Objectif du collaborateur
*/
libelle: string;
} }

@ -0,0 +1,31 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { StatutObjectif } from './statutObjectif';
/**
* DTO concernant un objectif du dernier EP effectué par le collaborateur.
*/
export interface ObjectifPrecedentDTO {
/**
* Id de l'objectif précédent
*/
id: number;
/**
* Objectif précédent du collaborateur
*/
libelle: string;
statutObjectif?: StatutObjectif;
/**
* Commentaire du collaborateur sur l'objectif
*/
commentaire?: string;
}

@ -0,0 +1,25 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* DTO concernant l'origine de la demande de formation.
*/
export interface OrigineDemandeFormationDTO {
/**
* Id de l'origine de la demande de formation
*/
id: number;
/**
* Libellé de l'origine de la demande de formation
*/
libelle: string;
}

@ -0,0 +1,25 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* DTO concernant l'origine d'une formation.
*/
export interface OrigineFormationDTO {
/**
* Id de l'origine de la formation
*/
id: number;
/**
* Libellé de l'origine de la formation
*/
libelle: string;
}

@ -0,0 +1,33 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
/**
* DTO concernant les participants supplémentaires dun EP en dehors du collaborateur et du référent.
*/
export interface ParticipationEPDTO {
/**
* Id de la participation
*/
id?: number;
/**
* Id du participant
*/
idParticipant: string;
/**
* Indique si la participation est juste une participation d'un EP en cours ou des prochains EP en plus
*/
estPermanente: boolean;
/**
* Nom et prénom du participant
*/
participant: string;
}

@ -0,0 +1,43 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { CollaborateurDTO } from './collaborateurDTO';
import { EpInformationDTO } from './epInformationDTO';
import { StatutFormationDTO } from './statutFormationDTO';
/**
* DTO concernant la participation à une formation.
*/
export interface ParticipationFormationDTO {
/**
* Id de la participation formation
*/
id?: number;
/**
* Date à laquelle la participation a é créée
*/
dateCreation: Date;
/**
* Intitulé de la formation
*/
intitule: string;
/**
* Date de début de la formation
*/
dateDebut: Date;
statut: StatutFormationDTO;
collaborateur: CollaborateurDTO;
/**
* Indique si le collaborateur a effectué l'évaluation de la formation
*/
estEvaluee: boolean;
ep?: EpInformationDTO;
}

@ -0,0 +1,35 @@
/**
* API du serveur de l'application de digitalisation des EP
* API qui sra utilisée afin de faire communiquer le client et le serveur ainsi que le serveur et la boîte noire.
*
* OpenAPI spec version: 1.3.6
*
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
import { TypeChamps } from './typeChamps';
/**
* DTO permettant au collaborateur d'avoir les informations sur la date de son prochain EP.
*/
export interface ProchainEPDTO {
/**
* Id de l'EP
*/
id: number;
type: TypeChamps;
/**
* Date à laquelle l'EP est disponible pour être saisi
*/
dateDisponibilite: Date;
/**
* Date à laquelle l'EP est prévu, la date par défaut est celle de l'anniversaire du collaborateur (+6 mois pour EPS)
*/
datePrevisionnelle: Date;
/**
* Indique si oui ou non l'EP doit obligatoirement être effectué
*/
obligatoire: boolean;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save