up
This commit is contained in:
parent
464e0e5499
commit
080cb4df48
5 changed files with 90 additions and 13 deletions
|
@ -11,6 +11,13 @@
|
||||||
<h3>Agenda</h3>
|
<h3>Agenda</h3>
|
||||||
<small>{{calendarEvents.length}} évènements</small>
|
<small>{{calendarEvents.length}} évènements</small>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="sidebar-filters">
|
||||||
|
<app-what-filter
|
||||||
|
[label]="'Filtrer par type d\'événement'"
|
||||||
|
[available]="availableWhatTypes"
|
||||||
|
[selected]="selectedWhatFilter"
|
||||||
|
(selectedChange)="onWhatFilterChange($event)"></app-what-filter>
|
||||||
|
</div>
|
||||||
<div class="day-groups">
|
<div class="day-groups">
|
||||||
@for (group of groupedEvents; track group.dateKey) {
|
@for (group of groupedEvents; track group.dateKey) {
|
||||||
<div class="day-group">
|
<div class="day-group">
|
||||||
|
@ -41,7 +48,7 @@
|
||||||
|
|
||||||
<main class="agenda-main">
|
<main class="agenda-main">
|
||||||
<app-calendar
|
<app-calendar
|
||||||
[events]="calendarEvents"
|
[events]="filteredCalendarEvents"
|
||||||
(eventClick)="onEventClick($event)"
|
(eventClick)="onEventClick($event)"
|
||||||
(dateClick)="onDateClick($event)">
|
(dateClick)="onDateClick($event)">
|
||||||
</app-calendar>
|
</app-calendar>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { OedbApi } from '../../services/oedb-api';
|
||||||
import { EditForm } from '../../forms/edit-form/edit-form';
|
import { EditForm } from '../../forms/edit-form/edit-form';
|
||||||
import { CalendarComponent, CalendarEvent } from './calendar/calendar';
|
import { CalendarComponent, CalendarEvent } from './calendar/calendar';
|
||||||
import oedb from '../../../oedb-types';
|
import oedb from '../../../oedb-types';
|
||||||
|
import { WhatFilterComponent } from '../../shared/what-filter/what-filter';
|
||||||
|
|
||||||
interface OedbEvent {
|
interface OedbEvent {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -27,7 +28,7 @@ interface OedbEvent {
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-agenda',
|
selector: 'app-agenda',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [CommonModule, FormsModule, EditForm, CalendarComponent],
|
imports: [CommonModule, FormsModule, EditForm, CalendarComponent, WhatFilterComponent],
|
||||||
templateUrl: './agenda.html',
|
templateUrl: './agenda.html',
|
||||||
styleUrl: './agenda.scss'
|
styleUrl: './agenda.scss'
|
||||||
})
|
})
|
||||||
|
@ -35,11 +36,15 @@ export class Agenda implements OnInit {
|
||||||
private oedbApi = inject(OedbApi);
|
private oedbApi = inject(OedbApi);
|
||||||
|
|
||||||
events: OedbEvent[] = [];
|
events: OedbEvent[] = [];
|
||||||
|
filteredEvents: OedbEvent[] = [];
|
||||||
calendarEvents: CalendarEvent[] = [];
|
calendarEvents: CalendarEvent[] = [];
|
||||||
|
filteredCalendarEvents: CalendarEvent[] = [];
|
||||||
selectedEvent: OedbEvent | null = null;
|
selectedEvent: OedbEvent | null = null;
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
|
|
||||||
groupedEvents: Array<{ dateKey: string; date: Date; items: OedbEvent[] }> = [];
|
groupedEvents: Array<{ dateKey: string; date: Date; items: OedbEvent[] }> = [];
|
||||||
|
availableWhatTypes: string[] = [];
|
||||||
|
selectedWhatFilter = '';
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.loadEvents();
|
this.loadEvents();
|
||||||
|
@ -61,14 +66,15 @@ export class Agenda implements OnInit {
|
||||||
|
|
||||||
this.oedbApi.getEvents(params).subscribe((response: any) => {
|
this.oedbApi.getEvents(params).subscribe((response: any) => {
|
||||||
this.events = Array.isArray(response?.features) ? response.features : [];
|
this.events = Array.isArray(response?.features) ? response.features : [];
|
||||||
this.convertToCalendarEvents();
|
this.updateAvailableWhatTypes();
|
||||||
this.buildGroupedEvents();
|
this.applyWhatFilter();
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
convertToCalendarEvents() {
|
convertToCalendarEvents() {
|
||||||
this.calendarEvents = this.events.map(event => {
|
const source = this.filteredEvents.length ? this.filteredEvents : this.events;
|
||||||
|
this.calendarEvents = source.map(event => {
|
||||||
const startDate = this.parseEventDate(event.properties.start || event.properties.when);
|
const startDate = this.parseEventDate(event.properties.start || event.properties.when);
|
||||||
const endDate = event.properties.stop ? this.parseEventDate(event.properties.stop) : null;
|
const endDate = event.properties.stop ? this.parseEventDate(event.properties.stop) : null;
|
||||||
|
|
||||||
|
@ -83,6 +89,7 @@ export class Agenda implements OnInit {
|
||||||
properties: event.properties
|
properties: event.properties
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
this.filteredCalendarEvents = this.calendarEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseEventDate(dateString: string | undefined): Date {
|
parseEventDate(dateString: string | undefined): Date {
|
||||||
|
@ -132,6 +139,29 @@ export class Agenda implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sidebar helpers
|
// Sidebar helpers
|
||||||
|
updateAvailableWhatTypes() {
|
||||||
|
const set = new Set<string>();
|
||||||
|
for (const e of this.events) {
|
||||||
|
const w = e?.properties?.what;
|
||||||
|
if (w) set.add(w);
|
||||||
|
}
|
||||||
|
this.availableWhatTypes = Array.from(set).sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
applyWhatFilter() {
|
||||||
|
if (this.selectedWhatFilter) {
|
||||||
|
this.filteredEvents = this.events.filter(e => e?.properties?.what === this.selectedWhatFilter);
|
||||||
|
} else {
|
||||||
|
this.filteredEvents = [...this.events];
|
||||||
|
}
|
||||||
|
this.convertToCalendarEvents();
|
||||||
|
this.buildGroupedEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
onWhatFilterChange(value: string) {
|
||||||
|
this.selectedWhatFilter = value || '';
|
||||||
|
this.applyWhatFilter();
|
||||||
|
}
|
||||||
private getEventStartDate(ev: OedbEvent): Date {
|
private getEventStartDate(ev: OedbEvent): Date {
|
||||||
const ds = ev.properties.start || ev.properties.when;
|
const ds = ev.properties.start || ev.properties.when;
|
||||||
return this.parseEventDate(ds);
|
return this.parseEventDate(ds);
|
||||||
|
|
|
@ -52,13 +52,7 @@
|
||||||
<input class="input" type="text" placeholder="Rechercher..." [(ngModel)]="searchText" (ngModelChange)="onSearchChange()">
|
<input class="input" type="text" placeholder="Rechercher..." [(ngModel)]="searchText" (ngModelChange)="onSearchChange()">
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label>Filtrer par type d'événement</label>
|
<app-what-filter [label]="'Filtrer par type d\'événement'" [available]="availableWhatTypes" [selected]="selectedWhatFilter" (selectedChange)="selectedWhatFilter = $event; onWhatFilterChange()"></app-what-filter>
|
||||||
<select class="input" [(ngModel)]="selectedWhatFilter" (ngModelChange)="onWhatFilterChange()">
|
|
||||||
<option value="">Tous les types</option>
|
|
||||||
@for (whatType of availableWhatTypes; track whatType) {
|
|
||||||
<option [value]="whatType">{{whatType}}</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { OedbApi } from '../../services/oedb-api';
|
||||||
import { UnlocatedEvents } from '../../shared/unlocated-events/unlocated-events';
|
import { UnlocatedEvents } from '../../shared/unlocated-events/unlocated-events';
|
||||||
import { OsmAuth } from '../../services/osm-auth';
|
import { OsmAuth } from '../../services/osm-auth';
|
||||||
import { Osm } from '../../forms/osm/osm';
|
import { Osm } from '../../forms/osm/osm';
|
||||||
|
import { WhatFilterComponent } from '../../shared/what-filter/what-filter';
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-home',
|
selector: 'app-home',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
|
@ -17,7 +18,8 @@ import { Osm } from '../../forms/osm/osm';
|
||||||
UnlocatedEvents,
|
UnlocatedEvents,
|
||||||
EditForm,
|
EditForm,
|
||||||
Osm,
|
Osm,
|
||||||
FormsModule
|
FormsModule,
|
||||||
|
WhatFilterComponent
|
||||||
],
|
],
|
||||||
templateUrl: './home.html',
|
templateUrl: './home.html',
|
||||||
styleUrl: './home.scss'
|
styleUrl: './home.scss'
|
||||||
|
|
44
frontend/src/app/shared/what-filter/what-filter.ts
Normal file
44
frontend/src/app/shared/what-filter/what-filter.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-what-filter',
|
||||||
|
standalone: true,
|
||||||
|
imports: [CommonModule, FormsModule],
|
||||||
|
template: `
|
||||||
|
<div class="what-filter">
|
||||||
|
<label *ngIf="label" class="filter-label">{{label}}</label>
|
||||||
|
<select class="input" [(ngModel)]="internalSelected" (ngModelChange)="onSelectedChange($event)">
|
||||||
|
<option value="">Tous les types</option>
|
||||||
|
<option *ngFor="let what of available" [value]="what">{{what}}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
styles: [`
|
||||||
|
.what-filter { display: flex; flex-direction: column; gap: 6px; }
|
||||||
|
.filter-label { font-size: 0.9rem; color: #374151; }
|
||||||
|
.input { padding: 8px 10px; border: 1px solid #dee2e6; border-radius: 4px; font-size: 0.9rem; }
|
||||||
|
.input:focus { outline: none; border-color: #3498db; }
|
||||||
|
`]
|
||||||
|
})
|
||||||
|
export class WhatFilterComponent {
|
||||||
|
@Input() available: string[] = [];
|
||||||
|
@Input() label: string | null = null;
|
||||||
|
|
||||||
|
@Input() set selected(val: string) {
|
||||||
|
this.internalSelected = val || '';
|
||||||
|
}
|
||||||
|
get selected(): string { return this.internalSelected; }
|
||||||
|
|
||||||
|
@Output() selectedChange = new EventEmitter<string>();
|
||||||
|
|
||||||
|
internalSelected = '';
|
||||||
|
|
||||||
|
onSelectedChange(value: string) {
|
||||||
|
this.internalSelected = value || '';
|
||||||
|
this.selectedChange.emit(this.internalSelected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue