From 675cbe497c3f2d0ee4d463a6e07af3921c88a612 Mon Sep 17 00:00:00 2001 From: Sean Landsman Date: Tue, 13 Jun 2017 18:15:05 +0100 Subject: [PATCH] AG-538 Upgrade to React 15x AG-539 React rich grid example - fix bugs --- package.json | 1 + src-large/simpleCellRenderer.jsx | 3 +- .../renderers/HorizontalBarComponent.jsx | 3 +- src/App.jsx | 1 - src/richGridExample/ColDefFactory.jsx | 4 +- ...actDateComponent.jsx => DateComponent.jsx} | 62 ++++++++++--------- ...Component.jsx => HeaderGroupComponent.jsx} | 14 +++-- src/richGridExample/NameCellEditor.jsx | 3 +- src/richGridExample/ProficiencyFilter.jsx | 2 - src/richGridExample/RichGridExample.jsx | 27 ++++---- src/richGridExample/SkillsCellRenderer.jsx | 3 +- src/richGridExample/SkillsFilter.jsx | 10 +-- ...ponent.jsx => SortableHeaderComponent.jsx} | 42 +++++++------ 13 files changed, 98 insertions(+), 77 deletions(-) rename src/richGridExample/{MyReactDateComponent.jsx => DateComponent.jsx} (78%) rename src/richGridExample/{MyReactHeaderGroupComponent.jsx => HeaderGroupComponent.jsx} (83%) rename src/richGridExample/{MyReactHeaderComponent.jsx => SortableHeaderComponent.jsx} (51%) diff --git a/package.json b/package.json index cb34733..3d4f355 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "babel-preset-react": "6.24.x", "babel-preset-stage-0": "6.24.x", "babel-preset-stage-1": "6.24.x", + "prop-types": "15.5.x", "css-loader": "0.23.x", "mkdirp": "0.5.1", "ncp": "2.0.0", diff --git a/src-large/simpleCellRenderer.jsx b/src-large/simpleCellRenderer.jsx index baf7c64..bc4c5b0 100644 --- a/src-large/simpleCellRenderer.jsx +++ b/src-large/simpleCellRenderer.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import * as PropTypes from 'prop-types'; export default class SimpleCellRenderer extends React.Component { render() { @@ -11,5 +12,5 @@ export default class SimpleCellRenderer extends React.Component { } SimpleCellRenderer.propTypes = { - params: React.PropTypes.object + params: PropTypes.object }; \ No newline at end of file diff --git a/src-trader-dashboard/components/renderers/HorizontalBarComponent.jsx b/src-trader-dashboard/components/renderers/HorizontalBarComponent.jsx index 8111b1e..5651ed3 100644 --- a/src-trader-dashboard/components/renderers/HorizontalBarComponent.jsx +++ b/src-trader-dashboard/components/renderers/HorizontalBarComponent.jsx @@ -1,4 +1,5 @@ import React, {Component} from "react"; +import * as PropTypes from 'prop-types'; export default class HorizontalBarComponent extends Component { @@ -38,5 +39,5 @@ export default class HorizontalBarComponent extends Component { } HorizontalBarComponent.propTypes = { - params: React.PropTypes.object + params: PropTypes.object }; \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index c7e9675..af6dd1b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -30,7 +30,6 @@ class App extends Component { } setExample(example) { - console.log(example); this.setState({ example }) diff --git a/src/richGridExample/ColDefFactory.jsx b/src/richGridExample/ColDefFactory.jsx index d68d513..8c0e239 100644 --- a/src/richGridExample/ColDefFactory.jsx +++ b/src/richGridExample/ColDefFactory.jsx @@ -4,7 +4,7 @@ import ProficiencyCellRenderer from './ProficiencyCellRenderer.jsx'; import RefData from './RefData'; import SkillsFilter from './SkillsFilter.jsx'; import ProficiencyFilter from './ProficiencyFilter.jsx'; -import MyReactHeaderGroupComponent from './MyReactHeaderGroupComponent.jsx'; +import HeaderGroupComponent from './HeaderGroupComponent.jsx'; export default class ColDefFactory { @@ -15,7 +15,7 @@ export default class ColDefFactory { suppressMenu: true, pinned: true}, { headerName: 'Employee', - headerGroupComponentFramework: MyReactHeaderGroupComponent, + headerGroupComponentFramework: HeaderGroupComponent, children: [ { headerName: "Name", field: "name", enableRowGroup: true, enablePivot: true, diff --git a/src/richGridExample/MyReactDateComponent.jsx b/src/richGridExample/DateComponent.jsx similarity index 78% rename from src/richGridExample/MyReactDateComponent.jsx rename to src/richGridExample/DateComponent.jsx index d298abc..5ae4328 100644 --- a/src/richGridExample/MyReactDateComponent.jsx +++ b/src/richGridExample/DateComponent.jsx @@ -1,10 +1,11 @@ -import React from 'react'; +import React from "react"; +import * as PropTypes from "prop-types"; // Date Component to be used in the date filter. // This is a very simple example of how a React component can be plugged as a DateComponentFramework // as you can see, the only requirement is that the React component implements the required methods // getDate and setDate and that it calls back into props.onDateChanged every time that the date changes. -export default class MyReactDateComponent extends React.Component { +export default class DateComponent extends React.Component { constructor(props) { super(props); @@ -27,7 +28,7 @@ export default class MyReactDateComponent extends React.Component { render() { //Inlining styles to make simpler the component let filterStyle = { - margin:'2px' + margin: '2px' }; let ddStyle = { width: '30px' @@ -50,9 +51,12 @@ export default class MyReactDateComponent extends React.Component { return (
x - / - / - + / + / +
); } @@ -61,20 +65,20 @@ export default class MyReactDateComponent extends React.Component { // METHODS REQUIRED BY AG-GRID //********************************************************************************* - getDate (){ + getDate() { //ag-grid will call us here when in need to check what the current date value is hold by this //component. return this.state.date; } - setDate (date){ + setDate(date) { //ag-grid will call us here when it needs this component to update the date that it holds. this.setState({ - date:date, - textBoxes:{ - dd: date.getDate(), - mm: date.getMonth() + 1, - yyyy: date.getFullYear() + date, + textBoxes: { + dd: date ? date.getDate() : '', + mm: date ? date.getMonth() + 1 : '', + yyyy: date ? date.getFullYear() : '' } }) } @@ -83,10 +87,10 @@ export default class MyReactDateComponent extends React.Component { // LINKS THE INTERNAL STATE AND AG-GRID //********************************************************************************* - updateAndNotifyAgGrid (date, textBoxes){ - this.setState ({ + updateAndNotifyAgGrid(date, textBoxes) { + this.setState({ date: date, - textBoxes:textBoxes + textBoxes: textBoxes }, //Callback after the state is set. This is where we tell ag-grid that the date has changed so //it will proceed with the filtering and we can then expect ag-Grid to call us back to getDate @@ -99,23 +103,23 @@ export default class MyReactDateComponent extends React.Component { // LINKING THE UI, THE STATE AND AG-GRID //********************************************************************************* - resetDate (){ + resetDate() { let date = null; let textBoxes = { - dd : '', - mm : '', - yyyy : '', + dd: '', + mm: '', + yyyy: '', }; this.updateAndNotifyAgGrid(date, textBoxes) } - onDateChanged () { + onDateChanged() { let date = this.parseDate(this.refs.dd.value, this.refs.mm.value, this.refs.yyyy.value); let textBoxes = { - dd : this.refs.dd.value, - mm : this.refs.mm.value, - yyyy : this.refs.yyyy.value, + dd: this.refs.dd.value, + mm: this.refs.mm.value, + yyyy: this.refs.yyyy.value, }; this.updateAndNotifyAgGrid(date, textBoxes) @@ -125,7 +129,7 @@ export default class MyReactDateComponent extends React.Component { // INTERNAL LOGIC //********************************************************************************* - parseDate (dd, mm, yyyy){ + parseDate(dd, mm, yyyy) { //If any of the three input date fields are empty, stop and return null if (dd.trim() === '' || mm.trim() === '' || yyyy.trim() === '') { return null; @@ -138,7 +142,7 @@ export default class MyReactDateComponent extends React.Component { let date = new Date(year, month - 1, day); //If the date is not valid - if (isNaN(date.getTime())){ + if (isNaN(date.getTime())) { return null; } @@ -150,7 +154,7 @@ export default class MyReactDateComponent extends React.Component { //If the javascript date parts don't match the provided fields, we assume that the input is non //sensical... ie: Day=-1 or month=14, if this is the case, we return null //This also protects us from non sensical dates like dd=31, mm=2 of any year - if (date.getDate() != day || date.getMonth() + 1 != month || date.getFullYear() != year){ + if (date.getDate() != day || date.getMonth() + 1 != month || date.getFullYear() != year) { return null; } @@ -162,6 +166,6 @@ export default class MyReactDateComponent extends React.Component { // which is the grid passing you the params for the cellRenderer. // this piece is optional. the grid will always pass the 'params' // props, so little need for adding this validation meta-data. -MyReactDateComponent.propTypes = { - params: React.PropTypes.object +DateComponent.propTypes = { + params: PropTypes.object }; \ No newline at end of file diff --git a/src/richGridExample/MyReactHeaderGroupComponent.jsx b/src/richGridExample/HeaderGroupComponent.jsx similarity index 83% rename from src/richGridExample/MyReactHeaderGroupComponent.jsx rename to src/richGridExample/HeaderGroupComponent.jsx index 7fe3037..9afcaef 100644 --- a/src/richGridExample/MyReactHeaderGroupComponent.jsx +++ b/src/richGridExample/HeaderGroupComponent.jsx @@ -1,14 +1,18 @@ import React from 'react'; +import * as PropTypes from 'prop-types'; // Header component to be used as default for all the columns. -export default class MyReactHeaderGroupComponent extends React.Component { +export default class HeaderGroupComponent extends React.Component { constructor(props) { super(props); this.props.columnGroup.getOriginalColumnGroup().addEventListener('expandedChanged', this.onExpandChanged.bind(this)); this.state = { - expanded:null - } + expanded: null + }; + } + + componentDidMount() { this.onExpandChanged(); } @@ -36,6 +40,6 @@ export default class MyReactHeaderGroupComponent extends React.Component { // which is the grid passing you the params for the cellRenderer. // this piece is optional. the grid will always pass the 'params' // props, so little need for adding this validation meta-data. -MyReactHeaderGroupComponent.propTypes = { - params: React.PropTypes.object +HeaderGroupComponent.propTypes = { + params: PropTypes.object }; \ No newline at end of file diff --git a/src/richGridExample/NameCellEditor.jsx b/src/richGridExample/NameCellEditor.jsx index 2433631..c48447b 100644 --- a/src/richGridExample/NameCellEditor.jsx +++ b/src/richGridExample/NameCellEditor.jsx @@ -1,5 +1,6 @@ import React from 'react'; import RefData from './RefData'; +import * as PropTypes from 'prop-types'; var KEY_BACKSPACE = 8; var KEY_DELETE = 46; @@ -113,5 +114,5 @@ export default class NameCellEditor extends React.Component { // this piece is optional. the grid will always pass the 'params' // props, so little need for adding this validation meta-data. NameCellEditor.propTypes = { - params: React.PropTypes.object + params: PropTypes.object }; \ No newline at end of file diff --git a/src/richGridExample/ProficiencyFilter.jsx b/src/richGridExample/ProficiencyFilter.jsx index 5925031..3da73e2 100644 --- a/src/richGridExample/ProficiencyFilter.jsx +++ b/src/richGridExample/ProficiencyFilter.jsx @@ -32,11 +32,9 @@ export default class ProficiencyFilter extends React.Component { }; onButtonPressed(name) { - console.log(name); var newState = {selected: name}; // set the state, and once it is done, then call filterChangedCallback this.setState(newState, this.props.filterChangedCallback); - console.log(name); } render() { diff --git a/src/richGridExample/RichGridExample.jsx b/src/richGridExample/RichGridExample.jsx index b028e0e..8635f14 100644 --- a/src/richGridExample/RichGridExample.jsx +++ b/src/richGridExample/RichGridExample.jsx @@ -2,8 +2,8 @@ import React, {Component} from "react"; import {AgGridReact} from "ag-grid-react"; import RowDataFactory from "./RowDataFactory"; import ColDefFactory from "./ColDefFactory.jsx"; -import MyReactDateComponent from "./MyReactDateComponent.jsx"; -import MyReactHeaderComponent from "./MyReactHeaderComponent.jsx"; +import DateComponent from "./DateComponent.jsx"; +import SortableHeaderComponent from "./SortableHeaderComponent"; import "./RichGridExample.css"; @@ -41,13 +41,13 @@ export default class RichGridExample extends Component { // what you want! this.gridOptions = { //We register the react date component that ag-grid will use to render - dateComponentFramework: MyReactDateComponent, + dateComponentFramework: DateComponent, // this is how you listen for events using gridOptions onModelUpdated: function () { console.log('event onModelUpdated received'); }, defaultColDef: { - headerComponentFramework: MyReactHeaderComponent, + headerComponentFramework: SortableHeaderComponent, headerComponentParams: { menuIcon: 'fa-bars' } @@ -101,15 +101,15 @@ export default class RichGridExample extends Component { } onRefreshData() { - var newRowData = new RowDataFactory().createRowData(); + let newRowData = new RowDataFactory().createRowData(); this.setState({ rowData: newRowData }); } invokeSkillsFilterMethod() { - var skillsFilter = this.api.getFilterInstance('skills'); - var componentInstance = skillsFilter.getFrameworkComponentInstance(); + let skillsFilter = this.api.getFilterInstance('skills'); + let componentInstance = skillsFilter.getFrameworkComponentInstance(); componentInstance.helloFromSkillsFilter(); } @@ -117,14 +117,19 @@ export default class RichGridExample extends Component { let dateFilterComponent = this.gridOptions.api.getFilterInstance('dob'); dateFilterComponent.setFilterType('equals'); dateFilterComponent.setDateFrom('2000-01-01'); - this.gridOptions.api.onFilterChanged(); + // as the date filter is a React component, and its using setState internally, we need + // to allow time for the state to be set (as setState is an async operation) + // simply wait for the next tick + setTimeout(() => { + this.gridOptions.api.onFilterChanged(); + },0) } render() { - var gridTemplate; - var bottomHeaderTemplate; - var topHeaderTemplate; + let gridTemplate; + let bottomHeaderTemplate; + let topHeaderTemplate; topHeaderTemplate = (
diff --git a/src/richGridExample/SkillsCellRenderer.jsx b/src/richGridExample/SkillsCellRenderer.jsx index 332de28..90820d4 100644 --- a/src/richGridExample/SkillsCellRenderer.jsx +++ b/src/richGridExample/SkillsCellRenderer.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import * as PropTypes from 'prop-types'; import RefData from './RefData'; export default class SkillsCellRenderer extends React.Component { @@ -22,5 +23,5 @@ export default class SkillsCellRenderer extends React.Component { // this piece is optional. the grid will always pass the 'params' // props, so little need for adding this validation meta-data. SkillsCellRenderer.propTypes = { - params: React.PropTypes.object + params: PropTypes.object }; \ No newline at end of file diff --git a/src/richGridExample/SkillsFilter.jsx b/src/richGridExample/SkillsFilter.jsx index 381097c..55e4ca4 100644 --- a/src/richGridExample/SkillsFilter.jsx +++ b/src/richGridExample/SkillsFilter.jsx @@ -31,11 +31,11 @@ export default class SkillsFilter extends React.Component { setModel(model) { this.setState({ - android: model.android, - css: model.css, - html5: model.html5, - mac: model.mac, - windows: model.windows + android: model ? model.android : null, + css: model ? model.css : null, + html5: model ? model.html5 : null, + mac: model ? model.mac : null, + windows: model ? model.windows : null }); } diff --git a/src/richGridExample/MyReactHeaderComponent.jsx b/src/richGridExample/SortableHeaderComponent.jsx similarity index 51% rename from src/richGridExample/MyReactHeaderComponent.jsx rename to src/richGridExample/SortableHeaderComponent.jsx index 2c5d098..f034c1c 100644 --- a/src/richGridExample/MyReactHeaderComponent.jsx +++ b/src/richGridExample/SortableHeaderComponent.jsx @@ -1,7 +1,8 @@ -import React from 'react'; +import React from "react"; +import * as PropTypes from "prop-types"; // Header component to be used as default for all the columns. -export default class MyReactHeaderComponent extends React.Component { +export default class SortableHeaderComponent extends React.Component { constructor(props) { super(props); @@ -11,27 +12,32 @@ export default class MyReactHeaderComponent extends React.Component { //The state of this component contains the current sort state of this column //The possible values are: 'asc', 'desc' and '' this.state = { - sorted: '' + sorted: '' } } render() { let sortElements = []; - if (this.props.enableSorting){ + if (this.props.enableSorting) { let downArrowClass = "customSortDownLabel " + (this.state.sorted === 'desc' ? " active" : ""); let upArrowClass = "customSortUpLabel " + (this.state.sorted === 'asc' ? " active" : ""); let removeArrowClass = "customSortRemoveLabel " + (this.state.sorted === '' ? " active" : ""); - sortElements.push(
) - sortElements.push(
) - sortElements.push(
) + sortElements.push(
) + sortElements.push(
) + sortElements.push(
) } let menuButton = null; - if (this.props.enableMenu){ - menuButton =
+ if (this.props.enableMenu) { + menuButton = +
} return
@@ -41,16 +47,16 @@ export default class MyReactHeaderComponent extends React.Component {
} - onSortRequested (order, event) { - this.props.setSort (order, event.shiftKey); + onSortRequested(order, event) { + this.props.setSort(order, event.shiftKey); }; - onSortChanged (){ - if (this.props.column.isSortAscending()){ + onSortChanged() { + if (this.props.column.isSortAscending()) { this.setState({ sorted: 'asc' }) - } else if (this.props.column.isSortDescending()){ + } else if (this.props.column.isSortDescending()) { this.setState({ sorted: 'desc' }) @@ -61,8 +67,8 @@ export default class MyReactHeaderComponent extends React.Component { } }; - onMenuClick (){ - this.props.showColumnMenu (this.refs.menuButton); + onMenuClick() { + this.props.showColumnMenu(this.refs.menuButton); }; } @@ -71,6 +77,6 @@ export default class MyReactHeaderComponent extends React.Component { // which is the grid passing you the params for the cellRenderer. // this piece is optional. the grid will always pass the 'params' // props, so little need for adding this validation meta-data. -MyReactHeaderComponent.propTypes = { - params: React.PropTypes.object +SortableHeaderComponent.propTypes = { + params: PropTypes.object }; \ No newline at end of file