From 459fc98bf1273e412516d3f806496c3f8fceb57c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=BB=D1=8C=D1=8F=20=D0=91=D1=80=D0=B0=D1=82=D1=81?= =?UTF-8?q?=D0=BA=D0=B8=D1=85?= Date: Sun, 28 Jun 2026 18:06:17 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D1=8C=20=D0=B2=D1=81=D0=B5=20=D0=BE=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D1=8C=20=D0=B3=D0=B8=D0=B1=D0=BA=D0=BE=20=D0=BD=D0=B0?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=B0=D0=B8=D0=B2=D0=B0=D1=82=D1=8C.=20?= =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D1=8B=D0=B5=20=D1=82=D0=B8=D0=BF=D1=8B.=20=D0=A1?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD=D1=8B=20=D0=BF=D1=80=D0=B8=D0=BC?= =?UTF-8?q?=D0=B5=D1=80=D1=8B.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 79 ++- assets/analytics.svg | 1 + assets/api.svg | 1 + assets/calendar.svg | 1 + assets/chat.svg | 1 + assets/cicd.svg | 1 + assets/drive.svg | 1 + assets/forum.svg | 1 + assets/social.svg | 1 + assets/vault.svg | 1 + assets/video.svg | 1 + assets/vpn.svg | 1 + assets/wiki.svg | 1 + examples/flat/index.html | 178 ++++++- examples/flat/panel-data.json | 98 ++++ examples/flat/settings.json | 39 +- examples/full/index.html | 178 ++++++- examples/full/panel-data.json | 188 +++++++- examples/full/settings.json | 39 +- examples/mixed/index.html | 178 ++++++- examples/mixed/panel-data.json | 122 ++++- examples/mixed/settings.json | 39 +- examples/section-items/index.html | 178 ++++++- examples/section-items/panel-data.json | 140 +++++- examples/section-items/settings.json | 39 +- examples/shared/assets/analytics.svg | 1 + examples/shared/assets/api.svg | 1 + examples/shared/assets/calendar.svg | 1 + examples/shared/assets/chat.svg | 1 + examples/shared/assets/cicd.svg | 1 + examples/shared/assets/drive.svg | 1 + examples/shared/assets/forum.svg | 1 + examples/shared/assets/social.svg | 1 + examples/shared/assets/vault.svg | 1 + examples/shared/assets/video.svg | 1 + examples/shared/assets/vpn.svg | 1 + examples/shared/assets/wiki.svg | 1 + examples/shared/script.js | 635 ++++++++++++++++++++++--- examples/shared/styles.css | 387 +++++++++++---- index.html | 175 ++++++- panel-data.json | 108 +---- script.js | 635 ++++++++++++++++++++++--- settings-top-bar.example.json | 32 +- settings.json | 36 +- styles.css | 387 +++++++++++---- 45 files changed, 3387 insertions(+), 527 deletions(-) create mode 100644 assets/analytics.svg create mode 100644 assets/api.svg create mode 100644 assets/calendar.svg create mode 100644 assets/chat.svg create mode 100644 assets/cicd.svg create mode 100644 assets/drive.svg create mode 100644 assets/forum.svg create mode 100644 assets/social.svg create mode 100644 assets/vault.svg create mode 100644 assets/video.svg create mode 100644 assets/vpn.svg create mode 100644 assets/wiki.svg create mode 100644 examples/shared/assets/analytics.svg create mode 100644 examples/shared/assets/api.svg create mode 100644 examples/shared/assets/calendar.svg create mode 100644 examples/shared/assets/chat.svg create mode 100644 examples/shared/assets/cicd.svg create mode 100644 examples/shared/assets/drive.svg create mode 100644 examples/shared/assets/forum.svg create mode 100644 examples/shared/assets/social.svg create mode 100644 examples/shared/assets/vault.svg create mode 100644 examples/shared/assets/video.svg create mode 100644 examples/shared/assets/vpn.svg create mode 100644 examples/shared/assets/wiki.svg diff --git a/README.md b/README.md index 63ebd51..c7f1ebe 100644 --- a/README.md +++ b/README.md @@ -124,11 +124,32 @@ ecosystem/ "accent": "violet", "showNumbers": false, "showTreeTags": true, - "treeTwoColumn": false, + "showTreeType": false, + "treeMetaLayout": "inline", + "treeColumns": 2, "autoCollapseSearch": true, "sidebarWidth": 390, + "topBarHeight": 140, + "shellMaxWidth": 2800, + "sidebarMinWidth": 260, + "sidebarMaxWidth": 800, + "sidebarMaxWidthWide": 1400, + "treeSidebarBaseWidth": 420, + "treeSidebarColumnWidth": 120, + "topBarMinHeight": 80, + "topBarMaxHeight": 560, "searchPlaceholder": "Grafana, S3, журнал, сервер..." }, + "limits": { + "shellMaxWidth": { "min": 1200, "max": 3840 }, + "sidebarMinWidth": { "min": 200, "max": 480 }, + "sidebarMaxWidth": { "min": 400, "max": 1200 }, + "sidebarMaxWidthWide": { "min": 560, "max": 2000 }, + "treeSidebarBaseWidth": { "min": 280, "max": 720 }, + "treeSidebarColumnWidth": { "min": 60, "max": 200 }, + "topBarMinHeight": { "min": 64, "max": 240 }, + "topBarMaxHeight": { "min": 160, "max": 800 } + }, "features": { "allowNavLayoutChange": true, "allowSearch": true, @@ -136,6 +157,7 @@ ecosystem/ "allowShowNumbers": true, "allowTreeOptions": true, "allowSidebarResize": true, + "allowLayoutLimitsChange": true, "allowThemeChange": true, "allowAccentChange": true } @@ -144,7 +166,8 @@ ecosystem/ | `defaults` | Варианты | Описание | |------------|----------|----------| -| `navLayout` | `"sidebar"`, `"top"` | `"sidebar"` — дерево слева; `"top"` — шапка с названием и поиском, без дерева | +| `navLayout` | `"sidebar"`, `"top"` | `"sidebar"` — панель слева; `"top"` — шапка с названием и поиском | +| `showTree` | `true`, `false` | Показывать дерево навигации (в любом режиме макета) | | `theme` | `"dark"`, `"light"` | Стартовая цветовая тема | | `view` | `"cards"`, `"list"`, `"compact-cards"`, `"compact-list"` | Режим отображения каталога | | `accent` | `"violet"`, `"cyan"`, `"lime"`, `"amber"`, `"custom"` | Пресет акцента; при `"custom"` используются поля градиента ниже | @@ -152,26 +175,54 @@ ecosystem/ | `customAccentTo` | `#rrggbb` | Цвет «до» для `accent: "custom"` (по умолчанию `#22d3ee`) | | `customAccentAngle` | `0`–`360` | Угол градиента в градусах (по умолчанию `135`) | | `showNumbers` | `true`, `false` | Показывать номера разделов, подразделов и элементов | -| `showTreeTags` | `true`, `false` | Теги рядом с элементами в дереве (взаимоисключимо с `treeTwoColumn`) | -| `treeTwoColumn` | `true`, `false` | Элементы папок дерева в 2 колонки (взаимоисключимо с `showTreeTags`) | +| `showTreeTags` | `true`, `false` | Теги элементов в дереве (оформление как на карточках) | +| `showTreeType` | `true`, `false` | Подпись типа сервиса в дереве | +| `treeMetaLayout` | `"inline"`, `"stacked"` | Расположение тегов и типа: сбоку от названия или снизу | +| `treeColumns` | `1`–`6` (по умолчанию `2`) | Число колонок элементов внутри папок дерева | | `autoCollapseSearch` | `true`, `false` | При поиске сворачивать ветки дерева без совпадений | -| `sidebarWidth` | `260`–`560` (`760` при `treeTwoColumn: true`) | Ширина боковой панели в px; игнорируется при `navLayout: "top"` | +| `sidebarWidth` | `sidebarMinWidth`–`sidebarMaxWidth` (или `sidebarMaxWidthWide` при `treeColumns` > 1) | Текущая ширина бокового меню (drag-resize); при `navLayout: "top"` не применяется | +| `topBarHeight` | `topBarMinHeight`–`topBarMaxHeight` (до ~75% высоты окна) | Текущая высота верхней шапки (drag-resize); только при `navLayout: "top"` | +| `shellMaxWidth` | см. `limits.shellMaxWidth` | Максимальная ширина контейнера `.shell` (вся страница) | +| `sidebarMinWidth` | см. `limits.sidebarMinWidth` | Минимальная ширина бокового меню при drag-resize | +| `sidebarMaxWidth` | см. `limits.sidebarMaxWidth` | Максимальная ширина меню при `treeColumns: 1` | +| `sidebarMaxWidthWide` | см. `limits.sidebarMaxWidthWide` | Потолок ширины меню при нескольких колонках дерева | +| `treeSidebarBaseWidth` | см. `limits.treeSidebarBaseWidth` | База формулы ширины меню: `base + columns × step` | +| `treeSidebarColumnWidth` | см. `limits.treeSidebarColumnWidth` | Прирост ширины меню за каждую колонку дерева | +| `topBarMinHeight` | см. `limits.topBarMinHeight` | Минимальная высота шапки в режиме «Сверху» | +| `topBarMaxHeight` | см. `limits.topBarMaxHeight` | Максимальная высота шапки (также ограничена ~75% окна) | | `searchPlaceholder` | произвольная строка | Текст-подсказка в поле поиска | +| `limits` | Формат | Описание | +|----------|--------|----------| +| `shellMaxWidth` | `{ "min", "max" }` | Диапазон слайдера «Ширина контента» в ⚙ → Габариты | +| `sidebarMinWidth` | `{ "min", "max" }` | Диапазон «Меню: мин. ширина» | +| `sidebarMaxWidth` | `{ "min", "max" }` | Диапазон «Меню: макс. (1 кол.)» | +| `sidebarMaxWidthWide` | `{ "min", "max" }` | Диапазон «Меню: макс. (неск. кол.)» | +| `treeSidebarBaseWidth` | `{ "min", "max" }` | Диапазон «Дерево: база ширины» | +| `treeSidebarColumnWidth` | `{ "min", "max" }` | Диапазон «Дерево: ширина колонки» | +| `topBarMinHeight` | `{ "min", "max" }` | Диапазон «Шапка: мин. высота» | +| `topBarMaxHeight` | `{ "min", "max" }` | Диапазон «Шапка: макс. высота» | + +При `treeColumns > 1` фактический потолок ширины меню: `min(sidebarMaxWidthWide, treeSidebarBaseWidth + treeColumns × treeSidebarColumnWidth)`. + +`shellMaxWidth` автоматически не опускается ниже `sidebarMaxWidthWide + 320`, чтобы оставалось место для каталога. + | `features` | Варианты | Описание | |------------|----------|----------| | `allowNavLayoutChange` | `true`, `false` | Переключатель «Сбоку / Сверху» | +| `allowShowTreeChange` | `true`, `false` | Показ/скрытие дерева и кнопка «Скрыть дерево» в панели | | `allowSearch` | `true`, `false` | Поле поиска | | `allowViewChange` | `true`, `false` | Режимы каталога | | `allowShowNumbers` | `true`, `false` | Нумерация | -| `allowTreeOptions` | `true`, `false` | Теги, 2 колонки, авто-раскрытие дерева | -| `allowSidebarResize` | `true`, `false` | Drag-resize боковой панели | +| `allowTreeOptions` | `true`, `false` | Колонки, теги, тип, расположение мета, авто-раскрытие дерева | +| `allowSidebarResize` | `true`, `false` | Drag-resize боковой панели (ширина) или верхней шапки (высота) | +| `allowLayoutLimitsChange` | `true`, `false` | Раздел ⚙ «Габариты»: лимиты ширины контента и навигации | | `allowThemeChange` | `true`, `false` | Светлая / тёмная тема | | `allowAccentChange` | `true`, `false` | Пресеты и свой градиент | Пользовательские изменения сохраняются в `localStorage`, но заблокированные `features` всегда возвращаются к `defaults`. -Пример пресета «только шапка»: [`settings-top-bar.example.json`](settings-top-bar.example.json) — `navLayout: "top"`, дерево и resize отключены. +Пример пресета «шапка сверху»: [`settings-top-bar.example.json`](settings-top-bar.example.json) — `navLayout: "top"`, дерево по умолчанию скрыто (`showTree: false`), но его можно включить. ### Форматы иерархии @@ -282,7 +333,7 @@ npx serve . Базовые типы заданы в `script.js` (`defaultServiceMeta`): -`ceph`, `cloudbeaver`, `config`, `gitea`, `grafana`, `ipmi`, `kubernetes`, `ldap`, `messages`, `opensearch`, `postgresql`, `prometheus`, `rabbitmq`, `redmine`, `rules`, `xpath`, `xmpp` +`analytics`, `api`, `calendar`, `ceph`, `chat`, `cicd`, `cloudbeaver`, `config`, `drive`, `forum`, `gitea`, `grafana`, `ipmi`, `kubernetes`, `ldap`, `messages`, `opensearch`, `postgresql`, `prometheus`, `rabbitmq`, `redmine`, `rules`, `social`, `vault`, `video`, `vpn`, `wiki`, `xpath`, `xmpp` Каждый тип имеет собственную SVG в `assets/` (например, `postgresql.svg`, `cloudbeaver.svg`). Иконка показывается на карточке каталога и в дереве навигации. @@ -329,14 +380,18 @@ Popup сгруппирован по разделам. Доступные бло | Раздел | Настройки | |--------|-----------| -| **Макет** | Панель навигации: **Сбоку** (дерево + поиск) или **Сверху** (только название и поиск) | +| **Макет** | **Сбоку** / **Сверху**; при «Сбоку» — toggle «Показывать дерево» и кнопка «Скрыть/Показать дерево» в панели | | **Каталог** | Вид карточек, нумерация | -| **Дерево** | Теги, 2 колонки, авто-раскрытие поиска (только при `navLayout: sidebar`) | +| **Дерево** | Теги, 2 колонки, авто-раскрытие (при `showTree: true`; 2 колонки — только «Сбоку») | | **Оформление** | Тема, акцент, свой градиент | ### Режим «Сверху» -Компактная шапка над каталогом: заголовок панели, поиск и ⚙. Дерево навигации скрыто — переход только через карточки каталога. Подходит для простых порталов и когда дерево избыточно. +Компактная шапка: заголовок, поиск и ⚙. Дерево по умолчанию скрыто, но его можно включить (`showTree: true`) — оно появится под шапкой на всю ширину. + +### Скрытие дерева + +Дерево управляется отдельно от макета (`showTree`). Переключение — в ⚙ → **Макет** или кнопкой **Скрыть/Показать дерево** под поиском. ### Свой градиент diff --git a/assets/analytics.svg b/assets/analytics.svg new file mode 100644 index 0000000..78ef5b5 --- /dev/null +++ b/assets/analytics.svg @@ -0,0 +1 @@ + diff --git a/assets/api.svg b/assets/api.svg new file mode 100644 index 0000000..893233a --- /dev/null +++ b/assets/api.svg @@ -0,0 +1 @@ + diff --git a/assets/calendar.svg b/assets/calendar.svg new file mode 100644 index 0000000..c47f8fe --- /dev/null +++ b/assets/calendar.svg @@ -0,0 +1 @@ + diff --git a/assets/chat.svg b/assets/chat.svg new file mode 100644 index 0000000..69dd009 --- /dev/null +++ b/assets/chat.svg @@ -0,0 +1 @@ + diff --git a/assets/cicd.svg b/assets/cicd.svg new file mode 100644 index 0000000..6f510ad --- /dev/null +++ b/assets/cicd.svg @@ -0,0 +1 @@ + diff --git a/assets/drive.svg b/assets/drive.svg new file mode 100644 index 0000000..8ebbff8 --- /dev/null +++ b/assets/drive.svg @@ -0,0 +1 @@ + diff --git a/assets/forum.svg b/assets/forum.svg new file mode 100644 index 0000000..1688d2d --- /dev/null +++ b/assets/forum.svg @@ -0,0 +1 @@ + diff --git a/assets/social.svg b/assets/social.svg new file mode 100644 index 0000000..fba41d6 --- /dev/null +++ b/assets/social.svg @@ -0,0 +1 @@ + diff --git a/assets/vault.svg b/assets/vault.svg new file mode 100644 index 0000000..14118fa --- /dev/null +++ b/assets/vault.svg @@ -0,0 +1 @@ + diff --git a/assets/video.svg b/assets/video.svg new file mode 100644 index 0000000..2452348 --- /dev/null +++ b/assets/video.svg @@ -0,0 +1 @@ + diff --git a/assets/vpn.svg b/assets/vpn.svg new file mode 100644 index 0000000..596c257 --- /dev/null +++ b/assets/vpn.svg @@ -0,0 +1 @@ + diff --git a/assets/wiki.svg b/assets/wiki.svg new file mode 100644 index 0000000..2ee7a0b --- /dev/null +++ b/assets/wiki.svg @@ -0,0 +1 @@ + diff --git a/examples/flat/index.html b/examples/flat/index.html index 2a6f59d..4d80fc9 100644 --- a/examples/flat/index.html +++ b/examples/flat/index.html @@ -5,9 +5,9 @@ - Пример: плоский список + Панель экосистемы -

Пример: плоский список

+

Панель экосистемы