Skip to content

Commit

Permalink
Simplify command panel filtering on misk web-actions
Browse files Browse the repository at this point in the history
GitOrigin-RevId: 789d81e64da07e1712c975df88d5ba20b0a63490
  • Loading branch information
aerb authored and svc-squareup-copybara committed Feb 24, 2025
1 parent 3eada58 commit 055c4fc
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 48 deletions.
14 changes: 0 additions & 14 deletions misk-admin/web-actions/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion misk-admin/web-actions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
"@chakra-ui/icons": "^2.1.1",
"@chakra-ui/react": "^2.8.2",
"ace-builds": "^1.36.2",
"fuse.js": "^7.0.0",
"react-select": "^5.8.2"
}
}
56 changes: 23 additions & 33 deletions misk-admin/web-actions/src/web-actions/ui/EndpointSelection.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from 'react';
import Select, { OnChangeValue, StylesConfig } from 'react-select';
import Fuse from 'fuse.js';
import { ActionGroup, MiskActions } from '@web-actions/api/responseTypes';
import RealMetadataClient from '@web-actions/api/RealMetadataClient';

export interface EndpointOption {
value: ActionGroup;
label: string;
lowerCaseLabel: string;
}

export type EndpointSelectionCallbacks = ((value: ActionGroup) => void)[];
Expand All @@ -17,69 +17,60 @@ interface Props {
}

interface State {
endpointOptions: EndpointOption[];
filterOptions: EndpointOption[];
filteredOptions: EndpointOption[];
inputValue: string;
menuIsOpen: boolean;
}

export default class EndpointSelection extends React.Component<Props, State> {
private selectRef = React.createRef<any>();
private fuse: Fuse<EndpointOption> | null = null;
private metadataClient = new RealMetadataClient();
private options: EndpointOption[] = [];

constructor(props: Props) {
super(props);

this.state = {
endpointOptions: [],
filterOptions: [],
filteredOptions: [],
inputValue: '',
menuIsOpen: false,
};
}

componentDidMount() {
this.metadataClient.fetchMetadata().then((actions: MiskActions) => {
const options = Object.entries(actions)
.map(([key, value]) => ({
value: value,
label: key,
}))
.sort((a, b) => a.value.name.localeCompare(b.value.name));
this.fuse = new Fuse(options, {
keys: ['label'],
useExtendedSearch: true,
});
this.setState({
endpointOptions: options,
filterOptions: options,
});
this.options = Object.values(actions)
.sort((a, b) => a.name.localeCompare(b.name))
.map((it) => ({
label: it.name,
lowerCaseLabel: it.name.toLowerCase(),
value: it,
}));
this.setState({ filteredOptions: this.options });
this.focusSelect();
});
}

componentDidUpdate(_: any, prevState: State) {
if (
prevState.inputValue !== this.state.inputValue ||
prevState.endpointOptions !== this.state.endpointOptions
) {
if (prevState.inputValue !== this.state.inputValue) {
this.updateFilterOptions();
}
}

updateFilterOptions() {
const { inputValue, endpointOptions } = this.state;
if (!inputValue.trim() || !this.fuse) {
this.setState({ filterOptions: endpointOptions });
const terms = this.state.inputValue
.split(/\s+/)
.filter((it) => it.length > 0)
.map((it) => it.toLowerCase());
if (terms.length === 0) {
this.setState({ filteredOptions: this.options });
return;
}

const results = this.fuse
.search(inputValue)
.sort((a, b) => b.score! - a.score!);
this.setState({
filterOptions: results.map((result) => result.item),
filteredOptions: this.options.filter((option) =>
terms.every((term) => option.lowerCaseLabel.includes(term)),
),
});
}

Expand Down Expand Up @@ -115,7 +106,6 @@ export default class EndpointSelection extends React.Component<Props, State> {
};

render() {
const { filterOptions } = this.state;
return (
<Select<EndpointOption, false>
ref={this.selectRef}
Expand All @@ -128,7 +118,7 @@ export default class EndpointSelection extends React.Component<Props, State> {
onMenuClose={() => this.setMenuOpen(false)}
onInputChange={this.handleInputChange}
onChange={this.handleChange}
options={filterOptions}
options={this.state.filteredOptions}
styles={
{
container: (base) => ({ ...base, width: '100%' }),
Expand Down

0 comments on commit 055c4fc

Please sign in to comment.