Extracted strings and fixes on localization support
Language chooser in the UI
This commit is contained in:
parent
9f449c0a2f
commit
dc7789c17b
126 changed files with 2919 additions and 2028 deletions
6
client/src/lib/bootstrap-components.js
vendored
6
client/src/lib/bootstrap-components.js
vendored
|
|
@ -1,11 +1,11 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { translate } from 'react-i18next';
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from './error-handling';
|
||||
|
||||
@translate()
|
||||
@withTranslation()
|
||||
@withErrorHandling
|
||||
class DismissibleAlert extends Component {
|
||||
static propTypes = {
|
||||
|
|
@ -192,7 +192,7 @@ class ActionLink extends Component {
|
|||
}
|
||||
|
||||
|
||||
@translate()
|
||||
@withTranslation()
|
||||
@withErrorHandling
|
||||
class ModalDialog extends Component {
|
||||
constructor(props) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import React, {Component} from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import {translate} from "react-i18next";
|
||||
import { withTranslation } from './i18n';
|
||||
import {
|
||||
requiresAuthenticatedUser,
|
||||
Title
|
||||
|
|
@ -16,7 +16,7 @@ import styles from "./styles.scss";
|
|||
import {withPageHelpers} from "./page";
|
||||
import {getUrl, getPublicUrl} from "./urls";
|
||||
|
||||
@translate()
|
||||
@withTranslation()
|
||||
@withErrorHandling
|
||||
@withPageHelpers
|
||||
@requiresAuthenticatedUser
|
||||
|
|
@ -50,22 +50,22 @@ export default class Files extends Component {
|
|||
const t = this.props.t;
|
||||
const details = [];
|
||||
if (response.data.added) {
|
||||
details.push(t('files.filesAdded', {count: response.data.added}));
|
||||
details.push(t('countFileAdded', {count: response.data.added}));
|
||||
}
|
||||
if (response.data.replaced) {
|
||||
details.push(t('files.filesReplaced', {count: response.data.replaced}));
|
||||
details.push(t('countFileReplaced', {count: response.data.replaced}));
|
||||
}
|
||||
if (response.data.ignored) {
|
||||
details.push(t('files.filesIgnored', {count: response.data.ignored}));
|
||||
details.push(t('countFileIgnored', {count: response.data.ignored}));
|
||||
}
|
||||
const detailsMessage = details ? ' (' + details.join(', ') + ')' : '';
|
||||
return t('files.filesUploaded', {count: response.data.uploaded}) + detailsMessage;
|
||||
return t('countFileUploaded', {count: response.data.uploaded}) + detailsMessage;
|
||||
}
|
||||
|
||||
onDrop(files){
|
||||
const t = this.props.t;
|
||||
if (files.length > 0) {
|
||||
this.setFlashMessage('info', t('files.uploadingFiles', {count: files.length}));
|
||||
this.setFlashMessage('info', t('uploadingCountFile', {count: files.length}));
|
||||
const data = new FormData();
|
||||
for (const file of files) {
|
||||
data.append('files[]', file)
|
||||
|
|
@ -76,10 +76,10 @@ export default class Files extends Component {
|
|||
const message = this.getFilesUploadedMessage(res);
|
||||
this.setFlashMessage('info', message);
|
||||
})
|
||||
.catch(res => this.setFlashMessage('danger', t('files.fileUploadFailed') + ' ' + res.message));
|
||||
.catch(res => this.setFlashMessage('danger', t('fileUploadFailed') + ' ' + res.message));
|
||||
}
|
||||
else{
|
||||
this.setFlashMessage('info', t('files.noFilesToUpload'));
|
||||
this.setFlashMessage('info', t('noFilesToUpload'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -97,13 +97,13 @@ export default class Files extends Component {
|
|||
await this.hideDeleteFile();
|
||||
|
||||
try {
|
||||
this.setFlashMessage('info', t('files.deletingFile'));
|
||||
this.setFlashMessage('info', t('deletingFile'));
|
||||
await axios.delete(getUrl(`rest/files/${this.props.entityTypeId}/${this.props.entitySubTypeId}/${fileToDeleteId}`));
|
||||
this.filesTable.refresh();
|
||||
this.setFlashMessage('info', t('files.fileDeleted'));
|
||||
this.setFlashMessage('info', t('fileDeleted'));
|
||||
} catch (err) {
|
||||
this.filesTable.refresh();
|
||||
this.setFlashMessage('danger', t('files.deleteFileFailed') + ' ' + err.message);
|
||||
this.setFlashMessage('danger', t('deleteFileFailed') + ' ' + err.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,13 +145,13 @@ export default class Files extends Component {
|
|||
<div>
|
||||
<ModalDialog
|
||||
hidden={this.state.fileToDeleteId === null}
|
||||
title={t('files.confirmFileDeletion')}
|
||||
title={t('confirmFileDeletion')}
|
||||
onCloseAsync={::this.hideDeleteFile}
|
||||
buttons={[
|
||||
{ label: t('no'), className: 'btn-primary', onClickAsync: ::this.hideDeleteFile },
|
||||
{ label: t('yes'), className: 'btn-danger', onClickAsync: ::this.performDeleteFile }
|
||||
]}>
|
||||
{t('files:areYouSureToDeleteFile', {name: this.state.fileToDeleteName})}
|
||||
{t('filesareYouSureToDeleteFile', {name: this.state.fileToDeleteName})}
|
||||
</ModalDialog>
|
||||
|
||||
{this.props.title && <Title>{this.props.title}</Title>}
|
||||
|
|
@ -161,7 +161,7 @@ export default class Files extends Component {
|
|||
{
|
||||
this.props.entity.permissions.includes(this.props.managePermission) &&
|
||||
<Dropzone onDrop={::this.onDrop} className={styles.dropZone} activeClassName={styles.dropZoneActive}>
|
||||
{state => state.isDragActive ? t('files.dropFiles', {count: state.draggedFiles.length}) : t('files.dropFilesHere')}
|
||||
{state => state.isDragActive ? t('dropCountFile', {count: state.draggedFiles.length}) : t('dropFilesHere')}
|
||||
</Dropzone>
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from './i18n';
|
||||
import axios, {HTTPMethod} from './axios';
|
||||
import Immutable from 'immutable';
|
||||
import { translate } from 'react-i18next';
|
||||
import PropTypes from 'prop-types';
|
||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
||||
import { withPageHelpers } from './page'
|
||||
|
|
@ -36,7 +36,7 @@ const FormState = {
|
|||
|
||||
const FormSendMethod = HTTPMethod;
|
||||
|
||||
@translate()
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
class Form extends Component {
|
||||
|
|
@ -462,7 +462,7 @@ class TextArea extends Component {
|
|||
}
|
||||
|
||||
|
||||
@translate()
|
||||
@withTranslation()
|
||||
class DatePicker extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -568,7 +568,7 @@ class DatePicker extends Component {
|
|||
<div>
|
||||
<div className="input-group">
|
||||
<input type="text" value={selectedDateStr} placeholder={placeholder} id={htmlId} className="form-control" aria-describedby={htmlId + '_help'} onChange={evt => owner.updateFormValue(id, evt.target.value)}/>
|
||||
<span className="input-group-addon" onClick={::this.toggleDayPicker}><Icon icon="calendar" title={t('form.openCalendar')}/></span>
|
||||
<span className="input-group-addon" onClick={::this.toggleDayPicker}><Icon icon="calendar" title={t('openCalendar')}/></span>
|
||||
</div>
|
||||
{this.state.opened &&
|
||||
<div className={styles.dayPickerWrapper}>
|
||||
|
|
@ -712,7 +712,7 @@ class TreeTableSelect extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@translate(null, { withRef: true })
|
||||
@withTranslation({delegateFuns: ['refresh']})
|
||||
class TableSelect extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -803,7 +803,7 @@ class TableSelect extends Component {
|
|||
<input type="text" className="form-control" value={this.state.selectedLabel} onClick={::this.toggleOpen} readOnly={!props.disabled} disabled={props.disabled}/>
|
||||
{!props.disabled &&
|
||||
<span className="input-group-btn">
|
||||
<Button label={t('form.select')} className="btn-default" onClickAsync={::this.toggleOpen}/>
|
||||
<Button label={t('select')} className="btn-default" onClickAsync={::this.toggleOpen}/>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
|
@ -824,14 +824,6 @@ class TableSelect extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Refreshes the table. This method is provided to allow programmatic refresh from a handler outside the table.
|
||||
The reference to the table can be obtained by ref.
|
||||
*/
|
||||
TableSelect.prototype.refresh = function() {
|
||||
this.getWrappedInstance().refresh()
|
||||
};
|
||||
|
||||
|
||||
class ACEEditor extends Component {
|
||||
static propTypes = {
|
||||
|
|
@ -1305,8 +1297,8 @@ function withForm(target) {
|
|||
this.disableForm();
|
||||
this.setFormStatusMessage('danger',
|
||||
<span>
|
||||
<strong>{t('form.yourUpdatesCannotBeSaved')}</strong>{' '}
|
||||
{t('form.modificationsInTheMeantime')}
|
||||
<strong>{t('yourUpdatesCannotBeSaved')}</strong>{' '}
|
||||
{t('someoneElseHasIntroducedModificationIn')}
|
||||
</span>
|
||||
);
|
||||
return;
|
||||
|
|
@ -1316,8 +1308,8 @@ function withForm(target) {
|
|||
this.disableForm();
|
||||
this.setFormStatusMessage('danger',
|
||||
<span>
|
||||
<strong>{t('form.yourUpdatesCannotBeSaved')}</strong>{' '}
|
||||
{t('form.namespaceDeletedInTheMeantime')}
|
||||
<strong>{t('yourUpdatesCannotBeSaved')}</strong>{' '}
|
||||
{t('itSeemsThatSomeoneElseHasDeletedThe')}
|
||||
</span>
|
||||
);
|
||||
return;
|
||||
|
|
@ -1327,8 +1319,8 @@ function withForm(target) {
|
|||
this.disableForm();
|
||||
this.setFormStatusMessage('danger',
|
||||
<span>
|
||||
<strong>{t('form.yourUpdatesCannotBeSaved')}</strong>{' '}
|
||||
{t('form.deletionInTheMeantime')}
|
||||
<strong>{t('yourUpdatesCannotBeSaved')}</strong>{' '}
|
||||
{t('itSeemsThatSomeoneElseHasDeletedThe-1')}
|
||||
</span>
|
||||
);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,62 +1,43 @@
|
|||
import i18n from 'i18next';
|
||||
import { reactI18nextModule } from "react-i18next";
|
||||
import LanguageDetector from 'i18next-browser-languagedetector';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import {getUrl} from "./urls";
|
||||
'use strict';
|
||||
|
||||
import commonEn from "../../../locales/common/en";
|
||||
import React, {Component} from 'react';
|
||||
import i18n
|
||||
from 'i18next';
|
||||
import {withNamespaces} from "react-i18next";
|
||||
import LanguageDetector
|
||||
from 'i18next-browser-languagedetector';
|
||||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
|
||||
function convertToFake(dict) {
|
||||
function convertValueToFakeLang(str) {
|
||||
let from = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+\\|`~[{]};:'\",<.>/?";
|
||||
let to = "ɐqɔpǝɟƃɥıɾʞʅɯuodbɹsʇnʌʍxʎz∀ԐↃᗡƎℲ⅁HIſӼ⅂WNOԀÒᴚS⊥∩ɅMX⅄Z0123456789¡@#$%ᵥ⅋⁎()-_=+\\|,~[{]};:,„´<.>/¿";
|
||||
import hoistStatics
|
||||
from 'hoist-non-react-statics';
|
||||
|
||||
return str.replace(/(\{\{[^\}]+\}\}|%s)/g, '\x00\x04$1\x00').split('\x00').map(c => {
|
||||
if (c.charAt(0) === '\x04') {
|
||||
return c;
|
||||
}
|
||||
let r = '';
|
||||
for (let i = 0, len = c.length; i < len; i++) {
|
||||
let pos = from.indexOf(c.charAt(i));
|
||||
if (pos < 0) {
|
||||
r += c.charAt(i);
|
||||
} else {
|
||||
r += to.charAt(pos);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}).join('\x00').replace(/[\x00\x04]/g, '');
|
||||
}
|
||||
import {convertToFake, langCodes} from '../../../shared/langs';
|
||||
|
||||
function _convertToFake(dict) {
|
||||
for (const key in dict) {
|
||||
const val = dict[key];
|
||||
import commonEn from "../../../locales/en/common";
|
||||
import commonEs from "../../../locales/es/common";
|
||||
|
||||
if (typeof val === 'string') {
|
||||
dict[key] = convertValueToFakeLang(val);
|
||||
} else {
|
||||
_convertToFake(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
const resourcesCommon = {
|
||||
en: commonEn,
|
||||
es: commonEs,
|
||||
fake: convertToFake(commonEn)
|
||||
};
|
||||
|
||||
return _convertToFake(dict);
|
||||
const resources = {};
|
||||
for (const lng of mailtrainConfig.enabledLanguages) {
|
||||
const shortCode = langCodes[lng].shortCode;
|
||||
resources[shortCode] = {
|
||||
common: resourcesCommon[shortCode]
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
i18n
|
||||
.use(LanguageDetector)
|
||||
.init({
|
||||
lng: mailtrainConfig.language,
|
||||
resources: {
|
||||
en: {
|
||||
common: commonEn
|
||||
},
|
||||
en_fake: {
|
||||
common: convertToFake(commonEn)
|
||||
}
|
||||
},
|
||||
resources,
|
||||
|
||||
fallbackLng: "en",
|
||||
fallbackLng: mailtrainConfig.defaultLanguage,
|
||||
defaultNS: 'common',
|
||||
|
||||
interpolation: {
|
||||
|
|
@ -79,4 +60,35 @@ i18n
|
|||
})
|
||||
|
||||
|
||||
export default i18n;
|
||||
export default i18n;
|
||||
|
||||
|
||||
export function withTranslation(opts) {
|
||||
if (opts && opts.delegateFuns) {
|
||||
return function (WrappedComponent) {
|
||||
class Wrapper extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.WrappedComponentWithNamespaces = withNamespaces(null, {innerRef: ref => this.wrappedComponent = ref})(WrappedComponent);
|
||||
}
|
||||
|
||||
render() {
|
||||
const WrappedComponentWithNamespaces = this.WrappedComponentWithNamespaces;
|
||||
return <WrappedComponentWithNamespaces {...this.props}/>;
|
||||
}
|
||||
}
|
||||
|
||||
for (const fun of opts.delegateFuns) {
|
||||
Wrapper.prototype[fun] = function (...args) {
|
||||
return this.wrappedComponent[fun](...args);
|
||||
}
|
||||
}
|
||||
|
||||
return hoistStatics(Wrapper, WrappedComponent);
|
||||
}
|
||||
} else {
|
||||
return withNamespaces();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
import axios, { HTTPMethod } from './axios';
|
||||
import { translate } from 'react-i18next';
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Icon,
|
||||
|
|
@ -14,7 +14,7 @@ import styles from './styles.scss';
|
|||
import interoperableErrors from '../../../shared/interoperable-errors';
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
@translate()
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
export class RestActionModalDialog extends Component {
|
||||
static propTypes = {
|
||||
|
|
@ -97,7 +97,7 @@ export class RestActionModalDialog extends Component {
|
|||
}
|
||||
|
||||
|
||||
@translate()
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
export class DeleteModalDialog extends Component {
|
||||
constructor(props) {
|
||||
|
|
@ -145,7 +145,7 @@ export class DeleteModalDialog extends Component {
|
|||
const name = this.props.name !== undefined ? this.props.name : (owner ? owner.getFormValue('name') : '');
|
||||
this.setFlashMessage('danger',
|
||||
<div>
|
||||
<p>{t('deleteDialog.cannotDeleteDueToDependencies', {name})}</p>
|
||||
<p>{t('cannoteDeleteNameDueToTheFollowing', {name})}</p>
|
||||
<ul className={styles.dependenciesList}>
|
||||
{err.data.dependencies.map(dep =>
|
||||
dep.link ?
|
||||
|
|
@ -153,7 +153,7 @@ export class DeleteModalDialog extends Component {
|
|||
: // if no dep.link is present, it means the user has no permission to view the entity, thus only id without the link is shown
|
||||
<li key={dep.id}>{this.entityTypeLabels[dep.entityTypeId]}: [{dep.id}]</li>
|
||||
)}
|
||||
{err.data.andMore && <li>{t('deleteDialog.andMore')}</li>}
|
||||
{err.data.andMore && <li>{t('andMore')}</li>}
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -180,8 +180,8 @@ export class DeleteModalDialog extends Component {
|
|||
const name = this.props.name !== undefined ? this.props.name : (owner ? owner.getFormValue('name') : '');
|
||||
|
||||
return <RestActionModalDialog
|
||||
title={t('deleteDialog.confirmDeletion')}
|
||||
message={t('deleteDialog.areYouSureToDelete', {name})}
|
||||
title={t('confirmDeletion')}
|
||||
message={t('areYouSureYouWantToDeleteName?', {name})}
|
||||
stateOwner={this.props.stateOwner}
|
||||
visible={this.props.visible}
|
||||
actionMethod={HTTPMethod.DELETE}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { translate } from 'react-i18next';
|
||||
import { withTranslation } from './i18n';
|
||||
import { TreeTableSelect } from './form';
|
||||
|
||||
|
||||
@translate()
|
||||
@withTranslation()
|
||||
class NamespaceSelect extends Component {
|
||||
render() {
|
||||
const t = this.props.t;
|
||||
|
|
@ -18,7 +18,7 @@ class NamespaceSelect extends Component {
|
|||
|
||||
function validateNamespace(t, state) {
|
||||
if (!state.getIn(['namespace', 'value'])) {
|
||||
state.setIn(['namespace', 'error'], t('namespace.mustBeSelected'));
|
||||
state.setIn(['namespace', 'error'], t('namespacemustBeSelected'));
|
||||
} else {
|
||||
state.setIn(['namespace', 'error'], null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from "react";
|
||||
import {translate} from "react-i18next";
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes from "prop-types";
|
||||
import {withRouter} from "react-router";
|
||||
import {BrowserRouter as Router, Link, Redirect, Route, Switch} from "react-router-dom";
|
||||
|
|
@ -14,6 +14,10 @@ import {getRoutes, needsResolve, resolve, withPageHelpers} from "./page-common";
|
|||
import {getBaseDir} from "./urls";
|
||||
|
||||
class Breadcrumb extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
route: PropTypes.object.isRequired,
|
||||
params: PropTypes.object.isRequired,
|
||||
|
|
@ -67,6 +71,7 @@ class Breadcrumb extends Component {
|
|||
|
||||
class SecondaryNavBar extends Component {
|
||||
static propTypes = {
|
||||
route: PropTypes.object.isRequired,
|
||||
params: PropTypes.object.isRequired,
|
||||
resolved: PropTypes.object.isRequired,
|
||||
className: PropTypes.string
|
||||
|
|
@ -144,7 +149,7 @@ class SecondaryNavBar extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@translate()
|
||||
@withTranslation()
|
||||
@withErrorHandling
|
||||
class RouteContent extends Component {
|
||||
constructor(props) {
|
||||
|
|
@ -367,17 +372,10 @@ class SectionContent extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@translate()
|
||||
@withTranslation()
|
||||
class Section extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
let structure = props.structure;
|
||||
if (typeof structure === 'function') {
|
||||
structure = structure(props.t);
|
||||
}
|
||||
|
||||
this.structure = structure;
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
|
|
@ -386,9 +384,14 @@ class Section extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
let structure = this.props.structure;
|
||||
if (typeof structure === 'function') {
|
||||
structure = structure(this.props.t);
|
||||
}
|
||||
|
||||
return (
|
||||
<Router basename={getBaseDir()}>
|
||||
<SectionContent root={this.props.root} structure={this.structure} />
|
||||
<SectionContent root={this.props.root} structure={structure} />
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,8 @@ import './public-path';
|
|||
import React, {Component} from 'react';
|
||||
import ReactDOM
|
||||
from 'react-dom';
|
||||
import {
|
||||
I18nextProvider,
|
||||
translate,
|
||||
} from 'react-i18next';
|
||||
import i18n
|
||||
from './i18n';
|
||||
import {I18nextProvider} from 'react-i18next';
|
||||
import i18n, {withTranslation} from './i18n';
|
||||
import {
|
||||
parentRPC,
|
||||
UntrustedContentRoot
|
||||
|
|
@ -32,10 +28,10 @@ import {
|
|||
import CKEditor
|
||||
from "react-ckeditor-component";
|
||||
|
||||
import { initialHeight } from "./sandboxed-ckeditor-shared";
|
||||
import {initialHeight} from "./sandboxed-ckeditor-shared";
|
||||
|
||||
|
||||
@translate(null, { withRef: true })
|
||||
@withTranslation()
|
||||
class CKEditorSandbox extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {translate} from 'react-i18next';
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import styles
|
||||
|
|
@ -14,7 +14,7 @@ import {getTrustedUrl} from "./urls";
|
|||
import { initialHeight } from "./sandboxed-ckeditor-shared";
|
||||
const navbarHeight = 34; // Sync this with navbarheight in sandboxed-ckeditor.scss
|
||||
|
||||
@translate(null, { withRef: true })
|
||||
@withTranslation({delegateFuns: ['exportState']})
|
||||
export class CKEditorHost extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -97,9 +97,3 @@ export class CKEditorHost extends Component {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
CKEditorHost.prototype.exportState = async function() {
|
||||
return await this.getWrappedInstance().exportState();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,8 @@ import './public-path';
|
|||
import React, {Component} from 'react';
|
||||
import ReactDOM
|
||||
from 'react-dom';
|
||||
import {
|
||||
I18nextProvider,
|
||||
translate,
|
||||
} from 'react-i18next';
|
||||
import i18n
|
||||
from './i18n';
|
||||
import {I18nextProvider} from 'react-i18next';
|
||||
import i18n, {withTranslation} from './i18n';
|
||||
import {
|
||||
parentRPC,
|
||||
UntrustedContentRoot
|
||||
|
|
@ -28,20 +24,21 @@ import {
|
|||
base,
|
||||
unbase
|
||||
} from "../../../shared/templates";
|
||||
|
||||
import brace from 'brace';
|
||||
import ACEEditorRaw from 'react-ace';
|
||||
import ACEEditorRaw
|
||||
from 'react-ace';
|
||||
import 'brace/theme/github';
|
||||
import 'brace/ext/searchbox';
|
||||
import 'brace/mode/html';
|
||||
import {CodeEditorSourceType} from "./sandboxed-codeeditor-shared";
|
||||
|
||||
import mjml2html from "mjml4-in-browser";
|
||||
import juice from "juice";
|
||||
import mjml2html
|
||||
from "mjml4-in-browser";
|
||||
import juice
|
||||
from "juice";
|
||||
|
||||
const refreshTimeout = 1000;
|
||||
|
||||
@translate(null, { withRef: true })
|
||||
@withTranslation()
|
||||
class CodeEditorSandbox extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {translate} from 'react-i18next';
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import styles
|
||||
|
|
@ -11,7 +11,7 @@ import {UntrustedContentHost} from './untrusted';
|
|||
import {Icon} from "./bootstrap-components";
|
||||
import {getTrustedUrl} from "./urls";
|
||||
|
||||
@translate(null, { withRef: true })
|
||||
@withTranslation({delegateFuns: ['exportState']})
|
||||
export class CodeEditorHost extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -83,7 +83,3 @@ export class CodeEditorHost extends Component {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
CodeEditorHost.prototype.exportState = async function() {
|
||||
return await this.getWrappedInstance().exportState();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,12 +5,8 @@ import './public-path';
|
|||
import React, {Component} from 'react';
|
||||
import ReactDOM
|
||||
from 'react-dom';
|
||||
import {
|
||||
I18nextProvider,
|
||||
translate,
|
||||
} from 'react-i18next';
|
||||
import i18n
|
||||
from './i18n';
|
||||
import {I18nextProvider} from 'react-i18next';
|
||||
import i18n, {withTranslation} from './i18n';
|
||||
import {
|
||||
parentRPC,
|
||||
UntrustedContentRoot
|
||||
|
|
@ -20,17 +16,18 @@ import PropTypes
|
|||
import {
|
||||
getPublicUrl,
|
||||
getSandboxUrl,
|
||||
getTrustedUrl,
|
||||
getUrl
|
||||
getTrustedUrl
|
||||
} from "./urls";
|
||||
import {
|
||||
base,
|
||||
unbase
|
||||
} from "../../../shared/templates";
|
||||
import mjml2html from "mjml4-in-browser";
|
||||
import mjml2html
|
||||
from "mjml4-in-browser";
|
||||
|
||||
import 'grapesjs/dist/css/grapes.min.css';
|
||||
import grapesjs from 'grapesjs';
|
||||
import grapesjs
|
||||
from 'grapesjs';
|
||||
|
||||
import 'grapesjs-mjml';
|
||||
|
||||
|
|
@ -39,7 +36,8 @@ import 'grapesjs-preset-newsletter/dist/grapesjs-preset-newsletter.css';
|
|||
|
||||
import "./sandboxed-grapesjs.scss";
|
||||
|
||||
import axios from './axios';
|
||||
import axios
|
||||
from './axios';
|
||||
import {GrapesJSSourceType} from "./sandboxed-grapesjs-shared";
|
||||
|
||||
|
||||
|
|
@ -54,7 +52,7 @@ grapesjs.plugins.add('mailtrain-remove-buttons', (editor, opts = {}) => {
|
|||
});
|
||||
|
||||
|
||||
@translate(null, { withRef: true })
|
||||
@withTranslation()
|
||||
export class GrapesJSSandbox extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {translate} from 'react-i18next';
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import styles
|
||||
|
|
@ -11,7 +11,7 @@ import {UntrustedContentHost} from './untrusted';
|
|||
import {Icon} from "./bootstrap-components";
|
||||
import {getTrustedUrl} from "./urls";
|
||||
|
||||
@translate(null, { withRef: true })
|
||||
@withTranslation({delegateFuns: ['exportState']})
|
||||
export class GrapesJSHost extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -73,7 +73,3 @@ export class GrapesJSHost extends Component {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
GrapesJSHost.prototype.exportState = async function() {
|
||||
return await this.getWrappedInstance().exportState();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,12 +5,8 @@ import './public-path';
|
|||
import React, {Component} from 'react';
|
||||
import ReactDOM
|
||||
from 'react-dom';
|
||||
import {
|
||||
I18nextProvider,
|
||||
translate,
|
||||
} from 'react-i18next';
|
||||
import i18n
|
||||
from './i18n';
|
||||
import {I18nextProvider} from 'react-i18next';
|
||||
import i18n, {withTranslation} from './i18n';
|
||||
import {
|
||||
parentRPC,
|
||||
UntrustedContentRoot
|
||||
|
|
@ -28,7 +24,7 @@ import {
|
|||
} from "../../../shared/templates";
|
||||
|
||||
|
||||
@translate(null, { withRef: true })
|
||||
@withTranslation()
|
||||
class MosaicoSandbox extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import {translate} from 'react-i18next';
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import styles
|
||||
|
|
@ -12,7 +12,7 @@ import {Icon} from "./bootstrap-components";
|
|||
import {getTrustedUrl} from "./urls";
|
||||
|
||||
|
||||
@translate(null, { withRef: true })
|
||||
@withTranslation({delegateFuns: ['exportState']})
|
||||
export class MosaicoHost extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -76,8 +76,3 @@ export class MosaicoHost extends Component {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
MosaicoHost.prototype.exportState = async function() {
|
||||
return await this.getWrappedInstance().exportState();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
import { translate } from 'react-i18next';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from './i18n';
|
||||
|
||||
import jQuery from 'jquery';
|
||||
|
||||
|
|
@ -28,8 +28,7 @@ const TableSelectMode = {
|
|||
MULTI: 2
|
||||
};
|
||||
|
||||
|
||||
@translate(null, { withRef: true })
|
||||
@withTranslation({delegateFuns: ['refresh']})
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
class Table extends Component {
|
||||
|
|
@ -111,7 +110,7 @@ class Table extends Component {
|
|||
|
||||
const count = this.selectionMap.size;
|
||||
if (this.selectionMap.size > 0) {
|
||||
const jqInfo = jQuery('<span>' + t('{{ count }} entries selected.', { count }) + ' </span>');
|
||||
const jqInfo = jQuery('<span>' + t('countEntriesSelected', { count }) + ' </span>');
|
||||
const jqDeselectLink = jQuery('<a href="">Deselect all.</a>').on('click', ::this.deselectAll);
|
||||
|
||||
this.jqSelectInfo.empty().append(jqInfo).append(jqDeselectLink);
|
||||
|
|
@ -404,14 +403,6 @@ class Table extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Refreshes the table. This method is provided to allow programmatic refresh from a handler outside the table.
|
||||
The reference to the table can be obtained by ref.
|
||||
*/
|
||||
Table.prototype.refresh = function() {
|
||||
this.getWrappedInstance().refresh();
|
||||
};
|
||||
|
||||
export {
|
||||
Table,
|
||||
TableSelectMode
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
import { translate } from 'react-i18next';
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import jQuery from 'jquery';
|
||||
|
|
@ -23,7 +23,7 @@ const TreeSelectMode = {
|
|||
MULTI: 2
|
||||
};
|
||||
|
||||
@translate(null, { withRef: true })
|
||||
@withTranslation({delegateFuns: ['refresh']})
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
class TreeTable extends Component {
|
||||
|
|
@ -327,8 +327,8 @@ class TreeTable extends Component {
|
|||
{props.withHeader &&
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="mt-treetable-title">{t('Name')}</th>
|
||||
{withDescription && <th>{t('Description')}</th>}
|
||||
<th className="mt-treetable-title">{t('name')}</th>
|
||||
{withDescription && <th>{t('description')}</th>}
|
||||
{actions && <th></th>}
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
@ -348,14 +348,6 @@ class TreeTable extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Refreshes the table. This method is provided to allow programmatic refresh from a handler outside the table.
|
||||
The reference to the table can be obtained by ref.
|
||||
*/
|
||||
TreeTable.prototype.refresh = function() {
|
||||
this.getWrappedInstance().refresh();
|
||||
};
|
||||
|
||||
|
||||
export {
|
||||
TreeTable,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import React, {Component} from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import {translate} from "react-i18next";
|
||||
import { withTranslation } from './i18n';
|
||||
import {
|
||||
requiresAuthenticatedUser,
|
||||
withPageHelpers
|
||||
|
|
@ -170,7 +170,7 @@ export class UntrustedContentHost extends Component {
|
|||
}
|
||||
|
||||
|
||||
@translate()
|
||||
@withTranslation()
|
||||
export class UntrustedContentRoot extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -243,7 +243,7 @@ export class UntrustedContentRoot extends Component {
|
|||
} else {
|
||||
return (
|
||||
<div>
|
||||
{t('Loading...')}
|
||||
{t('loading-1')}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue