refactor(PageHeaderActions): restructure actions layout and enhance button visibility for improved user interaction
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m52s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m52s
This commit is contained in:
@@ -436,6 +436,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
.header-actions .btn svg { width: 18px; height: 18px; }
|
.header-actions .btn svg { width: 18px; height: 18px; }
|
||||||
|
.header-actions .header-actions-right { flex-shrink: 0; }
|
||||||
|
|
||||||
/* Ensure dropdowns in header-actions overlay tables/cards correctly but stay below modals */
|
/* Ensure dropdowns in header-actions overlay tables/cards correctly but stay below modals */
|
||||||
.header-actions .dropdown-menu,
|
.header-actions .dropdown-menu,
|
||||||
|
|||||||
@@ -602,7 +602,7 @@ function ServerManager() {
|
|||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
actions={
|
actions={
|
||||||
<div className="d-flex flex-wrap align-items-center gap-2">
|
<>
|
||||||
<PageHeaderActions
|
<PageHeaderActions
|
||||||
loading={loading}
|
loading={loading}
|
||||||
onRefresh={handleRefreshAll}
|
onRefresh={handleRefreshAll}
|
||||||
@@ -612,7 +612,7 @@ function ServerManager() {
|
|||||||
onSave={handleSaveChanges}
|
onSave={handleSaveChanges}
|
||||||
disableSave={loading}
|
disableSave={loading}
|
||||||
/>
|
/>
|
||||||
<span className="vr d-none d-md-inline align-self-center" style={{ minHeight: '1.5rem' }} />
|
<div className="mt-3 d-flex flex-wrap align-items-center justify-content-end gap-2">
|
||||||
<div className="btn-group" role="group" aria-label="Переключение режимов">
|
<div className="btn-group" role="group" aria-label="Переключение режимов">
|
||||||
<button
|
<button
|
||||||
className={`btn ${activeTab === 'servers' ? 'btn-primary' : 'btn-outline-primary'}`}
|
className={`btn ${activeTab === 'servers' ? 'btn-primary' : 'btn-outline-primary'}`}
|
||||||
@@ -639,6 +639,7 @@ function ServerManager() {
|
|||||||
<IconPlus size={16} className="me-1" /> Добавить
|
<IconPlus size={16} className="me-1" /> Добавить
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import React from 'react'
|
|||||||
/**
|
/**
|
||||||
* Единый заголовок страницы в стиле Tabler UI.
|
* Единый заголовок страницы в стиле Tabler UI.
|
||||||
* Используется на всех страницах для одинакового UX.
|
* Используется на всех страницах для одинакового UX.
|
||||||
* Кнопки (actions) отображаются под названием страницы.
|
* Кнопки (actions) отображаются справа от названия страницы.
|
||||||
* @param {string} title - Заголовок страницы
|
* @param {string} title - Заголовок страницы
|
||||||
* @param {React.ReactNode} [icon] - Иконка слева от заголовка (например, <IconServer />)
|
* @param {React.ReactNode} [icon] - Иконка слева от заголовка (например, <IconServer />)
|
||||||
* @param {string} [pretitle] - Небольшая надпись над заголовком (page-pretitle)
|
* @param {string} [pretitle] - Небольшая надпись над заголовком (page-pretitle)
|
||||||
* @param {React.ReactNode} [meta] - Подзаголовок или мета-информация под заголовком
|
* @param {React.ReactNode} [meta] - Подзаголовок или мета-информация под заголовком
|
||||||
* @param {React.ReactNode} [actions] - Кнопки/действия под заголовком (btn-list, btn-group)
|
* @param {React.ReactNode} [actions] - Кнопки/действия справа в шапке (btn-list, btn-group)
|
||||||
*/
|
*/
|
||||||
function PageHeader({ title, icon, pretitle, actions, meta }) {
|
function PageHeader({ title, icon, pretitle, actions, meta }) {
|
||||||
return (
|
return (
|
||||||
@@ -26,15 +26,13 @@ function PageHeader({ title, icon, pretitle, actions, meta }) {
|
|||||||
<div className="text-muted small mt-1">{meta}</div>
|
<div className="text-muted small mt-1">{meta}</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{actions && (
|
{actions && (
|
||||||
<div className="row mt-2">
|
<div className="col-auto ms-auto d-print-none">
|
||||||
<div className="col d-print-none">
|
|
||||||
{actions}
|
{actions}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,9 +59,13 @@ function PageHeaderActions({
|
|||||||
{(onImport || onExport) && placeholderBtn(160)}
|
{(onImport || onExport) && placeholderBtn(160)}
|
||||||
{onClear && placeholderBtn(130)}
|
{onClear && placeholderBtn(130)}
|
||||||
{onClearCommunities && placeholderBtn(180)}
|
{onClearCommunities && placeholderBtn(180)}
|
||||||
|
</div>
|
||||||
|
{(onSave || onHistory) && (
|
||||||
|
<div className="header-actions-right ms-auto d-flex align-items-center gap-2">
|
||||||
{onSave && placeholderBtn(140)}
|
{onSave && placeholderBtn(140)}
|
||||||
{onHistory && placeholderBtn(110)}
|
{onHistory && placeholderBtn(110)}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -140,6 +144,9 @@ function PageHeaderActions({
|
|||||||
<IconEraser className="me-1" /> Очистить community
|
<IconEraser className="me-1" /> Очистить community
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
{(onSave || onHistory) && (
|
||||||
|
<div className="header-actions-right ms-auto d-flex align-items-center gap-2">
|
||||||
{onSave && (
|
{onSave && (
|
||||||
<button className="btn btn-primary" type="button" onClick={onSave} disabled={disableSave} title="Сохранить">
|
<button className="btn btn-primary" type="button" onClick={onSave} disabled={disableSave} title="Сохранить">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
@@ -155,7 +162,7 @@ function PageHeaderActions({
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{onHistory && (
|
{onHistory && (
|
||||||
<div className="btn-group">
|
<div className="btn-group d-none d-sm-inline-flex">
|
||||||
<button className="btn btn-outline-secondary" type="button" onClick={onHistory} title="История версий">История</button>
|
<button className="btn btn-outline-secondary" type="button" onClick={onHistory} title="История версий">История</button>
|
||||||
{lastModified && (
|
{lastModified && (
|
||||||
<button className="btn btn-outline-secondary" type="button" onClick={onHistory} title={`Последние изменения: ${formatDateTimeWithRelative(lastModified)}`}>
|
<button className="btn btn-outline-secondary" type="button" onClick={onHistory} title={`Последние изменения: ${formatDateTimeWithRelative(lastModified)}`}>
|
||||||
@@ -167,6 +174,7 @@ function PageHeaderActions({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
{/* Компактное меню для маленьких экранов */}
|
{/* Компактное меню для маленьких экранов */}
|
||||||
{secondaryButtons && (
|
{secondaryButtons && (
|
||||||
<div className="btn-group d-inline-flex d-sm-none">
|
<div className="btn-group d-inline-flex d-sm-none">
|
||||||
|
|||||||
Reference in New Issue
Block a user