@onehat/ui 0.3.380 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (440) hide show
  1. package/package.json +37 -9
  2. package/src/Components/Accordion/Accordion.js +22 -17
  3. package/src/Components/Blank.js +1 -3
  4. package/src/Components/Buttons/BackButton.js +21 -12
  5. package/src/Components/Buttons/Button.js +65 -13
  6. package/src/Components/Buttons/CartButtonWithBadge.js +14 -6
  7. package/src/Components/Buttons/IconButton.js +31 -74
  8. package/src/Components/Buttons/PlusMinusButton.js +34 -21
  9. package/src/Components/Buttons/ReloadButton.js +7 -8
  10. package/src/Components/Buttons/SquareButton.js +41 -55
  11. package/src/Components/Container/Container.js +55 -16
  12. package/src/Components/Container/ScreenContainer.js +26 -16
  13. package/src/Components/Container/Splitter.js +38 -25
  14. package/src/Components/Editor/Editor.js +3 -2
  15. package/src/Components/Editor/InlineEditor.js +38 -32
  16. package/src/Components/Filter/DateRange.js +37 -18
  17. package/src/Components/Filter/NumberRange.js +87 -83
  18. package/src/Components/Form/Field/CKEditor/CKEditor.js +4 -4
  19. package/src/Components/Form/Field/Checkbox/CheckboxGroup.js +9 -6
  20. package/src/Components/Form/Field/Color.js +95 -86
  21. package/src/Components/Form/Field/Combo/Combo.js +347 -284
  22. package/src/Components/Form/Field/Combo/PageSizeCombo.js +4 -7
  23. package/src/Components/Form/Field/Date.js +276 -312
  24. package/src/Components/Form/Field/DisplayField.js +11 -5
  25. package/src/Components/Form/Field/File.js +26 -32
  26. package/src/Components/Form/Field/FormikForm.js +1018 -0
  27. package/src/Components/Form/Field/Input.js +91 -41
  28. package/src/Components/Form/Field/Json.js +25 -21
  29. package/src/Components/Form/Field/Number.js +70 -51
  30. package/src/Components/Form/Field/RadioGroup/RadioGroup.js +4 -6
  31. package/src/Components/Form/Field/Select/PageSizeSelect.js +33 -0
  32. package/src/Components/Form/Field/Select/Select.js +109 -0
  33. package/src/Components/Form/Field/Slider.js +38 -30
  34. package/src/Components/Form/Field/Tag/Tag.js +88 -72
  35. package/src/Components/Form/Field/Tag/ValueBox.js +25 -20
  36. package/src/Components/Form/Field/Text.js +21 -12
  37. package/src/Components/Form/Field/TextArea.js +32 -15
  38. package/src/Components/Form/Field/Toggle.js +42 -24
  39. package/src/Components/Form/FieldSet.js +77 -54
  40. package/src/Components/Form/Form.js +491 -268
  41. package/src/Components/Form/Label.js +28 -17
  42. package/src/Components/Gluestack/accordion/index.tsx +394 -0
  43. package/src/Components/Gluestack/actionsheet/index.tsx +619 -0
  44. package/src/Components/Gluestack/alert/index.tsx +310 -0
  45. package/src/Components/Gluestack/alert-dialog/index.tsx +295 -0
  46. package/src/Components/Gluestack/avatar/index.tsx +190 -0
  47. package/src/Components/Gluestack/badge/index.tsx +272 -0
  48. package/src/Components/Gluestack/bottomsheet/index.tsx +294 -0
  49. package/src/Components/Gluestack/box/index.tsx +19 -0
  50. package/src/Components/Gluestack/box/index.web.tsx +18 -0
  51. package/src/Components/Gluestack/box/styles.tsx +10 -0
  52. package/src/Components/Gluestack/button/index.tsx +494 -0
  53. package/src/Components/Gluestack/card/index.tsx +23 -0
  54. package/src/Components/Gluestack/card/index.web.tsx +22 -0
  55. package/src/Components/Gluestack/card/styles.tsx +20 -0
  56. package/src/Components/Gluestack/center/index.tsx +22 -0
  57. package/src/Components/Gluestack/center/index.web.tsx +19 -0
  58. package/src/Components/Gluestack/center/styles.tsx +8 -0
  59. package/src/Components/Gluestack/checkbox/index.tsx +305 -0
  60. package/src/Components/Gluestack/divider/index.tsx +44 -0
  61. package/src/Components/Gluestack/drawer/index.tsx +354 -0
  62. package/src/Components/Gluestack/fab/index.tsx +286 -0
  63. package/src/Components/Gluestack/flat-list/index.tsx +2 -0
  64. package/src/Components/Gluestack/form-control/index.tsx +527 -0
  65. package/src/Components/Gluestack/gluestack-ui-provider/config.ts +332 -0
  66. package/src/Components/Gluestack/gluestack-ui-provider/index.tsx +47 -0
  67. package/src/Components/Gluestack/gluestack-ui-provider/index.web.tsx +94 -0
  68. package/src/Components/Gluestack/gluestack-ui-provider/script.ts +19 -0
  69. package/src/Components/Gluestack/grid/index.tsx +341 -0
  70. package/src/Components/Gluestack/grid/index.web.tsx +65 -0
  71. package/src/Components/Gluestack/grid/styles.tsx +15 -0
  72. package/src/Components/Gluestack/heading/index.tsx +212 -0
  73. package/src/Components/Gluestack/heading/index.web.tsx +203 -0
  74. package/src/Components/Gluestack/heading/styles.tsx +43 -0
  75. package/src/Components/Gluestack/hstack/index.tsx +23 -0
  76. package/src/Components/Gluestack/hstack/index.web.tsx +22 -0
  77. package/src/Components/Gluestack/hstack/styles.tsx +25 -0
  78. package/src/Components/Gluestack/image/index.tsx +52 -0
  79. package/src/Components/Gluestack/image-background/index.tsx +21 -0
  80. package/src/Components/Gluestack/index.js +116 -0
  81. package/src/Components/Gluestack/input/index.tsx +287 -0
  82. package/src/Components/Gluestack/input-accessory-view/index.tsx +2 -0
  83. package/src/Components/Gluestack/keyboard-avoiding-view/index.tsx +2 -0
  84. package/src/Components/Gluestack/link/index.tsx +107 -0
  85. package/src/Components/Gluestack/menu/index.tsx +210 -0
  86. package/src/Components/Gluestack/modal/index.tsx +279 -0
  87. package/src/Components/Gluestack/popover/index.tsx +352 -0
  88. package/src/Components/Gluestack/portal/index.tsx +13 -0
  89. package/src/Components/Gluestack/pressable/index.tsx +46 -0
  90. package/src/Components/Gluestack/progress/index.tsx +164 -0
  91. package/src/Components/Gluestack/radio/index.tsx +304 -0
  92. package/src/Components/Gluestack/refresh-control/index.tsx +2 -0
  93. package/src/Components/Gluestack/safe-area-view/index.tsx +2 -0
  94. package/src/Components/Gluestack/scroll-view/index.tsx +2 -0
  95. package/src/Components/Gluestack/section-list/index.tsx +2 -0
  96. package/src/Components/Gluestack/select/index.tsx +335 -0
  97. package/src/Components/Gluestack/select/select-actionsheet.tsx +584 -0
  98. package/src/Components/Gluestack/skeleton/index.tsx +138 -0
  99. package/src/Components/Gluestack/skeleton/index.web.tsx +103 -0
  100. package/src/Components/Gluestack/skeleton/styles.tsx +35 -0
  101. package/src/Components/Gluestack/slider/index.tsx +283 -0
  102. package/src/Components/Gluestack/spinner/index.tsx +34 -0
  103. package/src/Components/Gluestack/status-bar/index.tsx +2 -0
  104. package/src/Components/Gluestack/switch/index.tsx +55 -0
  105. package/src/Components/Gluestack/table/index.tsx +200 -0
  106. package/src/Components/Gluestack/table/index.web.tsx +142 -0
  107. package/src/Components/Gluestack/table/styles.tsx +44 -0
  108. package/src/Components/Gluestack/text/index.tsx +48 -0
  109. package/src/Components/Gluestack/text/index.web.tsx +45 -0
  110. package/src/Components/Gluestack/text/styles.tsx +47 -0
  111. package/src/Components/Gluestack/textarea/index.tsx +108 -0
  112. package/src/Components/Gluestack/toast/index.tsx +225 -0
  113. package/src/Components/Gluestack/tooltip/index.tsx +125 -0
  114. package/src/Components/Gluestack/utils/use-break-point-value.ts +101 -0
  115. package/src/Components/Gluestack/view/index.tsx +2 -0
  116. package/src/Components/Gluestack/virtualized-list/index.tsx +2 -0
  117. package/src/Components/Gluestack/vstack/index.tsx +24 -0
  118. package/src/Components/Gluestack/vstack/index.web.tsx +23 -0
  119. package/src/Components/Gluestack/vstack/styles.tsx +25 -0
  120. package/src/Components/Grid/Grid.js +192 -135
  121. package/src/Components/Grid/GridHeaderRow.js +51 -59
  122. package/src/Components/Grid/GridRow.js +152 -58
  123. package/src/Components/Grid/HeaderColumnSelectorHandle.js +16 -10
  124. package/src/Components/Grid/HeaderReorderHandle.js +17 -13
  125. package/src/Components/Grid/HeaderResizeHandle.js +17 -13
  126. package/src/Components/Grid/NoRecordsFound.js +15 -18
  127. package/src/Components/Grid/RowDragHandle.js +9 -13
  128. package/src/Components/Hoc/Secondary/withSecondaryEditor.js +14 -9
  129. package/src/Components/Hoc/Secondary/withSecondaryWindowedEditor.js +14 -11
  130. package/src/Components/Hoc/withAlert.js +150 -200
  131. package/src/Components/Hoc/withBlank.js +4 -6
  132. package/src/Components/Hoc/withCollapsible.js +4 -3
  133. package/src/Components/Hoc/withComponent.js +33 -6
  134. package/src/Components/Hoc/withContextMenu.js +133 -141
  135. package/src/Components/Hoc/withData.js +5 -4
  136. package/src/Components/Hoc/withDnd.js +11 -9
  137. package/src/Components/Hoc/withDraggable.js +10 -10
  138. package/src/Components/Hoc/withEditor.js +18 -13
  139. package/src/Components/Hoc/withEvents.js +4 -6
  140. package/src/Components/Hoc/withFilters.js +524 -498
  141. package/src/Components/Hoc/withInlineEditor.js +7 -5
  142. package/src/Components/Hoc/withModal.js +79 -137
  143. package/src/Components/Hoc/withMultiSelection.js +4 -2
  144. package/src/Components/Hoc/withPdfButtons.js +109 -111
  145. package/src/Components/Hoc/withPresetButtons.js +49 -53
  146. package/src/Components/Hoc/withSelection.js +6 -5
  147. package/src/Components/Hoc/withSideEditor.js +12 -6
  148. package/src/Components/Hoc/withTooltip.js +18 -12
  149. package/src/Components/Hoc/withValue.js +6 -5
  150. package/src/Components/Hoc/withWindowedEditor.js +13 -11
  151. package/src/Components/Icons/AddressBook.js +7 -10
  152. package/src/Components/Icons/Alt.js +8 -15
  153. package/src/Components/Icons/AngleLeft.js +7 -14
  154. package/src/Components/Icons/AngleRight.js +7 -14
  155. package/src/Components/Icons/AnglesLeft.js +7 -14
  156. package/src/Components/Icons/AnglesRight.js +7 -14
  157. package/src/Components/Icons/Asterisk.js +7 -10
  158. package/src/Components/Icons/Ban.js +9 -14
  159. package/src/Components/Icons/Bars.js +7 -10
  160. package/src/Components/Icons/BarsStaggered.js +7 -10
  161. package/src/Components/Icons/Bell.js +7 -19
  162. package/src/Components/Icons/BigCircle.js +7 -14
  163. package/src/Components/Icons/Book.js +7 -10
  164. package/src/Components/Icons/BookOpen.js +7 -10
  165. package/src/Components/Icons/Bookmark.js +8 -17
  166. package/src/Components/Icons/Bug.js +7 -10
  167. package/src/Components/Icons/Building.js +7 -10
  168. package/src/Components/Icons/Calendar.js +7 -14
  169. package/src/Components/Icons/Calendar2.js +7 -14
  170. package/src/Components/Icons/CalendarDays.js +7 -14
  171. package/src/Components/Icons/Camera.js +7 -14
  172. package/src/Components/Icons/CaretDown.js +7 -14
  173. package/src/Components/Icons/CaretUp.js +7 -14
  174. package/src/Components/Icons/CartPlus.js +7 -10
  175. package/src/Components/Icons/CartShopping.js +7 -10
  176. package/src/Components/Icons/CashRegister.js +7 -10
  177. package/src/Components/Icons/Certificate.js +7 -10
  178. package/src/Components/Icons/ChartLine.js +7 -10
  179. package/src/Components/Icons/ChartPie.js +7 -10
  180. package/src/Components/Icons/Check.js +7 -10
  181. package/src/Components/Icons/CheckDouble.js +7 -10
  182. package/src/Components/Icons/ChevronDown.js +7 -10
  183. package/src/Components/Icons/ChevronLeft.js +7 -10
  184. package/src/Components/Icons/ChevronRight.js +7 -10
  185. package/src/Components/Icons/ChevronUp.js +7 -10
  186. package/src/Components/Icons/Circle.js +7 -10
  187. package/src/Components/Icons/CircleArrowRight.js +7 -10
  188. package/src/Components/Icons/CircleExclamation.js +7 -14
  189. package/src/Components/Icons/CircleInfo.js +7 -10
  190. package/src/Components/Icons/CircleQuestion.js +7 -10
  191. package/src/Components/Icons/CircleXmark.js +7 -10
  192. package/src/Components/Icons/CircleXmarkRegular.js +7 -10
  193. package/src/Components/Icons/Clipboard.js +7 -14
  194. package/src/Components/Icons/ClipboardCheck.js +7 -17
  195. package/src/Components/Icons/ClipboardList.js +7 -16
  196. package/src/Components/Icons/Clock.js +7 -10
  197. package/src/Components/Icons/ClockRegular.js +7 -10
  198. package/src/Components/Icons/ClockRotateLeft.js +7 -10
  199. package/src/Components/Icons/Clone.js +7 -10
  200. package/src/Components/Icons/Collapse.js +7 -14
  201. package/src/Components/Icons/Comment.js +7 -10
  202. package/src/Components/Icons/CommentDots.js +7 -10
  203. package/src/Components/Icons/CommentRegular.js +7 -10
  204. package/src/Components/Icons/Comments.js +7 -10
  205. package/src/Components/Icons/CommentsRegular.js +7 -10
  206. package/src/Components/Icons/Copyright.js +7 -10
  207. package/src/Components/Icons/Dot.js +10 -15
  208. package/src/Components/Icons/Download.js +11 -0
  209. package/src/Components/Icons/Duplicate.js +7 -14
  210. package/src/Components/Icons/Edit.js +7 -14
  211. package/src/Components/Icons/EllipsisHorizontal.js +7 -16
  212. package/src/Components/Icons/EllipsisVertical.js +7 -14
  213. package/src/Components/Icons/Envelope.js +7 -10
  214. package/src/Components/Icons/EnvelopeRegular.js +7 -10
  215. package/src/Components/Icons/Excel.js +7 -10
  216. package/src/Components/Icons/Exclamation.js +7 -10
  217. package/src/Components/Icons/Expand.js +7 -10
  218. package/src/Components/Icons/Eye.js +7 -14
  219. package/src/Components/Icons/EyeSlash.js +7 -10
  220. package/src/Components/Icons/File.js +7 -14
  221. package/src/Components/Icons/FloppyDiskRegular.js +7 -10
  222. package/src/Components/Icons/Folder.js +7 -10
  223. package/src/Components/Icons/FolderClosed.js +7 -10
  224. package/src/Components/Icons/FolderOpen.js +7 -10
  225. package/src/Components/Icons/FolderTree.js +7 -10
  226. package/src/Components/Icons/FullWidth.js +10 -25
  227. package/src/Components/Icons/Gauge.js +7 -17
  228. package/src/Components/Icons/Gear.js +7 -14
  229. package/src/Components/Icons/Gears.js +7 -10
  230. package/src/Components/Icons/Gift.js +7 -10
  231. package/src/Components/Icons/Grip.js +7 -14
  232. package/src/Components/Icons/GripLines.js +7 -14
  233. package/src/Components/Icons/GripLinesVertical.js +7 -14
  234. package/src/Components/Icons/GripVertical.js +7 -14
  235. package/src/Components/Icons/Hammer.js +7 -10
  236. package/src/Components/Icons/Hand.js +7 -10
  237. package/src/Components/Icons/HighPriority.js +7 -17
  238. package/src/Components/Icons/House.js +7 -10
  239. package/src/Components/Icons/Images.js +7 -10
  240. package/src/Components/Icons/Info.js +7 -10
  241. package/src/Components/Icons/ItunesNote.js +7 -10
  242. package/src/Components/Icons/Js.js +7 -16
  243. package/src/Components/Icons/Leaf.js +7 -10
  244. package/src/Components/Icons/Link.js +7 -9
  245. package/src/Components/Icons/List.js +7 -10
  246. package/src/Components/Icons/ListCheck.js +7 -10
  247. package/src/Components/Icons/LocationDot.js +7 -10
  248. package/src/Components/Icons/Loop.js +7 -14
  249. package/src/Components/Icons/Loop1.js +8 -13
  250. package/src/Components/Icons/LoopAll.js +8 -13
  251. package/src/Components/Icons/LowPriority.js +7 -17
  252. package/src/Components/Icons/MagnifyingGlass.js +7 -10
  253. package/src/Components/Icons/Maximize.js +7 -10
  254. package/src/Components/Icons/MedPriority.js +7 -17
  255. package/src/Components/Icons/Microphone.js +7 -10
  256. package/src/Components/Icons/Minimize.js +7 -10
  257. package/src/Components/Icons/Minus.js +7 -14
  258. package/src/Components/Icons/MobileScreenButton.js +7 -10
  259. package/src/Components/Icons/MoneyBill.js +7 -10
  260. package/src/Components/Icons/MoneyBillWave.js +7 -10
  261. package/src/Components/Icons/Mouth.js +10 -21
  262. package/src/Components/Icons/Music.js +7 -10
  263. package/src/Components/Icons/Na.js +7 -14
  264. package/src/Components/Icons/NoLoop.js +11 -13
  265. package/src/Components/Icons/NoReorderRows.js +17 -22
  266. package/src/Components/Icons/ObjectGroupRegular.js +7 -10
  267. package/src/Components/Icons/Pause.js +7 -10
  268. package/src/Components/Icons/Pdf.js +7 -10
  269. package/src/Components/Icons/Pencil.js +7 -14
  270. package/src/Components/Icons/Phone.js +7 -10
  271. package/src/Components/Icons/Play.js +7 -10
  272. package/src/Components/Icons/Plus.js +7 -14
  273. package/src/Components/Icons/Presentation.js +7 -16
  274. package/src/Components/Icons/Print.js +7 -14
  275. package/src/Components/Icons/Question.js +7 -10
  276. package/src/Components/Icons/Rate-.25x.js +12 -17
  277. package/src/Components/Icons/Rate-.5x.js +11 -16
  278. package/src/Components/Icons/Rate-.75x.js +8 -13
  279. package/src/Components/Icons/Rate-1.25x.js +8 -13
  280. package/src/Components/Icons/Rate-1.5x.js +8 -13
  281. package/src/Components/Icons/Rate-1.75x.js +8 -13
  282. package/src/Components/Icons/Rate-1x.js +11 -16
  283. package/src/Components/Icons/Rate-2x.js +8 -13
  284. package/src/Components/Icons/RateIcon-.25x.js +8 -13
  285. package/src/Components/Icons/RateIcon-.5x.js +11 -16
  286. package/src/Components/Icons/RateIcon-.75x.js +8 -13
  287. package/src/Components/Icons/RateIcon-1.25x.js +8 -13
  288. package/src/Components/Icons/RateIcon-1.5x.js +8 -13
  289. package/src/Components/Icons/RateIcon-1.75x.js +8 -13
  290. package/src/Components/Icons/RateIcon-1x.js +8 -13
  291. package/src/Components/Icons/RateIcon-2x.js +8 -13
  292. package/src/Components/Icons/RectangleXmark.js +7 -10
  293. package/src/Components/Icons/RectangleXmarkRegular.js +7 -10
  294. package/src/Components/Icons/ReorderRows.js +8 -13
  295. package/src/Components/Icons/RightFromBracket.js +7 -10
  296. package/src/Components/Icons/RightLeft.js +7 -10
  297. package/src/Components/Icons/RightToBracket.js +7 -10
  298. package/src/Components/Icons/Rotate.js +7 -14
  299. package/src/Components/Icons/RotateLeft.js +7 -10
  300. package/src/Components/Icons/RotateRight.js +7 -14
  301. package/src/Components/Icons/ScrewdriverWrench.js +7 -10
  302. package/src/Components/Icons/Scroll.js +7 -10
  303. package/src/Components/Icons/Share.js +7 -10
  304. package/src/Components/Icons/Shop.js +7 -10
  305. package/src/Components/Icons/SideBySide.js +7 -20
  306. package/src/Components/Icons/SortDown.js +7 -10
  307. package/src/Components/Icons/SortDownAlt.js +7 -10
  308. package/src/Components/Icons/SortUp.js +7 -10
  309. package/src/Components/Icons/SortUpAlt.js +7 -14
  310. package/src/Components/Icons/Square.js +7 -10
  311. package/src/Components/Icons/SquareCheck.js +7 -10
  312. package/src/Components/Icons/SquareCheckRegular.js +7 -10
  313. package/src/Components/Icons/SquareMinus.js +7 -14
  314. package/src/Components/Icons/SquareRegular.js +7 -10
  315. package/src/Components/Icons/Store.js +7 -10
  316. package/src/Components/Icons/Table.js +7 -16
  317. package/src/Components/Icons/ThumbsDown.js +7 -10
  318. package/src/Components/Icons/ThumbsDownRegular.js +7 -10
  319. package/src/Components/Icons/ThumbsUp.js +7 -10
  320. package/src/Components/Icons/ThumbsUpRegular.js +7 -10
  321. package/src/Components/Icons/Trash.js +7 -14
  322. package/src/Components/Icons/TrashCan.js +7 -14
  323. package/src/Components/Icons/TriangleExclamation.js +7 -14
  324. package/src/Components/Icons/Truck.js +7 -10
  325. package/src/Components/Icons/TruckFast.js +7 -10
  326. package/src/Components/Icons/Upload.js +11 -0
  327. package/src/Components/Icons/UploadDownload.js +11 -11
  328. package/src/Components/Icons/User.js +7 -10
  329. package/src/Components/Icons/UserGroup.js +7 -10
  330. package/src/Components/Icons/UserPlus.js +7 -10
  331. package/src/Components/Icons/UserSecret.js +7 -10
  332. package/src/Components/Icons/Video.js +7 -16
  333. package/src/Components/Icons/X.js +7 -10
  334. package/src/Components/Icons/Xmark.js +7 -10
  335. package/src/Components/Layout/CenterBox.js +13 -9
  336. package/src/Components/Layout/Footer.js +20 -13
  337. package/src/Components/Messages/ConfirmationMessage.js +30 -13
  338. package/src/Components/Messages/ErrorMessage.js +29 -23
  339. package/src/Components/Messages/Loading.js +10 -8
  340. package/src/Components/Messages/OkMessage.js +30 -13
  341. package/src/Components/Messages/Unauthorized.js +5 -8
  342. package/src/Components/Messages/WaitMessage.js +37 -73
  343. package/src/Components/Panel/AccordionGridPanel.js +6 -6
  344. package/src/Components/Panel/FormPanel.js +7 -3
  345. package/src/Components/Panel/Header.js +132 -94
  346. package/src/Components/Panel/Mask.js +4 -4
  347. package/src/Components/Panel/Panel.js +55 -72
  348. package/src/Components/Panel/TabPanel.js +1 -1
  349. package/src/Components/Picker/Picker.js +10 -9
  350. package/src/Components/Report/Report.js +17 -14
  351. package/src/Components/Screens/Manager.js +22 -22
  352. package/src/Components/Tab/TabBar.js +293 -225
  353. package/src/Components/Toolbar/FilterToolbar.js +15 -11
  354. package/src/Components/Toolbar/Pagination.js +51 -46
  355. package/src/Components/Toolbar/PaginationToolbar.js +25 -19
  356. package/src/Components/Toolbar/Toolbar.js +26 -13
  357. package/src/Components/Tooltip/Tooltip.js +35 -0
  358. package/src/Components/Tree/Tree.js +144 -147
  359. package/src/Components/Tree/TreeNode.js +75 -36
  360. package/src/Components/Viewer/Viewer.js +203 -80
  361. package/src/Components/Window/Editor.js +0 -5
  362. package/src/Components/Window/UploadsDownloadsWindow.js +40 -22
  363. package/src/Components/index.js +11 -8
  364. package/src/Constants/Alert.js +0 -0
  365. package/src/Constants/AppStates.js +0 -0
  366. package/src/Constants/Colors.js +13 -0
  367. package/src/Constants/Commands.js +0 -0
  368. package/src/Constants/Date.js +0 -0
  369. package/src/Constants/Dates.js +16 -0
  370. package/src/Constants/Directions.js +0 -0
  371. package/src/Constants/Editor.js +0 -0
  372. package/src/Constants/EditorModes.js +2 -0
  373. package/src/Constants/File.js +0 -0
  374. package/src/Constants/Filters.js +0 -0
  375. package/src/Constants/Grid.js +0 -0
  376. package/src/Constants/Input.js +1 -0
  377. package/src/Constants/MimeTypes.js +0 -0
  378. package/src/Constants/Selection.js +0 -0
  379. package/src/Constants/Styles.js +119 -108
  380. package/src/Constants/Tasks.js +3 -0
  381. package/src/Constants/Tree.js +0 -0
  382. package/src/Constants/UiModes.js +4 -3
  383. package/src/Functions/BankersRound.js +0 -0
  384. package/src/Functions/Cypress/button_functions.js +0 -0
  385. package/src/Functions/Cypress/crud_functions.js +0 -0
  386. package/src/Functions/Cypress/dom_functions.js +0 -0
  387. package/src/Functions/Cypress/grid_functions.js +0 -0
  388. package/src/Functions/Cypress/navigation_functions.js +0 -0
  389. package/src/Functions/Cypress/tree_functions.js +0 -0
  390. package/src/Functions/Cypress/utilities.js +0 -0
  391. package/src/Functions/PlatformDetector.js +0 -0
  392. package/src/Functions/Timer.js +0 -0
  393. package/src/Functions/buildAdditionalButtons.js +5 -5
  394. package/src/Functions/chunkArray.js +0 -0
  395. package/src/Functions/colorConversions.js +74 -0
  396. package/src/Functions/delay.js +0 -0
  397. package/src/Functions/delayUntil.js +0 -0
  398. package/src/Functions/deleteSaved.js +0 -0
  399. package/src/Functions/deleteSecure.js +0 -0
  400. package/src/Functions/downloadInBackground.js +0 -0
  401. package/src/Functions/downloadWithFetch.js +0 -0
  402. package/src/Functions/emptyFn.js +0 -0
  403. package/src/Functions/getComponentFromType.js +0 -0
  404. package/src/Functions/getIconButtonFromConfig.js +5 -9
  405. package/src/Functions/getIsMobile.js +0 -0
  406. package/src/Functions/getNodeIcon.js +28 -0
  407. package/src/Functions/getPref.js +0 -0
  408. package/src/Functions/getSaved.js +0 -0
  409. package/src/Functions/getSecure.js +0 -0
  410. package/src/Functions/getTokenHeaders.js +0 -0
  411. package/src/Functions/gsToHex.js +205 -0
  412. package/src/Functions/ignoreWanings.js +46 -0
  413. package/src/Functions/inArray.js +0 -0
  414. package/src/Functions/isJson.js +0 -0
  415. package/src/Functions/isSerializable.js +0 -0
  416. package/src/Functions/isVideo.js +0 -0
  417. package/src/Functions/jsonValidator.js +0 -0
  418. package/src/Functions/nbToRgb.js +1 -1
  419. package/src/Functions/objectToClassName.js +72 -0
  420. package/src/Functions/parseNotification.js +0 -0
  421. package/src/Functions/processImage.js +0 -0
  422. package/src/Functions/registerReactNativeComponents.js +0 -0
  423. package/src/Functions/registerWebComponents.js +0 -0
  424. package/src/Functions/setCustomInflector.js +0 -0
  425. package/src/Functions/setPref.js +0 -0
  426. package/src/Functions/setProgress.js +0 -0
  427. package/src/Functions/setSaved.js +0 -0
  428. package/src/Functions/setSecure.js +0 -0
  429. package/src/Functions/setThemeOverrides.js +0 -0
  430. package/src/Functions/setUiSavesRepo.js +0 -0
  431. package/src/Functions/sleep.js +0 -0
  432. package/src/Functions/tailwindFunctions.js +384 -0
  433. package/src/Functions/testProps.js +0 -0
  434. package/src/Functions/trackEngagementHit.js +0 -0
  435. package/src/Functions/verifyCompleted.js +0 -0
  436. package/src/Functions/waitFor.js +2 -2
  437. package/src/PlatformImports/Web/Attachments.js +32 -38
  438. package/src/PlatformImports/Web/File.js +38 -31
  439. package/src/UiGlobals.js +8 -1
  440. package/src/Components/Grid/ColumnSelectorWindow.js +0 -125
@@ -1,12 +1,12 @@
1
- import { useState, useEffect, useRef, } from 'react';
1
+ import { forwardRef, useState, useEffect, useRef, } from 'react';
2
2
  import {
3
- Box,
4
- Column,
5
- Modal,
6
- Row,
7
- ScrollView,
3
+ HStack,
4
+ // ScrollView,
8
5
  Text,
9
- } from 'native-base';
6
+ } from '../Gluestack';
7
+ import {
8
+ ScrollView,
9
+ } from 'react-native'
10
10
  import {
11
11
  EDITOR_TYPE__PLAIN,
12
12
  } from '../../Constants/Editor.js';
@@ -14,11 +14,12 @@ import {
14
14
  FILTER_TYPE_ANCILLARY
15
15
  } from '../../Constants/Filters.js';
16
16
  import Inflector from 'inflector-js';
17
- import inArray from '../../Functions/inArray.js';
18
17
  import testProps from '../../Functions/testProps.js';
18
+ import inArray from '../../Functions/inArray.js';
19
19
  import getComponentFromType from '../../Functions/getComponentFromType.js';
20
20
  import IconButton from '../Buttons/IconButton.js';
21
- import FormPanel from '../Panel/FormPanel.js';
21
+ import Form from '../Form/Form.js';
22
+ import Label from '../Form/Label.js';
22
23
  import Ban from '../Icons/Ban.js';
23
24
  import Gear from '../Icons/Gear.js';
24
25
  import Toolbar from '../Toolbar/Toolbar.js';
@@ -35,13 +36,19 @@ import _ from 'lodash';
35
36
  // Model defaultFilters should adjust to this new arrangement
36
37
 
37
38
  export default function withFilters(WrappedComponent) {
38
- return (props) => {
39
+ return forwardRef((props, ref) => {
40
+
41
+ if (!props.useFilters) {
42
+ return <WrappedComponent {...props} ref={ref} />;
43
+ }
44
+
45
+ if (!props.Repository) {
46
+ throw Error('withFilters requires a Repository if useFilters === true');
47
+ }
48
+
39
49
  const {
40
50
  // config
41
- useFilters = false,
42
51
  searchAllText = true,
43
- showLabels = true,
44
- showFilterSelector = true,
45
52
  showClearFiltersButton = true,
46
53
  defaultFilters = [], // likely a list of field names, possibly could be of shape below
47
54
  customFilters = [], // of shape: { title, type, field, value, getRepoFilters(value) }
@@ -55,446 +62,294 @@ export default function withFilters(WrappedComponent) {
55
62
 
56
63
  // withComponent
57
64
  self,
58
- } = props;
59
65
 
60
- let modal = null,
61
- topToolbar = null;
62
-
63
- if (useFilters && Repository) {
64
-
65
- const
66
- // aliases
67
- {
68
- defaultFilters: modelDefaultFilters,
69
- ancillaryFilters: modelAncillaryFilters,
70
- } = Repository.getSchema().model,
71
- id = props.id || props.self?.path,
72
-
73
- // determine the starting filters
74
- startingFilters = !_.isEmpty(customFilters) ? customFilters : // custom filters override component filters
75
- !_.isEmpty(defaultFilters) ? defaultFilters : // component filters override model filters
76
- !_.isEmpty(modelDefaultFilters) ? modelDefaultFilters : [],
77
- isUsingCustomFilters = startingFilters === customFilters,
78
- modelFilterTypes = Repository.getSchema().getFilterTypes(),
79
- [isReady, setIsReady] = useState(false),
80
- [isFilterSelectorShown, setIsFilterSelectorShown] = useState(false),
81
- getFormattedFilter = (filter) => {
82
- let formatted = null;
83
- if (_.isString(filter)) {
84
- const
85
- field = filter,
86
- propertyDef = Repository.getSchema().getPropertyDefinition(field);
87
-
88
- let title, type;
89
- if (propertyDef) {
90
- title = propertyDef.title;
91
- type = propertyDef.filterType;
92
- } else if (modelAncillaryFilters[field]) {
93
- const ancillaryFilter = modelFilterTypes[field];
94
- title = ancillaryFilter.title;
95
- type = FILTER_TYPE_ANCILLARY;
96
- } else {
97
- throw Error('not a propertyDef, and not an ancillaryFilter!');
98
- }
99
- formatted = {
100
- field,
101
- title,
102
- type,
103
- value: null, // value starts as null
104
- };
105
- } else if (_.isPlainObject(filter)) {
106
- // already formatted
107
- formatted = filter;
108
- }
109
- return formatted;
110
- };
111
-
112
- let formattedStartingFilters = [],
113
- startingSlots = [];
114
- if (!isReady) {
115
- // Generate initial starting state
116
- if (searchAllText) {
117
- formattedStartingFilters.push({ field: 'q', title: 'Search all text fields', type: 'Input', value: null, });
118
- }
119
- _.each(startingFilters, (filter) => {
66
+ // withModal
67
+ showModal,
68
+ hideModal,
69
+ updateModalBody,
70
+
71
+ } = props,
72
+
73
+ // aliases
74
+ {
75
+ defaultFilters: modelDefaultFilters,
76
+ ancillaryFilters: modelAncillaryFilters,
77
+ } = Repository.getSchema().model,
78
+ id = props.id || props.self?.path,
79
+
80
+ // determine the starting filters
81
+ startingFilters = !_.isEmpty(customFilters) ? customFilters : // custom filters override component filters
82
+ !_.isEmpty(defaultFilters) ? defaultFilters : // component filters override model filters
83
+ !_.isEmpty(modelDefaultFilters) ? modelDefaultFilters : [],
84
+ isUsingCustomFilters = startingFilters === customFilters,
85
+ modelFilterTypes = Repository.getSchema().getFilterTypes(),
86
+ [isReady, setIsReady] = useState(false),
87
+ getFormattedFilter = (filter) => {
88
+ let formatted = null;
89
+ if (_.isString(filter)) {
120
90
  const
121
- formattedFilter = getFormattedFilter(filter),
122
- field = formattedFilter.field;
123
- formattedStartingFilters.push(formattedFilter);
124
- if (!isUsingCustomFilters) {
125
- startingSlots.push(field);
126
- }
127
- });
128
- if (startingSlots.length < minFilters) {
129
- for (let i = startingSlots.length; i < minFilters; i++) {
130
- startingSlots.push(null);
91
+ field = filter,
92
+ propertyDef = Repository.getSchema().getPropertyDefinition(field);
93
+
94
+ let title, type;
95
+ if (propertyDef) {
96
+ title = propertyDef.title;
97
+ type = propertyDef.filterType;
98
+ } else if (modelAncillaryFilters[field]) {
99
+ const ancillaryFilter = modelFilterTypes[field];
100
+ title = ancillaryFilter.title;
101
+ type = FILTER_TYPE_ANCILLARY;
102
+ } else {
103
+ throw Error('not a propertyDef, and not an ancillaryFilter!');
131
104
  }
105
+ formatted = {
106
+ field,
107
+ title,
108
+ type,
109
+ value: null, // value starts as null
110
+ };
111
+ } else if (_.isPlainObject(filter)) {
112
+ // already formatted
113
+ formatted = filter;
132
114
  }
115
+ return formatted;
116
+ };
117
+
118
+ let formattedStartingFilters = [],
119
+ startingSlots = [];
120
+ if (!isReady) {
121
+ // Generate initial starting state
122
+ if (searchAllText) {
123
+ formattedStartingFilters.push({ field: 'q', title: 'Search all text fields', type: 'Input', value: null, });
133
124
  }
134
-
135
- const
136
- filterCallbackRef = useRef(),
137
- [filters, setFiltersRaw] = useState(formattedStartingFilters), // array of formatted filters
138
- [slots, setSlots] = useState(startingSlots), // array of field names user is currently filtering on; blank slots have a null entry in array
139
- [modalFilters, setModalFilters] = useState([]),
140
- [modalSlots, setModalSlots] = useState([]),
141
- [previousFilterNames, setPreviousFilterNames] = useState([]), // names of filters the repository used last query
142
- canAddSlot = (() => {
143
- let canAdd = true;
144
- if (!!maxFilters && modalSlots.length >= maxFilters) {
145
- canAdd = false; // maxFilters has been reached
146
- }
147
- if (canAdd) {
148
- _.each(modalSlots, (field) => {
149
- if (_.isNil(field)) {
150
- canAdd = false; // at least one slot has no selected field to filter
151
- return false;
152
- }
153
- });
154
- }
155
- return canAdd;
156
- })(),
157
- canDeleteSlot = modalSlots.length > minFilters,
158
- onAddSlot = () => {
159
- if (!canAddSlot) {
160
- return;
161
- }
162
- const newSlots = _.clone(modalSlots);
163
- newSlots.push(null);
164
- setModalSlots(newSlots);
165
- },
166
- onDeleteSlot = () => {
167
- if (!canDeleteSlot) {
168
- return;
169
- }
170
- const
171
- newFilters = _.clone(modalFilters),
172
- newSlots = _.clone(modalSlots);
173
- newFilters.pop();
174
- newSlots.pop();
175
- setModalFilters(newFilters);
176
- setModalSlots(newSlots);
177
- },
178
- setFilters = (filters, doSetSlots = true, save = true) => {
179
- setFiltersRaw(filters);
180
-
181
- if (doSetSlots) {
182
- const newSlots = [];
183
- _.each(filters, (filter, ix) => {
184
- if (searchAllText && ix === 0) {
185
- return; // skip
186
- }
187
- newSlots.push(filter.field);
188
- });
189
- if (newSlots.length < minFilters) {
190
- // Add more slots until we get to minFilters
191
- for(let i = newSlots.length; i < minFilters; i++) {
192
- newSlots.push(null);
193
- }
194
- }
195
- setSlots(newSlots);
196
- }
197
- if (save && id) {
198
- setSaved(id + '-filters', filters);
199
- }
200
- if (onFilterChange) {
201
- onFilterChange(filters);
202
- }
203
- },
204
- onFilterChangeValue = (field, value) => {
205
- // handler for when a filter value changes
206
- const newFilters = [];
207
- _.each(filters, (filter) => {
208
- if (filter.field === field) {
209
- filter.value = value;
125
+ _.each(startingFilters, (filter) => {
126
+ const
127
+ formattedFilter = getFormattedFilter(filter),
128
+ field = formattedFilter.field;
129
+ formattedStartingFilters.push(formattedFilter);
130
+ if (!isUsingCustomFilters) {
131
+ startingSlots.push(field);
132
+ }
133
+ });
134
+ if (startingSlots.length < minFilters) {
135
+ for (let i = startingSlots.length; i < minFilters; i++) {
136
+ startingSlots.push(null);
137
+ }
138
+ }
139
+ }
140
+
141
+ const
142
+ filterCallbackRef = useRef(),
143
+ [filters, setFiltersRaw] = useState(formattedStartingFilters), // array of formatted filters
144
+ [slots, setSlots] = useState(startingSlots), // array of field names user is currently filtering on; blank slots have a null entry in array
145
+ [previousFilterNames, setPreviousFilterNames] = useState([]), // names of filters the repository used last query
146
+ setFilters = (filters, doSetSlots = true, save = true) => {
147
+ setFiltersRaw(filters);
148
+
149
+ if (doSetSlots) {
150
+ const newSlots = [];
151
+ _.each(filters, (filter, ix) => {
152
+ if (searchAllText && ix === 0) {
153
+ return; // skip
210
154
  }
211
- newFilters.push(filter);
155
+ newSlots.push(filter.field);
212
156
  });
213
- setFilters(newFilters, false);
214
- },
215
- onClearFilters = () => {
216
- // Clears values for all active filters
217
- const newFilters = [];
218
- _.each(filters, (filter) => {
219
- if (!inArray(filter.field, clearExceptions)) {
220
- filter.value = null;
157
+ if (newSlots.length < minFilters) {
158
+ // Add more slots until we get to minFilters
159
+ for(let i = newSlots.length; i < minFilters; i++) {
160
+ newSlots.push(null);
221
161
  }
222
- newFilters.push(filter);
223
- });
224
- setFilters(newFilters, false);
225
- },
226
- getFilterByField = (field) => {
227
- return _.find(filters, (filter) => {
228
- return filter.field === field;
229
- });
230
- },
231
- getFilterValue = (field) => {
232
- const filter = getFilterByField(field);
233
- return filter?.value;
234
- },
235
- getFilterType = (field) => {
236
- // Finds filter type for the field name, from active filters
237
- const filter = getFilterByField(field);
238
- return filter?.type;
239
- },
240
- getIsFilterRange = (filter) => {
241
- let filterType;
242
- if (filter.type) {
243
- // filter type is already determined
244
- filterType = filter.type;
245
- } else {
246
- // try to find filter type from field name
247
- const field = _.isString(filter) ? filter : filter.field;
248
- filterType = getFilterType(field);
249
162
  }
250
- if (filterType?.type) {
251
- filterType = filterType.type;
163
+ setSlots(newSlots);
164
+ }
165
+ if (save && id) {
166
+ setSaved(id + '-filters', filters);
167
+ }
168
+ if (onFilterChange) {
169
+ onFilterChange(filters);
170
+ }
171
+ },
172
+ onFilterChangeValue = (field, value) => {
173
+ // handler for when a filter value changes
174
+ const newFilters = [];
175
+ _.each(filters, (filter) => {
176
+ if (filter.field === field) {
177
+ filter.value = value;
178
+ }
179
+ newFilters.push(filter);
180
+ });
181
+ setFilters(newFilters, false);
182
+ },
183
+ onClearFilters = () => {
184
+ // Clears values for all active filters
185
+ const newFilters = [];
186
+ _.each(filters, (filter) => {
187
+ if (!inArray(filter.field, clearExceptions)) {
188
+ filter.value = null;
189
+ }
190
+ newFilters.push(filter);
191
+ });
192
+ setFilters(newFilters, false);
193
+ },
194
+ getFilterByField = (field) => {
195
+ return _.find(filters, (filter) => {
196
+ return filter.field === field;
197
+ });
198
+ },
199
+ getFilterValue = (field) => {
200
+ const filter = getFilterByField(field);
201
+ return filter?.value;
202
+ },
203
+ getFilterType = (field) => {
204
+ // Finds filter type for the field name, from active filters
205
+ const filter = getFilterByField(field);
206
+ return filter?.type;
207
+ },
208
+ getIsFilterRange = (filter) => {
209
+ let filterType;
210
+ if (filter.type) {
211
+ // filter type is already determined
212
+ filterType = filter.type;
213
+ } else {
214
+ // try to find filter type from field name
215
+ const field = _.isString(filter) ? filter : filter.field;
216
+ filterType = getFilterType(field);
217
+ }
218
+ if (filterType?.type) {
219
+ filterType = filterType.type;
220
+ }
221
+ return inArray(filterType, ['NumberRange', 'DateRange']);
222
+ },
223
+ filterById = (id, cb) => {
224
+ onClearFilters();
225
+ filterCallbackRef.current = cb; // store the callback, so we can call it the next time this HOC renders with new filters
226
+ const newFilters = _.clone(filters);
227
+ _.remove(newFilters, (filter) => {
228
+ return filter.field === 'q';
229
+ });
230
+ newFilters.unshift({
231
+ field: 'q',
232
+ title: 'Search all text fields',
233
+ type: 'Input',
234
+ value: 'id:' + id,
235
+ });
236
+ setFilters(newFilters, false, false);
237
+ },
238
+ renderFilters = () => {
239
+ const
240
+ filterProps = {
241
+ autoAdjustPageSizeToHeight: false,
242
+ pageSize: 20,
243
+ uniqueRepository: true,
244
+ className: 'Filter mx-1',
245
+ },
246
+ filterElements = [];
247
+ _.each(filters, (filter, ix) => {
248
+ let Element,
249
+ elementProps = {};
250
+ let {
251
+ field,
252
+ type: filterType,
253
+ title,
254
+ className = '',
255
+ } = filter;
256
+
257
+ if (!title) {
258
+ const propertyDef = Repository.getSchema().getPropertyDefinition(field);
259
+ title = propertyDef?.title;
252
260
  }
253
- return inArray(filterType, ['NumberRange', 'DateRange']);
254
- },
255
- filterById = (id, cb) => {
256
- onClearFilters();
257
- filterCallbackRef.current = cb; // store the callback, so we can call it the next time this HOC renders with new filters
258
- const newFilters = _.clone(filters);
259
- _.remove(newFilters, (filter) => {
260
- return filter.field === 'q';
261
- });
262
- newFilters.unshift({
263
- field: 'q',
264
- title: 'Search all text fields',
265
- type: 'Input',
266
- value: 'id:' + id,
267
- });
268
- setFilters(newFilters, false, false);
269
- },
270
- renderFilters = () => {
271
- const
272
- filterProps = {
273
- mx: 1,
274
- autoAdjustPageSizeToHeight: false,
275
- pageSize: 20,
276
- uniqueRepository: true,
277
- },
278
- filterElements = [];
279
- _.each(filters, (filter, ix) => {
280
- let Element,
281
- elementProps = {};
282
- let {
283
- field,
284
- type: filterType,
285
- title,
286
- } = filter;
287
-
288
- if (!title) {
289
- const propertyDef = Repository.getSchema().getPropertyDefinition(field);
290
- title = propertyDef?.title;
291
- }
292
261
 
293
- if (_.isString(filterType)) {
294
- if (filterType === FILTER_TYPE_ANCILLARY) {
295
- title = modelFilterTypes[field].title;
296
- const tagOrCombo = Repository.schema.model.ancillaryFiltersThatUseTags && inArray(field, Repository.schema.model.ancillaryFiltersThatUseTags) ? 'Tag' : 'Combo';
297
- filterType = Inflector.camelize(Inflector.pluralize(field)) + tagOrCombo; // Convert field to PluralCamelCombo
298
- }
299
- Element = getComponentFromType(filterType);
300
- if (filterType === 'Input') {
301
- elementProps.autoSubmit = true;
302
- }
303
- } else if (_.isPlainObject(filterType)) {
304
- const {
305
- type,
306
- ...p
307
- } = filterType;
308
- elementProps = p;
309
- Element = getComponentFromType(type);
310
- if (type === 'Input') {
311
- elementProps.autoSubmit = true;
312
- }
313
- }
314
- if (!Element) {
315
- return; // to protect against errors
262
+ if (_.isString(filterType)) {
263
+ if (filterType === FILTER_TYPE_ANCILLARY) {
264
+ title = modelFilterTypes[field].title;
265
+ const tagOrCombo = Repository.schema.model.ancillaryFiltersThatUseTags && inArray(field, Repository.schema.model.ancillaryFiltersThatUseTags) ? 'Tag' : 'Combo';
266
+ filterType = Inflector.camelize(Inflector.pluralize(field)) + tagOrCombo; // Convert field to PluralCamelCombo
316
267
  }
317
- if (field === 'q') {
318
- elementProps.flex = 1;
319
- elementProps.minWidth = 100;
268
+ Element = getComponentFromType(filterType);
269
+ if (filterType === 'Input') {
270
+ elementProps.autoSubmit = true;
320
271
  }
321
-
322
- const tooltip = filter.tooltip || title;
323
- let filterElement = <Element
324
- {...testProps('filter-' + field)}
325
- key={'filter-' + field}
326
- tooltip={tooltip}
327
- placeholder={tooltip}
328
- value={getFilterValue(field)}
329
- onChangeValue={(value) => onFilterChangeValue(field, value)}
330
- {...filterProps}
331
- {...elementProps}
332
- />;
333
- if (showLabels && field !== 'q') {
334
- filterElement = <Row key={'label-' + ix} alignItems="center" h="100%">
335
- <Text ml={2} mr={1} fontSize={UiGlobals.styles.FILTER_LABEL_FONTSIZE}>{title}</Text>
336
- {filterElement}
337
- </Row>;
338
- }
339
- // add a container for each filter
340
- filterElement = <Row
341
- key={'filter-' + ix}
342
- bg="trueGray.100"
343
- px={1}
344
- mx={1}
345
- borderRadius={6}
346
- borderLeftWidth={1}
347
- borderLeftColor="#fff"
348
- alignItems="center"
349
- h="100%"
350
- >
351
- {filterElement}
352
- </Row>;
353
-
354
- filterElements.push(filterElement);
355
- });
356
- return filterElements;
357
- };
358
-
359
- useEffect(() => {
360
- (async () => {
361
-
362
- // Whenever the filters change in some way, make repository conform to these new filters
363
- const newRepoFilters = [];
364
- let filtersToUse = filters
365
-
366
- if (!isReady && id && !isUsingCustomFilters) { // can't save custom filters bc we can't save JS fns in Repository (e.g. getRepoFilters)
367
- const savedFilters = await getSaved(id + '-filters');
368
- if (!_.isEmpty(savedFilters)) {
369
- // load saved filters
370
- filtersToUse = savedFilters;
371
- setFilters(savedFilters, true, false); // false to skip save
272
+ } else if (_.isPlainObject(filterType)) {
273
+ const {
274
+ type,
275
+ ...p
276
+ } = filterType;
277
+ elementProps = p;
278
+ Element = getComponentFromType(type);
279
+ if (type === 'Input') {
280
+ elementProps.autoSubmit = true;
372
281
  }
373
282
  }
374
-
375
- if (isUsingCustomFilters) {
376
- _.each(filtersToUse, ({ field, value, getRepoFilters }) => {
377
- if (getRepoFilters) {
378
- let repoFiltersFromFilter = getRepoFilters(value) || [];
379
- if (!_.isArray(repoFiltersFromFilter)) {
380
- repoFiltersFromFilter = [repoFiltersFromFilter];
381
- }
382
- _.each(repoFiltersFromFilter, (repoFilter) => { // one custom filter might generate multiple filters for the repository
383
- newRepoFilters.push(repoFilter);
384
- });
385
- } else {
386
- newRepoFilters.push({ name: field, value, });
387
- }
388
- });
389
- } else {
390
- const newFilterNames = [];
391
- _.each(filtersToUse, (filter) => {
392
- const {
393
- field,
394
- value,
395
- type,
396
- } = filter,
397
- isFilterRange = getIsFilterRange(filter);
398
- if (isFilterRange) {
399
- if (!!value) {
400
- const
401
- highField = field + ' <=',
402
- lowField = field + ' >=',
403
- highValue = value.high,
404
- lowValue = value.low;
405
- newFilterNames.push(highField);
406
- newFilterNames.push(lowField);
407
- newRepoFilters.push({ name: highField, value: highValue, });
408
- newRepoFilters.push({ name: lowField, value: lowValue, });
409
- }
410
- } else {
411
- const
412
- isAncillary = type === FILTER_TYPE_ANCILLARY,
413
- filterName = (isAncillary ? 'ancillary___' : '') + field;
414
- newFilterNames.push(filterName);
415
- newRepoFilters.push({ name: filterName, value, });
416
- }
417
- });
418
-
419
- // Go through previousFilterNames and see if any are no longer used.
420
- _.each(previousFilterNames, (name) => {
421
- if (!inArray(name, newFilterNames)) {
422
- newRepoFilters.push({ name, value: null, }); // no longer used, so set it to null so it'll be deleted
423
- }
424
- });
425
- setPreviousFilterNames(newFilterNames);
283
+ if (!Element) {
284
+ return; // to protect against errors
426
285
  }
427
-
428
- if (searchAllText && Repository.searchAncillary && !Repository.hasBaseParam('searchAncillary')) {
429
- Repository.setBaseParam('searchAncillary', true);
286
+ if (field === 'q') {
287
+ elementProps.flex = 1;
288
+ elementProps.minWidth = 100;
430
289
  }
431
290
 
432
- await Repository.filter(newRepoFilters, null, false); // false so other filters remain
433
-
434
- if (filterCallbackRef.current) {
435
- filterCallbackRef.current(); // call the callback
436
- filterCallbackRef.current = null; // clear the callback
291
+ const tooltip = filter.tooltip || title;
292
+ let filterClassName = filterProps.className + ` Filter-${field}`;
293
+ if (className) {
294
+ filterClassName += ' ' + className;
437
295
  }
438
-
439
- if (!isReady) {
440
- setIsReady(true);
296
+ if (elementProps.className) {
297
+ filterClassName += ' ' + elementProps.className;
441
298
  }
442
- })();
443
- }, [filters]);
444
-
445
- if (!isReady) {
446
- return null;
447
- }
448
-
449
- if (self) {
450
- self.filterById = filterById;
451
- self.setFilters = setFilters;
452
- }
453
-
454
- const
455
- renderedFilters = renderFilters(),
456
- hasFilters = !!renderedFilters.length;
457
- topToolbar = <Toolbar>
458
- <Row flex={1} alignItems="center">
459
- <ScrollView horizontal={true} contentContainerStyle={{ alignItems: 'center' }}>
460
- <Text fontStyle="italic" pr={2} userSelect="none">Filters:{hasFilters ? '' : ' None'}</Text>
461
- {renderedFilters}
462
- </ScrollView>
463
- </Row>
464
- <Row flex={hasFilters ? null : 1} alignItems="center" alignSelf="flex-end">
465
- {showClearFiltersButton &&
466
- <IconButton
467
- {...testProps('clearFiltersBtn')}
468
- key="clearFiltersBtn"
469
- _icon={{
470
- as: Ban,
471
- }}
472
- ml={1}
473
- onPress={onClearFilters}
474
- tooltip="Clear all filters"
475
- />}
476
- {showFilterSelector && !isUsingCustomFilters &&
477
- <IconButton
478
- {...testProps('swapFiltersBtn')}
479
- key="swapFiltersBtn"
480
- _icon={{
481
- as: Gear,
482
- }}
483
- ml={1}
484
- onPress={() => {
485
- const f = filters;
486
- const s = slots;
487
- setModalFilters(filters);
488
- setModalSlots(slots);
489
- setIsFilterSelectorShown(true);
490
- }}
491
- tooltip="Swap filters"
492
- />}
493
- </Row>
494
- </Toolbar>;
299
+ let filterElement = <Element
300
+ {...testProps('filter-' + field)}
301
+ tooltip={tooltip}
302
+ placeholder={tooltip}
303
+ value={getFilterValue(field)}
304
+ onChangeValue={(value) => onFilterChangeValue(field, value)}
305
+ isFilter={true}
306
+ {...filterProps}
307
+ {...elementProps}
308
+ className={filterClassName}
309
+ />;
310
+ if (field !== 'q') {
311
+ filterElement = <>
312
+ <Label
313
+ className="min-w-0 mr-1"
314
+ _text={{
315
+ className: UiGlobals.styles.FILTER_LABEL_FONTSIZE,
316
+ }}
317
+ >{title}</Label>
318
+ {filterElement}
319
+ </>;
320
+ }
321
+ // add a container for each filter
322
+ filterElement = <HStack
323
+ key={'filter-' + ix}
324
+ className={`
325
+ Filter-container-HStack
326
+ h-full
327
+ px-1
328
+ mx-1
329
+ bg-grey-100
330
+ rounded-[6px]
331
+ border
332
+ border-l-white
333
+ items-center
334
+ `}
335
+ >
336
+ {filterElement}
337
+ </HStack>;
338
+
339
+ filterElements.push(filterElement);
340
+ });
341
+ return filterElements;
342
+ },
343
+ onShowFilterSelector = () => {
344
+ showModal({
345
+ title: 'Filter Selector',
346
+ body: buildModalBody(filters, slots),
347
+ canClose: true,
348
+ w: 500,
349
+ });
350
+ },
351
+ buildModalBody = (modalFilters, modalSlots) => {
495
352
 
496
- if (isFilterSelectorShown) { // this is always false when isUsingCustomFilters
497
- // Build the modal to select the filters
498
353
  const
499
354
  modalFilterElements = [],
500
355
  usedFields = _.filter(_.map(modalFilters, (filter) => {
@@ -502,6 +357,7 @@ export default function withFilters(WrappedComponent) {
502
357
  }), el => !_.isNil(el)),
503
358
  formStartingValues = {};
504
359
 
360
+ // populate modalFilterElements and formStartingValues
505
361
  _.each(modalSlots, (field, ix) => {
506
362
 
507
363
  // Create the data for the combobox. (i.e. List all the possible filters for this slot)
@@ -540,20 +396,56 @@ export default function withFilters(WrappedComponent) {
540
396
  const
541
397
  newFilters = _.clone(modalFilters),
542
398
  newSlots = _.clone(modalSlots),
543
- i = searchAllText ? ixPlusOne : ix; // compensate for 'q' filter's possible presence
399
+ i = ix;//searchAllText ? ixPlusOne : ix; // compensate for 'q' filter's possible presence
544
400
 
545
401
  newFilters[i] = getFormattedFilter(value);
546
402
  newSlots[i] = value;
547
403
 
548
- setModalFilters(newFilters);
549
- setModalSlots(newSlots);
404
+ rebuildModalBody(newFilters, newSlots);
550
405
  },
551
406
  });
552
407
 
553
408
  formStartingValues[filterName] = field;
554
409
  });
555
410
 
411
+ const
412
+ canAddSlot = (() => {
413
+ let canAdd = true;
414
+ if (!!maxFilters && modalSlots.length >= maxFilters) {
415
+ canAdd = false; // maxFilters has been reached
416
+ }
417
+ if (canAdd) {
418
+ _.each(modalSlots, (field) => {
419
+ if (_.isNil(field)) {
420
+ canAdd = false; // at least one slot has no selected field to filter
421
+ return false;
422
+ }
423
+ });
424
+ }
425
+ return canAdd;
426
+ })(),
427
+ canDeleteSlot = modalSlots.length > minFilters;
556
428
  if (canAddSlot || canDeleteSlot) {
429
+ const
430
+ onAddSlot = () => {
431
+ if (!canAddSlot) {
432
+ return;
433
+ }
434
+ const newSlots = _.clone(modalSlots);
435
+ newSlots.push(null);
436
+ rebuildModalBody(modalFilters, newSlots);
437
+ },
438
+ onDeleteSlot = () => {
439
+ if (!canDeleteSlot) {
440
+ return;
441
+ }
442
+ const
443
+ newFilters = _.clone(modalFilters),
444
+ newSlots = _.clone(modalSlots);
445
+ newFilters.pop();
446
+ newSlots.pop();
447
+ rebuildModalBody(newFilters, newSlots);
448
+ };
557
449
  modalFilterElements.push({
558
450
  type: 'PlusMinusButton',
559
451
  name: 'plusMinusButton',
@@ -561,72 +453,206 @@ export default function withFilters(WrappedComponent) {
561
453
  minusHandler: onDeleteSlot,
562
454
  isPlusDisabled: !canAddSlot,
563
455
  isMinusDisabled: !canDeleteSlot,
564
- justifyContent: 'flex-end',
456
+ plusTooltip: 'Add another filter slot',
457
+ minusTooltip: 'Remove the last filter slot',
458
+ className: 'justify-end',
565
459
  });
566
460
  }
567
461
 
568
- modal = <Modal
569
- isOpen={true}
570
- onClose={() => setIsFilterSelectorShown(false)}
571
- >
572
- <Column bg="#fff" w={500}>
573
- <FormPanel
574
- title="Filter Selector"
575
- instructions="Please select which fields to filter by."
576
- editorType={EDITOR_TYPE__PLAIN}
577
- flex={1}
578
- startingValues={formStartingValues}
579
- items={[
580
- {
581
- type: 'Column',
582
- flex: 1,
583
- items: modalFilterElements,
584
- },
585
- ]}
586
- onCancel={(e) => {
587
- setIsFilterSelectorShown(false);
588
- }}
589
- onClose={(e) => {
590
- setIsFilterSelectorShown(false);
591
- }}
592
- onSave={(data, e) => {
593
- // Conform filters to this new choice of filters
594
-
595
- const newFilters = [];
596
-
597
- if (searchAllText) {
598
- newFilters.push(filters[0]);
599
- }
600
-
601
- // Conform the filters to the modal selection
602
- _.each(data, (field, ix) => {
603
- if (_.isEmpty(field) || !ix.match(/^filter/)) {
604
- return;
605
- }
606
-
607
- const newFilter = getFormattedFilter(field);
608
- newFilters.push(newFilter);
609
- });
610
-
611
- setFilters(newFilters);
612
-
613
- // Close the modal
614
- setIsFilterSelectorShown(false);
615
- }}
616
- onReset={() => {
617
- setModalFilters(filters);
618
- setModalSlots(slots);
619
- }}
620
- />
621
- </Column>
622
- </Modal>;
623
- }
462
+ return <Form
463
+ instructions="Please select which fields to filter by."
464
+ editorType={EDITOR_TYPE__PLAIN}
465
+ className="flex-1"
466
+ startingValues={formStartingValues}
467
+ items={[
468
+ {
469
+ name: 'instructions',
470
+ type: 'DisplayField',
471
+ text: 'Please select which fields to filter by.',
472
+ className: 'mb-3',
473
+ },
474
+ {
475
+ type: 'Column',
476
+ flex: 1,
477
+ items: modalFilterElements,
478
+ },
479
+ ]}
480
+ onReset={() => {
481
+ rebuildModalBody(filters, slots);
482
+ }}
483
+ onCancel={(e) => {
484
+ hideModal();
485
+ }}
486
+ onClose={(e) => {
487
+ hideModal();
488
+ }}
489
+ onSave={(data, e) => {
490
+ // Conform filters to this new choice of filters
491
+
492
+ const newFilters = [];
493
+
494
+ if (searchAllText) {
495
+ newFilters.push(filters[0]);
496
+ }
624
497
 
625
- } // END if (useFilters)
498
+ // Conform the filters to the modal selection
499
+ _.each(data, (field, ix) => {
500
+ if (_.isEmpty(field) || !ix.match(/^filter/)) {
501
+ return;
502
+ }
503
+
504
+ const newFilter = getFormattedFilter(field);
505
+ newFilters.push(newFilter);
506
+ });
507
+
508
+ setFilters(newFilters);
509
+
510
+ // Close the modal
511
+ hideModal();
512
+ }}
513
+ />;
514
+ },
515
+ rebuildModalBody = (filters, slots) => {
516
+ updateModalBody(buildModalBody(filters, slots));
517
+ };
518
+
519
+ useEffect(() => {
520
+ (async () => {
521
+
522
+ // Whenever the filters change in some way, make repository conform to these new filters
523
+ const newRepoFilters = [];
524
+ let filtersToUse = filters
525
+
526
+ if (!isReady && id && !isUsingCustomFilters) { // can't save custom filters bc we can't save JS fns in Repository (e.g. getRepoFilters)
527
+ const savedFilters = await getSaved(id + '-filters');
528
+ if (!_.isEmpty(savedFilters)) {
529
+ // load saved filters
530
+ filtersToUse = savedFilters;
531
+ setFilters(savedFilters, true, false); // false to skip save
532
+ }
533
+ }
534
+
535
+ if (isUsingCustomFilters) {
536
+ _.each(filtersToUse, ({ field, value, getRepoFilters }) => {
537
+ if (getRepoFilters) {
538
+ let repoFiltersFromFilter = getRepoFilters(value) || [];
539
+ if (!_.isArray(repoFiltersFromFilter)) {
540
+ repoFiltersFromFilter = [repoFiltersFromFilter];
541
+ }
542
+ _.each(repoFiltersFromFilter, (repoFilter) => { // one custom filter might generate multiple filters for the repository
543
+ newRepoFilters.push(repoFilter);
544
+ });
545
+ } else {
546
+ newRepoFilters.push({ name: field, value, });
547
+ }
548
+ });
549
+ } else {
550
+ const newFilterNames = [];
551
+ _.each(filtersToUse, (filter) => {
552
+ const {
553
+ field,
554
+ value,
555
+ type,
556
+ } = filter,
557
+ isFilterRange = getIsFilterRange(filter);
558
+ if (isFilterRange) {
559
+ if (!!value) {
560
+ const
561
+ highField = field + ' <=',
562
+ lowField = field + ' >=',
563
+ highValue = value.high,
564
+ lowValue = value.low;
565
+ newFilterNames.push(highField);
566
+ newFilterNames.push(lowField);
567
+ newRepoFilters.push({ name: highField, value: highValue, });
568
+ newRepoFilters.push({ name: lowField, value: lowValue, });
569
+ }
570
+ } else {
571
+ const
572
+ isAncillary = type === FILTER_TYPE_ANCILLARY,
573
+ filterName = (isAncillary ? 'ancillary___' : '') + field;
574
+ newFilterNames.push(filterName);
575
+ newRepoFilters.push({ name: filterName, value, });
576
+ }
577
+ });
578
+
579
+ // Go through previousFilterNames and see if any are no longer used.
580
+ _.each(previousFilterNames, (name) => {
581
+ if (!inArray(name, newFilterNames)) {
582
+ newRepoFilters.push({ name, value: null, }); // no longer used, so set it to null so it'll be deleted
583
+ }
584
+ });
585
+ setPreviousFilterNames(newFilterNames);
586
+ }
587
+
588
+ if (searchAllText && Repository.searchAncillary && !Repository.hasBaseParam('searchAncillary')) {
589
+ Repository.setBaseParam('searchAncillary', true);
590
+ }
591
+
592
+ await Repository.filter(newRepoFilters, null, false); // false so other filters remain
593
+
594
+ if (filterCallbackRef.current) {
595
+ filterCallbackRef.current(); // call the callback
596
+ filterCallbackRef.current = null; // clear the callback
597
+ }
598
+
599
+ if (!isReady) {
600
+ setIsReady(true);
601
+ }
602
+ })();
603
+ }, [filters]);
604
+
605
+ if (!isReady) {
606
+ return null;
607
+ }
608
+
609
+ if (self) {
610
+ self.filterById = filterById;
611
+ self.setFilters = setFilters;
612
+ }
613
+
614
+ const
615
+ renderedFilters = renderFilters(),
616
+ hasFilters = !!renderedFilters.length,
617
+ toolbar = <Toolbar>
618
+ <HStack className="withFilters-scrollViewContainer flex-1 items-center">
619
+ <ScrollView className="ScrollView" horizontal={true} contentContainerStyle={{ alignItems: 'center' }}>
620
+ <Text
621
+ className={`
622
+ withFilters-filtersLabel
623
+ italic-italic
624
+ pr-2
625
+ select-none
626
+ ${hasFilters ? 'flex-1' : 'italic'}
627
+ `}>{hasFilters ? 'Filters:' : 'No Filters'}</Text>
628
+ {renderedFilters}
629
+ </ScrollView>
630
+ </HStack>
631
+ {(showClearFiltersButton || !isUsingCustomFilters) &&
632
+ <HStack className="withFilters-endButtonsContainer self-end items-center h-full">
633
+ {showClearFiltersButton &&
634
+ <IconButton
635
+ {...testProps('clearFiltersBtn')}
636
+ key="clearFiltersBtn"
637
+ icon={Ban}
638
+ className="ml-1"
639
+ onPress={onClearFilters}
640
+ tooltip="Clear all filters"
641
+ isDisabled={!hasFilters}
642
+ />}
643
+ {!isUsingCustomFilters &&
644
+ <IconButton
645
+ {...testProps('swapFiltersBtn')}
646
+ key="swapFiltersBtn"
647
+ icon={Gear}
648
+ className="ml-1"
649
+ onPress={onShowFilterSelector}
650
+ tooltip="Set filters"
651
+ />}
652
+ </HStack>}
653
+ </Toolbar>;
654
+
655
+ return <WrappedComponent {...props} topToolbar={toolbar} ref={ref} />;
626
656
 
627
- return <>
628
- <WrappedComponent topToolbar={topToolbar} {...props} />
629
- {modal}
630
- </>;
631
- };
657
+ });
632
658
  }