@verdaccio/ui-components 5.0.0-next-9.19 → 5.0.0-next-9.21

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 (312) hide show
  1. package/build/api/use-data-mutation.js +1 -4
  2. package/build/api/use-data-mutation.js.map +1 -1
  3. package/build/api/use-data-mutation.mjs +1 -4
  4. package/build/api/use-data-mutation.mjs.map +1 -1
  5. package/build/api/use-data.d.ts +1 -0
  6. package/build/api/use-data.js +3 -2
  7. package/build/api/use-data.js.map +1 -1
  8. package/build/api/use-data.mjs +3 -3
  9. package/build/api/use-data.mjs.map +1 -1
  10. package/build/components/ActionBar/ActionBar.js +4 -2
  11. package/build/components/ActionBar/ActionBar.js.map +1 -1
  12. package/build/components/ActionBar/ActionBar.mjs +4 -2
  13. package/build/components/ActionBar/ActionBar.mjs.map +1 -1
  14. package/build/components/ActionBar/ActionBarAction.js +1 -1
  15. package/build/components/ActionBar/ActionBarAction.mjs +1 -1
  16. package/build/components/AppRoute/AppRoute.js +13 -0
  17. package/build/components/AppRoute/AppRoute.js.map +1 -1
  18. package/build/components/AppRoute/AppRoute.mjs +13 -0
  19. package/build/components/AppRoute/AppRoute.mjs.map +1 -1
  20. package/build/components/Author/Author.js +1 -1
  21. package/build/components/Author/Author.mjs +1 -1
  22. package/build/components/CopyClipboard/CopyToClipBoard.js +5 -0
  23. package/build/components/CopyClipboard/CopyToClipBoard.js.map +1 -1
  24. package/build/components/CopyClipboard/CopyToClipBoard.mjs +5 -0
  25. package/build/components/CopyClipboard/CopyToClipBoard.mjs.map +1 -1
  26. package/build/components/CopyClipboard/utils.js +14 -1
  27. package/build/components/CopyClipboard/utils.js.map +1 -1
  28. package/build/components/CopyClipboard/utils.mjs +14 -1
  29. package/build/components/CopyClipboard/utils.mjs.map +1 -1
  30. package/build/components/Dependencies/Dependencies.js +2 -1
  31. package/build/components/Dependencies/Dependencies.js.map +1 -1
  32. package/build/components/Dependencies/Dependencies.mjs +2 -1
  33. package/build/components/Dependencies/Dependencies.mjs.map +1 -1
  34. package/build/components/Dependencies/DependencyBlock.js +1 -1
  35. package/build/components/Dependencies/DependencyBlock.mjs +1 -1
  36. package/build/components/Developers/Title.js +1 -1
  37. package/build/components/Developers/Title.mjs +1 -1
  38. package/build/components/Developers/get-unique-developer-values.js +2 -1
  39. package/build/components/Developers/get-unique-developer-values.js.map +1 -1
  40. package/build/components/Developers/get-unique-developer-values.mjs +2 -1
  41. package/build/components/Developers/get-unique-developer-values.mjs.map +1 -1
  42. package/build/components/Distribution/Dist.js +3 -3
  43. package/build/components/Distribution/Dist.js.map +1 -1
  44. package/build/components/Distribution/Dist.mjs +3 -3
  45. package/build/components/Distribution/Dist.mjs.map +1 -1
  46. package/build/components/Engines/Engines.js +1 -1
  47. package/build/components/Engines/Engines.mjs +1 -1
  48. package/build/components/Forbidden/Forbidden.js +1 -1
  49. package/build/components/Forbidden/Forbidden.mjs +1 -1
  50. package/build/components/FundButton/FundButton.js +4 -3
  51. package/build/components/FundButton/FundButton.js.map +1 -1
  52. package/build/components/FundButton/FundButton.mjs +4 -3
  53. package/build/components/FundButton/FundButton.mjs.map +1 -1
  54. package/build/components/GenericError/GenericError.d.ts +3 -0
  55. package/build/components/GenericError/GenericError.js +60 -0
  56. package/build/components/GenericError/GenericError.js.map +1 -0
  57. package/build/components/GenericError/GenericError.mjs +54 -0
  58. package/build/components/GenericError/GenericError.mjs.map +1 -0
  59. package/build/components/GenericError/index.d.ts +1 -0
  60. package/build/components/GenericError/index.js +2 -0
  61. package/build/components/GenericError/index.mjs +2 -0
  62. package/build/components/Help/Help.js +1 -1
  63. package/build/components/Help/Help.mjs +1 -1
  64. package/build/components/Install/Install.js +1 -1
  65. package/build/components/Install/Install.mjs +1 -1
  66. package/build/components/Install/InstallListItem.js +2 -2
  67. package/build/components/Install/InstallListItem.js.map +1 -1
  68. package/build/components/Install/InstallListItem.mjs +2 -2
  69. package/build/components/Install/InstallListItem.mjs.map +1 -1
  70. package/build/components/Keywords/KeywordListItems.js +1 -1
  71. package/build/components/Keywords/KeywordListItems.js.map +1 -1
  72. package/build/components/Keywords/KeywordListItems.mjs +1 -1
  73. package/build/components/Keywords/KeywordListItems.mjs.map +1 -1
  74. package/build/components/Keywords/Keywords.js +2 -2
  75. package/build/components/Keywords/Keywords.js.map +1 -1
  76. package/build/components/Keywords/Keywords.mjs +2 -2
  77. package/build/components/Keywords/Keywords.mjs.map +1 -1
  78. package/build/components/LoginDialog/LoginDialogCloseButton.js +1 -1
  79. package/build/components/LoginDialog/LoginDialogCloseButton.mjs +1 -1
  80. package/build/components/LoginDialog/LoginDialogForm.js +2 -1
  81. package/build/components/LoginDialog/LoginDialogForm.js.map +1 -1
  82. package/build/components/LoginDialog/LoginDialogForm.mjs +2 -1
  83. package/build/components/LoginDialog/LoginDialogForm.mjs.map +1 -1
  84. package/build/components/LoginForm/Login.d.ts +1 -0
  85. package/build/components/LoginForm/Login.js +6 -4
  86. package/build/components/LoginForm/Login.js.map +1 -1
  87. package/build/components/LoginForm/Login.mjs +9 -7
  88. package/build/components/LoginForm/Login.mjs.map +1 -1
  89. package/build/components/LoginForm/PasswordField.js +4 -6
  90. package/build/components/LoginForm/PasswordField.js.map +1 -1
  91. package/build/components/LoginForm/PasswordField.mjs +4 -6
  92. package/build/components/LoginForm/PasswordField.mjs.map +1 -1
  93. package/build/components/LoginForm/UsernameField.js +4 -6
  94. package/build/components/LoginForm/UsernameField.js.map +1 -1
  95. package/build/components/LoginForm/UsernameField.mjs +4 -6
  96. package/build/components/LoginForm/UsernameField.mjs.map +1 -1
  97. package/build/components/LoginForm/styles.js +1 -1
  98. package/build/components/LoginForm/styles.mjs +1 -1
  99. package/build/components/LoginForm/useLoginForm.js +13 -3
  100. package/build/components/LoginForm/useLoginForm.js.map +1 -1
  101. package/build/components/LoginForm/useLoginForm.mjs +14 -4
  102. package/build/components/LoginForm/useLoginForm.mjs.map +1 -1
  103. package/build/components/NoItems/NoItems.js +2 -2
  104. package/build/components/NoItems/NoItems.mjs +1 -1
  105. package/build/components/NotFound/NotFound.js +1 -1
  106. package/build/components/NotFound/NotFound.mjs +1 -1
  107. package/build/components/Package/Package.d.ts +1 -1
  108. package/build/components/Package/Package.js +28 -29
  109. package/build/components/Package/Package.js.map +1 -1
  110. package/build/components/Package/Package.mjs +29 -30
  111. package/build/components/Package/Package.mjs.map +1 -1
  112. package/build/components/Person/Person.js +1 -1
  113. package/build/components/Person/Person.js.map +1 -1
  114. package/build/components/Person/Person.mjs +1 -1
  115. package/build/components/Person/Person.mjs.map +1 -1
  116. package/build/components/RawViewer/RawViewer.js +1 -1
  117. package/build/components/RawViewer/RawViewer.mjs +1 -1
  118. package/build/components/RegistryInfoDialog/RegistryInfoDialog.js +1 -1
  119. package/build/components/RegistryInfoDialog/RegistryInfoDialog.mjs +1 -1
  120. package/build/components/Repository/Repository.js +5 -8
  121. package/build/components/Repository/Repository.js.map +1 -1
  122. package/build/components/Repository/Repository.mjs +5 -8
  123. package/build/components/Repository/Repository.mjs.map +1 -1
  124. package/build/components/Search/AutoComplete/AutoComplete.d.ts +1 -0
  125. package/build/components/Search/AutoComplete/AutoComplete.js +4 -4
  126. package/build/components/Search/AutoComplete/AutoComplete.js.map +1 -1
  127. package/build/components/Search/AutoComplete/AutoComplete.mjs +4 -4
  128. package/build/components/Search/AutoComplete/AutoComplete.mjs.map +1 -1
  129. package/build/components/Search/Search.js +12 -4
  130. package/build/components/Search/Search.js.map +1 -1
  131. package/build/components/Search/Search.mjs +13 -5
  132. package/build/components/Search/Search.mjs.map +1 -1
  133. package/build/components/Search/SearchItem.js +1 -1
  134. package/build/components/Search/SearchItem.mjs +1 -1
  135. package/build/components/SettingsMenu/SettingsMenu.js +1 -1
  136. package/build/components/SettingsMenu/SettingsMenu.mjs +1 -1
  137. package/build/components/SideBarTitle/SideBarTitle.js +2 -2
  138. package/build/components/SideBarTitle/SideBarTitle.js.map +1 -1
  139. package/build/components/SideBarTitle/SideBarTitle.mjs +2 -2
  140. package/build/components/SideBarTitle/SideBarTitle.mjs.map +1 -1
  141. package/build/components/UpLinks/UpLinks.js +1 -1
  142. package/build/components/UpLinks/UpLinks.mjs +1 -1
  143. package/build/components/Versions/HistoryList.js +2 -2
  144. package/build/components/Versions/HistoryList.js.map +1 -1
  145. package/build/components/Versions/HistoryList.mjs +2 -2
  146. package/build/components/Versions/HistoryList.mjs.map +1 -1
  147. package/build/components/Versions/Versions.js +22 -21
  148. package/build/components/Versions/Versions.js.map +1 -1
  149. package/build/components/Versions/Versions.mjs +22 -21
  150. package/build/components/Versions/Versions.mjs.map +1 -1
  151. package/build/index.d.ts +1 -0
  152. package/build/index.js +4 -0
  153. package/build/index.mjs +4 -2
  154. package/build/pages/Stage/StageDetail.d.ts +2 -0
  155. package/build/pages/Stage/StageDetail.js +8 -0
  156. package/build/pages/Stage/StageDetail.js.map +1 -0
  157. package/build/pages/Stage/StageDetail.mjs +8 -0
  158. package/build/pages/Stage/StageDetail.mjs.map +1 -0
  159. package/build/pages/Stage/StageList.d.ts +2 -0
  160. package/build/pages/Stage/StageList.js +8 -0
  161. package/build/pages/Stage/StageList.js.map +1 -0
  162. package/build/pages/Stage/StageList.mjs +8 -0
  163. package/build/pages/Stage/StageList.mjs.map +1 -0
  164. package/build/pages/Stage/index.d.ts +2 -0
  165. package/build/pages/Version/Version.js +4 -1
  166. package/build/pages/Version/Version.js.map +1 -1
  167. package/build/pages/Version/Version.mjs +4 -1
  168. package/build/pages/Version/Version.mjs.map +1 -1
  169. package/build/providers/AuthProvider/AuthProvider.js +9 -7
  170. package/build/providers/AuthProvider/AuthProvider.js.map +1 -1
  171. package/build/providers/AuthProvider/AuthProvider.mjs +10 -8
  172. package/build/providers/AuthProvider/AuthProvider.mjs.map +1 -1
  173. package/build/providers/AuthProvider/utils.d.ts +12 -0
  174. package/build/providers/AuthProvider/utils.js +22 -0
  175. package/build/providers/AuthProvider/utils.js.map +1 -1
  176. package/build/providers/AuthProvider/utils.mjs +21 -2
  177. package/build/providers/AuthProvider/utils.mjs.map +1 -1
  178. package/build/providers/DownloadProvider/DownloadProvider.d.ts +1 -0
  179. package/build/providers/DownloadProvider/DownloadProvider.js +27 -4
  180. package/build/providers/DownloadProvider/DownloadProvider.js.map +1 -1
  181. package/build/providers/DownloadProvider/DownloadProvider.mjs +27 -6
  182. package/build/providers/DownloadProvider/DownloadProvider.mjs.map +1 -1
  183. package/build/providers/ManifestsProvider/ManifestsProvider.js +1 -1
  184. package/build/providers/ManifestsProvider/ManifestsProvider.js.map +1 -1
  185. package/build/providers/ManifestsProvider/ManifestsProvider.mjs +1 -1
  186. package/build/providers/ManifestsProvider/ManifestsProvider.mjs.map +1 -1
  187. package/build/providers/SearchProvider/SearchProvider.d.ts +1 -0
  188. package/build/providers/SearchProvider/SearchProvider.js +8 -6
  189. package/build/providers/SearchProvider/SearchProvider.js.map +1 -1
  190. package/build/providers/SearchProvider/SearchProvider.mjs +8 -6
  191. package/build/providers/SearchProvider/SearchProvider.mjs.map +1 -1
  192. package/build/providers/TranslatorProvider/TranslatorProvider.js +5 -3
  193. package/build/providers/TranslatorProvider/TranslatorProvider.js.map +1 -1
  194. package/build/providers/TranslatorProvider/TranslatorProvider.mjs +5 -3
  195. package/build/providers/TranslatorProvider/TranslatorProvider.mjs.map +1 -1
  196. package/build/providers/VersionProvider/VersionProvider.js +3 -3
  197. package/build/providers/VersionProvider/VersionProvider.js.map +1 -1
  198. package/build/providers/VersionProvider/VersionProvider.mjs +3 -3
  199. package/build/providers/VersionProvider/VersionProvider.mjs.map +1 -1
  200. package/build/sections/Detail/Tabs.js +1 -1
  201. package/build/sections/Detail/Tabs.mjs +1 -1
  202. package/build/sections/Footer/Footer.js +1 -1
  203. package/build/sections/Footer/Footer.mjs +1 -1
  204. package/build/sections/Header/Header.d.ts +0 -1
  205. package/build/sections/Header/Header.js +16 -14
  206. package/build/sections/Header/Header.js.map +1 -1
  207. package/build/sections/Header/Header.mjs +17 -15
  208. package/build/sections/Header/Header.mjs.map +1 -1
  209. package/build/sections/Header/HeaderGreetings.js +1 -1
  210. package/build/sections/Header/HeaderGreetings.mjs +1 -1
  211. package/build/sections/Header/HeaderMenu.js +26 -7
  212. package/build/sections/Header/HeaderMenu.js.map +1 -1
  213. package/build/sections/Header/HeaderMenu.mjs +26 -7
  214. package/build/sections/Header/HeaderMenu.mjs.map +1 -1
  215. package/build/sections/Header/HeaderRight.js +1 -1
  216. package/build/sections/Header/HeaderRight.mjs +1 -1
  217. package/build/sections/Header/HeaderSettingsDialog.js +1 -1
  218. package/build/sections/Header/HeaderSettingsDialog.mjs +1 -1
  219. package/build/sections/Header/LanguageSwitch.js +1 -1
  220. package/build/sections/Header/LanguageSwitch.mjs +1 -1
  221. package/build/sections/Header/RegistryInfoContent/RegistryInfoContent.js +1 -1
  222. package/build/sections/Header/RegistryInfoContent/RegistryInfoContent.mjs +1 -1
  223. package/build/sections/Home/Home.js +4 -3
  224. package/build/sections/Home/Home.js.map +1 -1
  225. package/build/sections/Home/Home.mjs +5 -4
  226. package/build/sections/Home/Home.mjs.map +1 -1
  227. package/build/sections/Security/AddUser.js +33 -18
  228. package/build/sections/Security/AddUser.js.map +1 -1
  229. package/build/sections/Security/AddUser.mjs +37 -22
  230. package/build/sections/Security/AddUser.mjs.map +1 -1
  231. package/build/sections/Security/ChangePassword.js +17 -15
  232. package/build/sections/Security/ChangePassword.js.map +1 -1
  233. package/build/sections/Security/ChangePassword.mjs +19 -17
  234. package/build/sections/Security/ChangePassword.mjs.map +1 -1
  235. package/build/sections/Security/Login.js +51 -35
  236. package/build/sections/Security/Login.js.map +1 -1
  237. package/build/sections/Security/Login.mjs +54 -38
  238. package/build/sections/Security/Login.mjs.map +1 -1
  239. package/build/sections/Security/Success.js +28 -24
  240. package/build/sections/Security/Success.js.map +1 -1
  241. package/build/sections/Security/Success.mjs +29 -25
  242. package/build/sections/Security/Success.mjs.map +1 -1
  243. package/build/sections/Stage/StageActions.d.ts +15 -0
  244. package/build/sections/Stage/StageActions.js +101 -0
  245. package/build/sections/Stage/StageActions.js.map +1 -0
  246. package/build/sections/Stage/StageActions.mjs +99 -0
  247. package/build/sections/Stage/StageActions.mjs.map +1 -0
  248. package/build/sections/Stage/StageDetail.d.ts +3 -0
  249. package/build/sections/Stage/StageDetail.js +110 -0
  250. package/build/sections/Stage/StageDetail.js.map +1 -0
  251. package/build/sections/Stage/StageDetail.mjs +108 -0
  252. package/build/sections/Stage/StageDetail.mjs.map +1 -0
  253. package/build/sections/Stage/StageList.d.ts +3 -0
  254. package/build/sections/Stage/StageList.js +153 -0
  255. package/build/sections/Stage/StageList.js.map +1 -0
  256. package/build/sections/Stage/StageList.mjs +151 -0
  257. package/build/sections/Stage/StageList.mjs.map +1 -0
  258. package/build/sections/Stage/index.d.ts +6 -0
  259. package/build/sections/Stage/index.js +13 -0
  260. package/build/sections/Stage/index.mjs +6 -0
  261. package/build/sections/Stage/types.d.ts +22 -0
  262. package/build/sections/Stage/useRequireSession.d.ts +14 -0
  263. package/build/sections/Stage/useRequireSession.js +33 -0
  264. package/build/sections/Stage/useRequireSession.js.map +1 -0
  265. package/build/sections/Stage/useRequireSession.mjs +33 -0
  266. package/build/sections/Stage/useRequireSession.mjs.map +1 -0
  267. package/build/sections/Stage/useStage.d.ts +34 -0
  268. package/build/sections/Stage/useStage.js +71 -0
  269. package/build/sections/Stage/useStage.js.map +1 -0
  270. package/build/sections/Stage/useStage.mjs +65 -0
  271. package/build/sections/Stage/useStage.mjs.map +1 -0
  272. package/build/store/api.js +7 -4
  273. package/build/store/api.js.map +1 -1
  274. package/build/store/api.mjs +7 -4
  275. package/build/store/api.mjs.map +1 -1
  276. package/build/types/packageMeta.d.ts +3 -2
  277. package/build/utils/cli-utils.js +2 -2
  278. package/build/utils/cli-utils.js.map +1 -1
  279. package/build/utils/cli-utils.mjs +2 -2
  280. package/build/utils/cli-utils.mjs.map +1 -1
  281. package/build/utils/index.js +1 -0
  282. package/build/utils/index.mjs +2 -2
  283. package/build/utils/routes.d.ts +5 -1
  284. package/build/utils/routes.js +4 -0
  285. package/build/utils/routes.js.map +1 -1
  286. package/build/utils/routes.mjs +4 -0
  287. package/build/utils/routes.mjs.map +1 -1
  288. package/build/utils/schemas.d.ts +1 -0
  289. package/build/utils/schemas.js +4 -4
  290. package/build/utils/schemas.js.map +1 -1
  291. package/build/utils/schemas.mjs +4 -4
  292. package/build/utils/schemas.mjs.map +1 -1
  293. package/build/utils/session-id.d.ts +8 -0
  294. package/build/utils/session-id.js +26 -0
  295. package/build/utils/session-id.js.map +1 -0
  296. package/build/utils/session-id.mjs +26 -0
  297. package/build/utils/session-id.mjs.map +1 -0
  298. package/build/utils/token.d.ts +1 -0
  299. package/build/utils/token.js +12 -8
  300. package/build/utils/token.js.map +1 -1
  301. package/build/utils/token.mjs +12 -9
  302. package/build/utils/token.mjs.map +1 -1
  303. package/build/utils/url.js +1 -1
  304. package/build/utils/url.js.map +1 -1
  305. package/build/utils/url.mjs +1 -1
  306. package/build/utils/url.mjs.map +1 -1
  307. package/build/utils/utils.d.ts +10 -0
  308. package/build/utils/utils.js +26 -0
  309. package/build/utils/utils.js.map +1 -1
  310. package/build/utils/utils.mjs +25 -1
  311. package/build/utils/utils.mjs.map +1 -1
  312. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"ChangePassword.mjs","names":[],"sources":["../../../src/sections/Security/ChangePassword.tsx"],"sourcesContent":["import { yupResolver } from '@hookform/resolvers/yup';\nimport { Button, Typography } from '@mui/material';\nimport React, { useCallback, useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { useNavigate } from 'react-router';\n\nimport { useDataMutation } from '../../api/use-data-mutation';\nimport LoginDialogFormError from '../../components/LoginDialog/LoginDialogFormError';\nimport { getConfiguration } from '../../configuration';\nimport SecurityLayout from '../../layouts/Security/Dialog';\nimport { normalizeAuthError } from '../../providers/AuthProvider/utils';\nimport { stripTrailingSlash } from '../../store/utils';\nimport { Route } from '../../utils';\nimport { APIRoute } from '../../utils/routes';\nimport type { ChangePasswordFormValues } from '../../utils/schemas';\nimport { changePasswordSchema } from '../../utils/schemas';\nimport { MessageType } from './Success';\nimport { SecurityContainer, SecurityForm, SecurityTextField } from './styles';\n\nconst ChangePassword: React.FC = () => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const configuration = getConfiguration();\n const basePath = stripTrailingSlash(configuration.base);\n const changePasswordEnabled = configuration?.flags?.changePassword;\n\n const form = useForm<ChangePasswordFormValues>({\n mode: 'onChange',\n defaultValues: {\n username: '',\n oldPassword: '',\n newPassword: '',\n confirmPassword: '',\n },\n resolver: yupResolver(changePasswordSchema),\n });\n\n const {\n setError,\n handleSubmit,\n register,\n formState: { isValid, errors },\n } = form;\n\n const { trigger } = useDataMutation<{ ok: string }>(basePath, APIRoute.RESET_PASSWORD, 'PUT');\n\n const handleChangePassword = useCallback(\n async (body: { password: { old: string; new: string } }) => {\n try {\n await trigger(body);\n } catch (err) {\n throw normalizeAuthError(err);\n }\n },\n [trigger]\n );\n\n const onSubmit = useCallback(\n async (data: ChangePasswordFormValues) => {\n try {\n await handleChangePassword({\n password: {\n old: data.oldPassword,\n new: data.newPassword,\n },\n });\n navigate(`${Route.SUCCESS}?messageType=${MessageType.ChangePassword}`);\n } catch {\n setError('root', {\n type: 'server',\n message: 'Failed to change password',\n });\n }\n },\n [handleChangePassword, setError, navigate]\n );\n\n useEffect(() => {\n if (!changePasswordEnabled) {\n navigate('/');\n }\n }, [changePasswordEnabled, navigate]);\n\n return changePasswordEnabled ? (\n <SecurityLayout>\n <SecurityContainer>\n <SecurityForm onSubmit={handleSubmit(onSubmit)}>\n <Typography align=\"center\" component=\"h1\" gutterBottom={true} variant=\"h4\">\n {t('security.changePassword.title')}\n </Typography>\n <SecurityTextField\n error={!!errors.username}\n helperText={errors.username?.message}\n label={t('security.changePassword.username')}\n {...register('username')}\n required={true}\n />\n <SecurityTextField\n error={!!errors.oldPassword}\n helperText={errors.oldPassword?.message}\n label={t('security.changePassword.oldPassword')}\n {...register('oldPassword')}\n required={true}\n type=\"password\"\n />\n <SecurityTextField\n error={!!errors.newPassword}\n helperText={errors.newPassword?.message}\n label={t('security.changePassword.newPassword')}\n {...register('newPassword')}\n required={true}\n type=\"password\"\n />\n <SecurityTextField\n error={!!errors.confirmPassword}\n helperText={errors.confirmPassword?.message}\n label={t('security.changePassword.confirmPassword')}\n {...register('confirmPassword')}\n required={true}\n type=\"password\"\n />\n {errors.root && <LoginDialogFormError error={errors.root} />}\n <Button\n color=\"primary\"\n disabled={!isValid}\n fullWidth={true}\n sx={{ mt: 2 }}\n type=\"submit\"\n variant=\"contained\"\n >\n {t('security.changePassword.submit')}\n </Button>\n </SecurityForm>\n </SecurityContainer>\n </SecurityLayout>\n ) : null;\n};\n\nexport default ChangePassword;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoBA,IAAM,uBAAiC;CACrC,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,gBAAgB,iBAAiB;CACvC,MAAM,WAAW,mBAAmB,cAAc,IAAI;CACtD,MAAM,wBAAwB,eAAe,OAAO;CAapD,MAAM,EACJ,UACA,cACA,UACA,WAAW,EAAE,SAAS,aAfX,QAAkC;EAC7C,MAAM;EACN,eAAe;GACb,UAAU;GACV,aAAa;GACb,aAAa;GACb,iBAAiB;EACnB;EACA,UAAU,YAAY,oBAAoB;CAC5C,CAOI;CAEJ,MAAM,EAAE,YAAY,gBAAgC,UAAU,SAAS,gBAAgB,KAAK;CAE5F,MAAM,uBAAuB,YAC3B,OAAO,SAAqD;EAC1D,IAAI;GACF,MAAM,QAAQ,IAAI;EACpB,SAAS,KAAK;GACZ,MAAM,mBAAmB,GAAG;EAC9B;CACF,GACA,CAAC,OAAO,CACV;CAEA,MAAM,WAAW,YACf,OAAO,SAAmC;EACxC,IAAI;GACF,MAAM,qBAAqB,EACzB,UAAU;IACR,KAAK,KAAK;IACV,KAAK,KAAK;GACZ,EACF,CAAC;GACD,SAAS,GAAG,QAAM,QAAQ,eAAe,YAAY,gBAAgB;EACvE,QAAQ;GACN,SAAS,QAAQ;IACf,MAAM;IACN,SAAS;GACX,CAAC;EACH;CACF,GACA;EAAC;EAAsB;EAAU;CAAQ,CAC3C;CAEA,gBAAgB;EACd,IAAI,CAAC,uBACH,SAAS,GAAG;CAEhB,GAAG,CAAC,uBAAuB,QAAQ,CAAC;CAEpC,OAAO,wBACL,oBAAC,gBAAD,EAAA,UACE,oBAAC,mBAAD,EAAA,UACE,qBAAC,cAAD;EAAc,UAAU,aAAa,QAAQ;EAA7C,UAAA;GACE,oBAAC,YAAD;IAAY,OAAM;IAAS,WAAU;IAAK,cAAc;IAAM,SAAQ;IACnE,UAAA,EAAE,+BAA+B;GACxB,CAAA;GACZ,oBAAC,mBAAD;IACE,OAAO,CAAC,CAAC,OAAO;IAChB,YAAY,OAAO,UAAU;IAC7B,OAAO,EAAE,kCAAkC;IAC3C,GAAI,SAAS,UAAU;IACvB,UAAU;GACX,CAAA;GACD,oBAAC,mBAAD;IACE,OAAO,CAAC,CAAC,OAAO;IAChB,YAAY,OAAO,aAAa;IAChC,OAAO,EAAE,qCAAqC;IAC9C,GAAI,SAAS,aAAa;IAC1B,UAAU;IACV,MAAK;GACN,CAAA;GACD,oBAAC,mBAAD;IACE,OAAO,CAAC,CAAC,OAAO;IAChB,YAAY,OAAO,aAAa;IAChC,OAAO,EAAE,qCAAqC;IAC9C,GAAI,SAAS,aAAa;IAC1B,UAAU;IACV,MAAK;GACN,CAAA;GACD,oBAAC,mBAAD;IACE,OAAO,CAAC,CAAC,OAAO;IAChB,YAAY,OAAO,iBAAiB;IACpC,OAAO,EAAE,yCAAyC;IAClD,GAAI,SAAS,iBAAiB;IAC9B,UAAU;IACV,MAAK;GACN,CAAA;GACA,OAAO,QAAQ,oBAAC,sBAAD,EAAsB,OAAO,OAAO,KAAO,CAAA;GAC3D,oBAAC,QAAD;IACE,OAAM;IACN,UAAU,CAAC;IACX,WAAW;IACX,IAAI,EAAE,IAAI,EAAE;IACZ,MAAK;IACL,SAAQ;IAEP,UAAA,EAAE,gCAAgC;GAC7B,CAAA;EACI;CACG,CAAA,EAAA,CAAA,EACL,CAAA,IACd;AACN"}
1
+ {"version":3,"file":"ChangePassword.mjs","names":[],"sources":["../../../src/sections/Security/ChangePassword.tsx"],"sourcesContent":["import { yupResolver } from '@hookform/resolvers/yup';\nimport { Button, Typography } from '@mui/material';\nimport React, { useCallback, useEffect, useRef } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { useNavigate } from 'react-router';\n\nimport { useDataMutation } from '../../api/use-data-mutation';\nimport LoginDialogFormError from '../../components/LoginDialog/LoginDialogFormError';\nimport { getConfiguration } from '../../configuration';\nimport SecurityLayout from '../../layouts/Security/Dialog';\nimport { authErrorMessage } from '../../providers/AuthProvider/utils';\nimport { stripTrailingSlash } from '../../store/utils';\nimport { Route } from '../../utils';\nimport { APIRoute } from '../../utils/routes';\nimport type { ChangePasswordFormValues } from '../../utils/schemas';\nimport {\n PASSWORD_MIN_LENGTH,\n USERNAME_MIN_LENGTH,\n changePasswordSchema,\n} from '../../utils/schemas';\nimport { MessageType } from './Success';\nimport { SecurityContainer, SecurityForm, SecurityTextField } from './styles';\n\nconst ChangePassword: React.FC = () => {\n const { t } = useTranslation();\n const navigate = useNavigate();\n const configuration = getConfiguration();\n const basePath = stripTrailingSlash(configuration.base);\n const changePasswordEnabled = configuration?.flags?.changePassword;\n\n const form = useForm<ChangePasswordFormValues>({\n mode: 'onChange',\n defaultValues: {\n username: '',\n oldPassword: '',\n newPassword: '',\n confirmPassword: '',\n },\n resolver: yupResolver(changePasswordSchema),\n });\n\n const {\n setError,\n handleSubmit,\n register,\n formState: { isValid, isSubmitting, errors },\n } = form;\n\n const { trigger } = useDataMutation<{ ok: string }>(basePath, APIRoute.RESET_PASSWORD, 'PUT');\n\n const handleChangePassword = useCallback(\n async (body: { password: { old: string; new: string } }) => {\n await trigger(body);\n },\n [trigger]\n );\n\n // `disabled={isSubmitting}` only applies after a re-render; clicks landing in\n // the same React batch would still fire duplicate requests\n const inFlight = useRef(false);\n\n const onSubmit = useCallback(\n async (data: ChangePasswordFormValues) => {\n if (inFlight.current) {\n return;\n }\n inFlight.current = true;\n try {\n await handleChangePassword({\n password: {\n old: data.oldPassword,\n new: data.newPassword,\n },\n });\n navigate(`${Route.SUCCESS}?messageType=${MessageType.ChangePassword}`);\n } catch (err) {\n setError('root', {\n type: 'server',\n message: authErrorMessage(err, t('security.error.unable-to-change-password')),\n });\n } finally {\n inFlight.current = false;\n }\n },\n [handleChangePassword, setError, navigate, t]\n );\n\n useEffect(() => {\n if (!changePasswordEnabled) {\n navigate('/');\n }\n }, [changePasswordEnabled, navigate]);\n\n return changePasswordEnabled ? (\n <SecurityLayout>\n <SecurityContainer>\n <SecurityForm onSubmit={handleSubmit(onSubmit)}>\n <Typography align=\"center\" component=\"h1\" gutterBottom={true} variant=\"h4\">\n {t('security.changePassword.title')}\n </Typography>\n <SecurityTextField\n error={!!errors.username}\n helperText={\n errors.username?.message\n ? t(errors.username.message, { length: USERNAME_MIN_LENGTH })\n : undefined\n }\n label={t('security.changePassword.username')}\n {...register('username')}\n required={true}\n />\n <SecurityTextField\n error={!!errors.oldPassword}\n helperText={\n errors.oldPassword?.message\n ? t(errors.oldPassword.message, { length: PASSWORD_MIN_LENGTH })\n : undefined\n }\n label={t('security.changePassword.oldPassword')}\n {...register('oldPassword')}\n required={true}\n type=\"password\"\n />\n <SecurityTextField\n error={!!errors.newPassword}\n helperText={\n errors.newPassword?.message\n ? t(errors.newPassword.message, { length: PASSWORD_MIN_LENGTH })\n : undefined\n }\n label={t('security.changePassword.newPassword')}\n {...register('newPassword')}\n required={true}\n type=\"password\"\n />\n <SecurityTextField\n error={!!errors.confirmPassword}\n helperText={\n errors.confirmPassword?.message ? t(errors.confirmPassword.message) : undefined\n }\n label={t('security.changePassword.confirmPassword')}\n {...register('confirmPassword')}\n required={true}\n type=\"password\"\n />\n {errors.root && <LoginDialogFormError error={errors.root} />}\n <Button\n color=\"primary\"\n disabled={!isValid || isSubmitting}\n fullWidth={true}\n sx={{ mt: 2 }}\n type=\"submit\"\n variant=\"contained\"\n >\n {t('security.changePassword.submit')}\n </Button>\n </SecurityForm>\n </SecurityContainer>\n </SecurityLayout>\n ) : null;\n};\n\nexport default ChangePassword;\n"],"mappings":"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"}
@@ -6,19 +6,20 @@ const require_configuration = require("../../configuration.js");
6
6
  const require_utils = require("../../store/utils.js");
7
7
  const require_use_data_mutation = require("../../api/use-data-mutation.js");
8
8
  const require_utils$1 = require("../../providers/AuthProvider/utils.js");
9
+ const require_AuthProvider = require("../../providers/AuthProvider/AuthProvider.js");
9
10
  const require_NotFound = require("../../components/NotFound/NotFound.js");
10
11
  require("../../components/NotFound/index.js");
11
12
  const require_styles = require("../../components/LoginForm/styles.js");
12
- const require_Login = require("../../components/LoginForm/Login.js");
13
13
  const require_schemas = require("../../utils/schemas.js");
14
+ const require_Login = require("../../components/LoginForm/Login.js");
14
15
  const require_Dialog = require("../../layouts/Security/Dialog.js");
15
16
  const require_styles$1 = require("./styles.js");
16
17
  const require_Success = require("./Success.js");
17
18
  const require_utils$2 = require("./utils.js");
18
19
  let react = require("react");
19
20
  react = require_runtime.__toESM(react);
20
- let react_jsx_runtime = require("react/jsx-runtime");
21
21
  let react_i18next = require("react-i18next");
22
+ let react_jsx_runtime = require("react/jsx-runtime");
22
23
  let react_router = require("react-router");
23
24
  let _mui_material = require("@mui/material");
24
25
  let _hookform_resolvers_yup = require("@hookform/resolvers/yup");
@@ -30,63 +31,78 @@ var Login = () => {
30
31
  const { t } = (0, react_i18next.useTranslation)();
31
32
  const location = (0, react_router.useLocation)();
32
33
  const navigate = (0, react_router.useNavigate)();
34
+ const { setUserState } = require_AuthProvider.useAuth();
33
35
  const { next } = require_utils$2.getSecurityUrlParams(location);
34
36
  const createUserEnabled = configuration?.flags?.createUser;
35
37
  const addUserLink = require_routes.Route.ADD_USER + (next ? "?next=" + next : "");
36
38
  const { trigger } = require_use_data_mutation.useDataMutation(basePath, next, "POST");
37
- const { setError, handleSubmit, register, formState: { isValid, errors } } = (0, react_hook_form.useForm)({
39
+ const { setError, handleSubmit, register, formState: { isValid, isSubmitting, errors } } = (0, react_hook_form.useForm)({
38
40
  mode: "onChange",
39
41
  resolver: (0, _hookform_resolvers_yup.yupResolver)(require_schemas.loginSchema)
40
42
  });
41
43
  const handleLogin = (0, react.useCallback)(async (body) => {
42
- try {
43
- return await trigger(body);
44
- } catch (err) {
45
- throw require_utils$1.normalizeAuthError(err);
46
- }
44
+ return await trigger(body);
47
45
  }, [trigger]);
48
46
  const onSuccess = (0, react.useCallback)(() => {
49
47
  navigate(`${require_routes.Route.SUCCESS}?messageType=${require_Success.MessageType.Login}`);
50
48
  }, [navigate]);
49
+ const inFlight = (0, react.useRef)(false);
51
50
  const onSubmit = (0, react.useCallback)(async (data) => {
51
+ if (inFlight.current) return;
52
+ inFlight.current = true;
52
53
  try {
53
54
  const result = await handleLogin?.(data);
54
- if (result && result.username && result.token) require_storage.saveAuth(result.username, result.token);
55
+ if (!result || !result.username || !result.token) throw new Error("login response is missing the token");
56
+ require_storage.saveAuth(result.username, result.token);
57
+ setUserState?.({
58
+ username: result.username,
59
+ token: result.token
60
+ });
55
61
  onSuccess();
56
- } catch {
62
+ } catch (err) {
63
+ const message = err?.code === 401 ? t("security.error.invalid-credentials") : require_utils$1.authErrorMessage(err, t("security.error.unable-to-login"));
57
64
  setError("root", {
58
65
  type: "server",
59
- message: "Invalid username or password"
66
+ message
60
67
  });
68
+ } finally {
69
+ inFlight.current = false;
61
70
  }
62
71
  }, [
63
72
  handleLogin,
64
73
  setError,
65
- onSuccess
74
+ setUserState,
75
+ onSuccess,
76
+ t
66
77
  ]);
67
- return !next ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_NotFound.default, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Dialog.default, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_styles$1.SecurityContainer, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_styles$1.SecurityForm, { children: [
68
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_styles.default, {}),
69
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Login.default, {
70
- errors,
71
- handleSubmit,
72
- isValid,
73
- onSubmit,
74
- register
75
- }),
76
- createUserEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material.Typography, {
77
- align: "center",
78
- sx: {
79
- mt: 2,
80
- fontSize: 12
81
- },
82
- variant: "body2",
83
- children: [t("security.login.noUserQuestion"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material.Link, {
84
- href: addUserLink,
85
- sx: { ml: 1 },
86
- children: t("security.login.createUser")
87
- })]
88
- })
89
- ] }) }) });
78
+ return !next ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_NotFound.default, {}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Dialog.default, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_styles$1.SecurityContainer, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_styles$1.SecurityForm, {
79
+ as: "div",
80
+ children: [
81
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_styles.default, {}),
82
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Login.default, {
83
+ errors,
84
+ handleSubmit,
85
+ isSubmitting,
86
+ isValid,
87
+ onSubmit,
88
+ register
89
+ }),
90
+ createUserEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_mui_material.Typography, {
91
+ align: "center",
92
+ sx: {
93
+ mt: 2,
94
+ fontSize: 12
95
+ },
96
+ variant: "body2",
97
+ children: [t("security.login.noUserQuestion"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material.Link, {
98
+ component: react_router.Link,
99
+ sx: { ml: 1 },
100
+ to: addUserLink,
101
+ children: t("security.login.createUser")
102
+ })]
103
+ })
104
+ ]
105
+ }) }) });
90
106
  };
91
107
  //#endregion
92
108
  exports.default = Login;
@@ -1 +1 @@
1
- {"version":3,"file":"Login.js","names":[],"sources":["../../../src/sections/Security/Login.tsx"],"sourcesContent":["import { yupResolver } from '@hookform/resolvers/yup';\nimport { Link, Typography } from '@mui/material';\nimport React, { useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { useLocation, useNavigate } from 'react-router';\n\nimport { useDataMutation } from '../../api/use-data-mutation';\nimport type { LoginFormValues } from '../../components/LoginForm/Login';\nimport LoginForm from '../../components/LoginForm/Login';\nimport LoginFormHeader from '../../components/LoginForm/styles';\nimport NotFound from '../../components/NotFound';\nimport { getConfiguration } from '../../configuration';\nimport SecurityLayout from '../../layouts/Security/Dialog';\nimport type { LoginBody } from '../../providers/AuthProvider/types';\nimport { normalizeAuthError } from '../../providers/AuthProvider/utils';\nimport { saveAuth } from '../../store/storage';\nimport { stripTrailingSlash } from '../../store/utils';\nimport { Route } from '../../utils';\nimport { loginSchema } from '../../utils/schemas';\nimport { MessageType } from './Success';\nimport { SecurityContainer, SecurityForm } from './styles';\nimport { getSecurityUrlParams } from './utils';\n\nconst configuration = getConfiguration();\nconst basePath = stripTrailingSlash(configuration.base);\n\nconst Login: React.FC = () => {\n const { t } = useTranslation();\n const location = useLocation();\n const navigate = useNavigate();\n const { next } = getSecurityUrlParams(location);\n const createUserEnabled = configuration?.flags?.createUser;\n const addUserLink = Route.ADD_USER + (next ? '?next=' + next : '');\n\n const { trigger } = useDataMutation<LoginBody>(basePath, next, 'POST');\n\n const form = useForm<LoginFormValues>({\n mode: 'onChange',\n resolver: yupResolver(loginSchema),\n });\n\n const {\n setError,\n handleSubmit,\n register,\n formState: { isValid, errors },\n } = form;\n\n const handleLogin = useCallback(\n async (body: { username: string; password: string }) => {\n try {\n return await trigger(body);\n } catch (err) {\n throw normalizeAuthError(err);\n }\n },\n [trigger]\n );\n\n const onSuccess = useCallback(() => {\n navigate(`${Route.SUCCESS}?messageType=${MessageType.Login}`);\n }, [navigate]);\n\n const onSubmit = useCallback(\n async (data: LoginFormValues) => {\n try {\n const result = await handleLogin?.(data);\n if (result && result.username && result.token) {\n saveAuth(result.username, result.token);\n }\n onSuccess();\n } catch {\n setError('root', {\n type: 'server',\n // TODO: add translation key\n message: 'Invalid username or password',\n });\n }\n },\n [handleLogin, setError, onSuccess]\n );\n\n return !next ? (\n <NotFound />\n ) : (\n <SecurityLayout>\n <SecurityContainer>\n <SecurityForm>\n <LoginFormHeader />\n <LoginForm\n errors={errors}\n handleSubmit={handleSubmit}\n isValid={isValid}\n onSubmit={onSubmit}\n register={register}\n />\n {createUserEnabled && (\n <Typography align=\"center\" sx={{ mt: 2, fontSize: 12 }} variant=\"body2\">\n {t('security.login.noUserQuestion')}\n <Link href={addUserLink} sx={{ ml: 1 }}>\n {t('security.login.createUser')}\n </Link>\n </Typography>\n )}\n </SecurityForm>\n </SecurityContainer>\n </SecurityLayout>\n );\n};\n\nexport default Login;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,IAAM,gBAAgB,sBAAA,iBAAiB;AACvC,IAAM,WAAW,cAAA,mBAAmB,cAAc,IAAI;AAEtD,IAAM,cAAwB;CAC5B,MAAM,EAAE,OAAA,GAAM,cAAA,eAAA,CAAe;CAC7B,MAAM,YAAA,GAAW,aAAA,YAAA,CAAY;CAC7B,MAAM,YAAA,GAAW,aAAA,YAAA,CAAY;CAC7B,MAAM,EAAE,SAAS,gBAAA,qBAAqB,QAAQ;CAC9C,MAAM,oBAAoB,eAAe,OAAO;CAChD,MAAM,cAAc,eAAA,MAAM,YAAY,OAAO,WAAW,OAAO;CAE/D,MAAM,EAAE,YAAY,0BAAA,gBAA2B,UAAU,MAAM,MAAM;CAOrE,MAAM,EACJ,UACA,cACA,UACA,WAAW,EAAE,SAAS,cAAA,GATX,gBAAA,QAAA,CAAyB;EACpC,MAAM;EACN,WAAA,GAAU,wBAAA,YAAA,CAAY,gBAAA,WAAW;CACnC,CAOI;CAEJ,MAAM,eAAA,GAAc,MAAA,YAAA,CAClB,OAAO,SAAiD;EACtD,IAAI;GACF,OAAO,MAAM,QAAQ,IAAI;EAC3B,SAAS,KAAK;GACZ,MAAM,gBAAA,mBAAmB,GAAG;EAC9B;CACF,GACA,CAAC,OAAO,CACV;CAEA,MAAM,aAAA,GAAY,MAAA,YAAA,OAAkB;EAClC,SAAS,GAAG,eAAA,MAAM,QAAQ,eAAe,gBAAA,YAAY,OAAO;CAC9D,GAAG,CAAC,QAAQ,CAAC;CAEb,MAAM,YAAA,GAAW,MAAA,YAAA,CACf,OAAO,SAA0B;EAC/B,IAAI;GACF,MAAM,SAAS,MAAM,cAAc,IAAI;GACvC,IAAI,UAAU,OAAO,YAAY,OAAO,OACtC,gBAAA,SAAS,OAAO,UAAU,OAAO,KAAK;GAExC,UAAU;EACZ,QAAQ;GACN,SAAS,QAAQ;IACf,MAAM;IAEN,SAAS;GACX,CAAC;EACH;CACF,GACA;EAAC;EAAa;EAAU;CAAS,CACnC;CAEA,OAAO,CAAC,OACN,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAA,SAAD,CAAW,CAAA,IAEX,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAA,SAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAA,mBAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,iBAAA,cAAD,EAAA,UAAA;EACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAA,SAAD,CAAkB,CAAA;EAClB,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAA,SAAD;GACU;GACM;GACL;GACC;GACA;EACX,CAAA;EACA,qBACC,iBAAA,GAAA,kBAAA,KAAA,CAAC,cAAA,YAAD;GAAY,OAAM;GAAS,IAAI;IAAE,IAAI;IAAG,UAAU;GAAG;GAAG,SAAQ;GAAhE,UAAA,CACG,EAAE,+BAA+B,GAClC,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAA,MAAD;IAAM,MAAM;IAAa,IAAI,EAAE,IAAI,EAAE;IAClC,UAAA,EAAE,2BAA2B;GAC1B,CAAA,CACI;;CAEF,EAAA,CAAA,EACG,CAAA,EACL,CAAA;AAEpB"}
1
+ {"version":3,"file":"Login.js","names":[],"sources":["../../../src/sections/Security/Login.tsx"],"sourcesContent":["import { yupResolver } from '@hookform/resolvers/yup';\nimport { Link, Typography } from '@mui/material';\nimport React, { useCallback, useRef } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { Link as RouterLink, useLocation, useNavigate } from 'react-router';\n\nimport { useDataMutation } from '../../api/use-data-mutation';\nimport type { LoginFormValues } from '../../components/LoginForm/Login';\nimport LoginForm from '../../components/LoginForm/Login';\nimport LoginFormHeader from '../../components/LoginForm/styles';\nimport NotFound from '../../components/NotFound';\nimport { getConfiguration } from '../../configuration';\nimport SecurityLayout from '../../layouts/Security/Dialog';\nimport { useAuth } from '../../providers/AuthProvider/AuthProvider';\nimport type { LoginBody } from '../../providers/AuthProvider/types';\nimport { authErrorMessage } from '../../providers/AuthProvider/utils';\nimport { saveAuth } from '../../store/storage';\nimport { stripTrailingSlash } from '../../store/utils';\nimport { Route } from '../../utils';\nimport { loginSchema } from '../../utils/schemas';\nimport { MessageType } from './Success';\nimport { SecurityContainer, SecurityForm } from './styles';\nimport { getSecurityUrlParams } from './utils';\n\nconst configuration = getConfiguration();\nconst basePath = stripTrailingSlash(configuration.base);\n\nconst Login: React.FC = () => {\n const { t } = useTranslation();\n const location = useLocation();\n const navigate = useNavigate();\n const { setUserState } = useAuth();\n const { next } = getSecurityUrlParams(location);\n const createUserEnabled = configuration?.flags?.createUser;\n const addUserLink = Route.ADD_USER + (next ? '?next=' + next : '');\n\n const { trigger } = useDataMutation<LoginBody>(basePath, next, 'POST');\n\n const form = useForm<LoginFormValues>({\n mode: 'onChange',\n resolver: yupResolver(loginSchema),\n });\n\n const {\n setError,\n handleSubmit,\n register,\n formState: { isValid, isSubmitting, errors },\n } = form;\n\n const handleLogin = useCallback(\n async (body: { username: string; password: string }) => {\n return await trigger(body);\n },\n [trigger]\n );\n\n const onSuccess = useCallback(() => {\n navigate(`${Route.SUCCESS}?messageType=${MessageType.Login}`);\n }, [navigate]);\n\n // `disabled={isSubmitting}` only applies after a re-render; clicks landing in\n // the same React batch would still fire duplicate requests\n const inFlight = useRef(false);\n\n const onSubmit = useCallback(\n async (data: LoginFormValues) => {\n if (inFlight.current) {\n return;\n }\n inFlight.current = true;\n try {\n const result = await handleLogin?.(data);\n if (!result || !result.username || !result.token) {\n // a 2xx with an unexpected body must not pass as a successful login\n throw new Error('login response is missing the token');\n }\n saveAuth(result.username, result.token);\n // AuthProvider reads storage only once, so the header needs the state update\n setUserState?.({ username: result.username, token: result.token });\n onSuccess();\n } catch (err: any) {\n // only a 401 means wrong credentials; a dead server, 500 or 429 must\n // not claim the credentials were invalid\n const message =\n err?.code === 401\n ? t('security.error.invalid-credentials')\n : authErrorMessage(err, t('security.error.unable-to-login'));\n setError('root', { type: 'server', message });\n } finally {\n inFlight.current = false;\n }\n },\n [handleLogin, setError, setUserState, onSuccess, t]\n );\n\n return !next ? (\n <NotFound />\n ) : (\n <SecurityLayout>\n <SecurityContainer>\n {/* container only: LoginForm renders the real <form>, and a <form>\n cannot be a descendant of another <form> */}\n <SecurityForm as=\"div\">\n <LoginFormHeader />\n <LoginForm\n errors={errors}\n handleSubmit={handleSubmit}\n isSubmitting={isSubmitting}\n isValid={isValid}\n onSubmit={onSubmit}\n register={register}\n />\n {createUserEnabled && (\n <Typography align=\"center\" sx={{ mt: 2, fontSize: 12 }} variant=\"body2\">\n {t('security.login.noUserQuestion')}\n <Link component={RouterLink} sx={{ ml: 1 }} to={addUserLink}>\n {t('security.login.createUser')}\n </Link>\n </Typography>\n )}\n </SecurityForm>\n </SecurityContainer>\n </SecurityLayout>\n );\n};\n\nexport default Login;\n"],"mappings":"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"}
@@ -4,20 +4,21 @@ import { saveAuth } from "../../store/storage.mjs";
4
4
  import { getConfiguration } from "../../configuration.mjs";
5
5
  import { stripTrailingSlash } from "../../store/utils.mjs";
6
6
  import { useDataMutation } from "../../api/use-data-mutation.mjs";
7
- import { normalizeAuthError } from "../../providers/AuthProvider/utils.mjs";
7
+ import { authErrorMessage } from "../../providers/AuthProvider/utils.mjs";
8
+ import { useAuth } from "../../providers/AuthProvider/AuthProvider.mjs";
8
9
  import NotFound from "../../components/NotFound/NotFound.mjs";
9
10
  import "../../components/NotFound/index.mjs";
10
11
  import LoginFormHeader from "../../components/LoginForm/styles.mjs";
11
- import LoginForm from "../../components/LoginForm/Login.mjs";
12
12
  import { loginSchema } from "../../utils/schemas.mjs";
13
+ import LoginForm from "../../components/LoginForm/Login.mjs";
13
14
  import SecurityLayout from "../../layouts/Security/Dialog.mjs";
14
15
  import { SecurityContainer, SecurityForm } from "./styles.mjs";
15
16
  import { MessageType } from "./Success.mjs";
16
17
  import { getSecurityUrlParams } from "./utils.mjs";
17
- import { useCallback } from "react";
18
- import { jsx, jsxs } from "react/jsx-runtime";
18
+ import { useCallback, useRef } from "react";
19
19
  import { useTranslation } from "react-i18next";
20
- import { useLocation, useNavigate } from "react-router";
20
+ import { jsx, jsxs } from "react/jsx-runtime";
21
+ import { Link, useLocation, useNavigate } from "react-router";
21
22
  import { Link as Link$1, Typography } from "@mui/material";
22
23
  import { yupResolver } from "@hookform/resolvers/yup";
23
24
  import { useForm } from "react-hook-form";
@@ -28,63 +29,78 @@ var Login = () => {
28
29
  const { t } = useTranslation();
29
30
  const location = useLocation();
30
31
  const navigate = useNavigate();
32
+ const { setUserState } = useAuth();
31
33
  const { next } = getSecurityUrlParams(location);
32
34
  const createUserEnabled = configuration?.flags?.createUser;
33
35
  const addUserLink = Route$1.ADD_USER + (next ? "?next=" + next : "");
34
36
  const { trigger } = useDataMutation(basePath, next, "POST");
35
- const { setError, handleSubmit, register, formState: { isValid, errors } } = useForm({
37
+ const { setError, handleSubmit, register, formState: { isValid, isSubmitting, errors } } = useForm({
36
38
  mode: "onChange",
37
39
  resolver: yupResolver(loginSchema)
38
40
  });
39
41
  const handleLogin = useCallback(async (body) => {
40
- try {
41
- return await trigger(body);
42
- } catch (err) {
43
- throw normalizeAuthError(err);
44
- }
42
+ return await trigger(body);
45
43
  }, [trigger]);
46
44
  const onSuccess = useCallback(() => {
47
45
  navigate(`${Route$1.SUCCESS}?messageType=${MessageType.Login}`);
48
46
  }, [navigate]);
47
+ const inFlight = useRef(false);
49
48
  const onSubmit = useCallback(async (data) => {
49
+ if (inFlight.current) return;
50
+ inFlight.current = true;
50
51
  try {
51
52
  const result = await handleLogin?.(data);
52
- if (result && result.username && result.token) saveAuth(result.username, result.token);
53
+ if (!result || !result.username || !result.token) throw new Error("login response is missing the token");
54
+ saveAuth(result.username, result.token);
55
+ setUserState?.({
56
+ username: result.username,
57
+ token: result.token
58
+ });
53
59
  onSuccess();
54
- } catch {
60
+ } catch (err) {
61
+ const message = err?.code === 401 ? t("security.error.invalid-credentials") : authErrorMessage(err, t("security.error.unable-to-login"));
55
62
  setError("root", {
56
63
  type: "server",
57
- message: "Invalid username or password"
64
+ message
58
65
  });
66
+ } finally {
67
+ inFlight.current = false;
59
68
  }
60
69
  }, [
61
70
  handleLogin,
62
71
  setError,
63
- onSuccess
72
+ setUserState,
73
+ onSuccess,
74
+ t
64
75
  ]);
65
- return !next ? /* @__PURE__ */ jsx(NotFound, {}) : /* @__PURE__ */ jsx(SecurityLayout, { children: /* @__PURE__ */ jsx(SecurityContainer, { children: /* @__PURE__ */ jsxs(SecurityForm, { children: [
66
- /* @__PURE__ */ jsx(LoginFormHeader, {}),
67
- /* @__PURE__ */ jsx(LoginForm, {
68
- errors,
69
- handleSubmit,
70
- isValid,
71
- onSubmit,
72
- register
73
- }),
74
- createUserEnabled && /* @__PURE__ */ jsxs(Typography, {
75
- align: "center",
76
- sx: {
77
- mt: 2,
78
- fontSize: 12
79
- },
80
- variant: "body2",
81
- children: [t("security.login.noUserQuestion"), /* @__PURE__ */ jsx(Link$1, {
82
- href: addUserLink,
83
- sx: { ml: 1 },
84
- children: t("security.login.createUser")
85
- })]
86
- })
87
- ] }) }) });
76
+ return !next ? /* @__PURE__ */ jsx(NotFound, {}) : /* @__PURE__ */ jsx(SecurityLayout, { children: /* @__PURE__ */ jsx(SecurityContainer, { children: /* @__PURE__ */ jsxs(SecurityForm, {
77
+ as: "div",
78
+ children: [
79
+ /* @__PURE__ */ jsx(LoginFormHeader, {}),
80
+ /* @__PURE__ */ jsx(LoginForm, {
81
+ errors,
82
+ handleSubmit,
83
+ isSubmitting,
84
+ isValid,
85
+ onSubmit,
86
+ register
87
+ }),
88
+ createUserEnabled && /* @__PURE__ */ jsxs(Typography, {
89
+ align: "center",
90
+ sx: {
91
+ mt: 2,
92
+ fontSize: 12
93
+ },
94
+ variant: "body2",
95
+ children: [t("security.login.noUserQuestion"), /* @__PURE__ */ jsx(Link$1, {
96
+ component: Link,
97
+ sx: { ml: 1 },
98
+ to: addUserLink,
99
+ children: t("security.login.createUser")
100
+ })]
101
+ })
102
+ ]
103
+ }) }) });
88
104
  };
89
105
  //#endregion
90
106
  export { Login as default };
@@ -1 +1 @@
1
- {"version":3,"file":"Login.mjs","names":[],"sources":["../../../src/sections/Security/Login.tsx"],"sourcesContent":["import { yupResolver } from '@hookform/resolvers/yup';\nimport { Link, Typography } from '@mui/material';\nimport React, { useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { useLocation, useNavigate } from 'react-router';\n\nimport { useDataMutation } from '../../api/use-data-mutation';\nimport type { LoginFormValues } from '../../components/LoginForm/Login';\nimport LoginForm from '../../components/LoginForm/Login';\nimport LoginFormHeader from '../../components/LoginForm/styles';\nimport NotFound from '../../components/NotFound';\nimport { getConfiguration } from '../../configuration';\nimport SecurityLayout from '../../layouts/Security/Dialog';\nimport type { LoginBody } from '../../providers/AuthProvider/types';\nimport { normalizeAuthError } from '../../providers/AuthProvider/utils';\nimport { saveAuth } from '../../store/storage';\nimport { stripTrailingSlash } from '../../store/utils';\nimport { Route } from '../../utils';\nimport { loginSchema } from '../../utils/schemas';\nimport { MessageType } from './Success';\nimport { SecurityContainer, SecurityForm } from './styles';\nimport { getSecurityUrlParams } from './utils';\n\nconst configuration = getConfiguration();\nconst basePath = stripTrailingSlash(configuration.base);\n\nconst Login: React.FC = () => {\n const { t } = useTranslation();\n const location = useLocation();\n const navigate = useNavigate();\n const { next } = getSecurityUrlParams(location);\n const createUserEnabled = configuration?.flags?.createUser;\n const addUserLink = Route.ADD_USER + (next ? '?next=' + next : '');\n\n const { trigger } = useDataMutation<LoginBody>(basePath, next, 'POST');\n\n const form = useForm<LoginFormValues>({\n mode: 'onChange',\n resolver: yupResolver(loginSchema),\n });\n\n const {\n setError,\n handleSubmit,\n register,\n formState: { isValid, errors },\n } = form;\n\n const handleLogin = useCallback(\n async (body: { username: string; password: string }) => {\n try {\n return await trigger(body);\n } catch (err) {\n throw normalizeAuthError(err);\n }\n },\n [trigger]\n );\n\n const onSuccess = useCallback(() => {\n navigate(`${Route.SUCCESS}?messageType=${MessageType.Login}`);\n }, [navigate]);\n\n const onSubmit = useCallback(\n async (data: LoginFormValues) => {\n try {\n const result = await handleLogin?.(data);\n if (result && result.username && result.token) {\n saveAuth(result.username, result.token);\n }\n onSuccess();\n } catch {\n setError('root', {\n type: 'server',\n // TODO: add translation key\n message: 'Invalid username or password',\n });\n }\n },\n [handleLogin, setError, onSuccess]\n );\n\n return !next ? (\n <NotFound />\n ) : (\n <SecurityLayout>\n <SecurityContainer>\n <SecurityForm>\n <LoginFormHeader />\n <LoginForm\n errors={errors}\n handleSubmit={handleSubmit}\n isValid={isValid}\n onSubmit={onSubmit}\n register={register}\n />\n {createUserEnabled && (\n <Typography align=\"center\" sx={{ mt: 2, fontSize: 12 }} variant=\"body2\">\n {t('security.login.noUserQuestion')}\n <Link href={addUserLink} sx={{ ml: 1 }}>\n {t('security.login.createUser')}\n </Link>\n </Typography>\n )}\n </SecurityForm>\n </SecurityContainer>\n </SecurityLayout>\n );\n};\n\nexport default Login;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAwBA,IAAM,gBAAgB,iBAAiB;AACvC,IAAM,WAAW,mBAAmB,cAAc,IAAI;AAEtD,IAAM,cAAwB;CAC5B,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,EAAE,SAAS,qBAAqB,QAAQ;CAC9C,MAAM,oBAAoB,eAAe,OAAO;CAChD,MAAM,cAAc,QAAM,YAAY,OAAO,WAAW,OAAO;CAE/D,MAAM,EAAE,YAAY,gBAA2B,UAAU,MAAM,MAAM;CAOrE,MAAM,EACJ,UACA,cACA,UACA,WAAW,EAAE,SAAS,aATX,QAAyB;EACpC,MAAM;EACN,UAAU,YAAY,WAAW;CACnC,CAOI;CAEJ,MAAM,cAAc,YAClB,OAAO,SAAiD;EACtD,IAAI;GACF,OAAO,MAAM,QAAQ,IAAI;EAC3B,SAAS,KAAK;GACZ,MAAM,mBAAmB,GAAG;EAC9B;CACF,GACA,CAAC,OAAO,CACV;CAEA,MAAM,YAAY,kBAAkB;EAClC,SAAS,GAAG,QAAM,QAAQ,eAAe,YAAY,OAAO;CAC9D,GAAG,CAAC,QAAQ,CAAC;CAEb,MAAM,WAAW,YACf,OAAO,SAA0B;EAC/B,IAAI;GACF,MAAM,SAAS,MAAM,cAAc,IAAI;GACvC,IAAI,UAAU,OAAO,YAAY,OAAO,OACtC,SAAS,OAAO,UAAU,OAAO,KAAK;GAExC,UAAU;EACZ,QAAQ;GACN,SAAS,QAAQ;IACf,MAAM;IAEN,SAAS;GACX,CAAC;EACH;CACF,GACA;EAAC;EAAa;EAAU;CAAS,CACnC;CAEA,OAAO,CAAC,OACN,oBAAC,UAAD,CAAW,CAAA,IAEX,oBAAC,gBAAD,EAAA,UACE,oBAAC,mBAAD,EAAA,UACE,qBAAC,cAAD,EAAA,UAAA;EACE,oBAAC,iBAAD,CAAkB,CAAA;EAClB,oBAAC,WAAD;GACU;GACM;GACL;GACC;GACA;EACX,CAAA;EACA,qBACC,qBAAC,YAAD;GAAY,OAAM;GAAS,IAAI;IAAE,IAAI;IAAG,UAAU;GAAG;GAAG,SAAQ;GAAhE,UAAA,CACG,EAAE,+BAA+B,GAClC,oBAAC,QAAD;IAAM,MAAM;IAAa,IAAI,EAAE,IAAI,EAAE;IAClC,UAAA,EAAE,2BAA2B;GAC1B,CAAA,CACI;;CAEF,EAAA,CAAA,EACG,CAAA,EACL,CAAA;AAEpB"}
1
+ {"version":3,"file":"Login.mjs","names":[],"sources":["../../../src/sections/Security/Login.tsx"],"sourcesContent":["import { yupResolver } from '@hookform/resolvers/yup';\nimport { Link, Typography } from '@mui/material';\nimport React, { useCallback, useRef } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport { Link as RouterLink, useLocation, useNavigate } from 'react-router';\n\nimport { useDataMutation } from '../../api/use-data-mutation';\nimport type { LoginFormValues } from '../../components/LoginForm/Login';\nimport LoginForm from '../../components/LoginForm/Login';\nimport LoginFormHeader from '../../components/LoginForm/styles';\nimport NotFound from '../../components/NotFound';\nimport { getConfiguration } from '../../configuration';\nimport SecurityLayout from '../../layouts/Security/Dialog';\nimport { useAuth } from '../../providers/AuthProvider/AuthProvider';\nimport type { LoginBody } from '../../providers/AuthProvider/types';\nimport { authErrorMessage } from '../../providers/AuthProvider/utils';\nimport { saveAuth } from '../../store/storage';\nimport { stripTrailingSlash } from '../../store/utils';\nimport { Route } from '../../utils';\nimport { loginSchema } from '../../utils/schemas';\nimport { MessageType } from './Success';\nimport { SecurityContainer, SecurityForm } from './styles';\nimport { getSecurityUrlParams } from './utils';\n\nconst configuration = getConfiguration();\nconst basePath = stripTrailingSlash(configuration.base);\n\nconst Login: React.FC = () => {\n const { t } = useTranslation();\n const location = useLocation();\n const navigate = useNavigate();\n const { setUserState } = useAuth();\n const { next } = getSecurityUrlParams(location);\n const createUserEnabled = configuration?.flags?.createUser;\n const addUserLink = Route.ADD_USER + (next ? '?next=' + next : '');\n\n const { trigger } = useDataMutation<LoginBody>(basePath, next, 'POST');\n\n const form = useForm<LoginFormValues>({\n mode: 'onChange',\n resolver: yupResolver(loginSchema),\n });\n\n const {\n setError,\n handleSubmit,\n register,\n formState: { isValid, isSubmitting, errors },\n } = form;\n\n const handleLogin = useCallback(\n async (body: { username: string; password: string }) => {\n return await trigger(body);\n },\n [trigger]\n );\n\n const onSuccess = useCallback(() => {\n navigate(`${Route.SUCCESS}?messageType=${MessageType.Login}`);\n }, [navigate]);\n\n // `disabled={isSubmitting}` only applies after a re-render; clicks landing in\n // the same React batch would still fire duplicate requests\n const inFlight = useRef(false);\n\n const onSubmit = useCallback(\n async (data: LoginFormValues) => {\n if (inFlight.current) {\n return;\n }\n inFlight.current = true;\n try {\n const result = await handleLogin?.(data);\n if (!result || !result.username || !result.token) {\n // a 2xx with an unexpected body must not pass as a successful login\n throw new Error('login response is missing the token');\n }\n saveAuth(result.username, result.token);\n // AuthProvider reads storage only once, so the header needs the state update\n setUserState?.({ username: result.username, token: result.token });\n onSuccess();\n } catch (err: any) {\n // only a 401 means wrong credentials; a dead server, 500 or 429 must\n // not claim the credentials were invalid\n const message =\n err?.code === 401\n ? t('security.error.invalid-credentials')\n : authErrorMessage(err, t('security.error.unable-to-login'));\n setError('root', { type: 'server', message });\n } finally {\n inFlight.current = false;\n }\n },\n [handleLogin, setError, setUserState, onSuccess, t]\n );\n\n return !next ? (\n <NotFound />\n ) : (\n <SecurityLayout>\n <SecurityContainer>\n {/* container only: LoginForm renders the real <form>, and a <form>\n cannot be a descendant of another <form> */}\n <SecurityForm as=\"div\">\n <LoginFormHeader />\n <LoginForm\n errors={errors}\n handleSubmit={handleSubmit}\n isSubmitting={isSubmitting}\n isValid={isValid}\n onSubmit={onSubmit}\n register={register}\n />\n {createUserEnabled && (\n <Typography align=\"center\" sx={{ mt: 2, fontSize: 12 }} variant=\"body2\">\n {t('security.login.noUserQuestion')}\n <Link component={RouterLink} sx={{ ml: 1 }} to={addUserLink}>\n {t('security.login.createUser')}\n </Link>\n </Typography>\n )}\n </SecurityForm>\n </SecurityContainer>\n </SecurityLayout>\n );\n};\n\nexport default Login;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,IAAM,gBAAgB,iBAAiB;AACvC,IAAM,WAAW,mBAAmB,cAAc,IAAI;AAEtD,IAAM,cAAwB;CAC5B,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,EAAE,iBAAiB,QAAQ;CACjC,MAAM,EAAE,SAAS,qBAAqB,QAAQ;CAC9C,MAAM,oBAAoB,eAAe,OAAO;CAChD,MAAM,cAAc,QAAM,YAAY,OAAO,WAAW,OAAO;CAE/D,MAAM,EAAE,YAAY,gBAA2B,UAAU,MAAM,MAAM;CAOrE,MAAM,EACJ,UACA,cACA,UACA,WAAW,EAAE,SAAS,cAAc,aATzB,QAAyB;EACpC,MAAM;EACN,UAAU,YAAY,WAAW;CACnC,CAOI;CAEJ,MAAM,cAAc,YAClB,OAAO,SAAiD;EACtD,OAAO,MAAM,QAAQ,IAAI;CAC3B,GACA,CAAC,OAAO,CACV;CAEA,MAAM,YAAY,kBAAkB;EAClC,SAAS,GAAG,QAAM,QAAQ,eAAe,YAAY,OAAO;CAC9D,GAAG,CAAC,QAAQ,CAAC;CAIb,MAAM,WAAW,OAAO,KAAK;CAE7B,MAAM,WAAW,YACf,OAAO,SAA0B;EAC/B,IAAI,SAAS,SACX;EAEF,SAAS,UAAU;EACnB,IAAI;GACF,MAAM,SAAS,MAAM,cAAc,IAAI;GACvC,IAAI,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,OAAO,OAEzC,MAAM,IAAI,MAAM,qCAAqC;GAEvD,SAAS,OAAO,UAAU,OAAO,KAAK;GAEtC,eAAe;IAAE,UAAU,OAAO;IAAU,OAAO,OAAO;GAAM,CAAC;GACjE,UAAU;EACZ,SAAS,KAAU;GAGjB,MAAM,UACJ,KAAK,SAAS,MACV,EAAE,oCAAoC,IACtC,iBAAiB,KAAK,EAAE,gCAAgC,CAAC;GAC/D,SAAS,QAAQ;IAAE,MAAM;IAAU;GAAQ,CAAC;EAC9C,UAAU;GACR,SAAS,UAAU;EACrB;CACF,GACA;EAAC;EAAa;EAAU;EAAc;EAAW;CAAC,CACpD;CAEA,OAAO,CAAC,OACN,oBAAC,UAAD,CAAW,CAAA,IAEX,oBAAC,gBAAD,EAAA,UACE,oBAAC,mBAAD,EAAA,UAGE,qBAAC,cAAD;EAAc,IAAG;EAAjB,UAAA;GACE,oBAAC,iBAAD,CAAkB,CAAA;GAClB,oBAAC,WAAD;IACU;IACM;IACA;IACL;IACC;IACA;GACX,CAAA;GACA,qBACC,qBAAC,YAAD;IAAY,OAAM;IAAS,IAAI;KAAE,IAAI;KAAG,UAAU;IAAG;IAAG,SAAQ;IAAhE,UAAA,CACG,EAAE,+BAA+B,GAClC,oBAAC,QAAD;KAAM,WAAW;KAAY,IAAI,EAAE,IAAI,EAAE;KAAG,IAAI;KAC7C,UAAA,EAAE,2BAA2B;IAC1B,CAAA,CACI;;EAEF;CACG,CAAA,EAAA,CAAA,EACL,CAAA;AAEpB"}
@@ -3,8 +3,8 @@ const require_Dialog = require("../../layouts/Security/Dialog.js");
3
3
  const require_styles = require("./styles.js");
4
4
  let react = require("react");
5
5
  react = require_runtime.__toESM(react);
6
- let react_jsx_runtime = require("react/jsx-runtime");
7
6
  let react_i18next = require("react-i18next");
7
+ let react_jsx_runtime = require("react/jsx-runtime");
8
8
  let react_router = require("react-router");
9
9
  let _mui_material = require("@mui/material");
10
10
  let _mui_icons_material_CheckCircle = require("@mui/icons-material/CheckCircle");
@@ -20,33 +20,37 @@ var MessageType = /* @__PURE__ */ function(MessageType) {
20
20
  var Success = () => {
21
21
  const { t } = (0, react_i18next.useTranslation)();
22
22
  const location = (0, react_router.useLocation)();
23
+ const navigate = (0, react_router.useNavigate)();
23
24
  const messageType = new URLSearchParams(location.search).get("messageType");
24
25
  const message = !messageType ? t("security.success.messageSuccess") : t(`security.success.message${messageType}`);
25
26
  const handleClose = () => {
26
- window.location.href = "/";
27
+ navigate("/");
27
28
  };
28
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Dialog.default, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_styles.SecurityContainer, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_styles.SecurityForm, { children: [
29
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_icons_material_CheckCircle.default, { color: "success" }),
30
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material.Typography, {
31
- component: "h1",
32
- gutterBottom: true,
33
- variant: "h4",
34
- children: t("security.success.title")
35
- }),
36
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material.Typography, {
37
- color: "text.secondary",
38
- paragraph: true,
39
- variant: "body1",
40
- children: message
41
- }),
42
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material.Button, {
43
- color: "primary",
44
- onClick: handleClose,
45
- sx: { mt: 2 },
46
- variant: "contained",
47
- children: t("security.success.submit")
48
- })
49
- ] }) }) });
29
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Dialog.default, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_styles.SecurityContainer, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_styles.SecurityForm, {
30
+ as: "div",
31
+ children: [
32
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_icons_material_CheckCircle.default, { color: "success" }),
33
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material.Typography, {
34
+ component: "h1",
35
+ gutterBottom: true,
36
+ variant: "h4",
37
+ children: t("security.success.title")
38
+ }),
39
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material.Typography, {
40
+ color: "text.secondary",
41
+ paragraph: true,
42
+ variant: "body1",
43
+ children: message
44
+ }),
45
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_mui_material.Button, {
46
+ color: "primary",
47
+ onClick: handleClose,
48
+ sx: { mt: 2 },
49
+ variant: "contained",
50
+ children: t("security.success.submit")
51
+ })
52
+ ]
53
+ }) }) });
50
54
  };
51
55
  //#endregion
52
56
  exports.MessageType = MessageType;
@@ -1 +1 @@
1
- {"version":3,"file":"Success.js","names":[],"sources":["../../../src/sections/Security/Success.tsx"],"sourcesContent":["import CheckCircleIcon from '@mui/icons-material/CheckCircle';\nimport { Button, Typography } from '@mui/material';\nimport React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useLocation } from 'react-router';\n\nimport SecurityLayout from '../../layouts/Security/Dialog';\nimport { SecurityContainer, SecurityForm } from './styles';\n\nexport enum MessageType {\n Login = 'Login',\n ChangePassword = 'ChangePassword',\n AddUser = 'AddUser',\n Success = 'Success',\n}\n\nconst Success: React.FC = () => {\n const { t } = useTranslation();\n const location = useLocation();\n const queryParams = new URLSearchParams(location.search);\n const messageType = queryParams.get('messageType') as MessageType;\n const message = !messageType\n ? t('security.success.messageSuccess')\n : t(`security.success.message${messageType}`);\n\n const handleClose = () => {\n window.location.href = '/';\n };\n\n return (\n <SecurityLayout>\n <SecurityContainer>\n <SecurityForm>\n <CheckCircleIcon color=\"success\" />\n <Typography component=\"h1\" gutterBottom={true} variant=\"h4\">\n {t('security.success.title')}\n </Typography>\n <Typography color=\"text.secondary\" paragraph={true} variant=\"body1\">\n {message}\n </Typography>\n <Button color=\"primary\" onClick={handleClose} sx={{ mt: 2 }} variant=\"contained\">\n {t('security.success.submit')}\n </Button>\n </SecurityForm>\n </SecurityContainer>\n </SecurityLayout>\n );\n};\n\nexport default Success;\n"],"mappings":";;;;;;;;;;;;AASA,IAAY,cAAL,yBAAA,aAAA;CACL,YAAA,WAAA;CACA,YAAA,oBAAA;CACA,YAAA,aAAA;CACA,YAAA,aAAA;;AACF,EAAA,CAAA,CAAA;AAEA,IAAM,gBAA0B;CAC9B,MAAM,EAAE,OAAA,GAAM,cAAA,eAAA,CAAe;CAC7B,MAAM,YAAA,GAAW,aAAA,YAAA,CAAY;CAE7B,MAAM,cAAc,IADI,gBAAgB,SAAS,MAC7B,CAAA,CAAY,IAAI,aAAa;CACjD,MAAM,UAAU,CAAC,cACb,EAAE,iCAAiC,IACnC,EAAE,2BAA2B,aAAa;CAE9C,MAAM,oBAAoB;EACxB,OAAO,SAAS,OAAO;CACzB;CAEA,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAA,SAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAA,mBAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,KAAA,CAAC,eAAA,cAAD,EAAA,UAAA;EACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,gCAAA,SAAD,EAAiB,OAAM,UAAW,CAAA;EAClC,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAA,YAAD;GAAY,WAAU;GAAK,cAAc;GAAM,SAAQ;GACpD,UAAA,EAAE,wBAAwB;EACjB,CAAA;EACZ,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAA,YAAD;GAAY,OAAM;GAAiB,WAAW;GAAM,SAAQ;GACzD,UAAA;EACS,CAAA;EACZ,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAA,QAAD;GAAQ,OAAM;GAAU,SAAS;GAAa,IAAI,EAAE,IAAI,EAAE;GAAG,SAAQ;GAClE,UAAA,EAAE,yBAAyB;EACtB,CAAA;CACI,EAAA,CAAA,EACG,CAAA,EACL,CAAA;AAEpB"}
1
+ {"version":3,"file":"Success.js","names":[],"sources":["../../../src/sections/Security/Success.tsx"],"sourcesContent":["import CheckCircleIcon from '@mui/icons-material/CheckCircle';\nimport { Button, Typography } from '@mui/material';\nimport React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useLocation, useNavigate } from 'react-router';\n\nimport SecurityLayout from '../../layouts/Security/Dialog';\nimport { SecurityContainer, SecurityForm } from './styles';\n\nexport enum MessageType {\n Login = 'Login',\n ChangePassword = 'ChangePassword',\n AddUser = 'AddUser',\n Success = 'Success',\n}\n\nconst Success: React.FC = () => {\n const { t } = useTranslation();\n const location = useLocation();\n const navigate = useNavigate();\n const queryParams = new URLSearchParams(location.search);\n const messageType = queryParams.get('messageType') as MessageType;\n const message = !messageType\n ? t('security.success.messageSuccess')\n : t(`security.success.message${messageType}`);\n\n const handleClose = () => {\n // navigate() keeps the router basename; window.location.href = '/' left the\n // registry entirely when it is served under a sub-path\n navigate('/');\n };\n\n return (\n <SecurityLayout>\n <SecurityContainer>\n {/* container only: this page has no form to submit */}\n <SecurityForm as=\"div\">\n <CheckCircleIcon color=\"success\" />\n <Typography component=\"h1\" gutterBottom={true} variant=\"h4\">\n {t('security.success.title')}\n </Typography>\n <Typography color=\"text.secondary\" paragraph={true} variant=\"body1\">\n {message}\n </Typography>\n <Button color=\"primary\" onClick={handleClose} sx={{ mt: 2 }} variant=\"contained\">\n {t('security.success.submit')}\n </Button>\n </SecurityForm>\n </SecurityContainer>\n </SecurityLayout>\n );\n};\n\nexport default Success;\n"],"mappings":";;;;;;;;;;;;AASA,IAAY,cAAL,yBAAA,aAAA;CACL,YAAA,WAAA;CACA,YAAA,oBAAA;CACA,YAAA,aAAA;CACA,YAAA,aAAA;;AACF,EAAA,CAAA,CAAA;AAEA,IAAM,gBAA0B;CAC9B,MAAM,EAAE,OAAA,GAAM,cAAA,eAAA,CAAe;CAC7B,MAAM,YAAA,GAAW,aAAA,YAAA,CAAY;CAC7B,MAAM,YAAA,GAAW,aAAA,YAAA,CAAY;CAE7B,MAAM,cAAc,IADI,gBAAgB,SAAS,MAC7B,CAAA,CAAY,IAAI,aAAa;CACjD,MAAM,UAAU,CAAC,cACb,EAAE,iCAAiC,IACnC,EAAE,2BAA2B,aAAa;CAE9C,MAAM,oBAAoB;EAGxB,SAAS,GAAG;CACd;CAEA,OACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAA,SAAD,EAAA,UACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,eAAA,mBAAD,EAAA,UAEE,iBAAA,GAAA,kBAAA,KAAA,CAAC,eAAA,cAAD;EAAc,IAAG;EAAjB,UAAA;GACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,gCAAA,SAAD,EAAiB,OAAM,UAAW,CAAA;GAClC,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAA,YAAD;IAAY,WAAU;IAAK,cAAc;IAAM,SAAQ;IACpD,UAAA,EAAE,wBAAwB;GACjB,CAAA;GACZ,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAA,YAAD;IAAY,OAAM;IAAiB,WAAW;IAAM,SAAQ;IACzD,UAAA;GACS,CAAA;GACZ,iBAAA,GAAA,kBAAA,IAAA,CAAC,cAAA,QAAD;IAAQ,OAAM;IAAU,SAAS;IAAa,IAAI,EAAE,IAAI,EAAE;IAAG,SAAQ;IAClE,UAAA,EAAE,yBAAyB;GACtB,CAAA;EACI;CACG,CAAA,EAAA,CAAA,EACL,CAAA;AAEpB"}
@@ -1,9 +1,9 @@
1
1
  import SecurityLayout from "../../layouts/Security/Dialog.mjs";
2
2
  import { SecurityContainer, SecurityForm } from "./styles.mjs";
3
3
  import "react";
4
- import { jsx, jsxs } from "react/jsx-runtime";
5
4
  import { useTranslation } from "react-i18next";
6
- import { useLocation } from "react-router";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { useLocation, useNavigate } from "react-router";
7
7
  import { Button, Typography } from "@mui/material";
8
8
  import CheckCircleIcon from "@mui/icons-material/CheckCircle";
9
9
  //#region src/sections/Security/Success.tsx
@@ -17,33 +17,37 @@ var MessageType = /* @__PURE__ */ function(MessageType) {
17
17
  var Success = () => {
18
18
  const { t } = useTranslation();
19
19
  const location = useLocation();
20
+ const navigate = useNavigate();
20
21
  const messageType = new URLSearchParams(location.search).get("messageType");
21
22
  const message = !messageType ? t("security.success.messageSuccess") : t(`security.success.message${messageType}`);
22
23
  const handleClose = () => {
23
- window.location.href = "/";
24
+ navigate("/");
24
25
  };
25
- return /* @__PURE__ */ jsx(SecurityLayout, { children: /* @__PURE__ */ jsx(SecurityContainer, { children: /* @__PURE__ */ jsxs(SecurityForm, { children: [
26
- /* @__PURE__ */ jsx(CheckCircleIcon, { color: "success" }),
27
- /* @__PURE__ */ jsx(Typography, {
28
- component: "h1",
29
- gutterBottom: true,
30
- variant: "h4",
31
- children: t("security.success.title")
32
- }),
33
- /* @__PURE__ */ jsx(Typography, {
34
- color: "text.secondary",
35
- paragraph: true,
36
- variant: "body1",
37
- children: message
38
- }),
39
- /* @__PURE__ */ jsx(Button, {
40
- color: "primary",
41
- onClick: handleClose,
42
- sx: { mt: 2 },
43
- variant: "contained",
44
- children: t("security.success.submit")
45
- })
46
- ] }) }) });
26
+ return /* @__PURE__ */ jsx(SecurityLayout, { children: /* @__PURE__ */ jsx(SecurityContainer, { children: /* @__PURE__ */ jsxs(SecurityForm, {
27
+ as: "div",
28
+ children: [
29
+ /* @__PURE__ */ jsx(CheckCircleIcon, { color: "success" }),
30
+ /* @__PURE__ */ jsx(Typography, {
31
+ component: "h1",
32
+ gutterBottom: true,
33
+ variant: "h4",
34
+ children: t("security.success.title")
35
+ }),
36
+ /* @__PURE__ */ jsx(Typography, {
37
+ color: "text.secondary",
38
+ paragraph: true,
39
+ variant: "body1",
40
+ children: message
41
+ }),
42
+ /* @__PURE__ */ jsx(Button, {
43
+ color: "primary",
44
+ onClick: handleClose,
45
+ sx: { mt: 2 },
46
+ variant: "contained",
47
+ children: t("security.success.submit")
48
+ })
49
+ ]
50
+ }) }) });
47
51
  };
48
52
  //#endregion
49
53
  export { MessageType, Success as default };
@@ -1 +1 @@
1
- {"version":3,"file":"Success.mjs","names":[],"sources":["../../../src/sections/Security/Success.tsx"],"sourcesContent":["import CheckCircleIcon from '@mui/icons-material/CheckCircle';\nimport { Button, Typography } from '@mui/material';\nimport React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useLocation } from 'react-router';\n\nimport SecurityLayout from '../../layouts/Security/Dialog';\nimport { SecurityContainer, SecurityForm } from './styles';\n\nexport enum MessageType {\n Login = 'Login',\n ChangePassword = 'ChangePassword',\n AddUser = 'AddUser',\n Success = 'Success',\n}\n\nconst Success: React.FC = () => {\n const { t } = useTranslation();\n const location = useLocation();\n const queryParams = new URLSearchParams(location.search);\n const messageType = queryParams.get('messageType') as MessageType;\n const message = !messageType\n ? t('security.success.messageSuccess')\n : t(`security.success.message${messageType}`);\n\n const handleClose = () => {\n window.location.href = '/';\n };\n\n return (\n <SecurityLayout>\n <SecurityContainer>\n <SecurityForm>\n <CheckCircleIcon color=\"success\" />\n <Typography component=\"h1\" gutterBottom={true} variant=\"h4\">\n {t('security.success.title')}\n </Typography>\n <Typography color=\"text.secondary\" paragraph={true} variant=\"body1\">\n {message}\n </Typography>\n <Button color=\"primary\" onClick={handleClose} sx={{ mt: 2 }} variant=\"contained\">\n {t('security.success.submit')}\n </Button>\n </SecurityForm>\n </SecurityContainer>\n </SecurityLayout>\n );\n};\n\nexport default Success;\n"],"mappings":";;;;;;;;;AASA,IAAY,cAAL,yBAAA,aAAA;CACL,YAAA,WAAA;CACA,YAAA,oBAAA;CACA,YAAA,aAAA;CACA,YAAA,aAAA;;AACF,EAAA,CAAA,CAAA;AAEA,IAAM,gBAA0B;CAC9B,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,WAAW,YAAY;CAE7B,MAAM,cAAc,IADI,gBAAgB,SAAS,MAC7B,CAAA,CAAY,IAAI,aAAa;CACjD,MAAM,UAAU,CAAC,cACb,EAAE,iCAAiC,IACnC,EAAE,2BAA2B,aAAa;CAE9C,MAAM,oBAAoB;EACxB,OAAO,SAAS,OAAO;CACzB;CAEA,OACE,oBAAC,gBAAD,EAAA,UACE,oBAAC,mBAAD,EAAA,UACE,qBAAC,cAAD,EAAA,UAAA;EACE,oBAAC,iBAAD,EAAiB,OAAM,UAAW,CAAA;EAClC,oBAAC,YAAD;GAAY,WAAU;GAAK,cAAc;GAAM,SAAQ;GACpD,UAAA,EAAE,wBAAwB;EACjB,CAAA;EACZ,oBAAC,YAAD;GAAY,OAAM;GAAiB,WAAW;GAAM,SAAQ;GACzD,UAAA;EACS,CAAA;EACZ,oBAAC,QAAD;GAAQ,OAAM;GAAU,SAAS;GAAa,IAAI,EAAE,IAAI,EAAE;GAAG,SAAQ;GAClE,UAAA,EAAE,yBAAyB;EACtB,CAAA;CACI,EAAA,CAAA,EACG,CAAA,EACL,CAAA;AAEpB"}
1
+ {"version":3,"file":"Success.mjs","names":[],"sources":["../../../src/sections/Security/Success.tsx"],"sourcesContent":["import CheckCircleIcon from '@mui/icons-material/CheckCircle';\nimport { Button, Typography } from '@mui/material';\nimport React from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useLocation, useNavigate } from 'react-router';\n\nimport SecurityLayout from '../../layouts/Security/Dialog';\nimport { SecurityContainer, SecurityForm } from './styles';\n\nexport enum MessageType {\n Login = 'Login',\n ChangePassword = 'ChangePassword',\n AddUser = 'AddUser',\n Success = 'Success',\n}\n\nconst Success: React.FC = () => {\n const { t } = useTranslation();\n const location = useLocation();\n const navigate = useNavigate();\n const queryParams = new URLSearchParams(location.search);\n const messageType = queryParams.get('messageType') as MessageType;\n const message = !messageType\n ? t('security.success.messageSuccess')\n : t(`security.success.message${messageType}`);\n\n const handleClose = () => {\n // navigate() keeps the router basename; window.location.href = '/' left the\n // registry entirely when it is served under a sub-path\n navigate('/');\n };\n\n return (\n <SecurityLayout>\n <SecurityContainer>\n {/* container only: this page has no form to submit */}\n <SecurityForm as=\"div\">\n <CheckCircleIcon color=\"success\" />\n <Typography component=\"h1\" gutterBottom={true} variant=\"h4\">\n {t('security.success.title')}\n </Typography>\n <Typography color=\"text.secondary\" paragraph={true} variant=\"body1\">\n {message}\n </Typography>\n <Button color=\"primary\" onClick={handleClose} sx={{ mt: 2 }} variant=\"contained\">\n {t('security.success.submit')}\n </Button>\n </SecurityForm>\n </SecurityContainer>\n </SecurityLayout>\n );\n};\n\nexport default Success;\n"],"mappings":";;;;;;;;;AASA,IAAY,cAAL,yBAAA,aAAA;CACL,YAAA,WAAA;CACA,YAAA,oBAAA;CACA,YAAA,aAAA;CACA,YAAA,aAAA;;AACF,EAAA,CAAA,CAAA;AAEA,IAAM,gBAA0B;CAC9B,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,WAAW,YAAY;CAC7B,MAAM,WAAW,YAAY;CAE7B,MAAM,cAAc,IADI,gBAAgB,SAAS,MAC7B,CAAA,CAAY,IAAI,aAAa;CACjD,MAAM,UAAU,CAAC,cACb,EAAE,iCAAiC,IACnC,EAAE,2BAA2B,aAAa;CAE9C,MAAM,oBAAoB;EAGxB,SAAS,GAAG;CACd;CAEA,OACE,oBAAC,gBAAD,EAAA,UACE,oBAAC,mBAAD,EAAA,UAEE,qBAAC,cAAD;EAAc,IAAG;EAAjB,UAAA;GACE,oBAAC,iBAAD,EAAiB,OAAM,UAAW,CAAA;GAClC,oBAAC,YAAD;IAAY,WAAU;IAAK,cAAc;IAAM,SAAQ;IACpD,UAAA,EAAE,wBAAwB;GACjB,CAAA;GACZ,oBAAC,YAAD;IAAY,OAAM;IAAiB,WAAW;IAAM,SAAQ;IACzD,UAAA;GACS,CAAA;GACZ,oBAAC,QAAD;IAAQ,OAAM;IAAU,SAAS;IAAa,IAAI,EAAE,IAAI,EAAE;IAAG,SAAQ;IAClE,UAAA,EAAE,yBAAyB;GACtB,CAAA;EACI;CACG,CAAA,EAAA,CAAA,EACL,CAAA;AAEpB"}
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import type { StagePackageVersion } from './types';
3
+ interface Props {
4
+ item: StagePackageVersion;
5
+ /** Called after a successful approve/reject so the caller can refresh. */
6
+ onDone: () => void;
7
+ }
8
+ /**
9
+ * Approve / reject buttons with a confirmation step.
10
+ *
11
+ * Both actions are irreversible from the UI: approving publishes the version
12
+ * for real, rejecting deletes the staged record and its tarball.
13
+ */
14
+ declare const StageActions: React.FC<Props>;
15
+ export default StageActions;