@griddo/ax 1.58.6 → 1.59.2

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 (120) hide show
  1. package/package.json +2 -2
  2. package/src/GlobalStore.tsx +3 -1
  3. package/src/api/checkgroups.tsx +1 -1
  4. package/src/api/domains.tsx +26 -0
  5. package/src/api/index.tsx +3 -1
  6. package/src/api/sites.tsx +25 -8
  7. package/src/api/utils.tsx +1 -1
  8. package/src/components/Browser/index.tsx +8 -3
  9. package/src/components/ElementsTooltip/index.tsx +23 -8
  10. package/src/components/ElementsTooltip/style.tsx +4 -5
  11. package/src/components/ErrorCenter/index.tsx +11 -1
  12. package/src/components/ErrorCenter/style.tsx +4 -3
  13. package/src/components/Fields/CheckGroup/index.tsx +5 -4
  14. package/src/components/Fields/ComponentArray/MixableComponentArray/AddItemButton/index.tsx +1 -0
  15. package/src/components/Fields/ReferenceField/Context/index.tsx +10 -6
  16. package/src/components/Fields/ReferenceField/ItemList/Item/index.tsx +2 -2
  17. package/src/components/Fields/ReferenceField/ItemList/index.tsx +15 -14
  18. package/src/components/FieldsBehavior/index.tsx +2 -1
  19. package/src/components/FloatingMenu/index.tsx +3 -1
  20. package/src/components/FloatingMenu/style.tsx +7 -5
  21. package/src/components/Gallery/GalleryPanel/DetailPanel/index.tsx +17 -19
  22. package/src/components/Gallery/GalleryPanel/DetailPanel/style.tsx +32 -19
  23. package/src/components/Gallery/style.tsx +1 -1
  24. package/src/components/Icon/components/Category.js +5 -6
  25. package/src/components/Icon/components/Refresh.js +12 -0
  26. package/src/components/Icon/svgs/Category.svg +1 -1
  27. package/src/components/Icon/svgs/Refresh.svg +3 -0
  28. package/src/components/Lists/style.tsx +10 -9
  29. package/src/components/MainWrapper/AppBar/index.tsx +16 -5
  30. package/src/components/MainWrapper/AppBar/style.tsx +2 -1
  31. package/src/components/SideModal/index.tsx +10 -4
  32. package/src/components/TableCounter/style.tsx +1 -4
  33. package/src/components/TableFilters/CategoryFilter/index.tsx +92 -0
  34. package/src/{modules/Content/HeaderMenus/Translations → components/TableFilters/CategoryFilter}/style.tsx +4 -3
  35. package/src/components/TableFilters/CustomizeFilters/index.tsx +52 -0
  36. package/src/components/TableFilters/CustomizeFilters/style.tsx +28 -0
  37. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Live → components/TableFilters/LiveFilter}/index.tsx +18 -6
  38. package/src/{modules/Content/HeaderMenus/Live → components/TableFilters/LiveFilter}/style.tsx +0 -0
  39. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Name → components/TableFilters/NameFilter}/index.tsx +18 -9
  40. package/src/{modules/Content/HeaderMenus/Name → components/TableFilters/NameFilter}/style.tsx +0 -0
  41. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Site → components/TableFilters/SiteFilter}/index.tsx +3 -3
  42. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Site → components/TableFilters/SiteFilter}/style.tsx +1 -1
  43. package/src/{modules/Content/HeaderMenus/Status → components/TableFilters/StatusFilter}/index.tsx +7 -4
  44. package/src/{modules/Content/HeaderMenus/Status → components/TableFilters/StatusFilter}/style.tsx +0 -0
  45. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Translations → components/TableFilters/TranslationsFilter}/index.tsx +4 -4
  46. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Translations → components/TableFilters/TranslationsFilter}/style.tsx +0 -0
  47. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Types → components/TableFilters/TypeFilter}/index.tsx +13 -9
  48. package/src/{modules/StructuredData/StructuredDataList/HeaderMenus/Types → components/TableFilters/TypeFilter}/style.tsx +1 -1
  49. package/src/components/TableFilters/index.tsx +19 -0
  50. package/src/components/Tag/index.tsx +1 -1
  51. package/src/components/Tag/style.tsx +10 -11
  52. package/src/components/index.tsx +19 -0
  53. package/src/containers/Domains/actions.tsx +51 -0
  54. package/src/containers/Domains/constants.tsx +5 -0
  55. package/src/containers/Domains/index.tsx +4 -0
  56. package/src/containers/Domains/interfaces.tsx +9 -0
  57. package/src/containers/Domains/reducer.tsx +22 -0
  58. package/src/containers/Gallery/actions.tsx +0 -1
  59. package/src/containers/PageEditor/actions.tsx +7 -0
  60. package/src/containers/PageEditor/utils.tsx +1 -1
  61. package/src/containers/Settings/Languages/constants.tsx +3 -3
  62. package/src/containers/Settings/Languages/index.tsx +2 -5
  63. package/src/containers/Sites/actions.tsx +3 -2
  64. package/src/containers/StructuredData/actions.tsx +62 -3
  65. package/src/containers/StructuredData/constants.tsx +4 -0
  66. package/src/containers/StructuredData/interfaces.tsx +13 -1
  67. package/src/containers/StructuredData/reducer.tsx +9 -1
  68. package/src/forms/editor.tsx +4 -0
  69. package/src/forms/elements.tsx +2 -5
  70. package/src/forms/index.tsx +2 -1
  71. package/src/forms/validators.tsx +12 -5
  72. package/src/helpers/arrays.tsx +12 -1
  73. package/src/helpers/index.tsx +4 -1
  74. package/src/helpers/strings.tsx +7 -0
  75. package/src/hooks/content.tsx +41 -0
  76. package/src/hooks/index.tsx +3 -1
  77. package/src/modules/Categories/CategoriesList/CategoryNav/NavItem/style.tsx +9 -9
  78. package/src/modules/Content/BulkHeader/TableHeader/index.tsx +95 -24
  79. package/src/modules/Content/BulkHeader/TableHeader/style.tsx +6 -19
  80. package/src/modules/Content/BulkHeader/index.tsx +16 -0
  81. package/src/modules/Content/ContentFilters/index.tsx +4 -4
  82. package/src/modules/Content/OptionTable/style.tsx +1 -1
  83. package/src/modules/Content/PageItem/atoms.tsx +28 -0
  84. package/src/modules/Content/PageItem/index.tsx +67 -24
  85. package/src/modules/Content/PageItem/style.tsx +14 -7
  86. package/src/modules/Content/hooks.tsx +27 -17
  87. package/src/modules/Content/index.tsx +53 -6
  88. package/src/modules/GlobalEditor/index.tsx +5 -11
  89. package/src/modules/GlobalSettings/Robots/Item/RobotsPanel/index.tsx +61 -0
  90. package/src/modules/GlobalSettings/Robots/Item/RobotsPanel/style.tsx +30 -0
  91. package/src/modules/GlobalSettings/Robots/Item/index.tsx +33 -0
  92. package/src/modules/GlobalSettings/Robots/Item/style.tsx +28 -0
  93. package/src/modules/GlobalSettings/Robots/index.tsx +120 -0
  94. package/src/modules/GlobalSettings/Robots/style.tsx +32 -0
  95. package/src/modules/GlobalSettings/index.tsx +26 -0
  96. package/src/modules/PageEditor/index.tsx +2 -5
  97. package/src/modules/Settings/Globals/style.tsx +1 -1
  98. package/src/modules/StructuredData/Form/ConnectedField/index.tsx +10 -2
  99. package/src/modules/StructuredData/Form/index.tsx +48 -9
  100. package/src/modules/StructuredData/Form/style.tsx +3 -6
  101. package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/index.tsx +84 -35
  102. package/src/modules/StructuredData/StructuredDataList/BulkHeader/TableHeader/style.tsx +6 -25
  103. package/src/modules/StructuredData/StructuredDataList/BulkHeader/index.tsx +10 -1
  104. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/atoms.tsx +24 -3
  105. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +53 -22
  106. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/style.tsx +16 -9
  107. package/src/modules/StructuredData/StructuredDataList/OptionTable/style.tsx +1 -1
  108. package/src/modules/StructuredData/StructuredDataList/hooks.tsx +9 -2
  109. package/src/modules/StructuredData/StructuredDataList/index.tsx +45 -5
  110. package/src/routes/multisite.tsx +8 -0
  111. package/src/types/index.tsx +28 -11
  112. package/src/modules/Content/HeaderMenus/Live/index.tsx +0 -93
  113. package/src/modules/Content/HeaderMenus/Name/index.tsx +0 -52
  114. package/src/modules/Content/HeaderMenus/Translations/index.tsx +0 -62
  115. package/src/modules/Content/HeaderMenus/Types/index.tsx +0 -73
  116. package/src/modules/Content/HeaderMenus/Types/style.tsx +0 -34
  117. package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Live/style.tsx +0 -37
  118. package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Name/style.tsx +0 -29
  119. package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Status/index.tsx +0 -47
  120. package/src/modules/StructuredData/StructuredDataList/HeaderMenus/Status/style.tsx +0 -30
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "1.58.6",
4
+ "version": "1.59.2",
5
5
  "authors": [
6
6
  "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
7
  "Carlos Torres <carlos.torres@secuoyas.com>",
@@ -241,5 +241,5 @@
241
241
  "publishConfig": {
242
242
  "access": "public"
243
243
  },
244
- "gitHead": "719daeba0b60ffb2be32ddff8f6e046e5564dcd4"
244
+ "gitHead": "9142113380c456c82deef599e5c5acff06bbefde"
245
245
  }
@@ -2,7 +2,6 @@ import { createStore, Reducer, combineReducers, applyMiddleware, Action, StoreEn
2
2
  import { persistReducer, persistStore, PersistConfig, Persistor } from "redux-persist";
3
3
  import storage from "redux-persist/lib/storage"; // defaults to localStorage for web
4
4
  import { connectRouter, routerMiddleware } from "connected-react-router";
5
- import { History } from "history";
6
5
  import { composeWithDevTools } from "redux-devtools-extension";
7
6
  import thunk from "redux-thunk";
8
7
 
@@ -17,6 +16,7 @@ import { dataPacksReducer, dataPacksInitialState } from "./containers/Settings/D
17
16
  import { socialReducer, socialInitialState } from "./containers/Settings/Social/reducer";
18
17
  import { usersReducer, usersInitialState } from "./containers/Users/reducer";
19
18
  import { galleryReducer, galleryInitialState } from "./containers/Gallery/reducer";
19
+ import { domainsReducer, domainsInitialState } from "./containers/Domains/reducer";
20
20
 
21
21
  import { IRootState } from "@ax/types";
22
22
 
@@ -46,6 +46,7 @@ export class GlobalStore {
46
46
  social: socialReducer as Reducer<any, Action<any>>,
47
47
  users: usersReducer as Reducer<any, Action<any>>,
48
48
  gallery: galleryReducer as Reducer<any, Action<any>>,
49
+ domains: domainsReducer as Reducer<any, Action<any>>,
49
50
  });
50
51
 
51
52
  const rootReducer = (state: IRootState | undefined, action: any) => {
@@ -63,6 +64,7 @@ export class GlobalStore {
63
64
  social: socialInitialState,
64
65
  users: usersInitialState,
65
66
  gallery: galleryInitialState,
67
+ domains: domainsInitialState,
66
68
  };
67
69
  }
68
70
 
@@ -15,7 +15,7 @@ const SERVICES: { [key: string]: IServiceConfig } = {
15
15
  },
16
16
  };
17
17
 
18
- const getCheckGroupItems = async (siteId: number | null, source: string): Promise<AxiosResponse<any>> => {
18
+ const getCheckGroupItems = async (siteId: number | string | null, source: string): Promise<AxiosResponse<any>> => {
19
19
  const {
20
20
  host,
21
21
  endpoint: [prefix, suffix],
@@ -0,0 +1,26 @@
1
+ import { IDomainRobot } from "@ax/types";
2
+ import { template } from "./config";
3
+ import { IServiceConfig, sendRequest } from "./utils";
4
+
5
+ const SERVICES: { [key: string]: IServiceConfig } = {
6
+ GET_ROBOTS: {
7
+ ...template,
8
+ endpoint: "/domains/robots",
9
+ method: "GET",
10
+ },
11
+ UPDATE_ROBOTS: {
12
+ ...template,
13
+ endpoint: "/domains/robots/bulk",
14
+ method: "PUT",
15
+ },
16
+ };
17
+
18
+ const getDomainsRobots = async () => {
19
+ return sendRequest(SERVICES.GET_ROBOTS);
20
+ };
21
+
22
+ const updateDomainsRobots = async (robots: IDomainRobot[]) => {
23
+ return sendRequest(SERVICES.UPDATE_ROBOTS, { robots });
24
+ };
25
+
26
+ export default { getDomainsRobots, updateDomainsRobots };
package/src/api/index.tsx CHANGED
@@ -13,6 +13,7 @@ import dataPack from "./dataPack";
13
13
  import social from "./social";
14
14
  import files from "./files";
15
15
  import users from "./users";
16
+ import domains from "./domains";
16
17
 
17
18
  export {
18
19
  sites,
@@ -29,5 +30,6 @@ export {
29
30
  dataPack,
30
31
  social,
31
32
  files,
32
- users
33
+ users,
34
+ domains,
33
35
  };
package/src/api/sites.tsx CHANGED
@@ -123,7 +123,7 @@ const getOrderedSitePages = async (siteID: number | string, query: string) => {
123
123
  return sendRequest(SERVICES.GET_ORDERED_SITE_PAGES);
124
124
  };
125
125
 
126
- const getStructuredSitePages = async (params: IGetSitePagesParams, structuredData: string) => {
126
+ const getStructuredSitePages = async (params: IGetSitePagesParams, structuredData: string, filterQuery?: string) => {
127
127
  const {
128
128
  host,
129
129
  endpoint: [prefix, suffix],
@@ -131,7 +131,10 @@ const getStructuredSitePages = async (params: IGetSitePagesParams, structuredDat
131
131
 
132
132
  const { siteID, deleted, page, itemsPerPage, query } = params;
133
133
 
134
- SERVICES.GET_SITE_STRUCTURED_PAGES.dynamicUrl = `${host}${prefix}${siteID}${suffix}${structuredData}?deleted=${deleted}&page=${page}&itemsPerPage=${itemsPerPage}`;
134
+ const filters = filterQuery ? `${filterQuery}&` : "?";
135
+
136
+ SERVICES.GET_SITE_STRUCTURED_PAGES.dynamicUrl = `${host}${prefix}${siteID}${suffix}${structuredData}${filters}deleted=${deleted}&page=${page}&itemsPerPage=${itemsPerPage}`;
137
+
135
138
  if (query && query.trim() !== "") {
136
139
  SERVICES.GET_SITE_STRUCTURED_PAGES.dynamicUrl = SERVICES.GET_SITE_STRUCTURED_PAGES.dynamicUrl + `&query=${query}`;
137
140
  }
@@ -145,14 +148,17 @@ const getSitePages = async (params: IGetSitePagesParams) => {
145
148
  endpoint: [prefix, suffix],
146
149
  } = SERVICES.GET_SITE_PAGES;
147
150
 
148
- const { siteID, deleted, page, itemsPerPage, query } = params;
151
+ const { siteID, deleted, page, itemsPerPage, query, filterStructuredData, lang } = params;
149
152
 
150
153
  SERVICES.GET_SITE_PAGES.dynamicUrl = `${host}${prefix}${siteID}${suffix}?deleted=${deleted}&page=${page}&itemsPerPage=${itemsPerPage}`;
151
- if (query && query.trim() !== "") {
152
- SERVICES.GET_SITE_PAGES.dynamicUrl = SERVICES.GET_SITE_PAGES.dynamicUrl + `&query=${query}`;
154
+ if (query && query.trim() !== "") SERVICES.GET_SITE_PAGES.dynamicUrl = SERVICES.GET_SITE_PAGES.dynamicUrl + `&query=${query}`;
155
+ if (filterStructuredData) SERVICES.GET_SITE_PAGES.dynamicUrl = SERVICES.GET_SITE_PAGES.dynamicUrl + `&filterStructuredData=${filterStructuredData}`;
156
+
157
+ const dataHeader = {
158
+ ...(lang && { lang })
153
159
  }
154
160
 
155
- return sendRequest(SERVICES.GET_SITE_PAGES);
161
+ return sendRequest(SERVICES.GET_SITE_PAGES, null, dataHeader);
156
162
  };
157
163
 
158
164
  const getGlobalPages = async (params: IGetGlobalPagesParams, filterQuery?: string): Promise<AxiosResponse> => {
@@ -245,8 +251,19 @@ const getSitePagesLight = async (params: IGetSitePagesParams): Promise<AxiosResp
245
251
  return sendRequest(SERVICES.GET_SITE_PAGES_LIGHT, null, dataHeader);
246
252
  };
247
253
 
248
- const getSiteImages = async (site: number | string, page: number, itemsPerPage: number | null, thumbWidth?: number, thumbHeight?: number, query?: string, search?: string): Promise<AxiosResponse> => {
249
- const { host, endpoint: [prefix, suffix] } = SERVICES.GET_SITE_IMAGES;
254
+ const getSiteImages = async (
255
+ site: number | string,
256
+ page: number,
257
+ itemsPerPage: number | null,
258
+ thumbWidth?: number,
259
+ thumbHeight?: number,
260
+ query?: string,
261
+ search?: string
262
+ ): Promise<AxiosResponse> => {
263
+ const {
264
+ host,
265
+ endpoint: [prefix, suffix],
266
+ } = SERVICES.GET_SITE_IMAGES;
250
267
  const items = itemsPerPage ? `&itemsPerPage=${itemsPerPage}` : "";
251
268
  const thumb = thumbWidth && thumbHeight ? `&thumbWidth=${thumbWidth}&thumbHeight=${thumbHeight}` : "";
252
269
  SERVICES.GET_SITE_IMAGES.dynamicUrl = `${host}${prefix}${site}${suffix}?page=${page}${items}${thumb}${query}`;
package/src/api/utils.tsx CHANGED
@@ -5,7 +5,7 @@ export interface IServiceConfig {
5
5
  host: string | undefined;
6
6
  endpoint: string | string[];
7
7
  method: Method;
8
- headers: { "Content-type": string; accept: string; site?: number | null };
8
+ headers: { "Content-type": string; accept: string; site?: number | null; lang?: number };
9
9
  hasToken: boolean;
10
10
  dynamicUrl?: string;
11
11
  }
@@ -4,6 +4,8 @@ import * as components from "components";
4
4
  import { providers, translations, cloudinaryDefaults } from "components";
5
5
  import { Preview } from "@griddo/core";
6
6
 
7
+ import { findByEditorID } from "@ax/forms";
8
+
7
9
  import * as S from "./style";
8
10
 
9
11
  const Browser = (props: IBrowserProps): JSX.Element => {
@@ -19,11 +21,12 @@ const Browser = (props: IBrowserProps): JSX.Element => {
19
21
  }, []);
20
22
 
21
23
  const selectEditorID = (
22
- selectedComponent: { editorID: number; component: any },
24
+ selectedComponent: { editorID: number; component: any; type: string, parentEditorID: number },
23
25
  parentComponent: string | undefined | null,
24
26
  e: React.SyntheticEvent
25
27
  ) => {
26
- e.stopPropagation();
28
+ const { element } = findByEditorID(content, selectedComponent.parentEditorID);
29
+ element && e.stopPropagation();
27
30
 
28
31
  const { setSelectedContent } = props;
29
32
 
@@ -31,7 +34,9 @@ const Browser = (props: IBrowserProps): JSX.Element => {
31
34
 
32
35
  const { editorID } = selectedComponent;
33
36
 
34
- if (!disabled) {
37
+ const isNavigationModule = ["header", "footer"].includes(selectedComponent.type);
38
+
39
+ if (!disabled || isNavigationModule) {
35
40
  setSelectedContent(editorID, parent);
36
41
  }
37
42
  };
@@ -1,9 +1,10 @@
1
1
  import React from "react";
2
+ import { trimText } from "@ax/helpers";
2
3
 
3
4
  import * as S from "./style";
4
5
 
5
6
  const ExpandedTooltip = (props: IProps): JSX.Element => {
6
- const { elements, defaultElements = 1 } = props;
7
+ const { elements, maxChar, defaultElements = 1, colors, rounded = false } = props;
7
8
 
8
9
  if (!elements) return <></>;
9
10
 
@@ -12,16 +13,27 @@ const ExpandedTooltip = (props: IProps): JSX.Element => {
12
13
 
13
14
  return (
14
15
  <S.Wrapper>
15
- {visibleElements.map((element, idx) => (
16
- <S.Element key={idx}>{element}</S.Element>
17
- ))}
16
+ {visibleElements.map((fullElement, idx) => {
17
+ const element = defaultElements === 1 && maxChar ? trimText(fullElement, maxChar) : fullElement;
18
+ const color = colors && colors[element] ? colors[element] : undefined;
19
+ return (
20
+ <S.Element key={idx} color={color} rounded={rounded}>
21
+ {element}
22
+ </S.Element>
23
+ );
24
+ })}
18
25
  {remainingElements > 0 && (
19
- <S.Element>
26
+ <S.Element rounded={rounded}>
20
27
  +{remainingElements}
21
28
  <S.Tooltip>
22
- {elements.map((element, idx) => (
23
- <S.Element key={idx}>{element}</S.Element>
24
- ))}
29
+ {elements.map((element, idx) => {
30
+ const color = colors && colors[element] ? colors[element] : undefined;
31
+ return (
32
+ <S.Element key={idx} color={color} rounded={rounded}>
33
+ {element}
34
+ </S.Element>
35
+ );
36
+ })}
25
37
  </S.Tooltip>
26
38
  </S.Element>
27
39
  )}
@@ -32,6 +44,9 @@ const ExpandedTooltip = (props: IProps): JSX.Element => {
32
44
  interface IProps {
33
45
  elements?: string[];
34
46
  defaultElements?: number;
47
+ maxChar?: number;
48
+ colors?: any;
49
+ rounded?: boolean;
35
50
  }
36
51
 
37
52
  export default ExpandedTooltip;
@@ -9,25 +9,24 @@ const Tooltip = styled.div`
9
9
  position: absolute;
10
10
  z-index: 1;
11
11
  display: none;
12
- flex-wrap: wrap;
12
+ flex-flow: row wrap;
13
13
  padding: ${(p) => p.theme.spacing.s};
14
14
  top: -50%;
15
15
  transform: translateX(-50%);
16
16
  box-shadow: ${(p) => p.theme.shadow.shadowL};
17
17
  background-color: ${(p) => p.theme.colors.uiBarBackground};
18
18
  border-radius: ${(p) => p.theme.radii.s};
19
- flex-flow: row;
20
19
  max-width: 350px;
21
20
  `;
22
21
 
23
- const Element = styled.div`
22
+ const Element = styled.div<{ color?: string; rounded: boolean }>`
24
23
  position: relative;
25
24
  ${(p) => p.theme.textStyle.uiXS};
26
25
  ${(p) => p.theme.colors.textMediumEmphasis};
27
26
  padding: ${(p) => p.theme.spacing.xxs} ${(p) => p.theme.spacing.xs};
28
27
  margin: calc(${(p) => p.theme.spacing.xxs} / 2);
29
- background-color: ${(p) => p.theme.colors.uiBackground01};
30
- border-radius: ${(p) => p.theme.radii.xs};
28
+ background-color: ${(p) => (p.color ? p.color : p.theme.colors.uiBackground01)};
29
+ border-radius: ${(p) => (p.rounded ? "34px" : p.theme.radii.xs)};
31
30
  white-space: nowrap;
32
31
 
33
32
  &:hover > ${Tooltip} {
@@ -7,8 +7,18 @@ import * as S from "./style";
7
7
  const ErrorCenter = (props: IProps): JSX.Element => {
8
8
  const { errors, actions } = props;
9
9
 
10
+ const goToElement = (key: string) => {
11
+ const element = document.getElementById(key);
12
+ if (element) {
13
+ element.scrollIntoView();
14
+ }
15
+ };
16
+
10
17
  const getErrorItem = (item: IErrorItem): JSX.Element => {
11
- const handleClick = () => actions?.goToError(item.editorID, item.tab, item.template);
18
+ const handleClick = () => {
19
+ actions?.goToError(item.editorID, item.tab, item.template);
20
+ goToElement(item.key);
21
+ };
12
22
 
13
23
  return (
14
24
  <S.Wrapper key={`${item.editorID}${item.key}`} onClick={handleClick}>
@@ -1,21 +1,22 @@
1
1
  import styled from "styled-components";
2
2
 
3
- const ActionMenu = styled.ul`
3
+ const ActionMenu = styled.div`
4
4
  padding: 0 ${(p) => p.theme.spacing.s};
5
5
  width: ${(p) => `calc(4 * ${p.theme.spacing.l})`};
6
6
  max-height: 380px;
7
7
  overflow: auto;
8
8
  `;
9
9
 
10
- const MenuHeader = styled.li`
10
+ const MenuHeader = styled.div`
11
11
  ${(p) => p.theme.textStyle.headingXXS};
12
12
  color: ${(p) => p.theme.color.textLowEmphasis};
13
13
  padding-top: ${(p) => p.theme.spacing.xs};
14
14
  `;
15
15
 
16
- const Wrapper = styled.li`
16
+ const Wrapper = styled.div`
17
17
  padding: ${(p) => p.theme.spacing.s} 0;
18
18
  border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
19
+ cursor: pointer;
19
20
  `;
20
21
 
21
22
  const Header = styled.div`
@@ -19,11 +19,12 @@ const CheckGroup = (props: ICheckGroupProps): JSX.Element => {
19
19
  }
20
20
 
21
21
  if (selectAllOption) {
22
- const isAllSelected = newValue.value === selectAllOption || (options && valueArray.length === options.length - 1);
22
+ const valueArrayNoAll = valueArray.filter((item: string | number) => item !== selectAllOption);
23
23
 
24
- valueArray = isAllSelected
25
- ? [selectAllOption]
26
- : valueArray.filter((item: string | number) => item !== selectAllOption);
24
+ const isAllSelected =
25
+ newValue.value === selectAllOption || (options && valueArrayNoAll.length === options.length - 1);
26
+
27
+ valueArray = isAllSelected ? [selectAllOption] : valueArrayNoAll;
27
28
  }
28
29
 
29
30
  if (!multipleSelection) {
@@ -22,6 +22,7 @@ const AddItemButton = (props: IProps) => {
22
22
  toggleModal={toggleModal}
23
23
  isOpen={isOpen}
24
24
  handleClick={handleClick}
25
+ showSearch
25
26
  />
26
27
  </>
27
28
  );
@@ -1,5 +1,7 @@
1
1
  import React, { createContext, useState, useCallback, useContext, ReactElement } from "react";
2
2
  import { moveElement } from "@ax/forms";
3
+ import { moveArrayElement } from "@ax/helpers";
4
+ import { IStructuredDataContent } from "@ax/types";
3
5
 
4
6
  const initState = {
5
7
  mode: "auto",
@@ -8,7 +10,7 @@ const initState = {
8
10
  quantity: 0,
9
11
  items: [],
10
12
  selectedItems: [],
11
- fixed: [],
13
+ fixed: null,
12
14
  search: "",
13
15
  showSelected: false,
14
16
  source: [],
@@ -48,14 +50,16 @@ const useReferenceProvider = (modes?: string[]) => {
48
50
  [setState, state]
49
51
  );
50
52
 
51
- const setReorderElements = (elementID: number, isPush: boolean) => {
52
- const { selectedItems } = state;
53
- const newItems = moveElement(elementID, selectedItems, isPush, "id");
54
- const fixed = newItems.map((item: any) => item.id);
53
+ const setReorderElements = (item: IStructuredDataContent, isPush: boolean) => {
54
+ const { selectedItems, fixed } = state;
55
+ const newItems = moveElement(item.id, selectedItems, isPush, "id");
56
+ const originalItemId = item.relatedPage?.originalStructuredDataId;
57
+ const itemId = state.fixed.includes(originalItemId) ? originalItemId : item.id;
58
+ const newFixed = moveArrayElement(itemId, fixed, isPush);
55
59
  const newState: IReferenceState = {
56
60
  ...state,
57
61
  selectedItems: newItems,
58
- fixed,
62
+ fixed: newFixed,
59
63
  };
60
64
  setState(newState);
61
65
  };
@@ -29,7 +29,7 @@ const Item = (props: IProps) => {
29
29
  const moveModule = (e: any, isPush: boolean) => {
30
30
  e.preventDefault();
31
31
  e.stopPropagation();
32
- handleReorder(item.id, isPush);
32
+ handleReorder(item, isPush);
33
33
  };
34
34
 
35
35
  const handleUpClick = (e: any) => moveModule(e, false);
@@ -80,7 +80,7 @@ interface IProps {
80
80
  listLength: number;
81
81
  source: IDataSource;
82
82
  handleDelete(item: IStructuredDataContent): void;
83
- handleReorder(elementID: number, isPush: boolean): void;
83
+ handleReorder(item: any, isPush: boolean): void;
84
84
  }
85
85
 
86
86
  export default Item;
@@ -13,6 +13,7 @@ const ItemList = (props: IProps) => {
13
13
  const { items, currentSite, handleListDelete, handleChange } = props;
14
14
 
15
15
  const { state, setState, setReorderElements } = useReference();
16
+ const { fixed, mode, selectedItems, sourceTitles } = state;
16
17
 
17
18
  useEffect(() => {
18
19
  const params = {
@@ -34,19 +35,19 @@ const ItemList = (props: IProps) => {
34
35
  }, [items]);
35
36
 
36
37
  useEffect(() => {
37
- const { mode, fixed } = state;
38
- const newValue = {
39
- mode,
40
- fixed,
41
- };
42
- handleChange(newValue);
38
+ if (fixed) {
39
+ const newValue = { mode, fixed };
40
+ handleChange(newValue);
41
+ }
43
42
  // eslint-disable-next-line react-hooks/exhaustive-deps
44
- }, [state.fixed]);
43
+ }, [fixed]);
45
44
 
46
45
  const handleDelete = (item: IStructuredDataContent) => {
47
- if (state.fixed.includes(item.id)) {
48
- const newSelIds = state.fixed.filter((a: any) => a !== item.id);
49
- const selItems = state.selectedItems.filter((b: any) => b.id !== item.id);
46
+ const originalItemId = item.relatedPage?.originalStructuredDataId;
47
+ const itemId = state.fixed.includes(originalItemId) ? originalItemId : item.id;
48
+ if (fixed.includes(itemId)) {
49
+ const newSelIds = fixed.filter((a: any) => a !== itemId);
50
+ const selItems = selectedItems.filter((b: any) => b.id !== itemId);
50
51
  setState((state: IReferenceState) => ({ ...state, fixed: newSelIds, selectedItems: selItems }));
51
52
  handleListDelete(newSelIds);
52
53
  }
@@ -54,9 +55,9 @@ const ItemList = (props: IProps) => {
54
55
 
55
56
  return (
56
57
  <S.ItemList>
57
- {state.selectedItems &&
58
- state.selectedItems.map((item: IStructuredDataContent, index: number) => {
59
- const source = state.sourceTitles.find((el: IDataSource) => el.id === item.structuredData);
58
+ {selectedItems &&
59
+ selectedItems.map((item: IStructuredDataContent, index: number) => {
60
+ const source = sourceTitles.find((el: IDataSource) => el.id === item.structuredData);
60
61
  return (
61
62
  <Item
62
63
  key={index}
@@ -64,7 +65,7 @@ const ItemList = (props: IProps) => {
64
65
  handleDelete={handleDelete}
65
66
  handleReorder={setReorderElements}
66
67
  index={index}
67
- listLength={state.selectedItems.length}
68
+ listLength={selectedItems.length}
68
69
  source={source}
69
70
  />
70
71
  );
@@ -25,6 +25,7 @@ const FieldsBehavior = (props: any): JSX.Element => {
25
25
  error,
26
26
  deleteError,
27
27
  editorID,
28
+ objKey,
28
29
  } = props;
29
30
 
30
31
  const [showAdvanced, setShowAdvanced] = useState(false);
@@ -73,7 +74,7 @@ const FieldsBehavior = (props: any): JSX.Element => {
73
74
  };
74
75
 
75
76
  return (
76
- <S.Wrapper error={errorField} className={wrapperClass} showTitle={showTitle}>
77
+ <S.Wrapper error={errorField} className={wrapperClass} showTitle={showTitle} id={objKey}>
77
78
  <S.Content error={errorField}>
78
79
  <Field {...props} showAdvanced={showAdvanced} handleValidation={handleValidation} error={errorField} />
79
80
  </S.Content>
@@ -13,6 +13,7 @@ const FloatingMenu = (props: IProps) => {
13
13
  closeOnSelect = true,
14
14
  isCheckGroup,
15
15
  reactiveToHover,
16
+ offset
16
17
  } = props;
17
18
  const wrapper = useRef<any>(null);
18
19
  const button = useRef<any>(null);
@@ -61,7 +62,7 @@ const FloatingMenu = (props: IProps) => {
61
62
  <Button />
62
63
  </S.ButtonWrapper>
63
64
  {isOpen && (
64
- <S.MenuWrapper isInAppBar={isInAppBar} ref={menuOptions} position={position}>
65
+ <S.MenuWrapper isInAppBar={isInAppBar} ref={menuOptions} position={position} offset={offset}>
65
66
  <S.Menu>
66
67
  {children}
67
68
  </S.Menu>
@@ -79,6 +80,7 @@ interface IProps {
79
80
  closeOnSelect?: boolean;
80
81
  isCheckGroup?: boolean;
81
82
  reactiveToHover?: boolean;
83
+ offset?: number;
82
84
  }
83
85
 
84
86
  export default FloatingMenu;
@@ -1,21 +1,21 @@
1
1
  import styled from "styled-components";
2
2
 
3
- export const Wrapper = styled.div``;
3
+ const Wrapper = styled.div``;
4
4
 
5
- export const ButtonWrapper = styled.div`
5
+ const ButtonWrapper = styled.div`
6
6
  display: flex;
7
7
  align-items: center;
8
8
  `;
9
9
 
10
- export const MenuWrapper = styled.div<{ isInAppBar?: boolean, position: string }>`
10
+ const MenuWrapper = styled.div<{ isInAppBar?: boolean; position: string; offset?: number }>`
11
11
  position: absolute;
12
12
  z-index: 3;
13
13
  padding-top: ${(p) => (p.isInAppBar ? p.theme.spacing.s : p.theme.spacing.xs)};
14
14
  margin-right: ${(p) => (p.isInAppBar ? p.theme.spacing.s : "0")};
15
- ${(p) => p.position}: 0;
15
+ ${(p) => p.position}: ${(p) => (p.offset ? `${p.offset}px` : "0")};
16
16
  `;
17
17
 
18
- export const Menu = styled.div`
18
+ const Menu = styled.div`
19
19
  padding: ${(p) => p.theme.spacing.xs} 0;
20
20
  max-width: ${(p) => `calc(${p.theme.spacing.l} * 5)`};
21
21
  min-width: ${(p) => `calc(${p.theme.spacing.m} * 7)`};
@@ -23,3 +23,5 @@ export const Menu = styled.div`
23
23
  box-shadow: ${(p) => p.theme.shadow.shadowL};
24
24
  border-radius: ${(p) => p.theme.spacing.xxs};
25
25
  `;
26
+
27
+ export { Wrapper, ButtonWrapper, MenuWrapper, Menu };
@@ -1,8 +1,8 @@
1
1
  import React, { memo, useEffect, useState } from "react";
2
2
  import { connect } from "react-redux";
3
3
  import { IImage, IRootState, IImageForm } from "@ax/types";
4
- import { Button, CheckField, FieldsBehavior, Toast } from "@ax/components";
5
- import { formatBytes, getFormattedDateWithTimezone } from "@ax/helpers";
4
+ import { Button, CheckField, FieldsBehavior, Toast, IconAction } from "@ax/components";
5
+ import { formatBytes, getFileExtension, getFormattedDateWithTimezone } from "@ax/helpers";
6
6
 
7
7
  import { galleryActions } from "@ax/containers/Gallery";
8
8
  import { IIsSaving } from "@ax/containers/Gallery/reducer";
@@ -100,7 +100,7 @@ const GalleryDetailPanel = (props: IProps) => {
100
100
  }
101
101
  };
102
102
 
103
- const handleOnClickUrl = () => {
103
+ const handleOpenUrl = () => {
104
104
  if (imageSelected) {
105
105
  const win = window.open(imageSelected.url, "_blank");
106
106
  if (win) {
@@ -109,6 +109,8 @@ const GalleryDetailPanel = (props: IProps) => {
109
109
  }
110
110
  };
111
111
 
112
+ const handleCopyUrl = () => imageSelected && navigator.clipboard.writeText(imageSelected.url);
113
+
112
114
  const dimensions =
113
115
  imageSelected && imageSelected.width && imageSelected.height
114
116
  ? `${imageSelected.width}x${imageSelected.height}px`
@@ -132,27 +134,23 @@ const GalleryDetailPanel = (props: IProps) => {
132
134
  const renderImageForm = !imageSelected ? null : (
133
135
  <S.PanelForm>
134
136
  {canSetAsGlobal && <AddToGlobal />}
135
- <S.DateWrapper>Uploaded: {getFormattedDateWithTimezone(imageSelected.published, "d MMM Y")}</S.DateWrapper>
136
- <S.ImageName>{imageSelected.name}</S.ImageName>
137
137
  <S.ImageInfoWrapper>
138
138
  <S.ImageWrapper>
139
- <img src={imageSelected.url} alt={imageForm.alt} />
139
+ <S.Image>
140
+ <img src={imageSelected.url} alt={imageForm.alt} />
141
+ </S.Image>
142
+ <Button type="button" onClick={handleCopyUrl} buttonStyle="line">
143
+ Copy URL
144
+ </Button>
145
+ <IconAction icon="OpenOutside" size="m" onClick={handleOpenUrl} />
140
146
  </S.ImageWrapper>
141
- <S.ImageData>
142
- <S.ImageSize>{formatBytes(imageSelected.size)}</S.ImageSize>
143
- <S.ImageDimensions>{dimensions}</S.ImageDimensions>
144
- </S.ImageData>
147
+ <S.ImageName>{imageSelected.name}</S.ImageName>
148
+ <S.Date><strong>Uploaded:</strong> {getFormattedDateWithTimezone(imageSelected.published, "d MMM Y")}</S.Date>
149
+ <S.Type><strong>Type:</strong> {getFileExtension(imageSelected.name)}</S.Type>
150
+ <S.ImageSize><strong>Size:</strong> {formatBytes(imageSelected.size)}</S.ImageSize>
151
+ <S.ImageDimensions><strong>Resolution:</strong> {dimensions}</S.ImageDimensions>
145
152
  </S.ImageInfoWrapper>
146
153
  <S.FormWrapper>
147
- <FieldsBehavior
148
- title=""
149
- name="url"
150
- value={imageSelected.url}
151
- fieldType="TextField"
152
- readonly={true}
153
- icon="openOutside"
154
- onClickIcon={handleOnClickUrl}
155
- />
156
154
  <FieldsBehavior
157
155
  title="Title"
158
156
  name="title"