21386: removed duplicate isWorking functions and moved default views to data-table...
authorLisa Knox <lisaknox83@gmail.com>
Tue, 20 Feb 2024 15:50:53 +0000 (10:50 -0500)
committerLisa Knox <lisaknox83@gmail.com>
Tue, 20 Feb 2024 15:50:53 +0000 (10:50 -0500)
services/workbench2/src/components/data-explorer/data-explorer.tsx
services/workbench2/src/components/data-table/data-table.tsx
services/workbench2/src/store/search-bar/search-bar-reducer.ts
services/workbench2/src/store/search-results-panel/search-results-middleware-service.ts
services/workbench2/src/views-components/data-explorer/data-explorer.tsx
services/workbench2/src/views/project-panel/project-panel.tsx
services/workbench2/src/views/search-results-panel/search-results-panel-view.tsx
services/workbench2/src/views/search-results-panel/search-results-panel.tsx

index 27e46d584962c8d3e1cb1ca536b21ab1b4577ecf..1f9fb42d6baddd443d026f5d5b9c9b5c7e3064e1 100644 (file)
@@ -118,12 +118,18 @@ interface DataExplorerActionProps<T> {
 
 type DataExplorerProps<T> = DataExplorerDataProps<T> & DataExplorerActionProps<T> & WithStyles<CssRules> & MPVPanelProps;
 
+type DataExplorerState = {
+    prevRefresh: string;
+    prevRoute: string;
+    notFound: boolean;
+};
+
 export const DataExplorer = withStyles(styles)(
     class DataExplorerGeneric<T> extends React.Component<DataExplorerProps<T>> {
-        state = {
-            showLoading: false,
+        state: DataExplorerState = {
             prevRefresh: "",
             prevRoute: "",
+            notFound: false,
         };
 
         multiSelectToolbarInTitle = !this.props.title && !this.props.progressBar;
@@ -136,7 +142,6 @@ export const DataExplorer = withStyles(styles)(
                 // Component already mounted, but the user comes from a route change,
                 // like browsing through a project hierarchy.
                 this.setState({
-                    showLoading: this.props.working,
                     prevRoute: currentRoute,
                 });
             }
@@ -145,13 +150,19 @@ export const DataExplorer = withStyles(styles)(
                 // Component already mounted, but the user just clicked the
                 // refresh button.
                 this.setState({
-                    showLoading: this.props.working,
                     prevRefresh: currentRefresh,
                 });
             }
-            if (this.state.showLoading && !this.props.working) {
+
+            if(this.state.notFound === true && this.props.itemsAvailable > 0) {
+                this.setState({
+                    notFound: false,
+                });
+            }
+
+            if (prevProps.working === true && this.props.working === false) {
                 this.setState({
-                    showLoading: false,
+                    notFound: this.props.itemsAvailable === 0,
                 });
             }
         }
@@ -162,7 +173,6 @@ export const DataExplorer = withStyles(styles)(
             }
             // Component just mounted, so we need to show the loading indicator.
             this.setState({
-                showLoading: this.props.working,
                 prevRefresh: this.props.currentRefresh || "",
                 prevRoute: this.props.currentRoute || "",
             });
@@ -207,6 +217,7 @@ export const DataExplorer = withStyles(styles)(
                 toggleMSToolbar,
                 setCheckedListOnStore,
                 checkedList,
+                working,
             } = this.props;
             return (
                 <Paper
@@ -314,7 +325,6 @@ export const DataExplorer = withStyles(styles)(
                                 onFiltersChange={onFiltersChange}
                                 onSortToggle={onSortToggle}
                                 extractKey={extractKey}
-                                working={this.state.showLoading}
                                 defaultViewIcon={defaultViewIcon}
                                 defaultViewMessages={defaultViewMessages}
                                 currentItemUuid={currentItemUuid}
@@ -322,6 +332,8 @@ export const DataExplorer = withStyles(styles)(
                                 toggleMSToolbar={toggleMSToolbar}
                                 setCheckedListOnStore={setCheckedListOnStore}
                                 checkedList={checkedList}
+                                working={working}
+                                notFound={this.state.notFound}
                             />
                         </Grid>
                         <Grid
index bbbc7bb0123f434eedd02cbefbdf754a125700dd..f9ab7f0a25c9927ab905af0dd20a3ee221bfd26d 100644 (file)
@@ -54,6 +54,7 @@ export interface DataTableDataProps<I> {
     toggleMSToolbar: (isVisible: boolean) => void;
     setCheckedListOnStore: (checkedList: TCheckedList) => void;
     checkedList: TCheckedList;
+    notFound?: boolean;
 }
 
 type CssRules =
@@ -285,7 +286,7 @@ export const DataTable = withStyles(styles)(
         };
 
         render() {
-            const { items, classes, working, columns } = this.props;
+            const { items, classes, working, columns, notFound } = this.props;
             if (columns[0].name === this.checkBoxColumn.name) columns.shift();
             columns.unshift(this.checkBoxColumn);
             return (
@@ -295,23 +296,40 @@ 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}>{(!working && !notFound) && items.map(this.renderBodyRow)}</TableBody>
                         </Table>
-                        {items.length === 0 && !working && this.renderNoItemsPlaceholder(this.props.columns)}
+                        {(working || notFound) && this.renderNoItemsPlaceholder(this.props.columns)}
                     </div>
                 </div>
             );
         }
 
         renderNoItemsPlaceholder = (columns: DataColumns<T, any>) => {
+            const { working, notFound } = this.props;
             const dirty = columns.some(column => getTreeDirty("")(column.filters));
-            return (
-                <DataTableDefaultView
-                    icon={this.props.defaultViewIcon}
-                    messages={this.props.defaultViewMessages}
-                    filtersApplied={dirty}
-                />
-            );
+            if (working) {
+                return (
+                    <DataTableDefaultView 
+                        icon={this.props.defaultViewIcon} 
+                        messages={["Loading data, please wait"]} 
+                    />
+                );
+            } else if (notFound) {
+                return (
+                    <DataTableDefaultView 
+                        icon={this.props.defaultViewIcon} 
+                        messages={["Project not found"]} 
+                    />
+                );
+            } else {
+                return (
+                    <DataTableDefaultView
+                        icon={this.props.defaultViewIcon}
+                        messages={this.props.defaultViewMessages}
+                        filtersApplied={dirty}
+                    />
+                );
+            }
         };
 
         renderHeadCell = (column: DataColumn<T, any>, index: number) => {
index 5f32e794cc0e055ce927bb2ae432d03b7d644674..05b75bf99c4a981f7fda8410d8c73fc74dd3c121 100644 (file)
@@ -24,7 +24,6 @@ interface SearchBar {
     savedQueries: SearchBarAdvancedFormData[];
     recentQueries: string[];
     selectedItem: SearchBarSelectedItem;
-    isSearching: boolean;
 }
 
 export enum SearchView {
@@ -44,7 +43,6 @@ const initialState: SearchBar = {
         id: '',
         query: ''
     },
-    isSearching: false,
 };
 
 const makeSelectedItem = (id: string, query?: string): SearchBarSelectedItem => ({ id, query: query ? query : id });
@@ -145,6 +143,5 @@ export const searchBarReducer = (state = initialState, action: SearchBarActions)
                 selectedItem
             };
         },
-        SET_IS_SEARCHING: isSearching => ({ ...state, isSearching }),
         default: () => state
     });
index 2f64d76fb5ed5d0776d94c0f48352c2cb24e6ab1..defacf21ded782ef15ecd3783628b68386f5995c 100644 (file)
@@ -18,7 +18,6 @@ import {
     getSearchSessions,
     queryToFilters,
     getAdvancedDataFromQuery,
-    searchBarActions
 } from 'store/search-bar/search-bar-actions';
 import { getSortColumn } from "store/data-explorer/data-explorer-reducer";
 import { FilterBuilder, joinFilters } from 'services/api/filter-builder';
@@ -27,6 +26,7 @@ import { serializeResourceTypeFilters } from 'store//resource-type-filters/resou
 import { ProjectPanelColumnNames } from 'views/project-panel/project-panel';
 import { ResourceKind } from 'models/resource';
 import { ContainerRequestResource } from 'models/container-request';
+import { progressIndicatorActions } from 'store/progress-indicator/progress-indicator-actions';
 
 export class SearchResultsMiddlewareService extends DataExplorerMiddlewareService {
     constructor(private services: ServiceRepository, id: string) {
@@ -58,7 +58,7 @@ export class SearchResultsMiddlewareService extends DataExplorerMiddlewareServic
 
         const numberOfSessions = sessions.length;
         let numberOfResolvedResponses = 0;
-        api.dispatch(searchBarActions.SET_IS_SEARCHING(true));
+        api.dispatch(progressIndicatorActions.START_WORKING(this.id))
 
         sessions.forEach(session => {
             const params = getParams(dataExplorer, searchValue, session.apiRevision);
@@ -67,9 +67,9 @@ export class SearchResultsMiddlewareService extends DataExplorerMiddlewareServic
                     api.dispatch(updateResources(response.items));
                     api.dispatch(appendItems(response));
                     numberOfResolvedResponses++;
-                        if (numberOfResolvedResponses === numberOfSessions) {
-                            api.dispatch(searchBarActions.SET_IS_SEARCHING(false));
-                        }
+                    if (numberOfResolvedResponses === numberOfSessions) {
+                        api.dispatch(progressIndicatorActions.STOP_WORKING(this.id))
+                    }
                     // Request all containers for process status to be available
                     const containerRequests = response.items.filter((item) => item.kind === ResourceKind.CONTAINER_REQUEST) as ContainerRequestResource[];
                     const containerUuids = containerRequests.map(container => container.containerUuid).filter(uuid => uuid !== null) as string[];
@@ -84,7 +84,7 @@ export class SearchResultsMiddlewareService extends DataExplorerMiddlewareServic
                         });
                     }).catch(() => {
                         api.dispatch(couldNotFetchSearchResults(session.clusterId));
-                        api.dispatch(searchBarActions.SET_IS_SEARCHING(false));
+                        api.dispatch(progressIndicatorActions.STOP_WORKING(this.id))
                     });
             }
         );
index 9b11f2ad3a703d83c22f6eb53bc7b702b5ac6ad3..05e923f1bbeecfb90583e1314b68e9e8e9afd3f0 100644 (file)
@@ -20,10 +20,10 @@ interface Props {
     onContextMenu?: (event: React.MouseEvent<HTMLElement>, item: any, isAdmin?: boolean) => void;
     onRowDoubleClick: (item: any) => void;
     extractKey?: (item: any) => React.Key;
+    working?: boolean;
 }
 
 const mapStateToProps = ({ progressIndicator, dataExplorer, router, multiselect, detailsPanel, properties}: RootState, { id }: Props) => {
-    const progress = progressIndicator.find(p => p.id === id);
     const dataExplorerState = getDataExplorer(dataExplorer, id);
     const currentRoute = router.location ? router.location.pathname : "";
     const currentRefresh = localStorage.getItem(LAST_REFRESH_TIMESTAMP) || "";
@@ -34,7 +34,6 @@ const mapStateToProps = ({ progressIndicator, dataExplorer, router, multiselect,
     const isMSToolbarVisible = multiselect.isVisible;
     return {
         ...dataExplorerState,
-        working: !!progress?.working,
         currentRefresh: currentRefresh,
         currentRoute: currentRoute,
         paperKey: currentRoute,
index 112f09968a5b532757e9153d9d5b6f100612cdf6..ad1234927bbe41faa085b38933d6e09265c76a15 100644 (file)
@@ -51,10 +51,7 @@ import { GroupClass, GroupResource } from 'models/group';
 import { CollectionResource } from 'models/collection';
 import { resourceIsFrozen } from 'common/frozen-resources';
 import { ProjectResource } from 'models/project';
-import { NotFoundView } from 'views/not-found-panel/not-found-panel';
 import { deselectAllOthers, toggleOne } from 'store/multiselect/multiselect-actions';
-import { PendingIcon } from 'components/icon/icon';
-import { DataTableDefaultView } from 'components/data-table-default-view/data-table-default-view';
 
 type CssRules = 'root' | 'button' | 'loader' | 'notFoundView';
 
@@ -276,57 +273,24 @@ const mapStateToProps = (state: RootState) => {
     };
 }
 
-type ProjectPanelState = {
-    isLoaded: boolean;
-};
-
 export const ProjectPanel = withStyles(styles)(
     connect(mapStateToProps)(
         class extends React.Component<ProjectPanelProps> {
 
-            state: ProjectPanelState ={
-                isLoaded: false,
-            }
-
-            componentDidMount(): void {
-                this.setState({ isLoaded: false });
-            }
-
-            componentDidUpdate( prevProps: Readonly<ProjectPanelProps>, prevState: Readonly<{}>, snapshot?: any ): void {
-                if(prevProps.working === true && this.props.working === false) {
-                    this.setState({ isLoaded: true });
-                }
-            }
-
             render() {
                 const { classes } = this.props;
-
-                return this.props.project ?
-                    <div data-cy='project-panel' className={classes.root}>
-                        <DataExplorer
-                            id={PROJECT_PANEL_ID}
-                            onRowClick={this.handleRowClick}
-                            onRowDoubleClick={this.handleRowDoubleClick}
-                            onContextMenu={this.handleContextMenu}
-                            contextMenuColumn={true}
-                            defaultViewIcon={ProjectIcon}
-                            defaultViewMessages={DEFAULT_VIEW_MESSAGES}
-                        />
-                    </div>
-                : this.state.isLoaded ?
-                    <div className={classes.notFoundView}>
-                        <NotFoundView
-                            icon={ProjectIcon}
-                            messages={["Project not found"]}
-                            />
-                    </div>
-                    :   
-                    <div className={classes.loader}>
-                        <DataTableDefaultView
-                            icon={PendingIcon}
-                            messages={["Loading data, please wait."]}
-                        />
-                    </div>
+                return <div data-cy='project-panel' className={classes.root}>
+                    <DataExplorer
+                        id={PROJECT_PANEL_ID}
+                        onRowClick={this.handleRowClick}
+                        onRowDoubleClick={this.handleRowDoubleClick}
+                        onContextMenu={this.handleContextMenu}
+                        contextMenuColumn={true}
+                        defaultViewIcon={ProjectIcon}
+                        defaultViewMessages={DEFAULT_VIEW_MESSAGES}
+                        working={this.props.working}
+                    />
+                </div>
             }
 
             isCurrentItemChild = (resource: Resource) => {
index bd32d997c20308cc2bbaded43f79a2d01a2b0d76..10ff2b75654128ce7dfb32a0d2616bb340509a24 100644 (file)
@@ -154,21 +154,8 @@ export const SearchResultsPanelView = withStyles(styles, { withTheme: true })(
             // eslint-disable-next-line react-hooks/exhaustive-deps
         }, [selectedItem]);
 
-        const prevIsSearching = React.useRef<boolean>(props.isSearching);
         const [isLoaded, setIsLoaded] = React.useState<boolean>(false);
 
-        useEffect(() => {
-            if(prevIsSearching.current === true && props.isSearching === false) {
-                setIsLoaded(true);
-                props.stopSpinner();
-            }
-            if(props.isSearching === true) {
-                setIsLoaded(false);
-                props.startSpinner();
-            }
-        // eslint-disable-next-line react-hooks/exhaustive-deps
-        }, [props.isSearching]);
-
         const onItemClick = useCallback((uuid) => {
             setSelectedItem(uuid);
             props.onItemClick(uuid);
index 60d70204a689be93ca2766235e183e97f3dc92a4..639008216c33fff822e5d450d73f3d402cc61a03 100644 (file)
@@ -24,7 +24,6 @@ export interface SearchResultsPanelDataProps {
     remoteHostsConfig: { [key: string]: Config };
     localCluster: string;
     numberOfItems: number;
-    isSearching: boolean;
 }
 
 export interface SearchResultsPanelActionProps {
@@ -39,7 +38,7 @@ export interface SearchResultsPanelActionProps {
 export type SearchResultsPanelProps = SearchResultsPanelDataProps & SearchResultsPanelActionProps;
 
 const mapStateToProps = (rootState: RootState) => {
-    const { dataExplorer, searchBar } = rootState;
+    const { dataExplorer } = rootState;
     const numberOfItems = dataExplorer[SEARCH_RESULTS_PANEL_ID].items.length;
     return {
         user: rootState.auth.user,
@@ -47,7 +46,6 @@ const mapStateToProps = (rootState: RootState) => {
         remoteHostsConfig: rootState.auth.remoteHostsConfig,
         localCluster: rootState.auth.localCluster,
         numberOfItems,
-        isSearching: searchBar.isSearching,
     };
 };