Convert files to typescript
The change converts the following files to typescript: * elements/diff/gr-apply-fix-dialog/gr-apply-fix-dialog.ts Change-Id: I274ba656285897c89c42f299724e402758b8cfe3
This commit is contained in:
@@ -38,6 +38,7 @@ import {
|
||||
RepoName,
|
||||
ReviewInputTag,
|
||||
VotingRangeInfo,
|
||||
ChangeNum,
|
||||
} from '../../../types/common';
|
||||
import {RestApiService} from '../../../services/services/gr-rest-api/gr-rest-api';
|
||||
import {CommentThread} from '../../diff/gr-comment-api/gr-comment-api';
|
||||
@@ -102,7 +103,7 @@ export class GrMessage extends GestureEventListeners(
|
||||
change?: ChangeInfo;
|
||||
|
||||
@property({type: Number})
|
||||
changeNum?: number;
|
||||
changeNum?: ChangeNum;
|
||||
|
||||
@property({type: Object})
|
||||
message: ChangeMessage | undefined;
|
||||
|
||||
@@ -596,7 +596,7 @@ export const GerritNav = {
|
||||
* @param basePatchNum The string 'PARENT' can be used for none.
|
||||
*/
|
||||
getUrlForChange(
|
||||
change: ChangeInfo,
|
||||
change: Pick<ChangeInfo, '_number' | 'project' | 'internalHost'>,
|
||||
patchNum?: PatchSetNum,
|
||||
basePatchNum?: PatchSetNum,
|
||||
isEdit?: boolean,
|
||||
@@ -640,7 +640,7 @@ export const GerritNav = {
|
||||
*
|
||||
*/
|
||||
navigateToChange(
|
||||
change: ChangeInfo,
|
||||
change: Pick<ChangeInfo, '_number' | 'project' | 'internalHost'>,
|
||||
patchNum?: PatchSetNum,
|
||||
basePatchNum?: PatchSetNum,
|
||||
isEdit?: boolean,
|
||||
|
||||
@@ -14,87 +14,131 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import '@polymer/iron-icon/iron-icon.js';
|
||||
import '../../../styles/shared-styles.js';
|
||||
import '../../shared/gr-dialog/gr-dialog.js';
|
||||
import '../../shared/gr-overlay/gr-overlay.js';
|
||||
import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
|
||||
import '../gr-diff/gr-diff.js';
|
||||
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
|
||||
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
|
||||
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
|
||||
import {htmlTemplate} from './gr-apply-fix-dialog_html.js';
|
||||
import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
|
||||
import '@polymer/iron-icon/iron-icon';
|
||||
import '../../../styles/shared-styles';
|
||||
import '../../shared/gr-dialog/gr-dialog';
|
||||
import '../../shared/gr-overlay/gr-overlay';
|
||||
import '../../shared/gr-rest-api-interface/gr-rest-api-interface';
|
||||
import '../gr-diff/gr-diff';
|
||||
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners';
|
||||
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin';
|
||||
import {PolymerElement} from '@polymer/polymer/polymer-element';
|
||||
import {htmlTemplate} from './gr-apply-fix-dialog_html';
|
||||
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
|
||||
import {customElement, property} from '@polymer/decorators';
|
||||
import {ParsedChangeInfo} from '../../shared/gr-rest-api-interface/gr-reviewer-updates-parser';
|
||||
import {
|
||||
ChangeNum,
|
||||
DiffInfo,
|
||||
DiffPreferencesInfo,
|
||||
EditPatchSetNum,
|
||||
FixId,
|
||||
FixSuggestionInfo,
|
||||
PatchSetNum,
|
||||
RobotId,
|
||||
} from '../../../types/common';
|
||||
import {GrOverlay} from '../../shared/gr-overlay/gr-overlay';
|
||||
import {
|
||||
CommentEventDetail,
|
||||
isRobotComment,
|
||||
} from '../../shared/gr-comment/gr-comment';
|
||||
import {RestApiService} from '../../../services/services/gr-rest-api/gr-rest-api';
|
||||
|
||||
/**
|
||||
* @extends PolymerElement
|
||||
*/
|
||||
class GrApplyFixDialog extends GestureEventListeners(
|
||||
LegacyElementMixin(PolymerElement)) {
|
||||
static get template() { return htmlTemplate; }
|
||||
export interface GrApplyFixDialog {
|
||||
$: {
|
||||
restAPI: RestApiService & Element;
|
||||
applyFixOverlay: GrOverlay;
|
||||
};
|
||||
}
|
||||
|
||||
static get is() { return 'gr-apply-fix-dialog'; }
|
||||
interface FilePreview {
|
||||
filepath: string;
|
||||
preview: DiffInfo;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
// Diff rendering preference API response.
|
||||
prefs: Array,
|
||||
// ChangeInfo API response object.
|
||||
change: Object,
|
||||
changeNum: String,
|
||||
_patchNum: Number,
|
||||
// robot ID associated with a robot comment.
|
||||
_robotId: String,
|
||||
// Selected FixSuggestionInfo entity from robot comment API response.
|
||||
_currentFix: Object,
|
||||
// Flattened /preview API response DiffInfo map object.
|
||||
_currentPreviews: {type: Array, value: () => []},
|
||||
// FixSuggestionInfo entities from robot comment API response.
|
||||
_fixSuggestions: Array,
|
||||
_isApplyFixLoading: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
// Index of currently showing suggested fix.
|
||||
_selectedFixIdx: Number,
|
||||
_disableApplyFixButton: {
|
||||
type: Boolean,
|
||||
computed: '_computeDisableApplyFixButton(_isApplyFixLoading, change, '
|
||||
+ '_patchNum)',
|
||||
},
|
||||
};
|
||||
@customElement('gr-apply-fix-dialog')
|
||||
export class GrApplyFixDialog extends GestureEventListeners(
|
||||
LegacyElementMixin(PolymerElement)
|
||||
) {
|
||||
static get template() {
|
||||
return htmlTemplate;
|
||||
}
|
||||
|
||||
@property({type: Object})
|
||||
prefs?: DiffPreferencesInfo;
|
||||
|
||||
@property({type: Object})
|
||||
change?: ParsedChangeInfo;
|
||||
|
||||
@property({type: String})
|
||||
changeNum?: ChangeNum;
|
||||
|
||||
@property({type: Number})
|
||||
_patchNum?: PatchSetNum;
|
||||
|
||||
@property({type: String})
|
||||
_robotId?: RobotId;
|
||||
|
||||
@property({type: Object})
|
||||
_currentFix?: FixSuggestionInfo;
|
||||
|
||||
@property({type: Array})
|
||||
_currentPreviews: FilePreview[] = [];
|
||||
|
||||
@property({type: Array})
|
||||
_fixSuggestions?: FixSuggestionInfo[];
|
||||
|
||||
@property({type: Boolean})
|
||||
_isApplyFixLoading = false;
|
||||
|
||||
@property({type: Number})
|
||||
_selectedFixIdx = 0;
|
||||
|
||||
@property({
|
||||
type: Boolean,
|
||||
computed:
|
||||
'_computeDisableApplyFixButton(_isApplyFixLoading, change, ' +
|
||||
'_patchNum)',
|
||||
})
|
||||
_disableApplyFixButton?: boolean;
|
||||
|
||||
private refitOverlay?: () => void;
|
||||
|
||||
/**
|
||||
* Given robot comment CustomEvent objevt, fetch diffs associated
|
||||
* Given robot comment CustomEvent object, fetch diffs associated
|
||||
* with first robot comment suggested fix and open dialog.
|
||||
*
|
||||
* @param {*} e CustomEvent to be passed from gr-comment with
|
||||
* robot comment detail.
|
||||
* @return {Promise<undefined>} Promise that resolves either when all
|
||||
* @param e to be passed from gr-comment with robot comment detail.
|
||||
* @return Promise that resolves either when all
|
||||
* preview diffs are fetched or no fix suggestions in custom event detail.
|
||||
*/
|
||||
open(e) {
|
||||
this._patchNum = e.detail.patchNum;
|
||||
this._fixSuggestions = e.detail.comment.fix_suggestions;
|
||||
this._robotId = e.detail.comment.robot_id;
|
||||
if (this._fixSuggestions == null || this._fixSuggestions.length == 0) {
|
||||
open(e: CustomEvent<CommentEventDetail>) {
|
||||
const detail = e.detail;
|
||||
const comment = detail.comment;
|
||||
if (!detail.patchNum || !comment || !isRobotComment(comment)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
this._patchNum = detail.patchNum;
|
||||
this._fixSuggestions = comment.fix_suggestions;
|
||||
this._robotId = comment.robot_id;
|
||||
if (!this._fixSuggestions || !this._fixSuggestions.length) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
this._selectedFixIdx = 0;
|
||||
const promises = [];
|
||||
promises.push(
|
||||
this._showSelectedFixSuggestion(this._fixSuggestions[0]),
|
||||
this.$.applyFixOverlay.open()
|
||||
this._showSelectedFixSuggestion(this._fixSuggestions[0]),
|
||||
this.$.applyFixOverlay.open()
|
||||
);
|
||||
return Promise.all(promises)
|
||||
.then(() => {
|
||||
// ensures gr-overlay repositions overlay in center
|
||||
this.$.applyFixOverlay.dispatchEvent(
|
||||
new CustomEvent('iron-resize', {
|
||||
composed: true, bubbles: true,
|
||||
}));
|
||||
});
|
||||
return Promise.all(promises).then(() => {
|
||||
// ensures gr-overlay repositions overlay in center
|
||||
this.$.applyFixOverlay.dispatchEvent(
|
||||
new CustomEvent('iron-resize', {
|
||||
composed: true,
|
||||
bubbles: true,
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
attached() {
|
||||
@@ -102,114 +146,132 @@ class GrApplyFixDialog extends GestureEventListeners(
|
||||
this.refitOverlay = () => {
|
||||
// re-center the dialog as content changed
|
||||
this.$.applyFixOverlay.dispatchEvent(
|
||||
new CustomEvent('iron-resize', {
|
||||
composed: true, bubbles: true,
|
||||
}));
|
||||
new CustomEvent('iron-resize', {
|
||||
composed: true,
|
||||
bubbles: true,
|
||||
})
|
||||
);
|
||||
};
|
||||
this.addEventListener('diff-context-expanded', this.refitOverlay);
|
||||
}
|
||||
|
||||
detached() {
|
||||
super.detached();
|
||||
this.removeEventListener('diff-context-expanded', this.refitOverlay);
|
||||
if (this.refitOverlay) {
|
||||
this.removeEventListener('diff-context-expanded', this.refitOverlay);
|
||||
}
|
||||
}
|
||||
|
||||
_showSelectedFixSuggestion(fixSuggestion) {
|
||||
_showSelectedFixSuggestion(fixSuggestion: FixSuggestionInfo) {
|
||||
this._currentFix = fixSuggestion;
|
||||
return this._fetchFixPreview(fixSuggestion.fix_id);
|
||||
}
|
||||
|
||||
_fetchFixPreview(fixId) {
|
||||
_fetchFixPreview(fixId: FixId) {
|
||||
if (!this.changeNum || !this._patchNum) {
|
||||
return Promise.reject(
|
||||
new Error('Both _patchNum and changeNum must be set')
|
||||
);
|
||||
}
|
||||
return this.$.restAPI
|
||||
.getRobotCommentFixPreview(this.changeNum, this._patchNum, fixId)
|
||||
.then(res => {
|
||||
if (res != null) {
|
||||
this._currentPreviews = Object.keys(res).map(key => {
|
||||
return {filepath: key, preview: res[key]};
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
this._close();
|
||||
throw err;
|
||||
});
|
||||
.getRobotCommentFixPreview(this.changeNum, this._patchNum, fixId)
|
||||
.then(res => {
|
||||
if (res) {
|
||||
this._currentPreviews = Object.keys(res).map(key => {
|
||||
return {filepath: key, preview: res[key]};
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
this._close();
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
hasSingleFix(_fixSuggestions) {
|
||||
return (_fixSuggestions || {}).length === 1;
|
||||
hasSingleFix(_fixSuggestions?: FixSuggestionInfo[]) {
|
||||
return (_fixSuggestions || []).length === 1;
|
||||
}
|
||||
|
||||
overridePartialPrefs(prefs) {
|
||||
overridePartialPrefs(prefs: DiffPreferencesInfo): DiffPreferencesInfo {
|
||||
// generate a smaller gr-diff than fullscreen for dialog
|
||||
return {...prefs, line_length: 50};
|
||||
}
|
||||
|
||||
onCancel(e) {
|
||||
onCancel(e: CustomEvent) {
|
||||
if (e) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
this._close();
|
||||
}
|
||||
|
||||
addOneTo(_selectedFixIdx) {
|
||||
addOneTo(_selectedFixIdx: number) {
|
||||
return _selectedFixIdx + 1;
|
||||
}
|
||||
|
||||
_onPrevFixClick(e) {
|
||||
_onPrevFixClick(e: CustomEvent) {
|
||||
if (e) e.stopPropagation();
|
||||
if (this._selectedFixIdx >= 1 && this._fixSuggestions != null) {
|
||||
if (this._selectedFixIdx >= 1 && this._fixSuggestions) {
|
||||
this._selectedFixIdx -= 1;
|
||||
return this._showSelectedFixSuggestion(
|
||||
this._fixSuggestions[this._selectedFixIdx]);
|
||||
this._showSelectedFixSuggestion(
|
||||
this._fixSuggestions[this._selectedFixIdx]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_onNextFixClick(e) {
|
||||
_onNextFixClick(e: CustomEvent) {
|
||||
if (e) e.stopPropagation();
|
||||
if (this._fixSuggestions &&
|
||||
this._selectedFixIdx < this._fixSuggestions.length) {
|
||||
if (
|
||||
this._fixSuggestions &&
|
||||
this._selectedFixIdx < this._fixSuggestions.length
|
||||
) {
|
||||
this._selectedFixIdx += 1;
|
||||
return this._showSelectedFixSuggestion(
|
||||
this._fixSuggestions[this._selectedFixIdx]);
|
||||
this._showSelectedFixSuggestion(
|
||||
this._fixSuggestions[this._selectedFixIdx]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
_noPrevFix(_selectedFixIdx) {
|
||||
_noPrevFix(_selectedFixIdx: number) {
|
||||
return _selectedFixIdx === 0;
|
||||
}
|
||||
|
||||
_noNextFix(_selectedFixIdx, fixSuggestions) {
|
||||
if (fixSuggestions == null) return true;
|
||||
_noNextFix(_selectedFixIdx: number, fixSuggestions?: FixSuggestionInfo[]) {
|
||||
if (!fixSuggestions) return true;
|
||||
return _selectedFixIdx === fixSuggestions.length - 1;
|
||||
}
|
||||
|
||||
_close() {
|
||||
this._currentFix = {};
|
||||
this._currentFix = undefined;
|
||||
this._currentPreviews = [];
|
||||
this._isApplyFixLoading = false;
|
||||
|
||||
this.dispatchEvent(new CustomEvent('close-fix-preview', {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
}));
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('close-fix-preview', {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
})
|
||||
);
|
||||
this.$.applyFixOverlay.close();
|
||||
}
|
||||
|
||||
_getApplyFixButtonLabel(isLoading) {
|
||||
_getApplyFixButtonLabel(isLoading: boolean) {
|
||||
return isLoading ? 'Saving...' : 'Apply Fix';
|
||||
}
|
||||
|
||||
_computeTooltip(change, patchNum) {
|
||||
if (!change || patchNum == undefined) return '';
|
||||
// If change is defined, change.revisions and change.current_revisions
|
||||
// must be defined
|
||||
_computeTooltip(change?: ParsedChangeInfo, patchNum?: PatchSetNum) {
|
||||
if (!change || !patchNum) return '';
|
||||
const latestPatchNum = change.revisions[change.current_revision]._number;
|
||||
return latestPatchNum !== patchNum ?
|
||||
'Fix can only be applied to the latest patchset' : '';
|
||||
return latestPatchNum !== patchNum
|
||||
? 'Fix can only be applied to the latest patchset'
|
||||
: '';
|
||||
}
|
||||
|
||||
_computeDisableApplyFixButton(isApplyFixLoading, change, patchNum) {
|
||||
if (!change || isApplyFixLoading == undefined || patchNum == undefined) {
|
||||
_computeDisableApplyFixButton(
|
||||
isApplyFixLoading?: boolean,
|
||||
change?: ParsedChangeInfo,
|
||||
patchNum?: PatchSetNum
|
||||
) {
|
||||
if (!change || isApplyFixLoading === undefined || patchNum === undefined) {
|
||||
return true;
|
||||
}
|
||||
const currentPatchNum = change.revisions[change.current_revision]._number;
|
||||
@@ -219,31 +281,36 @@ class GrApplyFixDialog extends GestureEventListeners(
|
||||
return isApplyFixLoading;
|
||||
}
|
||||
|
||||
_handleApplyFix(e) {
|
||||
_handleApplyFix(e: CustomEvent) {
|
||||
if (e) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
if (this._currentFix == null || this._currentFix.fix_id == null) {
|
||||
return;
|
||||
|
||||
const changeNum = this.changeNum;
|
||||
const patchNum = this._patchNum;
|
||||
const change = this.change;
|
||||
if (!changeNum || !patchNum || !change || !this._currentFix) {
|
||||
return Promise.reject(new Error('Not all required properties are set.'));
|
||||
}
|
||||
this._isApplyFixLoading = true;
|
||||
return this.$.restAPI
|
||||
.applyFixSuggestion(
|
||||
this.changeNum, this._patchNum, this._currentFix.fix_id
|
||||
)
|
||||
.then(res => {
|
||||
if (res && res.ok) {
|
||||
GerritNav.navigateToChange(this.change, 'edit', this._patchNum);
|
||||
this._close();
|
||||
}
|
||||
this._isApplyFixLoading = false;
|
||||
});
|
||||
.applyFixSuggestion(changeNum, patchNum, this._currentFix.fix_id)
|
||||
.then(res => {
|
||||
if (res && res.ok) {
|
||||
GerritNav.navigateToChange(change, EditPatchSetNum, patchNum);
|
||||
this._close();
|
||||
}
|
||||
this._isApplyFixLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
getFixDescription(currentFix) {
|
||||
return currentFix != null && currentFix.description ?
|
||||
currentFix.description : '';
|
||||
getFixDescription(currentFix?: FixSuggestionInfo) {
|
||||
return currentFix && currentFix.description ? currentFix.description : '';
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(GrApplyFixDialog.is, GrApplyFixDialog);
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'gr-apply-fix-dialog': GrApplyFixDialog;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,19 +179,19 @@ suite('gr-apply-fix-dialog tests', () => {
|
||||
comment: ROBOT_COMMENT_WITH_TWO_FIXES}});
|
||||
flush(() => {
|
||||
assert.isTrue(errorStub.called);
|
||||
assert.deepEqual(element._currentFix, {});
|
||||
assert.equal(element._currentFix, undefined);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('apply fix button should call apply ' +
|
||||
'and navigate to change view', done => {
|
||||
'and navigate to change view', () => {
|
||||
sinon.stub(element.$.restAPI, 'applyFixSuggestion')
|
||||
.returns(Promise.resolve({ok: true}));
|
||||
sinon.stub(GerritNav, 'navigateToChange');
|
||||
element._currentFix = {fix_id: '123'};
|
||||
|
||||
element._handleApplyFix().then(() => {
|
||||
return element._handleApplyFix().then(() => {
|
||||
assert.isTrue(element.$.restAPI.applyFixSuggestion
|
||||
.calledWithExactly('1', 2, '123'));
|
||||
assert.isTrue(GerritNav.navigateToChange.calledWithExactly({
|
||||
@@ -205,9 +205,8 @@ suite('gr-apply-fix-dialog tests', () => {
|
||||
}, 'edit', 2));
|
||||
|
||||
// reset gr-apply-fix-dialog and close
|
||||
assert.deepEqual(element._currentFix, {});
|
||||
assert.equal(element._currentFix, undefined);
|
||||
assert.equal(element._currentPreviews.length, 0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ import {
|
||||
PatchSetNum,
|
||||
EditPreferencesInfo,
|
||||
Base64FileContent,
|
||||
ChangeNum,
|
||||
} from '../../../types/common';
|
||||
import {GrStorage} from '../../shared/gr-storage/gr-storage';
|
||||
|
||||
@@ -83,7 +84,7 @@ export class GrEditorView extends KeyboardShortcutMixin(
|
||||
_change?: ChangeInfo | null;
|
||||
|
||||
@property({type: Number})
|
||||
_changeNum?: number;
|
||||
_changeNum?: ChangeNum;
|
||||
|
||||
@property({type: String})
|
||||
_patchNum?: PatchSetNum;
|
||||
@@ -189,7 +190,7 @@ export class GrEditorView extends KeyboardShortcutMixin(
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
_getChangeDetail(changeNum: number) {
|
||||
_getChangeDetail(changeNum: ChangeNum) {
|
||||
return this.$.restAPI.getDiffChangeDetail(changeNum).then(change => {
|
||||
this._change = change;
|
||||
});
|
||||
@@ -229,7 +230,7 @@ export class GrEditorView extends KeyboardShortcutMixin(
|
||||
);
|
||||
}
|
||||
|
||||
_getFileData(changeNum: number, path: string, patchNum?: PatchSetNum) {
|
||||
_getFileData(changeNum: ChangeNum, path: string, patchNum?: PatchSetNum) {
|
||||
if (patchNum === undefined) {
|
||||
return Promise.reject(new Error('patchNum undefined'));
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ import {
|
||||
CommentInfo,
|
||||
ConfigInfo,
|
||||
AccountDetailInfo,
|
||||
ChangeNum,
|
||||
} from '../../../types/common';
|
||||
import {GrButton} from '../gr-button/gr-button';
|
||||
import {GrConfirmDeleteCommentDialog} from '../gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog';
|
||||
@@ -96,6 +97,10 @@ export interface Draft {
|
||||
export type Comment = Draft & CommentInfo;
|
||||
export type RobotComment = Draft & RobotCommentInfo;
|
||||
|
||||
export function isRobotComment(c: Comment | RobotComment): c is RobotComment {
|
||||
return (c as RobotComment).robot_id !== undefined;
|
||||
}
|
||||
|
||||
interface CommentOverlays {
|
||||
confirmDelete?: GrOverlay | null;
|
||||
confirmDiscard?: GrOverlay | null;
|
||||
@@ -109,6 +114,12 @@ export interface GrComment {
|
||||
resolvedCheckbox: HTMLInputElement;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CommentEventDetail {
|
||||
patchNum?: PatchSetNum;
|
||||
comment?: Comment | RobotComment;
|
||||
}
|
||||
|
||||
@customElement('gr-comment')
|
||||
export class GrComment extends KeyboardShortcutMixin(
|
||||
GestureEventListeners(LegacyElementMixin(PolymerElement))
|
||||
@@ -160,7 +171,7 @@ export class GrComment extends KeyboardShortcutMixin(
|
||||
*/
|
||||
|
||||
@property({type: Number})
|
||||
changeNum?: number;
|
||||
changeNum?: ChangeNum;
|
||||
|
||||
@property({type: Object, notify: true, observer: '_commentChanged'})
|
||||
comment?: Comment | RobotComment;
|
||||
@@ -506,8 +517,8 @@ export class GrComment extends KeyboardShortcutMixin(
|
||||
);
|
||||
}
|
||||
|
||||
_getEventPayload(opt_mixin?: Record<string, any>) {
|
||||
return {...opt_mixin, comment: this.comment, patchNum: this.patchNum};
|
||||
_getEventPayload(): CommentEventDetail {
|
||||
return {comment: this.comment, patchNum: this.patchNum};
|
||||
}
|
||||
|
||||
_fireSave() {
|
||||
|
||||
@@ -130,6 +130,9 @@ import {
|
||||
SubmittedTogetherInfo,
|
||||
ChangeNum,
|
||||
EmailAddress,
|
||||
FixId,
|
||||
FilePathToDiffInfoMap,
|
||||
ChangeViewChangeInfo,
|
||||
} from '../../../types/common';
|
||||
import {
|
||||
CancelConditionCallback,
|
||||
@@ -1388,7 +1391,11 @@ export class GrRestApiInterface
|
||||
optionsHex,
|
||||
errFn,
|
||||
cancelCondition
|
||||
).then(GrReviewerUpdatesParser.parse);
|
||||
).then(detail =>
|
||||
// detail has ChangeViewChangeInfo type because the optionsHex always
|
||||
// includes ALL_REVISIONS flag.
|
||||
GrReviewerUpdatesParser.parse(detail as ChangeViewChangeInfo)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2329,21 +2336,21 @@ export class GrRestApiInterface
|
||||
getRobotCommentFixPreview(
|
||||
changeNum: ChangeNum,
|
||||
patchNum: PatchSetNum,
|
||||
fixId: string
|
||||
) {
|
||||
fixId: FixId
|
||||
): Promise<FilePathToDiffInfoMap | undefined> {
|
||||
return this._getChangeURLAndFetch({
|
||||
changeNum,
|
||||
patchNum,
|
||||
endpoint: `/fixes/${encodeURIComponent(fixId)}/preview`,
|
||||
reportEndpointAsId: true,
|
||||
});
|
||||
}) as Promise<FilePathToDiffInfoMap | undefined>;
|
||||
}
|
||||
|
||||
applyFixSuggestion(
|
||||
changeNum: ChangeNum,
|
||||
patchNum: PatchSetNum,
|
||||
fixId: string
|
||||
) {
|
||||
): Promise<Response> {
|
||||
return this._getChangeURLAndSend({
|
||||
method: HttpMethod.POST,
|
||||
changeNum,
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
AccountInfo,
|
||||
ChangeInfo,
|
||||
ChangeMessageInfo,
|
||||
ChangeViewChangeInfo,
|
||||
ReviewerUpdateInfo,
|
||||
Timestamp,
|
||||
} from '../../../types/common';
|
||||
@@ -30,7 +31,7 @@ import {accountKey} from '../../../utils/account-util';
|
||||
const MESSAGE_REVIEWERS_THRESHOLD_MILLIS = 500;
|
||||
const REVIEWER_UPDATE_THRESHOLD_MILLIS = 6000;
|
||||
|
||||
interface ChangeInfoParserInput extends ChangeInfo {
|
||||
interface ChangeInfoParserInput extends ChangeViewChangeInfo {
|
||||
messages: ChangeMessageInfo[];
|
||||
reviewer_updates: ReviewerUpdateInfo[]; // Always has at least 1 item
|
||||
}
|
||||
@@ -77,7 +78,8 @@ interface UpdateItem {
|
||||
prev_state?: ReviewerState;
|
||||
}
|
||||
|
||||
export interface ParsedChangeInfo extends Omit<ChangeInfo, 'reviewer_updates'> {
|
||||
export interface ParsedChangeInfo
|
||||
extends Omit<ChangeViewChangeInfo, 'reviewer_updates'> {
|
||||
reviewer_updates?: ReviewerUpdateInfo[] | FormattedReviewerUpdateInfo[];
|
||||
}
|
||||
|
||||
@@ -291,7 +293,7 @@ export class GrReviewerUpdatesParser {
|
||||
}
|
||||
|
||||
static parse(
|
||||
change: ChangeInfo | undefined | null
|
||||
change: ChangeViewChangeInfo | undefined | null
|
||||
): ParsedChangeInfo | undefined | null {
|
||||
// TODO(TS): The !change condition should be removed when all files are converted to TS
|
||||
if (!change || !isChangeInfoParserInput(change)) {
|
||||
|
||||
@@ -85,6 +85,8 @@ import {
|
||||
RelatedChangesInfo,
|
||||
SubmittedTogetherInfo,
|
||||
EmailAddress,
|
||||
FixId,
|
||||
FilePathToDiffInfoMap,
|
||||
} from '../../../types/common';
|
||||
import {ParsedChangeInfo} from '../../../elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser';
|
||||
import {HttpMethod} from '../../../constants/constants';
|
||||
@@ -718,4 +720,16 @@ export interface RestApiService {
|
||||
|
||||
hasPendingDiffDrafts(): number;
|
||||
awaitPendingDiffDrafts(): Promise<void>;
|
||||
|
||||
getRobotCommentFixPreview(
|
||||
changeNum: ChangeNum,
|
||||
patchNum: PatchSetNum,
|
||||
fixId: FixId
|
||||
): Promise<FilePathToDiffInfoMap | undefined>;
|
||||
|
||||
applyFixSuggestion(
|
||||
changeNum: ChangeNum,
|
||||
patchNum: PatchSetNum,
|
||||
fixId: string
|
||||
): Promise<Response>;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,12 @@ import {
|
||||
export type BrandType<T, BrandName extends string> = T &
|
||||
{[__brand in BrandName]: never};
|
||||
|
||||
/*
|
||||
* In T, make a set of properties whose keys are in the union K required
|
||||
*/
|
||||
export type RequireProperties<T, K extends keyof T> = Omit<T, K> &
|
||||
Required<Pick<T, K>>;
|
||||
|
||||
/**
|
||||
* Type alias for parsed json object to make code cleaner
|
||||
*/
|
||||
@@ -62,7 +68,7 @@ export const ParentPatchSetNum = 'PARENT' as PatchSetNum;
|
||||
export type ChangeId = BrandType<string, '_changeId'>;
|
||||
export type ChangeMessageId = BrandType<string, '_changeMessageId'>;
|
||||
export type NumericChangeId = BrandType<number, '_numericChangeId'>;
|
||||
export type ChangeNum = number; // !!!TODO: define correct types
|
||||
export type ChangeNum = NumericChangeId; // This type is removed in the following change
|
||||
export type RepoName = BrandType<string, '_repoName'>;
|
||||
export type UrlEncodedRepoName = BrandType<string, '_urlEncodedRepoName'>;
|
||||
export type TopicName = BrandType<string, '_topicName'>;
|
||||
@@ -74,6 +80,8 @@ export type TrackingId = BrandType<string, '_trackingId'>;
|
||||
export type ReviewInputTag = BrandType<string, '_reviewInputTag'>;
|
||||
export type RobotId = BrandType<string, '_robotId'>;
|
||||
export type RobotRunId = BrandType<string, '_robotRunId'>;
|
||||
|
||||
// The UUID of the suggested fix.
|
||||
export type FixId = BrandType<string, '_fixId'>;
|
||||
export type EmailAddress = BrandType<string, '_emailAddress'>;
|
||||
|
||||
@@ -237,6 +245,14 @@ export interface ChangeInfo {
|
||||
internalHost?: string; // TODO(TS): provide an explanation what is its
|
||||
}
|
||||
|
||||
/**
|
||||
* ChangeView request change detail with ALL_REVISIONS option set.
|
||||
* The response always contains current_revision and revisions.
|
||||
*/
|
||||
export type ChangeViewChangeInfo = RequireProperties<
|
||||
ChangeInfo,
|
||||
'current_revision' | 'revisions'
|
||||
>;
|
||||
/**
|
||||
* The AccountInfo entity contains information about an account.
|
||||
* https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#account-info
|
||||
@@ -1178,6 +1194,8 @@ export interface DiffInfo {
|
||||
binary: boolean;
|
||||
}
|
||||
|
||||
export type FilePathToDiffInfoMap = {[path: string]: DiffInfo};
|
||||
|
||||
/**
|
||||
* The DiffWebLinkInfo entity describes a link on a diff screen to an external site.
|
||||
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#diff-web-link-info
|
||||
@@ -1876,8 +1894,13 @@ export type PathToRobotCommentsInfoMap = {[path: string]: RobotCommentInfo[]};
|
||||
* The FixSuggestionInfo entity represents a suggested fix
|
||||
* https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#fix-suggestion-info
|
||||
*/
|
||||
export interface FixSuggestionInfo {
|
||||
fix_id?: FixId;
|
||||
export interface FixSuggestionInfoInput {
|
||||
description: string;
|
||||
replacements: FixReplacementInfo[];
|
||||
}
|
||||
|
||||
export interface FixSuggestionInfo extends FixSuggestionInfoInput {
|
||||
fix_id: FixId;
|
||||
description: string;
|
||||
replacements: FixReplacementInfo[];
|
||||
}
|
||||
|
||||
@@ -169,7 +169,9 @@ export function sortRevisions<T extends RevisionInfo>(revisions: T[]): T[] {
|
||||
* @return Sorted list of patch set objects, as described
|
||||
* above
|
||||
*/
|
||||
export function computeAllPatchSets(change: ParsedChangeInfo): PatchSet[] {
|
||||
export function computeAllPatchSets(
|
||||
change: ChangeInfo | ParsedChangeInfo
|
||||
): PatchSet[] {
|
||||
if (!change) {
|
||||
return [];
|
||||
}
|
||||
@@ -205,7 +207,7 @@ export function computeAllPatchSets(change: ParsedChangeInfo): PatchSet[] {
|
||||
* wip property set on each of them
|
||||
*/
|
||||
function _computeWipForPatchSets(
|
||||
change: ParsedChangeInfo,
|
||||
change: ChangeInfo | ParsedChangeInfo,
|
||||
patchNums: PatchSet[]
|
||||
) {
|
||||
if (!change.messages || !change.messages.length) {
|
||||
|
||||
Reference in New Issue
Block a user