mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Remove Namespace filter from ItemListLayout (#2952)
This commit is contained in:
parent
d21f99e609
commit
cb4a7497dd
@ -26,8 +26,6 @@ import { observer } from "mobx-react";
|
|||||||
import { components, PlaceholderProps } from "react-select";
|
import { components, PlaceholderProps } from "react-select";
|
||||||
|
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { FilterIcon } from "../item-object-list/filter-icon";
|
|
||||||
import { FilterType } from "../item-object-list/page-filters.store";
|
|
||||||
import { NamespaceSelect } from "./namespace-select";
|
import { NamespaceSelect } from "./namespace-select";
|
||||||
import { namespaceStore } from "./namespace.store";
|
import { namespaceStore } from "./namespace.store";
|
||||||
|
|
||||||
@ -63,7 +61,7 @@ export class NamespaceSelectFilter extends React.Component<SelectProps> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex gaps align-center">
|
<div className="flex gaps align-center">
|
||||||
<FilterIcon type={FilterType.NAMESPACE}/>
|
<Icon small material="layers" />
|
||||||
<span>{namespace}</span>
|
<span>{namespace}</span>
|
||||||
{isSelected && <Icon small material="check" className="box right"/>}
|
{isSelected && <Icon small material="check" className="box right"/>}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -31,9 +31,6 @@ export function FilterIcon(props: Props) {
|
|||||||
const { type, ...iconProps } = props;
|
const { type, ...iconProps } = props;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case FilterType.NAMESPACE:
|
|
||||||
return <Icon small material="layers" {...iconProps}/>;
|
|
||||||
|
|
||||||
case FilterType.SEARCH:
|
case FilterType.SEARCH:
|
||||||
return <Icon small material="search" {...iconProps}/>;
|
return <Icon small material="search" {...iconProps}/>;
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,6 @@ import type { ItemObject, ItemStore } from "../../item.store";
|
|||||||
import { SearchInputUrl } from "../input";
|
import { SearchInputUrl } from "../input";
|
||||||
import { Filter, FilterType, pageFilters } from "./page-filters.store";
|
import { Filter, FilterType, pageFilters } from "./page-filters.store";
|
||||||
import { PageFiltersList } from "./page-filters-list";
|
import { PageFiltersList } from "./page-filters-list";
|
||||||
import { PageFiltersSelect } from "./page-filters-select";
|
|
||||||
import { ThemeStore } from "../../theme.store";
|
import { ThemeStore } from "../../theme.store";
|
||||||
import { MenuActions } from "../menu/menu-actions";
|
import { MenuActions } from "../menu/menu-actions";
|
||||||
import { MenuItem } from "../menu";
|
import { MenuItem } from "../menu";
|
||||||
@ -179,16 +178,6 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
|||||||
|
|
||||||
return items;
|
return items;
|
||||||
},
|
},
|
||||||
|
|
||||||
[FilterType.NAMESPACE]: items => {
|
|
||||||
const filterValues = pageFilters.getValues(FilterType.NAMESPACE);
|
|
||||||
|
|
||||||
if (filterValues.length > 0) {
|
|
||||||
return items.filter(item => filterValues.includes(item.getNs()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@computed get isReady() {
|
@computed get isReady() {
|
||||||
@ -401,14 +390,7 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
|||||||
const placeholders: IHeaderPlaceholders = {
|
const placeholders: IHeaderPlaceholders = {
|
||||||
title: <h5 className="title">{title}</h5>,
|
title: <h5 className="title">{title}</h5>,
|
||||||
info: this.renderInfo(),
|
info: this.renderInfo(),
|
||||||
filters: (
|
filters: showNamespaceSelectFilter && <NamespaceSelectFilter />,
|
||||||
<>
|
|
||||||
{showNamespaceSelectFilter && <NamespaceSelectFilter />}
|
|
||||||
<PageFiltersSelect allowEmpty disableFilters={{
|
|
||||||
[FilterType.NAMESPACE]: true, // namespace-select used instead
|
|
||||||
}} />
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
search: <SearchInputUrl />,
|
search: <SearchInputUrl />,
|
||||||
};
|
};
|
||||||
let header = this.renderHeaderContent(placeholders);
|
let header = this.renderHeaderContent(placeholders);
|
||||||
|
|||||||
@ -1,136 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2021 OpenLens Authors
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
|
||||||
* the Software without restriction, including without limitation the rights to
|
|
||||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import { observer } from "mobx-react";
|
|
||||||
import { computed, makeObservable } from "mobx";
|
|
||||||
import { GroupSelectOption, Select, SelectOption, SelectProps } from "../select";
|
|
||||||
import { FilterType, pageFilters } from "./page-filters.store";
|
|
||||||
import { namespaceStore } from "../+namespaces/namespace.store";
|
|
||||||
import { Icon } from "../icon";
|
|
||||||
import { FilterIcon } from "./filter-icon";
|
|
||||||
|
|
||||||
export interface SelectOptionFilter extends SelectOption {
|
|
||||||
type: FilterType;
|
|
||||||
selected?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Props extends SelectProps {
|
|
||||||
allowEmpty?: boolean;
|
|
||||||
disableFilters?: {
|
|
||||||
[filterType: string]: boolean;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@observer
|
|
||||||
export class PageFiltersSelect extends React.Component<Props> {
|
|
||||||
static defaultProps: Props = {
|
|
||||||
allowEmpty: true,
|
|
||||||
disableFilters: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props: Props) {
|
|
||||||
super(props);
|
|
||||||
makeObservable(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@computed get groupedOptions() {
|
|
||||||
const options: GroupSelectOption<SelectOptionFilter>[] = [];
|
|
||||||
const { disableFilters } = this.props;
|
|
||||||
|
|
||||||
if (!disableFilters[FilterType.NAMESPACE]) {
|
|
||||||
const selectedValues = pageFilters.getValues(FilterType.NAMESPACE);
|
|
||||||
|
|
||||||
options.push({
|
|
||||||
label: "Namespace",
|
|
||||||
options: namespaceStore.items.map(ns => {
|
|
||||||
const name = ns.getName();
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: FilterType.NAMESPACE,
|
|
||||||
value: name,
|
|
||||||
icon: <Icon small material="layers"/>,
|
|
||||||
selected: selectedValues.includes(name),
|
|
||||||
};
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
@computed get options(): SelectOptionFilter[] {
|
|
||||||
return this.groupedOptions.reduce((options, optGroup) => {
|
|
||||||
options.push(...optGroup.options);
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}, []);
|
|
||||||
}
|
|
||||||
|
|
||||||
private formatLabel = (option: SelectOptionFilter) => {
|
|
||||||
const { label, value, type, selected } = option;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex gaps">
|
|
||||||
<FilterIcon type={type}/>
|
|
||||||
<span>{label || String(value)}</span>
|
|
||||||
{selected && <Icon small material="check" className="box right"/>}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
private onSelect = (option: SelectOptionFilter) => {
|
|
||||||
const { type, value, selected } = option;
|
|
||||||
const { addFilter, removeFilter } = pageFilters;
|
|
||||||
const filter = { type, value };
|
|
||||||
|
|
||||||
if (!selected) {
|
|
||||||
addFilter(filter);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
removeFilter(filter);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { groupedOptions, formatLabel, onSelect, options } = this;
|
|
||||||
|
|
||||||
if (!options.length && this.props.allowEmpty) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const { allowEmpty, disableFilters, ...selectProps } = this.props;
|
|
||||||
const selectedOptions = options.filter(opt => opt.selected);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Select
|
|
||||||
{...selectProps}
|
|
||||||
placeholder={`Filters (${selectedOptions.length}/${options.length})`}
|
|
||||||
noOptionsMessage={() => `No filters available.`}
|
|
||||||
autoConvertOptions={false}
|
|
||||||
tabSelectsValue={false}
|
|
||||||
controlShouldRenderValue={false}
|
|
||||||
options={groupedOptions}
|
|
||||||
formatOptionLabel={formatLabel}
|
|
||||||
onChange={onSelect}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -25,7 +25,6 @@ import { searchUrlParam } from "../input/search-input-url";
|
|||||||
|
|
||||||
export enum FilterType {
|
export enum FilterType {
|
||||||
SEARCH = "search",
|
SEARCH = "search",
|
||||||
NAMESPACE = "namespace",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Filter {
|
export interface Filter {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user