17308: Adds vocabulary terms handling to new project dialog's property editor.
authorLucas Di Pentima <lucas@di-pentima.com.ar>
Mon, 1 Feb 2021 22:27:09 +0000 (19:27 -0300)
committerLucas Di Pentima <lucas@di-pentima.com.ar>
Mon, 1 Feb 2021 22:27:09 +0000 (19:27 -0300)
Also, adds the ability to add multiple value properties. This makes the
new project dialog's editor behaviour consistent with the rest of the
application.

Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas@di-pentima.com.ar>

src/store/collection-panel/collection-panel-action.ts
src/store/projects/project-create-actions.ts
src/views-components/project-properties/create-project-properties-list.tsx
src/views-components/resource-properties-form/property-chip.tsx

index 7881d6723854242525c4b5c88a907d72772e870c..ff89ca38853946dde94c818e151ea067ee51e994 100644 (file)
@@ -61,7 +61,7 @@ export const createCollectionTag = (data: TagProperty) =>
             dispatch(collectionPanelActions.SET_COLLECTION(updatedCollection));
             dispatch(resourcesActions.SET_RESOURCES([updatedCollection]));
             dispatch(snackbarActions.OPEN_SNACKBAR({
-                message: "Tag has been successfully added.",
+                message: "Property has been successfully added.",
                 hideDuration: 2000,
                 kind: SnackbarKind.SUCCESS }));
             dispatch<any>(loadDetailsPanel(updatedCollection.uuid));
index 583a4bd6978237bfc695fd8fe8f1cdae93bd41a1..3599378ceec836abbd81f9b9f9054413cc7a39c2 100644 (file)
@@ -13,6 +13,7 @@ import { ServiceRepository } from '~/services/services';
 import { matchProjectRoute, matchRunProcessRoute } from '~/routes/routes';
 import { ResourcePropertiesFormData } from '~/views-components/resource-properties-form/resource-properties-form';
 import { RouterState } from "react-router-redux";
+import { addProperty, deleteProperty } from "~/lib/resource-properties";
 
 export interface ProjectCreateFormDialogData {
     ownerUuid: string;
@@ -22,7 +23,7 @@ export interface ProjectCreateFormDialogData {
 }
 
 export interface ProjectProperties {
-    [key: string]: string;
+    [key: string]: string | string[];
 }
 
 export const PROJECT_CREATE_FORM_NAME = 'projectCreateFormName';
@@ -69,13 +70,19 @@ export const createProject = (project: Partial<ProjectResource>) =>
 export const addPropertyToCreateProjectForm = (data: ResourcePropertiesFormData) =>
     (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         const properties = { ...PROJECT_CREATE_FORM_SELECTOR(getState(), 'properties') };
-        properties[data.key] = data.value;
-        dispatch(change(PROJECT_CREATE_FORM_NAME, 'properties', properties));
+        const key = data.keyID || data.key;
+        const value =  data.valueID || data.value;
+        dispatch(change(
+            PROJECT_CREATE_FORM_NAME,
+            'properties',
+            addProperty(properties, key, value)));
     };
 
-export const removePropertyFromCreateProjectForm = (key: string) =>
+export const removePropertyFromCreateProjectForm = (key: string, value: string) =>
     (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
         const properties = { ...PROJECT_CREATE_FORM_SELECTOR(getState(), 'properties') };
-        delete properties[key];
-        dispatch(change(PROJECT_CREATE_FORM_NAME, 'properties', properties));
+        dispatch(change(
+            PROJECT_CREATE_FORM_NAME,
+            'properties',
+            deleteProperty(properties, key, value)));
     };
index 1d2050fe4c25343f2f903a7ab27a469bd972ec60..b1de75b24d0affddfaebdd38acd4ddf7c2617154 100644 (file)
@@ -5,10 +5,15 @@
 import * as React from 'react';
 import { connect } from 'react-redux';
 import { Dispatch } from 'redux';
-import { withStyles, StyleRulesCallback, WithStyles, Chip } from '@material-ui/core';
+import {
+    withStyles,
+    StyleRulesCallback,
+    WithStyles,
+} from '@material-ui/core';
 import { RootState } from '~/store/store';
 import { removePropertyFromCreateProjectForm, PROJECT_CREATE_FORM_SELECTOR, ProjectProperties } from '~/store/projects/project-create-actions';
 import { ArvadosTheme } from '~/common/custom-theme';
+import { getPropertyChip } from '../resource-properties-form/property-chip';
 
 type CssRules = 'tag';
 
@@ -24,7 +29,7 @@ interface CreateProjectPropertiesListDataProps {
 }
 
 interface CreateProjectPropertiesListActionProps {
-    handleDelete: (key: string) => void;
+    handleDelete: (key: string, value: string) => void;
 }
 
 const mapStateToProps = (state: RootState): CreateProjectPropertiesListDataProps => {
@@ -33,21 +38,28 @@ const mapStateToProps = (state: RootState): CreateProjectPropertiesListDataProps
 };
 
 const mapDispatchToProps = (dispatch: Dispatch): CreateProjectPropertiesListActionProps => ({
-    handleDelete: (key: string) => dispatch<any>(removePropertyFromCreateProjectForm(key))
+    handleDelete: (key: string, value: string) => dispatch<any>(removePropertyFromCreateProjectForm(key, value))
 });
 
-type CreateProjectPropertiesListProps = CreateProjectPropertiesListDataProps & 
+type CreateProjectPropertiesListProps = CreateProjectPropertiesListDataProps &
     CreateProjectPropertiesListActionProps & WithStyles<CssRules>;
 
 const List = withStyles(styles)(
     ({ classes, handleDelete, properties }: CreateProjectPropertiesListProps) =>
         <div>
             {properties &&
-                Object.keys(properties).map(k => {
-                    return <Chip key={k} className={classes.tag}
-                        onDelete={() => handleDelete(k)}
-                        label={`${k}: ${properties[k]}`} />;
-                })}
+                Object.keys(properties).map(k =>
+                    Array.isArray(properties[k])
+                    ? (properties[k] as string[]).map((v: string) =>
+                        getPropertyChip(
+                            k, v,
+                            () => handleDelete(k, v),
+                            classes.tag))
+                    : getPropertyChip(
+                        k, (properties[k] as string),
+                        () => handleDelete(k, (properties[k] as string)),
+                        classes.tag))
+                }
         </div>
 );
 
index 1fba8a40a98b1dbdc1a22386a8f10ba41bdb8e58..b9a13fbbca52dbe3ab1f3543eb9f0ae099b33289 100644 (file)
@@ -51,7 +51,7 @@ export const PropertyChipComponent = connect(mapStateToProps, mapDispatchToProps
     }
 );
 
-export const getPropertyChip = (k:string, v:string, handleDelete:any, className:string) =>
+export const getPropertyChip = (k: string, v: string, handleDelete: any, className: string) =>
     <PropertyChipComponent
         key={`${k}-${v}`} className={className}
         onDelete={handleDelete}