@compill/admin 1.0.103 → 1.0.105

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 (165) hide show
  1. package/dist/index.cjs +2054 -0
  2. package/dist/index.d.cts +565 -0
  3. package/dist/index.d.ts +565 -50
  4. package/dist/index.js +2000 -50
  5. package/package.json +19 -18
  6. package/dist/lib/SectionTitle.d.ts +0 -2
  7. package/dist/lib/SectionTitle.js +0 -4
  8. package/dist/lib/breadcrumbs/BreadCrumbs.d.ts +0 -15
  9. package/dist/lib/breadcrumbs/BreadCrumbs.js +0 -29
  10. package/dist/lib/buttons/DialogButton.d.ts +0 -7
  11. package/dist/lib/buttons/DialogButton.js +0 -15
  12. package/dist/lib/buttons/InvalidateButton.d.ts +0 -6
  13. package/dist/lib/buttons/InvalidateButton.js +0 -11
  14. package/dist/lib/buttons/NavigateButton.d.ts +0 -4
  15. package/dist/lib/buttons/NavigateButton.js +0 -12
  16. package/dist/lib/buttons/PublishButton.d.ts +0 -9
  17. package/dist/lib/buttons/PublishButton.js +0 -17
  18. package/dist/lib/buttons/UpdateButton.d.ts +0 -2
  19. package/dist/lib/buttons/UpdateButton.js +0 -11
  20. package/dist/lib/buttons/ViewButton.d.ts +0 -5
  21. package/dist/lib/buttons/ViewButton.js +0 -13
  22. package/dist/lib/cells/OrderCell.d.ts +0 -11
  23. package/dist/lib/cells/OrderCell.js +0 -26
  24. package/dist/lib/json/DetailsView.d.ts +0 -5
  25. package/dist/lib/json/DetailsView.js +0 -69
  26. package/dist/lib/json/EditItemView.d.ts +0 -2
  27. package/dist/lib/json/EditItemView.js +0 -6
  28. package/dist/lib/json/MultiQueryWrapper.d.ts +0 -5
  29. package/dist/lib/json/MultiQueryWrapper.js +0 -61
  30. package/dist/lib/json/QueryWrapper.d.ts +0 -6
  31. package/dist/lib/json/QueryWrapper.js +0 -29
  32. package/dist/lib/json/ScreenRenderer.d.ts +0 -6
  33. package/dist/lib/json/ScreenRenderer.js +0 -19
  34. package/dist/lib/json/ScreenTopBar.d.ts +0 -15
  35. package/dist/lib/json/ScreenTopBar.js +0 -18
  36. package/dist/lib/json/TabbedView.d.ts +0 -3
  37. package/dist/lib/json/TabbedView.js +0 -21
  38. package/dist/lib/json/buttons/ActionButton.d.ts +0 -14
  39. package/dist/lib/json/buttons/ActionButton.js +0 -11
  40. package/dist/lib/json/buttons/ConfirmationActionButton.d.ts +0 -26
  41. package/dist/lib/json/buttons/ConfirmationActionButton.js +0 -20
  42. package/dist/lib/json/dialog/DialogRenderer.d.ts +0 -11
  43. package/dist/lib/json/dialog/DialogRenderer.js +0 -14
  44. package/dist/lib/json/dialog/ItemDeleteDialog.d.ts +0 -17
  45. package/dist/lib/json/dialog/ItemDeleteDialog.js +0 -14
  46. package/dist/lib/json/dialog/ItemEditDialog.d.ts +0 -32
  47. package/dist/lib/json/dialog/ItemEditDialog.js +0 -77
  48. package/dist/lib/json/dialog/MultiQueryWrapperDialog.d.ts +0 -7
  49. package/dist/lib/json/dialog/MultiQueryWrapperDialog.js +0 -23
  50. package/dist/lib/json/dialog/QueryWrapperDialog.d.ts +0 -13
  51. package/dist/lib/json/dialog/QueryWrapperDialog.js +0 -20
  52. package/dist/lib/json/table/RefreshButton.d.ts +0 -3
  53. package/dist/lib/json/table/RefreshButton.js +0 -11
  54. package/dist/lib/json/table/TableRowActionsView.d.ts +0 -11
  55. package/dist/lib/json/table/TableRowActionsView.js +0 -36
  56. package/dist/lib/json/table/TableRowPublishPostButton.d.ts +0 -8
  57. package/dist/lib/json/table/TableRowPublishPostButton.js +0 -20
  58. package/dist/lib/json/table/TableView.d.ts +0 -3
  59. package/dist/lib/json/table/TableView.js +0 -65
  60. package/dist/lib/json/table/TableViewContext.d.ts +0 -14
  61. package/dist/lib/json/table/TableViewContext.js +0 -58
  62. package/dist/lib/json/table/useTableProps.d.ts +0 -3
  63. package/dist/lib/json/table/useTableProps.js +0 -57
  64. package/dist/lib/json/types/DetailsView.d.ts +0 -57
  65. package/dist/lib/json/types/DetailsView.js +0 -1
  66. package/dist/lib/json/types/EditItemDialog.d.ts +0 -4
  67. package/dist/lib/json/types/EditItemDialog.js +0 -1
  68. package/dist/lib/json/types/MultiQueryWrapper.d.ts +0 -18
  69. package/dist/lib/json/types/MultiQueryWrapper.js +0 -1
  70. package/dist/lib/json/types/MultiQueryWrapperDialog.d.ts +0 -13
  71. package/dist/lib/json/types/MultiQueryWrapperDialog.js +0 -1
  72. package/dist/lib/json/types/QueryWrapper.d.ts +0 -27
  73. package/dist/lib/json/types/QueryWrapper.js +0 -1
  74. package/dist/lib/json/types/QueryWrapperDialog.d.ts +0 -22
  75. package/dist/lib/json/types/QueryWrapperDialog.js +0 -1
  76. package/dist/lib/json/types/ScreenConfig.d.ts +0 -8
  77. package/dist/lib/json/types/ScreenConfig.js +0 -1
  78. package/dist/lib/json/types/TabbedView.d.ts +0 -22
  79. package/dist/lib/json/types/TabbedView.js +0 -1
  80. package/dist/lib/json/types/TableView.d.ts +0 -117
  81. package/dist/lib/json/types/TableView.js +0 -1
  82. package/dist/lib/layout/AdminLayout.d.ts +0 -13
  83. package/dist/lib/layout/AdminLayout.js +0 -15
  84. package/dist/lib/layout/ButtonBar.d.ts +0 -19
  85. package/dist/lib/layout/ButtonBar.js +0 -19
  86. package/dist/lib/layout/Content.d.ts +0 -9
  87. package/dist/lib/layout/Content.js +0 -9
  88. package/dist/lib/layout/PageTitleBar.d.ts +0 -6
  89. package/dist/lib/layout/PageTitleBar.js +0 -4
  90. package/dist/lib/layout/Sidebar.d.ts +0 -20
  91. package/dist/lib/layout/Sidebar.js +0 -12
  92. package/dist/lib/layout/menu/Menu.d.ts +0 -12
  93. package/dist/lib/layout/menu/Menu.js +0 -23
  94. package/dist/lib/layout/menu/MenuButton.d.ts +0 -6
  95. package/dist/lib/layout/menu/MenuButton.js +0 -5
  96. package/dist/lib/layout/menu/MenuConfig.d.ts +0 -13
  97. package/dist/lib/layout/menu/MenuConfig.js +0 -1
  98. package/dist/lib/layout/menu/MenuItem.d.ts +0 -11
  99. package/dist/lib/layout/menu/MenuItem.js +0 -11
  100. package/dist/lib/layout/menu/NextMenuItem.d.ts +0 -11
  101. package/dist/lib/layout/menu/NextMenuItem.js +0 -11
  102. package/dist/lib/layout/menu/SelectedIndicator.d.ts +0 -3
  103. package/dist/lib/layout/menu/SelectedIndicator.js +0 -4
  104. package/dist/lib/layout/menu/UserBlock.d.ts +0 -9
  105. package/dist/lib/layout/menu/UserBlock.js +0 -34
  106. package/dist/lib/modal/AttachDialog.d.ts +0 -30
  107. package/dist/lib/modal/AttachDialog.js +0 -73
  108. package/dist/lib/modal/FormActionDialog.d.ts +0 -23
  109. package/dist/lib/modal/FormActionDialog.js +0 -20
  110. package/dist/lib/page/PageContainer.d.ts +0 -2
  111. package/dist/lib/page/PageContainer.js +0 -5
  112. package/dist/lib/page/PageContentEditor.d.ts +0 -4
  113. package/dist/lib/page/PageContentEditor.js +0 -10
  114. package/dist/lib/page/PageMain.d.ts +0 -2
  115. package/dist/lib/page/PageMain.js +0 -5
  116. package/dist/lib/page/PageQueryStateContainer.d.ts +0 -21
  117. package/dist/lib/page/PageQueryStateContainer.js +0 -16
  118. package/dist/lib/page/PageSectionTitle.d.ts +0 -2
  119. package/dist/lib/page/PageSectionTitle.js +0 -4
  120. package/dist/lib/page/PageSidebar.d.ts +0 -2
  121. package/dist/lib/page/PageSidebar.js +0 -4
  122. package/dist/lib/page/PageSidebarSection.d.ts +0 -4
  123. package/dist/lib/page/PageSidebarSection.js +0 -5
  124. package/dist/lib/page/PageStateContainer.d.ts +0 -7
  125. package/dist/lib/page/PageStateContainer.js +0 -7
  126. package/dist/lib/page/PageSubSectionTitle.d.ts +0 -2
  127. package/dist/lib/page/PageSubSectionTitle.js +0 -4
  128. package/dist/lib/page/PageTitle.d.ts +0 -2
  129. package/dist/lib/page/PageTitle.js +0 -4
  130. package/dist/lib/page/PageTopBar.d.ts +0 -13
  131. package/dist/lib/page/PageTopBar.js +0 -78
  132. package/dist/lib/status/StatusBadge.d.ts +0 -4
  133. package/dist/lib/status/StatusBadge.js +0 -21
  134. package/dist/lib/table/TableColumnButton.d.ts +0 -1
  135. package/dist/lib/table/TableColumnButton.js +0 -53
  136. package/dist/lib/table/TableContainer.d.ts +0 -10
  137. package/dist/lib/table/TableContainer.js +0 -6
  138. package/dist/lib/table/TableContainerContext.d.ts +0 -18
  139. package/dist/lib/table/TableContainerContext.js +0 -40
  140. package/dist/lib/table/TableCreateButton.d.ts +0 -4
  141. package/dist/lib/table/TableCreateButton.js +0 -7
  142. package/dist/lib/table/TableFilterButton.d.ts +0 -2
  143. package/dist/lib/table/TableFilterButton.js +0 -8
  144. package/dist/lib/table/TableFilters.d.ts +0 -9
  145. package/dist/lib/table/TableFilters.js +0 -27
  146. package/dist/lib/table/TableMassActions.d.ts +0 -6
  147. package/dist/lib/table/TableMassActions.js +0 -9
  148. package/dist/lib/table/TableRowActionBar.d.ts +0 -10
  149. package/dist/lib/table/TableRowActionBar.js +0 -8
  150. package/dist/lib/table/TableRowActionButton.d.ts +0 -4
  151. package/dist/lib/table/TableRowActionButton.js +0 -5
  152. package/dist/lib/table/TableRowActionDialogButton.d.ts +0 -4
  153. package/dist/lib/table/TableRowActionDialogButton.js +0 -6
  154. package/dist/lib/table/TableRowDeleteButton.d.ts +0 -2
  155. package/dist/lib/table/TableRowDeleteButton.js +0 -6
  156. package/dist/lib/table/TableRowEditButton.d.ts +0 -2
  157. package/dist/lib/table/TableRowEditButton.js +0 -6
  158. package/dist/lib/table/TableRowNavigateButton.d.ts +0 -4
  159. package/dist/lib/table/TableRowNavigateButton.js +0 -14
  160. package/dist/lib/table/TableRowPublishPostButton.d.ts +0 -8
  161. package/dist/lib/table/TableRowPublishPostButton.js +0 -19
  162. package/dist/lib/table/TableRowViewButton.d.ts +0 -4
  163. package/dist/lib/table/TableRowViewButton.js +0 -13
  164. package/dist/lib/table/TableTopBar.d.ts +0 -8
  165. package/dist/lib/table/TableTopBar.js +0 -5
package/dist/index.cjs ADDED
@@ -0,0 +1,2054 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('@soperio/jsx-runtime');
4
+ var api = require('@compill/api');
5
+ var components = require('@compill/components');
6
+ var js = require('@mdi/js');
7
+ var ui = require('@valerya/ui');
8
+ var compat = require('es-toolkit/compat');
9
+ var Link = require('next/link');
10
+ var reactRouterDom = require('react-router-dom');
11
+ var React8 = require('react');
12
+ var adminApi = require('@compill/admin-api');
13
+ var formik = require('formik');
14
+ var reactToastify = require('react-toastify');
15
+ var reactHotkeysHook = require('react-hotkeys-hook');
16
+ var form = require('@compill/form');
17
+ var react = require('@soperio/react');
18
+ var formEditor = require('@compill/form-editor');
19
+ var editor = require('@compill/editor');
20
+ var reactDom = require('react-dom');
21
+ var router = require('next/router');
22
+ var table = require('@compill/table');
23
+ var esToolkit = require('es-toolkit');
24
+ var hooks = require('@compill/hooks');
25
+ var env = require('@compill/env');
26
+ var reactTable = require('@tanstack/react-table');
27
+ var reactQuery = require('@tanstack/react-query');
28
+ var Image = require('next/image');
29
+ var auth = require('@compill/auth');
30
+
31
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
32
+
33
+ var Link__default = /*#__PURE__*/_interopDefault(Link);
34
+ var React8__default = /*#__PURE__*/_interopDefault(React8);
35
+ var Image__default = /*#__PURE__*/_interopDefault(Image);
36
+
37
+ // src/lib/SectionTitle.tsx
38
+ function SectionTitle({ children, ...props }) {
39
+ return /* @__PURE__ */ jsxRuntime.jsx("h2", { textSize: "xl", fontWeight: "600", textColor: "slate-800", ...props, children });
40
+ }
41
+ function Breadcrumbs({ breadcrumbs, ...props }) {
42
+ if (compat.isArray(breadcrumbs)) {
43
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { dflex: true, alignItems: "center", trait: "typo.h5", ...props, children: breadcrumbs.map((b, index) => /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbItem, { breadcrumb: b, showSeparator: index > 0 }, index)) });
44
+ }
45
+ return /* @__PURE__ */ jsxRuntime.jsx(QueryBreadcrumbs, { queryFn: breadcrumbs.queryFn, queryField: breadcrumbs.queryField, generate: breadcrumbs.generate });
46
+ }
47
+ function QueryBreadcrumbs({ queryFn, queryField, generate, ...props }) {
48
+ const params = reactRouterDom.useParams();
49
+ const id = queryField ? params[queryField] : void 0;
50
+ const { data, isLoading, isError } = api.useApiQuery([""], queryFn, id);
51
+ if (isLoading || isError) {
52
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { dflex: true, alignItems: "center", children: [
53
+ /* @__PURE__ */ jsxRuntime.jsx(components.Shimmer, { h: "8", w: "24" }),
54
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: js.mdiCircleSmall, mx: "1" }),
55
+ /* @__PURE__ */ jsxRuntime.jsx(components.Shimmer, { h: "8", w: "20" })
56
+ ] });
57
+ }
58
+ const breadcrumbs = generate(data);
59
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { dflex: true, alignItems: "center", trait: "typo.h5", ...props, children: breadcrumbs.map((b, index) => /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbItem, { breadcrumb: b, showSeparator: index > 0 }, index)) });
60
+ }
61
+ function BreadcrumbItem({ breadcrumb, showSeparator }) {
62
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
63
+ showSeparator && /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: js.mdiCircleSmall, mx: "1" }),
64
+ /* @__PURE__ */ jsxRuntime.jsx(Link__default.default, { href: `/${breadcrumb.path || "#"}`, children: /* @__PURE__ */ jsxRuntime.jsx(
65
+ "span",
66
+ {
67
+ hover_textDecoration: breadcrumb.path ? "underline" : void 0,
68
+ cursor: breadcrumb.path ? "pointer" : void 0,
69
+ children: breadcrumb.label
70
+ }
71
+ ) })
72
+ ] });
73
+ }
74
+ function DialogButton({ buildDialog, ...props }) {
75
+ const [showDialog, setShowDialog] = React8__default.default.useState(false);
76
+ const onShowDialog = React8__default.default.useCallback((event) => {
77
+ event?.preventDefault();
78
+ event?.stopPropagation();
79
+ setShowDialog(true);
80
+ }, [setShowDialog]);
81
+ const onCloseDialog = React8__default.default.useCallback(() => {
82
+ setShowDialog(false);
83
+ }, [setShowDialog]);
84
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
85
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { onClick: onShowDialog, ...props }),
86
+ showDialog && buildDialog(onCloseDialog)
87
+ ] });
88
+ }
89
+ function ButtonBar({ children, ...props }) {
90
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { dflex: true, border: "1px", borderColor: "zinc-200", divideX: "1px", divideColor: "zinc-200", rounded: "lg", overflow: "hidden", ...props, children });
91
+ }
92
+ var ButtonBarButton = React8__default.default.forwardRef(
93
+ function({ icon, children, ...props }, ref) {
94
+ return /* @__PURE__ */ jsxRuntime.jsxs(
95
+ ui.Button,
96
+ {
97
+ scheme: "dark",
98
+ size: "sm",
99
+ aspectRatio: icon && !children ? "square" : void 0,
100
+ variant: "borderless",
101
+ dflex: true,
102
+ alignItems: "center",
103
+ placeContent: "center",
104
+ corners: "square",
105
+ gap: "2",
106
+ ...props,
107
+ ref,
108
+ children: [
109
+ icon && /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: icon }),
110
+ children
111
+ ]
112
+ }
113
+ );
114
+ }
115
+ );
116
+ var ButtonBarSubmitButton = React8__default.default.forwardRef(
117
+ function({ useDirty, disabled, icon, children, ...props }, ref) {
118
+ const { dirty, handleSubmit } = formik.useFormikContext() ?? { dirty: false, handleSubmit: void 0};
119
+ const onSubmit = React8__default.default.useCallback(() => handleSubmit(), [handleSubmit]);
120
+ return /* @__PURE__ */ jsxRuntime.jsxs(
121
+ ui.Button,
122
+ {
123
+ scheme: "dark",
124
+ size: "sm",
125
+ aspectRatio: icon && !children ? "square" : void 0,
126
+ variant: "borderless",
127
+ dflex: true,
128
+ alignItems: "center",
129
+ placeContent: "center",
130
+ corners: "square",
131
+ gap: "2",
132
+ disabled: useDirty && !dirty || disabled,
133
+ onClick: onSubmit,
134
+ ...props,
135
+ ref,
136
+ children: [
137
+ icon && /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: icon }),
138
+ children
139
+ ]
140
+ }
141
+ );
142
+ }
143
+ );
144
+ function ButtonBarDialogButton({ icon, children, ...props }) {
145
+ return /* @__PURE__ */ jsxRuntime.jsxs(
146
+ DialogButton,
147
+ {
148
+ scheme: "dark",
149
+ size: "sm",
150
+ aspectRatio: icon && !children ? "square" : void 0,
151
+ variant: "borderless",
152
+ dflex: true,
153
+ alignItems: "center",
154
+ placeContent: "center",
155
+ corners: "square",
156
+ gap: "2",
157
+ ...props,
158
+ children: [
159
+ icon && /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: icon }),
160
+ children
161
+ ]
162
+ }
163
+ );
164
+ }
165
+ function InvalidateButton({ pathOrPermalink, ...props }) {
166
+ const api$1 = adminApi.INVALIDATE_API.new(pathOrPermalink);
167
+ const mutation = api.useApiMutation(api$1.invalidate, api$1.queryKey);
168
+ const invalidate = api.useMutate(mutation, { successMsg: "Page successfully invalidated" });
169
+ return /* @__PURE__ */ jsxRuntime.jsx(
170
+ ButtonBarButton,
171
+ {
172
+ title: "Regenerate",
173
+ disabled: mutation.isLoading,
174
+ onClick: invalidate,
175
+ icon: js.mdiDatabaseRefreshOutline,
176
+ ...props
177
+ }
178
+ );
179
+ }
180
+ function NavigateButton({ path, ...props }) {
181
+ const navigate = reactRouterDom.useNavigate();
182
+ const handleClick = React8__default.default.useCallback(() => {
183
+ navigate(path);
184
+ }, [navigate, path]);
185
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { type: "submit", scheme: "dark", variant: "glass", corners: "pill", w: "10", h: "10", onClick: handleClick, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: js.mdiPost }) });
186
+ }
187
+ function PublishButton({
188
+ status,
189
+ queryId,
190
+ api: api$1,
191
+ ...props
192
+ }) {
193
+ const isDraft = status == "draft";
194
+ const mutation = api.useInvalidateMutation(isDraft ? api$1.publish : api$1.unpublish, api$1.queryKey, queryId, { networkMode: "always" });
195
+ const publish = React8__default.default.useCallback(() => {
196
+ mutation.reset();
197
+ mutation.mutateAsync(queryId).then(() => reactToastify.toast.success(isDraft ? "Published!" : "Unpublished!")).catch((error) => reactToastify.toast.error(`Error: ${error}`));
198
+ }, [mutation, queryId]);
199
+ return /* @__PURE__ */ jsxRuntime.jsx(
200
+ ButtonBarButton,
201
+ {
202
+ disabled: mutation.isLoading,
203
+ onClick: publish,
204
+ icon: isDraft ? js.mdiEye : js.mdiEyeOff,
205
+ ...props,
206
+ children: isDraft ? "Publish" : "Switch to draft"
207
+ }
208
+ );
209
+ }
210
+ function UpdateButton({ ...props }) {
211
+ const { dirty, handleSubmit } = formik.useFormikContext() ?? { dirty: false, handleSubmit: void 0};
212
+ reactHotkeysHook.useHotkeys("ctrl+s", () => {
213
+ if (dirty && !props.disabled) handleSubmit();
214
+ }, { preventDefault: true }, [dirty, props, handleSubmit]);
215
+ return /* @__PURE__ */ jsxRuntime.jsx(ButtonBarSubmitButton, { icon: js.mdiCloudUpload, ...props, children: "Update" });
216
+ }
217
+ function ViewButton({ label, path, icon, ...props }) {
218
+ const openPage = React8__default.default.useCallback(() => {
219
+ window.open(path, "_blank");
220
+ }, [path]);
221
+ return /* @__PURE__ */ jsxRuntime.jsx(
222
+ ButtonBarButton,
223
+ {
224
+ onClick: openPage,
225
+ dflex: true,
226
+ alignItems: "center",
227
+ gap: "2",
228
+ icon: icon || js.mdiOpenInNew,
229
+ ...props,
230
+ children: label
231
+ }
232
+ );
233
+ }
234
+ function OrderCell({ api: api$1, postId, order }) {
235
+ const mutationDown = api.useInvalidateMutation(api$1.moveDown, api$1.queryKey);
236
+ const mutationUp = api.useInvalidateMutation(api$1.moveUp, api$1.queryKey);
237
+ const moveDown = React8__default.default.useCallback((e) => {
238
+ e.stopPropagation();
239
+ mutationDown.mutateAsync(postId).catch((error) => {
240
+ reactToastify.toast.error(`Error: ${error}`);
241
+ });
242
+ }, [mutationDown, postId]);
243
+ const moveUp = React8__default.default.useCallback((e) => {
244
+ e.stopPropagation();
245
+ mutationUp.mutateAsync(postId).catch((error) => {
246
+ reactToastify.toast.error(`Error: ${error}`);
247
+ });
248
+ }, [mutationUp, postId]);
249
+ return /* @__PURE__ */ jsxRuntime.jsxs(components.FlexCenter, { placeContent: "start", numericFontVariant: "tabular-nums", children: [
250
+ order,
251
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { ms: "3", variant: "borderless", scheme: "dark", onClick: moveUp, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: js.mdiArrowUpBoldBox }) }),
252
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "borderless", scheme: "dark", onClick: moveDown, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: js.mdiArrowDownBoldBox }) })
253
+ ] });
254
+ }
255
+ function PageContainer({ children, ...props }) {
256
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { center: true, dflex: true, flexCol: true, gap: "8", ...props, children });
257
+ }
258
+ function PageMain({ children, ...props }) {
259
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Tile, { scheme: "light", p: "5", ...props, children });
260
+ }
261
+ function PageContentEditor({ name, ...props }) {
262
+ const extensions = [editor.ImageExtension];
263
+ return /* @__PURE__ */ jsxRuntime.jsx(PageMain, { h: "min", ...props, children: /* @__PURE__ */ jsxRuntime.jsx(
264
+ formEditor.FormEditor,
265
+ {
266
+ minH: "128",
267
+ minW: "144",
268
+ maxW: props.maxW,
269
+ name,
270
+ placeHolder: "Write here...",
271
+ extensions
272
+ }
273
+ ) });
274
+ }
275
+ function PageQueryStateContainerInner({ queryId, api: api$1, apiFn, loadingStyles, errorStyles, children, ...props }) {
276
+ const { data, isLoading, isError } = apiFn == "getAll" ? api.useApiQuery(api$1.queryKey, api$1.getAll, props.apiParams) : api.useApiQuery(api$1.queryKey, api$1.get, queryId);
277
+ const invalidate = api.useInvalidateQuery(api$1.queryKey, queryId);
278
+ if (isLoading)
279
+ return /* @__PURE__ */ jsxRuntime.jsx(components.QueryLoadingState, { w: "full", h: "100%", ...loadingStyles });
280
+ if (isError)
281
+ return /* @__PURE__ */ jsxRuntime.jsx(components.RetryOnError, { p: "0", onClick: invalidate, ...errorStyles });
282
+ return /* @__PURE__ */ jsxRuntime.jsx(PageContainer, { ...props, children: apiFn == "get" ? children(data) : children(data) });
283
+ }
284
+ var PageQueryStateContainer = React8__default.default.forwardRef(PageQueryStateContainerInner);
285
+ function PageSidebar({ children, ...props }) {
286
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { w: "112", minW: "112", minH: "100%", gap: "8", dflex: true, flexCol: true, ...props, children });
287
+ }
288
+ function PageSectionTitle({ children, ...props }) {
289
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { trait: "typo.h6", mb: "5", ...props, children });
290
+ }
291
+ function PageSidebarSection({ title, children, ...props }) {
292
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { w: "full", ...props, children: [
293
+ title && /* @__PURE__ */ jsxRuntime.jsx(PageSectionTitle, { children: title }),
294
+ children
295
+ ] });
296
+ }
297
+ function PageTitle({ children, ...props }) {
298
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { trait: "typo.h5", ...props, children });
299
+ }
300
+ function PageTopBar({ title, breadcrumbs, children, ...props }) {
301
+ return /* @__PURE__ */ jsxRuntime.jsxs(components.FlexCenter, { gap: "3", minH: "9", ...props, children: [
302
+ title && /* @__PURE__ */ jsxRuntime.jsx(PageTitle, { children: title }),
303
+ breadcrumbs && /* @__PURE__ */ jsxRuntime.jsx(Breadcrumbs, { breadcrumbs }),
304
+ /* @__PURE__ */ jsxRuntime.jsx("div", { flexGrow: true }),
305
+ children
306
+ ] });
307
+ }
308
+ var [CP, usePageTabbedTopBarContext] = react.createContext();
309
+ function PageTabbedTopBarProvider({ children }) {
310
+ const [containerEl, setContainerEl] = React8__default.default.useState(null);
311
+ React8__default.default.createRef();
312
+ return /* @__PURE__ */ jsxRuntime.jsx(CP, { value: { containerEl, setContainerEl }, children });
313
+ }
314
+ function PageTabbedTopBar({ title, breadcrumbs, children, ...props }) {
315
+ const ref = React8__default.default.createRef();
316
+ const { setContainerEl } = usePageTabbedTopBarContext();
317
+ const [isSet, setIsSet] = React8__default.default.useState(false);
318
+ React8__default.default.useEffect(() => {
319
+ if (!isSet && ref.current) {
320
+ setContainerEl(ref.current);
321
+ setIsSet(true);
322
+ }
323
+ return () => setContainerEl(null);
324
+ }, []);
325
+ return /* @__PURE__ */ jsxRuntime.jsx(components.FlexCenter, { gap: "3", minH: "9", ...props, children: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
326
+ title && /* @__PURE__ */ jsxRuntime.jsx(PageTitle, { children: title }),
327
+ breadcrumbs && /* @__PURE__ */ jsxRuntime.jsx(Breadcrumbs, { breadcrumbs }),
328
+ /* @__PURE__ */ jsxRuntime.jsx("div", { flexGrow: true }),
329
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ref, dflex: true, flexRow: true, gap: "3" }),
330
+ children
331
+ ] }) });
332
+ }
333
+ function PageTopBarToolbar({ trackingRef, children }) {
334
+ const { containerEl } = usePageTabbedTopBarContext();
335
+ const [visible, setVisible] = React8__default.default.useState(false);
336
+ const portal = React8__default.default.useMemo(() => {
337
+ const node = containerEl;
338
+ return node;
339
+ }, [containerEl]);
340
+ const host = containerEl ?? (typeof window !== "undefined" ? document.body : void 0);
341
+ React8__default.default.useLayoutEffect(() => {
342
+ if (!portal || !host)
343
+ return;
344
+ try {
345
+ if (visible)
346
+ host.appendChild(portal);
347
+ else
348
+ host.removeChild(portal);
349
+ } catch (e) {
350
+ }
351
+ return () => {
352
+ try {
353
+ host.removeChild(portal);
354
+ } catch (e) {
355
+ }
356
+ };
357
+ }, [visible, portal, host]);
358
+ const callback = React8__default.default.useCallback((entries) => {
359
+ setVisible(entries[0].isVisible);
360
+ }, [children]);
361
+ React8__default.default.useEffect(() => {
362
+ const opts = {
363
+ root: null,
364
+ rootMargin: "0px",
365
+ threshold: 0,
366
+ /* required options*/
367
+ trackVisibility: true,
368
+ delay: 100
369
+ };
370
+ const observerScroll = new IntersectionObserver(callback, opts);
371
+ if (trackingRef)
372
+ observerScroll.observe(trackingRef);
373
+ return () => observerScroll.disconnect();
374
+ }, [trackingRef, callback, children]);
375
+ if (host && portal)
376
+ return reactDom.createPortal(children, portal);
377
+ return null;
378
+ }
379
+ function ScreenTopBar({ tabbed, breadcrumbs, api, item, isLoading, buttonBar, trackingRef }) {
380
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
381
+ tabbed && /* @__PURE__ */ jsxRuntime.jsx(PageTopBarToolbar, { trackingRef, children: /* @__PURE__ */ jsxRuntime.jsx(Buttons, { api, item, isLoading, buttonBar }) }),
382
+ !tabbed && /* @__PURE__ */ jsxRuntime.jsx(PageTopBar, { breadcrumbs, children: /* @__PURE__ */ jsxRuntime.jsx(Buttons, { api, item, isLoading, buttonBar }) })
383
+ ] });
384
+ }
385
+ function Buttons({ api, item, isLoading, buttonBar }) {
386
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
387
+ buttonBar && buttonBar.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ButtonBar, { children: buttonBar.map((button, index) => /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
388
+ button.type === "link" && /* @__PURE__ */ jsxRuntime.jsx(ViewButton, { label: button.label, path: button.path, icon: button.icon }),
389
+ button.type === "invalidate" && /* @__PURE__ */ jsxRuntime.jsx(InvalidateButton, { pathOrPermalink: button.pathOrPermalink }),
390
+ button.type == "custom" && button.render(item)
391
+ ] }, index)) }),
392
+ /* @__PURE__ */ jsxRuntime.jsxs(ButtonBar, { children: [
393
+ api instanceof adminApi.API && /* @__PURE__ */ jsxRuntime.jsx(PublishButton, { api, queryId: item.id, status: item.status, disabled: isLoading }),
394
+ /* @__PURE__ */ jsxRuntime.jsx(UpdateButton, { disabled: isLoading })
395
+ ] })
396
+ ] });
397
+ }
398
+ function useQueryField(queryField, useNextRouter) {
399
+ if (useNextRouter) {
400
+ const router$1 = router.useRouter();
401
+ return router$1.query[queryField];
402
+ }
403
+ const { [queryField]: id } = reactRouterDom.useParams();
404
+ return id;
405
+ }
406
+ function DetailsView({ queryField, api, useNextRouter, processInput, screen, tabbed, ...props }) {
407
+ const id = useQueryField(queryField, useNextRouter);
408
+ const ref = React8__default.default.useRef(null);
409
+ return /* @__PURE__ */ jsxRuntime.jsx(PageQueryStateContainer, { api, apiFn: "get", queryId: id, ref, p: "5", ...props, children: (item) => /* @__PURE__ */ jsxRuntime.jsx(Internal, { item, screen, api, tabbed, processInput, containerRef: ref }) });
410
+ }
411
+ function Internal({ item, screen, api: api$1, processInput, tabbed, containerRef }) {
412
+ const pScreen = react.runIfFn(screen, item);
413
+ const { breadcrumbs, schema, initialValues, header, sections, buttonBar, type, invalidateParentQueryKey, invalidatePage } = pScreen;
414
+ const mutation = api.useInvalidateParentMutation(api$1.update, invalidateParentQueryKey ?? api$1.queryKey, { networkMode: "always" });
415
+ const invalidatePageFn = adminApi.useInvalidatePage(invalidatePage || "");
416
+ const save = api.useMutate(mutation, {
417
+ processInput,
418
+ successMsg: (item2, values) => `${item2.title || item2.name} updated.`,
419
+ errorMsg: (error, item2) => `Error updating ${item2.title || item2.name}: ${error}`,
420
+ onSuccess: () => {
421
+ if (invalidatePage)
422
+ invalidatePageFn();
423
+ }
424
+ });
425
+ let editorMaxW = void 0;
426
+ if (!type || type == "post")
427
+ editorMaxW = "calc(1280px - 28rem)";
428
+ else if (type == "section")
429
+ editorMaxW = "calc(1280px - 22rem)";
430
+ return /* @__PURE__ */ jsxRuntime.jsxs(
431
+ form.FormProvider,
432
+ {
433
+ initialValues: react.runIfFn(initialValues, item),
434
+ validationSchema: schema,
435
+ onSubmit: save,
436
+ enableReinitialize: true,
437
+ children: [
438
+ /* @__PURE__ */ jsxRuntime.jsx(
439
+ ScreenTopBar,
440
+ {
441
+ tabbed,
442
+ api: api$1,
443
+ breadcrumbs,
444
+ buttonBar,
445
+ item,
446
+ isLoading: mutation.isLoading,
447
+ trackingRef: containerRef?.current
448
+ }
449
+ ),
450
+ type == "form" && sections?.map((section, index) => /* @__PURE__ */ jsxRuntime.jsx(Section, { section, item }, index)),
451
+ (pScreen.type == "post" || pScreen.type == "section") && /* @__PURE__ */ jsxRuntime.jsx("div", { p: "5", bgColor: "slate-100", rounded: "lg", children: /* @__PURE__ */ jsxRuntime.jsxs(PageContainer, { w: editorMaxW ? "auto" : "full", size: "x2", id: "pagecontainer", children: [
452
+ header,
453
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { dflex: true, gap: "5", children: [
454
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { dflex: true, flexCol: true, gap: "8", flexGrow: true, children: [
455
+ pScreen.editor?.type != "textarea" && // TODO Find a way to make this editor shrink in width when resizing the window...
456
+ /* @__PURE__ */ jsxRuntime.jsx(PageContentEditor, { name: "content", maxW: editorMaxW, minW: "144", shadow: true, rounded: "lg" }),
457
+ pScreen.editor?.type == "textarea" && /* @__PURE__ */ jsxRuntime.jsx(
458
+ form.TextArea,
459
+ {
460
+ name: pScreen.editor?.name,
461
+ maxW: editorMaxW,
462
+ minW: editorMaxW,
463
+ w: editorMaxW,
464
+ minH: "128",
465
+ rows: 25,
466
+ bgColor: "white",
467
+ border: "0",
468
+ shadow: true,
469
+ p: "5",
470
+ textColor: "slate-800"
471
+ }
472
+ ),
473
+ pScreen.editorFooter
474
+ ] }),
475
+ /* @__PURE__ */ jsxRuntime.jsx(PageSidebar, { children: sections?.map((section, index) => /* @__PURE__ */ jsxRuntime.jsx(Section, { section, item, cardStyle: true }, index)) })
476
+ ] })
477
+ ] }) })
478
+ ]
479
+ }
480
+ );
481
+ }
482
+ function Section({ section, item, cardStyle }) {
483
+ if (section.type === "section") {
484
+ const style = cardStyle ? {
485
+ bgColor: "white",
486
+ rounded: "lg",
487
+ p: "5",
488
+ textSize: "sm",
489
+ shadow: true
490
+ } : {};
491
+ return /* @__PURE__ */ jsxRuntime.jsx(PageSidebarSection, { title: section.title, ...style, children: /* @__PURE__ */ jsxRuntime.jsx(form.FormRenderer, { form: react.runIfFn(section.form, item) }) });
492
+ }
493
+ if (section.type === "custom")
494
+ return react.runIfFn(section.component, item);
495
+ return null;
496
+ }
497
+ function useApi(api, queryField) {
498
+ const params = reactRouterDom.useParams();
499
+ if (queryField === void 0)
500
+ return { id: void 0, api };
501
+ const { [queryField]: id } = params;
502
+ return { id, api: react.runIfFn(api, id) };
503
+ }
504
+ function QueryWrapper({
505
+ api: api$1,
506
+ queryField,
507
+ fn,
508
+ transformFn,
509
+ config,
510
+ tabbed,
511
+ ...props
512
+ }) {
513
+ const { id, api: mApi } = useApi(api$1, queryField);
514
+ const { data } = api.useApiQuery(mApi.queryKey, fn === "get" || fn === "getTransformed" ? mApi.get : mApi.getAll, react.isFunction(api$1) ? void 0 : id);
515
+ const transformedData = React8__default.default.useMemo(() => {
516
+ if (data && (fn === "getTransformed" || fn === "getAllTransformed")) {
517
+ if (!transformFn)
518
+ console.warn(`QueryWrapperDialog: you forgot to pass transformFn as parameter for fn ${fn}`);
519
+ return transformFn?.(data);
520
+ }
521
+ return data;
522
+ }, [data]);
523
+ if (!data)
524
+ return null;
525
+ return /* @__PURE__ */ jsxRuntime.jsx(ScreenRenderer, { config: config(transformedData), tabbed, ...props });
526
+ }
527
+ function TabbedView({ queryField, api, screen, ...props }) {
528
+ const { [queryField]: id } = reactRouterDom.useParams();
529
+ return /* @__PURE__ */ jsxRuntime.jsx(
530
+ PageQueryStateContainer,
531
+ {
532
+ queryId: id,
533
+ api,
534
+ apiFn: "get",
535
+ p: "5",
536
+ children: (city) => {
537
+ const { breadcrumbs, tabs } = react.runIfFn(screen, city);
538
+ return /* @__PURE__ */ jsxRuntime.jsxs(PageTabbedTopBarProvider, { children: [
539
+ /* @__PURE__ */ jsxRuntime.jsx(PageTabbedTopBar, { breadcrumbs, mb: "-3" }),
540
+ /* @__PURE__ */ jsxRuntime.jsx(
541
+ components.TabContainer,
542
+ {
543
+ tabs: tabs.map((tab) => tab.label),
544
+ saveKey: `tab-${id}`,
545
+ mt: "-3",
546
+ mb: "3",
547
+ id: "fff",
548
+ children: tabs.map((tab, index) => /* @__PURE__ */ jsxRuntime.jsx(TabView, { tab }, index))
549
+ }
550
+ )
551
+ ] });
552
+ }
553
+ }
554
+ );
555
+ }
556
+ function TabView({ tab }) {
557
+ if (!tab.component && !tab.config)
558
+ throw new Error(`Screen config for tabbed view: one of your tabs does not have a component or config declared: ${tab.label}`);
559
+ if (tab.component)
560
+ return tab.component();
561
+ return /* @__PURE__ */ jsxRuntime.jsx(ScreenRenderer, { config: tab.config, tabbed: true, p: "0" });
562
+ }
563
+ var [provider, useContext] = react.createContext();
564
+ function getColId(column) {
565
+ return column.accessorKey ?? column.id;
566
+ }
567
+ function TableContainerContextProvider({ initialVisibleColumns, columns, children }) {
568
+ const [showFilters, setShowFilters] = React8__default.default.useState(false);
569
+ const [showMassActions, setShowMassActions] = React8__default.default.useState(false);
570
+ const [visibleColumnIds, setVisibleColumnIds] = React8__default.default.useState(initialVisibleColumns ?? columns?.map((col) => getColId(col)) ?? []);
571
+ const filteredColumns = columns?.filter((col) => visibleColumnIds.includes(getColId(col))) ?? [];
572
+ const toggleColumnVisibility = React8__default.default.useCallback((id) => {
573
+ const index = visibleColumnIds.indexOf(id);
574
+ if (index > -1) {
575
+ const newIds = visibleColumnIds.concat();
576
+ newIds.splice(index, 1);
577
+ setVisibleColumnIds(newIds);
578
+ } else {
579
+ setVisibleColumnIds(visibleColumnIds.concat(id));
580
+ }
581
+ }, [visibleColumnIds, setVisibleColumnIds]);
582
+ const isColumnVisible = React8__default.default.useCallback((id) => {
583
+ return visibleColumnIds.includes(id);
584
+ }, [visibleColumnIds]);
585
+ const Provider = provider;
586
+ const value = {
587
+ showFilters,
588
+ setShowFilters,
589
+ showMassActions,
590
+ setShowMassActions,
591
+ columns: columns ?? [],
592
+ filteredColumns,
593
+ toggleColumnVisibility,
594
+ isColumnVisible
595
+ };
596
+ return /* @__PURE__ */ jsxRuntime.jsx(Provider, { value, children });
597
+ }
598
+ function TableContainer({ initialPageSize, initialVisibleColumns, columns, filtersMethod = "reactRouter", children, ...props }) {
599
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { w: "full", dflex: true, flexCol: true, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(table.TableContextProvider, { initialPageSize, filtersMethod, children: /* @__PURE__ */ jsxRuntime.jsx(TableContainerContextProvider, { columns, initialVisibleColumns, children }) }) });
600
+ }
601
+ function TableCreateButton({ icon, children, ...props }) {
602
+ return /* @__PURE__ */ jsxRuntime.jsxs(ButtonBarDialogButton, { ...props, children: [
603
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: icon ?? js.mdiPlusThick }),
604
+ children
605
+ ] });
606
+ }
607
+ function TableFilterButton({ ...props }) {
608
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Popover, { side: "bottom-end", modal: true, children: [
609
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { scheme: "dark", size: "sm", aspectRatio: "square", variant: "borderless", corners: "square", ...props, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: js.mdiFilter }) }),
610
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { bgColor: "white", rounded: true, shadow: true, children: [
611
+ /* @__PURE__ */ jsxRuntime.jsx("div", { py: "3", hover_bgColor: "#ff0000", px: "5", hover_textColor: "white", children: "First Item" }),
612
+ /* @__PURE__ */ jsxRuntime.jsx("div", { py: "3", hover_bgColor: "#ff0000", px: "5", hover_textColor: "white", children: "Second Item" }),
613
+ /* @__PURE__ */ jsxRuntime.jsx("div", { py: "3", hover_bgColor: "#ff0000", px: "5", hover_textColor: "white", children: "Third Item" })
614
+ ] })
615
+ ] });
616
+ }
617
+ function TableTopBar({ title, breadcrumbs, children, ...props }) {
618
+ return /* @__PURE__ */ jsxRuntime.jsxs(
619
+ "div",
620
+ {
621
+ dflex: true,
622
+ flexRow: true,
623
+ alignItems: "center",
624
+ gap: "3",
625
+ p: "8",
626
+ ...props,
627
+ children: [
628
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
629
+ title && /* @__PURE__ */ jsxRuntime.jsx("h2", { textSize: "x2", fontWeight: "600", textColor: "#3f4254", textTransform: "capitalize", children: title }),
630
+ breadcrumbs && /* @__PURE__ */ jsxRuntime.jsx(Breadcrumbs, { breadcrumbs })
631
+ ] }),
632
+ /* @__PURE__ */ jsxRuntime.jsx("div", { flexGrow: true, children: "\xA0" }),
633
+ children
634
+ ]
635
+ }
636
+ );
637
+ }
638
+ function TableFilters({ form: form$1, initialValues, schema, processInput }) {
639
+ const { showFilters } = useContext();
640
+ const { getFilters, setFilters } = table.useTableContext();
641
+ const handleSubmit = React8__default.default.useCallback((values, actions) => {
642
+ const params = processInput?.(values) ?? values;
643
+ if (!esToolkit.isEqual(params, getFilters()))
644
+ setFilters(params);
645
+ actions.setSubmitting(false);
646
+ }, [setFilters, processInput]);
647
+ const handleReset = React8__default.default.useCallback((resetForm) => {
648
+ setFilters(initialValues);
649
+ resetForm();
650
+ }, [setFilters, initialValues]);
651
+ React8__default.default.useEffect(() => setFilters(initialValues), []);
652
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Collapse, { in: showFilters, style: { overflow: showFilters ? "initial" : "hidden" }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { p: "8", borderT: "px", borderB: "px", borderColor: "slate-100", children: /* @__PURE__ */ jsxRuntime.jsx(
653
+ form.FormProvider,
654
+ {
655
+ initialValues: form.mergeInitialFormValues(getFilters(), initialValues),
656
+ onSubmit: handleSubmit,
657
+ validationSchema: schema,
658
+ enableReinitialize: true,
659
+ children: (props) => /* @__PURE__ */ jsxRuntime.jsxs("div", { dflex: true, gap: "3", placeContent: "start", children: [
660
+ /* @__PURE__ */ jsxRuntime.jsx(form.FormRenderer, { flexRow: true, w: "auto", form: form$1 }),
661
+ /* @__PURE__ */ jsxRuntime.jsx(Buttons2, { handleReset: () => handleReset(props.resetForm) })
662
+ ] })
663
+ }
664
+ ) }) });
665
+ }
666
+ function Buttons2({ handleReset }) {
667
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { dflex: true, gap: "3", children: [
668
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { dflex: true, flexCol: true, children: [
669
+ /* @__PURE__ */ jsxRuntime.jsx(form.FieldLabel, { name: "", label: "\xA0" }),
670
+ /* @__PURE__ */ jsxRuntime.jsx(form.SubmitButton, { children: "Filter" })
671
+ ] }),
672
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { dflex: true, flexCol: true, children: [
673
+ /* @__PURE__ */ jsxRuntime.jsx(form.FieldLabel, { name: "", label: "\xA0" }),
674
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { scheme: "neutral", onClick: handleReset, children: "Reset" })
675
+ ] })
676
+ ] });
677
+ }
678
+ function ActionButton({
679
+ label,
680
+ buttonProps,
681
+ icon,
682
+ queryKey,
683
+ queryFn,
684
+ successMsg,
685
+ errorMsg,
686
+ invalidateParent
687
+ }) {
688
+ const mutation = invalidateParent ? api.useInvalidateParentMutation(queryFn, queryKey) : api.useApiMutation(queryFn, queryKey);
689
+ const mutate = api.useMutate(
690
+ mutation,
691
+ {
692
+ successMsg,
693
+ errorMsg
694
+ }
695
+ );
696
+ return /* @__PURE__ */ jsxRuntime.jsxs(
697
+ ui.Button,
698
+ {
699
+ display: "flex",
700
+ alignItems: "center",
701
+ gap: "3",
702
+ ...buttonProps,
703
+ onClick: mutate,
704
+ disabled: mutation.isLoading,
705
+ children: [
706
+ icon && /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: icon }),
707
+ label
708
+ ]
709
+ }
710
+ );
711
+ }
712
+ function TableMassActions({ actions }) {
713
+ const { ids } = table.useTableContext();
714
+ const showMassActions = ids && ids.length > 0;
715
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Collapse, { in: showMassActions, style: { overflow: showMassActions ? "initial" : "hidden" }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { dflex: true, gap: "3", flexWrap: true, alignItems: "center", px: "8", pt: "5", children: actions.map((action, index) => /* @__PURE__ */ jsxRuntime.jsx("div", { children: action.type == "button" && !action.showConfirmationDialog && /* @__PURE__ */ jsxRuntime.jsx(ActionButton, { label: action.label, queryFn: action.queryFn, queryKey: action.queryKey, buttonProps: action.buttonProps }) }, index)) }) });
716
+ }
717
+ var defaultErrorMsg = "Oops, something went wrong...";
718
+ function nonNullValues(data) {
719
+ if (data) {
720
+ const nonNullData = { ...data };
721
+ for (const key in data)
722
+ nonNullData[key] = nonNullData[key] ?? "";
723
+ return nonNullData;
724
+ }
725
+ return data;
726
+ }
727
+ function ItemEditDialog({
728
+ initialValues,
729
+ itemLabel,
730
+ queryId = "",
731
+ api: api$1,
732
+ queryFetchOptions,
733
+ querySaveOptions,
734
+ onSuccess,
735
+ onFetchError,
736
+ fetchErrorMsg = defaultErrorMsg,
737
+ onSaveError,
738
+ saveErrorMsg = defaultErrorMsg,
739
+ fetchToFormData,
740
+ formToQueryData,
741
+ invalidateQueriesOnSuccess = true,
742
+ invalidateQueryKey,
743
+ retryText = "Retry",
744
+ cancelLabel = "Cancel",
745
+ saveLabel,
746
+ size = "lg",
747
+ title,
748
+ form: form$1,
749
+ show,
750
+ onClose,
751
+ formikProps,
752
+ ...props
753
+ }) {
754
+ const { isInitialLoading, isFetching, data, isError, error, refetch } = api.useApiQuery(api$1.queryKey, api$1.get, queryId, {
755
+ enabled: !/*queryId == 0 || */
756
+ (queryId == "" || queryId == null || queryId == void 0),
757
+ // means than this query is only enabled if the id is defined
758
+ onError: onFetchError,
759
+ ...queryFetchOptions
760
+ });
761
+ const mutation = invalidateQueriesOnSuccess ? api.useInvalidateParentMutation(api$1.upsert, invalidateQueryKey ?? api$1.queryKey, querySaveOptions) : api.useApiMutation(api$1.upsert, api$1.queryKey, queryId, querySaveOptions);
762
+ const retry = React8__default.default.useCallback(() => refetch(), [refetch]);
763
+ const saveItem = React8__default.default.useCallback(async (item, actions) => {
764
+ mutation.reset();
765
+ const formItem = formToQueryData ? formToQueryData(item) : { ...item };
766
+ await mutation.mutateAsync(formItem).then((response) => {
767
+ if (onSuccess)
768
+ onSuccess(formItem, response);
769
+ else
770
+ reactToastify.toast.success(`${title ? title(formItem) : formItem.name ?? formItem.title} ${queryId ? "saved" : "created"}`);
771
+ onClose?.();
772
+ }).catch((error2) => {
773
+ console.error("on error", error2);
774
+ if (onSaveError)
775
+ onSaveError(item);
776
+ else
777
+ reactToastify.toast.error(`Couldn't save ${title ? title(formItem) : formItem.name ?? formItem.title}`);
778
+ actions.setSubmitting(false);
779
+ });
780
+ }, [mutation, formToQueryData, onSuccess, onSaveError, onClose]);
781
+ return /* @__PURE__ */ jsxRuntime.jsxs(
782
+ ui.Modal,
783
+ {
784
+ size,
785
+ show,
786
+ onClose,
787
+ scheme: "light",
788
+ transition: true,
789
+ ...props,
790
+ children: [
791
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Modal.Header, { children: [
792
+ !isInitialLoading && queryId && `Edit ${title ? title(data) : data?.["name"] ?? data?.["title"] ?? data?.["name"] ?? ""}`,
793
+ !queryId && `Create new ${itemLabel ?? "item"}`,
794
+ Array.isArray(form$1) && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {})
795
+ ] }),
796
+ isInitialLoading && /* @__PURE__ */ jsxRuntime.jsx(ui.Modal.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(components.QueryLoadingState, { minW: "72" }) }),
797
+ isError && /* @__PURE__ */ jsxRuntime.jsx(ui.Modal.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(components.RetryOnError, { label: `${fetchErrorMsg} ${error}`, onClick: retry }) }),
798
+ !isInitialLoading && !isError && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
799
+ formik.Formik,
800
+ {
801
+ initialValues: fetchToFormData && queryId && data ? fetchToFormData(nonNullValues(data)) : nonNullValues(initialValues(data)) ?? {},
802
+ onSubmit: saveItem,
803
+ ...formikProps,
804
+ children: ({ setFieldValue, dirty, handleSubmit, isValid, values }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
805
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Modal.Body, { pb: "6", children: /* @__PURE__ */ jsxRuntime.jsxs(formik.Form, { children: [
806
+ React8__default.default.isValidElement(form$1) && form$1,
807
+ Array.isArray(form$1) && /* @__PURE__ */ jsxRuntime.jsx(form.FormRenderer, { form: form$1 }),
808
+ react.isFunction(form$1) && /* @__PURE__ */ jsxRuntime.jsx(form.FormRenderer, { form: form$1(data ?? values) })
809
+ ] }) }),
810
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Modal.Footer, { dflex: true, placeContent: "end", spaceX: "3", children: [
811
+ /* @__PURE__ */ jsxRuntime.jsx(
812
+ ui.Button,
813
+ {
814
+ disabled: mutation.isLoading,
815
+ onClick: onClose,
816
+ variant: "borderless",
817
+ me: "2",
818
+ children: cancelLabel
819
+ }
820
+ ),
821
+ /* @__PURE__ */ jsxRuntime.jsx(
822
+ ui.Button,
823
+ {
824
+ type: "submit",
825
+ disabled: !dirty || mutation.isLoading,
826
+ onClick: () => handleSubmit(),
827
+ children: saveLabel ? saveLabel : queryId ? "Update" : "Create"
828
+ }
829
+ )
830
+ ] })
831
+ ] })
832
+ }
833
+ ) }),
834
+ mutation.isLoading && /* @__PURE__ */ jsxRuntime.jsx(components.ModalLoadingOverlay, {})
835
+ ]
836
+ }
837
+ );
838
+ }
839
+ function QueryWrapperDialog({ api: api$1, fn, transformFn, config, onClose, queryId, invalidateQueryKey }) {
840
+ const { data, isFetching } = api.useApiQuery(
841
+ api$1.queryKey,
842
+ fn === "get" || fn === "getTransformed" ? api$1.get : api$1.getAll,
843
+ void 0,
844
+ { retryOnMount: false, refetchOnMount: false, refetchOnWindowFocus: false }
845
+ );
846
+ const transformedData = React8__default.default.useMemo(() => {
847
+ if (data && (fn === "getTransformed" || fn === "getAllTransformed")) {
848
+ if (!transformFn)
849
+ console.warn(`QueryWrapperDialog: you forgot to pass transformFn as parameter for fn ${fn}`);
850
+ return transformFn?.(data);
851
+ }
852
+ return data;
853
+ }, [data, fn, transformFn]);
854
+ if (isFetching)
855
+ return null;
856
+ return /* @__PURE__ */ jsxRuntime.jsx(ItemEditDialog, { ...config(transformedData), queryId, invalidateQueryKey, show: true, onClose });
857
+ }
858
+ function MultiQueryWrapperDialog({ queries, config, onClose, queryId, invalidateQueryKey }) {
859
+ const { data, isFetching, isError } = api.useApiQueries(queries.map((q) => ({
860
+ queryKey: q.api.queryKey,
861
+ queryFn: q.fn == "get" ? q.api.get : q.api.getAll,
862
+ queryOptions: {
863
+ cacheTime: q.cache === false ? 0 : void 0,
864
+ staleTime: q.cache === false ? 0 : void 0
865
+ }
866
+ })));
867
+ const transformedData = React8__default.default.useMemo(() => {
868
+ return data?.map((d, index) => queries[index]?.transformFn ? queries[index]?.transformFn?.(d) : d);
869
+ }, [data, queries]);
870
+ return /* @__PURE__ */ jsxRuntime.jsx(ItemEditDialog, { isPreloading: isFetching, ...config(...transformedData), queryId, invalidateQueryKey, show: true, onClose });
871
+ }
872
+ function DialogRenderer({ config, onClose, invalidateQueryKey, queryId }) {
873
+ const { type, ...props } = config;
874
+ if (config.type === "dialog")
875
+ return /* @__PURE__ */ jsxRuntime.jsx(ItemEditDialog, { ...props, queryId, invalidateQueryKey, show: true, onClose });
876
+ if (config.type === "query")
877
+ return /* @__PURE__ */ jsxRuntime.jsx(QueryWrapperDialog, { ...props, queryId, invalidateQueryKey, onClose });
878
+ if (config.type === "multiQuery")
879
+ return /* @__PURE__ */ jsxRuntime.jsx(MultiQueryWrapperDialog, { ...props, queryId, invalidateQueryKey, onClose });
880
+ return null;
881
+ }
882
+ function RefreshButton({ queryKey }) {
883
+ const invalidate = api.useInvalidateQuery(queryKey);
884
+ reactHotkeysHook.useHotkeys("ctrl+r", () => invalidate(), { preventDefault: true }, [invalidate]);
885
+ return /* @__PURE__ */ jsxRuntime.jsx(ButtonBarButton, { scheme: "dark", size: "sm", aspectRatio: "square", variant: "borderless", onClick: invalidate, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: js.mdiRefresh }) });
886
+ }
887
+ function ItemDeleteDialog({
888
+ title,
889
+ actionButtonLabel,
890
+ closeActionButtonLabel = "Cancel",
891
+ itemLabel,
892
+ queryId = "",
893
+ api: api$1,
894
+ apiFn,
895
+ invalidateQueriesOnSuccess = true,
896
+ invalidateQueryKey,
897
+ size = "lg",
898
+ md_boxSizing,
899
+ msg,
900
+ show,
901
+ onClose,
902
+ onSuccess,
903
+ ...props
904
+ }) {
905
+ const fn = apiFn ? api$1[apiFn] : api$1.delete;
906
+ const mutation = invalidateQueriesOnSuccess ? api.useInvalidateParentMutation(fn, invalidateQueryKey ?? api$1.queryKey) : api.useApiMutation(fn, api$1.queryKey);
907
+ const mutate = api.useMutate(mutation, { onSuccess: () => {
908
+ onClose?.();
909
+ onSuccess?.();
910
+ } });
911
+ const handleDelete = React8__default.default.useCallback(() => mutate(queryId), [mutate, queryId]);
912
+ return /* @__PURE__ */ jsxRuntime.jsxs(
913
+ ui.Modal,
914
+ {
915
+ size,
916
+ show,
917
+ onClose,
918
+ scheme: "danger",
919
+ variant: "glass",
920
+ transition: true,
921
+ ...props,
922
+ children: [
923
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Modal.Header, { children: title || `Delete ${itemLabel}` }),
924
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Modal.Body, { pb: "6", children: [
925
+ !msg && `Do you really want to delete ${itemLabel}?`,
926
+ msg && react.runIfFn(msg, itemLabel)
927
+ ] }),
928
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Modal.Footer, { dflex: true, placeContent: "end", spaceX: "3", children: [
929
+ /* @__PURE__ */ jsxRuntime.jsx(
930
+ ui.Button,
931
+ {
932
+ disabled: mutation.isPending,
933
+ onClick: onClose,
934
+ variant: "borderless",
935
+ scheme: "dark",
936
+ me: "2",
937
+ children: closeActionButtonLabel
938
+ }
939
+ ),
940
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { scheme: "danger", disabled: mutation.isPending, onClick: handleDelete, children: actionButtonLabel || "Delete" })
941
+ ] }),
942
+ mutation.isPending && /* @__PURE__ */ jsxRuntime.jsx(components.ModalLoadingOverlay, {})
943
+ ]
944
+ }
945
+ );
946
+ }
947
+ var [provider2, useContext2] = react.createContext();
948
+ function TableViewProvider({ editView, deleteItem, queryKey, children }) {
949
+ const openLink = hooks.useOpenLink();
950
+ const navigate = reactRouterDom.useNavigate();
951
+ const [dialog, setDialog] = React8__default.default.useState(null);
952
+ const onCloseDialog = React8__default.default.useCallback(() => setDialog(null), [setDialog]);
953
+ const onAction = React8__default.default.useCallback((action, item) => {
954
+ switch (action.type) {
955
+ case "view": {
956
+ navigate(react.runIfFn(action.path, item));
957
+ break;
958
+ }
959
+ case "link": {
960
+ openLink(`${env.AppEnv.websiteUrl()}/${react.runIfFn(action.path, item)}`);
961
+ break;
962
+ }
963
+ case "edit": {
964
+ const editConfig = react.runIfFn(editView, item);
965
+ if (editConfig) {
966
+ if (editConfig.type == "customDialog") {
967
+ setDialog(editConfig.render({ show: true, onClose: onCloseDialog }));
968
+ } else {
969
+ setDialog(
970
+ /* @__PURE__ */ jsxRuntime.jsx(
971
+ DialogRenderer,
972
+ {
973
+ onClose: onCloseDialog,
974
+ config: editConfig,
975
+ queryId: item.id,
976
+ invalidateQueryKey: queryKey
977
+ }
978
+ )
979
+ );
980
+ }
981
+ }
982
+ break;
983
+ }
984
+ case "delete": {
985
+ const deleteConfig = react.runIfFn(deleteItem, item);
986
+ setDialog(
987
+ /* @__PURE__ */ jsxRuntime.jsx(
988
+ ItemDeleteDialog,
989
+ {
990
+ show: true,
991
+ onClose: onCloseDialog,
992
+ queryId: item.id,
993
+ invalidateQueryKey: queryKey,
994
+ msg: item.msg,
995
+ ...deleteConfig,
996
+ itemLabel: react.runIfFn(deleteConfig.itemLabel, item)
997
+ }
998
+ )
999
+ );
1000
+ break;
1001
+ }
1002
+ }
1003
+ }, [navigate, editView, deleteItem]);
1004
+ const Provider = provider2;
1005
+ const value = {
1006
+ dialog,
1007
+ onAction
1008
+ };
1009
+ return /* @__PURE__ */ jsxRuntime.jsx(Provider, { value, children });
1010
+ }
1011
+ function TableRowPublishPostButton({ id, api: api$1, status, invalidateQueryKey, ...props }) {
1012
+ const isDraft = status == "draft";
1013
+ const mutation = api.useInvalidateParentMutation(isDraft ? api$1.publish : api$1.unpublish, invalidateQueryKey ?? api$1.queryKey, { networkMode: "always" });
1014
+ const publish = React8__default.default.useCallback((event) => {
1015
+ event?.preventDefault();
1016
+ event?.stopPropagation();
1017
+ mutation.reset();
1018
+ mutation.mutateAsync(id).then(() => reactToastify.toast.success(isDraft ? "Published!" : "Unpublished!")).catch((error) => reactToastify.toast.error(`Error: ${error}`));
1019
+ }, [mutation, id]);
1020
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "borderless", corners: "square", scheme: "dark", onClick: publish, ...props, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: isDraft ? js.mdiPublish : js.mdiPublishOff, size: "sm" }) });
1021
+ }
1022
+ function TableRowActionButton({ icon, children, ...props }) {
1023
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1024
+ ui.Button,
1025
+ {
1026
+ dflex: true,
1027
+ alignContent: "center",
1028
+ placeContent: "center",
1029
+ py: "2.5",
1030
+ px: "3",
1031
+ h: "full",
1032
+ size: "lg",
1033
+ variant: "borderless",
1034
+ corners: "square",
1035
+ gap: "2",
1036
+ ...props,
1037
+ children: [
1038
+ icon && /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: icon, size: "sm" }),
1039
+ children
1040
+ ]
1041
+ }
1042
+ );
1043
+ }
1044
+ function TableRowActionsView({ row, onAction, rowActions, api, queryKey }) {
1045
+ const item = row.original;
1046
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { dflex: true, w: "full", alignItems: "stretch", placeContent: "end", h: "full", children: react.runIfFn(rowActions, item)?.map(
1047
+ (action, index) => /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
1048
+ action.type === "publish" && /* @__PURE__ */ jsxRuntime.jsx(TableRowPublishPostButton, { id: item.id, api: action.api ?? api, status: item.status, invalidateQueryKey: queryKey }),
1049
+ action.type == "custom" && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: action.component(item, queryKey, action.icon, action.label) }),
1050
+ !["publish", "custom"].includes(action.type) && /* @__PURE__ */ jsxRuntime.jsx(ActionButton2, { onClick: () => onAction(action, item), scheme: schemes[action.type], children: /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: icons[action.type], size: "sm" }) })
1051
+ ] }, index)
1052
+ ) });
1053
+ }
1054
+ function ActionButton2({ onClick, ...props }) {
1055
+ const handleClick = React8__default.default.useCallback((event) => {
1056
+ event?.preventDefault();
1057
+ event?.stopPropagation();
1058
+ onClick?.(event);
1059
+ }, [onClick]);
1060
+ return /* @__PURE__ */ jsxRuntime.jsx(
1061
+ TableRowActionButton,
1062
+ {
1063
+ onClick: handleClick,
1064
+ ...props
1065
+ }
1066
+ );
1067
+ }
1068
+ var icons = {
1069
+ "link": js.mdiOpenInNew,
1070
+ "view": js.mdiEye,
1071
+ "edit": js.mdiPencil,
1072
+ "delete": js.mdiDelete,
1073
+ "publish": js.mdiDelete,
1074
+ "custom": ""
1075
+ };
1076
+ var schemes = {
1077
+ "link": "dark",
1078
+ "view": "dark",
1079
+ "edit": "dark",
1080
+ "delete": "dark",
1081
+ "publish": "dark",
1082
+ "custom": "dark"
1083
+ };
1084
+ function useTableProps(api, table, rowActions, queryParams) {
1085
+ const navigate = reactRouterDom.useNavigate();
1086
+ const nextRouter = router.useRouter();
1087
+ const openLink = hooks.useOpenLink();
1088
+ const { onAction } = useContext2();
1089
+ const { onRowClick, columns: c, ...props } = table;
1090
+ const onRowClickHandler = React8__default.default.useCallback((item) => {
1091
+ const config = react.runIfFn(onRowClick, item);
1092
+ if (config) {
1093
+ switch (config.type) {
1094
+ case "navigate": {
1095
+ navigate(react.runIfFn(config.path, item) ?? "");
1096
+ break;
1097
+ }
1098
+ case "nextpush": {
1099
+ nextRouter.push(react.runIfFn(config.path, item));
1100
+ break;
1101
+ }
1102
+ case "link": {
1103
+ openLink(`${env.AppEnv.websiteUrl()}/${react.runIfFn(config.path, item)}`);
1104
+ break;
1105
+ }
1106
+ }
1107
+ }
1108
+ }, [navigate, onRowClick]);
1109
+ const columns = React8__default.default.useMemo(() => {
1110
+ const columns2 = table.columns.concat([]);
1111
+ if (rowActions) {
1112
+ columns2.push(
1113
+ reactTable.createColumnHelper().display(
1114
+ {
1115
+ id: "actions",
1116
+ header: "Actions",
1117
+ cell: (props2) => /* @__PURE__ */ jsxRuntime.jsx(TableRowActionsView, { row: props2.row, onAction, rowActions, api, queryKey: api.queryKey })
1118
+ }
1119
+ )
1120
+ );
1121
+ }
1122
+ return columns2;
1123
+ }, [table, onAction, rowActions, api]);
1124
+ const tableProps = { ...props };
1125
+ tableProps.columns = columns;
1126
+ tableProps.onRowClick = onRowClickHandler;
1127
+ tableProps.queryKey = api.queryKey;
1128
+ tableProps.queryFilters = queryParams;
1129
+ tableProps.queryFn = api.search;
1130
+ return tableProps;
1131
+ }
1132
+ function useId(queryField) {
1133
+ const params = reactRouterDom.useParams();
1134
+ if (queryField === void 0)
1135
+ return void 0;
1136
+ const { [queryField]: id } = params;
1137
+ return id;
1138
+ }
1139
+ function TableView({ queryField, title, subtitle, screen, ...props }) {
1140
+ const id = useId(queryField);
1141
+ const _screen = react.runIfFn(screen, id);
1142
+ return /* @__PURE__ */ jsxRuntime.jsx(PageContainer, { bgColor: "white", ...props, children: /* @__PURE__ */ jsxRuntime.jsx(TableContainer, { columns: _screen.table.columns, initialVisibleColumns: _screen.table.initialVisibleColumns, filtersMethod: _screen.table.filtersMethod, children: /* @__PURE__ */ jsxRuntime.jsx(TT, { id, title, subtitle, screen: _screen }) }) });
1143
+ }
1144
+ function TT({ id, title, subtitle, screen }) {
1145
+ const { setRowSelection } = table.useTableContext();
1146
+ const { api, table: table$1, filters, massActions, buttonBar, rowActions, createView, editView, deleteItem, breadcrumbs } = screen;
1147
+ const tableApi = react.runIfFn(api, id ?? "");
1148
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1149
+ /* @__PURE__ */ jsxRuntime.jsx(TableTopBar, { title, breadcrumbs, children: /* @__PURE__ */ jsxRuntime.jsx(TableButtonBar, { buttonBar, createView, editView, api: tableApi, queryKey: tableApi.queryKey, children: filters && /* @__PURE__ */ jsxRuntime.jsx(TableFilterButton, {}) }) }),
1150
+ filters && /* @__PURE__ */ jsxRuntime.jsx(
1151
+ TableFilters,
1152
+ {
1153
+ form: filters.form,
1154
+ initialValues: filters.initialValues,
1155
+ schema: filters.schema,
1156
+ processInput: filters.processInput
1157
+ }
1158
+ ),
1159
+ massActions && /* @__PURE__ */ jsxRuntime.jsx(TableMassActions, { actions: massActions.items }),
1160
+ /* @__PURE__ */ jsxRuntime.jsxs(TableViewProvider, { queryKey: tableApi.queryKey, editView, deleteItem, children: [
1161
+ /* @__PURE__ */ jsxRuntime.jsx(TableWrapper, { table: { ...table$1, onSelectionChange: setRowSelection }, rowActions, api: tableApi, subtitle, queryParams: screen.queryParams }),
1162
+ /* @__PURE__ */ jsxRuntime.jsx(TableDialogManager, {})
1163
+ ] })
1164
+ ] });
1165
+ }
1166
+ function TableButtonBar({ buttonBar, queryKey, createView, editView, api, children }) {
1167
+ const createDialogFn = React8__default.default.useCallback((data) => {
1168
+ return (onClose) => {
1169
+ const view = react.runIfFn(createView, data) ?? react.runIfFn(editView, null);
1170
+ if (view.type == "customDialog")
1171
+ return view.render({ show: true, onClose });
1172
+ else
1173
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogRenderer, { config: view, onClose, invalidateQueryKey: api.queryKey });
1174
+ };
1175
+ }, [createView, editView, api]);
1176
+ return /* @__PURE__ */ jsxRuntime.jsxs(ButtonBar, { children: [
1177
+ /* @__PURE__ */ jsxRuntime.jsx(RefreshButton, { queryKey }),
1178
+ buttonBar && buttonBar.map(
1179
+ (button, index) => /* @__PURE__ */ jsxRuntime.jsxs(React8__default.default.Fragment, { children: [
1180
+ button.type === "create" && editView && /* @__PURE__ */ jsxRuntime.jsx(
1181
+ TableCreateButton,
1182
+ {
1183
+ buildDialog: createDialogFn(button.data),
1184
+ icon: button.icon,
1185
+ children: button.label
1186
+ }
1187
+ ),
1188
+ button.type === "invalidate" && /* @__PURE__ */ jsxRuntime.jsx(InvalidateButton, { pathOrPermalink: button.pathOrPermalink }),
1189
+ button.type === "custom" && button.render()
1190
+ ] }, index)
1191
+ ),
1192
+ children
1193
+ ] });
1194
+ }
1195
+ function TableWrapper({ table: table$1, subtitle, rowActions, api, queryParams }) {
1196
+ const tableProps = useTableProps(api, table$1, rowActions, queryParams);
1197
+ const _subtitle = React8__default.default.useMemo(() => {
1198
+ if (!subtitle)
1199
+ return void 0;
1200
+ return (data) => {
1201
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { textSize: "lg", textColor: "#475569", fontWeight: "600", children: react.isFunction(subtitle) ? subtitle(data) : subtitle });
1202
+ };
1203
+ }, [subtitle]);
1204
+ return /* @__PURE__ */ jsxRuntime.jsx(table.Table, { ...tableProps, p: "8", title: _subtitle });
1205
+ }
1206
+ function TableDialogManager() {
1207
+ const { dialog } = useContext2();
1208
+ return dialog;
1209
+ }
1210
+ function useQueries(queries) {
1211
+ const params = reactRouterDom.useParams();
1212
+ const { data, isFetching, isError } = api.useApiQueries(queries.map((q) => {
1213
+ if (!q.queryField) {
1214
+ const api2 = react.runIfFn(q.api);
1215
+ return {
1216
+ queryKey: api2.queryKey,
1217
+ queryFn: q.fn == "get" ? api2.get : api2.getAll,
1218
+ queryParam: q.params
1219
+ };
1220
+ }
1221
+ const id = params[q.queryField];
1222
+ const api = react.runIfFn(q.api, id);
1223
+ return {
1224
+ queryKey: api.queryKey,
1225
+ queryFn: q.fn == "get" ? api.get : api.getAll,
1226
+ queryParam: q.fn == "getAll" ? q.params : react.isFunction(q.api) ? void 0 : id
1227
+ };
1228
+ }));
1229
+ let transformedData = void 0;
1230
+ if (!isFetching && !isError) {
1231
+ transformedData = data?.map((d, index) => queries[index].transformFn ? queries[index].transformFn?.(d) : d);
1232
+ }
1233
+ return { data: transformedData, isFetching, isError };
1234
+ }
1235
+ function useInvalidate(queries) {
1236
+ const queryClient = reactQuery.useQueryClient();
1237
+ const params = reactRouterDom.useParams();
1238
+ const invalidate = React8__default.default.useCallback(
1239
+ () => {
1240
+ const queryKeys = [];
1241
+ queries.forEach((q) => {
1242
+ if (!q.queryField || !react.isFunction(q.api)) {
1243
+ queryKeys.push(q.api.queryKey);
1244
+ } else {
1245
+ const id = params[q.queryField];
1246
+ const api = react.runIfFn(q.api, id);
1247
+ queryKeys.push(api.queryKey);
1248
+ }
1249
+ });
1250
+ queryClient.invalidateQueries({ predicate: (query) => queryKeys.includes(query.queryKey) });
1251
+ },
1252
+ [queries, queryClient, params]
1253
+ );
1254
+ return invalidate;
1255
+ }
1256
+ function MultiQueryWrapper({
1257
+ queries,
1258
+ config,
1259
+ tabbed,
1260
+ ...props
1261
+ }) {
1262
+ const { data, isFetching, isError } = useQueries(queries);
1263
+ const invalidate = useInvalidate(queries);
1264
+ if (isFetching)
1265
+ return /* @__PURE__ */ jsxRuntime.jsx(components.QueryLoadingState, { w: "full", h: "100vh" });
1266
+ if (isError || !data)
1267
+ return /* @__PURE__ */ jsxRuntime.jsx(components.RetryOnError, { p: "0", w: "full", h: "100vh", onClick: invalidate });
1268
+ return /* @__PURE__ */ jsxRuntime.jsx(ScreenRenderer, { config: config(...data), tabbed, ...props });
1269
+ }
1270
+ function ScreenRenderer({ config, tabbed, ...props }) {
1271
+ if (config.type === "table")
1272
+ return /* @__PURE__ */ jsxRuntime.jsx(TableView, { ...config, ...props });
1273
+ if (config.type === "tabbed")
1274
+ return /* @__PURE__ */ jsxRuntime.jsx(TabbedView, { ...config, ...props });
1275
+ if (config.type === "details")
1276
+ return /* @__PURE__ */ jsxRuntime.jsx(DetailsView, { ...config, tabbed, ...props });
1277
+ if (config.type === "query")
1278
+ return /* @__PURE__ */ jsxRuntime.jsx(QueryWrapper, { ...config, tabbed, ...props });
1279
+ if (config.type === "multiQuery")
1280
+ return /* @__PURE__ */ jsxRuntime.jsx(MultiQueryWrapper, { ...config, tabbed, ...props });
1281
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {});
1282
+ }
1283
+ function Content({ ...props }) {
1284
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { w: "100%", h: "100%", overflowY: "auto", ...props, children: /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Outlet, {}) });
1285
+ }
1286
+ function SelectedIndicator({ darkMode }) {
1287
+ return /* @__PURE__ */ jsxRuntime.jsx(
1288
+ "div",
1289
+ {
1290
+ position: "absolute",
1291
+ bgColor: darkMode ? "white" : "black",
1292
+ bgOpacity: "90",
1293
+ w: "0.5",
1294
+ h: "6",
1295
+ top: "1.5",
1296
+ start: "-4"
1297
+ }
1298
+ );
1299
+ }
1300
+ function MenuButton({ depth, darkMode, icon, selected, children, ...props }) {
1301
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1302
+ ui.Button,
1303
+ {
1304
+ as: "li",
1305
+ minH: "8",
1306
+ ms: `${(depth ?? 0) * 2}`,
1307
+ p: "2",
1308
+ font: "title",
1309
+ textColor: darkMode ? "white" : "black",
1310
+ fontWeight: "600",
1311
+ rounded: "lg",
1312
+ textSize: "sm",
1313
+ variant: "borderless",
1314
+ hover_bgColor: darkMode ? "white" : "black",
1315
+ hover_bgOpacity: "10",
1316
+ hover_textColor: darkMode ? "white" : "zinc-800",
1317
+ cursor: "pointer",
1318
+ dflex: true,
1319
+ alignItems: "center",
1320
+ gap: "3",
1321
+ ...props,
1322
+ children: [
1323
+ icon && /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: icon, opacity: selected ? "100" : "60" }),
1324
+ children
1325
+ ]
1326
+ }
1327
+ );
1328
+ }
1329
+ function MenuItem({ icon, path, depth, darkMode, subMenu, ...props }) {
1330
+ const location = reactRouterDom.useLocation();
1331
+ const selected = path == "/" ? location.pathname == "/" : location.pathname.startsWith(path.startsWith("/") ? path : `/${path}`);
1332
+ const match = reactRouterDom.useMatch("/" + path) != null;
1333
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1334
+ /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Link, { to: path, style: { position: "relative" }, children: [
1335
+ /* @__PURE__ */ jsxRuntime.jsx(
1336
+ MenuButton,
1337
+ {
1338
+ depth,
1339
+ darkMode,
1340
+ icon,
1341
+ selected,
1342
+ ...props
1343
+ }
1344
+ ),
1345
+ match && /* @__PURE__ */ jsxRuntime.jsx(SelectedIndicator, { darkMode })
1346
+ ] }),
1347
+ subMenu?.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
1348
+ MenuItem,
1349
+ {
1350
+ icon: item.icon,
1351
+ path: item.path,
1352
+ depth: (depth ?? 0) + 1,
1353
+ darkMode,
1354
+ subMenu: item.children,
1355
+ children: item.label
1356
+ },
1357
+ index
1358
+ ))
1359
+ ] });
1360
+ }
1361
+ function NextMenuItem({ icon, path, depth, darkMode, subMenu, ...props }) {
1362
+ const { pathname } = router.useRouter();
1363
+ const selected = path == "/" ? pathname == "/" : pathname.startsWith(path.startsWith("/") ? path : `/${path}`);
1364
+ const match = path == "/" ? pathname == "/" : pathname == (path.startsWith("/") ? path : `/${path}`);
1365
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1366
+ /* @__PURE__ */ jsxRuntime.jsxs(Link__default.default, { href: path, style: { position: "relative" }, children: [
1367
+ /* @__PURE__ */ jsxRuntime.jsx(
1368
+ MenuButton,
1369
+ {
1370
+ depth,
1371
+ darkMode,
1372
+ icon,
1373
+ selected,
1374
+ ...props
1375
+ }
1376
+ ),
1377
+ match && /* @__PURE__ */ jsxRuntime.jsx(SelectedIndicator, { darkMode })
1378
+ ] }),
1379
+ subMenu?.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
1380
+ NextMenuItem,
1381
+ {
1382
+ icon: item.icon,
1383
+ path: item.path,
1384
+ depth: (depth ?? 0) + 1,
1385
+ darkMode,
1386
+ subMenu: item.children,
1387
+ children: item.label
1388
+ },
1389
+ index
1390
+ ))
1391
+ ] });
1392
+ }
1393
+ function Menu({ darkMode, config, useNextRouter, ...props }) {
1394
+ const Comp = useNextRouter ? NextMenuItem : MenuItem;
1395
+ return /* @__PURE__ */ jsxRuntime.jsx("ul", { ...props, children: config.map((item, index) => {
1396
+ if (item.type == "divider")
1397
+ return /* @__PURE__ */ jsxRuntime.jsx(Divider, { title: item.label }, index);
1398
+ if (item.type == "item") {
1399
+ return /* @__PURE__ */ jsxRuntime.jsx(
1400
+ Comp,
1401
+ {
1402
+ icon: item.icon,
1403
+ path: item.path,
1404
+ depth: 0,
1405
+ darkMode,
1406
+ subMenu: item.children,
1407
+ children: item.label
1408
+ },
1409
+ index
1410
+ );
1411
+ }
1412
+ }) });
1413
+ }
1414
+ function Divider({ title }) {
1415
+ return /* @__PURE__ */ jsxRuntime.jsx(
1416
+ "div",
1417
+ {
1418
+ px: "2",
1419
+ mt: "5",
1420
+ mb: "2",
1421
+ opacity: "75",
1422
+ textTransform: "capitalize",
1423
+ letterSpacing: "widest",
1424
+ fontWeight: "700",
1425
+ textSize: "xs",
1426
+ children: title
1427
+ }
1428
+ );
1429
+ }
1430
+ function UserBlock({ color, darkMode, menuConfig, path }) {
1431
+ const { isLoading, user } = auth.useSessionUser();
1432
+ const navigate = reactRouterDom.useNavigate();
1433
+ const handleClick = React8__default.default.useCallback(() => navigate(path), [navigate, path]);
1434
+ if (isLoading)
1435
+ return null;
1436
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1437
+ "div",
1438
+ {
1439
+ dflex: true,
1440
+ alignItems: "center",
1441
+ border: "0.5",
1442
+ borderColor: `${color}-${darkMode ? "800" : "200"}`,
1443
+ ps: "3",
1444
+ py: "1.5",
1445
+ textSize: "md",
1446
+ rounded: "lg",
1447
+ hover_bgColor: `${color}-${darkMode ? "800" : "200"}`,
1448
+ cursor: "pointer",
1449
+ textColor: darkMode ? "white" : "slate-800",
1450
+ onClick: handleClick,
1451
+ children: [
1452
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Avatar, { size: "sm", src: user?.media?.url ?? "", name: `${user?.firstname} ${user?.lastname}` }),
1453
+ /* @__PURE__ */ jsxRuntime.jsx("span", { flexGrow: true, ms: "2", children: `${esToolkit.capitalize(user?.firstname || user?.lastname || "")}` }),
1454
+ /* @__PURE__ */ jsxRuntime.jsx(
1455
+ ui.IconButton,
1456
+ {
1457
+ variant: "borderless",
1458
+ corners: "pill",
1459
+ scheme: "dark",
1460
+ textColor: darkMode ? "white" : "slate-800",
1461
+ hover_textColor: darkMode ? "white" : "slate-800",
1462
+ hover_bgColor: `${color}-${darkMode ? "900" : "200"}`,
1463
+ icon: js.mdiCog,
1464
+ onClick: handleClick
1465
+ }
1466
+ ),
1467
+ /* @__PURE__ */ jsxRuntime.jsx(OverflowMenu, { color, darkMode, menuConfig })
1468
+ ]
1469
+ }
1470
+ );
1471
+ }
1472
+ function OverflowMenu({ color, darkMode, menuConfig }) {
1473
+ const [showPopup, setShowPopup] = React8__default.default.useState(false);
1474
+ const navigate = reactRouterDom.useNavigate();
1475
+ const logout = auth.useSessionLogout(false);
1476
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(
1477
+ ui.Popup,
1478
+ {
1479
+ show: showPopup,
1480
+ position: "relative",
1481
+ side: "bottom-end",
1482
+ onClick: (e) => {
1483
+ e.preventDefault();
1484
+ e.stopPropagation();
1485
+ setShowPopup((show) => !show);
1486
+ },
1487
+ onHide: () => setShowPopup(false),
1488
+ children: [
1489
+ /* @__PURE__ */ jsxRuntime.jsx(
1490
+ ui.IconButton,
1491
+ {
1492
+ icon: js.mdiDotsVertical,
1493
+ variant: "borderless",
1494
+ corners: "pill",
1495
+ scheme: "dark",
1496
+ textColor: darkMode ? "white" : "slate-800",
1497
+ hover_textColor: darkMode ? "white" : "slate-800",
1498
+ hover_bgColor: `${color}-${darkMode ? "900" : "200"}`
1499
+ }
1500
+ ),
1501
+ /* @__PURE__ */ jsxRuntime.jsxs(
1502
+ "div",
1503
+ {
1504
+ bgColor: "white",
1505
+ rounded: "sm",
1506
+ overflow: "hidden",
1507
+ shadow: true,
1508
+ mt: "1",
1509
+ border: "px",
1510
+ borderColor: "gray-200",
1511
+ divideColor: "gray-200",
1512
+ divideY: "px",
1513
+ minW: "40",
1514
+ children: [
1515
+ menuConfig && menuConfig.length > 0 && menuConfig.map((item, index) => {
1516
+ if (item.type == "item") {
1517
+ return /* @__PURE__ */ jsxRuntime.jsx(MenuItem2, { icon: item.icon, onClick: () => navigate(item.path), children: item.label }, index);
1518
+ }
1519
+ return null;
1520
+ }),
1521
+ /* @__PURE__ */ jsxRuntime.jsx(MenuItem2, { icon: js.mdiLogout, onClick: logout, children: "Logout" })
1522
+ ]
1523
+ }
1524
+ )
1525
+ ]
1526
+ }
1527
+ ) });
1528
+ }
1529
+ function MenuItem2({ icon, onClick, children, ...props }) {
1530
+ const handleClick = React8__default.default.useCallback((e) => {
1531
+ e.preventDefault();
1532
+ e.stopPropagation();
1533
+ onClick?.(e);
1534
+ }, []);
1535
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1536
+ ui.Button,
1537
+ {
1538
+ variant: "borderless",
1539
+ scheme: "dark",
1540
+ size: "sm",
1541
+ alignItems: "center",
1542
+ dflex: true,
1543
+ gap: "2",
1544
+ px: "2",
1545
+ py: "1.5",
1546
+ w: "full",
1547
+ onClick: handleClick,
1548
+ textColor: "slate-700",
1549
+ ...props,
1550
+ children: [
1551
+ icon && /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: icon, size: "md" }),
1552
+ children
1553
+ ]
1554
+ }
1555
+ );
1556
+ }
1557
+ function Sidebar({ show, logo, title, menuConfig, userMenuConfig, userSettingsPath, color, darkMode, ...props }) {
1558
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1559
+ "div",
1560
+ {
1561
+ dflex: true,
1562
+ flexCol: true,
1563
+ w: "full",
1564
+ md_w: "64",
1565
+ minH: "screen",
1566
+ p: "0",
1567
+ textColor: darkMode ? "white" : "slate-800",
1568
+ ...props,
1569
+ children: [
1570
+ /* @__PURE__ */ jsxRuntime.jsxs(
1571
+ components.FlexCenter,
1572
+ {
1573
+ placeContent: "start",
1574
+ p: "4",
1575
+ font: "title",
1576
+ gap: "3",
1577
+ borderB: "px",
1578
+ borderBColor: "slate-900",
1579
+ borderOpacity: "5",
1580
+ children: [
1581
+ logo ?? /* @__PURE__ */ jsxRuntime.jsx(Logo, { width: 40, height: 40, darkMode }),
1582
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { textSize: "md", children: title || env.AppEnv.appName() })
1583
+ ]
1584
+ }
1585
+ ),
1586
+ /* @__PURE__ */ jsxRuntime.jsx(Menu, { overflowY: "auto", flexGrow: "1", p: "4", darkMode, config: menuConfig }),
1587
+ /* @__PURE__ */ jsxRuntime.jsx("div", { p: "2", children: /* @__PURE__ */ jsxRuntime.jsx(UserBlock, { darkMode, color, menuConfig: userMenuConfig, path: userSettingsPath }) })
1588
+ ]
1589
+ }
1590
+ );
1591
+ }
1592
+ function Logo({ width, height, darkMode, ...props }) {
1593
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ...props, children: /* @__PURE__ */ jsxRuntime.jsx(
1594
+ Image__default.default,
1595
+ {
1596
+ src: `/logo_${darkMode ? "light" : "dark"}.png`,
1597
+ alt: env.AppEnv.appName() || "",
1598
+ width,
1599
+ height,
1600
+ priority: true,
1601
+ unoptimized: true
1602
+ }
1603
+ ) });
1604
+ }
1605
+ function AdminLayout({ color, darkMode, logo, title, menuConfig, userMenuConfig, userSettingsPath, ...props }) {
1606
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1607
+ "div",
1608
+ {
1609
+ w: "full",
1610
+ h: "screen",
1611
+ dflex: true,
1612
+ flexRow: true,
1613
+ bgColor: `${color}-${darkMode ? "900" : "100"}`,
1614
+ ...props,
1615
+ children: [
1616
+ /* @__PURE__ */ jsxRuntime.jsx(
1617
+ LeftPanel,
1618
+ {
1619
+ color,
1620
+ darkMode,
1621
+ logo,
1622
+ title,
1623
+ menuConfig,
1624
+ userMenuConfig,
1625
+ userSettingsPath
1626
+ }
1627
+ ),
1628
+ /* @__PURE__ */ jsxRuntime.jsx("div", { w: "screen", py: "2", pe: "2", children: /* @__PURE__ */ jsxRuntime.jsx(Content, { bgColor: "white", rounded: "lg", shadow: true }) })
1629
+ ]
1630
+ }
1631
+ );
1632
+ }
1633
+ function LeftPanel({ color, darkMode, logo, title, menuConfig, userMenuConfig, userSettingsPath }) {
1634
+ const [isOpen, __, toggle] = hooks.useBoolean(true);
1635
+ reactHotkeysHook.useHotkeys("ctrl+t", () => toggle(), [toggle]);
1636
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1637
+ "div",
1638
+ {
1639
+ ms: isOpen ? "0" : "-14.5rem",
1640
+ transition: "all",
1641
+ duration: "500",
1642
+ transform: true,
1643
+ children: [
1644
+ /* @__PURE__ */ jsxRuntime.jsx(
1645
+ Sidebar,
1646
+ {
1647
+ flexShrink: "0",
1648
+ color,
1649
+ darkMode,
1650
+ logo,
1651
+ title,
1652
+ menuConfig,
1653
+ userMenuConfig,
1654
+ userSettingsPath
1655
+ }
1656
+ ),
1657
+ /* @__PURE__ */ jsxRuntime.jsx(
1658
+ ui.IconButton,
1659
+ {
1660
+ icon: js.mdiArrowLeft,
1661
+ transition: "all",
1662
+ duration: "500",
1663
+ transform: true,
1664
+ rotate: isOpen ? "0" : "180",
1665
+ position: "absolute",
1666
+ bottom: "14",
1667
+ end: "-5",
1668
+ size: "lg",
1669
+ corners: "pill",
1670
+ onClick: toggle,
1671
+ z: "100"
1672
+ }
1673
+ )
1674
+ ]
1675
+ }
1676
+ );
1677
+ }
1678
+ var defaultErrorMsg2 = "Oops, something went wrong...";
1679
+ function AttachDialog({
1680
+ queryId,
1681
+ queryKey,
1682
+ queryFetchFn,
1683
+ queryFetchAllKey,
1684
+ queryFetchAllFn,
1685
+ querySaveFn,
1686
+ matchKey,
1687
+ size = "lg",
1688
+ show,
1689
+ onClose,
1690
+ itemLabel,
1691
+ onSuccess,
1692
+ onFetchError,
1693
+ fetchErrorMsg = defaultErrorMsg2,
1694
+ onSaveError,
1695
+ saveErrorMsg = defaultErrorMsg2,
1696
+ invalidateQueriesOnSuccess = true,
1697
+ retryText = "Retry",
1698
+ cancelLabel = "Cancel",
1699
+ saveLabel,
1700
+ formikProps,
1701
+ getItemName,
1702
+ ...props
1703
+ }) {
1704
+ const queryClient = reactQuery.useQueryClient();
1705
+ const { data: attached, isInitialLoading: fetchLoading, isError: fetchError, refetch, error } = api.useApiQuery(queryKey, queryFetchFn);
1706
+ const { data, isInitialLoading: fetchAllLoading, isError: fetchAllError, refetch: refetchAll, error: errorAll } = api.useApiQuery(queryFetchAllKey, queryFetchAllFn);
1707
+ const [selectedResources, setSelectedResources] = React8__default.default.useState([]);
1708
+ const isLoading = fetchLoading || fetchAllLoading;
1709
+ const isError = fetchError || fetchAllError;
1710
+ const mutation = api.useApiMutation(querySaveFn, queryKey, queryId);
1711
+ const handleClick = React8__default.default.useCallback((event) => {
1712
+ const id = event?.currentTarget.dataset.id ?? "";
1713
+ const arr = selectedResources.concat([]);
1714
+ const i = selectedResources.indexOf(id);
1715
+ if (i != -1)
1716
+ arr.splice(i, 1);
1717
+ else
1718
+ arr.push(id);
1719
+ setSelectedResources(arr);
1720
+ }, [selectedResources, setSelectedResources]);
1721
+ const retry = React8__default.default.useCallback(() => {
1722
+ if (fetchError)
1723
+ refetch();
1724
+ if (fetchAllError)
1725
+ refetchAll();
1726
+ }, [refetch, refetchAll, fetchError, fetchAllError]);
1727
+ const saveItem = React8__default.default.useCallback(() => {
1728
+ mutation.reset();
1729
+ mutation.mutateAsync({ resources: selectedResources }).then((response) => {
1730
+ if (onSuccess)
1731
+ onSuccess(response);
1732
+ else
1733
+ reactToastify.toast.success(`${itemLabel} saved`);
1734
+ if (invalidateQueriesOnSuccess)
1735
+ queryClient.invalidateQueries({ queryKey });
1736
+ onClose?.();
1737
+ }).catch((error2) => {
1738
+ console.error("on error", error2);
1739
+ if (onSaveError)
1740
+ onSaveError();
1741
+ else
1742
+ reactToastify.toast.error(`Error adding ${itemLabel}`);
1743
+ });
1744
+ }, [mutation, queryId, onSuccess, queryClient, onSaveError, onClose]);
1745
+ const resources = React8__default.default.useMemo(() => {
1746
+ let r = [];
1747
+ if (attached && data) {
1748
+ r = [].concat(data);
1749
+ attached.forEach((attachedItem) => r.splice(r.findIndex((item) => item.id == attachedItem[matchKey]), 1));
1750
+ if (getItemName)
1751
+ r = r.map((item) => {
1752
+ return { ...item, name: getItemName(item) };
1753
+ });
1754
+ r = esToolkit.sortBy(r, ["name"]);
1755
+ }
1756
+ return r;
1757
+ }, [attached, data]);
1758
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1759
+ ui.Modal,
1760
+ {
1761
+ size,
1762
+ show,
1763
+ onClose,
1764
+ scheme: "light",
1765
+ transition: true,
1766
+ ...props,
1767
+ children: [
1768
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Modal.Header, { children: `Add ${itemLabel}` }),
1769
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx(ui.Modal.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(components.QueryLoadingState, { minW: "72" }) }),
1770
+ isError && /* @__PURE__ */ jsxRuntime.jsx(ui.Modal.Body, { children: /* @__PURE__ */ jsxRuntime.jsx(components.RetryOnError, { label: `${fetchErrorMsg} ${error}`, onClick: retry }) }),
1771
+ !isLoading && !isError && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1772
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Modal.Body, { px: "0", pb: "6", maxH: "750px", overflow: "auto", children: /* @__PURE__ */ jsxRuntime.jsx("div", { dflex: true, flexCol: true, overflow: "auto", children: resources.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
1773
+ ListItem,
1774
+ {
1775
+ label: item.name,
1776
+ value: item.id,
1777
+ "data-id": item.id,
1778
+ checked: selectedResources.includes(`${item.id}`),
1779
+ onClick: handleClick
1780
+ },
1781
+ item.id
1782
+ )) }) }),
1783
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Modal.Footer, { dflex: true, placeContent: "end", spaceX: "3", children: [
1784
+ /* @__PURE__ */ jsxRuntime.jsx(
1785
+ ui.Button,
1786
+ {
1787
+ disabled: mutation.isLoading,
1788
+ onClick: onClose,
1789
+ variant: "borderless",
1790
+ me: "2",
1791
+ children: cancelLabel
1792
+ }
1793
+ ),
1794
+ /* @__PURE__ */ jsxRuntime.jsx(
1795
+ ui.Button,
1796
+ {
1797
+ type: "submit",
1798
+ disabled: selectedResources.length == 0 || mutation.isLoading,
1799
+ onClick: saveItem,
1800
+ children: saveLabel ? saveLabel : queryId ? "Update" : "Create"
1801
+ }
1802
+ )
1803
+ ] })
1804
+ ] }),
1805
+ mutation.isLoading && /* @__PURE__ */ jsxRuntime.jsx(components.ModalLoadingOverlay, {})
1806
+ ]
1807
+ }
1808
+ );
1809
+ }
1810
+ function ListItem({ label, value, checked, ...props }) {
1811
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1812
+ "div",
1813
+ {
1814
+ dflex: true,
1815
+ alignItems: "center",
1816
+ hover_bgColor: "slate-100",
1817
+ px: "5",
1818
+ py: "2",
1819
+ cursor: "pointer",
1820
+ ...props,
1821
+ children: [
1822
+ /* @__PURE__ */ jsxRuntime.jsx("span", { flexGrow: true, children: label }),
1823
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Checkbox, { name: `resources.${value}`, value, checked })
1824
+ ]
1825
+ }
1826
+ );
1827
+ }
1828
+ function FormActionDialog({
1829
+ initialValues,
1830
+ itemLabel,
1831
+ queryId = "",
1832
+ queryKey,
1833
+ queryFn,
1834
+ queryOptions,
1835
+ onSuccess,
1836
+ successMsg,
1837
+ showSuccessMsg,
1838
+ onError,
1839
+ errorMsg,
1840
+ showErrorMsg,
1841
+ processInput,
1842
+ invalidateQueriesOnSuccess = true,
1843
+ cancelLabel = "Cancel",
1844
+ saveLabel = "Send",
1845
+ size = "lg",
1846
+ title,
1847
+ form: form$1,
1848
+ show,
1849
+ onClose,
1850
+ formikProps,
1851
+ ...props
1852
+ }) {
1853
+ const mutation = invalidateQueriesOnSuccess ? api.useInvalidateParentMutation(queryFn, queryKey, queryOptions) : api.useApiMutation(queryFn, queryKey, queryId, queryOptions);
1854
+ const mutate = api.useMutate(mutation, {
1855
+ onSuccess,
1856
+ successMsg,
1857
+ showSuccessMsg,
1858
+ onError,
1859
+ errorMsg,
1860
+ showErrorMsg,
1861
+ processInput
1862
+ });
1863
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1864
+ ui.Modal,
1865
+ {
1866
+ size,
1867
+ show,
1868
+ onClose,
1869
+ scheme: "light",
1870
+ transition: true,
1871
+ ...props,
1872
+ children: [
1873
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Modal.Header, { children: title }),
1874
+ /* @__PURE__ */ jsxRuntime.jsxs(
1875
+ form.FormProvider,
1876
+ {
1877
+ initialValues: initialValues ?? {},
1878
+ onSubmit: mutate,
1879
+ ...formikProps,
1880
+ children: [
1881
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Modal.Body, { pb: "6", children: [
1882
+ React8__default.default.isValidElement(form$1) && form$1,
1883
+ Array.isArray(form$1) && /* @__PURE__ */ jsxRuntime.jsx(form.FormRenderer, { form: form$1 })
1884
+ ] }),
1885
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Modal.Footer, { dflex: true, placeContent: "end", spaceX: "3", children: [
1886
+ /* @__PURE__ */ jsxRuntime.jsx(
1887
+ ui.Button,
1888
+ {
1889
+ disabled: mutation.isLoading,
1890
+ onClick: onClose,
1891
+ variant: "borderless",
1892
+ me: "2",
1893
+ children: cancelLabel
1894
+ }
1895
+ ),
1896
+ /* @__PURE__ */ jsxRuntime.jsx(form.SubmitButton, { disabled: mutation.isLoading, children: saveLabel })
1897
+ ] })
1898
+ ]
1899
+ }
1900
+ ),
1901
+ mutation.isLoading && /* @__PURE__ */ jsxRuntime.jsx(components.ModalLoadingOverlay, {})
1902
+ ]
1903
+ }
1904
+ );
1905
+ }
1906
+ var PageStateContainer = React8__default.default.forwardRef(({ loading = false, children, ...props }, ref) => {
1907
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1908
+ loading && /* @__PURE__ */ jsxRuntime.jsx(components.QueryLoadingState, { w: "full", h: "100%" }),
1909
+ !loading && /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { ref, center: true, size: "x2", dflex: true, flexCol: true, gap: "8", ...props, children })
1910
+ ] });
1911
+ });
1912
+ function PageSubSectionTitle({ children, ...props }) {
1913
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { trait: "typo.h6", mb: "3", ...props, children });
1914
+ }
1915
+ var labels = {
1916
+ draft: "Draft",
1917
+ published: "Published",
1918
+ pending: "Pending",
1919
+ approved: "Approved",
1920
+ partially_approved: "Partially Approved",
1921
+ rejected: "Rejected"
1922
+ };
1923
+ var schemes2 = {
1924
+ draft: "warning",
1925
+ published: "success",
1926
+ pending: "secondary",
1927
+ approved: "success",
1928
+ partially_approved: "warning",
1929
+ rejected: "danger"
1930
+ };
1931
+ function StatusBadge({ status, ...props }) {
1932
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "sm", variant: "glass", whiteSpace: "nowrap", rounded: "full", px: "3", scheme: schemes2[status], ...props, children: labels[status] });
1933
+ }
1934
+ function TableRowViewButton({ path, ...props }) {
1935
+ const openPage = React8__default.default.useCallback((event) => {
1936
+ event?.preventDefault();
1937
+ event?.stopPropagation();
1938
+ window.open(`${env.AppEnv.websiteUrl()}/${path}`, "_blank");
1939
+ }, [path]);
1940
+ return /* @__PURE__ */ jsxRuntime.jsx(TableRowActionButton, { icon: js.mdiOpenInNew, onClick: openPage, ...props });
1941
+ }
1942
+ function TableRowNavigateButton({ path, ...props }) {
1943
+ const navigate = reactRouterDom.useNavigate();
1944
+ const handleClick = React8__default.default.useCallback((event) => {
1945
+ event?.preventDefault();
1946
+ event?.stopPropagation();
1947
+ navigate(`${path}`);
1948
+ }, [navigate, path]);
1949
+ return /* @__PURE__ */ jsxRuntime.jsx(TableRowActionButton, { icon: js.mdiEye, onClick: handleClick, ...props });
1950
+ }
1951
+ function TableRowActionDialogButton({ icon, children, ...props }) {
1952
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1953
+ DialogButton,
1954
+ {
1955
+ dflex: true,
1956
+ alignContent: "center",
1957
+ placeContent: "center",
1958
+ py: "2.5",
1959
+ px: "3",
1960
+ h: "full",
1961
+ size: "lg",
1962
+ variant: "borderless",
1963
+ corners: "square",
1964
+ gap: "2",
1965
+ ...props,
1966
+ children: [
1967
+ icon && /* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { path: icon, size: "sm" }),
1968
+ children
1969
+ ]
1970
+ }
1971
+ );
1972
+ }
1973
+ function TableRowEditButton({ children, ...props }) {
1974
+ return /* @__PURE__ */ jsxRuntime.jsx(TableRowActionDialogButton, { icon: js.mdiPencil, ...props, children });
1975
+ }
1976
+ function TableRowDeleteButton({ children, ...props }) {
1977
+ return /* @__PURE__ */ jsxRuntime.jsx(TableRowActionDialogButton, { icon: js.mdiDelete, ...props, children });
1978
+ }
1979
+ function TableRowActionBar({
1980
+ publishId,
1981
+ viewPath,
1982
+ navigatePath,
1983
+ editDialog,
1984
+ deleteDialog,
1985
+ children,
1986
+ ...props
1987
+ }) {
1988
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { dflex: true, spaceX: "1", placeContent: "end", ...props, children: [
1989
+ viewPath && /* @__PURE__ */ jsxRuntime.jsx(TableRowViewButton, { path: viewPath }),
1990
+ navigatePath && /* @__PURE__ */ jsxRuntime.jsx(TableRowNavigateButton, { path: navigatePath }),
1991
+ editDialog && /* @__PURE__ */ jsxRuntime.jsx(TableRowEditButton, { buildDialog: editDialog }),
1992
+ deleteDialog && /* @__PURE__ */ jsxRuntime.jsx(TableRowDeleteButton, { buildDialog: deleteDialog }),
1993
+ children
1994
+ ] });
1995
+ }
1996
+ function TableRowPublishPostButton2({ id, api: api$1, status, invalidateQueryKey, ...props }) {
1997
+ const isDraft = status == "draft";
1998
+ const mutation = api.useInvalidateParentMutation(isDraft ? api$1.publish : api$1.unpublish, invalidateQueryKey ?? api$1.queryKey, { networkMode: "always" });
1999
+ const publish = React8__default.default.useCallback((event) => {
2000
+ event?.preventDefault();
2001
+ event?.stopPropagation();
2002
+ mutation.reset();
2003
+ mutation.mutateAsync(id).then(() => reactToastify.toast.success(isDraft ? "Published!" : "Unpublished!")).catch((error) => reactToastify.toast.error(`Error: ${error}`));
2004
+ }, [mutation, id]);
2005
+ return /* @__PURE__ */ jsxRuntime.jsx(TableRowActionButton, { icon: isDraft ? js.mdiPublish : js.mdiPublishOff, onClick: publish, ...props });
2006
+ }
2007
+
2008
+ exports.AdminLayout = AdminLayout;
2009
+ exports.AttachDialog = AttachDialog;
2010
+ exports.Breadcrumbs = Breadcrumbs;
2011
+ exports.ButtonBar = ButtonBar;
2012
+ exports.ButtonBarButton = ButtonBarButton;
2013
+ exports.ButtonBarDialogButton = ButtonBarDialogButton;
2014
+ exports.ButtonBarSubmitButton = ButtonBarSubmitButton;
2015
+ exports.DialogButton = DialogButton;
2016
+ exports.FormActionDialog = FormActionDialog;
2017
+ exports.InvalidateButton = InvalidateButton;
2018
+ exports.ItemDeleteDialog = ItemDeleteDialog;
2019
+ exports.ItemEditDialog = ItemEditDialog;
2020
+ exports.Menu = Menu;
2021
+ exports.NavigateButton = NavigateButton;
2022
+ exports.OrderCell = OrderCell;
2023
+ exports.PageContainer = PageContainer;
2024
+ exports.PageContentEditor = PageContentEditor;
2025
+ exports.PageMain = PageMain;
2026
+ exports.PageQueryStateContainer = PageQueryStateContainer;
2027
+ exports.PageSectionTitle = PageSectionTitle;
2028
+ exports.PageSidebar = PageSidebar;
2029
+ exports.PageSidebarSection = PageSidebarSection;
2030
+ exports.PageStateContainer = PageStateContainer;
2031
+ exports.PageSubSectionTitle = PageSubSectionTitle;
2032
+ exports.PageTabbedTopBar = PageTabbedTopBar;
2033
+ exports.PageTabbedTopBarProvider = PageTabbedTopBarProvider;
2034
+ exports.PageTitle = PageTitle;
2035
+ exports.PageTopBar = PageTopBar;
2036
+ exports.PageTopBarToolbar = PageTopBarToolbar;
2037
+ exports.PublishButton = PublishButton;
2038
+ exports.ScreenRenderer = ScreenRenderer;
2039
+ exports.SectionTitle = SectionTitle;
2040
+ exports.StatusBadge = StatusBadge;
2041
+ exports.TableContainer = TableContainer;
2042
+ exports.TableCreateButton = TableCreateButton;
2043
+ exports.TableFilterButton = TableFilterButton;
2044
+ exports.TableRowActionBar = TableRowActionBar;
2045
+ exports.TableRowActionButton = TableRowActionButton;
2046
+ exports.TableRowActionDialogButton = TableRowActionDialogButton;
2047
+ exports.TableRowDeleteButton = TableRowDeleteButton;
2048
+ exports.TableRowEditButton = TableRowEditButton;
2049
+ exports.TableRowNavigateButton = TableRowNavigateButton;
2050
+ exports.TableRowPublishPostButton = TableRowPublishPostButton2;
2051
+ exports.TableRowViewButton = TableRowViewButton;
2052
+ exports.TableTopBar = TableTopBar;
2053
+ exports.UpdateButton = UpdateButton;
2054
+ exports.ViewButton = ViewButton;