@griddo/ax 11.4.23 → 11.4.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/src/__tests__/components/Fields/ComponentContainer/ComponentContainer.test.tsx +10 -52
- package/src/components/ActionMenu/index.tsx +3 -2
- package/src/components/Fields/CheckField/style.tsx +16 -16
- package/src/components/Fields/ComponentArray/MixableComponentArray/index.tsx +65 -49
- package/src/components/Fields/ComponentArray/SameComponentArray/index.tsx +89 -69
- package/src/components/Fields/ComponentContainer/index.tsx +11 -11
- package/src/components/Fields/ComponentContainer/style.tsx +12 -4
- package/src/components/Fields/ReferenceField/ItemList/Item/index.tsx +19 -9
- package/src/components/Fields/ReferenceField/ItemList/Item/style.tsx +24 -13
- package/src/components/Fields/ReferenceField/ItemList/index.tsx +59 -41
- package/src/containers/StructuredData/actions.tsx +1 -1
- package/src/modules/Categories/CategoriesList/CategoryItem/index.tsx +71 -43
- package/src/modules/Categories/CategoriesList/CategoryItem/style.tsx +9 -1
- package/src/modules/Categories/CategoriesList/CategoryNav/index.tsx +0 -1
- package/src/modules/Categories/CategoriesList/CategoryPanel/index.tsx +1 -0
- package/src/modules/Categories/CategoriesList/helpers.tsx +135 -94
- package/src/modules/Categories/CategoriesList/index.tsx +153 -157
- package/src/modules/Categories/CategoriesList/style.tsx +0 -3
- package/src/modules/FileDrive/FolderTree/MenuItem/index.tsx +83 -0
- package/src/modules/FileDrive/FolderTree/MenuItem/style.tsx +69 -0
- package/src/modules/FileDrive/FolderTree/MenuList/index.tsx +26 -0
- package/src/modules/FileDrive/FolderTree/index.tsx +12 -58
- package/src/modules/FileDrive/FolderTree/style.tsx +6 -27
- package/src/modules/Forms/FormCategoriesList/CategoryItem/index.tsx +11 -17
- package/src/modules/Forms/FormCategoriesList/CategoryItem/style.tsx +4 -1
- package/src/modules/Forms/FormCategoriesList/index.tsx +68 -53
- package/src/modules/Navigation/Menus/List/Table/Item/index.tsx +45 -16
- package/src/modules/Navigation/Menus/List/Table/Item/style.tsx +8 -3
- package/src/modules/Navigation/Menus/List/Table/helpers.tsx +132 -74
- package/src/modules/Navigation/Menus/List/Table/index.tsx +119 -86
- package/src/modules/Settings/Integrations/IntegrationItem/index.tsx +11 -11
- package/src/modules/Settings/Integrations/IntegrationItem/style.tsx +9 -1
- package/src/modules/Settings/Integrations/index.tsx +59 -56
- package/src/types/index.tsx +4 -5
- package/src/modules/FileDrive/FolderTree/utils.tsx +0 -91
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
2
|
import { connect } from "react-redux";
|
|
3
|
+
import { AnimateLayoutChanges, useSortable } from "@dnd-kit/sortable";
|
|
3
4
|
|
|
4
5
|
import { structuredDataActions } from "@ax/containers/StructuredData";
|
|
5
6
|
import { useModal, usePermission } from "@ax/hooks";
|
|
@@ -25,11 +26,12 @@ const CategoryItem = (props: ICategoryItemProps): JSX.Element => {
|
|
|
25
26
|
toggleToast,
|
|
26
27
|
getContents,
|
|
27
28
|
currentSiteID,
|
|
28
|
-
dragHandleProps,
|
|
29
|
-
icon,
|
|
30
29
|
deleteCategoryGroup,
|
|
31
30
|
hoverCheck,
|
|
32
|
-
|
|
31
|
+
depth,
|
|
32
|
+
indentationWidth,
|
|
33
|
+
collapsed,
|
|
34
|
+
onCollapse,
|
|
33
35
|
} = props;
|
|
34
36
|
|
|
35
37
|
const { isOpen, toggleModal } = useModal();
|
|
@@ -49,6 +51,15 @@ const CategoryItem = (props: ICategoryItemProps): JSX.Element => {
|
|
|
49
51
|
const allowedToEditTaxonomy = currentSiteID ? allowedToEditSiteCategory : allowedToEditGlobalCategory;
|
|
50
52
|
const allowedToDeleteTaxonomy = currentSiteID ? allowedToDeleteSiteCategory : allowedToDeleteGlobalCategory;
|
|
51
53
|
|
|
54
|
+
const animateLayoutChanges: AnimateLayoutChanges = ({ isSorting, wasDragging }) =>
|
|
55
|
+
isSorting || wasDragging ? false : true;
|
|
56
|
+
|
|
57
|
+
const { attributes, isDragging, listeners, setDraggableNodeRef, setDroppableNodeRef, transform, transition } =
|
|
58
|
+
useSortable({
|
|
59
|
+
id: category.id,
|
|
60
|
+
animateLayoutChanges,
|
|
61
|
+
});
|
|
62
|
+
|
|
52
63
|
const { locale } = lang;
|
|
53
64
|
const { dataLanguages = [], content } = category;
|
|
54
65
|
const isGroup = category.type === "group";
|
|
@@ -189,40 +200,56 @@ const CategoryItem = (props: ICategoryItemProps): JSX.Element => {
|
|
|
189
200
|
|
|
190
201
|
return (
|
|
191
202
|
<>
|
|
192
|
-
<S.
|
|
193
|
-
<S.
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
<
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
203
|
+
<S.Wrapper identationWidth={isDragging ? indentationWidth : indentationWidth * depth} ref={setDroppableNodeRef}>
|
|
204
|
+
<S.CategoryRow
|
|
205
|
+
selected={isSelected}
|
|
206
|
+
onClick={handleClick}
|
|
207
|
+
ref={setDraggableNodeRef}
|
|
208
|
+
cssTransform={transform}
|
|
209
|
+
transition={transition}
|
|
210
|
+
{...listeners}
|
|
211
|
+
{...attributes}
|
|
212
|
+
>
|
|
213
|
+
<S.HandleCell>
|
|
214
|
+
<S.IconWrapperDrag role="cell">
|
|
215
|
+
<Icon name="drag" size="16" />
|
|
216
|
+
</S.IconWrapperDrag>
|
|
217
|
+
<S.IconWrapper onClick={handleCheckClick}>
|
|
218
|
+
{onCollapse && (
|
|
219
|
+
<div onClick={onCollapse} role="button" tabIndex={0} onKeyDown={onCollapse}>
|
|
220
|
+
{collapsed ? <Icon name="UpArrow" /> : <Icon name="DownArrow" />}
|
|
221
|
+
</div>
|
|
222
|
+
)}
|
|
223
|
+
</S.IconWrapper>
|
|
224
|
+
</S.HandleCell>
|
|
225
|
+
<S.CheckCell role="cell" onClick={handleCheckClick}>
|
|
226
|
+
<CheckField name="check" value={category.id} checked={isSelected || hoverCheck} onChange={handleOnChange} />
|
|
227
|
+
</S.CheckCell>
|
|
228
|
+
<S.NameCell role="cell" clickable={allowedToEditTaxonomy} isGroup={isGroup}>
|
|
229
|
+
{isGroup && (
|
|
230
|
+
<S.FolderWrapper>
|
|
231
|
+
<Icon name="project" size="24" />
|
|
232
|
+
</S.FolderWrapper>
|
|
233
|
+
)}
|
|
234
|
+
<div>{content?.title || ""}</div>
|
|
235
|
+
</S.NameCell>
|
|
236
|
+
<S.CodeCell role="cell" clickable={allowedToEditTaxonomy}>
|
|
237
|
+
{isCategory(category) && category.content ? category.content.code : ""}
|
|
238
|
+
</S.CodeCell>
|
|
239
|
+
<S.SelectableCell role="cell">
|
|
240
|
+
<Tag
|
|
241
|
+
type="square"
|
|
242
|
+
color={selectable ? "" : "#FFD4C7"}
|
|
243
|
+
text={selectable ? "Yes" : "No"}
|
|
244
|
+
textColor={selectable ? "" : "#20224C"}
|
|
245
|
+
/>
|
|
246
|
+
</S.SelectableCell>
|
|
247
|
+
<S.TransCell role="cell">{translations}</S.TransCell>
|
|
248
|
+
<S.ActionsCell role="cell">
|
|
249
|
+
<S.StyledActionMenu icon="more" options={menuOptions} tooltip="Actions" />
|
|
250
|
+
</S.ActionsCell>
|
|
251
|
+
</S.CategoryRow>
|
|
252
|
+
</S.Wrapper>
|
|
226
253
|
{isOpen && (
|
|
227
254
|
<CategoryPanel
|
|
228
255
|
isOpen={isOpen}
|
|
@@ -261,14 +288,15 @@ interface IProps {
|
|
|
261
288
|
lang: { locale: string; id: number | null };
|
|
262
289
|
isTranslatable: boolean;
|
|
263
290
|
isSelected: boolean;
|
|
264
|
-
onChange: (
|
|
265
|
-
toggleToast(state:
|
|
266
|
-
getContents(dataId: string)
|
|
291
|
+
onChange: (item: ICheck) => void;
|
|
292
|
+
toggleToast: (state: string) => void;
|
|
293
|
+
getContents: (dataId: string) => void;
|
|
267
294
|
currentSiteID: number | null;
|
|
268
|
-
icon: JSX.Element;
|
|
269
|
-
dragHandleProps?: any;
|
|
270
295
|
hoverCheck?: boolean;
|
|
271
|
-
|
|
296
|
+
depth: number;
|
|
297
|
+
indentationWidth: number;
|
|
298
|
+
collapsed: boolean;
|
|
299
|
+
onCollapse?: () => void;
|
|
272
300
|
}
|
|
273
301
|
|
|
274
302
|
interface IDispatchProps {
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
import styled from "styled-components";
|
|
2
|
+
import { CSS, Transform } from "@dnd-kit/utilities";
|
|
2
3
|
|
|
3
4
|
import { Cell, Row } from "@ax/components/TableList/TableItem/style";
|
|
4
5
|
import { ActionMenu } from "@ax/components";
|
|
5
6
|
|
|
7
|
+
const Wrapper = styled.div<{ identationWidth: number }>`
|
|
8
|
+
padding-left: ${(p) => `${p.identationWidth}px`};
|
|
9
|
+
`;
|
|
10
|
+
|
|
6
11
|
const CheckCell = styled(Cell)`
|
|
7
12
|
padding-left: 0;
|
|
8
13
|
padding-right: 0;
|
|
@@ -53,7 +58,9 @@ const StyledActionMenu = styled(ActionMenu)`
|
|
|
53
58
|
margin-left: auto;
|
|
54
59
|
`;
|
|
55
60
|
|
|
56
|
-
const CategoryRow = styled(Row)
|
|
61
|
+
const CategoryRow = styled(Row)<{ cssTransform: Transform | null; transition?: string }>`
|
|
62
|
+
transform: ${(p) => CSS.Transform.toString(p.cssTransform)};
|
|
63
|
+
transition: ${(p) => p.transition};
|
|
57
64
|
&:hover {
|
|
58
65
|
${StyledActionMenu} {
|
|
59
66
|
opacity: 1;
|
|
@@ -103,6 +110,7 @@ const FolderWrapper = styled.div`
|
|
|
103
110
|
`;
|
|
104
111
|
|
|
105
112
|
export {
|
|
113
|
+
Wrapper,
|
|
106
114
|
CheckCell,
|
|
107
115
|
NameCell,
|
|
108
116
|
ActionsCell,
|
|
@@ -1,116 +1,157 @@
|
|
|
1
|
-
import { ItemId, TreeData, TreeItem } from "@atlaskit/tree";
|
|
2
|
-
import { isEmptyObj } from "@ax/helpers";
|
|
3
1
|
import { ICategoryGroup, IStructuredDataCategory } from "@ax/types";
|
|
2
|
+
import type { UniqueIdentifier } from "@dnd-kit/core";
|
|
3
|
+
import { arrayMove } from "@dnd-kit/sortable";
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
id: "root",
|
|
11
|
-
children: [],
|
|
12
|
-
hasChildren: true,
|
|
13
|
-
isExpanded: true,
|
|
14
|
-
isChildrenLoading: false,
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const previousItems: (IStructuredDataCategory | ICategoryGroup)[] = [];
|
|
20
|
-
if (!isEmptyObj(tree.items)) {
|
|
21
|
-
previousItems.push(...formatTree(tree));
|
|
22
|
-
}
|
|
5
|
+
const flatten = (items: TreeItem[], parentId: UniqueIdentifier | null = null, depth = 0): FlattenedItem[] => {
|
|
6
|
+
return items.reduce<FlattenedItem[]>((acc, item, index) => {
|
|
7
|
+
return [...acc, { ...item, parentId, depth, index }, ...flatten(item.children || [], item.id, depth + 1)];
|
|
8
|
+
}, []);
|
|
9
|
+
};
|
|
23
10
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const getElement = (
|
|
30
|
-
item: IStructuredDataCategory | ICategoryGroup,
|
|
31
|
-
previousItems: IStructuredDataCategory | ICategoryGroup
|
|
32
|
-
) => {
|
|
33
|
-
normalized.items[item.id] = {
|
|
34
|
-
...item,
|
|
35
|
-
children: [],
|
|
36
|
-
isExpanded: isItemExpanded(previousItems),
|
|
37
|
-
};
|
|
38
|
-
if (item.children && item.children.length > 0) {
|
|
39
|
-
item.children.forEach((child: IStructuredDataCategory | ICategoryGroup, index: number) => {
|
|
40
|
-
normalized.items[item.id].children.push(child.id);
|
|
41
|
-
getElement(child, previousItems?.children[index]);
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
};
|
|
11
|
+
const flattenTree = (items: TreeItem[]): FlattenedItem[] => {
|
|
12
|
+
return flatten(items);
|
|
13
|
+
};
|
|
45
14
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
15
|
+
const buildTree = (flattenedItems: FlattenedItem[]): TreeItem[] => {
|
|
16
|
+
const root = { id: 0, children: [] };
|
|
17
|
+
const nodes: Record<string, Partial<TreeItem>> = { [root.id]: root };
|
|
18
|
+
const items = flattenedItems.map((item) => ({ ...item, children: [] })) as FlattenedItem[];
|
|
50
19
|
|
|
51
|
-
|
|
52
|
-
};
|
|
20
|
+
for (const item of items) {
|
|
21
|
+
const { id, children } = item;
|
|
22
|
+
const parentId = item.parentId ?? root.id;
|
|
23
|
+
const parent = nodes[parentId] ?? findItem(items, parentId);
|
|
53
24
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const elements: TreeItem[] = [];
|
|
57
|
-
for (const item of Object.values(items)) {
|
|
58
|
-
elements.push(item);
|
|
25
|
+
nodes[id] = { id, children };
|
|
26
|
+
parent.children && parent.children.push(item);
|
|
59
27
|
}
|
|
60
|
-
return elements;
|
|
61
|
-
};
|
|
62
28
|
|
|
63
|
-
|
|
64
|
-
const element = elements.find((element: IStructuredDataCategory | ICategoryGroup) => element.id === child);
|
|
65
|
-
const children = element?.children.map((child: ItemId) => getChild(child, elements));
|
|
66
|
-
return { ...element, children };
|
|
29
|
+
return root.children;
|
|
67
30
|
};
|
|
68
31
|
|
|
69
|
-
const
|
|
70
|
-
|
|
32
|
+
const findItem = (items: FlattenedItem[], itemId: UniqueIdentifier) => {
|
|
33
|
+
return items.find(({ id }) => id === itemId);
|
|
34
|
+
};
|
|
71
35
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
36
|
+
function getDragDepth(offset: number, indentationWidth: number) {
|
|
37
|
+
return Math.round(offset / indentationWidth);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function getProjection(
|
|
41
|
+
items: FlattenedItem[],
|
|
42
|
+
activeId: UniqueIdentifier,
|
|
43
|
+
overId: UniqueIdentifier,
|
|
44
|
+
dragOffset: number,
|
|
45
|
+
indentationWidth: number
|
|
46
|
+
) {
|
|
47
|
+
const overItemIndex = items.findIndex(({ id }) => id === overId);
|
|
48
|
+
const activeItemIndex = items.findIndex(({ id }) => id === activeId);
|
|
49
|
+
const activeItem = items[activeItemIndex];
|
|
50
|
+
const newItems = arrayMove(items, activeItemIndex, overItemIndex);
|
|
51
|
+
const previousItem = newItems[overItemIndex - 1];
|
|
52
|
+
const nextItem = newItems[overItemIndex + 1];
|
|
53
|
+
const dragDepth = getDragDepth(dragOffset, indentationWidth);
|
|
54
|
+
const projectedDepth = activeItem.depth + dragDepth;
|
|
55
|
+
const maxDepth = getMaxDepth({
|
|
56
|
+
previousItem,
|
|
75
57
|
});
|
|
58
|
+
const minDepth = getMinDepth({ nextItem });
|
|
59
|
+
let depth = projectedDepth;
|
|
76
60
|
|
|
77
|
-
|
|
78
|
-
|
|
61
|
+
if (projectedDepth >= maxDepth) {
|
|
62
|
+
depth = maxDepth;
|
|
63
|
+
} else if (projectedDepth < minDepth) {
|
|
64
|
+
depth = minDepth;
|
|
65
|
+
}
|
|
79
66
|
|
|
80
|
-
|
|
81
|
-
const elements = getElementsFromTree(tree);
|
|
67
|
+
return { depth, maxDepth, minDepth, parentId: getParentId() };
|
|
82
68
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
69
|
+
function getParentId() {
|
|
70
|
+
if (depth === 0 || !previousItem) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
87
73
|
|
|
88
|
-
|
|
89
|
-
|
|
74
|
+
if (depth === previousItem.depth) {
|
|
75
|
+
return previousItem.parentId;
|
|
76
|
+
}
|
|
90
77
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
};
|
|
78
|
+
if (depth > previousItem.depth) {
|
|
79
|
+
return previousItem.id;
|
|
80
|
+
}
|
|
95
81
|
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
82
|
+
const newParent = newItems
|
|
83
|
+
.slice(0, overItemIndex)
|
|
84
|
+
.reverse()
|
|
85
|
+
.find((item) => item.depth === depth)?.parentId;
|
|
86
|
+
|
|
87
|
+
return newParent ?? null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
104
90
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
91
|
+
function getMinDepth({ nextItem }: { nextItem: FlattenedItem }) {
|
|
92
|
+
if (nextItem) {
|
|
93
|
+
return nextItem.depth;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function getMaxDepth({ previousItem }: { previousItem: FlattenedItem }) {
|
|
100
|
+
if (previousItem) {
|
|
101
|
+
return previousItem.depth + 1;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const removeChildrenOf = (items: FlattenedItem[], ids: UniqueIdentifier[]) => {
|
|
108
|
+
const excludeParentIds = [...ids];
|
|
109
|
+
|
|
110
|
+
return items.filter((item) => {
|
|
111
|
+
if (item.parentId && excludeParentIds.includes(item.parentId)) {
|
|
112
|
+
if (item.children && item.children.length) {
|
|
113
|
+
excludeParentIds.push(item.id);
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
111
116
|
}
|
|
112
|
-
|
|
113
|
-
|
|
117
|
+
|
|
118
|
+
return true;
|
|
119
|
+
});
|
|
114
120
|
};
|
|
115
121
|
|
|
116
|
-
export
|
|
122
|
+
export function setProperty<T extends keyof TreeItem>(
|
|
123
|
+
items: TreeItem[],
|
|
124
|
+
id: UniqueIdentifier,
|
|
125
|
+
property: T,
|
|
126
|
+
setter: (value: TreeItem[T]) => TreeItem[T]
|
|
127
|
+
) {
|
|
128
|
+
for (const item of items) {
|
|
129
|
+
if (item.id === id) {
|
|
130
|
+
item[property] = setter(item[property]);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (item.children && item.children.length) {
|
|
135
|
+
item.children = setProperty(item.children || [], id, property, setter);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return [...items];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
interface FlattenedCategory extends IStructuredDataCategory {
|
|
143
|
+
parentId: UniqueIdentifier | null;
|
|
144
|
+
depth: number;
|
|
145
|
+
index: number;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
interface FlattenedGroup extends ICategoryGroup {
|
|
149
|
+
parentId: UniqueIdentifier | null;
|
|
150
|
+
depth: number;
|
|
151
|
+
index: number;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
type TreeItem = IStructuredDataCategory | ICategoryGroup;
|
|
155
|
+
export type FlattenedItem = FlattenedCategory | FlattenedGroup;
|
|
156
|
+
|
|
157
|
+
export { flattenTree, buildTree, removeChildrenOf };
|