pixel-react 1.9.4 → 1.9.5
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/.yarn/install-state.gz +0 -0
- package/lib/components/Charts/MultiRadialChart/types.d.ts +2 -2
- package/lib/components/TableTree/types.d.ts +27 -3
- package/lib/components/Tabs/Tabs.d.ts +1 -1
- package/lib/components/Tabs/types.d.ts +1 -0
- package/lib/index.d.ts +105 -9
- package/lib/index.esm.js +119 -27
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +120 -26
- package/lib/index.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/utils/getTreeDetails/getTreeDetails.d.ts +38 -0
- package/lib/utils/handleTreeNodeSelect/handleTreeNodeSelect.d.ts +31 -0
- package/package.json +1 -1
- package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.scss +6 -3
- package/src/components/Charts/DashboardDonutChart/DashboardDonutChart.tsx +10 -4
- package/src/components/Charts/MultiRadialChart/types.ts +16 -17
- package/src/components/TableTree/Components/TableBody.tsx +0 -3
- package/src/components/TableTree/TableTree.scss +11 -1
- package/src/components/TableTree/TableTree.tsx +24 -13
- package/src/components/TableTree/data.ts +86 -1
- package/src/components/TableTree/types.ts +27 -3
- package/src/components/Tabs/Tabs.scss +44 -1
- package/src/components/Tabs/Tabs.stories.tsx +26 -0
- package/src/components/Tabs/Tabs.tsx +2 -0
- package/src/components/Tabs/types.ts +1 -0
- package/src/index.ts +11 -3
- package/src/utils/findAndInsert/findAndInsert.stories.tsx +1 -0
- package/src/utils/getTreeDetails/getTreeDetails.stories.tsx +167 -0
- package/src/utils/getTreeDetails/getTreeDetails.ts +93 -0
- package/src/utils/handleTreeNodeSelect/HandleTreeNodeSelect.stories.tsx +195 -0
- package/src/utils/handleTreeNodeSelect/handleTreeNodeSelect.ts +90 -0
@@ -150,4 +150,30 @@ export const WithoutBorder: Story = {
|
|
150
150
|
},
|
151
151
|
};
|
152
152
|
|
153
|
+
export const WithoutPadding: Story = {
|
154
|
+
render: () => {
|
155
|
+
const [activeTabIdDefault, setActiveTabIdDefault] =
|
156
|
+
useState<string>('tab-1');
|
157
|
+
|
158
|
+
return (
|
159
|
+
<div style={{ display: 'flex', gap: '10px' }}>
|
160
|
+
<Tabs
|
161
|
+
tabsData={tabsData}
|
162
|
+
activeTabId={activeTabIdDefault}
|
163
|
+
onTabClick={setActiveTabIdDefault}
|
164
|
+
noPadding={true}
|
165
|
+
/>{' '}
|
166
|
+
<hr />
|
167
|
+
<Tabs
|
168
|
+
variant="capsule"
|
169
|
+
tabsData={tabsData}
|
170
|
+
activeTabId={activeTabIdDefault}
|
171
|
+
onTabClick={setActiveTabIdDefault}
|
172
|
+
noPadding={true}
|
173
|
+
/>
|
174
|
+
</div>
|
175
|
+
);
|
176
|
+
},
|
177
|
+
};
|
178
|
+
|
153
179
|
export default meta;
|
@@ -10,12 +10,14 @@ const Tabs = ({
|
|
10
10
|
activeTabId,
|
11
11
|
onTabClick,
|
12
12
|
noBorder = false,
|
13
|
+
noPadding = false,
|
13
14
|
}: TabsProps) => {
|
14
15
|
return (
|
15
16
|
<div className={`ff-tabs-container`}>
|
16
17
|
<div
|
17
18
|
className={classNames(`ff-tab-row--${variant}`, {
|
18
19
|
'ff-tab-row--no-border': noBorder,
|
20
|
+
'ff-tab-row--no-padding': noPadding,
|
19
21
|
})}
|
20
22
|
>
|
21
23
|
{tabsData.map((tab) => (
|
package/src/index.ts
CHANGED
@@ -105,7 +105,11 @@ import ConditionalDropdown from './components/ConditionalDropdown/ConditionalDro
|
|
105
105
|
import { hasDuplicateFile } from './utils/checkDuplicates/checkDuplicates';
|
106
106
|
import PhoneInputField from './components/PhoneInput';
|
107
107
|
import { useKeyboardActions } from './utils/keyBoardActionUtil/UseKeyboardActions';
|
108
|
-
import { rearrangeDragItem } from './utils/swapArrayItem/dragAndDropUtils'
|
108
|
+
import { rearrangeDragItem } from './utils/swapArrayItem/dragAndDropUtils';
|
109
|
+
|
110
|
+
import { getTreeDetails } from './utils/getTreeDetails/getTreeDetails';
|
111
|
+
import { handleTreeNodeSect } from './utils/handleTreeNodeSelect/handleTreeNodeSelect';
|
112
|
+
|
109
113
|
import {
|
110
114
|
EMAIL_REGEX,
|
111
115
|
URL_REGEX,
|
@@ -163,7 +167,10 @@ import {
|
|
163
167
|
ELEMENTS_WHITE_SPACE_REGEX,
|
164
168
|
PARAMETER_ALPHANUMERIC_REGEX,
|
165
169
|
} from './validations/regex';
|
166
|
-
import {
|
170
|
+
import {
|
171
|
+
getFromIndexedDB,
|
172
|
+
saveToIndexedDB,
|
173
|
+
} from './utils/indexDBStore/indexDB';
|
167
174
|
|
168
175
|
export {
|
169
176
|
Button,
|
@@ -275,7 +282,8 @@ export {
|
|
275
282
|
saveToIndexedDB,
|
276
283
|
getFromIndexedDB,
|
277
284
|
rearrangeDragItem,
|
278
|
-
|
285
|
+
getTreeDetails,
|
286
|
+
handleTreeNodeSect,
|
279
287
|
EMAIL_REGEX,
|
280
288
|
URL_REGEX,
|
281
289
|
PHONE_REGEX,
|
@@ -0,0 +1,167 @@
|
|
1
|
+
import { useState } from 'react';
|
2
|
+
import { getTreeDetails, TreeNode, TreeDetailsResult } from './getTreeDetails';
|
3
|
+
import React from 'react';
|
4
|
+
|
5
|
+
export default {
|
6
|
+
title: 'Utils/getTreeDetails',
|
7
|
+
component: getTreeDetails,
|
8
|
+
};
|
9
|
+
|
10
|
+
const initialData: TreeNode[] = [
|
11
|
+
{
|
12
|
+
createdBy: 'USR4705',
|
13
|
+
modifiedBy: '--',
|
14
|
+
createdByUname: 'Saqeb',
|
15
|
+
modifiedByUname: '--',
|
16
|
+
createdOn: '2023-05-31T10:54:33.296Z',
|
17
|
+
modifiedOn: '2023-05-31T10:54:33.296Z',
|
18
|
+
state: 'APPROVED',
|
19
|
+
path: '/Root',
|
20
|
+
searchKey: '/PAG1010',
|
21
|
+
key: 'PAG1010',
|
22
|
+
name: 'Root',
|
23
|
+
projectId: 'PJT1006',
|
24
|
+
hierarchy: 0,
|
25
|
+
executionOrder: 0,
|
26
|
+
subContainerCount: 1,
|
27
|
+
resourceCount: 0,
|
28
|
+
totalSubContainerCount: 1,
|
29
|
+
totalResourceCount: 2,
|
30
|
+
totalProjectElementCount: 0,
|
31
|
+
totalSharedElementCount: 0,
|
32
|
+
container: false,
|
33
|
+
localDelete: false,
|
34
|
+
defaultEntity: false,
|
35
|
+
lastResource: false,
|
36
|
+
platform: '',
|
37
|
+
},
|
38
|
+
{
|
39
|
+
createdBy: 'USR4705',
|
40
|
+
modifiedBy: '--',
|
41
|
+
createdByUname: 'Saqeb',
|
42
|
+
modifiedByUname: '--',
|
43
|
+
createdOn: '2023-05-31T10:57:31.721Z',
|
44
|
+
modifiedOn: '2023-05-31T10:57:31.721Z',
|
45
|
+
state: 'APPROVED',
|
46
|
+
path: '/Root/page1',
|
47
|
+
searchKey: '/PAG1010/PAG1011',
|
48
|
+
key: 'PAG1011',
|
49
|
+
name: 'page1',
|
50
|
+
projectId: 'PJT1006',
|
51
|
+
hierarchy: 0,
|
52
|
+
executionOrder: 1,
|
53
|
+
subContainerCount: 0,
|
54
|
+
resourceCount: 3,
|
55
|
+
totalSubContainerCount: 0,
|
56
|
+
totalResourceCount: 1,
|
57
|
+
totalProjectElementCount: 0,
|
58
|
+
totalSharedElementCount: 0,
|
59
|
+
container: false,
|
60
|
+
localDelete: false,
|
61
|
+
defaultEntity: false,
|
62
|
+
lastResource: true,
|
63
|
+
platform: '',
|
64
|
+
},
|
65
|
+
];
|
66
|
+
|
67
|
+
export const InteractivePlayground = () => {
|
68
|
+
const [data, setData] = useState<TreeNode[]>(initialData);
|
69
|
+
const [newData, setNewData] = useState<TreeNode[]>([]);
|
70
|
+
const [action, setAction] = useState<'above' | 'below' | 'expand' | 'collapse' | 'start'>('below');
|
71
|
+
const [index, setIndex] = useState<number | undefined>(undefined);
|
72
|
+
const [result, setResult] = useState<TreeDetailsResult | null>(null);
|
73
|
+
|
74
|
+
const handleGetTreeDetails = () => {
|
75
|
+
try {
|
76
|
+
const treeDetails = getTreeDetails(action, data, newData, index);
|
77
|
+
setData(treeDetails.treeDataList);
|
78
|
+
setResult(treeDetails);
|
79
|
+
} catch (error) {
|
80
|
+
alert(error instanceof Error ? error.message : 'An error occurred');
|
81
|
+
}
|
82
|
+
};
|
83
|
+
|
84
|
+
return (
|
85
|
+
<div>
|
86
|
+
<h1>Interactive Playground for getTreeDetails</h1>
|
87
|
+
|
88
|
+
<div>
|
89
|
+
<label htmlFor="action">Action:</label>
|
90
|
+
<select
|
91
|
+
id="action"
|
92
|
+
value={action}
|
93
|
+
onChange={(e) =>
|
94
|
+
setAction(e.target.value as 'above' | 'below' | 'expand' | 'collapse' | 'start')
|
95
|
+
}
|
96
|
+
>
|
97
|
+
<option value="above">Above</option>
|
98
|
+
<option value="below">Below</option>
|
99
|
+
<option value="expand">Expand</option>
|
100
|
+
<option value="collapse">Collapse</option>
|
101
|
+
<option value="start">Start</option>
|
102
|
+
</select>
|
103
|
+
</div>
|
104
|
+
|
105
|
+
{(action === 'expand' || action === 'collapse') && (
|
106
|
+
<div>
|
107
|
+
<label htmlFor="index">Index (for expand/collapse):</label>
|
108
|
+
<input
|
109
|
+
type="number"
|
110
|
+
id="index"
|
111
|
+
value={index !== undefined ? index : ''}
|
112
|
+
onChange={(e) =>
|
113
|
+
setIndex(e.target.value ? parseInt(e.target.value, 10) : undefined)
|
114
|
+
}
|
115
|
+
disabled={action !== 'expand' && action !== 'collapse'}
|
116
|
+
/>
|
117
|
+
</div>
|
118
|
+
)}
|
119
|
+
|
120
|
+
<div>
|
121
|
+
<label htmlFor="newData">New Data (JSON):</label>
|
122
|
+
<textarea
|
123
|
+
id="newData"
|
124
|
+
value={JSON.stringify(newData, null, 2)}
|
125
|
+
onChange={(e) => {
|
126
|
+
try {
|
127
|
+
setNewData(JSON.parse(e.target.value));
|
128
|
+
} catch {
|
129
|
+
alert('Invalid JSON');
|
130
|
+
}
|
131
|
+
}}
|
132
|
+
/>
|
133
|
+
</div>
|
134
|
+
|
135
|
+
<button onClick={handleGetTreeDetails}>Get Tree Details</button>
|
136
|
+
|
137
|
+
<h2>Result:</h2>
|
138
|
+
{result ? (
|
139
|
+
<div>
|
140
|
+
{result.root && (
|
141
|
+
<>
|
142
|
+
<h3>Root:</h3>
|
143
|
+
<pre>{JSON.stringify(result.root, null, 2)}</pre>
|
144
|
+
</>
|
145
|
+
)}
|
146
|
+
<p>
|
147
|
+
<strong>Next:</strong> {result.next.toString()}
|
148
|
+
</p>
|
149
|
+
<p>
|
150
|
+
<strong>Previous:</strong> {result.previous.toString()}
|
151
|
+
</p>
|
152
|
+
<p>
|
153
|
+
<strong>Start ID:</strong> {result.startId}
|
154
|
+
</p>
|
155
|
+
<p>
|
156
|
+
<strong>End ID:</strong> {result.endId}
|
157
|
+
</p>
|
158
|
+
</div>
|
159
|
+
) : (
|
160
|
+
<p>No result yet. Perform an action to see the details.</p>
|
161
|
+
)}
|
162
|
+
|
163
|
+
<h2>Current Tree Data:</h2>
|
164
|
+
<pre>{JSON.stringify(data, null, 2)}</pre>
|
165
|
+
</div>
|
166
|
+
);
|
167
|
+
};
|
@@ -0,0 +1,93 @@
|
|
1
|
+
export interface TreeNode {
|
2
|
+
createdBy: string;
|
3
|
+
modifiedBy: string;
|
4
|
+
createdByUname: string;
|
5
|
+
modifiedByUname: string;
|
6
|
+
createdOn: string;
|
7
|
+
modifiedOn: string;
|
8
|
+
state: string;
|
9
|
+
path: string;
|
10
|
+
searchKey: string;
|
11
|
+
key: string;
|
12
|
+
name: string;
|
13
|
+
projectId: string;
|
14
|
+
hierarchy: number;
|
15
|
+
executionOrder: number;
|
16
|
+
subContainerCount: number;
|
17
|
+
resourceCount: number;
|
18
|
+
totalSubContainerCount: number;
|
19
|
+
totalResourceCount: number;
|
20
|
+
totalProjectElementCount: number;
|
21
|
+
totalSharedElementCount: number;
|
22
|
+
container: boolean;
|
23
|
+
localDelete: boolean;
|
24
|
+
defaultEntity: boolean;
|
25
|
+
lastResource: boolean;
|
26
|
+
platform: string;
|
27
|
+
parentId?: string;
|
28
|
+
parentName?: string;
|
29
|
+
}
|
30
|
+
|
31
|
+
export interface TreeDetailsResult {
|
32
|
+
treeDataList: TreeNode[];
|
33
|
+
next: boolean;
|
34
|
+
previous: boolean;
|
35
|
+
startId: string;
|
36
|
+
endId: string;
|
37
|
+
root?: TreeNode;
|
38
|
+
}
|
39
|
+
|
40
|
+
export const getTreeDetails = (
|
41
|
+
action: 'above' | 'below' | 'expand' | 'collapse' | 'start',
|
42
|
+
oldData: TreeNode[],
|
43
|
+
newData: TreeNode[],
|
44
|
+
index?: number
|
45
|
+
): TreeDetailsResult => {
|
46
|
+
let treeDataList: TreeNode[];
|
47
|
+
let root: TreeNode | undefined = undefined;
|
48
|
+
|
49
|
+
switch (action) {
|
50
|
+
case 'above':
|
51
|
+
treeDataList = [...newData, ...oldData].slice(0, 40);
|
52
|
+
break;
|
53
|
+
case 'below':
|
54
|
+
treeDataList = [...oldData, ...newData].slice(0, 40);
|
55
|
+
break;
|
56
|
+
case 'expand':
|
57
|
+
case 'collapse':
|
58
|
+
if (typeof index === 'number') {
|
59
|
+
treeDataList = [...oldData.slice(0, index + 1), ...newData];
|
60
|
+
} else {
|
61
|
+
throw new Error(
|
62
|
+
"Index is required for 'expand' or 'collapse' actions."
|
63
|
+
);
|
64
|
+
}
|
65
|
+
break;
|
66
|
+
case 'start':
|
67
|
+
if (oldData.length > 0) {
|
68
|
+
root = oldData[0];
|
69
|
+
treeDataList = oldData.slice(1);
|
70
|
+
} else {
|
71
|
+
throw new Error('Tree data list is empty, cannot determine root.');
|
72
|
+
}
|
73
|
+
break;
|
74
|
+
default:
|
75
|
+
throw new Error(`Invalid action: ${action}`);
|
76
|
+
}
|
77
|
+
|
78
|
+
if (treeDataList.length === 0 && action !== 'start') {
|
79
|
+
throw new Error('Tree data list is empty.');
|
80
|
+
}
|
81
|
+
|
82
|
+
const firstNode = treeDataList[0] || root!;
|
83
|
+
const lastNode = treeDataList[treeDataList.length - 1]!;
|
84
|
+
|
85
|
+
return {
|
86
|
+
treeDataList,
|
87
|
+
next: !lastNode.lastResource,
|
88
|
+
previous: !firstNode.lastResource,
|
89
|
+
startId: firstNode.key,
|
90
|
+
endId: lastNode.key,
|
91
|
+
root,
|
92
|
+
};
|
93
|
+
};
|
@@ -0,0 +1,195 @@
|
|
1
|
+
import React, { useState } from 'react';
|
2
|
+
import { handleTreeNodeSect, TreeNode } from './handleTreeNodeSelect'; // Ensure this imports the utility function
|
3
|
+
|
4
|
+
export default {
|
5
|
+
title: 'Utils/handleTreeNodeSect',
|
6
|
+
component: handleTreeNodeSect,
|
7
|
+
};
|
8
|
+
|
9
|
+
const initialData: TreeNode[] = [
|
10
|
+
{
|
11
|
+
createdBy: 'USR4705',
|
12
|
+
modifiedBy: '--',
|
13
|
+
createdByUname: 'Saqeb',
|
14
|
+
modifiedByUname: '--',
|
15
|
+
createdOn: '2023-05-31T10:54:33.296Z',
|
16
|
+
modifiedOn: '2023-05-31T10:54:33.296Z',
|
17
|
+
state: 'APPROVED',
|
18
|
+
path: '/Root',
|
19
|
+
searchKey: '/PAG1010',
|
20
|
+
key: 'PAG1010',
|
21
|
+
name: 'Root',
|
22
|
+
projectId: 'PJT1006',
|
23
|
+
hierarchy: 0,
|
24
|
+
executionOrder: 0,
|
25
|
+
subContainerCount: 1,
|
26
|
+
resourceCount: 0,
|
27
|
+
totalSubContainerCount: 1,
|
28
|
+
totalResourceCount: 2,
|
29
|
+
totalProjectElementCount: 0,
|
30
|
+
totalSharedElementCount: 0,
|
31
|
+
container: false,
|
32
|
+
localDelete: false,
|
33
|
+
defaultEntity: false,
|
34
|
+
lastResource: false,
|
35
|
+
platform: '',
|
36
|
+
},
|
37
|
+
{
|
38
|
+
createdBy: 'USR4705',
|
39
|
+
modifiedBy: '--',
|
40
|
+
createdByUname: 'Saqeb',
|
41
|
+
modifiedByUname: '--',
|
42
|
+
createdOn: '2023-05-31T10:57:31.721Z',
|
43
|
+
modifiedOn: '2023-05-31T10:57:31.721Z',
|
44
|
+
state: 'APPROVED',
|
45
|
+
path: '/Root/page1',
|
46
|
+
searchKey: '/PAG1010/PAG1011',
|
47
|
+
parentId: 'PAG1010',
|
48
|
+
parentName: 'Root Page',
|
49
|
+
key: 'PAG1011',
|
50
|
+
name: 'page1',
|
51
|
+
projectId: 'PJT1006',
|
52
|
+
hierarchy: 1,
|
53
|
+
executionOrder: 1,
|
54
|
+
subContainerCount: 0,
|
55
|
+
resourceCount: 3,
|
56
|
+
totalSubContainerCount: 0,
|
57
|
+
totalResourceCount: 1,
|
58
|
+
totalProjectElementCount: 0,
|
59
|
+
totalSharedElementCount: 0,
|
60
|
+
container: false,
|
61
|
+
localDelete: false,
|
62
|
+
defaultEntity: false,
|
63
|
+
lastResource: true,
|
64
|
+
},
|
65
|
+
{
|
66
|
+
createdBy: 'USR4705',
|
67
|
+
modifiedBy: '--',
|
68
|
+
createdByUname: 'Saqeb',
|
69
|
+
modifiedByUname: '--',
|
70
|
+
createdOn: '2023-05-31T11:00:00.000Z',
|
71
|
+
modifiedOn: '2023-05-31T11:00:00.000Z',
|
72
|
+
state: 'APPROVED',
|
73
|
+
path: '/Root/page2',
|
74
|
+
searchKey: '/PAG1010/PAG1012',
|
75
|
+
parentId: 'PAG1010',
|
76
|
+
parentName: 'Root Page',
|
77
|
+
key: 'PAG1012',
|
78
|
+
name: 'page2',
|
79
|
+
projectId: 'PJT1006',
|
80
|
+
hierarchy: 1,
|
81
|
+
executionOrder: 2,
|
82
|
+
subContainerCount: 2,
|
83
|
+
resourceCount: 5,
|
84
|
+
totalSubContainerCount: 2,
|
85
|
+
totalResourceCount: 7,
|
86
|
+
totalProjectElementCount: 0,
|
87
|
+
totalSharedElementCount: 0,
|
88
|
+
container: true,
|
89
|
+
localDelete: false,
|
90
|
+
defaultEntity: false,
|
91
|
+
lastResource: false,
|
92
|
+
},
|
93
|
+
{
|
94
|
+
createdBy: 'USR4705',
|
95
|
+
modifiedBy: '--',
|
96
|
+
createdByUname: 'Saqeb',
|
97
|
+
modifiedByUname: '--',
|
98
|
+
createdOn: '2023-05-31T11:05:00.000Z',
|
99
|
+
modifiedOn: '2023-05-31T11:05:00.000Z',
|
100
|
+
state: 'APPROVED',
|
101
|
+
path: '/Root/page2/subpage1',
|
102
|
+
searchKey: '/PAG1010/PAG1012/PAG1013',
|
103
|
+
parentId: 'PAG1012',
|
104
|
+
parentName: 'page2',
|
105
|
+
key: 'PAG1013',
|
106
|
+
name: 'subpage1',
|
107
|
+
projectId: 'PJT1006',
|
108
|
+
hierarchy: 2,
|
109
|
+
executionOrder: 1,
|
110
|
+
subContainerCount: 0,
|
111
|
+
resourceCount: 2,
|
112
|
+
totalSubContainerCount: 0,
|
113
|
+
totalResourceCount: 2,
|
114
|
+
totalProjectElementCount: 0,
|
115
|
+
totalSharedElementCount: 0,
|
116
|
+
container: false,
|
117
|
+
localDelete: false,
|
118
|
+
defaultEntity: false,
|
119
|
+
lastResource: true,
|
120
|
+
},
|
121
|
+
{
|
122
|
+
createdBy: 'USR4705',
|
123
|
+
modifiedBy: '--',
|
124
|
+
createdByUname: 'Saqeb',
|
125
|
+
modifiedByUname: '--',
|
126
|
+
createdOn: '2023-05-31T11:10:00.000Z',
|
127
|
+
modifiedOn: '2023-05-31T11:10:00.000Z',
|
128
|
+
state: 'APPROVED',
|
129
|
+
path: '/Root/page2/subpage2',
|
130
|
+
searchKey: '/PAG1010/PAG1012/PAG1014',
|
131
|
+
parentId: 'PAG1012',
|
132
|
+
parentName: 'page2',
|
133
|
+
key: 'PAG1014',
|
134
|
+
name: 'subpage2',
|
135
|
+
projectId: 'PJT1006',
|
136
|
+
hierarchy: 2,
|
137
|
+
executionOrder: 2,
|
138
|
+
subContainerCount: 0,
|
139
|
+
resourceCount: 4,
|
140
|
+
totalSubContainerCount: 0,
|
141
|
+
totalResourceCount: 4,
|
142
|
+
totalProjectElementCount: 0,
|
143
|
+
totalSharedElementCount: 0,
|
144
|
+
container: false,
|
145
|
+
localDelete: false,
|
146
|
+
defaultEntity: false,
|
147
|
+
lastResource: true,
|
148
|
+
},
|
149
|
+
// Repeat similar patterns to generate 50 entries, modifying hierarchy, executionOrder, and other attributes as needed.
|
150
|
+
];
|
151
|
+
|
152
|
+
export const InteractiveTreeSelector = () => {
|
153
|
+
const [data, setData] = useState<TreeNode[]>(initialData);
|
154
|
+
const [selectedKey, setSelectedKey] = useState<string>('');
|
155
|
+
const [isChecked, setIsChecked] = useState<boolean>(false);
|
156
|
+
|
157
|
+
const handleUpdateTree = () => {
|
158
|
+
const updatedTree = handleTreeNodeSect(data, selectedKey, isChecked);
|
159
|
+
setData([...updatedTree]);
|
160
|
+
};
|
161
|
+
|
162
|
+
return (
|
163
|
+
<div style={{ fontFamily: 'Arial, sans-serif', padding: '20px' }}>
|
164
|
+
<h1>Interactive Tree Selector</h1>
|
165
|
+
<div>
|
166
|
+
<label htmlFor="nodeKey">Node Key:</label>
|
167
|
+
<input
|
168
|
+
id="nodeKey"
|
169
|
+
type="text"
|
170
|
+
value={selectedKey}
|
171
|
+
onChange={(e) => setSelectedKey(e.target.value)}
|
172
|
+
placeholder="Enter node key"
|
173
|
+
/>
|
174
|
+
</div>
|
175
|
+
<div>
|
176
|
+
<label>
|
177
|
+
<input
|
178
|
+
type="checkbox"
|
179
|
+
checked={isChecked}
|
180
|
+
onChange={(e) => setIsChecked(e.target.checked)}
|
181
|
+
/>
|
182
|
+
Set Checked
|
183
|
+
</label>
|
184
|
+
</div>
|
185
|
+
<button onClick={handleUpdateTree} style={{ marginTop: '10px' }}>
|
186
|
+
Update Tree
|
187
|
+
</button>
|
188
|
+
|
189
|
+
<h2>Tree Data:</h2>
|
190
|
+
<pre style={{ backgroundColor: '#f4f4f4', padding: '10px' }}>
|
191
|
+
{JSON.stringify(data, null, 2)}
|
192
|
+
</pre>
|
193
|
+
</div>
|
194
|
+
);
|
195
|
+
};
|
@@ -0,0 +1,90 @@
|
|
1
|
+
export type TreeNode = {
|
2
|
+
createdBy: string;
|
3
|
+
modifiedBy: string;
|
4
|
+
createdByUname: string;
|
5
|
+
modifiedByUname: string;
|
6
|
+
createdOn: string;
|
7
|
+
modifiedOn: string;
|
8
|
+
state: string;
|
9
|
+
path: string;
|
10
|
+
searchKey: string;
|
11
|
+
key: string;
|
12
|
+
name: string;
|
13
|
+
projectId: string;
|
14
|
+
hierarchy: number;
|
15
|
+
executionOrder: number;
|
16
|
+
subContainerCount: number;
|
17
|
+
resourceCount: number;
|
18
|
+
totalSubContainerCount: number;
|
19
|
+
totalResourceCount: number;
|
20
|
+
totalProjectElementCount: number;
|
21
|
+
totalSharedElementCount: number;
|
22
|
+
container: boolean;
|
23
|
+
localDelete: boolean;
|
24
|
+
defaultEntity: boolean;
|
25
|
+
lastResource: boolean;
|
26
|
+
platform?: string;
|
27
|
+
parentId?: string;
|
28
|
+
parentName?: string;
|
29
|
+
checked?: boolean | 'partial';
|
30
|
+
};
|
31
|
+
|
32
|
+
export const handleTreeNodeSect = (
|
33
|
+
data: TreeNode[],
|
34
|
+
key: string,
|
35
|
+
isChecked: boolean | 'partial'
|
36
|
+
): TreeNode[] => {
|
37
|
+
const nodesMap = new Map<string, TreeNode>();
|
38
|
+
|
39
|
+
// Build a map for quick access to nodes by key
|
40
|
+
data.forEach((node) => nodesMap.set(node.key, node));
|
41
|
+
|
42
|
+
// Helper to update child nodes
|
43
|
+
function updateChildren(nodeKey: string, checkedStatus: boolean | 'partial') {
|
44
|
+
for (const node of data) {
|
45
|
+
if (node.parentId === nodeKey) {
|
46
|
+
node.checked = checkedStatus;
|
47
|
+
updateChildren(node.key, checkedStatus);
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
// Helper to update parent nodes
|
53
|
+
function updateParents(nodeKey: string) {
|
54
|
+
const node = nodesMap.get(nodeKey);
|
55
|
+
if (node && node.parentId) {
|
56
|
+
const parentNode = nodesMap.get(node.parentId);
|
57
|
+
if (parentNode) {
|
58
|
+
const siblings = data.filter(
|
59
|
+
(sibling) => sibling.parentId === parentNode.key
|
60
|
+
);
|
61
|
+
const allChecked = siblings.every(
|
62
|
+
(sibling) => sibling.checked === true
|
63
|
+
);
|
64
|
+
const someChecked = siblings.some(
|
65
|
+
(sibling) => sibling.checked === true || sibling.checked === 'partial'
|
66
|
+
);
|
67
|
+
|
68
|
+
parentNode.checked = allChecked
|
69
|
+
? true
|
70
|
+
: someChecked
|
71
|
+
? 'partial'
|
72
|
+
: false;
|
73
|
+
|
74
|
+
updateParents(parentNode.key);
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
// Find the target node and update its state
|
80
|
+
const targetNode = nodesMap.get(key);
|
81
|
+
if (targetNode) {
|
82
|
+
targetNode.checked = isChecked;
|
83
|
+
// Update children recursively
|
84
|
+
updateChildren(key, isChecked);
|
85
|
+
// Update parents recursively
|
86
|
+
updateParents(key);
|
87
|
+
}
|
88
|
+
|
89
|
+
return data;
|
90
|
+
};
|