Skip to content

Commit

Permalink
refactor: extract ResourceTitleBar component
Browse files Browse the repository at this point in the history
  • Loading branch information
devcatalin committed Sep 29, 2023
1 parent 553ada1 commit 0e3ca0d
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 140 deletions.
147 changes: 7 additions & 140 deletions src/components/organisms/NavigatorPane/NavigatorPane.tsx
Original file line number Diff line number Diff line change
@@ -1,59 +1,23 @@
import {useCallback, useMemo} from 'react';

import {Dropdown, Tooltip} from 'antd';

import AntdIcon from '@ant-design/icons';

import styled from 'styled-components';

import {TOOLTIP_DELAY} from '@constants/constants';
import {
CollapseResourcesTooltip,
DisabledAddResourceTooltip,
ExpandResourcesTooltip,
NewResourceTooltip,
} from '@constants/tooltips';
import {useCallback} from 'react';

import {useAppDispatch, useAppSelector} from '@redux/hooks';
import {collapseResourceKinds, expandResourceKinds, toggleResourceFilters} from '@redux/reducers/ui';
import {activeResourceCountSelector, navigatorResourceKindsSelector} from '@redux/selectors/resourceMapSelectors';
import {toggleResourceFilters} from '@redux/reducers/ui';

import {CheckedResourcesActionsMenu, ResourceFilter} from '@molecules';

import {CollapseIcon, ExpandIcon} from '@components/atoms/Icons';
import {TitleBarWrapper} from '@components/atoms/StyledComponents/TitleBarWrapper';

import {useNewResourceMenuItems} from '@hooks/menuItemsHooks';

import {useSelectorWithRef} from '@utils/hooks';

import {TitleBar} from '@monokle/components';
import {ROOT_FILE_ENTRY} from '@shared/constants/fileEntry';
import {Colors} from '@shared/styles';
import {trackEvent} from '@shared/utils';
import {isInClusterModeSelector, isInPreviewModeSelector} from '@shared/utils/selectors';

import NavigatorDescription from './NavigatorDescription';
import * as S from './NavigatorPane.styled';
import ResourceNavigator from './ResourceNavigator';
import {ResourceTitleBar} from './ResourceTitleBar';

import * as S from './styled';

const NavPane: React.FC = () => {
const dispatch = useAppDispatch();

const checkedResourceIdentifiers = useAppSelector(state => state.main.checkedResourceIdentifiers);
const isFolderOpen = useAppSelector(state => Boolean(state.main.fileMap[ROOT_FILE_ENTRY]));
const isInClusterMode = useAppSelector(isInClusterModeSelector);
const isInPreviewMode = useAppSelector(isInPreviewModeSelector);

const isPreviewLoading = useAppSelector(state => state.main.previewOptions.isLoading);
const isResourceFiltersOpen = useAppSelector(state => state.ui.isResourceFiltersOpen);

const newResourceMenuItems = useNewResourceMenuItems();

const isAddResourceDisabled = useMemo(
() => !isFolderOpen || isInPreviewMode || isInClusterMode,
[isFolderOpen, isInClusterMode, isInPreviewMode]
);

const resourceFilterButtonHandler = useCallback(() => {
dispatch(toggleResourceFilters());
}, [dispatch]);
Expand All @@ -65,46 +29,7 @@ const NavPane: React.FC = () => {
<CheckedResourcesActionsMenu />
</S.SelectionBar>
) : (
<TitleBarWrapper $navigator>
<TitleBar
type="secondary"
title="Kubernetes Resources"
description={<NavigatorDescription />}
descriptionStyle={{paddingTop: '5px'}}
actions={
<S.TitleBarRightButtons>
<CollapseAction />

<Dropdown
trigger={['click']}
menu={{items: newResourceMenuItems}}
overlayClassName="dropdown-secondary"
disabled={isAddResourceDisabled}
>
<Tooltip
mouseEnterDelay={TOOLTIP_DELAY}
title={
isAddResourceDisabled
? DisabledAddResourceTooltip({
type: isInClusterMode ? 'cluster' : isInPreviewMode ? 'preview' : 'other',
})
: NewResourceTooltip
}
>
<S.NewButton
id="create-resource-button"
disabled={isAddResourceDisabled}
size="small"
type="primary"
>
New
</S.NewButton>
</Tooltip>
</Dropdown>
</S.TitleBarRightButtons>
}
/>
</TitleBarWrapper>
<ResourceTitleBar />
)}

<ResourceFilter active={isResourceFiltersOpen} onToggle={resourceFilterButtonHandler} />
Expand All @@ -117,61 +42,3 @@ const NavPane: React.FC = () => {
};

export default NavPane;

function CollapseAction() {
const dispatch = useAppDispatch();
const [hasAnyActiveResources, hasAnyActiveResourcesRef] = useSelectorWithRef(
state => activeResourceCountSelector(state) > 0
);

const [collapsedKinds, collapsedKindsRef] = useSelectorWithRef(s => s.ui.navigator.collapsedResourceKinds);
const [navigatorKinds, navigatorKindsRef] = useSelectorWithRef(navigatorResourceKindsSelector);

const isCollapsed = useMemo(
() => collapsedKinds.length === navigatorKinds.length,
[collapsedKinds.length, navigatorKinds.length]
);

const onClick = useCallback(() => {
if (!hasAnyActiveResourcesRef.current) {
return;
}

if (collapsedKindsRef.current.length === navigatorKindsRef.current.length) {
dispatch(expandResourceKinds(navigatorKindsRef.current));
trackEvent('navigator/expand_all');
return;
}

dispatch(collapseResourceKinds(navigatorKindsRef.current));
trackEvent('navigator/collapse_all');
}, [hasAnyActiveResourcesRef, collapsedKindsRef, navigatorKindsRef, dispatch]);

return (
<>
<Tooltip mouseEnterDelay={TOOLTIP_DELAY} title={isCollapsed ? ExpandResourcesTooltip : CollapseResourcesTooltip}>
{isCollapsed ? (
<StyledFullscreenOutlined component={ExpandIcon} onClick={onClick} $disabled={!hasAnyActiveResources} />
) : (
<StyledFullscreenExitOutlined component={CollapseIcon} onClick={onClick} $disabled={!hasAnyActiveResources} />
)}
</Tooltip>
</>
);
}

// Styled Components

const StyledFullscreenOutlined = styled(AntdIcon)<{$disabled: boolean}>`
color: ${({$disabled}) => ($disabled ? Colors.grey6 : Colors.blue6)};
cursor: ${({$disabled}) => ($disabled ? 'not-allowed' : 'pointer')};
padding-right: 10px;
font-size: 16px;
`;

const StyledFullscreenExitOutlined = styled(AntdIcon)<{$disabled: boolean}>`
color: ${({$disabled}) => ($disabled ? Colors.grey6 : Colors.blue6)};
cursor: ${({$disabled}) => ($disabled ? 'not-allowed' : 'pointer')};
padding-right: 10px;
font-size: 16px;
`;
122 changes: 122 additions & 0 deletions src/components/organisms/NavigatorPane/ResourceTitleBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import {useCallback, useMemo} from 'react';

import {Dropdown, Tooltip} from 'antd';

import {TOOLTIP_DELAY} from '@constants/constants';
import {
CollapseResourcesTooltip,
DisabledAddResourceTooltip,
ExpandResourcesTooltip,
NewResourceTooltip,
} from '@constants/tooltips';

import {useAppDispatch, useAppSelector} from '@redux/hooks';
import {collapseResourceKinds, expandResourceKinds} from '@redux/reducers/ui';
import {activeResourceCountSelector, navigatorResourceKindsSelector} from '@redux/selectors/resourceMapSelectors';

import {TitleBarWrapper} from '@components/atoms';
import {CollapseIcon, ExpandIcon} from '@components/atoms/Icons';

import {useNewResourceMenuItems} from '@hooks/menuItemsHooks';

import {useSelectorWithRef} from '@utils/hooks';

import {TitleBar} from '@monokle/components';
import {ROOT_FILE_ENTRY} from '@shared/constants/fileEntry';
import {isInClusterModeSelector, isInPreviewModeSelector, trackEvent} from '@shared/utils';

import NavigatorDescription from './NavigatorDescription';

import * as S from './styled';

export const ResourceTitleBar = () => {
const isFolderOpen = useAppSelector(state => Boolean(state.main.fileMap[ROOT_FILE_ENTRY]));
const isInClusterMode = useAppSelector(isInClusterModeSelector);
const isInPreviewMode = useAppSelector(isInPreviewModeSelector);

const newResourceMenuItems = useNewResourceMenuItems();

const isAddResourceDisabled = useMemo(
() => !isFolderOpen || isInPreviewMode || isInClusterMode,
[isFolderOpen, isInClusterMode, isInPreviewMode]
);
return (
<TitleBarWrapper $navigator>
<TitleBar
type="secondary"
title="Kubernetes Resources"
description={<NavigatorDescription />}
descriptionStyle={{paddingTop: '5px'}}
actions={
<S.TitleBarRightButtons>
<CollapseAction />

<Dropdown
trigger={['click']}
menu={{items: newResourceMenuItems}}
overlayClassName="dropdown-secondary"
disabled={isAddResourceDisabled}
>
<Tooltip
mouseEnterDelay={TOOLTIP_DELAY}
title={
isAddResourceDisabled
? DisabledAddResourceTooltip({
type: isInClusterMode ? 'cluster' : isInPreviewMode ? 'preview' : 'other',
})
: NewResourceTooltip
}
>
<S.NewButton id="create-resource-button" disabled={isAddResourceDisabled} size="small" type="primary">
New
</S.NewButton>
</Tooltip>
</Dropdown>
</S.TitleBarRightButtons>
}
/>
</TitleBarWrapper>
);
};

function CollapseAction() {
const dispatch = useAppDispatch();
const [hasAnyActiveResources, hasAnyActiveResourcesRef] = useSelectorWithRef(
state => activeResourceCountSelector(state) > 0
);

const [collapsedKinds, collapsedKindsRef] = useSelectorWithRef(s => s.ui.navigator.collapsedResourceKinds);
const [navigatorKinds, navigatorKindsRef] = useSelectorWithRef(navigatorResourceKindsSelector);

const isCollapsed = useMemo(
() => collapsedKinds.length === navigatorKinds.length,
[collapsedKinds.length, navigatorKinds.length]
);

const onClick = useCallback(() => {
if (!hasAnyActiveResourcesRef.current) {
return;
}

if (collapsedKindsRef.current.length === navigatorKindsRef.current.length) {
dispatch(expandResourceKinds(navigatorKindsRef.current));
trackEvent('navigator/expand_all');
return;
}

dispatch(collapseResourceKinds(navigatorKindsRef.current));
trackEvent('navigator/collapse_all');
}, [hasAnyActiveResourcesRef, collapsedKindsRef, navigatorKindsRef, dispatch]);

return (
<>
<Tooltip mouseEnterDelay={TOOLTIP_DELAY} title={isCollapsed ? ExpandResourcesTooltip : CollapseResourcesTooltip}>
{isCollapsed ? (
<S.FullscreenOutlined component={ExpandIcon} onClick={onClick} $disabled={!hasAnyActiveResources} />
) : (
<S.FullscreenExitOutlined component={CollapseIcon} onClick={onClick} $disabled={!hasAnyActiveResources} />
)}
</Tooltip>
</>
);
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import AntdIcon from '@ant-design/icons';

import styled from 'styled-components';

import {DEFAULT_PANE_TITLE_HEIGHT} from '@constants/constants';
Expand Down Expand Up @@ -56,3 +58,17 @@ export const TitleBarRightButtons = styled.div`
display: flex;
align-items: center;
`;

export const FullscreenOutlined = styled(AntdIcon)<{$disabled: boolean}>`
color: ${({$disabled}) => ($disabled ? Colors.grey6 : Colors.blue6)};
cursor: ${({$disabled}) => ($disabled ? 'not-allowed' : 'pointer')};
padding-right: 10px;
font-size: 16px;
`;

export const FullscreenExitOutlined = styled(AntdIcon)<{$disabled: boolean}>`
color: ${({$disabled}) => ($disabled ? Colors.grey6 : Colors.blue6)};
cursor: ${({$disabled}) => ($disabled ? 'not-allowed' : 'pointer')};
padding-right: 10px;
font-size: 16px;
`;

0 comments on commit 0e3ca0d

Please sign in to comment.