rajah 1 سال پیش
والد
کامیت
a4324339d5
26فایلهای تغییر یافته به همراه557 افزوده شده و 135 حذف شده
  1. 15 0
      package-lock.json
  2. 2 0
      package.json
  3. 2 0
      src/app/app.routes.ts
  4. 2 12
      src/app/participant-create/participant-create.component.html
  5. 4 8
      src/app/participant-create/participant-create.component.ts
  6. 2 12
      src/app/participant-details/participant-details.component.html
  7. 3 3
      src/app/participant-details/participant-details.component.ts
  8. 15 2
      src/app/participant-list/participant-list.component.html
  9. 3 1
      src/app/participant-list/participant-list.component.ts
  10. 2 12
      src/app/participant-update/participant-update.component.html
  11. 3 3
      src/app/participant-update/participant-update.component.ts
  12. 22 20
      src/app/participant.ts
  13. 3 8
      src/app/production-create/production-create.component.html
  14. 3 4
      src/app/production-create/production-create.component.ts
  15. 104 1
      src/app/production-details/production-details.component.html
  16. 31 7
      src/app/production-details/production-details.component.ts
  17. 4 4
      src/app/production-list/production-list.component.html
  18. 7 2
      src/app/production-list/production-list.component.ts
  19. 133 1
      src/app/production-update/production-update.component.html
  20. 58 9
      src/app/production-update/production-update.component.ts
  21. 0 0
      src/app/production-upload/production-upload.component.css
  22. 29 0
      src/app/production-upload/production-upload.component.html
  23. 23 0
      src/app/production-upload/production-upload.component.spec.ts
  24. 49 0
      src/app/production-upload/production-upload.component.ts
  25. 17 4
      src/app/production.service.ts
  26. 21 22
      src/app/production.ts

+ 15 - 0
package-lock.json

@@ -19,6 +19,7 @@
         "@fortawesome/fontawesome-free": "^6.7.2",
         "@ng-select/ng-select": "^14.2.2",
         "bootstrap": "^5.3.3",
+        "file-saver": "^2.0.5",
         "jquery": "^3.7.1",
         "rxjs": "~7.8.0",
         "tslib": "^2.3.0",
@@ -28,6 +29,7 @@
         "@angular-devkit/build-angular": "^19.1.7",
         "@angular/cli": "^19.1.7",
         "@angular/compiler-cli": "^19.1.0",
+        "@types/file-saver": "^2.0.7",
         "@types/jasmine": "~5.1.0",
         "jasmine-core": "~5.5.0",
         "karma": "~6.4.0",
@@ -4991,6 +4993,13 @@
         "@types/send": "*"
       }
     },
+    "node_modules/@types/file-saver": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz",
+      "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/@types/http-errors": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
@@ -7683,6 +7692,12 @@
         "node": ">=0.8.0"
       }
     },
+    "node_modules/file-saver": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
+      "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==",
+      "license": "MIT"
+    },
     "node_modules/fill-range": {
       "version": "7.1.1",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",

+ 2 - 0
package.json

@@ -21,6 +21,7 @@
     "@fortawesome/fontawesome-free": "^6.7.2",
     "@ng-select/ng-select": "^14.2.2",
     "bootstrap": "^5.3.3",
+    "file-saver": "^2.0.5",
     "jquery": "^3.7.1",
     "rxjs": "~7.8.0",
     "tslib": "^2.3.0",
@@ -30,6 +31,7 @@
     "@angular-devkit/build-angular": "^19.1.7",
     "@angular/cli": "^19.1.7",
     "@angular/compiler-cli": "^19.1.0",
+    "@types/file-saver": "^2.0.7",
     "@types/jasmine": "~5.1.0",
     "jasmine-core": "~5.5.0",
     "karma": "~6.4.0",

+ 2 - 0
src/app/app.routes.ts

@@ -16,6 +16,7 @@ import { ProductionListComponent } from './production-list/production-list.compo
 import { ProductionCreateComponent } from './production-create/production-create.component';
 import { ProductionDetailsComponent } from './production-details/production-details.component';
 import { ProductionUpdateComponent } from './production-update/production-update.component';
+import { ProductionUploadComponent } from './production-upload/production-upload.component';
 
 export const routes: Routes = [  
   {path: '', redirectTo: 'variable-list', pathMatch: 'full'},
@@ -35,6 +36,7 @@ export const routes: Routes = [
   {path: 'production-create', component: ProductionCreateComponent},
   {path: 'production-details/:numeroProduction', component: ProductionDetailsComponent},
   {path: 'production-update/:numeroProduction', component: ProductionUpdateComponent},
+  {path: 'production-upload/:numeroProduction', component: ProductionUploadComponent},
 ];
 
 @NgModule({

+ 2 - 12
src/app/participant-create/participant-create.component.html

@@ -96,13 +96,7 @@
 				<div class="col-sm-10">
 					<div class="form-group field-separate">
 						<select class="form-select form-select-sm" id="status" name="status" [(ngModel)]="participant.status" required #statusRef="ngModel" [class.is-invalid]="statusRef.invalid && statusRef.touched">
-							<option [value]="PS.EN_ATTENTE">{{ PS.EN_ATTENTE }}</option>
-							<option value="PAYE_CHEQUE">{{ PS.PAYE_CHEQUE }}</option>
-							<option value="PAYE_ESPECES">{{ PS.PAYE_ESPECES }}</option>
-							<option value="VIREMENT_BANCAIRE">{{ PS.VIREMENT_BANCAIRE }}</option>
-							<option value="VIREMENT_PAYPAL">{{ PS.VIREMENT_PAYPAL }}</option>
-							<option value="ORGA">{{ PS.ORGA }}</option>
-							<option value="GUEST">{{ PS.GUEST }}</option>
+							@for (ps of PS; track ps.key) { <option [value]="ps.key">{{ ps.value }}</option> }
 						</select>
 					</div>
 				</div>
@@ -180,11 +174,7 @@
 				<div class="col-sm-10">
 					<div class="form-group field-separate">
 						<select class="form-select form-select-sm" id="modePaiement" name="modePaiement" [(ngModel)]="participant.modePaiement" required #modePaiementRef="ngModel">
-							<option value="CHEQUE">{{ PMP.CHEQUE }}</option>
-							<option value="VIREMENT">{{ PMP.VIREMENT }}</option>
-							<option value="PAYPAL">{{ PMP.PAYPAL }}</option>
-							<option value="ESPECES">{{ PMP.ESPECES }}</option>
-							<option [value]="PMP.AUTRE">{{ PMP.AUTRE }}</option>
+							@for (pmp of PMP; track pmp.key) { <option [value]="pmp.key">{{ pmp.value }}</option> }
 						</select>
 					</div>
 				</div>

+ 4 - 8
src/app/participant-create/participant-create.component.ts

@@ -1,5 +1,5 @@
 import { Component, OnInit, ViewChild } from '@angular/core';
-import { Participant, ParticipantStatusEnum, ParticipantModePaiementEnum } from '../participant';
+import { Participant, ParticipantEnum, ParticipantStatusList, ParticipantModePaiementList } from '../participant';
 import { ParticipantService } from '../participant.service';
 import { Router } from '@angular/router';
 import { FormsModule, NgForm } from '@angular/forms'; 
@@ -9,8 +9,8 @@ import { FormsModule, NgForm } from '@angular/forms';
 export class ParticipantCreateComponent implements OnInit
 {
   
-  PS = ParticipantStatusEnum;
-  PMP = ParticipantModePaiementEnum;
+  PS: ParticipantEnum[] = ParticipantStatusList;
+  PMP: ParticipantEnum[] = ParticipantModePaiementList;
 
   @ViewChild('formRef') participantForm!: NgForm;
   
@@ -18,11 +18,7 @@ export class ParticipantCreateComponent implements OnInit
   
   constructor(private participantService: ParticipantService, private router: Router) { }
 
-  ngOnInit(): void 
-  { 
-    this.participant.status = this.PS.EN_ATTENTE;
-    this.participant.modePaiement = this.PMP.AUTRE;
-  }
+  ngOnInit(): void { }
 
   private saveParticipant() { this.participantService.createParticipant(this.participant).subscribe({ next: () => { this.goToListParticipant(); }, error: (err: any) => { console.log(err); }, complete: () => { } }); }
 

+ 2 - 12
src/app/participant-details/participant-details.component.html

@@ -109,13 +109,7 @@
 			<div class="col-sm-10">
 				<div class="form-group field-separate">
 					<select class="form-select form-select-sm" id="status" name="status" [(ngModel)]="participant.status" disabled>
-    				<option value="EN_ATTENTE">{{ PS.EN_ATTENTE }}</option>
-						<option value="PAYE_CHEQUE">{{ PS.PAYE_CHEQUE }}</option>
-						<option value="PAYE_ESPECES">{{ PS.PAYE_ESPECES }}</option>
-						<option value="VIREMENT_BANCAIRE">{{ PS.VIREMENT_BANCAIRE }}</option>
-						<option value="VIREMENT_PAYPAL">{{ PS.VIREMENT_PAYPAL }}</option>
-						<option value="ORGA">{{ PS.ORGA }}</option>
-						<option value="GUEST">{{ PS.GUEST }}</option>
+							@for (ps of PS; track ps.key) { <option [value]="ps.key">{{ ps.value }}</option> }
 					</select>
 				</div>
 			</div>
@@ -195,11 +189,7 @@
 			<div class="col-sm-10">
 				<div class="form-group field-separate">
 					<select class="form-select form-select-sm" id="modePaiement" name="modePaiement" [(ngModel)]="participant.modePaiement" disabled>
-						<option value="CHEQUE">{{ PMP.CHEQUE }}</option>
-						<option value="VIREMENT">{{ PMP.VIREMENT }}</option>
-						<option value="PAYPAL">{{ PMP.PAYPAL }}</option>
-						<option value="ESPECES">{{ PMP.ESPECES }}</option>
-						<option value="AUTRE">{{ PMP.AUTRE }}</option>
+							@for (pmp of PMP; track pmp.key) { <option [value]="pmp.key">{{ pmp.value }}</option> }
 					</select>
 				</div>
 			</div>

+ 3 - 3
src/app/participant-details/participant-details.component.ts

@@ -1,6 +1,6 @@
 import { Component, OnInit } from '@angular/core';
 import { ActivatedRoute, Router } from '@angular/router';
-import { Participant, ParticipantStatusEnum, ParticipantModePaiementEnum } from '../participant';
+import { Participant, ParticipantEnum, ParticipantStatusList, ParticipantModePaiementList } from '../participant';
 import { ParticipantService } from '../participant.service';
 import { FormsModule } from '@angular/forms'; 
 
@@ -9,8 +9,8 @@ import { FormsModule } from '@angular/forms';
 export class ParticipantDetailsComponent implements OnInit 
 {
   
-  PS = ParticipantStatusEnum;
-  PMP = ParticipantModePaiementEnum;
+  PS: ParticipantEnum[] = ParticipantStatusList;
+  PMP: ParticipantEnum[] = ParticipantModePaiementList;
  
   numeroParticipant: number = 0;
 

+ 15 - 2
src/app/participant-list/participant-list.component.html

@@ -16,6 +16,7 @@
 					<th class="fs-6 label-nobr"><small>Nom</small></th>
 					<th class="fs-6 label-nobr"><small>Pseudonyme</small></th>
 					<th class="fs-6 label-nobr"><small>Arrivé</small></th>
+					<th class="fs-6 label-nobr"><small>Status</small></th>
 				</tr>
 			</thead>
 			<tbody>
@@ -23,10 +24,22 @@
 				<tr>
 					<td class="label-nobr">{{ participant.nom }}&nbsp;{{ participant.prenom }}&nbsp;&nbsp;</td>
 					<td class="label-nobr"><a (click)="formParticipant(participant.numeroParticipant)" class="link-primary pointeur-souris text-decoration-none">{{ participant.pseudonyme }}</a>&nbsp;&nbsp;</td>
-					<td>@if (participant.arrived) { <i class="fa-solid fa-circle-check text-success"></i> } @else { <i class="fa-solid fa-circle-xmark text-danger"></i> }&nbsp;&nbsp;</td>
+					<td>
+					  @if (participant.arrived) { <i class="fa-solid fa-circle-check text-success"></i> } 
+					  @else { <i class="fa-solid fa-circle-xmark text-danger"></i> }&nbsp;&nbsp;
+					</td>
+					<td>
+					  @if (participant.status === PS[0].key) { <i class="fa-solid fa-circle-xmark text-danger" title="{{ PS[0].value }}"></i> }
+					  @else if (participant.status === PS[1].key) { <i class="fa-solid fa-circle-xmark text-success" title="{{ PS[1].value }}"></i> }  
+					  @else if (participant.status === PS[2].key) { <i class="fa-solid fa-circle-xmark text-success" title="{{ PS[2].value }}"></i> }  
+					  @else if (participant.status === PS[3].key) { <i class="fa-solid fa-circle-xmark text-success" title="{{ PS[3].value }}"></i> }  
+					  @else if (participant.status === PS[4].key) { <i class="fa-solid fa-circle-xmark text-success" title="{{ PS[4].value }}"></i> }  
+					  @else if (participant.status === PS[5].key) { <i class="fa-solid fa-circle-xmark text-primary" title="{{ PS[5].value }}"></i> }  
+					  @else if (participant.status === PS[6].key) { <i class="fa-solid fa-circle-xmark text-primary" title="{{ PS[6].value }}"></i> } 
+					 </td>
 				</tr>
 				}
 			</tbody>
 		</table>
 	</div>
-</div>
+</div>

+ 3 - 1
src/app/participant-list/participant-list.component.ts

@@ -1,6 +1,6 @@
 import { Component, OnInit } from '@angular/core';
 import { Router } from '@angular/router';
-import { Participant } from '../participant';
+import { Participant, ParticipantEnum, ParticipantStatusList } from '../participant';
 import { ParticipantService } from '../participant.service';
 
 @Component({ selector: 'app-participant-list', imports: [], templateUrl: './participant-list.component.html', styleUrl: './participant-list.component.css' })
@@ -8,6 +8,8 @@ import { ParticipantService } from '../participant.service';
 export class ParticipantListComponent implements OnInit  
 {
     
+  PS: ParticipantEnum[] = ParticipantStatusList;
+
   participants: Participant[] = [];
 
   constructor(private participantService: ParticipantService, private router: Router) { }

+ 2 - 12
src/app/participant-update/participant-update.component.html

@@ -110,13 +110,7 @@
 			<div class="col-sm-10">
 				<div class="form-group field-separate">
 					<select class="form-select form-select-sm" id="status" name="status" [(ngModel)]="participant.status">
-    				<option value="EN_ATTENTE">{{ PS.EN_ATTENTE }}</option>
-						<option value="PAYE_CHEQUE">{{ PS.PAYE_CHEQUE }}</option>
-						<option value="PAYE_ESPECES">{{ PS.PAYE_ESPECES }}</option>
-						<option value="VIREMENT_BANCAIRE">{{ PS.VIREMENT_BANCAIRE }}</option>
-						<option value="VIREMENT_PAYPAL">{{ PS.VIREMENT_PAYPAL }}</option>
-						<option value="ORGA">{{ PS.ORGA }}</option>
-						<option value="GUEST">{{ PS.GUEST }}</option>
+							@for (ps of PS; track ps.key) { <option [value]="ps.key">{{ ps.value }}</option> }
 					</select>
 				</div>
 			</div>
@@ -196,11 +190,7 @@
 			<div class="col-sm-10">
 				<div class="form-group field-separate">
 					<select class="form-select form-select-sm" id="modePaiement" name="modePaiement" [(ngModel)]="participant.modePaiement">
-						<option value="CHEQUE">{{ PMP.CHEQUE }}</option>
-						<option value="VIREMENT">{{ PMP.VIREMENT }}</option>
-						<option value="PAYPAL">{{ PMP.PAYPAL }}</option>
-						<option value="ESPECES">{{ PMP.ESPECES }}</option>
-						<option value="AUTRE">{{ PMP.AUTRE }}</option>
+							@for (pmp of PMP; track pmp.key) { <option [value]="pmp.key">{{ pmp.value }}</option> }
 					</select>
 				</div>
 			</div>

+ 3 - 3
src/app/participant-update/participant-update.component.ts

@@ -1,6 +1,6 @@
 import { Component, OnInit, ViewChild } from '@angular/core';
 import { ActivatedRoute, Router } from '@angular/router';
-import { Participant, ParticipantStatusEnum, ParticipantModePaiementEnum } from '../participant';
+import { Participant, ParticipantEnum, ParticipantStatusList, ParticipantModePaiementList } from '../participant';
 import { ParticipantService } from '../participant.service';
 import { FormsModule, NgForm } from '@angular/forms'; 
 
@@ -9,8 +9,8 @@ import { FormsModule, NgForm } from '@angular/forms';
 export class ParticipantUpdateComponent implements OnInit
 {
   
-  PS = ParticipantStatusEnum;
-  PMP = ParticipantModePaiementEnum;
+  PS: ParticipantEnum[] = ParticipantStatusList;
+  PMP: ParticipantEnum[] = ParticipantModePaiementList;
 
   @ViewChild('formRef') participantForm!: NgForm;
 

+ 22 - 20
src/app/participant.ts

@@ -1,22 +1,24 @@
-export enum ParticipantStatusEnum
-{
-  EN_ATTENTE = "En attente", 
-  PAYE_CHEQUE = "Payé chèque", 
-  PAYE_ESPECES = "Payé espèces", 
-  VIREMENT_BANCAIRE = "Virement bancaire", 
-  VIREMENT_PAYPAL = "Virement Paypal", 
-  ORGA = "Orga", 
-  GUEST = "Guest",
-}
+export class ParticipantEnum { key!: string; value!: string; }
 
-export enum ParticipantModePaiementEnum
-{
-  CHEQUE = "Chèque",
-  VIREMENT = "Virement", 
-  PAYPAL = "Paypal", 
-  ESPECES = "Espèces", 
-  AUTRE = "Autre",
-}
+export const ParticipantStatusList: ParticipantEnum[] = 
+[ 
+  { key: "EN_ATTENTE", value: "En attente"}, 
+  { key: "PAYE_CHEQUE", value: "Payé chèque"}, 
+  { key: "PAYE_ESPECES", value: "Payé espèces"}, 
+  { key: "VIREMENT_BANCAIRE", value: "Virement bancaire"}, 
+  { key: "VIREMENT_PAYPAL", value: "Virement Paypal"}, 
+  { key: "ORGA", value: "Orga"}, 
+  { key: "GUEST", value: "Guest"} 
+];
+
+export const ParticipantModePaiementList: ParticipantEnum[] = 
+[ 
+  { key: "CHEQUE", value: "Chèque"}, 
+  { key: "VIREMENT", value: "Virement"}, 
+  { key: "PAYPAL", value: "Paypal"}, 
+  { key: "ESPECES", value: "Espèces"}, 
+  { key: "AUTRE", value: "Autre"}
+];
 
 export class Participant 
 {
@@ -37,7 +39,7 @@ export class Participant
   pays: string = "";
   numeroTelephone: string = "";
   email: string = "";
-  status: ParticipantStatusEnum = ParticipantStatusEnum.EN_ATTENTE;
+  status: string = "EN_ATTENTE";
   withMachine: boolean = true;
   commentaire: string = "";
   hereDay1: boolean = false;
@@ -45,7 +47,7 @@ export class Participant
   hereDay3: boolean = false;
   sleepingOnSite: boolean = true;
   useAmigabus: boolean = false;
-  modePaiement: ParticipantModePaiementEnum = ParticipantModePaiementEnum.CHEQUE;
+  modePaiement: string = "CHEQUE";
   dateInscription: string = "";
   sommeRecue: string = "";
   arrived: boolean = false;

+ 3 - 8
src/app/production-create/production-create.component.html

@@ -12,12 +12,7 @@
 				<div class="col-sm-10">
 					<div class="form-group field-separate">
 						<select class="form-select form-select-sm" id="type" name="type" [(ngModel)]="production.type">
-							<option [value]="PT.EXECUTABLE">{{ PT.EXECUTABLE }}</option>
-							<option value="GRAPHE">{{ PT.GRAPHE }}</option>
-							<option value="MUSIQUE">{{ PT.MUSIQUE }}</option>
-							<option value="VIDEO">{{ PT.VIDEO }}</option>
-							<option value="TOPIC">{{ PT.TOPIC }}</option>
-							<option value="AUTRE">{{ PT.AUTRE }}</option>
+							@for (type of types; track type.key) { <option [value]="type.key">{{ type.value }}</option> }
 						</select>
 					</div>
 				</div>
@@ -68,8 +63,8 @@
 			<div class="form-group row">
 				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Gestionnaire&nbsp;<sup><span class="text-danger">*</span></sup></label>
 				<div class="col-sm-10">
-					<div class="form-group field-separate">
-						<select class="form-select form-select-sm" id="numeroParticipant" name="numeroParticipant" [(ngModel)]="production.numeroParticipant">
+					<div class="form-group">
+						<select class="form-select form-select-sm field-separate" id="numeroParticipant" name="numeroParticipant" [(ngModel)]="production.numeroParticipant">
 				    @for (participant of participants; track participant.numeroParticipant) {
 							<option [ngValue]="participant.numeroParticipant">{{ participant.pseudonyme }} = {{ participant.nom }}&nbsp;{{ participant.prenom }}</option>
 				    }

+ 3 - 4
src/app/production-create/production-create.component.ts

@@ -1,5 +1,5 @@
 import { Component, OnInit, ViewChild } from '@angular/core';
-import { Production, ProductionTypeEnum } from '../production';
+import { Production, ProductionEnum, ProductionTypeList } from '../production';
 import { ProductionService } from '../production.service';
 import { ParticipantShort } from '../participant';
 import { ParticipantService } from '../participant.service';
@@ -13,8 +13,8 @@ export class ProductionCreateComponent implements OnInit
   
   participants: ParticipantShort[] = [];
 
-  PT = ProductionTypeEnum;
-
+  types: ProductionEnum[] = ProductionTypeList;
+  
   @ViewChild('formRef') productionForm!: NgForm;
   
   production: Production = new Production();
@@ -23,7 +23,6 @@ export class ProductionCreateComponent implements OnInit
 
   ngOnInit(): void 
   { 
-    this.production.type = this.PT.EXECUTABLE;
     this.retreiveParticipants();
   }
 

+ 104 - 1
src/app/production-details/production-details.component.html

@@ -1 +1,104 @@
-<p>production-details works!</p>
+<br />
+<div class="card shadow">
+	<div class="card-header">Fiche d'une production</div>
+	<div class="card-header shadow-sm">
+		<button (click)="goToListProduction()" class="btn btn-primary btn-sm">
+			<i class="fa-solid fa-xmark"></i>&nbsp;Retour
+		</button>
+	</div>
+	<div class="card-body">
+
+		<div class="form-group row">
+			<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Créé le</label>
+			<div class="col-sm-10">
+				<input type="text" class="form-control form-control-sm field-separate" id="dateCreation" name="dateCreation" [(ngModel)]="production.dateCreation" disabled>
+			</div>
+		</div>
+
+		<div class="form-group row">
+			<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Modifié le</label>
+			<div class="col-sm-10">
+				<input type="text" class="form-control form-control-sm field-separate" id="dateModification" name="dateModification" [(ngModel)]="production.dateModification" disabled>
+			</div>
+		</div>
+
+		<div class="form-group row">
+			<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Type</label>
+			<div class="col-sm-10">
+				<div class="form-group field-separate">
+					<select class="form-select form-select-sm" id="type" name="type" [(ngModel)]="production.type" disabled> 
+					  @for (type of types; track type.key) { <option [value]="type.key">{{ type.value }}</option> }
+					</select>
+				</div>
+			</div>
+		</div>
+
+		<div class="form-group row">
+			<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Titre</label>
+			<div class="col-sm-10">
+				<input type="text" class="form-control form-control-sm field-separate" id="titre" name="titre" [(ngModel)]="production.titre" disabled>
+			</div>
+		</div>
+
+		<div class="form-group row">
+			<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Auteur(s)</label>
+			<div class="col-sm-10">
+				<input type="text" class="form-control form-control-sm field-separate" id="auteurs" name="auteurs" [(ngModel)]="production.auteurs" disabled>
+			</div>
+		</div>
+
+		<div class="form-group row">
+			<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Groupe(s)</label>
+			<div class="col-sm-10">
+				<input type="text" class="form-control form-control-sm field-separate" id="groupes" name="groupes" [(ngModel)]="production.groupes" disabled>
+			</div>
+		</div>
+
+		<div class="form-group row">
+			<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Plateforme</label>
+			<div class="col-sm-10">
+				<input type="text" class="form-control form-control-sm field-separate" id="plateforme" name="plateforme" [(ngModel)]="production.plateforme" disabled>
+			</div>
+		</div>
+
+		<div class="form-group row">
+			<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Commentaire</label>
+			<div class="col-sm-10">
+				<textarea class="form-control form-control-sm field-separate" id="commentaire" name="commentaire" [(ngModel)]="production.commentaire" disabled></textarea>
+			</div>
+		</div>
+
+		<div class="form-group row">
+			<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Informations privées</label>
+			<div class="col-sm-10">
+				<textarea class="form-control form-control-sm field-separate" id="informationsPrivees" name="informationsPrivees" [(ngModel)]="production.informationsPrivees" disabled></textarea>
+			</div>
+		</div>
+
+		<div class="form-group row">
+			<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Gestionnaire</label>
+			<div class="col-sm-10">
+				<input type="text" class="form-control form-control-sm field-separate" id="plateforme" name="plateforme" [(ngModel)]="production.nomGestionnaire" disabled>
+			</div>
+		</div>
+
+		<div class="form-group row">
+			<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Archive</label>
+			<div class="col-sm-10">
+				<button type="button" (click)="updateArchive(production.numeroProduction)" class="btn btn-primary btn-sm field-separate"><i class="fa-solid fa-upload"></i>&nbsp;Téléverser</button>
+				<small class="text-muted">&nbsp;&nbsp;déjà enregistré : {{ production.nomArchive }} (v{{ production.numeroVersion }})</small>
+			</div>
+		</div>
+
+		<div class="form-group row">
+			<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Vignette</label>
+			<div class="col-sm-10">
+				<img src="{{ production.vignette }}" alt="" class="img-fluid rounded-2">
+			</div>
+		</div>
+
+	</div>
+	<div class="card-footer">
+		<button type="button" (click)="updateProduction(production.numeroProduction)" class="btn btn-primary btn-sm"><i class="fa-solid fa-pen"></i>&nbsp;Editer</button>
+	</div>
+</div>

+ 31 - 7
src/app/production-details/production-details.component.ts

@@ -1,11 +1,35 @@
 import { Component } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { ProductionShort, ProductionEnum, ProductionTypeList } from '../production';
+import { ProductionService } from '../production.service';
+import { FormsModule } from '@angular/forms'; 
 
-@Component({
-  selector: 'app-production-details',
-  imports: [],
-  templateUrl: './production-details.component.html',
-  styleUrl: './production-details.component.css'
-})
-export class ProductionDetailsComponent {
+@Component({ selector: 'app-production-details', imports: [FormsModule], templateUrl: './production-details.component.html', styleUrl: './production-details.component.css' })
+
+export class ProductionDetailsComponent 
+{
+  
+  numeroProduction: number = 0;
+
+  types: ProductionEnum[] = ProductionTypeList;
+  
+  production: ProductionShort = new ProductionShort();
+  
+  constructor(private productionService: ProductionService, private route: ActivatedRoute, private router: Router) { }
+
+  ngOnInit(): void 
+  { 
+    this.numeroProduction = this.route.snapshot.params['numeroProduction'];
+    this.production = new ProductionShort();
+    this.productionService.getByIdProduction(this.numeroProduction).subscribe( data => { this.production = data; });
+  }
+
+  updateArchive(id: number) { this.router.navigate(['/production-upload', id]); }
+  
+  updateProduction(id: number) { this.router.navigate(['/production-update', id]); }
+
+  goToListProduction() {this.router.navigate(['/production-list'], { queryParams: { 'refresh': this.getRandomInteger(1, 100000) } }); }
+  
+  private getRandomInteger(min: number, max: number) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min)) + min; }
 
 }

+ 4 - 4
src/app/production-list/production-list.component.html

@@ -12,10 +12,10 @@
 	<div class="card-body"><div class="d-flex flex-wrap">
 		@for (production of productions; track production.numeroProduction) {
 
-			<div class="card" style="max-width:15rem;">
+			<div class="card" style="max-width:15rem;margin:2px;">
 				<img src="{{ production.vignette }}" class="img-fluid card-img-top pointeur-souris" (click)="formProduction(production.numeroProduction)">
 				<div class="card-header">
-  				<span class="card-title">@if (PT[production.type] === PT.EXECUTABLE) { <i class="fa-solid fa-square-binary"></i> } @else if (PT[production.type] === PT.GRAPHE) { <i class="fa-solid fa-image"></i> } @else if (PT[production.type] === PT.MUSIQUE) { <i class="fa-solid fa-music"></i> } @else if (PT[production.type] === PT.VIDEO) { <i class="fa-solid fa-video"></i> } @else if (PT[production.type] === PT.TOPIC) { <i class="fa-solid fa-comment"></i> } @else { <i class="fa-solid fa-question"></i> }
+  				<span class="card-title">@if (production.type === types[0].key) { <i class="fa-solid fa-square-binary"></i> } @else if (production.type === types[1].key) { <i class="fa-solid fa-image"></i> } @else if (production.type === types[2].key) { <i class="fa-solid fa-music"></i> } @else if (production.type === types[3].key) { <i class="fa-solid fa-video"></i> } @else if (production.type === types[4].key) { <i class="fa-solid fa-comment"></i> } @else { <i class="fa-solid fa-question"></i> }
 	  			<a (click)="formProduction(production.numeroProduction)" class="text-primary pointeur-souris" style="margin-left:7px;">{{ production.titre }}</a></span><br/>
 				  <small><span class="text-muted">par</span> {{ production.auteurs }} @if (production.groupes) { @if (production.groupes.length > 0) { &nbsp;/&nbsp;{{ production.groupes }} } }</small>
 				</div>
@@ -24,8 +24,8 @@
 			  	<small>{{ production.commentaire }}</small><br/>
 				  <small class="text-warning">{{ production.informationsPrivees }}</small>
         </div>
-				<div class="card-footer">
-				  <i class="fa-solid fa-download text-primary pointeur-souris" title="{{ production.nomArchive }} (v{{ production.numeroVersion }})"></i>
+				<div class="card-footer d-flex justify-content-between">
+				  <i class="fa-solid fa-download text-primary pointeur-souris" title="{{ production.nomArchive }} (v{{ production.numeroVersion }})" (click)="getFile(production.numeroProduction, production.nomArchive)"></i>
 					<i class="fa-solid fa-user-tie pointeur-souris" title="géré par {{ production.nomGestionnaire }}" style="margin-left:7px;"></i>
 				</div>
 			</div>

+ 7 - 2
src/app/production-list/production-list.component.ts

@@ -1,7 +1,8 @@
 import { Component } from '@angular/core';
 import { Router } from '@angular/router';
-import { ProductionShort, ProductionTypeKeys } from '../production';
+import { ProductionShort, ProductionEnum, ProductionTypeList } from '../production';
 import { ProductionService } from '../production.service';
+import { saveAs } from 'file-saver';
 
 @Component({ selector: 'app-production-list', imports: [], templateUrl: './production-list.component.html', styleUrl: './production-list.component.css' })
 
@@ -10,7 +11,7 @@ export class ProductionListComponent
   
   productions: ProductionShort[] = [];
 
-  PT = ProductionTypeKeys;
+  types: ProductionEnum[] = ProductionTypeList;
 
   constructor(private productionService: ProductionService, private router: Router) { }
 
@@ -26,4 +27,8 @@ export class ProductionListComponent
 
   formProduction(id: number) { this.router.navigate(['/production-details', id]); }
 
+  getFile(id: number, nom: string) { this.productionService.getProductionFile(id).subscribe(response => { this.saveFile(response.body, nom); }); }
+  
+  saveFile(data: any, filename?: string) { const blob = new Blob([data], {type: 'application/zip'}); saveAs(blob, filename); }
+  
 }

+ 133 - 1
src/app/production-update/production-update.component.html

@@ -1 +1,133 @@
-<p>production-update works!</p>
+<br />
+<form id="formProduction" #formRef="ngForm" class="needs-validation">
+	<div class="card shadow">
+		<div class="card-header">Fiche d'une production</div>
+		<div class="card-header shadow-sm">
+			<button (click)="goToListProduction()" class="btn btn-primary btn-sm">
+				<i class="fa-solid fa-xmark"></i>&nbsp;Retour
+			</button>
+		</div>
+		<div class="card-body">
+
+			<div class="form-group row">
+				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Créé le</label>
+				<div class="col-sm-10">
+					<input type="text" class="form-control form-control-sm field-separate" id="dateCreation" name="dateCreation" [(ngModel)]="production.dateCreation" disabled>
+				</div>
+			</div>
+
+			<div class="form-group row">
+				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Modifié le</label>
+				<div class="col-sm-10">
+					<input type="text" class="form-control form-control-sm field-separate" id="dateModification" name="dateModification" [(ngModel)]="production.dateModification" disabled>
+				</div>
+			</div>
+
+			<div class="form-group row">
+				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Type</label>
+				<div class="col-sm-10">
+					<div class="form-group field-separate">
+						<select class="form-select form-select-sm" id="type" name="type" [(ngModel)]="production.type"> @for (type of types; track type.key) {
+							<option [value]="type.key">{{ type.value }}</option> }
+						</select>
+					</div>
+				</div>
+			</div>
+
+			<div class="form-group row">
+				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Titre&nbsp;<sup><span class="text-danger">*</span></sup></label>
+				<div class="col-sm-10">
+					<input type="text" class="form-control form-control-sm field-separate" id="titre" name="titre" [(ngModel)]="production.titre" #titreRef="ngModel" required [class.is-invalid]="titreRef.invalid && titreRef.touched">
+				</div>
+			</div>
+
+			<div class="form-group row">
+				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Auteur(s)&nbsp;<sup><span class="text-danger">*</span></sup></label>
+				<div class="col-sm-10">
+					<input type="text" class="form-control form-control-sm field-separate" id="auteurs" name="auteurs" [(ngModel)]="production.auteurs" #auteursRef="ngModel" required [class.is-invalid]="auteursRef.invalid && auteursRef.touched">
+				</div>
+			</div>
+
+			<div class="form-group row">
+				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Groupe(s)</label>
+				<div class="col-sm-10">
+					<input type="text" class="form-control form-control-sm field-separate" id="groupes" name="groupes" [(ngModel)]="production.groupes">
+				</div>
+			</div>
+
+			<div class="form-group row">
+				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Plateforme</label>
+				<div class="col-sm-10">
+					<input type="text" class="form-control form-control-sm field-separate" id="plateforme" name="plateforme" [(ngModel)]="production.plateforme">
+				</div>
+			</div>
+
+			<div class="form-group row">
+				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Commentaire</label>
+				<div class="col-sm-10">
+					<textarea class="form-control form-control-sm field-separate" id="commentaire" name="commentaire" [(ngModel)]="production.commentaire"></textarea>
+				</div>
+			</div>
+
+			<div class="form-group row">
+				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Informations privées</label>
+				<div class="col-sm-10">
+					<textarea class="form-control form-control-sm field-separate" id="informationsPrivees" name="informationsPrivees" [(ngModel)]="production.informationsPrivees"></textarea>
+				</div>
+			</div>
+
+			<div class="form-group row">
+				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Gestionnaire&nbsp;<sup><span class="text-danger">*</span></sup></label>
+				<div class="col-sm-10">
+						<select class="form-select form-select-sm field-separate" id="numeroParticipant" name="numeroParticipant" [(ngModel)]="production.numeroGestionnaire">
+				    @for (participant of participants; track participant.numeroParticipant) {
+							<option [ngValue]="participant.numeroParticipant">{{ participant.pseudonyme }} = {{ participant.nom }}&nbsp;{{ participant.prenom }}</option>
+				    }
+						</select>
+				</div>
+			</div>
+
+			<div class="form-group row">
+				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Vignette</label>
+				<div class="col-sm-10">
+					<input type="file" class="form-control form-control-sm field-separate" id="vignette" name="vignette" accept="image/png, image/gif, image/jpeg" (change)="onVignetteSelected($event)">
+				</div>
+			</div>
+
+		</div>
+		<div class="card-footer">
+			<button type="button" class="btn btn-warning btn-sm" data-bs-toggle="modal" data-bs-target="#modalModifier" [disabled]="formRef.invalid"><i class="fa-solid fa-check"></i>&nbsp;Modifier</button>
+			<button type="button" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#modalEffacer" style="float: right;"><i class="fa-solid fa-trash"></i>&nbsp;Effacer</button>
+		</div>
+	</div>
+</form>
+
+<div class="modal fade" id="modalModifier" tabindex="-1" aria-labelledby="modalModifierTitre" aria-hidden="true">
+	<div class="modal-dialog modal-dialog-centered" role="document">
+		<div class="modal-content">
+			<div class="modal-header">
+				<h5 class="modal-title" id="modalModifierTitre">Modification</h5>
+			</div>
+			<div class="modal-body">Actualiser cet enregistrement ?</div>
+			<div class="modal-footer">
+				<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Annuler</button>
+				<button type="button" class="btn btn-warning btn-sm" (click)="updateConfirmed()" data-bs-dismiss="modal">Confirmer</button>
+			</div>
+		</div>
+	</div>
+</div>
+
+<div class="modal fade" id="modalEffacer" tabindex="-1" aria-labelledby="modalEffacerTitre" aria-hidden="true">
+	<div class="modal-dialog modal-dialog-centered" role="document">
+		<div class="modal-content">
+			<div class="modal-header">
+				<h5 class="modal-title text-danger" id="modalEffacerTitre">Suppression</h5>
+			</div>
+			<div class="modal-body">Effacer cet enregistrement ?</div>
+			<div class="modal-footer">
+				<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Annuler</button>
+				<button type="button" class="btn btn-danger btn-sm" (click)="deleteConfirmed()" data-bs-dismiss="modal">Confirmer</button>
+			</div>
+		</div>
+	</div>
+</div>

+ 58 - 9
src/app/production-update/production-update.component.ts

@@ -1,11 +1,60 @@
-import { Component } from '@angular/core';
-
-@Component({
-  selector: 'app-production-update',
-  imports: [],
-  templateUrl: './production-update.component.html',
-  styleUrl: './production-update.component.css'
-})
-export class ProductionUpdateComponent {
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { ProductionShort, ProductionEnum, ProductionTypeList } from '../production';
+import { ProductionService } from '../production.service';
+import { ParticipantShort } from '../participant';
+import { ParticipantService } from '../participant.service';
+import { FormsModule, NgForm } from '@angular/forms'; 
+
+@Component({ selector: 'app-production-update', imports: [FormsModule], templateUrl: './production-update.component.html', styleUrl: './production-update.component.css' })
+
+export class ProductionUpdateComponent implements OnInit
+{
+  
+  participants: ParticipantShort[] = [];
+
+  types: ProductionEnum[] = ProductionTypeList;
+  
+  @ViewChild('formRef') productionForm!: NgForm;
+  
+  production: ProductionShort = new ProductionShort();
+  
+  numeroProduction: number = 0;
+
+  constructor(private productionService: ProductionService, private participantService: ParticipantService, private route: ActivatedRoute, private router: Router) { }
+
+  ngOnInit(): void 
+  { 
+    this.retreiveParticipants();
+    this.numeroProduction = this.route.snapshot.params['numeroProduction'];
+    this.productionService.getByIdProduction(this.numeroProduction).subscribe(data => { this.production = data; });
+ }
+
+  private retreiveParticipants() { this.participantService.getOptionListParticipant().subscribe(data => { this.participants = data; }); }
+
+  onVignetteSelected(event: any) 
+  { 
+    const et = event.target;
+    const reader = new FileReader();
+
+    if (et.files && et.files.length > 0) 
+    {
+      const file = et.files[0];
+     
+      reader.onloadend = async (e: any) => { if (e.target.result) { this.production.vignette = e.target.result; } }
+
+      reader.readAsDataURL(file);
+		}
+  }
+ 
+  private saveProduction() { this.productionService.updateProduction(this.numeroProduction, this.production).subscribe({ next: () => { this.goToListProduction(); }, error: (err: any) => { console.log(err); }, complete: () => { } }); }
+
+  updateConfirmed() { if (this.productionForm.valid) { this.saveProduction(); } }
+
+  deleteConfirmed() { this.productionService.deleteProduction(this.numeroProduction).subscribe(() => { this.goToListProduction(); }); }
+
+  goToListProduction() {this.router.navigate(['/production-list'], { queryParams: { 'refresh': this.getRandomInteger(1, 100000) } }); }
+  
+  private getRandomInteger(min: number, max: number) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min)) + min; }
 
 }

+ 0 - 0
src/app/production-upload/production-upload.component.css


+ 29 - 0
src/app/production-upload/production-upload.component.html

@@ -0,0 +1,29 @@
+<br />
+<form #formRef="ngForm" (ngSubmit)="addProductionFile()" class="needs-validation">
+	<div class="card shadow">
+		<div class="card-header">Changement de l'archive d'une production</div>
+		<div class="card-header shadow-sm">
+			<button (click)="goToListProduction()" class="btn btn-primary btn-sm"><i class="fa-solid fa-xmark"></i>&nbsp;Retour</button>
+		</div>
+		<div class="card-body">
+
+			<div class="form-group row">
+				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Titre</label>
+				<div class="col-sm-10">
+					<input type="text" class="form-control form-control-sm field-separate" id="titre" name="titre" [(ngModel)]="production.titre" disabled>
+				</div>
+			</div>
+
+			<div class="form-group row">
+				<label class="col-sm-2 col-form-label col-form-label-sm label-nobr">Archive</label>
+				<div class="col-sm-10">
+					<input type="file" class="form-control form-control-sm field-separate" id="archive" name="archive" accept="application/zip" (change)="onArchiveSelected($event)">
+				</div>
+			</div>
+
+		</div>
+		<div class="card-footer">
+			<button type="button" class="btn btn-success btn-sm text-left" type="submit" [disabled]="formRef.invalid"><i class="fa-solid fa-plus"></i>&nbsp;Téléverser</button>
+		</div>
+	</div>
+</form>

+ 23 - 0
src/app/production-upload/production-upload.component.spec.ts

@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ProductionUploadComponent } from './production-upload.component';
+
+describe('ProductionUploadComponent', () => {
+  let component: ProductionUploadComponent;
+  let fixture: ComponentFixture<ProductionUploadComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [ProductionUploadComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(ProductionUploadComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});

+ 49 - 0
src/app/production-upload/production-upload.component.ts

@@ -0,0 +1,49 @@
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { ProductionFile } from '../production';
+import { ProductionService } from '../production.service';
+import { FormsModule } from '@angular/forms'; 
+
+@Component({ selector: 'app-production-upload', imports: [FormsModule], templateUrl: './production-upload.component.html', styleUrl: './production-upload.component.css' })
+
+export class ProductionUploadComponent implements OnInit 
+{
+
+  production: ProductionFile = new ProductionFile();
+  
+  numeroProduction: number = 0;
+
+  constructor(private productionService: ProductionService, private route: ActivatedRoute, private router: Router) { }
+
+  ngOnInit(): void 
+  { 
+    this.numeroProduction = this.route.snapshot.params['numeroProduction'];
+    this.productionService.getByIdProductionFile(this.numeroProduction).subscribe(data => { this.production = data; });
+  }
+
+  onArchiveSelected(event: any) 
+  { 
+    const et = event.target;
+    const reader = new FileReader();
+
+    if (et.files && et.files.length > 0) 
+    {
+      const file = et.files[0];
+ 
+      this.production.nomArchive = file.name;
+      
+      reader.onloadend = async (e: any) => { if (e.target.result) { this.production.archive = e.target.result; } }
+
+      reader.readAsDataURL(file);
+		}
+  }
+ 
+  private saveProduction() { this.productionService.uploadProductionFile(this.numeroProduction, this.production).subscribe({ next: () => { this.goToListProduction(); }, error: (err: any) => { console.log(err); }, complete: () => { } }); }
+
+  addProductionFile() { this.saveProduction(); }
+
+  goToListProduction() {this.router.navigate(['/production-list'], { queryParams: { 'refresh': this.getRandomInteger(1, 100000) } }); }
+  
+  private getRandomInteger(min: number, max: number) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min)) + min; }
+
+}

+ 17 - 4
src/app/production.service.ts

@@ -1,7 +1,7 @@
 import { Injectable } from '@angular/core';
-import { HttpClient } from '@angular/common/http'
+import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http'
 import { Observable } from 'rxjs';
-import { Production, ProductionShort } from './production';
+import { Production, ProductionShort, ProductionFile } from './production';
 
 @Injectable({ providedIn: 'root' })
 
@@ -14,11 +14,24 @@ export class ProductionService
   
   getListProduction(): Observable<ProductionShort[]>{ return this.httpClient.get<ProductionShort[]>(`${this.baseURL}/list`); }
 
+  getProductionFile(id: number): Observable<HttpResponse<Blob>>
+  {
+    let headers = new HttpHeaders();
+    
+    headers = headers.append('Accept', 'application/zip');
+
+    return this.httpClient.get(`${this.baseURL}/file/${id}`, { headers: headers, observe: 'response', responseType: 'blob' }); 
+  }
+
   createProduction(production: Production): Observable<Object>{ return this.httpClient.post(`${this.baseURL}/create`, production); }
 
-  getByIdProduction(id: number): Observable<Production>{ return this.httpClient.get<Production>(`${this.baseURL}/form/${id}`); }
+  getByIdProduction(id: number): Observable<ProductionShort>{ return this.httpClient.get<ProductionShort>(`${this.baseURL}/form/${id}`); }
+
+  updateProduction(id: number, production: ProductionShort): Observable<Object>{ return this.httpClient.put(`${this.baseURL}/update/${id}`, production); }
+
+  getByIdProductionFile(id: number): Observable<ProductionFile>{ return this.httpClient.get<ProductionFile>(`${this.baseURL}/formfile/${id}`); }
 
-  updateProduction(id: number, production: Production): Observable<Object>{ return this.httpClient.put(`${this.baseURL}/update/${id}`, production); }
+  uploadProductionFile(id: number, production: ProductionFile): Observable<Object>{ return this.httpClient.put(`${this.baseURL}/upload/${id}`, production); }
 
   deleteProduction(id: number): Observable<Object>{ return this.httpClient.delete(`${this.baseURL}/delete/${id}`); }
   

+ 21 - 22
src/app/production.ts

@@ -1,18 +1,20 @@
 
-export enum ProductionTypeEnum
-{
-  EXECUTABLE = "Exécutable",
-  GRAPHE = "Graphe", 
-  MUSIQUE = "Musique", 
-  VIDEO = "Vidéo", 
-  TOPIC = "Topic",
-  AUTRE = "Autre"
-}
+export class ProductionEnum { key!: string; value!: string; }
+
+export const ProductionTypeList: ProductionEnum[] = 
+[ 
+  { key: "EXECUTABLE", value: "Exécutable"}, 
+  { key: "GRAPHE", value: "Graphe"}, 
+  { key: "MUSIQUE", value: "Musique"}, 
+  { key: "VIDEO", value: "Vidéo"}, 
+  { key: "TOPIC", value: "Topic"}, 
+  { key: "AUTRE", value: "Autre"} 
+];
 
 export class Production 
 {
   numeroProduction: number = 0;
-  type: ProductionTypeEnum = ProductionTypeEnum.EXECUTABLE;
+  type: string = "AUTRE";
   titre: string = "";
   auteurs: string = "";
   groupes: string = "";
@@ -26,24 +28,13 @@ export class Production
   numeroVersion: number = 0;
 }
 
-
-export enum ProductionTypeKeys
-{
-  EXECUTABLE = "EXECUTABLE",
-  GRAPHE = "GRAPHE", 
-  MUSIQUE = "MUSIQUE", 
-  VIDEO = "VIDEO", 
-  TOPIC = "TOPIC",
-  AUTRE = "AUTRE"
-}
-
 export class ProductionShort
 {
   dateCreation: string = "";
   dateModification: string = "";
   numeroProduction: number = 0;
   adresseIP: string = "";
-  type: ProductionTypeKeys = ProductionTypeKeys.EXECUTABLE;
+  type: string = "AUTRE";
   titre: string = "";
   auteurs: string = "";
   groupes: string = "";
@@ -56,3 +47,11 @@ export class ProductionShort
   vignette!: string | any;
   numeroVersion: number = 0;
 }
+
+export class ProductionFile
+{
+  numeroProduction: number = 0;
+  titre: string = "";
+  nomArchive: string = "";
+  archive!: string | any;
+}