[Rt-commit] rt branch, 4.4/ticket-timer, created. rt-4.2.11-196-g6e38807

Shawn Moore shawn at bestpractical.com
Thu Sep 24 17:39:16 EDT 2015


The branch, 4.4/ticket-timer has been created
        at  6e38807ad91f55262c54b9800fb42b7eb159716e (commit)

- Log -----------------------------------------------------------------
commit 01d38a21c9705b78266b929906d148d9cfd2c768
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Mon Sep 21 22:08:19 2015 +0000

    Add ShowHeader for controlling inclusion of header title

diff --git a/share/html/Elements/Header b/share/html/Elements/Header
index bf3e6f9..dd54368 100644
--- a/share/html/Elements/Header
+++ b/share/html/Elements/Header
@@ -106,7 +106,9 @@
   <& /Elements/PersonalQuickbar, %ARGS &>
 </div>
 % }
+% if ($ShowTitle) {
 <div id="header"><h1><% $Title %></h1></div>
+% }
 <%INIT>
 $r->headers_out->{'Pragma'} = 'no-cache';
 $r->headers_out->{'Cache-control'} = 'no-cache';
@@ -149,6 +151,7 @@ $Focus => ''
 $Title =>  'RT'
 $Refresh => 0
 $ShowBar => 1
+$ShowTitle => 1
 $URL => undef
 $RSSAutoDiscovery => undef
 $onload => undef

commit fe41bbd8626772538efa9e03a68b1f18b897b86e
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Wed Sep 23 00:53:20 2015 +0000

    New bookmark star icons
    
        The old one does not look very modern. It's only 13x13 and is a GIF.
        The new one is 100x100 (but shrunken down by browsers) and is a PNG.

diff --git a/share/html/Ticket/Elements/Bookmark b/share/html/Ticket/Elements/Bookmark
index fa40cc1..1abb69e 100644
--- a/share/html/Ticket/Elements/Bookmark
+++ b/share/html/Ticket/Elements/Bookmark
@@ -65,9 +65,9 @@ $Toggle => 0
 % my $url = RT->Config->Get('WebPath') ."/Helpers/Toggle/TicketBookmark?id=". $id;
 <a align="right" href="<% $url %>" onclick="jQuery.get(<% $url |n,j %>, function(data){ jQuery('.toggle-bookmark-'+<% $id |n,j%>).replaceWith(data) }); return false;" >
 % if ( $is_bookmarked ) {
-<img src="<% RT->Config->Get('WebPath') %>/static/images/star.gif" alt="<% loc('Remove Bookmark') %>" style="border-style: none" />
+<img src="<% RT->Config->Get('WebPath') %>/static/images/star-full.png" alt="<% loc('Remove Bookmark') %>" style="border-style: none" />
 % } else {
-<img src="<% RT->Config->Get('WebPath') %>/static/images/empty_star.gif" alt="<% loc('Add Bookmark') %>" style="border-style: none" />
+<img src="<% RT->Config->Get('WebPath') %>/static/images/star-empty.png" alt="<% loc('Add Bookmark') %>" style="border-style: none" />
 % }
 </a>
 </span>
diff --git a/share/static/css/aileron/nav.css b/share/static/css/aileron/nav.css
index a35175d..d78fad2 100644
--- a/share/static/css/aileron/nav.css
+++ b/share/static/css/aileron/nav.css
@@ -117,17 +117,6 @@
  color: #000;
  }
 
-/* The bookmark star is too tall without adjusting the padding and height */
-
-.sf-menu .toggle-bookmark a {
-    padding: 0 1em;
-    height: 2.5em;
-}
-
-.sf-menu .toggle-bookmark a img {
-    padding-top: 0.6em;
-}
-
 /* Pin page menu to top left corner once you scroll past it */
 
 #page-menu.pinned {
diff --git a/share/static/css/base/misc.css b/share/static/css/base/misc.css
index a76bf00..2b4d33d 100644
--- a/share/static/css/base/misc.css
+++ b/share/static/css/base/misc.css
@@ -79,3 +79,8 @@ textarea.messagebox, #cke_Content, #cke_UpdateContent {
 .datepicker {
     width: 17em;
 }
+
+.toggle-bookmark a img {
+    height: 1em;
+    width: 1em;
+}
diff --git a/share/static/css/base/nav.css b/share/static/css/base/nav.css
index bb82861..71f305a 100644
--- a/share/static/css/base/nav.css
+++ b/share/static/css/base/nav.css
@@ -15,3 +15,12 @@
     text-align: right;
 }
 
+#li-page-bookmark .toggle-bookmark a {
+    padding: 0.5em 1em;
+}
+
+#li-page-bookmark a img {
+    height: 1.25em;
+    width: 1.25em;
+}
+
diff --git a/share/static/css/rudder/nav.css b/share/static/css/rudder/nav.css
index 907a74b..3e1be38 100644
--- a/share/static/css/rudder/nav.css
+++ b/share/static/css/rudder/nav.css
@@ -171,17 +171,6 @@
     box-shadow: 2px 2px 8px -2px #999;
 }
 
-/* The bookmark star is too tall without adjusting the padding and height */
-
-.sf-menu .toggle-bookmark a {
-    padding: 0 1em;
-    height: 2.5em;
-}
-
-.sf-menu .toggle-bookmark a img {
-    padding-top: 0.6em
-}
-
 /* Pin page menu to top left corner once you scroll past it */
 
 #page-navigation #page-menu.pinned {
diff --git a/share/static/images/empty_star.gif b/share/static/images/empty_star.gif
deleted file mode 100644
index 388e11c..0000000
Binary files a/share/static/images/empty_star.gif and /dev/null differ
diff --git a/share/static/images/star-empty.png b/share/static/images/star-empty.png
new file mode 100644
index 0000000..66e7eec
Binary files /dev/null and b/share/static/images/star-empty.png differ
diff --git a/share/static/images/star-full.png b/share/static/images/star-full.png
new file mode 100644
index 0000000..34d06dd
Binary files /dev/null and b/share/static/images/star-full.png differ
diff --git a/share/static/images/star.gif b/share/static/images/star.gif
deleted file mode 100644
index c72d4ce..0000000
Binary files a/share/static/images/star.gif and /dev/null differ
diff --git a/t/security/CVE-2012-4732-csrf-blacklist.t b/t/security/CVE-2012-4732-csrf-blacklist.t
index b20da3b..51d7412 100644
--- a/t/security/CVE-2012-4732-csrf-blacklist.t
+++ b/t/security/CVE-2012-4732-csrf-blacklist.t
@@ -18,7 +18,7 @@ ok $m->login, 'logged in';
 $m->add_header(Referer => $baseurl);
 $m->get_ok($test_page);
 $m->content_lacks("Possible cross-site request forgery");
-$m->content_contains("star.gif");
+$m->content_contains("star-full.png");
 
 # come from an external source
 $m->add_header(Referer => 'http://example.com');
@@ -36,7 +36,7 @@ $m->title_is('Possible cross-site request forgery');
 $m->follow_link(text_regex => qr{resume your request});
 $m->content_lacks("Possible cross-site request forgery");
 like($m->response->request->uri, qr{^http://[^/]+\Q$test_path\E\?CSRF_Token=\w+$});
-$m->content_contains("star.gif");
+$m->content_contains("star-empty.png");
 
 undef $m;
 done_testing;

commit 6e38807ad91f55262c54b9800fb42b7eb159716e
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Wed Sep 23 00:54:19 2015 +0000

    Dialog for tracking and submitting time worked on tickets

diff --git a/share/html/Elements/Tabs b/share/html/Elements/Tabs
index afdced1..d38c48d 100644
--- a/share/html/Elements/Tabs
+++ b/share/html/Elements/Tabs
@@ -631,7 +631,8 @@ my $build_main_nav = sub {
             if ( $obj and $obj->id ) {
                 my $actions = PageMenu()->child( actions => title => loc('Actions'), sort_order  => 95 );
                 my $tabs = PageMenu();
-                $tabs->child( bookmark => raw_html => $m->scomp( '/Ticket/Elements/Bookmark', id => $id ), sort_order => 99 );
+                $tabs->child( bookmark => raw_html => $m->scomp( '/Ticket/Elements/Bookmark', id => $id ), sort_order => 98 );
+                $tabs->child( timer => raw_html => $m->scomp( '/Ticket/Elements/PopupTimerLink', id => $id ), sort_order => 99 );
                 $tabs->child( display => title => loc('Display'), path => "/Ticket/Display.html?id=" . $id );
                 $tabs->child( history => title => loc('History'), path => "/Ticket/History.html?id=" . $id );
 
diff --git a/share/html/NoAuth/css/web2/AfterMenus b/share/html/Helpers/AddTimeWorked
similarity index 62%
copy from share/html/NoAuth/css/web2/AfterMenus
copy to share/html/Helpers/AddTimeWorked
index 9c075bf..4e92123 100644
--- a/share/html/NoAuth/css/web2/AfterMenus
+++ b/share/html/Helpers/AddTimeWorked
@@ -45,30 +45,38 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<script type="text/javascript">
-var initMenus = function() {
-    jQuery("#quick-personal").append('<ul id="prefs-menu"></ul>');
-    jQuery("#li-preferences").detach().appendTo("#prefs-menu");
-    jQuery("#li-tools-config").detach().appendTo("#app-nav");
-    jQuery("#li-search-simple").detach().insertBefore("#li-search");
-    jQuery("#li-tools-approval").detach().appendTo("#app-nav");
+<%ARGS>
+$id
+$seconds => 0
+</%ARGS>
+<%INIT>
+my $Ticket = RT::Ticket->new($session{'CurrentUser'});
+$Ticket->Load( $id );
 
-    jQuery("#li-page-bookmark").detach().appendTo("#li-page-actions>ul");
-    jQuery("#li-page-actions>ul").attr("id","page-action-menu").detach().insertAfter("#topactions");
+# round up 30s or more
+my $minutes = int(0.5 + $seconds / 60);
 
-    jQuery.fn.supersubs.defaults = {
-        maxWidth: 30,
-        extraWidth: 2
-    };
+my ($ok, $msg);
+if ($minutes == 0) {
+    # avoid "That is already the current value" error
+    $ok = 1;
+    $msg = loc("Worked [quant,_1,minute,minutes]", 0);
+}
+else {
+    my $total_worked = $Ticket->TimeWorked + $minutes;
+    ($ok, $msg) = $Ticket->SetTimeWorked($total_worked);
 
-    jQuery("#page-menu.toplevel").addClass("sf-menu sf-js-enabled").supersubs().superfish({ dropShadows: false, speed: 'fast' }).supposition();
-    jQuery("#app-nav.toplevel").addClass("sf-menu sf-vertical sf-js-enabled").supersubs().superfish({ speed: 'fast' }).supposition();
-    jQuery("#prefs-menu").addClass("sf-menu sf-js-enabled").supersubs().superfish().supposition({ speed: 'fast' });
-};
+    if ($ok) {
+        if ($minutes < 60) {
+            $msg = loc("Worked [quant,_1,minute,minutes]", $minutes);
+        }
+        else {
+            $msg = loc("Worked [quant,_1,hour,hours] ([quant,_2,minute,minutes])", sprintf("%.2f", $minutes / 60), $minutes);
+        }
+    }
+}
 
-// If everything is loaded, init NOW.  Otherwise, defer to DOM ready.
-if (jQuery.fn.supersubs && jQuery.fn.superfish && jQuery.fn.supposition)
-    initMenus();
-else
-    jQuery(initMenus);
-</script>
+$r->content_type('application/json; charset=utf-8');
+$m->print(JSON({ ok => $ok, msg => $msg }));
+$m->abort;
+</%INIT>
diff --git a/share/html/Helpers/TicketTimer b/share/html/Helpers/TicketTimer
new file mode 100644
index 0000000..fb5c800
--- /dev/null
+++ b/share/html/Helpers/TicketTimer
@@ -0,0 +1,196 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%ARGS>
+$id
+</%ARGS>
+<%INIT>
+my $Ticket = RT::Ticket->new($session{'CurrentUser'});
+$Ticket->Load( $id );
+
+my $unpause_img = RT->Config->Get('WebPath') . '/static/images/unpause.png';
+my $pause_img   = RT->Config->Get('WebPath') . '/static/images/pause.png';
+
+my $now = RT::Date->new($session{'CurrentUser'});
+$now->SetToNow;
+
+my $submit_url = RT->Config->Get('WebPath') . '/Helpers/AddTimeWorked';
+</%INIT>
+<& /Elements/Header, Title => loc('Timer for #[_1]: [_2]', $Ticket->Id, $Ticket->Subject), RichText => 0, ShowBar => 0, ShowTitle => 0 &>
+
+<script type="text/javascript">
+jQuery( function() {
+    var Interval;
+    var Seconds = 0;
+
+    var readout = jQuery('.readout');
+    var playpause = jQuery('.playpause');
+    var playpause_img = playpause.find('img');
+
+    var pause_alt = playpause_img.attr('alt');
+    var unpause_alt = playpause_img.data('toggle-alt');
+
+    var toHHMMSS = function (total) {
+        var hours   = Math.floor(total / 3600);
+        var minutes = Math.floor((total - (hours * 3600)) / 60);
+        var seconds = total - (hours * 3600) - (minutes * 60);
+
+        if (minutes < 10) { minutes = "0" + minutes; }
+        if (seconds < 10) { seconds = "0" + seconds; }
+
+        return hours + ':' + minutes + ':' + seconds;
+    };
+
+    var renderReadout = function (seconds) {
+        readout.text(toHHMMSS(seconds));
+    };
+
+    var tick = function () {
+        Seconds++;
+        renderReadout(Seconds);
+    };
+
+    jQuery('.playpause').click(function () {
+        if (Interval) {
+            // pause
+            clearInterval(Interval);
+            Interval = false;
+            playpause_img.attr('src', <% $unpause_img |n,j %>);
+            playpause_img.attr('alt', unpause_alt);
+            playpause_img.attr('title', unpause_alt);
+        }
+        else {
+            // unpause
+            Interval = setInterval(tick, 1000);
+            playpause_img.attr('src', <% $pause_img |n,j %>);
+            playpause_img.attr('alt', pause_alt);
+            playpause_img.attr('title', pause_alt);
+        }
+        return false;
+    });
+
+    jQuery('.submit-time').click(function () {
+        clearInterval(Interval);
+        jQuery('.control-line a').hide();
+
+        var payload = {
+            id: <% $Ticket->id %>,
+            seconds: Seconds
+        };
+
+        readout.text('<% loc("Submitting") %>');
+
+        var renderSubmitError = function (reason) {
+            renderReadout(Seconds);
+            jQuery('.ticket-timer').addClass('error');
+
+            // give the browser a chance to redraw the readout
+            setTimeout(function () {
+                alert('<% loc("Unable to submit time. Please add it to the ticket manually. Reason:") %>' + ' ' + reason);
+            }, 100);
+        };
+
+        jQuery.ajax({
+            url: <% $submit_url |n,j %>,
+            data: payload,
+            timeout: 30000, /* 30 seconds */
+            success: function (response) {
+                if (response.ok) {
+                    readout.text(response.msg);
+                    jQuery('.control-line .close-popup').show().removeClass('hidden');
+                }
+                else {
+                    renderSubmitError(response.msg);
+                }
+            },
+            error: function (xhr, reason) {
+                renderSubmitError(reason);
+            }
+        });
+
+        return false;
+    });
+
+    jQuery('.close-popup').click(function () {
+        window.close();
+        return false;
+    });
+
+    renderReadout(Seconds);
+    Interval = setInterval(tick, 1000);
+});
+</script>
+
+<div class="ticket-timer">
+    <div class="ticket-link">
+        <a target="_blank" href="<%RT->Config->Get('WebPath')%>/Ticket/Display.html?id=<%$Ticket->Id%>">
+            <img src="<% RT->Config->Get('WebPath') %>/static/images/stopwatch.png" alt="<% loc('Stopwatch') %>" />
+            <%$Ticket->Id%>: <%$Ticket->Subject%>
+        </a>
+    </div>
+
+    <div class="gutter">
+        <div class="readout"></div>
+
+        <div class="control-line">
+            <a href="#" class="playpause"><img src="<% $pause_img %>" alt="<% loc('Pause Timer') %>" data-toggle-alt="<% loc('Unpause Timer') %>" title="<% loc('Pause Timer') %>" /></a>
+            <a href="#" class="submit-time"><img src="<% RT->Config->Get('WebPath') %>/static/images/submit.png" alt="<% loc('Submit Timer') %>" alt="<% loc('Submit Timer') %>" /></a>
+            <a href="#" class="close-popup hidden"><img src="<% RT->Config->Get('WebPath') %>/static/images/close.png" alt="<% loc('Close Window') %>" title="<% loc('Close Window') %>" /></a>
+        </div>
+    </div>
+
+    <div class="extra"><&|/l, $now->AsString &>Started at [_1].</&></div>
+
+% if ($Ticket->TimeEstimated) {
+    <div class="extra"><&|/l&>Time estimated</&>: <& /Ticket/Elements/ShowTime, minutes => $Ticket->TimeEstimated &></div>
+% }
+
+    <div class="on-error"><&|/l&>An error occurred while submitting time. Please submit your time manually.</&></div>
+
+</div>
+
+% $m->abort();
diff --git a/share/html/NoAuth/css/web2/AfterMenus b/share/html/NoAuth/css/web2/AfterMenus
index 9c075bf..f7d3db0 100644
--- a/share/html/NoAuth/css/web2/AfterMenus
+++ b/share/html/NoAuth/css/web2/AfterMenus
@@ -54,6 +54,7 @@ var initMenus = function() {
     jQuery("#li-tools-approval").detach().appendTo("#app-nav");
 
     jQuery("#li-page-bookmark").detach().appendTo("#li-page-actions>ul");
+    jQuery("#li-page-timer").detach().appendTo("#li-page-actions>ul");
     jQuery("#li-page-actions>ul").attr("id","page-action-menu").detach().insertAfter("#topactions");
 
     jQuery.fn.supersubs.defaults = {
diff --git a/share/html/NoAuth/css/web2/AfterMenus b/share/html/Ticket/Elements/PopupTimerLink
similarity index 61%
copy from share/html/NoAuth/css/web2/AfterMenus
copy to share/html/Ticket/Elements/PopupTimerLink
index 9c075bf..737641f 100644
--- a/share/html/NoAuth/css/web2/AfterMenus
+++ b/share/html/Ticket/Elements/PopupTimerLink
@@ -45,30 +45,14 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<script type="text/javascript">
-var initMenus = function() {
-    jQuery("#quick-personal").append('<ul id="prefs-menu"></ul>');
-    jQuery("#li-preferences").detach().appendTo("#prefs-menu");
-    jQuery("#li-tools-config").detach().appendTo("#app-nav");
-    jQuery("#li-search-simple").detach().insertBefore("#li-search");
-    jQuery("#li-tools-approval").detach().appendTo("#app-nav");
-
-    jQuery("#li-page-bookmark").detach().appendTo("#li-page-actions>ul");
-    jQuery("#li-page-actions>ul").attr("id","page-action-menu").detach().insertAfter("#topactions");
-
-    jQuery.fn.supersubs.defaults = {
-        maxWidth: 30,
-        extraWidth: 2
-    };
-
-    jQuery("#page-menu.toplevel").addClass("sf-menu sf-js-enabled").supersubs().superfish({ dropShadows: false, speed: 'fast' }).supposition();
-    jQuery("#app-nav.toplevel").addClass("sf-menu sf-vertical sf-js-enabled").supersubs().superfish({ speed: 'fast' }).supposition();
-    jQuery("#prefs-menu").addClass("sf-menu sf-js-enabled").supersubs().superfish().supposition({ speed: 'fast' });
-};
-
-// If everything is loaded, init NOW.  Otherwise, defer to DOM ready.
-if (jQuery.fn.supersubs && jQuery.fn.superfish && jQuery.fn.supposition)
-    initMenus();
-else
-    jQuery(initMenus);
-</script>
+<%ARGS>
+$id
+</%ARGS>
+<%INIT>
+my $url = RT->Config->Get('WebPath') . "/Helpers/TicketTimer?id=" . $id;
+</%INIT>
+<span class="timer-link">
+    <a href="<% $url %>" onclick="window.open(<% $url |n,j %>, '_blank', 'height=200,width=200'); return false;" >
+        <img src="<% RT->Config->Get('WebPath') %>/static/images/stopwatch.png" alt="<% loc('Open Timer') %>" title="<% loc('Open Timer') %>" />
+    </a>
+</span>
diff --git a/share/static/css/aileron/main.css b/share/static/css/aileron/main.css
index 202c6f8..555e080 100644
--- a/share/static/css/aileron/main.css
+++ b/share/static/css/aileron/main.css
@@ -9,4 +9,5 @@
 @import "ticket-lists.css";
 @import "ticket-search.css";
 @import "ticket.css";
+ at import "ticket-timer.css";
 @import "misc.css";
diff --git a/share/static/css/aileron/ticket-timer.css b/share/static/css/aileron/ticket-timer.css
new file mode 100644
index 0000000..2f085af
--- /dev/null
+++ b/share/static/css/aileron/ticket-timer.css
@@ -0,0 +1,27 @@
+.ticket-timer {
+    padding: 1em 1em 1em 1em;
+    -moz-border-radius-topleft: 0.5em;
+    -webkit-border-top-left-radius: 0.5em;
+    -moz-border-radius-bottomleft: 0.5em;
+    -webkit-border-bottom-left-radius: 0.5em;
+    margin-left: .25em;
+    margin-top: .25em;
+    margin-right: 0;
+    margin-bottom: 0em;
+    background: #fff;
+    border-top: 2px solid #ccc;
+    border-left: 2px solid #ccc;
+    border-radius: 0.5em 0 0 0.5em;
+}
+
+.ticket-timer .gutter {
+    background-color: #fff;
+    border-left: 1px solid #ccc;
+    border-top: 1px solid #ccc;
+    background-color: #efefef;
+    -moz-border-radius: 0.5em;
+    -webkit-border-radius: 0.5em;
+    border-bottom: 2px solid #aaa;
+    border-right: 2px solid #aaa;
+    border-radius: 0.5em;
+}
diff --git a/share/static/css/ballard/main.css b/share/static/css/ballard/main.css
index c58e3ac..55ca3dd 100644
--- a/share/static/css/ballard/main.css
+++ b/share/static/css/ballard/main.css
@@ -6,4 +6,5 @@
 @import "boxes.css";
 @import "ticket-lists.css";
 @import "ticket-search.css";
+ at import "ticket-timer.css";
 @import "misc.css";
diff --git a/share/static/css/ballard/ticket-timer.css b/share/static/css/ballard/ticket-timer.css
new file mode 100644
index 0000000..2f085af
--- /dev/null
+++ b/share/static/css/ballard/ticket-timer.css
@@ -0,0 +1,27 @@
+.ticket-timer {
+    padding: 1em 1em 1em 1em;
+    -moz-border-radius-topleft: 0.5em;
+    -webkit-border-top-left-radius: 0.5em;
+    -moz-border-radius-bottomleft: 0.5em;
+    -webkit-border-bottom-left-radius: 0.5em;
+    margin-left: .25em;
+    margin-top: .25em;
+    margin-right: 0;
+    margin-bottom: 0em;
+    background: #fff;
+    border-top: 2px solid #ccc;
+    border-left: 2px solid #ccc;
+    border-radius: 0.5em 0 0 0.5em;
+}
+
+.ticket-timer .gutter {
+    background-color: #fff;
+    border-left: 1px solid #ccc;
+    border-top: 1px solid #ccc;
+    background-color: #efefef;
+    -moz-border-radius: 0.5em;
+    -webkit-border-radius: 0.5em;
+    border-bottom: 2px solid #aaa;
+    border-right: 2px solid #aaa;
+    border-radius: 0.5em;
+}
diff --git a/share/static/css/base/main.css b/share/static/css/base/main.css
index efe2a45..9f03969 100644
--- a/share/static/css/base/main.css
+++ b/share/static/css/base/main.css
@@ -26,6 +26,7 @@
 @import "history.css";
 @import "charts.css";
 @import "chosen.css";
+ at import "ticket-timer.css";
 @import "print.css";
 @import "dropzone.css";
 @import "dropzone.customized.css";
diff --git a/share/static/css/base/nav.css b/share/static/css/base/nav.css
index 71f305a..d851259 100644
--- a/share/static/css/base/nav.css
+++ b/share/static/css/base/nav.css
@@ -15,11 +15,13 @@
     text-align: right;
 }
 
-#li-page-bookmark .toggle-bookmark a {
+#li-page-bookmark .toggle-bookmark a,
+#li-page-timer .timer-link a {
     padding: 0.5em 1em;
 }
 
-#li-page-bookmark a img {
+#li-page-bookmark a img,
+#li-page-timer a img {
     height: 1.25em;
     width: 1.25em;
 }
diff --git a/share/static/css/base/ticket-timer.css b/share/static/css/base/ticket-timer.css
new file mode 100644
index 0000000..5b27335
--- /dev/null
+++ b/share/static/css/base/ticket-timer.css
@@ -0,0 +1,56 @@
+.ticket-timer {
+    padding: 1em;
+}
+
+.ticket-timer img {
+    height: 1.5em;
+}
+
+.ticket-timer .ticket-link img {
+    height: 1em;
+}
+
+.ticket-timer .ticket-link {
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+.ticket-timer .readout {
+    font-size: 2em;
+    text-align: center;
+    width: 100%;
+}
+
+.ticket-timer .control-line {
+    text-align: center;
+}
+
+.ticket-timer .control-line a {
+    margin: 0 1em;
+}
+
+.ticket-timer .extra {
+    color: #aaa;
+}
+
+.ticket-timer > div {
+    margin-bottom: 0.4em;
+}
+
+.ticket-timer.error .readout {
+    color: red;
+}
+
+.ticket-timer.error .extra {
+    display: none;
+}
+
+.ticket-timer .on-error {
+    display: none;
+}
+
+.ticket-timer.error .on-error {
+    display: block;
+    color: red;
+}
diff --git a/share/static/css/rudder/main.css b/share/static/css/rudder/main.css
index 31bc836..d6c86be 100644
--- a/share/static/css/rudder/main.css
+++ b/share/static/css/rudder/main.css
@@ -11,6 +11,7 @@
 @import "ticket-search.css";
 @import "ticket-forms.css";
 @import "ticket.css";
+ at import "ticket-timer.css";
 @import "history.css";
 @import "admin.css";
 @import "misc.css";
diff --git a/share/static/css/rudder/ticket-timer.css b/share/static/css/rudder/ticket-timer.css
new file mode 100644
index 0000000..3381a26
--- /dev/null
+++ b/share/static/css/rudder/ticket-timer.css
@@ -0,0 +1,32 @@
+.ticket-timer {
+    padding: 0;
+}
+
+.ticket-timer .ticket-link {
+    background: #547CCC;
+    padding: 0.33em 1em;
+    margin-bottom: 0;
+}
+
+.ticket-timer .ticket-link a {
+    color: #fff;
+    font-size: 1.1em;
+    font-weight: bold;
+}
+
+/* we use background: #547CCC; to help make the ticket timer look more like RT
+   but unfortunately that makes the stopwatch icon (being black) look bad */
+.ticket-timer .ticket-link img {
+    display: none;
+}
+
+.ticket-timer .gutter {
+    border-bottom: 1px solid #ccc;
+    background-color: #eee;
+    padding: 0.5em 0;
+}
+
+.ticket-timer .extra,
+.ticket-timer .on-error {
+    padding: 0 1em;
+}
diff --git a/share/static/css/web2/main.css b/share/static/css/web2/main.css
index c58e3ac..55ca3dd 100644
--- a/share/static/css/web2/main.css
+++ b/share/static/css/web2/main.css
@@ -6,4 +6,5 @@
 @import "boxes.css";
 @import "ticket-lists.css";
 @import "ticket-search.css";
+ at import "ticket-timer.css";
 @import "misc.css";
diff --git a/share/static/css/web2/ticket-timer.css b/share/static/css/web2/ticket-timer.css
new file mode 100644
index 0000000..2f085af
--- /dev/null
+++ b/share/static/css/web2/ticket-timer.css
@@ -0,0 +1,27 @@
+.ticket-timer {
+    padding: 1em 1em 1em 1em;
+    -moz-border-radius-topleft: 0.5em;
+    -webkit-border-top-left-radius: 0.5em;
+    -moz-border-radius-bottomleft: 0.5em;
+    -webkit-border-bottom-left-radius: 0.5em;
+    margin-left: .25em;
+    margin-top: .25em;
+    margin-right: 0;
+    margin-bottom: 0em;
+    background: #fff;
+    border-top: 2px solid #ccc;
+    border-left: 2px solid #ccc;
+    border-radius: 0.5em 0 0 0.5em;
+}
+
+.ticket-timer .gutter {
+    background-color: #fff;
+    border-left: 1px solid #ccc;
+    border-top: 1px solid #ccc;
+    background-color: #efefef;
+    -moz-border-radius: 0.5em;
+    -webkit-border-radius: 0.5em;
+    border-bottom: 2px solid #aaa;
+    border-right: 2px solid #aaa;
+    border-radius: 0.5em;
+}
diff --git a/share/static/images/close.png b/share/static/images/close.png
new file mode 100644
index 0000000..cb151d3
Binary files /dev/null and b/share/static/images/close.png differ
diff --git a/share/static/images/pause.png b/share/static/images/pause.png
new file mode 100644
index 0000000..8ac7c05
Binary files /dev/null and b/share/static/images/pause.png differ
diff --git a/share/static/images/stopwatch.png b/share/static/images/stopwatch.png
new file mode 100644
index 0000000..464beb0
Binary files /dev/null and b/share/static/images/stopwatch.png differ
diff --git a/share/static/images/submit.png b/share/static/images/submit.png
new file mode 100644
index 0000000..5faa4e1
Binary files /dev/null and b/share/static/images/submit.png differ
diff --git a/share/static/images/unpause.png b/share/static/images/unpause.png
new file mode 100644
index 0000000..0315a1e
Binary files /dev/null and b/share/static/images/unpause.png differ

-----------------------------------------------------------------------


More information about the rt-commit mailing list