# Детали

# Запись (row)

Страница детализации объекта, объединяет в себе несколько функций:

  • поля (fields) - поля модели/таблицы в виде списка, через запятую
  • действия (actions) - массив кнопок, для манипуляции состоянием объекта
  • вкладки (tabs) - массив вкладок, с перечнем полей, для отрисовки страницы

Ссылка на детальную страницу объекта из листинга, всегда присутствует в поле: details_url. Выглядит следующим образом: /api/v1/processing/view/{slug}/{id}/, но становится доступной только после регистрации в Конструкторе.

Для регистрации, необходимо добавить информацию в админке:

Конструктор -> Детали -> Добавить запись

Выбрать необходимый листинг и прописать необходимые поля модели/таблицы через запятую.

Внимание

Данные доступны только для чтения.

Значения Экстра - описаны в Object:Listing.

# Вывод Действий (actions)

Создаем Действия над объектом, предусмотренные бизнес логикой, в инлайне: "Действия в деталях записей".

Пример:

Активировать
Отменить
Опубликовать
Завершить

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

# Умное отображение действий

Создаем функцию, для вывода кнопок в интерфейсе:

CREATE OR REPLACE FUNCTION actions_model_list(action_name character, listing_id integer, user_organization_id integer, user_role character, user_id integer, user_language character, document_id character, params jsonb)
  RETURNS SETOF processing_listing_detail_actions
  LANGUAGE sql
AS $function$
    --
    -- Функция вывода кнопок в деталях, в зависимости от статуса объекта
    -- /admin/processing/detailpage/4/change/
    --
    
    SELECT
        a.*
    FROM
        processing_listing_detail_actions AS a
    JOIN
    processing_listing_details AS d
    ON a.detail_page_id = d.id
    WHERE
        d.listing_page_id = listing_id
      AND
          -- Доступ: Администратор и Координатор
          user_role IN ('ADMIN', 'COORDINATOR')
      AND
      (
          -- Статус: Черновик
          (
              (SELECT status_id FROM contest WHERE id = document_id::int) = 'DRAFT'
                AND 
              a.code IN ('MODEL_ACTIVATE', 'MODEL_REMOVE') -- Кнопки: Активировать, Отменить
          )
          OR
          -- Статус: Активировано

          (
              (SELECT status_id FROM contest WHERE id = document_id::int) = 'ACTIVE'
                AND 
              a.code IN ('MODEL_REMOVE', 'MODEL_PUBLISH') -- Кнопки: Опубликовать, Отменить
          )
          OR
          -- Статус: Опубликовано

          (
              (SELECT status_id FROM contest WHERE id = document_id::int) = 'PUBLISHED'
                AND 
              a.code IN ('MODEL_FINISH') -- Кнопки: Завершить
          )


        )
    ORDER BY a.order ASC
    ;
$function$

Таким образом, у нас на каждом этапе жизненного цикла объекта, будут лишь те кнопки, которые соответствуют статусу записи и отвечают требованиям ТЗ.

Внимание

Права доступа на детальную страницу неследуются из родительского листинга

# Действие

Пример функции, которая реализует небоходимую логику над объектом. Ссылка на вызов, имеется на странице детализации, в поле: action_url: /api/v1/processing/action/{slug}/{id}/view/{action-id}/

Пример:

CREATE OR REPLACE FUNCTION action_model_activate(action_name character, listing_id integer, user_organization_id integer, user_role character, user_id integer, user_language character, document_id character, params jsonb)
  RETURNS boolean
  LANGUAGE plpgsql
AS $function$
DECLARE
    --
    -- Действие: Активация
    --
    -- Валидация состояния данных, проверка роли пользователя и генерация необходимых записей.
    -- /admin/processing/detailpage/4/change/
    --

BEGIN
    -- Доступ: Админ и Координатор
    IF user_role IN ('ADMIN', 'COORDINATOR') THEN
        -- Проверка статуса: Черновик
        IF (SELECT status_id FROM {table} WHERE id = document_id::int) = 'DRAFT' THEN
    
            -- Проверка: Наличие требований
            IF (SELECT COUNT(*) FROM {table} WHERE {table}_id = document_id::int) = 0 THEN
                RAISE NOTICE '%', 'Не добавлены "Требования"!';
                RETURN FALSE;
            END IF;

            -- Обновление статуса объекта
            UPDATE
                {table}
            SET
                status_id = 'ACTIVE'
            WHERE
                id = document_id::int;

            -- История состояния родительского объекта
            INSERT INTO {table}_history ({table}_id, state_id, created_by_id, duration, is_rejected_to_this_state, created_at)
                VALUES(
                    document_id::int,
                    'ACTIVE',
                    user_id,
                    0,
                    FALSE,
                    NOW()
                );

            RETURN TRUE;
        ELSE
            RAISE NOTICE '%', 'Неверный статус!';
            RETURN FALSE;
        END IF;
    ELSE
        RAISE NOTICE '%', 'Ошибка доступа!';
        RETURN FALSE;
    END IF;

END;
$function$

При необходимости, если нужно добавить в ответ кастомные поля, можно использовать конструкцию в экшенах:

RAISE INFO '%', 'callback=REFRESH';

Результат будет:

{
    "result": True,
    "notices": [],
    "callback": "REFRESH",
}

# Вывод Вкладок (tabs)

Внимание

Не реализовано на фронте и является заглушкой.