var DBG = DBG || false;
var DBG1 = true;
if (!global.p5VendorJs) throw "Missing p5 Vendor js libs";
// if (!global.p5VendorJs.Redux) throw "Missing p5 Vendor js lib: Redux";
var createReactClass = global.p5VendorJs.createReactClass;
var h = global.p5VendorJs.React.createElement;
var ReactDOM = global.p5VendorJs.ReactDOM;
// var Redux = global.p5VendorJs.Redux;
// var ReduxThunk = global.p5VendorJs.ReduxThunk;
// var createStoreWithThunkMiddleware = Redux.applyMiddleware(ReduxThunk)(Redux.createStore); // TODO: to vendor.js
var baseCellStyle = {
height: 26,
padding: 4
};
var baseStickyCellStyle = Object.assign({}, baseCellStyle, {
position: "absolute", top: "auto", left: "0",
'background-color': "#fff"
});
var Defaults = {
cellFontSize: 12,
rowsPerPage: 10,
cellLineHeight: 18,
baseCellStyle: baseCellStyle,
baseStickyCellStyle: baseStickyCellStyle,
}
function p5Utils__mapToQuery(map, callback) {
var mapCallback = ('function' === typeof callback) ? callback : function (key) {
return '' + key + '=' + encodeURIComponent(map.get(key));
};
return Array.from(map.keys()).sort()
.map(mapCallback)
.join('&')
}
function p5Utils__mapToQueryWithKeyPrefix(map, keyPrefix, callback) {
var mapCallback = ('function' === typeof callback) ? callback : function (key) {
return '' + (keyPrefix || '') + key + '=' + encodeURIComponent(map.get(key));
};
return p5Utils__mapToQuery(map, mapCallback)
}
function p5Utils__objectToQueryWithKeyPrefix(obj, prefix, callback) {
if (!obj) return '';
var mapCallback = ('function' === typeof callback) ? callback : function (key) {
return '' + key + '=' + encodeURIComponent(obj[key]);
};
return Object.keys(obj).sort()
.map(mapCallback)
.join('&')
}
var TableAjax_Feature_FunctionsCell = function (props) {
DBG && console.warn('DBG::TableAjax_Feature_FunctionsCell::render', { props: props });
return h('div', {
style: props.style
}, [
(props.primaryKey) ? "F(" + props.primaryKey + ")" : null
]);
};
var TableAjax_Feature_SelectedCell = function (props) {
DBG && console.warn('DBG::TableAjax_Feature_SelectedCell::render', { props: props });
return h('div', {
style: props.style
}, [
(props.primaryKey) ? h('input', { type: 'checkbox', title: props.primaryKey }) : null
]);
};
var TableAjax_Feature_PrimaryKeyCell = function (props) {
return h('div', {
style: props.style
}, props.primaryKey);
};
var TableAjax_Filter_FunctionsCell = function (props) {
DBG && console.warn('DBG::TableAjax_Filter_FunctionsCell::render', { props: props });
return h('div', {
style: props.style
}, [
"(x)"
]);
};
var TableAjax_Filter_SelectedCell = function (props) {
DBG && console.warn('DBG::TableAjax_Filter_SelectedCell::render', { props: props });
return h('div', {
style: props.style
}, [
h('input', { type: 'checkbox' })
]);
};
var TableAjax_Filter_PrimaryKeyCell = function (props) {
return h('div', {
style: props.style
}, [
h('input', {
type: "text",
placeholder: "%",
style: {
'box-sizing': "border-box",
padding: "0 5px",
width: "100%",
height: "100%",
'border': "0px",
'border-bottom': "2px solid transparent",
'background-color': "#eee"
}
})
]);
};
var TableAjax_Label_FunctionsCell = function (props) {
DBG && console.warn('DBG::TableAjax_Label_FunctionsCell::render', { props: props });
return h('div', {
style: props.style
}, [
"(icons)"
]);
};
var TableAjax_Label_SelectedCell = function (props) {
DBG && console.warn('DBG::TableAjax_Label_SelectedCell::render', { props: props });
return h('div', {
style: props.style
}, [
h('input', { type: 'checkbox' })
]);
};
var TableAjax_Label_PrimaryKeyCell = function (props) {
return h('div', {
style: props.style
}, props.label);
};
var TableAjax_Tbody = createReactClass({
renderDataRow: function (value, rowIdx) {
var allColsCount = 13; // TODO: (this.state.cols.length || 0) + 3;
var renderRowCell = this.renderRowCell(rowIdx).bind(this);
return h('tr', {},
[
this.renderStickyRowCell(rowIdx)
].concat(
Array.apply(null, { length: allColsCount }).map(renderRowCell)
)
);
},
renderRowCell: function (rowIdx) {
var _rowIdx = rowIdx;
var _item = this.getItem(rowIdx);
return function (value, cellIdx) {
var value = (_item) ? Object.values(_item).slice(3)[ cellIdx ] : ''; // TODO: convert item to values Array by fields order - function itemToGridValuesList - defined in parent, passed by prop
return h('td', {
style: Object.assign({}, Defaults.baseCellStyle, {
})
}, value);
}
},
renderStickyRowCell: function (rowIdx) {
var cell1Width = this.props.stickyColWidths[0];
var cell2Width = this.props.stickyColWidths[1];
var cell3Width = this.props.stickyColWidths[2];
var cell1Style = Object.assign({}, Defaults.baseStickyCellStyle, { position: "absolute", top: "auto", left: "0", width: (cell1Width - 1), height: Defaults.baseCellStyle.height - 1 });
var cell2Style = Object.assign({}, Defaults.baseStickyCellStyle, { position: "absolute", top: "auto", left: cell1Width, width: (cell2Width - 1), height: Defaults.baseCellStyle.height - 1 });
var cell3Style = Object.assign({}, Defaults.baseStickyCellStyle, { position: "absolute", top: "auto", left: cell1Width + cell2Width, width: (cell3Width - 1), height: Defaults.baseCellStyle.height - 1 });
var item = this.getItem(rowIdx);
var primaryKey = (item) ? item['@primaryKey'] : null;
return h('td', {
style: Object.assign({}, Defaults.baseCellStyle, {
display: "block", position: "absolute", left: 0, top: "auto",
width: (cell1Width + cell2Width + cell3Width),
padding: 0,
'background-color': "#ddd"
})
}, [
h(TableAjax_Feature_FunctionsCell, { style: cell1Style, primaryKey: primaryKey }),
h(TableAjax_Feature_SelectedCell, { style: cell2Style, primaryKey: primaryKey }),
h(TableAjax_Feature_PrimaryKeyCell, { style: cell3Style, primaryKey: primaryKey }),
]);
},
getItem: function (rowIdx) {
return (this.props.rows.length > rowIdx) ? this.props.rows[rowIdx] : null; // { primaryKey: rowIdx } // TODO: real data
},
shouldComponentUpdate: function (nextProps, nextState) {
// receivedRequestId
var shouldUpdate = false;
if (nextProps.receivedRequestId > this.props.receivedRequestId) shouldUpdate = true;
if (nextProps.rowsPerPage != this.props.rowsPerPage) shouldUpdate = true;
else if (nextProps.stickyColWidths.join(',') != this.props.stickyColWidths.join(',')) shouldUpdate = true;
DBG && console.log("DBG:TableAjax_Tbody:shouldComponentUpdate", { shouldUpdate, props: this.props, nextProps, state: this.state, nextState });
return shouldUpdate;
},
render: function () {
DBG && console.log("DBG:TableAjax_Tbody:render");
return h('tbody', {}, [
Array.apply(null, { length: this.props.rowsPerPage }).map(this.renderDataRow)
]);
}
});
// p5UI__TableAjax.props.dataStore: priv.options.tableDataStore,
// p5UI__TableAjax.props.dataActions: priv.options.tableDataActions,
// p5UI__TableAjax.props.filterStore: priv.options.filterStore,
// p5UI__TableAjax.props.filterActions: priv.options.filterActions,
// p5UI__TableAjax.props.selectedStore: priv.options.selectedStore,
// p5UI__TableAjax.props.selectedActions: priv.options.selectedActions,
var p5UI__TableAjax = createReactClass({
// props.namespace
// props.width - table max width
// @doc: element.scrollLeft = intValue; // set scroll left for dom element
// TODO: stickyCols = [ rowFunctions, selectFeature, primaryKey, ...custom fields ]
_refContentEl: null,
setContentElRef: function (el) {
this._refContentEl = el;
},
_getStateFromDataStore: function () {
var state = this.props.dataStore.getState();
DBG && console.log('DBG::P5UI__TableAjax::_getStateFromDataStore', { state: state });
return {
width: state.width,
rowsPerPage: state.rowsPerPage || Defaults.rowsPerPage,
isLoading: state.isLoading,
sentRequestId: state.sentRequestId,
receivedRequestId: state.receivedRequestId,
rows: state.rows
};
},
getItem: function (rowIdx) {
return (this.state.rows.length > rowIdx) ? this.state.rows[rowIdx] : null; // { primaryKey: rowIdx } // TODO: real data
},
getInitialState: function () {
var cols = Array.apply(null, { length: 13 }).map(function (undefinedValue, cellIdx) {
var label = "Col("+cellIdx+")" + ( cellIdx % 2 ? "
Col line 2..." : "" );
return label;
});
var baseCellStyle = {
height: 26,
padding: 4
};
var baseStickyCellStyle = Object.assign({}, baseCellStyle, {
position: "absolute", top: "auto", left: "0",
'background-color': "#fff"
});
return Object.assign({
isLoading: false,
filter: null,
cols: cols,
data: [],
rowsPerPage: 10,
baseCellStyle: baseCellStyle,
baseStickyCellStyle: baseStickyCellStyle,
stickyColWidths: [
50,
25,
75 // 63
]
}, this._getStateFromDataStore());
},
componentDidMount: function () {
DBG && console.log('DBG::P5UI__TableAjax::componentDidMount');
this._unsubscribeDataStore = this.props.dataStore.subscribe(this._dataStoreUpdated)
this._unsubscribeFilterStore = this.props.filterStore.subscribe(this._filterStoreUpdated)
},
componentWillUnmount: function () {
this._unsubscribeDataStore()
this._unsubscribeFilterStore()
},
_dataStoreUpdated: function () {
DBG && console.log('DBG::P5UI__TableAjax::_dataStoreUpdated');
this.setState(this._getStateFromDataStore())
},
_filterStoreUpdated: function () {
DBG && console.log('DBG::P5UI__TableAjax::_filterStoreUpdated');
var curFilterState = this._getStateFromFilterStore();
var needFetchData = (
!this.state.filter
|| curFilterState.filterQuery !== this.state.filter.filterQuery
|| curFilterState.specialFilterQuery !== this.state.filter.specialFilterQuery
|| curFilterState.currSortCol !== this.state.filter.currSortCol
|| curFilterState.currSortFlip !== this.state.filter.currSortFlip
);
if (needFetchData) {
this.setState({ filter: curFilterState })
this.props.dataStore.dispatch(this.props.dataActions.loadData(this.props.namespace, curFilterState))
}
},
_getStateFromFilterStore: function () {
var curFilterState = this.props.filterStore.getState();
return {
filterQuery: p5Utils__mapToQueryWithKeyPrefix(curFilterState.filter, 'f_'),
specialFilterQuery: p5Utils__mapToQueryWithKeyPrefix(curFilterState.specialFilter, 'sf_'),
currSortCol: curFilterState.currSortCol,
currSortFlip: curFilterState.currSortFlip
};
},
shouldComponentUpdate: function (nextProps, nextState) {
DBG && console.log('DBG::P5UI__TableAjax::shouldComponentUpdate - TODO only when data changed?', { props: this.props, nextProps, state: this.state, nextState });
return true;
// var dataChanged = true; // TODO compare this.state.rows with nextState.rows array
// var getPk = function (item) {
// return item['@primaryKey'];
// }
// var listPks = this.state.rows.map(getPk).join(',');
// var prevPks = nextState.rows.map(getPk).join(',');
// DBG && console.log('DBG::P5UI__TableAjax::shouldComponentUpdate', { state: this.state, nextState, listPks, prevPks });
// return (
// this.state.isLoading !== nextState.isLoading
// || this.state.width !== nextState.width
// || dataChanged
// );
},
getTheadCellHeight: function () {
var maxLines = this.state.cols.reduce(function (ret, cell) {
var label = cell;
return Math.max(ret, label.replace('
', '###').replace('
', '###').split("###").length);
}, 1)
return 2 * 2 + maxLines * Defaults.cellLineHeight;
},
renderTheadColNameRowCell: function (value, cellIdx) {
var label = this.state.cols[cellIdx];
return h('th', {
style: {
padding: "2px 120px",
'white-space': 'nowrap',
'line-height': Defaults.cellLineHeight+"px",
'font-size': Defaults.cellFontSize+"px",
'border-bottom-width': "1px"
}
}, label.replace('
', '###
###').replace('
', '###
###').split("###").map(function (txtOrBr) {
return ('
' === txtOrBr) ? h('br') : txtOrBr;
}));
},
renderTheadFilterRowCell: function (value, cellIdx) {
return h('td', { style: { padding: 0 } }, [
//
h('input', {
type: "text",
placeholder: "%",
style: {
'box-sizing': "border-box",
width: "100%",
height: "26px",
padding: "4px 5px 0 5px",
'font-size': "12px",
'border': 0,
'border-bottom': "2px solid transparent",
'background-color': "#eee"
}
})
]);
},
renderStickyTheadNameRowCell: function (item) {
var headerCellHeight = this.getTheadCellHeight();
var cell1Width = this.state.stickyColWidths[0];
var cell2Width = this.state.stickyColWidths[1];
var cell3Width = this.state.stickyColWidths[2];
var cell1Style = Object.assign({}, this.state.baseStickyCellStyle, { position: "absolute", top: "auto", left: "0", width: (cell1Width - 1), height: headerCellHeight });
var cell2Style = Object.assign({}, this.state.baseStickyCellStyle, { position: "absolute", top: "auto", left: cell1Width, width: (cell2Width - 1), height: headerCellHeight });
var cell3Style = Object.assign({}, this.state.baseStickyCellStyle, { position: "absolute", top: "auto", left: cell1Width + cell2Width, width: (cell3Width - 1), height: headerCellHeight });
var label = 'Nr'; // TODO: get primaryKey cell label
return h('td', {
style: Object.assign({}, this.state.baseCellStyle, {
display: "block", position: "absolute", left: 0, top: "auto",
width: (cell1Width + cell2Width + cell3Width),
height: headerCellHeight,
padding: 0,
'background-color': "#ddd"
})
}, [
h(TableAjax_Label_FunctionsCell, { style: cell1Style }),
h(TableAjax_Label_SelectedCell, { style: cell2Style }),
h(TableAjax_Label_PrimaryKeyCell, { style: cell3Style, label: label }),
]);
},
renderStickyTheadFilterRowCell: function (item) {
var cell1Width = this.state.stickyColWidths[0];
var cell2Width = this.state.stickyColWidths[1];
var cell3Width = this.state.stickyColWidths[2];
var cell1Style = Object.assign({}, this.state.baseStickyCellStyle, { position: "absolute", top: "auto", left: "0", width: (cell1Width - 1) });
var cell2Style = Object.assign({}, this.state.baseStickyCellStyle, { position: "absolute", top: "auto", left: cell1Width, width: (cell2Width - 1) });
var cell3Style = Object.assign({}, this.state.baseStickyCellStyle, { position: "absolute", top: "auto", left: cell1Width + cell2Width, width: (cell3Width - 1), padding: "none" });
return h('td', {
style: Object.assign({}, this.state.baseCellStyle, {
display: "block", position: "absolute", left: 0, top: "auto",
width: (cell1Width + cell2Width + cell3Width),
height: this.state.baseCellStyle.height + 2,
padding: 0,
'background-color': "#ddd"
})
}, [
h(TableAjax_Filter_FunctionsCell, { style: cell1Style }),
h(TableAjax_Filter_SelectedCell, { style: cell2Style }),
h(TableAjax_Filter_PrimaryKeyCell, { style: cell3Style }),
]);
},
render: function () {
DBG && console.log('DBG::P5UI__TableAjax::render', { state: this.state });
var baseStyle = { 'border-top': "1px solid red", 'border-bottom': "1px solid red", 'min-height': "100px" } // TODO: DBG
var allColsCount = 13; // TODO: (this.state.cols.length || 0) + 3;
var widthTotal = this.state.width || 1200;
var widthStickyCols = this.state.stickyColWidths.reduce(function (a, b) { return a + b; }, 0);
var widthScrollableContent = widthTotal - widthStickyCols - 2;
return h('div', {
className: "p5UI__TableAjax",
style: Object.assign(baseStyle, {
'background-color': "#ddd",
})
}, [
h('div', { style: { 'background-color': "#f00", color: "#fff", padding: "3px 12px" } }, "namespace: '" + this.props.namespace + "' getTheadCellHeight("+this.getTheadCellHeight()+")"),
h('div', {
ref: this.setContentElRef,
style: {
'margin-left': widthStickyCols + 2,
// 'min-height': "300px",
'overflow': "scroll visible",
'padding-bottom': "1px",
'clear': "both",
'width': widthScrollableContent,
'background-color': "#fff",
}
}, [
h('table', {
className: "table table-bordered table-condensed",
style: {
'margin-bottom': 0,
'margin-left': "-2px",
}
}, [
h('thead', {}, [
h('tr', {}, [ this.renderStickyTheadNameRowCell() ].concat( Array.apply(null, { length: allColsCount }).map(this.renderTheadColNameRowCell) )),
h('tr', {}, [ this.renderStickyTheadFilterRowCell() ].concat( Array.apply(null, { length: allColsCount }).map(this.renderTheadFilterRowCell) ))
]),
h(TableAjax_Tbody, {
rowsPerPage: this.state.rowsPerPage,
receivedRequestId: this.state.receivedRequestId,
rows: this.state.rows,
stickyColWidths: this.state.stickyColWidths,
// store: this.props.dataStore
})
])
]),
h('hr', { style: { border: "5px solid red" } }),
h('pre', { style: { padding: "6px 12px", border: "1px solid red", 'background-color': "#eee" } }, [
"State: ",
(this.state.isLoading) ? " loading... " : null,
]),
h('div', { style: { padding: "6px 12px", border: "1px solid red", 'background-color': "#eee" } }, [
"TEST btns: ",
h('button', { onClick: this._testScrollContentTo100Left }, "scroll 100"),
h('button', { onClick: this._testScrollContentTo200Left }, "scroll 200"),
h('button', { onClick: this._testScrollContentTo0Left }, "scroll 0"),
h('button', { onClick: this._testLoadData }, "load data"),
])
]);
},
_testLoadData: function () { this.props.dataStore.dispatch(this.props.dataActions.loadData(this.props.namespace)); },
_testScrollContentTo100Left: function () { this._refContentEl.scrollLeft = 100; },
_testScrollContentTo200Left: function () { this._refContentEl.scrollLeft = 200; },
_testScrollContentTo0Left: function () { this._refContentEl.scrollLeft = 0; }
});
global.p5VendorJs['p5UI__TableAjax'] = p5UI__TableAjax;
// export default p5UI__TableAjax