style agenda
This commit is contained in:
parent
737781e9aa
commit
7dd38624a4
7 changed files with 471 additions and 161 deletions
|
@ -1,10 +1,6 @@
|
|||
<div class="agenda-page">
|
||||
<div class="layout">
|
||||
<div class="aside">
|
||||
<app-menu></app-menu>
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
@if (isLoading) {
|
||||
<div class="loading">
|
||||
<div class="loading-spinner"></div>
|
||||
|
@ -12,31 +8,31 @@
|
|||
</div>
|
||||
} @else {
|
||||
<div class="agenda-layout">
|
||||
<aside class="agenda-sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h3>Agenda</h3>
|
||||
<small>{{filteredCalendarEvents.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>
|
||||
@if (selectedDate) {
|
||||
<div class="date-filter-info">
|
||||
<small>Filtré par date: {{formatDayHeader(selectedDate)}}</small>
|
||||
<button class="btn-reset-date" (click)="clearDateFilter()">Afficher tous les jours</button>
|
||||
<aside class="agenda-sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h3>Agenda</h3>
|
||||
<small>{{filteredCalendarEvents.length}} évènements</small>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="day-groups">
|
||||
@for (group of groupedEvents; track group.dateKey) {
|
||||
<div class="day-group" [attr.data-date-key]="group.dateKey">
|
||||
<div class="day-title">{{formatDayHeader(group.date)}}</div>
|
||||
<ul class="event-list">
|
||||
@for (ev of group.items; track ev.id) {
|
||||
<li class="event-item" (click)="selectFromSidebar(ev)" [class.active]="selectedEvent?.id === ev.id">
|
||||
<div class="sidebar-filters">
|
||||
<app-what-filter
|
||||
[label]="'Filtrer par type d\'événement'"
|
||||
[available]="availableWhatTypes"
|
||||
[selected]="selectedWhatFilter"
|
||||
(selectedChange)="onWhatFilterChange($event)"></app-what-filter>
|
||||
@if (selectedDate) {
|
||||
<div class="date-filter-info">
|
||||
<small>Filtré par date: {{formatDayHeader(selectedDate)}}</small>
|
||||
<button class="btn-reset-date" (click)="clearDateFilter()">Afficher tous les jours</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="day-groups">
|
||||
@for (group of groupedEvents; track group.dateKey) {
|
||||
<div class="day-group" [attr.data-date-key]="group.dateKey">
|
||||
<div class="day-title">{{formatDayHeader(group.date)}}</div>
|
||||
<ul class="event-list">
|
||||
@for (ev of group.items; track ev.id) {
|
||||
<li class="event-item" (click)="selectFromSidebar(ev)" [class.active]="selectedEvent?.id === ev.id">
|
||||
<span class="event-icon">
|
||||
@if (getImageForWhat(ev.properties.what)) {
|
||||
<img [src]="getImageForWhat(ev.properties.what)" alt="" />
|
||||
|
@ -46,44 +42,49 @@
|
|||
📌
|
||||
}
|
||||
</span>
|
||||
<div class="event-meta">
|
||||
<div class="event-title">{{ev.properties.label || ev.properties.name || 'Événement'}}</div>
|
||||
<div class="event-when">{{(ev.properties.start || ev.properties.when) || '—'}}</div>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
<div class="event-meta">
|
||||
<div class="event-title">{{ev.properties.label || ev.properties.name || 'Événement'}}</div>
|
||||
<div class="event-when">{{(ev.properties.start || ev.properties.when) || '—'}}</div>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
|
||||
@if (selectedEvent) {
|
||||
<div class="event-edit-panel">
|
||||
<div class="panel-header">
|
||||
<h3>Modifier l'événement</h3>
|
||||
<button class="btn-close" (click)="selectedEvent = null">×</button>
|
||||
</div>
|
||||
<div class="panel-content">
|
||||
<app-edit-form
|
||||
[selected]="selectedEvent"
|
||||
(saved)="onEventSaved()"
|
||||
(created)="onEventCreated()"
|
||||
(deleted)="onEventDeleted()">
|
||||
</app-edit-form>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</aside>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
|
||||
<main class="agenda-main">
|
||||
<app-calendar
|
||||
<app-calendar
|
||||
[events]="filteredCalendarEvents"
|
||||
(eventClick)="onEventClick($event)"
|
||||
(dateClick)="onDateClick($event)">
|
||||
</app-calendar>
|
||||
</main>
|
||||
|
||||
@if (selectedEvent) {
|
||||
<div class="event-edit-panel">
|
||||
<div class="panel-header">
|
||||
<h3>Modifier l'événement</h3>
|
||||
<button class="btn-close" (click)="selectedEvent = null">×</button>
|
||||
</div>
|
||||
<div class="panel-content">
|
||||
<app-edit-form
|
||||
[selected]="selectedEvent"
|
||||
(saved)="onEventSaved()"
|
||||
(created)="onEventCreated()"
|
||||
(deleted)="onEventDeleted()">
|
||||
</app-edit-form>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
grid-template-rows: minmax(100vh, auto);
|
||||
gap: 0;
|
||||
// min-height: 100vh;
|
||||
|
||||
|
||||
&.is-small {
|
||||
grid-template-columns: 100px 1fr;
|
||||
}
|
||||
|
@ -220,4 +220,4 @@
|
|||
.event-edit-panel {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const oedb = {
|
||||
presets : {
|
||||
what : {
|
||||
presets: {
|
||||
what: {
|
||||
'community': {
|
||||
label: 'Événement de base',
|
||||
description: 'Événement communautaire',
|
||||
|
@ -22,11 +22,11 @@ const oedb = {
|
|||
description: 'Événement de type Culture ouvert au public',
|
||||
durationHours: 24,
|
||||
properties: {
|
||||
createdate: { label: 'Createdate', writable: true },
|
||||
lastupdate: { label: 'Lastupdate', writable: true },
|
||||
start: { label: 'Start', writable: true },
|
||||
stop: { label: 'Stop', writable: true },
|
||||
type: { label: 'Type', writable: true }
|
||||
createdate: {label: 'Createdate', writable: true},
|
||||
lastupdate: {label: 'Lastupdate', writable: true},
|
||||
start: {label: 'Start', writable: true},
|
||||
stop: {label: 'Stop', writable: true},
|
||||
type: {label: 'Type', writable: true}
|
||||
}
|
||||
},
|
||||
'culture.floss': {
|
||||
|
@ -35,15 +35,15 @@ const oedb = {
|
|||
category: 'Autre',
|
||||
description: 'Événement de type Culture Floss',
|
||||
durationHours: 24,
|
||||
properties: {
|
||||
}}, 'culture.viparis': {
|
||||
properties: {}
|
||||
}, 'culture.viparis': {
|
||||
emoji: '📅',
|
||||
label: 'Évènements organisés par Viparis',
|
||||
category: 'Autre',
|
||||
description: 'Événement culturel par Viparis, une entreprise qui gère plusieurs grandes salles en Île de France.',
|
||||
durationHours: 24,
|
||||
properties: {
|
||||
}},
|
||||
properties: {}
|
||||
},
|
||||
|
||||
|
||||
// Culture / Arts
|
||||
|
@ -109,8 +109,8 @@ const oedb = {
|
|||
description: 'Infrastructure de recharge disponible',
|
||||
durationHours: 300,
|
||||
properties: {
|
||||
"capacity:vehicles": { label: 'Nombre de véhicules qui peuvent actuellement se brancher', writable: true },
|
||||
"capacity:vehicles:max": { label: 'Nombre de véhicules maximum à pouvoir se brancher', writable: true }
|
||||
"capacity:vehicles": {label: 'Nombre de véhicules qui peuvent actuellement se brancher', writable: true},
|
||||
"capacity:vehicles:max": {label: 'Nombre de véhicules maximum à pouvoir se brancher', writable: true}
|
||||
}
|
||||
},
|
||||
'traffic.counter.bicycle': {
|
||||
|
@ -162,9 +162,9 @@ const oedb = {
|
|||
description: 'Accident de la circulation',
|
||||
durationHours: 6,
|
||||
properties: {
|
||||
severity: { label: 'Gravité', writable: true },
|
||||
lanes_closed: { label: 'Voies fermées', writable: true },
|
||||
vehicles: { label: 'Nombre de véhicules', writable: true }
|
||||
severity: {label: 'Gravité', writable: true},
|
||||
lanes_closed: {label: 'Voies fermées', writable: true},
|
||||
vehicles: {label: 'Nombre de véhicules', writable: true}
|
||||
}
|
||||
},
|
||||
'traffic.incident': {
|
||||
|
@ -193,9 +193,9 @@ const oedb = {
|
|||
description: 'Travaux sur la chaussée',
|
||||
durationHours: 72,
|
||||
properties: {
|
||||
contractor: { label: 'Entreprise', writable: true },
|
||||
reason: { label: 'Raison', writable: true },
|
||||
lanes_affected: { label: 'Voies impactées', writable: true }
|
||||
contractor: {label: 'Entreprise', writable: true},
|
||||
reason: {label: 'Raison', writable: true},
|
||||
lanes_affected: {label: 'Voies impactées', writable: true}
|
||||
}
|
||||
},
|
||||
'traffic.OperatorAction.NetworkManagement.RoadOrCarriagewayOrLaneManagement': {
|
||||
|
@ -206,7 +206,7 @@ const oedb = {
|
|||
description: 'Événement de type Traffic OperatorAction NetworkManagement RoadOrCarriagewayOrLaneManagement',
|
||||
durationHours: 24,
|
||||
properties: {
|
||||
source: { label: 'Source', writable: true },
|
||||
source: {label: 'Source', writable: true},
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -218,7 +218,7 @@ const oedb = {
|
|||
description: 'Événement de type Traffic OperatorAction NetworkManagement RoadOrCarriagewayOrLaneManagement',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: { label: 'Source', writable: true },
|
||||
source: {label: 'Source', writable: true},
|
||||
}
|
||||
},
|
||||
'traffic.OperatorAction.NetworkManagement.ReroutingManagement': {
|
||||
|
@ -229,7 +229,7 @@ const oedb = {
|
|||
description: 'Événement de type Traffic OperatorAction NetworkManagement ReroutingManagement',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: { label: 'Source', writable: true },
|
||||
source: {label: 'Source', writable: true},
|
||||
}
|
||||
},
|
||||
'traffic.OperatorAction.ConstructionWorks': {
|
||||
|
@ -240,7 +240,7 @@ const oedb = {
|
|||
description: 'Événement de type Traffic OperatorAction ConstructionWorks',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: { label: 'Source', writable: true },
|
||||
source: {label: 'Source', writable: true},
|
||||
}
|
||||
},
|
||||
'traffic.OperatorAction.NetworkManagement.SpeedManagement': {
|
||||
|
@ -251,75 +251,75 @@ const oedb = {
|
|||
description: 'Événement de type Traffic OperatorAction SpeedManagement',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: { label: 'Source', writable: true },
|
||||
source: {label: 'Source', writable: true},
|
||||
}
|
||||
},
|
||||
// Gestion générale du réseau
|
||||
'traffic.OperatorAction.NetworkManagement.GeneralNetworkManagement': {
|
||||
emoji: '',
|
||||
'traffic.OperatorAction.NetworkManagement.GeneralNetworkManagement': {
|
||||
emoji: '',
|
||||
image: 'static/cone.png',
|
||||
label: 'Gestion générale du réseau',
|
||||
category: 'Circulation',
|
||||
description: 'Événement de type Traffic OperatorAction GeneralNetworkManagement',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: { label: 'Source', writable: true },
|
||||
}
|
||||
},
|
||||
'traffic.closed': {
|
||||
emoji: '⛔',
|
||||
label: 'Chaussée fermée',
|
||||
category: 'Circulation',
|
||||
description: 'Événement de type Traffic Closed',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: { label: 'Source', writable: true },
|
||||
}
|
||||
},
|
||||
'traffic.TrafficElement.GeneralInstructionOrMessageToRoadUsers': {
|
||||
emoji: '',
|
||||
image: 'static/cone.png',
|
||||
label: 'Instruction ou message aux usagers',
|
||||
category: 'Circulation',
|
||||
description: 'Événement de type Traffic TrafficElement GeneralInstructionOrMessageToRoadUsers',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: { label: 'Source', writable: true },
|
||||
}
|
||||
},
|
||||
'traffic.TrafficElement.Obstruction.GeneralObstruction': {
|
||||
emoji: '',
|
||||
image: 'static/cone.png',
|
||||
label: 'Obstruction générale',
|
||||
category: 'Circulation',
|
||||
description: 'Événement de type Traffic TrafficElement Obstruction GeneralObstruction',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: { label: 'Source', writable: true },
|
||||
}
|
||||
},
|
||||
'traffic.TrafficElement.Obstruction.InfrastructureDamageObstruction': {
|
||||
emoji: '⛔',
|
||||
label: 'Gestion générale du réseau',
|
||||
category: 'Circulation',
|
||||
description: 'Événement de type Traffic OperatorAction GeneralNetworkManagement',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: {label: 'Source', writable: true},
|
||||
}
|
||||
},
|
||||
'traffic.closed': {
|
||||
emoji: '⛔',
|
||||
label: 'Chaussée fermée',
|
||||
category: 'Circulation',
|
||||
description: 'Événement de type Traffic Closed',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: {label: 'Source', writable: true},
|
||||
}
|
||||
},
|
||||
'traffic.TrafficElement.GeneralInstructionOrMessageToRoadUsers': {
|
||||
emoji: '',
|
||||
image: 'static/cone.png',
|
||||
label: 'Instruction ou message aux usagers',
|
||||
category: 'Circulation',
|
||||
description: 'Événement de type Traffic TrafficElement GeneralInstructionOrMessageToRoadUsers',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: {label: 'Source', writable: true},
|
||||
}
|
||||
},
|
||||
'traffic.TrafficElement.Obstruction.GeneralObstruction': {
|
||||
emoji: '',
|
||||
image: 'static/cone.png',
|
||||
label: 'Obstruction générale',
|
||||
category: 'Circulation',
|
||||
description: 'Événement de type Traffic TrafficElement Obstruction GeneralObstruction',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: {label: 'Source', writable: true},
|
||||
}
|
||||
},
|
||||
'traffic.TrafficElement.Obstruction.InfrastructureDamageObstruction': {
|
||||
emoji: '⛔',
|
||||
|
||||
label: 'Obstruction d\'infrastructure',
|
||||
category: 'Circulation',
|
||||
description: 'Événement de type Traffic TrafficElement Obstruction InfrastructureDamageObstruction',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: { label: 'Source', writable: true },
|
||||
}
|
||||
},
|
||||
'traffic.TrafficElement.Obstruction.EnvironmentalObstruction': {
|
||||
emoji: '⛔',
|
||||
label: 'Obstruction d\'infrastructure',
|
||||
category: 'Circulation',
|
||||
description: 'Événement de type Traffic TrafficElement Obstruction InfrastructureDamageObstruction',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: {label: 'Source', writable: true},
|
||||
}
|
||||
},
|
||||
'traffic.TrafficElement.Obstruction.EnvironmentalObstruction': {
|
||||
emoji: '⛔',
|
||||
|
||||
label: 'Obstruction environnementale',
|
||||
category: 'Circulation',
|
||||
description: 'Événement de type Traffic TrafficElement Obstruction EnvironmentalObstruction',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: { label: 'Source', writable: true },
|
||||
}
|
||||
},
|
||||
label: 'Obstruction environnementale',
|
||||
category: 'Circulation',
|
||||
description: 'Événement de type Traffic TrafficElement Obstruction EnvironmentalObstruction',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
source: {label: 'Source', writable: true},
|
||||
}
|
||||
},
|
||||
'traffic.obstacle.flood': {
|
||||
emoji: '🌊',
|
||||
label: 'Chaussée inondée',
|
||||
|
@ -379,9 +379,9 @@ const oedb = {
|
|||
description: 'Tempête (vent fort)',
|
||||
durationHours: 48,
|
||||
properties: {
|
||||
wind_speed: { label: 'Vent moyen (km/h)', writable: true },
|
||||
wind_gust: { label: 'Rafales (km/h)', writable: true },
|
||||
severity: { label: 'Sévérité', writable: true }
|
||||
wind_speed: {label: 'Vent moyen (km/h)', writable: true},
|
||||
wind_gust: {label: 'Rafales (km/h)', writable: true},
|
||||
severity: {label: 'Sévérité', writable: true}
|
||||
}
|
||||
},
|
||||
'weather.thunder': {
|
||||
|
@ -391,7 +391,7 @@ const oedb = {
|
|||
description: 'Activité orageuse',
|
||||
durationHours: 12,
|
||||
properties: {
|
||||
lightning_count: { label: 'Nombre d’éclairs', writable: true }
|
||||
lightning_count: {label: 'Nombre d’éclairs', writable: true}
|
||||
}
|
||||
}, 'weather.flood': {
|
||||
emoji: '🌊',
|
||||
|
@ -400,7 +400,7 @@ const oedb = {
|
|||
description: 'Inondation',
|
||||
durationHours: 24,
|
||||
properties: {
|
||||
flood_level: { label: 'Niveau d\'inondation', writable: true }
|
||||
flood_level: {label: 'Niveau d\'inondation', writable: true}
|
||||
}
|
||||
},
|
||||
'weather.snow': {
|
||||
|
@ -410,7 +410,7 @@ const oedb = {
|
|||
description: 'Neige',
|
||||
durationHours: 12,
|
||||
properties: {
|
||||
snow_level: { label: 'Niveau de neige', writable: true }
|
||||
snow_level: {label: 'Niveau de neige', writable: true}
|
||||
}
|
||||
},
|
||||
'weather.earthquake': {
|
||||
|
@ -420,8 +420,8 @@ const oedb = {
|
|||
description: 'Séisme',
|
||||
durationHours: 6,
|
||||
properties: {
|
||||
magnitude: { label: 'Magnitude (Mw)', writable: true },
|
||||
depth_km: { label: 'Profondeur (km)', writable: true }
|
||||
magnitude: {label: 'Magnitude (Mw)', writable: true},
|
||||
depth_km: {label: 'Profondeur (km)', writable: true}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -433,8 +433,8 @@ const oedb = {
|
|||
description: 'Interruption d\'itinéraire',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
reason: { label: 'Raison', writable: true },
|
||||
route: { label: 'Itinéraire', writable: true },
|
||||
reason: {label: 'Raison', writable: true},
|
||||
route: {label: 'Itinéraire', writable: true},
|
||||
|
||||
}
|
||||
},
|
||||
|
@ -445,8 +445,8 @@ const oedb = {
|
|||
description: 'Mauvais sens de circulation',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
reason: { label: 'Raison', writable: true },
|
||||
route: { label: 'Itinéraire', writable: true },
|
||||
reason: {label: 'Raison', writable: true},
|
||||
route: {label: 'Itinéraire', writable: true},
|
||||
|
||||
}
|
||||
},
|
||||
|
@ -457,7 +457,7 @@ const oedb = {
|
|||
description: 'Contestation d\'itinéraire',
|
||||
durationHours: 200,
|
||||
properties: {
|
||||
route: { label: 'Itinéraire', writable: true },
|
||||
route: {label: 'Itinéraire', writable: true},
|
||||
}
|
||||
}
|
||||
// ici ajouter d'autres catégories d'évènements à suggérer
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue