@plumile/backoffice-react 0.1.189 → 0.1.190

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 (33) hide show
  1. package/lib/esm/components/backoffice/detail/backofficeDetailRelationLink.css.js +1 -0
  2. package/lib/esm/components/backoffice/list/RowFlagsCell.css.js +0 -1
  3. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js +369 -298
  4. package/lib/esm/components/backoffice/scaffolds/BackofficeEntityListScaffold.js.map +1 -1
  5. package/lib/esm/components/backoffice/scaffolds/backofficeEntityListScaffold.css.js +2 -2
  6. package/lib/esm/components/backoffice/scaffolds/backofficeEntityListScaffold.css.js.map +1 -1
  7. package/lib/esm/i18n/locales/en/backofficeReact.js +4 -1
  8. package/lib/esm/i18n/locales/en/backofficeReact.js.map +1 -1
  9. package/lib/esm/i18n/locales/fr/backofficeReact.js +5 -1
  10. package/lib/esm/i18n/locales/fr/backofficeReact.js.map +1 -1
  11. package/lib/esm/pages/BackofficeEntityListDataPage.js +77 -70
  12. package/lib/esm/pages/BackofficeEntityListDataPage.js.map +1 -1
  13. package/lib/esm/pages/BackofficeEntityListPage.js +89 -85
  14. package/lib/esm/pages/BackofficeEntityListPage.js.map +1 -1
  15. package/lib/esm/pages/BackofficeEntityListRouteContext.js.map +1 -1
  16. package/lib/esm/provider/BackofficeListUiStateContext.js +88 -0
  17. package/lib/esm/provider/BackofficeListUiStateContext.js.map +1 -0
  18. package/lib/esm/provider/BackofficeProvider.js +80 -79
  19. package/lib/esm/provider/BackofficeProvider.js.map +1 -1
  20. package/lib/types/components/backoffice/scaffolds/BackofficeEntityListScaffold.d.ts +2 -0
  21. package/lib/types/components/backoffice/scaffolds/BackofficeEntityListScaffold.d.ts.map +1 -1
  22. package/lib/types/components/backoffice/scaffolds/backofficeEntityListScaffold.css.d.ts +2 -0
  23. package/lib/types/components/backoffice/scaffolds/backofficeEntityListScaffold.css.d.ts.map +1 -1
  24. package/lib/types/i18n/resources.d.ts +7 -0
  25. package/lib/types/i18n/resources.d.ts.map +1 -1
  26. package/lib/types/pages/BackofficeEntityListDataPage.d.ts.map +1 -1
  27. package/lib/types/pages/BackofficeEntityListPage.d.ts.map +1 -1
  28. package/lib/types/pages/BackofficeEntityListRouteContext.d.ts +2 -0
  29. package/lib/types/pages/BackofficeEntityListRouteContext.d.ts.map +1 -1
  30. package/lib/types/provider/BackofficeListUiStateContext.d.ts +21 -0
  31. package/lib/types/provider/BackofficeListUiStateContext.d.ts.map +1 -0
  32. package/lib/types/provider/BackofficeProvider.d.ts.map +1 -1
  33. package/package.json +13 -13
@@ -13,80 +13,86 @@ import { jsx as h } from "react/jsx-runtime";
13
13
  import { Button as g } from "@plumile/ui/atomic/atoms/button/Button.js";
14
14
  import { loadQuery as _, usePreloadedQuery as v } from "react-relay";
15
15
  import { BACKOFFICE_LIST_DEFAULTS as y, BACKOFFICE_LIST_REFETCH_POLICY as b } from "@plumile/backoffice-core/constants.js";
16
+ import { stableListVariablesKey as x } from "@plumile/backoffice-core/state/stableKey.js";
16
17
  //#region src/pages/BackofficeEntityListDataPage.tsx
17
- function x({ queryRef: t }) {
18
- let { config: a, state: f, pushState: p, headerActions: m, columns: g, gridTemplateColumns: _, getRowId: x, countFetchKey: S, bumpCountFetchKey: C, registerRefresh: w } = c(), T = a.list, { t: E } = e(), D = v(T.query, t), { data: O, loadNext: k, hasNext: A, isLoadingNext: j, refetch: M } = n(T.fragment, D), N = T.getConnection(O), P = d(() => N.edges.map((e) => T.toRow(e.node)), [N.edges, T]), F = a.listDefaults ?? T.defaultState ?? {
18
+ function S({ queryRef: t }) {
19
+ let { config: a, state: p, pushState: m, headerActions: g, columns: _, gridTemplateColumns: S, getRowId: C, countFetchKey: w, bumpCountFetchKey: T, filterDrawerState: E, registerRefresh: D } = c(), O = a.list, { t: k } = e(), A = v(O.query, t), { data: j, loadNext: M, hasNext: N, isLoadingNext: P, refetch: F } = n(O.fragment, A), I = O.getConnection(j), L = d(() => I.edges.map((e) => O.toRow(e.node)), [I.edges, O]), R = a.listDefaults ?? O.defaultState ?? {
19
20
  where: null,
20
21
  sort: null
21
- }, I = f.sort ?? F.sort, { pageSize: L } = y, { isRefreshing: R, onRefresh: z } = o({
22
- refetch: M,
23
- variables: d(() => ({
24
- where: f.where,
25
- sort: I,
26
- count: L,
27
- cursor: null
28
- }), [
29
- L,
30
- I,
31
- f.where
32
- ]),
22
+ }, z = p.sort ?? R.sort, { pageSize: B } = y, V = d(() => ({
23
+ where: p.where,
24
+ sort: z,
25
+ count: B,
26
+ cursor: null
27
+ }), [
28
+ B,
29
+ z,
30
+ p.where
31
+ ]), H = d(() => x(V), [V]), U = f(H), { isRefreshing: W, onRefresh: G } = o({
32
+ refetch: F,
33
+ variables: V,
33
34
  defaults: {
34
- where: F.where,
35
- sort: F.sort,
36
- count: L,
35
+ where: R.where,
36
+ sort: R.sort,
37
+ count: B,
37
38
  cursor: null
38
39
  },
39
40
  fetchPolicy: b,
40
- buildQueryVariables: T.buildQueryVariables
41
- }), B = l(() => {
42
- C(), z();
43
- }, [C, z]);
44
- u(() => (w(B), () => {
45
- w(null);
46
- }), [B, w]);
47
- let V = s({
48
- hasNext: A,
49
- isLoadingNext: j,
50
- loadNext: k,
51
- count: L
52
- }), H = /* @__PURE__ */ h("span", { children: E("common.loading") });
53
- return P.length > 0 && (H = /* @__PURE__ */ h("span", { children: E("list.loaded", { count: P.length }) })), /* @__PURE__ */ h(i, {
41
+ buildQueryVariables: O.buildQueryVariables
42
+ });
43
+ u(() => {
44
+ U.current !== H && (U.current = H, T());
45
+ }, [T, H]);
46
+ let K = l(() => {
47
+ T(), G();
48
+ }, [T, G]);
49
+ u(() => (D(K), () => {
50
+ D(null);
51
+ }), [K, D]);
52
+ let q = s({
53
+ hasNext: N,
54
+ isLoadingNext: P,
55
+ loadNext: M,
56
+ count: B
57
+ }), J = /* @__PURE__ */ h("span", { children: k("common.loading") });
58
+ return L.length > 0 && (J = /* @__PURE__ */ h("span", { children: k("list.loaded", { count: L.length }) })), /* @__PURE__ */ h(i, {
54
59
  config: a,
55
- state: f,
56
- pushState: p,
57
- headerActions: m,
58
- rows: P,
59
- columns: g,
60
- gridTemplateColumns: _,
61
- getRowId: x,
62
- hasNextPage: A,
63
- isLoadingMore: j,
64
- isRefreshing: R,
65
- onLoadMore: V,
66
- onRefresh: B,
60
+ state: p,
61
+ pushState: m,
62
+ headerActions: g,
63
+ rows: L,
64
+ columns: _,
65
+ gridTemplateColumns: S,
66
+ getRowId: C,
67
+ hasNextPage: N,
68
+ isLoadingMore: P,
69
+ isRefreshing: W,
70
+ onLoadMore: q,
71
+ onRefresh: K,
67
72
  totalCount: null,
68
73
  loadedCountLabel: /* @__PURE__ */ h(r, {
69
- count: T.count,
70
- where: f.where,
71
- fetchKey: S,
72
- loadingFallback: H,
73
- children: (e) => /* @__PURE__ */ h("span", { children: E("list.showing", {
74
- shown: P.length,
74
+ count: O.count,
75
+ where: p.where,
76
+ fetchKey: w,
77
+ loadingFallback: J,
78
+ children: (e) => /* @__PURE__ */ h("span", { children: k("list.showing", {
79
+ shown: L.length,
75
80
  total: e
76
81
  }) })
77
- })
82
+ }),
83
+ filterDrawerState: E
78
84
  });
79
85
  }
80
- var S = ({ prepared: n }) => {
81
- let { config: r, state: o, pushState: s, headerActions: d, columns: v, gridTemplateColumns: b, getRowId: S } = c(), C = a(), { t: w } = e(), [T, E] = p(() => n.query), D = f(null), O = l(() => {
82
- D.current?.dispose(), D.current = null;
86
+ var C = ({ prepared: n }) => {
87
+ let { config: r, state: o, pushState: s, headerActions: d, columns: v, gridTemplateColumns: b, getRowId: x, filterDrawerState: C } = c(), w = a(), { t: T } = e(), [E, D] = p(() => n.query), O = f(null), k = l(() => {
88
+ O.current?.dispose(), O.current = null;
83
89
  }, []);
84
90
  u(() => {
85
- O(), E(n.query);
86
- }, [O, n.query]), u(() => () => {
87
- O();
88
- }, [O]);
89
- let k = l(() => {
91
+ k(), D(n.query);
92
+ }, [k, n.query]), u(() => () => {
93
+ k();
94
+ }, [k]);
95
+ let A = l(() => {
90
96
  let e = r.list, t = r.listDefaults ?? e.defaultState ?? {
91
97
  where: null,
92
98
  sort: null
@@ -95,12 +101,12 @@ var S = ({ prepared: n }) => {
95
101
  sort: o.sort ?? t.sort,
96
102
  count: n,
97
103
  cursor: null
98
- }, a = e.buildQueryVariables(i), s = _(C, e.query, a, { fetchPolicy: "network-only" });
99
- O(), D.current = s, E(s);
104
+ }, a = e.buildQueryVariables(i), s = _(w, e.query, a, { fetchPolicy: "network-only" });
105
+ k(), O.current = s, D(s);
100
106
  }, [
101
107
  r,
102
- O,
103
- C,
108
+ k,
109
+ w,
104
110
  o.sort,
105
111
  o.where
106
112
  ]);
@@ -113,34 +119,35 @@ var S = ({ prepared: n }) => {
113
119
  rows: [],
114
120
  columns: v,
115
121
  gridTemplateColumns: b,
116
- getRowId: S,
122
+ getRowId: x,
117
123
  hasNextPage: !1,
118
124
  isLoadingMore: !1,
119
125
  isRefreshing: !1,
120
126
  onLoadMore: () => {},
121
127
  onRefresh: () => {
122
- e(), k();
128
+ e(), A();
123
129
  },
124
130
  totalCount: null,
131
+ filterDrawerState: C,
125
132
  emptyState: /* @__PURE__ */ h(m, {
126
133
  tone: "danger",
127
- title: w("list.errors.title"),
134
+ title: T("list.errors.title"),
128
135
  actions: /* @__PURE__ */ h(g, {
129
136
  type: "button",
130
137
  variant: "secondary",
131
138
  size: "small",
132
139
  onClick: () => {
133
- e(), k();
140
+ e(), A();
134
141
  },
135
- children: w("list.actions.retry")
142
+ children: T("list.actions.retry")
136
143
  }),
137
- children: w("list.errors.tableFailed")
144
+ children: T("list.errors.tableFailed")
138
145
  })
139
146
  }),
140
- children: /* @__PURE__ */ h(x, { queryRef: T })
147
+ children: /* @__PURE__ */ h(S, { queryRef: E })
141
148
  });
142
149
  };
143
150
  //#endregion
144
- export { S as BackofficeEntityListDataPage, S as default };
151
+ export { C as BackofficeEntityListDataPage, C as default };
145
152
 
146
153
  //# sourceMappingURL=BackofficeEntityListDataPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeEntityListDataPage.js","names":[],"sources":["../../../src/pages/BackofficeEntityListDataPage.tsx"],"sourcesContent":["import {\n type JSX,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { loadQuery, usePreloadedQuery } from 'react-relay';\nimport type { OperationType } from 'relay-runtime';\nimport {\n BACKOFFICE_LIST_DEFAULTS,\n BACKOFFICE_LIST_REFETCH_POLICY,\n} from '@plumile/backoffice-core/constants.js';\nimport type { BackofficePreparedListDataRoute } from '@plumile/backoffice-core/types.js';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { InlineBanner } from '@plumile/ui/components/feedback/InlineBanner.js';\n\nimport { BackofficeErrorBoundary } from '../components/backoffice/errors/BackofficeErrorBoundary.js';\nimport { BackofficeEntityListScaffold } from '../components/backoffice/scaffolds/BackofficeEntityListScaffold.js';\nimport { BackofficeLazyEntityCountLabel } from '../components/backoffice/refs/BackofficeLazyEntityCount.js';\nimport { useBackofficeLoadMore } from '../hooks/useBackofficeLoadMore.js';\nimport { useBackofficeListRefetch } from '../hooks/useBackofficeListRefetch.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficePaginationFragment } from '../relay/typedRelayHooks.js';\nimport { useRelayEnvironment } from '../relay/useRelayEnvironment.js';\nimport { useBackofficeEntityListRouteContext } from './BackofficeEntityListRouteContext.js';\n\nexport type BackofficeEntityListDataPageProps = {\n prepared: BackofficePreparedListDataRoute;\n};\n\ntype BackofficeEntityConnectionListDataProps = {\n queryRef: BackofficePreparedListDataRoute['query'];\n};\n\n/**\n * Renders the Relay-backed row data under the list layout route boundary.\n */\nfunction BackofficeEntityConnectionListData({\n queryRef,\n}: BackofficeEntityConnectionListDataProps): JSX.Element | null {\n const {\n config,\n state,\n pushState,\n headerActions,\n columns,\n gridTemplateColumns,\n getRowId,\n countFetchKey,\n bumpCountFetchKey,\n registerRefresh,\n } = useBackofficeEntityListRouteContext();\n const listConfig = config.list;\n const { t } = useBackofficeReactTranslation();\n\n const queryData = usePreloadedQuery(listConfig.query, queryRef);\n const {\n data: fragmentData,\n loadNext,\n hasNext,\n isLoadingNext,\n refetch,\n } = useBackofficePaginationFragment<OperationType, unknown, unknown>(\n listConfig.fragment,\n queryData,\n );\n\n const connection = listConfig.getConnection(fragmentData);\n\n const rows = useMemo(() => {\n return connection.edges.map((edge) => {\n return listConfig.toRow(edge.node);\n });\n }, [connection.edges, listConfig]);\n\n const listDefaults = config.listDefaults ??\n listConfig.defaultState ?? { where: null, sort: null };\n const resolvedSort = state.sort ?? listDefaults.sort;\n const { pageSize } = BACKOFFICE_LIST_DEFAULTS;\n\n const baseVariables = useMemo(() => {\n return {\n where: state.where,\n sort: resolvedSort,\n count: pageSize,\n cursor: null,\n };\n }, [pageSize, resolvedSort, state.where]);\n\n const { isRefreshing, onRefresh } = useBackofficeListRefetch({\n refetch,\n variables: baseVariables,\n defaults: {\n where: listDefaults.where,\n sort: listDefaults.sort,\n count: pageSize,\n cursor: null,\n },\n fetchPolicy: BACKOFFICE_LIST_REFETCH_POLICY,\n buildQueryVariables: listConfig.buildQueryVariables,\n });\n\n const handleRefresh = useCallback(() => {\n bumpCountFetchKey();\n onRefresh();\n }, [bumpCountFetchKey, onRefresh]);\n\n useEffect(() => {\n registerRefresh(handleRefresh);\n return () => {\n registerRefresh(null);\n };\n }, [handleRefresh, registerRefresh]);\n\n const handleLoadMore = useBackofficeLoadMore({\n hasNext,\n isLoadingNext,\n loadNext,\n count: pageSize,\n });\n\n let loadedCountFallback: JSX.Element = <span>{t('common.loading')}</span>;\n if (rows.length > 0) {\n loadedCountFallback = (\n <span>\n {t('list.loaded', {\n count: rows.length,\n })}\n </span>\n );\n }\n const loadedCountLabel = (\n <BackofficeLazyEntityCountLabel\n count={listConfig.count}\n where={state.where}\n fetchKey={countFetchKey}\n loadingFallback={loadedCountFallback}\n >\n {(totalCount) => {\n return (\n <span>\n {t('list.showing', {\n shown: rows.length,\n total: totalCount,\n })}\n </span>\n );\n }}\n </BackofficeLazyEntityCountLabel>\n );\n\n return (\n <BackofficeEntityListScaffold\n config={config}\n state={state}\n pushState={pushState}\n headerActions={headerActions}\n rows={rows}\n columns={columns}\n gridTemplateColumns={gridTemplateColumns}\n getRowId={getRowId}\n hasNextPage={hasNext}\n isLoadingMore={isLoadingNext}\n isRefreshing={isRefreshing}\n onLoadMore={handleLoadMore}\n onRefresh={handleRefresh}\n totalCount={null}\n loadedCountLabel={loadedCountLabel}\n />\n );\n}\n\nexport const BackofficeEntityListDataPage = ({\n prepared,\n}: BackofficeEntityListDataPageProps): JSX.Element | null => {\n const {\n config,\n state,\n pushState,\n headerActions,\n columns,\n gridTemplateColumns,\n getRowId,\n } = useBackofficeEntityListRouteContext();\n const relayEnvironment = useRelayEnvironment();\n const { t } = useBackofficeReactTranslation();\n const [queryRef, setQueryRef] = useState(() => {\n return prepared.query;\n });\n const ownedQueryRef = useRef<BackofficePreparedListDataRoute['query'] | null>(\n null,\n );\n\n const disposeOwnedQueryRef = useCallback(() => {\n ownedQueryRef.current?.dispose();\n ownedQueryRef.current = null;\n }, []);\n\n useEffect(() => {\n disposeOwnedQueryRef();\n setQueryRef(prepared.query);\n }, [disposeOwnedQueryRef, prepared.query]);\n\n useEffect(() => {\n return () => {\n disposeOwnedQueryRef();\n };\n }, [disposeOwnedQueryRef]);\n\n const reloadInitialQuery = useCallback(() => {\n const listConfig = config.list;\n const listDefaults = config.listDefaults ??\n listConfig.defaultState ?? { where: null, sort: null };\n const { pageSize } = BACKOFFICE_LIST_DEFAULTS;\n const variablesBase = {\n where: state.where,\n sort: state.sort ?? listDefaults.sort,\n count: pageSize,\n cursor: null,\n };\n const variables = listConfig.buildQueryVariables(variablesBase);\n const nextQueryRef = loadQuery<OperationType>(\n relayEnvironment,\n listConfig.query,\n variables,\n {\n fetchPolicy: 'network-only',\n },\n );\n disposeOwnedQueryRef();\n ownedQueryRef.current = nextQueryRef;\n setQueryRef(nextQueryRef);\n }, [config, disposeOwnedQueryRef, relayEnvironment, state.sort, state.where]);\n\n return (\n <BackofficeErrorBoundary\n fallback={({ reset }) => {\n return (\n <BackofficeEntityListScaffold\n config={config}\n state={state}\n pushState={pushState}\n headerActions={headerActions}\n rows={[]}\n columns={columns}\n gridTemplateColumns={gridTemplateColumns}\n getRowId={getRowId}\n hasNextPage={false}\n isLoadingMore={false}\n isRefreshing={false}\n onLoadMore={() => {}}\n onRefresh={() => {\n reset();\n reloadInitialQuery();\n }}\n totalCount={null}\n emptyState={\n <InlineBanner\n tone=\"danger\"\n title={t('list.errors.title')}\n actions={\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={() => {\n reset();\n reloadInitialQuery();\n }}\n >\n {t('list.actions.retry')}\n </Button>\n }\n >\n {t('list.errors.tableFailed')}\n </InlineBanner>\n }\n />\n );\n }}\n >\n <BackofficeEntityConnectionListData queryRef={queryRef} />\n </BackofficeErrorBoundary>\n );\n};\n\nexport default BackofficeEntityListDataPage;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BackofficeEntityListDataPage.js","names":[],"sources":["../../../src/pages/BackofficeEntityListDataPage.tsx"],"sourcesContent":["import {\n type JSX,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { loadQuery, usePreloadedQuery } from 'react-relay';\nimport type { OperationType } from 'relay-runtime';\nimport {\n BACKOFFICE_LIST_DEFAULTS,\n BACKOFFICE_LIST_REFETCH_POLICY,\n} from '@plumile/backoffice-core/constants.js';\nimport { stableListVariablesKey } from '@plumile/backoffice-core/state/stableKey.js';\nimport type { BackofficePreparedListDataRoute } from '@plumile/backoffice-core/types.js';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { InlineBanner } from '@plumile/ui/components/feedback/InlineBanner.js';\n\nimport { BackofficeErrorBoundary } from '../components/backoffice/errors/BackofficeErrorBoundary.js';\nimport { BackofficeEntityListScaffold } from '../components/backoffice/scaffolds/BackofficeEntityListScaffold.js';\nimport { BackofficeLazyEntityCountLabel } from '../components/backoffice/refs/BackofficeLazyEntityCount.js';\nimport { useBackofficeLoadMore } from '../hooks/useBackofficeLoadMore.js';\nimport { useBackofficeListRefetch } from '../hooks/useBackofficeListRefetch.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport { useBackofficePaginationFragment } from '../relay/typedRelayHooks.js';\nimport { useRelayEnvironment } from '../relay/useRelayEnvironment.js';\nimport { useBackofficeEntityListRouteContext } from './BackofficeEntityListRouteContext.js';\n\nexport type BackofficeEntityListDataPageProps = {\n prepared: BackofficePreparedListDataRoute;\n};\n\ntype BackofficeEntityConnectionListDataProps = {\n queryRef: BackofficePreparedListDataRoute['query'];\n};\n\n/**\n * Renders the Relay-backed row data under the list layout route boundary.\n */\nfunction BackofficeEntityConnectionListData({\n queryRef,\n}: BackofficeEntityConnectionListDataProps): JSX.Element | null {\n const {\n config,\n state,\n pushState,\n headerActions,\n columns,\n gridTemplateColumns,\n getRowId,\n countFetchKey,\n bumpCountFetchKey,\n filterDrawerState,\n registerRefresh,\n } = useBackofficeEntityListRouteContext();\n const listConfig = config.list;\n const { t } = useBackofficeReactTranslation();\n\n const queryData = usePreloadedQuery(listConfig.query, queryRef);\n const {\n data: fragmentData,\n loadNext,\n hasNext,\n isLoadingNext,\n refetch,\n } = useBackofficePaginationFragment<OperationType, unknown, unknown>(\n listConfig.fragment,\n queryData,\n );\n\n const connection = listConfig.getConnection(fragmentData);\n\n const rows = useMemo(() => {\n return connection.edges.map((edge) => {\n return listConfig.toRow(edge.node);\n });\n }, [connection.edges, listConfig]);\n\n const listDefaults = config.listDefaults ??\n listConfig.defaultState ?? { where: null, sort: null };\n const resolvedSort = state.sort ?? listDefaults.sort;\n const { pageSize } = BACKOFFICE_LIST_DEFAULTS;\n\n const baseVariables = useMemo(() => {\n return {\n where: state.where,\n sort: resolvedSort,\n count: pageSize,\n cursor: null,\n };\n }, [pageSize, resolvedSort, state.where]);\n const countVariablesKey = useMemo(() => {\n return stableListVariablesKey(baseVariables);\n }, [baseVariables]);\n const previousCountVariablesKeyRef = useRef(countVariablesKey);\n\n const { isRefreshing, onRefresh } = useBackofficeListRefetch({\n refetch,\n variables: baseVariables,\n defaults: {\n where: listDefaults.where,\n sort: listDefaults.sort,\n count: pageSize,\n cursor: null,\n },\n fetchPolicy: BACKOFFICE_LIST_REFETCH_POLICY,\n buildQueryVariables: listConfig.buildQueryVariables,\n });\n\n useEffect(() => {\n if (previousCountVariablesKeyRef.current === countVariablesKey) {\n return;\n }\n previousCountVariablesKeyRef.current = countVariablesKey;\n bumpCountFetchKey();\n }, [bumpCountFetchKey, countVariablesKey]);\n\n const handleRefresh = useCallback(() => {\n bumpCountFetchKey();\n onRefresh();\n }, [bumpCountFetchKey, onRefresh]);\n\n useEffect(() => {\n registerRefresh(handleRefresh);\n return () => {\n registerRefresh(null);\n };\n }, [handleRefresh, registerRefresh]);\n\n const handleLoadMore = useBackofficeLoadMore({\n hasNext,\n isLoadingNext,\n loadNext,\n count: pageSize,\n });\n\n let loadedCountFallback: JSX.Element = <span>{t('common.loading')}</span>;\n if (rows.length > 0) {\n loadedCountFallback = (\n <span>\n {t('list.loaded', {\n count: rows.length,\n })}\n </span>\n );\n }\n const loadedCountLabel = (\n <BackofficeLazyEntityCountLabel\n count={listConfig.count}\n where={state.where}\n fetchKey={countFetchKey}\n loadingFallback={loadedCountFallback}\n >\n {(totalCount) => {\n return (\n <span>\n {t('list.showing', {\n shown: rows.length,\n total: totalCount,\n })}\n </span>\n );\n }}\n </BackofficeLazyEntityCountLabel>\n );\n\n return (\n <BackofficeEntityListScaffold\n config={config}\n state={state}\n pushState={pushState}\n headerActions={headerActions}\n rows={rows}\n columns={columns}\n gridTemplateColumns={gridTemplateColumns}\n getRowId={getRowId}\n hasNextPage={hasNext}\n isLoadingMore={isLoadingNext}\n isRefreshing={isRefreshing}\n onLoadMore={handleLoadMore}\n onRefresh={handleRefresh}\n totalCount={null}\n loadedCountLabel={loadedCountLabel}\n filterDrawerState={filterDrawerState}\n />\n );\n}\n\nexport const BackofficeEntityListDataPage = ({\n prepared,\n}: BackofficeEntityListDataPageProps): JSX.Element | null => {\n const {\n config,\n state,\n pushState,\n headerActions,\n columns,\n gridTemplateColumns,\n getRowId,\n filterDrawerState,\n } = useBackofficeEntityListRouteContext();\n const relayEnvironment = useRelayEnvironment();\n const { t } = useBackofficeReactTranslation();\n const [queryRef, setQueryRef] = useState(() => {\n return prepared.query;\n });\n const ownedQueryRef = useRef<BackofficePreparedListDataRoute['query'] | null>(\n null,\n );\n\n const disposeOwnedQueryRef = useCallback(() => {\n ownedQueryRef.current?.dispose();\n ownedQueryRef.current = null;\n }, []);\n\n useEffect(() => {\n disposeOwnedQueryRef();\n setQueryRef(prepared.query);\n }, [disposeOwnedQueryRef, prepared.query]);\n\n useEffect(() => {\n return () => {\n disposeOwnedQueryRef();\n };\n }, [disposeOwnedQueryRef]);\n\n const reloadInitialQuery = useCallback(() => {\n const listConfig = config.list;\n const listDefaults = config.listDefaults ??\n listConfig.defaultState ?? { where: null, sort: null };\n const { pageSize } = BACKOFFICE_LIST_DEFAULTS;\n const variablesBase = {\n where: state.where,\n sort: state.sort ?? listDefaults.sort,\n count: pageSize,\n cursor: null,\n };\n const variables = listConfig.buildQueryVariables(variablesBase);\n const nextQueryRef = loadQuery<OperationType>(\n relayEnvironment,\n listConfig.query,\n variables,\n {\n fetchPolicy: 'network-only',\n },\n );\n disposeOwnedQueryRef();\n ownedQueryRef.current = nextQueryRef;\n setQueryRef(nextQueryRef);\n }, [config, disposeOwnedQueryRef, relayEnvironment, state.sort, state.where]);\n\n return (\n <BackofficeErrorBoundary\n fallback={({ reset }) => {\n return (\n <BackofficeEntityListScaffold\n config={config}\n state={state}\n pushState={pushState}\n headerActions={headerActions}\n rows={[]}\n columns={columns}\n gridTemplateColumns={gridTemplateColumns}\n getRowId={getRowId}\n hasNextPage={false}\n isLoadingMore={false}\n isRefreshing={false}\n onLoadMore={() => {}}\n onRefresh={() => {\n reset();\n reloadInitialQuery();\n }}\n totalCount={null}\n filterDrawerState={filterDrawerState}\n emptyState={\n <InlineBanner\n tone=\"danger\"\n title={t('list.errors.title')}\n actions={\n <Button\n type=\"button\"\n variant=\"secondary\"\n size=\"small\"\n onClick={() => {\n reset();\n reloadInitialQuery();\n }}\n >\n {t('list.actions.retry')}\n </Button>\n }\n >\n {t('list.errors.tableFailed')}\n </InlineBanner>\n }\n />\n );\n }}\n >\n <BackofficeEntityConnectionListData queryRef={queryRef} />\n </BackofficeErrorBoundary>\n );\n};\n\nexport default BackofficeEntityListDataPage;\n"],"mappings":"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"}
@@ -7,19 +7,20 @@ import { rowFlagsColumnCell as a } from "../components/backoffice/list/RowFlagsC
7
7
  import { RowFlagsCell as o } from "../components/backoffice/list/RowFlagsCell.js";
8
8
  import { BackofficeEntityListScaffold as s } from "../components/backoffice/scaffolds/BackofficeEntityListScaffold.js";
9
9
  import { useBackofficeListUrlState as c } from "../hooks/useBackofficeListUrlState.js";
10
- import { BackofficeEntityListRouteProvider as l } from "./BackofficeEntityListRouteContext.js";
11
- import { buildActionsColumn as u, computeActionsColumnWidthPx as d, computeRowFlagsColumnWidthPx as f, isFormMutationAction as p, isRouteAction as m, resolveActionVariant as h, resolveLabel as g, resolveTrackBySize as _ } from "./BackofficeEntityListPage.helpers.js";
12
- import { actionTrigger as v, actionsColumnCell as y, headerActions as b } from "./backofficeEntityListPage.css.js";
13
- import { Suspense as x, useCallback as S, useMemo as C, useRef as w, useState as T } from "react";
14
- import { jsx as E, jsxs as D } from "react/jsx-runtime";
15
- import { useTranslation as O } from "react-i18next";
16
- import { Button as k } from "@plumile/ui/atomic/atoms/button/Button.js";
17
- import A from "@plumile/router/routing/Link.js";
18
- import { LinkButton as j } from "@plumile/ui/atomic/atoms/button/LinkButton.js";
19
- import { TableCell as M } from "@plumile/ui/components/data-table/TableCell.js";
20
- import { EyeSvg as N } from "@plumile/ui/icons/EyeSvg.js";
10
+ import { createBackofficeEntityListUiStateKey as l, useBackofficeListFilterDrawerState as u } from "../provider/BackofficeListUiStateContext.js";
11
+ import { BackofficeEntityListRouteProvider as d } from "./BackofficeEntityListRouteContext.js";
12
+ import { buildActionsColumn as f, computeActionsColumnWidthPx as p, computeRowFlagsColumnWidthPx as m, isFormMutationAction as h, isRouteAction as g, resolveActionVariant as _, resolveLabel as v, resolveTrackBySize as y } from "./BackofficeEntityListPage.helpers.js";
13
+ import { actionTrigger as b, actionsColumnCell as x, headerActions as S } from "./backofficeEntityListPage.css.js";
14
+ import { Suspense as C, useCallback as w, useMemo as T, useRef as E, useState as D } from "react";
15
+ import { jsx as O, jsxs as k } from "react/jsx-runtime";
16
+ import { useTranslation as A } from "react-i18next";
17
+ import { Button as j } from "@plumile/ui/atomic/atoms/button/Button.js";
18
+ import M from "@plumile/router/routing/Link.js";
19
+ import { LinkButton as N } from "@plumile/ui/atomic/atoms/button/LinkButton.js";
20
+ import { TableCell as P } from "@plumile/ui/components/data-table/TableCell.js";
21
+ import { EyeSvg as F } from "@plumile/ui/icons/EyeSvg.js";
21
22
  //#region src/pages/BackofficeEntityListPage.tsx
22
- var P = (e, t, n, r) => {
23
+ var I = (e, t, n, r) => {
23
24
  let i = t != null && t.length > 0, s = e;
24
25
  if (i) {
25
26
  let n = [{
@@ -27,7 +28,7 @@ var P = (e, t, n, r) => {
27
28
  header: "",
28
29
  className: a,
29
30
  mobileRole: "badge",
30
- cell: (e) => /* @__PURE__ */ E(o, {
31
+ cell: (e) => /* @__PURE__ */ O(o, {
31
32
  row: e,
32
33
  flags: t,
33
34
  tApp: r
@@ -40,54 +41,54 @@ var P = (e, t, n, r) => {
40
41
  }
41
42
  let c = 0;
42
43
  i && (c = t.length);
43
- let l = f(c), u = d(n), p = 0;
44
- i && (p = 1);
45
- let m = s.length - p - 1, h = s.slice(p, p + Math.max(0, m)).map((e) => _(e, "1fr")).join(" "), g = "";
44
+ let l = m(c), u = p(n), d = 0;
45
+ i && (d = 1);
46
+ let f = s.length - d - 1, h = s.slice(d, d + Math.max(0, f)).map((e) => y(e, "1fr")).join(" "), g = "";
46
47
  return g = i ? `${l}px ${h} ${u}px` : `${h} ${u}px`, {
47
48
  columns: s,
48
49
  gridTemplateColumns: g
49
50
  };
50
- }, F = ({ children: i, config: a, breadcrumb: o }) => {
51
- let d = a.list, { t: f } = O(), { t: _ } = e(), [F, I] = T(null), [L, R] = T(0), z = w(null), B = S((e) => {
52
- z.current = e;
53
- }, []), { columns: V, gridTemplateColumns: H } = C(() => {
54
- let e = n(d.columns, {
55
- tApp: f,
56
- t: _
57
- }), t = u({
58
- ariaLabel: _("actions.view"),
59
- fallback: _("common.notAvailable"),
60
- className: y,
51
+ }, L = ({ children: i, config: a, breadcrumb: o }) => {
52
+ let p = a.list, { t: m } = A(), { t: y } = e(), [L, R] = D(null), [z, B] = D(0), V = E(null), H = w((e) => {
53
+ V.current = e;
54
+ }, []), { columns: U, gridTemplateColumns: W } = T(() => {
55
+ let e = n(p.columns, {
56
+ tApp: m,
57
+ t: y
58
+ }), t = f({
59
+ ariaLabel: y("actions.view"),
60
+ fallback: y("common.notAvailable"),
61
+ className: x,
61
62
  resolveDetailHref: (e) => a.routes.detail(e),
62
- renderAction: ({ href: e, ariaLabel: t }) => /* @__PURE__ */ E(M.Actions, { children: /* @__PURE__ */ E(A, {
63
+ renderAction: ({ href: e, ariaLabel: t }) => /* @__PURE__ */ O(P.Actions, { children: /* @__PURE__ */ O(M, {
63
64
  to: e,
64
- className: v,
65
+ className: b,
65
66
  "aria-label": t,
66
67
  title: t,
67
68
  preloadOnHover: "code",
68
- children: /* @__PURE__ */ E(N, {
69
+ children: /* @__PURE__ */ O(F, {
69
70
  width: 16,
70
71
  height: 16
71
72
  })
72
73
  }) })
73
74
  });
74
- return P([...e, t], d.rowFlags, 1, f);
75
+ return I([...e, t], p.rowFlags, 1, m);
75
76
  }, [
76
77
  a.routes,
77
- d.columns,
78
- d.rowFlags,
79
- _,
80
- f
81
- ]), U = S((e) => d.getRowId(e), [d]), { state: W, pushState: G } = c(a), K = S(() => {
82
- R((e) => e + 1), z.current?.();
83
- }, []), q = C(() => a.listActions ?? [], [a.listActions]), J = C(() => q.filter((e) => e.isVisible == null ? !0 : e.isVisible(null)), [q]), Y = C(() => {
84
- if (J.length !== 0) return /* @__PURE__ */ E("div", {
85
- className: b,
86
- children: J.map((e, t) => {
87
- let { variant: n } = e, r = g(e.label, f), i = r;
88
- e.ariaLabel != null && (i = g(e.ariaLabel, f));
89
- let a = h(n, t), o = e.size ?? "small", s = e.isDisabled?.(null) === !0;
90
- return m(e) ? /* @__PURE__ */ E(j, {
78
+ p.columns,
79
+ p.rowFlags,
80
+ y,
81
+ m
82
+ ]), G = w((e) => p.getRowId(e), [p]), { state: K, pushState: q } = c(a), J = u(T(() => l(a.id), [a.id])), Y = w(() => {
83
+ B((e) => e + 1), V.current?.();
84
+ }, []), X = T(() => a.listActions ?? [], [a.listActions]), Z = T(() => X.filter((e) => e.isVisible == null ? !0 : e.isVisible(null)), [X]), Q = T(() => {
85
+ if (Z.length !== 0) return /* @__PURE__ */ O("div", {
86
+ className: S,
87
+ children: Z.map((e, t) => {
88
+ let { variant: n } = e, r = v(e.label, m), i = r;
89
+ e.ariaLabel != null && (i = v(e.ariaLabel, m));
90
+ let a = _(n, t), o = e.size ?? "small", s = e.isDisabled?.(null) === !0;
91
+ return g(e) ? /* @__PURE__ */ O(N, {
91
92
  to: e.to(null),
92
93
  variant: a,
93
94
  size: o,
@@ -95,80 +96,83 @@ var P = (e, t, n, r) => {
95
96
  "aria-label": i,
96
97
  preloadOnHover: "code-and-data",
97
98
  children: r
98
- }, e.id) : p(e) ? /* @__PURE__ */ E(k, {
99
+ }, e.id) : h(e) ? /* @__PURE__ */ O(j, {
99
100
  type: "button",
100
101
  variant: a,
101
102
  size: o,
102
103
  disabled: s,
103
104
  onClick: () => {
104
- I(e.id);
105
+ R(e.id);
105
106
  },
106
107
  "aria-label": i,
107
108
  children: r
108
109
  }, e.id) : null;
109
110
  })
110
111
  });
111
- }, [f, J]), X = q.find((e) => e.id === F);
112
- return /* @__PURE__ */ D(r, {
112
+ }, [m, Z]), $ = X.find((e) => e.id === L);
113
+ return /* @__PURE__ */ k(r, {
113
114
  breadcrumb: o,
114
- children: [/* @__PURE__ */ E(l, {
115
- value: C(() => ({
115
+ children: [/* @__PURE__ */ O(d, {
116
+ value: T(() => ({
116
117
  config: a,
117
- state: W,
118
- pushState: G,
119
- headerActions: Y,
120
- columns: V,
121
- gridTemplateColumns: H,
122
- getRowId: U,
123
- countFetchKey: L,
118
+ state: K,
119
+ pushState: q,
120
+ headerActions: Q,
121
+ columns: U,
122
+ gridTemplateColumns: W,
123
+ getRowId: G,
124
+ countFetchKey: z,
125
+ filterDrawerState: J,
124
126
  bumpCountFetchKey: () => {
125
- R((e) => e + 1);
127
+ B((e) => e + 1);
126
128
  },
127
- registerRefresh: B
129
+ registerRefresh: H
128
130
  }), [
129
- V,
130
- a,
131
- L,
132
131
  U,
133
- H,
134
- Y,
132
+ a,
133
+ z,
134
+ J,
135
135
  G,
136
- B,
137
- W
136
+ W,
137
+ Q,
138
+ q,
139
+ H,
140
+ K
138
141
  ]),
139
- children: /* @__PURE__ */ E(x, {
140
- fallback: /* @__PURE__ */ E(s, {
142
+ children: /* @__PURE__ */ O(C, {
143
+ fallback: /* @__PURE__ */ O(s, {
141
144
  config: a,
142
- state: W,
143
- pushState: G,
144
- headerActions: Y,
145
+ state: K,
146
+ pushState: q,
147
+ headerActions: Q,
145
148
  rows: [],
146
- columns: V,
147
- gridTemplateColumns: H,
148
- getRowId: U,
149
+ columns: U,
150
+ gridTemplateColumns: W,
151
+ getRowId: G,
149
152
  hasNextPage: !1,
150
153
  isLoadingMore: !1,
151
154
  isRefreshing: !1,
152
155
  onLoadMore: () => {},
153
- onRefresh: K,
156
+ onRefresh: Y,
154
157
  totalCount: null,
155
- isLoadingInitial: !0
158
+ isLoadingInitial: !0,
159
+ filterDrawerState: J
156
160
  }),
157
161
  children: i
158
162
  })
159
- }), X != null && p(X) && /* @__PURE__ */ E(t, {
163
+ }), $ != null && h($) && /* @__PURE__ */ O(t, {
160
164
  isOpen: !0,
161
- action: X,
165
+ action: $,
162
166
  node: null,
163
167
  onClose: () => {
164
- I(null);
168
+ R(null);
165
169
  },
166
- onSuccess: K
170
+ onSuccess: Y
167
171
  })]
168
172
  });
169
- }, I = ({ children: e, entityManifest: t, config: n }) => {
170
- let { t: r } = O();
171
- return /* @__PURE__ */ E(F, {
173
+ }, R = ({ children: e, entityManifest: t, config: n }) => {
174
+ let { t: r } = A();
175
+ return /* @__PURE__ */ O(L, {
172
176
  children: e,
173
177
  entityManifest: t,
174
178
  config: n,
@@ -176,6 +180,6 @@ var P = (e, t, n, r) => {
176
180
  });
177
181
  };
178
182
  //#endregion
179
- export { I as BackofficeEntityListPage, I as default };
183
+ export { R as BackofficeEntityListPage, R as default };
180
184
 
181
185
  //# sourceMappingURL=BackofficeEntityListPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeEntityListPage.js","names":[],"sources":["../../../src/pages/BackofficeEntityListPage.tsx"],"sourcesContent":["import {\n Suspense,\n type JSX,\n type ReactNode,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport Link from '@plumile/router/routing/Link.js';\nimport type {\n BackofficeEntityManifestItem,\n BackofficePreparedListLayoutRoute,\n BackofficeRuntimeResolvedListFacetConfig,\n BackofficeRowFlagSpec,\n} from '@plumile/backoffice-core/types.js';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { LinkButton } from '@plumile/ui/atomic/atoms/button/LinkButton.js';\nimport {\n type DataTableColumn,\n type GetRowId,\n} from '@plumile/ui/components/data-table/DataTable.js';\nimport { TableCell } from '@plumile/ui/components/data-table/TableCell.js';\nimport { EyeSvg } from '@plumile/ui/icons/EyeSvg.js';\nimport { BackofficeEntityListScaffold } from '../components/backoffice/scaffolds/BackofficeEntityListScaffold.js';\nimport { LazyBackofficeEntityActionFormDialog } from '../components/backoffice/actions/LazyBackofficeEntityActionFormDialog.js';\nimport { buildDataTableColumns } from '../components/backoffice/columns/buildDataTableColumns.js';\nimport { RowFlagsCell } from '../components/backoffice/list/RowFlagsCell.js';\nimport { useBackofficeListUrlState } from '../hooks/useBackofficeListUrlState.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport * as pageStyles from './backofficeEntityListPage.css.js';\nimport { rowFlagsColumnCell } from '../components/backoffice/list/RowFlagsCell.css.js';\nimport { BackofficeRightPageLayout } from '../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js';\nimport { buildEntityListBreadcrumb } from '../components/backoffice/layout/breadcrumb/buildBreadcrumbs.js';\nimport { BackofficeEntityListRouteProvider } from './BackofficeEntityListRouteContext.js';\nimport {\n buildActionsColumn,\n computeActionsColumnWidthPx,\n computeRowFlagsColumnWidthPx,\n isFormMutationAction,\n isRouteAction,\n resolveLabel,\n resolveActionVariant,\n resolveTrackBySize,\n type ConnectionListConfig,\n} from './BackofficeEntityListPage.helpers.js';\n\nexport type BackofficeEntityListPageProps = {\n children?: ReactNode;\n entityManifest: BackofficeEntityManifestItem;\n config: BackofficeRuntimeResolvedListFacetConfig;\n prepared: BackofficePreparedListLayoutRoute;\n};\n\nconst applyListEdgeColumns = <Row,>(\n inputColumns: readonly DataTableColumn<Row>[],\n rowFlags: readonly BackofficeRowFlagSpec<Row>[] | undefined,\n actionCount: number,\n tApp: TFunction,\n): {\n columns: readonly DataTableColumn<Row>[];\n gridTemplateColumns?: string;\n} => {\n const hasFlags = rowFlags != null && rowFlags.length > 0;\n\n let columns = inputColumns;\n if (hasFlags) {\n const flagsColumn: DataTableColumn<Row> = {\n id: '__rowFlags',\n header: '',\n className: rowFlagsColumnCell,\n mobileRole: 'badge',\n cell: (row) => {\n return <RowFlagsCell row={row} flags={rowFlags} tApp={tApp} />;\n },\n };\n\n // Ensure we never pick the flags column as \"primary\".\n const withFlags = [flagsColumn, ...inputColumns];\n const hasPrimary = withFlags.some((col) => {\n return col.isPrimary === true;\n });\n\n columns = withFlags;\n if (!hasPrimary) {\n columns = withFlags.map((col, index) => {\n if (index === 1) {\n return { ...col, isPrimary: true };\n }\n return col;\n });\n }\n }\n\n let flagCount = 0;\n if (hasFlags) {\n flagCount = rowFlags.length;\n }\n const flagsWidthPx = computeRowFlagsColumnWidthPx(flagCount);\n const actionsWidthPx = computeActionsColumnWidthPx(actionCount);\n\n // We always include the right-side \"actions\" column in list pages.\n let leftColumnCount = 0;\n if (hasFlags) {\n leftColumnCount = 1;\n }\n const middleCount = columns.length - leftColumnCount - 1;\n\n const middleTracks = columns\n .slice(leftColumnCount, leftColumnCount + Math.max(0, middleCount))\n .map((column) => {\n return resolveTrackBySize(column as DataTableColumn<unknown>, '1fr');\n })\n .join(' ');\n\n let gridTemplateColumns = '';\n if (hasFlags) {\n gridTemplateColumns = `${flagsWidthPx}px ${middleTracks} ${actionsWidthPx}px`;\n } else {\n gridTemplateColumns = `${middleTracks} ${actionsWidthPx}px`;\n }\n\n return { columns, gridTemplateColumns };\n};\n\nconst BackofficeEntityConnectionListPage = ({\n children,\n config,\n breadcrumb,\n}: Omit<BackofficeEntityListPageProps, 'config' | 'prepared'> & {\n config: ConnectionListConfig;\n breadcrumb: ReturnType<typeof buildEntityListBreadcrumb>;\n}): JSX.Element | null => {\n const listConfig = config.list;\n\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const [activeFormActionId, setActiveFormActionId] = useState<string | null>(\n null,\n );\n const [countFetchKey, setCountFetchKey] = useState(0);\n const refreshRef = useRef<(() => void) | null>(null);\n\n const registerRefresh = useCallback((refresh: (() => void) | null) => {\n refreshRef.current = refresh;\n }, []);\n\n const { columns, gridTemplateColumns } = useMemo((): {\n columns: readonly DataTableColumn<unknown>[];\n gridTemplateColumns?: string;\n } => {\n const baseColumns = buildDataTableColumns(listConfig.columns, {\n tApp,\n t,\n });\n const actionsColumn = buildActionsColumn({\n ariaLabel: t('actions.view'),\n fallback: t('common.notAvailable'),\n className: pageStyles.actionsColumnCell,\n resolveDetailHref: (id) => {\n return config.routes.detail(id);\n },\n renderAction: ({ href, ariaLabel }) => {\n return (\n <TableCell.Actions>\n <Link\n to={href}\n className={pageStyles.actionTrigger}\n aria-label={ariaLabel}\n title={ariaLabel}\n preloadOnHover=\"code\"\n >\n <EyeSvg width={16} height={16} />\n </Link>\n </TableCell.Actions>\n );\n },\n });\n const allColumns = [...baseColumns, actionsColumn];\n return applyListEdgeColumns(allColumns, listConfig.rowFlags, 1, tApp);\n }, [config.routes, listConfig.columns, listConfig.rowFlags, t, tApp]);\n\n const getRowId = useCallback<GetRowId<unknown>>(\n (row) => {\n return listConfig.getRowId(row);\n },\n [listConfig],\n );\n\n const { state, pushState } = useBackofficeListUrlState(config);\n\n const handleRefreshRequest = useCallback(() => {\n setCountFetchKey((current) => {\n return current + 1;\n });\n refreshRef.current?.();\n }, []);\n\n const listActions = useMemo(() => {\n return config.listActions ?? [];\n }, [config.listActions]);\n const visibleActions = useMemo(() => {\n return listActions.filter((action) => {\n if (action.isVisible == null) {\n return true;\n }\n return action.isVisible(null);\n });\n }, [listActions]);\n\n const headerActions = useMemo(() => {\n if (visibleActions.length === 0) {\n return undefined;\n }\n return (\n <div className={pageStyles.headerActions}>\n {visibleActions.map((action, index) => {\n const { variant: actionVariant } = action;\n const label = resolveLabel(action.label, tApp);\n let ariaLabel = label;\n if (action.ariaLabel != null) {\n ariaLabel = resolveLabel(action.ariaLabel, tApp);\n }\n const variant = resolveActionVariant(actionVariant, index);\n const size = action.size ?? 'small';\n const isDisabled = action.isDisabled?.(null) === true;\n\n if (isRouteAction(action)) {\n const href = action.to(null);\n return (\n <LinkButton\n key={action.id}\n to={href}\n variant={variant}\n size={size}\n isDisabled={isDisabled}\n aria-label={ariaLabel}\n preloadOnHover=\"code-and-data\"\n >\n {label}\n </LinkButton>\n );\n }\n\n if (isFormMutationAction(action)) {\n return (\n <Button\n key={action.id}\n type=\"button\"\n variant={variant}\n size={size}\n disabled={isDisabled}\n onClick={() => {\n setActiveFormActionId(action.id);\n }}\n aria-label={ariaLabel}\n >\n {label}\n </Button>\n );\n }\n\n return null;\n })}\n </div>\n );\n }, [tApp, visibleActions]);\n\n const activeFormAction = listActions.find((action) => {\n return action.id === activeFormActionId;\n });\n\n const renderLoadingScaffold = () => {\n return (\n <BackofficeEntityListScaffold\n config={config}\n state={state}\n pushState={pushState}\n headerActions={headerActions}\n rows={[]}\n columns={columns}\n gridTemplateColumns={gridTemplateColumns}\n getRowId={getRowId}\n hasNextPage={false}\n isLoadingMore={false}\n isRefreshing={false}\n onLoadMore={() => {}}\n onRefresh={handleRefreshRequest}\n totalCount={null}\n isLoadingInitial\n />\n );\n };\n\n const contextValue = useMemo(() => {\n return {\n config,\n state,\n pushState,\n headerActions,\n columns,\n gridTemplateColumns,\n getRowId,\n countFetchKey,\n bumpCountFetchKey: () => {\n setCountFetchKey((current) => {\n return current + 1;\n });\n },\n registerRefresh,\n };\n }, [\n columns,\n config,\n countFetchKey,\n getRowId,\n gridTemplateColumns,\n headerActions,\n pushState,\n registerRefresh,\n state,\n ]);\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <BackofficeEntityListRouteProvider value={contextValue}>\n <Suspense fallback={renderLoadingScaffold()}>{children}</Suspense>\n </BackofficeEntityListRouteProvider>\n {activeFormAction != null && isFormMutationAction(activeFormAction) && (\n <LazyBackofficeEntityActionFormDialog\n isOpen\n action={activeFormAction}\n node={null}\n onClose={() => {\n setActiveFormActionId(null);\n }}\n onSuccess={handleRefreshRequest}\n />\n )}\n </BackofficeRightPageLayout>\n );\n};\n\nexport const BackofficeEntityListPage = ({\n children,\n entityManifest,\n config,\n}: BackofficeEntityListPageProps): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const breadcrumb = buildEntityListBreadcrumb(config, tApp);\n\n return (\n <BackofficeEntityConnectionListPage\n children={children}\n entityManifest={entityManifest}\n config={config}\n breadcrumb={breadcrumb}\n />\n );\n};\n\nexport default BackofficeEntityListPage;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BackofficeEntityListPage.js","names":[],"sources":["../../../src/pages/BackofficeEntityListPage.tsx"],"sourcesContent":["import {\n Suspense,\n type JSX,\n type ReactNode,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport type { TFunction } from 'i18next';\nimport { useTranslation } from 'react-i18next';\nimport Link from '@plumile/router/routing/Link.js';\nimport type {\n BackofficeEntityManifestItem,\n BackofficePreparedListLayoutRoute,\n BackofficeRuntimeResolvedListFacetConfig,\n BackofficeRowFlagSpec,\n} from '@plumile/backoffice-core/types.js';\nimport { Button } from '@plumile/ui/atomic/atoms/button/Button.js';\nimport { LinkButton } from '@plumile/ui/atomic/atoms/button/LinkButton.js';\nimport {\n type DataTableColumn,\n type GetRowId,\n} from '@plumile/ui/components/data-table/DataTable.js';\nimport { TableCell } from '@plumile/ui/components/data-table/TableCell.js';\nimport { EyeSvg } from '@plumile/ui/icons/EyeSvg.js';\nimport { BackofficeEntityListScaffold } from '../components/backoffice/scaffolds/BackofficeEntityListScaffold.js';\nimport { LazyBackofficeEntityActionFormDialog } from '../components/backoffice/actions/LazyBackofficeEntityActionFormDialog.js';\nimport { buildDataTableColumns } from '../components/backoffice/columns/buildDataTableColumns.js';\nimport { RowFlagsCell } from '../components/backoffice/list/RowFlagsCell.js';\nimport { useBackofficeListUrlState } from '../hooks/useBackofficeListUrlState.js';\nimport { useBackofficeReactTranslation } from '../i18n/useBackofficeReactTranslation.js';\nimport {\n createBackofficeEntityListUiStateKey,\n useBackofficeListFilterDrawerState,\n} from '../provider/BackofficeListUiStateContext.js';\nimport * as pageStyles from './backofficeEntityListPage.css.js';\nimport { rowFlagsColumnCell } from '../components/backoffice/list/RowFlagsCell.css.js';\nimport { BackofficeRightPageLayout } from '../components/backoffice/layout/breadcrumb/BackofficeRightPageLayout.js';\nimport { buildEntityListBreadcrumb } from '../components/backoffice/layout/breadcrumb/buildBreadcrumbs.js';\nimport { BackofficeEntityListRouteProvider } from './BackofficeEntityListRouteContext.js';\nimport {\n buildActionsColumn,\n computeActionsColumnWidthPx,\n computeRowFlagsColumnWidthPx,\n isFormMutationAction,\n isRouteAction,\n resolveLabel,\n resolveActionVariant,\n resolveTrackBySize,\n type ConnectionListConfig,\n} from './BackofficeEntityListPage.helpers.js';\n\nexport type BackofficeEntityListPageProps = {\n children?: ReactNode;\n entityManifest: BackofficeEntityManifestItem;\n config: BackofficeRuntimeResolvedListFacetConfig;\n prepared: BackofficePreparedListLayoutRoute;\n};\n\nconst applyListEdgeColumns = <Row,>(\n inputColumns: readonly DataTableColumn<Row>[],\n rowFlags: readonly BackofficeRowFlagSpec<Row>[] | undefined,\n actionCount: number,\n tApp: TFunction,\n): {\n columns: readonly DataTableColumn<Row>[];\n gridTemplateColumns?: string;\n} => {\n const hasFlags = rowFlags != null && rowFlags.length > 0;\n\n let columns = inputColumns;\n if (hasFlags) {\n const flagsColumn: DataTableColumn<Row> = {\n id: '__rowFlags',\n header: '',\n className: rowFlagsColumnCell,\n mobileRole: 'badge',\n cell: (row) => {\n return <RowFlagsCell row={row} flags={rowFlags} tApp={tApp} />;\n },\n };\n\n // Ensure we never pick the flags column as \"primary\".\n const withFlags = [flagsColumn, ...inputColumns];\n const hasPrimary = withFlags.some((col) => {\n return col.isPrimary === true;\n });\n\n columns = withFlags;\n if (!hasPrimary) {\n columns = withFlags.map((col, index) => {\n if (index === 1) {\n return { ...col, isPrimary: true };\n }\n return col;\n });\n }\n }\n\n let flagCount = 0;\n if (hasFlags) {\n flagCount = rowFlags.length;\n }\n const flagsWidthPx = computeRowFlagsColumnWidthPx(flagCount);\n const actionsWidthPx = computeActionsColumnWidthPx(actionCount);\n\n // We always include the right-side \"actions\" column in list pages.\n let leftColumnCount = 0;\n if (hasFlags) {\n leftColumnCount = 1;\n }\n const middleCount = columns.length - leftColumnCount - 1;\n\n const middleTracks = columns\n .slice(leftColumnCount, leftColumnCount + Math.max(0, middleCount))\n .map((column) => {\n return resolveTrackBySize(column as DataTableColumn<unknown>, '1fr');\n })\n .join(' ');\n\n let gridTemplateColumns = '';\n if (hasFlags) {\n gridTemplateColumns = `${flagsWidthPx}px ${middleTracks} ${actionsWidthPx}px`;\n } else {\n gridTemplateColumns = `${middleTracks} ${actionsWidthPx}px`;\n }\n\n return { columns, gridTemplateColumns };\n};\n\nconst BackofficeEntityConnectionListPage = ({\n children,\n config,\n breadcrumb,\n}: Omit<BackofficeEntityListPageProps, 'config' | 'prepared'> & {\n config: ConnectionListConfig;\n breadcrumb: ReturnType<typeof buildEntityListBreadcrumb>;\n}): JSX.Element | null => {\n const listConfig = config.list;\n\n const { t: tApp } = useTranslation();\n const { t } = useBackofficeReactTranslation();\n const [activeFormActionId, setActiveFormActionId] = useState<string | null>(\n null,\n );\n const [countFetchKey, setCountFetchKey] = useState(0);\n const refreshRef = useRef<(() => void) | null>(null);\n\n const registerRefresh = useCallback((refresh: (() => void) | null) => {\n refreshRef.current = refresh;\n }, []);\n\n const { columns, gridTemplateColumns } = useMemo((): {\n columns: readonly DataTableColumn<unknown>[];\n gridTemplateColumns?: string;\n } => {\n const baseColumns = buildDataTableColumns(listConfig.columns, {\n tApp,\n t,\n });\n const actionsColumn = buildActionsColumn({\n ariaLabel: t('actions.view'),\n fallback: t('common.notAvailable'),\n className: pageStyles.actionsColumnCell,\n resolveDetailHref: (id) => {\n return config.routes.detail(id);\n },\n renderAction: ({ href, ariaLabel }) => {\n return (\n <TableCell.Actions>\n <Link\n to={href}\n className={pageStyles.actionTrigger}\n aria-label={ariaLabel}\n title={ariaLabel}\n preloadOnHover=\"code\"\n >\n <EyeSvg width={16} height={16} />\n </Link>\n </TableCell.Actions>\n );\n },\n });\n const allColumns = [...baseColumns, actionsColumn];\n return applyListEdgeColumns(allColumns, listConfig.rowFlags, 1, tApp);\n }, [config.routes, listConfig.columns, listConfig.rowFlags, t, tApp]);\n\n const getRowId = useCallback<GetRowId<unknown>>(\n (row) => {\n return listConfig.getRowId(row);\n },\n [listConfig],\n );\n\n const { state, pushState } = useBackofficeListUrlState(config);\n const listUiStateKey = useMemo(() => {\n return createBackofficeEntityListUiStateKey(config.id);\n }, [config.id]);\n const filterDrawerState = useBackofficeListFilterDrawerState(listUiStateKey);\n\n const handleRefreshRequest = useCallback(() => {\n setCountFetchKey((current) => {\n return current + 1;\n });\n refreshRef.current?.();\n }, []);\n\n const listActions = useMemo(() => {\n return config.listActions ?? [];\n }, [config.listActions]);\n const visibleActions = useMemo(() => {\n return listActions.filter((action) => {\n if (action.isVisible == null) {\n return true;\n }\n return action.isVisible(null);\n });\n }, [listActions]);\n\n const headerActions = useMemo(() => {\n if (visibleActions.length === 0) {\n return undefined;\n }\n return (\n <div className={pageStyles.headerActions}>\n {visibleActions.map((action, index) => {\n const { variant: actionVariant } = action;\n const label = resolveLabel(action.label, tApp);\n let ariaLabel = label;\n if (action.ariaLabel != null) {\n ariaLabel = resolveLabel(action.ariaLabel, tApp);\n }\n const variant = resolveActionVariant(actionVariant, index);\n const size = action.size ?? 'small';\n const isDisabled = action.isDisabled?.(null) === true;\n\n if (isRouteAction(action)) {\n const href = action.to(null);\n return (\n <LinkButton\n key={action.id}\n to={href}\n variant={variant}\n size={size}\n isDisabled={isDisabled}\n aria-label={ariaLabel}\n preloadOnHover=\"code-and-data\"\n >\n {label}\n </LinkButton>\n );\n }\n\n if (isFormMutationAction(action)) {\n return (\n <Button\n key={action.id}\n type=\"button\"\n variant={variant}\n size={size}\n disabled={isDisabled}\n onClick={() => {\n setActiveFormActionId(action.id);\n }}\n aria-label={ariaLabel}\n >\n {label}\n </Button>\n );\n }\n\n return null;\n })}\n </div>\n );\n }, [tApp, visibleActions]);\n\n const activeFormAction = listActions.find((action) => {\n return action.id === activeFormActionId;\n });\n\n const renderLoadingScaffold = () => {\n return (\n <BackofficeEntityListScaffold\n config={config}\n state={state}\n pushState={pushState}\n headerActions={headerActions}\n rows={[]}\n columns={columns}\n gridTemplateColumns={gridTemplateColumns}\n getRowId={getRowId}\n hasNextPage={false}\n isLoadingMore={false}\n isRefreshing={false}\n onLoadMore={() => {}}\n onRefresh={handleRefreshRequest}\n totalCount={null}\n isLoadingInitial\n filterDrawerState={filterDrawerState}\n />\n );\n };\n\n const contextValue = useMemo(() => {\n return {\n config,\n state,\n pushState,\n headerActions,\n columns,\n gridTemplateColumns,\n getRowId,\n countFetchKey,\n filterDrawerState,\n bumpCountFetchKey: () => {\n setCountFetchKey((current) => {\n return current + 1;\n });\n },\n registerRefresh,\n };\n }, [\n columns,\n config,\n countFetchKey,\n filterDrawerState,\n getRowId,\n gridTemplateColumns,\n headerActions,\n pushState,\n registerRefresh,\n state,\n ]);\n\n return (\n <BackofficeRightPageLayout breadcrumb={breadcrumb}>\n <BackofficeEntityListRouteProvider value={contextValue}>\n <Suspense fallback={renderLoadingScaffold()}>{children}</Suspense>\n </BackofficeEntityListRouteProvider>\n {activeFormAction != null && isFormMutationAction(activeFormAction) && (\n <LazyBackofficeEntityActionFormDialog\n isOpen\n action={activeFormAction}\n node={null}\n onClose={() => {\n setActiveFormActionId(null);\n }}\n onSuccess={handleRefreshRequest}\n />\n )}\n </BackofficeRightPageLayout>\n );\n};\n\nexport const BackofficeEntityListPage = ({\n children,\n entityManifest,\n config,\n}: BackofficeEntityListPageProps): JSX.Element | null => {\n const { t: tApp } = useTranslation();\n const breadcrumb = buildEntityListBreadcrumb(config, tApp);\n\n return (\n <BackofficeEntityConnectionListPage\n children={children}\n entityManifest={entityManifest}\n config={config}\n breadcrumb={breadcrumb}\n />\n );\n};\n\nexport default BackofficeEntityListPage;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"BackofficeEntityListRouteContext.js","names":[],"sources":["../../../src/pages/BackofficeEntityListRouteContext.tsx"],"sourcesContent":["import { createContext, useContext, type JSX } from 'react';\nimport {\n type DataTableColumn,\n type GetRowId,\n} from '@plumile/ui/components/data-table/DataTable.js';\n\nimport type { useBackofficeListUrlState } from '../hooks/useBackofficeListUrlState.js';\nimport type { ConnectionListConfig } from './BackofficeEntityListPage.helpers.js';\n\nexport type BackofficeEntityListRouteContextValue = {\n config: ConnectionListConfig;\n state: ReturnType<typeof useBackofficeListUrlState>['state'];\n pushState: ReturnType<typeof useBackofficeListUrlState>['pushState'];\n headerActions: JSX.Element | undefined;\n columns: readonly DataTableColumn<unknown>[];\n gridTemplateColumns?: string;\n getRowId: GetRowId<unknown>;\n countFetchKey: number;\n bumpCountFetchKey: () => void;\n registerRefresh: (refresh: (() => void) | null) => void;\n};\n\nconst BackofficeEntityListRouteContext =\n createContext<BackofficeEntityListRouteContextValue | null>(null);\n\nexport const BackofficeEntityListRouteProvider = ({\n children,\n value,\n}: {\n children: JSX.Element;\n value: BackofficeEntityListRouteContextValue;\n}): JSX.Element => {\n return (\n <BackofficeEntityListRouteContext.Provider value={value}>\n {children}\n </BackofficeEntityListRouteContext.Provider>\n );\n};\n\nexport const useBackofficeEntityListRouteContext =\n (): BackofficeEntityListRouteContextValue => {\n const value = useContext(BackofficeEntityListRouteContext);\n if (value == null) {\n throw new Error('BackofficeEntityListRouteContext is missing.');\n }\n return value;\n };\n"],"mappings":";;;AAsBA,IAAM,IACJ,EAA4D,IAAI,GAErD,KAAqC,EAChD,aACA,eAME,kBAAC,EAAiC,UAAlC;CAAkD;CAC/C;AACwC,CAAA,GAIlC,UACkC;CAC3C,IAAM,IAAQ,EAAW,CAAgC;CACzD,IAAI,KAAS,MACX,MAAU,MAAM,8CAA8C;CAEhE,OAAO;AACT"}
1
+ {"version":3,"file":"BackofficeEntityListRouteContext.js","names":[],"sources":["../../../src/pages/BackofficeEntityListRouteContext.tsx"],"sourcesContent":["import { createContext, useContext, type JSX } from 'react';\nimport {\n type DataTableColumn,\n type GetRowId,\n} from '@plumile/ui/components/data-table/DataTable.js';\n\nimport type { useBackofficeListUrlState } from '../hooks/useBackofficeListUrlState.js';\nimport type { BackofficeFilterDrawerState } from '../provider/BackofficeListUiStateContext.js';\nimport type { ConnectionListConfig } from './BackofficeEntityListPage.helpers.js';\n\nexport type BackofficeEntityListRouteContextValue = {\n config: ConnectionListConfig;\n state: ReturnType<typeof useBackofficeListUrlState>['state'];\n pushState: ReturnType<typeof useBackofficeListUrlState>['pushState'];\n headerActions: JSX.Element | undefined;\n columns: readonly DataTableColumn<unknown>[];\n gridTemplateColumns?: string;\n getRowId: GetRowId<unknown>;\n countFetchKey: number;\n bumpCountFetchKey: () => void;\n filterDrawerState: BackofficeFilterDrawerState;\n registerRefresh: (refresh: (() => void) | null) => void;\n};\n\nconst BackofficeEntityListRouteContext =\n createContext<BackofficeEntityListRouteContextValue | null>(null);\n\nexport const BackofficeEntityListRouteProvider = ({\n children,\n value,\n}: {\n children: JSX.Element;\n value: BackofficeEntityListRouteContextValue;\n}): JSX.Element => {\n return (\n <BackofficeEntityListRouteContext.Provider value={value}>\n {children}\n </BackofficeEntityListRouteContext.Provider>\n );\n};\n\nexport const useBackofficeEntityListRouteContext =\n (): BackofficeEntityListRouteContextValue => {\n const value = useContext(BackofficeEntityListRouteContext);\n if (value == null) {\n throw new Error('BackofficeEntityListRouteContext is missing.');\n }\n return value;\n };\n"],"mappings":";;;AAwBA,IAAM,IACJ,EAA4D,IAAI,GAErD,KAAqC,EAChD,aACA,eAME,kBAAC,EAAiC,UAAlC;CAAkD;CAC/C;AACwC,CAAA,GAIlC,UACkC;CAC3C,IAAM,IAAQ,EAAW,CAAgC;CACzD,IAAI,KAAS,MACX,MAAU,MAAM,8CAA8C;CAEhE,OAAO;AACT"}