| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479 |
- 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 Defaults = {}
- var Defaults__baseCellStyle = {
- height: 26,
- padding: 4
- };
- Defaults.cellFontSize = 12;
- Defaults.rowsPerPage = 10;
- Defaults.cellLineHeight = 18;
- Defaults.baseCellStyle = Defaults__baseCellStyle;
- Defaults.baseStickyCellStyle = Object.assign({}, Defaults__baseCellStyle, {
- position: "absolute", top: "auto", left: "0",
- 'background-color': "#fff"
- });
- Defaults.baseHeaderCellStyle = {
- 'padding': "2px 5px",
- 'white-space': 'nowrap',
- 'line-height': Defaults.cellLineHeight+"px",
- 'font-size': Defaults.cellFontSize+"px",
- 'border-bottom-width': "1px",
- 'vertical-align': "bottom",
- };
- Defaults.primaryKeyLabel = "Nr";
- 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: Object.assign({}, {
- display: "table",
- }, props.style)
- }, [
- h('th', { style: Defaults.baseHeaderCellStyle }, 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,
- primaryKeyLabel: this.props.primaryKeyLabel || Defaults.primaryKeyLabel,
- };
- },
- 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 ? "<br>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 // TODO: depend on primaryKeyLabel width
- ]
- }, 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('<br>', '###').replace('<br/>', '###').split("###").length);
- }, 1)
- return 2 * 2 + maxLines * Defaults.cellLineHeight;
- },
- renderTheadColNameRowCell: function (value, cellIdx) {
- var label = this.state.cols[cellIdx];
- return h('th', {
- style: Defaults.baseHeaderCellStyle,
- }, label.replace('<br>', '###<br>###').replace('<br/>', '###<br>###').split("###").map(function (txtOrBr) {
- return ('<br>' === txtOrBr) ? h('br') : txtOrBr;
- }));
- },
- renderTheadFilterRowCell: function (value, cellIdx) {
- return h('td', { style: { padding: 0 } }, [
- // <input class="filter" placeholder="%" type="text" value="" style="box-sizing: border-box; width: 100%; height: 21px; border-top: 0px; border-bottom: 2px solid transparent;">
- 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", width: (cell1Width - 1), height: headerCellHeight });
- var cell2Style = Object.assign({}, this.state.baseStickyCellStyle, { position: "absolute", top: "auto", width: (cell2Width - 1), height: headerCellHeight });
- var cell3Style = Object.assign({}, this.state.baseStickyCellStyle, { position: "absolute", top: "auto", width: (cell3Width - 1), height: headerCellHeight });
- cell1Style.left = "0";
- cell2Style.left = cell1Width;
- cell3Style.left = cell1Width + cell2Width;
- var label = this.state.primaryKeyLabel;
- 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
|