fix: polish analytics dashboard tables
Some checks failed
CI/CD Pipeline / Quality Gate (push) Failing after 2m21s
CI/CD Pipeline / Build and Deploy Dev via Compose (push) Has been skipped

This commit is contained in:
Gleb Korotkiy
2026-06-21 12:27:22 +03:00
parent f43f2055e3
commit da273308f9
3 changed files with 623 additions and 49 deletions

View File

@@ -989,7 +989,8 @@ select {
.analytics-table {
width: 100%;
table-layout: fixed;
border-collapse: collapse;
border-collapse: separate;
border-spacing: 0;
color: var(--Infographic-Main-Dark-Blue, #022456);
font-size: 12px;
line-height: 16px;
@@ -997,11 +998,18 @@ select {
.analytics-table th,
.analytics-table td {
padding: 6px 7px;
text-align: left;
vertical-align: top;
}
.analytics-table th {
padding: 6px 7px;
}
.analytics-table td {
padding: 8px 7px;
}
.analytics-table th {
position: sticky;
top: 0;
@@ -1009,26 +1017,38 @@ select {
background: var(--Infographic-Base-White, #ffffff);
color: rgb(2 36 86 / 0.66);
font-weight: 800;
transition: background-color 160ms ease;
}
.analytics-table th:hover {
background: rgb(232 236 242 / 0.9);
background: var(--Infographic-Base-White, #ffffff);
}
.analytics-table tbody tr {
.analytics-table tbody td {
transition: background-color 160ms ease;
}
.analytics-table tbody tr:hover {
.analytics-table tbody tr:hover td {
background: rgb(243 243 243 / 0.7);
}
.analytics-table tbody tr:hover td:first-child {
border-radius: 10px 0 0 10px;
}
.analytics-table tbody tr:hover td:last-child {
border-radius: 0 10px 10px 0;
}
.analytics-table tbody tr.analytics-table-empty-row:hover,
.ranking-table tbody tr.ranking-table-empty-row:hover {
background: transparent;
}
.analytics-table tbody tr.analytics-table-empty-row:hover td,
.ranking-table tbody tr.ranking-table-empty-row:hover td {
background: transparent;
}
.analytics-table th:first-child,
.analytics-table td:first-child {
width: 44px;
@@ -1063,7 +1083,30 @@ select {
.sez-priority-table th:nth-child(3),
.sez-priority-table td:nth-child(3) {
width: 140px;
width: 170px;
}
.analytics-table-header-label {
display: inline-flex;
width: 100%;
min-width: 0;
min-height: 32px;
align-items: center;
border-radius: 10px;
padding: 6px 10px;
transition: background-color 160ms ease;
}
.analytics-table th:first-child .analytics-table-header-label {
justify-content: center;
}
.analytics-table th:last-child .analytics-table-header-label {
justify-content: flex-end;
}
.analytics-table th:hover .analytics-table-header-label {
background: rgb(232 236 242 / 0.9);
}
.analytics-table-sort-button {
@@ -1072,20 +1115,33 @@ select {
min-width: 0;
align-items: center;
justify-content: flex-end;
gap: 4px;
gap: 6px;
border: 0;
background: transparent;
padding: 0;
border-radius: 10px;
min-height: 32px;
padding: 6px 10px;
color: inherit;
font: inherit;
font-weight: inherit;
text-align: right;
transition: background-color 160ms ease;
cursor: pointer;
}
.analytics-table th:hover .analytics-table-sort-button,
.analytics-table-sort-button:hover,
.analytics-table-sort-button:focus-visible {
background: rgb(232 236 242 / 0.9);
}
.analytics-table-sort-button span {
flex: 0 1 auto;
min-width: 0;
overflow-wrap: anywhere;
overflow: visible;
text-overflow: clip;
overflow-wrap: normal;
white-space: nowrap;
}
.analytics-table-sort-button svg {
@@ -1093,7 +1149,7 @@ select {
min-width: 15px;
height: 15px;
flex: 0 0 15px;
color: rgb(2 36 86 / 0.28);
color: rgb(2 36 86 / 0.42);
stroke-width: 2.25;
transform-origin: center;
transition:
@@ -1103,7 +1159,7 @@ select {
.analytics-table-sort-button:hover svg,
.analytics-table-sort-button.is-active svg {
color: rgb(2 36 86 / 0.62);
color: rgb(2 36 86 / 0.68);
}
.analytics-table-sort-button.is-desc svg {
@@ -1173,9 +1229,10 @@ select {
.ranking-table {
width: 100%;
min-width: 0;
min-width: 560px;
table-layout: fixed;
border-collapse: collapse;
border-collapse: separate;
border-spacing: 0;
color: var(--Infographic-Main-Dark-Blue, #022456);
font-size: 12.5px;
line-height: 17px;
@@ -1186,11 +1243,11 @@ select {
}
.ranking-table__region-col {
width: 45%;
width: auto;
}
.ranking-table__metric-col {
width: 16%;
width: 136px;
}
.analytics-dashboard-grid.is-clusters .ranking-table__region-col,
@@ -1202,16 +1259,23 @@ select {
.analytics-dashboard-grid.is-clusters .ranking-table__metric-col,
.analytics-dashboard-grid.is-sez .ranking-table__metric-col,
.analytics-dashboard-grid.is-technoparks .ranking-table__metric-col {
width: 112px;
width: 136px;
}
.ranking-table th,
.ranking-table td {
padding: 6px 8px;
text-align: left;
vertical-align: middle;
}
.ranking-table th {
padding: 6px 8px;
}
.ranking-table td {
padding: 8px 8px;
}
.ranking-table th {
position: sticky;
top: 0;
@@ -1219,11 +1283,10 @@ select {
background: var(--Infographic-Base-White, #ffffff);
color: var(--Infographic-Main-Dark-Blue, #022456);
font-weight: 800;
transition: background-color 160ms ease;
}
.ranking-table th:hover {
background: rgb(232 236 242 / 0.96);
background: var(--Infographic-Base-White, #ffffff);
}
.ranking-table th:first-child,
@@ -1242,29 +1305,60 @@ select {
text-align: right;
}
.ranking-table-header-label {
display: inline-flex;
width: 100%;
min-width: 0;
min-height: 32px;
align-items: center;
border-radius: 10px;
padding: 6px 10px;
transition: background-color 160ms ease;
}
.ranking-table th:first-child .ranking-table-header-label {
justify-content: center;
}
.ranking-table th:nth-child(n + 3) .ranking-table-header-label {
justify-content: flex-end;
}
.ranking-table th:hover .ranking-table-header-label {
background: rgb(232 236 242 / 0.96);
}
.ranking-table-sort-button {
display: inline-flex;
width: 100%;
min-width: 0;
align-items: center;
justify-content: flex-end;
gap: 4px;
gap: 6px;
border: 0;
background: transparent;
padding: 0;
border-radius: 10px;
min-height: 32px;
padding: 6px 10px;
color: inherit;
font: inherit;
font-weight: inherit;
text-align: right;
transition: background-color 160ms ease;
cursor: pointer;
}
.ranking-table-sort-button span {
min-width: 0;
overflow-wrap: anywhere;
.ranking-table th:hover .ranking-table-sort-button,
.ranking-table-sort-button:hover,
.ranking-table-sort-button:focus-visible {
background: rgb(232 236 242 / 0.96);
}
.ranking-table th:nth-child(n + 3) .ranking-table-sort-button span {
.ranking-table-sort-button span {
flex: 0 1 auto;
min-width: 0;
overflow: visible;
text-overflow: clip;
overflow-wrap: normal;
white-space: nowrap;
}
@@ -1274,7 +1368,7 @@ select {
min-width: 15px;
height: 15px;
flex: 0 0 15px;
color: rgb(2 36 86 / 0.28);
color: rgb(2 36 86 / 0.42);
stroke-width: 2.25;
transform-origin: center;
transition:
@@ -1284,17 +1378,29 @@ select {
.ranking-table-sort-button:hover svg,
.ranking-table-sort-button.is-active svg {
color: rgb(2 36 86 / 0.62);
color: rgb(2 36 86 / 0.68);
}
.ranking-table-sort-button.is-desc svg {
transform: rotate(180deg);
}
.ranking-table tbody tr:hover {
.ranking-table tbody td {
transition: background-color 160ms ease;
}
.ranking-table tbody tr:hover td {
background: rgb(243 243 243 / 0.7);
}
.ranking-table tbody tr:hover td:first-child {
border-radius: 10px 0 0 10px;
}
.ranking-table tbody tr:hover td:last-child {
border-radius: 0 10px 10px 0;
}
.analytics-chart-legend {
display: flex;
flex-wrap: wrap;
@@ -1446,7 +1552,7 @@ select {
.cluster-specializations-table th:nth-child(3),
.cluster-specializations-table td:nth-child(3) {
width: 170px;
width: 220px;
text-align: right;
}

View File

@@ -206,13 +206,6 @@ const dashboardTabs = computed<DashboardTabOption[]>(() => [
...option,
kind: 'association' as const,
})),
{
associations_count: null,
disabled: false,
id: REGION_RATING_TAB_ID,
kind: 'region-rating',
label: 'Рейтинг субъектов РФ',
},
])
const isRegionRatingTabActive = computed(() => activeDashboardTab.value === REGION_RATING_TAB_ID)
const isDashboardDataLoading = computed(() => dashboard.isAnalyticsFetching)
@@ -979,8 +972,14 @@ const formatAreaUnit = (unit: string): string => (unit === 'ha' ? 'га' : unit)
<table class="analytics-table sez-priority-table">
<thead>
<tr>
<th scope="col" aria-label="Номер"></th>
<th>Наименование направления деятельности</th>
<th scope="col" aria-label="Номер">
<span class="analytics-table-header-label"></span>
</th>
<th>
<span class="analytics-table-header-label">
Наименование направления деятельности
</span>
</th>
<th :aria-sort="getSortAria(sezPrioritySort, 'sez_count')">
<button
type="button"
@@ -992,8 +991,8 @@ const formatAreaUnit = (unit: string): string => (unit === 'ha' ? 'га' : unit)
aria-label="Сортировать приоритетные направления по количеству ОЭЗ"
@click="updateMainTableSort('sez', 'sez_count')"
>
<ArrowUp aria-hidden="true" />
<span>Количество ОЭЗ</span>
<ArrowUp aria-hidden="true" />
</button>
</th>
</tr>
@@ -1066,8 +1065,12 @@ const formatAreaUnit = (unit: string): string => (unit === 'ha' ? 'га' : unit)
<table class="analytics-table technopark-area-table">
<thead>
<tr>
<th scope="col" aria-label="Номер"></th>
<th>Название технопарка</th>
<th scope="col" aria-label="Номер">
<span class="analytics-table-header-label"></span>
</th>
<th>
<span class="analytics-table-header-label">Название технопарка</span>
</th>
<th :aria-sort="getSortAria(technoparkAreaSort, 'area_value')">
<button
type="button"
@@ -1079,8 +1082,8 @@ const formatAreaUnit = (unit: string): string => (unit === 'ha' ? 'га' : unit)
aria-label="Сортировать технопарки по площади"
@click="updateMainTableSort('technoparks', 'area_value')"
>
<ArrowUp aria-hidden="true" />
<span>Площадь</span>
<ArrowUp aria-hidden="true" />
</button>
</th>
</tr>
@@ -1117,8 +1120,14 @@ const formatAreaUnit = (unit: string): string => (unit === 'ha' ? 'га' : unit)
<table class="analytics-table cluster-specializations-table">
<thead>
<tr>
<th scope="col" aria-label="Номер"></th>
<th>Наименование специализации</th>
<th scope="col" aria-label="Номер">
<span class="analytics-table-header-label"></span>
</th>
<th>
<span class="analytics-table-header-label">
Наименование специализации
</span>
</th>
<th
:aria-sort="getSortAria(clusterSpecializationsSort, 'clusters_count')"
>
@@ -1138,8 +1147,8 @@ const formatAreaUnit = (unit: string): string => (unit === 'ha' ? 'га' : unit)
aria-label="Сортировать специализации по количеству кластеров"
@click="updateMainTableSort('clusters', 'clusters_count')"
>
<ArrowUp aria-hidden="true" />
<span>Количество кластеров</span>
<ArrowUp aria-hidden="true" />
</button>
</th>
</tr>
@@ -1297,8 +1306,12 @@ const formatAreaUnit = (unit: string): string => (unit === 'ha' ? 'га' : unit)
</colgroup>
<thead>
<tr>
<th scope="col" aria-label="Номер"></th>
<th>Субъект РФ</th>
<th scope="col" aria-label="Номер">
<span class="ranking-table-header-label"></span>
</th>
<th>
<span class="ranking-table-header-label">Субъект РФ</span>
</th>
<th
v-for="column in regionRankingColumns"
:key="column.key"
@@ -1314,8 +1327,8 @@ const formatAreaUnit = (unit: string): string => (unit === 'ha' ? 'га' : unit)
:aria-label="`Сортировать рейтинг субъектов по колонке ${column.label}`"
@click="updateRegionRankingSort(column.key)"
>
<ArrowUp aria-hidden="true" />
<span>{{ column.label }}</span>
<ArrowUp aria-hidden="true" />
</button>
</th>
</tr>