pixel-react 1.10.5 → 1.10.7
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/lib/components/MenuOption/types.d.ts +1 -1
- package/lib/components/Select/components/types.d.ts +6 -1
- package/lib/components/Select/types.d.ts +17 -0
- package/lib/components/Table/Table.d.ts +1 -1
- package/lib/components/Table/Types.d.ts +1 -0
- package/lib/index.d.ts +20 -3
- package/lib/index.esm.js +245 -93
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +245 -93
- package/lib/index.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/utils/getAnchorElement/getAnchorElement.d.ts +1 -0
- package/lib/utils/getTreeDetails/getTreeDetails.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/MenuOption/MenuOption.scss +4 -0
- package/src/components/MenuOption/MenuOption.stories.tsx +2 -2
- package/src/components/MenuOption/MenuOption.tsx +72 -60
- package/src/components/MenuOption/types.ts +1 -1
- package/src/components/Select/Select.stories.tsx +43 -1
- package/src/components/Select/Select.tsx +16 -1
- package/src/components/Select/components/Dropdown.scss +41 -1
- package/src/components/Select/components/Dropdown.tsx +52 -6
- package/src/components/Select/components/types.ts +7 -2
- package/src/components/Select/types.ts +22 -0
- package/src/components/SequentialConnectingBranch/SequentialConnectingBranch.stories.tsx +8 -2
- package/src/components/SequentialConnectingBranch/components/Branches/Branches.tsx +1 -1
- package/src/components/SequentialConnectingBranch/components/DatasetTooltip/DataSetTooltip.scss +14 -0
- package/src/components/SequentialConnectingBranch/components/DatasetTooltip/DataSetTooltip.tsx +6 -11
- package/src/components/Table/Table.tsx +47 -0
- package/src/components/Table/Types.ts +4 -1
- package/src/components/TableTree/Components/TableBody.tsx +0 -1
- package/src/utils/getAnchorElement/getAnchorElement.ts +7 -0
- package/src/utils/getTreeDetails/getTreeDetails.stories.tsx +59 -9
- package/src/utils/getTreeDetails/getTreeDetails.ts +66 -13
@@ -6,12 +6,11 @@ import Typography from '../../Typography';
|
|
6
6
|
import { ffid } from '../../../utils/ffID/ffid';
|
7
7
|
import { ThemeContext } from '../../ThemeProvider/ThemeProvider';
|
8
8
|
import classNames from 'classnames';
|
9
|
-
import {
|
10
|
-
getLabel,
|
11
|
-
} from '../../../utils/getSelectOptionValue/getSelectOptionValue';
|
9
|
+
import { getLabel } from '../../../utils/getSelectOptionValue/getSelectOptionValue';
|
12
10
|
import useClickOutside from '../../../hooks/useClickOutside';
|
13
11
|
import Icon from '../../Icon';
|
14
12
|
import Tooltip from '../../Tooltip';
|
13
|
+
import Button from '../../Button';
|
15
14
|
|
16
15
|
const Dropdown: FC<DropdownProps> = ({
|
17
16
|
options = [],
|
@@ -27,12 +26,22 @@ const Dropdown: FC<DropdownProps> = ({
|
|
27
26
|
valueAccessor,
|
28
27
|
showIcon = false,
|
29
28
|
showToolTip = false,
|
29
|
+
customReccurenece = true,
|
30
|
+
onCancelModal = () => {},
|
31
|
+
onSaveModal = () => {},
|
32
|
+
recurrence = false,
|
33
|
+
modalJSXProps = <></>,
|
30
34
|
}) => {
|
31
35
|
const themeContext = useContext(ThemeContext);
|
32
36
|
const currentTheme = themeContext?.currentTheme;
|
33
37
|
|
38
|
+
const customRecurrenceOnBlur = customReccurenece ? () => {} : onSelectBlur;
|
39
|
+
|
34
40
|
const optionsWrapperRef = useRef<HTMLDivElement>(null);
|
35
|
-
useClickOutside(optionsWrapperRef,
|
41
|
+
useClickOutside(optionsWrapperRef, customRecurrenceOnBlur, [
|
42
|
+
inputRef,
|
43
|
+
selectArrowRef,
|
44
|
+
]);
|
36
45
|
|
37
46
|
const { positionX, positionY, fromBottom, width } = dropdownPosition;
|
38
47
|
const { margin, optionHeight, selectInputHeight, dropDownWrapperPadding } =
|
@@ -98,13 +107,30 @@ const Dropdown: FC<DropdownProps> = ({
|
|
98
107
|
);
|
99
108
|
};
|
100
109
|
|
110
|
+
const onHandleCancelModal = () => {
|
111
|
+
onSelectBlur();
|
112
|
+
onCancelModal();
|
113
|
+
};
|
114
|
+
|
115
|
+
const onHandleSaveModal = () => {
|
116
|
+
onSelectBlur();
|
117
|
+
onSaveModal();
|
118
|
+
};
|
119
|
+
|
101
120
|
return (
|
102
121
|
<div
|
103
|
-
className={classNames('ff-select-dropdown-wrapper', currentTheme
|
122
|
+
className={classNames('ff-select-dropdown-wrapper', currentTheme, {
|
123
|
+
'ff-select-dropdown-modal-wrapper': recurrence,
|
124
|
+
'ff-select-dropdown-mini-modal-wrapper': customReccurenece,
|
125
|
+
})}
|
104
126
|
ref={optionsWrapperRef}
|
105
127
|
style={updateDropdownPosition()}
|
106
128
|
>
|
107
|
-
<div
|
129
|
+
<div
|
130
|
+
className={classNames({
|
131
|
+
'ff-select-label-minimodal-wrapper': customReccurenece,
|
132
|
+
})}
|
133
|
+
>
|
108
134
|
{!checkEmpty(options) ? (
|
109
135
|
options.map((option) => (
|
110
136
|
<div
|
@@ -140,6 +166,26 @@ const Dropdown: FC<DropdownProps> = ({
|
|
140
166
|
</Typography>
|
141
167
|
)}
|
142
168
|
</div>
|
169
|
+
|
170
|
+
{customReccurenece && (
|
171
|
+
<div className="ff-select-mini-modal-wrapper" id="ff-select-mini-id">
|
172
|
+
<div className="ff-select-modal-wrapper">
|
173
|
+
{<>{modalJSXProps}</>}
|
174
|
+
<div className="ff-select-mini-modal-footer">
|
175
|
+
<Button
|
176
|
+
label="Cancel"
|
177
|
+
variant="tertiary"
|
178
|
+
onClick={onHandleCancelModal}
|
179
|
+
/>
|
180
|
+
<Button
|
181
|
+
label="Save"
|
182
|
+
variant="secondary"
|
183
|
+
onClick={onHandleSaveModal}
|
184
|
+
/>
|
185
|
+
</div>
|
186
|
+
</div>
|
187
|
+
</div>
|
188
|
+
)}
|
143
189
|
</div>
|
144
190
|
);
|
145
191
|
};
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { DropdownPosition, Option } from '../types';
|
2
|
-
import { RefObject } from 'react';
|
2
|
+
import { ReactNode, RefObject } from 'react';
|
3
3
|
|
4
4
|
export interface DropdownProps {
|
5
5
|
options: Option[];
|
@@ -14,7 +14,12 @@ export interface DropdownProps {
|
|
14
14
|
heightFromTop: number;
|
15
15
|
selectedOption?: Option;
|
16
16
|
showIcon?: boolean;
|
17
|
-
showToolTip?: boolean
|
17
|
+
showToolTip?: boolean;
|
18
|
+
customReccurenece?: boolean;
|
19
|
+
onCancelModal?: () => void;
|
20
|
+
onSaveModal?: () => void;
|
21
|
+
modalJSXProps?: ReactNode;
|
22
|
+
recurrence?: boolean;
|
18
23
|
}
|
19
24
|
|
20
25
|
export const dropdownDefaultCSSData = {
|
@@ -1,3 +1,5 @@
|
|
1
|
+
import { ReactNode } from 'react';
|
2
|
+
|
1
3
|
export interface SelectProps {
|
2
4
|
/*
|
3
5
|
* Label for the select dropdown
|
@@ -123,6 +125,26 @@ export interface SelectProps {
|
|
123
125
|
* Provide the background color for the select label on the hover state
|
124
126
|
*/
|
125
127
|
labelBackgroundColor?: string;
|
128
|
+
|
129
|
+
/**
|
130
|
+
* To close the modal in the select dropdown
|
131
|
+
*/
|
132
|
+
onCancelModal?: () => void;
|
133
|
+
|
134
|
+
/**
|
135
|
+
* To close the modal in the select dropdown
|
136
|
+
*/
|
137
|
+
onSaveModal?: () => void;
|
138
|
+
|
139
|
+
/**
|
140
|
+
* Pass the custom Jsx for the Modal
|
141
|
+
*/
|
142
|
+
modalJSXProps?: ReactNode;
|
143
|
+
|
144
|
+
/**
|
145
|
+
* Pass the recurrence boolean for the exeception cases
|
146
|
+
*/
|
147
|
+
recurrence?: boolean;
|
126
148
|
}
|
127
149
|
|
128
150
|
export interface DropdownPosition {
|
@@ -21,6 +21,7 @@ export const Primary: Story = {
|
|
21
21
|
label: 'ffe-Mahesh',
|
22
22
|
value: {
|
23
23
|
status: 'running',
|
24
|
+
clientId: 'test',
|
24
25
|
},
|
25
26
|
name: 'ffe-Mahesh',
|
26
27
|
});
|
@@ -33,6 +34,7 @@ export const Primary: Story = {
|
|
33
34
|
status: 'running',
|
34
35
|
},
|
35
36
|
name: 'ffe-Ganesh',
|
37
|
+
clientId: 'test',
|
36
38
|
},
|
37
39
|
{
|
38
40
|
label: 'ffe-Mahesh',
|
@@ -40,6 +42,7 @@ export const Primary: Story = {
|
|
40
42
|
status: 'running',
|
41
43
|
},
|
42
44
|
name: 'ffe-Mahesh',
|
45
|
+
clientId: 'test',
|
43
46
|
},
|
44
47
|
];
|
45
48
|
|
@@ -52,8 +55,10 @@ export const Primary: Story = {
|
|
52
55
|
return (
|
53
56
|
<>
|
54
57
|
<SequentialConnectingBranch
|
55
|
-
projectType="web"
|
56
58
|
dataSetValues={{
|
59
|
+
globalVariableSetName: 'test dev',
|
60
|
+
peVariableSetName: 'test dev',
|
61
|
+
testDataSetName: 'test dev',
|
57
62
|
peVariableSetId: 'Test dev',
|
58
63
|
globalVariableSetId: 'Test dev',
|
59
64
|
testDataSetId: 'Test dev',
|
@@ -64,7 +69,8 @@ export const Primary: Story = {
|
|
64
69
|
machineInstances={[]}
|
65
70
|
selectedMachine={machineSelect}
|
66
71
|
onHandleSelect={onMachineHandleSelect}
|
67
|
-
scriptType="Manual"
|
72
|
+
// scriptType="Manual"
|
73
|
+
readOnly={true}
|
68
74
|
/>
|
69
75
|
</>
|
70
76
|
);
|
package/src/components/SequentialConnectingBranch/components/DatasetTooltip/DataSetTooltip.tsx
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
import { FC } from 'react';
|
2
|
-
import Tooltip from '../../../Tooltip';
|
3
2
|
import Typography from '../../../Typography';
|
4
3
|
import { DataSetTooltipProps } from './types';
|
5
4
|
|
@@ -18,22 +17,18 @@ const DataSetTooltip: FC<DataSetTooltipProps> = ({
|
|
18
17
|
|
19
18
|
return (
|
20
19
|
<>
|
21
|
-
|
22
|
-
{
|
23
|
-
<div
|
24
|
-
<Typography
|
25
|
-
as="div"
|
26
|
-
fontSize={10}
|
27
|
-
lineHeight="15px"
|
28
|
-
>
|
20
|
+
{Object.entries(toolTipTitleValue).map(([key, value], index) => (
|
21
|
+
<div key={index} className='' >
|
22
|
+
<div className='' >
|
23
|
+
<Typography as="div" fontSize={10} lineHeight="15px">
|
29
24
|
{key}
|
30
25
|
</Typography>
|
31
26
|
<Typography as="div" lineHeight="18px">
|
32
27
|
{value}
|
33
28
|
</Typography>
|
34
29
|
</div>
|
35
|
-
|
36
|
-
|
30
|
+
</div>
|
31
|
+
))}
|
37
32
|
</>
|
38
33
|
);
|
39
34
|
};
|
@@ -18,6 +18,7 @@ import {
|
|
18
18
|
verticalListSortingStrategy,
|
19
19
|
} from '@dnd-kit/sortable';
|
20
20
|
import { CSS } from '@dnd-kit/utilities';
|
21
|
+
import { useEffect, useRef } from 'react';
|
21
22
|
|
22
23
|
const SortableRow = ({
|
23
24
|
row,
|
@@ -115,7 +116,49 @@ const Table = ({
|
|
115
116
|
headerIconOnClick = () => {},
|
116
117
|
draggable = false,
|
117
118
|
onDragEnd,
|
119
|
+
loadMore = () => {},
|
118
120
|
}: TableProps) => {
|
121
|
+
|
122
|
+
const observerRef = useRef<IntersectionObserver | null>(null);
|
123
|
+
|
124
|
+
useEffect(() => {
|
125
|
+
const scrollContainer = document.getElementById(
|
126
|
+
'ff-table-scroll-container'
|
127
|
+
);
|
128
|
+
const firstNode = document.getElementById('ff-table-first-node');
|
129
|
+
const lastNode = document.getElementById('ff-table-last-node');
|
130
|
+
|
131
|
+
// Exit early if data is empty or elements are missing
|
132
|
+
if (!scrollContainer || !firstNode || !lastNode || !data?.length) {
|
133
|
+
return;
|
134
|
+
}
|
135
|
+
|
136
|
+
observerRef.current = new IntersectionObserver(
|
137
|
+
(entries) => {
|
138
|
+
entries.forEach((entry) => {
|
139
|
+
if (entry.isIntersecting) {
|
140
|
+
const direction =
|
141
|
+
entry.target.id === 'ff-table-last-node' ? 'below' : 'above';
|
142
|
+
loadMore(direction);
|
143
|
+
}
|
144
|
+
});
|
145
|
+
},
|
146
|
+
{
|
147
|
+
root: scrollContainer,
|
148
|
+
rootMargin: '8px',
|
149
|
+
threshold: 0.1,
|
150
|
+
}
|
151
|
+
);
|
152
|
+
|
153
|
+
observerRef.current.observe(firstNode);
|
154
|
+
observerRef.current.observe(lastNode);
|
155
|
+
|
156
|
+
return () => {
|
157
|
+
// Cleanup observer
|
158
|
+
observerRef.current?.disconnect();
|
159
|
+
};
|
160
|
+
}, [data, loadMore]);
|
161
|
+
|
119
162
|
const handleOnclick = (column: ColumnsProps, row: DataProps) => {
|
120
163
|
let { onClick, accessor } = column;
|
121
164
|
if (onClick && isFunction(onClick)) {
|
@@ -153,6 +196,7 @@ const Table = ({
|
|
153
196
|
>
|
154
197
|
<div
|
155
198
|
style={{ height: height, position: 'relative' }}
|
199
|
+
id="ff-table-scroll-container"
|
156
200
|
className={classNames(className, {
|
157
201
|
'ff-fixed-header-table': withFixedHeader,
|
158
202
|
'border-borderRadius': borderWithRadius,
|
@@ -216,6 +260,7 @@ const Table = ({
|
|
216
260
|
</tr>
|
217
261
|
</thead>
|
218
262
|
<tbody className="ff-fixed-header-table">
|
263
|
+
<tr id="ff-table-first-node" />
|
219
264
|
{data?.length > 0 &&
|
220
265
|
data?.map((row: any) => (
|
221
266
|
<SortableRow
|
@@ -230,6 +275,8 @@ const Table = ({
|
|
230
275
|
draggable={draggable}
|
231
276
|
/>
|
232
277
|
))}
|
278
|
+
<tr id="ff-table-last-node" />
|
279
|
+
|
233
280
|
</tbody>
|
234
281
|
</table>
|
235
282
|
{data?.length <= 0 && (
|
@@ -128,5 +128,8 @@ export interface TableProps {
|
|
128
128
|
/**
|
129
129
|
* Drag and Drop indexes
|
130
130
|
*/
|
131
|
-
onDragEnd?: (startIndex: number, endIndex: number) => void | undefined
|
131
|
+
onDragEnd?: (startIndex: number, endIndex: number) => void | undefined,
|
132
|
+
|
133
|
+
loadMore?: (_direction?: string) => void;
|
134
|
+
|
132
135
|
}
|
@@ -1,13 +1,14 @@
|
|
1
1
|
import { useState } from 'react';
|
2
|
-
import { getTreeDetails,
|
2
|
+
import { getTreeDetails, TreeDetailsResult } from './getTreeDetails';
|
3
3
|
import React from 'react';
|
4
|
+
import { TreeNodeProps } from '../../ComponentProps/TreeNodeProps';
|
4
5
|
|
5
6
|
export default {
|
6
7
|
title: 'Utils/getTreeDetails',
|
7
8
|
component: getTreeDetails,
|
8
9
|
};
|
9
10
|
|
10
|
-
const initialData:
|
11
|
+
const initialData: TreeNodeProps[] = [
|
11
12
|
{
|
12
13
|
createdBy: 'USR4705',
|
13
14
|
modifiedBy: '--',
|
@@ -65,15 +66,31 @@ const initialData: TreeNode[] = [
|
|
65
66
|
];
|
66
67
|
|
67
68
|
export const InteractivePlayground = () => {
|
68
|
-
const [data, setData] = useState<
|
69
|
-
const [newData, setNewData] = useState<
|
70
|
-
const [action, setAction] = useState<
|
69
|
+
const [data, setData] = useState<TreeNodeProps[]>(initialData);
|
70
|
+
const [newData, setNewData] = useState<TreeNodeProps[]>([]);
|
71
|
+
const [action, setAction] = useState<
|
72
|
+
| 'above'
|
73
|
+
| 'below'
|
74
|
+
| 'expand'
|
75
|
+
| 'collapse'
|
76
|
+
| 'start'
|
77
|
+
| 'addAbove'
|
78
|
+
| 'addBelow'
|
79
|
+
>('below');
|
71
80
|
const [index, setIndex] = useState<number | undefined>(undefined);
|
81
|
+
const [sourceId, setSourceId] = useState<string | undefined>(undefined); // State for sourceId
|
72
82
|
const [result, setResult] = useState<TreeDetailsResult | null>(null);
|
73
83
|
|
74
84
|
const handleGetTreeDetails = () => {
|
75
85
|
try {
|
76
|
-
|
86
|
+
// If sourceId exists, we pass it, otherwise we pass the index
|
87
|
+
const treeDetails = getTreeDetails(
|
88
|
+
action,
|
89
|
+
data,
|
90
|
+
newData,
|
91
|
+
index,
|
92
|
+
sourceId
|
93
|
+
);
|
77
94
|
setData(treeDetails.treeDataList);
|
78
95
|
setResult(treeDetails);
|
79
96
|
} catch (error) {
|
@@ -91,7 +108,16 @@ export const InteractivePlayground = () => {
|
|
91
108
|
id="action"
|
92
109
|
value={action}
|
93
110
|
onChange={(e) =>
|
94
|
-
setAction(
|
111
|
+
setAction(
|
112
|
+
e.target.value as
|
113
|
+
| 'above'
|
114
|
+
| 'below'
|
115
|
+
| 'expand'
|
116
|
+
| 'collapse'
|
117
|
+
| 'start'
|
118
|
+
| 'addAbove'
|
119
|
+
| 'addBelow'
|
120
|
+
)
|
95
121
|
}
|
96
122
|
>
|
97
123
|
<option value="above">Above</option>
|
@@ -99,10 +125,32 @@ export const InteractivePlayground = () => {
|
|
99
125
|
<option value="expand">Expand</option>
|
100
126
|
<option value="collapse">Collapse</option>
|
101
127
|
<option value="start">Start</option>
|
128
|
+
<option value="addAbove">Add Above</option>
|
129
|
+
<option value="addBelow">Add Below</option>
|
102
130
|
</select>
|
103
131
|
</div>
|
104
132
|
|
105
|
-
{
|
133
|
+
{/* Input for sourceId, if action requires it */}
|
134
|
+
{(action === 'expand' ||
|
135
|
+
action === 'collapse' ||
|
136
|
+
action === 'addAbove' ||
|
137
|
+
action === 'addBelow') && (
|
138
|
+
<div>
|
139
|
+
<label htmlFor="sourceId">
|
140
|
+
Source ID (for expand/collapse/addAbove/addBelow):
|
141
|
+
</label>
|
142
|
+
<input
|
143
|
+
type="text"
|
144
|
+
id="sourceId"
|
145
|
+
value={sourceId || ''}
|
146
|
+
onChange={(e) => setSourceId(e.target.value)}
|
147
|
+
placeholder="Enter Source ID"
|
148
|
+
/>
|
149
|
+
</div>
|
150
|
+
)}
|
151
|
+
|
152
|
+
{/* Input for index, for actions requiring index */}
|
153
|
+
{(action === 'expand' || action === 'collapse') && !sourceId && (
|
106
154
|
<div>
|
107
155
|
<label htmlFor="index">Index (for expand/collapse):</label>
|
108
156
|
<input
|
@@ -110,7 +158,9 @@ export const InteractivePlayground = () => {
|
|
110
158
|
id="index"
|
111
159
|
value={index !== undefined ? index : ''}
|
112
160
|
onChange={(e) =>
|
113
|
-
setIndex(
|
161
|
+
setIndex(
|
162
|
+
e.target.value ? parseInt(e.target.value, 10) : undefined
|
163
|
+
)
|
114
164
|
}
|
115
165
|
disabled={action !== 'expand' && action !== 'collapse'}
|
116
166
|
/>
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { TreeNodeProps as TreeNode } from '../../ComponentProps/TreeNodeProps';
|
2
|
+
import { checkEmpty } from '../checkEmpty/checkEmpty';
|
2
3
|
|
3
4
|
export interface TreeDetailsResult {
|
4
5
|
treeDataList: TreeNode[];
|
@@ -10,14 +11,37 @@ export interface TreeDetailsResult {
|
|
10
11
|
}
|
11
12
|
|
12
13
|
export const getTreeDetails = (
|
13
|
-
action:
|
14
|
+
action:
|
15
|
+
| 'above'
|
16
|
+
| 'below'
|
17
|
+
| 'expand'
|
18
|
+
| 'collapse'
|
19
|
+
| 'start'
|
20
|
+
| 'addAbove'
|
21
|
+
| 'addBelow',
|
14
22
|
oldData: TreeNode[],
|
15
23
|
newData: TreeNode[],
|
16
|
-
index?: number
|
24
|
+
index?: number,
|
25
|
+
sourceId?: string
|
17
26
|
): TreeDetailsResult => {
|
18
27
|
let treeDataList: TreeNode[];
|
19
28
|
let root: TreeNode | undefined = undefined;
|
20
29
|
|
30
|
+
const findIndexByKey = (data: TreeNode[], key: string): number => {
|
31
|
+
return data.findIndex((node) => node.key === key);
|
32
|
+
};
|
33
|
+
|
34
|
+
const getIndex = (): number | undefined => {
|
35
|
+
if (sourceId) {
|
36
|
+
const indexByKey = findIndexByKey(oldData, sourceId);
|
37
|
+
if (indexByKey === -1) {
|
38
|
+
throw new Error(`Key "${sourceId}" not found in oldData.`);
|
39
|
+
}
|
40
|
+
return indexByKey;
|
41
|
+
}
|
42
|
+
return index; // Use index if sourceId is not provided
|
43
|
+
};
|
44
|
+
|
21
45
|
switch (action) {
|
22
46
|
case 'above':
|
23
47
|
treeDataList = [...newData, ...oldData].slice(0, 40);
|
@@ -27,16 +51,42 @@ export const getTreeDetails = (
|
|
27
51
|
break;
|
28
52
|
case 'expand':
|
29
53
|
case 'collapse':
|
30
|
-
|
31
|
-
|
32
|
-
} else {
|
54
|
+
const actionIndex = getIndex();
|
55
|
+
if (actionIndex === undefined) {
|
33
56
|
throw new Error(
|
34
|
-
"
|
57
|
+
"Both sourceId and index are required for 'expand' or 'collapse' actions."
|
35
58
|
);
|
36
59
|
}
|
60
|
+
treeDataList = [...oldData.slice(0, actionIndex), ...newData];
|
61
|
+
break;
|
62
|
+
case 'addAbove':
|
63
|
+
const addAboveIndex = getIndex();
|
64
|
+
if (addAboveIndex === undefined) {
|
65
|
+
throw new Error(
|
66
|
+
"Both sourceId and index are required for 'addAbove' action."
|
67
|
+
);
|
68
|
+
}
|
69
|
+
treeDataList = [
|
70
|
+
...oldData.slice(0, addAboveIndex),
|
71
|
+
...newData,
|
72
|
+
...oldData.slice(addAboveIndex),
|
73
|
+
];
|
74
|
+
break;
|
75
|
+
case 'addBelow':
|
76
|
+
const addBelowIndex = getIndex();
|
77
|
+
if (addBelowIndex === undefined) {
|
78
|
+
throw new Error(
|
79
|
+
"Both sourceId and index are required for 'addBelow' action."
|
80
|
+
);
|
81
|
+
}
|
82
|
+
treeDataList = [
|
83
|
+
...oldData.slice(0, addBelowIndex + 1),
|
84
|
+
...newData,
|
85
|
+
...oldData.slice(addBelowIndex + 1),
|
86
|
+
];
|
37
87
|
break;
|
38
88
|
case 'start':
|
39
|
-
if (newData
|
89
|
+
if (!checkEmpty(newData)) {
|
40
90
|
root = newData[0];
|
41
91
|
treeDataList = newData.slice(1);
|
42
92
|
} else {
|
@@ -47,19 +97,22 @@ export const getTreeDetails = (
|
|
47
97
|
throw new Error(`Invalid action: ${action}`);
|
48
98
|
}
|
49
99
|
|
50
|
-
if (treeDataList
|
100
|
+
if (checkEmpty(treeDataList) && action !== 'start') {
|
51
101
|
throw new Error('Tree data list is empty.');
|
52
102
|
}
|
53
103
|
|
54
104
|
const firstNode = treeDataList[0] || root!;
|
55
|
-
const lastNode = treeDataList[treeDataList.length - 1]
|
105
|
+
const lastNode = treeDataList[treeDataList.length - 1] || {
|
106
|
+
lastResource: true,
|
107
|
+
key: '',
|
108
|
+
};
|
56
109
|
|
57
110
|
return {
|
58
111
|
treeDataList,
|
59
|
-
next: !lastNode
|
60
|
-
previous: !firstNode
|
61
|
-
startId: firstNode
|
62
|
-
endId: lastNode
|
112
|
+
next: !lastNode?.lastResource,
|
113
|
+
previous: !firstNode?.lastResource,
|
114
|
+
startId: firstNode?.key,
|
115
|
+
endId: lastNode?.key,
|
63
116
|
root,
|
64
117
|
};
|
65
118
|
};
|