-
owner.updateFormValue(id, !owner.getFormValue(id))}/>
+ return wrapInput(id, htmlId, owner, props.format, '', props.label, props.help,
+
+ owner.updateFormValue(id, !owner.getFormValue(id))}/>
- );
- }
- else{
- return wrapInput(id, htmlId, owner, props.format, '', props.label, props.help,
-
- owner.updateFormValue(id, !owner.getFormValue(id))}/>
-
-
- );
- }
-
-
+ );
}
}
diff --git a/client/src/lib/page.js b/client/src/lib/page.js
index 7de90d0f..995b58d7 100644
--- a/client/src/lib/page.js
+++ b/client/src/lib/page.js
@@ -1,701 +1,699 @@
-'use strict';
-
-import React, {Component} from "react";
-import i18n, {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 {
- ActionLink,
- Button,
- DismissibleAlert,
- DropdownActionLink,
- ButtonDropdown,
- Icon
-} 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";
-import {getLang} from "../../../shared/langs";
-
-export { withPageHelpers }
-
-class Breadcrumb extends Component {
- constructor(props) {
- super(props);
- }
-
- static propTypes = {
- route: PropTypes.object.isRequired,
- params: PropTypes.object.isRequired,
- resolved: PropTypes.object.isRequired
- }
-
- renderElement(entry, isActive) {
- const params = this.props.params;
- let title;
- if (typeof entry.title === 'function') {
- title = entry.title(this.props.resolved, params);
- } else {
- title = entry.title;
- }
-
- if (isActive) {
- return
{title};
-
- } else if (entry.externalLink) {
- let externalLink;
- if (typeof entry.externalLink === 'function') {
- externalLink = entry.externalLink(params);
- } else {
- externalLink = entry.externalLink;
- }
-
- return
{title};
-
- } else if (entry.link) {
- let link;
- if (typeof entry.link === 'function') {
- link = entry.link(params);
- } else {
- link = entry.link;
- }
- return
{title};
-
- } else {
- return
{title};
- }
- }
-
- render() {
- const route = this.props.route;
-
- const renderedElems = [...route.parents.map(x => this.renderElement(x)), this.renderElement(route, true)];
-
- return
;
- }
-}
-
-class TertiaryNavBar extends Component {
- static propTypes = {
- route: PropTypes.object.isRequired,
- params: PropTypes.object.isRequired,
- resolved: PropTypes.object.isRequired,
- className: PropTypes.string
- }
-
- renderElement(key, entry) {
- const params = this.props.params;
- let title;
- if (typeof entry.title === 'function') {
- title = entry.title(this.props.resolved);
- } else {
- title = entry.title;
- }
-
- let liClassName = 'nav-item';
- let linkClassName = 'nav-link';
- if (entry.active) {
- linkClassName += ' active';
- }
-
- if (entry.link) {
- let link;
-
- if (typeof entry.link === 'function') {
- link = entry.link(params);
- } else {
- link = entry.link;
- }
-
- return
{title};
-
- } else if (entry.externalLink) {
- let externalLink;
- if (typeof entry.externalLink === 'function') {
- externalLink = entry.externalLink(params);
- } else {
- externalLink = entry.externalLink;
- }
-
- return
{title};
-
- } else {
- return
{title};
- }
- }
-
- render() {
- const route = this.props.route;
-
- const keys = Object.keys(route.navs);
- const renderedElems = [];
-
- for (const key of keys) {
- const entry = route.navs[key];
-
- let visible = true;
- if (typeof entry.visible === 'function') {
- visible = entry.visible(this.props.resolved);
- }
-
- if (visible) {
- renderedElems.push(this.renderElement(key, entry));
- }
- }
-
- if (renderedElems.length > 1) {
- let className = styles.tertiaryNav + ' nav nav-pills';
- if (this.props.className) {
- className += ' ' + this.props.className;
- }
-
- return
;
- } else {
- return null;
- }
- }
-}
-
-@withComponentMixins([
- withTranslation,
- withErrorHandling
-])
-class RouteContent extends Component {
- constructor(props) {
- super(props);
- this.state = {
- panelInFullScreen: props.route.panelInFullScreen
- };
-
- if (Object.keys(props.route.resolve).length === 0) {
- this.state.resolved = {};
- }
-
- this.sidebarAnimationNodeListener = evt => {
- if (evt.propertyName === 'left') {
- this.forceUpdate();
- }
- };
-
- this.setPanelInFullScreen = panelInFullScreen => this.setState({ panelInFullScreen });
- }
-
- static propTypes = {
- route: PropTypes.object.isRequired,
- flashMessage: PropTypes.object
- }
-
- @withAsyncErrorHandler
- async resolve() {
- const props = this.props;
-
- if (Object.keys(props.route.resolve).length === 0) {
- this.setState({
- resolved: {}
- });
-
- } else {
- this.setState({
- resolved: null
- });
-
- const resolved = await resolve(props.route, props.match);
-
- if (!this.disregardResolve) { // This is to prevent the warning about setState on discarded component when we immediatelly redirect.
- this.setState({
- resolved
- });
- }
- }
- }
-
- registerSidebarAnimationListener() {
- if (this.sidebarAnimationNode) {
- this.sidebarAnimationNode.addEventListener("transitionend", this.sidebarAnimationNodeListener);
- }
- }
-
- componentDidMount() {
- // noinspection JSIgnoredPromiseFromCall
- this.resolve();
- this.registerSidebarAnimationListener();
- }
-
- componentDidUpdate(prevProps) {
- this.registerSidebarAnimationListener();
-
- if (this.props.location.state !== prevProps.location.state || (this.props.match.params !== prevProps.match.params && needsResolve(prevProps.route, this.props.route, prevProps.match, this.props.match))) {
- // noinspection JSIgnoredPromiseFromCall
- this.resolve();
- }
- }
-
- componentWillUnmount() {
- this.disregardResolve = true; // This is to prevent the warning about setState on discarded component when we immediatelly redirect.
- }
-
- render() {
- const t = this.props.t;
- const route = this.props.route;
- const params = this.props.match.params;
- const resolved = this.state.resolved;
-
- const showSidebar = !!route.secondaryMenuComponent;
-
- const panelInFullScreen = this.state.panelInFullScreen;
-
- if (!route.panelRender && !route.panelComponent && route.link) {
- let link;
- if (typeof route.link === 'function') {
- link = route.link(params);
- } else {
- link = route.link;
- }
-
- return
;
-
- } else {
- let primaryMenu = null;
- let secondaryMenu = null;
- let content = null;
-
- if (resolved) {
- const compProps = {
- match: this.props.match,
- location: this.props.location,
- resolved,
- setPanelInFullScreen: this.setPanelInFullScreen,
- panelInFullScreen: this.state.panelInFullScreen
- };
-
- let panel;
- if (route.panelComponent) {
- panel = React.createElement(route.panelComponent, compProps);
- } else if (route.panelRender) {
- panel = route.panelRender(compProps);
- }
-
- if (route.primaryMenuComponent) {
- primaryMenu = React.createElement(route.primaryMenuComponent, compProps);
- }
-
- if (route.secondaryMenuComponent) {
- secondaryMenu = React.createElement(route.secondaryMenuComponent, compProps);
- }
-
- const panelContent = (
-
- {this.props.flashMessage}
- {panel}
-
- );
-
- if (panelInFullScreen) {
- content = panelContent;
- } else {
- content = (
- <>
-
-
-
-
- {panelContent}
- >
- );
- }
-
- } else {
- content = (
-
- {t('loading')}
-
- );
- }
-
- if (panelInFullScreen) {
- return (
-
- );
-
- } else {
- return (
-
-
-
-
-
-
- {showSidebar &&
-
- {secondaryMenu}
-
- }
-
- {content}
-
-
-
-
-
- );
- }
- }
- }
-}
-
-
-@withRouter
-@withComponentMixins([
- withErrorHandling
-])
-export class SectionContent extends Component {
- constructor(props) {
- super(props);
-
- this.state = {
- flashMessageText: ''
- };
-
- this.historyUnlisten = props.history.listen((location, action) => {
- // noinspection JSIgnoredPromiseFromCall
- this.closeFlashMessage();
- });
- }
-
- static propTypes = {
- structure: PropTypes.object.isRequired,
- root: PropTypes.string.isRequired
- }
-
- setFlashMessage(severity, text) {
- this.setState({
- flashMessageText: text,
- flashMessageSeverity: severity
- });
- }
-
- navigateTo(path) {
- this.props.history.push(path);
- }
-
- navigateBack() {
- this.props.history.goBack();
- }
-
- navigateToWithFlashMessage(path, severity, text) {
- this.props.history.push(path);
- this.setFlashMessage(severity, text);
- }
-
- ensureAuthenticated() {
- if (!mailtrainConfig.isAuthenticated) {
- this.navigateTo('/login?next=' + encodeURIComponent(window.location.pathname));
- }
- }
-
- errorHandler(error) {
- if (error instanceof interoperableErrors.NotLoggedInError) {
- if (window.location.pathname !== '/login') { // There may be multiple async requests failing at the same time. So we take the pathname only from the first one.
- this.navigateTo('/login?next=' + encodeURIComponent(window.location.pathname));
- }
- } else if (error.response && error.response.data && error.response.data.message) {
- console.error(error);
- this.navigateToWithFlashMessage(this.props.root, 'danger', error.response.data.message);
- } else {
- console.error(error);
- this.navigateToWithFlashMessage(this.props.root, 'danger', error.message);
- }
- return true;
- }
-
- async closeFlashMessage() {
- this.setState({
- flashMessageText: ''
- });
- }
-
- renderRoute(route) {
- let flashMessage;
- if (this.state.flashMessageText) {
- flashMessage = {this.state.flashMessageText};
- }
-
- const render = props => ;
-
- return
- }
-
- render() {
- let routes = getRoutes('', {}, [], this.props.structure, [], null, null);
-
- return (
-
- {routes.map(x => this.renderRoute(x))}
-
- );
- }
-}
-
-@withComponentMixins([
- withTranslation
-])
-export class Section extends Component {
- constructor(props) {
- super(props);
- }
-
- static propTypes = {
- structure: PropTypes.oneOfType([PropTypes.object, PropTypes.func]).isRequired,
- root: PropTypes.string.isRequired
- }
-
- render() {
- let structure = this.props.structure;
- if (typeof structure === 'function') {
- structure = structure(this.props.t);
- }
-
- return (
-
-
-
- );
- }
-}
-
-
-export class Title extends Component {
- render() {
- return (
-
-
{this.props.children}
-
-
- );
- }
-}
-
-export class Toolbar extends Component {
- static propTypes = {
- className: PropTypes.string,
- };
-
- render() {
- let className = styles.toolbar + ' ' + styles.buttonRow;
- if (this.props.className) {
- className += ' ' + this.props.className;
- }
-
- return (
-
- {this.props.children}
-
- );
- }
-}
-
-export class LinkButton extends Component {
- static propTypes = {
- label: PropTypes.string,
- icon: PropTypes.string,
- className: PropTypes.string,
- to: PropTypes.string
- };
-
- render() {
- const props = this.props;
-
- return (
-