Harmonization with IVIS
This commit is contained in:
parent
428fb9db7b
commit
397f85dac4
41 changed files with 8587 additions and 10940 deletions
2377
client/package-lock.json
generated
2377
client/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -22,17 +22,15 @@
|
|||
"dependencies": {
|
||||
"@coreui/coreui": "^2.1.4",
|
||||
"@fortawesome/fontawesome-free": "^5.6.3",
|
||||
"@material-ui/core": "^3.7.1",
|
||||
"@material-ui/icons": "^3.0.1",
|
||||
"axios": "^0.18.0",
|
||||
"datatables.net": "^1.10.19",
|
||||
"datatables.net-bs4": "^1.10.19",
|
||||
"grapesjs": "^0.14.49",
|
||||
"grapesjs": "^0.14.50",
|
||||
"grapesjs-mjml": "0.0.27",
|
||||
"grapesjs-preset-newsletter": "^0.2.20",
|
||||
"i18next": "^13.0.1",
|
||||
"i18next": "^13.1.0",
|
||||
"i18next-browser-languagedetector": "^2.2.4",
|
||||
"immutable": "^3.8.1",
|
||||
"immutable": "^4.0.0-rc.12",
|
||||
"juice": "^5.1.0",
|
||||
"mjml4-in-browser": "^1.0.1",
|
||||
"moment": "^2.23.0",
|
||||
|
@ -42,6 +40,7 @@
|
|||
"react": "^16.7.0",
|
||||
"react-ace": "^6.3.2",
|
||||
"react-ckeditor-component": "^1.1.0",
|
||||
"react-color": "^2.17.0",
|
||||
"react-day-picker": "^7.2.4",
|
||||
"react-dnd": "^7.0.2",
|
||||
"react-dnd-html5-backend": "^7.0.2",
|
||||
|
@ -49,33 +48,32 @@
|
|||
"react-dom": "^16.7.0",
|
||||
"react-dropzone": "^8.0.3",
|
||||
"react-google-charts": "^3.0.10",
|
||||
"react-i18next": "^8.4.0",
|
||||
"react-i18next": "^9.0.1",
|
||||
"react-router-dom": "^4.3.1",
|
||||
"react-sortable-tree": "^2.6.0",
|
||||
"slugify": "^1.3.4",
|
||||
"url-parse": "^1.4.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.1.5",
|
||||
"@babel/core": "^7.1.6",
|
||||
"@babel/plugin-proposal-class-properties": "^7.0.0",
|
||||
"@babel/plugin-proposal-decorators": "^7.0.0",
|
||||
"@babel/plugin-proposal-function-bind": "^7.0.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"@babel/cli": "^7.2.3",
|
||||
"@babel/core": "^7.2.2",
|
||||
"@babel/plugin-proposal-class-properties": "^7.2.3",
|
||||
"@babel/plugin-proposal-decorators": "^7.2.3",
|
||||
"@babel/plugin-proposal-function-bind": "^7.2.0",
|
||||
"@babel/preset-env": "^7.2.3",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"babel-loader": "^8.0.4",
|
||||
"clean-css-cli": "^4.2.1",
|
||||
"css-loader": "^1.0.1",
|
||||
"file-loader": "^2.0.0",
|
||||
"css-loader": "^2.1.0",
|
||||
"file-loader": "^3.0.1",
|
||||
"node-sass": "^4.11.0",
|
||||
"nodemon": "^1.18.9",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"raw-loader": "^0.5.1",
|
||||
"sass-loader": "^7.1.0",
|
||||
"style-loader": "^0.23.1",
|
||||
"url-loader": "^1.1.2",
|
||||
"webpack": "^4.25.1",
|
||||
"webpack-cli": "^3.1.2"
|
||||
"webpack": "^4.28.3",
|
||||
"webpack-cli": "^3.2.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
'use strict';
|
||||
|
||||
import csfrToken from 'csfrToken';
|
||||
import csrfToken from 'csrfToken';
|
||||
import axios from 'axios';
|
||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
||||
|
||||
const axiosInst = axios.create({
|
||||
headers: {'X-CSRF-TOKEN': csfrToken}
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': csrfToken
|
||||
}
|
||||
});
|
||||
|
||||
const axiosWrapper = {
|
||||
|
|
4
client/src/lib/bootstrap-components.js
vendored
4
client/src/lib/bootstrap-components.js
vendored
|
@ -14,7 +14,6 @@ import {withComponentMixins} from "./decorator-helpers";
|
|||
withTranslation,
|
||||
withErrorHandling
|
||||
])
|
||||
|
||||
class DismissibleAlert extends Component {
|
||||
static propTypes = {
|
||||
severity: PropTypes.string.isRequired,
|
||||
|
@ -74,6 +73,7 @@ class Button extends Component {
|
|||
icon: PropTypes.string,
|
||||
iconTitle: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
type: PropTypes.string
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ class Button extends Component {
|
|||
}
|
||||
|
||||
return (
|
||||
<button type={type} className={className} onClick={::this.onClick}>{icon}{iconSpacer}{props.label}</button>
|
||||
<button type={type} className={className} onClick={::this.onClick} title={this.props.title}>{icon}{iconSpacer}{props.label}</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
import React from "react";
|
||||
import PropTypes from 'prop-types';
|
||||
import {SectionContentContext} from "./page-common";
|
||||
import {createComponentMixin} from "./decorator-helpers";
|
||||
|
||||
function handleError(that, error) {
|
||||
|
@ -66,3 +65,12 @@ export function withAsyncErrorHandler(target, name, descriptor) {
|
|||
return descriptor;
|
||||
}
|
||||
|
||||
export function wrapWithAsyncErrorHandler(self, fn) {
|
||||
return async function () {
|
||||
try {
|
||||
await fn.apply(this, arguments)
|
||||
} catch (error) {
|
||||
handleError(self, error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ import {
|
|||
Button,
|
||||
Icon
|
||||
} from "./bootstrap-components";
|
||||
import { SketchPicker } from 'react-color';
|
||||
|
||||
import ACEEditorRaw
|
||||
from 'react-ace';
|
||||
import 'brace/theme/github';
|
||||
|
@ -494,6 +496,66 @@ class TextArea extends Component {
|
|||
}
|
||||
|
||||
|
||||
@withComponentMixins([
|
||||
withFormStateOwner
|
||||
])
|
||||
class ColorPicker extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
opened: false
|
||||
};
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
help: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
opened: !this.state.opened
|
||||
});
|
||||
}
|
||||
|
||||
selected(value) {
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
|
||||
this.setState({
|
||||
opened: false
|
||||
});
|
||||
|
||||
owner.updateFormValue(id, value.rgb);
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
const t = props.t;
|
||||
const color = owner.getFormValue(id);
|
||||
|
||||
return wrapInput(id, htmlId, owner, props.format, '', props.label, props.help,
|
||||
<div>
|
||||
<div className="input-group">
|
||||
<div className={styles.colorPickerSwatchWrapper} onClick={::this.toggle}>
|
||||
<div className={styles.colorPickerSwatchColor} style={{background: `rgba(${ color.r }, ${ color.g }, ${ color.b }, ${ color.a })`}}/>
|
||||
</div>
|
||||
</div>
|
||||
{this.state.opened &&
|
||||
<div className={styles.colorPickerWrapper}>
|
||||
<SketchPicker color={color} onChange={::this.selected} />
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withFormStateOwner
|
||||
|
@ -897,37 +959,6 @@ class ACEEditor extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
/* Excluded. It's not very useful and just eats a lot of space in the resulting JS.
|
||||
|
||||
@withComponentMixins([
|
||||
withFormStateOwner
|
||||
])
|
||||
class CKEditor extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
label: PropTypes.string,
|
||||
help: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
|
||||
height: PropTypes.string
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
|
||||
return wrapInput(id, htmlId, owner, props.format, '', props.label, props.help,
|
||||
<CKEditorRaw
|
||||
onChange={(event, editor) => owner.updateFormValue(id, editor.getData())}
|
||||
onInit={ editor => {
|
||||
editor.ui.view.editable.editableElement.style.height = props.height;
|
||||
} }
|
||||
data={owner.getFormValue(id)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
const withForm = createComponentMixin([], [], (TargetClass, InnerClass) => {
|
||||
const proto = InnerClass.prototype;
|
||||
|
@ -1378,6 +1409,7 @@ export {
|
|||
CheckBoxGroup,
|
||||
RadioGroup,
|
||||
TextArea,
|
||||
ColorPicker,
|
||||
DatePicker,
|
||||
Dropdown,
|
||||
AlignedRow,
|
||||
|
@ -1387,6 +1419,5 @@ export {
|
|||
TableSelect,
|
||||
TableSelectMode,
|
||||
ACEEditor,
|
||||
CKEditor,
|
||||
FormSendMethod
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import {convertToFake, getLang} from '../../../shared/langs';
|
|||
import {createComponentMixin} from "./decorator-helpers";
|
||||
|
||||
import lang_en_US_common from "../../../locales/en-US/common";
|
||||
import {withPageHelpers} from "./page-common";
|
||||
|
||||
const resourcesCommon = {
|
||||
'en-US': lang_en_US_common,
|
||||
|
|
|
@ -315,12 +315,12 @@ export class SectionContent extends Component {
|
|||
super(props);
|
||||
|
||||
this.state = {
|
||||
}
|
||||
};
|
||||
|
||||
this.historyUnlisten = props.history.listen((location, action) => {
|
||||
// noinspection JSIgnoredPromiseFromCall
|
||||
this.closeFlashMessage();
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
|
||||
.form { // This is here to give the styles below higher priority than Bootstrap has
|
||||
:global .DayPicker {
|
||||
border-left: 1px solid lightgray;
|
||||
border-right: 1px solid lightgray;
|
||||
border-bottom: 1px solid lightgray;
|
||||
border-radius: 4px;
|
||||
padding: 15px;
|
||||
border: $input-border-width solid $input-border-color;
|
||||
border-radius: $input-border-radius;
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
}
|
||||
|
||||
:global .form-horizontal .control-label {
|
||||
|
@ -114,11 +112,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
.dropZone {
|
||||
padding-top: 30px;
|
||||
padding-bottom: 30px;
|
||||
margin-bottom: 15px;
|
||||
margin-top: 8px;
|
||||
.colorPickerWrapper {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.dropZone{
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
margin-bottom: 3px;
|
||||
margin-top: 3px;
|
||||
border: 2px solid #E6E9ED;
|
||||
border-radius: 5px;
|
||||
background-color: #FAFAD2;
|
||||
|
|
|
@ -79,6 +79,7 @@ export class UntrustedContentHost extends Component {
|
|||
resolve(msg.data.ret);
|
||||
} else if (msg.type === 'rpcRequest') {
|
||||
const ret = await this.props.onMethodAsync(msg.data.method, msg.data.params);
|
||||
this.sendMessage('rpcResponse', {msgId: msg.data.msgId, ret});
|
||||
} else if (msg.type === 'clientHeight') {
|
||||
const newHeight = msg.data;
|
||||
this.contentNode.height = newHeight;
|
||||
|
@ -137,7 +138,7 @@ export class UntrustedContentHost extends Component {
|
|||
// noinspection JSIgnoredPromiseFromCall
|
||||
this.refreshAccessToken();
|
||||
this.scheduleRefreshAccessToken();
|
||||
}, 60 * 1000);
|
||||
}, 30 * 1000);
|
||||
}
|
||||
|
||||
handleUpdate() {
|
||||
|
@ -232,7 +233,7 @@ export class UntrustedContentRoot extends Component {
|
|||
}
|
||||
|
||||
sendMessage(type, data) {
|
||||
window.parent.postMessage({type, data}, getTrustedUrl());
|
||||
window.parent.postMessage({type, data}, '*');
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -334,7 +335,7 @@ class ParentRPC {
|
|||
}
|
||||
|
||||
sendMessage(type, data) {
|
||||
window.parent.postMessage({type, data}, getTrustedUrl());
|
||||
window.parent.postMessage({type, data}, '*');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,9 @@ function getTrustedUrl(path) {
|
|||
return mailtrainConfig.trustedUrlBase + (path || '');
|
||||
}
|
||||
|
||||
function getSandboxUrl(path) {
|
||||
return mailtrainConfig.sandboxUrlBase + restrictedAccessToken + '/' + (path || '');
|
||||
function getSandboxUrl(path, customRestrictedAccessToken) {
|
||||
const localRestrictedAccessToken = customRestrictedAccessToken || restrictedAccessToken;
|
||||
return mailtrainConfig.sandboxUrlBase + localRestrictedAccessToken + '/' + (path || '');
|
||||
}
|
||||
|
||||
function getPublicUrl(path, opts) {
|
||||
|
@ -43,7 +44,7 @@ function getBaseDir() {
|
|||
if (mailtrainConfig.appType === AppType.TRUSTED) {
|
||||
return mailtrainConfig.trustedUrlBaseDir;
|
||||
} else if (mailtrainConfig.appType === AppType.SANDBOXED) {
|
||||
return mailtrainConfig.sandboxUrlBaseDir + anonymousRestrictedAccessToken;
|
||||
return mailtrainConfig.sandboxUrlBaseDir + restrictedAccessToken;
|
||||
} else if (mailtrainConfig.appType === AppType.PUBLIC) {
|
||||
return mailtrainConfig.publicUrlBaseDir;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ export default class List extends Component {
|
|||
</Toolbar>
|
||||
}
|
||||
|
||||
<Title>{t('segment')}</Title>
|
||||
<Title>{t('Segments')}</Title>
|
||||
|
||||
<Table ref={node => this.table = node} withHeader dataUrl={`rest/segments-table/${this.props.list.id}`} columns={columns} />
|
||||
</div>
|
||||
|
|
|
@ -93,7 +93,7 @@ module.exports = {
|
|||
},
|
||||
externals: {
|
||||
jquery: 'jQuery',
|
||||
csfrToken: 'csfrToken',
|
||||
csrfToken: 'csrfToken',
|
||||
mailtrainConfig: 'mailtrainConfig'
|
||||
},
|
||||
plugins: [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue