Merge pull request #2100 from ONLYOFFICE/feature/fix-bugs

Feature/fix bugs
This commit is contained in:
maxkadushkin 2022-12-02 15:45:29 +03:00 committed by GitHub
commit e8f356160d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 162 additions and 62 deletions

View file

@ -0,0 +1,73 @@
import React, {useEffect} from 'react';
import ViewSharingSettings from "../view/SharingSettings";
import {observer, inject} from "mobx-react";
import { f7 } from 'framework7-react';
const SharingSettingsController = props => {
const appOptions = props.storeAppOptions;
const canRequestSharingSettings = appOptions.canRequestSharingSettings;
const sharingSettingsUrl = appOptions.sharingSettingsUrl;
const changeAccessRights = () => {
if (canRequestSharingSettings) {
Common.Gateway.requestSharingSettings();
}
};
const setSharingSettings = data => {
if (data) {
Common.Notifications.trigger('collaboration:sharingupdate', data.sharingSettings);
}
}
const onMessage = msg => {
if(msg) {
const msgData = JSON.parse(msg.data);
if (msgData && msgData?.Referer == "onlyoffice") {
if (msgData?.needUpdate) {
setSharingSettings(msgData.sharingSettings);
}
f7.views.current.router.back();
}
}
};
const bindWindowEvents = () => {
if (window.addEventListener) {
window.addEventListener("message", onMessage, false);
} else if (window.attachEvent) {
window.attachEvent("onmessage", onMessage);
}
};
const unbindWindowEvents = () => {
if (window.removeEventListener) {
window.removeEventListener("message", onMessage);
} else if (window.detachEvent) {
window.detachEvent("onmessage", onMessage);
}
};
useEffect(() => {
bindWindowEvents();
Common.Notifications.on('collaboration:sharing', changeAccessRights);
if (!!sharingSettingsUrl && sharingSettingsUrl.length || canRequestSharingSettings) {
Common.Gateway.on('showsharingsettings', changeAccessRights);
Common.Gateway.on('setsharingsettings', setSharingSettings);
}
return () => {
unbindWindowEvents();
}
}, []);
return (
<ViewSharingSettings
sharingSettingsUrl={sharingSettingsUrl}
/>
);
};
export default inject('storeAppOptions')(observer(SharingSettingsController));

View file

@ -1,27 +1,29 @@
import React, { Component, useEffect } from 'react'; import React, { useEffect } from 'react';
import { observer, inject } from "mobx-react"; import { Navbar, Page } from 'framework7-react';
import { f7, Popover, List, ListItem, Navbar, NavRight, Sheet, BlockTitle, Page, View, Icon, Link } from 'framework7-react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Device } from "../../utils/device";
const SharingSettings = props => { const ViewSharingSettings = props => {
const { t } = useTranslation(); const { t } = useTranslation();
const storeAppOptions = props.storeAppOptions; const sharingSettingsUrl = props.sharingSettingsUrl;
const sharingSettingsUrl = storeAppOptions.sharingSettingsUrl;
const _t = t('Common.Collaboration', {returnObjects: true}); const _t = t('Common.Collaboration', {returnObjects: true});
function resizeHeightIframe(iFrame) { function resizeHeightIframe(selector) {
const iFrame = document.querySelector(selector);
iFrame.height = iFrame.contentWindow.document.body.scrollHeight; iFrame.height = iFrame.contentWindow.document.body.scrollHeight;
} };
useEffect(() => {
resizeHeightIframe('#sharing-placeholder iframe');
}, []);
return ( return (
<Page> <Page>
<Navbar title={t('Common.Collaboration.textSharingSettings')} backLink={_t.textBack} /> <Navbar title={t('Common.Collaboration.textSharingSettings')} backLink={_t.textBack} />
<div id="sharing-placeholder" className="sharing-placeholder"> <div id="sharing-placeholder" className="sharing-placeholder">
<iframe width="100%" frameBorder={0} scrolling="0" align="top" src={sharingSettingsUrl} onLoad={resizeHeightIframe(this)}></iframe> <iframe width="100%" frameBorder={0} scrolling="0" align="top" src={sharingSettingsUrl}></iframe>
</div> </div>
</Page> </Page>
) )
} };
export default inject("storeAppOptions")(observer(SharingSettings)); export default ViewSharingSettings;

View file

@ -1,18 +1,19 @@
import React, { Component, useEffect } from 'react'; import React, { Component, useEffect } from 'react';
import { observer, inject } from "mobx-react"; import { observer, inject } from "mobx-react";
import { Popover, List, ListItem, Navbar, NavRight, Sheet, BlockTitle, Page, View, Icon, Link } from 'framework7-react'; import { Popover, List, ListItem, Navbar, NavRight, Sheet, BlockTitle, Page, View, Icon, Link, f7 } from 'framework7-react';
import { f7 } from 'framework7-react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import {Device} from "../../../utils/device"; import {Device} from "../../../utils/device";
import {ReviewController, ReviewChangeController} from "../../controller/collaboration/Review"; import {ReviewController, ReviewChangeController} from "../../controller/collaboration/Review";
import {PageDisplayMode} from "./Review"; import {PageDisplayMode} from "./Review";
import {ViewCommentsController, ViewCommentsSheetsController} from "../../controller/collaboration/Comments"; import {ViewCommentsController, ViewCommentsSheetsController} from "../../controller/collaboration/Comments";
import SharingSettings from "../SharingSettings"; // import SharingSettings from "../SharingSettings";
import SharingSettingsController from "../../controller/SharingSettings";
const PageUsers = inject("users")(observer(props => { const PageUsers = inject("users")(observer(props => {
const { t } = useTranslation(); const { t } = useTranslation();
const _t = t('Common.Collaboration', {returnObjects: true}); const _t = t('Common.Collaboration', {returnObjects: true});
const storeUsers = props.users; const storeUsers = props.users;
return ( return (
<Page name="collab__users" className='page-users'> <Page name="collab__users" className='page-users'>
<Navbar title={_t.textUsers} backLink={_t.textBack}> <Navbar title={_t.textUsers} backLink={_t.textBack}>
@ -83,7 +84,7 @@ const routes = [
}, },
{ {
path: '/sharing-settings/', path: '/sharing-settings/',
component: SharingSettings component: SharingSettingsController
} }
]; ];
@ -131,8 +132,8 @@ const PageCollaboration = inject('storeAppOptions', 'users')(observer(props => {
</Page> </Page>
</View> </View>
) )
})); }));
class CollaborationView extends Component { class CollaborationView extends Component {
constructor(props) { constructor(props) {
super(props); super(props);

View file

@ -95,6 +95,7 @@ export class storeAppOptions {
this.lang = config.lang; this.lang = config.lang;
this.location = (typeof (config.location) == 'string') ? config.location.toLowerCase() : ''; this.location = (typeof (config.location) == 'string') ? config.location.toLowerCase() : '';
this.sharingSettingsUrl = config.sharingSettingsUrl; this.sharingSettingsUrl = config.sharingSettingsUrl;
this.canRequestSharingSettings = config.canRequestSharingSettings;
this.fileChoiceUrl = config.fileChoiceUrl; this.fileChoiceUrl = config.fileChoiceUrl;
this.mergeFolderUrl = config.mergeFolderUrl; this.mergeFolderUrl = config.mergeFolderUrl;
this.canAnalytics = false; this.canAnalytics = false;

View file

@ -126,7 +126,7 @@
"txtIncorrectPwd": "Password is incorrect", "txtIncorrectPwd": "Password is incorrect",
"txtProtected": "Once you enter the password and open the file, the current password to the file will be reset", "txtProtected": "Once you enter the password and open the file, the current password to the file will be reset",
"warnLicenseExceeded": "You've reached the limit for simultaneous connections to %1 editors. This document will be opened for viewing only. Contact your administrator to learn more.", "warnLicenseExceeded": "You've reached the limit for simultaneous connections to %1 editors. This document will be opened for viewing only. Contact your administrator to learn more.",
"warnLicenseExp": "Your license has expired. Please, update it and refresh the page.", "warnLicenseExp": "Your license has expired. Please, update your license and refresh the page.",
"warnLicenseLimitedNoAccess": "License expired. You have no access to document editing functionality. Please, contact your administrator.", "warnLicenseLimitedNoAccess": "License expired. You have no access to document editing functionality. Please, contact your administrator.",
"warnLicenseLimitedRenewed": "License needs to be renewed. You have limited access to document editing functionality.<br>Please contact your administrator to get full access", "warnLicenseLimitedRenewed": "License needs to be renewed. You have limited access to document editing functionality.<br>Please contact your administrator to get full access",
"warnLicenseUsersExceeded": "You've reached the user limit for %1 editors. Contact your administrator to learn more.", "warnLicenseUsersExceeded": "You've reached the user limit for %1 editors. Contact your administrator to learn more.",

View file

@ -516,6 +516,9 @@ class MainController extends Component {
storeSpreadsheetInfo.changeTitle(meta.title); storeSpreadsheetInfo.changeTitle(meta.title);
} }
}); });
const storeAppOptions = this.props.storeAppOptions;
this.api.asc_setFilteringMode && this.api.asc_setFilteringMode(storeAppOptions.canModifyFilter);
} }
onEntriesListMenu(validation, textArr, addArr) { onEntriesListMenu(validation, textArr, addArr) {

View file

@ -80,6 +80,7 @@ export class storeAppOptions {
permissions.edit = false; permissions.edit = false;
this.canBranding = params.asc_getCustomization(); this.canBranding = params.asc_getCustomization();
this.canBrandingExt = params.asc_getCanBranding() && (typeof this.customization == 'object'); this.canBrandingExt = params.asc_getCanBranding() && (typeof this.customization == 'object');
this.canModifyFilter = permissions.modifyFilter !== false;
this.canAutosave = true; this.canAutosave = true;
this.canAnalytics = params.asc_getIsAnalyticsEnable(); this.canAnalytics = params.asc_getIsAnalyticsEnable();
this.canLicense = (licType === Asc.c_oLicenseResult.Success || licType === Asc.c_oLicenseResult.SuccessLimit); this.canLicense = (licType === Asc.c_oLicenseResult.Success || licType === Asc.c_oLicenseResult.SuccessLimit);

View file

@ -2,10 +2,13 @@ import React, {useEffect, useState} from 'react';
import {f7, List, Popover, Sheet, ListItem, Icon, Row, Button, ListButton, Page, Navbar, Segmented, BlockTitle, NavRight, Link, Toggle,View} from 'framework7-react'; import {f7, List, Popover, Sheet, ListItem, Icon, Row, Button, ListButton, Page, Navbar, Segmented, BlockTitle, NavRight, Link, Toggle,View} from 'framework7-react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Device } from '../../../../common/mobile/utils/device'; import { Device } from '../../../../common/mobile/utils/device';
import {observer, inject} from "mobx-react";
const FilterOptions = (props) => { const FilterOptions = inject('storeAppOptions')(observer(props => {
const { t } = useTranslation(); const { t } = useTranslation();
const _t = t('View.Edit', {returnObjects: true}); const _t = t('View.Edit', {returnObjects: true});
const storeAppOptions = props.storeAppOptions;
const canModifyFilter = storeAppOptions.canModifyFilter;
let is_all_checked = props.listVal.every(item => item.check); let is_all_checked = props.listVal.every(item => item.check);
const HandleClearFilter = () => { const HandleClearFilter = () => {
@ -40,34 +43,48 @@ const FilterOptions = (props) => {
</NavRight> </NavRight>
} }
</Navbar> </Navbar>
<List> <List>
<ListItem className='buttons'> <ListItem className='buttons'>
<Row> <Row>
<a className={'button' + (props.checkSort === 'down' ? ' active' : '')} onClick={() => {props.onSort('sortdown'); onValidChecked();}}> <a className={'button' + (props.checkSort === 'down' ? ' active' : '')} onClick={() => {
props.onSort('sortdown');
onValidChecked();
}}>
<Icon slot="media" icon="sortdown"/> <Icon slot="media" icon="sortdown"/>
</a> </a>
<a className={'button' + (props.checkSort === 'up' ? ' active' : '')} onClick={() => {props.onSort('sortup'); onValidChecked();}}> <a className={'button' + (props.checkSort === 'up' ? ' active' : '')} onClick={() => {
props.onSort('sortup');
onValidChecked();
}}>
<Icon slot="media" icon="sortup"/> <Icon slot="media" icon="sortup"/>
</a> </a>
</Row> </Row>
</ListItem> </ListItem>
</List> </List>
<List>
<List > <ListButton className={props.isValid || is_all_checked ? 'disabled' : ''}
<ListButton className={props.isValid || is_all_checked ? 'disabled' : ''} onClick={HandleClearFilter}>{_t.textClearFilter}</ListButton> onClick={HandleClearFilter}>{_t.textClearFilter}</ListButton>
<ListButton color="red" onClick={() => props.onDeleteFilter()} id="btn-delete-filter">{_t.textDeleteFilter}</ListButton> <ListButton color="red" className={!canModifyFilter ? 'disabled' : ''}
onClick={() => props.onDeleteFilter()}
id="btn-delete-filter">{_t.textDeleteFilter}</ListButton>
</List> </List>
<List> <List>
<ListItem className='radio-checkbox-item' onChange={e => {props.onUpdateCell('all', e.target.checked); onValidChecked();}} name='filter-cellAll' checkbox checked={is_all_checked}>{_t.textSelectAll}</ListItem> <ListItem className='radio-checkbox-item' onChange={e => {
props.onUpdateCell('all', e.target.checked);
onValidChecked();
}} name='filter-cellAll' checkbox checked={is_all_checked}>{_t.textSelectAll}</ListItem>
{props.listVal.map((value) => {props.listVal.map((value) =>
<ListItem className='radio-checkbox-item' onChange={e => {props.onUpdateCell(value.id, e.target.checked); onValidChecked();}} key={value.value} name='filter-cell' value={value.value} title={value.cellvalue} checkbox checked={value.check} /> <ListItem className='radio-checkbox-item' onChange={e => {
props.onUpdateCell(value.id, e.target.checked);
onValidChecked();
}} key={value.value} name='filter-cell' value={value.value} title={value.cellvalue} checkbox
checked={value.check}/>
)} )}
</List> </List>
</Page> </Page>
</View> </View>
) )
}; }));
const FilterView = (props) => { const FilterView = (props) => {
return ( return (

View file

@ -3,10 +3,12 @@ import { inject, observer } from 'mobx-react';
import {List, ListItem, Icon} from 'framework7-react'; import {List, ListItem, Icon} from 'framework7-react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
const AddOther = inject("storeFocusObjects")(observer(props => { const AddOther = inject("storeFocusObjects", "storeAppOptions")(observer(props => {
const { t } = useTranslation(); const { t } = useTranslation();
const _t = t('View.Add', {returnObjects: true}); const _t = t('View.Add', {returnObjects: true});
const storeFocusObjects = props.storeFocusObjects; const storeFocusObjects = props.storeFocusObjects;
const storeAppOptions = props.storeAppOptions;
const canModifyFilter = storeAppOptions.canModifyFilter;
const isHyperLink = storeFocusObjects.selections.indexOf('hyperlink') > -1; const isHyperLink = storeFocusObjects.selections.indexOf('hyperlink') > -1;
const hideAddComment = props.hideAddComment(); const hideAddComment = props.hideAddComment();
const wsProps = props.wsProps; const wsProps = props.wsProps;
@ -22,7 +24,7 @@ const AddOther = inject("storeFocusObjects")(observer(props => {
}}> }}>
<Icon slot="media" icon="icon-insert-comment"></Icon> <Icon slot="media" icon="icon-insert-comment"></Icon>
</ListItem>} </ListItem>}
<ListItem title={_t.textSortAndFilter} className={wsProps.Sort && 'disabled'} link={'/add-sort-and-filter/'}> <ListItem title={_t.textSortAndFilter} className={wsProps.Sort || !canModifyFilter ? 'disabled' : ''} link={'/add-sort-and-filter/'}>
<Icon slot="media" icon="icon-sort"></Icon> <Icon slot="media" icon="icon-sort"></Icon>
</ListItem> </ListItem>
<ListItem title={_t.textLink} className={wsProps.InsertHyperlinks && 'disabled'} link={isHyperLink ? '/edit-link/' : '/add-link/'} routeProps={{ <ListItem title={_t.textLink} className={wsProps.InsertHyperlinks && 'disabled'} link={isHyperLink ? '/edit-link/' : '/add-link/'} routeProps={{