Web: Client: Data Import: translate SelectUsersStep to ts
This commit is contained in:
parent
e32f5b36bc
commit
2328d10f95
@ -0,0 +1,53 @@
|
||||
// (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 { Row } from "@docspace/shared/components/row";
|
||||
import UsersRowContent from "./UsersRowContent";
|
||||
import { UsersRowProps } from "../../../../types";
|
||||
|
||||
const UsersRow = (props: UsersRowProps) => {
|
||||
const { t, data, sectionWidth, isChecked, toggleAccount } = props;
|
||||
|
||||
return (
|
||||
<Row
|
||||
checked={isChecked}
|
||||
onSelect={toggleAccount}
|
||||
contextButtonSpacerWidth="0"
|
||||
onRowClick={toggleAccount}
|
||||
>
|
||||
<UsersRowContent
|
||||
t={t}
|
||||
data={data}
|
||||
sectionWidth={sectionWidth}
|
||||
displayName={data.displayName}
|
||||
email={data.email}
|
||||
isDuplicate={data.isDuplicate}
|
||||
/>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
export default UsersRow;
|
@ -0,0 +1,95 @@
|
||||
// (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, { css } from "styled-components";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { Box } from "@docspace/shared/components/box";
|
||||
import { RowContent } from "@docspace/shared/components/row-content";
|
||||
import { UsersRowContentProps } from "../../../../types";
|
||||
|
||||
const StyledRowContent = styled(RowContent)`
|
||||
display: flex;
|
||||
|
||||
.rowMainContainer {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.username {
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
margin-left: 5px;
|
||||
`
|
||||
: css`
|
||||
margin-right: 5px;
|
||||
`}
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: ${(props) => props.theme.client.settings.migration.subtitleColor};
|
||||
}
|
||||
|
||||
.user-email {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: ${(props) =>
|
||||
props.theme.client.settings.migration.tableRowTextColor};
|
||||
}
|
||||
|
||||
.user-existing {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: ${(props) =>
|
||||
props.theme.client.settings.migration.existingTextColor};
|
||||
}
|
||||
`;
|
||||
|
||||
const UsersRowContent = (props: UsersRowContentProps) => {
|
||||
const { t, data, sectionWidth, displayName, email, isDuplicate } = props;
|
||||
|
||||
const contentData = [
|
||||
<div key={data.key}>
|
||||
<Box displayProp="flex">
|
||||
<Text className="username">{displayName}</Text>
|
||||
{isDuplicate && (
|
||||
<Text className="user-existing">
|
||||
({t("Settings:AccountAlreadyExists")})
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<Text className="user-email">{email}</Text>
|
||||
</div>,
|
||||
];
|
||||
|
||||
return (
|
||||
<StyledRowContent sectionWidth={sectionWidth}>
|
||||
{contentData}
|
||||
</StyledRowContent>
|
||||
);
|
||||
};
|
||||
|
||||
export default UsersRowContent;
|
@ -0,0 +1,195 @@
|
||||
// (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 { inject, observer } from "mobx-react";
|
||||
import { tablet } from "@docspace/shared/utils/device";
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
import { EmptyScreenContainer } from "@docspace/shared/components/empty-screen-container";
|
||||
import { IconButton } from "@docspace/shared/components/icon-button";
|
||||
import { Link, LinkType } from "@docspace/shared/components/link";
|
||||
import { Box } from "@docspace/shared/components/box";
|
||||
import { Checkbox } from "@docspace/shared/components/checkbox";
|
||||
import { RowContainer } from "@docspace/shared/components/row-container";
|
||||
import { Row } from "@docspace/shared/components/row";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import EmptyScreenUserReactSvgUrl from "PUBLIC_DIR/images/empty_screen_user.react.svg?url";
|
||||
import ClearEmptyFilterSvgUrl from "PUBLIC_DIR/images/clear.empty.filter.svg?url";
|
||||
import { TEnhancedMigrationUser } from "@docspace/shared/api/settings/types";
|
||||
import UsersRow from "./UsersRow";
|
||||
import { InjectedRowViewProps, RowViewProps } from "../../../../types";
|
||||
|
||||
const StyledRowContainer = styled(RowContainer)`
|
||||
margin: 0 0 20px;
|
||||
|
||||
.clear-icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.ec-desc {
|
||||
max-width: 348px;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledRow = styled(Row)`
|
||||
box-sizing: border-box;
|
||||
height: 40px;
|
||||
min-height: 40px;
|
||||
|
||||
.row-header-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
margin-right: 6px;
|
||||
`
|
||||
: css`
|
||||
margin-left: 6px;
|
||||
`}
|
||||
}
|
||||
|
||||
.row-header-title {
|
||||
color: ${(props) => props.theme.client.settings.migration.tableHeaderText};
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
.row_content {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const checkedAccountType = "withEmail";
|
||||
|
||||
const RowView = (props: RowViewProps) => {
|
||||
const {
|
||||
t,
|
||||
sectionWidth,
|
||||
accountsData,
|
||||
|
||||
checkedUsers,
|
||||
withEmailUsers,
|
||||
toggleAccount,
|
||||
toggleAllAccounts,
|
||||
isAccountChecked,
|
||||
setSearchValue,
|
||||
} = props as InjectedRowViewProps;
|
||||
|
||||
const toggleAll = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
toggleAllAccounts(e.target.checked, withEmailUsers, checkedAccountType);
|
||||
|
||||
const handleToggle = (user: TEnhancedMigrationUser) =>
|
||||
toggleAccount(user, checkedAccountType);
|
||||
|
||||
const onClearFilter = () => setSearchValue("");
|
||||
|
||||
const isIndeterminate =
|
||||
checkedUsers.withEmail.length > 0 &&
|
||||
checkedUsers.withEmail.length !== withEmailUsers.length;
|
||||
|
||||
const isChecked = checkedUsers.withEmail.length === withEmailUsers.length;
|
||||
|
||||
return (
|
||||
<StyledRowContainer useReactWindow={false}>
|
||||
{accountsData.length > 0 ? (
|
||||
<>
|
||||
<StyledRow>
|
||||
<div className="row-header-item">
|
||||
{checkedUsers.withEmail.length > 0 && (
|
||||
<Checkbox
|
||||
isIndeterminate={isIndeterminate}
|
||||
isChecked={isChecked}
|
||||
onChange={toggleAll}
|
||||
/>
|
||||
)}
|
||||
<Text className="row-header-title">{t("Common:Name")}</Text>
|
||||
</div>
|
||||
</StyledRow>
|
||||
|
||||
{accountsData.map((data) => (
|
||||
<UsersRow
|
||||
t={t}
|
||||
key={data.key}
|
||||
data={data}
|
||||
sectionWidth={sectionWidth}
|
||||
isChecked={isAccountChecked(data.key, checkedAccountType)}
|
||||
toggleAccount={() => handleToggle(data)}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<EmptyScreenContainer
|
||||
imageSrc={EmptyScreenUserReactSvgUrl}
|
||||
imageAlt="Empty Screen user image"
|
||||
headerText={t("Common:NotFoundUsers")}
|
||||
descriptionText={t("Common:NotFoundUsersDescription")}
|
||||
buttons={
|
||||
<Box displayProp="flex" alignItems="center">
|
||||
<IconButton
|
||||
className="clear-icon"
|
||||
isFill
|
||||
size={12}
|
||||
onClick={onClearFilter}
|
||||
iconName={ClearEmptyFilterSvgUrl}
|
||||
/>
|
||||
<Link
|
||||
type={LinkType.action}
|
||||
isHovered
|
||||
fontWeight="600"
|
||||
onClick={onClearFilter}
|
||||
>
|
||||
{t("Common:ClearFilter")}
|
||||
</Link>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</StyledRowContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject<TStore>(({ importAccountsStore }) => {
|
||||
const {
|
||||
checkedUsers,
|
||||
withEmailUsers,
|
||||
toggleAccount,
|
||||
toggleAllAccounts,
|
||||
isAccountChecked,
|
||||
setSearchValue,
|
||||
} = importAccountsStore;
|
||||
|
||||
return {
|
||||
checkedUsers,
|
||||
withEmailUsers,
|
||||
toggleAccount,
|
||||
toggleAllAccounts,
|
||||
isAccountChecked,
|
||||
setSearchValue,
|
||||
};
|
||||
})(observer(RowView));
|
@ -0,0 +1,151 @@
|
||||
// (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 { useState, useEffect } from "react";
|
||||
|
||||
import { TableHeader, TTableColumn } from "@docspace/shared/components/table";
|
||||
|
||||
import { UsersTableHeaderProps } from "../../../../types";
|
||||
|
||||
const TABLE_VERSION = "6";
|
||||
const TABLE_COLUMNS = `nextcloudSecondColumns_ver-${TABLE_VERSION}`;
|
||||
|
||||
const getColumns = (defaultColumns: TTableColumn[], userId?: string) => {
|
||||
const storageColumns = localStorage.getItem(`${TABLE_COLUMNS}=${userId}`);
|
||||
|
||||
if (storageColumns) {
|
||||
const splitColumns = storageColumns?.split(",");
|
||||
|
||||
return defaultColumns.map((col) => ({
|
||||
...col,
|
||||
enable: splitColumns.includes(col.key),
|
||||
}));
|
||||
}
|
||||
|
||||
return defaultColumns;
|
||||
};
|
||||
|
||||
const UsersTableHeader = (props: UsersTableHeaderProps) => {
|
||||
const {
|
||||
t,
|
||||
userId,
|
||||
sectionWidth,
|
||||
tableRef,
|
||||
columnStorageName,
|
||||
columnInfoPanelStorageName,
|
||||
isIndeterminate,
|
||||
isChecked,
|
||||
toggleAll,
|
||||
} = props;
|
||||
|
||||
const [columns, setColumns] = useState<TTableColumn[]>([
|
||||
{
|
||||
key: "Name",
|
||||
title: t("Common:Name"),
|
||||
resizable: true,
|
||||
enable: true,
|
||||
default: true,
|
||||
active: true,
|
||||
minWidth: 180,
|
||||
},
|
||||
]);
|
||||
|
||||
function onColumnChange(key: string) {
|
||||
const columnIndex = columns.findIndex((c) => c.key === key);
|
||||
|
||||
if (columnIndex === -1) return;
|
||||
|
||||
setColumns((prevColumns: TTableColumn[]) =>
|
||||
prevColumns.map((item, index) =>
|
||||
index === columnIndex ? { ...item, enable: !item.enable } : item,
|
||||
),
|
||||
);
|
||||
|
||||
const tableColumns = columns.map((c) => c.enable && c.key);
|
||||
localStorage.setItem(`${TABLE_COLUMNS}=${userId}`, tableColumns.toString());
|
||||
}
|
||||
|
||||
const defaultColumns: TTableColumn[] = [
|
||||
{
|
||||
key: "Name",
|
||||
title: t("Common:Name"),
|
||||
resizable: true,
|
||||
enable: true,
|
||||
default: true,
|
||||
active: true,
|
||||
minWidth: 180,
|
||||
checkbox: {
|
||||
value: isChecked,
|
||||
isIndeterminate,
|
||||
onChange: toggleAll,
|
||||
},
|
||||
onChange: onColumnChange,
|
||||
},
|
||||
{
|
||||
key: "Email",
|
||||
title: t("Common:Email"),
|
||||
enable: true,
|
||||
resizable: true,
|
||||
onChange: onColumnChange,
|
||||
},
|
||||
{
|
||||
key: "Duplicate",
|
||||
title: t("Settings:DuplicateNoun"),
|
||||
enable: true,
|
||||
resizable: true,
|
||||
onChange: onColumnChange,
|
||||
},
|
||||
];
|
||||
|
||||
const stub = () => {};
|
||||
|
||||
useEffect(() => {
|
||||
setColumns(getColumns(defaultColumns, userId));
|
||||
}, [isIndeterminate, isChecked]);
|
||||
|
||||
return (
|
||||
<TableHeader
|
||||
containerRef={tableRef as { current: HTMLDivElement }}
|
||||
columns={columns}
|
||||
columnStorageName={columnStorageName}
|
||||
columnInfoPanelStorageName={columnInfoPanelStorageName}
|
||||
sectionWidth={sectionWidth}
|
||||
showSettings={false}
|
||||
useReactWindow
|
||||
infoPanelVisible={false}
|
||||
onClick={stub}
|
||||
sortBy=""
|
||||
sorted={false}
|
||||
resetColumnsSize={false}
|
||||
isLengthenHeader={false}
|
||||
sortingVisible={false}
|
||||
setHideColumns={stub}
|
||||
tagRef={null}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default UsersTableHeader;
|
@ -0,0 +1,99 @@
|
||||
// (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 { TableRow, TableCell } from "@docspace/shared/components/table";
|
||||
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { Checkbox } from "@docspace/shared/components/checkbox";
|
||||
import styled from "styled-components";
|
||||
import { UsersTableRowProps } from "../../../../types";
|
||||
|
||||
const StyledTableRow = styled(TableRow)`
|
||||
.table-container_cell {
|
||||
padding-right: 30px;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.username {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: ${(props) => props.theme.client.settings.migration.subtitleColor};
|
||||
}
|
||||
|
||||
.user-email {
|
||||
margin-right: 5px;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: ${(props) =>
|
||||
props.theme.client.settings.migration.tableRowTextColor};
|
||||
}
|
||||
|
||||
.not-existing {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: ${(props) =>
|
||||
props.theme.client.settings.migration.tableRowTextColor};
|
||||
}
|
||||
|
||||
.user-existing {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: ${(props) =>
|
||||
props.theme.client.settings.migration.existingTextColor};
|
||||
}
|
||||
`;
|
||||
|
||||
const NOT_EXIST = "—";
|
||||
|
||||
const UsersTableRow = (props: UsersTableRowProps) => {
|
||||
const { t, displayName, email, isDuplicate, isChecked, toggleAccount } =
|
||||
props;
|
||||
|
||||
return (
|
||||
<StyledTableRow onClick={toggleAccount}>
|
||||
<TableCell className="checkboxWrapper" forwardedRef={null} style={{}}>
|
||||
<Checkbox isChecked={isChecked} onChange={toggleAccount} />
|
||||
<Text className="username">{displayName}</Text>
|
||||
</TableCell>
|
||||
|
||||
<TableCell forwardedRef={null} style={{}} className="">
|
||||
<Text className="user-email">{email}</Text>
|
||||
</TableCell>
|
||||
|
||||
<TableCell forwardedRef={null} style={{}} className="">
|
||||
{isDuplicate ? (
|
||||
<Text className="user-existing">
|
||||
{t("Settings:AccountAlreadyExists")}
|
||||
</Text>
|
||||
) : (
|
||||
<Text className="not-existing">{NOT_EXIST}</Text>
|
||||
)}
|
||||
</TableCell>
|
||||
</StyledTableRow>
|
||||
);
|
||||
};
|
||||
|
||||
export default UsersTableRow;
|
@ -0,0 +1,185 @@
|
||||
// (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 { useRef } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
||||
import { EmptyScreenContainer } from "@docspace/shared/components/empty-screen-container";
|
||||
import { IconButton } from "@docspace/shared/components/icon-button";
|
||||
import { Link, LinkType } from "@docspace/shared/components/link";
|
||||
import { Box } from "@docspace/shared/components/box";
|
||||
import { TableBody } from "@docspace/shared/components/table";
|
||||
import EmptyScreenUserReactSvgUrl from "PUBLIC_DIR/images/empty_screen_user.react.svg?url";
|
||||
import ClearEmptyFilterSvgUrl from "PUBLIC_DIR/images/clear.empty.filter.svg?url";
|
||||
import { TEnhancedMigrationUser } from "@docspace/shared/api/settings/types";
|
||||
import UsersTableRow from "./UsersTableRow";
|
||||
import UsersTableHeader from "./UsersTableHeader";
|
||||
import { StyledTableContainer } from "../../../../StyledDataImport";
|
||||
import { InjectedTableViewProps, TableViewProps } from "../../../../types";
|
||||
|
||||
const TABLE_VERSION = "6";
|
||||
const COLUMNS_SIZE = `nextcloudSecondColumnsSize_ver-${TABLE_VERSION}`;
|
||||
const INFO_PANEL_COLUMNS_SIZE = `infoPanelNextcloudSecondColumnsSize_ver-${TABLE_VERSION}`;
|
||||
|
||||
const checkedAccountType = "withEmail";
|
||||
|
||||
const TableView = (props: TableViewProps) => {
|
||||
const {
|
||||
t,
|
||||
withEmailUsers,
|
||||
userId,
|
||||
sectionWidth,
|
||||
accountsData,
|
||||
checkedUsers,
|
||||
toggleAccount,
|
||||
toggleAllAccounts,
|
||||
isAccountChecked,
|
||||
setSearchValue,
|
||||
} = props as InjectedTableViewProps;
|
||||
const tableRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const toggleAll = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
toggleAllAccounts(e.target.checked, withEmailUsers, checkedAccountType);
|
||||
|
||||
const handleToggle = (
|
||||
e: React.ChangeEvent<HTMLInputElement>,
|
||||
user: TEnhancedMigrationUser,
|
||||
) => {
|
||||
e.stopPropagation();
|
||||
toggleAccount(user, checkedAccountType);
|
||||
};
|
||||
|
||||
const onClearFilter = () => {
|
||||
setSearchValue("");
|
||||
};
|
||||
|
||||
const isIndeterminate =
|
||||
checkedUsers.withEmail.length > 0 &&
|
||||
checkedUsers.withEmail.length !== withEmailUsers.length;
|
||||
|
||||
const columnStorageName = `${COLUMNS_SIZE}=${userId}`;
|
||||
const columnInfoPanelStorageName = `${INFO_PANEL_COLUMNS_SIZE}=${userId}`;
|
||||
|
||||
const stub: () => Promise<void> = () =>
|
||||
new Promise((resolve) => {
|
||||
resolve();
|
||||
});
|
||||
|
||||
return (
|
||||
<StyledTableContainer forwardedRef={tableRef} useReactWindow>
|
||||
{accountsData.length > 0 ? (
|
||||
<>
|
||||
<UsersTableHeader
|
||||
t={t}
|
||||
sectionWidth={sectionWidth!}
|
||||
tableRef={tableRef}
|
||||
userId={userId}
|
||||
columnStorageName={columnStorageName}
|
||||
columnInfoPanelStorageName={columnInfoPanelStorageName}
|
||||
isIndeterminate={isIndeterminate}
|
||||
isChecked={checkedUsers.withEmail.length === withEmailUsers.length}
|
||||
toggleAll={toggleAll}
|
||||
/>
|
||||
<TableBody
|
||||
itemHeight={49}
|
||||
useReactWindow
|
||||
infoPanelVisible={false}
|
||||
columnStorageName={columnStorageName}
|
||||
columnInfoPanelStorageName={columnInfoPanelStorageName}
|
||||
filesLength={accountsData.length}
|
||||
hasMoreFiles={false}
|
||||
itemCount={accountsData.length}
|
||||
fetchMoreFiles={stub}
|
||||
onScroll={stub}
|
||||
>
|
||||
{accountsData.map((data) => (
|
||||
<UsersTableRow
|
||||
t={t}
|
||||
key={data.key}
|
||||
displayName={data.displayName}
|
||||
email={data.email}
|
||||
isDuplicate={data.isDuplicate}
|
||||
isChecked={isAccountChecked(data.key, checkedAccountType)}
|
||||
toggleAccount={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
handleToggle(e, data)
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</TableBody>
|
||||
</>
|
||||
) : (
|
||||
<EmptyScreenContainer
|
||||
imageSrc={EmptyScreenUserReactSvgUrl}
|
||||
imageAlt="Empty Screen user image"
|
||||
headerText={t("Common:NotFoundUsers")}
|
||||
descriptionText={t("Common:NotFoundUsersDescription")}
|
||||
buttons={
|
||||
<Box displayProp="flex" alignItems="center">
|
||||
<IconButton
|
||||
className="clear-icon"
|
||||
isFill
|
||||
size={12}
|
||||
onClick={onClearFilter}
|
||||
iconName={ClearEmptyFilterSvgUrl}
|
||||
/>
|
||||
<Link
|
||||
type={LinkType.action}
|
||||
isHovered
|
||||
fontWeight="600"
|
||||
onClick={onClearFilter}
|
||||
>
|
||||
{t("Common:ClearFilter")}
|
||||
</Link>
|
||||
</Box>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</StyledTableContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject<TStore>(({ userStore, importAccountsStore }) => {
|
||||
const userId = userStore.user?.id;
|
||||
|
||||
const {
|
||||
checkedUsers,
|
||||
withEmailUsers,
|
||||
toggleAccount,
|
||||
toggleAllAccounts,
|
||||
isAccountChecked,
|
||||
setSearchValue,
|
||||
} = importAccountsStore;
|
||||
|
||||
return {
|
||||
userId,
|
||||
checkedUsers,
|
||||
withEmailUsers,
|
||||
toggleAccount,
|
||||
toggleAllAccounts,
|
||||
isAccountChecked,
|
||||
setSearchValue,
|
||||
};
|
||||
})(observer(TableView));
|
@ -0,0 +1,64 @@
|
||||
// (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 { inject, observer } from "mobx-react";
|
||||
import { Consumer } from "@docspace/shared/utils/context";
|
||||
|
||||
import TableView from "./TableView";
|
||||
import RowView from "./RowView";
|
||||
|
||||
import { AccountsTableProps, InjectedAccountsTableProps } from "../../../types";
|
||||
|
||||
const AccountsTable = (props: AccountsTableProps) => {
|
||||
const { t, viewAs, accountsData } = props as InjectedAccountsTableProps;
|
||||
|
||||
return (
|
||||
<Consumer>
|
||||
{(context) =>
|
||||
viewAs === "table" ? (
|
||||
<TableView
|
||||
t={t}
|
||||
sectionWidth={context.sectionWidth}
|
||||
accountsData={accountsData}
|
||||
/>
|
||||
) : (
|
||||
<RowView
|
||||
t={t}
|
||||
sectionWidth={context.sectionWidth}
|
||||
accountsData={accountsData}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</Consumer>
|
||||
);
|
||||
};
|
||||
export default inject<TStore>(({ setup }) => {
|
||||
const { viewAs } = setup;
|
||||
|
||||
return {
|
||||
viewAs,
|
||||
};
|
||||
})(observer(AccountsTable));
|
@ -0,0 +1,194 @@
|
||||
// (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 { useEffect, useState } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
||||
import { SaveCancelButtons } from "@docspace/shared/components/save-cancel-buttons";
|
||||
import { SearchInput } from "@docspace/shared/components/search-input";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
|
||||
import { InputSize } from "@docspace/shared/components/text-input";
|
||||
import AccountsTable from "./AccountsTable";
|
||||
import AccountsPaging from "../../sub-components/AccountsPaging";
|
||||
|
||||
import UsersInfoBlock from "../../sub-components/UsersInfoBlock";
|
||||
import { Wrapper } from "../../StyledDataImport";
|
||||
|
||||
import { parseQuota } from "../../utils";
|
||||
|
||||
import {
|
||||
SelectUsersStepProps,
|
||||
InjectedSelectUsersStepProps,
|
||||
} from "../../types";
|
||||
|
||||
const SelectUsersStep = (props: SelectUsersStepProps) => {
|
||||
const {
|
||||
t,
|
||||
incrementStep,
|
||||
decrementStep,
|
||||
withEmailUsers,
|
||||
searchValue,
|
||||
setSearchValue,
|
||||
checkedUsers,
|
||||
users,
|
||||
|
||||
quotaCharacteristics,
|
||||
} = props as InjectedSelectUsersStepProps;
|
||||
|
||||
const [dataPortion, setDataPortion] = useState(withEmailUsers.slice(0, 25));
|
||||
const [quota, setQuota] = useState<{
|
||||
used: number;
|
||||
max: number | null;
|
||||
}>({
|
||||
used: 0,
|
||||
max: 0,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setSearchValue("");
|
||||
setQuota(parseQuota(quotaCharacteristics[1]));
|
||||
}, [quotaCharacteristics, setSearchValue]);
|
||||
|
||||
const handleDataChange = (leftBoundary: number, rightBoundary: number) => {
|
||||
setDataPortion(withEmailUsers.slice(leftBoundary, rightBoundary));
|
||||
};
|
||||
|
||||
const onChangeInput = (value: string) => {
|
||||
setSearchValue(value);
|
||||
};
|
||||
|
||||
const onClearSearchInput = () => {
|
||||
setSearchValue("");
|
||||
};
|
||||
|
||||
const filteredAccounts = dataPortion.filter(
|
||||
(data) =>
|
||||
data.firstName?.toLowerCase().startsWith(searchValue.toLowerCase()) ||
|
||||
data.displayName?.toLowerCase().startsWith(searchValue.toLowerCase()) ||
|
||||
data.email?.toLowerCase().startsWith(searchValue.toLowerCase()),
|
||||
);
|
||||
|
||||
const numberOfSelectedUsers =
|
||||
checkedUsers.withEmail.length + checkedUsers.withoutEmail.length;
|
||||
|
||||
const totalUsedUsers =
|
||||
quota.used +
|
||||
checkedUsers.withEmail.filter((user) => !user.isDuplicate).length +
|
||||
checkedUsers.withoutEmail.length;
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
{withEmailUsers.length > 0 ? (
|
||||
<>
|
||||
<SaveCancelButtons
|
||||
className="save-cancel-buttons"
|
||||
onSaveClick={incrementStep}
|
||||
onCancelClick={decrementStep}
|
||||
saveButtonLabel={t("Settings:NextStep")}
|
||||
cancelButtonLabel={t("Common:Back")}
|
||||
showReminder
|
||||
displaySettings
|
||||
/>
|
||||
|
||||
{quota.max && (
|
||||
<UsersInfoBlock
|
||||
t={t}
|
||||
totalUsedUsers={totalUsedUsers}
|
||||
selectedUsers={numberOfSelectedUsers}
|
||||
totalUsers={withEmailUsers.length + users.withoutEmail.length}
|
||||
totalLicenceLimit={quota.max}
|
||||
/>
|
||||
)}
|
||||
|
||||
<SearchInput
|
||||
id="search-users-input"
|
||||
placeholder={t("Common:Search")}
|
||||
value={searchValue}
|
||||
onChange={onChangeInput}
|
||||
refreshTimeout={100}
|
||||
onClearSearch={onClearSearchInput}
|
||||
size={InputSize.base}
|
||||
/>
|
||||
|
||||
<AccountsTable t={t} accountsData={filteredAccounts} />
|
||||
|
||||
{withEmailUsers.length > 25 && filteredAccounts.length > 0 && (
|
||||
<AccountsPaging
|
||||
t={t}
|
||||
numberOfItems={withEmailUsers.length}
|
||||
setDataPortion={handleDataChange}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<Text fontWeight={600} lineHeight="20px" className="mb-17">
|
||||
{t("Settings:AddEmailsWarning")}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{filteredAccounts.length > 0 && (
|
||||
<SaveCancelButtons
|
||||
className="save-cancel-buttons"
|
||||
onSaveClick={incrementStep}
|
||||
onCancelClick={decrementStep}
|
||||
saveButtonLabel={t("Settings:NextStep")}
|
||||
cancelButtonLabel={t("Common:Back")}
|
||||
showReminder
|
||||
displaySettings
|
||||
/>
|
||||
)}
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject<TStore>(({ importAccountsStore, currentQuotaStore }) => {
|
||||
const {
|
||||
incrementStep,
|
||||
decrementStep,
|
||||
users,
|
||||
withEmailUsers,
|
||||
searchValue,
|
||||
setSearchValue,
|
||||
cancelMigration,
|
||||
checkedUsers,
|
||||
} = importAccountsStore;
|
||||
|
||||
const { quotaCharacteristics } = currentQuotaStore;
|
||||
|
||||
return {
|
||||
incrementStep,
|
||||
decrementStep,
|
||||
users,
|
||||
withEmailUsers,
|
||||
searchValue,
|
||||
setSearchValue,
|
||||
cancelMigration,
|
||||
checkedUsers,
|
||||
|
||||
quotaCharacteristics,
|
||||
};
|
||||
})(observer(SelectUsersStep));
|
Loading…
Reference in New Issue
Block a user