Перейти к содержанию

Порталы — Администрирование

Обзор

Домен portal охватывает настройку портальных страниц, блоков, фильтров, JS/CSS includes и прав доступа. Администрирование использует:

  • Кастомная SPA-страница -- 1 форма (порталы) -- зарегистрирована в дереве автоадминки, но открывает собственную SPA-страницу
  • Admin API -- 10+ контроллеров (управление порталами, блоками, фильтрами, includes, правами)

Механизмы администрирования

Кастомная SPA-страница (в дереве автоадминки)

Alias формы Название Url Таблица БД Папка
portals Порталы /administration/portals/editor dbo.PortalGridTemplates Пользовательский интерфейс

Admin API контроллеры

Контроллер Маршрут Методы Назначение
PortalAdminController /api/admin/portals GET, POST, PUT, DELETE Список и базовая конфигурация порталов
PortalBlocksAdminController /api/admin/portals/blocks GET, POST, PUT, DELETE Настройки блоков
PortalBlockFiltersController /api/admin/portals/blocks/filters GET, POST, PUT, DELETE Фильтры блоков
PortalIncludesController /api/admin/portals/{portalId}/includes GET, POST, PUT, DELETE Подключаемые JS/CSS includes
PortalViewGroupsController /api/portals/{portalId}/view/groups GET, POST, DELETE Ограничение просмотра по группам

Подробная спецификация эндпоинтов -- см. backend.md.

Управление портальными страницами

Создание и редактирование

Портальная страница служит для размещения портальных блоков (виджетов). В отличие от портала, страницы подчиняются законам адаптивной верстки -- их поведение определяется способностью менять ширину/высоту и порядок следования для наилучшего заполнения пространства.

Создание: кнопка «Создать портал» → ввести название → ОК.

Меню управления страницей:

Кнопка Описание
Создать портал Новая портальная страница
Создать виджет Новый виджет
Создать раздел Раздел для группировки виджетов (тематический: СЭД, Маркетинг, ServiceDesk и т.п.)
Переименовать Переименовать портал
Дизайнер Выбрать режим верстки: Flex, Dashboard, CSS Grid, Board
Настроить вставки (js и css) Редактор JS/CSS инклудов для конкретного портала
Доступ Ограничение видимости портала по группам пользователей
Удалить Удалить портальную страницу
Добавить в избранное Добавить ссылку на портал в блок «Избранное» для выбранных пользователей

⚠️ Порталы в дизайне Flex и в дизайне Dashboard/CSS Grid имеют разный синтаксис адресной строки. Если портал был добавлен в Избранное, а потом режим отображения изменился -- нужно удалить прежнюю ссылку и добавить новую.

Стартовая страница

Чтобы портальная страница отображалась при входе в систему и при нажатии на логотип -- в «Общих настройках приложения» (sys_general_settings) в параметре «Стартовая страница» указать ссылку на портальную страницу (1 -- это ID портальной страницы).

Разделы виджетов

При создании виджета указывается его принадлежность одному или нескольким разделам. Разделы нужны для организации и удобного поиска. На любой портал можно добавить виджеты из любых разделов. Виджет без раздела отображается в разделе «Без раздела».

⚠️ При удалении раздела удаляются также все принадлежащие ему виджеты. Если виджет принадлежит нескольким разделам -- при удалении одного виджет сохраняется в остальных.

Различие «удалить с портала» и «полное удаление»

  • Удалить с портала -- виджет продолжает существовать и принадлежать своим разделам. В любой момент его можно снова добавить.
  • Полное удаление -- виджет перестает существовать, восстановить нельзя.

Конструкторы портальных страниц

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

Конструктор Dashboard

Портальная страница состоит из сетки, на которой расположены виджеты. Пользователи могут самостоятельно добавлять/удалять виджеты, менять местами и изменять размеры.

Кнопки управления:

Кнопка Действие
Добавить виджет Открыть окно добавления виджета из разделов
Сохранить Сохранить изменения
Сбросить пользовательские настройки Удалить все пользовательские overrides -- портал вернётся к административному виду
Скрыть/отобразить правую панель Переключение панели инструментов

Типы сетки (6):

Тип Описание
На весь экран Сетка занимает всю доступную область
Вертикальная прокрутка Прокрутка по вертикали
Горизонтальная прокрутка Прокрутка по горизонтали
Фиксированная Фиксированный размер
Фиксированная по вертикали Фиксирована по вертикали
Фиксированная по горизонтали Фиксирована по горизонтали

Параметры сетки:

Параметр Описание
Отступ (px) Расстояние между ячейками по горизонтали и вертикали
Внешний отступ Внешние отступы со всех сторон (размер = отступ между ячейками)
Ширина колонки (px) Ширина одной колонки
Высота строки (px) Высота одной строки
Макс. число колонок Максимальное число колонок (задаётся для каждого размера экрана)
Мин. число колонок Минимальное число колонок (задаётся для каждого размера экрана)
Поведение при перемещении «Менять местами» или «Толкать»

Параметры виджета на уровне сетки:

Параметр Описание
Перетаскивание Разрешить пользователям перетаскивать виджет
Изменение размеров Разрешить пользователям изменять размеры
Колонок макс./мин. Макс./мин. число колонок, которые может занимать виджет
Строк макс./мин. Макс./мин. число строк, которые может занимать виджет

⚠️ КРИТИЧНО: 5 контрольных точек адаптивности. Расположение виджетов настраивается отдельно для каждого размера экрана:

Точка Колонки по умолчанию
Не выбран --
xs 1 колонка
sm 2 колонки
md 4 колонки
lg 8 колонок
xl 12 колонок

⚠️ Если для одного из размеров экрана расположение виджетов не настроено -- на соответствующем устройстве виджеты НЕ будут отображаться. Для вертикального расположения экрана в большинстве случаев используется размер xs.

Конструктор CSS Grid (v2.266+)

Дизайнер CSS Grid используется для создания адаптивных портальных страниц с разнородными виджетами. В отличие от Dashboard и Board, CSS Grid позволяет комбинировать несколько стратегий в рамках одной страницы.

Кнопки управления: добавление блока, сохранение, удаление выделенного блока, перемещение блока на уровень выше/ниже.

Три типа блоков:

Тип Описание
Виджет Элемент с фиксированными размерами. Не растягивается. При изменении ширины экрана автоматически занимает место в плотной плиточной сетке. Виджет может быть только один.
Секция Занимает всю ширину строки, делит её на пропорциональные части. Шаблоны: 1/1, 1/full, full/1. В секцию можно добавить множество виджетов.
Контейнер Решает проблему динамического контента. Помещаются виджеты с ролевой видимостью. При скрытии виджета для конкретного пользователя в макете не образуется пустых мест.

Автоматическое расположение элементов:

Правило Описание
По строкам Элементы заполняются построчно (по умолчанию)
По колонкам Элементы заполняются по колонкам
По строкам + принудительное складывание Построчное с принудительным складыванием

Режимы заполнения пространства:

Режим Описание
По контенту Элементы распределяются без пустых областей (по умолчанию)
Пустотой Сохраняется пустое место до появления достаточного пространства для нового элемента

Размеры виджетов в CSS Grid:

Параметр Описание
Шаблон Предустановленный размер из дизайна конкретного виджета. Размеры, нарушающие вёрстку, в список не включаются.
Во всю ширину Виджет занимает всю ширину сетки. Параметр «Начать с новой строки» не применяется.
Кастом Произвольный размер. Допустимые значения колонок и строк: 2, 4, 6, 8, 12. Исключение: Баннер-кнопка в режиме Кастом -- высота 1 строка.

Таблица размеров 13 типов виджетов:

Тип виджета Доступные варианты Шаблоны (колонки × строки) По умолчанию
Кнопка-тикер Шаблон 2×2, 4×2, 2×4, 4×4 --
Баннер-кнопка Шаблон 1×2, 2×1, 2×2, 4×1, 4×2, 2×4, 4×4, 6×4, 4×6, 6×6 Из настроек виджета
Календарь New Шаблон 2×2, 4×2, 4×4 Из настроек виджета
Контакты Шаблон Из настроек виджета Из настроек виджета
Счётчики Шаблон Из настроек виджета Из настроек виджета
Список задач Шаблон 4×2, 4×4, 4×6, 6×4, 6×6 4×4
Избранное Шаблон 4×2, 4×4, 4×6, 6×4, 6×6 4×4
Новости Шаблон, Кастом 4×4, 6×6, 12×6, 12×8 12×8
Лента социальной сети Шаблон, Кастом 4×6, 6×8, 6×12, 8×12 --
Фильтр Во всю ширину -- --
Группа виджетов Кастом, Во всю ширину -- 4×4
Все остальные Кастом, Во всю ширину -- 4×4

Параметр «Начать с новой строки» -- доступен для виджетов с фиксированной шириной (не «во всю ширину»). При включении виджет всегда начинает отрисовываться с первой колонки строки сетки.

Адаптивные контрольные точки:

Ширина экрана Поведение
≥ 960px Стандартная сетка (12 колонок)
< 960px Ширина 6 колонок (для секций с шириной 6)
< 600px Ширина 2/4 колонки (для секций с шириной 2 или 4)

⚠️ Секции с шаблоном 1/1 на мобильных: при перестроении на малых экранах виджеты встают один под другим и каждый наследует высоту, заданную для всей секции.

Подробнее: portal-api-cookbook.md (таблица TypeId), academy-dashboards.md (краткие описания типов).

Конструктор Board

Board-дизайнер позволяет создавать портальные страницы с вкладками, в которых располагаются объединённые в секции дашборды.

Структура (боковая панель):

Элемент Описание
Портал Корневой элемент. Название редактируется. Недоступен для удаления.
Страницы Вкладки на уровне портала. Каждая отображает Board-портал. В списке недоступны порталы типа Flex и другие Dashboard-порталы.
Навигация Ссылки-«хлебные крошки» над заголовком портала. Несколько ссылок разделяются символом /. Поля: текст ссылки, URL.
Секции Встраивают Dashboard-порталы. Поля: название, фиксированная высота, показ заголовка, ссылка в заголовке, выбор Dashboard-портала, категория для создания задачи (добавляет кнопку «+»).
Группы Содержат секции и становятся внутренними вкладками. Имена групп НЕ видны на портале -- только в конструкторе. Удаление группы удаляет все её секции.

⚠️ Ограничения Board: - Виджет нельзя добавить напрямую в Board -- сначала добавить в Dashboard, потом встроить секцией. - Секцию нельзя переместить в группу -- нужно создать группу, затем создать секцию внутри. - Секции в группе не поддерживают «Категорию для создания задачи».

Flex-конструктор (LEGACY)

⚠️ LEGACY. Адаптивная верстка контейнерами. Основной элемент -- родительский контейнер с дочерними. Управление через контекстное меню (ПКМ). Не поддерживается в новом конструкторе. Упомянут для полноты -- новые порталы рекомендуется создавать в CSS Grid или Dashboard.

Типы портальных блоков (виджетов)

Полная таблица TypeId -- portal-api-cookbook.md. Ниже -- параметры каждого типа.

Блок поиска задач

Источник данных: смарт-фильтр или хранимая процедура.

Параметр Описание
Показывать счетчик Счетчик числа задач
Открывать по клику Задачи как ссылки
Фильтр задач Смарт-фильтр или хранимая процедура
Сортировка Поле + смарт-выражение + порядок + вывод пустых
Группировка Поле + выводимое значение (только для шаблона «Список»)
Шаблон Список (по умолчанию) или Карточки
Тип содержимого Задача (по умолчанию) или Новость
Категория для создания задачи Кнопка создания задачи в указанной категории
Кнопки управления Контекстные кнопки для действий над задачами

Параметры шаблона «Карточки»: ширина карточки (px), ID ДП картинки/видео/ссылки на видео, ID ДП для доп. текста/анонса, текст задачи для доп. текста, ID ДП ссылка, отображать теги, ID задачи, дата создания, срок, приоритет, заказчик, исполнитель, индикатор «Я ответственный», картинки, показывать только мои задачи, показывать все задачи.

⚠️ Если настроены кнопки управления с условиями видимости -- источник данных должен быть хранимая процедура (не смарт-фильтр).

Хранимая процедура: должна возвращать TaskID + любые колонки для кнопок управления. Параметры задач не нужны -- подтягиваются по TaskID. Принимает @UserID int, @XmlParam xml (необязательные).

Фильтрация данных не поддерживается.

Список задач (v2.262+)

Отображает список задач текущего пользователя из одного из 8 источников.

Источники:

Источник Описание
Задачи на сегодня Исполнитель = текущий пользователь, срок = сегодня (включая просроченные)
Активные задачи Исполнитель = текущий пользователь
Недавние задачи Последние задачи, с которыми взаимодействовал пользователь
Новые задачи из категории Задачи из выбранной категории, сортировка по дате создания
Отбор в категории Общий отбор или конкретная категория + смарт-отбор
Просроченные задачи Истекший срок, исполнитель = текущий пользователь
Задачи на подписи Запрошена подпись у текущего пользователя
Избранные задачи Добавленные в избранное

Параметры отображения (10): аватар задачи, текст задачи, номер задачи, название категории, статус, системные теги, приоритет, исполнители, заказчик, срок выполнения, количество подзадач.

Дополнительные настройки:

Параметр Описание
Отображать задач Количество от 1 до 6. По умолчанию -- зависит от размера блока
Показывать количество задач Синий тикер (общее число) + красный тикер (просроченные). Показываются только если задач больше, чем «Отображать задач». Для «Недавние задачи» недоступна
Сортировка Тип + поле (список формируется автоматически при выборе источника)

Фильтрация данных не поддерживается.

Таблица

Источник данных -- хранимая процедура (MSSQL) или SQL-функция (PostgreSQL). Поддержка смарт-кнопок для действий над строками.

Базовые настройки виджета

Параметр Описание
Хранимая процедура Название без схемы и квадратных скобок (рядом — кнопка перехода к редактированию SQL-запроса)
Автовысота строк Высота строк по содержимому
Автовысота таблицы Высота виджета по количеству строк
Автовысота дриллдауна Высота всплывающего окна детализации
Количество строк итогов ⚠️ Временно не работает с v2.256
Брать стиль строки из Колонка с описанием стиля форматирования (см. ниже «Стилизация»)
Брать ссылку для строки из Колонка со ссылкой (открыть в текущей вкладке)
Открывать в модальном окне Если включено — ссылка из «Брать ссылку из» открывается в модалке
Счетчик значений Выключено / Количество строк / Smart (смарт-выражение → скалярное int)
Цвет счётчика (только если Счётчик = Smart) info (синий), warning (оранжевый), default (серый), error (красный)
Отображать кнопку обновления По умолчанию выключено. Обновление учитывает текущие фильтры

Параметры хранимой процедуры

Сигнатура источника данных и процедуры детализации:

Параметр Тип Назначение
@XmlParam xml (readonly) Значения фильтра, привязанного к виджету
@DrillDownField varchar(max) = null Название столбца SQL, по которому кликнул пользователь (когда одна процедура обслуживает разные drilldown'ы)
@DrillDownParams varchar(max) = null История значений по уровням вложенной детализации (поддержка кнопки «Назад»)
@UserID int = null Пользователь, для которого формируются данные

⚠️ Все имена и значения регистрозависимые. taskId вместо taskID приведёт к ошибке. Для SPA-порталов первая буква имени параметра в SQL приходит строчной (в aspx — TaskId, в SPA — taskId).

⚠️ PostgreSQL: хранимые процедуры как источник табличных данных не поддерживаются. Используются SQL-функции (CREATE FUNCTION ... RETURNS TABLE/RECORD). Имя без [], точное соответствие имён и типов параметров. Параметры xml должны быть объявлены как xml, не text. Для PG детализация — отдельная функция; работа с фильтрами — через dbo.ssl_get_filter_param_by_name(xmlparam::xml, 'period') (вместо crm_repGetParams в MSSQL).

Настройки колонок

Каждая строка в таблице настроек — одна колонка. Первая (левая) колонка — кнопки (если настроены). Порядок меняется drag-and-drop'ом.

Базовые поля строки колонки:

Поле Назначение
Отображать Если выключено — колонка не показывается
Столбец SQL Имя колонки в результате процедуры
Имя Заголовок в UI
Ширина колонки В % от общей ширины таблицы
Колонка для функции DrillDown По какой колонке строится детализация. Взаимоисключающее с «Брать ссылку из» — одновременно нельзя

Общие настройки колонки (по кнопке «шестерёнка»):

Поле Эффект
Выравнивание текста По левому краю / по центру / по правому. Заголовок — по той же стороне
Название группы колонок Объединяет соседние колонки в общий заголовок верхнего уровня
Брать стилизацию из колонки Колонка с CSS-атрибутами для значения в данной колонке
Брать класс из колонки Колонка с CSS-классом
Режим фильтрации Отсутствует (default) / Обычный / Excel
Показывать нули Если выключено — 0 отображается как пустая ячейка
Вырезать теги Текст без html-тегов
Переносить текст на другую строку При заданной ширине: либо перенос по словам, либо обрезка
Длина дробной части Количество знаков после запятой для колонки типа Decimal. Значение от 0 до 10

Форматы вывода даты:

Формат Пример (для 20.04.2024)
DD.MM.YYYY 20.04.2024
DD.MM.YYYY, HH:mm:ss.sss 20.04.2024, 12:30:00
YYYY 2024
MMMM апрель
MMMM YYYY апрель 2024
DD 04
dddd суббота

Форматы числа:

Формат 1.71 1234.56
0 2 1235
0,0 2 1 235
0.0 1,7 1234,6
0,0.0 2 1 234,6
0.00 1,71 1234,56

Тип вывода в ячейке — флаг «Вывод информации»: Текст, Изображение, Индикатор, График. Можно комбинировать.

Изображение: колонка значения, ширина/высота в px/%, стиль (рамка, радиус), выравнивание.

Индикатор:

Поле Назначение
Тип индикатора Текст (по умолчанию) или Иконка (только набор Material; имя иконки — в колонке значения, со строчной буквы)
Колонка цвета Колонка с цветом фона в HEX (#XXXXXX)
Колонка значения Колонка со значением (текст или имя иконки)
Стиль Рамка, радиус закругления
Выравнивание Слева / справа от значения колонки

График: колонка возвращает JSON с типом (polyline / bar / pie), точками и стилизацией. Пример:

{ "type": "bar",
  "points": [
    {"x":1, "y":2, "color":"#FF0000"},
    {"x":2, "y":4, "color":"#00FF00"}
  ]
}

В SQL обычно формируется через FOR JSON PATH, WITHOUT_ARRAY_WRAPPER.

Стилизация строк и колонок

Поле в источнике данных, заданное в «Брать стиль строки из» / «Брать стилизацию из колонки», возвращает текстовое значение. Поддерживаемые типовые значения:

Значение Эффект
Default Без стиля
Success background-color: #dff0d8 (зелёный)
Info background-color: #d9edf7 (голубой)
Warning background-color: #fcf8e3 (жёлтый)
Danger background-color: #f2dede (розовый)
TotalsRow font-weight: bold
BackRed / BackGreen / BackBlue / BackYellow Фон pink / lightgreen / lightblue / gold
TextRed / TextGreen Цвет текста red / green

Произвольные значения: Color#XXXXXX (цвет текста), Background#XXXXXX (фон), HeightXXpx (высота строки). Несколько атрибутов перечисляются через запятую: Color#ff0000,Background#00ff00,Height40px.

Кнопки управления (smart-кнопки)

Настраиваются в блоке «Кнопки управления». Все кнопки выводятся в самой левой колонке.

Поле Назначение
Имя Текст на кнопке
Описание Tooltip при наведении
Иконка Путь к иконке (опционально)
JavaScript выражение (одно из двух) JS-скрипт по нажатию
Пакеты действий (одно из двух) Смарт-пакет по нажатию
URL Смарт-выражение → URL открываемой в модалке страницы (после выполнения пакета)
Колонка идентификатора (int) Имя колонки с ID объекта (например, TaskID). Доступно в смарте через «Идентификатор объекта»
Колонка видимости (bool) Колонка с признаком «показывать кнопку этому пользователю»
Колонка активности (bool) Колонка с признаком «кнопка активна»

⚠️ Для каждой кнопки задаётся либо JS, либо смарт-пакет — не оба одновременно.

⚠️ В абсолютном URL допустим только https://.

Объект event в JS-выражении:

{
  originalEvent: MouseEvent,           // стандартный объект
  data: any,                            // строка данных, к которой относится кнопка
  block: {
    reload:   () => void,               // перезагрузить блок
    freeze:   () => void,               // отключить все кнопки блока
    unfreeze: () => void                // снова включить
  }
}

При нажатии на любую кнопку все кнопки блока автоматически блокируются. Чтобы разблокировать, в скрипте нужно вызвать event.block.unfreeze() (например, через setTimeout).

К полям возвращаемой строки можно обращаться через event.data.<имя_колонки>, например event.data.isActive.

Параметры события «Нажатие на кнопку» (для смарт-пакета):

  • идентификатор объекта (из колонки идентификатора или ID строки),
  • строка с JSON-объектом всей строки,
  • ID кнопки,
  • параметры текущего пользователя.

Детализация (drill-down)

Настраивается per-column через «Колонка для функции DrillDown» + «Хранимая процедура» детализации. По клику на значение в ячейке открывается новый виджет, построенный процедурой детализации:

  • @DrillDownField — название колонки, по которой кликнули.
  • @DrillDownParams — полная история значений (поддержка вложенной детализации с кнопкой «Назад»).
  • Если процедура для детализации не указана, используется основная процедура виджета.
  • Уровни вложенности — неограниченны.

Фильтры (v2.265+)

Управляет данными на портале в других блоках. На одной странице может быть несколько независимых виджетов фильтров, но запрещены дубли с одинаковым набором.

Представление:

Режим Описание
Горизонтальный Ряд чипов. Активация сразу при изменении. Кнопка «Очистить» при активных фильтрах
Вертикальный Список полей в 1–4 колонках
Параметр Описание
Количество колонок 1–4 (только для вертикального режима)
Количество колонок в модальном окне Разметка окна «Все фильтры»
Закрепить сверху Фиксация в верхней зоне портала (только горизонтальный режим)

Параметры отдельных фильтров:

Параметр Описание
Видимость Всегда видимые / Только если выбрано значение / Всегда свернуто
Подсказка Tooltip по фильтру
Скрыть имя В горизонтальном режиме -- при выбранном значении показывать только значение без подписи
Колонка доступности Для смарт-набора: столбец с признаком доступности элемента
Ключ родителя Для статического набора: привязка к родительскому значению
Колонка родителя Для смарт-набора: столбец с ключом привязки к родительскому значению

Типы параметров фильтра:

Тип параметра Описание
Текст Строковое значение
Число Числовое значение. Можно задать длину дробной части (decimalPlaces) — количество знаков после запятой, от 0 до 10

Значения фильтров синхронизируются между связанными блоками (Фильтры, График, Таблица) в обе стороны.

Диаграмма Ганта

Параметр Описание
Хранимая процедура Обязательные колонки: Name (текст), Start (дата начала, not null), End (дата завершения, not null), ParentId (ID родителя), ID (номер задачи)
Масштаб Масштаб отображения в %
Открывать в модальном окне Клик на полоску → задача в модальном окне

Фильтрация данных не поддерживается.

Smart HTML

Самый гибкий портальный блок. Данные отбираются смарт-выражениями или источниками данных трёх типов, представление настраивается через шаблон Mustache.

Источники данных (3 типа):

Тип Описание
Произвольный Хранимая процедура, представление, функция или таблица БД. Параметры @UserId и @TaskID передаются автоматически.
Смарт-фильтр На основе смарт-фильтра + полей задач/ДП. Без программирования.
Скрипт (SmartScript) SmartScript (Lua/JS/Python). Должен вернуть RESULT -- массив объектов. Параметры: таймаут (сек), TTL (сек).

JS API: данные всех источников доступны через window.__smartHtmlData[blockId]. Доступ по алиасу. Объект __meta содержит тип, durationMs, cached, error для каждого источника.

⚠️ Если источники данных не настроены -- блок работает в прежнем режиме (смарт-выражения + mustache).

Mustache-шаблонизатор:

Конструкция Пример
Единичное значение {{smartXXX}} где XXX = ID смарт-выражения
Цикл (список) {{#smartXXX}}...{{/smartXXX}}
Условие {{#isComplainted}}Рекламация{{/isComplainted}}
Инвертированное условие {{^isComplainted}}Заявка{{/isComplainted}}

⚠️ Шаблонизатор не имеет средств форматирования данных (чисел, дат). Форматировать нужно в источнике данных (смарт-выражении, TSQL).

ve-link -- компонент для открытия контента в SPA без JS-вставок:

Что открывает Синтаксис
Зарегистрированную страницу <ve-link url="/dev/context-menu">{{url_to_open}}</ve-link>
Задачу <ve-link taskId="{{taskId}}">{{taskText}}</ve-link>
Портал <ve-link portalId="333">{{portal_name}}</ve-link>
Новость <ve-link newsId="{{taskId}}">{{news_title}}</ve-link>

Фильтрация данных не поддерживается.

Новости

Виджет отображает задачи из новостных категорий в виде большого блока, списка или карусели.

Тип данных: задачи новостной категории (определяется в настройках категории).

Стиль отображения:

Стиль Описание
Большой блок (по умолчанию) Одна главная новость с крупным изображением и карточки дополнительных
Список Компактный список новостей
Карусель Горизонтальная прокрутка новостей

Количество новостей: от 1 до 6.

Дополнительные настройки:

Параметр Описание Default
Отображать автора Показывать имя автора новости Выключено
Отображать рубрику Показывать рубрику новости Включено
Отображать аннотацию Показывать краткое описание Включено
Отображать дату публикации Показывать дату Выключено
Отображать счётчик лайков Показывать количество лайков Включено
Отображать счётчик просмотров Показывать количество просмотров Включено
Переход в ленту всех новостей Кнопка перехода к полной ленте Включено

Переход к полной ленте новостей открывает галерею с возможностью фильтрации по тегам.

Группа виджетов (v2.265+)

Блок с вкладками. Каждая вкладка -- отдельный ранее созданный виджет. Сохраняются все первоначальные настройки вкладок, включая фильтры.

Если вкладки не помещаются в одну строку -- появляется кнопка «Еще» с выпадающим списком.

Фильтрация данных не поддерживается.

Навигация (v2.266+)

Панель с элементами навигации в одном из трёх стилей: табы, чипы, хлебные крошки.

Параметр Описание
Тип навигации Табы / Чипы / Хлебные крошки
Закреплять в шапке при скролле Фиксация в верхней части экрана при вертикальной прокрутке

Элемент структуры:

Параметр Описание
Заголовок ссылки Название элемента
Портал Id ID портала для перехода
Порядок Порядок элемента
Доступно группам Видимость пункта для конкретных групп (независимо от доступности всего виджета)

⚠️ В хлебных крошках отображается полный путь до текущей страницы. Если промежуточный раздел не доступен пользователю по группе -- ссылка и разделитель скрываются.

Виджет работает как самостоятельный блок с кнопками и не содержит внутри другие виджеты или страницы.

Фильтрация данных не поддерживается.

Избранное (v2.263+)

Отображает список избранных объектов текущего пользователя.

Параметр Описание
Выбор содержимого Задачи / Пользователи / Пространства / Категории / Чаты / Отчеты / Ссылки
Порядок элементов По порядку в избранном / По дате добавления / По алфавиту

Фильтрация данных не поддерживается.

Кнопка-тикер (v2.261+)

Блок со счётчиком (может быть кликабельным), иконкой или кнопкой создания задачи.

Параметр Описание
Источник получения каунтера Смарт-выражение → числовое значение
Название иконки Из набора /spa/content-icons
Цвет иконки Основной / По умолчанию / кастомный
Цвет фона Brand / Global / Red / Yellow / Orange / Green / Cyan / Blue / Purple / Pink / Brown / Grey
Тон карточки Нет / Белый / Светлый / Нормальный / Темный
Badge style Текст / С фоном
Ссылка на блок Фиксированная или смарт-выражение. Отчеты/статьи пространства -- в модальном окне, URL -- в новом окне
Ссылка на создание задачи Формат: ewtask/{SubcatId}?ExtParamString=$Ext${ExtParamID}${Value}. Карточка создания -- в модальном окне
Без цвета, если каунтер ≤ При достижении значения фон меняет цвет

⚠️ Если задана ссылка на создание задачи -- вместо иконки отображается кнопка «+».

Фильтрация данных не поддерживается.

Тикеры (v2.262+)

Отображает несколько счётчиков в одном блоке (до 6). Отличается от «Кнопки-тикер» -- множество индикаторов одновременно.

Параметр Описание
Размер Малый / Средний / Смешанный
Количество счетчиков До 6
Текст ссылки блока Заголовок блока (кликабельный)
Ссылка блока Переход при клике на заголовок

Каждый счётчик:

Параметр Описание
Надпись Название счётчика
Тип значения Проценты / Штуки
Значение бейджа Числовое значение
Стиль бейджа Прямая метрика (+ = зелёный, − = красный) / Обратная метрика (+ = красный, − = зелёный) / Смарт (условие → success/warning/danger/default)
Значение Число из смарт-выражения
Единица измерения Текстовое обозначение
Подпись Текст под счётчиком

Фильтрация данных не поддерживается.

Баннер-кнопка (v2.261+)

Баннер на главном экране с настраиваемым оформлением.

Параметр Описание
Заголовок Фиксированный или смарт-выражение
Подзаголовок Фиксированный или смарт-выражение
Положение текста Верхний левый / Нижний левый / Нижний правый / Верхний правый
Положение иконки Не отображать / Противоположный угол / После текста / Угол, выравнивание по тексту
Цвет текста Чёрный / Белый / Всегда чёрный / Всегда белый
Пропорция 1:1 / 1:2 / 2:3
Ориентация Горизонталь / Вертикаль
Цвет фона Brand / Global / Red / Yellow / Orange / Green / Cyan / Blue / Purple / Pink / Brown / Grey
Тон фона White / Light / Color / Dark / Black
Url изображения Относительная ссылка (jpg, png)
Url видео Ссылка на видео (mp4)
Размер xs / sm / md / lg (управляет шрифтом и отступами)
Затемнение под текст None / White / Black / BackgroundColor
Ссылка на клик Фиксированная или смарт-выражение. Без префикса /spa/

⚠️ Относительные ссылки без /spa/. Правильно: /tasks/12345. С /spa/ → 404.

⚠️ Цвет текста динамически подстраивается под цвет фона и тон: на светлых фонах -- тёмный, на тёмных -- светлый.

Фильтрация данных не поддерживается.

Контакты (v2.262+)

Список контактов текущего пользователя. Быстрые действия: видеовызов, чат.

Параметр Описание
Вариант отображения Список / Карусель / Круги
Размер блока Малый / Средний / Большой
Размер контакта Малый / Средний / Большой / Очень большой
Содержание списка Недавние контакты / Звонки / Коллеги / Избранные контакты / Отдел орг. структуры / Отдел и все подчиненные / Смарт (UserID) / Смарт (пользователи с доп. инфо.)
ИД орг. структуры Для типов «Отдел»
Вторая строка Основная должность / Отдел / Тип недавнего / Статус / Дни рождения / Ближайшие отсутствия
Отображать занятость у аватара Календарная занятость + онлайн/офлайн

⚠️ Вторая строка не отображается при размере контакта «Малый» или «Большой».

Фильтрация данных не поддерживается.

Лента социальной сети

Отображает последние публикации из сообществ. Несколько лент = вкладки (одна лента = без вкладок).

Параметр Описание
Переход в раздел социальной сети Название виджета как ссылка на главную страницу соц. сетей
Название ленты Заголовок вкладки
Отображать количество непрочитанных Счётчик новых записей
Создание сообщения Поле для публикации новых постов (при наличии прав)
Источник ленты Главная лента / Раздел / Группы

⚠️ Количество постов зависит от высоты виджета. При слишком малой высоте ни один пост не будет показан.

⚠️ Создание публикаций соответствует правам доступа и настройкам каждой группы. Для автора/редактора/администратора/владельца -- всегда, для подписчика -- только если разрешено в настройках группы.

Фильтрация данных не поддерживается.

Календарь

Отображает данные в привязке к дате. Принцип настройки -- как Smart HTML: смарт-выражение + Mustache-шаблон.

Параметр Описание
Дата начала / окончания Период календаря (для тестирования)
Поле с датой Название поля типа «Дата» или «ДатаВремя» из смарт-выражения
Стили отображаемых дат Смарт-выражение → 2 колонки: дата + класс (success/warning/danger/default)
Шаблон Mustache-шаблон

Смарт-параметры: @dateFrom и @dateTo -- при первой загрузке = начало/конец текущего месяца, далее зависят от выбора пользователя.

Фильтрация данных не поддерживается.

Календарь New (v2.262+)

Соответствует календарю в профиле пользователя. Не используется для преднастроенного набора данных.

Параметр Описание
Размер Малый (2 ближайших события) / Средний (2 + 4 события в 2 колонки) / Большой (5 временных слотов, 2 колонки)
Набор данных Встречи / Срок задач (Ответственный исполнитель / Исполнитель / Заказчик) / Дата начала задач (Заказчик) / Дата завершения задач (Заказчик) / Напоминания / Подписи
Тип календаря Список / Хронологический две колонки (только для большого размера)

Фильтрация данных не поддерживается.

График (диаграмма)

Сводные данные в табличном или графическом виде. По умолчанию -- Apex Charts (ключ highCharts в custom-app-settings для HighCharts).

Источник данных: SQL-объект (хранимая процедура, view, таблица).

Поле Описание
SQL Объект Название процедуры/view/таблицы
Заголовок Текстовая колонка → ось X
Значения Числовая колонка → ось Y
Цвета HEX-коды или HTML-цвета
Колонка для Drilldown Колонка детализации
Группировать по Колонка группировки
Кол-во строк для игнорирования Итоговые строки, не отображаемые на графике

Типы диаграмм:

Тип Особенности
Линейная / Линейная (область) Отображать значения рядом с точками
Столбчатая / Столбчатая (горизонтальная) Сгруппировать столбцы, подписи столбцов
Секторная / Секторная без центра Значения вместо процентов, легенда рабочей области
Таблица Итого по таблице, текст итога
Воронка продаж ⚠️ Без агрегирования в источнике. Подписи, смещение справа
Линейная с накоплением / горизонтальная Обязательно заполнить «Группировать по»

Настройки блока:

Параметр Описание
Шаблон подсказки Формат highcharts: {series.name}, {point.name}, {point.x}, {point.y}, {point.percentage}, {point.total}
Цвет графика Из палитры или колонка SQL-объекта
Добавить график Несколько серий на одном графике (только SQL-объекты)
Показывать заголовки осей Названия осей
Показывать легенду Для секторных и воронки -- легенда, для линейных/столбчатых -- название
Открывать задачи по клику Список объектов для каждой области (не поддерживается для SQL View)
Тип шкалы Линейная / Логарифмическая / Авто логарифмическая
Мин./Макс. по оси X/Y Границы осей
Цена деления по оси X/Y ⚠️ Не работает для Apex Charts
Количество значений на оси Y ⚠️ Не работает для Apex Charts

⚠️ Не все типы графиков совместимы в одном блоке. Линейная + столбчатая -- совместимы. Линейная + секторная -- нет.

Меню

Произвольное количество кнопок с действиями (переход на страницу).

Параметр Описание
Текст ссылки* Название (обязательное). Текст или смарт-выражение
Css иконки Фрагмент CSS для форматирования индикатора
Путь к изображению Адрес файла с изображением
Ссылка Внутренняя (от /) или внешняя (http/https)
Открывать ссылку в Текущее окно / Модальное окно / Новая вкладка
Набор иконок material
Иконка из набора Название с маленькой буквы, слова через подчёркивание (calendar_today)

Фильтрация данных не поддерживается.

Новости

Задачи категории отображаются как публикации ленты.

⚠️ Задачи в статусах с типом «Начальный» не отображаются (например, статус «Новая»). Сначала подготовить новость → перевести в следующий статус → публикация.

Параметр Описание
Категория Категория с шаблоном «Новости» (статический шаблон в шаблонизации)
Шаблон (SPA) Карточки / 3 новости и главная / Объявления
Сортировать по доп.параметру ДП типа «Дата и время». Пустая дата = конец списка. Дата > текущей = не отображается
Направление сортировки По возрастанию / По убыванию
Не обрезать текст ⚠️ Только для устаревших порталов
Показывать заказчика ⚠️ Только для устаревших порталов
Показать счетчики Нравится / Комментарии / Просмотры

Поля шаблона новостей: Title, Annotation, FullText, Date, ImageAttachId, IsMain, Rubric, AuthorUser.

⚠️ Для категорий новостей рекомендуется включать «Не отображать системные комментарии» в основных настройках категории.

Фильтрация данных не поддерживается.

Паттерн: несколько блоков-отчётов с разными фильтрами

Частый сценарий: на портале нужно вывести однотипные графические виджеты для разных направлений/подразделений.

Подход: 1. Все виджеты имеют тип «Отчет» и вызывают один и тот же отчёт 2. В фильтре каждого виджета передаётся разное значение параметра:

{"27":{"name":"Direction","value":"3034","type":"Dropdown"}}
где 27 -- ID фильтра, 3034 -- ID направления. 3. Отчёт содержит диаграмму + два источника данных: таблица показателей и таблица цветовых настроек 4. Цветовая схема определяется в зависимости от значения параметра (@Direction) 5. Подвал отчёта с легендой отображается только на последнем блоке через событие AfterData:
private void ReportSummary1_AfterData(object sender, EventArgs e)
{
    string direction = ((String)Report.GetParameterValue("FilterDirection"));
    if (direction != "3032")
        ReportSummary1.Visible = false;
}

JS API порталов и портальных блоков

JS/CSS Includes

Создание вставки: описание → тип (js/css) → содержимое → сохранить.

Привязка: - К порталу -- вставка работает на всех страницах портала - К блоку -- вставка работает только в конкретном блоке

⚠️ Добавленные ранее вставки не будут корректно работать при переходе из старого МТФ/НТФ в новый SPA. Подробнее: js_migration_new_mtf.md.

Методы JS API для работы с порталами и портальными блоками описаны в js_syntax.md.

JS API портальных блоков

Основные методы для работы с портальными блоками из JS-вставок:

Метод Описание
portal.block(blockId) Получить объект портального блока
onLoaded Событие загрузки блока
refresh() Обновить данные блока
spaCommand Выполнить SPA-команду
fileViewer Открыть просмотрщик файлов
setFilters() Установить фильтры блока
filters() Получить текущие фильтры
freeze() / unfreeze() Блокировка/разблокировка рендера блока

Полный справочник методов -- js_syntax.md.

Ключевые настройки

Порталы (PortalGridTemplates)

Где настраивается: SPA-страница /administration/portals/editor (пункт portals в дереве автоадминки) / Admin API -> PortalAdminController Таблица БД: dbo.PortalGridTemplates

6 полей: страницы порталов и типы layout (dashboard, board, cssgrid).

Эффект в runtime: определяет набор доступных портальных страниц и их тип отображения.

Блоки порталов (PortalGridBlocks)

Где настраивается: Admin API -> PortalBlocksAdminController Таблица БД: dbo.PortalGridBlocks

Набор виджетов на портальной странице: тип блока, параметры, источник данных, позиционирование.

Группа полей Что контролирует
Тип блока Виджет (задачи, отчёт, HTML, iframe и т.д.)
Параметры блока Источник данных и конфигурация
Позиция, размер Расположение на странице

Эффект в runtime: данные блока загружаются через POST /api/portals/block/data/{blockId}.

Фильтры блоков

Где настраивается: Admin API -> PortalBlockFiltersController Таблицы БД: dbo.PortalGridBlocksFilters, dbo.PortalGridBlockFilters, dbo.PortalGridFilterParams, dbo.PortalGridFilterParamBlockValues

Фильтрация данных виджетов: параметры фильтров привязываются к блокам и определяют, какие данные отображаются.

Ключевые правила:

  1. На одной портальной странице может быть несколько независимых виджетов фильтров, но запрещены дубли с одинаковым набором фильтров.
  2. Значения фильтров синхронизируются между связанными блоками (Фильтры, График, Таблица) в обе стороны.
  3. Список параметров виджета строится из настройки фильтрации (filters_spa): что включено в фильтр, то доступно в виджете.

Параметры отображения виджета фильтров:

Параметр Что контролирует
Представление Режим: Горизонтальный (чипы) или Вертикальный (поля)
Количество колонок Число колонок для вертикального режима
Количество колонок в модальном окне Разметка окна Все фильтры/Еще фильтры

Параметры отдельных фильтров:

Параметр Что контролирует
Видимость Всегда видимые / Только если выбрано значение / Всегда свернуто
Подсказка Tooltip по фильтру (чип/поле)
Скрыть имя В горизонтальном режиме при выбранном значении показывать только значение без подписи
Колонка доступности Только для смарт-набора с заданными зависимостями. Имя столбца в результате смарт-выражения, содержащего признак доступности элемента. Бэкенд вычитывает эту колонку и включает значение в ответ (avalible на каждом элементе).
Ключ родителя Только для статического набора (Свой). Значение поля каждого элемента, по которому он привязывается к значению родительского параметра при каскадной зависимости.
Колонка родителя Только для смарт-набора. Имя столбца в результате смарт-выражения, содержащего ключ привязки к родительскому значению. Бэкенд вычитывает эту колонку и включает значение в ответ (parent на каждом элементе).

Каскадные выпадающие списки

Dropdown-параметр типа «Смарт-набор» может зависеть от другого параметра через настройку «Зависит от параметров»:

  1. При изменении значения в родительском параметре фронтенд вызывает POST /api/v10/filters/config/dropdown/items с otherValuesJson -- выбранным значением родителя.
  2. Смарт-выражение дочернего параметра получает это значение через @eventParam2 и возвращает отфильтрованный список.
  3. Если задана «Колонка родителя» -- бэкенд дополнительно вычитывает эту колонку из каждой строки результата смарт-выражения и включает её в ответ (поле parent).
  4. Если задана «Колонка доступности» -- бэкенд аналогично вычитывает её и включает в ответ (поле avalible), позволяя управлять доступностью элементов на стороне клиента.

Для статического набора каскад настраивается иначе: у каждого элемента вручную задаётся «Ключ родителя» -- значение из родительского параметра, при котором этот элемент доступен.

Эффект в runtime: - в горизонтальном режиме фильтр применяется сразу после изменения значения и закрытия редактора; - кнопка Очистить появляется только при наличии активных фильтров; - для свернутых фильтров используется модальное окно, на кнопке показывается счетчик выбранных значений.

Includes (JS/CSS)

Где настраивается: Admin API -> PortalIncludesController Таблицы БД: dbo.PortalIncludes, dbo.PortalBlockIncludes

Дополнительные JS/CSS файлы, влияющие на рендер и поведение портала или отдельного блока.

Права просмотра

Где настраивается: Admin API -> PortalViewGroupsController Таблица БД: dbo.PortalGridTemplateGroups

Ограничение видимости портала по группам пользователей.

Пользовательские layout-overrides

Таблица БД: dbo.PortalGridUserTemplates

Персональные настройки расположения блоков per-user. Перезаписывают дефолтный layout.

Типичные ошибки настройки

Симптом Причина Где проверить SQL-диагностика
Портал не виден части пользователей Ограничения по группам dbo.PortalGridTemplateGroups select * from dbo.PortalGridTemplateGroups where PortalGridTemplateId = {portalId}
Блок на странице пустой Некорректный конфиг блока или фильтры dbo.PortalGridBlocks, фильтры select * from dbo.PortalGridBlocks where PortalGridTemplateId = {portalId}
Фильтры не влияют на график/таблицу Блоки не связаны через общий filter-config или рассинхронизированы параметры Конфиг фильтров блока + набор параметров в фильтре (filters_spa) select * from dbo.PortalGridBlocksFilters where PortalGridBlockId = {blockId}
Пользователь не видит часть фильтров Параметр фильтра отмечен как Всегда свернуто / Только если выбрано значение Настройки параметров фильтра (PortalGridFilterParams) select * from dbo.PortalGridFilterParams where PortalGridFilterId = {filterId}
Над виджетом показывается старое название Name блока = заголовок виджета для пользователей, не внутреннее имя POST /api/portals/block/{blockId}/update с {"Name":"..."} select Name from dbo.PortalGridBlocks where Id = {blockId}
После изменений UI показывает старое Кэш snapshot в UI Фактическое сохранение select * from dbo.PortalGridBlocks where Id = {blockId}
Страница ломается после включения include Ошибка в JS/CSS include dbo.PortalIncludes select * from dbo.PortalIncludes where PortalGridTemplateId = {portalId}
Пользовательский override конфликтует с новым layout Старый PortalGridUserTemplates dbo.PortalGridUserTemplates select * from dbo.PortalGridUserTemplates where PortalGridTemplateId = {portalId} and UserId = {userId}

Работа с API порталов — ключевые правила

Детальный cookbook с примерами: portal-api-cookbook.md.

Создание блока

block_id = POST("/api/portals/block/add", {
    "Name": "Виджет",
    "TypeId": 33,              # SmartHtml
    "TemplateId": portal_id,   # Внимание: игнорируется при создании (баг)
    "GroupsIds": [1620],        # Обязательно, иначе блок не виден
    "ContextTypeId": 0,
    "IsEnabled": True
})

Advsets — контроллеры по типам блоков

Не все типы блоков имеют выделенный advsets-контроллер:

TypeId Тип Advsets-эндпоинт
33 SmartHtml POST /api/admin/portals/blocks/advsets/smart-html?blockId=N
21 Menu (Navigation) Настройки в TypeParams (JSON-строка внутри JSON-строки)
2 Subcat POST /api/admin/portals/blocks/advsets/subcat?blockId=N

SmartHtml — настройка шаблона

POST /api/admin/portals/blocks/advsets/smart-html?blockId={blockId}
{"template": "<div>...</div>", "smarts": ""}
# blockId — query parameter, не body!
# Ответ: 204 No Content

SmartHtml — двойное хранение шаблона: template хранится в TypeParams (legacy) и BlockTemplates (через advsets API). При обновлении через advsets обновляется BlockTemplates.

SmartHtml — источники данных (с 2.268 Скульптор)

В advsets добавлено поле dataSources — массив источников данных. Поддерживаются три типа:

POST /api/admin/portals/blocks/advsets/smart-html?blockId={blockId}
{
  "template": "...",
  "smarts": "",
  "dataSources": [
    {"alias": "myData", "type": "custom",      "sourceKey": "source_key"},
    {"alias": "tasks",  "type": "smartFilter", "filterId": 123, "fields": ["taskId","taskText","ep_42"]},
    {"alias": "kpi",    "type": "script",      "scriptId": 456, "ttl": 300, "timeout": 30}
  ]
}

Список системных полей для типа smartFilter:

GET /api/admin/portals/blocks/advsets/smart-html/smart-filter-fields

Данные всех источников записываются в window.__smartHtmlData[blockId] (по алиасу) до выполнения JS Include. Если dataSources пуст или отсутствует — поведение прежнее (обратная совместимость).

JS/CSS Includes

Создание:

POST("/api/includes/add", {
    "name": "Описание",    # при создании — "name"
    "type": 1,             # 1=Js, 2=Css, 3=JsUrl
    "content": "(function() { ... })()"
})  # → {"data": includeId}

Обновление:

POST(f"/api/includes/{includeId}/update", {
    "description": "Описание",  # при обновлении — "description" (не "name"!)
    "type": 1,
    "content": "(function() { ... })()"
})

Привязка к блоку:

POST /api/portals/block/{blockId}/includes/add?includeId={includeId}
# includeId — QUERY parameter, не body
# Требует пустой body {} — без body → 400

Типичные ошибки API порталов

Проблема Причина Решение
TemplateId игнорируется при создании Баг в CreatePortalBlock После создания: POST /api/portals/block/{id}/update с правильным TemplateId
Блок не виден пользователям Нет GroupsIds Всегда передавать GroupsIds: [1620]
Блок на портале, но не рендерится Блок не в mesh Добавить blockId в mesh JSON (формат в cookbook §4)
updateAdminTemplate → 500 Не все поля переданы (name=null) Передать ВСЕ поля: id, name, mesh, GridType, ShowHeader, ModuleId, dashboard, isFixedMode
Портал стал Flex (0) Забыли GridType: 2 Всегда передавать GridType: 2 (CssGrid)
Удалённый блок в mesh DELETE block не чистит mesh Вручную удалить запись из mesh JSON
GET /api/admin/portals/{id} → 405 Поддерживает только DELETE Читать портал: GET /app/v1.0/api/portal/template/{id}
addAdminTemplate дубль имени → 500 Сервер возвращает 500 (не 409) Проверить существующие порталы
addAdminTemplate — ответ без data Возвращает объект напрямую response['id'], не response['data']['id']
TypeParams — упрощённый формат → NullRef PUT /api/admin/portals/blocks/{id} пишет Key/Value Обновлять через POST /api/portals/block/{id}/type-params/update
name vs description для includes Разные имена одного и того же поля При создании — name. При обновлении — description
400 при привязке include Отправили без body Отправить пустой {} body
Include не выполняется в SmartHtml Привязан к порталу, а не к блоку Привязать к блоку: block/{blockId}/includes/add
Пустой виджет при SPA-навигации IIFE выполняется один раз MutationObserver + маркер data-*-init (паттерн в cookbook §5e)
Type: "JS" → ошибка Значение "Js" PascalCase "Js", "Css", "JsUrl" — не UPPERCASE
POST /api/includes → 404 Нет такого эндпоинта POST /api/includes/add (создание), /api/includes/{id}/update (обновление)

Связанные документы

  • docs/domains/portal/portal-api-cookbook.md -- практический cookbook с полными примерами
  • docs/domains/portal/backend.md -- backend-архитектура (контроллеры, сервисы, типы блоков)
  • docs/domains/portal/data-flow.md -- E2E диагностика (загрузка портала, данные блоков)
  • docs/domains/portal/academy-dashboards.md -- паттерны настройки дашбордов
  • docs/domains/portal/database.md -- схема БД (PortalGridTemplates, PortalGridBlocks, GridType)
  • docs/platform/backend/admin-architecture.md -- общая архитектура администрирования
  • docs/reference/database/dbadmin-forms-map.md -- карта всех форм автоадминки