[SSE mobile] Added the ability insert links

This commit is contained in:
JuliaSvinareva 2021-02-07 18:12:18 +03:00
parent 368c773d16
commit 683a9722e5
6 changed files with 313 additions and 1 deletions

View file

@ -242,6 +242,9 @@
}
}
}
.list-input-right input {
text-align: right;
}
}
.tab-buttons {

View file

@ -32,7 +32,19 @@
"textPictureFromURL": "Picture from URL",
"txtNotUrl": "This field should be a URL in the format \"http://www.example.com\"",
"textEmptyImgUrl": "You need to specify image URL.",
"notcriticalErrorTitle": "Warning"
"notcriticalErrorTitle": "Warning",
"textLink": "Link",
"textAddLink": "Add Link",
"textLinkType": "Link Type",
"textExternalLink": "External Link",
"textInternalDataRange": "Internal Data Range",
"textSheet": "Sheet",
"textRange": "Range",
"textRequired": "Required",
"textDisplay": "Display",
"textScreenTip": "Screen Tip",
"textInsert": "Insert",
"textInvalidRange": "ERROR! Invalid cells range"
},
"Edit" : {
"textSelectObjectToEdit": "Select object to edit",

View file

@ -0,0 +1,121 @@
import React, {Component} from 'react';
import { f7 } from 'framework7-react';
import {Device} from '../../../../../common/mobile/utils/device';
import {withTranslation} from 'react-i18next';
import {AddLink} from '../../view/add/AddLink';
class AddLinkController extends Component {
constructor (props) {
super(props);
this.onInsertLink = this.onInsertLink.bind(this);
const api = Common.EditorApi.get();
const cell = api.asc_getCellInfo();
const celltype = cell.asc_getSelectionType();
this.allowInternal = (celltype !== Asc.c_oAscSelectionType.RangeImage && celltype !== Asc.c_oAscSelectionType.RangeShape &&
celltype !== Asc.c_oAscSelectionType.RangeShapeText && celltype !== Asc.c_oAscSelectionType.RangeChart &&
celltype !== Asc.c_oAscSelectionType.RangeChartText);
this.displayText = cell.asc_getLockText() ? 'locked' : cell.asc_getText();
// sheets
let items = [];
let wsc = api.asc_getWorksheetsCount();
const aws = api.asc_getActiveWorksheetIndex();
if (wsc > 0) {
items = [];
while ( !(--wsc < 0) ) {
if ( !api.asc_isWorksheetHidden(wsc) ) {
items.unshift({
value: wsc,
caption: api.asc_getWorksheetName(wsc)
});
if (wsc === aws) {
this.activeSheet = {
value: wsc,
caption: api.asc_getWorksheetName(wsc)
}
}
}
}
this.sheets = items;
}
}
onInsertLink (args) {
const api = Common.EditorApi.get();
const { t } = this.props;
const _t = t("View.Add", { returnObjects: true });
const link = new Asc.asc_CHyperlink();
let display = '';
if (args.type == 'ext') {
let url = args.url;
const urltype = api.asc_getUrlType(url.trim());
const isEmail = (urltype == 2);
if (urltype < 1) {
f7.dialog.alert(_t.txtNotUrl, _t.notcriticalErrorTitle);
return;
}
url = url.replace(/^\s+|\s+$/g, '');
if (!/(((^https?)|(^ftp)):\/\/)|(^mailto:)/i.test(url))
url = (isEmail ? 'mailto:' : 'http://' ) + url;
url = url.replace(new RegExp("%20", 'g'), " ");
link.asc_setType(Asc.c_oAscHyperlinkType.WebLink);
link.asc_setHyperlinkUrl(url);
display = url;
} else {
const isValid = api.asc_checkDataRange(Asc.c_oAscSelectionDialogType.FormatTable, args.url, false);
if (isValid !== Asc.c_oAscError.ID.No) {
f7.dialog.alert(_t.textInvalidRange, _t.notcriticalErrorTitle);
return;
}
link.asc_setType(Asc.c_oAscHyperlinkType.RangeLink);
link.asc_setSheet(args.sheet);
link.asc_setRange(args.url);
display = args.sheet + '!' + args.url;
}
link.asc_setText(args.text == null ? null : !!args.text ? args.text : display);
link.asc_setTooltip(args.tooltip);
api.asc_insertHyperlink(link);
this.closeModal();
}
closeModal () {
if ( Device.phone ) {
f7.sheet.close('.add-popup', true);
} else {
f7.popover.close('#add-popover');
}
}
render () {
return (
<AddLink inTabs={this.props.inTabs}
allowInternal={this.allowInternal}
displayText={this.displayText}
sheets={this.sheets}
activeSheet={this.activeSheet}
onInsertLink={this.onInsertLink}
/>
)
}
}
const AddLinkWithTranslation = withTranslation()(AddLinkController);
export {AddLinkWithTranslation as AddLinkController};

View file

@ -12,6 +12,8 @@ import AddShapeController from "../../controller/add/AddShape";
import {AddOtherController} from "../../controller/add/AddOther";
import {AddImageController} from "../../controller/add/AddImage";
import {PageImageLinkSettings} from "./AddImage";
import {AddLinkController} from "../../controller/add/AddLink";
import {PageTypeLink, PageSheet} from "./AddLink";
const routes = [
// Functions
@ -31,6 +33,19 @@ const routes = [
{
path: '/add-image-from-url/',
component: PageImageLinkSettings
},
// Link
{
path: '/add-link/',
component: AddLinkController
},
{
path: '/add-link-type/',
component: PageTypeLink
},
{
path: '/add-link-sheet/',
component: PageSheet
}
];
@ -110,6 +125,13 @@ const AddTabs = props => {
component: <AddOtherController/>
});
}
if (showPanels && showPanels === 'hyperlink') {
tabs.push({
caption: _t.textAddLink,
id: 'add-link',
component: <AddLinkController/>
});
}
return (
<View style={props.style} stackPages={true} routes={routes}>
<Page pageContent={false}>

View file

@ -0,0 +1,151 @@
import React, {Fragment, useState} from 'react';
import {Page, Navbar, BlockTitle, List, ListItem, ListInput, ListButton, Icon} from 'framework7-react';
import { useTranslation } from 'react-i18next';
import {Device} from "../../../../../common/mobile/utils/device";
const PageTypeLink = ({curType, changeType}) => {
const { t } = useTranslation();
const _t = t('View.Add', {returnObjects: true});
const [typeLink, setTypeLink] = useState(curType);
return (
<Page>
<Navbar title={_t.textLinkType} backLink={_t.textBack}/>
<List>
<ListItem title={_t.textExternalLink} radio checked={typeLink === 'ext'} onClick={() => {setTypeLink('ext'); changeType('ext');}}></ListItem>
<ListItem title={_t.textInternalDataRange} radio checked={typeLink === 'int'} onClick={() => {setTypeLink('int'); changeType('int');}}></ListItem>
</List>
</Page>
)
};
const PageSheet = ({curSheet, sheets, changeSheet}) => {
const { t } = useTranslation();
const _t = t('View.Add', {returnObjects: true});
const [stateSheet, setSheet] = useState(curSheet.value);
return (
<Page>
<Navbar title={_t.textSheet} backLink={_t.textBack}/>
<List>
{sheets.map((sheet) => {
return(
<ListItem key={`sheet-${sheet.value}`}
title={sheet.caption}
radio
checked={stateSheet === sheet.value}
onClick={() => {
setSheet(sheet.value);
changeSheet(sheet);
}}
/>
)
})}
</List>
</Page>
)
};
const AddLinkView = props => {
const isIos = Device.ios;
const { t } = useTranslation();
const _t = t('View.Add', {returnObjects: true});
const [typeLink, setTypeLink] = useState('ext');
const textType = typeLink === 'ext' ? _t.textExternalLink : _t.textInternalDataRange;
const changeType = (newType) => {
setTypeLink(newType);
};
const [link, setLink] = useState('');
let displayText = props.displayText;
const displayDisabled = displayText === 'locked';
displayText = displayDisabled ? _t.textSelectedRange : displayText;
const [stateDisplayText, setDisplayText] = useState(displayText);
const [screenTip, setScreenTip] = useState('');
const activeSheet = props.activeSheet;
const [curSheet, setSheet] = useState(activeSheet);
const changeSheet = (sheet) => {
setSheet(sheet);
};
const [range, setRange] = useState('');
return (
<Fragment>
<List inlineLabels className='inputs-list'>
{props.allowInternal &&
<ListItem link={'/add-link-type/'} title={_t.textLinkType} after={textType} routeProps={{
changeType: changeType,
curType: typeLink
}}/>
}
{typeLink === 'ext' &&
<ListInput label={_t.textLink}
type="text"
placeholder={_t.textLink}
value={link}
onChange={(event) => {setLink(event.target.value)}}
className={isIos ? 'list-input-right' : ''}
/>
}
{typeLink === 'int' &&
<ListItem link={'/add-link-sheet/'} title={_t.textSheet} after={curSheet.caption} routeProps={{
changeSheet: changeSheet,
sheets: props.sheets,
curSheet: curSheet
}}/>
}
{typeLink === 'int' &&
<ListInput label={_t.textRange}
type="text"
placeholder={_t.textRequired}
value={range}
onChange={(event) => {setRange(event.target.value)}}
className={isIos ? 'list-input-right' : ''}
/>
}
<ListInput label={_t.textDisplay}
type="text"
placeholder={_t.textDisplay}
value={stateDisplayText}
disabled={displayDisabled}
onChange={(event) => {setDisplayText(event.target.value)}}
className={isIos ? 'list-input-right' : ''}
/>
<ListInput label={_t.textScreenTip}
type="text"
placeholder={_t.textScreenTip}
value={screenTip}
onChange={(event) => {setScreenTip(event.target.value)}}
className={isIos ? 'list-input-right' : ''}
/>
</List>
<List>
<ListButton title={_t.textInsert}
className={`button-fill button-raised${(typeLink === 'ext' && link.length < 1 || typeLink === 'int' && range.length < 1) && ' disabled'}`}
onClick={() => {props.onInsertLink(typeLink === 'ext' ?
{type: 'ext', url: link, text: stateDisplayText, tooltip: screenTip} :
{type: 'int', url: range, sheet: curSheet.caption, text: stateDisplayText, tooltip: screenTip})}}
/>
</List>
</Fragment>
)
};
const AddLink = props => {
const { t } = useTranslation();
const _t = t('View.Add', {returnObjects: true});
return (
props.inTabs ?
<AddLinkView allowInternal={props.allowInternal} displayText={props.displayText} sheets={props.sheets} activeSheet={props.activeSheet} onInsertLink={props.onInsertLink}/> :
<Page>
<Navbar title={_t.textAddLink} backLink={_t.textBack}/>
<AddLinkView allowInternal={props.allowInternal} displayText={props.displayText} sheets={props.sheets} activeSheet={props.activeSheet} onInsertLink={props.onInsertLink}/>
</Page>
)
};
export {AddLink, PageTypeLink, PageSheet};

View file

@ -10,6 +10,9 @@ const AddOther = props => {
<ListItem title={_t.textImage} link={'/add-image/'}>
<Icon slot="media" icon="icon-insimage"></Icon>
</ListItem>
<ListItem title={_t.textLink} link={'/add-link/'}>
<Icon slot="media" icon="icon-link"></Icon>
</ListItem>
</List>
)
};