diff --git a/src/actions/index.js b/src/actions/index.js
index e2095c0f..7b7cf347 100644
--- a/src/actions/index.js
+++ b/src/actions/index.js
@@ -7,6 +7,7 @@ import {
GRIDDLE_TOGGLE_SETTINGS,
GRIDDLE_TOGGLE_COLUMN,
GRIDDLE_SET_PAGE_SIZE,
+ GRIDDLE_UPDATE_STATE,
} from '../constants';
export function getNext() {
@@ -61,3 +62,10 @@ export function setPageSize(pageSize) {
pageSize
}
}
+
+export function updateState({ data = [], pageProperties = {}, sortProperties = {} }) {
+ return {
+ type: GRIDDLE_UPDATE_STATE,
+ newState: { data, pageProperties, sortProperties }
+ }
+}
diff --git a/src/plugins/local/components/CellContainer.js b/src/components/CellContainer.js
similarity index 78%
rename from src/plugins/local/components/CellContainer.js
rename to src/components/CellContainer.js
index 3bb98304..3a8ff443 100644
--- a/src/plugins/local/components/CellContainer.js
+++ b/src/components/CellContainer.js
@@ -2,8 +2,7 @@ import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { getContext, mapProps, compose, withHandlers } from 'recompose';
-import { cellValueSelector } from '../selectors/localSelectors';
-import { customComponentSelector } from '../../../selectors/dataSelectors';
+import { customComponentSelector, cellValueSelector } from '../selectors/dataSelectors';
const ComposedCellContainer = OriginalComponent => compose(
connect((state, props) => ({
@@ -26,4 +25,4 @@ const ComposedCellContainer = OriginalComponent => compose(
/>
))
-export default ComposedCellContainer;
\ No newline at end of file
+export default ComposedCellContainer;
diff --git a/src/components/ColumnDefinition.js b/src/components/ColumnDefinition.js
index 8f9c25f0..a674b17f 100644
--- a/src/components/ColumnDefinition.js
+++ b/src/components/ColumnDefinition.js
@@ -49,7 +49,6 @@ export default class ColumnDefinition extends Component {
};
render() {
- console.log('in column definition');
return null;
}
}
diff --git a/src/components/Filter.js b/src/components/Filter.js
index dd35a621..e64fbb0f 100644
--- a/src/components/Filter.js
+++ b/src/components/Filter.js
@@ -21,4 +21,4 @@ class Filter extends Component {
}
}
-export default Filter;
\ No newline at end of file
+export default Filter;
diff --git a/src/components/FilterContainer.js b/src/components/FilterContainer.js
index 59ac7352..9aaa77a1 100644
--- a/src/components/FilterContainer.js
+++ b/src/components/FilterContainer.js
@@ -1,12 +1,13 @@
-import React from 'react';
-import { connect } from 'react-redux';
-import { setFilter } from '../actions';
+import React, { PropTypes } from 'react';
+import { withHandlers, getContext, compose, mapProps } from 'recompose';
-const EnhancedFilterContainer = OriginalComponent => connect(
- null,
- {
- setFilter
- }
-)((props) => );
+const EnhancedFilter = OriginalComponent => compose(
+ getContext({
+ events: PropTypes.object
+ }),
+ mapProps(props => ({
+ setFilter: props.events.onFilter
+ }))
+)(({setFilter}) => );
-export default EnhancedFilterContainer;
\ No newline at end of file
+export default EnhancedFilter;
diff --git a/src/components/PageDropdown.js b/src/components/PageDropdown.js
index 93ed7c02..851f02a9 100644
--- a/src/components/PageDropdown.js
+++ b/src/components/PageDropdown.js
@@ -1,8 +1,13 @@
import React, { PropTypes, Component } from 'react';
+import _ from 'lodash';
/** Gets a range from a single value.
* Could probably make this take a predicate to avoid running through the loop twice */
-const getRange = (number) => Array(number).fill().map((_, i) => i + 1);
+const getRange = (number) => {
+ if (!_.isFinite(number)) { return [0] }
+
+ return Array(number).fill().map((_, i) => i + 1);
+}
class PageDropdown extends Component {
static propTypes = {
@@ -25,7 +30,7 @@ class PageDropdown extends Component {
>
{getRange(maxPages)
.map(num => (
-
+
))}
);
diff --git a/src/components/PaginationContainer.js b/src/components/PaginationContainer.js
new file mode 100644
index 00000000..890bb9f0
--- /dev/null
+++ b/src/components/PaginationContainer.js
@@ -0,0 +1,29 @@
+import React, { PropTypes } from 'react';
+import { bindActionCreators } from 'redux'
+import { connect } from 'react-redux';
+import { compose, mapProps, getContext } from 'recompose';
+import { createStructuredSelector } from 'reselect';
+
+import { hasNextSelector, hasPreviousSelector, currentPageSelector, maxPageSelector } from '../selectors/dataSelectors';
+
+const EnhancedPaginationContainer = OriginalComponent => compose(
+ getContext({
+ events: PropTypes.object
+ }),
+ connect(
+ createStructuredSelector({
+ hasNext: hasNextSelector,
+ hasPrevious: hasPreviousSelector,
+ maxPages: maxPageSelector,
+ currentPage: currentPageSelector
+ }),
+ ),
+ mapProps(({ events: {onNext:getNext, onPrevious:getPrevious, onGetPage:setPage }, ...props }) => ({
+ getNext,
+ getPrevious,
+ setPage,
+ ...props
+ }))
+)((props) => );
+
+export default EnhancedPaginationContainer;
diff --git a/src/components/Row.js b/src/components/Row.js
index 5c57e558..48648eb4 100644
--- a/src/components/Row.js
+++ b/src/components/Row.js
@@ -4,6 +4,7 @@ const Row = ({Cell, griddleKey, columnIds}) => (
{ columnIds && columnIds.map(c => (
|
diff --git a/src/components/RowContainer.js b/src/components/RowContainer.js
new file mode 100644
index 00000000..15f10409
--- /dev/null
+++ b/src/components/RowContainer.js
@@ -0,0 +1,25 @@
+import React, { PropTypes } from 'react';
+import { connect } from 'react-redux';
+import { getContext, mapProps, compose, withHandlers } from 'recompose';
+import { columnIdsSelector } from '../selectors/dataSelectors';
+
+const ComposedRowContainer = OriginalComponent => compose(
+ getContext({
+ components: PropTypes.object
+ }),
+ connect((state) => ({
+ columnIds: columnIdsSelector(state)
+ })),
+ mapProps(props => ({
+ Cell: props.components.Cell,
+ ...props
+ })),
+)(({Cell, columnIds, griddleKey}) => (
+
+));
+
+export default ComposedRowContainer;
diff --git a/src/components/RowDefinition.js b/src/components/RowDefinition.js
index 13d5d13a..3e8f3ffc 100644
--- a/src/components/RowDefinition.js
+++ b/src/components/RowDefinition.js
@@ -25,4 +25,4 @@ export default class extends Component {
render () {
return null;
}
-}
\ No newline at end of file
+}
diff --git a/src/components/TableBodyContainer.js b/src/components/TableBodyContainer.js
new file mode 100644
index 00000000..a4a4d79c
--- /dev/null
+++ b/src/components/TableBodyContainer.js
@@ -0,0 +1,28 @@
+import React, { PropTypes } from 'react';
+import { connect } from 'react-redux';
+import { getContext, mapProps, compose, withHandlers } from 'recompose';
+
+import { visibleRowIdsSelector } from '../selectors/dataSelectors';
+
+const ComposedTableBodyContainer = OriginalComponent => compose(
+ getContext({
+ components: PropTypes.object
+ }),
+ connect((state) => ({
+ visibleRowIds: visibleRowIdsSelector(state)
+ })),
+ mapProps(props => ({
+ Row: props.components.Row,
+ ...props
+ })),
+ // withHandlers({
+ // Row: props => props.components.Row
+ // })
+)(({Row, visibleRowIds}) => (
+
+));
+
+export default ComposedTableBodyContainer;
diff --git a/src/components/TableHeadingCellContainer.js b/src/components/TableHeadingCellContainer.js
new file mode 100644
index 00000000..01eb3f78
--- /dev/null
+++ b/src/components/TableHeadingCellContainer.js
@@ -0,0 +1,59 @@
+import React, { PropTypes } from 'react';
+import { connect } from 'react-redux';
+import { getContext, mapProps, compose, withHandlers } from 'recompose';
+import { sortPropertyByIdSelector, iconByNameSelector, customHeadingComponentSelector } from '../selectors/dataSelectors';
+import { setSortProperties } from '../utils/columnUtils';
+
+const DefaultTableHeadingCellContent = ({title, icon}) => (
+
+ { title }
+ { icon && {icon} }
+
+)
+
+function getIcon({sortProperty, sortAscendingIcon, sortDescendingIcon}) {
+console.log(sortProperty);
+ if (sortProperty) {
+ return sortProperty.sortAscending ? sortAscendingIcon : sortDescendingIcon;
+ }
+
+ // return null so we don't render anything if no sortProperty
+ return null;
+}
+
+const EnhancedHeadingCell = OriginalComponent => compose(
+ connect(
+ (state, props) => ({
+ sortProperty: sortPropertyByIdSelector(state, props),
+ sortAscendingIcon: iconByNameSelector(state, { name: 'sortAscending'}),
+ sortDescendingIcon: iconByNameSelector(state, { name: 'sortDescending'}),
+ customHeadingComponent: customHeadingComponentSelector(state, props)
+ })
+ ),
+ getContext({
+ events: PropTypes.object
+ }),
+ withHandlers({
+ onClick: ({ events: { onSort }, columnId }) => event => {
+ onSort({ id: columnId })
+ }
+ }),
+ mapProps(props => {
+ const icon = getIcon(props);
+ const title = props.customHeadingComponent ?
+ :
+ ;
+
+ return {
+ ...props,
+ icon,
+ title
+ };
+ })
+)((props) => {
+ return (
+
+ );
+});
+
+export default EnhancedHeadingCell;
diff --git a/src/components/TableHeadingContainer.js b/src/components/TableHeadingContainer.js
new file mode 100644
index 00000000..9684baca
--- /dev/null
+++ b/src/components/TableHeadingContainer.js
@@ -0,0 +1,28 @@
+import React, { PropTypes } from 'react';
+import { connect } from 'react-redux';
+import { getContext, mapProps, compose, withHandlers } from 'recompose';
+import { columnTitlesSelector, columnIdsSelector } from '../selectors/dataSelectors';
+
+const ComposedContainerComponent = OriginalComponent => compose(
+ getContext({
+ components: PropTypes.object
+ }),
+ connect((state) => ({
+ columnTitles: columnTitlesSelector(state),
+ columnIds: columnIdsSelector(state)
+ })),
+ mapProps(props => ({
+ TableHeadingCell: props.components.TableHeadingCell,
+ ...props
+ }))
+ // withHandlers({
+ // TableHeadingCell: props => props.components.TableHeadingCell
+ // })
+)(({TableHeadingCell, columnTitles, columnIds }) => (
+
+));
+
+export default ComposedContainerComponent;
diff --git a/src/components/index.js b/src/components/index.js
index 98458ff3..5cbfed7f 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -1,13 +1,19 @@
import Cell from './Cell';
+import CellContainer from './CellContainer';
import Row from './Row';
+import RowContainer from './RowContainer';
import Table from './Table';
import TableBody from './TableBody';
+import TableBodyContainer from './TableBodyContainer';
import TableHeading from './TableHeading';
+import TableHeadingContainer from './TableHeadingContainer';
import TableHeadingCell from './TableHeadingCell';
+import TableHeadingCellContainer from './TableHeadingCellContainer';
import TableContainer from './TableContainer';
import Layout from './Layout';
import LayoutContainer from './LayoutContainer';
import Pagination from './Pagination';
+import PaginationContainer from './PaginationContainer';
import Filter from './Filter';
import FilterContainer from './FilterContainer';
import SettingsToggle from './SettingsToggle';
@@ -19,15 +25,21 @@ import SettingsContainer from './SettingsContainer';
const components = {
Cell,
+ CellContainer,
Row,
+ RowContainer,
Table,
TableBody,
+ TableBodyContainer,
TableHeading,
+ TableHeadingContainer,
TableHeadingCell,
+ TableHeadingCellContainer,
TableContainer,
Layout,
LayoutContainer,
Pagination,
+ PaginationContainer,
Filter,
FilterContainer,
SettingsToggle,
diff --git a/src/constants/index.js b/src/constants/index.js
index 6c67a562..9bf25151 100644
--- a/src/constants/index.js
+++ b/src/constants/index.js
@@ -17,3 +17,4 @@ export const GRIDDLE_TOGGLE_COLUMN = 'GRIDDLE_TOGGLE_COLUMN';
export const GRIDDLE_ROW_TOGGLED = 'GRIDDLE_ROW_TOGGLED';
export const GRIDDLE_ROW_SELECTION_TOGGLED = 'GRIDDLE_ROW_SELECTION_TOGGLED';
export const GRIDDLE_TOGGLE_SETTINGS = 'GRIDDLE_TOGGLE_SETTINGS';
+export const GRIDDLE_UPDATE_STATE = 'GRIDDLE_UPDATE_STATE';
diff --git a/src/index.js b/src/index.js
index 0b385cda..800ae5be 100644
--- a/src/index.js
+++ b/src/index.js
@@ -10,17 +10,19 @@ import settingsComponentObjects from './settingsComponentObjects';
import { buildGriddleReducer, buildGriddleComponents } from './utils/compositionUtils';
import { getColumnProperties } from './utils/columnUtils';
import { getRowProperties } from './utils/rowUtils';
+import { updateState } from './actions';
-export default class extends Component {
+class Griddle extends Component {
static childContextTypes = {
components: React.PropTypes.object.isRequired,
- settingsComponentObjects: React.PropTypes.object
+ settingsComponentObjects: React.PropTypes.object,
+ events: React.PropTypes.object
}
constructor(props) {
super(props);
- const { plugins=[], data, children:rowPropertiesComponent } = props;
+ const { plugins=[], data, children:rowPropertiesComponent, events={}, sortProperties={} } = props;
const rowProperties = getRowProperties(rowPropertiesComponent);
const columnProperties = getColumnProperties(rowPropertiesComponent);
@@ -33,6 +35,8 @@ export default class extends Component {
this.settingsComponentObjects = Object.assign({}, settingsComponentObjects, ...plugins.map(p => plugins.settingsComponentObjects));
+ this.events = Object.assign({}, events, ...plugins.map(p => plugins.events));
+
//TODO: This should also look at the default and plugin initial state objects
const renderProperties = {
rowProperties,
@@ -81,10 +85,17 @@ export default class extends Component {
);
}
+ componentWillReceiveProps(nextProps) {
+ const { data, pageProperties, sortProperties } = nextProps;
+
+ this.store.dispatch(updateState({ data, pageProperties, sortProperties }));
+ }
+
getChildContext() {
return {
components: this.components,
settingsComponentObjects: this.settingsComponentObjects,
+ events: this.events,
};
}
@@ -97,3 +108,5 @@ export default class extends Component {
}
}
+
+export default Griddle;
diff --git a/src/plugins/local/components/FilterContainer.js b/src/plugins/local/components/FilterContainer.js
new file mode 100644
index 00000000..0f84ea5c
--- /dev/null
+++ b/src/plugins/local/components/FilterContainer.js
@@ -0,0 +1,12 @@
+import React from 'react';
+import { connect } from 'react-redux';
+import { setFilter } from '../../../actions';
+
+const EnhancedFilterContainer = OriginalComponent => connect(
+ null,
+ {
+ setFilter
+ }
+)((props) => );
+
+export default EnhancedFilterContainer;
diff --git a/src/plugins/local/components/TableHeadingContainer.js b/src/plugins/local/components/TableHeadingContainer.js
index 700e19f0..7e570492 100644
--- a/src/plugins/local/components/TableHeadingContainer.js
+++ b/src/plugins/local/components/TableHeadingContainer.js
@@ -25,4 +25,4 @@ const ComposedContainerComponent = OriginalComponent => compose(
TableHeadingCell={TableHeadingCell} />
));
-export default ComposedContainerComponent;
\ No newline at end of file
+export default ComposedContainerComponent;
diff --git a/src/plugins/local/components/index.js b/src/plugins/local/components/index.js
index 04b8a4e5..ef1a2a38 100644
--- a/src/plugins/local/components/index.js
+++ b/src/plugins/local/components/index.js
@@ -1,15 +1,13 @@
-import TableHeadingContainer from './TableHeadingContainer';
import TableBodyContainer from './TableBodyContainer';
import RowContainer from './RowContainer';
-import CellContainer from './CellContainer';
import PaginationContainer from './PaginationContainer';
import TableHeadingCellContainer from './TableHeadingCellContainer';
+import FilterContainer from './FilterContainer';
export default {
TableBodyContainer,
- TableHeadingContainer,
RowContainer,
- CellContainer,
PaginationContainer,
TableHeadingCellContainer,
-}
\ No newline at end of file
+ FilterContainer,
+}
diff --git a/src/plugins/local/selectors/localSelectors.js b/src/plugins/local/selectors/localSelectors.js
index 4a567eb1..673d8b1c 100644
--- a/src/plugins/local/selectors/localSelectors.js
+++ b/src/plugins/local/selectors/localSelectors.js
@@ -183,12 +183,7 @@ export const columnTitlesSelector = createSelector(
}
)
-// TODO: Needs tests and jsdoc
-export const cellValueSelector = (state, { griddleKey, columnId }) => {
- return state.get('data')
- .find(r => r.get('griddleKey') === griddleKey)
- .get(columnId);
-}
+export const cellValueSelector = dataSelectors.cellValueSelector;
// TODO: Needs tests and jsdoc
export const rowDataSelector = (state, { griddleKey}) => {
diff --git a/src/reducers/dataReducer.js b/src/reducers/dataReducer.js
index 99bb52b2..050c14f6 100644
--- a/src/reducers/dataReducer.js
+++ b/src/reducers/dataReducer.js
@@ -97,7 +97,7 @@ export function GRIDDLE_TOGGLE_SETTINGS(state, action) {
return state.set('showSettings', !showSettings);
}
-export function GRIDDLE_TOGGLE_COLUMN(state, action) {
+export function GRIDDLE_TOGGLE_COLUMN(state, action) {
// flips the visible state if the column property exists
return state.getIn(['renderProperties', 'columnProperties', action.columnId]) ?
state.setIn(['renderProperties', 'columnProperties', action.columnId, 'visible'],
@@ -107,3 +107,7 @@ export function GRIDDLE_TOGGLE_COLUMN(state, action) {
state.setIn(['renderProperties', 'columnProperties', action.columnId],
new Immutable.Map({ id: action.columnId, visible: true }))
}
+
+export function GRIDDLE_UPDATE_STATE(state, action) {
+ return state.mergeDeep(action.newState);
+}
diff --git a/src/selectors/__tests__/dataSelectorsTest.js b/src/selectors/__tests__/dataSelectorsTest.js
index 5fa2d7ed..3a9b8cff 100644
--- a/src/selectors/__tests__/dataSelectorsTest.js
+++ b/src/selectors/__tests__/dataSelectorsTest.js
@@ -90,19 +90,19 @@ test('gets max page', test => {
}
});
- test.is(selectors.maxPageCountSelector(state), 2);
+ test.is(selectors.maxPageSelector(state), 2);
//ensure that we get 2 pages when full pageSize would not be displayed on next page
const otherState = state.setIn(['pageProperties', 'pageSize'], 11);
- test.is(selectors.maxPageCountSelector(otherState), 2);
+ test.is(selectors.maxPageSelector(otherState), 2);
//when pageSize === recordCount should have 1 page
const onePageState = state.setIn(['pageProperties', 'pageSize'], 20);
- test.is(selectors.maxPageCountSelector(onePageState), 1);
+ test.is(selectors.maxPageSelector(onePageState), 1);
//when there are no records, there should be 0 pages
const noDataState = state.setIn(['pageProperties', 'recordCount'], 0);
- test.is(selectors.maxPageCountSelector(noDataState), 0);
+ test.is(selectors.maxPageSelector(noDataState), 0);
});
/* filterSelector */
diff --git a/src/selectors/dataSelectors.js b/src/selectors/dataSelectors.js
index 759d57b3..9ba97604 100644
--- a/src/selectors/dataSelectors.js
+++ b/src/selectors/dataSelectors.js
@@ -1,5 +1,6 @@
import Immutable from 'immutable';
import { createSelector } from 'reselect';
+import _ from 'lodash';
import MAX_SAFE_INTEGER from 'max-safe-integer'
//import { createSelector } from 'reselect';
@@ -19,27 +20,34 @@ export const recordCountSelector = state => state.getIn(['pageProperties', 'reco
/** Gets the render properties */
export const renderPropertiesSelector = state => (state.get('renderProperties'));
-/** Determines if there are more pages available. Assumes pageProperties.maxPage is set by the container */
-export const hasNextSelector = createSelector(
- currentPageSelector,
- pageSizeSelector,
- recordCountSelector,
- (currentPage, pageSize, recordCount) => {
- return (currentPage * pageSize) < recordCount;
- }
-);
-
/** Determines if there are previous pages */
export const hasPreviousSelector = createSelector(
currentPageSelector,
(currentPage) => (currentPage > 1)
);
-/** Determines the maxPageCount based on pageSize / recordCount */
-export const maxPageCountSelector = createSelector(
+/** Gets the max page size
+ */
+export const maxPageSelector = createSelector(
pageSizeSelector,
recordCountSelector,
- (pageSize, recordCount) => (Math.ceil(recordCount / pageSize))
+ (pageSize, recordCount) => {
+ const calc = recordCount / pageSize;
+
+ const result = calc > Math.floor(calc) ? Math.floor(calc) + 1 : Math.floor(calc);
+
+ return _.isFinite(result) ? result : 1;
+ }
+);
+
+/** Determines if there are more pages available. Assumes pageProperties.maxPage is set by the container */
+export const hasNextSelector = createSelector(
+ currentPageSelector,
+ maxPageSelector,
+ (currentPage, maxPage) => {
+ console.log(`hasNext current: ${currentPage} max: ${maxPage}`)
+ return currentPage < maxPage;
+ }
);
/** Gets current filter */
@@ -184,3 +192,46 @@ export const textSelector = (state, { key}) => {
return state.getIn(['textProperties', key]);
}
+/** Gets the column ids for the visible columns
+*/
+export const columnIdsSelector = createSelector(
+ dataSelector,
+ renderPropertiesSelector,
+ (visibleData, renderProperties) => {
+ if(visibleData.size > 0) {
+ return Object.keys(visibleData.get(0).toJSON()).map(k =>
+ renderProperties.getIn(['columnProperties', k, 'id']) || k
+ )
+ }
+ }
+)
+
+/** Gets the column titles for the visible columns
+ */
+export const columnTitlesSelector = createSelector(
+ dataSelector,
+ renderPropertiesSelector,
+ (visibleData, renderProperties) => {
+ if(visibleData.size > 0) {
+ return Object.keys(visibleData.get(0).toJSON()).map(k =>
+ renderProperties.getIn(['columnProperties', k, 'title']) || k
+ )
+ }
+
+ return [];
+ }
+)
+
+/** Gets the griddleIds for the visible rows */
+export const visibleRowIdsSelector = createSelector(
+ dataSelector,
+ (currentPageData) => currentPageData.map(c => c.get('griddleKey'))
+);
+
+// TODO: Needs tests and jsdoc
+export const cellValueSelector = (state, { griddleKey, columnId }) => {
+ return state.get('data')
+ .find(r => r.get('griddleKey') === griddleKey)
+ .get(columnId);
+}
+
diff --git a/src/utils/rowUtils.js b/src/utils/rowUtils.js
index e5157143..609469b1 100644
--- a/src/utils/rowUtils.js
+++ b/src/utils/rowUtils.js
@@ -2,6 +2,8 @@
* @param {Object} rowPropertiesComponent - A react component that contains rowProperties as props
*/
export function getRowProperties(rowPropertiesComponent) {
+ if (!rowPropertiesComponent) return null;
+
let rowProps = Object.assign({}, rowPropertiesComponent.props);
delete rowProps.children;
@@ -10,4 +12,4 @@ export function getRowProperties(rowPropertiesComponent) {
}
return rowProps;
-}
\ No newline at end of file
+}
diff --git a/stories/index.js b/stories/index.js
index 61d9c311..3fe7c065 100644
--- a/stories/index.js
+++ b/stories/index.js
@@ -13,7 +13,7 @@ import { Table } from '../src/components/Table';
import TableContainer from '../src/components/TableContainer';
import ColumnDefinition from '../src/components/ColumnDefinition';
import RowDefinition from '../src/components/RowDefinition';
-
+import _ from 'lodash';
import { rowDataSelector } from '../src/plugins/local/selectors/localSelectors';
import fakeData from './fakeData';
@@ -36,6 +36,17 @@ function sortBySecondCharacter(data, column, sortAscending = true) {
});
}
+// from mdn
+function getRandomIntInclusive(min, max) {
+ min = Math.ceil(min);
+ max = Math.floor(max);
+ return Math.floor(Math.random() * (max - min + 1)) + min;
+}
+
+function getRandomFakeData() {
+ const start = getRandomIntInclusive(0, fakeData.length - 10);
+ return fakeData.slice(start, start + 10);
+}
const GreenLeftSortIconComponent = (props) => (
{props.icon && {props.icon}}
@@ -89,7 +100,6 @@ storiesOf('Griddle main', module)
-
)
})
@@ -103,10 +113,79 @@ storiesOf('Griddle main', module)
-
)
})
+.add('with controlled griddle component', () => {
+
+ class Something extends React.Component {
+ constructor() {
+ super();
+
+ this.state = {
+ data: getRandomFakeData(),
+ sortProperties: {}
+ };
+ }
+
+ onFilter = (filter) => {
+ console.log('onFilter', filter);
+ this.setState({ data: getRandomFakeData() })
+ }
+
+ onSort = (sortProperties) => {
+ console.log('onSort', sortProperties);
+ this.setState({
+ data: getRandomFakeData(),
+ sortProperties: {
+ something: {
+ ...sortProperties,
+ sortAscending: getRandomIntInclusive(0,1) > 0 ? true : false
+ }
+ }
+ })
+ }
+
+ onNext = () => {
+ console.log('onNext');
+ this.setState({ data: getRandomFakeData() })
+ }
+
+ onPrevious = () => {
+ console.log('onPrevious');
+ this.setState({ data: getRandomFakeData() })
+ }
+
+ onGetPage = (pageNumber) => {
+ console.log('onGetPage', pageNumber);
+ this.setState({ data: getRandomFakeData() })
+ }
+
+ render() {
+ const pageProperties = {
+ currentPage: getRandomIntInclusive(1, 10),
+ recordCount: getRandomIntInclusive(1, 1000)
+ }
+
+ // don't do things this way - fine for example storybook
+ const events = {
+ onFilter: this.onFilter,
+ onSort: this.onSort,
+ onNext: this.onNext,
+ onPrevious: this.onPrevious,
+ onGetPage: this.onGetPage
+ }
+
+ return
+ }
+ }
+
+ return
+})
.add('with custom heading component', () => {
return (
@@ -117,7 +196,6 @@ storiesOf('Griddle main', module)
-
)
})