@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
@@ -1,39 +1,45 @@
1
1
  import React from "react";
2
2
  import { Switch, Route } from "react-router-dom";
3
+ import { INavItem } from "@ax/types";
4
+ import { usePermission } from "@ax/hooks";
3
5
 
4
6
  import Globals from "./Globals";
5
7
  import Languages from "./Languages";
6
8
  import Social from "./Social";
7
9
 
8
- const navItems = [
10
+ const navItems: INavItem[] = [
9
11
  {
10
12
  title: "Globals",
11
13
  path: "/sites/settings/globals",
12
- component: Globals
14
+ component: Globals,
15
+ permission: "general.manageSiteSettings",
13
16
  },
14
17
  {
15
18
  title: "Languages",
16
19
  path: "/sites/settings/languages",
17
- component: Languages
20
+ component: Languages,
21
+ permission: "general.accessToLanguages",
18
22
  },
19
23
  {
20
24
  title: "Social",
21
25
  path: "/sites/settings/social",
22
- component: Social
26
+ component: Social,
27
+ permission: "general.manageSocialMedia",
23
28
  },
24
29
  ];
25
30
 
26
31
  const Settings = (): JSX.Element => {
27
32
  return (
28
33
  <Switch>
29
- {navItems.map((item, index) => (
30
- <Route exact path={item.path} key={index}>
31
- {React.createElement(item.component, {navItems, currentNavItem: item}, null)}
32
- </Route>
33
- )
34
- )}
34
+ {navItems.map((item, index) => {
35
+ const isAllowed = usePermission(item.permission);
36
+ return (
37
+ <Route exact path={item.path} key={index}>
38
+ {isAllowed && React.createElement(item.component, { navItems, currentNavItem: item }, null)}
39
+ </Route>
40
+ )})}
35
41
  </Switch>
36
- )
42
+ );
37
43
  };
38
44
 
39
45
  export default Settings;
@@ -1,7 +1,7 @@
1
1
  import React, { useState } from "react";
2
2
  import { connect } from "react-redux";
3
3
 
4
- import { useModal } from "@ax/hooks";
4
+ import { useModal, usePermission } from "@ax/hooks";
5
5
  import { isDevelopment } from "@ax/helpers";
6
6
  import { IGetSitesParams, ISite } from "@ax/types";
7
7
  import { appActions } from "@ax/containers/App";
@@ -19,6 +19,10 @@ const GridSiteItem = (props: IGridSiteItemProps): JSX.Element => {
19
19
  const [inputValue, setInputValue] = useState("");
20
20
  const { updated, isPublished } = site;
21
21
 
22
+ const allowedToDeleteSite = usePermission("general.deleteSite");
23
+ const allowedToPublishSite = usePermission("general.publishSite");
24
+ const allowedToUnpublishSite = usePermission("general.unpublishSite");
25
+
22
26
  const getPublishedState = (isPublished: boolean, updated: boolean) => {
23
27
  switch (isPublished) {
24
28
  case true:
@@ -44,22 +48,31 @@ const GridSiteItem = (props: IGridSiteItemProps): JSX.Element => {
44
48
  };
45
49
 
46
50
  const getPublishOption = (isPublished: boolean) =>
47
- isPublished ? { label: "Unpublish", icon: "offlinePending" } : { label: "Publish", icon: "uploadPending" };
48
-
49
- const publishOption = getPublishOption(isPublished);
50
-
51
- const menuOptions = [
52
- {
53
- label: "delete",
54
- icon: "delete",
55
- action: toggleDeleteModal,
56
- },
57
- {
58
- label: publishOption.label,
59
- icon: publishOption.icon,
60
- action: togglePublishModal,
61
- },
62
- ];
51
+ isPublished && allowedToUnpublishSite
52
+ ? { label: "Unpublish", icon: "offlinePending" }
53
+ : !isPublished && allowedToPublishSite
54
+ ? { label: "Publish", icon: "uploadPending" }
55
+ : null;
56
+
57
+ const publishOptionProps = getPublishOption(isPublished);
58
+
59
+ const deleteOption = allowedToDeleteSite
60
+ ? {
61
+ label: "delete",
62
+ icon: "delete",
63
+ action: toggleDeleteModal,
64
+ }
65
+ : undefined;
66
+
67
+ const publishOption = publishOptionProps
68
+ ? {
69
+ label: publishOptionProps.label,
70
+ icon: publishOptionProps.icon,
71
+ action: togglePublishModal,
72
+ }
73
+ : undefined;
74
+
75
+ const menuOptions = [deleteOption, publishOption];
63
76
 
64
77
  const handleDeleteSite = async () => {
65
78
  const params = getParams();
@@ -171,7 +184,7 @@ const GridSiteItem = (props: IGridSiteItemProps): JSX.Element => {
171
184
 
172
185
  interface IGridSiteItemProps {
173
186
  site: ISite;
174
- setSiteInfo(currentSiteInfo: any): Promise<void>;
187
+ setSiteInfo(currentSiteInfo: ISite): Promise<void>;
175
188
  setHistoryPush(page: string, isEditor: boolean): void;
176
189
  deleteSite(siteID: number, params?: IGetSitesParams): Promise<void>;
177
190
  publishSite(siteID: number, params?: IGetSitesParams): Promise<void>;
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
 
3
3
  import { BulkSelectionOptions } from "@ax/components";
4
+ import { usePermission } from "@ax/hooks";
4
5
 
5
6
  import TableHeader from "./TableHeader";
6
7
 
@@ -21,18 +22,26 @@ const BulkHeader = (props: IBulkHeaderProps): JSX.Element => {
21
22
  filterValues,
22
23
  } = props;
23
24
 
24
- const actions = [
25
- {
26
- icon: "upload-pending",
27
- text: "publish",
28
- action: bulkPublish,
29
- },
30
- {
31
- icon: "offline",
32
- text: "unpublish",
33
- action: bulkUnpublish,
34
- },
35
- ];
25
+ const allowedToPublishSite = usePermission("general.publishSite");
26
+ const allowedToUnpublishSite = usePermission("general.unpublishSite");
27
+
28
+ const publishAction = allowedToPublishSite
29
+ ? {
30
+ icon: "upload-pending",
31
+ text: "publish",
32
+ action: bulkPublish,
33
+ }
34
+ : undefined;
35
+
36
+ const unpublishAction = allowedToUnpublishSite
37
+ ? {
38
+ icon: "offline",
39
+ text: "unpublish",
40
+ action: bulkUnpublish,
41
+ }
42
+ : undefined;
43
+
44
+ const actions = [publishAction, unpublishAction];
36
45
 
37
46
  return showBulk ? (
38
47
  <S.BulkWrapper data-testid="sites-list-bulk-wrapper">
@@ -1,7 +1,7 @@
1
1
  import React, { useState } from "react";
2
2
  import { connect } from "react-redux";
3
3
 
4
- import { useModal } from "@ax/hooks";
4
+ import { useModal, usePermission } from "@ax/hooks";
5
5
  import { getFormattedDateWithTimezone } from "@ax/helpers";
6
6
  import { ICheck, IGetSitesParams, ISite } from "@ax/types";
7
7
  import { appActions } from "@ax/containers/App";
@@ -21,6 +21,10 @@ const ListSiteItem = (props: IListSiteItemProps): JSX.Element => {
21
21
  const [inputValue, setInputValue] = useState("");
22
22
  const { updated, isPublished } = site;
23
23
 
24
+ const allowedToDeleteSite = usePermission("general.deleteSite");
25
+ const allowedToPublishSite = usePermission("general.publishSite");
26
+ const allowedToUnpublishSite = usePermission("general.unpublishSite");
27
+
24
28
  const getPublishedState = (isPublished: boolean, updated: boolean) => {
25
29
  switch (isPublished) {
26
30
  case true:
@@ -46,22 +50,31 @@ const ListSiteItem = (props: IListSiteItemProps): JSX.Element => {
46
50
  };
47
51
 
48
52
  const getPublishOption = (isPublished: boolean) =>
49
- isPublished ? { label: "Unpublish", icon: "offlinePending" } : { label: "Publish", icon: "uploadPending" };
50
-
51
- const publishOption = getPublishOption(isPublished);
52
-
53
- const menuOptions = [
54
- {
55
- label: "delete",
56
- icon: "delete",
57
- action: toggleDeleteModal,
58
- },
59
- {
60
- label: publishOption.label,
61
- icon: publishOption.icon,
62
- action: togglePublishModal,
63
- },
64
- ];
53
+ isPublished && allowedToUnpublishSite
54
+ ? { label: "Unpublish", icon: "offlinePending" }
55
+ : allowedToPublishSite
56
+ ? { label: "Publish", icon: "uploadPending" }
57
+ : null;
58
+
59
+ const publishOptionProps = getPublishOption(isPublished);
60
+
61
+ const deleteOption = allowedToDeleteSite
62
+ ? {
63
+ label: "delete",
64
+ icon: "delete",
65
+ action: toggleDeleteModal,
66
+ }
67
+ : undefined;
68
+
69
+ const publishOption = publishOptionProps
70
+ ? {
71
+ label: publishOptionProps.label,
72
+ icon: publishOptionProps.icon,
73
+ action: togglePublishModal,
74
+ }
75
+ : undefined;
76
+
77
+ const menuOptions = [deleteOption, publishOption];
65
78
 
66
79
  const handleDeleteSite = async () => {
67
80
  const params = getParams();
@@ -185,7 +198,7 @@ const ListSiteItem = (props: IListSiteItemProps): JSX.Element => {
185
198
  interface IListSiteItemProps {
186
199
  site: ISite;
187
200
  isSelected: boolean;
188
- setSiteInfo(currentSiteInfo: any): Promise<void>;
201
+ setSiteInfo(currentSiteInfo: ISite): Promise<void>;
189
202
  setHistoryPush(site: string, isEditor: boolean): void;
190
203
  deleteSite(siteID: number, params?: IGetSitesParams): Promise<void>;
191
204
  publishSite(siteID: number, params?: IGetSitesParams): Promise<void>;
@@ -38,7 +38,7 @@ const RecentSiteItem = (props: IRecentSiteItemProps): JSX.Element => {
38
38
 
39
39
  interface IRecentSiteItemProps {
40
40
  site: ISite;
41
- setSiteInfo(currentSiteInfo: any): Promise<void>;
41
+ setSiteInfo(currentSiteInfo: ISite): Promise<void>;
42
42
  setHistoryPush(page: string, isEditor: boolean): void;
43
43
  }
44
44
 
@@ -3,9 +3,9 @@ import { connect } from "react-redux";
3
3
 
4
4
  import { appActions } from "@ax/containers/App";
5
5
  import { sitesActions } from "@ax/containers/Sites";
6
- import { ICheck, IGetSitesParams, IRootState, ISettingsForm, ISite, ISiteListConfig, IUser } from "@ax/types";
6
+ import { ICheck, IGetSitesParams, IRootState, ISettingsForm, ISite, ISiteListConfig } from "@ax/types";
7
7
  import { IError } from "@ax/containers/App/reducer";
8
- import { useBulkSelection, useModal } from "@ax/hooks";
8
+ import { useBulkSelection, useModal, usePermission } from "@ax/hooks";
9
9
  import { MainWrapper, Modal, ErrorToast, Icon, IconAction, TableList, EmptyState, Pagination } from "@ax/components";
10
10
 
11
11
  import { useFilterQuery, useSortedListStatus, useIsMount } from "./hooks";
@@ -28,7 +28,6 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
28
28
  totalItems,
29
29
  saveSettings,
30
30
  setHistoryPush,
31
- currentUser,
32
31
  getSites,
33
32
  publishSitesBulk,
34
33
  unpublishSitesBulk,
@@ -66,6 +65,8 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
66
65
  const tableRef = useRef<HTMLDivElement>(null);
67
66
  const errorRef = useRef<HTMLDivElement>(null);
68
67
 
68
+ const allowedToCreateSite = usePermission("general.createSite");
69
+
69
70
  const pagination = {
70
71
  setPage,
71
72
  itemsPerPage,
@@ -76,10 +77,12 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
76
77
  const { isOpen, toggleModal } = useModal();
77
78
 
78
79
  const openModal = () => toggleModal();
79
- const rightButtonProps = {
80
- label: "New",
81
- action: openModal,
82
- };
80
+ const rightButtonProps = allowedToCreateSite
81
+ ? {
82
+ label: "New",
83
+ action: openModal,
84
+ }
85
+ : undefined;
83
86
 
84
87
  const { setSortedListStatus } = useSortedListStatus();
85
88
  const { setFiltersSelection, setFilterQuery, filterValues } = useFilterQuery(currentConfig.filterValues);
@@ -148,8 +151,6 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
148
151
  const mainAction = { title: "Create site", onClick: saveSiteSettings, disabled: isSubmitDisabled };
149
152
  const secondaryAction = { title: "Cancel", onClick: toggleModal };
150
153
 
151
- const userHasSite = (siteID: number) => currentUser.sites.includes("all") || currentUser.sites.includes(siteID);
152
-
153
154
  const toggleRecentSites = () => {
154
155
  const updatedConfig = { ...config, displayRecentSites: !isRecentSitesListDisplayed };
155
156
  setListConfig(updatedConfig);
@@ -204,13 +205,12 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
204
205
  </S.SectionHeader>
205
206
  );
206
207
 
207
- const currentRecentSites = recentSites.filter((site: ISite) => userHasSite(site.id));
208
208
  const RecentSitesList = () => {
209
209
  return (
210
- <S.RecentSites data-testid="recent-sites-list" fullWidth={currentRecentSites.length >= 5}>
210
+ <S.RecentSites data-testid="recent-sites-list" fullWidth={recentSites.length >= 5}>
211
211
  <RecentSitesHeader />
212
212
  <S.RecentSitesItemsWrapper data-testid="recent-sites-items-wrapper" isHidden={!isRecentSitesListDisplayed}>
213
- {currentRecentSites.map((site: ISite, i: number) => (
213
+ {recentSites.map((site: ISite, i: number) => (
214
214
  <RecentSiteItem key={i} site={site} />
215
215
  ))}
216
216
  </S.RecentSitesItemsWrapper>
@@ -288,11 +288,9 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
288
288
  />
289
289
  );
290
290
 
291
- const currentSites = sites.filter((site: ISite) => userHasSite(site.id));
292
-
293
291
  const mappedSites =
294
- currentSites.length > 0 ? (
295
- currentSites.map((site: ISite) => {
292
+ sites.length > 0 ? (
293
+ sites.map((site: ISite) => {
296
294
  const isItemSelected = isSelected(site.id);
297
295
  return displayMode === "grid" ? (
298
296
  <GridSiteItem key={site.id} site={site} getParams={getParams} />
@@ -316,11 +314,7 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
316
314
  const showPagination = totalItems > itemsPerPage;
317
315
  return (
318
316
  <>
319
- <S.GridList
320
- data-testid="sites-grid-list"
321
- isEmpty={currentSites.length === 0}
322
- fullWidth={currentSites.length >= 5}
323
- >
317
+ <S.GridList data-testid="sites-grid-list" isEmpty={sites.length === 0} fullWidth={sites.length >= 5}>
324
318
  {mappedSites}
325
319
  </S.GridList>
326
320
  {showPagination && (
@@ -350,7 +344,7 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
350
344
  <MainWrapper title="Sites" rightButton={rightButtonProps} searchAction={setSearchQuery} hasAnimation={hasAnimation}>
351
345
  <ErrorToast ref={errorRef} />
352
346
  <S.SitesListWrapper className={hasAnimation ? "animate" : ""}>
353
- {currentRecentSites?.length > 0 ? <RecentSitesList /> : null}
347
+ {recentSites?.length > 0 ? <RecentSitesList /> : null}
354
348
  <AllSitesHeader />
355
349
  <AllSitesList />
356
350
  </S.SitesListWrapper>
@@ -371,7 +365,6 @@ const SitesList = (props: ISitesListProps): JSX.Element => {
371
365
  interface ISitesProps {
372
366
  sites: ISite[];
373
367
  recentSites: ISite[];
374
- currentUser: IUser;
375
368
  totalItems: number;
376
369
  token: string;
377
370
  error: IError;
@@ -381,7 +374,6 @@ interface ISitesProps {
381
374
  }
382
375
 
383
376
  const mapStateToProps = (state: IRootState) => ({
384
- currentUser: state.users.currentUser,
385
377
  totalItems: state.sites.sitesTotalItems,
386
378
  token: state.app.token,
387
379
  sites: state.sites.sites,
@@ -3,7 +3,7 @@ import React, { useLayoutEffect } from "react";
3
3
  import { connect } from "react-redux";
4
4
  import { withRouter, RouteComponentProps } from "react-router-dom";
5
5
 
6
- import { IRootState } from "@ax/types";
6
+ import { IGetRoles, IRootState, ISite } from "@ax/types";
7
7
  import { Loading } from "@ax/components";
8
8
  import { appActions } from "@ax/containers/App";
9
9
  import { sitesActions } from "@ax/containers/Sites";
@@ -23,12 +23,14 @@ const Sites = (props: ISitesProps): JSX.Element => {
23
23
  getAllDataPacks,
24
24
  getUser,
25
25
  globalLangs,
26
+ getRoles,
26
27
  hasAnimation,
27
28
  } = props;
28
29
 
29
30
  useLayoutEffect(() => {
30
31
  const fetchInitialData = async () => {
31
32
  setCurrentSiteInfo(null);
33
+ await getRoles({ siteId: "global" }, token);
32
34
  await getUser("me", token);
33
35
  await getStructuredData(token);
34
36
  await getAllDataPacks();
@@ -67,11 +69,12 @@ interface IStateProps {
67
69
  }
68
70
 
69
71
  interface IDispatchProps {
70
- setCurrentSiteInfo(currentSiteInfo: any): void;
71
- getStructuredData(token: string, siteId?: number): Promise<void>;
72
+ setCurrentSiteInfo(currentSiteInfo: ISite | null): void;
73
+ getStructuredData(token: string, siteId?: number | null): Promise<void>;
72
74
  setLanguage(lang: { locale: string; id: number | null }): void;
73
75
  getAllDataPacks: () => Promise<void>;
74
76
  getUser: (id: string, token?: string) => Promise<void>;
77
+ getRoles: (params: IGetRoles, token?: string) => Promise<void>;
75
78
  }
76
79
 
77
80
  export type ISitesProps = IStateProps & IDispatchProps & RouteComponentProps;
@@ -82,6 +85,7 @@ const mapDispatchToProps = {
82
85
  setLanguage: appActions.setLanguage,
83
86
  getAllDataPacks: dataPacksActions.getAllDataPacks,
84
87
  getUser: usersActions.getUser,
88
+ getRoles: usersActions.getRoles,
85
89
  };
86
90
 
87
91
  export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Sites));
@@ -371,4 +371,4 @@ const mapDispatchToProps = {
371
371
  setFormValues: structuredDataActions.setFormValues,
372
372
  };
373
373
 
374
- export default connect(mapStateToProps, mapDispatchToProps)(Form);
374
+ export default connect(mapStateToProps, mapDispatchToProps)(Form);
@@ -1,8 +1,8 @@
1
1
  import React from "react";
2
2
  import { BulkSelectionOptions } from "@ax/components";
3
- import TableHeader from "./TableHeader";
4
-
5
3
  import { IColumn, IStructuredDataQueryValues, IStructuredDataSortedInitialState } from "@ax/types";
4
+ import { usePermission } from "@ax/hooks";
5
+ import TableHeader from "./TableHeader";
6
6
 
7
7
  const BulkHeader = (props: IProps): JSX.Element => {
8
8
  const {
@@ -27,13 +27,16 @@ const BulkHeader = (props: IProps): JSX.Element => {
27
27
  setColumns,
28
28
  } = props;
29
29
 
30
+ const isAllowedToPublishPages = usePermission("global.globalData.publishUnpublishAllGlobalData");
31
+ const isAllowedToDeletePage = usePermission("global.globalData.deleteAllGlobalData");
32
+
30
33
  const deleteAction = {
31
34
  icon: "delete",
32
35
  text: "delete",
33
36
  action: bulkDelete,
34
37
  };
35
38
 
36
- const actions = [
39
+ const actions = isAllowedToPublishPages ? [
37
40
  {
38
41
  icon: "upload-pending",
39
42
  text: "publish",
@@ -44,9 +47,9 @@ const BulkHeader = (props: IProps): JSX.Element => {
44
47
  text: "unpublish",
45
48
  action: bulkUnpublish,
46
49
  },
47
- ];
50
+ ] : [];
48
51
 
49
- const bulkActions = isEditable ? [deleteAction, ...actions] : actions;
52
+ const bulkActions = isEditable && isAllowedToDeletePage ? [deleteAction, ...actions] : actions;
50
53
 
51
54
  return showBulk ? (
52
55
  <BulkSelectionOptions
@@ -14,7 +14,7 @@ import { getFilters } from "./utils";
14
14
  import * as S from "./style";
15
15
 
16
16
  const ContentFilters = (props: IProps): JSX.Element => {
17
- const { setFilter, current, dynamicValues, onClick, addNew } = props;
17
+ const { setFilter, current, dynamicValues, onClick, addNew, isAllowedToCreate } = props;
18
18
  const clonedStructure = deepClone(filterStructure);
19
19
  const filters = getFilters(clonedStructure, dynamicValues);
20
20
 
@@ -43,11 +43,13 @@ const ContentFilters = (props: IProps): JSX.Element => {
43
43
  };
44
44
 
45
45
  return (
46
- <MenuItem key={filterKey} onClick={handleClick} extendedAction={isSelected && editable ? extendedAction : null}>
46
+ <MenuItem
47
+ key={filterKey}
48
+ onClick={handleClick}
49
+ extendedAction={isSelected && editable && isAllowedToCreate ? extendedAction : null}
50
+ >
47
51
  <NavLink to="#" className={selectedClass}>
48
- <S.Link active={isSelected}>
49
- {name}
50
- </S.Link>
52
+ <S.Link active={isSelected}>{name}</S.Link>
51
53
  </NavLink>
52
54
  </MenuItem>
53
55
  );
@@ -66,6 +68,7 @@ interface IProps {
66
68
  dynamicValues: IStructuredData[];
67
69
  onClick(dataID: string): void;
68
70
  addNew: () => void;
71
+ isAllowedToCreate: boolean;
69
72
  }
70
73
 
71
74
  const mapDispatchToProps = {
@@ -17,7 +17,7 @@ import {
17
17
  CategoryCell,
18
18
  } from "@ax/components";
19
19
  import { pageEditorActions } from "@ax/containers/PageEditor";
20
- import { useAdaptiveText, useModal } from "@ax/hooks";
20
+ import { useAdaptiveText, useModal, usePermission } from "@ax/hooks";
21
21
  import { DeleteModal, DuplicateModal, UnpublishModal } from "./atoms";
22
22
  import { getCurrentLanguages } from "./utils";
23
23
 
@@ -82,6 +82,12 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
82
82
  const path = useAdaptiveText(nameCellRef, fullPath.page, nameCellPadding);
83
83
  const API_URL = process.env.REACT_APP_API_ENDPOINT;
84
84
 
85
+ const isAllowedToDuplicatePages = usePermission("global.globalData.duplicateGlobalData");
86
+ const isAllowedToPublishPages = usePermission("global.globalData.publishUnpublishAllGlobalData");
87
+ const isAllowedToCreatePages = usePermission("global.globalData.createAllGlobalData");
88
+ const isAllowedToDeletePage = usePermission("global.globalData.deleteAllGlobalData");
89
+ const isAllowedToEditContentPage = usePermission("global.globalData.editAllGlobalData");
90
+
85
91
  const publishedTooltip: Record<string, string> = {
86
92
  active: "Live",
87
93
  "upload-pending": "Publication pending",
@@ -185,18 +191,23 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
185
191
  setHistoryPush("data/pages/editor", true);
186
192
  };
187
193
 
188
- let menuOptions = [
189
- {
194
+ let menuOptions = [];
195
+
196
+ if (isAllowedToDuplicatePages) {
197
+ menuOptions.push({
190
198
  label: "duplicate",
191
199
  icon: "duplicate",
192
200
  action: toggleDuplicateModal,
193
- },
194
- {
201
+ });
202
+ }
203
+
204
+ if (isAllowedToDeletePage) {
205
+ menuOptions.push({
195
206
  label: "delete",
196
207
  icon: "delete",
197
208
  action: toggleDeleteModal,
198
- },
199
- ];
209
+ });
210
+ }
200
211
 
201
212
  const getPublishItem = (status: string) => {
202
213
  switch (status) {
@@ -233,12 +244,6 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
233
244
  };
234
245
 
235
246
  const editOptions = [
236
- {
237
- label: "Edit draft",
238
- icon: "modified",
239
- action: _handleClick,
240
- color: true,
241
- },
242
247
  {
243
248
  label: "View live",
244
249
  icon: "active",
@@ -247,8 +252,17 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
247
252
  },
248
253
  ];
249
254
 
255
+ if (isAllowedToEditContentPage) {
256
+ editOptions.unshift({
257
+ label: "Edit draft",
258
+ icon: "modified",
259
+ action: _handleClick,
260
+ color: true,
261
+ });
262
+ }
263
+
250
264
  const publishAction = getPublishItem(globalPage.liveStatus.status);
251
- menuOptions = publishAction ? [publishAction, ...menuOptions] : menuOptions;
265
+ menuOptions = publishAction && isAllowedToPublishPages ? [publishAction, ...menuOptions] : menuOptions;
252
266
 
253
267
  menuOptions = globalPage.haveDraftPage ? [...editOptions, ...menuOptions] : menuOptions;
254
268
 
@@ -309,7 +323,7 @@ const GlobalPageItem = (props: IGlobalPageItemProps): JSX.Element => {
309
323
  const languageMenu = () => (
310
324
  <LanguageMenu
311
325
  language={locale}
312
- availableLanguages={languages}
326
+ availableLanguages={isAllowedToCreatePages ? languages : currentLanguages}
313
327
  setLanguage={handleLanguage}
314
328
  currentLanguages={currentLanguages}
315
329
  />