diff --git a/apps/comments/css/comments.css b/apps/comments/css/comments.scss similarity index 70% rename from apps/comments/css/comments.css rename to apps/comments/css/comments.scss index 311eeebe4db432684b129c2113530a0689796ec2..c2bc136ba66cb48275169ec90723fdfd5634bfe8 100644 --- a/apps/comments/css/comments.css +++ b/apps/comments/css/comments.scss @@ -13,53 +13,40 @@ } #commentsTabView .newCommentForm { - position: relative; - margin-bottom: 20px; + margin-left: 36px; } #commentsTabView .newCommentForm .message { - width: calc(100% - 81px); /* 36 (left margin) + 30 (right padding) + 15 (right padding of surrounding box) */ - margin-left: 36px; - padding-right: 30px; - display: block; + /* width = 100% - (width of submit button (44px) + margin (3px) + inline-block gap) */ + width: calc(100% - 52px); + display: inline-block; } #commentsTabView .newCommentForm .submit { - position: absolute; - bottom: 0px; - right: 8px; - width: 30px; + width: 44px; margin: 0; - padding: 7px 9px; + padding: 13px; background-color: transparent; border: none; opacity: .3; + vertical-align: bottom; } -#commentsTabView .newCommentForm .submit:not(:disabled):hover, -#commentsTabView .newCommentForm .submit:not(:disabled):focus { - opacity: 1; -} - -#commentsTabView .newCommentForm .submitLoading { - background-position: left; - /* Match rules for '#commentsTabView .newCommentForm .submit' to place the - loading icon at the same position as the confirm icon */ - position: absolute; - bottom: 0px; - right: 8px; - width: 30px; - margin: 0; - padding: 7px 9px; +#commentsTabView .deleteLoading { + float: right; + padding: 14px; + vertical-align: middle; +} - /* Match rules for 'input[type="submit"]' to place the loading icon at the - same position as the confirm icon */ - min-height: 34px; - box-sizing: border-box; +#commentsTabView .submitLoading { + vertical-align: bottom; + display: inline-block; + padding: 14px; } -#commentsTabView .newCommentForm .cancel { - margin-right: 6px; +#commentsTabView .newCommentForm .submit:not(:disabled):hover, +#commentsTabView .newCommentForm .submit:not(:disabled):focus { + opacity: 1; } #commentsTabView .newCommentForm div.message { @@ -73,11 +60,16 @@ #commentsTabView .comment { position: relative; - margin-bottom: 30px; + /** padding bottom is little more so that the top and bottom gap look uniform **/ + padding: 10px 0px 15px; word-wrap: break-word; overflow-wrap: break-word; } +#commentsTabView .comments .comment { + border-top: 1px solid $color-border; +} + #commentsTabView .comment .avatar, .atwho-view-ul * .avatar{ width: 32px; @@ -123,19 +115,22 @@ background: -o-linear-gradient(rgba(255,255,255,0), rgba(255,255,255,1)); background: -ms-linear-gradient(rgba(255,255,255,0), rgba(255,255,255,1)); background: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,1)); - filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#00FFFFFF', endColorstr='#FFFFFFFF'); background-repeat: no-repeat; } -#commentsTabView .authorRow>div:not(.contactsmenu-popover) { - display: inline-block; - vertical-align: middle; -} - -#commentsTabView .authorRow>div.hidden { +#commentsTabView .hidden { display: none !important; } +/** set min-height as 44px to ensure that it fits the button sizes. **/ +#commentsTabView .comment .authorRow { + min-height: 44px; +} +#commentsTabView .comment .authorRow .tooltip { + /** because of the padding on the element, the tooltip appear too far up, + adding this brings them closer to the element**/ + margin-top: 5px; +} #commentsTabView .comments li .message .avatar-name-wrapper, .atwho-view-ul * .avatar-name-wrapper, #commentsTabView .comment .authorRow { @@ -164,47 +159,48 @@ .atwho-view-ul * .avatar-name-wrapper { white-space: nowrap; } - #commentsTabView .comment .author, #commentsTabView .comment .date { opacity: .5; } +#commentsTabView .comment .author { + max-width: 210px; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} #commentsTabView .comment .date { margin-left: auto; + /** this is to fix the tooltip being too close due to the margin-top applied + to bring the tooltip closer for the action icons **/ + padding: 10px 0px; } -#commentsTabView .comments li .message { +#commentsTabView .comments > li:not(.newCommentRow) .message { padding-left: 40px; - display: inline-flex; - flex-wrap: wrap; - align-items: center; } #commentsTabView .comment .action { - opacity: 0; - padding: 5px; -} - -#commentsTabView .comment:hover .action { opacity: 0.3; + padding: 14px; + display: block; } -#commentsTabView .comment .action:hover { +#commentsTabView .comment .action:hover, +#commentsTabView .comment .action:focus { opacity: 1; } -#commentsTabView .comment .action.delete, -#commentsTabView .comment .deleteLoading { - position: absolute; - right: 0; +#commentsTabView .newCommentRow .action-container { + margin-left: auto; } -#commentsTabView .comment.disabled { +#commentsTabView .comment.disabled .message { opacity: 0.3; } #commentsTabView .comment.disabled .action { - visibility: hidden; + display: none; } #commentsTabView .message.error { @@ -215,4 +211,4 @@ .app-files .action-comment { padding: 16px 14px; -} +} \ No newline at end of file diff --git a/apps/comments/js/commentsmodifymenu.js b/apps/comments/js/commentsmodifymenu.js new file mode 100644 index 0000000000000000000000000000000000000000..4b17cbbfbf0214f921593680532e8c574778973d Binary files /dev/null and b/apps/comments/js/commentsmodifymenu.js differ diff --git a/apps/comments/js/commentstabview.js b/apps/comments/js/commentstabview.js index 20f1f590a285d8f13a26010194e92786920541ff..9477cb0c3011ead3e2874295daac09dc4ea7fc94 100644 Binary files a/apps/comments/js/commentstabview.js and b/apps/comments/js/commentstabview.js differ diff --git a/apps/comments/js/merged.json b/apps/comments/js/merged.json index 0202c7ff55a3d571c5ee793835ce4425e066e5e7..6e77d9cf80a5ef8f45fe1681560cf035ef8cc7f2 100644 --- a/apps/comments/js/merged.json +++ b/apps/comments/js/merged.json @@ -4,6 +4,7 @@ "commentcollection.js", "commentsummarymodel.js", "commentstabview.js", + "commentsmodifymenu.js", "filesplugin.js", "activitytabviewplugin.js", "vendor/Caret.js/dist/jquery.caret.min.js", diff --git a/apps/comments/tests/js/commentstabviewSpec.js b/apps/comments/tests/js/commentstabviewSpec.js index 0131bc7bce3f47a50c72531c9d155e7218484bfb..c90ad04e4191cd4949d3716bc3f539864aa9dc27 100644 --- a/apps/comments/tests/js/commentstabviewSpec.js +++ b/apps/comments/tests/js/commentstabviewSpec.js @@ -190,7 +190,7 @@ describe('OCA.Comments.CommentsTabView tests', function() { expect(fetchStub.notCalled).toEqual(true); - view.$el.find('.showMore').click(); + view.$el.find('.showMore').trigger('click'); expect(fetchStub.calledOnce).toEqual(true); }); @@ -398,10 +398,10 @@ describe('OCA.Comments.CommentsTabView tests', function() { $message = $newCommentForm.find('.message'); $submitButton = $newCommentForm.find('.submit'); }); - afterEach(function() { - tooltipStub.restore(); + afterEach(function() { + tooltipStub.restore(); }); - + it('does not displays tooltip when limit is far away', function() { $message.val(createMessageWithLength(3)); $message.trigger('change'); @@ -490,18 +490,21 @@ describe('OCA.Comments.CommentsTabView tests', function() { it('shows edit link for owner comments', function() { var $comment = view.$el.find('.comment[data-id=1]'); expect($comment.length).toEqual(1); + $comment.find('.action.more').trigger('click'); expect($comment.find('.action.edit').length).toEqual(1); }); it('does not show edit link for other user\'s comments', function() { var $comment = view.$el.find('.comment[data-id=2]'); expect($comment.length).toEqual(1); + $comment.find('.action.more').trigger('click'); expect($comment.find('.action.edit').length).toEqual(0); }); it('shows edit form when clicking edit', function() { var $comment = view.$el.find('.comment[data-id=1]'); - $comment.find('.action.edit').click(); + $comment.find('.action.more').trigger('click'); + $comment.find('.action.edit').trigger('click'); expect($comment.hasClass('hidden')).toEqual(true); var $formRow = view.$el.find('.newCommentRow.comment[data-id=1]'); @@ -510,7 +513,8 @@ describe('OCA.Comments.CommentsTabView tests', function() { it('saves message and updates comment item when clicking save', function() { var $comment = view.$el.find('.comment[data-id=1]'); - $comment.find('.action.edit').click(); + $comment.find('.action.more').trigger('click'); + $comment.find('.action.edit').trigger('click'); var $formRow = view.$el.find('.newCommentRow.comment[data-id=1]'); expect($formRow.length).toEqual(1); @@ -544,7 +548,8 @@ describe('OCA.Comments.CommentsTabView tests', function() { it('saves message and updates comment item with mentions when clicking save', function() { var $comment = view.$el.find('.comment[data-id=3]'); - $comment.find('.action.edit').click(); + $comment.find('.action.more').trigger('click'); + $comment.find('.action.edit').trigger('click'); var $formRow = view.$el.find('.newCommentRow.comment[data-id=3]'); expect($formRow.length).toEqual(1); @@ -591,13 +596,14 @@ describe('OCA.Comments.CommentsTabView tests', function() { it('restores original comment when cancelling', function() { var $comment = view.$el.find('.comment[data-id=1]'); - $comment.find('.action.edit').click(); + $comment.find('.action.more').trigger('click'); + $comment.find('.action.edit').trigger('click'); var $formRow = view.$el.find('.newCommentRow.comment[data-id=1]'); expect($formRow.length).toEqual(1); $formRow.find('textarea').val('modified\nmessage'); - $formRow.find('.cancel').click(); + $formRow.find('.cancel').trigger('click'); expect(saveStub.notCalled).toEqual(true); @@ -614,12 +620,8 @@ describe('OCA.Comments.CommentsTabView tests', function() { it('destroys model when clicking delete', function() { var destroyStub = sinon.stub(OCA.Comments.CommentModel.prototype, 'destroy'); var $comment = view.$el.find('.comment[data-id=1]'); - $comment.find('.action.edit').click(); - - var $formRow = view.$el.find('.newCommentRow.comment[data-id=1]'); - expect($formRow.length).toEqual(1); - - $formRow.find('.delete').click(); + $comment.find('.action.more').trigger('click'); + $comment.find('.action.delete').trigger('click'); expect(destroyStub.calledOnce).toEqual(true); expect(destroyStub.thisValues[0].id).toEqual(1); @@ -630,15 +632,11 @@ describe('OCA.Comments.CommentsTabView tests', function() { $comment = view.$el.find('.comment[data-id=1]'); expect($comment.length).toEqual(0); - // form row is gone - $formRow = view.$el.find('.newCommentRow.comment[data-id=1]'); - expect($formRow.length).toEqual(0); - destroyStub.restore(); }); it('does not submit comment if the field is empty', function() { var $comment = view.$el.find('.comment[data-id=1]'); - $comment.find('.action.edit').click(); + $comment.find('.action.edit').trigger('click'); $comment.find('.message').val(' '); $comment.find('form').submit(); @@ -646,7 +644,7 @@ describe('OCA.Comments.CommentsTabView tests', function() { }); it('does not submit comment if the field length is too large', function() { var $comment = view.$el.find('.comment[data-id=1]'); - $comment.find('.action.edit').click(); + $comment.find('.action.edit').trigger('click'); $comment.find('.message').val(createMessageWithLength(view._commentMaxLength * 2)); $comment.find('form').submit(); @@ -659,7 +657,7 @@ describe('OCA.Comments.CommentsTabView tests', function() { beforeEach(function() { updateMarkerStub = sinon.stub(OCA.Comments.CommentCollection.prototype, 'updateReadMarker'); }); - afterEach(function() { + afterEach(function() { updateMarkerStub.restore(); }); diff --git a/tests/karma.config.js b/tests/karma.config.js index 0254d6a33358eff82afbad5196d6eac8d59e0e27..3758636f074c20b11321204aca263d7dbe569dc3 100644 --- a/tests/karma.config.js +++ b/tests/karma.config.js @@ -93,6 +93,7 @@ module.exports = function(config) { 'apps/comments/js/commentmodel.js', 'apps/comments/js/commentcollection.js', 'apps/comments/js/commentsummarymodel.js', + 'apps/comments/js/commentsmodifymenu.js', 'apps/comments/js/commentstabview.js', 'apps/comments/js/filesplugin.js' ], @@ -223,7 +224,7 @@ module.exports = function(config) { // serve images to avoid warnings files.push({pattern: 'core/img/**/*', watched: false, included: false, served: true}); files.push({pattern: 'core/css/images/*', watched: false, included: false, served: true}); - + // include core CSS files.push({pattern: 'core/css/*.css', watched: true, included: true, served: true}); files.push({pattern: 'tests/css/*.css', watched: true, included: true, served: true});