mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
add more typing to sorting of tables
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
f66d84ae4a
commit
0015770739
@ -18,24 +18,73 @@ export type TableOrderBy = "asc" | "desc" | string;
|
|||||||
export type TableSortParams<SortingOption extends string> = { sortBy: SortingOption; orderBy: TableOrderBy };
|
export type TableSortParams<SortingOption extends string> = { sortBy: SortingOption; orderBy: TableOrderBy };
|
||||||
export type TableSortCallback<D> = (data: D) => string | number | (string | number)[];
|
export type TableSortCallback<D> = (data: D) => string | number | (string | number)[];
|
||||||
|
|
||||||
export interface TableProps<T, SortingOption extends string = string> extends React.DOMAttributes<HTMLDivElement> {
|
export interface TableProps<Entry extends ItemObject, SortingOption extends string> extends React.DOMAttributes<HTMLDivElement> {
|
||||||
items?: ItemObject[]; // Raw items data
|
/**
|
||||||
|
* Raw items data
|
||||||
|
*/
|
||||||
|
items?: Entry[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional className for the root element
|
||||||
|
*/
|
||||||
className?: string;
|
className?: string;
|
||||||
autoSize?: boolean; // Setup auto-sizing for all columns (flex: 1 0)
|
|
||||||
selectable?: boolean; // Highlight rows on hover
|
/**
|
||||||
scrollable?: boolean; // Use scrollbar if content is bigger than parent's height
|
* Setup auto-sizing for all columns (flex: 1 0)
|
||||||
storageKey?: string; // Keep some data in localStorage & restore on page reload, e.g sorting params
|
*/
|
||||||
sortable?: {
|
autoSize?: boolean;
|
||||||
// Define sortable callbacks for every column in <TableHead><TableCell sortBy="someCol"><TableHead>
|
|
||||||
// @sortItem argument in the callback is an object, provided in <TableRow sortItem={someColDataItem}/>
|
/**
|
||||||
[sortBy: string]: TableSortCallback<T>;
|
* Highlight rows on hover
|
||||||
};
|
*/
|
||||||
sortSyncWithUrl?: boolean; // sorting state is managed globally from url params
|
selectable?: boolean;
|
||||||
sortByDefault?: Partial<TableSortParams<SortingOption>>; // default sorting params
|
|
||||||
onSort?: (params: TableSortParams<SortingOption>) => void; // callback on sort change, default: global sync with url
|
/**
|
||||||
noItems?: React.ReactNode; // Show no items state table list is empty
|
* Use scrollbar if content is bigger than parent's height
|
||||||
selectedItemId?: string; // Allows to scroll list to selected item
|
*/
|
||||||
virtual?: boolean; // Use virtual list component to render only visible rows
|
scrollable?: boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep some data in localStorage & restore on page reload, e.g sorting params
|
||||||
|
*/
|
||||||
|
storageKey?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define sortable callbacks for every column in <TableHead><TableCell sortBy="someCol"><TableHead>
|
||||||
|
* @sortItem argument in the callback is an object, provided in <TableRow sortItem={someColDataItem}/>
|
||||||
|
*/
|
||||||
|
sortable?: Record<SortingOption, TableSortCallback<Entry>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sorting state is managed globally from url params
|
||||||
|
*/
|
||||||
|
sortSyncWithUrl?: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* default sorting params
|
||||||
|
*/
|
||||||
|
sortByDefault?: Partial<TableSortParams<SortingOption>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* callback on sort change, default: global sync with url
|
||||||
|
*/
|
||||||
|
onSort?: (params: TableSortParams<SortingOption>) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show no items state table list is empty
|
||||||
|
*/
|
||||||
|
noItems?: React.ReactNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to scroll list to selected item
|
||||||
|
*/
|
||||||
|
selectedItemId?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use virtual list component to render only visible rows
|
||||||
|
*/
|
||||||
|
virtual?: boolean;
|
||||||
|
|
||||||
rowPadding?: string;
|
rowPadding?: string;
|
||||||
rowLineHeight?: string;
|
rowLineHeight?: string;
|
||||||
customRowHeights?: (item: object, lineHeight: number, paddings: number) => number;
|
customRowHeights?: (item: object, lineHeight: number, paddings: number) => number;
|
||||||
@ -43,8 +92,8 @@ export interface TableProps<T, SortingOption extends string = string> extends Re
|
|||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class Table<T> extends React.Component<TableProps<T>> {
|
export class Table<Entry extends ItemObject = ItemObject, SortingOption extends string = string> extends React.Component<TableProps<Entry, SortingOption>> {
|
||||||
static defaultProps: TableProps<any> = {
|
static defaultProps: TableProps<ItemObject, string> = {
|
||||||
scrollable: true,
|
scrollable: true,
|
||||||
autoSize: true,
|
autoSize: true,
|
||||||
rowPadding: "8px",
|
rowPadding: "8px",
|
||||||
@ -54,9 +103,9 @@ export class Table<T> extends React.Component<TableProps<T>> {
|
|||||||
|
|
||||||
@observable sortParamsLocal = this.props.sortByDefault;
|
@observable sortParamsLocal = this.props.sortByDefault;
|
||||||
|
|
||||||
@computed get sortParams(): Partial<TableSortParams> {
|
@computed get sortParams(): Partial<TableSortParams<SortingOption>> {
|
||||||
if (this.props.sortSyncWithUrl) {
|
if (this.props.sortSyncWithUrl) {
|
||||||
const sortBy = navigation.searchParams.get("sortBy");
|
const sortBy = navigation.searchParams.get("sortBy") as SortingOption;
|
||||||
const orderBy = navigation.searchParams.get("orderBy");
|
const orderBy = navigation.searchParams.get("orderBy");
|
||||||
|
|
||||||
return { sortBy, orderBy };
|
return { sortBy, orderBy };
|
||||||
@ -111,7 +160,7 @@ export class Table<T> extends React.Component<TableProps<T>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
protected onSort(params: TableSortParams) {
|
protected onSort(params: TableSortParams<SortingOption>) {
|
||||||
const { sortSyncWithUrl, onSort } = this.props;
|
const { sortSyncWithUrl, onSort } = this.props;
|
||||||
|
|
||||||
if (sortSyncWithUrl) {
|
if (sortSyncWithUrl) {
|
||||||
@ -127,14 +176,14 @@ export class Table<T> extends React.Component<TableProps<T>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@autobind()
|
@autobind()
|
||||||
sort(colName: TableSortBy) {
|
sort(colName: SortingOption) {
|
||||||
const { sortBy, orderBy } = this.sortParams;
|
const { sortBy, orderBy } = this.sortParams;
|
||||||
const sameColumn = sortBy == colName;
|
const sameColumn = sortBy == colName;
|
||||||
const newSortBy: TableSortBy = colName;
|
const newSortBy: SortingOption = colName;
|
||||||
const newOrderBy: TableOrderBy = (!orderBy || !sameColumn || orderBy === "desc") ? "asc" : "desc";
|
const newOrderBy: TableOrderBy = (!orderBy || !sameColumn || orderBy === "desc") ? "asc" : "desc";
|
||||||
|
|
||||||
this.onSort({
|
this.onSort({
|
||||||
sortBy: String(newSortBy),
|
sortBy: newSortBy,
|
||||||
orderBy: newOrderBy,
|
orderBy: newOrderBy,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -185,15 +234,13 @@ export class Table<T> extends React.Component<TableProps<T>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { selectable, scrollable, sortable, autoSize, virtual } = this.props;
|
const { selectable, scrollable, sortable, autoSize, virtual, className } = this.props;
|
||||||
let { className } = this.props;
|
const classNames = cssNames("Table flex column", className, {
|
||||||
|
|
||||||
className = cssNames("Table flex column", className, {
|
|
||||||
selectable, scrollable, sortable, autoSize, virtual,
|
selectable, scrollable, sortable, autoSize, virtual,
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className}>
|
<div className={classNames}>
|
||||||
{this.renderHead()}
|
{this.renderHead()}
|
||||||
{this.renderRows()}
|
{this.renderRows()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user