Commiting initial version of fix for bug 251656: Redesign dependency

tree, part 1: fix the tree itself. Changes the way bullets are
displayed, allow for control-click expansion and contraction, and
simplify styling of the links themselves. Still needs some refinement.


git-svn-id: svn://10.0.0.236/branches/kiko_UI_20040909-BRANCH@162017 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
kiko%async.com.br
2004-09-09 21:59:41 +00:00
parent 7a2c9995d5
commit 904ee0f87e
7 changed files with 301 additions and 110 deletions

View File

@@ -0,0 +1,89 @@
/* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Bugzilla Bug Tracking System.
*
* The Initial Developer of the Original Code is Netscape
* Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s): Christian Reis <kiko@async.com.br>
*/
ul.tree {
padding-left: 0em;
margin-left: 1em;
display: block;
}
ul.tree ul {
padding-top: 3px;
display: block;
}
ul.tree li {
/* see http://www.kryogenix.org/code/browser/aqlists/ for idea */
padding-top: 3px;
text-indent: -1.2em;
padding-left: 0.5em;
list-style-type: none;
padding-bottom: 3px;
}
ul.tree li a.b {
padding-left: 12px;
margin-right: 2px;
text-decoration: none;
}
ul.tree li a.b_open {
background: url("../images/tree-open.png") center no-repeat;
cursor: pointer;
}
ul.tree li a.b_closed {
background: url("../images/tree-closed.png") center no-repeat;
cursor: pointer;
}
.summ_info {
/* change to inline if you would like to see the full bug details
* displayed in the list */
display: none;
font-size: 75%;
}
.hint {
font-size: 90%;
margin: 0.2em;
padding: 0.1em;
}
.hint h3, .hint ul {
margin-top: 0.1em;
margin-bottom: 0.1em;
}
/* uncomment this if you would like summary text of closed classes to be
* striked through */
/*
.bz_closed + .summ_text {
text-decoration: line-through;
}
*/
/* for styling summaries that are leaves or not */
.summ, .summ_deep {
}
.summ_deep {
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 B

View File

@@ -0,0 +1,117 @@
/* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Bugzilla Bug Tracking System.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s): Mike Shaver <shaver@mozilla.org>
* Christian Reis <kiko@async.com.br>
*/
if (!Node) {
/* MSIE doesn't define Node, so provide a compatibility object */
var Node = { TEXT_NODE: 3 }
}
function doToggle(node, event)
{
var deep = event.altKey || event.ctrlKey;
if (node.nodeType == Node.TEXT_NODE)
node = node.parentNode;
var toggle = node.nextSibling;
while (toggle && toggle.tagName != "UL")
toggle = toggle.nextSibling;
if (toggle) {
if (deep) {
var direction = toggleDisplay(toggle, node);
changeChildren(toggle, direction);
} else {
toggleDisplay(toggle, node);
}
}
/* avoid problems with default actions on links (mozilla's
* ctrl/shift-click defaults, for instance */
event.preventBubble();
event.preventDefault();
return false;
}
function changeChildren(node, direction) {
var item = node.firstChild;
while (item) {
/* find the LI inside the UL I got */
while (item && item.tagName != "LI")
item = item.nextSibling;
if (!item)
return;
/* got it, now find the first A */
var child = item.firstChild;
while (child && child.tagName != "A")
child = child.nextSibling;
if (!child) {
return
}
var bullet = child;
/* and check if it has its own sublist */
var sublist = item.firstChild;
while (sublist && sublist.tagName != "UL")
sublist = sublist.nextSibling;
if (sublist) {
if (direction && isClosed(sublist)) {
openNode(sublist, bullet);
} else if (!direction && !isClosed(sublist)) {
closeNode(sublist, bullet);
}
changeChildren(sublist, direction)
}
item = item.nextSibling;
}
}
function openNode(node, bullet)
{
node.style.display = "block";
bullet.className = "b b_open";
}
function closeNode(node, bullet)
{
node.style.display = "none";
bullet.className = "b b_closed";
}
function isClosed(node) {
/* XXX we should in fact check our *computed* style, not the display
* attribute of the current node, which may be inherited and not
* set. However, this really only matters when changing the default
* appearance of the tree through a parent style. */
return node.style.display == "none";
}
function toggleDisplay(node, bullet)
{
if (isClosed(node)) {
openNode(node, bullet);
return true;
}
closeNode(node, bullet);
return false;
}

View File

@@ -67,7 +67,7 @@ if ($maxdepth !~ /^\d+$/) { $maxdepth = 0 };
# have to embed a conditional statement into each query.
my $milestone_column = Param('usetargetmilestone') ? "target_milestone" : "''";
# The greatest depth to which either tree goes.
# Stores the greatest depth to which either tree goes.
my $realdepth = 0;
# Generate the tree of bugs that this bug depends on and a list of IDs
@@ -149,6 +149,7 @@ sub GetBug {
if (Bugzilla->user->can_see_bug($id)) {
SendSQL("SELECT 1,
bug_status,
resolution,
short_desc,
$milestone_column,
assignee.userid,
@@ -160,6 +161,7 @@ sub GetBug {
($bug->{'exists'},
$bug->{'status'},
$bug->{'resolution'},
$bug->{'summary'},
$bug->{'milestone'},
$bug->{'assignee_id'},

View File

@@ -25,135 +25,121 @@
[% PROCESS global/header.html.tmpl
title = "Dependency tree for $terms.Bug $bugid"
h1 = "Dependency tree for <a href=\"show_bug.cgi?id=$bugid\">$terms.Bug $bugid</a>"
h1 = "Dependency tree for
<a href=\"show_bug.cgi?id=$bugid\">$terms.Bug $bugid</a>"
javascript_urls = ["js/expanding-tree.js"]
style_urls = ["css/dependency-tree.css"]
%]
[% PROCESS depthControlToolbar %]
[%# Display the tree of bugs that this bug depends on. %]
<h3>
[% IF hide_resolved %]
Open [% terms.bugs %]
[% ELSE %]
[% terms.Bugs %]
[% END %]
that <a href="show_bug.cgi?id=[% bugid %]">[% terms.bug %] [%+ bugid %]</a>
depends on</h3>
[% IF dependson_ids.size > 0 %]
(
[% IF maxdepth -%]Up to [% maxdepth %] level[% "s" IF maxdepth > 1 %] deep | [% END %]
<a href="buglist.cgi?bug_id=[% dependson_ids.join(",") %]">view as [% terms.bug %] list</a>
[% IF canedit && dependson_ids.size > 1 %]
| <a href="buglist.cgi?bug_id=[% dependson_ids.join(",") %]&amp;tweak=1">change several</a>
[% END %])
[% INCLUDE display_tree tree=dependson_tree bug_id=bugid %]
[% ELSE %]
</h3>
<p>None</p>
[% END %]
[% INCLUDE tree_section ids=dependson_ids bugid=bugid
tree_name="dependson_tree" text="depends on" %]
[%# Display the tree of bugs that this bug blocks. %]
<h3>
[% IF hide_resolved %]
Open [% terms.bugs %]
[% ELSE %]
[% terms.Bugs %]
[% END %]
that <a href="show_bug.cgi?id=[% bugid %]">[% terms.bug %] [%+ bugid %]</a>
blocks</h3>
[% IF blocked_ids.size > 0 %]
(
[% IF maxdepth -%]Up to [% maxdepth %] level[% "s" IF maxdepth > 1 %] deep | [% END %]
<a href="buglist.cgi?bug_id=[% blocked_ids.join(",") %]">view as [% terms.bug %] list</a>
[% IF canedit && blocked_ids.size > 1 %]
| <a href="buglist.cgi?bug_id=[% blocked_ids.join(",") %]&amp;tweak=1">change several</a>
[% END %])
[% INCLUDE display_tree tree=blocked_tree bug_id=bugid %]
[% ELSE %]
</h3>
<p>None</p>
[% END %]
[% INCLUDE tree_section ids=blocked_ids bugid=bugid
tree_name="blocked_tree" text = "blocks" %]
[% PROCESS depthControlToolbar %]
<div class="hint">
<h3>Usage Hints</h3>
<ul>
<li>Click on expander icons to expand or contract a portion of the tree.
<li>Control-clicking on expander icons performs a "deep" change:<br>
all children [% terms.bugs %] are also expanded or contracted accordingly.
</ul>
</div>
[% PROCESS global/footer.html.tmpl %]
[%###########################################################################%]
[%# Tree-drawing blocks #%]
[%###########################################################################%]
[%###########################################################################%]
[%# Block to display a tree #%]
[%###########################################################################%]
[% BLOCK tree_section %]
[%# INTERFACE
# - tree_name: the name of the tree type ("dependson_tree" or "blocks_tree")
# - bugid: the ID of the toplevel bug being displayed
# - ids: a list of bug IDs to be displayed as children
# GLOBALS
# - seen: Maintains a global hash of bugs that have been displayed
#%]
[% global.seen = {} %]
[%# Display the tree of bugs that this bug depends on. %]
<h3>
[% IF hide_resolved %]
Open [% terms.bugs %]
[% ELSE %]
[% terms.Bugs %]
[%- END %]
that <a href="show_bug.cgi?id=[% bugid %]">[% terms.bug %] [%+ bugid %]</a>
[% text FILTER html %]
</h3>
[% IF ids.size > 0 %]([% IF maxdepth -%]Up to [% maxdepth %] level[% "s" IF maxdepth > 1 %] deep | [% END -%]<a href="buglist.cgi?bug_id=[% ids.join(",") %]">view as [% terms.bug %] list</a>
[% IF canedit && ids.size > 1 %]
| <a href="buglist.cgi?bug_id=[% ids.join(",") %]&amp;tweak=1">change several</a>
[% END %])
<ul class="tree">
[% INCLUDE display_tree tree=$tree_name bugid=bugid %]
</ul>
<b>Total [% terms.bugs %] displayed: [% ids.size %]</b>
<p>
[% ELSE %]
<p>None</p>
[% END %]
[% END %]
[% BLOCK display_tree %]
[% tree.$bug_id.seen = 1 %]
<ul>
[% FOREACH dep_id = tree.$bug_id.dependencies %]
[% dep = tree.$dep_id %]
<li>
[% "<script>document.write('<a href=\"#\" class=\"toggle\" onclick=\"listToggle(event); return false\">[-]</a>')</script>"
IF dep.dependencies.size > 0 && !dep.seen %]
[% isclosed = !dep.open %]
[% FILTER closed(isclosed) %]
<a href="show_bug.cgi?id=[% dep_id %]">[% dep_id %]
[[% IF dep.milestone %][% dep.milestone FILTER html %], [% END %]
[% dep.assignee_email FILTER html %]] -
[% IF dep.seen %]
<i>This [% terms.bug %] appears elsewhere in this tree.</i></a>
[% ELSE %]
[% dep.summary FILTER html %].</a>
[%# INTERFACE
# - bugid: the ID of the bug being displayed
# - tree: a hash of bug objects
#%]
[% bug = tree.$bugid %]
<li>[%- INCLUDE bullet bugid=bugid bug=bug -%]<span class="summ[% "_deep" IF bug.dependencies.size %]">[%- INCLUDE buglink bug=bug bugid=bugid %]</span>
[% IF global.seen.$bugid %]
<b>(<a title="Already displayed above; click to locate"
href="#b[% bugid %]">*</a>)</b>
[% ELSIF bug.dependencies.size %]
<ul>
[% FOREACH depid = bug.dependencies %]
[% INCLUDE display_tree bugid=depid %]
[% END %]
[% END %]
[% INCLUDE display_tree bug_id=dep_id
IF dep.dependencies.size > 0 && !dep.seen %]
</li>
</ul>
[% END %]
</li>
[% global.seen.$bugid = 1 %]
[% END %]
[% BLOCK bullet %]
[% IF bug.dependencies.size > 0 && ! global.seen.$bugid %]
[% extra_class = " b_open" %]
[% extra_args = 'href="#" onclick="return doToggle(this, event)"' %]
[% END %]
</ul>
<a name="b[% bugid %]" class="b [%+ extra_class %]" [% extra_args %]>&nbsp;</a>
[% END %]
[% BLOCK buglink %]
[% isclosed = !bug.open %]
[% FILTER closed(isclosed) -%]<a title="[% INCLUDE buginfo bug=bug %]" href="show_bug.cgi?id=[% bugid %]"><b>[% terms.bug %] [%+ bugid %]</b></a>[% END %]<span class="summ_text">: [%+ bug.summary FILTER html %]</span><span class="summ_info">[[% INCLUDE buginfo %]]</span>
[% END %]
[% BLOCK buginfo %]
[% bug.status FILTER html %]
[%+ bug.resolution FILTER html %]; assigned to [% bug.assignee_email FILTER html %];
[% "Target: " _ bug.milestone IF bug.milestone %]
[% END %]
[%###########################################################################%]
[%# Block for depth control toolbar #%]
[%###########################################################################%]
<script type="text/javascript" language="JavaScript">
if (!Node) {
/* MSIE doesn't define Node, so provide a compatibility array */
var Node = { TEXT_NODE: 3, };
}
function toggleDisplay(node)
{
var display = node.style.display;
if (display == "none") {
node.style.display =
("oldDisplay" in node) ? node.oldDisplay : "block";
return true;
}
node.oldDisplay = display;
node.style.display = "none";
return false;
}
function listToggle(event)
{
var node = event.target;
if (node.nodeType == Node.TEXT_NODE)
node = node.parentNode;
var toggle = node.nextSibling;
while (toggle && toggle.tagName != "UL")
toggle = toggle.nextSibling;
if (toggle) {
node.firstChild.data = toggleDisplay(toggle) ? "[-]" : "[+]";
}
}
</script>
[% BLOCK depthControlToolbar %]
<table cellpadding="3" border="0" cellspacing="0" bgcolor="#d0d0d0">
<table cellpadding="3" border="0" cellspacing="0" bgcolor="#e0e0e0">
<tr>
[%# Hide/show resolved button
Swaps text depending on the state of hide_resolved %]
<td align="center">
<form method="get" action="showdependencytree.cgi"
<form method="get" action="showdependencytree.cgi"
style="display: inline; margin: 0px;">
<input name="id" type="hidden" value="[% bugid %]">
[% IF maxdepth %]
@@ -162,7 +148,7 @@ function listToggle(event)
<input type="hidden" name="hide_resolved" value="[% hide_resolved ? 0 : 1 %]">
<input type="submit"
value="[% IF hide_resolved %]Show[% ELSE %]Hide[% END %] Resolved">
</form>
</form>
</td>
<td>
@@ -228,8 +214,7 @@ function listToggle(event)
[% END %]
<input name="hide_resolved" type="hidden" value="[% hide_resolved %]">
<input type="submit" value="&nbsp;&gt;&nbsp;"
[% "disabled" IF realdepth < 2 || !maxdepth || maxdepth >= realdepth %]
%]>
[% "disabled" IF realdepth < 2 || !maxdepth || maxdepth >= realdepth %]>
</form>
</td>

View File

@@ -323,10 +323,8 @@
'bug/dependency-tree.html.tmpl' => [
'bugid',
'maxdepth',
'dependson_ids.join(",")',
'blocked_ids.join(",")',
'dep_id',
'hide_resolved',
'ids.join(",")',
'maxdepth + 1',
'maxdepth > 0 && maxdepth <= realdepth ? maxdepth : ""',
'maxdepth == 1 ? 1