From e5dc88dd1a6c54610d92854d527e5048543d93ec Mon Sep 17 00:00:00 2001 From: Lucas Di Pentima Date: Wed, 14 Jul 2021 18:04:22 -0300 Subject: [PATCH] 17573: Adds storage selection checkboxes to edit dialog. Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima --- .../collections/collection-update-actions.ts | 2 ++ .../context-menu/context-menu-actions.ts | 1 + .../details-panel/collection-details.tsx | 2 ++ .../dialog-forms/update-collection-dialog.ts | 12 +++++--- .../dialog-collection-update.tsx | 7 ++++- .../form-fields/collection-form-fields.tsx | 22 +++++++++++++++ .../collection-content-address-panel.tsx | 28 ++++++++++++++----- src/views/favorite-panel/favorite-panel.tsx | 4 ++- src/views/project-panel/project-panel.tsx | 2 ++ .../public-favorites-panel.tsx | 2 ++ 10 files changed, 69 insertions(+), 13 deletions(-) diff --git a/src/store/collections/collection-update-actions.ts b/src/store/collections/collection-update-actions.ts index 3f3b662f..a9077cfb 100644 --- a/src/store/collections/collection-update-actions.ts +++ b/src/store/collections/collection-update-actions.ts @@ -19,6 +19,7 @@ export interface CollectionUpdateFormDialogData { uuid: string; name: string; description?: string; + storageClassesDesired?: string[]; } export const COLLECTION_UPDATE_FORM_NAME = 'collectionUpdateFormName'; @@ -37,6 +38,7 @@ export const updateCollection = (collection: CollectionUpdateFormDialogData) => services.collectionService.update(uuid, { name: collection.name, + storageClassesDesired: collection.storageClassesDesired, description: collection.description } ).then(updatedCollection => { dispatch(collectionPanelActions.LOAD_COLLECTION_SUCCESS({ item: updatedCollection as CollectionResource })); diff --git a/src/store/context-menu/context-menu-actions.ts b/src/store/context-menu/context-menu-actions.ts index 038b31e2..556d83b4 100644 --- a/src/store/context-menu/context-menu-actions.ts +++ b/src/store/context-menu/context-menu-actions.ts @@ -39,6 +39,7 @@ export type ContextMenuResource = { isEditable?: boolean; outputUuid?: string; workflowUuid?: string; + storageClassesDesired?: string[]; }; export const isKeyboardClick = (event: React.MouseEvent) => event.nativeEvent.detail === 0; diff --git a/src/views-components/details-panel/collection-details.tsx b/src/views-components/details-panel/collection-details.tsx index 0e747fed..c61b3340 100644 --- a/src/views-components/details-panel/collection-details.tsx +++ b/src/views-components/details-panel/collection-details.tsx @@ -87,6 +87,8 @@ const mapDispatchToProps = () => dispatch(openContextMenu(event, { name: collection.name, uuid: collection.uuid, + description: collection.description, + storageClassesDesired: collection.storageClassesDesired, ownerUuid: collection.ownerUuid, isTrashed: collection.isTrashed, kind: collection.kind, diff --git a/src/views-components/dialog-forms/update-collection-dialog.ts b/src/views-components/dialog-forms/update-collection-dialog.ts index 36e5cc39..e5d52f0b 100644 --- a/src/views-components/dialog-forms/update-collection-dialog.ts +++ b/src/views-components/dialog-forms/update-collection-dialog.ts @@ -2,19 +2,23 @@ // // SPDX-License-Identifier: AGPL-3.0 -import { compose } from "redux"; +import { compose, Dispatch } from "redux"; import { reduxForm } from 'redux-form'; import { withDialog } from "store/dialog/with-dialog"; import { DialogCollectionUpdate } from 'views-components/dialog-update/dialog-collection-update'; -import { COLLECTION_UPDATE_FORM_NAME, CollectionUpdateFormDialogData, updateCollection } from 'store/collections/collection-update-actions'; +import { + COLLECTION_UPDATE_FORM_NAME, + CollectionUpdateFormDialogData, + updateCollection +} from 'store/collections/collection-update-actions'; export const UpdateCollectionDialog = compose( withDialog(COLLECTION_UPDATE_FORM_NAME), reduxForm({ touchOnChange: true, form: COLLECTION_UPDATE_FORM_NAME, - onSubmit: (data, dispatch) => { - dispatch(updateCollection(data)); + onSubmit: (data: CollectionUpdateFormDialogData, dispatch: Dispatch) => { + dispatch(updateCollection(data)); } }) )(DialogCollectionUpdate); \ No newline at end of file diff --git a/src/views-components/dialog-update/dialog-collection-update.tsx b/src/views-components/dialog-update/dialog-collection-update.tsx index c30ceaac..cce64d27 100644 --- a/src/views-components/dialog-update/dialog-collection-update.tsx +++ b/src/views-components/dialog-update/dialog-collection-update.tsx @@ -7,7 +7,11 @@ import { InjectedFormProps } from 'redux-form'; import { WithDialogProps } from 'store/dialog/with-dialog'; import { CollectionUpdateFormDialogData } from 'store/collections/collection-update-actions'; import { FormDialog } from 'components/form-dialog/form-dialog'; -import { CollectionNameField, CollectionDescriptionField } from 'views-components/form-fields/collection-form-fields'; +import { + CollectionNameField, + CollectionDescriptionField, + CollectionStorageClassesField +} from 'views-components/form-fields/collection-form-fields'; type DialogCollectionProps = WithDialogProps<{}> & InjectedFormProps; @@ -22,4 +26,5 @@ export const DialogCollectionUpdate = (props: DialogCollectionProps) => const CollectionEditFields = () => + ; diff --git a/src/views-components/form-fields/collection-form-fields.tsx b/src/views-components/form-fields/collection-form-fields.tsx index b882d684..db18f76d 100644 --- a/src/views-components/form-fields/collection-form-fields.tsx +++ b/src/views-components/form-fields/collection-form-fields.tsx @@ -13,6 +13,8 @@ import { ProjectTreePickerField, CollectionTreePickerField } from "views-compone import { PickerIdProp } from 'store/tree-picker/picker-id'; import { connect } from "react-redux"; import { RootState } from "store/store"; +import { MultiCheckboxField } from "components/checkbox-field/checkbox-field"; +import { getStorageClasses } from "common/config"; interface CollectionNameFieldProps { validate: Validator[]; @@ -55,3 +57,23 @@ export const CollectionPickerField = (props: PickerIdProp) => pickerId={props.pickerId} component={CollectionTreePickerField} validate={COLLECTION_PROJECT_VALIDATION} />; + +interface StorageClassesProps { + items: string[]; +} + +export const CollectionStorageClassesField = connect( + (state: RootState) => { + return { + items: getStorageClasses(state.auth.config) + }; + })( + (props: StorageClassesProps) => + ); \ No newline at end of file diff --git a/src/views/collection-content-address-panel/collection-content-address-panel.tsx b/src/views/collection-content-address-panel/collection-content-address-panel.tsx index 13e131b0..88638085 100644 --- a/src/views/collection-content-address-panel/collection-content-address-panel.tsx +++ b/src/views/collection-content-address-panel/collection-content-address-panel.tsx @@ -34,6 +34,9 @@ import { ResourceLastModifiedDate, ResourceStatus } from 'views-components/data-explorer/renderers'; +import { getResource, ResourcesState } from 'store/resources/resources'; +import { RootState } from 'store/store'; +import { CollectionResource } from 'models/collection'; type CssRules = 'backLink' | 'backIcon' | 'card' | 'title' | 'iconHeader' | 'link'; @@ -110,18 +113,29 @@ export const collectionContentAddressPanelColumns: DataColumns = [ } ]; -export interface CollectionContentAddressPanelActionProps { - onContextMenu: (event: React.MouseEvent, uuid: string) => void; +interface CollectionContentAddressPanelActionProps { + onContextMenu: (resources: ResourcesState) => (event: React.MouseEvent, uuid: string) => void; onItemClick: (item: string) => void; onItemDoubleClick: (item: string) => void; } +interface CollectionContentAddressPanelDataProps { + resources: ResourcesState; +} + +const mapStateToProps = ({ resources }: RootState): CollectionContentAddressPanelDataProps => ({ + resources +}) + const mapDispatchToProps = (dispatch: Dispatch): CollectionContentAddressPanelActionProps => ({ - onContextMenu: (event, resourceUuid) => { + onContextMenu: (resources: ResourcesState) => (event, resourceUuid) => { + const resource = getResource(resourceUuid)(resources); const kind = dispatch(resourceUuidToContextMenuKind(resourceUuid)); if (kind) { dispatch(openContextMenu(event, { - name: '', + name: resource ? resource.name : '', + description: resource ? resource.description : '', + storageClassesDesired: resource ? resource.storageClassesDesired : [], uuid: resourceUuid, ownerUuid: '', kind: ResourceKind.NONE, @@ -145,8 +159,8 @@ interface CollectionContentAddressDataProps { } export const CollectionsContentAddressPanel = withStyles(styles)( - connect(null, mapDispatchToProps)( - class extends React.Component> { + connect(mapStateToProps, mapDispatchToProps)( + class extends React.Component> { render() { return