rewrited in typescript

This commit is contained in:
Elyor Djalilov 2024-07-10 16:59:43 +05:00
parent 25ea694d18
commit d4eadbddc3
44 changed files with 1770 additions and 768 deletions

View File

@ -62,9 +62,11 @@ export default function withContent(WrappedContent) {
const onContextClick = useCallback(
(item, isSingleMenu) => {
isSingleMenu
? singleContextMenuAction(item)
: multipleContextMenuAction(item);
if (isSingleMenu) {
setTimeout(() => singleContextMenuAction(item), 0);
} else {
setTimeout(() => multipleContextMenuAction(item), 0);
}
},
[singleContextMenuAction, multipleContextMenuAction],
);

View File

@ -41,7 +41,6 @@ import {
InvitePanel,
EditLinkPanel,
EmbeddingPanel,
UserSessionsPanel,
} from "../panels";
import {
ConnectDialog,
@ -78,6 +77,7 @@ import ChangeRoomOwnerPanel from "../panels/ChangeRoomOwnerPanel";
import { CreatedPDFFormDialog } from "../dialogs/CreatedPDFFormDialog";
import { PDFFormEditingDialog } from "../dialogs/PDFFormEditingDialog";
import { SharePDFFormDialog } from "../dialogs/SharePDFFormDialog";
import { SessionsPanel } from "../panels/UserSessionsPanel";
const Panels = (props) => {
const {
@ -357,7 +357,7 @@ const Panels = (props) => {
<SharePDFFormDialog key="share-pdf-form-dialog" {...sharePDFForm} />
),
userSessionsPanelVisible && <UserSessionsPanel key="user-sessions-panel" />,
userSessionsPanelVisible && <SessionsPanel key="user-sessions-panel" />,
];
};

View File

@ -0,0 +1,107 @@
// (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 {
ModalDialog,
ModalDialogType,
} from "@docspace/shared/components/modal-dialog";
import { Button, ButtonSize } from "@docspace/shared/components/button";
import { toastr } from "@docspace/shared/components/toast";
import { EmployeeStatus } from "@docspace/shared/enums";
import { TData } from "@docspace/shared/components/toast/Toast.type";
import { DisableUserDialogProps } from "./DisableUserDialog.types";
import ModalDialogContainer from "../ModalDialogContainer";
export const DisableUserDialog = ({
t,
visible,
onClose,
userIds,
isLoading,
fetchData,
updateUserStatus,
clearSelection,
}: DisableUserDialogProps) => {
const onlyOneUser = userIds.length === 1;
let headerText = "";
let bodyText = "";
headerText = onlyOneUser
? t("ChangeUserStatusDialog:DisableUser")
: t("ChangeUserStatusDialog:DisableUsers");
bodyText = onlyOneUser
? t("ChangeUserStatusDialog:DisableUserDescription")
: t("ChangeUserStatusDialog:DisableUsersDescription");
bodyText += t("ChangeUserStatusDialog:DisableGeneralDescription");
const onClickDisableUser = () => {
try {
updateUserStatus(EmployeeStatus.Disabled, userIds);
fetchData();
toastr.success(t("PeopleTranslations:SuccessChangeUserStatus"));
} catch (error) {
toastr.error(error as TData);
} finally {
clearSelection();
onClose();
}
};
return (
<ModalDialogContainer
visible={visible}
onClose={onClose}
displayType={ModalDialogType.modal}
>
<ModalDialog.Header>{headerText}</ModalDialog.Header>
<ModalDialog.Body>{bodyText}</ModalDialog.Body>
<ModalDialog.Footer>
<Button
key="DisableBtn"
label={t("Common:DisableUserButton")}
size={ButtonSize.normal}
scale
primary
onClick={onClickDisableUser}
isLoading={isLoading}
/>
<Button
key="CloseBtn"
label={t("Common:CancelButton")}
size={ButtonSize.normal}
scale
onClick={onClose}
isDisabled={isLoading}
/>
</ModalDialog.Footer>
</ModalDialogContainer>
);
};

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 { TTranslation } from "@docspace/shared/types";
export interface DisableUserDialogProps {
t: TTranslation;
visible: boolean;
onClose: () => void;
userIds: string[];
isLoading: boolean;
fetchData: () => void;
updateUserStatus: (status: string | number, userIds: string[]) => void;
clearSelection: () => void;
}

View File

@ -1,77 +0,0 @@
import { ModalDialog } from "@docspace/shared/components/modal-dialog";
import { Button } from "@docspace/shared/components/button";
import { toastr } from "@docspace/shared/components/toast";
import { EmployeeStatus } from "@docspace/shared/enums";
import ModalDialogContainer from "../ModalDialogContainer";
const DisableUserDialog = ({
t,
visible,
onClose,
userIds,
isLoading,
fetchData,
updateUserStatus,
clearSelection,
}) => {
const onlyOneUser = userIds.length === 1;
let headerText = "";
let bodyText = "";
headerText = onlyOneUser
? t("ChangeUserStatusDialog:DisableUser")
: t("ChangeUserStatusDialog:DisableUsers");
bodyText = onlyOneUser
? t("ChangeUserStatusDialog:DisableUserDescription")
: t("ChangeUserStatusDialog:DisableUsersDescription");
bodyText = bodyText + t("ChangeUserStatusDialog:DisableGeneralDescription");
const onClickDisableUser = async () => {
try {
await updateUserStatus(EmployeeStatus.Disabled, userIds);
await fetchData();
toastr.success(t("PeopleTranslations:SuccessChangeUserStatus"));
} catch (error) {
toastr.error(error);
} finally {
clearSelection();
onClose();
}
};
return (
<ModalDialogContainer
visible={visible}
onClose={onClose}
displayType="modal"
>
<ModalDialog.Header>{headerText}</ModalDialog.Header>
<ModalDialog.Body>{bodyText}</ModalDialog.Body>
<ModalDialog.Footer>
<Button
key="DisableBtn"
label={t("Common:DisableUserButton")}
size="normal"
scale
primary={true}
onClick={onClickDisableUser}
isLoading={isLoading}
/>
<Button
key="CloseBtn"
label={t("Common:CancelButton")}
size="normal"
scale
onClick={onClose}
isDisabled={isLoading}
/>
</ModalDialog.Footer>
</ModalDialogContainer>
);
};
export default DisableUserDialog;

View File

@ -0,0 +1,27 @@
// (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
export { DisableUserDialog } from "./DisableUserDialog";

View File

@ -25,15 +25,20 @@
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
import { useState } from "react";
import { ModalDialog } from "@docspace/shared/components/modal-dialog";
import {
ModalDialog,
ModalDialogType,
} from "@docspace/shared/components/modal-dialog";
import { Checkbox } from "@docspace/shared/components/checkbox";
import { Button } from "@docspace/shared/components/button";
import { Button, ButtonSize } from "@docspace/shared/components/button";
import { Text } from "@docspace/shared/components/text";
import { toastr } from "@docspace/shared/components/toast";
import { TData } from "@docspace/shared/components/toast/Toast.type";
import { LogoutAllSessionDialogProps } from "./LogoutAllSessionDialog.types";
import ModalDialogContainer from "../ModalDialogContainer";
const LogoutAllSessionDialog = ({
export const LogoutAllSessionDialog = ({
t,
visible,
isLoading,
@ -49,13 +54,11 @@ const LogoutAllSessionDialog = ({
onLogoutAllUsers,
onLogoutAllSessions,
onLogoutAllExceptThis,
}) => {
}: LogoutAllSessionDialogProps) => {
const [isChecked, setIsChecked] = useState(false);
const isProfile = location.pathname.includes("/profile");
const isProfile = window.location.pathname.includes("/profile");
const onChangeCheckbox = () => {
setIsChecked((prev) => !prev);
};
const onChangeCheckbox = () => setIsChecked((prev) => !prev);
const onClickLogout = () => {
const selectionId = selection[0]?.connections[0]?.id;
@ -64,15 +67,17 @@ const LogoutAllSessionDialog = ({
try {
if (!isChecked) {
isSeveralSelection
? onLogoutAllUsers(t, userIds)
: onLogoutAllSessions(t, userIds, displayName);
if (isSeveralSelection) {
onLogoutAllUsers(t, userIds);
} else {
onLogoutAllSessions(t, userIds, displayName);
}
onClosePanel();
} else {
onLogoutAllExceptThis(t, exceptId, displayName);
}
} catch (error) {
toastr.error(error);
toastr.error(error as TData);
} finally {
onClose();
}
@ -81,12 +86,12 @@ const LogoutAllSessionDialog = ({
const onClickRemove = () => {
try {
if (isChecked) {
onRemoveAllSessions();
onRemoveAllSessions?.();
} else {
onRemoveAllExceptThis();
onRemoveAllExceptThis?.();
}
} catch (error) {
toastr.error(error);
toastr.error(error as TData);
}
};
@ -113,7 +118,7 @@ const LogoutAllSessionDialog = ({
<ModalDialogContainer
visible={visible}
onClose={onClose}
displayType="modal"
displayType={ModalDialogType.modal}
>
<ModalDialog.Header>
{t("Profile:LogoutAllActiveConnections")}
@ -127,9 +132,9 @@ const LogoutAllSessionDialog = ({
className="logout"
key="Logout"
label={t("Common:Logout")}
size="normal"
size={ButtonSize.normal}
scale
primary={true}
primary
onClick={isProfile ? onClickRemove : onClickLogout}
isLoading={isLoading}
/>
@ -137,7 +142,7 @@ const LogoutAllSessionDialog = ({
className="cancel-button"
key="CloseBtn"
label={t("Common:CancelButton")}
size="normal"
size={ButtonSize.normal}
scale
onClick={onClose}
isDisabled={isLoading}
@ -146,5 +151,3 @@ const LogoutAllSessionDialog = ({
</ModalDialogContainer>
);
};
export default LogoutAllSessionDialog;

View File

@ -0,0 +1,54 @@
// (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 { TTranslation } from "@docspace/shared/types";
import { IAllSessions } from "SRC_DIR/pages/PortalSettings/categories/security/sessions/SecuritySessions.types";
export interface LogoutAllSessionDialogProps {
t: TTranslation;
visible: boolean;
isLoading: boolean;
userIds: string[];
displayName: string;
selection: IAllSessions[];
bufferSelection: IAllSessions | undefined;
isSeveralSelection: boolean;
onClose: () => void;
onClosePanel: () => void;
onRemoveAllSessions?: () => Promise<void>;
onRemoveAllExceptThis?: () => Promise<void>;
onLogoutAllUsers: (t: TTranslation, userIds: string[]) => void;
onLogoutAllSessions: (
t: TTranslation,
userIds: string[],
displayName: string,
) => void;
onLogoutAllExceptThis: (
t: TTranslation,
exceptId: number | undefined,
displayName: string,
) => void;
}

View File

@ -0,0 +1,27 @@
// (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
export { LogoutAllSessionDialog } from "./LogoutAllSessionDialog";

View File

@ -24,19 +24,23 @@
// 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 { Button } from "@docspace/shared/components/button";
import { ModalDialog } from "@docspace/shared/components/modal-dialog";
import {
ModalDialog,
ModalDialogType,
} from "@docspace/shared/components/modal-dialog";
import { Button, ButtonSize } from "@docspace/shared/components/button";
import { LogoutSessionDialogProps } from "./LogoutSessionDialog.types";
import ModalDialogContainer from "../ModalDialogContainer";
const LogoutSessionDialog = ({
export const LogoutSessionDialog = ({
t,
data,
visible,
data,
isLoading,
onClose,
onRemoveSession,
isLoading,
}) => {
}: LogoutSessionDialogProps) => {
const onRemoveClick = () => {
onRemoveSession(t, data.id);
onClose();
@ -46,7 +50,7 @@ const LogoutSessionDialog = ({
<ModalDialogContainer
visible={visible}
onClose={onClose}
displayType="modal"
displayType={ModalDialogType.modal}
>
<ModalDialog.Header>
{t("Profile:LogoutActiveConnection")}
@ -61,16 +65,16 @@ const LogoutSessionDialog = ({
<Button
key="Logout"
label={t("Common:Logout")}
size="normal"
size={ButtonSize.normal}
scale
primary={true}
primary
onClick={onRemoveClick}
isLoading={isLoading}
/>
<Button
key="CloseBtn"
label={t("Common:CancelButton")}
size="normal"
size={ButtonSize.normal}
scale
onClick={onClose}
isDisabled={isLoading}
@ -79,5 +83,3 @@ const LogoutSessionDialog = ({
</ModalDialogContainer>
);
};
export default LogoutSessionDialog;

View File

@ -0,0 +1,37 @@
// (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 { TTranslation } from "@docspace/shared/types";
import { ISessions } from "SRC_DIR/pages/PortalSettings/categories/security/sessions/SecuritySessions.types";
export interface LogoutSessionDialogProps {
t: TTranslation;
data: ISessions;
visible: boolean;
onClose: () => void;
onRemoveSession: (t: TTranslation, id: number) => void;
isLoading: boolean;
}

View File

@ -0,0 +1,27 @@
// (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
export { LogoutSessionDialog } from "./LogoutSessionDialog";

View File

@ -50,8 +50,6 @@ import ChangeNameDialog from "./ChangeNameDialog";
import AvatarEditorDialog from "./AvatarEditorDialog";
import DeletePortalDialog from "./DeletePortalDialog";
import InviteUsersWarningDialog from "./InviteUsersWarningDialog";
import LogoutSessionDialog from "./LogoutSessionDialog";
import LogoutAllSessionDialog from "./LogoutAllSessionDialog";
import CreateRoomConfirmDialog from "./CreateRoomConfirmDialog";
import PortalRenamingDialog from "./PortalRenamingDialog";
import DataReassignmentDialog from "./DataReassignmentDialog";
@ -69,7 +67,6 @@ import ShareFolderDialog from "./ShareFolderDialog";
import EditGroupMembersDialog from "./EditGroupMembersDialog";
import ChangeStorageQuotaDialog from "./ChangeStorageQuotaDialog";
import DeleteGroupDialog from "./DeleteGroupDialog";
import DisableUserDialog from "./DisableUserDialog";
export {
EmptyTrashDialog,
@ -98,9 +95,7 @@ export {
ChangeNameDialog,
AvatarEditorDialog,
DeletePortalDialog,
LogoutSessionDialog,
InviteUsersWarningDialog,
LogoutAllSessionDialog,
PortalRenamingDialog,
DataReassignmentDialog,
SubmitToFormGallery,
@ -117,5 +112,4 @@ export {
ChangeQuotaDialog,
ChangeStorageQuotaDialog,
DeleteGroupDialog,
DisableUserDialog,
};

View File

@ -1,84 +0,0 @@
import { observer, inject } from "mobx-react";
import { mobile } from "@docspace/shared/utils";
import { Text } from "@docspace/shared/components/text";
import { Button } from "@docspace/shared/components/button";
import { EmptyScreenContainer } from "@docspace/shared/components/empty-screen-container";
import styled from "styled-components";
import RowWrapper from "./sub-components";
import EmptyScreenSessionsReactSvgUrl from "PUBLIC_DIR/images/empty_screen_from_sessions.svg?url";
const Wrapper = styled.div`
padding: 20px 20px 12px;
.empty-screen-container {
width: auto;
padding-top: 60px;
@media ${mobile} {
padding-top: 30px;
}
}
.subtitle {
font-size: 14px;
font-weight: 600;
margin-bottom: 12px;
}
.desciption {
color: ${(props) => props.theme.profile.activeSessions.subtitleColor};
margin-bottom: 20px;
}
`;
const AllSessionsBlock = (props) => {
const { t, isLoading, items, onClickLogoutAllExceptThis } = props;
const { displayName } = items;
const exceptId = items.connections[0]?.id;
const sessions = items.sessions || items.connections;
const filteredSessions = sessions
.filter((session) => session.status === "offline")
.reverse();
return (
<>
<Wrapper>
<Text className="subtitle">{t("Profile:AllSessions")}</Text>
<Text className="desciption">{t("Profile:PanelDescription")}</Text>
{filteredSessions.length > 0 ? (
<Button
label={t("Profile:LogoutFromAllSessions")}
size="small"
onClick={() => onClickLogoutAllExceptThis(t, exceptId, displayName)}
scale={true}
isLoading={isLoading}
/>
) : (
<EmptyScreenContainer
imageSrc={EmptyScreenSessionsReactSvgUrl}
className="empty-screen-container"
imageAlt="Empty Screen Sessions image"
headerText={t("Settings:NoSessionsHere")}
/>
)}
</Wrapper>
<RowWrapper t={t} sessions={filteredSessions} />
</>
);
};
export default inject(({ peopleStore }) => {
const { getItems, isLoading, fetchData, onClickLogoutAllExceptThis } =
peopleStore.selectionStore;
return {
items: getItems,
isLoading,
fetchData,
onClickLogoutAllExceptThis,
};
})(observer(AllSessionsBlock));

View File

@ -0,0 +1,118 @@
// (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 { observer, inject } from "mobx-react";
import { mobile } from "@docspace/shared/utils";
import { Text } from "@docspace/shared/components/text";
import { Button, ButtonSize } from "@docspace/shared/components/button";
import { EmptyScreenContainer } from "@docspace/shared/components/empty-screen-container";
import styled from "styled-components";
import type SelectionPeopleStore from "SRC_DIR/store/SelectionPeopleStore";
import EmptyScreenSessionsReactSvgUrl from "PUBLIC_DIR/images/empty_screen_from_sessions.svg?url";
import { IAllSessions } from "SRC_DIR/pages/PortalSettings/categories/security/sessions/SecuritySessions.types";
import { AllSessionsBlockProps } from "./UserSessionsPanel.types";
import RowWrapper from "./sub-components";
const Wrapper = styled.div`
padding: 20px 20px 12px;
.empty-screen-container {
width: auto;
padding-top: 60px;
@media ${mobile} {
padding-top: 30px;
}
}
.subtitle {
font-size: 14px;
font-weight: 600;
margin-bottom: 12px;
}
.desciption {
color: ${(props) => props.theme.profile.activeSessions.subtitleColor};
margin-bottom: 20px;
}
`;
const AllSessionsBlock = (props: AllSessionsBlockProps) => {
const {
t,
isLoading,
items = {} as IAllSessions,
onClickLogoutAllExceptThis = () => {},
} = props;
const { displayName } = items;
const exceptId = items.connections[0]?.id;
const sessions = items.sessions || items.connections;
const filteredSessions = sessions
.filter((session) => session.status === "offline")
.reverse();
return (
<>
<Wrapper>
<Text className="subtitle">{t("Profile:AllSessions")}</Text>
<Text className="desciption">{t("Profile:PanelDescription")}</Text>
{filteredSessions.length > 0 ? (
<Button
label={t("Profile:LogoutFromAllSessions")}
size={ButtonSize.small}
onClick={() => onClickLogoutAllExceptThis(t, exceptId, displayName)}
scale
isLoading={isLoading}
/>
) : (
<EmptyScreenContainer
imageSrc={EmptyScreenSessionsReactSvgUrl}
className="empty-screen-container"
imageAlt="Empty Screen Sessions image"
headerText={t("Settings:NoSessionsHere")}
/>
)}
</Wrapper>
<RowWrapper t={t} sessions={filteredSessions} sectionWidth={0} />
</>
);
};
export default inject<TStore>(({ peopleStore }) => {
const { getItems, isLoading, onClickLogoutAllExceptThis } =
peopleStore.selectionStore as unknown as SelectionPeopleStore;
return {
items: getItems,
isLoading,
onClickLogoutAllExceptThis,
};
})(observer(AllSessionsBlock));

View File

@ -1,14 +1,50 @@
// (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 { observer, inject } from "mobx-react";
import { Avatar } from "@docspace/shared/components/avatar";
import {
Avatar,
AvatarSize,
AvatarRole,
} from "@docspace/shared/components/avatar";
import { Box } from "@docspace/shared/components/box";
import { Text } from "@docspace/shared/components/text";
import { ContextMenuButton } from "@docspace/shared/components/context-menu-button";
import {
ContextMenuButton,
ContextMenuButtonDisplayType,
} from "@docspace/shared/components/context-menu-button";
import { PRODUCT_NAME } from "@docspace/shared/constants";
import styled, { css } from "styled-components";
import LogoutReactSvgUrl from "PUBLIC_DIR/images/logout.react.svg?url";
import RemoveSvgUrl from "PUBLIC_DIR/images/remove.session.svg?url";
import type SelectionPeopleStore from "SRC_DIR/store/SelectionPeopleStore";
import { IAllSessions } from "SRC_DIR/pages/PortalSettings/categories/security/sessions/SecuritySessions.types";
import { LastSessionBlockProps } from "./UserSessionsPanel.types";
const StyledUserInfoBlock = styled.div`
display: flex;
align-items: center;
@ -96,15 +132,15 @@ const StyledLastSessionBlock = styled.div`
}
`;
const LastSessionBlock = (props) => {
const LastSessionBlock = (props: LastSessionBlockProps) => {
const {
t,
isMe,
items,
setDisplayName,
setDisableDialogVisible,
setLogoutAllDialogVisible,
getFromDateAgo,
items = {} as IAllSessions,
setDisplayName = () => {},
setDisableDialogVisible = () => {},
setLogoutAllDialogVisible = () => {},
getFromDateAgo = () => {},
} = props;
const {
@ -123,7 +159,7 @@ const LastSessionBlock = (props) => {
const isOnline = fromDateAgo === "online";
const { platform, browser, ip, city, country } = connections[0] ?? {};
const getUserType = () => {
const getUserType = (): string => {
if (isOwner) return t("Common:Owner");
if (isAdmin) return t("Common:PortalAdmin", { productName: PRODUCT_NAME });
if (isRoomAdmin) return t("Common:RoomAdmin");
@ -131,7 +167,11 @@ const LastSessionBlock = (props) => {
return t("Common:User");
};
const role = isOwner ? "owner" : isAdmin ? "admin" : null;
const role = isOwner
? AvatarRole.owner
: isAdmin
? AvatarRole.admin
: AvatarRole.none;
const onClickLogout = () => {
setLogoutAllDialogVisible(true);
@ -172,7 +212,7 @@ const LastSessionBlock = (props) => {
<Avatar
className="avatar"
role={role}
size="big"
size={AvatarSize.big}
userName={displayName}
source={avatar}
/>
@ -184,7 +224,9 @@ const LastSessionBlock = (props) => {
<ContextMenuButton
id="user-session-info"
displayType={ContextMenuButtonDisplayType.dropdown}
className="context-button"
data={[]}
getData={contextOptions}
/>
</StyledUserInfoBlock>
@ -227,11 +269,11 @@ const LastSessionBlock = (props) => {
);
};
export default inject(({ setup, peopleStore }) => {
export default inject<TStore>(({ setup, peopleStore }) => {
const { setDisableDialogVisible, setLogoutAllDialogVisible } = setup;
const { getItems, isMe, getFromDateAgo, setDisplayName } =
peopleStore.selectionStore;
peopleStore.selectionStore as unknown as SelectionPeopleStore;
return {
isMe,

View File

@ -1,3 +1,29 @@
// (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 { useTranslation } from "react-i18next";
import { observer, inject } from "mobx-react";
@ -7,10 +33,11 @@ import { Backdrop } from "@docspace/shared/components/backdrop";
import { Aside } from "@docspace/shared/components/aside";
import { Heading } from "@docspace/shared/components/heading";
import { Scrollbar } from "@docspace/shared/components/scrollbar";
import AllSessionsBlock from "./AllSessionsBlock";
import LastSessionBlock from "./LastSessionBlock";
import { UserSessionsPanelProps } from "./UserSessionsPanel.types";
const StyledSessionsPanel = styled.div`
.user-sessions-panel {
.scroll-body {
@ -43,7 +70,7 @@ const StyledScrollbar = styled(Scrollbar)`
height: calc(100vh - 87px) !important;
`;
const UserSessionsPanel = (props) => {
export const UserSessionsPanel = (props: UserSessionsPanelProps) => {
const { visible, setVisible } = props;
const { t } = useTranslation(["Settings", "Profile", "Common"]);
const scrollRef = useRef(null);
@ -54,12 +81,7 @@ const UserSessionsPanel = (props) => {
return (
<StyledSessionsPanel>
<Backdrop
onClick={onClose}
visible={visible}
isAside={true}
zIndex={210}
/>
<Backdrop onClick={onClose} visible={visible} zIndex={210} isAside />
<Aside
className="user-sessions-panel"
visible={visible}
@ -80,7 +102,7 @@ const UserSessionsPanel = (props) => {
);
};
export default inject(({ dialogsStore }) => {
export const SessionsPanel = inject<TStore>(({ dialogsStore }) => {
const { userSessionsPanelVisible, setUserSessionPanelVisible } = dialogsStore;
return {

View File

@ -0,0 +1,73 @@
// (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 { TTranslation } from "@docspace/shared/types";
import {
IAllSessions,
IConnections,
ISessions,
} from "SRC_DIR/pages/PortalSettings/categories/security/sessions/SecuritySessions.types";
export interface UserSessionsPanelProps {
visible: boolean;
setVisible: (visible: boolean) => void;
}
export interface LastSessionBlockProps {
t: TTranslation;
isMe?: boolean;
items?: IAllSessions;
setDisplayName?: (name: string) => void;
setDisableDialogVisible?: (visible: boolean) => void;
setLogoutAllDialogVisible?: (visible: boolean) => void;
getFromDateAgo?: (userId: string) => string;
}
export interface AllSessionsBlockProps {
t: TTranslation;
isLoading?: boolean;
items?: IAllSessions;
onClickLogoutAllExceptThis?: (
t: TTranslation,
exceptId: number,
displayName: string,
) => void;
}
export interface RowViewProps {
t: TTranslation;
sessions: ISessions[];
sectionWidth: number;
}
export interface SessionsRowProps {
t: TTranslation;
item: ISessions | IConnections;
connections?: IConnections;
sectionWidth: number;
setLogoutDialogVisible?: (visible: boolean) => void;
setPlatformData?: (item: ISessions) => void;
}

View File

@ -0,0 +1,27 @@
// (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
export { SessionsPanel } from "./UserSessionsPanel";

View File

@ -1,61 +0,0 @@
import { inject, observer } from "mobx-react";
import { Row } from "@docspace/shared/components/row";
import { IconButton } from "@docspace/shared/components/icon-button";
import styled from "styled-components";
import SessionsRowContent from "./SessionsRowContent";
import RemoveSessionSvgUrl from "PUBLIC_DIR/images/remove.session.svg?url";
const StyledRow = styled(Row)`
min-height: 56px;
`;
const SessionsRow = (props) => {
const {
item,
connections,
sectionWidth,
setLogoutDialogVisible,
setPlatformData,
} = props;
const onClickDisable = () => {
setLogoutDialogVisible(true);
setPlatformData(item);
};
const isEqualSession = item.id === connections.id;
const contentElement = !isEqualSession && (
<IconButton
size={20}
iconName={RemoveSessionSvgUrl}
isClickable
onClick={onClickDisable}
/>
);
return (
<StyledRow
key={item.id}
data={item}
sectionWidth={sectionWidth}
contentElement={contentElement}
>
<SessionsRowContent {...props} />
</StyledRow>
);
};
export default inject(({ setup, peopleStore }) => {
const { platformData, setPlatformData, items } = peopleStore.selectionStore;
const { setLogoutDialogVisible, setPlatformModalData } = setup;
return {
connections: items.connections[0],
setLogoutDialogVisible,
setPlatformModalData,
platformData,
setPlatformData,
};
})(observer(SessionsRow));

View File

@ -0,0 +1,88 @@
// (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 { Row } from "@docspace/shared/components/row";
import { IconButton } from "@docspace/shared/components/icon-button";
import styled from "styled-components";
import type SelectionPeopleStore from "SRC_DIR/store/SelectionPeopleStore";
import RemoveSessionSvgUrl from "PUBLIC_DIR/images/remove.session.svg?url";
import SessionsRowContent from "./SessionsRowContent";
import { SessionsRowProps } from "../../UserSessionsPanel.types";
const StyledRow = styled(Row)`
min-height: 56px;
`;
const SessionsRow = (props: SessionsRowProps) => {
const {
item,
connections,
setLogoutDialogVisible = () => {},
setPlatformData = () => {},
} = props;
const onClickDisable = () => {
setLogoutDialogVisible(true);
setPlatformData(item);
};
const isEqualSession = item.id === connections?.id;
const contentElement = !isEqualSession && (
<IconButton
size={20}
iconName={RemoveSessionSvgUrl}
isClickable
onClick={onClickDisable}
/>
);
return (
<StyledRow
key={item.id}
contentElement={contentElement}
onRowClick={() => {}}
>
<SessionsRowContent {...props} />
</StyledRow>
);
};
export default inject<TStore>(({ setup, peopleStore }) => {
const { setLogoutDialogVisible, setPlatformModalData } = setup;
const { platformData, setPlatformData, items } =
peopleStore.selectionStore as unknown as SelectionPeopleStore;
return {
connections: items.connections[0],
setLogoutDialogVisible,
setPlatformModalData,
platformData,
setPlatformData,
};
})(observer(SessionsRow));

View File

@ -1,47 +0,0 @@
import { Text } from "@docspace/shared/components/text";
import { convertTime } from "@docspace/shared/utils/convertTime";
import { RowContent } from "@docspace/shared/components/row-content";
import styled from "styled-components";
const StyledRowContent = styled(RowContent)`
.row-main-container-wrapper {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.date {
font-size: 14px;
font-weight: 600;
color: ${(props) => props.theme.profile.activeSessions.tableCellColor};
margin-left: 4px;
}
`;
const SessionsRowContent = ({ item, sectionWidth }) => {
const { id, platform, browser, country, city, date } = item;
return (
<StyledRowContent
key={id}
sectionWidth={sectionWidth}
sideColor={theme.profile.activeSessions.tableCellColor}
>
<Text fontSize="14px" fontWeight="600" containerWidth="160px" truncate>
{platform}, {browser?.split(".")[0] ?? ""}
<span className="date">{convertTime(new Date(date))}</span>
</Text>
<></>
{(country || city) && (
<Text fontSize="12px" fontWeight="600">
{country}
{country && city && ` ${city}`}
</Text>
)}
</StyledRowContent>
);
};
export default SessionsRowContent;

View File

@ -0,0 +1,76 @@
// (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 { Text } from "@docspace/shared/components/text";
import { convertTime } from "@docspace/shared/utils/convertTime";
import { RowContent } from "@docspace/shared/components/row-content";
import styled, { useTheme } from "styled-components";
import { IConnections } from "SRC_DIR/pages/PortalSettings/categories/security/sessions/SecuritySessions.types";
import { SessionsRowProps } from "../../UserSessionsPanel.types";
const StyledRowContent = styled(RowContent)`
.row-main-container-wrapper {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.date {
font-size: 14px;
font-weight: 600;
color: ${(props) => props.theme.profile.activeSessions.tableCellColor};
margin-left: 4px;
}
`;
const SessionsRowContent = ({ item, sectionWidth }: SessionsRowProps) => {
const { id, platform, browser, country, city, date } = item as IConnections;
const theme = useTheme();
return (
<StyledRowContent
key={id}
sectionWidth={sectionWidth}
sideColor={theme.profile.activeSessions.tableCellColor}
>
<Text fontSize="14px" fontWeight="600" truncate>
{platform}, {browser?.split(".")[0] ?? ""}
<span className="date">{convertTime(new Date(date))}</span>
</Text>
<span />
{(country || city) && (
<Text fontSize="12px" fontWeight="600">
{country}
{country && city && ` ${city}`}
</Text>
)}
</StyledRowContent>
);
};
export default SessionsRowContent;

View File

@ -1,33 +0,0 @@
import { RowContainer } from "@docspace/shared/components/row-container";
import styled from "styled-components";
import SessionsRow from "./SessionsRow";
const StyledRowContainer = styled(RowContainer)`
padding: 0px 16px;
`;
const RowView = (props) => {
const { t, sectionWidth, sessions } = props;
return (
<StyledRowContainer
useReactWindow={false}
hasMoreFiles={false}
itemHeight={58}
itemCount={sessions.length}
filesLength={sessions.length}
fetchMoreFiles={() => {}}
>
{sessions.map((item) => (
<SessionsRow
t={t}
key={item.id}
item={item}
sectionWidth={sectionWidth}
/>
))}
</StyledRowContainer>
);
};
export default RowView;

View File

@ -0,0 +1,61 @@
// (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 { RowContainer } from "@docspace/shared/components/row-container";
import styled from "styled-components";
import SessionsRow from "./SessionsRow";
import { RowViewProps } from "../../UserSessionsPanel.types";
const StyledRowContainer = styled(RowContainer)`
padding: 0px 16px;
`;
const RowView = (props: RowViewProps) => {
const { t, sectionWidth, sessions } = props;
return (
<StyledRowContainer
useReactWindow={false}
hasMoreFiles={false}
itemHeight={58}
itemCount={sessions.length}
filesLength={sessions.length}
fetchMoreFiles={() => Promise.resolve()}
onScroll={() => {}}
>
{sessions.map((item) => (
<SessionsRow
t={t}
key={item.id}
item={item}
sectionWidth={sectionWidth}
/>
))}
</StyledRowContainer>
);
};
export default RowView;

View File

@ -1,18 +0,0 @@
import { Consumer } from "@docspace/shared/utils";
import RowView from "./RowView";
const RowWrapper = ({ t, sessions }) => {
return (
<Consumer>
{(context) => (
<RowView
t={t}
sectionWidth={context.sectionWidth}
sessions={sessions}
/>
)}
</Consumer>
);
};
export default RowWrapper;

View File

@ -0,0 +1,45 @@
// (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 { Consumer } from "@docspace/shared/utils";
import { RowViewProps } from "../UserSessionsPanel.types";
import RowView from "./RowView";
const RowWrapper = ({ t, sessions }: RowViewProps) => {
return (
<Consumer>
{(context) => (
<RowView
t={t}
sectionWidth={context.sectionWidth as number}
sessions={sessions}
/>
)}
</Consumer>
);
};
export default RowWrapper;

View File

@ -33,7 +33,6 @@ import UploadPanel from "./UploadPanel";
import HotkeyPanel from "./HotkeysPanel";
import InvitePanel from "./InvitePanel";
import EditLinkPanel from "./EditLinkPanel";
import UserSessionsPanel from "./UserSessionsPanel";
export {
AddUsersPanel,
@ -45,5 +44,4 @@ export {
HotkeyPanel,
InvitePanel,
EditLinkPanel,
UserSessionsPanel,
};

View File

@ -38,7 +38,7 @@ import LoginHistory from "./login-history/index.js";
import MobileSecurityLoader from "./sub-components/loaders/mobile-security-loader";
import AccessLoader from "./sub-components/loaders/access-loader";
import AuditTrail from "./audit-trail/index.js";
import Sessions from "./sessions/index";
import { SecuritySessions } from "./sessions/SecuritySessions";
import { resetSessionStorage } from "../../utils";
import { DeviceType } from "@docspace/shared/enums";
import { SECTION_HEADER_HEIGHT } from "@docspace/shared/components/section/Section.constants";
@ -70,7 +70,7 @@ const SecurityWrapper = (props) => {
{
id: "sessions",
name: t("Common:Sessions"),
content: <Sessions />,
content: <SecuritySessions />,
},
];

View File

@ -1,29 +1,56 @@
// (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 } from "react";
import { useTranslation } from "react-i18next";
import { inject, observer } from "mobx-react";
import { useTranslation } from "react-i18next";
import { mobile, tablet } from "@docspace/shared/utils";
import SessionsLoader from "@docspace/shared/skeletons/sessions";
import styled from "styled-components";
import { MainContainer } from "../StyledSecurity";
import { Text } from "@docspace/shared/components/text";
import { Button } from "@docspace/shared/components/button";
import { Button, ButtonSize } from "@docspace/shared/components/button";
import { TTranslation } from "@docspace/shared/types";
import useViewEffect from "SRC_DIR/Hooks/useViewEffect";
import SessionsTable from "./SessionsTable";
import type UsersStore from "SRC_DIR/store/UsersStore";
import type SelectionPeopleStore from "SRC_DIR/store/SelectionPeopleStore";
import {
LogoutSessionDialog,
LogoutAllSessionDialog,
DisableUserDialog,
} from "SRC_DIR/components/dialogs";
import { DisableUserDialog } from "SRC_DIR/components/dialogs/DisableUserDialog";
import { LogoutSessionDialog } from "SRC_DIR/components/dialogs/LogoutSessionDialog";
import { LogoutAllSessionDialog } from "SRC_DIR/components/dialogs/LogoutAllSessionDialog";
import { SessionsProps } from "./SecuritySessions.types";
import { MainContainer } from "../StyledSecurity";
import SessionsTable from "./SessionsTable";
const DownLoadWrapper = styled.div`
display: flex;
align-items: center;
gap: 12px;
position: sticky;
bottom: 0;
background-color: ${({ theme }) => theme.backgroundColor};
@ -60,9 +87,7 @@ const DownLoadWrapper = styled.div`
font-weight: 400;
font-size: 12px;
line-height: 16px;
height: 16px;
margin: 0;
color: ${(props) =>
props.theme.client.settings.security.auditTrail
@ -102,20 +127,20 @@ const Sessions = ({
setUserSessionPanelVisible,
isSeveralSelection,
isSessionsLoaded,
}) => {
const { t } = useTranslation([
}: SessionsProps) => {
const { t }: { t: TTranslation } = useTranslation([
"Settings",
"Profile",
"Common",
"ChangeUserStatusDialog",
]);
useEffect(() => {
fetchData();
return () => {
clearSelection();
};
}, []);
}, [fetchData, clearSelection]);
useViewEffect({
view: viewAs,
@ -136,15 +161,14 @@ const Sessions = ({
<MainContainer>
<Text className="subtitle">{t("SessionsSubtitle")}</Text>
<SessionsTable t={t} sessionsData={allSessions} />
<SessionsTable t={t} sessionsData={allSessions} sectionWidth={0} />
<DownLoadWrapper>
<Button
className="download-report_button"
primary
label={t("DownloadReportBtnText")}
size="normal"
minwidth="auto"
size={ButtonSize.normal}
onClick={() => getLoginHistoryReport()}
isLoading={isLoadingDownloadReport}
/>
@ -159,6 +183,7 @@ const Sessions = ({
visible={disableDialogVisible}
onClose={() => setDisableDialogVisible(false)}
fetchData={fetchData}
isLoading={isLoading}
userIds={userIds}
updateUserStatus={updateUserStatus}
clearSelection={clearSelection}
@ -197,66 +222,69 @@ const Sessions = ({
);
};
export default inject(({ settingsStore, setup, peopleStore, dialogsStore }) => {
const { updateUserStatus } = peopleStore.usersStore;
const { currentDeviceType } = settingsStore;
const { setUserSessionPanelVisible } = dialogsStore;
const {
allSessions,
displayName,
clearSelection,
platformData,
fetchData,
selection,
bufferSelection,
isLoading,
isSeveralSelection,
onClickLogoutAllUsers,
onClickLogoutAllSessions,
onClickLogoutAllExceptThis,
onClickRemoveSession,
} = peopleStore.selectionStore;
export const SecuritySessions = inject<TStore>(
({ settingsStore, setup, peopleStore, dialogsStore }) => {
const { updateUserStatus } =
peopleStore.usersStore as unknown as UsersStore;
const { currentDeviceType } = settingsStore;
const { setUserSessionPanelVisible } = dialogsStore;
const {
allSessions,
displayName,
clearSelection,
platformData,
fetchData,
selection,
bufferSelection,
isLoading,
isSeveralSelection,
onClickLogoutAllUsers,
onClickLogoutAllSessions,
onClickLogoutAllExceptThis,
onClickRemoveSession,
} = peopleStore.selectionStore as unknown as SelectionPeopleStore;
const {
viewAs,
setViewAs,
disableDialogVisible,
logoutDialogVisible,
logoutAllDialogVisible,
setDisableDialogVisible,
setLogoutDialogVisible,
setLogoutAllDialogVisible,
getLoginHistoryReport,
isLoadingDownloadReport,
} = setup;
const {
viewAs,
setViewAs,
disableDialogVisible,
logoutDialogVisible,
logoutAllDialogVisible,
setDisableDialogVisible,
setLogoutDialogVisible,
setLogoutAllDialogVisible,
getLoginHistoryReport,
isLoadingDownloadReport,
} = setup;
return {
allSessions,
displayName,
clearSelection,
platformData,
selection,
bufferSelection,
fetchData,
viewAs,
setViewAs,
currentDeviceType,
disableDialogVisible,
logoutDialogVisible,
logoutAllDialogVisible,
setDisableDialogVisible,
setLogoutDialogVisible,
setLogoutAllDialogVisible,
isLoading,
onClickLogoutAllUsers,
onClickLogoutAllSessions,
onClickLogoutAllExceptThis,
onClickRemoveSession,
updateUserStatus,
getLoginHistoryReport,
isLoadingDownloadReport,
setUserSessionPanelVisible,
isSeveralSelection,
isSessionsLoaded: allSessions.length > 0,
};
})(observer(Sessions));
return {
allSessions,
displayName,
clearSelection,
platformData,
selection,
bufferSelection,
fetchData,
viewAs,
setViewAs,
currentDeviceType,
disableDialogVisible,
logoutDialogVisible,
logoutAllDialogVisible,
setDisableDialogVisible,
setLogoutDialogVisible,
setLogoutAllDialogVisible,
isLoading,
onClickLogoutAllUsers,
onClickLogoutAllSessions,
onClickLogoutAllExceptThis,
onClickRemoveSession,
updateUserStatus,
getLoginHistoryReport,
isLoadingDownloadReport,
setUserSessionPanelVisible,
isSeveralSelection,
isSessionsLoaded: allSessions.length > 0,
};
},
)(observer(Sessions));

View File

@ -0,0 +1,171 @@
// (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 { TViewAs, TTranslation } from "@docspace/shared/types";
import { DeviceType } from "@docspace/shared/enums";
export type TUserStatus = "online" | "offline";
export interface ISessions {
id: number;
platform: string;
browser: string;
ip: string;
status?: string;
date?: string;
}
export interface IConnections {
browser: string;
city: string | null;
country: string | null;
date: string;
id: number;
ip: string;
mobile: boolean;
page: string;
platform: string;
tenantId: number;
userId: string;
}
export interface IAllSessions {
avatar: string;
connections: IConnections[];
displayName: string;
id: string;
isAdmin: boolean;
isCollaborator: boolean;
isOwner: boolean;
isRoomAdmin: boolean;
isVisitor: boolean;
sessions: ISessions[];
status: TUserStatus;
}
export interface IDatafromSocket {
id: string;
displayName: string;
sessions: ISessions;
status: TUserStatus;
}
export interface SessionsProps {
allSessions: IAllSessions[];
displayName: string;
clearSelection: () => void;
platformData: ISessions;
selection: IAllSessions[];
bufferSelection?: IAllSessions;
fetchData: () => void;
isLoading: boolean;
viewAs: TViewAs;
setViewAs: (view: string) => void;
currentDeviceType: DeviceType;
disableDialogVisible: boolean;
logoutDialogVisible: boolean;
logoutAllDialogVisible: boolean;
setDisableDialogVisible: (visible: boolean) => void;
setLogoutDialogVisible: (visible: boolean) => void;
setLogoutAllDialogVisible: (visible: boolean) => void;
onClickLogoutAllUsers: () => void;
onClickLogoutAllSessions: () => void;
onClickLogoutAllExceptThis: () => void;
onClickRemoveSession: () => void;
updateUserStatus: () => void;
getLoginHistoryReport: () => void;
isLoadingDownloadReport: boolean;
setUserSessionPanelVisible: (visible: boolean) => void;
isSeveralSelection: boolean;
isSessionsLoaded: boolean;
}
export interface SessionsTableProps {
t: TTranslation;
userId?: string;
viewAs?: TViewAs;
sectionWidth: number;
setSelection?: (selection: unknown) => void;
setBufferSelection?: (selection: unknown | null) => void;
sessionsData: IAllSessions[];
}
export interface SessionsTableHeaderProps {
t: TTranslation;
userId?: string;
sectionWidth: number;
setHideColumns: (visible: boolean) => void;
containerRef: React.RefObject<HTMLDivElement>;
columnStorageName: string;
columnInfoPanelStorageName: string;
}
export interface SessionsTableRowProps {
t: TTranslation;
item: IAllSessions[];
element: React.ReactNode;
sectionWidth?: number;
onContentRowSelect?: (checked: boolean, item: IAllSessions[]) => void;
onContentRowClick?: (event: React.MouseEvent, item: IAllSessions[]) => void;
onUserContextClick?: (item: IAllSessions[], rightClick: boolean) => void;
isActive?: boolean;
checkedProps?: { checked: boolean };
displayName: string;
hideColumns?: boolean;
status: string;
userId: string;
connections: IConnections[];
isMe: boolean;
locale: string;
setLogoutAllDialogVisible: (visible: boolean) => void;
setDisableDialogVisible: (visible: boolean) => void;
setUserSessionPanelVisible: (visible: boolean) => void;
setItems: (item: IAllSessions[]) => void;
setDisplayName: (name: string) => void;
convertDate: (
t: (key: string) => string,
date: string,
locale: string,
) => string;
getFromDateAgo: (userId: string) => string;
setFromDateAgo: (userId: string, fromDateAgo: string | null) => void;
}
export interface SessionsRowProps {
t: TTranslation;
sectionWidth?: number;
sessionsData: IAllSessions[];
}
export interface SessionsRowContentProps {
t: TTranslation;
isOnline: boolean;
fromDateAgo: string | null;
displayName: string;
connections: IConnections[];
sectionWidth?: number;
}

View File

@ -1,3 +1,29 @@
// (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, useCallback } from "react";
import { inject, observer } from "mobx-react";
import { isMobile } from "react-device-detect";
@ -7,11 +33,14 @@ import { Row } from "@docspace/shared/components/row";
import styled, { css } from "styled-components";
import withContent from "SRC_DIR/HOCs/withPeopleContent";
import SessionsRowContent from "./SessionsRowContent";
import HistoryFinalizedReactSvgUrl from "PUBLIC_DIR/images/history-finalized.react.svg?url";
import RemoveSvgUrl from "PUBLIC_DIR/images/remove.session.svg?url";
import TrashReactSvgUrl from "PUBLIC_DIR/images/trash.react.svg?url";
import LogoutReactSvgUrl from "PUBLIC_DIR/images/logout.react.svg?url";
import type SelectionPeopleStore from "SRC_DIR/store/SelectionPeopleStore";
import { SessionsTableRowProps } from "../../SecuritySessions.types";
import SessionsRowContent from "./SessionsRowContent";
const marginStyles = css`
margin-left: -24px;
@ -57,7 +86,7 @@ const Wrapper = styled.div`
Wrapper.defaultProps = { theme: Base };
const StyledRow = styled(Row)`
${(props) => (props.checked || props.isActive) && checkedStyle};
${(props) => props.checked && checkedStyle};
${!isMobile &&
css`
@ -97,7 +126,7 @@ const StyledRow = styled(Row)`
}
`;
const SessionsRow = (props) => {
const SessionsRow = (props: SessionsTableRowProps) => {
const {
t,
item,
@ -106,7 +135,6 @@ const SessionsRow = (props) => {
onContentRowSelect,
onContentRowClick,
onUserContextClick,
isActive,
checkedProps,
displayName,
status,
@ -147,7 +175,7 @@ const SessionsRow = (props) => {
const intervalId = setInterval(updateStatus, 60000);
return () => clearInterval(intervalId);
}, [date, status, locale, userId, isOnline]);
}, [t, date, status, locale, userId, isOnline, convertDate, setFromDateAgo]);
const onClickSessions = () => {
setItems(item);
@ -173,7 +201,7 @@ const SessionsRow = (props) => {
{
key: "LogoutAllSessions",
label: t("Settings:LogoutAllSessions"),
icon: RemoveSvgUrl,
icon: LogoutReactSvgUrl,
onClick: onClickLogout,
},
{
@ -191,31 +219,30 @@ const SessionsRow = (props) => {
];
const onRowContextClick = useCallback(
(rightMouseButtonClick) => {
onUserContextClick?.(item, !rightMouseButtonClick);
(rightMouseButtonClick?: boolean) => {
if (onUserContextClick) onUserContextClick(item, !rightMouseButtonClick);
},
[item, onUserContextClick],
);
const onRowClick = (e) => onContentRowClick?.(e, item);
const onRowClick = (e: React.MouseEvent) => {
if (onContentRowClick) onContentRowClick(e, item);
};
return (
<Wrapper
className={`user-item row-wrapper ${
isChecked || isActive ? "row-selected" : ""
}`}
className={`user-item row-wrapper ${isChecked ? "row-selected" : ""}`}
>
<div className="user-item">
<StyledRow
key={item.userId}
key={userId}
data={item}
element={element}
onSelect={onContentRowSelect}
checked={isChecked}
isActive={isActive}
sectionWidth={sectionWidth}
mode={"modern"}
className={"user-row"}
mode="modern"
className="user-row"
contextOptions={contextOptions}
onRowClick={onRowClick}
onContextClick={onRowContextClick}
@ -231,7 +258,7 @@ const SessionsRow = (props) => {
);
};
export default inject(
export default inject<TStore>(
({ setup, dialogsStore, settingsStore, userStore, peopleStore }) => {
const { setUserSessionPanelVisible } = dialogsStore;
const { setLogoutAllDialogVisible, setDisableDialogVisible } = setup;
@ -246,7 +273,7 @@ export default inject(
convertDate,
getFromDateAgo,
setFromDateAgo,
} = peopleStore.selectionStore;
} = peopleStore.selectionStore as unknown as SelectionPeopleStore;
return {
isMe,

View File

@ -1,69 +0,0 @@
import styled, { css } from "styled-components";
import { Text } from "@docspace/shared/components/text";
import { RowContent } from "@docspace/shared/components/row-content";
const StyledRowContent = styled(RowContent)`
.online {
font-weight: 600;
color: ${(props) => props.theme.profile.activeSessions.textOnlineColor};
margin-left: 4px;
font-size: 14px;
::first-letter {
text-transform: uppercase;
}
}
.offline {
font-weight: 600;
color: ${(props) => props.theme.profile.activeSessions.tableCellColor};
font-size: 14px;
margin-left: 4px;
::first-letter {
text-transform: uppercase;
}
}
`;
const SessionsRowContent = ({
t,
isOnline,
fromDateAgo,
displayName,
connections,
sectionWidth,
}) => {
const { userId, platform, browser, ip, city, country } = connections[0] ?? {};
return (
<StyledRowContent
key={userId}
sectionWidth={sectionWidth}
sideColor={theme.profile.activeSessions.tableCellColor}
>
<Text fontSize="14px" fontWeight="600">
{displayName}
<span className={isOnline ? "online" : "offline"}>
{t(`Common:${fromDateAgo}`)}
</span>
</Text>
<></>
<Text fontSize="12px" fontWeight="600">
{platform}
{` ${browser}`}
</Text>
{(country || city) && (
<Text fontSize="12px" fontWeight="600">
{country}
{country && city && ` ${city}`}
</Text>
)}
<Text fontSize="12px" fontWeight="600" containerWidth="160px">
{ip}
</Text>
</StyledRowContent>
);
};
export default SessionsRowContent;

View File

@ -0,0 +1,98 @@
// (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, { useTheme } from "styled-components";
import { Text } from "@docspace/shared/components/text";
import { RowContent } from "@docspace/shared/components/row-content";
import { SessionsRowContentProps } from "../../SecuritySessions.types";
const StyledRowContent = styled(RowContent)`
.online {
font-weight: 600;
color: ${(props) => props.theme.profile.activeSessions.textOnlineColor};
margin-left: 4px;
font-size: 14px;
::first-letter {
text-transform: uppercase;
}
}
.offline {
font-weight: 600;
color: ${(props) => props.theme.profile.activeSessions.tableCellColor};
font-size: 14px;
margin-left: 4px;
::first-letter {
text-transform: uppercase;
}
}
`;
const SessionsRowContent = ({
t,
isOnline,
fromDateAgo,
displayName,
connections,
sectionWidth,
}: SessionsRowContentProps) => {
const theme = useTheme();
const { userId, platform, browser, ip, city, country } = connections[0] ?? {};
return (
<StyledRowContent
key={userId}
sectionWidth={sectionWidth}
sideColor={theme.profile.activeSessions.tableCellColor}
>
<Text fontSize="14px" fontWeight="600">
{displayName}
<span className={isOnline ? "online" : "offline"}>
{t(`Common:${fromDateAgo}`)}
</span>
</Text>
<span />
<Text fontSize="12px" fontWeight="600">
{platform}
{` ${browser}`}
</Text>
{(country || city) && (
<Text fontSize="12px" fontWeight="600">
{country}
{country && city && ` ${city}`}
</Text>
)}
<Text fontSize="12px" fontWeight="600">
{ip}
</Text>
</StyledRowContent>
);
};
export default SessionsRowContent;

View File

@ -1,8 +1,35 @@
// (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";
import styled, { css } from "styled-components";
import { RowContainer } from "@docspace/shared/components/row-container";
import { SessionsRowProps } from "../../SecuritySessions.types";
import SessionsRow from "./SessionsRow";
@ -81,7 +108,7 @@ const StyledRowContainer = styled(RowContainer)`
}
`;
const RowView = (props) => {
const RowView = (props: SessionsRowProps) => {
const { t, sectionWidth, sessionsData } = props;
return (
@ -92,7 +119,8 @@ const RowView = (props) => {
itemHeight={58}
itemCount={sessionsData.length}
filesLength={sessionsData.length}
fetchMoreFiles={() => {}}
onScroll={() => {}}
fetchMoreFiles={() => Promise.resolve()}
>
{sessionsData.map((item) => (
<SessionsRow
@ -110,8 +138,8 @@ const RowView = (props) => {
);
};
export default inject(({ userStore }) => {
const { id: userId } = userStore.user;
export default inject<TStore>(({ userStore }) => {
const userId = userStore.user?.id ?? null;
return {
userId,

View File

@ -1,111 +0,0 @@
import { useEffect, useState } from "react";
import { TableHeader } from "@docspace/shared/components/table";
const TABLE_VERSION = "4";
const TABLE_COLUMNS = `SecuritySessionsColumns_ver-${TABLE_VERSION}`;
const getColumns = (defaultColumns, userId) => {
const storageColumns = localStorage.getItem(`${TABLE_COLUMNS}=${userId}`);
const columns = [];
if (storageColumns) {
const splitColumns = storageColumns.split(",");
for (let col of defaultColumns) {
const column = splitColumns.find((key) => key === col.key);
column ? (col.enable = true) : (col.enable = false);
columns.push(col);
}
return columns;
} else {
return defaultColumns;
}
};
const SessionsTableHeader = (props) => {
const {
t,
userId,
sectionWidth,
setHideColumns,
containerRef,
columnStorageName,
columnInfoPanelStorageName,
} = props;
const defaultColumns = [
{
key: "User",
title: t("Common:User"),
resizable: true,
enable: true,
default: true,
active: true,
minWidth: 180,
isDisabled: true,
onChange: onColumnChange,
},
{
key: "Status",
title: t("Common:UserStatus"),
enable: true,
resizable: true,
onChange: onColumnChange,
},
{
key: "Platform",
title: t("Common:Platform"),
enable: true,
resizable: true,
onChange: onColumnChange,
},
{
key: "Location",
title: t("Common:Location"),
enable: true,
resizable: true,
onChange: onColumnChange,
},
];
const [columns, setColumns] = useState(getColumns(defaultColumns, userId));
useEffect(() => {
setColumns(getColumns(defaultColumns));
}, []);
function onColumnChange(key, e) {
const columnIndex = columns.findIndex((c) => c.key === key);
if (columnIndex === -1) return;
setColumns((prevColumns) =>
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);
}
return (
<TableHeader
checkboxSize="48px"
containerRef={containerRef}
columns={columns}
columnStorageName={columnStorageName}
columnInfoPanelStorageName={columnInfoPanelStorageName}
sectionWidth={sectionWidth}
checkboxMargin="12px"
showSettings={true}
useReactWindow
setHideColumns={setHideColumns}
infoPanelVisible={false}
/>
);
};
export default SessionsTableHeader;

View File

@ -0,0 +1,160 @@
// (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 { useTheme } from "styled-components";
import { SessionsTableHeaderProps } from "../../SecuritySessions.types";
const TABLE_VERSION = "4";
const TABLE_COLUMNS = `SecuritySessionsColumns_ver-${TABLE_VERSION}`;
const getColumns = (
defaultColumns: TTableColumn[],
userId?: string,
): TTableColumn[] => {
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 SessionsTableHeader = (props: SessionsTableHeaderProps) => {
const {
t,
userId,
sectionWidth,
setHideColumns,
containerRef,
columnStorageName,
columnInfoPanelStorageName,
} = props;
const [columns, setColumns] = useState<TTableColumn[]>([
{
key: "User",
title: t("Common:User"),
resizable: true,
enable: true,
default: true,
active: true,
minWidth: 180,
isDisabled: true,
},
]);
const theme = useTheme();
const onColumnChange = (key: string): void => {
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 : null))
.filter(Boolean);
localStorage.setItem(`${TABLE_COLUMNS}=${userId}`, tableColumns.toString());
};
const defaultColumns: TTableColumn[] = [
{
key: "User",
title: t("Common:User"),
resizable: true,
enable: true,
default: true,
active: true,
minWidth: 180,
isDisabled: true,
onChange: onColumnChange,
},
{
key: "Status",
title: t("Common:UserStatus"),
enable: true,
resizable: true,
onChange: onColumnChange,
},
{
key: "Platform",
title: t("Common:Platform"),
enable: true,
resizable: true,
onChange: onColumnChange,
},
{
key: "Location",
title: t("Common:Location"),
enable: true,
resizable: true,
onChange: onColumnChange,
},
];
useEffect(() => {
setColumns(getColumns(defaultColumns, userId));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [userId]);
return (
<TableHeader
containerRef={containerRef as { current: HTMLDivElement }}
columns={columns}
columnStorageName={columnStorageName}
columnInfoPanelStorageName={columnInfoPanelStorageName}
sectionWidth={sectionWidth}
showSettings
useReactWindow
setHideColumns={setHideColumns}
infoPanelVisible={false}
sortBy=""
sorted={false}
tableStorageName=""
onClick={() => {}}
resetColumnsSize={false}
isLengthenHeader={false}
sortingVisible={false}
tagRef={null}
theme={theme}
/>
);
};
export default SessionsTableHeader;

View File

@ -1,11 +1,36 @@
// (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, useCallback } from "react";
import { inject, observer } from "mobx-react";
import { Base } from "@docspace/shared/themes";
import styled, { css } from "styled-components";
import withContent from "SRC_DIR/HOCs/withPeopleContent";
import { TableRow } from "@docspace/shared/components/table";
import { TableCell } from "@docspace/shared/components/table";
import { TableCell, TableRow } from "@docspace/shared/components/table";
import { Text } from "@docspace/shared/components/text";
import { Checkbox } from "@docspace/shared/components/checkbox";
@ -13,6 +38,9 @@ import HistoryFinalizedReactSvgUrl from "PUBLIC_DIR/images/history-finalized.rea
import RemoveSvgUrl from "PUBLIC_DIR/images/remove.session.svg?url";
import LogoutReactSvgUrl from "PUBLIC_DIR/images/logout.react.svg?url";
import type SelectionPeopleStore from "SRC_DIR/store/SelectionPeopleStore";
import { SessionsTableRowProps } from "../../SecuritySessions.types";
const Wrapper = styled.div`
display: contents;
`;
@ -140,7 +168,7 @@ const StyledTableRow = styled(TableRow)`
StyledTableRow.defaultProps = { theme: Base };
const SessionsTableRow = (props) => {
const SessionsTableRow = (props: SessionsTableRowProps) => {
const {
t,
item,
@ -190,7 +218,7 @@ const SessionsTableRow = (props) => {
const intervalId = setInterval(updateStatus, 60000);
return () => clearInterval(intervalId);
}, [date, status, locale, userId, isOnline]);
}, [t, date, status, locale, userId, isOnline, convertDate, setFromDateAgo]);
const onClickSessions = () => {
setItems(item);
@ -233,18 +261,20 @@ const SessionsTableRow = (props) => {
},
];
const onChange = (e) => {
onContentRowSelect && onContentRowSelect(e.target.checked, item);
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (onContentRowSelect) onContentRowSelect(e.target.checked, item);
};
const onRowContextClick = useCallback(
(rightMouseButtonClick) => {
onUserContextClick?.(item, !rightMouseButtonClick);
(rightMouseButtonClick?: boolean) => {
if (onUserContextClick) onUserContextClick(item, !rightMouseButtonClick);
},
[item, onUserContextClick],
);
const onRowClick = (e) => onContentRowClick?.(e, item);
const onRowClick = (e: React.MouseEvent) => {
if (onContentRowClick) onContentRowClick(e, item);
};
return (
<Wrapper
@ -264,9 +294,9 @@ const SessionsTableRow = (props) => {
>
<TableCell className="table-container_user-name-cell">
<TableCell
hasAccess={true}
className="table-container_row-checkbox-wrapper"
checked={isChecked}
hasAccess
>
<div className="table-container_element">{element}</div>
<Checkbox
@ -302,7 +332,7 @@ const SessionsTableRow = (props) => {
{country}
{country && city && ", "}
{city}
<span className="divider"></span>
<span className="divider" />
</>
)}
{ip}
@ -313,7 +343,7 @@ const SessionsTableRow = (props) => {
);
};
export default inject(
export default inject<TStore>(
({ setup, dialogsStore, settingsStore, userStore, peopleStore }) => {
const { setUserSessionPanelVisible } = dialogsStore;
const { setLogoutAllDialogVisible, setDisableDialogVisible } = setup;
@ -328,7 +358,7 @@ export default inject(
convertDate,
getFromDateAgo,
setFromDateAgo,
} = peopleStore.selectionStore;
} = peopleStore.selectionStore as unknown as SelectionPeopleStore;
return {
isMe,

View File

@ -1,13 +1,40 @@
// (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, useRef } from "react";
import { inject, observer } from "mobx-react";
import { Base } from "@docspace/shared/themes";
import styled, { css } from "styled-components";
import { TableBody, TableContainer } from "@docspace/shared/components/table";
import SessionsTableHeader from "./SessionsTableHeader";
import SessionsTableRow from "./SessionsTableRow";
import { TableContainer } from "@docspace/shared/components/table";
import { TableBody } from "@docspace/shared/components/table";
import { SessionsTableProps } from "../../SecuritySessions.types";
const TABLE_VERSION = "4";
const COLUMNS_SIZE = `securitySessionsColumnsSize_ver-${TABLE_VERSION}`;
@ -130,9 +157,14 @@ const StyledTableContainer = styled(TableContainer)`
StyledTableContainer.defaultProps = { theme: Base };
const TableView = ({ t, sectionWidth, userId, sessionsData }) => {
const TableView = ({
t,
userId,
sectionWidth,
sessionsData,
}: SessionsTableProps) => {
const [hideColumns, setHideColumns] = useState(false);
const ref = useRef(null);
const ref = useRef<HTMLDivElement>(null);
const columnStorageName = `${COLUMNS_SIZE}=${userId}`;
const columnInfoPanelStorageName = `${INFO_PANEL_COLUMNS_SIZE}=${userId}`;
@ -176,8 +208,8 @@ const TableView = ({ t, sectionWidth, userId, sessionsData }) => {
);
};
export default inject(({ userStore }) => {
const { id: userId } = userStore.user;
export default inject<TStore>(({ userStore }) => {
const userId = userStore.user?.id ?? null;
return {
userId,

View File

@ -1,69 +0,0 @@
import { useEffect } from "react";
import { inject, observer } from "mobx-react";
import { Consumer } from "@docspace/shared/utils";
import TableView from "./TableView";
import RowView from "./RowView";
const SessionsTable = ({
t,
viewAs,
setSelection,
setBufferSelection,
sessionsData,
}) => {
useEffect(() => {
window.addEventListener("mousedown", onMouseDown);
return () => {
window.removeEventListener("mousedown", onMouseDown);
};
}, []);
const onMouseDown = (e) => {
if (
(e.target.closest(".scroll-body") &&
!e.target.closest(".user-item") &&
!e.target.closest(".not-selectable") &&
!e.target.closest(".info-panel") &&
!e.target.closest(".table-container_group-menu")) ||
e.target.closest(".files-main-button") ||
e.target.closest(".add-button") ||
e.target.closest(".search-input-block")
) {
setSelection([]);
setBufferSelection(null);
window?.getSelection()?.removeAllRanges();
}
};
return (
<Consumer>
{(context) =>
viewAs === "table" ? (
<TableView
t={t}
sectionWidth={context.sectionWidth}
sessionsData={sessionsData}
/>
) : (
<RowView
t={t}
sectionWidth={context.sectionWidth}
sessionsData={sessionsData}
/>
)
}
</Consumer>
);
};
export default inject(({ setup, peopleStore }) => {
const { setSelection, setBufferSelection } = peopleStore.selectionStore;
const { viewAs } = setup;
return {
viewAs,
setSelection,
setBufferSelection,
};
})(observer(SessionsTable));

View File

@ -0,0 +1,104 @@
// (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 } from "react";
import { inject, observer } from "mobx-react";
import { Consumer } from "@docspace/shared/utils";
import type SelectionPeopleStore from "SRC_DIR/store/SelectionPeopleStore";
import { SessionsTableProps } from "../SecuritySessions.types";
import TableView from "./TableView";
import RowView from "./RowView";
const SessionsTable = ({
t,
viewAs,
userId,
setSelection,
setBufferSelection,
sessionsData,
}: SessionsTableProps) => {
useEffect(() => {
const onMouseDown = (e: MouseEvent) => {
if (
e.target instanceof Element &&
((e.target.closest(".scroll-body") &&
!e.target.closest(".user-item") &&
!e.target.closest(".not-selectable") &&
!e.target.closest(".info-panel") &&
!e.target.closest(".table-container_group-menu")) ||
e.target.closest(".files-main-button") ||
e.target.closest(".add-button") ||
e.target.closest(".search-input-block"))
) {
if (setSelection) setSelection([]);
if (setBufferSelection) setBufferSelection(null);
window?.getSelection()?.removeAllRanges();
}
};
window.addEventListener("mousedown", onMouseDown);
return () => {
window.removeEventListener("mousedown", onMouseDown);
};
}, [setSelection, setBufferSelection]);
return (
<Consumer>
{(context) => {
return viewAs === "table" ? (
<TableView
t={t}
userId={userId}
sectionWidth={context.sectionWidth as number}
sessionsData={sessionsData}
/>
) : (
<RowView
t={t}
sectionWidth={context.sectionWidth as number}
sessionsData={sessionsData}
/>
);
}}
</Consumer>
);
};
export default inject<TStore>(({ setup, peopleStore, userStore }) => {
const userId = userStore.user?.id ?? null;
const { viewAs } = setup;
const { setSelection, setBufferSelection } =
peopleStore.selectionStore as unknown as SelectionPeopleStore;
return {
viewAs,
userId,
setSelection,
setBufferSelection,
};
})(observer(SessionsTable));

View File

@ -0,0 +1,27 @@
// (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
export { SecuritySessions } from "./SecuritySessions";

View File

@ -40,10 +40,8 @@ import InfoReactSvgUrl from "PUBLIC_DIR/images/info.react.svg?url";
import SessionsTable from "./SessionsTable";
import {
LogoutSessionDialog,
LogoutAllSessionDialog,
} from "SRC_DIR/components/dialogs";
import { LogoutSessionDialog } from "SRC_DIR/components/dialogs/LogoutSessionDialog";
import { LogoutAllSessionDialog } from "SRC_DIR/components/dialogs/LogoutAllSessionDialog";
const StyledWrapper = styled.div`
.auto-delete-title {

View File

@ -36,7 +36,7 @@ class SelectionStore {
dataFromSocket = [];
displayName = "";
fromDateAgo = {};
items = [];
items;
platformData = [];
isLoading = false;
selection = [];