Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/node list index #2178

Merged
merged 21 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions src/components/filters/filters-group/filters-group.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,7 @@ import { getDataTestAttribute } from '../../../utils/get-data-test-attribute';
import './filters-group.scss';

/** A group collection of FiltersRow */
const FiltersGroup = ({
items = [],
group,
collapsed,
onItemClick,
onItemChange,
}) => (
const FiltersGroup = ({ items = [], group, collapsed, onItemChange }) => (
<LazyList
height={(start, end) => (end - start) * nodeListRowHeight}
total={items.length}
Expand All @@ -40,8 +34,8 @@ const FiltersGroup = ({
kind={group.kind}
label={item.highlightedLabel}
name={item.name}
onChange={(e) => onItemChange(item, !e.target.checked)}
onClick={() => onItemClick(item)}
onChange={(e) => onItemChange(e, item)}
onClick={(e) => onItemChange(e, item)}
parentClassName={'node-list-filter-row'}
visible={item.visible}
indicatorIcon={item.visibleIcon}
Expand Down
2 changes: 1 addition & 1 deletion src/components/filters/filters-group/filters-group.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@use '../../../styles/variables' as var;
@use '../../node-list/styles/variables';
@use '../../node-list-tree/styles/variables';

.filters-group {
list-style: none;
Expand Down
2 changes: 1 addition & 1 deletion src/components/filters/filters-group/filters-group.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import FiltersGroup from './filters-group';
import { mockState, setup } from '../../../utils/state.mock';
import { getNodeTypes } from '../../../selectors/node-types';
import { getGroupedNodes } from '../../../selectors/nodes';
import { getGroups } from '../../node-list/node-list-items';
import { getGroups } from '../../../selectors/filtered-node-list-items';

describe('FiltersGroup Component', () => {
const mockProps = () => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/filters/filters-row/filters-row.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@use '../../../styles/variables' as var;
@use '../../node-list/styles/variables';
@use '../../node-list-tree/styles/variables';

.MuiTreeItem-iconContainer svg {
z-index: var.$zindex-MuiTreeItem-icon;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@use '../../../styles/variables' as var;
@use '../../node-list/styles/variables';
@use '../../node-list-tree/styles/variables';

.filters-section-heading {
background: var(--color-nodelist-filter-panel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import FiltersSectionHeading from './filters-section-heading';
import { mockState, setup } from '../../../utils/state.mock';
import { getNodeTypes } from '../../../selectors/node-types';
import { getGroupedNodes } from '../../../selectors/nodes';
import { getGroups } from '../../node-list/node-list-items';
import { getGroups } from '../../../selectors/filtered-node-list-items';

describe('FiltersSectionHeading', () => {
const mockProps = () => {
Expand Down
6 changes: 0 additions & 6 deletions src/components/filters/filters-section/filters-section.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ const FiltersSection = ({
items,
onGroupToggleChanged,
onItemChange,
onItemClick,
onItemMouseEnter,
onItemMouseLeave,
onToggleGroupCollapsed,
searchValue,
}) => {
Expand All @@ -41,9 +38,6 @@ const FiltersSection = ({
group={group}
items={groupItems}
onItemChange={onItemChange}
onItemClick={onItemClick}
onItemMouseEnter={onItemMouseEnter}
onItemMouseLeave={onItemMouseLeave}
/>
</li>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import FiltersSection from './filters-section';
import { mockState, setup } from '../../../utils/state.mock';
import { getNodeTypes } from '../../../selectors/node-types';
import { getGroupedNodes } from '../../../selectors/nodes';
import { getGroups } from '../../node-list/node-list-items';
import { getGroups } from '../../../selectors/filtered-node-list-items';

describe('FiltersSection Component', () => {
const mockProps = () => {
Expand Down
6 changes: 0 additions & 6 deletions src/components/filters/filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ const Filters = ({
items,
onGroupToggleChanged,
onItemChange,
onItemClick,
onItemMouseEnter,
onItemMouseLeave,
onResetFilter,
onToggleGroupCollapsed,
searchValue,
Expand Down Expand Up @@ -41,9 +38,6 @@ const Filters = ({
key={group.id}
onGroupToggleChanged={onGroupToggleChanged}
onItemChange={onItemChange}
onItemClick={onItemClick}
onItemMouseEnter={onItemMouseEnter}
onItemMouseLeave={onItemMouseLeave}
onToggleGroupCollapsed={onToggleGroupCollapsed}
searchValue={searchValue}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/components/filters/filters.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@use '../node-list/styles/variables';
@use '../node-list-tree/styles/variables';
@use '../../styles/extends';
@use '../../styles/variables' as colors;

Expand Down
2 changes: 1 addition & 1 deletion src/components/filters/filters.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Filters from './filters';
import { mockState, setup } from '../../utils/state.mock';
import { getNodeTypes } from '../../selectors/node-types';
import { getGroupedNodes } from '../../selectors/nodes';
import { getGroups } from '../node-list/node-list-items';
import { getGroups } from '../../selectors/filtered-node-list-items';

describe('Filters', () => {
const mockProps = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React from 'react';
import classnames from 'classnames';
import NodeIcon from '../../../icons/node-icon';
import VisibleIcon from '../../../icons/visible';
import InvisibleIcon from '../../../icons/invisible';
import FocusModeIcon from '../../../icons/focus-mode';
import { ToggleControl } from '../../../ui/toggle-control/toggle-control';
import { RowText } from '../../../ui/row-text/row-text';
import NodeIcon from '../../icons/node-icon';
import VisibleIcon from '../../icons/visible';
import InvisibleIcon from '../../icons/invisible';
import FocusModeIcon from '../../icons/focus-mode';
import { ToggleControl } from '../../ui/toggle-control/toggle-control';
import { RowText } from '../../ui/row-text/row-text';

import './row.scss';
import './node-list-row.scss';

const Row = ({
const NodeListRow = ({
active,
checked,
children,
Expand Down Expand Up @@ -44,24 +44,34 @@ const Row = ({

return (
<form
className={classnames('row kedro', `row--kind-${kind}`, parentClassName, {
'row--active': active,
'row--selected': selected || (!isSlicingPipelineApplied && highlight),
'row--overwrite': !(active || selected),
})}
className={classnames(
'node-list-row kedro',
`node-list-row--kind-${kind}`,
parentClassName,
{
'node-list-row--active': active,
'node-list-row--selected':
selected || (!isSlicingPipelineApplied && highlight),
'node-list-row--overwrite': !(active || selected),
}
)}
data-test={dataTest}
title={name}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
>
<NodeIcon
className={classnames('row__type-icon', 'row__icon', {
'row__type-icon--faded': faded,
'row__type-icon--disabled': disabled,
'row__type-icon--nested': !children,
'row__type-icon--active': active,
'row__type-icon--selected': selected,
})}
className={classnames(
'node-list-row__type-icon',
'node-list-row__icon',
{
'node-list-row__type-icon--faded': faded,
'node-list-row__type-icon--disabled': disabled,
'node-list-row__type-icon--nested': !children,
'node-list-row__type-icon--active': active,
'node-list-row__type-icon--selected': selected,
}
)}
icon={icon}
/>
<RowText
Expand All @@ -78,7 +88,7 @@ const Row = ({
/>
{VisibilityIcon && (
<ToggleControl
className={'row__icon'}
className={'node-list-row__icon'}
disabled={isModularPipeline ? focused : disabled}
focusChecked={isModularPipeline ? false : focused}
IconComponent={VisibilityIcon}
Expand All @@ -92,7 +102,7 @@ const Row = ({
)}
{FocusIcon && (
<ToggleControl
className={'row__icon'}
className={'node-list-row__icon'}
disabled={disabled}
focusChecked={focused}
IconComponent={FocusIcon}
Expand All @@ -110,4 +120,4 @@ const Row = ({
);
};

export default Row;
export default NodeListRow;
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
@use '../../../../styles/variables' as var;
@use '../../styles/variables';
@use '../../../styles/variables' as var;
@use '../../node-list-tree/styles/variables' as variables;

.MuiTreeItem-iconContainer svg {
z-index: var.$zindex-MuiTreeItem-icon;
}

.row {
.node-list-row {
align-items: center;
cursor: default;
display: flex;
Expand All @@ -14,6 +14,10 @@
transform: translate(0, 0);

&:hover,
&--active {
background-color: var(--color-nodelist-row-selected);
}

&--selected {
// Additional selector required to increase specificity to override previous rule
background-color: var(--color-nodelist-row-selected);
Expand All @@ -36,18 +40,18 @@
}

.MuiTreeItem-content:hover {
.row__type-icon path {
.node-list-row__type-icon path {
opacity: 1;
}
}

.row--active::before,
.row--selected::before,
.row:hover::before {
.node-list-row--active::before,
.node-list-row--selected::before,
.node-list-row:hover::before {
opacity: 1;
}

.row__icon {
.node-list-row__icon {
display: block;
flex-shrink: 0;
width: variables.$row-icon-size;
Expand All @@ -59,7 +63,7 @@
}
}

.row__type-icon {
.node-list-row__type-icon {
&--nested > * {
opacity: 0.3;
}
Expand All @@ -70,8 +74,8 @@

&--active,
&--selected,
.row--visible:hover &,
[data-whatintent='keyboard'] .row__text:focus & {
.node-list-row--visible:hover &,
[data-whatintent='keyboard'] .node-list-row__text:focus & {
> * {
opacity: 1;
}
Expand Down
78 changes: 78 additions & 0 deletions src/components/node-list-tree/node-list-row/node-list-row.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from 'react';
import NodeListRow from './node-list-row';
import { setup } from '../../../utils/state.mock';

// Mock props
const mockProps = {
name: 'Test Row',
kind: 'modular-pipeline',
active: false,
disabled: false,
selected: false,
visible: true,
onMouseEnter: jest.fn(),
onMouseLeave: jest.fn(),
onClick: jest.fn(),
icon: null,
type: 'modularPipeline',
checked: true,
focused: false,
};

describe('NodeListRow Component', () => {
it('renders without crashing', () => {
expect(() => setup.mount(<NodeListRow {...mockProps} />)).not.toThrow();
});

it('handles mouseenter events', () => {
const wrapper = setup.mount(<NodeListRow {...mockProps} />);
const nodeRow = () => wrapper.find('.node-list-row');
nodeRow().simulate('mouseenter');
expect(mockProps.onMouseEnter.mock.calls.length).toEqual(1);
});

it('handles mouseleave events', () => {
const wrapper = setup.mount(<NodeListRow {...mockProps} />);
const nodeRow = () => wrapper.find('.node-list-row');
nodeRow().simulate('mouseleave');
expect(mockProps.onMouseLeave.mock.calls.length).toEqual(1);
});

it('applies the node-list-row--active class when active is true', () => {
const wrapper = setup.mount(<NodeListRow {...mockProps} active={true} />);
expect(
wrapper.find('.node-list-row').hasClass('node-list-row--active')
).toBe(true);
});

it('applies the node-list-row--selected class when selected is true', () => {
const wrapper = setup.mount(<NodeListRow {...mockProps} selected={true} />);
expect(
wrapper.find('.node-list-row').hasClass('node-list-row--selected')
).toBe(true);
});

it('applies the node-list-row--selected class when highlight is true and isSlicingPipelineApplied is false', () => {
const wrapper = setup.mount(
<NodeListRow
{...mockProps}
highlight={true}
isSlicingPipelineApplied={false}
/>
);
expect(
wrapper.find('.node-list-row').hasClass('node-list-row--selected')
).toBe(true);
});

it('applies the overwrite class if not selected or active', () => {
const activeNodeWrapper = setup.mount(
<NodeListRow {...mockProps} selected={false} active={false} />
);
expect(
activeNodeWrapper
.find('.node-list-row')
.hasClass('node-list-row--overwrite')
).toBe(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import classnames from 'classnames';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import { TreeItem } from '@mui/x-tree-view';
import Row from './components/row/row';
import { getDataTestAttribute } from '../../utils/get-data-test-attribute';
import NodeListRow from '../node-list-row/node-list-row';
import { getDataTestAttribute } from '../../../utils/get-data-test-attribute';

const arrowIconColor = '#8e8e90';

Expand All @@ -29,7 +29,7 @@ const NodeListTreeItem = ({
collapseIcon={<ExpandMoreIcon style={{ color: arrowIconColor }} />}
expandIcon={<ChevronRightIcon style={{ color: arrowIconColor }} />}
label={
<Row
<NodeListRow
active={data.active}
checked={data.checked}
dataTest={getDataTestAttribute('node-list-tree-item', 'row')}
Expand Down
Loading
Loading