Базовый CRUD в Admiral

Время прочтения — 10 минут
Содержание
При разработке админ-панелей одной из ключевых задач становится реализация удобного и надёжного механизма управления данными. CRUD (Create, Read, Update, Delete) в Admiral – это базовая функциональность, которая обеспечивает полный цикл работы с таблицами: от создания новых записей до их редактирования и удаления.
Грамотно реализованные CRUD-операции позволяют пользователям эффективно взаимодействовать с данными, повышая продуктивность и снижая количество ошибок при ручной работе с базой.
Для начала рассмотрим основные компоненты, которые понадобятся для реализации CRUD-интерфейса, а затем разберём их работу на конкретном примере.
Посмотреть, как это работает в интерфейсе, можно на демо-стенде: https://admiral.dev.family/base-crud

Типы полей

Admiral предоставляет множество полей для реализации CRUD-интерфейсов, позволяя гибко настраивать формы в зависимости от типа данных и бизнес-логики. Каждый тип поля ориентирован на определённый формат ввода: от простого текста и чисел до выбора связанных сущностей, загрузки файлов.
Ниже представлены одни из основных свойств:
  • TextInput – текстовое поле для ввода текста;
  • SelectInput – поле с выбором значений(в том числе множественное);
  • FilePictureInput – поле для загрузки файлов, также позволяет добавлять несколько файлов;
  • BooleanInput – логическое поле, предназначенное для отображения и изменения булевого значения (истина/ложь);
  • ArrayInput – специфическое поле, которое позволяет отображать некоторое множество для конкретной сущности. Например для Заказа будет удобно отобразить все его позиции (товары).
Ниже мы подробно рассмотрим каждый из представленных типов полей, их особенности, назначение и примеры использования в интерфейсе админ-панели. Такой подход поможет лучше понять, в каких случаях и для каких задач стоит применять тот или иной компонент.

TextInput

Базовый компонент ввода текста, который используют для ввода коротких строковых значений. Он является самым универсальным полем и применяется в большинстве форм:
<TextInput label="Заголовок" name="title" placeholder="Заголовок" required columnSpan={2}/>
  • label – отображаемый заголовок поля, который подсказывает пользователю, что нужно ввести. Обычно размещается над или рядом с самим полем ввода;
  • name – уникальный идентификатор поля, используемый при отправке данных формы. Это имя также связывает поле с соответствующим значением в объекте данных;
  • placeholder – текст-подсказка, отображаемый внутри поля до ввода значений. Помогает понять ожидаемый формат или пример вводимых данных;
  • required – Булево значение, указывающее, что поле обязательно для заполнения;
  • columnSpan – определяет, сколько колонок в сетке формы занимает данное поле. Полезно для выравнивания и настройки визуального расположения элементов формы.

SelectInput

Используется для выбора одного значения из списка. Часто применяется для выбора статуса, категории, типа или других предопределённых опций. Удобен там, где важно ограничить ввод фиксированными вариантами.
<SelectInput label="По атрибуту" name="facet_id" placeholder="По атрибуту" required mode="multiple"columnSpan={2}/>
  • mode="multiple" позволяет выбрать не один, а сразу несколько значений из списка. Это полезно, когда нужно указать несколько категорий, тегов или других параметров одновременно.

FilePictureInput

Поле для загрузки изображений или файлов. Обычно используется для добавления аватаров, фотографий и других визуальных материалов.
<FilePictureInput columnSpan={2} label="Avatar" name="avatar" accept="image/*" maxCount={1} />
Свойства FilePictureInput:
  • accept – указывает допустимые типы файлов для загрузки. Например, image/* разрешает загрузку только изображений;
  • maxCount – ограничивает количество файлов, которые можно загрузить.

BooleanInput

Поле для выбора логического значения (истина/ложь). Обычно отображается в виде чекбокса или переключателя (toggle) и используется для управления бинарными настройками, такими как «Активен», «Опубликован», «Отображать на главной» и другими параметрами.
 <BooleanInput label="Active?" name="active" />
  • label – отображаемый заголовок поля, который подсказывает пользователю, что нужно ввести. Обычно размещается над или рядом с самим полем ввода;
  • name – уникальный идентификатор поля, используемый при отправке данных формы. Это имя также связывает поле с соответствующим значением в объекте данных.

ArrayInput

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

<ArrayInput label="Schedule" name="schedule" required>
            <SelectInput
              label="Day of the week"
              name="day"
              placeholder="Day of the week"
              required
             />
             <TimePickerInput
              label="Opening time"
              name="start_time"
              placeholder="Opening time"
              format="HH:mm"
             />
             <TimePickerInput
               label="Closing time"
               name="end_time"
               placeholder="Closing time"
               format="HH:mm"
             />          
  </ArrayInput>
  • required – Булево значение, указывающее, что поле обязательно для заполнения.
Дополнительно внутри ArrayInput можно использовать любые вложенные поля (например, SelectInput, BooleanInput), каждое из которых также может иметь свои свойства и валидации.

Пример

Теперь, когда мы познакомились с основными типами полей, посмотрим, как они работают в связке внутри одной формы. Ниже представлен пример типичной CRUD-формы, в которой использованы разные поля для ввода текста, выбора значений, загрузки файлов и составления расписания.
Такая форма может быть использована, например, для создания или редактирования записи сотрудника в админке.
В заранее подготовленном файле employer.tsx определим константу с набором полей.

const fields = (<>
      <TextInput label="Имя" name="name" placeholder="Введите имя" required />
      <SelectInput label="Должность" name="position"    placeholder="Выберите должность" required />
      <FilePictureInput label="Аватар" name="avatar" accept="image/*" maxCount={1} />
      <BooleanInput label="Активен" name="is_active" />
      <AjaxSelectInput label="Отдел" name="department_id" placeholder="Выберите отдел" />
      <ArrayInput label="Расписание" name="schedule">
        <TimePickerInput label="Начало" name="start_time" placeholder="Начало" format="HH:mm" />
        <TimePickerInput label="Конец" name="end_time" placeholder="Конец" format="HH:mm" />
        <BooleanInput label="Выходной?" name="day_off" />
      </ArrayInput>
<>)
Далее определим структуру таблицы и передим наши поля в свойства create и edit. После этого в интерфейсе на формах редактирования и создания появятся наши поля.

export const CRUD = createCRUD({path: '/employers',
resource: resource,
index: {
             title: 'Сотрудники',
             newButtonText: 'Добавить',
             tableColumns: [
                          {
                          sorter: true,

                          title: 'ID',
                          dataIndex: 'id',
                          key: 'id',
                          width: 90,
                          },
             ],
},
form: {
             create: {
                  fields,
             },
             edit: {
                  fields,
             },
},
create: {
             title: 'Добавление'
},
update: {
             title: (id: string) => `Редактирование`,
},
})

Backend

Запрос на получение данных для формы будет выглядеть так:
https://admiral.dev.family/admin/emploers/489/update?id=489 

Управление таблицей

Для демонстрации управления таблицей – списком наших записей из базы данных – обратимся к предыдущему примеру. Тут сохранил только необходимый блок для наглядности:

export const CRUD = createCRUD({path: '/employers',
              resource: resource,
              index: {
                            title: 'Сотрудники',
                            newButtonText: 'Добавить',
                            tableColumns: [
                            {
                            sorter: true,

                            title: 'ID',
                            dataIndex: 'id',
                            key: 'id',
                            width: 90,
                            },
                            {
                            sorter: true,
                            title: 'Активен',
                            dataIndex: 'is_active',
                            key: 'is_active',
                            render: (value) => (value ? 'Да' : 'Нет'),
                            },

              ],
              },
              ....
})

По ключу index.tableColumns мы можем управлять колонками таблицы.
  • sorter – указывает, что по этому столбцу можно сортировать данные. При клике на заголовок таблица будет отсортирована по соответствующему значению;
  • title — заголовок столбца, отображаемый в шапке таблицы. Показывает, какое поле представлено в этом столбце (в данном случае – «Активен»);
  • dataIndex — ключ из объекта данных, по которому будет отображаться значение в ячейках. Он указывает, какое свойство из строки данных использовать (например, is_active);
  • key — уникальный идентификатор столбца, часто совпадает с dataIndex. Используется для оптимизации работы таблицы, особенно при обновлениях;
  • render — функция, которая позволяет настроить, как будет отображаться значение в ячейке. В этом примере true выводится как «Да», а false — как «Нет»;
  • width – позволяет вручную задавать размер колонки.

Управление формой

Чтобы данные для формы загрузились, нужно подготовить данные в такую структуру:

{
"data": {
           "name": "Имя",
           "position": "Должность",
           "avatar": {
           "uid": "uid", //уникальный идентификатор файла
           "name": "name.png",
           "url": "https://admiral.dev.family/photo.png" //url на изображение
           "is_active": true,
           "departmen_id": 1,
           "schedule.start_time": "10:20",
           "schedule.end_time": "11:20",
           "schedule.day_off": true
},
"values": {
                  "departmen_id": [
                 {
                               "label": "Маркетинг",
                               "value": "7"
                               },
                               {
                               "label": "Бухгалтерия",
                               "value": "8"
                               }
		  ]
	}
}
Обратите внимание на values – они необходимы, чтобы подгрузить данные для SelectInput отделов. С бэкенда, в свою очередь, мы возвращаем идентификатор отдела – department_id.
Запрос на сохранение/обновление данных будет выглядеть так.
https://admiral.dev.family/admin/emploers/489 (POST)
Данные запроса во многом похожи на данные для получения формы.

{
         "name": "Имя",
         "position": "Должность",
         "avatar": {
		"uid": "uid", 
		"name": "name.png",
		"url": "https://admiral.dev.family/photo.png" 
         }, //будет либо бинарным файлом в случае загрузки в первый раз, либо объектом, если фото уже было загружено
         "is_active": true,
         "departmen_id": 1,
         "schedule": [
                      {
                              "day_id": 1,
                              "start_time": "10:20",
                              "end_time": "11:20",
                              "day_off": true
                      },
                      {
                              "day_id": 2,
                              "start_time": "09:20",
                              "end_time": "12:20",
                              "day_off": true
                      }
         ]
}

Вывод

Admiral предоставляет удобный и гибкий механизм реализации CRUD-интерфейсов для админ-панелей. С помощью компонентов, таких как TextInput, SelectInput, FilePictureInput, BooleanInput, ArrayInput и других, можно быстро настраивать формы для создания, просмотра, редактирования и удаления данных.
Система позволяет:
  • Легко конфигурировать таблицы с сортировкой и кастомным отображением данных;
  • Использовать готовые поля для различных типов данных, включая массивы и файлы;
  • Подгружать и сохранять данные через понятный API.
Благодаря этому можно быстро развертывать админ-интерфейсы с минимальными усилиями, сохраняя при этом высокую гибкость и масштабируемость.
Остались вопросы по базовому CRUD в Admiral? Мы здесь, чтобы помочь!
Читайте также