@webiny/cognito 6.4.11 → 6.6.0-alpha.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 (164) hide show
  1. package/Cognito.d.ts +4 -4
  2. package/admin/Cognito.d.ts +3 -1
  3. package/admin/Cognito.js +8 -2
  4. package/admin/Cognito.js.map +1 -1
  5. package/admin/Extension.js +21 -0
  6. package/admin/Extension.js.map +1 -1
  7. package/admin/features/account/getCurrentUser/GetCurrentUserGateway.d.ts +11 -0
  8. package/admin/features/account/getCurrentUser/GetCurrentUserGateway.js +44 -0
  9. package/admin/features/account/getCurrentUser/GetCurrentUserGateway.js.map +1 -0
  10. package/admin/features/account/getCurrentUser/GetCurrentUserUseCase.d.ts +10 -0
  11. package/admin/features/account/getCurrentUser/GetCurrentUserUseCase.js +19 -0
  12. package/admin/features/account/getCurrentUser/GetCurrentUserUseCase.js.map +1 -0
  13. package/admin/features/account/getCurrentUser/abstractions/GetCurrentUserGateway.d.ts +16 -0
  14. package/admin/features/account/getCurrentUser/abstractions/GetCurrentUserGateway.js +5 -0
  15. package/admin/features/account/getCurrentUser/abstractions/GetCurrentUserGateway.js.map +1 -0
  16. package/admin/features/account/getCurrentUser/abstractions/GetCurrentUserUseCase.d.ts +10 -0
  17. package/admin/features/account/getCurrentUser/abstractions/GetCurrentUserUseCase.js +5 -0
  18. package/admin/features/account/getCurrentUser/abstractions/GetCurrentUserUseCase.js.map +1 -0
  19. package/admin/features/account/getCurrentUser/abstractions/index.d.ts +6 -0
  20. package/admin/features/account/getCurrentUser/abstractions/index.js +2 -0
  21. package/admin/features/account/getCurrentUser/feature.d.ts +3 -0
  22. package/admin/features/account/getCurrentUser/feature.js +19 -0
  23. package/admin/features/account/getCurrentUser/feature.js.map +1 -0
  24. package/admin/features/account/getCurrentUser/index.d.ts +1 -0
  25. package/admin/features/account/getCurrentUser/index.js +1 -0
  26. package/admin/features/account/updateCurrentUser/UpdateCurrentUserGateway.d.ts +11 -0
  27. package/admin/features/account/updateCurrentUser/UpdateCurrentUserGateway.js +48 -0
  28. package/admin/features/account/updateCurrentUser/UpdateCurrentUserGateway.js.map +1 -0
  29. package/admin/features/account/updateCurrentUser/UpdateCurrentUserUseCase.d.ts +10 -0
  30. package/admin/features/account/updateCurrentUser/UpdateCurrentUserUseCase.js +19 -0
  31. package/admin/features/account/updateCurrentUser/UpdateCurrentUserUseCase.js.map +1 -0
  32. package/admin/features/account/updateCurrentUser/abstractions/UpdateCurrentUserGateway.d.ts +26 -0
  33. package/admin/features/account/updateCurrentUser/abstractions/UpdateCurrentUserGateway.js +5 -0
  34. package/admin/features/account/updateCurrentUser/abstractions/UpdateCurrentUserGateway.js.map +1 -0
  35. package/admin/features/account/updateCurrentUser/abstractions/UpdateCurrentUserUseCase.d.ts +13 -0
  36. package/admin/features/account/updateCurrentUser/abstractions/UpdateCurrentUserUseCase.js +5 -0
  37. package/admin/features/account/updateCurrentUser/abstractions/UpdateCurrentUserUseCase.js.map +1 -0
  38. package/admin/features/account/updateCurrentUser/abstractions/index.d.ts +8 -0
  39. package/admin/features/account/updateCurrentUser/abstractions/index.js +2 -0
  40. package/admin/features/account/updateCurrentUser/feature.d.ts +3 -0
  41. package/admin/features/account/updateCurrentUser/feature.js +19 -0
  42. package/admin/features/account/updateCurrentUser/feature.js.map +1 -0
  43. package/admin/features/account/updateCurrentUser/index.d.ts +1 -0
  44. package/admin/features/account/updateCurrentUser/index.js +1 -0
  45. package/admin/features/permissions/feature.d.ts +1 -1
  46. package/admin/features/users/createUser/CreateUserGateway.d.ts +11 -0
  47. package/admin/features/users/createUser/CreateUserGateway.js +49 -0
  48. package/admin/features/users/createUser/CreateUserGateway.js.map +1 -0
  49. package/admin/features/users/createUser/CreateUserUseCase.d.ts +10 -0
  50. package/admin/features/users/createUser/CreateUserUseCase.js +18 -0
  51. package/admin/features/users/createUser/CreateUserUseCase.js.map +1 -0
  52. package/admin/features/users/createUser/abstractions/CreateUserGateway.d.ts +21 -0
  53. package/admin/features/users/createUser/abstractions/CreateUserGateway.js +5 -0
  54. package/admin/features/users/createUser/abstractions/CreateUserGateway.js.map +1 -0
  55. package/admin/features/users/createUser/abstractions/CreateUserUseCase.d.ts +14 -0
  56. package/admin/features/users/createUser/abstractions/CreateUserUseCase.js +5 -0
  57. package/admin/features/users/createUser/abstractions/CreateUserUseCase.js.map +1 -0
  58. package/admin/features/users/createUser/abstractions/index.d.ts +2 -0
  59. package/admin/features/users/createUser/abstractions/index.js +2 -0
  60. package/admin/features/users/createUser/feature.d.ts +3 -0
  61. package/admin/features/users/createUser/feature.js +19 -0
  62. package/admin/features/users/createUser/feature.js.map +1 -0
  63. package/admin/features/users/createUser/index.d.ts +2 -0
  64. package/admin/features/users/createUser/index.js +2 -0
  65. package/admin/features/users/deleteUser/DeleteUserGateway.d.ts +11 -0
  66. package/admin/features/users/deleteUser/DeleteUserGateway.js +40 -0
  67. package/admin/features/users/deleteUser/DeleteUserGateway.js.map +1 -0
  68. package/admin/features/users/deleteUser/DeleteUserUseCase.d.ts +10 -0
  69. package/admin/features/users/deleteUser/DeleteUserUseCase.js +18 -0
  70. package/admin/features/users/deleteUser/DeleteUserUseCase.js.map +1 -0
  71. package/admin/features/users/deleteUser/abstractions/DeleteUserGateway.d.ts +11 -0
  72. package/admin/features/users/deleteUser/abstractions/DeleteUserGateway.js +5 -0
  73. package/admin/features/users/deleteUser/abstractions/DeleteUserGateway.js.map +1 -0
  74. package/admin/features/users/deleteUser/abstractions/DeleteUserUseCase.d.ts +11 -0
  75. package/admin/features/users/deleteUser/abstractions/DeleteUserUseCase.js +5 -0
  76. package/admin/features/users/deleteUser/abstractions/DeleteUserUseCase.js.map +1 -0
  77. package/admin/features/users/deleteUser/abstractions/index.d.ts +2 -0
  78. package/admin/features/users/deleteUser/abstractions/index.js +2 -0
  79. package/admin/features/users/deleteUser/feature.d.ts +3 -0
  80. package/admin/features/users/deleteUser/feature.js +19 -0
  81. package/admin/features/users/deleteUser/feature.js.map +1 -0
  82. package/admin/features/users/deleteUser/index.d.ts +2 -0
  83. package/admin/features/users/deleteUser/index.js +2 -0
  84. package/admin/features/users/getUser/GetUserGateway.d.ts +11 -0
  85. package/admin/features/users/getUser/GetUserGateway.js +57 -0
  86. package/admin/features/users/getUser/GetUserGateway.js.map +1 -0
  87. package/admin/features/users/getUser/GetUserUseCase.d.ts +10 -0
  88. package/admin/features/users/getUser/GetUserUseCase.js +18 -0
  89. package/admin/features/users/getUser/GetUserUseCase.js.map +1 -0
  90. package/admin/features/users/getUser/abstractions/GetUserGateway.d.ts +32 -0
  91. package/admin/features/users/getUser/abstractions/GetUserGateway.js +5 -0
  92. package/admin/features/users/getUser/abstractions/GetUserGateway.js.map +1 -0
  93. package/admin/features/users/getUser/abstractions/GetUserUseCase.d.ts +14 -0
  94. package/admin/features/users/getUser/abstractions/GetUserUseCase.js +5 -0
  95. package/admin/features/users/getUser/abstractions/GetUserUseCase.js.map +1 -0
  96. package/admin/features/users/getUser/abstractions/index.d.ts +2 -0
  97. package/admin/features/users/getUser/abstractions/index.js +2 -0
  98. package/admin/features/users/getUser/feature.d.ts +3 -0
  99. package/admin/features/users/getUser/feature.js +19 -0
  100. package/admin/features/users/getUser/feature.js.map +1 -0
  101. package/admin/features/users/getUser/index.d.ts +2 -0
  102. package/admin/features/users/getUser/index.js +2 -0
  103. package/admin/features/users/listUsers/ListUsersGateway.d.ts +11 -0
  104. package/admin/features/users/listUsers/ListUsersGateway.js +39 -0
  105. package/admin/features/users/listUsers/ListUsersGateway.js.map +1 -0
  106. package/admin/features/users/listUsers/ListUsersUseCase.d.ts +10 -0
  107. package/admin/features/users/listUsers/ListUsersUseCase.js +18 -0
  108. package/admin/features/users/listUsers/ListUsersUseCase.js.map +1 -0
  109. package/admin/features/users/listUsers/abstractions/ListUsersGateway.d.ts +17 -0
  110. package/admin/features/users/listUsers/abstractions/ListUsersGateway.js +5 -0
  111. package/admin/features/users/listUsers/abstractions/ListUsersGateway.js.map +1 -0
  112. package/admin/features/users/listUsers/abstractions/ListUsersUseCase.d.ts +10 -0
  113. package/admin/features/users/listUsers/abstractions/ListUsersUseCase.js +5 -0
  114. package/admin/features/users/listUsers/abstractions/ListUsersUseCase.js.map +1 -0
  115. package/admin/features/users/listUsers/abstractions/index.d.ts +2 -0
  116. package/admin/features/users/listUsers/abstractions/index.js +2 -0
  117. package/admin/features/users/listUsers/feature.d.ts +3 -0
  118. package/admin/features/users/listUsers/feature.js +19 -0
  119. package/admin/features/users/listUsers/feature.js.map +1 -0
  120. package/admin/features/users/listUsers/index.d.ts +2 -0
  121. package/admin/features/users/listUsers/index.js +2 -0
  122. package/admin/features/users/updateUser/UpdateUserGateway.d.ts +11 -0
  123. package/admin/features/users/updateUser/UpdateUserGateway.js +59 -0
  124. package/admin/features/users/updateUser/UpdateUserGateway.js.map +1 -0
  125. package/admin/features/users/updateUser/UpdateUserUseCase.d.ts +10 -0
  126. package/admin/features/users/updateUser/UpdateUserUseCase.js +18 -0
  127. package/admin/features/users/updateUser/UpdateUserUseCase.js.map +1 -0
  128. package/admin/features/users/updateUser/abstractions/UpdateUserGateway.d.ts +33 -0
  129. package/admin/features/users/updateUser/abstractions/UpdateUserGateway.js +5 -0
  130. package/admin/features/users/updateUser/abstractions/UpdateUserGateway.js.map +1 -0
  131. package/admin/features/users/updateUser/abstractions/UpdateUserUseCase.d.ts +15 -0
  132. package/admin/features/users/updateUser/abstractions/UpdateUserUseCase.js +5 -0
  133. package/admin/features/users/updateUser/abstractions/UpdateUserUseCase.js.map +1 -0
  134. package/admin/features/users/updateUser/abstractions/index.d.ts +2 -0
  135. package/admin/features/users/updateUser/abstractions/index.js +2 -0
  136. package/admin/features/users/updateUser/feature.d.ts +3 -0
  137. package/admin/features/users/updateUser/feature.js +19 -0
  138. package/admin/features/users/updateUser/feature.js.map +1 -0
  139. package/admin/features/users/updateUser/index.d.ts +2 -0
  140. package/admin/features/users/updateUser/index.js +2 -0
  141. package/admin/presentation/Cognito/CognitoLoginScreen.d.ts +2 -2
  142. package/admin/presentation/Cognito/components/View.d.ts +1 -1
  143. package/admin/presentation/Cognito/components/index.d.ts +1 -1
  144. package/admin/ui/views/Account/Account.js +42 -34
  145. package/admin/ui/views/Account/Account.js.map +1 -1
  146. package/admin/ui/views/Users/UsersDataList.js +44 -26
  147. package/admin/ui/views/Users/UsersDataList.js.map +1 -1
  148. package/admin/ui/views/Users/UsersForm.js +1 -1
  149. package/admin/ui/views/Users/UsersForm.js.map +1 -1
  150. package/admin/ui/views/Users/UsersView.js +3 -3
  151. package/admin/ui/views/Users/UsersView.js.map +1 -1
  152. package/admin/ui/views/Users/hooks/useUserForm.d.ts +2 -2
  153. package/admin/ui/views/Users/hooks/useUserForm.js +60 -78
  154. package/admin/ui/views/Users/hooks/useUserForm.js.map +1 -1
  155. package/api/graphql/user.gql.d.ts +2 -2
  156. package/api/graphql/user.gql.js +2 -2
  157. package/api/graphql/user.gql.js.map +1 -1
  158. package/package.json +21 -24
  159. package/admin/ui/views/Account/graphql.d.ts +0 -2
  160. package/admin/ui/views/Account/graphql.js +0 -41
  161. package/admin/ui/views/Account/graphql.js.map +0 -1
  162. package/admin/ui/views/Users/graphql.d.ts +0 -5
  163. package/admin/ui/views/Users/graphql.js +0 -98
  164. package/admin/ui/views/Users/graphql.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"admin/ui/views/Account/Account.js","sources":["../../../../../src/admin/ui/views/Account/Account.tsx"],"sourcesContent":["import React, { useState } from \"react\";\nimport omit from \"lodash/omit.js\";\nimport { useQuery, useMutation } from \"@apollo/react-hooks\";\nimport { i18n } from \"@webiny/app/i18n/index.js\";\nimport { Form } from \"@webiny/form\";\nimport { validation } from \"@webiny/validation\";\nimport { AvatarImage } from \"../../components/AvatarImage/index.js\";\nimport { GET_CURRENT_USER, UPDATE_CURRENT_USER } from \"./graphql.js\";\nimport { config as appConfig } from \"@webiny/app/config.js\";\n\nimport {\n SimpleForm,\n SimpleFormHeader,\n SimpleFormFooter,\n SimpleFormContent,\n useIdentity\n} from \"@webiny/app-admin\";\nimport { CenteredView } from \"@webiny/app-admin\";\nimport { usePasswordValidator } from \"~/admin/presentation/shared/usePasswordValidator.js\";\nimport { Alert, Button, Grid, Input, OverlayLoader, useToast } from \"@webiny/admin-ui\";\n\nconst t = i18n.ns(\"app-security-admin-users/account-form\");\n\ninterface UserAccountFormData {\n id?: boolean;\n firstName: string;\n lastName: string;\n email: string;\n password?: string;\n external?: boolean;\n avatar: {\n src?: string;\n };\n}\n\nexport const UserAccountForm = () => {\n const [isSaving, setSaving] = useState(false);\n const toast = useToast();\n const { identity } = useIdentity();\n const passwordValidator = usePasswordValidator();\n const currentUser = useQuery(GET_CURRENT_USER);\n const [updateUser] = useMutation(UPDATE_CURRENT_USER);\n\n const user = currentUser.loading ? {} : currentUser.data.adminUsers.user.data;\n\n const isFormLoading = isSaving || currentUser.loading;\n const loaderMessage = isSaving ? \"Saving account...\" : \"Loading account...\";\n\n const emailIsDisabled = appConfig.getKey(\n \"ADMIN_USER_CAN_CHANGE_EMAIL\",\n process.env.REACT_APP_ADMIN_USER_CAN_CHANGE_EMAIL === \"false\"\n );\n\n const isExternal = user?.external === true;\n\n const onSubmit = async (formData: UserAccountFormData) => {\n setSaving(true);\n const { data: response } = await updateUser({\n variables: { data: omit(formData, [\"id\", \"external\"]) }\n });\n\n const { error } = response.adminUsers.updateCurrentUser;\n setSaving(false);\n\n if (error) {\n toast.showWarningToast({\n title: \"Error updating user account\",\n description: error.message,\n duration: Infinity\n });\n return;\n }\n\n // TODO: set new roles/teams into the identity context\n\n identity.update({\n displayName: `${formData.firstName} ${formData.lastName}`,\n profile: {\n ...(identity.profile || {}),\n firstName: formData.firstName,\n lastName: formData.lastName,\n avatar: formData.avatar\n }\n });\n\n toast.showSuccessToast({ title: \"Account updated successfully!\" });\n };\n\n return (\n <CenteredView maxWidth={600}>\n <Form<UserAccountFormData> data={user} onSubmit={onSubmit}>\n {({ data, form, Bind }) => (\n <SimpleForm>\n {isFormLoading && <OverlayLoader text={loaderMessage} />}\n <SimpleFormHeader title={\"Account\"} />\n <SimpleFormContent>\n {isExternal && (\n <Grid>\n <Grid.Column span={12}>\n <Alert type={\"info\"} title={\"External User\"}>\n This user is an external user and cannot be edited.\n </Alert>\n </Grid.Column>\n </Grid>\n )}\n <Grid>\n <Grid.Column span={12} data-testid={\"avatar\"}>\n <Bind name=\"avatar\">\n <AvatarImage round disabled={isExternal} />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n <Bind\n name=\"firstName\"\n validators={validation.create(\"required\")}\n >\n <Input\n label={t`First Name`}\n disabled={isExternal}\n data-testid=\"account.firstname\"\n />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n {\" \"}\n <Bind\n name=\"lastName\"\n validators={validation.create(\"required\")}\n >\n <Input\n label={t`Last Name`}\n disabled={isExternal}\n data-testid=\"account.lastname\"\n />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n <Bind\n name=\"email\"\n validators={validation.create(\"required,email\")}\n >\n <Input\n value={data.email}\n label={t`Email`}\n disabled={emailIsDisabled || isExternal}\n data-testid=\"account.email\"\n description={\n \"Email is your unique identifier used to login!\"\n }\n />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n <Bind name=\"password\" validators={passwordValidator}>\n <Input\n autoComplete=\"off\"\n disabled={data.external}\n description={\n data.id && \"Type a new password to reset it.\"\n }\n type=\"password\"\n label={\"Password\"}\n data-testid=\"account.password\"\n />\n </Bind>\n </Grid.Column>\n </Grid>\n </SimpleFormContent>\n <SimpleFormFooter data-testid={\"form-footer\"}>\n <Button\n disabled={isExternal}\n data-testid=\"account.updatebutton\"\n onClick={form.submit}\n >{t`Update account`}</Button>\n </SimpleFormFooter>\n </SimpleForm>\n )}\n </Form>\n </CenteredView>\n );\n};\n"],"names":["t","i18n","UserAccountForm","isSaving","setSaving","useState","toast","useToast","identity","useIdentity","passwordValidator","usePasswordValidator","currentUser","useQuery","GET_CURRENT_USER","updateUser","useMutation","UPDATE_CURRENT_USER","user","isFormLoading","loaderMessage","emailIsDisabled","appConfig","process","isExternal","onSubmit","formData","response","omit","error","Infinity","CenteredView","Form","data","form","Bind","SimpleForm","OverlayLoader","SimpleFormHeader","SimpleFormContent","Grid","Alert","AvatarImage","validation","Input","SimpleFormFooter","Button"],"mappings":"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"}
1
+ {"version":3,"file":"admin/ui/views/Account/Account.js","sources":["../../../../../src/admin/ui/views/Account/Account.tsx"],"sourcesContent":["import React, { useEffect, useState } from \"react\";\nimport omit from \"lodash/omit.js\";\nimport { useFeature } from \"@webiny/app\";\nimport { i18n } from \"@webiny/app/i18n/index.js\";\nimport { Form } from \"@webiny/form\";\nimport { validation } from \"@webiny/validation\";\nimport { AvatarImage } from \"../../components/AvatarImage/index.js\";\nimport { config as appConfig } from \"@webiny/app/config.js\";\nimport { GetCurrentUserFeature } from \"~/admin/features/account/getCurrentUser/index.js\";\nimport { UpdateCurrentUserFeature } from \"~/admin/features/account/updateCurrentUser/index.js\";\n\nimport {\n SimpleForm,\n SimpleFormHeader,\n SimpleFormFooter,\n SimpleFormContent,\n useIdentity\n} from \"@webiny/app-admin\";\nimport { CenteredView } from \"@webiny/app-admin\";\nimport { usePasswordValidator } from \"~/admin/presentation/shared/usePasswordValidator.js\";\nimport { Alert, Button, Grid, Input, OverlayLoader, useToast } from \"@webiny/admin-ui\";\n\nconst t = i18n.ns(\"app-security-admin-users/account-form\");\n\ninterface UserAccountFormData {\n id?: boolean;\n firstName: string;\n lastName: string;\n email: string;\n password?: string;\n external?: boolean;\n avatar: {\n src?: string;\n };\n}\n\nexport const UserAccountForm = () => {\n const [isSaving, setSaving] = useState(false);\n const [isLoading, setIsLoading] = useState(true);\n const [user, setUser] = useState<Record<string, any>>({});\n const toast = useToast();\n const { identity } = useIdentity();\n const passwordValidator = usePasswordValidator();\n const { useCase: getCurrentUser } = useFeature(GetCurrentUserFeature);\n const { useCase: updateCurrentUser } = useFeature(UpdateCurrentUserFeature);\n\n useEffect(() => {\n getCurrentUser.execute().then(data => {\n setUser(data);\n setIsLoading(false);\n });\n }, []);\n\n const isFormLoading = isSaving || isLoading;\n const loaderMessage = isSaving ? \"Saving account...\" : \"Loading account...\";\n\n const emailIsDisabled = appConfig.getKey(\n \"ADMIN_USER_CAN_CHANGE_EMAIL\",\n process.env.REACT_APP_ADMIN_USER_CAN_CHANGE_EMAIL === \"false\"\n );\n\n const isExternal = user?.external === true;\n\n const onSubmit = async (formData: UserAccountFormData) => {\n setSaving(true);\n\n try {\n await updateCurrentUser.execute(omit(formData, [\"id\", \"external\"]));\n\n identity.update({\n displayName: `${formData.firstName} ${formData.lastName}`,\n profile: {\n ...(identity.profile || {}),\n firstName: formData.firstName,\n lastName: formData.lastName,\n avatar: formData.avatar\n }\n });\n\n toast.showSuccessToast({ title: \"Account updated successfully!\" });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n toast.showWarningToast({\n title: \"Error updating user account\",\n description: message,\n duration: Infinity\n });\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <CenteredView maxWidth={600}>\n <Form<UserAccountFormData> data={user} onSubmit={onSubmit}>\n {({ data, form, Bind }) => (\n <SimpleForm>\n {isFormLoading && <OverlayLoader text={loaderMessage} />}\n <SimpleFormHeader title={\"Account\"} />\n <SimpleFormContent>\n {isExternal && (\n <Grid>\n <Grid.Column span={12}>\n <Alert type={\"info\"} title={\"External User\"}>\n This user is an external user and cannot be edited.\n </Alert>\n </Grid.Column>\n </Grid>\n )}\n <Grid>\n <Grid.Column span={12} data-testid={\"avatar\"}>\n <Bind name=\"avatar\">\n <AvatarImage round disabled={isExternal} />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n <Bind\n name=\"firstName\"\n validators={validation.create(\"required\")}\n >\n <Input\n label={t`First Name`}\n disabled={isExternal}\n data-testid=\"account.firstname\"\n />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n {\" \"}\n <Bind\n name=\"lastName\"\n validators={validation.create(\"required\")}\n >\n <Input\n label={t`Last Name`}\n disabled={isExternal}\n data-testid=\"account.lastname\"\n />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n <Bind\n name=\"email\"\n validators={validation.create(\"required,email\")}\n >\n <Input\n value={data.email}\n label={t`Email`}\n disabled={emailIsDisabled || isExternal}\n data-testid=\"account.email\"\n description={\n \"Email is your unique identifier used to login!\"\n }\n />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n <Bind name=\"password\" validators={passwordValidator}>\n <Input\n autoComplete=\"off\"\n disabled={data.external}\n description={\n data.id && \"Type a new password to reset it.\"\n }\n type=\"password\"\n label={\"Password\"}\n data-testid=\"account.password\"\n />\n </Bind>\n </Grid.Column>\n </Grid>\n </SimpleFormContent>\n <SimpleFormFooter data-testid={\"form-footer\"}>\n <Button\n disabled={isExternal}\n data-testid=\"account.updatebutton\"\n onClick={form.submit}\n >{t`Update account`}</Button>\n </SimpleFormFooter>\n </SimpleForm>\n )}\n </Form>\n </CenteredView>\n );\n};\n"],"names":["t","i18n","UserAccountForm","isSaving","setSaving","useState","isLoading","setIsLoading","user","setUser","toast","useToast","identity","useIdentity","passwordValidator","usePasswordValidator","getCurrentUser","useFeature","GetCurrentUserFeature","updateCurrentUser","UpdateCurrentUserFeature","useEffect","data","isFormLoading","loaderMessage","emailIsDisabled","appConfig","process","isExternal","onSubmit","formData","omit","error","message","Error","Infinity","CenteredView","Form","form","Bind","SimpleForm","OverlayLoader","SimpleFormHeader","SimpleFormContent","Grid","Alert","AvatarImage","validation","Input","SimpleFormFooter","Button"],"mappings":"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"}
@@ -1,11 +1,12 @@
1
- import react, { useCallback, useMemo, useState } from "react";
2
- import { useMutation, useQuery } from "@apollo/react-hooks";
1
+ import react, { useCallback, useEffect, useMemo, useState } from "react";
3
2
  import orderBy from "lodash/orderBy.js";
3
+ import { useFeature } from "@webiny/app";
4
4
  import { Avatar, Button, DataList, DataListModal, DeleteIcon, Grid, List, Select, Tooltip } from "@webiny/admin-ui";
5
5
  import { ReactComponent } from "@webiny/icons/add.svg";
6
6
  import { i18n } from "@webiny/app/i18n/index.js";
7
7
  import { SearchUI, useConfirmationDialog, useRouter, useSecurity, useSnackbar } from "@webiny/app-admin";
8
- import { DELETE_USER, LIST_USERS } from "./graphql.js";
8
+ import { ListUsersFeature } from "../../../features/users/listUsers/index.js";
9
+ import { DeleteUserFeature } from "../../../features/users/deleteUser/index.js";
9
10
  import { deserializeSorters } from "../utils.js";
10
11
  import { Routes } from "../../../routes.js";
11
12
  const t = i18n.ns("app-identity/admin/users/data-list");
@@ -30,6 +31,9 @@ const SORTERS = [
30
31
  const UsersDataList = ()=>{
31
32
  const [filter, setFilter] = useState("");
32
33
  const [sort, setSort] = useState(SORTERS[0].sorter);
34
+ const [users, setUsers] = useState([]);
35
+ const [usersLoading, setUsersLoading] = useState(true);
36
+ const [deleteLoading, setDeleteLoading] = useState(false);
33
37
  const { identity } = useSecurity();
34
38
  const { goToRoute } = useRouter();
35
39
  const { showSnackbar } = useSnackbar();
@@ -38,13 +42,27 @@ const UsersDataList = ()=>{
38
42
  title: "Delete user",
39
43
  message: "Are you sure you want to delete this user? This action cannot be undone."
40
44
  });
45
+ const { useCase: listUsers } = useFeature(ListUsersFeature);
46
+ const { useCase: deleteUser } = useFeature(DeleteUserFeature);
47
+ const fetchUsers = useCallback(()=>{
48
+ setUsersLoading(true);
49
+ listUsers.execute().then((data)=>{
50
+ setUsers(data || []);
51
+ setUsersLoading(false);
52
+ });
53
+ }, [
54
+ listUsers
55
+ ]);
56
+ useEffect(()=>{
57
+ fetchUsers();
58
+ }, []);
41
59
  const filterUsers = useCallback(({ email, firstName, lastName })=>email.toLowerCase().includes(filter) || firstName.toLowerCase().includes(filter) || lastName.toLowerCase().includes(filter), [
42
60
  filter
43
61
  ]);
44
- const sortUsers = useCallback((users)=>{
45
- if (!sort) return users;
62
+ const sortUsers = useCallback((list)=>{
63
+ if (!sort) return list;
46
64
  const [key, sortBy] = deserializeSorters(sort);
47
- return orderBy(users, [
65
+ return orderBy(list, [
48
66
  key
49
67
  ], [
50
68
  sortBy
@@ -52,32 +70,32 @@ const UsersDataList = ()=>{
52
70
  }, [
53
71
  sort
54
72
  ]);
55
- const { data: listUsers, loading: usersLoading } = useQuery(LIST_USERS);
56
- const [deleteIt, { loading: deleteLoading }] = useMutation(DELETE_USER, {
57
- refetchQueries: [
58
- {
59
- query: LIST_USERS
60
- }
61
- ]
62
- });
63
- const data = usersLoading && !listUsers ? [] : listUsers.adminUsers.users.data || [];
64
- const filteredData = "" === filter ? data : data.filter(filterUsers);
73
+ const filteredData = "" === filter ? users : users.filter(filterUsers);
65
74
  const userList = sortUsers(filteredData);
66
75
  const id = new URLSearchParams(location.search).get("id");
67
76
  const deleteItem = useCallback((item)=>{
68
77
  showConfirmation(async ()=>{
69
- const response = await deleteIt({
70
- variables: item
71
- });
72
- const error = response?.data?.adminUsers?.deleteUser?.error;
73
- if (error) return showSnackbar(error.message);
74
- showSnackbar(t`User "{email}" deleted.`({
75
- email: item.email
76
- }));
77
- if (id === item.id) goToRoute(Routes.Users.List);
78
+ setDeleteLoading(true);
79
+ try {
80
+ await deleteUser.execute({
81
+ id: item.id
82
+ });
83
+ showSnackbar(t`User "{email}" deleted.`({
84
+ email: item.email
85
+ }));
86
+ fetchUsers();
87
+ if (id === item.id) goToRoute(Routes.Users.List);
88
+ } catch (error) {
89
+ const message = error instanceof Error ? error.message : "Unknown error";
90
+ showSnackbar(message);
91
+ } finally{
92
+ setDeleteLoading(false);
93
+ }
78
94
  });
79
95
  }, [
80
- id
96
+ id,
97
+ deleteUser,
98
+ fetchUsers
81
99
  ]);
82
100
  const usersDataListModalOverlay = useMemo(()=>/*#__PURE__*/ react.createElement(DataListModal.Content, null, /*#__PURE__*/ react.createElement(Grid, null, /*#__PURE__*/ react.createElement(Grid.Column, {
83
101
  span: 12
@@ -1 +1 @@
1
- {"version":3,"file":"admin/ui/views/Users/UsersDataList.js","sources":["../../../../../src/admin/ui/views/Users/UsersDataList.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useState } from \"react\";\nimport { useMutation, useQuery } from \"@apollo/react-hooks\";\nimport orderBy from \"lodash/orderBy.js\";\nimport { Avatar, Button, Grid, Select, Tooltip } from \"@webiny/admin-ui\";\nimport { ReactComponent as AddIcon } from \"@webiny/icons/add.svg\";\nimport { i18n } from \"@webiny/app/i18n/index.js\";\nimport { useSecurity } from \"@webiny/app-admin\";\nimport { List, DataList, DataListModal, DeleteIcon } from \"@webiny/admin-ui\";\nimport { useRouter, useSnackbar, useConfirmationDialog, SearchUI } from \"@webiny/app-admin\";\nimport { DELETE_USER, LIST_USERS } from \"./graphql.js\";\nimport { deserializeSorters } from \"../utils.js\";\nimport { Routes } from \"~/admin/routes.js\";\nimport type { UserItem } from \"~/admin/ui/UserItem.js\";\n\nconst t = i18n.ns(\"app-identity/admin/users/data-list\");\n\nconst SORTERS = [\n {\n label: t`Newest to oldest`,\n sorter: \"createdOn_DESC\"\n },\n {\n label: t`Oldest to newest`,\n sorter: \"createdOn_ASC\"\n },\n {\n label: t`Email A-Z`,\n sorter: \"email_ASC\"\n },\n {\n label: t`Email Z-A`,\n sorter: \"email_DESC\"\n }\n];\n\ninterface FilterUsersCallable {\n (user: Pick<UserItem, \"email\" | \"firstName\" | \"lastName\">): boolean;\n}\n\nconst UsersDataList = () => {\n const [filter, setFilter] = useState(\"\");\n const [sort, setSort] = useState<string>(SORTERS[0].sorter);\n const { identity } = useSecurity();\n const { goToRoute } = useRouter();\n const { showSnackbar } = useSnackbar();\n const { showConfirmation } = useConfirmationDialog({\n dataTestId: \"default-data-list.delete-dialog\",\n title: \"Delete user\",\n message: \"Are you sure you want to delete this user? This action cannot be undone.\"\n });\n\n const filterUsers = useCallback<FilterUsersCallable>(\n ({ email, firstName, lastName }) => {\n return (\n email.toLowerCase().includes(filter) ||\n firstName.toLowerCase().includes(filter) ||\n lastName.toLowerCase().includes(filter)\n );\n },\n [filter]\n );\n\n const sortUsers = useCallback(\n (users: UserItem[]) => {\n if (!sort) {\n return users;\n }\n const [key, sortBy] = deserializeSorters(sort);\n return orderBy(users, [key], [sortBy]);\n },\n [sort]\n );\n\n const { data: listUsers, loading: usersLoading } = useQuery(LIST_USERS);\n\n const [deleteIt, { loading: deleteLoading }] = useMutation(DELETE_USER, {\n refetchQueries: [{ query: LIST_USERS }]\n });\n\n const data = usersLoading && !listUsers ? [] : listUsers.adminUsers.users.data || [];\n const filteredData = filter === \"\" ? data : data.filter(filterUsers);\n const userList = sortUsers(filteredData);\n const id = new URLSearchParams(location.search).get(\"id\");\n\n const deleteItem = useCallback(\n (item: Pick<UserItem, \"id\" | \"email\">) => {\n showConfirmation(async () => {\n const response = await deleteIt({\n variables: item\n });\n\n const error = response?.data?.adminUsers?.deleteUser?.error;\n if (error) {\n return showSnackbar(error.message);\n }\n\n showSnackbar(t`User \"{email}\" deleted.`({ email: item.email }));\n\n if (id === item.id) {\n goToRoute(Routes.Users.List);\n }\n });\n },\n [id]\n );\n\n const usersDataListModalOverlay = useMemo(\n () => (\n <DataListModal.Content>\n <Grid>\n <Grid.Column span={12}>\n <Select\n value={sort}\n onChange={setSort}\n label={t`Sort by`}\n options={SORTERS.map(({ label, sorter: value }) => ({\n label,\n value\n }))}\n />\n </Grid.Column>\n </Grid>\n </DataListModal.Content>\n ),\n [sort]\n );\n\n const loading = usersLoading || deleteLoading;\n\n return (\n <DataList\n title={t`Admin Users`}\n actions={\n <Button\n text={t`New`}\n icon={<AddIcon />}\n size={\"sm\"}\n className={\"ml-xs\"}\n data-testid=\"new-record-button\"\n onClick={() => {\n goToRoute(Routes.Users.List, { new: true });\n }}\n />\n }\n data={userList}\n loading={loading}\n search={\n <SearchUI\n value={filter}\n onChange={setFilter}\n inputPlaceholder={t`Search users...`}\n />\n }\n modalOverlay={usersDataListModalOverlay}\n modalOverlayAction={<DataListModal.Trigger data-testid={\"default-data-list.filter\"} />}\n showOptions={{\n refresh: false\n }}\n >\n {({ data }: { data: UserItem[] }) => (\n <List data-testid=\"default-data-list\">\n {data.map(item => (\n <List.Item\n key={item.id}\n selected={item.id === id}\n title={`${item.firstName} ${item.lastName}`}\n description={item.email}\n icon={\n <Avatar\n image={\n <Avatar.Image\n src={item.avatar ? item.avatar.src : undefined}\n alt={item.firstName}\n />\n }\n fallback={\n <Avatar.Fallback delayMs={0}>\n {item.firstName ? item.firstName.charAt(0) : \"A\"}\n </Avatar.Fallback>\n }\n />\n }\n onClick={() => {\n goToRoute(Routes.Users.List, { id: item.id });\n }}\n actions={\n identity && identity.id !== item.id ? (\n <DeleteIcon\n onClick={() => deleteItem(item)}\n data-testid={\"default-data-list.delete\"}\n />\n ) : (\n <Tooltip\n content={\n <span>{t`You can't delete your own user account.`}</span>\n }\n trigger={<DeleteIcon disabled />}\n />\n )\n }\n />\n ))}\n </List>\n )}\n </DataList>\n );\n};\n\nexport default UsersDataList;\n"],"names":["t","i18n","SORTERS","UsersDataList","filter","setFilter","useState","sort","setSort","identity","useSecurity","goToRoute","useRouter","showSnackbar","useSnackbar","showConfirmation","useConfirmationDialog","filterUsers","useCallback","email","firstName","lastName","sortUsers","users","key","sortBy","deserializeSorters","orderBy","listUsers","usersLoading","useQuery","LIST_USERS","deleteIt","deleteLoading","useMutation","DELETE_USER","data","filteredData","userList","id","URLSearchParams","location","deleteItem","item","response","error","Routes","usersDataListModalOverlay","useMemo","DataListModal","Grid","Select","label","value","loading","DataList","Button","AddIcon","SearchUI","List","Avatar","undefined","DeleteIcon","Tooltip"],"mappings":"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"}
1
+ {"version":3,"file":"admin/ui/views/Users/UsersDataList.js","sources":["../../../../../src/admin/ui/views/Users/UsersDataList.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useState } from \"react\";\nimport orderBy from \"lodash/orderBy.js\";\nimport { useFeature } from \"@webiny/app\";\nimport { Avatar, Button, Grid, Select, Tooltip } from \"@webiny/admin-ui\";\nimport { ReactComponent as AddIcon } from \"@webiny/icons/add.svg\";\nimport { i18n } from \"@webiny/app/i18n/index.js\";\nimport { useSecurity } from \"@webiny/app-admin\";\nimport { List, DataList, DataListModal, DeleteIcon } from \"@webiny/admin-ui\";\nimport { useRouter, useSnackbar, useConfirmationDialog, SearchUI } from \"@webiny/app-admin\";\nimport { ListUsersFeature } from \"~/admin/features/users/listUsers/index.js\";\nimport { DeleteUserFeature } from \"~/admin/features/users/deleteUser/index.js\";\nimport { deserializeSorters } from \"../utils.js\";\nimport { Routes } from \"~/admin/routes.js\";\nimport type { UserItem } from \"~/admin/ui/UserItem.js\";\n\nconst t = i18n.ns(\"app-identity/admin/users/data-list\");\n\nconst SORTERS = [\n {\n label: t`Newest to oldest`,\n sorter: \"createdOn_DESC\"\n },\n {\n label: t`Oldest to newest`,\n sorter: \"createdOn_ASC\"\n },\n {\n label: t`Email A-Z`,\n sorter: \"email_ASC\"\n },\n {\n label: t`Email Z-A`,\n sorter: \"email_DESC\"\n }\n];\n\ninterface FilterUsersCallable {\n (user: Pick<UserItem, \"email\" | \"firstName\" | \"lastName\">): boolean;\n}\n\nconst UsersDataList = () => {\n const [filter, setFilter] = useState(\"\");\n const [sort, setSort] = useState<string>(SORTERS[0].sorter);\n const [users, setUsers] = useState<UserItem[]>([]);\n const [usersLoading, setUsersLoading] = useState(true);\n const [deleteLoading, setDeleteLoading] = useState(false);\n const { identity } = useSecurity();\n const { goToRoute } = useRouter();\n const { showSnackbar } = useSnackbar();\n const { showConfirmation } = useConfirmationDialog({\n dataTestId: \"default-data-list.delete-dialog\",\n title: \"Delete user\",\n message: \"Are you sure you want to delete this user? This action cannot be undone.\"\n });\n\n const { useCase: listUsers } = useFeature(ListUsersFeature);\n const { useCase: deleteUser } = useFeature(DeleteUserFeature);\n\n const fetchUsers = useCallback(() => {\n setUsersLoading(true);\n listUsers.execute().then(data => {\n setUsers((data || []) as UserItem[]);\n setUsersLoading(false);\n });\n }, [listUsers]);\n\n useEffect(() => {\n fetchUsers();\n }, []);\n\n const filterUsers = useCallback<FilterUsersCallable>(\n ({ email, firstName, lastName }) => {\n return (\n email.toLowerCase().includes(filter) ||\n firstName.toLowerCase().includes(filter) ||\n lastName.toLowerCase().includes(filter)\n );\n },\n [filter]\n );\n\n const sortUsers = useCallback(\n (list: UserItem[]) => {\n if (!sort) {\n return list;\n }\n const [key, sortBy] = deserializeSorters(sort);\n return orderBy(list, [key], [sortBy]);\n },\n [sort]\n );\n\n const filteredData = filter === \"\" ? users : users.filter(filterUsers);\n const userList = sortUsers(filteredData);\n const id = new URLSearchParams(location.search).get(\"id\");\n\n const deleteItem = useCallback(\n (item: Pick<UserItem, \"id\" | \"email\">) => {\n showConfirmation(async () => {\n setDeleteLoading(true);\n try {\n await deleteUser.execute({ id: item.id });\n showSnackbar(t`User \"{email}\" deleted.`({ email: item.email }));\n fetchUsers();\n\n if (id === item.id) {\n goToRoute(Routes.Users.List);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n showSnackbar(message);\n } finally {\n setDeleteLoading(false);\n }\n });\n },\n [id, deleteUser, fetchUsers]\n );\n\n const usersDataListModalOverlay = useMemo(\n () => (\n <DataListModal.Content>\n <Grid>\n <Grid.Column span={12}>\n <Select\n value={sort}\n onChange={setSort}\n label={t`Sort by`}\n options={SORTERS.map(({ label, sorter: value }) => ({\n label,\n value\n }))}\n />\n </Grid.Column>\n </Grid>\n </DataListModal.Content>\n ),\n [sort]\n );\n\n const loading = usersLoading || deleteLoading;\n\n return (\n <DataList\n title={t`Admin Users`}\n actions={\n <Button\n text={t`New`}\n icon={<AddIcon />}\n size={\"sm\"}\n className={\"ml-xs\"}\n data-testid=\"new-record-button\"\n onClick={() => {\n goToRoute(Routes.Users.List, { new: true });\n }}\n />\n }\n data={userList}\n loading={loading}\n search={\n <SearchUI\n value={filter}\n onChange={setFilter}\n inputPlaceholder={t`Search users...`}\n />\n }\n modalOverlay={usersDataListModalOverlay}\n modalOverlayAction={<DataListModal.Trigger data-testid={\"default-data-list.filter\"} />}\n showOptions={{\n refresh: false\n }}\n >\n {({ data }: { data: UserItem[] }) => (\n <List data-testid=\"default-data-list\">\n {data.map(item => (\n <List.Item\n key={item.id}\n selected={item.id === id}\n title={`${item.firstName} ${item.lastName}`}\n description={item.email}\n icon={\n <Avatar\n image={\n <Avatar.Image\n src={item.avatar ? item.avatar.src : undefined}\n alt={item.firstName}\n />\n }\n fallback={\n <Avatar.Fallback delayMs={0}>\n {item.firstName ? item.firstName.charAt(0) : \"A\"}\n </Avatar.Fallback>\n }\n />\n }\n onClick={() => {\n goToRoute(Routes.Users.List, { id: item.id });\n }}\n actions={\n identity && identity.id !== item.id ? (\n <DeleteIcon\n onClick={() => deleteItem(item)}\n data-testid={\"default-data-list.delete\"}\n />\n ) : (\n <Tooltip\n content={\n <span>{t`You can't delete your own user account.`}</span>\n }\n trigger={<DeleteIcon disabled />}\n />\n )\n }\n />\n ))}\n </List>\n )}\n </DataList>\n );\n};\n\nexport default UsersDataList;\n"],"names":["t","i18n","SORTERS","UsersDataList","filter","setFilter","useState","sort","setSort","users","setUsers","usersLoading","setUsersLoading","deleteLoading","setDeleteLoading","identity","useSecurity","goToRoute","useRouter","showSnackbar","useSnackbar","showConfirmation","useConfirmationDialog","listUsers","useFeature","ListUsersFeature","deleteUser","DeleteUserFeature","fetchUsers","useCallback","data","useEffect","filterUsers","email","firstName","lastName","sortUsers","list","key","sortBy","deserializeSorters","orderBy","filteredData","userList","id","URLSearchParams","location","deleteItem","item","Routes","error","message","Error","usersDataListModalOverlay","useMemo","DataListModal","Grid","Select","label","value","loading","DataList","Button","AddIcon","SearchUI","List","Avatar","undefined","DeleteIcon","Tooltip"],"mappings":"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"}
@@ -39,7 +39,7 @@ const UserForm = ({ teams })=>{
39
39
  onClick: userForm.createUser
40
40
  })
41
41
  });
42
- const isSelf = userForm.user.id === identity.id;
42
+ const isSelf = userForm.user?.id === identity.id;
43
43
  const isDisabled = isExternal || isSelf;
44
44
  return /*#__PURE__*/ react.createElement(Form, {
45
45
  data: userForm.user,
@@ -1 +1 @@
1
- {"version":3,"file":"admin/ui/views/Users/UsersForm.js","sources":["../../../../../src/admin/ui/views/Users/UsersForm.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport { i18n } from \"@webiny/app/i18n/index.js\";\nimport { Form } from \"@webiny/form\";\nimport { validation } from \"@webiny/validation\";\nimport {\n SimpleForm,\n SimpleFormHeader,\n SimpleFormFooter,\n SimpleFormContent,\n EmptyView,\n RolesMultiAutocomplete,\n TeamsMultiAutocomplete,\n useAuthentication,\n useRouter\n} from \"@webiny/app-admin\";\nimport { ReactComponent as AddIcon } from \"@webiny/icons/add.svg\";\nimport { ReactComponent as SecurityIcon } from \"@webiny/icons/gpp_maybe.svg\";\nimport { ReactComponent as SecurityTeamsIcon } from \"@webiny/icons/admin_panel_settings.svg\";\nimport { ReactComponent as SettingsIcon } from \"@webiny/icons/settings.svg\";\nimport { Accordion, Alert, OverlayLoader, Button, Input, Grid, Link } from \"@webiny/admin-ui\";\nimport { config as appConfig } from \"@webiny/app/config.js\";\nimport { AvatarImage } from \"../../components/AvatarImage/index.js\";\nimport { useUserForm } from \"~/admin/ui/views/Users/hooks/useUserForm.js\";\nimport { usePasswordValidator } from \"~/admin/presentation/shared/usePasswordValidator.js\";\nimport { Routes } from \"~/admin/routes.js\";\n\nconst t = i18n.ns(\"app-security-admin-users/account-form\");\n\nexport interface UserFormProps {\n teams: boolean;\n}\n\nexport const UserForm = ({ teams }: UserFormProps) => {\n const { identity } = useAuthentication();\n const userForm = useUserForm();\n const passwordValidator = usePasswordValidator();\n const { getLink } = useRouter();\n\n const isExternal = userForm.user?.external === true;\n const formTitle = userForm.isNewUser ? \"New User\" : userForm.fullName;\n const isNewUser = userForm.isNewUser;\n\n const emailIsDisabled = appConfig.getKey(\n \"ADMIN_USER_CAN_CHANGE_EMAIL\",\n process.env.REACT_APP_ADMIN_USER_CAN_CHANGE_EMAIL === \"false\"\n );\n\n const groupValidators = useMemo(() => {\n return teams ? [] : [validation.create(\"required\")];\n }, [teams]);\n\n const accountLink = getLink(Routes.Users.Account);\n\n // Render \"No content\" selected view.\n if (userForm.showEmptyView) {\n return (\n <EmptyView\n icon={<SettingsIcon />}\n title={t`Click on the left side list to display user details or create a...`}\n action={\n <Button\n icon={<AddIcon />}\n text={t`New User`}\n data-testid=\"new-record-button\"\n onClick={userForm.createUser}\n />\n }\n />\n );\n }\n\n const isSelf = userForm.user.id === identity.id;\n const isDisabled = isExternal || isSelf;\n\n return (\n <Form data={userForm.user} onSubmit={userForm.onSubmit}>\n {({ data, form, Bind }) => (\n <SimpleForm size={\"lg\"}>\n {userForm.loading && <OverlayLoader />}\n <div className={\"mb-xl\"}>\n <Bind name=\"avatar\">\n <AvatarImage round disabled={isDisabled} />\n </Bind>\n </div>\n <SimpleFormHeader title={formTitle} />\n <SimpleFormContent>\n {isExternal && (\n <Grid className={\"mb-lg\"}>\n <Grid.Column span={12}>\n <Alert type={\"info\"} title={\"External User\"}>\n This user is an external user and cannot be edited.\n </Alert>\n </Grid.Column>\n </Grid>\n )}\n {isSelf && (\n <Grid className={\"mb-lg\"}>\n <Grid.Column span={12}>\n <Alert type={\"info\"} title={\"Own Profile\"}>\n You cannot edit your own profile using this form. Please use\n the <Link to={accountLink}>account settings</Link> instead.\n </Alert>\n </Grid.Column>\n </Grid>\n )}\n <Accordion variant={\"underline\"}>\n <Accordion.Item\n title={\"Bio\"}\n description={\"Account information\"}\n icon={<SettingsIcon />}\n defaultOpen={true}\n >\n <Grid>\n <Grid.Column span={12}>\n <Bind\n name=\"firstName\"\n validators={validation.create(\"required\")}\n >\n <Input\n label={t`First Name`}\n disabled={isDisabled}\n data-testid=\"account.firstname\"\n />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n <Bind\n name=\"lastName\"\n validators={validation.create(\"required\")}\n >\n <Input\n label={t`Last Name`}\n disabled={isDisabled}\n data-testid=\"account.lastname\"\n />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n <Bind\n name=\"email\"\n validators={validation.create(\"required,email\")}\n >\n <Input\n value={data.email}\n label={t`Email`}\n disabled={emailIsDisabled || isDisabled}\n data-testid=\"account.email\"\n autoComplete=\"new-password\"\n description={\n \"Email is your unique identifier used to login!\"\n }\n />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n <Bind name=\"password\" validators={passwordValidator}>\n <Input\n autoComplete=\"new-password\"\n disabled={isDisabled}\n description={\n data.id && \"Type a new password to reset it.\"\n }\n type=\"password\"\n label={\"Password\"}\n data-testid=\"account.password\"\n />\n </Bind>\n </Grid.Column>\n </Grid>\n </Accordion.Item>\n <Accordion.Item\n title={\"Roles\"}\n description={\"Assign to security roles\"}\n icon={<SecurityIcon />}\n >\n <Grid>\n <Grid.Column span={12}>\n <Bind name={\"roles\"} validators={groupValidators}>\n {({ value, onChange, validation }) => (\n <RolesMultiAutocomplete\n values={value}\n onChange={onChange}\n validation={validation}\n label={\"Roles\"}\n data-testid=\"roles-autocomplete\"\n disabled={isDisabled}\n />\n )}\n </Bind>\n </Grid.Column>\n </Grid>\n </Accordion.Item>\n {teams ? (\n <Accordion.Item\n title={\"Teams\"}\n description={\"Assign to teams\"}\n icon={<SecurityTeamsIcon />}\n >\n <Grid>\n <Grid.Column span={12}>\n <Bind name={\"teams\"}>\n {({ value, onChange, validation }) => (\n <TeamsMultiAutocomplete\n values={value}\n onChange={onChange}\n validation={validation}\n label={\"Teams\"}\n data-testid=\"teams-autocomplete\"\n disabled={isDisabled}\n />\n )}\n </Bind>\n </Grid.Column>\n </Grid>\n </Accordion.Item>\n ) : null}\n </Accordion>\n </SimpleFormContent>\n <SimpleFormFooter data-testid={\"form-footer\"}>\n <Button\n variant={\"secondary\"}\n text={t`Cancel`}\n onClick={userForm.cancelEditing}\n />\n <Button\n variant={\"primary\"}\n text={isNewUser ? t`Create user` : t`Update user`}\n disabled={isDisabled}\n onClick={form.submit}\n />\n </SimpleFormFooter>\n </SimpleForm>\n )}\n </Form>\n );\n};\n"],"names":["t","i18n","UserForm","teams","identity","useAuthentication","userForm","useUserForm","passwordValidator","usePasswordValidator","getLink","useRouter","isExternal","formTitle","isNewUser","emailIsDisabled","appConfig","process","groupValidators","useMemo","validation","accountLink","Routes","EmptyView","SettingsIcon","Button","AddIcon","isSelf","isDisabled","Form","data","form","Bind","SimpleForm","OverlayLoader","AvatarImage","SimpleFormHeader","SimpleFormContent","Grid","Alert","Link","Accordion","Input","SecurityIcon","value","onChange","RolesMultiAutocomplete","SecurityTeamsIcon","TeamsMultiAutocomplete","SimpleFormFooter"],"mappings":";;;;;;;;;;;;;;;AA0BA,MAAMA,IAAIC,KAAK,EAAE,CAAC;AAMX,MAAMC,WAAW,CAAC,EAAEC,KAAK,EAAiB;IAC7C,MAAM,EAAEC,QAAQ,EAAE,GAAGC;IACrB,MAAMC,WAAWC;IACjB,MAAMC,oBAAoBC;IAC1B,MAAM,EAAEC,OAAO,EAAE,GAAGC;IAEpB,MAAMC,aAAaN,SAAS,IAAI,EAAE,aAAa;IAC/C,MAAMO,YAAYP,SAAS,SAAS,GAAG,aAAaA,SAAS,QAAQ;IACrE,MAAMQ,YAAYR,SAAS,SAAS;IAEpC,MAAMS,kBAAkBC,OAAAA,MAAgB,CACpC,+BACAC,AAAsD,YAAtDA,QAAQ,GAAG,CAAC,qCAAqC;IAGrD,MAAMC,kBAAkBC,QAAQ,IACrBhB,QAAQ,EAAE,GAAG;YAACiB,sBAAAA,MAAiB,CAAC;SAAY,EACpD;QAACjB;KAAM;IAEV,MAAMkB,cAAcX,QAAQY,OAAO,KAAK,CAAC,OAAO;IAGhD,IAAIhB,SAAS,aAAa,EACtB,OAAO,WAAP,GACI,oBAACiB,WAASA;QACN,oBAAM,oBAACC,6BAAYA;QACnB,OAAOxB,CAAC,CAAC,kEAAkE,CAAC;QAC5E,sBACI,oBAACyB,QAAMA;YACH,oBAAM,oBAACC,gBAAOA;YACd,MAAM1B,CAAC,CAAC,QAAQ,CAAC;YACjB,eAAY;YACZ,SAASM,SAAS,UAAU;;;IAOhD,MAAMqB,SAASrB,SAAS,IAAI,CAAC,EAAE,KAAKF,SAAS,EAAE;IAC/C,MAAMwB,aAAahB,cAAce;IAEjC,OAAO,WAAP,GACI,oBAACE,MAAIA;QAAC,MAAMvB,SAAS,IAAI;QAAE,UAAUA,SAAS,QAAQ;OACjD,CAAC,EAAEwB,IAAI,EAAEC,IAAI,EAAEC,IAAI,EAAE,iBAClB,oBAACC,YAAUA;YAAC,MAAM;WACb3B,SAAS,OAAO,IAAI,WAAJ,GAAI,oBAAC4B,eAAaA,OAAAA,WAAAA,GACnC,oBAAC;YAAI,WAAW;yBACZ,oBAACF,MAAAA;YAAK,MAAK;yBACP,oBAACG,aAAWA;YAAC;YAAM,UAAUP;4BAGrC,oBAACQ,kBAAgBA;YAAC,OAAOvB;0BACzB,oBAACwB,mBAAiBA,MACbzB,cAAc,WAAdA,GACG,oBAAC0B,MAAIA;YAAC,WAAW;yBACb,oBAACA,KAAK,MAAM;YAAC,MAAM;yBACf,oBAACC,OAAKA;YAAC,MAAM;YAAQ,OAAO;WAAiB,0DAMxDZ,UAAU,WAAVA,GACG,oBAACW,MAAIA;YAAC,WAAW;yBACb,oBAACA,KAAK,MAAM;YAAC,MAAM;yBACf,oBAACC,OAAKA;YAAC,MAAM;YAAQ,OAAO;WAAe,mFAEnC,oBAACC,MAAIA;YAAC,IAAInB;WAAa,qBAAuB,8BAKlE,oBAACoB,WAASA;YAAC,SAAS;yBAChB,oBAACA,UAAU,IAAI;YACX,OAAO;YACP,aAAa;YACb,oBAAM,oBAACjB,6BAAYA;YACnB,aAAa;yBAEb,oBAACc,MAAIA,MAAAA,WAAAA,GACD,oBAACA,KAAK,MAAM;YAAC,MAAM;yBACf,oBAACN,MAAAA;YACG,MAAK;YACL,YAAYZ,sBAAAA,MAAiB,CAAC;yBAE9B,oBAACsB,OAAKA;YACF,OAAO1C,CAAC,CAAC,UAAU,CAAC;YACpB,UAAU4B;YACV,eAAY;4BAIxB,oBAACU,KAAK,MAAM;YAAC,MAAM;yBACf,oBAACN,MAAAA;YACG,MAAK;YACL,YAAYZ,sBAAAA,MAAiB,CAAC;yBAE9B,oBAACsB,OAAKA;YACF,OAAO1C,CAAC,CAAC,SAAS,CAAC;YACnB,UAAU4B;YACV,eAAY;4BAIxB,oBAACU,KAAK,MAAM;YAAC,MAAM;yBACf,oBAACN,MAAAA;YACG,MAAK;YACL,YAAYZ,sBAAAA,MAAiB,CAAC;yBAE9B,oBAACsB,OAAKA;YACF,OAAOZ,KAAK,KAAK;YACjB,OAAO9B,CAAC,CAAC,KAAK,CAAC;YACf,UAAUe,mBAAmBa;YAC7B,eAAY;YACZ,cAAa;YACb,aACI;4BAKhB,oBAACU,KAAK,MAAM;YAAC,MAAM;yBACf,oBAACN,MAAAA;YAAK,MAAK;YAAW,YAAYxB;yBAC9B,oBAACkC,OAAKA;YACF,cAAa;YACb,UAAUd;YACV,aACIE,KAAK,EAAE,IAAI;YAEf,MAAK;YACL,OAAO;YACP,eAAY;8BAMhC,oBAACW,UAAU,IAAI;YACX,OAAO;YACP,aAAa;YACb,oBAAM,oBAACE,8BAAYA;yBAEnB,oBAACL,MAAIA,MAAAA,WAAAA,GACD,oBAACA,KAAK,MAAM;YAAC,MAAM;yBACf,oBAACN,MAAAA;YAAK,MAAM;YAAS,YAAYd;WAC5B,CAAC,EAAE0B,KAAK,EAAEC,QAAQ,EAAEzB,UAAU,EAAE,iBAC7B,oBAAC0B,wBAAsBA;gBACnB,QAAQF;gBACR,UAAUC;gBACV,YAAYzB;gBACZ,OAAO;gBACP,eAAY;gBACZ,UAAUQ;oBAOjCzB,QAAQ,WAARA,GACG,oBAACsC,UAAU,IAAI;YACX,OAAO;YACP,aAAa;YACb,oBAAM,oBAACM,yCAAiBA;yBAExB,oBAACT,MAAIA,MAAAA,WAAAA,GACD,oBAACA,KAAK,MAAM;YAAC,MAAM;yBACf,oBAACN,MAAAA;YAAK,MAAM;WACP,CAAC,EAAEY,KAAK,EAAEC,QAAQ,EAAEzB,UAAU,EAAE,iBAC7B,oBAAC4B,wBAAsBA;gBACnB,QAAQJ;gBACR,UAAUC;gBACV,YAAYzB;gBACZ,OAAO;gBACP,eAAY;gBACZ,UAAUQ;qBAOlC,sBAGZ,oBAACqB,kBAAgBA;YAAC,eAAa;yBAC3B,oBAACxB,QAAMA;YACH,SAAS;YACT,MAAMzB,CAAC,CAAC,MAAM,CAAC;YACf,SAASM,SAAS,aAAa;0BAEnC,oBAACmB,QAAMA;YACH,SAAS;YACT,MAAMX,YAAYd,CAAC,CAAC,WAAW,CAAC,GAAGA,CAAC,CAAC,WAAW,CAAC;YACjD,UAAU4B;YACV,SAASG,KAAK,MAAM;;AAOhD"}
1
+ {"version":3,"file":"admin/ui/views/Users/UsersForm.js","sources":["../../../../../src/admin/ui/views/Users/UsersForm.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport { i18n } from \"@webiny/app/i18n/index.js\";\nimport { Form } from \"@webiny/form\";\nimport { validation } from \"@webiny/validation\";\nimport {\n SimpleForm,\n SimpleFormHeader,\n SimpleFormFooter,\n SimpleFormContent,\n EmptyView,\n RolesMultiAutocomplete,\n TeamsMultiAutocomplete,\n useAuthentication,\n useRouter\n} from \"@webiny/app-admin\";\nimport { ReactComponent as AddIcon } from \"@webiny/icons/add.svg\";\nimport { ReactComponent as SecurityIcon } from \"@webiny/icons/gpp_maybe.svg\";\nimport { ReactComponent as SecurityTeamsIcon } from \"@webiny/icons/admin_panel_settings.svg\";\nimport { ReactComponent as SettingsIcon } from \"@webiny/icons/settings.svg\";\nimport { Accordion, Alert, OverlayLoader, Button, Input, Grid, Link } from \"@webiny/admin-ui\";\nimport { config as appConfig } from \"@webiny/app/config.js\";\nimport { AvatarImage } from \"../../components/AvatarImage/index.js\";\nimport { useUserForm } from \"~/admin/ui/views/Users/hooks/useUserForm.js\";\nimport { usePasswordValidator } from \"~/admin/presentation/shared/usePasswordValidator.js\";\nimport { Routes } from \"~/admin/routes.js\";\n\nconst t = i18n.ns(\"app-security-admin-users/account-form\");\n\nexport interface UserFormProps {\n teams: boolean;\n}\n\nexport const UserForm = ({ teams }: UserFormProps) => {\n const { identity } = useAuthentication();\n const userForm = useUserForm();\n const passwordValidator = usePasswordValidator();\n const { getLink } = useRouter();\n\n const isExternal = userForm.user?.external === true;\n const formTitle = userForm.isNewUser ? \"New User\" : userForm.fullName;\n const isNewUser = userForm.isNewUser;\n\n const emailIsDisabled = appConfig.getKey(\n \"ADMIN_USER_CAN_CHANGE_EMAIL\",\n process.env.REACT_APP_ADMIN_USER_CAN_CHANGE_EMAIL === \"false\"\n );\n\n const groupValidators = useMemo(() => {\n return teams ? [] : [validation.create(\"required\")];\n }, [teams]);\n\n const accountLink = getLink(Routes.Users.Account);\n\n // Render \"No content\" selected view.\n if (userForm.showEmptyView) {\n return (\n <EmptyView\n icon={<SettingsIcon />}\n title={t`Click on the left side list to display user details or create a...`}\n action={\n <Button\n icon={<AddIcon />}\n text={t`New User`}\n data-testid=\"new-record-button\"\n onClick={userForm.createUser}\n />\n }\n />\n );\n }\n\n const isSelf = userForm.user?.id === identity.id;\n const isDisabled = isExternal || isSelf;\n\n return (\n <Form data={userForm.user} onSubmit={userForm.onSubmit}>\n {({ data, form, Bind }) => (\n <SimpleForm size={\"lg\"}>\n {userForm.loading && <OverlayLoader />}\n <div className={\"mb-xl\"}>\n <Bind name=\"avatar\">\n <AvatarImage round disabled={isDisabled} />\n </Bind>\n </div>\n <SimpleFormHeader title={formTitle} />\n <SimpleFormContent>\n {isExternal && (\n <Grid className={\"mb-lg\"}>\n <Grid.Column span={12}>\n <Alert type={\"info\"} title={\"External User\"}>\n This user is an external user and cannot be edited.\n </Alert>\n </Grid.Column>\n </Grid>\n )}\n {isSelf && (\n <Grid className={\"mb-lg\"}>\n <Grid.Column span={12}>\n <Alert type={\"info\"} title={\"Own Profile\"}>\n You cannot edit your own profile using this form. Please use\n the <Link to={accountLink}>account settings</Link> instead.\n </Alert>\n </Grid.Column>\n </Grid>\n )}\n <Accordion variant={\"underline\"}>\n <Accordion.Item\n title={\"Bio\"}\n description={\"Account information\"}\n icon={<SettingsIcon />}\n defaultOpen={true}\n >\n <Grid>\n <Grid.Column span={12}>\n <Bind\n name=\"firstName\"\n validators={validation.create(\"required\")}\n >\n <Input\n label={t`First Name`}\n disabled={isDisabled}\n data-testid=\"account.firstname\"\n />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n <Bind\n name=\"lastName\"\n validators={validation.create(\"required\")}\n >\n <Input\n label={t`Last Name`}\n disabled={isDisabled}\n data-testid=\"account.lastname\"\n />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n <Bind\n name=\"email\"\n validators={validation.create(\"required,email\")}\n >\n <Input\n value={data.email}\n label={t`Email`}\n disabled={emailIsDisabled || isDisabled}\n data-testid=\"account.email\"\n autoComplete=\"new-password\"\n description={\n \"Email is your unique identifier used to login!\"\n }\n />\n </Bind>\n </Grid.Column>\n <Grid.Column span={12}>\n <Bind name=\"password\" validators={passwordValidator}>\n <Input\n autoComplete=\"new-password\"\n disabled={isDisabled}\n description={\n data.id && \"Type a new password to reset it.\"\n }\n type=\"password\"\n label={\"Password\"}\n data-testid=\"account.password\"\n />\n </Bind>\n </Grid.Column>\n </Grid>\n </Accordion.Item>\n <Accordion.Item\n title={\"Roles\"}\n description={\"Assign to security roles\"}\n icon={<SecurityIcon />}\n >\n <Grid>\n <Grid.Column span={12}>\n <Bind name={\"roles\"} validators={groupValidators}>\n {({ value, onChange, validation }) => (\n <RolesMultiAutocomplete\n values={value}\n onChange={onChange}\n validation={validation}\n label={\"Roles\"}\n data-testid=\"roles-autocomplete\"\n disabled={isDisabled}\n />\n )}\n </Bind>\n </Grid.Column>\n </Grid>\n </Accordion.Item>\n {teams ? (\n <Accordion.Item\n title={\"Teams\"}\n description={\"Assign to teams\"}\n icon={<SecurityTeamsIcon />}\n >\n <Grid>\n <Grid.Column span={12}>\n <Bind name={\"teams\"}>\n {({ value, onChange, validation }) => (\n <TeamsMultiAutocomplete\n values={value}\n onChange={onChange}\n validation={validation}\n label={\"Teams\"}\n data-testid=\"teams-autocomplete\"\n disabled={isDisabled}\n />\n )}\n </Bind>\n </Grid.Column>\n </Grid>\n </Accordion.Item>\n ) : null}\n </Accordion>\n </SimpleFormContent>\n <SimpleFormFooter data-testid={\"form-footer\"}>\n <Button\n variant={\"secondary\"}\n text={t`Cancel`}\n onClick={userForm.cancelEditing}\n />\n <Button\n variant={\"primary\"}\n text={isNewUser ? t`Create user` : t`Update user`}\n disabled={isDisabled}\n onClick={form.submit}\n />\n </SimpleFormFooter>\n </SimpleForm>\n )}\n </Form>\n );\n};\n"],"names":["t","i18n","UserForm","teams","identity","useAuthentication","userForm","useUserForm","passwordValidator","usePasswordValidator","getLink","useRouter","isExternal","formTitle","isNewUser","emailIsDisabled","appConfig","process","groupValidators","useMemo","validation","accountLink","Routes","EmptyView","SettingsIcon","Button","AddIcon","isSelf","isDisabled","Form","data","form","Bind","SimpleForm","OverlayLoader","AvatarImage","SimpleFormHeader","SimpleFormContent","Grid","Alert","Link","Accordion","Input","SecurityIcon","value","onChange","RolesMultiAutocomplete","SecurityTeamsIcon","TeamsMultiAutocomplete","SimpleFormFooter"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
1
  import react from "react";
2
- import { LeftPanel, RightPanel, SplitView, useWcp } from "@webiny/app-admin";
2
+ import { LeftPanel, RightPanel, SplitView, useFeatureFlags } from "@webiny/app-admin";
3
3
  import UsersDataList from "./UsersDataList.js";
4
4
  import { UserForm } from "./UsersForm.js";
5
5
  const UsersView = ()=>{
6
- const wcp = useWcp();
7
- const teams = wcp.canUseTeams();
6
+ const featureFlags = useFeatureFlags();
7
+ const teams = featureFlags.isEnabled("advancedAccessControlLayer.teams");
8
8
  return /*#__PURE__*/ react.createElement(SplitView, null, /*#__PURE__*/ react.createElement(LeftPanel, null, /*#__PURE__*/ react.createElement(UsersDataList, null)), /*#__PURE__*/ react.createElement(RightPanel, null, /*#__PURE__*/ react.createElement(UserForm, {
9
9
  teams: teams
10
10
  })));
@@ -1 +1 @@
1
- {"version":3,"file":"admin/ui/views/Users/UsersView.js","sources":["../../../../../src/admin/ui/views/Users/UsersView.tsx"],"sourcesContent":["import React from \"react\";\nimport { LeftPanel, RightPanel, SplitView } from \"@webiny/app-admin\";\nimport UsersDataList from \"~/admin/ui/views/Users/UsersDataList.js\";\nimport { useWcp } from \"@webiny/app-admin\";\nimport { UserForm } from \"./UsersForm.js\";\n\nexport const UsersView = () => {\n const wcp = useWcp();\n\n const teams = wcp.canUseTeams();\n\n return (\n <SplitView>\n <LeftPanel>\n <UsersDataList />\n </LeftPanel>\n <RightPanel>\n <UserForm teams={teams} />\n </RightPanel>\n </SplitView>\n );\n};\n"],"names":["UsersView","wcp","useWcp","teams","SplitView","LeftPanel","UsersDataList","RightPanel","UserForm"],"mappings":";;;;AAMO,MAAMA,YAAY;IACrB,MAAMC,MAAMC;IAEZ,MAAMC,QAAQF,IAAI,WAAW;IAE7B,OAAO,WAAP,GACI,oBAACG,WAASA,MAAAA,WAAAA,GACN,oBAACC,WAASA,MAAAA,WAAAA,GACN,oBAACC,eAAaA,QAAAA,WAAAA,GAElB,oBAACC,YAAUA,MAAAA,WAAAA,GACP,oBAACC,UAAQA;QAAC,OAAOL;;AAIjC"}
1
+ {"version":3,"file":"admin/ui/views/Users/UsersView.js","sources":["../../../../../src/admin/ui/views/Users/UsersView.tsx"],"sourcesContent":["import React from \"react\";\nimport { LeftPanel, RightPanel, SplitView } from \"@webiny/app-admin\";\nimport UsersDataList from \"~/admin/ui/views/Users/UsersDataList.js\";\nimport { useFeatureFlags } from \"@webiny/app-admin\";\nimport { UserForm } from \"./UsersForm.js\";\n\nexport const UsersView = () => {\n const featureFlags = useFeatureFlags();\n\n const teams = featureFlags.isEnabled(\"advancedAccessControlLayer.teams\");\n\n return (\n <SplitView>\n <LeftPanel>\n <UsersDataList />\n </LeftPanel>\n <RightPanel>\n <UserForm teams={teams} />\n </RightPanel>\n </SplitView>\n );\n};\n"],"names":["UsersView","featureFlags","useFeatureFlags","teams","SplitView","LeftPanel","UsersDataList","RightPanel","UserForm"],"mappings":";;;;AAMO,MAAMA,YAAY;IACrB,MAAMC,eAAeC;IAErB,MAAMC,QAAQF,aAAa,SAAS,CAAC;IAErC,OAAO,WAAP,GACI,oBAACG,WAASA,MAAAA,WAAAA,GACN,oBAACC,WAASA,MAAAA,WAAAA,GACN,oBAACC,eAAaA,QAAAA,WAAAA,GAElB,oBAACC,YAAUA,MAAAA,WAAAA,GACP,oBAACC,UAAQA;QAAC,OAAOL;;AAIjC"}
@@ -1,4 +1,4 @@
1
- export type UseUserForm = ReturnType<typeof useUserForm>;
1
+ import type { IGetUserGatewayResult } from "../../../../../admin/features/users/getUser/abstractions/GetUserGateway.js";
2
2
  interface SubmitUserCallableParams {
3
3
  id?: string;
4
4
  firstName: string;
@@ -16,7 +16,7 @@ interface SubmitUserCallable {
16
16
  export declare function useUserForm(): {
17
17
  id: string | undefined;
18
18
  loading: boolean;
19
- user: any;
19
+ user: IGetUserGatewayResult | undefined;
20
20
  onSubmit: SubmitUserCallable;
21
21
  isNewUser: boolean;
22
22
  fullName: string;
@@ -1,108 +1,90 @@
1
- import { useCallback } from "react";
2
- import { useMutation, useQuery } from "@apollo/react-hooks";
1
+ import { useCallback, useEffect, useState } from "react";
3
2
  import isEmpty from "lodash/isEmpty.js";
4
- import { useRoute, useRouter, useWcp } from "@webiny/app-admin";
5
- import { CREATE_USER, LIST_USERS, READ_USER, UPDATE_USER } from "../graphql.js";
6
3
  import omit from "lodash/omit.js";
4
+ import { useFeature } from "@webiny/app";
5
+ import { useRoute, useRouter } from "@webiny/app-admin";
6
+ import { GetUserFeature } from "../../../../features/users/getUser/index.js";
7
+ import { CreateUserFeature } from "../../../../features/users/createUser/index.js";
8
+ import { UpdateUserFeature } from "../../../../features/users/updateUser/index.js";
7
9
  import { Routes } from "../../../../routes.js";
8
10
  import { useToast } from "@webiny/admin-ui";
9
11
  function useUserForm() {
10
12
  const { goToRoute } = useRouter();
11
13
  const { route } = useRoute(Routes.Users.List);
12
14
  const toast = useToast();
13
- const wcp = useWcp();
14
- const teams = wcp.canUseTeams();
15
+ const { useCase: getUser } = useFeature(GetUserFeature);
16
+ const { useCase: createUser } = useFeature(CreateUserFeature);
17
+ const { useCase: updateUser } = useFeature(UpdateUserFeature);
15
18
  const id = route.params.id;
16
19
  const newUser = true === route.params.new;
17
- const { data, loading: userLoading } = useQuery(READ_USER({
18
- teams
19
- }), {
20
- variables: {
20
+ const [user, setUser] = useState(void 0);
21
+ const [userLoading, setUserLoading] = useState(false);
22
+ const [mutationLoading, setMutationLoading] = useState(false);
23
+ useEffect(()=>{
24
+ if (!id) return;
25
+ setUserLoading(true);
26
+ getUser.execute({
21
27
  id
22
- },
23
- skip: !id,
24
- onCompleted: (data)=>{
25
- if (!data) return;
26
- const { error } = data.adminUsers.user;
27
- if (error) {
28
- goToRoute(Routes.Users.List);
29
- toast.showWarningToast({
30
- title: "Error loading user profile",
31
- description: error.message,
32
- duration: 1 / 0
33
- });
34
- }
35
- }
36
- });
37
- const [create, { loading: createLoading }] = useMutation(CREATE_USER, {
38
- refetchQueries: [
39
- {
40
- query: LIST_USERS
41
- }
42
- ]
43
- });
44
- const [update, { loading: updateLoading }] = useMutation(UPDATE_USER({
45
- teams
46
- }), {
47
- refetchQueries: [
48
- {
49
- query: LIST_USERS
50
- }
51
- ]
52
- });
53
- const loading = userLoading || createLoading || updateLoading;
28
+ }).then((data)=>{
29
+ setUser(data);
30
+ setUserLoading(false);
31
+ }).catch((error)=>{
32
+ goToRoute(Routes.Users.List);
33
+ toast.showWarningToast({
34
+ title: "Error loading user profile",
35
+ description: error.message,
36
+ duration: 1 / 0
37
+ });
38
+ setUserLoading(false);
39
+ });
40
+ }, [
41
+ id
42
+ ]);
43
+ const loading = userLoading || mutationLoading;
54
44
  const onSubmit = useCallback(async (data)=>{
55
- const { id, ...rest } = data;
56
- const [operation, args] = newUser ? [
57
- create,
58
- {
59
- variables: {
45
+ setMutationLoading(true);
46
+ try {
47
+ if (newUser) {
48
+ const resultUser = await createUser.execute({
60
49
  data
61
- }
62
- }
63
- ] : [
64
- update,
65
- {
66
- variables: {
67
- id,
50
+ });
51
+ goToRoute(Routes.Users.List, {
52
+ id: resultUser.id
53
+ });
54
+ } else {
55
+ const { id: userId, ...rest } = data;
56
+ await updateUser.execute({
57
+ id: userId,
68
58
  data: omit(rest, [
69
59
  "external"
70
60
  ])
71
- }
61
+ });
72
62
  }
73
- ];
74
- const result = await operation(args);
75
- const { data: user, error } = result.data.adminUsers.user;
76
- if (error) return void toast.showWarningToast({
77
- title: "Error updating user profile",
78
- description: error.message,
79
- duration: 1 / 0
80
- });
81
- if (newUser) goToRoute(Routes.Users.List, {
82
- id: user.id
83
- });
84
- toast.showSuccessToast({
85
- title: "User saved successfully."
86
- });
63
+ toast.showSuccessToast({
64
+ title: "User saved successfully."
65
+ });
66
+ } catch (error) {
67
+ const message = error instanceof Error ? error.message : "Unknown error";
68
+ toast.showWarningToast({
69
+ title: "Error updating user profile",
70
+ description: message,
71
+ duration: 1 / 0
72
+ });
73
+ } finally{
74
+ setMutationLoading(false);
75
+ }
87
76
  }, [
88
77
  id,
89
78
  newUser
90
79
  ]);
91
- const user = userLoading ? {} : data ? data.adminUsers.user.data : {};
92
80
  const showEmptyView = !newUser && !userLoading && isEmpty(user);
93
81
  return {
94
82
  id,
95
83
  loading,
96
- user: {
97
- ...user,
98
- group: user.group ? user.group.id : void 0,
99
- team: user.team ? user.team.id : void 0,
100
- roles: user.roles ? user.roles.map((r)=>r.id) : [],
101
- teams: user.teams ? user.teams.map((t)=>t.id) : []
102
- },
84
+ user,
103
85
  onSubmit,
104
86
  isNewUser: newUser,
105
- fullName: `${user.firstName || ""} ${user.lastName || ""}`.trim(),
87
+ fullName: `${user?.firstName || ""} ${user?.lastName || ""}`.trim(),
106
88
  showEmptyView,
107
89
  createUser () {
108
90
  goToRoute(Routes.Users.List, {
@@ -1 +1 @@
1
- {"version":3,"file":"admin/ui/views/Users/hooks/useUserForm.js","sources":["../../../../../../src/admin/ui/views/Users/hooks/useUserForm.ts"],"sourcesContent":["import { useCallback } from \"react\";\nimport { useMutation, useQuery } from \"@apollo/react-hooks\";\nimport isEmpty from \"lodash/isEmpty.js\";\nimport { useRoute, useRouter, useWcp } from \"@webiny/app-admin\";\nimport { CREATE_USER, LIST_USERS, READ_USER, UPDATE_USER } from \"~/admin/ui/views/Users/graphql.js\";\nimport omit from \"lodash/omit.js\";\nimport { Routes } from \"~/admin/routes.js\";\nimport { useToast } from \"@webiny/admin-ui\";\n\nexport type UseUserForm = ReturnType<typeof useUserForm>;\n\ninterface SubmitUserCallableParams {\n id?: string;\n firstName: string;\n lastName: string;\n email: string;\n password?: string;\n avatar: {\n src?: string;\n };\n external?: boolean;\n}\n\ninterface SubmitUserCallable {\n (data: SubmitUserCallableParams): Promise<void>;\n}\n\nexport function useUserForm() {\n const { goToRoute } = useRouter();\n const { route } = useRoute(Routes.Users.List);\n const toast = useToast();\n\n const wcp = useWcp();\n const teams = wcp.canUseTeams();\n\n const id = route.params.id;\n const newUser = route.params.new === true;\n\n const { data, loading: userLoading } = useQuery(READ_USER({ teams }), {\n variables: { id },\n skip: !id,\n onCompleted: data => {\n if (!data) {\n return;\n }\n\n const { error } = data.adminUsers.user;\n if (error) {\n goToRoute(Routes.Users.List);\n toast.showWarningToast({\n title: \"Error loading user profile\",\n description: error.message,\n duration: Infinity\n });\n }\n }\n });\n\n const [create, { loading: createLoading }] = useMutation(CREATE_USER, {\n refetchQueries: [{ query: LIST_USERS }]\n });\n\n const [update, { loading: updateLoading }] = useMutation(UPDATE_USER({ teams }), {\n refetchQueries: [{ query: LIST_USERS }]\n });\n\n const loading = userLoading || createLoading || updateLoading;\n\n const onSubmit = useCallback<SubmitUserCallable>(\n async data => {\n const { id, ...rest } = data;\n const [operation, args] = !newUser\n ? [update, { variables: { id, data: omit(rest, [\"external\"]) } }]\n : [create, { variables: { data } }];\n\n const result = await operation(args);\n\n const { data: user, error } = result.data.adminUsers.user;\n\n if (error) {\n toast.showWarningToast({\n title: \"Error updating user profile\",\n description: error.message,\n duration: Infinity\n });\n return;\n }\n\n if (newUser) {\n goToRoute(Routes.Users.List, { id: user.id });\n }\n toast.showSuccessToast({\n title: \"User saved successfully.\"\n });\n },\n [id, newUser]\n );\n\n const user = userLoading ? {} : data ? data.adminUsers.user.data : {};\n\n const showEmptyView = !newUser && !userLoading && isEmpty(user);\n\n return {\n id,\n loading,\n user: {\n ...user,\n group: user.group ? user.group.id : undefined,\n team: user.team ? user.team.id : undefined,\n roles: user.roles ? user.roles.map((r: any) => r.id) : [],\n teams: user.teams ? user.teams.map((t: any) => t.id) : []\n },\n onSubmit,\n isNewUser: newUser,\n fullName: `${user.firstName || \"\"} ${user.lastName || \"\"}`.trim(),\n showEmptyView,\n createUser() {\n goToRoute(Routes.Users.List, { new: true });\n },\n cancelEditing() {\n goToRoute(Routes.Users.List);\n }\n };\n}\n"],"names":["useUserForm","goToRoute","useRouter","route","useRoute","Routes","toast","useToast","wcp","useWcp","teams","id","newUser","data","userLoading","useQuery","READ_USER","error","Infinity","create","createLoading","useMutation","CREATE_USER","LIST_USERS","update","updateLoading","UPDATE_USER","loading","onSubmit","useCallback","rest","operation","args","omit","result","user","showEmptyView","isEmpty","undefined","r","t"],"mappings":"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"}
1
+ {"version":3,"file":"admin/ui/views/Users/hooks/useUserForm.js","sources":["../../../../../../src/admin/ui/views/Users/hooks/useUserForm.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\nimport isEmpty from \"lodash/isEmpty.js\";\nimport omit from \"lodash/omit.js\";\nimport { useFeature } from \"@webiny/app\";\nimport { useRoute, useRouter } from \"@webiny/app-admin\";\nimport { GetUserFeature } from \"~/admin/features/users/getUser/index.js\";\nimport type { IGetUserGatewayResult } from \"~/admin/features/users/getUser/abstractions/GetUserGateway.js\";\nimport { CreateUserFeature } from \"~/admin/features/users/createUser/index.js\";\nimport { UpdateUserFeature } from \"~/admin/features/users/updateUser/index.js\";\nimport { Routes } from \"~/admin/routes.js\";\nimport { useToast } from \"@webiny/admin-ui\";\n\ninterface SubmitUserCallableParams {\n id?: string;\n firstName: string;\n lastName: string;\n email: string;\n password?: string;\n avatar: {\n src?: string;\n };\n external?: boolean;\n}\n\ninterface SubmitUserCallable {\n (data: SubmitUserCallableParams): Promise<void>;\n}\n\nexport function useUserForm() {\n const { goToRoute } = useRouter();\n const { route } = useRoute(Routes.Users.List);\n const toast = useToast();\n\n const { useCase: getUser } = useFeature(GetUserFeature);\n const { useCase: createUser } = useFeature(CreateUserFeature);\n const { useCase: updateUser } = useFeature(UpdateUserFeature);\n\n const id = route.params.id;\n const newUser = route.params.new === true;\n\n const [user, setUser] = useState<IGetUserGatewayResult | undefined>(undefined);\n const [userLoading, setUserLoading] = useState(false);\n const [mutationLoading, setMutationLoading] = useState(false);\n\n useEffect(() => {\n if (!id) {\n return;\n }\n setUserLoading(true);\n getUser\n .execute({ id })\n .then(data => {\n setUser(data);\n setUserLoading(false);\n })\n .catch(error => {\n goToRoute(Routes.Users.List);\n toast.showWarningToast({\n title: \"Error loading user profile\",\n description: error.message,\n duration: Infinity\n });\n setUserLoading(false);\n });\n }, [id]);\n\n const loading = userLoading || mutationLoading;\n\n const onSubmit = useCallback<SubmitUserCallable>(\n async data => {\n setMutationLoading(true);\n\n try {\n if (newUser) {\n const resultUser = await createUser.execute({ data });\n goToRoute(Routes.Users.List, { id: resultUser.id });\n } else {\n const { id: userId, ...rest } = data;\n await updateUser.execute({\n id: userId as string,\n data: omit(rest, [\"external\"])\n });\n }\n\n toast.showSuccessToast({\n title: \"User saved successfully.\"\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown error\";\n toast.showWarningToast({\n title: \"Error updating user profile\",\n description: message,\n duration: Infinity\n });\n } finally {\n setMutationLoading(false);\n }\n },\n [id, newUser]\n );\n\n const showEmptyView = !newUser && !userLoading && isEmpty(user);\n\n return {\n id,\n loading,\n user,\n onSubmit,\n isNewUser: newUser,\n fullName: `${user?.firstName || \"\"} ${user?.lastName || \"\"}`.trim(),\n showEmptyView,\n createUser() {\n goToRoute(Routes.Users.List, { new: true });\n },\n cancelEditing() {\n goToRoute(Routes.Users.List);\n }\n };\n}\n"],"names":["useUserForm","goToRoute","useRouter","route","useRoute","Routes","toast","useToast","getUser","useFeature","GetUserFeature","createUser","CreateUserFeature","updateUser","UpdateUserFeature","id","newUser","user","setUser","useState","undefined","userLoading","setUserLoading","mutationLoading","setMutationLoading","useEffect","data","error","Infinity","loading","onSubmit","useCallback","resultUser","userId","rest","omit","message","Error","showEmptyView","isEmpty"],"mappings":";;;;;;;;;;AA4BO,SAASA;IACZ,MAAM,EAAEC,SAAS,EAAE,GAAGC;IACtB,MAAM,EAAEC,KAAK,EAAE,GAAGC,SAASC,OAAO,KAAK,CAAC,IAAI;IAC5C,MAAMC,QAAQC;IAEd,MAAM,EAAE,SAASC,OAAO,EAAE,GAAGC,WAAWC;IACxC,MAAM,EAAE,SAASC,UAAU,EAAE,GAAGF,WAAWG;IAC3C,MAAM,EAAE,SAASC,UAAU,EAAE,GAAGJ,WAAWK;IAE3C,MAAMC,KAAKZ,MAAM,MAAM,CAAC,EAAE;IAC1B,MAAMa,UAAUb,AAAqB,SAArBA,MAAM,MAAM,CAAC,GAAG;IAEhC,MAAM,CAACc,MAAMC,QAAQ,GAAGC,SAA4CC;IACpE,MAAM,CAACC,aAAaC,eAAe,GAAGH,SAAS;IAC/C,MAAM,CAACI,iBAAiBC,mBAAmB,GAAGL,SAAS;IAEvDM,UAAU;QACN,IAAI,CAACV,IACD;QAEJO,eAAe;QACfd,QACK,OAAO,CAAC;YAAEO;QAAG,GACb,IAAI,CAACW,CAAAA;YACFR,QAAQQ;YACRJ,eAAe;QACnB,GACC,KAAK,CAACK,CAAAA;YACH1B,UAAUI,OAAO,KAAK,CAAC,IAAI;YAC3BC,MAAM,gBAAgB,CAAC;gBACnB,OAAO;gBACP,aAAaqB,MAAM,OAAO;gBAC1B,UAAUC,KAAQ;YACtB;YACAN,eAAe;QACnB;IACR,GAAG;QAACP;KAAG;IAEP,MAAMc,UAAUR,eAAeE;IAE/B,MAAMO,WAAWC,YACb,OAAML;QACFF,mBAAmB;QAEnB,IAAI;YACA,IAAIR,SAAS;gBACT,MAAMgB,aAAa,MAAMrB,WAAW,OAAO,CAAC;oBAAEe;gBAAK;gBACnDzB,UAAUI,OAAO,KAAK,CAAC,IAAI,EAAE;oBAAE,IAAI2B,WAAW,EAAE;gBAAC;YACrD,OAAO;gBACH,MAAM,EAAE,IAAIC,MAAM,EAAE,GAAGC,MAAM,GAAGR;gBAChC,MAAMb,WAAW,OAAO,CAAC;oBACrB,IAAIoB;oBACJ,MAAME,KAAKD,MAAM;wBAAC;qBAAW;gBACjC;YACJ;YAEA5B,MAAM,gBAAgB,CAAC;gBACnB,OAAO;YACX;QACJ,EAAE,OAAOqB,OAAO;YACZ,MAAMS,UAAUT,iBAAiBU,QAAQV,MAAM,OAAO,GAAG;YACzDrB,MAAM,gBAAgB,CAAC;gBACnB,OAAO;gBACP,aAAa8B;gBACb,UAAUR,KAAQ;YACtB;QACJ,SAAU;YACNJ,mBAAmB;QACvB;IACJ,GACA;QAACT;QAAIC;KAAQ;IAGjB,MAAMsB,gBAAgB,CAACtB,WAAW,CAACK,eAAekB,QAAQtB;IAE1D,OAAO;QACHF;QACAc;QACAZ;QACAa;QACA,WAAWd;QACX,UAAU,GAAGC,MAAM,aAAa,GAAG,CAAC,EAAEA,MAAM,YAAY,IAAI,CAAC,IAAI;QACjEqB;QACA;YACIrC,UAAUI,OAAO,KAAK,CAAC,IAAI,EAAE;gBAAE,KAAK;YAAK;QAC7C;QACA;YACIJ,UAAUI,OAAO,KAAK,CAAC,IAAI;QAC/B;IACJ;AACJ"}
@@ -1,8 +1,8 @@
1
- import { CoreGraphQLSchemaFactory } from "@webiny/handler-graphql/graphql/abstractions.js";
1
+ import { CoreGraphQLSchemaFactory } from "@webiny/api-graphql/graphql/abstractions.js";
2
2
  declare class AdminUserSchemaImpl implements CoreGraphQLSchemaFactory.Interface {
3
3
  execute(builder: CoreGraphQLSchemaFactory.SchemaBuilder): CoreGraphQLSchemaFactory.Return;
4
4
  }
5
5
  export declare const AdminUsersSchema: typeof AdminUserSchemaImpl & {
6
- __abstraction: import("@webiny/di").Abstraction<import("@webiny/handler-graphql/graphql/abstractions.public").IGraphQLSchemaFactory>;
6
+ __abstraction: import("@webiny/di").Abstraction<import("@webiny/api-graphql/graphql/abstractions.core").ICoreGraphQLSchemaFactory>;
7
7
  };
8
8
  export {};