Merge branch 'release/v2.0.0' of https://github.com/ONLYOFFICE/DocSpace-client into release/v2.0.0
This commit is contained in:
commit
9fba274d89
@ -144,7 +144,14 @@ const ClientContent = (props) => {
|
||||
<GlobalEvents />
|
||||
{!isFormGallery ? (
|
||||
isFrame ? (
|
||||
showMenu && <ClientArticle />
|
||||
showMenu && (
|
||||
<ClientArticle
|
||||
withMainButton={withMainButton}
|
||||
setIsHeaderLoading={setIsHeaderLoading}
|
||||
setIsFilterLoading={setIsFilterLoading}
|
||||
showArticleLoader={showArticleLoader}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<ClientArticle
|
||||
withMainButton={withMainButton}
|
||||
|
@ -2,7 +2,6 @@ import React, { useState, useCallback, useEffect, memo } from "react";
|
||||
import styled, { useTheme } from "styled-components";
|
||||
import { FixedSizeList as List, areEqual } from "react-window";
|
||||
import AutoSizer from "react-virtualized-auto-sizer";
|
||||
import CustomScrollbarsVirtualList from "@docspace/components/scrollbar/custom-scrollbars-virtual-list";
|
||||
import InfiniteLoader from "react-window-infinite-loader";
|
||||
import User from "./User";
|
||||
import { isMobile } from "@docspace/components/utils/device";
|
||||
@ -10,7 +9,7 @@ import throttle from "lodash/throttle";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
|
||||
const StyledMembersList = styled.div`
|
||||
height: ${({ offsetTop }) => `calc(100vh - ${offsetTop})`};
|
||||
height: ${(props) => props.height + "px"};
|
||||
`;
|
||||
|
||||
const Item = memo(({ data, index, style }) => {
|
||||
@ -78,6 +77,7 @@ const Item = memo(({ data, index, style }) => {
|
||||
);
|
||||
}, areEqual);
|
||||
|
||||
const itemSize = 48;
|
||||
const MembersList = (props) => {
|
||||
const {
|
||||
t,
|
||||
@ -108,26 +108,11 @@ const MembersList = (props) => {
|
||||
const [isNextPageLoading, setIsNextPageLoading] = useState(false);
|
||||
const [isMobileView, setIsMobileView] = useState(isMobile());
|
||||
|
||||
const [offsetTop, setOffsetTop] = useState(0);
|
||||
|
||||
const onResize = throttle(() => {
|
||||
const isMobileView = isMobile();
|
||||
setIsMobileView(isMobileView);
|
||||
setOffset();
|
||||
}, 300);
|
||||
|
||||
const setOffset = () => {
|
||||
const rect = document
|
||||
.getElementById("infoPanelMembersList")
|
||||
?.getBoundingClientRect();
|
||||
|
||||
setOffsetTop(Math.ceil(rect?.top) + 2 + "px");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setOffset();
|
||||
}, [members]);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("resize", onResize);
|
||||
|
||||
@ -155,7 +140,7 @@ const MembersList = (props) => {
|
||||
);
|
||||
|
||||
return (
|
||||
<StyledMembersList id="infoPanelMembersList" offsetTop={offsetTop}>
|
||||
<StyledMembersList id="infoPanelMembersList" height={itemsCount * itemSize}>
|
||||
<AutoSizer>
|
||||
{({ height, width }) => (
|
||||
<InfiniteLoader
|
||||
@ -168,12 +153,13 @@ const MembersList = (props) => {
|
||||
|
||||
return (
|
||||
<List
|
||||
style={{ overflow: "hidden" }}
|
||||
direction={interfaceDirection}
|
||||
ref={ref}
|
||||
width={listWidth}
|
||||
height={height}
|
||||
itemCount={itemsCount}
|
||||
itemSize={48}
|
||||
itemSize={itemSize}
|
||||
itemData={{
|
||||
t,
|
||||
security,
|
||||
@ -193,7 +179,6 @@ const MembersList = (props) => {
|
||||
fetchMembers,
|
||||
hasNextPage,
|
||||
}}
|
||||
outerElementType={CustomScrollbarsVirtualList}
|
||||
onItemsRendered={onItemsRendered}
|
||||
>
|
||||
{Item}
|
||||
|
@ -268,7 +268,8 @@ const User = ({
|
||||
isLoading={isLoading}
|
||||
isMobileView={isMobileOnly}
|
||||
directionY="both"
|
||||
onToggle={onToggle}
|
||||
//Uncomment when scroll lock will work
|
||||
// onToggle={onToggle}
|
||||
displaySelectedOption
|
||||
/>
|
||||
) : (
|
||||
|
@ -217,6 +217,9 @@ const Members = ({
|
||||
const expectedTitleCount = expected.length ? 1 : 0;
|
||||
|
||||
const headersCount = adminsTitleCount + usersTitleCount + expectedTitleCount;
|
||||
const dataReadyMembersList = selection?.id === selectionParentRoom?.id;
|
||||
|
||||
if (!dataReadyMembersList) return <></>;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -226,6 +226,7 @@ const LinkRow = (props) => {
|
||||
getData={getData}
|
||||
isDisabled={isLoading}
|
||||
title={t("Files:ShowLinkActions")}
|
||||
directionY="both"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
@ -1,16 +1,17 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useState, useEffect, useTransition, Suspense } from "react";
|
||||
import styled, { css } from "styled-components";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
import { Base } from "@docspace/components/themes";
|
||||
import FilterReactSvrUrl from "PUBLIC_DIR/images/filter.react.svg?url";
|
||||
import IconButton from "@docspace/components/icon-button";
|
||||
import Text from "@docspace/components/text";
|
||||
|
||||
import { useParams } from "react-router-dom";
|
||||
import FilterDialog from "./FilterDialog";
|
||||
import StatusBar from "./StatusBar";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { HistoryHeaderLoader } from "../../sub-components/Loaders/HistoryHeaderLoader";
|
||||
|
||||
import { isMobile } from "@docspace/components/utils/device";
|
||||
|
||||
@ -30,6 +31,9 @@ const ListHeading = styled(Text)`
|
||||
line-height: 22px;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
`;
|
||||
|
||||
const FilterButton = styled.div`
|
||||
@ -42,6 +46,8 @@ const FilterButton = styled.div`
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
flex-shrink: 0;
|
||||
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
|
||||
@ -80,11 +86,18 @@ const FilterButton = styled.div`
|
||||
FilterButton.defaultProps = { theme: Base };
|
||||
|
||||
const HistoryFilterHeader = (props) => {
|
||||
const { applyFilters, historyFilters, isGroupMenuVisible } = props;
|
||||
const { t } = useTranslation(["Webhooks"]);
|
||||
const { id } = useParams();
|
||||
const {
|
||||
applyFilters,
|
||||
historyFilters,
|
||||
isGroupMenuVisible,
|
||||
fetchConfigName,
|
||||
configName,
|
||||
clearConfigName,
|
||||
} = props;
|
||||
|
||||
const [isFiltersVisible, setIsFiltersVisible] = useState(false);
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const { id } = useParams();
|
||||
|
||||
const openFiltersModal = () => {
|
||||
setIsFiltersVisible(true);
|
||||
@ -94,21 +107,34 @@ const HistoryFilterHeader = (props) => {
|
||||
setIsFiltersVisible(false);
|
||||
};
|
||||
|
||||
const handleConfigFetch = async () => {
|
||||
await fetchConfigName({
|
||||
configId: id,
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
startTransition(handleConfigFetch);
|
||||
return clearConfigName;
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ListHeader>
|
||||
<ListHeading fontWeight={700} fontSize="16px">
|
||||
{t("Webhook")} {id}
|
||||
</ListHeading>
|
||||
<Suspense fallback={<HistoryHeaderLoader />}>
|
||||
<ListHeader>
|
||||
<ListHeading title={configName} fontWeight={700} fontSize="16px">
|
||||
{configName}
|
||||
</ListHeading>
|
||||
|
||||
<FilterButton
|
||||
id="filter-button"
|
||||
onClick={openFiltersModal}
|
||||
isGroupMenuVisible={isGroupMenuVisible}>
|
||||
<IconButton iconName={FilterReactSvrUrl} size={16} />
|
||||
<span hidden={historyFilters === null}></span>
|
||||
</FilterButton>
|
||||
</ListHeader>
|
||||
<FilterButton
|
||||
id="filter-button"
|
||||
onClick={openFiltersModal}
|
||||
isGroupMenuVisible={isGroupMenuVisible}>
|
||||
<IconButton iconName={FilterReactSvrUrl} size={16} />
|
||||
<span hidden={historyFilters === null}></span>
|
||||
</FilterButton>
|
||||
</ListHeader>
|
||||
</Suspense>
|
||||
{historyFilters !== null && <StatusBar applyFilters={applyFilters} />}
|
||||
<FilterDialog
|
||||
visible={isFiltersVisible}
|
||||
@ -120,9 +146,13 @@ const HistoryFilterHeader = (props) => {
|
||||
};
|
||||
|
||||
export default inject(({ webhooksStore }) => {
|
||||
const { historyFilters, isGroupMenuVisible } = webhooksStore;
|
||||
const { historyFilters, isGroupMenuVisible, fetchConfigName, configName, clearConfigName } =
|
||||
webhooksStore;
|
||||
return {
|
||||
historyFilters,
|
||||
isGroupMenuVisible,
|
||||
fetchConfigName,
|
||||
configName,
|
||||
clearConfigName,
|
||||
};
|
||||
})(observer(HistoryFilterHeader));
|
||||
|
@ -165,7 +165,7 @@ const HistoryHeader = (props) => {
|
||||
<b>{t("Common:Done")}</b>,
|
||||
);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.error(error);
|
||||
toastr.error(error);
|
||||
} finally {
|
||||
setRetryPendingFalse();
|
||||
|
@ -0,0 +1,28 @@
|
||||
import React from "react";
|
||||
|
||||
import styled from "styled-components";
|
||||
import Loaders from "@docspace/common/components/Loaders";
|
||||
|
||||
const LoaderWrapper = styled.div`
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 17px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.filterButton,
|
||||
.configName {
|
||||
border-radius: 3px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const HistoryHeaderLoader = () => {
|
||||
return (
|
||||
<LoaderWrapper>
|
||||
<Loaders.Rectangle width="118px" height="22px" className="configName" />
|
||||
|
||||
<Loaders.Rectangle width="32px" height="22px" className="filterButton" />
|
||||
</LoaderWrapper>
|
||||
);
|
||||
};
|
@ -24,6 +24,7 @@ class Profile extends React.Component {
|
||||
selectedTreeNode,
|
||||
setSelectedNode,
|
||||
setIsProfileLoaded,
|
||||
getTfaType,
|
||||
} = this.props;
|
||||
|
||||
const userId = "@self";
|
||||
@ -46,6 +47,9 @@ class Profile extends React.Component {
|
||||
// if (linkParams.email_change && linkParams.email_change === "success") {
|
||||
// toastr.success(t("ChangeEmailSuccess"));
|
||||
// }
|
||||
|
||||
getTfaType();
|
||||
|
||||
if (!profile || profile.userName !== userId) {
|
||||
fetchProfile(userId).finally(() => {
|
||||
setIsProfileLoaded(true);
|
||||
@ -109,7 +113,7 @@ Profile.propTypes = {
|
||||
|
||||
export default inject(
|
||||
({ auth, peopleStore, clientLoadingStore, treeFoldersStore }) => {
|
||||
const { setDocumentTitle, language } = auth;
|
||||
const { setDocumentTitle, language, tfaStore } = auth;
|
||||
|
||||
const {
|
||||
setIsProfileLoaded,
|
||||
@ -133,6 +137,9 @@ export default inject(
|
||||
} = targetUserStore;
|
||||
|
||||
const { selectedTreeNode, setSelectedNode } = treeFoldersStore;
|
||||
|
||||
const { getTfaType } = tfaStore;
|
||||
|
||||
return {
|
||||
setDocumentTitle,
|
||||
language,
|
||||
@ -149,6 +156,7 @@ export default inject(
|
||||
isVisitor: auth.userStore.user.isVisitor,
|
||||
setIsProfileLoaded,
|
||||
setIsLoading,
|
||||
getTfaType,
|
||||
};
|
||||
}
|
||||
)(observer(withTranslation(["Profile", "Common"])(withCultureNames(Profile))));
|
||||
|
@ -84,7 +84,6 @@ class PeopleStore {
|
||||
//this.authStore.settingsStore.setModuleInfo(config.homepage, config.id);
|
||||
|
||||
await this.authStore.settingsStore.getPortalPasswordSettings();
|
||||
await this.authStore.tfaStore.getTfaType();
|
||||
};
|
||||
|
||||
reset = () => {
|
||||
|
@ -21,6 +21,7 @@ class WebhooksStore {
|
||||
eventDetails = {};
|
||||
FETCH_COUNT = 100;
|
||||
isRetryPending = false;
|
||||
configName = "";
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
@ -114,6 +115,20 @@ class WebhooksStore {
|
||||
return await retryWebhooks(ids);
|
||||
};
|
||||
|
||||
fetchConfigName = async (params) => {
|
||||
const historyData = await getWebhooksJournal({
|
||||
...params,
|
||||
startIndex: 0,
|
||||
count: 1,
|
||||
});
|
||||
|
||||
this.configName = historyData.items[0].configName;
|
||||
};
|
||||
|
||||
clearConfigName = () => {
|
||||
this.configName = "";
|
||||
};
|
||||
|
||||
fetchHistoryItems = async (params) => {
|
||||
this.totalItems = 0;
|
||||
this.startIndex = 0;
|
||||
|
@ -7,7 +7,7 @@ const LoginContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 56px auto 0 auto;
|
||||
//margin: 56px auto 0 auto;
|
||||
max-width: 960px;
|
||||
z-index: 0;
|
||||
|
||||
|
@ -6,5 +6,6 @@
|
||||
"MailMergeFileType": "Select .XLSX file",
|
||||
"OpenSavedDocument": "Open saved document in new tab",
|
||||
"SelectFilesType": "Select files type: {{fileType}}",
|
||||
"UsersWithoutAccess": "Some users whom you want to mention don't have access to the room: {{users}}"
|
||||
"UsersWithoutAccess": "Some users whom you want to mention don't have access to the room: {{users}}",
|
||||
"ErrorConnectionLost": "Connection is lost"
|
||||
}
|
||||
|
@ -71,6 +71,11 @@ let documentserverUrl =
|
||||
let userAccessRights = {};
|
||||
let isArchiveFolderRoot = true;
|
||||
let usersInRoom = [];
|
||||
let isZoom =
|
||||
typeof window !== "undefined" &&
|
||||
(window?.navigator?.userAgent?.includes("ZoomWebKit") ||
|
||||
window?.navigator?.userAgent?.includes("ZoomApps"));
|
||||
|
||||
function Editor({
|
||||
config,
|
||||
//personal,
|
||||
@ -317,6 +322,33 @@ function Editor({
|
||||
docEditor.setReferenceData(referenceData);
|
||||
};
|
||||
|
||||
const onSDKRequestOpen = async (event) => {
|
||||
const windowName = event.data.windowName;
|
||||
const reference = event.data;
|
||||
|
||||
try {
|
||||
const data = {
|
||||
fileKey: reference.referenceData ? reference.referenceData.fileKey : "",
|
||||
instanceId: reference.referenceData
|
||||
? reference.referenceData.instanceId
|
||||
: "",
|
||||
fileId,
|
||||
path: reference.path || "",
|
||||
};
|
||||
|
||||
const result = await getReferenceData(data);
|
||||
|
||||
if (result.error) throw new Error(result.error);
|
||||
|
||||
var link = result.link;
|
||||
window.open(link, windowName);
|
||||
} catch (e) {
|
||||
var winEditor = window.open("", windowName);
|
||||
winEditor.close();
|
||||
docEditor.showMessage(e?.message || t("ErrorConnectionLost"));
|
||||
}
|
||||
};
|
||||
|
||||
const onMakeActionLink = (event) => {
|
||||
const url = window.location.href;
|
||||
const actionLink = config?.editorConfig?.actionLink;
|
||||
@ -618,7 +650,7 @@ function Editor({
|
||||
users,
|
||||
});
|
||||
} catch (e) {
|
||||
docEditor.showMessage(e?.message || "Connection is lost");
|
||||
docEditor.showMessage(e?.message || t("ErrorConnectionLost"));
|
||||
}
|
||||
};
|
||||
|
||||
@ -751,6 +783,7 @@ function Editor({
|
||||
onRequestRestore,
|
||||
onRequestHistory,
|
||||
onRequestReferenceData,
|
||||
onRequestOpen,
|
||||
onRequestUsers,
|
||||
onRequestSendNotify,
|
||||
onRequestCreateNew,
|
||||
@ -810,6 +843,10 @@ function Editor({
|
||||
|
||||
if (!fileInfo?.providerKey) {
|
||||
onRequestReferenceData = onSDKRequestReferenceData;
|
||||
|
||||
if (!isZoom) {
|
||||
onRequestOpen = onSDKRequestOpen;
|
||||
}
|
||||
}
|
||||
|
||||
if (fileInfo?.rootFolderType !== FolderType.USER) {
|
||||
@ -824,6 +861,7 @@ function Editor({
|
||||
const events = {
|
||||
events: {
|
||||
onRequestReferenceData,
|
||||
onRequestOpen,
|
||||
onAppReady: onSDKAppReady,
|
||||
onDocumentStateChange: onDocumentStateChange,
|
||||
onMetaChange: onMetaChange,
|
||||
|
@ -28,16 +28,15 @@ interface IStyledCaptchaProps {
|
||||
}
|
||||
|
||||
export const LoginFormWrapper = styled.div`
|
||||
display: grid;
|
||||
grid-template-rows: ${(props: ILoginFormWrapperProps) =>
|
||||
props.enabledJoin
|
||||
? props.isDesktop
|
||||
? css`1fr 10px`
|
||||
: css`1fr 68px`
|
||||
: css`1fr`};
|
||||
width: 100%;
|
||||
height: ${props => props.enabledJoin ? "calc(100vh - 68px)" : "100vh"};
|
||||
|
||||
box-sizing: border-box;
|
||||
|
||||
@media ${mobile}{
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bg-cover {
|
||||
background-image: ${(props) => props.bgPattern};
|
||||
background-repeat: no-repeat;
|
||||
@ -64,6 +63,7 @@ export const LoginContent = styled.div`
|
||||
margin: 0 auto;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
height: 100%;
|
||||
|
||||
@media ${mobile} {
|
||||
width: 100%;
|
||||
|
Loading…
Reference in New Issue
Block a user