ui-admin-lib 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +477 -0
- package/dist/components/AdminPanel/AdminPanel.d.ts +27 -0
- package/dist/components/AdminPanel/AdminPanel.d.ts.map +1 -0
- package/dist/components/Badge/Badge.d.ts +10 -0
- package/dist/components/Badge/Badge.d.ts.map +1 -0
- package/dist/components/CRUD/CrudForm.d.ts +26 -0
- package/dist/components/CRUD/CrudForm.d.ts.map +1 -0
- package/dist/components/CRUD/CrudList.d.ts +18 -0
- package/dist/components/CRUD/CrudList.d.ts.map +1 -0
- package/dist/components/Card/Card.d.ts +11 -0
- package/dist/components/Card/Card.d.ts.map +1 -0
- package/dist/components/Form/Button.d.ts +10 -0
- package/dist/components/Form/Button.d.ts.map +1 -0
- package/dist/components/Form/Checkbox.d.ts +7 -0
- package/dist/components/Form/Checkbox.d.ts.map +1 -0
- package/dist/components/Form/Input.d.ts +9 -0
- package/dist/components/Form/Input.d.ts.map +1 -0
- package/dist/components/Form/Label.d.ts +8 -0
- package/dist/components/Form/Label.d.ts.map +1 -0
- package/dist/components/Form/LoginForm.d.ts +10 -0
- package/dist/components/Form/LoginForm.d.ts.map +1 -0
- package/dist/components/Form/Radio.d.ts +7 -0
- package/dist/components/Form/Radio.d.ts.map +1 -0
- package/dist/components/Form/Select.d.ts +16 -0
- package/dist/components/Form/Select.d.ts.map +1 -0
- package/dist/components/Form/Textarea.d.ts +9 -0
- package/dist/components/Form/Textarea.d.ts.map +1 -0
- package/dist/components/Layout/Content.d.ts +8 -0
- package/dist/components/Layout/Content.d.ts.map +1 -0
- package/dist/components/Layout/Header.d.ts +9 -0
- package/dist/components/Layout/Header.d.ts.map +1 -0
- package/dist/components/Layout/PageLayout.d.ts +10 -0
- package/dist/components/Layout/PageLayout.d.ts.map +1 -0
- package/dist/components/Layout/Sidebar.d.ts +9 -0
- package/dist/components/Layout/Sidebar.d.ts.map +1 -0
- package/dist/components/Loading/Loading.d.ts +9 -0
- package/dist/components/Loading/Loading.d.ts.map +1 -0
- package/dist/components/Modal/Modal.d.ts +13 -0
- package/dist/components/Modal/Modal.d.ts.map +1 -0
- package/dist/components/Navigation/Breadcrumbs.d.ts +14 -0
- package/dist/components/Navigation/Breadcrumbs.d.ts.map +1 -0
- package/dist/components/Navigation/Menu.d.ts +16 -0
- package/dist/components/Navigation/Menu.d.ts.map +1 -0
- package/dist/components/Navigation/Tabs.d.ts +17 -0
- package/dist/components/Navigation/Tabs.d.ts.map +1 -0
- package/dist/components/Table/DataTable.d.ts +20 -0
- package/dist/components/Table/DataTable.d.ts.map +1 -0
- package/dist/components/Toast/Toast.d.ts +19 -0
- package/dist/components/Toast/Toast.d.ts.map +1 -0
- package/dist/index.cjs.js +30 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.js +1459 -0
- package/dist/styles.css +1 -0
- package/dist/utils/crud.d.ts +28 -0
- package/dist/utils/crud.d.ts.map +1 -0
- package/package.json +64 -0
package/README.md
ADDED
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
# UI Admin Library
|
|
2
|
+
|
|
3
|
+
Библиотека для быстрого создания административных панелей на React с полным CRUD функционалом. Создайте полноценную админку всего в несколько строк кода!
|
|
4
|
+
|
|
5
|
+
## Установка
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install ui-admin-lib
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Использование
|
|
12
|
+
|
|
13
|
+
Создайте админ-панель в несколько строк:
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
import { AdminPanel, CrudService } from 'ui-admin-lib'
|
|
17
|
+
import 'ui-admin-lib/styles'
|
|
18
|
+
|
|
19
|
+
// 1. Создайте сервис для работы с API
|
|
20
|
+
const userService = new CrudService({
|
|
21
|
+
baseUrl: 'https://api.example.com/users',
|
|
22
|
+
headers: {
|
|
23
|
+
'Authorization': 'Bearer YOUR_TOKEN'
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
// 2. Определите модель
|
|
28
|
+
const userModel = {
|
|
29
|
+
name: 'users',
|
|
30
|
+
label: 'Пользователи',
|
|
31
|
+
service: userService,
|
|
32
|
+
columns: [
|
|
33
|
+
{ key: 'id', title: 'ID', dataIndex: 'id' },
|
|
34
|
+
{ key: 'name', title: 'Имя', dataIndex: 'name' },
|
|
35
|
+
{ key: 'email', title: 'Email', dataIndex: 'email' },
|
|
36
|
+
],
|
|
37
|
+
fields: [
|
|
38
|
+
{ name: 'name', label: 'Имя', type: 'text', required: true },
|
|
39
|
+
{ name: 'email', label: 'Email', type: 'email', required: true },
|
|
40
|
+
],
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// 3. Используйте AdminPanel
|
|
44
|
+
function App() {
|
|
45
|
+
return (
|
|
46
|
+
<AdminPanel
|
|
47
|
+
title="Моя админка"
|
|
48
|
+
models={[userModel]}
|
|
49
|
+
login={{
|
|
50
|
+
onSubmit: async (username, password) => {
|
|
51
|
+
// Ваша логика авторизации
|
|
52
|
+
},
|
|
53
|
+
}}
|
|
54
|
+
/>
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Всё! AdminPanel автоматически создаст:
|
|
60
|
+
- Страницу входа
|
|
61
|
+
- Боковую навигацию
|
|
62
|
+
- Таблицы с данными
|
|
63
|
+
- Формы для создания/редактирования
|
|
64
|
+
- Полный CRUD функционал
|
|
65
|
+
|
|
66
|
+
## Полный пример конфигурации
|
|
67
|
+
|
|
68
|
+
Вот полный пример с несколькими моделями и всеми возможностями:
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
import { AdminPanel, CrudService, AdminModel } from 'ui-admin-lib'
|
|
72
|
+
import type { Column, FormField } from 'ui-admin-lib'
|
|
73
|
+
import 'ui-admin-lib/styles'
|
|
74
|
+
|
|
75
|
+
// Типы данных
|
|
76
|
+
interface User {
|
|
77
|
+
id: number
|
|
78
|
+
name: string
|
|
79
|
+
email: string
|
|
80
|
+
role: string
|
|
81
|
+
active: boolean
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface Product {
|
|
85
|
+
id: number
|
|
86
|
+
title: string
|
|
87
|
+
price: number
|
|
88
|
+
category: string
|
|
89
|
+
inStock: boolean
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Создание сервисов для работы с API
|
|
93
|
+
const userService = new CrudService<User>({
|
|
94
|
+
baseUrl: 'https://api.example.com/users',
|
|
95
|
+
headers: {
|
|
96
|
+
'Authorization': 'Bearer YOUR_TOKEN',
|
|
97
|
+
'Content-Type': 'application/json'
|
|
98
|
+
},
|
|
99
|
+
// Опционально: кастомные URL для операций
|
|
100
|
+
getListUrl: () => 'https://api.example.com/users',
|
|
101
|
+
getDetailUrl: (id) => `https://api.example.com/users/${id}`,
|
|
102
|
+
getCreateUrl: () => 'https://api.example.com/users',
|
|
103
|
+
getUpdateUrl: (id) => `https://api.example.com/users/${id}`,
|
|
104
|
+
getDeleteUrl: (id) => `https://api.example.com/users/${id}`,
|
|
105
|
+
// Опционально: трансформация данных
|
|
106
|
+
transformRequest: (data) => data, // Преобразование перед отправкой
|
|
107
|
+
transformResponse: (data) => data, // Преобразование после получения
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
const productService = new CrudService<Product>({
|
|
111
|
+
baseUrl: 'https://api.example.com/products',
|
|
112
|
+
headers: {
|
|
113
|
+
'Authorization': 'Bearer YOUR_TOKEN'
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
// Конфигурация модели пользователей
|
|
118
|
+
const userModel: AdminModel<User> = {
|
|
119
|
+
name: 'users',
|
|
120
|
+
label: 'Пользователи',
|
|
121
|
+
service: userService,
|
|
122
|
+
columns: [
|
|
123
|
+
{ key: 'id', title: 'ID', dataIndex: 'id' },
|
|
124
|
+
{ key: 'name', title: 'Имя', dataIndex: 'name' },
|
|
125
|
+
{ key: 'email', title: 'Email', dataIndex: 'email' },
|
|
126
|
+
{
|
|
127
|
+
key: 'role',
|
|
128
|
+
title: 'Роль',
|
|
129
|
+
dataIndex: 'role',
|
|
130
|
+
render: (value) => value.charAt(0).toUpperCase() + value.slice(1),
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
key: 'active',
|
|
134
|
+
title: 'Активен',
|
|
135
|
+
dataIndex: 'active',
|
|
136
|
+
render: (value) => (value ? 'Да' : 'Нет'),
|
|
137
|
+
},
|
|
138
|
+
] as Column<User>[],
|
|
139
|
+
fields: [
|
|
140
|
+
{ name: 'name', label: 'Имя', type: 'text', required: true, placeholder: 'Введите имя' },
|
|
141
|
+
{ name: 'email', label: 'Email', type: 'email', required: true, placeholder: 'Введите email' },
|
|
142
|
+
{
|
|
143
|
+
name: 'role',
|
|
144
|
+
label: 'Роль',
|
|
145
|
+
type: 'select',
|
|
146
|
+
required: true,
|
|
147
|
+
options: [
|
|
148
|
+
{ value: 'admin', label: 'Администратор' },
|
|
149
|
+
{ value: 'user', label: 'Пользователь' },
|
|
150
|
+
],
|
|
151
|
+
},
|
|
152
|
+
{ name: 'active', label: 'Активен', type: 'checkbox' },
|
|
153
|
+
] as FormField[],
|
|
154
|
+
// Опционально: кастомная функция получения ID
|
|
155
|
+
getItemId: (item) => item.id,
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Конфигурация модели товаров
|
|
159
|
+
const productModel: AdminModel<Product> = {
|
|
160
|
+
name: 'products',
|
|
161
|
+
label: 'Товары',
|
|
162
|
+
service: productService,
|
|
163
|
+
columns: [
|
|
164
|
+
{ key: 'id', title: 'ID', dataIndex: 'id' },
|
|
165
|
+
{ key: 'title', title: 'Название', dataIndex: 'title' },
|
|
166
|
+
{
|
|
167
|
+
key: 'price',
|
|
168
|
+
title: 'Цена',
|
|
169
|
+
dataIndex: 'price',
|
|
170
|
+
render: (value) => `${value.toLocaleString('ru-RU')} ₽`,
|
|
171
|
+
},
|
|
172
|
+
{ key: 'category', title: 'Категория', dataIndex: 'category' },
|
|
173
|
+
{
|
|
174
|
+
key: 'inStock',
|
|
175
|
+
title: 'В наличии',
|
|
176
|
+
dataIndex: 'inStock',
|
|
177
|
+
render: (value) => (value ? 'Да' : 'Нет'),
|
|
178
|
+
},
|
|
179
|
+
] as Column<Product>[],
|
|
180
|
+
fields: [
|
|
181
|
+
{ name: 'title', label: 'Название', type: 'text', required: true },
|
|
182
|
+
{ name: 'price', label: 'Цена', type: 'number', required: true },
|
|
183
|
+
{ name: 'category', label: 'Категория', type: 'text', required: true },
|
|
184
|
+
{ name: 'inStock', label: 'В наличии', type: 'checkbox' },
|
|
185
|
+
] as FormField[],
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Использование
|
|
189
|
+
function App() {
|
|
190
|
+
return (
|
|
191
|
+
<AdminPanel
|
|
192
|
+
title="Админ панель"
|
|
193
|
+
logo={<span>Мой Логотип</span>} // Опционально: кастомный логотип
|
|
194
|
+
models={[userModel, productModel]}
|
|
195
|
+
login={{
|
|
196
|
+
onSubmit: async (username, password) => {
|
|
197
|
+
// Ваша логика авторизации
|
|
198
|
+
const response = await fetch('https://api.example.com/auth/login', {
|
|
199
|
+
method: 'POST',
|
|
200
|
+
headers: { 'Content-Type': 'application/json' },
|
|
201
|
+
body: JSON.stringify({ username, password }),
|
|
202
|
+
})
|
|
203
|
+
if (!response.ok) {
|
|
204
|
+
throw new Error('Неверное имя пользователя или пароль')
|
|
205
|
+
}
|
|
206
|
+
const data = await response.json()
|
|
207
|
+
// Сохраните токен
|
|
208
|
+
localStorage.setItem('token', data.token)
|
|
209
|
+
},
|
|
210
|
+
}}
|
|
211
|
+
user={{
|
|
212
|
+
name: 'Администратор', // Опционально: имя пользователя в header
|
|
213
|
+
onLogout: () => {
|
|
214
|
+
// Опционально: обработчик выхода
|
|
215
|
+
localStorage.removeItem('token')
|
|
216
|
+
},
|
|
217
|
+
}}
|
|
218
|
+
/>
|
|
219
|
+
)
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Типы полей форм
|
|
224
|
+
|
|
225
|
+
Поддерживаются следующие типы полей в `FormField`:
|
|
226
|
+
|
|
227
|
+
- `text` - Текстовое поле
|
|
228
|
+
- `email` - Email поле
|
|
229
|
+
- `number` - Числовое поле
|
|
230
|
+
- `password` - Поле пароля
|
|
231
|
+
- `textarea` - Многострочное поле
|
|
232
|
+
- `select` - Выпадающий список (требует `options`)
|
|
233
|
+
- `checkbox` - Чекбокс
|
|
234
|
+
- `radio` - Радиокнопки (требует `options`)
|
|
235
|
+
|
|
236
|
+
Пример конфигурации поля:
|
|
237
|
+
|
|
238
|
+
```tsx
|
|
239
|
+
{
|
|
240
|
+
name: 'fieldName', // Имя поля (обязательно)
|
|
241
|
+
label: 'Метка поля', // Метка поля (обязательно)
|
|
242
|
+
type: 'text', // Тип поля (опционально, по умолчанию 'text')
|
|
243
|
+
required: true, // Обязательное поле (опционально)
|
|
244
|
+
placeholder: 'Подсказка', // Подсказка (опционально)
|
|
245
|
+
disabled: false, // Отключено (опционально)
|
|
246
|
+
options: [ // Опции для select/radio (обязательно для этих типов)
|
|
247
|
+
{ value: 'value1', label: 'Метка 1' },
|
|
248
|
+
{ value: 'value2', label: 'Метка 2' },
|
|
249
|
+
],
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Быстрый старт
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
npm install ui-admin-lib
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
```tsx
|
|
260
|
+
import { AdminPanel, CrudService } from 'ui-admin-lib'
|
|
261
|
+
import 'ui-admin-lib/styles'
|
|
262
|
+
|
|
263
|
+
const userService = new CrudService({
|
|
264
|
+
baseUrl: 'https://api.example.com/users',
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
const userModel = {
|
|
268
|
+
name: 'users',
|
|
269
|
+
label: 'Пользователи',
|
|
270
|
+
service: userService,
|
|
271
|
+
columns: [
|
|
272
|
+
{ key: 'id', title: 'ID', dataIndex: 'id' },
|
|
273
|
+
{ key: 'name', title: 'Имя', dataIndex: 'name' },
|
|
274
|
+
],
|
|
275
|
+
fields: [
|
|
276
|
+
{ name: 'name', label: 'Имя', type: 'text', required: true },
|
|
277
|
+
],
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function App() {
|
|
281
|
+
return <AdminPanel models={[userModel]} />
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## Демо приложение
|
|
286
|
+
|
|
287
|
+
Запустите демо приложение для просмотра всех возможностей:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
git clone <repository-url>
|
|
291
|
+
cd ui-admin-lib
|
|
292
|
+
npm install
|
|
293
|
+
npm run demo
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Откройте http://localhost:3000 в браузере.
|
|
297
|
+
|
|
298
|
+
**Вход:**
|
|
299
|
+
- Логин: `admin`
|
|
300
|
+
- Пароль: `admin`
|
|
301
|
+
|
|
302
|
+
## Основные компоненты
|
|
303
|
+
|
|
304
|
+
### AdminPanel
|
|
305
|
+
Главный компонент для создания админ-панели. Принимает конфигурацию и автоматически создает:
|
|
306
|
+
- Страницу входа
|
|
307
|
+
- Боковую навигацию
|
|
308
|
+
- Таблицы с данными
|
|
309
|
+
- Формы создания/редактирования
|
|
310
|
+
- Операции CRUD (Create, Read, Update, Delete)
|
|
311
|
+
|
|
312
|
+
### CrudService
|
|
313
|
+
Утилита для работы с REST API. Поддерживает любые форматы ответов API.
|
|
314
|
+
|
|
315
|
+
### Низкоуровневые компоненты
|
|
316
|
+
|
|
317
|
+
### Layout (Макет)
|
|
318
|
+
- `PageLayout` - Основной layout с header, sidebar и content
|
|
319
|
+
- `Header` - Шапка страницы
|
|
320
|
+
- `Sidebar` - Боковая панель
|
|
321
|
+
- `Content` - Основная область контента
|
|
322
|
+
|
|
323
|
+
### Form (Формы)
|
|
324
|
+
- `Button` - Кнопка (варианты: primary, success, danger, ghost)
|
|
325
|
+
- `Input` - Поле ввода текста
|
|
326
|
+
- `Select` - Выпадающий список
|
|
327
|
+
- `Textarea` - Многострочное поле ввода
|
|
328
|
+
- `Checkbox` - Чекбокс
|
|
329
|
+
- `Radio` - Радиокнопка
|
|
330
|
+
- `Label` - Метка для полей формы
|
|
331
|
+
|
|
332
|
+
### Table (Таблицы)
|
|
333
|
+
- `DataTable` - Таблица данных с колонками и строками
|
|
334
|
+
|
|
335
|
+
### Modal (Модальные окна)
|
|
336
|
+
- `Modal` - Модальное окно
|
|
337
|
+
|
|
338
|
+
### Navigation (Навигация)
|
|
339
|
+
- `Menu` - Меню навигации
|
|
340
|
+
- `Breadcrumbs` - Хлебные крошки
|
|
341
|
+
- `Tabs` - Вкладки
|
|
342
|
+
|
|
343
|
+
### Utility (Утилиты)
|
|
344
|
+
- `Card` - Карточка
|
|
345
|
+
- `Toast` / `ToastContainer` - Уведомления
|
|
346
|
+
- `Loading` - Индикатор загрузки
|
|
347
|
+
- `Badge` - Значок/бейдж
|
|
348
|
+
|
|
349
|
+
## API Reference
|
|
350
|
+
|
|
351
|
+
### AdminPanel
|
|
352
|
+
|
|
353
|
+
Главный компонент для создания админ-панели.
|
|
354
|
+
|
|
355
|
+
```tsx
|
|
356
|
+
<AdminPanel
|
|
357
|
+
title?: string // Заголовок админ-панели (по умолчанию "Админ панель")
|
|
358
|
+
logo?: React.ReactNode // Кастомный логотип
|
|
359
|
+
models: AdminModel[] // Массив моделей для отображения
|
|
360
|
+
login?: { // Конфигурация авторизации (опционально)
|
|
361
|
+
onSubmit: (username: string, password: string) => Promise<void> | void
|
|
362
|
+
}
|
|
363
|
+
user?: { // Информация о пользователе (опционально)
|
|
364
|
+
name?: string // Имя пользователя в header
|
|
365
|
+
onLogout?: () => void // Обработчик выхода
|
|
366
|
+
}
|
|
367
|
+
/>
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### AdminModel
|
|
371
|
+
|
|
372
|
+
Конфигурация модели данных.
|
|
373
|
+
|
|
374
|
+
```tsx
|
|
375
|
+
interface AdminModel<T = any> {
|
|
376
|
+
name: string // Уникальное имя модели
|
|
377
|
+
label: string // Отображаемое название
|
|
378
|
+
service: CrudService<T> // Сервис для работы с API
|
|
379
|
+
columns: Column<T>[] // Колонки таблицы
|
|
380
|
+
fields: FormField[] // Поля формы
|
|
381
|
+
getItemId?: (item: T) => string | number // Функция получения ID (опционально)
|
|
382
|
+
}
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### CrudService
|
|
386
|
+
|
|
387
|
+
Класс для работы с REST API.
|
|
388
|
+
|
|
389
|
+
```tsx
|
|
390
|
+
new CrudService<T>({
|
|
391
|
+
baseUrl: string // Базовый URL API
|
|
392
|
+
getListUrl?: (params?: any) => string // URL для получения списка (опционально)
|
|
393
|
+
getDetailUrl?: (id) => string // URL для получения элемента (опционально)
|
|
394
|
+
getCreateUrl?: () => string // URL для создания (опционально)
|
|
395
|
+
getUpdateUrl?: (id) => string // URL для обновления (опционально)
|
|
396
|
+
getDeleteUrl?: (id) => string // URL для удаления (опционально)
|
|
397
|
+
transformRequest?: (data) => any // Трансформация запроса (опционально)
|
|
398
|
+
transformResponse?: (data) => T // Трансформация ответа (опционально)
|
|
399
|
+
headers?: Record<string, string> // Заголовки запросов (опционально)
|
|
400
|
+
})
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
Методы:
|
|
404
|
+
- `getList(params?)` - Получить список элементов
|
|
405
|
+
- `getDetail(id)` - Получить элемент по ID
|
|
406
|
+
- `create(data)` - Создать новый элемент
|
|
407
|
+
- `update(id, data)` - Обновить элемент
|
|
408
|
+
- `delete(id)` - Удалить элемент
|
|
409
|
+
|
|
410
|
+
### Column
|
|
411
|
+
|
|
412
|
+
Конфигурация колонки таблицы.
|
|
413
|
+
|
|
414
|
+
```tsx
|
|
415
|
+
interface Column<T> {
|
|
416
|
+
key: string // Уникальный ключ колонки
|
|
417
|
+
title: string // Заголовок колонки
|
|
418
|
+
dataIndex?: string // Поле данных для отображения
|
|
419
|
+
render?: (value: any, record: T, index: number) => React.ReactNode // Кастомный рендер
|
|
420
|
+
width?: number | string // Ширина колонки
|
|
421
|
+
align?: 'left' | 'center' | 'right' // Выравнивание
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### FormField
|
|
426
|
+
|
|
427
|
+
Конфигурация поля формы.
|
|
428
|
+
|
|
429
|
+
```tsx
|
|
430
|
+
interface FormField {
|
|
431
|
+
name: string // Имя поля
|
|
432
|
+
label: string // Метка поля
|
|
433
|
+
type?: 'text' | 'email' | 'number' | 'password' | 'textarea' | 'select' | 'checkbox' | 'radio'
|
|
434
|
+
options?: Array<{ value: string | number; label: string }> // Опции для select/radio
|
|
435
|
+
required?: boolean // Обязательное поле
|
|
436
|
+
placeholder?: string // Подсказка
|
|
437
|
+
disabled?: boolean // Отключено
|
|
438
|
+
}
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
## Разработка
|
|
442
|
+
|
|
443
|
+
```bash
|
|
444
|
+
# Установка зависимостей
|
|
445
|
+
npm install
|
|
446
|
+
|
|
447
|
+
# Сборка библиотеки
|
|
448
|
+
npm run build
|
|
449
|
+
|
|
450
|
+
# Запуск демо приложения
|
|
451
|
+
npm run demo
|
|
452
|
+
|
|
453
|
+
# Линтинг
|
|
454
|
+
npm run lint
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
## Публикация в npm
|
|
458
|
+
|
|
459
|
+
```bash
|
|
460
|
+
# Убедитесь что все изменения закоммичены
|
|
461
|
+
git add .
|
|
462
|
+
git commit -m "Prepare for release"
|
|
463
|
+
|
|
464
|
+
# Обновите версию (если нужно)
|
|
465
|
+
npm version patch # или minor, major
|
|
466
|
+
|
|
467
|
+
# Соберите библиотеку
|
|
468
|
+
npm run build
|
|
469
|
+
|
|
470
|
+
# Опубликуйте
|
|
471
|
+
npm publish
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
## Лицензия
|
|
475
|
+
|
|
476
|
+
MIT
|
|
477
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { CrudService } from '../../utils/crud';
|
|
3
|
+
import { Column } from '../Table/DataTable';
|
|
4
|
+
import { FormField } from '../CRUD/CrudForm';
|
|
5
|
+
|
|
6
|
+
export interface AdminModel<T = any> {
|
|
7
|
+
name: string;
|
|
8
|
+
label: string;
|
|
9
|
+
service: CrudService<T>;
|
|
10
|
+
columns: Column<T>[];
|
|
11
|
+
fields: FormField[];
|
|
12
|
+
getItemId?: (item: T) => string | number;
|
|
13
|
+
}
|
|
14
|
+
export interface AdminConfig {
|
|
15
|
+
title?: string;
|
|
16
|
+
logo?: React.ReactNode;
|
|
17
|
+
models: AdminModel[];
|
|
18
|
+
login?: {
|
|
19
|
+
onSubmit: (username: string, password: string) => Promise<void> | void;
|
|
20
|
+
};
|
|
21
|
+
user?: {
|
|
22
|
+
name?: string;
|
|
23
|
+
onLogout?: () => void;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export declare const AdminPanel: React.FC<AdminConfig>;
|
|
27
|
+
//# sourceMappingURL=AdminPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminPanel.d.ts","sourceRoot":"","sources":["../../../src/components/AdminPanel/AdminPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAWlD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEjD,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,GAAG;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;IACvB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;IACpB,MAAM,EAAE,SAAS,EAAE,CAAA;IACnB,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,MAAM,CAAA;CACzC;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,KAAK,CAAC,EAAE;QACN,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;KACvE,CAAA;IACD,IAAI,CAAC,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;KACtB,CAAA;CACF;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CA4J5C,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
|
|
3
|
+
export type BadgeVariant = 'default' | 'primary' | 'success' | 'warning' | 'error';
|
|
4
|
+
export interface BadgeProps {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
variant?: BadgeVariant;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const Badge: React.FC<BadgeProps>;
|
|
10
|
+
//# sourceMappingURL=Badge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../../src/components/Badge/Badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;AAElF,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CActC,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface FormField {
|
|
2
|
+
name: string;
|
|
3
|
+
label: string;
|
|
4
|
+
type?: 'text' | 'email' | 'number' | 'password' | 'textarea' | 'select' | 'checkbox' | 'radio';
|
|
5
|
+
options?: Array<{
|
|
6
|
+
value: string | number;
|
|
7
|
+
label: string;
|
|
8
|
+
}>;
|
|
9
|
+
required?: boolean;
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
value?: any;
|
|
13
|
+
}
|
|
14
|
+
export interface CrudFormProps<T = any> {
|
|
15
|
+
fields: FormField[];
|
|
16
|
+
initialValues?: Partial<T>;
|
|
17
|
+
onSubmit: (values: Partial<T>) => Promise<void> | void;
|
|
18
|
+
onCancel?: () => void;
|
|
19
|
+
loading?: boolean;
|
|
20
|
+
title?: string;
|
|
21
|
+
submitLabel?: string;
|
|
22
|
+
cancelLabel?: string;
|
|
23
|
+
className?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function CrudForm<T = any>({ fields, initialValues, onSubmit, onCancel, loading, title, submitLabel, cancelLabel, className, }: CrudFormProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
//# sourceMappingURL=CrudForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CrudForm.d.ts","sourceRoot":"","sources":["../../../src/components/CRUD/CrudForm.tsx"],"names":[],"mappings":"AASA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAA;IAC9F,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,GAAG,CAAA;CACZ;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,GAAG;IACpC,MAAM,EAAE,SAAS,EAAE,CAAA;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;IAC1B,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACtD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,EAChC,MAAM,EACN,aAAkB,EAClB,QAAQ,EACR,QAAQ,EACR,OAAe,EACf,KAAK,EACL,WAAyB,EACzB,WAAsB,EACtB,SAAc,GACf,EAAE,aAAa,CAAC,CAAC,CAAC,2CAgJlB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { Column } from '../Table/DataTable';
|
|
3
|
+
import { CrudService } from '../../utils/crud';
|
|
4
|
+
|
|
5
|
+
export interface CrudListProps<T = any> {
|
|
6
|
+
service: CrudService<T>;
|
|
7
|
+
columns: Column<T>[];
|
|
8
|
+
refreshKey?: number | string;
|
|
9
|
+
title?: string;
|
|
10
|
+
onCreate?: () => void;
|
|
11
|
+
onEdit?: (item: T) => void;
|
|
12
|
+
onDelete?: (item: T) => Promise<void>;
|
|
13
|
+
getItemId?: (item: T) => string | number;
|
|
14
|
+
actions?: (item: T) => React.ReactNode;
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function CrudList<T = any>({ service, columns, title, onCreate, onEdit, onDelete, getItemId, actions, className, refreshKey, }: CrudListProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
//# sourceMappingURL=CrudList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CrudList.d.ts","sourceRoot":"","sources":["../../../src/components/CRUD/CrudList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAElD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAIhD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,GAAG;IACpC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAA;IACvB,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAA;IAC1B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,GAAG,MAAM,CAAA;IACxC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAA;IACtC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,EAChC,OAAO,EACP,OAAO,EACP,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,SAA2C,EAC3C,OAAO,EACP,SAAc,EACd,UAAU,GACX,EAAE,aAAa,CAAC,CAAC,CAAC,2CAsIlB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface CardProps {
|
|
4
|
+
title?: string;
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
footer?: React.ReactNode;
|
|
7
|
+
className?: string;
|
|
8
|
+
style?: React.CSSProperties;
|
|
9
|
+
}
|
|
10
|
+
export declare const Card: React.FC<CardProps>;
|
|
11
|
+
//# sourceMappingURL=Card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../src/components/Card/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;CAC5B;AAED,eAAO,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAoBpC,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
4
|
+
variant?: 'primary' | 'default' | 'success' | 'danger' | 'ghost';
|
|
5
|
+
size?: 'small' | 'medium' | 'large';
|
|
6
|
+
loading?: boolean;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export declare const Button: React.FC<ButtonProps>;
|
|
10
|
+
//# sourceMappingURL=Button.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/Form/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,WAAW,WAAY,SAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IAChF,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAA;IAChE,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAA;IACnC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CA8BxC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../../src/components/Form/Checkbox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC9F,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAqB5C,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
|
4
|
+
error?: boolean;
|
|
5
|
+
label?: string;
|
|
6
|
+
helperText?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const Input: React.FC<InputProps>;
|
|
9
|
+
//# sourceMappingURL=Input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../../src/components/Form/Input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CA4BtC,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
|
|
4
|
+
required?: boolean;
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export declare const Label: React.FC<LabelProps>;
|
|
8
|
+
//# sourceMappingURL=Label.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Label.d.ts","sourceRoot":"","sources":["../../../src/components/Form/Label.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,MAAM,WAAW,UAAW,SAAQ,KAAK,CAAC,mBAAmB,CAAC,gBAAgB,CAAC;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAC1B;AAED,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CAetC,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface LoginFormProps {
|
|
4
|
+
onSubmit: (username: string, password: string) => Promise<void> | void;
|
|
5
|
+
loading?: boolean;
|
|
6
|
+
error?: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const LoginForm: React.FC<LoginFormProps>;
|
|
10
|
+
//# sourceMappingURL=LoginForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginForm.d.ts","sourceRoot":"","sources":["../../../src/components/Form/LoginForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AAIvC,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACtE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAiE9C,CAAA"}
|