mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix item list layout header rendering bug
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
9746309949
commit
cf033adc2f
@ -1,17 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
import { observer } from "mobx-react";
|
|
||||||
import React from "react";
|
|
||||||
import type { HeaderPlaceholders } from "./list-layout";
|
|
||||||
|
|
||||||
export interface ItemListLayoutHeaderFiltersProps {
|
|
||||||
headerPlaceholders: HeaderPlaceholders
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ItemListLayoutHeaderFilters = observer(({ headerPlaceholders }: ItemListLayoutHeaderFiltersProps) => (
|
|
||||||
<>
|
|
||||||
{headerPlaceholders.filters}
|
|
||||||
</>
|
|
||||||
));
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
import React from "react";
|
|
||||||
import { observer } from "mobx-react";
|
|
||||||
import type { ItemObject, ItemStore } from "../../../common/item.store";
|
|
||||||
import type { Filter } from "./page-filters.store";
|
|
||||||
import type { HeaderPlaceholders } from "./list-layout";
|
|
||||||
|
|
||||||
interface ItemListLayoutHeaderInfoProps<I extends ItemObject> {
|
|
||||||
headerPlaceholders: HeaderPlaceholders;
|
|
||||||
getItems: () => I[];
|
|
||||||
store: ItemStore<I>;
|
|
||||||
getFilters: () => Filter[]
|
|
||||||
toggleFilters: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ItemListLayoutHeaderInfo = observer(<I extends ItemObject>({
|
|
||||||
headerPlaceholders,
|
|
||||||
getItems,
|
|
||||||
getFilters,
|
|
||||||
store,
|
|
||||||
toggleFilters,
|
|
||||||
}: ItemListLayoutHeaderInfoProps<I>) => {
|
|
||||||
const renderInfo = () => {
|
|
||||||
const allItemsCount = store.getTotalCount();
|
|
||||||
const itemsCount = getItems().length;
|
|
||||||
|
|
||||||
if (getFilters().length > 0) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<a onClick={toggleFilters}>Filtered</a>: {itemsCount} / {allItemsCount}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return allItemsCount === 1
|
|
||||||
? `${allItemsCount} item`
|
|
||||||
: `${allItemsCount} items`;
|
|
||||||
};
|
|
||||||
|
|
||||||
const info = headerPlaceholders.info ?? renderInfo();
|
|
||||||
|
|
||||||
if (!info) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="info-panel box grow">
|
|
||||||
{info}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
import { observer } from "mobx-react";
|
|
||||||
import type { ItemObject } from "../../../common/item.store";
|
|
||||||
import { SearchInputUrl } from "../input";
|
|
||||||
import React from "react";
|
|
||||||
import type { HeaderPlaceholders, SearchFilter } from "./list-layout";
|
|
||||||
|
|
||||||
interface ItemListLayoutHeaderSearchProps<I extends ItemObject> {
|
|
||||||
searchFilters: SearchFilter<I>[];
|
|
||||||
headerPlaceholders: HeaderPlaceholders;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ItemListLayoutHeaderSearch = observer(<I extends ItemObject>({
|
|
||||||
searchFilters,
|
|
||||||
headerPlaceholders = {},
|
|
||||||
}: ItemListLayoutHeaderSearchProps<I>) => {
|
|
||||||
const { searchProps } = headerPlaceholders;
|
|
||||||
|
|
||||||
if (searchFilters.length === 0 || !searchProps) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <SearchInputUrl {...searchProps} />;
|
|
||||||
});
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
import { observer } from "mobx-react";
|
|
||||||
import React from "react";
|
|
||||||
import type { HeaderPlaceholders } from "./list-layout";
|
|
||||||
|
|
||||||
interface ItemListLayoutHeaderTitleProps {
|
|
||||||
renderHeaderTitle: React.ReactNode | (() => React.ReactNode);
|
|
||||||
headerPlaceholders: HeaderPlaceholders;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ItemListLayoutHeaderTitle = observer(({ renderHeaderTitle, headerPlaceholders }: ItemListLayoutHeaderTitleProps) => {
|
|
||||||
if (headerPlaceholders.title) {
|
|
||||||
return <>{headerPlaceholders.title}</>;
|
|
||||||
}
|
|
||||||
|
|
||||||
const title =
|
|
||||||
typeof renderHeaderTitle === "function"
|
|
||||||
? renderHeaderTitle()
|
|
||||||
: renderHeaderTitle;
|
|
||||||
|
|
||||||
return <h5 className="title">{title}</h5>;
|
|
||||||
});
|
|
||||||
@ -10,11 +10,8 @@ import { observer } from "mobx-react";
|
|||||||
import { cssNames, IClassName } from "../../utils";
|
import { cssNames, IClassName } from "../../utils";
|
||||||
import type { ItemObject, ItemStore } from "../../../common/item.store";
|
import type { ItemObject, ItemStore } from "../../../common/item.store";
|
||||||
import type { Filter } from "./page-filters.store";
|
import type { Filter } from "./page-filters.store";
|
||||||
import { ItemListLayoutHeaderTitle } from "./header-title";
|
import type { HeaderCustomizer, HeaderPlaceholders, SearchFilter } from "./list-layout";
|
||||||
import { ItemListLayoutHeaderInfo } from "./header-info";
|
import { SearchInputUrl } from "../input";
|
||||||
import { ItemListLayoutHeaderFilters } from "./header-filters";
|
|
||||||
import { ItemListLayoutHeaderSearch } from "./header-search";
|
|
||||||
import type { HeaderCustomizer, SearchFilter } from "./list-layout";
|
|
||||||
|
|
||||||
export interface ItemListLayoutHeaderProps<I extends ItemObject> {
|
export interface ItemListLayoutHeaderProps<I extends ItemObject> {
|
||||||
getItems: () => I[];
|
getItems: () => I[];
|
||||||
@ -54,37 +51,54 @@ export class ItemListLayoutHeader<I extends ItemObject> extends React.Component<
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const customizeHeaders = [customizeHeader].flat().filter(Boolean);
|
const renderInfo = () => {
|
||||||
|
const allItemsCount = store.getTotalCount();
|
||||||
|
const itemsCount = getItems().length;
|
||||||
|
|
||||||
const headerPlaceholders = customizeHeaders.reduce(
|
if (getFilters().length > 0) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<a onClick={toggleFilters}>Filtered</a>: {itemsCount} / {allItemsCount}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return allItemsCount === 1
|
||||||
|
? `${allItemsCount} item`
|
||||||
|
: `${allItemsCount} items`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const customizeHeaderFunctions = [customizeHeader].flat().filter(Boolean);
|
||||||
|
const renderedTitle = typeof renderHeaderTitle === "function"
|
||||||
|
? renderHeaderTitle(this)
|
||||||
|
: renderHeaderTitle;
|
||||||
|
|
||||||
|
const {
|
||||||
|
filters,
|
||||||
|
info,
|
||||||
|
searchProps,
|
||||||
|
title,
|
||||||
|
} = customizeHeaderFunctions.reduce<HeaderPlaceholders>(
|
||||||
(prevPlaceholders, customizer) => customizer(prevPlaceholders),
|
(prevPlaceholders, customizer) => customizer(prevPlaceholders),
|
||||||
{},
|
{
|
||||||
|
title: <h5 className="title">{renderedTitle}</h5>,
|
||||||
|
info: renderInfo(),
|
||||||
|
searchProps: {},
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className={cssNames("header flex gaps align-center", headerClassName)}>
|
||||||
className={cssNames("header flex gaps align-center", headerClassName)}
|
{title}
|
||||||
>
|
{
|
||||||
<ItemListLayoutHeaderTitle
|
info && (
|
||||||
renderHeaderTitle={renderHeaderTitle}
|
<div className="info-panel box grow">
|
||||||
headerPlaceholders={headerPlaceholders}
|
{info}
|
||||||
/>
|
</div>
|
||||||
|
)
|
||||||
<ItemListLayoutHeaderInfo
|
}
|
||||||
headerPlaceholders={headerPlaceholders}
|
{filters}
|
||||||
getItems={getItems}
|
{searchFilters.length > 0 && searchProps && <SearchInputUrl {...searchProps} />}
|
||||||
store={store}
|
|
||||||
getFilters={getFilters}
|
|
||||||
toggleFilters={toggleFilters}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ItemListLayoutHeaderFilters headerPlaceholders={headerPlaceholders} />
|
|
||||||
|
|
||||||
<ItemListLayoutHeaderSearch
|
|
||||||
headerPlaceholders={headerPlaceholders}
|
|
||||||
searchFilters={searchFilters}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user