[SSE mobile] Corrected styles, Chart Settings and added Link Settings
This commit is contained in:
parent
1cb18ade25
commit
37248d0c0e
|
@ -393,25 +393,6 @@
|
|||
|
||||
// input[type="number"]
|
||||
|
||||
.item-input {
|
||||
width: 100%;
|
||||
margin-top: -8px;
|
||||
margin-bottom: -7px;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
.item-content {
|
||||
.item-after input {
|
||||
height: 43px;
|
||||
}
|
||||
.item-after input.right {
|
||||
text-align: right;
|
||||
}
|
||||
.item-after input.field {
|
||||
color: @darkGreen;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="number"]::placeholder { color: @darkGreen;}
|
||||
input[type="number"]::-webkit-input-placeholder {color: @darkGreen;}
|
||||
input[type="number"]::-moz-placeholder {color: @darkGreen;}
|
||||
|
|
|
@ -291,55 +291,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// input[type="number"]
|
||||
|
||||
.list.inputs-list {
|
||||
ul:after {
|
||||
display: none;
|
||||
}
|
||||
.item-inner {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
padding-bottom: 0;
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.item-input {
|
||||
flex-shrink: 1;
|
||||
font-size: 0;
|
||||
position: relative;
|
||||
margin-bottom: 4px;
|
||||
min-height: 36px;
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: auto;
|
||||
top: auto;
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
background-color: rgba(0,0,0,.12);
|
||||
display: block;
|
||||
z-index: 15;
|
||||
transform-origin: 50% 100%;
|
||||
transition: .2;
|
||||
}
|
||||
}
|
||||
.item-link {
|
||||
.item-inner .item-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
.item-after {
|
||||
font-size: 14px;
|
||||
color: @darkGrey;
|
||||
div {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -200,7 +200,22 @@
|
|||
"textCrossesValue": "Crosses Value",
|
||||
"textOnTickMarks": "On Tick Marks",
|
||||
"textBetweenTickMarks": "Between Tick Marks",
|
||||
"textAxisPosition": "Axis Position"
|
||||
"textAxisPosition": "Axis Position",
|
||||
"textHyperlink": "Hyperlink",
|
||||
"textLinkType": "Link Type",
|
||||
"textLink": "Link",
|
||||
"textSheet": "Sheet",
|
||||
"textRange": "Range",
|
||||
"textDisplay": "Display",
|
||||
"textScreenTip": "Screen Tip",
|
||||
"textEditLink": "Edit Link",
|
||||
"textRemoveLink": "Remove Link",
|
||||
"textRequired": "Required",
|
||||
"textInternalDataRange": "Internal Data Range",
|
||||
"textExternalLink": "External Link",
|
||||
"textDefault": "Selected range",
|
||||
"textInvalidRange": "Invalid cells range",
|
||||
"txtNotUrl": "This field should be a URL in the format \"http://www.example.com\""
|
||||
}
|
||||
},
|
||||
"Common": {
|
||||
|
|
145
apps/spreadsheeteditor/mobile/src/controller/edit/EditLink.jsx
Normal file
145
apps/spreadsheeteditor/mobile/src/controller/edit/EditLink.jsx
Normal file
|
@ -0,0 +1,145 @@
|
|||
import React, { Component } from 'react';
|
||||
import { f7 } from 'framework7-react';
|
||||
import { Device } from '../../../../../common/mobile/utils/device';
|
||||
import {observer, inject} from "mobx-react";
|
||||
import { withTranslation } from 'react-i18next';
|
||||
|
||||
import { EditLink } from '../../view/edit/EditLink';
|
||||
|
||||
class EditLinkController extends Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.onEditLink = this.onEditLink.bind(this);
|
||||
this.onRemoveLink = this.onRemoveLink.bind(this);
|
||||
|
||||
const api = Common.EditorApi.get();
|
||||
const cellInfo = api.asc_getCellInfo();
|
||||
|
||||
this.linkInfo = cellInfo.asc_getHyperlink();
|
||||
this.isLock = cellInfo.asc_getLockText();
|
||||
this.currentSheet = api.asc_getWorksheetName(api.asc_getActiveWorksheetIndex());
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
closeModal () {
|
||||
if ( Device.phone ) {
|
||||
f7.sheet.close('#edit-sheet', true);
|
||||
} else {
|
||||
f7.popover.close('#edit-popover');
|
||||
}
|
||||
}
|
||||
|
||||
onEditLink(args) {
|
||||
const api = Common.EditorApi.get();
|
||||
const { t } = this.props;
|
||||
const _t = t("View.Edit", {returnObjects: true});
|
||||
|
||||
let linkProps = new Asc.asc_CHyperlink(),
|
||||
sheet = "",
|
||||
displayText = args.text,
|
||||
tip = args.tooltip,
|
||||
defaultDisplay = "";
|
||||
|
||||
linkProps.asc_setType(args.type);
|
||||
|
||||
if(args.type === Asc.c_oAscHyperlinkType.RangeLink) {
|
||||
let range = args.url,
|
||||
isValidRange = /^[A-Z]+[1-9]\d*:[A-Z]+[1-9]\d*$/.test(range);
|
||||
|
||||
if (!isValidRange)
|
||||
isValidRange = /^[A-Z]+[1-9]\d*$/.test(range);
|
||||
|
||||
if (!isValidRange) {
|
||||
f7.dialog.alert(_t.textInvalidRange, _t.notcriticalErrorTitle);
|
||||
return;
|
||||
}
|
||||
|
||||
sheet = args.sheet;
|
||||
|
||||
linkProps.asc_setSheet(sheet);
|
||||
linkProps.asc_setRange(range);
|
||||
defaultDisplay = sheet + '!' + range;
|
||||
} else {
|
||||
let url = args.url.replace(/^\s+|\s+$/g,'');
|
||||
|
||||
if (! /(((^https?)|(^ftp)):\/\/)|(^mailto:)/i.test(url)) {
|
||||
let urlType = api.asc_getUrlType(url.trim());
|
||||
|
||||
if (urlType < 1) {
|
||||
f7.dialog.alert(_t.txtNotUrl, _t.notcriticalErrorTitle);
|
||||
return;
|
||||
}
|
||||
|
||||
url = ( (urlType == 2) ? 'mailto:' : 'http://' ) + url;
|
||||
}
|
||||
|
||||
url = url.replace(new RegExp("%20",'g')," ");
|
||||
|
||||
linkProps.asc_setHyperlinkUrl(url);
|
||||
defaultDisplay = url;
|
||||
}
|
||||
|
||||
if (this.isLock) {
|
||||
linkProps.asc_setText(null);
|
||||
} else {
|
||||
if (!displayText) {
|
||||
displayText = defaultDisplay;
|
||||
}
|
||||
linkProps.asc_setText(displayText);
|
||||
}
|
||||
|
||||
linkProps.asc_setTooltip(tip);
|
||||
|
||||
api.asc_insertHyperlink(linkProps);
|
||||
this.closeModal();
|
||||
|
||||
}
|
||||
|
||||
onRemoveLink() {
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_removeHyperlink();
|
||||
this.closeModal();
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<EditLink
|
||||
linkInfo={this.linkInfo}
|
||||
isLock={this.isLock}
|
||||
sheets={this.sheets}
|
||||
activeSheet={this.activeSheet}
|
||||
currentSheet={this.currentSheet}
|
||||
onEditLink={this.onEditLink}
|
||||
onRemoveLink={this.onRemoveLink}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const EditLinkWithTranslation = withTranslation()(EditLinkController);
|
||||
|
||||
export {EditLinkWithTranslation as EditLinkController};
|
|
@ -10,12 +10,14 @@ import EditShapeController from "../../controller/edit/EditShape";
|
|||
import EditImageController from "../../controller/edit/EditImage";
|
||||
import EditTextController from "../../controller/edit/EditText";
|
||||
import EditChartController from "../../controller/edit/EditChart";
|
||||
import { EditLinkController } from "../../controller/edit/EditLink";
|
||||
|
||||
import { PageShapeStyle, PageShapeStyleNoFill, PageReplaceContainer, PageReorderContainer, PageShapeBorderColor, PageShapeCustomBorderColor, PageShapeCustomFillColor } from './EditShape';
|
||||
import { PageImageReplace, PageImageReorder, PageLinkSettings } from './EditImage';
|
||||
import { TextColorCell, FillColorCell, CustomTextColorCell, CustomFillColorCell, FontsCell, TextFormatCell, TextOrientationCell, BorderStyleCell, BorderColorCell, CustomBorderColorCell, BorderSizeCell, PageFormatCell, PageAccountingFormatCell, PageCurrencyFormatCell, PageDateFormatCell, PageTimeFormatCell } from './EditCell';
|
||||
import { PageTextFonts, PageTextFontColor, PageTextCustomFontColor } from './EditText';
|
||||
import { PageChartStyle, PageChartCustomFillColor, PageChartBorderColor, PageChartCustomBorderColor, PageChartReorder, PageChartLayout, PageChartLegend, PageChartTitle, PageChartHorizontalAxisTitle, PageChartVerticalAxisTitle, PageChartHorizontalGridlines, PageChartVerticalGridlines, PageChartDataLabels, PageChartVerticalAxis, PageChartVertAxisCrosses, PageChartDisplayUnits, PageChartVertMajorType, PageChartVertMinorType, PageChartVertLabelPosition, PageChartHorizontalAxis, PageChartHorAxisCrosses, PageChartHorAxisPosition, PageChartHorMajorType, PageChartHorMinorType, PageChartHorLabelPosition } from './EditChart';
|
||||
import { PageTypeLink, PageSheet } from './EditLink';
|
||||
|
||||
const routes = [
|
||||
|
||||
|
@ -254,6 +256,17 @@ const routes = [
|
|||
{
|
||||
path: '/edit-hor-label-position/',
|
||||
component: PageChartHorLabelPosition
|
||||
},
|
||||
|
||||
// Link
|
||||
|
||||
{
|
||||
path: '/edit-link-type/',
|
||||
component: PageTypeLink
|
||||
},
|
||||
{
|
||||
path: '/edit-link-sheet',
|
||||
component: PageSheet
|
||||
}
|
||||
|
||||
|
||||
|
@ -361,6 +374,13 @@ const EditTabs = props => {
|
|||
component: <EditChartController />
|
||||
})
|
||||
}
|
||||
if (settings.indexOf('hyperlink') > -1) {
|
||||
editors.push({
|
||||
caption: _t.textHyperlink,
|
||||
id: 'edit-link',
|
||||
component: <EditLinkController />
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
@ -606,7 +606,7 @@ const PageDataLabels = props => {
|
|||
const PageVerticalAxis = props => {
|
||||
const { t } = useTranslation();
|
||||
const _t = t('View.Edit', {returnObjects: true});
|
||||
const isAndroid = Device.android;
|
||||
const isIos = Device.ios;
|
||||
const storeChartSettings = props.storeChartSettings;
|
||||
const axisProps = props.initVertAxis();
|
||||
const crossValue = axisProps.getCrossesRule();
|
||||
|
@ -694,41 +694,42 @@ const PageVerticalAxis = props => {
|
|||
return (
|
||||
<Page>
|
||||
<Navbar title={_t.textAxisOptions} backLink={_t.textBack} />
|
||||
<List className={isAndroid ? "inputs-list": ""}>
|
||||
<ListItem title={_t.textMinimumValue}>
|
||||
<div slot="after">
|
||||
<div className="item-input">
|
||||
<input type="number" className="field right placeholder-color" value={minValue}
|
||||
<List inlineLabels className="inputs-list">
|
||||
<ListInput
|
||||
label={_t.textMinimumValue}
|
||||
type="number"
|
||||
placeholder="Auto"
|
||||
value={minValue}
|
||||
onChange={e => props.onVerAxisMinValue(e.target.value)}
|
||||
onInput={e => setMinValue(e.target.value)} placeholder="Auto" />
|
||||
</div>
|
||||
</div>
|
||||
</ListItem>
|
||||
<ListItem title={_t.textMaximumValue}>
|
||||
<div slot="after">
|
||||
<div className="item-input">
|
||||
<input type="number" className="field right placeholder-color" value={maxValue}
|
||||
onInput={e => setMinValue(e.target.value)}
|
||||
className={isIos ? 'list-input-right' : ''}
|
||||
/>
|
||||
|
||||
<ListInput
|
||||
label={_t.textMaximumValue}
|
||||
type="number"
|
||||
placeholder="Auto"
|
||||
value={maxValue}
|
||||
onChange={e => props.onVerAxisMaxValue(e.target.value)}
|
||||
onInput={e => setMaxValue(e.target.value)} placeholder="Auto" />
|
||||
</div>
|
||||
</div>
|
||||
</ListItem>
|
||||
onInput={e => setMaxValue(e.target.value)}
|
||||
className={isIos ? 'list-input-right' : ''}
|
||||
/>
|
||||
</List>
|
||||
<List className={isAndroid ? "inputs-list": ""}>
|
||||
<List inlineLabels className="inputs-list">
|
||||
<ListItem title={_t.textAxisCrosses} link="/edit-vert-axis-crosses/" after={storeChartSettings.axisVertCrosses.display} routeProps={{
|
||||
axisCrosses,
|
||||
onVerAxisCrossType: props.onVerAxisCrossType
|
||||
}}></ListItem>
|
||||
{storeChartSettings.axisVertCrosses.value == Asc.c_oAscCrossesRule.value ? (
|
||||
<ListItem title={_t.textCrossesValue}>
|
||||
<div slot="after">
|
||||
<div className="item-input">
|
||||
<input type="number" className="field right placeholder-color" value={crossesValue}
|
||||
<ListInput
|
||||
label={_t.textCrossesValue}
|
||||
type="number"
|
||||
placeholder="0"
|
||||
value={crossesValue}
|
||||
onChange={e => props.onVerAxisCrossValue(e.target.value)}
|
||||
onInput={e => setCrossesValue(e.target.value)} placeholder="0" />
|
||||
</div>
|
||||
</div>
|
||||
</ListItem>
|
||||
onInput={e => setCrossesValue(e.target.value)}
|
||||
className={isIos ? 'list-input-right' : ''}
|
||||
/>
|
||||
) : null}
|
||||
</List>
|
||||
<List>
|
||||
|
@ -993,15 +994,15 @@ const PageHorizontalAxis = props => {
|
|||
onHorAxisCrossType: props.onHorAxisCrossType
|
||||
}}></ListItem>
|
||||
{storeChartSettings.axisHorCrosses.value == Asc.c_oAscCrossesRule.value ? (
|
||||
<ListItem title={_t.textCrossesValue}>
|
||||
<div slot="after">
|
||||
<div className="item-input">
|
||||
<input type="number" className="field right placeholder-color" value={crossesValue}
|
||||
<ListInput
|
||||
label={_t.textCrossesValue}
|
||||
type="text"
|
||||
placeholder="0"
|
||||
value={crossesValue}
|
||||
onChange={e => props.onHorAxisCrossValue(e.target.value)}
|
||||
onInput={e => setCrossesValue(e.target.value)} placeholder="0" />
|
||||
</div>
|
||||
</div>
|
||||
</ListItem>
|
||||
onInput={e => setCrossesValue(e.target.value)}
|
||||
className={isIos ? 'list-input-right' : ''}
|
||||
/>
|
||||
) : null}
|
||||
</List>
|
||||
<List>
|
||||
|
|
153
apps/spreadsheeteditor/mobile/src/view/edit/EditLink.jsx
Normal file
153
apps/spreadsheeteditor/mobile/src/view/edit/EditLink.jsx
Normal file
|
@ -0,0 +1,153 @@
|
|||
import React, {useState, useEffect, Fragment} from 'react';
|
||||
import {observer, inject} from "mobx-react";
|
||||
import {List, ListItem, Page, Navbar, Icon, ListButton, ListInput, Segmented, Button} 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.Edit', {returnObjects: true});
|
||||
const [typeLink, setTypeLink] = useState(curType);
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<Navbar title={_t.textLinkType} backLink={_t.textBack}/>
|
||||
<List>
|
||||
<ListItem title={_t.textExternalLink} radio checked={typeLink === 1} onClick={() => {setTypeLink(1); changeType(1);}}></ListItem>
|
||||
<ListItem title={_t.textInternalDataRange} radio checked={typeLink === 2} onClick={() => {setTypeLink(2); changeType(2);}}></ListItem>
|
||||
</List>
|
||||
</Page>
|
||||
)
|
||||
};
|
||||
|
||||
const PageSheet = ({curSheet, sheets, changeSheet}) => {
|
||||
const { t } = useTranslation();
|
||||
const _t = t('View.Edit', {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 EditLink = props => {
|
||||
const isIos = Device.ios;
|
||||
const { t } = useTranslation();
|
||||
const _t = t('View.Edit', {returnObjects: true});
|
||||
const linkInfo = props.linkInfo;
|
||||
const isLock = props.isLock;
|
||||
const sheets = props.sheets;
|
||||
const activeSheet = props.activeSheet;
|
||||
const currentSheet = props.currentSheet;
|
||||
const valueLinkInfo = linkInfo.asc_getType();
|
||||
const linkSheet = (valueLinkInfo == Asc.c_oAscHyperlinkType.RangeLink) ? linkInfo.asc_getSheet() : currentSheet;
|
||||
|
||||
const [typeLink, setTypeLink] = useState(valueLinkInfo);
|
||||
const textType = typeLink != Asc.c_oAscHyperlinkType.RangeLink ? _t.textExternalLink : _t.textInternalDataRange;
|
||||
const changeType = (newType) => {
|
||||
setTypeLink(newType);
|
||||
};
|
||||
|
||||
const [link, setLink] = useState(linkInfo.asc_getHyperlinkUrl() ? linkInfo.asc_getHyperlinkUrl().replace(new RegExp(" ", 'g'), "%20") : '');
|
||||
|
||||
const displayText = isLock ? _t.textDefault : linkInfo.asc_getText();
|
||||
const [stateDisplayText, setDisplayText] = useState(displayText);
|
||||
|
||||
const [screenTip, setScreenTip] = useState(linkInfo.asc_getTooltip());
|
||||
|
||||
const [curSheet, setSheet] = useState(activeSheet);
|
||||
const changeSheet = (sheet) => {
|
||||
setSheet(sheet);
|
||||
};
|
||||
|
||||
const valueRange = linkInfo.asc_getRange();
|
||||
const [range, setRange] = useState(valueRange || '');
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<List inlineLabels className='inputs-list'>
|
||||
<ListItem link={'/edit-link-type/'} title={_t.textLinkType} after={textType} routeProps={{
|
||||
changeType: changeType,
|
||||
curType: typeLink
|
||||
}}/>
|
||||
{typeLink != Asc.c_oAscHyperlinkType.RangeLink &&
|
||||
<ListInput label={_t.textLink}
|
||||
type="text"
|
||||
placeholder={_t.textLink}
|
||||
value={link}
|
||||
onChange={(event) => {setLink(event.target.value)}}
|
||||
className={isIos ? 'list-input-right' : ''}
|
||||
/>
|
||||
}
|
||||
{typeLink == Asc.c_oAscHyperlinkType.RangeLink &&
|
||||
<ListItem link={'/edit-link-sheet/'} title={_t.textSheet} after={linkSheet} routeProps={{
|
||||
changeSheet: changeSheet,
|
||||
sheets,
|
||||
curSheet
|
||||
}}/>
|
||||
}
|
||||
{typeLink == Asc.c_oAscHyperlinkType.RangeLink &&
|
||||
<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={isLock}
|
||||
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.textEditLink}
|
||||
className={`button-fill button-raised${(typeLink === 'ext' && link.length < 1 || typeLink === 'int' && range.length < 1) && ' disabled'}`}
|
||||
onClick={() => {props.onEditLink(typeLink === 1 ?
|
||||
{type: 1, url: link, text: stateDisplayText, tooltip: screenTip} :
|
||||
{type: 2, url: range, sheet: curSheet.caption, text: stateDisplayText, tooltip: screenTip})}}
|
||||
/>
|
||||
<ListButton title={_t.textRemoveLink}
|
||||
className={`button-fill button-red`}
|
||||
onClick={() => props.onRemoveLink()}
|
||||
/>
|
||||
</List>
|
||||
</Fragment>
|
||||
)
|
||||
};
|
||||
|
||||
export {
|
||||
EditLink,
|
||||
PageTypeLink,
|
||||
PageSheet
|
||||
};
|
Loading…
Reference in a new issue