fix(dashboard): add structured routing sections header with title and aligned test-all button
- Wrap test-all button in a clean sections header with Lucide route icon and localized title - Remove loose inline styles and align button with card grid boundaries - Add responsive wrapping for mobile displays - Add Russian localization for Routing sections - Rebuild LuCI frontend bundle
This commit is contained in:
@@ -6693,6 +6693,9 @@ msgstr ""
|
|||||||
msgid "Routing section"
|
msgid "Routing section"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Routing sections"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:995
|
#: ../luci-app-tachyon/htdocs/luci-static/resources/view/tachyon/settings.js:995
|
||||||
msgid "Routing sections, rules and strategies"
|
msgid "Routing sections, rules and strategies"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -4160,6 +4160,9 @@ msgstr "Правила маршрутизации"
|
|||||||
msgid "Routing section"
|
msgid "Routing section"
|
||||||
msgstr "Секция маршрутизации"
|
msgstr "Секция маршрутизации"
|
||||||
|
|
||||||
|
msgid "Routing sections"
|
||||||
|
msgstr "Секции маршрутизации"
|
||||||
|
|
||||||
msgid "Routing sections, rules and strategies"
|
msgid "Routing sections, rules and strategies"
|
||||||
msgstr "Секции маршрутизации, правила и стратегии"
|
msgstr "Секции маршрутизации, правила и стратегии"
|
||||||
|
|
||||||
|
|||||||
@@ -1857,29 +1857,62 @@ async function renderSectionsWidget() {
|
|||||||
'div',
|
'div',
|
||||||
{
|
{
|
||||||
class: 'tachyon_dashboard-page__sections-header',
|
class: 'tachyon_dashboard-page__sections-header',
|
||||||
style:
|
|
||||||
'display: flex; justify-content: flex-end; align-items: center; margin-bottom: 12px; gap: 8px;',
|
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
E(
|
E(
|
||||||
'button',
|
'div',
|
||||||
{
|
{
|
||||||
type: 'button',
|
class: 'tachyon_dashboard-page__sections-header__title',
|
||||||
id: 'dashboard-test-all-sections-button',
|
|
||||||
class: 'btn',
|
|
||||||
style:
|
|
||||||
'display: inline-flex; align-items: center; justify-content: center; gap: 6px; white-space: nowrap; padding: 4px 14px; height: 32px; font-size: 13px;',
|
|
||||||
disabled: isTestingAllSections ? true : undefined,
|
|
||||||
click: () => {
|
|
||||||
void handleTestAllSections();
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
isTestingAllSections
|
[
|
||||||
? [
|
svgEl(
|
||||||
renderLoaderCircleIcon24(),
|
'svg',
|
||||||
E('span', {}, _('Testing all sections...')),
|
{
|
||||||
]
|
width: '16',
|
||||||
: E('span', {}, _('Test all sections')),
|
height: '16',
|
||||||
|
viewBox: '0 0 24 24',
|
||||||
|
fill: 'none',
|
||||||
|
stroke: 'currentColor',
|
||||||
|
'stroke-width': '2',
|
||||||
|
'stroke-linecap': 'round',
|
||||||
|
'stroke-linejoin': 'round',
|
||||||
|
},
|
||||||
|
[
|
||||||
|
svgEl('circle', { cx: '6', cy: '19', r: '3' }),
|
||||||
|
svgEl('path', {
|
||||||
|
d: 'M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15',
|
||||||
|
}),
|
||||||
|
svgEl('circle', { cx: '18', cy: '5', r: '3' }),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
E('span', {}, _('Routing sections')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
E(
|
||||||
|
'div',
|
||||||
|
{
|
||||||
|
class: 'tachyon_dashboard-page__sections-header__actions',
|
||||||
|
},
|
||||||
|
[
|
||||||
|
E(
|
||||||
|
'button',
|
||||||
|
{
|
||||||
|
type: 'button',
|
||||||
|
id: 'dashboard-test-all-sections-button',
|
||||||
|
class: 'btn',
|
||||||
|
disabled: isTestingAllSections ? true : undefined,
|
||||||
|
click: () => {
|
||||||
|
void handleTestAllSections();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
isTestingAllSections
|
||||||
|
? [
|
||||||
|
renderLoaderCircleIcon24(),
|
||||||
|
E('span', {}, _('Testing all sections...')),
|
||||||
|
]
|
||||||
|
: E('span', {}, _('Test all sections')),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -189,13 +189,53 @@ export const styles = `
|
|||||||
opacity: 0.65;
|
opacity: 0.65;
|
||||||
}
|
}
|
||||||
|
|
||||||
#dashboard-test-all-sections-button {
|
.tachyon_dashboard-page__sections-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 16px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
padding: 0 2px;
|
||||||
|
gap: 12px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tachyon_dashboard-page__sections-header__title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
color: var(--text-color-high);
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.2px;
|
||||||
|
min-width: 0;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tachyon_dashboard-page__sections-header__title svg {
|
||||||
|
flex-shrink: 0;
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tachyon_dashboard-page__sections-header__actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 6px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tachyon_dashboard-page .btn#dashboard-test-all-sections-button {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
padding: 4px 14px;
|
||||||
|
height: 30px;
|
||||||
|
min-height: 28px;
|
||||||
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#dashboard-test-all-sections-button svg {
|
#dashboard-test-all-sections-button svg {
|
||||||
@@ -210,6 +250,13 @@ export const styles = `
|
|||||||
opacity: 0.65;
|
opacity: 0.65;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.tachyon_dashboard-page__sections-header {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tachyon_dashboard-page__outbound-grid {
|
.tachyon_dashboard-page__outbound-grid {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
@@ -9174,26 +9174,61 @@ async function renderSectionsWidget() {
|
|||||||
const testAllHeader = hasTestableSections ? E(
|
const testAllHeader = hasTestableSections ? E(
|
||||||
"div",
|
"div",
|
||||||
{
|
{
|
||||||
class: "tachyon_dashboard-page__sections-header",
|
class: "tachyon_dashboard-page__sections-header"
|
||||||
style: "display: flex; justify-content: flex-end; align-items: center; margin-bottom: 12px; gap: 8px;"
|
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
E(
|
E(
|
||||||
"button",
|
"div",
|
||||||
{
|
{
|
||||||
type: "button",
|
class: "tachyon_dashboard-page__sections-header__title"
|
||||||
id: "dashboard-test-all-sections-button",
|
|
||||||
class: "btn",
|
|
||||||
style: "display: inline-flex; align-items: center; justify-content: center; gap: 6px; white-space: nowrap; padding: 4px 14px; height: 32px; font-size: 13px;",
|
|
||||||
disabled: isTestingAllSections ? true : void 0,
|
|
||||||
click: () => {
|
|
||||||
void handleTestAllSections();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
isTestingAllSections ? [
|
[
|
||||||
renderLoaderCircleIcon24(),
|
svgEl(
|
||||||
E("span", {}, _("Testing all sections..."))
|
"svg",
|
||||||
] : E("span", {}, _("Test all sections"))
|
{
|
||||||
|
width: "16",
|
||||||
|
height: "16",
|
||||||
|
viewBox: "0 0 24 24",
|
||||||
|
fill: "none",
|
||||||
|
stroke: "currentColor",
|
||||||
|
"stroke-width": "2",
|
||||||
|
"stroke-linecap": "round",
|
||||||
|
"stroke-linejoin": "round"
|
||||||
|
},
|
||||||
|
[
|
||||||
|
svgEl("circle", { cx: "6", cy: "19", r: "3" }),
|
||||||
|
svgEl("path", {
|
||||||
|
d: "M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15"
|
||||||
|
}),
|
||||||
|
svgEl("circle", { cx: "18", cy: "5", r: "3" })
|
||||||
|
]
|
||||||
|
),
|
||||||
|
E("span", {}, _("Routing sections"))
|
||||||
|
]
|
||||||
|
),
|
||||||
|
E(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
class: "tachyon_dashboard-page__sections-header__actions"
|
||||||
|
},
|
||||||
|
[
|
||||||
|
E(
|
||||||
|
"button",
|
||||||
|
{
|
||||||
|
type: "button",
|
||||||
|
id: "dashboard-test-all-sections-button",
|
||||||
|
class: "btn",
|
||||||
|
disabled: isTestingAllSections ? true : void 0,
|
||||||
|
click: () => {
|
||||||
|
void handleTestAllSections();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isTestingAllSections ? [
|
||||||
|
renderLoaderCircleIcon24(),
|
||||||
|
E("span", {}, _("Testing all sections..."))
|
||||||
|
] : E("span", {}, _("Test all sections"))
|
||||||
|
)
|
||||||
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
) : null;
|
) : null;
|
||||||
@@ -9826,13 +9861,53 @@ var styles = `
|
|||||||
opacity: 0.65;
|
opacity: 0.65;
|
||||||
}
|
}
|
||||||
|
|
||||||
#dashboard-test-all-sections-button {
|
.tachyon_dashboard-page__sections-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 16px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
padding: 0 2px;
|
||||||
|
gap: 12px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tachyon_dashboard-page__sections-header__title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
color: var(--text-color-high);
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.2px;
|
||||||
|
min-width: 0;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tachyon_dashboard-page__sections-header__title svg {
|
||||||
|
flex-shrink: 0;
|
||||||
|
opacity: 0.85;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tachyon_dashboard-page__sections-header__actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 6px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tachyon_dashboard-page .btn#dashboard-test-all-sections-button {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
padding: 4px 14px;
|
||||||
|
height: 30px;
|
||||||
|
min-height: 28px;
|
||||||
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#dashboard-test-all-sections-button svg {
|
#dashboard-test-all-sections-button svg {
|
||||||
@@ -9847,6 +9922,13 @@ var styles = `
|
|||||||
opacity: 0.65;
|
opacity: 0.65;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.tachyon_dashboard-page__sections-header {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tachyon_dashboard-page__outbound-grid {
|
.tachyon_dashboard-page__outbound-grid {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|||||||
@@ -4160,6 +4160,9 @@ msgstr "Правила маршрутизации"
|
|||||||
msgid "Routing section"
|
msgid "Routing section"
|
||||||
msgstr "Секция маршрутизации"
|
msgstr "Секция маршрутизации"
|
||||||
|
|
||||||
|
msgid "Routing sections"
|
||||||
|
msgstr "Секции маршрутизации"
|
||||||
|
|
||||||
msgid "Routing sections, rules and strategies"
|
msgid "Routing sections, rules and strategies"
|
||||||
msgstr "Секции маршрутизации, правила и стратегии"
|
msgstr "Секции маршрутизации, правила и стратегии"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user