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",
|
||||
"datatables.net": "^1.10.19",
|
||||
"datatables.net-bs": "^1.10.19",
|
||||
"grapesjs": "^0.14.40",
|
||||
"grapesjs": "^0.14.49",
|
||||
"grapesjs-mjml": "0.0.27",
|
||||
"grapesjs-preset-newsletter": "^0.2.20",
|
||||
"i18next": "^12.0.0",
|
||||
"i18next": "^13.0.1",
|
||||
"i18next-browser-languagedetector": "^2.2.4",
|
||||
"immutable": "^3.8.1",
|
||||
"juice": "^5.0.1",
|
||||
"juice": "^5.1.0",
|
||||
"mjml4-in-browser": "^1.0.1",
|
||||
"moment": "^2.22.2",
|
||||
"moment": "^2.23.0",
|
||||
"moment-timezone": "^0.5.23",
|
||||
"prop-types": "^15.6.2",
|
||||
"querystringify": "^2.1.0",
|
||||
"react": "^15.6.1",
|
||||
"react-ace": "^5.10.0",
|
||||
"react": "^16.7.0",
|
||||
"react-ace": "^6.3.2",
|
||||
"react-ckeditor-component": "^1.1.0",
|
||||
"react-day-picker": "^6.1.0",
|
||||
"react-dnd-html5-backend": "^2.6.0",
|
||||
"react-dnd-touch-backend": "^0.3.21",
|
||||
"react-dom": "^15.6.1",
|
||||
"react-dropzone": "^4.3.0",
|
||||
"react-google-charts": "^2.0.29",
|
||||
"react-i18next": "^8.3.8",
|
||||
"react-day-picker": "^7.2.4",
|
||||
"react-dnd": "^7.0.2",
|
||||
"react-dnd-html5-backend": "^7.0.2",
|
||||
"react-dnd-touch-backend": "^0.7.1",
|
||||
"react-dom": "^16.7.0",
|
||||
"react-dropzone": "^8.0.3",
|
||||
"react-google-charts": "^3.0.10",
|
||||
"react-i18next": "^8.4.0",
|
||||
"react-router-dom": "^4.3.1",
|
||||
"react-sortable-tree": "^1.2.0",
|
||||
"slugify": "^1.3.3",
|
||||
"react-sortable-tree": "^2.6.0",
|
||||
"slugify": "^1.3.4",
|
||||
"url-parse": "^1.4.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import { withTranslation } from './lib/i18n';
|
||||
import { requiresAuthenticatedUser } from './lib/page';
|
||||
import {withTranslation} from './lib/i18n';
|
||||
import {requiresAuthenticatedUser} from './lib/page';
|
||||
import {withComponentMixins} from "./lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -16,11 +16,14 @@ import axios
|
|||
from '../lib/axios';
|
||||
import {Button} from '../lib/bootstrap-components';
|
||||
import {getUrl} from "../lib/urls";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class API extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,22 +1,41 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import { Trans } from 'react-i18next';
|
||||
import { requiresAuthenticatedUser, withPageHelpers, Title } from '../lib/page'
|
||||
import React, {Component} from 'react';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {Trans} from 'react-i18next';
|
||||
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';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
||||
import passwordValidator from '../../../shared/password-validator';
|
||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import {
|
||||
withAsyncErrorHandler,
|
||||
withErrorHandling
|
||||
} 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()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class Account extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -2,16 +2,23 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import { withPageHelpers, Title } from '../lib/page'
|
||||
import {
|
||||
withPageHelpers,
|
||||
Title,
|
||||
requiresAuthenticatedUser
|
||||
} from '../lib/page'
|
||||
import {
|
||||
withForm, Form, FormSendMethod, InputField, ButtonRow, Button
|
||||
} from '../lib/form';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers
|
||||
])
|
||||
export default class Forget extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,22 +1,37 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import { withPageHelpers, Title } from '../lib/page'
|
||||
import { Link } from 'react-router-dom'
|
||||
import React, {Component} from 'react';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
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';
|
||||
import { withErrorHandling } from '../lib/error-handling';
|
||||
import qs from 'querystringify';
|
||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import {withErrorHandling} from '../lib/error-handling';
|
||||
import qs
|
||||
from 'querystringify';
|
||||
import interoperableErrors
|
||||
from '../../../shared/interoperable-errors';
|
||||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
import {getUrl} from "../lib/urls";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers
|
||||
])
|
||||
export default class Login extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,17 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import { withPageHelpers, Title } from '../lib/page'
|
||||
import { Link } from 'react-router-dom'
|
||||
import React, {Component} from 'react';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
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';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
||||
import passwordValidator from '../../../shared/password-validator';
|
||||
import axios from '../lib/axios';
|
||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
||||
import {
|
||||
withAsyncErrorHandler,
|
||||
withErrorHandling
|
||||
} 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 {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
const ResetTokenValidationState = {
|
||||
PENDING: 0,
|
||||
|
@ -19,10 +34,12 @@ const ResetTokenValidationState = {
|
|||
INVALID: 2
|
||||
};
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers
|
||||
])
|
||||
export default class Account extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -14,12 +14,15 @@ import {
|
|||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
|
@ -33,15 +34,19 @@ import {
|
|||
validateNamespace
|
||||
} from '../lib/namespace';
|
||||
import {DeleteModalDialog} from "../lib/modals";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
import {
|
||||
getTemplateTypes,
|
||||
getTypeForm,
|
||||
ResourceType
|
||||
} from '../templates/helpers';
|
||||
import axios from '../lib/axios';
|
||||
import styles from "../lib/styles.scss";
|
||||
import campaignsStyles from "./styles.scss";
|
||||
import axios
|
||||
from '../lib/axios';
|
||||
import styles
|
||||
from "../lib/styles.scss";
|
||||
import campaignsStyles
|
||||
from "./styles.scss";
|
||||
import {getUrl} from "../lib/urls";
|
||||
import {
|
||||
campaignOverridables,
|
||||
|
@ -49,15 +54,19 @@ import {
|
|||
CampaignStatus,
|
||||
CampaignType
|
||||
} from "../../../shared/campaigns";
|
||||
import moment from 'moment';
|
||||
import moment
|
||||
from 'moment';
|
||||
import {getMailerTypes} from "../send-configurations/helpers";
|
||||
import {getCampaignLabels} from "./helpers";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
requiresAuthenticatedUser,
|
||||
Title,
|
||||
|
@ -17,24 +18,30 @@ import {
|
|||
withForm
|
||||
} from '../lib/form';
|
||||
import {withErrorHandling} from '../lib/error-handling';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
import {
|
||||
getEditForm,
|
||||
getTemplateTypes,
|
||||
getTypeForm,
|
||||
ResourceType
|
||||
} from '../templates/helpers';
|
||||
import axios from '../lib/axios';
|
||||
import styles from "../lib/styles.scss";
|
||||
import axios
|
||||
from '../lib/axios';
|
||||
import styles
|
||||
from "../lib/styles.scss";
|
||||
import {getUrl} from "../lib/urls";
|
||||
import {TestSendModalDialog} from "./TestSendModalDialog";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CustomContent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
DropdownMenu,
|
||||
Icon
|
||||
|
@ -18,7 +18,8 @@ import {
|
|||
withErrorHandling
|
||||
} from '../lib/error-handling';
|
||||
import {Table} from '../lib/table';
|
||||
import moment from 'moment';
|
||||
import moment
|
||||
from 'moment';
|
||||
import {
|
||||
CampaignSource,
|
||||
CampaignStatus,
|
||||
|
@ -31,11 +32,14 @@ import {
|
|||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -22,11 +22,14 @@ import {Icon} from "../lib/bootstrap-components";
|
|||
import styles
|
||||
from "./styles.scss";
|
||||
import {Link} from "react-router-dom";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class Statistics extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -11,11 +11,14 @@ import {
|
|||
} from '../lib/page';
|
||||
import {withErrorHandling} from '../lib/error-handling';
|
||||
import {Table} from "../lib/table";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class StatisticsLinkClicks extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -17,24 +17,24 @@ import axios
|
|||
from "../lib/axios";
|
||||
import {getUrl} from "../lib/urls";
|
||||
|
||||
import Chart from 'react-google-charts';
|
||||
import {AlignedRow} from "../lib/form";
|
||||
import {
|
||||
ActionLink,
|
||||
Icon
|
||||
} from "../lib/bootstrap-components";
|
||||
import {SubscriptionStatus} from "../../../shared/lists";
|
||||
import Chart
|
||||
from 'react-google-charts';
|
||||
|
||||
import styles from "./styles.scss";
|
||||
import styles
|
||||
from "./styles.scss";
|
||||
import {Table} from "../lib/table";
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
import mailtrainConfig from "mailtrainConfig";
|
||||
import mailtrainConfig
|
||||
from "mailtrainConfig";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class StatisticsOpened extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -11,11 +11,14 @@ import {
|
|||
} from '../lib/page';
|
||||
import {withErrorHandling} from '../lib/error-handling';
|
||||
import {Table} from "../lib/table";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class StatisticsSubsList extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
|
@ -30,24 +31,32 @@ import {
|
|||
Icon,
|
||||
ModalDialog
|
||||
} from "../lib/bootstrap-components";
|
||||
import axios from "../lib/axios";
|
||||
import {getUrl, getPublicUrl} from "../lib/urls";
|
||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
||||
import axios
|
||||
from "../lib/axios";
|
||||
import {
|
||||
getPublicUrl,
|
||||
getUrl
|
||||
} from "../lib/urls";
|
||||
import interoperableErrors
|
||||
from '../../../shared/interoperable-errors';
|
||||
import {
|
||||
CampaignSource,
|
||||
CampaignStatus,
|
||||
CampaignType
|
||||
} from "../../../shared/campaigns";
|
||||
import moment from 'moment';
|
||||
import campaignsStyles from "./styles.scss";
|
||||
import {tableAddDeleteButton} from "../lib/modals";
|
||||
import moment
|
||||
from 'moment';
|
||||
import campaignsStyles
|
||||
from "./styles.scss";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
class TestUser extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -107,11 +116,13 @@ class TestUser extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
class SendControls extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -361,10 +372,12 @@ class SendControls extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class Status extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {ModalDialog} from "../lib/bootstrap-components";
|
||||
|
@ -16,16 +16,19 @@ import {
|
|||
} from "../lib/form";
|
||||
import {withErrorHandling} from "../lib/error-handling";
|
||||
import {getMailerTypes} from "../send-configurations/helpers";
|
||||
import axios from '../lib/axios';
|
||||
import {} from '../lib/urls';
|
||||
import {getUrl} from "../lib/urls";
|
||||
import axios
|
||||
from '../lib/axios';
|
||||
import {getUrl} from '../lib/urls';
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export class TestSendModalDialog extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
|
@ -29,15 +30,19 @@ import {
|
|||
Entity,
|
||||
Event
|
||||
} from '../../../../shared/triggers';
|
||||
import moment from 'moment';
|
||||
import moment
|
||||
from 'moment';
|
||||
import {getCampaignLabels} from "../helpers";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
|
@ -14,17 +15,21 @@ import {withErrorHandling} from '../../lib/error-handling';
|
|||
import {Table} from '../../lib/table';
|
||||
import {getTriggerTypes} from './helpers';
|
||||
import {Icon} from "../../lib/bootstrap-components";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
import {
|
||||
tableAddDeleteButton,
|
||||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../../lib/modals";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(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';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from './error-handling';
|
||||
import React, {Component} from 'react';
|
||||
import {withTranslation} from './i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {
|
||||
withAsyncErrorHandler,
|
||||
withErrorHandling
|
||||
} from './error-handling';
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withErrorHandling
|
||||
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling
|
||||
])
|
||||
class DismissibleAlert extends Component {
|
||||
static propTypes = {
|
||||
severity: PropTypes.string.isRequired,
|
||||
|
@ -51,7 +59,9 @@ class Icon extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@withErrorHandling
|
||||
@withComponentMixins([
|
||||
withErrorHandling
|
||||
])
|
||||
class Button extends Component {
|
||||
static propTypes = {
|
||||
onClickAsync: PropTypes.func,
|
||||
|
@ -165,7 +175,9 @@ class DropdownMenuItem extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@withErrorHandling
|
||||
@withComponentMixins([
|
||||
withErrorHandling
|
||||
])
|
||||
class ActionLink extends Component {
|
||||
static propTypes = {
|
||||
onClickAsync: PropTypes.func,
|
||||
|
@ -192,8 +204,10 @@ class ActionLink extends Component {
|
|||
}
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withErrorHandling
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling
|
||||
])
|
||||
class ModalDialog extends Component {
|
||||
constructor(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';
|
||||
|
||||
import React from "react";
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {SectionContentContext} from "./page-common";
|
||||
import {createComponentMixin} from "./decorator-helpers";
|
||||
|
||||
function handleError(that, error) {
|
||||
let errorHandled;
|
||||
|
@ -9,8 +11,8 @@ function handleError(that, error) {
|
|||
errorHandled = that.errorHandler(error);
|
||||
}
|
||||
|
||||
if (!errorHandled && that.context.parentErrorHandler) {
|
||||
errorHandled = handleError(that.context.parentErrorHandler, error);
|
||||
if (!errorHandled && that.props.parentErrorHandler) {
|
||||
errorHandled = handleError(that.props.parentErrorHandler, error);
|
||||
}
|
||||
|
||||
if (!errorHandled) {
|
||||
|
@ -20,35 +22,8 @@ function handleError(that, error) {
|
|||
return errorHandled;
|
||||
}
|
||||
|
||||
function withErrorHandling(target) {
|
||||
const inst = target.prototype;
|
||||
|
||||
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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const ParentErrorHandlerContext = React.createContext(null);
|
||||
export const withErrorHandling = createComponentMixin([{context: ParentErrorHandlerContext, propName: 'parentErrorHandler'}], [], (TargetClass, InnerClass) => {
|
||||
/* Example of use:
|
||||
this.getFormValuesFromURL(....).catch(error => this.handleError(error));
|
||||
|
||||
|
@ -59,14 +34,25 @@ function withErrorHandling(target) {
|
|||
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);
|
||||
};
|
||||
|
||||
return target;
|
||||
}
|
||||
return TargetClass;
|
||||
});
|
||||
|
||||
function withAsyncErrorHandler(target, name, descriptor) {
|
||||
export function withAsyncErrorHandler(target, name, descriptor) {
|
||||
let fn = descriptor.value;
|
||||
|
||||
descriptor.value = async function () {
|
||||
|
@ -80,8 +66,3 @@ function withAsyncErrorHandler(target, name, descriptor) {
|
|||
return descriptor;
|
||||
}
|
||||
|
||||
|
||||
export {
|
||||
withErrorHandling,
|
||||
withAsyncErrorHandler
|
||||
}
|
|
@ -1,25 +1,38 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import {withTranslation} from './i18n';
|
||||
import {
|
||||
requiresAuthenticatedUser,
|
||||
Title
|
||||
Title,
|
||||
withPageHelpers
|
||||
} from "./page";
|
||||
import {withErrorHandling} from "./error-handling";
|
||||
import {Table} from "./table";
|
||||
import Dropzone from "react-dropzone";
|
||||
import {Icon, ModalDialog} from "./bootstrap-components";
|
||||
import axios from './axios';
|
||||
import styles from "./styles.scss";
|
||||
import {withPageHelpers} from "./page";
|
||||
import {getUrl, getPublicUrl} from "./urls";
|
||||
import Dropzone
|
||||
from "react-dropzone";
|
||||
import {
|
||||
Icon,
|
||||
ModalDialog
|
||||
} from "./bootstrap-components";
|
||||
import axios
|
||||
from './axios';
|
||||
import styles
|
||||
from "./styles.scss";
|
||||
import {
|
||||
getPublicUrl,
|
||||
getUrl
|
||||
} from "./urls";
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withErrorHandling
|
||||
@withPageHelpers
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class Files extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,29 +1,60 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from './i18n';
|
||||
import React, {Component} from 'react';
|
||||
import {withTranslation} from './i18n';
|
||||
import axios, {HTTPMethod} from './axios';
|
||||
import Immutable from 'immutable';
|
||||
import PropTypes from 'prop-types';
|
||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
||||
import { withPageHelpers } from './page'
|
||||
import { withErrorHandling, withAsyncErrorHandler } from './error-handling';
|
||||
import { TreeTable, TreeSelectMode } from './tree';
|
||||
import { Table, TableSelectMode } from './table';
|
||||
import {Button, Icon} from "./bootstrap-components";
|
||||
|
||||
import brace from 'brace';
|
||||
import ACEEditorRaw from 'react-ace';
|
||||
import Immutable
|
||||
from 'immutable';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import interoperableErrors
|
||||
from '../../../shared/interoperable-errors';
|
||||
import {withPageHelpers} from './page'
|
||||
import {
|
||||
ParentErrorHandlerContext,
|
||||
withAsyncErrorHandler,
|
||||
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/ext/searchbox';
|
||||
|
||||
import DayPicker from 'react-day-picker';
|
||||
import DayPicker
|
||||
from 'react-day-picker';
|
||||
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 moment from "moment";
|
||||
import styles
|
||||
from "./styles.scss";
|
||||
import moment
|
||||
from "moment";
|
||||
import {getUrl} from "./urls";
|
||||
import {
|
||||
createComponentMixin,
|
||||
withComponentMixins
|
||||
} from "./decorator-helpers";
|
||||
|
||||
|
||||
const FormState = {
|
||||
|
@ -34,9 +65,22 @@ const FormState = {
|
|||
|
||||
const FormSendMethod = HTTPMethod;
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
export const FormStateOwnerContext = React.createContext(null);
|
||||
|
||||
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 {
|
||||
static propTypes = {
|
||||
stateOwner: PropTypes.object.isRequired,
|
||||
|
@ -45,16 +89,6 @@ class Form extends Component {
|
|||
noStatus: PropTypes.bool
|
||||
}
|
||||
|
||||
static childContextTypes = {
|
||||
formStateOwner: PropTypes.object
|
||||
}
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
formStateOwner: this.props.stateOwner
|
||||
};
|
||||
}
|
||||
|
||||
@withAsyncErrorHandler
|
||||
async onSubmit(evt) {
|
||||
const t = this.props.t;
|
||||
|
@ -91,20 +125,25 @@ class Form extends Component {
|
|||
} else {
|
||||
return (
|
||||
<form className={formClass} onSubmit={::this.onSubmit}>
|
||||
<fieldset disabled={owner.isFormDisabled()}>
|
||||
{props.children}
|
||||
</fieldset>
|
||||
{!props.noStatus && statusMessageText &&
|
||||
<AlignedRow htmlId="form-status-message">
|
||||
<p className={`alert alert-${statusMessageSeverity} ${styles.formStatus}`} role="alert">{statusMessageText}</p>
|
||||
</AlignedRow>
|
||||
}
|
||||
<FormStateOwnerContext.Provider value={owner}>
|
||||
<fieldset disabled={owner.isFormDisabled()}>
|
||||
{props.children}
|
||||
</fieldset>
|
||||
{!props.noStatus && statusMessageText &&
|
||||
<AlignedRow htmlId="form-status-message">
|
||||
<p className={`alert alert-${statusMessageSeverity} ${styles.formStatus}`} role="alert">{statusMessageText}</p>
|
||||
</AlignedRow>
|
||||
}
|
||||
</FormStateOwnerContext.Provider>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@withComponentMixins([
|
||||
withFormStateOwner
|
||||
])
|
||||
class Fieldset extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.string,
|
||||
|
@ -114,13 +153,9 @@ class Fieldset extends Component {
|
|||
className: PropTypes.string
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
formStateOwner: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
|
||||
|
@ -230,6 +265,9 @@ function wrapInput(id, htmlId, owner, format, rightContainerClass, label, help,
|
|||
}
|
||||
}
|
||||
|
||||
@withComponentMixins([
|
||||
withFormStateOwner
|
||||
])
|
||||
class StaticField extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
|
@ -240,13 +278,9 @@ class StaticField extends Component {
|
|||
withValidation: PropTypes.bool
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
formStateOwner: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
|
||||
|
@ -261,6 +295,9 @@ class StaticField extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@withComponentMixins([
|
||||
withFormStateOwner
|
||||
])
|
||||
class InputField extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
|
@ -275,13 +312,9 @@ class InputField extends Component {
|
|||
type: 'text'
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
formStateOwner: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
|
||||
|
@ -298,6 +331,9 @@ class InputField extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@withComponentMixins([
|
||||
withFormStateOwner
|
||||
])
|
||||
class CheckBox extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
|
@ -307,13 +343,9 @@ class CheckBox extends Component {
|
|||
format: PropTypes.string
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
formStateOwner: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
|
||||
|
@ -336,13 +368,9 @@ class CheckBoxGroup extends Component {
|
|||
format: PropTypes.string
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
formStateOwner: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
onChange(key) {
|
||||
const id = this.props.id;
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const existingSelection = owner.getFormValue(id);
|
||||
|
||||
let newSelection;
|
||||
|
@ -357,7 +385,7 @@ class CheckBoxGroup extends Component {
|
|||
render() {
|
||||
const props = this.props;
|
||||
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
|
||||
|
@ -388,6 +416,9 @@ class CheckBoxGroup extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@withComponentMixins([
|
||||
withFormStateOwner
|
||||
])
|
||||
class RadioGroup extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
|
@ -398,14 +429,10 @@ class RadioGroup extends Component {
|
|||
format: PropTypes.string
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
formStateOwner: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
|
||||
|
@ -436,6 +463,9 @@ class RadioGroup extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@withComponentMixins([
|
||||
withFormStateOwner
|
||||
])
|
||||
class TextArea extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
|
@ -446,13 +476,9 @@ class TextArea extends Component {
|
|||
className: PropTypes.string
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
formStateOwner: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
const className = props.className || ''
|
||||
|
@ -464,7 +490,10 @@ class TextArea extends Component {
|
|||
}
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withFormStateOwner
|
||||
])
|
||||
class DatePicker extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -489,10 +518,6 @@ class DatePicker extends Component {
|
|||
dateFormat: DateFormat.INTL
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
formStateOwner: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
toggleDayPicker() {
|
||||
this.setState({
|
||||
opened: !this.state.opened
|
||||
|
@ -500,7 +525,7 @@ class DatePicker extends Component {
|
|||
}
|
||||
|
||||
daySelected(date) {
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const props = this.props;
|
||||
|
||||
|
@ -517,7 +542,7 @@ class DatePicker extends Component {
|
|||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
const t = props.t;
|
||||
|
@ -590,6 +615,9 @@ class DatePicker extends Component {
|
|||
}
|
||||
|
||||
|
||||
@withComponentMixins([
|
||||
withFormStateOwner
|
||||
])
|
||||
class Dropdown extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
|
@ -600,14 +628,10 @@ class Dropdown extends Component {
|
|||
format: PropTypes.string
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
formStateOwner: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
const options = [];
|
||||
|
@ -639,6 +663,9 @@ class Dropdown extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@withComponentMixins([
|
||||
withFormStateOwner
|
||||
])
|
||||
class AlignedRow extends Component {
|
||||
static propTypes = {
|
||||
className: PropTypes.string,
|
||||
|
@ -647,17 +674,13 @@ class AlignedRow extends Component {
|
|||
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 = {
|
||||
className: ''
|
||||
}
|
||||
|
||||
render() {
|
||||
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);
|
||||
}
|
||||
|
@ -683,6 +706,9 @@ class ButtonRow extends Component {
|
|||
}
|
||||
|
||||
|
||||
@withComponentMixins([
|
||||
withFormStateOwner
|
||||
])
|
||||
class TreeTableSelect extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
|
@ -693,18 +719,14 @@ class TreeTableSelect extends Component {
|
|||
format: PropTypes.string
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
formStateOwner: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
async onSelectionChangedAsync(sel) {
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
owner.updateFormValue(this.props.id, sel);
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
|
||||
|
@ -714,7 +736,10 @@ class TreeTableSelect extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@withTranslation({delegateFuns: ['refresh']})
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withFormStateOwner
|
||||
], ['refresh'])
|
||||
class TableSelect extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -751,10 +776,6 @@ class TableSelect extends Component {
|
|||
pageLength: 10
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
formStateOwner: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
async onSelectionChangedAsync(sel, data) {
|
||||
if (this.props.selectMode === TableSelectMode.SINGLE && this.props.dropdown) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -796,7 +817,7 @@ class TableSelect extends Component {
|
|||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
const t = props.t;
|
||||
|
@ -830,6 +851,9 @@ class TableSelect extends Component {
|
|||
}
|
||||
|
||||
|
||||
@withComponentMixins([
|
||||
withFormStateOwner
|
||||
])
|
||||
class ACEEditor extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
|
@ -840,13 +864,9 @@ class ACEEditor extends Component {
|
|||
format: PropTypes.string
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
formStateOwner: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.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.
|
||||
|
||||
@withComponentMixins([
|
||||
withFormStateOwner
|
||||
])
|
||||
class CKEditor extends Component {
|
||||
static propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
|
@ -878,13 +901,9 @@ class CKEditor extends Component {
|
|||
height: PropTypes.string
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
formStateOwner: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = this.props;
|
||||
const owner = this.context.formStateOwner;
|
||||
const owner = this.getFormStateOwner();
|
||||
const id = this.props.id;
|
||||
const htmlId = 'form_' + id;
|
||||
|
||||
|
@ -901,9 +920,8 @@ class CKEditor extends Component {
|
|||
}
|
||||
*/
|
||||
|
||||
|
||||
function withForm(target) {
|
||||
const inst = target.prototype;
|
||||
const withForm = createComponentMixin([], [], (TargetClass, InnerClass) => {
|
||||
const proto = InnerClass.prototype;
|
||||
|
||||
const cleanFormState = Immutable.Map({
|
||||
state: FormState.Loading,
|
||||
|
@ -1002,20 +1020,20 @@ function withForm(target) {
|
|||
}
|
||||
}
|
||||
|
||||
inst.initForm = function(settings) {
|
||||
proto.initForm = function(settings) {
|
||||
const state = this.state || {};
|
||||
state.formState = cleanFormState;
|
||||
state.formSettings = settings || {};
|
||||
this.state = state;
|
||||
};
|
||||
|
||||
inst.resetFormState = function() {
|
||||
proto.resetFormState = function() {
|
||||
this.setState({
|
||||
formState: cleanFormState
|
||||
});
|
||||
};
|
||||
|
||||
inst.getFormValuesFromEntity = function(entity, mutator) {
|
||||
proto.getFormValuesFromEntity = function(entity, mutator) {
|
||||
const data = Object.assign({}, entity);
|
||||
|
||||
data.originalHash = data.hash;
|
||||
|
@ -1028,7 +1046,7 @@ function withForm(target) {
|
|||
this.populateFormValues(data);
|
||||
};
|
||||
|
||||
inst.getFormValuesFromURL = async function(url, mutator) {
|
||||
proto.getFormValuesFromURL = async function(url, mutator) {
|
||||
setTimeout(() => {
|
||||
this.setState(previousState => {
|
||||
if (previousState.formState.get('state') === FormState.Loading) {
|
||||
|
@ -1057,7 +1075,7 @@ function withForm(target) {
|
|||
this.populateFormValues(data);
|
||||
};
|
||||
|
||||
inst.validateAndSendFormValuesToURL = async function(method, url, mutator) {
|
||||
proto.validateAndSendFormValuesToURL = async function(method, url, mutator) {
|
||||
await this.waitForFormServerValidated();
|
||||
|
||||
if (this.isFormWithoutErrors()) {
|
||||
|
@ -1081,7 +1099,7 @@ function withForm(target) {
|
|||
};
|
||||
|
||||
|
||||
inst.populateFormValues = function(data) {
|
||||
proto.populateFormValues = function(data) {
|
||||
this.setState(previousState => ({
|
||||
formState: previousState.formState.withMutations(mutState => {
|
||||
mutState.set('state', FormState.Ready);
|
||||
|
@ -1099,17 +1117,17 @@ function withForm(target) {
|
|||
}));
|
||||
};
|
||||
|
||||
inst.waitForFormServerValidated = async function() {
|
||||
proto.waitForFormServerValidated = async function() {
|
||||
if (!this.isFormServerValidated()) {
|
||||
await new Promise(resolve => { formValidateResolve = resolve; });
|
||||
}
|
||||
};
|
||||
|
||||
inst.scheduleFormRevalidate = function() {
|
||||
proto.scheduleFormRevalidate = function() {
|
||||
scheduleValidateForm(this);
|
||||
};
|
||||
|
||||
inst.updateForm = function(mutator) {
|
||||
proto.updateForm = function(mutator) {
|
||||
this.setState(previousState => {
|
||||
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 => {
|
||||
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']);
|
||||
};
|
||||
|
||||
inst.getFormValues = function(name) {
|
||||
proto.getFormValues = function(name) {
|
||||
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']);
|
||||
};
|
||||
|
||||
inst.isFormWithLoadingNotice = function() {
|
||||
proto.isFormWithLoadingNotice = function() {
|
||||
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;
|
||||
};
|
||||
|
||||
inst.isFormReady = function() {
|
||||
proto.isFormReady = function() {
|
||||
return this.state.formState.get('state') === FormState.Ready;
|
||||
};
|
||||
|
||||
inst.isFormValidationShown = function() {
|
||||
proto.isFormValidationShown = function() {
|
||||
return this.state.formState.get('isValidationShown');
|
||||
};
|
||||
|
||||
inst.addFormValidationClass = function(className, name) {
|
||||
proto.addFormValidationClass = function(className, name) {
|
||||
if (this.isFormValidationShown()) {
|
||||
const error = this.getFormError(name);
|
||||
if (error) {
|
||||
|
@ -1234,7 +1252,7 @@ function withForm(target) {
|
|||
}
|
||||
};
|
||||
|
||||
inst.getFormValidationMessage = function(name) {
|
||||
proto.getFormValidationMessage = function(name) {
|
||||
if (this.isFormValidationShown()) {
|
||||
return this.getFormError(name);
|
||||
} else {
|
||||
|
@ -1242,31 +1260,31 @@ function withForm(target) {
|
|||
}
|
||||
};
|
||||
|
||||
inst.showFormValidation = function() {
|
||||
proto.showFormValidation = function() {
|
||||
this.setState(previousState => ({formState: previousState.formState.set('isValidationShown', true)}));
|
||||
};
|
||||
|
||||
inst.hideFormValidation = function() {
|
||||
proto.hideFormValidation = function() {
|
||||
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'));
|
||||
};
|
||||
|
||||
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']));
|
||||
};
|
||||
|
||||
inst.getFormStatusMessageText = function() {
|
||||
proto.getFormStatusMessageText = function() {
|
||||
return this.state.formState.get('statusMessageText');
|
||||
};
|
||||
|
||||
inst.getFormStatusMessageSeverity = function() {
|
||||
proto.getFormStatusMessageSeverity = function() {
|
||||
return this.state.formState.get('statusMessageSeverity');
|
||||
};
|
||||
|
||||
inst.setFormStatusMessage = function(severity, text) {
|
||||
proto.setFormStatusMessage = function(severity, text) {
|
||||
this.setState(previousState => ({
|
||||
formState: previousState.formState.withMutations(map => {
|
||||
map.set('statusMessageText', text);
|
||||
|
@ -1275,7 +1293,7 @@ function withForm(target) {
|
|||
}));
|
||||
};
|
||||
|
||||
inst.clearFormStatusMessage = function() {
|
||||
proto.clearFormStatusMessage = function() {
|
||||
this.setState(previousState => ({
|
||||
formState: previousState.formState.withMutations(map => {
|
||||
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)}));
|
||||
};
|
||||
|
||||
inst.disableForm = function() {
|
||||
proto.disableForm = function() {
|
||||
this.setState(previousState => ({formState: previousState.formState.set('isDisabled', true)}));
|
||||
};
|
||||
|
||||
inst.isFormDisabled = function() {
|
||||
proto.isFormDisabled = function() {
|
||||
return this.state.formState.get('isDisabled');
|
||||
};
|
||||
|
||||
inst.formHandleChangedError = async function(fn) {
|
||||
proto.formHandleChangedError = async function(fn) {
|
||||
const t = this.props.t;
|
||||
try {
|
||||
await fn();
|
||||
|
@ -1337,8 +1355,8 @@ function withForm(target) {
|
|||
}
|
||||
};
|
||||
|
||||
return target;
|
||||
}
|
||||
return TargetClass;
|
||||
});
|
||||
|
||||
|
||||
export {
|
||||
|
|
|
@ -9,12 +9,11 @@ import LanguageDetector
|
|||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
|
||||
import hoistStatics
|
||||
from 'hoist-non-react-statics';
|
||||
|
||||
import {convertToFake, getLang} from '../../../shared/langs';
|
||||
import {createComponentMixin} from "./decorator-helpers";
|
||||
|
||||
import lang_en_US_common from "../../../locales/en-US/common";
|
||||
import {withPageHelpers} from "./page-common";
|
||||
|
||||
const resourcesCommon = {
|
||||
'en-US': lang_en_US_common,
|
||||
|
@ -42,8 +41,7 @@ i18n
|
|||
},
|
||||
|
||||
react: {
|
||||
wait: true,
|
||||
defaultTransParent: 'span' // This is because we use React < v16 FIXME
|
||||
wait: true
|
||||
},
|
||||
|
||||
detection: {
|
||||
|
@ -64,34 +62,9 @@ i18n
|
|||
export default i18n;
|
||||
|
||||
|
||||
export function withTranslation(opts) {
|
||||
if (opts && opts.delegateFuns) {
|
||||
return function (WrappedComponent) {
|
||||
class Wrapper extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.WrappedComponentWithNamespaces = withNamespaces(null, {innerRef: ref => this.wrappedComponent = ref})(WrappedComponent);
|
||||
}
|
||||
|
||||
render() {
|
||||
const WrappedComponentWithNamespaces = this.WrappedComponentWithNamespaces;
|
||||
return <WrappedComponentWithNamespaces {...this.props}/>;
|
||||
}
|
||||
}
|
||||
|
||||
for (const fun of opts.delegateFuns) {
|
||||
Wrapper.prototype[fun] = function (...args) {
|
||||
return this.wrappedComponent[fun](...args);
|
||||
}
|
||||
}
|
||||
|
||||
return hoistStatics(Wrapper, WrappedComponent);
|
||||
}
|
||||
} else {
|
||||
return withNamespaces();
|
||||
}
|
||||
}
|
||||
export const withTranslation = createComponentMixin([], [], (TargetClass, InnerClass) => {
|
||||
return withNamespaces()(TargetClass)
|
||||
});
|
||||
|
||||
export function tMark(key) {
|
||||
return key;
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import axios, { HTTPMethod } from './axios';
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import axios, {HTTPMethod} from './axios';
|
||||
import {withTranslation} from './i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {
|
||||
Icon,
|
||||
ModalDialog
|
||||
} from "./bootstrap-components";
|
||||
import {getUrl} from "./urls";
|
||||
import {withPageHelpers} from "./page";
|
||||
import styles from './styles.scss';
|
||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
||||
import styles
|
||||
from './styles.scss';
|
||||
import interoperableErrors
|
||||
from '../../../shared/interoperable-errors';
|
||||
import {Link} from "react-router-dom";
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withPageHelpers
|
||||
])
|
||||
export class RestActionModalDialog extends Component {
|
||||
static propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
|
@ -127,8 +133,10 @@ function _getDependencyErrorMessage(err, t, name) {
|
|||
}
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withPageHelpers
|
||||
])
|
||||
export class DeleteModalDialog extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from './i18n';
|
||||
import { TreeTableSelect } from './form';
|
||||
import React, {Component} from 'react';
|
||||
import {withTranslation} from './i18n';
|
||||
import {TreeTableSelect} from './form';
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withComponentMixins([
|
||||
withTranslation
|
||||
])
|
||||
class NamespaceSelect extends Component {
|
||||
render() {
|
||||
const t = this.props.t;
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
'use strict';
|
||||
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import React
|
||||
from "react";
|
||||
import {withRouter} from "react-router";
|
||||
import {withErrorHandling} from "./error-handling";
|
||||
import axios from "../lib/axios";
|
||||
import axios
|
||||
from "../lib/axios";
|
||||
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 nextResolve = nextRoute.resolve;
|
||||
|
||||
|
@ -25,7 +27,7 @@ function needsResolve(route, nextRoute, match, nextMatch) {
|
|||
return false;
|
||||
}
|
||||
|
||||
async function resolve(route, match) {
|
||||
export async function resolve(route, match) {
|
||||
const keys = Object.keys(route.resolve);
|
||||
|
||||
const promises = keys.map(key => {
|
||||
|
@ -46,7 +48,7 @@ async function resolve(route, match) {
|
|||
return resolved;
|
||||
}
|
||||
|
||||
function getRoutes(urlPrefix, resolve, parents, structure, navs, primaryMenuComponent, secondaryMenuComponent) {
|
||||
export function getRoutes(urlPrefix, resolve, parents, structure, navs, primaryMenuComponent, secondaryMenuComponent) {
|
||||
let routes = [];
|
||||
for (let routeKey in structure) {
|
||||
const entry = structure[routeKey];
|
||||
|
@ -119,39 +121,23 @@ function getRoutes(urlPrefix, resolve, parents, structure, navs, primaryMenuComp
|
|||
return routes;
|
||||
}
|
||||
|
||||
function withPageHelpers(target) {
|
||||
target = withErrorHandling(target);
|
||||
|
||||
const inst = target.prototype;
|
||||
|
||||
const contextTypes = target.contextTypes || {};
|
||||
|
||||
contextTypes.sectionContent = PropTypes.object.isRequired;
|
||||
|
||||
target.contextTypes = contextTypes;
|
||||
|
||||
inst.setFlashMessage = function(severity, text) {
|
||||
return this.context.sectionContent.setFlashMessage(severity, text);
|
||||
export const SectionContentContext = React.createContext(null);
|
||||
export const withPageHelpers = createComponentMixin([{context: SectionContentContext, propName: 'sectionContent'}], [withErrorHandling], (TargetClass, InnerClass) => {
|
||||
InnerClass.prototype.setFlashMessage = function(severity, text) {
|
||||
return this.props.sectionContent.setFlashMessage(severity, text);
|
||||
};
|
||||
|
||||
inst.navigateTo = function(path) {
|
||||
return this.context.sectionContent.navigateTo(path);
|
||||
InnerClass.prototype.navigateTo = function(path) {
|
||||
return this.props.sectionContent.navigateTo(path);
|
||||
}
|
||||
|
||||
inst.navigateBack = function() {
|
||||
return this.context.sectionContent.navigateBack();
|
||||
InnerClass.prototype.navigateBack = function() {
|
||||
return this.props.sectionContent.navigateBack();
|
||||
}
|
||||
|
||||
inst.navigateToWithFlashMessage = function(path, severity, text) {
|
||||
return this.context.sectionContent.navigateToWithFlashMessage(path, severity, text);
|
||||
InnerClass.prototype.navigateToWithFlashMessage = function(path, severity, text) {
|
||||
return this.props.sectionContent.navigateToWithFlashMessage(path, severity, text);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
export {
|
||||
needsResolve,
|
||||
resolve,
|
||||
getRoutes,
|
||||
withPageHelpers
|
||||
};
|
||||
return TargetClass;
|
||||
});
|
||||
|
|
|
@ -1,17 +1,45 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from "react";
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes from "prop-types";
|
||||
import {withTranslation} from './i18n';
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import {withRouter} from "react-router";
|
||||
import {BrowserRouter as Router, Link, Redirect, Route, Switch} from "react-router-dom";
|
||||
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, withPageHelpers} from "./page-common";
|
||||
import {
|
||||
BrowserRouter as Router,
|
||||
Link,
|
||||
Redirect,
|
||||
Route,
|
||||
Switch
|
||||
} 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 {
|
||||
createComponentMixin,
|
||||
withComponentMixins
|
||||
} from "./decorator-helpers";
|
||||
|
||||
export { withPageHelpers }
|
||||
|
||||
class Breadcrumb extends Component {
|
||||
constructor(props) {
|
||||
|
@ -149,8 +177,10 @@ class SecondaryNavBar extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
@withTranslation()
|
||||
@withErrorHandling
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling
|
||||
])
|
||||
class RouteContent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -276,8 +306,10 @@ class RouteContent extends Component {
|
|||
|
||||
|
||||
@withRouter
|
||||
@withErrorHandling
|
||||
class SectionContent extends Component {
|
||||
@withComponentMixins([
|
||||
withErrorHandling
|
||||
])
|
||||
export class SectionContent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
@ -295,16 +327,6 @@ class SectionContent extends Component {
|
|||
root: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
static childContextTypes = {
|
||||
sectionContent: PropTypes.object
|
||||
}
|
||||
|
||||
getChildContext() {
|
||||
return {
|
||||
sectionContent: this
|
||||
};
|
||||
}
|
||||
|
||||
setFlashMessage(severity, text) {
|
||||
this.setState({
|
||||
flashMessageText: text,
|
||||
|
@ -367,13 +389,17 @@ class SectionContent extends Component {
|
|||
let routes = getRoutes('', {}, [], this.props.structure, [], null, null);
|
||||
|
||||
return (
|
||||
<Switch>{routes.map(x => this.renderRoute(x))}</Switch>
|
||||
<SectionContentContext.Provider value={this}>
|
||||
<Switch>{routes.map(x => this.renderRoute(x))}</Switch>
|
||||
</SectionContentContext.Provider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@withTranslation()
|
||||
class Section extends Component {
|
||||
@withComponentMixins([
|
||||
withTranslation
|
||||
])
|
||||
export class Section extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
@ -398,7 +424,7 @@ class Section extends Component {
|
|||
}
|
||||
|
||||
|
||||
class Title extends Component {
|
||||
export class Title extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
|
@ -409,7 +435,7 @@ class Title extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
class Toolbar extends Component {
|
||||
export class Toolbar extends Component {
|
||||
static propTypes = {
|
||||
className: PropTypes.string,
|
||||
};
|
||||
|
@ -428,7 +454,7 @@ class Toolbar extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
class NavButton extends Component {
|
||||
export class NavButton extends Component {
|
||||
static propTypes = {
|
||||
label: PropTypes.string,
|
||||
icon: PropTypes.string,
|
||||
|
@ -445,7 +471,7 @@ class NavButton extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
class MenuLink extends Component {
|
||||
export class MenuLink extends Component {
|
||||
static propTypes = {
|
||||
to: PropTypes.string,
|
||||
className: PropTypes.string
|
||||
|
@ -460,33 +486,17 @@ class MenuLink extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
function requiresAuthenticatedUser(target) {
|
||||
const comp1 = withPageHelpers(target);
|
||||
|
||||
function comp2(props, context) {
|
||||
if (!new.target) {
|
||||
throw new TypeError();
|
||||
export const requiresAuthenticatedUser = createComponentMixin([], [withPageHelpers], (TargetClass, InnerClass) => {
|
||||
class RequiresAuthenticatedUser extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
props.sectionContent.ensureAuthenticated();
|
||||
}
|
||||
|
||||
context.sectionContent.ensureAuthenticated();
|
||||
return Reflect.construct(comp1, [props, context], new.target);
|
||||
render() {
|
||||
return <TargetClass {...this.props}/>
|
||||
}
|
||||
}
|
||||
|
||||
comp2.prototype = comp1.prototype;
|
||||
|
||||
for (const attr in comp1) {
|
||||
comp2[attr] = comp1[attr];
|
||||
}
|
||||
|
||||
return comp2;
|
||||
}
|
||||
|
||||
export {
|
||||
Section,
|
||||
Title,
|
||||
Toolbar,
|
||||
NavButton,
|
||||
MenuLink,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
};
|
||||
return RequiresAuthenticatedUser;
|
||||
});
|
||||
|
|
|
@ -29,9 +29,12 @@ import CKEditor
|
|||
from "react-ckeditor-component";
|
||||
|
||||
import {initialHeight} from "./sandboxed-ckeditor-shared";
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withComponentMixins([
|
||||
withTranslation
|
||||
])
|
||||
class CKEditorSandbox extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import { withTranslation } from './i18n';
|
||||
import {withTranslation} from './i18n';
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import styles
|
||||
|
@ -11,10 +11,14 @@ import {UntrustedContentHost} from './untrusted';
|
|||
import {Icon} from "./bootstrap-components";
|
||||
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
|
||||
|
||||
@withTranslation({delegateFuns: ['exportState']})
|
||||
@withComponentMixins([
|
||||
withTranslation
|
||||
], ['exportState'])
|
||||
export class CKEditorHost extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -35,10 +35,13 @@ import mjml2html
|
|||
from "mjml4-in-browser";
|
||||
import juice
|
||||
from "juice";
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
const refreshTimeout = 1000;
|
||||
|
||||
@withTranslation()
|
||||
@withComponentMixins([
|
||||
withTranslation
|
||||
])
|
||||
class CodeEditorSandbox extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import { withTranslation } from './i18n';
|
||||
import {withTranslation} from './i18n';
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import styles
|
||||
|
@ -10,8 +10,11 @@ import styles
|
|||
import {UntrustedContentHost} from './untrusted';
|
||||
import {Icon} from "./bootstrap-components";
|
||||
import {getTrustedUrl} from "./urls";
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
@withTranslation({delegateFuns: ['exportState']})
|
||||
@withComponentMixins([
|
||||
withTranslation
|
||||
], ['exportState'])
|
||||
export class CodeEditorHost extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -39,6 +39,7 @@ import "./sandboxed-grapesjs.scss";
|
|||
import axios
|
||||
from './axios';
|
||||
import {GrapesJSSourceType} from "./sandboxed-grapesjs-shared";
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
|
||||
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 {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import { withTranslation } from './i18n';
|
||||
import {withTranslation} from './i18n';
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import styles
|
||||
|
@ -10,8 +10,11 @@ import styles
|
|||
import {UntrustedContentHost} from './untrusted';
|
||||
import {Icon} from "./bootstrap-components";
|
||||
import {getTrustedUrl} from "./urls";
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
@withTranslation({delegateFuns: ['exportState']})
|
||||
@withComponentMixins([
|
||||
withTranslation
|
||||
], ['exportState'])
|
||||
export class GrapesJSHost extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -22,9 +22,12 @@ import {
|
|||
base,
|
||||
unbase
|
||||
} from "../../../shared/templates";
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withComponentMixins([
|
||||
withTranslation
|
||||
])
|
||||
class MosaicoSandbox extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import { withTranslation } from './i18n';
|
||||
import {withTranslation} from './i18n';
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import styles
|
||||
|
@ -10,9 +10,12 @@ import styles
|
|||
import {UntrustedContentHost} from './untrusted';
|
||||
import {Icon} from "./bootstrap-components";
|
||||
import {getTrustedUrl} from "./urls";
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
|
||||
@withTranslation({delegateFuns: ['exportState']})
|
||||
@withComponentMixins([
|
||||
withTranslation
|
||||
], ['exportState'])
|
||||
export class MosaicoHost extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,22 +1,31 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from './i18n';
|
||||
import React, {Component} from 'react';
|
||||
import ReactDOMServer
|
||||
from 'react-dom/server';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from './i18n';
|
||||
|
||||
import jQuery from 'jquery';
|
||||
import jQuery
|
||||
from 'jquery';
|
||||
|
||||
import 'datatables.net';
|
||||
import 'datatables.net-bs';
|
||||
import 'datatables.net-bs/css/dataTables.bootstrap.css';
|
||||
|
||||
import axios from './axios';
|
||||
import axios
|
||||
from './axios';
|
||||
|
||||
import { withPageHelpers } from './page'
|
||||
import { withErrorHandling, withAsyncErrorHandler } from './error-handling';
|
||||
import styles from "./styles.scss";
|
||||
import {withPageHelpers} from './page'
|
||||
import {
|
||||
withAsyncErrorHandler,
|
||||
withErrorHandling
|
||||
} from './error-handling';
|
||||
import styles
|
||||
from "./styles.scss";
|
||||
import {getUrl} from "./urls";
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
//dtFactory();
|
||||
//dtSelectFactory();
|
||||
|
@ -28,9 +37,11 @@ const TableSelectMode = {
|
|||
MULTI: 2
|
||||
};
|
||||
|
||||
@withTranslation({delegateFuns: ['refresh']})
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers
|
||||
], ['refresh'])
|
||||
class Table extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,21 +1,30 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, {Component} from 'react';
|
||||
import ReactDOMServer
|
||||
from 'react-dom/server';
|
||||
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/fancytree/jquery.fancytree-all.min.js';
|
||||
import '../../vendor/fancytree/skin-bootstrap/ui.fancytree.min.css';
|
||||
import './tree.css';
|
||||
import axios from './axios';
|
||||
import axios
|
||||
from './axios';
|
||||
|
||||
import { withPageHelpers } from './page'
|
||||
import { withErrorHandling, withAsyncErrorHandler } from './error-handling';
|
||||
import styles from "./styles.scss";
|
||||
import {withPageHelpers} from './page'
|
||||
import {
|
||||
withAsyncErrorHandler,
|
||||
withErrorHandling
|
||||
} from './error-handling';
|
||||
import styles
|
||||
from "./styles.scss";
|
||||
import {getUrl} from "./urls";
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
const TreeSelectMode = {
|
||||
NONE: 0,
|
||||
|
@ -23,9 +32,11 @@ const TreeSelectMode = {
|
|||
MULTI: 2
|
||||
};
|
||||
|
||||
@withTranslation({delegateFuns: ['refresh']})
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers
|
||||
], ['refresh'])
|
||||
class TreeTable extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { withTranslation } from './i18n';
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import {withTranslation} from './i18n';
|
||||
import {
|
||||
requiresAuthenticatedUser,
|
||||
withPageHelpers
|
||||
|
@ -11,18 +12,23 @@ import {
|
|||
withAsyncErrorHandler,
|
||||
withErrorHandling
|
||||
} from "./error-handling";
|
||||
import axios from "./axios";
|
||||
import styles from "./styles.scss";
|
||||
import axios
|
||||
from "./axios";
|
||||
import styles
|
||||
from "./styles.scss";
|
||||
import {
|
||||
getSandboxUrl,
|
||||
getTrustedUrl,
|
||||
getUrl,
|
||||
setRestrictedAccessToken
|
||||
} from "./urls";
|
||||
import {withComponentMixins} from "./decorator-helpers";
|
||||
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
], ['ask'])
|
||||
export class UntrustedContentHost extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -173,7 +179,9 @@ export class UntrustedContentHost extends Component {
|
|||
}
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withComponentMixins([
|
||||
withTranslation
|
||||
])
|
||||
export class UntrustedContentRoot extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -36,12 +36,15 @@ import styles
|
|||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
import {getMailerTypes} from "../send-configurations/helpers";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import {requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton} from '../lib/page';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
||||
import { Table } from '../lib/table';
|
||||
import axios from '../lib/axios';
|
||||
import React, {Component} from 'react';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
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 {Icon} from "../lib/bootstrap-components";
|
||||
import {checkPermissions} from "../lib/permissions";
|
||||
|
@ -14,11 +22,16 @@ import {
|
|||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
import {withForm} from "../lib/form";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
requiresAuthenticatedUser,
|
||||
Title,
|
||||
|
@ -12,17 +13,21 @@ import {withErrorHandling} from '../lib/error-handling';
|
|||
import {Table} from '../lib/table';
|
||||
import {getTriggerTypes} from '../campaigns/triggers/helpers';
|
||||
import {Icon} from "../lib/bootstrap-components";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
import {
|
||||
tableAddDeleteButton,
|
||||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -40,12 +40,15 @@ import styles
|
|||
from "../../lib/styles.scss";
|
||||
import 'brace/mode/json';
|
||||
import 'brace/mode/handlebars';
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,23 +1,33 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import {requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton} from '../../lib/page';
|
||||
import { withErrorHandling } from '../../lib/error-handling';
|
||||
import { Table } from '../../lib/table';
|
||||
import { getFieldTypes } from './helpers';
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
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 {
|
||||
tableAddDeleteButton,
|
||||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../../lib/modals";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -16,7 +16,6 @@ import {
|
|||
AlignedRow,
|
||||
Button,
|
||||
ButtonRow,
|
||||
CheckBox,
|
||||
Dropdown,
|
||||
Fieldset,
|
||||
Form,
|
||||
|
@ -48,13 +47,15 @@ import formsStyles
|
|||
from "./styles.scss";
|
||||
import axios
|
||||
from "../../lib/axios";
|
||||
import {UntrustedContentHost} from "../../lib/untrusted";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import {requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton} from '../../lib/page';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../../lib/error-handling';
|
||||
import { Table } from '../../lib/table';
|
||||
import axios from '../../lib/axios';
|
||||
import React, {Component} from 'react';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
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 {checkPermissions} from "../../lib/permissions";
|
||||
import {
|
||||
|
@ -13,11 +21,14 @@ import {
|
|||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../../lib/modals";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
|
@ -32,15 +33,18 @@ import {
|
|||
ImportSource,
|
||||
inProgress,
|
||||
MappingType,
|
||||
prepInProgress,
|
||||
runInProgress
|
||||
prepInProgress
|
||||
} from '../../../../shared/imports';
|
||||
import axios from "../../lib/axios";
|
||||
import axios
|
||||
from "../../lib/axios";
|
||||
import {getUrl} from "../../lib/urls";
|
||||
import listStyles from "../styles.scss";
|
||||
import styles from "../../lib/styles.scss";
|
||||
import listStyles
|
||||
from "../styles.scss";
|
||||
import styles
|
||||
from "../../lib/styles.scss";
|
||||
import interoperableErrors
|
||||
from "../../../../shared/interoperable-errors";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
|
||||
function truncate(str, len, ending = '...') {
|
||||
|
@ -54,11 +58,13 @@ function truncate(str, len, ending = '...') {
|
|||
}
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
|
@ -14,19 +15,24 @@ import {withErrorHandling} from '../../lib/error-handling';
|
|||
import {Table} from '../../lib/table';
|
||||
import {getImportLabels} from './helpers';
|
||||
import {Icon} from "../../lib/bootstrap-components";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import moment from "moment";
|
||||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
import moment
|
||||
from "moment";
|
||||
import {inProgress} from '../../../../shared/imports';
|
||||
import {
|
||||
tableAddDeleteButton,
|
||||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../../lib/modals";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
requiresAuthenticatedUser,
|
||||
Title,
|
||||
|
@ -14,16 +15,21 @@ import {
|
|||
withErrorHandling
|
||||
} from '../../lib/error-handling';
|
||||
import {getImportLabels} from './helpers';
|
||||
import axios from "../../lib/axios";
|
||||
import axios
|
||||
from "../../lib/axios";
|
||||
import {getUrl} from "../../lib/urls";
|
||||
import moment from "moment";
|
||||
import moment
|
||||
from "moment";
|
||||
import {runStatusInProgress} from "../../../../shared/imports";
|
||||
import {Table} from "../../lib/table";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class Status extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
requiresAuthenticatedUser,
|
||||
Title,
|
||||
|
@ -10,8 +11,7 @@ import {
|
|||
} from '../../lib/page';
|
||||
import {
|
||||
AlignedRow,
|
||||
ButtonRow,
|
||||
Fieldset
|
||||
ButtonRow
|
||||
} from '../../lib/form';
|
||||
import {
|
||||
withAsyncErrorHandler,
|
||||
|
@ -21,7 +21,6 @@ import {getImportLabels} from './helpers';
|
|||
import {
|
||||
prepFinishedAndNotInProgress,
|
||||
runInProgress,
|
||||
RunStatus,
|
||||
runStatusInProgress
|
||||
} from '../../../../shared/imports';
|
||||
import {Table} from "../../lib/table";
|
||||
|
@ -29,15 +28,21 @@ import {
|
|||
Button,
|
||||
Icon
|
||||
} from "../../lib/bootstrap-components";
|
||||
import axios from "../../lib/axios";
|
||||
import axios
|
||||
from "../../lib/axios";
|
||||
import {getUrl} from "../../lib/urls";
|
||||
import moment from "moment";
|
||||
import interoperableErrors from '../../../../shared/interoperable-errors';
|
||||
import moment
|
||||
from "moment";
|
||||
import interoperableErrors
|
||||
from '../../../../shared/interoperable-errors';
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class Status extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
|
@ -22,28 +23,37 @@ import {
|
|||
import {withErrorHandling} from "../../lib/error-handling";
|
||||
import {DeleteModalDialog} from "../../lib/modals";
|
||||
|
||||
import styles from "./CUD.scss";
|
||||
import styles
|
||||
from "./CUD.scss";
|
||||
import {DragDropContext} from "react-dnd";
|
||||
import HTML5Backend from "react-dnd-html5-backend";
|
||||
import TouchBackend from "react-dnd-touch-backend";
|
||||
import SortableTree from "react-sortable-tree";
|
||||
import HTML5Backend
|
||||
from "react-dnd-html5-backend";
|
||||
import TouchBackend
|
||||
from "react-dnd-touch-backend";
|
||||
import SortableTree
|
||||
from "react-sortable-tree";
|
||||
import 'react-sortable-tree/style.css';
|
||||
import {
|
||||
ActionLink,
|
||||
Button,
|
||||
Icon
|
||||
} from "../../lib/bootstrap-components";
|
||||
import {getRuleHelpers} from "./helpers";
|
||||
import RuleSettingsPane from "./RuleSettingsPane";
|
||||
import RuleSettingsPane
|
||||
from "./RuleSettingsPane";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
// https://stackoverflow.com/a/4819886/1601953
|
||||
const isTouchDevice = !!('ontouchstart' in window || navigator.maxTouchPoints);
|
||||
|
||||
@DragDropContext(isTouchDevice ? TouchBackend : HTML5Backend)
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
// 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
|
||||
|
|
|
@ -1,22 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import {requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton} from '../../lib/page';
|
||||
import { withErrorHandling } from '../../lib/error-handling';
|
||||
import { Table } from '../../lib/table';
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
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 {
|
||||
tableAddDeleteButton,
|
||||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../../lib/modals";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,21 +1,36 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import {requiresAuthenticatedUser, withPageHelpers} from "../../lib/page";
|
||||
import {Button, ButtonRow, Dropdown, Form, TableSelect, withForm} from "../../lib/form";
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
requiresAuthenticatedUser,
|
||||
withPageHelpers
|
||||
} from "../../lib/page";
|
||||
import {
|
||||
Button,
|
||||
ButtonRow,
|
||||
Dropdown,
|
||||
Form,
|
||||
TableSelect,
|
||||
withForm
|
||||
} from "../../lib/form";
|
||||
import {withErrorHandling} from "../../lib/error-handling";
|
||||
import {getRuleHelpers} from "./helpers";
|
||||
import {getFieldTypes} from "../fields/helpers";
|
||||
|
||||
import styles from "./CUD.scss";
|
||||
import styles
|
||||
from "./CUD.scss";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -33,12 +33,15 @@ import {
|
|||
} from './helpers';
|
||||
import moment
|
||||
from 'moment-timezone';
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,37 +1,56 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import {requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton} from '../../lib/page';
|
||||
import {withAsyncErrorHandler, withErrorHandling} from '../../lib/error-handling';
|
||||
import { Table } from '../../lib/table';
|
||||
import { SubscriptionStatus } from '../../../../shared/lists';
|
||||
import moment from 'moment';
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
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
|
||||
} 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 {
|
||||
DeleteModalDialog,
|
||||
RestActionModalDialog,
|
||||
Button,
|
||||
Icon
|
||||
} from "../../lib/bootstrap-components";
|
||||
import {HTTPMethod} from '../../lib/axios';
|
||||
import {
|
||||
getFieldTypes,
|
||||
getSubscriptionStatusLabels
|
||||
} from './helpers';
|
||||
import {
|
||||
getPublicUrl,
|
||||
getUrl
|
||||
} from "../../lib/urls";
|
||||
import {
|
||||
tableAddDeleteButton,
|
||||
tableAddRestActionButton,
|
||||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender,
|
||||
tableAddRestActionButton
|
||||
tableRestActionDialogRender
|
||||
} from "../../lib/modals";
|
||||
import listStyles from "../styles.scss";
|
||||
import styles from '../../lib/styles.scss';
|
||||
import listStyles
|
||||
from "../styles.scss";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,23 +1,47 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import {requiresAuthenticatedUser, withPageHelpers, Title, NavButton} from '../lib/page';
|
||||
import { withForm, Form, FormSendMethod, InputField, TextArea, ButtonRow, Button, TreeTableSelect } from '../lib/form';
|
||||
import axios from '../lib/axios';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
||||
import interoperableErrors from '../../../shared/interoperable-errors';
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
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 mailtrainConfig from 'mailtrainConfig';
|
||||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
import {getGlobalNamespaceId} from "../../../shared/namespaces";
|
||||
import {getUrl} from "../lib/urls";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import { requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton } from '../lib/page';
|
||||
import { TreeTable } from '../lib/tree';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
||||
import axios from '../lib/axios';
|
||||
import React, {Component} from 'react';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
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 {checkPermissions} from "../lib/permissions";
|
||||
import {
|
||||
|
@ -14,11 +22,14 @@ import {
|
|||
tableRestActionDialogRender
|
||||
} from "../lib/modals";
|
||||
import {getGlobalNamespaceId} from "../../../shared/namespaces";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withErrorHandling
|
||||
@withPageHelpers
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,26 +1,52 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import {requiresAuthenticatedUser, withPageHelpers, Title, NavButton} from '../lib/page';
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
withForm, Form, FormSendMethod, InputField, TextArea, TableSelect, TableSelectMode, ButtonRow, Button,
|
||||
Fieldset
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
Title,
|
||||
withPageHelpers
|
||||
} from '../lib/page';
|
||||
import {
|
||||
Button,
|
||||
ButtonRow,
|
||||
Fieldset,
|
||||
Form,
|
||||
FormSendMethod,
|
||||
InputField,
|
||||
TableSelect,
|
||||
TableSelectMode,
|
||||
TextArea,
|
||||
withForm
|
||||
} from '../lib/form';
|
||||
import axios from '../lib/axios';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
||||
import moment from 'moment';
|
||||
import { validateNamespace, NamespaceSelect } from '../lib/namespace';
|
||||
import axios
|
||||
from '../lib/axios';
|
||||
import {
|
||||
withAsyncErrorHandler,
|
||||
withErrorHandling
|
||||
} from '../lib/error-handling';
|
||||
import moment
|
||||
from 'moment';
|
||||
import {
|
||||
NamespaceSelect,
|
||||
validateNamespace
|
||||
} from '../lib/namespace';
|
||||
import {DeleteModalDialog} from "../lib/modals";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
import {getUrl} from "../lib/urls";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,29 +1,40 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import { requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, NavButton } from '../lib/page';
|
||||
import { Table } from '../lib/table';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
||||
import moment from 'moment';
|
||||
import axios from '../lib/axios';
|
||||
import { ReportState } from '../../../shared/reports';
|
||||
import React, {Component} from 'react';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
Title,
|
||||
Toolbar,
|
||||
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 {checkPermissions} from "../lib/permissions";
|
||||
import {
|
||||
getPublicUrl,
|
||||
getUrl
|
||||
} from "../lib/urls";
|
||||
import {getUrl} from "../lib/urls";
|
||||
import {
|
||||
tableAddDeleteButton,
|
||||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withErrorHandling
|
||||
@withPageHelpers
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,27 +1,33 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import React, {Component} from 'react';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
requiresAuthenticatedUser,
|
||||
withPageHelpers,
|
||||
Title,
|
||||
Toolbar,
|
||||
NavButton
|
||||
withPageHelpers
|
||||
} from '../lib/page'
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
||||
import axios from '../lib/axios';
|
||||
import { ReportState } from '../../../shared/reports';
|
||||
import {
|
||||
withAsyncErrorHandler,
|
||||
withErrorHandling
|
||||
} from '../lib/error-handling';
|
||||
import axios
|
||||
from '../lib/axios';
|
||||
import {ReportState} from '../../../shared/reports';
|
||||
import {getUrl} from "../lib/urls";
|
||||
import {Button} from "../lib/bootstrap-components";
|
||||
import {Link} from "react-router-dom";
|
||||
import PropTypes
|
||||
from "prop-types";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class ViewAndOutput extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Trans
|
||||
} from 'react-i18next';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {Trans} from 'react-i18next';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
|
@ -29,16 +28,20 @@ import {
|
|||
validateNamespace
|
||||
} from '../../lib/namespace';
|
||||
import {DeleteModalDialog} from "../../lib/modals";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
import 'brace/mode/javascript';
|
||||
import 'brace/mode/json';
|
||||
import 'brace/mode/handlebars';
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,25 +1,41 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import {DropdownMenu, Icon} from '../../lib/bootstrap-components';
|
||||
import { requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, MenuLink } from '../../lib/page';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../../lib/error-handling';
|
||||
import { Table } from '../../lib/table';
|
||||
import axios from '../../lib/axios';
|
||||
import moment from 'moment';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import React, {Component} from 'react';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
DropdownMenu,
|
||||
Icon
|
||||
} from '../../lib/bootstrap-components';
|
||||
import {
|
||||
MenuLink,
|
||||
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 {
|
||||
tableAddDeleteButton,
|
||||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../../lib/modals";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -87,10 +103,10 @@ export default class List extends Component {
|
|||
{this.state.createPermitted &&
|
||||
<Toolbar>
|
||||
<DropdownMenu className="btn-primary" label={t('createReportTemplate')}>
|
||||
<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-csv">{t('openCountsAsCsv')}</MenuLink>
|
||||
<MenuLink to="/reports/templates/create/aggregated-open-counts">{t('aggregratedOpenCounts')}</MenuLink>
|
||||
<MenuLink to="/reports/templates/create">{t('Blank')}</MenuLink>
|
||||
<MenuLink to="/reports/templates/create/open-counts">{t('Open counts')}</MenuLink>
|
||||
<MenuLink to="/reports/templates/create/open-counts-csv">{t('Open counts as CSV')}</MenuLink>
|
||||
<MenuLink to="/reports/templates/create/aggregated-open-counts">{t('Aggregated open counts')}</MenuLink>
|
||||
</DropdownMenu>
|
||||
</Toolbar>
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ import axios
|
|||
from './lib/axios';
|
||||
import {getUrl} from "./lib/urls";
|
||||
import {getLang} from "../../shared/langs";
|
||||
import {withComponentMixins} from "./lib/decorator-helpers";
|
||||
|
||||
const topLevelMenuKeys = ['lists', 'templates', 'campaigns'];
|
||||
|
||||
|
@ -55,7 +56,9 @@ if (mailtrainConfig.reportsEnabled) {
|
|||
}
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withComponentMixins([
|
||||
withTranslation
|
||||
])
|
||||
class Root extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -42,13 +42,16 @@ import styles
|
|||
|
||||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {Icon} from '../lib/bootstrap-components';
|
||||
import {
|
||||
NavButton,
|
||||
|
@ -15,8 +15,8 @@ import {
|
|||
withErrorHandling
|
||||
} from '../lib/error-handling';
|
||||
import {Table} from '../lib/table';
|
||||
import axios from '../lib/axios';
|
||||
import moment from 'moment';
|
||||
import moment
|
||||
from 'moment';
|
||||
import {getMailerTypes} from './helpers';
|
||||
import {checkPermissions} from "../lib/permissions";
|
||||
import {
|
||||
|
@ -24,12 +24,15 @@ import {
|
|||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Trans
|
||||
} from 'react-i18next';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {Trans} from 'react-i18next';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
requiresAuthenticatedUser,
|
||||
Title,
|
||||
|
@ -22,12 +21,15 @@ import {
|
|||
withForm
|
||||
} from '../lib/form';
|
||||
import {withErrorHandling} from '../lib/error-handling';
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class Update extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,23 +1,41 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import { requiresAuthenticatedUser, withPageHelpers, Title } from '../lib/page';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
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';
|
||||
import { Table } from '../lib/table';
|
||||
import axios from '../lib/axios';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import {Table} from '../lib/table';
|
||||
import axios
|
||||
from '../lib/axios';
|
||||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
import {getUrl} from "../lib/urls";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class Share extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,20 +1,31 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import { requiresAuthenticatedUser, withPageHelpers, Title } from '../lib/page';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../lib/error-handling';
|
||||
import { Table } from '../lib/table';
|
||||
import axios from '../lib/axios';
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
requiresAuthenticatedUser,
|
||||
Title,
|
||||
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 {getUrl} from "../lib/urls";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class UserShares extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
|
@ -26,23 +27,29 @@ import {
|
|||
validateNamespace
|
||||
} from '../lib/namespace';
|
||||
import {DeleteModalDialog} from "../lib/modals";
|
||||
import mailtrainConfig from 'mailtrainConfig';
|
||||
import mailtrainConfig
|
||||
from 'mailtrainConfig';
|
||||
import {
|
||||
getEditForm,
|
||||
getTemplateTypes,
|
||||
getTypeForm
|
||||
} from './helpers';
|
||||
import axios from '../lib/axios';
|
||||
import styles from "../lib/styles.scss";
|
||||
import axios
|
||||
from '../lib/axios';
|
||||
import styles
|
||||
from "../lib/styles.scss";
|
||||
import {getUrl} from "../lib/urls";
|
||||
import {TestSendModalDialog} from "./TestSendModalDialog";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {Icon} from '../lib/bootstrap-components';
|
||||
import {
|
||||
NavButton,
|
||||
|
@ -15,7 +15,8 @@ import {
|
|||
withErrorHandling
|
||||
} from '../lib/error-handling';
|
||||
import {Table} from '../lib/table';
|
||||
import moment from 'moment';
|
||||
import moment
|
||||
from 'moment';
|
||||
import {getTemplateTypes} from './helpers';
|
||||
import {checkPermissions} from "../lib/permissions";
|
||||
import {
|
||||
|
@ -23,11 +24,14 @@ import {
|
|||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {ModalDialog} from "../lib/bootstrap-components";
|
||||
|
@ -18,15 +18,19 @@ import {withErrorHandling} from "../lib/error-handling";
|
|||
import moment
|
||||
from "moment";
|
||||
import {getMailerTypes} from "../send-configurations/helpers";
|
||||
import axios from '../lib/axios';
|
||||
import axios
|
||||
from '../lib/axios';
|
||||
import {getUrl} from "../lib/urls";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export class TestSendModalDialog extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -447,376 +447,178 @@ export function getTemplateTypes(t, prefix = '', entityTypeId = ResourceType.TEM
|
|||
export function getEditForm(owner, typeKey, prefix = '') {
|
||||
const t = owner.props.t;
|
||||
|
||||
return <div>
|
||||
<AlignedRow>
|
||||
<Button
|
||||
className="btn-default"
|
||||
onClickAsync={::owner.toggleMergeTagReference}
|
||||
label={t('mergeTagReference')}/>
|
||||
{owner.state.showMergeTagReference &&
|
||||
<div
|
||||
style={{marginTop: '15px'}}>
|
||||
<Trans
|
||||
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
|
||||
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>
|
||||
</Trans>
|
||||
<table
|
||||
className="table table-bordered table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<Trans
|
||||
i18nKey="mergeTag-1">Merge
|
||||
tag</Trans>
|
||||
</th>
|
||||
<th>
|
||||
<Trans
|
||||
i18nKey="description">Description</Trans>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[LINK_UNSUBSCRIBE]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="urlThatPointsToTheUnsubscribePage">URL
|
||||
that
|
||||
points
|
||||
to
|
||||
the
|
||||
unsubscribe
|
||||
page</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[LINK_PREFERENCES]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="urlThatPointsToThePreferencesPageOfThe">URL
|
||||
that
|
||||
points
|
||||
to
|
||||
the
|
||||
preferences
|
||||
page
|
||||
of
|
||||
the
|
||||
subscriber</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[LINK_BROWSER]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="urlToPreviewTheMessageInABrowser">URL
|
||||
to
|
||||
preview
|
||||
the
|
||||
message
|
||||
in
|
||||
a
|
||||
browser</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[EMAIL]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="emailAddress-1">Email
|
||||
address</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[TO_NAME]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="recipientNameAsItAppearsInEmailsToHeader">Recipient
|
||||
name
|
||||
as
|
||||
it
|
||||
appears
|
||||
in
|
||||
email's
|
||||
'To'
|
||||
header</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[SUBSCRIPTION_ID]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="uniqueIdThatIdentifiesTheRecipient">Unique
|
||||
ID
|
||||
that
|
||||
identifies
|
||||
the
|
||||
recipient</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[LIST_ID]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="uniqueIdThatIdentifiesTheListUsedForThis">Unique
|
||||
ID
|
||||
that
|
||||
identifies
|
||||
the
|
||||
list
|
||||
used
|
||||
for
|
||||
this
|
||||
campaign</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[CAMPAIGN_ID]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="uniqueIdThatIdentifiesCurrentCampaign">Unique
|
||||
ID
|
||||
that
|
||||
identifies
|
||||
current
|
||||
campaign</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<Trans
|
||||
i18nKey="forRssCampaignsTheFollowingFurtherTags">
|
||||
<p>For
|
||||
RSS
|
||||
campaigns,
|
||||
the
|
||||
following
|
||||
further
|
||||
tags
|
||||
can
|
||||
be
|
||||
used.</p>
|
||||
</Trans>
|
||||
<table
|
||||
className="table table-bordered table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<Trans
|
||||
i18nKey="mergeTag-1">Merge
|
||||
tag</Trans>
|
||||
</th>
|
||||
<th>
|
||||
<Trans
|
||||
i18nKey="description">Description</Trans>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[RSS_ENTRY_TITLE]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="rssEntryTitle">RSS
|
||||
entry
|
||||
title</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[RSS_ENTRY_DATE]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="rssEntryDate">RSS
|
||||
entry
|
||||
date</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[RSS_ENTRY_LINK]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="rssEntryLink">RSS
|
||||
entry
|
||||
link</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[RSS_ENTRY_CONTENT]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="contentOfAnRssEntry">Content
|
||||
of
|
||||
an
|
||||
RSS
|
||||
entry</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[RSS_ENTRY_SUMMARY]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="rssEntrySummary">RSS
|
||||
entry
|
||||
summary</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[RSS_ENTRY_IMAGE_URL]
|
||||
</th>
|
||||
<td>
|
||||
<Trans
|
||||
i18nKey="rssEntryImageUrl">RSS
|
||||
entry
|
||||
image
|
||||
URL</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>}
|
||||
</AlignedRow>
|
||||
return (
|
||||
<div>
|
||||
<AlignedRow>
|
||||
<Button
|
||||
className="btn-default"
|
||||
onClickAsync={::owner.toggleMergeTagReference}
|
||||
label={t('mergeTagReference')}/>
|
||||
{owner.state.showMergeTagReference &&
|
||||
<div style={{marginTop: '15px'}}>
|
||||
<Trans 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 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>
|
||||
</Trans>
|
||||
<table className="table table-bordered table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<Trans i18nKey="mergeTag-1">Merge tag</Trans>
|
||||
</th>
|
||||
<th>
|
||||
<Trans i18nKey="description">Description</Trans>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[LINK_UNSUBSCRIBE]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="urlThatPointsToTheUnsubscribePage">URL that points to the unsubscribe page</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[LINK_PREFERENCES]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="urlThatPointsToThePreferencesPageOfThe">URL that points to the preferences page of the subscriber</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[LINK_BROWSER]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="urlToPreviewTheMessageInABrowser">URL to preview the message in a browser</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[EMAIL]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="emailAddress-1">Email address</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[TO_NAME]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="recipientNameAsItAppearsInEmailsToHeader">Recipient name as it appears in email's 'To' header</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[SUBSCRIPTION_ID]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="uniqueIdThatIdentifiesTheRecipient">Unique ID that identifies the recipient</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[LIST_ID]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="uniqueIdThatIdentifiesTheListUsedForThis">Unique ID that identifies the list used for this campaign</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[CAMPAIGN_ID]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="uniqueIdThatIdentifiesCurrentCampaign">Unique ID that identifies current campaign</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<Trans i18nKey="forRssCampaignsTheFollowingFurtherTags">
|
||||
<p>For RSS campaigns, the following further tags can be used.</p>
|
||||
</Trans>
|
||||
<table className="table table-bordered table-condensed table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<Trans i18nKey="mergeTag-1">Merge tag</Trans>
|
||||
</th>
|
||||
<th>
|
||||
<Trans i18nKey="description">Description</Trans>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[RSS_ENTRY_TITLE]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="rssEntryTitle">RSS entry title</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[RSS_ENTRY_DATE]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="rssEntryDate">RSS entry date</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[RSS_ENTRY_LINK]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="rssEntryLink">RSS entry link</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[RSS_ENTRY_CONTENT]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="contentOfAnRssEntry">Content of an RSS entry</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[RSS_ENTRY_SUMMARY]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="rssEntrySummary">RSS entry summary</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
[RSS_ENTRY_IMAGE_URL]
|
||||
</th>
|
||||
<td>
|
||||
<Trans i18nKey="rssEntryImageUrl">RSS entry image URL</Trans>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>}
|
||||
</AlignedRow>
|
||||
|
||||
{owner.templateTypes[typeKey].getHTMLEditor(owner)}
|
||||
{owner.templateTypes[typeKey].getHTMLEditor(owner)}
|
||||
|
||||
<ACEEditor
|
||||
id={prefix + 'text'}
|
||||
height="400px"
|
||||
mode="text"
|
||||
label={t('templateContentPlainText')}
|
||||
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>}/>
|
||||
</div>;
|
||||
<ACEEditor
|
||||
id={prefix + 'text'}
|
||||
height="400px"
|
||||
mode="text"
|
||||
label={t('templateContentPlainText')}
|
||||
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>}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function getTypeForm(owner, typeKey, isEdit) {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
|
@ -31,12 +32,15 @@ import {
|
|||
getTemplateTypes,
|
||||
getTemplateTypesOrder
|
||||
} from "./helpers";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,26 +1,41 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { withTranslation } from '../../lib/i18n';
|
||||
import {DropdownMenu, Icon} from '../../lib/bootstrap-components';
|
||||
import { requiresAuthenticatedUser, withPageHelpers, Title, Toolbar, MenuLink } from '../../lib/page';
|
||||
import { withErrorHandling, withAsyncErrorHandler } from '../../lib/error-handling';
|
||||
import { Table } from '../../lib/table';
|
||||
import axios from '../../lib/axios';
|
||||
import moment from 'moment';
|
||||
import { getTemplateTypes } from './helpers';
|
||||
import React, {Component} from 'react';
|
||||
import {withTranslation} from '../../lib/i18n';
|
||||
import {
|
||||
DropdownMenu,
|
||||
Icon
|
||||
} from '../../lib/bootstrap-components';
|
||||
import {
|
||||
MenuLink,
|
||||
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 {
|
||||
tableAddDeleteButton,
|
||||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../../lib/modals";
|
||||
import {withComponentMixins} from "../../lib/decorator-helpers";
|
||||
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,22 +1,45 @@
|
|||
'use strict';
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import {requiresAuthenticatedUser, withPageHelpers, Title, NavButton} from '../lib/page';
|
||||
import { withForm, Form, FormSendMethod, InputField, ButtonRow, Button, TableSelect } 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 { validateNamespace, NamespaceSelect } from '../lib/namespace';
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes
|
||||
from 'prop-types';
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
Title,
|
||||
withPageHelpers
|
||||
} 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 {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withForm
|
||||
@withPageHelpers
|
||||
@withErrorHandling
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withForm,
|
||||
withErrorHandling,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class CUD extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -1,20 +1,30 @@
|
|||
'use strict';
|
||||
|
||||
import React, {Component} from "react";
|
||||
import { withTranslation } from '../lib/i18n';
|
||||
import {NavButton, requiresAuthenticatedUser, Title, Toolbar, withPageHelpers} from "../lib/page";
|
||||
import {withTranslation} from '../lib/i18n';
|
||||
import {
|
||||
NavButton,
|
||||
requiresAuthenticatedUser,
|
||||
Title,
|
||||
Toolbar,
|
||||
withPageHelpers
|
||||
} from "../lib/page";
|
||||
import {Table} from "../lib/table";
|
||||
import mailtrainConfig from "mailtrainConfig";
|
||||
import mailtrainConfig
|
||||
from "mailtrainConfig";
|
||||
import {Icon} from "../lib/bootstrap-components";
|
||||
import {
|
||||
tableAddDeleteButton,
|
||||
tableRestActionDialogInit,
|
||||
tableRestActionDialogRender
|
||||
} from "../lib/modals";
|
||||
import {withComponentMixins} from "../lib/decorator-helpers";
|
||||
|
||||
@withTranslation()
|
||||
@withPageHelpers
|
||||
@requiresAuthenticatedUser
|
||||
@withComponentMixins([
|
||||
withTranslation,
|
||||
withPageHelpers,
|
||||
requiresAuthenticatedUser
|
||||
])
|
||||
export default class List extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
|
@ -23,6 +23,8 @@ const shares = require('./models/shares');
|
|||
const { AppType } = require('../shared/app');
|
||||
const builtinZoneMta = require('./lib/builtin-zone-mta');
|
||||
|
||||
const { uploadedFilesDir } = require('./lib/file-helpers');
|
||||
|
||||
const trustedPort = config.www.trustedPort;
|
||||
const sandboxPort = config.www.sandboxPort;
|
||||
const publicPort = config.www.publicPort;
|
||||
|
@ -68,7 +70,6 @@ function startHTTPServer(appType, appName, port, callback) {
|
|||
server.listen({port, host}, callback);
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// Start the whole circus here
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
@ -99,7 +100,10 @@ dbcheck(err => { // Check if database needs upgrading before starting the server
|
|||
builtinZoneMta.spawn(() =>
|
||||
startHTTPServer(AppType.TRUSTED, 'trusted', trustedPort, () =>
|
||||
startHTTPServer(AppType.SANDBOXED, 'sandbox', sandboxPort, () =>
|
||||
startHTTPServer(AppType.PUBLIC, 'public', publicPort, () => {
|
||||
startHTTPServer(AppType.PUBLIC, 'public', publicPort, async () => {
|
||||
|
||||
await privilegeHelpers.ensureMailtrainDir(uploadedFilesDir);
|
||||
|
||||
privilegeHelpers.dropRootPrivileges();
|
||||
|
||||
tzupdate.start();
|
||||
|
|
|
@ -18,5 +18,6 @@ function installUploadHandler(router, url, replacementBehavior, type, subType, t
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
installUploadHandler
|
||||
installUploadHandler,
|
||||
uploadedFilesDir
|
||||
};
|
|
@ -3,7 +3,7 @@
|
|||
const log = require('./log');
|
||||
const config = require('config');
|
||||
|
||||
const fs = require('fs');
|
||||
const fs = require('fs-extra-promise');
|
||||
|
||||
const tryRequire = require('try-require');
|
||||
const posix = tryRequire('posix');
|
||||
|
@ -49,6 +49,12 @@ function ensureMailtrainOwner(file, 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() {
|
||||
if (config.group) {
|
||||
try {
|
||||
|
@ -72,6 +78,7 @@ function dropRootPrivileges() {
|
|||
module.exports = {
|
||||
dropRootPrivileges,
|
||||
ensureMailtrainOwner,
|
||||
ensureMailtrainDir,
|
||||
getConfigUidGid,
|
||||
getConfigROUidGid
|
||||
};
|
||||
|
|
|
@ -25,7 +25,7 @@ function enforceTypePermitted(type, subType) {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -11,7 +11,8 @@ const fs = require('fs-extra-promise');
|
|||
const path = require('path');
|
||||
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 allowedKeysUpdate = new Set(['name', 'description', 'mapping_type', 'mapping']);
|
||||
|
|
|
@ -9,7 +9,8 @@ const {castToInteger} = require('../../lib/helpers');
|
|||
|
||||
const path = require('path');
|
||||
const files = require('../../models/files');
|
||||
const uploadedFilesDir = path.join(files.filesDir, 'uploaded');
|
||||
|
||||
const {uploadedFilesDir} = require('../../lib/file-helpers')
|
||||
|
||||
const multer = require('multer')({
|
||||
dest: uploadedFilesDir
|
||||
|
|
Loading…
Reference in a new issue