├── .gitignore
├── Procfile
├── README.MD
├── build
├── asset-manifest.json
├── favicon.ico
├── font-awesome
│ ├── HELP-US-OUT.txt
│ ├── css
│ │ ├── font-awesome.css
│ │ └── font-awesome.min.css
│ ├── fonts
│ │ ├── FontAwesome.otf
│ │ ├── fontawesome-webfont.eot
│ │ ├── fontawesome-webfont.svg
│ │ ├── fontawesome-webfont.ttf
│ │ ├── fontawesome-webfont.woff
│ │ └── fontawesome-webfont.woff2
│ ├── less
│ │ ├── animated.less
│ │ ├── bordered-pulled.less
│ │ ├── core.less
│ │ ├── fixed-width.less
│ │ ├── font-awesome.less
│ │ ├── icons.less
│ │ ├── larger.less
│ │ ├── list.less
│ │ ├── mixins.less
│ │ ├── path.less
│ │ ├── rotated-flipped.less
│ │ ├── screen-reader.less
│ │ ├── stacked.less
│ │ └── variables.less
│ └── scss
│ │ ├── _animated.scss
│ │ ├── _bordered-pulled.scss
│ │ ├── _core.scss
│ │ ├── _fixed-width.scss
│ │ ├── _icons.scss
│ │ ├── _larger.scss
│ │ ├── _list.scss
│ │ ├── _mixins.scss
│ │ ├── _path.scss
│ │ ├── _rotated-flipped.scss
│ │ ├── _screen-reader.scss
│ │ ├── _stacked.scss
│ │ ├── _variables.scss
│ │ └── font-awesome.scss
├── index.html
└── static
│ ├── css
│ ├── main.048b16d4.css
│ └── main.048b16d4.css.map
│ ├── js
│ ├── main.f685c311.js
│ └── main.f685c311.js.map
│ └── media
│ ├── github-square.df8a65b0.svg
│ ├── glyphicons-halflings-regular.448c34a5.woff2
│ ├── glyphicons-halflings-regular.89889688.svg
│ ├── glyphicons-halflings-regular.e18bbf61.ttf
│ ├── glyphicons-halflings-regular.f4769f9b.eot
│ ├── glyphicons-halflings-regular.fa277232.woff
│ ├── gridBlueIcon.426cc68f.svg
│ ├── gridGrey.8ab09ac7.svg
│ ├── gridPurpleIcon.b424db63.svg
│ ├── react.5d5d9eef.svg
│ ├── reactReduxGrid.fbd0480c.svg
│ ├── redux.5ae1af16.svg
│ ├── spinner.8c14c79f.gif
│ └── tiny_grid.c704d76c.png
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── font-awesome
│ ├── HELP-US-OUT.txt
│ ├── css
│ │ ├── font-awesome.css
│ │ └── font-awesome.min.css
│ ├── fonts
│ │ ├── FontAwesome.otf
│ │ ├── fontawesome-webfont.eot
│ │ ├── fontawesome-webfont.svg
│ │ ├── fontawesome-webfont.ttf
│ │ ├── fontawesome-webfont.woff
│ │ └── fontawesome-webfont.woff2
│ ├── less
│ │ ├── animated.less
│ │ ├── bordered-pulled.less
│ │ ├── core.less
│ │ ├── fixed-width.less
│ │ ├── font-awesome.less
│ │ ├── icons.less
│ │ ├── larger.less
│ │ ├── list.less
│ │ ├── mixins.less
│ │ ├── path.less
│ │ ├── rotated-flipped.less
│ │ ├── screen-reader.less
│ │ ├── stacked.less
│ │ └── variables.less
│ └── scss
│ │ ├── _animated.scss
│ │ ├── _bordered-pulled.scss
│ │ ├── _core.scss
│ │ ├── _fixed-width.scss
│ │ ├── _icons.scss
│ │ ├── _larger.scss
│ │ ├── _list.scss
│ │ ├── _mixins.scss
│ │ ├── _path.scss
│ │ ├── _rotated-flipped.scss
│ │ ├── _screen-reader.scss
│ │ ├── _stacked.scss
│ │ ├── _variables.scss
│ │ └── font-awesome.scss
└── index.html
├── server
├── api
│ ├── functions.js
│ ├── routes.js
│ └── services.js
├── config
│ ├── fakedata.js
│ ├── helpers.js
│ └── init.js
└── server.js
└── src
├── App.css
├── App.js
├── App.test.js
├── components
├── examples
│ ├── ColRenderer.js
│ ├── Editable.js
│ ├── ErrorMessage.js
│ ├── ExampleGridContainer.css
│ ├── ExampleGridContainer.js
│ ├── Simple.js
│ ├── Sticky.js
│ ├── Stress.js
│ ├── Tree.js
│ ├── bootstrap
│ │ ├── Bootstrap.js
│ │ ├── README.md
│ │ ├── css
│ │ │ ├── bootstrap-theme.css
│ │ │ ├── bootstrap-theme.css.map
│ │ │ ├── bootstrap-theme.min.css
│ │ │ ├── bootstrap-theme.min.css.map
│ │ │ ├── bootstrap.css
│ │ │ ├── bootstrap.css.map
│ │ │ ├── bootstrap.min.css
│ │ │ └── bootstrap.min.css.map
│ │ ├── fonts
│ │ │ ├── glyphicons-halflings-regular.eot
│ │ │ ├── glyphicons-halflings-regular.svg
│ │ │ ├── glyphicons-halflings-regular.ttf
│ │ │ ├── glyphicons-halflings-regular.woff
│ │ │ └── glyphicons-halflings-regular.woff2
│ │ └── js
│ │ │ ├── bootstrap.js
│ │ │ ├── bootstrap.min.js
│ │ │ └── npm.js
│ ├── bulk-selection
│ │ ├── BulkPager.js
│ │ ├── BulkSelection.js
│ │ ├── BulkSelection.test.js
│ │ └── getBulkSelectionSelectedRows.js
│ ├── complex
│ │ ├── Complex.js
│ │ └── Complex.test.js
│ ├── custom-loader
│ │ ├── CustomLoader.js
│ │ ├── loader.css
│ │ └── spinner.gif
│ ├── custom-pager
│ │ ├── Api.js
│ │ ├── CustomPager.js
│ │ ├── CustomPager.test.js
│ │ └── Pager.js
│ └── data
│ │ ├── Api.js
│ │ ├── demodata.js
│ │ ├── provider.js
│ │ ├── stressdata.js
│ │ └── treedata.json
├── footer
│ ├── Footer.css
│ ├── Footer.js
│ └── gridGrey.svg
├── header
│ ├── Header.css
│ ├── Header.js
│ ├── github-square.svg
│ ├── grid.svg
│ ├── react.svg
│ ├── reactReduxGrid.svg
│ ├── redux.svg
│ └── tiny_grid
│ │ ├── readme.txt
│ │ ├── tiny_grid.png
│ │ └── tiny_grid_@2X.png
├── instructions
│ ├── Instructions.css
│ └── Instructions.js
└── sidebar
│ ├── ExamplesSidebar.js
│ ├── FeaturesSidebar.js
│ ├── Sidebar.css
│ ├── gridBlueIcon.svg
│ └── gridPurpleIcon.svg
├── index.css
├── index.js
└── redux
├── actions
├── appActions.js
└── bulkSelectionActions.js
├── configureStore.js
├── configureStoreForTests.js
├── reducers
├── appReducers.js
├── bulkSelectionReducers.js
└── features.js
└── types
└── types.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 |
6 | # testing
7 | coverage
8 |
9 | # misc
10 | .DS_Store
11 | .env
12 | npm-debug.log
13 | yarn.lock
14 |
15 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: npm run prod
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | # React-Redux-Grid Examples
2 |
3 | A simple app displaying multiple grids with different features.
4 |
5 | [Examples Website](http://react-redux-grid.herokuapp.com/)
6 |
7 | The relevant (to grid) source code is located in:
8 |
9 | `/src/components/examples`
10 |
11 | ## Getting Started
12 |
13 | ```
14 | npm install
15 | npm start
16 | ```
17 | This will launch the examples website at http://localhost:3000 as well as a fake data API service on http://localhost:3001
18 |
19 | ## Contributing
20 |
21 | To begin creating an example, you can also simply copy an example folder and rename it.
22 |
23 | Feel free to install other libraries ( redux-sagas, etc) to demonstrate any new functionality in your example folder.
24 |
25 | When you add a new example, you will need to:
26 | 1. add a new example folder for your demo and provide at least one simple test that it renderers
27 | 2. add the new example data to features.js in redux/reducers
28 | 3. add the new route to index.js
29 |
30 | ## Tests
31 |
32 | We are using [jest](https://facebook.github.io/) & [enzyme](http://airbnb.io/enzyme) to manage our test suite with the goal of testing each example. We could use help here in testing the examples if you would like to contribute. Don't worry if you've never written tests before, this is good example site to learn.
33 |
34 | When you run the tests, they should all be passing. Please file a bug if you see any failing; better yet fix the fail and push an update!
35 |
36 | ```
37 | npm test
38 | ```
39 |
40 | ## Website
41 |
42 | We used create-react-app to build the website adding Redux & React-Redux-Grid.
43 |
44 | ```
45 | create-react-app folderName
46 | cd folderName
47 | npm i redux react-redux react-redux-grid redux-logger --save
48 | ```
49 |
50 | [shields.io](http://shields.io/)
51 |
52 | ## React-Redux-Grid
53 |
54 | This is examples site but the main library can be found here:
55 |
56 | 🍴[react-redux-grid on Github](https://github.com/bencripps/react-redux-grid)
57 | ⌛[react-redux-grid on NPM](https://www.npmjs.com/package/react-redux-grid)
58 |
--------------------------------------------------------------------------------
/build/asset-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "main.css": "static/css/main.048b16d4.css",
3 | "main.css.map": "static/css/main.048b16d4.css.map",
4 | "main.js": "static/js/main.f685c311.js",
5 | "main.js.map": "static/js/main.f685c311.js.map",
6 | "static/media/github-square.svg": "static/media/github-square.df8a65b0.svg",
7 | "static/media/glyphicons-halflings-regular.eot": "static/media/glyphicons-halflings-regular.f4769f9b.eot",
8 | "static/media/glyphicons-halflings-regular.svg": "static/media/glyphicons-halflings-regular.89889688.svg",
9 | "static/media/glyphicons-halflings-regular.ttf": "static/media/glyphicons-halflings-regular.e18bbf61.ttf",
10 | "static/media/glyphicons-halflings-regular.woff": "static/media/glyphicons-halflings-regular.fa277232.woff",
11 | "static/media/glyphicons-halflings-regular.woff2": "static/media/glyphicons-halflings-regular.448c34a5.woff2",
12 | "static/media/gridBlueIcon.svg": "static/media/gridBlueIcon.426cc68f.svg",
13 | "static/media/gridGrey.svg": "static/media/gridGrey.8ab09ac7.svg",
14 | "static/media/gridPurpleIcon.svg": "static/media/gridPurpleIcon.b424db63.svg",
15 | "static/media/react.svg": "static/media/react.5d5d9eef.svg",
16 | "static/media/reactReduxGrid.svg": "static/media/reactReduxGrid.fbd0480c.svg",
17 | "static/media/redux.svg": "static/media/redux.5ae1af16.svg",
18 | "static/media/spinner.gif": "static/media/spinner.8c14c79f.gif",
19 | "static/media/tiny_grid.png": "static/media/tiny_grid.c704d76c.png"
20 | }
--------------------------------------------------------------------------------
/build/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/build/favicon.ico
--------------------------------------------------------------------------------
/build/font-awesome/HELP-US-OUT.txt:
--------------------------------------------------------------------------------
1 | I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,
2 | Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,
3 | comprehensive icon sets or copy and paste your own.
4 |
5 | Please. Check it out.
6 |
7 | -Dave Gandy
8 |
--------------------------------------------------------------------------------
/build/font-awesome/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/build/font-awesome/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/build/font-awesome/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/build/font-awesome/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/build/font-awesome/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/build/font-awesome/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/build/font-awesome/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/build/font-awesome/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/build/font-awesome/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/build/font-awesome/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/build/font-awesome/less/animated.less:
--------------------------------------------------------------------------------
1 | // Animated Icons
2 | // --------------------------
3 |
4 | .@{fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .@{fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/build/font-awesome/less/bordered-pulled.less:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em @fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .@{fa-css-prefix}-pull-left { float: left; }
11 | .@{fa-css-prefix}-pull-right { float: right; }
12 |
13 | .@{fa-css-prefix} {
14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .@{fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/build/font-awesome/less/core.less:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .@{fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/build/font-awesome/less/fixed-width.less:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .@{fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/build/font-awesome/less/font-awesome.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables.less";
7 | @import "mixins.less";
8 | @import "path.less";
9 | @import "core.less";
10 | @import "larger.less";
11 | @import "fixed-width.less";
12 | @import "list.less";
13 | @import "bordered-pulled.less";
14 | @import "animated.less";
15 | @import "rotated-flipped.less";
16 | @import "stacked.less";
17 | @import "icons.less";
18 | @import "screen-reader.less";
19 |
--------------------------------------------------------------------------------
/build/font-awesome/less/larger.less:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .@{fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .@{fa-css-prefix}-2x { font-size: 2em; }
11 | .@{fa-css-prefix}-3x { font-size: 3em; }
12 | .@{fa-css-prefix}-4x { font-size: 4em; }
13 | .@{fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/build/font-awesome/less/list.less:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: @fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .@{fa-css-prefix}-li {
11 | position: absolute;
12 | left: -@fa-li-width;
13 | width: @fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.@{fa-css-prefix}-lg {
17 | left: (-@fa-li-width + (4em / 14));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/build/font-awesome/less/mixins.less:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | .fa-icon() {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
14 | .fa-icon-rotate(@degrees, @rotation) {
15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})";
16 | -webkit-transform: rotate(@degrees);
17 | -ms-transform: rotate(@degrees);
18 | transform: rotate(@degrees);
19 | }
20 |
21 | .fa-icon-flip(@horiz, @vert, @rotation) {
22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)";
23 | -webkit-transform: scale(@horiz, @vert);
24 | -ms-transform: scale(@horiz, @vert);
25 | transform: scale(@horiz, @vert);
26 | }
27 |
28 |
29 | // Only display content to screen readers. A la Bootstrap 4.
30 | //
31 | // See: http://a11yproject.com/posts/how-to-hide-content/
32 |
33 | .sr-only() {
34 | position: absolute;
35 | width: 1px;
36 | height: 1px;
37 | padding: 0;
38 | margin: -1px;
39 | overflow: hidden;
40 | clip: rect(0,0,0,0);
41 | border: 0;
42 | }
43 |
44 | // Use in conjunction with .sr-only to only display content when it's focused.
45 | //
46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
47 | //
48 | // Credit: HTML5 Boilerplate
49 |
50 | .sr-only-focusable() {
51 | &:active,
52 | &:focus {
53 | position: static;
54 | width: auto;
55 | height: auto;
56 | margin: 0;
57 | overflow: visible;
58 | clip: auto;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/build/font-awesome/less/path.less:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/build/font-awesome/less/rotated-flipped.less:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
7 |
8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .@{fa-css-prefix}-rotate-90,
15 | :root .@{fa-css-prefix}-rotate-180,
16 | :root .@{fa-css-prefix}-rotate-270,
17 | :root .@{fa-css-prefix}-flip-horizontal,
18 | :root .@{fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/build/font-awesome/less/screen-reader.less:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { .sr-only(); }
5 | .sr-only-focusable { .sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/build/font-awesome/less/stacked.less:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; }
21 |
--------------------------------------------------------------------------------
/build/font-awesome/scss/_animated.scss:
--------------------------------------------------------------------------------
1 | // Spinning Icons
2 | // --------------------------
3 |
4 | .#{$fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .#{$fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/build/font-awesome/scss/_bordered-pulled.scss:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em $fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .#{$fa-css-prefix}-pull-left { float: left; }
11 | .#{$fa-css-prefix}-pull-right { float: right; }
12 |
13 | .#{$fa-css-prefix} {
14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .#{$fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/build/font-awesome/scss/_core.scss:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/build/font-awesome/scss/_fixed-width.scss:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .#{$fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/build/font-awesome/scss/_larger.scss:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .#{$fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .#{$fa-css-prefix}-2x { font-size: 2em; }
11 | .#{$fa-css-prefix}-3x { font-size: 3em; }
12 | .#{$fa-css-prefix}-4x { font-size: 4em; }
13 | .#{$fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/build/font-awesome/scss/_list.scss:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: $fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .#{$fa-css-prefix}-li {
11 | position: absolute;
12 | left: -$fa-li-width;
13 | width: $fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.#{$fa-css-prefix}-lg {
17 | left: -$fa-li-width + (4em / 14);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/build/font-awesome/scss/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | @mixin fa-icon() {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
14 | @mixin fa-icon-rotate($degrees, $rotation) {
15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})";
16 | -webkit-transform: rotate($degrees);
17 | -ms-transform: rotate($degrees);
18 | transform: rotate($degrees);
19 | }
20 |
21 | @mixin fa-icon-flip($horiz, $vert, $rotation) {
22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)";
23 | -webkit-transform: scale($horiz, $vert);
24 | -ms-transform: scale($horiz, $vert);
25 | transform: scale($horiz, $vert);
26 | }
27 |
28 |
29 | // Only display content to screen readers. A la Bootstrap 4.
30 | //
31 | // See: http://a11yproject.com/posts/how-to-hide-content/
32 |
33 | @mixin sr-only {
34 | position: absolute;
35 | width: 1px;
36 | height: 1px;
37 | padding: 0;
38 | margin: -1px;
39 | overflow: hidden;
40 | clip: rect(0,0,0,0);
41 | border: 0;
42 | }
43 |
44 | // Use in conjunction with .sr-only to only display content when it's focused.
45 | //
46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
47 | //
48 | // Credit: HTML5 Boilerplate
49 |
50 | @mixin sr-only-focusable {
51 | &:active,
52 | &:focus {
53 | position: static;
54 | width: auto;
55 | height: auto;
56 | margin: 0;
57 | overflow: visible;
58 | clip: auto;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/build/font-awesome/scss/_path.scss:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/build/font-awesome/scss/_rotated-flipped.scss:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
7 |
8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .#{$fa-css-prefix}-rotate-90,
15 | :root .#{$fa-css-prefix}-rotate-180,
16 | :root .#{$fa-css-prefix}-rotate-270,
17 | :root .#{$fa-css-prefix}-flip-horizontal,
18 | :root .#{$fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/build/font-awesome/scss/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { @include sr-only(); }
5 | .sr-only-focusable { @include sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/build/font-awesome/scss/_stacked.scss:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; }
21 |
--------------------------------------------------------------------------------
/build/font-awesome/scss/font-awesome.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables";
7 | @import "mixins";
8 | @import "path";
9 | @import "core";
10 | @import "larger";
11 | @import "fixed-width";
12 | @import "list";
13 | @import "bordered-pulled";
14 | @import "animated";
15 | @import "rotated-flipped";
16 | @import "stacked";
17 | @import "icons";
18 | @import "screen-reader";
19 |
--------------------------------------------------------------------------------
/build/index.html:
--------------------------------------------------------------------------------
1 |
React App
--------------------------------------------------------------------------------
/build/static/css/main.048b16d4.css.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":[],"names":[],"mappings":"","file":"static/css/main.048b16d4.css","sourceRoot":""}
--------------------------------------------------------------------------------
/build/static/media/github-square.df8a65b0.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/build/static/media/glyphicons-halflings-regular.448c34a5.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/build/static/media/glyphicons-halflings-regular.448c34a5.woff2
--------------------------------------------------------------------------------
/build/static/media/glyphicons-halflings-regular.e18bbf61.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/build/static/media/glyphicons-halflings-regular.e18bbf61.ttf
--------------------------------------------------------------------------------
/build/static/media/glyphicons-halflings-regular.f4769f9b.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/build/static/media/glyphicons-halflings-regular.f4769f9b.eot
--------------------------------------------------------------------------------
/build/static/media/glyphicons-halflings-regular.fa277232.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/build/static/media/glyphicons-halflings-regular.fa277232.woff
--------------------------------------------------------------------------------
/build/static/media/gridBlueIcon.426cc68f.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/build/static/media/gridGrey.8ab09ac7.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/build/static/media/gridPurpleIcon.b424db63.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/build/static/media/react.5d5d9eef.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/build/static/media/reactReduxGrid.fbd0480c.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
37 |
38 |
39 |
40 |
50 |
51 |
52 |
53 |
56 |
57 |
62 |
63 |
66 |
67 |
68 |
69 |
72 |
73 |
74 |
75 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
--------------------------------------------------------------------------------
/build/static/media/redux.5ae1af16.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/build/static/media/spinner.8c14c79f.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/build/static/media/spinner.8c14c79f.gif
--------------------------------------------------------------------------------
/build/static/media/tiny_grid.c704d76c.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/build/static/media/tiny_grid.c704d76c.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "website",
3 | "version": "0.1.0",
4 | "private": true,
5 | "devDependencies": {
6 | "enzyme": "^2.7.1",
7 | "faker": "^3.1.0",
8 | "gh-pages": "^0.12.0",
9 | "react-addons-test-utils": "^15.4.2",
10 | "react-scripts": "0.8.5",
11 | "redux-logger": "^2.7.4"
12 | },
13 | "dependencies": {
14 | "body-parser": "^1.16.0",
15 | "concurrently": "^3.1.0",
16 | "express": "^4.14.0",
17 | "immutable": "^3.8.1",
18 | "isomorphic-fetch": "^2.2.1",
19 | "react": "^15.4.2",
20 | "react-dom": "^15.4.2",
21 | "react-redux": "^5.0.2",
22 | "react-redux-grid": "^5.5.2",
23 | "react-router": "^3.0.1",
24 | "react-router-redux": "^4.0.7",
25 | "redux": "^3.6.0",
26 | "redux-router": "^2.1.2",
27 | "redux-thunk": "^2.2.0",
28 | "serve-favicon": "^2.3.2"
29 | },
30 | "scripts": {
31 | "start": "concurrently --kill-others \"npm run api\" \"react-scripts start\" ",
32 | "prod": "npm run api",
33 | "build": "react-scripts build",
34 | "test": "react-scripts test --env=jsdom",
35 | "eject": "react-scripts eject",
36 | "api": "node ./server/server",
37 | "deploy": "npm run build&&gh-pages -d build"
38 | },
39 | "engines": {
40 | "node": "6.6.0",
41 | "npm": "3.10.8"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/public/favicon.ico
--------------------------------------------------------------------------------
/public/font-awesome/HELP-US-OUT.txt:
--------------------------------------------------------------------------------
1 | I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project,
2 | Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome,
3 | comprehensive icon sets or copy and paste your own.
4 |
5 | Please. Check it out.
6 |
7 | -Dave Gandy
8 |
--------------------------------------------------------------------------------
/public/font-awesome/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/public/font-awesome/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/public/font-awesome/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/public/font-awesome/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/public/font-awesome/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/public/font-awesome/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/public/font-awesome/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/public/font-awesome/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/public/font-awesome/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/public/font-awesome/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/public/font-awesome/less/animated.less:
--------------------------------------------------------------------------------
1 | // Animated Icons
2 | // --------------------------
3 |
4 | .@{fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .@{fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/public/font-awesome/less/bordered-pulled.less:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em @fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .@{fa-css-prefix}-pull-left { float: left; }
11 | .@{fa-css-prefix}-pull-right { float: right; }
12 |
13 | .@{fa-css-prefix} {
14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .@{fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/public/font-awesome/less/core.less:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .@{fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/public/font-awesome/less/fixed-width.less:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .@{fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/public/font-awesome/less/font-awesome.less:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables.less";
7 | @import "mixins.less";
8 | @import "path.less";
9 | @import "core.less";
10 | @import "larger.less";
11 | @import "fixed-width.less";
12 | @import "list.less";
13 | @import "bordered-pulled.less";
14 | @import "animated.less";
15 | @import "rotated-flipped.less";
16 | @import "stacked.less";
17 | @import "icons.less";
18 | @import "screen-reader.less";
19 |
--------------------------------------------------------------------------------
/public/font-awesome/less/larger.less:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .@{fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .@{fa-css-prefix}-2x { font-size: 2em; }
11 | .@{fa-css-prefix}-3x { font-size: 3em; }
12 | .@{fa-css-prefix}-4x { font-size: 4em; }
13 | .@{fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/public/font-awesome/less/list.less:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: @fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .@{fa-css-prefix}-li {
11 | position: absolute;
12 | left: -@fa-li-width;
13 | width: @fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.@{fa-css-prefix}-lg {
17 | left: (-@fa-li-width + (4em / 14));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/public/font-awesome/less/mixins.less:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | .fa-icon() {
5 | display: inline-block;
6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
14 | .fa-icon-rotate(@degrees, @rotation) {
15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})";
16 | -webkit-transform: rotate(@degrees);
17 | -ms-transform: rotate(@degrees);
18 | transform: rotate(@degrees);
19 | }
20 |
21 | .fa-icon-flip(@horiz, @vert, @rotation) {
22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)";
23 | -webkit-transform: scale(@horiz, @vert);
24 | -ms-transform: scale(@horiz, @vert);
25 | transform: scale(@horiz, @vert);
26 | }
27 |
28 |
29 | // Only display content to screen readers. A la Bootstrap 4.
30 | //
31 | // See: http://a11yproject.com/posts/how-to-hide-content/
32 |
33 | .sr-only() {
34 | position: absolute;
35 | width: 1px;
36 | height: 1px;
37 | padding: 0;
38 | margin: -1px;
39 | overflow: hidden;
40 | clip: rect(0,0,0,0);
41 | border: 0;
42 | }
43 |
44 | // Use in conjunction with .sr-only to only display content when it's focused.
45 | //
46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
47 | //
48 | // Credit: HTML5 Boilerplate
49 |
50 | .sr-only-focusable() {
51 | &:active,
52 | &:focus {
53 | position: static;
54 | width: auto;
55 | height: auto;
56 | margin: 0;
57 | overflow: visible;
58 | clip: auto;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/public/font-awesome/less/path.less:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/public/font-awesome/less/rotated-flipped.less:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
7 |
8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .@{fa-css-prefix}-rotate-90,
15 | :root .@{fa-css-prefix}-rotate-180,
16 | :root .@{fa-css-prefix}-rotate-270,
17 | :root .@{fa-css-prefix}-flip-horizontal,
18 | :root .@{fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/public/font-awesome/less/screen-reader.less:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { .sr-only(); }
5 | .sr-only-focusable { .sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/public/font-awesome/less/stacked.less:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .@{fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; }
21 |
--------------------------------------------------------------------------------
/public/font-awesome/scss/_animated.scss:
--------------------------------------------------------------------------------
1 | // Spinning Icons
2 | // --------------------------
3 |
4 | .#{$fa-css-prefix}-spin {
5 | -webkit-animation: fa-spin 2s infinite linear;
6 | animation: fa-spin 2s infinite linear;
7 | }
8 |
9 | .#{$fa-css-prefix}-pulse {
10 | -webkit-animation: fa-spin 1s infinite steps(8);
11 | animation: fa-spin 1s infinite steps(8);
12 | }
13 |
14 | @-webkit-keyframes fa-spin {
15 | 0% {
16 | -webkit-transform: rotate(0deg);
17 | transform: rotate(0deg);
18 | }
19 | 100% {
20 | -webkit-transform: rotate(359deg);
21 | transform: rotate(359deg);
22 | }
23 | }
24 |
25 | @keyframes fa-spin {
26 | 0% {
27 | -webkit-transform: rotate(0deg);
28 | transform: rotate(0deg);
29 | }
30 | 100% {
31 | -webkit-transform: rotate(359deg);
32 | transform: rotate(359deg);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/public/font-awesome/scss/_bordered-pulled.scss:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-border {
5 | padding: .2em .25em .15em;
6 | border: solid .08em $fa-border-color;
7 | border-radius: .1em;
8 | }
9 |
10 | .#{$fa-css-prefix}-pull-left { float: left; }
11 | .#{$fa-css-prefix}-pull-right { float: right; }
12 |
13 | .#{$fa-css-prefix} {
14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }
15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }
16 | }
17 |
18 | /* Deprecated as of 4.4.0 */
19 | .pull-right { float: right; }
20 | .pull-left { float: left; }
21 |
22 | .#{$fa-css-prefix} {
23 | &.pull-left { margin-right: .3em; }
24 | &.pull-right { margin-left: .3em; }
25 | }
26 |
--------------------------------------------------------------------------------
/public/font-awesome/scss/_core.scss:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix} {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/public/font-awesome/scss/_fixed-width.scss:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .#{$fa-css-prefix}-fw {
4 | width: (18em / 14);
5 | text-align: center;
6 | }
7 |
--------------------------------------------------------------------------------
/public/font-awesome/scss/_larger.scss:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | /* makes the font 33% larger relative to the icon container */
5 | .#{$fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -15%;
9 | }
10 | .#{$fa-css-prefix}-2x { font-size: 2em; }
11 | .#{$fa-css-prefix}-3x { font-size: 3em; }
12 | .#{$fa-css-prefix}-4x { font-size: 4em; }
13 | .#{$fa-css-prefix}-5x { font-size: 5em; }
14 |
--------------------------------------------------------------------------------
/public/font-awesome/scss/_list.scss:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-ul {
5 | padding-left: 0;
6 | margin-left: $fa-li-width;
7 | list-style-type: none;
8 | > li { position: relative; }
9 | }
10 | .#{$fa-css-prefix}-li {
11 | position: absolute;
12 | left: -$fa-li-width;
13 | width: $fa-li-width;
14 | top: (2em / 14);
15 | text-align: center;
16 | &.#{$fa-css-prefix}-lg {
17 | left: -$fa-li-width + (4em / 14);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/public/font-awesome/scss/_mixins.scss:
--------------------------------------------------------------------------------
1 | // Mixins
2 | // --------------------------
3 |
4 | @mixin fa-icon() {
5 | display: inline-block;
6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration
7 | font-size: inherit; // can't have font-size inherit on line above, so need to override
8 | text-rendering: auto; // optimizelegibility throws things off #1094
9 | -webkit-font-smoothing: antialiased;
10 | -moz-osx-font-smoothing: grayscale;
11 |
12 | }
13 |
14 | @mixin fa-icon-rotate($degrees, $rotation) {
15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})";
16 | -webkit-transform: rotate($degrees);
17 | -ms-transform: rotate($degrees);
18 | transform: rotate($degrees);
19 | }
20 |
21 | @mixin fa-icon-flip($horiz, $vert, $rotation) {
22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)";
23 | -webkit-transform: scale($horiz, $vert);
24 | -ms-transform: scale($horiz, $vert);
25 | transform: scale($horiz, $vert);
26 | }
27 |
28 |
29 | // Only display content to screen readers. A la Bootstrap 4.
30 | //
31 | // See: http://a11yproject.com/posts/how-to-hide-content/
32 |
33 | @mixin sr-only {
34 | position: absolute;
35 | width: 1px;
36 | height: 1px;
37 | padding: 0;
38 | margin: -1px;
39 | overflow: hidden;
40 | clip: rect(0,0,0,0);
41 | border: 0;
42 | }
43 |
44 | // Use in conjunction with .sr-only to only display content when it's focused.
45 | //
46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
47 | //
48 | // Credit: HTML5 Boilerplate
49 |
50 | @mixin sr-only-focusable {
51 | &:active,
52 | &:focus {
53 | position: static;
54 | width: auto;
55 | height: auto;
56 | margin: 0;
57 | overflow: visible;
58 | clip: auto;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/public/font-awesome/scss/_path.scss:
--------------------------------------------------------------------------------
1 | /* FONT PATH
2 | * -------------------------- */
3 |
4 | @font-face {
5 | font-family: 'FontAwesome';
6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
--------------------------------------------------------------------------------
/public/font-awesome/scss/_rotated-flipped.scss:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); }
5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }
6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }
7 |
8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }
9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); }
10 |
11 | // Hook for IE8-9
12 | // -------------------------
13 |
14 | :root .#{$fa-css-prefix}-rotate-90,
15 | :root .#{$fa-css-prefix}-rotate-180,
16 | :root .#{$fa-css-prefix}-rotate-270,
17 | :root .#{$fa-css-prefix}-flip-horizontal,
18 | :root .#{$fa-css-prefix}-flip-vertical {
19 | filter: none;
20 | }
21 |
--------------------------------------------------------------------------------
/public/font-awesome/scss/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only { @include sr-only(); }
5 | .sr-only-focusable { @include sr-only-focusable(); }
6 |
--------------------------------------------------------------------------------
/public/font-awesome/scss/_stacked.scss:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-stack {
5 | position: relative;
6 | display: inline-block;
7 | width: 2em;
8 | height: 2em;
9 | line-height: 2em;
10 | vertical-align: middle;
11 | }
12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x {
13 | position: absolute;
14 | left: 0;
15 | width: 100%;
16 | text-align: center;
17 | }
18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; }
19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; }
20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; }
21 |
--------------------------------------------------------------------------------
/public/font-awesome/scss/font-awesome.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome
3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
4 | */
5 |
6 | @import "variables";
7 | @import "mixins";
8 | @import "path";
9 | @import "core";
10 | @import "larger";
11 | @import "fixed-width";
12 | @import "list";
13 | @import "bordered-pulled";
14 | @import "animated";
15 | @import "rotated-flipped";
16 | @import "stacked";
17 | @import "icons";
18 | @import "screen-reader";
19 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
20 | React App
21 |
22 |
23 |
24 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/server/api/functions.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const dataObj = require('../config/fakedata');
4 | const url = require('url');
5 | const path = require('path');
6 |
7 | module.exports = class Functions {
8 | constructor() {
9 |
10 | }
11 |
12 | idx(vars, req, res) {
13 | res.render(vars.routeName, this.app.helper.template({env: this.env, vars: vars}));
14 | }
15 |
16 | main(vars, req, res) {
17 | res.sendFile(path.join(__dirname, './../../build', 'index.html'));
18 | }
19 |
20 | getFakeData(vars, req, res) {
21 | const reqURL = url.parse(req.url, true);
22 | const json = reqURL.query;
23 |
24 | res.setHeader('Access-Control-Allow-Origin', '*');
25 |
26 | const pageIndex = Number(json.pageIndex !== undefined ? json.pageIndex : 0);
27 | const pageSize = Number(json.pageSize || 20);
28 |
29 | const total = dataObj.data.length;
30 | const pages = dataObj.data.slice(pageIndex * pageSize, (pageIndex + 1) * pageSize);
31 |
32 | res.json({
33 | data: pages,
34 | total: total
35 | });
36 | }
37 |
38 | getFakedPagedDataForBootstrap(vars, req, res) {
39 | const reqURL = url.parse(req.url, true);
40 | const json = reqURL.query;
41 |
42 | res.setHeader('Access-Control-Allow-Origin', '*');
43 |
44 | const pageIndex = Number(json.pageIndex !== undefined ? json.pageIndex : 0);
45 | const pageSize = Number(json.pageSize || 20);
46 |
47 | const rows = dataObj.data.slice(1);
48 |
49 | const total = rows.length;
50 | const pages = rows.slice(pageIndex * pageSize, (pageIndex + 1) * pageSize);
51 |
52 | res.json({
53 | data: pages,
54 | total: total
55 | });
56 | }
57 |
58 |
59 |
60 | getPrefetchData(vars, req, res) {
61 | const reqURL = url.parse(req.url, true);
62 | const json = reqURL.query;
63 |
64 | const pageIndex = json.pageIndex !== undefined ? json.pageIndex : 0;
65 | const pageSize = json.pageSize || 25;
66 | const total = dataObj.data.length;
67 | const pages = dataObj.data.slice(pageIndex * (pageSize * 2), ((pageIndex) + 1) * (pageSize * 2));
68 |
69 | res.setHeader('Access-Control-Allow-Origin', '*');
70 |
71 | res.json({
72 | data: pages,
73 | total: total
74 | });
75 | }
76 |
77 | getTreeData(vars, req, res) {
78 |
79 | const reqURL = url.parse(req.url, true);
80 | const json = reqURL.query;
81 |
82 | res.setHeader('Access-Control-Allow-Origin', '*');
83 |
84 | if (json && json.parentId) {
85 | res.json({
86 | partial: true,
87 | data: [
88 | {
89 | id: 211,
90 | parentId: 21,
91 | Name: 'Category 211',
92 | GUID: '8f7q2dc-facf-91865',
93 | Email: 'hehehe@ed.gov',
94 | Gender: 'Male',
95 | Address: '21112 Park',
96 | 'Phone Number': '31-(678)495-4134'
97 | },
98 | {
99 | id: 212,
100 | parentId: 21,
101 | Name: 'Category 212',
102 | GUID: 'q2dc-facf-527fcsw-jdjd991865',
103 | Email: 'hehehe@ed.gov',
104 | Gender: 'Male',
105 | Address: '21112 Park',
106 | 'Phone Number': '31-(678)495-4134',
107 | children: [
108 | {
109 | id: 2121,
110 | parentId: 212,
111 | Name: 'Category 2121',
112 | GUID: 'q2dc-facf-527fcsw-sss865',
113 | Email: 'hehehe@ed.gov',
114 | Gender: 'Male',
115 | Address: '21112 Park',
116 | 'Phone Number': '31-(678)495-4134'
117 | }
118 | ]
119 | }
120 | ]
121 | });
122 | }
123 |
124 | else {
125 | res.json({
126 | data: dataObj.treeData
127 | });
128 | }
129 |
130 | }
131 |
132 | getFakeDataPaged(vars, req, res) {
133 | const json = JSON.parse(Object.keys(req.body)[0]);
134 | const pageIndex = json.pageIndex;
135 | const pageSize = json.pageSize;
136 | const total = dataObj.data.length;
137 | const pages = dataObj.data.slice(pageIndex * pageSize, (pageIndex + 1) * pageSize);
138 |
139 | res.setHeader('Access-Control-Allow-Origin', '*');
140 | res.json({
141 | data: pages,
142 | total: total
143 | });
144 | }
145 |
146 | };
--------------------------------------------------------------------------------
/server/api/routes.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: ben_cripps
3 | * @Date: 2015-05-18 20:58:33
4 | * @Last Modified by: ben_cripps
5 | * @Last Modified time: 2017-01-25 09:24:37
6 | */
7 |
8 | const Functions = require('./functions');
9 |
10 | const funcs = new Functions();
11 | module.exports = [
12 | {
13 | uri: '/getFakeData',
14 | method: 'get',
15 | func: funcs.getFakeData,
16 | vars: {}
17 | },
18 | {
19 | uri: '/getFakedPagedDataForBootstrap',
20 | method: 'get',
21 | func: funcs.getFakedPagedDataForBootstrap,
22 | vars: {}
23 | },
24 | {
25 | uri: '/getFakedPagedData',
26 | method: 'post',
27 | func: funcs.getFakeDataPaged,
28 | vars: {}
29 | },
30 | {
31 | uri: '/getTreeData',
32 | method: 'get',
33 | func: funcs.getTreeData,
34 | vars: {}
35 | },
36 | {
37 | uri: '/getPrefetchData',
38 | method: 'get',
39 | func: funcs.getPrefetchData,
40 | vars: {}
41 | },
42 | {
43 | uri: '/',
44 | method: 'get',
45 | func: funcs.main,
46 | vars: {}
47 | },
48 | {
49 | uri: '*',
50 | method: 'get',
51 | func: funcs.main,
52 | vars: {}
53 | }
54 | ];
--------------------------------------------------------------------------------
/server/api/services.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: ben_cripps
3 | * @Date: 2015-05-18 20:33:19
4 | * @Last Modified by: ben_cripps
5 | * @Last Modified time: 2016-05-31 20:42:41
6 | */
7 |
8 | 'use strict';
9 |
10 | const routes = require('./routes');
11 |
12 | module.exports = class Api {
13 | constructor(app) {
14 | this.app = app.server;
15 | this.env = app.env;
16 | this.initRoutes();
17 | }
18 | initRoutes() {
19 | routes.forEach((route) => this.app[route.method](route.uri, route.func.bind(this, route.vars)), this);
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/server/config/helpers.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: ben_cripps
3 | * @Date: 2015-05-22 14:29:47
4 | * @Last Modified by: ben_cripps
5 | * @Last Modified time: 2016-08-07 08:01:21
6 | */
7 | 'use strict';
8 |
9 | module.exports = class Helper {
10 | constructor() {
11 | this.template = this.templateFunc;
12 | }
13 | templateFunc(obj) {
14 |
15 | let base = {
16 | baseDir: '',
17 | routes: [
18 | {
19 | name: 'home',
20 | uri: '/'
21 | },
22 | {
23 | name: 'about',
24 | uri: '/about'
25 | },
26 | {
27 | name: 'blogs',
28 | uri: '/blog'
29 | },
30 | {
31 | name: 'projects',
32 | uri: '/projects'
33 | }
34 | ]
35 | };
36 |
37 | Object.keys(obj).map((k) => {
38 | if (k === 'vars') {
39 | Object.keys(obj[k]).forEach((internalK) => {
40 | base[internalK] = obj[k][internalK];
41 | });
42 | }
43 | else {
44 | base[k] = obj[k];
45 | }
46 | });
47 |
48 | return base;
49 |
50 | }
51 | }
--------------------------------------------------------------------------------
/server/config/init.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: ben_cripps
3 | * @Date: 2015-05-18 19:34:42
4 | * @Last Modified by: ben_cripps
5 | * @Last Modified time: 2017-01-25 09:39:34
6 | */
7 |
8 | 'use strict';
9 |
10 | const path = require('path');
11 | const Helper = require('./helpers.js');
12 |
13 | module.exports = class App {
14 |
15 | constructor(args) {
16 | this.env = args.length === 3 && args[2] === 'dev' ? args[2] : 'min';
17 | this.server = this.init(
18 | require('express'),
19 | require('body-parser'),
20 | require('serve-favicon')
21 | );
22 | }
23 |
24 | init(express, bodyParser, favicon) {
25 |
26 | const app = express()
27 | .set('port', process.env.PORT || 3001)
28 | .set('views', path.join(__dirname, '/../views'))
29 | .set('view engine', 'jade')
30 | .use(express.static('build'))
31 | .use(bodyParser.json())
32 | .use(bodyParser.urlencoded({extended: true}));
33 |
34 | app.helper = new Helper();
35 |
36 | return app;
37 | }
38 |
39 | }
--------------------------------------------------------------------------------
/server/server.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: ben_cripps
3 | * @Date: 2014-12-01 10:10:44
4 | * @Last Modified by: ben_cripps
5 | * @Last Modified time: 2016-05-31 20:38:50
6 | */
7 |
8 | const App = require('./config/init');
9 | const Api = require('./api/services');
10 |
11 | const app = new App(process.argv);
12 | const api = new Api(app);
13 |
14 | app.server.listen(app.server.get('port'), () => {
15 | console.log('The API is running in ' +
16 | (app.env === 'dev' ? app.env : 'prod') +
17 | ' mode, on port ' + app.server.get('port'));
18 | });
19 |
20 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .app {
2 | display: block;
3 | position: relative;
4 | }
5 |
6 | .split {
7 | display: flex;
8 | flex-direction: row;
9 | justify-content: flex-start;
10 | margin-left: 10px;
11 | margin-right: 10px;
12 | }
13 |
14 | .purpleHilite {
15 | color: #663399;
16 | }
17 |
18 | .tableContainer {
19 | display: block;
20 | position: relative;
21 | }
22 |
23 | ul {
24 | list-style-type: none;
25 | margin: 0px;
26 | margin-left: 0px;
27 | padding: 0px;
28 | padding-left: 5px;
29 | }
30 |
31 | li {
32 | margin: 0px;
33 | padding: 0px;
34 | }
35 |
36 | .react-redux-grid-active, .react-redux-grid-inactive {
37 | margin: 5px;
38 | border-radius: 5px;
39 | background-color: #49b8dc;
40 | }
41 |
42 | .react-redux-grid-active {
43 | color: white;
44 | background-color: #644581;
45 | }
46 |
47 | .gridH2 {
48 | font-family: 'Bree Serif', serif;
49 | font-size: 18px;
50 | color: #49b8dc;
51 | font-weight: normal;
52 | margin: 0px;
53 | margin-bottom: 10px;
54 | padding: 0px;
55 | margin-top: 10px;
56 | }
57 |
58 |
59 |
60 | :focus {
61 | border: none;
62 | outline: none;
63 | };
64 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Header from './components/header/Header';
3 | import ExamplesSidebar from './components/sidebar/ExamplesSidebar';
4 | import FeaturesSidebar from './components/sidebar/FeaturesSidebar';
5 | import Footer from './components/footer/Footer';
6 | import './App.css';
7 |
8 | class App extends Component {
9 |
10 | render() {
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | {this.props.children}
21 |
22 |
23 |
24 |
25 |
26 | );
27 | }
28 |
29 | componentDidMount() {
30 | document.title = 'React-Redux-Grid';
31 | }
32 | }
33 |
34 | export default App;
35 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 | import { Provider } from 'react-redux';
5 | import store from './redux/configureStoreForTests';
6 |
7 | describe(' ', () => {
8 | it('renders without crashing', () => {
9 | const div = document.createElement('div');
10 |
11 | ReactDOM.render(
12 |
13 |
14 | ,
15 | div
16 | );
17 | })
18 | });
19 |
--------------------------------------------------------------------------------
/src/components/examples/ColRenderer.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { PropTypes } from 'react';
3 | import { Grid } from 'react-redux-grid';
4 |
5 | import {
6 | data,
7 | pageSize,
8 | events,
9 | dataSource
10 | } from './data/demodata';
11 |
12 | export const ColRenderer = ({ store }) => {
13 |
14 | const cols = [{
15 | name: 'Phone',
16 | dataIndex: 'phone number',
17 | renderer: (ob) => {
18 |
19 | const imgProps = {
20 | src: '//icons.iconarchive.com/icons/icons8/windows-8/512/Mobile-Phone-icon.png',
21 | style: {
22 | height: '20px'
23 | }
24 | };
25 |
26 | const spanProps = {
27 | style: {
28 | position: 'relative',
29 | top: '-5px',
30 | left: '10px'
31 | }
32 | };
33 |
34 | return (
35 |
36 |
37 |
38 | { ob.row['Phone Number'] }
39 |
40 |
41 | );
42 | }
43 | }];
44 |
45 | const colData = {
46 | columns: cols,
47 | data,
48 | pageSize,
49 | plugins: {},
50 | events,
51 | dataSource,
52 | store,
53 | stateKey: 'colRenderer'
54 | };
55 |
56 | return (
57 |
58 | );
59 | };
60 |
61 | const { object } = PropTypes;
62 |
63 | ColRenderer.propTypes = {
64 | store: object.isRequired
65 | };
66 |
67 | ColRenderer.defaultProps = {};
68 |
69 | export default ColRenderer;
--------------------------------------------------------------------------------
/src/components/examples/Editable.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { Component, PropTypes } from 'react';
3 | import { Grid } from 'react-redux-grid';
4 |
5 | import {
6 | columns,
7 | data,
8 | pageSize,
9 | events,
10 | dataSource
11 | } from './data/demodata';
12 |
13 | export class Editable extends Component {
14 |
15 | render() {
16 |
17 | const { store } = this.props;
18 | const { on } = this.state;
19 |
20 | const editableProps = {
21 | columns,
22 | data: on ? [] : data,
23 | pageSize,
24 | plugins: {
25 | EDITOR: {
26 | enabled: true,
27 | type: 'grid'
28 | }
29 | },
30 | events,
31 | store,
32 | stateKey: 'editable'
33 | };
34 |
35 | return ;
36 | }
37 |
38 | constructor(props) {
39 | super(props);
40 | this.state = {};
41 | }
42 |
43 | handleClick = () => {
44 | const { on } = this.state;
45 | this.setState({ on: !on });
46 | }
47 | }
48 |
49 | const { object } = PropTypes;
50 |
51 | Editable.propTypes = {
52 | store: object.isRequired
53 | };
54 |
55 | Editable.defaultProps = {};
56 |
57 | export default Editable;
--------------------------------------------------------------------------------
/src/components/examples/ErrorMessage.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { Component, PropTypes } from 'react';
3 | import { Grid, Actions } from 'react-redux-grid';
4 |
5 | import {
6 | columns,
7 | data,
8 | pageSize,
9 | events,
10 | dataSource
11 | } from './data/demodata';
12 |
13 | export class ErrorMessage extends Component {
14 | componentDidMount() {
15 | const { store } = this.props;
16 |
17 | store.dispatch(
18 | Actions.ErrorHandlerActions.setError({
19 | stateKey: 'error',
20 | error: 'An error occurred!'
21 | })
22 | );
23 | }
24 |
25 | render() {
26 | const errorData = {
27 | columns,
28 | data: [],
29 | pageSize,
30 | plugins: {
31 | ERROR_HANDLER: {
32 | defaultErrorMessage: 'AN ERROR OCURRED',
33 | enabled: true
34 | }
35 | },
36 | events,
37 | store: this.props.store,
38 | stateKey: 'error'
39 | };
40 |
41 | return (
42 |
43 | );
44 | }
45 | };
46 |
47 | const { object } = PropTypes;
48 |
49 | ErrorMessage.propTypes = {
50 | store: object.isRequired
51 | };
52 |
53 | ErrorMessage.defaultProps = {};
54 |
55 | export default ErrorMessage;
--------------------------------------------------------------------------------
/src/components/examples/ExampleGridContainer.css:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | .simpleContainer {
3 | display: block;
4 | position: relative;
5 | padding-left: 10px;
6 | padding-right: 10px;
7 | width: auto;
8 | }
9 |
10 | /* override React-Redux-Grid library */
11 | .react-grid-pager-toolbar {
12 | height: 40px !important;
13 | padding: 5px !important;
14 |
15 | }
16 |
17 | .react-grid-header-fixed-container th {
18 | padding-left: 10px !important;
19 | background: transparent !important;
20 | overflow: visible !important;
21 | }
22 |
23 | .react-grid-pager-toolbar span {
24 | font-size: 12px !important;
25 | color: #666;
26 | }
27 |
28 | /* override Bootstrap library */
29 | .bootstrap-description {
30 | height: 30px !important;
31 | margin: 5px !important;
32 | }
33 |
34 | .bootstrap-description span {
35 | font-size: 12px !important;
36 | color: #666;
37 | }
38 |
39 | .bootstrap-description button {
40 | margin-right: 10px;
41 | }
42 |
43 | .table-responsive thead {
44 | display: none !important;
45 | }
46 |
47 | input[type="text"] {
48 | color: #000;
49 | height: 20px;
50 | border-radius: 5px;
51 | border-width: 0px;
52 | width: 100%;
53 | padding-left: 5px;
54 | background-color: #f9f9f9;
55 | }
56 |
57 | .react-grid-edit {
58 | background-color: #e4e4e4 !important;
59 | }
60 |
61 | .react-grid-button-container {
62 | background-color: #e4e4e4 !important;
63 | padding: 5px !important;
64 | }
65 |
66 | .react-grid-cancel-button {
67 | margin-right: 5px;
68 | font-size: 12px;
69 | font-weight: bold;
70 | }
71 |
72 | .react-grid-save-button {
73 | font-size: 12px;
74 | font-weight: bold;
75 | background-color: #663399 !important;
76 | }
77 |
78 | .react-grid-sort-handle {
79 | cursor: pointer;
80 | width: 20px;
81 | height: 20px;
82 | padding-left: 5px;
83 | }
84 |
85 | th {
86 | cursor: pointer;
87 | font-size: 12px;
88 | font-weight: bold;
89 | font-family: 'Open Sans', sans-serif;
90 | }
91 |
92 | button.react-redux-grid-active, button.react-redux-grid-inactive {
93 | border: none !important;
94 | }
95 |
--------------------------------------------------------------------------------
/src/components/examples/ExampleGridContainer.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { Component } from 'react';
3 | import './ExampleGridContainer.css';
4 | import { connect } from 'react-redux';
5 | import store from './../../redux/configureStore';
6 | import Simple from './Simple';
7 | import Complex from './complex/Complex';
8 | import Sticky from './Sticky';
9 | import Stress from './Stress';
10 | import ColRenderer from './ColRenderer';
11 | import Tree from './Tree';
12 | import Bootstrap from './bootstrap/Bootstrap';
13 | import Editable from './Editable';
14 | import CustomPager from './custom-pager/CustomPager';
15 | import ErrorMessage from './ErrorMessage';
16 | import BulkSelection from './bulk-selection/BulkSelection';
17 | import * as _ from "lodash";
18 | import CustomLoader from './custom-loader/CustomLoader';
19 | import getBulkSelectionSelectedRows from './bulk-selection/getBulkSelectionSelectedRows';
20 |
21 |
22 | class ExampleGridContainer extends Component {
23 |
24 | componentWillReceiveProps(nextProps, nextState){
25 | this.props = nextProps;
26 | }
27 |
28 | shouldComponentUpdate(){
29 | return true;
30 | }
31 |
32 | render() {
33 |
34 | const title = this.props.app.featureTitle;
35 |
36 | const getGrid = (title) => {
37 | switch(title) {
38 | case "BulkSelection" :
39 | return ( );
40 | case "Bootstrap" :
41 | return ( );
42 | case "ColRenderer" :
43 | return ( );
44 | case "Tree" :
45 | return ( );
46 | case "Stress" :
47 | return ( );
48 | case "Sticky" :
49 | return ( );
50 | case "Editable" :
51 | return ( );
52 | case "Complex" :
53 | return ( );
54 | case "CustomPager" :
55 | return ( );
56 | case "CustomLoader" :
57 | return ( );
58 | case "ErrorMessage" :
59 | return ( );
60 | case "Simple" :
61 | default :
62 | return ( );
63 | }
64 | }
65 |
66 | return (
67 |
68 |
{this.props.app.featureTitle}
69 | { getBulkSelectionSelectedRows(this.props) }
70 | { getGrid(title) }
71 |
72 | );
73 | }
74 | }
75 |
76 | const mapStateToProps = (state) => ({
77 | faker: state.faker,
78 | grid: state.grid,
79 | app: state.app,
80 | bulkSelection: state.bulkSelection,
81 | selection: state.selection
82 | });
83 |
84 | const mapDispatchToProps = (dispatch) => {
85 | return {
86 | dispatch
87 | }
88 | };
89 | export default connect(mapStateToProps, mapDispatchToProps)(ExampleGridContainer);
--------------------------------------------------------------------------------
/src/components/examples/Simple.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { PropTypes } from 'react';
3 | import { Grid } from 'react-redux-grid';
4 |
5 | import {
6 | columns,
7 | data,
8 | pageSize,
9 | events,
10 | dataSource
11 | } from './data/demodata';
12 |
13 | export const Simple = ({ store }) => {
14 |
15 | const simpleData = {
16 | columns,
17 | data,
18 | pageSize,
19 | plugins: {},
20 | events,
21 | store,
22 | stateKey: 'simple'
23 | };
24 |
25 | return (
26 |
27 | );
28 | };
29 |
30 | const { object } = PropTypes;
31 |
32 | Simple.propTypes = {
33 | store: object.isRequired
34 | };
35 |
36 | Simple.defaultProps = {};
37 |
38 | export default Simple;
--------------------------------------------------------------------------------
/src/components/examples/Sticky.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { PropTypes } from 'react';
3 | import { Grid } from 'react-redux-grid';
4 |
5 | import {
6 | columns,
7 | data,
8 | pageSize,
9 | events,
10 | plugins
11 | } from './data/demodata';
12 |
13 | export const Sticky = ({ store }) => {
14 |
15 | const stickyData = {
16 | columns,
17 | data,
18 | pageSize,
19 | plugins: {
20 | ...plugins,
21 | STICKY_HEADER: {
22 | enabled: true
23 | },
24 | STICKY_FOOTER: {
25 | enabled: true
26 | },
27 | FILTER_CONTAINER: {
28 | enabled: false
29 | },
30 | BULK_ACTIONS: {
31 | enabled: false
32 | }
33 | },
34 | height: '',
35 | events,
36 | store,
37 | stateKey: 'sticky'
38 | };
39 |
40 | return (
41 |
42 | );
43 | };
44 |
45 | const { object } = PropTypes;
46 |
47 | Sticky.propTypes = {
48 | store: object.isRequired
49 | };
50 |
51 | Sticky.defaultProps = {};
52 |
53 | export default Sticky;
--------------------------------------------------------------------------------
/src/components/examples/Stress.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { PropTypes } from 'react';
3 | import { Grid } from 'react-redux-grid';
4 |
5 | import {
6 | stressData
7 | } from './data/demodata';
8 |
9 | export const Stress = ({ store }) => {
10 |
11 | const stateKey = 'stress';
12 |
13 | const stressProps = {
14 | columns: [
15 | {
16 | name: 'Name',
17 | width: '10%',
18 | className: 'additional-class',
19 | dataIndex: 'Name',
20 | sortable: false
21 | },
22 | {
23 | name: 'Phone Number',
24 | width: '20%',
25 | dataIndex: 'Phone Number',
26 | sortable: false
27 | },
28 | {
29 | name: 'Email',
30 | width: '25%',
31 | dataIndex: 'Email',
32 | sortable: false
33 | },
34 | {
35 | name: 'Address',
36 | dataIndex: 'Address',
37 | sortable: false
38 | }
39 | ],
40 | data: stressData,
41 | pageSize: stressData.length,
42 | infinite: true,
43 | plugins: {
44 | PAGER: {
45 | enabled: false
46 | }
47 | },
48 | events: {},
49 | store,
50 | stateKey
51 | };
52 |
53 | return (
54 |
55 | );
56 | };
57 |
58 | const { object } = PropTypes;
59 |
60 | Stress.propTypes = {
61 | store: object.isRequired
62 | };
63 |
64 | Stress.defaultProps = {};
65 |
66 | export default Stress;
--------------------------------------------------------------------------------
/src/components/examples/Tree.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { PropTypes } from 'react';
3 | import { Grid, Actions } from 'react-redux-grid';
4 |
5 | import {
6 | columns,
7 | data,
8 | pageSize,
9 | events,
10 | plugins,
11 | treeDataSource
12 | } from './data/demodata';
13 |
14 | export const Tree = ({ store }) => {
15 |
16 | const stateKey = 'tree';
17 |
18 | const complexData = {
19 | showTreeRootNode: false,
20 | dataSource: treeDataSource,
21 | gridType: 'tree',
22 | dragAndDrop: true,
23 | columns: [
24 | {
25 | name: 'Name',
26 | width: '30%',
27 | className: 'additional-class',
28 | dataIndex: 'Name',
29 | sortable: false,
30 | expandable: true
31 | },
32 | {
33 | name: 'Phone Number',
34 | dataIndex: 'Phone Number',
35 | sortable: false,
36 | className: 'additional-class'
37 | },
38 | {
39 | name: 'Email',
40 | dataIndex: 'Email',
41 | sortable: false,
42 | className: 'additional-class',
43 | defaultSortDirection: 'descend'
44 | },
45 | {
46 | name: 'Address',
47 | dataIndex: 'Address',
48 | sortable: false,
49 | className: 'additional-class'
50 | }
51 | ],
52 | data,
53 | plugins: {
54 | ...plugins,
55 | GRID_ACTIONS: null,
56 | SELECTION_MODEL: {
57 | mode: 'single'
58 | },
59 | PAGER: {
60 | enabled: false
61 | },
62 | BULK_ACTIONS: {
63 | enabled: false
64 | }
65 | },
66 | events,
67 | store,
68 | stateKey
69 | };
70 |
71 | return (
72 |
73 | );
74 | };
75 |
76 | const { object } = PropTypes;
77 |
78 | Tree.propTypes = {
79 | store: object.isRequired
80 | };
81 |
82 | Tree.defaultProps = {};
83 |
84 | export default Tree;
--------------------------------------------------------------------------------
/src/components/examples/bootstrap/Bootstrap.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { Component, PropTypes } from 'react';
3 | import { Grid, Actions, applyGridConfig } from 'react-redux-grid';
4 | import './css/bootstrap.min.css';
5 |
6 | import {
7 | columns,
8 | data,
9 | pageSize,
10 | events,
11 | plugins,
12 | dataSource
13 | } from '../data/demodata';
14 |
15 | export class Bootstrap extends Component {
16 |
17 | componentWillUnmount() {
18 | applyGridConfig({
19 | CLASS_NAMES: {
20 | ACTIVE_CLASS: 'active',
21 | INACTIVE_CLASS: 'inactive',
22 | DRAG_HANDLE: 'drag-handle',
23 | SORT_HANDLE: 'sort-handle',
24 | SECONDARY_CLASS: 'secondary',
25 | CONTAINER: 'container',
26 | TABLE: 'table',
27 | TABLE_CONTAINER: 'table-container',
28 | HEADER: 'header',
29 | THEADER: 't-head',
30 | HEADER_HIDDEN: 'header-hidden',
31 | HEADER_FIXED: 'header-fixed',
32 | HEADER_FIXED_CONTAINER: 'header-fixed-container',
33 | HEADER_STUCK: 'header-stuck',
34 | HEADER_STUCK_BOTTOM: 'header-stuck-bottom',
35 | ROW: 'row',
36 | ROW_IS_DRAGGING: 'row-is-dragging',
37 | CELL: 'cell',
38 | CELL_TREE_ARROW: 'cell-tree-arrow',
39 | CELL_HANDNLE_CONTAINER: 'cell-handle-container',
40 | ROW_DRAG_HANDLE: 'row-drag-handle',
41 | PAGERTOOLBAR: 'pager-toolbar',
42 | EMPTY_ROW: 'empty-row',
43 | EDITED_CELL: 'edit',
44 | LOADING_BAR: 'loading-bar',
45 | DRAGGABLE_COLUMN: 'draggable-column',
46 | COLUMN: 'column',
47 | SORT_HANDLE_VISIBLE: 'sort-handle-visible',
48 | BUTTONS: {
49 | PAGER: 'page-buttons'
50 | },
51 | SELECTION_MODEL: {
52 | CHECKBOX: 'checkbox',
53 | CHECKBOX_CONTAINER: 'checkbox-container'
54 | },
55 | ERROR_HANDLER: {
56 | CONTAINER: 'error-container',
57 | MESSAGE: 'error-message'
58 | },
59 | EDITOR: {
60 | INLINE: {
61 | CONTAINER: 'inline-editor',
62 | SHOWN: 'shown',
63 | HIDDEN: 'hidden',
64 | SAVE_BUTTON: 'save-button',
65 | CANCEL_BUTTON: 'cancel-button',
66 | BUTTON_CONTAINER: 'button-container',
67 | INPUT_WRAPPER: 'editor-wrapper'
68 | }
69 | },
70 | GRID_ACTIONS: {
71 | CONTAINER: 'action-container',
72 | SELECTED_CLASS: 'action-menu-selected',
73 | NO_ACTIONS: 'no-actions',
74 | DISABLED: 'disabled',
75 | ICON: 'action-icon',
76 | MENU: {
77 | CONTAINER: 'action-menu-container',
78 | ITEM: 'action-menu-item'
79 | }
80 | },
81 | FILTER_CONTAINER: {
82 | CONTAINER: 'filter-container',
83 | INPUT: 'filter-input',
84 | SEARCH_BUTTON: 'filter-search-button',
85 | MENU_BUTTON: 'filter-menu-button',
86 | CLEAR_BUTTON: 'filter-clear-button',
87 | BUTTON_CONTAINER: 'filter-button-container',
88 | MENU: {
89 | CONTAINER: 'advanced-filter-menu-container',
90 | TITLE: 'advanced-filter-menu-title',
91 | BUTTON: 'advanced-filter-menu-button',
92 | BUTTON_CONTAINER: 'advanced-filter-menu-button-container',
93 | FIELD: {
94 | CONTAINER: 'advanced-filter-menu-field-container',
95 | LABEL: 'advanced-filter-menu-field-label',
96 | INPUT: 'advanced-filter-menu-field-input'
97 | }
98 | }
99 | },
100 | BULK_ACTIONS: {
101 | CONTAINER: 'bulkaction-container',
102 | DESCRIPTION: 'bulkaction-description',
103 | SHOWN: 'shown',
104 | HIDDEN: 'hidden'
105 | }
106 | },
107 | CSS_PREFIX: 'react-grid'
108 | });
109 | }
110 |
111 | render() {
112 | const { store } = this.props;
113 | const stateKey = 'bootstrap';
114 |
115 | applyGridConfig({
116 | CLASS_NAMES: {
117 | TABLE: 'table table-striped',
118 | TABLE_CONTAINER: 'table-responsive',
119 | HEADER_FIXED_CONTAINER: 'header-fixed',
120 | HEADER: 'header-bs',
121 | HEADER_HIDDEN: 'hidden-override',
122 | ROW: 'row-bs',
123 | CELL: 'text-left',
124 | COLUMN: 'column-bs',
125 | PAGERTOOLBAR: 'text-right bootstrap-description',
126 | BUTTONS: {
127 | PAGER: 'btn pull-left negative-margin'
128 | },
129 | ERROR_HANDLER: {
130 | CONTAINER: 'hidden'
131 | }
132 | },
133 | CSS_PREFIX: ''
134 | });
135 |
136 | const bootstrapData = {
137 | columns: [
138 | {
139 | name: 'Name',
140 | width: '10%',
141 | className: 'additional-class',
142 | dataIndex: 'Name',
143 | sortable: true,
144 | HANDLE_CLICK: () => { console.log('Header Click'); }
145 | },
146 | {
147 | name: 'Phone Number',
148 | width: '20%',
149 | dataIndex: 'Phone Number',
150 | sortable: true,
151 | className: 'additional-class'
152 | },
153 | {
154 | name: 'Email',
155 | width: '25%',
156 | dataIndex: 'Email',
157 | sortable: true,
158 | className: 'additional-class',
159 | defaultSortDirection: 'descend'
160 | },
161 | {
162 | name: 'Address',
163 | dataIndex: 'Address',
164 | sortable: true,
165 | width: '35%',
166 | className: 'additional-class'
167 | }
168 | ],
169 | data,
170 | pageSize,
171 | plugins: {
172 | ...plugins,
173 | BULK_ACTIONS: {
174 | enabled: false
175 | },
176 | GRID_ACTIONS: {
177 | menu: []
178 | }
179 | },
180 | events,
181 | dataSource,
182 | store,
183 | stateKey
184 | };
185 |
186 | return ;
187 | }
188 |
189 | }
190 |
191 | const { object } = PropTypes;
192 |
193 | Bootstrap.propTypes = {
194 | store: object.isRequired
195 | };
196 |
197 | Bootstrap.defaultProps = {};
198 |
199 | export default Bootstrap;
--------------------------------------------------------------------------------
/src/components/examples/bootstrap/README.md:
--------------------------------------------------------------------------------
1 | ## Bootstrap
2 |
3 | This example uses Bootstrap 3.3.7
4 |
5 | If you would like to use a different version, please update the css, fonts, js folders with the version of your choice. We can only load 1 version of bootstrap at time on the examples website but it we'll try to keep it a recent, stable version.
6 |
7 |
8 | #### Jan 24/2017
9 | Currently, Bootstrap is about to release version 4.0.0
--------------------------------------------------------------------------------
/src/components/examples/bootstrap/css/bootstrap-theme.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap v3.3.7 (http://getbootstrap.com)
3 | * Copyright 2011-2016 Twitter, Inc.
4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5 | */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)}
6 | /*# sourceMappingURL=bootstrap-theme.min.css.map */
--------------------------------------------------------------------------------
/src/components/examples/bootstrap/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/src/components/examples/bootstrap/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/src/components/examples/bootstrap/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/src/components/examples/bootstrap/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/src/components/examples/bootstrap/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/src/components/examples/bootstrap/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/src/components/examples/bootstrap/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/src/components/examples/bootstrap/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/src/components/examples/bootstrap/js/npm.js:
--------------------------------------------------------------------------------
1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
2 | require('../../js/transition.js')
3 | require('../../js/alert.js')
4 | require('../../js/button.js')
5 | require('../../js/carousel.js')
6 | require('../../js/collapse.js')
7 | require('../../js/dropdown.js')
8 | require('../../js/modal.js')
9 | require('../../js/tooltip.js')
10 | require('../../js/popover.js')
11 | require('../../js/scrollspy.js')
12 | require('../../js/tab.js')
13 | require('../../js/affix.js')
--------------------------------------------------------------------------------
/src/components/examples/bulk-selection/BulkPager.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { Component, PropTypes } from 'react';
3 | import { connect } from 'react-redux';
4 | import { Actions } from 'react-redux-grid';
5 | import * as BulkSelectionActions from '../../../redux/actions/bulkSelectionActions';
6 | import * as _ from 'lodash';
7 |
8 | import {
9 | columns,
10 | data,
11 | pageSize,
12 | events,
13 | dataSource,
14 | pagingDataSource
15 | } from './..//data/demodata';
16 |
17 | class BulkPager extends Component {
18 |
19 | constructor(props){
20 | super(props);
21 | this.state = {
22 | currentPageLimit: 10
23 | };
24 | this.handleBulkActionClick = this.handleBulkActionClick.bind(this);
25 | this.handleSelectChange = this.handleSelectChange.bind(this);
26 | this.handleNumberedPageButtonClick = this.handleNumberedPageButtonClick.bind(this);
27 |
28 | }
29 |
30 | getSelectedIds() {
31 |
32 | const bulkMap = this.props.selection.get("bulk");
33 | const selectedIds = bulkMap.get("indexes");
34 |
35 | if (undefined !== selectedIds) {
36 | return selectedIds;
37 | } else {
38 | // you could dispatch a notification...
39 | // this.props.displayWarningRequestMessage("No rows selected");
40 | console.warn("BulkPage selectedIds were false! no rows selected");
41 | console.log( bulkMap.toJSON() );
42 | return [];
43 | }
44 | };
45 |
46 | handleBulkActionClick(e) {
47 | e.preventDefault();
48 | const selectedIds = this.getSelectedIds();
49 |
50 | //const currentPageRecords = this.props.gridData.get("data").toJSON();
51 |
52 | // credit: http://stackoverflow.com/questions/28357971/lodash-challenges-i-have-an-array-of-objects-i-need-to-filter-for-an-array-of
53 | const list = this.props.gridData.get("data");
54 |
55 | console.warn("BulkPage selectedIds :", selectedIds);
56 |
57 | const remaining = list.toJSON().filter( obj => { return selectedIds.indexOf( obj._id ) > -1; })
58 | const removed = list.toJSON().filter( obj => { return selectedIds.indexOf( obj._id ) === -1; })
59 |
60 | this.props.bulkDisplay({removed, remaining})
61 |
62 | };
63 |
64 | handleSelectChange(e) {
65 | console.log("BulkPager handleSelectChange");
66 | e.preventDefault();
67 | const newPageLimit = Number(e.target.value);
68 |
69 | const currIndex = this.props.currentPager
70 | && this.props.currentPager.get !== undefined
71 | ? this.props.currentPager.get('pageIndex')
72 | : 0;
73 |
74 | this.setState({
75 | currentPageLimit: newPageLimit
76 | });
77 |
78 | Promise.all([
79 | this.props.getAsyncData({
80 | dataSource: this.props.api,
81 | stateKey: 'bulk',
82 | extraParams: {
83 | pageIndex: currIndex,
84 | pageSize: newPageLimit,
85 | }
86 | }),
87 | this.props.changePageLimit(newPageLimit)
88 | ])
89 |
90 | };
91 |
92 | handleNumberedPageButtonClick(e) {
93 |
94 | const newPageIndex = parseInt(e.target.innerHTML) - 1;
95 |
96 |
97 | this.props.getAsyncData({
98 | dataSource: this.props.api,
99 | stateKey: 'bulk',
100 | extraParams: {
101 | pageIndex: newPageIndex,
102 | pageSize: this.state.currentPageLimit,
103 | }
104 | })
105 |
106 | Promise.all([
107 | this.props.getAsyncData({
108 | dataSource: this.props.api,
109 | stateKey: 'bulk',
110 | extraParams: {
111 | pageIndex: newPageIndex,
112 | pageSize: this.state.currentPageLimit,
113 | }
114 | }),
115 |
116 | this.props.setPageIndexAsync({
117 | pageIndex: newPageIndex,
118 | pageSize: this.state.currentPageLimit,
119 | dataSource: this.props.api,
120 | stateKey: 'bulk'
121 | })
122 | ]);
123 |
124 | };
125 |
126 |
127 | render(){
128 |
129 | const total = this.props.gridData ?
130 | this.props.gridData.total
131 | : 0;
132 |
133 | const currIndex = this.props.currentPager
134 | && this.props.currentPager.get !== undefined
135 | ? this.props.currentPager.get('pageIndex')
136 | : 0;
137 |
138 |
139 | const totalButtons = total / this.props.bulkSelection.pageSize;
140 | const buttons = [];
141 |
142 | _.times(totalButtons, i => {
143 | buttons.push(
144 |
154 | );
155 | });
156 |
157 | const totalRowsSelected = ( undefined !== this.props.selection.get('bulk') && undefined !== this.props.selection.get('bulk').get("indexes") ) ? this.props.selection.get('bulk').get("indexes").length : 0;
158 | const rowsSelectedMessage = (totalRowsSelected > 0) ? totalRowsSelected + " Rows Selected" : "0 Rows Selected";
159 |
160 | return (
161 |
162 | [ {rowsSelectedMessage} ]
163 | Rows per Page:
164 |
165 | 10
166 | 20
167 | 50
168 | 100
169 |
170 | { buttons }
171 | Bulk Action
172 |
173 | );
174 | }
175 | };
176 |
177 | const { string, object } = PropTypes;
178 |
179 | BulkPager.propTypes = {
180 | pagingDataSource: string,
181 | store: object.isRequired
182 | };
183 |
184 | BulkPager.defaultProps = {};
185 |
186 | const mapStateToProps = (state, ownProps) => ({
187 | grid: state.grid,
188 | selection: state.selection,
189 | currentPager: state.pager.get('bulk'),
190 | gridData: state.dataSource.get('bulk'),
191 | bulkSelection: state.bulkSelection
192 | });
193 |
194 | const mapDispatchToProps = dispatch => {
195 | return {
196 | getAsyncData: config => {
197 | dispatch(Actions.GridActions.getAsyncData(config))
198 | },
199 | setPageIndexAsync: config => {
200 | dispatch(Actions.PagerActions.setPageIndexAsync(config))
201 | },
202 | bulkDisplay: newData => {
203 | dispatch(BulkSelectionActions.bulkDisplay(newData))
204 | },
205 | changePageLimit: newPageLimit => {
206 | dispatch(BulkSelectionActions.changePageLimit(newPageLimit))
207 | },
208 | dispatch
209 | }
210 | }
211 |
212 | export default connect(mapStateToProps, mapDispatchToProps)(BulkPager);
--------------------------------------------------------------------------------
/src/components/examples/bulk-selection/BulkSelection.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { Component } from 'react';
3 | import { Grid, Actions } from 'react-redux-grid';
4 | import { connect } from 'react-redux';
5 | import BulkPager from './BulkPager';
6 | import store from '../../../redux/configureStore';
7 | import Api from './..//data/Api';
8 |
9 | import {
10 | columns,
11 | events,
12 | plugins,
13 | } from '../data/demodata';
14 |
15 | class BulkSelection extends Component {
16 |
17 | constructor(props){
18 | super(props);
19 |
20 | console.log("BulkSelection constructor: ", props);
21 |
22 | const pagerConfig = {
23 | pageSize: this.props.bulkSelection.pageSize
24 | }
25 |
26 | };
27 |
28 | componentWillReceiveProps(nextProps, nextState) {
29 | this.props = nextProps;
30 | };
31 |
32 | componentDidMount() {
33 |
34 | };
35 |
36 | componentDidUpdate() {
37 | console.log("BulkSelection componentDidUpdate this.props: ", this.props);
38 |
39 | };
40 |
41 | render(){
42 | console.log("BulkSelection render this.props: ", this.props);
43 |
44 | let pagerConfig = {
45 | data: this.props.bulkSelection.data,
46 | pageSize: this.props.bulkSelection.pageSize
47 | }
48 |
49 | let config = {
50 | columns,
51 | dataSource: Api,
52 | pageSize: pagerConfig.pageSize,
53 | plugins: {
54 | ...plugins,
55 | STICKY_HEADER: {
56 | enabled: true
57 | },
58 | STICKY_FOOTER: {
59 | enabled: true
60 | },
61 | FILTER_CONTAINER: {
62 | enabled: true
63 | },
64 |
65 | PAGER: {
66 | enabled: true,
67 | pagingType: 'remote',
68 | pagerComponent: (
69 |
73 | )
74 | },
75 | BULK_ACTIONS: {
76 | enabled: true,
77 | actions: [
78 | {
79 | text: 'Move',
80 | EVENT_HANDLER: () => {
81 |
82 | }
83 | },
84 | {
85 | text: 'Add',
86 | EVENT_HANDLER: () => {
87 |
88 | }
89 | }
90 | ]
91 | },
92 | GRID_ACTIONS: {
93 | iconCls: 'action-icon',
94 | menu: [
95 | {
96 | text: 'Delete',
97 | EVENT_HANDLER: ({ metaData }) => {
98 | const rowIndex = metaData.rowIndex;
99 |
100 | store.dispatch(
101 | Actions.EditorActions.removeRow({
102 | stateKey,
103 | rowIndex
104 | })
105 | );
106 | }
107 | }
108 | ]
109 | }
110 | },
111 | height: '',
112 | events,
113 | store,
114 | stateKey: 'bulk'
115 | }
116 |
117 |
118 | return (
119 |
120 | );
121 | };
122 | }
123 |
124 |
125 |
126 | const mapStateToProps = (state, ownProps) => ({
127 | grid: state.grid,
128 | bulkSelection: state.bulkSelection,
129 | });
130 |
131 | const mapDispatchToProps = dispatch => {
132 | return {
133 | dispatch
134 | }
135 | }
136 |
137 | export default connect(mapStateToProps, mapDispatchToProps)(BulkSelection);
--------------------------------------------------------------------------------
/src/components/examples/bulk-selection/BulkSelection.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import store from '../../../redux/configureStoreForTests';
3 | import { shallow, mount, render } from 'enzyme';
4 | import BulkSelection from './BulkSelection';
5 | import { Grid, Actions } from 'react-redux-grid';
6 |
7 | jest.unmock()
8 |
9 | describe(' ', () => {
10 |
11 | it("should render swallowly without testing sub components", function() {
12 | const wrapper = shallow( );
13 | expect(wrapper).toBeDefined();
14 | });
15 |
16 | it("should render mounted with sub components affecting tests", function() {
17 | const wrapper = mount( );
18 | expect(wrapper).toBeDefined();
19 | });
20 |
21 | it("should have a Grid with data", function() {
22 | const wrapper = mount( );
23 | expect( wrapper.find('Grid') ).toBeDefined();
24 | //expect(wrapper.prop('data')).to.have.length.toBeGreaterThan(1);
25 | });
26 |
27 | it("should have a Grid with data with 1 on init", function() {
28 | const wrapper = mount( );
29 | const data = wrapper.find('Grid').prop('data');
30 |
31 | expect(data).toBeDefined();
32 | });
33 |
34 | it("should have a Grid with data with greater than 1 after load", function() {
35 | const wrapper = mount( );
36 | const data = wrapper.find('Grid').prop('data');
37 |
38 | expect(data.length).toBeGreaterThan(1);
39 | });
40 |
41 |
42 | });
43 |
44 |
--------------------------------------------------------------------------------
/src/components/examples/bulk-selection/getBulkSelectionSelectedRows.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React from 'react';
3 | import * as _ from "lodash";
4 | import store from './../../../redux/configureStore';
5 | import { events } from '../data/demodata';
6 | import { Grid } from 'react-redux-grid';
7 |
8 | // the BulkSelection example will display a message after you select several rows and click the Bulk Action button
9 | const getBulkSelectionSelectedRows = props => {
10 |
11 | console.log("getBulkSelectionSelectedRows props: ", props);
12 |
13 | const totalRowsSelected = ( undefined !== props.selection.get('bulk') && undefined !== props.selection.get('bulk').get("indexes") ) ? props.selection.get('bulk').get("indexes").length : 0;
14 | const rowsSelectedMessage = (totalRowsSelected > 0) ? totalRowsSelected + " Rows Selected" : "0 Rows Selected";
15 |
16 | if ( props.app.featureTitle === "BulkSelection" && props.bulkSelection.recordsRemoved.length > 0 ) {
17 |
18 | const emails = _.map( props.bulkSelection.recordsRemoved, record => {
19 | console.log("record ", record);
20 | return ({record.Email} )
21 | });
22 |
23 | const discStyle = {listStyleType:"disc", marginLeft: "20px", color:"#644581"};
24 | const selectedIndexes = props.selection.get('bulk').get("indexes");
25 |
26 | return (You have selected { ( undefined !== selectedIndexes ) ? selectedIndexes.length : 0 } records with the following emails:
27 |
30 |
)
31 | } else if (props.app.featureTitle === "BulkSelection") {
32 | return ({rowsSelectedMessage}
)
33 | } else {
34 | return null;
35 | }
36 | }
37 |
38 | export default getBulkSelectionSelectedRows;
39 |
--------------------------------------------------------------------------------
/src/components/examples/complex/Complex.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { PropTypes } from 'react';
3 | import { Grid, Actions } from 'react-redux-grid';
4 |
5 | import {
6 | columns,
7 | data,
8 | pageSize,
9 | events,
10 | plugins,
11 | dataSource
12 | } from '../data/demodata';
13 |
14 | export const Complex = ({ store }) => {
15 |
16 | const stateKey = 'complex';
17 |
18 | const complexData = {
19 | columns: [
20 | {
21 | name: 'Name',
22 | width: '10%',
23 | className: 'additional-class',
24 | dataIndex: 'Name',
25 | sortable: true,
26 | HANDLE_CLICK: () => { console.log('Header Click'); }
27 | },
28 | {
29 | name: 'Phone Number',
30 | width: '20%',
31 | dataIndex: 'Phone Number',
32 | sortable: true,
33 | className: 'additional-class'
34 | },
35 | {
36 | name: 'Email',
37 | width: '25%',
38 | dataIndex: 'Email',
39 | sortable: true,
40 | className: 'additional-class',
41 | defaultSortDirection: 'descend'
42 | },
43 | {
44 | name: 'Address',
45 | dataIndex: 'Address',
46 | sortable: true,
47 | width: '35%',
48 | className: 'additional-class'
49 | }
50 | ],
51 | data,
52 | pageSize,
53 | plugins: {
54 | ...plugins,
55 | BULK_ACTIONS: {
56 | enabled: true
57 | },
58 | GRID_ACTIONS: {
59 | iconCls: 'action-icon',
60 | menu: [
61 | {
62 | text: 'DeleteA',
63 | EVENT_HANDLER: ({ metaData }) => {
64 | const rowIndex = metaData.rowIndex;
65 |
66 | store.dispatch(
67 | Actions.EditorActions.removeRow({
68 | stateKey,
69 | rowIndex
70 | })
71 | );
72 | }
73 | }
74 | ]
75 | }
76 | },
77 | events,
78 | dataSource,
79 | store,
80 | stateKey
81 | };
82 |
83 | return (
84 |
85 | );
86 | };
87 |
88 | const { object } = PropTypes;
89 |
90 | Complex.propTypes = {
91 | store: object.isRequired
92 | };
93 |
94 | Complex.defaultProps = {};
95 |
96 | export default Complex;
--------------------------------------------------------------------------------
/src/components/examples/complex/Complex.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import store from '../../../redux/configureStoreForTests';
3 | import { shallow, mount, render } from 'enzyme';
4 | import Complex from './Complex';
5 | import { Grid, Actions } from 'react-redux-grid';
6 |
7 | jest.unmock()
8 |
9 | describe(' ', () => {
10 |
11 | it("should render swallowly without testing sub components", function() {
12 | const wrapper = shallow( );
13 | expect(wrapper).toBeDefined();
14 | });
15 |
16 | it("should render mounted with sub components affecting tests", function() {
17 | const wrapper = mount( );
18 | expect(wrapper).toBeDefined();
19 | });
20 |
21 | it("should have a Grid with data", function() {
22 | const wrapper = mount( );
23 | expect( wrapper.find('Grid') ).toBeDefined();
24 | //expect(wrapper.prop('data')).to.have.length.toBeGreaterThan(1);
25 | });
26 |
27 | it("should have a Grid with data with 1 on init", function() {
28 | const wrapper = mount( );
29 | const data = wrapper.find('Grid').prop('data');
30 |
31 | expect(data).toBeDefined();
32 | });
33 |
34 | it("should have a Grid with data with greater than 1 after load", function() {
35 | const wrapper = mount( );
36 | const data = wrapper.find('Grid').prop('data');
37 |
38 | expect(data.length).toBeGreaterThan(1);
39 | });
40 |
41 | describe('Phone Number column', () => {
42 | it("should have a drag handle", function() {
43 | const wrapper = mount( );
44 | expect(wrapper.find('./react-grid-resizable')).toBeDefined();
45 | // react-grid-drag-handle
46 | });
47 | });
48 |
49 | });
50 |
51 |
--------------------------------------------------------------------------------
/src/components/examples/custom-loader/CustomLoader.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { Component, PropTypes } from 'react';
3 | import { Actions, Grid } from 'react-redux-grid';
4 |
5 | import {
6 | columns,
7 | data,
8 | pageSize,
9 | events,
10 | dataSource
11 | } from './../data/demodata';
12 |
13 | import './loader.css';
14 |
15 | export class CustomLoader extends Component {
16 | render() {
17 |
18 | const { store } = this.props;
19 | const loaderData = {
20 | columns,
21 | data,
22 | pageSize,
23 | plugins: {
24 | LOADER: {
25 | enabled: true
26 | }
27 | },
28 | events,
29 | store,
30 | classNames: ['custom-loader'],
31 | stateKey: 'custom-loader',
32 |
33 | };
34 |
35 | return (
36 |
37 | );
38 | }
39 |
40 | componentDidMount() {
41 | const { store } = this.props;
42 |
43 | store.dispatch(
44 | Actions.LoaderActions.setLoaderState({
45 | state: true,
46 | stateKey: 'custom-loader'
47 | })
48 | )
49 | }
50 | };
51 |
52 | const { object } = PropTypes;
53 |
54 | CustomLoader.propTypes = {
55 | store: object.isRequired
56 | };
57 |
58 | CustomLoader.defaultProps = {};
59 |
60 | export default CustomLoader;
--------------------------------------------------------------------------------
/src/components/examples/custom-loader/loader.css:
--------------------------------------------------------------------------------
1 | .react-grid-custom-loader .react-grid-loading-bar {
2 | position: absolute;
3 | height: 100%;
4 | top: 0px;
5 | background-color: rgba(0,0,0,0.5);
6 | background-image: url('./spinner.gif');
7 | background-repeat: no-repeat;
8 | background-position: 50% 50%;
9 | background-size: 15%;
10 | }
--------------------------------------------------------------------------------
/src/components/examples/custom-loader/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/src/components/examples/custom-loader/spinner.gif
--------------------------------------------------------------------------------
/src/components/examples/custom-pager/Api.js:
--------------------------------------------------------------------------------
1 | export const dataSource = function getData({
2 | pageIndex
3 | }) {
4 | return new Promise((resolve) => {
5 | const request = new XMLHttpRequest();
6 |
7 | const config = {
8 | method: 'GET',
9 | route: 'http://react-redux-grid.herokuapp.com/getfakeData'
10 | };
11 |
12 | if (pageIndex) {
13 | config.route = `${config.route}?pageIndex=${pageIndex}&pageSize=10`; // eslint-disable-line max-len
14 | }
15 |
16 | else {
17 | config.route = `${config.route}?pageSize=10`; // eslint-disable-line max-len
18 | }
19 |
20 | request.open(config.method, config.route, true);
21 |
22 | request.addEventListener(
23 | 'load', (res) => {
24 | const response = JSON.parse(res.target.responseText);
25 |
26 | // if you have more data than is being shown
27 | // ensure you return a total, so the pager knows
28 | // what paging actions are possible
29 |
30 | resolve({
31 | data: response.data,
32 | total: response.total
33 | });
34 | }
35 | );
36 |
37 | request.send(config.data || null);
38 | });
39 | };
40 |
41 | export default dataSource;
--------------------------------------------------------------------------------
/src/components/examples/custom-pager/CustomPager.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { PropTypes } from 'react';
3 | import { Grid } from 'react-redux-grid';
4 |
5 | import Pager from './Pager';
6 | import Api from './..//data/Api';
7 |
8 | import {
9 | columns,
10 | data,
11 | events,
12 | dataSource
13 | } from './..//data/demodata';
14 |
15 | export const CustomFooter = ({ store }) => {
16 |
17 | const customFooter = {
18 | columns,
19 | dataSource: Api,
20 | plugins: {
21 | PAGER: {
22 | enabled: true,
23 | pagingType: 'remote',
24 | pagerComponent: (
25 |
29 | )
30 | }
31 | },
32 | events,
33 | store,
34 | stateKey: 'custom-pager'
35 | };
36 |
37 | return ;
38 | };
39 |
40 | const { object } = PropTypes;
41 |
42 | CustomFooter.propTypes = {
43 | store: object.isRequired
44 | };
45 |
46 | CustomFooter.defaultProps = {};
47 |
48 | export default CustomFooter;
--------------------------------------------------------------------------------
/src/components/examples/custom-pager/CustomPager.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import store from '../../../redux/configureStoreForTests';
3 | import { shallow, mount, render } from 'enzyme';
4 | import CustomerPager from './CustomerPager';
5 | import { Grid, Actions } from 'react-redux-grid';
6 |
7 | jest.unmock()
8 |
9 | describe(' ', () => {
10 |
11 | it("should render swallowly without testing sub components", function() {
12 | const wrapper = shallow( );
13 | expect(wrapper).toBeDefined();
14 | });
15 |
16 | it("should render mounted with sub components affecting tests", function() {
17 | const wrapper = mount( );
18 | expect(wrapper).toBeDefined();
19 | });
20 |
21 | it("should have a Grid with data", function() {
22 | const wrapper = mount( );
23 | expect( wrapper.find('Grid') ).toBeDefined();
24 | //expect(wrapper.prop('data')).to.have.length.toBeGreaterThan(1);
25 | });
26 |
27 | it("should have a Grid with data with 1 on init", function() {
28 | const wrapper = mount( );
29 | const data = wrapper.find('Grid').prop('data');
30 |
31 | expect(data).toBeDefined();
32 | });
33 |
34 | it("should have a Grid with data with greater than 1 after load", function() {
35 | const wrapper = mount( );
36 | const data = wrapper.find('Grid').prop('data');
37 |
38 | expect(data.length).toBeGreaterThan(1);
39 | });
40 |
41 |
42 | });
43 |
44 |
--------------------------------------------------------------------------------
/src/components/examples/custom-pager/Pager.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import React, { PropTypes } from 'react';
3 | import { connect } from 'react-redux';
4 | import { Actions } from 'react-redux-grid';
5 |
6 | import {
7 | columns,
8 | data,
9 | pageSize,
10 | events,
11 | dataSource,
12 | pagingDataSource
13 | } from './..//data/demodata';
14 |
15 | export const Pager = ({ api, current, gridData, pagingDataSource, store }) => {
16 |
17 | const total = gridData ?
18 | gridData.total
19 | : 0;
20 |
21 | const currIndex = current
22 | && current.get !== undefined
23 | ? current.get('pageIndex')
24 | : 0;
25 |
26 | const buttons = [];
27 |
28 | const onClick = (e) => {
29 | const index = e.target.innerHTML
30 | store.dispatch(
31 | Actions.PagerActions
32 | .setPageIndexAsync({
33 | pageIndex: parseInt(index) - 1,
34 | pageSize: 10,
35 | dataSource: api,
36 | stateKey: 'custom-pager'
37 | })
38 | );
39 | };
40 |
41 | for (let i = 0; i < total / 10; i++) {
42 | buttons.push(
43 |
53 | );
54 | }
55 |
56 | return (
57 |
58 | { buttons }
59 |
60 | );
61 | };
62 |
63 | const { string, object } = PropTypes;
64 |
65 | Pager.propTypes = {
66 | pagingDataSource: string,
67 | store: object.isRequired
68 | };
69 |
70 | Pager.defaultProps = {};
71 |
72 | export default connect((state, props) => ({
73 | gridData: state.dataSource.get('custom-pager'),
74 | current: state.pager.get('custom-pager'),
75 | }))(Pager);
--------------------------------------------------------------------------------
/src/components/examples/data/Api.js:
--------------------------------------------------------------------------------
1 | import * as _ from 'lodash';
2 |
3 | export const dataSource = function getData({
4 | pageIndex, pageSize
5 | }) {
6 | return new Promise((resolve) => {
7 | const request = new XMLHttpRequest();
8 |
9 | const config = {
10 | method: 'GET',
11 | route: 'http://react-redux-grid.herokuapp.com/getfakeData'
12 | };
13 |
14 | if (pageIndex) {
15 | config.route = `${config.route}?pageIndex=${pageIndex}&pageSize=${pageSize || 10}`; // eslint-disable-line max-len
16 | }
17 |
18 | else {
19 | config.route = `${config.route}?pageSize=${pageSize || 10}` ; // eslint-disable-line max-len
20 | }
21 |
22 | request.open(config.method, config.route, true);
23 |
24 | request.addEventListener(
25 | 'load', (res) => {
26 | const response = JSON.parse(res.target.responseText);
27 |
28 | // if you have more data than is being shown
29 | // ensure you return a total, so the pager knows
30 | // what paging actions are possible
31 |
32 | // add fake ids if you need them for your example
33 | _.each(response.data, (obj,index) => { obj._id = index });
34 |
35 | resolve({
36 | data: response.data,
37 | total: response.total
38 | });
39 | }
40 | );
41 |
42 | request.send(config.data || null);
43 | });
44 | };
45 |
46 | export default dataSource;
--------------------------------------------------------------------------------
/src/components/examples/data/provider.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Provider } from 'react-redux';
3 | import App from './components/App';
4 | import store from './store';
5 |
6 | export default (
7 |
8 |
9 |
10 | );
--------------------------------------------------------------------------------
/src/components/examples/data/treedata.json:
--------------------------------------------------------------------------------
1 | {
2 | "data":{
3 | "root":{
4 | "id":-1,
5 | "Name":"Root",
6 | "children":[
7 | {
8 | "id":1,
9 | "parentId":-1,
10 | "Name":"Category 1",
11 | "GUID":"8f7152dc-fed7-4a65-afcf-527fceb99865",
12 | "Email":"hgardnero6@ed.gov",
13 | "Gender":"Male",
14 | "Address":"605 Manley Park",
15 | "Phone Number":"31-(678)495-4134",
16 | "children":[
17 | {
18 | "id":11,
19 | "parentId":1,
20 | "Name":"Category 11",
21 | "GUID":"8f7152dc-fed7-4a65-afcf-527fceb991865",
22 | "Email":"hgardneross6@ed.gov",
23 | "Gender":"Male",
24 | "Address":"12 Manley Park",
25 | "Phone Number":"31-(678)495-4134"
26 | },
27 | {
28 | "id":12,
29 | "parentId":1,
30 | "Name":"Category 12",
31 | "GUID":"8f7152dc-fed7-4acf-527fceb991865",
32 | "Email":"hgardneross6@ed.gov",
33 | "Gender":"Male",
34 | "Address":"12 Manley Park",
35 | "Phone Number":"31-(678)495-4134",
36 | "children":[
37 | {
38 | "id":121,
39 | "parentId":12,
40 | "Name":"Category 121",
41 | "GUID":"8f7q2dc-fedsss7-4acf-527fceb991865",
42 | "Email":"hgoss6@eds.gov",
43 | "Gender":"Male",
44 | "Address":"21 fake Park",
45 | "Phone Number":"31-(678)495-4134"
46 | },
47 | {
48 | "id":122,
49 | "parentId":12,
50 | "Name":"Category 122",
51 | "GUID":"8f7q2dc-fed7-4acf-527fceb991865",
52 | "Email":"hgoss6@ed.gov",
53 | "Gender":"Male",
54 | "Address":"21 fake Park",
55 | "Phone Number":"31-(678)495-4134",
56 | "children":[
57 | {
58 | "id":1221,
59 | "parentId":122,
60 | "Name":"Category 1211",
61 | "GUID":"8f7q2dc-facf-527fceb991865",
62 | "Email":"hgossjdjdjdj6@ed.gov",
63 | "Gender":"Male",
64 | "Address":"21 fdjdjake Park",
65 | "Phone Number":"31-(678)495-4134"
66 | }
67 | ]
68 | }
69 | ]
70 | }
71 | ]
72 | },
73 | {
74 | "id":2,
75 | "parentId":-1,
76 | "Name":"Category 2",
77 | "GUID":"8f7q2dc-facf-527fcebdk=-jdjd991865",
78 | "Email":"hehehe@ed.gov",
79 | "Gender":"Male",
80 | "Address":"212 Park",
81 | "Phone Number":"31-(678)495-4134",
82 | "children":[
83 | {
84 | "id":21,
85 | "parentId":2,
86 | "Name":"Category 21",
87 | "GUID":"8f7q2dc-facf-527fcsw-jdjd991865",
88 | "Email":"hehehe@ed.gov",
89 | "Gender":"Male",
90 | "Address":"21112 Park",
91 | "Phone Number":"31-(678)495-4134",
92 | "leaf":false
93 | }
94 | ]
95 | }
96 | ]
97 | }
98 | }
99 | }
--------------------------------------------------------------------------------
/src/components/footer/Footer.css:
--------------------------------------------------------------------------------
1 | .footer {
2 | display: flex;
3 | flex-direction: row;
4 | justify-content: space-between;
5 | background-color: #fbfbfb;
6 | margin: 0px;
7 | margin-top: 50px;
8 | padding: 10px;
9 | color: white;
10 | height: 200px;
11 | }
12 |
13 | .footer .shojiContainer {
14 | display: block;
15 | width: 220px;
16 | }
17 |
18 | .footer .shoji {
19 | opacity: 0.5;
20 | }
--------------------------------------------------------------------------------
/src/components/footer/Footer.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import shoji from './gridGrey.svg';
3 | import Instructions from '../instructions/Instructions';
4 | import './Footer.css';
5 |
6 | class Footer extends Component {
7 | render() {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 | }
20 | }
21 |
22 | export default Footer;
--------------------------------------------------------------------------------
/src/components/footer/gridGrey.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/components/header/Header.css:
--------------------------------------------------------------------------------
1 | .gridHeader {
2 | display: flex;
3 | flex-direction: row;
4 | justify-content: flex-start;
5 | background-color: #fbfbfb;
6 | min-height: 116px;
7 | padding: 20px;
8 | color: white;
9 | border-bottom: 1px dotted #ddd;
10 | flex-wrap: wrap;
11 | }
12 |
13 | .title {
14 | display: flex;
15 | flex-direction: column;
16 | justify-content: flex-start;
17 | }
18 |
19 | .title-container {
20 | display: flex;
21 | flex: 1;
22 | }
23 |
24 | .gridHeader h1 {
25 | font-family: 'Bree Serif', serif;
26 | font-size: 40px;
27 | font-weight: normal;
28 | color: #000;
29 | margin: 0px;
30 | padding: 0px;
31 | }
32 |
33 | .listContainer {
34 | display: flex;
35 | flex-direction: column;
36 | justify-content: flex-start;
37 | right: 50px;
38 | }
39 |
40 | .listContainer img {
41 | margin-bottom: 10px;
42 | cursor: pointer;
43 | }
44 |
45 | .flex {
46 | display: flex;
47 | }
48 |
49 | .gridHeader h3 {
50 | font-family: 'Bree Serif', serif;
51 | font-size: 16px;
52 | color: #999;
53 | font-weight: normal;
54 | font-style: italic;
55 | margin: 0px;
56 | padding: 0px;
57 | }
58 |
59 | .react-logo {
60 | height: 80px;
61 | }
62 |
63 | @keyframes App-logo-spin {
64 | from { transform: rotate(0deg); }
65 | to { transform: rotate(360deg); }
66 | }
67 |
68 | .redux-logo {
69 | height: 80px;
70 | margin-right: 20px;
71 | }
72 |
73 | .grid-logo {
74 | height: 80px;
75 | }
76 |
77 | .github-logo {
78 | display: inline-block;
79 | height: 80px;
80 | cursor: pointer;
81 | padding-right: 20px;
82 | }
83 |
84 | @media (max-width: 775px) {
85 | .logo {
86 | display: none;
87 | }
88 | }
--------------------------------------------------------------------------------
/src/components/header/Header.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import reactLogo from './react.svg';
3 | import reduxLogo from './redux.svg';
4 | import reactReduxGridLogo from './reactReduxGrid.svg';
5 | import githubLogo from './github-square.svg';
6 | import './Header.css';
7 | import pattern from './tiny_grid/tiny_grid.png';
8 |
9 | class Header extends Component {
10 | render() {
11 |
12 | const tweet = "https://img.shields.io/twitter/url/https/github.com/bencripps/react-redux-grid.svg?style=social"
13 | const stars = "https://img.shields.io/github/stars/bencripps/react-redux-grid.svg";
14 | //const npm = "http://img.shields.io/npm/react-redux-grid/localeval.svg";
15 | //const coverage = "https://img.shields.io/codecov/coverage/github/codecov/example-python.svg";
16 | //const download = "https://img.shields.io/github/downloads/atom/atom/total.svg";
17 | const license = "https://img.shields.io/badge/license-MIT-blue.svg";
18 |
19 | // http://meyerweb.com/eric/tools/dencoder/
20 | const encodedTweetMessage = "Need%20a%20table%20for%20your%20React%20Redux%20project%3F%20check%20out%20React-Redux-Grid%20on%20github%20https%3A%2F%2Fgithub.com%2Fbencripps%2Freact-redux-grid";
21 | const tweetUrl = "https://twitter.com/intent/tweet?text=" + encodedTweetMessage;
22 |
23 | const headerStyle = {backgroundImage: `url(${pattern})`};
24 |
25 | return (
26 |
27 |
28 |
29 |
30 |
31 |
32 |
React Redux Grid
33 | A Flexible Grid Pattern Library for Tabular Data
34 |
35 |
36 |
48 |
49 | );
50 | }
51 | }
52 |
53 | export default Header;
--------------------------------------------------------------------------------
/src/components/header/github-square.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/header/grid.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/components/header/react.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/components/header/reactReduxGrid.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
37 |
38 |
39 |
40 |
50 |
51 |
52 |
53 |
56 |
57 |
62 |
63 |
66 |
67 |
68 |
69 |
72 |
73 |
74 |
75 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
--------------------------------------------------------------------------------
/src/components/header/redux.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/components/header/tiny_grid/readme.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 | ========================================================
4 | This pattern is downloaded from www.subtlepatterns.com
5 | If you need more, that's where to get'em.
6 | ========================================================
7 |
8 |
--------------------------------------------------------------------------------
/src/components/header/tiny_grid/tiny_grid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/src/components/header/tiny_grid/tiny_grid.png
--------------------------------------------------------------------------------
/src/components/header/tiny_grid/tiny_grid_@2X.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bencripps/react-redux-grid-demo/91776d836402efc0027821e95f6a62e23c5277d1/src/components/header/tiny_grid/tiny_grid_@2X.png
--------------------------------------------------------------------------------
/src/components/instructions/Instructions.css:
--------------------------------------------------------------------------------
1 | .instructionsContainer {
2 | display: flex;
3 | flex-direction: row;
4 | justify-content: center;
5 | font-size: 14px;
6 | border-bottom: 1px dashed #eee;
7 | padding: 0px;
8 | margin: 0px;
9 | padding-bottom: 20px;
10 | background-color: #f7f7f7;
11 | border-radius: 5px;
12 | }
13 |
14 | .instructions {
15 | max-width: 700px;
16 | margin: 10px;
17 | padding: 20px;
18 | }
19 |
20 | .instructions p {
21 | color: #666;
22 | font-size: 14px;
23 | font-family: Helvetica,sans-serif;
24 | margin-top:0px;
25 | margin-bottom: 10px;
26 | }
27 |
28 | code {
29 | color: #000;
30 | display: block;
31 | margin-bottom: 10px;
32 | }
33 |
--------------------------------------------------------------------------------
/src/components/instructions/Instructions.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import './Instructions.css';
3 |
4 | class Instructions extends Component {
5 | render() {
6 | return (
7 |
8 |
9 |
10 | Whether you're building a Highscore table or an Enterprise user admin, React-Redux-Grid will give you a highly configurable library that can draw tabular data. You can begin by installing:
11 |
12 |
npm install react-redux-grid --save
13 |
All the examples are available to download from a separate Examples Github where you can also contribute your own custom grid examples.
14 |
15 |
16 |
17 | );
18 | }
19 | }
20 |
21 | export default Instructions;
--------------------------------------------------------------------------------
/src/components/sidebar/ExamplesSidebar.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { push } from 'react-router-redux';
3 | import { connect } from 'react-redux';
4 | import gridIconOff from './gridBlueIcon.svg';
5 | import gridIconOn from './gridPurpleIcon.svg';
6 | import {
7 | switchFeature
8 | } from '../../redux/actions/appActions';
9 | import './Sidebar.css';
10 |
11 | class ExamplesSidebar extends Component {
12 |
13 | constructor(props){
14 | super(props);
15 | let selectedFeature = this.props.app.featureTitle;
16 | this.state = { selectedFeature };
17 | }
18 |
19 | componentWillReceiveProps(nextProps){
20 | this.props = nextProps;
21 | this.setState({
22 | selectedFeature: this.props.app.featureTitle
23 | });
24 | }
25 |
26 | componentDidUpdate(){
27 | let selectedFeature = this.props.app.featureTitle;
28 | this.setState({ selectedFeature });
29 | }
30 |
31 | handleClick(item, event){
32 | event.preventDefault();
33 |
34 | const capitalizeFirstLetter = (string) => {
35 | return string.charAt(0).toUpperCase() + string.slice(1);
36 | };
37 |
38 | this.props.switchFeature(capitalizeFirstLetter(item));
39 | this.props.changeRoute('/' + item);
40 | }
41 |
42 | render() {
43 | const { featureTitles } = this.props.app;
44 | const listItems = featureTitles.map((featureTitle) => {
45 | let boundClick = this.handleClick.bind(this, featureTitle);
46 | if (this.state.selectedFeature === featureTitle)
47 | return ( {featureTitle}
)
48 | else
49 | return ( {featureTitle}
)
50 | });
51 | return (
52 |
58 | );
59 | }
60 | }
61 |
62 | const mapStateToProps = (state) => ({
63 | app: state.app
64 | });
65 |
66 |
67 | const mapDispatchToProps = (dispatch) => {
68 | return {
69 | changeRoute: (url) => dispatch(push(url)),
70 | switchFeature: (featureTitle) => dispatch(switchFeature(featureTitle)),
71 | dispatch,
72 | };
73 | }
74 |
75 | export default connect(mapStateToProps, mapDispatchToProps)(ExamplesSidebar);
--------------------------------------------------------------------------------
/src/components/sidebar/FeaturesSidebar.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { connect } from 'react-redux';
3 | import './Sidebar.css';
4 |
5 | class FeaturesSidebar extends Component {
6 |
7 | constructor(props){
8 | super(props);
9 | this.handleClickSimple = this.handleClickSimple.bind(this);
10 | this.handleClickAllFeatures = this.handleClickAllFeatures.bind(this);
11 | }
12 |
13 | handleClickSimple(event){
14 | event.preventDefault();
15 |
16 | }
17 |
18 | handleClickAllFeatures(event){
19 | event.preventDefault();
20 |
21 | }
22 |
23 | render() {
24 | const { features } = this.props.app;
25 | const listItems = features.map((feature) =>
26 |
27 |
28 | {feature}
29 |
30 | );
31 |
32 | return (
33 |
39 | );
40 | }
41 | }
42 |
43 |
44 | const mapStateToProps = (state) => ({
45 | faker: state.faker,
46 | grid: state.grid,
47 | app: state.app
48 | });
49 |
50 | const mapDispatchToProps = (dispatch) => {
51 | return {
52 | dispatch
53 | }
54 | };
55 | export default connect(mapStateToProps, mapDispatchToProps)(FeaturesSidebar);
--------------------------------------------------------------------------------
/src/components/sidebar/Sidebar.css:
--------------------------------------------------------------------------------
1 | .sidebarContainer {
2 | display: block;
3 | position: relative;
4 | width: 170px;
5 | height: auto;
6 | background-color:white;
7 | }
8 |
9 | .featuresContainer {
10 | width: 170px;
11 | }
12 |
13 |
14 | .sidebarsContainer li {
15 | display: flex;
16 | justify-content: flex-start;
17 | flex-direction: column;
18 | width: 170px;
19 | }
20 |
21 | .sidebarContainer li {
22 | font-size: 12px;
23 | color: #666;
24 | margin: 0px;
25 | padding: 0px;
26 | font-size: 12px;
27 | }
28 |
29 | .examplesContainer li button {
30 | font-size: 12px;
31 | }
32 |
33 | .sidebarContainer button {
34 | display: block;
35 | position: relative;
36 | }
37 |
38 | .gridIcon {
39 | display: inline-block;
40 | width: 30px;
41 | vertical-align: top;
42 | margin-top: 3px;
43 | }
44 |
45 | .gridLabelOff {
46 | display: inline-block;
47 | vertical-align: top;
48 | margin:0px;
49 | padding:0px;
50 | position: absolute;
51 | left: 30px;
52 | top: 6px;
53 | color: #176680;
54 | }
55 |
56 | .gridButtonOff {
57 | display: block;
58 | border: none;
59 | border-radius: 5px;
60 | margin: 5px;
61 | background-color: #49b8dc;
62 | color: #fff;
63 | cursor: pointer;
64 | height: 28px;
65 | width: 150px;
66 | text-align: left;
67 | }
68 |
69 | .gridLabelOn {
70 | display: inline-block;
71 | vertical-align: top;
72 | margin:0px;
73 | padding:0px;
74 | position: absolute;
75 | left: 30px;
76 | top: 6px;
77 | color: #f1f1f1;
78 | }
79 |
80 | .gridButtonOn {
81 | display: block;
82 | border: none;
83 | border-radius: 5px;
84 | margin: 5px;
85 | background-color: #644581;
86 | color: #fff;
87 | cursor: pointer;
88 | height: 28px;
89 | width: 150px;
90 | text-align: left;
91 | }
92 |
93 | img {
94 | cursor: pointer;
95 | }
96 |
--------------------------------------------------------------------------------
/src/components/sidebar/gridBlueIcon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/components/sidebar/gridPurpleIcon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import { Provider } from 'react-redux';
4 | import store from './redux/configureStore';
5 | import App from './App';
6 | import ExampleGrid from './components/examples/ExampleGridContainer';
7 | import { Router, Route, IndexRoute, browserHistory } from 'react-router';
8 | import { syncHistoryWithStore } from 'react-router-redux';
9 | import './index.css';
10 |
11 | const history = syncHistoryWithStore(browserHistory, store)
12 |
13 | ReactDOM.render(
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | ,
33 | document.getElementById('root')
34 | );
--------------------------------------------------------------------------------
/src/redux/actions/appActions.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import fetch from 'isomorphic-fetch';
3 | import * as types from '../types/types';
4 |
5 | export const switchFeature = (featureTitle) => {
6 | return {
7 | type: types.FEATURE_SWITCH,
8 | featureTitle
9 | };
10 | }
11 |
12 | export function ready() {
13 | return {
14 | type: types.APP_READY
15 | };
16 | }
--------------------------------------------------------------------------------
/src/redux/actions/bulkSelectionActions.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import fetch from 'isomorphic-fetch';
3 | import * as types from '../types/types';
4 |
5 | export const bulkDisplay = newData => {
6 | return {
7 | type: types.BULK_DISPLAY,
8 | recordsRemaining: newData.removed,
9 | recordsRemoved: newData.remaining
10 | };
11 | }
12 |
13 | export const changePageLimit = newPageLimit => {
14 | return {
15 | type: types.PAGING_CHANGE_LIMIT,
16 | newPageLimit
17 | };
18 | }
--------------------------------------------------------------------------------
/src/redux/configureStore.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import { createStore, applyMiddleware, combineReducers } from 'redux'
3 | import createLogger from 'redux-logger'
4 | import { Reducers as gridReducers } from 'react-redux-grid';
5 | import appReducers from './reducers/appReducers';
6 | import bulkSelectionReducers from './reducers/bulkSelectionReducers';
7 | import { routerReducer, routerMiddleware } from 'react-router-redux';
8 | import { browserHistory } from 'react-router';
9 | import thunk from 'redux-thunk';
10 |
11 | const loggerMiddleware = createLogger();
12 |
13 | const rootReducer = combineReducers({
14 | ...gridReducers,
15 | app: appReducers,
16 | bulkSelection: bulkSelectionReducers,
17 | routing: routerReducer
18 | });
19 |
20 | export function configureStore() {
21 | return createStore(
22 | rootReducer,
23 | applyMiddleware(
24 | loggerMiddleware,
25 | routerMiddleware(browserHistory),
26 | thunk
27 | )
28 | )
29 | }
30 |
31 | const store = configureStore();
32 |
33 | export default store;
34 |
--------------------------------------------------------------------------------
/src/redux/configureStoreForTests.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | import { createStore, applyMiddleware, combineReducers } from 'redux'
3 | import { Reducers as gridReducers } from 'react-redux-grid';
4 | import appReducers from './reducers/appReducers';
5 | import { routerReducer, routerMiddleware } from 'react-router-redux';
6 | import { browserHistory } from 'react-router';
7 | import thunk from 'redux-thunk';
8 |
9 | const rootReducer = combineReducers({
10 | ...gridReducers,
11 | app: appReducers,
12 | routing: routerReducer
13 | });
14 |
15 | export function configureStore() {
16 | return createStore(
17 | rootReducer,
18 | applyMiddleware(
19 | routerMiddleware(browserHistory),
20 | thunk
21 | )
22 | )
23 | }
24 |
25 | const store = configureStore();
26 |
27 | export default store;
28 |
--------------------------------------------------------------------------------
/src/redux/reducers/appReducers.js:
--------------------------------------------------------------------------------
1 | import * as types from "../types/types";
2 | import * as features from "./features";
3 | import { LOCATION_CHANGE } from 'react-router-redux';
4 |
5 | const getFeatures = (featureTitle) => {
6 | let key = featureTitle.toLowerCase() + "Features";
7 | return features[key]
8 | }
9 |
10 | const initialState = {
11 | ready: false,
12 | name: "React Redux Grip Examples",
13 | features: getFeatures('Simple'),
14 | featureTitle: "Simple",
15 | featureTitles: features.featureTitles
16 | };
17 |
18 | export default function reducer(state = initialState, action = {}) {
19 | switch (action.type) {
20 | case LOCATION_CHANGE:
21 | console.log("App heard the route change action: ", action);
22 | let featureTitle = action.payload.pathname.split("/")[1];
23 | if (featureTitle === "") featureTitle = "Simple";
24 | return {
25 | ...state,
26 | featureTitle,
27 | features: getFeatures(featureTitle),
28 | ready: true
29 | };
30 | case types.APP_READY:
31 | return {
32 | ...state,
33 | ready: true
34 | };
35 | case types.FEATURE_SWITCH:
36 | return {
37 | ...state,
38 | features: getFeatures(action.featureTitle),
39 | featureTitle: action.featureTitle
40 | };
41 | default:
42 | return state;
43 | }
44 | }
45 |
46 | export function ready() {
47 | return {
48 | type: types.APP_READY
49 | };
50 | }
--------------------------------------------------------------------------------
/src/redux/reducers/bulkSelectionReducers.js:
--------------------------------------------------------------------------------
1 | import * as types from "../types/types";
2 | import {data} from "../../components/examples/data/demodata";
3 | // import {SET_DATA} from "react-redux-grid/src/constants/ActionTypes"; how can I get the types?!
4 |
5 | const initialState = {
6 | ready: false,
7 | pageSize: 10,
8 | data: data,
9 | recordsRemaining: [],
10 | recordsRemoved: []
11 | };
12 |
13 | export default function reducer(state = initialState, action = {}) {
14 | switch (action.type) {
15 | case types.APP_READY:
16 | return {
17 | ...state,
18 | ready: true
19 | };
20 | case types.PAGING_CHANGE_LIMIT:
21 | return {
22 | ...state,
23 | pageSize: action.newPageLimit
24 | };
25 | case types.GRID_ROWS_BULK_DELETE:
26 | return {
27 | ...state,
28 | data: action.newRows
29 | };
30 | case types.BULK_DISPLAY:
31 | return {
32 | ...state,
33 | recordsRemaining: action.recordsRemaining,
34 | recordsRemoved: action.recordsRemoved
35 | };
36 | case "@@react-redux-grid/SET_DATA":
37 | return {
38 | ...state,
39 | recordsRemaining: [],
40 | recordsRemoved: []
41 | };
42 | default:
43 | return state;
44 | }
45 | }
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/src/redux/reducers/features.js:
--------------------------------------------------------------------------------
1 |
2 | // all features
3 | export const featureTitles = [
4 | "Simple",
5 | "Complex",
6 | "Sticky",
7 | "ColRenderer",
8 | "Stress",
9 | "Editable",
10 | "Bootstrap",
11 | "Tree",
12 | "CustomPager",
13 | "BulkSelection",
14 | "CustomLoader",
15 | "ErrorMessage"
16 | ];
17 |
18 | export const errormessageFeatures = [];
19 |
20 | export const defaultFeatures = [
21 | "No Features Found"
22 | ]
23 |
24 | export const simpleFeatures = [
25 | "Flat List",
26 | "Local/Remote Data Source",
27 | "Sortable",
28 | "Selection Model"
29 | ]
30 |
31 | export const complexFeatures = [
32 | "Flat List",
33 | "Sortable",
34 | "Draggable Columns",
35 | "Resizeable Columns",
36 | "Local/Remote Data Source",
37 | "Checkbox Selection",
38 | "Multi Select",
39 | "Pagination",
40 | "Row Actions and Menus",
41 | "Hideable Columns"
42 | ]
43 |
44 | export const colrendererFeatures = [
45 | "Customizable Cell Components"
46 | ]
47 |
48 | export const stickyFeatures = [
49 | "Sticky Footer",
50 | "Sticky Header",
51 | "Infinite Scroll"
52 | ]
53 |
54 | export const bulkselectionFeatures = [
55 | "Sticky Footer",
56 | "Sticky Header",
57 | "Paging",
58 | "Change Row Limit",
59 | "Bulk Actions",
60 | "Checkbox Selection",
61 | "Multi Select"
62 | ]
63 |
64 | export const stressFeatures = [
65 | "1000000+ Records"
66 | ]
67 |
68 | export const editableFeatures = [
69 | "Edit Cells and Rows"
70 | ]
71 |
72 | export const bootstrapFeatures = [
73 | "Styled by Bootstrap "
74 | ];
75 |
76 |
77 | export const treeFeatures = [
78 | "Tree Structure ",
79 | "Drag amd Drop Rows",
80 | "Show/Hide Actions"
81 | ]
82 |
83 |
84 | export const custompagerFeatures = [
85 | "Tree Structure ",
86 | "Drag amd Drop Rows",
87 | "Show/Hide Actions"
88 | ]
89 |
90 | export const customloaderFeatures = [
91 | "Custom Loading Mask"
92 | ]
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/src/redux/types/types.js:
--------------------------------------------------------------------------------
1 | // OVERALL APP
2 | export const APP_READY = "APP_READY";
3 | export const APP_STATUS_CHANGE = "APP_STATUS_CHANGE";
4 | export const FEATURE_SWITCH = "FEATURE_SWITCH";
5 | // DATA
6 | export const REQUEST_DATA_FAKE = "REQUEST_DATA_FAKE";
7 | export const RECEIVE_DATA_FAKE_SUCCESS = "RECEIVE_DATA_FAKE_SUCCESS";
8 | export const RECEIVE_DATA_FAKE_FAIL = "RECEIVE_DATA_FAKE_FAIL";
9 | // GRID
10 | export const GRID_STATUS_CHANGE = "GRID_STATUS_CHANGE";
11 | export const GRID_SORT = "GRID_SORT";
12 | export const GRID_FILTERS_CHANGE = "GRID_FILTERS_CHANGE";
13 | export const GRID_FILTERS_CLEAR = "GRID_FILTERS_CLEAR";
14 | export const GRID_REQUEST_SAVE = "GRID_REQUEST_SAVE";
15 | export const GRID_RECEIVE_SAVE_SUCCESS = "GRID_RECEIVE_SAVE_SUCCESS";
16 | export const GRID_RECEIVE_SAVE_FAIL = "GRID_RECEIVE_SAVE_FAIL";
17 | export const GRID_ROWS_UPDATE = "GRID_ROWS_UPDATE";
18 | // PAGING
19 | export const PAGING_CHANGE_LIMIT = "PAGING_CHANGE_LIMIT";
20 | // BULK SELECTION
21 | export const BULK_DISPLAY = "BULK_DISPLAY";
--------------------------------------------------------------------------------