Le dashboard ne charge plus les alertes lui-même : le widget porte le flux, ses filtres, ses états et son rafraîchissement. Disparaissent la liste rouge quelle que soit la sévérité, le bandeau d'erreur dédié et la copie locale de la table sévérité vers ton, désormais dans alert-presentation.ts. Le spec passe par un helper setup() qui fournit aussi les services du widget enfant.
101 lines
3.3 KiB
HTML
101 lines
3.3 KiB
HTML
<div class="dashboard">
|
|
<header class="dashboard__header">
|
|
<div class="dashboard__brand">
|
|
<a routerLink="/dashboard" class="ev-brand-link">
|
|
<ev-brand class="dashboard__logo" />
|
|
</a>
|
|
<div>
|
|
<h1>Vue d'ensemble</h1>
|
|
<p class="dashboard__subtitle">Consommation instantanée du parc</p>
|
|
</div>
|
|
</div>
|
|
<div class="dashboard__actions">
|
|
@if (auth.principal()?.role === 'admin') {
|
|
<a routerLink="/monitoring/sensors" class="ev-link">Supervision des capteurs</a>
|
|
}
|
|
<a routerLink="/sites" class="ev-link">Voir les sites</a>
|
|
<ev-button
|
|
class="logout-button"
|
|
variant="secondary"
|
|
[fullWidth]="false"
|
|
(click)="onLogout()"
|
|
>Déconnexion</ev-button
|
|
>
|
|
</div>
|
|
</header>
|
|
|
|
@if (statsError(); as message) {
|
|
<ev-alert severity="danger" class="banner-error">{{ message }}</ev-alert>
|
|
}
|
|
@if (predictionsError(); as message) {
|
|
<ev-alert severity="danger" class="banner-error">{{ message }}</ev-alert>
|
|
}
|
|
|
|
@if (stats(); as s) {
|
|
<section class="overview">
|
|
<ev-card class="card card--gauge">
|
|
<span class="card__label">Consommation vs capacité</span>
|
|
<app-consumption-gauge
|
|
[consumption]="s.total_consumption_kw"
|
|
[capacity]="s.total_capacity_kw"
|
|
/>
|
|
<span class="card__value"
|
|
>{{ s.total_consumption_kw | number: '1.0-1' }} /
|
|
{{ s.total_capacity_kw | number }} kW</span
|
|
>
|
|
</ev-card>
|
|
|
|
<ev-card class="card">
|
|
<span class="card__label">Charge moyenne du parc</span>
|
|
<span class="card__value">{{ s.average_load_percent }} %</span>
|
|
<div class="progress-bar">
|
|
<div class="progress-bar__fill" [style.width.%]="s.average_load_percent"></div>
|
|
</div>
|
|
</ev-card>
|
|
|
|
<ev-card class="card">
|
|
<span class="card__label">Sites suivis</span>
|
|
<span class="card__value">{{ s.total_sites }}</span>
|
|
</ev-card>
|
|
</section>
|
|
|
|
<section class="chart-section">
|
|
<h2>Charge et alerte visuelle par site</h2>
|
|
<app-site-load-chart [sites]="s.sites" />
|
|
</section>
|
|
}
|
|
|
|
<section class="alerts-section">
|
|
<app-alert-feed />
|
|
</section>
|
|
|
|
@if (predictions().length > 0) {
|
|
<section class="predictions-section">
|
|
<h2>Prévisions de consommation</h2>
|
|
<ul class="predictions-list">
|
|
@for (site of predictions(); track site.site_id) {
|
|
<li class="prediction-item">
|
|
<span class="prediction-item__site">{{ site.site_name }}</span>
|
|
@if (site.prediction; as prediction) {
|
|
@if (prediction.status === 'available') {
|
|
<span class="prediction-item__value">
|
|
{{ prediction.predicted_value | number: '1.0-1' }} kWh
|
|
<span class="prediction-item__target">{{
|
|
prediction.target_at | date: "dd/MM 'à' HH:mm"
|
|
}}</span>
|
|
</span>
|
|
} @else {
|
|
<ev-badge [tone]="badgeToneForPredictionStatus(prediction.status)">{{
|
|
prediction.status === 'insufficient_data' ? 'Historique insuffisant' : 'Erreur'
|
|
}}</ev-badge>
|
|
}
|
|
} @else {
|
|
<ev-badge tone="neutral">Pas encore de prévision</ev-badge>
|
|
}
|
|
</li>
|
|
}
|
|
</ul>
|
|
</section>
|
|
}
|
|
</div>
|