Skip to content

Prepare SearchBar for the integration with unified resources#34402

Merged
gzdunek merged 10 commits intomasterfrom
gzdunek/prepare-search-bar
Nov 13, 2023
Merged

Prepare SearchBar for the integration with unified resources#34402
gzdunek merged 10 commits intomasterfrom
gzdunek/prepare-search-bar

Conversation

@gzdunek
Copy link
Copy Markdown
Contributor

@gzdunek gzdunek commented Nov 9, 2023

Part of #30422

I tried to explain a reason for each change in the commit message, let me know if something is unclear.
I'm going to backport this PR to v14 and v13 to make future backports easier. The change that allows selecting multiple resource filters probably won't be very useful without unified resources, but I think it is okay to backport it.

The most "controversial" may be 596e1e82ce6e0824dff34dec7ec08875c33221c6 that changes the way of rendering the search bar. It was based on a comment from Kenny, he suggested that we may wan't to switch to more "modal" version of the search bar, that is not restricted by the input width.
The biggest difference it makes when the window is narrow and the cluster selector is visible.

Before:
image

After:
image

IMO the controversial part is that the selector now opens horizontally centered, while the search input isn't centered. But I think that is fine, the command bar in VS code behaves very similarly.

Changelog: Allow selecting multiple resource filters in the search bar in Connect

This will be needed for unified resources integration,
where it is possible to select more than one filter.
Otherwise, we will have to convert the resource filter type to the type
expected by the unified resources component and vice-versa.
It is just easier to use the same type.
const [isOpen, setIsOpen] = useState(false);
const [inputValue, setInputValue] = useState('');
const [activePicker, setActivePicker] = useState(actionPicker);
// TODO(ravicious): Consider using another data structure for search filters as we know that we
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I removed the comment because now we can select multiple resource filters, and I think the current structure works quite well.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could have an object with fields clusterFilter and resourceFilters, this way you wouldn't need to do the filtering based on the type field. From what I see, 90% of the type we end up either plucking the cluster filter from the array or filtering it down just resource filters.

There rest are places which have logic like this:

// The preview should be fetched only when at least one filter is selected. Otherwise we'd send
// three requests for each connected cluster when the search bar gets open.
if (filters.length >= 1) {

It could be encapsulated in functions which work on the SearchFilters type (which would be that object with the fields I mentioned), here we could have something like hasActiveSearchFilters(filters: SearchFilters): boolean.


…aaand while writing this comment I realized what was the original requirement behind using an array – we need to keep the order of them so that if you first enter a resource filter and then a cluster filter, they're rendered in the UI in the same way.

Let's keep them this way I guess.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, the requirement to keep the filters in order didn't allow me to change the structure.

@gzdunek gzdunek requested review from avatus and ravicious November 9, 2023 17:38
@gzdunek gzdunek marked this pull request as ready for review November 9, 2023 17:38
@github-actions github-actions Bot requested review from rudream and ryanclark November 9, 2023 17:39
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Nov 9, 2023

The PR changelog entry failed validation: Changelog entry not found in the PR body. Please add a "no-changelog" label to the PR, or changelog lines starting with changelog: followed by the changelog entries for the PR.

Copy link
Copy Markdown
Member

@ravicious ravicious left a comment

Choose a reason for hiding this comment

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

Looking good. 👍

const [isOpen, setIsOpen] = useState(false);
const [inputValue, setInputValue] = useState('');
const [activePicker, setActivePicker] = useState(actionPicker);
// TODO(ravicious): Consider using another data structure for search filters as we know that we
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could have an object with fields clusterFilter and resourceFilters, this way you wouldn't need to do the filtering based on the type field. From what I see, 90% of the type we end up either plucking the cluster filter from the array or filtering it down just resource filters.

There rest are places which have logic like this:

// The preview should be fetched only when at least one filter is selected. Otherwise we'd send
// three requests for each connected cluster when the search bar gets open.
if (filters.length >= 1) {

It could be encapsulated in functions which work on the SearchFilters type (which would be that object with the fields I mentioned), here we could have something like hasActiveSearchFilters(filters: SearchFilters): boolean.


…aaand while writing this comment I realized what was the original requirement behind using an array – we need to keep the order of them so that if you first enter a resource filter and then a cluster filter, they're rendered in the UI in the same way.

Let's keep them this way I guess.

// TODO(ravicious): Accept just `server | database | kube` as searchFilter here, wrap it in a
// variant of a discriminated union in searchResult.ts.
filter: ResourceTypeSearchFilter | undefined;
filters: SupportedResourceType[] | undefined;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The filter field used to be of type ResourceTypeSearchFilter | undefined because we wanted to communicate that there might be no filter. In cases where an array is accepted, I think it's better to require the callsite to always provide an array and represent the "no filter" case by passing an empty array.

};

export type SupportedResourceType = 'kubes' | 'servers' | 'databases';
export type SupportedResourceType = 'kube_cluster' | 'node' | 'db';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could we use the Pick utility type to document that it's a subset of the type from unified resources?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That's a good idea, btw I had to use Extract utility type to make a subset of union (Pick doesn't work).

Comment on lines +183 to +185
'node' as const,
'db' as const,
'kube_cluster' as const,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

const is not needed AFAIR if you declared the type of the variable itself.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

They were needed here because the type was specified for an array that was then filtered and TS couldn't narrow down the type:

Type  string  is not assignable to type  SupportedResourceType 

I overcome this by extracting a const var:

const SUPPORTED_RESOURCE_TYPES: SupportedResourceType[] = [
  'node',
  'db',
  'kube_cluster',
];

@@ -126,7 +121,7 @@ export function ActionPicker(props: { input: ReactElement }) {
return (
<FilterButton
key="resource-type"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Keys need to be made unique, otherwise there's an error about them being the same and removing them is buggy.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Right, I forgot about this place.

<span
title={props.text}
css={`
max-width: calc(${props => props.theme.space[9]}px * 2);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we can remove max-width from here, with unified resources and the feedback we got about the connection picker we know how users feel about identifiers being cut off.

Without max-width, very long cluster names will be "naturally" cut off.

long cluster name

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done, I also removed text-overflow and overflow, they don't have any effect without max-width.

@github-actions
Copy link
Copy Markdown
Contributor

The PR changelog entry failed validation: Changelog entry not found in the PR body. Please add a "no-changelog" label to the PR, or changelog lines starting with changelog: followed by the changelog entries for the PR.

@gzdunek gzdunek added this pull request to the merge queue Nov 13, 2023
Merged via the queue into master with commit 2d83292 Nov 13, 2023
@gzdunek gzdunek deleted the gzdunek/prepare-search-bar branch November 13, 2023 11:06
@public-teleport-github-review-bot
Copy link
Copy Markdown

@gzdunek See the table below for backport results.

Branch Result
branch/v13 Create PR
branch/v14 Create PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants