@griddo/ax 11.0.4 → 11.0.5

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "11.0.4",
4
+ "version": "11.0.5",
5
5
  "authors": [
6
6
  "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
7
  "Carlos Torres <carlos.torres@secuoyas.com>",
@@ -229,5 +229,5 @@
229
229
  "publishConfig": {
230
230
  "access": "public"
231
231
  },
232
- "gitHead": "b97706dc29f2f8066e22ca49a9ee9c8959e8f820"
232
+ "gitHead": "b528c1933f0fe79e4feedacd2247336ab8f967a4"
233
233
  }
@@ -15,8 +15,8 @@ const FileField = (props: IFileFieldProps): JSX.Element => {
15
15
  const validFormats =
16
16
  allowedFormats && allowedFormats.length
17
17
  ? allowedFormats
18
- : ["pdf", "doc", "docx", "xls", "xlsx", "zip", "csv", "txt"];
19
-
18
+ : ["pdf", "doc", "docx", "xls", "xlsx", "zip", "csv", "txt", "mov", "mp4", "wmv", "avi", "webm", "mkv"];
19
+ const videoFormats = ["mov", "mp4", "wmv", "avi", "webm", "mkv"];
20
20
  const handleClick = () => {
21
21
  if (!disabled) {
22
22
  toggleModal();
@@ -92,7 +92,10 @@ const FileField = (props: IFileFieldProps): JSX.Element => {
92
92
  <Icon name="File" size="24" />
93
93
  </S.IconWrapper>
94
94
  </S.Field>
95
- <S.HelpText>Valid formats: {validFormats.join(", ")}. Max. size: 50MB</S.HelpText>
95
+ <S.HelpText>
96
+ Valid formats: {validFormats.filter((format) => !videoFormats.includes(format)).join(", ")} and videos. Max.
97
+ size: 50MB
98
+ </S.HelpText>
96
99
  </>
97
100
  )}
98
101
  {value && (
@@ -25,7 +25,7 @@ const GalleryDragAndDrop = (props: IProps) => {
25
25
  resetGalleryState,
26
26
  } = props;
27
27
  const validExtensions = validFormats.map((format) => `.${format}`).join(",");
28
-
28
+ const videoFormats = ["mov", "mp4", "wmv", "avi", "webm", "mkv"];
29
29
  const filesInputRef = useRef<HTMLInputElement>(null);
30
30
  const filesButtonRef = useRef<HTMLButtonElement>(null);
31
31
  const [inDropZone, setInDropZone] = useState(false);
@@ -130,7 +130,9 @@ const GalleryDragAndDrop = (props: IProps) => {
130
130
  <S.FilesButton ref={filesButtonRef} type="button" buttonStyle="line" onClick={handleFileClick}>
131
131
  Select files
132
132
  </S.FilesButton>
133
- <S.DragSubtitle>Valid formats: {validFormats.join(", ")}</S.DragSubtitle>
133
+ <S.DragSubtitle>
134
+ Valid formats: {validFormats.filter((format) => !videoFormats.includes(format)).join(", ")} and videos.
135
+ </S.DragSubtitle>
134
136
  <S.DragSubtitle>Max. size: 50MB</S.DragSubtitle>
135
137
  </S.DragStatus>
136
138
  <S.DragOverStatus onDragEnter={handleDragEnter} onDragLeave={handleDragLeave}>
@@ -138,7 +140,9 @@ const GalleryDragAndDrop = (props: IProps) => {
138
140
  <Icon name="success" size="36" />
139
141
  </S.DragIcon>
140
142
  <S.DragTitle>Drop your file</S.DragTitle>
141
- <S.DragSubtitle>Valid formats: {validFormats.join(", ")}</S.DragSubtitle>
143
+ <S.DragSubtitle>
144
+ Valid formats: {validFormats.filter((format) => !videoFormats.includes(format)).join(", ")} and videos.
145
+ </S.DragSubtitle>
142
146
  <S.DragSubtitle>Max. size: 50MB</S.DragSubtitle>
143
147
  </S.DragOverStatus>
144
148
  </S.StatusWrapper>
@@ -7,7 +7,7 @@ import { IContentFilter } from "@ax/types";
7
7
  import * as S from "./style";
8
8
 
9
9
  const MenuGroup = (props: IProps): JSX.Element => {
10
- const { filter, current, isAllowedToCreate, onClick, addNew } = props;
10
+ const { filter, current, isAllowedToCreate, isAllowedToAccessPrivate, onClick, addNew } = props;
11
11
 
12
12
  const [isOpen, setIsOpen] = useState(true);
13
13
  const [isSelected, setIsSelected] = useState(false);
@@ -47,7 +47,7 @@ const MenuGroup = (props: IProps): JSX.Element => {
47
47
  <S.Dropdown isOpen={isOpen}>
48
48
  {filter.items &&
49
49
  filter.items.map((filter) => {
50
- const { label, value, fromPage, firstTemplate, editable, isPrivate } = filter;
50
+ const { label, value, fromPage, firstTemplate, editable, isPrivate = false } = filter;
51
51
 
52
52
  const isSelected = value === current;
53
53
  const selectedClass = isSelected ? "selected" : "";
@@ -58,10 +58,13 @@ const MenuGroup = (props: IProps): JSX.Element => {
58
58
  onClick={() => handleClick(value, fromPage, firstTemplate)}
59
59
  extendedAction={editable && isAllowedToCreate ? extendedAction : null}
60
60
  className={selectedClass}
61
+ disabled={isPrivate && !isAllowedToAccessPrivate}
61
62
  >
62
63
  <NavLink to="#">
63
64
  <S.Link>
64
- <S.Text active={isSelected}>{label}</S.Text>
65
+ <S.Text active={isSelected} disabled={isPrivate && !isAllowedToAccessPrivate}>
66
+ {label}
67
+ </S.Text>
65
68
  {isPrivate && (
66
69
  <S.Icon>
67
70
  <Icon name="lock" size="16" />
@@ -81,6 +84,7 @@ interface IProps {
81
84
  filter: IContentFilter;
82
85
  current: string | undefined;
83
86
  isAllowedToCreate: boolean;
87
+ isAllowedToAccessPrivate: boolean;
84
88
  onClick: (value: string, fromPage: boolean, firstTemplate: string | null) => void;
85
89
  addNew: () => void;
86
90
  }
@@ -48,9 +48,14 @@ const Icon = styled.div`
48
48
  margin-right: ${(p) => p.theme.spacing.xs};
49
49
  `;
50
50
 
51
- const Text = styled.div<{ active: boolean }>`
51
+ const Text = styled.div<{ active: boolean; disabled: boolean }>`
52
52
  ${(p) => p.theme.textStyle.uiS};
53
- color: ${(p) => (p.active ? p.theme.color.textHighEmphasis : p.theme.color.textMediumEmphasis)};
53
+ color: ${(p) =>
54
+ p.disabled
55
+ ? p.theme.color.interactiveDisabled
56
+ : p.active
57
+ ? p.theme.color.textHighEmphasis
58
+ : p.theme.color.textMediumEmphasis};
54
59
  `;
55
60
 
56
61
  export { Item, NavLink, Title, Arrow, Dropdown, Link, Icon, Text };
@@ -4,10 +4,10 @@ import { IconAction } from "@ax/components";
4
4
  import * as S from "./style";
5
5
 
6
6
  const MenuItem = (props: IMenuItemProps): JSX.Element => {
7
- const { children, onClick, extendedAction, className } = props;
7
+ const { children, onClick, extendedAction, className, disabled = false } = props;
8
8
 
9
9
  const handleOnClick = (e: React.MouseEvent<HTMLLIElement>) => {
10
- if (onClick !== undefined) {
10
+ if (onClick !== undefined && !disabled) {
11
11
  e.preventDefault();
12
12
  onClick(e);
13
13
  }
@@ -24,6 +24,7 @@ const MenuItem = (props: IMenuItemProps): JSX.Element => {
24
24
  className={className}
25
25
  onlyOnHover={(extendedAction && extendedAction.onlyOnHover) ?? true}
26
26
  data-testid="menu-subitem"
27
+ disabled={disabled}
27
28
  >
28
29
  <div>{children}</div>
29
30
  {extendedAction && (
@@ -42,6 +43,7 @@ export interface IMenuItemProps {
42
43
  onClick?: (e: React.MouseEvent<HTMLLIElement>) => void;
43
44
  extendedAction?: { icon: string; action: () => void; onlyOnHover?: boolean } | null;
44
45
  className?: string;
46
+ disabled?: boolean;
45
47
  }
46
48
 
47
49
  export default MenuItem;
@@ -10,11 +10,11 @@ const ExtendedAction = styled.div`
10
10
  display: none;
11
11
  `;
12
12
 
13
- const SubItem = styled.li<{ onlyOnHover: boolean }>`
13
+ const SubItem = styled.li<{ onlyOnHover: boolean; disabled: boolean }>`
14
14
  ${(p) => p.theme.textStyle.uiM};
15
15
  display: flex;
16
16
  align-items: center;
17
- color: ${(p) => p.theme.color.textHighEmphasis};
17
+ color: ${(p) => (p.disabled ? p.theme.color.disabled : p.theme.color.textHighEmphasis)};
18
18
  width: 100%;
19
19
  margin-bottom: ${(p) => p.theme.spacing.xxs};
20
20
  margin-top: ${(p) => p.theme.spacing.xxs};
@@ -35,19 +35,19 @@ const SubItem = styled.li<{ onlyOnHover: boolean }>`
35
35
  }
36
36
 
37
37
  :hover {
38
- cursor: pointer;
38
+ cursor: ${(p) => (p.disabled ? "default" : "pointer")};
39
39
  ${ExtendedAction} {
40
40
  display: ${(p) => (p.onlyOnHover ? "block" : "none")};
41
41
  }
42
42
  }
43
43
 
44
44
  :hover:before {
45
- background-color: ${(p) => p.theme.color.overlayHoverPrimary};
45
+ background-color: ${(p) => (p.disabled ? "transparent" : p.theme.color.overlayHoverPrimary)};
46
46
  opacity: 1;
47
47
  }
48
48
 
49
49
  :active:before {
50
- background-color: ${(p) => p.theme.color.overlayPressedPrimary};
50
+ background-color: ${(p) => (p.disabled ? "transparent" : p.theme.color.overlayPressedPrimary)};
51
51
  opacity: 1;
52
52
  }
53
53
 
@@ -12,6 +12,11 @@ const getFileIcon = (type: string) => {
12
12
  case "zip":
13
13
  return "zip.png";
14
14
  case "mp4":
15
+ case "mov":
16
+ case "wmv":
17
+ case "avi":
18
+ case "webm":
19
+ case "mkv":
15
20
  case "mpg":
16
21
  case "mp2":
17
22
  case "mpeg":
@@ -8,6 +8,8 @@ import { pageEditorActions } from "@ax/containers/PageEditor";
8
8
  import { INITIAL_TEMPLATE } from "@ax/containers/PageEditor/constants";
9
9
  import { structuredDataActions } from "@ax/containers/StructuredData";
10
10
  import { IQueryValue, IStructuredData } from "@ax/types";
11
+ import { usePermission } from "@ax/hooks";
12
+
11
13
  import { getFilters } from "./utils";
12
14
 
13
15
  import * as S from "./style";
@@ -27,6 +29,14 @@ const ContentFilters = (props: IProps): JSX.Element => {
27
29
  addNew,
28
30
  } = props;
29
31
 
32
+ const privatePermissions = [
33
+ "content.createPrivateContentTypes",
34
+ "content.deletePrivateContentTypes",
35
+ "content.duplicatePrivateContentTypes",
36
+ "content.publishUnpublishPrivateContentTypes",
37
+ ];
38
+ const isAllowedToAccessPrivate = usePermission(privatePermissions);
39
+
30
40
  const type = typeFilters[0].value;
31
41
  const filters = getFilters(dynamicValues);
32
42
 
@@ -80,6 +90,7 @@ const ContentFilters = (props: IProps): JSX.Element => {
80
90
  onClick={handleClick}
81
91
  addNew={addNew}
82
92
  isAllowedToCreate={isAllowedToCreate}
93
+ isAllowedToAccessPrivate={isAllowedToAccessPrivate}
83
94
  />
84
95
  )}
85
96
  </React.Fragment>
@@ -207,7 +207,10 @@ const Content = (props: IProps): JSX.Element => {
207
207
 
208
208
  const [isDeleting, setIsDeleting] = useState<boolean>(false);
209
209
 
210
- const isAllowedToCreatePages = usePermission("content.createPages");
210
+ const createPermission = isDataPrivate ? "content.createPrivateContentTypes" : "content.createPages";
211
+ const exportPermission = isDataPrivate ? "content.exportPrivateContentTypes" : "content.exportContentTypes";
212
+ const isAllowedToCreatePages = usePermission(createPermission);
213
+ const isAllowedToExport = usePermission(exportPermission);
211
214
 
212
215
  const {
213
216
  resetBulkSelection,
@@ -550,14 +553,15 @@ const Content = (props: IProps): JSX.Element => {
550
553
  setFiltersSelection(filterPointer, filtersSelected);
551
554
  };
552
555
 
553
- const exportContent = isDataExportable
554
- ? async (formats: (number | string)[]) => {
555
- if (currentStructuredData && formats.length) {
556
- const ids = selectedItems.all.length ? selectedItems.all : undefined;
557
- await exportDataContent(currentStructuredData?.id, { format: formats as string[], ids });
556
+ const exportContent =
557
+ isDataExportable && isAllowedToExport
558
+ ? async (formats: (number | string)[]) => {
559
+ if (currentStructuredData && formats.length) {
560
+ const ids = selectedItems.all.length ? selectedItems.all : undefined;
561
+ await exportDataContent(currentStructuredData?.id, { format: formats as string[], ids });
562
+ }
558
563
  }
559
- }
560
- : undefined;
564
+ : undefined;
561
565
 
562
566
  const Header = (
563
567
  <BulkHeader
@@ -28,7 +28,7 @@ const FileDragAndDrop = (props: IProps) => {
28
28
  } = props;
29
29
 
30
30
  const validExtensions = validFormats.map((format) => `.${format}`).join(",");
31
-
31
+ const videoFormats = ["mov", "mp4", "wmv", "avi", "webm", "mkv"];
32
32
  const filesInputRef = useRef<any>(null);
33
33
  const filesButtonRef = useRef<any>(null);
34
34
  const [inDropZone, setInDropZone] = useState(false);
@@ -169,7 +169,8 @@ const FileDragAndDrop = (props: IProps) => {
169
169
  Select files
170
170
  </S.FilesButton>
171
171
  <S.DragSubtitle>
172
- Valid formats: {validFormats.join(", ")}.<br />
172
+ Valid formats: {validFormats.filter((format) => !videoFormats.includes(format)).join(", ")} and videos.
173
+ <br />
173
174
  Max. size: 50MB
174
175
  </S.DragSubtitle>
175
176
  </S.DragStatus>
@@ -179,7 +180,8 @@ const FileDragAndDrop = (props: IProps) => {
179
180
  </S.DropIcon>
180
181
  <S.DragTitle>Drop your file</S.DragTitle>
181
182
  <S.DragSubtitle>
182
- Valid formats: {validFormats.join(", ")}.<br />
183
+ Valid formats: {validFormats.filter((format) => !videoFormats.includes(format)).join(", ")} and videos.
184
+ <br />
183
185
  Max. size: 50MB
184
186
  </S.DragSubtitle>
185
187
  </S.DragOverStatus>
@@ -38,7 +38,7 @@ const FileModal = (props: IProps) => {
38
38
  const iconUrl = `/img/icons/${getFileIcon(fileType)}`;
39
39
  const index = items.indexOf(file.id);
40
40
 
41
- const validFormats = ["pdf", "doc", "docx", "xls", "xlsx", "zip"];
41
+ const validFormats = ["pdf", "doc", "docx", "xls", "xlsx", "zip", "mov", "mp4", "wmv", "avi", "webm", "mkv"];
42
42
 
43
43
  const handleArrowClick = (isPrev: boolean) => () => {
44
44
  if (isDirty) {
@@ -122,7 +122,22 @@ const FileDrive = (props: IProps) => {
122
122
  const hasFolders = !!folders.length;
123
123
  const isRoot = !breadcrumb.length;
124
124
  const isGrid = displayMode === "grid";
125
- const validFormats = ["pdf", "doc", "docx", "xls", "xlsx", "zip", "csv", "txt"];
125
+ const validFormats = [
126
+ "pdf",
127
+ "doc",
128
+ "docx",
129
+ "xls",
130
+ "xlsx",
131
+ "zip",
132
+ "csv",
133
+ "txt",
134
+ "mov",
135
+ "mp4",
136
+ "wmv",
137
+ "avi",
138
+ "webm",
139
+ "mkv",
140
+ ];
126
141
 
127
142
  const allowedToAccessGlobalFromSite = usePermission("mediaGallery.accessToGlobalFileDriveFromSite");
128
143
 
@@ -5,6 +5,7 @@ import { NavLink } from "react-router-dom";
5
5
  import { IStructuredData } from "@ax/types";
6
6
  import { MenuGroup, MenuItem, SubNav } from "@ax/components";
7
7
  import { pageEditorActions } from "@ax/containers/PageEditor";
8
+ import { usePermission } from "@ax/hooks";
8
9
 
9
10
  import { getFilters } from "./utils";
10
11
 
@@ -13,6 +14,14 @@ import * as S from "./style";
13
14
  const ContentFilters = (props: IProps): JSX.Element => {
14
15
  const { current, dynamicValues, onClick, addNew, isAllowedToCreate } = props;
15
16
 
17
+ const privatePermissions = [
18
+ "global.content.createPrivateContentTypes",
19
+ "global.content.deletePrivateContentTypes",
20
+ "global.content.duplicatePrivateContentTypes",
21
+ "global.content.publishUnpublishPrivateContentTypes",
22
+ ];
23
+ const isAllowedToAccessPrivate = usePermission(privatePermissions);
24
+
16
25
  const filters = getFilters(dynamicValues);
17
26
 
18
27
  const handleClick = (value: string) => {
@@ -43,6 +52,7 @@ const ContentFilters = (props: IProps): JSX.Element => {
43
52
  onClick={handleClick}
44
53
  addNew={addNew}
45
54
  isAllowedToCreate={isAllowedToCreate}
55
+ isAllowedToAccessPrivate={isAllowedToAccessPrivate}
46
56
  />
47
57
  )}
48
58
  </React.Fragment>
@@ -20,6 +20,7 @@ import { structuredDataActions } from "@ax/containers/StructuredData";
20
20
  import { appActions } from "@ax/containers/App";
21
21
  import { CheckField, FloatingMenu, Icon, Flag, LanguageMenu, Tooltip, CategoryCell } from "@ax/components";
22
22
  import { useAdaptiveText, usePermission } from "@ax/hooks";
23
+ import { getPermission } from "./utils";
23
24
 
24
25
  import * as S from "./style";
25
26
 
@@ -51,23 +52,13 @@ const StructuredDataItem = (props: IStructuredDataItemProps): JSX.Element => {
51
52
  hoverCheck,
52
53
  } = props;
53
54
 
54
- const isAllowedToDuplicatePagesGlobal = usePermission("global.globalData.duplicateGlobalData");
55
- const isAllowedToDuplicatePagesSite = usePermission("content.duplicatePages");
56
- const isAllowedToPublishPagesGlobal = usePermission("global.globalData.publishUnpublishAllGlobalData");
57
- const isAllowedToPublishPagesSite = usePermission("content.publishUnpublishPages");
58
- const isAllowedToCreatePagesGlobal = usePermission("global.globalData.createAllGlobalData");
59
- const isAllowedToCreatePagesSite = usePermission("content.createPages");
60
- const isAllowedToDeletePageGlobal = usePermission("global.globalData.deleteAllGlobalData");
61
- const isAllowedToDeletePageSite = usePermission("content.deletePages");
62
-
63
- const isAllowedToDuplicatePages =
64
- (!currentSiteInfo && isAllowedToDuplicatePagesGlobal) || (currentSiteInfo && isAllowedToDuplicatePagesSite);
65
- const isAllowedToPublishPages =
66
- (!currentSiteInfo && isAllowedToPublishPagesGlobal) || (currentSiteInfo && isAllowedToPublishPagesSite);
67
- const isAllowedToCreatePages =
68
- (!currentSiteInfo && isAllowedToCreatePagesGlobal) || (currentSiteInfo && isAllowedToCreatePagesSite);
69
- const isAllowedToDeletePage =
70
- (!currentSiteInfo && isAllowedToDeletePageGlobal) || (currentSiteInfo && isAllowedToDeletePageSite);
55
+ const isPrivateData = currentStructuredData?.private || false;
56
+ const isGlobal = !currentSiteInfo;
57
+
58
+ const isAllowedToDuplicatePages = usePermission(getPermission("duplicate", isGlobal, isPrivateData));
59
+ const isAllowedToPublishPages = usePermission(getPermission("publish", isGlobal, isPrivateData));
60
+ const isAllowedToCreatePages = usePermission(getPermission("create", isGlobal, isPrivateData));
61
+ const isAllowedToDeletePage = usePermission(getPermission("delete", isGlobal, isPrivateData));
71
62
 
72
63
  const nameCellRef = useRef<HTMLDivElement>(null);
73
64
  const theme: any = useTheme();
@@ -0,0 +1,54 @@
1
+ const getPermission = (type: "duplicate" | "create" | "delete" | "publish", isGlobal: boolean, isPrivate: boolean) => {
2
+ const permissions: Record<
3
+ "duplicate" | "create" | "delete" | "publish",
4
+ Record<"global" | "site", Record<"default" | "private", string>>
5
+ > = {
6
+ duplicate: {
7
+ global: {
8
+ default: "global.globalData.duplicateGlobalData",
9
+ private: "global.content.duplicatePrivateContentTypes",
10
+ },
11
+ site: {
12
+ default: "content.duplicatePages",
13
+ private: "content.duplicatePrivateContentTypes",
14
+ },
15
+ },
16
+ create: {
17
+ global: {
18
+ default: "global.globalData.createAllGlobalData",
19
+ private: "global.content.createPrivateContentTypes",
20
+ },
21
+ site: {
22
+ default: "content.createPages",
23
+ private: "content.createPrivateContentTypes",
24
+ },
25
+ },
26
+ delete: {
27
+ global: {
28
+ default: "global.globalData.deleteAllGlobalData",
29
+ private: "global.content.deletePrivateContentTypes",
30
+ },
31
+ site: {
32
+ default: "content.deletePages",
33
+ private: "content.deletePrivateContentTypes",
34
+ },
35
+ },
36
+ publish: {
37
+ global: {
38
+ default: "global.globalData.publishUnpublishAllGlobalData",
39
+ private: "global.content.publishUnpublishPrivateContentTypes",
40
+ },
41
+ site: {
42
+ default: "content.publishUnpublishPages",
43
+ private: "content.publishUnpublishPrivateContentTypes",
44
+ },
45
+ },
46
+ };
47
+
48
+ const privateStr = isPrivate ? "private" : "default";
49
+ const global = isGlobal ? "global" : "site";
50
+
51
+ return permissions[type][global][privateStr];
52
+ };
53
+
54
+ export { getPermission };
@@ -147,7 +147,16 @@ const StructuredDataList = (props: IProps): JSX.Element => {
147
147
  subErrors?: { id: number; error: string }[];
148
148
  } | null>(null);
149
149
 
150
- const allowedToCreatePages = usePermission("global.globalData.createAllGlobalData");
150
+ const isPrivateData = currentStructuredData?.private || false;
151
+ const createPermission = isPrivateData
152
+ ? "global.content.createPrivateContentTypes"
153
+ : "global.globalData.createAllGlobalData";
154
+ const exportPermission = isPrivateData
155
+ ? "global.content.exportPrivateContentTypes"
156
+ : "global.content.exportContentTypes";
157
+
158
+ const allowedToCreatePages = usePermission(createPermission);
159
+ const allowedToExport = usePermission(exportPermission);
151
160
 
152
161
  const scope = currentSiteID ? "site" : "global";
153
162
 
@@ -155,7 +164,6 @@ const StructuredDataList = (props: IProps): JSX.Element => {
155
164
  const isDataTranslatable = currentStructuredData && currentStructuredData.translate;
156
165
  const isAllPages = filter === "all-pages";
157
166
  const isStructuredDataFromPage = !!currentStructuredData?.fromPage || isAllPages;
158
- const isPrivateData = currentStructuredData?.private || false;
159
167
  const isDataExportable = currentStructuredData?.exportable || false;
160
168
  const dataIds = isStructuredDataFromPage
161
169
  ? currentSitePages.map((page: IPage) => page.id)
@@ -455,14 +463,15 @@ const StructuredDataList = (props: IProps): JSX.Element => {
455
463
  setFiltersSelection(filterPointer, filtersSelected);
456
464
  };
457
465
 
458
- const exportContent = isDataExportable
459
- ? async (formats: (number | string)[]) => {
460
- if (currentStructuredData && formats.length) {
461
- const ids = selectedItems.all.length ? selectedItems.all : undefined;
462
- await exportDataContent(currentStructuredData?.id, { format: formats as string[], ids });
466
+ const exportContent =
467
+ isDataExportable && allowedToExport
468
+ ? async (formats: (number | string)[]) => {
469
+ if (currentStructuredData && formats.length) {
470
+ const ids = selectedItems.all.length ? selectedItems.all : undefined;
471
+ await exportDataContent(currentStructuredData?.id, { format: formats as string[], ids });
472
+ }
463
473
  }
464
- }
465
- : undefined;
474
+ : undefined;
466
475
 
467
476
  const currentDataColumnsState = currentStructuredData ? columnsState[structuredDataType] || [] : columnsState["all"];
468
477