From ed79cae77d502e30dc075e9e34b67788c08aa398 Mon Sep 17 00:00:00 2001 From: OnlyPapy98 Date: Mon, 29 Dec 2025 13:56:18 +0100 Subject: [PATCH] first step for plr game platform --- src/app/core/interfaces/resultat.ts | 47 +++-- src/app/core/services/agent-limit.ts | 6 +- src/app/core/services/agent.ts | 6 +- src/app/core/services/course.ts | 2 +- src/app/core/services/resultat.ts | 126 +++++++------ src/app/core/services/reunion.ts | 16 +- src/app/core/services/role.ts | 8 +- src/app/core/services/services-utils.ts | 2 +- src/app/core/services/tpe.ts | 4 +- src/app/core/services/user.ts | 10 +- src/app/dashboard/dashboard-routing-module.ts | 4 + src/app/dashboard/layout/layout.ts | 2 +- src/app/dashboard/pages/agents/agents.html | 4 +- src/app/dashboard/pages/agents/agents.ts | 14 +- src/app/dashboard/pages/courses/courses.html | 8 +- src/app/dashboard/pages/courses/courses.ts | 168 ++++++++---------- .../pages/hippodrome/hippodrome.html | 2 +- .../dashboard/pages/hippodrome/hippodrome.ts | 4 +- src/app/dashboard/pages/limits/limits.html | 2 +- src/app/dashboard/pages/limits/limits.ts | 20 +-- src/app/dashboard/pages/main/main.ts | 4 +- src/app/dashboard/pages/rapport/rapport.css | 0 src/app/dashboard/pages/rapport/rapport.html | 33 ++++ .../dashboard/pages/rapport/rapport.spec.ts | 23 +++ src/app/dashboard/pages/rapport/rapport.ts | 94 ++++++++++ src/app/dashboard/pages/reunion/reunion.html | 4 +- src/app/dashboard/pages/reunion/reunion.ts | 10 +- src/app/dashboard/pages/roles/roles.ts | 10 +- src/app/dashboard/pages/tpe/tpe.ts | 22 +-- src/app/dashboard/pages/users/users.ts | 8 +- .../shared/forms/course-form/course-form.html | 102 +++++------ .../shared/forms/course-form/course-form.ts | 134 ++++++++++++-- .../forms/resultat-form/resultat-form.html | 14 +- .../forms/resultat-form/resultat-form.ts | 66 +++++-- .../shared/forms/reunion-form/reunion-form.ts | 2 +- src/app/shared/paging/data-source.ts | 2 +- .../shared/paging/paginated-http.service.ts | 4 +- src/app/shared/paging/paging.ts | 2 +- src/environments/environment.development.ts | 2 +- src/environments/environment.ts | 2 +- 40 files changed, 620 insertions(+), 373 deletions(-) create mode 100644 src/app/dashboard/pages/rapport/rapport.css create mode 100644 src/app/dashboard/pages/rapport/rapport.html create mode 100644 src/app/dashboard/pages/rapport/rapport.spec.ts create mode 100644 src/app/dashboard/pages/rapport/rapport.ts diff --git a/src/app/core/interfaces/resultat.ts b/src/app/core/interfaces/resultat.ts index 0baa814..6ed11b4 100644 --- a/src/app/core/interfaces/resultat.ts +++ b/src/app/core/interfaces/resultat.ts @@ -1,5 +1,13 @@ import { Course } from './course'; + +export enum ResultatStatut { + PROVISOIRE, + OFFICIEL, + ANNULE, + EN_ATTENTE +} + export interface Resultat { id: string; course: Course; @@ -8,7 +16,7 @@ export interface Resultat { * The backend returns an array of strings/numbers (cheval numbers); * in the UI we normalize them to plain numbers. */ - ordreArrivee: number[]; + ordreArrivee: string; /** * Chevaux en dead-heat (ex aequo), represented by their numbers. */ @@ -26,33 +34,24 @@ export interface Resultat { // API response structure (course may be just an ID in some cases) export interface ResultatApiResponse { id: string | number; - course: Course | string | number; - /** - * In the raw API this is an array of strings/numbers. - */ - ordreArrivee: (string | number)[]; - chevauxDeadHeat: (string | number)[]; - totalMises: number; - masseAPartager: number; - prelevementsLegaux: number; - montantRembourse: number; - montantCagnotte: number; - adeadHeat: boolean; + courseId: string | number; + ordreArrivee: string; + courseNom: string; + courseNumero: number; + reunionNumero:number; + hippodromeNom: string; + statut: ResultatStatut; + datePublication?: string; + dateAnnulation?: string; + dateValidation?: string; createdAt?: string; updatedAt?: string; } // POST payload structure export interface CreateResultatPayload { - course: { - id: string | number; - }; - ordreArrivee: string[]; - chevauxDeadHeat?: (string | number)[]; - totalMises?: number; - masseAPartager?: number; - prelevementsLegaux?: number; - montantRembourse?: number; - montantCagnotte?: number; - adeadHeat?: boolean; + courseId: number; + statut: ResultatStatut; + ordreArrivee: string; + notes?: string } diff --git a/src/app/core/services/agent-limit.ts b/src/app/core/services/agent-limit.ts index 0264599..967091c 100644 --- a/src/app/core/services/agent-limit.ts +++ b/src/app/core/services/agent-limit.ts @@ -108,7 +108,7 @@ export class AgentLimitService { let httpParams = new HttpParams(); if (params) { if (params.page) httpParams = httpParams.set('page', params.page.toString()); - if (params.perPage) httpParams = httpParams.set('perPage', params.perPage.toString()); + if (params.size) httpParams = httpParams.set('size', params.size.toString()); if (params.search) httpParams = httpParams.set('search', params.search); if (params.sortKey) httpParams = httpParams.set('sortKey', params.sortKey); if (params.sortDir) httpParams = httpParams.set('sortDir', params.sortDir); @@ -127,7 +127,7 @@ export class AgentLimitService { return normalizePage( { data: limits, meta: { total: limits.length } }, params.page || 1, - params.perPage || 10 + params.size || 10 ); } // Otherwise return all as single page @@ -207,7 +207,7 @@ export class AgentLimitService { // First, find the previous default limit return this.list({ page: 1, - perPage: 1000, + size: 1000, search: '', sortKey: 'code', sortDir: 'asc', diff --git a/src/app/core/services/agent.ts b/src/app/core/services/agent.ts index d0af32a..dfa0c16 100644 --- a/src/app/core/services/agent.ts +++ b/src/app/core/services/agent.ts @@ -274,7 +274,7 @@ export class AgentService { let httpParams = new HttpParams(); if (params) { if (params.page) httpParams = httpParams.set('page', params.page.toString()); - if (params.perPage) httpParams = httpParams.set('perPage', params.perPage.toString()); + if (params.size) httpParams = httpParams.set('perPage', params.size.toString()); if (params.search) httpParams = httpParams.set('search', params.search); if (params.sortKey) httpParams = httpParams.set('sortKey', params.sortKey); if (params.sortDir) httpParams = httpParams.set('sortDir', params.sortDir); @@ -296,7 +296,7 @@ export class AgentService { return normalizePage( { data: agents, meta: { total: agents.length } }, params.page || 1, - params.perPage || 10 + params.size || 10 ); } // Otherwise return all as single page @@ -445,7 +445,7 @@ export class AgentService { // Get all agents first return this.list({ page: 1, - perPage: 10000, + size: 10000, search: '', sortKey: 'code', sortDir: 'asc', diff --git a/src/app/core/services/course.ts b/src/app/core/services/course.ts index f82ad07..ce804f1 100644 --- a/src/app/core/services/course.ts +++ b/src/app/core/services/course.ts @@ -59,7 +59,7 @@ export class CourseService { return isNgrok ? { 'ngrok-skip-browser-warning': 'true' } : {}; } - list(params: ListParams, usePaginationEndpoint: boolean = true): Observable> { + list(params: ListParams): Observable> { const coursesList = this.http.get>(this.apiUrl, { headers: this.getNgrokHeaders(), params: this.servivesUtil.getParamsFromModel(params), diff --git a/src/app/core/services/resultat.ts b/src/app/core/services/resultat.ts index 848c2ef..72648c7 100644 --- a/src/app/core/services/resultat.ts +++ b/src/app/core/services/resultat.ts @@ -1,6 +1,8 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable, of, forkJoin } from 'rxjs'; +import { PaginatedHttpService } from '@shared/paging/paginated-http.service'; +import { ListParams, PagedResult } from '@shared/paging/paging'; import { map, catchError, switchMap } from 'rxjs/operators'; import { Resultat, ResultatApiResponse, CreateResultatPayload } from '../interfaces/resultat'; import { Course } from '../interfaces/course'; @@ -8,13 +10,20 @@ import { CourseService } from './course'; import { environment } from 'src/environments/environment.development'; const USE_SERVER = true; -const API_BASE = '/api/v1/resultat'; +const API_BASE = '/api/resultats'; @Injectable({ providedIn: 'root' }) export class ResultatService { private apiUrl = environment.apiBaseUrl + API_BASE; - constructor(private http: HttpClient, private courseService: CourseService) {} + constructor(private http: HttpClient, private courseService: CourseService, private pager: PaginatedHttpService) {} + + // Fetch raw paginated resultats from the backend and normalize paging + listRawPaged(params: ListParams): Observable> { + const url = this.apiUrl; + // Delegate to shared paginated HTTP helper (Spring-style defaults) + return this.pager.fetch(url, params); + } private getNgrokHeaders(): Record { const isNgrok = @@ -31,11 +40,8 @@ export class ResultatService { .get(`${this.apiUrl}/${id}`, { headers: this.getNgrokHeaders() }) .pipe( switchMap((apiResultat) => { - // Fetch the full course object if course is just an ID - const courseId = - typeof apiResultat.course === 'object' && 'id' in apiResultat.course - ? String(apiResultat.course.id) - : String(apiResultat.course); + // New API uses `courseId` explicitly + const courseId = String((apiResultat as any).courseId ?? ''); return this.courseService.getById(courseId).pipe( map((course) => { @@ -62,16 +68,8 @@ export class ResultatService { .get(this.apiUrl, { headers: this.getNgrokHeaders() }) .pipe( switchMap((apiResultats) => { - // Fetch all unique course IDs - const courseIds = [ - ...new Set( - apiResultats.map((r) => - typeof r.course === 'object' && 'id' in r.course - ? String(r.course.id) - : String(r.course) - ) - ), - ]; + // Fetch all unique course IDs (API uses courseId) + const courseIds = [...new Set(apiResultats.map((r) => String((r as any).courseId ?? '')))].filter(Boolean); // Fetch all courses in parallel const courseRequests = courseIds.map((id) => this.courseService @@ -91,10 +89,7 @@ export class ResultatService { return apiResultats .map((apiResultat) => { - const courseId = - typeof apiResultat.course === 'object' && 'id' in apiResultat.course - ? String(apiResultat.course.id) - : String(apiResultat.course); + const courseId = String((apiResultat as any).courseId ?? ''); const course = courseMap.get(courseId); if (!course) { return null; @@ -118,11 +113,23 @@ export class ResultatService { return of([]); } + // GET raw API responses (ResultatApiResponse[]) + listRaw(): Observable { + if (USE_SERVER) { + return this.http + .get(this.apiUrl, { headers: this.getNgrokHeaders() }) + .pipe( + catchError((err) => { + console.error('Error fetching raw resultats:', err); + return of([] as ResultatApiResponse[]); + }) + ); + } + return of([] as ResultatApiResponse[]); + } + // GET /api/v1/resultat/course/{courseId} getByCourseId(courseId: string): Observable { - if (!USE_SERVER) { - return of(undefined); - } return this.http .get(`${this.apiUrl}/course/${courseId}`, { @@ -169,28 +176,25 @@ export class ResultatService { // POST /api/v1/resultat create(payload: CreateResultatPayload): Observable { - if (USE_SERVER) { - return this.http - .post(this.apiUrl, payload, { headers: this.getNgrokHeaders() }) - .pipe( - switchMap((apiResultat) => { - const courseId = String(payload.course.id); - return this.courseService.getById(courseId).pipe( - map((course) => { - if (!course) { - throw new Error('Course not found'); - } - return this.transformApiResponse(apiResultat, course); - }) - ); - }), - catchError((err) => { - console.error('Error creating resultat:', err); - throw err; - }) - ); - } - throw new Error('Server mode is required'); + return this.http + .post(this.apiUrl, payload, { headers: this.getNgrokHeaders() }) + .pipe( + switchMap((apiResultat) => { + const courseId = String(payload.courseId); + return this.courseService.getById(courseId).pipe( + map((course) => { + if (!course) { + throw new Error('Course not found'); + } + return this.transformApiResponse(apiResultat, course); + }) + ); + }), + catchError((err) => { + console.error('Error creating resultat:', err); + throw err; + }) + ); } // PUT /api/v1/resultat/{id} @@ -202,10 +206,7 @@ export class ResultatService { }) .pipe( switchMap((apiResultat) => { - const courseId = - typeof apiResultat.course === 'object' && 'id' in apiResultat.course - ? String(apiResultat.course.id) - : String(apiResultat.course); + const courseId = String((apiResultat as any).courseId ?? ''); return this.courseService.getById(courseId).pipe( map((course) => { @@ -261,20 +262,17 @@ export class ResultatService { return { id: String(apiResultat.id), course, - // Normalize ordreArrivee to an array of cheval numbers - ordreArrivee: (apiResultat.ordreArrivee || []) - .map((v) => (typeof v === 'string' ? Number(v) : v)) - .filter((v): v is number => typeof v === 'number' && !Number.isNaN(v)), - // Normalize dead-heat horses to numbers as well - chevauxDeadHeat: (apiResultat.chevauxDeadHeat || []) - .map((v) => (typeof v === 'string' ? Number(v) : v)) - .filter((v): v is number => typeof v === 'number' && !Number.isNaN(v)), - totalMises: apiResultat.totalMises, - masseAPartager: apiResultat.masseAPartager, - prelevementsLegaux: apiResultat.prelevementsLegaux, - montantRembourse: apiResultat.montantRembourse, - montantCagnotte: apiResultat.montantCagnotte, - adeadHeat: apiResultat.adeadHeat, + // API now returns 'ordreArrivee' as CSV/string; normalize to number[] + ordreArrivee: apiResultat.ordreArrivee, + // dead-heat not provided by new API shape — default to empty + chevauxDeadHeat: [], + // Financial fields may not be present in new API; default to 0 + totalMises: (apiResultat as any).totalMises ?? 0, + masseAPartager: (apiResultat as any).masseAPartager ?? 0, + prelevementsLegaux: (apiResultat as any).prelevementsLegaux ?? 0, + montantRembourse: (apiResultat as any).montantRembourse ?? 0, + montantCagnotte: (apiResultat as any).montantCagnotte ?? 0, + adeadHeat: (apiResultat as any).adeadHeat ?? false, createdAt: apiResultat.createdAt, updatedAt: apiResultat.updatedAt, }; diff --git a/src/app/core/services/reunion.ts b/src/app/core/services/reunion.ts index bf3be49..b49606d 100644 --- a/src/app/core/services/reunion.ts +++ b/src/app/core/services/reunion.ts @@ -180,7 +180,7 @@ export class ReunionService { meta: { total: 0, uniqueHippodromes: 0, upcomingReunions: 0, pastReunions: 0 }, }, params.page, - params.perPage + params.size ) ); } @@ -197,7 +197,7 @@ export class ReunionService { meta: { total: 0, uniqueHippodromes: 0, upcomingReunions: 0, pastReunions: 0 }, }, params.page, - params.perPage + params.size ) ); } @@ -273,8 +273,8 @@ export class ReunionService { // Apply client-side filtering, sorting, and pagination let filtered = this.applyClientFilters(transformedData, params); const total = filtered.length; - const start = (params.page - 1) * params.perPage; - const pageData = filtered.slice(start, start + params.perPage); + const start = (params.page - 1) * params.size; + const pageData = filtered.slice(start, start + params.size); const upcomingReunions = filtered.filter( (r) => new Date(r.date) >= new Date() @@ -288,7 +288,7 @@ export class ReunionService { meta: { total, uniqueHippodromes, upcomingReunions, pastReunions }, }, params.page, - params.perPage + params.size ); }) ); @@ -359,8 +359,8 @@ export class ReunionService { }); } - const start = (params.page - 1) * params.perPage; - const pageData = data.slice(start, start + params.perPage); + const start = (params.page - 1) * params.size; + const pageData = data.slice(start, start + params.size); const upcomingReunions = data.filter((r) => new Date(r.date) >= new Date()).length; const pastReunions = data.filter((r) => new Date(r.date) < new Date()).length; @@ -373,7 +373,7 @@ export class ReunionService { meta: { total: data.length, uniqueHippodromes, upcomingReunions, pastReunions }, }, params.page, - params.perPage + params.size ) ); } diff --git a/src/app/core/services/role.ts b/src/app/core/services/role.ts index c25e41f..ce046de 100644 --- a/src/app/core/services/role.ts +++ b/src/app/core/services/role.ts @@ -91,7 +91,7 @@ export class RoleService { private buildParams(params: ListParams): HttpParams { let httpParams = new HttpParams() .set('page', String(params.page - 1)) - .set('size', String(params.perPage)); + .set('size', String(params.size)); if (params.search) { httpParams = httpParams.set('search', params.search); } @@ -117,13 +117,13 @@ export class RoleService { return normalizePage( { data: roles, meta: { total: roles.length } }, params.page, - params.perPage + params.size ); }), catchError((err) => { console.error('Error fetching roles:', err); return of( - normalizePage({ data: [], meta: { total: 0 } }, params.page, params.perPage) + normalizePage({ data: [], meta: { total: 0 } }, params.page, params.size) ); }) ); @@ -137,7 +137,7 @@ export class RoleService { meta: { total: 0 }, }, params.page, - params.perPage + params.size ) ); } diff --git a/src/app/core/services/services-utils.ts b/src/app/core/services/services-utils.ts index 88844fd..8551c88 100644 --- a/src/app/core/services/services-utils.ts +++ b/src/app/core/services/services-utils.ts @@ -8,7 +8,7 @@ export class ServicesUtils{ let httpParams = new HttpParams(); Object.entries(params).forEach(([key, value])=>{ if(params != null && params!=undefined){ - httpParams.set(key, String(value)) + httpParams = httpParams.set(key, String(value)) } }) return httpParams; diff --git a/src/app/core/services/tpe.ts b/src/app/core/services/tpe.ts index ad4345f..3fb22ff 100644 --- a/src/app/core/services/tpe.ts +++ b/src/app/core/services/tpe.ts @@ -211,7 +211,7 @@ export class TpeService { let httpParams = new HttpParams(); if (params) { if (params.page) httpParams = httpParams.set('page', params.page.toString()); - if (params.perPage) httpParams = httpParams.set('perPage', params.perPage.toString()); + if (params.size) httpParams = httpParams.set('perPage', params.size.toString()); if (params.search) httpParams = httpParams.set('search', params.search); if (params.sortKey) httpParams = httpParams.set('sortKey', params.sortKey); if (params.sortDir) httpParams = httpParams.set('sortDir', params.sortDir); @@ -230,7 +230,7 @@ export class TpeService { return normalizePage( { data: tpes, meta: { total: tpes.length } }, params.page || 1, - params.perPage || 10 + params.size || 10 ); } // Otherwise return all as single page diff --git a/src/app/core/services/user.ts b/src/app/core/services/user.ts index 30cd679..ba446a2 100644 --- a/src/app/core/services/user.ts +++ b/src/app/core/services/user.ts @@ -117,23 +117,23 @@ export class UserService { }); } - const start = (params.page - 1) * params.perPage; - const pageData = data.slice(start, start + params.perPage); + const start = (params.page - 1) * params.size; + const pageData = data.slice(start, start + params.size); return normalizePage( { data: pageData, meta: { total: data.length } }, params.page, - params.perPage + params.size ); }), catchError(() => - of(normalizePage({ data: [], meta: { total: 0 } }, params.page, params.perPage)) + of(normalizePage({ data: [], meta: { total: 0 } }, params.page, params.size)) ) ); } // Fallback should not be used anymore - return of(normalizePage({ data: [], meta: { total: 0 } }, params.page, params.perPage)); + return of(normalizePage({ data: [], meta: { total: 0 } }, params.page, params.size)); } create(payload: Omit): Observable { diff --git a/src/app/dashboard/dashboard-routing-module.ts b/src/app/dashboard/dashboard-routing-module.ts index 726eab0..18df032 100644 --- a/src/app/dashboard/dashboard-routing-module.ts +++ b/src/app/dashboard/dashboard-routing-module.ts @@ -21,6 +21,10 @@ const routes: Routes = [ path: 'reunions', loadComponent: () => import('./pages/reunion/reunion').then((m) => m.ReunionList), }, + { + path: 'rapport', + loadComponent: () => import('./pages/rapport/rapport').then((m) => m.Rapport), + }, { path: 'users', loadComponent: () => import('./pages/users/users').then((m) => m.UsersPage), diff --git a/src/app/dashboard/layout/layout.ts b/src/app/dashboard/layout/layout.ts index d358ec9..cb4ece2 100644 --- a/src/app/dashboard/layout/layout.ts +++ b/src/app/dashboard/layout/layout.ts @@ -46,7 +46,7 @@ export class Layout { { icon: '🏟️', label: 'Hippodromes', link: '/hippodromes' }, { icon: '📅', label: 'Reunions', link: '/reunions' }, { icon: '🏇', label: 'Courses', link: '/courses' }, - { icon: 'icon-chart-bar', label: 'Rapport des courses', link: '/rapport-courses' }, + { icon: 'icon-chart-bar', label: 'Rapport des courses', link: '/rapport' }, ]; workspaceMenuItems: MenuItem[] = [ diff --git a/src/app/dashboard/pages/agents/agents.html b/src/app/dashboard/pages/agents/agents.html index 9baee08..3c8b743 100644 --- a/src/app/dashboard/pages/agents/agents.html +++ b/src/app/dashboard/pages/agents/agents.html @@ -28,9 +28,9 @@ diff --git a/src/app/dashboard/pages/agents/agents.ts b/src/app/dashboard/pages/agents/agents.ts index 5886e8b..f5550a9 100644 --- a/src/app/dashboard/pages/agents/agents.ts +++ b/src/app/dashboard/pages/agents/agents.ts @@ -51,7 +51,7 @@ export class AgentsPage { loading = signal(false); page = signal(1); - perPage = signal(10); + size = signal(10); search = signal(''); sort = signal({ key: 'code', dir: 'asc' }); @@ -148,7 +148,7 @@ export class AgentsPage { ) { // Preload TPE maps for display this.tpeSvc - .list({ page: 1, perPage: 200, search: '', sortKey: 'imei', sortDir: 'asc' } as any) + .list({ page: 1, size: 200, search: '', sortKey: 'imei', sortDir: 'asc' } as any) .subscribe((res) => { const tpes = res.content as TpeDevice[]; this.rebuildTpeMaps(tpes); @@ -156,7 +156,7 @@ export class AgentsPage { effect(() => { const params = { page: this.page(), - perPage: this.perPage(), + size: this.size(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -167,7 +167,7 @@ export class AgentsPage { private fetch(params: { page: number; - perPage: number; + size: number; search: string; sortKey: string; sortDir: SortDir; @@ -191,7 +191,7 @@ export class AgentsPage { private refreshTpeMap() { this.tpeSvc - .list({ page: 1, perPage: 200, search: '', sortKey: 'imei', sortDir: 'asc' } as any) + .list({ page: 1, size: 200, search: '', sortKey: 'imei', sortDir: 'asc' } as any) .subscribe((res) => { const tpes = res.content as TpeDevice[]; this.rebuildTpeMaps(tpes); @@ -381,7 +381,7 @@ export class AgentsPage { // Refresh data this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.size(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -399,7 +399,7 @@ export class AgentsPage { this.api.delete(row.id).subscribe(() => this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.size(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, diff --git a/src/app/dashboard/pages/courses/courses.html b/src/app/dashboard/pages/courses/courses.html index cffc9e0..59e7f13 100644 --- a/src/app/dashboard/pages/courses/courses.html +++ b/src/app/dashboard/pages/courses/courses.html @@ -106,10 +106,10 @@ @@ -158,12 +158,12 @@ -
+
Fermer
diff --git a/src/app/dashboard/pages/courses/courses.ts b/src/app/dashboard/pages/courses/courses.ts index 519ce15..ec03a43 100644 --- a/src/app/dashboard/pages/courses/courses.ts +++ b/src/app/dashboard/pages/courses/courses.ts @@ -18,7 +18,7 @@ import { Course as CourseType } from 'src/app/core/interfaces/course'; import { SortDir } from '@shared/paging/paging'; import { CourseApiResponse, CourseService } from 'src/app/core/services/course'; import { ResultatService } from 'src/app/core/services/resultat'; -import { Resultat } from 'src/app/core/interfaces/resultat'; +import { Resultat, ResultatStatut } from 'src/app/core/interfaces/resultat'; import { A11yModule } from '@angular/cdk/a11y'; import { CourseForm } from '@shared/forms/course-form/course-form'; import { NonPartantForm } from '@shared/forms/nonpartant-form/nonpartant-form'; @@ -57,10 +57,10 @@ export class Course { totalClosed = signal(0); totalByType = signal>({}); - page = signal(1); + page = signal(0); perPage = signal(10); search = signal(''); - sort = signal({ key: 'numero', dir: 'asc' }); + sort = signal({ key: 'id', dir: 'asc' }); pageSize = [10, 20, 50]; modalOpen = signal(false); @@ -102,40 +102,42 @@ export class Course { return ''; } - // Group horses that are at the same place (ex-aequo/dead heat). - // Backend/Resultat model store ordreArrivee as cheval numbers (1,2,3,...) and - // chevauxDeadHeat as the subset that are ex-aequo. - const deadHeatSet = new Set(resultat.chevauxDeadHeat || []); + return `${resultat.ordreArrivee}` - const groups: number[][] = []; - let currentGroup: number[] = []; + // // Group horses that are at the same place (ex-aequo/dead heat). + // // Backend/Resultat model store ordreArrivee as cheval numbers (1,2,3,...) and + // // chevauxDeadHeat as the subset that are ex-aequo. + // const deadHeatSet = new Set(resultat.chevauxDeadHeat || []); - resultat.ordreArrivee.forEach((num, index) => { - const isInDeadHeat = deadHeatSet.has(num); - const prevNum = index > 0 ? resultat.ordreArrivee[index - 1] : null; - const prevIsInDeadHeat = prevNum !== null && deadHeatSet.has(prevNum); + // const groups: number[][] = []; + // let currentGroup: number[] = []; - if (isInDeadHeat && prevIsInDeadHeat && currentGroup.length > 0) { - // Continue the current dead heat group - currentGroup.push(num); - } else { - // Start a new group - if (currentGroup.length > 0) { - groups.push(currentGroup); - } - currentGroup = [num]; - } - }); + // resultat.ordreArrivee.forEach((num, index) => { + // const isInDeadHeat = deadHeatSet.has(num); + // const prevNum = index > 0 ? resultat.ordreArrivee[index - 1] : null; + // const prevIsInDeadHeat = prevNum !== null && deadHeatSet.has(prevNum); - // Don't forget the last group - if (currentGroup.length > 0) { - groups.push(currentGroup); - } + // if (isInDeadHeat && prevIsInDeadHeat && currentGroup.length > 0) { + // // Continue the current dead heat group + // currentGroup.push(num); + // } else { + // // Start a new group + // if (currentGroup.length > 0) { + // groups.push(currentGroup); + // } + // currentGroup = [num]; + // } + // }); - const s = groups.map((nums) => nums.join('=')).join(' - '); + // // Don't forget the last group + // if (currentGroup.length > 0) { + // groups.push(currentGroup); + // } - // For now, we'll show the resultat. In the future, we might add a statut field to Resultat - return `${s}`; + // const s = groups.map((nums) => nums.join('=')).join(' - '); + + // // For now, we'll show the resultat. In the future, we might add a statut field to Resultat + // return ; }, }, { @@ -187,7 +189,7 @@ export class Course { effect(() => { const params = { page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -198,7 +200,7 @@ export class Course { private fetch(params: { page: number; - perPage: number; + size: number; search: string; sortKey: string; sortDir: SortDir; @@ -256,7 +258,7 @@ export class Course { // === UI Actions === onSearch(q: string) { this.search.set(q); - this.page.set(1); + this.page.set(0); } openCreate() { @@ -283,21 +285,15 @@ export class Course { this.formComp?.onSubmit(); } - onFormSave(payload: Partial) { - const current = this.editingItem(); - const req$ = current?.id - ? this.api.update(current.id, payload) - : this.api.create(payload as Omit); - - req$.subscribe(() => { - this.closeModal(); - this.fetch({ - page: this.page(), - perPage: this.perPage(), - search: this.search(), - sortKey: this.sort().key, - sortDir: this.sort().dir, - }); + onFormSave(_: CourseType) { + // The form now persists create/update itself. Just close and refresh. + this.closeModal(); + this.fetch({ + page: this.page(), + size: this.perPage(), + search: this.search(), + sortKey: this.sort().key, + sortDir: this.sort().dir, }); } @@ -307,7 +303,7 @@ export class Course { this.api.delete(row.id).subscribe(() => this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir, @@ -360,7 +356,7 @@ export class Course { this.closeNonPartantModal(); this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir, @@ -381,20 +377,22 @@ export class Course { this.selectedCourseForResultat.set(null); } - onResultatSave(places: number[][]) { + onResultatSave(places: number[][], typesParisOuverts: string[]) { const c = this.selectedCourseForResultat(); if (!c) return; // Determine required number of horses based on course type - const getRequiredHorses = (type: string): number => { - const typeStr = String(type).toUpperCase(); - if (typeStr.includes('TIERCE') || typeStr === 'PLAT') return 3; - if (typeStr.includes('QUARTE')) return 4; + const getRequiredHorses = (types: string[]): number => { + const typeStr = types; + if (typeStr.includes('PLACE') || typeStr.includes('GAGNANT')) return 3; + if(typeStr.includes('JUMELE_GAGNANT') || typeStr.includes('JUMELE_PLACE') || typeStr.includes('JUMELE_ORDRE')) return 2; + if(typeStr.includes('TRIO') || typeStr.includes('TRIO_ORDRE') || typeStr.includes('TRIPLET')) return 3 + if (typeStr.includes('QUATRO')) return 4; if (typeStr.includes('QUINTE')) return 5; return 3; // Default }; - const requiredHorses = 3; + const requiredHorses = getRequiredHorses(typesParisOuverts); // Collect all selected horses (flatten the places array) const allHorses: number[] = places @@ -409,46 +407,28 @@ export class Course { // Convert to ordreArrivee format // If all are ex-aequo, they all go in ordreArrivee as they are (first place) // Otherwise, distribute them across places - const ordreArrivee: Array = []; - const chevauxDeadHeat: number[] = []; - - if (isAllExAequo) { - // All horses are in first place (ex-aequo) - allHorses.forEach((numero) => { - ordreArrivee.push(numero.toString()); - chevauxDeadHeat.push(numero); - }); - } else { - // Horses are distributed across places - places.forEach((placeGroup, placeIndex) => { - const validHorses = placeGroup.filter((n) => typeof n === 'number' && n > 0); - if (validHorses.length === 0) return; - - const isDeadHeat = validHorses.length > 1; - - validHorses.forEach((numero) => { - ordreArrivee.push(numero.toString()); - - if (isDeadHeat) { - chevauxDeadHeat.push(numero); - } - }); - }); - } + let ordreArrivee: string = ''; + places.forEach((place)=>{ + if(Array.isArray(place) && place.length>1){ + place.forEach((p, index)=>{ + if(index == 0){ + ordreArrivee = ordreArrivee ==''? String(p) : ordreArrivee+","+String(p) + }else{ + ordreArrivee = ordreArrivee ==''? String(p) : ordreArrivee+"="+String(p) + } + }) + }else{ + ordreArrivee = ordreArrivee ==''? String(place[0]): ordreArrivee+","+String(place[0]) + } + }) // Check if resultat already exists const existingResultat = this.resultatsMap().get(c.id); const payload = { - course: { id: c.id }, + courseId: Number(c.id) , ordreArrivee, - chevauxDeadHeat: chevauxDeadHeat.map((n) => String(n)), - totalMises: 0, - masseAPartager: 0, - prelevementsLegaux: 0, - montantRembourse: 0, - montantCagnotte: 0, - adeadHeat: chevauxDeadHeat.length > 0, + statut: ResultatStatut.EN_ATTENTE, }; const request$ = existingResultat @@ -460,7 +440,7 @@ export class Course { this.closeResultatModal(); this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir, @@ -490,7 +470,7 @@ export class Course { this.closeResultatModal(); this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir, @@ -520,7 +500,7 @@ export class Course { this.closeResultatModal(); this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir, diff --git a/src/app/dashboard/pages/hippodrome/hippodrome.html b/src/app/dashboard/pages/hippodrome/hippodrome.html index 7d719c6..dc6f57e 100644 --- a/src/app/dashboard/pages/hippodrome/hippodrome.html +++ b/src/app/dashboard/pages/hippodrome/hippodrome.html @@ -97,7 +97,7 @@ [page]="page()" [perPage]="perPage()" [total]="total()" - (pageChange)="page.set($event)" + (pageChange)="page.set($event - 1)" (perPageChange)="onPerPage($event)" [pageSizes]="pageSize" /> diff --git a/src/app/dashboard/pages/hippodrome/hippodrome.ts b/src/app/dashboard/pages/hippodrome/hippodrome.ts index 69fd188..8679fbd 100644 --- a/src/app/dashboard/pages/hippodrome/hippodrome.ts +++ b/src/app/dashboard/pages/hippodrome/hippodrome.ts @@ -46,7 +46,7 @@ export class Hippodrome { totalReunions = signal(0); totalCourses = signal(0); - page = signal(1); + page = signal(0); perPage = signal(10); pageSize = [10, 20, 50]; search = signal(''); @@ -105,7 +105,7 @@ export class Hippodrome { this.api .list({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir, diff --git a/src/app/dashboard/pages/limits/limits.html b/src/app/dashboard/pages/limits/limits.html index ec942be..81a46fc 100644 --- a/src/app/dashboard/pages/limits/limits.html +++ b/src/app/dashboard/pages/limits/limits.html @@ -49,7 +49,7 @@ - +
diff --git a/src/app/dashboard/pages/limits/limits.ts b/src/app/dashboard/pages/limits/limits.ts index 0cde4cb..8eb675b 100644 --- a/src/app/dashboard/pages/limits/limits.ts +++ b/src/app/dashboard/pages/limits/limits.ts @@ -24,7 +24,7 @@ export class LimitsPage implements OnInit { total = signal(0); loading = signal(false); page = signal(1); - perPage = signal(10); + size = signal(10); search = signal(''); sort = signal({ key: 'code', dir: 'asc' }); selectedActif = signal(null); @@ -92,11 +92,11 @@ export class LimitsPage implements OnInit { constructor(private api: AgentLimitService) { effect(() => { - // Only trigger fetch when page, perPage, or sort changes (not search - handled by searchSubject) + // Only trigger fetch when page, size, or sort changes (not search - handled by searchSubject) const searchValue = this.search(); const params = { page: this.page(), - perPage: this.perPage(), + size: this.size(), search: searchValue, sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -120,7 +120,7 @@ export class LimitsPage implements OnInit { // If empty, use normal list return this.api.list({ page: this.page(), - perPage: this.perPage(), + size: this.size(), search: '', sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -155,14 +155,14 @@ export class LimitsPage implements OnInit { // Initial fetch this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.size(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, }); } - private fetch(params: { page: number; perPage: number; search: string; sortKey: string; sortDir: SortDir }) { + private fetch(params: { page: number; size: number; search: string; sortKey: string; sortDir: SortDir }) { // Don't fetch if there's a search query - it's handled by searchSubject const searchQuery = params.search.trim(); if (searchQuery) { @@ -214,7 +214,7 @@ export class LimitsPage implements OnInit { // If empty, fetch normally this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.size(), search: '', sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -227,7 +227,7 @@ export class LimitsPage implements OnInit { this.page.set(1); this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.size(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -261,7 +261,7 @@ export class LimitsPage implements OnInit { this.closeModal(); this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.size(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -282,7 +282,7 @@ export class LimitsPage implements OnInit { this.api.delete(row.id).subscribe(() => { this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.size(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, diff --git a/src/app/dashboard/pages/main/main.ts b/src/app/dashboard/pages/main/main.ts index 96287cd..9f02bad 100644 --- a/src/app/dashboard/pages/main/main.ts +++ b/src/app/dashboard/pages/main/main.ts @@ -118,7 +118,7 @@ export class Main { private baseParams(): ListParams { return { page: 1, - perPage: 1, + size: 1, search: '', sortKey: 'id', sortDir: 'asc' as SortDir, @@ -158,7 +158,7 @@ export class Main { .list(params, true) .pipe(catchError(() => of({ data: [], meta: { total: 0 } } as any))), courses: this.courseService - .list(coursesParams, true) + .list(coursesParams) .pipe(catchError(() => of({ data: [], meta: { total: 0 } } as any))), roles: this.roleService .list(params) diff --git a/src/app/dashboard/pages/rapport/rapport.css b/src/app/dashboard/pages/rapport/rapport.css new file mode 100644 index 0000000..e69de29 diff --git a/src/app/dashboard/pages/rapport/rapport.html b/src/app/dashboard/pages/rapport/rapport.html new file mode 100644 index 0000000..236fbfb --- /dev/null +++ b/src/app/dashboard/pages/rapport/rapport.html @@ -0,0 +1,33 @@ +
+
+

Rapport — Courses avec résultats

+ Récupérer le rapport +
+ +
+ + + +
+
+
+
+
+
+
+ + +
+
{{ totalElements() }} résultats
+
+
+ +
+
+
+
diff --git a/src/app/dashboard/pages/rapport/rapport.spec.ts b/src/app/dashboard/pages/rapport/rapport.spec.ts new file mode 100644 index 0000000..a4fbbe8 --- /dev/null +++ b/src/app/dashboard/pages/rapport/rapport.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Rapport } from './rapport'; + +describe('Rapport', () => { + let component: Rapport; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [Rapport] + }) + .compileComponents(); + + fixture = TestBed.createComponent(Rapport); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/dashboard/pages/rapport/rapport.ts b/src/app/dashboard/pages/rapport/rapport.ts new file mode 100644 index 0000000..ba3f0ac --- /dev/null +++ b/src/app/dashboard/pages/rapport/rapport.ts @@ -0,0 +1,94 @@ +import { CommonModule } from '@angular/common'; +import { ChangeDetectionStrategy, Component, signal, ViewChild } from '@angular/core'; +import { DataTable, TableColumn } from '@shared/components/data-table/data-table'; +import { ZardButtonComponent } from '@shared/components/button/button.component'; +import { ZardPaginationModule } from '@shared/components/pagination/pagination.module'; +import { ListParams, PagedResult } from '@shared/paging/paging'; +import { ResultatApiResponse } from 'src/app/core/interfaces/resultat'; +import { ResultatService } from 'src/app/core/services/resultat'; + +@Component({ + standalone: true, + selector: 'app-rapport', + templateUrl: './rapport.html', + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CommonModule, DataTable, ZardButtonComponent, ZardPaginationModule], +}) +export class Rapport { + rows = signal([]); + loading = signal(false); + // Pagination state + page = signal(1); + perPage = signal(10); + totalPages = signal(1); + totalElements = signal(0); + @ViewChild(DataTable) table?: DataTable; + + cols: TableColumn[] = [ + { key: 'courseNumero', label: 'N°' }, + { key: 'hippodromeNom', label: 'Hippodrome' }, + { key: 'courseNom', label: 'Course' }, + { key: 'ordreArrivee', label: "Ordre d'arrivée", cell: (r) => String(r.ordreArrivee ?? '').replace(/,/g, ' - ') }, + { key: 'statut', label: 'Statut', cell: (r)=>(r.statut.toString().toLowerCase().replace("_", " ")) }, + { key: 'datePublication', label: 'Date pub.', cell: (r) => r.datePublication ?? r.createdAt ?? '—' }, + { key: 'dateValidation', label: 'Date validation' }, + ]; + + constructor(private api: ResultatService) { + // initial load + this.fetch(); + } + private fetchPage(params?: Partial) { + this.loading.set(true); + const p: ListParams = { page: this.page(), size: this.perPage(), ...(params || {}) }; + this.api.listRawPaged(p).subscribe({ + next: (res: PagedResult) => { + const filtered = (res?.content || []).filter((r) => !!(r.ordreArrivee && String(r.ordreArrivee).trim())); + this.rows.set(filtered); + // normalize paging meta + this.totalPages.set(res.totalPages ?? 1); + this.totalElements.set(res.totalElements ?? (filtered.length || 0)); + // ensure local page is in sync with backend response + if (res.pageable?.pageNumber) this.page.set(res.pageable.pageNumber); + this.loading.set(false); + }, + error: (err) => { + console.error('Error fetching paged reports:', err); + this.rows.set([]); + this.loading.set(false); + }, + }); + } + + fetch() { + this.fetchPage(); + } + + onPageChange(nextPage: number) { + this.page.set(nextPage); + this.fetchPage(); + } + + onPerPageChange(size: number) { + this.perPage.set(size); + this.page.set(1); + this.fetchPage(); + } + + // wrapper for template change event to avoid $event typing issues + onPerPageChangeEvent(e: Event) { + const v = (e.target as HTMLSelectElement)?.value; + const size = Number(v) || 10; + this.onPerPageChange(size); + } + + openReport(row: ResultatApiResponse) { + try { + // Open a per-result report URL in a new tab. Adjust path if your server uses another route. + const url = `/rapport/${row.id}`; + window.open(url, '_blank'); + } catch (err) { + console.error('Failed to open report for', row, err); + } + } +} diff --git a/src/app/dashboard/pages/reunion/reunion.html b/src/app/dashboard/pages/reunion/reunion.html index 0cd01af..71e194b 100644 --- a/src/app/dashboard/pages/reunion/reunion.html +++ b/src/app/dashboard/pages/reunion/reunion.html @@ -64,10 +64,10 @@ diff --git a/src/app/dashboard/pages/reunion/reunion.ts b/src/app/dashboard/pages/reunion/reunion.ts index ce56d27..52cad17 100644 --- a/src/app/dashboard/pages/reunion/reunion.ts +++ b/src/app/dashboard/pages/reunion/reunion.ts @@ -48,7 +48,7 @@ export class ReunionList { // pagination, sorting, search page = signal(1); - perPage = signal(10); + size = signal(10); search = signal(''); sort = signal({ key: 'date', dir: 'asc' }); pageSize = [10, 20, 50]; @@ -134,7 +134,7 @@ export class ReunionList { effect(() => { const params = { page: this.page(), - perPage: this.perPage(), + size: this.size(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir, @@ -145,7 +145,7 @@ export class ReunionList { private fetch(params: { page: number; - perPage: number; + size: number; search: string; sortKey: string; sortDir: SortDir; @@ -211,7 +211,7 @@ export class ReunionList { // refetch current page this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.size(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir, @@ -224,7 +224,7 @@ export class ReunionList { this.api.delete(row.id).subscribe(() => this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.size(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir, diff --git a/src/app/dashboard/pages/roles/roles.ts b/src/app/dashboard/pages/roles/roles.ts index 1b4c2c3..733c4e7 100644 --- a/src/app/dashboard/pages/roles/roles.ts +++ b/src/app/dashboard/pages/roles/roles.ts @@ -39,7 +39,7 @@ export class RolesPage { loading = signal(false); permissions = signal([]); page = signal(1); - perPage = signal(10); + size = signal(10); search = signal(''); sort = signal({ key: 'name', dir: 'asc' }); @@ -65,7 +65,7 @@ export class RolesPage { effect(() => { const params = { page: this.page(), - perPage: this.perPage(), + size: this.size(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -76,7 +76,7 @@ export class RolesPage { private fetch(params: { page: number; - perPage: number; + size: number; search: string; sortKey: string; sortDir: SortDir; @@ -136,7 +136,7 @@ export class RolesPage { ); this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.size(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -160,7 +160,7 @@ export class RolesPage { toast.success(`Le rôle « ${row.name} » a été supprimé avec succès`); this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.size(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, diff --git a/src/app/dashboard/pages/tpe/tpe.ts b/src/app/dashboard/pages/tpe/tpe.ts index 135e380..c0b3934 100644 --- a/src/app/dashboard/pages/tpe/tpe.ts +++ b/src/app/dashboard/pages/tpe/tpe.ts @@ -152,7 +152,7 @@ export class TpePage implements OnInit { const searchValue = this.search(); const params = { page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: searchValue, sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -175,7 +175,7 @@ export class TpePage implements OnInit { // If empty, use normal list return this.api.list({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: '', sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -211,7 +211,7 @@ export class TpePage implements OnInit { if (!this.search().trim()) { this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: '', sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -249,7 +249,7 @@ export class TpePage implements OnInit { private fetch(params: { page: number; - perPage: number; + size: number; search: string; sortKey: string; sortDir: SortDir; @@ -305,7 +305,7 @@ export class TpePage implements OnInit { // If empty, fetch normally this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: '', sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -318,7 +318,7 @@ export class TpePage implements OnInit { this.page.set(1); this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -331,7 +331,7 @@ export class TpePage implements OnInit { next: () => { this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -347,7 +347,7 @@ export class TpePage implements OnInit { next: () => { this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -393,7 +393,7 @@ export class TpePage implements OnInit { this.selectedAgentId.set(''); this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -456,7 +456,7 @@ export class TpePage implements OnInit { // Refresh data this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -476,7 +476,7 @@ export class TpePage implements OnInit { this.api.delete(row.id).subscribe(() => { this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, diff --git a/src/app/dashboard/pages/users/users.ts b/src/app/dashboard/pages/users/users.ts index ba5cecf..d833422 100644 --- a/src/app/dashboard/pages/users/users.ts +++ b/src/app/dashboard/pages/users/users.ts @@ -83,7 +83,7 @@ export class UsersPage { effect(() => { const params = { page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -94,7 +94,7 @@ export class UsersPage { private fetch(params: { page: number; - perPage: number; + size: number; search: string; sortKey: string; sortDir: SortDir; @@ -156,7 +156,7 @@ export class UsersPage { ); this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, @@ -181,7 +181,7 @@ export class UsersPage { toast.success(`L'utilisateur « ${row.nom} ${row.prenom} » a été supprimé avec succès`); this.fetch({ page: this.page(), - perPage: this.perPage(), + size: this.perPage(), search: this.search(), sortKey: this.sort().key, sortDir: this.sort().dir as SortDir, diff --git a/src/app/shared/forms/course-form/course-form.html b/src/app/shared/forms/course-form/course-form.html index 487bb01..26585c7 100644 --- a/src/app/shared/forms/course-form/course-form.html +++ b/src/app/shared/forms/course-form/course-form.html @@ -19,26 +19,25 @@
- - - - @if (loadingHippodromes()) { - Chargement des Hippodromes... - } @else { @for (r of filteredHippodromes(); track r.id) { - - {{ r.nom }} - ({{ r.ville }}) - - } } - - - - + + + + @if (loadingHippodromes()) { + Chargement des Hippodromes... + } @else { @for (r of filteredHippodromes(); track r.id) { + {{ r.nom }} - ({{ r.ville }}) + } } + + + + @@ -84,7 +83,7 @@ @@ -142,13 +141,13 @@ z-form-label class="text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2 block" > - heure de départ + heure de départ
@@ -161,23 +160,6 @@
- -
-
-
- 📅 -
-
-

Réunion associée

-

- Sélectionnez la réunion concernée ou créez-en une nouvelle -

-
-
-
-
@@ -194,21 +176,25 @@
- - - - @for (t of courseTypes; track t.value) { - {{ t.label }} - } - -

Séparez les types par des virgules.

-
-
+ + + + @for (t of courseTypes; track t.value) { + + } + + +
-
+