Compare commits

..

106 Commits

Author SHA1 Message Date
Sean Landsman
d540eea26d Release 22.1.1 Prep Work 2019-12-11 11:31:46 +00:00
Sean Landsman
86c353eaa9 Release 22.1.0 2019-12-02 14:30:27 +00:00
Sean Landsman
52cf4512a9 AG-3600 React - memoized functions don't render 2019-11-21 14:55:31 +00:00
Sean Landsman
611d668981 Merge branch 'b22.0.0' into latest 2019-11-11 15:02:22 +00:00
Sean Landsman
5ad3592fed AG-1329 Update examples 2019-11-11 11:22:13 +00:00
Sean Landsman
ff7c46e553 AG-1329 Add licenses etc to new packages 2019-11-08 10:54:47 +00:00
Sean Landsman
1c1e1bf555 AG-1329 Rename packages to new scopes (@ag-grid-community & @ag-grid-enterprise) 2019-11-05 09:18:50 +00:00
Sean Landsman
6ad4493357 AG-1329 Rename packages to new scopes (@ag-grid-community & @ag-grid-enterprise) 2019-11-04 20:25:39 +00:00
Sean Landsman
1cf70a551e Merge branch 'latest' into b22.0.0 2019-10-25 12:41:54 +01:00
Sean Landsman
fcc2bfffcd Merge branch 'latest' into b22.0.0 2019-10-25 11:11:08 +01:00
Sean Landsman
3e8b1b7979 Merge branch 'latest' into b22.0.0 2019-10-24 09:35:46 +01:00
Sean Landsman
61420e0d67 AG-1329 Move ag-grid-react and ag-grid-vue to modules 2019-10-23 20:25:40 +01:00
Sean Landsman
bd63d49c52 Release 22.0.0 2019-10-23 11:23:35 +01:00
Sean Landsman
36eb9c8a18 AG-1329 Fix source map issue, change versions, clean modules 2019-10-22 16:58:54 +01:00
Sean Landsman
b4c3ebc248 AG-1329 Update framework examples and tests 2019-10-18 20:46:09 +01:00
Sean Landsman
51621200da AG-1329 Modularisation work - update examples 2019-10-18 18:40:14 +01:00
Sean Landsman
46c26f074e AG-1329 Add modularisation mechanism 2019-10-09 18:41:11 +01:00
Sean Landsman
894d971f0e AG-3316 agGridReact needs to be updated to use the updated react lifecycle hooks 2019-09-30 15:00:08 +01:00
Sean Landsman
0584234be7 AG-3316 agGridReact needs to be updated to use the updated react lifecycle hooks 2019-09-25 12:22:09 +01:00
Sean Landsman
b9b2b03a6b AG-2914 DOCS - Add docs around react hooks with editors. 2019-09-23 14:29:21 +01:00
Sean Landsman
5a26863aff AG-3316 agGridReact needs to be updated to use the updated react lifecycle hooks 2019-09-16 15:45:07 +01:00
Sean Landsman
3223b82616 AG-3294 Update and improve build process 2019-09-10 12:32:05 +01:00
Sean Landsman
70f747e9f3 Update example versions 2019-06-04 15:39:31 +01:00
Sean Landsman
29152268bc Update example versions 2019-06-04 15:35:54 +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
158 changed files with 864 additions and 11531 deletions

1
.gitignore vendored
View File

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

View File

@@ -1,29 +1,18 @@
ag-Grid React Example ag-Grid React Example
============== ==============
Examples of running ag-Grid inside React application. ## Examples
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:
1. standard - shows a typical grid demonstrating many ag-Grid features 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 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 Building
============== ==============
To build: To build:
- `npm install` - `npm install`
- `npm install webpack -g`
- `npm run examples`, `npm run large` or `npm run trader` - `npm run examples`, `npm run large` or `npm run trader`
- navigate to localhost:8080 - navigate to localhost:8080

View File

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

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

@@ -0,0 +1,37 @@
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 React from 'react'
import {Route, Link} from 'react-router-dom' import * as PropTypes from 'prop-types';
import {Link, Route} from 'react-router-dom'
// for bootstrap li active functionality // for bootstrap li active functionality
export default function NavItem({children, to, exact}) { export default function NavItem({children, to, exact}) {
return ( return (
<Route path={to} exact={exact} children={({match}) => ( <Route path={to} exact={exact} children={({match}) => (
<li className={match ? 'active' : null}> <li className="nav-item">
<Link to={to}>{children}</Link> <Link className={match ? 'nav-link active' : 'nav-link'} to={to}>{children}</Link>
</li> </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> <head>
<meta charset="utf-8"> <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 --> <!-- Example uses font awesome icons -->
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet"> <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
@@ -16,6 +16,10 @@
line-height: 1 line-height: 1
} }
h1 {
font-size: 1.5rem;
}
div.card-body > a { div.card-body > a {
margin-top: 5px margin-top: 5px
} }

View File

@@ -4,14 +4,14 @@ import React from "react";
import {render} from "react-dom"; import {render} from "react-dom";
import {BrowserRouter} from "react-router-dom"; import {BrowserRouter} from "react-router-dom";
import "ag-grid-root/dist/styles/ag-grid.css"; import "@ag-grid-enterprise/all-modules/dist/styles/ag-grid.css";
import "ag-grid-root/dist/styles/theme-fresh.css"; import "@ag-grid-enterprise/all-modules/dist/styles/ag-theme-balham.css";
import "../node_modules/bootstrap/dist/css/bootstrap.css"; import "../node_modules/bootstrap/dist/css/bootstrap.css";
import App from "./App"; import App from "./App";
// only required when using enterprise features // only required when using enterprise features
// import {LicenseManager} from "ag-grid-enterprise/main"; // import {LicenseManager} from "@ag-grid-enterprise/all-modules";
// LicenseManager.setLicenseKey("<your license key>"); // LicenseManager.setLicenseKey("<your license key>");
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {

View File

@@ -37,7 +37,7 @@ export default class DateComponent extends React.Component {
width: '30px' width: '30px'
}; };
let yyyyStyle = { let yyyyStyle = {
width: '60px' width: '40px'
}; };
let resetStyle = { let resetStyle = {
padding: '2px', padding: '2px',
@@ -51,11 +51,11 @@ export default class DateComponent extends React.Component {
return ( return (
<div style={filterStyle}> <div style={filterStyle}>
<span style={resetStyle} onClick={this.resetDate.bind(this)}>x</span> <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"/>/ 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"/>/ 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"/> value={this.state.textBoxes.yyyy} maxLength="4"/>
</div> </div>
); );

View File

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

View File

@@ -0,0 +1,259 @@
import React, {Component} from "react";
import {AgGridColumn, AgGridReact} from "@ag-grid-community/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";
// for community features
// import {AllCommunityModules} from "@ag-grid-community/all-modules";
// for enterprise features
import {AllModules} from "@ag-grid-enterprise/all-modules";
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}
// register all modules (row model, csv/excel, row grouping etc)
modules={AllModules}
// 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; return passed;
}; };
getModel() { getModelAsString() {
return '' return ''
} }
@@ -83,7 +83,6 @@ export default class SkillsFilter extends React.Component {
const skillsTemplates = []; const skillsTemplates = [];
RefData.IT_SKILLS.forEach((skill, index) => { RefData.IT_SKILLS.forEach((skill, index) => {
const skillName = RefData.IT_SKILLS_NAMES[index]; const skillName = RefData.IT_SKILLS_NAMES[index];
const template = ( const template = (
<label key={skill} <label key={skill}

View File

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

View File

@@ -1,7 +1,5 @@
import React, {Component} from "react"; import React, {Component} from "react";
import {connect} from "react-redux"; import {connect} from "react-redux";
// take this line out if you do not want to use ag-Grid-Enterprise
import "ag-grid-enterprise";
import {setCurrency, updateRowData} from "./gridDataActions"; import {setCurrency, updateRowData} from "./gridDataActions";
@@ -25,8 +23,8 @@ class HeaderComponent extends Component {
render() { render() {
return ( return (
<div style={{marginTop: 15}}> <div style={{marginTop: 15}}>
<button onClick={this.setCurrency.bind(this, '£', 1)}>Set Currency to GBP</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)}>Set Currency to USD</button> <button onClick={this.setCurrency.bind(this, '$', 1.29)} className="btn btn-primary">Set Currency to USD</button>
</div> </div>
) )
} }
@@ -82,4 +80,4 @@ export default connect(
rowData: state.rowData rowData: state.rowData
} }
} }
)(HeaderComponent); )(HeaderComponent);

View File

@@ -1,6 +1,8 @@
import React, {Component} from "react"; import React, {Component} from "react";
import {connect} from "react-redux"; import {connect} from "react-redux";
import FontContext from './fontContext'
class PriceRenderer extends Component { class PriceRenderer extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
@@ -18,7 +20,10 @@ class PriceRenderer extends Component {
render() { render() {
return ( 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, currencySymbol: state.currencySymbol,
exchangeRate: state.exchangeRate exchangeRate: state.exchangeRate
} }
} },
)(PriceRenderer); null,
null,
{forwardRef: true} // must be supplied for react/redux when using AgGridReact
)(PriceRenderer);

View File

@@ -1,14 +1,14 @@
import React, {Component} from "react"; import React, {Component} from "react";
import {Provider} from "react-redux"; import {Provider} from "react-redux";
import {createStore} from "redux"; import {createStore} from "redux";
// take this line out if you do not want to use ag-Grid-Enterprise
import "ag-grid-enterprise";
import HeaderComponent from "./HeaderComponent"; import HeaderComponent from "./HeaderComponent";
import GridComponent from "./GridComponent"; import GridComponent from "./GridComponent";
import gridData from "./gridDataReducer"; import gridData from "./gridDataReducer";
import FontContext from './fontContext'
let store = createStore(gridData); let store = createStore(gridData);
/* /*
@@ -25,8 +25,10 @@ export default class SimpleReduxExample extends Component {
<Provider store={store}> <Provider store={store}>
<div> <div>
<h1>Simple Redux Example using Connected React Components</h1> <h1>Simple Redux Example using Connected React Components</h1>
<HeaderComponent /> <HeaderComponent/>
<GridComponent /> <FontContext.Provider value="bold">
<GridComponent/>
</FontContext.Provider>
</div> </div>
</Provider> </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 rowData
} }
} }
export function setCurrency(currencySymbol, exchangeRate) { export function setCurrency(currencySymbol, exchangeRate) {
return { return {
type: 'CURRENCY_CHANGED', type: 'CURRENCY_CHANGED',

View File

@@ -0,0 +1,34 @@
import React, {useContext} from "react";
import {Context} from "./store";
import {AgGridReact} from "@ag-grid-community/react";
import {AllModules} from "@ag-grid-enterprise/all-modules";
/*
* 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}
modules={AllModules}
defaultColDef={{filter: true}}
// events
onGridReady={onGridReady}>
</AgGridReact>
</div>
)
}

View File

@@ -0,0 +1,18 @@
import React, {useEffect, forwardRef, useImperativeHandle, useRef} from "react";
export default forwardRef((props, ref) => {
const inputRef = useRef();
useImperativeHandle(ref, () => {
return {
getValue: () => {
return inputRef.current.value;
}
};
});
useEffect(() => {
// https://github.com/facebook/react/issues/7835#issuecomment-395504863
setTimeout(() => inputRef.current.focus(), 10)
}, []);
return <input type="text" ref={inputRef} defaultValue={props.value}/>;
})

View File

@@ -0,0 +1,18 @@
import React, {forwardRef, useImperativeHandle, useRef} from "react";
export default forwardRef((props, ref) => {
const inputRef = useRef();
useImperativeHandle(ref, () => {
return {
isFilterActive() {
return inputRef.current.value !== '';
},
doesFilterPass: (params) => {
return params.data.price.toString() === inputRef.current.value;
}
};
});
return <input type="text" ref={inputRef} onChange={() => props.filterChangedCallback()}/>;
})

View File

@@ -1,13 +1,13 @@
import React, {Component} from "react"; import React, {Component} from "react";
export default class CurrencyRenderer extends Component { export default class PriceRenderer extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
} }
render() { render() {
return ( 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,81 @@
import React from "react";
import PriceRenderer from "./PriceRenderer";
import PriceEditor from "./PriceEditor";
import PriceFilter from "./PriceFilter";
export const initialState = {
rowData: [],
columnDefs: [
{
field: 'symbol',
editable: true
},
{
field: 'price',
cellClass: 'align-right',
editable: true,
cellEditorFramework: PriceEditor,
filterFramework: PriceFilter,
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> <head>
<meta charset="utf-8"> <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 --> <!-- Example uses font awesome icons -->
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet"> <link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet">
</head> </head>

View File

@@ -3,9 +3,9 @@
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import React from 'react'; import React from 'react';
import LargeGrid from './largeGrid.jsx'; 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-community/core/dist/styles/ag-grid.css';
import 'ag-grid-root/dist/styles/theme-fresh.css'; import '@ag-grid-community/core/dist/styles/ag-theme-fresh.css';
// waiting for dom to load before booting react. we could alternatively // 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. // put the index.js reference at the end fo the index.html, but i prefer this way.

View File

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

View File

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

View File

@@ -1,6 +1,7 @@
import React, {Component} from "react"; import React, {Component} from "react";
import {AgGridReact} from "ag-grid-react"; import {AgGridReact} from "@ag-grid-community/react";
import {ClientSideRowModelModule} from "@ag-grid-enterprise/all-modules";
import map from "lodash/map"; import map from "lodash/map";
import difference from "lodash/difference"; import difference from "lodash/difference";
@@ -24,21 +25,21 @@ export default class extends Component {
field: 'price', field: 'price',
headerName: 'Price', headerName: 'Price',
valueFormatter: this.numberFormatter, valueFormatter: this.numberFormatter,
cellRenderer: 'animateShowChange', cellRenderer: 'agAnimateShowChangeCellRenderer',
cellStyle: {'text-align': 'right'} cellStyle: {'text-align': 'right'}
}, },
{ {
field: 'bid', field: 'bid',
headerName: 'Bid', headerName: 'Bid',
valueFormatter: this.numberFormatter, valueFormatter: this.numberFormatter,
cellRenderer: 'animateShowChange', cellRenderer: 'agAnimateShowChangeCellRenderer',
cellStyle: {'text-align': 'right'} cellStyle: {'text-align': 'right'}
}, },
{ {
field: 'ask', field: 'ask',
headerName: 'Ask', headerName: 'Ask',
valueFormatter: this.numberFormatter, valueFormatter: this.numberFormatter,
cellRenderer: 'animateShowChange', cellRenderer: 'agAnimateShowChangeCellRenderer',
cellStyle: {'text-align': 'right'} cellStyle: {'text-align': 'right'}
} }
] ]
@@ -151,13 +152,17 @@ export default class extends Component {
render() { render() {
return ( return (
<div style={{height: 410, width: 800}} <div style={{height: 410, width: 800}}
className="ag-fresh"> className="ag-theme-fresh">
<AgGridReact <AgGridReact
// properties // properties
columnDefs={this.state.columnDefs} columnDefs={this.state.columnDefs}
enableSorting="true" defaultColDef={{
sortable: true
}}
rowSelection="single" rowSelection="single"
modules={[ClientSideRowModelModule]}
// callbacks // callbacks
getRowNodeId={this.getRowNodeId} getRowNodeId={this.getRowNodeId}
@@ -168,4 +173,4 @@ export default class extends Component {
</div> </div>
); );
} }
} }

View File

@@ -1,7 +1,8 @@
import React, {Component} from "react"; import React, {Component} from "react";
import {connect} from "react-redux"; import {connect} from "react-redux";
import {AgGridReact} from "ag-grid-react"; import {AgGridReact} from "@ag-grid-community/react";
import {ClientSideRowModelModule} from "@ag-grid-enterprise/all-modules";
class TopMoversGrid extends Component { class TopMoversGrid extends Component {
constructor(props) { constructor(props) {
@@ -17,24 +18,24 @@ class TopMoversGrid extends Component {
field: 'last', field: 'last',
headerName: 'Last', headerName: 'Last',
headerClass: 'align-right', headerClass: 'align-right',
cellRenderer: 'animateShowChange', cellRenderer: 'agAnimateShowChangeCellRenderer',
cellClass: 'align-right' cellClass: 'align-right'
}, },
{ {
field: 'net', field: 'net',
headerName: 'Net', headerName: 'Net',
headerClass: 'align-right', headerClass: 'align-right',
cellRenderer: 'animateShowChange', cellRenderer: 'agAnimateShowChangeCellRenderer',
cellClass: 'align-right' cellClass: 'align-right'
}, },
{ {
field: 'pct_net_change', field: 'pct_net_change',
headerName: '% NC', headerName: '% NC',
headerClass: 'align-right', headerClass: 'align-right',
cellRenderer: 'animateShowChange', cellRenderer: 'agAnimateShowChangeCellRenderer',
cellClass: 'align-right', cellClass: 'align-right',
sort: 'desc', sort: 'desc',
cellFormatter(params) { valueFormatter(params) {
return params.value.toFixed(2) return params.value.toFixed(2)
} }
}, },
@@ -62,17 +63,21 @@ class TopMoversGrid extends Component {
render() { render() {
return ( return (
<div style={{height: 410, width: 400}} <div style={{height: 410, width: 400}}
className="ag-fresh"> className="ag-theme-fresh">
<AgGridReact <AgGridReact
// properties // properties
columnDefs={this.state.columnDefs} columnDefs={this.state.columnDefs}
rowData={this.props.rowData} rowData={this.props.rowData}
enableSorting defaultColDef={{
enableFilter="false" sortable: true,
filter: false
}}
animateRows animateRows
deltaRowDataMode deltaRowDataMode
getRowNodeId={this.getRowNodeId} getRowNodeId={this.getRowNodeId}
modules={[ClientSideRowModelModule]}
// events // events
onGridReady={this.onGridReady}> onGridReady={this.onGridReady}>
</AgGridReact> </AgGridReact>
@@ -84,7 +89,7 @@ class TopMoversGrid extends Component {
export default connect( export default connect(
(state) => { (state) => {
return { 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 { export default class HorizontalBarComponent extends Component {
constructor(props) {
super(props);
this.state = {
value: this.props.value
}
}
render() { render() {
let positiveChange = { let positiveChange = {
fill: "green" fill: "green"
@@ -19,7 +27,7 @@ export default class HorizontalBarComponent extends Component {
textAlign: "right" textAlign: "right"
}; };
let pctNetChange = this.props.value; let pctNetChange = this.state.value;
let pctNetChangeBar = Math.min(Math.abs(pctNetChange) * 100, 100) / 2; let pctNetChangeBar = Math.min(Math.abs(pctNetChange) * 100, 100) / 2;
let barWidth = `${pctNetChangeBar}%`; let barWidth = `${pctNetChangeBar}%`;
@@ -36,6 +44,13 @@ export default class HorizontalBarComponent extends Component {
</div> </div>
) )
} }
refresh(params) {
this.setState({
value: params.value
});
return true;
}
} }
HorizontalBarComponent.propTypes = { HorizontalBarComponent.propTypes = {

View File

@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <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> <style>
html, body { html, body {

View File

@@ -5,12 +5,12 @@ import {render} from "react-dom";
import {Provider} from "react-redux"; import {Provider} from "react-redux";
import "ag-grid-root/dist/styles/ag-grid.css";
import "ag-grid-root/dist/styles/theme-fresh.css";
import StoreService from './services/StoreService'; import StoreService from './services/StoreService';
import TraderDashboard from "./components/TraderDashboard.jsx"; import TraderDashboard from "./components/TraderDashboard.jsx";
import "@ag-grid-enterprise/all-modules/dist/styles/ag-grid.css";
import "@ag-grid-enterprise/all-modules/dist/styles/ag-theme-fresh.css";
let store = StoreService.STORE; let store = StoreService.STORE;
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {

View File

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

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