This commit is contained in:
Tykayn 2025-10-05 00:24:43 +02:00 committed by tykayn
parent 464e0e5499
commit 080cb4df48
5 changed files with 90 additions and 13 deletions

View file

@ -11,6 +11,13 @@
<h3>Agenda</h3>
<small>{{calendarEvents.length}} évènements</small>
</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">
@for (group of groupedEvents; track group.dateKey) {
<div class="day-group">
@ -41,7 +48,7 @@
<main class="agenda-main">
<app-calendar
[events]="calendarEvents"
[events]="filteredCalendarEvents"
(eventClick)="onEventClick($event)"
(dateClick)="onDateClick($event)">
</app-calendar>

View file

@ -5,6 +5,7 @@ import { OedbApi } from '../../services/oedb-api';
import { EditForm } from '../../forms/edit-form/edit-form';
import { CalendarComponent, CalendarEvent } from './calendar/calendar';
import oedb from '../../../oedb-types';
import { WhatFilterComponent } from '../../shared/what-filter/what-filter';
interface OedbEvent {
id: string;
@ -27,7 +28,7 @@ interface OedbEvent {
@Component({
selector: 'app-agenda',
standalone: true,
imports: [CommonModule, FormsModule, EditForm, CalendarComponent],
imports: [CommonModule, FormsModule, EditForm, CalendarComponent, WhatFilterComponent],
templateUrl: './agenda.html',
styleUrl: './agenda.scss'
})
@ -35,11 +36,15 @@ export class Agenda implements OnInit {
private oedbApi = inject(OedbApi);
events: OedbEvent[] = [];
filteredEvents: OedbEvent[] = [];
calendarEvents: CalendarEvent[] = [];
filteredCalendarEvents: CalendarEvent[] = [];
selectedEvent: OedbEvent | null = null;
isLoading = false;
groupedEvents: Array<{ dateKey: string; date: Date; items: OedbEvent[] }> = [];
availableWhatTypes: string[] = [];
selectedWhatFilter = '';
ngOnInit() {
this.loadEvents();
@ -61,14 +66,15 @@ export class Agenda implements OnInit {
this.oedbApi.getEvents(params).subscribe((response: any) => {
this.events = Array.isArray(response?.features) ? response.features : [];
this.convertToCalendarEvents();
this.buildGroupedEvents();
this.updateAvailableWhatTypes();
this.applyWhatFilter();
this.isLoading = false;
});
}
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 endDate = event.properties.stop ? this.parseEventDate(event.properties.stop) : null;
@ -83,6 +89,7 @@ export class Agenda implements OnInit {
properties: event.properties
};
});
this.filteredCalendarEvents = this.calendarEvents;
}
parseEventDate(dateString: string | undefined): Date {
@ -132,6 +139,29 @@ export class Agenda implements OnInit {
}
// 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 {
const ds = ev.properties.start || ev.properties.when;
return this.parseEventDate(ds);

View file

@ -52,13 +52,7 @@
<input class="input" type="text" placeholder="Rechercher..." [(ngModel)]="searchText" (ngModelChange)="onSearchChange()">
<div class="control-group">
<label>Filtrer par type d'événement</label>
<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>
<app-what-filter [label]="'Filtrer par type d\'événement'" [available]="availableWhatTypes" [selected]="selectedWhatFilter" (selectedChange)="selectedWhatFilter = $event; onWhatFilterChange()"></app-what-filter>
</div>

View file

@ -8,6 +8,7 @@ import { OedbApi } from '../../services/oedb-api';
import { UnlocatedEvents } from '../../shared/unlocated-events/unlocated-events';
import { OsmAuth } from '../../services/osm-auth';
import { Osm } from '../../forms/osm/osm';
import { WhatFilterComponent } from '../../shared/what-filter/what-filter';
@Component({
selector: 'app-home',
standalone: true,
@ -17,7 +18,8 @@ import { Osm } from '../../forms/osm/osm';
UnlocatedEvents,
EditForm,
Osm,
FormsModule
FormsModule,
WhatFilterComponent
],
templateUrl: './home.html',
styleUrl: './home.scss'

View 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);
}
}