Merge branch 'release/v2.5.0' of github.com:ONLYOFFICE/DocSpace-client into release/v2.5.0

This commit is contained in:
Dmitry Sychugov 2024-04-08 19:07:53 +05:00
commit 0ae2317472
10 changed files with 141 additions and 179 deletions

View File

@ -24,103 +24,39 @@
// 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 ExpanderDownReactSvgUrl from "PUBLIC_DIR/images/expander-down.react.svg?url";
import React, { useEffect, useState, useRef } from "react";
import styled from "styled-components";
import { ReactSVG } from "react-svg";
import { StyledDropDown, StyledDropDownWrapper } from "../StyledDropdown";
import { isMobile as isMobileUtil, DomHelpers } from "@docspace/shared/utils";
import { isMobileOnly, isMobile } from "react-device-detect";
import { isMobile, DomHelpers } from "@docspace/shared/utils";
import { Text } from "@docspace/shared/components/text";
import { Button } from "@docspace/shared/components/button";
import { DropDownItem } from "@docspace/shared/components/drop-down-item";
import { connectedCloudsTypeTitleTranslation as ProviderKeyTranslation } from "@docspace/client/src/helpers/filesUtils";
import { Base } from "@docspace/shared/themes";
import { toastr } from "@docspace/shared/components/toast";
import { ComboBox } from "@docspace/shared/components/combobox";
const StyledStorageLocation = styled.div`
display: flex;
flex-direction: column;
.thirdparty-combobox {
padding: 0px;
.dropdown-container {
border: ${(props) =>
`1px solid ${props.theme.createEditRoomDialog.thirdpartyStorage.combobox.dropdownBorderColor}`};
}
.combo-button {
padding-left: 8px;
}
}
.set_room_params-thirdparty {
display: flex;
flex-direction: row;
gap: 8px;
&-combobox {
cursor: pointer;
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 5px 7px;
background: ${(props) =>
props.theme.createEditRoomDialog.thirdpartyStorage.combobox.background};
border-radius: 3px;
max-height: 32px;
border: ${(props) =>
`1px solid ${
props.isOpen
? props.theme.createEditRoomDialog.thirdpartyStorage.combobox
.isOpenDropdownBorderColor
: props.theme.createEditRoomDialog.thirdpartyStorage.combobox
.dropdownBorderColor
}`};
transition: all 0.2s ease;
&:hover {
border: ${(props) =>
`1px solid ${
props.isOpen
? props.theme.createEditRoomDialog.thirdpartyStorage.combobox
.isOpenDropdownBorderColor
: props.theme.createEditRoomDialog.thirdpartyStorage.combobox
.hoverDropdownBorderColor
}`};
}
&-text {
font-weight: 400;
font-size: ${(props) => props.theme.getCorrectFontSize("13px")};
line-height: 20px;
}
&-expander {
display: flex;
align-items: center;
justify-content: center;
width: 6.35px;
margin-top: -4px;
svg {
transform: ${(props) =>
props.isOpen ? "rotate(180deg)" : "rotate(0)"};
width: 6.35px;
height: auto;
path {
fill: ${(props) =>
props.theme.createEditRoomDialog.thirdpartyStorage.combobox
.arrowFill};
}
}
}
}
&-checkbox {
margin-top: 8px;
.checkbox {
${({ theme }) =>
theme.interfaceDirection === "rtl"
? `margin-left: 8px;`
: `margin-right: 8px;`}
}
.checkbox-text {
font-weight: 400;
font-size: ${(props) => props.theme.getCorrectFontSize("13px")};
line-height: 20px;
}
}
}
`;
@ -144,13 +80,10 @@ const ThirdPartyComboBox = ({
setConnectItem,
getOAuthToken,
setIsScrollLocked,
setIsOauthWindowOpen,
isDisabled,
}) => {
const dropdownRef = useRef(null);
const thirdparties = connectItems.map((item) => ({
...item,
title: item.category
@ -158,34 +91,8 @@ const ThirdPartyComboBox = ({
: ProviderKeyTranslation(item.providerKey, t),
}));
const [isOpen, setIsOpen] = useState(false);
const [dropdownDirection, setDropdownDirection] = useState("bottom");
const toggleIsOpen = () => {
if (isDisabled) return;
if (isOpen) setIsScrollLocked(false);
else {
setIsScrollLocked(true);
calculateDropdownDirection();
}
setIsOpen(!isOpen);
};
const setStorageLocaiton = (thirparty) => {
onChangeProvider(thirparty);
setIsOpen(false);
setIsScrollLocked(false);
};
const calculateDropdownDirection = () => {
const { top: offsetTop } = DomHelpers.getOffset(dropdownRef.current);
const offsetBottom = window.innerHeight - offsetTop;
const neededHeightDesktop = Math.min(thirdparties.length * 32 + 16, 404);
const neededHeightMobile = Math.min(thirdparties.length * 32 + 16, 180);
const neededheight = isMobile() ? neededHeightMobile : neededHeightDesktop;
setDropdownDirection(neededheight > offsetBottom ? "top" : "bottom");
};
const onShowService = async () => {
@ -245,24 +152,51 @@ const ThirdPartyComboBox = ({
setSaveThirdpartyResponse(null);
}, [saveThirdpartyResponse]);
return (
<StyledStorageLocation isOpen={isOpen}>
<div className="set_room_params-thirdparty">
<div
id="shared_third-party-storage_combobox"
className="set_room_params-thirdparty-combobox"
onClick={toggleIsOpen}
>
<Text className="set_room_params-thirdparty-combobox-text" noSelect>
{storageLocation?.provider?.title ||
t("ThirdPartyStorageComboBoxPlaceholder")}
</Text>
<ReactSVG
className="set_room_params-thirdparty-combobox-expander"
src={ExpanderDownReactSvgUrl}
/>
</div>
const options = thirdparties.map((item) => ({
label: item.title,
key: item?.category ?? item.id,
}));
const onSelect = (elem) => {
console.log("123a", elem);
console.log("thirdparties", thirdparties);
const thirdparty = thirdparties.find(
(t) => elem.key === t.id || elem.key === t.category,
);
console.log("thirdparty", thirdparty);
thirdparty && setStorageLocaiton(thirdparty);
};
return (
<StyledStorageLocation>
<div className="set_room_params-thirdparty">
<ComboBox
className="thirdparty-combobox"
selectedOption={{
key: "length",
label:
storageLocation?.provider?.title ||
t("ThirdPartyStorageComboBoxPlaceholder"),
}}
options={options}
scaled
withBackdrop={isMobile}
size="content"
title={t("Common:Role")}
manualWidth={"fit-content"}
isMobileView={isMobileOnly}
directionY="both"
displaySelectedOption
noBorder={false}
fixedDirection
isDefaultMode={false}
hideMobileView={false}
forceCloseClickOutside
scaledOptions
onSelect={onSelect}
/>
<Button
id="shared_third-party-storage_connect"
isDisabled={
@ -276,34 +210,6 @@ const ThirdPartyComboBox = ({
onClick={onShowService}
/>
</div>
<StyledDropDownWrapper
className="dropdown-content-wrapper"
ref={dropdownRef}
>
<StyledDropDown
className="dropdown-content"
open={isOpen}
forwardedRef={dropdownRef}
clickOutsideAction={toggleIsOpen}
maxHeight={isMobile() ? 158 : 382}
directionY={dropdownDirection}
marginTop={dropdownDirection === "bottom" ? "4px" : "-36px"}
hasItems={isOpen}
>
{thirdparties.map((thirdparty) => (
<DropDownItem
id={thirdparty.id}
className={`dropdown-item ${thirdparty.className ?? ""}`}
label={thirdparty.title}
key={thirdparty.id}
height={32}
heightTablet={32}
onClick={() => setStorageLocaiton(thirdparty)}
/>
))}
</StyledDropDown>
</StyledDropDownWrapper>
</StyledStorageLocation>
);
};

View File

@ -30,7 +30,6 @@ import { useCallback, useEffect, useRef, useState } from "react";
import DefaultUserPhoto from "PUBLIC_DIR/images/default_user_photo_size_82-82.png";
import EmptyScreenPersonsSvgUrl from "PUBLIC_DIR/images/empty_screen_persons.svg?url";
import CatalogAccountsReactSvgUrl from "PUBLIC_DIR/images/catalog.accounts.react.svg?url";
import EmptyScreenPersonsSvgDarkUrl from "PUBLIC_DIR/images/empty_screen_persons_dark.svg?url";
import { Aside } from "@docspace/shared/components/aside";
@ -44,7 +43,6 @@ import {
TAccessRight,
TSelectorAccessRights,
TSelectorCancelButton,
TSelectorSelectAll,
TWithTabs,
} from "@docspace/shared/components/selector/Selector.types";
import { toastr } from "@docspace/shared/components/toast";
@ -435,15 +433,6 @@ const AddUsersPanel = ({
);
};
const withSelectAllProps: TSelectorSelectAll = isMultiSelect
? {
withSelectAll: isMultiSelect,
selectAllLabel: t("Common:AllAccounts"),
selectAllIcon: CatalogAccountsReactSvgUrl,
onSelectAll: () => {},
}
: {};
const withAccessRightsProps: TSelectorAccessRights =
withAccessRights && isMultiSelect
? {
@ -520,7 +509,6 @@ const AddUsersPanel = ({
submitButtonLabel={t("Common:AddButton")}
onSubmit={onUsersSelect}
disableSubmitButton={false}
{...withSelectAllProps}
{...withAccessRightsProps}
{...withCancelButtonProps}
emptyScreenImage={emptyScreenImage}

View File

@ -309,6 +309,7 @@ const SectionHeaderContent = (props) => {
showNavigationButton,
deleteRooms,
setSelection,
startUpload,
} = props;
const navigate = useNavigate();
@ -358,6 +359,15 @@ const SectionHeaderContent = (props) => {
setSelectFileDialogVisible(true);
};
const onFileChange = React.useCallback(
(e) => {
startUpload(e.target.files, null, t);
},
[startUpload, t],
);
const onInputClick = React.useCallback((e) => (e.target.value = null), []);
const onShowGallery = () => {
const initOformFilter = (
oformsFilter || oformsFilter.getDefault()
@ -1276,6 +1286,29 @@ const SectionHeaderContent = (props) => {
/>
</div>
)}
{isFrame && (
<>
<input
id="customFileInput"
className="custom-file-input"
multiple
type="file"
style={{ display: "none" }}
onChange={onFileChange}
onClick={onInputClick}
/>
<input
id="customFolderInput"
className="custom-file-input"
webkitdirectory=""
mozdirectory=""
type="file"
style={{ display: "none" }}
onChange={onFileChange}
onClick={onInputClick}
/>
</>
)}
</StyledContainer>
)}
</Consumer>
@ -1300,7 +1333,9 @@ export default inject(
userStore,
currentTariffStatusStore,
settingsStore,
uploadDataStore,
}) => {
const { startUpload } = uploadDataStore;
const isOwner = userStore.user?.isOwner;
const isAdmin = userStore.user?.isAdmin;
const isCollaborator = userStore.user?.isCollaborator;
@ -1610,6 +1645,7 @@ export default inject(
deleteRooms,
setSelection,
setShareFolderDialogVisible,
startUpload,
};
},
)(

View File

@ -35,7 +35,7 @@ import SectionWrapper from "SRC_DIR/components/Section";
import SelectionArea from "../Home/SelectionArea/FilesSelectionArea";
import MediaViewer from "../Home/MediaViewer";
import { usePublic } from "../Home/Hooks";
import { usePublic, useSDK } from "../Home/Hooks";
const PublicRoomPage = (props) => {
const {
@ -49,6 +49,10 @@ const PublicRoomPage = (props) => {
showSecondaryButtonAlert,
fetchPublicRoom,
fetchPreviewMediaFile,
frameConfig,
setFrameConfig,
isLoading,
} = props;
const location = useLocation();
@ -60,6 +64,8 @@ const PublicRoomPage = (props) => {
fetchPreviewMediaFile,
});
useSDK({ frameConfig, setFrameConfig, isLoading });
const sectionProps = {
showSecondaryProgressBar,
secondaryProgressBarValue,
@ -107,7 +113,7 @@ export default inject(
filesSettingsStore,
mediaViewerDataStore,
}) => {
const { withPaging } = settingsStore;
const { withPaging, frameConfig, setFrameConfig } = settingsStore;
const { isLoaded, isLoading, roomStatus, fetchPublicRoom } =
publicRoomStore;
@ -141,6 +147,9 @@ export default inject(
isEmptyPage,
fetchPublicRoom,
fetchPreviewMediaFile,
frameConfig,
setFrameConfig,
};
},
)(observer(PublicRoomPage));

View File

@ -28,6 +28,7 @@
import React from "react";
import { CSSTransition } from "react-transition-group";
import { useTheme } from "styled-components";
import { isMobileOnly } from "react-device-detect";
import ArrowLeftReactUrl from "PUBLIC_DIR/images/arrow-left.react.svg?url";
@ -193,7 +194,11 @@ const ContextMenu = React.forwardRef((props: ContextMenuProps, ref) => {
left = event.pageX - width + 1;
}
if (isTabletUtils() && height > 483) {
if (
isTabletUtils() &&
(height > 483 ||
(isMobileOnly && window.innerHeight < window.innerWidth))
) {
const article = document.getElementById("article-container");
let currentArticleWidth = 0;
@ -506,7 +511,7 @@ const ContextMenu = React.forwardRef((props: ContextMenuProps, ref) => {
const element = renderContextMenu();
const isMobile = isMobileUtils();
const isMobileUtil = isMobileUtils();
const contextMenu = (
<>
@ -524,7 +529,7 @@ const ContextMenu = React.forwardRef((props: ContextMenuProps, ref) => {
);
const root = document.getElementById("root");
if (root && isMobile) {
if (root && isMobileUtil) {
const portal = <Portal element={contextMenu} appendTo={root} />;
return portal;

View File

@ -28,6 +28,8 @@ import React from "react";
import { useTheme } from "styled-components";
import { useTranslation } from "react-i18next";
import { isTablet, isIOS } from "react-device-detect";
import { DeviceType, FilterGroups } from "../../enums";
import { TViewSelectorOption, ViewSelector } from "../view-selector";
@ -175,6 +177,19 @@ const FilterInput = React.memo(
[selectedItems, removeSelectedItem],
);
const onInputFocus = (e: React.FocusEvent<HTMLInputElement>) => {
if (isTablet && isIOS) {
const scrollEvent = () => {
e.preventDefault();
e.stopPropagation();
window.scrollTo(0, 0);
window.onscroll = () => {};
};
window.onscroll = scrollEvent;
}
};
React.useEffect(() => {
return () => {
mountRef.current = false;
@ -191,6 +206,7 @@ const FilterInput = React.memo(
onClearSearch={onClearSearch}
id="filter_search-input"
size={InputSize.base}
onFocus={onInputFocus}
/>
<FilterButton
id="filter-button"

View File

@ -53,6 +53,7 @@ const SearchInput = ({
name,
isDisabled = false,
placeholder,
onFocus,
children,
}: SearchInputProps) => {
const timerId = React.useRef<null | ReturnType<typeof setTimeout>>(null);
@ -162,6 +163,7 @@ const SearchInput = ({
value={inputValue}
placeholder={placeholder}
onChange={onInputChange}
onFocus={onFocus}
>
{children}
</InputBlock>

View File

@ -62,4 +62,6 @@ export interface SearchInputProps {
children?: React.ReactNode;
/** Accepts css style */
style?: React.CSSProperties;
/** The callback function that is called when the field is focused */
onFocus?: (e: React.FocusEvent<HTMLInputElement>) => void;
}

View File

@ -1439,7 +1439,7 @@ export const getBaseTheme = () => {
zIndex: "400",
background: white,
borderRadius: "6px",
boxShadow: "0px 5px 20px rgba(0, 0, 0, 0.13)",
boxShadow: "0px 8px 16px 0px #040F1B14",
border: "none",
},
@ -2023,7 +2023,7 @@ export const getBaseTheme = () => {
expanderColor: black,
background: white,
rootFolderTitleColor: "#A3A9AE",
boxShadow: " 0px 12px 40px 0px #040F1B1F",
boxShadow: "0px 8px 16px 0px #040F1B14",
icon: {
fill: "#316DAA",
@ -2779,7 +2779,7 @@ export const getBaseTheme = () => {
background: white,
borderRadius: "6px",
mobileBorderRadius: "6px 6px 0 0",
boxShadow: "0px 12px 40px rgba(4, 15, 27, 0.12)",
boxShadow: "0px 8px 16px 0px #040F1B14",
padding: "6px 0px",
border: "none",
devices: {

View File

@ -1408,8 +1408,7 @@ const Dark: TTheme = {
zIndex: "400",
background: "#333333",
borderRadius: "6px",
boxShadow:
"0px 16px 16px rgba(0, 0, 0, 0.16), 0px 8.1px 6.975px rgba(0, 0, 0, 0.108), 0px 3.2px 2.6px rgba(0, 0, 0, 0.08), 0px 0.7px 0.925px rgba(0, 0, 0, 0.052)",
boxShadow: "0px 8px 16px 0px #040F1B29",
// boxShadowMobile: "0px -4px 60px rgba(0, 0, 0, 0.25)",
border: "1px solid #474747",
},
@ -1995,7 +1994,7 @@ const Dark: TTheme = {
expanderColor: "#eeeeee",
background: black,
rootFolderTitleColor: "#ADADAD",
boxShadow: "0px 12px 40px 0px #00000066",
boxShadow: "0px 8px 16px 0px #040F1B29",
icon: {
fill: "#E06A1B",
@ -2758,8 +2757,7 @@ const Dark: TTheme = {
background: black,
borderRadius: "6px",
mobileBorderRadius: "6px 6px 0 0",
boxShadow:
"0px 12px 24px rgba(0, 0, 0, 0.12), 0px 8px 16px rgba(0, 0, 0, 0.08), 0px 3.2px 2.6px rgba(0, 0, 0, 0.08)",
boxShadow: "0px 8px 16px 0px #040F1B29",
padding: "6px 0px",
border: "1px solid #474747",
devices: {