feat: add services page and API endpoints for service cost breakdown

- Implemented new API endpoints for fetching global services and service tenants details.
- Created a new services.html page with a sidebar for navigation and a chart for service costs.
- Updated frontend JavaScript to handle service data loading and rendering.
- Enhanced the dashboard with provider filtering options for AWS and Azure.
- Added a segmented toggle for selecting the date range for service costs.
- Improved styling for the sidebar and data tables.
- Refactored common utility functions for better reusability across pages.
This commit is contained in:
ludal committed 2026-09-20 21:55:52 +02:00
1 parent 9e78dfa4f2
commit c39364eda4
12 files changed
+834 -114

No files matched your search

+128 -22
View File
@@ -132,11 +132,103 @@ a {
}
.container {
max-width: 1240px;
/* width: 100% est nécessaire ici : .page (son parent) est en
display:flex, et des marges auto sur l'axe transversal désactivent
l'étirement flex par défaut — sans ce width, .container retombe sur
un calcul "taille selon son contenu" au lieu de remplir l'espace
disponible jusqu'à max-width. */
width: 100%;
max-width: 1520px;
margin: 0 auto;
padding: 28px 32px 64px;
}
/* ---------------------------------------------------------------- */
/* Sidebar de navigation */
/* ---------------------------------------------------------------- */
.app-shell {
display: flex;
min-height: 100vh;
align-items: stretch;
}
.sidebar {
width: 220px;
flex: none;
background: var(--surface-1);
border-right: 1px solid var(--border);
padding: 20px 0;
display: flex;
flex-direction: column;
gap: 4px;
}
.sidebar-brand {
padding: 0 20px 16px;
margin: 0 0 12px;
font-size: 14px;
font-weight: 600;
border-bottom: 1px solid var(--border);
}
.sidebar-nav {
display: flex;
flex-direction: column;
gap: 2px;
padding: 0 12px;
}
.sidebar-link {
display: block;
padding: 9px 12px;
border-radius: var(--radius-control);
color: var(--text-secondary);
text-decoration: none;
font-size: 13px;
font-weight: 500;
}
.sidebar-link:hover {
background: color-mix(in srgb, var(--text-primary) 6%, transparent);
color: var(--text-primary);
}
.sidebar-link.active {
background: color-mix(in srgb, var(--series-1) 14%, transparent);
color: var(--series-1);
}
.page {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
}
@media (max-width: 700px) {
.app-shell {
flex-direction: column;
min-height: 0;
}
.sidebar {
width: auto;
border-right: none;
border-bottom: 1px solid var(--border);
padding: 12px;
}
.sidebar-brand {
display: none;
}
.sidebar-nav {
flex-direction: row;
padding: 0;
}
}
.section-title {
font-size: 13px;
font-weight: 600;
@@ -207,23 +299,6 @@ a {
display: none;
}
/* ---------------------------------------------------------------- */
/* Grille de graphiques */
/* ---------------------------------------------------------------- */
.chart-grid {
display: grid;
grid-template-columns: 1.4fr 1fr;
gap: 16px;
align-items: stretch;
}
@media (max-width: 860px) {
.chart-grid {
grid-template-columns: 1fr;
}
}
.chart-card {
padding: 20px 20px 12px;
display: flex;
@@ -299,14 +374,14 @@ a {
outline-offset: -1px;
}
.range-toggle {
.segmented-toggle {
display: inline-flex;
border: 1px solid var(--border);
border-radius: var(--radius-control);
overflow: hidden;
}
.range-toggle button {
.segmented-toggle button {
border: none;
background: transparent;
color: var(--text-secondary);
@@ -316,11 +391,11 @@ a {
font-family: inherit;
}
.range-toggle button + button {
.segmented-toggle button + button {
border-left: 1px solid var(--border);
}
.range-toggle button.active {
.segmented-toggle button.active {
background: var(--series-1);
color: #ffffff;
font-weight: 500;
@@ -369,6 +444,21 @@ table.data-table {
white-space: nowrap;
}
.data-table thead th.sortable {
cursor: pointer;
user-select: none;
}
.data-table thead th.sortable:hover {
color: var(--text-primary);
}
.data-table thead th.sorted-asc,
.data-table thead th.sorted-desc {
color: var(--text-primary);
font-weight: 600;
}
.data-table td {
padding: 10px 12px;
border-bottom: 1px solid var(--gridline);
@@ -379,6 +469,11 @@ table.data-table {
border-bottom: none;
}
.data-table tfoot td {
padding: 10px 12px;
border-top: 1px solid var(--gridline);
}
.data-table tbody tr.clickable {
cursor: pointer;
}
@@ -578,6 +673,17 @@ table.data-table {
border-bottom: none;
}
.resource-row.clickable {
cursor: pointer;
margin: 0 -8px;
padding: 10px 8px;
border-radius: var(--radius-control);
}
.resource-row.clickable:hover {
background: color-mix(in srgb, var(--text-primary) 4%, transparent);
}
.resource-name {
font-size: 13px;
overflow-wrap: anywhere;