Changeset - 80ae9f5e9b32
[Not reviewed]
default
0 5 0
Mads Kiilerich - 8 years ago 2017-06-18 01:09:18
mads@kiilerich.com
notifications: remove custom 'container' class to avoid conflict with Bootstrap ... and rewrite things to use plain Bootstrap

Most of the markup and styling turned out to be easy to replace with plain
Bootstrap markup.
5 files changed with 19 insertions and 68 deletions:
0 comments (0 inline, 0 general)
kallithea/public/css/style.css
Show inline comments
 
@@ -2863,232 +2863,192 @@ div.comment-inline-form {
 
    font-family: Lucida Console, Consolas, Monaco, Inconsolata, Liberation Mono, monospace;
 
}
 

	
 
form.comment-inline-form {
 
    margin-top: 10px;
 
    margin-left: 10px;
 
}
 

	
 
.comment-inline-form-submit {
 
    margin-top: 5px;
 
    margin-left: 525px;
 
}
 

	
 
.file-comments {
 
    display: none;
 
}
 

	
 
.comment-inline-form .comment {
 
    margin-left: 10px;
 
}
 

	
 
.comment-inline-form .comment-help {
 
    padding: 5px 5px 5px 5px;
 
    color: #666;
 
}
 

	
 
.comment-inline-form .comment-button {
 
    padding-top: 5px;
 
}
 

	
 
/** comment inline **/
 
.inline-comments .comment {
 
    margin: 3px 3px 5px 5px;
 
}
 

	
 
.inline-comments #comments-general-comments .comment {
 
    margin-left: 0;
 
}
 

	
 
.inline-comments .comment .comment-wrapp {
 
    max-width: 978px;
 
    border: 1px solid #ddd;
 
    border-radius: 4px;
 
    background-color: #FAFAFA;
 
}
 

	
 
.inline-comments .add-button-row {
 
    padding: 2px 4px 8px 5px;
 
}
 

	
 
.inline-comments .comment .meta {
 
    background: #f8f8f8;
 
    padding: 4px;
 
    border-bottom: 1px solid #ddd;
 
    min-height: 15px;
 
    overflow: auto;
 
}
 

	
 
.inline-comments .comment .meta img {
 
    vertical-align: middle;
 
}
 

	
 
.inline-comments .comment .meta .user {
 
    font-weight: bold;
 
    float: left;
 
    padding: 3px;
 
}
 

	
 
.inline-comments .comment .meta .date {
 
    float: left;
 
    padding: 3px;
 
}
 

	
 
.inline-comments .comment .text {
 
    background-color: #FAFAFA;
 
    margin: 6px;
 
}
 

	
 
.inline-comments .comments-number {
 
    padding: 0px 0px 10px 0px;
 
    color: #666;
 
}
 

	
 
input.status_change_checkbox,
 
input.status_change_radio {
 
    margin: 0 0 5px 15px;
 
}
 

	
 
.badge {
 
    padding: 4px 4px !important;
 
    text-align: center;
 
    color: #888 !important;
 
    background-color: #DEDEDE !important;
 
    border-radius: 4px !important;
 
}
 

	
 
.notification-header {
 
    padding-top: 6px;
 
}
 
.notification-header .desc {
 
    font-size: 16px;
 
    height: 24px;
 
    float: left
 
}
 
.notification-list .container.unread {
 
    background: none repeat scroll 0 0 rgba(255, 255, 180, 0.6);
 
}
 
.notification-header .gravatar {
 
    background: none repeat scroll 0 0 transparent;
 
    padding: 0px 0px 0px 8px;
 
}
 
.notification-list .container .notification-header .desc {
 
    font-weight: bold;
 
    font-size: 17px;
 
}
 
.notification-header .delete-notifications {
 
    float: right;
 
    padding-top: 8px;
 
    cursor: pointer;
 
}
 
.notification-header .read-notifications {
 
    float: right;
 
    padding-top: 8px;
 
    cursor: pointer;
 
}
 
.notification-subject {
 
    clear: both;
 
    border-bottom: 1px solid #eee;
 
    padding: 5px 0px;
 
}
 

	
 
.notification-body {
 
    clear: both;
 
    margin: 34px 2px 2px 8px
 
}
 

	
 
/****
 
PULL REQUESTS
 
*****/
 
.pullrequests_section_head {
 
    padding: 10px 10px 10px 0px;
 
    margin: 0 15px;
 
    font-size: 16px;
 
    font-weight: bold;
 
}
 

	
 
div.pr-details-title.closed {
 
    color: #555;
 
    background: #eee;
 
}
 

	
 
div.pr {
 
    margin: 0px 15px;
 
    padding: 4px 4px;
 
}
 
div.pr-desc {
 
    margin: 0px 15px;
 
}
 
tr.pr-closed td {
 
    background-color: #eee !important;
 
    color: #555 !important;
 
}
 

	
 
span.pr-closed-tag {
 
    margin-bottom: 1px;
 
    margin-right: 1px;
 
    padding: 1px 3px;
 
    font-size: 10px;
 
    padding: 1px 3px 1px 3px;
 
    font-size: 10px;
 
    color: #577632;
 
    white-space: nowrap;
 
    border-radius: 4px;
 
    border: 1px solid #d9e8f8;
 
    line-height: 1.5em;
 
}
 

	
 
.panel-body .pr-box {
 
    max-width: 978px;
 
    margin-right: 15px;
 
}
 

	
 
#s2id_org_ref,
 
#s2id_other_ref,
 
#s2id_org_repo,
 
#s2id_other_repo {
 
    min-width: 150px;
 
    margin: 5px;
 
}
 

	
 
#pr-summary .msg-div {
 
    margin: 5px 0;
 
}
 

	
 
#pr-summary > .pr-not-edit {
 
    min-height: 50px !important;
 
}
 

	
 
#pr-edit-btn {
 
    margin: 20px 0 0 !important;
 
    position: absolute;
 
}
 

	
 
/****
 
  PERMS
 
*****/
 
#perms .perms_section_head {
 
    padding: 10px 10px 10px 0px;
 
    font-size: 16px;
 
    font-weight: bold;
 
    text-transform: capitalize;
 
}
 

	
 
#perms .perms_section_head label {
 
    margin-left: 10px;
 
}
 

	
 
#perms .perm_tag {
 
    position: relative;
 
    top: -2px;
 
    margin-left: 3px;
 
    padding: 3px 3px 1px 3px;
 
    font-size: 10px;
 
    font-weight: bold;
 
    text-transform: uppercase;
 
    white-space: nowrap;
 
    border-radius: 3px;
 
}
 

	
 
#perms .perm_tag.admin {
 
    background-color: #B94A48;
 
    color: #ffffff;
kallithea/public/js/base.js
Show inline comments
 
@@ -878,193 +878,193 @@ var initCodeMirror = function(textarea_i
 
    $('#reset').click(function(e){
 
            window.location=resetUrl;
 
        });
 

	
 
    $('#file_enable').click(function(){
 
            $('#upload_file_container').hide();
 
            $('#filename_container').show();
 
            $('#body').show();
 
        });
 

	
 
    $('#upload_file_enable').click(function(){
 
            $('#upload_file_container').show();
 
            $('#filename_container').hide();
 
            $('#body').hide();
 
        });
 

	
 
    return myCodeMirror
 
};
 

	
 
var setCodeMirrorMode = function(codeMirrorInstance, mode) {
 
    CodeMirror.autoLoadMode(codeMirrorInstance, mode);
 
}
 

	
 

	
 
var _getIdentNode = function(n){
 
    //iterate thrugh nodes until matching interesting node
 

	
 
    if (typeof n == 'undefined'){
 
        return -1
 
    }
 

	
 
    if(typeof n.id != "undefined" && n.id.match('L[0-9]+')){
 
        return n
 
    }
 
    else{
 
        return _getIdentNode(n.parentNode);
 
    }
 
};
 

	
 
/* generate links for multi line selects that can be shown by files.html page_highlights.
 
 * This is a mouseup handler for hlcode from CodeHtmlFormatter and pygmentize */
 
var getSelectionLink = function(e) {
 
    //get selection from start/to nodes
 
    if (typeof window.getSelection != "undefined") {
 
        var s = window.getSelection();
 

	
 
        var from = _getIdentNode(s.anchorNode);
 
        var till = _getIdentNode(s.focusNode);
 

	
 
        var f_int = parseInt(from.id.replace('L',''));
 
        var t_int = parseInt(till.id.replace('L',''));
 

	
 
        var yoffset = 35;
 
        var ranges = [parseInt(from.id.replace('L','')), parseInt(till.id.replace('L',''))];
 
        if (ranges[0] > ranges[1]){
 
            //highlight from bottom
 
            yoffset = -yoffset;
 
            ranges = [ranges[1], ranges[0]];
 
        }
 
        var $hl_div = $('div#linktt');
 
        // if we select more than 2 lines
 
        if (ranges[0] != ranges[1]){
 
            if ($hl_div.length) {
 
                $hl_div.html('');
 
            } else {
 
                $hl_div = $('<div id="linktt" class="hl-tip-box">');
 
                $('body').prepend($hl_div);
 
            }
 

	
 
            $hl_div.append($('<a>').html(_TM['Selection Link']).prop('href', location.href.substring(0, location.href.indexOf('#')) + '#L' + ranges[0] + '-'+ranges[1]));
 
            var xy = $(till).offset();
 
            $hl_div.css('top', (xy.top + yoffset) + 'px').css('left', xy.left + 'px');
 
            $hl_div.show();
 
        }
 
        else{
 
            $hl_div.hide();
 
        }
 
    }
 
};
 

	
 
var deleteNotification = function(url, notification_id, callbacks){
 
    var success = function(o){
 
            $("#notification_"+notification_id).remove();
 
            _run_callbacks(callbacks);
 
        };
 
    var failure = function(o){
 
            alert("deleteNotification failure");
 
        };
 
    var postData = {};
 
    var sUrl = url.replace('__NOTIFICATION_ID__',notification_id);
 
    ajaxPOST(sUrl, postData, success, failure);
 
};
 

	
 
var readNotification = function(url, notification_id, callbacks){
 
    var success = function(o){
 
            var $obj = $("#notification_"+notification_id);
 
            $obj.removeClass('unread');
 
            $obj.removeClass('list-group-item-warning');
 
            $obj.find('.read-notification').remove();
 
            _run_callbacks(callbacks);
 
        };
 
    var failure = function(o){
 
            alert("readNotification failure");
 
        };
 
    var postData = {};
 
    var sUrl = url.replace('__NOTIFICATION_ID__',notification_id);
 
    ajaxPOST(sUrl, postData, success, failure);
 
};
 

	
 
/**
 
 * Autocomplete functionality
 
 */
 

	
 
// Custom search function for the DataSource of users
 
var autocompleteMatchUsers = function (sQuery, myUsers) {
 
    // Case insensitive matching
 
    var query = sQuery.toLowerCase();
 
    var i = 0;
 
    var l = myUsers.length;
 
    var matches = [];
 

	
 
    // Match against each name of each contact
 
    for (; i < l; i++) {
 
        var contact = myUsers[i];
 
        if (((contact.fname+"").toLowerCase().indexOf(query) > -1) ||
 
             ((contact.lname+"").toLowerCase().indexOf(query) > -1) ||
 
             ((contact.nname) && ((contact.nname).toLowerCase().indexOf(query) > -1))) {
 
            matches[matches.length] = contact;
 
        }
 
    }
 
    return matches;
 
};
 

	
 
// Custom search function for the DataSource of userGroups
 
var autocompleteMatchGroups = function (sQuery, myGroups) {
 
    // Case insensitive matching
 
    var query = sQuery.toLowerCase();
 
    var i = 0;
 
    var l = myGroups.length;
 
    var matches = [];
 

	
 
    // Match against each name of each group
 
    for (; i < l; i++) {
 
        var matched_group = myGroups[i];
 
        if (matched_group.grname.toLowerCase().indexOf(query) > -1) {
 
            matches[matches.length] = matched_group;
 
        }
 
    }
 
    return matches;
 
};
 

	
 
// Helper highlight function for the formatter
 
var autocompleteHighlightMatch = function (full, snippet, matchindex) {
 
    return full.substring(0, matchindex)
 
        + "<span class='match'>"
 
        + full.substr(matchindex, snippet.length)
 
        + "</span>" + full.substring(matchindex + snippet.length);
 
};
 

	
 
// Return html snippet for showing the provided gravatar url
 
var gravatar = function(gravatar_lnk, size, cssclass) {
 
    if (!gravatar_lnk) {
 
        return '';
 
    }
 
    if (gravatar_lnk == 'default') {
 
        return '<i class="icon-user {1}" style="font-size: {0}px;"></i>'.format(size, cssclass);
 
    }
 
    return '<img alt="" class="{2}" style="width: {0}px; height: {0}px" src="{1}"/>'.format(size, gravatar_lnk, cssclass);
 
}
 

	
 
var autocompleteGravatar = function(res, gravatar_lnk, size, group) {
 
    var elem;
 
    if (group !== undefined) {
 
        elem = '<i class="perm-gravatar-ac icon-users"></i>';
 
    } else {
 
        elem = gravatar(gravatar_lnk, size, "perm-gravatar-ac");
 
    }
 
    return '<div class="ac-container-wrap">{0}{1}</div>'.format(elem, res);
 
}
 

	
 
// Custom formatter to highlight the matching letters
 
var autocompleteFormatter = function (oResultData, sQuery, sResultMatch) {
 
    var query = sQuery.toLowerCase();
 

	
 
    // group
 
    if (oResultData.grname != undefined) {
 
        var grname = oResultData.grname;
 
        var grmembers = oResultData.grmembers;
 
        var grnameMatchIndex = grname.toLowerCase().indexOf(query);
 
        var grprefix = "{0}: ".format(_TM['Group']);
 
        var grsuffix = " ({0} {1})".format(grmembers, _TM['members']);
 

	
 
        if (grnameMatchIndex > -1) {
 
            return autocompleteGravatar(grprefix + autocompleteHighlightMatch(grname, query, grnameMatchIndex) + grsuffix, null, null, true);
kallithea/templates/admin/notifications/notifications.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 

	
 
<%block name="title">
 
    ${_('My Notifications')} ${request.authuser.username}
 
</%block>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${_('My Notifications')}
 
</%def>
 

	
 
<%block name="header_menu">
 
    ${self.menu('admin')}
 
</%block>
 

	
 
<%def name="main()">
 
<div class="panel panel-primary">
 
    <div class="panel-heading clearfix">
 
        ${self.breadcrumbs()}
 
    </div>
 

	
 
    <div class="panel-body">
 
      <div class="pull-left">
 
            <span id='all' class="btn btn-default btn-sm"><a href="${h.url.current()}">${_('All')}</a></span>
 
            <span id='comment' class="btn btn-default btn-sm"><a href="${h.url.current(type=c.comment_type)}">${_('Comments')}</a></span>
 
            <span id='pull_request' class="btn btn-default btn-sm"><a href="${h.url.current(type=c.pull_request_type)}">${_('Pull Requests')}</a></span>
 
            <a class="btn btn-default btn-sm" href="${h.url.current()}">${_('All')}</a>
 
            <a class="btn btn-default btn-sm" href="${h.url.current(type=c.comment_type)}">${_('Comments')}</a>
 
            <a class="btn btn-default btn-sm" href="${h.url.current(type=c.pull_request_type)}">${_('Pull Requests')}</a>
 
      </div>
 
      %if c.notifications:
 
        <span id='mark_all_read' class="btn btn-default btn-sm pull-right">${_('Mark All Read')}</span>
 
      %endif
 
    </div>
 
    <div id="notification_data" class="panel-body">
 
        <%include file='notifications_data.html'/>
 
    </div>
 
</div>
 
<script type="text/javascript">
 
var url_delete = ${h.js(url('notification_delete', notification_id='__NOTIFICATION_ID__'))};
 
var url_read = ${h.js(url('notification_update', notification_id='__NOTIFICATION_ID__'))};
 
var run = function(){
 
  $('.delete-notification').click(function(e){
 
    var notification_id = e.currentTarget.id;
 
    deleteNotification(url_delete,notification_id);
 
  });
 
  $('.read-notification').click(function(e){
 
    var notification_id = e.currentTarget.id;
 
    readNotification(url_read,notification_id);
 
  });
 
}
 
run();
 
$('#mark_all_read').click(function(){
 
    var url = ${h.js(h.url('notifications_mark_all_read', **request.GET.mixed()))};
 
    asynchtml(url, $('#notification_data'), function(){run();});
 
});
 

	
 
var current_filter = ${h.js(c.current_filter)};
 
$('#'+current_filter).addClass('active');
 
</script>
 
</%def>
kallithea/templates/admin/notifications/notifications_data.html
Show inline comments
 

	
 
%if c.notifications:
 
<%
 
unread = lambda n:{False:'unread'}.get(n)
 
%>
 

	
 
<div class="notification-list notification-table list-group">
 
<div class="list-group">
 
%for notification in c.notifications:
 
  <div id="notification_${notification.notification.notification_id}" class="list-group-item ${unread(notification.read)}">
 
    <div>
 
  <div id="notification_${notification.notification.notification_id}" class="list-group-item ${'' if notification.read else 'list-group-item-warning'} clearfix">
 
      ${h.gravatar_div(notification.notification.created_by_user.email, size=24)}
 
      <span class="desc ${unread(notification.read)}">
 
      <span class="pull-left">
 
        <a href="${url('notification', notification_id=notification.notification.notification_id)}">${notification.notification.description}</a>
 
      </span>
 
      <span class="delete-notifications" title="${_('Delete')}">
 
        <span id="${notification.notification.notification_id}" class="delete-notification"><i class="btn icon-minus-circled"></i></span>
 
      <span class="pull-right">
 
        %if not notification.read:
 
          <span id="${notification.notification.notification_id}" class="btn btn-default btn-xs read-notification"><i class="icon-ok"></i>${_('Mark as read')}</span>
 
        %endif
 
        <span id="${notification.notification.notification_id}" class="btn btn-default btn-xs delete-notification"><i class="icon-minus-circled"></i>${_('Delete')}</span>
 
      </span>
 
      %if not notification.read:
 
      <span class="read-notifications" title="${_('Mark as read')}">
 
        <span id="${notification.notification.notification_id}" class="read-notification"><i class="btn icon-ok"></i></span>
 
      </span>
 
      %endif
 
    </div>
 
    <div class="notification-subject"></div>
 
  </div>
 
%endfor
 
</div>
 

	
 
<ul class="pagination">
 
    ${c.notifications.pager(controller='admin/notifications', **request.GET.mixed())}
 
</ul>
 

	
 
%else:
 
    <div>${_('No notifications here yet')}</div>
 
%endif
kallithea/templates/admin/notifications/show_notification.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="/base/base.html"/>
 

	
 
<%block name="title">
 
    ${_('Show Notification')} ${request.authuser.username}
 
</%block>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_('Notifications'),h.url('notifications'))}
 
    &raquo;
 
    ${_('Show Notification')}
 
</%def>
 

	
 
<%block name="header_menu">
 
    ${self.menu('admin')}
 
</%block>
 

	
 
<%def name="main()">
 
<div class="panel panel-primary">
 
    <div class="panel-heading clearfix">
 
        ${self.breadcrumbs()}
 
    </div>
 
    <div class="panel-body">
 
      <div id="notification_${c.notification.notification_id}">
 
        <div class="notification-header">
 
        <div class="clearfix">
 
          ${h.gravatar_div(c.notification.created_by_user.email, size=24)}
 
          <span class="desc">
 
          <span class="pull-left">
 
              ${c.notification.description}
 
          </span>
 
          <span class="delete-notifications">
 
            <span id="${c.notification.notification_id}" class="delete-notification action"><i class="btn icon-minus-circled"></i></span>
 
          </span>
 
          <span id="${c.notification.notification_id}" class="delete-notification btn btn-default pull-right"><i class="icon-minus-circled"></i>${_('Delete')}</span>
 
        </div>
 
        <div class="notification-body">
 
            <div class="notification-subject">${h.literal(c.notification.subject)}</div>
 
        <div>
 
            %if c.notification.subject:
 
                <div class="h4">${h.literal(c.notification.subject)}</div>
 
            %endif
 
            <div class="well">
 
            %if c.notification.body:
 
                ${h.render_w_mentions(c.notification.body)}
 
            %endif
 
            </div>
 
        </div>
 
      </div>
 
    </div>
 
</div>
 
<script type="text/javascript">
 
var url = ${h.js(url('notification_delete', notification_id='__NOTIFICATION_ID__'))};
 
var main = ${h.js(url('notifications'))};
 
   $('.delete-notification').click(function(e){
 
       var notification_id = e.currentTarget.id;
 
       deleteNotification(url,notification_id,[function(){window.location=main}]);
 
   });
 
</script>
 
</%def>
0 comments (0 inline, 0 general)