From 215016dc53873f311b5eb3e7e86f2d967ec447fe Mon Sep 17 00:00:00 2001 From: Peter Amstutz Date: Thu, 16 May 2019 13:34:01 -0400 Subject: [PATCH] 15230: Link to other workbenches when double-clicking search results. * Fix links in details panel. * Remove redirect to user column from users. Redirected users are hidden so this column is always null. * Fix additional details panels to use linkToUuid * Uuid or PDH entered into the search bar will navigate directly * Add portable data hash to collection page, make it clickable and copyable. Arvados-DCO-1.1-Signed-off-by: Peter Amstutz --- .../details-attribute/details-attribute.tsx | 46 +++++++++++----- src/models/resource.ts | 7 ++- src/routes/routes.ts | 34 +++++++++++- src/store/navigation/navigation-action.ts | 40 +++++++------- .../process-logs-panel-actions.ts | 4 +- .../process-panel/process-panel-actions.ts | 4 +- .../run-process-panel-actions.ts | 6 +-- src/store/search-bar/search-bar-actions.ts | 16 +++--- src/store/users/users-actions.ts | 6 +-- src/store/workbench/workbench-actions.ts | 4 +- .../data-explorer/renderers.tsx | 4 +- .../details-panel/collection-details.tsx | 6 +-- .../details-panel/process-details.tsx | 13 +++-- .../details-panel/project-details.tsx | 53 ++++++++++--------- src/views-components/snackbar/snackbar.tsx | 8 +-- .../collection-panel/collection-panel.tsx | 18 +++++-- .../search-results-panel-view.tsx | 24 +-------- .../search-results-panel.tsx | 40 ++++++++------ src/views/user-panel/user-panel.tsx | 8 --- 19 files changed, 197 insertions(+), 144 deletions(-) diff --git a/src/components/details-attribute/details-attribute.tsx b/src/components/details-attribute/details-attribute.tsx index 3586d22d..aa177882 100644 --- a/src/components/details-attribute/details-attribute.tsx +++ b/src/components/details-attribute/details-attribute.tsx @@ -3,11 +3,14 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; +import { connect } from 'react-redux'; import Typography from '@material-ui/core/Typography'; import { StyleRulesCallback, WithStyles, withStyles } from '@material-ui/core/styles'; import { ArvadosTheme } from '~/common/custom-theme'; import * as classnames from "classnames"; import { Link } from 'react-router-dom'; +import { RootState } from "~/store/store"; +import { FederationConfig, getNavUrl } from "~/routes/routes"; type CssRules = 'attribute' | 'label' | 'value' | 'lowercaseValue' | 'link'; @@ -26,8 +29,7 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ boxSizing: 'border-box', width: '60%', display: 'flex', - alignItems: 'flex-start', - textTransform: 'capitalize' + alignItems: 'flex-start' }, lowercaseValue: { textTransform: 'lowercase' @@ -50,18 +52,36 @@ interface DetailsAttributeDataProps { link?: string; children?: React.ReactNode; onValueClick?: () => void; - linkInsideCard?: string; + linkToUuid?: string; } -type DetailsAttributeProps = DetailsAttributeDataProps & WithStyles; +type DetailsAttributeProps = DetailsAttributeDataProps & WithStyles & FederationConfig; + +const mapStateToProps = ({ auth }: RootState): FederationConfig => ({ + localCluster: auth.localCluster, + remoteHostsConfig: auth.remoteHostsConfig, + sessions: auth.sessions +}); -export const DetailsAttribute = withStyles(styles)( - ({ label, link, value, children, classes, classLabel, classValue, lowercaseValue, onValueClick, linkInsideCard }: DetailsAttributeProps) => - +export const DetailsAttribute = connect(mapStateToProps)(withStyles(styles)( + ({ label, link, value, children, classes, classLabel, + classValue, lowercaseValue, onValueClick, linkToUuid, + localCluster, remoteHostsConfig, sessions }: DetailsAttributeProps) => { + let insertLink: React.ReactNode; + if (linkToUuid) { + const linkUrl = getNavUrl(linkToUuid || "", { localCluster, remoteHostsConfig, sessions }); + if (linkUrl[0] === '/') { + insertLink = {value}; + } else { + insertLink = {value}; + } + } else if (link) { + insertLink = {value}; + } + return {label} - {link && {value}} - {linkInsideCard && {value}} - {!link && !linkInsideCard && @@ -69,6 +89,6 @@ export const DetailsAttribute = withStyles(styles)( {children} } - - -); + ; + } +)); diff --git a/src/models/resource.ts b/src/models/resource.ts index 31f3eb88..2af51ecb 100644 --- a/src/models/resource.ts +++ b/src/models/resource.ts @@ -57,8 +57,9 @@ export enum ResourceObjectType { NODE = '7ekkf' } -export const RESOURCE_UUID_PATTERN = '.{5}-.{5}-.{15}'; +export const RESOURCE_UUID_PATTERN = '[a-z0-9]{5}-[a-z0-9]{5}-[a-z0-9]{15}'; export const RESOURCE_UUID_REGEX = new RegExp(RESOURCE_UUID_PATTERN); +export const COLLECTION_PDH_REGEX = /[a-f0-9]{32}\+\d+/; export const isResourceUuid = (uuid: string) => RESOURCE_UUID_REGEX.test(uuid); @@ -102,6 +103,8 @@ export const extractUuidKind = (uuid: string = '') => { case ResourceObjectType.LINK: return ResourceKind.LINK; default: - return undefined; + const match = COLLECTION_PDH_REGEX.exec(uuid); + console.log("matching " + match); + return match ? ResourceKind.COLLECTION : undefined; } }; diff --git a/src/routes/routes.ts b/src/routes/routes.ts index 831c69e5..ae418b80 100644 --- a/src/routes/routes.ts +++ b/src/routes/routes.ts @@ -3,9 +3,17 @@ // SPDX-License-Identifier: AGPL-3.0 import { matchPath } from 'react-router'; -import { ResourceKind, RESOURCE_UUID_PATTERN, extractUuidKind } from '~/models/resource'; +import { ResourceKind, RESOURCE_UUID_PATTERN, extractUuidKind, COLLECTION_PDH_REGEX } from '~/models/resource'; import { getProjectUrl } from '~/models/project'; import { getCollectionUrl } from '~/models/collection'; +import { Config } from '~/common/config'; +import { Session } from "~/models/session"; + +export interface FederationConfig { + localCluster: string; + remoteHostsConfig: { [key: string]: Config }; + sessions: Session[]; +} export const Routes = { ROOT: '/', @@ -41,9 +49,12 @@ export const Routes = { export const getResourceUrl = (uuid: string) => { const kind = extractUuidKind(uuid); + console.log(`for ${uuid} the kind is ${kind}`); switch (kind) { case ResourceKind.PROJECT: return getProjectUrl(uuid); + case ResourceKind.USER: + return getProjectUrl(uuid); case ResourceKind.COLLECTION: return getCollectionUrl(uuid); case ResourceKind.PROCESS: @@ -53,6 +64,27 @@ export const getResourceUrl = (uuid: string) => { } }; +export const getNavUrl = (uuid: string, config: FederationConfig) => { + const path = getResourceUrl(uuid) || ""; + const cls = uuid.substr(0, 5); + if (cls === config.localCluster || extractUuidKind(uuid) === ResourceKind.USER || COLLECTION_PDH_REGEX.exec(uuid)) { + return path; + } else if (config.remoteHostsConfig[cls]) { + let u: URL; + if (config.remoteHostsConfig[cls].workbench2Url) { + u = new URL(config.remoteHostsConfig[cls].workbench2Url || ""); + } else { + u = new URL(config.remoteHostsConfig[cls].workbenchUrl); + u.search = "api_token=" + config.sessions.filter((s) => s.clusterId === cls)[0].token; + } + u.pathname = path; + return u.toString(); + } else { + return ""; + } +}; + + export const getProcessUrl = (uuid: string) => `/processes/${uuid}`; export const getProcessLogUrl = (uuid: string) => `/process-logs/${uuid}`; diff --git a/src/store/navigation/navigation-action.ts b/src/store/navigation/navigation-action.ts index d7ad0178..b5d769e7 100644 --- a/src/store/navigation/navigation-action.ts +++ b/src/store/navigation/navigation-action.ts @@ -2,26 +2,22 @@ // // SPDX-License-Identifier: AGPL-3.0 -import { Dispatch, compose } from 'redux'; -import { push } from "react-router-redux"; +import { Dispatch, compose, AnyAction } from 'redux'; +import { push, RouterAction } from "react-router-redux"; import { ResourceKind, extractUuidKind } from '~/models/resource'; import { getCollectionUrl } from "~/models/collection"; import { getProjectUrl } from "~/models/project"; import { SidePanelTreeCategory } from '../side-panel-tree/side-panel-tree-actions'; -import { Routes, getProcessUrl, getProcessLogUrl, getGroupUrl } from '~/routes/routes'; +import { Routes, getProcessUrl, getProcessLogUrl, getGroupUrl, getNavUrl } from '~/routes/routes'; import { RootState } from '~/store/store'; import { ServiceRepository } from '~/services/services'; import { GROUPS_PANEL_LABEL } from '~/store/breadcrumbs/breadcrumbs-actions'; export const navigateTo = (uuid: string) => - async (dispatch: Dispatch) => { + async (dispatch: Dispatch, getState: () => RootState) => { const kind = extractUuidKind(uuid); - if (kind === ResourceKind.PROJECT || kind === ResourceKind.USER) { - dispatch(navigateToProject(uuid)); - } else if (kind === ResourceKind.COLLECTION) { - dispatch(navigateToCollection(uuid)); - } else if (kind === ResourceKind.CONTAINER_REQUEST) { - dispatch(navigateToProcess(uuid)); + if (kind === ResourceKind.PROJECT || kind === ResourceKind.USER || kind === ResourceKind.COLLECTION || kind === ResourceKind.CONTAINER_REQUEST) { + dispatch(pushOrGoto(getNavUrl(uuid, getState().auth))); } else if (kind === ResourceKind.VIRTUAL_MACHINE) { dispatch(navigateToAdminVirtualMachines); } @@ -50,18 +46,26 @@ export const navigateToPublicFavorites = push(Routes.PUBLIC_FAVORITES); export const navigateToWorkflows = push(Routes.WORKFLOWS); -export const navigateToProject = compose(push, getProjectUrl); - -export const navigateToCollection = compose(push, getCollectionUrl); +export const pushOrGoto = (url: string): AnyAction => { + if (url === "") { + console.log("url should not be empty"); + return { type: "noop" }; + } else if (url[0] === '/') { + return push(url); + } else { + window.location.href = url; + return { type: "noop" }; + } +}; -export const navigateToProcess = compose(push, getProcessUrl); export const navigateToProcessLogs = compose(push, getProcessLogUrl); export const navigateToRootProject = (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { const rootProjectUuid = services.authService.getUuid(); + console.log("rootProjectUuid " + rootProjectUuid); if (rootProjectUuid) { - dispatch(navigateToProject(rootProjectUuid)); + dispatch(navigateTo(rootProjectUuid)); } }; @@ -77,11 +81,11 @@ export const navigateToAdminVirtualMachines = push(Routes.VIRTUAL_MACHINES_ADMIN export const navigateToRepositories = push(Routes.REPOSITORIES); -export const navigateToSshKeysAdmin= push(Routes.SSH_KEYS_ADMIN); +export const navigateToSshKeysAdmin = push(Routes.SSH_KEYS_ADMIN); -export const navigateToSshKeysUser= push(Routes.SSH_KEYS_USER); +export const navigateToSshKeysUser = push(Routes.SSH_KEYS_USER); -export const navigateToSiteManager= push(Routes.SITE_MANAGER); +export const navigateToSiteManager = push(Routes.SITE_MANAGER); export const navigateToMyAccount = push(Routes.MY_ACCOUNT); diff --git a/src/store/process-logs-panel/process-logs-panel-actions.ts b/src/store/process-logs-panel/process-logs-panel-actions.ts index bf0dc935..fcb1b0ea 100644 --- a/src/store/process-logs-panel/process-logs-panel-actions.ts +++ b/src/store/process-logs-panel/process-logs-panel-actions.ts @@ -16,7 +16,7 @@ import { ResourceEventMessage } from '~/websocket/resource-event-message'; import { getProcess } from '~/store/processes/process'; import { FilterBuilder } from "~/services/api/filter-builder"; import { OrderBuilder } from "~/services/api/order-builder"; -import { navigateToCollection } from '~/store/navigation/navigation-action'; +import { navigateTo } from '~/store/navigation/navigation-action'; import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions'; export const processLogsPanelActions = unionize({ @@ -104,7 +104,7 @@ export const navigateToLogCollection = (uuid: string) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { try { await services.collectionService.get(uuid); - dispatch(navigateToCollection(uuid)); + dispatch(navigateTo(uuid)); } catch { dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'This collection does not exists!', hideDuration: 2000, kind: SnackbarKind.ERROR })); } diff --git a/src/store/process-panel/process-panel-actions.ts b/src/store/process-panel/process-panel-actions.ts index 42a718bd..da917f71 100644 --- a/src/store/process-panel/process-panel-actions.ts +++ b/src/store/process-panel/process-panel-actions.ts @@ -8,7 +8,7 @@ import { Dispatch } from 'redux'; import { ProcessStatus } from '~/store/processes/process'; import { RootState } from '~/store/store'; import { ServiceRepository } from "~/services/services"; -import { navigateToCollection, navigateToWorkflows } from '~/store/navigation/navigation-action'; +import { navigateTo, navigateToWorkflows } from '~/store/navigation/navigation-action'; import { snackbarActions } from '~/store/snackbar/snackbar-actions'; import { SnackbarKind } from '../snackbar/snackbar-actions'; import { showWorkflowDetails } from '~/store/workflow-panel/workflow-panel-actions'; @@ -32,7 +32,7 @@ export const navigateToOutput = (uuid: string) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { try { await services.collectionService.get(uuid); - dispatch(navigateToCollection(uuid)); + dispatch(navigateTo(uuid)); } catch { dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'This collection does not exists!', hideDuration: 2000, kind: SnackbarKind.ERROR })); } diff --git a/src/store/run-process-panel/run-process-panel-actions.ts b/src/store/run-process-panel/run-process-panel-actions.ts index 94759483..7203d375 100644 --- a/src/store/run-process-panel/run-process-panel-actions.ts +++ b/src/store/run-process-panel/run-process-panel-actions.ts @@ -13,7 +13,7 @@ import { RUN_PROCESS_INPUTS_FORM } from '~/views/run-process-panel/run-process-i import { WorkflowInputsData } from '~/models/workflow'; import { createWorkflowMounts } from '~/models/process'; import { ContainerRequestState } from '~/models/container-request'; -import { navigateToProcess } from '../navigation/navigation-action'; +import { navigateTo } from '../navigation/navigation-action'; import { RunProcessAdvancedFormData, RUN_PROCESS_ADVANCED_FORM, VCPUS_FIELD, RAM_FIELD, RUNTIME_FIELD, OUTPUT_FIELD, API_FIELD } from '~/views/run-process-panel/run-process-advanced-form'; import { dialogActions } from '~/store/dialog/dialog-actions'; import { setBreadcrumbs } from '~/store/breadcrumbs/breadcrumbs-actions'; @@ -152,10 +152,10 @@ export const runProcess = async (dispatch: Dispatch, getState: () => RootSt properties: { workflowUuid: selectedWorkflow.uuid, workflowName: selectedWorkflow.name - } + } }; const newProcess = await services.containerRequestService.create(newProcessData); - dispatch(navigateToProcess(newProcess.uuid)); + dispatch(navigateTo(newProcess.uuid)); } }; diff --git a/src/store/search-bar/search-bar-actions.ts b/src/store/search-bar/search-bar-actions.ts index 8734888b..68efb4e6 100644 --- a/src/store/search-bar/search-bar-actions.ts +++ b/src/store/search-bar/search-bar-actions.ts @@ -10,7 +10,7 @@ import { RootState } from '~/store/store'; import { initUserProject, treePickerActions } from '~/store/tree-picker/tree-picker-actions'; import { ServiceRepository } from '~/services/services'; import { FilterBuilder } from "~/services/api/filter-builder"; -import { ResourceKind, isResourceUuid, extractUuidKind } from '~/models/resource'; +import { ResourceKind, isResourceUuid, extractUuidKind, RESOURCE_UUID_REGEX, COLLECTION_PDH_REGEX } from '~/models/resource'; import { SearchView } from '~/store/search-bar/search-bar-reducer'; import { navigateTo, navigateToSearchResults } from '~/store/navigation/navigation-action'; import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions'; @@ -192,10 +192,14 @@ export const submitData = (event: React.FormEvent) => dispatch(saveRecentQuery(searchValue)); dispatch(loadRecentQueries()); dispatch(searchBarActions.CLOSE_SEARCH_VIEW()); - dispatch(searchBarActions.SET_SEARCH_VALUE(searchValue)); - dispatch(searchBarActions.SET_SEARCH_RESULTS([])); - dispatch(searchResultsPanelActions.CLEAR()); - dispatch(navigateToSearchResults); + if (RESOURCE_UUID_REGEX.exec(searchValue) || COLLECTION_PDH_REGEX.exec(searchValue)) { + dispatch(navigateTo(searchValue)); + } else { + dispatch(searchBarActions.SET_SEARCH_VALUE(searchValue)); + dispatch(searchBarActions.SET_SEARCH_RESULTS([])); + dispatch(searchResultsPanelActions.CLEAR()); + dispatch(navigateToSearchResults); + } }; @@ -327,7 +331,7 @@ export const queryToFilters = (query: string) => { const filter = new FilterBuilder(); const resourceKind = data.type; - if(data.searchValue){ + if (data.searchValue) { filter.addFullTextSearch(data.searchValue); } diff --git a/src/store/users/users-actions.ts b/src/store/users/users-actions.ts index caf466f7..1a567e9d 100644 --- a/src/store/users/users-actions.ts +++ b/src/store/users/users-actions.ts @@ -11,7 +11,7 @@ import { startSubmit, reset } from "redux-form"; import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions'; import { UserResource } from "~/models/user"; import { getResource } from '~/store/resources/resources'; -import { navigateToProject, navigateToUsers, navigateToRootProject } from "~/store/navigation/navigation-action"; +import { navigateTo, navigateToUsers, navigateToRootProject } from "~/store/navigation/navigation-action"; import { saveApiToken } from '~/store/auth/auth-action'; export const USERS_PANEL_ID = 'usersPanel'; @@ -73,7 +73,7 @@ export const openUserCreateDialog = () => export const openUserProjects = (uuid: string) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { - dispatch(navigateToProject(uuid)); + dispatch(navigateTo(uuid)); }; @@ -134,4 +134,4 @@ export const loadUsersData = () => export const loadUsersPanel = () => (dispatch: Dispatch) => { dispatch(userBindedActions.REQUEST_ITEMS()); - }; \ No newline at end of file + }; diff --git a/src/store/workbench/workbench-actions.ts b/src/store/workbench/workbench-actions.ts index 2363b579..fb85c0e0 100644 --- a/src/store/workbench/workbench-actions.ts +++ b/src/store/workbench/workbench-actions.ts @@ -32,7 +32,7 @@ import { setSidePanelBreadcrumbs, setTrashBreadcrumbs } from '~/store/breadcrumbs/breadcrumbs-actions'; -import { navigateToProject } from '~/store/navigation/navigation-action'; +import { navigateTo } from '~/store/navigation/navigation-action'; import { MoveToFormDialogData } from '~/store/move-to-dialog/move-to-dialog'; import { ServiceRepository } from '~/services/services'; import { getResource } from '~/store/resources/resources'; @@ -140,7 +140,7 @@ export const loadWorkbench = () => if (router.location) { const match = matchRootRoute(router.location.pathname); if (match) { - dispatch(navigateToProject(user.uuid)); + dispatch(navigateTo(user.uuid)); } } } else { diff --git a/src/views-components/data-explorer/renderers.tsx b/src/views-components/data-explorer/renderers.tsx index bf504f2b..cc311248 100644 --- a/src/views-components/data-explorer/renderers.tsx +++ b/src/views-components/data-explorer/renderers.tsx @@ -239,12 +239,12 @@ export const ResourceCluster = (props: { uuid: string }) => { const clusterId = pos >= CLUSTER_ID_LENGTH ? props.uuid.substr(0, pos) : ''; const ci = pos >= CLUSTER_ID_LENGTH ? (props.uuid.charCodeAt(0) + props.uuid.charCodeAt(1)) % clusterColors.length : 0; return -
{clusterId}
+ }}>{clusterId}
; }; diff --git a/src/views-components/details-panel/collection-details.tsx b/src/views-components/details-panel/collection-details.tsx index ec5bdabd..a523d6fc 100644 --- a/src/views-components/details-panel/collection-details.tsx +++ b/src/views-components/details-panel/collection-details.tsx @@ -21,11 +21,11 @@ export class CollectionDetails extends DetailsData { return
- + - - + + {/* Missing attrs */} diff --git a/src/views-components/details-panel/process-details.tsx b/src/views-components/details-panel/process-details.tsx index e3c9823d..b6fdaa6f 100644 --- a/src/views-components/details-panel/process-details.tsx +++ b/src/views-components/details-panel/process-details.tsx @@ -13,7 +13,7 @@ import { DetailsAttribute } from "~/components/details-attribute/details-attribu export class ProcessDetails extends DetailsData { - getIcon(className?: string){ + getIcon(className?: string) { return ; } @@ -31,15 +31,14 @@ export class ProcessDetails extends DetailsData { - {/* Links but we dont have view */} - - - + + + - {/* Link but we dont have view */} - + +
; } } diff --git a/src/views-components/details-panel/project-details.tsx b/src/views-components/details-panel/project-details.tsx index 91c5e027..1ec1c60c 100644 --- a/src/views-components/details-panel/project-details.tsx +++ b/src/views-components/details-panel/project-details.tsx @@ -57,31 +57,32 @@ const ProjectDetailsComponent = connect(null, mapDispatchToProps)( withStyles(styles)( ({ classes, project, onClick }: ProjectDetailsComponentProps) =>
- {/* Missing attr */} - - - - - {/* Missing attr */} - {/**/} - - {project.description ? - - : '---' - } - - -
- -
-
- { - Object.keys(project.properties).map(k => { - return ; - }) + {/* Missing attr */} + + + + + + {/* Missing attr */} + {/**/} + + {project.description ? + + : '---' } + + +
+ +
+
+ { + Object.keys(project.properties).map(k => { + return ; + }) + }
-)); \ No newline at end of file + )); diff --git a/src/views-components/snackbar/snackbar.tsx b/src/views-components/snackbar/snackbar.tsx index 4250dcdf..c5d0f483 100644 --- a/src/views-components/snackbar/snackbar.tsx +++ b/src/views-components/snackbar/snackbar.tsx @@ -9,7 +9,7 @@ import { RootState } from "~/store/store"; import { Button, IconButton, StyleRulesCallback, WithStyles, withStyles, SnackbarContent } from '@material-ui/core'; import MaterialSnackbar, { SnackbarOrigin } from "@material-ui/core/Snackbar"; import { snackbarActions, SnackbarKind } from "~/store/snackbar/snackbar-actions"; -import { navigateToProject } from '~/store/navigation/navigation-action'; +import { navigateTo } from '~/store/navigation/navigation-action'; import WarningIcon from '@material-ui/icons/Warning'; import CheckCircleIcon from '@material-ui/icons/CheckCircle'; import ErrorIcon from '@material-ui/icons/Error'; @@ -56,7 +56,7 @@ const mapDispatchToProps = (dispatch: Dispatch): SnackbarEventProps => ({ dispatch(snackbarActions.SHIFT_MESSAGES()); }, onClick: (uuid: string) => { - dispatch(navigateToProject(uuid)); + dispatch(navigateTo(uuid)); } }); @@ -121,7 +121,7 @@ export const Snackbar = withStyles(styles)(connect(mapStateToProps, mapDispatchT aria-describedby="client-snackbar" message={ - + {props.message} } @@ -150,7 +150,7 @@ const actions = (props: SnackbarProps) => { size="small" color="inherit" className={classes.linkButton} - onClick={() => onClick(link) }> + onClick={() => onClick(link)}> Go To ); diff --git a/src/views/collection-panel/collection-panel.tsx b/src/views/collection-panel/collection-panel.tsx index 948a20a0..f1e93783 100644 --- a/src/views/collection-panel/collection-panel.tsx +++ b/src/views/collection-panel/collection-panel.tsx @@ -110,7 +110,17 @@ export const CollectionPanel = withStyles(styles)( label='Collection UUID' value={item && item.uuid}> - this.onCopy()}> + this.onCopy("UUID has been copied")}> + + + + + + + this.onCopy("PDH has been copied")}> @@ -120,7 +130,7 @@ export const CollectionPanel = withStyles(styles)( + label='Owner' linkToUuid={item && item.ownerUuid} value={item && item.ownerUuid} /> {(item.properties.container_request || item.properties.containerRequest) && dispatch(navigateToProcess(item.properties.container_request || item.properties.containerRequest))}> @@ -176,9 +186,9 @@ export const CollectionPanel = withStyles(styles)( this.props.dispatch(deleteCollectionTag(key)); } - onCopy = () => { + onCopy = (message: string) => { this.props.dispatch(snackbarActions.OPEN_SNACKBAR({ - message: "Uuid has been copied", + message, hideDuration: 2000, kind: SnackbarKind.SUCCESS })); diff --git a/src/views/search-results-panel/search-results-panel-view.tsx b/src/views/search-results-panel/search-results-panel-view.tsx index 72a9b282..b82b1745 100644 --- a/src/views/search-results-panel/search-results-panel-view.tsx +++ b/src/views/search-results-panel/search-results-panel-view.tsx @@ -8,7 +8,6 @@ import { DataColumns } from '~/components/data-table/data-table'; import { DataTableFilterItem } from '~/components/data-table-filters/data-table-filters'; import { ResourceKind } from '~/models/resource'; import { ContainerRequestState } from '~/models/container-request'; -import { SearchBarAdvanceFormData } from '~/models/search-bar'; import { SEARCH_RESULTS_PANEL_ID } from '~/store/search-results-panel/search-results-panel-actions'; import { DataExplorer } from '~/views-components/data-explorer/data-explorer'; import { @@ -21,9 +20,7 @@ import { } from '~/views-components/data-explorer/renderers'; import { createTree } from '~/models/tree'; import { getInitialResourceTypeFilters } from '~/store/resource-type-filters/resource-type-filters'; -import { User } from "~/models/user"; -import { Config } from '~/common/config'; -import { Session } from "~/models/session"; +import { SearchResultsPanelProps } from "./search-results-panel"; export enum SearchResultsPanelColumnNames { CLUSTER = "Cluster", @@ -36,23 +33,6 @@ export enum SearchResultsPanelColumnNames { LAST_MODIFIED = "Last modified" } -export interface SearchResultsPanelDataProps { - data: SearchBarAdvanceFormData; - user: User; - sessions: Session[]; - remoteHostsConfig: { [key: string]: Config }; - localCluster: string; -} - -export interface SearchResultsPanelActionProps { - onItemClick: (item: string) => void; - onContextMenu: (event: React.MouseEvent, item: string) => void; - onDialogOpen: (ownerUuid: string) => void; - onItemDoubleClick: (item: string) => void; -} - -export type SearchResultsPanelProps = SearchResultsPanelDataProps & SearchResultsPanelActionProps; - export interface WorkflowPanelFilter extends DataTableFilterItem { type: ResourceKind | ContainerRequestState; } @@ -125,7 +105,7 @@ export const SearchResultsPanelView = (props: SearchResultsPanelProps) => { onRowClick={props.onItemClick} onRowDoubleClick={props.onItemDoubleClick} onContextMenu={props.onContextMenu} - contextMenuColumn={true} + contextMenuColumn={false} hideSearchInput title={ props.localCluster === homeCluster ? diff --git a/src/views/search-results-panel/search-results-panel.tsx b/src/views/search-results-panel/search-results-panel.tsx index bde7207a..7de1abd3 100644 --- a/src/views/search-results-panel/search-results-panel.tsx +++ b/src/views/search-results-panel/search-results-panel.tsx @@ -5,12 +5,32 @@ import { Dispatch } from "redux"; import { connect } from "react-redux"; import { navigateTo } from '~/store/navigation/navigation-action'; -import { SearchResultsPanelActionProps } from './search-results-panel-view'; -import { openContextMenu, resourceKindToContextMenuKind } from '~/store/context-menu/context-menu-actions'; -import { ResourceKind } from '~/models/resource'; +// import { openContextMenu, resourceKindToContextMenuKind } from '~/store/context-menu/context-menu-actions'; +// import { ResourceKind } from '~/models/resource'; import { loadDetailsPanel } from '~/store/details-panel/details-panel-action'; import { SearchResultsPanelView } from '~/views/search-results-panel/search-results-panel-view'; import { RootState } from '~/store/store'; +import { SearchBarAdvanceFormData } from '~/models/search-bar'; +import { User } from "~/models/user"; +import { Config } from '~/common/config'; +import { Session } from "~/models/session"; + +export interface SearchResultsPanelDataProps { + data: SearchBarAdvanceFormData; + user: User; + sessions: Session[]; + remoteHostsConfig: { [key: string]: Config }; + localCluster: string; +} + +export interface SearchResultsPanelActionProps { + onItemClick: (item: string) => void; + onContextMenu: (event: React.MouseEvent, item: string) => void; + onDialogOpen: (ownerUuid: string) => void; + onItemDoubleClick: (item: string) => void; +} + +export type SearchResultsPanelProps = SearchResultsPanelDataProps & SearchResultsPanelActionProps; const mapStateToProps = (rootState: RootState) => { return { @@ -22,19 +42,7 @@ const mapStateToProps = (rootState: RootState) => { }; const mapDispatchToProps = (dispatch: Dispatch): SearchResultsPanelActionProps => ({ - onContextMenu: (event, resourceUuid) => { - const kind = resourceKindToContextMenuKind(resourceUuid); - if (kind) { - dispatch(openContextMenu(event, { - name: '', - uuid: resourceUuid, - ownerUuid: '', - kind: ResourceKind.NONE, - menuKind: kind - })); - } - dispatch(loadDetailsPanel(resourceUuid)); - }, + onContextMenu: (event, resourceUuid) => { return; }, onDialogOpen: (ownerUuid: string) => { return; }, onItemClick: (resourceUuid: string) => { dispatch(loadDetailsPanel(resourceUuid)); diff --git a/src/views/user-panel/user-panel.tsx b/src/views/user-panel/user-panel.tsx index c42036ed..6c2fdafe 100644 --- a/src/views/user-panel/user-panel.tsx +++ b/src/views/user-panel/user-panel.tsx @@ -101,14 +101,6 @@ export const userPanelColumns: DataColumns = [ filters: createTree(), render: uuid => }, - { - name: UserPanelColumnNames.REDIRECT_TO_USER, - selected: true, - configurable: false, - sortDirection: SortDirection.NONE, - filters: createTree(), - render: () => (none) - }, { name: UserPanelColumnNames.USERNAME, selected: true, -- 2.30.2