Piotr Labudda пре 8 година
родитељ
комит
8add0af4f0

+ 1 - 1
SE/se-lib/Core/AclBase.php

@@ -899,7 +899,7 @@ if($DBG){die();}
 		// }
 		// return $longLabel;
 	}
-	public function getLongLabel($posLimit = 30) { // TODO: legacy
+	public function getLongLabel($posLimit = 30) { // TODO: RMME, legacy
     	return $this->getNamespace();
 		// $longLabel = $this->getRawLabel($posLimit);
 		// $opis = $this->_opis;

+ 5 - 54
SE/se-lib/ProcesMenu.php

@@ -314,7 +314,7 @@ jQuery(document).ready(function() {
 		$outUrls = array();
 		$outMenus = array();// typeName => label (order by label)
 		$typeNameToIdZasob = array();// $typeName => $idZasob
-		if ($userAcl->getPermsFiltrProcesId()) {
+		if ($userAcl->getPermsFiltrProcesId()) { // TODO: fetch menu from ajax - fix menuStore
 			$tbls = $userAcl->getTablesAcl();
 			$urls = $userAcl->getUrls();
 
@@ -334,7 +334,7 @@ jQuery(document).ready(function() {
 					if (null == $vTblAcl) continue;
 					$tblName = $vTblAcl->getName();
 					$typeName = "p5_default_db:{$tblName}";
-					$labelsOutMenus[$typeName] = $vTblAcl->getLongLabel();
+					$labelsOutMenus[$typeName] = $vTblAcl->getLongLabel(); // TODO: legacy
 					$rawOutMenus[$typeName] = strtolower($vTblAcl->getLongRawLabel());
 					$typeNameToIdZasob[$typeName] = $kZasobID;
 					// if ($userAcl->getPermsFiltrProcesId()) {
@@ -927,8 +927,6 @@ jQuery(document).ready(function() {
 	</nav>
 	<?php
 
-		UI::inlineJS(APP_PATH_WWW . '/static/p5UI/menuStore.js');
-
 		$idFiltrProcesID = $userAcl->getPermsFiltrProcesId();
 		if ($idFiltrProcesID > 0) {
 			echo UI::h('div', [ 'id' => "SE-menu-sub", 'style' => "clear:both;" ], array_merge(
@@ -988,49 +986,8 @@ jQuery(document).ready(function() {
 			})(window)
 		");
 
-		echo UI::h('script', [], "
-			(function (global) {
-				if (!global.p5UI__MenuStore) throw 'Missing global.p5UI__MenuStore'
-
-				function initP5MainMenuDropdown( btnNode, idSubMenu ) {
-					if (!btnNode._initialized) {
-						var jqDropdownTrigger = jQuery(btnNode)
-						var jqDropdownMenu = jQuery('#' + idSubMenu)
-						var jqDropdownParent = jqDropdownMenu.parent()
-
-						global.p5UI__MenuStore.subscribe(
-							(function (global, idSubMenu) {
-								return function renderP5MainMenuDropdown(data) {
-									var jqDropdownMenu = jQuery('#' + idSubMenu)
-									jqDropdownMenu.empty()
-									jqDropdownMenu.append(data.objects.map(function (item) {
-										var star = (-1 !== data.idsBookmarks.indexOf(item.id))
-											? '<i class=\"bookmark-item-rem glyphicon glyphicon-star\" title=\"Usuń z ulubionych\" onClick=\"return p5BookmarksRemove(event, ' + item.id + ')\"></i>'
-											: '<i class=\"bookmark-item-add glyphicon glyphicon-star-empty\" title=\"Dodaj do ulubionych\" onClick=\"return p5BookmarksAdd(event, ' + item.id + ')\"></i>'
-										return jQuery('<li>' +
-											'<a href=\"index.php?_route=ViewTableAjax&namespace=' + item.namespace + '\">' +
-												star +
-												' ' + item.label +
-											'</a>' +
-										'</li>');
-									}))
-								}
-							})(global, idSubMenu)
-						)
-
-						jqDropdownTrigger.attr('data-toggle', 'dropdown') // is required by bootstrap dorpdown.js evenf if is called via js
-
-						global.p5UI__MenuStore.forceUpdate()
-
-						jQuery(btnNode).dropdown()
-					}
-					btnNode._initialized = true
-					return true;
-				}
-
-				global.initP5MainMenuDropdown = initP5MainMenuDropdown
-			})(window)
-		");
+		UI::inlineCSS(APP_PATH_WWW . '/static/p5UI/initP5MainMenuDropdown.css');
+		UI::inlineJS(APP_PATH_WWW . '/static/p5UI/initP5MainMenuDropdown.js');
 
 		echo UI::h('script', [], "
 			(function (global) {
@@ -1076,20 +1033,14 @@ jQuery(document).ready(function() {
 			})(window)
 		");
 
-		$args = [
-			'P5MENU_URL' => Router::getRoute('P5Menu')->getLink(),
-		];
 		echo UI::h('script', [], "
 			(function (global) {
 				if (!global.p5UI__MenuStore) throw 'Missing global.p5UI__MenuStore'
-				var P5MENU_URL = '{$args['P5MENU_URL']}'
-
-				global.p5UI__MenuStore.setRemoteUrl(P5MENU_URL)
 
 				if (global.p5UI__MenuStore.hasData()) {
 					global.p5UI__MenuStore.forceUpdate() // force update all subscribers
 				} else {
-					global.p5UI__MenuStore.remoteUpdate() // update from remote url @see setRemoteUrl
+					global.p5UI__MenuStore.remoteUpdate() // update from remote url
 				}
 			})(window)
 		");

+ 34 - 3
SE/se-lib/Route/P5Menu.php

@@ -3,12 +3,37 @@
 Lib::loadClass('RouteBase');
 Lib::loadClass('UserBookmarks');
 Lib::loadClass('Response');
+Lib::loadClass('ProcesHelper');
 
 class Route_P5Menu extends RouteBase {
 
+	public function getVersion() {
+		return 2;
+	}
+
 	public function defaultAction() {
 		Response::sendTryCatchJson(array($this, 'getMenuData'), $args = 'JSON_FROM_REQUEST_BODY');
 	}
+	public function getRawLabel($zasobObj) { // { ID, DESC, DESC_PL, OPIS } // TODO: move to ProcesHelper::getZasobTableInfo ?
+		$posLimit = 20;
+		if (!empty($zasobObj->DESC_PL)) return $zasobObj->DESC_PL;
+		if (empty($zasobObj->OPIS)) return $zasobObj->DESC;
+
+		$opis = $zasobObj->OPIS;
+		$label = $opis;
+		if (mb_strlen($opis) > $posLimit) {
+			$pos = strpos($opis, ' - ');
+			if ($pos > $posLimit || $pos < 5) {
+				$pos = $posLimit;
+				$label = mb_substr($opis, 0, $posLimit, 'utf-8') . '...';
+			} else {
+				$label = mb_substr($opis, 0, $pos, 'utf-8');
+			}
+		}
+		return (empty($label))
+		? $zasobObj->DESC
+		: $label;
+	}
 	public function getMenuData($args = []) {
 		if ($postTask = V::get('_postTask', '', $args)) {
 			DBG::log($args, 'array', "exec '{$postTask}'");
@@ -22,24 +47,30 @@ class Route_P5Menu extends RouteBase {
 		// DBG::log($listUrls, 'array', "\$listUrls");
 
 		$bookmarks = UserBookmarks::getInstance()->getBookmarks();
+		$makeShortLabel = [ $this, 'getRawLabel' ];
 
 		return [
 			'type' => 'success',
 			'msg' => "OK",
 			'body' => [
+				'version' => $this->getVersion(),
 
-				'objects' => array_map(function ($acl, $idZasob) {
+				'objects' => array_map(function ($acl, $idZasob) use ($makeShortLabel) {
 					if (!$acl) return [
 						'id' => $idZasob,
 						'TODO' => 'TODO'
 					];
 
+					$zasobObj = ProcesHelper::getZasobTableInfo($acl->getID());
 					return [
 						'id' => $acl->getID(),
 						'namespace' => $acl->getNamespace(),
 						'name' => $acl->getName(),
-						'label' => $acl->getLongLabel(),
-						'raw_label' => strtolower($acl->getLongRawLabel()),
+						'desc' => $zasobObj->DESC,
+						'label' => ($zasobObj->DESC_PL) ? htmlspecialchars($zasobObj->DESC_PL) : $zasobObj->DESC,
+						'short_label' => $makeShortLabel($zasobObj),
+						'opis' => htmlspecialchars($zasobObj->OPIS),
+						// 'raw_zasob_obj' => $zasobObj,
 					];
 				}, array_values($listObjects), array_keys($listObjects)),
 

+ 2 - 2
SE/se-lib/Route/Users.php

@@ -1006,7 +1006,7 @@ class Route_Users extends RouteBase {
 	public function loginView($data = []) {
 		UI::gora();
 		UI::loadTemplate('login', $data);
-		UI::inlineJS(APP_PATH_WWW . '/static/p5UI/menuStore.js');
+		UI::inlineJS(APP_PATH_WWW . '/static/p5UI/menuStore.js'); // NOTE: only for p5UI__MenuStore.clearCache()
 		echo UI::h('script', [], "
 			(function (global) {
 				if (global.p5UI__MenuStore) global.p5UI__MenuStore.clearCache()
@@ -1017,7 +1017,7 @@ class Route_Users extends RouteBase {
 	public function logoutView($data = []) {
 		UI::gora();
 		UI::loadTemplate('logout', $data);
-		UI::inlineJS(APP_PATH_WWW . '/static/p5UI/menuStore.js');
+		UI::inlineJS(APP_PATH_WWW . '/static/p5UI/menuStore.js'); // NOTE: only for p5UI__MenuStore.clearCache()
 		echo UI::h('script', [], "
 			(function (global) {
 				if (global.p5UI__MenuStore) global.p5UI__MenuStore.clearCache()

+ 2 - 2
SE/se-lib/TableAcl.php

@@ -107,7 +107,7 @@ class TableAcl extends Core_AclBase {
 		return $opis;
 	}
 
-	public function getRawLabel($posLimit = 20) {
+	public function getRawLabel($posLimit = 20) { // TODO: moved to P5Menu
 		$label = $this->_label;
 		if (empty($label) && !empty($this->_opis)) {
 			$label = $this->_opis;
@@ -134,7 +134,7 @@ class TableAcl extends Core_AclBase {
 		return $shortLabel;
 	}
 
-	public function getLongLabel($posLimit = 30) {
+	public function getLongLabel($posLimit = 30) { // TODO: RMME
 		$longLabel = $this->getRawLabel($posLimit);
 		$opis = $this->_opis;
 		if ($longLabel != $this->_name) {

+ 5 - 0
SE/se-lib/tmpl/_layout_gora.php

@@ -53,6 +53,11 @@
 		'DBG' => V::get('DBG', '', $_REQUEST),
 	]);
 	UI::hButtonAjaxJsFunction();
+	$routeP5Menu = Router::getRoute('P5Menu');
+	UI::inlineJS(APP_PATH_WWW . '/static/p5UI/menuStore.js', [
+		'P5MENU_URL' => $routeP5Menu->getLink(),
+		'VERSION' => $routeP5Menu->getVersion(),
+	]);
 ?>
 	<?php Theme::head(); ?>
 </head><body style="position:relative; padding-bottom:30px">

+ 50 - 0
SE/static/p5UI/initP5MainMenuDropdown.css

@@ -0,0 +1,50 @@
+.dropdown-submenu {
+	position: relative;
+}
+
+.dropdown-submenu>.dropdown-menu {
+	top: 0;
+	left: 100%;
+	margin-top: -6px;
+	margin-left: -1px;
+	-webkit-border-radius: 0 6px 6px 6px;
+	-moz-border-radius: 0 6px 6px;
+	border-radius: 0 6px 6px 6px;
+}
+
+.dropdown-submenu:hover>.dropdown-menu {
+	display: block;
+}
+
+.dropdown-submenu>a:before {
+	display: block;
+	content: " ";
+	float: right;
+	width: 0;
+	height: 0;
+	border-color: transparent;
+	border-style: solid;
+	border-width: 5px 0 5px 5px;
+	border-left-color: #ccc;
+	margin-top: 5px;
+	margin-right: -10px;
+}
+
+.dropdown-submenu:hover>a:before {
+	border-left-color: #fff;
+}
+
+.dropdown-submenu.pull-left {
+	float: none;
+}
+
+.dropdown-submenu.pull-left>.dropdown-menu {
+	left: -100%;
+	margin-left: 10px;
+	-webkit-border-radius: 6px 0 6px 6px;
+	-moz-border-radius: 6px 0 6px 6px;
+	border-radius: 6px 0 6px 6px;
+}
+
+
+.dropdown-menu>li>a { max-width:500px; overflow:hidden; text-overflow:ellipsis }

+ 100 - 0
SE/static/p5UI/initP5MainMenuDropdown.js

@@ -0,0 +1,100 @@
+if (!global.p5UI__MenuStore) throw 'Missing global.p5UI__MenuStore'
+var DBG = DBG || 0
+
+function renderLabel(item) {
+	return (item.short_label !== item.desc)
+		? item.short_label + ' <em>' + item.desc + '</em>'
+		: item.short_label
+	;
+}
+function renderTitle(item) {
+	return (item.label !== item.desc)
+		? item.label + ' (' + item.desc + ')'
+		: item.label
+	;
+}
+function renderStar(id, idsBookmarks) {
+	return (-1 !== idsBookmarks.indexOf(id))
+		? '<i class=\"bookmark-item-rem glyphicon glyphicon-star\" title=\"Usuń z ulubionych\" onClick=\"return p5BookmarksRemove(event, ' + id + ')\"></i>'
+		: '<i class=\"bookmark-item-add glyphicon glyphicon-star-empty\" title=\"Dodaj do ulubionych\" onClick=\"return p5BookmarksAdd(event, ' + id + ')\"></i>'
+	;
+}
+
+function renderP5MainMenuDropdown(data, idSubMenu) {
+	DBG && console.log('DBG:renderP5MainMenuDropdown data.objects', data.objects)
+	var grouped = data.objects.reduce(function (ret, item, idx) {
+		ret.mapNsToIdx[ item.namespace ] = idx
+		var nsParts = item.namespace.split('/')
+		var baseNs = nsParts.slice(0, 2).join('/')
+		DBG && console.log('DBG:renderP5MainMenuDropdown >> reduce loop ', { nsParts, baseNs });
+		if (!ret.menuTreeNs[baseNs]) ret.menuTreeNs[baseNs] = []
+		ret.menuTreeNs[baseNs].push(item.namespace)
+		return ret;
+	}, { mapNsToIdx: {}, menuTreeNs: {} })
+	DBG && console.log('DBG:renderP5MainMenuDropdown grouped', grouped)
+
+	var jqDropdownMenu = jQuery('#' + idSubMenu)
+	jqDropdownMenu.empty()
+	liNodes = Object.keys(grouped.menuTreeNs).map(function (baseNs) {
+		var item = (baseNs in grouped.mapNsToIdx)
+			?	data.objects[ grouped.mapNsToIdx[baseNs] ]
+			:	data.objects[ grouped.mapNsToIdx[ grouped.menuTreeNs[baseNs][0] ] ]
+		;
+		DBG && console.log('DBG:renderP5MainMenuDropdown >> render loop', { baseNs, isInMap: (baseNs in grouped.mapNsToIdx), item, idx: [ grouped.mapNsToIdx[baseNs], grouped.menuTreeNs[baseNs][0] ] });
+
+		return (grouped.menuTreeNs[baseNs].length > 1)
+			?	'<li class="dropdown-submenu">' +
+					'<a href=\"index.php?_route=ViewTableAjax&namespace=' + item.namespace + '\" title="' + renderTitle(item) + '">' +
+						renderStar(item.id, data.idsBookmarks) +
+						' ' + renderLabel(item) +
+					'</a>' + "\n" +
+					'<ul class="dropdown-menu">' +
+						grouped.menuTreeNs[baseNs].map(function (subItemNs) {
+							var subItem = data.objects[ grouped.mapNsToIdx[subItemNs] ]
+							return '<li>' +
+									'<a href=\"index.php?_route=ViewTableAjax&namespace=' + subItem.namespace + '\" title="' + renderTitle(subItem) + '">' +
+										renderStar(subItem.id, data.idsBookmarks) +
+										' ' + renderLabel(subItem) +
+									'</a>' +
+								'</li>'
+							;
+						}).join("\n") +
+					'</ul>' +
+				'</li>' + "\n"
+			:	'<li>' +
+					'<a href=\"index.php?_route=ViewTableAjax&namespace=' + item.namespace + '\" title="' + renderTitle(item) + '">' +
+						renderStar(item.id, data.idsBookmarks) +
+						' ' + renderLabel(item) +
+					'</a>' +
+				'</li>' + "\n"
+		;
+	})
+	jqDropdownMenu.append(liNodes);
+}
+
+function initP5MainMenuDropdown( btnNode, idSubMenu ) {
+	DBG && console.log('DBG:initP5MainMenuDropdown({idSubMenu: '+idSubMenu+'})');
+	if (!btnNode._initialized) {
+		var jqDropdownTrigger = jQuery(btnNode)
+		var jqDropdownMenu = jQuery('#' + idSubMenu)
+		var jqDropdownParent = jqDropdownMenu.parent()
+
+		global.p5UI__MenuStore.subscribe(
+			(function (global, idSubMenu) {
+				return function (data) {
+					renderP5MainMenuDropdown(data, idSubMenu);
+				}
+			})(global, idSubMenu)
+		)
+
+		jqDropdownTrigger.attr('data-toggle', 'dropdown') // is required by bootstrap dorpdown.js evenf if is called via js
+
+		global.p5UI__MenuStore.forceUpdate()
+
+		jQuery(btnNode).dropdown()
+	}
+	// btnNode._initialized = true // TODO: DBG TEST
+	return true;
+}
+
+global.initP5MainMenuDropdown = initP5MainMenuDropdown

+ 18 - 15
SE/static/p5UI/menuStore.js

@@ -1,6 +1,8 @@
+if (!P5MENU_URL) throw "Missing P5MENU_URL"
+if (!VERSION) throw "Missing P5Menu VERSION"
+
 function p5UI__MenuStore() {
 
-	var _url = ''
 	var _subscribers = []
 
 	function _subscribe( fn ) { // fn( { bookmarks, idsBookmarks, objects, urls } )
@@ -10,16 +12,17 @@ function p5UI__MenuStore() {
 	function _update( data ) { // data: { bookmarks, idsBookmarks, objects, urls }
 
 		data.objects.sort(function (a, b) {
-			if (a.raw_label > b.raw_label) return 1
-			if (a.raw_label < b.raw_label) return -1
+			if (a.label.toLowerCase() > b.label.toLowerCase()) return 1
+			if (a.label.toLowerCase() < b.label.toLowerCase()) return -1
 			return 0
 		})
 		data.urls.sort(function (a, b) {
-			if (a.raw_label > b.raw_label) return 1
-			if (a.raw_label < b.raw_label) return -1
+			if (a.label.toLowerCase() > b.label.toLowerCase()) return 1
+			if (a.label.toLowerCase() < b.label.toLowerCase()) return -1
 			return 0
 		})
 
+		_set('version', data.version)
 		_set('bookmarks', data.bookmarks)
 		_set('idsBookmarks', data.idsBookmarks)
 		_set('objects', data.objects)
@@ -40,6 +43,7 @@ function p5UI__MenuStore() {
 
 	function _getData() {
 		return {
+			version: _get('version'),
 			bookmarks: _get('bookmarks'),
 			idsBookmarks: _get('idsBookmarks'),
 			objects: _get('objects'),
@@ -50,10 +54,13 @@ function p5UI__MenuStore() {
 	function _hasData() {
 		var data = _getData()
 		return (
-			null !== data.bookmarks
-			|| null !== data.idsBookmarks
-			|| null !== data.objects
-			|| null !== data.urls
+			parseInt(data.version || 0) === parseInt(VERSION)
+			&& (
+				null !== data.bookmarks
+				|| null !== data.idsBookmarks
+				|| null !== data.objects
+				|| null !== data.urls
+			)
 		)
 	}
 
@@ -66,13 +73,9 @@ function p5UI__MenuStore() {
 		return val ? JSON.parse(val) : null
 	}
 
-	function _setRemoteUrl(url) {
-		_url = url
-	}
-
 	function _remoteUpdate(postData) {
 		var options =
-		window.fetch(_url
+		window.fetch(P5MENU_URL
 			, (!postData)
 				?	{ method: 'GET',
 						headers: { 'Content-Type': 'application/json' },
@@ -99,13 +102,13 @@ function p5UI__MenuStore() {
 		global.localStorage.removeItem('p5Menu.' + 'objects')
 		global.localStorage.removeItem('p5Menu.' + 'bookmarks')
 		global.localStorage.removeItem('p5Menu.' + 'idsBookmarks')
+		global.localStorage.removeItem('p5Menu.' + 'version')
 	}
 
 	return {
 		subscribe: _subscribe,
 		update: _update,
 		forceUpdate: _forceUpdate,
-		setRemoteUrl: _setRemoteUrl,
 		remoteUpdate: _remoteUpdate,
 		getData: _getData,
 		hasData: _hasData,