* improve custom menu UI.

This commit is contained in:
Catouse
2016-04-21 12:07:15 +08:00
parent ceb8e4fe67
commit 825350f421
8 changed files with 212 additions and 60 deletions
+2 -2
View File
@@ -156,7 +156,7 @@ $lang->index->menu->project = "浏览{$lang->projectCommon}|project|browse";
$lang->my = new stdclass();
$lang->my->menu = new stdclass();
$lang->my->menu->account = '<span id="myname"><i class="icon-user"></i> %s' . $lang->arrow . '</span>';
$lang->my->menu->account = array('link' => '<span id="myname"><i class="icon-user"></i> %s' . $lang->arrow . '</span>', 'fixed' => true);
$lang->my->menu->index = '首页|my|index';
$lang->my->menu->todo = array('link' => '待办|my|todo|', 'subModule' => 'todo');
$lang->my->menu->task = array('link' => '任务|my|task|', 'subModule' => 'task');
@@ -176,7 +176,7 @@ $lang->todo->menu = $lang->my->menu;
$lang->product = new stdclass();
$lang->product->menu = new stdclass();
$lang->product->menu->list = '%s';
$lang->product->menu->list = array('link' => '%s', 'fixed' => true);
$lang->product->menu->index = '首页|product|index|locate=no';
$lang->product->menu->story = array('link' => '需求|product|browse|productID=%s', 'alias' => 'batchedit', 'subModule' => 'story');
$lang->product->menu->dynamic = '动态|product|dynamic|productID=%s';
+1 -1
View File
@@ -483,7 +483,7 @@ class commonModel extends model
/* Cycling to print every sub menus. */
foreach($menu as $menuItem)
{
if($menuItem->hidden) continue;
/* Init the these vars. */
if($menuItem->link)
{
+16 -7
View File
@@ -193,18 +193,27 @@ class custom extends control
if($_POST)
{
$account = $this->app->user->account;
$menu = $_POST['menu'];
$menus = $_POST['menus'];
if(empty($menus)) $this->send(array('result' => 'fail', 'message' => $this->lang->custom->saveFail));
if(empty($method))
if(is_array($menus))
{
$this->loadModel('setting')->setItem("$account.menucustom.$module", $menu);
foreach ($menus as $menu)
{
$menu = json_decode($menu);
$this->custom->saveCustomMenu($menu->value, $menu->module, $menu->method);
}
}
else
{
$configKey = 'menucustom' . $module;
$this->loadModel('setting')->setItem("$account.$configKey.$method", $menu);
if(!empty($_POST['module'])) $module = $_POST['module'];
if(!empty($_POST['method'])) $method = $_POST['method'];
$this->custom->saveCustomMenu($menus, $module, $method);
}
$this->send(array('result' => 'success', 'menu' => $menu));
$this->send(array('result' => 'success'));
}
if($this->viewType === 'json')
@@ -225,7 +234,7 @@ class custom extends control
{
$menu = !empty($method) ? customModel::getFeatureMenu($module, $method) : customModel::getModuleMenu($module, true);
}
$this->send(array('result' => $menu ? 'success' : 'fail', 'menu' => $menu));
die(json_encode(array('result' => $menu ? 'success' : 'fail', 'menu' => $menu), JSON_HEX_QUOT | JSON_HEX_APOS));
}
else
{
+150 -41
View File
@@ -13,8 +13,29 @@ $(function()
'feature': {}
};
var updateMenu = function($menu, items)
var updateConfig = function($menu)
{
var moduleName = $menu.data('module'), methodName = $menu.data('method');
var menu = [];
$menu.children('.nav').children('li:not(.drag-shadow)').each(function()
{
var $e = $(this);
var item = $e.children('a').data('menu');
item.order = $e.attr('data-order');
menu.push(item);
});
if(moduleName === 'main') menuConfig.main = menu;
else if(methodName) menuConfig['feature'][moduleName][methodName] = menu;
else menuConfig['module'][moduleName] = menu;
}
var updateMenu = function(moduleName, methodName, items)
{
var $menu = moduleName === 'main' ? $mainMenu : (methodName ? $featureMenu : $moduleMenu);
var items = items || (moduleName === 'main' ? menuConfig.main : (methodName ? menuConfig['feature'][moduleName][methodName] : menuConfig['module'][moduleName]));
$menu.data({'module': moduleName, 'method': methodName});
if(items)
{
var $nav = $('<ul class="nav"/>');
@@ -24,7 +45,10 @@ $(function()
var $a = $('<a href="#"/>').html(item.text).data('menu', item).append('<i class="item-hidden-icon icon icon-eye-close"></i>');
$('<li/>').attr('data-id', item.name).toggleClass('right', item.float === 'right').toggleClass('menu-hidden', !!item.hidden).append($a).appendTo($nav);
});
$nav.sortable();
$nav.sortable({finish: function(e)
{
updateConfig(e.element.closest('nav'));
}});
$menu.children('ul').replaceWith($nav);
}
else
@@ -43,71 +67,125 @@ $(function()
$moduleMenu.find('li[data-id="' + methodName + '"]').addClass('active');
};
var loadData = function(moduleName, methodName, type)
var loadData = function(moduleName, methodName, type, callback)
{
type = type || '';
var link = createLink('custom', 'menu', 'module=' + moduleName + '&method=' + methodName + '&type=' + type, 'json');
$loadingIcon.addClass('active');
$.get(link, function(data)
{
console.log(data);
if(data.result === 'success' && data.menu)
{
var menu = data.menu;
if(menu['main'])
if(menu['main'] && !menuConfig['main'])
{
updateMenu($mainMenu, menu['main']);
menuConfig['main'] = menu['main'];
}
if(menu['module'])
if(menu['module'] && !menuConfig['module'][moduleName])
{
updateMenu($moduleMenu, menu['module']);
menuConfig['module'][moduleName] = menu['module'];
}
if(menu['feature'] !== undefined)
if(menu['feature'] !== undefined && (!menuConfig['feature'][moduleName] || menuConfig['feature'][moduleName][methodName] === undefined))
{
updateMenu($featureMenu, menu['feature']);
if(!menuConfig['feature'][moduleName]) menuConfig['feature'][moduleName] = {};
menuConfig['feature'][moduleName][methodName] = menu['feature'];
}
activeCurrent(moduleName, methodName);
callback && callback(true, data);
}
else
{
callback && callback(false, data);
}
activeCurrent(moduleName, methodName);
$loadingIcon.removeClass('active');
}, 'json');
};
$menuEditor.on('mouseenter', '.nav > li > a', function()
var formatMenuConfig = function(items)
{
// var $a = $(this);
// var item = $a.data('menu');
// var $menu = $a.closest('nav');
// var moduleName = item.link && item.link['module'] ? item.link['module'] : item.name;
// var methodName = item.link && item.link['method'] ? item.link['method'] : '';
// if($menu.is('#modulemenu'))
// {
// moduleName = currentModule;
// methodName = item.name;
// }
// if(moduleName !== currentModule || methodName !== currentMethod)
// {
// if($menu.is('#mainmenu,#modulemenu'))
// {
// if(menuConfig['module'][moduleName] !== undefined && menuConfig['feature'][moduleName] && menuConfig['feature'][moduleName][methodName] !== undefined)
// {
// updateMenu($moduleMenu, menuConfig['module'][moduleName]);
// updateMenu($featureMenu, menuConfig['feature'][moduleName][methodName]);
// activeCurrent(moduleName, methodName);
// }
// else
// {
// loadData(moduleName, methodName, 'all');
// }
// }
// }
return $.map(items, function(item)
{
var data = {name: item.name, order: parseInt(item.order)};
if(item.hidden) data.hidden = true;
return data;
});
};
$menuEditor.on('mouseenter', '.nav > li:not(.drag-shadow) > a', function()
{
var $a = $(this);
var item = $a.data('menu');
var $menu = $a.closest('nav');
if($menu.is('#mainmenu'))
{
var moduleName = item.name;
if(moduleName !== currentModule)
{
var methodName = item.link['method'];
if(menuConfig['module'][moduleName])
{
updateMenu(moduleName);
if(menuConfig['feature'][moduleName] && menuConfig['feature'][moduleName][methodName] !== undefined)
{
updateMenu(moduleName, methodName);
activeCurrent(moduleName, methodName);
}
else
{
loadData(moduleName, methodName, 'all', function(result)
{
if(result)
{
updateMenu(moduleName, methodName);
activeCurrent(moduleName, methodName);
}
});
}
}
else
{
loadData(moduleName, methodName, 'all', function(result)
{
if(result)
{
updateMenu(moduleName);
updateMenu(moduleName, methodName);
activeCurrent(moduleName, methodName);
}
});
}
}
}
else if($menu.is('#modulemenu'))
{
var moduleName = currentModule;
var methodName = item.name;
if(methodName !== currentMethod)
{
if(menuConfig['feature'][moduleName] && menuConfig['feature'][moduleName][methodName] !== undefined)
{
updateMenu(moduleName, methodName);
activeCurrent(moduleName, methodName);
}
else
{
loadData(moduleName, methodName, 'all', function(result)
{
if(result)
{
updateMenu(moduleName, methodName);
activeCurrent(moduleName, methodName);
}
});
}
}
}
}).on('click', '.nav > li > a', function()
{
var $a = $(this);
var item = $a.data('menu');
item.hidden = !!!item.hidden;
var $menu = $a.closest('nav');
var moduleName = item.link && item.link['module'] ? item.link['module'] : item.name;
var methodName = item.link && item.link['method'] ? item.link['method'] : '';
@@ -116,14 +194,45 @@ $(function()
moduleName = currentModule;
methodName = item.name;
}
$a.parent().toggleClass('menu-hidden');
$a.parent().toggleClass('menu-hidden', item.hidden);
updateConfig($menu);
});
$('#saveMenuBtn').click(function()
{
console.log('save', menuConfig);
var postData = [{'module': 'main', value: formatMenuConfig(menuConfig.main)}];
$.each(menuConfig['module'], function(moduleName, items)
{
postData.push({'module': moduleName, value: formatMenuConfig(items)});
});
$.each(menuConfig['feature'], function(moduleName, feature)
{
if(!feature) return;
$.each(feature, function(methodName, items)
{
if(items) postData.push({'module': moduleName, 'method': methodName, value: formatMenuConfig(items)});
});
});
postData = $.map(postData, JSON.stringify);
$.post(createLink('custom', 'menu'), {menus: postData}, function(data)
{
if(data.result === 'success') window.parent.location.reload()
if(data.message) alert(data.message);
}, 'json').error(function(e) {alert(lang.timeout); console.log(e);});
}).on('mouseenter', function() {$menuEditor.addClass('preview')})
.on('mouseout', function() {$menuEditor.removeClass('preview')});
loadData(currentModule, currentMethod, 'all');
loadData(currentModule, currentMethod, 'all', function(result)
{
if(result)
{
updateMenu('main');
updateMenu(currentModule);
updateMenu(currentModule, currentMethod);
activeCurrent(currentModule, currentMethod);
}
});
});
+2 -1
View File
@@ -80,4 +80,5 @@ $lang->custom->productproject->relation['1_1'] = 'Project - Sprint';
$lang->custom->productproject->notice = 'You can change the name of product and project, and the corresponding name display';
$lang->custom->menuTip = 'Click menu item to toggle display status, drag and drop to change display order.';
$lang->custom->menuTip = 'Click menu item to toggle display status, drag and drop to change display order.';
$lang->custom->saveFail = 'Save failed.';
+2 -1
View File
@@ -80,4 +80,5 @@ $lang->custom->productproject->relation['1_1'] = '项目 - 迭代';
$lang->custom->productproject->notice = '请根据实际情况选择适合自己团队的概念。';
$lang->custom->menuTip = '点击导航项目来切换显示或隐藏,拖动导航项目来更改显示顺序。';
$lang->custom->menuTip = '点击导航项目来切换显示或隐藏,拖动导航项目来更改显示顺序。';
$lang->custom->saveFail = '保存失败!';
+31 -4
View File
@@ -173,7 +173,6 @@ class customModel extends model
$method = '';
$float = '';
$fixed = '';
$hidden = $isSetMenuConfig && $menuConfigMap[$name] && $menuConfigMap[$name]->hidden;
$link = is_array($item) ? $item['link'] : $item;
if(strpos($link, '|') !== false)
@@ -208,11 +207,12 @@ class customModel extends model
$fixed = $item['fixed'];
}
$hidden = !$fixed && $isSetMenuConfig && $menuConfigMap[$name] && $menuConfigMap[$name]->hidden;
$menuItem = new stdclass();
$menuItem->name = $name;
$menuItem->link = $itemLink;
$menuItem->text = $label;
$menuItem->source = $item;
$menuItem->order = $isSetMenuConfig && $menuConfigMap[$name] && isset($menuConfigMap[$name]->order) ? $menuConfigMap[$name]->order : $order++;
if($float) $menuItem->float = $float;
if($fixed) $menuItem->fixed = $fixed;
@@ -273,12 +273,39 @@ class customModel extends model
{
global $app, $lang, $config;
$app->loadLang($module);
$configKey = 'menucustom' . $module;
$menuConfig = $config->$configKey->$method;
$configKey = 'feature_' . $module . '_' . $method;
$menuConfig = $config->menucustom->$configKey;
if(!empty($menuConfig)) $menuConfig = json_decode($menuConfig);
$allMenu = $lang->$module->featurebar[$method];
return $allMenu ? self::buildMenuConfig($allMenu, $menuConfig) : null;
}
/**
* Save custom menu to config
* @param string $menu
* @param string $module
* @param string $method
* @access public
* @return void
*/
public function saveCustomMenu($menu, $module, $method)
{
$account = $this->app->user->account;
$settingKey = '';
if(!is_string($menu)) $menu = json_encode($menu);
if(empty($method))
{
$settingKey = "$account.common.menucustom.$module";
}
else
{
$settingKey = "$account.common.menucustom.feature_$module_$method";
}
$this->loadModel('setting')->setItem($settingKey, $menu);
}
}
+8 -3
View File
@@ -1795,10 +1795,15 @@ function initMainMenu()
selector: 'li:not(.custom-item)',
finish: function(e)
{
var menu = e.list.map(function(){return $(this).data('id');}).get();
$.post(createLink('custom', 'menu'), {menu: menu.join(',')}, function(data)
var menu = [];
e.list.each(function()
{
}, 'json');
var $e = $(this);
menu.push({name: $e.data('id'), order: $e.attr('data-order')});
});
$.post(createLink('custom', 'menu'), {menus: JSON.stringify(menu), "module": 'main'}, function(data)
{
}, 'json').error(function() {alert(lang.timeout)});
}
});
}