From e858ef67d3d17323b31eeb92e99ff8de70b5d591 Mon Sep 17 00:00:00 2001 From: Pawel Kowalczyk Date: Wed, 21 Nov 2018 11:19:39 +0100 Subject: [PATCH] creating and deleting repos Feature #13865 Arvados-DCO-1.1-Signed-off-by: Pawel Kowalczyk --- .../common-service/common-resource-service.ts | 3 ++ .../repositories/repositories-actions.ts | 47 ++++++++++++++++++- .../action-sets/repository-action-set.ts | 6 +-- .../dialog-repository-create.tsx | 4 +- .../form-fields/repository-form-fields.tsx | 30 ++++++++---- .../repository-remove-dialog.ts | 20 ++++++++ src/views/workbench/workbench.tsx | 2 + 7 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 src/views-components/repository-remove-dialog/repository-remove-dialog.ts diff --git a/src/services/common-service/common-resource-service.ts b/src/services/common-service/common-resource-service.ts index 70c1df0e..6114c560 100644 --- a/src/services/common-service/common-resource-service.ts +++ b/src/services/common-service/common-resource-service.ts @@ -35,6 +35,7 @@ export enum CommonResourceServiceError { UNIQUE_VIOLATION = 'UniqueViolation', OWNERSHIP_CYCLE = 'OwnershipCycle', MODIFYING_CONTAINER_REQUEST_FINAL_STATE = 'ModifyingContainerRequestFinalState', + NAME_HAS_ALREADY_BEEN_TAKEN = 'NameHasAlreadyBeenTaken', UNKNOWN = 'Unknown', NONE = 'None' } @@ -150,6 +151,8 @@ export const getCommonResourceServiceError = (errorResponse: any) => { return CommonResourceServiceError.OWNERSHIP_CYCLE; case /Mounts cannot be modified in state 'Final'/.test(error): return CommonResourceServiceError.MODIFYING_CONTAINER_REQUEST_FINAL_STATE; + case /Name has already been taken/.test(error): + return CommonResourceServiceError.NAME_HAS_ALREADY_BEEN_TAKEN; default: return CommonResourceServiceError.UNKNOWN; } diff --git a/src/store/repositories/repositories-actions.ts b/src/store/repositories/repositories-actions.ts index 2330f7b4..4fa65822 100644 --- a/src/store/repositories/repositories-actions.ts +++ b/src/store/repositories/repositories-actions.ts @@ -10,6 +10,10 @@ import { navigateToRepositories } from "~/store/navigation/navigation-action"; import { unionize, ofType, UnionOf } from "~/common/unionize"; import { dialogActions } from '~/store/dialog/dialog-actions'; import { RepositoryResource } from "~/models/repositories"; +import { startSubmit, reset, stopSubmit } from "redux-form"; +import { getCommonResourceServiceError, CommonResourceServiceError } from "~/services/common-service/common-resource-service"; +import { snackbarActions, SnackbarKind } from '~/store/snackbar/snackbar-actions'; +import { projectPanelActions } from '~/store/project-panel/project-panel-action'; export const repositoriesActions = unionize({ SET_REPOSITORIES: ofType(), @@ -21,6 +25,7 @@ export const REPOSITORIES_PANEL = 'repositoriesPanel'; export const REPOSITORIES_SAMPLE_GIT_DIALOG = 'repositoriesSampleGitDialog'; export const REPOSITORY_ATTRIBUTES_DIALOG = 'repositoryAttributesDialog'; export const REPOSITORY_CREATE_FORM_NAME = 'repositoryCreateFormName'; +export const REPOSITORY_REMOVE_DIALOG = 'repositoryRemoveDialog'; export const openRepositoriesSampleGitDialog = () => (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { @@ -36,14 +41,52 @@ export const openRepositoryAttributes = (index: number) => export const openRepositoryCreateDialog = () => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { - dispatch(dialogActions.OPEN_DIALOG({ id: REPOSITORY_CREATE_FORM_NAME, data: {} })); + const userUuid = await services.authService.getUuid(); + const user = await services.userService.get(userUuid!); + dispatch(reset(REPOSITORY_CREATE_FORM_NAME)); + dispatch(dialogActions.OPEN_DIALOG({ id: REPOSITORY_CREATE_FORM_NAME, data: { user } })); }; export const createRepository = (repository: RepositoryResource) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { const userUuid = await services.authService.getUuid(); const user = await services.userService.get(userUuid!); - await services.repositoriesService.create({ name: `${user.username}/${repository.name}` }); + dispatch(startSubmit(REPOSITORY_CREATE_FORM_NAME)); + try { + const newRepository = await services.repositoriesService.create({ name: `${user.username}/${repository.name}` }); + dispatch(dialogActions.CLOSE_DIALOG({ id: REPOSITORY_CREATE_FORM_NAME })); + dispatch(reset(REPOSITORY_CREATE_FORM_NAME)); + dispatch(loadRepositoriesData()); + dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Repository has been successfully created.", hideDuration: 2000, kind: SnackbarKind.SUCCESS })); + return newRepository; + } catch (e) { + const error = getCommonResourceServiceError(e); + if (error === CommonResourceServiceError.NAME_HAS_ALREADY_BEEN_TAKEN) { + dispatch(stopSubmit(REPOSITORY_CREATE_FORM_NAME, { name: 'Repository with the same name already exists.' })); + } + return undefined; + } + }; + +export const openRemoveRepositoryDialog = (uuid: string) => + (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + dispatch(dialogActions.OPEN_DIALOG({ + id: REPOSITORY_REMOVE_DIALOG, + data: { + title: 'Remove repository', + text: 'Are you sure you want to remove this repository?', + confirmButtonLabel: 'Remove', + uuid + } + })); + }; + +export const removeRepository = (uuid: string) => + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Removing ...' })); + await services.repositoriesService.delete(uuid); + dispatch(loadRepositoriesData()); + dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Removed.', hideDuration: 2000 })); }; const repositoriesBindedActions = bindDataExplorerActions(REPOSITORIES_PANEL); diff --git a/src/views-components/context-menu/action-sets/repository-action-set.ts b/src/views-components/context-menu/action-sets/repository-action-set.ts index 2341f9ac..b2bcb5cf 100644 --- a/src/views-components/context-menu/action-sets/repository-action-set.ts +++ b/src/views-components/context-menu/action-sets/repository-action-set.ts @@ -4,9 +4,9 @@ import { ContextMenuActionSet } from "~/views-components/context-menu/context-menu-action-set"; import { AdvancedIcon, RemoveIcon, ShareIcon, AttributesIcon } from "~/components/icon/icon"; -import { openFileRemoveDialog, openRenameFileDialog } from '~/store/collection-panel/collection-panel-files/collection-panel-files-actions'; +import { openRenameFileDialog } from '~/store/collection-panel/collection-panel-files/collection-panel-files-actions'; import { openAdvancedTabDialog } from "~/store/advanced-tab/advanced-tab"; -import { openRepositoryAttributes } from "~/store/repositories/repositories-actions"; +import { openRepositoryAttributes, openRemoveRepositoryDialog } from "~/store/repositories/repositories-actions"; export const repositoryActionSet: ContextMenuActionSet = [[{ name: "Attributes", @@ -30,6 +30,6 @@ export const repositoryActionSet: ContextMenuActionSet = [[{ name: "Remove", icon: RemoveIcon, execute: (dispatch, resource) => { - dispatch(openFileRemoveDialog(resource.uuid)); + dispatch(openRemoveRepositoryDialog(resource.uuid)); } }]]; diff --git a/src/views-components/dialog-create/dialog-repository-create.tsx b/src/views-components/dialog-create/dialog-repository-create.tsx index 465f622e..45817224 100644 --- a/src/views-components/dialog-create/dialog-repository-create.tsx +++ b/src/views-components/dialog-create/dialog-repository-create.tsx @@ -13,11 +13,9 @@ type DialogRepositoryProps = WithDialogProps<{}> & InjectedFormProps; export const DialogRepositoryCreate = (props: DialogRepositoryProps) => ; -const RepositoryAddField = () => - ; diff --git a/src/views-components/form-fields/repository-form-fields.tsx b/src/views-components/form-fields/repository-form-fields.tsx index 56f1c1b2..932a5fe2 100644 --- a/src/views-components/form-fields/repository-form-fields.tsx +++ b/src/views-components/form-fields/repository-form-fields.tsx @@ -6,15 +6,25 @@ import * as React from "react"; import { Field } from "redux-form"; import { TextField } from "~/components/text-field/text-field"; import { REPOSITORY_NAME_VALIDATION } from "~/validators/validators"; +import { Grid } from "@material-ui/core"; -export const RepositoryNameField = () => - - pawelkowalczyk/ - .git
+export const RepositoryNameField = (props: any) => + + + {props.data.user.username}/ + + + + + + .git + + It may take a minute or two before you can clone your new repository. -
; \ No newline at end of file + + ; \ No newline at end of file diff --git a/src/views-components/repository-remove-dialog/repository-remove-dialog.ts b/src/views-components/repository-remove-dialog/repository-remove-dialog.ts new file mode 100644 index 00000000..148e78bd --- /dev/null +++ b/src/views-components/repository-remove-dialog/repository-remove-dialog.ts @@ -0,0 +1,20 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 +import { Dispatch, compose } from 'redux'; +import { connect } from "react-redux"; +import { ConfirmationDialog } from "~/components/confirmation-dialog/confirmation-dialog"; +import { withDialog, WithDialogProps } from "~/store/dialog/with-dialog"; +import { removeRepository, REPOSITORY_REMOVE_DIALOG } from '~/store/repositories/repositories-actions'; + + const mapDispatchToProps = (dispatch: Dispatch, props: WithDialogProps) => ({ + onConfirm: () => { + props.closeDialog(); + dispatch(removeRepository(props.data.uuid)); + } +}); + + export const RemoveRepositoryDialog = compose( + withDialog(REPOSITORY_REMOVE_DIALOG), + connect(null, mapDispatchToProps) +)(ConfirmationDialog); \ No newline at end of file diff --git a/src/views/workbench/workbench.tsx b/src/views/workbench/workbench.tsx index cefd0dc6..eee9911c 100644 --- a/src/views/workbench/workbench.tsx +++ b/src/views/workbench/workbench.tsx @@ -52,6 +52,7 @@ import { RepositoriesPanel } from '~/views/repositories-panel/repositories-panel import { RepositoriesSampleGitDialog } from '~/views-components/repositories-sample-git-dialog/repositories-sample-git-dialog'; import { RepositoryAttributesDialog } from '~/views-components/repository-attributes-dialog/repository-attributes-dialog'; import { CreateRepositoryDialog } from '~/views-components/dialog-forms/create-repository-dialog'; +import { RemoveRepositoryDialog } from '~/views-components/repository-remove-dialog/repository-remove-dialog'; type CssRules = 'root' | 'container' | 'splitter' | 'asidePanel' | 'contentWrapper' | 'content'; @@ -150,6 +151,7 @@ export const WorkbenchPanel = + -- 2.30.2