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

feat: forward and back buttons for organize column search #1620

Merged
20 changes: 20 additions & 0 deletions packages/components/src/SearchInput.scss
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,24 @@
border-radius: 1rem;
background-color: rgba($white, 0.25);
}

.search-change-selection {
position: absolute;
right: $spacer-1;
top: 15%;
bottom: 15%;
height: 70%;
}

.search-change-button {
background: none;
border: none;
padding: 1px 2px;
}

.search-change-text {
background-color: rgba($white, 0.2);
border-radius: 10px;
padding: 1px 5px;
}
}
57 changes: 51 additions & 6 deletions packages/components/src/SearchInput.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import React, { PureComponent } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { vsSearch } from '@deephaven/icons';
import { vsArrowLeft, vsArrowRight, vsSearch } from '@deephaven/icons';
import classNames from 'classnames';
import './SearchInput.scss';

interface QueryParams {
queriedColumnIndex: number | undefined;
changeQueriedColumnIndex: (direction: 'forward' | 'back') => void;
}
interface SearchInputProps {
value: string;
placeholder: string;
Expand All @@ -15,6 +19,7 @@ interface SearchInputProps {
matchCount: number;
id: string;
'data-testid'?: string;
queryParams?: QueryParams;
}

class SearchInput extends PureComponent<SearchInputProps> {
Expand All @@ -27,6 +32,7 @@ class SearchInput extends PureComponent<SearchInputProps> {
},
id: '',
'data-testid': undefined,
queryParams: undefined,
};

constructor(props: SearchInputProps) {
Expand All @@ -52,7 +58,9 @@ class SearchInput extends PureComponent<SearchInputProps> {
id,
onKeyDown,
'data-testid': dataTestId,
queryParams,
} = this.props;

return (
<div className={classNames('search-group', className)}>
<input
Expand All @@ -67,13 +75,50 @@ class SearchInput extends PureComponent<SearchInputProps> {
ref={this.inputField}
id={id}
data-testid={dataTestId}
style={
queryParams && {
paddingRight:
queryParams?.queriedColumnIndex !== undefined
? '6rem'
: '4.5rem',
}
}
/>
{matchCount != null && (
<span className="search-match">{matchCount}</span>

{matchCount != null && queryParams !== undefined ? (
<div className="search-change-selection">
<button
className="search-change-button"
type="button"
onClick={() => {
queryParams.changeQueriedColumnIndex('back');
}}
disabled={matchCount <= 1}
>
<FontAwesomeIcon icon={vsArrowLeft} />
</button>
<span className="search-change-text">
{queryParams.queriedColumnIndex !== undefined &&
matchCount > 1 &&
`${queryParams.queriedColumnIndex + 1} of `}
{matchCount}
</span>
<button
className="search-change-button"
type="button"
onClick={() => {
queryParams.changeQueriedColumnIndex('forward');
}}
disabled={matchCount <= 1}
>
<FontAwesomeIcon icon={vsArrowRight} />
</button>
</div>
) : (
<span className="search-icon">
<FontAwesomeIcon icon={vsSearch} />
</span>
)}
<span className="search-icon">
<FontAwesomeIcon icon={vsSearch} />
</span>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ interface VisibilityOrderingBuilderProps {

interface VisibilityOrderingBuilderState {
selectedColumns: Set<string>;
queriedColumnIndex: number | undefined;
prevQueriedColumns: string[] | undefined;
lastSelectedColumn: string;
searchFilter: string;
}
Expand Down Expand Up @@ -100,6 +102,8 @@ class VisibilityOrderingBuilder extends Component<

this.state = {
selectedColumns: new Set(),
queriedColumnIndex: undefined,
prevQueriedColumns: undefined,
lastSelectedColumn: '',
searchFilter: '',
};
Expand All @@ -125,6 +129,8 @@ class VisibilityOrderingBuilder extends Component<

this.setState({
selectedColumns: new Set(),
queriedColumnIndex: undefined,
prevQueriedColumns: undefined,
lastSelectedColumn: '',
searchFilter: '',
});
Expand All @@ -135,7 +141,12 @@ class VisibilityOrderingBuilder extends Component<
}

resetSelection(): void {
this.setState({ selectedColumns: new Set(), lastSelectedColumn: '' });
this.setState({
selectedColumns: new Set(),
queriedColumnIndex: undefined,
prevQueriedColumns: undefined,
lastSelectedColumn: '',
});
}

handleSearchInputChange(event: ChangeEvent<HTMLInputElement>): void {
Expand Down Expand Up @@ -168,6 +179,50 @@ class VisibilityOrderingBuilder extends Component<
this.list?.querySelectorAll('.item-wrapper')[visibleIndexToFocus];
columnItemToFocus?.scrollIntoView({ block: 'center' });
}

this.setState({
prevQueriedColumns: columnsMatch,
queriedColumnIndex: undefined,
});
}

/**
* Change the selected column to either the next or previous column
*
* @param direction The direction to move the selection
*/

changeSelectedColumn(direction: 'forward' | 'back'): void {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i feel this could use a better name but not too sure what. This does change the selected column as the name implies but only from the previously queried list

const { queriedColumnIndex, prevQueriedColumns } = this.state;
let newQueriedColumnIndex = queriedColumnIndex;

if (prevQueriedColumns === undefined) return;

if (direction === 'forward') {
if (
newQueriedColumnIndex === undefined ||
newQueriedColumnIndex >= prevQueriedColumns.length - 1
) {
newQueriedColumnIndex = 0;
} else {
newQueriedColumnIndex += 1;
}
} else if (direction === 'back') {
if (newQueriedColumnIndex === undefined || newQueriedColumnIndex <= 0) {
newQueriedColumnIndex = prevQueriedColumns.length - 1;
} else {
newQueriedColumnIndex -= 1;
}
}

this.addColumnToSelected(
[prevQueriedColumns[newQueriedColumnIndex as number]],
false
);

this.setState({
queriedColumnIndex: newQueriedColumnIndex,
});
}

/**
Expand Down Expand Up @@ -1015,7 +1070,12 @@ class VisibilityOrderingBuilder extends Component<

render(): ReactElement {
const { model, hiddenColumns, onColumnVisibilityChanged } = this.props;
const { selectedColumns, searchFilter } = this.state;
const {
selectedColumns,
searchFilter,
prevQueriedColumns,
queriedColumnIndex,
} = this.state;
const hasSelection = selectedColumns.size > 0;
const treeItems = this.getTreeItems();
const nameToIndexes = new Map(
Expand Down Expand Up @@ -1049,6 +1109,14 @@ class VisibilityOrderingBuilder extends Component<
treeItems
);

const queryParams = {
Copy link
Contributor Author

@ethanalvizo ethanalvizo Nov 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i thought this would be nicer to pass in to SearchInput rather than creating two new optional props that would only be used by VisibilityOrderingBuilder. Could revert to that if preferred though

queriedColumnIndex,
changeQueriedColumnIndex: (direction: 'forward' | 'back') =>
this.changeSelectedColumn(direction),
};

const matchCount = prevQueriedColumns?.length;

return (
<div role="menu" className="visibility-ordering-builder" tabIndex={0}>
<div className="top-menu">
Expand All @@ -1067,8 +1135,9 @@ class VisibilityOrderingBuilder extends Component<
<SearchInput
className="visibility-search"
value={searchFilter}
matchCount={searchFilter ? selectedColumns.size : undefined}
matchCount={searchFilter ? matchCount : undefined}
onChange={this.handleSearchInputChange}
queryParams={queryParams}
/>
</div>
<div className="top-menu">
Expand Down
Loading