tasks done
This commit is contained in:
@@ -16,6 +16,7 @@ export interface TpeDevice {
|
||||
versionOs: string;
|
||||
adresseIp: string;
|
||||
adresseMac: string;
|
||||
assigned: boolean;
|
||||
agentConnecteId: string;
|
||||
derniereConnexionAgent: string;
|
||||
derniereDeconnexionAgent: string;
|
||||
|
||||
@@ -229,9 +229,14 @@ export class AgentService {
|
||||
|
||||
|
||||
|
||||
assigner(tpeId: string, agentId:string):Observable<Agent | undefined>{
|
||||
return this.http.post<Agent>(`${this.apiUrl}/${agentId}/terminaux/${tpeId}`,
|
||||
{Headers: this.getNgrokHeaders()}).pipe(map(res=> res),
|
||||
assigner(tpeIds: string[], agentId:string):Observable<Agent | undefined>{
|
||||
const payload = {
|
||||
terminalIds: [
|
||||
...tpeIds
|
||||
]
|
||||
}
|
||||
return this.http.put<Agent>(`${this.apiUrl}/${agentId}/terminaux`,
|
||||
payload, {headers: this.getNgrokHeaders()}).pipe(map(res=> res),
|
||||
catchError((err)=>{
|
||||
console.error(err);
|
||||
return of(undefined);
|
||||
|
||||
@@ -370,7 +370,7 @@
|
||||
</div>
|
||||
<div modal-actions class="flex justify-end gap-2">
|
||||
<z-button zType="destructive" (click)="closeAssignTpeModal()">Annuler</z-button>
|
||||
<button z-button [disabled]="selectedTpeId().length === 0 || tpesLoading()" (click)="confirmAssignTpe()">
|
||||
<button z-button [disabled]="tpesLoading()" (click)="confirmAssignTpe()">
|
||||
Assigner
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -458,25 +458,45 @@ export class AgentsPage {
|
||||
|
||||
confirmAssignTpe() {
|
||||
const agent = this.assigningAgent();
|
||||
const tpeId = this.selectedTpeId();
|
||||
if (!agent || tpeId.length === 0) {
|
||||
alert('Veuillez sélectionner un TPE');
|
||||
const tpeId = this.selectedTpeId().map(id=> id);
|
||||
if (!agent) {
|
||||
toast.error('Veuillez sélectionner un TPE');
|
||||
return;
|
||||
}
|
||||
|
||||
forkJoin(this.selectedTpeId().map(id=> this.api.assigner(id, agent.id))).subscribe(
|
||||
{
|
||||
this.api.assigner(tpeId, agent.id).subscribe({
|
||||
next:()=>{
|
||||
this.assignTpeModalOpen.set(false);
|
||||
this.assigningAgent.set(undefined);
|
||||
this.selectedTpeId.set([]);
|
||||
toast.success(`Tpe affecté à l'agent avec succès1`)
|
||||
toast.success("Termiaux affectés avec succès!");
|
||||
const params = {
|
||||
page: this.page(),
|
||||
size: this.size(),
|
||||
search: this.search(),
|
||||
sortKey: this.sort().key,
|
||||
sortDir: this.sort().dir as SortDir,
|
||||
};
|
||||
this.fetch(params);
|
||||
},
|
||||
error: (err)=>{
|
||||
console.error(err);
|
||||
error:()=>{
|
||||
console.error("Une érreur s'est produite")
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
// forkJoin(this.selectedTpeId().map(id=> this.api.assigner(id, agent.id))).subscribe(
|
||||
// {
|
||||
// next:()=>{
|
||||
// this.assignTpeModalOpen.set(false);
|
||||
// this.assigningAgent.set(undefined);
|
||||
// this.selectedTpeId.set([]);
|
||||
// toast.success(`Tpe affecté à l'agent avec succès1`)
|
||||
// },
|
||||
// error: (err)=>{
|
||||
// console.error(err);
|
||||
// }
|
||||
// }
|
||||
// )
|
||||
|
||||
// // Assign TPE to agent
|
||||
// this.tpeSvc.assigner(tpeId, agent.id).subscribe({
|
||||
|
||||
@@ -497,8 +497,8 @@ export class Course {
|
||||
onResultatConfirm() {
|
||||
const c = this.selectedCourseForResultat();
|
||||
if (!c) return;
|
||||
|
||||
const resultat = this.resultatsMap().get(c.id);
|
||||
|
||||
if (!resultat) {
|
||||
toast.error('Aucun résultat à confirmer');
|
||||
return;
|
||||
|
||||
@@ -67,8 +67,6 @@ export class TpeSelect {
|
||||
ngOnInit() {
|
||||
// Initialiser les TPE sélectionnés si fournis
|
||||
this.selectedIds.set(new Set(this.selected));
|
||||
|
||||
|
||||
}
|
||||
|
||||
private loadTpes(params:ListParams) {
|
||||
@@ -77,11 +75,11 @@ export class TpeSelect {
|
||||
next: (res) => {
|
||||
// Filtrer : TPE non assignés ou déjà assignés à cet agent
|
||||
// console.log(res.content);
|
||||
// const available = res.content.filter(
|
||||
// (t) =>
|
||||
// !t.agentConnecteId || t.agentConnecteId === this.agent?.id
|
||||
// );
|
||||
this.tpes.set(res.content);
|
||||
const available = res.content.filter(
|
||||
(t) =>
|
||||
!t.assigned || t.agentConnecteId === this.agent?.id
|
||||
);
|
||||
this.tpes.set(available);
|
||||
this.total.set(res.pageable.total);
|
||||
this.loading.set(false);
|
||||
},
|
||||
@@ -94,10 +92,10 @@ export class TpeSelect {
|
||||
|
||||
toggleTpe(tpe: TpeDevice) {
|
||||
const current = new Set(this.selectedIds());
|
||||
if (current.has(tpe.id)) {
|
||||
current.delete(tpe.id);
|
||||
if (current.has(String(tpe.id))) {
|
||||
current.delete(String(tpe.id));
|
||||
} else {
|
||||
current.add(tpe.id);
|
||||
current.add(String(tpe.id));
|
||||
}
|
||||
this.selectedIds.set(current);
|
||||
this.selectionChange.emit(Array.from(current));
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
[total]="total()"
|
||||
[page]="page()"
|
||||
[perPage]="perPage()"
|
||||
(pageChange)="page.set($event)"
|
||||
(pageChange)="page.set($event - 1)"
|
||||
(perPageChange)="perPage.set($event)"
|
||||
></app-paginator>
|
||||
</div>
|
||||
|
||||
@@ -28,6 +28,7 @@ import { forkJoin, Subject } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
|
||||
import { toast } from 'ngx-sonner';
|
||||
import { PointsVenteService } from 'src/app/core/services/points-vente';
|
||||
import { PointVente } from 'src/app/core/interfaces/points-ventes';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@@ -76,6 +77,8 @@ export class TpePage implements OnInit {
|
||||
assignmentStats = signal({ total: 0, assignes: 0, disponibles: 0 });
|
||||
statsLoading = signal(false);
|
||||
|
||||
pointDeVenteMap = signal<Map<string, PointVente>>(new Map());
|
||||
|
||||
// Live search
|
||||
private searchSubject = new Subject<string>();
|
||||
|
||||
@@ -102,21 +105,10 @@ export class TpePage implements OnInit {
|
||||
key: 'pointDeVenteId',
|
||||
label: 'Point de vente',
|
||||
sortable: true,
|
||||
cell:(p) => {
|
||||
let pointVente = signal('');
|
||||
this.pointVenteService.getById(p.pointDeVenteId).subscribe({
|
||||
next: (pdv)=>{
|
||||
if(!pdv || pdv === undefined){
|
||||
pointVente.set("Aucun point")
|
||||
return;
|
||||
};
|
||||
pointVente.set(`${pdv.ville}/${pdv.adresse}`)
|
||||
},
|
||||
error:(err)=>{
|
||||
pointVente.set('Aucun point')
|
||||
}
|
||||
})
|
||||
return pointVente();
|
||||
cell: (t) => {
|
||||
const pdv = this.pointDeVenteMap().get(String(t.pointDeVenteId));
|
||||
if (!pdv) return 'Pas de point de vente';
|
||||
return `${pdv.ville}/${pdv.adresse}`;
|
||||
},
|
||||
},
|
||||
{ key: 'versionLogicielle', label: 'Version', sortable: true },
|
||||
@@ -127,7 +119,7 @@ export class TpePage implements OnInit {
|
||||
key: 'assigne',
|
||||
label: 'Assigné à',
|
||||
cell: (d) => {
|
||||
if (!d.agentConnecteId) {
|
||||
if (!d.assigned) {
|
||||
return '<span class="text-muted-foreground text-sm">Non assigné</span>';
|
||||
}
|
||||
// a rectifier apres avec les données des agents!
|
||||
@@ -296,10 +288,32 @@ export class TpePage implements OnInit {
|
||||
});
|
||||
} else {
|
||||
// Normal list with pagination
|
||||
const map: Map<string, PointVente> = new Map();
|
||||
this.api.list(params).subscribe({
|
||||
next: (res) => {
|
||||
this.rows.set(res.content);
|
||||
this.total.set(res.pageable.total);
|
||||
const requests = res.content
|
||||
.filter((t) => t.pointDeVenteId)
|
||||
.map((t) => this.pointVenteService.getById(t.pointDeVenteId!));
|
||||
forkJoin(requests).subscribe({
|
||||
next: (pdvs) => {
|
||||
res.content.forEach((t) => {
|
||||
if (!t.pointDeVenteId) return;
|
||||
|
||||
const pdv = pdvs.find((p) => p?.id === t.pointDeVenteId);
|
||||
if (!pdv) return;
|
||||
|
||||
map.set(String(t.pointDeVenteId), pdv);
|
||||
});
|
||||
// ✅ SET ICI seulement
|
||||
this.pointDeVenteMap.set(map);
|
||||
this.loading.set(false);
|
||||
},
|
||||
error: () => this.loading.set(false),
|
||||
});
|
||||
|
||||
this.pointDeVenteMap.set(map);
|
||||
this.loading.set(false);
|
||||
},
|
||||
error: () => {
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
>
|
||||
<z-select
|
||||
id="hippodromeId"
|
||||
[zDisabled]="getCourseStatut()!==undefined && getCourseStatut() !=='BROUILLON'"
|
||||
placeholder="Rechercher une réunion..."
|
||||
formControlName="hippodromeId"
|
||||
[zLabel]="selectedHippodromeLabel() || ''"
|
||||
@@ -43,6 +44,7 @@
|
||||
>
|
||||
<z-form-control>
|
||||
<input
|
||||
[readOnly]="getCourseStatut()!==undefined && getCourseStatut() !=='BROUILLON'"
|
||||
z-input
|
||||
type="number"
|
||||
min="1"
|
||||
@@ -63,6 +65,7 @@
|
||||
>
|
||||
<z-form-control>
|
||||
<input
|
||||
[readOnly]="getCourseStatut()!==undefined && getCourseStatut() !=='BROUILLON'"
|
||||
z-input
|
||||
type="date"
|
||||
placeholder="Ex: 10/07/2025"
|
||||
@@ -82,6 +85,7 @@
|
||||
>
|
||||
<z-form-control>
|
||||
<input
|
||||
[readOnly]="getCourseStatut()!==undefined && getCourseStatut() !=='BROUILLON'"
|
||||
z-input
|
||||
placeholder="Ex: Plat"
|
||||
formControlName="discipline"
|
||||
@@ -101,6 +105,7 @@
|
||||
>
|
||||
<z-form-control>
|
||||
<input
|
||||
[readOnly]="getCourseStatut()!==undefined && getCourseStatut() !=='BROUILLON'"
|
||||
z-input
|
||||
type="text"
|
||||
placeholder="Ex: Grand Prix du Sahel"
|
||||
@@ -145,6 +150,7 @@
|
||||
</label>
|
||||
<div class="flex gap-3 items-center">
|
||||
<input
|
||||
[readOnly]="getCourseStatut()!==undefined && getCourseStatut() !=='BROUILLON'"
|
||||
z-input
|
||||
type="time"
|
||||
formControlName="heureDepartPrevue"
|
||||
@@ -184,6 +190,7 @@
|
||||
@for (t of courseTypes; track t.value) {
|
||||
<label class="flex items-center gap-2 text-sm">
|
||||
<input
|
||||
[disabled]="getCourseStatut()!==undefined && getCourseStatut() !=='BROUILLON'"
|
||||
type="checkbox"
|
||||
[value]="t.value"
|
||||
(change)="onToggleType($event)"
|
||||
@@ -208,6 +215,7 @@
|
||||
"
|
||||
>
|
||||
<input
|
||||
[readOnly]="getCourseStatut()!==undefined && getCourseStatut() !=='BROUILLON'"
|
||||
z-input
|
||||
type="number"
|
||||
min="1"
|
||||
@@ -223,6 +231,7 @@
|
||||
>
|
||||
<z-form-control>
|
||||
<input
|
||||
[readOnly]="getCourseStatut()!==undefined && getCourseStatut() !=='BROUILLON'"
|
||||
z-input
|
||||
type="number"
|
||||
min="1"
|
||||
@@ -238,6 +247,7 @@
|
||||
>
|
||||
<z-form-control>
|
||||
<input
|
||||
[readOnly]="getCourseStatut()!==undefined && getCourseStatut() !=='BROUILLON'"
|
||||
z-input
|
||||
placeholder="Ex: A"
|
||||
formControlName="categorie"
|
||||
@@ -267,7 +277,7 @@
|
||||
>Statut</label
|
||||
>
|
||||
<z-form-control>
|
||||
<z-select formControlName="statut" class="w-full">
|
||||
<z-select [zDisabled]="updateDisabled()" formControlName="statut" class="w-full">
|
||||
@for (s of courseStatus; track s.value) {
|
||||
<z-select-item [zValue]="s.value">{{ s.label }}</z-select-item>
|
||||
}
|
||||
@@ -281,6 +291,7 @@
|
||||
>
|
||||
<z-form-control>
|
||||
<input
|
||||
[readOnly]="getCourseStatut()!==undefined && getCourseStatut() !=='BROUILLON'"
|
||||
z-input
|
||||
type="number"
|
||||
min="1"
|
||||
@@ -314,6 +325,7 @@
|
||||
>
|
||||
<z-form-control>
|
||||
<input
|
||||
readOnly
|
||||
z-input
|
||||
formControlName="createdBy"
|
||||
readonly
|
||||
@@ -328,6 +340,7 @@
|
||||
>
|
||||
<z-form-control>
|
||||
<input
|
||||
readOnly
|
||||
z-input
|
||||
formControlName="validatedBy"
|
||||
readonly
|
||||
|
||||
@@ -60,6 +60,20 @@ export class CourseForm implements OnInit, AfterViewInit, OnDestroy {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
getCourseStatut():string|undefined{
|
||||
return this._value?.statut
|
||||
}
|
||||
|
||||
updateDisabled():boolean{
|
||||
const statut = this._value?.statut;
|
||||
if(statut !== undefined){
|
||||
if(statut === 'OUVERT' || statut === 'FERME'){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
form: FormGroup;
|
||||
submitted = false;
|
||||
|
||||
|
||||
@@ -21,19 +21,18 @@
|
||||
[disabled]="!canSave()">
|
||||
Enregistrer
|
||||
</button>
|
||||
<button
|
||||
<!-- <button
|
||||
type="button"
|
||||
class="flex-1 px-3 py-2 text-sm rounded border border-blue-300 bg-blue-50 text-blue-700 hover:bg-blue-100 disabled:opacity-50"
|
||||
(click)="validate.emit()"
|
||||
[disabled]="!canValidate()">
|
||||
Valider
|
||||
</button>
|
||||
</button> -->
|
||||
<button
|
||||
type="button"
|
||||
class="flex-1 px-3 py-2 text-sm rounded border border-emerald-300 bg-emerald-50 text-emerald-700 hover:bg-emerald-100 disabled:opacity-50"
|
||||
(click)="confirm.emit()"
|
||||
[disabled]="!canConfirm()"
|
||||
>
|
||||
[disabled]="!canConfirm()">
|
||||
Confirmer
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { ZardFormModule } from '@shared/components/form/form.module';
|
||||
import { ZardSelectComponent } from '@shared/components/select/select.component';
|
||||
import { ZardSelectItemComponent } from '@shared/components/select/select-item.component';
|
||||
import { Course, CourseType } from 'src/app/core/interfaces/course';
|
||||
import { Resultat } from 'src/app/core/interfaces/resultat';
|
||||
import { Resultat, ResultatStatut } from 'src/app/core/interfaces/resultat';
|
||||
|
||||
type PlaceRow = { picks: FormArray<FormControl<number | null>> };
|
||||
type ResultatShape = { places: FormArray<FormGroup<PlaceRow>> };
|
||||
@@ -65,12 +65,12 @@ export class ResultatForm {
|
||||
return this.resultat ? 'PROVISOIRE' : 'EN_ATTENTE';
|
||||
});
|
||||
|
||||
canValidate(): boolean {
|
||||
return this.statut() === 'EN_ATTENTE';
|
||||
}
|
||||
// canValidate(): boolean {
|
||||
// return this.statut() === 'PROVISOIRE';
|
||||
// }
|
||||
|
||||
canConfirm(): boolean {
|
||||
return this.statut() === 'PROVISOIRE';
|
||||
return this.statut() === 'PROVISOIRE' || this.statut() === 'OFFICIEL';
|
||||
}
|
||||
|
||||
// Helper methods for template
|
||||
@@ -228,6 +228,7 @@ export class ResultatForm {
|
||||
});
|
||||
|
||||
ngOnInit() {
|
||||
|
||||
this.seed();
|
||||
// Watch for changes to auto-populate places when ex-aequo is detected
|
||||
this.setupAutoPopulate();
|
||||
@@ -549,6 +550,10 @@ export class ResultatForm {
|
||||
}
|
||||
}
|
||||
|
||||
if(this.statut()==='OFFICIEL'){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export const environment = {
|
||||
production: false,
|
||||
apiBaseUrl: 'http://192.168.40.204:8080',
|
||||
apiBaseUrl: 'http://192.168.40.212:8080',
|
||||
depouillementBaseUrl: 'http://192.168.1.235:8383'
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user