Web: Templates: Added room creation from a template
This commit is contained in:
parent
63f17aa4c8
commit
51dacad300
@ -34,6 +34,8 @@ import TagHandler from "./handlers/TagHandler";
|
||||
import SetRoomParams from "./sub-components/SetRoomParams";
|
||||
import RoomTypeList from "./sub-components/RoomTypeList";
|
||||
import DialogHeader from "./sub-components/DialogHeader";
|
||||
import TemplateBody from "./sub-components/TemplateBody";
|
||||
import { RoomsType } from "@docspace/shared/enums";
|
||||
|
||||
const StyledModalDialog = styled(ModalDialog)`
|
||||
.header-with-button {
|
||||
@ -55,6 +57,19 @@ const StyledModalDialog = styled(ModalDialog)`
|
||||
display: none;
|
||||
}
|
||||
`}
|
||||
|
||||
${({ isTemplate }) =>
|
||||
isTemplate &&
|
||||
css`
|
||||
.selector_body,
|
||||
.modal-body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.selector_body {
|
||||
height: 100%;
|
||||
}
|
||||
`}
|
||||
`;
|
||||
|
||||
const CreateRoomDialog = ({
|
||||
@ -106,6 +121,7 @@ const CreateRoomDialog = ({
|
||||
|
||||
const [roomParams, setRoomParams] = useState({ ...startRoomParams });
|
||||
const [isValidTitle, setIsValidTitle] = useState(true);
|
||||
const [isTemplateSelected, setIsTemplateSelected] = useState(false);
|
||||
|
||||
const setRoomTags = (newTags) =>
|
||||
setRoomParams({ ...roomParams, tags: newTags });
|
||||
@ -143,6 +159,15 @@ const CreateRoomDialog = ({
|
||||
|
||||
const goBack = () => {
|
||||
if (isLoading) return;
|
||||
if (isTemplateSelected) {
|
||||
setIsTemplateSelected(false);
|
||||
setRoomParams((prev) => ({
|
||||
...prev,
|
||||
title: "",
|
||||
type: RoomsType.TemplateRoom,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
setRoomParams({ ...startRoomParams });
|
||||
};
|
||||
|
||||
@ -160,29 +185,42 @@ const CreateRoomDialog = ({
|
||||
onClose();
|
||||
};
|
||||
|
||||
const isTemplate =
|
||||
roomParams.type === RoomsType.TemplateRoom && !isTemplateSelected;
|
||||
|
||||
return (
|
||||
<StyledModalDialog
|
||||
displayType="aside"
|
||||
withBodyScroll
|
||||
withBodyScroll={!isTemplate}
|
||||
visible={visible}
|
||||
onClose={onCloseAndDisconnectThirdparty}
|
||||
isScrollLocked={isScrollLocked}
|
||||
withFooterBorder
|
||||
isOauthWindowOpen={isOauthWindowOpen}
|
||||
isTemplate={isTemplate}
|
||||
>
|
||||
<ModalDialog.Header>
|
||||
<DialogHeader
|
||||
isChooseRoomType={!roomParams.type}
|
||||
onArrowClick={goBack}
|
||||
isTemplate={isTemplate}
|
||||
isTemplateSelected={isTemplateSelected}
|
||||
/>
|
||||
</ModalDialog.Header>
|
||||
|
||||
<ModalDialog.Body>
|
||||
{!roomParams.type ? (
|
||||
<RoomTypeList t={t} setRoomType={setRoomType} />
|
||||
) : isTemplate ? (
|
||||
<TemplateBody
|
||||
t={t}
|
||||
setIsTemplateSelected={setIsTemplateSelected}
|
||||
setRoomParams={setRoomParams}
|
||||
/>
|
||||
) : (
|
||||
<SetRoomParams
|
||||
t={t}
|
||||
isTemplateSelected={isTemplateSelected}
|
||||
setIsOauthWindowOpen={setIsOauthWindowOpen}
|
||||
tagHandler={tagHandler}
|
||||
roomParams={roomParams}
|
||||
@ -200,7 +238,7 @@ const CreateRoomDialog = ({
|
||||
)}
|
||||
</ModalDialog.Body>
|
||||
|
||||
{!!roomParams.type && (
|
||||
{!!roomParams.type && !isTemplate && (
|
||||
<ModalDialog.Footer>
|
||||
<Button
|
||||
id="shared_create-room-modal_submit"
|
||||
|
@ -38,45 +38,48 @@ const ChangeRoomOwner = ({
|
||||
roomOwner,
|
||||
onOwnerChange,
|
||||
currentColorScheme,
|
||||
isTemplate,
|
||||
}) => {
|
||||
const userName = roomOwner.displayName ?? roomOwner.label;
|
||||
|
||||
return (
|
||||
<Styled.ChangeRoomOwner>
|
||||
<Styled.ChangeRoomOwner isTemplate={isTemplate}>
|
||||
<Text className="change-owner-label" fontWeight={600} fontSize="13px">
|
||||
{t("Files:RoomOwner")}
|
||||
{isTemplate ? `${t("Files:AccessToTemplate")}:` : t("Files:RoomOwner")}
|
||||
</Text>
|
||||
|
||||
<div className="change-owner-display">
|
||||
<Avatar
|
||||
className={"change-owner-display-avatar"}
|
||||
size="min"
|
||||
role={""}
|
||||
isDefaultSource={roomOwner.hasAvatar}
|
||||
source={roomOwner.avatarSmall ?? roomOwner.avatar}
|
||||
userName={userName}
|
||||
/>
|
||||
<div className="change-owner-display-name">
|
||||
<Text fontWeight={600} fontSize="13px">
|
||||
{userName}
|
||||
</Text>
|
||||
{roomOwner.id === currentUserId && (
|
||||
<Text className="me-label">({t("Common:MeLabel")})</Text>
|
||||
)}
|
||||
<div className="change-owner-display-wrapper">
|
||||
<div className="change-owner-display">
|
||||
<Avatar
|
||||
className={"change-owner-display-avatar"}
|
||||
size="base"
|
||||
role={""}
|
||||
isDefaultSource={roomOwner.hasAvatar}
|
||||
source={roomOwner.avatarSmall ?? roomOwner.avatar}
|
||||
userName={userName}
|
||||
/>
|
||||
<div className="change-owner-display-name">
|
||||
<Text fontWeight={600} fontSize="13px">
|
||||
{userName}
|
||||
</Text>
|
||||
{roomOwner.id === currentUserId && (
|
||||
<Text className="me-label">({t("Common:MeLabel")})</Text>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Link
|
||||
className="change-owner-link"
|
||||
isHovered
|
||||
type="action"
|
||||
fontWeight={600}
|
||||
fontSize="13px"
|
||||
color={currentColorScheme.main?.accent}
|
||||
onClick={onOwnerChange}
|
||||
>
|
||||
{t("Common:ChangeButton")}
|
||||
</Link>
|
||||
<Link
|
||||
className="change-owner-link"
|
||||
isHovered
|
||||
type="action"
|
||||
fontWeight={600}
|
||||
fontSize="13px"
|
||||
color={isTemplate ? null : currentColorScheme.main?.accent}
|
||||
onClick={onOwnerChange}
|
||||
>
|
||||
{isTemplate ? t("Files:AccessSettings") : t("Common:ChangeButton")}
|
||||
</Link>
|
||||
</div>
|
||||
</Styled.ChangeRoomOwner>
|
||||
);
|
||||
};
|
||||
|
@ -44,6 +44,15 @@ export const ChangeRoomOwner = styled.div`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.change-owner-display-wrapper {
|
||||
display: ${(props) => (props.isTemplate ? "flex" : "block")};
|
||||
align-items: center;
|
||||
|
||||
.change-owner-link {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
ChangeRoomOwner.defaultProps = { theme: Base };
|
||||
|
@ -32,7 +32,20 @@ import withLoader from "@docspace/client/src/HOCs/withLoader";
|
||||
import { IconButton } from "@docspace/shared/components/icon-button";
|
||||
import CreateEditRoomDilogHeaderLoader from "@docspace/shared/skeletons/create-edit-room/DilogHeader";
|
||||
|
||||
const DialogHeader = ({ t, isEdit, isChooseRoomType, onArrowClick }) => {
|
||||
const DialogHeader = ({
|
||||
t,
|
||||
isEdit,
|
||||
isChooseRoomType,
|
||||
onArrowClick,
|
||||
isTemplate,
|
||||
isTemplateSelected,
|
||||
}) => {
|
||||
const title = isTemplateSelected
|
||||
? t("Files:SaveAsTemplate")
|
||||
: isTemplate
|
||||
? t("Files:FromTemplate")
|
||||
: t("Files:CreateRoom");
|
||||
|
||||
return (
|
||||
<>
|
||||
{isEdit ? (
|
||||
@ -47,7 +60,7 @@ const DialogHeader = ({ t, isEdit, isChooseRoomType, onArrowClick }) => {
|
||||
className="sharing_panel-arrow"
|
||||
onClick={onArrowClick}
|
||||
/>
|
||||
<div>{t("Files:CreateRoom")}</div>
|
||||
<div>{title}</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
@ -31,14 +31,23 @@ import { StyledParam } from "./StyledParam";
|
||||
import { FieldContainer } from "@docspace/shared/components/field-container";
|
||||
import { Label } from "@docspace/shared/components/label";
|
||||
import { TextInput } from "@docspace/shared/components/text-input";
|
||||
import { HelpButton } from "@docspace/shared/components/help-button";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
|
||||
const StyledInputParam = styled(StyledParam)`
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
max-height: 54px;
|
||||
|
||||
.input-label {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
.input-label-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
||||
.input-label {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@ -59,18 +68,31 @@ const InputParam = React.forwardRef(
|
||||
isAutoFocussed,
|
||||
onKeyUp,
|
||||
onKeyDown,
|
||||
tooltipLabel,
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
return (
|
||||
<StyledInputParam>
|
||||
<Label
|
||||
title={title}
|
||||
className="input-label"
|
||||
display="display"
|
||||
htmlFor={id}
|
||||
text={title}
|
||||
/>
|
||||
<div className="input-label-wrapper">
|
||||
<Label
|
||||
title={title}
|
||||
className="input-label"
|
||||
display="display"
|
||||
htmlFor={id}
|
||||
text={title}
|
||||
/>
|
||||
{tooltipLabel && (
|
||||
<HelpButton
|
||||
place="right"
|
||||
tooltipContent={
|
||||
<Text fontSize="12px" fontWeight={400}>
|
||||
{tooltipLabel}
|
||||
</Text>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<FieldContainer
|
||||
isVertical={true}
|
||||
|
@ -37,6 +37,8 @@ import {
|
||||
getRoomTypeDescriptionTranslation,
|
||||
getRoomTypeTitleTranslation,
|
||||
} from "./../data/index";
|
||||
import { RoomsType } from "@docspace/shared/enums";
|
||||
import { Badge } from "@docspace/shared/components/badge";
|
||||
|
||||
const StyledRoomType = styled.div`
|
||||
cursor: pointer;
|
||||
@ -185,6 +187,8 @@ const RoomType = ({
|
||||
description: getRoomTypeDescriptionTranslation(roomType, t),
|
||||
};
|
||||
|
||||
const isTemplate = roomType === RoomsType.TemplateRoom;
|
||||
|
||||
const arrowClassName =
|
||||
type === "dropdownButton"
|
||||
? "choose_room-forward_btn dropdown-button"
|
||||
@ -203,6 +207,17 @@ const RoomType = ({
|
||||
<Text noSelect className="choose_room-title-text">
|
||||
{t(room.title)}
|
||||
</Text>
|
||||
{isTemplate && (
|
||||
<Badge
|
||||
label={t("New").toUpperCase()}
|
||||
backgroundColor="#7757D9"
|
||||
fontSize="9px"
|
||||
fontWeight={700}
|
||||
borderRadius="50px"
|
||||
noHover
|
||||
isHovered={false}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<Text noSelect className="choose_room-description">
|
||||
{t(room.description)}
|
||||
|
@ -95,6 +95,7 @@ const SetRoomParams = ({
|
||||
currentColorScheme,
|
||||
setChangeRoomOwnerIsVisible,
|
||||
folderFormValidation,
|
||||
isTemplateSelected,
|
||||
}) => {
|
||||
const [previewIcon, setPreviewIcon] = useState(null);
|
||||
const [createNewFolderIsChecked, setCreateNewFolderIsChecked] =
|
||||
@ -147,7 +148,7 @@ const SetRoomParams = ({
|
||||
|
||||
return (
|
||||
<StyledSetRoomParams disableImageRescaling={disableImageRescaling}>
|
||||
{isEdit ? (
|
||||
{isEdit || isTemplateSelected ? (
|
||||
<RoomType t={t} roomType={roomParams.type} type="displayItem" />
|
||||
) : (
|
||||
<RoomTypeDropdown
|
||||
|
@ -54,9 +54,11 @@ const StyledTagInput = styled.div`
|
||||
|
||||
const TagInput = ({
|
||||
t,
|
||||
title,
|
||||
tagHandler,
|
||||
setIsScrollLocked,
|
||||
isDisabled,
|
||||
tooltipLabel,
|
||||
onFocus,
|
||||
onBlur,
|
||||
}) => {
|
||||
@ -119,7 +121,7 @@ const TagInput = ({
|
||||
<InputParam
|
||||
ref={inputRef}
|
||||
id="shared_tags-input"
|
||||
title={`${t("Common:Tags")}:`}
|
||||
title={title ? `${title}:` : `${t("Common:Tags")}:`}
|
||||
placeholder={t("TagsPlaceholder")}
|
||||
value={tagInput}
|
||||
onChange={onTagInputChange}
|
||||
@ -127,6 +129,7 @@ const TagInput = ({
|
||||
onBlur={handleBlur}
|
||||
isDisabled={isDisabled}
|
||||
onKeyDown={handleKeyDown}
|
||||
tooltipLabel={tooltipLabel}
|
||||
/>
|
||||
|
||||
<TagDropdown
|
||||
|
@ -0,0 +1,56 @@
|
||||
// (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 RoomSelector from "@docspace/shared/selectors/Room";
|
||||
import { RoomsType } from "@docspace/shared/enums";
|
||||
|
||||
const TemplateBody = ({ t, setIsTemplateSelected, setRoomParams }) => {
|
||||
const onSubmit = (item) => {
|
||||
console.log("onSubmit", item);
|
||||
setIsTemplateSelected(item[0]);
|
||||
|
||||
setRoomParams((prev) => ({
|
||||
...prev,
|
||||
title: item[0]?.label,
|
||||
type: item[0]?.roomType,
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<RoomSelector
|
||||
className="template-body_selector"
|
||||
onSubmit={onSubmit}
|
||||
roomType={RoomsType.TemplateRoom}
|
||||
isMultiSelect={false}
|
||||
withHeader={false}
|
||||
withSearch
|
||||
emptyScreenHeader={t("Common:EmptyTemplatesRoomsHeader")}
|
||||
emptyScreenDescription={t("Common:EmptyTemplatesRoomsDescription")}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default TemplateBody;
|
Loading…
Reference in New Issue
Block a user