@boobooking/dashboard-ui-components 0.11.0 → 0.12.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 CHANGED
@@ -37,7 +37,7 @@ createApp(App).use(dashboardUi, {
37
37
  браузеру. Без `navigate` браузер идёт по ссылке сам.
38
38
 
39
39
  `navigate` получает адрес ровно таким, каким он лежит в компоненте:
40
- `Pagination` отдаёт `links` Laravel как есть, а это абсолютные URL. С Vue
40
+ пагинация `DataTable` отдаёт `links` Laravel как есть, а это абсолютные URL. С Vue
41
41
  Router приложение само превращает их в маршрут, например
42
42
  `new URL(href).pathname + search`, и только потом зовёт `router.push`.
43
43
 
@@ -50,12 +50,15 @@ Vue не ниже 3.5, ESM, сборщик, умеющий импорт CSS из
50
50
  Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в CSS приложения
51
51
  пакету не нужны.
52
52
 
53
+ Меню `DropdownButtonWithAction` стоит на Popover API браузера: Safari 17+,
54
+ Chrome 114+, Firefox 125+. В браузерах старше меню видно в потоке всегда.
55
+
53
56
  ## Компоненты
54
57
 
55
58
  Пакет экспортирует семнадцать компонентов: `Popup`, `Dot`, `PickDay`,
56
59
  `RussianMobileFilter`, `Search`, `SelectDateInterval`, `SelectSingle`,
57
60
  `SmallBadge`, `ErrorMessages`, `Closer`, `DownloadLink`,
58
- `ConfirmationModal`, `DropdownButtonWithAction`, `Pagination`,
61
+ `ConfirmationModal`, `DropdownButtonWithAction`, `DataTable`,
59
62
  `NavigationMenuElement`, `PageCard`, `NotificationMessage` и плагин
60
63
  `dashboardUi`. В архив пакета (`files: ["dist"]`) исходники не попадают,
61
64
  поэтому контракт каждого компонента — здесь и в playground, а не в исходном
@@ -137,7 +140,10 @@ Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в C
137
140
  `changed` — через 400 мс паузы после ввода, начиная с третьей цифры (раньше
138
141
  событие не летит вовсе), а также сразу — без дебаунса — при опустевшем поле,
139
142
  по клику на ластик, по Enter и по уходу фокуса. Дублей не бывает: компонент
140
- помнит последнее отправленное значение и не шлёт его повторно.
143
+ помнит последнее отправленное значение и не шлёт его повторно. При
144
+ размонтировании `changed` не летит, даже если поле было в фокусе: набранный,
145
+ но ещё не отправленный номер не отправляется, иначе запрос страницы, с
146
+ которой уходят, вернул бы на неё.
141
147
 
142
148
  ### Search
143
149
 
@@ -309,28 +315,95 @@ ConfirmationModal нет v-model».
309
315
  | `lang` | `String` | язык плагина | `"ru"` или `"en"` |
310
316
 
311
317
  Событие: `update:modelValue` — только когда меню открыл или закрыл сам
312
- компонент: клик по стрелке, клик вне меню, Escape. Значение, пришедшее от
313
- родителя, компонент принимает молча: ответное событие вернуло бы родителю его
314
- же решение. Без `v-model` меню работает само по себе.
315
-
316
- ### Pagination
317
-
318
- Переход на предыдущую и следующую страницу и строка «Показаны результаты X - Y
319
- из Z» для списков на Laravel API Resource.
320
-
321
- <pagination class="mt-6" :links="orders.links" :meta="orders.meta" />
318
+ компонент или браузер: клик по стрелке, клик вне меню, Escape, клик
319
+ по пункту меню, прокрутка, изменение размера окна. Значение, пришедшее
320
+ от родителя, компонент принимает молча: ответное событие вернуло бы
321
+ родителю его же решение. Без `v-model` меню работает само по себе.
322
+
323
+ Меню открывается в верхнем слое браузера (Popover API): его не обрезает
324
+ таблица с горизонтальной прокруткой, и оно стоит поверх страницы. Правый
325
+ край меню — по правому краю стрелки; меню открывается вниз или вверх —
326
+ где больше места, сужается у левого края окна и закрывается кликом
327
+ по любому пункту, прокруткой страницы или таблицы и изменением размера
328
+ окна. Открытие другого меню закрывает предыдущее.
329
+
330
+ ### DataTable
331
+
332
+ Список данных: бейдж «Найдено X: N», таблица в карточке с горизонтальной
333
+ прокруткой, пустое состояние и пагинация — по ответу Laravel API Resource
334
+ `{ data, meta, links }`. Особые ячейки — слотами.
335
+
336
+ <data-table
337
+ :rows="orderObjects"
338
+ :columns="columns"
339
+ row-key="uuid"
340
+ :meta="orders.meta"
341
+ :links="orders.links"
342
+ found-text="Найдено ордеров"
343
+ empty-text="Не найдено ордеров"
344
+ >
345
+ <template #results-actions>
346
+ <download-link :url="exportUrl" title="скачать xlsx" />
347
+ </template>
348
+ <template #cell-status="{ row }">
349
+ <small-badge :text="row.statusLabel" :color="row.statusColor" />
350
+ </template>
351
+ </data-table>
352
+
353
+ columns: [
354
+ { key: 'phone', label: 'Телефон' },
355
+ { key: 'vendor', label: 'Вендор / Сертификат', secondary: (row) => row.certificate },
356
+ { key: 'amount', label: 'Номинал', align: 'right', muted: true },
357
+ { key: 'status', label: 'Статус' },
358
+ { key: 'cost', label: 'Стоимость', align: 'right', visible: isAdmin },
359
+ { key: 'actions', align: 'right', narrow: true },
360
+ ]
322
361
 
323
362
  | Проп | Тип | По умолчанию | Описание |
324
363
  | --- | --- | --- | --- |
325
- | `links` | `Object` | обязателен | `{ prev, next }` — адреса соседних страниц или `null` |
326
- | `meta` | `Object` | обязателен | `{ from, to, total }` |
327
- | `lang` | `String` | язык плагина | `"ru"` или `"en"` |
328
-
329
- Если записей нет — `meta` не задан или `meta.total` не больше нуля, —
330
- компонент ничего не рисует. Строка «Показаны результаты» — только когда в
331
- `meta` есть числовые `from` и `to`. Кнопка — только при непустом адресе в
332
- `links.prev` / `links.next`; при `links: null` остаётся одна строка
333
- результатов. Ссылки — через `navigate` плагина. Событий нет.
364
+ | `rows` | `Array` | обязателен | Строки: обычные объекты или модели страницы |
365
+ | `columns` | `Array` | обязателен | Столбцы, см. ниже |
366
+ | `rowKey` | `String`, `Function` | обязателен | Имя поля ключа строки или `row => ключ` |
367
+ | `meta` | `Object` | `null` | `{ from, to, total }` пагинации Laravel; есть — внизу пагинация, а число в бейдже — `total` |
368
+ | `links` | `Object` | `null` | `{ prev, next }` пагинации Laravel |
369
+ | `foundText` | `String` | `null` | «Найдено ордеров» → бейдж «Найдено ордеров: 100», когда записи есть |
370
+ | `emptyText` | `String` | `null` | «Не найдено ордеров» — бейдж, когда записей нет |
371
+ | `variant` | `String` | `"page"` | `"page"` — отдельная карточка с тенью; `"card"` — таблица внутри карточки страницы, только линия сверху |
372
+ | `rowColor` | `Function` | `null` | `row => 'red' \| 'green' \| null` — цвет строки вместо полосатости |
373
+ | `lang` | `String` | язык плагина | `"ru"` или `"en"` — тексты пагинации |
374
+
375
+ Столбец:
376
+
377
+ | Поле | По умолчанию | Описание |
378
+ | --- | --- | --- |
379
+ | `key` | обязателен | Имя слота `cell-<key>` и поле значения по умолчанию |
380
+ | `label` | `""` | Заголовок; пустой — у столбца действий |
381
+ | `value` | `row => row[key]` | Основной текст ячейки. У моделей с геттерами — `(row) => row.getName()` |
382
+ | `secondary` | нет | `row => текст` — серая вторая строка |
383
+ | `muted` | `false` | Основной текст серый — даты, статусы, суммы |
384
+ | `align` | `"left"` | `"left"`, `"center"` или `"right"` — для заголовка и ячеек |
385
+ | `wrap` | `false` | Текст ячеек переносится |
386
+ | `narrow` | `false` | Ширина по содержимому — столбцы действий и иконок |
387
+ | `visible` | `true` | `false` — столбца нет вовсе: ни заголовка, ни ячеек, ни слота |
388
+
389
+ Скрытый столбец — только отображение: данные, которые пользователю видеть
390
+ нельзя, сервер не отдаёт.
391
+
392
+ Слоты: `#cell-<key>="{ row, index }"` — своя разметка ячейки (отступы,
393
+ выравнивание и перенос ячейки остаются за компонентом);
394
+ `#results-actions` — рядом с бейджем, только когда записи есть.
395
+
396
+ Пагинация: строка «Показаны результаты X - Y из Z» есть, только когда
397
+ `meta.from` и `meta.to` — числа; «Предыдущая» и «Следующая» — только когда
398
+ `links.prev` и `links.next` — непустые строки (`null`, пустая строка и
399
+ отсутствующий ключ — кнопки нет). Пагинации нет вовсе, когда `meta` не
400
+ передан или `meta.total` не больше нуля.
401
+
402
+ Записей нет — только бейдж с `emptyText`, без таблицы и пагинации; без
403
+ текстов — ничего. Страница за последней (`total` больше нуля, `rows` пуст) —
404
+ бейдж и пагинация без таблицы. Строки выравниваются по верху. Широкая
405
+ таблица прокручивается в своей карточке. Ссылки пагинации — через
406
+ `navigate` плагина. Событий нет.
334
407
 
335
408
  ### NavigationMenuElement
336
409
 
@@ -462,7 +535,7 @@ sm:rounded-lg`, `box-sizing: border-box`. Отступов у неё нет: ф
462
535
  | `DropdownButtonWithAction` — подпись стрелки для скринридера | Открыть меню | Open menu |
463
536
  | `PickDay` — месяцы, дни недели, кнопки календаря | по-русски | in English |
464
537
  | `SelectDateInterval` — подсказки полей | от / до | from / to |
465
- | `Pagination` | Предыдущая / Следующая / Показаны результаты X - Y из Z | Previous / Next / Showing X - Y of Z results |
538
+ | `DataTable` — пагинация | Предыдущая / Следующая / Показаны результаты X - Y из Z | Previous / Next / Showing X - Y of Z results |
466
539
  | `PageCard` — доступное имя крестика | Назад | Back |
467
540
  | `NotificationMessage` — подпись крестика для скринридера | Закрыть | Close |
468
541
 
@@ -519,7 +592,7 @@ Inertia SSR), а серверная разметка гидратируется
519
592
  `followLink($event, href)` миксина `withNavigation`, который отдаёт его
520
593
  `navigate` плагина. Ни Inertia, ни роутер пакет не импортирует. Исключение —
521
594
  `DownloadLink`: это обычная ссылка браузера, скачивающая файл, и через
522
- `navigate` она не идёт. Через `navigate` ходят `Pagination` и
595
+ `navigate` она не идёт. Через `navigate` ходят `DataTable` (его пагинация) и
523
596
  `NavigationMenuElement`.
524
597
  - Компонент обращается к `window`, `document` и другим API браузера только
525
598
  в `mounted()`, `beforeUnmount()` и обработчиках событий; загрузка модуля,
@@ -577,6 +650,19 @@ Tailwind, `@tailwindcss/forms` и типографикой, как у потре
577
650
  Правила номера телефона в `RussianMobileFilter` — российские; язык текстов
578
651
  задаётся, см. «Языки».
579
652
 
653
+ ## Обновление с 0.11
654
+
655
+ - `Pagination` больше не экспортируется. Страница, импортирующая её
656
+ из пакета, переводит свой список на `DataTable`: бейдж «Найдено»,
657
+ таблица, пустое состояние и пагинация теперь в одном компоненте.
658
+ - Меню `DropdownButtonWithAction` открывается в верхнем слое браузера
659
+ и закрывается кликом по пункту. Страницы, которые сами закрывали меню
660
+ через `v-model` перед открытием модалки, работают как раньше. Клик по пункту
661
+ теперь закрывает меню и эмитит `update:modelValue(false)`: если обработчик
662
+ закрытия на странице сбрасывает состояние, на которое опирается модалка,
663
+ цель модалки держат в отдельном поле (как certificates: `editUser` отдельно
664
+ от `activeUser`).
665
+
580
666
  ## Ограничение
581
667
 
582
668
  Утилиты пакета собраны с префиксом `bb`: классы внутри компонентов — вида