@griddo/ax 10.2.11 → 10.2.13

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 (56) hide show
  1. package/package.json +2 -2
  2. package/src/__tests__/components/Fields/ReferenceField/ReferenceField.test.tsx +1 -1
  3. package/src/__tests__/components/Fields/UrlField/UrlField.test.tsx +1 -1
  4. package/src/components/Fields/AsyncSelect/index.tsx +12 -8
  5. package/src/components/Fields/AsyncSelect/style.tsx +58 -1
  6. package/src/components/Fields/CheckField/index.tsx +15 -2
  7. package/src/components/Fields/IntegrationsField/IntegrationItem/CustomPanel/index.tsx +49 -47
  8. package/src/components/Fields/IntegrationsField/IntegrationItem/CustomPanel/style.tsx +6 -1
  9. package/src/components/Fields/IntegrationsField/IntegrationItem/VariablesPanel/index.tsx +13 -11
  10. package/src/components/Fields/IntegrationsField/IntegrationItem/VariablesPanel/style.tsx +6 -3
  11. package/src/components/Fields/MultiCheckSelect/style.tsx +1 -0
  12. package/src/components/Fields/ReferenceField/AutoPanel/AutoItem/index.tsx +6 -5
  13. package/src/components/Fields/ReferenceField/AutoPanel/index.tsx +277 -40
  14. package/src/components/Fields/ReferenceField/AutoPanel/style.tsx +117 -15
  15. package/src/components/Fields/ReferenceField/Context/index.tsx +18 -10
  16. package/src/components/Fields/ReferenceField/ItemList/Item/index.tsx +9 -30
  17. package/src/components/Fields/ReferenceField/ItemList/Item/style.tsx +9 -51
  18. package/src/components/Fields/ReferenceField/ItemList/index.tsx +14 -18
  19. package/src/components/Fields/ReferenceField/ManualPanel/Item/index.tsx +1 -1
  20. package/src/components/Fields/ReferenceField/ManualPanel/Item/style.tsx +25 -26
  21. package/src/components/Fields/ReferenceField/ManualPanel/index.tsx +91 -36
  22. package/src/components/Fields/ReferenceField/ManualPanel/style.tsx +29 -1
  23. package/src/components/Fields/ReferenceField/index.tsx +18 -11
  24. package/src/components/Fields/Select/index.tsx +10 -13
  25. package/src/components/Fields/Select/style.tsx +13 -7
  26. package/src/components/Fields/TimeField/index.tsx +1 -0
  27. package/src/components/Fields/UniqueCheck/index.tsx +3 -1
  28. package/src/components/Fields/UrlField/index.tsx +3 -1
  29. package/src/components/Fields/UrlField/style.tsx +6 -1
  30. package/src/components/FloatingPanel/style.tsx +0 -1
  31. package/src/components/PageFinder/index.tsx +8 -7
  32. package/src/components/SearchField/index.tsx +2 -3
  33. package/src/helpers/arrays.tsx +2 -2
  34. package/src/modules/Analytics/DimensionPanel/index.tsx +44 -42
  35. package/src/modules/Analytics/DimensionPanel/style.tsx +6 -1
  36. package/src/modules/Analytics/GroupPanel/index.tsx +57 -64
  37. package/src/modules/Analytics/GroupPanel/style.tsx +6 -0
  38. package/src/modules/Categories/CategoriesList/CategoryPanel/index.tsx +15 -13
  39. package/src/modules/Categories/CategoriesList/CategoryPanel/style.tsx +11 -4
  40. package/src/modules/GlobalSettings/Robots/Item/RobotsPanel/index.tsx +20 -18
  41. package/src/modules/GlobalSettings/Robots/Item/RobotsPanel/style.tsx +6 -1
  42. package/src/modules/Navigation/Menus/List/Table/ConfigPanel/index.tsx +8 -6
  43. package/src/modules/Navigation/Menus/List/Table/ConfigPanel/style.tsx +6 -1
  44. package/src/modules/Navigation/Menus/List/Table/SidePanel/index.tsx +15 -13
  45. package/src/modules/Navigation/Menus/List/Table/SidePanel/style.tsx +9 -2
  46. package/src/modules/PublicPreview/index.tsx +1 -1
  47. package/src/modules/Redirects/RedirectPanel/index.tsx +33 -31
  48. package/src/modules/Redirects/RedirectPanel/style.tsx +6 -1
  49. package/src/modules/Redirects/index.tsx +0 -1
  50. package/src/modules/Settings/Integrations/IntegrationForm/VariablePanel/index.tsx +63 -61
  51. package/src/modules/Settings/Integrations/IntegrationForm/VariablePanel/style.tsx +6 -1
  52. package/src/modules/Settings/Integrations/IntegrationForm/index.tsx +5 -3
  53. package/src/modules/Settings/Integrations/IntegrationForm/style.tsx +6 -0
  54. package/src/modules/Settings/Languages/LanguagePanel/index.tsx +14 -12
  55. package/src/modules/Settings/Languages/LanguagePanel/style.tsx +8 -1
  56. package/src/types/index.tsx +1 -1
@@ -1,20 +1,13 @@
1
+ import React from "react";
1
2
  import styled from "styled-components";
3
+ import { ActionMenu } from "@ax/components";
2
4
 
3
- const IconActionWrapper = styled.div`
4
- opacity: 0;
5
+ const StyledActionMenu = styled((props) => <ActionMenu {...props} />)`
5
6
  position: absolute;
6
7
  top: ${(p) => p.theme.spacing.xs};
7
- right: 0;
8
- width: 30px;
9
- display: flex;
10
- justify-content: center;
11
- align-items: center;
12
- margin-right: ${(p) => p.theme.spacing.xs};
13
-
14
- &:active {
15
- border-radius: 50%;
16
- background-color: ${(p) => p.theme.color.overlayPressedPrimary};
17
- }
8
+ right: ${(p) => p.theme.spacing.xs};
9
+ width: 32px;
10
+ opacity: 0;
18
11
  `;
19
12
 
20
13
  const Item = styled.li`
@@ -29,13 +22,13 @@ const Item = styled.li`
29
22
  cursor: pointer;
30
23
  &:hover {
31
24
  background-color: ${(p) => p.theme.color.overlayHoverPrimary};
32
- ${IconActionWrapper} {
25
+ ${StyledActionMenu} {
33
26
  opacity: 1;
34
27
  }
35
28
  }
36
29
  :focus {
37
30
  background-color: ${(p) => p.theme.color.overlayFocusPrimary};
38
- ${IconActionWrapper} {
31
+ ${StyledActionMenu} {
39
32
  opacity: 1;
40
33
  }
41
34
  }
@@ -69,38 +62,6 @@ const Title = styled.div`
69
62
  color: ${(p) => p.theme.color.textHighEmphasis};
70
63
  `;
71
64
 
72
- const ActionMenu = styled.ul`
73
- padding: 0;
74
- `;
75
-
76
- const ActionText = styled.span`
77
- padding-left: ${(p) => p.theme.spacing.xs};
78
- margin-left: ${(p) => p.theme.spacing.xxs};
79
- text-transform: capitalize;
80
- `;
81
-
82
- const ActionItem = styled.li`
83
- display: flex;
84
- align-items: center;
85
- ${(p) => p.theme.textStyle.uiM};
86
- color: ${(p) => p.theme.color.textMediumEmphasis};
87
- padding: ${(p) => p.theme.spacing.xs} ${(p) => p.theme.spacing.s};
88
- height: ${(p) => p.theme.spacing.l};
89
- &:focus {
90
- background: ${(p) => p.theme.color.overlayFocusPrimary};
91
- }
92
-
93
- &:hover {
94
- background: ${(p) => p.theme.color.overlayHoverPrimary};
95
- }
96
-
97
- svg {
98
- path {
99
- fill: ${(p) => p.theme.color.iconMediumEmphasis};
100
- }
101
- }
102
- `;
103
-
104
65
  const ButtonsWrapper = styled.span`
105
66
  display: flex;
106
67
  position: absolute;
@@ -125,17 +86,14 @@ const IconHandleWrapper = styled.div`
125
86
  `;
126
87
 
127
88
  export {
128
- IconActionWrapper,
129
89
  Item,
130
90
  TextWrapper,
131
91
  Header,
132
92
  Date,
133
93
  Type,
134
94
  Title,
135
- ActionMenu,
136
- ActionText,
137
- ActionItem,
138
95
  ButtonsWrapper,
139
96
  HandleWrapper,
140
97
  IconHandleWrapper,
98
+ StyledActionMenu,
141
99
  };
@@ -11,25 +11,26 @@ import { IReferenceState, useReference } from "../Context";
11
11
  import * as S from "./style";
12
12
 
13
13
  const ItemList = (props: IProps) => {
14
- const { items, currentSite, handleListDelete, handleChange } = props;
14
+ const { items, currentSite, handleListDelete } = props;
15
15
 
16
16
  const { state, setState, setReorderElements } = useReference();
17
- const { fixed, mode, selectedItems, sourceTitles, fullRelations } = state;
17
+ const { fixed, selectedItems, sourceTitles, fullRelations, site } = state;
18
18
 
19
19
  useEffect(() => {
20
20
  const params = {
21
21
  mode: "manual",
22
22
  fixed: items,
23
23
  fullRelations,
24
+ site,
24
25
  };
25
26
 
26
27
  const getItems = async () => {
27
28
  const siteID = currentSite ? currentSite : "global";
28
29
  const response = await structuredData.getDistributorContent(siteID, params);
29
- if (isReqOk(response.status)) {
30
+ if (isReqOk(response?.status)) {
30
31
  setState((state: IReferenceState) => ({ ...state, selectedItems: response.data }));
31
32
  if (fixed.length !== response.data.length) {
32
- const itemsID = response.data.reduce((previous: any, current: any) => [...previous, current.id], []);
33
+ const itemsID = response.data.map((item: IStructuredDataContent) => item.id);
33
34
  setState((state: IReferenceState) => ({ ...state, fixed: itemsID }));
34
35
  }
35
36
  } else {
@@ -40,20 +41,16 @@ const ItemList = (props: IProps) => {
40
41
  // eslint-disable-next-line react-hooks/exhaustive-deps
41
42
  }, [items]);
42
43
 
43
- useEffect(() => {
44
- if (fixed) {
45
- const newValue = { mode, fixed };
46
- handleChange(newValue);
47
- }
48
- // eslint-disable-next-line react-hooks/exhaustive-deps
49
- }, [fixed]);
50
-
51
44
  const handleDelete = (item: IStructuredDataContent) => {
52
- const originalItemId = item.relatedPage?.originalStructuredDataId;
53
- const itemId = state.fixed.includes(originalItemId) ? originalItemId : item.id;
54
- if (fixed.includes(itemId)) {
55
- const newSelIds = fixed.filter((a: any) => a !== itemId);
56
- const selItems = selectedItems.filter((b: any) => b.id !== itemId);
45
+ const langItem = item.dataLanguages?.length
46
+ ? item.dataLanguages.find((lang) => fixed.includes(lang.id))
47
+ : fixed.includes(item.id)
48
+ ? item
49
+ : null;
50
+
51
+ if (langItem) {
52
+ const newSelIds = fixed.filter((id: number) => id !== langItem.id);
53
+ const selItems = selectedItems.filter((item: IStructuredDataContent) => item.id !== langItem.id);
57
54
  setState((state: IReferenceState) => ({ ...state, fixed: newSelIds, selectedItems: selItems }));
58
55
  handleListDelete(newSelIds);
59
56
  }
@@ -114,7 +111,6 @@ interface IProps {
114
111
  items: number[];
115
112
  currentSite: number | null;
116
113
  handleListDelete(value: string[]): void;
117
- handleChange(newValue: any): void;
118
114
  }
119
115
 
120
116
  const mapStateToProps = (state: IRootState) => ({
@@ -16,7 +16,7 @@ const Item = (props: IProps): JSX.Element => {
16
16
 
17
17
  return (
18
18
  <Tooltip content={tooltip} bottom>
19
- <S.Item onClick={handleItemClick} data-testid="manual-panel-item">
19
+ <S.Item onClick={handleItemClick} data-testid="manual-panel-item" disabled={disabled}>
20
20
  <CheckField name="check" value={item.id} checked={isChecked} disabled={disabled} />
21
21
  <S.TextWrapper>
22
22
  <S.Header>
@@ -1,19 +1,40 @@
1
1
  import styled from "styled-components";
2
2
 
3
- const Item = styled.li`
3
+ const Date = styled.div`
4
+ ${(p) => p.theme.textStyle.uiXS};
5
+ `;
6
+
7
+ const Type = styled.div`
8
+ ${(p) => p.theme.textStyle.headingXSS};
9
+ `;
10
+
11
+ const Title = styled.div`
12
+ ${(p) => p.theme.textStyle.fieldContent};
13
+ `;
14
+
15
+ const Item = styled.li<{ disabled: boolean }>`
4
16
  display: flex;
5
17
  background-color: ${(p) => p.theme.color.uiBarBackground};
6
18
  border: ${(p) => `1px solid ${p.theme.color.uiLine}`};
7
19
  border-radius: ${(p) => p.theme.radii.s};
8
20
  padding: ${(p) => p.theme.spacing.s};
9
21
  margin-bottom: ${(p) => p.theme.spacing.xs};
10
- cursor: pointer;
22
+ cursor: ${(p) => (p.disabled ? "default" : "pointer")};
11
23
  :hover {
12
- background-color: ${(p) => p.theme.color.overlayHoverPrimary};
24
+ background-color: ${(p) => (p.disabled ? p.theme.color.uiBarBackground : p.theme.color.overlayHoverPrimary)};
13
25
  }
14
26
  :focus {
15
27
  background-color: ${(p) => p.theme.color.overlayFocusPrimary};
16
28
  }
29
+ ${Date} {
30
+ color: ${(p) => (p.disabled ? p.theme.color.uiLine : p.theme.color.textMediumEmphasis)};
31
+ }
32
+ ${Type} {
33
+ color: ${(p) => (p.disabled ? p.theme.color.uiLine : p.theme.color.textLowEmphasis)};
34
+ }
35
+ ${Title} {
36
+ color: ${(p) => (p.disabled ? p.theme.color.uiLine : p.theme.color.textHighEmphasis)};
37
+ }
17
38
  `;
18
39
 
19
40
  const TextWrapper = styled.div`
@@ -26,26 +47,4 @@ const Header = styled.div`
26
47
  margin-bottom: ${(p) => p.theme.spacing.xxs};
27
48
  `;
28
49
 
29
- const Date = styled.div`
30
- ${(p) => p.theme.textStyle.uiXS};
31
- color: ${(p) => p.theme.color.textMediumEmphasis};
32
- `;
33
-
34
- const Type = styled.div`
35
- ${(p) => p.theme.textStyle.headingXSS};
36
- color: ${(p) => p.theme.color.textLowEmphasis};
37
- `;
38
-
39
- const Title = styled.div`
40
- ${(p) => p.theme.textStyle.fieldContent};
41
- color: ${(p) => p.theme.color.textHighEmphasis};
42
- `;
43
-
44
- export {
45
- Item,
46
- TextWrapper,
47
- Header,
48
- Date,
49
- Type,
50
- Title
51
- };
50
+ export { Item, TextWrapper, Header, Date, Type, Title };
@@ -11,7 +11,7 @@ import {
11
11
  } from "@ax/types";
12
12
  import { isReqOk } from "@ax/helpers";
13
13
  import { structuredData } from "@ax/api";
14
- import { Button, Loader, Select, TextField } from "@ax/components";
14
+ import { AsyncSelect, Button, Loader, Select, TextField } from "@ax/components";
15
15
  import { useDebounce } from "@ax/hooks";
16
16
  import { IReferenceState, useReference } from "../Context";
17
17
  import Item from "./Item";
@@ -19,38 +19,43 @@ import Item from "./Item";
19
19
  import * as S from "./style";
20
20
 
21
21
  const ManualPanel = (props: IProps) => {
22
- const { onChange, currentSite, hasMaxItems, handleValidation, validators, lang, siteLangs, globalLangs } = props;
22
+ const { onChange, currentSite, hasMaxItems, handleValidation, validators, lang, globalLangs } = props;
23
23
 
24
24
  const { state, setState } = useReference();
25
25
 
26
26
  const [isLoading, setIsLoading] = useState(false);
27
- const [selectedSource, setSelectedSource] = useState(state.sourceTitles[0]?.id);
28
- const [selectedLang, setSelectedLang] = useState(lang.id);
27
+ const initForm: IFormState = {
28
+ source: state.sourceTitles[0]?.id,
29
+ lang: lang.id,
30
+ site: state.site || currentSite,
31
+ };
32
+ const [form, setForm] = useState(initForm);
33
+ const [itemSite, setItemSite] = useState<number | null>(state.site || currentSite);
29
34
  const debouncedSearch = useDebounce(state.search);
30
35
 
31
- const availableLangs = currentSite ? siteLangs : globalLangs;
32
- const langOptions = availableLangs.map((lang) => ({ label: lang.label, value: lang.id.toString() }));
36
+ const langOptions = globalLangs.map((lang) => ({ label: lang.label, value: lang.id.toString() }));
33
37
 
34
38
  useEffect(() => {
35
39
  let isMounted = true;
36
40
  const params: IGetStructuredDataParams = {
37
- dataID: selectedSource,
41
+ dataID: form.source,
38
42
  page: 1,
39
43
  itemsPerPage: 50,
40
44
  pagination: true,
41
45
  deleted: false,
42
46
  include_draft: false,
43
47
  query: debouncedSearch,
44
- lang: selectedLang,
48
+ lang: form.lang,
45
49
  };
46
50
 
47
51
  const getAndSetItems = async () => {
48
52
  if (!isMounted) return;
49
53
 
50
54
  setIsLoading(true);
55
+ const siteID = form.site ? form.site : currentSite;
51
56
  const response: { status: number; data: { totalItems: number; items: any } } =
52
- await structuredData.getDataContents(params, currentSite);
53
- if (isReqOk(response.status)) {
57
+ await structuredData.getDataContents(params, siteID);
58
+ if (isReqOk(response?.status)) {
54
59
  const { items } = response.data;
55
60
  setState((state: IReferenceState) => ({ ...state, items }));
56
61
  } else {
@@ -58,25 +63,33 @@ const ManualPanel = (props: IProps) => {
58
63
  }
59
64
  setIsLoading(false);
60
65
  };
61
- selectedSource && getAndSetItems();
66
+ form.source && getAndSetItems();
62
67
 
63
68
  return function cleanup() {
64
69
  isMounted = false;
65
70
  };
66
71
  // eslint-disable-next-line react-hooks/exhaustive-deps
67
- }, [currentSite, selectedSource, debouncedSearch, state.mode, selectedLang]);
72
+ }, [form.site, form.source, debouncedSearch, state.mode, form.lang]);
68
73
 
69
74
  const handleOnClick = (item: IStructuredDataContent) => {
70
75
  let newSelIds: number[];
71
76
  let selItems: number[];
72
- const itemSelected = item.dataLanguages.find((dataLang: IDataLanguage) => state.fixed.includes(dataLang.id));
77
+ const itemSelectedID = item.dataLanguages?.length
78
+ ? item.dataLanguages.find((dataLang: IDataLanguage) => state.fixed.includes(dataLang.id))?.id
79
+ : state.fixed.includes(item.id)
80
+ ? item.id
81
+ : undefined;
73
82
 
74
- if (itemSelected) {
75
- newSelIds = state.fixed.filter((a: number) => a !== itemSelected.id);
76
- selItems = state.selectedItems.filter((b: IStructuredDataContent) => b.id !== itemSelected.id);
83
+ if (itemSelectedID) {
84
+ newSelIds = state.fixed.filter((a: number) => a !== itemSelectedID);
85
+ selItems = state.selectedItems.filter((b: IStructuredDataContent) => b.id !== itemSelectedID);
86
+ if(selItems.length === 0) {
87
+ setItemSite(form.site);
88
+ }
77
89
  } else {
78
90
  newSelIds = [...state.fixed, item.id];
79
91
  selItems = [...state.selectedItems, item];
92
+ setItemSite(form.site);
80
93
  }
81
94
  const showSelected = state.showSelected && newSelIds.length === 0 ? false : state.showSelected;
82
95
  setState((state: IReferenceState) => ({ ...state, fixed: newSelIds, selectedItems: selItems, showSelected }));
@@ -86,8 +99,8 @@ const ManualPanel = (props: IProps) => {
86
99
  setState((state: IReferenceState) => ({ ...state, showSelected: !state.showSelected }));
87
100
 
88
101
  const handleAdd = () => {
89
- const { mode, fixed, fullRelations } = state;
90
- const newValue = { mode, fixed, fullRelations };
102
+ const { mode, fixed, fullRelations, site } = state;
103
+ const newValue = { mode, fixed, fullRelations, site };
91
104
  onChange(newValue);
92
105
  handleValidation && handleValidation(state.fixed, validators);
93
106
  };
@@ -108,9 +121,17 @@ const ManualPanel = (props: IProps) => {
108
121
  return { label: singleSource.title, value: singleSource.id };
109
122
  });
110
123
 
111
- const handleSource = (newSource: string) => setSelectedSource(newSource);
124
+ const handleSource = (newSource: string) => setForm({ ...form, source: newSource });
125
+
126
+ const handleLang = (newLang: string) => setForm({ ...form, lang: parseInt(newLang) });
127
+
128
+ const handleSite = (newSite: string | number | null) => {
129
+ (typeof newSite === "number" || newSite === null) && setForm({ ...form, site: newSite });
130
+ const siteID = newSite !== currentSite && newSite !== null ? newSite : undefined;
131
+ setState((state: IReferenceState) => ({ ...state, site: siteID }));
132
+ };
112
133
 
113
- const handleLang = (newLang: string) => setSelectedLang(parseInt(newLang));
134
+ const hasContentFromOtherSite = state.fixed.length > 0 && form.site !== itemSite && !state.showSelected;
114
135
 
115
136
  return (
116
137
  <S.Wrapper>
@@ -124,13 +145,26 @@ const ManualPanel = (props: IProps) => {
124
145
  {!state.showSelected && (
125
146
  <>
126
147
  <S.SelectsWrapper>
127
- {availableLangs.length > 1 && (
148
+ {globalLangs.length > 1 && (
128
149
  <Select
129
150
  name="selectLang"
130
151
  options={langOptions}
131
152
  onChange={handleLang}
132
- value={selectedLang.toString()}
153
+ value={form.lang.toString()}
133
154
  type="inline"
155
+ mandatory={true}
156
+ />
157
+ )}
158
+ {currentSite && (
159
+ <AsyncSelect
160
+ name="select"
161
+ entity="sites"
162
+ onChange={handleSite}
163
+ value={form.site}
164
+ type="inline"
165
+ placeholder="Select"
166
+ maxWidth={130}
167
+ mandatory={true}
134
168
  />
135
169
  )}
136
170
  {state.sourceTitles.length > 1 && (
@@ -138,8 +172,10 @@ const ManualPanel = (props: IProps) => {
138
172
  name="selectSource"
139
173
  options={options}
140
174
  onChange={handleSource}
141
- value={selectedSource}
175
+ value={form.source}
142
176
  type="inline"
177
+ mandatory={true}
178
+ maxWidth={70}
143
179
  />
144
180
  )}
145
181
  </S.SelectsWrapper>
@@ -154,6 +190,18 @@ const ManualPanel = (props: IProps) => {
154
190
  </S.LoadingWrapper>
155
191
  ) : (
156
192
  <S.ListWrapper>
193
+ <S.Order>Most recent</S.Order>
194
+ {state.site && !hasContentFromOtherSite && !state.showSelected && (
195
+ <S.Note>
196
+ You can only select content <strong>from 1 site</strong>.
197
+ </S.Note>
198
+ )}
199
+ {hasContentFromOtherSite && (
200
+ <S.Note>
201
+ Select content from one site at a time. <strong>Remove previous selection</strong> to choose from other
202
+ site.
203
+ </S.Note>
204
+ )}
157
205
  <S.ItemList>
158
206
  {showedItems &&
159
207
  showedItems.map((item: IStructuredDataContent) => {
@@ -162,20 +210,23 @@ const ManualPanel = (props: IProps) => {
162
210
  (dataLang: IDataLanguage) => dataLang.language === lang.id && item.language !== lang.id
163
211
  );
164
212
  const isSelectedOtherLanguage = item.dataLanguages.find(
165
- (dataLang: IDataLanguage) => state.fixed.includes(dataLang.id) && dataLang.language !== selectedLang
213
+ (dataLang: IDataLanguage) => state.fixed.includes(dataLang.id) && dataLang.language !== form.lang
166
214
  );
167
215
  const source = state.sourceTitles.find((el: IDataSource) => el.id === item.structuredData);
168
- const disabled = (hasMaxItems && !isChecked) || !!hasVersionInPageLanguage;
216
+ const disabled = (hasMaxItems && !isChecked) || !!hasVersionInPageLanguage || hasContentFromOtherSite;
169
217
  return (
170
- <>{source && <Item
171
- key={`${item.content.title}-${item.id}`}
172
- isChecked={isChecked || !!isSelectedOtherLanguage}
173
- handleOnClick={handleOnClick}
174
- item={item}
175
- source={source}
176
- disabled={disabled}
177
- tooltip={hasVersionInPageLanguage ? "Content has version in page language" : ""}
178
- />}</>
218
+ <React.Fragment key={`${item.content.title}-${item.id}`}>
219
+ {source && (
220
+ <Item
221
+ isChecked={isChecked || !!isSelectedOtherLanguage}
222
+ handleOnClick={handleOnClick}
223
+ item={item}
224
+ source={source}
225
+ disabled={disabled}
226
+ tooltip={hasVersionInPageLanguage ? "Content has version in page language" : ""}
227
+ />
228
+ )}
229
+ </React.Fragment>
179
230
  );
180
231
  })}
181
232
  </S.ItemList>
@@ -199,14 +250,18 @@ interface IProps {
199
250
  handleValidation?: (value: string, validators?: Record<string, unknown>) => void;
200
251
  validators?: Record<string, unknown>;
201
252
  lang: { locale: string; id: number };
202
- siteLangs: ILanguage[];
203
253
  globalLangs: ILanguage[];
204
254
  }
205
255
 
256
+ interface IFormState {
257
+ source: string | undefined;
258
+ lang: number;
259
+ site: number | null;
260
+ }
261
+
206
262
  const mapStateToProps = (state: IRootState) => ({
207
263
  lang: state.app.lang,
208
264
  currentSite: state.sites.currentSiteInfo && state.sites.currentSiteInfo.id,
209
- siteLangs: state.sites.currentSiteLanguages,
210
265
  globalLangs: state.app.globalLangs,
211
266
  });
212
267
 
@@ -2,6 +2,7 @@ import styled from "styled-components";
2
2
 
3
3
  const Wrapper = styled.div`
4
4
  height: 100%;
5
+ padding: ${(p) => p.theme.spacing.m};
5
6
  padding-bottom: ${(p) => p.theme.spacing.xl};
6
7
  display: flex;
7
8
  flex-flow: column nowrap;
@@ -38,6 +39,7 @@ const ButtonWrapper = styled.div`
38
39
  const ActionsWrapper = styled.div`
39
40
  text-align: right;
40
41
  padding-top: ${(p) => p.theme.spacing.s};
42
+ padding-bottom: ${(p) => p.theme.spacing.m};
41
43
  `;
42
44
 
43
45
  const SelectsWrapper = styled.div`
@@ -47,4 +49,30 @@ const SelectsWrapper = styled.div`
47
49
  }
48
50
  `;
49
51
 
50
- export { Wrapper, LoadingWrapper, ListWrapper, ItemList, SearchWrapper, ButtonWrapper, ActionsWrapper, SelectsWrapper };
52
+ const Note = styled.div`
53
+ ${(p) => p.theme.textStyle.uiXS};
54
+ margin-bottom: ${(p) => p.theme.spacing.xs};
55
+ background-color: ${(p) => p.theme.color.uiBackground03};
56
+ padding: ${(p) => p.theme.spacing.s};
57
+ border-radius: ${(p) => p.theme.radii.s};
58
+ color: ${(p) => p.theme.color.textMediumEmphasis};
59
+ `;
60
+
61
+ const Order = styled.div`
62
+ ${(p) => p.theme.textStyle.uiXS};
63
+ color: ${(p) => p.theme.color.textMediumEmphasis};
64
+ margin-bottom: ${(p) => p.theme.spacing.xs};
65
+ `;
66
+
67
+ export {
68
+ Wrapper,
69
+ LoadingWrapper,
70
+ ListWrapper,
71
+ ItemList,
72
+ SearchWrapper,
73
+ ButtonWrapper,
74
+ ActionsWrapper,
75
+ SelectsWrapper,
76
+ Note,
77
+ Order,
78
+ };
@@ -82,7 +82,7 @@ const ReferenceField = (props: IReferenceFieldProps) => {
82
82
  useEffect(() => {
83
83
  const getSourcesTitles = async () => {
84
84
  const response = await structuredData.getDataTitles(source);
85
- if (isReqOk(response.status)) {
85
+ if (isReqOk(response?.status)) {
86
86
  return response.data;
87
87
  } else {
88
88
  console.log("Error en getSourcesTitles");
@@ -138,13 +138,15 @@ const ReferenceField = (props: IReferenceFieldProps) => {
138
138
  alpha: "Alphabetical order",
139
139
  recent: "Most recent",
140
140
  };
141
+
141
142
  const getOrderLabel = () => {
142
143
  const stateOrder = splitCamelCase(state.order).toLowerCase();
143
144
  const orderLabel = defaultOrders[state.order] || capitalize(stateOrder);
144
145
  const directionLabel = state.orderDirection === "ASC" ? "(ascendent)" : "(descendent)";
145
146
  return `${orderLabel} ${directionLabel}`;
146
147
  };
147
- const autoData = (
148
+
149
+ const AutoData = () => (
148
150
  <S.DataWrapper data-testid="auto-data-wrapper">
149
151
  <S.SourcesWrapper>
150
152
  {value &&
@@ -171,7 +173,13 @@ const ReferenceField = (props: IReferenceFieldProps) => {
171
173
 
172
174
  const getPanel = () =>
173
175
  isAuto ? (
174
- <AutoPanel structuredData={structuredDataValues} categories={categories} onChange={handleOnChange} site={site} validators={validators} />
176
+ <AutoPanel
177
+ structuredData={structuredDataValues}
178
+ categories={categories}
179
+ onChange={handleOnChange}
180
+ site={site}
181
+ validators={validators}
182
+ />
175
183
  ) : (
176
184
  <ManualPanel
177
185
  onChange={handleOnChange}
@@ -183,7 +191,9 @@ const ReferenceField = (props: IReferenceFieldProps) => {
183
191
 
184
192
  const manualItems = !isAuto && value && Array.isArray(value.fixed) ? value.fixed.length : 0;
185
193
 
186
- const Asterisk = () => (mandatory ? <S.Asterisk>*</S.Asterisk> : null);
194
+ const Asterisk = () => (mandatory ? <S.Asterisk>*</S.Asterisk> : <></>);
195
+
196
+ const dataBlock = isAuto ? <AutoData /> : <ItemList items={value ? value.fixed : []} handleListDelete={handleListDelete} />;
187
197
 
188
198
  return (
189
199
  <S.Wrapper data-testid="reference-field-wrapper">
@@ -200,6 +210,7 @@ const ReferenceField = (props: IReferenceFieldProps) => {
200
210
  value={mode}
201
211
  type="inline"
202
212
  disabled={disabled}
213
+ mandatory={true}
203
214
  />
204
215
  )}
205
216
  {singleMode && !isAuto && value && <S.SingleModeText>{manualItems} items</S.SingleModeText>}
@@ -210,11 +221,7 @@ const ReferenceField = (props: IReferenceFieldProps) => {
210
221
  </S.ActionWrapper>
211
222
  )}
212
223
  </S.ModeWrapper>
213
- {isAuto ? (
214
- autoData
215
- ) : (
216
- <ItemList items={value ? value.fixed : []} handleListDelete={handleListDelete} handleChange={onChange} />
217
- )}
224
+ {dataBlock}
218
225
  <FloatingPanel title="Configure elements" toggleModal={toggleModal} isOpen={isOpen}>
219
226
  {isOpen && getPanel()}
220
227
  </FloatingPanel>
@@ -224,10 +231,10 @@ const ReferenceField = (props: IReferenceFieldProps) => {
224
231
 
225
232
  export interface IReferenceFieldProps {
226
233
  source: string[];
227
- value: any;
234
+ value?: any;
228
235
  onChange: (value: any) => void;
229
236
  disabled?: boolean;
230
- site: ISite;
237
+ site: ISite | null;
231
238
  selectionType?: string[];
232
239
  structuredDataValues: { global: IStructuredData[]; site: IStructuredData[] };
233
240
  categories: { global: IStructuredData[]; site: IStructuredData[] };