What if I don't want events I've already seen to take up so much space when I view a case? - FogBugz Knowledge Exchange most recent 30 from http://fogbugz.stackexchange.com2013-05-24T16:37:03Zhttp://fogbugz.stackexchange.com/feeds/question/3242http://www.creativecommons.org/licenses/by-nc/2.5/rdfhttp://fogbugz.stackexchange.com/questions/3242/what-if-i-dont-want-events-ive-already-seen-to-take-up-so-much-space-when-i-vieWhat if I don't want events I've already seen to take up so much space when I view a case?Daniel LeCheminant2010-06-04T00:57:10Z2013-04-12T07:27:13Z
<p>When I look at a case with a lot of events, it can be overwhelming.</p>
<p>Is there a way to make it so that events that I've already seen are hidden (or at least truncated)?</p>
http://fogbugz.stackexchange.com/questions/3242/what-if-i-dont-want-events-ive-already-seen-to-take-up-so-much-space-when-i-vie/3243#3243Answer by Daniel LeCheminant for What if I don't want events I've already seen to take up so much space when I view a case?Daniel LeCheminant2010-06-04T01:10:02Z2011-09-27T11:28:45Z<p>The following <a href="http://fogbugz.stackexchange.com/questions/3183/bugmonkey-how-do-i-get-started" rel="nofollow">BugMonkey</a> script shows one way to have more control over which/how case events are displayed:</p>
<pre><code>// Provide a menu on case view that allows you to do one of the following:
// View all events
// Show all events as one-line summaries
// Show seen events as one-line summaries
// Hide seen events
$(document).ready(function() {
// Don't do anything unless we're looking at a single bug
if (!window.goBug ||
!$("#bugviewContainer").length ||
$("#miniBugList").length)
return;
// The text displayed in the display menu
var modes = {
showAll: {
text: "Show All",
label: "Showing all events",
show: ".bugevent"
},
summarizeAll: {
text: "Summarize All",
label: "Summarizing all events",
show: ".small-summary"
},
summarizeSeen: {
text: "Summarize Seen",
label: "Summarizing #seen events",
show: ".bugevent:not(.seen),.small-summary.seen"
},
hideSeen: {
text: "Hide Seen",
label: "Hiding #seen events",
show: ".bugevent:not(.seen)"
}
};
// The name of the cookie used to save settings
var sCookie = "sSeenEventMode";
// Read the user's current settings. Default is to show all
var sSeenMode = getCookie(sCookie) || "showAll";
// Determine the last event the user saw
var ixLastView = goBug.ixBugEventLastView;
// A table describing the translation from a standard bug event
// to its summary
var summTrans = [
{ sel: ".action", color: "#000", css: { "font-weight": "bold"} },
{ sel: ".date a", color: "#68615e" },
{ fnHtml: function(ev) {
return (ev.find(".emailBody").html() || ev.find(".body").html() || "").
replace(/<[^>]*>/g, " ");
}, color: "#888"
},
{ sel: ".changes", color: "#aaa" }
];
var jAllEvents = $("#BugEvents .bugevent");
// Process bug events we've already seen
var numSeen =
jAllEvents
// Filter out events we haven't seen
.filter(function() {
return /\d+/.exec($(this).attr("id")) <= ixLastView;
})
.addClass("seen")
.length;
// Process all visible bug events
jAllEvents
.each(function() {
var ev = $(this);
// Create the event summary
var divSummary = $("<div>")
.addClass("small-summary")
.css({
"white-space": "nowrap",
overflow: "hidden",
"text-overflow": "ellipsis",
"font-size": "10px",
"margin-bottom": "4px",
"cursor": "pointer"
})
.insertBefore(this)
.click(function() {
// Clicking anywhere on the summary hides it
// and displays the full bug event
$(this).hide().next(".bugevent").show();
});
if (ev.hasClass("seen")) divSummary.addClass("seen");
// Convert the bug event into a summary
$.each(summTrans, function(ix, tbl) {
var entry = $("<span>")
.css(tbl.css)
.css({
color: tbl.color,
"margin-right": "4px"
})
.appendTo(divSummary);
if (tbl.fnHtml)
entry.html(tbl.fnHtml(ev));
else
entry.text(ev.find(tbl.sel).text())
});
});
var divMenu = $("<div>")
.css({
"margin-bottom": "1em",
border: "1px dotted #888",
padding: "4px",
"background-color": "#f4f4f4"
})
.insertBefore("#BugEvents");
var spanLabel = $("<span>")
.css({
"font-weight": "bold",
"float": "right"
})
.appendTo(divMenu);
// Set the display mode
var setMode = function(ev, sMode) {
// If this is being used as an event handler,
// get the mode from the link that was clicked
sMode = sMode || $(this).attr("mode");
// Don't underline the link that represents the current display mode
divMenu.find("a")
.css("text-decoration", function() {
return $(this).attr("mode") == sMode ? "none" : "underline";
});
// Only show the events/summaries allowed by the user's selection
$("#BugEvents").find(".bugevent,.small-summary")
.hide()
.filter(modes[sMode].show)
.show();
// Update the label
spanLabel.html(modes[sMode].label.replace(/#seen/g, numSeen));
// Remember the user's selection
setCookie(sCookie, sMode);
};
// Add the display modes to the menu
for (var mode in modes) {
$("<a>")
.text(modes[mode].text)
.css("margin", ".5em")
.attr({ href: "javascript:void(0)", mode: mode })
.appendTo(divMenu)
.click(setMode);
}
// Apply the user's saved mode
setMode(null, sSeenMode);
});
</code></pre>
<p>If you'd like to use the code as is, you can use the <a href="http://closure-compiler.appspot.com/home" rel="nofollow">Closure</a> compiled version:</p>
<pre><code>$(document).ready(function(){if(!(!window.goBug||!$("#bugviewContainer").length||$("#miniBugList").length)){var e={showAll:{text:"Show All",label:"Showing all events",show:".bugevent"},summarizeAll:{text:"Summarize All",label:"Summarizing all events",show:".small-summary"},summarizeSeen:{text:"Summarize Seen",label:"Summarizing #seen events",show:".bugevent:not(.seen),.small-summary.seen"},hideSeen:{text:"Hide Seen",label:"Hiding #seen events",show:".bugevent:not(.seen)"}},i=getCookie("sSeenEventMode")||
"showAll",j=goBug.ixBugEventLastView,k=[{sel:".action",color:"#000",css:{"font-weight":"bold"}},{sel:".date a",color:"#68615e"},{fnHtml:function(b){return(b.find(".emailBody").html()||b.find(".body").html()||"").replace(/<[^>]*>/g," ")},color:"#888"},{sel:".changes",color:"#aaa"}],c=$("#BugEvents .bugevent"),l=c.filter(function(){return/\d+/.exec($(this).attr("id"))<=j}).addClass("seen").length;c.each(function(){var b=$(this),a=$("<div>").addClass("small-summary").css({"white-space":"nowrap",overflow:"hidden",
"text-overflow":"ellipsis","font-size":"10px","margin-bottom":"4px",cursor:"pointer"}).insertBefore(this).click(function(){$(this).hide().next(".bugevent").show()});b.hasClass("seen")&&a.addClass("seen");$.each(k,function(n,d){var g=$("<span>").css(d.css).css({color:d.color,"margin-right":"4px"}).appendTo(a);d.fnHtml?g.html(d.fnHtml(b)):g.text(b.find(d.sel).text())})});var f=$("<div>").css({"margin-bottom":"1em",border:"1px dotted #888",padding:"4px","background-color":"#f4f4f4"}).insertBefore("#BugEvents"),
m=$("<span>").css({"font-weight":"bold","float":"right"}).appendTo(f);c=function(b,a){a=a||$(this).attr("mode");f.find("a").css("text-decoration",function(){return $(this).attr("mode")==a?"none":"underline"});$("#BugEvents").find(".bugevent,.small-summary").hide().filter(e[a].show).show();m.html(e[a].label.replace(/#seen/g,l));setCookie("sSeenEventMode",a)};for(var h in e)$("<a>").text(e[h].text).css("margin",".5em").attr({href:"javascript:void(0)",mode:h}).appendTo(f).click(c);c(null,i)}});
</code></pre>
http://fogbugz.stackexchange.com/questions/3242/what-if-i-dont-want-events-ive-already-seen-to-take-up-so-much-space-when-i-vie/10112#10112Answer by Michel de Ruiter for What if I don't want events I've already seen to take up so much space when I view a case?Michel de Ruiter2012-03-14T09:21:47Z2013-04-12T07:27:13Z<p>I took Daniel's version and tried to improve on it over time.</p>
<p>Major new features:</p>
<ul>
<li>summary tooltips</li>
<li>easily expand, collapse or hide individual events</li>
<li>integrated <a href="http://fogbugz.stackexchange.com/questions/6302/how-to-show-all-quoted-texts/6303#6303" rel="nofollow">Toggle quoted texts</a> link</li>
<li>border color makes unseen events stand out</li>
</ul>
<p>Minor improvements and fixes:</p>
<ul>
<li>changed to BugMonkey 2 format</li>
<li>compatible with Tidy Case Events and Case Event Merge plugins</li>
<li>works with recent FogBugz (.summary, jQuery version)</li>
<li>compatible with minor, pseudo and borrowed events</li>
<li>updates on edits</li>
<li>added extra counts</li>
<li>changed Summarize All position</li>
</ul>
<p>I tested it with recent versions of FogBugz: I might have broken older versions.</p>
<p>Hope this helps. At least I find it <strong>very</strong> useful!</p>
<p>Screen shot:
<img src="http://d.sentient.nl/Files/fogbugz.4.112428.1/SummarizeEvents.png" alt="alt text"></p>
<pre><code>name: Summarize Events
description: Add menu to case to summarize/hide seen events or summarize/show all events
author: Daniel LeCheminant, Michel de Ruiter
version: 1.2.7.0
js:
if (!window.goBug || !$("#bugviewContainer").length || $("#miniBugList").length)
return; // Don't do anything unless we're looking at a single bug :-(
var modes = { // The text displayed in the display menu
showAll: {
text: "Show All",
label: "Showing all #all (seen #seen)",
show: ".bugevent:not(.minor),.pseudobugevent,.small-summary.minor"
},
summarizeSeen: {
text: "Summarize Seen",
label: "Summarizing #seen of #all",
show: ".bugevent:not(.seen),.small-summary.seen:not(.minor,.SOcollapsed)"
},
hideSeen: {
text: "Hide Seen",
label: "Hiding #seen of #all",
show: ".bugevent:not(.seen)"
},
space1: {
text: ""
},
summarizeAll: {
text: "Summarize All",
label: "Summarizing all #alls (seen #seen)",
show: ".small-summary:not(.SOcollapsed)"
},
space2: {
text: ""
}
};
var summTrans = [ // A table describing the translation from a standard bug event to its summary
{ sel: ".action", color: "#000", css: { "font-weight": "bold"} },
{ sel: ".date a", color: "#68615e" },
{ fnHtml: function(ev) {
return (ev.find(".emailBody").html() || ev.find(".body").html() || "").replace(/<[^>]*>/g, " ");
}, color: "#888" },
{ sel: ".changes", color: "#aaa" }
];
$.fn.textNodes = function() {
var ret = [];
(function(el) {
if (el === undefined) // Necessary when "Not showing ... additional events"
return;
if (el.nodeType == 3)
ret.push(el.innerHTML || el.textContent || "");
else
for (var i = 0; i < el.childNodes.length; ++i)
arguments.callee(el.childNodes[i]);
})(this[0]);
return ret;
}
var sCookie = "sSeenEventMode"; // Name of the cookie used to save settings
$("#BugEvents > .bugevent:hidden").addClass("minor"); // Initially hidden events are 'minor' ones.
function doIt(sCommand) {
var sSeenMode = getCookie(sCookie) || "showAll"; // Default to all
var jAllEvents = $("#BugEvents .summary").parent();
var numAll = jAllEvents.length;
var ixLastView = goBug.ixBugEventLastView; // Determine the last event the user saw.
var jSeen = jAllEvents.filter(function() { // Process bug events we've already seen.
return /\d+/.exec($(this).attr("id") || "0") <= ixLastView; // Pseudo events are always 'seen',
});
if (jSeen.length < numAll)
jSeen = jSeen.add('.borrowed .bugevent'); // as are old events 'borrowed' from duplicates.
var numSeen = jSeen.addClass("seen").length;
var numHidden = $("#BugEvents .bugevent.minor:not(.seen)").length;
$('div.small-summary').remove(); // Remove any existing ones
jAllEvents.each(function() { // Process all visible bug events
var ev = $(this); // Create the event summary:
var txt = ev.find(".body").clone();
txt.find("script,.showQuote,pre.linenos,.emailActionsMore").remove();
txt.find(".emailHeaderName").each(function(i) {
$(this).replaceWith($(this).text() + " " + $(this).next().remove().text());
});
txt.find(".codesnippet").each(function(i) {
$(this).find("br").replaceWith("\n");
$(this).replaceWith($(this).find(".prettyprint").text());
});
txt.find("br").remove();
txt = txt.textNodes();
$.each(txt, function(i, v) {
txt[i] = v.replace(/^\n/, "");
});
txt = $.makeArray(txt);
txt = txt.join("\n");
txt = txt.replace(/\s+$/g, "");
txt = txt.replace(/^\s+/g, "");
txt = txt.replace(/[ \t\xA0]+$/mg, "");
txt = txt.replace(/\n\n+$/mg, "\n");
var divSummary = $("<div>").addClass("small-summary").attr("title", txt).css({
"white-space": "nowrap",
"overflow": "hidden",
"text-overflow": "ellipsis",
"font-size": "10px",
"margin-bottom": "3px",
"cursor": "pointer"
}).insertBefore(this)
.click(function() { // Clicking the summary hides it and displays the full bug event
$(this).hide().next(".bugevent,.pseudobugevent").show();
});
if (ev.hasClass("minor"))
divSummary.addClass("minor");
if (ev.hasClass("seen"))
divSummary.addClass("seen");
if (ev.has('input.scratchedOutFlagScratch').length > 0)
divSummary.addClass("SOcollapsed");
$.each(summTrans, function(ix, tbl) { // Convert the bug event into a summary
var entry = $("<span>").css({
"color": tbl.color,
"margin-right": "4px"
}).appendTo(divSummary);
if (tbl.css)
entry.css(tbl.css);
if (tbl.fnHtml)
entry.html(tbl.fnHtml(ev));
else
entry.text(ev.find(tbl.sel).text());
});
});
$("#BugEvents .summary").filter(":not(:has(.topright))").prepend($("<div>").addClass("topright")
.append($("<a>").text("\u2014").attr("title", "Summarize").click(function() {
$(this).closest(".summary").parent().hide().prev(".small-summary").show();
}))
.append($("<a>").text("\xD7").attr("title", "Hide").click(function() {
$(this).closest(".summary").parent().hide();
})));
$('div#summarize').remove(); // Remove any existing one
var divMenu = $("<div>").attr("id", "summarize").css({
"margin-bottom": "6px",
"border": "1px dotted #888",
"padding": "4px",
"background-color": "#f4f4f4"
}).insertBefore("#BugEvents");
var spanLabel = $("<span>").css({
"font-weight": "bold",
"float": "right"
}).appendTo(divMenu);
var setMode = function(ev, sMode) { // Set the display mode
// If this is being used as an event handler, get the mode from the link that was clicked
sMode = sMode || $(this).attr("mode");
// Don't underline the link that represents the current display mode
divMenu.find("a").css("text-decoration", function() {
return $(this).attr("mode") == sMode ? "none" : "underline";
});
// Only show the events/summaries allowed by the user's selection
$("#BugEvents").find(".bugevent,.pseudobugevent,.small-summary")
.hide().filter(modes[sMode].show).show();
spanLabel.html(modes[sMode].label
.replace(/#seen/g, numSeen)
.replace(/#all/g, numAll)
.replace(/#hidden/g, numHidden));
setCookie(sCookie, sMode); // Remember the user's selection
};
for (var mode in modes) { // Add the display modes to the menu
$("<a>").text(modes[mode].text).css("margin", ".5em")
.attr({ href: "javascript:void(0)", mode: mode })
.appendTo(divMenu).click(setMode);
}
var quotedTexts = $(".showQuote > a[href='#'][onclick]");
if (quotedTexts.length > 0) {
$("<a>").text("Toggle quoted texts").css("margin", ".5em")
.attr("title", quotedTexts.length)
.attr("href", "javascript:void(0)").appendTo(divMenu)
.click(function() {
$(".showQuote > a[href='#'][onclick]").each(function(){ this.onclick(); });
});
}
if (sCommand == 'load')
setMode(null, sSeenMode); // Apply the user's saved mode
}
doIt($("#sEventEdit").length > 0 ? "new" : "load");
$(window).on("BugViewChange", function(e, data) { doIt(data.sCommand); });
// Work around ListBrowser skipping hidden elements:
var originalFlipAttachDeleteIcons = TabManager.flipAttachDeleteIcons;
TabManager.flipAttachDeleteIcons = function(sCommand) {
var hidden = $("#BugEvents").find(".bugevent:hidden,.pseudobugevent:hidden").show();
originalFlipAttachDeleteIcons(sCommand);
hidden.hide();
};
css:
/* The Case Event Merge plugin makes this "none" by default. */
#bugviewContainer #BugEvents .borrowed .bugevent.brief { display: block; }
#bugviewContainer .bugevents .borrowed .bugevent em.borrowed { font-size: 10px; line-height: 10px; }
#bugviewContainer .bugevents .bugevent { border: 1px solid #808080 !important; }
#bugviewContainer .bugevents .pseudobugevent,
#bugviewContainer .bugevents .bugevent.seen { border: 1px solid #C0C0C0 !important; }
#bugviewContainer .bugevents .pseudobugevent.minor,
#bugviewContainer .bugevents .bugevent.minor { border: 1px solid yellow !important; }
#BugEvents .summary div.topright { float: right; }
#BugEvents .summary div.topright a { font-size: 9px; margin-left: 6px; cursor: pointer; }
#bugviewContainerTop { margin-bottom: 2px; }
</code></pre>