Skip to content

Commit 6272184

Browse files
authored
version(patch): Merge pull request #93 from sathish151198/root-label-edit
fix(rfk): update expand collapse during search | update move to functionality
2 parents 2478266 + 2526622 commit 6272184

2 files changed

Lines changed: 107 additions & 75 deletions

File tree

src/FieldsKeeper/FieldsKeeperBucket.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,12 @@ const GroupedItemRenderer = (
712712
groupFieldItems: groupHeader?.groupItems,
713713
onRenameField: onFieldRename,
714714
onMoveFieldToBucket: (targetBucketId: string, fieldItems?: IFieldsKeeperItem[]) => {
715-
const itemsToMove = fieldItems || (isGroupHeader ? groupHeader?.groupItems : [fieldItem]);
715+
let itemsToMove = fieldItems
716+
if(isGroupHeader) {
717+
itemsToMove = groupHeader?.groupItems;
718+
} else if(!fieldItems) {
719+
itemsToMove = [fieldItem];
720+
}
716721

717722
if (itemsToMove && itemsToMove.length > 0) {
718723
const validItems = itemsToMove.filter(item => item && item.id);

src/FieldsKeeper/FieldsKeeperRootBucket.tsx

Lines changed: 101 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ export const FieldsKeeperRootBucket = (props: IFieldsKeeperRootBucketProps) => {
6565
Record<string, boolean>
6666
>(initialFolderStates || {});
6767

68+
const [searchBasedExpCollapse, setSearchBasedExpCollapse] = useState<
69+
Record<string, boolean>
70+
>({});
6871
// refs
6972
const searchInputRef = useRef<HTMLInputElement>(null);
7073
const contentContainerRef = useRef<HTMLDivElement>(null);
@@ -90,6 +93,7 @@ export const FieldsKeeperRootBucket = (props: IFieldsKeeperRootBucketProps) => {
9093
// compute
9194
const defaultFolderScope = '___DEFAULT';
9295
const hasCustomSearchQuery = customSearchQuery !== undefined;
96+
const hasSearchQuery = (customSearchQuery ?? searchQuery) !== '';
9397
const folderScopedItems = useMemo<
9498
IFolderScopedItem<IGroupedFieldsKeeperItem>[]
9599
>(() => {
@@ -221,6 +225,29 @@ export const FieldsKeeperRootBucket = (props: IFieldsKeeperRootBucketProps) => {
221225
sortBasedOnFolder,
222226
]);
223227

228+
useEffect(() => {
229+
if (!hasSearchQuery) {
230+
setSearchBasedExpCollapse({});
231+
return;
232+
}
233+
234+
if (Object.keys(searchBasedExpCollapse).length === 0) {
235+
const allExpanded: Record<string, boolean> = {};
236+
folderScopedItems.forEach((folderItem) => {
237+
const folderId = folderItem.folderScopeItem?.id;
238+
if (folderId) {
239+
allExpanded[folderId] = false;
240+
}
241+
});
242+
setSearchBasedExpCollapse(allExpanded);
243+
}
244+
}, [hasSearchQuery]);
245+
246+
const activeCollapseMap = hasSearchQuery ? searchBasedExpCollapse : collapsedNodes;
247+
const setActiveCollapseMap = hasSearchQuery
248+
? setSearchBasedExpCollapse
249+
: setCollapsedNodes;
250+
224251
useEffect(() => {
225252
if (contentContainerRef.current) {
226253
const markInstance = new Mark(contentContainerRef.current);
@@ -265,25 +292,19 @@ export const FieldsKeeperRootBucket = (props: IFieldsKeeperRootBucketProps) => {
265292

266293
const onExpandCollapseAll = (isCollapse: boolean) => {
267294
const collapsedFolders: Record<string, boolean> = {};
268-
folderScopedItems.map((folderItem) => {
269-
if (folderItem.folderScopeItem) {
270-
const folderId = folderItem.folderScopeItem.id as string;
271-
collapsedFolders[folderId] = isCollapse;
272-
}
295+
folderScopedItems.forEach((folderItem) => {
296+
const folderId = folderItem.folderScopeItem?.id as string;
297+
if (folderId) collapsedFolders[folderId] = isCollapse;
273298
});
274-
setCollapsedNodes((prevState) => {
275-
const newState = {
276-
...prevState,
277-
...collapsedFolders,
278-
};
279-
299+
300+
setActiveCollapseMap((prev) => {
301+
const newState = { ...prev, ...collapsedFolders };
280302
if (onFolderStateChange) {
281-
Object.keys(collapsedFolders).forEach(folderId => {
282-
onFolderStateChange(folderId, isCollapse, newState);
283-
});
303+
Object.keys(collapsedFolders).forEach((folderId) =>
304+
onFolderStateChange(folderId, isCollapse, newState),
305+
);
284306
}
285-
286-
return newState;
307+
return newState;
287308
});
288309
};
289310
const onKeyDown = (
@@ -345,9 +366,10 @@ export const FieldsKeeperRootBucket = (props: IFieldsKeeperRootBucketProps) => {
345366
key={index}
346367
folderScopedItem={folderScopedItem}
347368
showFlatFolderScope={showFlatFolderScope}
369+
hasSearchQuery={hasSearchQuery}
348370
folderScopedItemsArray={folderScopedItems}
349-
collapsedNodes={collapsedNodes}
350-
setCollapsedNodes={setCollapsedNodes}
371+
collapsedNodes={activeCollapseMap}
372+
setCollapsedNodes={setActiveCollapseMap}
351373
onExpandCollapseAll={onExpandCollapseAll}
352374
/>
353375
))
@@ -401,6 +423,7 @@ function FolderScopeItemRenderer(
401423
props: IFieldsKeeperRootBucketProps & {
402424
folderScopedItem: IFolderScopedItem<IGroupedFieldsKeeperItem>;
403425
showFlatFolderScope: boolean;
426+
hasSearchQuery: boolean;
404427
folderScopedItemsArray: IFolderScopedItem<IGroupedFieldsKeeperItem>[];
405428
collapsedNodes: Record<string, boolean>;
406429
setCollapsedNodes: React.Dispatch<
@@ -413,9 +436,9 @@ function FolderScopeItemRenderer(
413436
const {
414437
folderScopedItem: { type, folderScopeItem, folderScopeItems },
415438
showFlatFolderScope,
439+
hasSearchQuery,
416440
folderScopedItemsArray,
417-
collapsedNodes,
418-
setCollapsedNodes,
441+
collapsedNodes: activeCollapseMap, setCollapsedNodes: setActive,
419442
customClassNames,
420443
sortBasedOnFolder = true,
421444
suffixNodeRenderer,
@@ -495,7 +518,7 @@ function FolderScopeItemRenderer(
495518
if (rootBucketProps.collapseFoldersOnMount !== undefined) {
496519
setIsFolderCollapsed(rootBucketProps.collapseFoldersOnMount);
497520
if (rootBucketProps.collapseFoldersOnMount) {
498-
setCollapsedNodes((prevState) => ({
521+
setActive((prevState) => ({
499522
...prevState,
500523
[id]: true,
501524
}));
@@ -504,10 +527,10 @@ function FolderScopeItemRenderer(
504527
}, [rootBucketProps.collapseFoldersOnMount, id]);
505528

506529
useEffect(() => {
507-
if (Object.keys(collapsedNodes).includes(id)) {
508-
setIsFolderCollapsed(collapsedNodes[id]);
530+
if (Object.keys(activeCollapseMap).includes(id)) {
531+
setIsFolderCollapsed(activeCollapseMap[id]);
509532
}
510-
}, [collapsedNodes]);
533+
}, [activeCollapseMap]);
511534

512535
useEffect(() => {
513536
setCrossHighlightItemIds(
@@ -576,24 +599,20 @@ function FolderScopeItemRenderer(
576599

577600
setHighlightedItem(instanceId, null);
578601
const toggleCollapse = (id: string) => {
579-
setCollapsedNodes((prevState) => {
602+
setActive((prevState) => {
580603
const newCollapsed = !prevState[id];
581-
const newState = {
582-
...prevState,
583-
[id]: newCollapsed,
584-
};
585-
604+
const newState = { ...prevState, [id]: newCollapsed };
605+
586606
if (rootBucketProps.onFolderStateChange) {
587607
rootBucketProps.onFolderStateChange(id, newCollapsed, newState);
588608
}
589-
590609
return newState;
591610
});
592611

593612
// Move highlight update logic outside of render phase
594613
const highlightedIds = getCrossHighlightIds();
595614
const folderIds = getFolderIdsFromValues(foldersMeta);
596-
const updatedHighlightIds = !collapsedNodes[id]
615+
const updatedHighlightIds = !activeCollapseMap[id]
597616
? [...highlightedIds.filter((id) => folderIds.includes(id))]
598617
: highlightedIds;
599618
setCrossHighlightItemIds(updatedHighlightIds);
@@ -670,7 +689,7 @@ function FolderScopeItemRenderer(
670689
if (foldersMeta[folder].isHidden) {
671690
isHidden = true;
672691
}
673-
if (collapsedNodes[folder]) {
692+
if (activeCollapseMap[folder]) {
674693
isCollapsed = true;
675694
}
676695
});
@@ -872,7 +891,7 @@ function FolderScopeItemRenderer(
872891
}
873892
if (isFolderCollapsedOriginal) {
874893
setIsFolderCollapsed(false);
875-
setCollapsedNodes((prevState) => ({
894+
setActive((prevState) => ({
876895
...prevState,
877896
[id]: false,
878897
}));
@@ -1237,30 +1256,37 @@ function GroupedItemRenderer(
12371256

12381257
// State to manage editable field items and their labels
12391258
const [editableItemId, setEditableItemId] = useState<string | null>(null);
1240-
const [editedLabels, setEditedLabels] = useState<Record<string, string>>(() => {
1241-
const labels: Record<string, string> = {};
1259+
const [editedLabels, setEditedLabels] = useState<Record<string, string>>(
1260+
() => {
1261+
const labels: Record<string, string> = {};
12421262

1243-
// 1. Add all real items
1244-
allItems.forEach((item) => {
1245-
labels[item.id] = item.label;
1246-
});
1263+
// 1. Add all real items
1264+
allItems.forEach((item) => {
1265+
labels[item.id] = item.label;
1266+
});
12471267

1248-
// 2. Add group header (if exists)
1249-
if (group && group !== FIELDS_KEEPER_CONSTANTS.NO_GROUP_ID && groupLabel) {
1250-
labels[group] = groupLabel;
1251-
}
1268+
// 2. Add group header (if exists)
1269+
if (
1270+
group &&
1271+
group !== FIELDS_KEEPER_CONSTANTS.NO_GROUP_ID &&
1272+
groupLabel
1273+
) {
1274+
labels[group] = groupLabel;
1275+
}
12521276

1253-
// 3. Add flat group header (if exists)
1254-
if (
1255-
flatGroup &&
1256-
flatGroup !== FIELDS_KEEPER_CONSTANTS.NO_GROUP_ID &&
1257-
flatGroupLabel
1258-
) {
1259-
labels[flatGroup as string] = flatGroupLabel as string;
1260-
}
1277+
// 3. Add flat group header (if exists)
1278+
if (
1279+
flatGroup &&
1280+
flatGroup !== FIELDS_KEEPER_CONSTANTS.NO_GROUP_ID &&
1281+
flatGroupLabel
1282+
) {
1283+
labels[flatGroup as string] = flatGroupLabel as string;
1284+
}
1285+
1286+
return labels;
1287+
},
1288+
);
12611289

1262-
return labels;
1263-
});
12641290
const inputRefs = useRef<Record<string, HTMLInputElement | null>>({});
12651291

12661292
// Click tracking for double-click detection
@@ -1288,9 +1314,11 @@ function GroupedItemRenderer(
12881314
}
12891315
return activeIds;
12901316
};
1317+
12911318
const [activeHighlightIds, setActiveHighlightIds] = useState<
12921319
Record<string, IHighlightInfo>
12931320
>(getInitialActiveHighlightIds());
1321+
12941322
useEffect(() => {
12951323
if (highlightedItem) {
12961324
setActiveHighlightIds((prev) => ({
@@ -1362,28 +1390,28 @@ function GroupedItemRenderer(
13621390
// Update editedLabels when allItems change
13631391
useEffect(() => {
13641392
setEditedLabels((prev) => {
1365-
const newLabels = { ...prev };
1393+
const newLabels = { ...prev };
13661394

1367-
// Sync real items
1368-
allItems.forEach((item) => {
1369-
if (!(item.id in newLabels)) {
1370-
newLabels[item.id] = item.label;
1371-
}
1372-
});
1395+
// Sync real items
1396+
allItems.forEach((item) => {
1397+
if (!(item.id in newLabels)) {
1398+
newLabels[item.id] = item.label;
1399+
}
1400+
});
13731401

1374-
// Sync group header
1375-
if (group && group !== FIELDS_KEEPER_CONSTANTS.NO_GROUP_ID && groupLabel) {
1376-
newLabels[group] = groupLabel;
1377-
}
1402+
// Sync group header
1403+
if (group && group !== FIELDS_KEEPER_CONSTANTS.NO_GROUP_ID && groupLabel) {
1404+
newLabels[group] = groupLabel;
1405+
}
13781406

1379-
// Sync flat group
1380-
if (flatGroup && flatGroup !== FIELDS_KEEPER_CONSTANTS.NO_GROUP_ID && flatGroupLabel) {
1381-
newLabels[flatGroup as string] = flatGroupLabel as string;
1382-
}
1407+
// Sync flat group
1408+
if (flatGroup && flatGroup !== FIELDS_KEEPER_CONSTANTS.NO_GROUP_ID && flatGroupLabel) {
1409+
newLabels[flatGroup as string] = flatGroupLabel as string;
1410+
}
13831411

1384-
return newLabels;
1385-
});
1386-
}, [allItems, group, groupLabel, flatGroup, flatGroupLabel]);
1412+
return newLabels;
1413+
});
1414+
}, [allItems, group, groupLabel, flatGroup, flatGroupLabel]);
13871415

13881416
// Handler functions for inline editing
13891417
const onInputFieldChange = (fieldId: string, newValue: string) => {
@@ -1446,8 +1474,6 @@ function GroupedItemRenderer(
14461474
clickTimeoutRef.current = null;
14471475
}, DOUBLE_CLICK_THRESHOLD);
14481476
} else if (onFieldItemLabelChange && clickCountRef.current === 2) {
1449-
console.log(clickTimeoutRef.current, " clickTimeoutRef.current ++")
1450-
console.log(fieldItem, " field Item ++")
14511477
if (clickTimeoutRef.current) {
14521478
clearTimeout(clickTimeoutRef.current);
14531479
clickTimeoutRef.current = null;
@@ -1498,6 +1524,7 @@ function GroupedItemRenderer(
14981524
const customTargetBucketIdentifier =
14991525
getPriorityTargetBucketToFillFromProps ??
15001526
getPriorityTargetBucketToFillFromContext;
1527+
15011528
const getPriorityTargetBucketToFill = ({
15021529
buckets,
15031530
currentFillingItem,

0 commit comments

Comments
 (0)