Панель экосистемы — лёгкая стартовая страница для быстрого доступа к внутренним сервисам. Древовидная навигация, каталог карточек, поиск, 4 режима отображения, светлая/тёмная тема, настраиваемые узоры и экспорт настроек. Данные и пресеты — через JSON, состояние UI — в localStorage.
Go to file
2026-06-28 18:18:42 +03:00
assets first commit 2026-06-28 18:18:35 +03:00
examples более гибкая архитектура размещения элементов с примерами и документацией 2026-06-28 18:18:42 +03:00
index.html более гибкая архитектура размещения элементов с примерами и документацией 2026-06-28 18:18:42 +03:00
panel-data-flat.example.json более гибкая архитектура размещения элементов с примерами и документацией 2026-06-28 18:18:42 +03:00
panel-data-full.example.json более гибкая архитектура размещения элементов с примерами и документацией 2026-06-28 18:18:42 +03:00
panel-data-mixed.example.json более гибкая архитектура размещения элементов с примерами и документацией 2026-06-28 18:18:42 +03:00
panel-data-section-items.example.json более гибкая архитектура размещения элементов с примерами и документацией 2026-06-28 18:18:42 +03:00
panel-data.json вынесение настроек в отдельный файл, добавление readme 2026-06-28 18:18:41 +03:00
README.md более гибкая архитектура размещения элементов с примерами и документацией 2026-06-28 18:18:42 +03:00
script.js более гибкая архитектура размещения элементов с примерами и документацией 2026-06-28 18:18:42 +03:00
settings.json вынесение настроек в отдельный файл, добавление readme 2026-06-28 18:18:41 +03:00
styles.css более гибкая архитектура размещения элементов с примерами и документацией 2026-06-28 18:18:42 +03:00

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

Статическая навигационная панель для быстрого доступа к сервисам инфраструктуры. Поддерживает гибкую иерархию данных, поиск, дерево навигации, несколько режимов отображения и настройку внешнего вида.

Стек: HTML, CSS, vanilla JavaScript. Без сборщиков и фреймворков.

Оглавление

Возможности

  • Древовидная навигация слева в стиле файлового менеджера
  • Каталог карточек справа с collapsible-разделами
  • Поиск по названию, тегам, типу сервиса и родительским разделам
  • 4 режима отображения: плитки, список, компактные плитки, компактный список
  • Темы: светлая / тёмная, 4 пресета акцента + свой градиент
  • Настройки через popup (иконка ⚙)
  • Изменяемая ширина бокового меню (drag)
  • Сохранение состояния в localStorage (настройки UI, раскрытие веток)
  • Конфигурация через JSON — локальный объект или загрузка по URL
  • Гибкая иерархия: полная вложенность, раздел без подраздела, плоский список

Быстрый старт

Панель использует fetch, поэтому её нужно открывать через HTTP-сервер, а не напрямую как file://.

cd ecosystem
npx serve .

Открой в браузере адрес, который покажет сервер (обычно http://localhost:3000).

Структура проекта

ecosystem/
├── index.html                              # Разметка страницы
├── styles.css                              # Стили, темы, адаптив
├── script.js                               # Логика, рендер, примеры структур
├── settings.json                           # Источник данных (URL или inline)
├── panel-data.json                         # Данные навигации (рабочий файл)
├── examples/                               # Готовые демо-страницы (см. examples/README.md)
│   ├── index.html                          # Оглавление примеров
│   ├── shared/                             # styles, script, assets для демо
│   ├── full/                               # section → group → item
│   ├── section-items/                      # section → item
│   ├── flat/                               # плоский items[]
│   └── mixed/                              # items + groups
├── panel-data-full.example.json            # JSON-сниппет (без страницы)
├── assets/                                 # SVG-иконки сервисов
└── README.md

Конфигурация

settings.json

Указывает, откуда загружать данные панели.

Вариант 1 — загрузка из файла или URL:

{
  "dataUrl": "./panel-data.json"
}

Можно указать внешний адрес или любой из example-файлов:

{
  "dataUrl": "./panel-data-flat.example.json"
}

Вариант 2 — inline-объект в том же файле:

{
  "dataUrl": "",
  "data": {
    "title": "Заголовок панели",
    "sections": []
  }
}

Если dataUrl не пустой, он имеет приоритет над полем data.

При ошибке загрузки или невалидном JSON на странице показывается экран с описанием проблемы.

Форматы иерархии

Панель поддерживает три базовых формата. Старый section → group → item работает без изменений.

Формат Структура Дерево Каталог
Полная sections[].groups[].items[] раздел → подраздел → файлы collapsible разделы и подразделы
Раздел → item sections[].items[] раздел → файлы карточки внутри раздела
Плоский список корневой items[] плоский список файлов только сетка карточек
Смешанный sections[].items[] + groups[] прямые файлы, затем подразделы прямые карточки, затем подразделы

Минимум данных: корень должен содержать sections или items. Каждый раздел — groups или items. Каждый элемент — title и type.

Схема panel-data

Абстрактная структура файла данных (без привязки к конкретным сервисам):

{
  "title": "<заголовок панели>",
  "sections": [
    {
      "id": "<slug-раздела>",
      "number": "<опционально>",
      "title": "<название раздела>",
      "description": "<опционально>",
      "items": [
        {
          "id": "<стабильный-ключ>",
          "number": "<опционально>",
          "title": "<название>",
          "type": "<ключ из serviceMeta>",
          "tags": ["<тег>"],
          "url": "<ссылка>"
        }
      ],
      "groups": [
        {
          "id": "<slug-подраздела>",
          "number": "<опционально>",
          "title": "<название подраздела>",
          "description": "<опционально>",
          "items": ["<элементы — та же форма>"]
        }
      ]
    }
  ],
  "items": ["<альтернатива sections: плоский список>"],
  "serviceMeta": {
    "<type-key>": {
      "label": "<подпись типа>",
      "icon": "assets/<иконка>.svg"
    }
  }
}

Используй либо sections, либо корневой items. Внутри раздела — либо groups, либо items, либо оба.

Поля данных

Уровень Поля Описание
Корень title Заголовок панели (sidebar + <title>)
sections Массив разделов (если нет корневого items)
items Плоский список без разделов
serviceMeta Дополнительные или переопределённые типы сервисов
section id, title Обязательные идентификатор и название
number, description Опционально
groups, items Хотя бы одно из двух
group id, title, items Подраздел с элементами
number, description Опционально
item title, type Обязательные название и тип
url Ссылка; "#" — заглушка
tags Массив строк для поиска
id Стабильный ключ (DOM, фокус из дерева)
number Отображаемый номер
  • type — ключ из встроенного defaultServiceMeta или из serviceMeta в JSON
  • id элемента нужен, если нет number — иначе ключ генерируется автоматически

Примеры данных

Готовые демо-страницы — в папке examples/. Корневые panel-data-*.example.json — те же структуры в виде JSON-сниппетов.

Готовые демо-страницы (examples/)

Каждый пример — отдельная страница с index.html, settings.json и panel-data.json. Общие ресурсы в examples/shared/.

cd examples
npx serve .
Путь Формат
/ оглавление примеров
/full/ section → group → item
/section-items/ section → item
/flat/ плоский items[]
/mixed/ items + groups в разделе

Подробнее: examples/README.md.

Типы сервисов (serviceMeta)

Базовые типы заданы в script.js (defaultServiceMeta):

ceph, cloudbeaver, config, gitea, grafana, ipmi, kubernetes, ldap, messages, opensearch, postgresql, prometheus, rabbitmq, redmine, rules, xpath, xmpp

Переопределение или добавление типов в JSON:

{
  "serviceMeta": {
    "my-type": {
      "label": "Подпись",
      "icon": "assets/config.svg"
    }
  }
}

Рекомендуемые типы сервисов

Популярные type, которые можно добавить в serviceMeta (иконки — переиспользовать из assets/):

Категория Типы (type) Комментарий
Прокси / балансировка nginx, traefik reverse proxy, ingress
Контейнеры docker, portainer, argocd runtime, UI, GitOps
CI/CD jenkins, gitlab, harbor сборка, репозиторий, registry
Базы данных mysql, mongodb, redis рядом с уже имеющимися postgresql, opensearch
Очереди / стриминг kafka аналог rabbitmq
Мониторинг / логи loki, zabbix, sentry логи, метрики, ошибки
Безопасность / IAM vault, keycloak, consul секреты, SSO, service mesh
Поиск elasticsearch, sonarqube полнотекст, качество кода
Хранилище minio S3-совместимое
IaC terraform инфраструктура как код
Трекеры jira задачи, рядом с redmine

Чтобы подключить тип:

  1. Добавь запись в serviceMeta вашего JSON или в defaultServiceMeta в script.js
  2. При необходимости положи отдельную SVG в assets/
  3. Укажи "type": "nginx" (и т.д.) в элементах

Настройки интерфейса (⚙)

Доступны в popup-окне и сохраняются в localStorage (ecosystem-panel-preferences):

Настройка Описание
Тема Светлая / тёмная
Вид Плитки, список, компакт плитки, компакт список
Нумерация Показывать номера разделов, подразделов и элементов
Теги дерева Поисковые теги рядом с элементами в дереве
2 колонки в дереве Элементы папок в 2 колонки (взаимоисключимо с тегами)
Авто раскрывать поиск При поиске сворачивать ветки без совпадений
Акцент violet, cyan, lime, amber или свой градиент

Свой градиент

Кнопка «Свой» открывает настройки:

  • угол (0–360°)
  • цвет «от» и «до»

Значения сохраняются в localStorage.

Поведение интерфейса

Поиск

Фильтрует каталог и подсвечивает совпадения в дереве и карточках. Ищет по:

  • названию элемента
  • номеру
  • тегам
  • типу сервиса
  • названиям родительских разделов

Дерево навигации

  • Клик по папке — раскрытие/сворачивание
  • Клик по названию — прокрутка к элементу в каталоге
  • Состояние раскрытия сохраняется отдельно для дерева и контента (ecosystem-panel-collapse-state)

Адаптив

  • Touch-устройства (pointer: coarse / hover: none): stacked-layout, меню сверху
  • Мышь (pointer: fine + hover: hover): sidebar + resizer + каталог в колонках
  • 2 колонки в дереве на touch: в portrait или при ширине от 520px

Ширина layout

  • Обычный режим: max 1560px, sidebar до 560px
  • Режим «2 колонки в дереве»: max 1920px, sidebar до 760px

localStorage

Ключ Содержимое
ecosystem-panel-preferences Тема, акцент, вид, ширина sidebar, toggle-настройки
ecosystem-panel-collapse-state Раскрытые/свернутые ветки дерева и каталога

Разработка

Добавить элемент

  1. Открой panel-data.json (или свой JSON из dataUrl)
  2. Найди нужный раздел / подраздел или добавь в items / корневой items
  3. Добавь объект с полями title, type, при необходимости tags, url, id, number
  4. Обнови страницу

Добавить иконку и тип

  1. Положи SVG в assets/ (или переиспользуй существующую)
  2. Зарегистрируй тип в serviceMeta JSON или в defaultServiceMeta в script.js

Внешний источник данных

{
  "dataUrl": "https://your-server/panel-data.json"
}

Убедись, что сервер отдаёт Content-Type: application/json и разрешает CORS при другом домене.

Ограничения

  • Требуется HTTP-сервер (fetch не работает с file://)
  • Внешний dataUrl должен быть доступен по CORS
  • Настройки UI хранятся локально в браузере и не синхронизируются между устройствами

Лицензия

Приватный проект. Используй и изменяй по своему усмотрению.