-
-
+
+
+ {t("LdapConnectionType")}
+
-
-
-
+
);
diff --git a/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/HideButton.js b/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/HideButton.js
index 0e4c1b6948..fe1aa8e5f8 100644
--- a/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/HideButton.js
+++ b/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/HideButton.js
@@ -35,7 +35,7 @@ const HideButton = (props) => {
const { t } = useTranslation("SingleSignOn");
const { text, label, isAdditionalParameters, value, setIsSettingsShown } =
props;
- const marginProp = isAdditionalParameters ? null : "24px 0";
+ const marginProp = isAdditionalParameters ? null : "24px 0 8px 0px";
const onClick = () => {
setIsSettingsShown(!value);
diff --git a/packages/client/src/pages/PortalSettings/categories/security/audit-trail/AuditTrailLoader.js b/packages/client/src/pages/PortalSettings/categories/security/audit-trail/AuditTrailLoader.js
new file mode 100644
index 0000000000..00c5610799
--- /dev/null
+++ b/packages/client/src/pages/PortalSettings/categories/security/audit-trail/AuditTrailLoader.js
@@ -0,0 +1,143 @@
+// (c) Copyright Ascensio System SIA 2009-2024
+//
+// This program is a free software product.
+// You can redistribute it and/or modify it under the terms
+// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
+// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
+// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
+// any third-party rights.
+//
+// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
+// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
+//
+// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
+//
+// The interactive user interfaces in modified source and object code versions of the Program must
+// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
+//
+// Pursuant to Section 7(b) of the License you must retain the original Product logo when
+// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
+// trademark law for use of our trademarks.
+//
+// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
+// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
+// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
+
+import styled from "styled-components";
+import { RectangleSkeleton } from "@docspace/shared/skeletons";
+import { tablet, mobile } from "@docspace/shared/utils";
+
+const StyledLoader = styled.div`
+ .header {
+ height: 30px;
+ margin-bottom: 8px;
+ max-width: 700px;
+ @media ${mobile} {
+ height: 60px;
+ }
+ }
+
+ .second-container {
+ margin: 16px 0;
+ display: grid;
+ gap: 8px;
+ max-width: 350px;
+ }
+
+ .second-header {
+ max-width: 132px;
+ display: block;
+ @media ${mobile} {
+ max-width: 100%;
+ }
+ }
+
+ .description {
+ margin-top: 16px;
+ max-width: 645px;
+ }
+
+ .third-container {
+ margin: 16px 0;
+ display: flex;
+ justify-content: space-between;
+ grid-template-columns: repeat(3, 1fr);
+ max-width: 700px;
+
+ @media ${tablet} {
+ display: none;
+ }
+ }
+
+ .fourth-container {
+ display: grid;
+ gap: 4px;
+ margin-top: 16px;
+
+ .rows-header {
+ max-width: 197px;
+ display: none;
+ @media ${tablet} {
+ display: block;
+ }
+ }
+ .rows {
+ max-width: 700px;
+ display: block;
+ margin-bottom: 8px;
+ }
+ }
+
+ .button {
+ margin-top: 32px;
+ max-width: 163px;
+ }
+`;
+
+const AuditTrailLoader = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default AuditTrailLoader;
diff --git a/packages/client/src/pages/PortalSettings/categories/security/audit-trail/index.js b/packages/client/src/pages/PortalSettings/categories/security/audit-trail/index.js
index 11d355c5c9..13f20f6181 100644
--- a/packages/client/src/pages/PortalSettings/categories/security/audit-trail/index.js
+++ b/packages/client/src/pages/PortalSettings/categories/security/audit-trail/index.js
@@ -24,15 +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 React, { useEffect } from "react";
+import React, { useEffect, useState } from "react";
import { withTranslation } from "react-i18next";
import { setDocumentTitle } from "SRC_DIR/helpers/utils";
import { inject } from "mobx-react";
+
import { Consumer } from "@docspace/shared/utils";
+import { EmptyScreenContainer } from "@docspace/shared/components/empty-screen-container";
+
import { Table } from "./TableView/TableView";
import AuditRowContainer from "./RowView/AuditRowContainer";
import HistoryMainContent from "../sub-components/HistoryMainContent";
+import EmptyScreenRecentUrl from "PUBLIC_DIR/images/empty_screen_recent.svg?url";
+import EmptyScreenRecentDarkUrl from "PUBLIC_DIR/images/empty_screen_recent_dark.svg?url";
+import AuditTrailLoader from "./AuditTrailLoader";
+
+let timerId = null;
const AuditTrail = (props) => {
const {
t,
@@ -48,11 +56,24 @@ const AuditTrail = (props) => {
isLoadingDownloadReport,
} = props;
+ const [isLoading, setIsLoading] = useState(!auditTrailUsers.length);
+ const [isShowLoader, setIShowLoader] = useState(false);
+ const initAudit = async () => {
+ timerId = setTimeout(() => {
+ if (!auditTrailUsers.length) setIShowLoader(true);
+ }, 500);
+
+ await getAuditTrail();
+
+ clearTimeout(timerId);
+ timerId = null;
+ setIShowLoader(false);
+ setIsLoading(false);
+ };
+
useEffect(() => {
setDocumentTitle(t("AuditTrailNav"));
-
- getAuditTrail();
-
+ initAudit();
getLifetimeAuditSettings();
}, []);
@@ -83,6 +104,27 @@ const AuditTrail = (props) => {
);
};
+
+ if (isShowLoader) {
+ return
;
+ }
+
+ if (isLoading) return <>>;
+
+ if (auditTrailUsers.length === 0) {
+ return (
+
+ );
+ }
+
return (
<>
{securityLifetime && securityLifetime.auditTrailLifeTime && (
diff --git a/packages/client/src/pages/Sdk/index.js b/packages/client/src/pages/Sdk/index.js
index 0394d26dcf..bdc86f0f19 100644
--- a/packages/client/src/pages/Sdk/index.js
+++ b/packages/client/src/pages/Sdk/index.js
@@ -53,9 +53,9 @@ const Sdk = ({
user,
updateProfileCulture,
getRoomsIcon,
- fetchExternalLinks,
getFilePrimaryLink,
getFilesSettings,
+ getPrimaryLink,
}) => {
const [isDataReady, setIsDataReady] = useState(false);
@@ -200,20 +200,11 @@ const Sdk = ({
(data[0].roomType === RoomsType.CustomRoom && data[0].shared) ||
(data[0].roomType === RoomsType.FormRoom && data[0].shared)
) {
- const links = await fetchExternalLinks(data[0].id);
+ const link = await getPrimaryLink(data[0].id);
- const requestTokens = links.map((link) => {
- const { id, title, requestToken, primary } = link.sharedTo;
+ const { id, title, requestToken, primary } = link.sharedTo;
- return {
- id,
- primary,
- title,
- requestToken,
- };
- });
-
- data[0].requestTokens = requestTokens;
+ data[0].requestTokens = [{ id, primary, title, requestToken }];
}
frameCallEvent({ event: "onSelectCallback", data });
@@ -321,7 +312,6 @@ export const Component = inject(
settingsStore,
filesSettingsStore,
peopleStore,
- publicRoomStore,
userStore,
filesStore,
}) => {
@@ -331,8 +321,7 @@ export const Component = inject(
const { loadCurrentUser, user } = userStore;
const { updateProfileCulture } = peopleStore.targetUserStore;
const { getIcon, getRoomsIcon, getFilesSettings } = filesSettingsStore;
- const { fetchExternalLinks } = publicRoomStore;
- const { getFilePrimaryLink } = filesStore;
+ const { getFilePrimaryLink, getPrimaryLink } = filesStore;
return {
theme,
@@ -347,9 +336,9 @@ export const Component = inject(
isLoaded,
updateProfileCulture,
user,
- fetchExternalLinks,
getFilePrimaryLink,
getFilesSettings,
+ getPrimaryLink,
};
},
)(
diff --git a/packages/shared/api/people/filter.js b/packages/shared/api/people/filter.js
index 086224fd9a..05f18a80cc 100644
--- a/packages/shared/api/people/filter.js
+++ b/packages/shared/api/people/filter.js
@@ -40,6 +40,7 @@ const DEFAULT_PAYMENTS = null;
const DEFAULT_ACCOUNT_LOGIN_TYPE = null;
const DEFAULT_WITHOUT_GROUP = false;
const DEFAULT_QUOTA_FILTER = null;
+const DEFAULT_FILTER_SEPARATOR = null;
const ACTIVE_EMPLOYEE_STATUS = 1;
@@ -56,6 +57,7 @@ const PAYMENTS = "payments";
const ACCOUNT_LOGIN_TYPE = "accountLoginType";
const WITHOUT_GROUP = "withoutGroup";
const QUOTA_FILTER = "quotaFilter";
+const FILTER_SEPARATOR = "filterSeparator";
class Filter {
static getDefault(total = DEFAULT_TOTAL) {
@@ -145,6 +147,7 @@ class Filter {
accountLoginType = DEFAULT_ACCOUNT_LOGIN_TYPE,
withoutGroup = DEFAULT_WITHOUT_GROUP,
quotaFilter = DEFAULT_QUOTA_FILTER,
+ filterSeparator = DEFAULT_FILTER_SEPARATOR,
) {
this.page = page;
this.pageCount = pageCount;
@@ -160,6 +163,7 @@ class Filter {
this.accountLoginType = accountLoginType;
this.withoutGroup = withoutGroup;
this.quotaFilter = quotaFilter;
+ this.filterSeparator = filterSeparator;
}
getStartIndex = () => {
@@ -188,6 +192,7 @@ class Filter {
accountLoginType,
withoutGroup,
quotaFilter,
+ filterSeparator,
} = this;
let employeetype = null;
@@ -212,6 +217,7 @@ class Filter {
accountLoginType,
withoutGroup,
quotaFilter,
+ filterSeparator,
};
dtoFilter = { ...dtoFilter, ...employeetype };
@@ -235,6 +241,7 @@ class Filter {
accountLoginType,
withoutGroup,
quotaFilter,
+ filterSeparator,
} = this;
const dtoFilter = {};
@@ -269,6 +276,8 @@ class Filter {
if (quotaFilter) dtoFilter[QUOTA_FILTER] = quotaFilter;
+ if (filterSeparator) dtoFilter[FILTER_SEPARATOR] = filterSeparator;
+
dtoFilter[PAGE] = page + 1;
dtoFilter[SORT_BY] = sortBy;
dtoFilter[SORT_ORDER] = sortOrder;
@@ -304,6 +313,7 @@ class Filter {
this.accountLoginType,
this.withoutGroup,
this.quotaFilter,
+ this.filterSeparator,
);
}
@@ -323,6 +333,7 @@ class Filter {
null,
null,
false,
+ null,
);
}
@@ -342,7 +353,8 @@ class Filter {
this.pageCount === filter.pageCount &&
this.payments === filter.payments &&
this.accountLoginType === filter.accountLoginType &&
- this.withoutGroup === filter.withoutGroup;
+ this.withoutGroup === filter.withoutGroup &&
+ this.filterSeparator === filter.filterSeparator;
return equals;
}
diff --git a/packages/shared/components/drop-down/DropDown.styled.ts b/packages/shared/components/drop-down/DropDown.styled.ts
index 3f7a4a79be..404052021d 100644
--- a/packages/shared/components/drop-down/DropDown.styled.ts
+++ b/packages/shared/components/drop-down/DropDown.styled.ts
@@ -100,8 +100,6 @@ const StyledDropdown = styled.div<{
-moz-box-shadow: ${(props) => props.theme.dropDown.boxShadow};
-webkit-box-shadow: ${(props) => props.theme.dropDown.boxShadow};
- padding: ${(props) =>
- !props.maxHeight && props.itemCount && props.itemCount > 1 && `4px 0px`};
${(props) =>
props.columnCount &&
`
diff --git a/packages/shared/components/password-input/PasswordInput.tsx b/packages/shared/components/password-input/PasswordInput.tsx
index 98f1509b1c..9dd32f1da6 100644
--- a/packages/shared/components/password-input/PasswordInput.tsx
+++ b/packages/shared/components/password-input/PasswordInput.tsx
@@ -180,7 +180,7 @@ const PasswordInput = React.forwardRef
(
[onKeyDown],
);
- const changeInputType = () => {
+ const changeInputType = React.useCallback(() => {
const newType =
state.type === InputType.text ? InputType.password : InputType.text;
@@ -188,7 +188,13 @@ const PasswordInput = React.forwardRef(
...s,
type: newType,
}));
- };
+ }, [state.type]);
+
+ React.useEffect(() => {
+ if (isDisabled && state.type === InputType.text) {
+ changeInputType();
+ }
+ }, [isDisabled, changeInputType, state.type]);
const testStrength = useCallback(
(value: string) => {
diff --git a/packages/shared/utils/axiosClient.ts b/packages/shared/utils/axiosClient.ts
index 5ea43f0623..01aac52126 100644
--- a/packages/shared/utils/axiosClient.ts
+++ b/packages/shared/utils/axiosClient.ts
@@ -241,10 +241,14 @@ class AxiosClient {
if (!this.isSSR) {
switch (error.response?.status) {
case 401: {
- if (options.skipUnauthorized || window?.ClientConfig?.isFrame)
- return Promise.resolve();
+ if (options.skipUnauthorized) return Promise.resolve();
+
if (options.skipLogout) return Promise.reject(error);
+ if (window?.ClientConfig?.isFrame) {
+ break;
+ }
+
const opt: AxiosRequestConfig = {
method: "POST",
url: "/authentication/logout",
@@ -286,6 +290,7 @@ class AxiosClient {
return Promise.reject(error);
}
+
switch (error.response?.status) {
case 401:
return Promise.resolve();