1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from "react";
6 import { Dispatch } from "redux";
7 import { connect } from "react-redux";
8 import { RootState } from '~/store/store';
9 import { withDialog, WithDialogProps } from "~/store/dialog/with-dialog";
10 import { ProjectResource } from '~/models/project';
11 import { PROJECT_PROPERTIES_DIALOG_NAME, deleteProjectProperty } from '~/store/details-panel/details-panel-action';
12 import { Dialog, DialogTitle, DialogContent, DialogActions, Button, Chip, withStyles, StyleRulesCallback, WithStyles } from '@material-ui/core';
13 import { ArvadosTheme } from '~/common/custom-theme';
14 import { ProjectPropertiesForm } from '~/views-components/project-properties-dialog/project-properties-form';
15 import { getResource } from '~/store/resources/resources';
16 import * as CopyToClipboard from 'react-copy-to-clipboard';
17 import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions';
18 import { getTagValueLabel, getTagKeyLabel, Vocabulary } from '~/models/vocabulary';
19 import { getVocabulary } from "~/store/vocabulary/vocabulary-selectors";
21 type CssRules = 'tag';
23 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => ({
25 marginRight: theme.spacing.unit,
26 marginBottom: theme.spacing.unit
30 interface ProjectPropertiesDialogDataProps {
31 project: ProjectResource;
32 vocabulary: Vocabulary;
35 interface ProjectPropertiesDialogActionProps {
36 handleDelete: (key: string) => void;
37 onCopy: (message: string) => void;
40 const mapStateToProps = ({ detailsPanel, resources, properties }: RootState): ProjectPropertiesDialogDataProps => ({
41 project: getResource(detailsPanel.resourceUuid)(resources) as ProjectResource,
42 vocabulary: getVocabulary(properties),
45 const mapDispatchToProps = (dispatch: Dispatch): ProjectPropertiesDialogActionProps => ({
46 handleDelete: (key: string) => dispatch<any>(deleteProjectProperty(key)),
47 onCopy: (message: string) => dispatch(snackbarActions.OPEN_SNACKBAR({
50 kind: SnackbarKind.SUCCESS
54 type ProjectPropertiesDialogProps = ProjectPropertiesDialogDataProps & ProjectPropertiesDialogActionProps & WithDialogProps<{}> & WithStyles<CssRules>;
56 export const ProjectPropertiesDialog = connect(mapStateToProps, mapDispatchToProps)(
58 withDialog(PROJECT_PROPERTIES_DIALOG_NAME)(
59 ({ classes, open, closeDialog, handleDelete, onCopy, project, vocabulary }: ProjectPropertiesDialogProps) =>
64 <DialogTitle>Properties</DialogTitle>
66 <ProjectPropertiesForm />
67 {project && project.properties &&
68 Object.keys(project.properties).map(k => {
69 const label = `${getTagKeyLabel(k, vocabulary)}: ${getTagValueLabel(k, project.properties[k], vocabulary)}`;
71 <CopyToClipboard key={k} text={label} onCopy={() => onCopy("Copied")}>
72 <Chip key={k} className={classes.tag}
73 onDelete={() => handleDelete(k)}
84 onClick={closeDialog}>