Changeset - 7276b170ce8b
[Not reviewed]
beta
0 8 0
Marcin Kuzminski - 14 years ago 2011-11-13 01:16:12
marcin@python-works.com
#71 code-review
- simple inline comments
8 files changed with 202 insertions and 21 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/changeset.py
Show inline comments
 
@@ -89,31 +89,35 @@ class ChangesetController(BaseRepoContro
 
            log.error(traceback.format_exc())
 
            h.flash(str(e), category='warning')
 
            return redirect(url('home'))
 

	
 
        c.changes = OrderedDict()
 
        c.sum_added = 0
 
        c.sum_removed = 0
 
        c.lines_added = 0
 
        c.lines_deleted = 0
 
        c.cut_off = False  # defines if cut off limit is reached
 

	
 
        c.comments = []
 

	
 
        c.inline_comments = []
 
        c.inline_cnt = 0
 
        # Iterate over ranges (default changeset view is always one changeset)
 
        for changeset in c.cs_ranges:
 
            c.comments.extend(ChangesetCommentsModel()\
 
                              .get_comments(c.rhodecode_db_repo.repo_id,
 
                                            changeset.raw_id))
 

	
 
            inlines = ChangesetCommentsModel()\
 
                        .get_inline_comments(c.rhodecode_db_repo.repo_id,
 
                                             changeset.raw_id)
 
            c.inline_comments.extend(inlines)
 
            c.changes[changeset.raw_id] = []
 
            try:
 
                changeset_parent = changeset.parents[0]
 
            except IndexError:
 
                changeset_parent = None
 

	
 
            #==================================================================
 
            # ADDED FILES
 
            #==================================================================
 
            for node in changeset.added:
 

	
 
                filenode_old = FileNode(node.path, '', EmptyChangeset())
 
@@ -190,24 +194,29 @@ class ChangesetController(BaseRepoContro
 
                    c.lines_deleted += st[1]
 
                    c.changes[changeset.raw_id].append(('changed', node, diff,
 
                                                        cs1, cs2, st))
 

	
 
            #==================================================================
 
            # REMOVED FILES
 
            #==================================================================
 
            if not c.cut_off:
 
                for node in changeset.removed:
 
                    c.changes[changeset.raw_id].append(('removed', node, None,
 
                                                        None, None, (0, 0)))
 

	
 
        # count inline comments
 
        for path, lines in c.inline_comments:
 
            for comments in lines.values():
 
                c.inline_cnt += len(comments)
 

	
 
        if len(c.cs_ranges) == 1:
 
            c.changeset = c.cs_ranges[0]
 
            c.changes = c.changes[c.changeset.raw_id]
 

	
 
            return render('changeset/changeset.html')
 
        else:
 
            return render('changeset/changeset_range.html')
 

	
 
    def raw_changeset(self, revision):
 

	
 
        method = request.GET.get('diff', 'show')
 
        try:
rhodecode/model/comment.py
Show inline comments
 
@@ -40,25 +40,25 @@ class ChangesetCommentsModel(BaseModel):
 
    def create(self, text, repo_id, user_id, revision, f_path=None,
 
               line_no=None):
 
        """
 
        Creates new comment for changeset
 
        
 
        :param text:
 
        :param repo_id:
 
        :param user_id:
 
        :param revision:
 
        :param f_path:
 
        :param line_no:
 
        """
 

	
 
        if text:
 
        comment = ChangesetComment()
 
        comment.repo_id = repo_id
 
        comment.user_id = user_id
 
        comment.revision = revision
 
        comment.text = text
 
        comment.f_path = f_path
 
        comment.line_no = line_no
 

	
 
        self.sa.add(comment)
 
        self.sa.commit()
 
        return comment
 

	
 
@@ -72,22 +72,22 @@ class ChangesetCommentsModel(BaseModel):
 
        self.sa.delete(comment)
 
        self.sa.commit()
 
        return comment
 

	
 

	
 
    def get_comments(self, repo_id, revision):
 
        return ChangesetComment.query()\
 
                .filter(ChangesetComment.repo_id == repo_id)\
 
                .filter(ChangesetComment.revision == revision)\
 
                .filter(ChangesetComment.line_no == None)\
 
                .filter(ChangesetComment.f_path == None).all()
 

	
 
    def get_comments_for_file(self, repo_id, f_path, raw_id):
 
    def get_inline_comments(self, repo_id, revision):
 
        comments = self.sa.query(ChangesetComment)\
 
            .filter(ChangesetComment.repo_id == repo_id)\
 
            .filter(ChangesetComment.commit_id == raw_id)\
 
            .filter(ChangesetComment.f_path == f_path).all()
 
            .filter(ChangesetComment.revision == revision).all()
 

	
 
        paths = defaultdict(lambda:defaultdict(list))
 

	
 
        d = defaultdict(list)
 
        for co in comments:
 
            d[co.line_no].append(co)
 
        return d.items()
 
            paths[co.f_path][co.line_no].append(co)
 
        return paths.items()
rhodecode/model/db.py
Show inline comments
 
@@ -1092,29 +1092,29 @@ class CacheInvalidation(Base, BaseModel)
 
            .filter(CacheInvalidation.cache_key == key).scalar()
 
        inv_obj.cache_active = True
 
        Session.add(inv_obj)
 
        Session.commit()
 

	
 

	
 
class ChangesetComment(Base, BaseModel):
 
    __tablename__ = 'changeset_comments'
 
    __table_args__ = ({'extend_existing':True},)
 
    comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True)
 
    repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False)
 
    revision = Column('revision', String(40), nullable=False)
 
    line_no = Column('line_no', Integer(), nullable=True)
 
    f_path = Column('f_path', String(1000), nullable=True)
 
    line_no = Column('line_no', Unicode(10), nullable=True)
 
    f_path = Column('f_path', Unicode(1000), nullable=True)
 
    user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False)
 
    text = Column('text', String(25000), nullable=False)
 
    modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
 
    text = Column('text', Unicode(25000), nullable=False)
 
    modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now)
 

	
 
    author = relationship('User')
 
    repo = relationship('Repository')
 

	
 

	
 
class DbMigrateVersion(Base, BaseModel):
 
    __tablename__ = 'db_migrate_version'
 
    __table_args__ = {'extend_existing':True}
 
    repository_id = Column('repository_id', String(250), primary_key=True)
 
    repository_path = Column('repository_path', Text)
 
    version = Column('version', Integer)
 

	
rhodecode/public/css/diff.css
Show inline comments
 
@@ -108,13 +108,22 @@ cursor: pointer;
 
}
 
.code-diff pre, .line pre { 
 
	padding: 3px;
 
    margin: 0;
 
}
 
.lineno a { 
 
	text-decoration: none; 
 
}
 

	
 
.line{
 
	padding:0;
 
	margin:0;
 
}
 
\ No newline at end of file
 
}
 

	
 
.line.highlight{
 
	background-color:#FFFFCC;
 
	cursor: pointer;
 
	background-image:url("../images/icons/comment_add.png");
 
	background-repeat:no-repeat;
 
	background-position: right;
 
	background-position: 100% 50%;
 
}
rhodecode/public/css/style.css
Show inline comments
 
@@ -1844,38 +1844,42 @@ h3.files_location {
 
 
.cs_files .cur_cs {
 
	margin: 10px 2px;
 
	font-weight: bold;
 
}
 
 
.cs_files .node {
 
	float: left;
 
}
 
 
.cs_files .changes {
 
	float: right;
 
	color:#003367;
 
	
 
}
 
 
.cs_files .changes .added {
 
	background-color: #BBFFBB;
 
	float: left;
 
	text-align: center;
 
	font-size: 90%;
 
	font-size: 9px;
 
    padding: 2px 0px 2px 0px;
 
}
 
 
.cs_files .changes .deleted {
 
	background-color: #FF8888;
 
	float: left;
 
	text-align: center;
 
	font-size: 90%;
 
	font-size: 9px;
 
    padding: 2px 0px 2px 0px;
 
}
 
 
.cs_files .cs_added {
 
	background: url("../images/icons/page_white_add.png") no-repeat scroll
 
		3px;
 
	height: 16px;
 
	padding-left: 20px;
 
	margin-top: 7px;
 
	text-align: left;
 
}
 
 
.cs_files .cs_changed {
 
@@ -3261,25 +3265,28 @@ div.rst-block  pre {
 
.comments .comment .meta .date {
 
    float: right;
 
}
 
 
.comments .comment .text {
 
    padding: 8px 6px 6px 14px;
 
    background-color: #FAFAFA;
 
}
 
 
.comments .comments-number{
 
	padding:0px 0px 10px 0px;
 
	font-weight: bold;
 
}
 
	color: #666;
 
	font-size: 16px;
 
}
 
/** comment form **/
 
 
.comment-form .clearfix{
 
	background: #EEE;
 
    -webkit-border-radius: 4px;
 
    -moz-border-radius: 4px;
 
    border-radius: 4px;
 
    padding: 10px;
 
}
 
 
div.comment-form {
 
    margin-top: 20px;
 
}
 
@@ -3323,12 +3330,68 @@ form.comment-form {
 
}
 
 
.add-another-button {
 
    margin-left: 10px;
 
    margin-top: 10px;
 
    margin-bottom: 10px;
 
}
 
 
.comment .buttons {
 
    position: absolute;
 
    right:40px;
 
}
 
 
 
 
/** comment inline form **/
 
 
.comment-inline-form .clearfix{
 
    background: #EEE;
 
    -webkit-border-radius: 4px;
 
    -moz-border-radius: 4px;
 
    border-radius: 4px;
 
    padding: 5px;
 
}
 
 
div.comment-inline-form {
 
    margin-top: 5px;
 
    padding:2px 6px 8px 6px;
 
}
 
 
.comment-inline-form strong {
 
    display: block;
 
    margin-bottom: 15px;
 
}
 
 
.comment-inline-form textarea {
 
    width: 100%;
 
    height: 100px;
 
    font-family: 'Monaco', 'Courier', 'Courier New', 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: 0px 0px 2px 0px;
 
    color: #666666;
 
    font-size: 10px;
 
}
 
 
.comment-inline-form .comment-button{
 
    padding-top:5px;
 
}
 
\ No newline at end of file
rhodecode/public/js/rhodecode.js
Show inline comments
 
@@ -289,12 +289,50 @@ var q_filter = function(target,nodes,dis
 
var ajaxPOST = function(url,postData,success) {
 
    var sUrl = url;
 
    var callback = {
 
        success: success,
 
        failure: function (o) {
 
            alert("error");
 
        },
 
    };
 
    var postData = postData;
 
    var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
 
};
 

	
 

	
 
/** comments **/
 
var removeInlineForm = function(form) {
 
	form.parentNode.removeChild(form);
 
}
 

	
 
var createInlineForm = function(parent_tr, f_path, line) {
 
	var form = document.createElement('tr');
 
	YUD.addClass(form, 'comment-form-inline');
 
	var tmpl = YUD.get('comment-inline-form-template').innerHTML;
 
	tmpl = tmpl.format(f_path, line);
 
	form.innerHTML = '<td class="lineno new"></td>'+
 
		             '<td class="lineno old"></td>'+ 
 
			         '<td>{0}</td>'.format(tmpl);
 

	
 
	// create event for hide button
 
	form = new YAHOO.util.Element(form);
 
	var form_hide_button = new YAHOO.util.Element(form.getElementsByClassName('hide-inline-form')[0]);
 
	form_hide_button.on('click', function(e) {
 
		var newtr = e.currentTarget.parentNode.parentNode.parentNode.parentNode.parentNode;
 
		removeInlineForm(newtr);
 
		YUD.removeClass(parent_tr, 'form-open');
 
	});
 
	return form
 
}
 
var getLineNo = function(tr) {
 
	var line;
 
	var o = tr.children[0].id.split('_');
 
	var n = tr.children[1].id.split('_');
 

	
 
	if (n.length == 2) {
 
		line = n[1];
 
	} else if (o.length == 2) {
 
		line = o[1];
 
	}
 

	
 
	return line
 
}
 
\ No newline at end of file
rhodecode/templates/changeset/changeset.html
Show inline comments
 
@@ -105,69 +105,110 @@
 
    </div>
 
    	
 
	%for change,filenode,diff,cs1,cs2,stat in c.changes:
 
		%if change !='removed':
 
		<div style="clear:both;height:10px"></div>
 
		<div class="diffblock  margined">
 
			<div id="${'C-%s-%s' % (h.short_id(filenode.changeset.raw_id),h.safeid(h.safe_unicode(filenode.path)))}" class="code-header">
 
				<div class="changeset_header">
 
					<span class="changeset_file">
 
						${h.link_to_if(change!='removed',h.safe_unicode(filenode.path),h.url('files_home',repo_name=c.repo_name,
 
						revision=filenode.changeset.raw_id,f_path=h.safe_unicode(filenode.path)))}
 
					</span>
 
					%if 1:
 
					&raquo; <span>${h.link_to(_('diff'),
 
					h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='diff'))}</span>
 
					&raquo; <span>${h.link_to(_('raw diff'),
 
					h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='raw'))}</span>
 
					&raquo; <span>${h.link_to(_('download diff'),
 
					h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='download'))}</span>
 
					%endif
 
				</div>
 
			</div>
 
			<div class="code-body">        
 
                <div class="full_f_path" path="${filenode.path}"></div>        
 
					%if diff:
 
						${diff|n}
 
					%else:
 
						${_('No changes in this file')}
 
					%endif
 
			</div>
 
		</div>
 
		%endif
 
	%endfor
 
  
 
    <%namespace name="comment" file="/changeset/changeset_file_comment.html"/>
 
    ## template for inline comment form
 
    ${comment.comment_inline_form()}
 
    
 
    <div class="comments">
 
        <div class="comments-number">${len(c.comments)} comment(s)</div>
 
        <div class="comments-number">${len(c.comments)} comment(s) (${c.inline_cnt} ${_('inline')})</div>
 
        
 
        %for path, lines in c.inline_comments:
 
            <div class="inline-comment-placeholder" path="${path} ">
 
            % for line,comments in lines.iteritems():
 
                <div class="inline-comment-placeholder-line" line="${line}"> 
 
                %for co in comments:
 
                    ${comment.comment_block(co)}
 
                %endfor
 
                </div>
 
            %endfor
 
            </div>
 
        %endfor        
 
        
 
        %for co in c.comments:
 
            ${comment.comment_block(co)}
 
        %endfor
 
        %if c.rhodecode_user.username != 'default':
 
        <div class="comment-form">
 
            ${h.form(h.url('changeset_comment', repo_name=c.repo_name, revision=c.changeset.raw_id))}
 
            <strong>Leave a comment</strong>
 
            <strong>${_('Leave a comment')}</strong>
 
            <div class="clearfix">
 
                <div class="comment-help">${_('Comments parsed using RST syntax')}</div>
 
                    ${h.textarea('text')}
 
            </div>
 
            <div class="comment-button">
 
            ${h.submit('save', _('Comment'), class_='ui-button')}
 
            </div>
 
            ${h.end_form()}
 
        </div>
 
        %endif
 
    </div>
 
    <script type="text/javascript">
 
      var deleteComment = function(comment_id){
 

	
 
          var url = "${url('changeset_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}".replace('__COMMENT_ID__',comment_id);
 
          var postData = '_method=delete';
 
          var success = function(o){
 
              var n = YUD.get('comment-'+comment_id);
 
              n.parentNode.removeChild(n);
 
          }
 
          ajaxPOST(url,postData,success);
 
      } 
 

	
 
      YUE.onDOMReady(function(){
 
    	  YUE.on(YUQ('.line'),'mouseenter',function(e){
 
    		  var tr = e.currentTarget;
 
              if(YUD.hasClass(tr,'form-open') || YUD.hasClass(tr,'context')){
 
                  return
 
              }    		  
 
    		  YUD.addClass(tr,'highlight');
 
    	  });
 
          YUE.on(YUQ('.line'),'mouseleave',function(e){
 
              YUD.removeClass(e.currentTarget,'highlight');
 
          });
 
          
 
          YUE.on(YUQ('.line'),'click',function(e){
 
        	  var tr = e.currentTarget;
 
        	  if(YUD.hasClass(tr,'form-open') || YUD.hasClass(tr,'context')){
 
        		  return
 
        	  }
 
        	  YUD.addClass(tr,'form-open');
 
        	  var node = tr.parentNode.parentNode.parentNode.getElementsByClassName('full_f_path')[0];
 
        	  var f_path = YUD.getAttribute(node,'path');
 
        	  var lineno = getLineNo(tr);
 
        	  var form = createInlineForm(tr, f_path, lineno);
 
        	  YUD.insertAfter(form,tr);
 
          })
 
      })
 
      
 
    </script> 
 
  </div>	
 
</%def>
rhodecode/templates/changeset/changeset_file_comment.html
Show inline comments
 
@@ -19,13 +19,34 @@
 
  			${h.age(co.modified_at)}
 
  		</span>
 
  	</div>
 
  	<div class="text">
 
  		%if h.HasPermissionAny('hg.admin', 'repository.admin')() or co.author.user_id == c.rhodecode_user.user_id:
 
  			<div class="buttons">
 
  				<span onClick="deleteComment(${co.comment_id})" class="delete-comment ui-button-small">${_('Delete')}</span>
 
  			</div>
 
  		%endif
 
  		${h.rst(co.text)|n}
 
  	</div>
 
  </div>
 
</%def>
 
 
 
 
<%def name="comment_inline_form()">
 
<div id='comment-inline-form-template' style="display:none">
 
  <div class="comment-inline-form">
 
      ${h.form(h.url('changeset_comment', repo_name=c.repo_name, revision=c.changeset.raw_id))}
 
      <div class="clearfix">
 
          <div class="comment-help">${_('Commenting on line')} {1} ${_('comments parsed using RST syntax')}</div>
 
              ${h.textarea('text')}
 
      </div>
 
      <div class="comment-button">
 
      <input type="hidden" name="f_path" value="{0}">
 
      <input type="hidden" name="line" value="{1}">            
 
      ${h.submit('save', _('Comment'), class_='ui-button-small')}
 
      ${h.reset('hide-inline-form', _('Hide'), class_='ui-button-small hide-inline-form')}
 
      </div>
 
      ${h.end_form()}
 
  </div>
 
</div>  
 
</%def>
 
\ No newline at end of file
0 comments (0 inline, 0 general)