Client: EditGroupMembersDialog: Add virtual list

This commit is contained in:
Aleksandr Lushkin 2024-07-22 17:11:40 +02:00
parent 68a7026879
commit e2de363696
5 changed files with 131 additions and 19 deletions

View File

@ -0,0 +1,38 @@
// (c) Copyright Ascensio System SIA 2009-2024
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
import styled from "styled-components";
import { ModalDialog } from "@docspace/shared/components/modal-dialog";
export const StyledModalDialog = styled(ModalDialog)`
.modal-body {
padding: 0;
}
.search-input {
margin: 16px 16px 12px;
}
`;

View File

@ -34,8 +34,10 @@ import { getGroupMembersInRoom } from "@docspace/shared/api/groups";
import { useTranslation } from "react-i18next";
import { InputSize } from "@docspace/shared/components/text-input";
import { SearchInput } from "@docspace/shared/components/search-input";
import GroupMember from "./GroupMember";
import GroupMember from "./sub-components/GroupMember";
import EmptyContainer from "./EmptyContainer";
import GroupMembersList from "./sub-components/GroupMembersList/GroupMembersList";
import { StyledModalDialog } from "./EditGroupMembersDialog.styled";
interface EditGroupMembersProps {
visible: boolean;
@ -87,7 +89,7 @@ const EditGroupMembers = ({
}
return (
<ModalDialog
<StyledModalDialog
visible={visible}
onClose={onClose}
displayType={ModalDialogType.aside}
@ -104,16 +106,15 @@ const EditGroupMembers = ({
size={InputSize.base}
/>
<div style={{ height: "12px", width: "100%" }} />
{isSearchListEmpty && <EmptyContainer />}
{hasMembers &&
filteredGroupMembers.map(({ user, ...rest }) => (
<GroupMember t={t} key={user.id} user={{ ...user, ...rest }} />
))}
{/*{hasMembers &&*/}
{/* filteredGroupMembers.map(({ user, ...rest }) => (*/}
{/* <GroupMember t={t} key={user.id} user={{ ...user, ...rest }} />*/}
{/* ))}*/}
{hasMembers && <GroupMembersList members={groupMembers} />}
</ModalDialog.Body>
</ModalDialog>
</StyledModalDialog>
);
};

View File

@ -31,7 +31,7 @@ export const GroupMember = styled.div<{ isExpect: boolean }>`
display: flex;
align-items: center;
gap: 8px;
padding: 8px 0;
padding: 8px 16px;
.avatar {
min-width: 32px;

View File

@ -44,19 +44,25 @@ import { HelpButton } from "@docspace/shared/components/help-button";
import { getUserRoleOptions } from "@docspace/shared/utils/room-members/getUserRoleOptions";
import { ShareAccessRights } from "@docspace/shared/enums";
import { getUserRole, getUserTypeLabel } from "@docspace/shared/utils/common";
import { useTranslation } from "react-i18next";
interface GroupMemberProps {
t: any;
user: any;
member: any;
infoPanelSelection: any;
}
const GroupMember = ({ t, user, infoPanelSelection }: GroupMemberProps) => {
const GroupMember = ({ member, infoPanelSelection }: GroupMemberProps) => {
const { user } = member;
const [isLoading, setIsLoading] = useState(false);
const { t } = useTranslation("Common");
const userRole = user.isOwner
? getUserRoleOptions(t).portalAdmin
: getUserRoleOptionsByUserAccess(t, user.userAccess || user.groupAccess);
: getUserRoleOptionsByUserAccess(
t,
member.userAccess || member.groupAccess,
);
const fullRoomRoleOptions = getUserRoleOptionsByRoomType(
t,
@ -86,7 +92,7 @@ const GroupMember = ({ t, user, infoPanelSelection }: GroupMemberProps) => {
else
selectedUserRoleCBOption = getUserRoleOptionsByUserAccess(
t,
user.userAccess || user.groupAccess,
member.userAccess || member.groupAccess,
);
const availableUserRoleCBOptions = filterUserRoleOptions(
@ -101,7 +107,7 @@ const GroupMember = ({ t, user, infoPanelSelection }: GroupMemberProps) => {
notify: false,
sharingMessage: "",
})
.then(() => (user.userAccess = userRoleOption.access))
.then(() => (member.userAccess = userRoleOption.access))
.catch((err) => toastr.error(err))
.finally(() => setIsLoading(false));
};
@ -134,8 +140,8 @@ const GroupMember = ({ t, user, infoPanelSelection }: GroupMemberProps) => {
</div>
<div className="individual-rights-tooltip">
{user.userAccess &&
user.userAccess !== user.groupAccess &&
{member.userAccess &&
member.userAccess !== member.groupAccess &&
!user.isOwner && (
<HelpButton
place="left"
@ -152,7 +158,7 @@ const GroupMember = ({ t, user, infoPanelSelection }: GroupMemberProps) => {
{userRole && userRoleOptions && (
<div className="role-wrapper">
{user.canEditAccess && !user.isOwner ? (
{member.canEditAccess && !user.isOwner ? (
<ComboBox
className="role-combobox"
selectedOption={userRole}

View File

@ -0,0 +1,67 @@
// (c) Copyright Ascensio System SIA 2009-2024
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
import { memo, useMemo } from "react";
import { areEqual, FixedSizeList as List } from "react-window";
import AutoSizer from "react-virtualized-auto-sizer";
import { CustomScrollbarsVirtualListWithAutoFocus } from "@docspace/shared/components/scrollbar";
import GroupMember from "../GroupMember";
const ROW_HEIGHT = 48;
const SEARCH_WITH_PADDING_HEIGHT = 60;
const Row = memo(({ data, index, style }) => {
const member = data[index];
return (
<div style={style}>
<GroupMember member={member} />
</div>
);
}, areEqual);
const GroupMembersList = ({ members }) => {
return (
<AutoSizer>
{({ height, width }) => (
<List
height={height - SEARCH_WITH_PADDING_HEIGHT}
width={width}
itemCount={members.length}
itemSize={ROW_HEIGHT}
itemData={members}
outerElementType={CustomScrollbarsVirtualListWithAutoFocus}
>
{Row}
</List>
)}
</AutoSizer>
);
};
export default GroupMembersList;