@griddo/ax 1.66.3 → 1.66.4

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 (71) hide show
  1. package/package.json +2 -2
  2. package/src/api/pages.tsx +15 -3
  3. package/src/api/redirects.tsx +4 -2
  4. package/src/api/sites.tsx +4 -2
  5. package/src/components/Browser/index.tsx +3 -1
  6. package/src/components/Browser/style.tsx +2 -2
  7. package/src/components/ConfigPanel/Form/ConnectedField/PageConnectedField/Field/index.tsx +0 -1
  8. package/src/components/ErrorCenter/index.tsx +8 -5
  9. package/src/components/ErrorCenter/style.tsx +21 -8
  10. package/src/components/Fields/ColorPicker/index.tsx +1 -0
  11. package/src/components/Fields/LinkField/index.tsx +85 -0
  12. package/src/components/Fields/ReferenceField/ItemList/index.tsx +5 -1
  13. package/src/components/Fields/ReferenceField/index.tsx +18 -14
  14. package/src/components/Fields/UrlField/index.tsx +13 -1
  15. package/src/components/Fields/index.tsx +2 -0
  16. package/src/components/FieldsBehavior/index.tsx +14 -1
  17. package/src/components/Icon/components/Copy.js +14 -0
  18. package/src/components/Icon/svgs/Copy2.svg +3 -0
  19. package/src/components/MainWrapper/AppBar/index.tsx +21 -10
  20. package/src/components/MainWrapper/AppBar/style.tsx +11 -3
  21. package/src/components/MainWrapper/index.tsx +2 -0
  22. package/src/components/Modal/style.tsx +0 -1
  23. package/src/components/SearchField/index.tsx +36 -4
  24. package/src/components/SearchField/style.tsx +23 -10
  25. package/src/components/SideModal/style.tsx +6 -6
  26. package/src/components/TableFilters/StatusFilter/index.tsx +2 -2
  27. package/src/components/index.tsx +2 -0
  28. package/src/containers/App/actions.tsx +3 -7
  29. package/src/containers/PageEditor/actions.tsx +91 -22
  30. package/src/containers/PageEditor/constants.tsx +1 -1
  31. package/src/containers/PageEditor/interfaces.tsx +6 -6
  32. package/src/containers/PageEditor/reducer.tsx +4 -4
  33. package/src/containers/PageEditor/utils.tsx +2 -1
  34. package/src/containers/Sites/actions.tsx +35 -23
  35. package/src/containers/Sites/constants.tsx +1 -0
  36. package/src/containers/Sites/interfaces.tsx +6 -0
  37. package/src/containers/Sites/reducer.tsx +4 -0
  38. package/src/forms/editor.tsx +34 -1
  39. package/src/forms/errors.tsx +1 -0
  40. package/src/forms/index.tsx +15 -1
  41. package/src/forms/validators.tsx +168 -9
  42. package/src/guards/error/index.tsx +1 -1
  43. package/src/helpers/dataPacks.tsx +8 -1
  44. package/src/helpers/index.tsx +2 -1
  45. package/src/modules/Content/PageItem/index.tsx +54 -4
  46. package/src/modules/Content/atoms.tsx +41 -3
  47. package/src/modules/Content/index.tsx +111 -64
  48. package/src/modules/Content/style.tsx +8 -1
  49. package/src/modules/GlobalEditor/Editor/index.tsx +3 -1
  50. package/src/modules/GlobalEditor/PageBrowser/index.tsx +3 -0
  51. package/src/modules/GlobalEditor/index.tsx +8 -6
  52. package/src/modules/Navigation/Menus/List/Table/SidePanel/Form/index.tsx +8 -0
  53. package/src/modules/PageEditor/Editor/index.tsx +6 -2
  54. package/src/modules/PageEditor/PageBrowser/index.tsx +3 -0
  55. package/src/modules/PageEditor/index.tsx +29 -15
  56. package/src/modules/Redirects/index.tsx +40 -10
  57. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/Editor/index.tsx +1 -1
  58. package/src/modules/Settings/ContentTypes/DataPacks/Config/Form/TemplateConfig/TemplateEditor/index.tsx +1 -1
  59. package/src/modules/Settings/ContentTypes/DataPacks/Config/index.tsx +1 -1
  60. package/src/modules/Settings/ContentTypes/DataPacks/index.tsx +1 -1
  61. package/src/modules/Sites/index.tsx +3 -3
  62. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +1 -1
  63. package/src/modules/StructuredData/StructuredDataList/atoms.tsx +1 -1
  64. package/src/modules/Users/Profile/index.tsx +3 -4
  65. package/src/modules/Users/UserCreate/SiteItem/index.tsx +1 -1
  66. package/src/modules/Users/UserCreate/SiteItem/style.tsx +1 -1
  67. package/src/modules/Users/UserForm/style.tsx +3 -3
  68. package/src/modules/Users/UserList/UserItem/index.tsx +3 -1
  69. package/src/modules/Users/UserList/hooks.tsx +1 -1
  70. package/src/modules/Users/UserList/index.tsx +2 -2
  71. package/src/types/index.tsx +16 -3
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@griddo/ax",
3
3
  "description": "Griddo Author Experience",
4
- "version": "1.66.3",
4
+ "version": "1.66.4",
5
5
  "authors": [
6
6
  "Álvaro Sánchez' <alvaro.sanches@secuoyas.com>",
7
7
  "Carlos Torres <carlos.torres@secuoyas.com>",
@@ -221,5 +221,5 @@
221
221
  "publishConfig": {
222
222
  "access": "public"
223
223
  },
224
- "gitHead": "c5cf3e9fcc40893cc5a92140dd3a4c50f42a2cfe"
224
+ "gitHead": "c293929f75ccb107b7ab790583cf3624bb9dc866"
225
225
  }
package/src/api/pages.tsx CHANGED
@@ -75,6 +75,11 @@ const SERVICES: { [key: string]: IServiceConfig } = {
75
75
  endpoint: ["/page/", "/preview/"],
76
76
  method: "GET",
77
77
  },
78
+ PAGE_CHECK: {
79
+ ...template,
80
+ endpoint: "/page/check",
81
+ method: "POST",
82
+ },
78
83
  };
79
84
 
80
85
  const getPageInfo = async (pageID: number) => {
@@ -154,15 +159,17 @@ const getPageBreadcrumb = async (pageID: number) => {
154
159
  return sendRequest(SERVICES.GET_PAGE_BREADCRUMB);
155
160
  };
156
161
 
157
- const duplicatePage = async (pageID: number, data: any) => {
162
+ const duplicatePage = async (pageID: number, data?: any, siteID?: number) => {
158
163
  const {
159
164
  host,
160
165
  endpoint: [prefix, suffix],
161
166
  } = SERVICES.DUPLICATE_PAGE;
162
167
 
163
- SERVICES.DUPLICATE_PAGE.dynamicUrl = `${host}${prefix}${pageID}${suffix}`;
168
+ SERVICES.DUPLICATE_PAGE.dynamicUrl = siteID
169
+ ? `${host}${prefix}${pageID}${suffix}/${siteID}`
170
+ : `${host}${prefix}${pageID}${suffix}`;
164
171
 
165
- return sendRequest(SERVICES.DUPLICATE_PAGE, { ...data });
172
+ return siteID ? sendRequest(SERVICES.DUPLICATE_PAGE) : sendRequest(SERVICES.DUPLICATE_PAGE, { ...data });
166
173
  };
167
174
 
168
175
  const bulkDelete = async (ids: any) => sendRequest(SERVICES.DELETE_BULK, { ids });
@@ -199,6 +206,10 @@ const getPublicPage = async (pageID: number, entity: string) => {
199
206
  return sendRequest(SERVICES.GET_PUPLIC_PAGE);
200
207
  };
201
208
 
209
+ const pageCheck = async (data: any) => {
210
+ return sendRequest(SERVICES.PAGE_CHECK, { ...data });
211
+ };
212
+
202
213
  export default {
203
214
  getPageInfo,
204
215
  updatePage,
@@ -214,4 +225,5 @@ export default {
214
225
  bulkRestore,
215
226
  sendPagePing,
216
227
  getPublicPage,
228
+ pageCheck,
217
229
  };
@@ -40,13 +40,15 @@ const SERVICES: { [key: string]: IServiceConfig } = {
40
40
  };
41
41
 
42
42
  const getRedirects = async (params: any, filters?: string) => {
43
- const { page, itemsPerPage, pagination } = params;
43
+ const { page, itemsPerPage, pagination, query, filterBy } = params;
44
44
 
45
45
  const { host, endpoint } = SERVICES.GET_REDIRECTS;
46
46
 
47
47
  const filterString = filters || "";
48
+ const searchQuery = query ? `&query=${query}` : "";
49
+ const filterQuery = filterBy ? `&filterBy=${filterBy}` : "";
48
50
 
49
- SERVICES.GET_REDIRECTS.dynamicUrl = `${host}${endpoint}?page=${page}&itemsPerPage=${itemsPerPage}&pagination=${pagination}${filterString}`;
51
+ SERVICES.GET_REDIRECTS.dynamicUrl = `${host}${endpoint}?page=${page}&itemsPerPage=${itemsPerPage}&pagination=${pagination}${filterString}${searchQuery}${filterQuery}`;
50
52
 
51
53
  return sendRequest(SERVICES.GET_REDIRECTS);
52
54
  };
package/src/api/sites.tsx CHANGED
@@ -101,8 +101,10 @@ const SERVICES: { [key: string]: IServiceConfig } = {
101
101
  },
102
102
  };
103
103
 
104
- const getAllSites = async (token: string) => {
105
- return sendInitialRequest(SERVICES.GET_ALL_SITES, token);
104
+ const getAllSites = async (language?: number) => {
105
+ const { host, endpoint } = SERVICES.GET_ALL_SITES;
106
+ SERVICES.GET_ALL_SITES.dynamicUrl = language ? `${host}${endpoint}?language=${language}` : "";
107
+ return sendRequest(SERVICES.GET_ALL_SITES);
106
108
  };
107
109
 
108
110
  const getSiteInfo = async (siteID: number) => {
@@ -29,6 +29,7 @@ const Browser = (props: IBrowserProps): JSX.Element => {
29
29
  siteID,
30
30
  isPreview,
31
31
  setSelectedContent,
32
+ browserRef,
32
33
  } = props;
33
34
 
34
35
  const API_URL = process.env.REACT_APP_API_ENDPOINT;
@@ -134,7 +135,7 @@ const Browser = (props: IBrowserProps): JSX.Element => {
134
135
  const initialContent = `<!DOCTYPE html><html><head>${getStylesFromHeader()}</head><body><div></div></body></html>`;
135
136
 
136
137
  return (
137
- <S.BrowserWrapper>
138
+ <S.BrowserWrapper ref={browserRef}>
138
139
  <S.NavBar>
139
140
  <S.NavUrl>{url}</S.NavUrl>
140
141
  {isPreview && (
@@ -195,6 +196,7 @@ interface IBrowserProps {
195
196
  disabled?: boolean;
196
197
  siteID?: number;
197
198
  isPreview?: boolean;
199
+ browserRef?: any;
198
200
  }
199
201
 
200
202
  export default Browser;
@@ -67,8 +67,8 @@ const FrameWrapper = styled.div`
67
67
  height: 100%;
68
68
  `;
69
69
 
70
- const StyledFrame = styled(Frame)`
71
- box-shadow: ${(p) => p.theme.shadow.shadowL};
70
+ const StyledFrame = styled(Frame)<{ isPreview: boolean }>`
71
+ box-shadow: ${(p) => (p.isPreview ? p.theme.shadow.shadowL : "none")};
72
72
  `;
73
73
 
74
74
  export { BrowserWrapper, Wrapper, NavBar, NavUrl, NavActions, IconWrapper, FrameWrapper, StyledFrame };
@@ -103,7 +103,6 @@ interface IProps {
103
103
  error?: IErrorItem;
104
104
  deleteError(error: IErrorItem): void;
105
105
  errors: IErrorItem[];
106
- collapsed?: boolean;
107
106
  theme: string;
108
107
  moduleCopy: { date: string; element: Record<string, unknown> } | null;
109
108
  availableDataPacks: Record<string, any>[];
@@ -20,15 +20,18 @@ const ErrorCenter = (props: IProps): JSX.Element => {
20
20
  goToElement(item.key);
21
21
  };
22
22
 
23
+ const icon = item.type === "warning" ? "warning" : "alert";
24
+
23
25
  return (
24
- <S.Wrapper key={`${item.editorID}${item.key}`} onClick={handleClick}>
25
- <S.Header>
26
- <Icon name="alert" size="16" />
27
- {item.type}
26
+ <S.Wrapper key={`${item.editorID}${item.key}`} clickable={!!item.editorID} onClick={handleClick}>
27
+ <S.Header type={item.type}>
28
+ <Icon name={icon} size="16" />
29
+ <S.Type>{item.type}</S.Type>
28
30
  </S.Header>
29
31
  <S.Content>
30
32
  <S.Title>{item.message}</S.Title>
31
33
  <S.Subtitle>{item.name}</S.Subtitle>
34
+ {item.editorID && <S.Link>Go to field</S.Link>}
32
35
  </S.Content>
33
36
  </S.Wrapper>
34
37
  );
@@ -45,7 +48,7 @@ const ErrorCenter = (props: IProps): JSX.Element => {
45
48
  interface IProps {
46
49
  errors: IErrorItem[];
47
50
  actions?: {
48
- goToError(editorID: number, tab: string, template: boolean): void;
51
+ goToError(editorID: number | null, tab: string, template: boolean): void;
49
52
  };
50
53
  }
51
54
 
@@ -1,7 +1,6 @@
1
1
  import styled from "styled-components";
2
2
 
3
3
  const ActionMenu = styled.div`
4
- padding: 0 ${(p) => p.theme.spacing.s};
5
4
  width: ${(p) => `calc(4 * ${p.theme.spacing.l})`};
6
5
  max-height: 380px;
7
6
  overflow: auto;
@@ -10,16 +9,20 @@ const ActionMenu = styled.div`
10
9
  const MenuHeader = styled.div`
11
10
  ${(p) => p.theme.textStyle.headingXXS};
12
11
  color: ${(p) => p.theme.color.textLowEmphasis};
13
- padding-top: ${(p) => p.theme.spacing.xs};
12
+ padding: ${(p) => `${p.theme.spacing.xs} ${p.theme.spacing.s}`};
14
13
  `;
15
14
 
16
- const Wrapper = styled.div`
17
- padding: ${(p) => p.theme.spacing.s} 0;
15
+ const Wrapper = styled.div<{ clickable: boolean }>`
16
+ padding: ${(p) => p.theme.spacing.xs} ${(p) => p.theme.spacing.s};
18
17
  border-bottom: 1px solid ${(p) => p.theme.color.uiLine};
19
- cursor: pointer;
18
+ pointer-events: ${(p) => (p.clickable ? "auto" : "none")};
19
+ cursor: ${(p) => (p.clickable ? "pointer" : "default")};
20
+ :hover {
21
+ background-color: ${(p) => (p.clickable ? p.theme.color.overlayHoverPrimary : "transparent")};
22
+ }
20
23
  `;
21
24
 
22
- const Header = styled.div`
25
+ const Header = styled.div<{ type: string }>`
23
26
  ${(p) => p.theme.textStyle.uiXS};
24
27
  color: ${(p) => p.theme.color.textLowEmphasis};
25
28
  display: flex;
@@ -28,7 +31,7 @@ const Header = styled.div`
28
31
  svg {
29
32
  margin-right: ${(p) => p.theme.spacing.xxs};
30
33
  path {
31
- fill: ${(p) => p.theme.color.error};
34
+ fill: ${(p) => (p.type === "warning" ? p.theme.color.interactive02 : p.theme.color.error)};
32
35
  }
33
36
  }
34
37
  `;
@@ -49,4 +52,14 @@ const Subtitle = styled.div`
49
52
  color: ${(p) => p.theme.color.textLowEmphasis};
50
53
  `;
51
54
 
52
- export { ActionMenu, MenuHeader, Wrapper, Header, Content, Title, Subtitle };
55
+ const Type = styled.span`
56
+ text-transform: capitalize;
57
+ `;
58
+
59
+ const Link = styled.div`
60
+ ${(p) => p.theme.textStyle.uiS};
61
+ color: ${(p) => p.theme.color.interactive01};
62
+ margin-top: ${(p) => p.theme.spacing.xxs};
63
+ `;
64
+
65
+ export { ActionMenu, MenuHeader, Wrapper, Header, Content, Title, Subtitle, Type, Link };
@@ -11,6 +11,7 @@ const ColorPicker = (props: IProps): JSX.Element => {
11
11
  const { value, onChange, error, colors, handleValidation, theme } = props;
12
12
 
13
13
  const initialState = { color: value, inputValue: value };
14
+
14
15
  const reducer = useCallback((state: any, payload: any) => ({ ...state, ...payload }), []);
15
16
  const [state, dispatch] = useReducer(reducer, initialState);
16
17
 
@@ -0,0 +1,85 @@
1
+ import React, { memo } from "react";
2
+
3
+ import { FieldsBehavior } from "@ax/components";
4
+ import { ILinkField, IUrlField } from "@ax/types";
5
+
6
+ const LinkField = (props: ILinkFieldProps): JSX.Element => {
7
+ const { value, onChange, disabled, whiteList, goTo, theme, actions } = props;
8
+
9
+ const handleTextChange = (newValue: string) => onChange({ ...value, text: newValue });
10
+ const handleLinkTypeChange = (newValue: string) => onChange({ ...value, linkType: newValue });
11
+ const handleUrlChange = (newValue: IUrlField) => onChange({ ...value, url: newValue });
12
+ const handleModalChange = (newValue: any) => onChange({ ...value, modal: newValue });
13
+
14
+ const isModal = value?.linkType === "modal";
15
+
16
+ return (
17
+ <>
18
+ <FieldsBehavior
19
+ title="Text"
20
+ name="text"
21
+ fieldType="TextField"
22
+ value={value.text}
23
+ onChange={handleTextChange}
24
+ disabled={disabled}
25
+ />
26
+ <FieldsBehavior
27
+ title="Type of link"
28
+ name="linkType"
29
+ fieldType="ConditionalField"
30
+ value={value.linkType}
31
+ onChange={handleLinkTypeChange}
32
+ disabled={disabled}
33
+ options={[
34
+ {
35
+ value: "url",
36
+ title: "Link to Page",
37
+ name: "url",
38
+ },
39
+ {
40
+ value: "modal",
41
+ title: "Open Modal",
42
+ name: "modal",
43
+ },
44
+ ]}
45
+ />
46
+ {isModal ? (
47
+ <FieldsBehavior
48
+ title="Modal"
49
+ name="modal"
50
+ fieldType="ComponentContainer"
51
+ value={value.modal}
52
+ onChange={handleModalChange}
53
+ disabled={disabled}
54
+ whiteList={whiteList}
55
+ selectedContent={value}
56
+ objKey="modal"
57
+ goTo={goTo}
58
+ theme={theme}
59
+ actions={actions}
60
+ />
61
+ ) : (
62
+ <FieldsBehavior
63
+ title="URL"
64
+ name="url"
65
+ fieldType="UrlField"
66
+ value={value.url}
67
+ onChange={handleUrlChange}
68
+ disabled={disabled}
69
+ />
70
+ )}
71
+ </>
72
+ );
73
+ };
74
+
75
+ interface ILinkFieldProps {
76
+ value: ILinkField;
77
+ onChange: (value: ILinkField | null) => void;
78
+ disabled?: boolean;
79
+ whiteList: string[];
80
+ actions: any;
81
+ theme: string;
82
+ goTo: any;
83
+ }
84
+
85
+ export default memo(LinkField);
@@ -27,6 +27,10 @@ const ItemList = (props: IProps) => {
27
27
  const response = await structuredData.getDistributorContent(siteID, params);
28
28
  if (isReqOk(response.status)) {
29
29
  setState((state: IReferenceState) => ({ ...state, selectedItems: response.data }));
30
+ if (fixed.length !== response.data.length) {
31
+ const itemsID = response.data.reduce((previous: any, current: any) => [...previous, current.id], []);
32
+ setState((state: IReferenceState) => ({ ...state, fixed: itemsID }));
33
+ }
30
34
  } else {
31
35
  console.log("Error en getItems");
32
36
  }
@@ -45,7 +49,7 @@ const ItemList = (props: IProps) => {
45
49
 
46
50
  const handleDelete = (item: IStructuredDataContent) => {
47
51
  const originalItemId = item.relatedPage?.originalStructuredDataId;
48
- const itemId = state.fixed.includes(originalItemId) ? originalItemId : item.id;
52
+ const itemId = fixed.includes(originalItemId) ? originalItemId : item.id;
49
53
  if (fixed.includes(itemId)) {
50
54
  const newSelIds = fixed.filter((a: any) => a !== itemId);
51
55
  const selItems = selectedItems.filter((b: any) => b.id !== itemId);
@@ -17,10 +17,21 @@ const ReferenceFieldWithProvider = (props: IProps) => (
17
17
  <ReferenceProvider modes={props.selectionType}>
18
18
  <ReferenceField {...props} />
19
19
  </ReferenceProvider>
20
- )
20
+ );
21
21
 
22
22
  const ReferenceField = (props: IProps) => {
23
- const { source, value, onChange, disabled, site, selectionType, structuredDataValues, validators, maxItems } = props;
23
+ const {
24
+ source,
25
+ value,
26
+ onChange,
27
+ disabled,
28
+ site,
29
+ selectionType,
30
+ structuredDataValues,
31
+ validators,
32
+ maxItems,
33
+ resetValidation,
34
+ } = props;
24
35
 
25
36
  const { isOpen, toggleModal } = useModal();
26
37
 
@@ -110,6 +121,7 @@ const ReferenceField = (props: IProps) => {
110
121
  fixed,
111
122
  };
112
123
  onChange(newValue);
124
+ resetValidation && resetValidation();
113
125
  };
114
126
 
115
127
  const icon = isAuto ? "edit" : "add";
@@ -152,14 +164,9 @@ const ReferenceField = (props: IProps) => {
152
164
 
153
165
  const getPanel = () =>
154
166
  isAuto ? (
155
- <AutoPanel
156
- structuredData={structuredDataValues}
157
- onChange={handleOnChange}
158
- site={site}
159
- validators={validators}
160
- />
167
+ <AutoPanel structuredData={structuredDataValues} onChange={handleOnChange} site={site} validators={validators} />
161
168
  ) : (
162
- <ManualPanel onChange={handleOnChange} hasMaxItems={hasMaxItems} />
169
+ <ManualPanel onChange={handleOnChange} hasMaxItems={hasMaxItems} />
163
170
  );
164
171
 
165
172
  const manualItems = !isAuto && value && Array.isArray(value.fixed) ? value.fixed.length : 0;
@@ -189,11 +196,7 @@ const ReferenceField = (props: IProps) => {
189
196
  {isAuto ? (
190
197
  autoData
191
198
  ) : (
192
- <ItemList
193
- items={value ? value.fixed : []}
194
- handleListDelete={handleListDelete}
195
- handleChange={onChange}
196
- />
199
+ <ItemList items={value ? value.fixed : []} handleListDelete={handleListDelete} handleChange={onChange} />
197
200
  )}
198
201
  <FloatingPanel title="Configure elements" toggleModal={toggleModal} isOpen={isOpen}>
199
202
  {isOpen && getPanel()}
@@ -212,6 +215,7 @@ interface IProps {
212
215
  structuredDataValues: { global: IStructuredData[]; site: IStructuredData[] };
213
216
  validators?: Record<string, unknown>;
214
217
  maxItems?: number;
218
+ resetValidation?: () => void;
215
219
  }
216
220
 
217
221
  const mapStateToProps = (state: IRootState) => ({
@@ -11,7 +11,17 @@ import { findAnchorsFromPage, findAnchorsFromTab, findTabsFromPage } from "./uti
11
11
  import * as S from "./style";
12
12
 
13
13
  const UrlField = (props: IUrlFieldProps): JSX.Element => {
14
- const { value, onChange, showAdvanced, handlePanel, inFloatingPanel, disabled, handleValidation, validators } = props;
14
+ const {
15
+ value,
16
+ onChange,
17
+ showAdvanced,
18
+ handlePanel,
19
+ inFloatingPanel,
20
+ disabled,
21
+ handleValidation,
22
+ validators,
23
+ resetValidation,
24
+ } = props;
15
25
  const { isOpen, toggleModal } = useModal();
16
26
  const [anchorOptions, setAnchorOptions] = useState<ISelectOption[]>([]);
17
27
  const [tabOptions, setTabOptions] = useState<ISelectOption[]>([]);
@@ -70,6 +80,7 @@ const UrlField = (props: IUrlFieldProps): JSX.Element => {
70
80
  const handleReset = () => {
71
81
  onChange(null);
72
82
  setInternalPageName(null);
83
+ resetValidation && resetValidation();
73
84
  };
74
85
 
75
86
  const handleSetPage = (page: IPage) => {
@@ -219,6 +230,7 @@ interface IUrlFieldProps {
219
230
  inFloatingPanel?: boolean;
220
231
  disabled?: boolean;
221
232
  handleValidation?: (value: string, validators?: Record<string, unknown>) => void;
233
+ resetValidation?: () => void;
222
234
  validators?: Record<string, unknown>;
223
235
  }
224
236
 
@@ -15,6 +15,7 @@ import FileField from "./FileField";
15
15
  import HeadingField from "./HeadingField";
16
16
  import HiddenField from "./HiddenField";
17
17
  import ImageField from "./ImageField";
18
+ import LinkField from "./LinkField";
18
19
  import MultiCheckSelect from "./MultiCheckSelect";
19
20
  import MultiCheckSelectGroup from "./MultiCheckSelectGroup";
20
21
  import NoteField from "./NoteField";
@@ -53,6 +54,7 @@ export {
53
54
  HeadingField,
54
55
  HiddenField,
55
56
  ImageField,
57
+ LinkField,
56
58
  MultiCheckSelect,
57
59
  MultiCheckSelectGroup,
58
60
  NoteField,
@@ -71,10 +71,23 @@ const FieldsBehavior = (props: any): JSX.Element => {
71
71
  }
72
72
  setErrorField(!isValid);
73
73
  };
74
+
75
+ const resetValidation = () => {
76
+ setMessage(helptext);
77
+ error && deleteError && deleteError(error);
78
+ setErrorField(false);
79
+ };
80
+
74
81
  return (
75
82
  <S.Wrapper error={errorField} className={wrapperClass} showTitle={showTitle} id={objKey}>
76
83
  <S.Content data-testid="contentWrapper" error={errorField}>
77
- <Field {...props} showAdvanced={showAdvanced} handleValidation={handleValidation} error={errorField} />
84
+ <Field
85
+ {...props}
86
+ showAdvanced={showAdvanced}
87
+ handleValidation={handleValidation}
88
+ resetValidation={resetValidation}
89
+ error={errorField}
90
+ />
78
91
  </S.Content>
79
92
  <S.Header className="fieldHeader">
80
93
  {showTitle && (
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+
3
+ const SvgCopy = (props) => (
4
+ <svg width={24} height={24} fill="none" {...props}>
5
+ <path
6
+ fillRule="evenodd"
7
+ clipRule="evenodd"
8
+ d="M12.5263 2.3158H3.78947C2.80526 2.3158 2 3.12106 2 4.10527V16.6316H3.78947V4.10527H12.5263V2.3158ZM15.2105 5.89475H7.36842C6.38421 5.89475 5.57894 6.70001 5.57894 7.68422V20.2105C5.57894 21.1947 6.38421 22 7.36842 22H15.2105C16.1947 22 17 21.1947 17 20.2105V18H15.2105V20.2105H7.36843V7.68422H15.2105V10H17V7.68422C17 6.70001 16.1947 5.89475 15.2105 5.89475ZM22 14L18 10V13H13V15H18V18L22 14Z"
9
+ fill="#5057FF"
10
+ />
11
+ </svg>
12
+ );
13
+
14
+ export default SvgCopy;
@@ -0,0 +1,3 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12.5263 2.3158H3.78947C2.80526 2.3158 2 3.12106 2 4.10527V16.6316H3.78947V4.10527H12.5263V2.3158ZM15.2105 5.89475H7.36842C6.38421 5.89475 5.57894 6.70001 5.57894 7.68422V20.2105C5.57894 21.1947 6.38421 22 7.36842 22H15.2105C16.1947 22 17 21.1947 17 20.2105V18H15.2105V20.2105H7.36843V7.68422H15.2105V10H17V7.68422C17 6.70001 16.1947 5.89475 15.2105 5.89475ZM22 14L18 10V13H13V15H18V18L22 14Z" fill="#5057FF"/>
3
+ </svg>
@@ -43,6 +43,8 @@ const AppBar = (props: IProps): JSX.Element => {
43
43
  errorActions,
44
44
  isFromEditor,
45
45
  pageStatusActions,
46
+ filterSearchAction,
47
+ searchFilters,
46
48
  } = props;
47
49
 
48
50
  const publishedTooltip: any = {
@@ -158,21 +160,28 @@ const AppBar = (props: IProps): JSX.Element => {
158
160
  </S.WrapperTitle>
159
161
  {tabs && (
160
162
  <S.WrapperTabs>
161
- <Tabs
162
- tabs={tabs.tabSet}
163
- icons={tabs.icons}
164
- active={tabs.selectedTab}
165
- setSelectedTab={tabs.action}
166
- isInAppBar={true}
167
- inversed={inversed}
168
- />
163
+ <S.TabsContent>
164
+ <Tabs
165
+ tabs={tabs.tabSet}
166
+ icons={tabs.icons}
167
+ active={tabs.selectedTab}
168
+ setSelectedTab={tabs.action}
169
+ isInAppBar={true}
170
+ inversed={inversed}
171
+ />
172
+ </S.TabsContent>
169
173
  </S.WrapperTabs>
170
174
  )}
171
175
  <S.WrapperEnd>
172
176
  {searchAction && (
173
177
  <>
174
- <S.SearchWrapper>
175
- <SearchField onChange={searchAction} closeOnInactive />
178
+ <S.SearchWrapper length={searchFilters && searchFilters.length ? 8 : 5}>
179
+ <SearchField
180
+ onChange={searchAction}
181
+ onFilterChange={filterSearchAction}
182
+ searchFilters={searchFilters}
183
+ closeOnInactive
184
+ />
176
185
  </S.SearchWrapper>
177
186
  <S.Separator />
178
187
  </>
@@ -261,6 +270,8 @@ interface IAppBarProps {
261
270
  inversed?: boolean;
262
271
  currentPageID?: number;
263
272
  searchAction?(query: string): void;
273
+ filterSearchAction?(filter: string): void;
274
+ searchFilters?: any;
264
275
  errors?: IErrorItem[];
265
276
  errorActions?: {
266
277
  goToError(editorID: number, tab: string, template: boolean): void;
@@ -7,6 +7,14 @@ const WrapperTabs = styled.div`
7
7
  flex-direction: row;
8
8
  align-items: center;
9
9
  margin-right: auto;
10
+ flex: 1 1 auto;
11
+ `;
12
+
13
+ const TabsContent = styled.div`
14
+ position: absolute;
15
+ right: 50%;
16
+ bottom: 0;
17
+ transform: translateX(50%);
10
18
  `;
11
19
 
12
20
  const WrapperEnd = styled.div`
@@ -20,7 +28,6 @@ const WrapperTitle = styled.div`
20
28
  display: flex;
21
29
  flex-direction: row;
22
30
  align-items: center;
23
- width: 600px;
24
31
  margin-right: ${(p) => p.theme.spacing.xl};
25
32
  `;
26
33
 
@@ -165,8 +172,8 @@ const ErrorWrapper = styled.div`
165
172
  }
166
173
  `;
167
174
 
168
- const SearchWrapper = styled.div`
169
- width: ${(p) => `calc(${p.theme.spacing.xl} * 5)`};
175
+ const SearchWrapper = styled.div<{ length: number }>`
176
+ width: ${(p) => `calc(${p.theme.spacing.xl} * ${p.length})`};
170
177
  display: flex;
171
178
  justify-content: flex-end;
172
179
  `;
@@ -191,4 +198,5 @@ export {
191
198
  SearchWrapper,
192
199
  WrapperEnd,
193
200
  WrapperTitle,
201
+ TabsContent,
194
202
  };
@@ -42,6 +42,8 @@ interface IWrapperProps {
42
42
  getDataContent?(dataID?: number): void;
43
43
  } | null;
44
44
  searchAction?(query: string): void;
45
+ filterSearchAction?(filter: string): void;
46
+ searchFilters?: any;
45
47
  errors?: IErrorItem[];
46
48
  errorActions?: {
47
49
  goToError(editorID: number, tab: string, template: boolean): void;
@@ -77,7 +77,6 @@ export const ModalHeader = styled.div`
77
77
  export const ModalContent = styled.div`
78
78
  position: relative;
79
79
  flex-grow: 1;
80
- overflow: auto;
81
80
  `;
82
81
 
83
82
  export const Title = styled.div`