提交 ede925ca 编写于 作者: D Daniel Beck

Merge pull request #2077 from kzantow/2.0-install-dependency-view

Fix dependency display in setup wizard: remove tooltip, clickable
......@@ -36,3 +36,4 @@ installWizard_installIncomplete_title=Resume Installation
installWizard_installIncomplete_banner=Resume Installation
installWizard_installIncomplete_message=Jenknins was restarted during installation and some plugins didn't seem to get installed.
installWizard_installIncomplete_resumeInstallationButtonLabel=Resume
installWizard_installIncomplete_dependenciesLabel=Dependencies
......@@ -66,8 +66,16 @@ var createPluginSetupWizard = function() {
}
});
// get total number of dependencies
Handlebars.registerHelper('dependencyCount', function(plugName) {
var plug = availablePlugins[plugName];
if(plug && plug.allDependencies && plug.allDependencies.length > 1) { // includes self
return plug.allDependencies.length - 1;
}
});
// gets user friendly dependency text
Handlebars.registerHelper('dependencyText', function(plugName) {
Handlebars.registerHelper('eachDependency', function(plugName, options) {
var plug = availablePlugins[plugName];
if(!plug) {
return '';
......@@ -75,20 +83,25 @@ var createPluginSetupWizard = function() {
var deps = $.grep(plug.allDependencies, function(value) { // remove self
return value !== plugName;
});
var out = '';
var out = '';
for(var i = 0; i < deps.length; i++) {
if(i > 0) {
out += ', ';
}
var depName = deps[i];
var dep = availablePlugins[depName];
if(dep) {
out += dep.title;
out += options.fn(dep);
}
}
return out;
});
// executes a block if there are dependencies
Handlebars.registerHelper('ifVisibleDependency', function(plugName, options) {
if(visibleDependencies[plugName]) {
return options.fn();
}
});
// Include handlebars templates here - explicitly require them and they'll be available by hbsfy as part of the bundle process
var errorPanel = require('./templates/errorPanel.hbs');
var loadingPanel = require('./templates/loadingPanel.hbs');
......@@ -122,6 +135,7 @@ var createPluginSetupWizard = function() {
var pluginList = pluginManager.plugins();
var allPluginNames = pluginManager.pluginNames();
var selectedPluginNames = pluginManager.recommendedPluginNames();
var visibleDependencies = {};
var categories = [];
var availablePlugins = {};
var categorizedPlugins = {};
......@@ -264,6 +278,25 @@ var createPluginSetupWizard = function() {
setPanel(progressPanel, { installingPlugins : installingPlugins });
};
// toggles visibility of dependency listing for a plugin
var toggleDependencyList = function() {
var $btn = $(this);
var $toggle = $btn.parents('.plugin:first');
var plugName = $btn.attr('data-plugin-name');
if(!visibleDependencies[plugName]) {
visibleDependencies[plugName] = true;
}
else {
visibleDependencies[plugName] = false;
}
if(!visibleDependencies[plugName]) {
$toggle.removeClass('show-dependencies');
}
else {
$toggle.addClass('show-dependencies');
}
};
// install the default plugins
var installDefaultPlugins = function() {
......@@ -519,7 +552,7 @@ var createPluginSetupWizard = function() {
findIndex = (findIndex+1) % matches.length;
}
var $el = $(matches[findIndex]);
$el = $el.parents('label:first'); // scroll to the block
$el = $el.parents('.plugin:first'); // scroll to the block
if($el && $el.length > 0) {
var pos = $pl.scrollTop() + $el.position().top;
$pl.stop(true).animate({
......@@ -538,7 +571,7 @@ var createPluginSetupWizard = function() {
// search for given text, optionally scroll to the next match, set classes on appropriate elements from the search match
var searchForPlugins = function(text, scroll) {
var $pl = $('.plugin-list');
var $containers = $pl.find('label');
var $containers = $pl.find('.plugin');
// must always do this, as it's called after refreshing the panel (e.g. check/uncheck plugs)
$containers.removeClass('match');
......@@ -550,7 +583,7 @@ var createPluginSetupWizard = function() {
}
else {
var matches = findElementsWithText($pl[0], text.toLowerCase(), function(d) { return d.toLowerCase(); });
$(matches).parents('label').addClass('match');
$(matches).parents('.plugin').addClass('match');
if(lastSearch !== text && scroll) {
scrollPlugin($pl, matches, text);
}
......@@ -669,6 +702,7 @@ var createPluginSetupWizard = function() {
// click action mappings
var actions = {
'.toggle-dependency-list': toggleDependencyList,
'.install-recommended': installDefaultPlugins,
'.install-custom': loadCustomPluginPanel,
'.install-home': function() { setPanel(welcomePanel); },
......
......@@ -26,21 +26,36 @@
</span>
</div>
<div class="plugin-list">
<div class="plugin-list-description">{{{translations.installWizard_installCustom_pluginListDesc}}}</div>
<div class="plugin-list-description">{{{translations.installWizard_installCustom_pluginListDesc}}}</div>
{{#each categorizedPlugins}}
<h2 id="{{id @key}}" class="expanded">{{@key}} {{pluginCountForCategory @key}}</h2>
<div class="plugins-for-category">
{{#each this}}
<label class="{{#inSelectedPlugins plugin.name}}selected{{/inSelectedPlugins}}" id="row-{{plugin.name}}"
{{#hasDependencies plugin.name}}data-tooltip="{{../../../translations.installWizard_installCustom_dependenciesPrefix}}: {{dependencyText ../plugin.name}}"{{/hasDependencies}}>
<span class="title">
<input type="checkbox" id="chk-{{plugin.name}}" name="{{plugin.name}}" value="{{searchTerm}}" {{#inSelectedPlugins plugin.name}}checked="checked"{{/inSelectedPlugins}}/>
{{plugin.title}}
</span>
<span class="description">
{{{plugin.excerpt}}}
</span>
</label>
<div class="plugin {{#inSelectedPlugins plugin.name}}selected{{/inSelectedPlugins}} {{#ifVisibleDependency plugin.name}}show-dependencies{{/ifVisibleDependency}}" id="row-{{plugin.name}}">
{{#hasDependencies plugin.name}}
<div class="btn btn-link toggle-dependency-list" type="button" data-plugin-name="{{../plugin.name}}">
{{../../../translations.installWizard_installIncomplete_dependenciesLabel}}<span class="badge">{{dependencyCount ../plugin.name}}</span>
</div>
{{/hasDependencies}}
<label>
<span class="title">
<input type="checkbox" id="chk-{{plugin.name}}" name="{{plugin.name}}" value="{{searchTerm}}" {{#inSelectedPlugins plugin.name}}checked="checked"{{/inSelectedPlugins}}/>
{{plugin.title}}
</span>
<span class="description">
{{{plugin.excerpt}}}
</span>
{{#hasDependencies plugin.name}}
<div class="dep-list">
{{#eachDependency ../plugin.name}}
<span class="dep badge">
{{title}}
</span>
{{/eachDependency}}
</div>
{{/hasDependencies}}
</label>
</div>
{{/each}}
</div>
{{/each}}
......
......@@ -282,7 +282,7 @@
}
&.searching-with-transition {
label {
.plugin {
display: none;
transition: all .25s;
......@@ -312,7 +312,7 @@
}
&.searching {
label {
.plugin {
display: none;
transition: all .25s;
......@@ -331,65 +331,118 @@
}
}
}
label {
font-weight: normal;
padding: 7px 2px 7px 27px;
.plugin {
position: relative;
display: block;
cursor: pointer;
margin: 4px -7px;
&:hover{
background: rgba(100, 200, 255, 0.1);
box-shadow:inset 0 200px 200px -200px rgba(100, 200, 255, 0.33),inset 0 0 0 1px rgba(100, 200, 255, 0.33);
}
&.selected {
&.selected label {
background: #dff0d8;
margin: 4px -7px;
padding: 6px 0 6px 26px;
border-radius: 2px;
border: 1px solid #C2E0A9;
color: #3c763d;
}
.title {
display: block;
font-weight: bold;
white-space: nowrap;
position: relative;
.dependencies {
color: #777;
}
}
.description {
label {
font-weight: normal;
padding: 7px 2px 7px 27px;
position: relative;
display: block;
margin-top: .5em;
cursor: pointer;
margin: 4px -7px;
&:hover{
background: rgba(100, 200, 255, 0.1);
box-shadow:inset 0 400px 400px -100px rgba(100, 200, 255, 0.33), inset 0 0 0 1px rgba(100, 200, 255, 0.33);
}
.title {
display: block;
font-weight: bold;
white-space: nowrap;
position: relative;
}
.description {
display: block;
margin-top: .5em;
}
input[type=checkbox] {
float: left;
margin: 2px -18px;
vertical-align: middle;
}
+ .tooltip {
left: 2px !important;
margin-right: 16px;
.tooltip-arrow {
left: 4em !important;
}
.tooltip-inner {
max-width: none;
padding: .5em 1em;
text-align: left;
}
}
}
&.selected .dependencies {
.toggle-dependency-list {
position: absolute;
top: 0;
right: 0;
color: #777;
border: 0;
text-decoration: none;
padding: 5px 13px;
z-index: 100;
.badge {
margin-left: 7px;
}
&:hover, &.active {
text-decoration: underline;
}
}
input[type=checkbox] {
float: left;
margin: 2px -18px;
vertical-align: middle;
.dep-list {
padding: 10px 0 6px 0;
display: none;
.badge {
padding: 4px 8px;
margin: 5px 3px 0 0;
}
}
&.show-dependencies {
.toggle-dependency-list:after {
content: '';
display: inline-block;
position: absolute;
top: 50%;
right: 100%;
width: 0;
height: 0;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 7px solid #999;
margin: -3px -3px 0 0;
}
.dep-list {
display: block;
}
}
+ .tooltip {
left: 2px !important;
margin-right: 16px;
.tooltip-arrow {
left: 4em !important;
}
.tooltip-inner {
max-width: none;
padding: .5em 1em;
text-align: left;
}
}
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册