Harmonization with IVIS

This commit is contained in:
Tomas Bures 2019-01-04 21:31:01 +01:00
parent 428fb9db7b
commit 397f85dac4
41 changed files with 8587 additions and 10940 deletions

2377
client/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -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"
}
}

View file

@ -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 = {

View file

@ -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>
);
}
}

View file

@ -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);
}
};
}

View file

@ -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
}

View file

@ -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,

View file

@ -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 = {

View file

@ -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;

View file

@ -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}, '*');
}
}

View file

@ -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;
}

View file

@ -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>

View file

@ -93,7 +93,7 @@ module.exports = {
},
externals: {
jquery: 'jQuery',
csfrToken: 'csfrToken',
csrfToken: 'csrfToken',
mailtrainConfig: 'mailtrainConfig'
},
plugins: [