diff --git a/app/assets/images/x-pale.png b/app/assets/images/x-pale.png new file mode 100644 index 000000000..e0a0d527e Binary files /dev/null and b/app/assets/images/x-pale.png differ diff --git a/app/assets/javascripts/extra/build_list.js b/app/assets/javascripts/extra/build_list.js index 3680da92a..62416b4a2 100644 --- a/app/assets/javascripts/extra/build_list.js +++ b/app/assets/javascripts/extra/build_list.js @@ -34,18 +34,49 @@ $(document).ready(function() { }); $('#build_list_save_to_repository_id').trigger('change'); -}); -function setBranchSelected(selected_option) { - var pl_name = selected_option.text().match(/([\w-.]+)\/[\w-.]+/)[1]; - var bl_version_sel = $('#build_list_project_version'); - var branch_pl_opt = bl_version_sel.find('option[value="' + pl_name + '"]'); - // If there is branch we need - set it selected: - if (branch_pl_opt.size() > 0) { - bl_version_sel.find('option[selected]').removeAttr('selected'); - branch_pl_opt.attr('selected', 'selected'); - bl_version_sel.val(branch_pl_opt); - // hack for FF to force render of select box. - bl_version_sel[0].innerHTML = bl_version_sel[0].innerHTML; + function setBranchSelected(selected_option) { + var pl_name = selected_option.text().match(/([\w-.]+)\/[\w-.]+/)[1]; + var bl_version_sel = $('#build_list_project_version'); + var branch_pl_opt = bl_version_sel.find('option[value="' + pl_name + '"]'); + // If there is branch we need - set it selected: + if (branch_pl_opt.size() > 0) { + bl_version_sel.find('option[selected]').removeAttr('selected'); + branch_pl_opt.attr('selected', 'selected'); + bl_version_sel.val(branch_pl_opt); + // hack for FF to force render of select box. + bl_version_sel[0].innerHTML = bl_version_sel[0].innerHTML; + } } -} + + var ownership_btn = $('.btn.ownership'); + ownership_btn.click(function() { + ownership_btn.removeClass('active'); + $('#filter_ownership').val($(this).val()); + $(this).addClass('active'); + return false; + }); + + var perpage_btn = $('.btn.per_page'); + perpage_btn.click(function() { + perpage_btn.removeClass('active'); + $('#per_page').val($(this).val()); + $(this).addClass('active'); + return false; + }); + + $('a#updated_at_clear').click(function() { + var tmp = $(this).attr('href'); + tmp = $(tmp); + $($(this).attr('href')).val(''); + return false; + }); + + $('#filter_clear').click(function() { + $('form .input_cleanse').val(''); + $('.btn-group .btn').removeClass('active'); + if(ownership_btn.length > 0) { ownership_btn[0].click(); } + perpage_btn[0].click(); + return false; + }); +}); diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 3236ff5ef..c908583cb 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -3,3 +3,4 @@ @import "design/git"; @import "design/common"; @import "design/custom"; +@import "design/build_lists_monitoring"; diff --git a/app/assets/stylesheets/design/build_lists_monitoring.scss b/app/assets/stylesheets/design/build_lists_monitoring.scss new file mode 100644 index 000000000..27b41557a --- /dev/null +++ b/app/assets/stylesheets/design/build_lists_monitoring.scss @@ -0,0 +1,748 @@ +#lleo_dialog, #lleo_dialog * { + margin: 0 !important; + padding: 0 !important; + background: none !important; + border: none 0 !important; + position: static !important; + vertical-align: baseline !important; + font: normal 13px Arial, Helvetica !important; + line-height: 15px !important; + color: #000 !important; + overflow: visible !important; + width: auto !important; + height: auto !important; + float: none !important; + visibility: visible !important; + text-align: left !important; + border-collapse: separate !important; + border-spacing: 2px !important; +} + +#lleo_dialog iframe { + height: 0 !important; + width: 0 !important; +} + +#lleo_dialog { + position: absolute !important; + background: #fff !important; + border: solid 1px #ccc !important; + padding: 7px 0 0 !important; + left: -999px; + top: -999px; + /*max-width: 450px !important;*/ + width: 440px !important; + overflow: hidden; + display: block !important; + z-index: 999999999 !important; + opacity: 0 !important; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.18) !important; + -moz-border-radius: 3px !important; + -webkit-border-radius: 3px !important; + border-radius: 3px !important; +} +#lleo_dialog.lleo_show { + opacity: 1 !important; + -webkit-transition: opacity 0.3s !important; +} +#lleo_dialog input::-webkit-input-placeholder { + color: #aaa !important; +} +#lleo_dialog .lleo_has_pic #lleo_word { + margin-right: 80px !important; +} +#lleo_dialog #lleo_translationsCopntainer1 { + position: relative !important; +} +#lleo_dialog #lleo_translationsCopntainer2 { + padding: 7px 0 0 !important; + vertical-align: middle !important; +} +#lleo_dialog #lleo_word { + color: #000 !important; + margin: 0 5px 2px 0 !important; + /*float: left !important;*/ +} +#lleo_dialog .lleo_has_sound #lleo_word { + margin-left: 17px !important; +} +#lleo_dialog #lleo_text { + font-weight: bold !important; + color: #d56e00 !important; + text-decoration: none !important; + cursor: default !important; +} +#lleo_dialog #lleo_text.lleo_known { + cursor: pointer !important; + text-decoration: underline !important; +} +#lleo_dialog #lleo_closeBtn { + position: absolute !important; + right: 6px !important; + top: 5px !important; + line-height: 1px !important; + text-decoration: none !important; + font-weight: bold !important; + font-size: 0 !important; + color: #aaa !important; + display: block !important; + padding: 2px !important; + z-index: 9999999999 !important; + width: 7px !important; + height: 7px !important; + padding: 0 !important; + margin: 0 !important; +} + +#lleo_dialog #lleo_optionsBtn { + position: absolute !important; + right: 1px !important; + top: 12px !important; + line-height: 1px !important; + text-decoration: none !important; + font-weight: bold !important; + font-size: 13px !important; + color: #aaa !important; + padding: 2px !important; + display: none; +} +#lleo_dialog #lleo_optionsBtn img{ + width: 12px !important; + height: 12px !important; +} +#lleo_dialog #lleo_sound { + float: left !important; + width: 16px !important; + height: 16px !important; + margin-left: 12px !important; + background: 0 0 no-repeat !important; + cursor: pointer !important; + display: none !important; +} +#lleo_dialog .lleo_has_sound #lleo_sound { + display: block !important; +} +#lleo_dialog #lleo_picOuter { + position: absolute !important; + float: right !important; + right: 29px; + top: 0; + display: none !important; + z-index: 9 !important; +} +#lleo_dialog .lleo_has_pic #lleo_picOuter { + display: block !important; +} +#lleo_dialog #lleo_picOuter:hover { + z-index: 11 !important; +} +#lleo_dialog #lleo_pic, +#lleo_dialog #lleo_picBig { + position: absolute !important; + top: 0 !important; + right: 0 !important; + border: solid 2px #fff !important; + -moz-border-radius: 2px !important; + -webkit-border-radius: 2px !important; + border-radius: 2px !important; + z-index: 1 !important; +} +#lleo_dialog #lleo_pic { + position: relative !important; + border: none !important; + width: 34px !important; +} +#lleo_dialog #lleo_picBig { + box-shadow: -1px 2px 4px rgba(0,0,0,0.3); + z-index: 2 !important; + opacity: 0 !important; + visibility: hidden !important; +} +#lleo_dialog #lleo_picOuter:hover #lleo_picBig { + visibility: visible !important; + opacity: 1 !important; + -webkit-transition: opacity 0.3s !important; + -webkit-transition-delay: 0.3s !important; +} +#lleo_dialog #lleo_transcription { + color: #486D85 !important; + margin: 0 0 4px 29px !important; + color: #aaaaaa !important; +} +#lleo_dialog .lleo_no_trans { + color: #aaa !important; +} +#lleo_dialog .ll-translation-counter { + float: right !important; + font-size: 11px !important; + color: #aaa !important; + padding: 2px 2px 1px 10px !important; +} + +#lleo_dialog .ll-translation-text { + float: left !important; + width: 80% !important; +} + +#lleo_dialog #lleo_trans a { + color: #3F669F !important; + padding: 1px 4px !important; + text-decoration: none !important; + text-overflow: ellipsis !important; + overflow: hidden !important; +} + +#lleo_dialog .ll-translation-item { + width: 100% !important; + float: left !important; + padding:1px 4px; + color: #3F669F !important; + padding: 3px !important; + border: solid 1px white !important; + -moz-border-radius: 2px !important; + -webkit-border-radius: 2px !important; + border-radius: 2px !important; +} + +#lleo_dialog .ll-translation-item:hover { + border: solid 1px #9FC2C9 !important; + background: #EDF4F6 !important; + cursor: pointer !important; +} + +#lleo_dialog .ll-translation-marker { + margin: 0px 5px 2px 2px !important; +} + +#lleo_dialog #lleo_icons { + margin: 10px 0 7px !important; + color: #aaa !important; + line-height: 20px !important; + font-size: 11px !important; + clear: both !important; + padding-left: 16px !important; +} +#lleo_icons a { + display: inline-block !important; + width: 16px !important; + height: 16px !important; + margin: 0 0 -2px 3px !important; + text-decoration: none !important; + background: 0 0 no-repeat !important; + opacity: 0.5 !important; +} +#lleo_icons a:hover { + opacity: 1 !important; +} +#lleo_icons a.lleo_google {background-position:-34px 0 !important;} +#lleo_icons a.lleo_multitran {background-position:-64px 0 !important;} +#lleo_icons a.lleo_lingvo {background-position:-51px 0 !important; width: 12px !important;} +#lleo_icons a.lleo_dict {background-position:-17px 0 !important;} +#lleo_icons a.lleo_linguee {background-position:-81px 0 !important;} +#lleo_icons a.lleo_michaelis {background-position:-98px 0 !important;} + +#lleo_dialog #lleo_contextContainer { + margin: 0 !important; + padding: 3px 15px 3px 10px !important; + background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#eee)) !important; + border-bottom: solid 1px #ddd !important; + border-top-left-radius: 3px !important; + border-top-right-radius: 3px !important; + display: none !important; + overflow: hidden !important; +} +#lleo_dialog .lleo_has_context #lleo_contextContainer { + display: block !important; +} +#lleo_dialog #lleo_context { + color: #444 !important; + text-shadow: 1px 1px 0 #f4f4f4 !important; + line-height: 12px !important; + font-size: 11px !important; + margin-left: 2px !important; +} +#lleo_dialog #lleo_context b { + line-height: 12px !important; + color: #000 !important; + font-weight: bold !important; + font-size: 11px !important; +} +#lleo_dialog #lleo_gBrand { + color: #aaa !important; + font-size: 10px !important; + /*padding-right: 52px !important;*/ + padding-bottom: 14px !important; + margin: -3px 4px 0 4px !important; + background: left bottom no-repeat !important; + display: inline-block !important; + float: right !important; +} +#lleo_dialog #lleo_gBrand.hidden { + display: none !important; +} +#lleo_dialog #lleo_translateContextLink { + color: #444 !important; + text-shadow: 1px 1px 0 #f4f4f4 !important; + background: -webkit-gradient(linear, left top, left bottom, from(#f4f4f4), to(#ddd)) !important; + border: solid 1px !important; + box-shadow: 1px 1px 0 #f6f6f6 !important; + border-color: #999 #aaa #aaa #999 !important; + -moz-border-radius: 2px !important; + -webkit-border-radius: 2px !important; + border-radius: 2px !important; + padding: 0 3px !important; + font-size: 11px !important; + text-decoration: none !important; + margin: 1px 5px 0 !important; + display: inline-block !important; + white-space: nowrap !important; +} +#lleo_dialog #lleo_translateContextLink:hover { + background: #f8f8f8 !important; +} + +#lleo_dialog #lleo_setTransForm { + display: block !important; + margin-top: 3px !important; + padding-top: 5px !important; + /* Set position and background because the form might be overlapped by an image when no translations */ + position: relative !important; + background: #fff !important; + z-index: 10 !important; + padding-bottom: 10px !important; + padding-left: 16px !important; +} +#lleo_dialog .lleo-custom-translation { + padding: 4px 5px !important; + border: solid 1px #ddd !important; + -moz-border-radius: 2px !important; + -webkit-border-radius: 2px !important; + border-radius: 2px !important; + width: 90% !important; + min-width: 270px !important; + background: -webkit-gradient(linear, 0 0, 0 20, from(#f1f1f1), to(#fff)) !important; + font: normal 13px Arial, Helvetica !important; + line-height: 15px !important; +} +#lleo_dialog .lleo-custom-translation:hover { + border: solid 1px #aaa !important; +} +#lleo_dialog .lleo-custom-translation:focus { + background: #FFFEC9 !important; +} + +#lleo_dialog *.hidden { + display: none !important; +} + +#lleo_dialog .infinitive{ + color: #D56E00 !important; + text-decoration: none; + border-bottom: 1px dotted #D56E00 !important; +} +#lleo_dialog .infinitive:hover{ + border: none !important; +} + +#lleo_dialog #lleo_trans{ + zoom: 1; + border-top: 1px solid #eeeeee !important; + margin: 10px 0 0 !important; + padding: 5px 30px 0 14px !important; +} + +#lleo_dialog .lleo_clearfix { + display: block !important; + clear: both !important; + visibility: hidden !important; + height: 0 !important; + font-size: 0 !important; +} + +#lleo_dialog #lleo_markBlock { + background: #eeeeee !important; + cursor: pointer !important; + border-bottom-left-radius: 3px !important; + border-bottom-right-radius: 3px !important; + border-collapse: separate !important; + border-spacing: 2px !important; +} + +#lleo_dialog #lleo_markBlock img{ + width: 14px !important; + height: 14px !important; +} + +#lleo_dialog #lleo_markBlock .icon-cell { + padding: 5px 2px 5px 16px !important; + height: 17px !important; +} + +#lleo_dialog #lleo_markBlock .wide-cell { + width: 100% !important; +} + +#lleo_dialog #lleo_markBlock .text-cell { + color: #999999 !important; + font: normal 13px Arial, Helvetica !important; + text-shadow: 0 1px #fff !important; +} + +#lleo_dialog #lleo_markBlock td { + vertical-align: middle !important; + border-collapse: separate !important; + border-spacing: 2px !important; +} + +#lleo_dialog #lleo_picOuter table{ + width: 44px !important; + position: absolute !important; + right: 0 !important; + vertical-align: middle !important; +} + +#lleo_dialog #lleo_picOuter td{ + width: 38px !important; + height: 38px !important; + border: 1px solid #eeeeee !important; + vertical-align: middle !important; + text-align: center !important; +} + +#lleo_dialog #lleo_picOuter td div { + height: 38px !important; + overflow: hidden !important; +} +.ll-content-notification *{ + letter-spacing: normal !important; + margin: 0 !important; + padding: 0 !important; + background: none !important; + border: 0 !important; + float: none !important; + text-align: left !important; + text-decoration: none !important; + font: normal 15px 'Lucida Grande', 'Lucida Sans Unicode', Lucida, Arial, Helvetica, sans-serif !important; +} + +.ll-content-notification { + vertical-align: baseline !important; + color: #000 !important; + overflow: visible !important; + visibility: visible !important; + margin: 0 !important; + padding: 0 !important; + position: fixed !important; + background: #fff !important; + border: solid 1px #AAA !important; + /* + left: -999px; + top: -999px; + */ + width: auto; + /* width: 300px !important; */ + display: block; + z-index: 999999999 !important; + -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.18) !important; + -moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.18) !important; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.18) !important; + -webkit-border-radius: 3px !important; + -moz-border-radius: 3px !important; + border-radius: 3px !important; + overflow: hidden !important; + /* opacity: 0 !important; */ + transition: opacity 0.8s !important; + -moz-transition: opacity 0.8s !important; /* Firefox 4 */ + -webkit-transition: opacity 0.8s !important; /* Safari and Chrome */ + -o-transition: opacity 0.8s !important; /* Opera */ + cursor: default !important; +} + +.ll-content-notification-shown { + opacity: 1 !important; + transition: opacity 0.8s !important; + -moz-transition: opacity 0.8s !important; /* Firefox 4 */ + -webkit-transition: opacity 0.8s !important; /* Safari and Chrome */ + -o-transition: opacity 0.8s !important; /* Opera */ +} + +.ll-content-notification-header { + border: 0 !important; + margin: 0 !important; + background: url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAABCAIAAABsYngUAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAABJJREFUGFdjePHmCxw9e/UZjgAVYhYtk8xZqAAAAABJRU5ErkJggg==) !important; + border-bottom: solid 1px #CCC !important; + padding: 1px 4px !important; + min-height: 18px !important; + width: 100% !important; + -webkit-border-top-left-radius: 3px !important; + -webkit-border-top-right-radius: 3px !important; + -moz-border-radius-topleft: 3px !important; + -moz-border-radius-topright: 3px !important; + border-top-left-radius: 3px !important; + border-top-right-radius: 3px !important; + border-collapse: collapse !important; + border-spacing: 0 !important; +} + +.ll-content-notification-header-pic { + border: 0 !important; + margin: 0 !important; + padding: 3px 0 0 3px !important; + width: 20px !important; + vertical-align: top !important; + line-height: 1px !important; +} + +.ll-content-notification-header-pic img{ + border: 0 !important; + padding: 0 !important; + margin: 0 !important; + line-height: 1px !important; +} + +.ll-content-notification-header-caption { + font: normal 13px 'Lucida Grande', 'Lucida Sans Unicode', Lucida, Arial, Helvetica, sans-serif !important; + font-weight: bold !important; + line-height: 15px !important; + color: #555 !important; + float: left !important; + text-shadow: none !important; + letter-spacing: normal !important; + white-space: normal !important; + padding: 3px !important; + margin: 0 !important; +} + +.ll-content-notification-header-close { + width: 15px !important; + vertical-align: top !important; + text-align: right !important; + padding: 6px 5px 0 0 !important; + margin: 0 !important; + line-height: 1px !important; +} + +.ll-content-notification-header-close img { + border: 0 !important; + width: 7px !important; + height: 7px !important; + margin: 0 !important; + padding: 0 !important; +} + +.ll-content-notification-content { + margin: 0 !important; + padding: 8px !important; + float: left !important; + overflow: hidden !important; + width: auto !important; +} + +.ll-content-notification-content-logo { + float: left !important; + height: 48px !important; + width: 48px !important; +} + +.ll-content-notification-content-main { + margin-left: 60px !important; + overflow: hidden !important; + padding: 0 0 2px 0 !important; + color: #333 !important; + text-align: left !important; + text-shadow: none !important; + letter-spacing: normal !important; + font: normal 13px 'Lucida Grande', 'Lucida Sans Unicode', Lucida, Arial, Helvetica, sans-serif !important; + line-height: 15px !important; + width: auto !important; +} + +.ll-content-notification-content-header { + text-align: left !important; + text-decoration: none !important; + font: bold 15px 'Lucida Grande', 'Lucida Sans Unicode', Lucida, Arial, Helvetica, sans-serif !important; + line-height: 19px !important; + margin: 0 0 4px 0 !important; + padding: 0 !important; + border: 0 !important; + color: #333 !important; + text-shadow: none !important; + letter-spacing: normal !important; + display: block !important; + top: 0 !important; + left: 0 !important; +} + +.ll-content-notification-word { + color: #d56e00 !important; + font-weight: bold !important; + font-size: 14px !important; +} + +article .all .top { + + background: #e9f4fb; + border: 1px solid #dfeefa; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + // width: 760px; + color: 477cae; + padding: 8px; + +} + +article .all .top .column { + width: 190px; + margin: 5px 10px; + float:left; +} + +div.reloader { +float: none; +} + +.floatright, article input.floatright { + float: right; + margin-right: 8px; +} + +.floatleft { + float: left; +} + +h3.medium { + font-size: 13px; + margin: 5px 0px; + padding: 3px 0px; +} + +.switch { + font-size: 11px; + float: center; + text-align: center; + color: #125687; + font-weight: bold; + //margin: -7px 0; + margin-bottom: -7px; +} + +.top .switch a { + text-decoration: none; +} +.btn-group { + width: 180px; +} + +.btn-group .btn { + width: 40%; + height: 26px; + padding: 2px 0px; +} + +.btn-group > .btn:first-child, +.btn-group > .btn:last-child { + width: 30%; +} + +.sel80.medium { + display: inline-block; + width: 180px; + margin-bottom: 0px; + height: 26px; + line-height: 26px; + padding: 4px 2px; + // margin-bottom: 5px; + color: #555; + vertical-align: middle; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + background-color: white; + border: 1px solid #CCC; +} + +input.mediumheight { + height: 20px; + margin-bottom: 0px; + width: 180px; + margin-right: -19px; +} +input.mediumheight.min { + width: 85px; + font-size: 12px; + padding-left: 5px; +} +article .all .top form .butgrp { + margin-top: 20px; + float: right; + margin-right: 17px; +} + +article .all .top form .butgrp input[type="submit"] { + width: 85px; + padding: 3px 13px 5px; + float: right; + margin-left: 10px; +} + +.ui-datepicker, .ui-widget, .ui-widget-content, .ui-helper-clearfix, .ui-corner-all { + font-size: 75%; + z-index: 99!important; +} + +article label { + font-size: 12px; +} + +article .all .top form .floatleft a img, +article .all .top form .floatright a img { + vertical-align: middle; +} + +/* bootstrap 3149*/ +.btn { +display: inline-block; +padding: 4px 12px; +margin-bottom: 0; +line-height: 20px; +color: #333333; +text-align: center; +text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); +vertical-align: middle; +cursor: pointer; +background-color: #f5f5f5; +background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); +background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); +background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); +background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); +background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); +background-repeat: repeat-x; +border: 1px solid #bbbbbb; +border-color: #e6e6e6 #e6e6e6 #bfbfbf; +border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); +border-bottom-color: #a2a2a2; +-webkit-border-radius: 4px; +-moz-border-radius: 4px; +border-radius: 4px; +filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); +filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +/* bootstrap 3190*/ +.btn:hover, .btn:active, .btn.active, .btn.disabled, .btn[disabled] { +color: #333333; +background-color: #e6e6e6; +} + +/* bootstrap 3222*/ +.btn.active, .btn:active { +background-image: none; +outline: 0; +-webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +-moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} \ No newline at end of file diff --git a/app/controllers/projects/build_lists_controller.rb b/app/controllers/projects/build_lists_controller.rb index 3cc8338f8..00bfdf8cb 100644 --- a/app/controllers/projects/build_lists_controller.rb +++ b/app/controllers/projects/build_lists_controller.rb @@ -16,6 +16,7 @@ class Projects::BuildListsController < Projects::BaseController params[:filter].each do |k,v| new_params[:filter][k] = v unless v.empty? end + new_params[:per_page] = params[:per_page] if params[:per_page].present? redirect_to @project ? project_build_lists_path(@project, new_params) : build_lists_path(new_params) end @@ -24,7 +25,8 @@ class Projects::BuildListsController < Projects::BaseController @filter = BuildList::Filter.new(@project, current_user, params[:filter] || {}) page = params[:page].to_i == 0 ? nil : params[:page] - @bls = @filter.find.recent.paginate :page => page + @per_page = [25, 50, 100].include?(params[:per_page].to_i) ? params[:per_page].to_i : 25 + @bls = @filter.find.recent.paginate :page => page, :per_page => @per_page @build_lists = BuildList.where(:id => @bls.pluck("#{BuildList.table_name}.id")).recent @build_lists = @build_lists.includes [:save_to_platform, :save_to_repository, :arch, :user, :project => [:owner]] diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 970715327..d2498da18 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -4,8 +4,6 @@ module ApplicationHelper case when controller_name == 'issues' && action_name == 'new' 'right nopadding' - when controller_name == 'build_lists' && action_name == 'index' - 'right slim' when controller_name == 'build_lists' && ['new', 'create'].include?(action_name) nil when controller_name == 'platforms' && ['build_all', 'mass_builds'].include?(action_name) diff --git a/app/models/build_list/filter.rb b/app/models/build_list/filter.rb index bae506cf3..f44e7de4d 100644 --- a/app/models/build_list/filter.rb +++ b/app/models/build_list/filter.rb @@ -71,14 +71,11 @@ class BuildList::Filter end def build_date_from_params(field_name, params) - if params[field_name].present? - Time.at(params[field_name].to_i) - elsif params["#{field_name}(1i)"].present? || params["#{field_name}(2i)"].present? || params["#{field_name}(3i)"].present? - Date.civil((params["#{field_name}(1i)"].presence || Date.today.year).to_i, - (params["#{field_name}(2i)"].presence || Date.today.month).to_i, - (params["#{field_name}(3i)"].presence || Date.today.day).to_i) - else - nil - end + return nil if params[field_name].blank? + return Date.parse(params[field_name]) if params[field_name].strip =~ /\A\d{2}.\d{2}\.\d{4}\z/ + + time = params[field_name].to_i + return Time.at(time) if time != 0 + Date.parse params[field_name].trim end end diff --git a/app/views/projects/build_lists/_filter.html.haml b/app/views/projects/build_lists/_filter.html.haml index d3bf13aea..8ebb19091 100644 --- a/app/views/projects/build_lists/_filter.html.haml +++ b/app/views/projects/build_lists/_filter.html.haml @@ -1,49 +1,92 @@ -- content_for :sidebar do - = render 'server_status' - - = form_for :filter, :url => @action_url, :html => { :method => :post, :class => :form } do |f| - - if current_user - .bordered.nopadding - %h3= t("layout.build_lists.ownership.header") - .table - .lefter= f.radio_button :ownership, 'owned', :class => 'niceRadio', :id => 'myradio1' - .lefter= t("layout.build_lists.ownership.owned") +.top + .filter + = form_for :filter, :url => @action_url, :html => { :method => :post, :class => :form } do |f| + .column + = render 'server_status' + = hidden_field_tag :servertime, Time.now.utc.to_i + .reloader + = label_tag :autoreload do + = check_box_tag :autoreload, true, true + = t 'layout.autoreload_page' + .column + - if current_user + .bordered.nopadding + %h3.medium= t("layout.build_lists.ownership.header") + =f.hidden_field :ownership + .btn-group + -if @project + %button.btn.ownership{:value => 'owned', :class => @filter.ownership == 'owned' ? 'active' : '', :style => 'width:50%;'}= t 'layout.build_lists.ownership.owned' + %button.btn.ownership{:value => 'everything', :class => @filter.ownership == 'everything' ? 'active' : '', :style => 'width:50%;'}= t 'layout.build_lists.ownership.everything' + -else + %button.btn.ownership{:value => 'owned', :class => @filter.ownership == 'owned' ? 'active' : ''}= t 'layout.build_lists.ownership.owned' + %button.btn.ownership{:class => @filter.ownership == 'related' ? 'active' : '', :value => "related"}= t 'layout.build_lists.ownership.related' + %button.btn.ownership{:value => 'everything', :class => @filter.ownership == 'everything' ? 'active' : ''}= t 'layout.build_lists.ownership.everything' + %h3.medium= t 'number_rows' + =hidden_field_tag :per_page, @per_page + .btn-group + -[25,50,100].each do |num| + %button.btn.per_page{:value => num, :class => @per_page == num ? 'active' : ''}=num + %h3.medium= t 'activerecord.attributes.build_list.status' + .lineForm.aside + = f.select :status, BuildList::STATUSES.collect{|status| [BuildList.human_status(status), status]}, {:include_blank => true, :selected => @filter.status}, + {:class => 'sel80 medium input_cleanse', :id => 'status', :tabindex => 2} .both - - unless @project - .table - .lefter= f.radio_button :ownership, 'related', :class => 'niceRadio', :id => 'myradio2' - .lefter= t("layout.build_lists.ownership.related") - .both - .table - .lefter= f.radio_button :ownership, 'everything', :class => 'niceRadio', :id => 'myradio3' - .lefter= t("layout.build_lists.ownership.everything") + %br/ + .column + %h3.medium= t 'activerecord.models.platform' + .lineForm.aside + = f.select :platform_id, Platform.main.collect{|pl| [pl.name, pl.id]}, {:include_blank => true, :selected => @filter.platform_id}, + {:class => 'sel80 medium input_cleanse', :id => 'platform', :tabindex => 2} + %h3.medium= t 'activerecord.attributes.build_list.arch' + .lineForm.aside + = f.select :arch_id, Arch.recent.collect{|arch| [arch.name, arch.id]}, {:include_blank => true, :selected => @filter.arch_id}, + {:class => 'sel80 medium input_cleanse', :id => 'architecture', :tabindex => 2} + %h3.medium= t 'activerecord.models.mass_build' + .lineForm.aside + = f.select :mass_build_id, options_from_collection_for_select( MassBuild.all, :id, :name, @filter.mass_build_id ), {:include_blank => true, :selected => @filter.mass_build_id}, + {:class => 'sel80 medium input_cleanse', :id => 'mass_build', :tabindex => 2} + .column + .floatleft + %h3.medium= t '_on' + -date = @filter.updated_at_start ? @filter.updated_at_start.strftime('%d.%m.%Y') : nil + =f.text_field :updated_at_start, :readonly => "readonly", :size => 10, :class => 'mediumheight min input_cleanse', :value => date + =link_to image_tag('x-pale.png', :alt => 'x'), '#filter_updated_at_start', :id => 'updated_at_clear' + .floatright + %h3.medium= t 'until' + -date = @filter.updated_at_end ? @filter.updated_at_end.strftime('%d.%m.%Y') : nil + =f.text_field :updated_at_end, :readonly => "readonly", :size => 10, :class => 'mediumheight min input_cleanse', :value => date + =link_to image_tag('x-pale.png', :alt => 'x'), '#filter_updated_at_end', :id => 'updated_at_clear' .both - %br - = f.submit t("layout.search.header") - .block - %h3.small= t("activerecord.attributes.build_list.new_core") - .lineForm.aside= f.select :new_core, build_list_options_for_new_core, {:include_blank => true, :selected => @filter.new_core}, {:class => 'sel80 aside', :id => 'new_core', :tabindex => 2} - %h3.small= t("activerecord.attributes.build_list.status") - .lineForm.aside= f.select :status, BuildList::STATUSES.collect{|status| [BuildList.human_status(status), status]}, {:include_blank => true, :selected => @filter.status}, {:class => 'sel80 aside', :id => 'status', :tabindex => 2} - %h3.small= t("activerecord.models.platform") - .lineForm.aside= f.select :platform_id, Platform.main.collect{|pl| [pl.name, pl.id]}, {:include_blank => true, :selected => @filter.platform_id}, {:class => 'sel80 aside', :id => 'platform', :tabindex => 2} - %h3.small= t("activerecord.attributes.build_list.mass_build") - .lineForm.aside= f.select :mass_build_id, options_from_collection_for_select( MassBuild.all, :id, :name, @filter.mass_build_id ), {:include_blank => true} - %h3.small= t("activerecord.attributes.build_list.arch") - .lineForm.aside= f.select :arch_id, Arch.recent.collect{|arch| [arch.name, arch.id]}, {:include_blank => true, :selected => @filter.arch_id}, {:class => 'sel80 aside', :id => 'architecture', :tabindex => 2} - -# TODO [BuildList#created_at filters] Uncomment here and in BuildList::Filter to return filters - %h3.small= t("layout.build_lists.created_at_start") - .date_select= f.date_select(:created_at_start, :include_blank => true, :selected => @filter.created_at_start) - %h3.small= t("layout.build_lists.created_at_end") - .date_select= f.date_select(:created_at_end, :include_blank => true, :selected => @filter.created_at_end) - %h3.small= t("layout.build_lists.updated_at_start") - .date_select= f.date_select(:updated_at_start, :include_blank => true, :selected => @filter.updated_at_start) - %h3.small= t("layout.build_lists.updated_at_end") - .date_select= f.date_select(:updated_at_end, :include_blank => true, :selected => @filter.updated_at_end) - %h3.small= t("layout.build_lists.project_name_search") - = f.text_field :project_name - %h3.small= t("layout.build_lists.bs_id_search") - = f.text_field :bs_id - %br - %br - = f.submit t("layout.search.header") + %h3.medium= t 'layout.build_lists.project_name_search' + %input#filter_project_name.mediumheight.input_cleanse{:name => "filter[project_name]", :size => "30", :type => "text"}/ + %h3.medium= t 'layout.build_lists.bs_id_search' + %input#filter_bs_id.mediumheight.input_cleanse{:name => "filter[bs_id]", :size => "30", :type => "text"}/ + %br/ + %br/ + .butgrp + -if @project and can?(:create, @project.build_lists.build) + %input{:type => 'button', :onclick => "location.href='#{new_project_build_list_path(@project)}'", :value => t('layout.build_lists.new_header')} + = f.submit t('layout.search.header') + = f.submit t('reset'), :id => 'filter_clear' + .both + .both + .switch + %a{:href => "#"}= t 'layout.hide' +:javascript + $(".switch").toggle( + function () { + $(".filter").hide("slow"); + $(".switch a").text("#{t 'layout.show'}"); + }, + function () { + $(".filter").show("slow"); + $(".switch a").text("#{t 'layout.hide'}"); + } + ); + $('.mediumheight.min').datetimepicker({ + dateFormat: 'dd.mm.yy', + timeFormat: '', + showTime: false, + showHour: false, + showMinute: false + }); diff --git a/app/views/projects/build_lists/_server_status.html.haml b/app/views/projects/build_lists/_server_status.html.haml index 7bef79c07..8a86a33e6 100644 --- a/app/views/projects/build_lists/_server_status.html.haml +++ b/app/views/projects/build_lists/_server_status.html.haml @@ -1,7 +1,6 @@ - queues ||= [:rpm, :publish] .bordered.nopadding - %h3= t('layout.build_lists.build_server_status.header') - + %h3.medium= t('layout.build_lists.build_server_status.header') - queues.each do |queue| .table .lefter= t("layout.build_lists.build_server_status.#{queue}_workers") @@ -12,4 +11,3 @@ .righter= @build_server_status[queue][metric] .both %br - = link_to t('layout.build_lists.new_header'), new_project_build_list_path(@project), :class => 'button' if @project and can?(:create, @project.build_lists.build) \ No newline at end of file diff --git a/app/views/projects/build_lists/index.html.haml b/app/views/projects/build_lists/index.html.haml index 98849964c..9133efa65 100644 --- a/app/views/projects/build_lists/index.html.haml +++ b/app/views/projects/build_lists/index.html.haml @@ -1,11 +1,6 @@ -set_meta_tags :title => t('.title') -= hidden_field_tag :servertime, Time.now.utc.to_i -%div.reloader - = label_tag :autoreload do - = check_box_tag :autoreload, true, true - = t("layout.autoreload_page") -.both += render 'filter' %table.tablesorter{:cellpadding => "0", :cellspacing => "0"} %thead @@ -74,5 +69,4 @@ = will_paginate @bls -= render 'filter' = render @project ? 'projects/base/submenu' : 'projects/build_lists/submenu' diff --git a/config/locales/en.yml b/config/locales/en.yml index 6d3b9b58c..be090706d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -20,6 +20,7 @@ en: user_list: User list edit: Edit show: View + hide: Hide cancel: Cancel create: Create update: Update @@ -203,3 +204,7 @@ en: from: from by: by diff: Diff + number_rows: Number rows + reset: Reset + _on: 'On' + until: Until diff --git a/config/locales/models/build_list.ru.yml b/config/locales/models/build_list.ru.yml index 1cf1026a1..e6f38838f 100644 --- a/config/locales/models/build_list.ru.yml +++ b/config/locales/models/build_list.ru.yml @@ -89,7 +89,7 @@ ru: ownership: header: Принадлежность заданий owned: Мне - related: Связанные со мной + related: Связанные everything: Все build_server_status: diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 742e84ed4..1afe052cd 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -20,6 +20,7 @@ ru: user_list: Список пользователей edit: Редактировать show: Просмотр + hide: Скрыть cancel: Отмена create: Создать update: Обновить @@ -204,3 +205,7 @@ ru: from: из by: от diff: Изменения + number_rows: Количество строк + reset: Сброс + _on: с + until: по diff --git a/vendor/assets/javascripts/jquery-ui-timepicker-addon.js b/vendor/assets/javascripts/jquery-ui-timepicker-addon.js new file mode 100644 index 000000000..f9b5faa2d --- /dev/null +++ b/vendor/assets/javascripts/jquery-ui-timepicker-addon.js @@ -0,0 +1,1919 @@ +/* + * jQuery timepicker addon + * By: Trent Richardson [http://trentrichardson.com] + * Version 1.2 + * Last Modified: 02/02/2013 + * + * Copyright 2013 Trent Richardson + * You may use this project under MIT or GPL licenses. + * http://trentrichardson.com/Impromptu/GPL-LICENSE.txt + * http://trentrichardson.com/Impromptu/MIT-LICENSE.txt + */ + +/*jslint evil: true, white: false, undef: false, nomen: false */ + +(function($) { + + /* + * Lets not redefine timepicker, Prevent "Uncaught RangeError: Maximum call stack size exceeded" + */ + $.ui.timepicker = $.ui.timepicker || {}; + if ($.ui.timepicker.version) { + return; + } + + /* + * Extend jQueryUI, get it started with our version number + */ + $.extend($.ui, { + timepicker: { + version: "1.2" + } + }); + + /* + * Timepicker manager. + * Use the singleton instance of this class, $.timepicker, to interact with the time picker. + * Settings for (groups of) time pickers are maintained in an instance object, + * allowing multiple different settings on the same page. + */ + var Timepicker = function() { + this.regional = []; // Available regional settings, indexed by language code + this.regional[''] = { // Default regional settings + currentText: 'Now', + closeText: 'Done', + amNames: ['AM', 'A'], + pmNames: ['PM', 'P'], + timeFormat: 'HH:mm', + timeSuffix: '', + timeOnlyTitle: 'Choose Time', + timeText: 'Time', + hourText: 'Hour', + minuteText: 'Minute', + secondText: 'Second', + millisecText: 'Millisecond', + timezoneText: 'Time Zone', + isRTL: false + }; + this._defaults = { // Global defaults for all the datetime picker instances + showButtonPanel: true, + timeOnly: false, + showHour: true, + showMinute: true, + showSecond: false, + showMillisec: false, + showTimezone: false, + showTime: true, + stepHour: 1, + stepMinute: 1, + stepSecond: 1, + stepMillisec: 1, + hour: 0, + minute: 0, + second: 0, + millisec: 0, + timezone: null, + useLocalTimezone: false, + defaultTimezone: "+0000", + hourMin: 0, + minuteMin: 0, + secondMin: 0, + millisecMin: 0, + hourMax: 23, + minuteMax: 59, + secondMax: 59, + millisecMax: 999, + minDateTime: null, + maxDateTime: null, + onSelect: null, + hourGrid: 0, + minuteGrid: 0, + secondGrid: 0, + millisecGrid: 0, + alwaysSetTime: true, + separator: ' ', + altFieldTimeOnly: true, + altTimeFormat: null, + altSeparator: null, + altTimeSuffix: null, + pickerTimeFormat: null, + pickerTimeSuffix: null, + showTimepicker: true, + timezoneIso8601: false, + timezoneList: null, + addSliderAccess: false, + sliderAccessArgs: null, + controlType: 'slider', + defaultValue: null, + parse: 'strict' + }; + $.extend(this._defaults, this.regional['']); + }; + + $.extend(Timepicker.prototype, { + $input: null, + $altInput: null, + $timeObj: null, + inst: null, + hour_slider: null, + minute_slider: null, + second_slider: null, + millisec_slider: null, + timezone_select: null, + hour: 0, + minute: 0, + second: 0, + millisec: 0, + timezone: null, + defaultTimezone: "+0000", + hourMinOriginal: null, + minuteMinOriginal: null, + secondMinOriginal: null, + millisecMinOriginal: null, + hourMaxOriginal: null, + minuteMaxOriginal: null, + secondMaxOriginal: null, + millisecMaxOriginal: null, + ampm: '', + formattedDate: '', + formattedTime: '', + formattedDateTime: '', + timezoneList: null, + units: ['hour','minute','second','millisec'], + control: null, + + /* + * Override the default settings for all instances of the time picker. + * @param settings object - the new settings to use as defaults (anonymous object) + * @return the manager object + */ + setDefaults: function(settings) { + extendRemove(this._defaults, settings || {}); + return this; + }, + + /* + * Create a new Timepicker instance + */ + _newInst: function($input, o) { + var tp_inst = new Timepicker(), + inlineSettings = {}, + fns = {}, + overrides, i; + + for (var attrName in this._defaults) { + if(this._defaults.hasOwnProperty(attrName)){ + var attrValue = $input.attr('time:' + attrName); + if (attrValue) { + try { + inlineSettings[attrName] = eval(attrValue); + } catch (err) { + inlineSettings[attrName] = attrValue; + } + } + } + } + overrides = { + beforeShow: function (input, dp_inst) { + if ($.isFunction(tp_inst._defaults.evnts.beforeShow)) { + return tp_inst._defaults.evnts.beforeShow.call($input[0], input, dp_inst, tp_inst); + } + }, + onChangeMonthYear: function (year, month, dp_inst) { + // Update the time as well : this prevents the time from disappearing from the $input field. + tp_inst._updateDateTime(dp_inst); + if ($.isFunction(tp_inst._defaults.evnts.onChangeMonthYear)) { + tp_inst._defaults.evnts.onChangeMonthYear.call($input[0], year, month, dp_inst, tp_inst); + } + }, + onClose: function (dateText, dp_inst) { + if (tp_inst.timeDefined === true && $input.val() !== '') { + tp_inst._updateDateTime(dp_inst); + } + if ($.isFunction(tp_inst._defaults.evnts.onClose)) { + tp_inst._defaults.evnts.onClose.call($input[0], dateText, dp_inst, tp_inst); + } + } + }; + for (i in overrides) { + if (overrides.hasOwnProperty(i)) { + fns[i] = o[i] || null; + } + } + tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, overrides, { + evnts:fns, + timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker'); + }); + tp_inst.amNames = $.map(tp_inst._defaults.amNames, function(val) { + return val.toUpperCase(); + }); + tp_inst.pmNames = $.map(tp_inst._defaults.pmNames, function(val) { + return val.toUpperCase(); + }); + + // controlType is string - key to our this._controls + if(typeof(tp_inst._defaults.controlType) === 'string'){ + if($.fn[tp_inst._defaults.controlType] === undefined){ + tp_inst._defaults.controlType = 'select'; + } + tp_inst.control = tp_inst._controls[tp_inst._defaults.controlType]; + } + // controlType is an object and must implement create, options, value methods + else{ + tp_inst.control = tp_inst._defaults.controlType; + } + + if (tp_inst._defaults.timezoneList === null) { + var timezoneList = ['-1200', '-1100', '-1000', '-0930', '-0900', '-0800', '-0700', '-0600', '-0500', '-0430', '-0400', '-0330', '-0300', '-0200', '-0100', '+0000', + '+0100', '+0200', '+0300', '+0330', '+0400', '+0430', '+0500', '+0530', '+0545', '+0600', '+0630', '+0700', '+0800', '+0845', '+0900', '+0930', + '+1000', '+1030', '+1100', '+1130', '+1200', '+1245', '+1300', '+1400']; + + if (tp_inst._defaults.timezoneIso8601) { + timezoneList = $.map(timezoneList, function(val) { + return val == '+0000' ? 'Z' : (val.substring(0, 3) + ':' + val.substring(3)); + }); + } + tp_inst._defaults.timezoneList = timezoneList; + } + + tp_inst.timezone = tp_inst._defaults.timezone; + tp_inst.hour = tp_inst._defaults.hour < tp_inst._defaults.hourMin? tp_inst._defaults.hourMin : + tp_inst._defaults.hour > tp_inst._defaults.hourMax? tp_inst._defaults.hourMax : tp_inst._defaults.hour; + tp_inst.minute = tp_inst._defaults.minute < tp_inst._defaults.minuteMin? tp_inst._defaults.minuteMin : + tp_inst._defaults.minute > tp_inst._defaults.minuteMax? tp_inst._defaults.minuteMax : tp_inst._defaults.minute; + tp_inst.second = tp_inst._defaults.second < tp_inst._defaults.secondMin? tp_inst._defaults.secondMin : + tp_inst._defaults.second > tp_inst._defaults.secondMax? tp_inst._defaults.secondMax : tp_inst._defaults.second; + tp_inst.millisec = tp_inst._defaults.millisec < tp_inst._defaults.millisecMin? tp_inst._defaults.millisecMin : + tp_inst._defaults.millisec > tp_inst._defaults.millisecMax? tp_inst._defaults.millisecMax : tp_inst._defaults.millisec; + tp_inst.ampm = ''; + tp_inst.$input = $input; + + if (o.altField) { + tp_inst.$altInput = $(o.altField).css({ + cursor: 'pointer' + }).focus(function() { + $input.trigger("focus"); + }); + } + + if (tp_inst._defaults.minDate === 0 || tp_inst._defaults.minDateTime === 0) { + tp_inst._defaults.minDate = new Date(); + } + if (tp_inst._defaults.maxDate === 0 || tp_inst._defaults.maxDateTime === 0) { + tp_inst._defaults.maxDate = new Date(); + } + + // datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime.. + if (tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date) { + tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime()); + } + if (tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date) { + tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime()); + } + if (tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date) { + tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime()); + } + if (tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date) { + tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime()); + } + tp_inst.$input.bind('focus', function() { + tp_inst._onFocus(); + }); + + return tp_inst; + }, + + /* + * add our sliders to the calendar + */ + _addTimePicker: function(dp_inst) { + var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ? this.$input.val() + ' ' + this.$altInput.val() : this.$input.val(); + + this.timeDefined = this._parseTime(currDT); + this._limitMinMaxDateTime(dp_inst, false); + this._injectTimePicker(); + }, + + /* + * parse the time string from input value or _setTime + */ + _parseTime: function(timeString, withDate) { + if (!this.inst) { + this.inst = $.datepicker._getInst(this.$input[0]); + } + + if (withDate || !this._defaults.timeOnly) { + var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat'); + try { + var parseRes = parseDateTimeInternal(dp_dateFormat, this._defaults.timeFormat, timeString, $.datepicker._getFormatConfig(this.inst), this._defaults); + if (!parseRes.timeObj) { + return false; + } + $.extend(this, parseRes.timeObj); + } catch (err) { + $.timepicker.log("Error parsing the date/time string: " + err + + "\ndate/time string = " + timeString + + "\ntimeFormat = " + this._defaults.timeFormat + + "\ndateFormat = " + dp_dateFormat); + return false; + } + return true; + } else { + var timeObj = $.datepicker.parseTime(this._defaults.timeFormat, timeString, this._defaults); + if (!timeObj) { + return false; + } + $.extend(this, timeObj); + return true; + } + }, + + /* + * generate and inject html for timepicker into ui datepicker + */ + _injectTimePicker: function() { + var $dp = this.inst.dpDiv, + o = this.inst.settings, + tp_inst = this, + litem = '', + uitem = '', + max = {}, + gridSize = {}, + size = null; + + // Prevent displaying twice + if ($dp.find("div.ui-timepicker-div").length === 0 && o.showTimepicker) { + var noDisplay = ' style="display:none;"', + html = '
' + '
' + o.timeText + '
' + + '
'; + + // Create the markup + for(var i=0,l=this.units.length; i' + o[litem +'Text'] + '' + + '
'; + + if (o['show'+uitem] && o[litem+'Grid'] > 0) { + html += '
'; + + if(litem == 'hour'){ + for (var h = o[litem+'Min']; h <= max[litem]; h += parseInt(o[litem+'Grid'], 10)) { + gridSize[litem]++; + var tmph = $.datepicker.formatTime(useAmpm(o.pickerTimeFormat || o.timeFormat)? 'hht':'HH', {hour:h}, o); + html += ''; + } + } + else{ + for (var m = o[litem+'Min']; m <= max[litem]; m += parseInt(o[litem+'Grid'], 10)) { + gridSize[litem]++; + html += ''; + } + } + + html += '
' + tmph + '' + ((m < 10) ? '0' : '') + m + '
'; + } + html += '
'; + } + + // Timezone + html += '
' + o.timezoneText + '
'; + html += '
'; + + // Create the elements from string + html += '
'; + var $tp = $(html); + + // if we only want time picker... + if (o.timeOnly === true) { + $tp.prepend('
' + '
' + o.timeOnlyTitle + '
' + '
'); + $dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide(); + } + + // add sliders, adjust grids, add events + for(var i=0,l=tp_inst.units.length; i 0) { + size = 100 * gridSize[litem] * o[litem+'Grid'] / (max[litem] - o[litem+'Min']); + $tp.find('.ui_tpicker_'+litem+' table').css({ + width: size + "%", + marginLeft: o.isRTL? '0' : ((size / (-2 * gridSize[litem])) + "%"), + marginRight: o.isRTL? ((size / (-2 * gridSize[litem])) + "%") : '0', + borderCollapse: 'collapse' + }).find("td").click(function(e){ + var $t = $(this), + h = $t.html(), + n = parseInt(h.replace(/[^0-9]/g),10), + ap = h.replace(/[^apm]/ig), + f = $t.data('for'); // loses scope, so we use data-for + + if(f == 'hour'){ + if(ap.indexOf('p') !== -1 && n < 12){ + n += 12; + } + else{ + if(ap.indexOf('a') !== -1 && n === 12){ + n = 0; + } + } + } + + tp_inst.control.value(tp_inst, tp_inst[f+'_slider'], litem, n); + + tp_inst._onTimeChange(); + tp_inst._onSelectHandler(); + }) + .css({ + cursor: 'pointer', + width: (100 / gridSize[litem]) + '%', + textAlign: 'center', + overflow: 'hidden' + }); + } // end if grid > 0 + } // end for loop + + // Add timezone options + this.timezone_select = $tp.find('.ui_tpicker_timezone').append('').find("select"); + $.fn.append.apply(this.timezone_select, + $.map(o.timezoneList, function(val, idx) { + return $("