* add new drop menu UI for doc views.

This commit is contained in:
Catouse
2016-11-09 08:40:27 +08:00
parent 75e12fbb13
commit 61b6e9d520
3 changed files with 238 additions and 22 deletions
+46 -2
View File
@@ -11,6 +11,50 @@
.w-lib-p33{width:31%;}
#titlebar > .heading > strong > i{display:inline;}
#modulemenu .nav > li > .dropdown > a#libType{display:inline-block;}
#modulemenu .nav > li > .dropdown.open > a#libType{background:#e5e5e5;}
#groups_chosen .chosen-choices {border-right:0px;}
#dropMenu.loading > #libMenu,
#dropMenu > .icon {display: none}
#dropMenu.loading > .icon {display: block}
#dropMenu {min-width: 600px; transition: min-width .2s;}
#libMenu {display: block; margin: -10px -15px; position: relative;}
#libMenuHeading {padding: 10px;}
#libMenuGroups {display: table; width: 100%; margin-bottom: 10px;}
.lib-menu-group {display: table-cell; width: 33.333333%; padding: 0 10px}
.lib-menu-group + .lib-menu-group {border-left: 1px dotted #ddd;}
.lib-menu-list-heading {background-color: #fafafa; color: #808080; padding: 0 10px; text-align: center; display: inline-block; margin-bottom: 10px; border: 1px solid #ddd; line-height: 20px; border-radius: 10px;}
.lib-menu-list-heading:hover {border-color: #114f8e; cursor: pointer; color: #114f8e;}
.lib-menu-list-heading > .icon {display: none}
.lib-menu-list {max-height: 500px; overflow-y: auto; min-height: 100px;}
.list-menu-item-heading {padding: 0 10px 0 0; font-weight: bold; color: #a1a1a1; background-color: #fff; border-bottom: 1px dotted #ddd; float: left; width: 100%;}
.list-menu-item-heading > .icon {display: inline-block; width: 20px;}
.list-menu-item + .list-menu-item-heading {border-top: 1px solid #ddd;}
.list-menu-item {padding: 0 10px 0 20px; display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; width: 100%; float: left;}
.list-menu-item.current {background-color: #EBF2F9;}
.list-menu-item.active,
.list-menu-item:hover {background-color: #e5e5e5; color: #1a53ff}
#searchLib {padding: 2px 8px; height: 28px; max-width: 190px;}
#dropMenu.lib-menu-lg {min-width: 1200px;}
#dropMenu.lib-menu-lg .list-menu-item {width: 50%; float: left;}
#dropMenu[data-filter="project"] #libMenuProjectGroup,
#dropMenu[data-filter="custom"] #libMenuCustomGroup,
#dropMenu[data-filter="product"] #libMenuProductGroup {display: block; width: 100%}
#dropMenu[data-filter="project"] #libMenuProjectGroup .lib-menu-list-heading,
#dropMenu[data-filter="custom"] #libMenuCustomGroup .lib-menu-list-heading,
#dropMenu[data-filter="product"] #libMenuProductGroup .lib-menu-list-heading {position: absolute; top: 13px; left: 215px; padding-right: 25px; background-color: #114f8e; color: #fff; border-color: #114f8e;}
#dropMenu[data-filter="project"] #libMenuProjectGroup .lib-menu-list-heading > .icon,
#dropMenu[data-filter="custom"] #libMenuCustomGroup .lib-menu-list-heading > .icon,
#dropMenu[data-filter="product"] #libMenuProductGroup .lib-menu-list-heading > .icon {position: absolute; right: 3px; top: 2px; display: block;}
#dropMenu[data-filter="project"] #libMenuProjectGroup .list-menu-item,
#dropMenu[data-filter="custom"] #libMenuCustomGroup .list-menu-item,
#dropMenu[data-filter="product"] #libMenuProductGroup .list-menu-item {width: 33.33333%;}
#dropMenu.lib-menu-lg[data-filter="product"] #libMenuProductGroup .list-menu-item {width: 16.666667%;}
#dropMenu[data-filter="project"] #libMenuProductGroup,
#dropMenu[data-filter="project"] #libMenuCustomGroup,
#dropMenu[data-filter="custom"] #libMenuProjectGroup,
#dropMenu[data-filter="custom"] #libMenuProductGroup,
#dropMenu[data-filter="product"] #libMenuProjectGroup,
#dropMenu[data-filter="product"] #libMenuCustomGroup {display: none;}
+172
View File
@@ -1,3 +1,175 @@
function showLibMenu()
{
var $item = $('#currentItem');
var $li = $item.closest('li');
var $menu = $('#dropMenu');
if($li.hasClass('show')) {$li.removeClass('show'); return;}
var isBigMode = false;
if(!$li.data('showagain'))
{
$menu.addClass('loading');
var $search = $('#searchLib');
var items = {};
var itemIdSeed = $.zui.uuid();
var orderSeed = 1;
$.getJSON(createLink('doc', 'ajaxGetAllLibs'), function(data)
{
$menu.removeClass('loading');
var $list = $('#libMenuProductGroup > .lib-menu-list');
var productCount = 0, projectCount = 0, customCount = 0;
$.each(data.product, function(idx, product)
{
$list.append('<div class="list-menu-item-heading" data-product="' + product.id + '"><i class="icon icon-cube"></i>' + product.name + '</div>');
$.each(product.libs, function(libId, libName)
{
var url = libId === 'files' ? createLink('doc', 'showFiles', 'type=product&objectID=' + product.id) : createLink('doc', 'browse', 'libID=' + libId);
var itemId = 'lib-' + itemIdSeed++;
$list.append('<a data-order="' + (orderSeed++) + '" title="' + product.name + '/' + libName + '" id="' + itemId + '" href="' + url + '" class="list-menu-item" data-type="product" data-product="' + product.id + '" data-id="' + libId + '">' + libName + '</a>');
items[itemId] = {type: 'product', id: libId, name: libName, objectId: product.id, product: product.name, search: (libName + ' ' + product.name).toLowerCase()};
productCount++;
});
});
$list = $('#libMenuProjectGroup > .lib-menu-list');
$.each(data.project, function(idx, project)
{
$list.append('<div class="list-menu-item-heading" data-product="' + project.id + '"><i class="icon icon-folder-close-alt"></i>' + project.name + '</div>');
$.each(project.libs, function(libId, libName)
{
var url = libId === 'files' ? createLink('doc', 'showFiles', 'type=project&objectID=' + project.id) : createLink('doc', 'browse', 'libID=' + libId);
var itemId = 'lib-' + itemIdSeed++;
$list.append('<a data-order="' + (orderSeed++) + '" title="' + project.name + '/' + libName + '" id="' + itemId + '" href="' + url + '" class="list-menu-item" data-type="project" data-project="' + project.id + '" data-id="' + libId + '">' + libName + '</a>');
items[itemId] = {type: 'project', id: libId, name: libName, objectId: project.id, project: project.name, search: (libName + ' ' + project.name).toLowerCase()};
projectCount++;
});
});
$list = $('#libMenuCustomGroup > .lib-menu-list');
$.each(data.custom, function(libId, libName)
{
var url = createLink('doc', 'browse', 'libID=' + libId);
var itemId = 'lib-' + itemIdSeed++;
$list.append('<a data-order="' + (orderSeed++) + '" title="' + libName + '" id="' + itemId + '" href="' + url + '" class="list-menu-item" data-type="custom" data-id="' + libId + '">' + libName + '</a>');
items[itemId] = {type: 'custom', id: libId, name: libName, search: libName.toLowerCase()};
customCount++;
});
var $items = $menu.find('.list-menu-item');
$items.filter('[data-id="' + $item.data('libId') + '"]').addClass('current');
$items.first().addClass('active');
isBigMode = productCount > 8 && projectCount > 8 && customCount > 8;
$menu.toggleClass('lib-menu-lg', isBigMode && $(window).width() > 1200);
var lastSearchKey = $search.val();
$search.on('change keyup paste input propertychange', function()
{
var searchKey = $search.val();
if(searchKey == lastSearchKey) return;
lastSearchKey = searchKey;
$menu.find('.list-menu-item.active').removeClass('active');
if(searchKey)
{
var $menuHeadings = $menu.find('.list-menu-item-heading').addClass('hidden');
searchKey = searchKey.toLowerCase();
$.each(items, function(itemId, item)
{
var isMatch = item.search.indexOf(searchKey) > -1 || '@' + item.type === searchKey || item.id === searchKey;
$('#' + itemId).toggleClass('hidden', !isMatch);
if(isMatch && item.type !== 'custom' && item.objectId)
{
$menuHeadings.filter('[data-' + item.type + '="' + item.objectId + '"]').removeClass('hidden');
}
});
}
else
{
$menu.find('.list-menu-item.hidden,.list-menu-item-heading.hidden').removeClass('hidden');
}
$menu.find('.list-menu-item:not(.hidden)').first().addClass('active');
}).on('keydown', function(e)
{
$items = $menu.find('.list-menu-item');
var code = e.which;
var $this = $items.filter('.list-menu-item.active');
if(code === 38) // up
{
$this.removeClass('active');
if($this.length)
{
var order = $this.data('order') - 1;
if(order > 0)
{
var $prev = $items.filter('.list-menu-item[data-order="' + order + '"]');
while($prev.hasClass('hidden') && order > 1)
{
order -= 1;
$prev = $items.filter('.list-menu-item[data-order="' + order + '"]');
}
if($prev.length)
{
$prev.addClass('active');
return;
}
}
}
$items.last(':not(.hidden)').addClass('active');
}
else if(code === 40) // down
{
$this.removeClass('active');
if($this.length)
{
var order = $this.data('order') + 1;
if(order <= $items.length)
{
var $next = $items.filter('.list-menu-item[data-order="' + order + '"]');
while($next.hasClass('hidden') && order <= $items.length)
{
order += 1;
$next = $items.filter('.list-menu-item[data-order="' + order + '"]');
}
if($next.length)
{
$next.addClass('active');
return;
}
}
}
$items.first(':not(.hidden)').addClass('active');
}
else if(code === 13) // enter
{
if($this.length) window.location.href = $this.attr('href');
}
});
$menu.on('mouseenter', '.list-menu-item', function()
{
$menu.find('.list-menu-item.active').removeClass('active');
$(this).addClass('active');
});
$menu.on('click', '.lib-menu-list-heading', function()
{
var libType = $(this).data('type');
var showFilter = $menu.attr('data-filter') != libType;
$menu.attr('data-filter', showFilter ? libType : '');
});
});
$li.data('showagain', true);
$li.on('click', function(e){e.stopPropagation();});
$(document).click(function(){$li.removeClass('show');});
}
$menu.toggleClass('lib-menu-lg', isBigMode && $(window).width() > 1200);
$menu.find('.lib-menu-list').css('max-height', $(window).height() - 210);
$li.addClass('show')
}
showLibMenu();
function loadModules(libID)
{
link = createLink('doc', 'ajaxGetModules', 'libID=' + libID);
+20 -20
View File
@@ -36,17 +36,9 @@ class docModel extends model
}
}
$selectHtml = "<a id='currentItem' href=\"javascript:showDropMenu('doc', '$libID', '$currentModule', '$currentMethod', '$extra')\">{$libs[$libID]} <span class='icon-caret-down'></span></a><div id='dropMenu'><i class='icon icon-spin icon-spinner'></i></div>";
$selectHtml = "<a id='currentItem' data-lib-id='$libID' href=\"javascript:showLibMenu()\">{$libs[$libID]} <span class='icon-caret-down'></span></a><div id='dropMenu'><i class='icon icon-spin icon-spinner'></i><div id='libMenu'><div id='libMenuHeading'><input id='searchLib' type='search' placeholder='{$this->lang->doc->searchDoc}' class='form-control'></div><div id='libMenuGroups' class='clearfix'><div class='lib-menu-group' id='libMenuProductGroup'><div class='lib-menu-list-heading' data-type='product'>{$this->lang->doc->libTypeList['product']}<i class='icon icon-remove'></i></div><div class='lib-menu-list clearfix'></div></div><div class='lib-menu-group' id='libMenuProjectGroup'><div class='lib-menu-list-heading' data-type='project'>{$this->lang->doc->libTypeList['project']}<i class='icon icon-remove'></i></div><div class='lib-menu-list clearfix'></div></div><div class='lib-menu-group' id='libMenuCustomGroup'><div class='lib-menu-list-heading' data-type='custom'>{$this->lang->doc->libTypeList['custom']}<i class='icon icon-remove'></i></div><div class='lib-menu-list clearfix'></div></div></div></div></div>";
common::setMenuVars($this->lang->doc->menu, 'list', $selectHtml);
$libTypeSelect = "<div class='dropdown'><a id='libType' class='dropdown-toggle' data-toggle='dropdown' href='###'>{$this->lang->doc->libTypeList[$extra]} <span class='icon-caret-down'></span></a> {$this->lang->arrow} ";
$libTypeSelect .= "<ul class='dropdown-menu' role='menu'>";
foreach($this->lang->doc->libTypeList as $libType => $libName)
{
$libTypeSelect .= '<li>' . html::a(helper::createLink('doc', 'allLibs', "type=$libType"), $libName) . '</li>';
}
$libTypeSelect .= "</ul></div>";
common::setMenuVars($this->lang->doc->menu, 'type', $libTypeSelect);
common::setMenuVars($this->lang->doc->menu, 'type', '');
}
/**
@@ -695,11 +687,19 @@ class docModel extends model
{
if($lib->product)
{
$productLibs[$lib->product][$lib->id] = $lib->name;
if(empty($productLibs[$lib->product]))
{
$productLibs[$lib->product] = array('id' => $lib->product, 'libs' => array());
}
$productLibs[$lib->product]['libs'][$lib->id] = $lib->name;
}
elseif($lib->project)
{
$projectLibs[$lib->project][$lib->id] = $lib->name;
if(empty($projectLibs[$lib->project]))
{
$projectLibs[$lib->project] = array('id' => $lib->project, 'libs' => array());
}
$projectLibs[$lib->project]['libs'][$lib->id] = $lib->name;
}
else
{
@@ -716,20 +716,20 @@ class docModel extends model
$hasLibsPriv = common::hasPriv('doc', 'allLibs');
$hasFilesPriv = common::hasPriv('doc', 'showFiles');
foreach($products as $productID => $productName)
foreach ($productLibs as $productID => $productLib)
{
foreach($productLibs[$productID] as $libID => $libName) $productLibs[$productID][$libID] = $productName . ' / ' . $libName;
if(isset($hasProject[$productID]) and $hasLibsPriv) $productLibs[$productID]['project'] = $productName . ' / ' . $this->lang->doc->systemLibs['project'];
if($hasFilesPriv) $productLibs[$productID]['files'] = $productName . ' / ' . $this->lang->doclib->files;
$productLibs[$productID]['name'] = $products[$productID];
if(isset($hasProject[$productID]) and $hasLibsPriv) $productLibs[$productID]['libs']['project'] = $this->lang->doc->systemLibs['project'];
if($hasFilesPriv) $productLibs[$productID]['libs']['files'] = $this->lang->doclib->files;
}
$projects = $this->dao->select('id,name')->from(TABLE_PROJECT)->where('id')->in(array_keys($projectLibs))->andWhere('deleted')->eq('0')->orderBy('`order`_desc')->fetchPairs('id', 'name');
foreach($projects as $projectID => $projectName)
foreach($projectLibs as $projectID => $projectName)
{
foreach($projectLibs[$projectID] as $libID => $libName) $projectLibs[$projectID][$libID] = $projectName . ' / ' . $libName;
if($hasFilesPriv) $projectLibs[$projectID]['files'] = $projectName . ' / ' . $this->lang->doclib->files;
$projectLibs[$projectID]['name'] = $projects[$projectID];
if($hasFilesPriv) $projectLibs[$projectID]['libs']['files'] = $this->lang->doclib->files;
}
return array('product' => $productLibs, 'project' => $projectLibs, 'custom' => $customLibs);
return array('product' => array_values($productLibs), 'project' => array_values($projectLibs), 'custom' => $customLibs);
}
/**