Move default views to corresponding panels
authorMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Wed, 5 Sep 2018 11:02:58 +0000 (13:02 +0200)
committerMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Wed, 5 Sep 2018 11:02:58 +0000 (13:02 +0200)
Feature #14160

Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski@contractors.roche.com>

src/components/data-explorer/data-explorer.tsx
src/views/favorite-panel/favorite-panel.tsx
src/views/project-panel/project-panel.tsx
src/views/trash-panel/trash-panel.tsx

index 2ff4e7fe1c8589fc45b9401a386566539c12768a..0147937f834d5f0bd7a7f3f5525a084e5f7c00c1 100644 (file)
@@ -45,8 +45,6 @@ interface DataExplorerDataProps<T> {
     rowsPerPage: number;
     rowsPerPageOptions: number[];
     page: number;
-    defaultIcon: IconType;
-    defaultMessages: string[];
     contextMenuColumn: boolean;
     noItemsPlaceholder?: React.ReactNode;
 }
@@ -78,7 +76,7 @@ export const DataExplorer = withStyles(styles)(
             const {
                 columns, onContextMenu, onFiltersChange, onSortToggle, extractKey,
                 rowsPerPage, rowsPerPageOptions, onColumnToggle, searchValue, onSearch,
-                items, itemsAvailable, onRowClick, onRowDoubleClick, defaultIcon, defaultMessages, classes,
+                items, itemsAvailable, onRowClick, onRowDoubleClick, classes,
                 noItemsPlaceholder
             } = this.props;
             return <Paper>
index 803d8002a365105c2691648e2a5f000cbd3be254..ce86adf913daf7f933c02cd234af5ebc5f621495 100644 (file)
@@ -28,6 +28,9 @@ import { openContextMenu, resourceKindToContextMenuKind } from '~/store/context-
 import { loadDetailsPanel } from '~/store/details-panel/details-panel-action';
 import { navigateTo } from '~/store/navigation/navigation-action';
 import { ContainerRequestState } from "~/models/container-request";
+import { DefaultView } from '~/components/default-view/default-view';
+import { FavoritesState } from '../../store/favorites/favorites-reducer';
+import { RootState } from '~/store/store';
 
 type CssRules = "toolbar" | "button";
 
@@ -124,7 +127,7 @@ export const favoritePanelColumns: DataColumns<string, FavoritePanelFilter> = [
 ];
 
 interface FavoritePanelDataProps {
-    currentItemId: string;
+    favorites: FavoritesState;
 }
 
 interface FavoritePanelActionProps {
@@ -133,6 +136,9 @@ interface FavoritePanelActionProps {
     onDialogOpen: (ownerUuid: string) => void;
     onItemDoubleClick: (item: string) => void;
 }
+const mapStateToProps = ({ favorites }: RootState): FavoritePanelDataProps => ({
+    favorites
+});
 
 const mapDispatchToProps = (dispatch: Dispatch): FavoritePanelActionProps => ({
     onContextMenu: (event, resourceUuid) => {
@@ -160,17 +166,25 @@ type FavoritePanelProps = FavoritePanelDataProps & FavoritePanelActionProps & Di
     & WithStyles<CssRules> & RouteComponentProps<{ id: string }>;
 
 export const FavoritePanel = withStyles(styles)(
-    connect(undefined, mapDispatchToProps)(
+    connect(mapStateToProps, mapDispatchToProps)(
         class extends React.Component<FavoritePanelProps> {
             render() {
-                return <DataExplorer
-                    id={FAVORITE_PANEL_ID}
-                    onRowClick={this.props.onItemClick}
-                    onRowDoubleClick={this.props.onItemDoubleClick}
-                    onContextMenu={this.props.onContextMenu}
-                    defaultIcon={FavoriteIcon}
-                    defaultMessages={['Your favorites list is empty.']}
-                    contextMenuColumn={true}/>;
+                return this.hasAnyFavorites()
+                    ? <DataExplorer
+                        id={FAVORITE_PANEL_ID}
+                        onRowClick={this.props.onItemClick}
+                        onRowDoubleClick={this.props.onItemDoubleClick}
+                        onContextMenu={this.props.onContextMenu}
+                        contextMenuColumn={true} />
+                    : <DefaultView
+                        icon={FavoriteIcon}
+                        messages={['Your favorites list is empty.']} />;
+            }
+
+            hasAnyFavorites = () => {
+                return Object
+                    .keys(this.props.favorites)
+                    .find(uuid => this.props.favorites[uuid]);
             }
         }
     )
index 2573f81813a920256cc9a0801e2af8f2dd7eb611..19d4ee1c490bddbb7eda17c16b949c4a57443991 100644 (file)
@@ -12,7 +12,7 @@ import { RootState } from '~/store/store';
 import { DataTableFilterItem } from '~/components/data-table-filters/data-table-filters';
 import { ContainerRequestState } from '~/models/container-request';
 import { SortDirection } from '~/components/data-table/data-column';
-import { ResourceKind } from '~/models/resource';
+import { ResourceKind, Resource } from '~/models/resource';
 import { resourceLabel } from '~/common/labels';
 import { ArvadosTheme } from '~/common/custom-theme';
 import { ResourceFileSize, ResourceLastModifiedDate, ProcessStatus, ResourceType, ResourceOwner } from '~/views-components/data-explorer/renderers';
@@ -27,6 +27,8 @@ import { getProperty } from '~/store/properties/properties';
 import { PROJECT_PANEL_CURRENT_UUID } from '~/store/project-panel/project-panel-action';
 import { openCollectionCreateDialog } from '../../store/collections/collection-create-actions';
 import { openProjectCreateDialog } from '~/store/projects/project-create-actions';
+import { filterResources } from '../../store/resources/resources';
+import { DefaultView } from '~/components/default-view/default-view';
 
 type CssRules = 'root' | "toolbar" | "button";
 
@@ -157,17 +159,30 @@ export const ProjectPanel = withStyles(styles)(
                             New project
                         </Button>
                     </div>
-                    <DataExplorer
-                        id={PROJECT_PANEL_ID}
-                        onRowClick={this.handleRowClick}
-                        onRowDoubleClick={this.handleRowDoubleClick}
-                        onContextMenu={this.handleContextMenu}
-                        defaultIcon={ProjectIcon}
-                        defaultMessages={['Your project is empty.', 'Please create a project or create a collection and upload a data.']}
-                        contextMenuColumn={true}/>
+                    {this.hasAnyItems()
+                        ? <DataExplorer
+                            id={PROJECT_PANEL_ID}
+                            onRowClick={this.handleRowClick}
+                            onRowDoubleClick={this.handleRowDoubleClick}
+                            onContextMenu={this.handleContextMenu}
+                            contextMenuColumn={true} />
+                        : <DefaultView
+                            icon={ProjectIcon}
+                            messages={['Your project is empty.', 'Please create a project or create a collection and upload a data.']} />
+                    }
+
                 </div>;
             }
 
+            hasAnyItems = () => {
+                const resources = filterResources(this.isCurrentItemChild)(this.props.resources);
+                return resources.length > 0;
+            }
+
+            isCurrentItemChild = (resource: Resource) => {
+                return resource.ownerUuid === this.props.currentItemId;
+            }
+
             handleNewProjectClick = () => {
                 this.props.dispatch<any>(openProjectCreateDialog(this.props.currentItemId));
             }
index 08df05c247b61b8be75874ba87c4adbaa7834d71..2c9d61e7868acd446dfff7ba09bddc14d254f9d8 100644 (file)
@@ -31,6 +31,7 @@ import { loadDetailsPanel } from "~/store/details-panel/details-panel-action";
 import { toggleCollectionTrashed, toggleProjectTrashed, toggleTrashed } from "~/store/trash/trash-actions";
 import { ContextMenuKind } from "~/views-components/context-menu/context-menu";
 import { Dispatch } from "redux";
+import { DefaultView } from '~/components/default-view/default-view';
 
 type CssRules = "toolbar" | "button";
 
@@ -71,7 +72,7 @@ export const ResourceRestore =
                 ));
             }
         }}>
-            <RestoreFromTrashIcon/>
+            <RestoreFromTrashIcon />
         </IconButton>
     );
 
@@ -82,7 +83,7 @@ export const trashPanelColumns: DataColumns<string, TrashPanelFilter> = [
         configurable: true,
         sortDirection: SortDirection.ASC,
         filters: [],
-        render: uuid => <ResourceName uuid={uuid}/>,
+        render: uuid => <ResourceName uuid={uuid} />,
         width: "450px"
     },
     {
@@ -107,7 +108,7 @@ export const trashPanelColumns: DataColumns<string, TrashPanelFilter> = [
                 type: ResourceKind.PROJECT
             }
         ],
-        render: uuid => <ResourceType uuid={uuid}/>,
+        render: uuid => <ResourceType uuid={uuid} />,
         width: "125px"
     },
     {
@@ -143,7 +144,7 @@ export const trashPanelColumns: DataColumns<string, TrashPanelFilter> = [
         configurable: false,
         sortDirection: SortDirection.NONE,
         filters: [],
-        render: uuid => <ResourceRestore uuid={uuid}/>,
+        render: uuid => <ResourceRestore uuid={uuid} />,
         width: "50px"
     }
 ];
@@ -162,15 +163,22 @@ export const TrashPanel = withStyles(styles)(
     }))(
         class extends React.Component<TrashPanelProps> {
             render() {
-                return <DataExplorer
-                    id={TRASH_PANEL_ID}
-                    onRowClick={this.handleRowClick}
-                    onRowDoubleClick={this.handleRowDoubleClick}
-                    onContextMenu={this.handleContextMenu}
-                    defaultIcon={TrashIcon}
-                    defaultMessages={['Your trash list is empty.']}
-                    contextMenuColumn={false}/>
-                ;
+                return this.hasAnyTrashedResources()
+                    ? <DataExplorer
+                        id={TRASH_PANEL_ID}
+                        onRowClick={this.handleRowClick}
+                        onRowDoubleClick={this.handleRowDoubleClick}
+                        onContextMenu={this.handleContextMenu}
+                        contextMenuColumn={false} />
+                    : <DefaultView
+                        icon={TrashIcon}
+                        messages={['Your trash list is empty.']} />;
+            }
+
+            hasAnyTrashedResources = () => {
+                // TODO: implement check if there is anything in the trash,
+                //       without taking pagination into the account
+                return true;
             }
 
             handleContextMenu = (event: React.MouseEvent<HTMLElement>, resourceUuid: string) => {