mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
refactoring & fixes
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
85ddcb47b4
commit
3b40f044b4
@ -14,9 +14,6 @@
|
||||
.VirtualList {
|
||||
height: 100%;
|
||||
|
||||
.list {
|
||||
overflow-x: scroll!important;
|
||||
|
||||
.LogRow {
|
||||
padding: 2px 16px;
|
||||
height: 18px; // Must be equal to lineHeight variable in pod-log-list.tsx
|
||||
@ -51,7 +48,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.isLoading {
|
||||
cursor: wait;
|
||||
|
||||
@ -407,10 +407,12 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
||||
)}
|
||||
{renderTableHeader.map((cellProps, index) => {
|
||||
if (!this.isHiddenColumn(cellProps)) {
|
||||
const storageId = cellProps.id ?? cellProps.storageId;
|
||||
|
||||
return (
|
||||
<TableCell
|
||||
key={cellProps.id ?? cellProps.storageId ?? index}
|
||||
storageId={cellProps.storageId}
|
||||
key={storageId ?? index}
|
||||
storageId={storageId}
|
||||
tableId={tableId} {...cellProps}
|
||||
/>
|
||||
);
|
||||
|
||||
@ -19,8 +19,37 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.warning {
|
||||
flex: 0 0 40px !important;
|
||||
}
|
||||
|
||||
&.resizable {
|
||||
position: relative; // required for resizing-anchor with `position:absolute`
|
||||
min-width: 50px;
|
||||
|
||||
> .ResizingAnchor {
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
.TableHead:hover & {
|
||||
> .ResizingAnchor {
|
||||
opacity: .25;
|
||||
|
||||
&:hover {
|
||||
opacity: .75;
|
||||
}
|
||||
|
||||
&:after {
|
||||
font: 20px "Material Icons";
|
||||
content: "compress";
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: 10px;
|
||||
transform: rotate(90deg);
|
||||
transform-origin: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.resizing {
|
||||
filter: invert(50%);
|
||||
|
||||
@ -27,9 +27,9 @@ export interface TableCellProps extends React.DOMAttributes<HTMLDivElement> {
|
||||
title?: ReactNode;
|
||||
/**
|
||||
* Allow to resize width and save to local storage, default: true
|
||||
* (applicable only with props.id)
|
||||
*/
|
||||
isResizable?: boolean;
|
||||
onResizeEnd?: () => void;
|
||||
checkbox?: boolean; // render cell with a checkbox
|
||||
isChecked?: boolean; // mark checkbox as checked or not
|
||||
renderBoolean?: boolean; // show "true" or "false" for all of the children elements are "typeof boolean"
|
||||
@ -43,7 +43,7 @@ export interface TableCellProps extends React.DOMAttributes<HTMLDivElement> {
|
||||
|
||||
@observer
|
||||
export class TableCell extends React.Component<TableCellProps> {
|
||||
private elem: HTMLElement;
|
||||
@observable.ref elem?: HTMLElement;
|
||||
|
||||
static defaultProps: TableCellProps = {
|
||||
isResizable: true,
|
||||
@ -97,7 +97,9 @@ export class TableCell extends React.Component<TableCellProps> {
|
||||
}
|
||||
|
||||
@computed get columnSize(): number {
|
||||
return getColumnSize(this.props.tableId, this.columnId) ?? 0;
|
||||
const savedSize = getColumnSize(this.props.tableId, this.columnId);
|
||||
|
||||
return savedSize ?? this.elem?.offsetWidth;
|
||||
}
|
||||
|
||||
@computed get isResizable(): boolean {
|
||||
@ -113,6 +115,7 @@ export class TableCell extends React.Component<TableCellProps> {
|
||||
|
||||
if (this.isResizable && this.columnSize) {
|
||||
styles.flexGrow = 0;
|
||||
styles.flexShrink = 0;
|
||||
styles.flexBasis = this.columnSize;
|
||||
}
|
||||
|
||||
@ -123,10 +126,20 @@ export class TableCell extends React.Component<TableCellProps> {
|
||||
onResize(extent: number) {
|
||||
const { tableId } = this.props;
|
||||
const { columnId } = this;
|
||||
const size = extent || this.elem?.offsetWidth;
|
||||
|
||||
// persist state in storage
|
||||
setColumnSize({ tableId, columnId, size });
|
||||
setColumnSize({ tableId, columnId, size: extent });
|
||||
}
|
||||
|
||||
@autobind()
|
||||
onResizeStart() {
|
||||
this.isResizing = true;
|
||||
}
|
||||
|
||||
@autobind()
|
||||
onResizeEnd() {
|
||||
this.isResizing = false;
|
||||
this.props.onResizeEnd?.();
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@ -136,7 +149,7 @@ export class TableCell extends React.Component<TableCellProps> {
|
||||
|
||||
render() {
|
||||
const {
|
||||
className, checkbox, isChecked, isResizable, sortBy,
|
||||
className, checkbox, isChecked, isResizable, sortBy, onResizeEnd,
|
||||
_sort, _sorting, _nowrap, children, title, tableId, storageId,
|
||||
renderBoolean: displayBoolean, showWithColumn,
|
||||
...cellProps
|
||||
@ -147,7 +160,7 @@ export class TableCell extends React.Component<TableCellProps> {
|
||||
nowrap: _nowrap,
|
||||
sorting: this.isSortable,
|
||||
resizing: this.isResizing,
|
||||
resizable: isResizable,
|
||||
resizable: this.isResizable,
|
||||
});
|
||||
const content = displayBooleans(displayBoolean, title || children);
|
||||
|
||||
@ -158,12 +171,13 @@ export class TableCell extends React.Component<TableCellProps> {
|
||||
{this.renderSortIcon()}
|
||||
{this.isResizable && (
|
||||
<ResizingAnchor
|
||||
minExtent={50}
|
||||
direction={ResizeDirection.HORIZONTAL}
|
||||
placement={ResizeSide.TRAILING}
|
||||
growthDirection={ResizeGrowthDirection.LEFT_TO_RIGHT}
|
||||
getCurrentExtent={() => this.columnSize}
|
||||
onStart={() => this.isResizing = true}
|
||||
onEnd={() => this.isResizing = false}
|
||||
onStart={this.onResizeStart}
|
||||
onEnd={this.onResizeEnd}
|
||||
onDrag={this.onResize}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -10,6 +10,7 @@ export interface TableHeadProps extends React.DOMAttributes<HTMLDivElement> {
|
||||
showTopLine?: boolean; // show border line at the top
|
||||
sticky?: boolean; // keep header on top when scrolling
|
||||
nowrap?: boolean; // white-space: nowrap, align inner <TableCell> in one line
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
|
||||
export class TableHead extends React.Component<TableHeadProps> {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import "./table.scss";
|
||||
|
||||
import React from "react";
|
||||
import { orderBy } from "lodash";
|
||||
import { orderBy, throttle } from "lodash";
|
||||
import { observer } from "mobx-react";
|
||||
import { observable } from "mobx";
|
||||
import { autobind, cssNames, noop } from "../../utils";
|
||||
@ -57,6 +57,8 @@ export const orderByUrlParam = createPageParam({
|
||||
|
||||
@observer
|
||||
export class Table extends React.Component<TableProps> {
|
||||
@observable.ref elemRef = React.createRef<HTMLDivElement>();
|
||||
|
||||
static defaultProps: TableProps = {
|
||||
scrollable: true,
|
||||
autoSize: true,
|
||||
@ -73,6 +75,14 @@ export class Table extends React.Component<TableProps> {
|
||||
this.props.sortByDefault,
|
||||
);
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener("resize", this.refreshDimensions);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener("resize", this.refreshDimensions);
|
||||
}
|
||||
|
||||
renderHead() {
|
||||
const { sortable, children } = this.props;
|
||||
const content = React.Children.toArray(children) as (TableRowElem | TableHeadElem)[];
|
||||
@ -83,6 +93,10 @@ export class Table extends React.Component<TableProps> {
|
||||
const columns = React.Children.toArray(headElem.props.children) as TableCellElem[];
|
||||
|
||||
return React.cloneElement(headElem, {
|
||||
style: {
|
||||
...(headElem.props.style ?? {}),
|
||||
width: this.contentWidth,
|
||||
},
|
||||
children: columns.map(elem => {
|
||||
if (elem.props.checkbox) {
|
||||
return elem;
|
||||
@ -98,6 +112,10 @@ export class Table extends React.Component<TableProps> {
|
||||
_sort: this.sort,
|
||||
_sorting: this.sortParams,
|
||||
_nowrap: headElem.props.nowrap,
|
||||
onResizeEnd: () => {
|
||||
elem.props.onResizeEnd?.();
|
||||
this.refreshDimensions();
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
@ -180,6 +198,10 @@ export class Table extends React.Component<TableProps> {
|
||||
getRow={getTableRow}
|
||||
selectedItemId={selectedItemId}
|
||||
className={className}
|
||||
// must match to table's content width for proper scrolling header and virtual-list items.
|
||||
// required if some column(s) are resized and overall content-area more than 100%.
|
||||
// why: table & virtual-list has own scrolling areas and table-head is sticky..
|
||||
width={this.contentWidth}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -187,16 +209,25 @@ export class Table extends React.Component<TableProps> {
|
||||
return rows;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { selectable, scrollable, sortable, autoSize, virtual } = this.props;
|
||||
let { className } = this.props;
|
||||
@observable refreshKey: number;
|
||||
|
||||
className = cssNames("Table flex column", className, {
|
||||
get contentWidth() {
|
||||
return this.elemRef.current?.scrollWidth;
|
||||
}
|
||||
|
||||
refreshDimensions = throttle(() => {
|
||||
// using "full refresh" with changing "key" as this.forceUpdate() don't update some internals
|
||||
this.refreshKey = Math.random();
|
||||
}, 250);
|
||||
|
||||
render() {
|
||||
const { selectable, scrollable, sortable, autoSize, virtual, className } = this.props;
|
||||
const classNames = cssNames("Table flex column", className, {
|
||||
selectable, scrollable, sortable, autoSize, virtual,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<div key={this.refreshKey} className={classNames} ref={this.elemRef}>
|
||||
{this.renderHead()}
|
||||
{this.renderRows()}
|
||||
</div>
|
||||
|
||||
@ -1,7 +1,4 @@
|
||||
.VirtualList {
|
||||
overflow: hidden;
|
||||
|
||||
> .list {
|
||||
overflow-x: hidden !important;
|
||||
overflow-y: overlay !important;
|
||||
}
|
||||
}
|
||||
@ -32,7 +32,7 @@ interface State {
|
||||
}
|
||||
|
||||
const defaultProps: Partial<Props> = {
|
||||
width: "100%",
|
||||
width: "auto",
|
||||
initialOffset: 1,
|
||||
readyOffset: 10,
|
||||
onScroll: noop
|
||||
@ -52,7 +52,7 @@ export class VirtualList extends Component<Props, State> {
|
||||
componentDidMount() {
|
||||
this.setListHeight();
|
||||
this.scrollToSelectedItem();
|
||||
new ResizeSensor(this.parentRef.current as any as Element, this.setListHeight);
|
||||
new ResizeSensor(this.parentRef.current, this.setListHeight);
|
||||
this.setState({ overscanCount: this.props.readyOffset });
|
||||
}
|
||||
|
||||
@ -100,9 +100,8 @@ export class VirtualList extends Component<Props, State> {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cssNames("VirtualList", className)} ref={this.parentRef}>
|
||||
<VariableSizeList
|
||||
className="list"
|
||||
className={cssNames("VirtualList", className)}
|
||||
width={width}
|
||||
height={height}
|
||||
itemSize={this.getItemSize}
|
||||
@ -110,12 +109,12 @@ export class VirtualList extends Component<Props, State> {
|
||||
itemData={rowData}
|
||||
overscanCount={overscanCount}
|
||||
ref={this.listRef}
|
||||
innerRef={this.parentRef}
|
||||
outerRef={outerRef}
|
||||
onScroll={onScroll}
|
||||
>
|
||||
{Row}
|
||||
</VariableSizeList>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user