Web: Added saving watermark information for text.

This commit is contained in:
Tatiana Lopaeva 2024-05-02 16:22:22 +03:00
parent b36b3e9648
commit c07d7218b3
8 changed files with 152 additions and 137 deletions

View File

@ -1,4 +1,6 @@
{ {
"AddWatermarkElements": "Add watermark elements",
"AddStaticText": "Add static text",
"Diagonal": "Diagonal", "Diagonal": "Diagonal",
"ChooseRoomType": "Choose room type", "ChooseRoomType": "Choose room type",
"CollaborationRoomDescription": "Collaborate on one or multiple documents with your team", "CollaborationRoomDescription": "Collaborate on one or multiple documents with your team",
@ -33,7 +35,6 @@
"RoomEditing": "Room editing", "RoomEditing": "Room editing",
"RootFolderLabel": "Root folder", "RootFolderLabel": "Root folder",
"StorageDescription": "Storage quota set per room. You can change this value or turn off storage limit.", "StorageDescription": "Storage quota set per room. You can change this value or turn off storage limit.",
"Semitransparent": "Semitransparent",
"TagsPlaceholder": "Add a tag", "TagsPlaceholder": "Add a tag",
"Text": "Text", "Text": "Text",
"ThirdPartyStorageComboBoxPlaceholder": "Select storage", "ThirdPartyStorageComboBoxPlaceholder": "Select storage",
@ -46,7 +47,6 @@
"UserIPAddress": "User IP Address", "UserIPAddress": "User IP Address",
"ViewOnlyRoomDescription": "Share any ready documents, reports, documentation, and other files for viewing.", "ViewOnlyRoomDescription": "Share any ready documents, reports, documentation, and other files for viewing.",
"ViewOnlyRoomTitle": "View-only room", "ViewOnlyRoomTitle": "View-only room",
"WatermarkElements": "Watermark elements",
"AutomaticIndexing": "Automatic indexing", "AutomaticIndexing": "Automatic indexing",
"AutomaticIndexingDescription": "Enable automatic indexing to index files and folders by serial number. Sorting by number will be set as default for all users.", "AutomaticIndexingDescription": "Enable automatic indexing to index files and folders by serial number. Sorting by number will be set as default for all users.",
"FileLifetime": "File lifetime", "FileLifetime": "File lifetime",

View File

@ -128,7 +128,7 @@ const VirtualDataRoomBlock = ({ t, roomParams, setRoomParams }) => {
isDisabled={false} isDisabled={false}
isChecked={watermarksChecked} isChecked={watermarksChecked}
> >
<Watermarks /> <Watermarks setRoomParams={setRoomParams} />
</Block> </Block>
</StyledVirtualDataRoomBlock> </StyledVirtualDataRoomBlock>
); );

View File

@ -1,90 +0,0 @@
// (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 { useState } from "react";
import { useTranslation } from "react-i18next";
import { TextInput } from "@docspace/shared/components/text-input";
import { ComboBox } from "@docspace/shared/components/combobox";
import { Text } from "@docspace/shared/components/text";
import { Checkbox } from "@docspace/shared/components/checkbox";
import { StyledWatermark } from "./StyledComponent";
const options = (t) => [
{ key: "diagonal", label: t("Diagonal") },
{ key: "horizontal", label: t("Horizontal") },
];
const TextWatermark = () => {
const { t } = useTranslation(["CreateEditRoomDialog", "Common"]);
const typesOptions = options(t);
const [value, setValue] = useState("");
const [isChecked, setIsChecked] = useState(true);
const [selectedOption, setSelectedOption] = useState(typesOptions[0]);
const onChange = (e) => {
const { value } = e.target;
setValue(value);
};
const onTypeChange = (item) => {
setSelectedOption(item);
};
const onCheckboxChange = () => {
setIsChecked(!isChecked);
};
return (
<StyledWatermark>
<div>
<TextInput
scale
value={value}
tabIndex={1}
isAutoFocussed
onChange={onChange}
/>
<Text className="watermark-title" fontWeight={600} lineHeight="20px">
{t("Position")}
</Text>
<ComboBox
selectedOption={selectedOption}
options={typesOptions}
onSelect={onTypeChange}
scaled
/>
<Checkbox
className="watermark-checkbox"
label={t("Semitransparent")}
onChange={onCheckboxChange}
isChecked={isChecked}
/>
</div>
</StyledWatermark>
);
};
export default TextWatermark;

View File

@ -29,25 +29,26 @@ import { useTranslation } from "react-i18next";
import { TabsContainer } from "@docspace/shared/components/tabs-container"; import { TabsContainer } from "@docspace/shared/components/tabs-container";
import { TextInput } from "@docspace/shared/components/text-input"; import { TextInput } from "@docspace/shared/components/text-input";
import { Text } from "@docspace/shared/components/text"; import { Text } from "@docspace/shared/components/text";
import { Checkbox } from "@docspace/shared/components/checkbox"; import { ComboBox } from "@docspace/shared/components/combobox";
import { StyledWatermark } from "./StyledComponent"; import { StyledWatermark } from "./StyledComponent";
import { WatermarkAdditions } from "@docspace/shared/enums";
const options = (t) => [ const options = (t) => [
{ {
key: "userName", key: "UserName",
title: t("UserName"), title: t("UserName"),
}, },
{ {
key: "userEmail", key: "UserEmail",
title: t("UserEmail"), title: t("UserEmail"),
}, },
{ {
key: "userIPAddress", key: "UserIpAdress",
title: t("UserIPAddress"), title: t("UserIPAddress"),
}, },
{ {
key: "currentDate", key: "CurrentDate",
title: t("Common:CurrentDate"), title: t("Common:CurrentDate"),
}, },
{ {
@ -55,52 +56,89 @@ const options = (t) => [
title: t("Common:RoomName"), title: t("Common:RoomName"),
}, },
]; ];
const ViewerInfoWatermark = () => {
const ViewerInfoWatermark = ({ setParams, initialPosition, dataPosition }) => {
const { t } = useTranslation(["CreateEditRoomDialog", "Common"]); const { t } = useTranslation(["CreateEditRoomDialog", "Common"]);
const [isChecked, setIsChecked] = useState(true);
const [elements, setElements] = useState({
userName: false,
userEmail: false,
userIP: false,
currentDate: false,
roomName: false,
});
const dataTabs = options(t); const dataTabs = options(t);
const [elements, setElements] = useState({
UserName: false,
UserEmail: false,
UserIpAdress: false,
CurrentDate: false,
RoomName: false,
});
const [selectedPosition, setSelectedPosition] = useState(initialPosition);
const [textValue, setTextValue] = useState("");
const onSelect = (item) => { const onSelect = (item) => {
const updatedElem = elements[item.key]; const updatedElem = elements[item.key];
const key = item.key; const key = item.key;
setElements({ ...elements, [key]: !updatedElem });
const updatedState = { ...elements, [key]: !updatedElem };
setElements(updatedState);
let flagsCount = 0;
for (const key in updatedState) {
const value = updatedState[key];
if (value) {
flagsCount += WatermarkAdditions[key];
}
}
setParams({ additions: flagsCount });
}; };
const onCheckboxChange = () => {
setIsChecked(!isChecked); const onPositionChange = (item) => {
setSelectedPosition(item);
setParams({ rotate: item.key });
};
const onTextChange = (e) => {
const { value } = e.target;
setTextValue(value);
setParams({ text: value });
}; };
return ( return (
<StyledWatermark> <StyledWatermark>
<Text className="watermark-title" fontWeight={600} lineHeight="20px">
{t("AddWatermarkElements")}
</Text>
<TabsContainer
elements={dataTabs}
onSelect={onSelect}
multiple
withBorder
/>
<div> <div>
<Text className="watermark-title" fontWeight={600} lineHeight="20px"> <Text className="watermark-title" fontWeight={600} lineHeight="20px">
{t("WatermarkElements")} {t("AddStaticText")}
</Text> </Text>
<TabsContainer <TextInput
elements={dataTabs} scale
onSelect={onSelect} value={textValue}
multiple tabIndex={1}
withBorder isAutoFocussed
/> onChange={onTextChange}
<Text className="watermark-title" fontWeight={600} lineHeight="20px">
{t("Position")}
</Text>
<TextInput scale value={t("Center")} isReadOnly />
<Checkbox
className="watermark-checkbox"
label={t("Semitransparent")}
onChange={onCheckboxChange}
isChecked={isChecked}
/> />
</div> </div>
<Text className="watermark-title" fontWeight={600} lineHeight="20px">
{t("Position")}
</Text>
<ComboBox
selectedOption={selectedPosition}
options={dataPosition}
onSelect={onPositionChange}
scaled
scaledOptions
/>
</StyledWatermark> </StyledWatermark>
); );
}; };

View File

@ -24,12 +24,11 @@
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 // 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 // International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
import { useState } from "react"; import { useState, useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { RadioButtonGroup } from "@docspace/shared/components/radio-button-group"; import { RadioButtonGroup } from "@docspace/shared/components/radio-button-group";
import TextWatermark from "./Text";
import ViewerInfoWatermark from "./ViewerInfo"; import ViewerInfoWatermark from "./ViewerInfo";
import { StyledBody } from "./StyledComponent"; import { StyledBody } from "./StyledComponent";
@ -42,18 +41,34 @@ const options = (t) => [
label: t("ViewerInfo"), label: t("ViewerInfo"),
value: viewerInfoWatermark, value: viewerInfoWatermark,
}, },
{
label: t("Text"),
value: textWatermark,
},
{ {
label: t("Common:Image"), label: t("Common:Image"),
value: imageWatermark, value: imageWatermark,
}, },
]; ];
const Watermarks = () => {
const positionOptions = (t) => [
{ key: -45, label: t("Diagonal") },
{ key: 0, label: t("Horizontal") },
];
const Watermarks = ({ setRoomParams }) => {
const { t } = useTranslation(["CreateEditRoomDialog", "Common"]); const { t } = useTranslation(["CreateEditRoomDialog", "Common"]);
const [type, setType] = useState(textWatermark); const [type, setType] = useState(viewerInfoWatermark);
const dataPosition = positionOptions(t);
const initialPosition = dataPosition[0];
useEffect(() => {
setRoomParams((prevState) => ({
...prevState,
watermarks: {
enabled: true,
rotate: initialPosition.key,
text: "",
additions: 0,
},
}));
}, []);
const onSelectType = (e) => { const onSelectType = (e) => {
const { value } = e.target; const { value } = e.target;
@ -61,6 +76,13 @@ const Watermarks = () => {
setType(value); setType(value);
}; };
const setParams = (info) => {
setRoomParams((prevState) => ({
...prevState,
watermarks: { ...prevState.watermarks, ...info },
}));
};
const typeOptions = options(t); const typeOptions = options(t);
return ( return (
@ -75,8 +97,13 @@ const Watermarks = () => {
onClick={onSelectType} onClick={onSelectType}
/> />
{type === textWatermark && <TextWatermark />} {type === viewerInfoWatermark && (
{type === viewerInfoWatermark && <ViewerInfoWatermark />} <ViewerInfoWatermark
setParams={setParams}
initialPosition={initialPosition}
dataPosition={dataPosition}
/>
)}
</StyledBody> </StyledBody>
); );
}; };

View File

@ -31,6 +31,7 @@ import FilesFilter from "@docspace/shared/api/files/filter";
import { getCategoryUrl } from "SRC_DIR/helpers/utils"; import { getCategoryUrl } from "SRC_DIR/helpers/utils";
import { CategoryType } from "SRC_DIR/helpers/constants"; import { CategoryType } from "SRC_DIR/helpers/constants";
import { RoomsType } from "@docspace/shared/enums"; import { RoomsType } from "@docspace/shared/enums";
import { setRoomWatermarks } from "@docspace/shared/api/rooms";
class CreateEditRoomStore { class CreateEditRoomStore {
roomParams = null; roomParams = null;
@ -157,6 +158,11 @@ class CreateEditRoomStore {
const actions = []; const actions = [];
const watermarks = roomParams.watermarks;
if (watermarks) {
await setRoomWatermarks(room.id, watermarks);
}
// delete thirdparty account if not needed // delete thirdparty account if not needed
if (!isThirdparty && storageFolderId) if (!isThirdparty && storageFolderId)
await deleteThirdParty(thirdpartyAccount.providerId); await deleteThirdParty(thirdpartyAccount.providerId);

View File

@ -477,3 +477,25 @@ export function resetRoomQuota(roomIds) {
return request(options); return request(options);
} }
export function setRoomWatermarks(
roomId: number | string,
data: {
enabled: boolean;
rotate: number;
text: string;
additions: number;
imageScale: number;
imageUrl: string;
imageWidth: string;
imageHeight: string;
},
) {
const options = {
method: "put",
url: `files/rooms/${roomId}/watermark`,
data,
};
return request(options);
}

View File

@ -523,3 +523,15 @@ export const enum EditorConfigErrorType {
AccessDeniedScope = "System.Security.SecurityException", AccessDeniedScope = "System.Security.SecurityException",
TenantQuotaException = "ASC.Core.Tenants.TenantQuotaException", TenantQuotaException = "ASC.Core.Tenants.TenantQuotaException",
} }
/**
* Enum for watermarks.
* @readonly
*/
export const enum WatermarkAdditions {
UserName = 1,
UserEmail = 2,
UserIpAdress = 4,
CurrentDate = 8,
RoomName = 16,
}