Fixed bug - files/uploaded had wrong owner
Upgrade to React 16
This commit is contained in:
parent
dce5ba7464
commit
cfdcaf65d8
84 changed files with 2381 additions and 1546 deletions
891
client/package-lock.json
generated
891
client/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -17,31 +17,32 @@
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
"datatables.net": "^1.10.19",
|
"datatables.net": "^1.10.19",
|
||||||
"datatables.net-bs": "^1.10.19",
|
"datatables.net-bs": "^1.10.19",
|
||||||
"grapesjs": "^0.14.40",
|
"grapesjs": "^0.14.49",
|
||||||
"grapesjs-mjml": "0.0.27",
|
"grapesjs-mjml": "0.0.27",
|
||||||
"grapesjs-preset-newsletter": "^0.2.20",
|
"grapesjs-preset-newsletter": "^0.2.20",
|
||||||
"i18next": "^12.0.0",
|
"i18next": "^13.0.1",
|
||||||
"i18next-browser-languagedetector": "^2.2.4",
|
"i18next-browser-languagedetector": "^2.2.4",
|
||||||
"immutable": "^3.8.1",
|
"immutable": "^3.8.1",
|
||||||
"juice": "^5.0.1",
|
"juice": "^5.1.0",
|
||||||
"mjml4-in-browser": "^1.0.1",
|
"mjml4-in-browser": "^1.0.1",
|
||||||
"moment": "^2.22.2",
|
"moment": "^2.23.0",
|
||||||
"moment-timezone": "^0.5.23",
|
"moment-timezone": "^0.5.23",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"querystringify": "^2.1.0",
|
"querystringify": "^2.1.0",
|
||||||
"react": "^15.6.1",
|
"react": "^16.7.0",
|
||||||
"react-ace": "^5.10.0",
|
"react-ace": "^6.3.2",
|
||||||
"react-ckeditor-component": "^1.1.0",
|
"react-ckeditor-component": "^1.1.0",
|
||||||
"react-day-picker": "^6.1.0",
|
"react-day-picker": "^7.2.4",
|
||||||
"react-dnd-html5-backend": "^2.6.0",
|
"react-dnd": "^7.0.2",
|
||||||
"react-dnd-touch-backend": "^0.3.21",
|
"react-dnd-html5-backend": "^7.0.2",
|
||||||
"react-dom": "^15.6.1",
|
"react-dnd-touch-backend": "^0.7.1",
|
||||||
"react-dropzone": "^4.3.0",
|
"react-dom": "^16.7.0",
|
||||||
"react-google-charts": "^2.0.29",
|
"react-dropzone": "^8.0.3",
|
||||||
"react-i18next": "^8.3.8",
|
"react-google-charts": "^3.0.10",
|
||||||
|
"react-i18next": "^8.4.0",
|
||||||
"react-router-dom": "^4.3.1",
|
"react-router-dom": "^4.3.1",
|
||||||
"react-sortable-tree": "^1.2.0",
|
"react-sortable-tree": "^2.6.0",
|
||||||
"slugify": "^1.3.3",
|
"slugify": "^1.3.4",
|
||||||
"url-parse": "^1.4.4"
|
"url-parse": "^1.4.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from './lib/i18n';
|
import {withTranslation} from './lib/i18n';
|
||||||
import { requiresAuthenticatedUser } from './lib/page';
|
import {requiresAuthenticatedUser} from './lib/page';
|
||||||
|
import {withComponentMixins} from "./lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@requiresAuthenticatedUser
|
withTranslation,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -16,11 +16,14 @@ import axios
|
||||||
from '../lib/axios';
|
from '../lib/axios';
|
||||||
import {Button} from '../lib/bootstrap-components';
|
import {Button} from '../lib/bootstrap-components';
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from "../lib/urls";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class API extends Component {
|
export default class API extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,22 +1,41 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../lib/i18n';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import { Trans } from 'react-i18next';
|
import {Trans} from 'react-i18next';
|
||||||
import { requiresAuthenticatedUser, withPageHelpers, Title } from '../lib/page'
|
|
||||||
import {
|
import {
|
||||||
withForm, Form, Fieldset, FormSendMethod, InputField, ButtonRow, Button
|
requiresAuthenticatedUser,
|
||||||
|
Title,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../lib/page'
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonRow,
|
||||||
|
Fieldset,
|
||||||
|
Form,
|
||||||
|
FormSendMethod,
|
||||||
|
InputField,
|
||||||
|
withForm
|
||||||
} from '../lib/form';
|
} from '../lib/form';
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
import {
|
||||||
import passwordValidator from '../../../shared/password-validator';
|
withAsyncErrorHandler,
|
||||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
withErrorHandling
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
} from '../lib/error-handling';
|
||||||
|
import passwordValidator
|
||||||
|
from '../../../shared/password-validator';
|
||||||
|
import interoperableErrors
|
||||||
|
from '../../../shared/interoperable-errors';
|
||||||
|
import mailtrainConfig
|
||||||
|
from 'mailtrainConfig';
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class Account extends Component {
|
export default class Account extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -2,16 +2,23 @@
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { withTranslation } from '../lib/i18n';
|
import { withTranslation } from '../lib/i18n';
|
||||||
import { withPageHelpers, Title } from '../lib/page'
|
import {
|
||||||
|
withPageHelpers,
|
||||||
|
Title,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
} from '../lib/page'
|
||||||
import {
|
import {
|
||||||
withForm, Form, FormSendMethod, InputField, ButtonRow, Button
|
withForm, Form, FormSendMethod, InputField, ButtonRow, Button
|
||||||
} from '../lib/form';
|
} from '../lib/form';
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
|
withPageHelpers
|
||||||
|
])
|
||||||
export default class Forget extends Component {
|
export default class Forget extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,22 +1,37 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../lib/i18n';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import { withPageHelpers, Title } from '../lib/page'
|
|
||||||
import { Link } from 'react-router-dom'
|
|
||||||
import {
|
import {
|
||||||
withForm, Form, FormSendMethod, InputField, CheckBox, ButtonRow, Button, AlignedRow
|
Title,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../lib/page'
|
||||||
|
import {Link} from 'react-router-dom'
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonRow,
|
||||||
|
CheckBox,
|
||||||
|
Form,
|
||||||
|
FormSendMethod,
|
||||||
|
InputField,
|
||||||
|
withForm
|
||||||
} from '../lib/form';
|
} from '../lib/form';
|
||||||
import { withErrorHandling } from '../lib/error-handling';
|
import {withErrorHandling} from '../lib/error-handling';
|
||||||
import qs from 'querystringify';
|
import qs
|
||||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
from 'querystringify';
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
import interoperableErrors
|
||||||
|
from '../../../shared/interoperable-errors';
|
||||||
|
import mailtrainConfig
|
||||||
|
from 'mailtrainConfig';
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from "../lib/urls";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
|
withPageHelpers
|
||||||
|
])
|
||||||
export default class Login extends Component {
|
export default class Login extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,17 +1,32 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../lib/i18n';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import { withPageHelpers, Title } from '../lib/page'
|
|
||||||
import { Link } from 'react-router-dom'
|
|
||||||
import {
|
import {
|
||||||
withForm, Form, Fieldset, FormSendMethod, InputField, ButtonRow, Button
|
Title,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../lib/page'
|
||||||
|
import {Link} from 'react-router-dom'
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonRow,
|
||||||
|
Form,
|
||||||
|
FormSendMethod,
|
||||||
|
InputField,
|
||||||
|
withForm
|
||||||
} from '../lib/form';
|
} from '../lib/form';
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
import {
|
||||||
import passwordValidator from '../../../shared/password-validator';
|
withAsyncErrorHandler,
|
||||||
import axios from '../lib/axios';
|
withErrorHandling
|
||||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
} from '../lib/error-handling';
|
||||||
|
import passwordValidator
|
||||||
|
from '../../../shared/password-validator';
|
||||||
|
import axios
|
||||||
|
from '../lib/axios';
|
||||||
|
import interoperableErrors
|
||||||
|
from '../../../shared/interoperable-errors';
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from "../lib/urls";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
const ResetTokenValidationState = {
|
const ResetTokenValidationState = {
|
||||||
PENDING: 0,
|
PENDING: 0,
|
||||||
|
@ -19,10 +34,12 @@ const ResetTokenValidationState = {
|
||||||
INVALID: 2
|
INVALID: 2
|
||||||
};
|
};
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
|
withPageHelpers
|
||||||
|
])
|
||||||
export default class Account extends Component {
|
export default class Account extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -14,12 +14,15 @@ import {
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../lib/modals";
|
} from "../lib/modals";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../lib/i18n';
|
from 'prop-types';
|
||||||
|
import {withTranslation} from '../lib/i18n';
|
||||||
import {
|
import {
|
||||||
NavButton,
|
NavButton,
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
|
@ -33,15 +34,19 @@ import {
|
||||||
validateNamespace
|
validateNamespace
|
||||||
} from '../lib/namespace';
|
} from '../lib/namespace';
|
||||||
import {DeleteModalDialog} from "../lib/modals";
|
import {DeleteModalDialog} from "../lib/modals";
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
import mailtrainConfig
|
||||||
|
from 'mailtrainConfig';
|
||||||
import {
|
import {
|
||||||
getTemplateTypes,
|
getTemplateTypes,
|
||||||
getTypeForm,
|
getTypeForm,
|
||||||
ResourceType
|
ResourceType
|
||||||
} from '../templates/helpers';
|
} from '../templates/helpers';
|
||||||
import axios from '../lib/axios';
|
import axios
|
||||||
import styles from "../lib/styles.scss";
|
from '../lib/axios';
|
||||||
import campaignsStyles from "./styles.scss";
|
import styles
|
||||||
|
from "../lib/styles.scss";
|
||||||
|
import campaignsStyles
|
||||||
|
from "./styles.scss";
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from "../lib/urls";
|
||||||
import {
|
import {
|
||||||
campaignOverridables,
|
campaignOverridables,
|
||||||
|
@ -49,15 +54,19 @@ import {
|
||||||
CampaignStatus,
|
CampaignStatus,
|
||||||
CampaignType
|
CampaignType
|
||||||
} from "../../../shared/campaigns";
|
} from "../../../shared/campaigns";
|
||||||
import moment from 'moment';
|
import moment
|
||||||
|
from 'moment';
|
||||||
import {getMailerTypes} from "../send-configurations/helpers";
|
import {getMailerTypes} from "../send-configurations/helpers";
|
||||||
import {getCampaignLabels} from "./helpers";
|
import {getCampaignLabels} from "./helpers";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../lib/i18n';
|
from 'prop-types';
|
||||||
|
import {withTranslation} from '../lib/i18n';
|
||||||
import {
|
import {
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
Title,
|
Title,
|
||||||
|
@ -17,24 +18,30 @@ import {
|
||||||
withForm
|
withForm
|
||||||
} from '../lib/form';
|
} from '../lib/form';
|
||||||
import {withErrorHandling} from '../lib/error-handling';
|
import {withErrorHandling} from '../lib/error-handling';
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
import mailtrainConfig
|
||||||
|
from 'mailtrainConfig';
|
||||||
import {
|
import {
|
||||||
getEditForm,
|
getEditForm,
|
||||||
getTemplateTypes,
|
getTemplateTypes,
|
||||||
getTypeForm,
|
getTypeForm,
|
||||||
ResourceType
|
ResourceType
|
||||||
} from '../templates/helpers';
|
} from '../templates/helpers';
|
||||||
import axios from '../lib/axios';
|
import axios
|
||||||
import styles from "../lib/styles.scss";
|
from '../lib/axios';
|
||||||
|
import styles
|
||||||
|
from "../lib/styles.scss";
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from "../lib/urls";
|
||||||
import {TestSendModalDialog} from "./TestSendModalDialog";
|
import {TestSendModalDialog} from "./TestSendModalDialog";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CustomContent extends Component {
|
export default class CustomContent extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../lib/i18n';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
Icon
|
Icon
|
||||||
|
@ -18,7 +18,8 @@ import {
|
||||||
withErrorHandling
|
withErrorHandling
|
||||||
} from '../lib/error-handling';
|
} from '../lib/error-handling';
|
||||||
import {Table} from '../lib/table';
|
import {Table} from '../lib/table';
|
||||||
import moment from 'moment';
|
import moment
|
||||||
|
from 'moment';
|
||||||
import {
|
import {
|
||||||
CampaignSource,
|
CampaignSource,
|
||||||
CampaignStatus,
|
CampaignStatus,
|
||||||
|
@ -31,11 +32,14 @@ import {
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../lib/modals";
|
} from "../lib/modals";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -22,11 +22,14 @@ import {Icon} from "../lib/bootstrap-components";
|
||||||
import styles
|
import styles
|
||||||
from "./styles.scss";
|
from "./styles.scss";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class Statistics extends Component {
|
export default class Statistics extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -11,11 +11,14 @@ import {
|
||||||
} from '../lib/page';
|
} from '../lib/page';
|
||||||
import {withErrorHandling} from '../lib/error-handling';
|
import {withErrorHandling} from '../lib/error-handling';
|
||||||
import {Table} from "../lib/table";
|
import {Table} from "../lib/table";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class StatisticsLinkClicks extends Component {
|
export default class StatisticsLinkClicks extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -17,24 +17,24 @@ import axios
|
||||||
from "../lib/axios";
|
from "../lib/axios";
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from "../lib/urls";
|
||||||
|
|
||||||
import Chart from 'react-google-charts';
|
import Chart
|
||||||
import {AlignedRow} from "../lib/form";
|
from 'react-google-charts';
|
||||||
import {
|
|
||||||
ActionLink,
|
|
||||||
Icon
|
|
||||||
} from "../lib/bootstrap-components";
|
|
||||||
import {SubscriptionStatus} from "../../../shared/lists";
|
|
||||||
|
|
||||||
import styles from "./styles.scss";
|
import styles
|
||||||
|
from "./styles.scss";
|
||||||
import {Table} from "../lib/table";
|
import {Table} from "../lib/table";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
|
|
||||||
import mailtrainConfig from "mailtrainConfig";
|
import mailtrainConfig
|
||||||
|
from "mailtrainConfig";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class StatisticsOpened extends Component {
|
export default class StatisticsOpened extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -11,11 +11,14 @@ import {
|
||||||
} from '../lib/page';
|
} from '../lib/page';
|
||||||
import {withErrorHandling} from '../lib/error-handling';
|
import {withErrorHandling} from '../lib/error-handling';
|
||||||
import {Table} from "../lib/table";
|
import {Table} from "../lib/table";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class StatisticsSubsList extends Component {
|
export default class StatisticsSubsList extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../lib/i18n';
|
from 'prop-types';
|
||||||
|
import {withTranslation} from '../lib/i18n';
|
||||||
import {
|
import {
|
||||||
NavButton,
|
NavButton,
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
|
@ -30,24 +31,32 @@ import {
|
||||||
Icon,
|
Icon,
|
||||||
ModalDialog
|
ModalDialog
|
||||||
} from "../lib/bootstrap-components";
|
} from "../lib/bootstrap-components";
|
||||||
import axios from "../lib/axios";
|
import axios
|
||||||
import {getUrl, getPublicUrl} from "../lib/urls";
|
from "../lib/axios";
|
||||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
import {
|
||||||
|
getPublicUrl,
|
||||||
|
getUrl
|
||||||
|
} from "../lib/urls";
|
||||||
|
import interoperableErrors
|
||||||
|
from '../../../shared/interoperable-errors';
|
||||||
import {
|
import {
|
||||||
CampaignSource,
|
|
||||||
CampaignStatus,
|
CampaignStatus,
|
||||||
CampaignType
|
CampaignType
|
||||||
} from "../../../shared/campaigns";
|
} from "../../../shared/campaigns";
|
||||||
import moment from 'moment';
|
import moment
|
||||||
import campaignsStyles from "./styles.scss";
|
from 'moment';
|
||||||
import {tableAddDeleteButton} from "../lib/modals";
|
import campaignsStyles
|
||||||
|
from "./styles.scss";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
class TestUser extends Component {
|
class TestUser extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -107,11 +116,13 @@ class TestUser extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
class SendControls extends Component {
|
class SendControls extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -361,10 +372,12 @@ class SendControls extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class Status extends Component {
|
export default class Status extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../lib/i18n';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import PropTypes
|
import PropTypes
|
||||||
from 'prop-types';
|
from 'prop-types';
|
||||||
import {ModalDialog} from "../lib/bootstrap-components";
|
import {ModalDialog} from "../lib/bootstrap-components";
|
||||||
|
@ -16,16 +16,19 @@ import {
|
||||||
} from "../lib/form";
|
} from "../lib/form";
|
||||||
import {withErrorHandling} from "../lib/error-handling";
|
import {withErrorHandling} from "../lib/error-handling";
|
||||||
import {getMailerTypes} from "../send-configurations/helpers";
|
import {getMailerTypes} from "../send-configurations/helpers";
|
||||||
import axios from '../lib/axios';
|
import axios
|
||||||
import {} from '../lib/urls';
|
from '../lib/axios';
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from '../lib/urls';
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export class TestSendModalDialog extends Component {
|
export class TestSendModalDialog extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../../lib/i18n';
|
from 'prop-types';
|
||||||
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import {
|
import {
|
||||||
NavButton,
|
NavButton,
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
|
@ -29,15 +30,19 @@ import {
|
||||||
Entity,
|
Entity,
|
||||||
Event
|
Event
|
||||||
} from '../../../../shared/triggers';
|
} from '../../../../shared/triggers';
|
||||||
import moment from 'moment';
|
import moment
|
||||||
|
from 'moment';
|
||||||
import {getCampaignLabels} from "../helpers";
|
import {getCampaignLabels} from "../helpers";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../../lib/i18n';
|
from 'prop-types';
|
||||||
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import {
|
import {
|
||||||
NavButton,
|
NavButton,
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
|
@ -14,17 +15,21 @@ import {withErrorHandling} from '../../lib/error-handling';
|
||||||
import {Table} from '../../lib/table';
|
import {Table} from '../../lib/table';
|
||||||
import {getTriggerTypes} from './helpers';
|
import {getTriggerTypes} from './helpers';
|
||||||
import {Icon} from "../../lib/bootstrap-components";
|
import {Icon} from "../../lib/bootstrap-components";
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
import mailtrainConfig
|
||||||
|
from 'mailtrainConfig';
|
||||||
import {
|
import {
|
||||||
tableAddDeleteButton,
|
tableAddDeleteButton,
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../../lib/modals";
|
} from "../../lib/modals";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
34
client/src/lib/bootstrap-components.js
vendored
34
client/src/lib/bootstrap-components.js
vendored
|
@ -1,12 +1,20 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from './i18n';
|
import {withTranslation} from './i18n';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from './error-handling';
|
from 'prop-types';
|
||||||
|
import {
|
||||||
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from './error-handling';
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
|
||||||
@withErrorHandling
|
@withComponentMixins([
|
||||||
|
withTranslation,
|
||||||
|
withErrorHandling
|
||||||
|
])
|
||||||
class DismissibleAlert extends Component {
|
class DismissibleAlert extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
severity: PropTypes.string.isRequired,
|
severity: PropTypes.string.isRequired,
|
||||||
|
@ -51,7 +59,9 @@ class Icon extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@withErrorHandling
|
@withComponentMixins([
|
||||||
|
withErrorHandling
|
||||||
|
])
|
||||||
class Button extends Component {
|
class Button extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
onClickAsync: PropTypes.func,
|
onClickAsync: PropTypes.func,
|
||||||
|
@ -165,7 +175,9 @@ class DropdownMenuItem extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@withErrorHandling
|
@withComponentMixins([
|
||||||
|
withErrorHandling
|
||||||
|
])
|
||||||
class ActionLink extends Component {
|
class ActionLink extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
onClickAsync: PropTypes.func,
|
onClickAsync: PropTypes.func,
|
||||||
|
@ -192,8 +204,10 @@ class ActionLink extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withErrorHandling
|
withTranslation,
|
||||||
|
withErrorHandling
|
||||||
|
])
|
||||||
class ModalDialog extends Component {
|
class ModalDialog extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
90
client/src/lib/decorator-helpers.js
Normal file
90
client/src/lib/decorator-helpers.js
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export function createComponentMixin(contexts, deps, decoratorFn) {
|
||||||
|
return {
|
||||||
|
contexts,
|
||||||
|
deps,
|
||||||
|
decoratorFn
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function withComponentMixins(mixins, delegateFuns) {
|
||||||
|
const mixinsClosure = new Set();
|
||||||
|
for (const mixin of mixins) {
|
||||||
|
mixinsClosure.add(mixin);
|
||||||
|
for (const dep of mixin.deps) {
|
||||||
|
mixinsClosure.add(dep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const contexts = new Map();
|
||||||
|
for (const mixin of mixinsClosure.values()) {
|
||||||
|
for (const ctx of mixin.contexts) {
|
||||||
|
contexts.set(ctx.propName, ctx.context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TargetClass => {
|
||||||
|
class ComponentMixinsInner extends React.Component {
|
||||||
|
render() {
|
||||||
|
const props = {
|
||||||
|
...this.props,
|
||||||
|
ref: this.props._decoratorInnerInstanceRefFn
|
||||||
|
};
|
||||||
|
delete props._decoratorInnerInstanceRefFn;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TargetClass {...props}/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let DecoratedInner = ComponentMixinsInner;
|
||||||
|
|
||||||
|
for (const mixin of mixinsClosure.values()) {
|
||||||
|
DecoratedInner = mixin.decoratorFn(DecoratedInner, TargetClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ComponentMixinsOuter extends React.Component {
|
||||||
|
render() {
|
||||||
|
let innerFn = parentProps => {
|
||||||
|
const props = {
|
||||||
|
...parentProps,
|
||||||
|
_decoratorInnerInstanceRefFn: node => this._decoratorInnerInstance = node
|
||||||
|
};
|
||||||
|
|
||||||
|
return <DecoratedInner {...props}/>
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [propName, Context] of contexts.entries()) {
|
||||||
|
const existingInnerFn = innerFn;
|
||||||
|
innerFn = parentProps => (
|
||||||
|
<Context.Consumer>
|
||||||
|
{
|
||||||
|
value => existingInnerFn({
|
||||||
|
...parentProps,
|
||||||
|
[propName]: value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</Context.Consumer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return innerFn(this.props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delegateFuns) {
|
||||||
|
for (const fun of delegateFuns) {
|
||||||
|
ComponentMixinsOuter.prototype[fun] = function (...args) {
|
||||||
|
return this._decoratorInnerInstance[fun](...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ComponentMixinsOuter;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import {SectionContentContext} from "./page-common";
|
||||||
|
import {createComponentMixin} from "./decorator-helpers";
|
||||||
|
|
||||||
function handleError(that, error) {
|
function handleError(that, error) {
|
||||||
let errorHandled;
|
let errorHandled;
|
||||||
|
@ -9,8 +11,8 @@ function handleError(that, error) {
|
||||||
errorHandled = that.errorHandler(error);
|
errorHandled = that.errorHandler(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!errorHandled && that.context.parentErrorHandler) {
|
if (!errorHandled && that.props.parentErrorHandler) {
|
||||||
errorHandled = handleError(that.context.parentErrorHandler, error);
|
errorHandled = handleError(that.props.parentErrorHandler, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!errorHandled) {
|
if (!errorHandled) {
|
||||||
|
@ -20,35 +22,8 @@ function handleError(that, error) {
|
||||||
return errorHandled;
|
return errorHandled;
|
||||||
}
|
}
|
||||||
|
|
||||||
function withErrorHandling(target) {
|
export const ParentErrorHandlerContext = React.createContext(null);
|
||||||
const inst = target.prototype;
|
export const withErrorHandling = createComponentMixin([{context: ParentErrorHandlerContext, propName: 'parentErrorHandler'}], [], (TargetClass, InnerClass) => {
|
||||||
|
|
||||||
if (inst._withErrorHandlingApplied) return target;
|
|
||||||
inst._withErrorHandlingApplied = true;
|
|
||||||
|
|
||||||
const contextTypes = target.contextTypes || {};
|
|
||||||
contextTypes.parentErrorHandler = PropTypes.object;
|
|
||||||
target.contextTypes = contextTypes;
|
|
||||||
|
|
||||||
const childContextTypes = target.childContextTypes || {};
|
|
||||||
childContextTypes.parentErrorHandler = PropTypes.object;
|
|
||||||
target.childContextTypes = childContextTypes;
|
|
||||||
|
|
||||||
const existingGetChildContext = inst.getChildContext;
|
|
||||||
if (existingGetChildContext) {
|
|
||||||
inst.getChildContext = function() {
|
|
||||||
const childContext = (this::existingGetChildContext)();
|
|
||||||
childContext.parentErrorHandler = this;
|
|
||||||
return childContext;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
inst.getChildContext = function() {
|
|
||||||
return {
|
|
||||||
parentErrorHandler: this
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Example of use:
|
/* Example of use:
|
||||||
this.getFormValuesFromURL(....).catch(error => this.handleError(error));
|
this.getFormValuesFromURL(....).catch(error => this.handleError(error));
|
||||||
|
|
||||||
|
@ -59,14 +34,25 @@ function withErrorHandling(target) {
|
||||||
await this.getFormValuesFromURL(...);
|
await this.getFormValuesFromURL(...);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
inst.handleError = function(error) {
|
|
||||||
|
const originalRender = InnerClass.prototype.render;
|
||||||
|
|
||||||
|
InnerClass.prototype.render = function() {
|
||||||
|
return (
|
||||||
|
<ParentErrorHandlerContext.Provider value={this}>
|
||||||
|
{originalRender.apply(this)}
|
||||||
|
</ParentErrorHandlerContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
InnerClass.prototype.handleError = function(error) {
|
||||||
handleError(this, error);
|
handleError(this, error);
|
||||||
};
|
};
|
||||||
|
|
||||||
return target;
|
return TargetClass;
|
||||||
}
|
});
|
||||||
|
|
||||||
function withAsyncErrorHandler(target, name, descriptor) {
|
export function withAsyncErrorHandler(target, name, descriptor) {
|
||||||
let fn = descriptor.value;
|
let fn = descriptor.value;
|
||||||
|
|
||||||
descriptor.value = async function () {
|
descriptor.value = async function () {
|
||||||
|
@ -80,8 +66,3 @@ function withAsyncErrorHandler(target, name, descriptor) {
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export {
|
|
||||||
withErrorHandling,
|
|
||||||
withAsyncErrorHandler
|
|
||||||
}
|
|
|
@ -1,25 +1,38 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes
|
||||||
import { withTranslation } from './i18n';
|
from "prop-types";
|
||||||
|
import {withTranslation} from './i18n';
|
||||||
import {
|
import {
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
Title
|
Title,
|
||||||
|
withPageHelpers
|
||||||
} from "./page";
|
} from "./page";
|
||||||
import {withErrorHandling} from "./error-handling";
|
import {withErrorHandling} from "./error-handling";
|
||||||
import {Table} from "./table";
|
import {Table} from "./table";
|
||||||
import Dropzone from "react-dropzone";
|
import Dropzone
|
||||||
import {Icon, ModalDialog} from "./bootstrap-components";
|
from "react-dropzone";
|
||||||
import axios from './axios';
|
import {
|
||||||
import styles from "./styles.scss";
|
Icon,
|
||||||
import {withPageHelpers} from "./page";
|
ModalDialog
|
||||||
import {getUrl, getPublicUrl} from "./urls";
|
} from "./bootstrap-components";
|
||||||
|
import axios
|
||||||
|
from './axios';
|
||||||
|
import styles
|
||||||
|
from "./styles.scss";
|
||||||
|
import {
|
||||||
|
getPublicUrl,
|
||||||
|
getUrl
|
||||||
|
} from "./urls";
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withErrorHandling
|
withTranslation,
|
||||||
@withPageHelpers
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class Files extends Component {
|
export default class Files extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,29 +1,60 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from './i18n';
|
import {withTranslation} from './i18n';
|
||||||
import axios, {HTTPMethod} from './axios';
|
import axios, {HTTPMethod} from './axios';
|
||||||
import Immutable from 'immutable';
|
import Immutable
|
||||||
import PropTypes from 'prop-types';
|
from 'immutable';
|
||||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
import PropTypes
|
||||||
import { withPageHelpers } from './page'
|
from 'prop-types';
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from './error-handling';
|
import interoperableErrors
|
||||||
import { TreeTable, TreeSelectMode } from './tree';
|
from '../../../shared/interoperable-errors';
|
||||||
import { Table, TableSelectMode } from './table';
|
import {withPageHelpers} from './page'
|
||||||
import {Button, Icon} from "./bootstrap-components";
|
import {
|
||||||
|
ParentErrorHandlerContext,
|
||||||
import brace from 'brace';
|
withAsyncErrorHandler,
|
||||||
import ACEEditorRaw from 'react-ace';
|
withErrorHandling
|
||||||
|
} from './error-handling';
|
||||||
|
import {
|
||||||
|
TreeSelectMode,
|
||||||
|
TreeTable
|
||||||
|
} from './tree';
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableSelectMode
|
||||||
|
} from './table';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Icon
|
||||||
|
} from "./bootstrap-components";
|
||||||
|
import ACEEditorRaw
|
||||||
|
from 'react-ace';
|
||||||
import 'brace/theme/github';
|
import 'brace/theme/github';
|
||||||
import 'brace/ext/searchbox';
|
import 'brace/ext/searchbox';
|
||||||
|
|
||||||
import DayPicker from 'react-day-picker';
|
import DayPicker
|
||||||
|
from 'react-day-picker';
|
||||||
import 'react-day-picker/lib/style.css';
|
import 'react-day-picker/lib/style.css';
|
||||||
import { parseDate, parseBirthday, formatDate, formatBirthday, DateFormat, birthdayYear, getDateFormatString, getBirthdayFormatString } from '../../../shared/date';
|
import {
|
||||||
|
birthdayYear,
|
||||||
|
DateFormat,
|
||||||
|
formatBirthday,
|
||||||
|
formatDate,
|
||||||
|
getBirthdayFormatString,
|
||||||
|
getDateFormatString,
|
||||||
|
parseBirthday,
|
||||||
|
parseDate
|
||||||
|
} from '../../../shared/date';
|
||||||
|
|
||||||
import styles from "./styles.scss";
|
import styles
|
||||||
import moment from "moment";
|
from "./styles.scss";
|
||||||
|
import moment
|
||||||
|
from "moment";
|
||||||
import {getUrl} from "./urls";
|
import {getUrl} from "./urls";
|
||||||
|
import {
|
||||||
|
createComponentMixin,
|
||||||
|
withComponentMixins
|
||||||
|
} from "./decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
const FormState = {
|
const FormState = {
|
||||||
|
@ -34,9 +65,22 @@ const FormState = {
|
||||||
|
|
||||||
const FormSendMethod = HTTPMethod;
|
const FormSendMethod = HTTPMethod;
|
||||||
|
|
||||||
@withTranslation()
|
export const FormStateOwnerContext = React.createContext(null);
|
||||||
@withPageHelpers
|
|
||||||
@withErrorHandling
|
const withFormStateOwner = createComponentMixin([{context: FormStateOwnerContext, propName: 'formStateOwner'}], [], (TargetClass, InnerClass) => {
|
||||||
|
InnerClass.prototype.getFormStateOwner = function() {
|
||||||
|
return this.props.formStateOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TargetClass;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@withComponentMixins([
|
||||||
|
withTranslation,
|
||||||
|
withErrorHandling,
|
||||||
|
withPageHelpers
|
||||||
|
])
|
||||||
class Form extends Component {
|
class Form extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
stateOwner: PropTypes.object.isRequired,
|
stateOwner: PropTypes.object.isRequired,
|
||||||
|
@ -45,16 +89,6 @@ class Form extends Component {
|
||||||
noStatus: PropTypes.bool
|
noStatus: PropTypes.bool
|
||||||
}
|
}
|
||||||
|
|
||||||
static childContextTypes = {
|
|
||||||
formStateOwner: PropTypes.object
|
|
||||||
}
|
|
||||||
|
|
||||||
getChildContext() {
|
|
||||||
return {
|
|
||||||
formStateOwner: this.props.stateOwner
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@withAsyncErrorHandler
|
@withAsyncErrorHandler
|
||||||
async onSubmit(evt) {
|
async onSubmit(evt) {
|
||||||
const t = this.props.t;
|
const t = this.props.t;
|
||||||
|
@ -91,6 +125,7 @@ class Form extends Component {
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<form className={formClass} onSubmit={::this.onSubmit}>
|
<form className={formClass} onSubmit={::this.onSubmit}>
|
||||||
|
<FormStateOwnerContext.Provider value={owner}>
|
||||||
<fieldset disabled={owner.isFormDisabled()}>
|
<fieldset disabled={owner.isFormDisabled()}>
|
||||||
{props.children}
|
{props.children}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
@ -99,12 +134,16 @@ class Form extends Component {
|
||||||
<p className={`alert alert-${statusMessageSeverity} ${styles.formStatus}`} role="alert">{statusMessageText}</p>
|
<p className={`alert alert-${statusMessageSeverity} ${styles.formStatus}`} role="alert">{statusMessageText}</p>
|
||||||
</AlignedRow>
|
</AlignedRow>
|
||||||
}
|
}
|
||||||
|
</FormStateOwnerContext.Provider>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@withComponentMixins([
|
||||||
|
withFormStateOwner
|
||||||
|
])
|
||||||
class Fieldset extends Component {
|
class Fieldset extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
|
@ -114,13 +153,9 @@ class Fieldset extends Component {
|
||||||
className: PropTypes.string
|
className: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const htmlId = 'form_' + id;
|
const htmlId = 'form_' + id;
|
||||||
|
|
||||||
|
@ -230,6 +265,9 @@ function wrapInput(id, htmlId, owner, format, rightContainerClass, label, help,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@withComponentMixins([
|
||||||
|
withFormStateOwner
|
||||||
|
])
|
||||||
class StaticField extends Component {
|
class StaticField extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
@ -240,13 +278,9 @@ class StaticField extends Component {
|
||||||
withValidation: PropTypes.bool
|
withValidation: PropTypes.bool
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const htmlId = 'form_' + id;
|
const htmlId = 'form_' + id;
|
||||||
|
|
||||||
|
@ -261,6 +295,9 @@ class StaticField extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@withComponentMixins([
|
||||||
|
withFormStateOwner
|
||||||
|
])
|
||||||
class InputField extends Component {
|
class InputField extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
@ -275,13 +312,9 @@ class InputField extends Component {
|
||||||
type: 'text'
|
type: 'text'
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const htmlId = 'form_' + id;
|
const htmlId = 'form_' + id;
|
||||||
|
|
||||||
|
@ -298,6 +331,9 @@ class InputField extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@withComponentMixins([
|
||||||
|
withFormStateOwner
|
||||||
|
])
|
||||||
class CheckBox extends Component {
|
class CheckBox extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
@ -307,13 +343,9 @@ class CheckBox extends Component {
|
||||||
format: PropTypes.string
|
format: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const htmlId = 'form_' + id;
|
const htmlId = 'form_' + id;
|
||||||
|
|
||||||
|
@ -336,13 +368,9 @@ class CheckBoxGroup extends Component {
|
||||||
format: PropTypes.string
|
format: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
onChange(key) {
|
onChange(key) {
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const existingSelection = owner.getFormValue(id);
|
const existingSelection = owner.getFormValue(id);
|
||||||
|
|
||||||
let newSelection;
|
let newSelection;
|
||||||
|
@ -357,7 +385,7 @@ class CheckBoxGroup extends Component {
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
|
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const htmlId = 'form_' + id;
|
const htmlId = 'form_' + id;
|
||||||
|
|
||||||
|
@ -388,6 +416,9 @@ class CheckBoxGroup extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@withComponentMixins([
|
||||||
|
withFormStateOwner
|
||||||
|
])
|
||||||
class RadioGroup extends Component {
|
class RadioGroup extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
@ -398,14 +429,10 @@ class RadioGroup extends Component {
|
||||||
format: PropTypes.string
|
format: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
|
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const htmlId = 'form_' + id;
|
const htmlId = 'form_' + id;
|
||||||
|
|
||||||
|
@ -436,6 +463,9 @@ class RadioGroup extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@withComponentMixins([
|
||||||
|
withFormStateOwner
|
||||||
|
])
|
||||||
class TextArea extends Component {
|
class TextArea extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
@ -446,13 +476,9 @@ class TextArea extends Component {
|
||||||
className: PropTypes.string
|
className: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = props.id;
|
const id = props.id;
|
||||||
const htmlId = 'form_' + id;
|
const htmlId = 'form_' + id;
|
||||||
const className = props.className || ''
|
const className = props.className || ''
|
||||||
|
@ -464,7 +490,10 @@ class TextArea extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
|
withTranslation,
|
||||||
|
withFormStateOwner
|
||||||
|
])
|
||||||
class DatePicker extends Component {
|
class DatePicker extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -489,10 +518,6 @@ class DatePicker extends Component {
|
||||||
dateFormat: DateFormat.INTL
|
dateFormat: DateFormat.INTL
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleDayPicker() {
|
toggleDayPicker() {
|
||||||
this.setState({
|
this.setState({
|
||||||
opened: !this.state.opened
|
opened: !this.state.opened
|
||||||
|
@ -500,7 +525,7 @@ class DatePicker extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
daySelected(date) {
|
daySelected(date) {
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
|
|
||||||
|
@ -517,7 +542,7 @@ class DatePicker extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const htmlId = 'form_' + id;
|
const htmlId = 'form_' + id;
|
||||||
const t = props.t;
|
const t = props.t;
|
||||||
|
@ -590,6 +615,9 @@ class DatePicker extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@withComponentMixins([
|
||||||
|
withFormStateOwner
|
||||||
|
])
|
||||||
class Dropdown extends Component {
|
class Dropdown extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
@ -600,14 +628,10 @@ class Dropdown extends Component {
|
||||||
format: PropTypes.string
|
format: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
|
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const htmlId = 'form_' + id;
|
const htmlId = 'form_' + id;
|
||||||
const options = [];
|
const options = [];
|
||||||
|
@ -639,6 +663,9 @@ class Dropdown extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@withComponentMixins([
|
||||||
|
withFormStateOwner
|
||||||
|
])
|
||||||
class AlignedRow extends Component {
|
class AlignedRow extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
|
@ -647,17 +674,13 @@ class AlignedRow extends Component {
|
||||||
format: PropTypes.string
|
format: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object // AlignedRow may be used also outside forms to make a kind of fake read-only forms
|
|
||||||
}
|
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
className: ''
|
className: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
|
|
||||||
return wrapInput(null, props.htmlId, owner, props.format, props.className, props.label, null, this.props.children);
|
return wrapInput(null, props.htmlId, owner, props.format, props.className, props.label, null, this.props.children);
|
||||||
}
|
}
|
||||||
|
@ -683,6 +706,9 @@ class ButtonRow extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@withComponentMixins([
|
||||||
|
withFormStateOwner
|
||||||
|
])
|
||||||
class TreeTableSelect extends Component {
|
class TreeTableSelect extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
@ -693,18 +719,14 @@ class TreeTableSelect extends Component {
|
||||||
format: PropTypes.string
|
format: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
async onSelectionChangedAsync(sel) {
|
async onSelectionChangedAsync(sel) {
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
owner.updateFormValue(this.props.id, sel);
|
owner.updateFormValue(this.props.id, sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const htmlId = 'form_' + id;
|
const htmlId = 'form_' + id;
|
||||||
|
|
||||||
|
@ -714,7 +736,10 @@ class TreeTableSelect extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@withTranslation({delegateFuns: ['refresh']})
|
@withComponentMixins([
|
||||||
|
withTranslation,
|
||||||
|
withFormStateOwner
|
||||||
|
], ['refresh'])
|
||||||
class TableSelect extends Component {
|
class TableSelect extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -751,10 +776,6 @@ class TableSelect extends Component {
|
||||||
pageLength: 10
|
pageLength: 10
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
async onSelectionChangedAsync(sel, data) {
|
async onSelectionChangedAsync(sel, data) {
|
||||||
if (this.props.selectMode === TableSelectMode.SINGLE && this.props.dropdown) {
|
if (this.props.selectMode === TableSelectMode.SINGLE && this.props.dropdown) {
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -762,7 +783,7 @@ class TableSelect extends Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
owner.updateFormValue(this.props.id, sel);
|
owner.updateFormValue(this.props.id, sel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -796,7 +817,7 @@ class TableSelect extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const htmlId = 'form_' + id;
|
const htmlId = 'form_' + id;
|
||||||
const t = props.t;
|
const t = props.t;
|
||||||
|
@ -830,6 +851,9 @@ class TableSelect extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@withComponentMixins([
|
||||||
|
withFormStateOwner
|
||||||
|
])
|
||||||
class ACEEditor extends Component {
|
class ACEEditor extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
@ -840,13 +864,9 @@ class ACEEditor extends Component {
|
||||||
format: PropTypes.string
|
format: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const htmlId = 'form_' + id;
|
const htmlId = 'form_' + id;
|
||||||
|
|
||||||
|
@ -870,6 +890,9 @@ class ACEEditor extends Component {
|
||||||
|
|
||||||
/* Excluded. It's not very useful and just eats a lot of space in the resulting JS.
|
/* Excluded. It's not very useful and just eats a lot of space in the resulting JS.
|
||||||
|
|
||||||
|
@withComponentMixins([
|
||||||
|
withFormStateOwner
|
||||||
|
])
|
||||||
class CKEditor extends Component {
|
class CKEditor extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
|
@ -878,13 +901,9 @@ class CKEditor extends Component {
|
||||||
height: PropTypes.string
|
height: PropTypes.string
|
||||||
}
|
}
|
||||||
|
|
||||||
static contextTypes = {
|
|
||||||
formStateOwner: PropTypes.object.isRequired
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
const owner = this.context.formStateOwner;
|
const owner = this.getFormStateOwner();
|
||||||
const id = this.props.id;
|
const id = this.props.id;
|
||||||
const htmlId = 'form_' + id;
|
const htmlId = 'form_' + id;
|
||||||
|
|
||||||
|
@ -901,9 +920,8 @@ class CKEditor extends Component {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const withForm = createComponentMixin([], [], (TargetClass, InnerClass) => {
|
||||||
function withForm(target) {
|
const proto = InnerClass.prototype;
|
||||||
const inst = target.prototype;
|
|
||||||
|
|
||||||
const cleanFormState = Immutable.Map({
|
const cleanFormState = Immutable.Map({
|
||||||
state: FormState.Loading,
|
state: FormState.Loading,
|
||||||
|
@ -1002,20 +1020,20 @@ function withForm(target) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inst.initForm = function(settings) {
|
proto.initForm = function(settings) {
|
||||||
const state = this.state || {};
|
const state = this.state || {};
|
||||||
state.formState = cleanFormState;
|
state.formState = cleanFormState;
|
||||||
state.formSettings = settings || {};
|
state.formSettings = settings || {};
|
||||||
this.state = state;
|
this.state = state;
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.resetFormState = function() {
|
proto.resetFormState = function() {
|
||||||
this.setState({
|
this.setState({
|
||||||
formState: cleanFormState
|
formState: cleanFormState
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.getFormValuesFromEntity = function(entity, mutator) {
|
proto.getFormValuesFromEntity = function(entity, mutator) {
|
||||||
const data = Object.assign({}, entity);
|
const data = Object.assign({}, entity);
|
||||||
|
|
||||||
data.originalHash = data.hash;
|
data.originalHash = data.hash;
|
||||||
|
@ -1028,7 +1046,7 @@ function withForm(target) {
|
||||||
this.populateFormValues(data);
|
this.populateFormValues(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.getFormValuesFromURL = async function(url, mutator) {
|
proto.getFormValuesFromURL = async function(url, mutator) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.setState(previousState => {
|
this.setState(previousState => {
|
||||||
if (previousState.formState.get('state') === FormState.Loading) {
|
if (previousState.formState.get('state') === FormState.Loading) {
|
||||||
|
@ -1057,7 +1075,7 @@ function withForm(target) {
|
||||||
this.populateFormValues(data);
|
this.populateFormValues(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.validateAndSendFormValuesToURL = async function(method, url, mutator) {
|
proto.validateAndSendFormValuesToURL = async function(method, url, mutator) {
|
||||||
await this.waitForFormServerValidated();
|
await this.waitForFormServerValidated();
|
||||||
|
|
||||||
if (this.isFormWithoutErrors()) {
|
if (this.isFormWithoutErrors()) {
|
||||||
|
@ -1081,7 +1099,7 @@ function withForm(target) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
inst.populateFormValues = function(data) {
|
proto.populateFormValues = function(data) {
|
||||||
this.setState(previousState => ({
|
this.setState(previousState => ({
|
||||||
formState: previousState.formState.withMutations(mutState => {
|
formState: previousState.formState.withMutations(mutState => {
|
||||||
mutState.set('state', FormState.Ready);
|
mutState.set('state', FormState.Ready);
|
||||||
|
@ -1099,17 +1117,17 @@ function withForm(target) {
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.waitForFormServerValidated = async function() {
|
proto.waitForFormServerValidated = async function() {
|
||||||
if (!this.isFormServerValidated()) {
|
if (!this.isFormServerValidated()) {
|
||||||
await new Promise(resolve => { formValidateResolve = resolve; });
|
await new Promise(resolve => { formValidateResolve = resolve; });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.scheduleFormRevalidate = function() {
|
proto.scheduleFormRevalidate = function() {
|
||||||
scheduleValidateForm(this);
|
scheduleValidateForm(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.updateForm = function(mutator) {
|
proto.updateForm = function(mutator) {
|
||||||
this.setState(previousState => {
|
this.setState(previousState => {
|
||||||
const onChangeBeforeValidationCallback = this.state.formSettings.onChangeBeforeValidation || {};
|
const onChangeBeforeValidationCallback = this.state.formSettings.onChangeBeforeValidation || {};
|
||||||
|
|
||||||
|
@ -1152,7 +1170,7 @@ function withForm(target) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.updateFormValue = function(key, value) {
|
proto.updateFormValue = function(key, value) {
|
||||||
this.setState(previousState => {
|
this.setState(previousState => {
|
||||||
const oldValue = previousState.formState.getIn(['data', key, 'value']);
|
const oldValue = previousState.formState.getIn(['data', key, 'value']);
|
||||||
|
|
||||||
|
@ -1193,35 +1211,35 @@ function withForm(target) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.getFormValue = function(name) {
|
proto.getFormValue = function(name) {
|
||||||
return this.state.formState.getIn(['data', name, 'value']);
|
return this.state.formState.getIn(['data', name, 'value']);
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.getFormValues = function(name) {
|
proto.getFormValues = function(name) {
|
||||||
return this.state.formState.get('data').map(attr => attr.get('value')).toJS();
|
return this.state.formState.get('data').map(attr => attr.get('value')).toJS();
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.getFormError = function(name) {
|
proto.getFormError = function(name) {
|
||||||
return this.state.formState.getIn(['data', name, 'error']);
|
return this.state.formState.getIn(['data', name, 'error']);
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.isFormWithLoadingNotice = function() {
|
proto.isFormWithLoadingNotice = function() {
|
||||||
return this.state.formState.get('state') === FormState.LoadingWithNotice;
|
return this.state.formState.get('state') === FormState.LoadingWithNotice;
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.isFormLoading = function() {
|
proto.isFormLoading = function() {
|
||||||
return this.state.formState.get('state') === FormState.Loading || this.state.formState.get('state') === FormState.LoadingWithNotice;
|
return this.state.formState.get('state') === FormState.Loading || this.state.formState.get('state') === FormState.LoadingWithNotice;
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.isFormReady = function() {
|
proto.isFormReady = function() {
|
||||||
return this.state.formState.get('state') === FormState.Ready;
|
return this.state.formState.get('state') === FormState.Ready;
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.isFormValidationShown = function() {
|
proto.isFormValidationShown = function() {
|
||||||
return this.state.formState.get('isValidationShown');
|
return this.state.formState.get('isValidationShown');
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.addFormValidationClass = function(className, name) {
|
proto.addFormValidationClass = function(className, name) {
|
||||||
if (this.isFormValidationShown()) {
|
if (this.isFormValidationShown()) {
|
||||||
const error = this.getFormError(name);
|
const error = this.getFormError(name);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -1234,7 +1252,7 @@ function withForm(target) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.getFormValidationMessage = function(name) {
|
proto.getFormValidationMessage = function(name) {
|
||||||
if (this.isFormValidationShown()) {
|
if (this.isFormValidationShown()) {
|
||||||
return this.getFormError(name);
|
return this.getFormError(name);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1242,31 +1260,31 @@ function withForm(target) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.showFormValidation = function() {
|
proto.showFormValidation = function() {
|
||||||
this.setState(previousState => ({formState: previousState.formState.set('isValidationShown', true)}));
|
this.setState(previousState => ({formState: previousState.formState.set('isValidationShown', true)}));
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.hideFormValidation = function() {
|
proto.hideFormValidation = function() {
|
||||||
this.setState(previousState => ({formState: previousState.formState.set('isValidationShown', false)}));
|
this.setState(previousState => ({formState: previousState.formState.set('isValidationShown', false)}));
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.isFormWithoutErrors = function() {
|
proto.isFormWithoutErrors = function() {
|
||||||
return !this.state.formState.get('data').find(attr => attr.get('error'));
|
return !this.state.formState.get('data').find(attr => attr.get('error'));
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.isFormServerValidated = function() {
|
proto.isFormServerValidated = function() {
|
||||||
return !this.state.formSettings.serverValidation || this.state.formSettings.serverValidation.changed.every(attr => this.state.formState.getIn(['data', attr, 'serverValidated']));
|
return !this.state.formSettings.serverValidation || this.state.formSettings.serverValidation.changed.every(attr => this.state.formState.getIn(['data', attr, 'serverValidated']));
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.getFormStatusMessageText = function() {
|
proto.getFormStatusMessageText = function() {
|
||||||
return this.state.formState.get('statusMessageText');
|
return this.state.formState.get('statusMessageText');
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.getFormStatusMessageSeverity = function() {
|
proto.getFormStatusMessageSeverity = function() {
|
||||||
return this.state.formState.get('statusMessageSeverity');
|
return this.state.formState.get('statusMessageSeverity');
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.setFormStatusMessage = function(severity, text) {
|
proto.setFormStatusMessage = function(severity, text) {
|
||||||
this.setState(previousState => ({
|
this.setState(previousState => ({
|
||||||
formState: previousState.formState.withMutations(map => {
|
formState: previousState.formState.withMutations(map => {
|
||||||
map.set('statusMessageText', text);
|
map.set('statusMessageText', text);
|
||||||
|
@ -1275,7 +1293,7 @@ function withForm(target) {
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.clearFormStatusMessage = function() {
|
proto.clearFormStatusMessage = function() {
|
||||||
this.setState(previousState => ({
|
this.setState(previousState => ({
|
||||||
formState: previousState.formState.withMutations(map => {
|
formState: previousState.formState.withMutations(map => {
|
||||||
map.set('statusMessageText', '');
|
map.set('statusMessageText', '');
|
||||||
|
@ -1283,19 +1301,19 @@ function withForm(target) {
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.enableForm = function() {
|
proto.enableForm = function() {
|
||||||
this.setState(previousState => ({formState: previousState.formState.set('isDisabled', false)}));
|
this.setState(previousState => ({formState: previousState.formState.set('isDisabled', false)}));
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.disableForm = function() {
|
proto.disableForm = function() {
|
||||||
this.setState(previousState => ({formState: previousState.formState.set('isDisabled', true)}));
|
this.setState(previousState => ({formState: previousState.formState.set('isDisabled', true)}));
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.isFormDisabled = function() {
|
proto.isFormDisabled = function() {
|
||||||
return this.state.formState.get('isDisabled');
|
return this.state.formState.get('isDisabled');
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.formHandleChangedError = async function(fn) {
|
proto.formHandleChangedError = async function(fn) {
|
||||||
const t = this.props.t;
|
const t = this.props.t;
|
||||||
try {
|
try {
|
||||||
await fn();
|
await fn();
|
||||||
|
@ -1337,8 +1355,8 @@ function withForm(target) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return target;
|
return TargetClass;
|
||||||
}
|
});
|
||||||
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -9,12 +9,11 @@ import LanguageDetector
|
||||||
import mailtrainConfig
|
import mailtrainConfig
|
||||||
from 'mailtrainConfig';
|
from 'mailtrainConfig';
|
||||||
|
|
||||||
import hoistStatics
|
|
||||||
from 'hoist-non-react-statics';
|
|
||||||
|
|
||||||
import {convertToFake, getLang} from '../../../shared/langs';
|
import {convertToFake, getLang} from '../../../shared/langs';
|
||||||
|
import {createComponentMixin} from "./decorator-helpers";
|
||||||
|
|
||||||
import lang_en_US_common from "../../../locales/en-US/common";
|
import lang_en_US_common from "../../../locales/en-US/common";
|
||||||
|
import {withPageHelpers} from "./page-common";
|
||||||
|
|
||||||
const resourcesCommon = {
|
const resourcesCommon = {
|
||||||
'en-US': lang_en_US_common,
|
'en-US': lang_en_US_common,
|
||||||
|
@ -42,8 +41,7 @@ i18n
|
||||||
},
|
},
|
||||||
|
|
||||||
react: {
|
react: {
|
||||||
wait: true,
|
wait: true
|
||||||
defaultTransParent: 'span' // This is because we use React < v16 FIXME
|
|
||||||
},
|
},
|
||||||
|
|
||||||
detection: {
|
detection: {
|
||||||
|
@ -64,34 +62,9 @@ i18n
|
||||||
export default i18n;
|
export default i18n;
|
||||||
|
|
||||||
|
|
||||||
export function withTranslation(opts) {
|
export const withTranslation = createComponentMixin([], [], (TargetClass, InnerClass) => {
|
||||||
if (opts && opts.delegateFuns) {
|
return withNamespaces()(TargetClass)
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function tMark(key) {
|
export function tMark(key) {
|
||||||
return key;
|
return key;
|
||||||
|
|
|
@ -1,21 +1,27 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import axios, { HTTPMethod } from './axios';
|
import axios, {HTTPMethod} from './axios';
|
||||||
import { withTranslation } from './i18n';
|
import {withTranslation} from './i18n';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
|
from 'prop-types';
|
||||||
import {
|
import {
|
||||||
Icon,
|
Icon,
|
||||||
ModalDialog
|
ModalDialog
|
||||||
} from "./bootstrap-components";
|
} from "./bootstrap-components";
|
||||||
import {getUrl} from "./urls";
|
import {getUrl} from "./urls";
|
||||||
import {withPageHelpers} from "./page";
|
import {withPageHelpers} from "./page";
|
||||||
import styles from './styles.scss';
|
import styles
|
||||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
from './styles.scss';
|
||||||
|
import interoperableErrors
|
||||||
|
from '../../../shared/interoperable-errors';
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
|
withPageHelpers
|
||||||
|
])
|
||||||
export class RestActionModalDialog extends Component {
|
export class RestActionModalDialog extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
|
@ -127,8 +133,10 @@ function _getDependencyErrorMessage(err, t, name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
|
withPageHelpers
|
||||||
|
])
|
||||||
export class DeleteModalDialog extends Component {
|
export class DeleteModalDialog extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from './i18n';
|
import {withTranslation} from './i18n';
|
||||||
import { TreeTableSelect } from './form';
|
import {TreeTableSelect} from './form';
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
|
withTranslation
|
||||||
|
])
|
||||||
class NamespaceSelect extends Component {
|
class NamespaceSelect extends Component {
|
||||||
render() {
|
render() {
|
||||||
const t = this.props.t;
|
const t = this.props.t;
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from "react";
|
import React
|
||||||
import PropTypes from "prop-types";
|
from "react";
|
||||||
import {withRouter} from "react-router";
|
import {withRouter} from "react-router";
|
||||||
import {withErrorHandling} from "./error-handling";
|
import {withErrorHandling} from "./error-handling";
|
||||||
import axios from "../lib/axios";
|
import axios
|
||||||
|
from "../lib/axios";
|
||||||
import {getUrl} from "./urls";
|
import {getUrl} from "./urls";
|
||||||
|
import {createComponentMixin} from "./decorator-helpers";
|
||||||
|
|
||||||
function needsResolve(route, nextRoute, match, nextMatch) {
|
export function needsResolve(route, nextRoute, match, nextMatch) {
|
||||||
const resolve = route.resolve;
|
const resolve = route.resolve;
|
||||||
const nextResolve = nextRoute.resolve;
|
const nextResolve = nextRoute.resolve;
|
||||||
|
|
||||||
|
@ -25,7 +27,7 @@ function needsResolve(route, nextRoute, match, nextMatch) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resolve(route, match) {
|
export async function resolve(route, match) {
|
||||||
const keys = Object.keys(route.resolve);
|
const keys = Object.keys(route.resolve);
|
||||||
|
|
||||||
const promises = keys.map(key => {
|
const promises = keys.map(key => {
|
||||||
|
@ -46,7 +48,7 @@ async function resolve(route, match) {
|
||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRoutes(urlPrefix, resolve, parents, structure, navs, primaryMenuComponent, secondaryMenuComponent) {
|
export function getRoutes(urlPrefix, resolve, parents, structure, navs, primaryMenuComponent, secondaryMenuComponent) {
|
||||||
let routes = [];
|
let routes = [];
|
||||||
for (let routeKey in structure) {
|
for (let routeKey in structure) {
|
||||||
const entry = structure[routeKey];
|
const entry = structure[routeKey];
|
||||||
|
@ -119,39 +121,23 @@ function getRoutes(urlPrefix, resolve, parents, structure, navs, primaryMenuComp
|
||||||
return routes;
|
return routes;
|
||||||
}
|
}
|
||||||
|
|
||||||
function withPageHelpers(target) {
|
export const SectionContentContext = React.createContext(null);
|
||||||
target = withErrorHandling(target);
|
export const withPageHelpers = createComponentMixin([{context: SectionContentContext, propName: 'sectionContent'}], [withErrorHandling], (TargetClass, InnerClass) => {
|
||||||
|
InnerClass.prototype.setFlashMessage = function(severity, text) {
|
||||||
const inst = target.prototype;
|
return this.props.sectionContent.setFlashMessage(severity, text);
|
||||||
|
|
||||||
const contextTypes = target.contextTypes || {};
|
|
||||||
|
|
||||||
contextTypes.sectionContent = PropTypes.object.isRequired;
|
|
||||||
|
|
||||||
target.contextTypes = contextTypes;
|
|
||||||
|
|
||||||
inst.setFlashMessage = function(severity, text) {
|
|
||||||
return this.context.sectionContent.setFlashMessage(severity, text);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inst.navigateTo = function(path) {
|
InnerClass.prototype.navigateTo = function(path) {
|
||||||
return this.context.sectionContent.navigateTo(path);
|
return this.props.sectionContent.navigateTo(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
inst.navigateBack = function() {
|
InnerClass.prototype.navigateBack = function() {
|
||||||
return this.context.sectionContent.navigateBack();
|
return this.props.sectionContent.navigateBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
inst.navigateToWithFlashMessage = function(path, severity, text) {
|
InnerClass.prototype.navigateToWithFlashMessage = function(path, severity, text) {
|
||||||
return this.context.sectionContent.navigateToWithFlashMessage(path, severity, text);
|
return this.props.sectionContent.navigateToWithFlashMessage(path, severity, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
return target;
|
return TargetClass;
|
||||||
}
|
});
|
||||||
|
|
||||||
export {
|
|
||||||
needsResolve,
|
|
||||||
resolve,
|
|
||||||
getRoutes,
|
|
||||||
withPageHelpers
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,17 +1,45 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import { withTranslation } from './i18n';
|
import {withTranslation} from './i18n';
|
||||||
import PropTypes from "prop-types";
|
import PropTypes
|
||||||
|
from "prop-types";
|
||||||
import {withRouter} from "react-router";
|
import {withRouter} from "react-router";
|
||||||
import {BrowserRouter as Router, Link, Redirect, Route, Switch} from "react-router-dom";
|
import {
|
||||||
import {withAsyncErrorHandler, withErrorHandling} from "./error-handling";
|
BrowserRouter as Router,
|
||||||
import interoperableErrors from "../../../shared/interoperable-errors";
|
Link,
|
||||||
import {Button, DismissibleAlert} from "./bootstrap-components";
|
Redirect,
|
||||||
import mailtrainConfig from "mailtrainConfig";
|
Route,
|
||||||
import styles from "./styles.scss";
|
Switch
|
||||||
import {getRoutes, needsResolve, resolve, withPageHelpers} from "./page-common";
|
} from "react-router-dom";
|
||||||
|
import {
|
||||||
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from "./error-handling";
|
||||||
|
import interoperableErrors
|
||||||
|
from "../../../shared/interoperable-errors";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
DismissibleAlert
|
||||||
|
} from "./bootstrap-components";
|
||||||
|
import mailtrainConfig
|
||||||
|
from "mailtrainConfig";
|
||||||
|
import styles
|
||||||
|
from "./styles.scss";
|
||||||
|
import {
|
||||||
|
getRoutes,
|
||||||
|
needsResolve,
|
||||||
|
resolve,
|
||||||
|
SectionContentContext,
|
||||||
|
withPageHelpers
|
||||||
|
} from "./page-common";
|
||||||
import {getBaseDir} from "./urls";
|
import {getBaseDir} from "./urls";
|
||||||
|
import {
|
||||||
|
createComponentMixin,
|
||||||
|
withComponentMixins
|
||||||
|
} from "./decorator-helpers";
|
||||||
|
|
||||||
|
export { withPageHelpers }
|
||||||
|
|
||||||
class Breadcrumb extends Component {
|
class Breadcrumb extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -149,8 +177,10 @@ class SecondaryNavBar extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withErrorHandling
|
withTranslation,
|
||||||
|
withErrorHandling
|
||||||
|
])
|
||||||
class RouteContent extends Component {
|
class RouteContent extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -276,8 +306,10 @@ class RouteContent extends Component {
|
||||||
|
|
||||||
|
|
||||||
@withRouter
|
@withRouter
|
||||||
@withErrorHandling
|
@withComponentMixins([
|
||||||
class SectionContent extends Component {
|
withErrorHandling
|
||||||
|
])
|
||||||
|
export class SectionContent extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
@ -295,16 +327,6 @@ class SectionContent extends Component {
|
||||||
root: PropTypes.string.isRequired
|
root: PropTypes.string.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
static childContextTypes = {
|
|
||||||
sectionContent: PropTypes.object
|
|
||||||
}
|
|
||||||
|
|
||||||
getChildContext() {
|
|
||||||
return {
|
|
||||||
sectionContent: this
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
setFlashMessage(severity, text) {
|
setFlashMessage(severity, text) {
|
||||||
this.setState({
|
this.setState({
|
||||||
flashMessageText: text,
|
flashMessageText: text,
|
||||||
|
@ -367,13 +389,17 @@ class SectionContent extends Component {
|
||||||
let routes = getRoutes('', {}, [], this.props.structure, [], null, null);
|
let routes = getRoutes('', {}, [], this.props.structure, [], null, null);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<SectionContentContext.Provider value={this}>
|
||||||
<Switch>{routes.map(x => this.renderRoute(x))}</Switch>
|
<Switch>{routes.map(x => this.renderRoute(x))}</Switch>
|
||||||
|
</SectionContentContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
class Section extends Component {
|
withTranslation
|
||||||
|
])
|
||||||
|
export class Section extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
@ -398,7 +424,7 @@ class Section extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Title extends Component {
|
export class Title extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
@ -409,7 +435,7 @@ class Title extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Toolbar extends Component {
|
export class Toolbar extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
@ -428,7 +454,7 @@ class Toolbar extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NavButton extends Component {
|
export class NavButton extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
label: PropTypes.string,
|
label: PropTypes.string,
|
||||||
icon: PropTypes.string,
|
icon: PropTypes.string,
|
||||||
|
@ -445,7 +471,7 @@ class NavButton extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MenuLink extends Component {
|
export class MenuLink extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
to: PropTypes.string,
|
to: PropTypes.string,
|
||||||
className: PropTypes.string
|
className: PropTypes.string
|
||||||
|
@ -460,33 +486,17 @@ class MenuLink extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function requiresAuthenticatedUser(target) {
|
export const requiresAuthenticatedUser = createComponentMixin([], [withPageHelpers], (TargetClass, InnerClass) => {
|
||||||
const comp1 = withPageHelpers(target);
|
class RequiresAuthenticatedUser extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
function comp2(props, context) {
|
super(props);
|
||||||
if (!new.target) {
|
props.sectionContent.ensureAuthenticated();
|
||||||
throw new TypeError();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context.sectionContent.ensureAuthenticated();
|
render() {
|
||||||
return Reflect.construct(comp1, [props, context], new.target);
|
return <TargetClass {...this.props}/>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
comp2.prototype = comp1.prototype;
|
return RequiresAuthenticatedUser;
|
||||||
|
});
|
||||||
for (const attr in comp1) {
|
|
||||||
comp2[attr] = comp1[attr];
|
|
||||||
}
|
|
||||||
|
|
||||||
return comp2;
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
Section,
|
|
||||||
Title,
|
|
||||||
Toolbar,
|
|
||||||
NavButton,
|
|
||||||
MenuLink,
|
|
||||||
withPageHelpers,
|
|
||||||
requiresAuthenticatedUser
|
|
||||||
};
|
|
||||||
|
|
|
@ -29,9 +29,12 @@ import CKEditor
|
||||||
from "react-ckeditor-component";
|
from "react-ckeditor-component";
|
||||||
|
|
||||||
import {initialHeight} from "./sandboxed-ckeditor-shared";
|
import {initialHeight} from "./sandboxed-ckeditor-shared";
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
|
withTranslation
|
||||||
|
])
|
||||||
class CKEditorSandbox extends Component {
|
class CKEditorSandbox extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from './i18n';
|
import {withTranslation} from './i18n';
|
||||||
import PropTypes
|
import PropTypes
|
||||||
from "prop-types";
|
from "prop-types";
|
||||||
import styles
|
import styles
|
||||||
|
@ -11,10 +11,14 @@ import {UntrustedContentHost} from './untrusted';
|
||||||
import {Icon} from "./bootstrap-components";
|
import {Icon} from "./bootstrap-components";
|
||||||
import {getTrustedUrl} from "./urls";
|
import {getTrustedUrl} from "./urls";
|
||||||
|
|
||||||
import { initialHeight } from "./sandboxed-ckeditor-shared";
|
import {initialHeight} from "./sandboxed-ckeditor-shared";
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
const navbarHeight = 34; // Sync this with navbarheight in sandboxed-ckeditor.scss
|
const navbarHeight = 34; // Sync this with navbarheight in sandboxed-ckeditor.scss
|
||||||
|
|
||||||
@withTranslation({delegateFuns: ['exportState']})
|
@withComponentMixins([
|
||||||
|
withTranslation
|
||||||
|
], ['exportState'])
|
||||||
export class CKEditorHost extends Component {
|
export class CKEditorHost extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -35,10 +35,13 @@ import mjml2html
|
||||||
from "mjml4-in-browser";
|
from "mjml4-in-browser";
|
||||||
import juice
|
import juice
|
||||||
from "juice";
|
from "juice";
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
const refreshTimeout = 1000;
|
const refreshTimeout = 1000;
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
|
withTranslation
|
||||||
|
])
|
||||||
class CodeEditorSandbox extends Component {
|
class CodeEditorSandbox extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from './i18n';
|
import {withTranslation} from './i18n';
|
||||||
import PropTypes
|
import PropTypes
|
||||||
from "prop-types";
|
from "prop-types";
|
||||||
import styles
|
import styles
|
||||||
|
@ -10,8 +10,11 @@ import styles
|
||||||
import {UntrustedContentHost} from './untrusted';
|
import {UntrustedContentHost} from './untrusted';
|
||||||
import {Icon} from "./bootstrap-components";
|
import {Icon} from "./bootstrap-components";
|
||||||
import {getTrustedUrl} from "./urls";
|
import {getTrustedUrl} from "./urls";
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
@withTranslation({delegateFuns: ['exportState']})
|
@withComponentMixins([
|
||||||
|
withTranslation
|
||||||
|
], ['exportState'])
|
||||||
export class CodeEditorHost extends Component {
|
export class CodeEditorHost extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -39,6 +39,7 @@ import "./sandboxed-grapesjs.scss";
|
||||||
import axios
|
import axios
|
||||||
from './axios';
|
from './axios';
|
||||||
import {GrapesJSSourceType} from "./sandboxed-grapesjs-shared";
|
import {GrapesJSSourceType} from "./sandboxed-grapesjs-shared";
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
grapesjs.plugins.add('mailtrain-remove-buttons', (editor, opts = {}) => {
|
grapesjs.plugins.add('mailtrain-remove-buttons', (editor, opts = {}) => {
|
||||||
|
@ -52,7 +53,9 @@ grapesjs.plugins.add('mailtrain-remove-buttons', (editor, opts = {}) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
|
withTranslation
|
||||||
|
])
|
||||||
export class GrapesJSSandbox extends Component {
|
export class GrapesJSSandbox extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from './i18n';
|
import {withTranslation} from './i18n';
|
||||||
import PropTypes
|
import PropTypes
|
||||||
from "prop-types";
|
from "prop-types";
|
||||||
import styles
|
import styles
|
||||||
|
@ -10,8 +10,11 @@ import styles
|
||||||
import {UntrustedContentHost} from './untrusted';
|
import {UntrustedContentHost} from './untrusted';
|
||||||
import {Icon} from "./bootstrap-components";
|
import {Icon} from "./bootstrap-components";
|
||||||
import {getTrustedUrl} from "./urls";
|
import {getTrustedUrl} from "./urls";
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
@withTranslation({delegateFuns: ['exportState']})
|
@withComponentMixins([
|
||||||
|
withTranslation
|
||||||
|
], ['exportState'])
|
||||||
export class GrapesJSHost extends Component {
|
export class GrapesJSHost extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -22,9 +22,12 @@ import {
|
||||||
base,
|
base,
|
||||||
unbase
|
unbase
|
||||||
} from "../../../shared/templates";
|
} from "../../../shared/templates";
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
|
withTranslation
|
||||||
|
])
|
||||||
class MosaicoSandbox extends Component {
|
class MosaicoSandbox extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from './i18n';
|
import {withTranslation} from './i18n';
|
||||||
import PropTypes
|
import PropTypes
|
||||||
from "prop-types";
|
from "prop-types";
|
||||||
import styles
|
import styles
|
||||||
|
@ -10,9 +10,12 @@ import styles
|
||||||
import {UntrustedContentHost} from './untrusted';
|
import {UntrustedContentHost} from './untrusted';
|
||||||
import {Icon} from "./bootstrap-components";
|
import {Icon} from "./bootstrap-components";
|
||||||
import {getTrustedUrl} from "./urls";
|
import {getTrustedUrl} from "./urls";
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
@withTranslation({delegateFuns: ['exportState']})
|
@withComponentMixins([
|
||||||
|
withTranslation
|
||||||
|
], ['exportState'])
|
||||||
export class MosaicoHost extends Component {
|
export class MosaicoHost extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,22 +1,31 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import ReactDOMServer from 'react-dom/server';
|
import ReactDOMServer
|
||||||
import PropTypes from 'prop-types';
|
from 'react-dom/server';
|
||||||
import { withTranslation } from './i18n';
|
import PropTypes
|
||||||
|
from 'prop-types';
|
||||||
|
import {withTranslation} from './i18n';
|
||||||
|
|
||||||
import jQuery from 'jquery';
|
import jQuery
|
||||||
|
from 'jquery';
|
||||||
|
|
||||||
import 'datatables.net';
|
import 'datatables.net';
|
||||||
import 'datatables.net-bs';
|
import 'datatables.net-bs';
|
||||||
import 'datatables.net-bs/css/dataTables.bootstrap.css';
|
import 'datatables.net-bs/css/dataTables.bootstrap.css';
|
||||||
|
|
||||||
import axios from './axios';
|
import axios
|
||||||
|
from './axios';
|
||||||
|
|
||||||
import { withPageHelpers } from './page'
|
import {withPageHelpers} from './page'
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from './error-handling';
|
import {
|
||||||
import styles from "./styles.scss";
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from './error-handling';
|
||||||
|
import styles
|
||||||
|
from "./styles.scss";
|
||||||
import {getUrl} from "./urls";
|
import {getUrl} from "./urls";
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
//dtFactory();
|
//dtFactory();
|
||||||
//dtSelectFactory();
|
//dtSelectFactory();
|
||||||
|
@ -28,9 +37,11 @@ const TableSelectMode = {
|
||||||
MULTI: 2
|
MULTI: 2
|
||||||
};
|
};
|
||||||
|
|
||||||
@withTranslation({delegateFuns: ['refresh']})
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
|
withPageHelpers
|
||||||
|
], ['refresh'])
|
||||||
class Table extends Component {
|
class Table extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,21 +1,30 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import ReactDOMServer from 'react-dom/server';
|
import ReactDOMServer
|
||||||
import { withTranslation } from './i18n';
|
from 'react-dom/server';
|
||||||
import PropTypes from 'prop-types';
|
import {withTranslation} from './i18n';
|
||||||
|
import PropTypes
|
||||||
|
from 'prop-types';
|
||||||
|
|
||||||
import jQuery from 'jquery';
|
import jQuery
|
||||||
|
from 'jquery';
|
||||||
import '../../vendor/jquery/jquery-ui-1.12.1.min.js';
|
import '../../vendor/jquery/jquery-ui-1.12.1.min.js';
|
||||||
import '../../vendor/fancytree/jquery.fancytree-all.min.js';
|
import '../../vendor/fancytree/jquery.fancytree-all.min.js';
|
||||||
import '../../vendor/fancytree/skin-bootstrap/ui.fancytree.min.css';
|
import '../../vendor/fancytree/skin-bootstrap/ui.fancytree.min.css';
|
||||||
import './tree.css';
|
import './tree.css';
|
||||||
import axios from './axios';
|
import axios
|
||||||
|
from './axios';
|
||||||
|
|
||||||
import { withPageHelpers } from './page'
|
import {withPageHelpers} from './page'
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from './error-handling';
|
import {
|
||||||
import styles from "./styles.scss";
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from './error-handling';
|
||||||
|
import styles
|
||||||
|
from "./styles.scss";
|
||||||
import {getUrl} from "./urls";
|
import {getUrl} from "./urls";
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
const TreeSelectMode = {
|
const TreeSelectMode = {
|
||||||
NONE: 0,
|
NONE: 0,
|
||||||
|
@ -23,9 +32,11 @@ const TreeSelectMode = {
|
||||||
MULTI: 2
|
MULTI: 2
|
||||||
};
|
};
|
||||||
|
|
||||||
@withTranslation({delegateFuns: ['refresh']})
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
|
withPageHelpers
|
||||||
|
], ['refresh'])
|
||||||
class TreeTable extends Component {
|
class TreeTable extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes
|
||||||
import { withTranslation } from './i18n';
|
from "prop-types";
|
||||||
|
import {withTranslation} from './i18n';
|
||||||
import {
|
import {
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
withPageHelpers
|
withPageHelpers
|
||||||
|
@ -11,18 +12,23 @@ import {
|
||||||
withAsyncErrorHandler,
|
withAsyncErrorHandler,
|
||||||
withErrorHandling
|
withErrorHandling
|
||||||
} from "./error-handling";
|
} from "./error-handling";
|
||||||
import axios from "./axios";
|
import axios
|
||||||
import styles from "./styles.scss";
|
from "./axios";
|
||||||
|
import styles
|
||||||
|
from "./styles.scss";
|
||||||
import {
|
import {
|
||||||
getSandboxUrl,
|
getSandboxUrl,
|
||||||
getTrustedUrl,
|
getTrustedUrl,
|
||||||
getUrl,
|
getUrl,
|
||||||
setRestrictedAccessToken
|
setRestrictedAccessToken
|
||||||
} from "./urls";
|
} from "./urls";
|
||||||
|
import {withComponentMixins} from "./decorator-helpers";
|
||||||
|
|
||||||
@withPageHelpers
|
@withComponentMixins([
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
], ['ask'])
|
||||||
export class UntrustedContentHost extends Component {
|
export class UntrustedContentHost extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -173,7 +179,9 @@ export class UntrustedContentHost extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
|
withTranslation
|
||||||
|
])
|
||||||
export class UntrustedContentRoot extends Component {
|
export class UntrustedContentRoot extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -36,12 +36,15 @@ import styles
|
||||||
import mailtrainConfig
|
import mailtrainConfig
|
||||||
from 'mailtrainConfig';
|
from 'mailtrainConfig';
|
||||||
import {getMailerTypes} from "../send-configurations/helpers";
|
import {getMailerTypes} from "../send-configurations/helpers";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../lib/i18n';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import {requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton} from '../lib/page';
|
import {
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
NavButton,
|
||||||
import { Table } from '../lib/table';
|
requiresAuthenticatedUser,
|
||||||
import axios from '../lib/axios';
|
Title,
|
||||||
|
Toolbar,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../lib/page';
|
||||||
|
import {
|
||||||
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from '../lib/error-handling';
|
||||||
|
import {Table} from '../lib/table';
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import {Icon} from "../lib/bootstrap-components";
|
import {Icon} from "../lib/bootstrap-components";
|
||||||
import {checkPermissions} from "../lib/permissions";
|
import {checkPermissions} from "../lib/permissions";
|
||||||
|
@ -14,11 +22,16 @@ import {
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../lib/modals";
|
} from "../lib/modals";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
import {withForm} from "../lib/form";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withForm,
|
||||||
@requiresAuthenticatedUser
|
withErrorHandling,
|
||||||
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../lib/i18n';
|
from 'prop-types';
|
||||||
|
import {withTranslation} from '../lib/i18n';
|
||||||
import {
|
import {
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
Title,
|
Title,
|
||||||
|
@ -12,17 +13,21 @@ import {withErrorHandling} from '../lib/error-handling';
|
||||||
import {Table} from '../lib/table';
|
import {Table} from '../lib/table';
|
||||||
import {getTriggerTypes} from '../campaigns/triggers/helpers';
|
import {getTriggerTypes} from '../campaigns/triggers/helpers';
|
||||||
import {Icon} from "../lib/bootstrap-components";
|
import {Icon} from "../lib/bootstrap-components";
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
import mailtrainConfig
|
||||||
|
from 'mailtrainConfig';
|
||||||
import {
|
import {
|
||||||
tableAddDeleteButton,
|
tableAddDeleteButton,
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../lib/modals";
|
} from "../lib/modals";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -40,12 +40,15 @@ import styles
|
||||||
from "../../lib/styles.scss";
|
from "../../lib/styles.scss";
|
||||||
import 'brace/mode/json';
|
import 'brace/mode/json';
|
||||||
import 'brace/mode/handlebars';
|
import 'brace/mode/handlebars';
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,23 +1,33 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../../lib/i18n';
|
from 'prop-types';
|
||||||
import {requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton} from '../../lib/page';
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import { withErrorHandling } from '../../lib/error-handling';
|
import {
|
||||||
import { Table } from '../../lib/table';
|
NavButton,
|
||||||
import { getFieldTypes } from './helpers';
|
requiresAuthenticatedUser,
|
||||||
|
Title,
|
||||||
|
Toolbar,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../../lib/page';
|
||||||
|
import {withErrorHandling} from '../../lib/error-handling';
|
||||||
|
import {Table} from '../../lib/table';
|
||||||
|
import {getFieldTypes} from './helpers';
|
||||||
import {Icon} from "../../lib/bootstrap-components";
|
import {Icon} from "../../lib/bootstrap-components";
|
||||||
import {
|
import {
|
||||||
tableAddDeleteButton,
|
tableAddDeleteButton,
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../../lib/modals";
|
} from "../../lib/modals";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -16,7 +16,6 @@ import {
|
||||||
AlignedRow,
|
AlignedRow,
|
||||||
Button,
|
Button,
|
||||||
ButtonRow,
|
ButtonRow,
|
||||||
CheckBox,
|
|
||||||
Dropdown,
|
Dropdown,
|
||||||
Fieldset,
|
Fieldset,
|
||||||
Form,
|
Form,
|
||||||
|
@ -48,13 +47,15 @@ import formsStyles
|
||||||
from "./styles.scss";
|
from "./styles.scss";
|
||||||
import axios
|
import axios
|
||||||
from "../../lib/axios";
|
from "../../lib/axios";
|
||||||
import {UntrustedContentHost} from "../../lib/untrusted";
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../../lib/i18n';
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import {requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton} from '../../lib/page';
|
import {
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../../lib/error-handling';
|
NavButton,
|
||||||
import { Table } from '../../lib/table';
|
requiresAuthenticatedUser,
|
||||||
import axios from '../../lib/axios';
|
Title,
|
||||||
|
Toolbar,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../../lib/page';
|
||||||
|
import {
|
||||||
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from '../../lib/error-handling';
|
||||||
|
import {Table} from '../../lib/table';
|
||||||
import {Icon} from "../../lib/bootstrap-components";
|
import {Icon} from "../../lib/bootstrap-components";
|
||||||
import {checkPermissions} from "../../lib/permissions";
|
import {checkPermissions} from "../../lib/permissions";
|
||||||
import {
|
import {
|
||||||
|
@ -13,11 +21,14 @@ import {
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../../lib/modals";
|
} from "../../lib/modals";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../../lib/i18n';
|
from 'prop-types';
|
||||||
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import {
|
import {
|
||||||
NavButton,
|
NavButton,
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
|
@ -32,15 +33,18 @@ import {
|
||||||
ImportSource,
|
ImportSource,
|
||||||
inProgress,
|
inProgress,
|
||||||
MappingType,
|
MappingType,
|
||||||
prepInProgress,
|
prepInProgress
|
||||||
runInProgress
|
|
||||||
} from '../../../../shared/imports';
|
} from '../../../../shared/imports';
|
||||||
import axios from "../../lib/axios";
|
import axios
|
||||||
|
from "../../lib/axios";
|
||||||
import {getUrl} from "../../lib/urls";
|
import {getUrl} from "../../lib/urls";
|
||||||
import listStyles from "../styles.scss";
|
import listStyles
|
||||||
import styles from "../../lib/styles.scss";
|
from "../styles.scss";
|
||||||
|
import styles
|
||||||
|
from "../../lib/styles.scss";
|
||||||
import interoperableErrors
|
import interoperableErrors
|
||||||
from "../../../../shared/interoperable-errors";
|
from "../../../../shared/interoperable-errors";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
function truncate(str, len, ending = '...') {
|
function truncate(str, len, ending = '...') {
|
||||||
|
@ -54,11 +58,13 @@ function truncate(str, len, ending = '...') {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../../lib/i18n';
|
from 'prop-types';
|
||||||
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import {
|
import {
|
||||||
NavButton,
|
NavButton,
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
|
@ -14,19 +15,24 @@ import {withErrorHandling} from '../../lib/error-handling';
|
||||||
import {Table} from '../../lib/table';
|
import {Table} from '../../lib/table';
|
||||||
import {getImportLabels} from './helpers';
|
import {getImportLabels} from './helpers';
|
||||||
import {Icon} from "../../lib/bootstrap-components";
|
import {Icon} from "../../lib/bootstrap-components";
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
import mailtrainConfig
|
||||||
import moment from "moment";
|
from 'mailtrainConfig';
|
||||||
|
import moment
|
||||||
|
from "moment";
|
||||||
import {inProgress} from '../../../../shared/imports';
|
import {inProgress} from '../../../../shared/imports';
|
||||||
import {
|
import {
|
||||||
tableAddDeleteButton,
|
tableAddDeleteButton,
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../../lib/modals";
|
} from "../../lib/modals";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../../lib/i18n';
|
from 'prop-types';
|
||||||
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import {
|
import {
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
Title,
|
Title,
|
||||||
|
@ -14,16 +15,21 @@ import {
|
||||||
withErrorHandling
|
withErrorHandling
|
||||||
} from '../../lib/error-handling';
|
} from '../../lib/error-handling';
|
||||||
import {getImportLabels} from './helpers';
|
import {getImportLabels} from './helpers';
|
||||||
import axios from "../../lib/axios";
|
import axios
|
||||||
|
from "../../lib/axios";
|
||||||
import {getUrl} from "../../lib/urls";
|
import {getUrl} from "../../lib/urls";
|
||||||
import moment from "moment";
|
import moment
|
||||||
|
from "moment";
|
||||||
import {runStatusInProgress} from "../../../../shared/imports";
|
import {runStatusInProgress} from "../../../../shared/imports";
|
||||||
import {Table} from "../../lib/table";
|
import {Table} from "../../lib/table";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class Status extends Component {
|
export default class Status extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../../lib/i18n';
|
from 'prop-types';
|
||||||
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import {
|
import {
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
Title,
|
Title,
|
||||||
|
@ -10,8 +11,7 @@ import {
|
||||||
} from '../../lib/page';
|
} from '../../lib/page';
|
||||||
import {
|
import {
|
||||||
AlignedRow,
|
AlignedRow,
|
||||||
ButtonRow,
|
ButtonRow
|
||||||
Fieldset
|
|
||||||
} from '../../lib/form';
|
} from '../../lib/form';
|
||||||
import {
|
import {
|
||||||
withAsyncErrorHandler,
|
withAsyncErrorHandler,
|
||||||
|
@ -21,7 +21,6 @@ import {getImportLabels} from './helpers';
|
||||||
import {
|
import {
|
||||||
prepFinishedAndNotInProgress,
|
prepFinishedAndNotInProgress,
|
||||||
runInProgress,
|
runInProgress,
|
||||||
RunStatus,
|
|
||||||
runStatusInProgress
|
runStatusInProgress
|
||||||
} from '../../../../shared/imports';
|
} from '../../../../shared/imports';
|
||||||
import {Table} from "../../lib/table";
|
import {Table} from "../../lib/table";
|
||||||
|
@ -29,15 +28,21 @@ import {
|
||||||
Button,
|
Button,
|
||||||
Icon
|
Icon
|
||||||
} from "../../lib/bootstrap-components";
|
} from "../../lib/bootstrap-components";
|
||||||
import axios from "../../lib/axios";
|
import axios
|
||||||
|
from "../../lib/axios";
|
||||||
import {getUrl} from "../../lib/urls";
|
import {getUrl} from "../../lib/urls";
|
||||||
import moment from "moment";
|
import moment
|
||||||
import interoperableErrors from '../../../../shared/interoperable-errors';
|
from "moment";
|
||||||
|
import interoperableErrors
|
||||||
|
from '../../../../shared/interoperable-errors';
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class Status extends Component {
|
export default class Status extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes
|
||||||
import { withTranslation } from '../../lib/i18n';
|
from "prop-types";
|
||||||
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import {
|
import {
|
||||||
NavButton,
|
NavButton,
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
|
@ -22,28 +23,37 @@ import {
|
||||||
import {withErrorHandling} from "../../lib/error-handling";
|
import {withErrorHandling} from "../../lib/error-handling";
|
||||||
import {DeleteModalDialog} from "../../lib/modals";
|
import {DeleteModalDialog} from "../../lib/modals";
|
||||||
|
|
||||||
import styles from "./CUD.scss";
|
import styles
|
||||||
|
from "./CUD.scss";
|
||||||
import {DragDropContext} from "react-dnd";
|
import {DragDropContext} from "react-dnd";
|
||||||
import HTML5Backend from "react-dnd-html5-backend";
|
import HTML5Backend
|
||||||
import TouchBackend from "react-dnd-touch-backend";
|
from "react-dnd-html5-backend";
|
||||||
import SortableTree from "react-sortable-tree";
|
import TouchBackend
|
||||||
|
from "react-dnd-touch-backend";
|
||||||
|
import SortableTree
|
||||||
|
from "react-sortable-tree";
|
||||||
|
import 'react-sortable-tree/style.css';
|
||||||
import {
|
import {
|
||||||
ActionLink,
|
ActionLink,
|
||||||
Button,
|
Button,
|
||||||
Icon
|
Icon
|
||||||
} from "../../lib/bootstrap-components";
|
} from "../../lib/bootstrap-components";
|
||||||
import {getRuleHelpers} from "./helpers";
|
import {getRuleHelpers} from "./helpers";
|
||||||
import RuleSettingsPane from "./RuleSettingsPane";
|
import RuleSettingsPane
|
||||||
|
from "./RuleSettingsPane";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
// https://stackoverflow.com/a/4819886/1601953
|
// https://stackoverflow.com/a/4819886/1601953
|
||||||
const isTouchDevice = !!('ontouchstart' in window || navigator.maxTouchPoints);
|
const isTouchDevice = !!('ontouchstart' in window || navigator.maxTouchPoints);
|
||||||
|
|
||||||
@DragDropContext(isTouchDevice ? TouchBackend : HTML5Backend)
|
@DragDropContext(isTouchDevice ? TouchBackend : HTML5Backend)
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
// The code below keeps the segment settings in form value. However, it uses it as a mutable datastructure.
|
// The code below keeps the segment settings in form value. However, it uses it as a mutable datastructure.
|
||||||
// After initilization, segment settings is never set using setState. This is OK we update the state.rulesTree
|
// After initilization, segment settings is never set using setState. This is OK we update the state.rulesTree
|
||||||
|
|
|
@ -1,22 +1,32 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../../lib/i18n';
|
from 'prop-types';
|
||||||
import {requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton} from '../../lib/page';
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import { withErrorHandling } from '../../lib/error-handling';
|
import {
|
||||||
import { Table } from '../../lib/table';
|
NavButton,
|
||||||
|
requiresAuthenticatedUser,
|
||||||
|
Title,
|
||||||
|
Toolbar,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../../lib/page';
|
||||||
|
import {withErrorHandling} from '../../lib/error-handling';
|
||||||
|
import {Table} from '../../lib/table';
|
||||||
import {Icon} from "../../lib/bootstrap-components";
|
import {Icon} from "../../lib/bootstrap-components";
|
||||||
import {
|
import {
|
||||||
tableAddDeleteButton,
|
tableAddDeleteButton,
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../../lib/modals";
|
} from "../../lib/modals";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,21 +1,36 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes
|
||||||
import { withTranslation } from '../../lib/i18n';
|
from "prop-types";
|
||||||
import {requiresAuthenticatedUser, withPageHelpers} from "../../lib/page";
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import {Button, ButtonRow, Dropdown, Form, TableSelect, withForm} from "../../lib/form";
|
import {
|
||||||
|
requiresAuthenticatedUser,
|
||||||
|
withPageHelpers
|
||||||
|
} from "../../lib/page";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonRow,
|
||||||
|
Dropdown,
|
||||||
|
Form,
|
||||||
|
TableSelect,
|
||||||
|
withForm
|
||||||
|
} from "../../lib/form";
|
||||||
import {withErrorHandling} from "../../lib/error-handling";
|
import {withErrorHandling} from "../../lib/error-handling";
|
||||||
import {getRuleHelpers} from "./helpers";
|
import {getRuleHelpers} from "./helpers";
|
||||||
import {getFieldTypes} from "../fields/helpers";
|
import {getFieldTypes} from "../fields/helpers";
|
||||||
|
|
||||||
import styles from "./CUD.scss";
|
import styles
|
||||||
|
from "./CUD.scss";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -33,12 +33,15 @@ import {
|
||||||
} from './helpers';
|
} from './helpers';
|
||||||
import moment
|
import moment
|
||||||
from 'moment-timezone';
|
from 'moment-timezone';
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,37 +1,56 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../../lib/i18n';
|
from 'prop-types';
|
||||||
import {requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton} from '../../lib/page';
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import {withAsyncErrorHandler, withErrorHandling} from '../../lib/error-handling';
|
|
||||||
import { Table } from '../../lib/table';
|
|
||||||
import { SubscriptionStatus } from '../../../../shared/lists';
|
|
||||||
import moment from 'moment';
|
|
||||||
import {
|
import {
|
||||||
Dropdown, Form,
|
NavButton,
|
||||||
|
requiresAuthenticatedUser,
|
||||||
|
Title,
|
||||||
|
Toolbar,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../../lib/page';
|
||||||
|
import {withErrorHandling} from '../../lib/error-handling';
|
||||||
|
import {Table} from '../../lib/table';
|
||||||
|
import {SubscriptionStatus} from '../../../../shared/lists';
|
||||||
|
import moment
|
||||||
|
from 'moment';
|
||||||
|
import {
|
||||||
|
Dropdown,
|
||||||
|
Form,
|
||||||
withForm
|
withForm
|
||||||
} from '../../lib/form';
|
} from '../../lib/form';
|
||||||
import {Icon, Button} from "../../lib/bootstrap-components";
|
|
||||||
import {HTTPMethod} from '../../lib/axios';
|
|
||||||
import {getFieldTypes, getSubscriptionStatusLabels} from './helpers';
|
|
||||||
import {getUrl, getPublicUrl} from "../../lib/urls";
|
|
||||||
import {
|
import {
|
||||||
DeleteModalDialog,
|
Button,
|
||||||
RestActionModalDialog,
|
Icon
|
||||||
|
} from "../../lib/bootstrap-components";
|
||||||
|
import {HTTPMethod} from '../../lib/axios';
|
||||||
|
import {
|
||||||
|
getFieldTypes,
|
||||||
|
getSubscriptionStatusLabels
|
||||||
|
} from './helpers';
|
||||||
|
import {
|
||||||
|
getPublicUrl,
|
||||||
|
getUrl
|
||||||
|
} from "../../lib/urls";
|
||||||
|
import {
|
||||||
tableAddDeleteButton,
|
tableAddDeleteButton,
|
||||||
|
tableAddRestActionButton,
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender,
|
tableRestActionDialogRender
|
||||||
tableAddRestActionButton
|
|
||||||
} from "../../lib/modals";
|
} from "../../lib/modals";
|
||||||
import listStyles from "../styles.scss";
|
import listStyles
|
||||||
import styles from '../../lib/styles.scss';
|
from "../styles.scss";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,23 +1,47 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../lib/i18n';
|
from 'prop-types';
|
||||||
import {requiresAuthenticatedUser, withPageHelpers, Title, NavButton} from '../lib/page';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import { withForm, Form, FormSendMethod, InputField, TextArea, ButtonRow, Button, TreeTableSelect } from '../lib/form';
|
import {
|
||||||
import axios from '../lib/axios';
|
NavButton,
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
requiresAuthenticatedUser,
|
||||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
Title,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../lib/page';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonRow,
|
||||||
|
Form,
|
||||||
|
FormSendMethod,
|
||||||
|
InputField,
|
||||||
|
TextArea,
|
||||||
|
TreeTableSelect,
|
||||||
|
withForm
|
||||||
|
} from '../lib/form';
|
||||||
|
import axios
|
||||||
|
from '../lib/axios';
|
||||||
|
import {
|
||||||
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from '../lib/error-handling';
|
||||||
|
import interoperableErrors
|
||||||
|
from '../../../shared/interoperable-errors';
|
||||||
import {DeleteModalDialog} from "../lib/modals";
|
import {DeleteModalDialog} from "../lib/modals";
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
import mailtrainConfig
|
||||||
|
from 'mailtrainConfig';
|
||||||
import {getGlobalNamespaceId} from "../../../shared/namespaces";
|
import {getGlobalNamespaceId} from "../../../shared/namespaces";
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from "../lib/urls";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../lib/i18n';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import { requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton } from '../lib/page';
|
import {
|
||||||
import { TreeTable } from '../lib/tree';
|
NavButton,
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
requiresAuthenticatedUser,
|
||||||
import axios from '../lib/axios';
|
Title,
|
||||||
|
Toolbar,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../lib/page';
|
||||||
|
import {TreeTable} from '../lib/tree';
|
||||||
|
import {
|
||||||
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from '../lib/error-handling';
|
||||||
import {Icon} from "../lib/bootstrap-components";
|
import {Icon} from "../lib/bootstrap-components";
|
||||||
import {checkPermissions} from "../lib/permissions";
|
import {checkPermissions} from "../lib/permissions";
|
||||||
import {
|
import {
|
||||||
|
@ -14,11 +22,14 @@ import {
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../lib/modals";
|
} from "../lib/modals";
|
||||||
import {getGlobalNamespaceId} from "../../../shared/namespaces";
|
import {getGlobalNamespaceId} from "../../../shared/namespaces";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withErrorHandling
|
withTranslation,
|
||||||
@withPageHelpers
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,26 +1,52 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../lib/i18n';
|
from 'prop-types';
|
||||||
import {requiresAuthenticatedUser, withPageHelpers, Title, NavButton} from '../lib/page';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import {
|
import {
|
||||||
withForm, Form, FormSendMethod, InputField, TextArea, TableSelect, TableSelectMode, ButtonRow, Button,
|
NavButton,
|
||||||
Fieldset
|
requiresAuthenticatedUser,
|
||||||
|
Title,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../lib/page';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonRow,
|
||||||
|
Fieldset,
|
||||||
|
Form,
|
||||||
|
FormSendMethod,
|
||||||
|
InputField,
|
||||||
|
TableSelect,
|
||||||
|
TableSelectMode,
|
||||||
|
TextArea,
|
||||||
|
withForm
|
||||||
} from '../lib/form';
|
} from '../lib/form';
|
||||||
import axios from '../lib/axios';
|
import axios
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
from '../lib/axios';
|
||||||
import moment from 'moment';
|
import {
|
||||||
import { validateNamespace, NamespaceSelect } from '../lib/namespace';
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from '../lib/error-handling';
|
||||||
|
import moment
|
||||||
|
from 'moment';
|
||||||
|
import {
|
||||||
|
NamespaceSelect,
|
||||||
|
validateNamespace
|
||||||
|
} from '../lib/namespace';
|
||||||
import {DeleteModalDialog} from "../lib/modals";
|
import {DeleteModalDialog} from "../lib/modals";
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
import mailtrainConfig
|
||||||
|
from 'mailtrainConfig';
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from "../lib/urls";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,29 +1,40 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../lib/i18n';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import { requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton } from '../lib/page';
|
import {
|
||||||
import { Table } from '../lib/table';
|
NavButton,
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
requiresAuthenticatedUser,
|
||||||
import moment from 'moment';
|
Title,
|
||||||
import axios from '../lib/axios';
|
Toolbar,
|
||||||
import { ReportState } from '../../../shared/reports';
|
withPageHelpers
|
||||||
|
} from '../lib/page';
|
||||||
|
import {Table} from '../lib/table';
|
||||||
|
import {
|
||||||
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from '../lib/error-handling';
|
||||||
|
import moment
|
||||||
|
from 'moment';
|
||||||
|
import axios
|
||||||
|
from '../lib/axios';
|
||||||
|
import {ReportState} from '../../../shared/reports';
|
||||||
import {Icon} from "../lib/bootstrap-components";
|
import {Icon} from "../lib/bootstrap-components";
|
||||||
import {checkPermissions} from "../lib/permissions";
|
import {checkPermissions} from "../lib/permissions";
|
||||||
import {
|
import {getUrl} from "../lib/urls";
|
||||||
getPublicUrl,
|
|
||||||
getUrl
|
|
||||||
} from "../lib/urls";
|
|
||||||
import {
|
import {
|
||||||
tableAddDeleteButton,
|
tableAddDeleteButton,
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../lib/modals";
|
} from "../lib/modals";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withErrorHandling
|
withTranslation,
|
||||||
@withPageHelpers
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,27 +1,33 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../lib/i18n';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import {
|
import {
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
withPageHelpers,
|
|
||||||
Title,
|
Title,
|
||||||
Toolbar,
|
Toolbar,
|
||||||
NavButton
|
withPageHelpers
|
||||||
} from '../lib/page'
|
} from '../lib/page'
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
import {
|
||||||
import axios from '../lib/axios';
|
withAsyncErrorHandler,
|
||||||
import { ReportState } from '../../../shared/reports';
|
withErrorHandling
|
||||||
|
} from '../lib/error-handling';
|
||||||
|
import axios
|
||||||
|
from '../lib/axios';
|
||||||
|
import {ReportState} from '../../../shared/reports';
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from "../lib/urls";
|
||||||
import {Button} from "../lib/bootstrap-components";
|
import {Button} from "../lib/bootstrap-components";
|
||||||
import {Link} from "react-router-dom";
|
import {Link} from "react-router-dom";
|
||||||
import PropTypes
|
import PropTypes
|
||||||
from "prop-types";
|
from "prop-types";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class ViewAndOutput extends Component {
|
export default class ViewAndOutput extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import {
|
from 'prop-types';
|
||||||
Trans
|
import {Trans} from 'react-i18next';
|
||||||
} from 'react-i18next';
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import { withTranslation } from '../../lib/i18n';
|
|
||||||
import {
|
import {
|
||||||
NavButton,
|
NavButton,
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
|
@ -29,16 +28,20 @@ import {
|
||||||
validateNamespace
|
validateNamespace
|
||||||
} from '../../lib/namespace';
|
} from '../../lib/namespace';
|
||||||
import {DeleteModalDialog} from "../../lib/modals";
|
import {DeleteModalDialog} from "../../lib/modals";
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
import mailtrainConfig
|
||||||
|
from 'mailtrainConfig';
|
||||||
import 'brace/mode/javascript';
|
import 'brace/mode/javascript';
|
||||||
import 'brace/mode/json';
|
import 'brace/mode/json';
|
||||||
import 'brace/mode/handlebars';
|
import 'brace/mode/handlebars';
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,25 +1,41 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../../lib/i18n';
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import {DropdownMenu, Icon} from '../../lib/bootstrap-components';
|
import {
|
||||||
import { requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, MenuLink } from '../../lib/page';
|
DropdownMenu,
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../../lib/error-handling';
|
Icon
|
||||||
import { Table } from '../../lib/table';
|
} from '../../lib/bootstrap-components';
|
||||||
import axios from '../../lib/axios';
|
import {
|
||||||
import moment from 'moment';
|
MenuLink,
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
requiresAuthenticatedUser,
|
||||||
|
Title,
|
||||||
|
Toolbar,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../../lib/page';
|
||||||
|
import {
|
||||||
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from '../../lib/error-handling';
|
||||||
|
import {Table} from '../../lib/table';
|
||||||
|
import moment
|
||||||
|
from 'moment';
|
||||||
|
import mailtrainConfig
|
||||||
|
from 'mailtrainConfig';
|
||||||
import {checkPermissions} from "../../lib/permissions";
|
import {checkPermissions} from "../../lib/permissions";
|
||||||
import {
|
import {
|
||||||
tableAddDeleteButton,
|
tableAddDeleteButton,
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../../lib/modals";
|
} from "../../lib/modals";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -87,10 +103,10 @@ export default class List extends Component {
|
||||||
{this.state.createPermitted &&
|
{this.state.createPermitted &&
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<DropdownMenu className="btn-primary" label={t('createReportTemplate')}>
|
<DropdownMenu className="btn-primary" label={t('createReportTemplate')}>
|
||||||
<MenuLink to="/reports/templates/create">{t('blank')}</MenuLink>
|
<MenuLink to="/reports/templates/create">{t('Blank')}</MenuLink>
|
||||||
<MenuLink to="/reports/templates/create/open-counts">{t('openCounts')}</MenuLink>
|
<MenuLink to="/reports/templates/create/open-counts">{t('Open counts')}</MenuLink>
|
||||||
<MenuLink to="/reports/templates/create/open-counts-csv">{t('openCountsAsCsv')}</MenuLink>
|
<MenuLink to="/reports/templates/create/open-counts-csv">{t('Open counts as CSV')}</MenuLink>
|
||||||
<MenuLink to="/reports/templates/create/aggregated-open-counts">{t('aggregratedOpenCounts')}</MenuLink>
|
<MenuLink to="/reports/templates/create/aggregated-open-counts">{t('Aggregated open counts')}</MenuLink>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ import axios
|
||||||
from './lib/axios';
|
from './lib/axios';
|
||||||
import {getUrl} from "./lib/urls";
|
import {getUrl} from "./lib/urls";
|
||||||
import {getLang} from "../../shared/langs";
|
import {getLang} from "../../shared/langs";
|
||||||
|
import {withComponentMixins} from "./lib/decorator-helpers";
|
||||||
|
|
||||||
const topLevelMenuKeys = ['lists', 'templates', 'campaigns'];
|
const topLevelMenuKeys = ['lists', 'templates', 'campaigns'];
|
||||||
|
|
||||||
|
@ -55,7 +56,9 @@ if (mailtrainConfig.reportsEnabled) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
|
withTranslation
|
||||||
|
])
|
||||||
class Root extends Component {
|
class Root extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -42,13 +42,16 @@ import styles
|
||||||
|
|
||||||
import mailtrainConfig
|
import mailtrainConfig
|
||||||
from 'mailtrainConfig';
|
from 'mailtrainConfig';
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../lib/i18n';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import {Icon} from '../lib/bootstrap-components';
|
import {Icon} from '../lib/bootstrap-components';
|
||||||
import {
|
import {
|
||||||
NavButton,
|
NavButton,
|
||||||
|
@ -15,8 +15,8 @@ import {
|
||||||
withErrorHandling
|
withErrorHandling
|
||||||
} from '../lib/error-handling';
|
} from '../lib/error-handling';
|
||||||
import {Table} from '../lib/table';
|
import {Table} from '../lib/table';
|
||||||
import axios from '../lib/axios';
|
import moment
|
||||||
import moment from 'moment';
|
from 'moment';
|
||||||
import {getMailerTypes} from './helpers';
|
import {getMailerTypes} from './helpers';
|
||||||
import {checkPermissions} from "../lib/permissions";
|
import {checkPermissions} from "../lib/permissions";
|
||||||
import {
|
import {
|
||||||
|
@ -24,12 +24,15 @@ import {
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../lib/modals";
|
} from "../lib/modals";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import {
|
from 'prop-types';
|
||||||
Trans
|
import {Trans} from 'react-i18next';
|
||||||
} from 'react-i18next';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import { withTranslation } from '../lib/i18n';
|
|
||||||
import {
|
import {
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
Title,
|
Title,
|
||||||
|
@ -22,12 +21,15 @@ import {
|
||||||
withForm
|
withForm
|
||||||
} from '../lib/form';
|
} from '../lib/form';
|
||||||
import {withErrorHandling} from '../lib/error-handling';
|
import {withErrorHandling} from '../lib/error-handling';
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class Update extends Component {
|
export default class Update extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,23 +1,41 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../lib/i18n';
|
from 'prop-types';
|
||||||
import { requiresAuthenticatedUser, withPageHelpers, Title } from '../lib/page';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
|
||||||
import {
|
import {
|
||||||
withForm, Form, FormSendMethod, TableSelect, ButtonRow, Button
|
requiresAuthenticatedUser,
|
||||||
|
Title,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../lib/page';
|
||||||
|
import {
|
||||||
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from '../lib/error-handling';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonRow,
|
||||||
|
Form,
|
||||||
|
FormSendMethod,
|
||||||
|
TableSelect,
|
||||||
|
withForm
|
||||||
} from '../lib/form';
|
} from '../lib/form';
|
||||||
import { Table } from '../lib/table';
|
import {Table} from '../lib/table';
|
||||||
import axios from '../lib/axios';
|
import axios
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
from '../lib/axios';
|
||||||
|
import mailtrainConfig
|
||||||
|
from 'mailtrainConfig';
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from "../lib/urls";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class Share extends Component {
|
export default class Share extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,20 +1,31 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../lib/i18n';
|
from 'prop-types';
|
||||||
import { requiresAuthenticatedUser, withPageHelpers, Title } from '../lib/page';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
import {
|
||||||
import { Table } from '../lib/table';
|
requiresAuthenticatedUser,
|
||||||
import axios from '../lib/axios';
|
Title,
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
withPageHelpers
|
||||||
|
} from '../lib/page';
|
||||||
|
import {
|
||||||
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from '../lib/error-handling';
|
||||||
|
import {Table} from '../lib/table';
|
||||||
|
import axios
|
||||||
|
from '../lib/axios';
|
||||||
import {Icon} from "../lib/bootstrap-components";
|
import {Icon} from "../lib/bootstrap-components";
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from "../lib/urls";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class UserShares extends Component {
|
export default class UserShares extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../lib/i18n';
|
from 'prop-types';
|
||||||
|
import {withTranslation} from '../lib/i18n';
|
||||||
import {
|
import {
|
||||||
NavButton,
|
NavButton,
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
|
@ -26,23 +27,29 @@ import {
|
||||||
validateNamespace
|
validateNamespace
|
||||||
} from '../lib/namespace';
|
} from '../lib/namespace';
|
||||||
import {DeleteModalDialog} from "../lib/modals";
|
import {DeleteModalDialog} from "../lib/modals";
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
import mailtrainConfig
|
||||||
|
from 'mailtrainConfig';
|
||||||
import {
|
import {
|
||||||
getEditForm,
|
getEditForm,
|
||||||
getTemplateTypes,
|
getTemplateTypes,
|
||||||
getTypeForm
|
getTypeForm
|
||||||
} from './helpers';
|
} from './helpers';
|
||||||
import axios from '../lib/axios';
|
import axios
|
||||||
import styles from "../lib/styles.scss";
|
from '../lib/axios';
|
||||||
|
import styles
|
||||||
|
from "../lib/styles.scss";
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from "../lib/urls";
|
||||||
import {TestSendModalDialog} from "./TestSendModalDialog";
|
import {TestSendModalDialog} from "./TestSendModalDialog";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../lib/i18n';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import {Icon} from '../lib/bootstrap-components';
|
import {Icon} from '../lib/bootstrap-components';
|
||||||
import {
|
import {
|
||||||
NavButton,
|
NavButton,
|
||||||
|
@ -15,7 +15,8 @@ import {
|
||||||
withErrorHandling
|
withErrorHandling
|
||||||
} from '../lib/error-handling';
|
} from '../lib/error-handling';
|
||||||
import {Table} from '../lib/table';
|
import {Table} from '../lib/table';
|
||||||
import moment from 'moment';
|
import moment
|
||||||
|
from 'moment';
|
||||||
import {getTemplateTypes} from './helpers';
|
import {getTemplateTypes} from './helpers';
|
||||||
import {checkPermissions} from "../lib/permissions";
|
import {checkPermissions} from "../lib/permissions";
|
||||||
import {
|
import {
|
||||||
|
@ -23,11 +24,14 @@ import {
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../lib/modals";
|
} from "../lib/modals";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../lib/i18n';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import PropTypes
|
import PropTypes
|
||||||
from 'prop-types';
|
from 'prop-types';
|
||||||
import {ModalDialog} from "../lib/bootstrap-components";
|
import {ModalDialog} from "../lib/bootstrap-components";
|
||||||
|
@ -18,15 +18,19 @@ import {withErrorHandling} from "../lib/error-handling";
|
||||||
import moment
|
import moment
|
||||||
from "moment";
|
from "moment";
|
||||||
import {getMailerTypes} from "../send-configurations/helpers";
|
import {getMailerTypes} from "../send-configurations/helpers";
|
||||||
import axios from '../lib/axios';
|
import axios
|
||||||
|
from '../lib/axios';
|
||||||
import {getUrl} from "../lib/urls";
|
import {getUrl} from "../lib/urls";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export class TestSendModalDialog extends Component {
|
export class TestSendModalDialog extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -447,96 +447,29 @@ export function getTemplateTypes(t, prefix = '', entityTypeId = ResourceType.TEM
|
||||||
export function getEditForm(owner, typeKey, prefix = '') {
|
export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
const t = owner.props.t;
|
const t = owner.props.t;
|
||||||
|
|
||||||
return <div>
|
return (
|
||||||
|
<div>
|
||||||
<AlignedRow>
|
<AlignedRow>
|
||||||
<Button
|
<Button
|
||||||
className="btn-default"
|
className="btn-default"
|
||||||
onClickAsync={::owner.toggleMergeTagReference}
|
onClickAsync={::owner.toggleMergeTagReference}
|
||||||
label={t('mergeTagReference')}/>
|
label={t('mergeTagReference')}/>
|
||||||
{owner.state.showMergeTagReference &&
|
{owner.state.showMergeTagReference &&
|
||||||
<div
|
<div style={{marginTop: '15px'}}>
|
||||||
style={{marginTop: '15px'}}>
|
<Trans i18nKey="mergeTagsAreTagsThatAreReplacedBefore">
|
||||||
<Trans
|
<p>Merge tags are tags that are replaced before sending out the message. The format of the merge tag is the following: <code>[TAG_NAME]</code> or <code>[TAG_NAME/fallback]</code> where <code>fallback</code> is an optional text value used when <code>TAG_NAME</code> is empty.</p>
|
||||||
i18nKey="mergeTagsAreTagsThatAreReplacedBefore">
|
|
||||||
<p>Merge
|
|
||||||
tags
|
|
||||||
are
|
|
||||||
tags
|
|
||||||
that
|
|
||||||
are
|
|
||||||
replaced
|
|
||||||
before
|
|
||||||
sending
|
|
||||||
out
|
|
||||||
the
|
|
||||||
message.
|
|
||||||
The
|
|
||||||
format
|
|
||||||
of
|
|
||||||
the
|
|
||||||
merge
|
|
||||||
tag
|
|
||||||
is
|
|
||||||
the
|
|
||||||
following: <code>[TAG_NAME]</code> or <code>[TAG_NAME/fallback]</code> where <code>fallback</code> is
|
|
||||||
an
|
|
||||||
optional
|
|
||||||
text
|
|
||||||
value
|
|
||||||
used
|
|
||||||
when <code>TAG_NAME</code> is
|
|
||||||
empty.
|
|
||||||
</p>
|
|
||||||
</Trans>
|
</Trans>
|
||||||
<Trans
|
<Trans i18nKey="youCanUseAnyOfTheStandardMergeTagsBelow">
|
||||||
i18nKey="youCanUseAnyOfTheStandardMergeTagsBelow">
|
<p>You can use any of the standard merge tags below. In addition to that every custom field has its own merge tag. Check the fields of the list you are going to send to.</p>
|
||||||
<p>You
|
|
||||||
can
|
|
||||||
use
|
|
||||||
any
|
|
||||||
of
|
|
||||||
the
|
|
||||||
standard
|
|
||||||
merge
|
|
||||||
tags
|
|
||||||
below.
|
|
||||||
In
|
|
||||||
addition
|
|
||||||
to
|
|
||||||
that
|
|
||||||
every
|
|
||||||
custom
|
|
||||||
field
|
|
||||||
has
|
|
||||||
its
|
|
||||||
own
|
|
||||||
merge
|
|
||||||
tag.
|
|
||||||
Check
|
|
||||||
the
|
|
||||||
fields
|
|
||||||
of
|
|
||||||
the
|
|
||||||
list
|
|
||||||
you
|
|
||||||
are
|
|
||||||
going
|
|
||||||
to
|
|
||||||
send
|
|
||||||
to.</p>
|
|
||||||
</Trans>
|
</Trans>
|
||||||
<table
|
<table className="table table-bordered table-condensed table-striped">
|
||||||
className="table table-bordered table-condensed table-striped">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<Trans
|
<Trans i18nKey="mergeTag-1">Merge tag</Trans>
|
||||||
i18nKey="mergeTag-1">Merge
|
|
||||||
tag</Trans>
|
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<Trans
|
<Trans i18nKey="description">Description</Trans>
|
||||||
i18nKey="description">Description</Trans>
|
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -546,14 +479,7 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[LINK_UNSUBSCRIBE]
|
[LINK_UNSUBSCRIBE]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="urlThatPointsToTheUnsubscribePage">URL that points to the unsubscribe page</Trans>
|
||||||
i18nKey="urlThatPointsToTheUnsubscribePage">URL
|
|
||||||
that
|
|
||||||
points
|
|
||||||
to
|
|
||||||
the
|
|
||||||
unsubscribe
|
|
||||||
page</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -561,17 +487,7 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[LINK_PREFERENCES]
|
[LINK_PREFERENCES]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="urlThatPointsToThePreferencesPageOfThe">URL that points to the preferences page of the subscriber</Trans>
|
||||||
i18nKey="urlThatPointsToThePreferencesPageOfThe">URL
|
|
||||||
that
|
|
||||||
points
|
|
||||||
to
|
|
||||||
the
|
|
||||||
preferences
|
|
||||||
page
|
|
||||||
of
|
|
||||||
the
|
|
||||||
subscriber</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -579,15 +495,7 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[LINK_BROWSER]
|
[LINK_BROWSER]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="urlToPreviewTheMessageInABrowser">URL to preview the message in a browser</Trans>
|
||||||
i18nKey="urlToPreviewTheMessageInABrowser">URL
|
|
||||||
to
|
|
||||||
preview
|
|
||||||
the
|
|
||||||
message
|
|
||||||
in
|
|
||||||
a
|
|
||||||
browser</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -595,9 +503,7 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[EMAIL]
|
[EMAIL]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="emailAddress-1">Email address</Trans>
|
||||||
i18nKey="emailAddress-1">Email
|
|
||||||
address</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -605,16 +511,7 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[TO_NAME]
|
[TO_NAME]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="recipientNameAsItAppearsInEmailsToHeader">Recipient name as it appears in email's 'To' header</Trans>
|
||||||
i18nKey="recipientNameAsItAppearsInEmailsToHeader">Recipient
|
|
||||||
name
|
|
||||||
as
|
|
||||||
it
|
|
||||||
appears
|
|
||||||
in
|
|
||||||
email's
|
|
||||||
'To'
|
|
||||||
header</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -622,13 +519,7 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[SUBSCRIPTION_ID]
|
[SUBSCRIPTION_ID]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="uniqueIdThatIdentifiesTheRecipient">Unique ID that identifies the recipient</Trans>
|
||||||
i18nKey="uniqueIdThatIdentifiesTheRecipient">Unique
|
|
||||||
ID
|
|
||||||
that
|
|
||||||
identifies
|
|
||||||
the
|
|
||||||
recipient</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -636,17 +527,7 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[LIST_ID]
|
[LIST_ID]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="uniqueIdThatIdentifiesTheListUsedForThis">Unique ID that identifies the list used for this campaign</Trans>
|
||||||
i18nKey="uniqueIdThatIdentifiesTheListUsedForThis">Unique
|
|
||||||
ID
|
|
||||||
that
|
|
||||||
identifies
|
|
||||||
the
|
|
||||||
list
|
|
||||||
used
|
|
||||||
for
|
|
||||||
this
|
|
||||||
campaign</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -654,42 +535,22 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[CAMPAIGN_ID]
|
[CAMPAIGN_ID]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="uniqueIdThatIdentifiesCurrentCampaign">Unique ID that identifies current campaign</Trans>
|
||||||
i18nKey="uniqueIdThatIdentifiesCurrentCampaign">Unique
|
|
||||||
ID
|
|
||||||
that
|
|
||||||
identifies
|
|
||||||
current
|
|
||||||
campaign</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<Trans
|
<Trans i18nKey="forRssCampaignsTheFollowingFurtherTags">
|
||||||
i18nKey="forRssCampaignsTheFollowingFurtherTags">
|
<p>For RSS campaigns, the following further tags can be used.</p>
|
||||||
<p>For
|
|
||||||
RSS
|
|
||||||
campaigns,
|
|
||||||
the
|
|
||||||
following
|
|
||||||
further
|
|
||||||
tags
|
|
||||||
can
|
|
||||||
be
|
|
||||||
used.</p>
|
|
||||||
</Trans>
|
</Trans>
|
||||||
<table
|
<table className="table table-bordered table-condensed table-striped">
|
||||||
className="table table-bordered table-condensed table-striped">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<Trans
|
<Trans i18nKey="mergeTag-1">Merge tag</Trans>
|
||||||
i18nKey="mergeTag-1">Merge
|
|
||||||
tag</Trans>
|
|
||||||
</th>
|
</th>
|
||||||
<th>
|
<th>
|
||||||
<Trans
|
<Trans i18nKey="description">Description</Trans>
|
||||||
i18nKey="description">Description</Trans>
|
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -699,10 +560,7 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[RSS_ENTRY_TITLE]
|
[RSS_ENTRY_TITLE]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="rssEntryTitle">RSS entry title</Trans>
|
||||||
i18nKey="rssEntryTitle">RSS
|
|
||||||
entry
|
|
||||||
title</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -710,10 +568,7 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[RSS_ENTRY_DATE]
|
[RSS_ENTRY_DATE]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="rssEntryDate">RSS entry date</Trans>
|
||||||
i18nKey="rssEntryDate">RSS
|
|
||||||
entry
|
|
||||||
date</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -721,10 +576,7 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[RSS_ENTRY_LINK]
|
[RSS_ENTRY_LINK]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="rssEntryLink">RSS entry link</Trans>
|
||||||
i18nKey="rssEntryLink">RSS
|
|
||||||
entry
|
|
||||||
link</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -732,12 +584,7 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[RSS_ENTRY_CONTENT]
|
[RSS_ENTRY_CONTENT]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="contentOfAnRssEntry">Content of an RSS entry</Trans>
|
||||||
i18nKey="contentOfAnRssEntry">Content
|
|
||||||
of
|
|
||||||
an
|
|
||||||
RSS
|
|
||||||
entry</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -745,10 +592,7 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[RSS_ENTRY_SUMMARY]
|
[RSS_ENTRY_SUMMARY]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="rssEntrySummary">RSS entry summary</Trans>
|
||||||
i18nKey="rssEntrySummary">RSS
|
|
||||||
entry
|
|
||||||
summary</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -756,11 +600,7 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
[RSS_ENTRY_IMAGE_URL]
|
[RSS_ENTRY_IMAGE_URL]
|
||||||
</th>
|
</th>
|
||||||
<td>
|
<td>
|
||||||
<Trans
|
<Trans i18nKey="rssEntryImageUrl">RSS entry image URL</Trans>
|
||||||
i18nKey="rssEntryImageUrl">RSS
|
|
||||||
entry
|
|
||||||
image
|
|
||||||
URL</Trans>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -775,48 +615,10 @@ export function getEditForm(owner, typeKey, prefix = '') {
|
||||||
height="400px"
|
height="400px"
|
||||||
mode="text"
|
mode="text"
|
||||||
label={t('templateContentPlainText')}
|
label={t('templateContentPlainText')}
|
||||||
help={
|
help={<Trans i18nKey="toExtractTheTextFromHtmlClickHerePlease">To extract the text from HTML click <ActionLink onClickAsync={::owner.extractPlainText}>here</ActionLink>. Please note that your existing plaintext in the field above will be overwritten. This feature uses the <a href="http://premailer.dialect.ca/api">Premailer API</a>, a third party service. Their Terms of Service and Privacy Policy apply.</Trans>}
|
||||||
<Trans
|
/>
|
||||||
i18nKey="toExtractTheTextFromHtmlClickHerePlease">To
|
</div>
|
||||||
extract
|
);
|
||||||
the
|
|
||||||
text
|
|
||||||
from
|
|
||||||
HTML
|
|
||||||
click <ActionLink
|
|
||||||
onClickAsync={::owner.extractPlainText}>here</ActionLink>.
|
|
||||||
Please
|
|
||||||
note
|
|
||||||
that
|
|
||||||
your
|
|
||||||
existing
|
|
||||||
plaintext
|
|
||||||
in
|
|
||||||
the
|
|
||||||
field
|
|
||||||
above
|
|
||||||
will
|
|
||||||
be
|
|
||||||
overwritten.
|
|
||||||
This
|
|
||||||
feature
|
|
||||||
uses
|
|
||||||
the <a
|
|
||||||
href="http://premailer.dialect.ca/api">Premailer
|
|
||||||
API</a>,
|
|
||||||
a
|
|
||||||
third
|
|
||||||
party
|
|
||||||
service.
|
|
||||||
Their
|
|
||||||
Terms
|
|
||||||
of
|
|
||||||
Service
|
|
||||||
and
|
|
||||||
Privacy
|
|
||||||
Policy
|
|
||||||
apply.</Trans>}/>
|
|
||||||
</div>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTypeForm(owner, typeKey, isEdit) {
|
export function getTypeForm(owner, typeKey, isEdit) {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../../lib/i18n';
|
from 'prop-types';
|
||||||
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import {
|
import {
|
||||||
NavButton,
|
NavButton,
|
||||||
requiresAuthenticatedUser,
|
requiresAuthenticatedUser,
|
||||||
|
@ -31,12 +32,15 @@ import {
|
||||||
getTemplateTypes,
|
getTemplateTypes,
|
||||||
getTemplateTypesOrder
|
getTemplateTypesOrder
|
||||||
} from "./helpers";
|
} from "./helpers";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,26 +1,41 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import { withTranslation } from '../../lib/i18n';
|
import {withTranslation} from '../../lib/i18n';
|
||||||
import {DropdownMenu, Icon} from '../../lib/bootstrap-components';
|
import {
|
||||||
import { requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, MenuLink } from '../../lib/page';
|
DropdownMenu,
|
||||||
import { withErrorHandling, withAsyncErrorHandler } from '../../lib/error-handling';
|
Icon
|
||||||
import { Table } from '../../lib/table';
|
} from '../../lib/bootstrap-components';
|
||||||
import axios from '../../lib/axios';
|
import {
|
||||||
import moment from 'moment';
|
MenuLink,
|
||||||
import { getTemplateTypes } from './helpers';
|
requiresAuthenticatedUser,
|
||||||
|
Title,
|
||||||
|
Toolbar,
|
||||||
|
withPageHelpers
|
||||||
|
} from '../../lib/page';
|
||||||
|
import {
|
||||||
|
withAsyncErrorHandler,
|
||||||
|
withErrorHandling
|
||||||
|
} from '../../lib/error-handling';
|
||||||
|
import {Table} from '../../lib/table';
|
||||||
|
import moment
|
||||||
|
from 'moment';
|
||||||
|
import {getTemplateTypes} from './helpers';
|
||||||
import {checkPermissions} from "../../lib/permissions";
|
import {checkPermissions} from "../../lib/permissions";
|
||||||
import {
|
import {
|
||||||
tableAddDeleteButton,
|
tableAddDeleteButton,
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../../lib/modals";
|
} from "../../lib/modals";
|
||||||
|
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||||
|
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,22 +1,45 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, {Component} from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes
|
||||||
import { withTranslation } from '../lib/i18n';
|
from 'prop-types';
|
||||||
import {requiresAuthenticatedUser, withPageHelpers, Title, NavButton} from '../lib/page';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import { withForm, Form, FormSendMethod, InputField, ButtonRow, Button, TableSelect } from '../lib/form';
|
import {
|
||||||
import { withErrorHandling } from '../lib/error-handling';
|
NavButton,
|
||||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
requiresAuthenticatedUser,
|
||||||
import passwordValidator from '../../../shared/password-validator';
|
Title,
|
||||||
import mailtrainConfig from 'mailtrainConfig';
|
withPageHelpers
|
||||||
import { validateNamespace, NamespaceSelect } from '../lib/namespace';
|
} from '../lib/page';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonRow,
|
||||||
|
Form,
|
||||||
|
FormSendMethod,
|
||||||
|
InputField,
|
||||||
|
TableSelect,
|
||||||
|
withForm
|
||||||
|
} from '../lib/form';
|
||||||
|
import {withErrorHandling} from '../lib/error-handling';
|
||||||
|
import interoperableErrors
|
||||||
|
from '../../../shared/interoperable-errors';
|
||||||
|
import passwordValidator
|
||||||
|
from '../../../shared/password-validator';
|
||||||
|
import mailtrainConfig
|
||||||
|
from 'mailtrainConfig';
|
||||||
|
import {
|
||||||
|
NamespaceSelect,
|
||||||
|
validateNamespace
|
||||||
|
} from '../lib/namespace';
|
||||||
import {DeleteModalDialog} from "../lib/modals";
|
import {DeleteModalDialog} from "../lib/modals";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withForm
|
withTranslation,
|
||||||
@withPageHelpers
|
withForm,
|
||||||
@withErrorHandling
|
withErrorHandling,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class CUD extends Component {
|
export default class CUD extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -1,20 +1,30 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import { withTranslation } from '../lib/i18n';
|
import {withTranslation} from '../lib/i18n';
|
||||||
import {NavButton, requiresAuthenticatedUser, Title, Toolbar, withPageHelpers} from "../lib/page";
|
import {
|
||||||
|
NavButton,
|
||||||
|
requiresAuthenticatedUser,
|
||||||
|
Title,
|
||||||
|
Toolbar,
|
||||||
|
withPageHelpers
|
||||||
|
} from "../lib/page";
|
||||||
import {Table} from "../lib/table";
|
import {Table} from "../lib/table";
|
||||||
import mailtrainConfig from "mailtrainConfig";
|
import mailtrainConfig
|
||||||
|
from "mailtrainConfig";
|
||||||
import {Icon} from "../lib/bootstrap-components";
|
import {Icon} from "../lib/bootstrap-components";
|
||||||
import {
|
import {
|
||||||
tableAddDeleteButton,
|
tableAddDeleteButton,
|
||||||
tableRestActionDialogInit,
|
tableRestActionDialogInit,
|
||||||
tableRestActionDialogRender
|
tableRestActionDialogRender
|
||||||
} from "../lib/modals";
|
} from "../lib/modals";
|
||||||
|
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||||
|
|
||||||
@withTranslation()
|
@withComponentMixins([
|
||||||
@withPageHelpers
|
withTranslation,
|
||||||
@requiresAuthenticatedUser
|
withPageHelpers,
|
||||||
|
requiresAuthenticatedUser
|
||||||
|
])
|
||||||
export default class List extends Component {
|
export default class List extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
|
@ -23,6 +23,8 @@ const shares = require('./models/shares');
|
||||||
const { AppType } = require('../shared/app');
|
const { AppType } = require('../shared/app');
|
||||||
const builtinZoneMta = require('./lib/builtin-zone-mta');
|
const builtinZoneMta = require('./lib/builtin-zone-mta');
|
||||||
|
|
||||||
|
const { uploadedFilesDir } = require('./lib/file-helpers');
|
||||||
|
|
||||||
const trustedPort = config.www.trustedPort;
|
const trustedPort = config.www.trustedPort;
|
||||||
const sandboxPort = config.www.sandboxPort;
|
const sandboxPort = config.www.sandboxPort;
|
||||||
const publicPort = config.www.publicPort;
|
const publicPort = config.www.publicPort;
|
||||||
|
@ -68,7 +70,6 @@ function startHTTPServer(appType, appName, port, callback) {
|
||||||
server.listen({port, host}, callback);
|
server.listen({port, host}, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
// Start the whole circus here
|
// Start the whole circus here
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
|
@ -99,7 +100,10 @@ dbcheck(err => { // Check if database needs upgrading before starting the server
|
||||||
builtinZoneMta.spawn(() =>
|
builtinZoneMta.spawn(() =>
|
||||||
startHTTPServer(AppType.TRUSTED, 'trusted', trustedPort, () =>
|
startHTTPServer(AppType.TRUSTED, 'trusted', trustedPort, () =>
|
||||||
startHTTPServer(AppType.SANDBOXED, 'sandbox', sandboxPort, () =>
|
startHTTPServer(AppType.SANDBOXED, 'sandbox', sandboxPort, () =>
|
||||||
startHTTPServer(AppType.PUBLIC, 'public', publicPort, () => {
|
startHTTPServer(AppType.PUBLIC, 'public', publicPort, async () => {
|
||||||
|
|
||||||
|
await privilegeHelpers.ensureMailtrainDir(uploadedFilesDir);
|
||||||
|
|
||||||
privilegeHelpers.dropRootPrivileges();
|
privilegeHelpers.dropRootPrivileges();
|
||||||
|
|
||||||
tzupdate.start();
|
tzupdate.start();
|
||||||
|
|
|
@ -18,5 +18,6 @@ function installUploadHandler(router, url, replacementBehavior, type, subType, t
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
installUploadHandler
|
installUploadHandler,
|
||||||
|
uploadedFilesDir
|
||||||
};
|
};
|
|
@ -3,7 +3,7 @@
|
||||||
const log = require('./log');
|
const log = require('./log');
|
||||||
const config = require('config');
|
const config = require('config');
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs-extra-promise');
|
||||||
|
|
||||||
const tryRequire = require('try-require');
|
const tryRequire = require('try-require');
|
||||||
const posix = tryRequire('posix');
|
const posix = tryRequire('posix');
|
||||||
|
@ -49,6 +49,12 @@ function ensureMailtrainOwner(file, callback) {
|
||||||
fs.chown(file, ids.uid, ids.gid, callback);
|
fs.chown(file, ids.uid, ids.gid, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function ensureMailtrainDir(dir) {
|
||||||
|
const ids = getConfigUidGid();
|
||||||
|
await fs.ensureDir(dir);
|
||||||
|
await fs.chownAsync(dir, ids.uid, ids.gid);
|
||||||
|
}
|
||||||
|
|
||||||
function dropRootPrivileges() {
|
function dropRootPrivileges() {
|
||||||
if (config.group) {
|
if (config.group) {
|
||||||
try {
|
try {
|
||||||
|
@ -72,6 +78,7 @@ function dropRootPrivileges() {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
dropRootPrivileges,
|
dropRootPrivileges,
|
||||||
ensureMailtrainOwner,
|
ensureMailtrainOwner,
|
||||||
|
ensureMailtrainDir,
|
||||||
getConfigUidGid,
|
getConfigUidGid,
|
||||||
getConfigROUidGid
|
getConfigROUidGid
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,7 +25,7 @@ function enforceTypePermitted(type, subType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFilePath(type, subType, entityId, filename) {
|
function getFilePath(type, subType, entityId, filename) {
|
||||||
return path.join(path.join(filesDir, type, subType, entityId.toString()), filename);
|
return path.join(filesDir, type, subType, entityId.toString(), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFileUrl(context, type, subType, entityId, filename) {
|
function getFileUrl(context, type, subType, entityId, filename) {
|
||||||
|
|
|
@ -11,7 +11,8 @@ const fs = require('fs-extra-promise');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const importer = require('../lib/importer');
|
const importer = require('../lib/importer');
|
||||||
|
|
||||||
const filesDir = path.join(__dirname, '..', 'files', 'imports');
|
const files = require('./files');
|
||||||
|
const filesDir = path.join(files.filesDir, 'imports');
|
||||||
|
|
||||||
const allowedKeysCreate = new Set(['name', 'description', 'source', 'settings']);
|
const allowedKeysCreate = new Set(['name', 'description', 'source', 'settings']);
|
||||||
const allowedKeysUpdate = new Set(['name', 'description', 'mapping_type', 'mapping']);
|
const allowedKeysUpdate = new Set(['name', 'description', 'mapping_type', 'mapping']);
|
||||||
|
|
|
@ -9,7 +9,8 @@ const {castToInteger} = require('../../lib/helpers');
|
||||||
|
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const files = require('../../models/files');
|
const files = require('../../models/files');
|
||||||
const uploadedFilesDir = path.join(files.filesDir, 'uploaded');
|
|
||||||
|
const {uploadedFilesDir} = require('../../lib/file-helpers')
|
||||||
|
|
||||||
const multer = require('multer')({
|
const multer = require('multer')({
|
||||||
dest: uploadedFilesDir
|
dest: uploadedFilesDir
|
||||||
|
|
Loading…
Reference in a new issue