Merge pull request #969 from ONLYOFFICE/feature/sort-comments

Feature/sort comments
This commit is contained in:
Julia Radzhabova 2021-07-08 19:34:33 +03:00 committed by GitHub
commit bce1ec7a56
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 173 additions and 12 deletions

View file

@ -102,7 +102,8 @@ define([
// work handlers // work handlers
'comment:closeEditing': _.bind(this.closeEditing, this) 'comment:closeEditing': _.bind(this.closeEditing, this),
'comment:sort': _.bind(this.setComparator, this)
}, },
'Common.Views.ReviewPopover': { 'Common.Views.ReviewPopover': {
@ -144,10 +145,11 @@ define([
}.bind(this)); }.bind(this));
}, },
onLaunch: function () { onLaunch: function () {
var filter = Common.localStorage.getKeysFilter();
this.appPrefix = (filter && filter.length) ? filter.split(',')[0] : '';
this.collection = this.getApplication().getCollection('Common.Collections.Comments'); this.collection = this.getApplication().getCollection('Common.Collections.Comments');
if (this.collection) { this.setComparator();
this.collection.comparator = function (collection) { return -collection.get('time'); };
}
this.popoverComments = new Common.Collections.Comments(); this.popoverComments = new Common.Collections.Comments();
if (this.popoverComments) { if (this.popoverComments) {
@ -204,6 +206,33 @@ define([
}, },
// //
setComparator: function(type) {
if (this.collection) {
var sort = (type !== undefined);
if (type === undefined) {
type = Common.localStorage.getItem(this.appPrefix + "comments-sort") || 'date';
}
Common.localStorage.setItem(this.appPrefix + "comments-sort", type);
Common.Utils.InternalSettings.set(this.appPrefix + "comments-sort", type);
if (type=='position') {
} else if (type=='author') {
this.collection.comparator = function (collection) {
return collection.get('parsedName').toLowerCase();
};
} else { // date
this.collection.comparator = function (collection) {
return -collection.get('time');
};
}
sort && this.updateComments(true);
}
},
getComparator: function() {
return Common.Utils.InternalSettings.get(this.appPrefix + "comments-sort") || 'date';
},
onCreateComment: function (panel, commentVal, editMode, hidereply, documentFlag) { onCreateComment: function (panel, commentVal, editMode, hidereply, documentFlag) {
if (this.api && commentVal && commentVal.length > 0) { if (this.api && commentVal && commentVal.length > 0) {
var comment = buildCommentData(); // new asc_CCommentData(null); var comment = buildCommentData(); // new asc_CCommentData(null);
@ -776,9 +805,11 @@ define([
((data.asc_getTime() == '') ? new Date() : new Date(this.stringUtcToLocalDate(data.asc_getTime()))); ((data.asc_getTime() == '') ? new Date() : new Date(this.stringUtcToLocalDate(data.asc_getTime())));
var user = this.userCollection.findOriginalUser(data.asc_getUserId()); var user = this.userCollection.findOriginalUser(data.asc_getUserId());
var needSort = (this.getComparator() == 'author') && (data.asc_getUserName() !== comment.get('username'));
comment.set('comment', data.asc_getText()); comment.set('comment', data.asc_getText());
comment.set('userid', data.asc_getUserId()); comment.set('userid', data.asc_getUserId());
comment.set('username', data.asc_getUserName()); comment.set('username', data.asc_getUserName());
comment.set('parsedName', AscCommon.UserInfoParser.getParsedName(data.asc_getUserName()));
comment.set('usercolor', (user) ? user.get('color') : null); comment.set('usercolor', (user) ? user.get('color') : null);
comment.set('resolved', data.asc_getSolved()); comment.set('resolved', data.asc_getSolved());
comment.set('quote', data.asc_getQuoteText()); comment.set('quote', data.asc_getQuoteText());
@ -804,6 +835,7 @@ define([
id : Common.UI.getId(), id : Common.UI.getId(),
userid : data.asc_getReply(i).asc_getUserId(), userid : data.asc_getReply(i).asc_getUserId(),
username : data.asc_getReply(i).asc_getUserName(), username : data.asc_getReply(i).asc_getUserName(),
parsedName : AscCommon.UserInfoParser.getParsedName(data.asc_getReply(i).asc_getUserName()),
usercolor : (user) ? user.get('color') : null, usercolor : (user) ? user.get('color') : null,
date : t.dateToLocaleTimeString(dateReply), date : t.dateToLocaleTimeString(dateReply),
reply : data.asc_getReply(i).asc_getText(), reply : data.asc_getReply(i).asc_getText(),
@ -825,7 +857,7 @@ define([
} }
if (!silentUpdate) { if (!silentUpdate) {
this.updateComments(false, true); this.updateComments(needSort, !needSort);
// if (this.getPopover() && this.getPopover().isVisible()) { // if (this.getPopover() && this.getPopover().isVisible()) {
// this._dontScrollToComment = true; // this._dontScrollToComment = true;
@ -1089,7 +1121,7 @@ define([
var i, end = true; var i, end = true;
if (_.isUndefined(disableSort)) { if (!disableSort) {
this.collection.sort(); this.collection.sort();
} }
@ -1253,6 +1285,7 @@ define([
guid : data.asc_getGuid(), guid : data.asc_getGuid(),
userid : data.asc_getUserId(), userid : data.asc_getUserId(),
username : data.asc_getUserName(), username : data.asc_getUserName(),
parsedName : AscCommon.UserInfoParser.getParsedName(data.asc_getUserName()),
usercolor : (user) ? user.get('color') : null, usercolor : (user) ? user.get('color') : null,
date : this.dateToLocaleTimeString(date), date : this.dateToLocaleTimeString(date),
quote : data.asc_getQuoteText(), quote : data.asc_getQuoteText(),
@ -1299,6 +1332,7 @@ define([
id : Common.UI.getId(), id : Common.UI.getId(),
userid : data.asc_getReply(i).asc_getUserId(), userid : data.asc_getReply(i).asc_getUserId(),
username : data.asc_getReply(i).asc_getUserName(), username : data.asc_getReply(i).asc_getUserName(),
parsedName : AscCommon.UserInfoParser.getParsedName(data.asc_getReply(i).asc_getUserName()),
usercolor : (user) ? user.get('color') : null, usercolor : (user) ? user.get('color') : null,
date : this.dateToLocaleTimeString(date), date : this.dateToLocaleTimeString(date),
reply : data.asc_getReply(i).asc_getText(), reply : data.asc_getReply(i).asc_getText(),
@ -1340,6 +1374,7 @@ define([
date: this.dateToLocaleTimeString(date), date: this.dateToLocaleTimeString(date),
userid: this.currentUserId, userid: this.currentUserId,
username: AscCommon.UserInfoParser.getCurrentName(), username: AscCommon.UserInfoParser.getCurrentName(),
parsedName: AscCommon.UserInfoParser.getParsedName(AscCommon.UserInfoParser.getCurrentName()),
usercolor: (user) ? user.get('color') : null, usercolor: (user) ? user.get('color') : null,
editTextInPopover: true, editTextInPopover: true,
showReplyInPopover: false, showReplyInPopover: false,

View file

@ -56,6 +56,7 @@ define([
guid : '', guid : '',
userid : 0, userid : 0,
username : 'Guest', username : 'Guest',
parsedName : 'Guest',
usercolor : null, usercolor : null,
date : undefined, date : undefined,
quote : '', quote : '',
@ -88,6 +89,7 @@ define([
time : 0, // acs time : 0, // acs
userid : 0, userid : 0,
username : 'Guest', username : 'Guest',
parsedName : 'Guest',
usercolor : null, usercolor : null,
reply : '', reply : '',
date : undefined, date : undefined,

View file

@ -4,7 +4,7 @@
<!-- comment block --> <!-- comment block -->
<div class="user-name"> <div class="user-name">
<div class="color" style="display: inline-block; background-color: <% if (usercolor!==null) { %><%=usercolor%><% } else { %> #cfcfcf <% } %>; " ></div><%= scope.getUserName(username) %> <div class="color" style="display: inline-block; background-color: <% if (usercolor!==null) { %><%=usercolor%><% } else { %> #cfcfcf <% } %>; " ></div><%= scope.getEncodedName(parsedName) %>
</div> </div>
<div class="user-date"><%=date%></div> <div class="user-date"><%=date%></div>
<% if (quote!==null && quote!=='') { %> <% if (quote!==null && quote!=='') { %>
@ -31,7 +31,7 @@
<% } %> <% } %>
<div class="reply-item-ct" <% if (scope.viewmode && index==replys.length-1) { %>style="padding-bottom: 0;" <% } %>;> <div class="reply-item-ct" <% if (scope.viewmode && index==replys.length-1) { %>style="padding-bottom: 0;" <% } %>;>
<div class="user-name"> <div class="user-name">
<div class="color" style="display: inline-block; background-color: <% if (item.get("usercolor")!==null) { %><%=item.get("usercolor")%><% } else { %> #cfcfcf <% } %>; " ></div><%= scope.getUserName(item.get("username")) %> <div class="color" style="display: inline-block; background-color: <% if (item.get("usercolor")!==null) { %><%=item.get("usercolor")%><% } else { %> #cfcfcf <% } %>; " ></div><%= scope.getEncodedName(item.get("parsedName")) %>
</div> </div>
<div class="user-date"><%=item.get("date")%></div> <div class="user-date"><%=item.get("date")%></div>
<% if (!item.get("editText")) { %> <% if (!item.get("editText")) { %>

View file

@ -10,4 +10,9 @@
<button class="btn add normal dlg-btn primary"><%=textAddComment%></button> <button class="btn add normal dlg-btn primary"><%=textAddComment%></button>
<button class="btn cancel normal dlg-btn"><%=textCancel%></button> <button class="btn cancel normal dlg-btn"><%=textCancel%></button>
</div> </div>
<div id="comments-header" class="">
<label><%=textComments%></label>
<div id="comments-btn-close" style="float:right;margin-left: 4px;"></div>
<div id="comments-btn-sort" style="float:right;"></div>
</div>
</div> </div>

View file

@ -4,7 +4,7 @@
<!-- comment block --> <!-- comment block -->
<div class="user-name"> <div class="user-name">
<div class="color" style="display: inline-block; background-color: <% if (usercolor!==null) { %><%=usercolor%><% } else { %> #cfcfcf <% } %>; " ></div><%= scope.getUserName(username) %> <div class="color" style="display: inline-block; background-color: <% if (usercolor!==null) { %><%=usercolor%><% } else { %> #cfcfcf <% } %>; " ></div><%= scope.getEncodedName(parsedName) %>
</div> </div>
<div class="user-date"><%=date%></div> <div class="user-date"><%=date%></div>
<% if (!editTextInPopover || hint) { %> <% if (!editTextInPopover || hint) { %>
@ -32,7 +32,7 @@
<% } %> <% } %>
<div class="reply-item-ct"> <div class="reply-item-ct">
<div class="user-name"> <div class="user-name">
<div class="color" style="display: inline-block; background-color: <% if (item.get("usercolor")!==null) { %><%=item.get("usercolor")%><% } else { %> #cfcfcf <% } %>; " ></div><%= scope.getUserName(item.get("username")) %> <div class="color" style="display: inline-block; background-color: <% if (item.get("usercolor")!==null) { %><%=item.get("usercolor")%><% } else { %> #cfcfcf <% } %>; " ></div><%= scope.getEncodedName(item.get("parsedName")) %>
</div> </div>
<div class="user-date"><%=item.get("date")%></div> <div class="user-date"><%=item.get("date")%></div>
<% if (!item.get("editTextInPopover")) { %> <% if (!item.get("editTextInPopover")) { %>

View file

@ -293,6 +293,9 @@ define([
Common.UI.BaseView.prototype.initialize.call(this, options); Common.UI.BaseView.prototype.initialize.call(this, options);
this.store = this.options.store; this.store = this.options.store;
var filter = Common.localStorage.getKeysFilter();
this.appPrefix = (filter && filter.length) ? filter.split(',')[0] : '';
}, },
render: function () { render: function () {
@ -304,7 +307,8 @@ define([
textAddComment: me.textAddComment, textAddComment: me.textAddComment,
textCancel: me.textCancel, textCancel: me.textCancel,
textEnterCommentHint: me.textEnterCommentHint, textEnterCommentHint: me.textEnterCommentHint,
maxCommLength: Asc.c_oAscMaxCellOrCommentLength maxCommLength: Asc.c_oAscMaxCellOrCommentLength,
textComments: me.textComments
})); }));
this.buttonAddCommentToDoc = new Common.UI.Button({ this.buttonAddCommentToDoc = new Common.UI.Button({
@ -321,9 +325,52 @@ define([
enableToggle: false enableToggle: false
}); });
this.buttonSort = new Common.UI.Button({
parentEl: $('#comments-btn-sort', this.$el),
cls: 'btn-toolbar',
iconCls: 'toolbar__icon btn-sorting',
hint: this.textSort,
menu: new Common.UI.Menu({
menuAlign: 'tr-br',
style: 'min-width: auto;',
items: [
// {
// caption: this.mniPosition,
// value: 'position',
// checkable: true,
// checked: Common.localStorage.getItem(this.appPrefix + "comments-sort") === 'position',
// toggleGroup: 'sortcomments'
// },
{
caption: this.mniAuthor,
value: 'author',
checkable: true,
checked: Common.localStorage.getItem(this.appPrefix + "comments-sort") === 'author',
toggleGroup: 'sortcomments'
},
{
caption: this.mniDate,
value: 'date',
checkable: true,
checked: (Common.localStorage.getItem(this.appPrefix + "comments-sort") || 'date') === 'date',
toggleGroup: 'sortcomments'
}
]
})
});
this.buttonClose = new Common.UI.Button({
parentEl: $('#comments-btn-close', this.$el),
cls: 'btn-toolbar',
iconCls: 'toolbar__icon btn-close',
hint: this.textClosePanel
});
this.buttonAddCommentToDoc.on('click', _.bind(this.onClickShowBoxDocumentComment, this)); this.buttonAddCommentToDoc.on('click', _.bind(this.onClickShowBoxDocumentComment, this));
this.buttonAdd.on('click', _.bind(this.onClickAddDocumentComment, this)); this.buttonAdd.on('click', _.bind(this.onClickAddDocumentComment, this));
this.buttonCancel.on('click', _.bind(this.onClickCancelDocumentComment, this)); this.buttonCancel.on('click', _.bind(this.onClickCancelDocumentComment, this));
this.buttonClose.on('click', _.bind(this.onClickClosePanel, this));
this.buttonSort.menu.on('item:toggle', _.bind(this.onSortClick, this));
this.txtComment = $('#comment-msg-new', this.el); this.txtComment = $('#comment-msg-new', this.el);
this.txtComment.keydown(function (event) { this.txtComment.keydown(function (event) {
@ -658,6 +705,9 @@ define([
getUserName: function (username) { getUserName: function (username) {
return Common.Utils.String.htmlEncode(AscCommon.UserInfoParser.getParsedName(username)); return Common.Utils.String.htmlEncode(AscCommon.UserInfoParser.getParsedName(username));
}, },
getEncodedName: function (username) {
return Common.Utils.String.htmlEncode(username);
},
pickLink: function (message) { pickLink: function (message) {
var arr = [], offset, len; var arr = [], offset, len;
@ -730,6 +780,14 @@ define([
}); });
}, },
onSortClick: function(menu, item, state) {
state && this.fireEvent('comment:sort', [item.value]);
},
onClickClosePanel: function() {
Common.NotificationCenter.trigger('leftmenu:change', 'hide');
},
textComments : 'Comments', textComments : 'Comments',
textAnonym : 'Guest', textAnonym : 'Guest',
textAddCommentToDoc : 'Add Comment to Document', textAddCommentToDoc : 'Add Comment to Document',
@ -744,6 +802,11 @@ define([
textEdit : 'Edit', textEdit : 'Edit',
textAdd : "Add", textAdd : "Add",
textOpenAgain : "Open Again", textOpenAgain : "Open Again",
textHintAddComment : 'Add Comment' textHintAddComment : 'Add Comment',
textSort: 'Sort comments',
mniPosition: 'Sort by Position',
mniAuthor: 'Sort by Authors',
mniDate: 'Sort by Date',
textClosePanel: 'Close comments'
}, Common.Views.Comments || {})) }, Common.Views.Comments || {}))
}); });

Binary file not shown.

Before

Width:  |  Height:  |  Size: 284 B

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 291 B

After

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 B

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 B

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 193 B

View file

@ -7,6 +7,33 @@
display: table-row; display: table-row;
} }
#comments-header {
position: absolute;
height: 45px;
left: 0;
top: 0;
right: 0;
padding: 12px;
overflow: hidden;
border-bottom: @scaled-one-px-value-ie solid @border-toolbar-ie;
border-bottom: @scaled-one-px-value solid @border-toolbar;
label {
font-size: 12px;
font-weight: bold;
margin-top: 2px;
}
#comments-btn-sort {
.btn-toolbar {
min-width: 20px;
}
.inner-box-caret {
display: none;
}
}
}
.messages-ct { .messages-ct {
position: absolute; position: absolute;
overflow: hidden; overflow: hidden;
@ -14,6 +41,7 @@
right: 0; right: 0;
bottom: 45px; bottom: 45px;
height: 300px; height: 300px;
padding-top: 45px;
border-bottom: @scaled-one-px-value-ie solid @border-toolbar-ie; border-bottom: @scaled-one-px-value-ie solid @border-toolbar-ie;
border-bottom: @scaled-one-px-value solid @border-toolbar; border-bottom: @scaled-one-px-value solid @border-toolbar;

View file

@ -246,6 +246,11 @@
"Common.Views.Comments.textReply": "Reply", "Common.Views.Comments.textReply": "Reply",
"Common.Views.Comments.textResolve": "Resolve", "Common.Views.Comments.textResolve": "Resolve",
"Common.Views.Comments.textResolved": "Resolved", "Common.Views.Comments.textResolved": "Resolved",
"Common.Views.Comments.textSort": "Sort comments",
"Common.Views.Comments.mniPosition": "Sort by Position",
"Common.Views.Comments.mniAuthor": "Sort by Authors",
"Common.Views.Comments.mniDate": "Sort by Date",
"Common.Views.Comments.textClosePanel": "Close comments",
"Common.Views.CopyWarningDialog.textDontShow": "Don't show this message again", "Common.Views.CopyWarningDialog.textDontShow": "Don't show this message again",
"Common.Views.CopyWarningDialog.textMsg": "Copy, cut and paste actions using the editor toolbar buttons and context menu actions will be performed within this editor tab only.<br><br>To copy or paste to or from applications outside the editor tab use the following keyboard combinations:", "Common.Views.CopyWarningDialog.textMsg": "Copy, cut and paste actions using the editor toolbar buttons and context menu actions will be performed within this editor tab only.<br><br>To copy or paste to or from applications outside the editor tab use the following keyboard combinations:",
"Common.Views.CopyWarningDialog.textTitle": "Copy, Cut and Paste Actions", "Common.Views.CopyWarningDialog.textTitle": "Copy, Cut and Paste Actions",

View file

@ -139,6 +139,11 @@
"Common.Views.Comments.textReply": "Reply", "Common.Views.Comments.textReply": "Reply",
"Common.Views.Comments.textResolve": "Resolve", "Common.Views.Comments.textResolve": "Resolve",
"Common.Views.Comments.textResolved": "Resolved", "Common.Views.Comments.textResolved": "Resolved",
"Common.Views.Comments.textSort": "Sort comments",
"Common.Views.Comments.mniPosition": "Sort by Position",
"Common.Views.Comments.mniAuthor": "Sort by Authors",
"Common.Views.Comments.mniDate": "Sort by Date",
"Common.Views.Comments.textClosePanel": "Close comments",
"Common.Views.CopyWarningDialog.textDontShow": "Don't show this message again", "Common.Views.CopyWarningDialog.textDontShow": "Don't show this message again",
"Common.Views.CopyWarningDialog.textMsg": "Copy, cut and paste actions using the editor toolbar buttons and context menu actions will be performed within this editor tab only.<br><br>To copy or paste to or from applications outside the editor tab use the following keyboard combinations:", "Common.Views.CopyWarningDialog.textMsg": "Copy, cut and paste actions using the editor toolbar buttons and context menu actions will be performed within this editor tab only.<br><br>To copy or paste to or from applications outside the editor tab use the following keyboard combinations:",
"Common.Views.CopyWarningDialog.textTitle": "Copy, Cut and Paste Actions", "Common.Views.CopyWarningDialog.textTitle": "Copy, Cut and Paste Actions",

View file

@ -98,6 +98,7 @@ define([
} }
}); });
Common.NotificationCenter.on('app:comment:add', _.bind(this.onAppAddComment, this)); Common.NotificationCenter.on('app:comment:add', _.bind(this.onAppAddComment, this));
Common.NotificationCenter.on('leftmenu:change', _.bind(this.onMenuChange, this));
}, },
onLaunch: function() { onLaunch: function() {
@ -961,6 +962,18 @@ define([
} }
}, },
onMenuChange: function (value) {
if ('hide' === value) {
if (this.leftMenu.btnComments.isActive() && this.api) {
this.leftMenu.btnComments.toggle(false);
this.leftMenu.onBtnMenuClick(this.leftMenu.btnComments);
// focus to sdk
this.api.asc_enableKeyEvents(true);
}
}
},
textNoTextFound : 'Text not found', textNoTextFound : 'Text not found',
newDocumentTitle : 'Unnamed document', newDocumentTitle : 'Unnamed document',
textItemEntireCell : 'Entire cell contents', textItemEntireCell : 'Entire cell contents',

View file

@ -187,6 +187,11 @@
"Common.Views.Comments.textReply": "Reply", "Common.Views.Comments.textReply": "Reply",
"Common.Views.Comments.textResolve": "Resolve", "Common.Views.Comments.textResolve": "Resolve",
"Common.Views.Comments.textResolved": "Resolved", "Common.Views.Comments.textResolved": "Resolved",
"Common.Views.Comments.textSort": "Sort comments",
"Common.Views.Comments.mniPosition": "Sort by Position",
"Common.Views.Comments.mniAuthor": "Sort by Authors",
"Common.Views.Comments.mniDate": "Sort by Date",
"Common.Views.Comments.textClosePanel": "Close comments",
"Common.Views.CopyWarningDialog.textDontShow": "Don't show this message again", "Common.Views.CopyWarningDialog.textDontShow": "Don't show this message again",
"Common.Views.CopyWarningDialog.textMsg": "Copy, cut and paste actions using the editor toolbar buttons and context menu actions will be performed within this editor tab only.<br><br>To copy or paste to or from applications outside the editor tab use the following keyboard combinations:", "Common.Views.CopyWarningDialog.textMsg": "Copy, cut and paste actions using the editor toolbar buttons and context menu actions will be performed within this editor tab only.<br><br>To copy or paste to or from applications outside the editor tab use the following keyboard combinations:",
"Common.Views.CopyWarningDialog.textTitle": "Copy, Cut and Paste Actions", "Common.Views.CopyWarningDialog.textTitle": "Copy, Cut and Paste Actions",