Compare commits

...

83 Commits

Author SHA1 Message Date
Sean Landsman
b26dfb5b82 Release 21.0.0 dist files added and license key updated 2019-05-31 08:14:14 +01:00
Sean Landsman
cda61736cf Framework sweep (react) 2019-05-18 15:47:50 +01:00
Sean Landsman
e55950227f AG-2750 Pre-release framework sweep 2019-03-19 16:30:35 +00:00
Sean Landsman
940cc314aa AG-2750 Pre-release framework sweep 2019-03-19 12:15:40 +00:00
Sean Landsman
5e4a94d865 AG-2750 Pre-release framework sweep 2019-03-19 08:17:15 +00:00
Sean Landsman
efa5167c54 Minor updates to deps 2019-03-18 15:08:58 +00:00
Sean Landsman
6b06b9fa01 AG-2741 Functional components don't work with reactNext 2019-03-14 12:01:33 +00:00
Sean Landsman
eecd2a6bb2 AG-1520 React wrapper causes styling issues for components 2019-03-06 14:13:10 +00:00
Sean Landsman
ec4f7dea27 Test CI Breaks on test failure 2019-03-06 09:36:31 +00:00
Sean Landsman
3d7774e7c7 AG-2656 Allow equality checking for rowData to be configurable (ie use equality checking, deep checking and so on) 2019-03-05 14:57:53 +00:00
Sean Landsman
92ad56ed49 AG-2656 Allow equality checking for rowData to be configurable (ie use equality checking, deep checking and so on) 2019-02-27 15:26:04 +00:00
Sean Landsman
7ff41a6966 Update fw examples 2019-02-20 15:35:12 +00:00
Sean Landsman
74ccfa6b26 AG-2653 Put React Hook example together, update docs 2019-02-12 14:45:24 +00:00
Sean Landsman
e07c66c95d AG-2264 Configuring AggregationPanel in status bar does not work if any other status panel is enabled 2019-02-08 11:00:27 +00:00
Sean Landsman
cb438ce67b Update versions 2019-01-11 11:06:50 +00:00
Sean Landsman
3f0fe9f899 AG-644 Refactor of sorting, filtering and resizing properties 2019-01-08 16:46:07 +00:00
Sean Landsman
a3a1d74b88 Framework sweep pre-release testing 2019-01-03 12:36:17 +00:00
Sean Landsman
2b49fb1b01 AG-2114 React Components are rendered to the root of the DOM tree
AG-2417 Issue with React 6: withRef is removed. To access the wrapped instance, use a ref on the connected component
AG-2439 Add support for react-redux v6

h/t @hrgui - thanks!
2018-12-17 13:18:28 +00:00
Sean Landsman
c338f851e0 Merge branch 'master' into latest 2018-11-09 16:22:29 +00:00
Sean Landsman
58df719d45 Merge branch 'b19.1.2' 2018-11-09 15:31:00 +00:00
Sean Landsman
2b6e3e8f41 Release 19.1.2 dist files added, package.json updated, license key updated 2018-11-09 08:32:07 +00:00
Sean Landsman
f470a4c33d Merge 19.1.1 2018-10-31 16:22:47 +00:00
rmc-software
b51caf4746 Merge branch 'b19.0.0' into Master 2018-10-31 15:42:56 +00:00
rmc-software
30746397ef Updated npm and bower versions for b19.1.1 2018-10-31 13:10:02 +00:00
Sean Landsman
4998a51817 AG-2178 Add docs and example on how to use Context API with React 2018-10-16 17:42:29 +01:00
Sean Landsman
518a95ee89 AG-2177 React Example - allow force refresh (routing breaks) 2018-10-16 16:07:35 +01:00
Sean Landsman
3debbabe28 Allow more flexibility with prop-types, fix trader example 2018-10-16 15:50:21 +01:00
Guilherme Lopes
550f6c4077 updated dependencies and webpack config 2018-10-16 12:09:53 +01:00
Robert Clarke
99bc479b60 Release 19.0.0 dist files created 2018-09-05 13:11:46 +01:00
Sean Landsman
f5c1a4ba17 Update fw examples 2018-09-04 17:07:32 +01:00
Sean Landsman
168a127e51 AG-2018 Rename ag-Grid to ag-Grid-Community 2018-08-21 16:07:22 +01:00
Sean Landsman
f9b1f8527a retiring deprecated themes 2018-08-14 10:23:54 +01:00
MrSafferty
eee938e0e7 AG-1922 Framework Sweep 2018-07-18 16:03:44 +01:00
MrSafferty
449a88e832 AG-1905 Future proof ag-grid-react by removing dependency on unstable_renderSubtreeIntoContainer 2018-07-16 14:49:45 +01:00
Alberto
60181add9a Merge branch 'master' into latest
Merge branch 'master' into latest

# Conflicts:
#	package-lock.json
#	packages/ag-grid-angular/package-lock.json
#	packages/ag-grid-aurelia/package-lock.json
#	packages/ag-grid-docs/package.json
#	packages/ag-grid-enterprise/package.json
#	packages/ag-grid-react/package-lock.json
#	packages/ag-grid-vue/package-lock.json
2018-07-05 11:14:57 +01:00
Alberto
847005c758 Merge branch 'b18.1.0'
# Conflicts:
#	package.json

Merge branch 'b18.1.0'

Merge branch 'b18.1.0'

# Conflicts:
#	package-lock.json
#	package.json
#	vue.config.js
2018-07-05 11:06:51 +01:00
Alberto
ca64dae64c Release 18.1.0 dist files created 2018-07-03 11:21:25 +01:00
MrSafferty
3591b78e4b Set example repos to private 2018-07-02 11:12:58 +01:00
MrSafferty
2fedd32efd Test, Fix and Clean React Examples 2018-06-29 11:11:35 +01:00
MrSafferty
849472a031 Test, Fix and Clean React Examples 2018-06-29 10:58:22 +01:00
Minh Nguyen
a2743f9076 AG-1868 Remove dependency on react-dom-factories in ag-grid-react 2018-06-27 16:01:27 +01:00
MrSafferty
d9724f7ab5 Remove an ignore package-lock.json files 2018-06-20 17:27:35 +01:00
MrSafferty
c0443ba6ef Remove an ignore package-lock.json files 2018-06-20 17:23:06 +01:00
MrSafferty
88752be90b Further monorepo work 2018-06-14 15:42:39 +01:00
MrSafferty
2080ebb054 Bring changes from master over 2018-06-13 16:57:40 +01:00
MrSafferty
172c2a05b0 Add Vue and Aurelia Examples 2018-06-13 12:15:03 +01:00
Alberto
badb5ea485 Merge remote-tracking branch 'origin/b18.0.0'
Merge remote-tracking branch 'origin/b18.0.1'
2018-06-12 16:34:06 +01:00
Alberto
c3af000642 Release 18.0.0 setting new license key 2018-06-11 11:48:53 +01:00
Alberto
7b6b609cdf Release 18.0.0 dist files created 2018-06-11 11:29:34 +01:00
Alberto
5ffb682014 Merge remote-tracking branch 'origin/master' into latest 2018-04-17 10:09:22 +02:00
Alberto
de18262157 Merge remote-tracking branch 'origin/b17.1.0' 2018-04-17 10:05:12 +02:00
Alberto
1f6c1e41a1 Release 17.1.0 dist files created 2018-04-12 15:50:19 +01:00
Alberto
ba3762bbd3 Release 17.1.0 dist files created 2018-04-12 15:48:39 +01:00
Alberto
455f982d6c Merge remote-tracking branch 'origin/master' into latest
Merge remote-tracking branch 'origin/master' into latest

# Conflicts:
#	src/index.php
2018-03-08 12:02:45 +01:00
Alberto
0c927ae3c5 Merge remote-tracking branch 'origin/b17.0.0' 2018-03-08 11:54:52 +01:00
Alberto
2bd8d4c987 Release 17.0.0 dist files created 2018-03-05 12:59:50 +01:00
Alberto
318f78de84 Release 17.0.0 dist files created 2018-03-05 12:57:11 +01:00
Alberto
9ca52a727d Merge branch 'master' into latest 2018-01-29 11:08:55 +00:00
Alberto
56ccdd028c Merge branch 'b16.0.0' 2018-01-29 10:35:22 +00:00
Alberto
a5ccb6d622 Release 16.0.0 dist files created 2018-01-24 11:56:55 +00:00
seanlandsman
25e1f1c184 Merge pull request #34 from ag-grid/latest
AG-1294 Sweep framework examples & update versions Sprint IV
2017-12-18 11:02:15 +00:00
Alberto
8dd0f96b32 Merge branch 'master' into latest
# Conflicts:
#	angular-cli/package.json
#	ngtools_webpack/package.json
#	systemjs_aot/package.json
#	webpack/package.json
#	webpack2/package.json

Merge branch 'master' into latest

Merge branch 'master' into latest

# Conflicts:
#	package.json
2017-12-18 11:15:57 +01:00
Alberto
cf0796eb84 Merge branch 'b15.0.0' 2017-12-18 10:55:49 +01:00
Sean Landsman
a64626e67e AG-1294 Sweep framework examples & update versions Sprint IV 2017-12-15 14:29:20 +00:00
Alberto
95445e558c Release 15.0.0 dist files created 2017-12-11 21:42:59 +00:00
Alberto
79a6206026 Release 15.0.0 creating branch 2017-12-11 21:29:22 +00:00
Sean Landsman
f8ac0e5c98 Pre 15x smoke test - minor tweaks 2017-12-08 12:34:24 +00:00
Alberto
06d9e88e88 Merge master into latest post 14.2.0 2017-11-16 16:26:14 +00:00
Alberto
f860a740f3 Merge branch 'b14.2.0' 2017-11-16 16:02:35 +00:00
Sean Landsman
90ec337474 Release 14.2.0 dist/lib files created 2017-11-15 11:15:38 +00:00
Sean Landsman
05d4341dfc Release 14.2.0 creating branch 2017-11-15 10:53:49 +00:00
Sean Landsman
df77361fd4 AG-1075 Remove legacy master/detail from FW examples 2017-11-13 09:55:06 +00:00
Sean Landsman
983b5974cf AG-1053 Tidy react examples, make more idiomatic 2017-11-08 14:45:28 +00:00
Sean Landsman
b030235bbc AG-530 Implement React declarative offering 2017-11-07 16:32:03 +00:00
Sean Landsman
351d93b8fb AG-530 Implement React declarative offering 2017-11-07 16:22:19 +00:00
Alberto
43af1237bd Merge branch 'master' into latest 2017-11-03 11:23:13 +00:00
Alberto
fc76e85d77 Release 14.0.0 2017-10-31 17:03:55 +00:00
Sean Landsman
6979c51eaf v14 fixes 2017-10-31 12:07:38 +00:00
Sean Landsman
f035ee7a9d v14 changes 2017-10-31 10:16:42 +00:00
Sean Landsman
a982e0f2a7 Revert versions 2017-10-30 15:18:53 +00:00
Sean Landsman
cbb4a31be6 Merge branch 'latest' of /Users/seanlandsman/IdeaProjects/ag/ag-grid/react/ag-grid-react-example with conflicts. 2017-10-05 13:02:49 +01:00
Alberto
d2b92b4c9a Release 13.3.0 2017-10-02 14:55:11 +02:00
Sean Landsman
c8267730bf Update code to match latest changes 2017-09-28 13:56:46 +01:00
156 changed files with 789 additions and 11514 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
/node_modules
/dist
package-lock.json

View File

@@ -1,29 +1,18 @@
ag-Grid React Example
==============
Examples of running ag-Grid inside React application.
See [www.ag-grid.com](http://www.ag-grid.com) for an overview and full documentation.
Frameworks Supported
====================
Framework specific Getting Started guides:
[Angular 1](https://www.ag-grid.com/best-angularjs-data-grid/) | [Angular 2](https://www.ag-grid.com/best-angular-2-data-grid/) | [Aurelia](https://www.ag-grid.com/best-aurelia-data-grid/)
[Javascript](https://www.ag-grid.com/best-javascript-data-grid/) | [React](https://www.ag-grid.com/best-react-data-grid/) | [TypeScript](https://www.ag-grid.com/ag-grid-typescript-webpack-2/)
[VueJS](https://www.ag-grid.com/best-vuejs-data-grid/) | [Web Components](https://www.ag-grid.com/best-web-component-data-grid/)
There are two examples:
## Examples
1. standard - shows a typical grid demonstrating many ag-Grid features
2. large - shows a very large grid (767 columns and 1,000 rows) using React cell renderers
See [www.ag-grid.com](http://www.ag-grid.com) for full documentation and examples.
Building
==============
To build:
- `npm install`
- `npm install webpack -g`
- `npm run examples`, `npm run large` or `npm run trader`
- navigate to localhost:8080

View File

@@ -0,0 +1,51 @@
const path = require('path');
const SRC_DIR = path.resolve(__dirname, '../src-examples');
module.exports = {
mode: 'production',
entry: SRC_DIR + "/index.js",
output: {
path: path.resolve(__dirname, '../'),
filename: "dist/react-examples.js"
},
module: {
rules: [
{
test: /\.css$/,
loader: "style-loader!css-loader"
},
{
test: /\.js$|\.jsx$/,
include: SRC_DIR,
loader: 'babel-loader',
query: {
presets: ['@babel/preset-react', '@babel/preset-env'],
plugins: [
require('@babel/plugin-proposal-function-bind'),
require('@babel/plugin-proposal-class-properties')
]
}
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file-loader?name=[path]/[name].[ext]'
}
]
},
resolve: {
alias: {
"ag-grid-community": path.resolve('./node_modules/ag-grid-community'),
"ag-grid-enterprise": path.resolve('./node_modules/ag-grid-enterprise'),
react: path.resolve('./node_modules/react')
},
extensions: ['.js', '.jsx']
},
performance: {
hints: false
},
devServer: {
port: 8080,
historyApiFallback: true
}
};

View File

@@ -0,0 +1,46 @@
const path = require('path');
const SRC_DIR = path.resolve(__dirname, '../src-large-data');
module.exports = {
mode: 'production',
entry: SRC_DIR + "/index.js",
output: {
path: path.resolve(__dirname, '../'),
filename: "dist/react-large.js"
},
module: {
rules: [
{
test: /\.css$/,
loader: "style-loader!css-loader"
},
{
test: /\.js$|\.jsx$/,
include: SRC_DIR,
loader: 'babel-loader',
query: {
presets: ['@babel/preset-react', '@babel/preset-env'],
plugins: [
require('@babel/plugin-proposal-function-bind'),
require('@babel/plugin-proposal-class-properties')
]
}
}
]
},
resolve: {
alias: {
"ag-grid-community": path.resolve('./node_modules/ag-grid-community'),
"ag-grid-enterprise": path.resolve('./node_modules/ag-grid-enterprise'),
react: path.resolve('./node_modules/react')
},
extensions: ['.js', '.jsx']
},
performance: {
hints: false
},
devServer: {
port: 8080,
}
};

View File

@@ -0,0 +1,46 @@
const path = require('path');
const SRC_DIR = path.resolve(__dirname, '../src-trader-dashboard');
module.exports = {
mode: 'production',
entry: SRC_DIR + "/index.js",
output: {
path: path.resolve(__dirname, '../'),
filename: "dist/react-trader.js"
},
module: {
rules: [
{
test: /\.css$/,
loader: "style-loader!css-loader"
},
{
test: /\.js$|\.jsx$/,
include: SRC_DIR,
loader: 'babel-loader',
query: {
presets: ['@babel/preset-react', '@babel/preset-env'],
plugins: [
require('@babel/plugin-proposal-function-bind'),
require('@babel/plugin-proposal-class-properties')
]
}
}
]
},
resolve: {
alias: {
"ag-grid-community": path.resolve('./node_modules/ag-grid-community'),
"ag-grid-enterprise": path.resolve('./node_modules/ag-grid-enterprise'),
react: path.resolve('./node_modules/react')
},
extensions: ['.js', '.jsx']
},
performance: {
hints: false
},
devServer: {
port: 8080,
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,30 @@
{
"name": "ag-grid-react-example",
"version": "13.2.0",
"version": "21.0.0",
"description": "Example Reach applicaiton using ag-Grid.",
"main": "dist/ag-grid-react-example.js",
"scripts": {
"trader": "webpack-dev-server --content-base src-trader-dashboard/ --config webpack.config.trader.js --progress --colors --hot --inline",
"examples": "webpack-dev-server --content-base src/ --config webpack.config.examples.js --progress --colors --hot --inline",
"large": "webpack-dev-server --config webpack.config.large.js --progress --colors --hot --inline",
"trader": "webpack-dev-server --content-base src-trader-dashboard/ --config config/webpack.config.trader.js --mode development --open",
"examples": "webpack-dev-server --content-base src-examples/ --config config/webpack.config.examples.js --mode development --open",
"large": "webpack-dev-server --content-base src-large-data/ --config config/webpack.config.large.js --mode development --open",
"clean": "rimraf dist",
"mkdirs": "mkdirp dist/trader/dist dist/examples/dist",
"copy-examples": "ncp images dist/examples/images && ncp src/index.html dist/examples/index.html && ncp dist/react-examples.js dist/examples/dist/react-examples.js && ncp src dist/examples/src",
"copy-examples": "ncp src-examples/images dist/examples/images && ncp src-examples/index.html dist/examples/index.html && ncp dist/react-examples.js dist/examples/dist/react-examples.js && ncp src-examples/ dist/examples/src",
"copy-trader": "ncp src-trader-dashboard/index.html dist/trader/index.html && ncp dist/react-trader.js dist/trader/dist/react-trader.js",
"copy": "npm run copy-examples && npm run copy-trader",
"build-large": "webpack --config webpack.config.large.js --progress --profile --bail",
"build-examples": "webpack --config webpack.config.examples.js --progress --profile --bail",
"build-dashboard": "webpack --config webpack.config.trader.js --progress --profile --bail",
"build-large": "webpack --config config/webpack.config.large.js --progress --profile --bail",
"build-examples": "webpack --config config/webpack.config.examples.js --progress --profile --bail",
"build-dashboard": "webpack --config config/webpack.config.trader.js --progress --profile --bail",
"build-all": "npm run build-examples && npm run build-dashboard",
"build": "npm run clean && npm run mkdirs && npm run build-all && npm run copy",
"copy-to-docs": "ncp dist/examples ../ag-grid-docs/src/framework-examples/react-examples/examples && ncp dist/trader ../ag-grid-docs/src/framework-examples/react-examples/trader",
"build-to-docs": "npm run build && npm run copy-to-docs",
"start": "npm run examples"
"start": "npm run examples",
"test": "./ts-tests/runTsTests.sh"
},
"repository": {
"type": "git",
"url": "https://github.com/ag-grid/ag-grid-react-example.git"
},
"private": true,
"keywords": [
"react",
"grid",
@@ -38,39 +38,39 @@
},
"homepage": "http://www.ag-grid.com/",
"devDependencies": {
"babel-core": "6.24.x",
"babel-loader": "6.4.x",
"babel-preset-es2015": "6.24.x",
"babel-preset-react": "6.24.x",
"babel-preset-stage-0": "6.24.x",
"babel-preset-stage-1": "6.24.x",
"css-loader": "0.23.x",
"@babel/core": "7.4.4",
"@babel/plugin-proposal-class-properties": "7.4.4",
"@babel/plugin-proposal-function-bind": "7.2.0",
"@babel/preset-env": "7.4.4",
"@babel/preset-react": "7.0.0",
"@types/react": "16.8.17",
"@types/react-dom": "16.8.4",
"babel-loader": "8.0.6",
"css-loader": "2.1.1",
"file-loader": "3.0.1",
"gulp": "3.9.1",
"merge2": "1.2.3",
"mkdirp": "0.5.1",
"ncp": "2.0.0",
"prop-types": "15.5.x",
"rimraf": "2.5.x",
"style-loader": "0.13.x",
"webpack": "1.12.x",
"webpack-dev-server": "1.14.x",
"gulp": "3.9.x",
"gulp-typescript": "3.1.x",
"merge2": "1.0.x",
"typescript": "2.3.x"
"prop-types": "15.7.2",
"rimraf": "2.6.3",
"style-loader": "0.23.1",
"typescript": "3.4.5",
"webpack": "4.31.0",
"webpack-cli": "3.3.2",
"webpack-dev-server": "3.4.1"
},
"dependencies": {
"ag-grid": "13.2.x",
"ag-grid-enterprise": "13.2.x",
"ag-grid-react": "13.2.x",
"bootstrap": "3.3.7",
"ag-grid-community": "^21.0.0",
"ag-grid-enterprise": "^21.0.0",
"ag-grid-react": "^21.0.0",
"bootstrap": "4.3.1",
"d3": "4.9.1",
"file-loader": "0.11.1",
"lodash": "4.17.4",
"react": "15.6.x",
"react-dom": "15.6.x",
"react-dom-factories": "1.0.0",
"react-redux": "5.0.x",
"react-router-dom": "4.2.x",
"redux": "3.6.x",
"url-search-params-polyfill": "1.2.0"
"lodash": "4.17.11",
"react": "16.8.6",
"react-dom": "16.8.6",
"react-redux": "7.0.3",
"react-router-dom": "5.0.0",
"redux": "4.0.1"
}
}

38
src-examples/App.jsx Normal file
View File

@@ -0,0 +1,38 @@
import React, {Component} from "react";
import {Redirect, Route, Switch} from "react-router-dom";
import NavItem from "./NavItem";
import RichGridDeclarativeExample from "./richGridDeclarativeExample/RichGridDeclarativeExample";
import SimpleReduxDynamicExample from "./simpleReduxDynamicComponentExample/SimpleReduxExample";
import SimpleReduxHookExample from "./simpleReduxHooksExample/SimpleReduxHookExample";
const SideBar = () => (
<div style={{float: "left", width: 335, marginRight: 25}}>
<ul className="nav nav-pills">
<NavItem to='/rich-grid-declarative'>Rich Grid with Declarative Markup</NavItem>
<NavItem to='/simple-redux-dynamic'>Simple Redux Dynamic Component Example</NavItem>
<NavItem to='/simple-redux-hook'>Simple React Hook Component Example</NavItem>
</ul>
</div>
);
class App extends Component {
render() {
return (
<div style={{display: "inline-block", width: "100%"}}>
<SideBar/>
<div style={{float: "left"}}>
<Switch>
<Redirect from="/" exact to="/rich-grid-declarative"/>
<Route exact path='/rich-grid-declarative' component={RichGridDeclarativeExample}/>
<Route exact path='/simple-redux-dynamic' component={SimpleReduxDynamicExample}/>
<Route exact path='/simple-redux-hook' component={SimpleReduxHookExample}/>
</Switch>
</div>
</div>
)
}
}
export default App

View File

@@ -1,12 +1,13 @@
import React, {PropTypes} from 'react'
import {Route, Link} from 'react-router-dom'
import React from 'react'
import * as PropTypes from 'prop-types';
import {Link, Route} from 'react-router-dom'
// for bootstrap li active functionality
export default function NavItem({children, to, exact}) {
return (
<Route path={to} exact={exact} children={({match}) => (
<li className={match ? 'active' : null}>
<Link to={to}>{children}</Link>
<li className="nav-item">
<Link className={match ? 'nav-link active' : 'nav-link'} to={to}>{children}</Link>
</li>
)}/>
)

View File

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 606 B

After

Width:  |  Height:  |  Size: 606 B

View File

Before

Width:  |  Height:  |  Size: 128 B

After

Width:  |  Height:  |  Size: 128 B

View File

Before

Width:  |  Height:  |  Size: 256 B

After

Width:  |  Height:  |  Size: 256 B

View File

Before

Width:  |  Height:  |  Size: 99 B

After

Width:  |  Height:  |  Size: 99 B

View File

Before

Width:  |  Height:  |  Size: 99 B

After

Width:  |  Height:  |  Size: 99 B

View File

Before

Width:  |  Height:  |  Size: 174 B

After

Width:  |  Height:  |  Size: 174 B

View File

Before

Width:  |  Height:  |  Size: 94 B

After

Width:  |  Height:  |  Size: 94 B

View File

Before

Width:  |  Height:  |  Size: 289 B

After

Width:  |  Height:  |  Size: 289 B

View File

Before

Width:  |  Height:  |  Size: 228 B

After

Width:  |  Height:  |  Size: 228 B

View File

Before

Width:  |  Height:  |  Size: 119 B

After

Width:  |  Height:  |  Size: 119 B

View File

Before

Width:  |  Height:  |  Size: 154 B

After

Width:  |  Height:  |  Size: 154 B

View File

Before

Width:  |  Height:  |  Size: 94 B

After

Width:  |  Height:  |  Size: 94 B

View File

Before

Width:  |  Height:  |  Size: 136 B

After

Width:  |  Height:  |  Size: 136 B

View File

Before

Width:  |  Height:  |  Size: 154 B

After

Width:  |  Height:  |  Size: 154 B

View File

Before

Width:  |  Height:  |  Size: 89 B

After

Width:  |  Height:  |  Size: 89 B

View File

Before

Width:  |  Height:  |  Size: 227 B

After

Width:  |  Height:  |  Size: 227 B

View File

Before

Width:  |  Height:  |  Size: 97 B

After

Width:  |  Height:  |  Size: 97 B

View File

Before

Width:  |  Height:  |  Size: 222 B

After

Width:  |  Height:  |  Size: 222 B

View File

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

View File

Before

Width:  |  Height:  |  Size: 739 B

After

Width:  |  Height:  |  Size: 739 B

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View File

Before

Width:  |  Height:  |  Size: 883 B

After

Width:  |  Height:  |  Size: 883 B

View File

Before

Width:  |  Height:  |  Size: 902 B

After

Width:  |  Height:  |  Size: 902 B

View File

Before

Width:  |  Height:  |  Size: 953 B

After

Width:  |  Height:  |  Size: 953 B

View File

Before

Width:  |  Height:  |  Size: 394 B

After

Width:  |  Height:  |  Size: 394 B

View File

Before

Width:  |  Height:  |  Size: 893 B

After

Width:  |  Height:  |  Size: 893 B

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

View File

Before

Width:  |  Height:  |  Size: 570 B

After

Width:  |  Height:  |  Size: 570 B

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<script type="text/javascript" src="dist/react-examples.js" charset="utf-8"></script>
<script type="text/javascript" src="../dist/react-examples.js" charset="utf-8"></script>
<!-- Example uses font awesome icons -->
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
@@ -16,6 +16,10 @@
line-height: 1
}
h1 {
font-size: 1.5rem;
}
div.card-body > a {
margin-top: 5px
}

View File

@@ -4,8 +4,8 @@ import React from "react";
import {render} from "react-dom";
import {BrowserRouter} from "react-router-dom";
import "ag-grid-root/dist/styles/ag-grid.css";
import "ag-grid-root/dist/styles/theme-fresh.css";
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-balham.css";
import "../node_modules/bootstrap/dist/css/bootstrap.css";
import App from "./App";

View File

@@ -37,7 +37,7 @@ export default class DateComponent extends React.Component {
width: '30px'
};
let yyyyStyle = {
width: '60px'
width: '40px'
};
let resetStyle = {
padding: '2px',
@@ -51,11 +51,11 @@ export default class DateComponent extends React.Component {
return (
<div style={filterStyle}>
<span style={resetStyle} onClick={this.resetDate.bind(this)}>x</span>
<input onInput={this.onDateChanged.bind(this)} ref="dd" placeholder="dd" style={ddStyle}
<input onChange={this.onDateChanged.bind(this)} ref="dd" placeholder="dd" style={ddStyle}
value={this.state.textBoxes.dd} maxLength="2"/>/
<input onInput={this.onDateChanged.bind(this)} ref="mm" placeholder="mm" style={mmStyle}
<input onChange={this.onDateChanged.bind(this)} ref="mm" placeholder="mm" style={mmStyle}
value={this.state.textBoxes.mm} maxLength="2"/>/
<input onInput={this.onDateChanged.bind(this)} ref="yyyy" placeholder="yyyy" style={yyyyStyle}
<input onChange={this.onDateChanged.bind(this)} ref="yyyy" placeholder="yyyy" style={yyyyStyle}
value={this.state.textBoxes.yyyy} maxLength="4"/>
</div>
);

View File

@@ -41,16 +41,20 @@ export default class ProficiencyFilter extends React.Component {
this.setState(newState, this.props.filterChangedCallback);
}
getModel() {
return ''
}
setModel(model) {
}
render() {
const rows = [];
PROFICIENCY_NAMES.forEach((name) => {
const selected = this.state.selected === name;
rows.push(
<div key={name}>
<div key={name} style={{marginTop: 3}}>
<label style={{paddingLeft: 4}}>
<input type="radio" checked={selected} name={Math.random()}
onChange={this.onButtonPressed.bind(this, name)}/>

View File

@@ -0,0 +1,252 @@
import React, {Component} from "react";
import {AgGridColumn, AgGridReact} from "ag-grid-react";
import RowDataFactory from "./RowDataFactory";
import DateComponent from "./DateComponent.jsx";
import SkillsCellRenderer from './SkillsCellRenderer.jsx';
import NameCellEditor from './NameCellEditor.jsx';
import ProficiencyCellRenderer from './ProficiencyCellRenderer.jsx';
import RefData from './RefData';
import SkillsFilter from './SkillsFilter.jsx';
import ProficiencyFilter from './ProficiencyFilter.jsx';
import HeaderGroupComponent from './HeaderGroupComponent.jsx';
import SortableHeaderComponent from './SortableHeaderComponent.jsx';
import "./RichGridDeclarativeExample.css";
// take this line out if you do not want to use ag-Grid-Enterprise
import "ag-grid-enterprise";
export default class RichGridDeclarativeExample extends Component {
constructor(props) {
super(props);
this.state = {
quickFilterText: null,
sideBar: false,
rowData: new RowDataFactory().createRowData(),
rowCount: null,
icons: {
columnRemoveFromGroup: '<i class="fa fa-remove"/>',
filter: '<i class="fa fa-filter"/>',
sortAscending: '<i class="fa fa-long-arrow-down"/>',
sortDescending: '<i class="fa fa-long-arrow-up"/>',
groupExpanded: '<i class="fa fa-minus-square-o"/>',
groupContracted: '<i class="fa fa-plus-square-o"/>'
}
};
}
/* Grid Events we're listening to */
onGridReady = (params) => {
this.api = params.api;
this.columnApi = params.columnApi;
this.calculateRowCount();
};
onCellClicked = (event) => {
console.log('onCellClicked: ' + event.data.name + ', col ' + event.colIndex);
};
onRowSelected = (event) => {
console.log('onRowSelected: ' + event.node.data.name);
};
/* Demo related methods */
onToggleSidebar = (event) => {
this.setState({sideBar: event.target.checked});
};
deselectAll() {
this.api.deselectAll();
}
onQuickFilterText = (event) => {
this.setState({quickFilterText: event.target.value});
};
onRefreshData = () => {
this.setState({
rowData: new RowDataFactory().createRowData()
});
};
invokeSkillsFilterMethod = () => {
let skillsFilter = this.api.getFilterInstance('skills');
let componentInstance = skillsFilter.getFrameworkComponentInstance();
componentInstance.helloFromSkillsFilter();
};
dobFilter = () => {
let dateFilterComponent = this.api.getFilterInstance('dob');
dateFilterComponent.setModel({
type: 'equals',
dateFrom: '2000-01-01'
});
// 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.api.onFilterChanged();
});
};
calculateRowCount = () => {
if (this.api && this.state.rowData) {
const model = this.api.getModel();
const totalRows = this.state.rowData.length;
const processedRows = model.getRowCount();
this.setState({
rowCount: processedRows.toLocaleString() + ' / ' + totalRows.toLocaleString()
});
}
};
static countryCellRenderer(params) {
if (params.value) {
return `<img border='0' width='15' height='10' style='margin-bottom: 2px' src='http://flags.fmcdn.net/data/flags/mini/${RefData.COUNTRY_CODES[params.value]}.png'> ${params.value}`;
} else {
return null;
}
}
static dateCellRenderer(params) {
return RichGridDeclarativeExample.pad(params.value.getDate(), 2) + '/' +
RichGridDeclarativeExample.pad(params.value.getMonth() + 1, 2) + '/' +
params.value.getFullYear();
}
static pad(num, totalStringSize) {
let asString = num + "";
while (asString.length < totalStringSize) asString = "0" + asString;
return asString;
}
render() {
return (
<div style={{width: '900px'}}>
<h1>Rich Grid with Declarative Markup Example</h1>
<div style={{display: "inline-block", width: "100%"}}>
<div style={{float: "left"}}>
<b>Employees Skills and Contact Details: </b>{ this.state.rowCount }
</div>
</div>
<div style={{marginTop: 10}}>
<div>
<span>
Grid API:
<button onClick={() => {
this.api.selectAll()
}} className="btn btn-primary">Select All</button>
<button onClick={() => {
this.api.deselectAll()
}} className="btn btn-primary">Clear Selection</button>
</span>
<span style={{float: "right"}}>
Column API:
<button onClick={() => {
this.columnApi.setColumnVisible('country', false)
}} className="btn btn-primary">Hide Country Column</button>
<button onClick={() => {
this.columnApi.setColumnVisible('country', true)
}} className="btn btn-primary">Show Country Column</button>
</span>
</div>
<div style={{display: "inline-block", width: "100%", marginTop: 10, marginBottom: 10}}>
<div style={{float: "left"}}>
<button onClick={this.onRefreshData} className="btn btn-primary">Refresh Data</button>
</div>
<div style={{float: "right"}}>
Filter API:
<button onClick={this.invokeSkillsFilterMethod}
className="btn btn-primary">Invoke Skills Filter Method
</button>
<button onClick={this.dobFilter} className="btn btn-primary">DOB equals to 01/01/2000
</button>
</div>
</div>
<div style={{display: "inline-block", width: "100%", marginTop: 10, marginBottom: 10}}>
<div style={{float: "left"}}>
<label htmlFor="sideBarToggle">Show Side Bar&nbsp;</label>
<input type="checkbox" id="sideBarToggle" onChange={this.onToggleSidebar} style={{marginRight: 5}}/>
</div>
<div style={{float: "right", marginLeft: 20}}>
<label htmlFor="quickFilter">Quick Filter:&nbsp;</label>
<input type="text" id="quickFilter" onChange={this.onQuickFilterText} placeholder="Type text to filter..."/>
</div>
</div>
<div style={{height: 400, width: 900}} className="ag-theme-balham">
<AgGridReact
// listening for events
onGridReady={this.onGridReady}
onRowSelected={this.onRowSelected}
onCellClicked={this.onCellClicked}
onModelUpdated={this.calculateRowCount}
// binding to simple properties
sideBar={this.state.sideBar}
quickFilterText={this.state.quickFilterText}
// binding to an object property
icons={this.state.icons}
// binding to array properties
rowData={this.state.rowData}
// no binding, just providing hard coded strings for the properties
// boolean properties will default to true if provided (ie suppressRowClickSelection => suppressRowClickSelection="true")
suppressRowClickSelection
rowSelection="multiple"
groupHeaders
// setting grid wide date component
dateComponentFramework={DateComponent}
// setting default column properties
defaultColDef={{
resizable: true,
sortable: true,
filter: true,
headerComponentFramework: SortableHeaderComponent,
headerComponentParams: {
menuIcon: 'fa-bars'
}
}}>
<AgGridColumn headerName="#" width={30}
checkboxSelection sortable={false} suppressMenu filter={false} pinned>
</AgGridColumn>
<AgGridColumn headerName="Employee" headerGroupComponentFramework={HeaderGroupComponent}>
<AgGridColumn field="name" width={150}
cellEditorFramework={NameCellEditor}
enableRowGroup enablePivot pinned editable/>
<AgGridColumn field="country" width={150}
cellRenderer={RichGridDeclarativeExample.countryCellRenderer}
filterParams={{
cellRenderer: RichGridDeclarativeExample.countryCellRenderer,
cellHeight: 20
}}
enableRowGroup enablePivot pinned editable/>
<AgGridColumn field="dob" width={175} headerName="DOB" filter="agDateColumnFilter"
pinned columnGroupShow="open"
cellRenderer={RichGridDeclarativeExample.dateCellRenderer}/>
</AgGridColumn>
<AgGridColumn headerName="IT Skills">
<AgGridColumn field="skills" width={120} enableRowGroup enablePivot sortable={false}
cellRendererFramework={SkillsCellRenderer}
filterFramework={SkillsFilter}/>
<AgGridColumn field="proficiency" width={160} enableValue
cellRendererFramework={ProficiencyCellRenderer}
filterFramework={ProficiencyFilter}/>
</AgGridColumn>
<AgGridColumn headerName="Contact">
<AgGridColumn field="mobile" width={150} filter="text"/>
<AgGridColumn field="landline" width={150} filter="text"/>
<AgGridColumn field="address" width={500} filter="text"/>
</AgGridColumn>
</AgGridReact>
</div>
</div>
</div>
);
}
}

View File

@@ -56,7 +56,7 @@ export default class SkillsFilter extends React.Component {
return passed;
};
getModel() {
getModelAsString() {
return ''
}
@@ -83,7 +83,6 @@ export default class SkillsFilter extends React.Component {
const skillsTemplates = [];
RefData.IT_SKILLS.forEach((skill, index) => {
const skillName = RefData.IT_SKILLS_NAMES[index];
const template = (
<label key={skill}

View File

@@ -1,7 +1,7 @@
import React, {Component} from "react";
import {connect} from "react-redux";
import {AgGridReact} from "ag-grid-react";
import {connect} from "react-redux";
import PriceRenderer from "./PriceRenderer";
@@ -14,8 +14,14 @@ class GridComponent extends Component {
this.state = {
columnDefs: [
{headerName: 'Symbol', field: 'symbol'},
{headerName: 'Price', field: 'price', cellClass: 'align-right', cellRendererFramework: PriceRenderer}
{
field: 'symbol'
},
{
field: 'price',
cellClass: 'align-right',
cellRendererFramework: PriceRenderer
}
]
};
@@ -33,12 +39,14 @@ class GridComponent extends Component {
render() {
return (
<div style={{height: 400, width: 900, marginTop: 15}}
className="ag-fresh">
className="ag-theme-balham">
<AgGridReact
// properties
columnDefs={this.state.columnDefs}
rowData={this.props.rowData}
reactNext={true}
// events
onGridReady={this.onGridReady}>
</AgGridReact>

View File

@@ -25,8 +25,8 @@ class HeaderComponent extends Component {
render() {
return (
<div style={{marginTop: 15}}>
<button onClick={this.setCurrency.bind(this, '£', 1)}>Set Currency to GBP</button>
<button onClick={this.setCurrency.bind(this, '$', 1.29)}>Set Currency to USD</button>
<button onClick={this.setCurrency.bind(this, '£', 1)} className="btn btn-primary">Set Currency to GBP</button>
<button onClick={this.setCurrency.bind(this, '$', 1.29)} className="btn btn-primary">Set Currency to USD</button>
</div>
)
}
@@ -82,4 +82,4 @@ export default connect(
rowData: state.rowData
}
}
)(HeaderComponent);
)(HeaderComponent);

View File

@@ -1,6 +1,8 @@
import React, {Component} from "react";
import {connect} from "react-redux";
import FontContext from './fontContext'
class PriceRenderer extends Component {
constructor(props) {
super(props);
@@ -18,7 +20,10 @@ class PriceRenderer extends Component {
render() {
return (
<span>{this.props.currencySymbol}{this.state.convertedValue}</span>
<FontContext.Consumer>
{fontWeight => <span
style={{fontWeight}}> {this.props.currencySymbol}{this.state.convertedValue}</span>}
</FontContext.Consumer>
);
}
@@ -33,5 +38,8 @@ export default connect(
currencySymbol: state.currencySymbol,
exchangeRate: state.exchangeRate
}
}
},
null,
null,
{forwardRef: true} // must be supplied for react/redux when using GridOptions.reactNext
)(PriceRenderer);

View File

@@ -9,6 +9,8 @@ import GridComponent from "./GridComponent";
import gridData from "./gridDataReducer";
import FontContext from './fontContext'
let store = createStore(gridData);
/*
@@ -25,8 +27,10 @@ export default class SimpleReduxExample extends Component {
<Provider store={store}>
<div>
<h1>Simple Redux Example using Connected React Components</h1>
<HeaderComponent />
<GridComponent />
<HeaderComponent/>
<FontContext.Provider value="bold">
<GridComponent/>
</FontContext.Provider>
</div>
</Provider>
)

View File

@@ -0,0 +1,3 @@
import React from "react";
export default React.createContext('normal');

View File

@@ -4,6 +4,7 @@ export function updateRowData(rowData) {
rowData
}
}
export function setCurrency(currencySymbol, exchangeRate) {
return {
type: 'CURRENCY_CHANGED',

View File

@@ -0,0 +1,32 @@
import React, { useContext } from "react";
import {Context} from "./store";
import {AgGridReact} from "ag-grid-react";
/*
* This component serves to display the row data (provided by redux)
*/
export default function GridComponent() {
const {store, dispatch} = useContext(Context);
const {columnDefs, rowData} = store;
const onGridReady = (params) => {
params.api.sizeColumnsToFit();
};
// row data will be provided via redux on this.props.rowData
return (
<div style={{height: 400, width: 900, marginTop: 15}}
className="ag-theme-balham">
<AgGridReact
// properties
columnDefs={columnDefs}
rowData={rowData}
reactNext={true}
// events
onGridReady={onGridReady}>
</AgGridReact>
</div>
)
}

View File

@@ -1,13 +1,13 @@
import React, {Component} from "react";
export default class CurrencyRenderer extends Component {
export default class PriceRenderer extends Component {
constructor(props) {
super(props);
}
render() {
return (
<span style={this.props.style}>{this.props.value}</span>
<span>{this.props.value}</span>
);
}
};
}

View File

@@ -0,0 +1,18 @@
import React, {useReducer} from "react";
import GridComponent from "./GridComponent";
import {Context, initialState, reducer} from "./store";
export default function SimpleReduxHookExample() {
const [store, dispatch] = useReducer(reducer, initialState);
return (
<Context.Provider value={{store, dispatch}}>
<div>
<h1>Simple Example using Hooks (with useContext and useReducer)</h1>
<button onClick={() => dispatch({type: "SET_ROW_DATA"})} className="btn btn-primary">Populate Row Data</button>
<GridComponent/>
</div>
</Context.Provider>
)
}

View File

@@ -0,0 +1,14 @@
export function updateRowData(rowData) {
return {
type: 'ROW_DATA_CHANGED',
rowData
}
}
export function setCurrency(currencySymbol, exchangeRate) {
return {
type: 'CURRENCY_CHANGED',
currencySymbol,
exchangeRate
}
}

View File

@@ -0,0 +1,75 @@
import React from "react";
import PriceRenderer from "./PriceRenderer";
export const initialState = {
rowData: [],
columnDefs: [
{
field: 'symbol'
},
{
field: 'price',
cellClass: 'align-right',
cellRendererFramework: PriceRenderer
}
]
};
export const reducer = (state = {rowData: []}, action) => {
switch (action.type) {
case 'SET_ROW_DATA':
return {
...state,
rowData: createRowData()
};
default:
return state;
}
};
export const Context = React.createContext();
// for test data
// the following methods are for creating dummy row data
const createRowData = () => {
let rowData = [];
for (let i = 0; i < 14; i++) {
let newItem = createItem(rowData);
rowData.push(newItem);
}
return rowData;
};
const createItem = (rowData) => {
return {
symbol: createUniqueRandomSymbol(rowData),
price: Math.floor(Math.random() * 100)
};
};
// creates a unique symbol, eg 'ADG' or 'ZJD'
const createUniqueRandomSymbol = (rowData) => {
let symbol;
let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let isUnique = false;
while (!isUnique) {
symbol = '';
// create symbol
for (let i = 0; i < 3; i++) {
symbol += possible.charAt(Math.floor(Math.random() * possible.length));
}
// check uniqueness
isUnique = true;
rowData.forEach(function (oldItem) {
if (oldItem.symbol === symbol) {
isUnique = false;
}
});
}
return symbol;
};

View File

@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8">
<script type="text/javascript" src="dist/bundle.js" charset="utf-8"></script>
<script type="text/javascript" src="../dist/react-large.js" charset="utf-8"></script>
<!-- Example uses font awesome icons -->
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
</head>

View File

@@ -3,9 +3,9 @@
import ReactDOM from 'react-dom';
import React from 'react';
import LargeGrid from './largeGrid.jsx';
// is there a better way of doing this?
import 'ag-grid-root/dist/styles/ag-grid.css';
import 'ag-grid-root/dist/styles/theme-fresh.css';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-fresh.css';
// waiting for dom to load before booting react. we could alternatively
// put the index.js reference at the end fo the index.html, but i prefer this way.

View File

@@ -1,5 +1,4 @@
import React from 'react';
import {reactCellRendererFactory} from 'ag-grid-react';
import React, {Component} from 'react';
import SimpleCellRenderer from './simpleCellRenderer.jsx';
import {AgGridReact} from 'ag-grid-react';
@@ -7,7 +6,7 @@ import {AgGridReact} from 'ag-grid-react';
// put this line in to use ag-Grid enterprise
// import 'ag-grid-enterprise';
export default class MyApp extends React.Component {
export default class MyApp extends Component {
constructor() {
super();
@@ -22,22 +21,22 @@ export default class MyApp extends React.Component {
createColumnNames() {
// creates column names by iterating the alphabet twice, eg {'aa','ab','ac',.....'zz'}
var alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
this.columnNames = [];
alphabet.forEach( letter1 => {
alphabet.forEach( letter2 => {
alphabet.forEach(letter1 => {
alphabet.forEach(letter2 => {
this.columnNames.push(letter1 + letter2);
});
});
}
createRowData() {
var rowData = [];
const rowData = [];
for (var i = 0; i<1000; i++) {
var item = {};
this.columnNames.forEach( colName => {
item[colName] = '('+colName.toUpperCase()+','+i+')'
for (let i = 0; i < 1000; i++) {
const item = {};
this.columnNames.forEach(colName => {
item[colName] = '(' + colName.toUpperCase() + ',' + i + ')'
});
rowData.push(item);
}
@@ -46,9 +45,9 @@ export default class MyApp extends React.Component {
}
createColumnDefs() {
var columnDefs = [];
const columnDefs = [];
this.columnNames.forEach( colName => {
this.columnNames.forEach(colName => {
columnDefs.push({
headerName: colName.toUpperCase(),
field: colName,
@@ -62,8 +61,8 @@ export default class MyApp extends React.Component {
render() {
return (
<div style={{height: '100%'}} className="ag-fresh">
<AgGridReact columnDefs={this.state.columnDefs} rowData={this.state.rowData} />
<div style={{height: '100%'}} className="ag-theme-fresh">
<AgGridReact columnDefs={this.state.columnDefs} rowData={this.state.rowData}/>
</div>
);
}

View File

@@ -3,9 +3,6 @@ import {connect} from "react-redux";
import {AgGridReact} from "ag-grid-react";
import assign from "lodash/assign";
import uniq from "lodash/uniq";
class FxQuoteMatrix extends Component {
constructor(props) {
super(props);
@@ -35,37 +32,41 @@ class FxQuoteMatrix extends Component {
}
componentWillReceiveProps(nextProps) {
const newRowData = nextProps.rowData;
if (this.gridApi) {
const newRowData = nextProps.rowData;
const updatedRows = [];
const updatedRows = [];
for (let i = 0; i < newRowData.length; i++) {
let newRow = newRowData[i];
let currentRowNode = this.gridApi.getRowNode(newRow.symbol);
for (let i = 0; i < newRowData.length; i++) {
let newRow = newRowData[i];
let currentRowNode = this.gridApi.getRowNode(newRow.symbol);
const {data} = currentRowNode;
for (const def of this.state.columnDefs) {
if (data[def.field] !== newRow[def.field]) {
updatedRows.push(newRow);
break;
const {data} = currentRowNode;
for (const def of this.state.columnDefs) {
if (data[def.field] !== newRow[def.field]) {
updatedRows.push(newRow);
break;
}
}
}
this.gridApi.updateRowData({update: updatedRows});
}
this.gridApi.updateRowData({update: updatedRows});
}
render() {
return (
<div style={{height: 410, width: 800}}
className="ag-fresh">
className="ag-theme-fresh">
<AgGridReact
// properties
columnDefs={this.state.columnDefs}
enableSorting="false"
enableFilter="false"
defaultColDef={{
sortable: false,
filter: false
}}
// callbacks
getRowNodeId={this.getRowNodeId}
@@ -81,7 +82,7 @@ class FxQuoteMatrix extends Component {
export default connect(
(state) => {
return {
rowData: state.fxData
rowData: state ? state.fxData : null
}
}
)(FxQuoteMatrix);

View File

@@ -24,21 +24,21 @@ export default class extends Component {
field: 'price',
headerName: 'Price',
valueFormatter: this.numberFormatter,
cellRenderer: 'animateShowChange',
cellRenderer: 'agAnimateShowChangeCellRenderer',
cellStyle: {'text-align': 'right'}
},
{
field: 'bid',
headerName: 'Bid',
valueFormatter: this.numberFormatter,
cellRenderer: 'animateShowChange',
cellRenderer: 'agAnimateShowChangeCellRenderer',
cellStyle: {'text-align': 'right'}
},
{
field: 'ask',
headerName: 'Ask',
valueFormatter: this.numberFormatter,
cellRenderer: 'animateShowChange',
cellRenderer: 'agAnimateShowChangeCellRenderer',
cellStyle: {'text-align': 'right'}
}
]
@@ -151,11 +151,13 @@ export default class extends Component {
render() {
return (
<div style={{height: 410, width: 800}}
className="ag-fresh">
className="ag-theme-fresh">
<AgGridReact
// properties
columnDefs={this.state.columnDefs}
enableSorting="true"
defaultColDef={{
sortable: true
}}
rowSelection="single"
// callbacks

View File

@@ -17,24 +17,24 @@ class TopMoversGrid extends Component {
field: 'last',
headerName: 'Last',
headerClass: 'align-right',
cellRenderer: 'animateShowChange',
cellRenderer: 'agAnimateShowChangeCellRenderer',
cellClass: 'align-right'
},
{
field: 'net',
headerName: 'Net',
headerClass: 'align-right',
cellRenderer: 'animateShowChange',
cellRenderer: 'agAnimateShowChangeCellRenderer',
cellClass: 'align-right'
},
{
field: 'pct_net_change',
headerName: '% NC',
headerClass: 'align-right',
cellRenderer: 'animateShowChange',
cellRenderer: 'agAnimateShowChangeCellRenderer',
cellClass: 'align-right',
sort: 'desc',
cellFormatter(params) {
valueFormatter(params) {
return params.value.toFixed(2)
}
},
@@ -62,13 +62,15 @@ class TopMoversGrid extends Component {
render() {
return (
<div style={{height: 410, width: 400}}
className="ag-fresh">
className="ag-theme-fresh">
<AgGridReact
// properties
columnDefs={this.state.columnDefs}
rowData={this.props.rowData}
enableSorting
enableFilter="false"
defaultColDef={{
sortable: true,
filter: false
}}
animateRows
deltaRowDataMode
getRowNodeId={this.getRowNodeId}
@@ -84,7 +86,7 @@ class TopMoversGrid extends Component {
export default connect(
(state) => {
return {
rowData: state.fxTopMovers
rowData: state ? state.fxTopMovers : null
}
}
)(TopMoversGrid);
)(TopMoversGrid);

View File

@@ -3,6 +3,14 @@ import * as PropTypes from 'prop-types';
export default class HorizontalBarComponent extends Component {
constructor(props) {
super(props);
this.state = {
value: this.props.value
}
}
render() {
let positiveChange = {
fill: "green"
@@ -19,7 +27,7 @@ export default class HorizontalBarComponent extends Component {
textAlign: "right"
};
let pctNetChange = this.props.value;
let pctNetChange = this.state.value;
let pctNetChangeBar = Math.min(Math.abs(pctNetChange) * 100, 100) / 2;
let barWidth = `${pctNetChangeBar}%`;
@@ -36,6 +44,13 @@ export default class HorizontalBarComponent extends Component {
</div>
)
}
refresh(params) {
this.setState({
value: params.value
});
return true;
}
}
HorizontalBarComponent.propTypes = {

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<script type="text/javascript" src="dist/react-trader.js" charset="utf-8"></script>
<script type="text/javascript" src="../dist/react-trader.js" charset="utf-8"></script>
<style>
html, body {

View File

@@ -5,8 +5,8 @@ import {render} from "react-dom";
import {Provider} from "react-redux";
import "ag-grid-root/dist/styles/ag-grid.css";
import "ag-grid-root/dist/styles/theme-fresh.css";
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-fresh.css";
import StoreService from './services/StoreService';
import TraderDashboard from "./components/TraderDashboard.jsx";

View File

@@ -120,7 +120,7 @@ const FX_DELTA_HEADERS = [
field: 'last',
headerName: 'Last',
headerClass: 'align-right',
cellRenderer: 'animateShowChange',
cellRenderer: 'agAnimateShowChangeCellRenderer',
cellClass: 'align-right',
width: 100
},
@@ -128,7 +128,7 @@ const FX_DELTA_HEADERS = [
field: 'net',
headerName: 'Net',
headerClass: 'align-right',
cellRenderer: 'animateShowChange',
cellRenderer: 'agAnimateShowChangeCellRenderer',
cellClass: 'align-right',
width: 90
},
@@ -145,7 +145,7 @@ const FX_DELTA_HEADERS = [
headerName: symbol,
width: 67,
cellClass: 'align-right',
cellRenderer: 'animateShowChange',
cellRenderer: 'agAnimateShowChangeCellRenderer',
cellClassRules: {
'fx-positive': 'x > 0.8',
'fx-null': 'x === null',

View File

@@ -1,159 +0,0 @@
import React, {Component} from "react";
import {Redirect, Route, Switch} from "react-router-dom";
import NavItem from "./NavItem";
import DynamicComponentsExample from "./dynamicComponentExample/DynamicComponentsExample";
import RichGridExample from "./richGridExample/RichGridExample";
import RichComponentsExample from "./richComponentExample/RichComponentsExample";
import EditorComponentsExample from "./editorComponentExample/EditorComponentsExample";
import PinnedRowComponentExample from "./pinnedRowExample/PinnedRowComponentExample";
import FullWidthComponentExample from "./fullWidthExample/FullWidthComponentExample";
import GroupedRowInnerRendererComponentExample from "./groupedRowInnerRendererExample/GroupedRowInnerRendererComponentExample";
import FilterComponentExample from "./filterComponentExample/FilterComponentExample";
import MasterDetailExample from "./masterDetailExample/MasterDetailExample";
import SimpleReduxExample from "./simpleReduxExample/SimpleReduxExample";
import FloatingFilterGridExample from "./floatingFilter/FloatingFilterGridExample";
import SimpleReduxDynamicExample from "./simpleReduxDynamicComponentExample/SimpleReduxExample";
const SideBar = () => (
<div style={{float: "left", width: 335, marginRight: 25}}>
<ul className="nav nav-pills nav-stacked">
<NavItem to='/rich-grid'>Rich Grid Example</NavItem>
<NavItem to='/dynamic'>Dynamic React Component Example</NavItem>
<NavItem to='/rich-dynamic'>Dynamic React Components - Richer Example</NavItem>
<NavItem to='/editor'>Cell Editor Component Example</NavItem>
<NavItem to='/floating-row'>Floating Row Renderer Example</NavItem>
<NavItem to='/full-width'>Full Width Renderer Example</NavItem>
<NavItem to='/group-row'>Grouped Row Inner Renderer Example</NavItem>
<NavItem to='/filter'>Filters Component Example</NavItem>
<NavItem to='/master-detail'>Master Detail Example</NavItem>
<NavItem to='/floating-filter'>Floating Filters</NavItem>
<NavItem to='/simple-redux'>Simple Redux Example</NavItem>
<NavItem to='/simple-redux-dynamic'>Simple Redux Dynamic Component Example</NavItem>
</ul>
</div>
);
class App extends Component {
render() {
return (
<div style={{display: "inline-block", width: "100%"}}>
<SideBar/>
<div style={{float: "left"}}>
<Switch>
<Redirect from="/" exact to="/rich-grid"/>
<Route exact path='/rich-grid' component={RichGridExample}/>
<Route exact path='/dynamic' component={DynamicComponentsExample}/>
<Route exact path='/rich-dynamic' component={RichComponentsExample}/>
<Route exact path='/editor' component={EditorComponentsExample}/>
<Route exact path='/floating-row' component={PinnedRowComponentExample}/>
<Route exact path='/full-width' component={FullWidthComponentExample}/>
<Route exact path='/group-row' component={GroupedRowInnerRendererComponentExample}/>
<Route exact path='/filter' component={FilterComponentExample}/>
<Route exact path='/master-detail' component={MasterDetailExample}/>
<Route exact path='/floating-filter' component={FloatingFilterGridExample}/>
<Route exact path='/simple-redux' component={SimpleReduxExample}/>
<Route exact path='/simple-redux-dynamic' component={SimpleReduxDynamicExample}/>
</Switch>
</div>
</div>
)
}
}
export default App
/*
class App extends Component {
constructor(props) {
super(props);
let searchParams = new URLSearchParams(window.location.search);
let fromDocs = searchParams.has("fromDocs");
let example = searchParams.has("example") ? searchParams.get("example") : 'rich-grid';
this.state = {
example,
fromDocs
};
this.setExample = this.setExample.bind(this);
}
setExample(example) {
this.setState({
example
})
}
render() {
let header = null;
if (!this.state.fromDocs) {
header = (
<ul className="nav nav-pills">
<li role="presentation" className={this.state.example === 'rich-grid' ? 'active' : null} onClick={() => this.setExample("rich-grid")}><a href="#">Rich Grid Example</a></li>
<li role="presentation" className={this.state.example === 'dynamic' ? 'active' : null} onClick={() => this.setExample("dynamic")}><a href="#">Dynamic React Component Example</a></li>
<li role="presentation" className={this.state.example === 'rich-dynamic' ? 'active' : null} onClick={() => this.setExample("rich-dynamic")}><a href="#">Dynamic React Components - Richer Example</a></li>
<li role="presentation" className={this.state.example === 'editor' ? 'active' : null} onClick={() => this.setExample("editor")}><a href="#">Cell Editor Component Example</a></li>
<li role="presentation" className={this.state.example === 'pinned-row' ? 'active' : null} onClick={() => this.setExample("pinned-row")}><a href="#">Pinned Row Renderer Example</a></li>
<li role="presentation" className={this.state.example === 'full-width' ? 'active' : null} onClick={() => this.setExample("full-width")}><a href="#">Full Width Renderer Example</a></li>
<li role="presentation" className={this.state.example === 'group-row' ? 'active' : null} onClick={() => this.setExample("group-row")}><a href="#">Grouped Row Inner Renderer Example</a></li>
<li role="presentation" className={this.state.example === 'filter' ? 'active' : null} onClick={() => this.setExample("filter")}><a href="#">Filters Component Example</a></li>
<li role="presentation" className={this.state.example === 'floating-filter' ? 'active' : null} onClick={() => this.setExample("floating-filter")}><a href="#">Floating Filters</a></li>
<li role="presentation" className={this.state.example === 'master-detail' ? 'active' : null} onClick={() => this.setExample("master-detail")}><a href="#">Master Detail Example</a></li>
<li role="presentation" className={this.state.example === 'simple-redux' ? 'active' : null} onClick={() => this.setExample("simple-redux")}><a href="#">Simple Redux Example</a></li>
<li role="presentation" className={this.state.example === 'simple-redux-dynamic' ? 'active' : null} onClick={() => this.setExample("simple-redux-dynamic")}><a href="#">Simple Redux Dynamic Component Example</a></li>
</ul>)
}
let example = null;
switch (this.state.example) {
case 'dynamic':
example = <DynamicComponentsExample/>;
break;
case 'rich-dynamic':
example = <RichComponentsExample/>;
break;
case 'editor':
example = <EditorComponentsExample/>;
break;
case 'pinned-row':
example = <PinnedRowComponentExample/>;
break;
case 'full-width':
example = <FullWidthComponentExample/>;
break;
case 'group-row':
example = <GroupedRowInnerRendererComponentExample/>;
break;
case 'filter':
example = <FilterComponentExample/>;
break;
case 'master-detail':
example = <MasterDetailExample/>;
break;
case 'simple-redux':
example = <SimpleReduxExample/>;
break;
case 'floating-filter':
example = <FloatingFilterGridExample/>;
break;
case 'simple-redux-dynamic':
example = <SimpleReduxDynamicExample/>;
break;
default:
example = <RichGridExample/>;
}
return (
<div>
{header}
{example}
</div>
)
}
}
export default App
*/

View File

@@ -1,19 +0,0 @@
import React, {Component} from "react";
export default class ChildMessageRenderer extends Component {
constructor(props) {
super(props);
this.invokeParentMethod = this.invokeParentMethod.bind(this);
}
invokeParentMethod() {
this.props.context.componentParent.methodFromParent(`Row: ${this.props.node.rowIndex}, Col: ${this.props.colDef.headerName}`)
}
render() {
return (
<span><button style={{height: 20, lineHeight: 0.5}} onClick={this.invokeParentMethod} className="btn btn-info">Invoke Parent</button></span>
);
}
};

View File

@@ -1,21 +0,0 @@
import React, {Component} from "react";
export default class CubeRenderer extends Component {
constructor(props) {
super(props);
this.state = {
value: this.valueSquared()
};
}
valueSquared() {
return this.props.value * this.props.value * this.props.value;
}
render() {
return (
<span>{this.state.value}</span>
);
}
};

View File

@@ -1,31 +0,0 @@
import React, {Component} from "react";
export default class CurrencyRenderer extends Component {
constructor(props) {
super(props);
this.state = {
value: props.value
}
}
formatValueToCurrency(currency, value) {
return `${currency}${value}`
}
// noinspection JSUnusedGlobalSymbols
refresh(params) {
if(params.value !== this.state.value) {
this.setState({
value: params.value.toFixed(2)
})
}
return true;
}
render() {
return (
<span>{this.formatValueToCurrency('EUR', this.state.value)}</span>
);
}
};

View File

@@ -1,153 +0,0 @@
import React, {Component} from "react";
import {AgGridReact} from "ag-grid-react";
import SquareRenderer from "./SquareRenderer";
import CubeRenderer from "./CubeRenderer";
import ParamsRenderer from "./ParamsRenderer";
import CurrencyRenderer from "./CurrencyRenderer";
import ChildMessageRenderer from "./ChildMessageRenderer";
export default class DynamicComponentsExample extends Component {
constructor(props) {
super(props);
this.state = {
gridOptions: {
context: {
componentParent: this
}
},
rowData: DynamicComponentsExample.createRowData(),
columnDefs: DynamicComponentsExample.createColumnDefs()
};
this.onGridReady = this.onGridReady.bind(this);
this.refreshEvenRowsCurrencyData = this.refreshEvenRowsCurrencyData.bind(this);
}
onGridReady(params) {
this.gridApi = params.api;
this.columnApi = params.columnApi;
this.gridApi.sizeColumnsToFit();
}
methodFromParent(cell) {
alert(`Parent Component Method from ${cell}!`);
}
refreshEvenRowsCurrencyData() {
this.gridApi.forEachNode(rowNode => {
if (rowNode.data.value % 2 === 0) {
rowNode.setDataValue('currency', rowNode.data.value + Number(Math.random().toFixed(2)))
}
});
this.gridApi.refreshCells({
columns: ['currency']
})
}
static createColumnDefs() {
return [
{headerName: "Row", field: "row", width: 100},
{
headerName: "Square",
field: "value",
cellRendererFramework: SquareRenderer,
editable: true,
colId: "square",
width: 100
},
{
headerName: "Cube",
field: "value",
cellRendererFramework: CubeRenderer,
colId: "cube",
width: 100
},
{
headerName: "Row Params",
field: "row",
cellRendererFramework: ParamsRenderer,
colId: "params",
width: 215
},
{
headerName: "Currency",
field: "currency",
cellRendererFramework: CurrencyRenderer,
colId: "currency",
width: 135
},
{
headerName: "Child/Parent",
field: "value",
cellRendererFramework: ChildMessageRenderer,
colId: "params",
width: 120
}
];
}
static createRowData() {
let rowData = [];
for (let i = 0; i < 15; i++) {
rowData.push({
row: "Row " + i,
value: i,
currency: 1 + Number(Math.random()).toFixed(2)
});
}
return rowData;
}
render() {
return (
<div style={{height: 400, width: 900}}
className="ag-fresh">
<h1>Dynamic React Component Example</h1>
<button onClick={this.refreshEvenRowsCurrencyData} style={{marginBottom: 10}} className="btn btn-primary">Refresh Even Row Currency Data</button>
<AgGridReact
// properties
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}
gridOptions={this.state.gridOptions}
// events
onGridReady={this.onGridReady}>
</AgGridReact>
<div className="row">
<div className="col-sm-12"><h1>Dynamic React Component Example</h1></div>
</div>
<div className="row">
<div className="col-sm-12">
<h5>This example demonstrates Dynamic React Components with ag-Grid, Parent/Child Communication (cell component to parent grid component), as well as
dynamic data updates of the <code>Currency</code> column.</h5>
<p><span style={{fontWeight: "bold"}}>Square, Cube, Row Params, Currency and Child/Parent</span>: React Components within the Grid</p>
<p><span style={{fontWeight: "bold"}}>Currency (Pipe)</span>: An React Component mimicking a Currency Pipe, dynamically updated with the button above.</p>
<p><span style={{fontWeight: "bold"}}>Child/Parent</span>: Demonstrates the Child Cell Component communicating with the Parent Grid Component.</p>
<p><span style={{fontWeight: "bold"}}>Refresh Even Row Currency Data</span>: Dynamically Updates Event Rows Currency Value. Only the Currency column will be re-rendered.</p>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<div className="card">
<div className="card-body">
<h4 className="card-title">React Functionality</h4>
<p className="card-text">Utilise React Components within ag-Grid</p>
<a target="_blank" href="https://www.ag-grid.com/best-react-data-grid/?framework=react" className="btn btn-primary">React with ag-Grid</a>
<a target="_blank" href="https://www.ag-grid.com/javascript-grid-cell-rendering-components/?framework=react" className="btn btn-primary">React Renderers</a>
<a target="_blank" href="https://www.ag-grid.com/javascript-grid-data-update/" className="btn btn-primary">Updating Data</a>
</div>
</div>
</div>
</div>
</div>
);
}
};

View File

@@ -1,13 +0,0 @@
import React, {Component} from "react";
export default class ParamsRenderer extends Component {
constructor(props) {
super(props);
}
render() {
return (
<span>Field: {this.props.colDef.field}, Value: {this.props.value}</span>
);
}
};

View File

@@ -1,21 +0,0 @@
import React, {Component} from "react";
export default class SquareRenderer extends Component {
constructor(props) {
super(props);
this.state = {
value: this.valueSquared()
};
}
valueSquared() {
return this.props.value * this.props.value;
}
render() {
return (
<span>{this.state.value}</span>
);
}
};

View File

@@ -1,132 +0,0 @@
import React, {Component} from "react";
import {AgGridReact} from "ag-grid-react";
import MoodRenderer from "./MoodRenderer";
import MoodEditor from "./MoodEditor";
import NumericEditor from "./NumericEditor";
export default class EditorComponentsExample extends Component {
constructor(props) {
super(props);
this.state = {
rowData: EditorComponentsExample.createRowData(),
columnDefs: EditorComponentsExample.createColumnDefs()
};
this.onGridReady = this.onGridReady.bind(this);
}
onGridReady(params) {
this.gridApi = params.api;
this.columnApi = params.columnApi;
this.gridApi.sizeColumnsToFit();
}
static createColumnDefs() {
return [
{
headerName: "Name",
field: "name",
width: 300,
editable: true,
cellEditor: 'richSelect',
cellEditorParams: {
values: [
"Bob",
"Harry",
"Sally",
"Mary",
"John",
"Jack",
"Sue",
"Sean",
"Niall",
"Albert",
"Fred",
"Jenny",
"Larry"
]
}
},
{
headerName: "Mood",
field: "mood",
cellRendererFramework: MoodRenderer,
cellEditorFramework: MoodEditor,
editable: true,
width: 250
},
{
headerName: "Numeric",
field: "number",
cellEditorFramework: NumericEditor,
editable: true,
width: 250
}
];
}
static createRowData() {
return [
{name: "Bob", mood: "Happy", number: 10},
{name: "Harry", mood: "Sad", number: 3},
{name: "Sally", mood: "Happy", number: 20},
{name: "Mary", mood: "Sad", number: 5},
{name: "John", mood: "Happy", number: 15},
{name: "Jack", mood: "Happy", number: 25},
{name: "Sue", mood: "Sad", number: 43},
{name: "Sean", mood: "Sad", number: 1335},
{name: "Niall", mood: "Happy", number: 2},
{name: "Alberto", mood: "Happy", number: 123},
{name: "Fred", mood: "Sad", number: 532},
{name: "Jenny", mood: "Happy", number: 34},
{name: "Larry", mood: "Happy", number: 13},
];
}
render() {
return (
<div style={{height: 370, width: 900}}
className="ag-fresh">
<h1>Cell Editor Component Example</h1>
<AgGridReact
// properties
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}
// events
onGridReady={this.onGridReady}>
</AgGridReact>
<div className="row">
<div className="col-sm-12"><h1>Cell Editor Component Example</h1></div>
</div>
<div className="row">
<div className="col-sm-12">
<h5>This example demonstrates React Editor Components within ag-Grid, as well as an example using the built in Rich Select editor.</h5>
<p><span style={{fontWeight: "bold"}}>Name</span>: Utilises the built in <code>RichSelect</code> editor</p>
<p><span style={{fontWeight: "bold"}}>Mood</span>: A Custom React Editor demonstrating popup functionality, with full keyboard control.</p>
<p><span style={{fontWeight: "bold"}}>Numeric</span>: A Custom React Editor demonstrating pre & post validation. Only numeric characters are allowed,
and numbers greater than 1000000 will be rejected.</p>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<div className="card">
<div className="card-body">
<h4 className="card-title">React Functionality</h4>
<p className="card-text">Utilise React Components within ag-Grid</p>
<a target="_blank" href="https://www.ag-grid.com/javascript-grid-cell-editing/?framework=react" className="btn btn-primary">Cell Editing</a>
<a target="_blank" href="https://www.ag-grid.com/javascript-grid-cell-editor/?framework=react" className="btn btn-primary">Editor Components</a>
<a target="_blank" href="https://www.ag-grid.com/best-react-data-grid/?framework=react" className="btn btn-primary">React with ag-Grid</a>
<a target="_blank" href="https://www.ag-grid.com/javascript-grid-cell-editor/?framework=react#reactCellEditing" className="btn btn-primary">React Editor Components</a>
</div>
</div>
</div>
</div>
</div>
);
}
};

View File

@@ -1,120 +0,0 @@
import React, {Component} from "react";
import ReactDOM from "react-dom";
export default class MoodEditor extends Component {
constructor(props) {
super(props);
this.onHappyClick = this.onHappyClick.bind(this);
this.onSadClick = this.onSadClick.bind(this);
this.state = {
happy: false
}
}
componentWillMount() {
this.setHappy(this.props.value === "Happy");
}
componentDidMount() {
this.refs.container.addEventListener('keydown', this.checkAndToggleMoodIfLeftRight);
this.focus();
}
componentWillUnmount() {
this.refs.container.removeEventListener('keydown', this.checkAndToggleMoodIfLeftRight);
}
checkAndToggleMoodIfLeftRight = (event) => {
if ([37, 39].indexOf(event.keyCode) > -1) { // left and right
this.toggleMood();
event.stopPropagation();
}
}
componentDidUpdate() {
this.focus();
}
focus() {
setTimeout(() => {
let container = ReactDOM.findDOMNode(this.refs.container);
if (container) {
container.focus();
}
})
}
getValue() {
return this.state.happy ? "Happy" : "Sad";
}
isPopup() {
return true;
}
setHappy(happy) {
this.setState({
happy
});
}
onHappyClick() {
this.setState({
happy: true
},
() => this.props.api.stopEditing()
);
}
onSadClick() {
this.setState({
happy: false
},
() => this.props.api.stopEditing()
);
}
toggleMood() {
this.setHappy(!this.state.happy);
}
render() {
let mood = {
borderRadius: 15,
border: "1px solid grey",
background: "#e6e6e6",
padding: 15,
textAlign: "center",
display: "inline-block"
};
let unselected = {
paddingLeft: 10,
paddingRight: 10,
border: "1px solid transparent",
padding: 4
};
let selected = {
paddingLeft: 10,
paddingRight: 10,
border: "1px solid lightgreen",
padding: 4
};
let happyStyle = this.state.happy ? selected : unselected;
let sadStyle = !this.state.happy ? selected : unselected;
return (
<div ref="container"
style={mood}
tabIndex={1} // important - without this the keypresses wont be caught
>
<img src="images/smiley.png" onClick={this.onHappyClick} style={happyStyle}/>
<img src="images/smiley-sad.png" onClick={this.onSadClick} style={sadStyle}/>
</div>
);
}
}

View File

@@ -1,27 +0,0 @@
import React, {Component} from "react";
export default class MoodRenderer extends Component {
constructor(props) {
super(props);
}
componentWillMount() {
this.setMood(this.props.value)
}
refresh(params) {
this.setMood(params.value);
}
setMood(mood) {
this.setState({
imgForMood: mood === 'Happy' ? 'images/smiley.png' : 'images/smiley-sad.png'
})
};
render() {
return (
<img width="20px" src={this.state.imgForMood}/>
);
}
}

View File

@@ -1,99 +0,0 @@
import React, {Component} from "react";
export default class MoodEditor extends Component {
constructor(props) {
super(props);
this.cancelBeforeStart = this.props.charPress && ('1234567890'.indexOf(this.props.charPress) < 0);
let value = this.props.value;
if (!this.cancelBeforeStart && this.props.charPress) {
value = value + this.props.charPress;
}
this.state = {
value
};
this.onKeyDown = this.onKeyDown.bind(this);
this.handleChange = this.handleChange.bind(this);
}
componentDidMount() {
this.refs.input.addEventListener('keydown', this.onKeyDown);
this.focus();
}
componentDidUpdate() {
this.focus();
}
componentWillUnmount() {
this.refs.input.removeEventListener('keydown', this.onKeyDown);
}
focus() {
setTimeout(() => {
this.refs.input.focus();
this.refs.input.setSelectionRange(this.state.value.length, this.state.value.length);
})
}
getValue() {
return this.state.value;
}
isCancelBeforeStart() {
return this.cancelBeforeStart;
}
// will reject the number if it greater than 1,000,000
// not very practical, but demonstrates the method.
isCancelAfterEnd() {
return this.state.value > 1000000;
};
onKeyDown(event) {
if (this.isLeftOrRight(event)) {
event.stopPropagation();
return;
}
if (!this.isKeyPressedNumeric(event)) {
if (event.preventDefault) event.preventDefault();
}
}
isLeftOrRight(event) {
return [37, 39].indexOf(event.keyCode) > -1;
}
handleChange(event) {
this.setState({value: event.target.value});
}
getCharCodeFromEvent(event) {
event = event || window.event;
return (typeof event.which === "undefined") ? event.keyCode : event.which;
}
isCharNumeric(charStr) {
return !!/\d/.test(charStr);
}
isKeyPressedNumeric(event) {
const charCode = this.getCharCodeFromEvent(event);
const charStr = event.key ? event.key : String.fromCharCode(charCode);
return this.isCharNumeric(charStr);
}
render() {
return (
<input ref="input"
value={this.state.value}
onChange={this.handleChange}
style={{width: "100%"}}
/>
);
}
}

View File

@@ -1,86 +0,0 @@
import React, {Component} from "react";
import {AgGridReact} from "ag-grid-react";
import "ag-grid-enterprise";
import PartialMatchFilter from "./PartialMatchFilter";
export default class FilterComponentExample extends Component {
constructor(props) {
super(props);
this.state = {
gridOptions: {},
rowData: FilterComponentExample.createRowData(),
columnDefs: FilterComponentExample.createColumnDefs(),
};
this.onGridReady = this.onGridReady.bind(this);
this.onClicked = this.onClicked.bind(this);
}
onGridReady(params) {
this.gridApi = params.api;
this.columnApi = params.columnApi;
this.gridApi.sizeColumnsToFit();
}
onClicked() {
this.gridApi.getFilterInstance("name").getFrameworkComponentInstance().componentMethod("Hello World!");
}
static createColumnDefs() {
return [
{headerName: "Row", field: "row", width: 400},
{
headerName: "Filter Component",
field: "name",
filterFramework: PartialMatchFilter,
width: 400,
menuTabs:['filterMenuTab']
}
];
}
static createRowData() {
return [
{"row": "Row 1", "name": "Michael Phelps"},
{"row": "Row 2", "name": "Natalie Coughlin"},
{"row": "Row 3", "name": "Aleksey Nemov"},
{"row": "Row 4", "name": "Alicia Coutts"},
{"row": "Row 5", "name": "Missy Franklin"},
{"row": "Row 6", "name": "Ryan Lochte"},
{"row": "Row 7", "name": "Allison Schmitt"},
{"row": "Row 8", "name": "Natalie Coughlin"},
{"row": "Row 9", "name": "Ian Thorpe"},
{"row": "Row 10", "name": "Bob Mill"},
{"row": "Row 11", "name": "Willy Walsh"},
{"row": "Row 12", "name": "Sarah McCoy"},
{"row": "Row 13", "name": "Jane Jack"},
{"row": "Row 14", "name": "Tina Wills"}
];
}
render() {
return (
<div style={{height: 400, width: 900}}
className="ag-fresh">
<h1>Filter Component Example</h1>
<button style={{marginBottom: 10}} onClick={this.onClicked} className="btn btn-primary">Filter Instance Method</button>
<AgGridReact
// properties
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}
enableFilter
// events
onGridReady={this.onGridReady}>
</AgGridReact>
</div>
);
}
};

View File

@@ -1,80 +0,0 @@
import React, {Component} from "react";
import ReactDOM from "react-dom";
export default class PartialMatchFilter extends Component {
constructor(props) {
super(props);
this.state = {
text: ''
};
this.valueGetter = this.props.valueGetter;
this.onChange = this.onChange.bind(this);
}
isFilterActive() {
return this.state.text !== null && this.state.text !== undefined && this.state.text !== '';
}
doesFilterPass(params) {
return this.state.text.toLowerCase()
.split(" ")
.every((filterWord) => {
return this.valueGetter(params.node).toString().toLowerCase().indexOf(filterWord) >= 0;
});
}
getModel() {
return {value: this.state.text};
}
setModel(model) {
this.state.text = model ? model.value : '';
}
afterGuiAttached(params) {
this.focus();
}
focus() {
setTimeout(() => {
let container = ReactDOM.findDOMNode(this.refs.input);
if (container) {
container.focus();
}
})
}
componentMethod(message) {
alert(`Alert from PartialMatchFilterComponent ${message}`);
}
onChange(event) {
let newValue = event.target.value;
if (this.state.text !== newValue) {
this.setState({
text: newValue
}, () => {
this.props.filterChangedCallback();
});
}
}
render() {
let style = {
border: "2px solid #22ff22",
borderRadius: "5px",
backgroundColor: "#bbffbb",
width: "200px",
height: "50px"
};
return (
<div style={style}>Filter: <input style={{height: "20px"}} ref="input" value={this.state.text}
onChange={this.onChange} className="form-control"/></div>
);
}
};

View File

@@ -1,69 +0,0 @@
import React, {Component} from "react";
import {AgGridReact} from "ag-grid-react";
import FloatingFilter from "./floatingFilter";
import overrideStyle from "./floatingFilter.css";
export default class FloatingFilterGridExample extends Component {
constructor(props) {
super(props);
this.state = {
columnDefs: this.createColumnDefs(),
rowData: this.createRowData()
}
}
onGridReady(params) {
this.gridApi = params.api;
this.columnApi = params.columnApi;
this.gridApi.sizeColumnsToFit();
}
createColumnDefs() {
return [
{
headerName: "Make",
field: "make",
floatingFilterComponentFramework: FloatingFilter,
filter: 'set'
},
{headerName: "Model", field: "model"},
{headerName: "Price", field: "price"}
];
}
createRowData() {
return [
{make: "Toyota", model: "Celica", price: 35000},
{make: "Ford", model: "Mondeo", price: 32000},
{make: "Porsche", model: "Boxter", price: 72000}
];
}
render() {
let divStyle = {
height: 400,
width: 900
};
// combine the styles
const style = Object.assign({}, divStyle, overrideStyle);
return (
<div style={style} className="ag-fresh">
<h1>Floating Filter Example</h1>
<AgGridReact
// properties
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}
floatingFilter={true}
// events
onGridReady={this.onGridReady}>
</AgGridReact>
</div>
)
}
};

View File

@@ -1,3 +0,0 @@
.ag-floating-filter-button button {
margin: 0
}

View File

@@ -1,39 +0,0 @@
import React, {Component} from "react";
export default class FloatingFilter extends Component {
constructor(props) {
super(props);
this.state = {
parentModel: null
}
}
// when does this get called? how to test this?
onParentModelChanged(parentModel) {
this.setState({
parentModel: parentModel
})
}
remove(item) {
this.props.onFloatingFilterChanged({
model: this.state.parentModel.filter(it => it !== item)
});
}
render() {
if (!this.state.parentModel) return null;
// as the backing filter is a set filter what we're doing here is rendering the list in the set
// and when the [x] removing the selected item, thereby effectively hiding it
let options = this.state.parentModel.map((item, i) => {
let removeMeListener = () => {
this.remove(item)
};
let removeMeElement = <a onClick={removeMeListener}>[x]</a>;
return <span key={i}>{item}{removeMeElement}</span>;
});
return <div>{options}</div>;
}
}

View File

@@ -1,88 +0,0 @@
import React, {Component} from "react";
import {AgGridReact} from "ag-grid-react";
import NameAndAgeRenderer from "./NameAndAgeRenderer";
export default class FullWidthComponentExample extends Component {
constructor(props) {
super(props);
this.state = {
gridOptions: {},
rowData: FullWidthComponentExample.createRowData(),
columnDefs: FullWidthComponentExample.createColumnDefs()
};
this.onGridReady = this.onGridReady.bind(this);
}
onGridReady(params) {
this.gridApi = params.api;
this.columnApi = params.columnApi;
this.gridApi.sizeColumnsToFit();
}
isFullWidthCell(rowNode) {
return (rowNode.id === "0") || (parseInt(rowNode.id) % 2 === 0);
}
static createColumnDefs() {
return [
{
headerName: "Name",
field: "name",
width: 400
},
{
headerName: "Age",
field: "age",
width: 399
},
];
}
static createRowData() {
return [
{name: "Bob", age: 10},
{name: "Harry", age: 3},
{name: "Sally", age: 20},
{name: "Mary", age: 5},
{name: "John", age: 15},
{name: "Bob", age: 10},
{name: "Harry", age: 3},
{name: "Sally", age: 20},
{name: "Mary", age: 5},
{name: "John", age: 15},
{name: "Jack", age: 25},
{name: "Sue", age: 43},
{name: "Sean", age: 44},
{name: "Niall", age: 2},
{name: "Alberto", age: 32},
{name: "Fred", age: 53},
{name: "Jenny", age: 34},
{name: "Larry", age: 13},
];
}
render() {
return (
<div style={{height: 400, width: 900}}
className="ag-fresh">
<h1>Full Width Renderer Example</h1>
<AgGridReact
// properties
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}
isFullWidthCell={this.isFullWidthCell}
fullWidthCellRendererFramework={NameAndAgeRenderer}
// events
onGridReady={this.onGridReady}>
</AgGridReact>
</div>
);
}
};

View File

@@ -1,21 +0,0 @@
import React, {Component} from "react";
export default class NameAndAgeRenderer extends Component {
constructor(props) {
super(props);
this.values = `Name: ${this.props.data.name}, Age: ${this.props.data.age}`;
}
render() {
let style = {
border: "2px solid #22ff22",
borderRadius: "5px",
backgroundColor: "#bbffbb"
};
return (
<div style={style}>Full Width Column! { this.values }</div>
);
}
};

View File

@@ -1,126 +0,0 @@
import React, {Component} from "react";
import {AgGridReact} from "ag-grid-react";
import MedalRenderer from "./MedalRenderer";
import "ag-grid-enterprise";
export default class GroupedRowInnerRendererComponentExample extends Component {
constructor(props) {
super(props);
this.state = {
gridOptions: {},
rowData: this.createRowData(),
columnDefs: this.createColumnDefs(),
};
this.onGridReady = this.onGridReady.bind(this);
}
onGridReady(params) {
this.gridApi = params.api;
this.columnApi = params.columnApi;
this.gridApi.sizeColumnsToFit();
}
createColumnDefs() {
return [
{
headerName: "Country",
field: "country",
width: 100,
rowGroupIndex: 0
},
{
headerName: "Name",
field: "name",
width: 100
},
{
headerName: "Gold",
field: "gold",
width: 100,
aggFunc: 'sum'
},
{
headerName: "Silver",
field: "silver",
width: 100,
aggFunc: 'sum'
},
{
headerName: "Bronze",
field: "bronze",
width: 100,
aggFunc: 'sum'
},
];
}
createRowData() {
return [
{country: "United States", name: "Bob", gold: 1, silver: 0, bronze: 0},
{country: "United States", name: "Jack", gold: 0, silver: 1, bronze: 1},
{country: "United States", name: "Sue", gold: 1, silver: 0, bronze: 1},
{country: "United Kingdom", name: "Mary", gold: 1, silver: 1, bronze: 0},
{country: "United Kingdom", name: "Tess", gold: 0, silver: 1, bronze: 1},
{country: "United Kingdom", name: "John", gold: 0, silver: 2, bronze: 1},
{country: "Jamaica", name: "Bob", gold: 1, silver: 1, bronze: 0},
{country: "Jamaica", name: "Jack", gold: 1, silver: 1, bronze: 0},
{country: "Jamaica", name: "Mary", gold: 1, silver: 1, bronze: 0},
{country: "South Africa", name: "Bob", gold: 1, silver: 0, bronze: 1},
{country: "South Africa", name: "Jack", gold: 1, silver: 0, bronze: 1},
{country: "South Africa", name: "Mary", gold: 1, silver: 0, bronze: 1},
{country: "South Africa", name: "John", gold: 1, silver: 0, bronze: 1},
{country: "New Zealand", name: "Bob", gold: 1, silver: 0, bronze: 0},
{country: "New Zealand", name: "Jack", gold: 0, silver: 1, bronze: 1},
{country: "New Zealand", name: "Sue", gold: 1, silver: 0, bronze: 1},
{country: "Australia", name: "Mary", gold: 1, silver: 1, bronze: 0},
{country: "Australia", name: "Tess", gold: 0, silver: 1, bronze: 1},
{country: "Australia", name: "John", gold: 0, silver: 2, bronze: 1},
{country: "Canada", name: "Bob", gold: 1, silver: 1, bronze: 0},
{country: "Canada", name: "Jack", gold: 1, silver: 1, bronze: 0},
{country: "Canada", name: "Mary", gold: 1, silver: 1, bronze: 0},
{country: "Switzerland", name: "Bob", gold: 1, silver: 0, bronze: 1},
{country: "Switzerland", name: "Jack", gold: 1, silver: 0, bronze: 1},
{country: "Switzerland", name: "Mary", gold: 1, silver: 0, bronze: 1},
{country: "Switzerland", name: "John", gold: 1, silver: 0, bronze: 1},
{country: "Spain", name: "Bob", gold: 1, silver: 0, bronze: 0},
{country: "Spain", name: "Jack", gold: 0, silver: 1, bronze: 1},
{country: "Spain", name: "Sue", gold: 1, silver: 0, bronze: 1},
{country: "Portugal", name: "Mary", gold: 1, silver: 1, bronze: 0},
{country: "Portugal", name: "Tess", gold: 0, silver: 1, bronze: 1},
{country: "Portugal", name: "John", gold: 0, silver: 2, bronze: 1},
{country: "Zimbabwe", name: "Bob", gold: 1, silver: 1, bronze: 0},
{country: "Zimbabwe", name: "Jack", gold: 1, silver: 1, bronze: 0},
{country: "Zimbabwe", name: "Mary", gold: 1, silver: 1, bronze: 0},
{country: "Brazil", name: "Bob", gold: 1, silver: 0, bronze: 1},
{country: "Brazil", name: "Jack", gold: 1, silver: 0, bronze: 1},
{country: "Brazil", name: "Mary", gold: 1, silver: 0, bronze: 1},
{country: "Brazil", name: "John", gold: 1, silver: 0, bronze: 1}
];
}
render() {
return (
<div style={{height: 400, width: 900}}
className="ag-fresh">
<h1>Group Row Renderer Example</h1>
<AgGridReact
// properties
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}
groupUseEntireRow
groupRowInnerRendererFramework={MedalRenderer}
// events
onGridReady={this.onGridReady}>
</AgGridReact>
</div>
);
}
};

Some files were not shown because too many files have changed in this diff Show More