Skip to content

Commit

Permalink
feat: improve branch display on TreeView (#793)
Browse files Browse the repository at this point in the history
* RM#86488
  • Loading branch information
vhu-axelor authored and lme-axelor committed Nov 22, 2024
1 parent 46370a5 commit 9ecd41a
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 93 deletions.
5 changes: 5 additions & 0 deletions changelogs/unreleased/86488_feat_ActionCard.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"title": "ActionCard: add the possibility to define a quick action which is displayed above the button to see all the actions",
"type": "feat",
"packages": "ui"
}
5 changes: 5 additions & 0 deletions changelogs/unreleased/86488_feat_TreeView.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"title": "TreeView: add the possibility to define additional actions on branch",
"type": "feat",
"packages": "ui"
}
5 changes: 5 additions & 0 deletions changelogs/unreleased/86488_refactor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"title": "TreeView: use ActionCard for branch display",
"type": "refactor",
"packages": "ui"
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import React, {useCallback, useEffect, useState} from 'react';
import {StyleSheet, View} from 'react-native';
import {
ActionCardType,
ActionType,
AutoCompleteSearch,
HeaderContainer,
Expand Down Expand Up @@ -59,6 +60,7 @@ interface SearchTreeViewProps {
headerTopChildren?: any;
parentFieldName?: string;
renderBranch?: (item: any) => any;
getBranchActions?: (branch: any) => ActionCardType[];
renderLeaf: (item: any) => any;
actionList?: ActionType[];
verticalActions?: boolean;
Expand Down Expand Up @@ -94,6 +96,7 @@ const SearchTreeView = ({
headerTopChildren,
parentFieldName,
renderBranch,
getBranchActions,
renderLeaf,
actionList,
verticalActions,
Expand Down Expand Up @@ -236,6 +239,7 @@ const SearchTreeView = ({
parentFieldName={parentFieldName}
branchCardInfoButtonIndication={I18n.t('Base_Filter')}
renderBranch={renderBranch}
getBranchActions={getBranchActions}
renderLeaf={renderLeaf}
fetchData={fetchListAPI}
fetchBranchData={fetchBranchData}
Expand Down
12 changes: 12 additions & 0 deletions packages/ui/__tests__/components/organisms/ActionCard.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ describe('ActionCard Component', () => {
expect(actionList[0].onPress).toHaveBeenCalled();
});

it('should render InfoButton components for quick action if present', () => {
const quickAction = {iconName: 'heart', onPress: jest.fn()};
const wrapper = shallow(
<ActionCard {...props} quickAction={quickAction} />,
);

expect(wrapper.find(InfoButton).length).toBe(actionList.length + 1);

const quickActionWrapper = wrapper.find(InfoButton).at(actionList.length);
expect(quickActionWrapper.props()).toMatchObject(quickAction);
});

it('should apply custom style to the container if provided', () => {
const customStyle = {width: 200};
const wrapper = shallow(<ActionCard {...props} style={customStyle} />);
Expand Down
85 changes: 61 additions & 24 deletions packages/ui/src/components/organisms/ActionCard/ActionCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
const ACTION_WIDTH = 40;
const TWO_ACTIONS_HEIGHT = 84;

interface Action {
export interface Action {
iconName: string;
iconColor?: string;
helper?: string;
Expand All @@ -42,6 +42,7 @@ interface ActionCardProps {
style?: any;
children: any;
actionList: Action[];
quickAction?: Action;
horizontal?: boolean;
forceActionsDisplay?: boolean;
translator: (key: string) => string;
Expand All @@ -51,6 +52,7 @@ const ActionCard = ({
style,
children,
actionList,
quickAction,
horizontal = false,
forceActionsDisplay = false,
translator,
Expand Down Expand Up @@ -90,6 +92,12 @@ const ActionCard = ({
[actionList],
);

const _quickAction = useMemo(
() =>
quickAction != null && !quickAction.hidden ? quickAction : undefined,
[quickAction],
);

const isMoreThanOneAction = useMemo(
() => _actionList.length > 1,
[_actionList],
Expand All @@ -110,13 +118,14 @@ const ActionCard = ({

useEffect(() => {
const shouldDisplay =
(_actionList.length > 2 ||
(_actionList[0]?.large && horizontal) ||
_actionList[1]?.large) &&
!forceActionsDisplay;
(_quickAction != null && !_quickAction.large
? _actionList.length > 1
: _actionList.length > 2 ||
(_actionList[0]?.large && horizontal) ||
_actionList[1]?.large) && !forceActionsDisplay;
setDisplaySeeActionsButton(shouldDisplay);
setIsActionsVisible(!shouldDisplay);
}, [_actionList, forceActionsDisplay, horizontal]);
}, [_actionList, forceActionsDisplay, horizontal, _quickAction]);

const isCardMinHeight = useMemo(
() => _actionList.length > 1 || _actionList[0]?.large,
Expand All @@ -129,7 +138,7 @@ const ActionCard = ({
);

const getIconColor = (action: Action) => {
return action.iconColor ?? Colors.secondaryColor_dark.background;
return action?.iconColor ?? Colors.secondaryColor_dark.background;
};

const renderHorizontalActions = (list, isLastList) => {
Expand Down Expand Up @@ -168,9 +177,7 @@ const ActionCard = ({

verticalActions.push(
<View
style={
getVerticalActionStyle(action2 == null || action3 === null).action
}
style={getVerticalActionStyle(action2 == null || action3 === null)}
key={index}>
<InfoButton
style={{width: ACTION_WIDTH}}
Expand Down Expand Up @@ -207,15 +214,8 @@ const ActionCard = ({
})}
</View>
{_actionList.length > 0 &&
(displaySeeActionsButton && !isActionsVisible ? (
<InfoButton
style={styles.seeActions}
iconName="three-dots"
iconColor={Colors.secondaryColor_dark.background}
indication={translator('Base_SeeActions')}
onPress={() => setIsActionsVisible(true)}
/>
) : (
isActionsVisible &&
(!_quickAction || isMoreThanOneAction) && (
<View>
{horizontal ? (
<>
Expand All @@ -240,7 +240,42 @@ const ActionCard = ({
</View>
)}
</View>
))}
)}
<View style={styles.quickActionContainer}>
{_quickAction != null && _actionList.length === 1 && (
<InfoButton
style={getVerticalActionStyle(false)}
iconName={actionList[0].iconName}
iconColor={getIconColor(actionList[0])}
indication={actionList[0].helper}
onPress={actionList[0].onPress}
disabled={actionList[0].disabled}
/>
)}
{displaySeeActionsButton && (
<InfoButton
style={getVerticalActionStyle(
_quickAction == null || _quickAction.large,
)}
iconName="three-dots"
iconColor={Colors.secondaryColor_dark.background}
indication={translator('Base_SeeActions')}
onPress={() => setIsActionsVisible(current => !current)}
/>
)}
{_quickAction != null && (
<InfoButton
style={getVerticalActionStyle(
_actionList.length === 0 || _quickAction.large,
)}
iconName={_quickAction.iconName}
iconColor={getIconColor(_quickAction)}
indication={_quickAction.helper}
onPress={_quickAction.onPress}
disabled={_quickAction.disabled}
/>
)}
</View>
</View>
);
};
Expand All @@ -257,9 +292,6 @@ const getStyles = (isMoreThanOneAction: boolean) =>
cardContainer: {
flex: 1,
},
seeActions: {
width: 40,
},
horizontalActionContainer: {
flexDirection: 'row',
flexWrap: 'wrap',
Expand All @@ -269,13 +301,18 @@ const getStyles = (isMoreThanOneAction: boolean) =>
verticalActionContainer: {
flexDirection: 'row',
},
quickActionContainer: {
flexDirection: 'column-reverse',
flexWrap: 'wrap',
},
});

const getVerticalActionStyle = (isLargeAction: boolean) =>
StyleSheet.create({
action: {
width: ACTION_WIDTH,
height: isLargeAction ? '100%' : '50%',
},
});
}).action;

export default ActionCard;
5 changes: 4 additions & 1 deletion packages/ui/src/components/organisms/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

export {default as ActionCard} from './ActionCard/ActionCard';
export {
default as ActionCard,
Action as ActionCardType,
} from './ActionCard/ActionCard';
export {default as AutoCompleteSearch} from './AutoCompleteSearch/AutoCompleteSearch';
export {default as CheckboxScrollList} from './CheckboxScrollList/CheckboxScrollList';
export {default as ChipSelect} from './ChipSelect/ChipSelect';
Expand Down
13 changes: 11 additions & 2 deletions packages/ui/src/components/templates/TreeView/Branch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {ActivityIndicator, StyleSheet, View} from 'react-native';
import {useThemeColor} from '../../../theme';
import {Label} from '../../molecules';
import {ActionCardType} from '../../organisms';
import BranchCard from './BranchCard';

interface SubBranchViewProps {
Expand All @@ -30,11 +31,12 @@ interface SubBranchViewProps {
setOpenBranches: (current: any) => void;
branchCardInfoButtonIndication: string;
renderBranch: (renderParams: any) => any;
getBranchActions?: (renderParams: any) => ActionCardType[];
renderLeaf: (renderParams: any) => any;
fetchBranchData: (idParent: number) => Promise<any>;
branchCondition: (item: any) => boolean;
onBranchFilterPress: (branch: any) => void;
translator?: (translationKey: string) => string;
translator: (translationKey: string) => string;
}

const SubBranchView = ({
Expand All @@ -45,6 +47,7 @@ const SubBranchView = ({
setOpenBranches,
branchCardInfoButtonIndication,
renderBranch,
getBranchActions,
renderLeaf,
fetchBranchData,
branchCondition,
Expand Down Expand Up @@ -101,6 +104,7 @@ const SubBranchView = ({
setOpenBranches={setOpenBranches}
renderBranch={renderBranch}
branchCardInfoButtonIndication={branchCardInfoButtonIndication}
getBranchActions={getBranchActions}
renderLeaf={renderLeaf}
fetchBranchData={fetchBranchData}
branchCondition={branchCondition}
Expand All @@ -123,11 +127,12 @@ interface BranchProps {
setOpenBranches: (current: any) => void;
branchCardInfoButtonIndication: string;
renderBranch: (renderParams: any) => any;
getBranchActions?: (renderParams: any) => ActionCardType[];
renderLeaf: (renderParams: any) => any;
fetchBranchData: (idParent: number) => Promise<any>;
branchCondition: (item: any) => boolean;
onBranchFilterPress: (branch: any) => void;
translator?: (translationKey: string) => string;
translator: (translationKey: string) => string;
}

const Branch = ({
Expand All @@ -138,6 +143,7 @@ const Branch = ({
setOpenBranches,
branchCardInfoButtonIndication,
renderBranch,
getBranchActions,
renderLeaf,
fetchBranchData,
branchCondition,
Expand Down Expand Up @@ -189,6 +195,8 @@ const Branch = ({
parent={branch.item}
onFilterPress={onBranchFilterPress}
infoButtonIndication={branchCardInfoButtonIndication}
actionList={getBranchActions?.(branch)}
translator={translator}
/>
{isBranchOpen && (
<SubBranchView
Expand All @@ -199,6 +207,7 @@ const Branch = ({
setOpenBranches={setOpenBranches}
renderBranch={renderBranch}
branchCardInfoButtonIndication={branchCardInfoButtonIndication}
getBranchActions={getBranchActions}
renderLeaf={renderLeaf}
fetchBranchData={fetchBranchData}
branchCondition={branchCondition}
Expand Down
Loading

0 comments on commit 9ecd41a

Please sign in to comment.