Попробуйте живую демо-версию
Admiral — это интерфейсная платформа для создания бэк-офиса в React. Он предоставляет готовые компоненты и инструменты, которые упрощают и ускоряют разработку интерфейса администратора.
Сделано с? от dev.family
Требования:
Существует несколько вариантов установки Адмирала:
Чтобы использовать npx, убедитесь, что у вас установлен Node.js.
npx create-admiral-app@latest
При вводе этой команды в консоль вы увидите 2 варианта установки:
Если вы выберете « Установить шаблон с настройкой серверной части в Express.js », вы установите полностью настроенный шаблон с серверной частью в Express.js.
Подробная инструкция по установке и запуску.
Все переменные среды будут установлены автоматически. Если вы хотите настроить их вручную, перейдите в папку проекта и откройте файл .env. С самого начала у вас будет 1 CRUD — Users . Чтобы их найти пройдите путь - admiral/src/crud/users/index.tsx
Если вы выберете « Установить шаблон без настройки бэкэнда », вы получите только интерфейсную оболочку Admiral в папке адмирала с CRUD- Users . Чтобы его найти, пройдите путь — admiral/src/crud/users/index.tsx
. Чтобы использовать свой бэкэнд, прочтите документацию
Адмирал доступен по адресу http://localhost:3000. Если порт 3000 занят, будет выбран любой другой свободный порт.
В консоли вы увидите что-то вроде этого
Port 3000 is in use, trying another one...
vite v2.9.15 dev server running at:
> Local: http://localhost:3001/
> Network: http://192.168.100.82:3001/
ready in 459ms.
Подробные инструкции по установке и запуску есть в каждом из примеров.
Откройте браузер и перейдите по адресу http://localhost:3000.
Да, это так. Вы можете просто клонировать этот репозиторий и ввести следующие команды:
yarn
yarn dev
Затем перейдите по адресу http://localhost:3000. Адмирал с макетными данными теперь доступен вам.
Файл App.tsx является точкой входа в приложение. Здесь инициализируется библиотека и отображаются компоненты Admin
.
import React from 'react'
import { Admin , createRoutesFrom , OAuthProvidersEnum } from '../admiral'
import Menu from './config/menu'
import dataProvider from './dataProvider'
import authProvider from './authProvider'
const apiUrl = '/api'
// import all pages from pages folder and create routes
const Routes = createRoutesFrom ( import . meta . globEager ( '../pages/**/*' ) )
function App ( ) {
return (
< Admin
dataProvider = { dataProvider ( apiUrl ) }
authProvider = { authProvider ( apiUrl ) }
menu = { Menu }
oauthProviders = { [
OAuthProvidersEnum . Google ,
OAuthProvidersEnum . Github ,
OAuthProvidersEnum . Jira ,
] }
>
< Routes />
</ Admin >
)
}
export default App
Основным контрактом для авторизации в системе является интерфейс AuthProvider
.
export interface AuthProvider {
login : ( params : any ) => Promise < any >
logout : ( params : any ) => Promise < void | false | string >
checkAuth : ( params : any ) => Promise < void >
getIdentity : ( ) => Promise < UserIdentity >
oauthLogin ?: ( provider : OAuthProvidersEnum ) => Promise < { redirect : string } >
oauthCallback ?: ( provider : OAuthProvidersEnum , data : string ) => Promise < any >
[ key : string ] : any
}
Пример реализации Сам интерфейс можно настроить по своему вкусу, но важно соблюдать предоставляемый им контракт. Подробное описание контракта
Давайте рассмотрим основные способы реализации:
Метод | Имя | Описание | Параметры | Возвращаемое значение |
---|---|---|---|---|
авторизоваться | Аутентификация пользователя | Делает POST-запрос к /api/login и сохраняет поле token в localStorage, которое используется в дальнейших запросах. | params — объект с полями username и password | Объект с полем token и объект user с полями email и name . |
выход из системы | Выход пользователя | Выполняет POST-запрос к /api/logout и удаляет поле token из localStorage. | void | |
проверкаAuth | Проверка авторизации пользователя | Делает запрос GET к /api/checkAuth и проверяет достоверность токена, ожидает код состояния — 200. Используется каждый раз, когда используется API. | token на предъявителя | Код состояния 200 |
getIdentity | Получение пользовательских данных | Делает запрос GET к /api/getIdentity и возвращает объект с пользовательскими данными. | token на предъявителя | user объекта с полями email и name |
oauthВход | Авторизация через OAuth | Делает запрос GET к /api/auth/social-login/${provider} и возвращает объект с полем redirect , которое используется для перенаправления. | provider - провайдер OAuth | Объект с redirect поля |
oauthОбратный вызов | Авторизация обратного звонка через OAuth | Делает запрос POST к /api/auth/social-login/${provider}/callback и сохраняет поле token в localStorage, которое используется в дальнейших запросах. | provider — провайдер OAuth, data — данные, полученные от провайдера OAuth, где существует поле token . | Объект с token поля |
Основной контракт для работы с данными представляет собой интерфейс DataProvider
.
export interface DataProvider {
getList : (
resource : string ,
params : Partial < GetListParams > ,
) => Promise < GetListResult < RecordType > >
reorderList : ( resource : string , params : ReorderParams ) => Promise < void >
getOne : ( resource : string , params : GetOneParams ) => Promise < GetOneResult < RecordType > >
getCreateFormData : ( resource : string ) => Promise < GetFormDataResult < RecordType > >
getFiltersFormData : (
resource : string ,
urlState ?: Record < string , any > ,
) => Promise < GetFiltersFormDataResult >
create : ( resource : string , params : CreateParams ) => Promise < CreateResult < RecordType > >
getUpdateFormData : (
resource : string ,
params : GetOneParams ,
) => Promise < GetFormDataResult < RecordType > >
update : ( resource : string , params : UpdateParams ) => Promise < UpdateResult < RecordType > >
deleteOne : ( resource : string , params : DeleteParams ) => Promise < DeleteResult < RecordType > >
[ key : string ] : any
}
Пример реализации Подробное описание контракта
Давайте рассмотрим основные способы реализации:
Метод | Имя | Описание | Параметры |
---|---|---|---|
получить список | Получение списка сущностей | Выполняет запрос GET к /api/${resource} и возвращает объект с данными, которые будут использоваться в компоненте List . | resource - имя ресурса, params - объект с параметрами запроса |
список переупорядочения | Изменение порядка сущностей | Выполняет POST-запрос к /api/${resource}/reorder и возвращает объект с данными, которые будут использоваться в компоненте List . | resource - имя ресурса, params - объект с параметрами запроса |
getOne | Получение сущности | Выполняет запрос GET к /api/${resource}/${id} и возвращает объект с данными, которые будут использоваться в компоненте Show . | resource - имя ресурса, id - идентификатор сущности |
getCreateFormData | Получение данных для формы создания сущности (Select, AjaxSelect) | Выполняет запрос GET к /api/${resource}/create и возвращает объект с данными, которые будут использоваться в компоненте Create . | resource - имя ресурса |
getFiltersFormData | Получение данных для фильтров | Выполняет запрос GET к /api/${resource}/filters и возвращает объект с данными, которые будут использоваться в компоненте Filters . | resource - имя ресурса, urlState - объект с параметрами из URL, которые будут использоваться в Filters компонента. |
создавать | Создание сущности | Выполняет POST-запрос к /api/${resource} и возвращает объект с данными, которые будут использоваться в компоненте Create | resource - имя ресурса, params - объект данных сущности |
getUpdateFormData | Получение данных для формы редактирования сущности (Select, AjaxSelect) | Делает запрос GET к /api/${resource}/${id}/update и возвращает объект с данными, которые будут использоваться в компоненте. Edit | resource - имя ресурса, id - идентификатор сущности |
обновлять | Обновление объекта | Выполняет POST-запрос к /api/${resource}/${id} и возвращает объект с данными, которые будут использоваться в компоненте. Edit | resource - имя ресурса, id - идентификатор сущности, params - объект данных сущности. |
удалить | Удаление объекта | Выполняет запрос DELETE к /api/${resource}/${id} и возвращает объект с данными, которые будут использоваться в компоненте Delete | resource - имя ресурса, id - идентификатор сущности |
Запрос:
http://localhost/admin/users?page=1&perPage=10&filter%5Bid%5D=1
Результат:
{
"items" : [
{
"id" : 1 ,
"name" : " Dev family " ,
"email" : " [email protected] " ,
"role" : " Administrator " ,
"created_at" : " 2023-05-05 14:17:51 "
}
],
"meta" : {
"current_page" : 1 ,
"from" : 1 ,
"last_page" : 1 ,
"per_page" : 10 ,
"to" : 1 ,
"total" : 1
}
}
Запрос:
http://localhost/admin/users/1/update?id=1
Результат:
{
"data" : {
"id" : 1 ,
"name" : " Dev family " ,
"email" : " [email protected] " ,
"role_id" : 1
},
"values" : {
"role_id" : [
{
"label" : " Administrator " ,
"value" : 1
}
]
}
}
❗ Примечание . Мы используем код состояния HTTP 422 Unprocessable Entity для обработки ошибок проверки.
{
"errors" : {
"name" : [ " Field 'name' is invalid. " ],
"email" : [ " Field 'email' is invalid. " ]
},
"message" : " Validation failed "
}
Работа с нумерацией страниц осуществляется методом getList
. Вы можете передать параметры page
и perPage
методу getList
, и он вернет объект PaginationResult
с items
и meta
.
Фильтры работают с методом getList
. Вы можете передать параметр filter[$field]
методу getList
, и он вернет объект PaginationResult
с items
и meta
.
Сортировка работает с методом getList
. Вы можете передать параметр sort[$field]
методу getList
, и он вернет объект PaginationResult
с items
и meta
.
У Admiral есть маршрутизатор на основе файловой системы .
Страница — это компонент React, экспортированный из файла .js, .jsx, .ts или .tsx в каталоге страниц. Когда файл добавляется в каталог страниц, он автоматически становится доступным в качестве маршрута. React-router-dom используется под капотом.
Маршрутизатор автоматически направит файлы с именем index в корень каталога.
pages/index.ts → /
pages/users/index.ts → /users
Маршрутизатор поддерживает вложенные файлы. Если вы создадите вложенную структуру папок, файлы будут автоматически маршрутизироваться таким же образом.
pages/users/create.ts → /users/create
Чтобы сопоставить динамический сегмент, вы можете использовать синтаксис скобок. Это позволяет сопоставлять именованные параметры.
pages/users/[id].ts → /users/:id (/users/42)
Этот компонент является самым важным в вашей админ-панели. С его помощью вы можете задать основные настройки и конфигурации вашего приложения, такие как: навигация, логотип, API для запросов к серверу, авторизация по API, локализация, тема и другие вещи.
Пример использования:
< Admin
dataProvider = { dataProvider ( apiUrl ) }
authProvider = { authProvider ( apiUrl ) }
menu = { Menu }
oauthProviders = { [
OAuthProvidersEnum . Google ,
OAuthProvidersEnum . Github ,
OAuthProvidersEnum . Jira ,
] }
>
< Routes />
</ Admin >
Компонент принимает следующие реквизиты:
меню
Здесь вы можете настроить навигацию. Вам следует использовать специальные компоненты из нашего пакета: Menu, MenuItemLink, SubMenu. Вы можете найти пример здесь.
логотип
Вы можете изменить логотип, отображаемый на боковой панели навигации. Проп принимает ссылку на компонент svg, JSX или файл в формате svg.
ВойтиЛоготип
Вы можете изменить логотип, который отображается в форме авторизации. Проп принимает ссылку на компонент svg, JSX или файл в формате svg.
в сторонуСодержимое
С помощью этого инструмента вы можете добавить необходимый контент на боковую панель навигации под ссылками. Вам необходимо передать ReactNode.
поставщик данных
Основной контракт на работу с данными. Более подробную информацию вы можете получить в нашей документации.
автораутпровидер
Основной контракт на авторизацию в системе. Более подробную информацию вы можете получить в нашей документации.
ТемаПресеты
Вы можете настроить цветовую тему для своего приложения. Более подробную информацию вы можете получить в нашей документации.
локаль
Схема локализации вашей админ-панели, которую вы можете получить с помощью хука useLocaleProvider. Пример схемы вы можете найти здесь.
oauthProviders
Используйте авторизацию OAuth, используя этот реквизит. Передайте имя требуемого провайдера в массиве, используя перечисление OAuthProvidersEnum от адмирала.
базовыйAppUrl
Добавьте реквизиты, чтобы изменить базовый путь приложения.
Меню представляет собой массив объектов, имеющих следующую структуру:
import { Menu , SubMenu , MenuItemLink } from '../../admiral'
const CustomMenu = ( ) => {
return (
< Menu >
< MenuItemLink icon = "FiCircle" name = "First Menu Item" to = "/first" />
< SubMenu icon = "FiCircle" name = "Second Menu Item" >
< MenuItemLink icon = "FiCircle" name = "Sub Menu Item" to = "/second" />
</ SubMenu >
</ Menu >
)
}
export default CustomMenu
В нашем приложении используются хуки React. Вы можете использовать их из любой точки приложения внутри компонентов React. Вот крючки, которые вы можете использовать:
Этот хук позволяет получать и управлять статусом панели навигации.
import { useNav } from '@devfamily/admiral'
const { collapsed , toggleCollapsed , visible , toggle , open , close } = useNav ( )
Этот хук позволяет получать значения формы и управлять ее состоянием. Хук можно использовать в компонентах, используемых в «форме» внутри конфигурации функции createCRUD.
import { useForm } from '@devfamily/admiral'
const {
values ,
options ,
errors ,
setErrors ,
setValues ,
setOptions ,
isSubmitting ,
isFetching ,
locale ,
} = useForm ( )
Этот хук позволяет вам получать состояние темы и управлять им.
import { useTheme } from '@devfamily/admiral'
const { themeName , setTheme } = useTheme ( )
Хук, позволяющий получить состояние, полученное вызовом AuthProvider.getIdentity().
import { useGetIdentty } from '@devfamily/admiral'
const { identity , loading , loaded , error } = useGetIdentty ( )
Иконки, используемые в Admiral, взяты из React Icons.
ThemeProvider использует компонент Theme @consta/uikit под капотом.
Вы можете передать свои пресеты компоненту Admin
с помощью свойства themePresets
:
import React from 'react'
import { Admin , createRoutesFrom } from '../admiral'
import Menu from './config/menu'
import dataProvider from './dataProvider'
import authProvider from './authProvider'
import themeLight from './theme/presets/themeLight'
import themeDark from './theme/presets/themeDark'
const apiUrl = '/api'
const Routes = createRoutesFrom ( import . meta . globEager ( '../pages/**/*' ) )
function App ( ) {
return (
< Admin
dataProvider = { dataProvider ( apiUrl ) }
authProvider = { authProvider ( apiUrl ) }
menu = { Menu }
themePresets = { { light : themeLight , dark : themeDark } }
>
< Routes />
</ Admin >
)
}
Создайте каталог для пресетов. Внутри создайте папки для каждого модификатора — такие же, как и в компоненте «Тема».
Создайте CSS-файлы. В папки с модификаторами поместите файлы CSS, которые будут отвечать за эти модификаторы.
Вы получите нечто подобное:
presets/
_color/
_Theme_color_themeDark.css
_Theme_color_themeLight.css
_control/
_Theme_control_themeLight.css
_font/
_Theme_font_themeLight.css
_size/
_Theme_size_themeLight.css
_space/
_Theme_space_themeLight.css
_shadow/
_Theme_shadow_themeLight.css
themeLight.ts
themeDark.ts
Настройте переменные в файлах CSS.
Создайте файлы предустановок (themeLight, themeDark).
Импортируйте файлы CSS, которые вы собираетесь использовать.
Создайте предустановленный объект. Укажите, какие значения (например, CSS-файлы) и какие модификаторы использовать в наборе настроек. Вы получите нечто подобное:
// in presets/themeLight.ts
import './_color/_Theme_color_themeLight.css'
import './_color/_Theme_color_themeDark.css'
import './_control/_Theme_control_themeLight.css'
import './_font/_Theme_font_themeLight.css'
import './_size/_Theme_size_themeLight.css'
import './_space/_Theme_space_themeLight.css'
import './_shadow/_Theme_shadow_themeLight.css'
export default {
color : {
primary : 'themeLight' ,
accent : 'themeDark' ,
invert : 'themeDark' ,
} ,
control : 'themeLight' ,
font : 'themeLight' ,
size : 'themeLight' ,
space : 'themeLight' ,
shadow : 'themeLight' ,
}
Передайте свои пресеты компоненту Admin
, как показано в примере выше.
❗ Примечание : плагины postcss используются для преобразования цвета в примере пресетов Admiral. Если вы хотите воспроизвести, установите плагин postcss и postcss-color-mod-function.
Если вы хотите принять участие в разработке Admiral, сделайте форк репозитория, внесите нужные изменения и отправьте запрос на включение. Будем рады рассмотреть Ваши предложения!
Эта библиотека распространяется по лицензии MIT.
Если у вас есть вопросы, пишите нам по адресу: [email protected] Мы всегда рады вашим отзывам!