From: Lucas Di Pentima Date: Thu, 14 Nov 2019 13:06:55 +0000 (-0300) Subject: 15067: Creates PropertyChipComponent to be used where tags need listing. X-Git-Tag: 2.0.0~29^2~2 X-Git-Url: https://git.arvados.org/arvados-workbench2.git/commitdiff_plain/6656a000d2992676dcfcbed51b34d327d304d05e 15067: Creates PropertyChipComponent to be used where tags need listing. Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima --- diff --git a/src/views-components/details-panel/project-details.tsx b/src/views-components/details-panel/project-details.tsx index 7db4df7b..59035da1 100644 --- a/src/views-components/details-panel/project-details.tsx +++ b/src/views-components/details-panel/project-details.tsx @@ -4,7 +4,6 @@ import * as React from 'react'; import { connect } from 'react-redux'; -import { RootState } from '~/store/store'; import { openProjectPropertiesDialog } from '~/store/details-panel/details-panel-action'; import { ProjectIcon, RenameIcon } from '~/components/icon/icon'; import { ProjectResource } from '~/models/project'; @@ -14,13 +13,10 @@ import { resourceLabel } from '~/common/labels'; import { DetailsData } from "./details-data"; import { DetailsAttribute } from "~/components/details-attribute/details-attribute"; import { RichTextEditorLink } from '~/components/rich-text-editor-link/rich-text-editor-link'; -import { withStyles, StyleRulesCallback, Chip, WithStyles } from '@material-ui/core'; +import { withStyles, StyleRulesCallback, WithStyles } from '@material-ui/core'; import { ArvadosTheme } from '~/common/custom-theme'; -import * as CopyToClipboard from 'react-copy-to-clipboard'; -import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions'; -import { getTagValueLabel, getTagKeyLabel, Vocabulary } from '~/models/vocabulary'; -import { getVocabulary } from "~/store/vocabulary/vocabulary-selectors"; import { Dispatch } from 'redux'; +import { PropertyChipComponent } from '../resource-properties-form/property-chip'; export class ProjectDetails extends DetailsData { getIcon(className?: string) { @@ -45,35 +41,23 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ } }); - interface ProjectDetailsComponentDataProps { project: ProjectResource; - vocabulary: Vocabulary; } interface ProjectDetailsComponentActionProps { onClick: () => void; - onCopy: (message: string) => void; } -const mapStateToProps = ({ properties }: RootState) => ({ - vocabulary: getVocabulary(properties), -}); - const mapDispatchToProps = (dispatch: Dispatch) => ({ onClick: () => dispatch(openProjectPropertiesDialog()), - onCopy: (message: string) => dispatch(snackbarActions.OPEN_SNACKBAR({ - message, - hideDuration: 2000, - kind: SnackbarKind.SUCCESS - })) }); type ProjectDetailsComponentProps = ProjectDetailsComponentDataProps & ProjectDetailsComponentActionProps & WithStyles; -const ProjectDetailsComponent = connect(mapStateToProps, mapDispatchToProps)( +const ProjectDetailsComponent = connect(null, mapDispatchToProps)( withStyles(styles)( - ({ classes, project, onClick, vocabulary, onCopy }: ProjectDetailsComponentProps) =>
+ ({ classes, project, onClick }: ProjectDetailsComponentProps) =>
{/* Missing attr */} @@ -98,14 +82,11 @@ const ProjectDetailsComponent = connect(mapStateToProps, mapDispatchToProps)(
{ - Object.keys(project.properties).map(k => { - const label = `${getTagKeyLabel(k, vocabulary)}: ${getTagValueLabel(k, project.properties[k], vocabulary)}`; - return ( - onCopy("Copied")}> - - - ); - }) + Object.keys(project.properties).map(k => + + ) }
)); diff --git a/src/views-components/project-properties-dialog/project-properties-dialog.tsx b/src/views-components/project-properties-dialog/project-properties-dialog.tsx index a071a985..7a4cfba6 100644 --- a/src/views-components/project-properties-dialog/project-properties-dialog.tsx +++ b/src/views-components/project-properties-dialog/project-properties-dialog.tsx @@ -9,14 +9,11 @@ import { RootState } from '~/store/store'; import { withDialog, WithDialogProps } from "~/store/dialog/with-dialog"; import { ProjectResource } from '~/models/project'; import { PROJECT_PROPERTIES_DIALOG_NAME, deleteProjectProperty } from '~/store/details-panel/details-panel-action'; -import { Dialog, DialogTitle, DialogContent, DialogActions, Button, Chip, withStyles, StyleRulesCallback, WithStyles } from '@material-ui/core'; +import { Dialog, DialogTitle, DialogContent, DialogActions, Button, withStyles, StyleRulesCallback, WithStyles } from '@material-ui/core'; import { ArvadosTheme } from '~/common/custom-theme'; import { ProjectPropertiesForm } from '~/views-components/project-properties-dialog/project-properties-form'; import { getResource } from '~/store/resources/resources'; -import * as CopyToClipboard from 'react-copy-to-clipboard'; -import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions'; -import { getTagValueLabel, getTagKeyLabel, Vocabulary } from '~/models/vocabulary'; -import { getVocabulary } from "~/store/vocabulary/vocabulary-selectors"; +import { PropertyChipComponent } from "../resource-properties-form/property-chip"; type CssRules = 'tag'; @@ -29,26 +26,18 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ interface ProjectPropertiesDialogDataProps { project: ProjectResource; - vocabulary: Vocabulary; } interface ProjectPropertiesDialogActionProps { handleDelete: (key: string) => void; - onCopy: (message: string) => void; } const mapStateToProps = ({ detailsPanel, resources, properties }: RootState): ProjectPropertiesDialogDataProps => ({ project: getResource(detailsPanel.resourceUuid)(resources) as ProjectResource, - vocabulary: getVocabulary(properties), }); const mapDispatchToProps = (dispatch: Dispatch): ProjectPropertiesDialogActionProps => ({ handleDelete: (key: string) => dispatch(deleteProjectProperty(key)), - onCopy: (message: string) => dispatch(snackbarActions.OPEN_SNACKBAR({ - message, - hideDuration: 2000, - kind: SnackbarKind.SUCCESS - })) }); type ProjectPropertiesDialogProps = ProjectPropertiesDialogDataProps & ProjectPropertiesDialogActionProps & WithDialogProps<{}> & WithStyles; @@ -56,7 +45,7 @@ type ProjectPropertiesDialogProps = ProjectPropertiesDialogDataProps & ProjectP export const ProjectPropertiesDialog = connect(mapStateToProps, mapDispatchToProps)( withStyles(styles)( withDialog(PROJECT_PROPERTIES_DIALOG_NAME)( - ({ classes, open, closeDialog, handleDelete, onCopy, project, vocabulary }: ProjectPropertiesDialogProps) => + ({ classes, open, closeDialog, handleDelete, project }: ProjectPropertiesDialogProps) => {project && project.properties && - Object.keys(project.properties).map(k => { - const label = `${getTagKeyLabel(k, vocabulary)}: ${getTagValueLabel(k, project.properties[k], vocabulary)}`; - return ( - onCopy("Copied")}> - handleDelete(k)} - label={label} /> - - ); - }) + Object.keys(project.properties).map(k => + handleDelete(k)} + key={k} className={classes.tag} + propKey={k} propValue={project.properties[k]} />) } @@ -86,4 +70,5 @@ export const ProjectPropertiesDialog = connect(mapStateToProps, mapDispatchToPro -))); \ No newline at end of file + ) +)); \ No newline at end of file diff --git a/src/views-components/resource-properties-form/property-chip.tsx b/src/views-components/resource-properties-form/property-chip.tsx new file mode 100644 index 00000000..c51a8d8e --- /dev/null +++ b/src/views-components/resource-properties-form/property-chip.tsx @@ -0,0 +1,52 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import * as React from 'react'; +import { Chip } from '@material-ui/core'; +import { connect } from 'react-redux'; +import { RootState } from '~/store/store'; +import * as CopyToClipboard from 'react-copy-to-clipboard'; +import { getVocabulary } from '~/store/vocabulary/vocabulary-selectors'; +import { Dispatch } from 'redux'; +import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions'; +import { getTagValueLabel, getTagKeyLabel, Vocabulary } from '~/models/vocabulary'; + +interface PropertyChipComponentDataProps { + propKey: string; + propValue: string; + className: string; + vocabulary: Vocabulary; +} + +interface PropertyChipComponentActionProps { + onDelete?: () => void; + onCopy: (message: string) => void; +} + +type PropertyChipComponentProps = PropertyChipComponentActionProps & PropertyChipComponentDataProps; + +const mapStateToProps = ({ properties }: RootState) => ({ + vocabulary: getVocabulary(properties), +}); + +const mapDispatchToProps = (dispatch: Dispatch) => ({ + onCopy: (message: string) => dispatch(snackbarActions.OPEN_SNACKBAR({ + message, + hideDuration: 2000, + kind: SnackbarKind.SUCCESS + })) +}); + +// Renders a Chip with copyable-on-click tag:value data based on the vocabulary +export const PropertyChipComponent = connect(mapStateToProps, mapDispatchToProps)( + ({ propKey, propValue, vocabulary, className, onCopy, onDelete }: PropertyChipComponentProps) => { + const label = `${getTagKeyLabel(propKey, vocabulary)}: ${getTagValueLabel(propKey, propValue, vocabulary)}`; + return ( + onCopy("Copied to clipboard")}> + + + ); + } +); diff --git a/src/views/collection-panel/collection-panel.tsx b/src/views/collection-panel/collection-panel.tsx index 87768e64..28ae2f05 100644 --- a/src/views/collection-panel/collection-panel.tsx +++ b/src/views/collection-panel/collection-panel.tsx @@ -5,9 +5,8 @@ import * as React from 'react'; import { StyleRulesCallback, WithStyles, withStyles, Card, - CardHeader, IconButton, CardContent, Grid, Chip, Tooltip + CardHeader, IconButton, CardContent, Grid, Tooltip } from '@material-ui/core'; -import { compose } from "redux"; import { connect, DispatchProp } from "react-redux"; import { RouteComponentProps } from 'react-router'; import { ArvadosTheme } from '~/common/custom-theme'; @@ -25,10 +24,8 @@ import { formatFileSize } from "~/common/formatters"; import { getResourceData } from "~/store/resources-data/resources-data"; import { ResourceData } from "~/store/resources-data/resources-data-reducer"; import { openDetailsPanel } from '~/store/details-panel/details-panel-action'; -import * as CopyToClipboard from 'react-copy-to-clipboard'; import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions'; -import { connectVocabulary, VocabularyProp } from '~/views-components/resource-properties-form/property-field-common'; -import { getTagValueLabel, getTagKeyLabel } from '~/models/vocabulary'; +import { PropertyChipComponent } from '~/views-components/resource-properties-form/property-chip'; type CssRules = 'card' | 'iconHeader' | 'tag' | 'label' | 'value' | 'link'; @@ -68,19 +65,16 @@ interface CollectionPanelDataProps { type CollectionPanelProps = CollectionPanelDataProps & DispatchProp & WithStyles & RouteComponentProps<{ id: string }>; -export const CollectionPanel = compose( - connectVocabulary, - withStyles(styles))( - connect((state: RootState, props: RouteComponentProps<{ id: string }> & VocabularyProp) => { +export const CollectionPanel = withStyles(styles)( + connect((state: RootState, props: RouteComponentProps<{ id: string }>) => { const item = getResource(props.match.params.id)(state.resources); const data = getResourceData(props.match.params.id)(state.resourcesData); - const vocabulary = props.vocabulary; - return { item, data, vocabulary }; + return { item, data }; })( - class extends React.Component { + class extends React.Component { render() { - const { classes, item, data, dispatch, vocabulary } = this.props; + const { classes, item, data, dispatch } = this.props; return item ? <> @@ -136,14 +130,12 @@ export const CollectionPanel = compose( - {Object.keys(item.properties).map(k => { - const label = `${getTagKeyLabel(k, vocabulary)}: ${getTagValueLabel(k, item.properties[k], vocabulary)}`; - return this.onCopy("Copied")}> - - ; - })} + {Object.keys(item.properties).map(k => + + )}