Client: moved new logic from ItemIcon to RoomIcon

This commit is contained in:
Dmitry Sychugov 2024-09-02 20:01:54 +05:00
parent e8fb4f81b2
commit 7d70e4892a
7 changed files with 174 additions and 76 deletions

View File

@ -31,13 +31,8 @@ import styled, { css } from "styled-components";
import { Base } from "@docspace/shared/themes"; import { Base } from "@docspace/shared/themes";
import { NoUserSelect } from "@docspace/shared/utils"; import { NoUserSelect } from "@docspace/shared/utils";
import { RoomIcon } from "@docspace/shared/components/room-icon"; import { RoomIcon } from "@docspace/shared/components/room-icon";
import { IconButton } from "@docspace/shared/components/icon-button";
import { DropDown } from "@docspace/shared/components/drop-down";
import { DropDownItem } from "@docspace/shared/components/drop-down-item";
import EditPenSvgUrl from "PUBLIC_DIR/images/icons/12/pen-edit.react.svg?url"; import EditPenSvgUrl from "PUBLIC_DIR/images/icons/12/pen-edit.react.svg?url";
import PenSvgUrl from "PUBLIC_DIR/images/pencil.react.svg?url";
import UploadPenSvgUrl from "PUBLIC_DIR/images/actions.upload.react.svg?url";
const IconWrapper = styled.div` const IconWrapper = styled.div`
${(props) => ${(props) =>
@ -68,25 +63,6 @@ const IconWrapper = styled.div`
} }
`; `;
const EditWrapper = styled.div`
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
background-color: ${(props) => props.theme.itemIcon.editIconColor};
border-radius: 50%;
position: absolute;
bottom: -6px;
right: -6px;
.open-edit-logo-icon {
&:hover {
cursor: pointer;
}
}
`;
IconWrapper.defaultProps = { theme: Base }; IconWrapper.defaultProps = { theme: Base };
const EncryptedFileIcon = styled.div` const EncryptedFileIcon = styled.div`
@ -110,26 +86,13 @@ const ItemIcon = ({
badgeUrl, badgeUrl,
size, size,
withEditing, withEditing,
setRoomLogoCoverDialogVisible,
showDefault, showDefault,
imgClassName, imgClassName,
model,
}) => { }) => {
const isLoadedRoomIcon = !!logo?.medium; const isLoadedRoomIcon = !!logo?.medium;
const showDefaultRoomIcon = !isLoadedRoomIcon && isRoom; const showDefaultRoomIcon = !isLoadedRoomIcon && isRoom;
const [editLogoOpen, setEditLogoOpen] = useState(false);
const toggleEditLogo = () => {
setEditLogoOpen(!editLogoOpen);
};
const closeEditLogo = () => {
setEditLogoOpen(false);
};
const openCustomizeCover = () => {
setRoomLogoCoverDialogVisible(true);
closeEditLogo();
};
return ( return (
<> <>
<IconWrapper isRoom={isRoom}> <IconWrapper isRoom={isRoom}>
@ -142,45 +105,15 @@ const ItemIcon = ({
imgClassName={imgClassName || "react-svg-icon"} imgClassName={imgClassName || "react-svg-icon"}
imgSrc={isRoom ? logo?.medium : icon} imgSrc={isRoom ? logo?.medium : icon}
badgeUrl={badgeUrl ? badgeUrl : ""} badgeUrl={badgeUrl ? badgeUrl : ""}
withEditing={withEditing}
model={model}
/> />
{withEditing && (
<EditWrapper>
<IconButton
className="open-edit-logo-icon"
size={12}
iconName={EditPenSvgUrl}
onClick={toggleEditLogo}
isFill
/>
<DropDown
open={editLogoOpen}
clickOutsideAction={closeEditLogo}
withBackdrop={false}
isDefaultMode={false}
fixedDirection={true}
>
<DropDownItem
label={`Upload picture`}
icon={UploadPenSvgUrl}
// onClick={() => shareEmail(activeLink[0])}
/>
<DropDownItem
label={`Customize cover`}
icon={PenSvgUrl}
onClick={openCustomizeCover}
/>
</DropDown>
</EditWrapper>
)}
</IconWrapper> </IconWrapper>
{isPrivacy && fileExst && <EncryptedFileIcon isEdit={false} />} {isPrivacy && fileExst && <EncryptedFileIcon isEdit={false} />}
</> </>
); );
}; };
export default inject(({ treeFoldersStore, dialogsStore }) => { export default inject(({ treeFoldersStore }) => {
return { return { isPrivacy: treeFoldersStore.isPrivacyFolder };
isPrivacy: treeFoldersStore.isPrivacyFolder,
setRoomLogoCoverDialogVisible: dialogsStore.setRoomLogoCoverDialogVisible,
};
})(observer(ItemIcon)); })(observer(ItemIcon));

View File

@ -44,6 +44,9 @@ import { ImageEditor } from "@docspace/shared/components/image-editor";
import PreviewTile from "@docspace/shared/components/image-editor/PreviewTile"; import PreviewTile from "@docspace/shared/components/image-editor/PreviewTile";
import { Text } from "@docspace/shared/components/text"; import { Text } from "@docspace/shared/components/text";
import PenSvgUrl from "PUBLIC_DIR/images/pencil.react.svg?url";
import UploadPenSvgUrl from "PUBLIC_DIR/images/actions.upload.react.svg?url";
import ItemIcon from "@docspace/client/src/components/ItemIcon"; import ItemIcon from "@docspace/client/src/components/ItemIcon";
import ChangeRoomOwner from "./ChangeRoomOwner"; import ChangeRoomOwner from "./ChangeRoomOwner";
@ -131,6 +134,7 @@ const SetRoomParams = ({
disabledChangeRoomType, disabledChangeRoomType,
maxImageUploadSize, maxImageUploadSize,
bufferSelection, bufferSelection,
setRoomLogoCoverDialogVisible,
}) => { }) => {
const [previewIcon, setPreviewIcon] = useState(null); const [previewIcon, setPreviewIcon] = useState(null);
const [createNewFolderIsChecked, setCreateNewFolderIsChecked] = const [createNewFolderIsChecked, setCreateNewFolderIsChecked] =
@ -180,6 +184,18 @@ const SetRoomParams = ({
...{ createAsNewFolder: !createNewFolderIsChecked }, ...{ createAsNewFolder: !createNewFolderIsChecked },
}); });
}; };
const model = [
{
label: "UploadPicture",
icon: UploadPenSvgUrl,
onClick: () => {},
},
{
label: "CustomizeCover",
icon: PenSvgUrl,
onClick: () => setRoomLogoCoverDialogVisible(true),
},
];
const element = ( const element = (
<ItemIcon <ItemIcon
@ -191,6 +207,7 @@ const SetRoomParams = ({
color={bufferSelection.logo?.color} color={bufferSelection.logo?.color}
size={isMobile() ? "96px" : "64px"} size={isMobile() ? "96px" : "64px"}
withEditing={true} withEditing={true}
model={model}
/> />
); );
@ -324,7 +341,8 @@ export default inject(
const { bufferSelection } = filesStore; const { bufferSelection } = filesStore;
const { setChangeRoomOwnerIsVisible } = dialogsStore; const { setChangeRoomOwnerIsVisible, setRoomLogoCoverDialogVisible } =
dialogsStore;
const { folderFormValidation, maxImageUploadSize } = settingsStore; const { folderFormValidation, maxImageUploadSize } = settingsStore;
return { return {
@ -333,6 +351,7 @@ export default inject(
setChangeRoomOwnerIsVisible, setChangeRoomOwnerIsVisible,
maxImageUploadSize, maxImageUploadSize,
bufferSelection, bufferSelection,
setRoomLogoCoverDialogVisible,
}; };
}, },
)( )(

View File

@ -31,6 +31,7 @@ import { Text } from "@docspace/shared/components/text";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import PersonPlusReactSvgUrl from "PUBLIC_DIR/images/person+.react.svg?url"; import PersonPlusReactSvgUrl from "PUBLIC_DIR/images/person+.react.svg?url";
import Planet12ReactSvgUrl from "PUBLIC_DIR/images/icons/12/planet.react.svg?url"; import Planet12ReactSvgUrl from "PUBLIC_DIR/images/icons/12/planet.react.svg?url";
import Camera10ReactSvgUrl from "PUBLIC_DIR/images/icons/10/cover.camera.react.svg?url";
import SearchIconReactSvgUrl from "PUBLIC_DIR/images/search.react.svg?url"; import SearchIconReactSvgUrl from "PUBLIC_DIR/images/search.react.svg?url";
import { IconButton } from "@docspace/shared/components/icon-button"; import { IconButton } from "@docspace/shared/components/icon-button";
import { StyledTitle } from "../../../styles/common"; import { StyledTitle } from "../../../styles/common";
@ -113,6 +114,7 @@ const RoomsItemHeader = ({
imgClassName={`icon ${selection.isRoom && "is-room"}`} imgClassName={`icon ${selection.isRoom && "is-room"}`}
imgSrc={icon} imgSrc={icon}
badgeUrl={badgeUrl ? badgeUrl : ""} badgeUrl={badgeUrl ? badgeUrl : ""}
hoverSrc={Camera10ReactSvgUrl}
/> />
</div> </div>

View File

@ -1,12 +1,13 @@
import styled, { css } from "styled-components"; import styled, { css } from "styled-components";
import { Base } from "../../themes"; import { Base } from "../../themes";
export const StyledIcon = styled.div<{ const StyledIcon = styled.div<{
size: string; size: string;
radius: string; radius: string;
isArchive?: boolean; isArchive?: boolean;
color?: string; color?: string;
wrongImage: boolean; wrongImage: boolean;
withHover: boolean;
}>` }>`
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -35,6 +36,9 @@ export const StyledIcon = styled.div<{
font-size: 14px; font-size: 14px;
font-weight: 700; font-weight: 700;
line-height: 16px; line-height: 16px;
transition: all 0.2s ease;
opacity: 1;
transform: translateY(0);
color: ${(props) => color: ${(props) =>
props.wrongImage && props.theme.isBase ? "#333333" : "#ffffff"}; props.wrongImage && props.theme.isBase ? "#333333" : "#ffffff"};
position: relative; position: relative;
@ -67,6 +71,56 @@ export const StyledIcon = styled.div<{
} }
} }
} }
.room-icon_hover {
position: absolute;
opacity: 0;
transform: translateY(20px);
transition: all 0.2s ease;
}
${(props) =>
props.withHover &&
css`
cursor: pointer;
&:hover {
.hover-class {
filter: brightness(80%);
}
.room-icon_hover {
opacity: 1;
transform: translateY(0px);
}
.room-title {
opacity: 0;
transform: translateY(-20px);
}
}
`}
`; `;
StyledIcon.defaultProps = { theme: Base }; StyledIcon.defaultProps = { theme: Base };
const EditWrapper = styled.div`
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
background-color: ${(props) => props.theme.itemIcon.editIconColor};
border-radius: 50%;
position: absolute;
bottom: -6px;
right: -6px;
.open-edit-logo-icon {
&:hover {
cursor: pointer;
}
}
`;
export { StyledIcon, EditWrapper };

View File

@ -6,6 +6,8 @@ type RoomIconDefault = {
showDefault: boolean; showDefault: boolean;
imgClassName?: string; imgClassName?: string;
className?: string; className?: string;
hoverSrc?: string;
withEditing?: boolean;
}; };
type RoomIconColor = { type RoomIconColor = {

View File

@ -27,6 +27,7 @@
import React, { useMemo } from "react"; import React, { useMemo } from "react";
import { Text } from "../text"; import { Text } from "../text";
import EditIcon from "./sub-components/EditIcon";
import { IconButton } from "../icon-button"; import { IconButton } from "../icon-button";
import { classNames } from "../../utils"; import { classNames } from "../../utils";
@ -48,6 +49,9 @@ const RoomIcon = ({
badgeUrl, badgeUrl,
onBadgeClick, onBadgeClick,
className, className,
withEditing,
hoverSrc,
model,
}: RoomIconProps) => { }: RoomIconProps) => {
const [correctImage, setCorrectImage] = React.useState(true); const [correctImage, setCorrectImage] = React.useState(true);
@ -77,19 +81,27 @@ const RoomIcon = ({
wrongImage={!correctImage} wrongImage={!correctImage}
className={className} className={className}
data-testid="room-icon" data-testid="room-icon"
withHover={!!hoverSrc}
> >
{showDefault || !correctImage ? ( {showDefault || !correctImage ? (
<> <>
<div className="room-background" /> <div className="room-background hover-class" />
<Text className="room-title">{roomTitle}</Text> <Text className="room-title">{roomTitle}</Text>
</> </>
) : ( ) : (
<img <img
className={classNames([imgClassName, "not-selectable"])} className={classNames([
imgClassName,
"hover-class",
"not-selectable",
])}
src={imgSrc} src={imgSrc}
alt="room icon" alt="room icon"
/> />
)} )}
{hoverSrc && (
<img className="room-icon_hover" src={hoverSrc} alt="room icon" />
)}
{badgeUrl && ( {badgeUrl && (
<div className="room-icon_badge"> <div className="room-icon_badge">
@ -102,6 +114,7 @@ const RoomIcon = ({
/> />
</div> </div>
)} )}
{withEditing && <EditIcon model={model} />}
</StyledIcon> </StyledIcon>
); );
}; };

View File

@ -0,0 +1,75 @@
// (c) Copyright Ascensio System SIA 2009-2024
//
// This program is a free software product.
// You can redistribute it and/or modify it under the terms
// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software
// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended
// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of
// any third-party rights.
//
// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see
// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
//
// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021.
//
// The interactive user interfaces in modified source and object code versions of the Program must
// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3.
//
// Pursuant to Section 7(b) of the License you must retain the original Product logo when
// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under
// trademark law for use of our trademarks.
//
// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
import React from "react";
import { DropDown } from "@docspace/shared/components/drop-down";
import { DropDownItem } from "@docspace/shared/components/drop-down-item";
import EditPenSvgUrl from "PUBLIC_DIR/images/icons/12/pen-edit.react.svg?url";
import { IconButton } from "../../icon-button";
import { EditWrapper } from "../RoomIcon.styled";
const EditIcon = ({ model }) => {
const [openEditLogo, setOpenLogoEdit] = React.useState<boolean>(false);
const onToggleOpenEditLogo = () => setOpenLogoEdit(!openEditLogo);
return (
<EditWrapper>
<IconButton
className="open-edit-logo-icon"
size={12}
iconName={EditPenSvgUrl}
onClick={onToggleOpenEditLogo}
isFill
/>
<DropDown
open={openEditLogo}
clickOutsideAction={() => setOpenLogoEdit(false)}
withBackdrop={false}
isDefaultMode={false}
>
{model?.map((option, i) => {
const optionOnClickAction = () => {
setOpenLogoEdit(false);
option.onClick();
};
return (
<DropDownItem
key={i}
label={option.label}
icon={option.icon}
onClick={optionOnClickAction}
/>
);
})}
</DropDown>
</EditWrapper>
);
};
export default EditIcon;