2960: Merge branch 'main' into 2960-keepstore-streaming
[arvados.git] / services / workbench2 / src / components / data-table / data-table.tsx
index d3bbab5077f863a96010f3e248c1fbda232077e8..7b787994577305ea5725b80fcfd942d42f34f360 100644 (file)
@@ -24,11 +24,12 @@ import { DataTableFilters } from "../data-table-filters/data-table-filters-tree"
 import { DataTableMultiselectPopover } from "../data-table-multiselect-popover/data-table-multiselect-popover";
 import { DataTableFiltersPopover } from "../data-table-filters/data-table-filters-popover";
 import { countNodes, getTreeDirty } from "models/tree";
-import { IconType, PendingIcon } from "components/icon/icon";
+import { IconType } from "components/icon/icon";
 import { SvgIconProps } from "@material-ui/core/SvgIcon";
 import ArrowDownwardIcon from "@material-ui/icons/ArrowDownward";
 import { createTree } from "models/tree";
 import { DataTableMultiselectOption } from "../data-table-multiselect-popover/data-table-multiselect-popover";
+import { PendingIcon } from "components/icon/icon";
 
 export type DataColumns<I, R> = Array<DataColumn<I, R>>;
 
@@ -54,6 +55,7 @@ export interface DataTableDataProps<I> {
     toggleMSToolbar: (isVisible: boolean) => void;
     setCheckedListOnStore: (checkedList: TCheckedList) => void;
     checkedList: TCheckedList;
+    isNotFound?: boolean;
 }
 
 type CssRules =
@@ -69,8 +71,7 @@ type CssRules =
     | "tableCell"
     | "arrow"
     | "arrowButton"
-    | "tableCellWorkflows"
-    | "loader";
+    | "tableCellWorkflows";
 
 const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
     root: {
@@ -83,11 +84,6 @@ const styles: StyleRulesCallback<CssRules> = (theme: Theme) => ({
     tableBody: {
         background: theme.palette.background.paper,
     },
-    loader: {
-        left: "50%",
-        marginLeft: "-84px",
-        position: "absolute",
-    },
     noItemsInfo: {
         textAlign: "center",
         padding: theme.spacing.unit,
@@ -146,6 +142,7 @@ export type TCheckedList = Record<string, boolean>;
 
 type DataTableState = {
     isSelected: boolean;
+    isLoaded: boolean;
 };
 
 type DataTableProps<T> = DataTableDataProps<T> & WithStyles<CssRules>;
@@ -154,6 +151,7 @@ export const DataTable = withStyles(styles)(
     class Component<T> extends React.Component<DataTableProps<T>> {
         state: DataTableState = {
             isSelected: false,
+            isLoaded: false,
         };
 
         componentDidMount(): void {
@@ -171,6 +169,12 @@ export const DataTable = withStyles(styles)(
             if (prevProps.currentRoute !== this.props.currentRoute) {
                 this.initializeCheckedList([])
             }
+            if(prevProps.working === true && this.props.working === false) {
+                this.setState({ isLoaded: true });
+            }
+            if((this.props.items.length > 0) && !this.state.isLoaded) {
+                this.setState({ isLoaded: true });
+            }
         }
 
         componentWillUnmount(): void {
@@ -291,7 +295,8 @@ export const DataTable = withStyles(styles)(
         };
 
         render() {
-            const { items, classes, working, columns } = this.props;
+            const { items, classes, columns, isNotFound } = this.props;
+            const { isLoaded } = this.state;
             if (columns[0].name === this.checkBoxColumn.name) columns.shift();
             columns.unshift(this.checkBoxColumn);
             return (
@@ -301,31 +306,43 @@ export const DataTable = withStyles(styles)(
                             <TableHead>
                                 <TableRow>{this.mapVisibleColumns(this.renderHeadCell)}</TableRow>
                             </TableHead>
-                            <TableBody className={classes.tableBody}>{!working && items.map(this.renderBodyRow)}</TableBody>
+                            <TableBody className={classes.tableBody}>{(isLoaded && !isNotFound) && items.map(this.renderBodyRow)}</TableBody>
                         </Table>
-                        {!!working && (
-                            <div className={classes.loader}>
-                                <DataTableDefaultView
-                                    icon={PendingIcon}
-                                    messages={["Loading data, please wait."]}
-                                />
-                            </div>
-                        )}
-                        {items.length === 0 && !working && this.renderNoItemsPlaceholder(this.props.columns)}
+                        {(!isLoaded || isNotFound || items.length === 0) && this.renderNoItemsPlaceholder(this.props.columns)}
                     </div>
                 </div>
             );
         }
 
         renderNoItemsPlaceholder = (columns: DataColumns<T, any>) => {
+            const { isLoaded } = this.state;
+            const { working, isNotFound } = this.props;
             const dirty = columns.some(column => getTreeDirty("")(column.filters));
-            return (
-                <DataTableDefaultView
-                    icon={this.props.defaultViewIcon}
-                    messages={this.props.defaultViewMessages}
-                    filtersApplied={dirty}
-                />
-            );
+            if (isNotFound && isLoaded) {
+                return (
+                    <DataTableDefaultView 
+                        icon={this.props.defaultViewIcon} 
+                        messages={["No items found"]} 
+                    />
+                );
+            } else 
+            if (isLoaded === false || working === true) {
+                return (
+                    <DataTableDefaultView 
+                        icon={PendingIcon} 
+                        messages={["Loading data, please wait"]} 
+                    />
+                );
+            } else {
+                // isLoaded && !working && !isNotFound
+                return (
+                    <DataTableDefaultView
+                        icon={this.props.defaultViewIcon}
+                        messages={this.props.defaultViewMessages}
+                        filtersApplied={dirty}
+                    />
+                );
+            }
         };
 
         renderHeadCell = (column: DataColumn<T, any>, index: number) => {