X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/59ad75d2aca135adeb1aadc9847653e5c273ccc1..1826bc21a34b983778f6e221b6c4004fdea1ad1d:/src/store/sharing-dialog/sharing-dialog-actions.ts diff --git a/src/store/sharing-dialog/sharing-dialog-actions.ts b/src/store/sharing-dialog/sharing-dialog-actions.ts index 586ab664..17b237ec 100644 --- a/src/store/sharing-dialog/sharing-dialog-actions.ts +++ b/src/store/sharing-dialog/sharing-dialog-actions.ts @@ -8,7 +8,7 @@ import { SHARING_DIALOG_NAME, SharingPublicAccessFormData, SHARING_PUBLIC_ACCESS import { Dispatch } from 'redux'; import { ServiceRepository } from "~/services/services"; import { FilterBuilder } from '~/services/api/filter-builder'; -import { initialize, getFormValues, isDirty, reset } from 'redux-form'; +import { initialize, getFormValues, reset } from 'redux-form'; import { SHARING_MANAGEMENT_FORM_NAME } from '~/store/sharing-dialog/sharing-dialog-types'; import { RootState } from '~/store/store'; import { getDialog } from '~/store/dialog/dialog-reducer'; @@ -16,6 +16,11 @@ import { PermissionLevel } from '~/models/permission'; import { getPublicGroupUuid } from "~/store/workflow-panel/workflow-panel-actions"; import { PermissionResource } from '~/models/permission'; import { differenceWith } from "lodash"; +import { withProgress } from "~/store/progress-indicator/with-progress"; +import { progressIndicatorActions } from '~/store/progress-indicator/progress-indicator-actions.ts'; +import { snackbarActions, SnackbarKind } from "../snackbar/snackbar-actions"; +import { extractUuidKind, ResourceKind } from "~/models/resource"; +import { LinkClass } from "~/models/link"; export const openSharingDialog = (resourceUuid: string) => (dispatch: Dispatch) => { @@ -27,8 +32,11 @@ export const closeSharingDialog = () => dialogActions.CLOSE_DIALOG({ id: SHARING_DIALOG_NAME }); export const connectSharingDialog = withDialog(SHARING_DIALOG_NAME); +export const connectSharingDialogProgress = withProgress(SHARING_DIALOG_NAME); + export const saveSharingDialogChanges = async (dispatch: Dispatch) => { + dispatch(progressIndicatorActions.START_WORKING(SHARING_DIALOG_NAME)); await dispatch(savePublicPermissionChanges); await dispatch(saveManagementChanges); await dispatch(sendInvitations); @@ -36,19 +44,32 @@ export const saveSharingDialogChanges = async (dispatch: Dispatch) => { await dispatch(loadSharingDialog); }; -export const hasChanges = (state: RootState) => - isDirty(SHARING_PUBLIC_ACCESS_FORM_NAME)(state) || - isDirty(SHARING_MANAGEMENT_FORM_NAME)(state) || - isDirty(SHARING_INVITATION_FORM_NAME)(state); +export const sendSharingInvitations = async (dispatch: Dispatch) => { + dispatch(progressIndicatorActions.START_WORKING(SHARING_DIALOG_NAME)); + await dispatch(sendInvitations); + dispatch(closeSharingDialog()); + dispatch(snackbarActions.OPEN_SNACKBAR({ + message: 'Resource has been shared', + kind: SnackbarKind.SUCCESS, + })); + dispatch(progressIndicatorActions.STOP_WORKING(SHARING_DIALOG_NAME)); +}; const loadSharingDialog = async (dispatch: Dispatch, getState: () => RootState, { permissionService }: ServiceRepository) => { const dialog = getDialog(getState().dialog, SHARING_DIALOG_NAME); - if (dialog) { - const { items } = await permissionService.listResourcePermissions(dialog.data); - dispatch(initializePublicAccessForm(items)); - await dispatch(initializeManagementForm(items)); + dispatch(progressIndicatorActions.START_WORKING(SHARING_DIALOG_NAME)); + try { + const { items } = await permissionService.listResourcePermissions(dialog.data); + dispatch(initializePublicAccessForm(items)); + await dispatch(initializeManagementForm(items)); + dispatch(progressIndicatorActions.STOP_WORKING(SHARING_DIALOG_NAME)); + } catch (e) { + dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'You do not have access to share this item', hideDuration: 2000, kind: SnackbarKind.ERROR })); + dispatch(dialogActions.CLOSE_DIALOG({ id: SHARING_DIALOG_NAME })); + dispatch(progressIndicatorActions.STOP_WORKING(SHARING_DIALOG_NAME)); + } } }; @@ -146,9 +167,9 @@ const saveManagementChanges = async (_: Dispatch, getState: () => RootState, { p if (visibility === VisibilityLevel.PRIVATE) { - await Promise.all(initialPermissions.map(({ permissionUuid, permissions }) => - permissionService.delete(permissionUuid) - )); + for (const permission of initialPermissions) { + await permissionService.delete(permission.permissionUuid); + } } else { @@ -158,34 +179,64 @@ const saveManagementChanges = async (_: Dispatch, getState: () => RootState, { p (a, b) => a.permissionUuid === b.permissionUuid ); - await Promise.all(cancelledPermissions.map(({ permissionUuid }) => - permissionService.delete(permissionUuid) - )); + for (const { permissionUuid } of cancelledPermissions) { + await permissionService.delete(permissionUuid); + } + + for (const permission of permissions) { + await permissionService.update(permission.permissionUuid, { name: permission.permissions }); + } - await Promise.all(permissions.map(({ permissionUuid, permissions }) => - permissionService.update(permissionUuid, { name: permissions }) - )); } } }; -const sendInvitations = async (_: Dispatch, getState: () => RootState, { permissionService }: ServiceRepository) => { +const sendInvitations = async (_: Dispatch, getState: () => RootState, { permissionService, userService }: ServiceRepository) => { const state = getState(); const { user } = state.auth; const dialog = getDialog(state.dialog, SHARING_DIALOG_NAME); if (dialog && user) { - const invitations = getFormValues(SHARING_INVITATION_FORM_NAME)(state) as SharingInvitationFormData; - const promises = invitations.invitedPeople + const getGroupsFromForm = invitations.invitedPeople.filter((invitation) => extractUuidKind(invitation.uuid) === ResourceKind.GROUP); + const getUsersFromForm = invitations.invitedPeople.filter((invitation) => extractUuidKind(invitation.uuid) === ResourceKind.USER); + const uuids = getGroupsFromForm.map(group => group.uuid); + + const permissions = await permissionService.list({ + filters: new FilterBuilder() + .addIn('tailUuid', uuids) + .addEqual('linkClass', LinkClass.PERMISSION) + .getFilters() + }); + + const usersFromGroups = await userService.list({ + filters: new FilterBuilder() + .addIn('uuid', permissions.items.map(item => item.headUuid)) + .getFilters() + + }); + + const invitationDataUsers = getUsersFromForm .map(person => ({ ownerUuid: user.uuid, headUuid: dialog.data, tailUuid: person.uuid, name: invitations.permissions - })) - .map(data => permissionService.create(data)); + })); - await Promise.all(promises); + const invitationsDataGroups = usersFromGroups.items.map( + person => ({ + ownerUuid: user.uuid, + headUuid: dialog.data, + tailUuid: person.uuid, + name: invitations.permissions + }) + ); + + const data = invitationDataUsers.concat(invitationsDataGroups); + + for (const invitation of data) { + await permissionService.create(invitation); + } } };