[DE mobile] Adding protection of document

This commit is contained in:
SergeyEzhin 2023-01-11 15:05:15 +04:00
parent 3077e51878
commit a92997107f
8 changed files with 163 additions and 5 deletions

View file

@ -658,6 +658,17 @@
"textRightToLeft": "Right To Left",
"textSearch": "Search",
"textSettings": "Settings",
"textProtectDocument": "Protect Document",
"textUnprotect": "Unprotect",
"textSetPassword": "Set Password",
"textTypeEditing": "Type Of Editing",
"textNoChanges": "No changes (Read only)",
"textFillingForms": "Filling forms",
"textTrackedChanges": "Tracked changes",
"textPassword": "Password",
"textVerify": "Verify",
"textSave": "Save",
"textRequired": "Required",
"textShowNotification": "Show Notification",
"textSpaces": "Spaces",
"textSpellcheck": "Spell Checking",

View file

@ -0,0 +1,37 @@
import React from 'react';
import { Device } from '../../../../../common/mobile/utils/device';
// import { withTranslation } from 'react-i18next';
import { f7 } from "framework7-react";
import ProtectionView from '../../view/settings/Protection';
class ProtectionController extends React.Component {
constructor(props) {
super(props);
this.onProtectDocument = this.onProtectDocument.bind(this);
}
closeModal() {
if (Device.phone) {
f7.sheet.close('.settings-popup', false);
} else {
f7.popover.close('#settings-popover', false);
}
};
onProtectDocument(typeProtection, password) {
const api = Common.EditorApi.get();
const protection = api.asc_getDocumentProtection() || new AscCommonWord.CDocProtect();
protection.asc_setEditType(typeProtection);
protection.asc_setPassword(password);
api.asc_setDocumentProtection(protection);
this.closeModal();
};
render() {
return <ProtectionView onProtectDocument={this.onProtectDocument} />
}
}
export default ProtectionController;

View file

@ -54,4 +54,10 @@ i.icon {
height: 22px;
.encoded-svg-background('<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M18 12C14.6863 12 12 14.6863 12 18C12 21.3137 14.6863 24 18 24C21.3137 24 24 21.3137 24 18C24 14.6863 21.3137 12 18 12ZM18.7458 22V16.7307H21.2522V15.4956H18.7458H17.2265H14.7478V16.7307H17.2265V22H18.7458Z" fill="#A8A8A8"/><path fill-rule="evenodd" clip-rule="evenodd" d="M4 1C2.34315 1 1 2.34315 1 4V20C1 21.6569 2.34315 23 4 23H13.101C11.8045 21.7295 11 19.9587 11 18C11 17.4576 11.0617 16.9296 11.1785 16.4226C9.86316 15.0952 8.20867 14.5842 6.37705 14.5842C5.6032 14.5842 4.85524 14.7369 4.15044 15.018C4.14616 15.0202 4.14224 15.0216 4.13776 15.0231L4.13654 15.0235C4.12921 15.0255 4.12161 15.0269 4.11419 15.0269C4.0511 15.0269 4 14.959 4 14.8755C4 14.8263 4.01769 14.7835 4.04393 14.7567C4.0454 14.7554 4.04681 14.754 4.04819 14.7527C4.05119 14.7498 4.05401 14.7471 4.05679 14.7448C5.28644 13.6439 6.76778 13.0011 8.36321 13.0011C9.48515 13.0011 10.5512 13.3196 11.5132 13.891C12.1885 13.2535 12.9445 12.7563 13.7571 12.432C14.9342 11.5336 16.4048 11 18 11C19.9587 11 21.7295 11.8045 23 13.101V4C23 2.34315 21.6569 1 20 1H4ZM19.9523 7.74897V7.74817C19.9256 7.72981 19.8987 7.71247 19.8719 7.69519L19.8513 7.68188C19.3128 7.33699 18.7196 7.11012 18.0893 7.03103C16.9751 6.89113 15.9103 7.23056 15.0106 7.92168C14.3943 7.45795 13.6965 7.156 12.9453 7.06171C11.91 6.93181 10.9174 7.21642 10.0601 7.81245L10.0495 7.82011L10.0495 7.82011C10.0445 7.82374 10.0396 7.82735 10.0349 7.83046C10.0141 7.85206 10 7.88567 10 7.92342C10 7.98904 10.0394 8.04212 10.0894 8.04212C10.094 8.04212 10.0985 8.04118 10.1034 8.03985C10.1055 8.03958 10.1076 8.03838 10.1095 8.03785C10.5706 7.92475 11.0513 7.89274 11.5415 7.95423C12.9173 8.12667 14.1162 8.69056 14.9573 9.95625C15.0013 10.0169 15.04 10.0132 15.0846 9.95305C16.1426 8.32593 17.7652 7.68295 19.509 7.90154C19.6063 7.91408 19.7021 7.92995 19.7976 7.94889L19.8265 7.95483C19.8559 7.96094 19.8894 7.96791 19.9115 7.97116C19.969 7.97957 20 7.91822 20 7.85233C19.9995 7.80778 19.985 7.77044 19.9523 7.74897Z" fill="#3C6D88"/></svg>');
}
&.icon-protect-document {
width: 22px;
height: 22px;
.encoded-svg-mask('<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M9 1L3 7V22H10V21H4V8H10V2H19V10H20V1H9ZM4.41422 7L9 2.41422V7H4.41422Z" fill="@{brandColor}"/><g clip-path="url(#clip0_205_12376)"><path fill-rule="evenodd" clip-rule="evenodd" d="M14.5002 15.5V15.5003C14.5001 15.6797 14.5002 15.8457 14.5008 16H14.5V17H13.5V16H13.5007C13.5001 15.8416 13.5001 15.675 13.5002 15.5C13.5002 13.567 15.0672 12 17.0002 12C18.9332 12 20.5002 13.567 20.5002 15.5C20.5002 15.675 20.5002 15.8416 20.4995 16H20.5V17H19.5V16H19.4994C19.5001 15.8457 19.5002 15.6795 19.5002 15.5C19.5002 14.1193 18.3809 13 17.0002 13C15.6195 13 14.5002 14.1193 14.5002 15.5ZM13.5 18H20.5C20.5 18 21 18 21 18.5V22.5C21 23 20.5 23 20.5 23H13.5C13.5 23 13 23 13 22.5V18.5C13 18 13.5 18 13.5 18ZM12 18C12 17 13 17 13 17H21C21 17 22 17 22 18V22.6667C22 23.3111 21.6443 24 21 24H13C13 24 12 24 12 23V18ZM17.5833 20.4023C17.7623 20.2421 17.875 20.0092 17.875 19.7501C17.875 19.2668 17.4832 18.8751 17 18.8751C16.5168 18.8751 16.125 19.2668 16.125 19.7501C16.125 20.0092 16.2377 20.2421 16.4167 20.4023V22.0834H17.5833V20.4023Z" fill="black"/></g><defs><clipPath id="clip0_205_12376"><rect width="12" height="12" fill="white" transform="translate(11 12)"/></clipPath></defs></svg>')
}
}

View file

@ -79,7 +79,7 @@
height: 24px;
.encoded-svg-mask('<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M7 1V3.5C7 3.77614 6.77614 4 6.5 4H4V3H6V1H7ZM17 3.5V1H18V3H20V4H17.5C17.2239 4 17 3.77614 17 3.5ZM17 20.5V23H18V21H20V20H17.5C17.2239 20 17 20.2239 17 20.5ZM7 20.5V23H6V21H4V20H6.5C6.77614 20 7 20.2239 7 20.5ZM16 6H8C7.44772 6 7 6.44772 7 7V17C7 17.5523 7.44772 18 8 18H16C16.5523 18 17 17.5523 17 17V7C17 6.44772 16.5523 6 16 6ZM8 5C6.89543 5 6 5.89543 6 7V17C6 18.1046 6.89543 19 8 19H16C17.1046 19 18 18.1046 18 17V7C18 5.89543 17.1046 5 16 5H8ZM9 8.5C9 8.22386 9.22386 8 9.5 8H14.5C14.7761 8 15 8.22386 15 8.5C15 8.77614 14.7761 9 14.5 9H9.5C9.22386 9 9 8.77614 9 8.5ZM9.5 11C9.22386 11 9 11.2239 9 11.5C9 11.7761 9.22386 12 9.5 12H14.5C14.7761 12 15 11.7761 15 11.5C15 11.2239 14.7761 11 14.5 11H9.5ZM9 14.5C9 14.2239 9.22386 14 9.5 14H14.5C14.7761 14 15 14.2239 15 14.5C15 14.7761 14.7761 15 14.5 15H9.5C9.22386 15 9 14.7761 9 14.5Z" fill="@{toolbar-icons}"/></svg>', @toolbar-icons);
}
&.icon-back-reader-mode {
&.icon-check {
width: 24px;
height: 24px;
.encoded-svg-mask('<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M9 16.1719L19.5938 5.57812L21 6.98438L9 18.9844L3.42188 13.4062L4.82812 12L9 16.1719Z" fill="@{toolbar-icons}" /></svg>', @toolbar-icons);
@ -92,6 +92,11 @@
height: 24px;
.encoded-svg-mask('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 22 22" fill="@{fill-white}"><g><path d="M21,12h-9v9h-2v-9H1v-2h9V1h2v9h9V12z"/></g></svg>', @fill-white);
}
&.icon-check {
width: 24px;
height: 24px;
.encoded-svg-mask('<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M9 16.1719L19.5938 5.57812L21 6.98438L9 18.9844L3.42188 13.4062L4.82812 12L9 16.1719Z" fill="@{brandColor}" /></svg>');
}
&.icon-expand-down {
width: 17px;
height: 17px;

View file

@ -32,7 +32,10 @@ export class storeAppOptions {
changeMobileView: action,
isProtected: observable,
setProtection: action
setProtection: action,
typeProtection: observable,
setTypeProtection: action
});
}
@ -43,6 +46,11 @@ export class storeAppOptions {
this.isProtected = value;
}
typeProtection = 3;
setTypeProtection(type) {
this.typeProtection = type;
}
isMobileView = true;
changeMobileView() {
this.isMobileView = !this.isMobileView;

View file

@ -44,7 +44,7 @@ const ToolbarView = props => {
return (
<Fragment>
<NavLeft>
{!isViewer && <Link text={Device.ios ? t("Toolbar.textOk") : ''} icon={Device.android ? 'icon-back-reader-mode' : null} className='back-reader-mode' onClick={() => props.turnOnViewerMode()}></Link>}
{!isViewer && <Link text={Device.ios ? t("Toolbar.textOk") : ''} icon={Device.android ? 'icon-check' : null} className='back-reader-mode' onClick={() => props.turnOnViewerMode()}></Link>}
{(props.isShowBack && isViewer) && <Link className={`btn-doc-back${props.disabledControls && ' disabled'}`} icon='icon-back' onClick={props.onBack}></Link>}
{(Device.ios && props.isEdit && !isViewer) && EditorUIController.getUndoRedo && EditorUIController.getUndoRedo({
disabledUndo: !props.isCanUndo || isDisconnected,

View file

@ -0,0 +1,83 @@
import React, { useState } from 'react';
import { observer, inject } from "mobx-react";
import { Device } from '../../../../../common/mobile/utils/device';
import { Page, Navbar, List, ListItem, BlockTitle, Toggle, NavRight, f7, Link, ListInput, Icon, Block } from "framework7-react";
import { useTranslation } from "react-i18next";
const ProtectionView = inject("storeAppOptions")(observer(props => {
const { t } = useTranslation();
const _t = t("Settings", { returnObjects: true });
const isIos = Device.ios;
const appOptions = props.storeAppOptions;
const typeProtection = appOptions.typeProtection;
const [isPassword, setPassword] = useState(false);
const [password, changePassword] = useState('');
const [passwordRepeat, repeatPassword] = useState('');
const isDisabledProtection = isPassword && ((!password.length || !passwordRepeat.length) || password !== passwordRepeat);
return (
<Page>
<Navbar title={t('Settings.textProtectDocument')} backLink={_t.textBack}>
<NavRight>
<Link text={isIos && t('Settings.textSave')} className={isDisabledProtection && 'disabled'} onClick={() => {
props.onProtectDocument(typeProtection, password);
}}>
{Device.android && <Icon icon='icon-check'/>}
</Link>
</NavRight>
</Navbar>
<List>
<ListItem title={t('Settings.textSetPassword')}>
<Toggle checked={isPassword} onToggleChange={() => {
setPassword(!isPassword);
}} />
</ListItem>
</List>
{isPassword &&
<>
<List inlineLabels className="inputs-list">
<ListInput
label={t('Settings.textPassword')}
type="password"
placeholder={t('Settings.textRequired')}
value={password}
onInput={e => changePassword(e.target.value)}
className={isIos ? 'list-input-right' : ''}
/>
<ListInput
label={t('Settings.textVerify')}
type="password"
placeholder={t('Settings.textRequired')}
value={passwordRepeat}
onInput={e => repeatPassword(e.target.value)}
className={isIos ? 'list-input-right' : ''}
/>
</List>
<Block>
<p>If the password is forgotten or lost, it cannot be recovered.</p>
</Block>
</>
}
<BlockTitle>{t('Settings.textTypeEditing')}</BlockTitle>
<List>
<ListItem radio checked={typeProtection === Asc.c_oAscEDocProtect.ReadOnly} title={t('Settings.textNoChanges')} onClick={() => {
appOptions.setTypeProtection(Asc.c_oAscEDocProtect.ReadOnly);
}}></ListItem>
<ListItem radio checked={typeProtection === Asc.c_oAscEDocProtect.Forms} title={t('Settings.textFillingForms')} onClick={() => {
appOptions.setTypeProtection(Asc.c_oAscEDocProtect.Forms);
}}></ListItem>
<ListItem radio checked={typeProtection === Asc.c_oAscEDocProtect.TrackedChanges} title={t('Settings.textTrackedChanges')} onClick={() => {
appOptions.setTypeProtection(Asc.c_oAscEDocProtect.TrackedChanges);
}}></ListItem>
<ListItem radio checked={typeProtection === Asc.c_oAscEDocProtect.Comments} title={t('Settings.textComments')} onClick={() => {
appOptions.setTypeProtection(Asc.c_oAscEDocProtect.Comments);
}}></ListItem>
</List>
<Block>
<p>Allow only this type of editing in the document.</p>
</Block>
</Page>
)
}));
export default ProtectionView;

View file

@ -14,6 +14,7 @@ import { MacrosSettings, Direction } from "./ApplicationSettings";
import About from '../../../../../common/mobile/lib/view/About';
import NavigationController from '../../controller/settings/Navigation';
import SharingSettings from "../../../../../common/mobile/lib/view/SharingSettings";
import ProtectionController from '../../controller/settings/Protection';
const routes = [
{
@ -65,17 +66,21 @@ const routes = [
},
// Direction
{
path: '/direction/',
component: Direction
},
// Sharing Settings
{
path: '/sharing-settings/',
component: SharingSettings
},
// Protection
{
path: '/protection-document/',
component: ProtectionController
}
];
@ -150,6 +155,9 @@ const SettingsList = inject("storeAppOptions", "storeReview")(observer(props =>
<Icon slot="media" icon="icon-search"></Icon>
</ListItem>
}
<ListItem title={t('Settings.textProtectDocument')} link="#" onClick={onoptionclick.bind(this, '/protection-document/')}>
<Icon slot="media" icon="icon-protect-document"></Icon>
</ListItem>
<ListItem title={t('Settings.textNavigation')} link='#' onClick={() => {
if(Device.phone) {
onOpenNavigation();