Fix Bug 65327 - Rooms. Fixed change of room owner

This commit is contained in:
Nikita Gopienko 2023-12-04 12:23:15 +03:00
parent ec00ea664a
commit 8c1acb19b8
10 changed files with 138 additions and 152 deletions

View File

@ -45,6 +45,7 @@ const EditRoomEvent = ({
removeLogoPaths,
reloadInfoPanelSelection,
changeRoomOwner,
}) => {
const { t } = useTranslation(["CreateEditRoomDialog", "Common", "Files"]);
@ -97,6 +98,8 @@ const EditRoomEvent = ({
title: roomParams.title || t("Files:NewRoom"),
};
const isOwnerChanged = roomParams?.roomOwner?.id !== item.createdBy.id;
const tags = roomParams.tags.map((tag) => tag.name);
const newTags = roomParams.tags.filter((t) => t.isNew).map((t) => t.name);
const removedTags = startTags.filter((sT) => !tags.includes(sT));
@ -107,6 +110,10 @@ const EditRoomEvent = ({
try {
setIsLoading(true);
if (isOwnerChanged) {
await changeRoomOwner(t, roomParams?.roomOwner?.id);
}
let room = await editRoom(item.id, editRoomParams);
room.isLogoLoading = true;
@ -259,7 +266,7 @@ export default inject(
removeLogoPaths,
updateLogoPathsCacheBreaker,
} = selectedFolderStore;
const { updateCurrentFolder } = filesActionsStore;
const { updateCurrentFolder, changeRoomOwner } = filesActionsStore;
const { getThirdPartyIcon } = settingsStore.thirdPartyStore;
const { setCreateRoomDialogVisible } = dialogsStore;
const { withPaging } = auth.settingsStore;
@ -297,6 +304,7 @@ export default inject(
removeLogoPaths,
reloadInfoPanelSelection,
changeRoomOwner,
};
}
)(observer(EditRoomEvent));

View File

@ -59,6 +59,7 @@ const PeopleSelector = ({
withFooterCheckbox,
footerCheckboxLabel,
isChecked,
setIsChecked,
filterUserId,
}) => {
const [itemsList, setItemsList] = useState(items);
@ -104,6 +105,7 @@ const PeopleSelector = ({
isAdmin,
isVisitor,
isCollaborator,
hasAvatar,
};
};
@ -246,6 +248,7 @@ const PeopleSelector = ({
withFooterCheckbox={withFooterCheckbox}
footerCheckboxLabel={footerCheckboxLabel}
isChecked={isChecked}
setIsChecked={setIsChecked}
searchLoader={<Loaders.SelectorSearchLoader />}
isSearchLoading={isLoading}
rowLoader={<Loaders.SelectorRowLoader isUser isContainer={isLoading} />}

View File

@ -14,6 +14,8 @@ const ChangeRoomOwner = ({
onOwnerChange,
currentColorScheme,
}) => {
const userName = roomOwner.displayName ?? roomOwner.label;
return (
<Styled.ChangeRoomOwner>
<Text className="change-owner-label" fontWeight={600} fontSize="13px">
@ -26,12 +28,12 @@ const ChangeRoomOwner = ({
size="base"
role={""}
isDefaultSource={roomOwner.hasAvatar}
source={roomOwner.avatarSmall}
userName={roomOwner.displayName}
source={roomOwner.avatarSmall ?? roomOwner.avatar}
userName={userName}
/>
<div className="change-owner-display-name">
<Text fontWeight={600} fontSize="13px">
{roomOwner.displayName}
{userName}
</Text>
{roomOwner.id === currentUserId && (
<Text className="me-label">({t("Common:MeLabel")})</Text>

View File

@ -1,13 +1,9 @@
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useEffect, useState } from "react";
import ModalDialog from "@docspace/components/modal-dialog";
import Button from "@docspace/components/button";
import Text from "@docspace/components/text";
import { withTranslation } from "react-i18next";
import { inject, observer } from "mobx-react";
import { ShareAccessRights } from "@docspace/common/constants";
import toastr from "@docspace/components/toast/toastr";
import RoomsFilter from "@docspace/common/api/rooms/filter";
const LeaveRoomDialog = (props) => {
const {
@ -17,19 +13,9 @@ const LeaveRoomDialog = (props) => {
setIsVisible,
setChangeRoomOwnerIsVisible,
isOwner,
updateRoomMemberRole,
roomId,
userId,
removeFiles,
isAdmin,
setSelected,
isRoot,
folders,
setFolders,
onLeaveRoomAction,
} = props;
const navigate = useNavigate();
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
@ -45,38 +31,15 @@ const LeaveRoomDialog = (props) => {
if (e.keyCode === 13 || e.which === 13) onLeaveRoom();
};
const onLeaveRoom = () => {
const onLeaveRoom = async () => {
if (isOwner) {
setChangeRoomOwnerIsVisible(true);
onClose();
} else {
setIsLoading(true);
updateRoomMemberRole(roomId, {
invitations: [{ id: userId, access: ShareAccessRights.None }],
})
.then(() => {
if (!isAdmin) {
if (!isRoot) {
const filter = RoomsFilter.getDefault();
navigate(`rooms/shared/filter?${filter.toUrlParams()}`);
} else {
removeFiles(null, [roomId]);
}
} else {
const newFolders = folders;
const folderIndex = newFolders.findIndex((r) => r.id === roomId);
newFolders[folderIndex].inRoom = false;
setFolders(newFolders);
}
toastr.success(t("Files:YouLeftTheRoom"));
})
.finally(() => {
onClose();
setIsLoading(false);
setSelected("none");
});
await onLeaveRoomAction(t, isOwner);
setIsLoading(false);
onClose();
}
};
@ -118,49 +81,32 @@ const LeaveRoomDialog = (props) => {
};
export default inject(
({ auth, dialogsStore, filesStore, selectedFolderStore }) => {
({
auth,
dialogsStore,
filesStore,
selectedFolderStore,
filesActionsStore,
}) => {
const {
leaveRoomDialogVisible: visible,
setLeaveRoomDialogVisible: setIsVisible,
setChangeRoomOwnerIsVisible,
} = dialogsStore;
const { user } = auth.userStore;
const {
selection,
bufferSelection,
updateRoomMemberRole,
removeFiles,
setSelected,
folders,
setFolders,
} = filesStore;
const roomId = selection.length
? selection[0].id
: bufferSelection
? bufferSelection.id
: selectedFolderStore.id;
const { selection, bufferSelection } = filesStore;
const selections = selection.length ? selection : [bufferSelection];
const folderItem = selections[0] ? selections[0] : selectedFolderStore;
const isRoomOwner = folderItem?.createdBy?.id === user.id;
const isRoot = selectedFolderStore.isRootFolder;
return {
visible,
setIsVisible,
setChangeRoomOwnerIsVisible,
isOwner: isRoomOwner,
updateRoomMemberRole,
roomId,
userId: user.id,
removeFiles,
isAdmin: user.isOwner || user.isAdmin,
setSelected,
isRoot,
folders,
setFolders,
onLeaveRoomAction: filesActionsStore.onLeaveRoom,
};
}
)(observer(withTranslation(["Common", "Files"])(LeaveRoomDialog)));

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react";
import { useState, useEffect } from "react";
import { inject, observer } from "mobx-react";
import styled, { css } from "styled-components";
import Aside from "@docspace/components/aside";
@ -6,8 +6,7 @@ import Backdrop from "@docspace/components/backdrop";
import PeopleSelector from "@docspace/client/src/components/PeopleSelector";
import { withTranslation } from "react-i18next";
import Filter from "@docspace/common/api/people/filter";
import { EmployeeType, ShareAccessRights } from "@docspace/common/constants";
import toastr from "@docspace/components/toast/toastr";
import { EmployeeType } from "@docspace/common/constants";
import { DeviceType } from "@docspace/common/constants";
import Portal from "@docspace/components/portal";
@ -43,23 +42,14 @@ const ChangeRoomOwner = (props) => {
visible,
setIsVisible,
showBackButton,
setRoomOwner,
roomId,
setFolder,
updateRoomMemberRole,
userId,
isAdmin,
setRoomParams,
removeFiles,
folders,
setFolders,
currentDeviceType,
roomOwnerId,
isRootFolder,
setCreatedBy,
changeRoomOwner,
} = props;
const [isLoading, setIsLoading] = useState(false);
const [isChecked, setIsChecked] = useState(!showBackButton);
useEffect(() => {
document.addEventListener("keyup", onKeyUp, false);
@ -74,47 +64,16 @@ const ChangeRoomOwner = (props) => {
if (e.keyCode === 13 || e.which === 13) onChangeRoomOwner();
};
const onLeaveRoom = () => {
setIsLoading(true);
updateRoomMemberRole(roomId, {
invitations: [{ id: userId, access: ShareAccessRights.None }],
})
.then(() => {
if (!isAdmin) removeFiles(null, [roomId]);
else {
const newFolders = folders;
const folderIndex = newFolders.findIndex((r) => r.id === roomId);
newFolders[folderIndex].inRoom = false;
setFolders(newFolders);
}
toastr.success(t("Files:LeftAndAppointNewOwner"));
})
const onChangeRoomOwner = async (user) => {
if (showBackButton) {
setRoomParams && setRoomParams(user[0]);
} else {
setIsLoading(true);
.finally(() => {
onClose();
setIsLoading(false);
});
};
const onChangeRoomOwner = (user, isChecked) => {
setIsLoading(true);
setRoomOwner(user[0].id, [roomId])
.then(async (res) => {
if (isRootFolder) {
setFolder(res[0]);
} else {
setCreatedBy(res[0].createdBy);
}
if (isChecked) await onLeaveRoom();
else toastr.success(t("Files:AppointNewOwner"));
setRoomParams && setRoomParams(res[0].createdBy);
})
.finally(() => {
setIsLoading(false);
onClose();
});
await changeRoomOwner(t, user[0]?.id, isChecked);
setIsLoading(false);
}
onClose();
};
const onClose = () => {
@ -150,13 +109,16 @@ const ChangeRoomOwner = (props) => {
{...backClickProp}
onAccept={onChangeRoomOwner}
onCancel={onClose}
acceptButtonLabel={t("Files:AssignOwner")}
acceptButtonLabel={
showBackButton ? t("Common:SelectAction") : t("Files:AssignOwner")
}
headerLabel={t("Files:ChangeTheRoomOwner")}
filter={filter}
isLoading={isLoading}
withFooterCheckbox={!showBackButton}
footerCheckboxLabel={t("Files:LeaveTheRoom")}
isChecked={!showBackButton}
isChecked={isChecked}
setIsChecked={setIsChecked}
withOutCurrentAuthorizedUser
filterUserId={roomOwnerId}
/>
@ -172,7 +134,13 @@ const ChangeRoomOwner = (props) => {
};
export default inject(
({ auth, dialogsStore, filesStore, selectedFolderStore }) => {
({
auth,
dialogsStore,
filesStore,
selectedFolderStore,
filesActionsStore,
}) => {
const {
changeRoomOwnerIsVisible,
setChangeRoomOwnerIsVisible,
@ -180,17 +148,7 @@ export default inject(
} = dialogsStore;
const { settingsStore } = auth;
const { user } = auth.userStore;
const {
setRoomOwner,
selection,
bufferSelection,
setFolder,
updateRoomMemberRole,
removeFiles,
folders,
setFolders,
} = filesStore;
const { selection, bufferSelection } = filesStore;
const room = selection.length
? selection[0]
@ -205,19 +163,9 @@ export default inject(
setIsVisible: setChangeRoomOwnerIsVisible,
showBackButton: changeRoomOwnerData.showBackButton,
setRoomParams: changeRoomOwnerData.setRoomParams,
setRoomOwner,
userId: user.id,
roomId: room.id,
roomOwnerId: room?.createdBy?.id,
isRootFolder: selectedFolderStore.isRootFolder,
setCreatedBy: selectedFolderStore.setCreatedBy,
setFolder,
updateRoomMemberRole,
isAdmin: user.isOwner || user.isAdmin,
removeFiles,
folders,
setFolders,
currentDeviceType,
changeRoomOwner: filesActionsStore.changeRoomOwner,
};
}
)(observer(withTranslation(["Files"])(ChangeRoomOwner)));

View File

@ -30,6 +30,7 @@ import {
FileStatus,
FolderType,
RoomsType,
ShareAccessRights,
} from "@docspace/common/constants";
import { makeAutoObservable } from "mobx";
@ -2417,6 +2418,78 @@ class FilesActionStore {
this.uploadDataStore.itemOperationToFolder(operationData);
};
onLeaveRoom = (t, isOwner = false) => {
const {
updateRoomMemberRole,
removeFiles,
folders,
setFolders,
selection,
bufferSelection,
} = this.filesStore;
const { user } = this.authStore.userStore;
const roomId = selection.length
? selection[0].id
: bufferSelection
? bufferSelection.id
: this.selectedFolderStore.id;
const isAdmin = user.isOwner || user.isAdmin;
const isRoot = this.selectedFolderStore.isRootFolder;
return updateRoomMemberRole(roomId, {
invitations: [{ id: user?.id, access: ShareAccessRights.None }],
}).then(() => {
if (!isAdmin) {
if (!isRoot) {
const filter = RoomsFilter.getDefault();
window.DocSpace.navigate(
`rooms/shared/filter?${filter.toUrlParams()}`
);
} else {
removeFiles(null, [roomId]);
}
} else {
const newFolders = folders;
const folderIndex = newFolders.findIndex((r) => r.id === roomId);
newFolders[folderIndex].inRoom = false;
setFolders(newFolders);
}
isOwner
? toastr.success(t("Files:LeftAndAppointNewOwner"))
: toastr.success(t("Files:YouLeftTheRoom"));
});
};
changeRoomOwner = (t, userId, isLeaveChecked = false) => {
const { setRoomOwner, setFolder, setSelected, selection, bufferSelection } =
this.filesStore;
const { isRootFolder, setCreatedBy, id } = this.selectedFolderStore;
const roomId = selection.length
? selection[0].id
: bufferSelection
? bufferSelection.id
: id;
return setRoomOwner(userId, [roomId])
.then(async (res) => {
if (isRootFolder) {
setFolder(res[0]);
} else {
setCreatedBy(res[0].createdBy);
}
if (isLeaveChecked) await this.onLeaveRoom(t);
else toastr.success(t("Files:AppointNewOwner"));
})
.finally(() => {
setSelected("none");
});
};
}
export default FilesActionStore;

View File

@ -80,4 +80,5 @@ export type SelectorProps = {
acceptButtonId?: string;
cancelButtonId?: string;
isChecked?: boolean;
setIsChecked?: any;
};

View File

@ -84,6 +84,7 @@ const Selector = ({
acceptButtonId,
cancelButtonId,
isChecked,
setIsChecked,
}: SelectorProps) => {
const [footerVisible, setFooterVisible] = React.useState<boolean>(false);
const [isSearch, setIsSearch] = React.useState<boolean>(false);
@ -375,6 +376,7 @@ const Selector = ({
setNewFooterInputValue={setNewFooterInputValue}
isFooterCheckboxChecked={isFooterCheckboxChecked}
setIsFooterCheckboxChecked={setIsFooterCheckboxChecked}
setIsChecked={setIsChecked}
disableAcceptButton={
withFooterInput
? disableAcceptButton

View File

@ -22,6 +22,7 @@ export type FooterProps = {
setNewFooterInputValue?: (value: string) => void;
isFooterCheckboxChecked?: boolean;
setIsFooterCheckboxChecked?: any;
setIsChecked?: any;
acceptButtonId?: string;
cancelButtonId?: string;

View File

@ -36,6 +36,7 @@ const Footer = React.memo(
setNewFooterInputValue,
isFooterCheckboxChecked,
setIsFooterCheckboxChecked,
setIsChecked,
acceptButtonId,
cancelButtonId,
}: FooterProps) => {
@ -50,6 +51,7 @@ const Footer = React.memo(
};
const onChangeCheckbox = () => {
setIsChecked && setIsChecked((value: boolean) => !value);
setIsFooterCheckboxChecked &&
setIsFooterCheckboxChecked((value: boolean) => !value);
};