diff --git a/packages/asc-web-common/components/Loaders/TileLoader/StyledTileLoader.js b/packages/asc-web-common/components/Loaders/TileLoader/StyledTileLoader.js index 60dcf68fa04..bce25a8ed90 100644 --- a/packages/asc-web-common/components/Loaders/TileLoader/StyledTileLoader.js +++ b/packages/asc-web-common/components/Loaders/TileLoader/StyledTileLoader.js @@ -1,85 +1,79 @@ import styled, { css } from "styled-components"; -import { mobile, tablet } from "@appserver/components/utils/device"; +import { smallTablet, tablet, size } from "@appserver/components/utils/device"; const StyledTile = styled.div` position: relative; display: grid; - //min-width: 250px; width: 100%; - height: ${(props) => (props.isFolder ? "57px" : "240px")}; - border: 1px solid #d0d5da; - border-radius: 3px; + height: ${(props) => (props.isFolder ? "32px" : "220px")}; - ${(props) => - props.isFolder - ? css` - &:before { - content: ""; - position: absolute; - top: -5px; - left: -1px; - border-top: 1px solid #d0d5da; - border-top-left-radius: 3px; - border-left: 1px solid #d0d5da; - width: 38px; - height: 8px; - background-color: #fff; - border-bottom: transparent; - } + @media ${smallTablet} { + &:nth-of-type(n + 3) { + display: none; + } - &:after { - content: ""; - position: absolute; - top: -4px; - left: 34px; - border-top: 1px solid #d0d5da; - background-color: #fff; - width: 7px; - height: 10px; - transform: rotateZ(35deg); + ${(props) => + props.isFolder && + css` + &:nth-of-type(n + 2) { + display: none; + } + `} + } - @media ${tablet} { - left: 34px; - } - } - ` - : null} + @media (min-width: ${size.smallTablet}px) and ${tablet} { + &:nth-of-type(n + 7) { + display: none; + } + } `; const StyledMainContent = styled.div` - padding: 12px 12px 4px 12px; - height: 175px; - - clipPath > rect { - width: calc(100% + 20px); - } + height: 172px; `; const StyledBottom = styled.div` - display: grid; - grid-template-columns: 24px auto; - grid-gap: 8px; - padding: ${(props) => (props.isFolder ? "20px 12px" : "8px 12px 12px 12px")}; + display: flex; + align-items: ${(props) => (props.isFolder ? "center" : "stretch")}; + margin-top: ${(props) => (props.isFolder ? 0 : "10px")}; + height: 38px; .first-content { - display: inline-block; - ${(props) => - !props.isFolder - ? css` - width: 24px; - height: 30px; - ` - : css` - width: 16px; - height: 16px; - `} + height: 32px; + width: 32px; + min-width: 32px; } + .second-content { - clipPath > rect { - width: calc(100% + 20px); - } width: 100%; - height: ${(props) => (props.isFolder ? "16px" : "30px")}; + height: ${(props) => (props.isFolder ? "32px" : "16px")}; + margin-left: 8px; + } + + .files-second-content { + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: flex-end; + margin-left: 8px; + + .second-content { + &:last-of-type { + height: 12px; + margin-right: auto; + margin-left: 0; + width: 50%; + border-radius: 3px; + } + } + } + + .option-button { + height: 16px; + width: 16px; + min-width: 16px; + margin-left: 8px; + border-radius: 6px; } `; diff --git a/packages/asc-web-common/components/Loaders/TileLoader/TileLoader.js b/packages/asc-web-common/components/Loaders/TileLoader/TileLoader.js index e3d519737c4..e578e755009 100644 --- a/packages/asc-web-common/components/Loaders/TileLoader/TileLoader.js +++ b/packages/asc-web-common/components/Loaders/TileLoader/TileLoader.js @@ -32,7 +32,7 @@ const TileLoader = ({ backgroundOpacity={backgroundOpacity} foregroundOpacity={foregroundOpacity} speed={speed} - animate={false} + animate={true} /> + @@ -53,7 +64,6 @@ const TileLoader = ({ @@ -75,20 +85,34 @@ const TileLoader = ({ backgroundOpacity={backgroundOpacity} foregroundOpacity={foregroundOpacity} speed={speed} - animate={false} - /> - +
+ + +
); diff --git a/packages/asc-web-common/components/Loaders/TilesLoader/TilesLoader.js b/packages/asc-web-common/components/Loaders/TilesLoader/TilesLoader.js index ee6244d0429..d93d186fe9e 100644 --- a/packages/asc-web-common/components/Loaders/TilesLoader/TilesLoader.js +++ b/packages/asc-web-common/components/Loaders/TilesLoader/TilesLoader.js @@ -4,10 +4,11 @@ import PropTypes from "prop-types"; import TileLoader from "../TileLoader"; import RectangleLoader from "../RectangleLoader"; +import { tablet } from "@appserver/components/utils/device"; const StyledTilesLoader = styled.div` display: grid; - grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); + grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); width: 100%; grid-gap: 16px; `; @@ -18,18 +19,22 @@ const StyledWrapper = styled.div` grid-gap: 16px; .folders { - margin-bottom: -4px; + margin-top: -1px; + margin-bottom: 12px; } + .files { - margin-top: 12px; + margin-top: 25px; } - margin-right: 9px; - @media (max-width: 1024px) { - margin-right: 2px; + + margin-right: 3px; + + @media ${tablet} { + margin-right: -1px; } `; -const TilesLoader = ({ foldersCount, filesCount, ...rest }) => { +const TilesLoader = ({ foldersCount, filesCount, sectionWidth, ...rest }) => { const folders = []; const files = []; @@ -40,24 +45,26 @@ const TilesLoader = ({ foldersCount, filesCount, ...rest }) => { for (let i = 0; i < filesCount; i++) { files.push(); } + return ( {foldersCount > 0 ? ( ) : null} {folders} + {filesCount > 0 ? ( ) : null} @@ -72,8 +79,8 @@ TilesLoader.propTypes = { }; TilesLoader.defaultProps = { - foldersCount: 3, - filesCount: 3, + foldersCount: 2, + filesCount: 8, }; export default TilesLoader; diff --git a/packages/asc-web-components/badge/index.js b/packages/asc-web-components/badge/index.js index 5dff0c7e7b8..b3566db646b 100644 --- a/packages/asc-web-components/badge/index.js +++ b/packages/asc-web-components/badge/index.js @@ -23,10 +23,12 @@ const Badge = (props) => { padding, maxWidth, lineHeight, + isHovered, + label, } = props; return ( - + { color={color} fontSize={fontSize} > - {props.label} + {label} @@ -74,6 +76,10 @@ Badge.propTypes = { id: PropTypes.string, /** Accepts css style */ style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), + /** Set hovered state and effects of link */ + isHovered: PropTypes.bool, + /** Disabled hover styles */ + noHover: PropTypes.bool, }; Badge.defaultProps = { @@ -86,6 +92,8 @@ Badge.defaultProps = { padding: "0 5px", maxWidth: "50px", lineHeight: "1.78", + isHovered: false, + noHover: false, }; export default Badge; diff --git a/packages/asc-web-components/badge/styled-badge.js b/packages/asc-web-components/badge/styled-badge.js index c8f73658cd2..ea6a8dfeec4 100644 --- a/packages/asc-web-components/badge/styled-badge.js +++ b/packages/asc-web-components/badge/styled-badge.js @@ -1,6 +1,10 @@ -import styled from "styled-components"; +import styled, { css } from "styled-components"; import Base from "../themes/base"; +const hoveredCss = css` + border-color: ${(props) => props.backgroundColor}; +`; + const StyledBadge = styled.div` display: ${(props) => props.label.length > 0 || props.label != "0" ? "inline-block" : "none"}; @@ -12,9 +16,11 @@ const StyledBadge = styled.div` cursor: pointer; overflow: ${(props) => props.theme.badge.overflow}; - :hover { - border-color: ${(props) => props.backgroundColor}; + &:hover { + ${(props) => !props.noHover && hoveredCss}; } + + ${(props) => !props.noHover && props.isHovered && hoveredCss} `; StyledBadge.defaultProps = { theme: Base }; diff --git a/products/ASC.Files/Client/src/HOCs/withBadges.js b/products/ASC.Files/Client/src/HOCs/withBadges.js index 4d5aac0eede..078c5af409e 100644 --- a/products/ASC.Files/Client/src/HOCs/withBadges.js +++ b/products/ASC.Files/Client/src/HOCs/withBadges.js @@ -122,6 +122,7 @@ export default function withBadges(WrappedComponent) { isAdmin, isDesktopClient, sectionWidth, + viewAs, } = this.props; const { fileStatus, access } = item; @@ -150,6 +151,7 @@ export default function withBadges(WrappedComponent) { onBadgeClick={this.onBadgeClick} setConvertDialogVisible={this.setConvertDialogVisible} onFilesClick={onFilesClick} + viewAs={viewAs} /> ); diff --git a/products/ASC.Files/Client/src/components/Badges.js b/products/ASC.Files/Client/src/components/Badges.js index 8c698b15271..201db2fb864 100644 --- a/products/ASC.Files/Client/src/components/Badges.js +++ b/products/ASC.Files/Client/src/components/Badges.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState } from "react"; import styled from "styled-components"; import Badge from "@appserver/components/badge"; import IconButton from "@appserver/components/icon-button"; @@ -9,6 +9,42 @@ export const StyledIcon = styled(IconButton)` ${commonIconsStyles} `; +const StyledWrapper = styled.div` + display: flex; + justify-content: center; + align-items: center; + background: white; + padding: 6px; + border-radius: 4px; + box-shadow: 0px 2px 4px rgba(4, 15, 27, 0.16); +`; + +const BadgeWrapper = ({ onClick, isTile, children: badge }) => { + if (!isTile) return badge; + + const [isHovered, setIsHovered] = useState(false); + + const onMouseEnter = () => { + setIsHovered(true); + }; + + const onMouseLeave = () => { + setIsHovered(false); + }; + + const newBadge = React.cloneElement(badge, { isHovered: isHovered }); + + return ( + + {newBadge} + + ); +}; + const Badges = ({ t, newItems, @@ -25,6 +61,7 @@ const Badges = ({ onShowVersionHistory, onBadgeClick, setConvertDialogVisible, + viewAs, }) => { const { id, locked, fileStatus, version, versionGroup, fileExst } = item; @@ -34,6 +71,7 @@ const Badges = ({ const showEditBadge = !locked || item.access === 0; const isPrivacy = isPrivacyFolder && isDesktopClient; const isForm = fileExst === ".oform"; + const isTile = viewAs === "tile"; const iconEdit = isForm ? "/static/images/access.edit.form.react.svg" @@ -48,15 +86,26 @@ const Badges = ({ const contentNewItems = newItems > 999 ? "999+" : newItems; const tabletViewBadge = - (sectionWidth > 500 && sectionWidth <= 1024) || isTablet; + !isTile && ((sectionWidth > 500 && sectionWidth <= 1024) || isTablet); - const sizeBadge = tabletViewBadge ? "medium" : "small"; + const sizeBadge = isTile || tabletViewBadge ? "medium" : "small"; - const lineHeightBadge = tabletViewBadge ? "1.46" : "1.34"; + const lineHeightBadge = isTile || tabletViewBadge ? "1.46" : "1.34"; - const paddingBadge = tabletViewBadge ? "0 5px" : "0 3px"; + const paddingBadge = isTile || tabletViewBadge ? "0 5px" : "0 3px"; - const fontSizeBadge = tabletViewBadge ? "11px" : "9px"; + const fontSizeBadge = isTile || tabletViewBadge ? "11px" : "9px"; + + const commonBadgeProps = { + borderRadius: "11px", + color: "#FFFFFF", + fontSize: fontSizeBadge, + fontWeight: 800, + maxWidth: "50px", + padding: paddingBadge, + lineHeight: lineHeightBadge, + "data-id": id, + }; return fileExst ? (
@@ -98,53 +147,36 @@ const Badges = ({ /> )} {version > 1 && ( - + + + )} {(showNew || isNewWithFav) && ( - + + + )}
) : ( showNew && ( ) ); diff --git a/products/ASC.Files/Client/src/components/EditingWrapperComponent.js b/products/ASC.Files/Client/src/components/EditingWrapperComponent.js index a731fbbcad8..b421b61bca3 100644 --- a/products/ASC.Files/Client/src/components/EditingWrapperComponent.js +++ b/products/ASC.Files/Client/src/components/EditingWrapperComponent.js @@ -6,6 +6,7 @@ import commonIconsStyles from "@appserver/components/utils/common-icons-style"; import CheckIcon from "../../public/images/check.react.svg"; import CrossIcon from "../../../../../public/images/cross.react.svg"; +import { tablet } from "@appserver/components/utils/device"; const StyledCheckIcon = styled(CheckIcon)` ${commonIconsStyles} @@ -52,11 +53,13 @@ const EditingWrapper = styled.div` ${(props) => props.viewAs === "tile" && - `margin-right: 12px !important; margin-left: -4px;`} - - @media (max-width: 1024px) { + `margin-right: 10px !important; margin-left: 8px;`} + + + @media ${tablet} { height: 56px; } + .edit-text { height: 32px; font-size: ${(props) => @@ -71,13 +74,34 @@ const EditingWrapper = styled.div` font-family: "Open Sans", sans-serif, Arial; text-align: left; color: #333333; - margin-left: 6px; + ${(props) => + props.viewAs === "tile" && + css` + margin-right: 2px; + border: none; + background: none; + `}; } + .edit-button { - margin-left: 8px; height: 32px; padding: 8px 7px 7px 7px; + ${(props) => + props.viewAs === "tile" && + css` + background: none; + border: 1px solid transparent; + + :hover { + border-color: #d0d5da; + } + + &:last-child { + margin-left: 2px; + } + `}; + ${(props) => props.viewAs === "table" && css` @@ -90,10 +114,6 @@ const EditingWrapper = styled.div` border: 1px solid #d0d5da; } `} - - &:last-child { - margin-left: 4px; - } } .edit-ok-icon { @@ -139,11 +159,9 @@ const EditingWrapperComponent = (props) => { if (!isLoading) setIsLoading(true); return onClickUpdateItem(e); } - //if (code === 27) return cancelUpdateItem(e); }; const onEscapeKeyPress = (e) => { if (e.keyCode === 27) return cancelUpdateItem(e); - return; }; const setIsHoveredOkHandler = () => { diff --git a/products/ASC.Files/Client/src/components/QuickButtons.js b/products/ASC.Files/Client/src/components/QuickButtons.js index ebd416b2e90..b7ee214d973 100644 --- a/products/ASC.Files/Client/src/components/QuickButtons.js +++ b/products/ASC.Files/Client/src/components/QuickButtons.js @@ -26,9 +26,11 @@ const QuickButtons = ({ const isEditingWithFav = fileStatus === 33; const showFavorite = isFavorite || isNewWithFav || isEditingWithFav; - const colorSharedButton = shared ? "#3B72A7" : "#a3a9ae"; + const isTile = viewAs === "tile"; - const iconShare = "/static/images/catalog.share.react.svg"; + const iconShare = shared + ? "/static/images/file.actions.share.react.svg" + : "/static/images/catalog.share.react.svg"; const iconLock = locked ? "/static/images/file.actions.locked.react.svg" @@ -39,8 +41,8 @@ const QuickButtons = ({ : "/static/images/favorite.react.svg"; const tabletViewQuickButton = - (sectionWidth > 500 && sectionWidth <= 1024) || isTablet; - const sizeQuickButton = tabletViewQuickButton ? "medium" : "small"; + !isTile && ((sectionWidth > 500 && sectionWidth <= 1024) || isTablet); + const sizeQuickButton = isTile || tabletViewQuickButton ? "medium" : "small"; const displayShare = viewAs === "row" && (isMobile || sectionWidth <= 500); const displayLock = !locked && (isMobile || sectionWidth <= 500); @@ -48,27 +50,30 @@ const QuickButtons = ({ return (
- {item.canShare && showShare && !displayShare && ( + {item.canShare && showShare && (!displayShare || isTile) && ( - )} - {fileExst && accessToEdit && !isTrashFolder && !displayLock && ( - )} - {fileExst && !isTrashFolder && !displayFavorite && ( + {fileExst && + accessToEdit && + !isTrashFolder && + (!displayLock || isTile) && ( + + )} + {fileExst && !isTrashFolder && (!displayFavorite || isTile) && ( { diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FileTile.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FileTile.js index eb450c427a5..2ae7f32e33e 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FileTile.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FileTile.js @@ -11,10 +11,10 @@ import withFileActions from "../../../../../HOCs/withFileActions"; import withContextOptions from "../../../../../HOCs/withContextOptions"; import withQuickButtons from "../../../../../HOCs/withQuickButtons"; import ItemIcon from "../../../../../components/ItemIcon"; +import withBadges from "../../../../../HOCs/withBadges"; -const FilesTile = (props) => { +const FileTile = (props) => { const { - t, item, sectionWidth, dragging, @@ -27,17 +27,16 @@ const FilesTile = (props) => { value, displayShareButton, isPrivacy, - //sharedButton, contextOptionsProps, checkedProps, - //element, getIcon, onFilesClick, onMouseClick, - showShare, isActive, isEdit, quickButtonsComponent, + badgesComponent, + t, } = props; const temporaryExtension = @@ -97,6 +96,7 @@ const FilesTile = (props) => { sectionWidth={sectionWidth} onFilesClick={onFilesClick} /> + {badgesComponent}
@@ -107,9 +107,11 @@ export default inject(({ formatsStore }) => { const { getIcon } = formatsStore.iconFormatsStore; return { getIcon }; })( - withTranslation("Home")( + withTranslation(["Home", "VersionBadge"])( withFileActions( - withContextOptions(withRouter(withQuickButtons(observer(FilesTile)))) + withContextOptions( + withRouter(withBadges(withQuickButtons(observer(FileTile)))) + ) ) ) ); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FilesTileContent.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FilesTileContent.js index 469a8bc3391..79b7ecbdc99 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FilesTileContent.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FilesTileContent.js @@ -4,33 +4,23 @@ import { withTranslation } from "react-i18next"; import styled from "styled-components"; import Link from "@appserver/components/link"; -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"; +import { isDesktop } from "react-device-detect"; const SimpleFilesTileContent = styled(TileContent)` .row-main-container { height: auto; max-width: 100%; align-self: flex-end; - - a { - word-break: break-word; - } } .main-icons { align-self: flex-end; } - .badge-ext { - margin-left: -8px; - margin-right: 8px; - } - .badge { margin-right: 8px; cursor: pointer; @@ -54,11 +44,6 @@ const SimpleFilesTileContent = styled(TileContent)` padding-right: 8px; } - .title-link { - font-size: ${isMobile ? "15px" : "13px"}; - margin-top: 2px; - } - .favorite, .can-convert, .edit { @@ -78,45 +63,26 @@ const SimpleFilesTileContent = styled(TileContent)` } `; -const FilesTileContent = ({ - item, - titleWithoutExt, - linkStyles, - badgesComponent, -}) => { +const FilesTileContent = ({ item, titleWithoutExt, linkStyles }) => { const { fileExst, title } = item; return ( <> {titleWithoutExt} - {fileExst ? ( - - {fileExst} - - ) : null} - -
{badgesComponent}
); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js index 29a34ebe578..9102fafb725 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js @@ -6,11 +6,12 @@ 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 { isDesktop } from "react-device-detect"; import Link from "@appserver/components/link"; +import Loader from "@appserver/components/loader"; -const svgLoader = () =>
; +const svgLoader = () =>
; const FlexBoxStyles = css` display: flex; @@ -23,89 +24,48 @@ const FlexBoxStyles = css` `; const FolderStyles = css` - padding-left: 13px; - padding-bottom: 2px; - box-sizing: border-box; -`; - -const draggingStyle = css` - background-color: #f8f7bf; + height: 64px; `; -const draggingHoverStyle = css` - background-color: #efefb2; +const FileStyles = css` + height: 220px; `; const checkedStyle = css` background: #f3f4f4 !important; `; +const bottomFileBorder = css` + border-top-color: #d0d5da; + border-radius: 0 0 6px 6px; +`; + const StyledTile = styled.div` cursor: ${(props) => (!props.isRecycleBin ? "pointer" : "default")}; - min-height: 57px; + ${(props) => + props.inProgress && + css` + pointer-events: none; + /* cursor: wait; */ + `} box-sizing: border-box; width: 100%; border: 1px solid #d0d5da; - border-radius: 3px; - ${(props) => props.isFolder && "border-top-left-radius: 0px;"} + border-radius: 6px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); ${(props) => props.isFolder && FlexBoxStyles} - ${(props) => props.isFolder && FolderStyles} - ${(props) => (props.checked || props.isActive) && checkedStyle} - ${(props) => + ${(props) => (props.isFolder ? FolderStyles : FileStyles)} + ${(props) => + !props.isEdit && props.isFolder && - css` - &:before { - content: ""; - position: absolute; - top: -5px; - left: 0px; - border-top: 1px solid #d0d5da; - border-top-left-radius: 3px; - border-left: 1px solid #d0d5da; - width: 38px; - height: 8px; - background-color: #fff; - border-bottom: transparent; - } - &:after { - content: ""; - position: absolute; - top: -3.5px; - left: 36px; - border-top: 1px solid #d0d5da; - background-color: #fff; - width: 9px; - height: 10px; - transform: rotateZ(35deg); - - @media ${tablet} { - left: 35px; - } - } - `} - - &:before, - &:after { - ${(props) => props.isFolder && props.dragging && draggingStyle}; - } - - &:before, - &:after { - ${(props) => (props.checked || props.isActive) && checkedStyle}; - } - - &:hover:before, - &:hover:after { - ${(props) => props.isFolder && props.dragging && draggingHoverStyle}; - } + (props.checked || props.isActive) && + checkedStyle} .checkbox { display: flex; opacity: ${(props) => (props.checked ? 1 : 0)}; flex: 0 0 16px; - margin-right: 4px; justify-content: center; @media ${tablet} { @@ -116,68 +76,33 @@ const StyledTile = styled.div` .file-checkbox { display: ${(props) => (props.checked ? "flex" : "none")}; flex: 0 0 16px; - margin-top: 3px; - - margin-left: ${(props) => - isMobile - ? css` - ${props.isFolder ? "6px" : "12px"}; - ` - : css` - ${props.isFolder ? "5px" : "8px"} - `}; - - @media ${tablet} { - margin-top: 2px; - } + margin-top: 8px; + margin-left: ${(props) => (props.isFolder ? "8px" : "7px")}; } .file-icon { display: ${(props) => (props.checked ? "none" : "flex")}; flex: 0 0 auto; - margin-right: 4px; user-select: none; - margin-top: ${(props) => (props.isFolder ? "-8px" : "-6px")}; - - height: ${isMobile ? "32px" : "24px"}; - width: ${isMobile ? "32px" : "24px"}; - - img { - height: ${isMobile ? "32px" : "24px"}; - width: ${isMobile ? "32px" : "24px"}; - } - - margin-left: ${(props) => - isMobile - ? css` - ${props.isFolder ? "2px" : "4px"}; - ` - : css` - ${props.isFolder ? "2px" : "4px"} - `}; + margin-top: ${(props) => (props.isFolder ? "0" : "-2px")}; } .file-icon_container { - min-width: ${isMobile ? "36px" : "28px"}; + width: 32px; + height: 32px; + margin-left: ${(props) => (props.isFolder ? "15px" : "16px")}; + margin-right: ${(props) => (props.isFolder ? "7px" : "8px")}; } - .styled-content { - padding-left: 10px; - - padding-left: ${(props) => - isMobile - ? css` - ${props.isFolder ? "8px" : "12px"}; - ` - : css` - ${props.isFolder ? "10px" : "13px"} - `}; + .tile-folder-loader { + padding-top: 4px; } :hover { ${(props) => !props.dragging && props.isDesktop && + !props.inProgress && css` .checkbox { opacity: 1; @@ -193,41 +118,40 @@ const StyledTile = styled.div` `; const StyledFileTileTop = styled.div` - ${FlexBoxStyles} + ${FlexBoxStyles}; justify-content: space-between; align-items: baseline; - background-color: #f8f9f9; - padding-top: 21px; - height: ${(props) => (props.checked || props.isActive ? "156px" : "156px")}; + height: 156px; position: relative; - border-bottom: ${(props) => - props.checked || props.isActive - ? "1px solid #D0D5DA" - : "1px solid transparent"}; - .thumbnail-image, - .temporary-icon > .injected-svg { + .thumbnail-image { pointer-events: none; position: absolute; - left: 0; - right: 0; - bottom: 0; - margin: auto; + height: 100%; + width: 100%; + object-fit: cover; + border-radius: 6px 6px 0 0; z-index: 0; - - min-width: 208px; } .temporary-icon > .injected-svg { - margin-bottom: 16px; + position: absolute; + width: 100%; + bottom: 16px; } `; const StyledFileTileBottom = styled.div` - ${FlexBoxStyles} - padding: 9px 10px; - padding-right: 0; - height: 56px; + ${FlexBoxStyles}; + ${(props) => + !props.isEdit && (props.checked || props.isActive) && checkedStyle} + + border-top: 1px solid transparent; + ${(props) => + !props.isEdit && (props.checked || props.isActive) && bottomFileBorder} + + padding: 9px 0; + height: 62px; box-sizing: border-box; `; @@ -241,13 +165,13 @@ const StyledContent = styled.div` max-width: 400px; height: auto; margin: 0 auto; - font-size: 15px; line-height: 19px; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; white-space: normal; + word-break: break-word; } @media (max-width: 1024px) { @@ -272,10 +196,60 @@ const StyledOptionButton = styled.div` display: block; .expandButton > div:first-child { - padding-top: 8px; - padding-bottom: 8px; - padding-left: 12px; - padding-right: 13px; + padding: 8px 21px 8px 12px; + } +`; + +const badgesPosition = css` + left: 9px; + + .badges { + display: grid; + grid-template-columns: repeat(3, fit-content(50px)); + grid-template-rows: 32px; + grid-gap: 7px; + + .badge-new-version { + order: 1; + } + + .badge-version-current { + order: 2; + } + + .is-editing, + .can-convert { + order: 3; + } + } +`; + +const quickButtonsPosition = css` + right: 9px; + + .badges { + display: grid; + grid-template-columns: 32px; + grid-template-rows: repeat(3, 32px); + grid-gap: 7px; + } +`; + +const StyledIcons = styled.div` + position: absolute; + top: 8px; + + ${(props) => props.isBadges && badgesPosition} + ${(props) => props.isQuickButtons && quickButtonsPosition} + + .badge { + display: flex; + align-items: center; + justify-content: center; + padding: 8px; + background: rgb(255, 255, 255); + border-radius: 4px; + box-shadow: 0px 2px 4px rgba(4, 15, 27, 0.16); } `; @@ -344,19 +318,21 @@ class Tile extends React.PureComponent { isRecycleBin, item, isActive, + inProgress, isEdit, + contentElement, title, } = this.props; const { isFolder, id, fileExst } = item; - const renderCheckbox = Object.prototype.hasOwnProperty.call( + const renderElement = Object.prototype.hasOwnProperty.call( this.props, - "checked" + "element" ); - const renderElement = Object.prototype.hasOwnProperty.call( + const renderContentElement = Object.prototype.hasOwnProperty.call( this.props, - "element" + "contentElement" ); const renderContext = @@ -377,6 +353,8 @@ class Tile extends React.PureComponent { }; const icon = this.getIconFile(); + const [FilesTileContent, badges] = children; + const quickButtons = contentElement; return ( {isFolder || (!fileExst && id === -1) ? ( <> {renderElement && !(!fileExst && id === -1) && !isEdit && ( -
- - {element} - - -
+ <> + {!inProgress ? ( +
+ + {element} + + + +
+ ) : ( + + )} + )} - {children} + {FilesTileContent} {renderContext ? ( @@ -427,9 +416,9 @@ class Tile extends React.PureComponent { title={title} /> ) : ( -
+
)} - + ) : ( @@ -437,25 +426,37 @@ class Tile extends React.PureComponent { {icon} - + + {badges} + + {renderContentElement && ( + {quickButtons} + )} + + {id !== -1 && !isEdit && ( -
-
- {element} + <> +
+
+ {element} +
+
- -
+ )} - {children} + {FilesTileContent} {renderContext ? ( @@ -470,9 +471,9 @@ class Tile extends React.PureComponent { title={title} /> ) : ( -
+
)} - + @@ -484,7 +485,10 @@ class Tile extends React.PureComponent { Tile.propTypes = { checked: PropTypes.bool, - children: PropTypes.element, + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.element), + PropTypes.element, + ]), className: PropTypes.string, contextButtonSpacerWidth: PropTypes.string, contextOptions: PropTypes.array, @@ -497,6 +501,7 @@ Tile.propTypes = { style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), viewAs: PropTypes.string, tileContextClick: PropTypes.func, + contentElement: PropTypes.element, }; Tile.defaultProps = { diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js index d832ecf2c77..c4ba860e5ba 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js @@ -20,35 +20,21 @@ const paddingCss = css` } `; -const foldersStyle = css` - grid-gap: 19px 16px; - - ${paddingCss} - - @media ${tablet} { - grid-gap: 17px 12px; - } -`; +const StyledGridWrapper = styled.div` + display: grid; + grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); + width: 100%; + margin-bottom: ${(props) => (props.isFolders ? "23px" : 0)}; + box-sizing: border-box; + ${paddingCss}; -const filesStyle = css` grid-gap: 14px 16px; - ${paddingCss} - @media ${tablet} { - grid-gap: 12px; + grid-gap: 14px; } `; -const StyledGridWrapper = styled.div` - display: grid; - grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); - width: 100%; - padding-bottom: 24px; - box-sizing: border-box; - ${(props) => (props.isFolders ? foldersStyle : filesStyle)}; -`; - const StyledTileContainer = styled.div` position: relative; @@ -66,12 +52,8 @@ const StyledTileContainer = styled.div` .tile-items-heading { margin: 0; - padding-bottom: 11px; + margin-bottom: 15px; pointer-events: none; - - &.files { - padding-top: 8px; - } } @media ${tablet} { @@ -105,11 +87,11 @@ class TileContainer extends React.PureComponent { } renderFolders = () => { - return
; + return
; }; renderFiles = () => { - return
; + return
; }; // eslint-disable-next-line react/prop-types @@ -209,9 +191,11 @@ class TileContainer extends React.PureComponent { {Files.length > 0 && ( <> - - {headingFiles} - + {Folders.length > 0 && ( + + {headingFiles} + + )} {useReactWindow ? ( {renderList} ) : ( diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContent.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContent.js index 4f8bebc5d65..490e82530bc 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContent.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContent.js @@ -19,15 +19,6 @@ const commonCss = css` const StyledTileContent = styled.div` width: 100%; display: inline-flex; - - ${(props) => - !props.disableSideInfo && - css` - @media (max-width: 1024px) { - display: block; - height: 56px; - } - `}; `; const MainContainerWrapper = styled.div` @@ -36,161 +27,31 @@ const MainContainerWrapper = styled.div` display: flex; align-self: center; margin-right: auto; - - ${(props) => - !props.disableSideInfo && - css` - @media (max-width: 1024px) { - margin-right: 8px; - margin-top: 8px; - } - `}; `; const MainContainer = styled.div` height: 20px; - .badge-ext { - margin: 0px !important; - } - @media (max-width: 1024px) { ${truncateCss}; } `; -const MainIcons = styled.div` - align-self: center; - white-space: nowrap; - .badges { - margin-right: 4px; - } - - .additional-badges { - position: absolute; - top: 1px; - right: 2px; - display: flex; - flex-direction: row; - - .icons-group { - margin-top: 10px; - margin-right: 3px; - } - } -`; - -const SideContainerWrapper = styled.div` - ${commonCss}; - - @media (max-width: 1024px) { - ${truncateCss}; - } - - align-self: center; - align-items: center; - - > a { - vertical-align: middle; - } - - color: ${(props) => props.color && props.color}; - - ${(props) => - !props.disableSideInfo && - css` - @media (max-width: 1024px) { - display: none; - } - `}; -`; - -const TabletSideInfo = styled.div` - display: none; - - @media (max-width: 1024px) { - display: block; - color: ${(props) => props.color && props.color}; - - ${commonCss}; - ${truncateCss}; - } -`; - -const getSideInfo = (content) => { - let info = ""; - const lastIndex = content.length - 1; - - content.forEach((element, index) => { - if (element) { - const delimiter = index === lastIndex ? "" : " | "; - if (index > 1) { - info += - element.props && element.props.children - ? element.props.children + delimiter - : ""; - } - } - }); - - return info; -}; - const TileContent = (props) => { - //console.log("TileContent render"); - const { - children, - disableSideInfo, - id, - className, - style, - sideColor, - onClick, - badges, - } = props; - - const sideInfo = getSideInfo(children); + const { children, id, className, style, onClick } = props; return ( - {badges} - - {children[0]} - - {children[1]} + {children} - {children.map((element, index) => { - if (index > 1 && element) { - return ( - - {element} - - ); - } - return null; - })} - {!disableSideInfo && ( - {sideInfo} - )} ); }; @@ -198,15 +59,10 @@ const TileContent = (props) => { TileContent.propTypes = { children: PropTypes.node.isRequired, className: PropTypes.string, - disableSideInfo: PropTypes.bool, id: PropTypes.string, onClick: PropTypes.func, sideColor: PropTypes.string, style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), }; -TileContent.defaultProps = { - disableSideInfo: false, -}; - export default TileContent; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/index.js index 0f1e66ceb07..4efa962c000 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/index.js @@ -230,8 +230,6 @@ export default inject( fileActionId: fileActionStore.id, isEmptyFilesList, setDragging, - startDrag, - setStartDrag, folderId: selectedFolderStore.id, setTooltipPosition, isRecycleBinFolder: treeFoldersStore.isRecycleBinFolder, diff --git a/products/ASC.Files/Client/src/pages/Home/index.js b/products/ASC.Files/Client/src/pages/Home/index.js index d3a203b7b38..a7d4b36c4aa 100644 --- a/products/ASC.Files/Client/src/pages/Home/index.js +++ b/products/ASC.Files/Client/src/pages/Home/index.js @@ -291,7 +291,6 @@ class PureHome extends React.Component { isHeaderVisible={isHeaderVisible} onOpenUploadPanel={this.showUploadPanel} firstLoad={firstLoad} - dragging={dragging} > diff --git a/public/images/file.actions.share.react.svg b/public/images/file.actions.share.react.svg new file mode 100644 index 00000000000..14185852a78 --- /dev/null +++ b/public/images/file.actions.share.react.svg @@ -0,0 +1,3 @@ + + +