Merge pull request #1075 from ONLYOFFICE/feature/de-review

Feature/de review
This commit is contained in:
Julia Radzhabova 2021-08-13 20:28:10 +03:00 committed by GitHub
commit 43491e0115
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 166 additions and 59 deletions

View file

@ -136,7 +136,8 @@
label: string (default: "Guest") // postfix for user name
},
review: {
hideReviewDisplay: false // hide button Review mode
hideReviewDisplay: false, // hide button Review mode
hoverMode: false // true - show review balloons on mouse move, not on click on text
},
chat: true,
comments: true,
@ -155,7 +156,7 @@
compactHeader: false,
toolbarNoTabs: false,
toolbarHideFileName: false,
reviewDisplay: 'original',
reviewDisplay: 'original', // original for viewer, markup for editor
spellcheck: true,
compatibleFeatures: false,
unit: 'cm' // cm, pt, inch,

View file

@ -1185,7 +1185,8 @@ define([
renderTo : this.sdkViewName,
canRequestUsers: (this.mode) ? this.mode.canRequestUsers : undefined,
canRequestSendNotify: (this.mode) ? this.mode.canRequestSendNotify : undefined,
mentionShare: (this.mode) ? this.mode.mentionShare : true
mentionShare: (this.mode) ? this.mode.mentionShare : true,
api: this.api
});
this.popover.setCommentsStore(this.popoverComments);
}

View file

@ -131,8 +131,7 @@ define([
this.api.asc_registerCallback('asc_onUpdateRevisionsChangesPosition', _.bind(this.onApiUpdateChangePosition, this));
this.api.asc_registerCallback('asc_onAuthParticipantsChanged', _.bind(this.onAuthParticipantsChanged, this));
this.api.asc_registerCallback('asc_onParticipantsChanged', _.bind(this.onAuthParticipantsChanged, this));
this.api.asc_registerCallback('asc_onBeginViewModeInReview', _.bind(this.onBeginViewModeInReview, this));
this.api.asc_registerCallback('asc_onEndViewModeInReview', _.bind(this.onEndViewModeInReview, this));
this.api.asc_registerCallback('asc_onChangeDisplayModeInReview', _.bind(this.onChangeDisplayModeInReview, this));
}
if (this.appConfig.canReview)
this.api.asc_registerCallback('asc_onOnTrackRevisionsChange', _.bind(this.onApiTrackRevisionsChange, this));
@ -181,7 +180,7 @@ define([
onApiShowChange: function (sdkchange) {
if (this.getPopover()) {
if (sdkchange && sdkchange.length>0) {
if (!this.appConfig.reviewHoverMode && sdkchange && sdkchange.length>0) {
var i = 0,
changes = this.readSDKChange(sdkchange),
posX = sdkchange[0].get_X(),
@ -256,7 +255,8 @@ define([
if ((this.appConfig.canReview || this.appConfig.canViewReview) && _.isUndefined(this.popover)) {
this.popover = Common.Views.ReviewPopover.prototype.getPopover({
reviewStore : this.popoverChanges,
renderTo : this.sdkViewName
renderTo : this.sdkViewName,
api: this.api
});
this.popover.setReviewStore(this.popoverChanges);
}
@ -595,7 +595,10 @@ define([
onReviewViewClick: function(menu, item, e) {
this.turnDisplayMode(item.value);
!this.appConfig.canReview && Common.localStorage.setItem(this.view.appPrefix + "review-mode", item.value);
if (!this.appConfig.isEdit && !this.appConfig.isRestrictedEdit)
Common.localStorage.setItem(this.view.appPrefix + "review-mode", item.value); // for viewer
else if (item.value=='markup' || item.value=='simple')
Common.localStorage.setItem(this.view.appPrefix + "review-mode-editor", item.value); // for editor save only markup modes
Common.NotificationCenter.trigger('edit:complete', this.view);
},
@ -685,27 +688,40 @@ define([
turnDisplayMode: function(mode) {
if (this.api) {
if (mode === 'final')
this.api.asc_BeginViewModeInReview(true);
else if (mode === 'original')
this.api.asc_BeginViewModeInReview(false);
else
this.api.asc_EndViewModeInReview();
var type = Asc.c_oAscDisplayModeInReview.Edit;
switch (mode) {
case 'final':
type = Asc.c_oAscDisplayModeInReview.Final;
break;
case 'original':
type = Asc.c_oAscDisplayModeInReview.Original;
break;
case 'simple':
type = Asc.c_oAscDisplayModeInReview.Simple;
break;
}
this.api.asc_SetDisplayModeInReview(type);
}
this.disableEditing(mode == 'final' || mode == 'original');
this._state.previewMode = (mode == 'final' || mode == 'original');
},
onBeginViewModeInReview: function(mode) {
this.disableEditing(true);
this.view && this.view.turnDisplayMode(mode ? 'final' : 'original');
this._state.previewMode = true;
},
onEndViewModeInReview: function() {
this.disableEditing(false);
this.view && this.view.turnDisplayMode('markup');
this._state.previewMode = false;
onChangeDisplayModeInReview: function(type) {
this.disableEditing(type===Asc.c_oAscDisplayModeInReview.Final || type===Asc.c_oAscDisplayModeInReview.Original);
var mode = 'markup';
switch (type) {
case Asc.c_oAscDisplayModeInReview.Final:
mode = 'final';
break;
case Asc.c_oAscDisplayModeInReview.Original:
mode = 'original';
break;
case Asc.c_oAscDisplayModeInReview.Simple:
mode = 'simple';
break;
}
this.view && this.view.turnDisplayMode(mode);
this._state.previewMode = (type===Asc.c_oAscDisplayModeInReview.Final || type===Asc.c_oAscDisplayModeInReview.Original);
},
isPreviewChangesMode: function() {
@ -804,7 +820,11 @@ define([
me.onApiTrackRevisionsChange(me.api.asc_GetLocalTrackRevisions(), me.api.asc_GetGlobalTrackRevisions());
me.api.asc_HaveRevisionsChanges() && me.view.markChanges(true);
// _setReviewStatus(state, global);
var val = Common.localStorage.getItem(me.view.appPrefix + "review-mode-editor");
if (val===null)
val = me.appConfig.customization && /^(original|final|markup|simple)$/i.test(me.appConfig.customization.reviewDisplay) ? me.appConfig.customization.reviewDisplay.toLocaleLowerCase() : 'markup';
me.turnDisplayMode(val); // load display mode for all modes (viewer or editor)
me.view.turnDisplayMode(val);
if ( typeof (me.appConfig.customization) == 'object' && (me.appConfig.customization.showReviewChanges==true) ) {
me.dlgChanges = (new Common.Views.ReviewChangesDialog({
@ -819,11 +839,11 @@ define([
} else if (config.canViewReview) {
config.canViewReview = (config.isEdit || me.api.asc_HaveRevisionsChanges(true)); // check revisions from all users
if (config.canViewReview) {
var val = Common.localStorage.getItem(me.view.appPrefix + "review-mode");
var val = Common.localStorage.getItem(me.view.appPrefix + (config.isEdit || config.isRestrictedEdit ? "review-mode-editor" : "review-mode"));
if (val===null)
val = me.appConfig.customization && /^(original|final|markup)$/i.test(me.appConfig.customization.reviewDisplay) ? me.appConfig.customization.reviewDisplay.toLocaleLowerCase() : 'original';
me.turnDisplayMode((config.isEdit || config.isRestrictedEdit) ? 'markup' : val); // load display mode only in viewer
me.view.turnDisplayMode((config.isEdit || config.isRestrictedEdit) ? 'markup' : val);
val = me.appConfig.customization && /^(original|final|markup|simple)$/i.test(me.appConfig.customization.reviewDisplay) ? me.appConfig.customization.reviewDisplay.toLocaleLowerCase() : (config.isEdit || config.isRestrictedEdit ? 'markup' : 'original');
me.turnDisplayMode(val);
me.view.turnDisplayMode(val);
}
}
@ -837,6 +857,14 @@ define([
me.view.btnCommentRemove && me.view.btnCommentRemove.setDisabled(!Common.localStorage.getBool(me.view.appPrefix + "settings-livecomment", true));
me.view.btnCommentResolve && me.view.btnCommentResolve.setDisabled(!Common.localStorage.getBool(me.view.appPrefix + "settings-livecomment", true));
}
var val = Common.localStorage.getItem(me.view.appPrefix + "settings-review-hover-mode");
if (val === null) {
val = me.appConfig.customization && me.appConfig.customization.review ? !!me.appConfig.customization.review.hoverMode : false;
} else
val = !!parseInt(val);
Common.Utils.InternalSettings.set(me.view.appPrefix + "settings-review-hover-mode", val);
me.appConfig.reviewHoverMode = val;
},
showTips: function(strings) {

View file

@ -298,6 +298,15 @@ define([
template: menuTemplate,
description: this.txtMarkup
},
{
caption: this.txtMarkupSimpleCap,
checkable: true,
toggleGroup: 'menuReviewView',
checked: false,
value: 'simple',
template: menuTemplate,
description: this.txtMarkupSimple
},
{
caption: this.txtFinalCap,
checkable: true,
@ -750,8 +759,9 @@ define([
turnDisplayMode: function(mode) {
if (this.btnReviewView) {
this.btnReviewView.menu.items[0].setChecked(mode=='markup', true);
this.btnReviewView.menu.items[1].setChecked(mode=='final', true);
this.btnReviewView.menu.items[2].setChecked(mode=='original', true);
this.btnReviewView.menu.items[1].setChecked(mode=='simple', true);
this.btnReviewView.menu.items[2].setChecked(mode=='final', true);
this.btnReviewView.menu.items[3].setChecked(mode=='original', true);
}
},
@ -850,7 +860,9 @@ define([
txtOff: 'OFF for me',
textWarnTrackChangesTitle: 'Enable Track Changes for everyone?',
textWarnTrackChanges: 'Track Changes will be switched ON for all users with full access. The next time anyone opens the doc, Track Changes will remain enabled.',
textEnable: 'Enable'
textEnable: 'Enable',
txtMarkupSimpleCap: 'Simple Markup',
txtMarkupSimple: 'All changes (Editing)<br>Turn off balloons'
}
}()), Common.Views.ReviewChanges || {}));

View file

@ -103,6 +103,7 @@ define([
this.canRequestUsers = options.canRequestUsers;
this.canRequestSendNotify = options.canRequestSendNotify;
this.mentionShare = options.mentionShare;
this.api = options.api;
this.externalUsers = [];
this._state = {commentsVisible: false, reviewVisible: false};
@ -784,7 +785,7 @@ define([
}
}
}
if (!retainContent)
if (!retainContent || this.isOverCursor())
this.calculateSizeOfContent();
},
calculateSizeOfContent: function (testVisible) {
@ -839,7 +840,34 @@ define([
outerHeight = Math.max(commentsView.outerHeight(), this.$window.outerHeight());
if (sdkBoundsHeight <= outerHeight) {
var movePos = this.isOverCursor();
if (movePos) {
var newTopDown = movePos[1] + sdkPanelHeight,// try move down
newTopUp = movePos[0] + sdkPanelHeight; // try move up
if (newTopDown + outerHeight>sdkBoundsTop + sdkBoundsHeight) {
var diffDown = sdkBoundsTop + sdkBoundsHeight - newTopDown;
if (newTopUp - outerHeight<sdkBoundsTop) {
var diffUp = newTopUp - sdkBoundsTop;
if (diffDown < diffUp * 0.9) {// magic)
this.$window.css({
maxHeight: diffUp + 'px',
top: sdkBoundsTop + 'px'
});
commentsView.css({height: diffUp - 3 + 'px'});
} else {
this.$window.css({
maxHeight: diffDown + 'px',
top: newTopDown + 'px'
});
commentsView.css({height: diffDown - 3 + 'px'});
}
} else
this.$window.css('top', newTopUp - outerHeight + 'px'); // move up
} else
this.$window.css('top', newTopDown + 'px'); // move down
arrowView.addClass('hidden');
} else if (sdkBoundsHeight <= outerHeight) {
this.$window.css({
maxHeight: sdkBoundsHeight - sdkPanelHeight + 'px',
top: sdkBoundsTop + sdkPanelHeight + 'px'
@ -851,6 +879,7 @@ define([
arrowPosY = Math.min(arrowPosY, sdkBoundsHeight - (sdkPanelHeight + this.arrow.margin + this.arrow.height));
arrowView.css({top: arrowPosY + 'px'});
arrowView.removeClass('hidden');
this.scroller.scrollTop(scrollPos);
} else {
@ -869,6 +898,7 @@ define([
arrowPosY = Math.min(arrowPosY, outerHeight - this.arrow.margin - this.arrow.height);
arrowView.css({top: arrowPosY + 'px'});
arrowView.removeClass('hidden');
}
}
}
@ -880,6 +910,23 @@ define([
this.scroller.update({minScrollbarLength: 40, alwaysVisibleY: true});
}
},
isOverCursor: function() {
if (!this.api.asc_GetSelectionBounds) return;
var p = this.api.asc_GetSelectionBounds(),
isCursor = Math.abs(p[0][0] - p[1][0])<0.1 && Math.abs(p[0][1] - p[1][1])<0.1 && Math.abs(p[2][0] - p[3][0])<0.1 && Math.abs(p[2][1] - p[3][1])<0.1;
var x0 = p[0][0], y0 = p[0][1],
x1 = p[isCursor ? 2 : 1][0], y1 = p[isCursor ? 2 : 1][1];
var leftPos = parseInt(this.$window.css('left'))-25,
windowWidth = this.$window.outerWidth();
if (x0>leftPos && x0<leftPos+windowWidth || x1>leftPos && x1<leftPos+windowWidth) {
var newTopDown = Math.max(y0, y1),// try move down
newTopUp = Math.min(y0, y1); // try move up
return [newTopUp, newTopDown];
}
},
saveText: function (clear) {
if (this.commentsView && this.commentsView.cmpEl.find('.lock-area').length < 1) {
this.textVal = undefined;

View file

@ -22,24 +22,26 @@ class InitReview extends Component {
api.asc_SetTrackRevisions(appOptions.isReviewOnly || trackChanges===true || (trackChanges!==false) && LocalStorage.getBool("de-mobile-track-changes-" + (appOptions.fileKey || '')));
// Init display mode
if (!appOptions.canReview) {
const canViewReview = appOptions.isEdit || api.asc_HaveRevisionsChanges(true);
const canViewReview = appOptions.canReview || appOptions.isEdit || api.asc_HaveRevisionsChanges(true);
if (!appOptions.canReview)
appOptions.setCanViewReview(canViewReview);
if (canViewReview) {
let viewReviewMode = LocalStorage.getItem("de-view-review-mode");
if (viewReviewMode === null)
viewReviewMode = appOptions.customization && /^(original|final|markup)$/i.test(appOptions.customization.reviewDisplay) ? appOptions.customization.reviewDisplay.toLocaleLowerCase() : 'original';
viewReviewMode = (appOptions.isEdit || appOptions.isRestrictedEdit) ? 'markup' : viewReviewMode;
const displayMode = viewReviewMode.toLocaleLowerCase();
if (displayMode === 'final') {
api.asc_BeginViewModeInReview(true);
} else if (displayMode === 'original') {
api.asc_BeginViewModeInReview(false);
} else {
api.asc_EndViewModeInReview();
}
props.storeReview.changeDisplayMode(displayMode);
if (canViewReview) {
let viewReviewMode = (appOptions.isEdit || appOptions.isRestrictedEdit) ? null : LocalStorage.getItem("de-view-review-mode");
if (viewReviewMode === null)
viewReviewMode = appOptions.customization && /^(original|final|markup|simple)$/i.test(appOptions.customization.reviewDisplay) ? appOptions.customization.reviewDisplay.toLocaleLowerCase() : ( appOptions.isEdit || appOptions.isRestrictedEdit ? 'markup' : 'original');
let displayMode = viewReviewMode.toLocaleLowerCase();
let type = Asc.c_oAscDisplayModeInReview.Edit;
switch (displayMode) {
case 'final':
type = Asc.c_oAscDisplayModeInReview.Final;
break;
case 'original':
type = Asc.c_oAscDisplayModeInReview.Original;
break;
}
api.asc_SetDisplayModeInReview(type);
props.storeReview.changeDisplayMode(displayMode);
}
});
}
@ -95,14 +97,17 @@ class Review extends Component {
onDisplayMode (mode) {
const api = Common.EditorApi.get();
if (mode === 'final') {
api.asc_BeginViewModeInReview(true);
} else if (mode === 'original') {
api.asc_BeginViewModeInReview(false);
} else {
api.asc_EndViewModeInReview();
let type = Asc.c_oAscDisplayModeInReview.Edit;
switch (mode) {
case 'final':
type = Asc.c_oAscDisplayModeInReview.Final;
break;
case 'original':
type = Asc.c_oAscDisplayModeInReview.Original;
break;
}
!this.appConfig.canReview && LocalStorage.setItem("de-view-review-mode", mode);
api.asc_SetDisplayModeInReview(type);
!this.appConfig.isEdit && !this.appConfig.isRestrictedEdit && LocalStorage.setItem("de-view-review-mode", mode);
this.props.storeReview.changeDisplayMode(mode);
}

View file

@ -491,7 +491,8 @@ define([
var showPoint, ToolTip,
type = moveData.get_Type();
if (type==Asc.c_oAscMouseMoveDataTypes.Hyperlink || type==Asc.c_oAscMouseMoveDataTypes.Footnote || type==Asc.c_oAscMouseMoveDataTypes.Form) { // 1 - hyperlink, 3 - footnote
if (type==Asc.c_oAscMouseMoveDataTypes.Hyperlink || type==Asc.c_oAscMouseMoveDataTypes.Footnote || type==Asc.c_oAscMouseMoveDataTypes.Form ||
type==Asc.c_oAscMouseMoveDataTypes.Review && me.mode.reviewHoverMode) {
if (isTooltipHiding) {
mouseMoveData = moveData;
return;
@ -511,12 +512,22 @@ define([
ToolTip = moveData.get_FormHelpText();
if (ToolTip.length>1000)
ToolTip = ToolTip.substr(0, 1000) + '...';
} else if (type==Asc.c_oAscMouseMoveDataTypes.Review && moveData.get_ReviewChange()) {
var changes = DE.getController("Common.Controllers.ReviewChanges").readSDKChange([moveData.get_ReviewChange()]);
if (changes && changes.length>0)
changes = changes[0];
if (changes) {
ToolTip = '<b>'+ Common.Utils.String.htmlEncode(AscCommon.UserInfoParser.getParsedName(changes.get('username'))) +' </b>';
ToolTip += '<span style="font-size:10px; opacity: 0.7;">'+ changes.get('date') +'</span><br>';
ToolTip += changes.get('changetext');
}
}
var recalc = false;
screenTip.isHidden = false;
ToolTip = Common.Utils.String.htmlEncode(ToolTip);
if (type!==Asc.c_oAscMouseMoveDataTypes.Review)
ToolTip = Common.Utils.String.htmlEncode(ToolTip);
if (screenTip.tipType !== type || screenTip.tipLength !== ToolTip.length || screenTip.strTip.indexOf(ToolTip)<0 ) {
screenTip.toolTip.setTitle((type==Asc.c_oAscMouseMoveDataTypes.Hyperlink) ? (ToolTip + '<br><b>' + me.txtPressLink + '</b>') : ToolTip);

View file

@ -398,6 +398,8 @@
"Common.Views.ReviewChanges.txtSpelling": "Spell Checking",
"Common.Views.ReviewChanges.txtTurnon": "Track Changes",
"Common.Views.ReviewChanges.txtView": "Display Mode",
"Common.Views.ReviewChanges.txtMarkupSimpleCap": "Simple Markup",
"Common.Views.ReviewChanges.txtMarkupSimple": "All changes (Editing)<br>Turn off balloons",
"Common.Views.ReviewChangesDialog.textTitle": "Review Changes",
"Common.Views.ReviewChangesDialog.txtAccept": "Accept",
"Common.Views.ReviewChangesDialog.txtAcceptAll": "Accept All Changes",