From 75a96e5c5da3811975d8e05f7f4f8e4e44548ef4 Mon Sep 17 00:00:00 2001 From: Catalin <20538711+devcatalin@users.noreply.github.com> Date: Thu, 17 Feb 2022 18:20:06 +0200 Subject: [PATCH 1/2] feat: name weight & size options for section headers --- .../molecules/SectionRenderer/SectionHeader.tsx | 2 ++ src/components/molecules/SectionRenderer/styled.tsx | 9 +++++++-- src/models/navigator.ts | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/molecules/SectionRenderer/SectionHeader.tsx b/src/components/molecules/SectionRenderer/SectionHeader.tsx index 1fa18fac35..a89957dfdb 100644 --- a/src/components/molecules/SectionRenderer/SectionHeader.tsx +++ b/src/components/molecules/SectionRenderer/SectionHeader.tsx @@ -119,6 +119,8 @@ function SectionHeader(props: SectionHeaderProps) { $isHighlighted={sectionInstance.isSelected && isCollapsed} $isCheckable={Boolean(sectionInstance.checkable)} $nameColor={sectionBlueprint.customization?.nameColor} + $nameSize={sectionBlueprint.customization?.nameSize} + $nameWeight={sectionBlueprint.customization?.nameWeight} $level={level} onClick={toggleCollapse} > diff --git a/src/components/molecules/SectionRenderer/styled.tsx b/src/components/molecules/SectionRenderer/styled.tsx index 2abac6db28..bd7c55c306 100644 --- a/src/components/molecules/SectionRenderer/styled.tsx +++ b/src/components/molecules/SectionRenderer/styled.tsx @@ -85,6 +85,8 @@ type NameProps = { $isCheckable?: boolean; $level: number; $nameColor?: string; + $nameSize?: number; + $nameWeight?: number; }; export const Name = styled.span` @@ -94,9 +96,11 @@ export const Name = styled.span` padding-left: 5px; cursor: pointer; ${props => { + if (props.$nameSize) { + return `font-size: ${props.$nameSize}px;`; + } return `font-size: ${24 - 4 * props.$level}px;`; }} - ${props => { if (props.$isSelected) { return `font-weight: 700;`; @@ -109,8 +113,9 @@ export const Name = styled.span` if (props.$isSelected) { return `color: ${Colors.blackPure};`; } - return props.$nameColor ? `color: ${props.$nameColor}` : `color: ${Colors.whitePure};`; + return props.$nameColor ? `color: ${props.$nameColor};` : `color: ${Colors.whitePure};`; }} + ${props => props.$nameWeight && `font-weight: ${props.$nameWeight};`} `; export const EmptyGroupText = styled.p` diff --git a/src/models/navigator.ts b/src/models/navigator.ts index 252e1773bb..f760a7be88 100644 --- a/src/models/navigator.ts +++ b/src/models/navigator.ts @@ -68,6 +68,8 @@ export interface SectionCustomization { /** Number of pixels to indent this section, by default all sections/susections are aligned */ indentation?: number; nameColor?: string; + nameSize?: number; + nameWeight?: number; emptyGroupText?: string; disableHoverStyle?: boolean; beforeInitializationText?: string; From ecf107c6cadbea298f044e34807ee28354065fd9 Mon Sep 17 00:00:00 2001 From: Catalin <20538711+devcatalin@users.noreply.github.com> Date: Thu, 17 Feb 2022 20:19:32 +0200 Subject: [PATCH 2/2] refactor: helm chart sections styling --- .../SectionRenderer/SectionHeader.tsx | 17 ++++++--- .../molecules/SectionRenderer/styled.tsx | 7 +++- .../useSectionCustomization.ts | 8 +++- src/models/navigator.ts | 6 +++ .../CollapseSectionPrefix.tsx | 36 ++++++++++++++++++ .../FileItemPrefix.tsx | 32 ++++++++++++++++ .../HelmChartSectionBlueprint.ts | 37 ++++++++++++++++--- .../RootHelmChartsSectionBlueprint.ts | 1 + 8 files changed, 131 insertions(+), 13 deletions(-) create mode 100644 src/navsections/HelmChartSectionBlueprint/CollapseSectionPrefix.tsx create mode 100644 src/navsections/HelmChartSectionBlueprint/FileItemPrefix.tsx diff --git a/src/components/molecules/SectionRenderer/SectionHeader.tsx b/src/components/molecules/SectionRenderer/SectionHeader.tsx index a89957dfdb..c0c34c9827 100644 --- a/src/components/molecules/SectionRenderer/SectionHeader.tsx +++ b/src/components/molecules/SectionRenderer/SectionHeader.tsx @@ -35,7 +35,7 @@ function SectionHeader(props: SectionHeaderProps) { const dispatch = useAppDispatch(); const [isHovered, setIsHovered] = useState(false); - const {NameDisplay, NameSuffix, NameContext} = useSectionCustomization(sectionBlueprint.customization); + const {NameDisplay, NamePrefix, NameSuffix, NameContext} = useSectionCustomization(sectionBlueprint.customization); const toggleCollapse = useCallback(() => { if (isCollapsed) { @@ -111,9 +111,12 @@ function SectionHeader(props: SectionHeaderProps) { )} {NameDisplay.Component ? ( - + ) : ( <> + {NamePrefix.Component && ( + + )} @@ -128,14 +133,16 @@ function SectionHeader(props: SectionHeaderProps) { {counter && {counter}} - {NameSuffix.Component && NameSuffix.options?.isVisibleOnHover && isHovered && ( - + {NameSuffix.Component && (NameSuffix.options?.isVisibleOnHover ? isHovered : true) && ( + )} )} - {!NameDisplay.Component && NameContext.Component && } + {!NameDisplay.Component && NameContext.Component && ( + + )} ); diff --git a/src/components/molecules/SectionRenderer/styled.tsx b/src/components/molecules/SectionRenderer/styled.tsx index bd7c55c306..ff1d9d664a 100644 --- a/src/components/molecules/SectionRenderer/styled.tsx +++ b/src/components/molecules/SectionRenderer/styled.tsx @@ -87,13 +87,18 @@ type NameProps = { $nameColor?: string; $nameSize?: number; $nameWeight?: number; + $nameVerticalPadding?: number; + $nameHorizontalPadding?: number; }; export const Name = styled.span` overflow: hidden; text-overflow: ellipsis; white-space: nowrap; - padding-left: 5px; + ${props => + `padding: ${props.$nameVerticalPadding !== undefined ? props.$nameVerticalPadding : 0}px ${ + props.$nameHorizontalPadding !== undefined ? props.$nameHorizontalPadding : 5 + }px;`} cursor: pointer; ${props => { if (props.$nameSize) { diff --git a/src/components/molecules/SectionRenderer/useSectionCustomization.ts b/src/components/molecules/SectionRenderer/useSectionCustomization.ts index 2fcc50d48a..3286abad93 100644 --- a/src/components/molecules/SectionRenderer/useSectionCustomization.ts +++ b/src/components/molecules/SectionRenderer/useSectionCustomization.ts @@ -4,6 +4,12 @@ import {SectionCustomization} from '@models/navigator'; export function useSectionCustomization(customization: SectionCustomization = {}) { const NameDisplay = useMemo(() => ({Component: customization.nameDisplay?.component}), [customization.nameDisplay]); + const NamePrefix = useMemo( + () => ({ + Component: customization.namePrefix?.component, + }), + [customization.namePrefix] + ); const NameSuffix = useMemo( () => ({ Component: customization.nameSuffix?.component, @@ -17,5 +23,5 @@ export function useSectionCustomization(customization: SectionCustomization = {} ); const NameContext = useMemo(() => ({Component: customization.nameContext?.component}), [customization.nameContext]); - return {NameDisplay, EmptyDisplay, NameSuffix, NameContext}; + return {NameDisplay, EmptyDisplay, NamePrefix, NameSuffix, NameContext}; } diff --git a/src/models/navigator.ts b/src/models/navigator.ts index f760a7be88..14ecb509bf 100644 --- a/src/models/navigator.ts +++ b/src/models/navigator.ts @@ -43,6 +43,7 @@ export interface ItemCustomization { export type SectionCustomComponentProps = { sectionInstance: SectionInstance; + onClick?: () => void; }; export type SectionCustomComponent = React.ComponentType; @@ -63,6 +64,9 @@ export interface SectionCustomization { nameContext?: { component: SectionCustomComponent; }; + namePrefix?: { + component: SectionCustomComponent; + }; /** If no value is provided, default value will be "descendants" */ counterDisplayMode?: 'descendants' | 'items' | 'subsections' | 'none'; /** Number of pixels to indent this section, by default all sections/susections are aligned */ @@ -70,6 +74,8 @@ export interface SectionCustomization { nameColor?: string; nameSize?: number; nameWeight?: number; + nameHorizontalPadding?: number; + nameVerticalPadding?: number; emptyGroupText?: string; disableHoverStyle?: boolean; beforeInitializationText?: string; diff --git a/src/navsections/HelmChartSectionBlueprint/CollapseSectionPrefix.tsx b/src/navsections/HelmChartSectionBlueprint/CollapseSectionPrefix.tsx new file mode 100644 index 0000000000..d6c39675e2 --- /dev/null +++ b/src/navsections/HelmChartSectionBlueprint/CollapseSectionPrefix.tsx @@ -0,0 +1,36 @@ +import {useMemo} from 'react'; + +import {MinusSquareOutlined, PlusSquareOutlined} from '@ant-design/icons'; + +import {SectionCustomComponentProps} from '@models/navigator'; + +import {useAppSelector} from '@redux/hooks'; + +import Colors from '@styles/Colors'; + +const CollapseSectionPrefix = (props: SectionCustomComponentProps) => { + const {sectionInstance, onClick} = props; + + const isSectionCollapsed = useAppSelector(state => state.navigator.collapsedSectionIds.includes(sectionInstance.id)); + + const iconProps = useMemo(() => { + return { + style: { + color: sectionInstance.isSelected && isSectionCollapsed ? Colors.blackPure : Colors.grey9, + marginLeft: 4, + marginRight: 8, + }, + fontSize: 10, + cursor: 'pointer', + onClick, + }; + }, [sectionInstance.isSelected, isSectionCollapsed, onClick]); + + if (isSectionCollapsed) { + return ; + } + + return ; +}; + +export default CollapseSectionPrefix; diff --git a/src/navsections/HelmChartSectionBlueprint/FileItemPrefix.tsx b/src/navsections/HelmChartSectionBlueprint/FileItemPrefix.tsx new file mode 100644 index 0000000000..3d679eed71 --- /dev/null +++ b/src/navsections/HelmChartSectionBlueprint/FileItemPrefix.tsx @@ -0,0 +1,32 @@ +import {useMemo} from 'react'; + +import {FileOutlined} from '@ant-design/icons'; + +import {ItemCustomComponentProps} from '@models/navigator'; + +import Colors from '@styles/Colors'; + +const FileItemPrefix = (props: ItemCustomComponentProps) => { + const {itemInstance} = props; + + const {fileItemPrefixStyle} = itemInstance.meta; + + const style = useMemo(() => { + const baseStyle = { + marginLeft: 4, + marginRight: 8, + color: itemInstance.isSelected ? Colors.blackPure : Colors.whitePure, + }; + if (fileItemPrefixStyle) { + return { + ...baseStyle, + ...fileItemPrefixStyle, + }; + } + return baseStyle; + }, [fileItemPrefixStyle, itemInstance.isSelected]); + + return ; +}; + +export default FileItemPrefix; diff --git a/src/navsections/HelmChartSectionBlueprint/HelmChartSectionBlueprint.ts b/src/navsections/HelmChartSectionBlueprint/HelmChartSectionBlueprint.ts index 7d0fe835fa..cf7411ff81 100644 --- a/src/navsections/HelmChartSectionBlueprint/HelmChartSectionBlueprint.ts +++ b/src/navsections/HelmChartSectionBlueprint/HelmChartSectionBlueprint.ts @@ -8,6 +8,8 @@ import {selectFile, selectHelmValuesFile} from '@redux/reducers/main'; import Colors from '@styles/Colors'; +import CollapseSectionPrefix from './CollapseSectionPrefix'; +import FileItemPrefix from './FileItemPrefix'; import HelmChartQuickAction from './HelmChartQuickAction'; export type ValuesFilesScopeType = { @@ -15,6 +17,7 @@ export type ValuesFilesScopeType = { previewValuesFileId: string | undefined; isInClusterMode: boolean; isFolderOpen: boolean; + selectedPath: string | undefined; }; type HelmChartScopeType = { @@ -39,6 +42,7 @@ export function makeHelmChartSectionBlueprint(helmChart: HelmChart) { : false, previewValuesFileId: state.main.previewValuesFileId, isFolderOpen: Boolean(state.main.fileMap[ROOT_FILE_ENTRY]), + selectedPath: state.main.selectedPath, }; }, builder: { @@ -56,18 +60,31 @@ export function makeHelmChartSectionBlueprint(helmChart: HelmChart) { }, customization: { counterDisplayMode: 'items', - indentation: 8, - nameColor: Colors.grey400, + indentation: 10, + nameWeight: 400, + nameSize: 14, + nameColor: Colors.grey9, + nameHorizontalPadding: 0, + namePrefix: { + component: CollapseSectionPrefix, + }, }, itemBlueprint: { getName: rawItem => rawItem.name, getInstanceId: rawItem => rawItem.id, builder: { - isSelected: rawItem => { - return rawItem.isSelected; + isSelected: (rawItem, scope) => { + return rawItem.filePath === scope.selectedPath; }, isDisabled: (rawItem, scope) => Boolean((scope.previewValuesFileId && scope.previewValuesFileId !== rawItem.id) || scope.isInClusterMode), + getMeta: () => { + return { + fileItemPrefixStyle: { + paddingLeft: 10, + }, + }; + }, }, instanceHandler: { onClick: (itemInstance, dispatch) => { @@ -79,6 +96,9 @@ export function makeHelmChartSectionBlueprint(helmChart: HelmChart) { component: HelmChartQuickAction, options: {isVisibleOnHover: true}, }, + prefix: { + component: FileItemPrefix, + }, }, }, }; @@ -100,7 +120,6 @@ export function makeHelmChartSectionBlueprint(helmChart: HelmChart) { [helmChart.id]: state.main.helmChartMap[helmChart.id], }; }, - builder: { transformName: (_, scope) => { const currentHelmChart = scope[helmChart.id] as HelmChart | undefined; @@ -139,10 +158,16 @@ export function makeHelmChartSectionBlueprint(helmChart: HelmChart) { dispatch(selectFile({filePath})); }, }, + customization: { + prefix: {component: FileItemPrefix}, + }, }, customization: { counterDisplayMode: 'none', - indentation: 8, + indentation: 0, + nameWeight: 600, + nameSize: 14, + nameColor: Colors.grey9, }, }; diff --git a/src/navsections/HelmChartSectionBlueprint/RootHelmChartsSectionBlueprint.ts b/src/navsections/HelmChartSectionBlueprint/RootHelmChartsSectionBlueprint.ts index 409f9a7021..706ac6b5da 100644 --- a/src/navsections/HelmChartSectionBlueprint/RootHelmChartsSectionBlueprint.ts +++ b/src/navsections/HelmChartSectionBlueprint/RootHelmChartsSectionBlueprint.ts @@ -57,6 +57,7 @@ const RootHelmChartsSectionBlueprint: SectionBlueprint