Merge branch 'develop' into feature/catalog
This commit is contained in:
commit
94cbac3c02
@ -26,6 +26,7 @@
|
||||
"deploy:personal": "shx rm -rf build/deploy/products && shx rm -rf build/deploy/public && shx rm -rf build/deploy/studio && lerna run deploy --parallel --scope {@appserver/studio,@appserver/people,@appserver/files,@appserver/editor} && shx cp -r public build/deploy",
|
||||
"serve": "lerna run serve --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc --ignore @appserver/debug-info",
|
||||
"start": "lerna run start --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc --ignore @appserver/debug-info",
|
||||
"start:personal": "lerna run start --parallel --scope {@appserver/studio,@appserver/people,@appserver/files,@appserver/editor}",
|
||||
"start-prod": "lerna run start-prod --parallel --ignore @appserver/common --ignore @appserver/components --ignore @appserver/browserslist-config-asc --ignore @appserver/debug-info",
|
||||
"storybook": "yarn workspace @appserver/components storybook",
|
||||
"storybook-build": "yarn workspace @appserver/components run storybook-build",
|
||||
|
@ -36,7 +36,7 @@ RectangleLoader.propTypes = {
|
||||
backgroundOpacity: PropTypes.number,
|
||||
foregroundOpacity: PropTypes.number,
|
||||
speed: PropTypes.number,
|
||||
animate: PropTypes.bool,
|
||||
animate: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
|
||||
};
|
||||
|
||||
RectangleLoader.defaultProps = {
|
||||
|
@ -13,6 +13,7 @@ import equal from "fast-deep-equal/react";
|
||||
import Hammer from "hammerjs";
|
||||
import IconButton from "@appserver/components/icon-button";
|
||||
import commonIconsStyles from "@appserver/components/utils/common-icons-style";
|
||||
import { isDesktop } from "react-device-detect";
|
||||
|
||||
const StyledVideoViewer = styled(VideoViewer)`
|
||||
z-index: 301;
|
||||
@ -104,7 +105,7 @@ class MediaViewer extends React.Component {
|
||||
document.getElementsByClassName("videoViewerOverlay")[0]
|
||||
);
|
||||
}
|
||||
if (_this.hammer) {
|
||||
if (_this.hammer && !isDesktop) {
|
||||
_this.hammer.on("swipeleft", _this.nextMedia);
|
||||
_this.hammer.on("swiperight", _this.prevMedia);
|
||||
}
|
||||
|
@ -394,7 +394,7 @@ class PageLayout extends React.Component {
|
||||
display: 'grid',
|
||||
paddingRight: '20px',
|
||||
}}></div>
|
||||
<SubSectionFilter className="section-header_filter">
|
||||
<SubSectionFilter className="section-header_filter" viewAs={viewAs}>
|
||||
{sectionFilterContent ? sectionFilterContent.props.children : null}
|
||||
</SubSectionFilter>
|
||||
</>
|
||||
|
@ -10,23 +10,38 @@ import Scrollbar from "@appserver/components/scrollbar";
|
||||
import DragAndDrop from "@appserver/components/drag-and-drop";
|
||||
import { tablet } from "@appserver/components/utils/device";
|
||||
|
||||
const paddingStyles = css`
|
||||
padding: 17px 7px 16px 24px;
|
||||
@media ${tablet} {
|
||||
padding: 16px 0 16px 24px;
|
||||
}
|
||||
`;
|
||||
const commonStyles = css`
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
${(props) => !props.withScroll && `height: 100%;`}
|
||||
border-left: none;
|
||||
|
||||
-webkit-user-select: none;
|
||||
|
||||
.section-wrapper-content {
|
||||
flex: 1 0 auto;
|
||||
padding: 17px 7px 16px 24px;
|
||||
outline: none;
|
||||
${(props) => props.viewAs == "tile" && "padding-right:0;"}
|
||||
|
||||
@media ${tablet} {
|
||||
padding: 16px 0 16px 24px;
|
||||
.section-wrapper {
|
||||
${(props) =>
|
||||
!props.withScroll &&
|
||||
`display: flex; height: 100%; box-sizing:border-box`};
|
||||
${(props) => !props.withScroll && paddingStyles}
|
||||
}
|
||||
|
||||
.section-wrapper-content {
|
||||
${paddingStyles}
|
||||
flex: 1 0 auto;
|
||||
|
||||
outline: none;
|
||||
${(props) =>
|
||||
props.viewAs == "tile" &&
|
||||
css`
|
||||
padding-right: 0;
|
||||
padding-left: 20px;
|
||||
`}
|
||||
|
||||
.section-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -49,6 +64,15 @@ const StyledSectionBody = styled.div`
|
||||
|
||||
margin-left: -24px;
|
||||
`}
|
||||
|
||||
.additional-scroll-height {
|
||||
${(props) =>
|
||||
!props.withScroll &&
|
||||
!props.pinned &&
|
||||
` height: 64px;
|
||||
|
||||
`}
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledDropZoneBody = styled(DragAndDrop)`
|
||||
@ -87,8 +111,9 @@ class SectionBody extends React.Component {
|
||||
// }
|
||||
|
||||
componentDidMount() {
|
||||
const { withScroll } = this.props;
|
||||
if (!this.props.autoFocus) return;
|
||||
this.focusRef.current.focus();
|
||||
if (withScroll) this.focusRef.current.focus();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@ -176,10 +201,7 @@ class SectionBody extends React.Component {
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
<div className="section-wrapper">
|
||||
{children}
|
||||
<StyledSpacer pinned={pinned} />
|
||||
</div>
|
||||
<div className="section-wrapper">{children}</div>
|
||||
)}
|
||||
</StyledSectionBody>
|
||||
);
|
||||
|
@ -1,11 +1,20 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import styled, { css } from "styled-components";
|
||||
import equal from "fast-deep-equal/react";
|
||||
import { tablet } from "@appserver/components/utils/device";
|
||||
import { tablet, desktop } from "@appserver/components/utils/device";
|
||||
|
||||
const StyledSectionFilter = styled.div`
|
||||
margin: 11px 24px 9px 0;
|
||||
|
||||
@media ${desktop} {
|
||||
${(props) =>
|
||||
(props.viewAs === "table" || props.viewAs === "tile") &&
|
||||
css`
|
||||
margin-left: -4px;
|
||||
margin-right: 20px;
|
||||
`};
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
@ -25,6 +25,11 @@ const StyledSectionHeader = styled.div`
|
||||
} */
|
||||
`}
|
||||
|
||||
@media ${desktop} {
|
||||
${(props) =>
|
||||
(props.viewAs === "table" || props.viewAs === "tile") &&
|
||||
"margin-left: -4px"};
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
${(props) =>
|
||||
|
@ -53,8 +53,8 @@ class FirebaseHelper {
|
||||
this.config["projectId"] &&
|
||||
this.config["storageBucket"] &&
|
||||
this.config["messagingSenderId"] &&
|
||||
this.config["appId"] &&
|
||||
this.config["measurementId"]
|
||||
this.config["appId"] /*&&
|
||||
this.config["measurementId"]*/
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ const Aside = React.memo((props) => {
|
||||
zIndex,
|
||||
className,
|
||||
contentPaddingBottom,
|
||||
withoutBodyScroll,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
@ -23,7 +24,11 @@ const Aside = React.memo((props) => {
|
||||
contentPaddingBottom={contentPaddingBottom}
|
||||
className={`${className} not-selectable aside`}
|
||||
>
|
||||
<Scrollbar>{children}</Scrollbar>
|
||||
{withoutBodyScroll ? (
|
||||
children
|
||||
) : (
|
||||
<Scrollbar stype="mediumBlack">{children}</Scrollbar>
|
||||
)}
|
||||
</StyledAside>
|
||||
);
|
||||
});
|
||||
@ -40,10 +45,12 @@ Aside.propTypes = {
|
||||
PropTypes.arrayOf(PropTypes.node),
|
||||
PropTypes.node,
|
||||
]),
|
||||
withoutBodyScroll: PropTypes.bool,
|
||||
};
|
||||
Aside.defaultProps = {
|
||||
scale: false,
|
||||
zIndex: 400,
|
||||
withoutBodyScroll: false,
|
||||
};
|
||||
|
||||
export default Aside;
|
||||
|
@ -311,7 +311,13 @@ class AvatarEditorBody extends React.Component {
|
||||
const desktopMode = isDesktop();
|
||||
return (
|
||||
<Text as="span">
|
||||
<Link type="action" isHovered color="#316DAA" onClick={this.openDialog}>
|
||||
<Link
|
||||
type="action"
|
||||
fontWeight={600}
|
||||
isHovered
|
||||
color="#316DAA"
|
||||
onClick={this.openDialog}
|
||||
>
|
||||
{selectNewPhotoLabel}
|
||||
</Link>{" "}
|
||||
{desktopMode && orDropFileHereLabel}
|
||||
|
@ -27,5 +27,4 @@ Default.args = {
|
||||
source: "",
|
||||
userName: "",
|
||||
editing: false,
|
||||
editLabel: "Edit photo",
|
||||
};
|
||||
|
@ -4,7 +4,6 @@ import styled from "styled-components";
|
||||
|
||||
import { GuestIcon, AdministratorIcon, OwnerIcon } from "./svg";
|
||||
import {
|
||||
EditLink,
|
||||
EmptyIcon,
|
||||
EditContainer,
|
||||
AvatarWrapper,
|
||||
@ -13,7 +12,7 @@ import {
|
||||
StyledImage,
|
||||
StyledAvatar,
|
||||
} from "./styled-avatar";
|
||||
import Link from "../link";
|
||||
import IconButton from "../icon-button";
|
||||
import commonIconsStyles from "../utils/common-icons-style";
|
||||
|
||||
const whiteColor = "#FFFFFF";
|
||||
@ -57,15 +56,7 @@ Initials.propTypes = {
|
||||
// eslint-disable-next-line react/display-name
|
||||
const Avatar = (props) => {
|
||||
//console.log("Avatar render");
|
||||
const {
|
||||
size,
|
||||
source,
|
||||
userName,
|
||||
role,
|
||||
editing,
|
||||
editLabel,
|
||||
editAction,
|
||||
} = props;
|
||||
const { size, source, userName, role, editing, editAction } = props;
|
||||
|
||||
const avatarContent = source ? (
|
||||
<StyledImage src={source} />
|
||||
@ -83,21 +74,13 @@ const Avatar = (props) => {
|
||||
{avatarContent}
|
||||
</AvatarWrapper>
|
||||
{editing && size === "max" && (
|
||||
<EditContainer gradient={!!source}>
|
||||
<EditLink>
|
||||
<Link
|
||||
type="action"
|
||||
title={editLabel}
|
||||
isTextOverflow={true}
|
||||
isHovered={true}
|
||||
fontSize="14px"
|
||||
fontWeight={600}
|
||||
<EditContainer>
|
||||
<IconButton
|
||||
color={whiteColor}
|
||||
iconName="/static/images/pencil.react.svg"
|
||||
onClick={editAction}
|
||||
>
|
||||
{editLabel}
|
||||
</Link>
|
||||
</EditLink>
|
||||
size={16}
|
||||
/>
|
||||
</EditContainer>
|
||||
)}
|
||||
<RoleWrapper size={size}>{roleIcon}</RoleWrapper>
|
||||
@ -112,8 +95,6 @@ Avatar.propTypes = {
|
||||
role: PropTypes.oneOf(["owner", "admin", "guest", "user"]),
|
||||
/** The address of the image for an image avatar */
|
||||
source: PropTypes.string,
|
||||
/** Displays avatar edit layer */
|
||||
editLabel: PropTypes.string,
|
||||
userName: PropTypes.string,
|
||||
editing: PropTypes.bool,
|
||||
/** Function called when the avatar change button is pressed */
|
||||
@ -130,7 +111,6 @@ Avatar.defaultProps = {
|
||||
size: "medium",
|
||||
role: "",
|
||||
source: "",
|
||||
editLabel: "Edit photo",
|
||||
userName: "",
|
||||
editing: false,
|
||||
};
|
||||
|
@ -5,23 +5,6 @@ import NoUserSelect from "../utils/commonStyles";
|
||||
import { CameraIcon } from "./svg";
|
||||
import commonIconsStyles from "../utils/common-icons-style";
|
||||
|
||||
|
||||
const EditLink = styled.div`
|
||||
padding-left: ${(props) => props.theme.avatar.editLink.paddingLeft};
|
||||
padding-right: ${(props) => props.theme.avatar.editLink.paddingRight};
|
||||
|
||||
a:hover {
|
||||
border-bottom: ${(props) => props.theme.avatar.editLink.borderBottom};
|
||||
}
|
||||
|
||||
span {
|
||||
display: ${(props) => props.theme.avatar.editLink.display};
|
||||
max-width: ${(props) => props.theme.avatar.editLink.maxWidth};
|
||||
text-decoration: ${(props) => props.theme.avatar.editLink.textDecoration};
|
||||
}
|
||||
`;
|
||||
EditLink.defaultProps = { theme: Base };
|
||||
|
||||
const EmptyIcon = styled(CameraIcon)`
|
||||
${commonIconsStyles}
|
||||
border-radius: ${(props) => props.theme.avatar.image.borderRadius};
|
||||
@ -29,21 +12,17 @@ const EmptyIcon = styled(CameraIcon)`
|
||||
EmptyIcon.defaultProps = { theme: Base };
|
||||
|
||||
const EditContainer = styled.div`
|
||||
box-sizing: ${(props) => props.theme.avatar.editContainer.boxSizing};
|
||||
position: absolute;
|
||||
width: ${(props) => props.theme.avatar.editContainer.width};
|
||||
height: ${(props) => props.theme.avatar.editContainer.height};
|
||||
top: ${(props) => props.theme.avatar.editContainer.top};
|
||||
left: ${(props) => props.theme.avatar.editContainer.left};
|
||||
transform: ${(props) => props.theme.avatar.editContainer.transform};
|
||||
padding: ${(props) => props.theme.avatar.editContainer.padding};
|
||||
text-align: ${(props) => props.theme.avatar.editContainer.textAlign};
|
||||
line-height: ${(props) => props.theme.avatar.editContainer.lineHeight};
|
||||
display: flex;
|
||||
right: ${(props) => props.theme.avatar.editContainer.right};
|
||||
bottom: ${(props) => props.theme.avatar.editContainer.bottom};
|
||||
background-color: ${(props) =>
|
||||
props.theme.avatar.editContainer.backgroundColor};
|
||||
border-radius: ${(props) => props.theme.avatar.editContainer.borderRadius};
|
||||
background: ${(props) =>
|
||||
props.gradient
|
||||
? props.theme.avatar.editContainer.linearGradient
|
||||
: props.theme.avatar.editContainer.transparent};
|
||||
height: ${(props) => props.theme.avatar.editContainer.height};
|
||||
width: ${(props) => props.theme.avatar.editContainer.width};
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`;
|
||||
EditContainer.defaultProps = { theme: Base };
|
||||
|
||||
@ -129,7 +108,6 @@ const StyledAvatar = styled.div`
|
||||
StyledAvatar.defaultProps = { theme: Base };
|
||||
|
||||
export {
|
||||
EditLink,
|
||||
EmptyIcon,
|
||||
EditContainer,
|
||||
AvatarWrapper,
|
||||
|
@ -32,7 +32,7 @@ class ContextMenuSub extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
onItemClick(e, item) {
|
||||
onItemClick(item, e) {
|
||||
if (item.disabled) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
@ -157,13 +157,16 @@ class ContextMenuSub extends Component {
|
||||
const dataKeys = Object.fromEntries(
|
||||
Object.entries(item).filter((el) => el[0].indexOf("data-") === 0)
|
||||
);
|
||||
const onClick = (e) => {
|
||||
this.onItemClick(item, e);
|
||||
};
|
||||
let content = (
|
||||
<a
|
||||
href={item.url || "#"}
|
||||
className={linkClassName}
|
||||
target={item.target}
|
||||
{...dataKeys}
|
||||
onClick={(event) => this.onItemClick(event, item, index)}
|
||||
onClick={onClick}
|
||||
role="menuitem"
|
||||
>
|
||||
{icon}
|
||||
@ -174,7 +177,7 @@ class ContextMenuSub extends Component {
|
||||
|
||||
if (item.template) {
|
||||
const defaultContentOptions = {
|
||||
onClick: (event) => this.onItemClick(event, item, index),
|
||||
onClick,
|
||||
className: linkClassName,
|
||||
labelClassName: "p-menuitem-text",
|
||||
iconClassName,
|
||||
|
@ -80,7 +80,7 @@ class DropDown extends React.PureComponent {
|
||||
const left = rects.left < 0 && rects.width < container.width;
|
||||
const right =
|
||||
rects.width &&
|
||||
rects.left < 250 &&
|
||||
rects.left < (rects.width || 250) &&
|
||||
rects.left > rects.width &&
|
||||
rects.width < container.width;
|
||||
const top = rects.bottom > container.height && rects.top > rects.height;
|
||||
|
@ -2,7 +2,7 @@
|
||||
import React from "react";
|
||||
import Scrollbar from "../scrollbar";
|
||||
|
||||
class CustomScrollbars extends React.Component {
|
||||
export class CustomScrollbars extends React.Component {
|
||||
refSetter = (scrollbarsRef, forwardedRef) => {
|
||||
if (scrollbarsRef) {
|
||||
forwardedRef(scrollbarsRef.view);
|
||||
@ -32,6 +32,7 @@ class CustomScrollbars extends React.Component {
|
||||
className={className}
|
||||
>
|
||||
{children}
|
||||
<div className="additional-scroll-height"></div>
|
||||
</Scrollbar>
|
||||
);
|
||||
}
|
||||
|
@ -16,6 +16,11 @@ const StyledScrollbar = styled(Scrollbars)`
|
||||
? props.color
|
||||
: props.theme.scrollbar.backgroundColorHorizontal};
|
||||
}
|
||||
|
||||
.nav-thumb-vertical:hover {
|
||||
background-color: ${(props) =>
|
||||
props.theme.scrollbar.hoverBackgroundColorVertical};
|
||||
}
|
||||
`;
|
||||
|
||||
StyledScrollbar.defaultProps = {
|
||||
|
@ -478,8 +478,9 @@ const Base = {
|
||||
},
|
||||
|
||||
scrollbar: {
|
||||
backgroundColorVertical: "#e5e5e5",
|
||||
backgroundColorVertical: "rgba(208, 213, 218, 1)",
|
||||
backgroundColorHorizontal: "rgba(0, 0, 0, 0.1)",
|
||||
hoverBackgroundColorVertical: "rgba(163, 169, 174, 1)",
|
||||
},
|
||||
|
||||
modalDialog: {
|
||||
@ -917,28 +918,12 @@ const Base = {
|
||||
},
|
||||
|
||||
editContainer: {
|
||||
boxSizing: "border-box",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
padding: "75% 16px 5px",
|
||||
textAlign: "center",
|
||||
lineHeight: "19px",
|
||||
right: "0px",
|
||||
bottom: "0px",
|
||||
backgroundColor: "#265a8f",
|
||||
borderRadius: "50%",
|
||||
linearGradient:
|
||||
"linear-gradient(180deg, rgba(6, 22, 38, 0) 24.48%, rgba(6, 22, 38, 0.75) 100%)",
|
||||
transparent: "transparent",
|
||||
},
|
||||
|
||||
editLink: {
|
||||
paddingLeft: "10px",
|
||||
paddingRight: "10px",
|
||||
borderBottom: "none",
|
||||
display: "inline-block",
|
||||
maxWidth: "100%",
|
||||
textDecoration: "underline dashed",
|
||||
height: "32px",
|
||||
width: "32px",
|
||||
},
|
||||
|
||||
image: {
|
||||
@ -1403,7 +1388,7 @@ const Base = {
|
||||
maxWidth: "175px",
|
||||
|
||||
lineHeightWithoutBorder: "16px",
|
||||
lineHeightTextDecoration: "underline dashed transparent",
|
||||
lineHeightTextDecoration: "underline dashed",
|
||||
},
|
||||
|
||||
childrenButton: {
|
||||
|
@ -444,8 +444,9 @@ const Dark = {
|
||||
},
|
||||
|
||||
scrollbar: {
|
||||
backgroundColorVertical: "rgba(255, 255, 255, 0.5)",
|
||||
backgroundColorVertical: "rgba(208, 213, 218, 1)",
|
||||
backgroundColorHorizontal: "rgba(255, 255, 255, 0.5)",
|
||||
hoverBackgroundColorVertical: "rgba(163, 169, 174, 1)",
|
||||
},
|
||||
|
||||
modalDialog: {
|
||||
@ -880,29 +881,14 @@ const Dark = {
|
||||
},
|
||||
},
|
||||
editContainer: {
|
||||
boxSizing: "border-box",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
top: "50%",
|
||||
left: "50%",
|
||||
transform: "translate(-50%, -50%)",
|
||||
padding: "75% 16px 5px",
|
||||
textAlign: "center",
|
||||
lineHeight: "19px",
|
||||
right: "0px",
|
||||
bottom: "0px",
|
||||
backgroundColor: "#265a8f",
|
||||
borderRadius: "50%",
|
||||
linearGradient:
|
||||
"linear-gradient(180deg, rgba(6, 22, 38, 0) 24.48%, rgba(6, 22, 38, 0.75) 100%)",
|
||||
transparent: "transparent",
|
||||
height: "32px",
|
||||
width: "32px",
|
||||
},
|
||||
|
||||
editLink: {
|
||||
paddingLeft: "10px",
|
||||
paddingRight: "10px",
|
||||
borderBottom: "none",
|
||||
display: "inline-block",
|
||||
maxWidth: "100%",
|
||||
textDecoration: "underline dashed",
|
||||
},
|
||||
image: {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
@ -1194,7 +1180,7 @@ const Dark = {
|
||||
maxWidth: "175px",
|
||||
|
||||
lineHeightWithoutBorder: "16px",
|
||||
lineHeightTextDecoration: "underline dashed transparent",
|
||||
lineHeightTextDecoration: "underline dashed",
|
||||
},
|
||||
|
||||
childrenButton: {
|
||||
|
@ -109,18 +109,19 @@ export default function withContent(WrappedContent) {
|
||||
return this.completeAction(e);
|
||||
};
|
||||
|
||||
onClickUpdateItem = (e) => {
|
||||
onClickUpdateItem = (e, open = true) => {
|
||||
const { fileActionType } = this.props;
|
||||
fileActionType === FileAction.Create
|
||||
? this.createItem(e)
|
||||
? this.createItem(e, open)
|
||||
: this.updateItem(e);
|
||||
};
|
||||
|
||||
createItem = (e) => {
|
||||
createItem = (e, open) => {
|
||||
const {
|
||||
createFile,
|
||||
item,
|
||||
setIsLoading,
|
||||
isLoading,
|
||||
openDocEditor,
|
||||
isPrivacy,
|
||||
isDesktop,
|
||||
@ -131,6 +132,8 @@ export default function withContent(WrappedContent) {
|
||||
} = this.props;
|
||||
const { itemTitle } = this.state;
|
||||
|
||||
if (isLoading) return;
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
const itemId = e.currentTarget.dataset.itemid;
|
||||
@ -141,7 +144,7 @@ export default function withContent(WrappedContent) {
|
||||
}
|
||||
|
||||
let tab =
|
||||
!isDesktop && item.fileExst
|
||||
!isDesktop && item.fileExst && open
|
||||
? window.open(
|
||||
combineUrl(
|
||||
AppServerConfig.proxyURL,
|
||||
@ -170,10 +173,12 @@ export default function withContent(WrappedContent) {
|
||||
encryptedFile,
|
||||
true,
|
||||
false
|
||||
).then(() => openDocEditor(file.id, file.providerKey, tab));
|
||||
).then(
|
||||
() => open && openDocEditor(file.id, file.providerKey, tab)
|
||||
);
|
||||
});
|
||||
}
|
||||
return openDocEditor(file.id, file.providerKey, tab);
|
||||
return open && openDocEditor(file.id, file.providerKey, tab);
|
||||
})
|
||||
.then(() => this.completeAction(itemId))
|
||||
.catch((e) => toastr.error(e))
|
||||
@ -315,6 +320,7 @@ export default function withContent(WrappedContent) {
|
||||
const { editCompleteAction } = filesActionsStore;
|
||||
const {
|
||||
setIsLoading,
|
||||
isLoading,
|
||||
openDocEditor,
|
||||
updateFile,
|
||||
renameFolder,
|
||||
@ -338,6 +344,7 @@ export default function withContent(WrappedContent) {
|
||||
|
||||
return {
|
||||
setIsLoading,
|
||||
isLoading,
|
||||
isTrashFolder: isRecycleBinFolder,
|
||||
openDocEditor,
|
||||
updateFile,
|
||||
|
@ -248,9 +248,10 @@ export default function withContextOptions(WrappedComponent) {
|
||||
};
|
||||
|
||||
onClickShare = () => {
|
||||
const { onSelectItem, setSharingPanelVisible, id, isFolder } = this.props;
|
||||
onSelectItem({ id, isFolder });
|
||||
const { setSharingPanelVisible } = this.props;
|
||||
setTimeout(() => {
|
||||
setSharingPanelVisible(true);
|
||||
}, 10); //TODO: remove delay after fix context menu callback
|
||||
};
|
||||
|
||||
onClickMarkRead = () => {
|
||||
|
@ -96,7 +96,7 @@ export default function withFileActions(WrappedFileItem) {
|
||||
}
|
||||
e.preventDefault();
|
||||
setTooltipPosition(e.pageX, e.pageY);
|
||||
setStartDrag(true);
|
||||
!isFileName && setStartDrag(true);
|
||||
!isActive && setBufferSelection(null);
|
||||
};
|
||||
|
||||
|
@ -46,6 +46,8 @@ const EditingWrapper = styled.div`
|
||||
border-bottom: 1px solid #eceef1;
|
||||
padding-bottom: 4px;
|
||||
margin-top: 4px;
|
||||
|
||||
margin-left: -4px;
|
||||
`}
|
||||
|
||||
${(props) =>
|
||||
@ -149,6 +151,7 @@ const EditingWrapperComponent = (props) => {
|
||||
};
|
||||
|
||||
const onFocus = (e) => e.target.select();
|
||||
const onBlur = (e) => onClickUpdateItem(e, false);
|
||||
|
||||
return (
|
||||
<EditingWrapper viewAs={viewAs}>
|
||||
@ -164,6 +167,7 @@ const EditingWrapperComponent = (props) => {
|
||||
onKeyUp={onKeyUpUpdateItem}
|
||||
onKeyDown={onEscapeKeyPress}
|
||||
onFocus={onFocus}
|
||||
onBlur={onBlur}
|
||||
isDisabled={isLoading}
|
||||
data-itemid={itemId}
|
||||
withBorder={!isTable}
|
||||
|
@ -0,0 +1,131 @@
|
||||
import React, { useEffect, useState, useCallback } from "react";
|
||||
import Text from "@appserver/components/text";
|
||||
import Link from "@appserver/components/link";
|
||||
import TextInput from "@appserver/components/text-input";
|
||||
import Textarea from "@appserver/components/textarea";
|
||||
import copy from "copy-to-clipboard";
|
||||
import toastr from "@appserver/components/toast/toastr";
|
||||
import IconButton from "@appserver/components/icon-button";
|
||||
import i18n from "./i18n";
|
||||
import { withTranslation, I18nextProvider } from "react-i18next";
|
||||
|
||||
const EmbeddingBody = ({ embeddingLink, t }) => {
|
||||
const [size, setSize] = useState("auto");
|
||||
const [widthValue, setWidthValue] = useState("100%");
|
||||
const [heightValue, setHeightValue] = useState("100%");
|
||||
const getIframe = useCallback(
|
||||
() =>
|
||||
`<iframe src="${embeddingLink}" width="${widthValue}" height="${heightValue}" frameborder="0" scrolling="no" allowtransparency> </iframe>`,
|
||||
[embeddingLink, widthValue, heightValue]
|
||||
);
|
||||
const [link, setLink] = useState(getIframe());
|
||||
|
||||
useEffect(() => {
|
||||
const link = getIframe();
|
||||
setLink(link);
|
||||
}, [embeddingLink, widthValue, heightValue]);
|
||||
|
||||
const onSelectSizeMiddle = () => {
|
||||
if (size === "600x800") return;
|
||||
|
||||
setSize("600x800");
|
||||
setWidthValue("600");
|
||||
setHeightValue("800");
|
||||
};
|
||||
|
||||
const onSelectSizeSmall = () => {
|
||||
if (size === "400x600") return;
|
||||
|
||||
setSize("400x600");
|
||||
setWidthValue("400");
|
||||
setHeightValue("600");
|
||||
};
|
||||
const onSelectSizeAuto = () => {
|
||||
if (size === "auto") return;
|
||||
|
||||
setSize("auto");
|
||||
setWidthValue("100%");
|
||||
setHeightValue("100%");
|
||||
};
|
||||
|
||||
const onChangeWidth = (e) => {
|
||||
setWidthValue(e.target.value);
|
||||
};
|
||||
const onChangeHeight = (e) => {
|
||||
setHeightValue(e.target.value);
|
||||
};
|
||||
|
||||
const onCopyLink = () => {
|
||||
copy(link);
|
||||
toastr.success(t("CodeCopySuccess"));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="embedding-panel_body">
|
||||
<Text className="embedding-panel_text">{t("Common:Size")}:</Text>
|
||||
<div className="embedding-panel_links-container">
|
||||
<Link
|
||||
isHovered
|
||||
type="action"
|
||||
className="embedding-panel_link"
|
||||
onClick={onSelectSizeMiddle}
|
||||
>
|
||||
600 x 800 px
|
||||
</Link>
|
||||
<Link
|
||||
isHovered
|
||||
type="action"
|
||||
className="embedding-panel_link"
|
||||
onClick={onSelectSizeSmall}
|
||||
>
|
||||
400 x 600 px
|
||||
</Link>
|
||||
<Link
|
||||
isHovered
|
||||
type="action"
|
||||
className="embedding-panel_link"
|
||||
onClick={onSelectSizeAuto}
|
||||
>
|
||||
{t("Auto")}
|
||||
</Link>
|
||||
</div>
|
||||
<div className="embedding-panel_inputs-container">
|
||||
<div>
|
||||
<Text className="embedding-panel_text">{t("Width")}:</Text>
|
||||
<TextInput
|
||||
className="embedding-panel_input"
|
||||
value={widthValue}
|
||||
onChange={onChangeWidth}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Text className="embedding-panel_text">{t("Height")}:</Text>
|
||||
<TextInput
|
||||
className="embedding-panel_input"
|
||||
value={heightValue}
|
||||
onChange={onChangeHeight}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="embedding-panel_code-container">
|
||||
<Text className="embedding-panel_text">{t("EmbedCode")}:</Text>
|
||||
<IconButton
|
||||
className="embedding-panel_copy-icon"
|
||||
size="16"
|
||||
iconName="/static/images/copy.react.svg"
|
||||
color="#333"
|
||||
onClick={onCopyLink}
|
||||
/>
|
||||
<Textarea color="#AEAEAE" isReadOnly value={link} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const EmbeddingBodyWrapper = withTranslation("EmbeddingPanel")(EmbeddingBody);
|
||||
|
||||
export default (props) => (
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<EmbeddingBodyWrapper {...props} />
|
||||
</I18nextProvider>
|
||||
);
|
@ -4,33 +4,18 @@ import Backdrop from "@appserver/components/backdrop";
|
||||
import Heading from "@appserver/components/heading";
|
||||
import Aside from "@appserver/components/aside";
|
||||
import IconButton from "@appserver/components/icon-button";
|
||||
import Text from "@appserver/components/text";
|
||||
import Link from "@appserver/components/link";
|
||||
import TextInput from "@appserver/components/text-input";
|
||||
import Textarea from "@appserver/components/textarea";
|
||||
import toastr from "@appserver/components/toast/toastr";
|
||||
import { withTranslation, I18nextProvider } from "react-i18next";
|
||||
import i18n from "./i18n";
|
||||
import {
|
||||
StyledEmbeddingPanel,
|
||||
StyledContent,
|
||||
StyledHeaderContent,
|
||||
StyledBody,
|
||||
} from "../StyledPanels";
|
||||
import copy from "copy-to-clipboard";
|
||||
import i18n from "./i18n";
|
||||
|
||||
import EmbeddingBody from "./EmbeddingBody";
|
||||
|
||||
class EmbeddingPanelComponent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
size: "auto",
|
||||
widthValue: "100%",
|
||||
heightValue: "100%",
|
||||
link: `<iframe src="${props.embeddingLink}" width="100%" height="100%" frameborder="0" scrolling="no" allowtransparency> </iframe>`,
|
||||
};
|
||||
}
|
||||
|
||||
onArrowClick = () => this.props.onClose();
|
||||
|
||||
onClosePanels = () => {
|
||||
@ -38,81 +23,8 @@ class EmbeddingPanelComponent extends React.Component {
|
||||
this.props.onSharingPanelClose();
|
||||
};
|
||||
|
||||
onSelectSizeMiddle = () => {
|
||||
this.state.size !== "600x800" &&
|
||||
this.setState({ size: "600x800", widthValue: "600", heightValue: "800" });
|
||||
};
|
||||
|
||||
onSelectSizeSmall = () => {
|
||||
this.state.size !== "400x600" &&
|
||||
this.setState({ size: "400x600", widthValue: "400", heightValue: "600" });
|
||||
};
|
||||
onSelectSizeAuto = () => {
|
||||
this.state.size !== "auto" &&
|
||||
this.setState({ size: "auto", widthValue: "100%", heightValue: "100%" });
|
||||
};
|
||||
|
||||
onChangeWidth = (e) => {
|
||||
this.setState({ widthValue: e.target.value });
|
||||
};
|
||||
onChangeHeight = (e) => {
|
||||
this.setState({ heightValue: e.target.value });
|
||||
};
|
||||
|
||||
onCopyLink = () => {
|
||||
copy(this.state.link);
|
||||
toastr.success(this.props.t("CodeCopySuccess"));
|
||||
};
|
||||
|
||||
// shouldComponentUpdate(nextProps, nextState) {
|
||||
// const { size, widthValue, heightValue, link } = this.state;
|
||||
// const { visible, embeddingLink } = this.props;
|
||||
|
||||
// if (size !== nextState.size) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// if (widthValue !== nextState.widthValue) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// if (heightValue !== nextState.heightValue) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// if (visible !== nextProps.visible) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// if (embeddingLink !== nextProps.embeddingLink) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// if (link !== nextState.link) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// return false;
|
||||
// }
|
||||
|
||||
componentDidUpdate(prevProps, prevState) {
|
||||
const { embeddingLink } = this.props;
|
||||
const { widthValue, heightValue } = this.state;
|
||||
|
||||
if (
|
||||
prevProps.embeddingLink !== embeddingLink ||
|
||||
widthValue !== prevState.widthValue ||
|
||||
heightValue !== prevState.heightValue
|
||||
) {
|
||||
const link = `<iframe src="${embeddingLink}" width="${widthValue}" height="${heightValue}" frameborder="0" scrolling="no" allowtransparency> </iframe>`;
|
||||
this.setState({ link });
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { visible, t } = this.props;
|
||||
const { size, widthValue, heightValue, link } = this.state;
|
||||
|
||||
const zIndex = 310;
|
||||
|
||||
//console.log("EmbeddingPanel render");
|
||||
@ -141,69 +53,8 @@ class EmbeddingPanelComponent extends React.Component {
|
||||
{t("EmbeddingDocument")}
|
||||
</Heading>
|
||||
</StyledHeaderContent>
|
||||
<StyledBody size={size}>
|
||||
<div className="embedding-panel_body">
|
||||
<Text className="embedding-panel_text">
|
||||
{t("Common:Size")}:
|
||||
</Text>
|
||||
<div className="embedding-panel_links-container">
|
||||
<Link
|
||||
isHovered
|
||||
type="action"
|
||||
className="embedding-panel_link"
|
||||
onClick={this.onSelectSizeMiddle}
|
||||
>
|
||||
600 x 800 px
|
||||
</Link>
|
||||
<Link
|
||||
isHovered
|
||||
type="action"
|
||||
className="embedding-panel_link"
|
||||
onClick={this.onSelectSizeSmall}
|
||||
>
|
||||
400 x 600 px
|
||||
</Link>
|
||||
<Link
|
||||
isHovered
|
||||
type="action"
|
||||
className="embedding-panel_link"
|
||||
onClick={this.onSelectSizeAuto}
|
||||
>
|
||||
{t("Auto")}
|
||||
</Link>
|
||||
</div>
|
||||
<div className="embedding-panel_inputs-container">
|
||||
<div>
|
||||
<Text className="embedding-panel_text">{t("Width")}:</Text>
|
||||
<TextInput
|
||||
className="embedding-panel_input"
|
||||
value={widthValue}
|
||||
onChange={this.onChangeWidth}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Text className="embedding-panel_text">{t("Height")}:</Text>
|
||||
<TextInput
|
||||
className="embedding-panel_input"
|
||||
value={heightValue}
|
||||
onChange={this.onChangeHeight}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="embedding-panel_code-container">
|
||||
<Text className="embedding-panel_text">
|
||||
{t("EmbedCode")}:
|
||||
</Text>
|
||||
<IconButton
|
||||
className="embedding-panel_copy-icon"
|
||||
size="16"
|
||||
iconName="/static/images/copy.react.svg"
|
||||
color="#333"
|
||||
onClick={this.onCopyLink}
|
||||
/>
|
||||
<Textarea color="#AEAEAE" isReadOnly value={link} />
|
||||
</div>
|
||||
</div>
|
||||
<StyledBody>
|
||||
<EmbeddingBody />
|
||||
</StyledBody>
|
||||
</StyledContent>
|
||||
</Aside>
|
||||
@ -218,12 +69,12 @@ EmbeddingPanelComponent.propTypes = {
|
||||
onClose: PropTypes.func,
|
||||
};
|
||||
|
||||
const EmbeddingPanel = withTranslation("EmbeddingPanel")(
|
||||
const EmbeddingBodyWrapper = withTranslation("EmbeddingPanel")(
|
||||
EmbeddingPanelComponent
|
||||
);
|
||||
|
||||
export default (props) => (
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<EmbeddingPanel {...props} />
|
||||
<EmbeddingBodyWrapper {...props} />
|
||||
</I18nextProvider>
|
||||
);
|
||||
|
@ -16,8 +16,10 @@ const OperationsPanelComponent = (props) => {
|
||||
visible,
|
||||
provider,
|
||||
selection,
|
||||
isFolderActions,
|
||||
isRecycleBin,
|
||||
setDestFolderId,
|
||||
setIsFolderActions,
|
||||
currentFolderId,
|
||||
operationsFolders,
|
||||
setCopyPanelVisible,
|
||||
@ -25,6 +27,7 @@ const OperationsPanelComponent = (props) => {
|
||||
setMoveToPanelVisible,
|
||||
checkOperationConflict,
|
||||
setThirdPartyMoveDialogVisible,
|
||||
parentFolderId,
|
||||
} = props;
|
||||
|
||||
const zIndex = 310;
|
||||
@ -33,7 +36,12 @@ const OperationsPanelComponent = (props) => {
|
||||
const expandedKeys = props.expandedKeys.map((item) => item.toString());
|
||||
|
||||
const onClose = () => {
|
||||
isCopy ? setCopyPanelVisible(false) : setMoveToPanelVisible(false);
|
||||
if (isCopy) {
|
||||
setCopyPanelVisible(false);
|
||||
setIsFolderActions(false);
|
||||
} else {
|
||||
setMoveToPanelVisible(false);
|
||||
}
|
||||
setExpandedPanelKeys(null);
|
||||
};
|
||||
|
||||
@ -41,6 +49,10 @@ const OperationsPanelComponent = (props) => {
|
||||
const folderTitle = treeNode.node.props.title;
|
||||
const destFolderId = isNaN(+folder[0]) ? folder[0] : +folder[0];
|
||||
|
||||
if (isFolderActions && destFolderId === parentFolderId) {
|
||||
return onClose();
|
||||
}
|
||||
|
||||
if (currentFolderId === destFolderId) {
|
||||
return onClose();
|
||||
}
|
||||
@ -68,8 +80,9 @@ const OperationsPanelComponent = (props) => {
|
||||
? selection.filter((x) => !x.providerKey)
|
||||
: selection;
|
||||
|
||||
const fileIds = [];
|
||||
const folderIds = [];
|
||||
let fileIds = [];
|
||||
let folderIds = [];
|
||||
|
||||
|
||||
for (let item of items) {
|
||||
if (item.fileExst || item.contentLength) {
|
||||
@ -81,6 +94,13 @@ const OperationsPanelComponent = (props) => {
|
||||
}
|
||||
}
|
||||
|
||||
if (isFolderActions) {
|
||||
fileIds = [];
|
||||
folderIds = [];
|
||||
|
||||
folderIds.push(currentFolderId);
|
||||
}
|
||||
|
||||
if (!folderIds.length && !fileIds.length) return;
|
||||
|
||||
checkOperationConflict({
|
||||
@ -152,10 +172,12 @@ export default inject(
|
||||
const {
|
||||
moveToPanelVisible,
|
||||
copyPanelVisible,
|
||||
isFolderActions,
|
||||
setCopyPanelVisible,
|
||||
setMoveToPanelVisible,
|
||||
setDestFolderId,
|
||||
setThirdPartyMoveDialogVisible,
|
||||
setIsFolderActions,
|
||||
} = dialogsStore;
|
||||
|
||||
const selections = selection.length ? selection : [bufferSelection];
|
||||
@ -167,16 +189,19 @@ export default inject(
|
||||
? expandedPanelKeys
|
||||
: selectedFolderStore.pathParts,
|
||||
currentFolderId: selectedFolderStore.id,
|
||||
parentFolderId: selectedFolderStore.parentId,
|
||||
isRecycleBin: isRecycleBinFolder,
|
||||
filter,
|
||||
operationsFolders,
|
||||
visible: copyPanelVisible || moveToPanelVisible,
|
||||
provider,
|
||||
selection: selections,
|
||||
isFolderActions,
|
||||
|
||||
setCopyPanelVisible,
|
||||
setMoveToPanelVisible,
|
||||
setDestFolderId,
|
||||
setIsFolderActions,
|
||||
setThirdPartyMoveDialogVisible,
|
||||
checkOperationConflict,
|
||||
setExpandedPanelKeys,
|
||||
|
@ -19,6 +19,7 @@ import {
|
||||
StyledFooter,
|
||||
StyledHeaderContent,
|
||||
StyledSharingBody,
|
||||
StyledModalRowContainer,
|
||||
} from "../StyledPanels";
|
||||
import { AddUsersPanel, AddGroupsPanel, EmbeddingPanel } from "../index";
|
||||
import SharingRow from "./SharingRow";
|
||||
@ -26,9 +27,12 @@ import { inject, observer } from "mobx-react";
|
||||
import config from "../../../../package.json";
|
||||
import i18n from "./i18n";
|
||||
import { I18nextProvider } from "react-i18next";
|
||||
import { isMobile } from "react-device-detect";
|
||||
import { isMobile, isMobileOnly } from "react-device-detect";
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
import withLoader from "../../../HOCs/withLoader";
|
||||
import ModalDialogContainer from "../../dialogs/ModalDialogContainer";
|
||||
import ModalDialog from "@appserver/components/modal-dialog";
|
||||
import EmbeddingBody from "../EmbeddingPanel/EmbeddingBody";
|
||||
|
||||
const SharingBodyStyle = { height: `calc(100vh - 156px)` };
|
||||
|
||||
@ -50,6 +54,7 @@ class SharingPanelComponent extends React.Component {
|
||||
showPanel: false,
|
||||
accessOptions: [],
|
||||
filesOwnerId: null,
|
||||
showEmbeddingContent: false,
|
||||
};
|
||||
|
||||
this.ref = React.createRef();
|
||||
@ -74,11 +79,16 @@ class SharingPanelComponent extends React.Component {
|
||||
newDataItems[0].access = rights;
|
||||
this.setState({
|
||||
shareDataItems: newDataItems,
|
||||
showEmbeddingContent: false,
|
||||
});
|
||||
};
|
||||
|
||||
updateRowData = (newRowData) => {
|
||||
const { getFileInfo, getFolderInfo } = this.props;
|
||||
const { getFileInfo, getFolderInfo, isFolderActions, id } = this.props;
|
||||
|
||||
if (isFolderActions) {
|
||||
return getFolderInfo(id);
|
||||
}
|
||||
|
||||
for (let item of newRowData) {
|
||||
!item.fileExst ? getFolderInfo(item.id) : getFileInfo(item.id);
|
||||
@ -105,7 +115,9 @@ class SharingPanelComponent extends React.Component {
|
||||
isDesktop,
|
||||
setEncryptionAccess,
|
||||
setShareFiles,
|
||||
setIsFolderActions,
|
||||
onSuccess,
|
||||
isFolderActions,
|
||||
} = this.props;
|
||||
|
||||
let folderIds = [];
|
||||
@ -153,6 +165,13 @@ class SharingPanelComponent extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
if (isFolderActions) {
|
||||
folderIds = [];
|
||||
fileIds = [];
|
||||
|
||||
folderIds.push(selection[0]);
|
||||
}
|
||||
|
||||
const owner = shareDataItems.find((x) => x.isOwner);
|
||||
const ownerId =
|
||||
filesOwnerId !== owner.sharedTo.id ? owner.sharedTo.id : null;
|
||||
@ -205,7 +224,10 @@ class SharingPanelComponent extends React.Component {
|
||||
})
|
||||
.then(() => onSuccess && onSuccess())
|
||||
.catch((err) => toastr.error(err))
|
||||
.finally(() => setIsLoading(false));
|
||||
.finally(() => {
|
||||
setIsFolderActions(false);
|
||||
setIsLoading(false);
|
||||
});
|
||||
};
|
||||
onNotifyUsersChange = () =>
|
||||
this.setState({ isNotifyUsers: !this.state.isNotifyUsers });
|
||||
@ -240,9 +262,10 @@ class SharingPanelComponent extends React.Component {
|
||||
};
|
||||
|
||||
getData = () => {
|
||||
const { selection } = this.props;
|
||||
const folderId = [];
|
||||
const fileId = [];
|
||||
const { selection, id, access } = this.props;
|
||||
|
||||
let folderId = [];
|
||||
let fileId = [];
|
||||
|
||||
for (let item of selection) {
|
||||
if (item.access === 1 || item.access === 0) {
|
||||
@ -254,6 +277,13 @@ class SharingPanelComponent extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.props.isFolderActions) {
|
||||
folderId = [];
|
||||
fileId = [];
|
||||
|
||||
folderId = access === 1 || access === 0 ? [id] : [];
|
||||
}
|
||||
|
||||
return [folderId, fileId];
|
||||
};
|
||||
|
||||
@ -269,7 +299,6 @@ class SharingPanelComponent extends React.Component {
|
||||
const returnValue = this.getData();
|
||||
const folderId = returnValue[0];
|
||||
const fileId = returnValue[1];
|
||||
|
||||
if (folderId.length !== 0 || fileId.length !== 0) {
|
||||
!isMobile && setIsLoading(true);
|
||||
getShareUsers(folderId, fileId)
|
||||
@ -320,6 +349,12 @@ class SharingPanelComponent extends React.Component {
|
||||
shareLink: link,
|
||||
});
|
||||
|
||||
onShowEmbeddingContainer = (link) =>
|
||||
this.setState({
|
||||
showEmbeddingContent: !this.state.showEmbeddingContent,
|
||||
shareLink: link,
|
||||
});
|
||||
|
||||
onShowGroupsPanel = () =>
|
||||
this.setState({
|
||||
showAddGroupsPanel: !this.state.showAddGroupsPanel,
|
||||
@ -341,10 +376,14 @@ class SharingPanelComponent extends React.Component {
|
||||
onCancel,
|
||||
setSharingPanelVisible,
|
||||
selectUploadedFile,
|
||||
setIsFolderActions,
|
||||
setSelection,
|
||||
setBufferSelection,
|
||||
} = this.props;
|
||||
|
||||
setSharingPanelVisible(false);
|
||||
setSelection([]);
|
||||
|
||||
selectUploadedFile([]);
|
||||
setBufferSelection(null);
|
||||
onCancel && onCancel();
|
||||
@ -421,6 +460,7 @@ class SharingPanelComponent extends React.Component {
|
||||
//showPanel,
|
||||
accessOptions,
|
||||
externalAccessOptions,
|
||||
showEmbeddingContent,
|
||||
} = this.state;
|
||||
|
||||
const visible = sharingPanelVisible;
|
||||
@ -433,7 +473,66 @@ class SharingPanelComponent extends React.Component {
|
||||
const internalLink =
|
||||
selection.length === 1 && !isEncrypted && this.getInternalLink();
|
||||
|
||||
return (
|
||||
return isPersonal && !isMobileOnly ? (
|
||||
<ModalDialog
|
||||
isLoading={!tReady}
|
||||
visible={visible}
|
||||
displayType="modal"
|
||||
onClose={this.onClose}
|
||||
>
|
||||
<ModalDialog.Header>{t("SharingSettingsTitle")}</ModalDialog.Header>
|
||||
<ModalDialog.Body>
|
||||
<StyledModalRowContainer>
|
||||
{!isLoading ? (
|
||||
shareDataItems.map((item, index) => (
|
||||
<SharingRow
|
||||
t={t}
|
||||
isPersonal={isPersonal}
|
||||
index={index}
|
||||
key={`${item.sharedTo.id}_${index}`}
|
||||
selection={selection}
|
||||
item={item}
|
||||
isMyId={isMyId}
|
||||
accessOptions={accessOptions}
|
||||
externalAccessOptions={externalAccessOptions}
|
||||
canShareOwnerChange={canShareOwnerChange}
|
||||
onChangeItemAccess={this.onChangeItemAccess}
|
||||
internalLink={internalLink}
|
||||
onRemoveUserClick={this.onRemoveUserItemClick}
|
||||
onShowEmbeddingPanel={this.onShowEmbeddingContainer}
|
||||
onToggleLink={this.onToggleLink}
|
||||
onShowChangeOwnerPanel={this.onShowChangeOwnerPanel}
|
||||
isLoading={isLoading}
|
||||
documentTitle={documentTitle}
|
||||
/>
|
||||
))
|
||||
) : (
|
||||
<Loaders.Rectangle
|
||||
height="47px"
|
||||
animate={0}
|
||||
foregroundColor="#f8f9f9"
|
||||
backgroundColor="#f8f9f9"
|
||||
backgroundOpacity={1}
|
||||
foregroundOpacity={1}
|
||||
/>
|
||||
)}
|
||||
{showEmbeddingContent && (
|
||||
<EmbeddingBody embeddingLink={shareLink} />
|
||||
)}
|
||||
</StyledModalRowContainer>
|
||||
</ModalDialog.Body>
|
||||
<ModalDialog.Footer>
|
||||
<Button
|
||||
className="sharing_panel-button"
|
||||
label={t("Common:SaveButton")}
|
||||
size="big"
|
||||
primary
|
||||
onClick={this.onSaveClick}
|
||||
isDisabled={isLoading}
|
||||
/>
|
||||
</ModalDialog.Footer>
|
||||
</ModalDialog>
|
||||
) : (
|
||||
<StyledAsidePanel visible={visible}>
|
||||
<Backdrop
|
||||
onClick={this.onClose}
|
||||
@ -618,12 +717,21 @@ class SharingPanelComponent extends React.Component {
|
||||
|
||||
const SharingPanel = inject(
|
||||
(
|
||||
{ auth, filesStore, uploadDataStore, dialogsStore, treeFoldersStore },
|
||||
{
|
||||
auth,
|
||||
filesStore,
|
||||
uploadDataStore,
|
||||
dialogsStore,
|
||||
treeFoldersStore,
|
||||
selectedFolderStore,
|
||||
},
|
||||
{ uploadPanelVisible }
|
||||
) => {
|
||||
const { replaceFileStream, setEncryptionAccess } = auth;
|
||||
const { personal, customNames, isDesktopClient } = auth.settingsStore;
|
||||
|
||||
const { id, access } = selectedFolderStore;
|
||||
|
||||
const {
|
||||
selection,
|
||||
bufferSelection,
|
||||
@ -635,13 +743,19 @@ const SharingPanel = inject(
|
||||
getShareUsers,
|
||||
setShareFiles,
|
||||
setIsLoading,
|
||||
setSelection,
|
||||
getFileInfo,
|
||||
getFolderInfo,
|
||||
isLoading,
|
||||
setBufferSelection,
|
||||
} = filesStore;
|
||||
const { isPrivacyFolder } = treeFoldersStore;
|
||||
const { setSharingPanelVisible, sharingPanelVisible } = dialogsStore;
|
||||
const {
|
||||
setSharingPanelVisible,
|
||||
sharingPanelVisible,
|
||||
setIsFolderActions,
|
||||
isFolderActions,
|
||||
} = dialogsStore;
|
||||
const {
|
||||
selectedUploadFile,
|
||||
selectUploadedFile,
|
||||
@ -661,11 +775,14 @@ const SharingPanel = inject(
|
||||
: [bufferSelection],
|
||||
isLoading,
|
||||
isPrivacy: isPrivacyFolder,
|
||||
isFolderActions,
|
||||
selectedUploadFile,
|
||||
canShareOwnerChange,
|
||||
|
||||
setIsLoading,
|
||||
setSharingPanelVisible,
|
||||
setIsFolderActions,
|
||||
setSelection,
|
||||
sharingPanelVisible,
|
||||
selectUploadedFile,
|
||||
updateUploadedItem,
|
||||
@ -679,7 +796,9 @@ const SharingPanel = inject(
|
||||
setShareFiles,
|
||||
getFileInfo,
|
||||
getFolderInfo,
|
||||
id,
|
||||
setBufferSelection,
|
||||
access,
|
||||
};
|
||||
}
|
||||
)(
|
||||
|
@ -41,7 +41,11 @@ class LinkRow extends React.Component {
|
||||
const isDisabled = isLoading || disableLink;
|
||||
|
||||
return (
|
||||
<StyledLinkRow withToggle={withToggle} isDisabled={isDisabled}>
|
||||
<StyledLinkRow
|
||||
withToggle={withToggle}
|
||||
isDisabled={isDisabled}
|
||||
className="link-row__container"
|
||||
>
|
||||
<Row
|
||||
className="link-row"
|
||||
key={`${linkText.replace(" ", "-")}-key_${index}`}
|
||||
|
@ -92,11 +92,11 @@ const StyledVersionHistoryPanel = styled.div`
|
||||
${PanelStyles}
|
||||
.version-history-modal-dialog {
|
||||
transform: translateX(${(props) => (props.visible ? "0" : "720px")});
|
||||
width: 720px;
|
||||
width: 500px;
|
||||
}
|
||||
.version-history-aside-panel {
|
||||
transform: translateX(${(props) => (props.visible ? "0" : "720px")});
|
||||
width: 720px;
|
||||
width: 500px;
|
||||
}
|
||||
.version-history-panel-header {
|
||||
height: 53px;
|
||||
@ -108,10 +108,14 @@ const StyledVersionHistoryPanel = styled.div`
|
||||
}
|
||||
}
|
||||
.version-history-panel-body {
|
||||
padding: ${(props) => (props.isLoading ? "16px 0" : null)};
|
||||
margin: 0 16px;
|
||||
padding-top: ${(props) => (props.isLoading ? "16px" : null)};
|
||||
padding-bottom: ${(props) => (props.isLoading ? "0px" : null)};
|
||||
margin-left: 16px;
|
||||
border-top: 1px solid #eceef1;
|
||||
|
||||
height: calc(100% - 53px);
|
||||
box-sizing: border-box;
|
||||
|
||||
.version-comment-wrapper {
|
||||
margin-left: 79px;
|
||||
}
|
||||
@ -170,6 +174,7 @@ const StyledContent = styled.div`
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
|
||||
.header_aside-panel-header {
|
||||
@ -775,6 +780,125 @@ const StyledFilesList = styled.div`
|
||||
grid-template-columns: 22px 32px 1fr;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledModalRowContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 47px;
|
||||
|
||||
.link-row__container {
|
||||
width: 100%;
|
||||
|
||||
.link-row {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.link-row::after {
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.panel_combo-box {
|
||||
margin-left: 0px;
|
||||
|
||||
.combo-button {
|
||||
height: 30px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.optionalBlock {
|
||||
margin-right: 4px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.combo-button-label {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.sharing-access-combo-box-icon {
|
||||
height: 16px;
|
||||
path {
|
||||
fill: ${(props) => (props.isDisabled ? "#D0D5DA" : "#A3A9AE")};
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 16px;
|
||||
min-width: 16px;
|
||||
height: 16px;
|
||||
min-height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.embedding-panel_code-container {
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.embedding-panel_text {
|
||||
padding: 8px 0 4px 0;
|
||||
}
|
||||
|
||||
.embedding-panel_copy-icon {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
margin: 8px;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.embedding-panel_links-container {
|
||||
display: flex;
|
||||
.embedding-panel_link {
|
||||
margin-right: 8px;
|
||||
height: 32px;
|
||||
background-color: #eceef1;
|
||||
line-height: 30px;
|
||||
padding: 0px 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.embedding-panel_inputs-container {
|
||||
display: flex;
|
||||
|
||||
.embedding-panel_input {
|
||||
margin-right: 8px;
|
||||
width: 94px;
|
||||
}
|
||||
}
|
||||
|
||||
.embedding-panel_code-container {
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.embedding-panel_text {
|
||||
padding: 8px 0 4px 0;
|
||||
}
|
||||
|
||||
.embedding-panel_copy-icon {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
margin: 8px;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.panel-loader-wrapper {
|
||||
margin-top: 8px;
|
||||
padding-left: 32px;
|
||||
}
|
||||
.panel-loader {
|
||||
display: inline;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.row_content {
|
||||
height: 19px;
|
||||
overflow: initial;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export {
|
||||
StyledAsidePanel,
|
||||
StyledAddGroupsPanel,
|
||||
@ -790,4 +914,5 @@ export {
|
||||
StyledSelectFolderPanel,
|
||||
StyledSelectFilePanel,
|
||||
StyledFilesList,
|
||||
StyledModalRowContainer,
|
||||
};
|
||||
|
@ -1,10 +1,14 @@
|
||||
import React from "react";
|
||||
import CustomScrollbarsVirtualList from "@appserver/components/scrollbar/custom-scrollbars-virtual-list";
|
||||
import CustomScrollbars from "@appserver/components/scrollbar/custom-scrollbars-virtual-list";
|
||||
import AutoSizer from "react-virtualized-auto-sizer";
|
||||
import { FixedSizeList as List } from "react-window";
|
||||
import RowWrapper from "./RowWrapper";
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
||||
const CustomScrollbarsVirtualList = React.forwardRef((props, ref) => (
|
||||
<CustomScrollbars stype="mediumBlack" {...props} forwardedRef={ref} />
|
||||
));
|
||||
|
||||
const FileList = ({ uploadDataFiles }) => {
|
||||
//console.log("FileList render");
|
||||
|
||||
|
@ -87,7 +87,11 @@ class UploadPanelComponent extends React.Component {
|
||||
zIndex={zIndex}
|
||||
isAside={true}
|
||||
/>
|
||||
<Aside className="header_aside-panel" visible={visible}>
|
||||
<Aside
|
||||
className="header_aside-panel"
|
||||
visible={visible}
|
||||
withoutBodyScroll
|
||||
>
|
||||
<StyledContent>
|
||||
<StyledHeaderContent className="upload-panel_header-content">
|
||||
<Heading className="upload_panel-header" size="medium" truncate>
|
||||
|
@ -51,7 +51,7 @@ class PureVersionHistoryPanel extends React.Component {
|
||||
zIndex={zIndex}
|
||||
isAside={true}
|
||||
/>
|
||||
<Aside className="version-history-aside-panel">
|
||||
<Aside className="version-history-aside-panel" withoutBodyScroll>
|
||||
<StyledContent>
|
||||
<StyledHeaderContent className="version-history-panel-header">
|
||||
{versions && !isLoading ? (
|
||||
|
@ -63,6 +63,10 @@ const StyledTableRow = styled(TableRow)`
|
||||
"url(images/cursor.palm.svg), auto"};
|
||||
}
|
||||
|
||||
.table-container_element {
|
||||
margin-left: ${(props) => (props.item.isFolder ? "-3px" : "-4px")};
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.table-container_row-checkbox-wrapper {
|
||||
${(props) => props.dragging && rowCheckboxDraggingHoverStyle}
|
||||
|
@ -9,6 +9,7 @@ import Text from "@appserver/components/text";
|
||||
import TileContent from "./sub-components/TileContent";
|
||||
import withContent from "../../../../../HOCs/withContent";
|
||||
import withBadges from "../../../../../HOCs/withBadges";
|
||||
import { isMobile } from "react-device-detect";
|
||||
|
||||
const SimpleFilesTileContent = styled(TileContent)`
|
||||
.row-main-container {
|
||||
@ -54,7 +55,8 @@ const SimpleFilesTileContent = styled(TileContent)`
|
||||
}
|
||||
|
||||
.title-link {
|
||||
font-size: 14px;
|
||||
font-size: ${isMobile ? "15px" : "13px"};
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.favorite,
|
||||
@ -83,18 +85,14 @@ const FilesTileContent = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
<SimpleFilesTileContent
|
||||
sideColor="#333"
|
||||
isFile={fileExst}
|
||||
//disableSideInfo
|
||||
>
|
||||
<SimpleFilesTileContent sideColor="#333" isFile={fileExst}>
|
||||
<Link
|
||||
className="title-link item-file-name"
|
||||
containerWidth="100%"
|
||||
type="page"
|
||||
title={title}
|
||||
fontWeight="600"
|
||||
fontSize="14px"
|
||||
fontSize={isMobile ? "15px" : "13px"}
|
||||
target="_blank"
|
||||
{...linkStyles}
|
||||
color="#333"
|
||||
@ -106,7 +104,7 @@ const FilesTileContent = ({
|
||||
className="badge-ext"
|
||||
as="span"
|
||||
color="#A3A9AE"
|
||||
fontSize="14px"
|
||||
fontSize={isMobile ? "15px" : "13px"}
|
||||
fontWeight={600}
|
||||
truncate={true}
|
||||
>
|
||||
|
@ -6,6 +6,7 @@ import { ReactSVG } from "react-svg";
|
||||
import styled, { css } from "styled-components";
|
||||
import ContextMenu from "@appserver/components/context-menu";
|
||||
import { tablet } from "@appserver/components/utils/device";
|
||||
import { isDesktop, isMobile } from "react-device-detect";
|
||||
|
||||
import Link from "@appserver/components/link";
|
||||
|
||||
@ -100,9 +101,11 @@ const StyledTile = styled.div`
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
display: flex;
|
||||
opacity: ${(props) => (props.checked ? 1 : 0)};
|
||||
flex: 0 0 16px;
|
||||
margin-right: 4px;
|
||||
justify-content: center;
|
||||
|
||||
@media ${tablet} {
|
||||
opacity: 1;
|
||||
@ -112,11 +115,18 @@ const StyledTile = styled.div`
|
||||
.file-checkbox {
|
||||
display: ${(props) => (props.checked ? "flex" : "none")};
|
||||
flex: 0 0 16px;
|
||||
margin-right: ${(props) => (props.isFolder ? "8px" : "4px")};
|
||||
margin-top: 3px;
|
||||
|
||||
margin-left: ${(props) =>
|
||||
isMobile
|
||||
? css`
|
||||
${props.isFolder ? "6px" : "12px"};
|
||||
`
|
||||
: css`
|
||||
${props.isFolder ? "5px" : "8px"}
|
||||
`};
|
||||
|
||||
@media ${tablet} {
|
||||
display: flex;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
@ -126,33 +136,47 @@ const StyledTile = styled.div`
|
||||
flex: 0 0 auto;
|
||||
margin-right: 4px;
|
||||
user-select: none;
|
||||
margin-top: 3px;
|
||||
margin-top: ${(props) => (props.isFolder ? "-6px" : "-4px")};
|
||||
margin-top: ${(props) => (props.isFolder ? "-8px" : "-6px")};
|
||||
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
height: ${isMobile ? "32px" : "24px"};
|
||||
width: ${isMobile ? "32px" : "24px"};
|
||||
|
||||
img {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
height: ${isMobile ? "32px" : "24px"};
|
||||
width: ${isMobile ? "32px" : "24px"};
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
display: none;
|
||||
}
|
||||
margin-left: ${(props) =>
|
||||
isMobile
|
||||
? css`
|
||||
${props.isFolder ? "2px" : "4px"};
|
||||
`
|
||||
: css`
|
||||
${props.isFolder ? "2px" : "4px"}
|
||||
`};
|
||||
}
|
||||
|
||||
.file-icon_container {
|
||||
min-width: 36px;
|
||||
|
||||
@media ${tablet} {
|
||||
min-width: 28px;
|
||||
min-width: ${isMobile ? "36px" : "28px"};
|
||||
}
|
||||
|
||||
.styled-content {
|
||||
padding-left: 10px;
|
||||
|
||||
padding-left: ${(props) =>
|
||||
isMobile
|
||||
? css`
|
||||
${props.isFolder ? "8px" : "12px"};
|
||||
`
|
||||
: css`
|
||||
${props.isFolder ? "10px" : "13px"}
|
||||
`};
|
||||
}
|
||||
|
||||
:hover {
|
||||
${(props) =>
|
||||
!props.dragging &&
|
||||
props.isDesktop &&
|
||||
css`
|
||||
.checkbox {
|
||||
opacity: 1;
|
||||
@ -173,8 +197,12 @@ const StyledFileTileTop = styled.div`
|
||||
align-items: baseline;
|
||||
background-color: #f8f9f9;
|
||||
padding: 13px;
|
||||
height: 157px;
|
||||
height: ${(props) => (props.checked || props.isActive ? "156px" : "156px")};
|
||||
position: relative;
|
||||
border-bottom: ${(props) =>
|
||||
props.checked || props.isActive
|
||||
? "1px solid #D0D5DA"
|
||||
: "1px solid transparent"};
|
||||
|
||||
.thumbnail-image,
|
||||
.temporary-icon > .injected-svg {
|
||||
@ -195,8 +223,6 @@ const StyledFileTileBottom = styled.div`
|
||||
padding-right: 0;
|
||||
min-height: 56px;
|
||||
box-sizing: border-box;
|
||||
border-top: ${(props) =>
|
||||
(props.checked || props.isActive) && "1px solid #D0D5DA"};
|
||||
`;
|
||||
|
||||
const StyledContent = styled.div`
|
||||
@ -292,6 +318,13 @@ class Tile extends React.PureComponent {
|
||||
onSelect && onSelect(e.target.checked, item);
|
||||
};
|
||||
|
||||
onFileIconClick = () => {
|
||||
if (isDesktop) return;
|
||||
|
||||
const { onSelect, item } = this.props;
|
||||
onSelect && onSelect(true, item);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
checked,
|
||||
@ -348,12 +381,18 @@ class Tile extends React.PureComponent {
|
||||
isRecycleBin={isRecycleBin}
|
||||
checked={checked}
|
||||
isActive={isActive}
|
||||
isDesktop={isDesktop}
|
||||
>
|
||||
{isFolder || (!fileExst && id === -1) ? (
|
||||
<>
|
||||
{renderElement && !(!fileExst && id === -1) && !isEdit && (
|
||||
<div className="file-icon_container">
|
||||
<StyledElement className="file-icon">{element}</StyledElement>
|
||||
<StyledElement
|
||||
className="file-icon"
|
||||
onClick={this.onFileIconClick}
|
||||
>
|
||||
{element}
|
||||
</StyledElement>
|
||||
<Checkbox
|
||||
className="checkbox file-checkbox"
|
||||
isChecked={checked}
|
||||
@ -363,6 +402,7 @@ class Tile extends React.PureComponent {
|
||||
</div>
|
||||
)}
|
||||
<StyledContent
|
||||
className="styled-content"
|
||||
isFolder={(isFolder && !fileExst) || (!fileExst && id === -1)}
|
||||
>
|
||||
{children}
|
||||
@ -386,11 +426,15 @@ class Tile extends React.PureComponent {
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<StyledFileTileTop>{icon}</StyledFileTileTop>
|
||||
<StyledFileTileBottom checked={checked} isActive={isActive}>
|
||||
<StyledFileTileTop checked={checked} isActive={isActive}>
|
||||
{icon}
|
||||
</StyledFileTileTop>
|
||||
<StyledFileTileBottom>
|
||||
{id !== -1 && !isEdit && (
|
||||
<div className="file-icon_container">
|
||||
<div className="file-icon">{element}</div>
|
||||
<div className="file-icon" onClick={this.onFileIconClick}>
|
||||
{element}
|
||||
</div>
|
||||
<Checkbox
|
||||
className="file-checkbox"
|
||||
isChecked={checked}
|
||||
|
@ -1,35 +1,50 @@
|
||||
/* eslint-disable react/display-name */
|
||||
import React, { memo } from "react";
|
||||
import styled from "styled-components";
|
||||
import styled, { css } from "styled-components";
|
||||
import PropTypes from "prop-types";
|
||||
import { FixedSizeList as List, areEqual } from "react-window";
|
||||
import AutoSizer from "react-virtualized-auto-sizer";
|
||||
import Heading from "@appserver/components/heading";
|
||||
import ContextMenu from "@appserver/components/context-menu";
|
||||
import CustomScrollbarsVirtualList from "@appserver/components/scrollbar";
|
||||
import { tablet } from "@appserver/components/utils/device";
|
||||
|
||||
import { tablet, desktop } from "@appserver/components/utils/device";
|
||||
|
||||
const foldersStyle = css`
|
||||
grid-gap: 19px 14px;
|
||||
|
||||
@media ${desktop} {
|
||||
margin-left: -1px;
|
||||
padding-right: 1px;
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
grid-gap: 17px 12px;
|
||||
margin-left: -1px;
|
||||
}
|
||||
`;
|
||||
|
||||
const filesStyle = css`
|
||||
grid-gap: 14px 18px;
|
||||
|
||||
@media ${desktop} {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
grid-gap: 12px 14px;
|
||||
margin-left: -1px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledGridWrapper = styled.div`
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
width: 100%;
|
||||
grid-gap: ${(props) => (props.isFolders ? "13px 14px" : "16px 18px")};
|
||||
padding-bottom: 24px;
|
||||
padding-right: 2px;
|
||||
box-sizing: border-box;
|
||||
padding-left: 1px;
|
||||
|
||||
@media ${tablet} {
|
||||
margin-left: -6px !important;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
margin-left: -2px;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
margin-left: -2px;
|
||||
}
|
||||
${(props) => (props.isFolders ? foldersStyle : filesStyle)};
|
||||
`;
|
||||
|
||||
const StyledTileContainer = styled.div`
|
||||
@ -59,6 +74,8 @@ const StyledTileContainer = styled.div`
|
||||
&.files {
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
margin-left: -1px;
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
@ -68,6 +85,10 @@ const StyledTileContainer = styled.div`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
margin-right: -3px;
|
||||
}
|
||||
`;
|
||||
|
||||
class TileContainer extends React.PureComponent {
|
||||
|
@ -208,15 +208,32 @@ class SectionHeaderContent extends React.Component {
|
||||
toastr.success(t("Translations:LinkCopySuccess"));
|
||||
};
|
||||
|
||||
onMoveAction = () => this.props.setMoveToPanelVisible(true);
|
||||
onCopyAction = () => this.props.setCopyPanelVisible(true);
|
||||
downloadAction = () =>
|
||||
onMoveAction = () => {
|
||||
this.props.setIsFolderActions(true);
|
||||
this.props.setBufferSelection(this.props.currentFolderId);
|
||||
return this.props.setMoveToPanelVisible(true);
|
||||
};
|
||||
onCopyAction = () => {
|
||||
this.props.setIsFolderActions(true);
|
||||
this.props.setBufferSelection(this.props.currentFolderId);
|
||||
return this.props.setCopyPanelVisible(true);
|
||||
};
|
||||
downloadAction = () => {
|
||||
this.props.setBufferSelection(this.props.currentFolderId);
|
||||
this.props.setIsFolderActions(true);
|
||||
this.props
|
||||
.downloadAction(this.props.t("Translations:ArchivingData"))
|
||||
.downloadAction(this.props.t("Translations:ArchivingData"), [
|
||||
this.props.currentFolderId,
|
||||
])
|
||||
.catch((err) => toastr.error(err));
|
||||
};
|
||||
|
||||
renameAction = () => console.log("renameAction click");
|
||||
onOpenSharingPanel = () => this.props.setSharingPanelVisible(true);
|
||||
onOpenSharingPanel = () => {
|
||||
this.props.setBufferSelection(this.props.currentFolderId);
|
||||
this.props.setIsFolderActions(true);
|
||||
return this.props.setSharingPanelVisible(true);
|
||||
};
|
||||
|
||||
onDeleteAction = () => {
|
||||
const {
|
||||
@ -225,10 +242,18 @@ class SectionHeaderContent extends React.Component {
|
||||
confirmDelete,
|
||||
setDeleteDialogVisible,
|
||||
isThirdPartySelection,
|
||||
currentFolderId,
|
||||
getFolderInfo,
|
||||
setBufferSelection,
|
||||
} = this.props;
|
||||
|
||||
this.props.setIsFolderActions(true);
|
||||
|
||||
if (confirmDelete || isThirdPartySelection) {
|
||||
getFolderInfo(currentFolderId).then((data) => {
|
||||
setBufferSelection(data);
|
||||
setDeleteDialogVisible(true);
|
||||
});
|
||||
} else {
|
||||
const translations = {
|
||||
deleteOperation: t("Translations:DeleteOperation"),
|
||||
@ -236,45 +261,48 @@ class SectionHeaderContent extends React.Component {
|
||||
deleteSelectedElem: t("Translations:DeleteSelectedElem"),
|
||||
};
|
||||
|
||||
deleteAction(translations);
|
||||
deleteAction(translations, [currentFolderId], true).catch((err) =>
|
||||
toastr.error(err)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
onEmptyTrashAction = () => this.props.setEmptyTrashDialogVisible(true);
|
||||
|
||||
getContextOptionsFolder = () => {
|
||||
const { t } = this.props;
|
||||
const { t, personal } = this.props;
|
||||
|
||||
return [
|
||||
{
|
||||
key: "sharing-settings",
|
||||
label: t("SharingSettings"),
|
||||
onClick: this.onOpenSharingPanel,
|
||||
disabled: true,
|
||||
disabled: personal ? true : false,
|
||||
},
|
||||
{
|
||||
key: "link-portal-users",
|
||||
label: t("LinkForPortalUsers"),
|
||||
onClick: this.createLinkForPortalUsers,
|
||||
disabled: false,
|
||||
disabled: personal ? true : false,
|
||||
},
|
||||
{ key: "separator-2", isSeparator: true },
|
||||
{
|
||||
key: "move-to",
|
||||
label: t("MoveTo"),
|
||||
onClick: this.onMoveAction,
|
||||
disabled: true,
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "copy",
|
||||
label: t("Translations:Copy"),
|
||||
onClick: this.onCopyAction,
|
||||
disabled: true,
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "download",
|
||||
label: t("Common:Download"),
|
||||
onClick: this.downloadAction,
|
||||
disabled: true,
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
key: "rename",
|
||||
@ -286,7 +314,7 @@ class SectionHeaderContent extends React.Component {
|
||||
key: "delete",
|
||||
label: t("Common:Delete"),
|
||||
onClick: this.onDeleteAction,
|
||||
disabled: true,
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
};
|
||||
@ -418,7 +446,7 @@ class SectionHeaderContent extends React.Component {
|
||||
getData={this.getContextOptionsPlus}
|
||||
isDisabled={false}
|
||||
/>
|
||||
{!personal && (
|
||||
|
||||
<ContextMenuButton
|
||||
className="option-button"
|
||||
directionX="right"
|
||||
@ -430,7 +458,6 @@ class SectionHeaderContent extends React.Component {
|
||||
getData={this.getContextOptionsFolder}
|
||||
isDisabled={false}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
canCreate && (
|
||||
@ -469,6 +496,7 @@ export default inject(
|
||||
}) => {
|
||||
const {
|
||||
setSelected,
|
||||
setSelection,
|
||||
fileActionStore,
|
||||
fetchFiles,
|
||||
filter,
|
||||
@ -481,6 +509,8 @@ export default inject(
|
||||
viewAs,
|
||||
cbMenuItems,
|
||||
getCheckboxItemLabel,
|
||||
getFolderInfo,
|
||||
setBufferSelection,
|
||||
} = filesStore;
|
||||
const { setAction } = fileActionStore;
|
||||
const {
|
||||
@ -488,6 +518,7 @@ export default inject(
|
||||
setMoveToPanelVisible,
|
||||
setCopyPanelVisible,
|
||||
setDeleteDialogVisible,
|
||||
setIsFolderActions,
|
||||
} = dialogsStore;
|
||||
|
||||
const { deleteAction, downloadAction, getHeaderMenu } = filesActionsStore;
|
||||
@ -509,14 +540,18 @@ export default inject(
|
||||
personal: auth.settingsStore.personal,
|
||||
viewAs,
|
||||
cbMenuItems,
|
||||
getFolderInfo,
|
||||
|
||||
setSelected,
|
||||
setSelection,
|
||||
setAction,
|
||||
setIsLoading,
|
||||
fetchFiles,
|
||||
setSharingPanelVisible,
|
||||
setMoveToPanelVisible,
|
||||
setCopyPanelVisible,
|
||||
setBufferSelection,
|
||||
setIsFolderActions,
|
||||
deleteAction,
|
||||
setDeleteDialogVisible,
|
||||
downloadAction,
|
||||
|
@ -1,19 +1,124 @@
|
||||
import styled, { css } from "styled-components";
|
||||
import styled from "styled-components";
|
||||
import Row from "@appserver/components/row";
|
||||
import { tablet } from "@appserver/components/utils/device";
|
||||
|
||||
const StyledVersionRow = styled(Row)`
|
||||
min-height: 70px;
|
||||
const StyledBody = styled.div`
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
.version-list {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.loader-history-rows {
|
||||
padding-right: 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledVersionList = styled.div`
|
||||
|
||||
.row_context-menu-wrapper {
|
||||
.expandButton {
|
||||
${(props) =>
|
||||
props.isRestoreProcess &&
|
||||
`
|
||||
touch-action: none;
|
||||
pointer-events: none;
|
||||
`}
|
||||
svg {
|
||||
path {
|
||||
${(props) =>
|
||||
props.isRestoreProcess &&
|
||||
`
|
||||
fill: #d0d5da;
|
||||
`};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.row_content {
|
||||
|
||||
.version_link,
|
||||
.version-link-file,
|
||||
.version_content-length,
|
||||
.version_link-action,
|
||||
.row_context-menu-wrapper,
|
||||
.version_text {
|
||||
${(props) =>
|
||||
props.isRestoreProcess &&
|
||||
`
|
||||
color: #d0d5da;
|
||||
touch-action: none;
|
||||
pointer-events: none;
|
||||
`}
|
||||
}
|
||||
|
||||
.versioned, .not-versioned {
|
||||
${(props) =>
|
||||
props.isRestoreProcess &&
|
||||
`
|
||||
touch-action: none;
|
||||
pointer-events: none;
|
||||
`}
|
||||
}
|
||||
|
||||
.versioned {
|
||||
svg {
|
||||
path {
|
||||
${(props) =>
|
||||
props.isRestoreProcess &&
|
||||
`
|
||||
fill: #d0d5da;
|
||||
`};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.not-versioned{
|
||||
svg {
|
||||
path {
|
||||
|
||||
${(props) =>
|
||||
props.isRestoreProcess &&
|
||||
`
|
||||
stroke: #d0d5da;
|
||||
`};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
.icon-link {
|
||||
${(props) =>
|
||||
props.isRestoreProcess &&
|
||||
`
|
||||
touch-action: none;
|
||||
pointer-events: none;
|
||||
`}
|
||||
svg {
|
||||
path {
|
||||
${(props) => props.isRestoreProcess && " fill: #d0d5da"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledVersionRow = styled(Row)`
|
||||
@media ${tablet} {
|
||||
min-height: 69px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.row_content {
|
||||
position: relative;
|
||||
padding-top: 14px;
|
||||
padding-bottom: 14px;
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
|
||||
${(props) => props.isTabletView && "height: auto"};
|
||||
${(props) => !props.isTabletView && "padding-right:16px"};
|
||||
}
|
||||
|
||||
.version_badge {
|
||||
@ -133,6 +238,26 @@ const StyledVersionRow = styled(Row)`
|
||||
.row_context-menu-wrapper {
|
||||
display: none;
|
||||
|
||||
right: 16px !important;
|
||||
|
||||
.expandButton {
|
||||
${(props) =>
|
||||
props.isSavingComment &&
|
||||
`
|
||||
touch-action: none;
|
||||
pointer-events: none;
|
||||
`}
|
||||
svg {
|
||||
path {
|
||||
${(props) =>
|
||||
props.isSavingComment &&
|
||||
`
|
||||
fill: #d0d5da;
|
||||
`};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
display: block;
|
||||
position: absolute;
|
||||
@ -143,6 +268,16 @@ const StyledVersionRow = styled(Row)`
|
||||
|
||||
.row_content {
|
||||
display: block;
|
||||
|
||||
.version_link-action {
|
||||
${(props) =>
|
||||
props.isSavingComment &&
|
||||
`
|
||||
color: #d0d5da;
|
||||
touch-action: none;
|
||||
pointer-events: none;
|
||||
`}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-dialog-aside-footer {
|
||||
@ -168,4 +303,4 @@ const StyledVersionRow = styled(Row)`
|
||||
}
|
||||
`;
|
||||
|
||||
export default StyledVersionRow;
|
||||
export { StyledBody, StyledVersionRow, StyledVersionList };
|
@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import styled from "styled-components";
|
||||
import Link from "@appserver/components/link";
|
||||
import Text from "@appserver/components/text";
|
||||
@ -9,7 +9,7 @@ import ModalDialog from "@appserver/components/modal-dialog";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { withRouter } from "react-router";
|
||||
import VersionBadge from "./VersionBadge";
|
||||
import StyledVersionRow from "./StyledVersionRow";
|
||||
import { StyledVersionRow } from "./StyledVersionHistory";
|
||||
import ExternalLinkIcon from "../../../../../public/images/external.link.react.svg";
|
||||
import commonIconsStyles from "@appserver/components/utils/common-icons-style";
|
||||
import { inject, observer } from "mobx-react";
|
||||
@ -31,11 +31,14 @@ const VersionRow = (props) => {
|
||||
markAsVersion,
|
||||
restoreVersion,
|
||||
updateCommentVersion,
|
||||
onSetRestoreProcess,
|
||||
isTabletView,
|
||||
onUpdateHeight,
|
||||
versionsListLength,
|
||||
} = props;
|
||||
const [showEditPanel, setShowEditPanel] = useState(false);
|
||||
const [commentValue, setCommentValue] = useState(info.comment);
|
||||
|
||||
const [isRestoring, setIsRestoring] = useState(false);
|
||||
const [isSavingComment, setIsSavingComment] = useState(false);
|
||||
|
||||
const canEdit = info.access === 1 || info.access === 0;
|
||||
|
||||
@ -52,10 +55,12 @@ const VersionRow = (props) => {
|
||||
const onChange = (e) => setCommentValue(e.target.value);
|
||||
|
||||
const onSaveClick = () => {
|
||||
setIsSavingComment(true);
|
||||
updateCommentVersion(info.id, commentValue, info.version)
|
||||
.catch((err) => toastr.error(err))
|
||||
.finally(() => {
|
||||
onEditComment();
|
||||
setIsSavingComment(false);
|
||||
});
|
||||
};
|
||||
|
||||
@ -66,11 +71,12 @@ const VersionRow = (props) => {
|
||||
const onOpenFile = () => window.open(info.webUrl);
|
||||
|
||||
const onRestoreClick = () => {
|
||||
setIsRestoring(true);
|
||||
|
||||
onSetRestoreProcess(true);
|
||||
restoreVersion(info.id, info.version)
|
||||
.catch((err) => toastr.error(err))
|
||||
.finally(() => setIsRestoring(false));
|
||||
.finally(() => {
|
||||
onSetRestoreProcess(false);
|
||||
});
|
||||
};
|
||||
|
||||
const onVersionClick = () => {
|
||||
@ -94,17 +100,29 @@ const VersionRow = (props) => {
|
||||
];
|
||||
|
||||
const onClickProp = canEdit ? { onClick: onVersionClick } : {};
|
||||
|
||||
useEffect(() => {
|
||||
const newRowHeight = document.getElementsByClassName(
|
||||
`version-row_${index}`
|
||||
)[0]?.clientHeight;
|
||||
|
||||
newRowHeight && onUpdateHeight(index, newRowHeight);
|
||||
}, [showEditPanel, versionsListLength]);
|
||||
|
||||
return (
|
||||
<StyledVersionRow
|
||||
showEditPanel={showEditPanel}
|
||||
contextOptions={contextOptions}
|
||||
canEdit={canEdit}
|
||||
isRestoring={isRestoring}
|
||||
isTabletView={isTabletView}
|
||||
isSavingComment={isSavingComment}
|
||||
>
|
||||
<>
|
||||
<div className={`version-row_${index}`}>
|
||||
<Box displayProp="flex">
|
||||
<VersionBadge
|
||||
className="version_badge"
|
||||
className={`version_badge ${
|
||||
isVersion ? "versioned" : "not-versioned"
|
||||
}`}
|
||||
isVersion={isVersion}
|
||||
index={index}
|
||||
versionGroup={info.versionGroup}
|
||||
@ -147,6 +165,7 @@ const VersionRow = (props) => {
|
||||
fontSize={12}
|
||||
heightTextArea={54}
|
||||
value={commentValue}
|
||||
isDisabled={isSavingComment}
|
||||
/>
|
||||
<Box className="version_modal-dialog">
|
||||
<ModalDialog
|
||||
@ -165,10 +184,12 @@ const VersionRow = (props) => {
|
||||
onChange={onChange}
|
||||
heightTextArea={298}
|
||||
value={commentValue}
|
||||
isDisabled={isSavingComment}
|
||||
/>
|
||||
</ModalDialog.Body>
|
||||
<ModalDialog.Footer>
|
||||
<Button
|
||||
isDisabled={isSavingComment}
|
||||
className="version_save-button"
|
||||
label={t("Common:SaveButton")}
|
||||
size="big"
|
||||
@ -195,7 +216,7 @@ const VersionRow = (props) => {
|
||||
<div className="version_links-container">
|
||||
{canEdit && (
|
||||
<Link
|
||||
{...(!isRestoring && { onClick: onRestoreClick })}
|
||||
onClick={onRestoreClick}
|
||||
{...linkStyles}
|
||||
className="version_link-action"
|
||||
>
|
||||
@ -218,6 +239,7 @@ const VersionRow = (props) => {
|
||||
displayProp="inline-block"
|
||||
>
|
||||
<Button
|
||||
isDisabled={isSavingComment}
|
||||
size="base"
|
||||
scale={true}
|
||||
primary
|
||||
@ -230,6 +252,7 @@ const VersionRow = (props) => {
|
||||
displayProp="inline-block"
|
||||
>
|
||||
<Button
|
||||
isDisabled={isSavingComment}
|
||||
size="base"
|
||||
scale={true}
|
||||
onClick={onCancelClick}
|
||||
@ -238,14 +261,14 @@ const VersionRow = (props) => {
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
</div>
|
||||
</StyledVersionRow>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ auth, versionHistoryStore }) => {
|
||||
const { user } = auth.userStore;
|
||||
const { culture } = auth.settingsStore;
|
||||
const { culture, isTabletView } = auth.settingsStore;
|
||||
const language = (user && user.cultureName) || culture || "en-US";
|
||||
|
||||
const {
|
||||
@ -256,7 +279,7 @@ export default inject(({ auth, versionHistoryStore }) => {
|
||||
|
||||
return {
|
||||
culture: language,
|
||||
|
||||
isTabletView,
|
||||
markAsVersion,
|
||||
restoreVersion,
|
||||
updateCommentVersion,
|
||||
|
@ -1,13 +1,26 @@
|
||||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
import { withRouter } from "react-router";
|
||||
import RowContainer from "@appserver/components/row-container";
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
import VersionRow from "./VersionRow";
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
||||
import { VariableSizeList as List, areEqual } from "react-window";
|
||||
import AutoSizer from "react-virtualized-auto-sizer";
|
||||
import CustomScrollbarsVirtualList from "@appserver/components/scrollbar/custom-scrollbars-virtual-list";
|
||||
import { StyledBody, StyledVersionList } from "./StyledVersionHistory";
|
||||
class SectionBodyContent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isRestoreProcess: false,
|
||||
rowSizes: {},
|
||||
};
|
||||
this.listKey = 0;
|
||||
this.listRef = React.createRef();
|
||||
this.timerId = null;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { match, setFirstLoad } = this.props;
|
||||
const { match, setFirstLoad, versions } = this.props;
|
||||
const fileId = match.params.fileId || this.props.fileId;
|
||||
|
||||
if (fileId && fileId !== this.props.fileId) {
|
||||
@ -21,36 +34,104 @@ class SectionBodyContent extends React.Component {
|
||||
setIsLoading(true);
|
||||
fetchFileVersions(fileId).then(() => setIsLoading(false));
|
||||
};
|
||||
render() {
|
||||
const { versions, culture, isLoading } = this.props;
|
||||
//console.log("VersionHistory SectionBodyContent render()", versions);
|
||||
|
||||
let itemVersion = null;
|
||||
onSetRestoreProcess = (restoring) => {
|
||||
const { isRestoreProcess } = this.state;
|
||||
|
||||
return versions && !isLoading ? (
|
||||
<RowContainer useReactWindow={false}>
|
||||
{versions.map((info, index) => {
|
||||
let isVersion = true;
|
||||
if (itemVersion === info.versionGroup) {
|
||||
isVersion = false;
|
||||
if (restoring) {
|
||||
this.timerId = setTimeout(
|
||||
() =>
|
||||
this.setState({
|
||||
isRestoreProcess: restoring,
|
||||
}),
|
||||
100
|
||||
);
|
||||
} else {
|
||||
itemVersion = info.versionGroup;
|
||||
clearTimeout(this.timerId);
|
||||
this.timerId = null;
|
||||
|
||||
restoring !== isRestoreProcess &&
|
||||
this.setState({
|
||||
isRestoreProcess: restoring,
|
||||
});
|
||||
}
|
||||
};
|
||||
onUpdateHeight = (i, itemHeight) => {
|
||||
if (this.listRef.current) {
|
||||
this.listRef.current.resetAfterIndex(i);
|
||||
}
|
||||
|
||||
this.setState((prevState) => ({
|
||||
rowSizes: {
|
||||
...prevState.rowSizes,
|
||||
[i]: itemHeight + 24, //composed of itemHeight = clientHeight of div and padding-top = 12px and padding-bottom = 12px
|
||||
},
|
||||
}));
|
||||
};
|
||||
|
||||
getSize = (i) => {
|
||||
return this.state.rowSizes[i] ? this.state.rowSizes[i] : 66;
|
||||
};
|
||||
|
||||
renderRow = memo(({ index, style }) => {
|
||||
const { versions, culture } = this.props;
|
||||
|
||||
const prevVersion = versions[index > 0 ? index - 1 : index].versionGroup;
|
||||
let isVersion = true;
|
||||
|
||||
if (index > 0 && prevVersion === versions[index].versionGroup) {
|
||||
isVersion = false;
|
||||
}
|
||||
return (
|
||||
<div style={style}>
|
||||
<VersionRow
|
||||
getFileVersions={this.getFileVersions}
|
||||
isVersion={isVersion}
|
||||
key={`${info.id}-${index}`}
|
||||
info={info}
|
||||
key={`${versions[index].id}-${index}`}
|
||||
info={versions[index]}
|
||||
versionsListLength={versions.length}
|
||||
index={index}
|
||||
culture={culture}
|
||||
onSetRestoreProcess={this.onSetRestoreProcess}
|
||||
onUpdateHeight={this.onUpdateHeight}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</RowContainer>
|
||||
}, areEqual);
|
||||
render() {
|
||||
const { versions, isLoading } = this.props;
|
||||
|
||||
const renderList = ({ height, width }) => {
|
||||
return (
|
||||
<StyledVersionList isRestoreProcess={this.state.isRestoreProcess}>
|
||||
<List
|
||||
ref={this.listRef}
|
||||
className="List"
|
||||
height={height}
|
||||
width={width}
|
||||
itemSize={this.getSize}
|
||||
itemCount={versions.length}
|
||||
itemData={versions}
|
||||
outerElementType={CustomScrollbarsVirtualList}
|
||||
>
|
||||
{this.renderRow}
|
||||
</List>
|
||||
</StyledVersionList>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledBody>
|
||||
{versions && !isLoading ? (
|
||||
<div className="version-list">
|
||||
<AutoSizer>{renderList}</AutoSizer>
|
||||
</div>
|
||||
) : (
|
||||
<div className="loader-history-rows">
|
||||
<Loaders.HistoryRows title="version-history-body-loader" />
|
||||
</div>
|
||||
)}
|
||||
</StyledBody>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -50,12 +50,12 @@ class PureVersionHistory extends React.Component {
|
||||
|
||||
return (
|
||||
<PageLayout
|
||||
withBodyScroll={true}
|
||||
withBodyAutoFocus={true}
|
||||
headerBorderBottom={true}
|
||||
showSecondaryProgressBar={showProgressBar}
|
||||
secondaryProgressBarIcon="file"
|
||||
showSecondaryButtonAlert={false}>
|
||||
showSecondaryButtonAlert={false}
|
||||
withBodyScroll={false}>
|
||||
<PageLayout.ArticleHeader>
|
||||
<ArticleHeaderContent />
|
||||
</PageLayout.ArticleHeader>
|
||||
|
@ -20,6 +20,7 @@ class DialogsStore {
|
||||
newFilesPanelVisible = false;
|
||||
conflictResolveDialogVisible = false;
|
||||
convertDialogVisible = false;
|
||||
isFolderActions = false;
|
||||
|
||||
removeItem = null;
|
||||
connectItem = null;
|
||||
@ -44,6 +45,10 @@ class DialogsStore {
|
||||
this.sharingPanelVisible = sharingPanelVisible;
|
||||
};
|
||||
|
||||
setIsFolderActions = (isFolderActions) => {
|
||||
this.isFolderActions = isFolderActions;
|
||||
};
|
||||
|
||||
setChangeOwnerPanelVisible = (ownerPanelVisible) => {
|
||||
this.ownerPanelVisible = ownerPanelVisible;
|
||||
};
|
||||
|
@ -61,13 +61,24 @@ class FilesActionStore {
|
||||
clearSecondaryProgressData,
|
||||
} = this.uploadDataStore.secondaryProgressDataStore;
|
||||
|
||||
let updatedFolder = this.selectedFolderStore.id;
|
||||
|
||||
if (this.dialogsStore.isFolderActions) {
|
||||
updatedFolder = this.selectedFolderStore.parentId;
|
||||
}
|
||||
|
||||
const { filter, fetchFiles } = this.filesStore;
|
||||
fetchFiles(this.selectedFolderStore.id, filter, true, true).finally(() =>
|
||||
setTimeout(() => clearSecondaryProgressData(), TIMEOUT)
|
||||
);
|
||||
fetchFiles(updatedFolder, filter, true, true).finally(() => {
|
||||
this.dialogsStore.setIsFolderActions(false);
|
||||
return setTimeout(() => clearSecondaryProgressData(), TIMEOUT);
|
||||
});
|
||||
};
|
||||
|
||||
deleteAction = async (translations, newSelection = null) => {
|
||||
deleteAction = async (
|
||||
translations,
|
||||
newSelection = null,
|
||||
withoutDialog = false
|
||||
) => {
|
||||
const { isRecycleBinFolder, isPrivacyFolder } = this.treeFoldersStore;
|
||||
|
||||
const selection = newSelection ? newSelection : this.filesStore.selection;
|
||||
@ -88,8 +99,8 @@ class FilesActionStore {
|
||||
const deleteAfter = false; //Delete after finished TODO: get from settings
|
||||
const immediately = isRecycleBinFolder || isPrivacyFolder ? true : false; //Don't move to the Recycle Bin
|
||||
|
||||
const folderIds = [];
|
||||
const fileIds = [];
|
||||
let folderIds = [];
|
||||
let fileIds = [];
|
||||
|
||||
let i = 0;
|
||||
while (selection.length !== i) {
|
||||
@ -101,6 +112,13 @@ class FilesActionStore {
|
||||
i++;
|
||||
}
|
||||
|
||||
if (this.dialogsStore.isFolderActions && withoutDialog) {
|
||||
folderIds = [];
|
||||
fileIds = [];
|
||||
|
||||
folderIds.push(selection[0]);
|
||||
}
|
||||
|
||||
if (folderIds.length || fileIds.length) {
|
||||
this.isMediaOpen();
|
||||
|
||||
@ -211,18 +229,18 @@ class FilesActionStore {
|
||||
}
|
||||
};
|
||||
|
||||
downloadAction = (label) => {
|
||||
downloadAction = (label, folderId) => {
|
||||
const { bufferSelection } = this.filesStore;
|
||||
|
||||
const selection = this.filesStore.selection.length
|
||||
? this.filesStore.selection
|
||||
: [bufferSelection];
|
||||
|
||||
const fileIds = [];
|
||||
const folderIds = [];
|
||||
let fileIds = [];
|
||||
let folderIds = [];
|
||||
const items = [];
|
||||
|
||||
if (selection.length === 1 && selection[0].fileExst) {
|
||||
if (selection.length === 1 && selection[0].fileExst && !folderId) {
|
||||
window.open(selection[0].viewUrl, "_self");
|
||||
return Promise.resolve();
|
||||
}
|
||||
@ -237,6 +255,14 @@ class FilesActionStore {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.dialogsStore.isFolderActions) {
|
||||
fileIds = [];
|
||||
folderIds = [];
|
||||
|
||||
folderIds.push(bufferSelection);
|
||||
this.dialogsStore.setIsFolderActions(false);
|
||||
}
|
||||
|
||||
return this.downloadFiles(fileIds, folderIds, label);
|
||||
};
|
||||
|
||||
|
@ -1062,7 +1062,7 @@ class FilesStore {
|
||||
const { getFileIcon, getFolderIcon } = this.formatsStore.iconFormatsStore;
|
||||
|
||||
if (items.length && items[0].id === -1) return; //TODO: if change media collection from state remove this;
|
||||
const iconSize = this.viewAs === "tile" ? 32 : 24;
|
||||
const iconSize = this.viewAs === "tile" && isMobile ? 32 : 24;
|
||||
const icon = this.fileActionStore.extension
|
||||
? getFileIcon(`.${this.fileActionStore.extension}`, iconSize)
|
||||
: getFolderIcon(null, iconSize);
|
||||
@ -1134,7 +1134,7 @@ class FilesStore {
|
||||
const isThirdPartyFolder = providerKey && id === rootFolderId;
|
||||
|
||||
//const isCanWebEdit = canWebEdit(item.fileExst);
|
||||
const iconSize = this.viewAs === "tile" ? 32 : 24;
|
||||
const iconSize = this.viewAs === "tile" && isMobile ? 32 : 24;
|
||||
const icon = getIcon(iconSize, fileExst, providerKey, contentLength);
|
||||
|
||||
let isFolder = false;
|
||||
@ -1573,6 +1573,7 @@ class FilesStore {
|
||||
getFolderInfo = async (id) => {
|
||||
const folderInfo = await api.files.getFolderInfo(id);
|
||||
this.setFolder(folderInfo);
|
||||
return folderInfo;
|
||||
};
|
||||
|
||||
openDocEditor = (id, providerKey = null, tab = null, url = null) => {
|
||||
|
@ -389,7 +389,7 @@ class UploadDataStore {
|
||||
this.uploadToFolder = null;
|
||||
this.percent = 0;
|
||||
}
|
||||
if (this.converted) {
|
||||
if (this.uploaded && this.converted) {
|
||||
this.files = [];
|
||||
this.filesToConversion = [];
|
||||
}
|
||||
@ -874,13 +874,14 @@ class UploadDataStore {
|
||||
return;
|
||||
}
|
||||
|
||||
let operationItem = null;
|
||||
let operationItem = data;
|
||||
let finished = data.finished;
|
||||
|
||||
while (progress !== 100) {
|
||||
await this.getOperationProgress(data.id)
|
||||
.then((item) => {
|
||||
while (!finished) {
|
||||
const item = await this.getOperationProgress(data.id);
|
||||
operationItem = item;
|
||||
progress = item ? item.progress : 100;
|
||||
finished = item.finished;
|
||||
|
||||
setSecondaryProgressBarData({
|
||||
icon: pbData.icon,
|
||||
@ -889,10 +890,9 @@ class UploadDataStore {
|
||||
visible: true,
|
||||
alert: false,
|
||||
});
|
||||
})
|
||||
.catch((err) => Promise.reject(err));
|
||||
}
|
||||
return Promise.resolve(operationItem);
|
||||
|
||||
return operationItem;
|
||||
};
|
||||
|
||||
moveToCopyTo = (destFolderId, pbData, isCopy) => {
|
||||
@ -904,7 +904,15 @@ class UploadDataStore {
|
||||
label,
|
||||
} = this.secondaryProgressDataStore;
|
||||
|
||||
getFolder(destFolderId).then((data) => {
|
||||
let receivedFolder = destFolderId;
|
||||
let updatedFolder = this.selectedFolderStore.id;
|
||||
|
||||
if (this.dialogsStore.isFolderActions) {
|
||||
receivedFolder = this.selectedFolderStore.parentId;
|
||||
updatedFolder = destFolderId;
|
||||
}
|
||||
|
||||
getFolder(receivedFolder).then((data) => {
|
||||
let newTreeFolders = treeFolders;
|
||||
let path = data.pathParts.slice(0);
|
||||
let folders = data.folders;
|
||||
@ -912,11 +920,12 @@ class UploadDataStore {
|
||||
loopTreeFolders(path, newTreeFolders, folders, foldersCount);
|
||||
|
||||
if (!isCopy || destFolderId === this.selectedFolderStore.id) {
|
||||
fetchFiles(this.selectedFolderStore.id, filter, true, true).finally(
|
||||
() => {
|
||||
this.filesStore
|
||||
.fetchFiles(updatedFolder, this.filesStore.filter, true, true)
|
||||
.finally(() => {
|
||||
setTimeout(() => clearSecondaryProgressData(), TIMEOUT);
|
||||
}
|
||||
);
|
||||
this.dialogsStore.setIsFolderActions(false);
|
||||
});
|
||||
} else {
|
||||
setSecondaryProgressBarData({
|
||||
icon: pbData.icon,
|
||||
|
@ -7,6 +7,7 @@ class VersionHistoryStore {
|
||||
versions = null;
|
||||
filesStore = null;
|
||||
showProgressBar = false;
|
||||
timerId = null;
|
||||
|
||||
constructor(filesStore) {
|
||||
makeObservable(this, {
|
||||
@ -79,7 +80,7 @@ class VersionHistoryStore {
|
||||
};
|
||||
|
||||
restoreVersion = (id, version) => {
|
||||
this.setShowProgressBar(true);
|
||||
this.timerId = setTimeout(() => this.setShowProgressBar(true), 100);
|
||||
|
||||
return api.files
|
||||
.versionRestore(id, version)
|
||||
@ -87,9 +88,13 @@ class VersionHistoryStore {
|
||||
const updatedVersions = this.versions.slice();
|
||||
updatedVersions.splice(1, 0, newVersion);
|
||||
this.setVerHistoryFileVersions(updatedVersions);
|
||||
this.setShowProgressBar(false);
|
||||
})
|
||||
.catch(() => this.setShowProgressBar(false));
|
||||
.catch((e) => console.error(e))
|
||||
.finally(() => {
|
||||
clearTimeout(this.timerId);
|
||||
this.timerId = null;
|
||||
this.setShowProgressBar(false);
|
||||
});
|
||||
};
|
||||
|
||||
updateCommentVersion = (id, comment, version) => {
|
||||
|
@ -515,6 +515,7 @@ namespace ASC.Files.Core.Data
|
||||
|
||||
var toInsert = FilesDbContext.Tree
|
||||
.Where(r => r.FolderId == toFolderId)
|
||||
.OrderBy(r => r.Level)
|
||||
.ToList();
|
||||
|
||||
foreach (var subfolder in subfolders)
|
||||
@ -525,7 +526,7 @@ namespace ASC.Files.Core.Data
|
||||
{
|
||||
FolderId = subfolder.Key,
|
||||
ParentId = f.ParentId,
|
||||
Level = f.Level + 1
|
||||
Level = subfolder.Value + 1 + f.Level
|
||||
};
|
||||
FilesDbContext.AddOrUpdate(r => r.Tree, newTree);
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ using ASC.Common.Threading;
|
||||
using ASC.Common.Web;
|
||||
using ASC.Core.Tenants;
|
||||
using ASC.Files.Core;
|
||||
using ASC.Files.Core.EF;
|
||||
using ASC.Files.Core.Resources;
|
||||
using ASC.MessagingSystem;
|
||||
using ASC.Web.Core.Files;
|
||||
@ -117,9 +118,42 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
|
||||
MimeMapping.GetMimeMapping(path),
|
||||
"attachment; filename=\"" + fileName + "\"");
|
||||
Result = string.Format("{0}?{1}=bulk&ext={2}", filesLinkUtility.FileHandlerPath, FilesLinkUtility.Action, archiveExtension);
|
||||
|
||||
TaskInfo.SetProperty(PROGRESS, 100);
|
||||
TaskInfo.SetProperty(RESULT, Result);
|
||||
TaskInfo.SetProperty(FINISHED, true);
|
||||
|
||||
}
|
||||
|
||||
FillDistributedTask();
|
||||
TaskInfo.PublishChanges();
|
||||
}
|
||||
|
||||
public override void PublishChanges(DistributedTask task)
|
||||
{
|
||||
var thirdpartyTask = ThirdPartyOperation.GetDistributedTask();
|
||||
var daoTask = DaoOperation.GetDistributedTask();
|
||||
|
||||
var error1 = thirdpartyTask.GetProperty<string>(ERROR);
|
||||
var error2 = daoTask.GetProperty<string>(ERROR);
|
||||
|
||||
if (!string.IsNullOrEmpty(error1))
|
||||
{
|
||||
Error = error1;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(error2))
|
||||
{
|
||||
Error = error2;
|
||||
}
|
||||
|
||||
successProcessed = thirdpartyTask.GetProperty<int>(PROCESSED) + daoTask.GetProperty<int>(PROCESSED);
|
||||
|
||||
var progressSteps = ThirdPartyOperation.Total + DaoOperation.Total + 1;
|
||||
|
||||
var progress = (int)(successProcessed / (double)progressSteps * 100);
|
||||
|
||||
base.FillDistributedTask();
|
||||
|
||||
TaskInfo.SetProperty(PROGRESS, progress < 100 ? progress : progress);
|
||||
TaskInfo.PublishChanges();
|
||||
}
|
||||
}
|
||||
@ -146,6 +180,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
|
||||
if (!Files.Any() && !Folders.Any()) return;
|
||||
|
||||
entriesPathId = GetEntriesPathId(scope);
|
||||
|
||||
if (entriesPathId == null || entriesPathId.Count == 0)
|
||||
{
|
||||
if (Files.Count > 0)
|
||||
@ -157,6 +192,10 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
|
||||
}
|
||||
|
||||
ReplaceLongPath(entriesPathId);
|
||||
|
||||
Total = entriesPathId.Count;
|
||||
|
||||
TaskInfo.PublishChanges();
|
||||
}
|
||||
|
||||
private ItemNameValueCollection<T> ExecPathFromFile(IServiceScope scope, File<T> file, string path)
|
||||
@ -345,6 +384,15 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
|
||||
}
|
||||
compressTo.CloseEntry();
|
||||
counter++;
|
||||
|
||||
if (!Equals(entryId, default(T)) && file != null)
|
||||
{
|
||||
ProcessedFile(entryId);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessedFolder(default(T));
|
||||
}
|
||||
}
|
||||
|
||||
ProgressStep();
|
||||
|
@ -149,7 +149,7 @@ namespace ASC.Web.Files.Services.WCFService.FileOperations
|
||||
base.FillDistributedTask();
|
||||
}
|
||||
|
||||
public void PublishChanges(DistributedTask task)
|
||||
public virtual void PublishChanges(DistributedTask task)
|
||||
{
|
||||
var thirdpartyTask = ThirdPartyOperation.GetDistributedTask();
|
||||
var daoTask = DaoOperation.GetDistributedTask();
|
||||
|
@ -11,7 +11,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AppLimit.CloudComputing.SharpBox" Version="1.1.0.456" />
|
||||
<PackageReference Include="AppLimit.CloudComputing.SharpBox" Version="1.1.0.457" />
|
||||
<PackageReference Include="Autofac" Version="6.0.0" />
|
||||
<PackageReference Include="Autofac.Configuration" Version="6.0.0" />
|
||||
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
|
||||
|
@ -21,8 +21,6 @@ class ContactField extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log("ContactField render");
|
||||
|
||||
const {
|
||||
isDisabled,
|
||||
|
||||
|
@ -66,8 +66,6 @@ class ContactsField extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log("ContactsField render");
|
||||
|
||||
const {
|
||||
pattern,
|
||||
contacts,
|
||||
|
@ -9,8 +9,6 @@ class DateField extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log("DateField render");
|
||||
|
||||
const {
|
||||
isRequired,
|
||||
hasError,
|
||||
|
@ -16,8 +16,6 @@ class DepartmentField extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
console.log("DepartmentField render");
|
||||
|
||||
const {
|
||||
isRequired,
|
||||
isDisabled,
|
||||
|
@ -9,8 +9,6 @@ class EmailField extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log("EmailField render");
|
||||
|
||||
const {
|
||||
isRequired,
|
||||
hasError,
|
||||
|
@ -11,8 +11,6 @@ class PasswordField extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log("PasswordField render");
|
||||
|
||||
const {
|
||||
isRequired,
|
||||
hasError,
|
||||
|
@ -9,8 +9,6 @@ class RadioField extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
//console.log("RadioField render");
|
||||
|
||||
const {
|
||||
isRequired,
|
||||
hasError,
|
||||
|
@ -18,8 +18,6 @@ class TextChangeField extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log("TextChangeField render");
|
||||
|
||||
const {
|
||||
isRequired,
|
||||
hasError,
|
||||
|
@ -9,8 +9,6 @@ class TextField extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log("TextField render");
|
||||
|
||||
const {
|
||||
isRequired,
|
||||
hasError,
|
||||
|
@ -499,7 +499,6 @@ class UpdateUserForm extends React.Component {
|
||||
this.setState({ isLoading: true });
|
||||
const { profile, setAvatarMax, personal } = this.props;
|
||||
|
||||
console.log("profile", profile);
|
||||
if (isUpdate) {
|
||||
createThumbnailsAvatar(profile.id, {
|
||||
x: Math.round(result.x * avatar.defaultWidth - result.width / 2),
|
||||
@ -727,7 +726,6 @@ class UpdateUserForm extends React.Component {
|
||||
source={this.props.avatarMax || profile.avatarMax}
|
||||
userName={profile.displayName}
|
||||
editing={true}
|
||||
editLabel={t("Common:EditAvatar")}
|
||||
editAction={
|
||||
isMobile ? this.openAvatarEditorPage : this.openAvatarEditor
|
||||
}
|
||||
|
3
public/images/pencil.react.svg
Normal file
3
public/images/pencil.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="M1.35866 11.0127L0.366956 14.6494C0.204108 15.2466 0.752062 15.7945 1.34924 15.6317L4.98595 14.64C5.32177 14.5484 5.62787 14.3708 5.87399 14.1247L12.7918 7.20689L8.79177 3.20689L1.87399 10.1247C1.62787 10.3708 1.45024 10.6769 1.35866 11.0127ZM10.2059 1.79264L14.2059 5.79264L14.9985 4.99999C16.103 3.89541 16.103 2.1046 14.9985 1.00006C13.8939 -0.104537 12.103 -0.104507 10.9984 1.00012L10.2059 1.79264Z" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 572 B |
Loading…
Reference in New Issue
Block a user