Merge branch 'feature/virtual-rooms-1.2' of github.com:ONLYOFFICE/AppServer into feature/virtual-rooms-1.2
This commit is contained in:
commit
ebff3a8f80
@ -31,7 +31,7 @@ const Article = ({
|
||||
toggleShowText,
|
||||
toggleArticleOpen,
|
||||
setIsMobileArticle,
|
||||
isLoading,
|
||||
isLoadedPage,
|
||||
children,
|
||||
...rest
|
||||
}) => {
|
||||
@ -117,7 +117,7 @@ const Article = ({
|
||||
handleWrapperClass="resizable-border not-selectable"
|
||||
>
|
||||
<SubArticleHeader
|
||||
isLoading={isLoading}
|
||||
isLoadedPage={isLoadedPage}
|
||||
showText={showText}
|
||||
onClick={toggleShowText}
|
||||
>
|
||||
@ -128,7 +128,7 @@ const Article = ({
|
||||
{articleMainButtonContent.props.children}
|
||||
</SubArticleMainButton>
|
||||
) : null}
|
||||
<SubArticleBody isLoading={isLoading} showText={showText}>
|
||||
<SubArticleBody showText={showText}>
|
||||
{articleBodyContent ? articleBodyContent.props.children : null}
|
||||
</SubArticleBody>
|
||||
</Resizable>
|
||||
|
@ -1,10 +1,8 @@
|
||||
import React from "react";
|
||||
import Scrollbar from "@appserver/components/scrollbar";
|
||||
import LoaderArticleBody from "./article-body-loader";
|
||||
const ArticleBody = ({ children, isLoading = false }) => {
|
||||
return isLoading ? (
|
||||
<LoaderArticleBody />
|
||||
) : (
|
||||
|
||||
const ArticleBody = ({ children }) => {
|
||||
return (
|
||||
<Scrollbar className="article-body__scrollbar" stype="mediumBlack">
|
||||
{children}
|
||||
</Scrollbar>
|
||||
|
@ -1,9 +1,9 @@
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
import { isTablet as isTabletUtils } from "@appserver/components/utils/device";
|
||||
import { isTablet } from "react-device-detect";
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
import {
|
||||
StyledArticleHeader,
|
||||
StyledHeading,
|
||||
@ -15,12 +15,22 @@ const ArticleHeader = ({
|
||||
showText,
|
||||
children,
|
||||
onClick,
|
||||
isLoading = false,
|
||||
isLoadedPage,
|
||||
isLoaded,
|
||||
tReady,
|
||||
setIsLoadedArticleHeader,
|
||||
...rest
|
||||
}) => {
|
||||
const heightLoader = isTabletUtils() || isTablet ? "20px" : "32px";
|
||||
const isLoadedSetting = isLoaded;
|
||||
const commonSettings = location.pathname.includes("common");
|
||||
|
||||
return isLoading ? (
|
||||
useEffect(() => {
|
||||
if (isLoadedSetting) setIsLoadedArticleHeader(isLoadedSetting);
|
||||
}, [isLoadedSetting]);
|
||||
|
||||
const heightLoader = isTabletUtils() || isTablet ? "20px" : "32px";
|
||||
const showLoader = commonSettings ? !isLoadedPage : false;
|
||||
return showLoader ? (
|
||||
<StyledArticleHeader>
|
||||
<Loaders.ArticleHeader height={heightLoader} className="loader" />
|
||||
</StyledArticleHeader>
|
||||
@ -45,4 +55,11 @@ ArticleHeader.propTypes = {
|
||||
|
||||
ArticleHeader.displayName = "Header";
|
||||
|
||||
export default React.memo(ArticleHeader);
|
||||
export default inject(({ common }) => {
|
||||
const { isLoaded, setIsLoadedArticleHeader } = common;
|
||||
|
||||
return {
|
||||
isLoaded,
|
||||
setIsLoadedArticleHeader,
|
||||
};
|
||||
})(observer(ArticleHeader));
|
||||
|
@ -250,8 +250,13 @@ class SettingsStore {
|
||||
this.isLoaded = isLoaded;
|
||||
};
|
||||
|
||||
setCultures = (cultures) => {
|
||||
this.cultures = cultures;
|
||||
};
|
||||
|
||||
getPortalCultures = async () => {
|
||||
this.cultures = await api.settings.getPortalCultures();
|
||||
const cultures = await api.settings.getPortalCultures();
|
||||
this.setCultures(cultures);
|
||||
};
|
||||
|
||||
setIsEncryptionSupport = (isEncryptionSupport) => {
|
||||
|
@ -156,8 +156,7 @@ const StyledButton = styled(ButtonWrapper).attrs((props) => ({
|
||||
: props.theme.button.border.base};
|
||||
|
||||
${(props) => props.scale && `width: 100%;`};
|
||||
min-width: ${(props) =>
|
||||
props.minwidth ? props.minwidth : props.theme.button.minWidth[props.size]};
|
||||
min-width: ${(props) => props.minwidth && props.minwidth};
|
||||
|
||||
padding: ${(props) => `${props.theme.button.padding[props.size]}`};
|
||||
|
||||
@ -214,6 +213,8 @@ const StyledButton = styled(ButtonWrapper).attrs((props) => ({
|
||||
}
|
||||
|
||||
.button-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
@ -127,7 +127,6 @@ const MainButtonMobile = (props) => {
|
||||
};
|
||||
|
||||
const onMainButtonClick = (e) => {
|
||||
if (isOpen && ref.current.contains(e.target)) return;
|
||||
toggle(!isOpen);
|
||||
};
|
||||
|
||||
@ -191,8 +190,8 @@ const MainButtonMobile = (props) => {
|
||||
/>
|
||||
))}
|
||||
</StyledProgressContainer>
|
||||
<StyledButtonOptions isOpenButton={isOpenButton}>
|
||||
{isOpenButton && buttonOptions
|
||||
<StyledButtonOptions>
|
||||
{buttonOptions
|
||||
? buttonOptions.map((option) =>
|
||||
option.isSeparator ? (
|
||||
<div key={option.key} className="separator-wrapper">
|
||||
@ -213,20 +212,6 @@ const MainButtonMobile = (props) => {
|
||||
)
|
||||
: ""}
|
||||
</StyledButtonOptions>
|
||||
{withButton && (
|
||||
<StyledButtonWrapper
|
||||
isUploading={isUploading}
|
||||
isOpenButton={isOpenButton}
|
||||
>
|
||||
<Button
|
||||
label={title}
|
||||
className="action-mobile-button"
|
||||
primary
|
||||
size="medium"
|
||||
onClick={onUploadClick}
|
||||
/>
|
||||
</StyledButtonWrapper>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -134,7 +134,6 @@ const StyledDropDownItem = styled(DropDownItem)`
|
||||
`;
|
||||
|
||||
const StyledButtonOptions = styled.div`
|
||||
display: ${(props) => !props.isOpenButton && "none"};
|
||||
padding: 16px 0;
|
||||
background-color: ${(props) =>
|
||||
props.theme.mainButtonMobile.buttonOptions.backgroundColor};
|
||||
|
@ -5,7 +5,7 @@ import StyledButton from "./styled-selector-add-button";
|
||||
import IconButton from "../icon-button";
|
||||
|
||||
const SelectorAddButton = (props) => {
|
||||
const { isDisabled, title, className, id, style } = props;
|
||||
const { isDisabled, title, className, id, style, iconName } = props;
|
||||
|
||||
const onClick = (e) => {
|
||||
!isDisabled && props.onClick && props.onClick(e);
|
||||
@ -22,7 +22,7 @@ const SelectorAddButton = (props) => {
|
||||
>
|
||||
<IconButton
|
||||
size={14}
|
||||
iconName="/static/images/actions.header.touch.react.svg"
|
||||
iconName={iconName}
|
||||
isFill={true}
|
||||
isDisabled={isDisabled}
|
||||
isClickable={!isDisabled}
|
||||
@ -44,10 +44,13 @@ SelectorAddButton.propTypes = {
|
||||
id: PropTypes.string,
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
/** Specifies the icon name */
|
||||
iconName: PropTypes.string,
|
||||
};
|
||||
|
||||
SelectorAddButton.defaultProps = {
|
||||
isDisabled: false,
|
||||
iconName: "/static/images/actions.header.touch.react.svg",
|
||||
};
|
||||
|
||||
export default SelectorAddButton;
|
||||
|
@ -12,8 +12,9 @@ import {
|
||||
StyledSubmenuItems,
|
||||
StyledSubmenuItemText,
|
||||
} from "./styled-submenu";
|
||||
import LoaderSubmenu from "./loader";
|
||||
|
||||
const Submenu = ({ data, startSelect = 0, onSelect, ...rest }) => {
|
||||
const Submenu = ({ data, startSelect = 0, onSelect, isLoading, ...rest }) => {
|
||||
if (!data) return null;
|
||||
|
||||
const [currentItem, setCurrentItem] = useState(
|
||||
@ -74,29 +75,40 @@ const Submenu = ({ data, startSelect = 0, onSelect, ...rest }) => {
|
||||
|
||||
return (
|
||||
<StyledSubmenu {...rest}>
|
||||
<StyledSubmenuItems ref={submenuItemsRef} role="list">
|
||||
{data.map((d) => {
|
||||
const isActive = d.id === currentItem.id;
|
||||
{isLoading ? (
|
||||
<LoaderSubmenu />
|
||||
) : (
|
||||
<>
|
||||
<StyledSubmenuItems ref={submenuItemsRef} role="list">
|
||||
{data.map((d) => {
|
||||
const isActive = d.id === currentItem.id;
|
||||
|
||||
return (
|
||||
<StyledSubmenuItem key={d.id} id={d.id} onClick={selectSubmenuItem}>
|
||||
<StyledSubmenuItemText>
|
||||
<Text
|
||||
color={isActive ? "#316DAA" : "#657077"}
|
||||
fontSize="13px"
|
||||
fontWeight="600"
|
||||
truncate={false}
|
||||
return (
|
||||
<StyledSubmenuItem
|
||||
key={d.id}
|
||||
id={d.id}
|
||||
onClick={selectSubmenuItem}
|
||||
>
|
||||
{d.name}
|
||||
</Text>
|
||||
</StyledSubmenuItemText>
|
||||
<StyledSubmenuItemLabel color={isActive ? "#316DAA" : "none"} />
|
||||
</StyledSubmenuItem>
|
||||
);
|
||||
})}
|
||||
</StyledSubmenuItems>
|
||||
<StyledSubmenuBottomLine />
|
||||
|
||||
<StyledSubmenuItemText>
|
||||
<Text
|
||||
color={isActive ? "#316DAA" : "#657077"}
|
||||
fontSize="13px"
|
||||
fontWeight="600"
|
||||
truncate={false}
|
||||
>
|
||||
{d.name}
|
||||
</Text>
|
||||
</StyledSubmenuItemText>
|
||||
<StyledSubmenuItemLabel
|
||||
color={isActive ? "#316DAA" : "none"}
|
||||
/>
|
||||
</StyledSubmenuItem>
|
||||
);
|
||||
})}
|
||||
</StyledSubmenuItems>
|
||||
<StyledSubmenuBottomLine />
|
||||
</>
|
||||
)}
|
||||
<StyledSubmenuContentWrapper>
|
||||
{currentItem.content}
|
||||
</StyledSubmenuContentWrapper>
|
||||
@ -108,6 +120,7 @@ Submenu.propTypes = {
|
||||
data: PropTypes.arrayOf(PropTypes.object.isRequired).isRequired,
|
||||
startSelect: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
||||
onSelect: PropTypes.func,
|
||||
isLoading: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Submenu;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import styled, { css } from "styled-components";
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
import { isTablet } from "react-device-detect";
|
||||
|
@ -168,7 +168,7 @@ class TabContainer extends Component {
|
||||
selected={activeTab === index}
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
<Text className="title_style" fontSize="13px">
|
||||
<Text fontWeight={600} className="title_style" fontSize="13px">
|
||||
{item.title}
|
||||
</Text>
|
||||
</Label>
|
||||
|
@ -127,14 +127,6 @@ const Base = {
|
||||
medium: "0 32px",
|
||||
},
|
||||
|
||||
minWidth: {
|
||||
extraSmall: "none",
|
||||
small: "100px",
|
||||
normalDesktop: "100px",
|
||||
normalTouchscreen: "100px",
|
||||
medium: "100px",
|
||||
},
|
||||
|
||||
color: {
|
||||
base: black,
|
||||
baseHover: black,
|
||||
@ -2442,6 +2434,13 @@ const Base = {
|
||||
border: `1px solid ${grayMid}`,
|
||||
borderBottom: `1px solid ${grayLightMid}`,
|
||||
|
||||
tile: {
|
||||
background: globalColors.lightHover,
|
||||
itemBackground: white,
|
||||
itemBorder: grayMid,
|
||||
itemActiveBorder: blueMain,
|
||||
},
|
||||
|
||||
fill: gray,
|
||||
hoverFill: grayMain,
|
||||
},
|
||||
|
@ -127,14 +127,6 @@ const Dark = {
|
||||
medium: "0 32px",
|
||||
},
|
||||
|
||||
minWidth: {
|
||||
extraSmall: "none",
|
||||
small: "100px",
|
||||
normalDesktop: "100px",
|
||||
normalTouchscreen: "100px",
|
||||
medium: "100px",
|
||||
},
|
||||
|
||||
color: {
|
||||
base: "#CCCCCC",
|
||||
baseHover: "#FAFAFA",
|
||||
@ -2453,6 +2445,13 @@ const Dark = {
|
||||
border: "1px solid #474747",
|
||||
borderBottom: "1px solid #474747",
|
||||
|
||||
tile: {
|
||||
background: globalColors.black,
|
||||
itemBackground: "#242424",
|
||||
itemBorder: gray,
|
||||
itemActiveBorder: "#eeeeee",
|
||||
},
|
||||
|
||||
fill: "#858585",
|
||||
hoverFill: "#eeeeee",
|
||||
},
|
||||
|
@ -19,5 +19,6 @@
|
||||
"StoringFileVersion": "Storing file versions",
|
||||
"ThirdPartyBtn": "Allow users to connect third-party storages",
|
||||
"ThirdPartySettings": "Connected clouds",
|
||||
"UpdateOrCreate": "Update the file version for the existing file with the same name. Otherwise, a copy of the file will be created."
|
||||
"UpdateOrCreate": "Update the file version for the existing file with the same name. Otherwise, a copy of the file will be created.",
|
||||
"Clouds": "Clouds"
|
||||
}
|
||||
|
@ -19,5 +19,6 @@
|
||||
"StoringFileVersion": "Хранение версий файлов",
|
||||
"ThirdPartyBtn": "Разрешить пользователям подключать сторонние хранилища",
|
||||
"ThirdPartySettings": "Подключенные облака",
|
||||
"UpdateOrCreate": "Обновлять версию файла для существующего файла с таким же именем. В противном случае будет создаваться копия файла."
|
||||
"UpdateOrCreate": "Обновлять версию файла для существующего файла с таким же именем. В противном случае будет создаваться копия файла.",
|
||||
"Clouds": "Облака"
|
||||
}
|
||||
|
@ -11,6 +11,16 @@ export const StyledIcon = styled(IconButton)`
|
||||
${commonIconsStyles}
|
||||
`;
|
||||
|
||||
const StyledEditIcon = styled(IconButton)`
|
||||
${commonIconsStyles}
|
||||
|
||||
svg {
|
||||
path {
|
||||
fill: ${(props) => props.theme.filesSection.rowView.editingIconColor};
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@ -129,7 +139,7 @@ const Badges = ({
|
||||
/>
|
||||
)}
|
||||
{isEditing && (
|
||||
<StyledIcon
|
||||
<StyledEditIcon
|
||||
iconName={iconEdit}
|
||||
className="badge icons-group is-editing tablet-badge tablet-edit"
|
||||
size={sizeBadge}
|
||||
|
@ -53,15 +53,30 @@ const EditingWrapper = styled.div`
|
||||
border-bottom: ${(props) => props.theme.filesEditingWrapper.borderBottom};
|
||||
padding-bottom: 4px;
|
||||
margin-top: 4px;
|
||||
|
||||
/* margin-left: -4px; */
|
||||
`}
|
||||
|
||||
${(props) =>
|
||||
props.viewAs === "tile" &&
|
||||
`margin-right: 10px !important; margin-left: 8px;`}
|
||||
|
||||
|
||||
css`
|
||||
position: absolute;
|
||||
width: calc(100% - 18px);
|
||||
z-index: 1;
|
||||
gap: 4px;
|
||||
|
||||
background-color: ${(props) =>
|
||||
props.theme.filesEditingWrapper.tile.background};
|
||||
|
||||
border: ${(props) => props.theme.filesEditingWrapper.border};
|
||||
border-radius: 0 0 6px 6px;
|
||||
|
||||
height: 43px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 9px 8px 9px 8px;
|
||||
`}
|
||||
|
||||
|
||||
@media ${tablet} {
|
||||
height: 56px;
|
||||
}
|
||||
@ -96,26 +111,37 @@ const EditingWrapper = styled.div`
|
||||
`}
|
||||
|
||||
${(props) => props.viewAs === "table" && `padding-left: 12px`}
|
||||
|
||||
${(props) =>
|
||||
props.viewAs === "tile" &&
|
||||
css`
|
||||
background: #fff;
|
||||
border: ${(props) =>
|
||||
`1px solid ${props.theme.filesEditingWrapper.tile.itemBorder}`};
|
||||
|
||||
&:focus {
|
||||
border: ${(props) =>
|
||||
`1px solid ${props.theme.filesEditingWrapper.tile.itemActiveBorder}`};
|
||||
}
|
||||
`};
|
||||
}
|
||||
|
||||
.edit-button {
|
||||
margin-left: 8px;
|
||||
height: 32px;
|
||||
padding: 8px 7px 7px 7px;
|
||||
padding: 0px 7px 0px 7px;
|
||||
|
||||
${(props) =>
|
||||
props.viewAs === "tile" &&
|
||||
css`
|
||||
margin-left: 0px;
|
||||
background: none;
|
||||
border: 1px solid transparent;
|
||||
background: #fff;
|
||||
border: ${(props) =>
|
||||
`1px solid ${props.theme.filesEditingWrapper.tile.itemBorder}`};
|
||||
|
||||
:hover {
|
||||
border: ${(props) => props.theme.filesEditingWrapper.border};
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-left: 2px;
|
||||
&:hover {
|
||||
border: ${(props) =>
|
||||
`1px solid ${props.theme.filesEditingWrapper.tile.itemActiveBorder}`};
|
||||
}
|
||||
`};
|
||||
|
||||
@ -125,22 +151,23 @@ const EditingWrapper = styled.div`
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border: 1px transparent;
|
||||
padding: 4px 0 0 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
:hover {
|
||||
&:hover {
|
||||
border: ${(props) => props.theme.filesEditingWrapper.border};
|
||||
}
|
||||
`}
|
||||
}
|
||||
|
||||
.edit-ok-icon {
|
||||
margin-top: -6px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.edit-cancel-icon {
|
||||
margin-top: -6px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
padding: 1px;
|
||||
|
@ -202,6 +202,7 @@ const PureConnectDialogContainer = (props) => {
|
||||
isLoading={!tReady}
|
||||
visible={visible}
|
||||
zIndex={310}
|
||||
displayType="modal"
|
||||
onClose={onClose}
|
||||
>
|
||||
<ModalDialog.Header>
|
||||
|
@ -8,88 +8,78 @@ import ModalDialog from "@appserver/components/modal-dialog";
|
||||
import Text from "@appserver/components/text";
|
||||
import Link from "@appserver/components/link";
|
||||
import { connectedCloudsTitleTranslation } from "../../../helpers/utils";
|
||||
import NoUserSelect from "@appserver/components/utils/commonStyles";
|
||||
import { Base } from "@appserver/components/themes";
|
||||
import Button from "@appserver/components/button";
|
||||
import SelectorAddButton from "@appserver/components/selector-add-button";
|
||||
import { isMobile } from "react-device-detect";
|
||||
|
||||
const StyledServicesBlock = styled.div`
|
||||
display: grid;
|
||||
column-gap: 55px;
|
||||
row-gap: 20px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
grid-template-columns: repeat(auto-fill, 158px);
|
||||
padding-top: 24px;
|
||||
|
||||
.service-item {
|
||||
border: ${(props) => props.theme.filesThirdPartyDialog.border};
|
||||
width: 158px;
|
||||
height: 40px;
|
||||
|
||||
:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
const StyledModalDialog = styled(ModalDialog)`
|
||||
.modal-dialog-aside-body {
|
||||
margin-right: -16px;
|
||||
}
|
||||
|
||||
.service-item__svg {
|
||||
${NoUserSelect}
|
||||
border: ${(props) => props.theme.filesThirdPartyDialog.border};
|
||||
width: 158px;
|
||||
height: 40px;
|
||||
.service-block {
|
||||
padding-top: 20px;
|
||||
display: grid;
|
||||
grid-gap: 16px;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-item: center;
|
||||
.service-item-container {
|
||||
display: flex;
|
||||
|
||||
:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
.service-name-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
${(props) =>
|
||||
!props.theme.isBase &&
|
||||
css`
|
||||
svg {
|
||||
rect {
|
||||
fill: #333333;
|
||||
}
|
||||
path {
|
||||
fill: #ffffff;
|
||||
opacity: 0.16;
|
||||
.service-item__svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.kDrive {
|
||||
svg {
|
||||
path:nth-child(7) {
|
||||
opacity: 0.5 !important;
|
||||
}
|
||||
path:nth-child(8) {
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
path:nth-child(9) {
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
path:nth-child(10) {
|
||||
opacity: 0.16 !important;
|
||||
}
|
||||
path:nth-child(11) {
|
||||
opacity: 0.16 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
`}
|
||||
}
|
||||
}
|
||||
|
||||
.kDrive {
|
||||
svg {
|
||||
path:nth-child(7) {
|
||||
opacity: 0.5 !important;
|
||||
}
|
||||
path:nth-child(8) {
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
path:nth-child(9) {
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
path:nth-child(10) {
|
||||
opacity: 0.16 !important;
|
||||
}
|
||||
path:nth-child(11) {
|
||||
opacity: 0.16 !important;
|
||||
.service-btn {
|
||||
margin-left: auto;
|
||||
|
||||
svg {
|
||||
path {
|
||||
fill: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.service-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
`;
|
||||
|
||||
StyledServicesBlock.defaultProps = { theme: Base };
|
||||
StyledModalDialog.defaultProps = { theme: Base };
|
||||
|
||||
const ServiceItem = (props) => {
|
||||
const { capability, t, className, ...rest } = props;
|
||||
const {
|
||||
t,
|
||||
capability,
|
||||
className,
|
||||
getThirdPartyIcon,
|
||||
serviceName,
|
||||
onClick,
|
||||
} = props;
|
||||
|
||||
const capabilityName = capability[0];
|
||||
const capabilityLink = capability.length > 1 ? capability[1] : "";
|
||||
@ -100,13 +90,38 @@ const ServiceItem = (props) => {
|
||||
"data-key": capabilityName,
|
||||
};
|
||||
|
||||
const src = getThirdPartyIcon(capabilityName);
|
||||
|
||||
return (
|
||||
<ReactSVG
|
||||
{...dataProps}
|
||||
{...rest}
|
||||
className={`service-item__svg ${className}`}
|
||||
alt=""
|
||||
/>
|
||||
<div className="service-item-container">
|
||||
<div className="service-name-container">
|
||||
<ReactSVG
|
||||
src={src}
|
||||
className={`service-item__svg ${className}`}
|
||||
alt=""
|
||||
/>
|
||||
<Text fontWeight={600} fontSize="14px">
|
||||
{serviceName ? serviceName : capabilityName}
|
||||
</Text>
|
||||
</div>
|
||||
{isMobile ? (
|
||||
<SelectorAddButton
|
||||
onClick={onClick}
|
||||
iconName="/static/images/actions.plus.icon.react.svg"
|
||||
className="service-btn"
|
||||
title={t("Common:Connect")}
|
||||
{...dataProps}
|
||||
/>
|
||||
) : (
|
||||
<Button
|
||||
size="small"
|
||||
className="service-btn"
|
||||
label={t("Common:Connect")}
|
||||
onClick={onClick}
|
||||
{...dataProps}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -133,6 +148,7 @@ const ThirdPartyDialog = (props) => {
|
||||
getOAuthToken,
|
||||
setConnectDialogVisible,
|
||||
setConnectItem,
|
||||
getThirdPartyIcon,
|
||||
} = props;
|
||||
|
||||
const onClose = () => {
|
||||
@ -178,17 +194,12 @@ const ThirdPartyDialog = (props) => {
|
||||
setThirdPartyDialogVisible(false);
|
||||
};
|
||||
|
||||
const yandexLogoUrl =
|
||||
i18n && i18n.language === "ru-RU"
|
||||
? "images/services/logo_yandex_ru.svg"
|
||||
: "images/services/logo_yandex_en.svg";
|
||||
|
||||
return (
|
||||
<ModalDialog
|
||||
<StyledModalDialog
|
||||
isLoading={!tReady}
|
||||
visible={visible}
|
||||
scale={false}
|
||||
displayType="auto"
|
||||
displayType="aside"
|
||||
zIndex={310}
|
||||
onClose={onClose}
|
||||
>
|
||||
@ -207,100 +218,110 @@ const ThirdPartyDialog = (props) => {
|
||||
</Trans>
|
||||
)}
|
||||
</Text>
|
||||
<StyledServicesBlock>
|
||||
<div className="service-block">
|
||||
{googleConnectItem && (
|
||||
<ServiceItem
|
||||
t={t}
|
||||
capability={googleConnectItem}
|
||||
onClick={onShowService}
|
||||
src="images/services/logo_google-drive.svg"
|
||||
getThirdPartyIcon={getThirdPartyIcon}
|
||||
/>
|
||||
)}
|
||||
|
||||
{boxConnectItem && (
|
||||
<ServiceItem
|
||||
t={t}
|
||||
capability={boxConnectItem}
|
||||
onClick={onShowService}
|
||||
src="images/services/logo_box.svg"
|
||||
getThirdPartyIcon={getThirdPartyIcon}
|
||||
/>
|
||||
)}
|
||||
|
||||
{dropboxConnectItem && (
|
||||
<ServiceItem
|
||||
t={t}
|
||||
capability={dropboxConnectItem}
|
||||
onClick={onShowService}
|
||||
src="images/services/logo_dropbox.svg"
|
||||
getThirdPartyIcon={getThirdPartyIcon}
|
||||
/>
|
||||
)}
|
||||
|
||||
{sharePointConnectItem && (
|
||||
<ServiceItem
|
||||
t={t}
|
||||
capability={sharePointConnectItem}
|
||||
onClick={onShowService}
|
||||
src={"images/services/logo_sharepoint.svg"}
|
||||
getThirdPartyIcon={getThirdPartyIcon}
|
||||
/>
|
||||
)}
|
||||
|
||||
{oneDriveConnectItem && (
|
||||
<ServiceItem
|
||||
t={t}
|
||||
capability={oneDriveConnectItem}
|
||||
onClick={onShowService}
|
||||
src="images/services/logo_onedrive.svg"
|
||||
getThirdPartyIcon={getThirdPartyIcon}
|
||||
/>
|
||||
)}
|
||||
|
||||
{sharePointConnectItem && (
|
||||
{/* {sharePointConnectItem && (
|
||||
<ServiceItem
|
||||
t={t}
|
||||
capability={sharePointConnectItem}
|
||||
onClick={onShowService}
|
||||
src={"images/services/logo_onedrive-for-business.svg"}
|
||||
getThirdPartyIcon={getThirdPartyIcon}
|
||||
/>
|
||||
)}
|
||||
)} */}
|
||||
|
||||
{nextCloudConnectItem && (
|
||||
<ServiceItem
|
||||
t={t}
|
||||
serviceName="Nextcloud"
|
||||
capability={webDavConnectItem}
|
||||
onClick={onShowService}
|
||||
src="images/services/logo_nextcloud.svg"
|
||||
getThirdPartyIcon={getThirdPartyIcon}
|
||||
/>
|
||||
)}
|
||||
|
||||
{ownCloudConnectItem && (
|
||||
<ServiceItem
|
||||
t={t}
|
||||
serviceName="ownCloud"
|
||||
capability={webDavConnectItem}
|
||||
onClick={onShowService}
|
||||
src="images/services/logo_owncloud.svg"
|
||||
getThirdPartyIcon={getThirdPartyIcon}
|
||||
/>
|
||||
)}
|
||||
|
||||
{kDriveConnectItem && (
|
||||
<ServiceItem
|
||||
t={t}
|
||||
capability={kDriveConnectItem}
|
||||
onClick={onShowService}
|
||||
className={"kDrive"}
|
||||
src="images/services/logo_kdrive.svg"
|
||||
getThirdPartyIcon={getThirdPartyIcon}
|
||||
/>
|
||||
)}
|
||||
{yandexConnectItem && (
|
||||
<ServiceItem
|
||||
t={t}
|
||||
capability={yandexConnectItem}
|
||||
onClick={onShowService}
|
||||
src={yandexLogoUrl}
|
||||
getThirdPartyIcon={getThirdPartyIcon}
|
||||
/>
|
||||
)}
|
||||
{webDavConnectItem && (
|
||||
<Text
|
||||
<ServiceItem
|
||||
t={t}
|
||||
serviceName={t("ConnextOtherAccount")}
|
||||
capability={webDavConnectItem}
|
||||
onClick={onShowService}
|
||||
className="service-item service-text"
|
||||
data-title={webDavConnectItem[0]}
|
||||
data-key={webDavConnectItem[0]}
|
||||
noSelect
|
||||
>
|
||||
{t("ConnextOtherAccount")}
|
||||
</Text>
|
||||
getThirdPartyIcon={getThirdPartyIcon}
|
||||
/>
|
||||
)}
|
||||
</StyledServicesBlock>
|
||||
</div>
|
||||
</ModalDialog.Body>
|
||||
</ModalDialog>
|
||||
</StyledModalDialog>
|
||||
);
|
||||
};
|
||||
|
||||
@ -317,6 +338,7 @@ export default inject(({ auth, settingsStore, dialogsStore }) => {
|
||||
webDavConnectItem,
|
||||
sharePointConnectItem,
|
||||
openConnectWindow,
|
||||
getThirdPartyIcon,
|
||||
} = settingsStore.thirdPartyStore;
|
||||
const {
|
||||
setThirdPartyDialogVisible,
|
||||
@ -346,5 +368,10 @@ export default inject(({ auth, settingsStore, dialogsStore }) => {
|
||||
setThirdPartyDialogVisible,
|
||||
getOAuthToken,
|
||||
openConnectWindow,
|
||||
getThirdPartyIcon,
|
||||
};
|
||||
})(withTranslation(["Settings", "Translations"])(observer(ThirdPartyDialog)));
|
||||
})(
|
||||
withTranslation(["Settings", "Translations, Common"])(
|
||||
observer(ThirdPartyDialog)
|
||||
)
|
||||
);
|
||||
|
@ -41,11 +41,6 @@ const SimpleFilesRowContent = styled(RowContent)`
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.is-editing {
|
||||
path {
|
||||
fill: ${(props) => props.theme.filesSection.rowView.editingIconColor};
|
||||
}
|
||||
}
|
||||
${(props) =>
|
||||
((props.sectionWidth <= 1024 && props.sectionWidth > 500) || isTablet) &&
|
||||
`
|
||||
|
@ -5,20 +5,10 @@ import Text from "@appserver/components/text";
|
||||
import Link from "@appserver/components/link";
|
||||
import Box from "@appserver/components/box";
|
||||
import Row from "@appserver/components/row";
|
||||
import RowContent from "@appserver/components/row-content";
|
||||
import RowContainer from "@appserver/components/row-container";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import EmptyFolderContainer from "../../../../components/EmptyContainer/EmptyContainer";
|
||||
import BoxIcon from "../../../../../public/images/icon_box.react.svg";
|
||||
import DropBoxIcon from "../../../../../public/images/icon_dropbox.react.svg";
|
||||
import GoogleDriveIcon from "../../../../../public/images/icon_google_drive.react.svg";
|
||||
import KDriveIcon from "../../../../../public/images/icon_kdrive.react.svg";
|
||||
import NextCloudIcon from "../../../../../public/images/icon_nextcloud.react.svg";
|
||||
import OneDriveIcon from "../../../../../public/images/icon_onedrive.react.svg";
|
||||
import OwnCloudIcon from "../../../../../public/images/icon_owncloud.react.svg";
|
||||
import SharePointIcon from "../../../../../public/images/icon_sharepoint.react.svg";
|
||||
import WebDavIcon from "../../../../../public/images/icon_webdav.react.svg";
|
||||
import YandexDiskIcon from "../../../../../public/images/icon_yandex_disk.react.svg";
|
||||
import commonIconsStyles from "@appserver/components/utils/common-icons-style";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import combineUrl from "@appserver/common/utils/combineUrl";
|
||||
import AppServerConfig from "@appserver/common/constants/AppServerConfig";
|
||||
@ -26,37 +16,8 @@ import config from "../../../../../package.json";
|
||||
import { withRouter } from "react-router";
|
||||
import { connectedCloudsTypeTitleTranslation } from "../../../../helpers/utils";
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
|
||||
const StyledBoxIcon = styled(BoxIcon)`
|
||||
${commonIconsStyles}
|
||||
`;
|
||||
const StyledDropBoxIcon = styled(DropBoxIcon)`
|
||||
${commonIconsStyles}
|
||||
`;
|
||||
const StyledGoogleDriveIcon = styled(GoogleDriveIcon)`
|
||||
${commonIconsStyles}
|
||||
`;
|
||||
const StyledKDriveIcon = styled(KDriveIcon)`
|
||||
${commonIconsStyles}
|
||||
`;
|
||||
const StyledNextCloudIcon = styled(NextCloudIcon)`
|
||||
${commonIconsStyles}
|
||||
`;
|
||||
const StyledOneDriveIcon = styled(OneDriveIcon)`
|
||||
${commonIconsStyles}
|
||||
`;
|
||||
const StyledOwnCloudIcon = styled(OwnCloudIcon)`
|
||||
${commonIconsStyles}
|
||||
`;
|
||||
const StyledSharePointIcon = styled(SharePointIcon)`
|
||||
${commonIconsStyles}
|
||||
`;
|
||||
const StyledWebDavIcon = styled(WebDavIcon)`
|
||||
${commonIconsStyles}
|
||||
`;
|
||||
const StyledYandexDiskIcon = styled(YandexDiskIcon)`
|
||||
${commonIconsStyles}
|
||||
`;
|
||||
import { tablet } from "@appserver/components/utils/device";
|
||||
import { ReactSVG } from "react-svg";
|
||||
|
||||
const linkStyles = {
|
||||
isHovered: true,
|
||||
@ -66,6 +27,48 @@ const linkStyles = {
|
||||
display: "flex",
|
||||
};
|
||||
|
||||
const StyledHeader = styled.div`
|
||||
display: flex;
|
||||
border-bottom: 1px solid #eceef1;
|
||||
padding-bottom: 12px;
|
||||
|
||||
@media ${tablet} {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cloud-settings-clouds {
|
||||
width: 30%;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.cloud-settings-name {
|
||||
display: flex;
|
||||
margin-left: 6px;
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.cloud-settings-separator {
|
||||
display: block;
|
||||
height: 10px;
|
||||
margin: 4px 8px 0 0;
|
||||
z-index: 1;
|
||||
border-right: 1px solid #d0d5da;
|
||||
}
|
||||
|
||||
.cloud-settings-header_connection {
|
||||
display: flex;
|
||||
margin-left: -15px;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledRow = styled(Row)`
|
||||
.cloud-settings-row-content {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
class ConnectClouds extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -111,36 +114,6 @@ class ConnectClouds extends React.Component {
|
||||
this.props.setConnectDialogVisible(true);
|
||||
};
|
||||
|
||||
getThirdPartyIcon = (iconName) => {
|
||||
switch (iconName) {
|
||||
case "Box":
|
||||
return <StyledBoxIcon size="big" />;
|
||||
case "DropboxV2":
|
||||
return <StyledDropBoxIcon size="big" />;
|
||||
case "GoogleDrive":
|
||||
return <StyledGoogleDriveIcon size="big" />;
|
||||
case "OneDrive":
|
||||
return <StyledOneDriveIcon size="big" />;
|
||||
case "SharePoint":
|
||||
return <StyledSharePointIcon size="big" />;
|
||||
case "kDrive":
|
||||
return <StyledKDriveIcon size="big" />;
|
||||
case "Yandex":
|
||||
return <StyledYandexDiskIcon size="big" />;
|
||||
case "OwnCloud":
|
||||
return <StyledOwnCloudIcon size="big" />;
|
||||
case "NextCloud":
|
||||
return <StyledNextCloudIcon size="big" />;
|
||||
case "OneDriveForBusiness":
|
||||
return <StyledOneDriveIcon size="big" />;
|
||||
case "WebDav":
|
||||
return <StyledWebDavIcon size="big" />;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
openLocation = (e) => {
|
||||
const {
|
||||
myFolderId,
|
||||
@ -186,6 +159,7 @@ class ConnectClouds extends React.Component {
|
||||
{
|
||||
key: `${index}_change`,
|
||||
"data-provider-id": item.provider_id,
|
||||
icon: "/static/images/access.edit.react.svg",
|
||||
label: t("Translations:ThirdPartyInfo"),
|
||||
onClick: this.onChangeThirdPartyInfo,
|
||||
},
|
||||
@ -193,6 +167,7 @@ class ConnectClouds extends React.Component {
|
||||
key: `${index}_delete`,
|
||||
"data-id": item.provider_id,
|
||||
"data-title": item.customer_title,
|
||||
icon: "/static/images/catalog.trash.react.svg",
|
||||
label: t("Translations:DeleteThirdParty"),
|
||||
onClick: this.onDeleteThirdParty,
|
||||
},
|
||||
@ -200,7 +175,7 @@ class ConnectClouds extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { t, providers, tReady, theme } = this.props;
|
||||
const { t, providers, tReady, theme, getThirdPartyIcon } = this.props;
|
||||
|
||||
linkStyles.color = theme.filesSettings.color;
|
||||
|
||||
@ -210,43 +185,53 @@ class ConnectClouds extends React.Component {
|
||||
<>
|
||||
<Button
|
||||
size="small"
|
||||
style={{ marginBottom: "8px" }}
|
||||
style={{ marginBottom: "24px" }}
|
||||
onClick={this.onShowThirdPartyDialog}
|
||||
label={t("ConnectedCloud")}
|
||||
label={t("Common:AddButton")}
|
||||
primary
|
||||
/>
|
||||
<StyledHeader>
|
||||
<Text
|
||||
className="cloud-settings-clouds"
|
||||
fontSize="12px"
|
||||
fontWeight={600}
|
||||
color="#657077"
|
||||
>
|
||||
{t("Clouds")}
|
||||
</Text>
|
||||
|
||||
<div className="cloud-settings-name">
|
||||
<div className="cloud-settings-separator" />
|
||||
<Text fontSize="12px" fontWeight={600} color="#A3A9AE">
|
||||
{t("Common:Name")}
|
||||
</Text>
|
||||
</div>
|
||||
</StyledHeader>
|
||||
<RowContainer useReactWindow={false}>
|
||||
{providers.map((item, index) => {
|
||||
const element = this.getThirdPartyIcon(item.provider_key);
|
||||
const src = getThirdPartyIcon(item.provider_key);
|
||||
const element = <ReactSVG src={src} alt="" />;
|
||||
const typeTitle = connectedCloudsTypeTitleTranslation(
|
||||
item.provider_key,
|
||||
t
|
||||
);
|
||||
|
||||
return (
|
||||
<Row
|
||||
<StyledRow
|
||||
key={index}
|
||||
element={element}
|
||||
contextOptions={this.getContextOptions(item, index)}
|
||||
>
|
||||
<Box
|
||||
containerMinWidth="200px"
|
||||
containerWidth="100%"
|
||||
displayProp="flex"
|
||||
flexDirection="row"
|
||||
alignItems="baseline"
|
||||
alignSelf="baseline"
|
||||
marginProp="auto 0"
|
||||
>
|
||||
<RowContent>
|
||||
<Text
|
||||
style={{ width: 100 }}
|
||||
as="div"
|
||||
type="page"
|
||||
fontSize="13px"
|
||||
fontWeight={600}
|
||||
title={item.provider_key}
|
||||
fontWeight="600"
|
||||
fontSize="15px"
|
||||
color={theme.filesSettings.linkColor}
|
||||
//color={theme.filesSettings.linkColor}
|
||||
noSelect
|
||||
containerWidth="30%"
|
||||
>
|
||||
{tReady ? (
|
||||
typeTitle
|
||||
@ -254,21 +239,25 @@ class ConnectClouds extends React.Component {
|
||||
<Loaders.Rectangle width="90px" height="10px" />
|
||||
)}
|
||||
</Text>
|
||||
<div></div>
|
||||
|
||||
<Link
|
||||
type="page"
|
||||
title={item.customer_title}
|
||||
color={theme.filesSettings.linkColor}
|
||||
fontSize="13px"
|
||||
//color={theme.filesSettings.linkColor}
|
||||
color="#A3A9AE"
|
||||
fontSize="11px"
|
||||
fontWeight={400}
|
||||
truncate={true}
|
||||
data-provider-key={item.provider_key}
|
||||
data-provider-id={item.provider_id}
|
||||
onClick={this.openLocation}
|
||||
containerWidth="70%"
|
||||
>
|
||||
{item.customer_title}
|
||||
</Link>
|
||||
</Box>
|
||||
</Row>
|
||||
</RowContent>
|
||||
</StyledRow>
|
||||
);
|
||||
})}
|
||||
</RowContainer>
|
||||
@ -302,7 +291,11 @@ class ConnectClouds extends React.Component {
|
||||
|
||||
export default inject(
|
||||
({ auth, filesStore, settingsStore, treeFoldersStore, dialogsStore }) => {
|
||||
const { providers, capabilities } = settingsStore.thirdPartyStore;
|
||||
const {
|
||||
providers,
|
||||
capabilities,
|
||||
getThirdPartyIcon,
|
||||
} = settingsStore.thirdPartyStore;
|
||||
const { filter, setFirstLoad } = filesStore;
|
||||
const { myFolder, commonFolder, getSubfolders } = treeFoldersStore;
|
||||
const {
|
||||
@ -327,6 +320,7 @@ export default inject(
|
||||
setDeleteThirdPartyDialogVisible,
|
||||
setRemoveItem,
|
||||
getSubfolders,
|
||||
getThirdPartyIcon,
|
||||
|
||||
homepage: config.homepage,
|
||||
};
|
||||
|
@ -1,6 +1,4 @@
|
||||
import React from "react";
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
import Error403 from "studio/Error403";
|
||||
import Error520 from "studio/Error520";
|
||||
import ConnectClouds from "./ConnectedClouds";
|
||||
@ -12,29 +10,6 @@ import TabsContainer from "@appserver/components/tabs-container";
|
||||
import CommonSettings from "./CommonSettings";
|
||||
import AdminSettings from "./AdminSettings";
|
||||
|
||||
import { tablet } from "@appserver/components/utils/device";
|
||||
import { isMobile } from "react-device-detect";
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
|
||||
width: calc(100% - 40px);
|
||||
|
||||
height: auto;
|
||||
|
||||
@media ${tablet} {
|
||||
position: static;
|
||||
width: calc(100% - 32px);
|
||||
}
|
||||
|
||||
${isMobile &&
|
||||
css`
|
||||
position: static;
|
||||
width: calc(100% - 32px);
|
||||
`}
|
||||
`;
|
||||
|
||||
const SectionBodyContent = ({
|
||||
setting,
|
||||
isAdmin,
|
||||
@ -116,13 +91,13 @@ const SectionBodyContent = ({
|
||||
) : isErrorSettings ? (
|
||||
<Error520 />
|
||||
) : (
|
||||
<StyledContainer>
|
||||
<div>
|
||||
<TabsContainer
|
||||
elements={elements}
|
||||
onSelect={onSelect}
|
||||
selectedItem={selectedTab()}
|
||||
/>
|
||||
</StyledContainer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -17,6 +17,7 @@ const PureSettings = ({
|
||||
isLoadedSettingsTree,
|
||||
history,
|
||||
setFirstLoad,
|
||||
capabilities,
|
||||
tReady,
|
||||
}) => {
|
||||
const [title, setTitle] = useState("");
|
||||
@ -55,7 +56,10 @@ const PureSettings = ({
|
||||
</Section.SectionHeader>
|
||||
|
||||
<Section.SectionBody>
|
||||
{(!isLoadedSettingsTree && isLoading) || isLoading || !tReady ? (
|
||||
{(!isLoadedSettingsTree && isLoading) ||
|
||||
isLoading ||
|
||||
!tReady ||
|
||||
!capabilities ? (
|
||||
setting === "thirdParty" ? (
|
||||
<Loaders.Rows />
|
||||
) : (
|
||||
@ -79,7 +83,12 @@ const Settings = withTranslation(["Settings", "Common"])(PureSettings);
|
||||
export default inject(({ filesStore, settingsStore, treeFoldersStore }) => {
|
||||
const { setFirstLoad, isLoading } = filesStore;
|
||||
const { setSelectedNode } = treeFoldersStore;
|
||||
const { getFilesSettings, isLoadedSettingsTree } = settingsStore;
|
||||
const {
|
||||
getFilesSettings,
|
||||
isLoadedSettingsTree,
|
||||
thirdPartyStore,
|
||||
} = settingsStore;
|
||||
const { capabilities } = thirdPartyStore;
|
||||
|
||||
return {
|
||||
isLoading,
|
||||
@ -87,5 +96,6 @@ export default inject(({ filesStore, settingsStore, treeFoldersStore }) => {
|
||||
setFirstLoad,
|
||||
setSelectedNode,
|
||||
getFilesSettings,
|
||||
capabilities,
|
||||
};
|
||||
})(withRouter(observer(Settings)));
|
||||
|
@ -2,7 +2,7 @@ import { makeAutoObservable } from "mobx";
|
||||
import api from "@appserver/common/api";
|
||||
|
||||
class ThirdPartyStore {
|
||||
capabilities = [];
|
||||
capabilities = null;
|
||||
providers = [];
|
||||
|
||||
constructor() {
|
||||
@ -87,44 +87,92 @@ class ThirdPartyStore {
|
||||
});
|
||||
};
|
||||
|
||||
getThirdPartyIcon = (iconName) => {
|
||||
switch (iconName) {
|
||||
case "Box":
|
||||
return "images/icon_box.react.svg";
|
||||
case "DropboxV2":
|
||||
return "images/icon_dropbox.react.svg";
|
||||
case "GoogleDrive":
|
||||
return "images/icon_google_drive.react.svg";
|
||||
case "OneDrive":
|
||||
return "images/icon_onedrive.react.svg";
|
||||
case "SharePoint":
|
||||
return "images/icon_sharepoint.react.svg";
|
||||
case "kDrive":
|
||||
return "images/icon_kdrive.react.svg";
|
||||
case "Yandex":
|
||||
return "images/icon_yandex_disk.react.svg";
|
||||
case "OwnCloud":
|
||||
return "images/icon_owncloud.react.svg";
|
||||
case "NextCloud":
|
||||
return "images/icon_nextcloud.react.svg";
|
||||
case "OneDriveForBusiness":
|
||||
return "images/icon_onedrive.react.svg";
|
||||
case "WebDav":
|
||||
return "images/icon_webdav.react.svg";
|
||||
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
get googleConnectItem() {
|
||||
return this.capabilities.find((x) => x[0] === "GoogleDrive");
|
||||
return (
|
||||
this.capabilities && this.capabilities.find((x) => x[0] === "GoogleDrive")
|
||||
);
|
||||
}
|
||||
|
||||
get boxConnectItem() {
|
||||
return this.capabilities.find((x) => x[0] === "Box");
|
||||
return this.capabilities && this.capabilities.find((x) => x[0] === "Box");
|
||||
}
|
||||
|
||||
get dropboxConnectItem() {
|
||||
return this.capabilities.find((x) => x[0] === "DropboxV2");
|
||||
return (
|
||||
this.capabilities && this.capabilities.find((x) => x[0] === "DropboxV2")
|
||||
);
|
||||
}
|
||||
get oneDriveConnectItem() {
|
||||
return this.capabilities.find((x) => x[0] === "OneDrive");
|
||||
return (
|
||||
this.capabilities && this.capabilities.find((x) => x[0] === "OneDrive")
|
||||
);
|
||||
}
|
||||
|
||||
get sharePointConnectItem() {
|
||||
return this.capabilities.find((x) => x[0] === "SharePoint");
|
||||
return (
|
||||
this.capabilities && this.capabilities.find((x) => x[0] === "SharePoint")
|
||||
);
|
||||
}
|
||||
|
||||
get kDriveConnectItem() {
|
||||
return this.capabilities.find((x) => x[0] === "kDrive");
|
||||
return (
|
||||
this.capabilities && this.capabilities.find((x) => x[0] === "kDrive")
|
||||
);
|
||||
}
|
||||
|
||||
get yandexConnectItem() {
|
||||
return this.capabilities.find((x) => x[0] === "Yandex");
|
||||
return (
|
||||
this.capabilities && this.capabilities.find((x) => x[0] === "Yandex")
|
||||
);
|
||||
}
|
||||
|
||||
get webDavConnectItem() {
|
||||
return this.capabilities.find((x) => x[0] === "WebDav");
|
||||
return (
|
||||
this.capabilities && this.capabilities.find((x) => x[0] === "WebDav")
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: remove WebDav get NextCloud
|
||||
get nextCloudConnectItem() {
|
||||
return this.capabilities.find((x) => x[0] === "WebDav");
|
||||
return (
|
||||
this.capabilities && this.capabilities.find((x) => x[0] === "WebDav")
|
||||
);
|
||||
}
|
||||
// TODO:remove WebDav get OwnCloud
|
||||
get ownCloudConnectItem() {
|
||||
return this.capabilities.find((x) => x[0] === "WebDav");
|
||||
return (
|
||||
this.capabilities && this.capabilities.find((x) => x[0] === "WebDav")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "Elektron poçt uğurla dəyişdirildi",
|
||||
"ChangesApplied": "Dəyişiklər tətbiq olundu",
|
||||
"Connect": "Qoşulmaq",
|
||||
"ContactInformation": "Əlaqə məlumatları",
|
||||
"CountCodesRemaining": "qalan kodlar",
|
||||
"Disconnect": "Bağlantını kəs",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Abunəliklər",
|
||||
"TfaLoginSettings": "Daxilolma sazlamaları",
|
||||
"TwoFactorDescription": "Bütün istifadəçilər üçün ikili audentifikasiya (kod generasiyası ilə) inzibatçı tərəfindən yandırıldı."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "Имейлът беше променен успешно ",
|
||||
"ChangesApplied": "Промените са приложени",
|
||||
"Connect": "Свържи",
|
||||
"ContactInformation": "Информация за Контакт",
|
||||
"CountCodesRemaining": "кода остават",
|
||||
"Disconnect": "Прекъсни връзката",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Абонаменти",
|
||||
"TfaLoginSettings": "Настройки за вписване",
|
||||
"TwoFactorDescription": "Двуфакторното удостоверяване чрез приложението за генериране на кодове беше активирано за всички потребители от администратора."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "E-mail byl úspěšně změněn ",
|
||||
"ChangesApplied": "Změny jsou aplikovány",
|
||||
"Connect": "Připojit",
|
||||
"ContactInformation": "Kontaktní informace",
|
||||
"CountCodesRemaining": "zbývající kódy",
|
||||
"Disconnect": "Odpojit",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Předplatné",
|
||||
"TfaLoginSettings": "Nastavení přihlášení",
|
||||
"TwoFactorDescription": "Dvoufázové ověřování prostřednictvím aplikace generující kódy bylo správcem povoleno pro všechny uživatele."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "E-Mail wurde erfolgreich geändert",
|
||||
"ChangesApplied": "Die Änderungen wurden übernommen",
|
||||
"Connect": "Verbinden",
|
||||
"ContactInformation": "Kontaktdaten",
|
||||
"CountCodesRemaining": "Codes übrig",
|
||||
"Disconnect": "Trennen Sie die Verbindung",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Abonnements",
|
||||
"TfaLoginSettings": "Login-Einstellungen",
|
||||
"TwoFactorDescription": "Zwei-Faktor-Authentifizierung über eine App für Generierung von Codes wurde für alle aktiviert."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "Το email άλλαξε με επιτυχία",
|
||||
"ChangesApplied": "Το email άλλαξε με επιτυχία",
|
||||
"Connect": "Σύνδεση",
|
||||
"ContactInformation": "Στοιχεία επικοινωνίας",
|
||||
"CountCodesRemaining": "εναπομείναντες κωδικοί",
|
||||
"Disconnect": "Αποσύνδεση",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Συνδρομές",
|
||||
"TfaLoginSettings": "Ρυθμίσεις σύνδεσης",
|
||||
"TwoFactorDescription": "Ο έλεγχος ταυτότητας δύο παραγόντων μέσω μιας εφαρμογής δημιουργίας κωδικών ενεργοποιήθηκε για όλους τους χρήστες από τον διαχειριστή."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "Email has been changed successfully ",
|
||||
"ChangesApplied": "Changes are applied",
|
||||
"Connect": "Connect",
|
||||
"ContactInformation": "Contact Information",
|
||||
"CountCodesRemaining": "codes remaining",
|
||||
"Disconnect": "Disconnect",
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "El email se ha cambiado correctamente",
|
||||
"ChangesApplied": "Los cambios se han aplicado",
|
||||
"Connect": "Conectar",
|
||||
"ContactInformation": "Información de contacto",
|
||||
"CountCodesRemaining": "códigos restantes",
|
||||
"Disconnect": "Desconectar",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Suscripciones",
|
||||
"TfaLoginSettings": "Ajustes de acceso",
|
||||
"TwoFactorDescription": "El administrador ha habilitado la autenticación de dos factores a través de una aplicación que genera códigos para todos los usuarios."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "Sähköpostin vaihtaminen onnistui ",
|
||||
"ChangesApplied": "Muutokset otetaan käyttöön",
|
||||
"Connect": "Yhdistä",
|
||||
"ContactInformation": "Yhteystiedot",
|
||||
"CountCodesRemaining": "Jäljellä olevat koodit",
|
||||
"Disconnect": "Katkaise",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Tilaukset",
|
||||
"TfaLoginSettings": "Kirjautumisasetukset",
|
||||
"TwoFactorDescription": "Järjestelmänvalvoja otti käyttöön kaksivaiheisen todennuksen koodia luovan sovelluksen kautta kaikille käyttäjille."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "L'adresse E-mail a été modifiée avec succès.",
|
||||
"ChangesApplied": "Changements appliqués",
|
||||
"Connect": "Connexion",
|
||||
"ContactInformation": "Informations de contact",
|
||||
"CountCodesRemaining": "Codes restants",
|
||||
"Disconnect": "Déconnecter",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Abonnements",
|
||||
"TfaLoginSettings": "Paramètres de connexion",
|
||||
"TwoFactorDescription": "L'authentification à deux facteurs via une application générant des codes a été activée pour tous les utilisateurs par l'administrateur."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "L'indirizzo e-mail è stato modificato con successo",
|
||||
"ChangesApplied": "Le modifiche sono state applicate",
|
||||
"Connect": "Collega",
|
||||
"ContactInformation": "Informazioni di contatto",
|
||||
"CountCodesRemaining": "codici rimanenti",
|
||||
"Disconnect": "Scollega",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Sottoscrizione",
|
||||
"TfaLoginSettings": "Impostazioni di accesso",
|
||||
"TwoFactorDescription": "L'autenticazione a due fattori tramite un'app che genera codice è stata attivata per tutti gli utenti dall'amministratore."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "メールの変更が完了しました 。",
|
||||
"ChangesApplied": "変更が適用されました。",
|
||||
"Connect": "接続",
|
||||
"ContactInformation": "連絡先",
|
||||
"CountCodesRemaining": "残されたコード",
|
||||
"Disconnect": "接続解除",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "サブスクリプション",
|
||||
"TfaLoginSettings": "ログイン設定",
|
||||
"TwoFactorDescription": "管理者がすべてのユーザーに対して、コード生成アプリによる二要素認証を有効にしました。"
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "이메일이 성공적으로 변경되었습니다",
|
||||
"ChangesApplied": "변경 사항이 적용되었습니다",
|
||||
"Connect": "연결",
|
||||
"ContactInformation": "연락처 정보",
|
||||
"CountCodesRemaining": "남은 코드",
|
||||
"Disconnect": "연결 해제",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "구독",
|
||||
"TfaLoginSettings": "로그인 설정",
|
||||
"TwoFactorDescription": "관리자에 의해 코드 생성 앱을 통한 이중 인증이 모든 사용자에 대해 활성화됩니다."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "ອີເມວໄດ້ຖືກປ່ຽນແປງແລ້ວ",
|
||||
"ChangesApplied": "ນຳໃຊ້ການປ່ຽນແປງ",
|
||||
"Connect": "ຕິດຕໍ່",
|
||||
"ContactInformation": "ຂໍ້ມູນຕິດຕໍ່",
|
||||
"CountCodesRemaining": "ລະຫັດທີ່ເຫລື່ອ",
|
||||
"Disconnect": "ຕັດການເຊື່ອມຕໍ່",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "ການສະໝັກຮັບຂໍ້ມູນ",
|
||||
"TfaLoginSettings": "ຕັ້ງຄ່າການເຂົ້າລະບົບ",
|
||||
"TwoFactorDescription": "ການຢືນຢັນຕົວຕົນສອງຂັ້ນຕອນຜ່ານແອັບພລິເຄຊັນທີ່ສ້າງລະຫັດໄດ້ຖືກເປີດໂດຍ Admin."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "E-pasts ir veiksmīgi mainīts",
|
||||
"ChangesApplied": "Izmaiņas ir piemērotas",
|
||||
"Connect": "Savienot",
|
||||
"ContactInformation": "Kontaktinformācija",
|
||||
"CountCodesRemaining": "atlikušie kodi",
|
||||
"Disconnect": "Atvienot",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Abonementi",
|
||||
"TfaLoginSettings": "Pieteikšanās iestatījumi",
|
||||
"TwoFactorDescription": "Administrators visiem lietotājiem ir iespējojis divu faktoru autentifikāciju, izmantojot kodu ģenerējošu lietotni."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "E-mail is met succes gewijzigd ",
|
||||
"ChangesApplied": "Wijzigingen worden toegepast",
|
||||
"Connect": "Verbinden",
|
||||
"ContactInformation": "Contactinformatie",
|
||||
"CountCodesRemaining": "resterende codes",
|
||||
"Disconnect": "Loskoppelen",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Abonnementen",
|
||||
"TfaLoginSettings": "Inlog instellingen",
|
||||
"TwoFactorDescription": "Two-factor authenticatie via een code-genererende app was ingeschakeld voor alle gebruikers door de beheerder."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "E-mail został pomyślnie zmieniony ",
|
||||
"ChangesApplied": "Zmiany zostały zastosowane",
|
||||
"Connect": "Podłącz",
|
||||
"ContactInformation": "Dane kontaktowe",
|
||||
"CountCodesRemaining": "Pozostało kodów:",
|
||||
"Disconnect": "Rozłącz",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Subskrypcje",
|
||||
"TfaLoginSettings": "Ustawienia logowania",
|
||||
"TwoFactorDescription": "Weryfikacja dwuetapowa za pośrednictwem aplikacji generującej kody została włączona przez administratora dla wszystkich użytkowników."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "O e-mail foi alterado com sucesso",
|
||||
"ChangesApplied": "Alterações são aplicadas",
|
||||
"Connect": "Conectar",
|
||||
"ContactInformation": "Informação de Contato",
|
||||
"CountCodesRemaining": "códigos restantes",
|
||||
"Disconnect": "Desconectar",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Assinaturas",
|
||||
"TfaLoginSettings": "Ajustes de acesso",
|
||||
"TwoFactorDescription": "A autenticação de dois fatores por meio de um aplicativo de geração de código foi habilitada para todos os usuários pelo administrador."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "O e-mail foi alterado com êxito",
|
||||
"ChangesApplied": "As alterações são aplicadas",
|
||||
"Connect": "Ligar",
|
||||
"ContactInformation": "Informação de contacto",
|
||||
"CountCodesRemaining": "códigos restantes",
|
||||
"Disconnect": "Desligar",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Subscrições",
|
||||
"TfaLoginSettings": "Definições de acesso",
|
||||
"TwoFactorDescription": "A autenticação de dois fatores através de uma aplicação geradora de códigos foi ativada para todos os utilizadores pelo administrador."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "Adresa e-mail a fost modificată cu succes",
|
||||
"ChangesApplied": "Modificările au fost aplicate",
|
||||
"Connect": "Adaugă cont",
|
||||
"ContactInformation": "Informații de contact",
|
||||
"CountCodesRemaining": "codurile rămase ",
|
||||
"Disconnect": "Deconectare",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Subscripții",
|
||||
"TfaLoginSettings": "Setări de conexiune",
|
||||
"TwoFactorDescription": "Autentificarea cu doi factori prin aplicația de generare coduri a fost activată pentru toți utilizatorii de către administratorul."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "Email успешно изменен",
|
||||
"ChangesApplied": "Изменения успешно применены",
|
||||
"Connect": "Подключить",
|
||||
"ContactInformation": "Контактные данные",
|
||||
"CountCodesRemaining": "оставшиеся коды",
|
||||
"Disconnect": "Отключить",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Подписки",
|
||||
"TfaLoginSettings": "Настройки входа",
|
||||
"TwoFactorDescription": "Двухфакторная аутентификация с помощью приложения для генерации кодов включена администратором для всех пользователей."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "E-mail bol úspešne zmenený ",
|
||||
"ChangesApplied": "Zmeny boli vykonané",
|
||||
"Connect": "Pripojiť",
|
||||
"ContactInformation": "Kontaktné informácie",
|
||||
"CountCodesRemaining": "zostávajúce kódy",
|
||||
"Disconnect": "Odpojiť",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Predplatné",
|
||||
"TfaLoginSettings": "Nastavenia prihlasovania",
|
||||
"TwoFactorDescription": "Správca povolil všetkým používateľom dvojfaktorovú autentifikáciu prostredníctvom aplikácie generujúcej kód."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "E-mail naslov je bil uspešno spremenjen ",
|
||||
"ChangesApplied": "Spremembe so uporabljene",
|
||||
"Connect": "Poveži",
|
||||
"ContactInformation": "Kontaktne informacije",
|
||||
"CountCodesRemaining": "preostale kode",
|
||||
"Disconnect": "Prekinitev",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Naročnine",
|
||||
"TfaLoginSettings": "Nastavitve za prijavo",
|
||||
"TwoFactorDescription": "Administrator je za vse uporabnike omogočil dvofaktorsko avtentikacijo preko aplikacije za ustvarjanje kode."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "E-posta başarıyla değiştirildi ",
|
||||
"ChangesApplied": "Değişiklikler uygulandı",
|
||||
"Connect": "Bağlan",
|
||||
"ContactInformation": "İletişim bilgileri",
|
||||
"CountCodesRemaining": "kalan kodlar",
|
||||
"Disconnect": "Bağlantıyı kes",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Abonelikler",
|
||||
"TfaLoginSettings": "Giriş ayarları",
|
||||
"TwoFactorDescription": "Tüm kullanıcılar için kod üreten bir uygulama aracılığıyla iki faktörlü kimlik doğrulama yönetici tarafından etkinleştirildi."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "Електронну пошту успішно змінено ",
|
||||
"ChangesApplied": "Зміни застосовано",
|
||||
"Connect": "Підключити",
|
||||
"ContactInformation": "Контактна інформація",
|
||||
"CountCodesRemaining": "кодів залишилося",
|
||||
"Disconnect": "Відключити",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Підписки",
|
||||
"TfaLoginSettings": "Параметри входу",
|
||||
"TwoFactorDescription": "Двофакторна автентифікація за допомогою програми генерування кодів була ввімкнена для всіх користувачів адміністратором."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "Email đã được thay đổi thành công",
|
||||
"ChangesApplied": "Thay đổi đã được áp dụng",
|
||||
"Connect": "Kết nối",
|
||||
"ContactInformation": "Thông tin liên hệ",
|
||||
"CountCodesRemaining": "mã còn lại",
|
||||
"Disconnect": "Ngắt kết nối",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "Đăng ký",
|
||||
"TfaLoginSettings": "Thiết lập đăng nhập ",
|
||||
"TwoFactorDescription": " Xác thực hai yếu tố qua ứng dụng tạo mã đã được quản trị viên bật cho tất cả người dùng."
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
{
|
||||
"ChangeEmailSuccess": "邮箱已成功更改",
|
||||
"ChangesApplied": "已应用更改",
|
||||
"Connect": "连接",
|
||||
"ContactInformation": "联系信息",
|
||||
"CountCodesRemaining": "剩余代码",
|
||||
"Disconnect": "断开连接",
|
||||
@ -18,4 +17,4 @@
|
||||
"Subscriptions": "订阅",
|
||||
"TfaLoginSettings": "登录设置",
|
||||
"TwoFactorDescription": "管理员为所有用户启用了通过代码生成应用进行的双因素身份认证功能。"
|
||||
}
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ class SectionBodyContent extends React.PureComponent {
|
||||
onClick={(e) => this.linkAccount(item.provider, item.url, e)}
|
||||
isHovered={true}
|
||||
>
|
||||
{t("Connect")}
|
||||
{t("Common:Connect")}
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
|
3
public/images/actions.plus.icon.react.svg
Normal file
3
public/images/actions.plus.icon.react.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9 7V1H7V7H1V9H7V15H9V9H15V7H9Z" fill="#333333"/>
|
||||
</svg>
|
After Width: | Height: | Size: 202 B |
@ -145,5 +145,6 @@
|
||||
"Video": "Video",
|
||||
"View": "Baxın",
|
||||
"ViewWeb": "Veb versiyaya baxın",
|
||||
"Warning": "Xəbərdarlıq"
|
||||
"Warning": "Xəbərdarlıq",
|
||||
"Connect": "Qoşulmaq"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "Видео",
|
||||
"View": "Преглед",
|
||||
"ViewWeb": "Отиди към уеб версия",
|
||||
"Warning": "Внимание"
|
||||
"Warning": "Внимание",
|
||||
"Connect": "Свържи"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "Video",
|
||||
"View": "Zobrazit",
|
||||
"ViewWeb": "Zobrazit webovou verzi",
|
||||
"Warning": "Varování"
|
||||
"Warning": "Varování",
|
||||
"Connect": "Připojit"
|
||||
}
|
||||
|
@ -150,5 +150,6 @@
|
||||
"Video": "Video",
|
||||
"View": "Anzeigen",
|
||||
"ViewWeb": "Web-Version öffnen",
|
||||
"Warning": "Warnung"
|
||||
"Warning": "Warnung",
|
||||
"Connect": "Verbinden"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "Βίντεο",
|
||||
"View": "Προβολή",
|
||||
"ViewWeb": "Προβολή διαδικτυακής έκδοσης",
|
||||
"Warning": "Προειδοποίηση"
|
||||
"Warning": "Προειδοποίηση",
|
||||
"Connect": "Σύνδεση"
|
||||
}
|
||||
|
@ -157,5 +157,6 @@
|
||||
"Video": "Video",
|
||||
"View": "View",
|
||||
"ViewWeb": "View web version",
|
||||
"Warning": "Warning"
|
||||
"Warning": "Warning",
|
||||
"Connect": "Connect"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "Vídeo",
|
||||
"View": "Ver",
|
||||
"ViewWeb": "Ver versión web",
|
||||
"Warning": "Advertencia"
|
||||
"Warning": "Advertencia",
|
||||
"Connect": "Conectar"
|
||||
}
|
||||
|
@ -144,5 +144,6 @@
|
||||
"Video": "Video",
|
||||
"View": "Näkymä",
|
||||
"ViewWeb": "Näytä verkkoversio",
|
||||
"Warning": "Varoitus"
|
||||
"Warning": "Varoitus",
|
||||
"Connect": "Yhdistä"
|
||||
}
|
||||
|
@ -150,5 +150,6 @@
|
||||
"Video": "Vidéo",
|
||||
"View": "Afficher",
|
||||
"ViewWeb": "Voir la version web",
|
||||
"Warning": "Attention"
|
||||
"Warning": "Attention",
|
||||
"Connect": "Connexion"
|
||||
}
|
||||
|
@ -150,5 +150,6 @@
|
||||
"Video": "Video",
|
||||
"View": "Visualizza",
|
||||
"ViewWeb": "Visualizza la versione web",
|
||||
"Warning": "Avviso"
|
||||
"Warning": "Avviso",
|
||||
"Connect": "Collega"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "動画",
|
||||
"View": "ビュー",
|
||||
"ViewWeb": "ウェブ版を表示する",
|
||||
"Warning": "警告"
|
||||
"Warning": "警告",
|
||||
"Connect": "接続"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "동영상",
|
||||
"View": "보기",
|
||||
"ViewWeb": "웹 버전 보기",
|
||||
"Warning": "경고"
|
||||
"Warning": "경고",
|
||||
"Connect": "연결"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "ວິດີໂອ",
|
||||
"View": "ມຸມມອງ",
|
||||
"ViewWeb": "ເປີດຜ່ານຫນ້າເວັບ",
|
||||
"Warning": "ແຈ້ງເຕືອນ"
|
||||
"Warning": "ແຈ້ງເຕືອນ",
|
||||
"Connect": "ຕິດຕໍ່"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "Video",
|
||||
"View": "Skatīt",
|
||||
"ViewWeb": "Skatīt tīmekļa versiju",
|
||||
"Warning": "Brīdinājums"
|
||||
"Warning": "Brīdinājums",
|
||||
"Connect": "Savienot"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "Video",
|
||||
"View": "Bekijk",
|
||||
"ViewWeb": "Webversie bekijken",
|
||||
"Warning": "Waarschuwing"
|
||||
"Warning": "Waarschuwing",
|
||||
"Connect": "Verbinden"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "Wideo",
|
||||
"View": "Podgląd",
|
||||
"ViewWeb": "Zobacz wersję internetową",
|
||||
"Warning": "Ostrzeżenie"
|
||||
"Warning": "Ostrzeżenie",
|
||||
"Connect": "Podłącz"
|
||||
}
|
||||
|
@ -150,5 +150,6 @@
|
||||
"Video": "Vídeo",
|
||||
"View": "Ver",
|
||||
"ViewWeb": "Veja a versão web",
|
||||
"Warning": "Aviso"
|
||||
"Warning": "Aviso",
|
||||
"Connect": "Conectar"
|
||||
}
|
||||
|
@ -144,5 +144,6 @@
|
||||
"Video": "Vídeo",
|
||||
"View": "Ver",
|
||||
"ViewWeb": "Ver versão web",
|
||||
"Warning": "Aviso"
|
||||
"Warning": "Aviso",
|
||||
"Connect": "Ligar"
|
||||
}
|
||||
|
@ -147,5 +147,6 @@
|
||||
"Video": "Video",
|
||||
"View": "Vizualizare",
|
||||
"ViewWeb": "Accesați versiunea online",
|
||||
"Warning": "Avertisment"
|
||||
"Warning": "Avertisment",
|
||||
"Connect": "Adaugă cont"
|
||||
}
|
||||
|
@ -157,5 +157,6 @@
|
||||
"Video": "Видео",
|
||||
"View": "Просмотр",
|
||||
"ViewWeb": "Просмотреть веб-версию",
|
||||
"Warning": "Внимание"
|
||||
"Warning": "Внимание",
|
||||
"Connect": "Подключить"
|
||||
}
|
||||
|
@ -148,5 +148,6 @@
|
||||
"Video": "Video",
|
||||
"View": "Vyhliadka",
|
||||
"ViewWeb": "Zobraziť webovú verziu",
|
||||
"Warning": "Upozornenie"
|
||||
"Warning": "Upozornenie",
|
||||
"Connect": "Pripojiť"
|
||||
}
|
||||
|
@ -144,5 +144,6 @@
|
||||
"Video": "Video",
|
||||
"View": "Ogled",
|
||||
"ViewWeb": "Ogled spletne verzije",
|
||||
"Warning": "Opozorilo"
|
||||
"Warning": "Opozorilo",
|
||||
"Connect": "Poveži"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "Video",
|
||||
"View": "Görüntüle",
|
||||
"ViewWeb": "Web sürümünü görüntüle",
|
||||
"Warning": "Uyarı"
|
||||
"Warning": "Uyarı",
|
||||
"Connect": "Bağlan"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "Відео",
|
||||
"View": "Переглянути",
|
||||
"ViewWeb": "Переглянути веб-версію",
|
||||
"Warning": "Попередження"
|
||||
"Warning": "Попередження",
|
||||
"Connect": "Підключити"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "Video",
|
||||
"View": "Xem",
|
||||
"ViewWeb": "Xem phiên bản web",
|
||||
"Warning": "Cảnh báo"
|
||||
"Warning": "Cảnh báo",
|
||||
"Connect": "Kết nối"
|
||||
}
|
||||
|
@ -145,5 +145,6 @@
|
||||
"Video": "视频",
|
||||
"View": "查看",
|
||||
"ViewWeb": "查看网页版",
|
||||
"Warning": "警告"
|
||||
"Warning": "警告",
|
||||
"Connect": "连接"
|
||||
}
|
||||
|
101
web/ASC.Web.Client/src/HOCs/withLoading.js
Normal file
101
web/ASC.Web.Client/src/HOCs/withLoading.js
Normal file
@ -0,0 +1,101 @@
|
||||
import React from "react";
|
||||
import { observer, inject } from "mobx-react";
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
import { isSmallTablet } from "@appserver/components/utils/device";
|
||||
|
||||
const withLoading = (WrappedComponent) => {
|
||||
const withLoading = (props) => {
|
||||
const {
|
||||
isLoadedArticleBody,
|
||||
isLoadedArticleHeader,
|
||||
isLoadedSectionHeader,
|
||||
isLoadedSubmenu,
|
||||
isLoadedLngTZSettings,
|
||||
isLoadedPortalRenaming,
|
||||
isLoadedCustomization,
|
||||
isLoadedCustomizationNavbar,
|
||||
isLoadedWelcomePageSettings,
|
||||
} = props;
|
||||
|
||||
const pathname = location.pathname;
|
||||
const index = pathname.lastIndexOf("/");
|
||||
const setting = pathname.slice(index + 1);
|
||||
|
||||
const viewMobile = isSmallTablet() || isMobileOnly;
|
||||
|
||||
const isLoadedCustomizationSettings =
|
||||
isLoadedCustomization &&
|
||||
isLoadedLngTZSettings &&
|
||||
isLoadedWelcomePageSettings &&
|
||||
isLoadedPortalRenaming &&
|
||||
isLoadedArticleBody &&
|
||||
isLoadedArticleHeader &&
|
||||
isLoadedSectionHeader &&
|
||||
isLoadedSubmenu;
|
||||
|
||||
const isLoadedCustomizationNavbarSettings =
|
||||
isLoadedCustomizationNavbar &&
|
||||
isLoadedArticleBody &&
|
||||
isLoadedArticleHeader &&
|
||||
isLoadedSectionHeader &&
|
||||
isLoadedSubmenu;
|
||||
|
||||
const isLoadedCustomizationSettingLngTZSettings =
|
||||
isLoadedArticleBody &&
|
||||
isLoadedArticleHeader &&
|
||||
isLoadedSectionHeader &&
|
||||
isLoadedLngTZSettings;
|
||||
|
||||
const isLoadedCustomizationSettingWelcomePageSettings =
|
||||
isLoadedArticleBody &&
|
||||
isLoadedArticleHeader &&
|
||||
isLoadedSectionHeader &&
|
||||
isLoadedWelcomePageSettings;
|
||||
|
||||
const isLoadedCustomizationSettingPortalRenaming =
|
||||
isLoadedArticleBody &&
|
||||
isLoadedArticleHeader &&
|
||||
isLoadedSectionHeader &&
|
||||
isLoadedPortalRenaming;
|
||||
|
||||
const isLoadedPage =
|
||||
setting === "language-and-time-zone"
|
||||
? isLoadedCustomizationSettingLngTZSettings
|
||||
: setting === "welcome-page-settings"
|
||||
? isLoadedCustomizationSettingWelcomePageSettings
|
||||
: setting === "portal-renaming"
|
||||
? isLoadedCustomizationSettingPortalRenaming
|
||||
: viewMobile
|
||||
? isLoadedCustomizationNavbarSettings
|
||||
: isLoadedCustomizationSettings;
|
||||
|
||||
return <WrappedComponent {...props} isLoadedPage={isLoadedPage} />;
|
||||
};
|
||||
|
||||
return inject(({ common }) => {
|
||||
const {
|
||||
isLoadedArticleBody,
|
||||
isLoadedArticleHeader,
|
||||
isLoadedSectionHeader,
|
||||
isLoadedSubmenu,
|
||||
isLoadedLngTZSettings,
|
||||
isLoadedPortalRenaming,
|
||||
isLoadedCustomization,
|
||||
isLoadedCustomizationNavbar,
|
||||
isLoadedWelcomePageSettings,
|
||||
} = common;
|
||||
|
||||
return {
|
||||
isLoadedArticleBody,
|
||||
isLoadedArticleHeader,
|
||||
isLoadedSectionHeader,
|
||||
isLoadedSubmenu,
|
||||
isLoadedLngTZSettings,
|
||||
isLoadedPortalRenaming,
|
||||
isLoadedCustomization,
|
||||
isLoadedCustomizationNavbar,
|
||||
isLoadedWelcomePageSettings,
|
||||
};
|
||||
})(observer(withLoading));
|
||||
};
|
||||
export default withLoading;
|
@ -535,11 +535,13 @@ const Shell = ({ items = [], page = "home", ...rest }) => {
|
||||
component={ComingSoonRoute}
|
||||
/>
|
||||
<PrivateRoute path={PAYMENTS_URL} component={PaymentsRoute} />
|
||||
<PrivateRoute
|
||||
restricted
|
||||
path={SETTINGS_URL}
|
||||
component={SettingsRoute}
|
||||
/>
|
||||
{!personal && (
|
||||
<PrivateRoute
|
||||
restricted
|
||||
path={SETTINGS_URL}
|
||||
component={SettingsRoute}
|
||||
/>
|
||||
)}
|
||||
<PrivateRoute
|
||||
exact
|
||||
allowForMe
|
||||
|
@ -121,14 +121,15 @@ const HeaderNav = ({
|
||||
settingsModule && useCallback(() => history.push(settingsUrl), []);
|
||||
|
||||
const getCurrentUserActions = useCallback(() => {
|
||||
const settings = settingsModule
|
||||
? {
|
||||
key: "SettingsBtn",
|
||||
label: t("Common:Settings"),
|
||||
onClick: onSettingsClick,
|
||||
url: settingsUrl,
|
||||
}
|
||||
: null;
|
||||
const settings =
|
||||
settingsModule && !isPersonal
|
||||
? {
|
||||
key: "SettingsBtn",
|
||||
label: t("Common:Settings"),
|
||||
onClick: onSettingsClick,
|
||||
url: settingsUrl,
|
||||
}
|
||||
: null;
|
||||
|
||||
const actions = [
|
||||
{
|
||||
|
@ -9,6 +9,7 @@ import { isArrayEqual } from "@appserver/components/utils/array";
|
||||
import { isMobileOnly } from "react-device-detect";
|
||||
|
||||
import { isMobile } from "@appserver/components/utils/device";
|
||||
import withLoading from "../../../../../../HOCs/withLoading";
|
||||
|
||||
import {
|
||||
//getKeyByLink,
|
||||
@ -19,6 +20,7 @@ import {
|
||||
} from "../../../utils";
|
||||
|
||||
import CatalogItem from "@appserver/components/catalog-item";
|
||||
import LoaderArticleBody from "./loaderArticleBody";
|
||||
|
||||
class ArticleBodyContent extends React.Component {
|
||||
constructor(props) {
|
||||
@ -57,6 +59,12 @@ class ArticleBodyContent extends React.Component {
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const { isLoaded, tReady, setIsLoadedArticleBody } = this.props;
|
||||
|
||||
const isLoadedSetting = isLoaded && tReady;
|
||||
|
||||
if (isLoadedSetting) setIsLoadedArticleBody(isLoadedSetting);
|
||||
|
||||
if (!isArrayEqual(prevState.selectedKeys, this.state.selectedKeys)) {
|
||||
const { selectedKeys } = this.state;
|
||||
|
||||
@ -145,14 +153,27 @@ class ArticleBodyContent extends React.Component {
|
||||
|
||||
render() {
|
||||
const items = this.catalogItems();
|
||||
const { isLoadedPage } = this.props;
|
||||
const commonSettings = location.pathname.includes("common");
|
||||
// TODO: styles fix
|
||||
|
||||
return <>{items}</>;
|
||||
const showLoader = commonSettings ? !isLoadedPage : false;
|
||||
|
||||
return showLoader ? <LoaderArticleBody /> : <>{items}</>;
|
||||
}
|
||||
}
|
||||
|
||||
export default inject(({ auth }) => {
|
||||
export default inject(({ auth, common }) => {
|
||||
const { isLoaded, setIsLoadedArticleBody } = common;
|
||||
|
||||
return {
|
||||
showText: auth.settingsStore.showText,
|
||||
toggleArticleOpen: auth.settingsStore.toggleArticleOpen,
|
||||
isLoaded,
|
||||
setIsLoadedArticleBody,
|
||||
};
|
||||
})(withRouter(withTranslation("Settings")(observer(ArticleBodyContent))));
|
||||
})(
|
||||
withLoading(
|
||||
withRouter(withTranslation("Settings")(observer(ArticleBodyContent)))
|
||||
)
|
||||
);
|
||||
|
@ -7,8 +7,9 @@ import Headline from "@appserver/common/components/Headline";
|
||||
import IconButton from "@appserver/components/icon-button";
|
||||
import GroupButtonsMenu from "@appserver/components/group-buttons-menu";
|
||||
import DropDownItem from "@appserver/components/drop-down-item";
|
||||
|
||||
import LoaderSectionHeader from "../loaderSectionHeader";
|
||||
import { tablet, desktop } from "@appserver/components/utils/device";
|
||||
import withLoading from "../../../../../../HOCs/withLoading";
|
||||
|
||||
import {
|
||||
getKeyByLink,
|
||||
@ -132,6 +133,12 @@ class SectionHeaderContent extends React.Component {
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { isLoaded, tReady, setIsLoadedSectionHeader } = this.props;
|
||||
|
||||
const isLoadedSetting = isLoaded && tReady;
|
||||
|
||||
if (isLoadedSetting) setIsLoadedSectionHeader(isLoadedSetting);
|
||||
|
||||
const arrayOfParams = this.getArrayOfParams();
|
||||
|
||||
const key = getKeyByLink(arrayOfParams, settingsTree);
|
||||
@ -214,6 +221,7 @@ class SectionHeaderContent extends React.Component {
|
||||
isHeaderChecked,
|
||||
isHeaderVisible,
|
||||
selection,
|
||||
isLoadedPage,
|
||||
} = this.props;
|
||||
const { header, isCategoryOrHeader } = this.state;
|
||||
const arrayOfParams = this.getArrayOfParams();
|
||||
@ -241,6 +249,8 @@ class SectionHeaderContent extends React.Component {
|
||||
},
|
||||
];
|
||||
|
||||
const commonSettings = location.pathname.includes("common");
|
||||
const showLoader = commonSettings ? !isLoadedPage : false;
|
||||
return (
|
||||
<StyledContainer isHeaderVisible={isHeaderVisible}>
|
||||
{isHeaderVisible ? (
|
||||
@ -257,6 +267,8 @@ class SectionHeaderContent extends React.Component {
|
||||
selected={menuItems[0].label}
|
||||
/>
|
||||
</div>
|
||||
) : showLoader ? (
|
||||
<LoaderSectionHeader />
|
||||
) : (
|
||||
<HeaderContainer>
|
||||
{!isCategoryOrHeader && arrayOfParams[0] && (
|
||||
@ -289,7 +301,7 @@ class SectionHeaderContent extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default inject(({ auth, setup }) => {
|
||||
export default inject(({ auth, setup, common }) => {
|
||||
const { customNames } = auth.settingsStore;
|
||||
const { addUsers, removeAdmins } = setup.headerAction;
|
||||
const { toggleSelector } = setup;
|
||||
@ -304,7 +316,7 @@ export default inject(({ auth, setup }) => {
|
||||
selection,
|
||||
} = setup.selectionStore;
|
||||
const { admins, selectorIsOpen } = setup.security.accessRight;
|
||||
|
||||
const { isLoaded, setIsLoadedSectionHeader } = common;
|
||||
return {
|
||||
addUsers,
|
||||
removeAdmins,
|
||||
@ -320,9 +332,13 @@ export default inject(({ auth, setup }) => {
|
||||
toggleSelector,
|
||||
selectorIsOpen,
|
||||
selection,
|
||||
isLoaded,
|
||||
setIsLoadedSectionHeader,
|
||||
};
|
||||
})(
|
||||
withRouter(
|
||||
withTranslation(["Settings", "Common"])(observer(SectionHeaderContent))
|
||||
withLoading(
|
||||
withRouter(
|
||||
withTranslation(["Settings", "Common"])(observer(SectionHeaderContent))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -4,11 +4,11 @@ import { ArticleHeaderContent, ArticleBodyContent } from "./Article";
|
||||
import { SectionHeaderContent, SectionPagingContent } from "./Section";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import Section from "@appserver/common/components/Section";
|
||||
import LoaderSectionHeader from "./Section/loaderSectionHeader";
|
||||
|
||||
const ArticleSettings = React.memo(() => {
|
||||
import withLoading from "../../../../HOCs/withLoading";
|
||||
import commonIconsStyles from "@appserver/components/utils/common-icons-style";
|
||||
const ArticleSettings = React.memo(({ isLoadedPage }) => {
|
||||
return (
|
||||
<Article>
|
||||
<Article isLoadedPage={isLoadedPage}>
|
||||
<Article.Header>
|
||||
<ArticleHeaderContent />
|
||||
</Article.Header>
|
||||
@ -26,6 +26,7 @@ const Layout = ({
|
||||
language,
|
||||
children,
|
||||
addUsers,
|
||||
isLoadedPage,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
currentProductId !== "settings" && setCurrentProductId("settings");
|
||||
@ -33,7 +34,7 @@ const Layout = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<ArticleSettings />
|
||||
<ArticleSettings isLoadedPage={isLoadedPage} />
|
||||
<Section withBodyScroll={true}>
|
||||
<Section.SectionHeader>
|
||||
<SectionHeaderContent />
|
||||
@ -53,9 +54,10 @@ const Layout = ({
|
||||
export default inject(({ auth, setup }) => {
|
||||
const { language, settingsStore } = auth;
|
||||
const { addUsers } = setup.headerAction;
|
||||
|
||||
return {
|
||||
language,
|
||||
setCurrentProductId: settingsStore.setCurrentProductId,
|
||||
addUsers,
|
||||
};
|
||||
})(observer(Layout));
|
||||
})(withLoading(observer(Layout)));
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import styled from "styled-components";
|
||||
import Text from "@appserver/components/text";
|
||||
@ -11,9 +11,8 @@ import withCultureNames from "@appserver/common/hoc/withCultureNames";
|
||||
import history from "@appserver/common/history";
|
||||
import { Base } from "@appserver/components/themes";
|
||||
import LoaderCustomizationNavbar from "./sub-components/loaderCustomizationNavbar";
|
||||
|
||||
import { StyledArrowRightIcon } from "../common/settingsCustomization/StyledSettings";
|
||||
|
||||
import { withRouter } from "react-router";
|
||||
const StyledComponent = styled.div`
|
||||
padding-top: 13px;
|
||||
|
||||
@ -47,15 +46,28 @@ const StyledComponent = styled.div`
|
||||
|
||||
StyledComponent.defaultProps = { theme: Base };
|
||||
|
||||
const CustomizationNavbar = ({ t, theme, helpUrlCommonSettings }) => {
|
||||
const CustomizationNavbar = ({
|
||||
t,
|
||||
theme,
|
||||
helpUrlCommonSettings,
|
||||
isLoaded,
|
||||
tReady,
|
||||
setIsLoadedCustomizationNavbar,
|
||||
isLoadedPage,
|
||||
}) => {
|
||||
const isLoadedSetting = isLoaded && tReady;
|
||||
useEffect(() => {
|
||||
if (isLoadedSetting) setIsLoadedCustomizationNavbar(isLoadedSetting);
|
||||
}, [isLoadedSetting]);
|
||||
|
||||
const onClickLink = (e) => {
|
||||
e.preventDefault();
|
||||
history.push(e.target.pathname);
|
||||
};
|
||||
|
||||
//return <LoaderCustomizationNavbar />;
|
||||
|
||||
return (
|
||||
return !isLoadedPage ? (
|
||||
<LoaderCustomizationNavbar />
|
||||
) : (
|
||||
<StyledComponent>
|
||||
<div className="category-item-wrapper">
|
||||
<div className="category-item-heading">
|
||||
@ -128,14 +140,19 @@ const CustomizationNavbar = ({ t, theme, helpUrlCommonSettings }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ auth }) => {
|
||||
export default inject(({ auth, common }) => {
|
||||
const { helpUrlCommonSettings, theme } = auth.settingsStore;
|
||||
const { isLoaded, setIsLoadedCustomizationNavbar } = common;
|
||||
return {
|
||||
theme,
|
||||
helpUrlCommonSettings,
|
||||
isLoaded,
|
||||
setIsLoadedCustomizationNavbar,
|
||||
};
|
||||
})(
|
||||
withCultureNames(
|
||||
observer(withTranslation(["Settings", "Common"])(CustomizationNavbar))
|
||||
withRouter(
|
||||
withCultureNames(
|
||||
observer(withTranslation(["Settings", "Common"])(CustomizationNavbar))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -11,6 +11,8 @@ import CustomizationNavbar from "./customization-navbar";
|
||||
import { Base } from "@appserver/components/themes";
|
||||
import { setDocumentTitle } from "../../../../../helpers/utils";
|
||||
import LoaderDescriptionCustomization from "./sub-components/loaderDescriptionCustomization";
|
||||
import { withRouter } from "react-router";
|
||||
import withLoading from "../../../../../HOCs/withLoading";
|
||||
|
||||
const StyledComponent = styled.div`
|
||||
width: 100%;
|
||||
@ -65,9 +67,24 @@ const StyledComponent = styled.div`
|
||||
|
||||
StyledComponent.defaultProps = { theme: Base };
|
||||
|
||||
const Customization = ({ t, setIsLoadingArticleSettings }) => {
|
||||
const Customization = (props) => {
|
||||
const { t, isLoaded, tReady, setIsLoadedCustomization, isLoadedPage } = props;
|
||||
const [mobileView, setMobileView] = useState(true);
|
||||
const [isLoadingCustomization, setIsLoadingCustomization] = useState(false);
|
||||
|
||||
const isLoadedSetting = isLoaded && tReady;
|
||||
|
||||
useEffect(() => {
|
||||
setDocumentTitle(t("Customization"));
|
||||
window.addEventListener("resize", checkInnerWidth);
|
||||
|
||||
return () => window.removeEventListener("resize", checkInnerWidth);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoadedSetting) {
|
||||
setIsLoadedCustomization(isLoadedSetting);
|
||||
}
|
||||
}, [isLoadedSetting]);
|
||||
|
||||
const checkInnerWidth = () => {
|
||||
if (isSmallTablet()) {
|
||||
@ -77,47 +94,35 @@ const Customization = ({ t, setIsLoadingArticleSettings }) => {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setDocumentTitle(t("Customization"));
|
||||
//TODO: Add method to get the portal name
|
||||
setIsLoadingArticleSettings(true);
|
||||
setTimeout(() => {
|
||||
setIsLoadingCustomization(false);
|
||||
setIsLoadingArticleSettings(isLoadingCustomization);
|
||||
}, 3000);
|
||||
|
||||
window.addEventListener("resize", checkInnerWidth);
|
||||
return () => window.removeEventListener("resize", checkInnerWidth);
|
||||
}, []);
|
||||
|
||||
const isMobile = !!(isSmallTablet() && mobileView);
|
||||
|
||||
return isMobile ? (
|
||||
<CustomizationNavbar />
|
||||
<CustomizationNavbar isLoadedPage={isLoadedPage} />
|
||||
) : (
|
||||
<StyledComponent>
|
||||
<div className="category-description">{`${t(
|
||||
"Settings:CustomizationDescription"
|
||||
)}`}</div>
|
||||
{/* <LoaderDescriptionCustomization /> */}
|
||||
<LanguageAndTimeZone
|
||||
isLoadingCustomization={isLoadingCustomization}
|
||||
isMobileView={isMobile}
|
||||
/>
|
||||
{!isLoadedPage ? (
|
||||
<LoaderDescriptionCustomization />
|
||||
) : (
|
||||
<div className="category-description">{`${t(
|
||||
"Settings:CustomizationDescription"
|
||||
)}`}</div>
|
||||
)}
|
||||
<LanguageAndTimeZone isMobileView={isMobile} />
|
||||
<WelcomePageSettings isMobileView={isMobile} />
|
||||
<PortalRenaming isMobileView={isMobile} />
|
||||
</StyledComponent>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ setup }) => {
|
||||
const { setIsLoadingArticleSettings } = setup;
|
||||
export default inject(({ common }) => {
|
||||
const { isLoaded, setIsLoadedCustomization } = common;
|
||||
|
||||
return {
|
||||
setIsLoadingArticleSettings,
|
||||
isLoaded,
|
||||
setIsLoadedCustomization,
|
||||
};
|
||||
})(
|
||||
withCultureNames(
|
||||
withTranslation(["Settings", "Common"])(observer(Customization))
|
||||
withLoading(
|
||||
withRouter(withTranslation(["Settings", "Common"])(observer(Customization)))
|
||||
)
|
||||
);
|
||||
|
@ -5,15 +5,35 @@ import { withTranslation } from "react-i18next";
|
||||
import { AppServerConfig } from "@appserver/common/constants";
|
||||
import { combineUrl } from "@appserver/common/utils";
|
||||
import config from "../../../../../../package.json";
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
import Customization from "./customization";
|
||||
import WhiteLabel from "./whitelabel";
|
||||
import LoaderSubmenu from "./sub-components/loaderSubmenu";
|
||||
import withLoading from "../../../../../HOCs/withLoading";
|
||||
|
||||
const SubmenuCommon = (props) => {
|
||||
const { t, history } = props;
|
||||
const {
|
||||
t,
|
||||
history,
|
||||
isLoaded,
|
||||
tReady,
|
||||
setIsLoadedSubmenu,
|
||||
isLoadedPage,
|
||||
} = props;
|
||||
const [currentTab, setCurrentTab] = useState(0);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const isLoadedSetting = isLoaded && tReady;
|
||||
|
||||
useEffect(() => {
|
||||
const path = location.pathname;
|
||||
const currentTab = data.findIndex((item) => path.includes(item.id));
|
||||
if (currentTab !== -1) {
|
||||
setCurrentTab(currentTab);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoadedSetting) setIsLoadedSubmenu(isLoadedSetting);
|
||||
}, [isLoadedSetting]);
|
||||
|
||||
const data = [
|
||||
{
|
||||
@ -28,15 +48,6 @@ const SubmenuCommon = (props) => {
|
||||
},
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
const path = location.pathname;
|
||||
const currentTab = data.findIndex((item) => path.includes(item.id));
|
||||
if (currentTab !== -1) {
|
||||
setCurrentTab(currentTab);
|
||||
}
|
||||
//setIsLoading(true);
|
||||
}, []);
|
||||
|
||||
const onSelect = (e) => {
|
||||
history.push(
|
||||
combineUrl(
|
||||
@ -46,16 +57,23 @@ const SubmenuCommon = (props) => {
|
||||
)
|
||||
);
|
||||
};
|
||||
//TODO: isLoading
|
||||
return isLoading ? (
|
||||
<LoaderSubmenu />
|
||||
) : (
|
||||
|
||||
return (
|
||||
<Submenu
|
||||
data={data}
|
||||
startSelect={currentTab}
|
||||
onSelect={(e) => onSelect(e)}
|
||||
isLoading={!isLoadedPage}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default withTranslation("Settings")(withRouter(SubmenuCommon));
|
||||
export default inject(({ common }) => {
|
||||
const { isLoaded, setIsLoadedSubmenu } = common;
|
||||
return {
|
||||
isLoaded,
|
||||
setIsLoadedSubmenu,
|
||||
};
|
||||
})(
|
||||
withLoading(withRouter(withTranslation("Settings")(observer(SubmenuCommon))))
|
||||
);
|
||||
|
@ -3,7 +3,6 @@ import { withTranslation } from "react-i18next";
|
||||
import FieldContainer from "@appserver/components/field-container";
|
||||
import ToggleButton from "@appserver/components/toggle-button";
|
||||
import ComboBox from "@appserver/components/combobox";
|
||||
import Loader from "@appserver/components/loader";
|
||||
import toastr from "@appserver/components/toast/toastr";
|
||||
import HelpButton from "@appserver/components/help-button";
|
||||
import SaveCancelButtons from "@appserver/components/save-cancel-buttons";
|
||||
@ -11,8 +10,6 @@ import { saveToSessionStorage, getFromSessionStorage } from "../../../utils";
|
||||
import { setDocumentTitle } from "../../../../../../helpers/utils";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { LANGUAGE } from "@appserver/common/constants";
|
||||
import { convertLanguage } from "@appserver/common/utils";
|
||||
import withCultureNames from "@appserver/common/hoc/withCultureNames";
|
||||
import { LanguageTimeSettingsTooltip } from "../sub-components/common-tooltips";
|
||||
import { combineUrl } from "@appserver/common/utils";
|
||||
import { AppServerConfig } from "@appserver/common/constants";
|
||||
@ -23,12 +20,21 @@ import { isSmallTablet } from "@appserver/components/utils/device";
|
||||
import checkScrollSettingsBlock from "../utils";
|
||||
import { StyledSettingsComponent, StyledScrollbar } from "./StyledSettings";
|
||||
import LoaderCustomization from "../sub-components/loaderCustomization";
|
||||
import withLoading from "../../../../../../HOCs/withLoading";
|
||||
|
||||
const mapTimezonesToArray = (timezones) => {
|
||||
return timezones.map((timezone) => {
|
||||
return { key: timezone.id, label: timezone.displayName };
|
||||
});
|
||||
};
|
||||
|
||||
const mapCulturesToArray = (cultures, i18n) => {
|
||||
const t = i18n.getFixedT(null, "Common");
|
||||
return cultures.map((culture) => {
|
||||
return { key: culture, label: t(`Culture_${culture}`) };
|
||||
});
|
||||
};
|
||||
|
||||
const findSelectedItemByKey = (items, selectedItemKey) => {
|
||||
return items.find((item) => item.key === selectedItemKey);
|
||||
};
|
||||
@ -44,25 +50,7 @@ class LanguageAndTimeZone extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const {
|
||||
portalLanguage,
|
||||
portalTimeZoneId,
|
||||
rawTimezones,
|
||||
cultureNames,
|
||||
/*organizationName,*/
|
||||
t,
|
||||
//i18n,
|
||||
} = props;
|
||||
|
||||
const timezones = mapTimezonesToArray(rawTimezones);
|
||||
const language = findSelectedItemByKey(
|
||||
cultureNames,
|
||||
convertLanguage(portalLanguage || cultureNames[0])
|
||||
);
|
||||
const timezone = findSelectedItemByKey(
|
||||
timezones,
|
||||
portalTimeZoneId || timezones[0]
|
||||
);
|
||||
const { t } = props;
|
||||
|
||||
languageFromSessionStorage = getFromSessionStorage("language");
|
||||
languageDefaultFromSessionStorage = getFromSessionStorage(
|
||||
@ -76,13 +64,11 @@ class LanguageAndTimeZone extends React.Component {
|
||||
setDocumentTitle(t("StudioTimeLanguageSettings"));
|
||||
|
||||
this.state = {
|
||||
isLoadedData: false,
|
||||
isLoading: false,
|
||||
timezones,
|
||||
timezone: timezoneFromSessionStorage || timezone,
|
||||
timezoneDefault: timezoneDefaultFromSessionStorage || timezone,
|
||||
language: languageFromSessionStorage || language,
|
||||
languageDefault: languageDefaultFromSessionStorage || language,
|
||||
timezone: timezoneFromSessionStorage || "",
|
||||
timezoneDefault: timezoneDefaultFromSessionStorage || "",
|
||||
language: languageFromSessionStorage || "",
|
||||
languageDefault: languageDefaultFromSessionStorage || "",
|
||||
hasChanged: false,
|
||||
showReminder: false,
|
||||
hasScroll: false,
|
||||
@ -90,67 +76,85 @@ class LanguageAndTimeZone extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { languageDefault, timezoneDefault } = this.state;
|
||||
|
||||
const {
|
||||
cultureNames,
|
||||
portalLanguage,
|
||||
i18n,
|
||||
language,
|
||||
rawTimezones,
|
||||
portalTimeZoneId,
|
||||
getPortalTimezones,
|
||||
isLoaded,
|
||||
cultures,
|
||||
portalLanguage,
|
||||
tReady,
|
||||
setIsLoadedLngTZSettings,
|
||||
} = this.props;
|
||||
const { timezones, isLoadedData } = this.state;
|
||||
|
||||
const isLoadedSetting = isLoaded && tReady;
|
||||
|
||||
if (isLoadedSetting) {
|
||||
setIsLoadedLngTZSettings(isLoadedSetting);
|
||||
}
|
||||
|
||||
window.addEventListener("resize", this.checkInnerWidth);
|
||||
|
||||
if (!timezones.length) {
|
||||
getPortalTimezones().then(() => {
|
||||
const timezones = mapTimezonesToArray(this.props.rawTimezones);
|
||||
if (
|
||||
rawTimezones.length > 0 &&
|
||||
isLoaded === true &&
|
||||
tReady === true &&
|
||||
this.state.timezone === ""
|
||||
) {
|
||||
const timezones = mapTimezonesToArray(rawTimezones);
|
||||
|
||||
const language =
|
||||
languageFromSessionStorage ||
|
||||
findSelectedItemByKey(cultureNames, portalLanguage) ||
|
||||
cultureNames[0];
|
||||
const timezone =
|
||||
timezoneFromSessionStorage ||
|
||||
findSelectedItemByKey(timezones, portalTimeZoneId) ||
|
||||
timezones[0];
|
||||
const timezone =
|
||||
timezoneFromSessionStorage ||
|
||||
findSelectedItemByKey(timezones, portalTimeZoneId) ||
|
||||
rawTimezones[0];
|
||||
|
||||
const languageDefault =
|
||||
findSelectedItemByKey(cultureNames, portalLanguage) ||
|
||||
cultureNames[0];
|
||||
const timezoneDefault =
|
||||
findSelectedItemByKey(timezones, portalTimeZoneId) || timezones[0];
|
||||
const timezoneDefault =
|
||||
findSelectedItemByKey(timezones, portalTimeZoneId) || timezones[0];
|
||||
|
||||
this.setState({
|
||||
language,
|
||||
timezones,
|
||||
timezone,
|
||||
languageDefault,
|
||||
timezoneDefault,
|
||||
});
|
||||
|
||||
if (!timezoneDefault) {
|
||||
this.setState({
|
||||
timezoneDefault: timezone,
|
||||
});
|
||||
}
|
||||
if (!languageDefault) {
|
||||
this.setState({
|
||||
languageDefault: language,
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
timezone,
|
||||
timezoneDefault,
|
||||
});
|
||||
}
|
||||
if (timezones.length && !isLoadedData) {
|
||||
this.setState({ isLoadedData: true });
|
||||
|
||||
if (
|
||||
cultures.length > 0 &&
|
||||
isLoaded === true &&
|
||||
tReady === true &&
|
||||
this.state.language === ""
|
||||
) {
|
||||
const cultureNames = mapCulturesToArray(cultures, i18n);
|
||||
|
||||
const language =
|
||||
languageFromSessionStorage ||
|
||||
findSelectedItemByKey(cultureNames, portalLanguage) ||
|
||||
cultureNames[0];
|
||||
|
||||
const languageDefault =
|
||||
findSelectedItemByKey(cultureNames, portalLanguage) || cultureNames[0];
|
||||
|
||||
this.setState({
|
||||
language,
|
||||
languageDefault,
|
||||
});
|
||||
}
|
||||
|
||||
if (!languageDefault) {
|
||||
this.setState({
|
||||
languageDefault: language,
|
||||
});
|
||||
}
|
||||
|
||||
if (timezoneDefault && languageDefault) {
|
||||
this.checkChanges();
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const {
|
||||
timezones,
|
||||
timezoneDefault,
|
||||
languageDefault,
|
||||
hasScroll,
|
||||
} = this.state;
|
||||
const { timezoneDefault, languageDefault, hasScroll } = this.state;
|
||||
|
||||
const {
|
||||
i18n,
|
||||
@ -158,8 +162,66 @@ class LanguageAndTimeZone extends React.Component {
|
||||
nameSchemaId,
|
||||
getCurrentCustomSchema,
|
||||
cultureNames,
|
||||
rawTimezones,
|
||||
portalTimeZoneId,
|
||||
isLoaded,
|
||||
cultures,
|
||||
portalLanguage,
|
||||
tReady,
|
||||
setIsLoadedLngTZSettings,
|
||||
} = this.props;
|
||||
|
||||
if (isLoaded !== prevProps.isLoaded || tReady !== prevProps.tReady) {
|
||||
const isLoadedSetting = isLoaded && tReady;
|
||||
|
||||
if (isLoadedSetting) {
|
||||
setIsLoadedLngTZSettings(isLoadedSetting);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
rawTimezones.length > 0 &&
|
||||
isLoaded === true &&
|
||||
tReady === true &&
|
||||
this.state.timezone === ""
|
||||
) {
|
||||
const timezones = mapTimezonesToArray(rawTimezones);
|
||||
|
||||
const timezone =
|
||||
timezoneFromSessionStorage ||
|
||||
findSelectedItemByKey(timezones, portalTimeZoneId) ||
|
||||
rawTimezones[0];
|
||||
|
||||
const timezoneDefault =
|
||||
findSelectedItemByKey(timezones, portalTimeZoneId) || timezones[0];
|
||||
|
||||
this.setState({
|
||||
timezone,
|
||||
timezoneDefault,
|
||||
});
|
||||
}
|
||||
|
||||
if (
|
||||
cultures.length > 0 &&
|
||||
isLoaded === true &&
|
||||
tReady === true &&
|
||||
this.state.language === ""
|
||||
) {
|
||||
const cultureNames = mapCulturesToArray(cultures, i18n);
|
||||
const language =
|
||||
languageFromSessionStorage ||
|
||||
findSelectedItemByKey(cultureNames, portalLanguage) ||
|
||||
cultureNames[0];
|
||||
|
||||
const languageDefault =
|
||||
findSelectedItemByKey(cultureNames, portalLanguage) || cultureNames[0];
|
||||
|
||||
this.setState({
|
||||
language,
|
||||
languageDefault,
|
||||
});
|
||||
}
|
||||
|
||||
const checkScroll = checkScrollSettingsBlock();
|
||||
|
||||
window.addEventListener("resize", checkScroll);
|
||||
@ -180,9 +242,6 @@ class LanguageAndTimeZone extends React.Component {
|
||||
settingsMobile.style.display = "none";
|
||||
}
|
||||
|
||||
if (timezones.length && !prevState.isLoadedData) {
|
||||
this.setState({ isLoadedData: true });
|
||||
}
|
||||
if (language !== prevProps.language) {
|
||||
i18n
|
||||
.changeLanguage(language)
|
||||
@ -332,21 +391,24 @@ class LanguageAndTimeZone extends React.Component {
|
||||
const {
|
||||
t,
|
||||
theme,
|
||||
cultureNames,
|
||||
isMobileView,
|
||||
isLoadingCustomization,
|
||||
rawTimezones,
|
||||
cultures,
|
||||
i18n,
|
||||
isLoadedPage,
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
isLoadedData,
|
||||
language,
|
||||
isLoading,
|
||||
timezones,
|
||||
timezone,
|
||||
showReminder,
|
||||
hasScroll,
|
||||
} = this.state;
|
||||
|
||||
const timezones = mapTimezonesToArray(rawTimezones);
|
||||
const cultureNames = mapCulturesToArray(cultures, i18n);
|
||||
|
||||
const tooltipLanguageTimeSettings = (
|
||||
<LanguageTimeSettingsTooltip theme={theme} t={t} />
|
||||
);
|
||||
@ -399,9 +461,8 @@ class LanguageAndTimeZone extends React.Component {
|
||||
</div>
|
||||
);
|
||||
|
||||
//return <LoaderCustomization lngTZSettings={true} />;
|
||||
return !isLoadedData ? (
|
||||
<Loader className="pageLoader" type="rombs" size="40px" />
|
||||
return !isLoadedPage ? (
|
||||
<LoaderCustomization lngTZSettings={true} />
|
||||
) : (
|
||||
<StyledSettingsComponent
|
||||
hasScroll={hasScroll}
|
||||
@ -440,24 +501,23 @@ class LanguageAndTimeZone extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default inject(({ auth, setup }) => {
|
||||
export default inject(({ auth, setup, common }) => {
|
||||
const {
|
||||
culture,
|
||||
timezone,
|
||||
timezones,
|
||||
//cultures,
|
||||
nameSchemaId,
|
||||
organizationName,
|
||||
greetingSettings,
|
||||
//getPortalCultures,
|
||||
getPortalTimezones,
|
||||
getCurrentCustomSchema,
|
||||
cultures,
|
||||
} = auth.settingsStore;
|
||||
|
||||
const { user } = auth.userStore;
|
||||
|
||||
const { setLanguageAndTime } = setup;
|
||||
|
||||
const { isLoaded, setIsLoadedLngTZSettings } = common;
|
||||
return {
|
||||
theme: auth.settingsStore.theme,
|
||||
user,
|
||||
@ -465,17 +525,18 @@ export default inject(({ auth, setup }) => {
|
||||
portalTimeZoneId: timezone,
|
||||
language: culture,
|
||||
rawTimezones: timezones,
|
||||
//rawCultures: cultures,
|
||||
greetingSettings,
|
||||
nameSchemaId,
|
||||
organizationName,
|
||||
//getPortalCultures,
|
||||
setLanguageAndTime,
|
||||
getCurrentCustomSchema,
|
||||
getPortalTimezones,
|
||||
isLoaded,
|
||||
setIsLoadedLngTZSettings,
|
||||
cultures,
|
||||
};
|
||||
})(
|
||||
withCultureNames(
|
||||
withLoading(
|
||||
withTranslation(["Settings", "Common"])(observer(LanguageAndTimeZone))
|
||||
)
|
||||
);
|
||||
|
@ -1,6 +1,5 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import Loader from "@appserver/components/loader";
|
||||
import toastr from "@appserver/components/toast/toastr";
|
||||
import HelpButton from "@appserver/components/help-button";
|
||||
import FieldContainer from "@appserver/components/field-container";
|
||||
@ -19,10 +18,18 @@ import { StyledSettingsComponent, StyledScrollbar } from "./StyledSettings";
|
||||
import { saveToSessionStorage, getFromSessionStorage } from "../../../utils";
|
||||
import { setDocumentTitle } from "../../../../../../helpers/utils";
|
||||
import LoaderCustomization from "../sub-components/loaderCustomization";
|
||||
import withLoading from "../../../../../../HOCs/withLoading";
|
||||
const PortalRenaming = (props) => {
|
||||
const {
|
||||
t,
|
||||
setPortalRename,
|
||||
isMobileView,
|
||||
tReady,
|
||||
isLoaded,
|
||||
setIsLoadedPortalRenaming,
|
||||
isLoadedPage,
|
||||
} = props;
|
||||
|
||||
const PortalRenaming = ({ t, setPortalRename, isMobileView }) => {
|
||||
// TODO: Change false
|
||||
const [isLoadedData, setIsLoadedData] = useState(true);
|
||||
const [isLoadingPortalNameSave, setIsLoadingPortalNameSave] = useState(false);
|
||||
|
||||
const portalNameFromSessionStorage = getFromSessionStorage("portalName");
|
||||
@ -46,6 +53,8 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => {
|
||||
const lengthNameError =
|
||||
"The account name must be between 6 and 50 characters long";
|
||||
|
||||
const isLoadedSetting = isLoaded && tReady;
|
||||
|
||||
useEffect(() => {
|
||||
setDocumentTitle(t("PortalRenaming"));
|
||||
|
||||
@ -77,6 +86,10 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => {
|
||||
);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (isLoadedSetting) setIsLoadedPortalRenaming(isLoadedSetting);
|
||||
}, [isLoadedSetting]);
|
||||
|
||||
//TODO: Need a method to get the portal name
|
||||
const onSavePortalRename = () => {
|
||||
setIsLoadingPortalNameSave(true);
|
||||
@ -187,9 +200,8 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => {
|
||||
</div>
|
||||
);
|
||||
|
||||
//return <LoaderCustomization portalRenaming={true} />;
|
||||
return !isLoadedData ? (
|
||||
<Loader className="pageLoader" type="rombs" size="40px" />
|
||||
return !isLoadedPage ? (
|
||||
<LoaderCustomization portalRenaming={true} />
|
||||
) : (
|
||||
<StyledSettingsComponent
|
||||
hasScroll={hasScroll}
|
||||
@ -225,12 +237,16 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ auth, setup }) => {
|
||||
export default inject(({ auth, setup, common }) => {
|
||||
const { theme } = auth.settingsStore;
|
||||
const { setPortalRename } = setup;
|
||||
|
||||
const { isLoaded, setIsLoadedPortalRenaming } = common;
|
||||
return {
|
||||
theme,
|
||||
setPortalRename,
|
||||
isLoaded,
|
||||
setIsLoadedPortalRenaming,
|
||||
};
|
||||
})(withTranslation(["Settings", "Common"])(observer(PortalRenaming)));
|
||||
})(
|
||||
withLoading(withTranslation(["Settings", "Common"])(observer(PortalRenaming)))
|
||||
);
|
||||
|
@ -20,6 +20,7 @@ import { isSmallTablet } from "@appserver/components/utils/device";
|
||||
import checkScrollSettingsBlock from "../utils";
|
||||
import { StyledSettingsComponent, StyledScrollbar } from "./StyledSettings";
|
||||
import LoaderCustomization from "../sub-components/loaderCustomization";
|
||||
import withLoading from "../../../../../../HOCs/withLoading";
|
||||
|
||||
let greetingTitleFromSessionStorage = "";
|
||||
let greetingTitleDefaultFromSessionStorage = "";
|
||||
@ -45,7 +46,6 @@ class WelcomePageSettings extends React.Component {
|
||||
setDocumentTitle(t("CustomTitlesWelcome"));
|
||||
|
||||
this.state = {
|
||||
isLoadedData: false,
|
||||
isLoading: false,
|
||||
greetingTitle: greetingTitleFromSessionStorage || greetingSettings,
|
||||
greetingTitleDefault:
|
||||
@ -61,15 +61,17 @@ class WelcomePageSettings extends React.Component {
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener("resize", this.checkInnerWidth);
|
||||
showLoader();
|
||||
this.setState({
|
||||
isLoadedData: true,
|
||||
});
|
||||
hideLoader();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const { isLoaded, setIsLoadedWelcomePageSettings, tReady } = this.props;
|
||||
|
||||
const { hasScroll } = this.state;
|
||||
|
||||
const isLoadedSetting = isLoaded && tReady;
|
||||
|
||||
if (isLoadedSetting) setIsLoadedWelcomePageSettings(isLoadedSetting);
|
||||
|
||||
const checkScroll = checkScrollSettingsBlock();
|
||||
|
||||
window.addEventListener("resize", checkScroll);
|
||||
@ -90,12 +92,6 @@ class WelcomePageSettings extends React.Component {
|
||||
settingsMobile.style.display = "none";
|
||||
}
|
||||
|
||||
if (prevState.isLoadedData !== true) {
|
||||
this.setState({
|
||||
isLoadedData: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (this.state.greetingTitleDefault) {
|
||||
this.checkChanges();
|
||||
}
|
||||
@ -217,9 +213,8 @@ class WelcomePageSettings extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { t, isMobileView } = this.props;
|
||||
const { t, isMobileView, isLoadedPage } = this.props;
|
||||
const {
|
||||
isLoadedData,
|
||||
greetingTitle,
|
||||
isLoadingGreetingSave,
|
||||
isLoadingGreetingRestore,
|
||||
@ -250,9 +245,8 @@ class WelcomePageSettings extends React.Component {
|
||||
</div>
|
||||
);
|
||||
|
||||
// return <LoaderCustomization welcomePage={true} />;
|
||||
return !isLoadedData ? (
|
||||
<Loader className="pageLoader" type="rombs" size="40px" />
|
||||
return !isLoadedPage ? (
|
||||
<LoaderCustomization welcomePage={true} />
|
||||
) : (
|
||||
<StyledSettingsComponent
|
||||
hasScroll={hasScroll}
|
||||
@ -293,14 +287,21 @@ class WelcomePageSettings extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
export default inject(({ auth, setup }) => {
|
||||
export default inject(({ auth, setup, common }) => {
|
||||
const { greetingSettings, organizationName, theme } = auth.settingsStore;
|
||||
const { setGreetingTitle, restoreGreetingTitle } = setup;
|
||||
const { isLoaded, setIsLoadedWelcomePageSettings } = common;
|
||||
return {
|
||||
theme,
|
||||
greetingSettings,
|
||||
organizationName,
|
||||
setGreetingTitle,
|
||||
restoreGreetingTitle,
|
||||
isLoaded,
|
||||
setIsLoadedWelcomePageSettings,
|
||||
};
|
||||
})(withTranslation(["Settings", "Common"])(observer(WelcomePageSettings)));
|
||||
})(
|
||||
withLoading(
|
||||
withTranslation(["Settings", "Common"])(observer(WelcomePageSettings))
|
||||
)
|
||||
);
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React, { lazy, Suspense } from "react";
|
||||
import React, { lazy, Suspense, useEffect } from "react";
|
||||
import { Route, Switch, Redirect } from "react-router-dom";
|
||||
import { withRouter } from "react-router";
|
||||
import Layout from "./Layout";
|
||||
import { combineUrl } from "@appserver/common/utils";
|
||||
import AppServerConfig from "@appserver/common/constants/AppServerConfig";
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
const SecuritySettings = lazy(() => import("./categories/security/index.js"));
|
||||
const Admins = lazy(() => import("./categories/security/access-rights/admins"));
|
||||
const TfaPage = lazy(() => import("./categories/security/access-portal/tfa"));
|
||||
@ -105,7 +105,13 @@ const DATA_MANAGEMENT_URL = combineUrl(
|
||||
|
||||
const ERROR_404_URL = combineUrl(AppServerConfig.proxyURL, "/error/404");
|
||||
|
||||
const Settings = () => {
|
||||
const Settings = (props) => {
|
||||
const { loadBaseInfo } = props;
|
||||
|
||||
useEffect(() => {
|
||||
loadBaseInfo();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Layout key="1">
|
||||
<Suspense fallback={null}>
|
||||
@ -159,4 +165,10 @@ const Settings = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export default withRouter(Settings);
|
||||
export default inject(({ common }) => {
|
||||
return {
|
||||
loadBaseInfo: async () => {
|
||||
await common.initSettings();
|
||||
},
|
||||
};
|
||||
})(withRouter(observer(Settings)));
|
||||
|
95
web/ASC.Web.Client/src/store/CommonStore.js
Normal file
95
web/ASC.Web.Client/src/store/CommonStore.js
Normal file
@ -0,0 +1,95 @@
|
||||
import { makeAutoObservable, runInAction } from "mobx";
|
||||
|
||||
import authStore from "@appserver/common/store/AuthStore";
|
||||
|
||||
class CommonStore {
|
||||
isInit = false;
|
||||
isLoaded = false;
|
||||
isLoadedArticleBody = false;
|
||||
isLoadedArticleHeader = false;
|
||||
isLoadedSectionHeader = false;
|
||||
isLoadedSubmenu = false;
|
||||
isLoadedLngTZSettings = false;
|
||||
isLoadedPortalRenaming = false;
|
||||
isLoadedCustomization = false;
|
||||
isLoadedCustomizationNavbar = false;
|
||||
isLoadedWelcomePageSettings = false;
|
||||
|
||||
constructor() {
|
||||
this.authStore = authStore;
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
initSettings = async () => {
|
||||
if (this.isInit) return;
|
||||
this.isInit = true;
|
||||
|
||||
const requests = [];
|
||||
requests.push(
|
||||
authStore.settingsStore.getPortalTimezones(),
|
||||
authStore.settingsStore.getPortalCultures()
|
||||
);
|
||||
|
||||
return Promise.all(requests).finally(() => this.setIsLoaded(true));
|
||||
};
|
||||
|
||||
setIsLoadedArticleBody = (isLoadedArticleBody) => {
|
||||
runInAction(() => {
|
||||
this.isLoadedArticleBody = isLoadedArticleBody;
|
||||
});
|
||||
};
|
||||
|
||||
setIsLoadedArticleHeader = (isLoadedArticleHeader) => {
|
||||
runInAction(() => {
|
||||
this.isLoadedArticleHeader = isLoadedArticleHeader;
|
||||
});
|
||||
};
|
||||
|
||||
setIsLoadedSectionHeader = (isLoadedSectionHeader) => {
|
||||
runInAction(() => {
|
||||
this.isLoadedSectionHeader = isLoadedSectionHeader;
|
||||
});
|
||||
};
|
||||
|
||||
setIsLoadedSubmenu = (isLoadedSubmenu) => {
|
||||
runInAction(() => {
|
||||
this.isLoadedSubmenu = isLoadedSubmenu;
|
||||
});
|
||||
};
|
||||
|
||||
setIsLoadedLngTZSettings = (isLoadedLngTZSettings) => {
|
||||
runInAction(() => {
|
||||
this.isLoadedLngTZSettings = isLoadedLngTZSettings;
|
||||
});
|
||||
};
|
||||
|
||||
setIsLoadedWelcomePageSettings = (isLoadedWelcomePageSettings) => {
|
||||
runInAction(() => {
|
||||
this.isLoadedWelcomePageSettings = isLoadedWelcomePageSettings;
|
||||
});
|
||||
};
|
||||
|
||||
setIsLoadedPortalRenaming = (isLoadedPortalRenaming) => {
|
||||
runInAction(() => {
|
||||
this.isLoadedPortalRenaming = isLoadedPortalRenaming;
|
||||
});
|
||||
};
|
||||
|
||||
setIsLoadedCustomization = (isLoadedCustomization) => {
|
||||
runInAction(() => {
|
||||
this.isLoadedCustomization = isLoadedCustomization;
|
||||
});
|
||||
};
|
||||
|
||||
setIsLoadedCustomizationNavbar = (isLoadedCustomizationNavbar) => {
|
||||
runInAction(() => {
|
||||
this.isLoadedCustomizationNavbar = isLoadedCustomizationNavbar;
|
||||
});
|
||||
};
|
||||
|
||||
setIsLoaded = (isLoaded) => {
|
||||
this.isLoaded = isLoaded;
|
||||
};
|
||||
}
|
||||
|
||||
export default CommonStore;
|
@ -10,9 +10,6 @@ import config from "../../package.json";
|
||||
class SettingsSetupStore {
|
||||
selectionStore = null;
|
||||
authStore = null;
|
||||
|
||||
isLoadingArticleSettings = false;
|
||||
|
||||
isInit = false;
|
||||
|
||||
common = {
|
||||
@ -334,8 +331,10 @@ class SettingsSetupStore {
|
||||
return api.settings.sendOwnerChange(id);
|
||||
};
|
||||
|
||||
setIsLoadingArticleSettings = (isLoading) => {
|
||||
this.isLoadingArticleSettings = isLoading;
|
||||
getCommonThirdPartyList = async () => {
|
||||
const res = await api.settings.getCommonThirdPartyList();
|
||||
|
||||
this.setCommonThirdPartyList(res);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -4,12 +4,14 @@ import WizardStore from "./WizardStore";
|
||||
import SettingsSetupStore from "./SettingsSetupStore";
|
||||
import ConfirmStore from "./ConfirmStore";
|
||||
import BackupStore from "./BackupStore";
|
||||
import CommonStore from "./CommonStore";
|
||||
|
||||
const paymentStore = new PaymentStore();
|
||||
const wizardStore = new WizardStore();
|
||||
const setupStore = new SettingsSetupStore();
|
||||
const confirmStore = new ConfirmStore();
|
||||
const backupStore = new BackupStore();
|
||||
const commonStore = new CommonStore();
|
||||
|
||||
const store = {
|
||||
auth: authStore,
|
||||
@ -18,6 +20,7 @@ const store = {
|
||||
setup: setupStore,
|
||||
confirm: confirmStore,
|
||||
backup: backupStore,
|
||||
common: commonStore,
|
||||
};
|
||||
|
||||
export default store;
|
||||
|
Loading…
Reference in New Issue
Block a user