@aws-amplify/ui-react-storage 3.3.10 → 3.4.1

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 (458) hide show
  1. package/browser/package.json +8 -0
  2. package/dist/browser.js +73 -0
  3. package/dist/createAmplifyAuthAdapter-BRctUWdR.js +4868 -0
  4. package/dist/esm/browser.mjs +4 -0
  5. package/dist/esm/components/FileUploader/utils/getInput.mjs +1 -1
  6. package/dist/esm/components/StorageBrowser/ComponentsProvider.mjs +16 -0
  7. package/dist/esm/components/StorageBrowser/ErrorBoundary/ErrorBoundary.mjs +25 -0
  8. package/dist/esm/components/StorageBrowser/StorageBrowserAmplify.mjs +19 -0
  9. package/dist/esm/components/StorageBrowser/StorageBrowserDefault.mjs +42 -0
  10. package/dist/esm/components/StorageBrowser/actions/configs/context.mjs +13 -0
  11. package/dist/esm/components/StorageBrowser/actions/configs/defaults.mjs +87 -0
  12. package/dist/esm/components/StorageBrowser/actions/handlers/copy.mjs +41 -0
  13. package/dist/esm/components/StorageBrowser/actions/handlers/createFolder.mjs +38 -0
  14. package/dist/esm/components/StorageBrowser/actions/handlers/delete.mjs +22 -0
  15. package/dist/esm/components/StorageBrowser/actions/handlers/download.mjs +38 -0
  16. package/dist/esm/components/StorageBrowser/actions/handlers/listLocationItems.mjs +73 -0
  17. package/dist/esm/components/StorageBrowser/actions/handlers/listLocations.mjs +32 -0
  18. package/dist/esm/components/StorageBrowser/actions/handlers/upload.mjs +54 -0
  19. package/dist/esm/components/StorageBrowser/actions/handlers/utils.mjs +99 -0
  20. package/dist/esm/components/StorageBrowser/actions/useAction/createEnhancedListHandler.mjs +123 -0
  21. package/dist/esm/components/StorageBrowser/actions/useAction/useListLocations.mjs +18 -0
  22. package/dist/esm/components/StorageBrowser/adapters/createAmplifyAuthAdapter/createAmplifyAuthAdapter.mjs +42 -0
  23. package/dist/esm/components/StorageBrowser/adapters/createAmplifyAuthAdapter/createAmplifyListLocationsHandler.mjs +36 -0
  24. package/dist/esm/components/StorageBrowser/adapters/createAmplifyAuthAdapter/getPaginatedLocations.mjs +22 -0
  25. package/dist/esm/components/StorageBrowser/adapters/createManagedAuthAdapter/createLocationCredentialsHandler.mjs +26 -0
  26. package/dist/esm/components/StorageBrowser/adapters/createManagedAuthAdapter/createManagedAuthAdapter.mjs +40 -0
  27. package/dist/esm/components/StorageBrowser/adapters/permissionParsers.mjs +42 -0
  28. package/dist/esm/components/StorageBrowser/components/BreadcrumbNavigation.mjs +23 -0
  29. package/dist/esm/components/StorageBrowser/components/DescriptionList.mjs +16 -0
  30. package/dist/esm/components/StorageBrowser/components/DropdownMenu.mjs +31 -0
  31. package/dist/esm/components/StorageBrowser/components/Field.mjs +15 -0
  32. package/dist/esm/components/StorageBrowser/components/PaginationButton.mjs +15 -0
  33. package/dist/esm/components/StorageBrowser/components/Separator.mjs +11 -0
  34. package/dist/esm/components/StorageBrowser/components/Table.mjs +15 -0
  35. package/dist/esm/components/StorageBrowser/componentsDefault.mjs +114 -0
  36. package/dist/esm/components/StorageBrowser/composables/ActionCancel.mjs +9 -0
  37. package/dist/esm/components/StorageBrowser/composables/ActionDestination.mjs +25 -0
  38. package/dist/esm/components/StorageBrowser/composables/ActionExit.mjs +12 -0
  39. package/dist/esm/components/StorageBrowser/composables/ActionStart.mjs +9 -0
  40. package/dist/esm/components/StorageBrowser/composables/ActionsList.mjs +8 -0
  41. package/dist/esm/components/StorageBrowser/composables/AddFiles.mjs +9 -0
  42. package/dist/esm/components/StorageBrowser/composables/AddFolder.mjs +9 -0
  43. package/dist/esm/components/StorageBrowser/composables/DataRefresh.mjs +9 -0
  44. package/dist/esm/components/StorageBrowser/composables/DataTable/DataTable.mjs +77 -0
  45. package/dist/esm/components/StorageBrowser/composables/DataTable/dataCells/ButtonDataCell.mjs +25 -0
  46. package/dist/esm/components/StorageBrowser/composables/DataTable/dataCells/CheckboxDataCell.mjs +9 -0
  47. package/dist/esm/components/StorageBrowser/composables/DataTable/dataCells/DateDataCell.mjs +12 -0
  48. package/dist/esm/components/StorageBrowser/composables/DataTable/dataCells/NumberDataCell.mjs +12 -0
  49. package/dist/esm/components/StorageBrowser/composables/DataTable/dataCells/TextDataCell.mjs +14 -0
  50. package/dist/esm/components/StorageBrowser/composables/DataTable/headers/CheckboxHeader.mjs +9 -0
  51. package/dist/esm/components/StorageBrowser/composables/DataTable/headers/SortHeader.mjs +14 -0
  52. package/dist/esm/components/StorageBrowser/composables/DataTable/headers/TextHeader.mjs +12 -0
  53. package/dist/esm/components/StorageBrowser/composables/DropZone.mjs +17 -0
  54. package/dist/esm/components/StorageBrowser/composables/FolderNameField.mjs +16 -0
  55. package/dist/esm/components/StorageBrowser/composables/LoadingIndicator.mjs +13 -0
  56. package/dist/esm/components/StorageBrowser/composables/Message.mjs +30 -0
  57. package/dist/esm/components/StorageBrowser/composables/Navigation.mjs +11 -0
  58. package/dist/esm/components/StorageBrowser/composables/OverwriteToggle.mjs +12 -0
  59. package/dist/esm/components/StorageBrowser/composables/Pagination.mjs +28 -0
  60. package/dist/esm/components/StorageBrowser/composables/SearchField.mjs +22 -0
  61. package/dist/esm/components/StorageBrowser/composables/SearchSubfoldersToggle.mjs +12 -0
  62. package/dist/esm/components/StorageBrowser/composables/StatusDisplay.mjs +16 -0
  63. package/dist/esm/components/StorageBrowser/composables/Title.mjs +9 -0
  64. package/dist/esm/components/StorageBrowser/composables/context.mjs +9 -0
  65. package/dist/esm/components/StorageBrowser/composables/defaults.mjs +45 -0
  66. package/dist/esm/components/StorageBrowser/constants.mjs +4 -0
  67. package/dist/esm/components/StorageBrowser/context/elements/IconElement.mjs +40 -0
  68. package/dist/esm/components/StorageBrowser/context/elements/defaults.mjs +120 -0
  69. package/dist/esm/components/StorageBrowser/context/elements/definitions.mjs +86 -0
  70. package/dist/esm/components/StorageBrowser/controls/ActionCancelControl.mjs +12 -0
  71. package/dist/esm/components/StorageBrowser/controls/ActionDestinationControl.mjs +12 -0
  72. package/dist/esm/components/StorageBrowser/controls/ActionExitControl.mjs +12 -0
  73. package/dist/esm/components/StorageBrowser/controls/ActionStartControl.mjs +12 -0
  74. package/dist/esm/components/StorageBrowser/controls/ActionsListControl.mjs +12 -0
  75. package/dist/esm/components/StorageBrowser/controls/AddFilesControl.mjs +12 -0
  76. package/dist/esm/components/StorageBrowser/controls/AddFolderControl.mjs +12 -0
  77. package/dist/esm/components/StorageBrowser/controls/DataRefreshControl.mjs +12 -0
  78. package/dist/esm/components/StorageBrowser/controls/DataTableControl.mjs +12 -0
  79. package/dist/esm/components/StorageBrowser/controls/DropZoneControl.mjs +12 -0
  80. package/dist/esm/components/StorageBrowser/controls/FolderNameFieldControl.mjs +12 -0
  81. package/dist/esm/components/StorageBrowser/controls/LoadingIndicatorControl.mjs +12 -0
  82. package/dist/esm/components/StorageBrowser/controls/MessageControl.mjs +12 -0
  83. package/dist/esm/components/StorageBrowser/controls/NavigationControl.mjs +12 -0
  84. package/dist/esm/components/StorageBrowser/controls/OverwriteToggleControl.mjs +12 -0
  85. package/dist/esm/components/StorageBrowser/controls/PaginationControl.mjs +12 -0
  86. package/dist/esm/components/StorageBrowser/controls/SearchControl.mjs +13 -0
  87. package/dist/esm/components/StorageBrowser/controls/SearchSubfoldersToggleControl.mjs +12 -0
  88. package/dist/esm/components/StorageBrowser/controls/StatusDisplayControl.mjs +12 -0
  89. package/dist/esm/components/StorageBrowser/controls/TitleControl.mjs +12 -0
  90. package/dist/esm/components/StorageBrowser/controls/context.mjs +9 -0
  91. package/dist/esm/components/StorageBrowser/controls/hooks/compareFunctions/compareButtonData.mjs +11 -0
  92. package/dist/esm/components/StorageBrowser/controls/hooks/compareFunctions/compareDateData.mjs +11 -0
  93. package/dist/esm/components/StorageBrowser/controls/hooks/compareFunctions/compareNumberData.mjs +11 -0
  94. package/dist/esm/components/StorageBrowser/controls/hooks/compareFunctions/compareTextData.mjs +11 -0
  95. package/dist/esm/components/StorageBrowser/controls/hooks/getNavigationItems.mjs +27 -0
  96. package/dist/esm/components/StorageBrowser/controls/hooks/getNavigationParts.mjs +25 -0
  97. package/dist/esm/components/StorageBrowser/controls/hooks/useActionCancel.mjs +12 -0
  98. package/dist/esm/components/StorageBrowser/controls/hooks/useActionDestination.mjs +36 -0
  99. package/dist/esm/components/StorageBrowser/controls/hooks/useActionExit.mjs +8 -0
  100. package/dist/esm/components/StorageBrowser/controls/hooks/useActionStart.mjs +12 -0
  101. package/dist/esm/components/StorageBrowser/controls/hooks/useActionsList.mjs +12 -0
  102. package/dist/esm/components/StorageBrowser/controls/hooks/useAddFiles.mjs +12 -0
  103. package/dist/esm/components/StorageBrowser/controls/hooks/useAddFolder.mjs +12 -0
  104. package/dist/esm/components/StorageBrowser/controls/hooks/useDataRefresh.mjs +8 -0
  105. package/dist/esm/components/StorageBrowser/controls/hooks/useDataTable.mjs +106 -0
  106. package/dist/esm/components/StorageBrowser/controls/hooks/useDropZone.mjs +12 -0
  107. package/dist/esm/components/StorageBrowser/controls/hooks/useFolderNameField.mjs +17 -0
  108. package/dist/esm/components/StorageBrowser/controls/hooks/useLoadingIndicator.mjs +8 -0
  109. package/dist/esm/components/StorageBrowser/controls/hooks/useMessage.mjs +8 -0
  110. package/dist/esm/components/StorageBrowser/controls/hooks/useNavigation.mjs +28 -0
  111. package/dist/esm/components/StorageBrowser/controls/hooks/useOverwriteToggle.mjs +13 -0
  112. package/dist/esm/components/StorageBrowser/controls/hooks/useResolvedComposable.mjs +17 -0
  113. package/dist/esm/components/StorageBrowser/controls/hooks/useSearchSubfoldersToggle.mjs +12 -0
  114. package/dist/esm/components/StorageBrowser/controls/hooks/useStatusDisplay.mjs +18 -0
  115. package/dist/esm/components/StorageBrowser/controls/hooks/useTitle.mjs +10 -0
  116. package/dist/esm/components/StorageBrowser/createStorageBrowser.mjs +90 -0
  117. package/dist/esm/components/StorageBrowser/credentials/store/constants.mjs +4 -0
  118. package/dist/esm/components/StorageBrowser/credentials/store/create.mjs +30 -0
  119. package/dist/esm/components/StorageBrowser/credentials/store/registry.mjs +40 -0
  120. package/dist/esm/components/StorageBrowser/credentials/store/store.mjs +93 -0
  121. package/dist/esm/components/StorageBrowser/displayText/context.mjs +44 -0
  122. package/dist/esm/components/StorageBrowser/displayText/libraries/en/copyView.mjs +54 -0
  123. package/dist/esm/components/StorageBrowser/displayText/libraries/en/createFolderView.mjs +29 -0
  124. package/dist/esm/components/StorageBrowser/displayText/libraries/en/default.mjs +17 -0
  125. package/dist/esm/components/StorageBrowser/displayText/libraries/en/deleteView.mjs +23 -0
  126. package/dist/esm/components/StorageBrowser/displayText/libraries/en/locationDetailView.mjs +61 -0
  127. package/dist/esm/components/StorageBrowser/displayText/libraries/en/locationsView.mjs +54 -0
  128. package/dist/esm/components/StorageBrowser/displayText/libraries/en/shared.mjs +34 -0
  129. package/dist/esm/components/StorageBrowser/displayText/libraries/en/uploadView.mjs +87 -0
  130. package/dist/esm/components/StorageBrowser/providers/configuration/context.mjs +19 -0
  131. package/dist/esm/components/StorageBrowser/providers/configuration/createConfigurationProvider.mjs +23 -0
  132. package/dist/esm/components/StorageBrowser/providers/configuration/credentials/context.mjs +16 -0
  133. package/dist/esm/components/StorageBrowser/providers/configuration/credentials/useCredentialsStore.mjs +37 -0
  134. package/dist/esm/components/StorageBrowser/providers/configuration/useGetActionInputCallback.mjs +41 -0
  135. package/dist/esm/components/StorageBrowser/providers/store/StoreProvider.mjs +15 -0
  136. package/dist/esm/components/StorageBrowser/providers/store/actionType/context.mjs +16 -0
  137. package/dist/esm/components/StorageBrowser/providers/store/actionType/useActionTypeState.mjs +19 -0
  138. package/dist/esm/components/StorageBrowser/providers/store/files/context.mjs +31 -0
  139. package/dist/esm/components/StorageBrowser/providers/store/files/utils.mjs +52 -0
  140. package/dist/esm/components/StorageBrowser/providers/store/location/context.mjs +49 -0
  141. package/dist/esm/components/StorageBrowser/providers/store/locationItems/context.mjs +52 -0
  142. package/dist/esm/components/StorageBrowser/providers/store/useStore.mjs +47 -0
  143. package/dist/esm/components/StorageBrowser/tasks/constants.mjs +11 -0
  144. package/dist/esm/components/StorageBrowser/tasks/useProcessTasks.mjs +150 -0
  145. package/dist/esm/components/StorageBrowser/tasks/utils.mjs +16 -0
  146. package/dist/esm/components/StorageBrowser/validators/assertAccountId.mjs +7 -0
  147. package/dist/esm/components/StorageBrowser/validators/assertLocationData.mjs +24 -0
  148. package/dist/esm/components/StorageBrowser/validators/assertRegisterAuthListener.mjs +9 -0
  149. package/dist/esm/components/StorageBrowser/validators/isFileTooBig.mjs +4 -0
  150. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/CopyView.mjs +66 -0
  151. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/CopyViewProvider.mjs +59 -0
  152. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/FoldersMessageControl.mjs +30 -0
  153. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/FoldersPaginationControl.mjs +15 -0
  154. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/FoldersTableControl.mjs +23 -0
  155. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/getDestinationPickerTableData.mjs +35 -0
  156. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/useCopyView.mjs +79 -0
  157. package/dist/esm/components/StorageBrowser/views/LocationActionView/CopyView/useFolders.mjs +102 -0
  158. package/dist/esm/components/StorageBrowser/views/LocationActionView/CreateFolderView/CreateFolderView.mjs +36 -0
  159. package/dist/esm/components/StorageBrowser/views/LocationActionView/CreateFolderView/CreateFolderViewProvider.mjs +35 -0
  160. package/dist/esm/components/StorageBrowser/views/LocationActionView/CreateFolderView/useCreateFolderView.mjs +53 -0
  161. package/dist/esm/components/StorageBrowser/views/LocationActionView/CreateFolderView/utils.mjs +6 -0
  162. package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/DeleteView.mjs +44 -0
  163. package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/DeleteViewProvider.mjs +39 -0
  164. package/dist/esm/components/StorageBrowser/views/LocationActionView/DeleteView/useDeleteView.mjs +62 -0
  165. package/dist/esm/components/StorageBrowser/views/LocationActionView/LocationActionView.mjs +28 -0
  166. package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/UploadView.mjs +61 -0
  167. package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/UploadViewProvider.mjs +62 -0
  168. package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/constants.mjs +3 -0
  169. package/dist/esm/components/StorageBrowser/views/LocationActionView/UploadView/useUploadView.mjs +101 -0
  170. package/dist/esm/components/StorageBrowser/views/LocationActionView/constants.mjs +3 -0
  171. package/dist/esm/components/StorageBrowser/views/LocationActionView/getActionIcon.mjs +25 -0
  172. package/dist/esm/components/StorageBrowser/views/LocationActionView/getActionViewTableData.mjs +155 -0
  173. package/dist/esm/components/StorageBrowser/views/LocationActionView/getDefaultActionViewHeaders.mjs +24 -0
  174. package/dist/esm/components/StorageBrowser/views/LocationActionView/getFileTypeDisplayValue.mjs +5 -0
  175. package/dist/esm/components/StorageBrowser/views/LocationActionView/getPercentValue.mjs +3 -0
  176. package/dist/esm/components/StorageBrowser/views/LocationActionView/useActionView.mjs +20 -0
  177. package/dist/esm/components/StorageBrowser/views/LocationDetailView/LocationDetailView.mjs +56 -0
  178. package/dist/esm/components/StorageBrowser/views/LocationDetailView/LocationDetailViewProvider.mjs +60 -0
  179. package/dist/esm/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/constants.mjs +10 -0
  180. package/dist/esm/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFileRowContent.mjs +76 -0
  181. package/dist/esm/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFolderRowContent.mjs +32 -0
  182. package/dist/esm/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getLocationDetailViewTableData.mjs +77 -0
  183. package/dist/esm/components/StorageBrowser/views/LocationDetailView/useLocationDetailView.mjs +218 -0
  184. package/dist/esm/components/StorageBrowser/views/LocationsView/LocationsView.mjs +44 -0
  185. package/dist/esm/components/StorageBrowser/views/LocationsView/LocationsViewProvider.mjs +43 -0
  186. package/dist/esm/components/StorageBrowser/views/LocationsView/getLocationsViewTableData/getHeaders.mjs +29 -0
  187. package/dist/esm/components/StorageBrowser/views/LocationsView/getLocationsViewTableData/getLocationsViewTableData.mjs +76 -0
  188. package/dist/esm/components/StorageBrowser/views/LocationsView/useLocationsView.mjs +122 -0
  189. package/dist/esm/components/StorageBrowser/views/context.mjs +43 -0
  190. package/dist/esm/components/StorageBrowser/views/createUseView.mjs +47 -0
  191. package/dist/esm/components/StorageBrowser/views/hooks/usePaginate.mjs +40 -0
  192. package/dist/esm/components/StorageBrowser/views/hooks/useSearch.mjs +27 -0
  193. package/dist/esm/index.mjs +1 -0
  194. package/dist/esm/version.mjs +1 -1
  195. package/dist/index.js +16 -2
  196. package/dist/storage-browser-styles.css +482 -0
  197. package/dist/storage-browser-styles.js +2 -0
  198. package/dist/styles.css +151 -0
  199. package/dist/types/components/StorageBrowser/ComponentsProvider.d.ts +11 -0
  200. package/dist/types/components/StorageBrowser/ErrorBoundary/ErrorBoundary.d.ts +13 -0
  201. package/dist/types/components/StorageBrowser/ErrorBoundary/index.d.ts +1 -0
  202. package/dist/types/components/StorageBrowser/StorageBrowserAmplify.d.ts +5 -0
  203. package/dist/types/components/StorageBrowser/StorageBrowserDefault.d.ts +8 -0
  204. package/dist/types/components/StorageBrowser/actions/__testUtils__/permissions.d.ts +3 -0
  205. package/dist/types/components/StorageBrowser/actions/configs/context.d.ts +14 -0
  206. package/dist/types/components/StorageBrowser/actions/configs/defaults.d.ts +24 -0
  207. package/dist/types/components/StorageBrowser/actions/configs/index.d.ts +3 -0
  208. package/dist/types/components/StorageBrowser/actions/configs/types.d.ts +111 -0
  209. package/dist/types/components/StorageBrowser/actions/createUseAction.d.ts +2 -0
  210. package/dist/types/components/StorageBrowser/actions/handlers/copy.d.ts +11 -0
  211. package/dist/types/components/StorageBrowser/actions/handlers/createFolder.d.ts +14 -0
  212. package/dist/types/components/StorageBrowser/actions/handlers/delete.d.ts +12 -0
  213. package/dist/types/components/StorageBrowser/actions/handlers/download.d.ts +12 -0
  214. package/dist/types/components/StorageBrowser/actions/handlers/index.d.ts +9 -0
  215. package/dist/types/components/StorageBrowser/actions/handlers/listLocationItems.d.ts +16 -0
  216. package/dist/types/components/StorageBrowser/actions/handlers/listLocations.d.ts +31 -0
  217. package/dist/types/components/StorageBrowser/actions/handlers/types.d.ts +102 -0
  218. package/dist/types/components/StorageBrowser/actions/handlers/upload.d.ts +21 -0
  219. package/dist/types/components/StorageBrowser/actions/handlers/utils.d.ts +17 -0
  220. package/dist/types/components/StorageBrowser/actions/index.d.ts +4 -0
  221. package/dist/types/components/StorageBrowser/actions/types.d.ts +8 -0
  222. package/dist/types/components/StorageBrowser/actions/useAction/createEnhancedListHandler.d.ts +45 -0
  223. package/dist/types/components/StorageBrowser/actions/useAction/index.d.ts +1 -0
  224. package/dist/types/components/StorageBrowser/actions/useAction/useListLocations.d.ts +8 -0
  225. package/dist/types/components/StorageBrowser/adapters/createAmplifyAuthAdapter/createAmplifyAuthAdapter.d.ts +5 -0
  226. package/dist/types/components/StorageBrowser/adapters/createAmplifyAuthAdapter/createAmplifyListLocationsHandler.d.ts +2 -0
  227. package/dist/types/components/StorageBrowser/adapters/createAmplifyAuthAdapter/getPaginatedLocations.d.ts +6 -0
  228. package/dist/types/components/StorageBrowser/adapters/createAmplifyAuthAdapter/index.d.ts +1 -0
  229. package/dist/types/components/StorageBrowser/adapters/createManagedAuthAdapter/createLocationCredentialsHandler.d.ts +10 -0
  230. package/dist/types/components/StorageBrowser/adapters/createManagedAuthAdapter/createManagedAuthAdapter.d.ts +9 -0
  231. package/dist/types/components/StorageBrowser/adapters/createManagedAuthAdapter/index.d.ts +1 -0
  232. package/dist/types/components/StorageBrowser/adapters/index.d.ts +3 -0
  233. package/dist/types/components/StorageBrowser/adapters/permissionParsers.d.ts +5 -0
  234. package/dist/types/components/StorageBrowser/adapters/types.d.ts +27 -0
  235. package/dist/types/components/StorageBrowser/components/BreadcrumbNavigation.d.ts +13 -0
  236. package/dist/types/components/StorageBrowser/components/Checkbox.d.ts +11 -0
  237. package/dist/types/components/StorageBrowser/components/DescriptionList.d.ts +11 -0
  238. package/dist/types/components/StorageBrowser/components/DropdownMenu.d.ts +20 -0
  239. package/dist/types/components/StorageBrowser/components/EmptyMessage.d.ts +6 -0
  240. package/dist/types/components/StorageBrowser/components/Field.d.ts +9 -0
  241. package/dist/types/components/StorageBrowser/components/PaginationButton.d.ts +10 -0
  242. package/dist/types/components/StorageBrowser/components/Separator.d.ts +2 -0
  243. package/dist/types/components/StorageBrowser/components/Table.d.ts +15 -0
  244. package/dist/types/components/StorageBrowser/components/types.d.ts +8 -0
  245. package/dist/types/components/StorageBrowser/componentsDefault.d.ts +2 -0
  246. package/dist/types/components/StorageBrowser/composables/ActionCancel.d.ts +7 -0
  247. package/dist/types/components/StorageBrowser/composables/ActionDestination.d.ts +8 -0
  248. package/dist/types/components/StorageBrowser/composables/ActionExit.d.ts +7 -0
  249. package/dist/types/components/StorageBrowser/composables/ActionStart.d.ts +7 -0
  250. package/dist/types/components/StorageBrowser/composables/ActionsList.d.ts +15 -0
  251. package/dist/types/components/StorageBrowser/composables/AddFiles.d.ts +7 -0
  252. package/dist/types/components/StorageBrowser/composables/AddFolder.d.ts +7 -0
  253. package/dist/types/components/StorageBrowser/composables/DataRefresh.d.ts +6 -0
  254. package/dist/types/components/StorageBrowser/composables/DataTable/DataTable.d.ts +11 -0
  255. package/dist/types/components/StorageBrowser/composables/DataTable/dataCells/ButtonDataCell.d.ts +12 -0
  256. package/dist/types/components/StorageBrowser/composables/DataTable/dataCells/CheckboxDataCell.d.ts +10 -0
  257. package/dist/types/components/StorageBrowser/composables/DataTable/dataCells/DateDataCell.d.ts +8 -0
  258. package/dist/types/components/StorageBrowser/composables/DataTable/dataCells/NumberDataCell.d.ts +8 -0
  259. package/dist/types/components/StorageBrowser/composables/DataTable/dataCells/TextDataCell.d.ts +9 -0
  260. package/dist/types/components/StorageBrowser/composables/DataTable/headers/CheckboxHeader.d.ts +10 -0
  261. package/dist/types/components/StorageBrowser/composables/DataTable/headers/SortHeader.d.ts +10 -0
  262. package/dist/types/components/StorageBrowser/composables/DataTable/headers/TextHeader.d.ts +7 -0
  263. package/dist/types/components/StorageBrowser/composables/DataTable/index.d.ts +2 -0
  264. package/dist/types/components/StorageBrowser/composables/DataTable/types.d.ts +35 -0
  265. package/dist/types/components/StorageBrowser/composables/DropZone.d.ts +6 -0
  266. package/dist/types/components/StorageBrowser/composables/FolderNameField.d.ts +11 -0
  267. package/dist/types/components/StorageBrowser/composables/LoadingIndicator.d.ts +6 -0
  268. package/dist/types/components/StorageBrowser/composables/Message.d.ts +10 -0
  269. package/dist/types/components/StorageBrowser/composables/Navigation.d.ts +11 -0
  270. package/dist/types/components/StorageBrowser/composables/OverwriteToggle.d.ts +8 -0
  271. package/dist/types/components/StorageBrowser/composables/Pagination.d.ts +8 -0
  272. package/dist/types/components/StorageBrowser/composables/SearchField.d.ts +13 -0
  273. package/dist/types/components/StorageBrowser/composables/SearchSubfoldersToggle.d.ts +7 -0
  274. package/dist/types/components/StorageBrowser/composables/StatusDisplay.d.ts +11 -0
  275. package/dist/types/components/StorageBrowser/composables/Title.d.ts +5 -0
  276. package/dist/types/components/StorageBrowser/composables/context.d.ts +5 -0
  277. package/dist/types/components/StorageBrowser/composables/defaults.d.ts +2 -0
  278. package/dist/types/components/StorageBrowser/composables/index.d.ts +3 -0
  279. package/dist/types/components/StorageBrowser/composables/types.d.ts +46 -0
  280. package/dist/types/components/StorageBrowser/constants.d.ts +2 -0
  281. package/dist/types/components/StorageBrowser/context/elements/IconElement.d.ts +7 -0
  282. package/dist/types/components/StorageBrowser/context/elements/defaults.d.ts +34 -0
  283. package/dist/types/components/StorageBrowser/context/elements/definitions.d.ts +94 -0
  284. package/dist/types/components/StorageBrowser/context/elements/index.d.ts +3 -0
  285. package/dist/types/components/StorageBrowser/controls/ActionCancelControl.d.ts +2 -0
  286. package/dist/types/components/StorageBrowser/controls/ActionDestinationControl.d.ts +2 -0
  287. package/dist/types/components/StorageBrowser/controls/ActionExitControl.d.ts +2 -0
  288. package/dist/types/components/StorageBrowser/controls/ActionStartControl.d.ts +2 -0
  289. package/dist/types/components/StorageBrowser/controls/ActionsListControl.d.ts +2 -0
  290. package/dist/types/components/StorageBrowser/controls/AddFilesControl.d.ts +2 -0
  291. package/dist/types/components/StorageBrowser/controls/AddFolderControl.d.ts +2 -0
  292. package/dist/types/components/StorageBrowser/controls/DataRefreshControl.d.ts +2 -0
  293. package/dist/types/components/StorageBrowser/controls/DataTableControl.d.ts +2 -0
  294. package/dist/types/components/StorageBrowser/controls/DropZoneControl.d.ts +4 -0
  295. package/dist/types/components/StorageBrowser/controls/FolderNameFieldControl.d.ts +2 -0
  296. package/dist/types/components/StorageBrowser/controls/LoadingIndicatorControl.d.ts +2 -0
  297. package/dist/types/components/StorageBrowser/controls/MessageControl.d.ts +2 -0
  298. package/dist/types/components/StorageBrowser/controls/NavigationControl.d.ts +2 -0
  299. package/dist/types/components/StorageBrowser/controls/OverwriteToggleControl.d.ts +2 -0
  300. package/dist/types/components/StorageBrowser/controls/PaginationControl.d.ts +2 -0
  301. package/dist/types/components/StorageBrowser/controls/SearchControl.d.ts +2 -0
  302. package/dist/types/components/StorageBrowser/controls/SearchSubfoldersToggleControl.d.ts +2 -0
  303. package/dist/types/components/StorageBrowser/controls/StatusDisplayControl.d.ts +2 -0
  304. package/dist/types/components/StorageBrowser/controls/TitleControl.d.ts +2 -0
  305. package/dist/types/components/StorageBrowser/controls/context.d.ts +5 -0
  306. package/dist/types/components/StorageBrowser/controls/hooks/compareFunctions/compareButtonData.d.ts +2 -0
  307. package/dist/types/components/StorageBrowser/controls/hooks/compareFunctions/compareDateData.d.ts +3 -0
  308. package/dist/types/components/StorageBrowser/controls/hooks/compareFunctions/compareNumberData.d.ts +3 -0
  309. package/dist/types/components/StorageBrowser/controls/hooks/compareFunctions/compareTextData.d.ts +3 -0
  310. package/dist/types/components/StorageBrowser/controls/hooks/getNavigationItems.d.ts +9 -0
  311. package/dist/types/components/StorageBrowser/controls/hooks/getNavigationParts.d.ts +8 -0
  312. package/dist/types/components/StorageBrowser/controls/hooks/useActionCancel.d.ts +2 -0
  313. package/dist/types/components/StorageBrowser/controls/hooks/useActionDestination.d.ts +2 -0
  314. package/dist/types/components/StorageBrowser/controls/hooks/useActionExit.d.ts +2 -0
  315. package/dist/types/components/StorageBrowser/controls/hooks/useActionStart.d.ts +2 -0
  316. package/dist/types/components/StorageBrowser/controls/hooks/useActionsList.d.ts +2 -0
  317. package/dist/types/components/StorageBrowser/controls/hooks/useAddFiles.d.ts +2 -0
  318. package/dist/types/components/StorageBrowser/controls/hooks/useAddFolder.d.ts +2 -0
  319. package/dist/types/components/StorageBrowser/controls/hooks/useDataRefresh.d.ts +2 -0
  320. package/dist/types/components/StorageBrowser/controls/hooks/useDataTable.d.ts +2 -0
  321. package/dist/types/components/StorageBrowser/controls/hooks/useDropZone.d.ts +6 -0
  322. package/dist/types/components/StorageBrowser/controls/hooks/useFolderNameField.d.ts +2 -0
  323. package/dist/types/components/StorageBrowser/controls/hooks/useLoadingIndicator.d.ts +2 -0
  324. package/dist/types/components/StorageBrowser/controls/hooks/useMessage.d.ts +2 -0
  325. package/dist/types/components/StorageBrowser/controls/hooks/useNavigation.d.ts +2 -0
  326. package/dist/types/components/StorageBrowser/controls/hooks/useOverwriteToggle.d.ts +2 -0
  327. package/dist/types/components/StorageBrowser/controls/hooks/useResolvedComposable.d.ts +3 -0
  328. package/dist/types/components/StorageBrowser/controls/hooks/useSearchSubfoldersToggle.d.ts +2 -0
  329. package/dist/types/components/StorageBrowser/controls/hooks/useStatusDisplay.d.ts +2 -0
  330. package/dist/types/components/StorageBrowser/controls/hooks/useTitle.d.ts +2 -0
  331. package/dist/types/components/StorageBrowser/controls/types.d.ts +90 -0
  332. package/dist/types/components/StorageBrowser/createStorageBrowser.d.ts +7 -0
  333. package/dist/types/components/StorageBrowser/credentials/store/constants.d.ts +2 -0
  334. package/dist/types/components/StorageBrowser/credentials/store/create.d.ts +2 -0
  335. package/dist/types/components/StorageBrowser/credentials/store/index.d.ts +1 -0
  336. package/dist/types/components/StorageBrowser/credentials/store/registry.d.ts +21 -0
  337. package/dist/types/components/StorageBrowser/credentials/store/store.d.ts +41 -0
  338. package/dist/types/components/StorageBrowser/credentials/types.d.ts +26 -0
  339. package/dist/types/components/StorageBrowser/displayText/context.d.ts +10 -0
  340. package/dist/types/components/StorageBrowser/displayText/en.d.ts +9 -0
  341. package/dist/types/components/StorageBrowser/displayText/index.d.ts +3 -0
  342. package/dist/types/components/StorageBrowser/displayText/libraries/en/copyView.d.ts +2 -0
  343. package/dist/types/components/StorageBrowser/displayText/libraries/en/createFolderView.d.ts +2 -0
  344. package/dist/types/components/StorageBrowser/displayText/libraries/en/default.d.ts +2 -0
  345. package/dist/types/components/StorageBrowser/displayText/libraries/en/deleteView.d.ts +2 -0
  346. package/dist/types/components/StorageBrowser/displayText/libraries/en/index.d.ts +1 -0
  347. package/dist/types/components/StorageBrowser/displayText/libraries/en/locationDetailView.d.ts +3 -0
  348. package/dist/types/components/StorageBrowser/displayText/libraries/en/locationsView.d.ts +3 -0
  349. package/dist/types/components/StorageBrowser/displayText/libraries/en/shared.d.ts +3 -0
  350. package/dist/types/components/StorageBrowser/displayText/libraries/en/uploadView.d.ts +2 -0
  351. package/dist/types/components/StorageBrowser/displayText/libraries/index.d.ts +1 -0
  352. package/dist/types/components/StorageBrowser/displayText/types.d.ts +151 -0
  353. package/dist/types/components/StorageBrowser/index.d.ts +4 -0
  354. package/dist/types/components/StorageBrowser/providers/configuration/context.d.ts +6 -0
  355. package/dist/types/components/StorageBrowser/providers/configuration/createConfigurationProvider.d.ts +3 -0
  356. package/dist/types/components/StorageBrowser/providers/configuration/credentials/context.d.ts +6 -0
  357. package/dist/types/components/StorageBrowser/providers/configuration/credentials/index.d.ts +2 -0
  358. package/dist/types/components/StorageBrowser/providers/configuration/credentials/types.d.ts +20 -0
  359. package/dist/types/components/StorageBrowser/providers/configuration/credentials/useCredentialsStore.d.ts +8 -0
  360. package/dist/types/components/StorageBrowser/providers/configuration/index.d.ts +4 -0
  361. package/dist/types/components/StorageBrowser/providers/configuration/types.d.ts +19 -0
  362. package/dist/types/components/StorageBrowser/providers/configuration/useGetActionInputCallback.d.ts +7 -0
  363. package/dist/types/components/StorageBrowser/providers/index.d.ts +2 -0
  364. package/dist/types/components/StorageBrowser/providers/store/StoreProvider.d.ts +8 -0
  365. package/dist/types/components/StorageBrowser/providers/store/actionType/context.d.ts +6 -0
  366. package/dist/types/components/StorageBrowser/providers/store/actionType/index.d.ts +2 -0
  367. package/dist/types/components/StorageBrowser/providers/store/actionType/types.d.ts +16 -0
  368. package/dist/types/components/StorageBrowser/providers/store/actionType/useActionTypeState.d.ts +2 -0
  369. package/dist/types/components/StorageBrowser/providers/store/files/context.d.ts +6 -0
  370. package/dist/types/components/StorageBrowser/providers/store/files/index.d.ts +2 -0
  371. package/dist/types/components/StorageBrowser/providers/store/files/types.d.ts +23 -0
  372. package/dist/types/components/StorageBrowser/providers/store/files/utils.d.ts +8 -0
  373. package/dist/types/components/StorageBrowser/providers/store/index.d.ts +3 -0
  374. package/dist/types/components/StorageBrowser/providers/store/location/context.d.ts +58 -0
  375. package/dist/types/components/StorageBrowser/providers/store/location/index.d.ts +1 -0
  376. package/dist/types/components/StorageBrowser/providers/store/locationItems/context.d.ts +27 -0
  377. package/dist/types/components/StorageBrowser/providers/store/locationItems/index.d.ts +1 -0
  378. package/dist/types/components/StorageBrowser/providers/store/useStore.d.ts +12 -0
  379. package/dist/types/components/StorageBrowser/storage-internal.d.ts +1 -0
  380. package/dist/types/components/StorageBrowser/tasks/constants.d.ts +2 -0
  381. package/dist/types/components/StorageBrowser/tasks/index.d.ts +3 -0
  382. package/dist/types/components/StorageBrowser/tasks/types.d.ts +30 -0
  383. package/dist/types/components/StorageBrowser/tasks/useProcessTasks.d.ts +4 -0
  384. package/dist/types/components/StorageBrowser/tasks/utils.d.ts +4 -0
  385. package/dist/types/components/StorageBrowser/types.d.ts +39 -0
  386. package/dist/types/components/StorageBrowser/validators/assertAccountId.d.ts +1 -0
  387. package/dist/types/components/StorageBrowser/validators/assertLocationData.d.ts +3 -0
  388. package/dist/types/components/StorageBrowser/validators/assertRegisterAuthListener.d.ts +2 -0
  389. package/dist/types/components/StorageBrowser/validators/index.d.ts +4 -0
  390. package/dist/types/components/StorageBrowser/validators/isFileTooBig.d.ts +2 -0
  391. package/dist/types/components/StorageBrowser/views/LocationActionView/CopyView/CopyView.d.ts +2 -0
  392. package/dist/types/components/StorageBrowser/views/LocationActionView/CopyView/CopyViewProvider.d.ts +3 -0
  393. package/dist/types/components/StorageBrowser/views/LocationActionView/CopyView/FoldersMessageControl.d.ts +16 -0
  394. package/dist/types/components/StorageBrowser/views/LocationActionView/CopyView/FoldersPaginationControl.d.ts +9 -0
  395. package/dist/types/components/StorageBrowser/views/LocationActionView/CopyView/FoldersTableControl.d.ts +15 -0
  396. package/dist/types/components/StorageBrowser/views/LocationActionView/CopyView/getDestinationPickerTableData.d.ts +10 -0
  397. package/dist/types/components/StorageBrowser/views/LocationActionView/CopyView/index.d.ts +3 -0
  398. package/dist/types/components/StorageBrowser/views/LocationActionView/CopyView/types.d.ts +50 -0
  399. package/dist/types/components/StorageBrowser/views/LocationActionView/CopyView/useCopyView.d.ts +2 -0
  400. package/dist/types/components/StorageBrowser/views/LocationActionView/CopyView/useFolders.d.ts +16 -0
  401. package/dist/types/components/StorageBrowser/views/LocationActionView/CreateFolderView/CreateFolderView.d.ts +2 -0
  402. package/dist/types/components/StorageBrowser/views/LocationActionView/CreateFolderView/CreateFolderViewProvider.d.ts +3 -0
  403. package/dist/types/components/StorageBrowser/views/LocationActionView/CreateFolderView/index.d.ts +3 -0
  404. package/dist/types/components/StorageBrowser/views/LocationActionView/CreateFolderView/types.d.ts +24 -0
  405. package/dist/types/components/StorageBrowser/views/LocationActionView/CreateFolderView/useCreateFolderView.d.ts +2 -0
  406. package/dist/types/components/StorageBrowser/views/LocationActionView/CreateFolderView/utils.d.ts +1 -0
  407. package/dist/types/components/StorageBrowser/views/LocationActionView/DeleteView/DeleteView.d.ts +2 -0
  408. package/dist/types/components/StorageBrowser/views/LocationActionView/DeleteView/DeleteViewProvider.d.ts +3 -0
  409. package/dist/types/components/StorageBrowser/views/LocationActionView/DeleteView/index.d.ts +3 -0
  410. package/dist/types/components/StorageBrowser/views/LocationActionView/DeleteView/types.d.ts +23 -0
  411. package/dist/types/components/StorageBrowser/views/LocationActionView/DeleteView/useDeleteView.d.ts +2 -0
  412. package/dist/types/components/StorageBrowser/views/LocationActionView/LocationActionView.d.ts +6 -0
  413. package/dist/types/components/StorageBrowser/views/LocationActionView/UploadView/UploadView.d.ts +2 -0
  414. package/dist/types/components/StorageBrowser/views/LocationActionView/UploadView/UploadViewProvider.d.ts +3 -0
  415. package/dist/types/components/StorageBrowser/views/LocationActionView/UploadView/constants.d.ts +1 -0
  416. package/dist/types/components/StorageBrowser/views/LocationActionView/UploadView/index.d.ts +3 -0
  417. package/dist/types/components/StorageBrowser/views/LocationActionView/UploadView/types.d.ts +36 -0
  418. package/dist/types/components/StorageBrowser/views/LocationActionView/UploadView/useUploadView.d.ts +2 -0
  419. package/dist/types/components/StorageBrowser/views/LocationActionView/constants.d.ts +1 -0
  420. package/dist/types/components/StorageBrowser/views/LocationActionView/getActionIcon.d.ts +3 -0
  421. package/dist/types/components/StorageBrowser/views/LocationActionView/getActionViewTableData.d.ts +16 -0
  422. package/dist/types/components/StorageBrowser/views/LocationActionView/getDefaultActionViewHeaders.d.ts +5 -0
  423. package/dist/types/components/StorageBrowser/views/LocationActionView/getFileTypeDisplayValue.d.ts +1 -0
  424. package/dist/types/components/StorageBrowser/views/LocationActionView/getPercentValue.d.ts +1 -0
  425. package/dist/types/components/StorageBrowser/views/LocationActionView/index.d.ts +7 -0
  426. package/dist/types/components/StorageBrowser/views/LocationActionView/types.d.ts +37 -0
  427. package/dist/types/components/StorageBrowser/views/LocationActionView/useActionView.d.ts +2 -0
  428. package/dist/types/components/StorageBrowser/views/LocationDetailView/LocationDetailView.d.ts +6 -0
  429. package/dist/types/components/StorageBrowser/views/LocationDetailView/LocationDetailViewProvider.d.ts +3 -0
  430. package/dist/types/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/constants.d.ts +2 -0
  431. package/dist/types/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFileRowContent.d.ts +15 -0
  432. package/dist/types/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFolderRowContent.d.ts +6 -0
  433. package/dist/types/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getLocationDetailViewTableData.d.ts +19 -0
  434. package/dist/types/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/index.d.ts +1 -0
  435. package/dist/types/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/types.d.ts +4 -0
  436. package/dist/types/components/StorageBrowser/views/LocationDetailView/index.d.ts +3 -0
  437. package/dist/types/components/StorageBrowser/views/LocationDetailView/types.d.ts +77 -0
  438. package/dist/types/components/StorageBrowser/views/LocationDetailView/useLocationDetailView.d.ts +6 -0
  439. package/dist/types/components/StorageBrowser/views/LocationsView/LocationsView.d.ts +2 -0
  440. package/dist/types/components/StorageBrowser/views/LocationsView/LocationsViewProvider.d.ts +3 -0
  441. package/dist/types/components/StorageBrowser/views/LocationsView/getLocationsViewTableData/getHeaders.d.ts +8 -0
  442. package/dist/types/components/StorageBrowser/views/LocationsView/getLocationsViewTableData/getLocationsViewTableData.d.ts +9 -0
  443. package/dist/types/components/StorageBrowser/views/LocationsView/getLocationsViewTableData/index.d.ts +1 -0
  444. package/dist/types/components/StorageBrowser/views/LocationsView/getLocationsViewTableData/types.d.ts +4 -0
  445. package/dist/types/components/StorageBrowser/views/LocationsView/index.d.ts +3 -0
  446. package/dist/types/components/StorageBrowser/views/LocationsView/types.d.ts +50 -0
  447. package/dist/types/components/StorageBrowser/views/LocationsView/useLocationsView.d.ts +7 -0
  448. package/dist/types/components/StorageBrowser/views/context.d.ts +16 -0
  449. package/dist/types/components/StorageBrowser/views/createUseView.d.ts +19 -0
  450. package/dist/types/components/StorageBrowser/views/hooks/usePaginate.d.ts +15 -0
  451. package/dist/types/components/StorageBrowser/views/hooks/useSearch.d.ts +13 -0
  452. package/dist/types/components/StorageBrowser/views/index.d.ts +4 -0
  453. package/dist/types/components/StorageBrowser/views/types.d.ts +12 -0
  454. package/dist/types/index.d.ts +1 -0
  455. package/dist/types/styles/storage-browser-styles.d.ts +1 -0
  456. package/dist/types/version.d.ts +1 -1
  457. package/package.json +36 -8
  458. /package/dist/types/{styles.d.ts → styles/styles.d.ts} +0 -0
@@ -0,0 +1,4868 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var uiReactCore = require('@aws-amplify/ui-react-core');
5
+ var uiReact = require('@aws-amplify/ui-react');
6
+ var elements = require('@aws-amplify/ui-react-core/elements');
7
+ var internal = require('@aws-amplify/ui-react/internal');
8
+ var ui = require('@aws-amplify/ui');
9
+ var internals = require('@aws-amplify/storage/internals');
10
+ var storage = require('aws-amplify/storage');
11
+ var awsAmplify = require('aws-amplify');
12
+ var auth = require('aws-amplify/auth');
13
+ var utils = require('aws-amplify/utils');
14
+
15
+ function _interopNamespace(e) {
16
+ if (e && e.__esModule) return e;
17
+ var n = Object.create(null);
18
+ if (e) {
19
+ Object.keys(e).forEach(function (k) {
20
+ if (k !== 'default') {
21
+ var d = Object.getOwnPropertyDescriptor(e, k);
22
+ Object.defineProperty(n, k, d.get ? d : {
23
+ enumerable: true,
24
+ get: function () { return e[k]; }
25
+ });
26
+ }
27
+ });
28
+ }
29
+ n["default"] = e;
30
+ return Object.freeze(n);
31
+ }
32
+
33
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
34
+
35
+ const defaultValue$9 = {};
36
+ const { useComposables, ComposablesProvider } = uiReactCore.createContextUtilities({
37
+ contextName: 'Composables',
38
+ defaultValue: defaultValue$9,
39
+ });
40
+
41
+ function Button(props) {
42
+ const { disabled, variant } = props;
43
+ switch (variant) {
44
+ case 'menu-item':
45
+ return (React__namespace["default"].createElement(uiReact.Button, { ...props, variation: "link", size: "small", borderRadius: "0", justifyContent: "flex-start" }));
46
+ case 'cancel':
47
+ return (React__namespace["default"].createElement(uiReact.Button, { ...props, size: "small", variation: "link", colorTheme: "error" }));
48
+ case 'primary':
49
+ return (React__namespace["default"].createElement(uiReact.Button, { ...props, isDisabled: disabled, size: "small", variation: "primary" }));
50
+ case 'exit':
51
+ return (React__namespace["default"].createElement(uiReact.Button, { ...props, size: "small", paddingInline: "xs", variation: "link" }));
52
+ case 'message-dismiss':
53
+ return (React__namespace["default"].createElement(uiReact.Button, { ...props, size: "small", variation: "link", colorTheme: "overlay" }));
54
+ case 'navigate':
55
+ case 'paginate-current':
56
+ case 'paginate-next':
57
+ case 'paginate-previous':
58
+ return (React__namespace["default"].createElement(uiReact.Button, { ...props, size: "small", paddingInline: "xs", variation: "link" }));
59
+ case 'menu-toggle':
60
+ case 'download':
61
+ case 'refresh':
62
+ case 'sort':
63
+ return React__namespace["default"].createElement(uiReact.Button, { ...props, size: "small", variation: "link" });
64
+ case 'table-data':
65
+ return (React__namespace["default"].createElement(uiReact.Button, { ...props, variation: "link", size: "small", textDecoration: "underline" }));
66
+ default:
67
+ return React__namespace["default"].createElement(uiReact.Button, { ...props, size: "small" });
68
+ }
69
+ }
70
+ function DescriptionTerm(props) {
71
+ return React__namespace["default"].createElement(uiReact.View, { ...props, as: "dt", fontWeight: "bold" });
72
+ }
73
+ function Label(props) {
74
+ const { children } = props;
75
+ return React__namespace["default"].createElement(uiReact.Label, { ...props }, children);
76
+ }
77
+ function Input(props) {
78
+ const { type } = props;
79
+ if (type === 'checkbox') {
80
+ return React__namespace["default"].createElement("input", { ...props });
81
+ }
82
+ return React__namespace["default"].createElement(uiReact.Input, { ...props });
83
+ }
84
+ function Heading(props) {
85
+ return (React__namespace["default"].createElement(uiReact.Heading, { ...props, level: 2, fontSize: "large", fontWeight: "bold", alignSelf: "center" }));
86
+ }
87
+ function Span(props) {
88
+ const { variant } = props;
89
+ if (variant === 'navigation-text' || variant === 'destination-text') {
90
+ return (React__namespace["default"].createElement(uiReact.View, { ...props, as: "span", padding: "xs", color: "font.secondary", fontSize: "small" }));
91
+ }
92
+ return React__namespace["default"].createElement(uiReact.View, { ...props, as: "span" });
93
+ }
94
+ function Table$1(props) {
95
+ return (React__namespace["default"].createElement(uiReact.Table, { ...props, size: "small", lineHeight: "small", variation: "striped" }));
96
+ }
97
+ function TableBody(props) {
98
+ return React__namespace["default"].createElement(uiReact.TableBody, { ...props });
99
+ }
100
+ function TableHead(props) {
101
+ return React__namespace["default"].createElement(uiReact.TableHead, { ...props });
102
+ }
103
+ function TableDataCell(props) {
104
+ return React__namespace["default"].createElement(uiReact.TableCell, { ...props });
105
+ }
106
+ function TableRow(props) {
107
+ return React__namespace["default"].createElement(uiReact.TableRow, { ...props });
108
+ }
109
+ function TableHeader(props) {
110
+ return React__namespace["default"].createElement(uiReact.TableCell, { as: "th", ...props });
111
+ }
112
+ function Text(props) {
113
+ const { variant } = props;
114
+ switch (variant) {
115
+ case 'field-error':
116
+ return React__namespace["default"].createElement(uiReact.Text, { ...props, color: "font.error", margin: "0" });
117
+ default:
118
+ return React__namespace["default"].createElement(uiReact.Text, { ...props });
119
+ }
120
+ }
121
+ function View({ variant, ...props }) {
122
+ switch (variant) {
123
+ case 'menu-list':
124
+ return (React__namespace["default"].createElement(uiReact.View, { ...props, marginTop: "2px", borderRadius: "medium", boxShadow: "0 1px 3px hsla(210, 50%, 10%, 0.25)", backgroundColor: "background.primary", padding: "small" }));
125
+ case 'info':
126
+ case 'warning':
127
+ case 'success':
128
+ case 'error':
129
+ return (React__namespace["default"].createElement(uiReact.Message, { ...props, hasIcon: false, colorTheme: variant },
130
+ React__namespace["default"].createElement(uiReact.Flex, { gap: "small", alignItems: "center" }, props.children)));
131
+ case 'empty-message':
132
+ return (React__namespace["default"].createElement(uiReact.Message, { ...props, colorTheme: "neutral" },
133
+ React__namespace["default"].createElement(uiReact.Flex, { justifyContent: "center" }, props.children)));
134
+ default:
135
+ return React__namespace["default"].createElement(uiReact.View, { ...props });
136
+ }
137
+ }
138
+ const Nav = (props) => (React__namespace["default"].createElement(uiReact.View, { ...props, as: "nav" }));
139
+ const elementsDefault = {
140
+ Button,
141
+ DescriptionTerm,
142
+ Input,
143
+ Label,
144
+ Nav,
145
+ Heading,
146
+ Span,
147
+ Table: Table$1,
148
+ TableBody,
149
+ TableDataCell,
150
+ TableHead,
151
+ TableHeader,
152
+ TableRow,
153
+ Text,
154
+ View,
155
+ };
156
+
157
+ const DEFAULT_ICON_ATTRIBUTES = {
158
+ 'aria-hidden': true,
159
+ width: '24',
160
+ height: '24',
161
+ // `viewBox` coordinates map to `path` data in STORAGE_BROWSER_ICON_PATHS
162
+ viewBox: '0 -960 960 960',
163
+ fill: 'none',
164
+ xmlns: 'http://www.w3.org/2000/svg',
165
+ role: 'img',
166
+ };
167
+ const BaseIconElement = elements.defineBaseElement({
168
+ type: 'svg',
169
+ displayName: 'Icon',
170
+ });
171
+ const getIconProps = ({ variant, ...props }) => {
172
+ const pathData = variant ? internal.STORAGE_BROWSER_ICON_PATHS[variant] : undefined;
173
+ const children = pathData ? (React__namespace["default"].createElement("path", { d: pathData, fill: "currentColor" })) : undefined;
174
+ return {
175
+ ...DEFAULT_ICON_ATTRIBUTES,
176
+ ...props,
177
+ children: props.children ?? children,
178
+ variant,
179
+ };
180
+ };
181
+ const IconElement = (props) => {
182
+ const { variant } = props;
183
+ const icons = internal.useIcons('storageBrowser');
184
+ const icon = variant ? icons?.[variant] : undefined;
185
+ if (icon) {
186
+ return React__namespace["default"].createElement(React__namespace["default"].Fragment, null, icon);
187
+ }
188
+ return React__namespace["default"].createElement(BaseIconElement, { ...getIconProps(props) });
189
+ };
190
+
191
+ const DescriptionListElement = elements.defineBaseElement({
192
+ type: 'dl',
193
+ displayName: 'DescriptionList',
194
+ });
195
+ const DescriptionTermElement = elements.defineBaseElement({
196
+ type: 'dt',
197
+ displayName: 'DescriptionTerm',
198
+ });
199
+ const DescriptionDetailsElement = elements.defineBaseElement({
200
+ type: 'dd',
201
+ displayName: 'DescriptionDetails',
202
+ });
203
+ const LabelElement = elements.defineBaseElement({
204
+ type: 'label',
205
+ displayName: 'Label',
206
+ });
207
+ const NavElement = elements.defineBaseElement({
208
+ type: 'nav',
209
+ displayName: 'Nav',
210
+ });
211
+ elements.defineBaseElement({
212
+ type: 'p',
213
+ displayName: 'Text',
214
+ });
215
+ const OrderedListElement = elements.defineBaseElement({
216
+ type: 'ol',
217
+ displayName: 'OrderedList',
218
+ });
219
+ elements.defineBaseElement({
220
+ type: 'ul',
221
+ displayName: 'UnorderedList',
222
+ });
223
+ const ListItemElement = elements.defineBaseElement({
224
+ type: 'li',
225
+ displayName: 'ListItem',
226
+ });
227
+ const TableElement = elements.defineBaseElement({
228
+ type: 'table',
229
+ displayName: 'Table',
230
+ });
231
+ const TableDataCellElement = elements.defineBaseElement({
232
+ type: 'td',
233
+ displayName: 'TableDataCell',
234
+ });
235
+ const TableRowElement = elements.defineBaseElement({
236
+ type: 'tr',
237
+ displayName: 'TableRow',
238
+ });
239
+ const TableHeaderElement = elements.defineBaseElement({
240
+ type: 'th',
241
+ displayName: 'TableHeader',
242
+ });
243
+ const TableHeadElement = elements.defineBaseElement({
244
+ type: 'thead',
245
+ displayName: 'TableHead',
246
+ });
247
+ const TableBodyElement = elements.defineBaseElement({
248
+ type: 'tbody',
249
+ displayName: 'TableBody',
250
+ });
251
+ const HeadingElement = elements.defineBaseElement({
252
+ type: 'h2',
253
+ displayName: 'Title',
254
+ });
255
+ elements.defineBaseElement({
256
+ type: 'svg',
257
+ displayName: 'ProgressBar',
258
+ });
259
+ const InputElement = elements.defineBaseElement({
260
+ type: 'input',
261
+ displayName: 'Input',
262
+ });
263
+ const ButtonElement = elements.defineBaseElement({ type: 'button', displayName: 'Button' });
264
+ const ViewElement = elements.defineBaseElement({
265
+ type: 'div',
266
+ displayName: 'View',
267
+ });
268
+ const SpanElement = elements.defineBaseElement({
269
+ type: 'span',
270
+ displayName: 'Span',
271
+ });
272
+
273
+ const STORAGE_BROWSER_BLOCK_TO_BE_UPDATED = 'storage-browser';
274
+ const STORAGE_BROWSER_BLOCK = 'amplify-storage-browser';
275
+
276
+ const ActionCancel = ({ onCancel, isDisabled, label, }) => (React__namespace["default"].createElement(ButtonElement, { variant: "cancel", className: `${STORAGE_BROWSER_BLOCK}__cancel`, onClick: onCancel, disabled: isDisabled }, label));
277
+
278
+ function Separator() {
279
+ return (React__namespace["default"].createElement(SpanElement, { "aria-hidden": true, className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__breadcrumb-separator` }, "/"));
280
+ }
281
+
282
+ const Breadcrumb = ({ isCurrent, name, onNavigate, }) => {
283
+ const isNavigable = ui.isFunction(onNavigate);
284
+ return (React__namespace["default"].createElement(ListItemElement, { "aria-current": isCurrent ? 'page' : undefined, className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__breadcrumb-list-item` },
285
+ React__namespace["default"].createElement(React__namespace["default"].Fragment, null,
286
+ !isCurrent && isNavigable ? (React__namespace["default"].createElement(ButtonElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__breadcrumb-button`, onClick: onNavigate, variant: "navigate" }, name)) : (React__namespace["default"].createElement(SpanElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__breadcrumb-text`, variant: "navigation-text" }, name)),
287
+ !isCurrent ? React__namespace["default"].createElement(Separator, null) : null)));
288
+ };
289
+ function BreadcrumbNavigation({ breadcrumbs, role = 'navigation', }) {
290
+ return (React__namespace["default"].createElement(NavElement, { "aria-label": 'Breadcrumb', className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__breadcrumb`, role: role },
291
+ React__namespace["default"].createElement(OrderedListElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__breadcrumb-list` }, breadcrumbs.map(({ isCurrent, name, onNavigate }, index) => {
292
+ return (React__namespace["default"].createElement(Breadcrumb, { key: `${index}-breadcrumb-${name}`, isCurrent: isCurrent, name: name, onNavigate: onNavigate }));
293
+ }))));
294
+ }
295
+
296
+ const ActionDestination$1 = ({ isNavigable, items, label, }) => {
297
+ if (!items.length) {
298
+ return null;
299
+ }
300
+ return (React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__destination` }, isNavigable ? (React__namespace["default"].createElement(React__namespace["default"].Fragment, null,
301
+ React__namespace["default"].createElement(SpanElement, null, `${label}:`),
302
+ React__namespace["default"].createElement(BreadcrumbNavigation, { breadcrumbs: items, role: "complementary" }))) : (React__namespace["default"].createElement(DescriptionListElement, { className: `${STORAGE_BROWSER_BLOCK}__description-list`, role: "list" },
303
+ React__namespace["default"].createElement(DescriptionTermElement, { className: `${STORAGE_BROWSER_BLOCK}__description-term`, role: "term" }, `${label}:`),
304
+ items.map(({ name }, index) => {
305
+ return (React__namespace["default"].createElement(React__namespace["default"].Fragment, { key: `action-destination-item-${name}-${index}` },
306
+ React__namespace["default"].createElement(DescriptionDetailsElement, { className: `${STORAGE_BROWSER_BLOCK}__description-details`, role: "definition" },
307
+ React__namespace["default"].createElement(SpanElement, { variant: "destination-text" }, name)),
308
+ index === items.length - 1 ? null : React__namespace["default"].createElement(Separator, null)));
309
+ })))));
310
+ };
311
+
312
+ const ActionExit = ({ onExit, isDisabled = false, label, }) => (React__namespace["default"].createElement(ButtonElement, { className: `${STORAGE_BROWSER_BLOCK}__exit`, variant: "exit", onClick: onExit, disabled: isDisabled },
313
+ React__namespace["default"].createElement(IconElement, { className: `${STORAGE_BROWSER_BLOCK}__action-exit-icon`, variant: "exit" }),
314
+ ' ',
315
+ label));
316
+
317
+ const ActionStart = ({ onStart, isDisabled, label, }) => (React__namespace["default"].createElement(ButtonElement, { variant: "primary", className: `${STORAGE_BROWSER_BLOCK}__action-start`, onClick: onStart, disabled: isDisabled }, label));
318
+
319
+ function MenuItem({ isDisabled, icon, label, onClick, }) {
320
+ return (React__namespace["default"].createElement(ButtonElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__menu-item`, disabled: isDisabled, role: 'menuitem', onClick: onClick, variant: "menu-item" },
321
+ icon && (React__namespace["default"].createElement(IconElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__menu-item-icon`, variant: icon })),
322
+ label));
323
+ }
324
+ function DropdownMenu({ isDisabled = false, items, onItemSelect, }) {
325
+ const [isOpen, setIsOpen] = React__namespace["default"].useState(false);
326
+ return (React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__menu` },
327
+ React__namespace["default"].createElement(ButtonElement, { "aria-label": "Menu Toggle", className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__menu-toggle`, disabled: isDisabled || !items?.length, "data-testid": "MENU_TOGGLE", onClick: () => {
328
+ setIsOpen((prev) => !prev);
329
+ }, variant: "menu-toggle" },
330
+ React__namespace["default"].createElement(IconElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__menu-toggle-icon`, variant: "vertical-kebab" })),
331
+ React__namespace["default"].createElement(ViewElement, { "aria-label": "Menu Items", className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__menu-list${isOpen
332
+ ? ` ${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__menu-list--open`
333
+ : ''}`, "data-testid": "MENU_LIST", role: "menu", variant: "menu-list" }, items
334
+ .filter(({ isHidden }) => !isHidden)
335
+ .map(({ icon, id, isDisabled, label }) => {
336
+ return (React__namespace["default"].createElement(MenuItem, { key: `menu-item-${id}`, isDisabled: isDisabled, icon: icon, label: label, onClick: () => {
337
+ setIsOpen(false);
338
+ onItemSelect?.(id);
339
+ } }));
340
+ }))));
341
+ }
342
+
343
+ const ActionsList$1 = ({ isDisabled, items, onActionSelect, }) => {
344
+ return (React__namespace["default"].createElement(DropdownMenu, { isDisabled: isDisabled, items: items.map((item) => ({ ...item, id: item.actionType })), onItemSelect: onActionSelect }));
345
+ };
346
+
347
+ const AddFiles = ({ onAddFiles, isDisabled, label, }) => (React__namespace["default"].createElement(ButtonElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__add-files`, disabled: isDisabled, onClick: onAddFiles, variant: "add-files" }, label));
348
+
349
+ const AddFolder = ({ onAddFolder, isDisabled, label, }) => (React__namespace["default"].createElement(ButtonElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__add-folder`, disabled: isDisabled, onClick: onAddFolder, variant: "add-folder" }, label));
350
+
351
+ const DataRefresh$1 = ({ onRefresh, isDisabled = false, }) => (React__namespace["default"].createElement(ButtonElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__data-refresh`, "aria-label": "Refresh data", variant: "refresh", onClick: onRefresh, disabled: isDisabled },
352
+ React__namespace["default"].createElement(IconElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__data-refresh-icon`, variant: "refresh" })));
353
+
354
+ const Table = ({ headers, rows }) => {
355
+ return (React__namespace["default"].createElement(TableElement, { className: `${STORAGE_BROWSER_BLOCK}__table` },
356
+ React__namespace["default"].createElement(TableHeadElement, { className: `${STORAGE_BROWSER_BLOCK}__table-head` }, headers.length ? (React__namespace["default"].createElement(TableRowElement, { className: `${STORAGE_BROWSER_BLOCK}__table-row` }, headers.map(({ key, content }) => (React__namespace["default"].createElement(TableHeaderElement, { key: key, className: `${STORAGE_BROWSER_BLOCK}__table-header` }, content))))) : null),
357
+ React__namespace["default"].createElement(TableBodyElement, { className: `${STORAGE_BROWSER_BLOCK}__table-body` }, rows?.map(({ key, content }) => (React__namespace["default"].createElement(TableRowElement, { key: key, className: `${STORAGE_BROWSER_BLOCK}__table-row` }, content.map(({ key, content, type }) => {
358
+ return type === 'header' ? (React__namespace["default"].createElement(TableHeaderElement, { key: key, className: `${STORAGE_BROWSER_BLOCK}__table-header`, role: "rowheader" }, content)) : (React__namespace["default"].createElement(TableDataCellElement, { key: key, className: `${STORAGE_BROWSER_BLOCK}__table-data-cell` }, content));
359
+ })))))));
360
+ };
361
+
362
+ const SortHeader = ({ content }) => {
363
+ const { label, sortDirection, onSort } = content;
364
+ return (React__namespace["default"].createElement(ButtonElement, { variant: "sort", className: `${STORAGE_BROWSER_BLOCK}__table-sort-header`, onClick: onSort },
365
+ label,
366
+ React__namespace["default"].createElement(IconElement, { variant: `sort-${sortDirection ?? 'indeterminate'}` })));
367
+ };
368
+
369
+ const TextHeader = ({ content }) => {
370
+ const { text } = content;
371
+ return (React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__table-text-header` }, text));
372
+ };
373
+
374
+ const ButtonDataCell = ({ content, }) => {
375
+ const { ariaLabel, isDisabled, icon, label, onClick } = content;
376
+ // Special handling for icon-only cancel buttons
377
+ let buttonVariant = 'table-data';
378
+ const isIconOnlyButton = !!icon && !label;
379
+ if (isIconOnlyButton && icon === 'cancel') {
380
+ buttonVariant = 'cancel';
381
+ }
382
+ return (React__namespace["default"].createElement(ButtonElement, { className: [
383
+ `${STORAGE_BROWSER_BLOCK}__table-button-data-cell`,
384
+ isIconOnlyButton
385
+ ? `${STORAGE_BROWSER_BLOCK}__table-button-data-cell--icon-only`
386
+ : '',
387
+ ].join(' '), disabled: isDisabled, onClick: onClick, "aria-label": ariaLabel, variant: buttonVariant },
388
+ icon && (React__namespace["default"].createElement(IconElement, { className: `${STORAGE_BROWSER_BLOCK}__table-button-data-cell-icon--${icon}`, variant: icon })),
389
+ label));
390
+ };
391
+
392
+ const DateDataCell = ({ content, }) => {
393
+ const { value, displayValue } = content;
394
+ return (React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__table-date-data-cell` }, displayValue ?? value?.toLocaleString()));
395
+ };
396
+
397
+ const NumberDataCell = ({ content, }) => {
398
+ const { displayValue, value } = content;
399
+ return (React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__table-number-data-cell` }, displayValue ?? value));
400
+ };
401
+
402
+ const CheckboxDataCell = ({ content, }) => {
403
+ const { checked = false, label, onSelect, id } = content;
404
+ return (React__namespace["default"].createElement(uiReact.Checkbox, { name: label ?? '', checked: checked, labelHidden: true, label: label, onChange: onSelect, id: id }));
405
+ };
406
+
407
+ const TextDataCell = ({ content, }) => {
408
+ const { icon, text } = content;
409
+ return (React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__table-text-data-cell` },
410
+ icon && (React__namespace["default"].createElement(IconElement, { className: `${STORAGE_BROWSER_BLOCK}__table-text-data-cell-icon ${STORAGE_BROWSER_BLOCK}__table-text-data-cell-icon--${icon}`, variant: icon })),
411
+ React__namespace["default"].createElement(SpanElement, { className: `${STORAGE_BROWSER_BLOCK}__table-text-data-cell-text`, title: text }, text)));
412
+ };
413
+
414
+ const CheckboxHeader = ({ content, }) => {
415
+ const { checked = false, label, onSelect, id } = content;
416
+ return (React__namespace["default"].createElement(uiReact.Checkbox, { name: label ?? '', checked: checked, labelHidden: true, label: label, onChange: onSelect, id: id }));
417
+ };
418
+
419
+ const DataTable = ({ headers, rows, }) => {
420
+ const mappedHeaders = headers.map(({ key, content, type }) => {
421
+ switch (type) {
422
+ case 'checkbox': {
423
+ return {
424
+ key,
425
+ content: React__namespace["default"].createElement(CheckboxHeader, { content: content }),
426
+ };
427
+ }
428
+ case 'sort': {
429
+ return {
430
+ key,
431
+ content: React__namespace["default"].createElement(SortHeader, { content: content }),
432
+ };
433
+ }
434
+ case 'text':
435
+ default: {
436
+ return {
437
+ key,
438
+ content: React__namespace["default"].createElement(TextHeader, { content: content }),
439
+ };
440
+ }
441
+ }
442
+ });
443
+ const mappedRows = rows.map(({ key, content }) => ({
444
+ key,
445
+ content: content.map(({ key, content, type }) => {
446
+ switch (type) {
447
+ case 'button': {
448
+ return {
449
+ key,
450
+ content: React__namespace["default"].createElement(ButtonDataCell, { content: content }),
451
+ };
452
+ }
453
+ case 'checkbox': {
454
+ return {
455
+ key,
456
+ content: React__namespace["default"].createElement(CheckboxDataCell, { content: content }),
457
+ };
458
+ }
459
+ case 'date': {
460
+ return {
461
+ key,
462
+ content: React__namespace["default"].createElement(DateDataCell, { content: content }),
463
+ };
464
+ }
465
+ case 'number': {
466
+ return {
467
+ key,
468
+ content: React__namespace["default"].createElement(NumberDataCell, { content: content }),
469
+ };
470
+ }
471
+ case 'text':
472
+ default: {
473
+ return {
474
+ key,
475
+ content: React__namespace["default"].createElement(TextDataCell, { content: content }),
476
+ };
477
+ }
478
+ }
479
+ }),
480
+ }));
481
+ return React__namespace["default"].createElement(Table, { headers: mappedHeaders, rows: mappedRows });
482
+ };
483
+
484
+ const DropZone = ({ children, onDropFiles, }) => {
485
+ const { dragState, ...dropHandlers } = uiReactCore.useDropZone({
486
+ onDropComplete: ({ acceptedFiles }) => {
487
+ onDropFiles?.(acceptedFiles);
488
+ },
489
+ });
490
+ return (React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__drop-zone ${STORAGE_BROWSER_BLOCK}__drop-zone${dragState !== 'inactive' ? '--active' : ''}`, ...dropHandlers }, children));
491
+ };
492
+
493
+ function Field({ 'aria-describedby': ariaDescribedBy = 'fieldError', className = `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__field`, children, label, icon = null, id, ...props }) {
494
+ return (React__namespace["default"].createElement(ViewElement, { className: className },
495
+ icon,
496
+ label ? (React__namespace["default"].createElement(LabelElement, { className: `${className}__label`, htmlFor: id }, label)) : null,
497
+ React__namespace["default"].createElement(InputElement, { ...props, "aria-describedby": ariaDescribedBy, className: `${className}-input`, id: id, type: 'text' }),
498
+ children));
499
+ }
500
+
501
+ function FolderNameField$1({ id, isDisabled, label, onChange, onValidate, placeholder, validationMessage, }) {
502
+ const handleValidate = ({ target: { value }, }) => {
503
+ onValidate?.(value);
504
+ };
505
+ return (React__namespace["default"].createElement(Field, { "aria-describedby": id, "aria-invalid": !!validationMessage, className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__folder-name-field`, disabled: isDisabled, id: id, label: label, onBlur: handleValidate, onChange: (event) => {
506
+ if (validationMessage)
507
+ handleValidate?.(event);
508
+ onChange?.(event.target.value);
509
+ }, placeholder: placeholder, type: "text" }, validationMessage));
510
+ }
511
+
512
+ function LoadingIndicator$1({ label, isLoading, }) {
513
+ return !isLoading ? null : (React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__loading-indicator` },
514
+ React__namespace["default"].createElement(IconElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__loading-indicator-icon`, variant: "loading" }),
515
+ React__namespace["default"].createElement(SpanElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__loading-indicator-label`, "aria-live": "polite" }, label)));
516
+ }
517
+
518
+ const Message = ({ content, id, onDismiss, type, }) => {
519
+ let ariaLabel;
520
+ switch (type) {
521
+ case 'error':
522
+ ariaLabel = 'Error';
523
+ break;
524
+ case 'info':
525
+ ariaLabel = 'Information';
526
+ break;
527
+ case 'warning':
528
+ ariaLabel = 'Warning';
529
+ break;
530
+ case 'success':
531
+ ariaLabel = 'Success';
532
+ break;
533
+ }
534
+ return !content ? null : (React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__message`, role: "alert", variant: type },
535
+ React__namespace["default"].createElement(IconElement, { variant: type, "aria-label": ariaLabel }),
536
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__message-content` }, content),
537
+ !onDismiss ? null : (React__namespace["default"].createElement(ButtonElement, { onClick: () => onDismiss(id), className: `${STORAGE_BROWSER_BLOCK}__message-dismiss`, variant: "message-dismiss", "aria-label": "Dismiss message", role: "button" },
538
+ React__namespace["default"].createElement(IconElement, { variant: "dismiss", className: `${STORAGE_BROWSER_BLOCK}__message-dismiss-icon` })))));
539
+ };
540
+
541
+ const Navigation$1 = ({ items, }) => {
542
+ if (!items.length) {
543
+ return null;
544
+ }
545
+ return React__namespace["default"].createElement(BreadcrumbNavigation, { breadcrumbs: items });
546
+ };
547
+
548
+ const OVERWRITE_TOGGLE_ID = 'overwrite-toggle';
549
+ const OverwriteToggle$1 = ({ isOverwritingEnabled, isDisabled, label, onToggle, }) => (React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__overwrite-toggle` },
550
+ React__namespace["default"].createElement(InputElement, { checked: isOverwritingEnabled, disabled: isDisabled, id: OVERWRITE_TOGGLE_ID, onChange: onToggle, type: "checkbox" }),
551
+ React__namespace["default"].createElement(LabelElement, { htmlFor: OVERWRITE_TOGGLE_ID }, label)));
552
+
553
+ function PaginationButton({ isDisabled, onClick, type, }) {
554
+ if (!type)
555
+ return null;
556
+ const buttonType = `paginate-${type}`;
557
+ return (React__namespace["default"].createElement(ButtonElement, { "aria-label": `Go to ${type} page`, className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__pagination-button--${buttonType}`, disabled: isDisabled, onClick: onClick, variant: buttonType },
558
+ React__namespace["default"].createElement(IconElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__pagination-button-icon`, variant: buttonType })));
559
+ }
560
+
561
+ const Pagination$1 = ({ page, hasNextPage, onPaginate, highestPageVisited, }) => {
562
+ if (!page)
563
+ return null;
564
+ return (React__namespace["default"].createElement(NavElement, { "aria-label": 'Pagination', className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__pagination` },
565
+ React__namespace["default"].createElement(OrderedListElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__pagination-list` },
566
+ React__namespace["default"].createElement(ListItemElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__pagination-list-item` },
567
+ React__namespace["default"].createElement(PaginationButton, { isDisabled: page <= 1, onClick: () => {
568
+ if (onPaginate)
569
+ onPaginate(page - 1);
570
+ }, type: "previous" })),
571
+ React__namespace["default"].createElement(ListItemElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__pagination-list-item` },
572
+ React__namespace["default"].createElement(SpanElement, { "aria-label": `Page ${page}`, "aria-current": "page", className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__pagination-current-page` }, page)),
573
+ React__namespace["default"].createElement(ListItemElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__pagination-list-item` },
574
+ React__namespace["default"].createElement(PaginationButton, { isDisabled: !highestPageVisited ||
575
+ (page >= highestPageVisited && !hasNextPage), onClick: () => {
576
+ if (onPaginate)
577
+ onPaginate(page + 1);
578
+ }, type: "next" })))));
579
+ };
580
+
581
+ const SearchField$1 = ({ id, label, clearLabel, submitLabel, onSearch, onClear, placeholder, query = '', onQueryChange, }) => {
582
+ // FIXME: focus not returning to input field after clear
583
+ return (React__namespace["default"].createElement(React__namespace["default"].Fragment, null,
584
+ React__namespace["default"].createElement(Field, { id: id, label: label, icon: React__namespace["default"].createElement(IconElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__search-field-icon`, variant: "search" }), className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__search-field`, variant: "search", onChange: (e) => {
585
+ onQueryChange?.(e.target.value);
586
+ }, placeholder: placeholder, onKeyUp: (event) => {
587
+ if (event.key === 'Enter') {
588
+ onSearch?.();
589
+ }
590
+ }, value: query }, query ? (React__namespace["default"].createElement(ButtonElement, { "aria-label": clearLabel, className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__search-field-clear`, onClick: onClear, variant: "refresh" },
591
+ React__namespace["default"].createElement(IconElement, { variant: "dismiss" }))) : null),
592
+ React__namespace["default"].createElement(ButtonElement, { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__search-submit`, onClick: onSearch }, submitLabel)));
593
+ };
594
+
595
+ const SEARCH_SUBFOLDERS_TOGGLE_ID = 'search-subfolders-toggle';
596
+ const SearchSubfoldersToggle$1 = ({ isSearchingSubfolders, label, onToggle, }) => (React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__search-subfolders-toggle` },
597
+ React__namespace["default"].createElement(InputElement, { checked: isSearchingSubfolders, id: SEARCH_SUBFOLDERS_TOGGLE_ID, onChange: onToggle, type: "checkbox" }),
598
+ React__namespace["default"].createElement(LabelElement, { htmlFor: SEARCH_SUBFOLDERS_TOGGLE_ID }, label)));
599
+
600
+ const Description = ({ term, details }) => {
601
+ return (React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__description` },
602
+ React__namespace["default"].createElement(DescriptionTermElement, { className: `${STORAGE_BROWSER_BLOCK}__description-term`, role: "term" }, term),
603
+ React__namespace["default"].createElement(DescriptionDetailsElement, { className: `${STORAGE_BROWSER_BLOCK}__description-details`, role: "definition" }, details)));
604
+ };
605
+ const DescriptionList = ({ descriptions, className = '', }) => {
606
+ return (React__namespace["default"].createElement(DescriptionListElement, { className: `${STORAGE_BROWSER_BLOCK}__description-list ${className}`, role: "list" }, descriptions.map(({ term, details }, index) => (React__namespace["default"].createElement(Description, { term: term, details: details, key: `${index}-description-${term}` })))));
607
+ };
608
+
609
+ const StatusDisplay$1 = ({ statuses, total, }) => {
610
+ if (!statuses?.length) {
611
+ return null;
612
+ }
613
+ const descriptions = statuses.map(({ name, count }) => ({
614
+ term: name,
615
+ details: `${count}/${total}`,
616
+ }));
617
+ return (React__namespace["default"].createElement(DescriptionList, { className: `${STORAGE_BROWSER_BLOCK}__status-display`, descriptions: descriptions }));
618
+ };
619
+
620
+ const Title$1 = ({ title }) => (React__namespace["default"].createElement(HeadingElement, { className: `${STORAGE_BROWSER_BLOCK}__title` }, title));
621
+
622
+ const DEFAULT_COMPOSABLES = {
623
+ ActionCancel,
624
+ ActionDestination: ActionDestination$1,
625
+ ActionExit,
626
+ ActionStart,
627
+ ActionsList: ActionsList$1,
628
+ AddFiles,
629
+ AddFolder,
630
+ DataRefresh: DataRefresh$1,
631
+ DataTable,
632
+ DropZone,
633
+ FolderNameField: FolderNameField$1,
634
+ LoadingIndicator: LoadingIndicator$1,
635
+ Message,
636
+ Navigation: Navigation$1,
637
+ OverwriteToggle: OverwriteToggle$1,
638
+ Pagination: Pagination$1,
639
+ SearchSubfoldersToggle: SearchSubfoldersToggle$1,
640
+ SearchField: SearchField$1,
641
+ StatusDisplay: StatusDisplay$1,
642
+ Title: Title$1,
643
+ };
644
+
645
+ function ComponentsProvider(props) {
646
+ const { children, composables, elements: elements$1 } = props;
647
+ return (React__namespace["default"].createElement(elements.ElementsProvider, { elements: elements$1 },
648
+ React__namespace["default"].createElement(ComposablesProvider, { composables: composables }, children)));
649
+ }
650
+
651
+ const OverwriteToggle = ({ isDisabled, isOverwritingEnabled, label = '', onToggle, }) => {
652
+ return (React__namespace.createElement(uiReact.CheckboxField, { name: label, label: label, labelPosition: "end", isDisabled: isDisabled, checked: isOverwritingEnabled, onChange: () => {
653
+ onToggle?.();
654
+ } }));
655
+ };
656
+ const SearchSubfoldersToggle = ({ isSearchingSubfolders, label = '', onToggle, }) => {
657
+ return (React__namespace.createElement(uiReact.CheckboxField, { name: label, label: label, labelPosition: "end", checked: isSearchingSubfolders, onChange: () => {
658
+ onToggle?.();
659
+ } }));
660
+ };
661
+ const Pagination = ({ page = 1, onPaginate, hasNextPage, highestPageVisited, }) => {
662
+ return (React__namespace.createElement(uiReact.Pagination, { currentPage: page, totalPages: highestPageVisited ?? 1, hasMorePages: hasNextPage, siblingCount: 1, onChange: (index) => {
663
+ onPaginate?.(index ?? 0);
664
+ }, onNext: () => {
665
+ onPaginate?.(page + 1);
666
+ }, onPrevious: () => {
667
+ onPaginate?.(page - 1);
668
+ } }));
669
+ };
670
+ const SearchField = ({ onQueryChange, onSearch, onClear, placeholder, label, query, }) => {
671
+ return (React__namespace.createElement(uiReact.SearchField, { label: label, size: "small", clearButtonLabel: "Clear search", placeholder: placeholder, value: query, onChange: (e) => {
672
+ onQueryChange?.(e.target.value);
673
+ }, onSubmit: () => {
674
+ onSearch?.();
675
+ }, onClear: () => {
676
+ onClear?.();
677
+ } }));
678
+ };
679
+ const Navigation = ({ items }) => {
680
+ return (React__namespace.createElement(uiReact.Breadcrumbs.Container, null, items.map((item, i) => {
681
+ return (React__namespace.createElement(uiReact.Breadcrumbs.Item, { key: i },
682
+ React__namespace.createElement(uiReact.Breadcrumbs.Link, { as: item.isCurrent ? 'span' : 'button', isCurrent: item.isCurrent, onClick: item.onNavigate }, item.name),
683
+ item.isCurrent ? null : React__namespace.createElement(uiReact.Breadcrumbs.Separator, null)));
684
+ })));
685
+ };
686
+ const LoadingIndicator = ({ isLoading }) => {
687
+ if (isLoading) {
688
+ return (React__namespace.createElement(uiReact.Loader, { className: "amplify-storage-browser__loader", variation: "linear", size: "small" }));
689
+ }
690
+ };
691
+ const FolderNameField = ({ onChange, label, placeholder, validationMessage, onValidate, }) => {
692
+ const handleValidate = ({ target: { value }, }) => {
693
+ onValidate?.(value);
694
+ };
695
+ return (React__namespace.createElement(uiReact.TextField, { label: label, placeholder: placeholder, errorMessage: validationMessage, hasError: !!validationMessage, onBlur: handleValidate, onChange: (event) => {
696
+ const { value } = event.target;
697
+ handleValidate?.(event);
698
+ onChange?.(value);
699
+ } }));
700
+ };
701
+ const DataRefresh = ({ onRefresh }) => {
702
+ return (React__namespace.createElement(uiReact.Button, { onClick: () => {
703
+ onRefresh?.();
704
+ }, "aria-label": "Refresh data" },
705
+ React__namespace.createElement(IconElement, { className: "amplify-icon", variant: "refresh" })));
706
+ };
707
+ const ActionsList = ({ items, onActionSelect, isDisabled, }) => {
708
+ return (React__namespace.createElement(uiReact.Menu, { isDisabled: isDisabled, trigger: React__namespace.createElement(uiReact.Button, { ariaLabel: "Menu Toggle" },
709
+ React__namespace.createElement(IconElement, { className: "amplify-icon", variant: "menu" })) }, items
710
+ .filter(({ isHidden }) => !isHidden)
711
+ .map(({ actionType, icon, label, isDisabled }, i) => {
712
+ return (React__namespace.createElement(uiReact.MenuItem, { key: i, size: "small", gap: "xs", isDisabled: isDisabled, onClick: () => {
713
+ onActionSelect?.(actionType);
714
+ } },
715
+ icon && React__namespace.createElement(IconElement, { variant: icon }),
716
+ label));
717
+ })));
718
+ };
719
+ const StatusDisplay = ({ statuses, total }) => {
720
+ if (!statuses?.length) {
721
+ return null;
722
+ }
723
+ return (React__namespace.createElement(uiReact.View, { as: "dl", className: `${STORAGE_BROWSER_BLOCK}__status-display` }, statuses.map(({ name, count }, i) => (React__namespace.createElement(uiReact.View, { as: "div", className: `${STORAGE_BROWSER_BLOCK}__status`, key: i },
724
+ React__namespace.createElement(uiReact.View, { as: "dt", className: `${STORAGE_BROWSER_BLOCK}__status-label` }, name),
725
+ React__namespace.createElement(uiReact.View, { as: "dd", className: `${STORAGE_BROWSER_BLOCK}__status-value` }, `${count}/${total}`))))));
726
+ };
727
+ const ActionDestination = ({ isNavigable, items, label, }) => {
728
+ if (!items.length) {
729
+ return null;
730
+ }
731
+ return (React__namespace.createElement(uiReact.View, { as: "dl", className: `${STORAGE_BROWSER_BLOCK}__destination` },
732
+ React__namespace.createElement(uiReact.View, { as: "dt", className: `${STORAGE_BROWSER_BLOCK}__destination-label` }, label),
733
+ React__namespace.createElement(uiReact.View, { as: "dd", className: `${STORAGE_BROWSER_BLOCK}__destination-value` },
734
+ React__namespace.createElement(uiReact.Breadcrumbs.Container, null, items.map((item, i) => {
735
+ return (React__namespace.createElement(uiReact.Breadcrumbs.Item, { key: i },
736
+ isNavigable ? (React__namespace.createElement(uiReact.Breadcrumbs.Link, { as: item.isCurrent ? 'span' : 'button', isCurrent: item.isCurrent, onClick: item.onNavigate }, item.name)) : (item.name),
737
+ item.isCurrent ? null : React__namespace.createElement(uiReact.Breadcrumbs.Separator, null)));
738
+ })))));
739
+ };
740
+ const Title = ({ title }) => {
741
+ return (React__namespace.createElement(uiReact.Heading, { className: `${STORAGE_BROWSER_BLOCK}__title`, level: 2 }, title));
742
+ };
743
+ const componentsDefault = {
744
+ ActionDestination,
745
+ ActionsList,
746
+ DataRefresh,
747
+ LoadingIndicator,
748
+ Pagination,
749
+ Navigation,
750
+ OverwriteToggle,
751
+ SearchField,
752
+ SearchSubfoldersToggle,
753
+ StatusDisplay,
754
+ FolderNameField,
755
+ Title,
756
+ };
757
+
758
+ const Fallback = () => (React__namespace["default"].createElement("div", { className: STORAGE_BROWSER_BLOCK_TO_BE_UPDATED },
759
+ React__namespace["default"].createElement("div", { className: `${STORAGE_BROWSER_BLOCK_TO_BE_UPDATED}__error-boundary` }, "Something went wrong.")));
760
+ class ErrorBoundary extends React__namespace["default"].Component {
761
+ constructor(props) {
762
+ super(props);
763
+ this.state = { hasError: false };
764
+ }
765
+ static getDerivedStateFromError(_error) {
766
+ // Update state so the next render will show the fallback UI.
767
+ return { hasError: true };
768
+ }
769
+ render() {
770
+ const { hasError } = this.state;
771
+ const { children } = this.props;
772
+ if (hasError) {
773
+ return React__namespace["default"].createElement(Fallback, null);
774
+ }
775
+ return children;
776
+ }
777
+ }
778
+
779
+ function assertLocationPermissions(value, message) {
780
+ if (!Array.isArray(value) ||
781
+ value.some((inputPermissionEntry) => typeof inputPermissionEntry !== 'string' ||
782
+ !['list', 'get', 'write', 'delete'].includes(inputPermissionEntry))) {
783
+ throw new Error(message);
784
+ }
785
+ }
786
+ function assertLocationData(value, message = 'Invalid value provided as `location`.') {
787
+ const locationStringDataKeys = ['bucket', 'id', 'prefix', 'type'];
788
+ if (!ui.isObject(value) ||
789
+ locationStringDataKeys.some((key) => !ui.isString(value[key]))) {
790
+ throw new Error(message);
791
+ }
792
+ assertLocationPermissions(value?.permissions, message);
793
+ }
794
+ function assertPrefix(value, message) {
795
+ if (!ui.isString(value)) {
796
+ throw new Error(message ?? 'Invalid value provided as `prefix`.');
797
+ }
798
+ }
799
+
800
+ function assertRegisterAuthListener(value) {
801
+ if (!ui.isFunction(value)) {
802
+ throw new Error('StorageBrowser: `registerAuthListener` must be a function.');
803
+ }
804
+ }
805
+
806
+ function assertAccountId(value) {
807
+ if (!value) {
808
+ throw new Error('Storage Browser: Must provide accountId to `listCallerAccessGrants`.');
809
+ }
810
+ }
811
+
812
+ const UPLOAD_FILE_SIZE_LIMIT = 160 * 1000 * 1000 * 1000;
813
+ const isFileTooBig = (file) => file.size > UPLOAD_FILE_SIZE_LIMIT;
814
+
815
+ const ERROR_MESSAGE$3 = 'Invalid `location` value provided as initial value to `LocationProvider.';
816
+ const DEFAULT_STATE$1 = {
817
+ current: undefined,
818
+ path: '',
819
+ key: '',
820
+ };
821
+ function handleAction$1(state, action) {
822
+ switch (action.type) {
823
+ case 'NAVIGATE': {
824
+ const { location, path = '' } = action;
825
+ if (state.current?.id === location.id && state.path === path) {
826
+ return state;
827
+ }
828
+ return {
829
+ current: location,
830
+ path,
831
+ key: `${location.prefix ?? ''}${path}`,
832
+ };
833
+ }
834
+ case 'RESET_LOCATION': {
835
+ return DEFAULT_STATE$1;
836
+ }
837
+ }
838
+ }
839
+ const defaultValue$8 = [DEFAULT_STATE$1, ui.noop];
840
+ const { LocationContext, useLocation } = uiReactCore.createContextUtilities({
841
+ contextName: 'Location',
842
+ defaultValue: defaultValue$8,
843
+ });
844
+ function LocationProvider({ children, location, path = '', }) {
845
+ if (location) {
846
+ assertLocationData(location, ERROR_MESSAGE$3);
847
+ }
848
+ const value = React__namespace["default"].useReducer(handleAction$1, location
849
+ ? {
850
+ current: location,
851
+ path,
852
+ key: `${location.prefix ?? ''}${path}`,
853
+ }
854
+ : DEFAULT_STATE$1);
855
+ return (React__namespace["default"].createElement(LocationContext.Provider, { value: value }, children));
856
+ }
857
+
858
+ const compareFileItems = (prev, next) => prev.key.localeCompare(next.key);
859
+ const resolveFiles = (prevItems, files) => {
860
+ if (!files?.length)
861
+ return prevItems;
862
+ // construct `nextItems` and filter out existing `file` entries
863
+ const nextItems = files.reduce((items, file) => {
864
+ const { name, webkitRelativePath } = file;
865
+ return prevItems.some(({ file: existing }) => existing.name === name &&
866
+ existing.webkitRelativePath === webkitRelativePath)
867
+ ? items
868
+ : items.concat({
869
+ key: ui.isEmpty(webkitRelativePath) ? name : webkitRelativePath,
870
+ id: crypto.randomUUID(),
871
+ file,
872
+ });
873
+ }, []);
874
+ if (!nextItems.length)
875
+ return prevItems;
876
+ if (!prevItems.length) {
877
+ return nextItems.sort(compareFileItems);
878
+ }
879
+ return prevItems.concat(nextItems).sort(compareFileItems);
880
+ };
881
+ const filesReducer = (prevItems, input) => {
882
+ switch (input.type) {
883
+ case 'ADD_FILE_ITEMS': {
884
+ return resolveFiles(prevItems, input.files);
885
+ }
886
+ case 'REMOVE_FILE_ITEM': {
887
+ const filteredItems = prevItems.filter(({ id }) => id !== input.id);
888
+ return filteredItems.length === prevItems.length
889
+ ? prevItems
890
+ : filteredItems;
891
+ }
892
+ case 'RESET_FILE_ITEMS': {
893
+ return [];
894
+ }
895
+ // TODO: clear message
896
+ }
897
+ };
898
+ const parseFileSelectParams = (value) => {
899
+ if (ui.isUndefined(value))
900
+ return ['FILE', undefined];
901
+ if (ui.isString(value))
902
+ return [value, undefined];
903
+ const [selectType, ...rest] = value;
904
+ return [selectType, !rest?.length ? undefined : { accept: rest.join() }];
905
+ };
906
+
907
+ const defaultValue$7 = [undefined, ui.noop];
908
+ const { FilesContext, useFiles } = uiReactCore.createContextUtilities({
909
+ contextName: 'Files',
910
+ defaultValue: defaultValue$7,
911
+ });
912
+ function FilesProvider({ children, }) {
913
+ const [items, dispatch] = React__namespace["default"].useReducer(filesReducer, []);
914
+ const [fileInput, handleFileSelect] = internal.useFileSelect((nextFiles) => {
915
+ dispatch({ type: 'ADD_FILE_ITEMS', files: nextFiles });
916
+ });
917
+ const handleFilesAction = React__namespace["default"].useCallback((action) => {
918
+ if (action.type === 'SELECT_FILES') {
919
+ handleFileSelect(...parseFileSelectParams(action.selectionType));
920
+ }
921
+ else {
922
+ dispatch(action);
923
+ }
924
+ }, [handleFileSelect]);
925
+ const value = React__namespace["default"].useMemo(() => [items, handleFilesAction], [items, handleFilesAction]);
926
+ return (React__namespace["default"].createElement(FilesContext.Provider, { value: value },
927
+ fileInput,
928
+ children));
929
+ }
930
+
931
+ const handleAction = (event) => {
932
+ switch (event.type) {
933
+ case 'SET_ACTION_TYPE': {
934
+ return event.actionType;
935
+ }
936
+ case 'RESET_ACTION_TYPE': {
937
+ return undefined;
938
+ }
939
+ }
940
+ };
941
+ function useActionTypeState(initialState) {
942
+ const [actionType, setActionType] = React__namespace["default"].useState(initialState);
943
+ const handler = React__namespace["default"].useCallback((action) => setActionType(handleAction(action)), []);
944
+ return [actionType, handler];
945
+ }
946
+
947
+ const defaultValue$6 = [undefined, ui.noop];
948
+ const { ActionTypeContext, useActionType } = uiReactCore.createContextUtilities({
949
+ contextName: 'ActionType',
950
+ defaultValue: defaultValue$6,
951
+ });
952
+ function ActionTypeProvider({ actionType, children, }) {
953
+ const value = useActionTypeState(actionType);
954
+ return (React__namespace["default"].createElement(ActionTypeContext.Provider, { value: value }, children));
955
+ }
956
+
957
+ const defaultValue$5 = { actions: undefined };
958
+ const { useActionConfigs, ActionConfigsProvider } = uiReactCore.createContextUtilities({ contextName: 'ActionConfigs', defaultValue: defaultValue$5 });
959
+ function useActionConfig(type) {
960
+ const { actions } = useActionConfigs();
961
+ const config = actions?.[type];
962
+ if (!config)
963
+ throw new Error('No action!');
964
+ return config;
965
+ }
966
+
967
+ const constructBucket = ({ bucket: bucketName, region, }) => ({ bucketName, region });
968
+ const parseAccessGrantLocation = (location) => {
969
+ const { permission, scope, type } = location;
970
+ if (!scope.startsWith('s3://')) {
971
+ throw new Error(`Invalid scope: ${scope}`);
972
+ }
973
+ const id = crypto.randomUUID();
974
+ // remove default path
975
+ const slicedScope = scope.slice(5);
976
+ let bucket, prefix;
977
+ switch (type) {
978
+ case 'BUCKET': {
979
+ // { scope: 's3://bucket/*', type: 'BUCKET', },
980
+ bucket = slicedScope.slice(0, -2);
981
+ prefix = '';
982
+ break;
983
+ }
984
+ case 'PREFIX': {
985
+ // { scope: 's3://bucket/path/*', type: 'PREFIX', },
986
+ bucket = slicedScope.slice(0, slicedScope.indexOf('/'));
987
+ prefix = `${slicedScope.slice(bucket.length + 1, -1)}`;
988
+ break;
989
+ }
990
+ case 'OBJECT': {
991
+ // { scope: 's3://bucket/path/to/object', type: 'OBJECT', },
992
+ bucket = slicedScope.slice(0, slicedScope.indexOf('/'));
993
+ prefix = slicedScope.slice(bucket.length + 1);
994
+ break;
995
+ }
996
+ default: {
997
+ throw new Error(`Invalid location type: ${type}`);
998
+ }
999
+ }
1000
+ let permissions;
1001
+ switch (permission) {
1002
+ case 'READ':
1003
+ permissions = ['get', 'list'];
1004
+ break;
1005
+ case 'READWRITE':
1006
+ permissions = ['delete', 'get', 'list', 'write'];
1007
+ break;
1008
+ case 'WRITE':
1009
+ permissions = ['delete', 'write'];
1010
+ break;
1011
+ default:
1012
+ throw new Error(`Invalid location permission: ${permission}`);
1013
+ }
1014
+ return { bucket, id, permissions: permissions, prefix, type };
1015
+ };
1016
+ const isSamePermissions = (permissionsToExclude, locationPermissions) => {
1017
+ if (permissionsToExclude.length !== locationPermissions.length) {
1018
+ return false;
1019
+ }
1020
+ const sortedLocationPermissions = locationPermissions.sort();
1021
+ return permissionsToExclude
1022
+ .sort()
1023
+ .every((permission, index) => permission === sortedLocationPermissions[index]);
1024
+ };
1025
+ const isSameType = (typeToExclude, locationType) => typeof typeToExclude === 'string'
1026
+ ? typeToExclude === locationType
1027
+ : typeToExclude.includes(locationType);
1028
+ const shouldExcludeLocation = ({ permissions, type }, exclude) => {
1029
+ const excludedByPermssions = !!(exclude?.exactPermissions &&
1030
+ isSamePermissions(exclude.exactPermissions, permissions));
1031
+ const excludedByType = !!(exclude?.type && isSameType(exclude.type, type));
1032
+ return excludedByPermssions || excludedByType;
1033
+ };
1034
+ const getFilteredLocations = (locations, exclude) => locations.reduce((filteredLocations, location) => {
1035
+ const parsedLocation = parseAccessGrantLocation(location);
1036
+ const isNonFolderLikePrefix = !parsedLocation.prefix.endsWith('/') &&
1037
+ parsedLocation.type === 'PREFIX';
1038
+ if (isNonFolderLikePrefix) {
1039
+ return filteredLocations;
1040
+ }
1041
+ if (!shouldExcludeLocation(parsedLocation, exclude)) {
1042
+ filteredLocations.push(parsedLocation);
1043
+ }
1044
+ return filteredLocations;
1045
+ }, []);
1046
+ const getFileKey = (key) => key.slice(key.lastIndexOf('/') + 1, key.length);
1047
+ const createFileDataItem = (data) => ({
1048
+ ...data,
1049
+ fileKey: getFileKey(data.key),
1050
+ });
1051
+ const createFileDataItemFromLocation = (data) => ({
1052
+ id: data.id,
1053
+ type: 'FILE',
1054
+ key: data.prefix,
1055
+ fileKey: getFileKey(data.prefix),
1056
+ // `lastModified` and `size` included to satisfy
1057
+ // expected shape of `FileDataItem`
1058
+ lastModified: new Date(),
1059
+ size: 0,
1060
+ });
1061
+ const isFileItem = (value) => !!value.file;
1062
+ const isFileDataItem = (item) => !!item.fileKey;
1063
+ const getProgress = ({ totalBytes, transferredBytes, }) => totalBytes ? transferredBytes / totalBytes : undefined;
1064
+
1065
+ const copyHandler = (input) => {
1066
+ const { config, destinationPrefix: path, data } = input;
1067
+ const { accountId: expectedBucketOwner, credentials, customEndpoint, } = config;
1068
+ const { key: sourcePath, fileKey, lastModified, eTag } = data;
1069
+ const bucket = constructBucket(config);
1070
+ const destinationPath = `${path}${fileKey}`;
1071
+ const source = {
1072
+ bucket,
1073
+ expectedBucketOwner,
1074
+ /**
1075
+ * Per S3 requirement, copy source must the URI encoded.
1076
+ * This is NOT added to Amplify JS v6 because it will be a breaking
1077
+ * change to suddenly introduce URI encode to copy API source.
1078
+ *
1079
+ * see: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CopyObject.html#API_CopyObject_RequestSyntax
1080
+ */
1081
+ path: sourcePath.split('/').map(encodeURIComponent).join('/'),
1082
+ notModifiedSince: lastModified,
1083
+ eTag,
1084
+ };
1085
+ const destination = {
1086
+ bucket,
1087
+ expectedBucketOwner,
1088
+ path: destinationPath,
1089
+ };
1090
+ const result = internals.copy({
1091
+ source,
1092
+ destination,
1093
+ options: { locationCredentialsProvider: credentials, customEndpoint },
1094
+ });
1095
+ return {
1096
+ result: result
1097
+ .then(() => ({ status: 'COMPLETE' }))
1098
+ .catch(({ message }) => ({ message, status: 'FAILED' })),
1099
+ };
1100
+ };
1101
+
1102
+ const createFolderHandler = (input) => {
1103
+ const { destinationPrefix, config, data, options } = input;
1104
+ const { accountId, credentials, customEndpoint } = config;
1105
+ const { onProgress, preventOverwrite } = options ?? {};
1106
+ const { key } = data;
1107
+ const bucket = constructBucket(config);
1108
+ const { result } = internals.uploadData({
1109
+ path: `${destinationPrefix}${key}`,
1110
+ data: '',
1111
+ options: {
1112
+ bucket,
1113
+ expectedBucketOwner: accountId,
1114
+ locationCredentialsProvider: credentials,
1115
+ customEndpoint,
1116
+ onProgress: (event) => {
1117
+ if (ui.isFunction(onProgress))
1118
+ onProgress(data, getProgress(event));
1119
+ },
1120
+ preventOverwrite,
1121
+ },
1122
+ });
1123
+ return {
1124
+ result: result
1125
+ .then(() => ({ status: 'COMPLETE' }))
1126
+ .catch(({ message, name }) => {
1127
+ if (name === 'PreconditionFailed') {
1128
+ return { message, status: 'OVERWRITE_PREVENTED' };
1129
+ }
1130
+ return { message, status: 'FAILED' };
1131
+ }),
1132
+ };
1133
+ };
1134
+
1135
+ const deleteHandler = ({ config, data: { key }, }) => {
1136
+ const { accountId, credentials, customEndpoint } = config;
1137
+ const result = internals.remove({
1138
+ path: key,
1139
+ options: {
1140
+ bucket: constructBucket(config),
1141
+ locationCredentialsProvider: credentials,
1142
+ expectedBucketOwner: accountId,
1143
+ customEndpoint,
1144
+ },
1145
+ });
1146
+ return {
1147
+ result: result
1148
+ .then(() => ({ status: 'COMPLETE' }))
1149
+ .catch(({ message }) => ({ message, status: 'FAILED' })),
1150
+ };
1151
+ };
1152
+
1153
+ function downloadFromUrl(fileName, url) {
1154
+ const a = document.createElement('a');
1155
+ a.href = url;
1156
+ a.download = fileName;
1157
+ a.target = '_blank';
1158
+ document.body.appendChild(a);
1159
+ a.click();
1160
+ document.body.removeChild(a);
1161
+ }
1162
+ const downloadHandler = ({ config, data: { key }, }) => {
1163
+ const { accountId, credentials, customEndpoint } = config;
1164
+ const result = internals.getUrl({
1165
+ path: key,
1166
+ options: {
1167
+ bucket: constructBucket(config),
1168
+ customEndpoint,
1169
+ locationCredentialsProvider: credentials,
1170
+ validateObjectExistence: true,
1171
+ contentDisposition: 'attachment',
1172
+ expectedBucketOwner: accountId,
1173
+ },
1174
+ }).then((result) => {
1175
+ return result;
1176
+ });
1177
+ return {
1178
+ result: result
1179
+ .then(({ url }) => {
1180
+ downloadFromUrl(key, url.toString());
1181
+ return { status: 'COMPLETE' };
1182
+ })
1183
+ .catch(({ message }) => ({ message, status: 'FAILED' })),
1184
+ };
1185
+ };
1186
+
1187
+ const DEFAULT_PAGE_SIZE$4 = 1000;
1188
+ const parseItems = (items, excludedPath) => items
1189
+ // remove root `key` from results
1190
+ .filter(({ path }) => path !== excludedPath)
1191
+ .map(({ path: key, lastModified, size, eTag }) => {
1192
+ const id = crypto.randomUUID();
1193
+ // Mark zero byte files as Folders
1194
+ if (size === 0 && key.endsWith('/')) {
1195
+ return { key, id, type: 'FOLDER' };
1196
+ }
1197
+ return {
1198
+ key,
1199
+ id,
1200
+ eTag,
1201
+ lastModified: lastModified,
1202
+ size: size,
1203
+ type: 'FILE',
1204
+ };
1205
+ });
1206
+ const parseExcludedPaths = (paths) => paths?.map((key) => ({ key, id: crypto.randomUUID(), type: 'FOLDER' })) ?? [];
1207
+ const filterDotItems = (items, prefix) => items.filter((item) => {
1208
+ const key = (item.key.startsWith(prefix) ? item.key.substring(prefix.length) : item.key).trim();
1209
+ // matches object keys that would cause problems either as folder names in navigation (`/`, `./`, `../`) or as objects (`.`, `..`)
1210
+ return !(key === '/' ||
1211
+ key === './' ||
1212
+ key === '../' ||
1213
+ key === '.' ||
1214
+ key === '..');
1215
+ });
1216
+ const parseResult = ({ excludedSubpaths, items }, prefix) => filterDotItems([...parseExcludedPaths(excludedSubpaths), ...parseItems(items, prefix)], prefix);
1217
+ const listLocationItemsHandler = async (input) => {
1218
+ const { config, prefix, options } = input;
1219
+ const { bucket: _bucket, credentials, customEndpoint, region, accountId, } = config;
1220
+ const { exclude, delimiter, nextToken, pageSize: _pageSize = DEFAULT_PAGE_SIZE$4, ..._options } = options ?? {};
1221
+ const bucket = { bucketName: _bucket, region };
1222
+ const subpathStrategy = {
1223
+ delimiter,
1224
+ strategy: delimiter ? 'exclude' : 'include',
1225
+ };
1226
+ // `ListObjectsV2` returns the root `key` on initial request, which is from
1227
+ // filtered from `results` by `parseResult`, creatimg a scenario where the
1228
+ // return count of `results` to be one item less than provided the `pageSize`.
1229
+ // To mitigate, if a `pageSize` is provided and there are no previous `results`
1230
+ // or `refresh` is `true` increment the provided `pageSize` by `1`
1231
+ const hasOffset = !nextToken;
1232
+ const pageSize = hasOffset ? _pageSize + 1 : _pageSize;
1233
+ const result = [];
1234
+ let nextNextToken = nextToken;
1235
+ do {
1236
+ const listInput = {
1237
+ path: prefix,
1238
+ options: {
1239
+ nextToken: nextNextToken,
1240
+ ..._options,
1241
+ bucket,
1242
+ customEndpoint,
1243
+ expectedBucketOwner: accountId,
1244
+ locationCredentialsProvider: credentials,
1245
+ pageSize,
1246
+ subpathStrategy,
1247
+ },
1248
+ };
1249
+ const output = await internals.list(listInput);
1250
+ nextNextToken = output.nextToken;
1251
+ const items = parseResult(output, prefix);
1252
+ result.push(...(exclude ? items.filter((item) => item.type !== exclude) : items));
1253
+ } while (nextNextToken && result.length < pageSize);
1254
+ return { items: result, nextToken: nextNextToken };
1255
+ };
1256
+
1257
+ const DEFAULT_PAGE_SIZE$3 = 1000;
1258
+ const listLocationsHandler = async (input) => {
1259
+ const { config, options } = input;
1260
+ const { accountId, credentials, customEndpoint, region } = config;
1261
+ const { exclude, nextToken, pageSize = DEFAULT_PAGE_SIZE$3 } = options ?? {};
1262
+ const fetchLocations = async (accumulatedItems, locationsNextToken) => {
1263
+ const remainingPageSize = pageSize - accumulatedItems.length;
1264
+ assertAccountId(accountId);
1265
+ const output = await internals.listCallerAccessGrants({
1266
+ accountId,
1267
+ credentialsProvider: credentials,
1268
+ customEndpoint,
1269
+ nextToken: locationsNextToken,
1270
+ pageSize: remainingPageSize,
1271
+ region,
1272
+ });
1273
+ const parsedOutput = getFilteredLocations(output.locations, exclude);
1274
+ const items = [...accumulatedItems, ...parsedOutput];
1275
+ if (output.nextToken && items.length < pageSize) {
1276
+ return fetchLocations(items, output.nextToken);
1277
+ }
1278
+ return { items, nextToken: output.nextToken };
1279
+ };
1280
+ return fetchLocations([], nextToken);
1281
+ };
1282
+
1283
+ // 5MB for multipart upload
1284
+ // https://github.com/aws-amplify/amplify-js/blob/1a5366d113c9af4ce994168653df3aadb142c581/packages/storage/src/providers/s3/utils/constants.ts#L16
1285
+ const MULTIPART_UPLOAD_THRESHOLD_BYTES = 5 * 1024 * 1024;
1286
+ const UNDEFINED_CALLBACKS = {
1287
+ cancel: undefined,
1288
+ pause: undefined,
1289
+ resume: undefined,
1290
+ };
1291
+ const uploadHandler = ({ config, data, destinationPrefix, options, }) => {
1292
+ const { accountId, credentials, customEndpoint } = config;
1293
+ const { key, file } = data;
1294
+ const { onProgress, preventOverwrite } = options ?? {};
1295
+ const input = {
1296
+ path: `${destinationPrefix}${key}`,
1297
+ data: file,
1298
+ options: {
1299
+ bucket: constructBucket(config),
1300
+ expectedBucketOwner: accountId,
1301
+ locationCredentialsProvider: credentials,
1302
+ onProgress: (event) => {
1303
+ if (ui.isFunction(onProgress))
1304
+ onProgress(data, getProgress(event));
1305
+ },
1306
+ preventOverwrite,
1307
+ customEndpoint,
1308
+ checksumAlgorithm: 'crc-32',
1309
+ },
1310
+ };
1311
+ const { cancel, pause, resume, result } = internals.uploadData(input);
1312
+ return {
1313
+ ...(file.size > MULTIPART_UPLOAD_THRESHOLD_BYTES
1314
+ ? { cancel, pause, resume }
1315
+ : UNDEFINED_CALLBACKS),
1316
+ result: result
1317
+ .then(() => ({ status: 'COMPLETE' }))
1318
+ .catch((error) => {
1319
+ const { message } = error;
1320
+ if (error.name === 'PreconditionFailed') {
1321
+ return { message, status: 'OVERWRITE_PREVENTED' };
1322
+ }
1323
+ return {
1324
+ message,
1325
+ status: storage.isCancelError(error) ? 'CANCELED' : 'FAILED',
1326
+ };
1327
+ }),
1328
+ };
1329
+ };
1330
+
1331
+ const copyActionConfig = {
1332
+ componentName: 'CopyView',
1333
+ actionsListItemConfig: {
1334
+ disable: (selected) => !selected || selected.length === 0,
1335
+ hide: (permissions) => !permissions.includes('write'),
1336
+ icon: 'copy-file',
1337
+ label: 'Copy',
1338
+ },
1339
+ displayName: 'Copy',
1340
+ handler: copyHandler,
1341
+ };
1342
+ const deleteActionConfig = {
1343
+ componentName: 'DeleteView',
1344
+ actionsListItemConfig: {
1345
+ disable: (selected) => !selected || selected.length === 0,
1346
+ hide: (permissions) => !permissions.includes('delete'),
1347
+ icon: 'delete-file',
1348
+ label: 'Delete',
1349
+ },
1350
+ displayName: 'Delete',
1351
+ handler: deleteHandler,
1352
+ };
1353
+ const createFolderActionConfig = {
1354
+ componentName: 'CreateFolderView',
1355
+ actionsListItemConfig: {
1356
+ disable: () => false,
1357
+ hide: (permissions) => !permissions.includes('write'),
1358
+ icon: 'create-folder',
1359
+ label: 'Create folder',
1360
+ },
1361
+ handler: createFolderHandler,
1362
+ isCancelable: false,
1363
+ displayName: 'Create Folder',
1364
+ };
1365
+ const listLocationItemsActionConfig = {
1366
+ componentName: 'LocationDetailView',
1367
+ handler: listLocationItemsHandler,
1368
+ displayName: (bucket, prefix) => {
1369
+ if (bucket && prefix) {
1370
+ const prefixes = prefix.split('/');
1371
+ return `${bucket}: ${prefixes.length > 2 ? `../${prefixes[prefixes.length - 2]}/` : prefix}`;
1372
+ }
1373
+ return !bucket ? '-' : bucket;
1374
+ },
1375
+ };
1376
+ const listLocationsActionConfig = {
1377
+ componentName: 'LocationsView',
1378
+ handler: listLocationsHandler,
1379
+ displayName: 'Home',
1380
+ };
1381
+ const uploadActionConfig = {
1382
+ componentName: 'UploadView',
1383
+ actionsListItemConfig: {
1384
+ disable: () => false,
1385
+ fileSelection: 'FILE',
1386
+ hide: (permissions) => !permissions.includes('write'),
1387
+ icon: 'upload-file',
1388
+ label: 'Upload',
1389
+ },
1390
+ isCancelable: true,
1391
+ includeProgress: true,
1392
+ handler: uploadHandler,
1393
+ displayName: 'Upload',
1394
+ };
1395
+ const defaultActionViewConfigs = {
1396
+ copy: copyActionConfig,
1397
+ createFolder: createFolderActionConfig,
1398
+ delete: deleteActionConfig,
1399
+ upload: uploadActionConfig,
1400
+ };
1401
+ const DEFAULT_ACTION_VIEW_TYPES = Object.keys(defaultActionViewConfigs);
1402
+ const isDefaultActionViewType = (value) => DEFAULT_ACTION_VIEW_TYPES.some((type) => type === value);
1403
+ const defaultActionConfigs = {
1404
+ ...defaultActionViewConfigs,
1405
+ listLocationItems: listLocationItemsActionConfig,
1406
+ listLocations: listLocationsActionConfig,
1407
+ };
1408
+
1409
+ const SEARCH_LIMIT = 10000;
1410
+ const SEARCH_PAGE_SIZE = 1000;
1411
+ /**
1412
+ * Normalizes and converts a string to lower case,
1413
+ * handling Unicode characters and locale-specific case mappings.
1414
+ * Uses NFKD to fully decompose unicode: https://unicode.org/reports/tr15/#Normalization_Forms_Table
1415
+ */
1416
+ function normalize(input) {
1417
+ return input
1418
+ .normalize('NFKD')
1419
+ .replace(/[\u0300-\u036f]/g, '') // remove diacritic modifiers
1420
+ .toLocaleLowerCase();
1421
+ }
1422
+ /**
1423
+ * Performs a case-insensitive check to determine if a string includes another string,
1424
+ * handling Unicode characters and locale-specific case mappings.
1425
+ *
1426
+ * @param {string} input - The string to search within.
1427
+ * @param {string} query - The substring to search for.
1428
+ * @returns {boolean} - Returns `true` if `query` is found in `input` (case-insensitively), otherwise `false`.
1429
+ *
1430
+ * @example
1431
+ * caseInsensitiveIncludes("Photos", "photo"); // true
1432
+ * caseInsensitiveIncludes("Hello", "HELLO"); // true
1433
+ * caseInsensitiveIncludes("\uFB00", "\u0046\u0046"); // ff = FF true
1434
+ * caseInsensitiveIncludes("Cafè", "cafe"); // true
1435
+ */
1436
+ function caseInsensitiveIncludes(input, query) {
1437
+ return normalize(input).includes(normalize(query));
1438
+ }
1439
+ function searchItems({ prefix = '', list, options }) {
1440
+ const { query, filterBy, groupBy } = options;
1441
+ // filter keys that match `filterBy` search option
1442
+ const filteredItems = list.filter((item) => {
1443
+ const key = typeof filterBy === 'function' ? filterBy(item) : filterBy;
1444
+ const path = item[key];
1445
+ const suffix = path.slice(prefix.length);
1446
+ return caseInsensitiveIncludes(suffix, query);
1447
+ });
1448
+ if (!groupBy) {
1449
+ return filteredItems;
1450
+ }
1451
+ // group items using the provided grouping delimiter
1452
+ const uniquePaths = new Map();
1453
+ for (const item of filteredItems) {
1454
+ const key = typeof filterBy === 'function' ? filterBy(item) : filterBy;
1455
+ const path = item[key];
1456
+ const components = path.split(groupBy);
1457
+ for (const [i, component] of components.entries()) {
1458
+ if (!caseInsensitiveIncludes(component, query)) {
1459
+ continue;
1460
+ }
1461
+ // list of components ending with match
1462
+ const matchedPathSegments = components.slice(0, i + 1);
1463
+ // create new path
1464
+ let matchedPath = matchedPathSegments.join(groupBy);
1465
+ const isFolder = matchedPath !== path;
1466
+ if (isFolder) {
1467
+ matchedPath += groupBy;
1468
+ }
1469
+ // ignore anything below the prefix for matching
1470
+ if (matchedPath.length > prefix.length && !uniquePaths.has(matchedPath)) {
1471
+ // add a new item
1472
+ uniquePaths.set(matchedPath, {
1473
+ ...item,
1474
+ id: crypto.randomUUID(),
1475
+ [key]: matchedPath,
1476
+ type: isFolder ? 'FOLDER' : 'FILE',
1477
+ });
1478
+ }
1479
+ }
1480
+ }
1481
+ return Array.from(uniquePaths.values());
1482
+ }
1483
+ const createEnhancedListHandler = (action) => {
1484
+ return async function listActionHandler(prevState, { options, ...input }) {
1485
+ const { nextToken: _nextToken, refresh, reset, search, ...rest } = options ?? {};
1486
+ if (reset) {
1487
+ return { items: [], nextToken: undefined };
1488
+ }
1489
+ // collect and filter results on `search`
1490
+ if (search) {
1491
+ const result = [];
1492
+ let nextNextToken = undefined;
1493
+ do {
1494
+ const output = (await action({
1495
+ ...input,
1496
+ options: {
1497
+ ...rest,
1498
+ pageSize: SEARCH_PAGE_SIZE,
1499
+ nextToken: nextNextToken,
1500
+ },
1501
+ }));
1502
+ result.push(...output.items);
1503
+ nextNextToken = output.nextToken;
1504
+ } while (nextNextToken && result.length < SEARCH_LIMIT);
1505
+ return {
1506
+ items: searchItems({
1507
+ list: result,
1508
+ prefix: input.prefix,
1509
+ options: search,
1510
+ }),
1511
+ search: {
1512
+ // search limit reached but we still have a next token
1513
+ hasExhaustedSearch: !!nextNextToken,
1514
+ },
1515
+ nextToken: undefined,
1516
+ };
1517
+ }
1518
+ // ignore provided `nextToken` on `refresh`
1519
+ const nextToken = refresh ? undefined : _nextToken;
1520
+ const output = (await action({
1521
+ ...input,
1522
+ options: { ...rest, nextToken },
1523
+ }));
1524
+ return {
1525
+ items: [...(refresh ? [] : prevState.items), ...output.items],
1526
+ nextToken: output.nextToken,
1527
+ };
1528
+ };
1529
+ };
1530
+
1531
+ const useListLocations = () => {
1532
+ const { handler } = useActionConfig('listLocations');
1533
+ const enhancedHandler = React__namespace["default"].useMemo(() => createEnhancedListHandler(handler), [handler]);
1534
+ return uiReactCore.useDataState(enhancedHandler, {
1535
+ items: [],
1536
+ nextToken: undefined,
1537
+ });
1538
+ };
1539
+
1540
+ const DEFAULT_STATE = {
1541
+ fileDataItems: undefined,
1542
+ };
1543
+ const locationItemsReducer = (prevState, event) => {
1544
+ switch (event.type) {
1545
+ case 'SET_LOCATION_ITEMS': {
1546
+ const { items } = event;
1547
+ if (!items?.length)
1548
+ return prevState;
1549
+ if (!prevState.fileDataItems?.length) {
1550
+ return { fileDataItems: items.map(createFileDataItem) };
1551
+ }
1552
+ const nextFileDataItems = items?.reduce((fileDataItems, data) => prevState.fileDataItems?.some(({ id }) => id === data.id)
1553
+ ? fileDataItems
1554
+ : fileDataItems.concat(createFileDataItem(data)), []);
1555
+ if (!nextFileDataItems?.length)
1556
+ return prevState;
1557
+ return {
1558
+ fileDataItems: prevState.fileDataItems.concat(nextFileDataItems),
1559
+ };
1560
+ }
1561
+ case 'REMOVE_LOCATION_ITEM': {
1562
+ const { id } = event;
1563
+ if (!prevState.fileDataItems)
1564
+ return prevState;
1565
+ const fileDataItems = prevState.fileDataItems.filter((item) => item.id !== id);
1566
+ if (fileDataItems.length === prevState.fileDataItems.length) {
1567
+ return prevState;
1568
+ }
1569
+ return { fileDataItems };
1570
+ }
1571
+ case 'RESET_LOCATION_ITEMS': {
1572
+ return DEFAULT_STATE;
1573
+ }
1574
+ }
1575
+ };
1576
+ const defaultValue$4 = [DEFAULT_STATE, ui.noop];
1577
+ const { LocationItemsContext, useLocationItems } = uiReactCore.createContextUtilities({ contextName: 'LocationItems', defaultValue: defaultValue$4 });
1578
+ function LocationItemsProvider({ children, }) {
1579
+ const value = React__namespace["default"].useReducer(locationItemsReducer, DEFAULT_STATE);
1580
+ return (React__namespace["default"].createElement(LocationItemsContext.Provider, { value: value }, children));
1581
+ }
1582
+
1583
+ function StoreProvider(props) {
1584
+ const { actionType, children, location, path } = props;
1585
+ return (React__namespace["default"].createElement(FilesProvider, null,
1586
+ React__namespace["default"].createElement(LocationProvider, { location: location, path: path },
1587
+ React__namespace["default"].createElement(LocationItemsProvider, null,
1588
+ React__namespace["default"].createElement(ActionTypeProvider, { actionType: actionType }, children)))));
1589
+ }
1590
+
1591
+ function useStore() {
1592
+ const [actionType, dispatchActionType] = useActionType();
1593
+ const [files, dispatchFilesAction] = useFiles();
1594
+ const [location, dispatchLocationAction] = useLocation();
1595
+ const [locationItems, dispatchLocationItemsAction] = useLocationItems();
1596
+ const dispatchHandler = React__namespace["default"].useCallback((action) => {
1597
+ switch (action.type) {
1598
+ case 'ADD_FILE_ITEMS':
1599
+ case 'REMOVE_FILE_ITEM':
1600
+ case 'SELECT_FILES':
1601
+ case 'RESET_FILE_ITEMS': {
1602
+ dispatchFilesAction(action);
1603
+ break;
1604
+ }
1605
+ case 'NAVIGATE':
1606
+ case 'RESET_LOCATION': {
1607
+ dispatchLocationAction(action);
1608
+ break;
1609
+ }
1610
+ case 'SET_LOCATION_ITEMS':
1611
+ case 'REMOVE_LOCATION_ITEM':
1612
+ case 'RESET_LOCATION_ITEMS': {
1613
+ dispatchLocationItemsAction(action);
1614
+ break;
1615
+ }
1616
+ case 'SET_ACTION_TYPE':
1617
+ case 'RESET_ACTION_TYPE': {
1618
+ dispatchActionType(action);
1619
+ break;
1620
+ }
1621
+ }
1622
+ }, [
1623
+ dispatchActionType,
1624
+ dispatchFilesAction,
1625
+ dispatchLocationAction,
1626
+ dispatchLocationItemsAction,
1627
+ ]);
1628
+ return [{ actionType, files, location, locationItems }, dispatchHandler];
1629
+ }
1630
+
1631
+ const CREDENTIALS_STORE_DEFAULT_SIZE = 10;
1632
+ const CREDENTIALS_REFRESH_WINDOW_MS = 30000;
1633
+
1634
+ const serializedPermissions = (permissions) => permissions.sort().join('_');
1635
+ const createCacheKey = (location) => `${location.scope}_${serializedPermissions(location.permissions)}`;
1636
+ const pastTTL = (credentials) => {
1637
+ const { expiration } = credentials;
1638
+ return expiration.getTime() - CREDENTIALS_REFRESH_WINDOW_MS <= Date.now();
1639
+ };
1640
+ const setCacheRecord = (store, key, value) => {
1641
+ if (store.capacity === store.values.size) {
1642
+ // Pop least used entry. The Map's key are in insertion order.
1643
+ // So first key is the last recently inserted.
1644
+ const [oldestKey] = store.values.keys();
1645
+ store.values.delete(oldestKey);
1646
+ // TODO(@AllanZhengYP): Add log info when record is evicted.
1647
+ }
1648
+ // Add latest used value to the cache.
1649
+ store.values.set(key, value);
1650
+ };
1651
+ const dispatchRefresh = (refreshHandler, value, onRefreshFailure) => {
1652
+ if (value.inflightCredentials) {
1653
+ return value.inflightCredentials;
1654
+ }
1655
+ value.inflightCredentials = (async () => {
1656
+ try {
1657
+ const { credentials } = await refreshHandler({
1658
+ scope: value.scope,
1659
+ permissions: value.permissions,
1660
+ });
1661
+ value.credentials = credentials;
1662
+ return { credentials };
1663
+ }
1664
+ catch (e) {
1665
+ onRefreshFailure();
1666
+ throw e;
1667
+ }
1668
+ finally {
1669
+ value.inflightCredentials = undefined;
1670
+ }
1671
+ })();
1672
+ return value.inflightCredentials;
1673
+ };
1674
+ /**
1675
+ * @internal
1676
+ */
1677
+ const initStore = (refreshHandler, size = CREDENTIALS_STORE_DEFAULT_SIZE) => {
1678
+ internals.assertValidationError(size > 0, internals.StorageValidationErrorCode.InvalidLocationCredentialsCacheSize);
1679
+ return {
1680
+ capacity: size,
1681
+ refreshHandler,
1682
+ values: new Map(),
1683
+ };
1684
+ };
1685
+ const getCacheValue = (store, location) => {
1686
+ const cacheKey = createCacheKey(location);
1687
+ const cachedValue = store.values.get(cacheKey);
1688
+ const cachedCredentials = cachedValue?.credentials;
1689
+ if (!cachedCredentials) {
1690
+ return null;
1691
+ }
1692
+ // Delete and re-insert to key to map to indicate a latest reference in LRU.
1693
+ store.values.delete(cacheKey);
1694
+ if (!pastTTL(cachedCredentials)) {
1695
+ // TODO(@AllanZhengYP): If the credential is still valid but will expire
1696
+ // soon, we should return credentials AND dispatch a refresh.
1697
+ store.values.set(cacheKey, cachedValue);
1698
+ return cachedCredentials;
1699
+ }
1700
+ return null;
1701
+ };
1702
+ /**
1703
+ * Fetch new credentials value with refresh handler and cache the result in
1704
+ * LRU cache.
1705
+ * @internal
1706
+ */
1707
+ const fetchNewValue = async (store, location) => {
1708
+ const storeValues = store.values;
1709
+ const key = createCacheKey(location);
1710
+ if (!storeValues.has(key)) {
1711
+ const newStoreValue = {
1712
+ scope: location.scope,
1713
+ permissions: location.permissions,
1714
+ };
1715
+ setCacheRecord(store, key, newStoreValue);
1716
+ }
1717
+ const storeValue = storeValues.get(key);
1718
+ return dispatchRefresh(store.refreshHandler, storeValue, () => {
1719
+ store.values.delete(key);
1720
+ });
1721
+ };
1722
+
1723
+ /**
1724
+ * Keep all cache records for all instances of credentials store in a singleton
1725
+ * so we can reliably de-reference from the memory when we destroy a store
1726
+ * instance.
1727
+ */
1728
+ const storeRegistry = new WeakMap();
1729
+ /**
1730
+ * @internal
1731
+ */
1732
+ const createStore = (refreshHandler, size) => {
1733
+ const storeSymbol = { value: Symbol('LocationCredentialsStore') };
1734
+ storeRegistry.set(storeSymbol, initStore(refreshHandler, size));
1735
+ return storeSymbol;
1736
+ };
1737
+ const getCredentialsStore = (storeSymbol) => {
1738
+ internals.assertValidationError(storeRegistry.has(storeSymbol), internals.StorageValidationErrorCode.LocationCredentialsStoreDestroyed);
1739
+ return storeRegistry.get(storeSymbol);
1740
+ };
1741
+ /**
1742
+ * @internal
1743
+ */
1744
+ const getValue = async (input) => {
1745
+ const { storeSymbol: storeReference, location, forceRefresh } = input;
1746
+ const store = getCredentialsStore(storeReference);
1747
+ if (!forceRefresh) {
1748
+ const credentials = getCacheValue(store, location);
1749
+ if (credentials !== null) {
1750
+ return { credentials };
1751
+ }
1752
+ }
1753
+ return fetchNewValue(store, location);
1754
+ };
1755
+ const removeStore = (storeSymbol) => {
1756
+ storeRegistry.delete(storeSymbol);
1757
+ };
1758
+
1759
+ const validateS3Uri = (uri) => {
1760
+ const s3UrlSchemaRegex = /^s3:\/\/[^/]+/;
1761
+ internals.assertValidationError(s3UrlSchemaRegex.test(uri), internals.StorageValidationErrorCode.InvalidS3Uri);
1762
+ };
1763
+ const createLocationCredentialsStore = (input) => {
1764
+ const storeSymbol = createStore(input.handler);
1765
+ const store = {
1766
+ getProvider(providerLocation) {
1767
+ const locationCredentialsProvider = async ({ forceRefresh = false, } = {}) => {
1768
+ validateS3Uri(providerLocation.scope);
1769
+ // TODO(@AllanZhengYP): validate the action bucket and paths matches provider scope.
1770
+ return getValue({
1771
+ storeSymbol,
1772
+ location: { ...providerLocation },
1773
+ forceRefresh,
1774
+ });
1775
+ };
1776
+ return locationCredentialsProvider;
1777
+ },
1778
+ destroy() {
1779
+ removeStore(storeSymbol);
1780
+ },
1781
+ };
1782
+ return store;
1783
+ };
1784
+
1785
+ const createCredentialsStore = ({ ...input }) => {
1786
+ const { destroy, getProvider } = createLocationCredentialsStore(input);
1787
+ return {
1788
+ destroy,
1789
+ getCredentials: ({ scope, permissions }) => getProvider({
1790
+ scope,
1791
+ permissions,
1792
+ }),
1793
+ };
1794
+ };
1795
+ const isCredentialsStore = (value) => ui.isFunction(value?.getCredentials);
1796
+ function useCredentialsStore({ getLocationCredentials: handler, initialValue, onDestroy, registerAuthListener, }) {
1797
+ const hasExistingStore = isCredentialsStore(initialValue);
1798
+ const [store, setStore] = React__namespace["default"].useState(() => hasExistingStore ? initialValue : createCredentialsStore({ handler }));
1799
+ const { destroy } = store;
1800
+ React__namespace["default"].useEffect(() => {
1801
+ if (hasExistingStore) {
1802
+ return;
1803
+ }
1804
+ const handleAuthStatusChange = () => {
1805
+ destroy();
1806
+ if (ui.isFunction(onDestroy)) {
1807
+ onDestroy();
1808
+ }
1809
+ setStore(createCredentialsStore({ handler }));
1810
+ };
1811
+ // provide `handleAuthStatusChange` to consumer
1812
+ registerAuthListener(handleAuthStatusChange);
1813
+ }, [destroy, handler, hasExistingStore, onDestroy, registerAuthListener]);
1814
+ return store;
1815
+ }
1816
+
1817
+ const ERROR_MESSAGE$2 = '`useCredentials` must be called from within a `CredentialsProvider`.';
1818
+ const { useCredentials, CredentialsContext } = uiReactCore.createContextUtilities({
1819
+ contextName: 'Credentials',
1820
+ errorMessage: ERROR_MESSAGE$2,
1821
+ });
1822
+ function CredentialsProvider({ children, ...props }) {
1823
+ const initialValue = React__namespace["default"].useContext(CredentialsContext);
1824
+ const value = useCredentialsStore({ ...props, initialValue });
1825
+ return (React__namespace["default"].createElement(CredentialsContext.Provider, { value: value }, children));
1826
+ }
1827
+
1828
+ const getErrorMessage = (propertyName) => `Unable to resolve credentials due to invalid value of '${propertyName}'`;
1829
+ function useGetActionInputCallback({ accountId, customEndpoint, region, }) {
1830
+ const { getCredentials } = useCredentials();
1831
+ const [{ location }] = useStore();
1832
+ const { current, key } = location;
1833
+ return React__namespace["default"].useCallback((location) => {
1834
+ // prefer passed in location / prefix over current location in state
1835
+ const _location = location ?? current;
1836
+ // when `location` has been provided as a param, resolve `_prefix` to `location.prefix`.
1837
+ // in the default scenario where `current` is the target `location` use the fully qualified `key`
1838
+ // that includes the default `prefix` and any additional prefixes from navigation
1839
+ const _prefix = location ? location.prefix : key;
1840
+ assertLocationData(_location, getErrorMessage('locationData'));
1841
+ assertPrefix(_prefix, getErrorMessage('prefix'));
1842
+ const { bucket, permissions, type } = _location;
1843
+ // BUCKET/PREFIX grants end with `*`, but object grants do not.
1844
+ const scope = `s3://${bucket}/${_prefix}${type === 'OBJECT' ? '' : '*'}`;
1845
+ return {
1846
+ accountId,
1847
+ bucket,
1848
+ credentials: getCredentials({
1849
+ permissions,
1850
+ scope,
1851
+ }),
1852
+ region,
1853
+ customEndpoint,
1854
+ };
1855
+ }, [accountId, current, customEndpoint, getCredentials, key, region]);
1856
+ }
1857
+
1858
+ const ERROR_MESSAGE$1 = '`useGetActionInput` must be called from within a `ConfigurationProvider`.';
1859
+ const { useGetActionInput, GetActionInputContext } = uiReactCore.createContextUtilities({
1860
+ contextName: 'GetActionInput',
1861
+ errorMessage: ERROR_MESSAGE$1,
1862
+ });
1863
+ function GetActionInputProvider({ accountId, children, customEndpoint, region, }) {
1864
+ const value = useGetActionInputCallback({
1865
+ accountId,
1866
+ customEndpoint,
1867
+ region,
1868
+ });
1869
+ return (React__namespace["default"].createElement(GetActionInputContext.Provider, { value: value }, children));
1870
+ }
1871
+
1872
+ const Passthrough = ({ children }) => (React__namespace["default"].createElement(React__namespace["default"].Fragment, null, children));
1873
+ function createConfigurationProvider(input) {
1874
+ const { accountId, actions, ChildComponent, displayName, region, customEndpoint, ...rest } = input;
1875
+ const Child = elements.isComponent(ChildComponent) ? ChildComponent : Passthrough;
1876
+ const Provider = (props) => (React__namespace["default"].createElement(ActionConfigsProvider, { actions: actions },
1877
+ React__namespace["default"].createElement(CredentialsProvider, { ...rest },
1878
+ React__namespace["default"].createElement(GetActionInputProvider, { accountId: accountId, region: region, customEndpoint: customEndpoint },
1879
+ React__namespace["default"].createElement(Child, { ...props })))));
1880
+ Provider.displayName = displayName;
1881
+ return Provider;
1882
+ }
1883
+
1884
+ const defaultValue$3 = { data: {} };
1885
+ const { useControlsContext, ControlsContextProvider } = uiReactCore.createContextUtilities({
1886
+ contextName: 'ControlsContext',
1887
+ defaultValue: defaultValue$3,
1888
+ });
1889
+
1890
+ const useActionCancel = () => {
1891
+ const { data: { actionCancelLabel, isActionCancelDisabled }, onActionCancel, } = useControlsContext();
1892
+ return {
1893
+ onCancel: onActionCancel,
1894
+ isDisabled: isActionCancelDisabled,
1895
+ label: actionCancelLabel,
1896
+ };
1897
+ };
1898
+
1899
+ function useResolvedComposable(DefaultComposable, name) {
1900
+ const { composables } = useComposables();
1901
+ const Composable = React__namespace["default"].useMemo(() => {
1902
+ const ResolvedComposable = (props) => {
1903
+ const Resolved = composables?.[name] ?? DefaultComposable;
1904
+ return React__namespace["default"].createElement(Resolved, { ...props });
1905
+ };
1906
+ ResolvedComposable.displayName = name;
1907
+ return ResolvedComposable;
1908
+ }, [composables, DefaultComposable, name]);
1909
+ return Composable;
1910
+ }
1911
+
1912
+ const ActionCancelControl = () => {
1913
+ const props = useActionCancel();
1914
+ const Resolved = useResolvedComposable(ActionCancel, 'ActionCancel');
1915
+ return React__namespace["default"].createElement(Resolved, { ...props });
1916
+ };
1917
+
1918
+ const useActionExit = () => {
1919
+ const { data: { actionExitLabel: label, isActionExitDisabled: isDisabled }, onActionExit: onExit, } = useControlsContext();
1920
+ return { label, isDisabled, onExit };
1921
+ };
1922
+
1923
+ const ActionExitControl = () => {
1924
+ const props = useActionExit();
1925
+ const Resolved = useResolvedComposable(ActionExit, 'ActionExit');
1926
+ return React__namespace["default"].createElement(Resolved, { ...props });
1927
+ };
1928
+
1929
+ const useActionStart = () => {
1930
+ const { data: { actionStartLabel, isActionStartDisabled }, onActionStart, } = useControlsContext();
1931
+ return {
1932
+ label: actionStartLabel,
1933
+ isDisabled: isActionStartDisabled,
1934
+ onStart: onActionStart,
1935
+ };
1936
+ };
1937
+
1938
+ const ActionStartControl = () => {
1939
+ const props = useActionStart();
1940
+ const Resolved = useResolvedComposable(ActionStart, 'ActionStart');
1941
+ return React__namespace["default"].createElement(Resolved, { ...props });
1942
+ };
1943
+
1944
+ const compareContent$3 = ({ label: a }, { label: b }) => {
1945
+ if (a === undefined) {
1946
+ return b === undefined ? 0 : 1;
1947
+ }
1948
+ return b === undefined ? -1 : a.localeCompare(b);
1949
+ };
1950
+ const compareButtonData = (a, b, direction) => direction === 'ascending'
1951
+ ? compareContent$3(a.content, b.content)
1952
+ : compareContent$3(b.content, a.content);
1953
+
1954
+ const compareContent$2 = ({ value: a }, { value: b }) => {
1955
+ if (a === undefined) {
1956
+ return b === undefined ? 0 : 1;
1957
+ }
1958
+ return b === undefined ? -1 : a.getTime() - b.getTime();
1959
+ };
1960
+ const compareDateData = (a, b, direction) => direction === 'ascending'
1961
+ ? compareContent$2(a.content, b.content)
1962
+ : compareContent$2(b.content, a.content);
1963
+
1964
+ const compareContent$1 = ({ value: a }, { value: b }) => {
1965
+ if (a === undefined) {
1966
+ return b === undefined ? 0 : 1;
1967
+ }
1968
+ return b === undefined ? -1 : a - b;
1969
+ };
1970
+ const compareNumberData = (a, b, direction) => direction === 'ascending'
1971
+ ? compareContent$1(a.content, b.content)
1972
+ : compareContent$1(b.content, a.content);
1973
+
1974
+ const compareContent = ({ text: a }, { text: b }) => {
1975
+ if (a === undefined) {
1976
+ return b === undefined ? 0 : 1;
1977
+ }
1978
+ return b === undefined ? -1 : a.localeCompare(b);
1979
+ };
1980
+ const compareTextData = (a, b, direction) => direction === 'ascending'
1981
+ ? compareContent(a.content, b.content)
1982
+ : compareContent(b.content, a.content);
1983
+
1984
+ const GROUP_ORDER = [
1985
+ 'checkbox',
1986
+ 'button',
1987
+ 'date',
1988
+ 'number',
1989
+ 'text',
1990
+ ];
1991
+ const UNSORTABLE_GROUPS = ['checkbox'];
1992
+ const useDataTable = () => {
1993
+ const { data } = useControlsContext();
1994
+ const { tableData } = data;
1995
+ const defaultSortIndex = React__namespace["default"].useMemo(() => tableData?.headers?.findIndex(({ type }) => type === 'sort') ?? -1, [tableData]);
1996
+ const [sortState, setSortState] = React__namespace["default"].useState({
1997
+ index: defaultSortIndex,
1998
+ direction: 'ascending',
1999
+ });
2000
+ const mappedHeaders = React__namespace["default"].useMemo(() => tableData?.headers.map((header, index) => {
2001
+ const { type } = header;
2002
+ switch (type) {
2003
+ case 'sort': {
2004
+ return {
2005
+ ...header,
2006
+ content: {
2007
+ ...header.content,
2008
+ onSort: () => {
2009
+ setSortState({
2010
+ index,
2011
+ direction: sortState.index === index
2012
+ ? sortState.direction === 'ascending'
2013
+ ? 'descending'
2014
+ : 'ascending'
2015
+ : 'ascending',
2016
+ });
2017
+ },
2018
+ sortDirection: sortState.index === index ? sortState.direction : undefined,
2019
+ },
2020
+ };
2021
+ }
2022
+ case 'checkbox':
2023
+ case 'text':
2024
+ default: {
2025
+ return header;
2026
+ }
2027
+ }
2028
+ }), [sortState, tableData]);
2029
+ const sortedRows = React__namespace["default"].useMemo(() => {
2030
+ // Early return if there is no table data
2031
+ if (!tableData) {
2032
+ return;
2033
+ }
2034
+ // Return rows as is if there are no sortable columns
2035
+ if (sortState.index < 0) {
2036
+ return tableData.rows;
2037
+ }
2038
+ const { index, direction } = sortState;
2039
+ const groupedRows = {
2040
+ button: [],
2041
+ checkbox: [],
2042
+ date: [],
2043
+ number: [],
2044
+ text: [],
2045
+ };
2046
+ tableData.rows.forEach((row) => {
2047
+ const { type } = row.content[index];
2048
+ groupedRows[type].push(row);
2049
+ });
2050
+ const groupOrder = direction === 'ascending' ? GROUP_ORDER : [...GROUP_ORDER].reverse();
2051
+ return groupOrder
2052
+ .map((groupType) => {
2053
+ if (UNSORTABLE_GROUPS.includes(groupType)) {
2054
+ return groupedRows[groupType];
2055
+ }
2056
+ return groupedRows[groupType].sort((rowA, rowB) => {
2057
+ switch (groupType) {
2058
+ case 'button': {
2059
+ return compareButtonData(rowA.content[index], rowB.content[index], direction);
2060
+ }
2061
+ case 'date': {
2062
+ return compareDateData(rowA.content[index], rowB.content[index], direction);
2063
+ }
2064
+ case 'number': {
2065
+ return compareNumberData(rowA.content[index], rowB.content[index], direction);
2066
+ }
2067
+ case 'text':
2068
+ default: {
2069
+ return compareTextData(rowA.content[index], rowB.content[index], direction);
2070
+ }
2071
+ }
2072
+ });
2073
+ })
2074
+ .flat();
2075
+ }, [sortState, tableData]);
2076
+ return {
2077
+ headers: mappedHeaders ?? [],
2078
+ rows: sortedRows ?? [],
2079
+ };
2080
+ };
2081
+
2082
+ const DataTableControl = () => {
2083
+ const props = useDataTable();
2084
+ const Resolved = useResolvedComposable(DataTable, 'DataTable');
2085
+ return React__namespace["default"].createElement(Resolved, { ...props });
2086
+ };
2087
+
2088
+ const useLoadingIndicator = () => {
2089
+ const { data: { isLoading, loadingIndicatorLabel: label }, } = useControlsContext();
2090
+ return { isLoading, label };
2091
+ };
2092
+
2093
+ const LoadingIndicatorControl = () => {
2094
+ const props = useLoadingIndicator();
2095
+ const Resolved = useResolvedComposable(LoadingIndicator$1, 'LoadingIndicator');
2096
+ return React__namespace["default"].createElement(Resolved, { ...props });
2097
+ };
2098
+
2099
+ const useMessage = () => {
2100
+ const { data: { message = {} }, } = useControlsContext();
2101
+ return message;
2102
+ };
2103
+
2104
+ const MessageControl = () => {
2105
+ const props = useMessage();
2106
+ const Resolved = useResolvedComposable(Message, 'Message');
2107
+ return React__namespace["default"].createElement(Resolved, { ...props });
2108
+ };
2109
+
2110
+ const SearchControl = () => {
2111
+ const { data, onSearch, onSearchQueryChange, onSearchClear } = useControlsContext();
2112
+ const { searchPlaceholder, searchClearLabel, searchQuery, searchSubmitLabel, } = data;
2113
+ const Resolved = useResolvedComposable(SearchField$1, 'SearchField');
2114
+ return (React__namespace["default"].createElement(Resolved, { placeholder: searchPlaceholder, query: searchQuery, clearLabel: searchClearLabel, submitLabel: searchSubmitLabel, onSearch: onSearch, onQueryChange: onSearchQueryChange, onClear: onSearchClear }));
2115
+ };
2116
+
2117
+ const useStatusDisplay = () => {
2118
+ const { data } = useControlsContext();
2119
+ const { statusCounts, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, } = data;
2120
+ if (!statusCounts?.TOTAL) {
2121
+ return { statuses: [], total: 0 };
2122
+ }
2123
+ const statuses = [
2124
+ { name: statusDisplayCompletedLabel ?? '', count: statusCounts.COMPLETE },
2125
+ { name: statusDisplayFailedLabel ?? '', count: statusCounts.FAILED },
2126
+ { name: statusDisplayCanceledLabel ?? '', count: statusCounts.CANCELED },
2127
+ { name: statusDisplayQueuedLabel ?? '', count: statusCounts.QUEUED },
2128
+ ];
2129
+ return { statuses, total: statusCounts.TOTAL };
2130
+ };
2131
+
2132
+ const StatusDisplayControl = () => {
2133
+ const props = useStatusDisplay();
2134
+ const Resolved = useResolvedComposable(StatusDisplay$1, 'StatusDisplay');
2135
+ return React__namespace["default"].createElement(Resolved, { ...props });
2136
+ };
2137
+
2138
+ const useTitle = () => {
2139
+ const { data } = useControlsContext();
2140
+ return {
2141
+ title: data?.title,
2142
+ };
2143
+ };
2144
+
2145
+ const TitleControl = () => {
2146
+ const props = useTitle();
2147
+ const Resolved = useResolvedComposable(Title$1, 'Title');
2148
+ return React__namespace["default"].createElement(Resolved, { ...props });
2149
+ };
2150
+
2151
+ const DEFAULT_ACTION_VIEW_DISPLAY_TEXT = {
2152
+ actionCancelLabel: 'Cancel',
2153
+ actionExitLabel: 'Exit',
2154
+ actionDestinationLabel: 'Destination',
2155
+ statusDisplayCanceledLabel: 'Canceled',
2156
+ statusDisplayCompletedLabel: 'Completed',
2157
+ statusDisplayFailedLabel: 'Failed',
2158
+ statusDisplayInProgressLabel: 'In progress',
2159
+ statusDisplayTotalLabel: 'Total',
2160
+ statusDisplayQueuedLabel: 'Not started',
2161
+ // empty by default
2162
+ tableColumnCancelHeader: '',
2163
+ tableColumnStatusHeader: 'Status',
2164
+ tableColumnFolderHeader: 'Folder',
2165
+ tableColumnNameHeader: 'Name',
2166
+ tableColumnTypeHeader: 'Type',
2167
+ tableColumnSizeHeader: 'Size',
2168
+ tableColumnProgressHeader: 'Progress',
2169
+ };
2170
+ const DEFAULT_LIST_VIEW_DISPLAY_TEXT = {
2171
+ loadingIndicatorLabel: 'Loading',
2172
+ searchSubmitLabel: 'Submit',
2173
+ searchClearLabel: 'Clear search',
2174
+ getDateDisplayValue: (date) => new Intl.DateTimeFormat('en-US', {
2175
+ month: 'short',
2176
+ day: 'numeric',
2177
+ hour: 'numeric',
2178
+ year: 'numeric',
2179
+ minute: 'numeric',
2180
+ hourCycle: 'h12',
2181
+ }).format(date),
2182
+ };
2183
+
2184
+ const DEFAULT_CREATE_FOLDER_VIEW_DISPLAY_TEXT = {
2185
+ ...DEFAULT_ACTION_VIEW_DISPLAY_TEXT,
2186
+ title: 'Create folder',
2187
+ actionStartLabel: 'Create folder',
2188
+ folderNameLabel: 'Folder name',
2189
+ folderNamePlaceholder: 'Folder name cannot contain "/", nor end or start with "."',
2190
+ getValidationMessage: () => 'Folder name cannot contain "/", nor end or start with "."',
2191
+ getActionCompleteMessage: (data) => {
2192
+ const { counts } = data ?? {};
2193
+ const { FAILED, OVERWRITE_PREVENTED } = counts ?? {};
2194
+ if (OVERWRITE_PREVENTED) {
2195
+ return {
2196
+ content: 'A folder already exists with the provided name',
2197
+ type: 'warning',
2198
+ };
2199
+ }
2200
+ if (FAILED) {
2201
+ return {
2202
+ content: 'There was an issue creating the folder.',
2203
+ type: 'error',
2204
+ };
2205
+ }
2206
+ return { content: 'Folder created.', type: 'success' };
2207
+ },
2208
+ };
2209
+
2210
+ const DEFAULT_COPY_VIEW_DISPLAY_TEXT = {
2211
+ ...DEFAULT_ACTION_VIEW_DISPLAY_TEXT,
2212
+ title: 'Copy',
2213
+ actionStartLabel: 'Copy',
2214
+ actionDestinationLabel: 'Copy destination',
2215
+ getListFoldersResultsMessage: ({ folders, query, message, hasError, hasExhaustedSearch, }) => {
2216
+ if (!folders?.length) {
2217
+ return {
2218
+ content: query
2219
+ ? `No folders found matching "${query}"`
2220
+ : 'No subfolders found within selected folder.',
2221
+ type: 'info',
2222
+ };
2223
+ }
2224
+ if (message && !!query) {
2225
+ return { content: 'Error loading folders.', type: 'error' };
2226
+ }
2227
+ if (hasError) {
2228
+ return { content: 'Error loading folders.', type: 'error' };
2229
+ }
2230
+ if (hasExhaustedSearch) {
2231
+ return {
2232
+ content: 'Showing results for up to the first 10,000 items.',
2233
+ type: 'info',
2234
+ };
2235
+ }
2236
+ },
2237
+ loadingIndicatorLabel: 'Loading',
2238
+ overwriteWarningMessage: 'Copied files will overwrite existing files at selected destination.',
2239
+ searchPlaceholder: 'Search for folders',
2240
+ getActionCompleteMessage: (data) => {
2241
+ const { counts } = data ?? {};
2242
+ const { COMPLETE, FAILED, TOTAL } = counts ?? {};
2243
+ if (COMPLETE === TOTAL) {
2244
+ return {
2245
+ content: 'All files copied.',
2246
+ type: 'success',
2247
+ };
2248
+ }
2249
+ if (FAILED === TOTAL) {
2250
+ return { content: 'All files failed to copy.', type: 'error' };
2251
+ }
2252
+ return {
2253
+ content: `${COMPLETE} files copied, ${FAILED} files failed to copy.`,
2254
+ type: 'error',
2255
+ };
2256
+ },
2257
+ searchSubmitLabel: 'Submit',
2258
+ searchClearLabel: 'Clear search',
2259
+ };
2260
+
2261
+ const DEFAULT_DELETE_VIEW_DISPLAY_TEXT = {
2262
+ ...DEFAULT_ACTION_VIEW_DISPLAY_TEXT,
2263
+ title: 'Delete',
2264
+ actionStartLabel: 'Delete',
2265
+ getActionCompleteMessage: (data) => {
2266
+ const { counts } = data ?? {};
2267
+ const { COMPLETE, FAILED, TOTAL } = counts ?? {};
2268
+ if (COMPLETE === TOTAL) {
2269
+ return { content: 'All files deleted.', type: 'success' };
2270
+ }
2271
+ if (FAILED === TOTAL) {
2272
+ return { content: 'All files failed to delete.', type: 'error' };
2273
+ }
2274
+ return {
2275
+ content: `${COMPLETE} files deleted, ${FAILED} files failed to delete.`,
2276
+ type: 'error',
2277
+ };
2278
+ },
2279
+ };
2280
+
2281
+ const DEFAULT_ERROR_MESSAGE$1 = 'There was an error loading items.';
2282
+ const DEFAULT_LOCATION_DETAIL_VIEW_DISPLAY_TEXT = {
2283
+ ...DEFAULT_LIST_VIEW_DISPLAY_TEXT,
2284
+ getListItemsResultMessage: (data) => {
2285
+ const { items, hasExhaustedSearch, hasError = false, message, isLoading, } = data ?? {};
2286
+ if (isLoading) {
2287
+ return undefined;
2288
+ }
2289
+ if (hasError) {
2290
+ return {
2291
+ type: 'error',
2292
+ content: message ?? DEFAULT_ERROR_MESSAGE$1,
2293
+ };
2294
+ }
2295
+ if (!items?.length) {
2296
+ return {
2297
+ type: 'info',
2298
+ content: 'No files.',
2299
+ };
2300
+ }
2301
+ if (hasExhaustedSearch) {
2302
+ return {
2303
+ type: 'info',
2304
+ content: `Showing results for up to the first 10,000 items.`,
2305
+ };
2306
+ }
2307
+ // TODO: add more cases as needed
2308
+ return undefined;
2309
+ },
2310
+ searchSubfoldersToggleLabel: 'Include subfolders',
2311
+ searchPlaceholder: 'Search current folder',
2312
+ tableColumnLastModifiedHeader: 'Last modified',
2313
+ tableColumnNameHeader: 'Name',
2314
+ tableColumnSizeHeader: 'Size',
2315
+ tableColumnTypeHeader: 'Type',
2316
+ selectFileLabel: 'Select file',
2317
+ selectAllFilesLabel: 'Select all files',
2318
+ getActionListItemLabel: (key = '') => {
2319
+ switch (key) {
2320
+ case 'Copy':
2321
+ return 'Copy';
2322
+ case 'Delete':
2323
+ return 'Delete';
2324
+ case 'Create folder':
2325
+ return 'Create folder';
2326
+ case 'Upload':
2327
+ return 'Upload';
2328
+ default:
2329
+ return key;
2330
+ }
2331
+ },
2332
+ getTitle: (location) => {
2333
+ const { current, key } = location;
2334
+ const { bucket = '' } = current ?? {};
2335
+ return key || bucket;
2336
+ },
2337
+ };
2338
+
2339
+ const DEFAULT_ERROR_MESSAGE = 'There was an error loading locations.';
2340
+ const DEFAULT_LOCATIONS_VIEW_DISPLAY_TEXT = {
2341
+ ...DEFAULT_LIST_VIEW_DISPLAY_TEXT,
2342
+ title: 'Home',
2343
+ searchPlaceholder: 'Filter folders and files',
2344
+ getListLocationsResultMessage: (data) => {
2345
+ const { isLoading, locations, hasExhaustedSearch, hasError = false, message, } = data ?? {};
2346
+ if (isLoading) {
2347
+ return undefined;
2348
+ }
2349
+ if (hasError) {
2350
+ return {
2351
+ type: 'error',
2352
+ content: message ?? DEFAULT_ERROR_MESSAGE,
2353
+ };
2354
+ }
2355
+ if (locations?.length === 0 && !hasExhaustedSearch) {
2356
+ return {
2357
+ type: 'info',
2358
+ content: 'No folders or files.',
2359
+ };
2360
+ }
2361
+ if (hasExhaustedSearch) {
2362
+ return {
2363
+ type: 'info',
2364
+ content: `Showing results for up to the first 10,000 items.`,
2365
+ };
2366
+ }
2367
+ // TODO: add more cases as needed
2368
+ return undefined;
2369
+ },
2370
+ getPermissionName: (permissions) => {
2371
+ let text = '';
2372
+ if (permissions.includes('get') || permissions.includes('list')) {
2373
+ text = 'Read';
2374
+ }
2375
+ if (permissions.includes('write') || permissions.includes('delete')) {
2376
+ text = text ? 'Read/Write' : 'Write';
2377
+ }
2378
+ if (!text) {
2379
+ text = permissions.join('/');
2380
+ }
2381
+ return text;
2382
+ },
2383
+ getDownloadLabel: (fileName) => `Download ${fileName}`,
2384
+ tableColumnBucketHeader: 'Bucket',
2385
+ tableColumnFolderHeader: 'Folder',
2386
+ tableColumnPermissionsHeader: 'Permissions',
2387
+ tableColumnActionsHeader: 'Actions',
2388
+ };
2389
+
2390
+ const DEFAULT_UPLOAD_VIEW_DISPLAY_TEXT = {
2391
+ ...DEFAULT_ACTION_VIEW_DISPLAY_TEXT,
2392
+ title: 'Upload',
2393
+ actionStartLabel: 'Upload',
2394
+ addFilesLabel: 'Add files',
2395
+ addFolderLabel: 'Add folder',
2396
+ getActionCompleteMessage: (data) => {
2397
+ const { counts } = data ?? {};
2398
+ const { COMPLETE, FAILED, OVERWRITE_PREVENTED, CANCELED, TOTAL } = counts ?? {};
2399
+ const hasPreventedOverwrite = !!OVERWRITE_PREVENTED;
2400
+ const hasFailure = !!FAILED;
2401
+ const hasSuccess = !!COMPLETE;
2402
+ const hasCanceled = !!CANCELED;
2403
+ const type = hasFailure
2404
+ ? 'error'
2405
+ : hasPreventedOverwrite || hasCanceled
2406
+ ? 'warning'
2407
+ : 'success';
2408
+ const preventedOverwriteMessage = hasPreventedOverwrite
2409
+ ? [
2410
+ 'Overwrite prevented for',
2411
+ OVERWRITE_PREVENTED === TOTAL ? 'all' : String(OVERWRITE_PREVENTED),
2412
+ OVERWRITE_PREVENTED > 1 || OVERWRITE_PREVENTED === TOTAL
2413
+ ? `files`
2414
+ : 'file',
2415
+ ].join(' ')
2416
+ : undefined;
2417
+ const canceledMessage = hasCanceled
2418
+ ? [
2419
+ CANCELED === TOTAL ? 'All' : String(CANCELED),
2420
+ CANCELED > 1 || CANCELED === TOTAL ? `uploads` : 'upload',
2421
+ 'canceled',
2422
+ ].join(' ')
2423
+ : undefined;
2424
+ const failedMessage = hasFailure
2425
+ ? [
2426
+ FAILED === TOTAL ? 'All' : String(FAILED),
2427
+ FAILED > 1 || FAILED === TOTAL ? `files` : 'file',
2428
+ 'failed to upload',
2429
+ ].join(' ')
2430
+ : undefined;
2431
+ const completedMessage = hasSuccess
2432
+ ? [
2433
+ COMPLETE === TOTAL ? 'All' : String(COMPLETE),
2434
+ COMPLETE > 1 || COMPLETE === TOTAL ? `files` : 'file',
2435
+ 'uploaded',
2436
+ ].join(' ')
2437
+ : undefined;
2438
+ const messages = [
2439
+ preventedOverwriteMessage,
2440
+ failedMessage,
2441
+ canceledMessage,
2442
+ completedMessage,
2443
+ ].filter(Boolean);
2444
+ if (messages.length > 0) {
2445
+ return {
2446
+ content: messages.join(', ') + '.',
2447
+ type,
2448
+ };
2449
+ }
2450
+ return { content: 'All files uploaded.', type };
2451
+ },
2452
+ getFilesValidationMessage: (data) => {
2453
+ if (!data?.invalidFiles) {
2454
+ return undefined;
2455
+ }
2456
+ const tooBigFileNames = data.invalidFiles
2457
+ .filter(({ file }) => isFileTooBig(file))
2458
+ .map(({ file }) => file.name)
2459
+ .join(', ');
2460
+ if (tooBigFileNames) {
2461
+ return {
2462
+ content: `Files larger than 160GB cannot be added to the upload queue: ${tooBigFileNames}`,
2463
+ type: 'warning',
2464
+ };
2465
+ }
2466
+ return undefined;
2467
+ },
2468
+ statusDisplayOverwritePreventedLabel: 'Overwrite prevented',
2469
+ overwriteToggleLabel: 'Overwrite existing files',
2470
+ };
2471
+
2472
+ const DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT = {
2473
+ CopyView: DEFAULT_COPY_VIEW_DISPLAY_TEXT,
2474
+ CreateFolderView: DEFAULT_CREATE_FOLDER_VIEW_DISPLAY_TEXT,
2475
+ DeleteView: DEFAULT_DELETE_VIEW_DISPLAY_TEXT,
2476
+ LocationDetailView: DEFAULT_LOCATION_DETAIL_VIEW_DISPLAY_TEXT,
2477
+ LocationsView: DEFAULT_LOCATIONS_VIEW_DISPLAY_TEXT,
2478
+ UploadView: DEFAULT_UPLOAD_VIEW_DISPLAY_TEXT,
2479
+ };
2480
+
2481
+ const { DisplayTextContext, useDisplayText } = uiReactCore.createContextUtilities({
2482
+ contextName: 'DisplayText',
2483
+ errorMessage: '`useDisplayText` must be called inside `DisplayTextProvider`',
2484
+ });
2485
+ function resolveDisplayText(displayText) {
2486
+ if (!displayText)
2487
+ return DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT;
2488
+ // override
2489
+ const { CopyView, CreateFolderView, DeleteView, LocationDetailView, LocationsView, UploadView, } = displayText;
2490
+ return {
2491
+ CopyView: { ...DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT.CopyView, ...CopyView },
2492
+ CreateFolderView: {
2493
+ ...DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT.CreateFolderView,
2494
+ ...CreateFolderView,
2495
+ },
2496
+ DeleteView: {
2497
+ ...DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT.DeleteView,
2498
+ ...DeleteView,
2499
+ },
2500
+ LocationDetailView: {
2501
+ ...DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT.LocationDetailView,
2502
+ ...LocationDetailView,
2503
+ },
2504
+ LocationsView: {
2505
+ ...DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT.LocationsView,
2506
+ ...LocationsView,
2507
+ },
2508
+ UploadView: {
2509
+ ...DEFAULT_STORAGE_BROWSER_DISPLAY_TEXT.UploadView,
2510
+ ...UploadView,
2511
+ },
2512
+ };
2513
+ }
2514
+ function DisplayTextProvider({ children, displayText: _override, }) {
2515
+ // do deep merge here of default and override here
2516
+ const resolvedDisplayText = React__namespace["default"].useMemo(() => resolveDisplayText(_override), [_override]);
2517
+ return (React__namespace["default"].createElement(DisplayTextContext.Provider, { value: resolvedDisplayText }, children));
2518
+ }
2519
+
2520
+ const getActionIcon = (status) => {
2521
+ switch (status) {
2522
+ case 'PENDING': {
2523
+ return 'action-progress';
2524
+ }
2525
+ case 'COMPLETE': {
2526
+ return 'action-success';
2527
+ }
2528
+ case 'FAILED': {
2529
+ return 'action-error';
2530
+ }
2531
+ case 'OVERWRITE_PREVENTED': {
2532
+ return 'action-info';
2533
+ }
2534
+ case 'CANCELED': {
2535
+ return 'action-canceled';
2536
+ }
2537
+ case 'QUEUED':
2538
+ default: {
2539
+ return 'action-queued';
2540
+ }
2541
+ }
2542
+ };
2543
+
2544
+ const getFileTypeDisplayValue = (fileName) => fileName.lastIndexOf('.') !== -1
2545
+ ? fileName.slice(fileName.lastIndexOf('.') + 1)
2546
+ : '';
2547
+
2548
+ const getPercentValue = (value) => Math.round(value * 100);
2549
+
2550
+ const getDefaultActionViewHeaders = ({ displayText: { tableColumnNameHeader, tableColumnTypeHeader, tableColumnSizeHeader, tableColumnStatusHeader, tableColumnCancelHeader, tableColumnFolderHeader, }, }) => {
2551
+ return [
2552
+ {
2553
+ key: 'name',
2554
+ type: 'sort',
2555
+ content: { label: tableColumnNameHeader },
2556
+ },
2557
+ {
2558
+ key: 'folder',
2559
+ type: 'sort',
2560
+ content: { label: tableColumnFolderHeader },
2561
+ },
2562
+ { key: 'type', type: 'sort', content: { label: tableColumnTypeHeader } },
2563
+ { key: 'size', type: 'sort', content: { label: tableColumnSizeHeader } },
2564
+ {
2565
+ key: 'status',
2566
+ type: 'sort',
2567
+ content: { label: tableColumnStatusHeader },
2568
+ },
2569
+ { key: 'cancel', type: 'text', content: { text: tableColumnCancelHeader } },
2570
+ ];
2571
+ };
2572
+
2573
+ const getTaskStatusDisplayLabel = ({ status, displayText: { statusDisplayInProgressLabel, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, statusDisplayOverwritePreventedLabel, }, }) => {
2574
+ switch (status) {
2575
+ case 'PENDING':
2576
+ return statusDisplayInProgressLabel;
2577
+ case 'CANCELED':
2578
+ return statusDisplayCanceledLabel;
2579
+ case 'COMPLETE':
2580
+ return statusDisplayCompletedLabel;
2581
+ case 'FAILED':
2582
+ return statusDisplayFailedLabel;
2583
+ case 'QUEUED':
2584
+ return statusDisplayQueuedLabel;
2585
+ case 'OVERWRITE_PREVENTED':
2586
+ return statusDisplayOverwritePreventedLabel;
2587
+ default:
2588
+ return statusDisplayQueuedLabel;
2589
+ }
2590
+ };
2591
+ const getProgressHeader = (label) => ({
2592
+ key: 'progress',
2593
+ type: 'sort',
2594
+ content: { label },
2595
+ });
2596
+ const getActionViewTableData = ({ tasks, displayText, isProcessing, locationKey, shouldDisplayProgress = false, onTaskRemove, }) => {
2597
+ const headers = [
2598
+ ...getDefaultActionViewHeaders({
2599
+ displayText,
2600
+ }),
2601
+ ];
2602
+ if (shouldDisplayProgress) {
2603
+ headers.splice(-1, 0, getProgressHeader(displayText.tableColumnProgressHeader));
2604
+ }
2605
+ const rows = tasks.map((task) => {
2606
+ const { cancel, data, progress, status } = task;
2607
+ const { id } = data;
2608
+ const displayKey = isFileDataItem(data)
2609
+ ? data.fileKey
2610
+ : data.key.split('/').pop() ?? '';
2611
+ return {
2612
+ key: id,
2613
+ content: headers.map(({ key: columnKey }) => {
2614
+ const key = `${columnKey}-${id}`;
2615
+ switch (columnKey) {
2616
+ case 'name': {
2617
+ return {
2618
+ key,
2619
+ type: 'text',
2620
+ content: {
2621
+ icon: getActionIcon(status),
2622
+ text: displayKey,
2623
+ },
2624
+ };
2625
+ }
2626
+ case 'folder': {
2627
+ if (locationKey) {
2628
+ return { key, type: 'text', content: { text: locationKey } };
2629
+ }
2630
+ if (isFileItem(data)) {
2631
+ const { webkitRelativePath } = data.file;
2632
+ return {
2633
+ key,
2634
+ type: 'text',
2635
+ content: {
2636
+ text: webkitRelativePath
2637
+ ? webkitRelativePath.slice(0, webkitRelativePath.lastIndexOf('/') + 1)
2638
+ : '-',
2639
+ },
2640
+ };
2641
+ }
2642
+ return { key, type: 'text', content: { text: '/' } };
2643
+ }
2644
+ case 'type': {
2645
+ return {
2646
+ key,
2647
+ type: 'text',
2648
+ content: { text: getFileTypeDisplayValue(displayKey) },
2649
+ };
2650
+ }
2651
+ case 'size': {
2652
+ const value = isFileItem(data)
2653
+ ? data.file.size
2654
+ : isFileDataItem(data)
2655
+ ? data.size
2656
+ : undefined;
2657
+ return {
2658
+ key,
2659
+ type: 'number',
2660
+ content: {
2661
+ value,
2662
+ displayValue: value ? ui.humanFileSize(value, true) : '-',
2663
+ },
2664
+ };
2665
+ }
2666
+ case 'status': {
2667
+ return {
2668
+ key,
2669
+ type: 'text',
2670
+ content: {
2671
+ text: getTaskStatusDisplayLabel({ status, displayText }),
2672
+ },
2673
+ };
2674
+ }
2675
+ case 'progress': {
2676
+ return {
2677
+ key,
2678
+ type: 'number',
2679
+ content: {
2680
+ value: progress,
2681
+ displayValue: `${getPercentValue(progress ?? 0)}%`,
2682
+ },
2683
+ };
2684
+ }
2685
+ case 'cancel': {
2686
+ const isPending = status === 'PENDING';
2687
+ const isQueued = status === 'QUEUED';
2688
+ const isDisabled = (!isPending && !isQueued) || !cancel || progress === 1;
2689
+ const ariaLabel = `${isProcessing ? 'Cancel' : 'Remove'} item: ${displayKey}`;
2690
+ return {
2691
+ key,
2692
+ type: 'button',
2693
+ content: {
2694
+ isDisabled,
2695
+ onClick: () => {
2696
+ if (!isProcessing) {
2697
+ onTaskRemove?.(task);
2698
+ }
2699
+ cancel?.();
2700
+ },
2701
+ ariaLabel,
2702
+ icon: 'cancel',
2703
+ },
2704
+ };
2705
+ }
2706
+ default:
2707
+ return { key, type: 'text', content: {} };
2708
+ }
2709
+ }),
2710
+ };
2711
+ });
2712
+ return { headers, rows };
2713
+ };
2714
+
2715
+ const defaultValue$2 = {};
2716
+ const { useFoldersMessage, FoldersMessageProvider } = uiReactCore.createContextUtilities({ contextName: 'FoldersMessage', defaultValue: defaultValue$2 });
2717
+ const FoldersMessageControl = () => {
2718
+ const { CopyView: { getListFoldersResultsMessage }, } = useDisplayText();
2719
+ const { hasError, folders, message, query, hasExhaustedSearch } = useFoldersMessage();
2720
+ const messageContent = getListFoldersResultsMessage({
2721
+ hasError,
2722
+ folders,
2723
+ message,
2724
+ query,
2725
+ hasExhaustedSearch,
2726
+ });
2727
+ return (React__namespace["default"].createElement(ControlsContextProvider, { data: { message: messageContent } },
2728
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__message` },
2729
+ React__namespace["default"].createElement(MessageControl, null))));
2730
+ };
2731
+ FoldersMessageControl.displayName = 'FoldersMessage';
2732
+
2733
+ const defaultValue$1 = {};
2734
+ const { FoldersPaginationProvider, useFoldersPagination } = uiReactCore.createContextUtilities({ contextName: 'FoldersPagination', defaultValue: defaultValue$1 });
2735
+ const FoldersPaginationControl = () => {
2736
+ const props = useFoldersPagination();
2737
+ const Resolved = useResolvedComposable(Pagination$1, 'Pagination');
2738
+ return React__namespace["default"].createElement(Resolved, { ...props });
2739
+ };
2740
+ FoldersPaginationControl.displayName = 'FoldersPagination';
2741
+
2742
+ const DESTINATION_PICKER_COLUMNS = [
2743
+ { key: 'name', type: 'sort', content: { label: 'Folder name' } },
2744
+ ];
2745
+ const getDestinationPickerTableData = ({ prefix, path, folders, onSelectFolder, }) => {
2746
+ const rows = !folders
2747
+ ? []
2748
+ : folders.map(({ id, key }) => {
2749
+ const folderSubPath = key.slice(`${prefix ?? ''}${path}`.length);
2750
+ const folderLocationPath = key.slice(prefix.length);
2751
+ const row = {
2752
+ key: id,
2753
+ content: [
2754
+ {
2755
+ key: `${DESTINATION_PICKER_COLUMNS[0].key}-${id}`,
2756
+ type: 'button',
2757
+ content: {
2758
+ icon: 'folder',
2759
+ ariaLabel: folderSubPath,
2760
+ label: folderSubPath,
2761
+ onClick: () => {
2762
+ onSelectFolder?.(id, folderLocationPath);
2763
+ },
2764
+ },
2765
+ },
2766
+ ],
2767
+ };
2768
+ return row;
2769
+ });
2770
+ return {
2771
+ headers: DESTINATION_PICKER_COLUMNS,
2772
+ rows,
2773
+ };
2774
+ };
2775
+
2776
+ const defaultValue = {};
2777
+ const { useFoldersTable, FoldersTableProvider } = uiReactCore.createContextUtilities({ contextName: 'FoldersTable', defaultValue });
2778
+ const FoldersTableControl = () => {
2779
+ const { destination, folders, onSelectFolder } = useFoldersTable();
2780
+ const { current, path = '' } = destination ?? {};
2781
+ const tableData = getDestinationPickerTableData({
2782
+ prefix: current?.prefix ?? '',
2783
+ path,
2784
+ folders,
2785
+ onSelectFolder,
2786
+ });
2787
+ return (React__namespace["default"].createElement(ControlsContextProvider, { data: { tableData } },
2788
+ React__namespace["default"].createElement(DataTableControl, null)));
2789
+ };
2790
+ FoldersTableControl.displayName = 'FoldersTable';
2791
+
2792
+ function CopyViewProvider({ children, ...props }) {
2793
+ const { CopyView: displayText } = useDisplayText();
2794
+ const { actionCancelLabel, actionDestinationLabel, actionExitLabel, actionStartLabel, getActionCompleteMessage, overwriteWarningMessage, searchPlaceholder, searchSubmitLabel, searchClearLabel, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, } = displayText;
2795
+ const { destination, folders, isProcessing, isProcessingComplete, location, statusCounts, tasks, onActionCancel, onActionExit, onActionStart, onSelectDestination, onTaskRemove, } = props;
2796
+ const { hasNextPage, highestPageVisited, hasError: hasFoldersError, message: foldersErrorMessage, query, hasExhaustedSearch, isLoading, page, pageItems, onPaginate, onQuery, onSearchClear, onSearch, onSelectFolder, } = folders;
2797
+ const { key: locationKey } = location ?? {};
2798
+ const tableData = getActionViewTableData({
2799
+ tasks,
2800
+ locationKey,
2801
+ isProcessing,
2802
+ displayText,
2803
+ onTaskRemove,
2804
+ });
2805
+ const isActionStartDisabled = isProcessing || isProcessingComplete || !destination?.current;
2806
+ const isActionCancelDisabled = !isProcessing || isProcessingComplete;
2807
+ const message = !isProcessingComplete
2808
+ ? {
2809
+ content: overwriteWarningMessage,
2810
+ type: 'warning',
2811
+ }
2812
+ : getActionCompleteMessage({ counts: statusCounts });
2813
+ return (React__namespace["default"].createElement(ControlsContextProvider, { data: {
2814
+ actionCancelLabel,
2815
+ actionDestinationLabel,
2816
+ actionExitLabel,
2817
+ actionStartLabel,
2818
+ destination,
2819
+ isActionCancelDisabled,
2820
+ isActionDestinationNavigable: !isProcessing && !isProcessingComplete,
2821
+ isActionExitDisabled: isProcessing,
2822
+ isActionStartDisabled,
2823
+ isLoading,
2824
+ message,
2825
+ searchQuery: query,
2826
+ searchPlaceholder,
2827
+ searchSubmitLabel,
2828
+ searchClearLabel,
2829
+ statusCounts,
2830
+ statusDisplayCanceledLabel,
2831
+ statusDisplayCompletedLabel,
2832
+ statusDisplayFailedLabel,
2833
+ statusDisplayQueuedLabel,
2834
+ tableData,
2835
+ }, onActionCancel: onActionCancel, onActionExit: onActionExit, onActionStart: onActionStart, onSearch: onSearch, onSearchClear: onSearchClear, onSearchQueryChange: onQuery, onSelectDestination: onSelectDestination },
2836
+ React__namespace["default"].createElement(FoldersPaginationProvider, { hasNextPage: hasNextPage, highestPageVisited: highestPageVisited, page: page, onPaginate: onPaginate },
2837
+ React__namespace["default"].createElement(FoldersTableProvider, { destination: destination, folders: pageItems, onSelectFolder: onSelectFolder },
2838
+ React__namespace["default"].createElement(FoldersMessageProvider, { folders: folders.pageItems, hasError: hasFoldersError, message: foldersErrorMessage, query: query, hasExhaustedSearch: hasExhaustedSearch }, children)))));
2839
+ }
2840
+
2841
+ const getNavigationItems = ({ destinationParts, location, onNavigate, }) => {
2842
+ const { bucket, permissions, prefix = '', type } = location;
2843
+ const destinationSubpaths = [];
2844
+ return destinationParts.map((part, index) => {
2845
+ const isCurrent = index === destinationParts.length - 1;
2846
+ if (index !== 0) {
2847
+ destinationSubpaths.push(part);
2848
+ }
2849
+ const destinationPath = `${destinationSubpaths.concat('').join('/')}`;
2850
+ const destination = {
2851
+ id: crypto.randomUUID(),
2852
+ type,
2853
+ permissions,
2854
+ bucket,
2855
+ prefix,
2856
+ };
2857
+ return {
2858
+ name: part,
2859
+ ...(isCurrent && { isCurrent }),
2860
+ onNavigate: () => {
2861
+ onNavigate?.(destination, destinationPath);
2862
+ },
2863
+ };
2864
+ });
2865
+ };
2866
+
2867
+ const getNavigationParts = ({ location, path, includeBucketInPrefix, }) => {
2868
+ const { bucket, prefix = '', type } = location;
2869
+ const trimmedPrefix = prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;
2870
+ const trimmedPath = path.endsWith('/') ? path.slice(0, -1) : path;
2871
+ const firstPrefixPart = [];
2872
+ if (type !== 'BUCKET') {
2873
+ if (includeBucketInPrefix) {
2874
+ firstPrefixPart.push(bucket);
2875
+ }
2876
+ if (trimmedPrefix) {
2877
+ if (includeBucketInPrefix) {
2878
+ firstPrefixPart.push('/');
2879
+ }
2880
+ firstPrefixPart.push(trimmedPrefix);
2881
+ }
2882
+ }
2883
+ const prefixParts = type === 'BUCKET' ? [bucket] : [firstPrefixPart.join('')];
2884
+ if (type === 'BUCKET' && trimmedPrefix) {
2885
+ prefixParts.push(trimmedPrefix);
2886
+ }
2887
+ const pathParts = trimmedPath ? trimmedPath.split('/') : [];
2888
+ return prefixParts.concat(pathParts);
2889
+ };
2890
+
2891
+ // import { ActionDestinationProps } from '../../composables/ActionDestination';
2892
+ const useActionDestination = () => {
2893
+ const { data, onSelectDestination } = useControlsContext();
2894
+ const { actionDestinationLabel, isActionDestinationNavigable, destination } = data;
2895
+ return React__namespace["default"].useMemo(() => {
2896
+ if (!destination?.current) {
2897
+ return { items: [] };
2898
+ }
2899
+ const { current, path } = destination;
2900
+ const destinationParts = getNavigationParts({
2901
+ location: current,
2902
+ path,
2903
+ });
2904
+ return {
2905
+ label: actionDestinationLabel,
2906
+ items: getNavigationItems({
2907
+ location: current,
2908
+ destinationParts,
2909
+ onNavigate: onSelectDestination,
2910
+ }),
2911
+ isNavigable: isActionDestinationNavigable,
2912
+ };
2913
+ }, [
2914
+ actionDestinationLabel,
2915
+ isActionDestinationNavigable,
2916
+ destination,
2917
+ onSelectDestination,
2918
+ ]);
2919
+ };
2920
+
2921
+ const ActionDestinationControl = () => {
2922
+ const props = useActionDestination();
2923
+ const Resolved = useResolvedComposable(ActionDestination$1, 'ActionDestination');
2924
+ return React__namespace["default"].createElement(Resolved, { ...props });
2925
+ };
2926
+
2927
+ const INITIAL_STATUS_COUNTS = {
2928
+ CANCELED: 0,
2929
+ COMPLETE: 0,
2930
+ FAILED: 0,
2931
+ PENDING: 0,
2932
+ OVERWRITE_PREVENTED: 0,
2933
+ QUEUED: 0,
2934
+ TOTAL: 0,
2935
+ };
2936
+
2937
+ const getStatusCounts = (tasks = []) => tasks.reduce((counts, { status }) => ({ ...counts, [status]: counts[status] + 1 }), { ...INITIAL_STATUS_COUNTS, TOTAL: tasks.length });
2938
+ const isProcessingTasks = (statusCounts) => {
2939
+ if (statusCounts.TOTAL === 0 || statusCounts.TOTAL === statusCounts.QUEUED) {
2940
+ return false;
2941
+ }
2942
+ return !(statusCounts.QUEUED === 0 && statusCounts.PENDING === 0);
2943
+ };
2944
+ const hasCompletedProcessingTasks = (statusCounts) => {
2945
+ if (statusCounts.TOTAL === 0 || isProcessingTasks(statusCounts))
2946
+ return false;
2947
+ return statusCounts.QUEUED === 0 && statusCounts.PENDING === 0;
2948
+ };
2949
+
2950
+ const QUEUED_TASK_BASE = {
2951
+ cancel: undefined,
2952
+ message: undefined,
2953
+ progress: undefined,
2954
+ status: 'QUEUED',
2955
+ };
2956
+ const isTaskHandlerInput = (input) => !!input.data;
2957
+ const useProcessTasks = (handler, items, options) => {
2958
+ const { concurrency, ...callbacks } = options ?? {};
2959
+ const callbacksRef = React__namespace["default"].useRef(callbacks);
2960
+ if (callbacks) {
2961
+ callbacksRef.current = callbacks;
2962
+ }
2963
+ const tasksRef = React__namespace["default"].useRef(new Map());
2964
+ const flush = React__namespace["default"].useReducer(() => ({}), {})[1];
2965
+ const updateTask = React__namespace["default"].useCallback((id, next) => {
2966
+ const { onTaskRemove } = callbacksRef.current;
2967
+ const task = tasksRef.current.get(id);
2968
+ if (!task)
2969
+ return;
2970
+ if (!next) {
2971
+ onTaskRemove?.(task);
2972
+ tasksRef.current.delete(id);
2973
+ }
2974
+ else {
2975
+ tasksRef.current.set(id, { ...task, ...next });
2976
+ }
2977
+ flush();
2978
+ }, [flush]);
2979
+ const createTask = React__namespace["default"].useCallback((data) => {
2980
+ const getTask = () => tasksRef.current.get(data.id);
2981
+ const { onTaskCancel } = callbacksRef.current;
2982
+ function cancel() {
2983
+ const task = getTask();
2984
+ if (!task || task?.status !== 'QUEUED')
2985
+ return;
2986
+ if (task && ui.isFunction(onTaskCancel))
2987
+ onTaskCancel(task);
2988
+ updateTask(data.id, { cancel: undefined, status: 'CANCELED' });
2989
+ }
2990
+ const task = { ...QUEUED_TASK_BASE, cancel, data };
2991
+ tasksRef.current.set(data.id, task);
2992
+ }, [updateTask]);
2993
+ React__namespace["default"].useEffect(() => {
2994
+ // Sync tasks with items by first creating a lookup of current tasks
2995
+ const taskLookup = {};
2996
+ tasksRef.current.forEach(({ data }) => {
2997
+ taskLookup[data.id] = true;
2998
+ });
2999
+ items?.forEach((item) => {
3000
+ if (!taskLookup[item.id]) {
3001
+ // If an item doesn't yet have a task created for it, create one
3002
+ createTask(item);
3003
+ }
3004
+ // Remove the item from the lookup to mark it as "synced"
3005
+ delete taskLookup[item.id];
3006
+ });
3007
+ // Remaining tasks are items which have been removed from state but not yet from tasks, so they should be removed
3008
+ Object.keys(taskLookup).forEach((taskId) => {
3009
+ // This should not happen, but if the task is pending then it cannot be removed
3010
+ if (tasksRef.current.get(taskId)?.status === 'PENDING')
3011
+ return;
3012
+ updateTask(taskId);
3013
+ });
3014
+ flush();
3015
+ }, [createTask, flush, updateTask, items]);
3016
+ const processNextTask = (_input) => {
3017
+ const hasInputData = isTaskHandlerInput(_input);
3018
+ if (hasInputData) {
3019
+ createTask(_input.data);
3020
+ flush();
3021
+ }
3022
+ const { data } = hasInputData
3023
+ ? _input
3024
+ : [...tasksRef.current.values()].find(({ status }) => status === 'QUEUED') ?? {};
3025
+ if (!data)
3026
+ return;
3027
+ const { onTaskCancel, onTaskComplete, onTaskError, onTaskProgress, onTaskSuccess, } = callbacksRef.current;
3028
+ const getTask = () => tasksRef.current.get(data.id);
3029
+ const onProgress = ({ id }, progress) => {
3030
+ const task = getTask();
3031
+ if (task && ui.isFunction(onTaskProgress)) {
3032
+ onTaskProgress(task, progress);
3033
+ }
3034
+ updateTask(id, { progress });
3035
+ };
3036
+ const { options } = _input;
3037
+ const input = { ..._input, data, options: { ...options, onProgress } };
3038
+ const { cancel: _cancel, result } = handler(input);
3039
+ const cancel = !_cancel
3040
+ ? undefined
3041
+ : () => {
3042
+ const task = getTask();
3043
+ if (task && ui.isFunction(onTaskCancel))
3044
+ onTaskCancel(task);
3045
+ _cancel();
3046
+ };
3047
+ result
3048
+ .then((output) => {
3049
+ const task = getTask();
3050
+ if (task && ui.isFunction(onTaskSuccess))
3051
+ onTaskSuccess(task);
3052
+ updateTask(data.id, output);
3053
+ })
3054
+ .catch((e) => {
3055
+ const task = getTask();
3056
+ if (task && ui.isFunction(onTaskError))
3057
+ onTaskError(task, e);
3058
+ updateTask(data.id, { message: e.message, status: 'FAILED' });
3059
+ })
3060
+ .finally(() => {
3061
+ const task = getTask();
3062
+ if (task && ui.isFunction(onTaskComplete))
3063
+ onTaskComplete(task);
3064
+ // ignore process next task for single operation inputs
3065
+ if (hasInputData)
3066
+ return;
3067
+ processNextTask(_input);
3068
+ });
3069
+ updateTask(data.id, { cancel, status: 'PENDING' });
3070
+ };
3071
+ const tasks = [...tasksRef.current.values()];
3072
+ const statusCounts = getStatusCounts(tasks);
3073
+ const isProcessing = isProcessingTasks(statusCounts);
3074
+ const isProcessingComplete = hasCompletedProcessingTasks(statusCounts);
3075
+ const handleProcessTasks = (input) => {
3076
+ if (isProcessing) {
3077
+ return;
3078
+ }
3079
+ if (!concurrency) {
3080
+ processNextTask(input);
3081
+ return;
3082
+ }
3083
+ let count = 0;
3084
+ while (count < concurrency) {
3085
+ processNextTask(input);
3086
+ count++;
3087
+ }
3088
+ };
3089
+ return [
3090
+ { isProcessing, isProcessingComplete, statusCounts, tasks },
3091
+ handleProcessTasks,
3092
+ ];
3093
+ };
3094
+
3095
+ const usePaginate = ({ hasNextToken, items, paginateCallback, pageSize, }) => {
3096
+ const [currentPage, setCurrentPage] = React__namespace["default"].useState(1);
3097
+ const handleReset = React__namespace["default"].useRef(() => {
3098
+ setCurrentPage(1);
3099
+ }).current;
3100
+ return React__namespace["default"].useMemo(() => {
3101
+ const resultCount = Array.isArray(items) ? items.length : 0;
3102
+ const highestPageVisited = Math.ceil(resultCount / pageSize);
3103
+ const isFirstPage = currentPage === 1;
3104
+ const start = isFirstPage ? 0 : (currentPage - 1) * pageSize;
3105
+ const end = isFirstPage ? pageSize : currentPage * pageSize;
3106
+ const pageItems = Array.isArray(items) ? items.slice(start, end) : [];
3107
+ return {
3108
+ currentPage,
3109
+ onPaginate: (page) => {
3110
+ const shouldPaginate = page >= 1 && (page <= highestPageVisited || hasNextToken);
3111
+ if (shouldPaginate) {
3112
+ if (ui.isFunction(paginateCallback))
3113
+ paginateCallback();
3114
+ setCurrentPage(page);
3115
+ }
3116
+ },
3117
+ handleReset,
3118
+ highestPageVisited,
3119
+ pageItems,
3120
+ };
3121
+ }, [
3122
+ currentPage,
3123
+ handleReset,
3124
+ hasNextToken,
3125
+ items,
3126
+ paginateCallback,
3127
+ pageSize,
3128
+ ]);
3129
+ };
3130
+
3131
+ function useSearch(props) {
3132
+ const { onSearch } = props;
3133
+ const [searchQuery, setQuery] = React__namespace["default"].useState('');
3134
+ const [isSearchingSubfolders, setIsSearchingSubfolders] = React__namespace["default"].useState(false);
3135
+ const resetSearch = () => {
3136
+ setQuery('');
3137
+ setIsSearchingSubfolders(false);
3138
+ };
3139
+ return {
3140
+ searchQuery,
3141
+ isSearchingSubfolders,
3142
+ onSearchQueryChange: (value) => {
3143
+ setQuery(value);
3144
+ },
3145
+ onToggleSearchSubfolders: () => {
3146
+ setIsSearchingSubfolders((prev) => !prev);
3147
+ },
3148
+ onSearchSubmit: () => {
3149
+ onSearch?.(searchQuery, isSearchingSubfolders);
3150
+ },
3151
+ resetSearch,
3152
+ };
3153
+ }
3154
+
3155
+ const DEFAULT_PAGE_SIZE$2 = 100;
3156
+ const DEFAULT_LIST_OPTIONS$2 = {
3157
+ pageSize: DEFAULT_PAGE_SIZE$2,
3158
+ delimiter: '/',
3159
+ exclude: 'FILE',
3160
+ };
3161
+ const DEFAULT_REFRESH_OPTIONS = { ...DEFAULT_LIST_OPTIONS$2, refresh: true };
3162
+ const listLocationItemsAction$1 = createEnhancedListHandler(listLocationItemsHandler);
3163
+ const useFolders = ({ destination, setDestination, }) => {
3164
+ const { current, key } = destination;
3165
+ const [{ data, hasError, isLoading, message }, handleList] = uiReactCore.useDataState(listLocationItemsAction$1, { items: [], nextToken: undefined });
3166
+ const getInput = useGetActionInput();
3167
+ const { items, nextToken, search } = data;
3168
+ const { hasExhaustedSearch = false } = search ?? {};
3169
+ const onInitialize = React__namespace["default"].useCallback(() => {
3170
+ handleList({
3171
+ config: getInput(),
3172
+ prefix: key,
3173
+ options: { ...DEFAULT_REFRESH_OPTIONS },
3174
+ });
3175
+ }, [getInput, handleList, key]);
3176
+ const hasNextToken = !!nextToken;
3177
+ const paginateCallback = () => {
3178
+ if (!nextToken)
3179
+ return;
3180
+ handleList({
3181
+ config: getInput(),
3182
+ prefix: key,
3183
+ options: { ...DEFAULT_LIST_OPTIONS$2, nextToken },
3184
+ });
3185
+ };
3186
+ const { currentPage: page, onPaginate, highestPageVisited, pageItems, handleReset, } = usePaginate({
3187
+ items,
3188
+ paginateCallback,
3189
+ pageSize: DEFAULT_PAGE_SIZE$2,
3190
+ hasNextToken,
3191
+ });
3192
+ const onSearch = (query) => {
3193
+ handleReset();
3194
+ handleList({
3195
+ config: getInput(),
3196
+ prefix: key,
3197
+ options: {
3198
+ ...DEFAULT_LIST_OPTIONS$2,
3199
+ search: { query, filterBy: 'key' },
3200
+ },
3201
+ });
3202
+ };
3203
+ const { onSearchSubmit, searchQuery: query, resetSearch, onSearchQueryChange: onQuery, } = useSearch({ onSearch });
3204
+ const onSelectFolder = (id, folderLocationPath) => {
3205
+ if (!current) {
3206
+ return;
3207
+ }
3208
+ resetSearch();
3209
+ setDestination({
3210
+ current: { ...current, id },
3211
+ path: folderLocationPath,
3212
+ key: `${current.prefix ?? ''}${folderLocationPath}`,
3213
+ });
3214
+ };
3215
+ return {
3216
+ hasError,
3217
+ hasNextPage: hasNextToken,
3218
+ highestPageVisited,
3219
+ isLoading,
3220
+ message,
3221
+ onInitialize,
3222
+ page,
3223
+ pageItems,
3224
+ query,
3225
+ hasExhaustedSearch,
3226
+ onPaginate,
3227
+ onQuery,
3228
+ onSearch: onSearchSubmit,
3229
+ onSearchClear: () => {
3230
+ handleReset();
3231
+ resetSearch();
3232
+ handleList({
3233
+ config: getInput(),
3234
+ prefix: key,
3235
+ options: { ...DEFAULT_REFRESH_OPTIONS },
3236
+ });
3237
+ },
3238
+ onSelectFolder,
3239
+ };
3240
+ };
3241
+
3242
+ const useCopyView = (options) => {
3243
+ const { onExit } = options ?? {};
3244
+ const [{ location, locationItems: { fileDataItems }, }, dispatchStoreAction,] = useStore();
3245
+ const getInput = useGetActionInput();
3246
+ const [processState, handleProcess] = useProcessTasks(copyHandler, fileDataItems, { concurrency: 4 });
3247
+ const [destination, setDestination] = React.useState(location);
3248
+ const folders = useFolders({ destination, setDestination });
3249
+ const { isProcessing, isProcessingComplete, statusCounts, tasks } = processState;
3250
+ const { current } = location;
3251
+ const { onInitialize } = folders;
3252
+ // initial load
3253
+ React__namespace["default"].useEffect(() => {
3254
+ onInitialize();
3255
+ }, [onInitialize]);
3256
+ const onActionStart = () => {
3257
+ handleProcess({
3258
+ config: getInput(),
3259
+ destinationPrefix: destination.key,
3260
+ });
3261
+ };
3262
+ const onActionCancel = () => {
3263
+ tasks.forEach((task) => {
3264
+ if (ui.isFunction(task.cancel))
3265
+ task.cancel();
3266
+ });
3267
+ };
3268
+ const onActionExit = () => {
3269
+ // clear files state
3270
+ dispatchStoreAction({ type: 'RESET_LOCATION_ITEMS' });
3271
+ // clear selected action
3272
+ dispatchStoreAction({ type: 'RESET_ACTION_TYPE' });
3273
+ if (ui.isFunction(onExit))
3274
+ onExit(current);
3275
+ };
3276
+ const onTaskRemove = React__namespace["default"].useCallback(({ data }) => {
3277
+ dispatchStoreAction({ type: 'REMOVE_LOCATION_ITEM', id: data.id });
3278
+ }, [dispatchStoreAction]);
3279
+ const onSelectDestination = (selectedDestination, path) => {
3280
+ setDestination({
3281
+ current: selectedDestination,
3282
+ path: path ?? '',
3283
+ key: `${selectedDestination.prefix ?? ''}${path}`,
3284
+ });
3285
+ };
3286
+ return {
3287
+ destination,
3288
+ isProcessing,
3289
+ isProcessingComplete,
3290
+ folders,
3291
+ location,
3292
+ statusCounts,
3293
+ tasks,
3294
+ onActionCancel,
3295
+ onActionStart,
3296
+ onActionExit,
3297
+ onSelectDestination,
3298
+ onTaskRemove,
3299
+ };
3300
+ };
3301
+
3302
+ const CopyView = ({ className, ...props }) => {
3303
+ const state = useCopyView(props);
3304
+ const { isProcessing, isProcessingComplete } = state;
3305
+ return (React__namespace["default"].createElement(ViewElement, { className: ui.classNames(STORAGE_BROWSER_BLOCK, className) },
3306
+ React__namespace["default"].createElement(CopyViewProvider, { ...state },
3307
+ React__namespace["default"].createElement(ActionExitControl, null),
3308
+ React__namespace["default"].createElement(TitleControl, null),
3309
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__data-table` },
3310
+ React__namespace["default"].createElement(DataTableControl, null)),
3311
+ isProcessing || isProcessingComplete ? null : (React__namespace["default"].createElement(React__namespace["default"].Fragment, null,
3312
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__controls` },
3313
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__search` },
3314
+ React__namespace["default"].createElement(SearchControl, null)),
3315
+ React__namespace["default"].createElement(FoldersPaginationControl, null)),
3316
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__data-table` },
3317
+ React__namespace["default"].createElement(LoadingIndicatorControl, null),
3318
+ React__namespace["default"].createElement(FoldersTableControl, null),
3319
+ React__namespace["default"].createElement(FoldersMessageControl, null)))),
3320
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__summary` },
3321
+ React__namespace["default"].createElement(ActionDestinationControl, null),
3322
+ React__namespace["default"].createElement(StatusDisplayControl, null)),
3323
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__footer` },
3324
+ React__namespace["default"].createElement(MessageControl, null),
3325
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__buttons` },
3326
+ React__namespace["default"].createElement(ActionCancelControl, null),
3327
+ React__namespace["default"].createElement(ActionStartControl, null))))));
3328
+ };
3329
+ CopyView.displayName = 'CopyView';
3330
+ CopyView.Provider = CopyViewProvider;
3331
+ CopyView.Cancel = ActionCancelControl;
3332
+ CopyView.Destination = ActionDestinationControl;
3333
+ CopyView.Exit = ActionExitControl;
3334
+ CopyView.FoldersLoadingIndicator = LoadingIndicatorControl;
3335
+ CopyView.FoldersMessage = FoldersMessageControl;
3336
+ CopyView.FoldersPagination = FoldersPaginationControl;
3337
+ CopyView.FoldersSearch = SearchControl;
3338
+ CopyView.FoldersTable = FoldersTableControl;
3339
+ CopyView.Message = MessageControl;
3340
+ CopyView.Start = ActionStartControl;
3341
+ CopyView.Statuses = StatusDisplayControl;
3342
+ CopyView.TasksTable = DataTableControl;
3343
+ CopyView.Title = TitleControl;
3344
+
3345
+ const useFolderNameField = () => {
3346
+ const { data, onValidateFolderName, onFolderNameChange } = useControlsContext();
3347
+ const { folderNameId, folderNameLabel, folderNamePlaceholder, folderNameValidationMessage, isFolderNameDisabled, } = data;
3348
+ return {
3349
+ id: folderNameId,
3350
+ isDisabled: isFolderNameDisabled,
3351
+ label: folderNameLabel,
3352
+ onChange: onFolderNameChange,
3353
+ onValidate: onValidateFolderName,
3354
+ placeholder: folderNamePlaceholder,
3355
+ validationMessage: folderNameValidationMessage,
3356
+ };
3357
+ };
3358
+
3359
+ const FolderNameFieldControl = () => {
3360
+ const props = useFolderNameField();
3361
+ const Resolved = useResolvedComposable(FolderNameField$1, 'FolderNameField');
3362
+ return React__namespace["default"].createElement(Resolved, { ...props });
3363
+ };
3364
+
3365
+ const isValidFolderName = (name) => !!name?.length &&
3366
+ !name.includes('/') &&
3367
+ !name.trim().endsWith('.') &&
3368
+ !name.trim().startsWith('.');
3369
+
3370
+ function CreateFolderViewProvider({ children, ...props }) {
3371
+ const { CreateFolderView: { actionExitLabel, actionStartLabel, folderNameLabel, folderNamePlaceholder, getActionCompleteMessage, getValidationMessage, title, }, } = useDisplayText();
3372
+ const { folderName, folderNameId, isProcessing, isProcessingComplete, onActionStart, onActionExit, onFolderNameChange, statusCounts, } = props;
3373
+ const [validationMessage, setValidationMessage] = React__namespace["default"].useState();
3374
+ const message = isProcessingComplete
3375
+ ? getActionCompleteMessage({ counts: statusCounts })
3376
+ : undefined;
3377
+ const onValidateFolderName = (value) => {
3378
+ setValidationMessage(() => isValidFolderName(value) ? undefined : getValidationMessage(value));
3379
+ };
3380
+ const isActionStartDisabled = !folderName.length ||
3381
+ !!validationMessage ||
3382
+ isProcessing ||
3383
+ isProcessingComplete;
3384
+ return (React__namespace["default"].createElement(ControlsContextProvider, { data: {
3385
+ actionExitLabel,
3386
+ folderNameId,
3387
+ folderNameLabel,
3388
+ folderNamePlaceholder,
3389
+ folderNameValidationMessage: validationMessage,
3390
+ actionStartLabel,
3391
+ isActionStartDisabled,
3392
+ isActionExitDisabled: isProcessing,
3393
+ message,
3394
+ title,
3395
+ }, onActionExit: onActionExit, onActionStart: onActionStart, onFolderNameChange: onFolderNameChange, onValidateFolderName: onValidateFolderName }, children));
3396
+ }
3397
+
3398
+ const useCreateFolderView = (options) => {
3399
+ const { onExit } = options ?? {};
3400
+ const [folderName, setFolderName] = React__namespace["default"].useState('');
3401
+ const folderNameId = React__namespace["default"].useRef(crypto.randomUUID()).current;
3402
+ const getConfig = useGetActionInput();
3403
+ const [{ tasks, isProcessing, isProcessingComplete, statusCounts }, handleCreateFolder,] = useProcessTasks(createFolderHandler);
3404
+ const [{ location }, dispatchStoreAction] = useStore();
3405
+ const { current, key: destinationPrefix } = location;
3406
+ return {
3407
+ folderName,
3408
+ folderNameId,
3409
+ isProcessing,
3410
+ isProcessingComplete,
3411
+ location,
3412
+ onActionStart: () => {
3413
+ handleCreateFolder({
3414
+ config: getConfig(),
3415
+ data: { id: folderNameId, key: `${folderName}/` },
3416
+ destinationPrefix,
3417
+ options: { preventOverwrite: true },
3418
+ });
3419
+ },
3420
+ onActionExit: () => {
3421
+ if (ui.isFunction(onExit))
3422
+ onExit(current);
3423
+ dispatchStoreAction({ type: 'RESET_ACTION_TYPE' });
3424
+ },
3425
+ onFolderNameChange: (value) => {
3426
+ setFolderName(value.trim());
3427
+ },
3428
+ statusCounts,
3429
+ tasks,
3430
+ };
3431
+ };
3432
+
3433
+ const CreateFolderView = ({ className, ...props }) => {
3434
+ const state = useCreateFolderView(props);
3435
+ return (React__namespace["default"].createElement(ViewElement, { className: ui.classNames(STORAGE_BROWSER_BLOCK, className) },
3436
+ React__namespace["default"].createElement(CreateFolderViewProvider, { ...state },
3437
+ React__namespace["default"].createElement(ActionExitControl, null),
3438
+ React__namespace["default"].createElement(TitleControl, null),
3439
+ React__namespace["default"].createElement(FolderNameFieldControl, null),
3440
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__footer` },
3441
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__message` },
3442
+ React__namespace["default"].createElement(MessageControl, null)),
3443
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__buttons` },
3444
+ React__namespace["default"].createElement(ActionStartControl, null))))));
3445
+ };
3446
+ CreateFolderView.displayName = 'CreateFolderView';
3447
+ CreateFolderView.Provider = CreateFolderViewProvider;
3448
+ CreateFolderView.Exit = ActionExitControl;
3449
+ CreateFolderView.NameField = FolderNameFieldControl;
3450
+ CreateFolderView.Message = MessageControl;
3451
+ CreateFolderView.Start = ActionStartControl;
3452
+ CreateFolderView.Title = TitleControl;
3453
+
3454
+ function DeleteViewProvider({ children, ...props }) {
3455
+ const { DeleteView: displayText } = useDisplayText();
3456
+ const { actionCancelLabel, actionExitLabel, actionStartLabel, title, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, getActionCompleteMessage, } = displayText;
3457
+ const { isProcessing, isProcessingComplete, location, statusCounts, tasks, onActionCancel, onActionStart, onActionExit, onTaskRemove, } = props;
3458
+ const message = isProcessingComplete
3459
+ ? getActionCompleteMessage({ counts: statusCounts })
3460
+ : undefined;
3461
+ const tableData = getActionViewTableData({
3462
+ tasks,
3463
+ locationKey: location.key,
3464
+ isProcessing,
3465
+ displayText,
3466
+ onTaskRemove,
3467
+ });
3468
+ return (React__namespace["default"].createElement(ControlsContextProvider, { data: {
3469
+ actionCancelLabel,
3470
+ actionExitLabel,
3471
+ actionStartLabel,
3472
+ isActionCancelDisabled: !isProcessing || isProcessingComplete,
3473
+ isActionExitDisabled: isProcessing,
3474
+ isActionStartDisabled: isProcessing || isProcessingComplete,
3475
+ statusDisplayCanceledLabel,
3476
+ statusDisplayCompletedLabel,
3477
+ statusDisplayFailedLabel,
3478
+ statusDisplayQueuedLabel,
3479
+ statusCounts,
3480
+ tableData,
3481
+ title,
3482
+ message,
3483
+ }, onActionStart: onActionStart, onActionExit: onActionExit, onActionCancel: onActionCancel }, children));
3484
+ }
3485
+
3486
+ const useDeleteView = (options) => {
3487
+ const { onExit: _onExit } = options ?? {};
3488
+ const [{ location, locationItems }, dispatchStoreAction] = useStore();
3489
+ const { fileDataItems } = locationItems;
3490
+ const { current } = location;
3491
+ const getInput = useGetActionInput();
3492
+ const [processState, handleProcess] = useProcessTasks(deleteHandler, fileDataItems, { concurrency: 4 });
3493
+ const { isProcessing, isProcessingComplete, statusCounts, tasks } = processState;
3494
+ const onActionStart = () => {
3495
+ if (!current)
3496
+ return;
3497
+ handleProcess({ config: getInput() });
3498
+ };
3499
+ const onActionCancel = () => {
3500
+ tasks.forEach((task) => {
3501
+ // @TODO Fixme, calling cancel on task doesn't currently work
3502
+ if (ui.isFunction(task.cancel))
3503
+ task.cancel();
3504
+ });
3505
+ };
3506
+ const onActionExit = () => {
3507
+ // clear files state
3508
+ dispatchStoreAction({ type: 'RESET_LOCATION_ITEMS' });
3509
+ // clear selected action
3510
+ dispatchStoreAction({ type: 'RESET_ACTION_TYPE' });
3511
+ if (ui.isFunction(_onExit))
3512
+ _onExit(current);
3513
+ };
3514
+ const onTaskRemove = React__namespace["default"].useCallback(({ data }) => {
3515
+ dispatchStoreAction({ type: 'REMOVE_LOCATION_ITEM', id: data.id });
3516
+ }, [dispatchStoreAction]);
3517
+ return {
3518
+ isProcessing,
3519
+ isProcessingComplete,
3520
+ location,
3521
+ statusCounts,
3522
+ tasks,
3523
+ onActionCancel,
3524
+ onActionExit,
3525
+ onActionStart,
3526
+ onTaskRemove,
3527
+ };
3528
+ };
3529
+
3530
+ const DeleteView = ({ className, ...props }) => {
3531
+ const state = useDeleteView(props);
3532
+ return (React__namespace["default"].createElement(ViewElement, { className: ui.classNames(STORAGE_BROWSER_BLOCK, className) },
3533
+ React__namespace["default"].createElement(DeleteViewProvider, { ...state },
3534
+ React__namespace["default"].createElement(ActionExitControl, null),
3535
+ React__namespace["default"].createElement(TitleControl, null),
3536
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__data-table` },
3537
+ React__namespace["default"].createElement(DataTableControl, null)),
3538
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__summary` },
3539
+ React__namespace["default"].createElement(StatusDisplayControl, null)),
3540
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__footer` },
3541
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__message` },
3542
+ React__namespace["default"].createElement(MessageControl, null)),
3543
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__buttons` },
3544
+ React__namespace["default"].createElement(ActionCancelControl, null),
3545
+ React__namespace["default"].createElement(ActionStartControl, null))))));
3546
+ };
3547
+ DeleteView.displayName = 'DeleteView';
3548
+ DeleteView.Provider = DeleteViewProvider;
3549
+ DeleteView.Cancel = ActionCancelControl;
3550
+ DeleteView.Exit = ActionExitControl;
3551
+ DeleteView.Message = MessageControl;
3552
+ DeleteView.Start = ActionStartControl;
3553
+ DeleteView.Statuses = StatusDisplayControl;
3554
+ DeleteView.TasksTable = DataTableControl;
3555
+ DeleteView.Title = TitleControl;
3556
+
3557
+ const useAddFiles = () => {
3558
+ const { data: { addFilesLabel, isAddFilesDisabled }, onAddFiles, } = useControlsContext();
3559
+ return {
3560
+ isDisabled: isAddFilesDisabled,
3561
+ label: addFilesLabel,
3562
+ onAddFiles,
3563
+ };
3564
+ };
3565
+
3566
+ const AddFilesControl = () => {
3567
+ const props = useAddFiles();
3568
+ const Resolved = useResolvedComposable(AddFiles, 'AddFiles');
3569
+ return React__namespace["default"].createElement(Resolved, { ...props });
3570
+ };
3571
+
3572
+ const useAddFolder = () => {
3573
+ const { data: { addFolderLabel, isAddFolderDisabled }, onAddFolder, } = useControlsContext();
3574
+ return {
3575
+ isDisabled: isAddFolderDisabled,
3576
+ label: addFolderLabel,
3577
+ onAddFolder,
3578
+ };
3579
+ };
3580
+
3581
+ const AddFolderControl = () => {
3582
+ const props = useAddFolder();
3583
+ const Resolved = useResolvedComposable(AddFolder, 'AddFolder');
3584
+ return React__namespace["default"].createElement(Resolved, { ...props });
3585
+ };
3586
+
3587
+ /**
3588
+ * This hook, not to be confused with the useDropZone vended from @aws-amplify/ui-react-core, is only intended for use
3589
+ * with its corresponding DropZone control.
3590
+ */
3591
+ const useDropZone = () => {
3592
+ const { onDropFiles } = useControlsContext();
3593
+ return { onDropFiles };
3594
+ };
3595
+
3596
+ const DropZoneControl = ({ children, }) => {
3597
+ const props = useDropZone();
3598
+ const Resolved = useResolvedComposable(DropZone, 'DropZone');
3599
+ return React__namespace["default"].createElement(Resolved, { ...props }, children);
3600
+ };
3601
+
3602
+ const useOverwriteToggle = () => {
3603
+ const { data: { isOverwritingEnabled, isOverwriteToggleDisabled, overwriteToggleLabel, }, onToggleOverwrite, } = useControlsContext();
3604
+ return {
3605
+ isDisabled: isOverwriteToggleDisabled,
3606
+ isOverwritingEnabled,
3607
+ label: overwriteToggleLabel,
3608
+ onToggle: onToggleOverwrite,
3609
+ };
3610
+ };
3611
+
3612
+ const OverwriteToggleControl = () => {
3613
+ const props = useOverwriteToggle();
3614
+ const Resolved = useResolvedComposable(OverwriteToggle$1, 'OverwriteToggle');
3615
+ return React__namespace["default"].createElement(Resolved, { ...props });
3616
+ };
3617
+
3618
+ function UploadViewProvider({ children, ...props }) {
3619
+ const { UploadView: displayText } = useDisplayText();
3620
+ const { actionCancelLabel, actionDestinationLabel, actionExitLabel, actionStartLabel, addFilesLabel, addFolderLabel, statusDisplayCanceledLabel, statusDisplayCompletedLabel, statusDisplayFailedLabel, statusDisplayQueuedLabel, overwriteToggleLabel, title, getActionCompleteMessage, getFilesValidationMessage, } = displayText;
3621
+ const { isOverwritingEnabled, isProcessing, isProcessingComplete, location, tasks, statusCounts, invalidFiles, onActionStart, onActionCancel, onDropFiles, onActionExit, onTaskRemove, onSelectFiles, onToggleOverwrite, } = props;
3622
+ const isActionStartDisabled = isProcessing || isProcessingComplete || statusCounts.TOTAL === 0;
3623
+ const isActionCancelDisabled = !isProcessing || isProcessingComplete;
3624
+ const isAddFilesDisabled = isProcessing || isProcessingComplete;
3625
+ const isAddFolderDisabled = isProcessing || isProcessingComplete;
3626
+ const isActionExitDisabled = isProcessing;
3627
+ const actionCompleteMessage = isProcessingComplete
3628
+ ? getActionCompleteMessage({
3629
+ counts: statusCounts,
3630
+ })
3631
+ : undefined;
3632
+ const filesValidationMessage = invalidFiles && !isProcessing
3633
+ ? getFilesValidationMessage({ invalidFiles })
3634
+ : undefined;
3635
+ return (React__namespace["default"].createElement(ControlsContextProvider, { data: {
3636
+ actionCancelLabel,
3637
+ actionDestinationLabel,
3638
+ actionExitLabel,
3639
+ actionStartLabel,
3640
+ addFilesLabel,
3641
+ addFolderLabel,
3642
+ isActionCancelDisabled,
3643
+ isActionExitDisabled,
3644
+ isActionStartDisabled,
3645
+ isAddFilesDisabled,
3646
+ isAddFolderDisabled,
3647
+ isActionDestinationNavigable: false,
3648
+ isOverwriteToggleDisabled: isProcessing || isProcessingComplete,
3649
+ isOverwritingEnabled,
3650
+ overwriteToggleLabel,
3651
+ destination: location,
3652
+ message: actionCompleteMessage ?? filesValidationMessage,
3653
+ statusCounts,
3654
+ statusDisplayCanceledLabel,
3655
+ statusDisplayCompletedLabel,
3656
+ statusDisplayFailedLabel,
3657
+ statusDisplayQueuedLabel,
3658
+ tableData: getActionViewTableData({
3659
+ tasks,
3660
+ shouldDisplayProgress: true,
3661
+ displayText,
3662
+ isProcessing,
3663
+ onTaskRemove,
3664
+ }),
3665
+ title,
3666
+ }, onActionCancel: onActionCancel, onActionExit: onActionExit, onActionStart: onActionStart, onAddFiles: () => {
3667
+ onSelectFiles('FILE');
3668
+ }, onAddFolder: () => {
3669
+ onSelectFiles('FOLDER');
3670
+ }, onDropFiles: onDropFiles, onToggleOverwrite: onToggleOverwrite }, children));
3671
+ }
3672
+
3673
+ const DEFAULT_ACTION_CONCURRENCY = 4;
3674
+
3675
+ const DEFAULT_OVERWRITE_ENABLED = false;
3676
+
3677
+ const useUploadView = (options) => {
3678
+ const { onExit: _onExit } = options ?? {};
3679
+ const getInput = useGetActionInput();
3680
+ const [{ files, location }, dispatchStoreAction] = useStore();
3681
+ const { current, key } = location;
3682
+ const { invalidFiles, validFiles } = React__namespace["default"].useMemo(() => (files ?? [])?.reduce((curr, file) => {
3683
+ if (isFileTooBig(file.file)) {
3684
+ curr.invalidFiles = ui.isUndefined(curr.invalidFiles)
3685
+ ? [file]
3686
+ : curr.invalidFiles.concat(file);
3687
+ }
3688
+ else {
3689
+ curr.validFiles = ui.isUndefined(curr.validFiles)
3690
+ ? [file]
3691
+ : curr.validFiles.concat(file);
3692
+ }
3693
+ return curr;
3694
+ }, {}), [files]);
3695
+ const [isOverwritingEnabled, setIsOverwritingEnabled] = React__namespace["default"].useState(DEFAULT_OVERWRITE_ENABLED);
3696
+ const [{ isProcessing, isProcessingComplete, statusCounts, tasks }, handleProcess,] = useProcessTasks(uploadHandler, validFiles, {
3697
+ concurrency: DEFAULT_ACTION_CONCURRENCY,
3698
+ });
3699
+ const onDropFiles = React__namespace["default"].useCallback((files) => {
3700
+ if (files) {
3701
+ dispatchStoreAction({ type: 'ADD_FILE_ITEMS', files });
3702
+ }
3703
+ }, [dispatchStoreAction]);
3704
+ const onSelectFiles = React__namespace["default"].useCallback((type) => {
3705
+ dispatchStoreAction({ type: 'SELECT_FILES', selectionType: type });
3706
+ }, [dispatchStoreAction]);
3707
+ const onActionStart = React__namespace["default"].useCallback(() => {
3708
+ invalidFiles?.forEach((file) => {
3709
+ dispatchStoreAction({ type: 'REMOVE_FILE_ITEM', id: file.id });
3710
+ });
3711
+ handleProcess({
3712
+ config: getInput(),
3713
+ destinationPrefix: key,
3714
+ options: { preventOverwrite: !isOverwritingEnabled },
3715
+ });
3716
+ }, [
3717
+ isOverwritingEnabled,
3718
+ key,
3719
+ getInput,
3720
+ handleProcess,
3721
+ invalidFiles,
3722
+ dispatchStoreAction,
3723
+ ]);
3724
+ const onActionCancel = React__namespace["default"].useCallback(() => {
3725
+ tasks.forEach((task) => task.cancel?.());
3726
+ }, [tasks]);
3727
+ const onActionExit = React__namespace["default"].useCallback(() => {
3728
+ // clear files state
3729
+ dispatchStoreAction({ type: 'RESET_FILE_ITEMS' });
3730
+ // clear selected action
3731
+ dispatchStoreAction({ type: 'RESET_ACTION_TYPE' });
3732
+ _onExit?.(current);
3733
+ }, [dispatchStoreAction, _onExit, current]);
3734
+ const onToggleOverwrite = React__namespace["default"].useCallback(() => {
3735
+ setIsOverwritingEnabled((prev) => !prev);
3736
+ }, []);
3737
+ const onTaskRemove = React__namespace["default"].useCallback(({ data }) => {
3738
+ dispatchStoreAction({ type: 'REMOVE_FILE_ITEM', id: data.id });
3739
+ }, [dispatchStoreAction]);
3740
+ return {
3741
+ isProcessing,
3742
+ isProcessingComplete,
3743
+ isOverwritingEnabled,
3744
+ location,
3745
+ invalidFiles,
3746
+ statusCounts,
3747
+ tasks,
3748
+ onActionCancel,
3749
+ onActionExit,
3750
+ onActionStart,
3751
+ onDropFiles,
3752
+ onTaskRemove,
3753
+ onSelectFiles,
3754
+ onToggleOverwrite,
3755
+ };
3756
+ };
3757
+
3758
+ const UploadView = ({ className, ...props }) => {
3759
+ const state = useUploadView(props);
3760
+ return (React__namespace["default"].createElement(ViewElement, { className: ui.classNames(STORAGE_BROWSER_BLOCK, className) },
3761
+ React__namespace["default"].createElement(UploadViewProvider, { ...state },
3762
+ React__namespace["default"].createElement(ActionExitControl, null),
3763
+ React__namespace["default"].createElement(TitleControl, null),
3764
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__controls` },
3765
+ React__namespace["default"].createElement(OverwriteToggleControl, null),
3766
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__buttons` },
3767
+ React__namespace["default"].createElement(AddFolderControl, null),
3768
+ React__namespace["default"].createElement(AddFilesControl, null))),
3769
+ React__namespace["default"].createElement(DropZoneControl, null,
3770
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__data-table` },
3771
+ React__namespace["default"].createElement(DataTableControl, null))),
3772
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__summary` },
3773
+ React__namespace["default"].createElement(ActionDestinationControl, null),
3774
+ React__namespace["default"].createElement(StatusDisplayControl, null)),
3775
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__footer` },
3776
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__message` },
3777
+ React__namespace["default"].createElement(MessageControl, null)),
3778
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__buttons` },
3779
+ React__namespace["default"].createElement(ActionCancelControl, null),
3780
+ React__namespace["default"].createElement(ActionStartControl, null))))));
3781
+ };
3782
+ UploadView.displayName = 'UploadView';
3783
+ UploadView.Provider = UploadViewProvider;
3784
+ UploadView.AddFiles = AddFilesControl;
3785
+ UploadView.AddFolder = AddFolderControl;
3786
+ UploadView.Cancel = ActionCancelControl;
3787
+ UploadView.Destination = ActionDestinationControl;
3788
+ UploadView.DropZone = DropZoneControl;
3789
+ UploadView.Exit = ActionExitControl;
3790
+ UploadView.Message = MessageControl;
3791
+ UploadView.OverwriteToggle = OverwriteToggleControl;
3792
+ UploadView.Start = ActionStartControl;
3793
+ UploadView.Statuses = StatusDisplayControl;
3794
+ UploadView.TasksTable = DataTableControl;
3795
+ UploadView.Title = TitleControl;
3796
+
3797
+ function useActionView() {
3798
+ return {
3799
+ isProcessing: false,
3800
+ isProcessingComplete: false,
3801
+ location: DEFAULT_STATE$1,
3802
+ statusCounts: INITIAL_STATUS_COUNTS,
3803
+ tasks: [],
3804
+ onActionExit: () => null,
3805
+ onActionStart: () => null,
3806
+ onActionCancel: () => null,
3807
+ onTaskRemove: () => null,
3808
+ };
3809
+ }
3810
+
3811
+ const LocationActionView = ({ type, ...props }) => {
3812
+ const [{ actionType = type }] = useStore();
3813
+ if (!isDefaultActionViewType(actionType))
3814
+ return null;
3815
+ return (React__namespace["default"].createElement(React__namespace["default"].Fragment, null, actionType === 'createFolder' ? (React__namespace["default"].createElement(CreateFolderView, { ...props })) : actionType === 'delete' ? (React__namespace["default"].createElement(DeleteView, { ...props })) : actionType === 'copy' ? (React__namespace["default"].createElement(CopyView, { ...props })) : (React__namespace["default"].createElement(UploadView, { ...props }))));
3816
+ };
3817
+
3818
+ const useActionsList = () => {
3819
+ const { data: { actions, isActionsListDisabled }, onActionSelect, } = useControlsContext();
3820
+ return {
3821
+ isDisabled: isActionsListDisabled,
3822
+ items: actions ?? [],
3823
+ onActionSelect,
3824
+ };
3825
+ };
3826
+
3827
+ const ActionsListControl = () => {
3828
+ const props = useActionsList();
3829
+ const Resolved = useResolvedComposable(ActionsList$1, 'ActionsList');
3830
+ return React__namespace["default"].createElement(Resolved, { ...props });
3831
+ };
3832
+
3833
+ const useDataRefresh = () => {
3834
+ const { data: { isDataRefreshDisabled }, onRefresh, } = useControlsContext();
3835
+ return { isDisabled: isDataRefreshDisabled, onRefresh };
3836
+ };
3837
+
3838
+ const DataRefreshControl = () => {
3839
+ const props = useDataRefresh();
3840
+ const Resolved = useResolvedComposable(DataRefresh$1, 'DataRefresh');
3841
+ return React__namespace["default"].createElement(Resolved, { ...props });
3842
+ };
3843
+
3844
+ const useNavigation = () => {
3845
+ const { data, onNavigate, onNavigateHome } = useControlsContext();
3846
+ const { location } = data;
3847
+ return React__namespace["default"].useMemo(() => {
3848
+ if (!location?.current) {
3849
+ return { items: [] };
3850
+ }
3851
+ const { current, path } = location;
3852
+ const destinationParts = getNavigationParts({
3853
+ location: current,
3854
+ path,
3855
+ includeBucketInPrefix: true,
3856
+ });
3857
+ const homeItem = [
3858
+ { name: 'Home', onNavigate: onNavigateHome },
3859
+ ];
3860
+ return {
3861
+ items: homeItem.concat(getNavigationItems({ location: current, destinationParts, onNavigate })),
3862
+ };
3863
+ }, [location, onNavigate, onNavigateHome]);
3864
+ };
3865
+
3866
+ const NavigationControl = () => {
3867
+ const props = useNavigation();
3868
+ const Resolved = useResolvedComposable(Navigation$1, 'Navigation');
3869
+ return React__namespace["default"].createElement(Resolved, { ...props });
3870
+ };
3871
+
3872
+ const PaginationControl = () => {
3873
+ const { data } = useControlsContext();
3874
+ const Resolved = useResolvedComposable(Pagination$1, 'Pagination');
3875
+ return React__namespace["default"].createElement(Resolved, { ...data.paginationData });
3876
+ };
3877
+
3878
+ const useSearchSubfoldersToggle = () => {
3879
+ const { data: { isSearchingSubfolders, searchSubfoldersToggleLabel }, onToggleSearchSubfolders, } = useControlsContext();
3880
+ return {
3881
+ isSearchingSubfolders,
3882
+ label: searchSubfoldersToggleLabel,
3883
+ onToggle: onToggleSearchSubfolders,
3884
+ };
3885
+ };
3886
+
3887
+ const SearchSubfoldersToggleControl = () => {
3888
+ const props = useSearchSubfoldersToggle();
3889
+ const Resolved = useResolvedComposable(SearchSubfoldersToggle$1, 'SearchSubfoldersToggle');
3890
+ return React__namespace["default"].createElement(Resolved, { ...props });
3891
+ };
3892
+
3893
+ const DEFAULT_PAGE_SIZE$1 = 100;
3894
+ const DEFAULT_LIST_OPTIONS$1 = {
3895
+ delimiter: '/',
3896
+ pageSize: DEFAULT_PAGE_SIZE$1,
3897
+ };
3898
+ const listLocationItemsAction = createEnhancedListHandler(listLocationItemsHandler);
3899
+ const getDownloadErrorMessageFromFailedDownloadTask = (tasks) => {
3900
+ if (!tasks.length) {
3901
+ return undefined;
3902
+ }
3903
+ return `Failed to download ${tasks[0].data.fileKey ?? tasks[0].data.key} due to error: ${tasks[0].message}.`;
3904
+ };
3905
+ const useLocationDetailView = (options) => {
3906
+ const getConfig = useGetActionInput();
3907
+ const { initialValues, onExit, onNavigate } = options ?? {};
3908
+ const listOptionsRef = React__namespace["default"].useRef({
3909
+ ...DEFAULT_LIST_OPTIONS$1,
3910
+ ...initialValues,
3911
+ });
3912
+ const listOptions = listOptionsRef.current;
3913
+ const [{ location, locationItems }, dispatchStoreAction] = useStore();
3914
+ const { current, key } = location;
3915
+ const { permissions, prefix } = current ?? {};
3916
+ const { fileDataItems } = locationItems;
3917
+ const hasInvalidPrefix = ui.isUndefined(prefix);
3918
+ const [downloadTaskResult, handleDownload] = useProcessTasks(downloadHandler);
3919
+ const [{ data, isLoading, hasError, message }, handleList] = uiReactCore.useDataState(listLocationItemsAction, { items: [], nextToken: undefined });
3920
+ // set up pagination
3921
+ const { items, nextToken, search } = data;
3922
+ const { hasExhaustedSearch = false } = search ?? {};
3923
+ const hasNextToken = !!nextToken;
3924
+ const paginateCallback = () => {
3925
+ if (hasInvalidPrefix || !nextToken)
3926
+ return;
3927
+ dispatchStoreAction({ type: 'RESET_LOCATION_ITEMS' });
3928
+ handleList({
3929
+ config: getConfig(),
3930
+ prefix: key,
3931
+ options: { ...listOptions, nextToken },
3932
+ });
3933
+ };
3934
+ const { currentPage, onPaginate, handleReset, highestPageVisited, pageItems, } = usePaginate({
3935
+ items,
3936
+ paginateCallback,
3937
+ pageSize: listOptions.pageSize,
3938
+ hasNextToken,
3939
+ });
3940
+ const onSearch = (query, includeSubfolders) => {
3941
+ if (hasInvalidPrefix)
3942
+ return;
3943
+ const searchOptions = {
3944
+ ...listOptions,
3945
+ delimiter: includeSubfolders ? undefined : listOptions.delimiter,
3946
+ search: {
3947
+ query,
3948
+ filterBy: 'key',
3949
+ groupBy: includeSubfolders ? listOptions.delimiter : undefined,
3950
+ },
3951
+ };
3952
+ handleReset();
3953
+ handleList({ config: getConfig(), prefix: key, options: searchOptions });
3954
+ dispatchStoreAction({ type: 'RESET_LOCATION_ITEMS' });
3955
+ };
3956
+ const { searchQuery, isSearchingSubfolders, onSearchQueryChange, onSearchSubmit, onToggleSearchSubfolders, resetSearch, } = useSearch({ onSearch });
3957
+ const onRefresh = () => {
3958
+ if (hasInvalidPrefix)
3959
+ return;
3960
+ handleReset();
3961
+ resetSearch();
3962
+ handleList({
3963
+ config: getConfig(),
3964
+ prefix: key,
3965
+ options: { ...listOptions, refresh: true },
3966
+ });
3967
+ dispatchStoreAction({ type: 'RESET_LOCATION_ITEMS' });
3968
+ };
3969
+ React__namespace["default"].useEffect(() => {
3970
+ if (hasInvalidPrefix)
3971
+ return;
3972
+ handleList({
3973
+ config: getConfig(),
3974
+ prefix: key,
3975
+ options: { ...listOptions, refresh: true },
3976
+ });
3977
+ handleReset();
3978
+ }, [
3979
+ handleList,
3980
+ handleReset,
3981
+ listOptions,
3982
+ hasInvalidPrefix,
3983
+ getConfig,
3984
+ prefix,
3985
+ key,
3986
+ ]);
3987
+ // Logic for Select All Files functionality
3988
+ const fileItems = React__namespace["default"].useMemo(() => pageItems.filter((item) => item.type === 'FILE'), [pageItems]);
3989
+ const areAllFilesSelected = fileDataItems?.length === fileItems.length;
3990
+ const shouldShowEmptyMessage = pageItems.length === 0 && !isLoading && !hasError;
3991
+ const actions = React__namespace["default"].useMemo(() => {
3992
+ if (!permissions) {
3993
+ return [];
3994
+ }
3995
+ return Object.entries(defaultActionViewConfigs).map(([actionType, config]) => {
3996
+ const { actionsListItemConfig } = config ?? {};
3997
+ const { icon, hide, disable, label } = actionsListItemConfig ?? {};
3998
+ return {
3999
+ actionType,
4000
+ icon,
4001
+ isDisabled: ui.isFunction(disable)
4002
+ ? disable(fileDataItems)
4003
+ : disable ?? false,
4004
+ isHidden: ui.isFunction(hide) ? hide(permissions) : hide,
4005
+ label,
4006
+ };
4007
+ });
4008
+ }, [fileDataItems, permissions]);
4009
+ return {
4010
+ actions,
4011
+ page: currentPage,
4012
+ pageItems,
4013
+ location,
4014
+ areAllFilesSelected,
4015
+ fileDataItems,
4016
+ hasFiles: fileItems.length > 0,
4017
+ hasError,
4018
+ hasDownloadError: downloadTaskResult.statusCounts.FAILED > 0,
4019
+ hasNextPage: hasNextToken,
4020
+ highestPageVisited,
4021
+ message,
4022
+ downloadErrorMessage: getDownloadErrorMessageFromFailedDownloadTask(downloadTaskResult.tasks),
4023
+ shouldShowEmptyMessage,
4024
+ isLoading,
4025
+ isSearchingSubfolders,
4026
+ onPaginate,
4027
+ searchQuery,
4028
+ hasExhaustedSearch,
4029
+ onRefresh,
4030
+ onNavigate: (location, path) => {
4031
+ onNavigate?.(location, path);
4032
+ resetSearch();
4033
+ dispatchStoreAction({ type: 'NAVIGATE', location, path });
4034
+ dispatchStoreAction({ type: 'RESET_LOCATION_ITEMS' });
4035
+ },
4036
+ onDropFiles: (files) => {
4037
+ dispatchStoreAction({ type: 'ADD_FILE_ITEMS', files });
4038
+ const actionType = 'upload';
4039
+ dispatchStoreAction({ type: 'SET_ACTION_TYPE', actionType });
4040
+ options?.onActionSelect?.(actionType);
4041
+ },
4042
+ onDownload: (data) => {
4043
+ handleDownload({ config: getConfig(), data });
4044
+ },
4045
+ onNavigateHome: () => {
4046
+ onExit?.();
4047
+ dispatchStoreAction({ type: 'RESET_LOCATION' });
4048
+ handleList({
4049
+ config: getConfig(),
4050
+ // @todo: prefix should not be required to refresh
4051
+ prefix: prefix ?? '',
4052
+ options: { reset: true },
4053
+ });
4054
+ dispatchStoreAction({ type: 'RESET_ACTION_TYPE' });
4055
+ dispatchStoreAction({ type: 'RESET_LOCATION_ITEMS' });
4056
+ },
4057
+ onActionSelect: (actionType) => {
4058
+ options?.onActionSelect?.(actionType);
4059
+ dispatchStoreAction({ type: 'SET_ACTION_TYPE', actionType });
4060
+ },
4061
+ onSelect: (isSelected, fileItem) => {
4062
+ dispatchStoreAction(isSelected
4063
+ ? { type: 'REMOVE_LOCATION_ITEM', id: fileItem.id }
4064
+ : { type: 'SET_LOCATION_ITEMS', items: [fileItem] });
4065
+ },
4066
+ onSelectAll: () => {
4067
+ dispatchStoreAction(areAllFilesSelected
4068
+ ? { type: 'RESET_LOCATION_ITEMS' }
4069
+ : { type: 'SET_LOCATION_ITEMS', items: fileItems });
4070
+ },
4071
+ onSearch: onSearchSubmit,
4072
+ onSearchClear: () => {
4073
+ resetSearch();
4074
+ if (hasInvalidPrefix)
4075
+ return;
4076
+ handleList({
4077
+ config: getConfig(),
4078
+ prefix: key,
4079
+ options: { ...listOptions, refresh: true },
4080
+ });
4081
+ handleReset();
4082
+ },
4083
+ onSearchQueryChange,
4084
+ onToggleSearchSubfolders,
4085
+ };
4086
+ };
4087
+
4088
+ const LOCATION_DETAIL_VIEW_HEADERS = [
4089
+ { key: 'checkbox', type: 'text', content: { text: '' } },
4090
+ { key: 'name', type: 'sort', content: { label: 'Name' } },
4091
+ { key: 'type', type: 'sort', content: { label: 'Type' } },
4092
+ { key: 'last-modified', type: 'sort', content: { label: 'Last modified' } },
4093
+ { key: 'size', type: 'sort', content: { label: 'Size' } },
4094
+ { key: 'download', type: 'text', content: { text: '' } },
4095
+ ];
4096
+
4097
+ const getFileRowContent = ({ permissions, isSelected, itemLocationKey, getDateDisplayValue, lastModified, rowId, rowKey, selectFileLabel, size, onDownload, onSelect, }) => LOCATION_DETAIL_VIEW_HEADERS.map(({ key: columnKey }) => {
4098
+ const key = `${columnKey}-${rowId}`;
4099
+ switch (columnKey) {
4100
+ case 'checkbox': {
4101
+ return {
4102
+ key,
4103
+ type: 'checkbox',
4104
+ content: {
4105
+ checked: isSelected,
4106
+ id: key,
4107
+ label: `${selectFileLabel} ${rowKey}`,
4108
+ onSelect,
4109
+ },
4110
+ };
4111
+ }
4112
+ case 'name': {
4113
+ return {
4114
+ key,
4115
+ type: 'text',
4116
+ content: {
4117
+ icon: 'file',
4118
+ ariaLabel: 'file',
4119
+ text: rowKey.slice(itemLocationKey.length),
4120
+ },
4121
+ };
4122
+ }
4123
+ case 'type': {
4124
+ const splitKey = rowKey.split('.');
4125
+ return {
4126
+ key,
4127
+ type: 'text',
4128
+ content: {
4129
+ text: `${splitKey.length > 1 && splitKey[0] ? splitKey.pop() : '-'}`,
4130
+ },
4131
+ };
4132
+ }
4133
+ case 'last-modified': {
4134
+ return {
4135
+ key,
4136
+ type: 'date',
4137
+ content: {
4138
+ value: lastModified,
4139
+ displayValue: getDateDisplayValue(lastModified),
4140
+ },
4141
+ };
4142
+ }
4143
+ case 'size': {
4144
+ return {
4145
+ key,
4146
+ type: 'number',
4147
+ content: {
4148
+ value: size,
4149
+ displayValue: ui.humanFileSize(size, true),
4150
+ },
4151
+ };
4152
+ }
4153
+ case 'download': {
4154
+ return permissions.includes('get')
4155
+ ? {
4156
+ key,
4157
+ type: 'button',
4158
+ content: {
4159
+ icon: 'download',
4160
+ onClick: onDownload,
4161
+ ariaLabel: 'download',
4162
+ },
4163
+ }
4164
+ : { key, type: 'text', content: { text: '' } };
4165
+ }
4166
+ }
4167
+ });
4168
+
4169
+ const getFolderRowContent = ({ itemSubPath, rowId, onNavigate, }) => LOCATION_DETAIL_VIEW_HEADERS.map(({ key: columnKey }) => {
4170
+ const key = `${columnKey}-${rowId}`;
4171
+ switch (columnKey) {
4172
+ case 'checkbox': {
4173
+ return { key, type: 'text', content: { text: '' } };
4174
+ }
4175
+ case 'name': {
4176
+ return {
4177
+ key,
4178
+ type: 'button',
4179
+ content: {
4180
+ icon: 'folder',
4181
+ ariaLabel: itemSubPath,
4182
+ label: itemSubPath,
4183
+ onClick: onNavigate,
4184
+ },
4185
+ };
4186
+ }
4187
+ case 'type': {
4188
+ return { key, type: 'text', content: { text: 'Folder' } };
4189
+ }
4190
+ case 'last-modified':
4191
+ case 'size':
4192
+ case 'download': {
4193
+ return { key, type: 'text', content: { text: '' } };
4194
+ }
4195
+ }
4196
+ });
4197
+
4198
+ const getLocationDetailViewTableData = ({ areAllFilesSelected, location, fileDataItems, hasFiles, pageItems, selectFileLabel, selectAllFilesLabel, getDateDisplayValue, onDownload, onNavigate, onSelect, onSelectAll, }) => {
4199
+ const headerCheckbox = {
4200
+ key: 'checkbox',
4201
+ type: 'checkbox',
4202
+ content: {
4203
+ checked: areAllFilesSelected,
4204
+ label: selectAllFilesLabel,
4205
+ onSelect: onSelectAll,
4206
+ id: 'header-checkbox',
4207
+ },
4208
+ };
4209
+ const headers = hasFiles
4210
+ ? [headerCheckbox, ...LOCATION_DETAIL_VIEW_HEADERS.slice(1)]
4211
+ : LOCATION_DETAIL_VIEW_HEADERS;
4212
+ const rows = pageItems.map((locationItem) => {
4213
+ const { id, key, type } = locationItem;
4214
+ switch (type) {
4215
+ case 'FILE': {
4216
+ const { lastModified, size } = locationItem;
4217
+ const { current, path } = location;
4218
+ const isSelected = fileDataItems?.some((item) => item.id === id) ?? false;
4219
+ const onFileDownload = () => {
4220
+ onDownload(createFileDataItem(locationItem));
4221
+ };
4222
+ const onFileSelect = () => {
4223
+ onSelect(isSelected, locationItem);
4224
+ };
4225
+ return {
4226
+ key: id,
4227
+ content: getFileRowContent({
4228
+ permissions: current?.permissions ?? [],
4229
+ isSelected,
4230
+ itemLocationKey: `${current?.prefix ?? ''}${path}`,
4231
+ lastModified,
4232
+ getDateDisplayValue,
4233
+ rowId: id,
4234
+ rowKey: key,
4235
+ selectFileLabel,
4236
+ size,
4237
+ onDownload: onFileDownload,
4238
+ onSelect: onFileSelect,
4239
+ }),
4240
+ };
4241
+ }
4242
+ case 'FOLDER': {
4243
+ const { current, path } = location;
4244
+ const itemSubPath = key.slice(`${current?.prefix ?? ''}${path}`.length);
4245
+ const itemLocationPath = key.slice(current?.prefix.length);
4246
+ const onFolderNavigate = () => {
4247
+ if (!current) {
4248
+ return;
4249
+ }
4250
+ onNavigate({ ...current, id }, itemLocationPath);
4251
+ };
4252
+ return {
4253
+ key: id,
4254
+ content: getFolderRowContent({
4255
+ itemSubPath,
4256
+ rowId: id,
4257
+ onNavigate: onFolderNavigate,
4258
+ }),
4259
+ };
4260
+ }
4261
+ }
4262
+ });
4263
+ return { headers, rows };
4264
+ };
4265
+
4266
+ function LocationDetailViewProvider({ children, ...props }) {
4267
+ const { LocationDetailView: { loadingIndicatorLabel, searchSubfoldersToggleLabel, selectFileLabel, selectAllFilesLabel, searchPlaceholder, searchSubmitLabel, searchClearLabel, getActionListItemLabel, getDateDisplayValue, getTitle, getListItemsResultMessage, }, } = useDisplayText();
4268
+ const { actions, page, pageItems, hasNextPage, highestPageVisited, isLoading, isSearchingSubfolders, location, areAllFilesSelected, fileDataItems, hasFiles, hasError, hasDownloadError, message, downloadErrorMessage, searchQuery, hasExhaustedSearch, onActionSelect, onDropFiles, onRefresh, onPaginate, onDownload, onNavigate, onNavigateHome, onSelect, onSelectAll, onSearch, onSearchQueryChange, onSearchClear, onToggleSearchSubfolders, } = props;
4269
+ const actionsWithDisplayText = actions.map((item) => ({
4270
+ ...item,
4271
+ label: getActionListItemLabel(item.label),
4272
+ }));
4273
+ const messageControlContent = getListItemsResultMessage({
4274
+ isLoading,
4275
+ items: pageItems,
4276
+ hasError: hasError || hasDownloadError,
4277
+ hasExhaustedSearch,
4278
+ message: hasError ? message : downloadErrorMessage,
4279
+ });
4280
+ const isNoActionAvailable = !Array.isArray(actions) || actions?.every((action) => action.isHidden);
4281
+ return (React__namespace["default"].createElement(ControlsContextProvider, { data: {
4282
+ actions: actionsWithDisplayText,
4283
+ isActionsListDisabled: isLoading || isNoActionAvailable,
4284
+ isDataRefreshDisabled: isLoading,
4285
+ isLoading,
4286
+ isSearchingSubfolders,
4287
+ loadingIndicatorLabel,
4288
+ location,
4289
+ paginationData: {
4290
+ page,
4291
+ hasNextPage,
4292
+ highestPageVisited,
4293
+ onPaginate,
4294
+ },
4295
+ searchPlaceholder,
4296
+ searchSubfoldersToggleLabel,
4297
+ searchSubmitLabel,
4298
+ searchClearLabel,
4299
+ searchQuery,
4300
+ tableData: getLocationDetailViewTableData({
4301
+ areAllFilesSelected,
4302
+ location,
4303
+ fileDataItems,
4304
+ getDateDisplayValue,
4305
+ hasFiles,
4306
+ pageItems,
4307
+ selectFileLabel,
4308
+ selectAllFilesLabel,
4309
+ onDownload,
4310
+ onNavigate,
4311
+ onSelect,
4312
+ onSelectAll,
4313
+ }),
4314
+ title: getTitle(location),
4315
+ message: messageControlContent,
4316
+ }, onActionSelect: onActionSelect, onDropFiles: onDropFiles, onNavigate: onNavigate, onNavigateHome: onNavigateHome, onRefresh: onRefresh, onSearch: onSearch, onSearchQueryChange: onSearchQueryChange, onSearchClear: onSearchClear, onToggleSearchSubfolders: onToggleSearchSubfolders }, children));
4317
+ }
4318
+
4319
+ const LocationDetailView = ({ className, ...props }) => {
4320
+ const state = useLocationDetailView(props);
4321
+ const { hasError } = state;
4322
+ return (React__namespace["default"].createElement(ViewElement, { className: ui.classNames(STORAGE_BROWSER_BLOCK, className), "data-testid": "LOCATION_DETAIL_VIEW" },
4323
+ React__namespace["default"].createElement(LocationDetailViewProvider, { ...state },
4324
+ React__namespace["default"].createElement(NavigationControl, null),
4325
+ React__namespace["default"].createElement(TitleControl, null),
4326
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__controls` },
4327
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__search` },
4328
+ React__namespace["default"].createElement(SearchControl, null),
4329
+ React__namespace["default"].createElement(SearchSubfoldersToggleControl, null)),
4330
+ React__namespace["default"].createElement(PaginationControl, null),
4331
+ React__namespace["default"].createElement(DataRefreshControl, null),
4332
+ React__namespace["default"].createElement(ActionsListControl, null)),
4333
+ hasError ? null : (React__namespace["default"].createElement(DropZoneControl, null,
4334
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__data-table` },
4335
+ React__namespace["default"].createElement(LoadingIndicatorControl, null),
4336
+ React__namespace["default"].createElement(DataTableControl, null)))),
4337
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__footer` },
4338
+ React__namespace["default"].createElement(MessageControl, null)))));
4339
+ };
4340
+ LocationDetailView.displayName = 'LocationDetailView';
4341
+ LocationDetailView.Provider = LocationDetailViewProvider;
4342
+ LocationDetailView.ActionsList = ActionsListControl;
4343
+ LocationDetailView.DropZone = DropZoneControl;
4344
+ LocationDetailView.LoadingIndicator = LoadingIndicatorControl;
4345
+ LocationDetailView.LocationItemsTable = DataTableControl;
4346
+ LocationDetailView.Message = MessageControl;
4347
+ LocationDetailView.Navigation = NavigationControl;
4348
+ LocationDetailView.Pagination = PaginationControl;
4349
+ LocationDetailView.Refresh = DataRefreshControl;
4350
+ LocationDetailView.Search = SearchControl;
4351
+ LocationDetailView.SearchSubfoldersToggle = SearchSubfoldersToggleControl;
4352
+ LocationDetailView.Title = TitleControl;
4353
+
4354
+ const getHeaders = ({ hasObjectLocations, tableColumnActionsHeader, tableColumnBucketHeader, tableColumnFolderHeader, tableColumnPermissionsHeader, }) => {
4355
+ const headers = [
4356
+ {
4357
+ key: 'folder',
4358
+ type: 'sort',
4359
+ content: { label: tableColumnFolderHeader },
4360
+ },
4361
+ {
4362
+ key: 'bucket',
4363
+ type: 'sort',
4364
+ content: { label: tableColumnBucketHeader },
4365
+ },
4366
+ {
4367
+ key: 'permission',
4368
+ type: 'sort',
4369
+ content: { label: tableColumnPermissionsHeader },
4370
+ },
4371
+ ];
4372
+ if (hasObjectLocations) {
4373
+ headers.push({
4374
+ key: 'action',
4375
+ type: 'sort',
4376
+ content: { label: tableColumnActionsHeader },
4377
+ });
4378
+ }
4379
+ return headers;
4380
+ };
4381
+
4382
+ const getLocationsViewTableData = ({ displayText, pageItems, onNavigate, onDownload, }) => {
4383
+ const { tableColumnActionsHeader, tableColumnBucketHeader, tableColumnFolderHeader, tableColumnPermissionsHeader, getDownloadLabel, getPermissionName, } = displayText;
4384
+ const headers = getHeaders({
4385
+ hasObjectLocations: pageItems.some(({ type }) => type === 'OBJECT'),
4386
+ tableColumnActionsHeader,
4387
+ tableColumnBucketHeader,
4388
+ tableColumnFolderHeader,
4389
+ tableColumnPermissionsHeader,
4390
+ });
4391
+ const rows = pageItems.map((location) => {
4392
+ const { bucket, id, permissions, prefix } = location;
4393
+ return {
4394
+ key: id,
4395
+ content: headers.map(({ key: columnKey }) => {
4396
+ const key = `${columnKey}-${id}`;
4397
+ switch (columnKey) {
4398
+ case 'bucket': {
4399
+ return { key, type: 'text', content: { text: bucket } };
4400
+ }
4401
+ case 'folder': {
4402
+ return location.type === 'OBJECT'
4403
+ ? {
4404
+ key,
4405
+ type: 'text',
4406
+ content: {
4407
+ text: prefix,
4408
+ },
4409
+ }
4410
+ : {
4411
+ key,
4412
+ type: 'button',
4413
+ content: {
4414
+ label: prefix || bucket,
4415
+ onClick: () => {
4416
+ onNavigate(location);
4417
+ },
4418
+ },
4419
+ };
4420
+ }
4421
+ case 'permission': {
4422
+ return {
4423
+ key,
4424
+ type: 'text',
4425
+ content: { text: getPermissionName(permissions) },
4426
+ };
4427
+ }
4428
+ case 'action': {
4429
+ return location.type === 'OBJECT' &&
4430
+ location.permissions.includes('get')
4431
+ ? {
4432
+ key,
4433
+ type: 'button',
4434
+ content: {
4435
+ icon: 'download',
4436
+ ariaLabel: getDownloadLabel(location.prefix),
4437
+ onClick: () => {
4438
+ onDownload(location);
4439
+ },
4440
+ },
4441
+ }
4442
+ : {
4443
+ key,
4444
+ type: 'text',
4445
+ content: { text: '' },
4446
+ };
4447
+ }
4448
+ }
4449
+ }),
4450
+ };
4451
+ });
4452
+ return { headers, rows };
4453
+ };
4454
+
4455
+ function LocationsViewProvider({ children, ...props }) {
4456
+ const { LocationsView: displayText } = useDisplayText();
4457
+ const { loadingIndicatorLabel, title, searchPlaceholder, searchSubmitLabel, searchClearLabel, getListLocationsResultMessage, } = displayText;
4458
+ const { hasError, hasNextPage, highestPageVisited, page, isLoading, searchQuery, hasExhaustedSearch, pageItems, message, onDownload, onRefresh, onPaginate, onNavigate, onSearch, onSearchQueryChange, onSearchClear, } = props;
4459
+ const messageControlContent = getListLocationsResultMessage({
4460
+ hasExhaustedSearch,
4461
+ isLoading,
4462
+ locations: pageItems,
4463
+ hasError,
4464
+ message,
4465
+ });
4466
+ return (React__namespace["default"].createElement(ControlsContextProvider, { data: {
4467
+ isDataRefreshDisabled: isLoading,
4468
+ loadingIndicatorLabel,
4469
+ tableData: getLocationsViewTableData({
4470
+ displayText,
4471
+ pageItems,
4472
+ onDownload,
4473
+ onNavigate,
4474
+ }),
4475
+ paginationData: {
4476
+ page,
4477
+ hasNextPage,
4478
+ highestPageVisited,
4479
+ onPaginate,
4480
+ },
4481
+ title,
4482
+ searchPlaceholder,
4483
+ searchClearLabel,
4484
+ searchSubmitLabel,
4485
+ searchQuery,
4486
+ message: messageControlContent,
4487
+ isLoading,
4488
+ }, onSearch: onSearch, onRefresh: onRefresh, onSearchQueryChange: onSearchQueryChange, onSearchClear: onSearchClear }, children));
4489
+ }
4490
+
4491
+ const DEFAULT_EXCLUDE = {
4492
+ exactPermissions: ['delete', 'write'],
4493
+ };
4494
+ const DEFAULT_PAGE_SIZE = 100;
4495
+ const DEFAULT_LIST_OPTIONS = {
4496
+ exclude: DEFAULT_EXCLUDE,
4497
+ pageSize: DEFAULT_PAGE_SIZE,
4498
+ };
4499
+ const useLocationsView = (options) => {
4500
+ const getConfig = useGetActionInput();
4501
+ const [state, handleList] = useListLocations();
4502
+ const { data, message, hasError, isLoading } = state;
4503
+ const [_, handleDownload] = useProcessTasks(downloadHandler);
4504
+ const [, dispatchStoreAction] = useStore();
4505
+ const { items, nextToken, search } = data;
4506
+ const hasNextToken = !!nextToken;
4507
+ const { hasExhaustedSearch = false } = search ?? {};
4508
+ const onNavigate = options?.onNavigate;
4509
+ const initialValues = options?.initialValues ?? {};
4510
+ const listOptionsRef = React__namespace["default"].useRef({
4511
+ ...DEFAULT_LIST_OPTIONS,
4512
+ ...initialValues,
4513
+ });
4514
+ const listOptions = listOptionsRef.current;
4515
+ // initial load
4516
+ React__namespace["default"].useEffect(() => {
4517
+ handleList({
4518
+ options: { ...listOptions, refresh: true },
4519
+ });
4520
+ }, [handleList, listOptions]);
4521
+ // set up pagination
4522
+ const paginateCallback = () => {
4523
+ if (!nextToken)
4524
+ return;
4525
+ handleList({
4526
+ options: { ...listOptions, nextToken },
4527
+ });
4528
+ };
4529
+ const { currentPage, onPaginate, handleReset, highestPageVisited, pageItems, } = usePaginate({
4530
+ items,
4531
+ paginateCallback,
4532
+ pageSize: listOptions.pageSize,
4533
+ hasNextToken,
4534
+ });
4535
+ const onSearch = (query) => {
4536
+ handleReset();
4537
+ handleList({
4538
+ options: {
4539
+ ...listOptions,
4540
+ search: {
4541
+ query,
4542
+ filterBy: (location) => {
4543
+ return location.prefix ? 'prefix' : 'bucket';
4544
+ },
4545
+ },
4546
+ },
4547
+ });
4548
+ };
4549
+ const { searchQuery, onSearchQueryChange, onSearchSubmit, resetSearch } = useSearch({ onSearch });
4550
+ const shouldShowEmptyMessage = pageItems.length === 0 && !isLoading && !hasError;
4551
+ return {
4552
+ isLoading,
4553
+ hasError,
4554
+ message,
4555
+ page: currentPage,
4556
+ hasNextPage: hasNextToken,
4557
+ highestPageVisited,
4558
+ pageItems,
4559
+ shouldShowEmptyMessage,
4560
+ searchQuery,
4561
+ hasExhaustedSearch,
4562
+ onDownload: (location) => {
4563
+ handleDownload({
4564
+ config: getConfig(location),
4565
+ data: createFileDataItemFromLocation(location),
4566
+ });
4567
+ },
4568
+ onNavigate: (location) => {
4569
+ onNavigate?.(location);
4570
+ dispatchStoreAction({ type: 'NAVIGATE', location });
4571
+ },
4572
+ onRefresh: () => {
4573
+ resetSearch();
4574
+ handleReset();
4575
+ handleList({
4576
+ options: { ...listOptions, refresh: true },
4577
+ });
4578
+ },
4579
+ onPaginate,
4580
+ onSearch: onSearchSubmit,
4581
+ onSearchQueryChange,
4582
+ onSearchClear: () => {
4583
+ resetSearch();
4584
+ handleReset();
4585
+ handleList({
4586
+ options: { ...listOptions, refresh: true },
4587
+ });
4588
+ },
4589
+ };
4590
+ };
4591
+
4592
+ const LocationsView = ({ className, ...props }) => {
4593
+ const state = useLocationsView(props);
4594
+ const { hasError } = state;
4595
+ return (React__namespace["default"].createElement(ViewElement, { className: ui.classNames(STORAGE_BROWSER_BLOCK, className), "data-testid": "LOCATIONS_VIEW" },
4596
+ React__namespace["default"].createElement(LocationsViewProvider, { ...state },
4597
+ React__namespace["default"].createElement(TitleControl, null),
4598
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__controls` },
4599
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__search` },
4600
+ React__namespace["default"].createElement(SearchControl, null)),
4601
+ React__namespace["default"].createElement(PaginationControl, null),
4602
+ React__namespace["default"].createElement(DataRefreshControl, null)),
4603
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__data-table` },
4604
+ React__namespace["default"].createElement(LoadingIndicatorControl, null),
4605
+ hasError ? null : React__namespace["default"].createElement(DataTableControl, null)),
4606
+ React__namespace["default"].createElement(ViewElement, { className: `${STORAGE_BROWSER_BLOCK}__message` },
4607
+ React__namespace["default"].createElement(MessageControl, null)))));
4608
+ };
4609
+ LocationsView.displayName = 'LocationsView';
4610
+ LocationsView.Provider = LocationsViewProvider;
4611
+ LocationsView.LoadingIndicator = LoadingIndicatorControl;
4612
+ LocationsView.LocationsTable = DataTableControl;
4613
+ LocationsView.Message = MessageControl;
4614
+ LocationsView.Pagination = PaginationControl;
4615
+ LocationsView.Refresh = DataRefreshControl;
4616
+ LocationsView.Search = SearchControl;
4617
+ LocationsView.Title = TitleControl;
4618
+
4619
+ const ERROR_MESSAGE = '`useViews` must be called from within a `ViewsProvider`';
4620
+ const ViewsContext = React__namespace["default"].createContext(undefined);
4621
+ function ViewsProvider({ children, views, }) {
4622
+ // destructure `views` to prevent extraneous rerender of components in the
4623
+ // scenario of an unstable reference provided as `views`
4624
+ const { LocationDetailView: LocationDetailView$1, LocationActionView: LocationActionView$1, LocationsView: LocationsView$1 } = views ?? {};
4625
+ const value = React__namespace["default"].useMemo(() => ({
4626
+ LocationActionView: LocationActionView$1 ?? LocationActionView,
4627
+ LocationDetailView: LocationDetailView$1 ?? LocationDetailView,
4628
+ LocationsView: LocationsView$1 ?? LocationsView,
4629
+ }), [LocationDetailView$1, LocationActionView$1, LocationsView$1]);
4630
+ return (React__namespace["default"].createElement(ViewsContext.Provider, { value: value }, children));
4631
+ }
4632
+ function useViews() {
4633
+ const context = React__namespace["default"].useContext(ViewsContext);
4634
+ if (!context) {
4635
+ throw new Error(ERROR_MESSAGE);
4636
+ }
4637
+ return context;
4638
+ }
4639
+
4640
+ /**
4641
+ * Handles default `StorageBrowser` behavior:
4642
+ * - render `LocationsView` on init
4643
+ * - render `LocationDetailView` on location selection
4644
+ * - render `ActionView` on action selection
4645
+ */
4646
+ function StorageBrowserDefault() {
4647
+ const { LocationActionView, LocationDetailView, LocationsView } = useViews();
4648
+ const [{ actionType, location }] = useStore();
4649
+ const { current } = location;
4650
+ if (actionType) {
4651
+ return React__namespace["default"].createElement(LocationActionView, null);
4652
+ }
4653
+ if (current) {
4654
+ return React__namespace["default"].createElement(LocationDetailView, null);
4655
+ }
4656
+ return React__namespace["default"].createElement(LocationsView, null);
4657
+ }
4658
+
4659
+ const DEFAULT_USE_VIEWS = {
4660
+ CopyView: useCopyView,
4661
+ CreateFolderView: useCreateFolderView,
4662
+ DeleteView: useDeleteView,
4663
+ LocationDetailView: useLocationDetailView,
4664
+ LocationsView: useLocationsView,
4665
+ UploadView: useUploadView,
4666
+ };
4667
+ const isDefaultUseViewName = (viewName) => Object.keys(DEFAULT_USE_VIEWS).some((key) => key === viewName);
4668
+ const createUseView = (configs) => {
4669
+ const hooks = Object.values(configs).reduce((out, { componentName }) => ({
4670
+ ...out,
4671
+ [componentName.slice(0, -4)]: isDefaultUseViewName(componentName)
4672
+ ? DEFAULT_USE_VIEWS[componentName]
4673
+ : useActionView,
4674
+ }), {});
4675
+ return function useView(type) {
4676
+ // todo: add assertion here
4677
+ return hooks[type](type);
4678
+ };
4679
+ };
4680
+
4681
+ function createStorageBrowser(input) {
4682
+ assertRegisterAuthListener(input.config.registerAuthListener);
4683
+ const { accountId, customEndpoint, registerAuthListener, getLocationCredentials, region, } = input.config;
4684
+ const ConfigurationProvider = createConfigurationProvider({
4685
+ accountId,
4686
+ actions: {
4687
+ ...defaultActionConfigs,
4688
+ // @ts-expect-error To be addressed with line 40
4689
+ listLocations: {
4690
+ componentName: 'LocationsView',
4691
+ handler: input.config.listLocations,
4692
+ },
4693
+ },
4694
+ customEndpoint,
4695
+ displayName: 'ConfigurationProvider',
4696
+ getLocationCredentials,
4697
+ region,
4698
+ registerAuthListener,
4699
+ });
4700
+ const composables = {
4701
+ // fallback composables
4702
+ ...DEFAULT_COMPOSABLES,
4703
+ // default components
4704
+ ...componentsDefault,
4705
+ // override components
4706
+ ...input.components,
4707
+ };
4708
+ /**
4709
+ * Provides state, configuration and action values that are shared between
4710
+ * the primary View components
4711
+ */
4712
+ function Provider({ children, ...props }) {
4713
+ return (React__namespace["default"].createElement(StoreProvider, { ...props },
4714
+ React__namespace["default"].createElement(ConfigurationProvider, null,
4715
+ React__namespace["default"].createElement(DisplayTextProvider, { displayText: props.displayText },
4716
+ React__namespace["default"].createElement(ComponentsProvider, { composables: composables, elements: elementsDefault }, children)))));
4717
+ }
4718
+ const StorageBrowser = ({ views, displayText }) => (React__namespace["default"].createElement(ErrorBoundary, null,
4719
+ React__namespace["default"].createElement(Provider, { displayText: displayText },
4720
+ React__namespace["default"].createElement(ViewsProvider, { views: views },
4721
+ React__namespace["default"].createElement(StorageBrowserDefault, null)))));
4722
+ StorageBrowser.LocationActionView = LocationActionView;
4723
+ StorageBrowser.LocationDetailView = LocationDetailView;
4724
+ StorageBrowser.LocationsView = LocationsView;
4725
+ StorageBrowser.CopyView = CopyView;
4726
+ StorageBrowser.CreateFolderView = CreateFolderView;
4727
+ StorageBrowser.DeleteView = DeleteView;
4728
+ StorageBrowser.UploadView = UploadView;
4729
+ StorageBrowser.Provider = Provider;
4730
+ StorageBrowser.displayName = 'StorageBrowser';
4731
+ const useView = createUseView(defaultActionConfigs);
4732
+ return { StorageBrowser, useView };
4733
+ }
4734
+
4735
+ const toAccessGrantPermission = (permission) => {
4736
+ let result = '';
4737
+ permission.forEach((access) => {
4738
+ if (['read', 'get', 'list'].includes(access)) {
4739
+ if (!result.includes('READ')) {
4740
+ result = 'READ' + result;
4741
+ }
4742
+ }
4743
+ if (['write', 'delete'].includes(access)) {
4744
+ if (!result.includes('WRITE')) {
4745
+ result += 'WRITE';
4746
+ }
4747
+ }
4748
+ });
4749
+ if (result === '') {
4750
+ throw new Error('Improper Permission: Please provide correct permission.');
4751
+ }
4752
+ return result;
4753
+ };
4754
+ const parseAmplifyAuthPermission = (permissions) => {
4755
+ const result = [];
4756
+ permissions.forEach((access) => {
4757
+ if (access === 'read') {
4758
+ if (!result.includes('list')) {
4759
+ result.push('list');
4760
+ }
4761
+ if (!result.includes('get')) {
4762
+ result.push('get');
4763
+ }
4764
+ }
4765
+ else if (['delete', 'get', 'list', 'write'].includes(access) &&
4766
+ !result.includes(access)) {
4767
+ result.push(access);
4768
+ }
4769
+ });
4770
+ if (result.length === 0) {
4771
+ throw new Error('Improper Permission: Please provide correct permission.');
4772
+ }
4773
+ return result.sort();
4774
+ };
4775
+
4776
+ const getPaginatedLocations = ({ items, pageSize, nextToken, }) => {
4777
+ if (pageSize) {
4778
+ if (nextToken) {
4779
+ if (Number(nextToken) > items.length) {
4780
+ return { items: [], nextToken: undefined };
4781
+ }
4782
+ const start = -nextToken;
4783
+ const end = start + pageSize < 0 ? start + pageSize : undefined;
4784
+ return {
4785
+ items: items.slice(start, end),
4786
+ nextToken: end ? `${-end}` : undefined,
4787
+ };
4788
+ }
4789
+ return {
4790
+ items: items.slice(0, pageSize),
4791
+ nextToken: items.length > pageSize ? `${items.length - pageSize}` : undefined,
4792
+ };
4793
+ }
4794
+ return { items, nextToken: undefined };
4795
+ };
4796
+
4797
+ const createAmplifyListLocationsHandler = () => {
4798
+ let cachedItems = [];
4799
+ return async function listLocations(input) {
4800
+ const { options } = input ?? {};
4801
+ const { nextToken, pageSize } = options ?? {};
4802
+ if (cachedItems.length > 0) {
4803
+ return getPaginatedLocations({
4804
+ items: cachedItems,
4805
+ pageSize,
4806
+ nextToken,
4807
+ });
4808
+ }
4809
+ const { locations } = await internals.listPaths();
4810
+ const sanitizedItems = locations.map(({ bucket, permission, prefix, type }) => {
4811
+ return {
4812
+ type,
4813
+ permissions: parseAmplifyAuthPermission(permission),
4814
+ bucket,
4815
+ prefix: prefix.endsWith('*') ? prefix.slice(0, -1) : prefix,
4816
+ id: crypto.randomUUID(),
4817
+ };
4818
+ });
4819
+ cachedItems = sanitizedItems;
4820
+ return getPaginatedLocations({
4821
+ items: cachedItems,
4822
+ pageSize,
4823
+ nextToken,
4824
+ });
4825
+ };
4826
+ };
4827
+
4828
+ const MISSING_BUCKET_OR_REGION_ERROR = 'Amplify Storage configuration not found. Did you run `Amplify.configure` from your project root?';
4829
+ const MISSING_IDENTITY_ID_ERROR = '`identityId` not found.';
4830
+ const MISSING_TEMPORARY_CREDENTIALS_ERROR = 'Temporary Auth `credentials` not found.';
4831
+ const isTemporaryCredentials = (value) => !!value?.sessionToken || !!value?.expiration;
4832
+ const createAmplifyAuthAdapter = () => {
4833
+ const { bucket, region } = awsAmplify.Amplify.getConfig()?.Storage?.S3 ?? {};
4834
+ if (!bucket || !region) {
4835
+ throw new Error(MISSING_BUCKET_OR_REGION_ERROR);
4836
+ }
4837
+ const listLocations = createAmplifyListLocationsHandler();
4838
+ const getLocationCredentials = async () => {
4839
+ const { credentials, identityId } = await auth.fetchAuthSession();
4840
+ if (!isTemporaryCredentials(credentials)) {
4841
+ throw new Error(MISSING_TEMPORARY_CREDENTIALS_ERROR);
4842
+ }
4843
+ if (!identityId) {
4844
+ throw new Error(MISSING_IDENTITY_ID_ERROR);
4845
+ }
4846
+ return { credentials, identityId };
4847
+ };
4848
+ const registerAuthListener = (onStateChange) => {
4849
+ const remove = utils.Hub.listen('auth', (data) => {
4850
+ if (data.payload.event === 'signedOut') {
4851
+ onStateChange();
4852
+ remove();
4853
+ }
4854
+ });
4855
+ };
4856
+ return {
4857
+ getLocationCredentials,
4858
+ listLocations,
4859
+ registerAuthListener,
4860
+ region,
4861
+ };
4862
+ };
4863
+
4864
+ exports.componentsDefault = componentsDefault;
4865
+ exports.createAmplifyAuthAdapter = createAmplifyAuthAdapter;
4866
+ exports.createStorageBrowser = createStorageBrowser;
4867
+ exports.listLocationsHandler = listLocationsHandler;
4868
+ exports.toAccessGrantPermission = toAccessGrantPermission;