diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/GroupMembersList/GroupMembersList.tsx b/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/GroupMembersList/GroupMembersList.tsx
new file mode 100644
index 0000000000..08800bb675
--- /dev/null
+++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/GroupMembersList/GroupMembersList.tsx
@@ -0,0 +1,155 @@
+// (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 React, { useCallback, useEffect, useState } from "react";
+import {
+ ListRowProps,
+ Index,
+ IndexRange,
+ InfiniteLoader,
+ List,
+ WindowScroller,
+} from "react-virtualized";
+import styled from "styled-components";
+
+import { TUser } from "@docspace/shared/api/people/types";
+import { RowLoader } from "@docspace/shared/skeletons/selector";
+
+import GroupMember from "../GroupMember";
+
+const ROW_HEIGHT = 50;
+
+export const StyledList = styled(List)`
+ width: ${({ width }) => `${width - 40}px`} !important;
+
+ .group-member-row-loader {
+ padding: 0;
+ }
+`;
+
+interface GroupMembersListProps {
+ members: TUser[];
+ loadNextPage: (startIndex: number) => Promise
;
+ hasNextPage: boolean;
+ total: number;
+}
+
+export const GroupMembersList = ({
+ members,
+ loadNextPage,
+ hasNextPage,
+ total,
+}: GroupMembersListProps) => {
+ const [scrollElement, setScrollElement] = useState(
+ null,
+ );
+ const [isNextPageLoading, setIsNextPageLoading] = useState(false);
+
+ const itemsCount = hasNextPage ? members.length + 1 : members.length;
+
+ const isItemLoaded = useCallback(
+ ({ index }: Index) => {
+ return !hasNextPage || index < itemsCount;
+ },
+ [hasNextPage, itemsCount],
+ );
+
+ const loadMoreItems = useCallback(
+ async ({ startIndex }: IndexRange) => {
+ setIsNextPageLoading(true);
+ if (!isNextPageLoading) {
+ await loadNextPage(startIndex - 1);
+ }
+ setIsNextPageLoading(false);
+ },
+ [isNextPageLoading, loadNextPage],
+ );
+
+ const renderRow = ({ key, index, style }: ListRowProps) => {
+ const item = members[index];
+
+ return (
+
+ {item ? (
+
+ ) : (
+
+ )}
+
+ );
+ };
+
+ useEffect(() => {
+ const scrollEl = document.querySelector(".info-panel-scroll");
+
+ if (scrollEl) {
+ setScrollElement(scrollEl as HTMLDivElement);
+ }
+ }, []);
+
+ if (!scrollElement) {
+ return null;
+ }
+
+ return (
+
+ {({ onRowsRendered, registerChild }) => (
+
+ {({ height, isScrolling, scrollTop }) => {
+ const scrollRect = scrollElement.getBoundingClientRect();
+
+ return (
+
+ );
+ }}
+
+ )}
+
+ );
+};
diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/index.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/index.js
index ac9bebf5b7..78361e93e3 100644
--- a/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/index.js
+++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/index.js
@@ -26,13 +26,22 @@
import { inject, observer } from "mobx-react";
import { withTranslation } from "react-i18next";
-import * as Styled from "../../styles/groups.styled";
+import { useParams } from "react-router-dom";
+import { useState, useEffect, useRef } from "react";
+
import withLoader from "@docspace/client/src/HOCs/withLoader";
import InfoPanelViewLoader from "@docspace/shared/skeletons/info-panel/body";
+import api from "@docspace/shared/api";
+import AccountsFilter from "@docspace/shared/api/people/filter";
+import {
+ MIN_LOADER_TIMER,
+ SHOW_LOADER_TIMER,
+} from "@docspace/shared/selectors/Files/FilesSelector.constants";
+
import GroupMember from "./GroupMember";
+import * as Styled from "../../styles/groups.styled";
import useFetchGroup from "./useFetchGroup";
-import { useParams } from "react-router-dom";
-import { useState, useEffect } from "react";
+import { GroupMembersList } from "./GroupMembersList/GroupMembersList";
const Groups = ({
infoPanelSelection,
@@ -41,7 +50,14 @@ const Groups = ({
infoPanelSelectedGroup,
setInfoPanelSelectedGroup,
}) => {
- const [isShowLoader, setIsShowLoader] = useState(false);
+ const [isFirstLoad, setIsFirstLoad] = useState(true);
+ const [showLoader, setShowLoader] = useState(false);
+ const [groupMembers, setGroupMembers] = useState(null);
+ const [total, setTotal] = useState(0);
+
+ const abortControllerRef = useRef(new AbortController());
+ const startLoader = useRef(null);
+ const loaderTimeout = useRef(null);
const { groupId: paramsGroupId } = useParams();
const isInsideGroup = !!paramsGroupId;
@@ -51,32 +67,121 @@ const Groups = ({
const groupId = isInsideGroup ? paramsGroupId : infoPanelSelection?.id;
const setGroup = isInsideGroup ? setCurrentGroup : setInfoPanelSelectedGroup;
+ const groupManager = group?.manager;
+
+ const loadNextPage = async (startIndex) => {
+ try {
+ abortControllerRef.current = new AbortController();
+
+ const pageCount = 100;
+ const filter = AccountsFilter.getDefault();
+ filter.group = groupId;
+ filter.page = Math.ceil(startIndex / pageCount);
+ filter.pageCount = pageCount;
+
+ const res = await api.people.getUserList(
+ filter,
+ abortControllerRef.current.signal,
+ );
+
+ const membersWithoutManager = groupManager
+ ? res.items.filter((item) => item.id !== groupManager.id)
+ : res.items;
+
+ setTotal(res.total);
+ if (startIndex === 0 || !groupMembers) {
+ setGroupMembers(membersWithoutManager);
+ } else {
+ setGroupMembers([...groupMembers, ...membersWithoutManager]);
+ }
+ } catch (e) {
+ console.log(e);
+ } finally {
+ if (startIndex === 0) {
+ setIsFirstLoad(false);
+ }
+ }
+ };
+
+ const calculateLoader = () => {
+ if (isFirstLoad) {
+ loaderTimeout.current = setTimeout(() => {
+ startLoader.current = new Date();
+ setShowLoader(true);
+ }, SHOW_LOADER_TIMER);
+ } else if (startLoader.current) {
+ const currentDate = new Date();
+
+ const ms = Math.abs(
+ startLoader.current.getTime() - currentDate.getTime(),
+ );
+
+ if (ms >= MIN_LOADER_TIMER) {
+ startLoader.current = null;
+ return setShowLoader(false);
+ }
+
+ setTimeout(() => {
+ startLoader.current = null;
+ setShowLoader(false);
+ }, MIN_LOADER_TIMER - ms);
+
+ loaderTimeout.current = null;
+ } else if (loaderTimeout.current) {
+ clearTimeout(loaderTimeout.current);
+ loaderTimeout.current = null;
+ }
+ };
+
useFetchGroup(groupId, group?.id, setGroup);
useEffect(() => {
- const showLoaderTimer = setTimeout(() => setIsShowLoader(true), 500);
- return () => clearTimeout(showLoaderTimer);
+ setIsFirstLoad(true);
+ }, [infoPanelSelection.id]);
+
+ useEffect(() => {
+ if (group) {
+ loadNextPage(0);
+ }
+
+ return () => {
+ abortControllerRef.current.abort();
+ };
+ }, [group]);
+
+ useEffect(() => {
+ calculateLoader();
+ }, [isFirstLoad]);
+
+ useEffect(() => {
+ return () => {
+ loaderTimeout.current = null;
+ };
}, []);
- const groupManager = group?.manager;
- const groupMembers = group?.members?.filter(
- (user) => user.id !== groupManager?.id,
- );
-
- if (!group) {
- if (isShowLoader) return ;
- return null;
+ if (showLoader) {
+ return (
+
+
+
+ );
}
+ const totalWithoutManager = groupManager ? total - 1 : total;
+
return (
- {groupManager && }
- {!groupMembers ? (
-
- ) : (
- groupMembers?.map((groupMember) => (
-
- ))
+ {isFirstLoad || !groupMembers ? null : (
+ <>
+ {groupManager && }
+
+ >
)}
);
diff --git a/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/useFetchGroup.js b/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/useFetchGroup.js
index c65aff8872..cb2b08f351 100644
--- a/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/useFetchGroup.js
+++ b/packages/client/src/pages/Home/InfoPanel/Body/views/Groups/useFetchGroup.js
@@ -45,7 +45,7 @@ const useFetchGroup = (groupId, fetchedGroupId, setGroup) => {
setIsLoading(true);
}
- getGroupById(groupId, abortControllerRef.current?.signal)
+ getGroupById(groupId, false, abortControllerRef.current?.signal)
.then((data) => {
if (isMount.current) startTransition(() => setGroup(data));
})
diff --git a/packages/client/src/pages/PortalSettings/categories/common/Branding/additionalResources.js b/packages/client/src/pages/PortalSettings/categories/common/Branding/additionalResources.js
index 3bf68280bf..f7d3cd0e19 100644
--- a/packages/client/src/pages/PortalSettings/categories/common/Branding/additionalResources.js
+++ b/packages/client/src/pages/PortalSettings/categories/common/Branding/additionalResources.js
@@ -187,12 +187,14 @@ const AdditionalResources = (props) => {
const onSave = useCallback(async () => {
setIsLoading(true);
+ const settings = JSON.parse(JSON.stringify(additionalResourcesData));
+
+ settings.feedbackAndSupportEnabled = feedbackAndSupportEnabled;
+ settings.videoGuidesEnabled = videoGuidesEnabled;
+ settings.helpCenterEnabled = helpCenterEnabled;
+
await api.settings
- .setAdditionalResources(
- feedbackAndSupportEnabled,
- videoGuidesEnabled,
- helpCenterEnabled,
- )
+ .setAdditionalResources(settings)
.then(() => {
toastr.success(t("Settings:SuccessfullySaveSettingsMessage"));
})
diff --git a/packages/client/src/pages/PortalSettings/categories/integration/DocumentService/index.js b/packages/client/src/pages/PortalSettings/categories/integration/DocumentService/index.js
index 2b56be8a0b..5f8c16293e 100644
--- a/packages/client/src/pages/PortalSettings/categories/integration/DocumentService/index.js
+++ b/packages/client/src/pages/PortalSettings/categories/integration/DocumentService/index.js
@@ -273,7 +273,7 @@ const DocumentService = ({
onSaveClick={onSubmit}
onCancelClick={onReset}
saveButtonLabel={t("Common:SaveButton")}
- cancelButtonLabel={t("Common:Restore")}
+ cancelButtonLabel={t("Settings:DefaultSettings")}
reminderText={t("Settings:YouHaveUnsavedChanges")}
saveButtonDisabled={saveButtonDisabled}
disableRestoreToDefault={
diff --git a/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/AttributeMapping.js b/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/AttributeMapping.js
index 6f6d1fc483..3505190b34 100644
--- a/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/AttributeMapping.js
+++ b/packages/client/src/pages/PortalSettings/categories/integration/LDAP/sub-components/AttributeMapping.js
@@ -129,6 +129,26 @@ const AttributeMapping = (props) => {
/>
+
+
+
+
{
/>
+
+
+
+
{
tabIndex={11}
/>
-
-
-
-
-
-
-
-
{
const { t } = useTranslation(["Settings", "Common"]);
@@ -56,6 +62,7 @@ const ButtonContainer = ({
}, [saveLdapSettings, t]);
const onResetClick = React.useCallback(() => {
+ closeResetModal();
restoreToDefault(t).catch((e) => toastr.error(e));
}, [restoreToDefault, t]);
@@ -76,7 +83,7 @@ const ButtonContainer = ({
+ {confirmationResetModal && (
+
+ )}
);
};
@@ -104,6 +118,9 @@ export default inject(({ settingsStore, ldapStore }) => {
isUIDisabled,
progressStatus,
+ confirmationResetModal,
+ closeResetModal,
+ openResetModal,
} = ldapStore;
const { currentDeviceType } = settingsStore;
@@ -123,5 +140,9 @@ export default inject(({ settingsStore, ldapStore }) => {
isMobileView,
hasProgressError: !!error,
+
+ confirmationResetModal,
+ closeResetModal,
+ openResetModal,
};
})(observer(ButtonContainer));
diff --git a/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/SubmitButton.js b/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/SubmitButton.js
index 683fbfbbe0..4c12848b89 100644
--- a/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/SubmitButton.js
+++ b/packages/client/src/pages/PortalSettings/categories/integration/SingleSignOn/SubmitButton.js
@@ -30,7 +30,7 @@ import { useTranslation } from "react-i18next";
import { SaveCancelButtons } from "@docspace/shared/components/save-cancel-buttons";
-import ResetConfirmationModal from "./sub-components/ResetConfirmationModal";
+import ResetConfirmationModal from "SRC_DIR/components/dialogs/ResetConfirmationDialog/ResetConfirmationModal";
const SubmitResetButtons = (props) => {
const { t } = useTranslation(["SingleSignOn", "Settings", "Common"]);
@@ -46,6 +46,8 @@ const SubmitResetButtons = (props) => {
isLoadingXml,
enableSso,
isSSOAvailable,
+ closeResetModal,
+ confirmReset,
} = props;
return (
@@ -56,7 +58,7 @@ const SubmitResetButtons = (props) => {
onCancelClick={isSsoEnabled ? openResetModal : resetForm}
showReminder={true}
saveButtonLabel={t("Common:SaveButton")}
- cancelButtonLabel={t("Common:Restore")}
+ cancelButtonLabel={t("Settings:DefaultSettings")}
displaySettings={true}
hasScroll={true}
isSaving={isSubmitLoading}
@@ -69,7 +71,13 @@ const SubmitResetButtons = (props) => {
additionalClassSaveButton="save-button"
additionalClassCancelButton="restore-button"
/>
- {confirmationResetModal && }
+ {confirmationResetModal && (
+
+ )}
>
);
};
@@ -86,6 +94,8 @@ export default inject(({ ssoStore, currentQuotaStore }) => {
hasChanges,
isLoadingXml,
enableSso,
+ closeResetModal,
+ confirmReset,
} = ssoStore;
const { isSSOAvailable } = currentQuotaStore;
@@ -101,5 +111,7 @@ export default inject(({ ssoStore, currentQuotaStore }) => {
isLoadingXml,
enableSso,
isSSOAvailable,
+ closeResetModal,
+ confirmReset,
};
})(observer(SubmitResetButtons));
diff --git a/packages/client/src/store/EditGroupStore.ts b/packages/client/src/store/EditGroupStore.ts
new file mode 100644
index 0000000000..541ace92c8
--- /dev/null
+++ b/packages/client/src/store/EditGroupStore.ts
@@ -0,0 +1,248 @@
+// (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 { makeAutoObservable } from "mobx";
+
+import { TUser } from "@docspace/shared/api/people/types";
+import { TGroup } from "@docspace/shared/api/groups/types";
+import AccountsFilter from "@docspace/shared/api/people/filter";
+import api from "@docspace/shared/api";
+import PeopleStore from "SRC_DIR/store/PeopleStore";
+import GroupsStore from "SRC_DIR/store/GroupsStore";
+
+class EditGroupStore {
+ isInit = false;
+
+ group: TGroup | null = null;
+
+ title: string = "";
+
+ manager: TUser | null = null;
+
+ members: TUser[] | null = null;
+
+ addedMembersMap: Map = new Map();
+
+ removedMembersMap: Map = new Map();
+
+ initialTotal: number = 0;
+
+ filter = AccountsFilter.getDefault();
+
+ peopleStore: PeopleStore;
+
+ constructor(peopleStore: PeopleStore) {
+ this.peopleStore = peopleStore;
+
+ makeAutoObservable(this);
+ }
+
+ initGroupData = async (group: TGroup) => {
+ try {
+ this.setGroup(group);
+ this.setTitle(group.name);
+
+ if (group.manager) {
+ this.setManager(group.manager);
+ }
+
+ this.filter.group = group.id;
+ this.filter.pageCount = 100;
+
+ await this.loadMembers(0);
+
+ this.setIsInit(true);
+ } catch (e) {
+ console.log(e);
+ }
+ };
+
+ resetGroupData = () => {
+ this.isInit = false;
+ this.group = null;
+ this.title = "";
+ this.manager = null;
+ this.members = null;
+ this.addedMembersMap = new Map();
+ this.removedMembersMap = new Map();
+ this.initialTotal = 0;
+ this.filter = AccountsFilter.getDefault();
+ };
+
+ loadMembers = async (startIndex: number) => {
+ try {
+ if (!this.group?.id) return;
+
+ this.filter.page = !startIndex ? 0 : this.filter.page + 1;
+
+ const res = await api.people.getUserList(this.filter);
+
+ const membersWithoutManager = res.items.filter(
+ (item) =>
+ item.id !== this.manager?.id || item.id !== this.group?.manager?.id,
+ );
+
+ this.setInitialTotal(res.total);
+
+ if (startIndex === 0 || !this.members) {
+ this.setMembers(membersWithoutManager);
+ } else {
+ this.setMembers([...this.members, ...membersWithoutManager]);
+ }
+ } catch (e) {
+ console.log(e);
+ }
+ };
+
+ submitChanges = async () => {
+ try {
+ if (!this.group) return;
+
+ const { updateGroup } = this.peopleStore.groupsStore! as GroupsStore;
+
+ const addedIds = Array.from(this.addedMembersMap.keys());
+ const removedIds = Array.from(this.removedMembersMap.keys());
+
+ await updateGroup(
+ this.group?.id,
+ this.title.trim(),
+ this.manager?.id,
+ addedIds,
+ removedIds,
+ );
+ } catch (e) {
+ console.log(e);
+ }
+ };
+
+ addManager = (manager: TUser) => {
+ this.removedMembersMap.delete(manager.id);
+ const alreadyMember = manager.groups?.find((g) => g.id === this.group?.id);
+
+ if (!alreadyMember) {
+ this.addedMembersMap.set(manager.id, manager);
+ }
+
+ if (this.members?.length) {
+ this.members = this.members.filter((member) => member.id !== manager.id);
+ }
+
+ this.manager = manager;
+ };
+
+ removeManager = () => {
+ if (!this.manager) return;
+
+ const wasAdded = this.addedMembersMap.delete(this.manager.id);
+
+ if (!wasAdded) {
+ this.removedMembersMap.set(this.manager.id, this.manager);
+ }
+
+ this.manager = null;
+ };
+
+ setIsInit = (value: boolean) => {
+ this.isInit = value;
+ };
+
+ setGroup = (group: TGroup) => {
+ this.group = group;
+ };
+
+ setTitle = (title: string) => {
+ this.title = title;
+ };
+
+ setManager = (manager: TUser | null) => {
+ this.manager = manager;
+ };
+
+ setMembers = (members: TUser[] | null) => {
+ this.members = members;
+ };
+
+ addMembers = (members: TUser[]) => {
+ members.forEach((member) => {
+ const wasRemoved = this.removedMembersMap.delete(member.id);
+
+ if (!wasRemoved) {
+ this.addedMembersMap.set(member.id, member);
+ }
+ });
+
+ this.members = this.members ? [...this.members, ...members] : members;
+ };
+
+ removeMember = (member: TUser) => {
+ const wasAdded = this.addedMembersMap.delete(member.id);
+
+ if (!wasAdded) {
+ this.removedMembersMap.set(member.id, member);
+ }
+
+ this.members = this.members?.filter((m) => m.id !== member.id) || null;
+ };
+
+ setInitialTotal = (total: number) => {
+ this.initialTotal = total;
+ };
+
+ get currentTotal() {
+ let total =
+ this.initialTotal +
+ this.addedMembersMap.size -
+ this.removedMembersMap.size;
+
+ const prevManager = this.group?.manager;
+ const newManager = this.manager;
+ const managerWasChanged = prevManager?.id !== newManager?.id;
+
+ if (prevManager && !managerWasChanged) {
+ total -= 1;
+ }
+
+ if (newManager && managerWasChanged) {
+ total -= 1;
+ }
+
+ return total;
+ }
+
+ get hasChanges() {
+ const titleWasChanged = this.title.trim() !== this.group?.name;
+ const managerWasChanged = this.group?.manager?.id !== this.manager?.id;
+
+ return (
+ titleWasChanged ||
+ managerWasChanged ||
+ this.addedMembersMap.size ||
+ this.removedMembersMap.size
+ );
+ }
+}
+
+export default EditGroupStore;
diff --git a/packages/client/src/store/FilesActionsStore.js b/packages/client/src/store/FilesActionsStore.js
index 11fc69fd0c..1349a9ec62 100644
--- a/packages/client/src/store/FilesActionsStore.js
+++ b/packages/client/src/store/FilesActionsStore.js
@@ -155,13 +155,6 @@ class FilesActionStore {
this.isBulkDownload = isBulkDownload;
};
- isMediaOpen = () => {
- const { visible, setMediaViewerData, playlist } = this.mediaViewerDataStore;
- if (visible && playlist.length === 1) {
- setMediaViewerData({ visible: false, id: null });
- }
- };
-
updateCurrentFolder = (fileIds, folderIds, clearSelection, operationId) => {
const { clearSecondaryProgressData } =
this.uploadDataStore.secondaryProgressDataStore;
@@ -390,8 +383,6 @@ class FilesActionStore {
addActiveItems(null, folderIds, destFolderId);
if (folderIds.length || fileIds.length) {
- this.isMediaOpen();
-
try {
this.filesStore.setOperationAction(true);
this.setGroupMenuBlocked(true);
@@ -852,7 +843,6 @@ class FilesActionStore {
if (isFile) {
addActiveItems([itemId], null, destFolderId);
- this.isMediaOpen();
return deleteFile(itemId)
.then(async (res) => {
if (res[0]?.error) return Promise.reject(res[0].error);
diff --git a/packages/client/src/store/GroupsStore.ts b/packages/client/src/store/GroupsStore.ts
index 398255f934..28a14c28b2 100644
--- a/packages/client/src/store/GroupsStore.ts
+++ b/packages/client/src/store/GroupsStore.ts
@@ -637,7 +637,7 @@ class GroupsStore {
updateGroup = async (
groupId: string,
groupName: string,
- groupManagerId: string,
+ groupManagerId: string | undefined,
membersToAdd: string[],
membersToRemove: string[],
) => {
diff --git a/packages/client/src/store/LdapFormStore.js b/packages/client/src/store/LdapFormStore.js
index 6417fd6efa..c725630f72 100644
--- a/packages/client/src/store/LdapFormStore.js
+++ b/packages/client/src/store/LdapFormStore.js
@@ -14,7 +14,6 @@ import delay from "lodash/delay";
import { toastr } from "@docspace/shared/components/toast";
const constants = {
- NULL_PERCENT: 0,
SSL_LDAP_PORT: 636,
DEFAULT_LDAP_PORT: 389,
GET_STATUS_TIMEOUT: 1000,
@@ -92,6 +91,8 @@ class LdapFormStore {
currentQuotaStore = null;
+ confirmationResetModal = false;
+
constructor(currentQuotaStore) {
makeAutoObservable(this);
@@ -604,6 +605,15 @@ class LdapFormStore {
setIsSslEnabled = (enabled) => {
this.isSslEnabled = enabled;
+
+ if (
+ this.requiredSettings.portNumber == constants.DEFAULT_LDAP_PORT ||
+ this.requiredSettings.portNumber == constants.SSL_LDAP_PORT
+ ) {
+ this.setPortNumber(
+ enabled ? constants.SSL_LDAP_PORT : constants.DEFAULT_LDAP_PORT,
+ );
+ }
};
get isCronEnabled() {
@@ -662,6 +672,14 @@ class LdapFormStore {
};
};
+ openResetModal = () => {
+ this.confirmationResetModal = true;
+ };
+
+ closeResetModal = () => {
+ this.confirmationResetModal = false;
+ };
+
get hasChanges() {
const settings = this.getSettings();
return !isEqual(settings, this.serverSettings);
diff --git a/packages/client/src/store/index.js b/packages/client/src/store/index.js
index 8d2478efe5..7a3f831d8d 100644
--- a/packages/client/src/store/index.js
+++ b/packages/client/src/store/index.js
@@ -80,6 +80,7 @@ import ImportAccountsStore from "./ImportAccountsStore";
import PluginStore from "./PluginStore";
import InfoPanelStore from "./InfoPanelStore";
import CampaignsStore from "./CampaignsStore";
+import EditGroupStore from "./EditGroupStore";
const selectedFolderStore = new SelectedFolderStore(settingsStore);
@@ -300,6 +301,8 @@ const storageManagement = new StorageManagement(
const campaignsStore = new CampaignsStore(settingsStore, userStore);
+const editGroupStore = new EditGroupStore(peopleStore);
+
const store = {
authStore,
userStore,
@@ -354,6 +357,7 @@ const store = {
pluginStore,
storageManagement,
campaignsStore,
+ editGroupStore,
};
export default store;
diff --git a/packages/login/src/app/(root)/layout.tsx b/packages/login/src/app/(root)/layout.tsx
index f3de5d58d0..53d1c7ae01 100644
--- a/packages/login/src/app/(root)/layout.tsx
+++ b/packages/login/src/app/(root)/layout.tsx
@@ -35,6 +35,7 @@ import SimpleNav from "@/components/SimpleNav";
import { LoginContent, LoginFormWrapper } from "@/components/Login";
import GreetingContainer from "@/components/GreetingContainer";
import { getColorTheme, getSettings } from "@/utils/actions";
+import { cookies } from "next/headers";
const LanguageComboboxWrapper = dynamic(
() => import("@/components/LanguageCombobox"),
@@ -59,9 +60,12 @@ export default async function Layout({
const isRegisterContainerVisible = objectSettings?.enabledJoin;
+ const culture =
+ cookies().get("asc_language")?.value ?? objectSettings?.culture;
+
return (
-
+
@@ -73,6 +77,7 @@ export default async function Layout({
>
{children}
diff --git a/packages/login/src/app/(root)/page.tsx b/packages/login/src/app/(root)/page.tsx
index 1a5de16d06..fe7451e38e 100644
--- a/packages/login/src/app/(root)/page.tsx
+++ b/packages/login/src/app/(root)/page.tsx
@@ -70,7 +70,7 @@ async function Page() {
reCaptchaPublicKey={settings?.recaptchaPublicKey}
reCaptchaType={settings?.recaptchaType}
ldapDomain={capabilities?.ldapDomain}
- ldapEnabled={capabilities?.ldapEnabled}
+ ldapEnabled={capabilities?.ldapEnabled || false}
/>
{
+const GreetingContainer = ({
+ greetingSettings,
+ culture,
+}: GreetingContainersProps) => {
const { t } = useTranslation(["Login"]);
const theme = useTheme();
- const logoUrl = getLogoUrl(WhiteLabelLogoType.LoginPage, !theme.isBase);
+ const logoUrl = getLogoUrl(
+ WhiteLabelLogoType.LoginPage,
+ !theme.isBase,
+ false,
+ culture,
+ );
const searchParams = useSearchParams();
diff --git a/packages/login/src/components/LoginForm/index.tsx b/packages/login/src/components/LoginForm/index.tsx
index f0aba58529..1910ebba51 100644
--- a/packages/login/src/components/LoginForm/index.tsx
+++ b/packages/login/src/components/LoginForm/index.tsx
@@ -112,7 +112,9 @@ const LoginForm = ({
const [password, setPassword] = useState("");
const [isChecked, setIsChecked] = useState(false);
- const [isLdapLoginChecked, setIsLdapLoginChecked] = useState(!!ldapDomain);
+ const [isLdapLoginChecked, setIsLdapLoginChecked] = useState(
+ ldapEnabled || false,
+ );
const [isCaptcha, setIsCaptcha] = useState(false);
const [isCaptchaSuccessful, setIsCaptchaSuccess] = useState(false);
const [isCaptchaError, setIsCaptchaError] = useState(false);
@@ -171,10 +173,6 @@ const LoginForm = ({
[t, referenceUrl, currentCulture],
);
- useEffect(() => {
- setIsLdapLoginChecked(!!ldapDomain);
- }, [ldapDomain]);
-
useEffect(() => {
const profile = localStorage.getItem("profile");
if (!profile) return;
diff --git a/packages/login/src/components/SimpleNav.tsx b/packages/login/src/components/SimpleNav.tsx
index f780bdb2da..4d50449a8a 100644
--- a/packages/login/src/components/SimpleNav.tsx
+++ b/packages/login/src/components/SimpleNav.tsx
@@ -61,19 +61,26 @@ const StyledSimpleNav = styled.div`
StyledSimpleNav.defaultProps = { theme: Base };
-interface SimpleNavProps {}
+interface SimpleNavProps {
+ culture?: string;
+}
-const SimpleNav = ({}: SimpleNavProps) => {
+const SimpleNav = ({ culture }: SimpleNavProps) => {
const theme = useTheme();
const isDark = !theme.isBase;
- const logoUrl = getLogoUrl(WhiteLabelLogoType.LightSmall, isDark);
+ const logoUrl = getLogoUrl(
+ WhiteLabelLogoType.LightSmall,
+ isDark,
+ false,
+ culture,
+ );
return (
);
};
diff --git a/packages/login/src/types/index.ts b/packages/login/src/types/index.ts
index bb4e03db09..d804405148 100644
--- a/packages/login/src/types/index.ts
+++ b/packages/login/src/types/index.ts
@@ -43,6 +43,7 @@ export type TDataContext = {
export type GreetingContainersProps = {
greetingSettings?: string;
+ culture?: string;
};
export type LoginProps = {
diff --git a/packages/management/src/categories/spaces/sub-components/RowView/RoomContent.tsx b/packages/management/src/categories/spaces/sub-components/RowView/RoomContent.tsx
index 4ec1006a3c..54831deb73 100644
--- a/packages/management/src/categories/spaces/sub-components/RowView/RoomContent.tsx
+++ b/packages/management/src/categories/spaces/sub-components/RowView/RoomContent.tsx
@@ -26,20 +26,17 @@
import React from "react";
import { useTranslation } from "react-i18next";
+import styled from "styled-components";
+
import { RowContent } from "@docspace/shared/components/row-content";
import { Text } from "@docspace/shared/components/text";
-import styled, { css } from "styled-components";
-import { isMobileOnly } from "react-device-detect";
import { getConvertedSize } from "@docspace/shared/utils/common";
+import { mobile } from "@docspace/shared/utils";
import { TPortals } from "SRC_DIR/types/spaces";
const StyledRowContent = styled(RowContent)`
padding-bottom: 10px;
.row-main-container-wrapper {
- ${isMobileOnly &&
- css`
- margin-top: 14px;
- `}
display: flex;
justify-content: flex-start;
}
@@ -47,6 +44,16 @@ const StyledRowContent = styled(RowContent)`
.mainIcons {
height: 20px;
}
+
+ @media ${mobile} {
+ .row-main-container-wrapper {
+ flex-direction: column;
+ }
+
+ .mainIcons {
+ align-self: flex-start;
+ }
+ }
`;
type TRoomContent = {
diff --git a/packages/shared/api/groups/index.ts b/packages/shared/api/groups/index.ts
index e9f642f9cf..3b54cba3b1 100644
--- a/packages/shared/api/groups/index.ts
+++ b/packages/shared/api/groups/index.ts
@@ -38,7 +38,7 @@ import {
export const createGroup = (
groupName: string,
- groupManager: string,
+ groupManager: string | undefined,
members: string[],
) => {
return request({
@@ -49,7 +49,7 @@ export const createGroup = (
groupManager,
members,
},
- });
+ }) as Promise;
};
// * Read
@@ -69,12 +69,16 @@ export const getGroups = (filter = Filter.getDefault()) => {
});
};
-export const getGroupById = (groupId: string, signal: AbortSignal) => {
+export const getGroupById = (
+ groupId: string,
+ includeMembers: boolean = false,
+ signal?: AbortSignal,
+) => {
return request({
method: "get",
- url: `/group/${groupId}`,
+ url: `/group/${groupId}?includeMembers=${includeMembers}`,
signal,
- });
+ }) as Promise;
};
export const getGroupsByName = async (
@@ -123,7 +127,7 @@ export const getGroupMembersInRoom = (
export const updateGroup = (
groupId: string,
groupName: string,
- groupManager: string,
+ groupManager: string | undefined,
membersToAdd: string[],
membersToRemove: string[],
) => {
diff --git a/packages/shared/api/groups/types.ts b/packages/shared/api/groups/types.ts
index 1669911d06..04ed62ef9c 100644
--- a/packages/shared/api/groups/types.ts
+++ b/packages/shared/api/groups/types.ts
@@ -30,10 +30,11 @@ import { ShareAccessRights } from "../../enums";
export type TGroup = {
category: string;
id: string;
- manager: TUser;
+ manager?: TUser;
name: string;
parent: string;
isGroup?: boolean;
+ members?: TUser[];
membersCount: number;
shared?: boolean;
isLDAP: boolean;
diff --git a/packages/shared/api/settings/index.ts b/packages/shared/api/settings/index.ts
index 8f3b5919ba..395c38dbad 100644
--- a/packages/shared/api/settings/index.ts
+++ b/packages/shared/api/settings/index.ts
@@ -407,16 +407,10 @@ export async function getCustomSchemaList() {
}
export function setAdditionalResources(
- feedbackAndSupportEnabled,
- videoGuidesEnabled,
- helpCenterEnabled,
+ additionalResources: TAdditionalResources,
) {
const data = {
- settings: {
- helpCenterEnabled,
- feedbackAndSupportEnabled,
- videoGuidesEnabled,
- },
+ settings: additionalResources,
};
return request({
diff --git a/packages/shared/components/drop-down/DropDown.styled.ts b/packages/shared/components/drop-down/DropDown.styled.ts
index 69bd55f1c1..4fa68fb4af 100644
--- a/packages/shared/components/drop-down/DropDown.styled.ts
+++ b/packages/shared/components/drop-down/DropDown.styled.ts
@@ -93,6 +93,7 @@ const StyledDropdown = styled.div<{
props.zIndex ? props.zIndex : props.theme.dropDown.zIndex};
display: ${(props) =>
props.open ? (props.columnCount ? "block" : "table") : "none"};
+ table-layout: fixed;
${(props) =>
!props.isDropdownReady &&
@@ -105,7 +106,7 @@ const StyledDropdown = styled.div<{
border: ${(props) => props.theme.dropDown.border};
border-radius: ${(props) => props.theme.dropDown.borderRadius};
-moz-border-radius: ${(props) => props.theme.dropDown.borderRadius};
- -webkit-border-radius: ${(props) => props.theme.dropDown.borderRadius};
+ -webkit-border-radius: ${(props) => props.theme.dropDown.borderRadius};dropDownMaxHeight
box-shadow: ${(props) => props.theme.dropDown.boxShadow};
-moz-box-shadow: ${(props) => props.theme.dropDown.boxShadow};
-webkit-box-shadow: ${(props) => props.theme.dropDown.boxShadow};
diff --git a/packages/shared/components/language-combobox/LanguageCombobox.tsx b/packages/shared/components/language-combobox/LanguageCombobox.tsx
index 27b2a2864a..d28925944c 100644
--- a/packages/shared/components/language-combobox/LanguageCombobox.tsx
+++ b/packages/shared/components/language-combobox/LanguageCombobox.tsx
@@ -74,7 +74,7 @@ const LanguageCombobox = (props: ComboboxProps) => {
dropDownMaxHeight={300}
fillIcon={false}
displaySelectedOption
- manualWidth="41px"
+ manualWidth="42px"
noBorder={false}
type="onlyIcon"
optionStyle={{ padding: "0 8px" }}
diff --git a/packages/shared/components/selector/Selector.types.ts b/packages/shared/components/selector/Selector.types.ts
index 29bfd0a026..1e3714a6e4 100644
--- a/packages/shared/components/selector/Selector.types.ts
+++ b/packages/shared/components/selector/Selector.types.ts
@@ -30,6 +30,7 @@ import { MergeTypes, Nullable } from "../../types";
import { TFileSecurity, TFolderSecurity } from "../../api/files/types";
import { TRoomSecurity } from "../../api/rooms/types";
+import { TGroup } from "../../api/groups/types";
import { AvatarRole } from "../avatar";
import { TTabItem } from "../tabs";
@@ -394,6 +395,7 @@ type TSelectorItemEmpty = {
iconOriginal?: undefined;
role?: undefined;
email?: undefined;
+ groups?: TGroup[];
isOwner?: undefined;
isAdmin?: undefined;
isVisitor?: undefined;
@@ -438,6 +440,7 @@ export type TSelectorItemUser = MergeTypes<
avatar: string;
hasAvatar: boolean;
role: AvatarRole;
+ groups?: TGroup[];
access?: ShareAccessRights | string | number;
}
diff --git a/packages/shared/components/table/TableHeader.tsx b/packages/shared/components/table/TableHeader.tsx
index 5bd6bd2cab..64a988c352 100644
--- a/packages/shared/components/table/TableHeader.tsx
+++ b/packages/shared/components/table/TableHeader.tsx
@@ -232,6 +232,12 @@ class TableHeaderComponent extends React.Component<
const maxSize = Math.max.apply(Math, clearSize);
const defaultSize = columns[activeColumnIndex - 1].defaultSize;
+
+ if (!Array.isArray(clearSize)) {
+ console.log("addNewColumns clearSize", clearSize);
+ return true;
+ }
+
const indexOfMaxSize = clearSize.findLastIndex((s) => s === maxSize);
const addedColumn = 1;
diff --git a/packages/shared/utils/common.ts b/packages/shared/utils/common.ts
index 2a152dd527..45f76ffc1c 100644
--- a/packages/shared/utils/common.ts
+++ b/packages/shared/utils/common.ts
@@ -1103,8 +1103,9 @@ export function getLogoUrl(
logoType: WhiteLabelLogoType,
dark: boolean = false,
def: boolean = false,
+ culture?: string,
) {
- return `/logo.ashx?logotype=${logoType}&dark=${dark}&default=${def}`;
+ return `/logo.ashx?logotype=${logoType}&dark=${dark}&default=${def}${culture ? `&culture=${culture}` : ""}`;
}
export const getUserTypeName = (
diff --git a/public/locales/ar-SA/Common.json b/public/locales/ar-SA/Common.json
index aa9d668da1..1b3e9c49a3 100644
--- a/public/locales/ar-SA/Common.json
+++ b/public/locales/ar-SA/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "من نحن",
"AboutCompanyTitle": "نبذة تعريفية عن البرنامج",
"AccessDenied": "المحاولة مرفوضة",
@@ -55,6 +55,7 @@
"CommonFiles": "الملفات المشتركة",
"CompanyName": "اسم الشركة",
"Confirmation": "تأكيد",
+ "ConfirmationText": "سيتم فقدان جميع البيانات التي أدخلتها. هل أنت متأكد أنك ترغب في المتابعة؟",
"ConflictResolveSelectAction": "الرجاء تحديد الإجراء:",
"Connect": "ربط",
"Content": "المحتوى",
@@ -509,4 +510,4 @@
"Yes": "نعم",
"Yesterday": "أمس",
"You": "أنت"
-}
+}
\ No newline at end of file
diff --git a/public/locales/az/Common.json b/public/locales/az/Common.json
index be8de6f1cb..6baca3a7d9 100644
--- a/public/locales/az/Common.json
+++ b/public/locales/az/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Haqqında",
"AboutCompanyTitle": "Proqram haqqında",
"AccessDenied": "Giriş qadağandır",
@@ -55,6 +55,7 @@
"CommonFiles": "Ümumi fayllar",
"CompanyName": "Şirkət adı",
"Confirmation": "Təsdiqləmə",
+ "ConfirmationText": "Daxil etdiyiniz bütün məlumatlar itiriləcək. Davam etmək istədiyinizə əminsiniz?",
"ConflictResolveSelectAction": "Xahiş edirik əməliyyatı seçin:",
"Connect": "Qoşulmaq",
"Content": "Kontent",
@@ -509,4 +510,4 @@
"Yes": "Bəli",
"Yesterday": "Dünən",
"You": "Siz"
-}
+}
\ No newline at end of file
diff --git a/public/locales/bg/Common.json b/public/locales/bg/Common.json
index 961a3772ed..d437cf79b7 100644
--- a/public/locales/bg/Common.json
+++ b/public/locales/bg/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Относно",
"AboutCompanyTitle": "За тази програма",
"AccessDenied": "Достъпът отказан",
@@ -55,6 +55,7 @@
"CommonFiles": "Общи файлове",
"CompanyName": "Име на фирмата",
"Confirmation": "Потвърждение",
+ "ConfirmationText": "Всички въведени от вас данни ще бъдат загубени. Сигурни ли сте, че искате да продължите?",
"ConflictResolveSelectAction": "Моля, изберете действие:",
"Connect": "Свържи",
"Content": "Съдържание",
@@ -509,4 +510,4 @@
"Yes": "Да",
"Yesterday": "Вчера",
"You": "Вие"
-}
+}
\ No newline at end of file
diff --git a/public/locales/cs/Common.json b/public/locales/cs/Common.json
index 41c4874d38..a8c0bf7c4b 100644
--- a/public/locales/cs/Common.json
+++ b/public/locales/cs/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "O nás",
"AboutCompanyTitle": "O tomto programu",
"AccessDenied": "Přístup odepřen",
@@ -55,6 +55,7 @@
"CommonFiles": "Společné soubory",
"CompanyName": "Název společnosti",
"Confirmation": "Potvrzení",
+ "ConfirmationText": "Všechna zadaná data budou ztracena. Určitě chcete pokračovat?",
"ConflictResolveSelectAction": "Prosím, vyberte akci:",
"Connect": "Připojit",
"Content": "Obsah",
@@ -509,4 +510,4 @@
"Yes": "Ano",
"Yesterday": "Včera",
"You": "Vy"
-}
+}
\ No newline at end of file
diff --git a/public/locales/de/Common.json b/public/locales/de/Common.json
index 0c663b1fee..cbfe9f04d2 100644
--- a/public/locales/de/Common.json
+++ b/public/locales/de/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Informationen",
"AboutCompanyTitle": "Über diese Software",
"AccessDenied": "Zugriff verweigert",
@@ -55,6 +55,7 @@
"CommonFiles": "Gemeinsame Dateien",
"CompanyName": "Name des Unternehmens",
"Confirmation": "Bestätigung",
+ "ConfirmationText": "Alle von Ihnen eingegebenen Daten gehen verloren. Sind Sie sicher, dass Sie fortfahren möchten?",
"ConflictResolveSelectAction": "Bitte wählen Sie die Aktion aus:",
"Connect": "Verbinden",
"Content": "Inhalt",
@@ -509,4 +510,4 @@
"Yes": "Ja",
"Yesterday": "Gestern",
"You": "Sie"
-}
+}
\ No newline at end of file
diff --git a/public/locales/el-GR/Common.json b/public/locales/el-GR/Common.json
index 683ff35db8..2bac1fddcf 100644
--- a/public/locales/el-GR/Common.json
+++ b/public/locales/el-GR/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Σχετικά",
"AboutCompanyTitle": "Σχετικά με αυτό το πρόγραμμα",
"AccessDenied": "Απαγόρευση πρόσβασης",
@@ -55,6 +55,7 @@
"CommonFiles": "Κοινά αρχε",
"CompanyName": "Όνομα εταιρείας",
"Confirmation": "Επιβεβαίωση",
+ "ConfirmationText": "Όλα τα δεδομένα που έχετε εισάγει θα χαθούν. Θέλετε σίγουρα να συνεχίσετε;",
"ConflictResolveSelectAction": "Επιλέξτε την ενέργεια",
"Connect": "Σύνδεση",
"Content": "Περιεχόμενο",
@@ -509,4 +510,4 @@
"Yes": "Ναι",
"Yesterday": "Χθες",
"You": "Εσείς"
-}
+}
\ No newline at end of file
diff --git a/public/locales/en/Common.json b/public/locales/en/Common.json
index 61acc3af18..d38ffc9648 100644
--- a/public/locales/en/Common.json
+++ b/public/locales/en/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "About",
"AboutCompanyTitle": "About this program",
"AccessDenied": "Access denied",
@@ -55,6 +55,7 @@
"CommonFiles": "Common files",
"CompanyName": "Company name",
"Confirmation": "Confirmation",
+ "ConfirmationText": "All the data you entered will be lost. Are you sure you want to continue?",
"ConflictResolveSelectAction": "Please select the action:",
"Connect": "Connect",
"Content": "Content",
@@ -509,4 +510,4 @@
"Yes": "Yes",
"Yesterday": "Yesterday",
"You": "You"
-}
+}
\ No newline at end of file
diff --git a/public/locales/es/Common.json b/public/locales/es/Common.json
index e852d72f73..b0a4df3cfb 100644
--- a/public/locales/es/Common.json
+++ b/public/locales/es/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Acerca de",
"AboutCompanyTitle": "Acerca del programa",
"AccessDenied": "Acceso denegado ",
@@ -55,6 +55,7 @@
"CommonFiles": "Archivos comunes",
"CompanyName": "Nombre de empresa",
"Confirmation": "Confirmación",
+ "ConfirmationText": "Se perderán todos los datos introducidos. ¿Está seguro de que desea continuar?",
"ConflictResolveSelectAction": "Por favor, seleccione la acción:",
"Connect": "Conectar",
"Content": "Contenido",
@@ -509,4 +510,4 @@
"Yes": "Sí",
"Yesterday": "Ayer",
"You": "Usted"
-}
+}
\ No newline at end of file
diff --git a/public/locales/fi/Common.json b/public/locales/fi/Common.json
index e41b00dd63..175a2bf32a 100644
--- a/public/locales/fi/Common.json
+++ b/public/locales/fi/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Tietoja",
"AboutCompanyTitle": "Tietoja tästä ohjelmasta",
"AccessDenied": "Pääsy evätty",
@@ -55,6 +55,7 @@
"CommonFiles": "Yleiset kansiot",
"CompanyName": "Yrityksen nimi",
"Confirmation": "Vahvistus",
+ "ConfirmationText": "Kaikki syöttämäsi tieto menetetään. Haluatko varmasti jatkaa?",
"ConflictResolveSelectAction": "Valitse toiminto:",
"Connect": "Yhdistä",
"Content": "Sisältö",
@@ -509,4 +510,4 @@
"Yes": "Kyllä",
"Yesterday": "Eilen",
"You": "Sinä"
-}
+}
\ No newline at end of file
diff --git a/public/locales/fr/Common.json b/public/locales/fr/Common.json
index b25fc44048..c71ebede5b 100644
--- a/public/locales/fr/Common.json
+++ b/public/locales/fr/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "À propos de",
"AboutCompanyTitle": "À propos de ce programme",
"AccessDenied": " Accès refusé",
@@ -55,6 +55,7 @@
"CommonFiles": "Fichiers communs",
"CompanyName": "Nom de l'entreprise",
"Confirmation": "Confirmation",
+ "ConfirmationText": "Toutes les données que vous avez saisies seront perdues. Êtes-vous sûr de vouloir continuer ?",
"ConflictResolveSelectAction": "Veuillez sélectionner une action :",
"Connect": "Connexion",
"Content": "Contenu",
@@ -509,4 +510,4 @@
"Yes": "Oui",
"Yesterday": "Hier",
"You": "Vous"
-}
+}
\ No newline at end of file
diff --git a/public/locales/hy-AM/Common.json b/public/locales/hy-AM/Common.json
index b6e8a5130a..4f1a029d32 100644
--- a/public/locales/hy-AM/Common.json
+++ b/public/locales/hy-AM/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Մասին",
"AboutCompanyTitle": "Ծրագրի մասին",
"AccessDenied": "Մուտքն արգելված է",
@@ -55,6 +55,7 @@
"CommonFiles": "Ընդհանուր ֆայլեր",
"CompanyName": "Ընկերության անվանում",
"Confirmation": "Հաստատում",
+ "ConfirmationText": "Ձեր մուտքագրած բոլոր տվյալները կկորչեն: Վստա՞հ եք, որ ցանկանում եք շարունակել:",
"ConflictResolveSelectAction": "Խնդրում ենք ընտրել գործողությունը:",
"Connect": "Կապակցվել",
"Content": "Բովանդակություն",
@@ -509,4 +510,4 @@
"Yes": "Այո",
"Yesterday": "Երեկ",
"You": "Դու"
-}
+}
\ No newline at end of file
diff --git a/public/locales/it/Common.json b/public/locales/it/Common.json
index 8e3d9eda21..3f7e0116ce 100644
--- a/public/locales/it/Common.json
+++ b/public/locales/it/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Informazioni su",
"AboutCompanyTitle": "Informazioni sul programma",
"AccessDenied": " Accesso negato",
@@ -55,6 +55,7 @@
"CommonFiles": "File comuni",
"CompanyName": "Nome azienda",
"Confirmation": "Conferma",
+ "ConfirmationText": "Tutti i dati inseriti andranno persi. Sei sicuro di voler continuare?",
"ConflictResolveSelectAction": "Ti preghiamo di selezionare l'azione:",
"Connect": "Collega",
"Content": "Contenuto",
@@ -509,4 +510,4 @@
"Yes": "Sì",
"Yesterday": "Ieri",
"You": "Tu"
-}
+}
\ No newline at end of file
diff --git a/public/locales/ja-JP/Common.json b/public/locales/ja-JP/Common.json
index 2cfd2d7873..fda90cc230 100644
--- a/public/locales/ja-JP/Common.json
+++ b/public/locales/ja-JP/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "について",
"AboutCompanyTitle": "本プログラムについて",
"AccessDenied": "アクセス拒否",
@@ -55,6 +55,7 @@
"CommonFiles": "共通のファイル",
"CompanyName": "企業名",
"Confirmation": "確認事項",
+ "ConfirmationText": "入力したデータはすべて失われます。このまま続けますか?",
"ConflictResolveSelectAction": "アクションをお選びください:",
"Connect": "接続",
"Content": "コンテンツ",
@@ -509,4 +510,4 @@
"Yes": "はい",
"Yesterday": "昨日",
"You": "あなた"
-}
+}
\ No newline at end of file
diff --git a/public/locales/ko-KR/Common.json b/public/locales/ko-KR/Common.json
index 12837a9a74..aeca1319d6 100644
--- a/public/locales/ko-KR/Common.json
+++ b/public/locales/ko-KR/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "소개",
"AboutCompanyTitle": "프로그램 소개",
"AccessDenied": "액세스가 거부되었습니다",
@@ -55,6 +55,7 @@
"CommonFiles": "공통 파일",
"CompanyName": "회사 이름",
"Confirmation": "확인",
+ "ConfirmationText": "입력한 모든 데이터가 손실됩니다. 정말로 계속하시겠습니까?",
"ConflictResolveSelectAction": "작업 선택:",
"Connect": "연결",
"Content": "콘텐츠",
@@ -509,4 +510,4 @@
"Yes": "네",
"Yesterday": "어제",
"You": "나"
-}
+}
\ No newline at end of file
diff --git a/public/locales/lo-LA/Common.json b/public/locales/lo-LA/Common.json
index fb81799148..ff03bbc147 100644
--- a/public/locales/lo-LA/Common.json
+++ b/public/locales/lo-LA/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "ກ່ຽວກັບ",
"AboutCompanyTitle": "ກ່ຽວກັບໂປແກລມນີ້",
"AccessDenied": "ປະຕິເສດການເຂົ້າເຖິງ",
@@ -51,6 +51,7 @@
"CommonFiles": "ໄຟລ໌ທົ່ວໄປ",
"CompanyName": "ຊື່ບໍລິສັດ",
"Confirmation": "ການຢັ້ງຢືນຕົວຕົນ",
+ "ConfirmationText": "ຂໍ້ມູນທັງໝົດທີ່ທ່ານປ້ອນເຂົ້າຈະສູນເສຍໄປ. ທ່ານແນ່ໃຈບໍ່ວ່າຕ້ອງການສືບຕໍ່?",
"ConflictResolveSelectAction": "ກະລຸນາເລືອກການດຳເນີນການ",
"Connect": "ຕິດຕໍ່",
"Content": "ເນື້ອຫາ",
@@ -374,4 +375,4 @@
"Warning": "ແຈ້ງເຕືອນ",
"Website": "ເວັບໄຊທ໌",
"Yesterday": "ມື້ວານນີ້"
-}
+}
\ No newline at end of file
diff --git a/public/locales/lv/Common.json b/public/locales/lv/Common.json
index 97673c93e5..51a6af60f3 100644
--- a/public/locales/lv/Common.json
+++ b/public/locales/lv/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Par",
"AboutCompanyTitle": "Par šo programmu",
"AccessDenied": "Pieeja ir liegta",
@@ -55,6 +55,7 @@
"CommonFiles": "Kopīgi faili",
"CompanyName": "Uzņēmuma nosaukums",
"Confirmation": "Apstiprinājums",
+ "ConfirmationText": "Visi ievadītie dati tiks zaudēti. Vai tiešām vēlaties turpināt?",
"ConflictResolveSelectAction": "Lūdzu, atlasiet darbību:",
"Connect": "Savienot",
"Content": "Saturs",
@@ -509,4 +510,4 @@
"Yes": "Jā",
"Yesterday": "어제",
"You": "Jūs"
-}
+}
\ No newline at end of file
diff --git a/public/locales/nl/Common.json b/public/locales/nl/Common.json
index 2991c496e4..e280355d30 100644
--- a/public/locales/nl/Common.json
+++ b/public/locales/nl/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Over",
"AboutCompanyTitle": "Over dit programma",
"AccessDenied": "Toegang geweigerd",
@@ -55,6 +55,7 @@
"CommonFiles": "Algemene bestanden",
"CompanyName": "Bedrijfsnaam",
"Confirmation": "Bevestiging",
+ "ConfirmationText": "Alle ingevoerde gegevens gaan verloren. Weet u zeker dat u door wilt gaan?",
"ConflictResolveSelectAction": "Kies de actie:",
"Connect": "Verbinden",
"Content": "Inhoud",
@@ -509,4 +510,4 @@
"Yes": "Ja",
"Yesterday": "Gisteren",
"You": "U"
-}
+}
\ No newline at end of file
diff --git a/public/locales/pl/Common.json b/public/locales/pl/Common.json
index 1863e57a33..7907beb3ba 100644
--- a/public/locales/pl/Common.json
+++ b/public/locales/pl/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "O",
"AboutCompanyTitle": "O tym programie",
"AccessDenied": "Odmowa dostępu",
@@ -55,6 +55,7 @@
"CommonFiles": "Wspólne pliki",
"CompanyName": "Nama Perusahaan",
"Confirmation": "Potwierdzenie",
+ "ConfirmationText": "Wszystkie wprowadzone dane zostaną utracone. Czy na pewno chcesz kontynuować?",
"ConflictResolveSelectAction": "Wybierz działanie:",
"Connect": "Podłącz",
"Content": "Treść",
@@ -509,4 +510,4 @@
"Yes": "Tak",
"Yesterday": "Wczoraj",
"You": "Ty"
-}
+}
\ No newline at end of file
diff --git a/public/locales/pt-BR/Common.json b/public/locales/pt-BR/Common.json
index 0263297711..b27ed9c3f2 100644
--- a/public/locales/pt-BR/Common.json
+++ b/public/locales/pt-BR/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Sobre",
"AboutCompanyTitle": "Sobre este programa",
"AccessDenied": "Acesso negado",
@@ -55,6 +55,7 @@
"CommonFiles": "Arquivos comuns",
"CompanyName": "Nome da empresa",
"Confirmation": "Confirmação",
+ "ConfirmationText": "Todos os dados inseridos serão perdidos. Você tem certeza que quer continuar?",
"ConflictResolveSelectAction": "Selecione a ação:",
"Connect": "Conectar",
"Content": "Conteúdo",
@@ -509,4 +510,4 @@
"Yes": "Sim",
"Yesterday": "Ontem",
"You": "Você"
-}
+}
\ No newline at end of file
diff --git a/public/locales/pt/Common.json b/public/locales/pt/Common.json
index 1404599e99..572fd9634b 100644
--- a/public/locales/pt/Common.json
+++ b/public/locales/pt/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Sobre",
"AboutCompanyTitle": "Sobre este programa",
"AccessDenied": "Acesso negado",
@@ -55,6 +55,7 @@
"CommonFiles": "Arquivos comuns",
"CompanyName": "Nome da empresa",
"Confirmation": "Confirmação",
+ "ConfirmationText": "Todos os dados que introduziu serão perdidos. Tem a certeza que quer proceder?",
"ConflictResolveSelectAction": "Selecione a ação:",
"Connect": "Ligar",
"Content": "Conteúdo",
@@ -509,4 +510,4 @@
"Yes": "Sim",
"Yesterday": "Ontem",
"You": "Você"
-}
+}
\ No newline at end of file
diff --git a/public/locales/ro/Common.json b/public/locales/ro/Common.json
index e11685fcd3..2085087a1d 100644
--- a/public/locales/ro/Common.json
+++ b/public/locales/ro/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Informații",
"AboutCompanyTitle": "Despre aplicația",
"AccessDenied": "Acces refuzat ",
@@ -55,6 +55,7 @@
"CommonFiles": "Fișiere comune",
"CompanyName": "Numele companiei",
"Confirmation": "Confirmare",
+ "ConfirmationText": "Toate datele introduse se vor pierde. Sigur doriţi să continuați?",
"ConflictResolveSelectAction": "Selectați acțiune:",
"Connect": "Adaugă cont",
"Content": "Conținut",
@@ -509,4 +510,4 @@
"Yes": "Da",
"Yesterday": "Ieri",
"You": "Dvs"
-}
+}
\ No newline at end of file
diff --git a/public/locales/ru/Common.json b/public/locales/ru/Common.json
index 1103421604..383bc97209 100644
--- a/public/locales/ru/Common.json
+++ b/public/locales/ru/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "О программе",
"AboutCompanyTitle": "О программе",
"AccessDenied": "Доступ запрещен",
@@ -55,6 +55,7 @@
"CommonFiles": "Общие файлы",
"CompanyName": "Название компании",
"Confirmation": "Подтверждение",
+ "ConfirmationText": "Все введенные данные будут потеряны. Вы уверены, что хотите продолжить?",
"ConflictResolveSelectAction": "Пожалуйста, выберите действие:",
"Connect": "Подключить",
"Content": "Контент",
@@ -509,4 +510,4 @@
"Yes": "Да",
"Yesterday": "Вчера",
"You": "Вы"
-}
+}
\ No newline at end of file
diff --git a/public/locales/si/Common.json b/public/locales/si/Common.json
index edb6f1ee04..7dbe838614 100644
--- a/public/locales/si/Common.json
+++ b/public/locales/si/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "පිළිබඳව",
"AboutCompanyTitle": "මෙම මෘදුකාංගය ගැන",
"AccessDenied": "ප්රවේශය ප්රතික්ෂේපිතයි",
@@ -51,6 +51,7 @@
"CommonFiles": "සාමාන්ය ගොනු",
"CompanyName": "සමාගමේ නම",
"Confirmation": "තහවුරු කිරීම",
+ "ConfirmationText": "ඔබ ඇතුල් කළ සියළුම දත්ත නැති වී යනු ඇත. ඔබට ඉදිරියට යාමට වුවමනා ද?",
"ConflictResolveSelectAction": "ක්රියාමාර්ගය තෝරන්න:",
"Connect": "සබඳින්න",
"Content": "අන්තර්ගතය",
@@ -457,4 +458,4 @@
"Yes": "ඔව්",
"Yesterday": "ඊයේ",
"You": "ඔබ"
-}
+}
\ No newline at end of file
diff --git a/public/locales/sk/Common.json b/public/locales/sk/Common.json
index aa3cb0f96b..15aebb9ab3 100644
--- a/public/locales/sk/Common.json
+++ b/public/locales/sk/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "O aplikácii",
"AboutCompanyTitle": "O programe",
"AccessDenied": "Prístup bol zamietnutý",
@@ -55,6 +55,7 @@
"CommonFiles": "Spoločné súbory",
"CompanyName": "Meno spoločnosti",
"Confirmation": "Potvrdenie",
+ "ConfirmationText": "Všetky zadané údaje sa stratia. Ste si istý, že chcete pokračovať?",
"ConflictResolveSelectAction": "Vyberte akciu:",
"Connect": "Pripojiť",
"Content": "Obsah",
@@ -509,4 +510,4 @@
"Yes": "Áno",
"Yesterday": "Včera",
"You": "Vy"
-}
+}
\ No newline at end of file
diff --git a/public/locales/sl/Common.json b/public/locales/sl/Common.json
index b135af0330..f8e30ae8e6 100644
--- a/public/locales/sl/Common.json
+++ b/public/locales/sl/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "O nas",
"AboutCompanyTitle": "O tem programu",
"AccessDenied": "Dostop je zavrnjen",
@@ -55,6 +55,7 @@
"CommonFiles": "Skupne datoteke",
"CompanyName": "Ime podjetja",
"Confirmation": "Potrditev",
+ "ConfirmationText": "Vsi vneseni podatki bodo izgubljeni. Ali ste prepričani, da želite nadaljevati?",
"ConflictResolveSelectAction": "Prosim, izberite akcijo:",
"Connect": "Poveži",
"Content": "Vsebina",
@@ -509,4 +510,4 @@
"Yes": "Da",
"Yesterday": "Včeraj",
"You": "Vi"
-}
+}
\ No newline at end of file
diff --git a/public/locales/sr-Cyrl-RS/Common.json b/public/locales/sr-Cyrl-RS/Common.json
index 6c73a169a2..fdfa6a0e70 100644
--- a/public/locales/sr-Cyrl-RS/Common.json
+++ b/public/locales/sr-Cyrl-RS/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "У вези са",
"AboutCompanyTitle": "У вези овог програма",
"AccessDenied": "Приступ одбијен",
@@ -55,6 +55,7 @@
"CommonFiles": "Заједничке датотеке",
"CompanyName": "Име компаније",
"Confirmation": "Конфирмација",
+ "ConfirmationText": "Сви подаци које сте унели ће бити изгубљени. Да ли сте сигурни да желите да наставите?",
"ConflictResolveSelectAction": "Изаберите радњу:",
"Connect": "Повежи",
"Content": "Садржај",
@@ -509,4 +510,4 @@
"Yes": "Да",
"Yesterday": "Јуче",
"You": "Ви"
-}
+}
\ No newline at end of file
diff --git a/public/locales/sr-Latn-RS/Common.json b/public/locales/sr-Latn-RS/Common.json
index f71b0f1b8c..55d459d457 100644
--- a/public/locales/sr-Latn-RS/Common.json
+++ b/public/locales/sr-Latn-RS/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "U vezi sa",
"AboutCompanyTitle": "U vezi ovog programa",
"AccessDenied": "Pristup odbijen",
@@ -55,6 +55,7 @@
"CommonFiles": "Zajedničke datoteke",
"CompanyName": "Ime kompanije",
"Confirmation": "Konfirmacija",
+ "ConfirmationText": "Svi podaci koje ste uneli će biti izgubljeni. Da li ste sigurni da želite da nastavite?",
"ConflictResolveSelectAction": "Molim vas odaberite akciju:",
"Connect": "Poveži",
"Content": "Sadržaj",
@@ -509,4 +510,4 @@
"Yes": "Da",
"Yesterday": "Juče",
"You": "Vi"
-}
+}
\ No newline at end of file
diff --git a/public/locales/tr/Common.json b/public/locales/tr/Common.json
index abb6fb192f..cf6142204d 100644
--- a/public/locales/tr/Common.json
+++ b/public/locales/tr/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Hakkında",
"AboutCompanyTitle": "Bu program hakkında",
"AccessDenied": "Erişim engellendi",
@@ -55,6 +55,7 @@
"CommonFiles": "Ortak dosyalar",
"CompanyName": "Şirket ismi",
"Confirmation": "Onay",
+ "ConfirmationText": "Girdiğiniz tüm veriler kaybolacak. Devam etmek istediğinize emin misiniz?",
"ConflictResolveSelectAction": "Lütfen işlemi seçin:",
"Connect": "Bağlan",
"Content": "İçerik",
@@ -509,4 +510,4 @@
"Yes": "Evet",
"Yesterday": "Dün",
"You": "Siz"
-}
+}
\ No newline at end of file
diff --git a/public/locales/uk-UA/Common.json b/public/locales/uk-UA/Common.json
index 3ed9bd6a5f..1f0cb6242a 100644
--- a/public/locales/uk-UA/Common.json
+++ b/public/locales/uk-UA/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Інформація",
"AboutCompanyTitle": "Про цю програму",
"AccessDenied": "Доступ заборонено",
@@ -55,6 +55,7 @@
"CommonFiles": "Загальні файли",
"CompanyName": "Назва компанії",
"Confirmation": "Підтвердження",
+ "ConfirmationText": "Усі введені вами дані буде втрачено. Ви впевнені, що бажаєте продовжити?",
"ConflictResolveSelectAction": "Оберіть дію:",
"Connect": "Підключити",
"Content": "Зміст",
@@ -509,4 +510,4 @@
"Yes": "Так",
"Yesterday": "Вчора",
"You": "Ви"
-}
+}
\ No newline at end of file
diff --git a/public/locales/vi/Common.json b/public/locales/vi/Common.json
index 439797a076..7205fa11d0 100644
--- a/public/locales/vi/Common.json
+++ b/public/locales/vi/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "Giới thiệu",
"AboutCompanyTitle": "Giới thiệu về chương trình này",
"AccessDenied": "Truy cập bị từ chối",
@@ -55,6 +55,7 @@
"CommonFiles": "Các tập tin chung",
"CompanyName": "Tên công ty",
"Confirmation": "Xác nhận",
+ "ConfirmationText": "Tất cả dữ liệu bạn đã nhập sẽ bị mất. Bạn có chắc chắn muốn tiếp tục không?",
"ConflictResolveSelectAction": "Vui lòng chọn hành động:",
"Connect": "Kết nối",
"Content": "Nội dung",
@@ -509,4 +510,4 @@
"Yes": "Có",
"Yesterday": "Hôm qua",
"You": "Bạn"
-}
+}
\ No newline at end of file
diff --git a/public/locales/zh-CN/Common.json b/public/locales/zh-CN/Common.json
index 40b292119f..69fe41dac4 100644
--- a/public/locales/zh-CN/Common.json
+++ b/public/locales/zh-CN/Common.json
@@ -1,4 +1,4 @@
-{
+{
"About": "关于",
"AboutCompanyTitle": "关于本计划",
"AccessDenied": "拒绝访问",
@@ -55,6 +55,7 @@
"CommonFiles": "公共文件",
"CompanyName": "企业名称",
"Confirmation": "确认",
+ "ConfirmationText": "您所输入的所有数据都将丢失。确定要继续吗?",
"ConflictResolveSelectAction": "请选择操作:",
"Connect": "连接",
"Content": "内容",
@@ -509,4 +510,4 @@
"Yes": "是",
"Yesterday": "昨天",
"You": "您"
-}
+}
\ No newline at end of file