UNPKG

ldx-widgets

Version:

widgets

316 lines (284 loc) 10.1 kB
(function() { var ConfirmSave, ESCAPE, Form, KEY_S, PropTypes, React, Spinner, StyleSheet, assign, button, createClass, css, dialogueMixin, div, ref, ref1, ref2, span, styles; React = require('react'); createClass = require('create-react-class'); PropTypes = require('prop-types'); ref = require('aphrodite/no-important'), StyleSheet = ref.StyleSheet, css = ref.css; assign = require('lodash/assign'); dialogueMixin = require('../mixins/dialogue_mixin'); ref1 = require('../constants/keyboard'), ESCAPE = ref1.ESCAPE, KEY_S = ref1.KEY_S; ConfirmSave = React.createFactory(require('./confirm_save')); Spinner = React.createFactory(require('./spinner')); ref2 = require('react-dom-factories'), div = ref2.div, span = ref2.span, button = ref2.button; /*& @props.title - OPTIONAL - [String] title for the modal header @props.buttons - OPTIONAL - [Array] Array of button objects with name, handler to be called on click, and disabled boolean, eg... ``` [ { name: 'Create' handler: @create disabled: no } ] ``` @props.children - REQUIRED - [Element] React element (or array of elements) to inserted as the form body @props.styleOverride - OPTIONAL - [Object] aphrodite style object, optionally can contain .form, .title, .bar, .btn, .class defs, eg... ``` { formBase: {} form: {} title: {} bar: {} btn: {} } ``` @props.canUpdate - OPTIONAL - [Boolean] Defaults to no, whether or not the user can update and save the form @props.save - OPTIONAL - [Function] Function that save the form @props.close - OPTIONAL - [Function] Function that closes the form @props.onClose - OPTIONAL - [Function] Function that is called right before the modal closes @props.showClose - OPTIONAL - [Boolean] Defaults to yes, set it to no to not show the close button @props.closeAfterSave - OPTIONAL - [Boolean] Defaults to yes, set it to no to prevent the modal from calling @props.close after a save is complete Note: in this case you MUST pass an onSaveComplete handler that sets the saveState to null after a save @props.onSaveComplete - OPTIONAL - [Function] Function that is called right after the saveState is set to complete and the success indicator finishes animating @props.closeBtnText - OPTIONAL - [String] Defaults to 'Cancel', text to display in the close button @props.loading - OPTIONAL - [Boolean] Defaults to no, whether or not to show the spinner instead of the children @props.displayProgressBar - OPTIONAL - [Boolean] Defaults to no, whether or not the confirm/save show the progress bar instead of the spinner @props.uploadProgress - OPTIONAL Progress of a file being uploaded @props.unSavedMessage - OPTIONAL Message to be displayed in dialog if you have unsaved changes & */ Form = createClass({ displayName: 'Form', mixins: [dialogueMixin], propTypes: { styleOverride: PropTypes.shape({ form: PropTypes.object, bar: PropTypes.object, title: PropTypes.object, btn: PropTypes.object }), title: PropTypes.string, buttons: PropTypes.array, canUpdate: PropTypes.bool, save: PropTypes.func.isRequired, close: PropTypes.func.isRequired, onClose: PropTypes.func, onSaveComplete: PropTypes.func, showClose: PropTypes.bool, closeAfterSave: PropTypes.bool, closeBtnText: PropTypes.string, unSavedMessage: PropTypes.string, unSavedDialogueHeight: PropTypes.number, unSavedChanges: PropTypes.bool, onSaveFail: PropTypes.func, inLineStyle: PropTypes.object, loading: PropTypes.bool, spinnerProps: PropTypes.object, displayProgressBar: PropTypes.bool, uploadProgress: PropTypes.oneOfType([PropTypes.string, PropTypes.number]) }, getDefaultProps: function() { return { styleOverride: {}, inLineStyle: {}, buttons: [], canUpdate: true, showClose: true, closeAfterSave: true, unSavedDialogueHeight: 100, saveState: null, saveMessage: null, unSavedChanges: false, loading: false, spinnerProps: { length: 7, radius: 7, lines: 12, width: 2 }, displayProgressBar: false, uploadProgress: '' }; }, componentWillMount: function() { this.closeBtnText = t('Cancel'); return document.addEventListener('keydown', this.handleKeyPress); }, componentWillUnmount: function() { return document.removeEventListener('keydown', this.handleKeyPress); }, render: function() { var b, btns, buttons, canUpdate, children, closeBtnText, displayProgressBar, i, inLineStyle, loading, onSaveFail, ref3, save, saveMessage, saveState, showClose, spinnerProps, styleOverride, title, unSavedChanges, uploadProgress; ref3 = this.props, styleOverride = ref3.styleOverride, title = ref3.title, buttons = ref3.buttons, closeBtnText = ref3.closeBtnText, showClose = ref3.showClose, children = ref3.children, save = ref3.save, saveState = ref3.saveState, saveMessage = ref3.saveMessage, canUpdate = ref3.canUpdate, unSavedChanges = ref3.unSavedChanges, onSaveFail = ref3.onSaveFail, inLineStyle = ref3.inLineStyle, loading = ref3.loading, spinnerProps = ref3.spinnerProps, displayProgressBar = ref3.displayProgressBar, uploadProgress = ref3.uploadProgress; closeBtnText = closeBtnText || this.closeBtnText; btns = []; if (canUpdate) { btns.push(button({ key: 'save', className: unSavedChanges ? css(styles.btn) : css(styles.btn, styles.disabled), onClick: save, disabled: !unSavedChanges, tabIndex: -1 }, t('Save'))); } if (showClose) { btns.push(button({ key: 'cancel', className: css(styles.btn), onClick: this.closeWithCheck, tabIndex: -1 }, closeBtnText)); } for (i = buttons.length - 1; i >= 0; i += -1) { b = buttons[i]; btns.push(button({ key: b.name, className: css(styles.btn), onClick: b.handler, disabled: b.disabled }, b.name)); } assign(styles, styleOverride); inLineStyle = assign({}, inLineStyle); assign(spinnerProps, { key: 'spinner' }); return div({ className: css(styles.formBase, styles.form), style: inLineStyle }, [ !loading ? div({ key: 'bar', className: css(styles.bar) }, [ div({ key: 'name', className: css(styles.title) }, title), btns ]) : void 0, this.dialogueBox(), saveState != null ? ConfirmSave({ key: 'confirm', done: this.saveComplete, fail: function() { return typeof onSaveFail === "function" ? onSaveFail() : void 0; }, saveMessage: saveMessage, saveState: saveState, displayProgressBar: displayProgressBar, uploadProgress: uploadProgress }) : void 0, loading ? Spinner(spinnerProps) : children ]); }, closeWithCheck: function() { var ref3, unSavedChanges, unSavedDialogueHeight, unSavedMessage; ref3 = this.props, unSavedMessage = ref3.unSavedMessage, unSavedDialogueHeight = ref3.unSavedDialogueHeight, unSavedChanges = ref3.unSavedChanges; if (unSavedChanges) { return this.showDialogue({ message: unSavedMessage || t('There are unsaved changes. How do you want to proceed?'), confirmText: t('Discard Changes'), height: unSavedDialogueHeight, confirmCallback: this.close }); } else { return this.close(); } }, close: function() { var close, onClose, ref3; ref3 = this.props, close = ref3.close, onClose = ref3.onClose; if (typeof onClose === "function") { onClose(); } return close(); }, saveComplete: function() { var close, closeAfterSave, onSaveComplete, ref3; ref3 = this.props, close = ref3.close, onSaveComplete = ref3.onSaveComplete, closeAfterSave = ref3.closeAfterSave; if (typeof onSaveComplete === "function") { onSaveComplete(); } if (closeAfterSave) { return close(); } }, handleKeyPress: function(e) { var buttons, keyCode, metaKey, ref3; keyCode = e.keyCode, metaKey = e.metaKey; if (keyCode === ESCAPE) { this.closeWithCheck(); } if (keyCode === KEY_S && metaKey) { e.preventDefault(); buttons = this.props.buttons; if (((ref3 = buttons[0]) != null ? ref3.name : void 0) === t('Save')) { return buttons[0].handler(); } } } }); styles = StyleSheet.create({ formBase: { position: 'absolute', backgroundColor: 'white', overflow: 'hidden', width: '100%', height: '100%' }, form: { top: '0px', left: '0px' }, bar: { position: 'absolute', height: '40px', backgroundColor: '#fafaf6', borderBottom: '1px solid #e5e4dc', overflow: 'hidden', zIndex: '8', width: '100%' }, title: { overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis', fontSize: '18px', height: '100%', lineHeight: '40px', color: '#666666', display: 'inline-block', marginTop: '0px', marginLeft: '20px', paddingRight: '20px' }, btn: { float: 'right', marginRight: '15px', color: '#007fff', height: '28px', textAlign: 'center', lineHeight: '26px', marginTop: '6px', fontSize: '13px' }, disabled: { color: '#cccccc' } }); module.exports = Form; }).call(this);