From de19addabf5f467ea2b469fb92abd71cac85b5f5 Mon Sep 17 00:00:00 2001 From: Niles Turner Date: Sun, 5 Nov 2017 09:30:56 -0500 Subject: [PATCH 01/12] progress --- src/app.jsx | 50 ++++++++++++++++++++- src/components/Pivot/Pivot.jsx | 81 +++++++++++++++++++++++++++------- src/components/Table/Table.jsx | 2 + 3 files changed, 116 insertions(+), 17 deletions(-) diff --git a/src/app.jsx b/src/app.jsx index a61afb7..55395bf 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -39,11 +39,15 @@ export default class App extends React.Component { gridBorders: '#e0e0e0', icons: '#ccc', }, + colFields: ['name'], + rowFields: ['gender'], + onLeftGridCellClick: () => console.log('clicking leftHeader') }; this.handleFileSelect = this.handleFileSelect.bind(this); this.onSelectData = this.onSelectData.bind(this); this.onSelectColorPack = this.onSelectColorPack.bind(this); + this.onButtonClick = this.onButtonClick.bind(this); } handleFileSelect(evt) { @@ -63,6 +67,8 @@ export default class App extends React.Component { data: data.smallData, isLoaded: true, selectedAggregationDimension: 'age', + colFields: [], + rowFields: [], }); } if (dataSize.value === 'medium') { @@ -71,6 +77,8 @@ export default class App extends React.Component { data: data.mediumData, isLoaded: true, selectedAggregationDimension: 'Quantity', + colFields: [], + rowFields: [], }); } if (dataSize.value === 'large') { @@ -86,12 +94,20 @@ export default class App extends React.Component { data: results.data, selectedAggregationDimension: 'Amount Requested', isLoaded: true, + colFields: [], + rowFields: [], }); }, }); } } + onButtonClick() { + this.setState({ + onLeftHeaderCellClick: function(){}, + }); + } + onSelectColorPack(colorPack) { if (colorPack.value === 'standard') { this.setState({ @@ -206,6 +222,7 @@ export default class App extends React.Component {
+
{ + console.log('got the state', prevState); + /* eslint-disable */ + var save = {"aggregationDimensions": + [{"value":"name","label":"name"},{"value":"gender","label":"gender"},{"value":"house","label":"house"},{"value":"age","label":"age"}], + "dataArray":null, + "fields":["name","gender","house","age"], + "pivot":null, + "colFields":["name"], + "rowFields": ["house"], + "selectedAggregationType":"sum", + "selectedAggregationDimension":"age", + "currentFilter":"", + "currentValues":[], + "filters":{}, + "columnWidth":100, + "columnCount":0, + "overscanColumnCount":5, + "overscanRowCount":5, + "headerHeight":40, + "rowHeight":30, + "rowCount":0, + "data":null, + "header":{}, + "headerCounter":0, + "isDrawerOpen":false} + this.setState({ + colFields: save.colFields, + rowFields: save.rowFields, + }); + }} colorPack={colorPack} data={data} onGridCellClick={({ @@ -304,7 +352,7 @@ export default class App extends React.Component { console.log('childrenData', childrenData); // eslint-disable-line no-console console.log('rowHeaders', rowHeaders); // eslint-disable-line no-console }} - onLeftHeaderCellClick={() => console.log('clicking leftHeader')} // eslint-disable-line no-console + onLeftHeaderCellClick={this.state.onLeftHeaderCellClick} // eslint-disable-line no-console selectedAggregationDimension={selectedAggregationDimension} /> diff --git a/src/components/Pivot/Pivot.jsx b/src/components/Pivot/Pivot.jsx index 72b4fa6..496c978 100644 --- a/src/components/Pivot/Pivot.jsx +++ b/src/components/Pivot/Pivot.jsx @@ -19,17 +19,29 @@ export default class Pivot extends PureComponent { const dataArray = this.props.data !== undefined ? this.props.data : []; const fields = this.props.data !== undefined ? this.props.data[0] : []; const pivot = this.props.data !== undefined ? - new QuickPivot(this.props.data, [], [], - this.props.selectedAggregationDimension || '', 'sum', '') : - {}; + new QuickPivot(this.props.data, this.props.rowFields || [], + this.props.colFields || [], this.props.selectedAggregationDimension || + '', 'sum', '') : {}; + + let headerCounter = 0; + + if (pivot.data) { + while (true) { + if (pivot.data.table[headerCounter].type === 'colHeader') { + headerCounter += 1; + } else { + break; + } + } + } this.state = { aggregationDimensions, dataArray, fields, pivot, - colFields: [], - rowFields: [], + colFields: this.props.colFields || [], + rowFields: this.props.rowFields || [], selectedAggregationType: 'sum', selectedAggregationDimension: this.props.selectedAggregationDimension || '', @@ -37,18 +49,23 @@ export default class Pivot extends PureComponent { currentValues: [], filters: {}, columnWidth: 100, - columnCount: 0, + columnCount: + (pivot !== undefined && pivot.data.table.length && + pivot.data.table[0].value.length) ? + pivot.data.table[0].value.length : 0, overscanColumnCount: 5, overscanRowCount: 5, headerHeight: 40, rowHeight: 30, - rowCount: 0, - data: [], + rowCount: pivot !== undefined ? pivot.data.table.length : 0, + data: pivot !== undefined ? pivot.data.table : [], header: {}, - headerCounter: 0, + headerCounter, isDrawerOpen: false, }; + console.log(this.state.data) + this.onSelectAggregationDimension = this.onSelectAggregationDimension.bind(this); this.onSelectAggregationType = this.onSelectAggregationType.bind(this); @@ -67,9 +84,15 @@ export default class Pivot extends PureComponent { } componentWillReceiveProps(nextProps) { + console.log('nextProps.colFields', nextProps.colFields) + console.log('nextProps.rowFields', nextProps.rowFields) + if (this.props.colorPack !== nextProps.colorPack) { + console.log('in here'); return; } + console.log('reached here'); + const aggregationDimensions = nextProps.data !== undefined ? nextProps.data[0].map((item, index) => { return {value: item, label: item}; @@ -77,9 +100,27 @@ export default class Pivot extends PureComponent { []; const dataArray = nextProps.data !== undefined ? nextProps.data : []; const fields = nextProps.data !== undefined ? nextProps.data[0] : []; + const pivot = nextProps.data !== undefined ? - new QuickPivot(nextProps.data, [], [], - nextProps.selectedAggregationDimension || '', 'sum', '') : {}; + new QuickPivot(nextProps.data, nextProps.rowFields || [], + nextProps.colFields || [], nextProps.selectedAggregationDimension || + '', 'sum', '') : {}; + + console.log('new Pivot', pivot); + + let headerCounter = 0; + + if (pivot.data) { + while (true) { + if (pivot.data.table[headerCounter].type === 'colHeader') { + headerCounter += 1; + } else { + break; + } + } + } + + console.log('headerCounter', headerCounter); // Reset entire state execpt selectedAggregationType this.setState({ @@ -87,23 +128,29 @@ export default class Pivot extends PureComponent { dataArray, fields, pivot, - colFields: [], - rowFields: [], + colFields: nextProps.colFields || [], + rowFields: nextProps.rowFields || [], selectedAggregationDimension: nextProps.selectedAggregationDimension || '', currentFilter: '', currentValues: [], filters: {}, columnWidth: 100, - columnCount: 0, + columnCount: + (pivot !== undefined && pivot.data.table.length && + pivot.data.table[0].value.length) ? + pivot.data.table[0].value.length : 0, overscanColumnCount: 0, overscanRowCount: 5, rowHeight: 30, - rowCount: 0, + rowCount: pivot !== undefined ? pivot.data.table.length : 0, data: [], header: {}, - headerCounter: 0, + headerCounter, }); + + // this.props.onChange(this.state); + console.log('final state', this.state); } onSelectAggregationType(selectedAggregationType) { @@ -442,6 +489,8 @@ export default class Pivot extends PureComponent { { value: 'average', label: 'average' }, ]; + console.log('jesus im in the table render with data', data) + return (
Date: Sun, 12 Nov 2017 15:34:41 -0500 Subject: [PATCH 02/12] progress --- src/app.jsx | 47 ++++------- src/components/Pivot/Pivot.jsx | 143 +++++++++++++++++++-------------- src/components/Table/Table.jsx | 2 - 3 files changed, 95 insertions(+), 97 deletions(-) diff --git a/src/app.jsx b/src/app.jsx index 55395bf..84ccd64 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -41,7 +41,14 @@ export default class App extends React.Component { }, colFields: ['name'], rowFields: ['gender'], - onLeftGridCellClick: () => console.log('clicking leftHeader') + onLeftGridCellClick: () => console.log('clicking leftHeader'), + pivotOnChangeFunction: (prevState) => { + /* eslint-disable */ + const newState = prevState; + prevState.colFields=["name","house"]; + console.log('new state', newState) + return newState + } }; this.handleFileSelect = this.handleFileSelect.bind(this); @@ -79,6 +86,7 @@ export default class App extends React.Component { selectedAggregationDimension: 'Quantity', colFields: [], rowFields: [], + pivotOnChangeFunction: undefined, }); } if (dataSize.value === 'large') { @@ -96,6 +104,7 @@ export default class App extends React.Component { isLoaded: true, colFields: [], rowFields: [], + pivotOnChangeFunction: undefined, }); }, }); @@ -104,7 +113,7 @@ export default class App extends React.Component { onButtonClick() { this.setState({ - onLeftHeaderCellClick: function(){}, + onLeftHeaderCellClick: function(){console.log('Changes OnClick')}, }); } @@ -283,37 +292,9 @@ export default class App extends React.Component {
{ - console.log('got the state', prevState); - /* eslint-disable */ - var save = {"aggregationDimensions": - [{"value":"name","label":"name"},{"value":"gender","label":"gender"},{"value":"house","label":"house"},{"value":"age","label":"age"}], - "dataArray":null, - "fields":["name","gender","house","age"], - "pivot":null, - "colFields":["name"], - "rowFields": ["house"], - "selectedAggregationType":"sum", - "selectedAggregationDimension":"age", - "currentFilter":"", - "currentValues":[], - "filters":{}, - "columnWidth":100, - "columnCount":0, - "overscanColumnCount":5, - "overscanRowCount":5, - "headerHeight":40, - "rowHeight":30, - "rowCount":0, - "data":null, - "header":{}, - "headerCounter":0, - "isDrawerOpen":false} - this.setState({ - colFields: save.colFields, - rowFields: save.rowFields, - }); - }} + colFields={this.state.colFields} + rowFields={this.state.rowFields} + onChange={this.state.pivotOnChangeFunction} colorPack={colorPack} data={data} onGridCellClick={({ diff --git a/src/components/Pivot/Pivot.jsx b/src/components/Pivot/Pivot.jsx index 496c978..84ab91f 100644 --- a/src/components/Pivot/Pivot.jsx +++ b/src/components/Pivot/Pivot.jsx @@ -64,8 +64,6 @@ export default class Pivot extends PureComponent { isDrawerOpen: false, }; - console.log(this.state.data) - this.onSelectAggregationDimension = this.onSelectAggregationDimension.bind(this); this.onSelectAggregationType = this.onSelectAggregationType.bind(this); @@ -84,73 +82,95 @@ export default class Pivot extends PureComponent { } componentWillReceiveProps(nextProps) { - console.log('nextProps.colFields', nextProps.colFields) - console.log('nextProps.rowFields', nextProps.rowFields) if (this.props.colorPack !== nextProps.colorPack) { console.log('in here'); return; } - console.log('reached here'); - - const aggregationDimensions = nextProps.data !== undefined ? - nextProps.data[0].map((item, index) => { - return {value: item, label: item}; - }) : - []; - const dataArray = nextProps.data !== undefined ? nextProps.data : []; - const fields = nextProps.data !== undefined ? nextProps.data[0] : []; - - const pivot = nextProps.data !== undefined ? - new QuickPivot(nextProps.data, nextProps.rowFields || [], - nextProps.colFields || [], nextProps.selectedAggregationDimension || - '', 'sum', '') : {}; - - console.log('new Pivot', pivot); - - let headerCounter = 0; - if (pivot.data) { - while (true) { - if (pivot.data.table[headerCounter].type === 'colHeader') { - headerCounter += 1; - } else { - break; + console.log('got the onChange Function', nextProps.onChange); + + if (nextProps.onChange !== undefined) { + const newState = this.props.onChange(this.state); + + this.setState({ + aggregationDimensions: newState.aggregationDimensions, + dataArray: newState.dataArray, + fields: newState.fields, + pivot: newState.pivot, + colFields: newState.colFields, + rowFields: newState.rowFields, + selectedAggregationType: newState.selectedAggregationType, + selectedAggregationDimension: newState.selectedAggregationDimension, + currentFilter: newState.currentFilter, + currentValues: newState.currentValues, + filters: newState.filters, + columnWidth: newState.columnWidth, + columnCount: + newState.columnCount, + overscanColumnCount: newState.overscanColumnCount, + overscanRowCount: newState.overscanRowCount, + headerHeight: newState.headerHeight, + rowHeight: newState.rowHeight, + rowCount: newState.rowCount, + data: newState.data, + header: newState.header, + headerCounter: newState.headerCounter, + isDrawerOpen: newState.isDrawerOpen, + }); + } else { + const aggregationDimensions = nextProps.data !== undefined ? + nextProps.data[0].map((item, index) => { + return {value: item, label: item}; + }) : + []; + const dataArray = nextProps.data !== undefined ? nextProps.data : []; + const fields = nextProps.data !== undefined ? nextProps.data[0] : []; + + const pivot = nextProps.data !== undefined ? + new QuickPivot(nextProps.data, nextProps.rowFields || [], + nextProps.colFields || [], nextProps.selectedAggregationDimension || + '', 'sum', '') : {}; + + let headerCounter = 0; + + if (pivot.data) { + while (true) { + if (pivot.data.table[headerCounter].type === 'colHeader') { + headerCounter += 1; + } else { + break; + } } } - } - - console.log('headerCounter', headerCounter); - // Reset entire state execpt selectedAggregationType - this.setState({ - aggregationDimensions, - dataArray, - fields, - pivot, - colFields: nextProps.colFields || [], - rowFields: nextProps.rowFields || [], - selectedAggregationDimension: nextProps.selectedAggregationDimension || - '', - currentFilter: '', - currentValues: [], - filters: {}, - columnWidth: 100, - columnCount: - (pivot !== undefined && pivot.data.table.length && - pivot.data.table[0].value.length) ? - pivot.data.table[0].value.length : 0, - overscanColumnCount: 0, - overscanRowCount: 5, - rowHeight: 30, - rowCount: pivot !== undefined ? pivot.data.table.length : 0, - data: [], - header: {}, - headerCounter, - }); - - // this.props.onChange(this.state); - console.log('final state', this.state); + // Reset entire state execpt selectedAggregationType + this.setState({ + aggregationDimensions, + dataArray, + fields, + pivot, + colFields: nextProps.colFields || [], + rowFields: nextProps.rowFields || [], + selectedAggregationDimension: nextProps.selectedAggregationDimension || + '', + currentFilter: '', + currentValues: [], + filters: {}, + columnWidth: 100, + columnCount: + (pivot !== undefined && pivot.data.table.length && + pivot.data.table[0].value.length) ? + pivot.data.table[0].value.length : 0, + overscanColumnCount: 0, + overscanRowCount: 5, + rowHeight: 30, + rowCount: pivot !== undefined ? pivot.data.table.length : 0, + data: pivot !== undefined ? pivot.data.table : [], + header: {}, + headerCounter, + }); + } } onSelectAggregationType(selectedAggregationType) { @@ -489,8 +509,6 @@ export default class Pivot extends PureComponent { { value: 'average', label: 'average' }, ]; - console.log('jesus im in the table render with data', data) - return (
Date: Sun, 12 Nov 2017 16:45:20 -0500 Subject: [PATCH 03/12] basic draft --- src/app.jsx | 2 +- src/components/Pivot/Pivot.jsx | 63 ++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/app.jsx b/src/app.jsx index 84ccd64..179aeae 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -231,7 +231,7 @@ export default class App extends React.Component {
- +
{ + return {value: item, label: item}; + }) : + []; + const dataArray = nextProps.data !== undefined ? nextProps.data : []; + const fields = nextProps.data !== undefined ? nextProps.data[0] : []; - if (this.props.colorPack !== nextProps.colorPack) { - console.log('in here'); - return; - } + const pivot = nextProps.data !== undefined ? + new QuickPivot(nextProps.data, newState.rowFields || [], + newState.colFields || [], newState.selectedAggregationDimension || + '', 'sum', '') : {}; - console.log('got the onChange Function', nextProps.onChange); + let headerCounter = 0; - if (nextProps.onChange !== undefined) { - const newState = this.props.onChange(this.state); + if (pivot.data) { + while (true) { + if (pivot.data.table[headerCounter].type === 'colHeader') { + headerCounter += 1; + } else { + break; + } + } + } this.setState({ - aggregationDimensions: newState.aggregationDimensions, - dataArray: newState.dataArray, - fields: newState.fields, - pivot: newState.pivot, + aggregationDimensions, + dataArray: dataArray, + fields, + pivot, colFields: newState.colFields, rowFields: newState.rowFields, - selectedAggregationType: newState.selectedAggregationType, - selectedAggregationDimension: newState.selectedAggregationDimension, - currentFilter: newState.currentFilter, - currentValues: newState.currentValues, - filters: newState.filters, - columnWidth: newState.columnWidth, + selectedAggregationDimension: newState.selectedAggregationDimension || + '', + currentFilter: '', + currentValues: [], + filters: {}, + columnWidth: 100, columnCount: - newState.columnCount, + (pivot !== undefined && pivot.data.table.length && + pivot.data.table[0].value.length) ? + pivot.data.table[0].value.length : 0, overscanColumnCount: newState.overscanColumnCount, overscanRowCount: newState.overscanRowCount, headerHeight: newState.headerHeight, rowHeight: newState.rowHeight, - rowCount: newState.rowCount, - data: newState.data, - header: newState.header, - headerCounter: newState.headerCounter, + rowCount: pivot !== undefined ? pivot.data.table.length : 0, + data: pivot !== undefined ? pivot.data.table : [], + header: {}, + headerCounter: headerCounter, isDrawerOpen: newState.isDrawerOpen, }); + } else { const aggregationDimensions = nextProps.data !== undefined ? nextProps.data[0].map((item, index) => { From e383a24b3f50653512d8aa43e500c51a904229a5 Mon Sep 17 00:00:00 2001 From: Niles Turner Date: Sun, 12 Nov 2017 17:05:26 -0500 Subject: [PATCH 04/12] small change --- src/app.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.jsx b/src/app.jsx index 179aeae..704f8b7 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -45,7 +45,7 @@ export default class App extends React.Component { pivotOnChangeFunction: (prevState) => { /* eslint-disable */ const newState = prevState; - prevState.colFields=["name","house"]; + newState.colFields=["name","house"]; console.log('new state', newState) return newState } From bc9a7394612becfe6a0216705c83a906d3ef99a6 Mon Sep 17 00:00:00 2001 From: Niles Turner Date: Sun, 12 Nov 2017 21:22:13 -0500 Subject: [PATCH 05/12] adds deps and updating quick-pivot --- package.json | 20 +- .../CustomReactSortable.jsx | 160 +- .../CustomReactSortable/CustomSortable.js | 2931 +++++++++-------- src/components/Pivot/Pivot.jsx | 2 + yarn.lock | 91 +- 5 files changed, 1631 insertions(+), 1573 deletions(-) diff --git a/package.json b/package.json index bededad..faf8a93 100644 --- a/package.json +++ b/package.json @@ -49,11 +49,14 @@ "verbose": true }, "dependencies": { - "babel-runtime": "^6.26.0", - "quick-pivot": "^2.2.6", - "react-draggable": "^2.2.6", - "react-select": "^1.0.0-rc.5", - "react-virtualized": "^9.9.0" + "quick-pivot": "^2.3.0", + "react": "^16.1.0", + "react-dom": "^16.1.0", + "react-draggable": "^3.0.3", + "react-select": "^1.0.0-rc.10", + "react-sortablejs": "^1.3.5", + "react-virtualized": "^9.12.0", + "sortablejs": "^1.7.0" }, "devDependencies": { "autoprefixer": "^7.1.2", @@ -72,6 +75,7 @@ "babel-preset-es2015": "^6.22.0", "babel-preset-react": "^6.24.1", "babel-preset-stage-2": "^6.24.1", + "babel-runtime": "^6.26.0", "cross-env": "^5.0.5", "css-loader": "0.26.1", "enzyme": "^2.8.2", @@ -94,9 +98,7 @@ "pre-commit": "^1.2.2", "prop-types": "^15.5.10", "raf": "^3.3.2", - "react": "^15.6.1", "react-addons-test-utils": "^15.5.1", - "react-dom": "^15.6.1", "react-hot-loader": "^3.0.0-beta.7", "rimraf": "^2.6.1", "sass-loader": "^6.0.6", @@ -107,9 +109,5 @@ "webpack-dashboard": "^0.3.0", "webpack-dev-server": "^2.4.1", "webpack-node-externals": "^1.6.0" - }, - "peerDependencies": { - "react": "^15.6.1", - "react-dom": "^15.6.1" } } diff --git a/src/components/CustomReactSortable/CustomReactSortable.jsx b/src/components/CustomReactSortable/CustomReactSortable.jsx index f9eee98..54f6035 100644 --- a/src/components/CustomReactSortable/CustomReactSortable.jsx +++ b/src/components/CustomReactSortable/CustomReactSortable.jsx @@ -1,3 +1,4 @@ +/* eslint-disable */ /* eslint consistent-return: 0 */ import PropTypes from 'prop-types'; import React, { Component } from 'react'; @@ -5,106 +6,97 @@ import ReactDOM from 'react-dom'; import SortableJS from './CustomSortable'; const store = { - nextSibling: null, - activeComponent: null, + nextSibling: null, + activeComponent: null }; class Sortable extends Component { static propTypes = { - options: PropTypes.object, - onChange: PropTypes.func, - tag: PropTypes.string, - style: PropTypes.object, + options: PropTypes.object, + onChange: PropTypes.func, + tag: PropTypes.string, + style: PropTypes.object }; static defaultProps = { - options: {}, - tag: 'div', - style: {}, + options: {}, + tag: 'div', + style: {} }; sortable = null; componentDidMount() { - const options = { ...this.props.options }; - - [ - 'onChoose', - 'onStart', - 'onEnd', - 'onAdd', - 'onUpdate', - 'onSort', - 'onRemove', - 'onFilter', - 'onMove', - 'onClone', - ].forEach((name) => { - const eventHandler = options[name]; - - options[name] = (...params) => { - const [evt] = params; - - if (name === 'onChoose') { - store.nextSibling = evt.item.nextElementSibling; - store.activeComponent = this; - } else if ((name === 'onAdd' || name === 'onUpdate') && - this.props.onChange) { - const items = this.sortable.toArray(); - const remote = store.activeComponent; - const remoteItems = remote.sortable.toArray(); - - const referenceNode = (store.nextSibling && - store.nextSibling.parentNode !== null) ? - store.nextSibling : null; - - evt.from.insertBefore(evt.item, referenceNode); - if (remote !== this) { - const remoteOptions = remote.props.options || {}; - - if ((typeof remoteOptions.group === 'object') && - (remoteOptions.group.pull === 'clone')) { - // Remove the node with the same data-reactid - evt.item.parentNode.removeChild(evt.item); - } - - remote.props.onChange && - remote.props.onChange(remoteItems, remote.sortable, evt); - } - - this.props.onChange && - this.props.onChange(items, this.sortable, evt); - } - - if (evt.type === 'move') { - const [evt, originalEvent] = params; - const canMove = eventHandler ? - eventHandler(evt, originalEvent) : true; - - return canMove; - } - - setTimeout(() => { - eventHandler && eventHandler(evt); - }, 0); - }; - }); - - this.sortable = SortableJS.create(ReactDOM.findDOMNode(this), options); + const options = { ...this.props.options }; + + [ + 'onChoose', + 'onStart', + 'onEnd', + 'onAdd', + 'onUpdate', + 'onSort', + 'onRemove', + 'onFilter', + 'onMove', + 'onClone' + ].forEach((name) => { + const eventHandler = options[name]; + + options[name] = (...params) => { + const [evt] = params; + + if (name === 'onChoose') { + store.nextSibling = evt.item.nextElementSibling; + store.activeComponent = this; + } else if ((name === 'onAdd' || name === 'onUpdate') && this.props.onChange) { + const items = this.sortable.toArray(); + const remote = store.activeComponent; + const remoteItems = remote.sortable.toArray(); + + const referenceNode = (store.nextSibling && store.nextSibling.parentNode !== null) ? store.nextSibling : null; + evt.from.insertBefore(evt.item, referenceNode); + if (remote !== this) { + const remoteOptions = remote.props.options || {}; + + if ((typeof remoteOptions.group === 'object') && (remoteOptions.group.pull === 'clone')) { + // Remove the node with the same data-reactid + evt.item.parentNode.removeChild(evt.item); + } + + remote.props.onChange && remote.props.onChange(remoteItems, remote.sortable, evt); + } + + this.props.onChange && this.props.onChange(items, this.sortable, evt); + } + + if (evt.type === 'move') { + const [evt, originalEvent] = params; + const canMove = eventHandler ? eventHandler(evt, originalEvent) : true; + return canMove; + } + + setTimeout(() => { + eventHandler && eventHandler(evt); + }, 0); + }; + }); + + this.sortable = SortableJS.create(ReactDOM.findDOMNode(this), options); } componentWillUnmount() { - if (this.sortable) { - this.sortable.destroy(); - this.sortable = null; - } + if (this.sortable) { + this.sortable.destroy(); + this.sortable = null; + } } render() { - const { tag: Component, ...props } = this.props; + const { tag: Component, ...props } = this.props; - delete props.options; - delete props.onChange; + delete props.options; + delete props.onChange; - return ( - - ); + return ( + + ); } } diff --git a/src/components/CustomReactSortable/CustomSortable.js b/src/components/CustomReactSortable/CustomSortable.js index e77d57b..c89a117 100644 --- a/src/components/CustomReactSortable/CustomSortable.js +++ b/src/components/CustomReactSortable/CustomSortable.js @@ -1,1492 +1,1541 @@ /* eslint-disable */ /**! * Sortable - * @author RubaXa + * @author RubaXa * @license MIT */ (function sortableModule(factory) { - "use strict"; - - if (typeof define === "function" && define.amd) { - define(factory); - } - else if (typeof module != "undefined" && typeof module.exports != "undefined") { - module.exports = factory(); - } - else { - /* jshint sub:true */ - window["Sortable"] = factory(); - } + "use strict"; + + if (typeof define === "function" && define.amd) { + define(factory); + } + else if (typeof module != "undefined" && typeof module.exports != "undefined") { + module.exports = factory(); + } + else { + /* jshint sub:true */ + window["Sortable"] = factory(); + } })(function sortableFactory() { - "use strict"; + "use strict"; - if (typeof window == "undefined" || !window.document) { - return function sortableError() { - throw new Error("Sortable.js requires a window with a document"); - }; - } - - var dragEl, - parentEl, - ghostEl, - cloneEl, - rootEl, - nextEl, - lastDownEl, - - scrollEl, - scrollParentEl, - scrollCustomFn, - - lastEl, - lastCSS, - lastParentCSS, - - oldIndex, - newIndex, - - activeGroup, - putSortable, + if (typeof window === "undefined" || !window.document) { + return function sortableError() { + throw new Error("Sortable.js requires a window with a document"); + }; + } + + var dragEl, + parentEl, + ghostEl, + cloneEl, + rootEl, + nextEl, + lastDownEl, + + scrollEl, + scrollParentEl, + scrollCustomFn, + + lastEl, + lastCSS, + lastParentCSS, + + oldIndex, + newIndex, + + activeGroup, + putSortable, + + autoScroll = {}, + + tapEvt, + touchEvt, + + moved, + + /** @const */ + R_SPACE = /\s+/g, + R_FLOAT = /left|right|inline/, + + expando = 'Sortable' + (new Date).getTime(), + + win = window, + document = win.document, + parseInt = win.parseInt, + setTimeout = win.setTimeout, + + $ = win.jQuery || win.Zepto, + Polymer = win.Polymer, + + captureMode = false, + passiveMode = false, + + supportDraggable = ('draggable' in document.createElement('div')), + supportCssPointerEvents = (function (el) { + // false when IE11 + if (!!navigator.userAgent.match(/(?:Trident.*rv[ :]?11\.|msie)/i)) { + return false; + } + el = document.createElement('x'); + el.style.cssText = 'pointer-events:auto'; + return el.style.pointerEvents === 'auto'; + })(), + + _silent = false, + + abs = Math.abs, + min = Math.min, + + savedInputChecked = [], + touchDragOverListeners = [], + + _autoScroll = _throttle(function (/**Event*/evt, /**Object*/options, /**HTMLElement*/rootEl) { + // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 + if (rootEl && options.scroll) { + var _this = rootEl[expando], + el, + rect, + sens = options.scrollSensitivity, + speed = options.scrollSpeed, + + x = evt.clientX, + y = evt.clientY, + + winWidth = window.innerWidth, + winHeight = window.innerHeight, + + vx, + vy, + + scrollOffsetX, + scrollOffsetY + ; + + // Delect scrollEl + if (scrollParentEl !== rootEl) { + scrollEl = options.scroll; + scrollParentEl = rootEl; + scrollCustomFn = options.scrollFn; + + if (scrollEl === true) { + scrollEl = rootEl; + + do { + if ((scrollEl.offsetWidth < scrollEl.scrollWidth) || + (scrollEl.offsetHeight < scrollEl.scrollHeight) + ) { + break; + } + /* jshint boss:true */ + } while (scrollEl = scrollEl.parentNode); + } + } + + if (scrollEl) { + el = scrollEl; + rect = scrollEl.getBoundingClientRect(); + vx = (abs(rect.right - x) <= sens) - (abs(rect.left - x) <= sens); + vy = (abs(rect.bottom - y) <= sens) - (abs(rect.top - y) <= sens); + } + + + if (!(vx || vy)) { + vx = (winWidth - x <= sens) - (x <= sens); + vy = (winHeight - y <= sens) - (y <= sens); + + /* jshint expr:true */ + (vx || vy) && (el = win); + } + + + if (autoScroll.vx !== vx || autoScroll.vy !== vy || autoScroll.el !== el) { + autoScroll.el = el; + autoScroll.vx = vx; + autoScroll.vy = vy; + + clearInterval(autoScroll.pid); + + if (el) { + autoScroll.pid = setInterval(function () { + scrollOffsetY = vy ? vy * speed : 0; + scrollOffsetX = vx ? vx * speed : 0; + + if ('function' === typeof(scrollCustomFn)) { + return scrollCustomFn.call(_this, scrollOffsetX, scrollOffsetY, evt); + } + + if (el === win) { + win.scrollTo(win.pageXOffset + scrollOffsetX, win.pageYOffset + scrollOffsetY); + } else { + el.scrollTop += scrollOffsetY; + el.scrollLeft += scrollOffsetX; + } + }, 24); + } + } + } + }, 30), + + _prepareGroup = function (options) { + function toFn(value, pull) { + if (value === void 0 || value === true) { + value = group.name; + } + + if (typeof value === 'function') { + return value; + } else { + return function (to, from) { + var fromGroup = from.options.group.name; + + return pull + ? value + : value && (value.join + ? value.indexOf(fromGroup) > -1 + : (fromGroup == value) + ); + }; + } + } + + var group = {}; + var originalGroup = options.group; + + if (!originalGroup || typeof originalGroup != 'object') { + originalGroup = {name: originalGroup}; + } + + group.name = originalGroup.name; + group.checkPull = toFn(originalGroup.pull, true); + group.checkPut = toFn(originalGroup.put); + group.revertClone = originalGroup.revertClone; + + options.group = group; + } + ; + + // Detect support a passive mode + try { + window.addEventListener('test', null, Object.defineProperty({}, 'passive', { + get: function () { + // `false`, because everything starts to work incorrectly and instead of d'n'd, + // begins the page has scrolled. + passiveMode = false; + captureMode = { + capture: false, + passive: passiveMode + }; + } + })); + } catch (err) {} + + /** + * @class Sortable + * @param {HTMLElement} el + * @param {Object} [options] + */ + function Sortable(el, options) { + if (!(el && el.nodeType && el.nodeType === 1)) { + throw 'Sortable: `el` must be HTMLElement, and not ' + {}.toString.call(el); + } + + this.el = el; // root element + this.options = options = _extend({}, options); + + + // Export instance + el[expando] = this; + + // Default options + var defaults = { + group: Math.random(), + sort: true, + disabled: false, + store: null, + handle: null, + scroll: true, + scrollSensitivity: 30, + scrollSpeed: 10, + draggable: /[uo]l/i.test(el.nodeName) ? 'li' : '>*', + ghostClass: 'sortable-ghost', + chosenClass: 'sortable-chosen', + dragClass: 'sortable-drag', + ignore: 'a, img', + filter: null, + preventOnFilter: true, + animation: 0, + setData: function (dataTransfer, dragEl) { + dataTransfer.setData('Text', dragEl.textContent); + }, + dropBubble: false, + dragoverBubble: false, + dataIdAttr: 'data-id', + delay: 0, + forceFallback: false, + fallbackClass: 'sortable-fallback', + fallbackOnBody: false, + fallbackTolerance: 0, + fallbackOffset: {x: 0, y: 0}, + supportPointer: Sortable.supportPointer !== false + }; + + + // Set default options + for (var name in defaults) { + !(name in options) && (options[name] = defaults[name]); + } + + _prepareGroup(options); + + // Bind all private methods + for (var fn in this) { + if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { + this[fn] = this[fn].bind(this); + } + } + + // Setup drag mode + this.nativeDraggable = options.forceFallback ? false : supportDraggable; + + // Bind events + _on(el, 'mousedown', this._onTapStart); + _on(el, 'touchstart', this._onTapStart); + options.supportPointer && _on(el, 'pointerdown', this._onTapStart); + + if (this.nativeDraggable) { + _on(el, 'dragover', this); + _on(el, 'dragenter', this); + } + + touchDragOverListeners.push(this._onDragOver); + + // Restore sorting + options.store && this.sort(options.store.get(this)); + } + + + Sortable.prototype = /** @lends Sortable.prototype */ { + constructor: Sortable, + + _onTapStart: function (/** Event|TouchEvent */evt) { + var _this = this, + el = this.el, + options = this.options, + preventOnFilter = options.preventOnFilter, + type = evt.type, + touch = evt.touches && evt.touches[0], + target = (touch || evt).target, + originalTarget = evt.target.shadowRoot && (evt.path && evt.path[0]) || target, + filter = options.filter, + startIndex; + + _saveInputCheckedState(el); + + + // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. + if (dragEl) { + return; + } + + if (/mousedown|pointerdown/.test(type) && evt.button !== 0 || options.disabled) { + return; // only left button or enabled + } + + // cancel dnd if original target is content editable + if (originalTarget.isContentEditable) { + return; + } + + target = _closest(target, options.draggable, el); + + if (!target) { + return; + } + + if (lastDownEl === target) { + // Ignoring duplicate `down` + return; + } + + // Get the index of the dragged element within its parent + startIndex = _index(target, options.draggable); + + // Check filter + if (typeof filter === 'function') { + if (filter.call(this, evt, target, this)) { + _dispatchEvent(_this, originalTarget, 'filter', target, el, el, startIndex); + preventOnFilter && evt.preventDefault(); + return; // cancel dnd + } + } + else if (filter) { + filter = filter.split(',').some(function (criteria) { + criteria = _closest(originalTarget, criteria.trim(), el); + + if (criteria) { + _dispatchEvent(_this, criteria, 'filter', target, el, el, startIndex); + return true; + } + }); + + if (filter) { + preventOnFilter && evt.preventDefault(); + return; // cancel dnd + } + } + + if (options.handle && !_closest(originalTarget, options.handle, el)) { + return; + } + + // Prepare `dragstart` + this._prepareDragStart(evt, touch, target, startIndex); + }, + + _prepareDragStart: function (/** Event */evt, /** Touch */touch, /** HTMLElement */target, /** Number */startIndex) { + var _this = this, + el = _this.el, + options = _this.options, + ownerDocument = el.ownerDocument, + dragStartFn; + + if (target && !dragEl && (target.parentNode === el)) { + tapEvt = evt; + + rootEl = el; + dragEl = target; + parentEl = dragEl.parentNode; + nextEl = dragEl.nextSibling; + lastDownEl = target; + activeGroup = options.group; + oldIndex = startIndex; + + this._lastX = (touch || evt).clientX; + this._lastY = (touch || evt).clientY; + + // dragEl.style['will-change'] = 'all'; + + dragStartFn = function () { + // Delayed drag has been triggered + // we can re-enable the events: touchmove/mousemove + _this._disableDelayedDrag(); + + // Make the element draggable + dragEl.draggable = _this.nativeDraggable; + + // Chosen item + _toggleClass(dragEl, options.chosenClass, true); + + // Bind the events: dragstart/dragend + _this._triggerDragStart(evt, touch); + + // Drag start event + _dispatchEvent(_this, rootEl, 'choose', dragEl, rootEl, rootEl, oldIndex); + }; + + // Disable "draggable" + options.ignore.split(',').forEach(function (criteria) { + _find(dragEl, criteria.trim(), _disableDraggable); + }); + + _on(ownerDocument, 'mouseup', _this._onDrop); + _on(ownerDocument, 'touchend', _this._onDrop); + _on(ownerDocument, 'touchcancel', _this._onDrop); + _on(ownerDocument, 'selectstart', _this); + options.supportPointer && _on(ownerDocument, 'pointercancel', _this._onDrop); + + if (options.delay) { + // If the user moves the pointer or let go the click or touch + // before the delay has been reached: + // disable the delayed drag + _on(ownerDocument, 'mouseup', _this._disableDelayedDrag); + _on(ownerDocument, 'touchend', _this._disableDelayedDrag); + _on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); + _on(ownerDocument, 'mousemove', _this._disableDelayedDrag); + _on(ownerDocument, 'touchmove', _this._disableDelayedDrag); + options.supportPointer && _on(ownerDocument, 'pointermove', _this._disableDelayedDrag); + + _this._dragStartTimer = setTimeout(dragStartFn, options.delay); + } else { + dragStartFn(); + } + + + } + }, + + _disableDelayedDrag: function () { + var ownerDocument = this.el.ownerDocument; + + clearTimeout(this._dragStartTimer); + _off(ownerDocument, 'mouseup', this._disableDelayedDrag); + _off(ownerDocument, 'touchend', this._disableDelayedDrag); + _off(ownerDocument, 'touchcancel', this._disableDelayedDrag); + _off(ownerDocument, 'mousemove', this._disableDelayedDrag); + _off(ownerDocument, 'touchmove', this._disableDelayedDrag); + _off(ownerDocument, 'pointermove', this._disableDelayedDrag); + }, + + _triggerDragStart: function (/** Event */evt, /** Touch */touch) { + touch = touch || (evt.pointerType == 'touch' ? evt : null); + + if (touch) { + // Touch device support + tapEvt = { + target: dragEl, + clientX: touch.clientX, + clientY: touch.clientY + }; + + this._onDragStart(tapEvt, 'touch'); + } + else if (!this.nativeDraggable) { + this._onDragStart(tapEvt, true); + } + else { + _on(dragEl, 'dragend', this); + _on(rootEl, 'dragstart', this._onDragStart); + } + + try { + if (document.selection) { + // Timeout neccessary for IE9 + _nextTick(function () { + document.selection.empty(); + }); + } else { + window.getSelection().removeAllRanges(); + } + } catch (err) { + } + }, + + _dragStarted: function () { + if (rootEl && dragEl) { + var options = this.options; + + // Apply effect + _toggleClass(dragEl, options.ghostClass, true); + _toggleClass(dragEl, options.dragClass, false); + + Sortable.active = this; + + // Drag start event + _dispatchEvent(this, rootEl, 'start', dragEl, rootEl, rootEl, oldIndex); + } else { + this._nulling(); + } + }, + + _emulateDragOver: function () { + if (touchEvt) { + if (this._lastX === touchEvt.clientX && this._lastY === touchEvt.clientY) { + return; + } + + this._lastX = touchEvt.clientX; + this._lastY = touchEvt.clientY; + + if (!supportCssPointerEvents) { + _css(ghostEl, 'display', 'none'); + } + + var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + var parent = target; + var i = touchDragOverListeners.length; + + if (target && target.shadowRoot) { + target = target.shadowRoot.elementFromPoint(touchEvt.clientX, touchEvt.clientY); + parent = target; + } + + if (parent) { + do { + if (parent[expando]) { + while (i--) { + touchDragOverListeners[i]({ + clientX: touchEvt.clientX, + clientY: touchEvt.clientY, + target: target, + rootEl: parent + }); + } + + break; + } + + target = parent; // store last element + } + /* jshint boss:true */ + while (parent = parent.parentNode); + } + + if (!supportCssPointerEvents) { + _css(ghostEl, 'display', ''); + } + } + }, + + + _onTouchMove: function (/**TouchEvent*/evt) { + if (tapEvt) { + var options = this.options, + fallbackTolerance = options.fallbackTolerance, + fallbackOffset = options.fallbackOffset, + touch = evt.touches ? evt.touches[0] : evt, + dx = (touch.clientX - tapEvt.clientX) + fallbackOffset.x, + dy = (touch.clientY - tapEvt.clientY) + fallbackOffset.y, + translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)'; + + // only set the status to dragging, when we are actually dragging + if (!Sortable.active) { + if (fallbackTolerance && + min(abs(touch.clientX - this._lastX), abs(touch.clientY - this._lastY)) < fallbackTolerance + ) { + return; + } + + this._dragStarted(); + } + + // as well as creating the ghost element on the document body + this._appendGhost(); + + moved = true; + touchEvt = touch; + + _css(ghostEl, 'webkitTransform', translate3d); + _css(ghostEl, 'mozTransform', translate3d); + _css(ghostEl, 'msTransform', translate3d); + _css(ghostEl, 'transform', translate3d); + + evt.preventDefault(); + } + }, + + _appendGhost: function () { + if (!ghostEl) { + var rect = dragEl.getBoundingClientRect(), + css = _css(dragEl), + options = this.options, + ghostRect; + + ghostEl = dragEl.cloneNode(true); + + _toggleClass(ghostEl, options.ghostClass, false); + _toggleClass(ghostEl, options.fallbackClass, true); + _toggleClass(ghostEl, options.dragClass, true); + + _css(ghostEl, 'top', rect.top - parseInt(css.marginTop, 10)); + _css(ghostEl, 'left', rect.left - parseInt(css.marginLeft, 10)); + _css(ghostEl, 'width', rect.width); + _css(ghostEl, 'height', rect.height); + _css(ghostEl, 'opacity', '0.8'); + _css(ghostEl, 'position', 'fixed'); + _css(ghostEl, 'zIndex', '100000'); + _css(ghostEl, 'pointerEvents', 'none'); + + options.fallbackOnBody && document.body.appendChild(ghostEl) || rootEl.appendChild(ghostEl); + + // Fixing dimensions. + ghostRect = ghostEl.getBoundingClientRect(); + _css(ghostEl, 'width', rect.width * 2 - ghostRect.width); + _css(ghostEl, 'height', rect.height * 2 - ghostRect.height); + } + }, + + _onDragStart: function (/**Event*/evt, /**boolean*/useFallback) { + var _this = this; + var dataTransfer = evt.dataTransfer; + var options = _this.options; + + _this._offUpEvents(); + + if (activeGroup.checkPull(_this, _this, dragEl, evt)) { + cloneEl = _clone(dragEl); + + cloneEl.draggable = false; + // cloneEl.style['will-change'] = ''; + + _css(cloneEl, 'display', 'none'); + _toggleClass(cloneEl, _this.options.chosenClass, false); + + // #1143: IFrame support workaround + _this._cloneId = _nextTick(function () { + rootEl.insertBefore(cloneEl, dragEl); + _dispatchEvent(_this, rootEl, 'clone', dragEl); + }); + } + + _toggleClass(dragEl, options.dragClass, true); + + if (useFallback) { + if (useFallback === 'touch') { + // Bind touch events + _on(document, 'touchmove', _this._onTouchMove); + _on(document, 'touchend', _this._onDrop); + _on(document, 'touchcancel', _this._onDrop); + + if (options.supportPointer) { + _on(document, 'pointermove', _this._onTouchMove); + _on(document, 'pointerup', _this._onDrop); + } + } else { + // Old brwoser + _on(document, 'mousemove', _this._onTouchMove); + _on(document, 'mouseup', _this._onDrop); + } + + _this._loopId = setInterval(_this._emulateDragOver, 50); + } + else { + if (dataTransfer) { + dataTransfer.effectAllowed = 'move'; + options.setData && options.setData.call(_this, dataTransfer, dragEl); + } + + _on(document, 'drop', _this); + + // #1143: Бывает элемент с IFrame внутри блокирует `drop`, + // поэтому если вызвался `mouseover`, значит надо отменять весь d'n'd. + // Breaking Chrome 62+ + // _on(document, 'mouseover', _this); + + _this._dragStartId = _nextTick(_this._dragStarted); + } + }, + + _onDragOver: function (/**Event*/evt) { + var el = this.el, + target, + dragRect, + targetRect, + revert, + options = this.options, + group = options.group, + activeSortable = Sortable.active, + isOwner = (activeGroup === group), + isMovingBetweenSortable = false, + canSort = options.sort; + + if (evt.preventDefault !== void 0) { + evt.preventDefault(); + !options.dragoverBubble && evt.stopPropagation(); + } + + if (dragEl.animated) { + return; + } + + moved = true; + + if (activeSortable && !options.disabled && + (isOwner + ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list + : ( + putSortable === this || + ( + (activeSortable.lastPullMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && + group.checkPut(this, activeSortable, dragEl, evt) + ) + ) + ) && + (evt.rootEl === void 0 || evt.rootEl === this.el) // touch fallback + ) { + // Smart auto-scrolling + _autoScroll(evt, options, this.el); + + if (_silent) { + return; + } + + target = _closest(evt.target, options.draggable, el); + dragRect = dragEl.getBoundingClientRect(); + + if (putSortable !== this) { + putSortable = this; + isMovingBetweenSortable = true; + } + + if (revert) { + _cloneHide(activeSortable, true); + parentEl = rootEl; // actualization + + if (cloneEl || nextEl) { + rootEl.insertBefore(dragEl, cloneEl || nextEl); + } + else if (!canSort) { + rootEl.appendChild(dragEl); + } + + return; + } + + + if ((el.children.length === 0) || (el.children[0] === ghostEl) || + (el === evt.target) && (_ghostIsLast(el, evt)) + ) { + //assign target only if condition is true + if (el.children.length !== 0 && el.children[0] !== ghostEl && el === evt.target) { + target = el.lastElementChild; + } + + if (target) { + if (target.animated) { + return; + } + + targetRect = target.getBoundingClientRect(); + } + + _cloneHide(activeSortable, isOwner); + + if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt) !== false) { + if (!dragEl.contains(el)) { + el.appendChild(dragEl); + parentEl = el; // actualization + } + + this._animate(dragRect, dragEl); + target && this._animate(targetRect, target); + } + } + else if (target && !target.animated && target !== dragEl && (target.parentNode[expando] !== void 0)) { + if (lastEl !== target) { + lastEl = target; + lastCSS = _css(target); + lastParentCSS = _css(target.parentNode); + } + + targetRect = target.getBoundingClientRect(); + + var width = targetRect.right - targetRect.left, + height = targetRect.bottom - targetRect.top, + floating = R_FLOAT.test(lastCSS.cssFloat + lastCSS.display) + || (lastParentCSS.display == 'flex' && lastParentCSS['flex-direction'].indexOf('row') === 0), + isWide = (target.offsetWidth > dragEl.offsetWidth), + isLong = (target.offsetHeight > dragEl.offsetHeight), + halfway = (floating ? (evt.clientX - targetRect.left) / width : (evt.clientY - targetRect.top) / height) > 0.5, + nextSibling = target.nextElementSibling, + after = false + ; + + if (floating) { + var elTop = dragEl.offsetTop, + tgTop = target.offsetTop; + + if (elTop === tgTop) { + after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide; + } + else if (target.previousElementSibling === dragEl || dragEl.previousElementSibling === target) { + after = (evt.clientY - targetRect.top) / height > 0.5; + } else { + after = tgTop > elTop; + } + } else if (!isMovingBetweenSortable) { + after = (nextSibling !== dragEl) && !isLong || halfway && isLong; + } + + var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); + + if (moveVector !== false) { + if (moveVector === 1 || moveVector === -1) { + after = (moveVector === 1); + } + + _silent = true; + setTimeout(_unsilent, 30); + + _cloneHide(activeSortable, isOwner); + + if (!dragEl.contains(el)) { + if (after && !nextSibling) { + el.appendChild(dragEl); + } else { + target.parentNode.insertBefore(dragEl, after ? nextSibling : target); + } + } + + parentEl = dragEl.parentNode; // actualization + + this._animate(dragRect, dragEl); + this._animate(targetRect, target); + } + } + } + }, + + _animate: function (prevRect, target) { + var ms = this.options.animation; + + if (ms) { + var currentRect = target.getBoundingClientRect(); + + if (prevRect.nodeType === 1) { + prevRect = prevRect.getBoundingClientRect(); + } + + _css(target, 'transition', 'none'); + _css(target, 'transform', 'translate3d(' + + (prevRect.left - currentRect.left) + 'px,' + + (prevRect.top - currentRect.top) + 'px,0)' + ); + + target.offsetWidth; // repaint + + _css(target, 'transition', 'all ' + ms + 'ms'); + _css(target, 'transform', 'translate3d(0,0,0)'); + + clearTimeout(target.animated); + target.animated = setTimeout(function () { + _css(target, 'transition', ''); + _css(target, 'transform', ''); + target.animated = false; + }, ms); + } + }, + + _offUpEvents: function () { + var ownerDocument = this.el.ownerDocument; + + _off(document, 'touchmove', this._onTouchMove); + _off(document, 'pointermove', this._onTouchMove); + _off(ownerDocument, 'mouseup', this._onDrop); + _off(ownerDocument, 'touchend', this._onDrop); + _off(ownerDocument, 'pointerup', this._onDrop); + _off(ownerDocument, 'touchcancel', this._onDrop); + _off(ownerDocument, 'pointercancel', this._onDrop); + _off(ownerDocument, 'selectstart', this); + }, + + _onDrop: function (/**Event*/evt) { + var el = this.el, + options = this.options; + + clearInterval(this._loopId); + clearInterval(autoScroll.pid); + clearTimeout(this._dragStartTimer); + + _cancelNextTick(this._cloneId); + _cancelNextTick(this._dragStartId); + + // Unbind events + _off(document, 'mouseover', this); + _off(document, 'mousemove', this._onTouchMove); + + if (this.nativeDraggable) { + _off(document, 'drop', this); + _off(el, 'dragstart', this._onDragStart); + } + + this._offUpEvents(); + + if (evt) { + if (moved) { + evt.preventDefault(); + !options.dropBubble && evt.stopPropagation(); + } + + ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); + + if (rootEl === parentEl || Sortable.active.lastPullMode !== 'clone') { + // Remove clone + cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); + } + + if (dragEl) { + if (this.nativeDraggable) { + _off(dragEl, 'dragend', this); + } + + _disableDraggable(dragEl); + // dragEl.style['will-change'] = ''; + + // Remove class's + _toggleClass(dragEl, this.options.ghostClass, false); + _toggleClass(dragEl, this.options.chosenClass, false); + + // Drag stop event + _dispatchEvent(this, rootEl, 'unchoose', dragEl, parentEl, rootEl, oldIndex); + + if (rootEl !== parentEl) { + newIndex = _index(dragEl, options.draggable); + + if (newIndex >= 0) { + // Add event + _dispatchEvent(null, parentEl, 'add', dragEl, parentEl, rootEl, oldIndex, newIndex); + + // Remove event + _dispatchEvent(this, rootEl, 'remove', dragEl, parentEl, rootEl, oldIndex, newIndex); + + // drag from one list and drop into another + _dispatchEvent(null, parentEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex); + _dispatchEvent(this, rootEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex); + } + } + else { + if (dragEl.nextSibling !== nextEl) { + // Get the index of the dragged element within its parent + newIndex = _index(dragEl, options.draggable); + + if (newIndex >= 0) { + // drag & drop within the same list + _dispatchEvent(this, rootEl, 'update', dragEl, parentEl, rootEl, oldIndex, newIndex); + _dispatchEvent(this, rootEl, 'sort', dragEl, parentEl, rootEl, oldIndex, newIndex); + } + } + } + + if (Sortable.active) { + /* jshint eqnull:true */ + if (newIndex == null || newIndex === -1) { + newIndex = oldIndex; + } + + _dispatchEvent(this, rootEl, 'end', dragEl, parentEl, rootEl, oldIndex, newIndex); + + // Save sorting + this.save(); + } + } + + } + + this._nulling(); + }, + + _nulling: function() { + rootEl = + dragEl = + parentEl = + ghostEl = + nextEl = + cloneEl = + lastDownEl = + + scrollEl = + scrollParentEl = + + tapEvt = + touchEvt = + + moved = + newIndex = + + lastEl = + lastCSS = + + putSortable = + activeGroup = + Sortable.active = null; + + savedInputChecked.forEach(function (el) { + el.checked = true; + }); + savedInputChecked.length = 0; + }, + + handleEvent: function (/**Event*/evt) { + switch (evt.type) { + case 'drop': + case 'dragend': + this._onDrop(evt); + break; + + case 'dragover': + case 'dragenter': + if (dragEl) { + this._onDragOver(evt); + _globalDragOver(evt); + } + break; + + case 'mouseover': + this._onDrop(evt); + break; + + case 'selectstart': + evt.preventDefault(); + break; + } + }, + + + /** + * Serializes the item into an array of string. + * @returns {String[]} + */ + toArray: function () { + var order = [], + el, + children = this.el.children, + i = 0, + n = children.length, + options = this.options; + + for (; i < n; i++) { + el = children[i]; + if (_closest(el, options.draggable, this.el)) { + order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); + } + } + + return order; + }, + + + /** + * Sorts the elements according to the array. + * @param {String[]} order order of the items + */ + sort: function (order) { + var items = {}, rootEl = this.el; + + this.toArray().forEach(function (id, i) { + var el = rootEl.children[i]; + + if (_closest(el, this.options.draggable, rootEl)) { + items[id] = el; + } + }, this); + + order.forEach(function (id) { + if (items[id]) { + rootEl.removeChild(items[id]); + rootEl.appendChild(items[id]); + } + }); + }, + + + /** + * Save the current sorting + */ + save: function () { + var store = this.options.store; + store && store.set(this); + }, + + + /** + * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. + * @param {HTMLElement} el + * @param {String} [selector] default: `options.draggable` + * @returns {HTMLElement|null} + */ + closest: function (el, selector) { + return _closest(el, selector || this.options.draggable, this.el); + }, + + + /** + * Set/get option + * @param {string} name + * @param {*} [value] + * @returns {*} + */ + option: function (name, value) { + var options = this.options; + + if (value === void 0) { + return options[name]; + } else { + options[name] = value; + + if (name === 'group') { + _prepareGroup(options); + } + } + }, + + + /** + * Destroy + */ + destroy: function () { + var el = this.el; + + el[expando] = null; + + _off(el, 'mousedown', this._onTapStart); + _off(el, 'touchstart', this._onTapStart); + _off(el, 'pointerdown', this._onTapStart); + + if (this.nativeDraggable) { + _off(el, 'dragover', this); + _off(el, 'dragenter', this); + } + + // Remove draggable attributes + Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { + el.removeAttribute('draggable'); + }); + + touchDragOverListeners.splice(touchDragOverListeners.indexOf(this._onDragOver), 1); + + this._onDrop(); + + this.el = el = null; + } + }; + + + function _cloneHide(sortable, state) { + if (sortable.lastPullMode !== 'clone') { + state = true; + } + + if (cloneEl && (cloneEl.state !== state)) { + _css(cloneEl, 'display', state ? 'none' : ''); + + if (!state) { + if (cloneEl.state) { + if (sortable.options.group.revertClone) { + rootEl.insertBefore(cloneEl, nextEl); + sortable._animate(dragEl, cloneEl); + } else { + rootEl.insertBefore(cloneEl, dragEl); + } + } + } + + cloneEl.state = state; + } + } - autoScroll = {}, - - tapEvt, - touchEvt, - moved, + function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx) { + if (el) { + ctx = ctx || document; - /** @const */ - R_SPACE = /\s+/g, - R_FLOAT = /left|right|inline/, - - expando = 'Sortable' + (new Date).getTime(), + do { + if ((selector === '>*' && el.parentNode === ctx) || _matches(el, selector)) { + return el; + } + /* jshint boss:true */ + } while (el = _getParentOrHost(el)); + } - win = window, - document = win.document, - parseInt = win.parseInt, + return null; + } - $ = win.jQuery || win.Zepto, - Polymer = win.Polymer, - - captureMode = false, - - supportDraggable = !!('draggable' in document.createElement('div')), - supportCssPointerEvents = (function (el) { - // false when IE11 - if (!!navigator.userAgent.match(/Trident.*rv[ :]?11\./)) { - return false; - } - el = document.createElement('x'); - el.style.cssText = 'pointer-events:auto'; - return el.style.pointerEvents === 'auto'; - })(), - - _silent = false, - - abs = Math.abs, - min = Math.min, - - savedInputChecked = [], - touchDragOverListeners = [], - - _autoScroll = _throttle(function (/**Event*/evt, /**Object*/options, /**HTMLElement*/rootEl) { - // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 - if (rootEl && options.scroll) { - var _this = rootEl[expando], - el, - rect, - sens = options.scrollSensitivity, - speed = options.scrollSpeed, - - x = evt.clientX, - y = evt.clientY, - - winWidth = window.innerWidth, - winHeight = window.innerHeight, - - vx, - vy, - - scrollOffsetX, - scrollOffsetY - ; - - // Delect scrollEl - if (scrollParentEl !== rootEl) { - scrollEl = options.scroll; - scrollParentEl = rootEl; - scrollCustomFn = options.scrollFn; - - if (scrollEl === true) { - scrollEl = rootEl; - - do { - if ((scrollEl.offsetWidth < scrollEl.scrollWidth) || - (scrollEl.offsetHeight < scrollEl.scrollHeight) - ) { - break; - } - /* jshint boss:true */ - } while (scrollEl = scrollEl.parentNode); - } - } - - if (scrollEl) { - el = scrollEl; - rect = scrollEl.getBoundingClientRect(); - vx = (abs(rect.right - x) <= sens) - (abs(rect.left - x) <= sens); - vy = (abs(rect.bottom - y) <= sens) - (abs(rect.top - y) <= sens); - } - - - if (!(vx || vy)) { - vx = (winWidth - x <= sens) - (x <= sens); - vy = (winHeight - y <= sens) - (y <= sens); - - /* jshint expr:true */ - (vx || vy) && (el = win); - } - - - if (autoScroll.vx !== vx || autoScroll.vy !== vy || autoScroll.el !== el) { - autoScroll.el = el; - autoScroll.vx = vx; - autoScroll.vy = vy; - - clearInterval(autoScroll.pid); - - if (el) { - autoScroll.pid = setInterval(function () { - scrollOffsetY = vy ? vy * speed : 0; - scrollOffsetX = vx ? vx * speed : 0; - - if ('function' === typeof(scrollCustomFn)) { - return scrollCustomFn.call(_this, scrollOffsetX, scrollOffsetY, evt); - } - - if (el === win) { - win.scrollTo(win.pageXOffset + scrollOffsetX, win.pageYOffset + scrollOffsetY); - } else { - el.scrollTop += scrollOffsetY; - el.scrollLeft += scrollOffsetX; - } - }, 24); - } - } - } - }, 30), - - _prepareGroup = function (options) { - function toFn(value, pull) { - if (value === void 0 || value === true) { - value = group.name; - } - - if (typeof value === 'function') { - return value; - } else { - return function (to, from) { - var fromGroup = from.options.group.name; - - return pull - ? value - : value && (value.join - ? value.indexOf(fromGroup) > -1 - : (fromGroup == value) - ); - }; - } - } - - var group = {}; - var originalGroup = options.group; - - if (!originalGroup || typeof originalGroup != 'object') { - originalGroup = {name: originalGroup}; - } - - group.name = originalGroup.name; - group.checkPull = toFn(originalGroup.pull, true); - group.checkPut = toFn(originalGroup.put); - group.revertClone = originalGroup.revertClone; - - options.group = group; - } - ; - - - /** - * @class Sortable - * @param {HTMLElement} el - * @param {Object} [options] - */ - function Sortable(el, options) { - if (!(el && el.nodeType && el.nodeType === 1)) { - throw 'Sortable: `el` must be HTMLElement, and not ' + {}.toString.call(el); - } - - this.el = el; // root element - this.options = options = _extend({}, options); - - - // Export instance - el[expando] = this; - - // Default options - var defaults = { - group: Math.random(), - sort: true, - disabled: false, - store: null, - handle: null, - scroll: true, - scrollSensitivity: 30, - scrollSpeed: 10, - draggable: /[uo]l/i.test(el.nodeName) ? 'li' : '>*', - ghostClass: 'sortable-ghost', - chosenClass: 'sortable-chosen', - dragClass: 'sortable-drag', - ignore: 'a, img', - filter: null, - preventOnFilter: true, - animation: 0, - setData: function (dataTransfer, dragEl) { - dataTransfer.setData('Text', dragEl.textContent); - }, - dropBubble: false, - dragoverBubble: false, - dataIdAttr: 'data-id', - delay: 0, - forceFallback: false, - fallbackClass: 'sortable-fallback', - fallbackOnBody: false, - fallbackTolerance: 0, - fallbackOffset: {x: 0, y: 0} - }; - - - // Set default options - for (var name in defaults) { - !(name in options) && (options[name] = defaults[name]); - } - - _prepareGroup(options); - - // Bind all private methods - for (var fn in this) { - if (fn.charAt(0) === '_' && typeof this[fn] === 'function') { - this[fn] = this[fn].bind(this); - } - } - - // Setup drag mode - this.nativeDraggable = options.forceFallback ? false : supportDraggable; - - // Bind events - _on(el, 'mousedown', this._onTapStart); - _on(el, 'touchstart', this._onTapStart); - _on(el, 'pointerdown', this._onTapStart); - - if (this.nativeDraggable) { - _on(el, 'dragover', this); - _on(el, 'dragenter', this); - } - - touchDragOverListeners.push(this._onDragOver); - - // Restore sorting - options.store && this.sort(options.store.get(this)); - } - - - Sortable.prototype = /** @lends Sortable.prototype */ { - constructor: Sortable, - - _onTapStart: function (/** Event|TouchEvent */evt) { - var _this = this, - el = this.el, - options = this.options, - preventOnFilter = options.preventOnFilter, - type = evt.type, - touch = evt.touches && evt.touches[0], - target = (touch || evt).target, - originalTarget = evt.target.shadowRoot && evt.path[0] || target, - filter = options.filter, - startIndex; - - _saveInputCheckedState(el); - - - // Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group. - if (dragEl) { - return; - } - - if (type === 'mousedown' && evt.button !== 0 || options.disabled) { - return; // only left button or enabled - } - - - target = _closest(target, options.draggable, el); - - if (!target) { - return; - } - - if (lastDownEl === target) { - // Ignoring duplicate `down` - return; - } - - // Get the index of the dragged element within its parent - startIndex = _index(target, options.draggable); - - // Check filter - if (typeof filter === 'function') { - if (filter.call(this, evt, target, this)) { - _dispatchEvent(_this, originalTarget, 'filter', target, el, startIndex); - preventOnFilter && evt.preventDefault(); - return; // cancel dnd - } - } - else if (filter) { - filter = filter.split(',').some(function (criteria) { - criteria = _closest(originalTarget, criteria.trim(), el); - - if (criteria) { - _dispatchEvent(_this, criteria, 'filter', target, el, startIndex); - return true; - } - }); - - if (filter) { - preventOnFilter && evt.preventDefault(); - return; // cancel dnd - } - } - - if (options.handle && !_closest(originalTarget, options.handle, el)) { - return; - } - - // Prepare `dragstart` - this._prepareDragStart(evt, touch, target, startIndex); - }, - - _prepareDragStart: function (/** Event */evt, /** Touch */touch, /** HTMLElement */target, /** Number */startIndex) { - var _this = this, - el = _this.el, - options = _this.options, - ownerDocument = el.ownerDocument, - dragStartFn; - - if (target && !dragEl && (target.parentNode === el)) { - tapEvt = evt; - - rootEl = el; - dragEl = target; - parentEl = dragEl.parentNode; - nextEl = dragEl.nextSibling; - lastDownEl = target; - activeGroup = options.group; - oldIndex = startIndex; - - this._lastX = (touch || evt).clientX; - this._lastY = (touch || evt).clientY; - - // dragEl.style['will-change'] = 'transform'; - - dragStartFn = function () { - // Delayed drag has been triggered - // we can re-enable the events: touchmove/mousemove - _this._disableDelayedDrag(); - - // Make the element draggable - dragEl.draggable = _this.nativeDraggable; - - // Chosen item - _toggleClass(dragEl, options.chosenClass, true); - - // Bind the events: dragstart/dragend - _this._triggerDragStart(evt, touch); - - // Drag start event - _dispatchEvent(_this, rootEl, 'choose', dragEl, rootEl, oldIndex); - }; - - // Disable "draggable" - options.ignore.split(',').forEach(function (criteria) { - _find(dragEl, criteria.trim(), _disableDraggable); - }); - - _on(ownerDocument, 'mouseup', _this._onDrop); - _on(ownerDocument, 'touchend', _this._onDrop); - _on(ownerDocument, 'touchcancel', _this._onDrop); - _on(ownerDocument, 'pointercancel', _this._onDrop); - _on(ownerDocument, 'selectstart', _this); - - if (options.delay) { - // If the user moves the pointer or let go the click or touch - // before the delay has been reached: - // disable the delayed drag - _on(ownerDocument, 'mouseup', _this._disableDelayedDrag); - _on(ownerDocument, 'touchend', _this._disableDelayedDrag); - _on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); - _on(ownerDocument, 'mousemove', _this._disableDelayedDrag); - _on(ownerDocument, 'touchmove', _this._disableDelayedDrag); - _on(ownerDocument, 'pointermove', _this._disableDelayedDrag); - - _this._dragStartTimer = setTimeout(dragStartFn, options.delay); - } else { - dragStartFn(); - } - - - } - }, - - _disableDelayedDrag: function () { - var ownerDocument = this.el.ownerDocument; - - clearTimeout(this._dragStartTimer); - _off(ownerDocument, 'mouseup', this._disableDelayedDrag); - _off(ownerDocument, 'touchend', this._disableDelayedDrag); - _off(ownerDocument, 'touchcancel', this._disableDelayedDrag); - _off(ownerDocument, 'mousemove', this._disableDelayedDrag); - _off(ownerDocument, 'touchmove', this._disableDelayedDrag); - _off(ownerDocument, 'pointermove', this._disableDelayedDrag); - }, - - _triggerDragStart: function (/** Event */evt, /** Touch */touch) { - touch = touch || (evt.pointerType == 'touch' ? evt : null); - - if (touch) { - // Touch device support - tapEvt = { - target: dragEl, - clientX: touch.clientX, - clientY: touch.clientY - }; - - this._onDragStart(tapEvt, 'touch'); - } - else if (!this.nativeDraggable) { - this._onDragStart(tapEvt, true); - } - else { - _on(dragEl, 'dragend', this); - _on(rootEl, 'dragstart', this._onDragStart); - } - - try { - if (document.selection) { - // Timeout neccessary for IE9 - setTimeout(function () { - document.selection.empty(); - }); - } else { - window.getSelection().removeAllRanges(); - } - } catch (err) { - } - }, - - _dragStarted: function () { - if (rootEl && dragEl) { - var options = this.options; - - // Apply effect - _toggleClass(dragEl, options.ghostClass, true); - _toggleClass(dragEl, options.dragClass, false); - - Sortable.active = this; - - // Drag start event - _dispatchEvent(this, rootEl, 'start', dragEl, rootEl, oldIndex); - } else { - this._nulling(); - } - }, - - _emulateDragOver: function () { - if (touchEvt) { - if (this._lastX === touchEvt.clientX && this._lastY === touchEvt.clientY) { - return; - } - - this._lastX = touchEvt.clientX; - this._lastY = touchEvt.clientY; - - if (!supportCssPointerEvents) { - _css(ghostEl, 'display', 'none'); - } - - var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY), - parent = target, - i = touchDragOverListeners.length; - - if (parent) { - do { - if (parent[expando]) { - while (i--) { - touchDragOverListeners[i]({ - clientX: touchEvt.clientX, - clientY: touchEvt.clientY, - target: target, - rootEl: parent - }); - } - - break; - } - - target = parent; // store last element - } - /* jshint boss:true */ - while (parent = parent.parentNode); - } - - if (!supportCssPointerEvents) { - _css(ghostEl, 'display', ''); - } - } - }, - - - _onTouchMove: function (/**TouchEvent*/evt) { - if (tapEvt) { - var options = this.options, - fallbackTolerance = options.fallbackTolerance, - fallbackOffset = options.fallbackOffset, - touch = evt.touches ? evt.touches[0] : evt, - dx = (touch.clientX - tapEvt.clientX) + fallbackOffset.x, - dy = (touch.clientY - tapEvt.clientY) + fallbackOffset.y, - translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)'; - - // only set the status to dragging, when we are actually dragging - if (!Sortable.active) { - if (fallbackTolerance && - min(abs(touch.clientX - this._lastX), abs(touch.clientY - this._lastY)) < fallbackTolerance - ) { - return; - } - - this._dragStarted(); - } - - // as well as creating the ghost element on the document body - this._appendGhost(); - - moved = true; - touchEvt = touch; - - _css(ghostEl, 'webkitTransform', translate3d); - _css(ghostEl, 'mozTransform', translate3d); - _css(ghostEl, 'msTransform', translate3d); - _css(ghostEl, 'transform', translate3d); - - evt.preventDefault(); - } - }, - - _appendGhost: function () { - if (!ghostEl) { - var rect = dragEl.getBoundingClientRect(), - css = _css(dragEl), - options = this.options, - ghostRect; - - ghostEl = dragEl.cloneNode(true); - - _toggleClass(ghostEl, options.ghostClass, false); - _toggleClass(ghostEl, options.fallbackClass, true); - _toggleClass(ghostEl, options.dragClass, true); - - _css(ghostEl, 'top', rect.top - parseInt(css.marginTop, 10)); - _css(ghostEl, 'left', rect.left - parseInt(css.marginLeft, 10)); - _css(ghostEl, 'width', rect.width); - _css(ghostEl, 'height', rect.height); - _css(ghostEl, 'opacity', '0.8'); - _css(ghostEl, 'position', 'fixed'); - _css(ghostEl, 'zIndex', '100000'); - _css(ghostEl, 'pointerEvents', 'none'); - - options.fallbackOnBody && document.body.appendChild(ghostEl) || rootEl.appendChild(ghostEl); - - // Fixing dimensions. - ghostRect = ghostEl.getBoundingClientRect(); - _css(ghostEl, 'width', rect.width * 2 - ghostRect.width); - _css(ghostEl, 'height', rect.height * 2 - ghostRect.height); - } - }, - - _onDragStart: function (/**Event*/evt, /**boolean*/useFallback) { - var dataTransfer = evt.dataTransfer, - options = this.options; - - this._offUpEvents(); - - if (activeGroup.checkPull(this, this, dragEl, evt)) { - cloneEl = _clone(dragEl); - - cloneEl.draggable = false; - // cloneEl.style['will-change'] = ''; - - _css(cloneEl, 'display', 'none'); - _toggleClass(cloneEl, this.options.chosenClass, false); - - rootEl.insertBefore(cloneEl, dragEl); - _dispatchEvent(this, rootEl, 'clone', dragEl); - } - - _toggleClass(dragEl, options.dragClass, true); - - if (useFallback) { - if (useFallback === 'touch') { - // Bind touch events - _on(document, 'touchmove', this._onTouchMove); - _on(document, 'touchend', this._onDrop); - _on(document, 'touchcancel', this._onDrop); - _on(document, 'pointermove', this._onTouchMove); - _on(document, 'pointerup', this._onDrop); - } else { - // Old brwoser - _on(document, 'mousemove', this._onTouchMove); - _on(document, 'mouseup', this._onDrop); - } - - this._loopId = setInterval(this._emulateDragOver, 50); - } - else { - if (dataTransfer) { - dataTransfer.effectAllowed = 'move'; - options.setData && options.setData.call(this, dataTransfer, dragEl); - } - - _on(document, 'drop', this); - setTimeout(this._dragStarted, 0); - } - }, - - _onDragOver: function (/**Event*/evt) { - var el = this.el, - target, - dragRect, - targetRect, - revert, - options = this.options, - group = options.group, - activeSortable = Sortable.active, - isOwner = (activeGroup === group), - isMovingBetweenSortable = false, - canSort = options.sort; - - if (evt.preventDefault !== void 0) { - evt.preventDefault(); - !options.dragoverBubble && evt.stopPropagation(); - } - - if (dragEl.animated) { - return; - } - - moved = true; - - if (activeSortable && !options.disabled && - (isOwner - ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list - : ( - putSortable === this || - ( - (activeSortable.lastPullMode = activeGroup.checkPull(this, activeSortable, dragEl, evt)) && - group.checkPut(this, activeSortable, dragEl, evt) - ) - ) - ) && - (evt.rootEl === void 0 || evt.rootEl === this.el) // touch fallback - ) { - // Smart auto-scrolling - _autoScroll(evt, options, this.el); - - if (_silent) { - return; - } - - target = _closest(evt.target, options.draggable, el); - dragRect = dragEl.getBoundingClientRect(); - - if (putSortable !== this) { - putSortable = this; - isMovingBetweenSortable = true; - } - - if (revert) { - _cloneHide(activeSortable, true); - parentEl = rootEl; // actualization - - if (cloneEl || nextEl) { - rootEl.insertBefore(dragEl, cloneEl || nextEl); - } - else if (!canSort) { - rootEl.appendChild(dragEl); - } - - return; - } - - - if ((el.children.length === 0) || (el.children[0] === ghostEl) || - (el === evt.target) && (_ghostIsLast(el, evt)) - ) { - //assign target only if condition is true - if (el.children.length !== 0 && el.children[0] !== ghostEl && el === evt.target) { - target = el.lastElementChild; - } - - if (target) { - if (target.animated) { - return; - } - - targetRect = target.getBoundingClientRect(); - } - - _cloneHide(activeSortable, isOwner); - - if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt) !== false) { - if (!dragEl.contains(el)) { - el.appendChild(dragEl); - parentEl = el; // actualization - } - - this._animate(dragRect, dragEl); - target && this._animate(targetRect, target); - } - } - else if (target && !target.animated && target !== dragEl && (target.parentNode[expando] !== void 0)) { - if (lastEl !== target) { - lastEl = target; - lastCSS = _css(target); - lastParentCSS = _css(target.parentNode); - } - - targetRect = target.getBoundingClientRect(); - - var width = targetRect.right - targetRect.left, - height = targetRect.bottom - targetRect.top, - floating = R_FLOAT.test(lastCSS.cssFloat + lastCSS.display) - || (lastParentCSS.display == 'flex' && lastParentCSS['flex-direction'].indexOf('row') === 0), - isWide = (target.offsetWidth > dragEl.offsetWidth), - isLong = (target.offsetHeight > dragEl.offsetHeight), - halfway = (floating ? (evt.clientX - targetRect.left) / width : (evt.clientY - targetRect.top) / height) > 0.5, - nextSibling = target.nextElementSibling, - after = false - ; - - if (floating) { - var elTop = dragEl.offsetTop, - tgTop = target.offsetTop; - - if (elTop === tgTop) { - after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide; - } - else if (target.previousElementSibling === dragEl || dragEl.previousElementSibling === target) { - after = (evt.clientY - targetRect.top) / height > 0.5; - } else { - after = tgTop > elTop; - } - } else if (!isMovingBetweenSortable) { - after = (nextSibling !== dragEl) && !isLong || halfway && isLong; - } - - var moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt, after); - - if (moveVector !== false) { - if (moveVector === 1 || moveVector === -1) { - after = (moveVector === 1); - } - - _silent = true; - setTimeout(_unsilent, 30); - - _cloneHide(activeSortable, isOwner); - - if (!dragEl.contains(el)) { - if (after && !nextSibling) { - el.appendChild(dragEl); - } else { - target.parentNode.insertBefore(dragEl, after ? nextSibling : target); - } - } - - parentEl = dragEl.parentNode; // actualization - - this._animate(dragRect, dragEl); - this._animate(targetRect, target); - } - } - } - }, - - _animate: function (prevRect, target) { - var ms = this.options.animation; - - if (ms) { - var currentRect = target.getBoundingClientRect(); - - if (prevRect.nodeType === 1) { - prevRect = prevRect.getBoundingClientRect(); - } - - _css(target, 'transition', 'none'); - _css(target, 'transform', 'translate3d(' - + (prevRect.left - currentRect.left) + 'px,' - + (prevRect.top - currentRect.top) + 'px,0)' - ); - - target.offsetWidth; // repaint - - _css(target, 'transition', 'all ' + ms + 'ms'); - _css(target, 'transform', 'translate3d(0,0,0)'); - - clearTimeout(target.animated); - target.animated = setTimeout(function () { - _css(target, 'transition', ''); - _css(target, 'transform', ''); - target.animated = false; - }, ms); - } - }, - - _offUpEvents: function () { - var ownerDocument = this.el.ownerDocument; - - _off(document, 'touchmove', this._onTouchMove); - _off(document, 'pointermove', this._onTouchMove); - _off(ownerDocument, 'mouseup', this._onDrop); - _off(ownerDocument, 'touchend', this._onDrop); - _off(ownerDocument, 'pointerup', this._onDrop); - _off(ownerDocument, 'touchcancel', this._onDrop); - _off(ownerDocument, 'pointercancel', this._onDrop); - _off(ownerDocument, 'selectstart', this); - }, - - _onDrop: function (/**Event*/evt) { - var el = this.el, - options = this.options; - - clearInterval(this._loopId); - clearInterval(autoScroll.pid); - clearTimeout(this._dragStartTimer); - - // Unbind events - _off(document, 'mousemove', this._onTouchMove); - - if (this.nativeDraggable) { - _off(document, 'drop', this); - _off(el, 'dragstart', this._onDragStart); - } - - this._offUpEvents(); - - if (evt) { - if (moved) { - evt.preventDefault(); - !options.dropBubble && evt.stopPropagation(); - } - - ghostEl && ghostEl.parentNode && ghostEl.parentNode.removeChild(ghostEl); - - if (rootEl === parentEl || Sortable.active.lastPullMode !== 'clone') { - // Remove clone - cloneEl && cloneEl.parentNode && cloneEl.parentNode.removeChild(cloneEl); - } - - if (dragEl) { - if (this.nativeDraggable) { - _off(dragEl, 'dragend', this); - } - - _disableDraggable(dragEl); - // dragEl.style['will-change'] = ''; - - // Remove class's - _toggleClass(dragEl, this.options.ghostClass, false); - _toggleClass(dragEl, this.options.chosenClass, false); - - // Drag stop event - _dispatchEvent(this, rootEl, 'unchoose', dragEl, rootEl, oldIndex); - - if (rootEl !== parentEl) { - newIndex = _index(dragEl, options.draggable); - - if (newIndex >= 0) { - // Add event - _dispatchEvent(null, parentEl, 'add', dragEl, rootEl, oldIndex, newIndex); - - // Remove event - _dispatchEvent(this, rootEl, 'remove', dragEl, rootEl, oldIndex, newIndex); - - // drag from one list and drop into another - _dispatchEvent(null, parentEl, 'sort', dragEl, rootEl, oldIndex, newIndex); - _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex); - } - } - else { - if (dragEl.nextSibling !== nextEl) { - // Get the index of the dragged element within its parent - newIndex = _index(dragEl, options.draggable); - - if (newIndex >= 0) { - // drag & drop within the same list - _dispatchEvent(this, rootEl, 'update', dragEl, rootEl, oldIndex, newIndex); - _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex); - } - } - } - - if (Sortable.active) { - /* jshint eqnull:true */ - if (newIndex == null || newIndex === -1) { - newIndex = oldIndex; - } - - _dispatchEvent(this, rootEl, 'end', dragEl, rootEl, oldIndex, newIndex); - - // Save sorting - this.save(); - } - } - - } - - this._nulling(); - }, - - _nulling: function() { - rootEl = - dragEl = - parentEl = - ghostEl = - nextEl = - cloneEl = - lastDownEl = - - scrollEl = - scrollParentEl = - - tapEvt = - touchEvt = - - moved = - newIndex = - - lastEl = - lastCSS = - - putSortable = - activeGroup = - Sortable.active = null; - - savedInputChecked.forEach(function (el) { - el.checked = true; - }); - savedInputChecked.length = 0; - }, - - handleEvent: function (/**Event*/evt) { - switch (evt.type) { - case 'drop': - case 'dragend': - this._onDrop(evt); - break; - - case 'dragover': - case 'dragenter': - if (dragEl) { - this._onDragOver(evt); - _globalDragOver(evt); - } - break; - - case 'selectstart': - evt.preventDefault(); - break; - } - }, - - - /** - * Serializes the item into an array of string. - * @returns {String[]} - */ - toArray: function () { - var order = [], - el, - children = this.el.children, - i = 0, - n = children.length, - options = this.options; - - for (; i < n; i++) { - el = children[i]; - if (_closest(el, options.draggable, this.el)) { - order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); - } - } - - return order; - }, - - - /** - * Sorts the elements according to the array. - * @param {String[]} order order of the items - */ - sort: function (order) { - var items = {}, rootEl = this.el; - - this.toArray().forEach(function (id, i) { - var el = rootEl.children[i]; - - if (_closest(el, this.options.draggable, rootEl)) { - items[id] = el; - } - }, this); - - order.forEach(function (id) { - if (items[id]) { - rootEl.removeChild(items[id]); - rootEl.appendChild(items[id]); - } - }); - }, - - - /** - * Save the current sorting - */ - save: function () { - var store = this.options.store; - store && store.set(this); - }, - - - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * @param {HTMLElement} el - * @param {String} [selector] default: `options.draggable` - * @returns {HTMLElement|null} - */ - closest: function (el, selector) { - return _closest(el, selector || this.options.draggable, this.el); - }, - - - /** - * Set/get option - * @param {string} name - * @param {*} [value] - * @returns {*} - */ - option: function (name, value) { - var options = this.options; - - if (value === void 0) { - return options[name]; - } else { - options[name] = value; - - if (name === 'group') { - _prepareGroup(options); - } - } - }, - - - /** - * Destroy - */ - destroy: function () { - var el = this.el; - - el[expando] = null; - - _off(el, 'mousedown', this._onTapStart); - _off(el, 'touchstart', this._onTapStart); - _off(el, 'pointerdown', this._onTapStart); - - if (this.nativeDraggable) { - _off(el, 'dragover', this); - _off(el, 'dragenter', this); - } - - // Remove draggable attributes - Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { - el.removeAttribute('draggable'); - }); - - touchDragOverListeners.splice(touchDragOverListeners.indexOf(this._onDragOver), 1); - - this._onDrop(); - - this.el = el = null; - } - }; - - - function _cloneHide(sortable, state) { - if (sortable.lastPullMode !== 'clone') { - state = true; - } - - if (cloneEl && (cloneEl.state !== state)) { - _css(cloneEl, 'display', state ? 'none' : ''); - - if (!state) { - if (cloneEl.state) { - if (sortable.options.group.revertClone) { - rootEl.insertBefore(cloneEl, nextEl); - sortable._animate(dragEl, cloneEl); - } else { - rootEl.insertBefore(cloneEl, dragEl); - } - } - } - - cloneEl.state = state; - } - } + function _getParentOrHost(el) { + var parent = el.host; - function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx) { - if (el) { - ctx = ctx || document; + return (parent && parent.nodeType) ? parent : el.parentNode; + } - do { - if ((selector === '>*' && el.parentNode === ctx) || _matches(el, selector)) { - return el; - } - /* jshint boss:true */ - } while (el = _getParentOrHost(el)); - } - return null; - } + function _globalDragOver(/**Event*/evt) { + if (evt.dataTransfer) { + evt.dataTransfer.dropEffect = 'move'; + } + evt.preventDefault(); + } - function _getParentOrHost(el) { - var parent = el.host; + function _on(el, event, fn) { + el.addEventListener(event, fn, captureMode); + } - return (parent && parent.nodeType) ? parent : el.parentNode; - } + function _off(el, event, fn) { + el.removeEventListener(event, fn, captureMode); + } - function _globalDragOver(/**Event*/evt) { - if (evt.dataTransfer) { - evt.dataTransfer.dropEffect = 'move'; - } - evt.preventDefault(); - } + function _toggleClass(el, name, state) { + if (el) { + if (el.classList) { + el.classList[state ? 'add' : 'remove'](name); + } + else { + var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' '); + el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' '); + } + } + } - function _on(el, event, fn) { - el.addEventListener(event, fn, captureMode); - } + function _css(el, prop, val) { + var style = el && el.style; - function _off(el, event, fn) { - el.removeEventListener(event, fn, captureMode); - } + if (style) { + if (val === void 0) { + if (document.defaultView && document.defaultView.getComputedStyle) { + val = document.defaultView.getComputedStyle(el, ''); + } + else if (el.currentStyle) { + val = el.currentStyle; + } + return prop === void 0 ? val : val[prop]; + } + else { + if (!(prop in style)) { + prop = '-webkit-' + prop; + } - function _toggleClass(el, name, state) { - if (el) { - if (el.classList) { - el.classList[state ? 'add' : 'remove'](name); - } - else { - var className = (' ' + el.className + ' ').replace(R_SPACE, ' ').replace(' ' + name + ' ', ' '); - el.className = (className + (state ? ' ' + name : '')).replace(R_SPACE, ' '); - } - } - } + style[prop] = val + (typeof val === 'string' ? '' : 'px'); + } + } + } - function _css(el, prop, val) { - var style = el && el.style; + function _find(ctx, tagName, iterator) { + if (ctx) { + var list = ctx.getElementsByTagName(tagName), i = 0, n = list.length; - if (style) { - if (val === void 0) { - if (document.defaultView && document.defaultView.getComputedStyle) { - val = document.defaultView.getComputedStyle(el, ''); - } - else if (el.currentStyle) { - val = el.currentStyle; - } + if (iterator) { + for (; i < n; i++) { + iterator(list[i], i); + } + } - return prop === void 0 ? val : val[prop]; - } - else { - if (!(prop in style)) { - prop = '-webkit-' + prop; - } + return list; + } - style[prop] = val + (typeof val === 'string' ? '' : 'px'); - } - } - } + return []; + } - function _find(ctx, tagName, iterator) { - if (ctx) { - var list = ctx.getElementsByTagName(tagName), i = 0, n = list.length; - if (iterator) { - for (; i < n; i++) { - iterator(list[i], i); - } - } + function _dispatchEvent(sortable, rootEl, name, targetEl, toEl, fromEl, startIndex, newIndex) { + sortable = (sortable || rootEl[expando]); - return list; - } + var evt = document.createEvent('Event'), + options = sortable.options, + onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); - return []; - } + evt.initEvent(name, true, true); + evt.to = toEl || rootEl; + evt.from = fromEl || rootEl; + evt.item = targetEl || rootEl; + evt.clone = cloneEl; + evt.oldIndex = startIndex; + evt.newIndex = newIndex; - function _dispatchEvent(sortable, rootEl, name, targetEl, fromEl, startIndex, newIndex) { - sortable = (sortable || rootEl[expando]); + rootEl.dispatchEvent(evt); - var evt = document.createEvent('Event'), - options = sortable.options, - onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); + if (options[onName]) { + options[onName].call(sortable, evt); + } + } - evt.initEvent(name, true, true); - evt.to = rootEl; - evt.from = fromEl || rootEl; - evt.item = targetEl || rootEl; - evt.clone = cloneEl; + function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvt, willInsertAfter) { + var evt, + sortable = fromEl[expando], + onMoveFn = sortable.options.onMove, + retVal; - evt.oldIndex = startIndex; - evt.newIndex = newIndex; + evt = document.createEvent('Event'); + evt.initEvent('move', true, true); - rootEl.dispatchEvent(evt); + evt.to = toEl; + evt.from = fromEl; + evt.dragged = dragEl; + evt.draggedRect = dragRect; + evt.related = targetEl || toEl; + evt.relatedRect = targetRect || toEl.getBoundingClientRect(); + evt.willInsertAfter = willInsertAfter; + + fromEl.dispatchEvent(evt); + + if (onMoveFn) { + retVal = onMoveFn.call(sortable, evt, originalEvt); + } + + return retVal; + } - if (options[onName]) { - options[onName].call(sortable, evt); - } - } + function _disableDraggable(el) { + el.draggable = false; + } - function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvt, willInsertAfter) { - var evt, - sortable = fromEl[expando], - onMoveFn = sortable.options.onMove, - retVal; - - evt = document.createEvent('Event'); - evt.initEvent('move', true, true); - - evt.to = toEl; - evt.from = fromEl; - evt.dragged = dragEl; - evt.draggedRect = dragRect; - evt.related = targetEl || toEl; - evt.relatedRect = targetRect || toEl.getBoundingClientRect(); - evt.willInsertAfter = willInsertAfter; - - fromEl.dispatchEvent(evt); - - if (onMoveFn) { - retVal = onMoveFn.call(sortable, evt, originalEvt); - } - - return retVal; - } - - - function _disableDraggable(el) { - el.draggable = false; - } - - - function _unsilent() { - _silent = false; - } - - - /** @returns {HTMLElement|false} */ - function _ghostIsLast(el, evt) { - var lastEl = el.lastElementChild, - rect = lastEl.getBoundingClientRect(); - - // 5 — min delta - // abs — нельзя добавлять, а то глюки при наведении сверху - return (evt.clientY - (rect.top + rect.height) > 5) || - (evt.clientX - (rect.left + rect.width) > 5); - } - - - /** - * Generate id - * @param {HTMLElement} el - * @returns {String} - * @private - */ - function _generateId(el) { - var str = el.tagName + el.className + el.src + el.href + el.textContent, - i = str.length, - sum = 0; - - while (i--) { - sum += str.charCodeAt(i); - } - - return sum.toString(36); - } - - /** - * Returns the index of an element within its parent for a selected set of - * elements - * @param {HTMLElement} el - * @param {selector} selector - * @return {number} - */ - function _index(el, selector) { - var index = 0; - - if (!el || !el.parentNode) { - return -1; - } - - while (el && (el = el.previousElementSibling)) { - if ((el.nodeName.toUpperCase() !== 'TEMPLATE') && (selector === '>*' || _matches(el, selector))) { - index++; - } - } - - return index; - } - - function _matches(/**HTMLElement*/el, /**String*/selector) { - if (el) { - selector = selector.split('.'); - - var tag = selector.shift().toUpperCase(), - re = new RegExp('\\s(' + selector.join('|') + ')(?=\\s)', 'g'); - - return ( - (tag === '' || el.nodeName.toUpperCase() == tag) && - (!selector.length || ((' ' + el.className + ' ').match(re) || []).length == selector.length) - ); - } - - return false; - } - - function _throttle(callback, ms) { - var args, _this; - - return function () { - if (args === void 0) { - args = arguments; - _this = this; - - setTimeout(function () { - if (args.length === 1) { - callback.call(_this, args[0]); - } else { - callback.apply(_this, args); - } - - args = void 0; - }, ms); - } - }; - } - - function _extend(dst, src) { - if (dst && src) { - for (var key in src) { - if (src.hasOwnProperty(key)) { - dst[key] = src[key]; - } - } - } - - return dst; - } - - function _clone(el) { - return $ - ? $(el).clone(true)[0] - : (Polymer && Polymer.dom - ? Polymer.dom(el).cloneNode(true) - : el.cloneNode(true) - ); - } - - function _saveInputCheckedState(root) { - var inputs = root.getElementsByTagName('input'); - var idx = inputs.length; - - while (idx--) { - var el = inputs[idx]; - el.checked && savedInputChecked.push(el); - } - } - - // Fixed #973: - _on(document, 'touchmove', function (evt) { - if (Sortable.active) { - evt.preventDefault(); - } - }); - - try { - window.addEventListener('test', null, Object.defineProperty({}, 'passive', { - get: function () { - captureMode = { - capture: false, - passive: false - }; - } - })); - } catch (err) {} - - // Export utils - Sortable.utils = { - on: _on, - off: _off, - css: _css, - find: _find, - is: function (el, selector) { - return !!_closest(el, selector, el); - }, - extend: _extend, - throttle: _throttle, - closest: _closest, - toggleClass: _toggleClass, - clone: _clone, - index: _index - }; - - - /** - * Create sortable instance - * @param {HTMLElement} el - * @param {Object} [options] - */ - Sortable.create = function (el, options) { - return new Sortable(el, options); - }; - - - // Export - Sortable.version = '1.6.0'; - return Sortable; + + function _unsilent() { + _silent = false; + } + + + /** @returns {HTMLElement|false} */ + function _ghostIsLast(el, evt) { + var lastEl = el.lastElementChild, + rect = lastEl.getBoundingClientRect(); + + // 5 — min delta + // abs — нельзя добавлять, а то глюки при наведении сверху + return (evt.clientY - (rect.top + rect.height) > 5) || + (evt.clientX - (rect.left + rect.width) > 5); + } + + + /** + * Generate id + * @param {HTMLElement} el + * @returns {String} + * @private + */ + function _generateId(el) { + var str = el.tagName + el.className + el.src + el.href + el.textContent, + i = str.length, + sum = 0; + + while (i--) { + sum += str.charCodeAt(i); + } + + return sum.toString(36); + } + + /** + * Returns the index of an element within its parent for a selected set of + * elements + * @param {HTMLElement} el + * @param {selector} selector + * @return {number} + */ + function _index(el, selector) { + var index = 0; + + if (!el || !el.parentNode) { + return -1; + } + + while (el && (el = el.previousElementSibling)) { + if ((el.nodeName.toUpperCase() !== 'TEMPLATE') && (selector === '>*' || _matches(el, selector))) { + index++; + } + } + + return index; + } + + function _matches(/**HTMLElement*/el, /**String*/selector) { + if (el) { + selector = selector.split('.'); + + var tag = selector.shift().toUpperCase(), + re = new RegExp('\\s(' + selector.join('|') + ')(?=\\s)', 'g'); + + return ( + (tag === '' || el.nodeName.toUpperCase() == tag) && + (!selector.length || ((' ' + el.className + ' ').match(re) || []).length == selector.length) + ); + } + + return false; + } + + function _throttle(callback, ms) { + var args, _this; + + return function () { + if (args === void 0) { + args = arguments; + _this = this; + + setTimeout(function () { + if (args.length === 1) { + callback.call(_this, args[0]); + } else { + callback.apply(_this, args); + } + + args = void 0; + }, ms); + } + }; + } + + function _extend(dst, src) { + if (dst && src) { + for (var key in src) { + if (src.hasOwnProperty(key)) { + dst[key] = src[key]; + } + } + } + + return dst; + } + + function _clone(el) { + if (Polymer && Polymer.dom) { + return Polymer.dom(el).cloneNode(true); + } + else if ($) { + return $(el).clone(true)[0]; + } + else { + return el.cloneNode(true); + } + } + + function _saveInputCheckedState(root) { + var inputs = root.getElementsByTagName('input'); + var idx = inputs.length; + + while (idx--) { + var el = inputs[idx]; + el.checked && savedInputChecked.push(el); + } + } + + function _nextTick(fn) { + return setTimeout(fn, 0); + } + + function _cancelNextTick(id) { + return clearTimeout(id); + } + + // Fixed #973: + _on(document, 'touchmove', function (evt) { + if (Sortable.active) { + evt.preventDefault(); + } + }); + + // Export utils + Sortable.utils = { + on: _on, + off: _off, + css: _css, + find: _find, + is: function (el, selector) { + return !!_closest(el, selector, el); + }, + extend: _extend, + throttle: _throttle, + closest: _closest, + toggleClass: _toggleClass, + clone: _clone, + index: _index, + nextTick: _nextTick, + cancelNextTick: _cancelNextTick + }; + + + /** + * Create sortable instance + * @param {HTMLElement} el + * @param {Object} [options] + */ + Sortable.create = function (el, options) { + return new Sortable(el, options); + }; + + + // Export + Sortable.version = '1.7.0'; + return Sortable; }); diff --git a/src/components/Pivot/Pivot.jsx b/src/components/Pivot/Pivot.jsx index 72b4fa6..133235f 100644 --- a/src/components/Pivot/Pivot.jsx +++ b/src/components/Pivot/Pivot.jsx @@ -227,6 +227,8 @@ export default class Pivot extends PureComponent { '', ); + console.log('pivotedData', pivotedData); + Object.keys(filters).forEach((filter) => { pivotedData.filter((elem, index, array) => { return filters[filter].findIndex((field) => { diff --git a/yarn.lock b/yarn.lock index 55217a2..f6b7376 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1011,7 +1011,7 @@ babel-register@^6.26.0: mkdirp "^0.5.1" source-map-support "^0.4.15" -babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: +babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" dependencies: @@ -1717,7 +1717,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" -create-react-class@^15.5.2, create-react-class@^15.6.0: +create-react-class@^15.5.2: version "15.6.0" resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.0.tgz#ab448497c26566e1e29413e883207d57cfe7bed4" dependencies: @@ -2615,9 +2615,9 @@ fb-watchman@^2.0.0: dependencies: bser "^2.0.0" -fbjs@^0.8.9: - version "0.8.14" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.14.tgz#d1dbe2be254c35a91e09f31f9cd50a40b2a0ed1c" +fbjs@^0.8.16, fbjs@^0.8.9: + version "0.8.16" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" dependencies: core-js "^1.0.0" isomorphic-fetch "^2.1.1" @@ -5334,7 +5334,15 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8: +prop-types@>=15.0.0, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.0: + version "15.6.0" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.3.1" + object-assign "^4.1.1" + +prop-types@^15.5.10: version "15.5.10" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154" dependencies: @@ -5409,9 +5417,9 @@ querystringify@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb" -quick-pivot@^2.2.6: - version "2.2.7" - resolved "https://registry.yarnpkg.com/quick-pivot/-/quick-pivot-2.2.7.tgz#7b25aef443ddf7546d21fa49dc520faff2e25044" +quick-pivot@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/quick-pivot/-/quick-pivot-2.3.0.tgz#96cffd87536ee6bcdf649f7fd6b826efe12aa718" raf@^3.3.2: version "3.3.2" @@ -5453,20 +5461,21 @@ react-deep-force-update@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-2.1.0.tgz#1c5f36ea96bcbf411605ec063f36c568ea4df86c" -react-dom@^15.6.1: - version "15.6.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.1.tgz#2cb0ed4191038e53c209eb3a79a23e2a4cf99470" +react-dom@^16.1.0: + version "16.1.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.1.0.tgz#ab6fd2a285096f388aeba51919a573d06c9bdde4" dependencies: - fbjs "^0.8.9" + fbjs "^0.8.16" loose-envify "^1.1.0" - object-assign "^4.1.0" - prop-types "^15.5.10" + object-assign "^4.1.1" + prop-types "^15.6.0" -react-draggable@^2.2.6: - version "2.2.6" - resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-2.2.6.tgz#3a806e10f2da6babfea4136be6510e89b0d76901" +react-draggable@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-3.0.3.tgz#a6f9b3a7171981b76dadecf238316925cb9eacf4" dependencies: classnames "^2.2.5" + prop-types "^15.5.10" react-hot-loader@^3.0.0-beta.7: version "3.0.0-beta.7" @@ -5479,9 +5488,9 @@ react-hot-loader@^3.0.0-beta.7: redbox-react "^1.3.6" source-map "^0.4.4" -react-input-autosize@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-1.1.4.tgz#cbc45072d4084ddc57806db8e3b34e644b8366ac" +react-input-autosize@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.0.1.tgz#e92190497b4026c2780ad0f2fd703c835ba03e33" dependencies: create-react-class "^15.5.2" prop-types "^15.5.8" @@ -5492,34 +5501,38 @@ react-proxy@^3.0.0-alpha.0: dependencies: lodash "^4.6.1" -react-select@^1.0.0-rc.5: - version "1.0.0-rc.5" - resolved "https://registry.yarnpkg.com/react-select/-/react-select-1.0.0-rc.5.tgz#9d316f252b1adc372ddb5cdf1f119c6b7cfdb5d6" +react-select@^1.0.0-rc.10: + version "1.0.0-rc.10" + resolved "https://registry.yarnpkg.com/react-select/-/react-select-1.0.0-rc.10.tgz#f137346250f9255c979fbfa21860899928772350" dependencies: classnames "^2.2.4" - create-react-class "^15.5.2" prop-types "^15.5.8" - react-input-autosize "^1.1.3" + react-input-autosize "^2.0.1" -react-virtualized@^9.9.0: - version "9.9.0" - resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.9.0.tgz#799a6f23819eeb82860d59b82fad33d1d420325e" +react-sortablejs@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/react-sortablejs/-/react-sortablejs-1.3.5.tgz#824ef717c9357cf888d49f2d4f494508f7a962db" + dependencies: + prop-types ">=15.0.0" + +react-virtualized@^9.12.0: + version "9.12.0" + resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.12.0.tgz#1b4d3e5ab197ed1d832df8e6688b1b18f725b6c5" dependencies: - babel-runtime "^6.11.6" + babel-runtime "^6.23.0" classnames "^2.2.3" dom-helpers "^2.4.0 || ^3.0.0" loose-envify "^1.3.0" prop-types "^15.5.4" -react@^15.6.1: - version "15.6.1" - resolved "https://registry.yarnpkg.com/react/-/react-15.6.1.tgz#baa8434ec6780bde997cdc380b79cd33b96393df" +react@^16.1.0: + version "16.1.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.1.0.tgz#1c2bdac3c17fe7ee9282fa35aca6cc36387903e1" dependencies: - create-react-class "^15.6.0" - fbjs "^0.8.9" + fbjs "^0.8.16" loose-envify "^1.1.0" - object-assign "^4.1.0" - prop-types "^15.5.10" + object-assign "^4.1.1" + prop-types "^15.6.0" read-cache@^1.0.0: version "1.0.0" @@ -6081,6 +6094,10 @@ sort-keys@^1.0.0: dependencies: is-plain-obj "^1.0.0" +sortablejs@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/sortablejs/-/sortablejs-1.7.0.tgz#80a2b2370abd568e1cec8c271131ef30a904fa28" + source-list-map@^0.1.4: version "0.1.8" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" From 86b2e0c1f7805385e7fc1b31d607d29b826f8698 Mon Sep 17 00:00:00 2001 From: Niles Turner Date: Sun, 12 Nov 2017 21:30:32 -0500 Subject: [PATCH 06/12] add console log --- src/components/Pivot/Pivot.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/Pivot/Pivot.jsx b/src/components/Pivot/Pivot.jsx index 133235f..50e8ee6 100644 --- a/src/components/Pivot/Pivot.jsx +++ b/src/components/Pivot/Pivot.jsx @@ -338,6 +338,8 @@ export default class Pivot extends PureComponent { } } + console.log('pivotedData', pivotedData); + this.setState({ filters, headerCounter, From 5fde768e0dcab1a5b77da322f1a45f72a4e844e1 Mon Sep 17 00:00:00 2001 From: Niles Turner Date: Mon, 13 Nov 2017 00:09:17 -0500 Subject: [PATCH 07/12] implements basic totals --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index faf8a93..630e4ae 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "verbose": true }, "dependencies": { - "quick-pivot": "^2.3.0", + "quick-pivot": "^2.3.1", "react": "^16.1.0", "react-dom": "^16.1.0", "react-draggable": "^3.0.3", diff --git a/yarn.lock b/yarn.lock index f6b7376..3932bf1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5417,9 +5417,9 @@ querystringify@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-1.0.0.tgz#6286242112c5b712fa654e526652bf6a13ff05cb" -quick-pivot@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/quick-pivot/-/quick-pivot-2.3.0.tgz#96cffd87536ee6bcdf649f7fd6b826efe12aa718" +quick-pivot@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/quick-pivot/-/quick-pivot-2.3.1.tgz#4cc86f7de64de8c336b5b019e3f82b710aafeea1" raf@^3.3.2: version "3.3.2" From b0301378f661ca2316932f8df6df084f96effcae Mon Sep 17 00:00:00 2001 From: Niles Turner Date: Sun, 19 Nov 2017 01:09:11 -0500 Subject: [PATCH 08/12] update-deps-row-totals: final draft --- CHANGELOG.md | 4 + README.md | 6 + package.json | 7 +- src/app.jsx | 1 + src/components/Menu/Drawer/Drawer.spec.js | 22 +-- src/components/Pivot/Pivot.jsx | 17 +- src/components/Pivot/Pivot.spec.js | 5 + yarn.lock | 185 +++++++++++++--------- 8 files changed, 155 insertions(+), 92 deletions(-) create mode 100644 src/components/Pivot/Pivot.spec.js diff --git a/CHANGELOG.md b/CHANGELOG.md index b3fe187..e9b4668 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,3 +4,7 @@ Changelog ##### 0.1.1-beta * Removes react-md * Adds jest and some tests + +##### 0.1.2-beta +* Adds row totals as an optional prop enabled by default +* Updates React/React-DOM from 15.6.1 to 16.1.0 diff --git a/README.md b/README.md index a7d8c1e..cabdc3d 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,10 @@ You can also use a global-friendly UMD build: * rowHeaders: all the parent row headers above the current clicked row header cell and at the current cell * `onLeftHeaderCellClick` * A function that is fired when clicking on the top left most cell (above the row headers and to the left of the column headers) +* `rowTotals` + * A boolean that when false will not display row totals in the table. Totals are turned on by default. +* `selectedAggregationDimension` + * Sets the default aggregation dimension in the Drawer. ## Example usage with optional props ```js @@ -185,6 +189,8 @@ function onLeftHeaderCellClick() { onLeftGridCellClick={onLeftGridCellClick} onGridHeaderCellClick={onGridHeaderCellClick} onLeftHeaderCellClick={onLeftHeaderCellClick} + rowTotals={true} + selectedAggregationDimension={'age'} /> ``` diff --git a/package.json b/package.json index 630e4ae..ba65473 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-virtualized-pivot", - "version": "0.1.1-beta", + "version": "0.2.0-beta", "description": "React Virtualized Pivot", "main": "dist/es/index.js", "module": "dist/es/index.js", @@ -49,12 +49,14 @@ "verbose": true }, "dependencies": { + "enzyme-adapter-react-16": "^1.1.0", "quick-pivot": "^2.3.1", "react": "^16.1.0", "react-dom": "^16.1.0", "react-draggable": "^3.0.3", "react-select": "^1.0.0-rc.10", "react-sortablejs": "^1.3.5", + "react-test-renderer": "^16.1.1", "react-virtualized": "^9.12.0", "sortablejs": "^1.7.0" }, @@ -78,7 +80,7 @@ "babel-runtime": "^6.26.0", "cross-env": "^5.0.5", "css-loader": "0.26.1", - "enzyme": "^2.8.2", + "enzyme": "^3.2.0", "eslint": "^4.4.1", "eslint-loader": "1.1.0", "eslint-plugin-import": "^2.7.0", @@ -98,7 +100,6 @@ "pre-commit": "^1.2.2", "prop-types": "^15.5.10", "raf": "^3.3.2", - "react-addons-test-utils": "^15.5.1", "react-hot-loader": "^3.0.0-beta.7", "rimraf": "^2.6.1", "sass-loader": "^6.0.6", diff --git a/src/app.jsx b/src/app.jsx index a61afb7..124e0f2 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -305,6 +305,7 @@ export default class App extends React.Component { console.log('rowHeaders', rowHeaders); // eslint-disable-line no-console }} onLeftHeaderCellClick={() => console.log('clicking leftHeader')} // eslint-disable-line no-console + rowTotals={true} selectedAggregationDimension={selectedAggregationDimension} />
diff --git a/src/components/Menu/Drawer/Drawer.spec.js b/src/components/Menu/Drawer/Drawer.spec.js index 6426812..f5b49d1 100644 --- a/src/components/Menu/Drawer/Drawer.spec.js +++ b/src/components/Menu/Drawer/Drawer.spec.js @@ -1,16 +1,18 @@ import React from 'react'; -import { shallow } from 'enzyme'; +import { configure, shallow } from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; import Drawer from './Drawer.jsx'; -it('should render without throwing an error', function() { - const wrapper = shallow(); - const container = wrapper.find( -
- ); +configure({ adapter: new Adapter() }); - expect(container.root.length).toBe(1); -}); +describe('A suite', function() { + it('should render without throwing an error', function() { + const wrapper = shallow(); -it('should be selectable by class "drawer-container"', function() { - expect(shallow().is('.drawer-container')).toBe(true); + expect(wrapper.find('.react-virtualized-pivot-module-menu') + .length).toBe(1); + }); + it('should be selectable by class "drawer-container"', function() { + expect(shallow().is('.drawer-container')).toBe(true); + }); }); diff --git a/src/components/Pivot/Pivot.jsx b/src/components/Pivot/Pivot.jsx index 50e8ee6..8484de3 100644 --- a/src/components/Pivot/Pivot.jsx +++ b/src/components/Pivot/Pivot.jsx @@ -227,8 +227,6 @@ export default class Pivot extends PureComponent { '', ); - console.log('pivotedData', pivotedData); - Object.keys(filters).forEach((filter) => { pivotedData.filter((elem, index, array) => { return filters[filter].findIndex((field) => { @@ -413,7 +411,6 @@ export default class Pivot extends PureComponent { columnWidth, currentFilter, currentValues, - data, fields, filters, headerCounter, @@ -421,7 +418,6 @@ export default class Pivot extends PureComponent { overscanColumnCount, overscanRowCount, pivot, - rowCount, rowFields, rowHeight, selectedAggregationDimension, @@ -429,6 +425,11 @@ export default class Pivot extends PureComponent { isDrawerOpen, } = this.state; + let { + data, + rowCount, + } = this.state; + const { bodyCellValueTransformation, colorPack, @@ -436,6 +437,7 @@ export default class Pivot extends PureComponent { onGridHeaderCellClick, onLeftGridCellClick, onLeftHeaderCellClick, + rowTotals, } = this.props; const aggregationTypes = [ @@ -446,6 +448,11 @@ export default class Pivot extends PureComponent { { value: 'average', label: 'average' }, ]; + if (data !== undefined && data.length && !rowTotals) { + rowCount = rowCount - 1; + data = data.slice(0, rowCount); + } + return (
{}, onLeftGridCellClick: () => {}, onLeftHeaderCellClick: () => {}, + rowTotals: true, }; diff --git a/src/components/Pivot/Pivot.spec.js b/src/components/Pivot/Pivot.spec.js new file mode 100644 index 0000000..a5954d1 --- /dev/null +++ b/src/components/Pivot/Pivot.spec.js @@ -0,0 +1,5 @@ +describe('Pivot', () => { + it('should return true', () => { + expect(true).toEqual(true); + }); +}); diff --git a/yarn.lock b/yarn.lock index 3932bf1..993d6b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,10 @@ # yarn lockfile v1 +"@types/node@*": + version "8.0.53" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8" + abab@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.3.tgz#b81de5f7274ec4e756d797cd834f303642724e5d" @@ -1370,26 +1374,16 @@ chalk@^2.0.0, chalk@^2.1.0: escape-string-regexp "^1.0.5" supports-color "^4.0.0" -cheerio@^0.22.0: - version "0.22.0" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" +cheerio@^1.0.0-rc.2: + version "1.0.0-rc.2" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.2.tgz#4b9f53a81b27e4d5dac31c0ffd0cfa03cc6830db" dependencies: css-select "~1.2.0" dom-serializer "~0.1.0" entities "~1.1.1" htmlparser2 "^3.9.1" - lodash.assignin "^4.0.9" - lodash.bind "^4.1.4" - lodash.defaults "^4.0.1" - lodash.filter "^4.4.0" - lodash.flatten "^4.2.0" - lodash.foreach "^4.3.0" - lodash.map "^4.4.0" - lodash.merge "^4.4.0" - lodash.pick "^4.2.1" - lodash.reduce "^4.4.0" - lodash.reject "^4.4.0" - lodash.some "^4.4.0" + lodash "^4.15.0" + parse5 "^3.0.1" chokidar@^1.6.0, chokidar@^1.6.1, chokidar@^1.7.0: version "1.7.0" @@ -1543,6 +1537,10 @@ colormin@^1.0.5: css-color-names "0.0.4" has "^1.0.1" +colors@0.5.x: + version "0.5.1" + resolved "https://registry.yarnpkg.com/colors/-/colors-0.5.1.tgz#7d0023eaeb154e8ee9fce75dcb923d0ed1667774" + colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" @@ -2022,6 +2020,10 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" +discontinuous-range@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" + dns-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" @@ -2228,20 +2230,40 @@ entities@^1.1.1, entities@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" -enzyme@^2.8.2: - version "2.9.1" - resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-2.9.1.tgz#07d5ce691241240fb817bf2c4b18d6e530240df6" +enzyme-adapter-react-16@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.1.0.tgz#86c5db7c10f0be6ec25d54ca41b59f2abb397cf4" + dependencies: + enzyme-adapter-utils "^1.1.0" + lodash "^4.17.4" + object.assign "^4.0.4" + object.values "^1.0.4" + prop-types "^15.5.10" + react-test-renderer "^16.0.0-0" + +enzyme-adapter-utils@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.1.1.tgz#689de8853f0751710590d6dfa730ff4056ea36b2" + dependencies: + lodash "^4.17.4" + object.assign "^4.0.4" + prop-types "^15.5.10" + +enzyme@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.2.0.tgz#998bdcda0fc71b8764a0017f7cc692c943f54a7a" dependencies: - cheerio "^0.22.0" - function.prototype.name "^1.0.0" + cheerio "^1.0.0-rc.2" + function.prototype.name "^1.0.3" + has "^1.0.1" is-subset "^0.1.1" lodash "^4.17.4" object-is "^1.0.1" object.assign "^4.0.4" object.entries "^1.0.4" object.values "^1.0.4" - prop-types "^15.5.10" - uuid "^3.0.1" + raf "^3.4.0" + rst-selector-parser "^2.2.3" errno@^0.1.3, errno@^0.1.4: version "0.1.4" @@ -2812,7 +2834,7 @@ function-bind@^1.0.2, function-bind@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" -function.prototype.name@^1.0.0: +function.prototype.name@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.0.3.tgz#0099ae5572e9dd6f03c97d023fd92bcc5e639eac" dependencies: @@ -4047,14 +4069,6 @@ lodash.assign@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" -lodash.assignin@^4.0.9: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" - -lodash.bind@^4.1.4: - version "4.2.1" - resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" - lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" @@ -4071,54 +4085,18 @@ lodash.cond@^4.3.0: version "4.5.2" resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" -lodash.defaults@^4.0.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - -lodash.filter@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" - -lodash.flatten@^4.2.0: +lodash.flattendeep@^4.4.0: version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - -lodash.foreach@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" - -lodash.map@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" -lodash.merge@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" - lodash.mergewith@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55" -lodash.pick@^4.2.1: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" - -lodash.reduce@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" - -lodash.reject@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" - -lodash.some@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" - lodash.tail@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664" @@ -4131,7 +4109,7 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^4.0.0, lodash@^4.1.0, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.3.0, lodash@^4.6.1, lodash@~4.17.4: +lodash@^4.0.0, lodash@^4.1.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.3.0, lodash@^4.6.1, lodash@~4.17.4: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -4388,6 +4366,14 @@ ncname@1.0.x: dependencies: xml-char-classes "^1.0.0" +nearley@^2.7.10: + version "2.11.0" + resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.11.0.tgz#5e626c79a6cd2f6ab9e7e5d5805e7668967757ae" + dependencies: + nomnom "~1.6.2" + railroad-diagrams "^1.0.0" + randexp "^0.4.2" + negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" @@ -4505,6 +4491,13 @@ node-sass@^4.5.3: sass-graph "^2.1.1" stdout-stream "^1.4.0" +nomnom@~1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.6.2.tgz#84a66a260174408fc5b77a18f888eccc44fb6971" + dependencies: + colors "0.5.x" + underscore "~1.4.4" + "nopt@2 || 3": version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" @@ -4847,6 +4840,12 @@ parse5@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" +parse5@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" + dependencies: + "@types/node" "*" + parsejson@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/parsejson/-/parsejson-0.0.3.tgz#ab7e3759f209ece99437973f7d0f1f64ae0e64ab" @@ -5427,6 +5426,23 @@ raf@^3.3.2: dependencies: performance-now "^2.1.0" +raf@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.0.tgz#a28876881b4bc2ca9117d4138163ddb80f781575" + dependencies: + performance-now "^2.1.0" + +railroad-diagrams@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e" + +randexp@^0.4.2: + version "0.4.6" + resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3" + dependencies: + discontinuous-range "1.0.0" + ret "~0.1.10" + randomatic@^1.1.3: version "1.1.7" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" @@ -5453,10 +5469,6 @@ rc@^1.1.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-addons-test-utils@^15.5.1: - version "15.6.0" - resolved "https://registry.yarnpkg.com/react-addons-test-utils/-/react-addons-test-utils-15.6.0.tgz#062d36117fe8d18f3ba5e06eb33383b0b85ea5b9" - react-deep-force-update@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-2.1.0.tgz#1c5f36ea96bcbf411605ec063f36c568ea4df86c" @@ -5515,6 +5527,14 @@ react-sortablejs@^1.3.5: dependencies: prop-types ">=15.0.0" +react-test-renderer@^16.0.0-0, react-test-renderer@^16.1.1: + version "16.1.1" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.1.1.tgz#a05184688d564be799f212449262525d1e350537" + dependencies: + fbjs "^0.8.16" + object-assign "^4.1.1" + prop-types "^15.6.0" + react-virtualized@^9.12.0: version "9.12.0" resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.12.0.tgz#1b4d3e5ab197ed1d832df8e6688b1b18f725b6c5" @@ -5797,6 +5817,10 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + right-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" @@ -5816,6 +5840,13 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^2.0.0" inherits "^2.0.1" +rst-selector-parser@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91" + dependencies: + lodash.flattendeep "^4.4.0" + nearley "^2.7.10" + run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" @@ -6549,6 +6580,10 @@ ultron@1.0.x: version "1.0.2" resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" +underscore@~1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604" + uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" @@ -6633,7 +6668,7 @@ uuid@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" -uuid@^3.0.0, uuid@^3.0.1: +uuid@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" From e259111bf12bbcb4a6cf312a6a6e23f8c7f9e40b Mon Sep 17 00:00:00 2001 From: Niles Turner Date: Sun, 19 Nov 2017 01:11:56 -0500 Subject: [PATCH 09/12] update-deps-row-totals: small change --- CHANGELOG.md | 2 +- src/components/Pivot/Pivot.jsx | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9b4668..a9c2d40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,6 @@ Changelog * Removes react-md * Adds jest and some tests -##### 0.1.2-beta +##### 0.2.0-beta * Adds row totals as an optional prop enabled by default * Updates React/React-DOM from 15.6.1 to 16.1.0 diff --git a/src/components/Pivot/Pivot.jsx b/src/components/Pivot/Pivot.jsx index 8484de3..e812ebf 100644 --- a/src/components/Pivot/Pivot.jsx +++ b/src/components/Pivot/Pivot.jsx @@ -336,8 +336,6 @@ export default class Pivot extends PureComponent { } } - console.log('pivotedData', pivotedData); - this.setState({ filters, headerCounter, From 2c85c7ee04115e19a8485dc11f89c777615bcefb Mon Sep 17 00:00:00 2001 From: Niles Turner Date: Sun, 19 Nov 2017 23:13:35 -0500 Subject: [PATCH 10/12] fixed multiple fields when giving full fields and field in rows --- src/app.jsx | 2 +- src/components/Pivot/Pivot.jsx | 24 +++++++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/app.jsx b/src/app.jsx index 5cb21be..ff44a5d 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -41,7 +41,7 @@ export default class App extends React.Component { }, colFields: ['name'], rowFields: ['gender'], - onLeftGridCellClick: () => console.log('clicking leftHeader'), + onLeftGridCellClick: () => console.log('clicking leftHeader'), // eslint-disable-line no-console pivotOnChangeFunction: (prevState) => { /* eslint-disable */ const newState = prevState; diff --git a/src/components/Pivot/Pivot.jsx b/src/components/Pivot/Pivot.jsx index 171d61b..638d130 100644 --- a/src/components/Pivot/Pivot.jsx +++ b/src/components/Pivot/Pivot.jsx @@ -17,7 +17,25 @@ export default class Pivot extends PureComponent { }) : []; const dataArray = this.props.data !== undefined ? this.props.data : []; - const fields = this.props.data !== undefined ? this.props.data[0] : []; + let fields = this.props.data !== undefined ? this.props.data[0] : []; + const colFields = this.props.colFields || []; + const rowFields = this.props.rowFields || []; + + console.log('fields before colfields', fields) + if (fields.length) { + colFields.forEach((field) => { + console.log('in here', field) + if (fields.indexOf(field) > -1) { + fields = [].concat(fields.slice(0, fields.indexOf(field)), fields.slice(fields.indexOf(field)+1)); + } + }) + rowFields.forEach((field) => { + if (fields.indexOf(field) > -1) { + fields = [].concat(fields.slice(0, fields.indexOf(field)), fields.slice(fields.indexOf(field)+1)); + } + }) + } + const pivot = this.props.data !== undefined ? new QuickPivot(this.props.data, this.props.rowFields || [], this.props.colFields || [], this.props.selectedAggregationDimension || @@ -40,8 +58,8 @@ export default class Pivot extends PureComponent { dataArray, fields, pivot, - colFields: this.props.colFields || [], - rowFields: this.props.rowFields || [], + colFields, + rowFields, selectedAggregationType: 'sum', selectedAggregationDimension: this.props.selectedAggregationDimension || '', From 04ac815aa3072ad4cc3c30be7a82a5533c41a9ac Mon Sep 17 00:00:00 2001 From: Niles Turner Date: Tue, 21 Nov 2017 20:49:49 -0500 Subject: [PATCH 11/12] nearing final draft --- src/app.jsx | 10 +++++ src/components/Pivot/Pivot.jsx | 80 +++++++++++++++++++++++++++++----- 2 files changed, 78 insertions(+), 12 deletions(-) diff --git a/src/app.jsx b/src/app.jsx index ff44a5d..8c3fdc2 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -46,6 +46,7 @@ export default class App extends React.Component { /* eslint-disable */ const newState = prevState; newState.colFields=["name","house"]; + newState.filters={name: ["Cersei"]}; console.log('new state', newState) return newState } @@ -76,6 +77,14 @@ export default class App extends React.Component { selectedAggregationDimension: 'age', colFields: [], rowFields: [], + pivotOnChangeFunction: (prevState) => { + /* eslint-disable */ + const newState = prevState; + newState.colFields=["name","house"]; + newState.filters={name: ["Cersei"]}; + console.log('new state', newState) + return newState + }, }); } if (dataSize.value === 'medium') { @@ -297,6 +306,7 @@ export default class App extends React.Component { onChange={this.state.pivotOnChangeFunction} colorPack={colorPack} data={data} + filters={{name: ['Arya', 'Jon']}} onGridCellClick={({ rowIndex, columnIndex, diff --git a/src/components/Pivot/Pivot.jsx b/src/components/Pivot/Pivot.jsx index 638d130..0b06ac6 100644 --- a/src/components/Pivot/Pivot.jsx +++ b/src/components/Pivot/Pivot.jsx @@ -21,19 +21,19 @@ export default class Pivot extends PureComponent { const colFields = this.props.colFields || []; const rowFields = this.props.rowFields || []; - console.log('fields before colfields', fields) if (fields.length) { colFields.forEach((field) => { - console.log('in here', field) if (fields.indexOf(field) > -1) { - fields = [].concat(fields.slice(0, fields.indexOf(field)), fields.slice(fields.indexOf(field)+1)); + fields = [].concat(fields.slice(0, fields.indexOf(field)), + fields.slice(fields.indexOf(field) + 1)); } - }) + }); rowFields.forEach((field) => { if (fields.indexOf(field) > -1) { - fields = [].concat(fields.slice(0, fields.indexOf(field)), fields.slice(fields.indexOf(field)+1)); + fields = [].concat(fields.slice(0, fields.indexOf(field)), + fields.slice(fields.indexOf(field) + 1)); } - }) + }); } const pivot = this.props.data !== undefined ? @@ -41,6 +41,14 @@ export default class Pivot extends PureComponent { this.props.colFields || [], this.props.selectedAggregationDimension || '', 'sum', '') : {}; + Object.keys(this.props.filters).forEach((filter) => { + pivot.filter((elem, index, array) => { + return this.props.filters[filter].findIndex((field) => { + return field === elem[filter]; + }) === -1; + }); + }); + let headerCounter = 0; if (pivot.data) { @@ -65,7 +73,7 @@ export default class Pivot extends PureComponent { '', currentFilter: '', currentValues: [], - filters: {}, + filters: this.props.filters, columnWidth: 100, columnCount: (pivot !== undefined && pivot.data.table.length && @@ -101,20 +109,43 @@ export default class Pivot extends PureComponent { componentWillReceiveProps(nextProps) { if (nextProps.onChange !== undefined) { - const newState = this.props.onChange(this.state); + const newState = nextProps.onChange(this.state); const aggregationDimensions = nextProps.data !== undefined ? nextProps.data[0].map((item, index) => { return {value: item, label: item}; }) : []; const dataArray = nextProps.data !== undefined ? nextProps.data : []; - const fields = nextProps.data !== undefined ? nextProps.data[0] : []; + let fields = nextProps.data !== undefined ? nextProps.data[0] : []; + + if (fields.length) { + newState.colFields.forEach((field) => { + if (fields.indexOf(field) > -1) { + fields = [].concat(fields.slice(0, fields.indexOf(field)), + fields.slice(fields.indexOf(field) + 1)); + } + }); + newState.rowFields.forEach((field) => { + if (fields.indexOf(field) > -1) { + fields = [].concat(fields.slice(0, fields.indexOf(field)), + fields.slice(fields.indexOf(field) + 1)); + } + }); + } const pivot = nextProps.data !== undefined ? new QuickPivot(nextProps.data, newState.rowFields || [], newState.colFields || [], newState.selectedAggregationDimension || '', 'sum', '') : {}; + Object.keys(newState.filters).forEach((filter) => { + pivot.filter((elem, index, array) => { + return newState.filters[filter].findIndex((field) => { + return field === elem[filter]; + }) === -1; + }); + }); + let headerCounter = 0; if (pivot.data) { @@ -138,7 +169,7 @@ export default class Pivot extends PureComponent { '', currentFilter: '', currentValues: [], - filters: {}, + filters: newState.filters, columnWidth: 100, columnCount: (pivot !== undefined && pivot.data.table.length && @@ -162,13 +193,36 @@ export default class Pivot extends PureComponent { }) : []; const dataArray = nextProps.data !== undefined ? nextProps.data : []; - const fields = nextProps.data !== undefined ? nextProps.data[0] : []; + let fields = nextProps.data !== undefined ? nextProps.data[0] : []; + + if (fields.length) { + nextProps.colFields.forEach((field) => { + if (fields.indexOf(field) > -1) { + fields = [].concat(fields.slice(0, fields.indexOf(field)), + fields.slice(fields.indexOf(field) + 1)); + } + }); + nextProps.rowFields.forEach((field) => { + if (fields.indexOf(field) > -1) { + fields = [].concat(fields.slice(0, fields.indexOf(field)), + fields.slice(fields.indexOf(field) + 1)); + } + }); + } const pivot = nextProps.data !== undefined ? new QuickPivot(nextProps.data, nextProps.rowFields || [], nextProps.colFields || [], nextProps.selectedAggregationDimension || '', 'sum', '') : {}; + Object.keys(nextProps.filters).forEach((filter) => { + pivot.filter((elem, index, array) => { + return nextProps.filters[filter].findIndex((field) => { + return field === elem[filter]; + }) === -1; + }); + }); + let headerCounter = 0; if (pivot.data) { @@ -193,7 +247,7 @@ export default class Pivot extends PureComponent { '', currentFilter: '', currentValues: [], - filters: {}, + filters: nextProps.filters, columnWidth: 100, columnCount: (pivot !== undefined && pivot.data.table.length && @@ -620,6 +674,7 @@ Pivot.propTypes = { bodyCellValueTransformation: PropTypes.func, colorPack: PropTypes.object, data: PropTypes.array.isRequired, + filters: PropTypes.object, onChange: PropTypes.func, onGridCellClick: PropTypes.func, onGridHeaderCellClick: PropTypes.func, @@ -652,6 +707,7 @@ Pivot.defaultProps = { sortableFieldBackground: '#fafafa', sortableFieldText: '#000', }, + filters: {}, onGridCellClick: () => {}, onGridHeaderCellClick: () => {}, onLeftGridCellClick: () => {}, From c59047f195359250aa404d2d37976879a96b319c Mon Sep 17 00:00:00 2001 From: Niles Turner Date: Thu, 18 Jan 2018 02:02:18 -0500 Subject: [PATCH 12/12] logs --- src/app.jsx | 1 + src/components/Pivot/Pivot.jsx | 2 ++ src/components/Table/Table.jsx | 4 ++++ 3 files changed, 7 insertions(+) diff --git a/src/app.jsx b/src/app.jsx index 8c3fdc2..1b3f85d 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -42,6 +42,7 @@ export default class App extends React.Component { colFields: ['name'], rowFields: ['gender'], onLeftGridCellClick: () => console.log('clicking leftHeader'), // eslint-disable-line no-console + pivotOnChangeEnabled: true, pivotOnChangeFunction: (prevState) => { /* eslint-disable */ const newState = prevState; diff --git a/src/components/Pivot/Pivot.jsx b/src/components/Pivot/Pivot.jsx index 0b06ac6..8f95a15 100644 --- a/src/components/Pivot/Pivot.jsx +++ b/src/components/Pivot/Pivot.jsx @@ -108,7 +108,9 @@ export default class Pivot extends PureComponent { } componentWillReceiveProps(nextProps) { + console.log(nextProps) if (nextProps.onChange !== undefined) { + console.log('in the onchange') const newState = nextProps.onChange(this.state); const aggregationDimensions = nextProps.data !== undefined ? nextProps.data[0].map((item, index) => { diff --git a/src/components/Table/Table.jsx b/src/components/Table/Table.jsx index 9fc6aa4..5dd2aaf 100644 --- a/src/components/Table/Table.jsx +++ b/src/components/Table/Table.jsx @@ -35,6 +35,10 @@ export default class Table extends PureComponent { } componentWillReceiveProps(nextProps) { + console.log(nextProps.rawData === this.props.rawData) + console.log(nextProps.rawData) + console.log(this.props.rawData) + console.log('hi', nextProps) if (nextProps.columnCount !== this.props.columnCount) { this.setState({ columnWidths: Array(nextProps.columnCount > 1 ?