@griddo/ax 10.1.96 → 10.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. package/package.json +3 -2
  2. package/src/__mocks__/axios/Roles.ts +10 -0
  3. package/src/__mocks__/axios/UserList.ts +545 -0
  4. package/src/__mocks__/store/GenericStore.ts +25 -0
  5. package/src/__mocks__/store/Roles.ts +1050 -0
  6. package/src/__mocks__/store/SitesList.ts +7 -1
  7. package/src/__mocks__/store/UserList.ts +482 -0
  8. package/src/__mocks__/store/UsersCreate.ts +298 -0
  9. package/src/__tests__/components/Avatar/Avatar.test.tsx +49 -48
  10. package/src/__tests__/components/ConfigPanel/ConfigPanel.test.tsx +2 -0
  11. package/src/__tests__/components/ConfigPanel/Form/Form.test.tsx +2 -0
  12. package/src/__tests__/components/ConfigPanel/GlobalPageForm/GlobalPageForm.test.tsx +25 -0
  13. package/src/__tests__/components/Fields/Button/Button.test.tsx +2 -2
  14. package/src/__tests__/components/Fields/ImageField/ImageField.test.tsx +2 -0
  15. package/src/__tests__/components/Fields/IntegrationsField/IntegrationsField.test.tsx +44 -2
  16. package/src/__tests__/components/Fields/Tooltip/Tooltip.test.tsx +0 -1
  17. package/src/__tests__/components/Gallery/Gallery.test.tsx +4 -0
  18. package/src/__tests__/components/Gallery/GalleryPanel/DetailPanel/DetailPanel.test.tsx +14 -0
  19. package/src/__tests__/components/Gallery/GalleryPanel/GalleryPanel.test.tsx +2 -1
  20. package/src/__tests__/components/Lists/Lists.test.tsx +3 -3
  21. package/src/__tests__/components/Login/Login.test.tsx +1 -1
  22. package/src/__tests__/components/TableFilters/DateFilter/DateFilter.test.tsx +1 -1
  23. package/src/__tests__/components/TableFilters/NameFilter/NameFilter.test.tsx +1 -1
  24. package/src/__tests__/components/TableFilters/RoleFilter/RoleFilter.test.tsx +165 -0
  25. package/src/__tests__/components/TableFilters/StatusFilter/StatusFilter.test.tsx +2 -2
  26. package/src/__tests__/components/TableFilters/UsersFilter/UsersFilter.test.tsx +153 -0
  27. package/src/__tests__/components/Tabs/Tabs.test.tsx +1 -1
  28. package/src/__tests__/modules/Settings/Integrations/Integrations.test.tsx +6 -0
  29. package/src/__tests__/modules/Sites/Sites.test.tsx +2 -1
  30. package/src/__tests__/modules/Sites/SitesList/ListView/BulkHeader/BulkHeader.test.tsx +14 -5
  31. package/src/__tests__/modules/Sites/SitesList/SitesList.test.tsx +6 -4
  32. package/src/__tests__/modules/Users/Roles/BulkHeader/BulkHeader.test.tsx +158 -0
  33. package/src/__tests__/modules/Users/Roles/Roles.test.tsx +619 -0
  34. package/src/__tests__/modules/Users/UserCreate/SiteItem/RolesModal/RoleItem/RoleItem.test.tsx +107 -0
  35. package/src/__tests__/modules/Users/UserCreate/SiteItem/RolesModal/RolesModal.test.tsx +159 -0
  36. package/src/__tests__/modules/Users/UserCreate/SiteItem/SiteItem.test.tsx +175 -0
  37. package/src/__tests__/modules/Users/UserCreate/UserCreate.test.tsx +320 -0
  38. package/src/__tests__/modules/Users/UserList/UserItem/UserItem.test.tsx +417 -0
  39. package/src/__tests__/modules/Users/UserList/UserList.test.tsx +310 -0
  40. package/src/api/index.tsx +2 -0
  41. package/src/api/roles.tsx +77 -0
  42. package/src/api/users.tsx +22 -2
  43. package/src/components/ActionMenu/index.tsx +12 -6
  44. package/src/components/Avatar/index.tsx +5 -3
  45. package/src/components/Avatar/style.tsx +8 -9
  46. package/src/components/BulkSelectionOptions/index.tsx +19 -12
  47. package/src/components/BulkSelectionOptions/style.tsx +6 -11
  48. package/src/components/ConfigPanel/Form/index.tsx +24 -1
  49. package/src/components/ConfigPanel/GlobalPageForm/index.tsx +17 -4
  50. package/src/components/ElementsTooltip/index.tsx +1 -1
  51. package/src/components/Fields/IntegrationsField/index.tsx +5 -6
  52. package/src/components/Fields/RadioField/index.tsx +1 -1
  53. package/src/components/Fields/ReferenceField/AutoPanel/index.tsx +3 -3
  54. package/src/components/Fields/ReferenceField/ItemList/index.tsx +1 -1
  55. package/src/components/Fields/ReferenceField/ManualPanel/index.tsx +3 -3
  56. package/src/components/Fields/TagsField/index.tsx +4 -2
  57. package/src/components/Fields/TextField/index.tsx +3 -0
  58. package/src/components/Fields/UrlField/index.tsx +5 -5
  59. package/src/components/Gallery/GalleryPanel/DetailPanel/index.tsx +42 -15
  60. package/src/components/Gallery/GalleryPanel/GalleryDragAndDrop/index.tsx +1 -1
  61. package/src/components/Gallery/GalleryPanel/index.tsx +20 -5
  62. package/src/components/Gallery/index.tsx +12 -6
  63. package/src/components/Icon/index.tsx +9 -1
  64. package/src/components/MainWrapper/AppBar/atoms.tsx +2 -2
  65. package/src/components/MainWrapper/AppBar/index.tsx +12 -10
  66. package/src/components/MainWrapper/AppBar/style.tsx +2 -1
  67. package/src/components/Modal/style.tsx +2 -2
  68. package/src/components/Nav/index.tsx +12 -2
  69. package/src/components/PageFinder/index.tsx +2 -2
  70. package/src/components/SearchField/index.tsx +3 -8
  71. package/src/components/TableFilters/PermissionsFilter/index.tsx +50 -0
  72. package/src/{modules/Users/UserList/HeaderMenus/Name → components/TableFilters/PermissionsFilter}/style.tsx +6 -2
  73. package/src/components/TableFilters/RoleFilter/index.tsx +61 -0
  74. package/src/components/TableFilters/RoleFilter/style.tsx +28 -0
  75. package/src/components/TableFilters/UsersFilter/index.tsx +55 -0
  76. package/src/components/TableFilters/UsersFilter/style.tsx +31 -0
  77. package/src/components/TableFilters/index.tsx +6 -0
  78. package/src/components/TableList/TableItem/style.tsx +2 -2
  79. package/src/components/TableList/style.tsx +1 -1
  80. package/src/components/index.tsx +7 -1
  81. package/src/containers/App/actions.tsx +3 -3
  82. package/src/containers/PageEditor/actions.tsx +14 -20
  83. package/src/containers/Redirects/actions.tsx +1 -0
  84. package/src/containers/Sites/actions.tsx +22 -14
  85. package/src/containers/Sites/interfaces.tsx +3 -3
  86. package/src/containers/Sites/reducer.tsx +1 -1
  87. package/src/containers/StructuredData/actions.tsx +15 -3
  88. package/src/containers/Users/actions.tsx +160 -26
  89. package/src/containers/Users/constants.tsx +8 -10
  90. package/src/containers/Users/interfaces.tsx +25 -3
  91. package/src/containers/Users/reducer.tsx +24 -15
  92. package/src/guards/index.tsx +2 -1
  93. package/src/guards/restricted/index.tsx +21 -0
  94. package/src/hooks/index.tsx +3 -0
  95. package/src/hooks/users.tsx +38 -0
  96. package/src/modules/App/Routing/NavMenu/NavItem/index.tsx +10 -5
  97. package/src/modules/App/Routing/NavMenu/index.tsx +16 -7
  98. package/src/modules/App/Routing/PrivateRoute/index.tsx +13 -5
  99. package/src/modules/App/Routing/index.tsx +17 -6
  100. package/src/modules/Categories/CategoriesList/BulkHeader/TableHeader/style.tsx +1 -0
  101. package/src/modules/Categories/CategoriesList/BulkHeader/index.tsx +2 -10
  102. package/src/modules/Categories/CategoriesList/CategoryItem/index.tsx +27 -12
  103. package/src/modules/Categories/CategoriesList/CategoryItem/style.tsx +4 -2
  104. package/src/modules/Categories/CategoriesList/index.tsx +27 -8
  105. package/src/modules/Content/BulkHeader/index.tsx +7 -3
  106. package/src/modules/Content/PageImporter/index.tsx +1 -1
  107. package/src/modules/Content/PageItem/index.tsx +45 -31
  108. package/src/modules/Content/PageItem/style.tsx +2 -1
  109. package/src/modules/Content/index.tsx +22 -13
  110. package/src/modules/FramePreview/index.tsx +2 -2
  111. package/src/modules/GlobalEditor/index.tsx +68 -53
  112. package/src/modules/GlobalSettings/index.tsx +2 -0
  113. package/src/modules/Navigation/Defaults/BulkHeader/index.tsx +2 -10
  114. package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/DefaultsBrowser/index.tsx +9 -11
  115. package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/index.tsx +5 -1
  116. package/src/modules/Navigation/Defaults/DefaultsEditor/index.tsx +10 -5
  117. package/src/modules/Navigation/Defaults/Item/index.tsx +41 -27
  118. package/src/modules/Navigation/Defaults/Item/style.tsx +2 -1
  119. package/src/modules/Navigation/Defaults/index.tsx +29 -10
  120. package/src/modules/Navigation/Menus/List/Table/Header/index.tsx +7 -5
  121. package/src/modules/Navigation/Menus/List/Table/Item/index.tsx +10 -10
  122. package/src/modules/Navigation/Menus/List/Table/Item/style.tsx +2 -1
  123. package/src/modules/Navigation/Menus/List/index.tsx +6 -2
  124. package/src/modules/Navigation/Menus/index.tsx +12 -7
  125. package/src/modules/PageEditor/Editor/index.tsx +5 -1
  126. package/src/modules/PageEditor/PageBrowser/index.tsx +9 -3
  127. package/src/modules/PageEditor/index.tsx +67 -57
  128. package/src/modules/Redirects/index.tsx +97 -98
  129. package/src/modules/Settings/ContentTypes/DataPacks/AddModal/index.tsx +5 -1
  130. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/TemplateBrowser/index.tsx +8 -9
  131. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/index.tsx +7 -3
  132. package/src/modules/Settings/ContentTypes/DataPacks/Config/index.tsx +5 -1
  133. package/src/modules/Settings/ContentTypes/DataPacks/Item/index.tsx +5 -1
  134. package/src/modules/Settings/Integrations/BulkHeader/index.tsx +2 -17
  135. package/src/modules/Settings/Integrations/IntegrationForm/index.tsx +6 -2
  136. package/src/modules/Settings/Integrations/IntegrationItem/index.tsx +18 -8
  137. package/src/modules/Settings/Integrations/IntegrationItem/style.tsx +6 -3
  138. package/src/modules/Settings/Integrations/index.tsx +32 -7
  139. package/src/modules/Settings/Languages/LanguagePanel/index.tsx +6 -2
  140. package/src/modules/Settings/Languages/Table/Header/index.tsx +4 -2
  141. package/src/modules/Settings/Languages/Table/Item/index.tsx +19 -43
  142. package/src/modules/Settings/Languages/Table/Item/style.tsx +11 -54
  143. package/src/modules/Settings/Languages/index.tsx +2 -2
  144. package/src/modules/Settings/SeoAnalyticsSettings/Analytics/index.tsx +2 -4
  145. package/src/modules/Settings/SeoAnalyticsSettings/index.tsx +4 -2
  146. package/src/modules/Settings/Social/index.tsx +1 -1
  147. package/src/modules/Settings/index.tsx +17 -11
  148. package/src/modules/Sites/SitesList/GridView/GridSiteItem/index.tsx +31 -18
  149. package/src/modules/Sites/SitesList/ListView/BulkHeader/index.tsx +21 -12
  150. package/src/modules/Sites/SitesList/ListView/ListSiteItem/index.tsx +31 -18
  151. package/src/modules/Sites/SitesList/RecentSiteItem/index.tsx +1 -1
  152. package/src/modules/Sites/SitesList/index.tsx +16 -24
  153. package/src/modules/Sites/index.tsx +7 -3
  154. package/src/modules/StructuredData/Form/index.tsx +1 -1
  155. package/src/modules/StructuredData/StructuredDataList/BulkHeader/index.tsx +8 -5
  156. package/src/modules/StructuredData/StructuredDataList/ContentFilters/index.tsx +8 -5
  157. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +29 -15
  158. package/src/modules/StructuredData/StructuredDataList/StructuredDataItem/index.tsx +50 -19
  159. package/src/modules/StructuredData/StructuredDataList/index.tsx +9 -6
  160. package/src/modules/Users/Profile/index.tsx +16 -4
  161. package/src/modules/Users/Roles/BulkHeader/TableHeader/index.tsx +52 -0
  162. package/src/modules/Users/Roles/BulkHeader/TableHeader/style.tsx +43 -0
  163. package/src/modules/Users/Roles/BulkHeader/index.tsx +74 -0
  164. package/src/modules/Users/Roles/RoleItem/index.tsx +104 -0
  165. package/src/modules/Users/Roles/RoleItem/style.tsx +127 -0
  166. package/src/modules/Users/Roles/SideModal/index.tsx +81 -0
  167. package/src/modules/Users/Roles/SideModal/style.tsx +132 -0
  168. package/src/modules/Users/Roles/hooks.tsx +78 -0
  169. package/src/modules/Users/Roles/index.tsx +256 -0
  170. package/src/modules/Users/Roles/style.tsx +23 -0
  171. package/src/modules/Users/Roles/utils.tsx +12 -0
  172. package/src/modules/Users/UserCreate/OptionItem/index.tsx +45 -0
  173. package/src/modules/Users/UserCreate/OptionItem/style.tsx +48 -0
  174. package/src/modules/Users/UserCreate/SiteItem/RolesModal/RoleItem/index.tsx +48 -0
  175. package/src/modules/Users/UserCreate/SiteItem/RolesModal/RoleItem/style.tsx +42 -0
  176. package/src/modules/Users/UserCreate/SiteItem/RolesModal/index.tsx +140 -0
  177. package/src/modules/Users/UserCreate/SiteItem/RolesModal/style.tsx +94 -0
  178. package/src/modules/Users/UserCreate/SiteItem/index.tsx +103 -22
  179. package/src/modules/Users/UserCreate/SiteItem/style.tsx +49 -6
  180. package/src/modules/Users/UserCreate/index.tsx +278 -121
  181. package/src/modules/Users/UserCreate/style.tsx +71 -4
  182. package/src/modules/Users/UserEdit/index.tsx +71 -24
  183. package/src/modules/Users/UserForm/atoms.tsx +40 -8
  184. package/src/modules/Users/UserForm/index.tsx +335 -116
  185. package/src/modules/Users/UserForm/style.tsx +70 -6
  186. package/src/modules/Users/UserList/BulkHeader/TableHeader/index.tsx +61 -31
  187. package/src/modules/Users/UserList/BulkHeader/TableHeader/style.tsx +18 -4
  188. package/src/modules/Users/UserList/BulkHeader/index.tsx +10 -3
  189. package/src/modules/Users/UserList/UserItem/index.tsx +121 -38
  190. package/src/modules/Users/UserList/UserItem/style.tsx +32 -14
  191. package/src/modules/Users/UserList/hooks.tsx +13 -8
  192. package/src/modules/Users/UserList/index.tsx +67 -29
  193. package/src/modules/Users/UserList/utils.tsx +1 -1
  194. package/src/modules/Users/index.tsx +20 -3
  195. package/src/routes/index.tsx +9 -17
  196. package/src/routes/multisite.tsx +73 -8
  197. package/src/routes/site.tsx +96 -10
  198. package/src/types/index.tsx +42 -1
  199. package/tsconfig.paths.json +1 -0
  200. package/src/__tests__/components/Avatar/__snapshots__/Avatar.test.tsx.snap +0 -61
  201. package/src/modules/Users/UserList/HeaderMenus/Name/index.tsx +0 -55
@@ -26,7 +26,7 @@ export interface ISitesState {
26
26
  recentSites: ISite[];
27
27
  sitesTotalItems: number;
28
28
  sitesByLang: ISite[];
29
- currentSiteInfo: any;
29
+ currentSiteInfo: ISite | null;
30
30
  currentFilter: string | null;
31
31
  totalItems: number;
32
32
  currentSiteLanguages: ILanguage[];
@@ -148,7 +148,7 @@ function resetForm(setDefault?: boolean): (dispatch: Dispatch, getState: any) =>
148
148
  };
149
149
  }
150
150
 
151
- const filterStructuredData = (data: IStructuredData[], isTaxonomy: boolean, siteID?: number) => {
151
+ const filterStructuredData = (data: IStructuredData[], isTaxonomy: boolean, siteID?: number | null) => {
152
152
  const scope = !siteID ? "global" : "site";
153
153
 
154
154
  const filteredData: { global: IStructuredData[]; site: IStructuredData[] } = { global: [], site: [] };
@@ -160,7 +160,7 @@ const filterStructuredData = (data: IStructuredData[], isTaxonomy: boolean, site
160
160
 
161
161
  function getStructuredData(
162
162
  token: string | null,
163
- siteID?: number
163
+ siteID?: number | null
164
164
  ): (dispatch: Dispatch, getState: any) => Promise<void> {
165
165
  return async (dispatch, getState) => {
166
166
  try {
@@ -227,7 +227,7 @@ function setSelectedCategory(id: string, scope: string): (dispatch: Dispatch, ge
227
227
 
228
228
  function getStructuredDataContents(
229
229
  params: IGetStructuredDataParams,
230
- siteID?: number
230
+ siteID?: number | null
231
231
  ): (dispatch: Dispatch, getState: any) => Promise<void> {
232
232
  return async (dispatch, getState) => {
233
233
  if (!params.dataID) {
@@ -568,6 +568,17 @@ function deleteError(error: IErrorItem): (dispatch: Dispatch, getState: any) =>
568
568
  };
569
569
  }
570
570
 
571
+ function resetStructuredData(): (dispatch: Dispatch) => void {
572
+ return async (dispatch) => {
573
+ try {
574
+ dispatch(setCurrentDataContent([]));
575
+ dispatch(setCurrentData(null));
576
+ dispatch(setCurrentDataID(null));
577
+ } catch (e) {
578
+ console.log(e);
579
+ }
580
+ };
581
+ }
571
582
  function getDataContentTranslation(langID: number): (dispatch: Dispatch, getState: any) => Promise<boolean> {
572
583
  return async (dispatch, getState) => {
573
584
  try {
@@ -658,6 +669,7 @@ export {
658
669
  validateForm,
659
670
  deleteError,
660
671
  setContentFilters,
672
+ resetStructuredData,
661
673
  getDataContentTranslation,
662
674
  setFormValues,
663
675
  setIsTranslated,
@@ -1,9 +1,23 @@
1
1
  import { Dispatch } from "redux";
2
- import { SET_USERS, SET_USER_FORM, SET_CURRENT_USER } from "./constants";
3
-
4
- import { ISetUsers, ISetCurrentUser, ISetUserForm } from "./interfaces";
5
- import { ICreatePasswordParams, IUser } from "@ax/types";
6
- import { global, users } from "@ax/api";
2
+ import {
3
+ SET_USERS,
4
+ SET_USER_FORM,
5
+ SET_CURRENT_USER,
6
+ SET_ROLES,
7
+ SET_CURRENT_PERMISSIONS,
8
+ SET_GLOBAL_PERMISSIONS,
9
+ } from "./constants";
10
+
11
+ import {
12
+ ISetUsers,
13
+ ISetCurrentUser,
14
+ ISetUserForm,
15
+ ISetRoles,
16
+ ISetCurrentPermissions,
17
+ ISetGlobalPermissions,
18
+ } from "./interfaces";
19
+ import { ICreatePasswordParams, IActivateRole, IGetRoles, IRole, IUser } from "@ax/types";
20
+ import { global, users, roles } from "@ax/api";
7
21
  import { appActions } from "@ax/containers/App";
8
22
  import { handleRequest, isReqOk } from "@ax/helpers";
9
23
 
@@ -19,10 +33,22 @@ function setUserForm(userForm: IUser): ISetUserForm {
19
33
  return { type: SET_USER_FORM, payload: { userForm } };
20
34
  }
21
35
 
22
- function getUsers(params: any): (dispatch: Dispatch) => Promise<void> {
36
+ function setRoles(roles: IRole[]): ISetRoles {
37
+ return { type: SET_ROLES, payload: { roles } };
38
+ }
39
+
40
+ function setCurrentPermissions(currentPermissions: string[]): ISetCurrentPermissions {
41
+ return { type: SET_CURRENT_PERMISSIONS, payload: { currentPermissions } };
42
+ }
43
+
44
+ function setGlobalPermissions(globalPermissions: string[]): ISetGlobalPermissions {
45
+ return { type: SET_GLOBAL_PERMISSIONS, payload: { globalPermissions } };
46
+ }
47
+
48
+ function getUsers(params: any, siteID?: number | null): (dispatch: Dispatch) => Promise<void> {
23
49
  return async (dispatch) => {
24
50
  try {
25
- const callback = async () => users.getUsers(params);
51
+ const callback = async () => (siteID ? users.getSiteUsers(params, siteID) : users.getUsers(params));
26
52
 
27
53
  const responseActions = {
28
54
  handleSuccess: (response: any) => {
@@ -38,18 +64,19 @@ function getUsers(params: any): (dispatch: Dispatch) => Promise<void> {
38
64
  };
39
65
  }
40
66
 
41
- function getUser(id: string | number, token?: string): (dispatch: Dispatch) => Promise<void> {
42
- return async (dispatch) => {
67
+ function getUser(id: string | number, token?: string): (dispatch: Dispatch, getState: any) => Promise<void> {
68
+ return async (dispatch, getState) => {
43
69
  try {
44
70
  const callback = async () => users.getUser(id, token);
45
71
 
46
72
  const responseActions = {
47
- handleSuccess: (response: any) => {
73
+ handleSuccess: (response: IUser) => {
48
74
  if (token) {
49
75
  dispatch(appActions.setToken(token));
50
76
  }
51
77
  if (id === "me") {
52
78
  dispatch(setCurrentUser(response));
79
+ getUserCurrentPermissions()(dispatch, getState);
53
80
  } else {
54
81
  dispatch(setUserForm(response));
55
82
  }
@@ -66,12 +93,16 @@ function getUser(id: string | number, token?: string): (dispatch: Dispatch) => P
66
93
 
67
94
  function updateUser(
68
95
  id: number,
69
- data: any,
96
+ data: IUser,
70
97
  isProfile: boolean,
71
98
  isList?: boolean
72
- ): (dispatch: Dispatch, getState: any) => Promise<void> {
73
- return async (dispatch) => {
99
+ ): (dispatch: Dispatch, getState: any) => Promise<boolean> {
100
+ return async (dispatch, getState) => {
74
101
  try {
102
+ const {
103
+ sites: { currentSiteInfo },
104
+ } = getState();
105
+
75
106
  const callback = async () => users.updateUser(id, data);
76
107
 
77
108
  const responseActions = {
@@ -80,7 +111,8 @@ function updateUser(
80
111
  dispatch(setCurrentUser(response));
81
112
  } else if (isList) {
82
113
  const params = { filterQuery: "?order=dateCreated" };
83
- getUsers(params)(dispatch);
114
+ const siteID = currentSiteInfo ? currentSiteInfo.id : null;
115
+ getUsers(params, siteID)(dispatch);
84
116
  } else {
85
117
  dispatch(setUserForm(response));
86
118
  }
@@ -88,16 +120,18 @@ function updateUser(
88
120
  handleError: (response: any) => appActions.handleError(response)(dispatch),
89
121
  };
90
122
 
91
- await handleRequest(callback, responseActions, [appActions.setIsSaving])(dispatch);
123
+ return await handleRequest(callback, responseActions, [appActions.setIsSaving])(dispatch);
92
124
  } catch (e) {
93
- console.log(e); // TODO: capturar error bien
125
+ console.log(e);
126
+ return false;
94
127
  }
95
128
  };
96
129
  }
97
130
 
98
- function updatePassword(id: string, data: any): (dispatch: Dispatch, getState: any) => Promise<boolean | undefined> {
131
+ function updatePassword(id: number | null, data: any): (dispatch: Dispatch) => Promise<boolean> {
99
132
  return async (dispatch) => {
100
133
  try {
134
+ if (!id) return false;
101
135
  const callback = async () => users.updatePassword(id, data);
102
136
 
103
137
  const responseActions = {
@@ -107,12 +141,13 @@ function updatePassword(id: string, data: any): (dispatch: Dispatch, getState: a
107
141
 
108
142
  return await handleRequest(callback, responseActions, [appActions.setIsSaving])(dispatch);
109
143
  } catch (e) {
110
- console.log(e); // TODO: capturar error bien
144
+ console.log(e);
145
+ return false;
111
146
  }
112
147
  };
113
148
  }
114
149
 
115
- function createUser(data: { name: string; email: string; sites: any[] }): (dispatch: Dispatch) => Promise<boolean> {
150
+ function createUser(data: { name: string; email: string }): (dispatch: Dispatch) => Promise<boolean> {
116
151
  return async (dispatch) => {
117
152
  try {
118
153
  const callback = async () => users.createUser(data);
@@ -130,15 +165,18 @@ function createUser(data: { name: string; email: string; sites: any[] }): (dispa
130
165
  };
131
166
  }
132
167
 
133
- function createPassword(id: string, params: ICreatePasswordParams): (dispatch: Dispatch) => Promise<boolean> {
134
- return async (dispatch) => {
168
+ function createPassword(
169
+ id: string,
170
+ params: ICreatePasswordParams
171
+ ): (dispatch: Dispatch, getState: any) => Promise<boolean> {
172
+ return async (dispatch, getState) => {
135
173
  try {
136
174
  const callback = async () => global.createPassword(id, params);
137
175
 
138
176
  const responseActions = {
139
177
  handleSuccess: async (response: any) => {
140
178
  dispatch(appActions.setToken(response.token));
141
- await getUser("me", response.token)(dispatch);
179
+ await getUser("me", response.token)(dispatch, getState);
142
180
  },
143
181
  handleError: (response: any) => appActions.handleError(response)(dispatch),
144
182
  };
@@ -151,13 +189,20 @@ function createPassword(id: string, params: ICreatePasswordParams): (dispatch: D
151
189
  };
152
190
  }
153
191
 
154
- function deleteUser(id: number | number[]): (dispatch: Dispatch) => Promise<boolean> {
155
- return async (dispatch) => {
192
+ function deleteUser(id: number | number[]): (dispatch: Dispatch, getState: any) => Promise<boolean> {
193
+ return async (dispatch, getState) => {
156
194
  try {
195
+ const {
196
+ sites: { currentSiteInfo },
197
+ } = getState();
198
+
157
199
  const params = { filterQuery: "?order=dateCreated" };
158
200
 
159
201
  const responseActions = {
160
- handleSuccess: () => getUsers(params)(dispatch),
202
+ handleSuccess: () => {
203
+ const siteID = currentSiteInfo ? currentSiteInfo.id : null;
204
+ getUsers(params, siteID)(dispatch);
205
+ },
161
206
  handleError: (response: any) => {
162
207
  const {
163
208
  data: { message },
@@ -170,7 +215,7 @@ function deleteUser(id: number | number[]): (dispatch: Dispatch) => Promise<bool
170
215
 
171
216
  const callback = async () => (Array.isArray(id) ? users.deleteUserBulk(id) : users.deleteUser(id));
172
217
 
173
- return await handleRequest(callback, responseActions, [appActions.setIsLoading])(dispatch);
218
+ return await handleRequest(callback, responseActions, [])(dispatch);
174
219
  } catch (e) {
175
220
  console.log(e); // TODO: capturar error bien
176
221
  return false;
@@ -211,6 +256,92 @@ function resendInvitation(id: number): (dispatch: Dispatch) => Promise<boolean>
211
256
  };
212
257
  }
213
258
 
259
+ function getRoles(params: IGetRoles, token?: string, hasLoading?: boolean): (dispatch: Dispatch) => Promise<void> {
260
+ return async (dispatch) => {
261
+ try {
262
+ const callback = async () => roles.getRoles(params, token);
263
+
264
+ const responseActions = {
265
+ handleSuccess: (response: any) => dispatch(setRoles(response)),
266
+ handleError: (response: any) => appActions.handleError(response)(dispatch),
267
+ };
268
+
269
+ const loading = hasLoading === false ? [] : [appActions.setIsLoading];
270
+
271
+ await handleRequest(callback, responseActions, loading)(dispatch);
272
+ } catch (e) {
273
+ console.log(e);
274
+ }
275
+ };
276
+ }
277
+
278
+ function activateRoles(params: IActivateRole): (dispatch: Dispatch) => Promise<boolean> {
279
+ return async (dispatch) => {
280
+ try {
281
+ const { id, siteId, active } = params;
282
+ const getRolesParams = { siteId };
283
+ const responseActions = {
284
+ handleSuccess: () => getRoles(getRolesParams)(dispatch),
285
+ handleError: (response: any) => {
286
+ const {
287
+ data: { message },
288
+ } = response;
289
+ const isMultiple = Array.isArray(message) && message.length > 1;
290
+ const msg = isMultiple ? `The activate action failed due to ${message.length} errors.` : undefined;
291
+ appActions.handleError(response, isMultiple, msg)(dispatch);
292
+ },
293
+ };
294
+
295
+ const callback = async () =>
296
+ Array.isArray(id)
297
+ ? roles.activateRolesBulk({ id, siteId, active })
298
+ : roles.activateRole({ id, siteId, active });
299
+
300
+ return await handleRequest(callback, responseActions, [])(dispatch);
301
+ } catch (e) {
302
+ console.log(e);
303
+ return false;
304
+ }
305
+ };
306
+ }
307
+
308
+ function getUserCurrentPermissions(): (dispatch: Dispatch, getState: any) => void {
309
+ return async (dispatch, getState) => {
310
+ const {
311
+ users: { roles, currentUser },
312
+ sites: { currentSiteInfo },
313
+ } = getState();
314
+
315
+ const userRoles = currentSiteInfo
316
+ ? currentUser.roles.find((roleSite: any) => roleSite.siteId === currentSiteInfo.id || roleSite.siteId === "all")
317
+ ?.roles
318
+ : currentUser.roles.find((roleSite: any) => roleSite.siteId === "global")?.roles;
319
+
320
+ let permissions: string[] = [];
321
+ if (userRoles && userRoles.length) {
322
+ userRoles.forEach((roleID: number) => {
323
+ const rolePerms =
324
+ roles &&
325
+ roles.reduce((acc: string[], curr: IRole) => {
326
+ if (curr.id === roleID) {
327
+ const permissions = currentSiteInfo
328
+ ? curr.permissions.sitePermissions
329
+ : [...curr.permissions.globalPermissions, ...curr.permissions.sitePermissions];
330
+ const keys = permissions.map((perm: any) => perm.key);
331
+ acc = [...acc, ...keys];
332
+ }
333
+ return acc;
334
+ }, []);
335
+ permissions = [...permissions, ...rolePerms];
336
+ });
337
+ }
338
+ dispatch(setCurrentPermissions(permissions));
339
+ if(!currentSiteInfo) {
340
+ dispatch(setGlobalPermissions(permissions));
341
+ }
342
+ };
343
+ }
344
+
214
345
  export {
215
346
  getUsers,
216
347
  updateUser,
@@ -222,5 +353,8 @@ export {
222
353
  setCurrentUser,
223
354
  deleteUser,
224
355
  resendInvitation,
356
+ getRoles,
357
+ activateRoles,
225
358
  createPassword,
359
+ getUserCurrentPermissions,
226
360
  };
@@ -1,12 +1,10 @@
1
- const NAME: string = "users";
1
+ const NAME = "users";
2
2
 
3
- const SET_USERS: string = `${NAME}/SET_USERS`;
4
- const SET_CURRENT_USER: string = `${NAME}/SET_CURRENT_USER`;
5
- const SET_USER_FORM: string = `${NAME}/SET_USER_FORM`;
3
+ const SET_USERS = `${NAME}/SET_USERS`;
4
+ const SET_CURRENT_USER = `${NAME}/SET_CURRENT_USER`;
5
+ const SET_USER_FORM = `${NAME}/SET_USER_FORM`;
6
+ const SET_ROLES = `${NAME}/SET_ROLES`;
7
+ const SET_CURRENT_PERMISSIONS = `${NAME}/SET_CURRENT_PERMISSIONS`;
8
+ const SET_GLOBAL_PERMISSIONS = `${NAME}/SET_GLOBAL_PERMISSIONS`;
6
9
 
7
- export {
8
- NAME,
9
- SET_USERS,
10
- SET_USER_FORM,
11
- SET_CURRENT_USER
12
- };
10
+ export { NAME, SET_USERS, SET_USER_FORM, SET_CURRENT_USER, SET_ROLES, SET_CURRENT_PERMISSIONS, SET_GLOBAL_PERMISSIONS };
@@ -1,5 +1,12 @@
1
- import { IUser } from "@ax/types";
2
- import { SET_CURRENT_USER, SET_USERS, SET_USER_FORM } from "./constants";
1
+ import { IRole, IUser } from "@ax/types";
2
+ import {
3
+ SET_CURRENT_PERMISSIONS,
4
+ SET_CURRENT_USER,
5
+ SET_GLOBAL_PERMISSIONS,
6
+ SET_ROLES,
7
+ SET_USERS,
8
+ SET_USER_FORM,
9
+ } from "./constants";
3
10
 
4
11
  export interface ISetUsers {
5
12
  type: typeof SET_USERS;
@@ -16,4 +23,19 @@ export interface ISetUserForm {
16
23
  payload: { userForm: IUser };
17
24
  }
18
25
 
19
- export type UsersActionsCreators = ISetUsers & ISetCurrentUser & ISetUserForm;
26
+ export interface ISetRoles {
27
+ type: typeof SET_ROLES;
28
+ payload: { roles: IRole[] };
29
+ }
30
+
31
+ export interface ISetCurrentPermissions {
32
+ type: typeof SET_CURRENT_PERMISSIONS;
33
+ payload: { currentPermissions: string[] };
34
+ }
35
+
36
+ export interface ISetGlobalPermissions {
37
+ type: typeof SET_GLOBAL_PERMISSIONS;
38
+ payload: { globalPermissions: string[] };
39
+ }
40
+
41
+ export type UsersActionsCreators = ISetUsers & ISetCurrentUser & ISetUserForm & ISetRoles & ISetCurrentPermissions;
@@ -1,11 +1,20 @@
1
- import { IUser } from "@ax/types";
2
- import { SET_USERS, SET_USER_FORM, SET_CURRENT_USER } from "./constants";
3
- import { UsersActionsCreators } from "./interfaces";
1
+ import { IRole, IUser } from "@ax/types";
2
+ import {
3
+ SET_USERS,
4
+ SET_USER_FORM,
5
+ SET_CURRENT_USER,
6
+ SET_ROLES,
7
+ SET_CURRENT_PERMISSIONS,
8
+ SET_GLOBAL_PERMISSIONS,
9
+ } from "./constants";
4
10
 
5
11
  export interface IUsersState {
6
12
  users: IUser[];
7
13
  userForm: IUser;
8
- currentUser: IUser;
14
+ currentUser: IUser | null;
15
+ currentPermissions: string[];
16
+ globalPermissions: string[];
17
+ roles: IRole[];
9
18
  }
10
19
 
11
20
  export const initialState = {
@@ -16,27 +25,27 @@ export const initialState = {
16
25
  name: "",
17
26
  email: "",
18
27
  failed: 0,
19
- sites: ["all"],
20
- },
21
- currentUser: {
22
- id: null,
23
- username: "",
24
- name: "",
25
- email: "",
26
- failed: 0,
27
- sites: ["all"],
28
+ roles: [],
29
+ isSuperAdmin: false,
28
30
  },
31
+ currentUser: null,
32
+ currentPermissions: [],
33
+ globalPermissions: [],
34
+ roles: [],
29
35
  };
30
36
 
31
- export function reducer(state = initialState, action: UsersActionsCreators): IUsersState {
37
+ export function reducer(state = initialState, action: any): IUsersState {
32
38
  switch (action.type) {
33
39
  case SET_USERS:
34
40
  case SET_USER_FORM:
35
41
  case SET_CURRENT_USER:
42
+ case SET_ROLES:
43
+ case SET_CURRENT_PERMISSIONS:
44
+ case SET_GLOBAL_PERMISSIONS:
36
45
  return { ...state, ...action.payload };
37
46
  default:
38
47
  return state;
39
48
  }
40
49
  }
41
50
 
42
- export { initialState as usersInitialState, reducer as usersReducer };
51
+ export { initialState as usersInitialState, reducer as usersReducer };
@@ -1,4 +1,5 @@
1
1
  import ErrorGuard from "./error";
2
2
  import RouteLeavingGuard from "./routeLeaving";
3
+ import Restricted from "./restricted";
3
4
 
4
- export { ErrorGuard, RouteLeavingGuard };
5
+ export { ErrorGuard, RouteLeavingGuard, Restricted };
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ import { usePermission } from "@ax/hooks";
3
+
4
+ const Restricted = (props: IRestrictedProps): JSX.Element => {
5
+ const { to, fallback, children } = props;
6
+ const isAllowed = usePermission(to);
7
+
8
+ if (isAllowed) {
9
+ return <>{children}</>;
10
+ }
11
+
12
+ return <>{fallback}</>;
13
+ };
14
+
15
+ interface IRestrictedProps {
16
+ children: JSX.Element | JSX.Element[];
17
+ to: string | string[];
18
+ fallback?: JSX.Element;
19
+ }
20
+
21
+ export default Restricted;
@@ -5,6 +5,7 @@ import { useURLSearchParam } from "./location";
5
5
  import { useCategoryColors, useEmptyState, useAdaptiveText } from "./content";
6
6
  import { useWindowSize } from "./window";
7
7
  import { useOnMessageReceivedFromIframe, useOnMessageReceivedFromOutside } from "./iframe";
8
+ import { usePermission, useGlobalPermission } from "./users";
8
9
 
9
10
  export {
10
11
  useModal,
@@ -20,6 +21,8 @@ export {
20
21
  useEmptyState,
21
22
  useWindowSize,
22
23
  useAdaptiveText,
24
+ usePermission,
25
+ useGlobalPermission,
23
26
  useOnMessageReceivedFromIframe,
24
27
  useOnMessageReceivedFromOutside,
25
28
  };
@@ -0,0 +1,38 @@
1
+ import { useSelector } from "react-redux";
2
+ import { IRootState } from "@ax/types";
3
+
4
+ const usePermission = (permission: string | string[] | undefined): boolean => {
5
+ const userPermissions = useSelector((state: IRootState) => state.users.currentPermissions);
6
+ const isSuperAdmin = useSelector(
7
+ (state: IRootState) => state.users.currentUser && state.users.currentUser.isSuperAdmin
8
+ );
9
+
10
+ const isAllowedTo = (permissions: string[]) => userPermissions && permissions.some((permission: string) => userPermissions.includes(permission));
11
+
12
+ if (!permission || isSuperAdmin) {
13
+ return true;
14
+ }
15
+
16
+ const arrayPermission = Array.isArray(permission) ? permission : [permission];
17
+
18
+ return isAllowedTo(arrayPermission);
19
+ };
20
+
21
+ const useGlobalPermission = (permission: string | string[] | undefined): boolean => {
22
+ const userPermissions = useSelector((state: IRootState) => state.users.globalPermissions);
23
+ const isSuperAdmin = useSelector(
24
+ (state: IRootState) => state.users.currentUser && state.users.currentUser.isSuperAdmin
25
+ );
26
+
27
+ const isAllowedTo = (permissions: string[]) => userPermissions && permissions.some((permission: string) => userPermissions.includes(permission));
28
+
29
+ if (!permission || isSuperAdmin) {
30
+ return true;
31
+ }
32
+
33
+ const arrayPermission = Array.isArray(permission) ? permission : [permission];
34
+
35
+ return isAllowedTo(arrayPermission);
36
+ };
37
+
38
+ export { usePermission, useGlobalPermission };
@@ -1,9 +1,10 @@
1
1
  import React, { useContext } from "react";
2
2
 
3
3
  import { IRouter } from "@ax/routes";
4
+ import { Restricted } from "@ax/guards";
5
+ import { Icon } from "@ax/components";
4
6
 
5
7
  import NavSubItem from "./NavSubItem";
6
- import { Icon } from "@ax/components";
7
8
  import { NavContext } from "./../context";
8
9
 
9
10
  import * as S from "./style";
@@ -72,15 +73,19 @@ const NavItem = (props: IProps) => {
72
73
 
73
74
  const isSelectedSubItem = location.pathname === subLink.path ? true : false;
74
75
 
75
- return (
76
+ const navSubItem = (
76
77
  <NavSubItem key={subI} active={isSelectedSubItem} type={type}>
77
78
  <S.NavLink onClick={goToSubLink}>
78
- <S.LinkName active={isSelected}>
79
- {subLink.name}
80
- </S.LinkName>
79
+ <S.LinkName active={isSelected}>{subLink.name}</S.LinkName>
81
80
  </S.NavLink>
82
81
  </NavSubItem>
83
82
  );
83
+
84
+ return subLink.permission ? (
85
+ <Restricted to={subLink.permission} key={subI}>{navSubItem}</Restricted>
86
+ ) : (
87
+ navSubItem
88
+ );
84
89
  })}
85
90
  </>
86
91
  )}
@@ -5,9 +5,10 @@ import { version } from "./../../../../../package.json";
5
5
 
6
6
  import { IRouter, multisite, site } from "@ax/routes";
7
7
 
8
- import { IRootState } from "@ax/types";
8
+ import { IRootState, ISite } from "@ax/types";
9
9
  import { appActions } from "@ax/containers/App";
10
10
  import { Icon, Tag } from "@ax/components";
11
+ import { Restricted } from "@ax/guards";
11
12
 
12
13
  import NavItem from "./NavItem";
13
14
  import { NavProvider } from "./context";
@@ -54,7 +55,7 @@ const NavMenu = (props: IProps) => {
54
55
  };
55
56
 
56
57
  const goToProfile = () => {
57
- const profileRoute = isSite ? "/sites/profile" : "profile";
58
+ const profileRoute = isSite ? "/sites/profile" : "/profile";
58
59
  setHistoryPush(profileRoute);
59
60
  };
60
61
 
@@ -140,8 +141,8 @@ const NavMenu = (props: IProps) => {
140
141
  {config.routes &&
141
142
  config.routes
142
143
  .filter((route: IRouter) => route.showInNav)
143
- .map(
144
- (route: IRouter): JSX.Element => (
144
+ .map((route: IRouter): JSX.Element => {
145
+ const navItem = (
145
146
  <NavItem
146
147
  setHistoryPush={setHistoryPush}
147
148
  key={route.name}
@@ -150,8 +151,16 @@ const NavMenu = (props: IProps) => {
150
151
  type={config.type}
151
152
  isOpened={isOpened}
152
153
  />
153
- )
154
- )}
154
+ );
155
+
156
+ return route.permission ? (
157
+ <Restricted key={route.name} to={route.permission}>
158
+ {navItem}
159
+ </Restricted>
160
+ ) : (
161
+ navItem
162
+ );
163
+ })}
155
164
  </S.List>
156
165
  <S.List>
157
166
  {isSitePublished && (
@@ -190,7 +199,7 @@ interface IConfig {
190
199
 
191
200
  interface INavMenuProps {
192
201
  categories: any;
193
- currentSiteInfo: any;
202
+ currentSiteInfo: ISite | null;
194
203
  siteLanguages: any[];
195
204
  lang: any;
196
205
  }