From 236788ffb42092255f4264e96f8ac1a824fc5d2a Mon Sep 17 00:00:00 2001 From: Durran Jordan Date: Sun, 4 Dec 2016 13:28:10 +0100 Subject: [PATCH 1/4] Refactoring crud elements --- package.json | 3 +- src/internal-packages/crud/README.md | 2 +- .../crud/lib/component/document.jsx | 4 +- .../crud/lib/component/editable-document.jsx | 2 +- .../crud/lib/component/editable-element.jsx | 2 +- .../crud/lib/component/element.jsx | 177 ++++++++++++++++++ .../crud/lib/component/readonly-document.jsx | 23 ++- .../explain/lib/components/explain-json.jsx | 4 +- 8 files changed, 205 insertions(+), 12 deletions(-) create mode 100644 src/internal-packages/crud/lib/component/element.jsx diff --git a/package.json b/package.json index 5dd64003291..c0f546d972d 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,8 @@ "hadron-ipc": "^0.0.7", "hadron-module-cache": "^0.0.3", "hadron-package-manager": "0.2.0", - "hadron-react-bson": "^0.0.1", + "hadron-react-bson": "^0.0.2", + "hadron-react-buttons": "^0.0.2", "hadron-reflux-store": "^0.0.2", "hadron-style-manager": "0.0.1", "hadron-type-checker": "^0.15.0", diff --git a/src/internal-packages/crud/README.md b/src/internal-packages/crud/README.md index a4b138d9727..68a1f6972a6 100644 --- a/src/internal-packages/crud/README.md +++ b/src/internal-packages/crud/README.md @@ -52,7 +52,7 @@ const Document = app.appRegistry.getComponent('CRUD.Document'); class MyComponent extends React.Component { render() { - return (); + return (); } } ``` diff --git a/src/internal-packages/crud/lib/component/document.jsx b/src/internal-packages/crud/lib/component/document.jsx index e26047c90c7..15de15bf542 100644 --- a/src/internal-packages/crud/lib/component/document.jsx +++ b/src/internal-packages/crud/lib/component/document.jsx @@ -19,7 +19,7 @@ class Document extends React.Component { return ( + expandAll={this.props.expandAll} /> ); } } @@ -29,7 +29,7 @@ Document.displayName = 'Document'; Document.propTypes = { doc: React.PropTypes.object.isRequired, editable: React.PropTypes.bool, - preExpanded: React.PropTypes.bool + expandAll: React.PropTypes.bool }; module.exports = Document; diff --git a/src/internal-packages/crud/lib/component/editable-document.jsx b/src/internal-packages/crud/lib/component/editable-document.jsx index c78c56fda3e..956fe6895df 100644 --- a/src/internal-packages/crud/lib/component/editable-document.jsx +++ b/src/internal-packages/crud/lib/component/editable-document.jsx @@ -362,7 +362,7 @@ EditableDocument.displayName = 'EditableDocument'; EditableDocument.propTypes = { doc: React.PropTypes.object.isRequired, editable: React.PropTypes.bool, - preExpanded: React.PropTypes.bool + expandAll: React.PropTypes.bool }; module.exports = EditableDocument; diff --git a/src/internal-packages/crud/lib/component/editable-element.jsx b/src/internal-packages/crud/lib/component/editable-element.jsx index 742550e1450..46ce28d4fbd 100644 --- a/src/internal-packages/crud/lib/component/editable-element.jsx +++ b/src/internal-packages/crud/lib/component/editable-element.jsx @@ -91,7 +91,7 @@ class EditableElement extends React.Component { this.element.on(Element.Events.Edited, this.handleChange.bind(this)); this.element.on(Element.Events.Removed, this.handleChange.bind(this)); this.element.on(Element.Events.Reverted, this.handleChange.bind(this)); - this.state = { expanded: false }; + this.state = { expanded: this.props.expandAll }; } /** diff --git a/src/internal-packages/crud/lib/component/element.jsx b/src/internal-packages/crud/lib/component/element.jsx new file mode 100644 index 00000000000..a6079047acc --- /dev/null +++ b/src/internal-packages/crud/lib/component/element.jsx @@ -0,0 +1,177 @@ +const React = require('react'); +const getComponent = require('hadron-react-bson'); + +/** + * The base class. + */ +const CLASS = 'element'; + +/** + * The field class. + */ +const FIELD = `${CLASS}-field`; + +/** + * The separator class. + */ +const SEPARATOR = `${CLASS}-separator`; + +/** + * The expandable element class. + */ +const EXP_CLASS = 'expandable-element'; + +/** + * The expandable header class. + */ +const EXP_HEADER = `${EXP_CLASS}-header`; + +/** + * The carat toggle class. + */ +const EXP_TOGGLE = `${EXP_HEADER}-toggle`; + +/** + * The expandable field class. + */ +const EXP_FIELD = `${EXP_HEADER}-field`; + +/** + * The expandable label class. + */ +const EXP_LABEL = `${EXP_HEADER}-label`; + +/** + * The expandable children class. + */ +const EXP_CHILDREN = `${EXP_CLASS}-children`; + +/** + * The expandable element separator class. + */ +const EXP_SEPARATOR = `${EXP_HEADER}-separator`; + +/** + * General element component. + */ +class Element extends React.Component { + + /** + * Instantiate the element. + * + * @param {Object} props - The properties. + */ + constructor(props) { + super(props); + this.state = { expanded: props.expandAll }; + } + + /** + * Get the full class name for the base style. + * + * @param {String} base - The base class. + * + * @returns {String} The full class name. + */ + getClassName(base) { + if (this.state.expanded) { + return `${base} ${base}-is-expanded`; + } + return base; + } + + /** + * Toggles the expandable aspect of the element. + */ + toggleExpandable() { + this.setState({ expanded: !this.state.expanded }); + } + + /** + * Render the children. + * + * @returns {Array} The children. + */ + renderChildren() { + const components = []; + for (const element of this.props.element.elements) { + components.push( + () + ); + } + return components; + } + + /** + * Render a single element. + * + * @returns {React.Component} The single element. + */ + renderElement() { + return ( +
  • +
    + {this.props.element.currentKey} +
    + : + {this.renderValue()} +
  • + ); + } + + /** + * Render a single expandable element. + * + * @returns {React.Component} The expandable element. + */ + renderExpandableElement() { + return ( +
  • +
    +
    +
    {this.props.element.currentKey}
    + : +
    + {this.props.element.currentType} +
    +
    +
      + {this.renderChildren()} +
    +
  • + ); + } + + /** + * Render the value of the element. + * + * @returns {React.Component} The value component. + */ + renderValue() { + const component = getComponent(this.props.element.currentType); + return React.createElement( + component, + { type: this.props.element.currentType, value: this.props.element.currentValue } + ); + } + + /** + * Render a single element in a document. + * + * @returns {React.Component} The element component. + */ + render() { + return this.props.element.elements ? this.renderExpandableElement() : this.renderElement(); + } +} + +Element.displayName = 'Element'; + +Element.propTypes = { + element: React.PropTypes.any.isRequired +}; + +module.exports = Element; diff --git a/src/internal-packages/crud/lib/component/readonly-document.jsx b/src/internal-packages/crud/lib/component/readonly-document.jsx index 52b5fd4f10f..950be9aaf81 100644 --- a/src/internal-packages/crud/lib/component/readonly-document.jsx +++ b/src/internal-packages/crud/lib/component/readonly-document.jsx @@ -1,5 +1,6 @@ const React = require('react'); -const ElementFactory = require('hadron-app-registry').ElementFactory; +const HadronDocument = require('hadron-document'); +const Element = require('./element'); /** * The base class. @@ -21,13 +22,29 @@ const TEST_ID = 'readonly-document'; */ class ReadonlyDocument extends React.Component { + /** + * Initialize the readonly document. + * + * @param {Object} props - The properties. + */ + constructor(props) { + super(props); + this.doc = new HadronDocument(props.doc); + } + /** * Get the elements for the document. * * @returns {Array} The elements. */ renderElements() { - return ElementFactory.elements(this.props.doc, this.props.preExpanded || false); + const components = []; + for (const element of this.doc.elements) { + components.push(( + + )); + } + return components; } /** @@ -50,7 +67,7 @@ ReadonlyDocument.displayName = 'ReadonlyDocument'; ReadonlyDocument.propTypes = { doc: React.PropTypes.object.isRequired, - preExpanded: React.PropTypes.bool + expandAll: React.PropTypes.bool }; module.exports = ReadonlyDocument; diff --git a/src/internal-packages/explain/lib/components/explain-json.jsx b/src/internal-packages/explain/lib/components/explain-json.jsx index ee48feb6f35..10674fcc62c 100644 --- a/src/internal-packages/explain/lib/components/explain-json.jsx +++ b/src/internal-packages/explain/lib/components/explain-json.jsx @@ -1,8 +1,6 @@ const React = require('react'); const app = require('ampersand-app'); -// const debug = require('debug')('mongodb-compass:explain:summary'); - class ExplainJSON extends React.Component { componentWillMount() { @@ -20,7 +18,7 @@ class ExplainJSON extends React.Component {
      - +
    From f8ced5d726eafde4f199373965ba5b99b10cb346 Mon Sep 17 00:00:00 2001 From: Durran Jordan Date: Sun, 4 Dec 2016 13:33:58 +0100 Subject: [PATCH 2/4] Use new hadron-react-buttons --- src/internal-packages/crud/lib/component/document-actions.jsx | 2 +- src/internal-packages/crud/lib/component/document-footer.jsx | 2 +- .../crud/lib/component/insert-document-dialog.jsx | 2 +- .../crud/lib/component/remove-document-footer.jsx | 2 +- .../database/lib/components/collections-table.jsx | 2 +- .../database/lib/components/create-collection-dialog.jsx | 2 +- .../database/lib/components/drop-collection-dialog.jsx | 2 +- src/internal-packages/query/lib/component/sampling-message.jsx | 2 +- .../server-stats/lib/component/create-database-dialog.jsx | 2 +- .../server-stats/lib/component/databases-table.jsx | 2 +- .../server-stats/lib/component/drop-database-dialog.jsx | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/internal-packages/crud/lib/component/document-actions.jsx b/src/internal-packages/crud/lib/component/document-actions.jsx index 8d7a10e3e4c..8b872493164 100644 --- a/src/internal-packages/crud/lib/component/document-actions.jsx +++ b/src/internal-packages/crud/lib/component/document-actions.jsx @@ -1,5 +1,5 @@ const React = require('react'); -const IconButton = require('hadron-app-registry').IconButton; +const { IconButton } = require('hadron-react-buttons'); /** * Component for actions on the document. diff --git a/src/internal-packages/crud/lib/component/document-footer.jsx b/src/internal-packages/crud/lib/component/document-footer.jsx index 1cc86f0b79b..e184eb721c2 100644 --- a/src/internal-packages/crud/lib/component/document-footer.jsx +++ b/src/internal-packages/crud/lib/component/document-footer.jsx @@ -1,6 +1,6 @@ const React = require('react'); const Element = require('hadron-document').Element; -const TextButton = require('hadron-app-registry').TextButton; +const { TextButton } = require('hadron-react-buttons'); /** * The progress mode. diff --git a/src/internal-packages/crud/lib/component/insert-document-dialog.jsx b/src/internal-packages/crud/lib/component/insert-document-dialog.jsx index ec2eaf8e440..e524532bda9 100644 --- a/src/internal-packages/crud/lib/component/insert-document-dialog.jsx +++ b/src/internal-packages/crud/lib/component/insert-document-dialog.jsx @@ -4,7 +4,7 @@ const OpenInsertDocumentDialogStore = require('../store/open-insert-document-dia const InsertDocumentStore = require('../store/insert-document-store'); const InsertDocument = require('./insert-document'); const InsertDocumentFooter = require('./insert-document-footer'); -const TextButton = require('hadron-app-registry').TextButton; +const { TextButton } = require('hadron-react-buttons'); const Actions = require('../actions'); /** diff --git a/src/internal-packages/crud/lib/component/remove-document-footer.jsx b/src/internal-packages/crud/lib/component/remove-document-footer.jsx index 1f69dba1dd6..dd636564bb2 100644 --- a/src/internal-packages/crud/lib/component/remove-document-footer.jsx +++ b/src/internal-packages/crud/lib/component/remove-document-footer.jsx @@ -1,5 +1,5 @@ const React = require('react'); -const TextButton = require('hadron-app-registry').TextButton; +const { TextButton } = require('hadron-react-buttons'); /** * The progress mode. diff --git a/src/internal-packages/database/lib/components/collections-table.jsx b/src/internal-packages/database/lib/components/collections-table.jsx index 7c1d2820212..c059ea00beb 100644 --- a/src/internal-packages/database/lib/components/collections-table.jsx +++ b/src/internal-packages/database/lib/components/collections-table.jsx @@ -3,7 +3,7 @@ const app = require('ampersand-app'); const CollectionsActions = require('../actions/collections-actions'); const CreateCollectionDialog = require('./create-collection-dialog'); const DropCollectionDialog = require('./drop-collection-dialog'); -const TextButton = require('hadron-app-registry').TextButton; +const { TextButton } = require('hadron-react-buttons'); const numeral = require('numeral'); const _ = require('lodash'); diff --git a/src/internal-packages/database/lib/components/create-collection-dialog.jsx b/src/internal-packages/database/lib/components/create-collection-dialog.jsx index 89b7e962816..e798573a4d6 100644 --- a/src/internal-packages/database/lib/components/create-collection-dialog.jsx +++ b/src/internal-packages/database/lib/components/create-collection-dialog.jsx @@ -2,7 +2,7 @@ const app = require('ampersand-app'); const shell = require('electron').shell; const React = require('react'); const Modal = require('react-bootstrap').Modal; -const TextButton = require('hadron-app-registry').TextButton; +const { TextButton } = require('hadron-react-buttons'); const NamespaceStore = require('hadron-reflux-store').NamespaceStore; const toNS = require('mongodb-ns'); const Actions = require('../actions/collections-actions'); diff --git a/src/internal-packages/database/lib/components/drop-collection-dialog.jsx b/src/internal-packages/database/lib/components/drop-collection-dialog.jsx index 8b69cd34333..7146386b6d6 100644 --- a/src/internal-packages/database/lib/components/drop-collection-dialog.jsx +++ b/src/internal-packages/database/lib/components/drop-collection-dialog.jsx @@ -3,7 +3,7 @@ const React = require('react'); const Modal = require('react-bootstrap').Modal; const NamespaceStore = require('hadron-reflux-store').NamespaceStore; const toNS = require('mongodb-ns'); -const TextButton = require('hadron-app-registry').TextButton; +const { TextButton } = require('hadron-react-buttons'); const Actions = require('../actions/collections-actions'); const DropCollectionStore = require('../stores/drop-collection-store'); diff --git a/src/internal-packages/query/lib/component/sampling-message.jsx b/src/internal-packages/query/lib/component/sampling-message.jsx index 11377ad6f78..5f7f21d9fc9 100644 --- a/src/internal-packages/query/lib/component/sampling-message.jsx +++ b/src/internal-packages/query/lib/component/sampling-message.jsx @@ -1,6 +1,6 @@ const React = require('react'); const app = require('ampersand-app'); -const TextButton = require('hadron-app-registry').TextButton; +const { TextButton } = require('hadron-react-buttons'); const numeral = require('numeral'); const pluralize = require('pluralize'); diff --git a/src/internal-packages/server-stats/lib/component/create-database-dialog.jsx b/src/internal-packages/server-stats/lib/component/create-database-dialog.jsx index fdbe4f807ff..2b8768311c3 100644 --- a/src/internal-packages/server-stats/lib/component/create-database-dialog.jsx +++ b/src/internal-packages/server-stats/lib/component/create-database-dialog.jsx @@ -2,7 +2,7 @@ const app = require('ampersand-app'); const shell = require('electron').shell; const React = require('react'); const Modal = require('react-bootstrap').Modal; -const TextButton = require('hadron-app-registry').TextButton; +const { TextButton } = require('hadron-react-buttons'); const Actions = require('../action/databases-actions'); const CreateDatabaseStore = require('../store/create-database-store'); diff --git a/src/internal-packages/server-stats/lib/component/databases-table.jsx b/src/internal-packages/server-stats/lib/component/databases-table.jsx index 2880b7d4380..3cb23ce2cd2 100644 --- a/src/internal-packages/server-stats/lib/component/databases-table.jsx +++ b/src/internal-packages/server-stats/lib/component/databases-table.jsx @@ -1,6 +1,6 @@ const React = require('react'); const app = require('ampersand-app'); -const TextButton = require('hadron-app-registry').TextButton; +const { TextButton } = require('hadron-react-buttons'); const DatabasesActions = require('../action/databases-actions'); const CreateDatabaseDialog = require('./create-database-dialog'); const DropDatabaseDialog = require('./drop-database-dialog'); diff --git a/src/internal-packages/server-stats/lib/component/drop-database-dialog.jsx b/src/internal-packages/server-stats/lib/component/drop-database-dialog.jsx index 131bdbdb2ff..2bf6386d811 100644 --- a/src/internal-packages/server-stats/lib/component/drop-database-dialog.jsx +++ b/src/internal-packages/server-stats/lib/component/drop-database-dialog.jsx @@ -1,7 +1,7 @@ const app = require('ampersand-app'); const React = require('react'); const Modal = require('react-bootstrap').Modal; -const TextButton = require('hadron-app-registry').TextButton; +const { TextButton } = require('hadron-react-buttons'); const Actions = require('../action/databases-actions'); const DropDatabaseStore = require('../store/drop-database-store'); From a264237fe2c9a93011731e3d9faac4e7606b362c Mon Sep 17 00:00:00 2001 From: Durran Jordan Date: Sun, 4 Dec 2016 14:00:57 +0100 Subject: [PATCH 3/4] Bump the app registry to 4.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c0f546d972d..68a1dca4b66 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "font-awesome": "https://github.com/FortAwesome/Font-Awesome/archive/v4.4.0.tar.gz", "get-object-path": "azer/get-object-path#74eb42de0cfd02c14ffdd18552f295aba723d394", "hadron-action": "^0.1.0", - "hadron-app-registry": "^3.5.0", + "hadron-app-registry": "^4.0.0", "hadron-auto-update-manager": "^0.0.12", "hadron-compile-cache": "^0.3.0", "hadron-document": "^1.0.0", From 8d9bab2fab47baa020339c7710166b8590036a36 Mon Sep 17 00:00:00 2001 From: Durran Jordan Date: Sun, 4 Dec 2016 14:12:16 +0100 Subject: [PATCH 4/4] Fix eslint errors --- src/app/migrations/1.5.0-beta.5.js | 2 ++ src/internal-packages/crud/lib/component/editable-element.jsx | 3 ++- src/internal-packages/crud/lib/component/editable-value.jsx | 2 ++ src/internal-packages/crud/lib/component/element.jsx | 3 ++- src/internal-packages/crud/lib/component/utils.js | 3 +++ 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/app/migrations/1.5.0-beta.5.js b/src/app/migrations/1.5.0-beta.5.js index 7b4fec32684..e17aef4fac3 100644 --- a/src/app/migrations/1.5.0-beta.5.js +++ b/src/app/migrations/1.5.0-beta.5.js @@ -6,6 +6,8 @@ const ConnectionCollection = require('../models/connection-collection'); * This migration removes and then re-saves all connections in order to trigger * the secureCondition of the "splice" storage backend again, which wasn't correctly * working in 1.4.1, see COMPASS-426. + * + * @param {Function} done - The done callback. */ function rewriteStoredConnections(done) { debug('migration: rewriteStoredConnections'); diff --git a/src/internal-packages/crud/lib/component/editable-element.jsx b/src/internal-packages/crud/lib/component/editable-element.jsx index 46ce28d4fbd..a3e109d19dd 100644 --- a/src/internal-packages/crud/lib/component/editable-element.jsx +++ b/src/internal-packages/crud/lib/component/editable-element.jsx @@ -353,7 +353,8 @@ EditableElement.propTypes = { editing: React.PropTypes.bool, element: React.PropTypes.object.isRequired, index: React.PropTypes.number, - indent: React.PropTypes.number + indent: React.PropTypes.number, + expandAll: React.PropTypes.bool }; module.exports = EditableElement; diff --git a/src/internal-packages/crud/lib/component/editable-value.jsx b/src/internal-packages/crud/lib/component/editable-value.jsx index 0bf660a5612..06e86075b94 100644 --- a/src/internal-packages/crud/lib/component/editable-value.jsx +++ b/src/internal-packages/crud/lib/component/editable-value.jsx @@ -194,6 +194,8 @@ class EditableValue extends React.Component { /** * Get the style for the input wrapper. + * + * @returns {String} The class name. */ wrapperStyle() { return `${VALUE_CLASS}-wrapper-is-${this.element.currentType.toLowerCase()}`; diff --git a/src/internal-packages/crud/lib/component/element.jsx b/src/internal-packages/crud/lib/component/element.jsx index a6079047acc..95a6078fe73 100644 --- a/src/internal-packages/crud/lib/component/element.jsx +++ b/src/internal-packages/crud/lib/component/element.jsx @@ -171,7 +171,8 @@ class Element extends React.Component { Element.displayName = 'Element'; Element.propTypes = { - element: React.PropTypes.any.isRequired + element: React.PropTypes.any.isRequired, + expandAll: React.PropTypes.bool }; module.exports = Element; diff --git a/src/internal-packages/crud/lib/component/utils.js b/src/internal-packages/crud/lib/component/utils.js index 047c148fddb..9007f611e18 100644 --- a/src/internal-packages/crud/lib/component/utils.js +++ b/src/internal-packages/crud/lib/component/utils.js @@ -8,6 +8,8 @@ const FORMAT = 'YYYY-MM-DD HH:mm:ss.SSS'; /** * Get the size for the string value. * + * @param {Object} value - The value. + * * @return {Number} The size. */ function size(value) { @@ -19,6 +21,7 @@ function size(value) { * Get the size value for an input field when editing. * * @param {Object} value - The value. + * @param {String} type - The type. * * @returns {Integer} The size. */