Browse Source

+ export to html, csv in bocian table

Piotr Labudda 6 years ago
parent
commit
646cad3574
2 changed files with 598 additions and 122 deletions
  1. 18 0
      tools/Bocian.php
  2. 580 122
      tools/Bocian.php.view.js

+ 18 - 0
tools/Bocian.php

@@ -164,6 +164,22 @@ public static $helpEmailTo = 'biuro@bialnet.com.pl'; // todo:email na który zos
 
 		echo UI::h('script', ['src'=>"static/vendor.js?v=71baa97d", 'type'=>"text/javascript"]);
 		$this->viewIncludeStoreJs($storeName = "bocianRaportStore");
+		$aclOd = ACL::getAclByNamespace('default_db/BI_audit_ENERGA_PRACOWNICY/BI_audit_ENERGA_PRACOWNICY');
+		$exportFieldsOd = Core_AclHelper::getExportFieldList($aclOd);
+		$exportFieldLabelsOd = array_map(function ($fieldName) use ($aclOd) {
+			return [ 'name' => $fieldName, 'label' => $aclOd->getFieldLabel($fieldName) ];
+		}, $exportFieldsOd);
+
+		$aclDo = ACL::getAclByNamespace('default_db/BI_audit_ENERGA_RUM_KONTRAHENCI/BI_audit_ENERGA_RUM_KONTRAHENCI');
+		$exportFieldsDo = Core_AclHelper::getExportFieldList($aclDo);
+		$exportFieldLabelsDo = array_map(function ($fieldName) use ($aclDo) {
+			return [ 'name' => $fieldName, 'label' => $aclDo->getFieldLabel($fieldName) ];
+		}, $exportFieldsDo);
+		// $exportFieldLabelsDo = [ // TODO: RMME TEST DEV
+		// 	[ 'name' => 'ID', 'label' => 'Nr' ],
+		// 	[ 'name' => 'NIP', 'label' => 'NIP' ],
+		// ];
+
 		UI::inlineJS(__FILE__ . '.view.js', [
 			'BASE_URLS' => Request::getPathUri(),
 			'URL_FETCH_KONTRAHENCI_POWIAZANIA' => $this->getLink('fetchEnergaRumKontrahenciPowiazaniaAjax'),
@@ -205,6 +221,8 @@ public static $helpEmailTo = 'biuro@bialnet.com.pl'; // todo:email na który zos
 			'FIELD_LIST_KONTRAHENCI' => array_map(function ($fieldName) {
 				return "f_{$fieldName}";
 			}, self::$FIELD_LIST_KONTRAHENCI),
+			'EXPORT_FIELDS_OD' => $exportFieldLabelsOd,
+			'EXPORT_FIELDS_DO' => $exportFieldLabelsDo,
 			'CURRENT_DATE' => date("j.n.Y"),
 			'STORE_NAME' => $storeName = "bocianRaportStore",
 		]);

+ 580 - 122
tools/Bocian.php.view.js

@@ -10,12 +10,17 @@ if (!BASE_URLS) throw "Brak BASE_URLS"
 var RECORD_MORE_FUNCTIONS_OPENED_NODE = null;
 if (!FIELD_LIST_PRACOWNICY) throw "Brak FIELD_LIST_PRACOWNICY"
 if (!FIELD_LIST_KONTRAHENCI) throw "Brak FIELD_LIST_KONTRAHENCI"
+var EXPORT_FIELDS_OD = EXPORT_FIELDS_OD || null;
+var EXPORT_FIELDS_DO = EXPORT_FIELDS_DO || null;
 
 var createReactClass = global.p5VendorJs.createReactClass;
 var h = global.p5VendorJs.React.createElement;
 var ReactDOM = global.p5VendorJs.ReactDOM;
 var swal = window.swal;
 var globalRaportStore = global[STORE_NAME];
+if (!p5UI__clickedOutsideElement) throw "Brak p5UI__clickedOutsideElement"
+if (!global.p5VendorJs.Unstated) throw "Brak Unstated"
+var Unstated = global.p5VendorJs.Unstated;
 
 var P5UI__BocianHeader = createReactClass({
 	getStateFromStore: function () {
@@ -1561,6 +1566,36 @@ function getNameGroupById(store, filterIdGroup) {
 	return NAZWA;
 }
 
+function getSearchParamsKontrahenci(page) {
+	var filterIdGroup = getItemLocalStorage('Bocian.biAuditForm.kontrahenci.filterIdGroup');
+	var frm = document.getElementById('filtersFieldRemoveBtn-KONTRAHENCI').form
+	var fieldNameList = FIELD_LIST_KONTRAHENCI
+	var filterFields = fieldNameList.filter(function (fieldName) {
+		if (!frm[fieldName] && DBG) console.log('Err missing field: "' + fieldName + '"')
+		return (frm[fieldName]) ? true : false
+	}).map(function (fieldName) {
+		return [fieldName, frm[fieldName].value]
+	}).filter(function (filter) {
+		return (filter[1].length > 0)
+	}).map(function (filter) {
+		return '' + filter[0] + '=' + filter[1]
+	}).join('&')
+	return {
+		page: page,
+		filterIdGroup: filterIdGroup,
+		filterFields: (filterFields.length > 0) ? filterFields : null,
+	};
+}
+function getUrlFetchKontrahenci(page) {
+	// return URL_FETCH_PRACOWNICY + '&page=' + page + '&filterIdGroup=' + filterIdGroup + filterFields;
+	var searchParams = getSearchParamsKontrahenci(page);
+	return [
+		URL_FETCH_KONTRAHENCI,
+		'page=' + searchParams.page,
+		'filterIdGroup=' + searchParams.filterIdGroup,
+		searchParams.filterFields,
+	].filter(Boolean).join('&');
+}
 
 function urlFetchKontrahenci(page) {
 	hideMoreRecordFunctionsPopover()
@@ -1683,68 +1718,84 @@ function urlFetchKontrahenci(page) {
 				})
 }
 
+function getSearchParamsPracownicy(page) {
+	var filterIdGroup = getItemLocalStorage('Bocian.biAuditForm.pracownicy.filterIdGroup');
+	var frm = document.getElementById('filtersFieldRemoveBtn-PRACOWNICY').form
+	var fieldNameList = FIELD_LIST_PRACOWNICY
+	var filterFields = fieldNameList.filter(function (fieldName) {
+		if (!frm[fieldName] && DBG) console.log('Err missing field: "' + fieldName + '"')
+		return (frm[fieldName]) ? true : false
+	}).map(function (fieldName) {
+		return [fieldName, frm[fieldName].value]
+	}).filter(function (filter) {
+		return (filter[1].length > 0)
+	}).map(function (filter) {
+		return '' + filter[0] + '=' + filter[1]
+	}).join('&')
+	return {
+		page: page,
+		filterIdGroup: filterIdGroup,
+		filterFields: (filterFields.length > 0) ? filterFields : null,
+	};
+}
+function getUrlFetchPracownicy(page) {
+	// return URL_FETCH_PRACOWNICY + '&page=' + page + '&filterIdGroup=' + filterIdGroup + filterFields;
+	var searchParams = getSearchParamsPracownicy(page);
+	return [
+		URL_FETCH_PRACOWNICY,
+		'page=' + searchParams.page,
+		'filterIdGroup=' + searchParams.filterIdGroup,
+		searchParams.filterFields,
+	].filter(Boolean).join('&');
+}
+
 function urlFetchPracownicy(page) {
 	hideMoreRecordFunctionsPopover()
-		var page = page || getItemLocalStorage('Bocian.biAuditForm.pracownicy.pagination.page');
+	var page = page || getItemLocalStorage('Bocian.biAuditForm.pracownicy.pagination.page');
 
-		if ( page === 1) {
-			setItemLocalStorage('Bocian.biAuditForm.pracownicy.pagination.page', 1);
-		}
-
-			var filterIdGroup = getItemLocalStorage('Bocian.biAuditForm.pracownicy.filterIdGroup');
-
-			selectPage('PRACOWNICY', page);
-
-			var frm = document.getElementById('filtersFieldRemoveBtn-PRACOWNICY').form
-			var fieldNameList = FIELD_LIST_PRACOWNICY
-			var filterFields = fieldNameList.filter(function (fieldName) {
-				if (!frm[fieldName] && DBG) console.log('Err missing field: "'+fieldName+'"')
-				return (frm[fieldName]) ? true : false
-			}).map(function (fieldName) {
-				return [ fieldName, frm[fieldName].value ]
-			}).filter(function (filter) {
-				return ( filter[1].length > 0 )
-			}).map(function (filter) {
-				return '' + filter[0] + '=' + filter[1]
-			}).join('&')
-			filterFields = (filterFields.length > 0) ? '&' + filterFields : ''
+	if ( page === 1) {
+		setItemLocalStorage('Bocian.biAuditForm.pracownicy.pagination.page', 1);
+	}
+	var filterIdGroup = getItemLocalStorage('Bocian.biAuditForm.pracownicy.filterIdGroup');
+	selectPage('PRACOWNICY', page);
+	// var paginationLimit = 20;
+	/*p5WFS_GetFeature('default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY',
+		Object.assign({
+			sortBy: 'ID+D',
+			maxFeatures: paginationLimit,
+			startIndex: (page - 1) * paginationLimit,
+			// TODO: backRefNS, backRefPK, backRefField - TODO: from groups
+			// resolve: 'all',
+			// resolveDepth: 2
+			'ogc:Filter': '<wfs:Query>' + '\n' + [
+				'*',
+				'default_db__x3A__BI_audit_ENERGA_PRACOWNICY_adresy:BI_audit_ENERGA_PRACOWNICY_adresy/*',
+				[
+					'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object',
+					'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row',
+					'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object',
+					'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI:BI_audit_ENERGA_RUM_KONTRAHENCI'
+				].join('/')
+			].map(function (fieldName) {
+				return '<wfs:PropertyName>' + fieldName + '</wfs:PropertyName>';
+			}).join('\n') + '\n' + '</wfs:Query>'
+		}, (filterIdGroup > 0)
+			? {
+					backRefNS: 'default_db/BI_audit_ENERGA_PRACOWNICY_group/BI_audit_ENERGA_PRACOWNICY_group',
+					backRefPK: filterIdGroup,
+					backRefField: 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY',
+				}
+			: {}
+		)
+	).then(function (items) {
+		if(DBG)console.log('p5WFS_GetFeature: items: ', items);
+	}).catch(function (err) {
+		if(DBG)console.log('p5WFS_GetFeature: err: ', err);
+	})*/
 
-			var paginationLimit = 20;
-			/*p5WFS_GetFeature('default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY',
-				Object.assign({
-					sortBy: 'ID+D',
-					maxFeatures: paginationLimit,
-					startIndex: (page - 1) * paginationLimit,
-					// TODO: backRefNS, backRefPK, backRefField - TODO: from groups
-					// resolve: 'all',
-					// resolveDepth: 2
-					'ogc:Filter': '<wfs:Query>' + '\n' + [
-						'*',
-						'default_db__x3A__BI_audit_ENERGA_PRACOWNICY_adresy:BI_audit_ENERGA_PRACOWNICY_adresy/*',
-						[
-							'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object',
-							'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row',
-							'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object',
-							'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI:BI_audit_ENERGA_RUM_KONTRAHENCI'
-						].join('/')
-					].map(function (fieldName) {
-						return '<wfs:PropertyName>' + fieldName + '</wfs:PropertyName>';
-					}).join('\n') + '\n' + '</wfs:Query>'
-				}, (filterIdGroup > 0)
-					? {
-							backRefNS: 'default_db/BI_audit_ENERGA_PRACOWNICY_group/BI_audit_ENERGA_PRACOWNICY_group',
-							backRefPK: filterIdGroup,
-							backRefField: 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY',
-						}
-					: {}
-				)
-			).then(function (items) {
-				if(DBG)console.log('p5WFS_GetFeature: items: ', items);
-			}).catch(function (err) {
-				if(DBG)console.log('p5WFS_GetFeature: err: ', err);
-			})*/
-
-			fetch(URL_FETCH_PRACOWNICY + '&page=' + page + '&filterIdGroup=' + filterIdGroup + filterFields, {
+	var fetchUrl = getUrlFetchPracownicy(page);
+	DBG && console.log('DBG: fetch ', { fetchUrl });
+			fetch(fetchUrl, {
 				credentials: 'same-origin'
 			})
 			.then(function parseJSON(response) {
@@ -2271,6 +2322,356 @@ function updateTopCounters() {
 }
 
 
+var P5UI__Bocian__ExportFieldSelectOverlay = createReactClass({
+	handleChange: function (fieldName) {
+		DBG && console.log('DBG:P5UI__Bocian__ExportFieldSelectOverlay:handleChange', { fieldName })
+		this.props.handleToggle(fieldName);
+	},
+	setRef: function (reactComponent) {
+		this._rootNode = reactComponent;
+	},
+	componentWillMount: function () { // TODO: mv to div at the end of body, then position div by event.target.offsetTop / offsetLeft
+		this._closeDropdownIfClickedOutside = function (event) {
+			if (DBG) console.log("P5UI__Bocian__ExportFieldSelectOverlay::_closeDropdownIfClickedOutside idHtmlPopover:", { 'this__rootNode': this._rootNode })
+			if (!this._rootNode) return;
+
+			var isClickedOutside = p5UI__clickedOutsideElement(this._rootNode, event)
+			if (isClickedOutside) {
+				this._unbindCloseDropdownIfClickedOutside();
+				this.props.handleClose();
+			}
+		}.bind(this);
+		this._bindCloseDropdownIfClickedOutside = function () {
+			if (DBG) console.log("P5UI__Bocian__ExportFieldSelectOverlay::_bindCloseDropdownIfClickedOutside", this._closeDropdownIfClickedOutside)
+			if (!document.addEventListener && document.attachEvent) {
+				document.attachEvent('onclick', this._closeDropdownIfClickedOutside);
+			} else {
+				document.addEventListener('click', this._closeDropdownIfClickedOutside);
+			}
+		}.bind(this);
+		this._unbindCloseDropdownIfClickedOutside = function () {
+			if (DBG) console.log("P5UI__Bocian__ExportFieldSelectOverlay::_unbindCloseDropdownIfClickedOutside", this._closeDropdownIfClickedOutside)
+			if (!document.removeEventListener && document.detachEvent) {
+				document.detachEvent('onclick', this._closeDropdownIfClickedOutside);
+			} else {
+				document.removeEventListener('click', this._closeDropdownIfClickedOutside);
+			}
+		}.bind(this);
+	},
+	componentDidMount: function () {
+		this._bindCloseDropdownIfClickedOutside();
+	},
+	renderExportField: function (field) {
+		// <li><input checked="" type="checkbox" title="ID" value="ID">&nbsp;Nr</li>
+		var self = this;
+		var fieldName = field.name;
+		var label = field.label;
+		var isChecked = this.props.exportFieldsStore.state.selected.has(fieldName);
+		return h('li', {}, [
+			h('label', { style: { 'font-size': "small", 'font-weight': "normal", 'margin-bottom': "0" } }, [
+				h('input', {
+					checked: isChecked,
+					type: "checkbox",
+					title: fieldName,
+					value: fieldName,
+					onChange: function () {
+						self.handleChange(fieldName);
+					}
+				}),
+				" ",
+				label.replace(/_/g, ' ')
+			])
+		]);
+	},
+
+	handleExportToHTML: function (event) {
+		event.preventDefault();
+		var selected = this.props.exportFieldsStore.state.selected;
+		DBG && console.log('DBG:P5UI__Bocian__ExportFieldSelectOverlay:handleExportToHTML', { selected: selected, props: this.props })
+		var format = 'html';
+		var exportUrl = [ 'index.php?_route=ViewTableAjax&_task=export&namespace=' + this.props.namespace,
+			'format=' + format,
+			'flds=' + Array.from(selected).join(','),
+			'sortCol=' + (this.props.sortCol || ''),
+			'sortDir=' + (this.props.sortDir ? "desc" : "asc"),
+			this.props.queryFilter
+		].join('&');
+		var win = window.open(exportUrl, '_blank');
+		win.focus();
+	},
+	handleExportToCSV: function (event) {
+		event.preventDefault();
+		var selected = this.props.exportFieldsStore.state.selected;
+		DBG && console.log('DBG:P5UI__Bocian__ExportFieldSelectOverlay:handleExportToCSV', { selected: selected })
+		var format = 'csv';
+		var exportUrl = [ 'index.php?_route=ViewTableAjax&_task=export&namespace=' + this.props.namespace,
+			'format=' + format,
+			'flds=' + Array.from(selected).join(','),
+			'sortCol=' + (this.props.sortCol || ''),
+			'sortDir=' + (this.props.sortDir ? "desc" : "asc"),
+			this.props.queryFilter
+		].join('&');
+		var win = window.open(exportUrl, '_blank');
+		win.focus();
+	},
+	handleExportToLatin2CSV: function (event) {
+		event.preventDefault();
+		var selected = this.props.exportFieldsStore.state.selected;
+		DBG && console.log('DBG:P5UI__Bocian__ExportFieldSelectOverlay:handleExportToLatin2CSV', { selected: selected })
+		var format = 'csv_cp1250';
+		var exportUrl = [ 'index.php?_route=ViewTableAjax&_task=export&namespace=' + this.props.namespace,
+			'format=' + format,
+			'flds=' + Array.from(selected).join(','),
+			'sortCol=' + (this.props.sortCol || ''),
+			'sortDir=' + (this.props.sortDir ? "desc" : "asc"),
+			this.props.queryFilter
+		].join('&');
+		var win = window.open(exportUrl, '_blank');
+		win.focus();
+	},
+	// 	if (!exportFields.length) {
+	// 		alert('Nie wybrano żadnych pól do eksportu.');
+	// 		e.preventDefault();
+	// 		return false;
+	// 	}
+
+	// 	var limit = 10000;
+	// 	if (!_data.total || _data.total <= 0) {
+	// 		alert('Brak rekordów do eksportu.');
+	// 		e.preventDefault();
+	// 		return false;
+	// 	}
+	// 	if (_data.total > limit) {
+	// 		if (!confirm('Za dużo rekordów. Wyeksportowane zostaną tylko pierwsze ' + limit + ' z ' + _data.total + ' rekordów.')) {
+	// 			e.preventDefault();
+	// 			return false;
+	// 		}
+	// 	}
+
+	renderExportToHTML: function () {
+		return h('li', {}, [
+			h('a', { href: "#", onClick: this.handleExportToHTML, style: { 'font-size': "small", 'font-weight': "normal", 'margin-bottom': "0" } }, [
+				h('i', { className: "glyphicon glyphicon-share" }),
+				" Export do HTML"
+			])
+		]);
+	},
+	renderExportToCSV: function () {
+		return h('li', {}, [
+			h('a', { href: "#", onClick: this.handleExportToCSV, style: { 'font-size': "small", 'font-weight': "normal", 'margin-bottom': "0" } }, [
+				h('i', { className: "glyphicon glyphicon-share" }),
+				" Export do CSV"
+			])
+		]);
+	},
+	renderExportToLatin2CSV: function () {
+		return h('li', {}, [
+			h('a', {
+				href: "#", onClick: this.handleExportToLatin2CSV,
+				style: { 'font-size': "small", 'font-weight': "normal", 'margin-bottom': "0" },
+				title: "Export do pliku CSV w kodowaniu Windows-1250",
+			}, [
+				h('i', { className: "glyphicon glyphicon-share" }),
+				" Export do CSV (Windows-1250)"
+			])
+		]);
+	},
+
+	render: function () {
+		if (!this.props.exportFields) console.warn('DBG: missing this.props.exportFields', { 'this.props': this.props });
+		if (!this.props.exportFields) return null;
+		return h('ul', {
+			ref: this.setRef,
+			className: "dropdown-menu",
+			style: {
+				height: "250px",
+				'min-width': "300px",
+				'padding': "5px 20px 5px 8px",
+				overflow: "auto",
+				display: "block",
+				position: "absolute",
+				left: this.props.offsetLeft,
+				top: this.props.offsetTop - 250,
+				margin: 0,
+				// height: 250px;
+				// this.props.btnBBox
+			},
+		}, this.props.exportFields.map(this.renderExportField).concat([
+			this.renderExportToHTML(),
+			this.renderExportToCSV(),
+			this.renderExportToLatin2CSV(),
+		]));
+	}
+});
+
+var _Containers__ExportFields = {}; // namespace => Unstated Container
+var _Containers__get = function (namespace, initialSelected) {
+	if (_Containers__ExportFields[namespace]) return _Containers__ExportFields[namespace];
+	var selected = new Set();
+	if (initialSelected) initialSelected.forEach(function (field) {
+		selected.add(field.name);
+	})
+	_Containers__ExportFields[namespace] = global.p5VendorJs.createUnstatedContainer({
+		state: {
+			namespace: namespace,
+			selected: selected,
+		},
+		toggleField(fieldName) {
+			var selected = this.state.selected;
+			selected.has(fieldName) ? selected.delete(fieldName) : selected.add(fieldName)
+			this.setState({ selected: selected });
+		},
+		selectField(fieldName) {
+			var selected = this.state.selected;
+			selected.add(fieldName)
+			this.setState({ selected: selected });
+		},
+		unselectField(fieldName) {
+			var selected = this.state.selected;
+			selected.delete(fieldName)
+			this.setState({ selected: selected });
+		},
+
+	});
+	// namespace = 'default_db/BI_audit_ENERGA_PRACOWNICY/BI_audit_ENERGA_PRACOWNICY';
+	// namespace = 'default_db/BI_audit_ENERGA_RUM_KONTRAHENCI/BI_audit_ENERGA_RUM_KONTRAHENCI';
+	return _Containers__ExportFields[namespace];
+}
+
+var P5UI__Bocian__ExportTable = createReactClass({ // @props: { namespace, exportFields }
+	_node: null,
+	getInitialState: function () {
+		return {
+			isOpen: false,
+		};
+	},
+	handleToggleDropdown: function (event) {
+		var offsetLeft = 0;
+		var offsetTop = 0;
+		DBG && console.log('DBG:P5UI__Bocian__ExportTable:handleToggleDropdown', {
+			event,
+			target: event.target,
+			targetBox: event.target.getBoundingClientRect(),
+			'top': event.target.offsetTop, 'left': event.target.offsetLeft,
+			'this___node__type': (this._node) ? this._node.nodeType : null,
+		});
+
+		this.removePopup();
+		if (!this.state.isOpen) {
+			var btnBBox = ("BUTTON" !== event.target.nodeName) ? event.target.parentNode.getBoundingClientRect() : event.target.getBoundingClientRect();
+			offsetLeft = btnBBox.left;
+			offsetTop = window.pageYOffset + btnBBox.y;
+			this._node = document.createElement('div');
+			this._node.setAttribute('data-p5class', "P5UI__Bocian__ExportTable");
+			this._node.position = "absolute";
+			this._node.left = "0";
+			this._node.top = "0";
+			this._node.height = "100%";
+			this._node.backgroundColor = "#00000050";
+			this._node.width = "100%";
+			var handleClose = this.handleClose.bind(this);
+			var exportFields = this.props.exportFields;
+			var exportFieldsContainer = _Containers__get(this.props.namespace, this.props.exportFields);
+
+			document.body.appendChild(this._node);
+
+			var self__props = this.props;
+			ReactDOM.render(
+				h(Unstated.Provider, {}, [
+					h(Unstated.Subscribe, { to: [ exportFieldsContainer ] },
+						function (exportFieldsCont) {
+							console.log('DBG:exportFieldsCont', { exportFieldsCont })
+							return h(P5UI__Bocian__ExportFieldSelectOverlay, Object.assign({}, self__props, {
+								exportFields: exportFields,
+								btnBBox: btnBBox,
+								exportFieldsStore: exportFieldsCont,
+								handleToggle: exportFieldsCont.toggleField.bind(exportFieldsCont),
+								handleClose: handleClose,
+								offsetLeft: offsetLeft,
+								offsetTop: offsetTop,
+							}));
+						}
+					)
+				]),
+				this._node
+			);
+		}
+		this.setState({ isOpen: !this.state.isOpen });
+	},
+	removePopup: function () {
+		if (this._node && 1 === this._node.nodeType) {
+			document.body.removeChild(this._node);
+		}
+		this._node = null;
+	},
+	handleClose: function () {
+		this.removePopup();
+		this.setState({ isOpen: false });
+	},
+	render: function () {
+		// Pagination.code += '<div class="btn-group dropup pagesize" style="margin-left:40px">' +
+		// <button class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#">Export&nbsp;<span class="caret"></span></button>
+		// <ul class="dropdown-menu" style="max-height:250px;padding:5px 20px 5px 8px;overflow:auto;">
+		//   <li><input checked="" type="checkbox" title="ID" value="ID">&nbsp;Nr</li>
+		//   <li><input checked="" type="checkbox" title="A_STATUS" value="A_STATUS">&nbsp;Status</li>
+		//   ...
+		//   <li><input checked="" type="checkbox" title="TV_DVBC_EPG_CHANNEL_NUMBER" value="TV_DVBC_EPG_CHANNEL_NUMBER">&nbsp;TV: Nr kanału w EPG</li>
+		//   <li><a href="index.php" target="_blank" class=""><i class="glyphicon glyphicon-share"></i>Export do HTML</a></li>
+		//   <li><a href="index.php" target="_blank" class=""><i class="glyphicon glyphicon-share"></i>Export do CSV</a></li>
+		//   <li><a href="index.php" target="_blank" class=""><i class="glyphicon glyphicon-share" title="Export do pliku CSV w kodowaniu Windows-1250"></i>Export do CSV (Windows-1250)</a></li>
+		// </ul></div>';
+		return h('div', {
+			className: "btn-group", // className: "btn-group dropup pagesize" + " open",
+		}, [
+			h('button', {
+				className: "btn btn-sm btn-default", // className: "btn btn-sm btn-default dropdown-toggle", // 'data-toggle': "dropdown",
+				onClick: this.handleToggleDropdown
+			}, [
+				"Export ",
+				h('span', { className: "caret" }),
+			]),
+			// h('ul', {
+			// 	className: "dropdown-menu",
+			// 	style: {
+			// 		'max-height': "250px",
+			// 		'min-width': "300px",
+			// 		'padding': "5px 20px 5px 8px",
+			// 		overflow: "auto",
+			// 	}
+			// }, this.props.exportFields.map(this.renderExportField))
+		]);
+
+		// @from TableAjax:
+		// if (priv.options.exportFields && priv.options.exportFields.length) {
+		// 	node = $('<div class="btn-group dropup pagesize ' + nodeClass + '"></div>');
+		// 	var btn = $('<button class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#">Export&nbsp;</button>').appendTo(node);
+		// 	var span = $('<span class="caret"></span>').appendTo(btn);
+		// 	var ul = $('<ul class="dropdown-menu" style="max-height:250px;padding:5px 20px 5px 8px;overflow:auto;">').appendTo(node);
+
+		// 	$.each(_data.cols, function (col, props) {
+		// 		if (-1 !== priv.options.exportFields.indexOf(col)) {
+		// 			var li = $('<li></li>').appendTo(ul);
+		// 			$(p5Utils__format('<input {0} type="checkbox" title="{1}" value="{1}" >&nbsp;{2}</input>', [(_exportFieldsSelect[col]) ? 'checked' : '', col, props.friendly || col])).appendTo(li);
+		// 			li.on('click', 'input', priv.exportFieldChanged);
+		// 		}
+		// 	});
+
+		// 	var li = $('<li></li>').appendTo(ul);
+		// 	$('<a href="index.php" target="_blank" class=""><i class="glyphicon glyphicon-share"></i>Export do HTML</a>').appendTo(li);
+		// 	li.on('click', 'a', priv.exportToHTML);
+		// 	var li = $('<li></li>').appendTo(ul);
+		// 	$('<a href="index.php" target="_blank" class=""><i class="glyphicon glyphicon-share"></i>Export do CSV</a>').appendTo(li);
+		// 	li.on('click', 'a', priv.exportToCSV);
+		// 	var li = $('<li></li>').appendTo(ul);
+		// 	$('<a href="index.php" target="_blank" class=""><i class="glyphicon glyphicon-share" title="Export do pliku CSV w kodowaniu Windows-1250"></i>Export do CSV (Windows-1250)</a>').appendTo(li);
+		// 	li.on('click', 'a', priv.exportToCSVWinCP1250);
+		// } else {
+		// 	node = $('<span class="' + nodeClass + '"></span>');
+		// }
+	}
+});
+
+
 // Pagination
 var Pagination = {
 
@@ -2328,46 +2729,46 @@ var Pagination = {
 
     // change page
     Click: function() {
-			clearSelectedCheckbox();
+		clearSelectedCheckbox();
 
-			var selectPage = $("#pagination-"+Pagination.type.toLowerCase()+' .tblAjax__footer__toolbar__pagination').find('a.active').text();
-			Pagination.clickPage = +this.innerHTML || '';
-			if ( selectPage === NaN || selectPage > Pagination.size) { selectPage = 1; }
+		var selectPage = $("#pagination-"+Pagination.type.toLowerCase()+' .tblAjax__footer__toolbar__pagination').find('a.active').text();
+		Pagination.clickPage = +this.innerHTML || '';
+		if ( selectPage === NaN || selectPage > Pagination.size) { selectPage = 1; }
 
-			switch (this.innerHTML) {
-				case '&gt;&gt;': // last
-					Pagination.clickPage = Pagination.size;
-					break;
+		switch (this.innerHTML) {
+			case '&gt;&gt;': // last
+				Pagination.clickPage = Pagination.size;
+				break;
 
-				case '&lt;&lt;': // first
-					Pagination.clickPage = 1;
-					break;
+			case '&lt;&lt;': // first
+				Pagination.clickPage = 1;
+				break;
 
-				case '&lt;': // prev
-					Pagination.clickPage = parseInt(selectPage) - 1;
-					if (Pagination.clickPage < 1) {
-							Pagination.clickPage = 1;
-					}
+			case '&lt;': // prev
+				Pagination.clickPage = parseInt(selectPage) - 1;
+				if (Pagination.clickPage < 1) {
+						Pagination.clickPage = 1;
+				}
 
-					break;
+				break;
 
-				case '&gt;': // next
-					Pagination.clickPage = parseInt(selectPage) + 1;
+			case '&gt;': // next
+				Pagination.clickPage = parseInt(selectPage) + 1;
 
-					if (Pagination.clickPage > Pagination.size) {
-							Pagination.clickPage = Pagination.size;
-					}
-					break;
-			}
+				if (Pagination.clickPage > Pagination.size) {
+						Pagination.clickPage = Pagination.size;
+				}
+				break;
+		}
 
-			if ( Pagination.type === 'KONTRAHENCI' ) {
-				setItemLocalStorage('Bocian.biAuditForm.kontrahenci.pagination.page', Pagination.clickPage);
-				Pagination.page = urlFetchKontrahenci(Pagination.clickPage);
-			}
-			else if ( Pagination.type === 'PRACOWNICY' ){
-				setItemLocalStorage('Bocian.biAuditForm.pracownicy.pagination.page', Pagination.clickPage);
-				Pagination.page = urlFetchPracownicy(Pagination.clickPage);
-			}
+		if ( Pagination.type === 'KONTRAHENCI' ) {
+			setItemLocalStorage('Bocian.biAuditForm.kontrahenci.pagination.page', Pagination.clickPage);
+			Pagination.page = urlFetchKontrahenci(Pagination.clickPage);
+		}
+		else if ( Pagination.type === 'PRACOWNICY' ){
+			setItemLocalStorage('Bocian.biAuditForm.pracownicy.pagination.page', Pagination.clickPage);
+			Pagination.page = urlFetchPracownicy(Pagination.clickPage);
+		}
 
         Pagination.Start();
     },
@@ -2380,44 +2781,99 @@ var Pagination = {
     // binding pages
     Bind: function() {
         var a = Pagination.e.getElementsByTagName('a');
-				var currentPage = Pagination.clickPage || 1;
+		// var currentPage = Pagination.clickPage || 1;
         for (var i = 0; i < a.length; i++) {
             if (+a[i].innerHTML === Pagination.page) a[i].className = 'btn btn-default active';
             a[i].addEventListener('click', Pagination.Click, false);
         }
     },
 
-    // write pagination
-    Finish: function() {
+	ExportWidget: function() {
+		var exportWidgetId = 'p5__exportWidget__' + Pagination.type;
+		Pagination.code += '<div id="' + exportWidgetId + '" class="btn-group dropup pagesize" style="margin-left:40px"></div>';
+	},
+	getSearchQueryFilter: function () { // @return url query filter by namespace
+		switch (Pagination.type) {
+			case 'PRACOWNICY': {
+				var searchParams = getSearchParamsPracownicy();
+				return [
+					searchParams.filterFields,
+					(searchParams.filterIdGroup) ? 'filterIdGroup=' + searchParams.filterIdGroup : null, // TODO: backRef search
+				].filter(Boolean).join('&')
+			}
+			case 'KONTRAHENCI': {
+				var searchParams = getSearchParamsKontrahenci();
+				return [
+					searchParams.filterFields,
+					(searchParams.filterIdGroup) ? 'filterIdGroup=' + searchParams.filterIdGroup : null, // TODO: backRef search
+				].filter(Boolean).join('&')
+			}
+			default: return '';
+		}
+	},
+	CreateExportWidget: function() {
+		var exportFields = null;
+		var namespace = '';
+		if (Pagination.type === 'PRACOWNICY') {
+			exportFields = EXPORT_FIELDS_OD;
+			namespace = 'default_db/BI_audit_ENERGA_PRACOWNICY/BI_audit_ENERGA_PRACOWNICY';
+		} else if (Pagination.type === 'KONTRAHENCI') {
+			exportFields = EXPORT_FIELDS_DO;
+			namespace = 'default_db/BI_audit_ENERGA_RUM_KONTRAHENCI/BI_audit_ENERGA_RUM_KONTRAHENCI';
+		}
+		DBG && console.log('DBG:EXPORT_FIELDS...', { EXPORT_FIELDS_OD, EXPORT_FIELDS_DO, exportFields });
+		if (!exportFields || (exportFields && !exportFields.length)) return;
+
+		var exportWidgetId = 'p5__exportWidget__' + Pagination.type;
+		var node = document.getElementById(exportWidgetId);
+		DBG && console.log('node: ', { node });
+		if (!node) return;
+
+		var sortCol = 'ID';
+		var sortDir = 'desc';
+		var queryFilter = Pagination.getSearchQueryFilter();
+		ReactDOM.render(
+			h(P5UI__Bocian__ExportTable, {
+				namespace: namespace,
+				exportFields: exportFields,
+				sortCol: sortCol,
+				sortDir: sortDir,
+				queryFilter: queryFilter,
+			}),
+			node
+		);
+	},
+
+
+	Finish: function() {
         Pagination.e.innerHTML = Pagination.code;
-        Pagination.code = '</ul></nav>';
         Pagination.Bind();
+        Pagination.CreateExportWidget();
     },
 
 
     // find pagination type
     Start: function() {
-			Pagination.code = '';
-			if ( Pagination.type === 'KONTRAHENCI' ) {
-				Pagination.code = '<div class="foot-info tblAjax__footer__toolbar__info footer_pagination_menu_items"><p>Wiersze od <span id="paginationShowNextCount-KONTRAHENCI"></span> do ' + Pagination.total_items + ' z ' + Pagination.total_items + '</p></div>';
-			} else if ( Pagination.type === 'PRACOWNICY' ) {
-					Pagination.code = '<div class="foot-info tblAjax__footer__toolbar__info footer_pagination_menu_items"><p>Wiersze od <span id="paginationShowNextCount-PRACOWNICY"></span> do ' + Pagination.total_items + ' z ' + Pagination.total_items + '</p></div>';
-			}
-			Pagination.code += '<nav aria-label="Page navigation" class="footer_pagination_menu_items"><ul class="btn-group tblAjax__footer__toolbar__pagination smad-pagination">';
-			Pagination.First();
-			Pagination.Prev();
-
+		Pagination.code = '';
+		if ( Pagination.type === 'KONTRAHENCI' ) {
+			Pagination.code += '<div class="foot-info tblAjax__footer__toolbar__info footer_pagination_menu_items"><p>Wiersze od <span id="paginationShowNextCount-KONTRAHENCI"></span> do ' + Pagination.total_items + ' z ' + Pagination.total_items + '</p></div>';
+		} else if ( Pagination.type === 'PRACOWNICY' ) {
+			Pagination.code += '<div class="foot-info tblAjax__footer__toolbar__info footer_pagination_menu_items"><p>Wiersze od <span id="paginationShowNextCount-PRACOWNICY"></span> do ' + Pagination.total_items + ' z ' + Pagination.total_items + '</p></div>';
+		}
+		Pagination.code += '<nav aria-label="Page navigation" class="footer_pagination_menu_items"><ul class="btn-group tblAjax__footer__toolbar__pagination smad-pagination" style="margin-bottom:0">';
+		Pagination.First();
+		Pagination.Prev();
 
-				if ( Pagination.type === 'KONTRAHENCI' ) {
-					Pagination.page = getItemLocalStorage('Bocian.biAuditForm.kontrahenci.pagination.page') || 1;
-				}
-				else if ( Pagination.type === 'PRACOWNICY' ) {
-					Pagination.page = getItemLocalStorage('Bocian.biAuditForm.pracownicy.pagination.page') || 1;
-				}
+		if ( Pagination.type === 'KONTRAHENCI' ) {
+			Pagination.page = getItemLocalStorage('Bocian.biAuditForm.kontrahenci.pagination.page') || 1;
+		}
+		else if ( Pagination.type === 'PRACOWNICY' ) {
+			Pagination.page = getItemLocalStorage('Bocian.biAuditForm.pracownicy.pagination.page') || 1;
+		}
 
-				if ( Pagination.page > Pagination.size ) {
-						Pagination.page = 1;
-				}
+		if ( Pagination.page > Pagination.size ) {
+			Pagination.page = 1;
+		}
 
         if (Pagination.size < Pagination.step * 2 + 6) {
             Pagination.Add(1, Pagination.size + 1);
@@ -2431,8 +2887,10 @@ var Pagination = {
         else {
             Pagination.Add(Pagination.page - Pagination.step, Pagination.page + Pagination.step + 1);
         }
-				Pagination.Next();
-				Pagination.Last();
+		Pagination.Next();
+		Pagination.Last();
+		Pagination.code += '</ul></nav>';
+		Pagination.ExportWidget();
         Pagination.Finish();
     },
 
@@ -2447,21 +2905,21 @@ var Pagination = {
     },
 
     // create skeleton
-    Create: function(e) {
+    Create: function(element) {
 
         var html = [
              '<div></div>'  // pagination container
         ];
 
-        e.innerHTML = html.join('');
-        Pagination.e = e.getElementsByTagName('div')[0];
-        Pagination.Buttons(e);
+		element.innerHTML = html.join('');
+		Pagination.e = element.getElementsByTagName('div')[0];
+		Pagination.Buttons(element);
     },
 
     // init
-    Init: function(e, data) {
-        Pagination.Extend(data);
-        Pagination.Create(e);
+    Init: function(element, options) {
+        Pagination.Extend(options);
+        Pagination.Create(element);
         Pagination.Start();
     }
 };