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 {
|
.VirtualList {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
.list {
|
|
||||||
overflow-x: scroll!important;
|
|
||||||
|
|
||||||
.LogRow {
|
.LogRow {
|
||||||
padding: 2px 16px;
|
padding: 2px 16px;
|
||||||
height: 18px; // Must be equal to lineHeight variable in pod-log-list.tsx
|
height: 18px; // Must be equal to lineHeight variable in pod-log-list.tsx
|
||||||
@ -38,15 +35,14 @@
|
|||||||
background-color: var(--overlay-bg);
|
background-color: var(--overlay-bg);
|
||||||
|
|
||||||
span {
|
span {
|
||||||
background-color: var(--overlay-bg)!important; // Rewriting inline styles from AnsiUp library
|
background-color: var(--overlay-bg) !important; // Rewriting inline styles from AnsiUp library
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
background-color: var(--overlay-active-bg);
|
background-color: var(--overlay-active-bg);
|
||||||
|
|
||||||
span {
|
span {
|
||||||
background-color: var(--overlay-active-bg)!important; // Rewriting inline styles from AnsiUp library
|
background-color: var(--overlay-active-bg) !important; // Rewriting inline styles from AnsiUp library
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,7 +55,7 @@
|
|||||||
|
|
||||||
&.isScrollHidden {
|
&.isScrollHidden {
|
||||||
.VirtualList .list {
|
.VirtualList .list {
|
||||||
overflow-x: hidden!important; // fixing scroll to bottom issues in PodLogs
|
overflow-x: hidden !important; // fixing scroll to bottom issues in PodLogs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -407,10 +407,12 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
|
|||||||
)}
|
)}
|
||||||
{renderTableHeader.map((cellProps, index) => {
|
{renderTableHeader.map((cellProps, index) => {
|
||||||
if (!this.isHiddenColumn(cellProps)) {
|
if (!this.isHiddenColumn(cellProps)) {
|
||||||
|
const storageId = cellProps.id ?? cellProps.storageId;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableCell
|
<TableCell
|
||||||
key={cellProps.id ?? cellProps.storageId ?? index}
|
key={storageId ?? index}
|
||||||
storageId={cellProps.storageId}
|
storageId={storageId}
|
||||||
tableId={tableId} {...cellProps}
|
tableId={tableId} {...cellProps}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -19,8 +19,37 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
flex: 0 0 40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
&.resizable {
|
&.resizable {
|
||||||
position: relative; // required for resizing-anchor with `position:absolute`
|
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 {
|
&.resizing {
|
||||||
filter: invert(50%);
|
filter: invert(50%);
|
||||||
|
|||||||
@ -27,9 +27,9 @@ export interface TableCellProps extends React.DOMAttributes<HTMLDivElement> {
|
|||||||
title?: ReactNode;
|
title?: ReactNode;
|
||||||
/**
|
/**
|
||||||
* Allow to resize width and save to local storage, default: true
|
* Allow to resize width and save to local storage, default: true
|
||||||
* (applicable only with props.id)
|
|
||||||
*/
|
*/
|
||||||
isResizable?: boolean;
|
isResizable?: boolean;
|
||||||
|
onResizeEnd?: () => void;
|
||||||
checkbox?: boolean; // render cell with a checkbox
|
checkbox?: boolean; // render cell with a checkbox
|
||||||
isChecked?: boolean; // mark checkbox as checked or not
|
isChecked?: boolean; // mark checkbox as checked or not
|
||||||
renderBoolean?: boolean; // show "true" or "false" for all of the children elements are "typeof boolean"
|
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
|
@observer
|
||||||
export class TableCell extends React.Component<TableCellProps> {
|
export class TableCell extends React.Component<TableCellProps> {
|
||||||
private elem: HTMLElement;
|
@observable.ref elem?: HTMLElement;
|
||||||
|
|
||||||
static defaultProps: TableCellProps = {
|
static defaultProps: TableCellProps = {
|
||||||
isResizable: true,
|
isResizable: true,
|
||||||
@ -97,7 +97,9 @@ export class TableCell extends React.Component<TableCellProps> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@computed get columnSize(): number {
|
@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 {
|
@computed get isResizable(): boolean {
|
||||||
@ -113,6 +115,7 @@ export class TableCell extends React.Component<TableCellProps> {
|
|||||||
|
|
||||||
if (this.isResizable && this.columnSize) {
|
if (this.isResizable && this.columnSize) {
|
||||||
styles.flexGrow = 0;
|
styles.flexGrow = 0;
|
||||||
|
styles.flexShrink = 0;
|
||||||
styles.flexBasis = this.columnSize;
|
styles.flexBasis = this.columnSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,10 +126,20 @@ export class TableCell extends React.Component<TableCellProps> {
|
|||||||
onResize(extent: number) {
|
onResize(extent: number) {
|
||||||
const { tableId } = this.props;
|
const { tableId } = this.props;
|
||||||
const { columnId } = this;
|
const { columnId } = this;
|
||||||
const size = extent || this.elem?.offsetWidth;
|
|
||||||
|
|
||||||
// persist state in storage
|
// 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()
|
@autobind()
|
||||||
@ -136,7 +149,7 @@ export class TableCell extends React.Component<TableCellProps> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
className, checkbox, isChecked, isResizable, sortBy,
|
className, checkbox, isChecked, isResizable, sortBy, onResizeEnd,
|
||||||
_sort, _sorting, _nowrap, children, title, tableId, storageId,
|
_sort, _sorting, _nowrap, children, title, tableId, storageId,
|
||||||
renderBoolean: displayBoolean, showWithColumn,
|
renderBoolean: displayBoolean, showWithColumn,
|
||||||
...cellProps
|
...cellProps
|
||||||
@ -147,7 +160,7 @@ export class TableCell extends React.Component<TableCellProps> {
|
|||||||
nowrap: _nowrap,
|
nowrap: _nowrap,
|
||||||
sorting: this.isSortable,
|
sorting: this.isSortable,
|
||||||
resizing: this.isResizing,
|
resizing: this.isResizing,
|
||||||
resizable: isResizable,
|
resizable: this.isResizable,
|
||||||
});
|
});
|
||||||
const content = displayBooleans(displayBoolean, title || children);
|
const content = displayBooleans(displayBoolean, title || children);
|
||||||
|
|
||||||
@ -158,12 +171,13 @@ export class TableCell extends React.Component<TableCellProps> {
|
|||||||
{this.renderSortIcon()}
|
{this.renderSortIcon()}
|
||||||
{this.isResizable && (
|
{this.isResizable && (
|
||||||
<ResizingAnchor
|
<ResizingAnchor
|
||||||
|
minExtent={50}
|
||||||
direction={ResizeDirection.HORIZONTAL}
|
direction={ResizeDirection.HORIZONTAL}
|
||||||
placement={ResizeSide.TRAILING}
|
placement={ResizeSide.TRAILING}
|
||||||
growthDirection={ResizeGrowthDirection.LEFT_TO_RIGHT}
|
growthDirection={ResizeGrowthDirection.LEFT_TO_RIGHT}
|
||||||
getCurrentExtent={() => this.columnSize}
|
getCurrentExtent={() => this.columnSize}
|
||||||
onStart={() => this.isResizing = true}
|
onStart={this.onResizeStart}
|
||||||
onEnd={() => this.isResizing = false}
|
onEnd={this.onResizeEnd}
|
||||||
onDrag={this.onResize}
|
onDrag={this.onResize}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ export interface TableHeadProps extends React.DOMAttributes<HTMLDivElement> {
|
|||||||
showTopLine?: boolean; // show border line at the top
|
showTopLine?: boolean; // show border line at the top
|
||||||
sticky?: boolean; // keep header on top when scrolling
|
sticky?: boolean; // keep header on top when scrolling
|
||||||
nowrap?: boolean; // white-space: nowrap, align inner <TableCell> in one line
|
nowrap?: boolean; // white-space: nowrap, align inner <TableCell> in one line
|
||||||
|
style?: React.CSSProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TableHead extends React.Component<TableHeadProps> {
|
export class TableHead extends React.Component<TableHeadProps> {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import "./table.scss";
|
import "./table.scss";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { orderBy } from "lodash";
|
import { orderBy, throttle } from "lodash";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { autobind, cssNames, noop } from "../../utils";
|
import { autobind, cssNames, noop } from "../../utils";
|
||||||
@ -57,6 +57,8 @@ export const orderByUrlParam = createPageParam({
|
|||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class Table extends React.Component<TableProps> {
|
export class Table extends React.Component<TableProps> {
|
||||||
|
@observable.ref elemRef = React.createRef<HTMLDivElement>();
|
||||||
|
|
||||||
static defaultProps: TableProps = {
|
static defaultProps: TableProps = {
|
||||||
scrollable: true,
|
scrollable: true,
|
||||||
autoSize: true,
|
autoSize: true,
|
||||||
@ -73,6 +75,14 @@ export class Table extends React.Component<TableProps> {
|
|||||||
this.props.sortByDefault,
|
this.props.sortByDefault,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
window.addEventListener("resize", this.refreshDimensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
window.removeEventListener("resize", this.refreshDimensions);
|
||||||
|
}
|
||||||
|
|
||||||
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)[];
|
||||||
@ -83,6 +93,10 @@ export class Table extends React.Component<TableProps> {
|
|||||||
const columns = React.Children.toArray(headElem.props.children) as TableCellElem[];
|
const columns = React.Children.toArray(headElem.props.children) as TableCellElem[];
|
||||||
|
|
||||||
return React.cloneElement(headElem, {
|
return React.cloneElement(headElem, {
|
||||||
|
style: {
|
||||||
|
...(headElem.props.style ?? {}),
|
||||||
|
width: this.contentWidth,
|
||||||
|
},
|
||||||
children: columns.map(elem => {
|
children: columns.map(elem => {
|
||||||
if (elem.props.checkbox) {
|
if (elem.props.checkbox) {
|
||||||
return elem;
|
return elem;
|
||||||
@ -98,6 +112,10 @@ export class Table extends React.Component<TableProps> {
|
|||||||
_sort: this.sort,
|
_sort: this.sort,
|
||||||
_sorting: this.sortParams,
|
_sorting: this.sortParams,
|
||||||
_nowrap: headElem.props.nowrap,
|
_nowrap: headElem.props.nowrap,
|
||||||
|
onResizeEnd: () => {
|
||||||
|
elem.props.onResizeEnd?.();
|
||||||
|
this.refreshDimensions();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -180,6 +198,10 @@ export class Table extends React.Component<TableProps> {
|
|||||||
getRow={getTableRow}
|
getRow={getTableRow}
|
||||||
selectedItemId={selectedItemId}
|
selectedItemId={selectedItemId}
|
||||||
className={className}
|
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;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
@observable refreshKey: number;
|
||||||
const { selectable, scrollable, sortable, autoSize, virtual } = this.props;
|
|
||||||
let { className } = this.props;
|
|
||||||
|
|
||||||
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,
|
selectable, scrollable, sortable, autoSize, virtual,
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div key={this.refreshKey} className={classNames} ref={this.elemRef}>
|
||||||
{this.renderHead()}
|
{this.renderHead()}
|
||||||
{this.renderRows()}
|
{this.renderRows()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,7 +1,4 @@
|
|||||||
.VirtualList {
|
.VirtualList {
|
||||||
overflow: hidden;
|
overflow-x: hidden !important;
|
||||||
|
overflow-y: overlay !important;
|
||||||
> .list {
|
|
||||||
overflow-y: overlay!important;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -32,7 +32,7 @@ interface State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const defaultProps: Partial<Props> = {
|
const defaultProps: Partial<Props> = {
|
||||||
width: "100%",
|
width: "auto",
|
||||||
initialOffset: 1,
|
initialOffset: 1,
|
||||||
readyOffset: 10,
|
readyOffset: 10,
|
||||||
onScroll: noop
|
onScroll: noop
|
||||||
@ -52,7 +52,7 @@ export class VirtualList extends Component<Props, State> {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setListHeight();
|
this.setListHeight();
|
||||||
this.scrollToSelectedItem();
|
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 });
|
this.setState({ overscanCount: this.props.readyOffset });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,9 +100,8 @@ export class VirtualList extends Component<Props, State> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cssNames("VirtualList", className)} ref={this.parentRef}>
|
|
||||||
<VariableSizeList
|
<VariableSizeList
|
||||||
className="list"
|
className={cssNames("VirtualList", className)}
|
||||||
width={width}
|
width={width}
|
||||||
height={height}
|
height={height}
|
||||||
itemSize={this.getItemSize}
|
itemSize={this.getItemSize}
|
||||||
@ -110,12 +109,12 @@ export class VirtualList extends Component<Props, State> {
|
|||||||
itemData={rowData}
|
itemData={rowData}
|
||||||
overscanCount={overscanCount}
|
overscanCount={overscanCount}
|
||||||
ref={this.listRef}
|
ref={this.listRef}
|
||||||
|
innerRef={this.parentRef}
|
||||||
outerRef={outerRef}
|
outerRef={outerRef}
|
||||||
onScroll={onScroll}
|
onScroll={onScroll}
|
||||||
>
|
>
|
||||||
{Row}
|
{Row}
|
||||||
</VariableSizeList>
|
</VariableSizeList>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user