@panneau/lists 5.0.0-alpha.16 → 5.0.0-alpha.18

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.
Files changed (68) hide show
  1. package/README.md +14 -14
  2. package/dist/ListSkeleton.d.ts +3 -1
  3. package/dist/ListSkeleton.d.ts.map +1 -1
  4. package/dist/ListSkeleton.js +34 -30
  5. package/dist/ListSkeleton.js.map +1 -1
  6. package/dist/ListView.d.ts +10 -3
  7. package/dist/ListView.d.ts.map +1 -1
  8. package/dist/ListView.js +44 -35
  9. package/dist/ListView.js.map +1 -1
  10. package/dist/actions/ActionButton.d.ts +7 -1
  11. package/dist/actions/ActionButton.d.ts.map +1 -1
  12. package/dist/actions/ActionButton.js +74 -72
  13. package/dist/actions/ActionButton.js.map +1 -1
  14. package/dist/actions/Actions.css +12 -0
  15. package/dist/actions/Actions.module.js +6 -2
  16. package/dist/actions/Actions.module.js.map +1 -1
  17. package/dist/actions/ConfirmDialog.d.ts +5 -1
  18. package/dist/actions/ConfirmDialog.d.ts.map +1 -1
  19. package/dist/actions/ConfirmDialog.js +7 -3
  20. package/dist/actions/ConfirmDialog.js.map +1 -1
  21. package/dist/actions/RowActions.d.ts +21 -4
  22. package/dist/actions/RowActions.d.ts.map +1 -1
  23. package/dist/actions/RowActions.js +149 -84
  24. package/dist/actions/RowActions.js.map +1 -1
  25. package/dist/actions/fit.d.ts +25 -0
  26. package/dist/actions/fit.d.ts.map +1 -0
  27. package/dist/actions/fit.js +197 -0
  28. package/dist/actions/fit.js.map +1 -0
  29. package/dist/actions/icons.d.ts +5 -0
  30. package/dist/actions/icons.d.ts.map +1 -1
  31. package/dist/actions/icons.js +15 -1
  32. package/dist/actions/icons.js.map +1 -1
  33. package/dist/displays/Displays.css +12 -1
  34. package/dist/displays/Displays.module.js +6 -2
  35. package/dist/displays/Displays.module.js.map +1 -1
  36. package/dist/displays/displays.d.ts +12 -3
  37. package/dist/displays/displays.d.ts.map +1 -1
  38. package/dist/displays/displays.js +223 -66
  39. package/dist/displays/displays.js.map +1 -1
  40. package/dist/images.d.ts +3 -2
  41. package/dist/images.d.ts.map +1 -1
  42. package/dist/images.js +24 -3
  43. package/dist/images.js.map +1 -1
  44. package/dist/index.d.ts +1 -1
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +3 -3
  47. package/dist/inline/InlineCell.d.ts +3 -1
  48. package/dist/inline/InlineCell.d.ts.map +1 -1
  49. package/dist/inline/InlineCell.js +153 -134
  50. package/dist/inline/InlineCell.js.map +1 -1
  51. package/dist/layouts/CardsLayout.d.ts.map +1 -1
  52. package/dist/layouts/CardsLayout.js +90 -93
  53. package/dist/layouts/CardsLayout.js.map +1 -1
  54. package/dist/layouts/GalleryLayout.css +7 -0
  55. package/dist/layouts/GalleryLayout.d.ts.map +1 -1
  56. package/dist/layouts/GalleryLayout.js +76 -53
  57. package/dist/layouts/GalleryLayout.js.map +1 -1
  58. package/dist/layouts/GalleryLayout.module.js.map +1 -1
  59. package/dist/layouts/TableLayout.css +31 -0
  60. package/dist/layouts/TableLayout.d.ts +4 -3
  61. package/dist/layouts/TableLayout.d.ts.map +1 -1
  62. package/dist/layouts/TableLayout.js +158 -98
  63. package/dist/layouts/TableLayout.js.map +1 -1
  64. package/dist/layouts/TableLayout.module.js +5 -1
  65. package/dist/layouts/TableLayout.module.js.map +1 -1
  66. package/dist/types.d.ts +4 -1
  67. package/dist/types.d.ts.map +1 -1
  68. package/package.json +7 -7
package/README.md CHANGED
@@ -77,23 +77,23 @@ const { data, isFetching, error } = useResourceList('pages', query); // @panneau
77
77
 
78
78
  ## What a list does
79
79
 
80
- | Feature | How |
81
- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
82
- | Columns | `item[id]` shown with a display: the column's `display`, else text. Localized values in the UI's locale. `render` for a cell of its own |
83
- | Displays | `text`, `textarea`, `slug`, `richtext`, `number`, `boolean`, `date`, `datetime`, `time`, `select`, `relation`, `url`, `email`, `color`, `media` |
84
- | Columns | A "Columns" menu shows, hides and orders them: `hidden` columns are shown when the user picks them, and `hideable: false` ones always are. In the view of the list state |
85
- | Layouts | `table`, `cards`, `gallery` (on `itemImage`) and `calendar` (with `calendar`), the first of `layouts` being the default, in the view of the list state. On narrow lists, table rows stack and show the label of each value, and the calendar lists its days with items ([0044](../../docs/decisions/0044-gallery-and-calendar.md)) |
86
- | Sorting | Sortable column headers (`aria-sort`), and a select for cards and phones |
87
- | Filters | `text`, `select`, `toggle`, `date`, `date-range` (sent as bounds: `filter[id][from]`, `filter[id][to]`), `relation`, with chips for the active filters and the search |
88
- | Pagination | With `total`: the range, previous and next pages, and the page size (`perPageOptions`) |
89
- | Selection | Checkboxes, the page, then "select all N items", which selects every item matching the query, with exceptions |
90
- | Actions | `row` (buttons), `menu` (the row's menu), `toolbar` (selection and resource actions), with `confirm`, hidden by abilities ([0011](../../docs/decisions/0011-permissions.md)) |
91
- | Editing | Columns of `inlineEdit` edit their field in place in the table (`text`, `number`, `select`, `boolean`, `date`), on items that can be updated: `onInlineEdit` saves the one field ([0043](../../docs/decisions/0043-inline-editing.md)) |
92
- | States | Skeleton rows of the columns while `items` is `undefined`, an error with a retry, an empty message, and "no results" with a button that clears the filters |
80
+ | Feature | How |
81
+ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
82
+ | Columns | `item[id]` shown with a display: the column's `display`, else text. Localized values in the UI's locale. `render` for a cell of its own |
83
+ | Displays | `text`, `textarea`, `slug`, `richtext`, `number`, `boolean`, `date`, `datetime`, `time`, `select`, `relation`, `url`, `email`, `color`, `media` |
84
+ | Columns | A "Columns" menu shows, hides and orders them: `hidden` columns are shown when the user picks them, and `hideable: false` ones always are. In the view of the list state |
85
+ | Layouts | `table`, `cards`, `gallery` (on `itemImage`) and `calendar` (with `calendar`), the first of `layouts` being the default, in the view of the list state. With `itemImage`, the table starts each title with a thumbnail ([0061](../../docs/decisions/0061-item-images-in-lists.md)). On narrow lists, table rows stack and show the label of each value, and the calendar lists its days with items ([0044](../../docs/decisions/0044-gallery-and-calendar.md)) |
86
+ | Sorting | Sortable column headers (`aria-sort`), and a select for cards and phones |
87
+ | Filters | `text`, `select`, `toggle`, `date`, `date-range` (sent as bounds: `filter[id][from]`, `filter[id][to]`), `relation`, with chips for the active filters and the search |
88
+ | Pagination | With `total`: the range, previous and next pages, and the page size (`perPageOptions`) |
89
+ | Selection | Checkboxes, the page, then "select all N items", which selects every item matching the query, with exceptions |
90
+ | Actions | `row` (buttons), `menu` (the row's menu), `toolbar` (selection and resource actions), with `confirm`, hidden by abilities ([0011](../../docs/decisions/0011-permissions.md)) |
91
+ | Editing | Columns of `inlineEdit` edit their field in place in the table (`text`, `number`, `select`, `boolean`, `date`), on items that can be updated: `onInlineEdit` saves the one field ([0043](../../docs/decisions/0043-inline-editing.md)) |
92
+ | States | Skeleton rows of the columns while `items` is `undefined`, an error with a retry, an empty message, and "no results" with a button that clears the filters |
93
93
 
94
94
  An action shows the icon it names (`"icon": "send"`, through `getNamedIcon()` of `@panneau/ui`, which needs an `iconLoader` on `PanneauRoot`, such as `lucideIconLoader` of `@panneau/ui/named-icons`), or the icon of a built-in action (`edit`, `delete`…). Actions written in code can get icon components by id instead, which win over names: `actionIcons={{ archive: Archive }}`.
95
95
 
96
- Lists confirm an action when it has `confirm` (its title and message are ICU messages with `{count}`), or when some selected items don't allow it. For every item matching a query, they only know the current page: with `previewAction` (`useActionPreview()` of `@panneau/actions`), an action that declares `dryRun` asks the backend first, and the confirmation gives its count of skipped items. Then they call `onAction` with the action, its scope, the item or the `Selection` of the protocol, the count and the skipped items. A promise shows the action as pending; when it rejects, a toast says that it failed. After a selection action, the selection is cleared.
96
+ Lists confirm an action when it has `confirm` (its title and message are ICU messages with `{count}`), or when some selected items don't allow it. An `undoable` action runs without a confirmation, unless it sets one, up to `UNDO_LIMIT` items (100), counted from the selection or the dry run: its toast offers "Undo" instead (`asksConfirmation()` of `@panneau/core`, [decision 0063](../../docs/decisions/0063-undo-instead-of-a-confirmation.md)). A value changed in place says so in a toast whose "Undo" saves the previous value the same way, with the version the save got. For every item matching a query, they only know the current page: with `previewAction` (`useActionPreview()` of `@panneau/actions`), an action that declares `dryRun` asks the backend first, and the confirmation gives its count of skipped items. Then they call `onAction` with the action, its scope, the item or the `Selection` of the protocol, the count and the skipped items. A promise shows the action as pending; when it rejects, a toast says that it failed. After a selection action, the selection is cleared.
97
97
 
98
98
  A `relation` filter keeps ids in the query (`filter[author]=7`). Its chip and picker show the labels of the items it picked, and those of ids from the URL once the relation source's `resolve()` gives them.
99
99
 
@@ -6,6 +6,8 @@ export interface ListSkeletonProps {
6
6
  perPage: number | undefined;
7
7
  sort: readonly string[];
8
8
  label: string;
9
+ /** Whether items have an image: the table draws the placeholder of their thumbnails. */
10
+ withImages?: boolean;
9
11
  }
10
12
  /**
11
13
  * The first page of a list that loads (decision 0034): the list's own layout, with its columns
@@ -13,5 +15,5 @@ export interface ListSkeletonProps {
13
15
  * inert and hidden: its headers can't be used before the items are there, and the status message
14
16
  * of the region says that the list loads.
15
17
  */
16
- export declare function ListSkeleton({ Layout, columns, perPage, sort, label }: ListSkeletonProps): import("react").JSX.Element;
18
+ export declare function ListSkeleton({ Layout, columns, perPage, sort, label, withImages, }: ListSkeletonProps): import("react").JSX.Element;
17
19
  //# sourceMappingURL=ListSkeleton.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ListSkeleton.d.ts","sourceRoot":"","sources":["../src/ListSkeleton.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAY,eAAe,EAAE,MAAM,SAAS,CAAC;AAUrE,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,oDAAoD;IACpD,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,iBAAiB,+BAgCxF"}
1
+ {"version":3,"file":"ListSkeleton.d.ts","sourceRoot":"","sources":["../src/ListSkeleton.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAY,eAAe,EAAE,MAAM,SAAS,CAAC;AAUrE,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,oDAAoD;IACpD,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,wFAAwF;IACxF,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EACzB,MAAM,EACN,OAAO,EACP,OAAO,EACP,IAAI,EACJ,KAAK,EACL,UAAkB,GACrB,EAAE,iBAAiB,+BAiCnB"}
@@ -23,37 +23,39 @@ var nothing = () => void 0;
23
23
  * of the region says that the list loads.
24
24
  */
25
25
  function ListSkeleton(t0) {
26
- const $ = c(17);
27
- const { Layout, columns, perPage, sort, label } = t0;
26
+ const $ = c(18);
27
+ const { Layout, columns, perPage, sort, label, withImages: t1 } = t0;
28
+ const withImages = t1 === void 0 ? false : t1;
28
29
  const intl = usePanneauIntl();
29
30
  const rows = Math.max(1, Math.min(perPage ?? MAX_ROWS, MAX_ROWS));
30
- let t1;
31
+ let t2;
31
32
  if ($[0] !== rows) {
32
- t1 = Array.from({ length: rows }, _temp);
33
+ t2 = Array.from({ length: rows }, _temp);
33
34
  $[0] = rows;
34
- $[1] = t1;
35
- } else t1 = $[1];
36
- const items = t1;
37
- let t2;
35
+ $[1] = t2;
36
+ } else t2 = $[1];
37
+ const items = t2;
38
+ let t3;
38
39
  if ($[2] !== columns || $[3] !== items) {
39
- t2 = (item, column) => {
40
+ t3 = (item, column) => {
40
41
  const offset = items.indexOf(item) + columns.indexOf(column);
41
42
  return /* @__PURE__ */ jsx(Skeleton, { width: WIDTHS[offset % WIDTHS.length] });
42
43
  };
43
44
  $[2] = columns;
44
45
  $[3] = items;
45
- $[4] = t2;
46
- } else t2 = $[4];
47
- const renderValue = t2;
48
- let t3;
46
+ $[4] = t3;
47
+ } else t3 = $[4];
48
+ const renderValue = t3;
49
+ let t4;
49
50
  if ($[5] !== intl) {
50
- t3 = intl.formatMessage(messages.loading);
51
+ t4 = intl.formatMessage(messages.loading);
51
52
  $[5] = intl;
52
- $[6] = t3;
53
- } else t3 = $[6];
54
- let t4;
55
- if ($[7] !== Layout || $[8] !== columns || $[9] !== items || $[10] !== label || $[11] !== renderValue || $[12] !== sort) {
56
- t4 = /* @__PURE__ */ jsx("div", {
53
+ $[6] = t4;
54
+ } else t4 = $[6];
55
+ const t5 = withImages ? none : void 0;
56
+ let t6;
57
+ if ($[7] !== Layout || $[8] !== columns || $[9] !== items || $[10] !== label || $[11] !== renderValue || $[12] !== sort || $[13] !== t5) {
58
+ t6 = /* @__PURE__ */ jsx("div", {
57
59
  inert: true,
58
60
  "aria-hidden": "true",
59
61
  children: /* @__PURE__ */ jsx(Layout, {
@@ -62,6 +64,7 @@ function ListSkeleton(t0) {
62
64
  renderValue,
63
65
  getItemLabel: _temp2,
64
66
  getItemHref: none,
67
+ getItemImage: t5,
65
68
  isCurrent: _temp3,
66
69
  selectable: false,
67
70
  isSelected: _temp4,
@@ -79,19 +82,20 @@ function ListSkeleton(t0) {
79
82
  $[10] = label;
80
83
  $[11] = renderValue;
81
84
  $[12] = sort;
82
- $[13] = t4;
83
- } else t4 = $[13];
84
- let t5;
85
- if ($[14] !== t3 || $[15] !== t4) {
86
- t5 = /* @__PURE__ */ jsx(LoadingRegion, {
87
- label: t3,
88
- children: t4
85
+ $[13] = t5;
86
+ $[14] = t6;
87
+ } else t6 = $[14];
88
+ let t7;
89
+ if ($[15] !== t4 || $[16] !== t6) {
90
+ t7 = /* @__PURE__ */ jsx(LoadingRegion, {
91
+ label: t4,
92
+ children: t6
89
93
  });
90
- $[14] = t3;
91
94
  $[15] = t4;
92
- $[16] = t5;
93
- } else t5 = $[16];
94
- return t5;
95
+ $[16] = t6;
96
+ $[17] = t7;
97
+ } else t7 = $[17];
98
+ return t7;
95
99
  }
96
100
  function _temp4() {
97
101
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"ListSkeleton.js","names":["ReactNode","LoadingRegion","Skeleton","usePanneauIntl","messages","ListColumn","ListItem","ListLayoutEntry","MAX_ROWS","WIDTHS","none","nothing","undefined","ListSkeletonProps","Layout","columns","perPage","sort","label","ListSkeleton","t0","$","_c","intl","rows","Math","max","min","t1","Array","from","length","_temp","items","t2","item","column","offset","indexOf","renderValue","t3","formatMessage","loading","t4","_temp2","_temp3","_temp4","t5","item_0","id","_","index","String","_c"],"sources":["../src/ListSkeleton.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { LoadingRegion, Skeleton, usePanneauIntl } from '@panneau/ui';\n\nimport { messages } from './messages';\nimport type { ListColumn, ListItem, ListLayoutEntry } from './types';\n\n/** The most rows a skeleton draws: about what fits in a window. */\nconst MAX_ROWS = 10;\n/** Widths of the values, varied so the rows read as text. */\nconst WIDTHS = ['72%', '48%', '64%', '40%', '56%', '80%'];\n\nconst none = () => null;\nconst nothing = () => undefined;\n\nexport interface ListSkeletonProps {\n Layout: ListLayoutEntry;\n columns: readonly ListColumn[];\n /** The page size: as many rows, up to what fits. */\n perPage: number | undefined;\n sort: readonly string[];\n label: string;\n}\n\n/**\n * The first page of a list that loads (decision 0034): the list's own layout, with its columns\n * and a skeleton for each value, as many rows as the page size, up to what fits. The layout is\n * inert and hidden: its headers can't be used before the items are there, and the status message\n * of the region says that the list loads.\n */\nexport function ListSkeleton({ Layout, columns, perPage, sort, label }: ListSkeletonProps) {\n const intl = usePanneauIntl();\n const rows = Math.max(1, Math.min(perPage ?? MAX_ROWS, MAX_ROWS));\n const items: ListItem[] = Array.from({ length: rows }, (_, index) => ({\n id: `skeleton-${String(index)}`,\n }));\n const renderValue = (item: ListItem, column: ListColumn): ReactNode => {\n const offset = items.indexOf(item) + columns.indexOf(column);\n return <Skeleton width={WIDTHS[offset % WIDTHS.length]} />;\n };\n return (\n <LoadingRegion label={intl.formatMessage(messages.loading)}>\n <div inert aria-hidden=\"true\">\n <Layout\n items={items}\n columns={columns}\n renderValue={renderValue}\n getItemLabel={(item) => item.id}\n getItemHref={none}\n isCurrent={() => false}\n selectable={false}\n isSelected={() => false}\n onToggle={nothing}\n renderActions={none}\n sort={sort}\n onSort={nothing}\n label={label}\n pageSelection={null}\n />\n </div>\n </LoadingRegion>\n );\n}\n"],"mappings":";;;;;;AAQA,IAAMQ,WAAW;;AAEjB,IAAMC,SAAS;CAAC;CAAO;CAAO;CAAO;CAAO;CAAO;AAAK;AAExD,IAAMC,aAAa;AACnB,IAAMC,gBAAgBC,KAAAA;;;;;;;AAiBtB,SAAOO,aAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAsB,MAAA,EAAAR,QAAAC,SAAAC,SAAAC,MAAAC,UAAAE;CACzB,MAAAG,OAAapB,eAAe;CAC5B,MAAAqB,OAAaC,KAAIC,IAAK,GAAGD,KAAIE,IAAKX,WAAAR,UAAqBA,QAAQ,CAAC;CAAE,IAAAoB;CAAA,IAAAP,EAAA,OAAAG,MAAA;EACxCI,KAAAC,MAAKC,KAAM,EAAAC,QAAUP,KAAK,GAAGQ,KAErD;EAACX,EAAA,KAAAG;EAAAH,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAFH,MAAAY,QAA0BL;CAEtB,IAAAM;CAAA,IAAAb,EAAA,OAAAN,WAAAM,EAAA,OAAAY,OAAA;EACgBC,MAAAC,MAAAC,WAAA;GAChB,MAAAC,SAAeJ,MAAKK,QAASH,IAAI,IAAIpB,QAAOuB,QAASF,MAAM;GAAE,OACtD,oBAAC,UAAD,EAAiB,OAAA3B,OAAO4B,SAAS5B,OAAMsB,QAAQ,CAAA;EAAI;EAC7DV,EAAA,KAAAN;EAAAM,EAAA,KAAAY;EAAAZ,EAAA,KAAAa;CAAA,OAAAA,KAAAb,EAAA;CAHD,MAAAkB,cAAoBL;CAGlB,IAAAM;CAAA,IAAAnB,EAAA,OAAAE,MAAA;EAEwBiB,KAAAjB,KAAIkB,cAAerC,SAAQsC,OAAQ;EAACrB,EAAA,KAAAE;EAAAF,EAAA,KAAAmB;CAAA,OAAAA,KAAAnB,EAAA;CAAA,IAAAsB;CAAA,IAAAtB,EAAA,OAAAP,UAAAO,EAAA,OAAAN,WAAAM,EAAA,OAAAY,SAAAZ,EAAA,QAAAH,SAAAG,EAAA,QAAAkB,eAAAlB,EAAA,QAAAJ,MAAA;EACtD0B,KAAA,oBAAA,OAAA;GAAK,OAAA;GAAkB,eAAA;GACnB,UAAA,oBAAC,QAAD;IACWV;IACElB;IACIwB;IACC,cAAAK;IACDlC,aAAAA;IACF,WAAAmC;IACC,YAAA;IACA,YAAAC;IACFnC,UAAAA;IACKD,eAAAA;IACTO;IACEN,QAAAA;IACDO;IACQ,eAAA;GAAI,CAAA;EAErB,CAAA;EAAAG,EAAA,KAAAP;EAAAO,EAAA,KAAAN;EAAAM,EAAA,KAAAY;EAAAZ,EAAA,MAAAH;EAAAG,EAAA,MAAAkB;EAAAlB,EAAA,MAAAJ;EAAAI,EAAA,MAAAsB;CAAA,OAAAA,KAAAtB,EAAA;CAAA,IAAA0B;CAAA,IAAA1B,EAAA,QAAAmB,MAAAnB,EAAA,QAAAsB,IAAA;EAlBVI,KAAA,oBAAC,eAAD;GAAsB,OAAAP;GAClBG,UAAAA;EADU,CAAA;EAmBEtB,EAAA,MAAAmB;EAAAnB,EAAA,MAAAsB;EAAAtB,EAAA,MAAA0B;CAAA,OAAAA,KAAA1B,EAAA;CAAA,OAnBhB0B;AAmBgB;AA9BjB,SAAAD,SAAA;CAAA,OAqB+B;AAAK;AArBpC,SAAAD,SAAA;CAAA,OAmB8B;AAAK;AAnBnC,SAAAD,OAAAI,QAAA;CAAA,OAiBqCb,OAAIc;AAAG;AAjB5C,SAAAjB,MAAAkB,GAAAC,OAAA;CAAA,OAGmE,EAAAF,IAC9D,YAAYG,OAAOD,KAAK,IAChC;AAAC"}
1
+ {"version":3,"file":"ListSkeleton.js","names":["ReactNode","LoadingRegion","Skeleton","usePanneauIntl","messages","ListColumn","ListItem","ListLayoutEntry","MAX_ROWS","WIDTHS","none","nothing","undefined","ListSkeletonProps","Layout","columns","perPage","sort","label","withImages","ListSkeleton","t0","$","_c","t1","intl","rows","Math","max","min","t2","Array","from","length","_temp","items","t3","item","column","offset","indexOf","renderValue","t4","formatMessage","loading","t5","t6","_temp2","_temp3","_temp4","t7","item_0","id","_","index","String","_c"],"sources":["../src/ListSkeleton.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { LoadingRegion, Skeleton, usePanneauIntl } from '@panneau/ui';\n\nimport { messages } from './messages';\nimport type { ListColumn, ListItem, ListLayoutEntry } from './types';\n\n/** The most rows a skeleton draws: about what fits in a window. */\nconst MAX_ROWS = 10;\n/** Widths of the values, varied so the rows read as text. */\nconst WIDTHS = ['72%', '48%', '64%', '40%', '56%', '80%'];\n\nconst none = () => null;\nconst nothing = () => undefined;\n\nexport interface ListSkeletonProps {\n Layout: ListLayoutEntry;\n columns: readonly ListColumn[];\n /** The page size: as many rows, up to what fits. */\n perPage: number | undefined;\n sort: readonly string[];\n label: string;\n /** Whether items have an image: the table draws the placeholder of their thumbnails. */\n withImages?: boolean;\n}\n\n/**\n * The first page of a list that loads (decision 0034): the list's own layout, with its columns\n * and a skeleton for each value, as many rows as the page size, up to what fits. The layout is\n * inert and hidden: its headers can't be used before the items are there, and the status message\n * of the region says that the list loads.\n */\nexport function ListSkeleton({\n Layout,\n columns,\n perPage,\n sort,\n label,\n withImages = false,\n}: ListSkeletonProps) {\n const intl = usePanneauIntl();\n const rows = Math.max(1, Math.min(perPage ?? MAX_ROWS, MAX_ROWS));\n const items: ListItem[] = Array.from({ length: rows }, (_, index) => ({\n id: `skeleton-${String(index)}`,\n }));\n const renderValue = (item: ListItem, column: ListColumn): ReactNode => {\n const offset = items.indexOf(item) + columns.indexOf(column);\n return <Skeleton width={WIDTHS[offset % WIDTHS.length]} />;\n };\n return (\n <LoadingRegion label={intl.formatMessage(messages.loading)}>\n <div inert aria-hidden=\"true\">\n <Layout\n items={items}\n columns={columns}\n renderValue={renderValue}\n getItemLabel={(item) => item.id}\n getItemHref={none}\n getItemImage={withImages ? none : undefined}\n isCurrent={() => false}\n selectable={false}\n isSelected={() => false}\n onToggle={nothing}\n renderActions={none}\n sort={sort}\n onSort={nothing}\n label={label}\n pageSelection={null}\n />\n </div>\n </LoadingRegion>\n );\n}\n"],"mappings":";;;;;;AAQA,IAAMQ,WAAW;;AAEjB,IAAMC,SAAS;CAAC;CAAO;CAAO;CAAO;CAAO;CAAO;AAAK;AAExD,IAAMC,aAAa;AACnB,IAAMC,gBAAgBC,KAAAA;;;;;;;AAmBtB,SAAOQ,aAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAsB,MAAA,EAAAT,QAAAC,SAAAC,SAAAC,MAAAC,OAAAC,YAAAK,OAAAH;CAMzB,MAAAF,aAAAK,OAAAZ,KAAAA,IAAA,QAAAY;CAEA,MAAAC,OAAatB,eAAe;CAC5B,MAAAuB,OAAaC,KAAIC,IAAK,GAAGD,KAAIE,IAAKb,WAAAR,UAAqBA,QAAQ,CAAC;CAAE,IAAAsB;CAAA,IAAAR,EAAA,OAAAI,MAAA;EACxCI,KAAAC,MAAKC,KAAM,EAAAC,QAAUP,KAAK,GAAGQ,KAErD;EAACZ,EAAA,KAAAI;EAAAJ,EAAA,KAAAQ;CAAA,OAAAA,KAAAR,EAAA;CAFH,MAAAa,QAA0BL;CAEtB,IAAAM;CAAA,IAAAd,EAAA,OAAAP,WAAAO,EAAA,OAAAa,OAAA;EACgBC,MAAAC,MAAAC,WAAA;GAChB,MAAAC,SAAeJ,MAAKK,QAASH,IAAI,IAAItB,QAAOyB,QAASF,MAAM;GAAE,OACtD,oBAAC,UAAD,EAAiB,OAAA7B,OAAO8B,SAAS9B,OAAMwB,QAAQ,CAAA;EAAI;EAC7DX,EAAA,KAAAP;EAAAO,EAAA,KAAAa;EAAAb,EAAA,KAAAc;CAAA,OAAAA,KAAAd,EAAA;CAHD,MAAAmB,cAAoBL;CAGlB,IAAAM;CAAA,IAAApB,EAAA,OAAAG,MAAA;EAEwBiB,KAAAjB,KAAIkB,cAAevC,SAAQwC,OAAQ;EAACtB,EAAA,KAAAG;EAAAH,EAAA,KAAAoB;CAAA,OAAAA,KAAApB,EAAA;CAQhC,MAAAuB,KAAA1B,aAAAT,OAAAE,KAAAA;CAA6B,IAAAkC;CAAA,IAAAxB,EAAA,OAAAR,UAAAQ,EAAA,OAAAP,WAAAO,EAAA,OAAAa,SAAAb,EAAA,QAAAJ,SAAAI,EAAA,QAAAmB,eAAAnB,EAAA,QAAAL,QAAAK,EAAA,QAAAuB,IAAA;EAPnDC,KAAA,oBAAA,OAAA;GAAK,OAAA;GAAkB,eAAA;GACnB,UAAA,oBAAC,QAAD;IACWX;IACEpB;IACI0B;IACC,cAAAM;IACDrC,aAAAA;IACC,cAAAmC;IACH,WAAAG;IACC,YAAA;IACA,YAAAC;IACFtC,UAAAA;IACKD,eAAAA;IACTO;IACEN,QAAAA;IACDO;IACQ,eAAA;GAAI,CAAA;EAErB,CAAA;EAAAI,EAAA,KAAAR;EAAAQ,EAAA,KAAAP;EAAAO,EAAA,KAAAa;EAAAb,EAAA,MAAAJ;EAAAI,EAAA,MAAAmB;EAAAnB,EAAA,MAAAL;EAAAK,EAAA,MAAAuB;EAAAvB,EAAA,MAAAwB;CAAA,OAAAA,KAAAxB,EAAA;CAAA,IAAA4B;CAAA,IAAA5B,EAAA,QAAAoB,MAAApB,EAAA,QAAAwB,IAAA;EAnBVI,KAAA,oBAAC,eAAD;GAAsB,OAAAR;GAClBI,UAAAA;EADU,CAAA;EAoBExB,EAAA,MAAAoB;EAAApB,EAAA,MAAAwB;EAAAxB,EAAA,MAAA4B;CAAA,OAAAA,KAAA5B,EAAA;CAAA,OApBhB4B;AAoBgB;AAtCjB,SAAAD,SAAA;CAAA,OA6B+B;AAAK;AA7BpC,SAAAD,SAAA;CAAA,OA2B8B;AAAK;AA3BnC,SAAAD,OAAAI,QAAA;CAAA,OAwBqCd,OAAIe;AAAG;AAxB5C,SAAAlB,MAAAmB,GAAAC,OAAA;CAAA,OAUmE,EAAAF,IAC9D,YAAYG,OAAOD,KAAK,IAChC;AAAC"}
@@ -74,8 +74,9 @@ export interface ListViewProps {
74
74
  /** The field that titles items, for their label (`itemTitle` of the resource). */
75
75
  itemTitle?: string;
76
76
  /**
77
- * The field shown as the image of items (`itemImage` of the resource): a media reference, a
78
- * file or a URL. The `gallery` layout needs it (decision 0044).
77
+ * The field shown as the image of items (`itemImage` of the resource, or `media` in a media
78
+ * library): a media reference, a media, a file or a URL. The `gallery` layout needs it
79
+ * (decision 0044), and the table starts each title with its thumbnail (decision 0061).
79
80
  */
80
81
  itemImage?: string | undefined;
81
82
  /**
@@ -83,6 +84,12 @@ export interface ListViewProps {
83
84
  * state asks for its month when it is given the same calendar.
84
85
  */
85
86
  calendar?: Pick<ResolvedCalendar, 'field' | 'filter'> | null | undefined;
87
+ /**
88
+ * The id of the main action of rows, which keeps its label while the others show their icons
89
+ * (decision 0060): the one the title of an item opens, `edit` for a resource that opens its
90
+ * items in their form. Defaults to `show` when rows have it, else `edit`.
91
+ */
92
+ primaryAction?: string | null;
86
93
  /** The label of an item, for checkboxes and actions. Defaults to its title, then its id. */
87
94
  getItemLabel?: (item: ListItem) => string;
88
95
  /** A link to an item, on its title. */
@@ -130,5 +137,5 @@ export interface ListViewProps {
130
137
  * cards), with sorting, search, filters and their chips, pagination, selection and actions. It
131
138
  * fetches nothing: the caller gives the items of the list's query and their total.
132
139
  */
133
- export declare function ListView({ list, items, columns: allColumns, columnChoice, total, cursors, isLoading, error, onRetry, filters: filtersProp, fields, search, layouts: layoutsProp, layout: controlledLayout, onLayoutChange, perPageOptions, selectable: selectableProp, actions: actionsProp, onAction, previewAction, actionIcons, itemTitle, itemImage, calendar, getItemLabel: getItemLabelProp, getItemHref, getLinkHref, currentItemId, displays, layoutComponents, filterControls, inlineEdit, onInlineEdit, formatError, toolbar, emptyMessage, 'aria-label': ariaLabel, className, }: ListViewProps): import("react").JSX.Element;
140
+ export declare function ListView({ list, items, columns: allColumns, columnChoice, total, cursors, isLoading, error, onRetry, filters: filtersProp, fields, search, layouts: layoutsProp, layout: controlledLayout, onLayoutChange, perPageOptions, selectable: selectableProp, actions: actionsProp, onAction, previewAction, actionIcons, itemTitle, itemImage, calendar, primaryAction: primaryActionProp, getItemLabel: getItemLabelProp, getItemHref, getLinkHref, currentItemId, displays, layoutComponents, filterControls, inlineEdit, onInlineEdit, formatError, toolbar, emptyMessage, 'aria-label': ariaLabel, className, }: ListViewProps): import("react").JSX.Element;
134
141
  //# sourceMappingURL=ListView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ListView.d.ts","sourceRoot":"","sources":["../src/ListView.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ListView.d.ts","sourceRoot":"","sources":["../src/ListView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAoB,MAAM,OAAO,CAAC;AAEzD,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAS5D,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQ5E,OAAO,EACH,KAAK,WAAW,EAKnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAgBnD,OAAO,KAAK,EACR,YAAY,EACZ,WAAW,EAEX,iBAAiB,EACjB,mBAAmB,EACnB,UAAU,EACV,qBAAqB,EACrB,QAAQ,EACR,eAAe,EAClB,MAAM,SAAS,CAAC;AAKjB,MAAM,WAAW,aAAa;IAC1B,4EAA4E;IAC5E,IAAI,EAAE,IAAI,CAAC;IACX;;;OAGG;IACH,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,SAAS,CAAC;IACvC;;;OAGG;IACH,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,+EAA+E;IAC/E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B;;;;OAIG;IACH,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;IACpF,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wEAAwE;IACxE,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,uFAAuF;IACvF,MAAM,CAAC,EAAE,SAAS,KAAK,EAAE,CAAC;IAC1B,kCAAkC;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wFAAwF;IACxF,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,iCAAiC;IACjC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,yEAAyE;IACzE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B;;;;OAIG;IACH,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,OAAO,GAAG,QAAQ,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IACzE;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,4FAA4F;IAC5F,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,CAAC;IAC1C,uCAAuC;IACvC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,MAAM,GAAG,IAAI,CAAC;IAChD;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,KAAK,MAAM,GAAG,IAAI,CAAC;IAChE;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAClD,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;IAC7D,8DAA8D;IAC9D,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IACvD;;;OAGG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,yEAAyE;IACzE,YAAY,CAAC,EAAE,qBAAqB,CAAC;IACrC;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7D,6EAA6E;IAC7E,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,mEAAmE;IACnE,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,EACrB,IAAI,EACJ,KAAK,EACL,OAAO,EAAE,UAAU,EACnB,YAAmB,EACnB,KAAK,EACL,OAAO,EACP,SAAiB,EACjB,KAAY,EACZ,OAAO,EACP,OAAO,EAAE,WAAgB,EACzB,MAAW,EACX,MAAc,EACd,OAAO,EAAE,WAAuB,EAChC,MAAM,EAAE,gBAAgB,EACxB,cAAc,EACd,cAAc,EACd,UAAU,EAAE,cAAc,EAC1B,OAAO,EAAE,WAAW,EACpB,QAAQ,EACR,aAAa,EACb,WAAW,EACX,SAAS,EACT,SAAS,EACT,QAAe,EACf,aAAa,EAAE,iBAAiB,EAChC,YAAY,EAAE,gBAAgB,EAC9B,WAAW,EACX,WAAW,EACX,aAAoB,EACpB,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,UAAe,EACf,YAAY,EACZ,WAA+B,EAC/B,OAAO,EACP,YAAY,EACZ,YAAY,EAAE,SAAS,EACvB,SAAS,GACZ,EAAE,aAAa,+BAqiBf"}
package/dist/ListView.js CHANGED
@@ -2,6 +2,7 @@ import { getActionHref, groupListActions, hasScope, isAllowedOn } from "./action
2
2
  import { messages } from "./messages.js";
3
3
  import { ConfirmDialog, needsConfirmation } from "./actions/ConfirmDialog.js";
4
4
  import { getColumnValue, toText } from "./values.js";
5
+ import { getImageUrl } from "./images.js";
5
6
  import { getCalendarTimeZone } from "./layouts/calendarDays.js";
6
7
  import { cx } from "./cx.js";
7
8
  import { builtInLayouts } from "./layouts/builtIn.js";
@@ -9,10 +10,9 @@ import { useRenderValue } from "./useRenderValue.js";
9
10
  import { ListSkeleton } from "./ListSkeleton.js";
10
11
  import ListView_module_default from "./ListView.module.js";
11
12
  import { ActionButton } from "./actions/ActionButton.js";
12
- import { RowActions } from "./actions/RowActions.js";
13
+ import { RowActions, orderRowActions } from "./actions/RowActions.js";
13
14
  import { getShownColumns } from "./columns.js";
14
15
  import { FilterChips, FilterControls, useFilterLabels } from "./filters/Filters.js";
15
- import { getImageUrl } from "./images.js";
16
16
  import { InlineCell } from "./inline/InlineCell.js";
17
17
  import { getInlineField } from "./inline/editable.js";
18
18
  import { countSelected, getPageSelection, isItemSelected } from "./selection.js";
@@ -22,7 +22,7 @@ import { CursorPagination, Pagination } from "./toolbar/Pagination.js";
22
22
  import { SearchField } from "./toolbar/SearchField.js";
23
23
  import { SortSelect } from "./toolbar/SortSelect.js";
24
24
  import { useListState } from "./useListState.js";
25
- import { currentMonth, formatRuleFailure, selectItemActions, usePlugins } from "@panneau/core";
25
+ import { asksConfirmation, currentMonth, formatRuleFailure, selectItemActions, usePlugins } from "@panneau/core";
26
26
  import { c } from "react/compiler-runtime";
27
27
  import { getActionLabel } from "@panneau/intl";
28
28
  import { Alert, Button, Checkbox, usePanneauIntl, useToast } from "@panneau/ui";
@@ -39,7 +39,7 @@ function keyOf(action, item) {
39
39
  */
40
40
  function ListView(t0) {
41
41
  const $ = c(116);
42
- const { list, items, columns: allColumns, columnChoice: t1, total, cursors, isLoading: t2, error: t3, onRetry, filters: t4, fields: t5, search: t6, layouts: t7, layout: controlledLayout, onLayoutChange, perPageOptions, selectable: selectableProp, actions: actionsProp, onAction, previewAction, actionIcons, itemTitle, itemImage, calendar: t8, getItemLabel: getItemLabelProp, getItemHref, getLinkHref, currentItemId: t9, displays, layoutComponents, filterControls, inlineEdit: t10, onInlineEdit, formatError: t11, toolbar, emptyMessage, "aria-label": ariaLabel, className } = t0;
42
+ const { list, items, columns: allColumns, columnChoice: t1, total, cursors, isLoading: t2, error: t3, onRetry, filters: t4, fields: t5, search: t6, layouts: t7, layout: controlledLayout, onLayoutChange, perPageOptions, selectable: selectableProp, actions: actionsProp, onAction, previewAction, actionIcons, itemTitle, itemImage, calendar: t8, primaryAction: primaryActionProp, getItemLabel: getItemLabelProp, getItemHref, getLinkHref, currentItemId: t9, displays, layoutComponents, filterControls, inlineEdit: t10, onInlineEdit, formatError: t11, toolbar, emptyMessage, "aria-label": ariaLabel, className } = t0;
43
43
  const columnChoice = t1 === void 0 ? true : t1;
44
44
  const isLoading = t2 === void 0 ? false : t2;
45
45
  const error = t3 === void 0 ? null : t3;
@@ -202,6 +202,7 @@ function ListView(t0) {
202
202
  item: item_3,
203
203
  field,
204
204
  itemLabel: getItemLabel(item_3),
205
+ getItemLabel,
205
206
  renderValue: (current_0) => renderValue(current_0, column_0),
206
207
  onSave: (base_0, value) => onInlineEdit({
207
208
  item: base_0,
@@ -241,7 +242,8 @@ function ListView(t0) {
241
242
  setPreview({ status: "loading" });
242
243
  previewAction(event_0).then((result) => {
243
244
  if (confirmation.current !== current_1) return;
244
- if ((result?.skipped ?? event_0.skipped.length) === 0 && !asks) execute(event_0);
245
+ const skipped = result?.skipped ?? event_0.skipped.length;
246
+ if (skipped === 0 && !asks && !asksConfirmation(action_2, Math.max(0, event_0.count - skipped))) execute(event_0);
245
247
  else setPreview(result !== null ? {
246
248
  status: "done",
247
249
  ...result
@@ -280,18 +282,24 @@ function ListView(t0) {
280
282
  count,
281
283
  skipped: []
282
284
  });
283
- const renderActions = (item_6) => {
284
- const allowed = selectItemActions(grouped.row, item_6, "row", { getLinkHref });
285
- const menu = selectItemActions(grouped.menu, item_6, "menu", { getLinkHref });
285
+ const pageActions = pageItems.map((item_6) => [...selectItemActions(grouped.row, item_6, "row", { getLinkHref }), ...selectItemActions(grouped.menu, item_6, "menu", { getLinkHref })]);
286
+ const firstOf = (action_6) => pageActions.flat().find((entry) => entry.action.id === action_6.id) ?? [];
287
+ const slots = orderRowActions(grouped.row.flatMap(firstOf), grouped.menu.flatMap(firstOf));
288
+ const primaryAction = primaryActionProp !== void 0 ? primaryActionProp : ["show", "edit"].find((id_1) => slots.some((slot) => slot.action.id === id_1)) ?? null;
289
+ const renderActions = (item_7) => {
290
+ const allowed = selectItemActions(grouped.row, item_7, "row", { getLinkHref });
291
+ const menu = selectItemActions(grouped.menu, item_7, "menu", { getLinkHref });
286
292
  if (allowed.length === 0 && menu.length === 0) return null;
287
- const running = pending?.endsWith(`\u0000${item_6.id}`) === true ? pending.split("\0")[0] : null;
293
+ const running = pending?.endsWith(`\u0000${item_7.id}`) === true ? pending.split("\0")[0] : null;
288
294
  return /* @__PURE__ */ jsx(RowActions, {
289
- itemLabel: getItemLabel(item_6),
295
+ itemLabel: getItemLabel(item_7),
290
296
  actions: allowed,
291
297
  menu,
292
298
  pending: running ?? null,
293
- onRun: (action_6) => runOnItem(action_6, item_6),
294
- icons: actionIcons
299
+ onRun: (action_7) => runOnItem(action_7, item_7),
300
+ icons: actionIcons,
301
+ slots,
302
+ primary: primaryAction
295
303
  });
296
304
  };
297
305
  let t26;
@@ -317,7 +325,7 @@ function ListView(t0) {
317
325
  let t27;
318
326
  if ($[36] !== filterValues || $[37] !== list || $[38] !== query.q) {
319
327
  t27 = function clearFilters() {
320
- Object.keys(filterValues).forEach((id_1) => list.setFilter(id_1, void 0));
328
+ Object.keys(filterValues).forEach((id_2) => list.setFilter(id_2, void 0));
321
329
  if ((query.q ?? "") !== "") list.setSearch("");
322
330
  };
323
331
  $[36] = filterValues;
@@ -368,7 +376,8 @@ function ListView(t0) {
368
376
  columns,
369
377
  perPage: query.perPage,
370
378
  sort,
371
- label
379
+ label,
380
+ withImages: itemImage !== void 0
372
381
  });
373
382
  break bb0;
374
383
  }
@@ -414,25 +423,25 @@ function ListView(t0) {
414
423
  }
415
424
  let t29;
416
425
  if ($[62] !== itemImage) {
417
- t29 = itemImage !== void 0 ? (item_8) => getImageUrl(item_8[itemImage]) : void 0;
426
+ t29 = itemImage !== void 0 ? (item_9) => getImageUrl(item_9[itemImage]) : void 0;
418
427
  $[62] = itemImage;
419
428
  $[63] = t29;
420
429
  } else t29 = $[63];
421
430
  let t30;
422
431
  if ($[64] !== currentItemId) {
423
- t30 = (item_9) => item_9.id === currentItemId;
432
+ t30 = (item_10) => item_10.id === currentItemId;
424
433
  $[64] = currentItemId;
425
434
  $[65] = t30;
426
435
  } else t30 = $[65];
427
436
  let t31;
428
437
  if ($[66] !== selection) {
429
- t31 = (item_10) => isItemSelected(selection, item_10.id);
438
+ t31 = (item_11) => isItemSelected(selection, item_11.id);
430
439
  $[66] = selection;
431
440
  $[67] = t31;
432
441
  } else t31 = $[67];
433
442
  let t32;
434
443
  if ($[68] !== list) {
435
- t32 = (item_11) => list.toggle(item_11.id);
444
+ t32 = (item_12) => list.toggle(item_12.id);
436
445
  $[68] = list;
437
446
  $[69] = t32;
438
447
  } else t32 = $[69];
@@ -485,7 +494,7 @@ function ListView(t0) {
485
494
  }) : null, filters.length > 0 ? /* @__PURE__ */ jsx(FilterControls, {
486
495
  filters,
487
496
  values: filterValues,
488
- onChange: (id_2, value_0) => list.setFilter(id_2, value_0),
497
+ onChange: (id_3, value_0) => list.setFilter(id_3, value_0),
489
498
  onLabel: filterLabels.remember,
490
499
  controls: filterControls,
491
500
  columns: allColumns,
@@ -517,14 +526,14 @@ function ListView(t0) {
517
526
  onChange: (ids_0) => list.setColumns(ids_0),
518
527
  onReset: view.columns !== void 0 ? () => list.resetColumns() : null
519
528
  }) : null,
520
- resourceActions.filter((action_7) => selectedCount === 0 || !hasScope(action_7, "selection")).map((action_8) => /* @__PURE__ */ jsx(ActionButton, {
521
- action: action_8,
529
+ resourceActions.filter((action_8) => selectedCount === 0 || !hasScope(action_8, "selection")).map((action_9) => /* @__PURE__ */ jsx(ActionButton, {
530
+ action: action_9,
522
531
  icons: actionIcons,
523
532
  size: "md",
524
- href: getActionHref(action_8),
525
- isPending: pending === keyOf(action_8),
526
- onPress: () => runOnResource(action_8)
527
- }, action_8.id)),
533
+ href: getActionHref(action_9),
534
+ isPending: pending === keyOf(action_9),
535
+ onPress: () => runOnResource(action_9)
536
+ }, action_9.id)),
528
537
  toolbar
529
538
  ]
530
539
  })]
@@ -532,7 +541,7 @@ function ListView(t0) {
532
541
  let t31;
533
542
  let t32;
534
543
  if ($[74] !== list) {
535
- t31 = (id_3) => list.setFilter(id_3, void 0);
544
+ t31 = (id_4) => list.setFilter(id_4, void 0);
536
545
  t32 = () => list.setSearch("");
537
546
  $[74] = list;
538
547
  $[75] = t31;
@@ -587,17 +596,17 @@ function ListView(t0) {
587
596
  }),
588
597
  selectionActions.length > 0 ? /* @__PURE__ */ jsx("div", {
589
598
  className: ListView_module_default.selectionActions,
590
- children: selectionActions.map((action_9) => {
591
- const skipped_0 = selectedItems.filter((item_12) => !isAllowedOn(action_9, item_12)).length;
599
+ children: selectionActions.map((action_10) => {
600
+ const skipped_0 = selectedItems.filter((item_13) => !isAllowedOn(action_10, item_13)).length;
592
601
  return /* @__PURE__ */ jsx(ActionButton, {
593
- action: action_9,
602
+ action: action_10,
594
603
  icons: actionIcons,
595
604
  size: "md",
596
605
  href: null,
597
- isPending: pending === keyOf(action_9),
598
- isDisabled: pending !== null && pending !== keyOf(action_9) || skipped_0 >= selectedCount,
599
- onPress: () => runOnSelection(action_9)
600
- }, action_9.id);
606
+ isPending: pending === keyOf(action_10),
607
+ isDisabled: pending !== null && pending !== keyOf(action_10) || skipped_0 >= selectedCount,
608
+ onPress: () => runOnSelection(action_10)
609
+ }, action_10.id);
601
610
  })
602
611
  }) : null
603
612
  ]
@@ -696,8 +705,8 @@ function _temp6(column_2) {
696
705
  function _temp5(column_1) {
697
706
  return column_1.sortable === true;
698
707
  }
699
- function _temp4(item_7) {
700
- return item_7.id;
708
+ function _temp4(item_8) {
709
+ return item_8.id;
701
710
  }
702
711
  function _temp3(action_1) {
703
712
  return hasScope(action_1, "resource");