ekm-ui 0.3.74 → 0.3.78

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 (264) hide show
  1. package/.turbo/turbo-build.log +128 -128
  2. package/CHANGELOG.md +12 -0
  3. package/dist/accordion.d.ts +28 -21
  4. package/dist/accordion.mjs +1 -1
  5. package/dist/alert-banner.mjs +1 -1
  6. package/dist/avatar.mjs +1 -1
  7. package/dist/badge.mjs +1 -1
  8. package/dist/breadcrumb.mjs +1 -1
  9. package/dist/card-payment-block.css +1 -1
  10. package/dist/card-payment-block.css.map +1 -1
  11. package/dist/card-payment-block.mjs +46 -46
  12. package/dist/checkbox.mjs +1 -1
  13. package/dist/chunk-2OTVEVU7.mjs +11 -0
  14. package/dist/chunk-2OTVEVU7.mjs.map +1 -0
  15. package/dist/{chunk-47S6AX7M.mjs → chunk-2PW7KHXJ.mjs} +1 -1
  16. package/dist/chunk-2PW7KHXJ.mjs.map +1 -0
  17. package/dist/{chunk-CMA7TSQG.mjs → chunk-35VEFUPA.mjs} +4 -4
  18. package/dist/chunk-35VEFUPA.mjs.map +1 -0
  19. package/dist/{chunk-ZWJSMASL.mjs → chunk-3AGRJPPN.mjs} +3 -3
  20. package/dist/chunk-3AGRJPPN.mjs.map +1 -0
  21. package/dist/{chunk-MRJOYGDD.mjs → chunk-3TAXDPV6.mjs} +2 -2
  22. package/dist/{chunk-MRJOYGDD.mjs.map → chunk-3TAXDPV6.mjs.map} +1 -1
  23. package/dist/{chunk-5DQUZENZ.mjs → chunk-6F3XKP3G.mjs} +2 -2
  24. package/dist/chunk-6F3XKP3G.mjs.map +1 -0
  25. package/dist/{chunk-HEKVJKLH.mjs → chunk-6UK5Y6KZ.mjs} +2 -2
  26. package/dist/{chunk-HEKVJKLH.mjs.map → chunk-6UK5Y6KZ.mjs.map} +1 -1
  27. package/dist/{chunk-EWNPNF2B.mjs → chunk-76V2THLN.mjs} +3 -3
  28. package/dist/chunk-76V2THLN.mjs.map +1 -0
  29. package/dist/chunk-7GLTVVKS.mjs +12 -0
  30. package/dist/chunk-7GLTVVKS.mjs.map +1 -0
  31. package/dist/{chunk-UUWBHZKH.mjs → chunk-7MH2LXFV.mjs} +4 -4
  32. package/dist/{chunk-UUWBHZKH.mjs.map → chunk-7MH2LXFV.mjs.map} +1 -1
  33. package/dist/{chunk-7YKZ7D7U.mjs → chunk-ATNP3Z6G.mjs} +2 -2
  34. package/dist/{chunk-25FJ277C.mjs → chunk-AYH56CFA.mjs} +3 -3
  35. package/dist/chunk-AYH56CFA.mjs.map +1 -0
  36. package/dist/{chunk-NEJOZRKV.mjs → chunk-BK5RX7N5.mjs} +2 -2
  37. package/dist/chunk-BK5RX7N5.mjs.map +1 -0
  38. package/dist/{chunk-F6ZWBNIM.mjs → chunk-CIUW5YZ7.mjs} +2 -2
  39. package/dist/chunk-CIUW5YZ7.mjs.map +1 -0
  40. package/dist/{chunk-WMFTYTMD.mjs → chunk-CZC4EJOD.mjs} +3 -3
  41. package/dist/chunk-CZC4EJOD.mjs.map +1 -0
  42. package/dist/{chunk-CEK5K5TU.mjs → chunk-D3VRYN5H.mjs} +4 -4
  43. package/dist/chunk-D3VRYN5H.mjs.map +1 -0
  44. package/dist/{chunk-W3DRXKTC.mjs → chunk-DBTYTFGU.mjs} +2 -2
  45. package/dist/chunk-DBTYTFGU.mjs.map +1 -0
  46. package/dist/{chunk-JCWSMIVA.mjs → chunk-E6KQBM7F.mjs} +2 -2
  47. package/dist/chunk-E6KQBM7F.mjs.map +1 -0
  48. package/dist/{chunk-5FPVCRAI.mjs → chunk-ECOC3JRK.mjs} +1 -1
  49. package/dist/{chunk-5FPVCRAI.mjs.map → chunk-ECOC3JRK.mjs.map} +1 -1
  50. package/dist/{chunk-3LINEESX.mjs → chunk-EH3ZVEVT.mjs} +1 -1
  51. package/dist/chunk-EH3ZVEVT.mjs.map +1 -0
  52. package/dist/{chunk-YJKULMWM.mjs → chunk-EX5FMSQL.mjs} +2 -2
  53. package/dist/chunk-EX5FMSQL.mjs.map +1 -0
  54. package/dist/{chunk-ASCPOK5F.mjs → chunk-FVUORQJX.mjs} +4 -4
  55. package/dist/chunk-FVUORQJX.mjs.map +1 -0
  56. package/dist/{chunk-WFRV27QA.mjs → chunk-G5A3E5IG.mjs} +3 -3
  57. package/dist/chunk-G5A3E5IG.mjs.map +1 -0
  58. package/dist/{chunk-2IL2LP47.mjs → chunk-HOCKBMTF.mjs} +3 -3
  59. package/dist/chunk-HOCKBMTF.mjs.map +1 -0
  60. package/dist/{chunk-FRIXS4BL.mjs → chunk-JPF3K5TD.mjs} +1 -1
  61. package/dist/chunk-JPF3K5TD.mjs.map +1 -0
  62. package/dist/{chunk-AYXC2DCM.mjs → chunk-K2G6O2LX.mjs} +3 -3
  63. package/dist/chunk-K2G6O2LX.mjs.map +1 -0
  64. package/dist/chunk-LVJYP46A.mjs +9 -0
  65. package/dist/chunk-LVJYP46A.mjs.map +1 -0
  66. package/dist/{chunk-VQ3MZS4J.mjs → chunk-MPIWXVKP.mjs} +2 -2
  67. package/dist/chunk-MPIWXVKP.mjs.map +1 -0
  68. package/dist/{chunk-DZABAR36.mjs → chunk-NJC2WLYK.mjs} +2 -2
  69. package/dist/chunk-NJC2WLYK.mjs.map +1 -0
  70. package/dist/{chunk-5CGIKL2Y.mjs → chunk-OG6UBKMG.mjs} +2 -2
  71. package/dist/chunk-OG6UBKMG.mjs.map +1 -0
  72. package/dist/chunk-PEODF7PL.mjs +34 -0
  73. package/dist/chunk-PEODF7PL.mjs.map +1 -0
  74. package/dist/{chunk-FAFXVD4P.mjs → chunk-PJZVMYPN.mjs} +4 -4
  75. package/dist/chunk-PJZVMYPN.mjs.map +1 -0
  76. package/dist/{chunk-KEIDXVZB.mjs → chunk-PT4IH2KW.mjs} +2 -2
  77. package/dist/chunk-PT4IH2KW.mjs.map +1 -0
  78. package/dist/{chunk-MXH3TZWM.mjs → chunk-QFECX4D6.mjs} +1 -1
  79. package/dist/chunk-QFECX4D6.mjs.map +1 -0
  80. package/dist/{chunk-5VH26DHQ.mjs → chunk-QMFUWXJJ.mjs} +1 -1
  81. package/dist/chunk-QMFUWXJJ.mjs.map +1 -0
  82. package/dist/chunk-R4A5DO7E.mjs +12 -0
  83. package/dist/chunk-R4A5DO7E.mjs.map +1 -0
  84. package/dist/{chunk-LQQDRIZN.mjs → chunk-RGCO6BCU.mjs} +3 -3
  85. package/dist/chunk-RGCO6BCU.mjs.map +1 -0
  86. package/dist/{chunk-PPMW7YAZ.mjs → chunk-SFSA2WUE.mjs} +28 -28
  87. package/dist/chunk-SFSA2WUE.mjs.map +1 -0
  88. package/dist/{chunk-XUXHB434.mjs → chunk-SM4TG5VI.mjs} +1 -1
  89. package/dist/chunk-SM4TG5VI.mjs.map +1 -0
  90. package/dist/{chunk-D6H235SZ.mjs → chunk-UPAA75QA.mjs} +1 -1
  91. package/dist/chunk-UPAA75QA.mjs.map +1 -0
  92. package/dist/{chunk-256SAVHD.mjs → chunk-W3XYS7M3.mjs} +1 -1
  93. package/dist/{chunk-256SAVHD.mjs.map → chunk-W3XYS7M3.mjs.map} +1 -1
  94. package/dist/chunk-X2JENUDV.mjs +16 -0
  95. package/dist/chunk-X2JENUDV.mjs.map +1 -0
  96. package/dist/chunk-XBWUYKZW.mjs +10 -0
  97. package/dist/chunk-XBWUYKZW.mjs.map +1 -0
  98. package/dist/{chunk-Q365BFES.mjs → chunk-YJINOUZ7.mjs} +1 -1
  99. package/dist/chunk-YJINOUZ7.mjs.map +1 -0
  100. package/dist/{chunk-4IKXV4FQ.mjs → chunk-Z5YZVKS5.mjs} +2 -2
  101. package/dist/{chunk-ZHCGY4YB.mjs → chunk-ZO5NWKNY.mjs} +2 -2
  102. package/dist/{chunk-ZHCGY4YB.mjs.map → chunk-ZO5NWKNY.mjs.map} +1 -1
  103. package/dist/color-picker.mjs +1 -1
  104. package/dist/dashboard-notification.mjs +1 -1
  105. package/dist/date-range-picker.mjs +4 -4
  106. package/dist/drag-and-drop.css +1 -1
  107. package/dist/drag-and-drop.css.map +1 -1
  108. package/dist/drag-and-drop.mjs +46 -46
  109. package/dist/draggable-stacked-list-item.mjs +2 -2
  110. package/dist/drawer.mjs +1 -1
  111. package/dist/dropdown.mjs +1 -1
  112. package/dist/feature-cards/feature-card.mjs +2 -2
  113. package/dist/featurePageComponents/feature-page-group.mjs +1 -1
  114. package/dist/file-picker/file-listing.d.ts +1 -1
  115. package/dist/file-picker/file-listing.mjs +2 -2
  116. package/dist/file-picker/file-picker.css +1 -1
  117. package/dist/file-picker/file-picker.css.map +1 -1
  118. package/dist/file-picker/file-picker.d.ts +2 -2
  119. package/dist/file-picker/file-picker.mjs +46 -46
  120. package/dist/fixed-alert.mjs +1 -1
  121. package/dist/footer-heart-icon.mjs +1 -1
  122. package/dist/form-row.mjs +2 -2
  123. package/dist/index.css +1 -1
  124. package/dist/index.css.map +1 -1
  125. package/dist/index.mjs +46 -46
  126. package/dist/input-copy.mjs +2 -2
  127. package/dist/label.mjs +1 -1
  128. package/dist/layout/layout.css +1 -1
  129. package/dist/layout/layout.css.map +1 -1
  130. package/dist/layout/layout.mjs +46 -46
  131. package/dist/loading-button.mjs +1 -1
  132. package/dist/love-footer.mjs +2 -2
  133. package/dist/mini-feature-block.mjs +2 -2
  134. package/dist/modal.mjs +1 -1
  135. package/dist/navbar/navbar.mjs +1 -1
  136. package/dist/no-results-block.d.ts +1 -1
  137. package/dist/no-results-block.mjs +1 -1
  138. package/dist/page-header.mjs +2 -2
  139. package/dist/pagination/pagination.mjs +1 -1
  140. package/dist/product-picker/product-drawer.css +1 -1
  141. package/dist/product-picker/product-drawer.css.map +1 -1
  142. package/dist/product-picker/product-drawer.mjs +46 -46
  143. package/dist/product-picker/product-listing.d.ts +1 -1
  144. package/dist/product-picker/product-listing.mjs +2 -2
  145. package/dist/progress-bar.mjs +1 -1
  146. package/dist/radio.mjs +1 -1
  147. package/dist/rich-text-editor/index.mjs +1 -1
  148. package/dist/search/search.mjs +1 -1
  149. package/dist/select.mjs +1 -1
  150. package/dist/sort/sort.mjs +1 -1
  151. package/dist/spinner.mjs +1 -1
  152. package/dist/stacked-list-item.css +1 -1
  153. package/dist/stacked-list-item.css.map +1 -1
  154. package/dist/stacked-list-item.mjs +46 -46
  155. package/dist/table-header/table-header.mjs +3 -3
  156. package/dist/table-result-block.css +1 -1
  157. package/dist/table-result-block.css.map +1 -1
  158. package/dist/table-result-block.mjs +46 -46
  159. package/dist/text-row.mjs +1 -1
  160. package/dist/textarea.mjs +1 -1
  161. package/dist/textinput.mjs +1 -1
  162. package/dist/toast/index.mjs +1 -1
  163. package/dist/toggleswitch.mjs +1 -1
  164. package/dist/tooltip/tooltip.mjs +1 -1
  165. package/dist/video-dashboard-notification.mjs +1 -1
  166. package/dist/video-modal.mjs +1 -1
  167. package/package.json +4 -2
  168. package/src/accordion.tsx +120 -58
  169. package/src/alert-banner.tsx +78 -56
  170. package/src/avatar.tsx +71 -49
  171. package/src/badge.tsx +38 -30
  172. package/src/breadcrumb.tsx +28 -21
  173. package/src/checkbox.tsx +28 -20
  174. package/src/color-picker.tsx +2 -4
  175. package/src/dashboard-notification.tsx +1 -2
  176. package/src/date-range-picker.tsx +208 -139
  177. package/src/drag-and-drop.tsx +4 -4
  178. package/src/draggable-stacked-list-item.tsx +2 -2
  179. package/src/drawer.tsx +2 -2
  180. package/src/dropdown.tsx +91 -73
  181. package/src/featurePageComponents/feature-page-group.tsx +0 -1
  182. package/src/file-picker/file-listing.tsx +86 -38
  183. package/src/file-picker/file-picker.tsx +296 -212
  184. package/src/fixed-alert.tsx +2 -5
  185. package/src/footer-heart-icon.tsx +31 -7
  186. package/src/form-row.tsx +1 -1
  187. package/src/index.tsx +1 -1
  188. package/src/input-copy.tsx +1 -1
  189. package/src/label.tsx +12 -6
  190. package/src/layout/layout.tsx +2 -2
  191. package/src/loading-button.tsx +21 -21
  192. package/src/mini-feature-block.tsx +2 -6
  193. package/src/modal.tsx +46 -34
  194. package/src/navbar/navbar.tsx +1 -1
  195. package/src/no-results-block.tsx +7 -3
  196. package/src/page-header.tsx +13 -8
  197. package/src/pagination/pagination.tsx +1 -1
  198. package/src/product-picker/product-drawer.tsx +226 -144
  199. package/src/product-picker/product-listing.tsx +84 -45
  200. package/src/progress-bar.tsx +39 -25
  201. package/src/radio.tsx +11 -11
  202. package/src/rich-text-editor/headless-editor.ts +5 -5
  203. package/src/search/search.tsx +4 -4
  204. package/src/select.tsx +2 -3
  205. package/src/sort/sort.tsx +33 -31
  206. package/src/spinner.tsx +3 -3
  207. package/src/stacked-list-item.tsx +1 -1
  208. package/src/table-header/table-header.tsx +114 -90
  209. package/src/table-result-block.tsx +12 -10
  210. package/src/text-row.tsx +1 -1
  211. package/src/textarea.tsx +27 -24
  212. package/src/textinput.tsx +31 -28
  213. package/src/toast/index.tsx +4 -4
  214. package/src/toggleswitch.tsx +3 -1
  215. package/src/tooltip/tooltip.tsx +1 -1
  216. package/src/video-dashboard-notification.tsx +0 -2
  217. package/src/video-modal.tsx +2 -5
  218. package/dist/chunk-25FJ277C.mjs.map +0 -1
  219. package/dist/chunk-2IL2LP47.mjs.map +0 -1
  220. package/dist/chunk-3LINEESX.mjs.map +0 -1
  221. package/dist/chunk-47S6AX7M.mjs.map +0 -1
  222. package/dist/chunk-5CGIKL2Y.mjs.map +0 -1
  223. package/dist/chunk-5DQUZENZ.mjs.map +0 -1
  224. package/dist/chunk-5VH26DHQ.mjs.map +0 -1
  225. package/dist/chunk-ASCPOK5F.mjs.map +0 -1
  226. package/dist/chunk-AYXC2DCM.mjs.map +0 -1
  227. package/dist/chunk-CEK5K5TU.mjs.map +0 -1
  228. package/dist/chunk-CMA7TSQG.mjs.map +0 -1
  229. package/dist/chunk-CZNQ24DQ.mjs +0 -16
  230. package/dist/chunk-CZNQ24DQ.mjs.map +0 -1
  231. package/dist/chunk-D6H235SZ.mjs.map +0 -1
  232. package/dist/chunk-DZABAR36.mjs.map +0 -1
  233. package/dist/chunk-EWNPNF2B.mjs.map +0 -1
  234. package/dist/chunk-F6ZWBNIM.mjs.map +0 -1
  235. package/dist/chunk-FAFXVD4P.mjs.map +0 -1
  236. package/dist/chunk-FRIXS4BL.mjs.map +0 -1
  237. package/dist/chunk-HZTQAUGX.mjs +0 -34
  238. package/dist/chunk-HZTQAUGX.mjs.map +0 -1
  239. package/dist/chunk-JACXLYPD.mjs +0 -12
  240. package/dist/chunk-JACXLYPD.mjs.map +0 -1
  241. package/dist/chunk-JCWSMIVA.mjs.map +0 -1
  242. package/dist/chunk-KEIDXVZB.mjs.map +0 -1
  243. package/dist/chunk-LQQDRIZN.mjs.map +0 -1
  244. package/dist/chunk-MXH3TZWM.mjs.map +0 -1
  245. package/dist/chunk-NEJOZRKV.mjs.map +0 -1
  246. package/dist/chunk-PPMW7YAZ.mjs.map +0 -1
  247. package/dist/chunk-Q365BFES.mjs.map +0 -1
  248. package/dist/chunk-REFCK56T.mjs +0 -12
  249. package/dist/chunk-REFCK56T.mjs.map +0 -1
  250. package/dist/chunk-VPLCWU7T.mjs +0 -9
  251. package/dist/chunk-VPLCWU7T.mjs.map +0 -1
  252. package/dist/chunk-VQ3MZS4J.mjs.map +0 -1
  253. package/dist/chunk-W3DRXKTC.mjs.map +0 -1
  254. package/dist/chunk-WFRV27QA.mjs.map +0 -1
  255. package/dist/chunk-WLJEFSES.mjs +0 -10
  256. package/dist/chunk-WLJEFSES.mjs.map +0 -1
  257. package/dist/chunk-WMFTYTMD.mjs.map +0 -1
  258. package/dist/chunk-XUXHB434.mjs.map +0 -1
  259. package/dist/chunk-YJKULMWM.mjs.map +0 -1
  260. package/dist/chunk-ZJATBQ3X.mjs +0 -10
  261. package/dist/chunk-ZJATBQ3X.mjs.map +0 -1
  262. package/dist/chunk-ZWJSMASL.mjs.map +0 -1
  263. /package/dist/{chunk-7YKZ7D7U.mjs.map → chunk-ATNP3Z6G.mjs.map} +0 -0
  264. /package/dist/{chunk-4IKXV4FQ.mjs.map → chunk-Z5YZVKS5.mjs.map} +0 -0
@@ -1,37 +1,36 @@
1
1
  // @ts-nocheck
2
- import { useEffect, useRef, useState, useReducer } from 'react'
3
- import { Drawer } from '../drawer'
4
- import { Button } from '../button'
5
- import { AlertBanner } from '../alert-banner'
6
- import { Search } from '../search/search'
7
- import { DragAndDrop } from '../drag-and-drop'
8
- import { BsFillImageFill } from 'react-icons/bs'
9
- import { HiOutlineSearch } from 'react-icons/hi'
10
- import Listing from './file-listing'
11
- import PropTypes from 'prop-types'
12
-
13
-
14
- const apiUrl = '/admin/api/common/directoryinformation/'
2
+ import PropTypes from "prop-types";
3
+ import { useEffect, useReducer, useRef, useState } from "react";
4
+ import { BsFillImageFill } from "react-icons/bs";
5
+ import { HiOutlineSearch } from "react-icons/hi";
6
+ import { AlertBanner } from "../alert-banner";
7
+ import { Button } from "../button";
8
+ import { DragAndDrop } from "../drag-and-drop";
9
+ import { Drawer } from "../drawer";
10
+ import { Search } from "../search/search";
11
+ import Listing from "./file-listing";
12
+
13
+ const apiUrl = "/admin/api/common/directoryinformation/";
15
14
  const Status = Object.freeze({
16
- EMPTY: 'EMPTY',
17
- SEARCH_LOADING: 'SEARCH-LOADING',
18
- LOADING: 'LOADING',
19
- LOADED: 'LOADED',
20
- LOADED_NO_DRAG: 'LOADED_NO_DRAG',
21
- SEARCH_RESULTS: 'SEARCH-RESULTS',
22
- SEARCH_EMPTY: 'SEARCH-EMPTY',
23
- UPLOAD_ERROR: 'ERROR',
24
- DRAGGING: 'DRAGGING',
25
- })
15
+ EMPTY: "EMPTY",
16
+ SEARCH_LOADING: "SEARCH-LOADING",
17
+ LOADING: "LOADING",
18
+ LOADED: "LOADED",
19
+ LOADED_NO_DRAG: "LOADED_NO_DRAG",
20
+ SEARCH_RESULTS: "SEARCH-RESULTS",
21
+ SEARCH_EMPTY: "SEARCH-EMPTY",
22
+ UPLOAD_ERROR: "ERROR",
23
+ DRAGGING: "DRAGGING",
24
+ });
26
25
 
27
26
  const initialState = Object.freeze({
28
27
  mode: Status.LOADING,
29
- actionBtnTxt: 'I Accept',
30
- actionBtnColor: 'success',
31
- listSize: 'h-5/6',
32
- listBorder: '',
28
+ actionBtnTxt: "I Accept",
29
+ actionBtnColor: "success",
30
+ listSize: "h-5/6",
31
+ listBorder: "",
33
32
  searchDisabled: false,
34
- })
33
+ });
35
34
 
36
35
  function FilePickerReducer(state, action) {
37
36
  switch (action.type) {
@@ -39,51 +38,51 @@ function FilePickerReducer(state, action) {
39
38
  return {
40
39
  mode: Status.EMPTY,
41
40
  actionBtnTxt: 'Add Image',
42
- actionBtnColor: 'blue',
41
+ actionBtnColor: 'default',
43
42
  listSize: 'h-5/6',
44
43
  listBorder: '',
45
44
  searchDisabled: true,
46
- }
45
+ };
47
46
  case Status.LOADING:
48
- return initialState
47
+ return initialState;
49
48
  case Status.LOADED:
50
49
  return {
51
50
  mode: Status.LOADED,
52
- actionBtnTxt: 'I Accept',
53
- actionBtnColor: 'success',
54
- listSize: 'h-[68.666667%]',
55
- listBorder: 'border',
51
+ actionBtnTxt: "I Accept",
52
+ actionBtnColor: "success",
53
+ listSize: "h-[68.666667%]",
54
+ listBorder: "border",
56
55
  searchDisabled: false,
57
- }
56
+ };
58
57
  case Status.LOADED_NO_DRAG:
59
58
  return {
60
59
  mode: Status.LOADED_NO_DRAG,
61
- actionBtnTxt: 'I Accept',
62
- actionBtnColor: 'success',
63
- listSize: 'h-[87.666667%]',
64
- listBorder: 'border',
60
+ actionBtnTxt: "I Accept",
61
+ actionBtnColor: "success",
62
+ listSize: "h-[87.666667%]",
63
+ listBorder: "border",
65
64
  searchDisabled: false,
66
- }
65
+ };
67
66
  case Status.SEARCH_RESULTS:
68
67
  return {
69
68
  mode: Status.SEARCH_RESULTS,
70
- actionBtnTxt: 'I Accept',
71
- actionBtnColor: 'success',
72
- listSize: 'h-5/6',
73
- listBorder: 'border',
69
+ actionBtnTxt: "I Accept",
70
+ actionBtnColor: "success",
71
+ listSize: "h-5/6",
72
+ listBorder: "border",
74
73
  searchDisabled: false,
75
- }
74
+ };
76
75
  case Status.SEARCH_EMPTY:
77
76
  return {
78
77
  mode: Status.SEARCH_EMPTY,
79
- actionBtnTxt: 'I Accept',
80
- actionBtnColor: 'success',
81
- listSize: 'h-5/6',
82
- listBorder: '',
78
+ actionBtnTxt: "I Accept",
79
+ actionBtnColor: "success",
80
+ listSize: "h-5/6",
81
+ listBorder: "",
83
82
  searchDisabled: false,
84
- }
83
+ };
85
84
  default:
86
- throw new Error('Unknown file picker state: ' + action.page ?? '')
85
+ throw new Error("Unknown file picker state: " + action.page ?? "");
87
86
  }
88
87
  }
89
88
 
@@ -94,199 +93,237 @@ function FilePickerReducer(state, action) {
94
93
  * be handled by the parent/calling component
95
94
  */
96
95
 
97
- export function FilePicker({ appUrl, uri, show, hideDrag = false, onClose, callback }) {
98
- const searchFieldRef = useRef()
99
- const [state, dispatch] = useReducer(FilePickerReducer, { mode: Status.LOADING, footerBorder: 'border-t' })
100
- const [totalPages, setTotalPages] = useState(0)
101
- const currentPageRef = useRef(1)
102
- const [dragging, setDragging] = useState(false)
103
- const [err, setErr] = useState(false)
104
- const listAttributeRef = useRef({ pages: 0, totalEntries: 0 })
105
- const [fetchData, setFetchData] = useState(false)
106
- const [search, setSearch] = useState(null)
107
- const [selected, setSelected] = useState(null)
108
- const [files, setFiles] = useState([])
109
- const [uploadedImage, setUploadedImage] = useState('none')
96
+ export function FilePicker({
97
+ appUrl,
98
+ uri,
99
+ show,
100
+ hideDrag = false,
101
+ onClose,
102
+ callback,
103
+ }) {
104
+ const searchFieldRef = useRef();
105
+ const [state, dispatch] = useReducer(FilePickerReducer, {
106
+ mode: Status.LOADING,
107
+ footerBorder: "border-t",
108
+ });
109
+ const [totalPages, setTotalPages] = useState(0);
110
+ const currentPageRef = useRef(1);
111
+ const [dragging, setDragging] = useState(false);
112
+ const [err, setErr] = useState(false);
113
+ const listAttributeRef = useRef({ pages: 0, totalEntries: 0 });
114
+ const [fetchData, setFetchData] = useState(false);
115
+ const [search, setSearch] = useState(null);
116
+ const [selected, setSelected] = useState(null);
117
+ const [files, setFiles] = useState([]);
118
+ const [uploadedImage, setUploadedImage] = useState("none");
110
119
 
111
120
  useEffect(() => {
112
121
  // Workaround to ensure the drawer is cleared when it is first opened as its always on the DOM!
113
122
  if (show) {
114
- dispatch({ type: Status.LOADING })
115
- setSelected(null)
116
- listAttributeRef.current = { pages: 0, totalEntries: 0 }
117
- clearState()
118
- getFiles(1)
123
+ dispatch({ type: Status.LOADING });
124
+ setSelected(null);
125
+ listAttributeRef.current = { pages: 0, totalEntries: 0 };
126
+ clearState();
127
+ getFiles(1);
119
128
  }
120
- }, [show])
129
+ }, [show]);
121
130
 
122
131
  useEffect(() => {
123
132
  if (show) {
124
- currentPageRef.current = 1
125
- getFiles()
126
- setErr(false)
133
+ currentPageRef.current = 1;
134
+ getFiles();
135
+ setErr(false);
127
136
  }
128
- }, [search])
137
+ }, [search]);
129
138
 
130
139
  useEffect(() => {
131
- if (selected) setSelected(null)
132
- if (err) setErr(false)
133
- }, [state.mode])
140
+ if (selected) setSelected(null);
141
+ if (err) setErr(false);
142
+ }, [state.mode]);
134
143
 
135
144
  const clearState = () => {
136
- setFiles([])
137
- setUploadedImage('none')
138
- setFetchData(false)
139
- setSelected(null)
140
- setErr(false)
141
- }
145
+ setFiles([]);
146
+ setUploadedImage("none");
147
+ setFetchData(false);
148
+ setSelected(null);
149
+ setErr(false);
150
+ };
142
151
 
143
152
  const getFiles = async (cp = 0) => {
144
153
  try {
145
- let page = cp === 0 ? currentPageRef.current : cp
146
- let searchUri = search?.length > 0 ? `&FileNameIncludesString=${search}` : `&FileNameIncludesString=`
147
- const response = await fetch(`${appUrl}${apiUrl}?CurrentPage=${page}&PageSize=10&Uri=${uri}${searchUri}`, {
148
- method: 'GET',
149
- credentials: 'same-origin',
150
- headers: { 'Content-Type': 'application/json' },
151
- })
152
- const data = await response.json()
153
- if (search?.length > 0) dispatch({ type: Status.SEARCH_RESULTS })
154
+ let page = cp === 0 ? currentPageRef.current : cp;
155
+ let searchUri =
156
+ search?.length > 0
157
+ ? `&FileNameIncludesString=${search}`
158
+ : `&FileNameIncludesString=`;
159
+ const response = await fetch(
160
+ `${appUrl}${apiUrl}?CurrentPage=${page}&PageSize=10&Uri=${uri}${searchUri}`,
161
+ {
162
+ method: "GET",
163
+ credentials: "same-origin",
164
+ headers: { "Content-Type": "application/json" },
165
+ }
166
+ );
167
+ const data = await response.json();
168
+ if (search?.length > 0) dispatch({ type: Status.SEARCH_RESULTS });
154
169
  if (data.Items.Data.length > 0 && page > 1) {
155
- setFiles((files) => [...files, ...data.Items.Data])
170
+ setFiles((files) => [...files, ...data.Items.Data]);
156
171
  } else {
157
- setFiles(data.Items.Data)
172
+ setFiles(data.Items.Data);
158
173
  }
159
174
 
160
- listAttributeRef.current = { pages: data.Items.NumberOfPages, totalEntries: data.Items.Total }
161
- setTotalPages(data.Items.NumberOfPages)
175
+ listAttributeRef.current = {
176
+ pages: data.Items.NumberOfPages,
177
+ totalEntries: data.Items.Total,
178
+ };
179
+ setTotalPages(data.Items.NumberOfPages);
162
180
 
163
181
  if (search?.length > 0) {
164
- dispatch({ type: data.Items.Data.length > 0 ? Status.SEARCH_RESULTS : Status.SEARCH_EMPTY })
182
+ dispatch({
183
+ type:
184
+ data.Items.Data.length > 0
185
+ ? Status.SEARCH_RESULTS
186
+ : Status.SEARCH_EMPTY,
187
+ });
165
188
  } else {
166
- const loadedState = hideDrag ? Status.LOADED_NO_DRAG : Status.LOADED
167
- dispatch({ type: data.Items.Data.length > 0 ? loadedState : Status.EMPTY })
189
+ const loadedState = hideDrag ? Status.LOADED_NO_DRAG : Status.LOADED;
190
+ dispatch({
191
+ type: data.Items.Data.length > 0 ? loadedState : Status.EMPTY,
192
+ });
168
193
  }
169
194
 
170
- setUploadedImage('none')
195
+ setUploadedImage("none");
171
196
 
172
- setFetchData(false)
173
- setDragging(false)
197
+ setFetchData(false);
198
+ setDragging(false);
174
199
  } catch (error) {
175
- dispatch({ type: search?.length === 0 ? Status.SEARCH_EMPTY : Status.EMPTY })
200
+ dispatch({
201
+ type: search?.length === 0 ? Status.SEARCH_EMPTY : Status.EMPTY,
202
+ });
176
203
  }
177
- }
204
+ };
178
205
 
179
206
  const handleDragEnter = (e) => {
180
- if (hidedrag) return
207
+ if (hideDrag) return
181
208
  setDragging(true)
182
209
  searchFieldRef.current.removeFocus()
183
210
  e.preventDefault()
184
211
  }
185
212
 
186
213
  const handleDragLeave = (e) => {
187
- if (hidedrag) return
214
+ if (hideDrag) return
188
215
  setDragging(false)
189
216
  }
190
217
 
191
218
  const handleSearchRequest = (searchTerm) => {
192
- const text = searchTerm.text ?? ''
193
- const s = search ?? ''
194
- setSearch(searchTerm.text)
195
- if ((s.length > 0 && text.length === 0) || (s.length === 0 && text.length > 0 && state.mode !== Status.LOADING))
196
- dispatch({ type: Status.LOADING })
197
- }
219
+ const text = searchTerm.text ?? "";
220
+ const s = search ?? "";
221
+ setSearch(searchTerm.text);
222
+ if (
223
+ (s.length > 0 && text.length === 0) ||
224
+ (s.length === 0 && text.length > 0 && state.mode !== Status.LOADING)
225
+ )
226
+ dispatch({ type: Status.LOADING });
227
+ };
198
228
 
199
229
  const handleDropError = () => {
200
- setErr(true)
201
- setDragging(false)
202
- setUploadedImage('none')
203
- }
230
+ setErr(true);
231
+ setDragging(false);
232
+ setUploadedImage("none");
233
+ };
204
234
 
205
235
  const handleUseImage = () => {
206
- callback(`https://files.ekmcdn.com/${selected.Uri}`)
207
- handleClose()
208
- }
236
+ callback(`https://files.ekmcdn.com/${selected.Uri}`);
237
+ handleClose();
238
+ };
209
239
 
210
240
  const handleClose = () => {
211
- clearState()
212
- onClose()
213
- }
241
+ clearState();
242
+ onClose();
243
+ };
214
244
 
215
245
  const handleFileUpload = async (file) => {
216
246
  if (file == null) {
217
- setUploadedImage('error')
218
- handleDropError()
219
- return
247
+ setUploadedImage("error");
248
+ handleDropError();
249
+ return;
220
250
  }
221
251
 
222
252
  try {
253
+ const newName = sanitiseFilename(file.name)
223
254
  const arr = await getAsByteArray(file)
224
255
  const payload = {
225
256
  Path: `/${uri}/`,
226
- Name: file.name,
257
+ Name: newName,
227
258
  Bytes: getBase64(arr),
228
259
  ForceOverwriteFile: true,
229
- }
260
+ };
230
261
  const res = await fetch(`${appUrl}${apiUrl}`, {
231
- method: 'POST',
232
- credentials: 'same-origin',
233
- headers: { 'Content-Type': 'application/json' },
262
+ method: "POST",
263
+ credentials: "same-origin",
264
+ headers: { "Content-Type": "application/json" },
234
265
  body: JSON.stringify(payload),
235
- })
266
+ });
236
267
 
237
268
  if (res.status === 200) {
238
- setUploadedImage('success')
239
- setSearch(null)
240
- searchFieldRef.current.clear()
269
+ setUploadedImage("success");
270
+ setSearch(null);
271
+ searchFieldRef.current.clear();
241
272
  // dispatch({ type: Status.LOADED })
242
- setFiles([])
243
- setErr(false)
244
- getFiles(1)
273
+ setFiles([]);
274
+ setErr(false);
275
+ getFiles(1);
245
276
  } else {
246
- setUploadedImage('error')
277
+ setUploadedImage("error");
247
278
  }
248
279
  } catch (error) {
249
- setUploadedImage('error')
280
+ setUploadedImage("error");
250
281
  }
251
- }
282
+ };
252
283
 
253
284
  const handleListActions = (action) => {
254
285
  switch (action.type) {
255
- case 'FETCH_DATA':
256
- setFetchData(action.payload)
257
- if (currentPageRef.current < listAttributeRef.current.pages && !fetchData) {
286
+ case "FETCH_DATA":
287
+ setFetchData(action.payload);
288
+ if (
289
+ currentPageRef.current < listAttributeRef.current.pages &&
290
+ !fetchData
291
+ ) {
258
292
  // pass in the current page + 1 to get the next page of data then change state as the state is not updated immediately
259
- setFetchData(true)
260
- currentPageRef.current = currentPageRef.current + 1
261
- getFiles()
293
+ setFetchData(true);
294
+ currentPageRef.current = currentPageRef.current + 1;
295
+ getFiles();
262
296
  }
263
- break
264
- case 'SELECTION':
265
- setSelected(action.payload)
266
- setErr(false)
267
- break
297
+ break;
298
+ case "SELECTION":
299
+ setSelected(action.payload);
300
+ setErr(false);
301
+ break;
268
302
  default:
269
- break
303
+ break;
270
304
  }
271
- }
305
+ };
272
306
 
273
307
  const calculateListSize = () => {
274
- if (!err) return state.listSize
275
-
276
- if (state.mode === Status.LOADED) return 'h-2/4'
277
- if (state.mode === Status.SEARCH_RESULTS || state.mode === Status.LOADED_NO_DRAG) {
278
- return 'h-2/3'
308
+ if (!err) return state.listSize;
309
+
310
+ if (state.mode === Status.LOADED) return "h-2/4";
311
+ if (
312
+ state.mode === Status.SEARCH_RESULTS ||
313
+ state.mode === Status.LOADED_NO_DRAG
314
+ ) {
315
+ return "h-2/3";
279
316
  } else {
280
- return state.listSize
317
+ return state.listSize;
281
318
  }
282
- }
319
+ };
283
320
 
284
321
  const renderList = () => {
285
322
  switch (state.mode) {
286
323
  case Status.EMPTY:
287
- return <EmptyPlaceholder />
324
+ return <EmptyPlaceholder />;
288
325
  case Status.LOADING:
289
- return <LoadingPlaceholder />
326
+ return <LoadingPlaceholder />;
290
327
  case Status.SEARCH_RESULTS:
291
328
  case Status.LOADED:
292
329
  case Status.LOADED_NO_DRAG:
@@ -300,65 +337,96 @@ export function FilePicker({ appUrl, uri, show, hideDrag = false, onClose, callb
300
337
  pages={totalPages}
301
338
  callback={handleListActions}
302
339
  />
303
- )
340
+ );
304
341
  case Status.SEARCH_EMPTY:
305
- return <SearchEmptyPlaceholder />
342
+ return <SearchEmptyPlaceholder />;
306
343
  default:
307
- break
344
+ break;
308
345
  }
309
- }
346
+ };
310
347
 
311
348
  const renderContent = () => (
312
349
  <>
313
- <Search id="file-search" ref={searchFieldRef} placeholder="Search your images" disabled={state.searchDisabled} callback={handleSearchRequest} />
314
- <div className="mt-4 mb-4">
350
+ <Search
351
+ id="file-search"
352
+ ref={searchFieldRef}
353
+ placeholder="Search your images"
354
+ disabled={state.searchDisabled}
355
+ callback={handleSearchRequest}
356
+ />
357
+ <div className="mb-4 mt-4">
315
358
  {err && (
316
359
  <AlertBanner
317
360
  type="danger"
318
361
  onDismiss={() => {
319
- setErr(false)
362
+ setErr(false);
320
363
  }}
321
364
  >
322
365
  <p className="font-semibold">File could not be uploaded</p>
323
366
  <p>There was an error uploading the file. Please try again.</p>
324
367
  </AlertBanner>
325
368
  )}
326
- {state.mode !== Status.SEARCH_RESULTS && state.mode !== Status.SEARCH_EMPTY && !hideDrag && (
327
- <div className="h-68">
328
- <DragAndDrop uploaded={uploadedImage} callback={handleFileUpload} errorCallback={handleDropError} />
329
- </div>
330
- )}
331
- {(state.mode === Status.SEARCH_RESULTS || state.mode === Status.SEARCH_EMPTY) && search?.length > 0 && (
332
- <span className="ms-1 text-sm font-medium text-gray-500 md:ms-2 dark:text-gray-400">{`Showing results for..."${search}"`}</span>
333
- )}
369
+ {state.mode !== Status.SEARCH_RESULTS &&
370
+ state.mode !== Status.SEARCH_EMPTY &&
371
+ !hideDrag && (
372
+ <div className="h-68">
373
+ <DragAndDrop
374
+ uploaded={uploadedImage}
375
+ callback={handleFileUpload}
376
+ errorCallback={handleDropError}
377
+ />
378
+ </div>
379
+ )}
380
+ {(state.mode === Status.SEARCH_RESULTS ||
381
+ state.mode === Status.SEARCH_EMPTY) &&
382
+ search?.length > 0 && (
383
+ <span className="ms-1 text-sm font-medium text-gray-500 dark:text-gray-400 md:ms-2">{`Showing results for..."${search}"`}</span>
384
+ )}
334
385
  </div>
335
386
 
336
387
  {renderList()}
337
388
  </>
338
- )
389
+ );
339
390
 
340
391
  const renderOversizedDropZone = () => (
341
- <div className="h-[90.666667%] w-[93.666667%] z-50 absolute">
342
- <DragAndDrop uploaded={uploadedImage} exitCallback={handleDragLeave} callback={handleFileUpload} errorCallback={handleDropError} />
392
+ <div className="absolute z-50 h-[90.666667%] w-[93.666667%]">
393
+ <DragAndDrop
394
+ uploaded={uploadedImage}
395
+ exitCallback={handleDragLeave}
396
+ callback={handleFileUpload}
397
+ errorCallback={handleDropError}
398
+ />
343
399
  </div>
344
- )
400
+ );
345
401
 
346
402
  return (
347
- <Drawer show={show} onClose={handleClose} title="File Picker" onHide={() => {}}>
403
+ <Drawer
404
+ show={show}
405
+ onClose={handleClose}
406
+ title="File Picker"
407
+ onHide={() => {}}
408
+ >
348
409
  <div className="h-full" onDragEnter={handleDragEnter}>
349
- {show && dragging && !hidedrag && renderOversizedDropZone()}
410
+ {show && dragging && !hideDrag && renderOversizedDropZone()}
350
411
  {show && renderContent()}
351
412
  </div>
352
- <div className={`grid grid-cols-2 grid-flow-col gap-4 bottom-0 mt-0 pt-2 bg-white dark:border-gray-600`} style={{ marginTop: '-50px' }}>
413
+ <div
414
+ className={`bottom-0 mt-0 grid grid-flow-col grid-cols-2 gap-4 bg-white pt-2 dark:border-gray-600`}
415
+ style={{ marginTop: "-50px" }}
416
+ >
353
417
  <Button color="light" onClick={handleClose}>
354
418
  Close
355
419
  </Button>
356
- <Button color={state.actionBtnColor} onClick={handleUseImage} disabled={selected == null}>
420
+ <Button
421
+ color={state.actionBtnColor}
422
+ onClick={handleUseImage}
423
+ disabled={selected == null}
424
+ >
357
425
  {state.actionBtnTxt}
358
426
  </Button>
359
427
  </div>
360
428
  </Drawer>
361
- )
429
+ );
362
430
  }
363
431
 
364
432
  FilePicker.propTypes = {
@@ -368,55 +436,67 @@ FilePicker.propTypes = {
368
436
  uri: PropTypes.string.isRequired,
369
437
  /** Show the drawer */
370
438
  show: PropTypes.bool.isRequired,
371
- /** Hides the the drag and drop and assosiated functionality */
439
+ /** Hides the the drag and drop and associated functionality */
372
440
  hideDrag: PropTypes.bool,
373
441
  /** Callback to close the drawer */
374
442
  onClose: PropTypes.func.isRequired,
375
443
  /** Callback to return the selected image */
376
444
  callback: PropTypes.func.isRequired,
377
- }
445
+ };
378
446
 
379
- FilePicker.displayName = "FilePicker"
447
+ FilePicker.displayName = "FilePicker";
380
448
 
381
449
  // HELPER FUNCTIONAL COMPONENTS FOR FILE PICKER
382
450
  function EmptyPlaceholder() {
383
451
  return (
384
- <div className="flex flex-col items-center justify-center mt-5">
452
+ <div className="mt-5 flex flex-col items-center justify-center">
385
453
  <h1>
386
454
  <BsFillImageFill className="text-9xl text-gray-700" />
387
455
  </h1>
388
- <p className="mt-4 font-semibold text-2xl text-gray-900">You Have No Images</p>
389
- <p className="mt-4 text-sm text-gray-500">Images will appear here when you upload them</p>
456
+ <p className="mt-4 text-2xl font-semibold text-gray-900">
457
+ You Have No Images
458
+ </p>
459
+ <p className="mt-4 text-sm text-gray-500">
460
+ Images will appear here when you upload them
461
+ </p>
390
462
  </div>
391
- )
463
+ );
392
464
  }
393
465
 
394
466
  function LoadingPlaceholder() {
395
467
  return (
396
- <div className="h-2/3 overflow-y-auto flex items-center justify-center">
468
+ <div className="flex h-2/3 items-center justify-center overflow-y-auto">
397
469
  <div className="flex flex-col items-center justify-center">
398
470
  <h1>
399
471
  <Spinner />
400
472
  </h1>
401
- <p className="mt-4 font-semibold text-2xl text-gray-900">Loading Files</p>
402
- <p className="mt-4 text-sm text-gray-500">Don't worry, this won't take long...</p>
473
+ <p className="mt-4 text-2xl font-semibold text-gray-900">
474
+ Loading Files
475
+ </p>
476
+ <p className="mt-4 text-sm text-gray-500">
477
+ Don't worry, this won't take long...
478
+ </p>
403
479
  </div>
404
480
  </div>
405
- )
481
+ );
406
482
  }
407
483
 
408
484
  function SearchEmptyPlaceholder() {
409
485
  return (
410
- <div className="h-5/6 overflow-y-auto flex items-center justify-center">
486
+ <div className="flex h-5/6 items-center justify-center overflow-y-auto">
411
487
  <div className="flex flex-col items-center justify-center">
412
488
  <h1>
413
489
  <HiOutlineSearch className="text-9xl text-gray-700" />
414
490
  </h1>
415
- <p className="mt-4 font-semibold text-2xl text-gray-900">No Files Found</p>
416
- <p className="mt-4 text-sm text-gray-500">No files were found matching your search</p>
491
+ <p className="mt-4 text-2xl font-semibold text-gray-900">
492
+ No Files Found
493
+ </p>
494
+ <p className="mt-4 text-sm text-gray-500">
495
+ No files were found matching your search
496
+ </p>
417
497
  </div>
418
498
  </div>
419
- )
499
+ );
420
500
  }
421
501
 
422
502
  function Spinner() {
@@ -424,7 +504,7 @@ function Spinner() {
424
504
  <div role="status">
425
505
  <svg
426
506
  aria-hidden="true"
427
- className="inline w-14 h-14 text-gray-200 animate-spin dark:text-gray-600 fill-blue-600"
507
+ className="inline h-14 w-14 animate-spin fill-blue-600 text-gray-200 dark:text-gray-600"
428
508
  viewBox="0 0 100 101"
429
509
  fill="none"
430
510
  xmlns="http://www.w3.org/2000/svg"
@@ -440,22 +520,22 @@ function Spinner() {
440
520
  </svg>
441
521
  <span className="sr-only">Loading...</span>
442
522
  </div>
443
- )
523
+ );
444
524
  }
445
525
 
446
526
  // HELPER FUNCTIONS FOR FILE PICKER
447
527
 
448
528
  async function getAsByteArray(file) {
449
- return new Uint8Array(await readFile(file))
529
+ return new Uint8Array(await readFile(file));
450
530
  }
451
531
 
452
532
  function readFile(file) {
453
533
  return new Promise((resolve, reject) => {
454
- const reader = new FileReader()
455
- reader.onloadend = (event) => resolve(event.target.result)
456
- reader.onerror = (err) => reject(err)
457
- reader.readAsArrayBuffer(file)
458
- })
534
+ const reader = new FileReader();
535
+ reader.onloadend = (event) => resolve(event.target.result);
536
+ reader.onerror = (err) => reject(err);
537
+ reader.readAsArrayBuffer(file);
538
+ });
459
539
  }
460
540
 
461
541
  function getBase64(data) {
@@ -463,6 +543,10 @@ function getBase64(data) {
463
543
  return btoa(
464
544
  Array.from(data)
465
545
  .map((b) => String.fromCharCode(b))
466
- .join(''),
467
- )
546
+ .join("")
547
+ );
548
+ }
549
+
550
+ function sanitiseFilename(fileName) {
551
+ return fileName.replace(/[^a-z0-9_\.-]/gi, '_').toLowerCase()
468
552
  }