public-fav-panel
authorPawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>
Tue, 2 Apr 2019 12:59:30 +0000 (14:59 +0200)
committerPawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>
Tue, 2 Apr 2019 12:59:30 +0000 (14:59 +0200)
Feature #14941

Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk <pawel.kowalczyk@contractors.roche.com>

src/store/public-favorites-panel/public-favorites-middleware-service.ts
src/store/workbench/workbench-actions.ts
src/views-components/data-explorer/renderers.tsx
src/views-components/favorite-star/favorite-star.tsx
src/views-components/public-favorite-icon/public-favorite-icon.tsx [deleted file]
src/views/public-favorites-panel/public-favorites-panel.tsx

index 3f686498ce9a6a17b2f5088acf30a600883de1fd..c7bbf8dd1e957bdc651627ffcb677e73664c7aa6 100644 (file)
@@ -17,7 +17,7 @@ import { FavoritePanelColumnNames } from '~/views/favorite-panel/favorite-panel'
 import { publicFavoritePanelActions } from '~/store/public-favorites-panel/public-favorites-action';
 import { DataColumns } from '~/components/data-table/data-table';
 import { serializeSimpleObjectTypeFilters } from '../resource-type-filters/resource-type-filters';
-import { LinkResource } from '~/models/link';
+import { LinkResource, LinkClass } from '~/models/link';
 import { GroupContentsResource, GroupContentsResourcePrefix } from '~/services/groups-service/groups-service';
 import { progressIndicatorActions } from '~/store/progress-indicator/progress-indicator-actions';
 import { loadMissingProcessesInformation } from '~/store/project-panel/project-panel-middleware-service';
@@ -54,28 +54,27 @@ export class PublicFavoritesMiddlewareService extends DataExplorerMiddlewareServ
             }
             try {
                 api.dispatch(progressIndicatorActions.START_WORKING(this.getId()));
-                const response = await this.services.favoriteService
-                    .list(this.services.authService.getUuid()!, {
-                        limit: dataExplorer.rowsPerPage,
-                        offset: dataExplorer.page * dataExplorer.rowsPerPage,
-                        linkOrder: linkOrder.getOrder(),
-                        contentOrder: contentOrder.getOrder(),
-                        filters: new FilterBuilder()
-                            .addILike("name", dataExplorer.searchValue)
-                            .addIsA("headUuid", typeFilters)
-                            .getFilters(),
-
-                    });
+                const uuidPrefix = api.getState().config.uuidPrefix;
+                const uuid = `${uuidPrefix}-j7d0g-fffffffffffffff`;
+                const response = await this.services.linkService.list({
+                    limit: dataExplorer.rowsPerPage,
+                    offset: dataExplorer.page * dataExplorer.rowsPerPage,
+                    filters: new FilterBuilder()
+                        .addEqual('linkClass', LinkClass.STAR)
+                        .addILike("name", dataExplorer.searchValue)
+                        .addEqual('ownerUuid', uuid)
+                        .addIsA("headUuid", typeFilters)
+                        .getFilters()
+                });
                 api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
                 api.dispatch(resourcesActions.SET_RESOURCES(response.items));
-                await api.dispatch<any>(loadMissingProcessesInformation(response.items));
                 api.dispatch(publicFavoritePanelActions.SET_ITEMS({
                     items: response.items.map(resource => resource.uuid),
                     itemsAvailable: response.itemsAvailable,
                     page: Math.floor(response.offset / response.limit),
                     rowsPerPage: response.limit
                 }));
-                api.dispatch<any>(updatePublicFavorites(response.items.map(item => item.uuid)));
+                api.dispatch<any>(updatePublicFavorites(response.items.map(item => item.headUuid)));
             } catch (e) {
                 api.dispatch(progressIndicatorActions.PERSIST_STOP_WORKING(this.getId()));
                 api.dispatch(publicFavoritePanelActions.SET_ITEMS({
index e2276cef71c02cb1f781ae50de9fe640249b2d0a..adf3fa15aeeb416f927ed99a3f483e4ae7894325 100644 (file)
@@ -93,6 +93,7 @@ import * as groupDetailsPanelActions from '~/store/group-details-panel/group-det
 import { groupDetailsPanelColumns } from '~/views/group-details-panel/group-details-panel';
 import { DataTableFetchMode } from "~/components/data-table/data-table";
 import { loadPublicFavoritePanel, publicFavoritePanelActions } from '~/store/public-favorites-panel/public-favorites-action';
+import { publicFavoritePanelColumns } from '~/views/public-favorites-panel/public-favorites-panel';
 
 export const WORKBENCH_LOADING_SCREEN = 'workbenchLoadingScreen';
 
@@ -120,7 +121,7 @@ export const loadWorkbench = () =>
         if (user) {
             dispatch(projectPanelActions.SET_COLUMNS({ columns: projectPanelColumns }));
             dispatch(favoritePanelActions.SET_COLUMNS({ columns: favoritePanelColumns }));
-            dispatch(publicFavoritePanelActions.SET_COLUMNS({ columns: favoritePanelColumns }));
+            dispatch(publicFavoritePanelActions.SET_COLUMNS({ columns: publicFavoritePanelColumns }));
             dispatch(trashPanelActions.SET_COLUMNS({ columns: trashPanelColumns }));
             dispatch(sharedWithMePanelActions.SET_COLUMNS({ columns: projectPanelColumns }));
             dispatch(workflowPanelActions.SET_COLUMNS({ columns: workflowPanelColumns }));
index 8ca4deff6e93a8eee3d68a2cdb7b14a4fdce4a16..04dbfa7c03ae05f40cf5a42003728d2ce91cddbd 100644 (file)
@@ -26,12 +26,11 @@ import { toggleIsActive, toggleIsAdmin } from '~/store/users/users-actions';
 import { LinkResource } from '~/models/link';
 import { navigateTo } from '~/store/navigation/navigation-action';
 import { withResourceData } from '~/views-components/data-explorer/with-resources';
-import { PublicFavorite } from '~/views-components/public-favorite-icon/public-favorite-icon';
 
 const renderName = (item: { name: string; uuid: string, kind: string }) =>
     <Grid container alignItems="center" wrap="nowrap" spacing={16}>
         <Grid item>
-            {renderIcon(item)}
+            {renderIcon(item.kind)}
         </Grid>
         <Grid item>
             <Typography color="primary" style={{ width: 'auto' }}>
@@ -43,11 +42,6 @@ const renderName = (item: { name: string; uuid: string, kind: string }) =>
                 <FavoriteStar resourceUuid={item.uuid} />
             </Typography>
         </Grid>
-        <Grid item>
-            <Typography variant="caption">
-                <PublicFavorite resourceUuid={item.uuid} />
-            </Typography>
-        </Grid>
     </Grid>;
 
 export const ResourceName = connect(
@@ -56,8 +50,8 @@ export const ResourceName = connect(
         return resource || { name: '', uuid: '', kind: '' };
     })(renderName);
 
-const renderIcon = (item: { kind: string }) => {
-    switch (item.kind) {
+const renderIcon = (kind: string) => {
+    switch (kind) {
         case ResourceKind.PROJECT:
             return <ProjectIcon />;
         case ResourceKind.COLLECTION:
@@ -78,7 +72,7 @@ const renderDate = (date?: string) => {
 const renderWorkflowName = (item: { name: string; uuid: string, kind: string, ownerUuid: string }) =>
     <Grid container alignItems="center" wrap="nowrap" spacing={16}>
         <Grid item>
-            {renderIcon(item)}
+            {renderIcon(item.kind)}
         </Grid>
         <Grid item>
             <Typography color="primary" style={{ width: '100px' }}>
@@ -332,6 +326,35 @@ export const ResourceLinkUuid = connect(
         return resource || { uuid: '' };
     })(renderUuid);
 
+const renderLinkNameAndIcon = (item: { name: string; headUuid: string, headKind: string }) =>
+    <Grid container alignItems="center" wrap="nowrap" spacing={16}>
+        <Grid item>
+            {renderIcon(item.headKind)}
+        </Grid>
+        <Grid item>
+            <Typography color="primary" style={{ width: 'auto' }}>
+                {item.name}
+            </Typography>
+        </Grid>
+        <Grid item>
+            <Typography variant="caption">
+                <FavoriteStar resourceUuid={item.headUuid} />
+            </Typography>
+        </Grid>
+    </Grid>;
+
+export const ResourceLinkNameAndIcon = connect(
+    (state: RootState, props: { uuid: string }) => {
+        const resource = getResource<LinkResource>(props.uuid)(state.resources);
+        return resource || { name: '', headUuid: '', headKind: '' };
+    })(renderLinkNameAndIcon);
+
+export const ResourceLinkType = connect(
+    (state: RootState, props: { uuid: string }) => {
+        const resource = getResource<LinkResource>(props.uuid)(state.resources);
+        return { type: resource ? resource.headKind : '' };
+    })((props: { type: string }) => renderType(props.type));
+
 // Process Resources
 const resourceRunProcess = (dispatch: Dispatch, uuid: string) => {
     return (
index 755cc67c265b52e0b80c12b04561f6b081bb989a..586b442d6371066ffed728463bec28ae432509bf 100644 (file)
@@ -18,10 +18,17 @@ const styles: StyleRulesCallback<CssRules> = theme => ({
 
 const mapStateToProps = (state: RootState, props: { resourceUuid: string; className?: string; }) => ({
     ...props,
-    visible: state.favorites[props.resourceUuid],
+    isFavoriteVisible: state.favorites[props.resourceUuid],
+    isPublicFavoriteVisible: state.publicFavorites[props.resourceUuid]
 });
 
 export const FavoriteStar = connect(mapStateToProps)(
-    withStyles(styles)((props: { visible: boolean; className?: string; } & WithStyles<CssRules>) =>
-        props.visible ? <FavoriteIcon className={props.className || props.classes.icon} /> : null
-    ));
+    withStyles(styles)((props: { isFavoriteVisible: boolean; isPublicFavoriteVisible: boolean; className?: string; } & WithStyles<CssRules>) => {
+        if (props.isPublicFavoriteVisible) {
+            return <FavoriteIcon className={props.className || props.classes.icon} />;
+        } else if (props.isFavoriteVisible) {
+            return <FavoriteIcon className={props.className || props.classes.icon} />;
+        } else {
+            return null;
+        }
+    }));
diff --git a/src/views-components/public-favorite-icon/public-favorite-icon.tsx b/src/views-components/public-favorite-icon/public-favorite-icon.tsx
deleted file mode 100644 (file)
index 30b3aa9..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (C) The Arvados Authors. All rights reserved.
-//
-// SPDX-License-Identifier: AGPL-3.0
-
-import * as React from "react";
-import { FavoriteIcon } from "~/components/icon/icon";
-import { connect } from "react-redux";
-import { RootState } from "~/store/store";
-import { withStyles, StyleRulesCallback, WithStyles } from "@material-ui/core";
-
-type CssRules = "icon";
-
-const styles: StyleRulesCallback<CssRules> = theme => ({
-    icon: {
-        fontSize: "inherit"
-    }
-});
-
-const mapStateToProps = (state: RootState, props: { resourceUuid: string; className?: string; }) => ({
-    ...props,
-    visible: state.publicFavorites[props.resourceUuid],
-});
-
-export const PublicFavorite = connect(mapStateToProps)(
-    withStyles(styles)((props: { visible: boolean; className?: string; } & WithStyles<CssRules>) =>
-        props.visible ? <FavoriteIcon className={props.className || props.classes.icon} /> : null
-    ));
index f559a616ebeb18f271f251abe21f263debba229d..3970418f4894bbc10defce05923f443315ab103d 100644 (file)
@@ -16,9 +16,8 @@ import {
     ProcessStatus,
     ResourceFileSize,
     ResourceLastModifiedDate,
-    ResourceName,
-    ResourceOwner,
-    ResourceType
+    ResourceLinkNameAndIcon,
+    ResourceLinkType
 } from '~/views-components/data-explorer/renderers';
 import { FavoriteIcon } from '~/components/icon/icon';
 import { Dispatch } from 'redux';
@@ -26,12 +25,12 @@ 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 { FavoritesState } from '~/store/favorites/favorites-reducer';
 import { RootState } from '~/store/store';
 import { DataTableDefaultView } from '~/components/data-table-default-view/data-table-default-view';
 import { createTree } from '~/models/tree';
 import { getSimpleObjectTypeFilters } from '~/store/resource-type-filters/resource-type-filters';
 import { PUBLIC_FAVORITE_PANEL_ID } from '~/store/public-favorites-panel/public-favorites-action';
+import { PublicFavoritesState } from '~/store/public-favorites/public-favorites-reducer';
 
 type CssRules = "toolbar" | "button";
 
@@ -58,14 +57,14 @@ export interface FavoritePanelFilter extends DataTableFilterItem {
     type: ResourceKind | ContainerRequestState;
 }
 
-export const favoritePanelColumns: DataColumns<string> = [
+export const publicFavoritePanelColumns: DataColumns<string> = [
     {
         name: FavoritePanelColumnNames.NAME,
         selected: true,
         configurable: true,
         sortDirection: SortDirection.NONE,
         filters: createTree(),
-        render: uuid => <ResourceName uuid={uuid} />
+        render: uuid => <ResourceLinkNameAndIcon uuid={uuid} />
     },
     {
         name: "Status",
@@ -79,14 +78,7 @@ export const favoritePanelColumns: DataColumns<string> = [
         selected: true,
         configurable: true,
         filters: getSimpleObjectTypeFilters(),
-        render: uuid => <ResourceType uuid={uuid} />
-    },
-    {
-        name: FavoritePanelColumnNames.OWNER,
-        selected: true,
-        configurable: true,
-        filters: createTree(),
-        render: uuid => <ResourceOwner uuid={uuid} />
+        render: uuid => <ResourceLinkType uuid={uuid} />
     },
     {
         name: FavoritePanelColumnNames.FILE_SIZE,
@@ -105,21 +97,21 @@ export const favoritePanelColumns: DataColumns<string> = [
     }
 ];
 
-interface FavoritePanelDataProps {
-    favorites: FavoritesState;
+interface PublicFavoritePanelDataProps {
+    publicFavorites: PublicFavoritesState;
 }
 
-interface FavoritePanelActionProps {
+interface PublicFavoritePanelActionProps {
     onItemClick: (item: string) => void;
     onContextMenu: (event: React.MouseEvent<HTMLElement>, item: string) => void;
     onDialogOpen: (ownerUuid: string) => void;
     onItemDoubleClick: (item: string) => void;
 }
-const mapStateToProps = ({ favorites }: RootState): FavoritePanelDataProps => ({
-    favorites
+const mapStateToProps = ({ publicFavorites }: RootState): PublicFavoritePanelDataProps => ({
+    publicFavorites
 });
 
-const mapDispatchToProps = (dispatch: Dispatch): FavoritePanelActionProps => ({
+const mapDispatchToProps = (dispatch: Dispatch): PublicFavoritePanelActionProps => ({
     onContextMenu: (event, resourceUuid) => {
         const kind = resourceKindToContextMenuKind(resourceUuid);
         if (kind) {
@@ -142,7 +134,7 @@ const mapDispatchToProps = (dispatch: Dispatch): FavoritePanelActionProps => ({
     }
 });
 
-type FavoritePanelProps = FavoritePanelDataProps & FavoritePanelActionProps & DispatchProp
+type FavoritePanelProps = PublicFavoritePanelDataProps & PublicFavoritePanelActionProps & DispatchProp
     & WithStyles<CssRules> & RouteComponentProps<{ id: string }>;
 
 export const PublicFavoritePanel = withStyles(styles)(
@@ -158,8 +150,7 @@ export const PublicFavoritePanel = withStyles(styles)(
                     dataTableDefaultView={
                         <DataTableDefaultView
                             icon={FavoriteIcon}
-                            messages={['Public favorites list is empty.']}
-                            />
+                            messages={['Public favorites list is empty.']} />
                     } />;
             }
         }