@rangka/client 0.1.0 → 0.1.2

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 (352) hide show
  1. package/dist/App.d.ts.map +1 -1
  2. package/dist/App.js +7 -1
  3. package/dist/App.js.map +1 -1
  4. package/dist/components/ui/input-group.d.ts +1 -1
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +2 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/main.d.ts.map +1 -1
  10. package/dist/main.js +20 -0
  11. package/dist/main.js.map +1 -1
  12. package/dist/shell/assets/AttachmentWidget-BTTGroHP.js +1 -0
  13. package/dist/shell/assets/AttachmentsWidget-DZgvmO9P.js +1 -0
  14. package/dist/shell/assets/BadgeWidget-DN6GsAAG.js +1 -0
  15. package/dist/shell/assets/CardWidget-qX-UvqJh.js +1 -0
  16. package/dist/shell/assets/CheckboxWidget-CYPZ85ih.js +1 -0
  17. package/dist/shell/assets/CodeWidget-DnVtHG1d.js +1 -0
  18. package/dist/shell/assets/ColumnWidget-CYmFCVOf.js +1 -0
  19. package/dist/shell/assets/ComputedWidget-BQApkfir.js +1 -0
  20. package/dist/shell/assets/DatePickerWidget-pEusSy9D.js +1 -0
  21. package/dist/shell/assets/DatetimeWidget-M0fEGDTD.js +1 -0
  22. package/dist/shell/assets/DividerWidget-hXVGhIKC.js +1 -0
  23. package/dist/shell/assets/DrawerWidget-DynL7EIy.js +1 -0
  24. package/dist/shell/assets/DynamicLinkWidget-ChMJ5DAf.js +1 -0
  25. package/dist/shell/assets/IconWidget-Cgo9txq1.js +1 -0
  26. package/dist/shell/assets/ImageWidget-YUv1_OQK.js +1 -0
  27. package/dist/shell/assets/JsonWidget-RHUHhXHJ.js +1 -0
  28. package/dist/shell/assets/LinkWidget-CIu7qmb2.js +1 -0
  29. package/dist/shell/assets/ManyToManyWidget-DCQnygvZ.js +1 -0
  30. package/dist/shell/assets/ModalWidget-FggzYaS2.js +1 -0
  31. package/dist/shell/assets/MoneyWidget-CKjOSucD.js +1 -0
  32. package/dist/shell/assets/RepeatWidget-Dfp4zW4d.js +1 -0
  33. package/dist/shell/assets/ScrollAreaWidget-CdFdf4rv.js +1 -0
  34. package/dist/shell/assets/SequenceWidget-DIXHZslz.js +1 -0
  35. package/dist/shell/assets/SpacerWidget-BgM4dC6x.js +1 -0
  36. package/dist/shell/assets/SplitWidget-_mcQkjQk.js +1 -0
  37. package/dist/shell/assets/StackWidget-BI_VIreo.js +1 -0
  38. package/dist/shell/assets/TableWidget-DuIvd6qR.js +1 -0
  39. package/dist/shell/assets/TextareaWidget-CATua7Ls.js +1 -0
  40. package/dist/shell/assets/TreeWidget-BoHlhfza.js +1 -0
  41. package/dist/shell/assets/calendar-DqckiKt1.js +1 -0
  42. package/dist/shell/assets/index-63v1sBS3.css +1 -0
  43. package/dist/shell/assets/index-D1wStSrO.js +8635 -0
  44. package/dist/shell/assets/popover-DywIKFaQ.js +1 -0
  45. package/dist/shell/assets/textarea-BVCZevA6.js +1 -0
  46. package/dist/shell/assets/useSurfaceContext-kzu9770H.js +1 -0
  47. package/dist/shell/assets/vendor-query-dRdWN_eK.js +1 -0
  48. package/dist/shell/assets/vendor-radix-D-Trh8JA.js +69 -0
  49. package/dist/shell/assets/vendor-router-B1WM9yRc.js +17 -0
  50. package/dist/shell/index.html +5 -2
  51. package/dist/theme.css +82 -0
  52. package/dist/widgets/components/lazy-manifest.d.ts +11 -0
  53. package/dist/widgets/components/lazy-manifest.d.ts.map +1 -0
  54. package/dist/widgets/components/lazy-manifest.js +32 -0
  55. package/dist/widgets/components/lazy-manifest.js.map +1 -0
  56. package/dist/widgets/components/register.d.ts.map +1 -1
  57. package/dist/widgets/components/register.js +0 -58
  58. package/dist/widgets/components/register.js.map +1 -1
  59. package/dist/widgets/loader.d.ts +3 -0
  60. package/dist/widgets/loader.d.ts.map +1 -0
  61. package/dist/widgets/loader.js +99 -0
  62. package/dist/widgets/loader.js.map +1 -0
  63. package/dist/widgets/renderer/LazyWidget.d.ts +8 -0
  64. package/dist/widgets/renderer/LazyWidget.d.ts.map +1 -0
  65. package/dist/widgets/renderer/LazyWidget.js +31 -0
  66. package/dist/widgets/renderer/LazyWidget.js.map +1 -0
  67. package/dist/widgets/renderer/WidgetErrorBoundary.d.ts +17 -0
  68. package/dist/widgets/renderer/WidgetErrorBoundary.d.ts.map +1 -0
  69. package/dist/widgets/renderer/WidgetErrorBoundary.js +18 -0
  70. package/dist/widgets/renderer/WidgetErrorBoundary.js.map +1 -0
  71. package/dist/widgets/renderer/WidgetRenderer.d.ts.map +1 -1
  72. package/dist/widgets/renderer/WidgetRenderer.js +8 -6
  73. package/dist/widgets/renderer/WidgetRenderer.js.map +1 -1
  74. package/package.json +7 -4
  75. package/.claude/skills/add-widget/SKILL.md +0 -101
  76. package/.turbo/turbo-build.log +0 -29
  77. package/CHANGELOG.md +0 -18
  78. package/CLAUDE.md +0 -236
  79. package/components.json +0 -25
  80. package/dist/components/ui/chart.d.ts +0 -45
  81. package/dist/components/ui/chart.d.ts.map +0 -1
  82. package/dist/components/ui/chart.js +0 -119
  83. package/dist/components/ui/chart.js.map +0 -1
  84. package/dist/shell/assets/index--35CAvcP.js +0 -8715
  85. package/dist/shell/assets/index-COLmoPYo.css +0 -1
  86. package/index.html +0 -12
  87. package/src/App.tsx +0 -44
  88. package/src/__tests__/setup.ts +0 -1
  89. package/src/api/auth.ts +0 -41
  90. package/src/api/boot.ts +0 -10
  91. package/src/api/client.ts +0 -26
  92. package/src/api/paths.ts +0 -3
  93. package/src/api/token.ts +0 -13
  94. package/src/auth/LoginForm.tsx +0 -67
  95. package/src/auth/SessionExpired.tsx +0 -24
  96. package/src/auth/SetupForm.tsx +0 -76
  97. package/src/boot/BootGate.tsx +0 -35
  98. package/src/boot/BootProvider.tsx +0 -28
  99. package/src/boot/types.ts +0 -9
  100. package/src/boot/useBoot.ts +0 -111
  101. package/src/components/Icon.tsx +0 -17
  102. package/src/components/ui/accordion.tsx +0 -82
  103. package/src/components/ui/alert-dialog.tsx +0 -180
  104. package/src/components/ui/alert.tsx +0 -76
  105. package/src/components/ui/aspect-ratio.tsx +0 -9
  106. package/src/components/ui/avatar.tsx +0 -94
  107. package/src/components/ui/badge.tsx +0 -45
  108. package/src/components/ui/breadcrumb.tsx +0 -104
  109. package/src/components/ui/button-group.tsx +0 -78
  110. package/src/components/ui/button.tsx +0 -65
  111. package/src/components/ui/calendar.tsx +0 -187
  112. package/src/components/ui/card.tsx +0 -85
  113. package/src/components/ui/carousel.tsx +0 -229
  114. package/src/components/ui/chart.tsx +0 -339
  115. package/src/components/ui/checkbox.tsx +0 -27
  116. package/src/components/ui/collapsible.tsx +0 -21
  117. package/src/components/ui/combobox.tsx +0 -275
  118. package/src/components/ui/command.tsx +0 -178
  119. package/src/components/ui/context-menu.tsx +0 -242
  120. package/src/components/ui/dialog.tsx +0 -146
  121. package/src/components/ui/direction.tsx +0 -20
  122. package/src/components/ui/drawer.tsx +0 -118
  123. package/src/components/ui/dropdown-menu.tsx +0 -247
  124. package/src/components/ui/empty.tsx +0 -94
  125. package/src/components/ui/field.tsx +0 -224
  126. package/src/components/ui/hover-card.tsx +0 -36
  127. package/src/components/ui/input-group.tsx +0 -142
  128. package/src/components/ui/input-otp.tsx +0 -86
  129. package/src/components/ui/input.tsx +0 -19
  130. package/src/components/ui/item.tsx +0 -182
  131. package/src/components/ui/kbd.tsx +0 -26
  132. package/src/components/ui/label.tsx +0 -19
  133. package/src/components/ui/menubar.tsx +0 -260
  134. package/src/components/ui/native-select.tsx +0 -55
  135. package/src/components/ui/navigation-menu.tsx +0 -160
  136. package/src/components/ui/pagination.tsx +0 -112
  137. package/src/components/ui/popover.tsx +0 -74
  138. package/src/components/ui/progress.tsx +0 -31
  139. package/src/components/ui/radio-group.tsx +0 -42
  140. package/src/components/ui/resizable.tsx +0 -42
  141. package/src/components/ui/scroll-area.tsx +0 -53
  142. package/src/components/ui/select.tsx +0 -185
  143. package/src/components/ui/separator.tsx +0 -26
  144. package/src/components/ui/sheet.tsx +0 -128
  145. package/src/components/ui/sidebar.tsx +0 -669
  146. package/src/components/ui/skeleton.tsx +0 -13
  147. package/src/components/ui/slider.tsx +0 -54
  148. package/src/components/ui/sonner.tsx +0 -43
  149. package/src/components/ui/spinner.tsx +0 -16
  150. package/src/components/ui/switch.tsx +0 -33
  151. package/src/components/ui/table.tsx +0 -87
  152. package/src/components/ui/tabs.tsx +0 -80
  153. package/src/components/ui/textarea.tsx +0 -18
  154. package/src/components/ui/toggle-group.tsx +0 -86
  155. package/src/components/ui/toggle.tsx +0 -44
  156. package/src/components/ui/tooltip.tsx +0 -53
  157. package/src/context/MetaContext.tsx +0 -22
  158. package/src/context/ModuleContext.tsx +0 -62
  159. package/src/context/PermissionsContext.tsx +0 -39
  160. package/src/context/ShellProviders.tsx +0 -33
  161. package/src/context/UserContext.tsx +0 -16
  162. package/src/data/QueryProvider.tsx +0 -7
  163. package/src/data/queryClient.ts +0 -18
  164. package/src/data/useModelMeta.ts +0 -17
  165. package/src/data/useMutation.ts +0 -60
  166. package/src/data/useRecord.ts +0 -29
  167. package/src/data/useSource.ts +0 -112
  168. package/src/hooks/use-mobile.ts +0 -19
  169. package/src/index.css +0 -260
  170. package/src/index.ts +0 -16
  171. package/src/lib/utils.ts +0 -6
  172. package/src/main.tsx +0 -17
  173. package/src/router/NotFound.tsx +0 -8
  174. package/src/router/RouterProvider.tsx +0 -7
  175. package/src/router/buildRouteTree.tsx +0 -63
  176. package/src/router/createShellRouter.ts +0 -9
  177. package/src/router/hooks.ts +0 -43
  178. package/src/shell/CommandPalette.tsx +0 -76
  179. package/src/shell/ConfirmDialog.tsx +0 -34
  180. package/src/shell/ConfirmProvider.tsx +0 -56
  181. package/src/shell/DrawerContext.tsx +0 -44
  182. package/src/shell/HeaderActions.tsx +0 -31
  183. package/src/shell/ModuleSelectorPage.tsx +0 -149
  184. package/src/shell/PageOutlet.tsx +0 -21
  185. package/src/shell/ShellContext.tsx +0 -45
  186. package/src/shell/ShellDevTools.tsx +0 -153
  187. package/src/shell/ShellLayout.tsx +0 -231
  188. package/src/shell/Toast.tsx +0 -58
  189. package/src/shell/ToastProvider.tsx +0 -60
  190. package/src/shell/app-sidebar/AppSidebar.tsx +0 -44
  191. package/src/shell/app-sidebar/ModuleSwitcher.tsx +0 -87
  192. package/src/shell/app-sidebar/NavMain.tsx +0 -64
  193. package/src/shell/app-sidebar/NavUser.tsx +0 -97
  194. package/src/shell/app-sidebar/SearchMenu.tsx +0 -22
  195. package/src/shell/app-sidebar/index.ts +0 -8
  196. package/src/shell/app-sidebar/types.ts +0 -38
  197. package/src/shell/types.ts +0 -6
  198. package/src/shell/useBreadcrumbs.ts +0 -42
  199. package/src/studio/bridge.ts +0 -125
  200. package/src/studio/index.ts +0 -3
  201. package/src/studio/overlay.ts +0 -47
  202. package/src/studio/types.ts +0 -32
  203. package/src/studio/walker.ts +0 -48
  204. package/src/vite-env.d.ts +0 -1
  205. package/src/widgets/__tests__/action-edge-cases.test.ts +0 -281
  206. package/src/widgets/__tests__/action.test.ts +0 -236
  207. package/src/widgets/__tests__/attachment-widget.test.tsx +0 -85
  208. package/src/widgets/__tests__/attachments-widget.test.tsx +0 -109
  209. package/src/widgets/__tests__/binding.test.ts +0 -76
  210. package/src/widgets/__tests__/button-widget.test.tsx +0 -145
  211. package/src/widgets/__tests__/checkbox-widget.test.tsx +0 -158
  212. package/src/widgets/__tests__/code-widget.test.tsx +0 -64
  213. package/src/widgets/__tests__/computed-widget.test.tsx +0 -62
  214. package/src/widgets/__tests__/condition-edge-cases.test.ts +0 -120
  215. package/src/widgets/__tests__/condition.test.ts +0 -221
  216. package/src/widgets/__tests__/context.test.ts +0 -99
  217. package/src/widgets/__tests__/data-widget.test.tsx +0 -204
  218. package/src/widgets/__tests__/datepicker-widget.test.tsx +0 -66
  219. package/src/widgets/__tests__/datetime-widget.test.tsx +0 -67
  220. package/src/widgets/__tests__/drawer-widget.test.tsx +0 -149
  221. package/src/widgets/__tests__/dynamic-link-widget.test.tsx +0 -52
  222. package/src/widgets/__tests__/edge-cases.test.ts +0 -232
  223. package/src/widgets/__tests__/evaluator.test.ts +0 -107
  224. package/src/widgets/__tests__/functions.test.ts +0 -147
  225. package/src/widgets/__tests__/grid-widget.test.tsx +0 -137
  226. package/src/widgets/__tests__/hooks.test.tsx +0 -249
  227. package/src/widgets/__tests__/icon-widget.test.tsx +0 -129
  228. package/src/widgets/__tests__/input-widget.test.tsx +0 -264
  229. package/src/widgets/__tests__/integration.test.ts +0 -116
  230. package/src/widgets/__tests__/json-widget.test.tsx +0 -70
  231. package/src/widgets/__tests__/link-widget.test.tsx +0 -92
  232. package/src/widgets/__tests__/many-to-many-widget.test.tsx +0 -93
  233. package/src/widgets/__tests__/modal-widget.test.tsx +0 -148
  234. package/src/widgets/__tests__/money-widget.test.tsx +0 -97
  235. package/src/widgets/__tests__/parser.test.ts +0 -171
  236. package/src/widgets/__tests__/reactive-variables.test.ts +0 -383
  237. package/src/widgets/__tests__/renderer.test.tsx +0 -300
  238. package/src/widgets/__tests__/repeat-widget.test.tsx +0 -229
  239. package/src/widgets/__tests__/select-widget.test.tsx +0 -231
  240. package/src/widgets/__tests__/sequence-widget.test.tsx +0 -58
  241. package/src/widgets/__tests__/shell-integration.test.tsx +0 -1343
  242. package/src/widgets/__tests__/split-widget.test.tsx +0 -133
  243. package/src/widgets/__tests__/state-edge-cases.test.ts +0 -118
  244. package/src/widgets/__tests__/state.test.ts +0 -106
  245. package/src/widgets/__tests__/table-data-binding.test.tsx +0 -482
  246. package/src/widgets/__tests__/table-filter-popover.test.tsx +0 -486
  247. package/src/widgets/__tests__/table-search.test.tsx +0 -305
  248. package/src/widgets/__tests__/table-widget.test.tsx +0 -509
  249. package/src/widgets/__tests__/textarea-widget.test.tsx +0 -105
  250. package/src/widgets/__tests__/tracker-validator-edge-cases.test.ts +0 -242
  251. package/src/widgets/__tests__/tracker.test.ts +0 -133
  252. package/src/widgets/__tests__/tree-widget.test.tsx +0 -97
  253. package/src/widgets/__tests__/use-model-source.test.ts +0 -67
  254. package/src/widgets/__tests__/validator.test.ts +0 -208
  255. package/src/widgets/action/dispatcher.ts +0 -334
  256. package/src/widgets/action/index.ts +0 -2
  257. package/src/widgets/binding/index.ts +0 -2
  258. package/src/widgets/binding/resolver.ts +0 -61
  259. package/src/widgets/components/AttachmentWidget.tsx +0 -111
  260. package/src/widgets/components/AttachmentsWidget.tsx +0 -121
  261. package/src/widgets/components/BadgeWidget.tsx +0 -35
  262. package/src/widgets/components/ButtonWidget.tsx +0 -43
  263. package/src/widgets/components/CardWidget.tsx +0 -68
  264. package/src/widgets/components/CheckboxWidget.tsx +0 -39
  265. package/src/widgets/components/CodeWidget.tsx +0 -44
  266. package/src/widgets/components/ColumnWidget.tsx +0 -22
  267. package/src/widgets/components/ComputedWidget.tsx +0 -49
  268. package/src/widgets/components/DataWidget.tsx +0 -189
  269. package/src/widgets/components/DatePickerWidget.tsx +0 -73
  270. package/src/widgets/components/DatetimeWidget.tsx +0 -160
  271. package/src/widgets/components/DividerWidget.tsx +0 -37
  272. package/src/widgets/components/DrawerWidget.tsx +0 -52
  273. package/src/widgets/components/DynamicLinkWidget.tsx +0 -130
  274. package/src/widgets/components/GridWidget.tsx +0 -134
  275. package/src/widgets/components/GroupWidget.tsx +0 -111
  276. package/src/widgets/components/IconWidget.tsx +0 -29
  277. package/src/widgets/components/ImageWidget.tsx +0 -28
  278. package/src/widgets/components/InputWidget.tsx +0 -70
  279. package/src/widgets/components/JsonWidget.tsx +0 -78
  280. package/src/widgets/components/LinkWidget.tsx +0 -99
  281. package/src/widgets/components/ManyToManyWidget.tsx +0 -125
  282. package/src/widgets/components/ModalWidget.tsx +0 -52
  283. package/src/widgets/components/MoneyWidget.tsx +0 -80
  284. package/src/widgets/components/RepeatWidget.tsx +0 -66
  285. package/src/widgets/components/ScrollAreaWidget.tsx +0 -40
  286. package/src/widgets/components/SectionWidget.tsx +0 -78
  287. package/src/widgets/components/SelectWidget.tsx +0 -63
  288. package/src/widgets/components/SequenceWidget.tsx +0 -32
  289. package/src/widgets/components/SpacerWidget.tsx +0 -29
  290. package/src/widgets/components/SplitWidget.tsx +0 -60
  291. package/src/widgets/components/StackWidget.tsx +0 -44
  292. package/src/widgets/components/TableWidget.tsx +0 -366
  293. package/src/widgets/components/TextWidget.tsx +0 -44
  294. package/src/widgets/components/TextareaWidget.tsx +0 -49
  295. package/src/widgets/components/TreeWidget.tsx +0 -109
  296. package/src/widgets/components/index.ts +0 -30
  297. package/src/widgets/components/register.ts +0 -93
  298. package/src/widgets/components/table/CellRenderers.tsx +0 -83
  299. package/src/widgets/components/table/TablePagination.tsx +0 -45
  300. package/src/widgets/components/table/TableToolbar.tsx +0 -285
  301. package/src/widgets/components/table/filter-operators.ts +0 -134
  302. package/src/widgets/components/table/index.ts +0 -11
  303. package/src/widgets/condition/evaluator.ts +0 -57
  304. package/src/widgets/condition/index.ts +0 -1
  305. package/src/widgets/context/builder.ts +0 -99
  306. package/src/widgets/context/index.ts +0 -8
  307. package/src/widgets/context/types.ts +0 -37
  308. package/src/widgets/data/index.ts +0 -5
  309. package/src/widgets/data/useModelQuery.ts +0 -116
  310. package/src/widgets/data/useModelRecord.ts +0 -37
  311. package/src/widgets/expression/evaluator.ts +0 -100
  312. package/src/widgets/expression/functions.ts +0 -131
  313. package/src/widgets/expression/index.ts +0 -13
  314. package/src/widgets/expression/parser.ts +0 -229
  315. package/src/widgets/expression/types.ts +0 -45
  316. package/src/widgets/form/FormContext.ts +0 -29
  317. package/src/widgets/form/FormProvider.tsx +0 -84
  318. package/src/widgets/form/FormWidget.tsx +0 -42
  319. package/src/widgets/form/index.ts +0 -4
  320. package/src/widgets/form/useFormState.ts +0 -127
  321. package/src/widgets/form/useFormSubmit.ts +0 -90
  322. package/src/widgets/form/useFormValidation.ts +0 -62
  323. package/src/widgets/hooks/index.ts +0 -8
  324. package/src/widgets/hooks/useAction.ts +0 -83
  325. package/src/widgets/hooks/useBind.ts +0 -34
  326. package/src/widgets/hooks/useCondition.ts +0 -21
  327. package/src/widgets/hooks/useDataQuery.ts +0 -48
  328. package/src/widgets/hooks/useExpression.ts +0 -14
  329. package/src/widgets/hooks/usePageState.ts +0 -21
  330. package/src/widgets/hooks/useSurfaceContext.ts +0 -11
  331. package/src/widgets/hooks/useWidgetContext.ts +0 -14
  332. package/src/widgets/index.ts +0 -80
  333. package/src/widgets/lib/layout-props.ts +0 -135
  334. package/src/widgets/reactivity/index.ts +0 -11
  335. package/src/widgets/reactivity/tracker.ts +0 -139
  336. package/src/widgets/reactivity/variables.ts +0 -213
  337. package/src/widgets/registry.ts +0 -41
  338. package/src/widgets/renderer/SlotRenderer.tsx +0 -47
  339. package/src/widgets/renderer/WidgetRenderer.tsx +0 -191
  340. package/src/widgets/renderer/index.ts +0 -4
  341. package/src/widgets/shell/WidgetSlotRenderer.tsx +0 -73
  342. package/src/widgets/shell/index.ts +0 -4
  343. package/src/widgets/shell/useActionHandlers.ts +0 -170
  344. package/src/widgets/state/index.ts +0 -2
  345. package/src/widgets/state/store.ts +0 -96
  346. package/src/widgets/types.ts +0 -28
  347. package/src/widgets/validation/index.ts +0 -2
  348. package/src/widgets/validation/validator.ts +0 -140
  349. package/tsconfig.json +0 -27
  350. package/tsconfig.tsbuildinfo +0 -1
  351. package/vite.config.ts +0 -21
  352. package/vitest.config.ts +0 -16
@@ -1,305 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
- import React from 'react';
3
- import { render, screen, fireEvent, cleanup, waitFor } from '@testing-library/react';
4
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
5
- import type { WidgetNode } from '@rangka/shared';
6
- import { registerWidget, clearWidgetRegistry } from '../registry.js';
7
- import { SlotRenderer } from '../renderer/SlotRenderer.js';
8
- import { StateStore } from '../state/store.js';
9
- import { TableWidget } from '../components/TableWidget.js';
10
- import { ColumnWidget } from '../components/ColumnWidget.js';
11
- import { MetaProvider } from '../../context/MetaContext.js';
12
- import type { WidgetContext } from '../context/types.js';
13
-
14
- vi.mock('../../api/client.js', () => ({
15
- apiClient: vi.fn(),
16
- }));
17
-
18
- import { apiClient } from '../../api/client.js';
19
- const mockApiClient = vi.mocked(apiClient);
20
-
21
- const sampleData = [
22
- { id: '1', name: 'Acme Corp', email: 'acme@test.com', total: 1500 },
23
- { id: '2', name: 'Beta Inc', email: 'beta@test.com', total: 2500 },
24
- ];
25
-
26
- function createQueryClient() {
27
- return new QueryClient({
28
- defaultOptions: { queries: { retry: false, gcTime: 0 } },
29
- });
30
- }
31
-
32
- function mockApiResponse(data: Record<string, unknown>[], total?: number) {
33
- mockApiClient.mockResolvedValueOnce({
34
- ok: true,
35
- json: () => Promise.resolve({ data, meta: { total: total ?? data.length } }),
36
- } as unknown as Response);
37
- }
38
-
39
- function tableNode(): WidgetNode[] {
40
- return [
41
- {
42
- type: 'table',
43
- bind: { model: { name: 'test.model' } },
44
- props: { pageSize: 20 },
45
- children: [
46
- { type: 'column', bind: { field: 'name' }, props: { label: 'Name', filterable: true } },
47
- { type: 'column', bind: { field: 'email' }, props: { label: 'Email', filterable: true } },
48
- { type: 'column', bind: { field: 'total' }, props: { label: 'Total', align: 'right' } },
49
- ],
50
- },
51
- ];
52
- }
53
-
54
- const metaWithSearch = {
55
- navigation: [],
56
- pages: [],
57
- models: {
58
- 'test.model': {
59
- qualifiedName: 'test.model',
60
- fields: [
61
- { name: 'name', type: 'string', label: 'Name', searchable: true },
62
- { name: 'email', type: 'string', label: 'Email', searchable: true },
63
- { name: 'total', type: 'money', label: 'Total' },
64
- ],
65
- },
66
- },
67
- };
68
-
69
- const metaWithoutSearch = {
70
- navigation: [],
71
- pages: [],
72
- models: {
73
- 'test.model': {
74
- qualifiedName: 'test.model',
75
- fields: [
76
- { name: 'name', type: 'string', label: 'Name' },
77
- { name: 'email', type: 'string', label: 'Email' },
78
- { name: 'total', type: 'money', label: 'Total' },
79
- ],
80
- },
81
- },
82
- };
83
-
84
- function renderTable(options: { state?: StateStore; meta?: Record<string, unknown> } = {}) {
85
- const { state = new StateStore(), meta = metaWithSearch } = options;
86
- const ctx: WidgetContext = { record: {}, model: 'test.model', mode: 'view' };
87
- const queryClient = createQueryClient();
88
- const result = render(
89
- <MetaProvider meta={meta}>
90
- <QueryClientProvider client={queryClient}>
91
- <SlotRenderer nodes={tableNode()} context={ctx} state={state} />
92
- </QueryClientProvider>
93
- </MetaProvider>,
94
- );
95
- return { ...result, state, queryClient };
96
- }
97
-
98
- beforeEach(() => {
99
- clearWidgetRegistry();
100
- registerWidget(
101
- {
102
- name: 'table',
103
- label: 'Table',
104
- category: 'data',
105
- schema: {},
106
- binding: 'model',
107
- triggers: [],
108
- container: true,
109
- accepts: ['column'],
110
- },
111
- TableWidget as never,
112
- );
113
- registerWidget(
114
- {
115
- name: 'column',
116
- label: 'Column',
117
- category: 'data',
118
- schema: {},
119
- binding: 'field',
120
- triggers: [],
121
- container: false,
122
- },
123
- ColumnWidget as never,
124
- );
125
- });
126
-
127
- afterEach(() => {
128
- cleanup();
129
- vi.restoreAllMocks();
130
- });
131
-
132
- describe('Table search', () => {
133
- describe('visibility', () => {
134
- it('shows searchbar when model has searchable fields', async () => {
135
- mockApiResponse(sampleData);
136
- renderTable();
137
-
138
- await waitFor(() => {
139
- expect(screen.getByText('Acme Corp')).toBeInTheDocument();
140
- });
141
-
142
- expect(screen.getByPlaceholderText('Search...')).toBeInTheDocument();
143
- });
144
-
145
- it('hides searchbar when model has no searchable fields', async () => {
146
- mockApiResponse(sampleData);
147
- renderTable({ meta: metaWithoutSearch });
148
-
149
- await waitFor(() => {
150
- expect(screen.getByText('Acme Corp')).toBeInTheDocument();
151
- });
152
-
153
- expect(screen.queryByPlaceholderText('Search...')).not.toBeInTheDocument();
154
- });
155
- });
156
-
157
- describe('debounced store update', () => {
158
- it('updates $search store key after debounce', async () => {
159
- mockApiResponse(sampleData);
160
- const state = new StateStore();
161
- renderTable({ state });
162
-
163
- await waitFor(() => {
164
- expect(screen.getByText('Acme Corp')).toBeInTheDocument();
165
- });
166
-
167
- const searchInput = screen.getByPlaceholderText('Search...');
168
- fireEvent.change(searchInput, { target: { value: 'Acme' } });
169
-
170
- await waitFor(
171
- () => {
172
- expect(state.get('$search.test.model')).toBe('Acme');
173
- },
174
- { timeout: 500 },
175
- );
176
- });
177
-
178
- it('resets page to 1 when search is applied', async () => {
179
- mockApiResponse(sampleData);
180
- const state = new StateStore();
181
- state.set('$page.test.model', 3);
182
- renderTable({ state });
183
-
184
- await waitFor(() => {
185
- expect(screen.getByText('Acme Corp')).toBeInTheDocument();
186
- });
187
-
188
- const searchInput = screen.getByPlaceholderText('Search...');
189
- fireEvent.change(searchInput, { target: { value: 'test' } });
190
-
191
- await waitFor(
192
- () => {
193
- expect(state.get('$page.test.model')).toBe(1);
194
- },
195
- { timeout: 500 },
196
- );
197
- });
198
-
199
- it('clears search from store when input is emptied', async () => {
200
- mockApiResponse(sampleData);
201
- const state = new StateStore();
202
- state.set('$search.test.model', 'old');
203
- renderTable({ state });
204
-
205
- await waitFor(() => {
206
- expect(screen.getByText('Acme Corp')).toBeInTheDocument();
207
- });
208
-
209
- const searchInput = screen.getByPlaceholderText('Search...');
210
- fireEvent.change(searchInput, { target: { value: '' } });
211
-
212
- await waitFor(
213
- () => {
214
- expect(state.get('$search.test.model')).toBeNull();
215
- },
216
- { timeout: 500 },
217
- );
218
- });
219
- });
220
-
221
- describe('API integration', () => {
222
- it('sends search param in API call', async () => {
223
- mockApiClient.mockResolvedValue({
224
- ok: true,
225
- json: () => Promise.resolve({ data: sampleData, meta: { total: 2 } }),
226
- } as unknown as Response);
227
-
228
- const state = new StateStore();
229
- renderTable({ state });
230
-
231
- await waitFor(() => {
232
- expect(screen.getByText('Acme Corp')).toBeInTheDocument();
233
- });
234
-
235
- const searchInput = screen.getByPlaceholderText('Search...');
236
- fireEvent.change(searchInput, { target: { value: 'Acme' } });
237
-
238
- await waitFor(
239
- () => {
240
- const calls = mockApiClient.mock.calls.map((c) => c[0] as string);
241
- expect(calls.some((url) => url.includes('search=Acme'))).toBe(true);
242
- },
243
- { timeout: 1000 },
244
- );
245
- });
246
-
247
- it('does not send search param when empty', async () => {
248
- mockApiResponse(sampleData);
249
- renderTable();
250
-
251
- await waitFor(() => {
252
- expect(screen.getByText('Acme Corp')).toBeInTheDocument();
253
- });
254
-
255
- const firstCall = mockApiClient.mock.calls[0][0] as string;
256
- expect(firstCall).not.toContain('search');
257
- });
258
- });
259
-
260
- describe('clear button', () => {
261
- it('shows clear button when search has value', async () => {
262
- mockApiResponse(sampleData);
263
- renderTable();
264
-
265
- await waitFor(() => {
266
- expect(screen.getByText('Acme Corp')).toBeInTheDocument();
267
- });
268
-
269
- const searchInput = screen.getByPlaceholderText('Search...');
270
- fireEvent.change(searchInput, { target: { value: 'test' } });
271
-
272
- expect(screen.getByLabelText('Clear search')).toBeInTheDocument();
273
- });
274
-
275
- it('clears input and store on clear button click', async () => {
276
- mockApiResponse(sampleData);
277
- const state = new StateStore();
278
- renderTable({ state });
279
-
280
- await waitFor(() => {
281
- expect(screen.getByText('Acme Corp')).toBeInTheDocument();
282
- });
283
-
284
- const searchInput = screen.getByPlaceholderText('Search...') as HTMLInputElement;
285
- fireEvent.change(searchInput, { target: { value: 'test' } });
286
-
287
- await waitFor(
288
- () => {
289
- expect(state.get('$search.test.model')).toBe('test');
290
- },
291
- { timeout: 500 },
292
- );
293
-
294
- fireEvent.click(screen.getByLabelText('Clear search'));
295
-
296
- await waitFor(
297
- () => {
298
- expect(searchInput.value).toBe('');
299
- expect(state.get('$search.test.model')).toBeNull();
300
- },
301
- { timeout: 500 },
302
- );
303
- });
304
- });
305
- });