зеркало из https://github.com/mozilla/oldpto.git
Latest round of usability updates
git-svn-id: https://svn.mozilla.org/projects/pto/trunk@48911 4eb1ac78-321c-0410-a911-ec516a8615a5
This commit is contained in:
Родитель
fd545b3621
Коммит
a0e663c4dd
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.9 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 11 KiB |
228
css/style.css
228
css/style.css
|
@ -1,75 +1,209 @@
|
|||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: inherit;
|
||||
font-size: 100%;
|
||||
font-weight: inherit;
|
||||
font-style: inherit;
|
||||
text-decoration: none;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
html {
|
||||
font: 14px "Lucida Grande", "Lucida Sans Unicode", sans-serif;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
background: url(bg.png) #67a7c7 repeat-x fixed;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Georgia, sans-serif;
|
||||
padding: 15px;
|
||||
margin: 0;
|
||||
background: url(background.jpg) repeat-x;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
left: 10%;
|
||||
height: 47px;
|
||||
width: 0;
|
||||
padding-left: 275px;
|
||||
background: url(pto.png) no-repeat;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #acd1e3;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#page {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#page a {
|
||||
color: #0489B7;
|
||||
}
|
||||
|
||||
form {
|
||||
color: black;
|
||||
background-color: white;
|
||||
padding: 1em;
|
||||
-moz-border-radius: 0.5em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0.5em 0 1em 0;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
span.ui-timepickr {
|
||||
background-color: #FCFDFD;
|
||||
border: 1px solid #A6C9E2;
|
||||
-moz-border-radius: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
#menu {
|
||||
position: absolute;
|
||||
right: 3em;
|
||||
top: 1em;
|
||||
}
|
||||
|
||||
#menu li {
|
||||
display: inline;
|
||||
margin-left: 3em;
|
||||
}
|
||||
|
||||
#menu li a {
|
||||
color: #ACD1E3;
|
||||
}
|
||||
|
||||
#views {
|
||||
background-color: rgba(102, 204, 255, 0.5);
|
||||
padding: 0.25em 0 0.25em 0;
|
||||
}
|
||||
padding: 0.5em 0 0.5em 0;
|
||||
-moz-border-radius-topleft: 0.5em;
|
||||
-moz-border-radius-topright: 0.5em;
|
||||
-moz-user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#views li {
|
||||
display: inline;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
border-right: 1px solid black;
|
||||
}
|
||||
#views li {
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
|
||||
#views li.view {
|
||||
float: right;
|
||||
border-right: 1px solid black;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
#views li:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
#views li:first-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
#views li a {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
}
|
||||
#views li a {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
padding: 0.25em;
|
||||
}
|
||||
|
||||
#views li a:hover {
|
||||
background-color: #DDD;
|
||||
}
|
||||
|
||||
#views li a:hover {
|
||||
background-color: #DDD;
|
||||
}
|
||||
#loading {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#loading.loading {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-bottom: 4px;
|
||||
height: 0;
|
||||
padding: 0;
|
||||
padding-top: 16px;
|
||||
width: 16px;
|
||||
overflow: hidden;
|
||||
background: url(throbber.png) no-repeat;
|
||||
}
|
||||
|
||||
#formats {
|
||||
background-color: #BDDCE6;
|
||||
color: #000;
|
||||
padding: 0.5em 0.5em 0 1em;
|
||||
-moz-user-select: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#formats ul {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#formats ul li {
|
||||
display: inline;
|
||||
padding: 0.25em 1em 0.25em 1em;
|
||||
}
|
||||
|
||||
#formats ul li.active {
|
||||
background-color: white;
|
||||
-moz-border-radius-topleft: 0.4em;
|
||||
-moz-border-radius-topright: 0.4em;
|
||||
}
|
||||
|
||||
td {
|
||||
vertical-align: top;
|
||||
}
|
||||
padding: 0.25em;
|
||||
}
|
||||
|
||||
tr td:first-child label {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
#pto tr td {
|
||||
padding: 0.3em;
|
||||
}
|
||||
#pto {
|
||||
padding-top: 0.25em;
|
||||
background-color: white;
|
||||
color: black
|
||||
}
|
||||
|
||||
#pto tbody tr:nth-child(even) {
|
||||
background: rgba(192, 192, 192, 0.7);
|
||||
}
|
||||
#pto tr td {
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
||||
#pto th {
|
||||
background: rgba(128, 128, 128, 0.5) no-repeat right center;
|
||||
padding-right: 24px;
|
||||
}
|
||||
#pto tbody tr:nth-child(even) {
|
||||
background: rgba(192, 192, 192, 0.7);
|
||||
}
|
||||
|
||||
#pto th.header {
|
||||
cursor: pointer;
|
||||
background-image: url(sort.gif);
|
||||
}
|
||||
#pto th.headerSortDown { background-image: url(desc.gif); }
|
||||
#pto th.headerSortUp { background-image: url(asc.gif); }
|
||||
#pto th.headerSortDown, #pto th.headerSortUp {
|
||||
background-color: rgba(128, 128, 128, 1);
|
||||
}
|
||||
#pto th {
|
||||
background: rgba(128, 128, 128, 0.5) no-repeat right center;
|
||||
padding-right: 24px;
|
||||
}
|
||||
|
||||
#pto #no-match {
|
||||
text-align: center;
|
||||
}
|
||||
#pto th.header {
|
||||
cursor: pointer;
|
||||
background-image: url(sort.gif);
|
||||
}
|
||||
#pto th.headerSortDown { background-image: url(desc.gif); }
|
||||
#pto th.headerSortUp { background-image: url(asc.gif); }
|
||||
#pto th.headerSortDown, #pto th.headerSortUp {
|
||||
background-color: rgba(128, 128, 128, 1);
|
||||
}
|
||||
|
||||
#pto #no-match {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 8.8 KiB |
100
export.php
100
export.php
|
@ -47,15 +47,28 @@ if (function_exists($output_function)){
|
|||
|
||||
require_once "./templates/header.php";
|
||||
?>
|
||||
<h1>PTO Notifications</h1>
|
||||
<p>Herro thar, <?= email_to_alias($notifier_email) ?>.</p>
|
||||
<p>Herro thar, <?= email_to_alias($notifier_email) ?>. We've got all your PTOs right here™.</p>
|
||||
<ul id="views">
|
||||
<li><a id="view-all">All</a></li>
|
||||
<li><a id="view-today">Today</a></li>
|
||||
<li><a id="view-week">This Week</a></li>
|
||||
<li><a id="view-month">This Month</a></li>
|
||||
<li><a id="view-year">This Year</a></li>
|
||||
<li class="view"><a id="view-year">This Year</a></li>
|
||||
<li class="view"><a id="view-month">This Month</a></li>
|
||||
<li class="view"><a id="view-week">This Week</a></li>
|
||||
<li class="view"><a id="view-today">Today</a></li>
|
||||
<li class="view"><a id="view-all">All</a></li>
|
||||
<li id="range"><input type="text" id="from" size="8" /> -
|
||||
<input type="text" id="to" size="8" />
|
||||
<button id="filter">Filter</button>
|
||||
<span id="loading">Loading...</span></li>
|
||||
</ul>
|
||||
<div id="formats">
|
||||
Formats:
|
||||
<ul>
|
||||
<li class="active" title="You're lookin' at it">Table</li>
|
||||
<li><a class="format" href="?format=csv" id="format-csv" title="Good for spreadsheet software">CSV</a></li>
|
||||
<li><a class="format" href="?format=atom" id="format-atom" title="Good for feed readers">Atom</a></li>
|
||||
<li><a class="format" href="?format=ical" id="format-ical" title="Good for calendar apps">iCal</a></li>
|
||||
<li><a class="format" href="?format=json" id="format-json" title="Good for mash-ups">JSON</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="pto"></div>
|
||||
|
||||
<script type="text/javascript" src="./js/jquery.strftime-minified.js"></script>
|
||||
|
@ -63,15 +76,30 @@ require_once "./templates/header.php";
|
|||
<script type="text/javascript">
|
||||
jQuery.noConflict();
|
||||
(function($) {
|
||||
$(document).ready(function() {
|
||||
$("#view-all").click(function() { fetch(); });
|
||||
Number.prototype.toTimestamp = function() {
|
||||
return Math.round(this.valueOf() / 1000);
|
||||
};
|
||||
|
||||
var match;
|
||||
if (match = window.location.search.match(/^\?id=(\d+)/)) {
|
||||
fetch({id: match[1]});
|
||||
} else {
|
||||
$("#view-all").click(); // Fire "View All"
|
||||
}
|
||||
$(document).ready(function() {
|
||||
$("#loading").ajaxStart(function() {
|
||||
$(this).addClass("loading");
|
||||
}).ajaxStop(function() {
|
||||
$(this).removeClass("loading");
|
||||
});
|
||||
|
||||
$("#filter").click(function() {
|
||||
fire({
|
||||
from: Date.parse($("#from").val()).toTimestamp(),
|
||||
to: Date.parse($("#to").val()).toTimestamp()
|
||||
});
|
||||
});
|
||||
$("#from, #to").keypress(function(e) {
|
||||
if (e.which == 13) {
|
||||
$("#filter").click();
|
||||
}
|
||||
});
|
||||
|
||||
$("#view-all").click(function() { fetch(); });
|
||||
|
||||
$("#view-today").click(function() {
|
||||
var [from, to] = makeZeroedDates();
|
||||
|
@ -99,31 +127,57 @@ require_once "./templates/header.php";
|
|||
to.setFullYear(to.getFullYear() + 1);
|
||||
fetch({from: from, to: to});
|
||||
});
|
||||
|
||||
var match;
|
||||
if (match = window.location.search.match(/^\?id=(\d+)/)) {
|
||||
fetch({id: match[1]});
|
||||
} else {
|
||||
$("#view-month").click(); // Fire "View This Month"
|
||||
}
|
||||
});
|
||||
|
||||
function makeZeroedDates(opts) {
|
||||
opts = opts || {};
|
||||
opts.from = opts.from || new Date();
|
||||
opts.to = to || new Date();
|
||||
opts.to = opts.to || new Date();
|
||||
opts.methods = opts.methods || [];
|
||||
var methods = "Hours|Minutes|Seconds|Milliseconds".split('|');
|
||||
methods.concat.apply(methods, opts.methods).forEach(function(method) {
|
||||
if (opts.from) { opts.from["set" + method](0); }
|
||||
if (opts.to) { opts.to["set" + method](0); }
|
||||
var val = (method == "Date") ? 1 : 0;
|
||||
if (opts.from) { opts.from["set" + method](val); }
|
||||
if (opts.to) { opts.to["set" + method](val); }
|
||||
});
|
||||
return [from, to];
|
||||
return [opts.from, opts.to];
|
||||
}
|
||||
|
||||
function fetch(options) {
|
||||
options = options || {};
|
||||
if (options.from) {
|
||||
options.from = Math.floor(options.from.valueOf() / 1000);
|
||||
options.from = Math.round(options.from.valueOf() / 1000);
|
||||
}
|
||||
if (options.to) {
|
||||
options.to = Math.floor(options.to.valueOf() / 1000);
|
||||
options.to = Math.round(options.to.valueOf() / 1000);
|
||||
}
|
||||
var from = options.from ? fdate(options.from) : '';
|
||||
var to = options.to ? fdate(options.to) : '';
|
||||
$("#from").val(from);
|
||||
$("#to").val(to);
|
||||
fire(options);
|
||||
}
|
||||
|
||||
function fire(options) {
|
||||
$("#formats a.format").each(function() {
|
||||
var url = "?format=" + $(this).attr("id").replace(/^format-/, '');
|
||||
opts = $.param(options);
|
||||
$(this).attr("href", url + (opts ? '&' + opts : ''));
|
||||
});
|
||||
$.getJSON("export.php", $.extend({format: "json"}, options), inject);
|
||||
}
|
||||
|
||||
function fdate(x) {
|
||||
return $.strftime({format: '%Y/%m/%d', dateTime: new Date(x * 1000)});
|
||||
};
|
||||
|
||||
function inject(data) {
|
||||
var preferredOrder = "id|person|added|hours|start|end|details".split('|');
|
||||
var fieldNames = {
|
||||
|
@ -137,10 +191,6 @@ require_once "./templates/header.php";
|
|||
if (presentFields.indexOf(field) != -1) { fields.push(field); }
|
||||
});
|
||||
|
||||
var fdate = function(x) {
|
||||
return $.strftime({format: '%Y-%m-%d', dateTime: new Date(x * 1000)});
|
||||
};
|
||||
|
||||
var K = function(x) { return x; };
|
||||
var formatters = {
|
||||
id: K, person: function(x) x.replace(/@mozilla.*$/, ''), hours: K,
|
||||
|
|
|
@ -26,9 +26,8 @@ $notified_people[] = $manager_name ." <". $manager_email .'>';
|
|||
|
||||
require_once "./templates/header.php";
|
||||
?>
|
||||
<h1>PTO Notification</h1>
|
||||
<p>O hai, <?= email_to_alias($notifier_email) ?>. Submit your PTO notification here. <a href="https://intranet.mozilla.org/Paid_Time_Off_%28PTO%29">All your PTO are belong to us</a>.</p>
|
||||
<form action="submit.php" method="post" name="pto-notify">
|
||||
<p>O hai, <?= email_to_alias($notifier_email) ?>. Submit your PTO notification here. <a href="https://intranet.mozilla.org/Paid_Time_Off_%28PTO%29">All your PTO are belong to us</a>.</p>
|
||||
<table><tbody>
|
||||
<tr>
|
||||
<td><label for="hours">Total Hours</label></td>
|
||||
|
|
|
@ -18,6 +18,9 @@ function output_csv($data) {
|
|||
}
|
||||
|
||||
header("Content-Type: ". ($correct_mime ? "text/csv" : "text/plain"));
|
||||
if ($correct_mime) {
|
||||
header("Content-Disposition: attachment; filename=\"PTOs.csv\"");
|
||||
}
|
||||
$f = fopen("php://output", 'w');
|
||||
$fields = array("id", "person", "added", "hours", "details", "start", "end");
|
||||
fputcsv($f, array_map("ucwords", $fields));
|
||||
|
|
|
@ -16,9 +16,10 @@ foreach ($validations as $field => $pattern) {
|
|||
}
|
||||
if (!empty($failures)) {
|
||||
require_once "./templates/header.php";
|
||||
print "<h1>PTO Notifications</h1>";
|
||||
print "<form>";
|
||||
print "<p>Oh noes! The following fields weren't in the right formats!</p>";
|
||||
print "<pre>". implode(", ", $failures) ."</pre>";
|
||||
print "</form>";
|
||||
require_once "./templates/footer.php";
|
||||
die;
|
||||
}
|
||||
|
@ -127,7 +128,7 @@ if (!DISABLE_MAIL) {
|
|||
|
||||
require_once "./templates/header.php";
|
||||
?>
|
||||
<h1>PTO Notification</h1>
|
||||
<form>
|
||||
<p>
|
||||
<?php
|
||||
if ($query && $mail_result) {
|
||||
|
@ -152,5 +153,6 @@ require_once "./templates/header.php";
|
|||
print "<pre>". htmlspecialchars(implode(", ", $banned)) ."</pre>";
|
||||
}
|
||||
?>
|
||||
</form>
|
||||
|
||||
<?php require_once "./templates/footer.php"; ?>
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
</body>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -12,3 +12,9 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div id="page">
|
||||
<h1>PTO Notification</h1>
|
||||
<ul id="menu">
|
||||
<li><a href="./">Notify</a></li>
|
||||
<li><a href="./export.php">List</a></li>
|
||||
</ul>
|
||||
|
|
Загрузка…
Ссылка в новой задаче