From 361af18384208c87c38d3139446268d45b883364 Mon Sep 17 00:00:00 2001 From: Tomas Bures Date: Sun, 30 Jul 2017 16:22:07 +0300 Subject: [PATCH] Custom forms list and CUD. --- client/src/account/Account.js | 12 +- client/src/lib/delete.js | 65 ++++ client/src/lib/form.js | 395 +++++++++++++++++++++++- client/src/lists/CUD.js | 55 +--- client/src/lists/forms/CUD.js | 450 ++++++++++++++++++++++++++++ client/src/lists/root.js | 19 +- client/src/namespaces/CUD.js | 66 ++-- client/src/reports/CUD.js | 43 +-- client/src/reports/templates/CUD.js | 42 +-- client/src/users/CUD.js | 31 +- lib/client-helpers.js | 14 +- models/forms.js | 85 ++++-- 12 files changed, 1068 insertions(+), 209 deletions(-) create mode 100644 client/src/lib/delete.js create mode 100644 client/src/lists/forms/CUD.js diff --git a/client/src/account/Account.js b/client/src/account/Account.js index 159a8cea..8223f83c 100644 --- a/client/src/account/Account.js +++ b/client/src/account/Account.js @@ -27,7 +27,7 @@ export default class Account extends Component { this.initForm({ serverValidation: { url: '/rest/account-validate', - changed: ['email', 'username', 'currentPassword'] + changed: ['email', 'currentPassword'] } }); } @@ -53,10 +53,12 @@ export default class Account extends Component { if (!email) { state.setIn(['email', 'error'], t('Email must not be empty.')); - } else if (!emailServerValidation || emailServerValidation.invalid) { + } else if (emailServerValidation && emailServerValidation.invalid) { state.setIn(['email', 'error'], t('Invalid email address.')); - } else if (!emailServerValidation || emailServerValidation.exists) { + } else if (emailServerValidation && emailServerValidation.exists) { state.setIn(['email', 'error'], t('The email is already associated with another user in the system.')); + } else if (!emailServerValidation) { + state.setIn(['email', 'error'], t('Validation is in progress...')); } else { state.setIn(['email', 'error'], null); } @@ -86,8 +88,10 @@ export default class Account extends Component { if (!currentPassword) { state.setIn(['currentPassword', 'error'], t('Current password must not be empty.')); - } else if (!currentPasswordServerValidation || currentPasswordServerValidation.incorrect) { + } else if (currentPasswordServerValidation && currentPasswordServerValidation.incorrect) { state.setIn(['currentPassword', 'error'], t('Incorrect password.')); + } else if (!currentPasswordServerValidation) { + state.setIn(['email', 'error'], t('Validation is in progress...')); } else { state.setIn(['currentPassword', 'error'], null); } diff --git a/client/src/lib/delete.js b/client/src/lib/delete.js new file mode 100644 index 00000000..5a2730df --- /dev/null +++ b/client/src/lib/delete.js @@ -0,0 +1,65 @@ +'use strict'; + +import React, { Component } from 'react'; +import axios from './axios'; +import { translate } from 'react-i18next'; +import PropTypes from 'prop-types'; +import {ModalDialog} from "./bootstrap-components"; + +@translate() +class DeleteModalDialog extends Component { + static propTypes = { + stateOwner: PropTypes.object.isRequired, + visible: PropTypes.bool.isRequired, + deleteUrl: PropTypes.string.isRequired, + cudUrl: PropTypes.string.isRequired, + listUrl: PropTypes.string.isRequired, + deletingMsg: PropTypes.string.isRequired, + deletedMsg: PropTypes.string.isRequired, + onErrorAsync: PropTypes.func + } + + async hideDeleteModal() { + this.props.stateOwner.navigateTo(this.props.cudUrl); + } + + async performDelete() { + const t = this.props.t; + const owner = this.props.stateOwner; + + await this.hideDeleteModal(); + + try { + owner.disableForm(); + owner.setFormStatusMessage('info', this.props.deletingMsg); + await axios.delete(this.props.deleteUrl); + + owner.navigateToWithFlashMessage(this.props.listUrl, 'success', this.props.deletedMsg); + } catch (err) { + if (this.props.onErrorAsync) { + await this.props.onErrorAsync(err); + } else { + throw err; + } + } + } + + render() { + const t = this.props.t; + const owner = this.props.stateOwner; + + return ( + + ); + } +} + + +export { + DeleteModalDialog +} diff --git a/client/src/lib/form.js b/client/src/lib/form.js index d07d9a6d..333c2174 100644 --- a/client/src/lib/form.js +++ b/client/src/lib/form.js @@ -244,7 +244,8 @@ class Dropdown extends Component { id: PropTypes.string.isRequired, label: PropTypes.string.isRequired, help: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), - options: PropTypes.array.isRequired + options: PropTypes.array, + optGroups: PropTypes.array } static contextTypes = { @@ -257,7 +258,18 @@ class Dropdown extends Component { const owner = this.context.formStateOwner; const id = this.props.id; const htmlId = 'form_' + id; - const options = props.options.map(option => ); + let options = []; + + if (this.props.options) { + options = props.options.map(option => ); + } else if (this.props.optGroups) { + options = props.optGroups.map(optGroup => + + {optGroup.options.map(option => )} + + ); + } + return wrapInput(id, htmlId, owner, props.label, props.help,