mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Refactoring VirtualList types
Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
This commit is contained in:
parent
588c6d7fec
commit
ae4dc3023c
@ -36,3 +36,4 @@ export * from "../../renderer/components/+events/kube-event-details";
|
|||||||
export * from "../../renderer/components/status-brick";
|
export * from "../../renderer/components/status-brick";
|
||||||
export { terminalStore, createTerminalTab } from "../../renderer/components/dock/terminal.store";
|
export { terminalStore, createTerminalTab } from "../../renderer/components/dock/terminal.store";
|
||||||
export { createPodLogsTab } from "../../renderer/components/dock/pod-logs.store";
|
export { createPodLogsTab } from "../../renderer/components/dock/pod-logs.store";
|
||||||
|
export { ItemObject } from "../../renderer/item.store";
|
||||||
|
|||||||
@ -73,9 +73,7 @@ export class ClusterIssues extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
getTableRow(uid: string) {
|
getTableRow(warning: IWarning) {
|
||||||
const { warnings } = this;
|
|
||||||
const warning = warnings.find(warn => warn.getId() == uid);
|
|
||||||
const { getId, getName, message, kind, selfLink } = warning;
|
const { getId, getName, message, kind, selfLink } = warning;
|
||||||
return (
|
return (
|
||||||
<TableRow
|
<TableRow
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import React from "react";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { EndpointSubset, Endpoint, EndpointAddress} from "../../api/endpoints";
|
import { EndpointSubset, Endpoint, EndpointAddress} from "../../api/endpoints";
|
||||||
import { _i18n } from "../../i18n";
|
import { _i18n } from "../../i18n";
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
|
||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
@ -20,16 +19,12 @@ interface Props {
|
|||||||
@observer
|
@observer
|
||||||
export class EndpointSubsetList extends React.Component<Props> {
|
export class EndpointSubsetList extends React.Component<Props> {
|
||||||
|
|
||||||
getAddressTableRow(ip: string) {
|
getAddressTableRow(address: EndpointAddress) {
|
||||||
const { subset } = this.props;
|
|
||||||
const address = subset.getAddresses().find(address => address.getId() == ip);
|
|
||||||
return this.renderAddressTableRow(address);
|
return this.renderAddressTableRow(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
getNotReadyAddressTableRow(ip: string) {
|
getNotReadyAddressTableRow(address: EndpointAddress) {
|
||||||
const { subset} = this.props;
|
|
||||||
const address = subset.getNotReadyAddresses().find(address => address.getId() == ip);
|
|
||||||
return this.renderAddressTableRow(address);
|
return this.renderAddressTableRow(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +47,7 @@ export class EndpointSubsetList extends React.Component<Props> {
|
|||||||
<TableCell className="target">Target</TableCell>
|
<TableCell className="target">Target</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{
|
{
|
||||||
!virtual && addresses.map(address => this.getAddressTableRow(address.getId()))
|
!virtual && addresses.map(address => this.getAddressTableRow(address))
|
||||||
}
|
}
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
@ -105,7 +100,7 @@ export class EndpointSubsetList extends React.Component<Props> {
|
|||||||
<TableCell className="host"><Trans>Hostname</Trans></TableCell>
|
<TableCell className="host"><Trans>Hostname</Trans></TableCell>
|
||||||
<TableCell className="target">Target</TableCell>
|
<TableCell className="target">Target</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{ !addressesVirtual && addresses.map(address => this.getAddressTableRow(address.getId())) }
|
{ !addressesVirtual && addresses.map(this.getAddressTableRow) }
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -126,7 +121,7 @@ export class EndpointSubsetList extends React.Component<Props> {
|
|||||||
<TableCell className="host"><Trans>Hostname</Trans></TableCell>
|
<TableCell className="host"><Trans>Hostname</Trans></TableCell>
|
||||||
<TableCell className="target">Target</TableCell>
|
<TableCell className="target">Target</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{ !notReadyAddressesVirtual && notReadyAddresses.map(address => this.getNotReadyAddressTableRow(address.getId())) }
|
{ !notReadyAddressesVirtual && notReadyAddresses.map(this.getNotReadyAddressTableRow) }
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -95,9 +95,7 @@ export class PodDetailsList extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
getTableRow(uid: string) {
|
getTableRow(pod: Pod) {
|
||||||
const { pods } = this.props;
|
|
||||||
const pod = pods.find(pod => pod.getId() == uid);
|
|
||||||
const metrics = podsStore.getPodKubeMetrics(pod);
|
const metrics = podsStore.getPodKubeMetrics(pod);
|
||||||
return (
|
return (
|
||||||
<TableRow
|
<TableRow
|
||||||
@ -146,7 +144,7 @@ export class PodDetailsList extends React.Component<Props> {
|
|||||||
<TableCell className="status"><Trans>Status</Trans></TableCell>
|
<TableCell className="status"><Trans>Status</Trans></TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{
|
{
|
||||||
!virtual && pods.map(pod => this.getTableRow(pod.getId()))
|
!virtual && pods.map(pod => this.getTableRow(pod))
|
||||||
}
|
}
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -198,15 +198,13 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
getRow(uid: string) {
|
getRow(item: ItemObject) {
|
||||||
const {
|
const {
|
||||||
isSelectable, renderTableHeader, renderTableContents, renderItemMenu,
|
isSelectable, renderTableHeader, renderTableContents, renderItemMenu,
|
||||||
store, hasDetailsView, onDetails,
|
store, hasDetailsView, onDetails,
|
||||||
copyClassNameFromHeadCells, customizeTableRowProps, detailsItem,
|
copyClassNameFromHeadCells, customizeTableRowProps, detailsItem,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { isSelected } = store;
|
const { isSelected } = store;
|
||||||
const item = this.items.find(item => item.getId() == uid);
|
|
||||||
if (!item) return;
|
|
||||||
const itemId = item.getId();
|
const itemId = item.getId();
|
||||||
return (
|
return (
|
||||||
<TableRow
|
<TableRow
|
||||||
@ -411,7 +409,7 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
|||||||
</TableHead>
|
</TableHead>
|
||||||
)}
|
)}
|
||||||
{
|
{
|
||||||
!virtual && items.map(item => this.getRow(item.getId()))
|
!virtual && items.map((item) => this.getRow(item))
|
||||||
}
|
}
|
||||||
</Table>
|
</Table>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -9,8 +9,9 @@ import { TableHead, TableHeadElem, TableHeadProps } from "./table-head";
|
|||||||
import { TableCellElem } from "./table-cell";
|
import { TableCellElem } from "./table-cell";
|
||||||
import { VirtualList } from "../virtual-list";
|
import { VirtualList } from "../virtual-list";
|
||||||
import { navigation, setQueryParams } from "../../navigation";
|
import { navigation, setQueryParams } from "../../navigation";
|
||||||
import orderBy from "lodash/orderBy";
|
|
||||||
import { ItemObject } from "../../item.store";
|
import { ItemObject } from "../../item.store";
|
||||||
|
import orderBy from "lodash/orderBy";
|
||||||
|
import debounce from "lodash/debounce";
|
||||||
|
|
||||||
// todo: refactor + decouple search from location
|
// todo: refactor + decouple search from location
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ export type TableSortParams = { sortBy: TableSortBy; orderBy: TableOrderBy };
|
|||||||
export type TableSortCallback<D = any> = (data: D) => string | number | (string | number)[];
|
export type TableSortCallback<D = any> = (data: D) => string | number | (string | number)[];
|
||||||
|
|
||||||
export interface TableProps extends React.DOMAttributes<HTMLDivElement> {
|
export interface TableProps extends React.DOMAttributes<HTMLDivElement> {
|
||||||
items?: any[]; // Raw items data
|
items?: ItemObject[]; // Raw items data
|
||||||
className?: string;
|
className?: string;
|
||||||
autoSize?: boolean; // Setup auto-sizing for all columns (flex: 1 0)
|
autoSize?: boolean; // Setup auto-sizing for all columns (flex: 1 0)
|
||||||
selectable?: boolean; // Highlight rows on hover
|
selectable?: boolean; // Highlight rows on hover
|
||||||
@ -40,7 +41,7 @@ export interface TableProps extends React.DOMAttributes<HTMLDivElement> {
|
|||||||
rowPadding?: string;
|
rowPadding?: string;
|
||||||
rowLineHeight?: string;
|
rowLineHeight?: string;
|
||||||
customRowHeights?: (item: object, lineHeight: number, paddings: number) => number;
|
customRowHeights?: (item: object, lineHeight: number, paddings: number) => number;
|
||||||
getTableRow?: (uid: string | number) => React.ReactElement<TableRowProps>;
|
getTableRow?: (item: ItemObject) => React.ReactElement<TableRowProps>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
@ -55,6 +56,8 @@ export class Table extends React.Component<TableProps> {
|
|||||||
|
|
||||||
@observable sortParamsLocal = this.props.sortByDefault;
|
@observable sortParamsLocal = this.props.sortByDefault;
|
||||||
|
|
||||||
|
private virtualListRef = React.createRef<VirtualList>();
|
||||||
|
|
||||||
@computed get sortParams(): Partial<TableSortParams> {
|
@computed get sortParams(): Partial<TableSortParams> {
|
||||||
if (this.props.sortSyncWithUrl) {
|
if (this.props.sortSyncWithUrl) {
|
||||||
const sortBy = navigation.searchParams.get("sortBy");
|
const sortBy = navigation.searchParams.get("sortBy");
|
||||||
@ -64,6 +67,19 @@ export class Table extends React.Component<TableProps> {
|
|||||||
return this.sortParamsLocal || {};
|
return this.sortParamsLocal || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.scrollToSelectedItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollToSelectedItem = debounce(() => {
|
||||||
|
const { items, selectedItemId, sortable } = this.props;
|
||||||
|
if (!selectedItemId) return;
|
||||||
|
const sortedItems = sortable ? this.getSorted(items) : items;
|
||||||
|
const index = sortedItems.findIndex(item => item.getId() == selectedItemId);
|
||||||
|
if (index === -1) return;
|
||||||
|
this.virtualListRef.current.scrollToItem(index, "start");
|
||||||
|
});
|
||||||
|
|
||||||
renderHead() {
|
renderHead() {
|
||||||
const { sortable, children } = this.props;
|
const { sortable, children } = this.props;
|
||||||
const content = React.Children.toArray(children) as (TableRowElem | TableHeadElem)[];
|
const content = React.Children.toArray(children) as (TableRowElem | TableHeadElem)[];
|
||||||
@ -162,6 +178,7 @@ export class Table extends React.Component<TableProps> {
|
|||||||
getRow={getTableRow}
|
getRow={getTableRow}
|
||||||
selectedItemId={selectedItemId}
|
selectedItemId={selectedItemId}
|
||||||
className={className}
|
className={className}
|
||||||
|
ref={this.virtualListRef}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,22 +6,19 @@ import React, { Component } from "react";
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Align, ListChildComponentProps, ListOnScrollProps, VariableSizeList } from "react-window";
|
import { Align, ListChildComponentProps, ListOnScrollProps, VariableSizeList } from "react-window";
|
||||||
import { cssNames, noop } from "../../utils";
|
import { cssNames, noop } from "../../utils";
|
||||||
import { TableRowProps } from "../table/table-row";
|
|
||||||
import { ItemObject } from "../../item.store";
|
|
||||||
import throttle from "lodash/throttle";
|
import throttle from "lodash/throttle";
|
||||||
import debounce from "lodash/debounce";
|
|
||||||
import isEqual from "lodash/isEqual";
|
import isEqual from "lodash/isEqual";
|
||||||
import ResizeSensor from "css-element-queries/src/ResizeSensor";
|
import ResizeSensor from "css-element-queries/src/ResizeSensor";
|
||||||
|
|
||||||
interface Props<T = ItemObject | any> {
|
interface Props {
|
||||||
items: T[];
|
items: any[];
|
||||||
rowHeights: number[];
|
rowHeights: number[];
|
||||||
className?: string;
|
className?: string;
|
||||||
width?: number | string;
|
width?: number | string;
|
||||||
initialOffset?: number;
|
initialOffset?: number;
|
||||||
readyOffset?: number;
|
readyOffset?: number;
|
||||||
selectedItemId?: string;
|
selectedItemId?: string;
|
||||||
getRow?: (uid: string | number) => React.ReactElement<any>;
|
getRow: (item: any) => React.ReactElement<any>;
|
||||||
onScroll?: (props: ListOnScrollProps) => void;
|
onScroll?: (props: ListOnScrollProps) => void;
|
||||||
outerRef?: React.Ref<any>
|
outerRef?: React.Ref<any>
|
||||||
}
|
}
|
||||||
@ -51,7 +48,6 @@ export class VirtualList extends Component<Props, State> {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setListHeight();
|
this.setListHeight();
|
||||||
this.scrollToSelectedItem();
|
|
||||||
new ResizeSensor(this.parentRef.current as any as Element, this.setListHeight);
|
new ResizeSensor(this.parentRef.current as any as Element, this.setListHeight);
|
||||||
this.setState({ overscanCount: this.props.readyOffset });
|
this.setState({ overscanCount: this.props.readyOffset });
|
||||||
}
|
}
|
||||||
@ -75,13 +71,6 @@ export class VirtualList extends Component<Props, State> {
|
|||||||
|
|
||||||
getItemSize = (index: number) => this.props.rowHeights[index];
|
getItemSize = (index: number) => this.props.rowHeights[index];
|
||||||
|
|
||||||
scrollToSelectedItem = debounce(() => {
|
|
||||||
if (!this.props.selectedItemId) return;
|
|
||||||
const { items, selectedItemId } = this.props;
|
|
||||||
const index = items.findIndex(item => item.getId() == selectedItemId);
|
|
||||||
if (index === -1) return;
|
|
||||||
this.listRef.current.scrollToItem(index, "start");
|
|
||||||
});
|
|
||||||
|
|
||||||
scrollToItem = (index: number, align: Align) => {
|
scrollToItem = (index: number, align: Align) => {
|
||||||
this.listRef.current.scrollToItem(index, align);
|
this.listRef.current.scrollToItem(index, align);
|
||||||
@ -115,8 +104,8 @@ export class VirtualList extends Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface RowData {
|
interface RowData {
|
||||||
items: ItemObject[];
|
items: any[];
|
||||||
getRow?: (uid: string | number) => React.ReactElement<TableRowProps>;
|
getRow?: (item: any) => React.ReactElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RowProps extends ListChildComponentProps {
|
interface RowProps extends ListChildComponentProps {
|
||||||
@ -126,8 +115,8 @@ interface RowProps extends ListChildComponentProps {
|
|||||||
const Row = observer((props: RowProps) => {
|
const Row = observer((props: RowProps) => {
|
||||||
const { index, style, data } = props;
|
const { index, style, data } = props;
|
||||||
const { items, getRow } = data;
|
const { items, getRow } = data;
|
||||||
const uid = items[index]?.getId ? items[index].getId() : index;
|
const item = items[index];
|
||||||
const row = getRow(uid);
|
const row = getRow(item);
|
||||||
if (!row) return null;
|
if (!row) return null;
|
||||||
return React.cloneElement(row, {
|
return React.cloneElement(row, {
|
||||||
style: Object.assign({}, row.props.style, style)
|
style: Object.assign({}, row.props.style, style)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user