@griddo/ax 1.68.7 → 1.69.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/config/webpack.config.js +24 -0
  2. package/package.json +6 -2
  3. package/src/__mocks__/axios/ReferenceField.ts +471 -0
  4. package/src/{__tests__/components/Fields/UrlField → __mocks__}/mockedAxios.ts +0 -0
  5. package/src/__mocks__/reducers/structuredData.tsx +10 -0
  6. package/src/__mocks__/store/ReferenceField.ts +1671 -0
  7. package/src/__tests__/components/Fields/AnalyticsField/AnalyticsField.test.tsx +20 -28
  8. package/src/__tests__/components/Fields/CheckGroup/CheckGroup.test.tsx +16 -28
  9. package/src/__tests__/components/Fields/MultiCheckSelectGroup/MultiCheckSelectGroup.test.tsx +120 -0
  10. package/src/__tests__/components/Fields/ReferenceField/ReferenceField.test.tsx +532 -0
  11. package/src/__tests__/components/Fields/TextField/TextField.test.tsx +0 -1
  12. package/src/__tests__/components/Fields/UrlField/UrlField.test.tsx +14 -13
  13. package/src/__tests__/components/Fields/Wysiwyg/Wysiwyg.test.tsx +121 -0
  14. package/src/components/Fields/ComponentArray/MixableComponentArray/PasteModuleButton/index.tsx +4 -3
  15. package/src/components/Fields/ComponentArray/MixableComponentArray/index.tsx +69 -34
  16. package/src/components/Fields/ComponentArray/SameComponentArray/index.tsx +59 -26
  17. package/src/components/Fields/ComponentContainer/atoms.tsx +2 -8
  18. package/src/components/Fields/ComponentContainer/index.tsx +21 -21
  19. package/src/components/Fields/ComponentContainer/style.tsx +49 -28
  20. package/src/components/Fields/MultiCheckSelectGroup/index.tsx +2 -2
  21. package/src/components/Fields/MultiCheckSelectGroup/style.tsx +4 -4
  22. package/src/components/Fields/ReferenceField/AutoPanel/AutoItem/index.tsx +1 -1
  23. package/src/components/Fields/ReferenceField/AutoPanel/index.tsx +2 -4
  24. package/src/components/Fields/ReferenceField/AutoPanel/style.tsx +3 -0
  25. package/src/components/Fields/ReferenceField/Context/index.tsx +3 -3
  26. package/src/components/Fields/ReferenceField/ItemList/Item/index.tsx +15 -24
  27. package/src/components/Fields/ReferenceField/ItemList/Item/style.tsx +22 -15
  28. package/src/components/Fields/ReferenceField/ItemList/index.tsx +42 -11
  29. package/src/components/Fields/ReferenceField/ManualPanel/Item/index.tsx +1 -1
  30. package/src/components/Fields/ReferenceField/index.tsx +5 -6
  31. package/src/components/Fields/Wysiwyg/index.tsx +4 -4
  32. package/src/components/Gallery/GalleryPanel/DetailPanel/index.tsx +12 -4
  33. package/src/components/Gallery/GalleryPanel/index.tsx +10 -2
  34. package/src/components/Gallery/index.tsx +5 -1
  35. package/src/components/MainWrapper/AppBar/index.tsx +1 -1
  36. package/src/containers/App/reducer.tsx +1 -0
  37. package/src/containers/Gallery/actions.tsx +11 -5
  38. package/src/containers/Navigation/Defaults/actions.tsx +2 -2
  39. package/src/containers/PageEditor/actions.tsx +18 -7
  40. package/src/forms/elements.tsx +5 -6
  41. package/src/helpers/arrays.tsx +1 -2
  42. package/src/modules/Content/PageItem/index.tsx +13 -2
  43. package/src/modules/Content/index.tsx +18 -1
  44. package/src/modules/GlobalEditor/Editor/index.tsx +2 -2
  45. package/src/modules/GlobalEditor/index.tsx +9 -7
  46. package/src/modules/Navigation/Defaults/DefaultsEditor/Editor/index.tsx +1 -1
  47. package/src/modules/PageEditor/Editor/index.tsx +2 -2
  48. package/src/modules/PageEditor/index.tsx +8 -6
  49. package/src/modules/StructuredData/Form/index.tsx +7 -4
  50. package/src/modules/StructuredData/StructuredDataList/GlobalPageItem/index.tsx +25 -3
  51. package/src/modules/StructuredData/StructuredDataList/index.tsx +4 -0
  52. package/src/__mocks__/reducers/analyticsState.tsx +0 -14
  53. package/src/__mocks__/reducers/app.tsx +0 -10
  54. package/src/__mocks__/reducers/pageEditor.tsx +0 -30
  55. package/src/__mocks__/reducers/sites.tsx +0 -10
@@ -5,13 +5,13 @@ import { Tooltip, IconAction, Toast } from "@ax/components";
5
5
  import { INotification } from "@ax/types";
6
6
 
7
7
  const PasteModuleButton = (props: IProps): JSX.Element => {
8
- const { pasteModule, setNotification, setHistoryPush, editorID, isModuleCopyUnavailable } = props;
8
+ const { pasteModule, setNotification, setHistoryPush, editorID, isModuleCopyUnavailable, arrayKey } = props;
9
9
 
10
10
  const { isVisible, toggleToast, setIsVisible } = useToast();
11
11
 
12
12
  const handlePasteModule = async () => {
13
13
  if (!isModuleCopyUnavailable) {
14
- const pasteResult = await pasteModule(editorID);
14
+ const pasteResult = await pasteModule(editorID, arrayKey);
15
15
  if (pasteResult.error) {
16
16
  const { type, text } = pasteResult.error;
17
17
  setNotification && setNotification({ type, text });
@@ -40,11 +40,12 @@ const PasteModuleButton = (props: IProps): JSX.Element => {
40
40
  };
41
41
 
42
42
  interface IProps {
43
- pasteModule: (editorID: number) => Promise<{ error?: INotification }>;
43
+ pasteModule: (editorID: number, key: string) => Promise<{ error?: INotification }>;
44
44
  setNotification?: (notification: INotification) => void;
45
45
  setHistoryPush?: (path: string, isEditor: boolean) => void;
46
46
  editorID: number;
47
47
  isModuleCopyUnavailable: boolean;
48
+ arrayKey: string;
48
49
  }
49
50
 
50
51
  export default memo(PasteModuleButton);
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import differenceInSeconds from "date-fns/differenceInSeconds";
3
+ import { DragDropContext, Droppable, Draggable, DropResult } from "react-beautiful-dnd";
3
4
 
4
5
  import { IModule } from "@ax/types";
5
6
  import { ComponentContainer, SideModal } from "@ax/components";
@@ -95,7 +96,7 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
95
96
 
96
97
  const showPasteModuleButton =
97
98
  showAddItemButton &&
98
- isModuleArr &&
99
+ (isModuleArr || objKey === "componentModules") &&
99
100
  !!moduleCopy &&
100
101
  timeSinceModuleCopy < eightHoursInSeconds &&
101
102
  (whiteList.includes(moduleCopyComponent) || isModuleCopyUnavailable);
@@ -106,6 +107,60 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
106
107
 
107
108
  const Asterisk = () => (mandatory ? <S.Asterisk>*</S.Asterisk> : null);
108
109
 
110
+ const ComponentList = React.memo(function ComponentList({ components }: any) {
111
+ return components.map((element: any, i: number) => {
112
+ const { editorID } = element;
113
+ const { moduleTitle, isModuleDeactivated, componentTitle, displayName, isModule } = getComponentProps(
114
+ element,
115
+ activatedModules,
116
+ isModuleArr
117
+ );
118
+ const text = getText(componentTitle || displayName, i);
119
+ return (
120
+ <Draggable draggableId={`${editorID}`} index={i} key={editorID}>
121
+ {(provided) => (
122
+ <ComponentContainer
123
+ actionReplace={toggleModal}
124
+ canReplace={canReplace}
125
+ isArray={true}
126
+ key={editorID}
127
+ editorID={editorID}
128
+ goTo={goTo}
129
+ text={text}
130
+ moduleTitle={moduleTitle}
131
+ whiteList={whiteList}
132
+ categories={categories}
133
+ actions={actions}
134
+ selectedContent={selectedContent}
135
+ disabled={disabled}
136
+ canDuplicate={showAddItemButton && !isModuleDeactivated}
137
+ parentKey={objKey}
138
+ theme={theme}
139
+ arrayLength={components.length}
140
+ innerRef={provided.innerRef}
141
+ provided={provided}
142
+ isModule={isModule}
143
+ />
144
+ )}
145
+ </Draggable>
146
+ );
147
+ });
148
+ });
149
+
150
+ const onDragEnd = (result: DropResult) => {
151
+ const { moveModuleAction } = actions;
152
+
153
+ if (!result.destination) {
154
+ return;
155
+ }
156
+
157
+ if (result.destination.index === result.source.index) {
158
+ return;
159
+ }
160
+
161
+ moveModuleAction(parseInt(result.draggableId), selectedContent, result.destination.index, objKey);
162
+ };
163
+
109
164
  return (
110
165
  <S.Wrapper>
111
166
  <S.Title>
@@ -121,6 +176,7 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
121
176
  pasteModule={actions.pasteModuleAction}
122
177
  setNotification={actions.setNotificationAction}
123
178
  setHistoryPush={setHistoryPush}
179
+ arrayKey={objKey}
124
180
  />
125
181
  )}
126
182
  {showAddItemButton && !disabled && (
@@ -136,39 +192,18 @@ const MixableComponentArray = (props: IMixableComponentArrayProps): JSX.Element
136
192
  )}
137
193
  </S.ActionsWrapper>
138
194
  </S.ItemRow>
139
- {fixedValue &&
140
- fixedValue.map((element: any, i: number) => {
141
- const { editorID } = element;
142
- const { moduleTitle, isModuleDeactivated, componentTitle, displayName, isModule } = getComponentProps(
143
- element,
144
- activatedModules,
145
- isModuleArr
146
- );
147
- const text = getText(componentTitle || displayName, i);
148
- return (
149
- <ComponentContainer
150
- actionReplace={toggleModal}
151
- canReplace={canReplace}
152
- isArray={true}
153
- arrayLength={fixedValue.length}
154
- index={i}
155
- key={editorID}
156
- editorID={editorID}
157
- goTo={goTo}
158
- text={text}
159
- moduleTitle={moduleTitle}
160
- whiteList={whiteList}
161
- categories={categories}
162
- actions={actions}
163
- selectedContent={selectedContent}
164
- disabled={disabled}
165
- canDuplicate={showAddItemButton && !isModuleDeactivated}
166
- parentKey={objKey}
167
- theme={theme}
168
- isModule={isModule}
169
- />
170
- );
171
- })}
195
+ {fixedValue && (
196
+ <DragDropContext onDragEnd={onDragEnd}>
197
+ <Droppable droppableId="list">
198
+ {(provided) => (
199
+ <div ref={provided.innerRef} {...provided.droppableProps}>
200
+ <ComponentList components={fixedValue} />
201
+ {provided.placeholder}
202
+ </div>
203
+ )}
204
+ </Droppable>
205
+ </DragDropContext>
206
+ )}
172
207
  {displayReplaceSideModal && isOpen && (
173
208
  <SideModal
174
209
  optionsType={optionsType}
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import { DragDropContext, Droppable, Draggable, DropResult } from "react-beautiful-dnd";
2
3
 
3
4
  import { IModule } from "@ax/types";
4
5
  import { ComponentContainer } from "@ax/components";
@@ -57,32 +58,34 @@ const SameComponentArray = (props: ISameComponentArrayProps): JSX.Element => {
57
58
 
58
59
  const Asterisk = () => (mandatory ? <S.Asterisk>*</S.Asterisk> : null);
59
60
 
60
- return (
61
- <S.Wrapper data-testid="sameComponentWrapper">
62
- <S.Title>
63
- {title} <Asterisk />
64
- </S.Title>
65
- <S.ItemRow>
66
- <S.Subtitle>{value && value.length} items</S.Subtitle>
67
- {showAddItemButton && !disabled && (
68
- <AddItemButton handleClick={handleAdd} tooltipText={isModuleArr ? "Add module" : "Add component"} />
69
- )}
70
- </S.ItemRow>
71
- {value &&
72
- Array.isArray(value) &&
73
- value.map((element: any, i: number) => {
74
- const { editorID } = element;
75
- const { moduleTitle, isModuleDeactivated, componentTitle, displayName, isModule } = getComponentProps(
76
- element,
77
- activatedModules,
78
- isModuleArr
79
- );
80
- const text = getText(componentTitle || displayName, i);
81
- return (
61
+ const onDragEnd = (result: DropResult) => {
62
+ const { moveModuleAction } = actions;
63
+
64
+ if (!result.destination) {
65
+ return;
66
+ }
67
+
68
+ if (result.destination.index === result.source.index) {
69
+ return;
70
+ }
71
+
72
+ moveModuleAction(parseInt(result.draggableId), selectedContent, result.destination.index, objKey);
73
+ };
74
+
75
+ const ComponentList = React.memo(function ComponentList({ components }: any) {
76
+ return components.map((element: any, i: number) => {
77
+ const { editorID } = element;
78
+ const { moduleTitle, isModuleDeactivated, componentTitle, displayName, isModule } = getComponentProps(
79
+ element,
80
+ activatedModules,
81
+ isModuleArr
82
+ );
83
+ const text = getText(componentTitle || displayName, i);
84
+ return (
85
+ <Draggable draggableId={`${editorID}`} index={i} key={editorID}>
86
+ {(provided) => (
82
87
  <ComponentContainer
83
88
  isArray={true}
84
- arrayLength={value.length}
85
- index={i}
86
89
  key={editorID}
87
90
  editorID={editorID}
88
91
  goTo={goTo}
@@ -96,10 +99,40 @@ const SameComponentArray = (props: ISameComponentArrayProps): JSX.Element => {
96
99
  canDuplicate={showAddItemButton && !isModuleDeactivated}
97
100
  parentKey={objKey}
98
101
  theme={theme}
102
+ arrayLength={components.length}
103
+ innerRef={provided.innerRef}
104
+ provided={provided}
99
105
  isModule={isModule}
100
106
  />
101
- );
102
- })}
107
+ )}
108
+ </Draggable>
109
+ );
110
+ });
111
+ });
112
+
113
+ return (
114
+ <S.Wrapper data-testid="sameComponentWrapper">
115
+ <S.Title>
116
+ {title} <Asterisk />
117
+ </S.Title>
118
+ <S.ItemRow>
119
+ <S.Subtitle>{value && value.length} items</S.Subtitle>
120
+ {showAddItemButton && !disabled && (
121
+ <AddItemButton handleClick={handleAdd} tooltipText={isModuleArr ? "Add module" : "Add component"} />
122
+ )}
123
+ </S.ItemRow>
124
+ {value && Array.isArray(value) && (
125
+ <DragDropContext onDragEnd={onDragEnd}>
126
+ <Droppable droppableId="list">
127
+ {(provided) => (
128
+ <div ref={provided.innerRef} {...provided.droppableProps}>
129
+ <ComponentList components={value} />
130
+ {provided.placeholder}
131
+ </div>
132
+ )}
133
+ </Droppable>
134
+ </DragDropContext>
135
+ )}
103
136
  </S.Wrapper>
104
137
  );
105
138
  };
@@ -1,19 +1,13 @@
1
1
  import React from "react";
2
2
 
3
- import { ActionMenu, ReorderArrows } from "@ax/components";
3
+ import { ActionMenu } from "@ax/components";
4
4
 
5
5
  import * as S from "./style";
6
6
 
7
7
  const ArrayContainerButtons = (props: any) => {
8
- const { handleDownClick, handleUpClick, listLength, index, options, icon } = props;
8
+ const { options, icon } = props;
9
9
  return (
10
10
  <S.ButtonsWrapper>
11
- <ReorderArrows
12
- handleDownClick={handleDownClick}
13
- handleUpClick={handleUpClick}
14
- listLength={listLength}
15
- index={index}
16
- />
17
11
  <ActionMenu options={options} icon={icon} />
18
12
  </S.ButtonsWrapper>
19
13
  );
@@ -1,4 +1,5 @@
1
1
  import React from "react";
2
+ import { DraggableProvided } from "react-beautiful-dnd";
2
3
 
3
4
  import { useModal, useToast } from "@ax/hooks";
4
5
  import { isEmptyContainer, getDisplayName, trimText } from "@ax/helpers";
@@ -22,27 +23,26 @@ const ComponentContainer = (props: IComponentContainerProps): JSX.Element => {
22
23
  actions,
23
24
  title,
24
25
  categories,
25
- index,
26
- arrayLength,
27
26
  disabled,
28
27
  canDuplicate,
29
28
  parentKey,
30
29
  theme,
31
30
  canReplace,
32
31
  actionReplace,
32
+ arrayLength,
33
+ innerRef,
34
+ provided,
33
35
  isModule,
34
36
  } = props;
35
37
 
36
38
  const { isVisible, toggleToast, setIsVisible } = useToast();
37
39
 
38
40
  let deleteModuleAction: any;
39
- let moveModuleAction: any;
40
41
  let duplicateModuleAction: any;
41
42
  let copyModuleAction: any;
42
43
 
43
44
  if (actions) {
44
45
  deleteModuleAction = actions.deleteModuleAction;
45
- moveModuleAction = actions.moveModuleAction;
46
46
  duplicateModuleAction = actions.duplicateModuleAction;
47
47
  copyModuleAction = actions.copyModuleAction;
48
48
  }
@@ -124,26 +124,12 @@ const ComponentContainer = (props: IComponentContainerProps): JSX.Element => {
124
124
 
125
125
  const actionMenuIcon = "more";
126
126
 
127
- const handleUpClick = (e: any) => moveModule(e, false);
128
-
129
- const handleDownClick = (e: any) => moveModule(e, true);
130
-
131
- const moveModule = (e: any, isPush: boolean) => {
132
- e.preventDefault();
133
- e.stopPropagation();
134
- moveModuleAction(editorID, selectedContent, isPush, parentKey);
135
- };
136
-
137
127
  const handleOptionClick = (option: any) => actions.addComponentAction(option);
138
128
 
139
129
  const compoundKey = parentKey ? `${parentKey}.${objKey}` : objKey;
140
130
  const handleReplace = (option: any) => actions.replaceModuleAction(option, selectedContent, compoundKey);
141
131
 
142
132
  const arrayContainerButtonsProps = {
143
- handleDownClick,
144
- handleUpClick,
145
- listLength: arrayLength,
146
- index,
147
133
  options: actionArrayMenuOptions,
148
134
  icon: actionMenuIcon,
149
135
  };
@@ -161,7 +147,20 @@ const ComponentContainer = (props: IComponentContainerProps): JSX.Element => {
161
147
  />
162
148
  ) : (
163
149
  <>
164
- <S.Component isArray={isArray} onClick={handleClick} disabled={disabled} className={`editorId-${editorID}`}>
150
+ <S.Component
151
+ disabled={disabled}
152
+ className={`editorId-${editorID}`}
153
+ onClick={handleClick}
154
+ ref={innerRef}
155
+ {...provided?.draggableProps}
156
+ >
157
+ {isArray && provided && arrayLength > 1 && (
158
+ <S.HandleWrapper {...provided?.dragHandleProps}>
159
+ <S.IconHandleWrapper>
160
+ <Icon name="drag" size="16" />
161
+ </S.IconHandleWrapper>
162
+ </S.HandleWrapper>
163
+ )}
165
164
  {containerInfo && !disabled && (
166
165
  <S.IconWrapper>
167
166
  <Icon name={containerText} />
@@ -209,14 +208,15 @@ interface IComponentContainerProps {
209
208
  selectedContent?: any;
210
209
  objKey?: string;
211
210
  actions: any;
212
- index: number;
213
- arrayLength: number;
214
211
  disabled?: boolean;
215
212
  canDuplicate?: boolean;
216
213
  parentKey?: string;
217
214
  theme: string;
218
215
  canReplace?: boolean;
219
216
  actionReplace?: () => void;
217
+ arrayLength: number;
218
+ innerRef?: any;
219
+ provided?: DraggableProvided;
220
220
  isModule?: boolean;
221
221
  }
222
222
 
@@ -1,14 +1,14 @@
1
1
  import styled from "styled-components";
2
2
 
3
3
  const IconWrapper = styled.div`
4
- background-color: ${p => p.theme.color.uiBackground03};
4
+ background-color: ${(p) => p.theme.color.uiBackground03};
5
5
  border-radius: 4px;
6
- height: calc(${p => p.theme.spacing.s} * 2);
7
- width: calc(${p => p.theme.spacing.s} * 2);
6
+ height: calc(${(p) => p.theme.spacing.s} * 2);
7
+ width: calc(${(p) => p.theme.spacing.s} * 2);
8
8
  display: flex;
9
9
  justify-content: center;
10
10
  align-items: center;
11
- margin-right: ${p => p.theme.spacing.xs};
11
+ margin-right: ${(p) => p.theme.spacing.xs};
12
12
  `;
13
13
 
14
14
  const HiddenButtonsWrapper = styled.span`
@@ -17,32 +17,31 @@ const HiddenButtonsWrapper = styled.span`
17
17
  opacity: 0;
18
18
  `;
19
19
 
20
- const Component = styled.span<{ isArray: boolean | undefined; disabled?: boolean }>`
21
- color: ${p => p.theme.color.textHighEmphasis};
20
+ const Component = styled.span<{ disabled?: boolean }>`
21
+ color: ${(p) => p.theme.color.textHighEmphasis};
22
22
  position: relative;
23
23
  display: flex;
24
- align-items: center;
25
- justify-content: ${p => p.isArray ? "space-between" : "initial"};
24
+ align-items: stretch;
26
25
  width: 100%;
27
- background: ${p => p.theme.color.uiBackground02};
26
+ background: ${(p) => p.theme.color.uiBackground02};
28
27
  border: 1px solid transparent;
29
- margin-bottom: ${p => p.theme.spacing.xs};
30
- padding: calc(${p => p.theme.spacing.xs} - 1px) ${p => p.theme.spacing.xs};
31
- border-radius: ${p => p.theme.radii.s};
32
- box-shadow: ${p => p.theme.shadow.shadowS};
33
- ${p => p.theme.textStyle.fieldLabel};
28
+ margin-bottom: ${(p) => p.theme.spacing.xs};
29
+ padding: calc(${(p) => p.theme.spacing.xs} - 1px) ${(p) => p.theme.spacing.xs};
30
+ border-radius: ${(p) => p.theme.radii.s};
31
+ box-shadow: ${(p) => p.theme.shadow.shadowS};
32
+ ${(p) => p.theme.textStyle.fieldLabel};
34
33
  text-align: left;
35
- cursor: ${p => p.disabled ? `default` : `pointer`};
34
+ cursor: ${(p) => (p.disabled ? `default` : `pointer`)};
36
35
 
37
- &:hover ${HiddenButtonsWrapper}{
36
+ &:hover ${HiddenButtonsWrapper} {
38
37
  display: flex;
39
38
  opacity: 1;
40
39
  }
41
40
 
42
41
  &:focus,
43
42
  &:active {
44
- background: ${p => p.disabled ? p.theme.color.uiBackground02 : p.theme.color.overlayFocusPrimary};
45
- border: 1px solid ${p => p.disabled ? `transparent` : p.theme.color.interactive01};
43
+ background: ${(p) => (p.disabled ? p.theme.color.uiBackground02 : p.theme.color.overlayFocusPrimary)};
44
+ border: 1px solid ${(p) => (p.disabled ? `transparent` : p.theme.color.interactive01)};
46
45
  outline: none;
47
46
  }
48
47
  `;
@@ -50,27 +49,47 @@ const Component = styled.span<{ isArray: boolean | undefined; disabled?: boolean
50
49
  const Text = styled.div`
51
50
  display: flex;
52
51
  flex-direction: column;
53
- margin-left: ${p => p.theme.spacing.xs};
52
+ margin-left: ${(p) => p.theme.spacing.xs};
53
+ justify-content: center;
54
54
  `;
55
55
 
56
- const Label = styled.span<{containerInfo: boolean | undefined; disabled?: boolean}>`
57
- margin: ${p => p.theme.spacing.xxs } 0;
58
- ${p => p.containerInfo ? p.theme.textStyle.headingXS : null };
59
- color: ${p => p.disabled ? p.theme.color.interactiveDisabled : p.containerInfo ? p.theme.color.textMediumEmphasis : p.theme.color.textHighEmphasis};
56
+ const Label = styled.span<{ containerInfo: boolean | undefined; disabled?: boolean }>`
57
+ margin: ${(p) => p.theme.spacing.xxs} 0;
58
+ ${(p) => (p.containerInfo ? p.theme.textStyle.headingXS : null)};
59
+ color: ${(p) =>
60
+ p.disabled
61
+ ? p.theme.color.interactiveDisabled
62
+ : p.containerInfo
63
+ ? p.theme.color.textMediumEmphasis
64
+ : p.theme.color.textHighEmphasis};
60
65
  `;
61
66
 
62
- const Title = styled.span<{disabled?: boolean}>`
63
- ${p => p.theme.textStyle.uiXS };
64
- color: ${p => p.disabled ? p.theme.color.interactiveDisabled : p.theme.color.textMediumEmphasis};
65
- margin-bottom: ${p => p.theme.spacing.xxs};
67
+ const Title = styled.span<{ disabled?: boolean }>`
68
+ ${(p) => p.theme.textStyle.uiXS};
69
+ color: ${(p) => (p.disabled ? p.theme.color.interactiveDisabled : p.theme.color.textMediumEmphasis)};
70
+ margin-bottom: ${(p) => p.theme.spacing.xxs};
66
71
  `;
67
72
 
68
73
  const ButtonsWrapper = styled.span`
69
74
  display: flex;
70
75
  align-items: center;
76
+ margin-left: auto;
71
77
  `;
72
78
 
79
+ const HandleWrapper = styled.div`
80
+ display: flex;
81
+ align-items: center;
82
+ `;
73
83
 
84
+ const IconHandleWrapper = styled.div`
85
+ width: ${(p) => p.theme.spacing.s};
86
+ height: ${(p) => p.theme.spacing.s};
87
+ svg {
88
+ path {
89
+ fill: ${(p) => p.theme.color.textLowEmphasis};
90
+ }
91
+ }
92
+ `;
74
93
 
75
94
  export {
76
95
  IconWrapper,
@@ -79,5 +98,7 @@ export {
79
98
  Label,
80
99
  Title,
81
100
  ButtonsWrapper,
82
- HiddenButtonsWrapper
101
+ HiddenButtonsWrapper,
102
+ HandleWrapper,
103
+ IconHandleWrapper,
83
104
  };
@@ -4,7 +4,7 @@ import { ISite } from "@ax/types";
4
4
 
5
5
  import * as S from "./style";
6
6
 
7
- const MultiCheckSelectGroup = (props: IProps) => {
7
+ const MultiCheckSelectGroup = (props: IMultiCheckSelectGroupProps) => {
8
8
  const { value, onChange, site, elements, note } = props;
9
9
 
10
10
  return (
@@ -38,7 +38,7 @@ const MultiCheckSelectGroup = (props: IProps) => {
38
38
  );
39
39
  };
40
40
 
41
- interface IProps {
41
+ export interface IMultiCheckSelectGroupProps {
42
42
  value: any;
43
43
  elements: any[];
44
44
  onChange: (value: string | string[]) => void;
@@ -1,14 +1,14 @@
1
+ import React from "react";
1
2
  import styled from "styled-components";
2
3
  import MultiCheckSelect from "../MultiCheckSelect";
3
4
  import NoteField from "../NoteField";
4
5
 
5
-
6
- const StyledMultiCheckSelect = styled(MultiCheckSelect)`
7
- margin-bottom: ${p => p.theme.spacing.xs};
6
+ const StyledMultiCheckSelect = styled((props) => <MultiCheckSelect {...props} />)`
7
+ margin-bottom: ${(p) => p.theme.spacing.xs};
8
8
  `;
9
9
 
10
10
  const StyledNoteField = styled(NoteField)`
11
- margin-bottom: ${p => p.theme.spacing.xs};
11
+ margin-bottom: ${(p) => p.theme.spacing.xs};
12
12
  `;
13
13
 
14
14
  export { StyledMultiCheckSelect, StyledNoteField };
@@ -32,7 +32,7 @@ const AutoItem = (props: IProps) => {
32
32
  const actionMenuItem = (item: any, source: string) => {
33
33
  const handleClick = () => item.action(source);
34
34
  return (
35
- <S.ActionItem key={item.icon} onClick={handleClick}>
35
+ <S.ActionItem key={item.icon} onClick={handleClick} data-testid="auto-item-action-item">
36
36
  <Icon name={item.icon} />
37
37
  <S.ActionText>{item.label}</S.ActionText>
38
38
  </S.ActionItem>
@@ -135,9 +135,7 @@ const AutoPanel = (props: IProps): JSX.Element => {
135
135
 
136
136
  const addSource =
137
137
  state.sourceTitles.length > 1 ? (
138
- <FloatingMenu Button={addSourceButton}>
139
- {sourceMenu(state.sourceTitles)}
140
- </FloatingMenu>
138
+ <FloatingMenu Button={addSourceButton}>{sourceMenu(state.sourceTitles)}</FloatingMenu>
141
139
  ) : null;
142
140
 
143
141
  const removeItem = (item: string) => {
@@ -172,7 +170,7 @@ const AutoPanel = (props: IProps): JSX.Element => {
172
170
  };
173
171
 
174
172
  return (
175
- <S.Wrapper>
173
+ <S.Wrapper data-testid="auto-panel-wrapper">
176
174
  <S.FormWrapper>
177
175
  <S.DataLabel>Data source</S.DataLabel>
178
176
  <S.SourcesWrapper>
@@ -47,6 +47,9 @@ const SelectWrapper = styled.div`
47
47
  position: absolute;
48
48
  right: 0;
49
49
  margin-top: ${(p) => `-${p.theme.spacing.xs}`};
50
+ div {
51
+ right: 0;
52
+ }
50
53
  `;
51
54
 
52
55
  const ActionsWrapper = styled.div`
@@ -47,12 +47,12 @@ const useReferenceProvider = (modes?: string[]) => {
47
47
  [setState, state]
48
48
  );
49
49
 
50
- const setReorderElements = (item: IStructuredDataContent, isPush: boolean) => {
50
+ const setReorderElements = (item: IStructuredDataContent, newIndex: number) => {
51
51
  const { selectedItems, fixed, fullRelations = false } = state;
52
- const newItems = moveElement(item.id, selectedItems, isPush, "id");
52
+ const newItems = moveElement(item.id, selectedItems, newIndex, "id");
53
53
  const originalItemId = item.relatedPage?.originalStructuredDataId;
54
54
  const itemId = state.fixed.includes(originalItemId) ? originalItemId : item.id;
55
- const newFixed = moveArrayElement(itemId, fixed, isPush);
55
+ const newFixed = moveArrayElement(itemId, fixed, newIndex);
56
56
  const newState: IReferenceState = {
57
57
  ...state,
58
58
  selectedItems: newItems,