Convert gr-error-manager to typescript
The change converts the following files to typescript:
* elements/core/gr-error-manager/gr-error-manager.ts
Change-Id: Iafe5680b04b45ffe7b71fd9e1cc22f972e7f780b
diff --git a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.ts b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.ts
index 0c88426..11996c1 100644
--- a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.ts
+++ b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.ts
@@ -16,18 +16,28 @@
*/
/* Import to get Gerrit interface */
/* TODO(taoalpha): decouple gr-gerrit from gr-js-api-interface */
-import '../gr-error-dialog/gr-error-dialog.js';
-import '../../shared/gr-alert/gr-alert.js';
-import '../../shared/gr-overlay/gr-overlay.js';
-import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
-import '../../shared/gr-js-api-interface/gr-js-api-interface.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-error-manager_html.js';
-import {getBaseUrl} from '../../../utils/url-util.js';
-import {appContext} from '../../../services/app-context.js';
-import {IronA11yAnnouncer} from '@polymer/iron-a11y-announcer/iron-a11y-announcer.js';
+import '../gr-error-dialog/gr-error-dialog';
+import '../../shared/gr-alert/gr-alert';
+import '../../shared/gr-overlay/gr-overlay';
+import '../../shared/gr-rest-api-interface/gr-rest-api-interface';
+import '../../shared/gr-js-api-interface/gr-js-api-interface';
+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-error-manager_html';
+import {getBaseUrl} from '../../../utils/url-util';
+import {appContext} from '../../../services/app-context';
+import {IronA11yAnnouncer} from '@polymer/iron-a11y-announcer/iron-a11y-announcer';
+import {customElement, property} from '@polymer/decorators';
+import {ReportingService} from '../../../services/gr-reporting/gr-reporting';
+import {AuthService} from '../../../services/gr-auth/gr-auth';
+import {EventEmitterService} from '../../../services/gr-event-interface/gr-event-interface';
+import {GrOverlay} from '../../shared/gr-overlay/gr-overlay';
+import {GrErrorDialog} from '../gr-error-dialog/gr-error-dialog';
+import {GrAlert} from '../../shared/gr-alert/gr-alert';
+import {RestApiService} from '../../../services/services/gr-rest-api/gr-rest-api';
+import {FetchRequest} from '../../shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';
+import {ErrorType, FixIronA11yAnnouncer} from '../../../types/types';
const HIDE_ALERT_TIMEOUT_MS = 5000;
const CHECK_SIGN_IN_INTERVAL_MS = 60 * 1000;
@@ -37,12 +47,6 @@
const TOO_MANY_FILES = 'too many files to find conflicts';
const AUTHENTICATION_REQUIRED = 'Authentication required\n';
-const ErrorType = {
- AUTH: 'AUTH',
- NETWORK: 'NETWORK',
- GENERIC: 'GENERIC',
-};
-
// Bigger number has higher priority
const ErrorTypePriority = {
[ErrorType.AUTH]: 3,
@@ -50,59 +54,71 @@
[ErrorType.GENERIC]: 1,
};
+interface ErrorMsg {
+ errorText?: string;
+ status?: number;
+ statusText?: string;
+ url?: string;
+ trace?: string | null;
+ tip?: string;
+}
+
export const __testOnly_ErrorType = ErrorType;
-/**
- * @extends PolymerElement
- */
-class GrErrorManager extends GestureEventListeners(
- LegacyElementMixin(
- PolymerElement)) {
- static get template() { return htmlTemplate; }
-
- static get is() { return 'gr-error-manager'; }
-
- static get properties() {
- return {
- /**
- * The ID of the account that was logged in when the app was launched. If
- * not set, then there was no account at launch.
- */
- knownAccountId: Number,
-
- /** @type {?Object} */
- _alertElement: Object,
- /** @type {?number} */
- _hideAlertHandle: Number,
- _refreshingCredentials: {
- type: Boolean,
- value: false,
- },
-
- /**
- * The time (in milliseconds) since the most recent credential check.
- */
- _lastCredentialCheck: {
- type: Number,
- value() { return Date.now(); },
- },
-
- loginUrl: {
- type: String,
- value: '/login',
- },
- };
+export interface GrErrorManager {
+ $: {
+ noInteractionOverlay: GrOverlay;
+ errorDialog: GrErrorDialog;
+ errorOverlay: GrOverlay;
+ restAPI: RestApiService & Element;
+ };
+}
+@customElement('gr-error-manager')
+export class GrErrorManager extends GestureEventListeners(
+ LegacyElementMixin(PolymerElement)
+) {
+ static get template() {
+ return htmlTemplate;
}
+ /**
+ * The ID of the account that was logged in when the app was launched. If
+ * not set, then there was no account at launch.
+ */
+ @property({type: Number})
+ knownAccountId?: number;
+
+ @property({type: Object})
+ _alertElement: GrAlert | null = null;
+
+ @property({type: Number})
+ _hideAlertHandle: number | null = null;
+
+ @property({type: Boolean})
+ _refreshingCredentials = false;
+
+ /**
+ * The time (in milliseconds) since the most recent credential check.
+ */
+ @property({type: Number})
+ _lastCredentialCheck: number = Date.now();
+
+ @property({type: String})
+ loginUrl = '/login';
+
+ reporting: ReportingService;
+
+ _authService: AuthService;
+
+ eventEmitter: EventEmitterService;
+
+ _authErrorHandlerDeregistrationHook?: Function;
+
constructor() {
super();
- /** @type {!Auth} */
this._authService = appContext.authService;
- /** @type {?Function} */
- this._authErrorHandlerDeregistrationHook;
-
this.reporting = appContext.reportingService;
this.eventEmitter = appContext.eventEmitter;
}
@@ -118,13 +134,14 @@
this.listen(document, 'visibilitychange', '_handleVisibilityChange');
this.listen(document, 'show-auth-required', '_handleAuthRequired');
- this._authErrorHandlerDeregistrationHook =
- this.eventEmitter.on('auth-error',
- event => {
- this._handleAuthError(event.message, event.action);
- });
+ this._authErrorHandlerDeregistrationHook = this.eventEmitter.on(
+ 'auth-error',
+ event => {
+ this._handleAuthError(event.message, event.action);
+ }
+ );
- IronA11yAnnouncer.requestAvailability();
+ ((IronA11yAnnouncer as unknown) as FixIronA11yAnnouncer).requestAvailability();
}
/** @override */
@@ -139,38 +156,48 @@
this.unlisten(document, 'visibilitychange', '_handleVisibilityChange');
this.unlisten(document, 'show-auth-required', '_handleAuthRequired');
- this._authErrorHandlerDeregistrationHook();
+ if (this._authErrorHandlerDeregistrationHook) {
+ this._authErrorHandlerDeregistrationHook();
+ }
}
- _shouldSuppressError(msg) {
+ _shouldSuppressError(msg: string) {
return msg.includes(TOO_MANY_FILES);
}
_handleAuthRequired() {
this._showAuthErrorAlert(
- 'Log in is required to perform that action.', 'Log in.');
+ 'Log in is required to perform that action.',
+ 'Log in.'
+ );
}
- _handleAuthError(msg, action) {
+ _handleAuthError(msg: string, action: string) {
this.$.noInteractionOverlay.open().then(() => {
this._showAuthErrorAlert(msg, action);
});
}
- _handleServerError(e) {
+ _handleServerError(
+ e: CustomEvent<{response: Response; request: FetchRequest}>
+ ) {
const {request, response} = e.detail;
response.text().then(errorText => {
const url = request && (request.anonymizedUrl || request.url);
const {status, statusText} = response;
- if (response.status === 403
- && !this._authService.isAuthed
- && errorText === AUTHENTICATION_REQUIRED) {
+ if (
+ response.status === 403 &&
+ !this._authService.isAuthed &&
+ errorText === AUTHENTICATION_REQUIRED
+ ) {
// if not authed previously, this is trying to access auth required APIs
// show auth required alert
this._handleAuthRequired();
- } else if (response.status === 403
- && this._authService.isAuthed
- && errorText === AUTHENTICATION_REQUIRED) {
+ } else if (
+ response.status === 403 &&
+ this._authService.isAuthed &&
+ errorText === AUTHENTICATION_REQUIRED
+ ) {
// The app was logged at one point and is now getting auth errors.
// This indicates the auth token may no longer valid.
// Re-check on auth
@@ -178,7 +205,7 @@
this.$.restAPI.getLoggedIn();
} else if (!this._shouldSuppressError(errorText)) {
const trace =
- response.headers && response.headers.get('X-Gerrit-Trace');
+ response.headers && response.headers.get('X-Gerrit-Trace');
if (response.status === 404) {
this._showNotFoundMessageWithTip({
status,
@@ -188,57 +215,89 @@
trace,
});
} else {
- this._showErrorDialog(this._constructServerErrorMsg({
- status,
- statusText,
- errorText,
- url,
- trace,
- }));
+ this._showErrorDialog(
+ this._constructServerErrorMsg({
+ status,
+ statusText,
+ errorText,
+ url,
+ trace,
+ })
+ );
}
}
console.info(`server error: ${errorText}`);
});
}
- _showNotFoundMessageWithTip({status, statusText, errorText, url, trace}) {
+ _showNotFoundMessageWithTip({
+ status,
+ statusText,
+ errorText,
+ url,
+ trace,
+ }: ErrorMsg) {
this.$.restAPI.getLoggedIn().then(isLoggedIn => {
- const tip = isLoggedIn ?
- 'You might have not enough privileges.' :
- 'You might have not enough privileges. Sign in and try again.';
- this._showErrorDialog(this._constructServerErrorMsg({
- status,
- statusText,
- errorText,
- url,
- trace,
- tip,
- }), {
- showSignInButton: !isLoggedIn,
- });
+ const tip = isLoggedIn
+ ? 'You might have not enough privileges.'
+ : 'You might have not enough privileges. Sign in and try again.';
+ this._showErrorDialog(
+ this._constructServerErrorMsg({
+ status,
+ statusText,
+ errorText,
+ url,
+ trace,
+ tip,
+ }),
+ {
+ showSignInButton: !isLoggedIn,
+ }
+ );
});
}
- _constructServerErrorMsg({errorText, status, statusText, url, trace, tip}) {
+ _constructServerErrorMsg({
+ errorText,
+ status,
+ statusText,
+ url,
+ trace,
+ tip,
+ }: ErrorMsg) {
let err = '';
if (tip) {
err += `${tip}\n\n`;
}
err += `Error ${status}`;
- if (statusText) { err += ` (${statusText})`; }
- if (errorText || url) { err += ': '; }
- if (errorText) { err += errorText; }
- if (url) { err += `\nEndpoint: ${url}`; }
- if (trace) { err += `\nTrace Id: ${trace}`; }
+ if (statusText) {
+ err += ` (${statusText})`;
+ }
+ if (errorText || url) {
+ err += ': ';
+ }
+ if (errorText) {
+ err += errorText;
+ }
+ if (url) {
+ err += `\nEndpoint: ${url}`;
+ }
+ if (trace) {
+ err += `\nTrace Id: ${trace}`;
+ }
return err;
}
- _handleShowAlert(e) {
- this._showAlert(e.detail.message, e.detail.action, e.detail.callback,
- e.detail.dismissOnNavigation);
+ _handleShowAlert(e: CustomEvent) {
+ this._showAlert(
+ e.detail.message,
+ e.detail.action,
+ e.detail.callback,
+ e.detail.dismissOnNavigation
+ );
}
- _handleNetworkError(e) {
+ _handleNetworkError(e: CustomEvent) {
this._showAlert('Server unavailable');
console.error(e.detail.error.message);
}
@@ -249,37 +308,39 @@
return ErrorTypePriority[incoming] >= ErrorTypePriority[existing];
}
- /**
- * @param {string} text
- * @param {?string=} opt_actionText
- * @param {?Function=} opt_actionCallback
- * @param {?boolean=} opt_dismissOnNavigation
- * @param {?string=} opt_type
- */
- _showAlert(text, opt_actionText, opt_actionCallback,
- opt_dismissOnNavigation, opt_type) {
+ _showAlert(
+ text: string,
+ actionText?: string,
+ actionCallback?: () => void,
+ dismissOnNavigation?: boolean,
+ type?: ErrorType
+ ) {
if (this._alertElement) {
// check priority before hiding
- if (!this._canOverride(opt_type, this._alertElement.type)) return;
+ if (!this._canOverride(type, this._alertElement.type)) return;
this._hideAlert();
}
this._clearHideAlertHandle();
- if (opt_dismissOnNavigation) {
+ if (dismissOnNavigation) {
// Persist alert until navigation.
this.listen(document, 'location-change', '_hideAlert');
} else {
- this._hideAlertHandle =
- this.async(this._hideAlert, HIDE_ALERT_TIMEOUT_MS);
+ this._hideAlertHandle = this.async(
+ this._hideAlert,
+ HIDE_ALERT_TIMEOUT_MS
+ );
}
const el = this._createToastAlert();
- el.show(text, opt_actionText, opt_actionCallback);
+ el.show(text, actionText, actionCallback);
this._alertElement = el;
- this.fire('iron-announce', {text}, {bubbles: true} );
+ this.fire('iron-announce', {text}, {bubbles: true});
}
_hideAlert() {
- if (!this._alertElement) { return; }
+ if (!this._alertElement) {
+ return;
+ }
this._alertElement.hide();
this._alertElement = null;
@@ -289,13 +350,13 @@
}
_clearHideAlertHandle() {
- if (this._hideAlertHandle != null) {
+ if (this._hideAlertHandle !== null) {
this.cancelAsync(this._hideAlertHandle);
this._hideAlertHandle = null;
}
}
- _showAuthErrorAlert(errorText, actionText) {
+ _showAuthErrorAlert(errorText: string, actionText?: string) {
// hide any existing alert like `reload`
// as auth error should have the highest priority
if (this._alertElement) {
@@ -304,9 +365,12 @@
this._alertElement = this._createToastAlert();
this._alertElement.type = ErrorType.AUTH;
- this._alertElement.show(errorText, actionText,
- this._createLoginPopup.bind(this));
- this.fire('iron-announce', {text: errorText}, {bubbles: true} );
+ this._alertElement.show(
+ errorText,
+ actionText,
+ this._createLoginPopup.bind(this)
+ );
+ this.fire('iron-announce', {text: errorText}, {bubbles: true});
this._refreshingCredentials = true;
this._requestCheckLoggedIn();
if (!document.hidden) {
@@ -323,15 +387,19 @@
_handleVisibilityChange() {
// Ignore when the page is transitioning to hidden (or hidden is
// undefined).
- if (document.hidden !== false) { return; }
+ if (document.hidden !== false) {
+ return;
+ }
// If not currently refreshing credentials and the credentials are old,
// request them to confirm their validity or (display an auth toast if it
// fails).
const timeSinceLastCheck = Date.now() - this._lastCredentialCheck;
- if (!this._refreshingCredentials &&
- this.knownAccountId !== undefined &&
- timeSinceLastCheck > STALE_CREDENTIAL_THRESHOLD_MS) {
+ if (
+ !this._refreshingCredentials &&
+ this.knownAccountId !== undefined &&
+ timeSinceLastCheck > STALE_CREDENTIAL_THRESHOLD_MS
+ ) {
this._lastCredentialCheck = Date.now();
// check auth status in case:
@@ -343,7 +411,10 @@
_requestCheckLoggedIn() {
this.debounce(
- 'checkLoggedIn', this._checkSignedIn, CHECK_SIGN_IN_INTERVAL_MS);
+ 'checkLoggedIn',
+ this._checkSignedIn,
+ CHECK_SIGN_IN_INTERVAL_MS
+ );
}
_checkSignedIn() {
@@ -369,7 +440,7 @@
if (this._refreshingCredentials) {
// If the credentials were refreshed but the account is different
// then reload the page completely.
- if (account._account_id !== this.knownAccountId) {
+ if (account?._account_id !== this.knownAccountId) {
this._reloadPage();
return;
}
@@ -386,18 +457,19 @@
}
_createLoginPopup() {
- const left = window.screenLeft +
- (window.outerWidth - SIGN_IN_WIDTH_PX) / 2;
- const top = window.screenTop +
- (window.outerHeight - SIGN_IN_HEIGHT_PX) / 2;
+ const left = window.screenLeft + (window.outerWidth - SIGN_IN_WIDTH_PX) / 2;
+ const top = window.screenTop + (window.outerHeight - SIGN_IN_HEIGHT_PX) / 2;
const options = [
- 'width=' + SIGN_IN_WIDTH_PX,
- 'height=' + SIGN_IN_HEIGHT_PX,
- 'left=' + left,
- 'top=' + top,
+ `width=${SIGN_IN_WIDTH_PX}`,
+ `height=${SIGN_IN_HEIGHT_PX}`,
+ `left=${left}`,
+ `top=${top}`,
];
- window.open(getBaseUrl() +
- '/login/%3FcloseAfterLogin', '_blank', options.join(','));
+ window.open(
+ getBaseUrl() + '/login/%3FcloseAfterLogin',
+ '_blank',
+ options.join(',')
+ );
this.listen(window, 'focus', '_handleWindowFocus');
}
@@ -416,7 +488,7 @@
this.flushDebouncer('checkLoggedIn');
}
- _handleShowErrorDialog(e) {
+ _handleShowErrorDialog(e: CustomEvent) {
this._showErrorDialog(e.detail.message);
}
@@ -424,13 +496,17 @@
this.$.errorOverlay.close();
}
- _showErrorDialog(message, opt_options) {
+ _showErrorDialog(message: string, options?: {showSignInButton?: boolean}) {
this.reporting.reportErrorDialog(message);
this.$.errorDialog.text = message;
this.$.errorDialog.showSignInButton =
- opt_options && opt_options.showSignInButton;
+ !!options && !!options.showSignInButton;
this.$.errorOverlay.open();
}
}
-customElements.define(GrErrorManager.is, GrErrorManager);
+declare global {
+ interface HTMLElementTagNameMap {
+ 'gr-error-manager': GrErrorManager;
+ }
+}
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.ts b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.ts
index bec07f0..e0333cc 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.ts
@@ -27,6 +27,7 @@
import {htmlTemplate} from './gr-diff-mode-selector_html';
import {customElement, property} from '@polymer/decorators';
import {IronA11yAnnouncer} from '@polymer/iron-a11y-announcer/iron-a11y-announcer';
+import {FixIronA11yAnnouncer} from '../../../types/types';
export interface GrDiffModeSelector {
$: {
@@ -34,10 +35,6 @@
};
}
-interface FixIronA11yAnnouncer extends IronA11yAnnouncer {
- requestAvailability(): void;
-}
-
@customElement('gr-diff-mode-selector')
export class GrDiffModeSelector extends GestureEventListeners(
LegacyElementMixin(PolymerElement)
diff --git a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.ts b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.ts
index 3a20b5e..046218b 100644
--- a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.ts
+++ b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.ts
@@ -22,6 +22,7 @@
import {htmlTemplate} from './gr-alert_html';
import {getRootElement} from '../../../scripts/rootElement';
import {customElement, property} from '@polymer/decorators';
+import {ErrorType} from '../../../types/types';
declare global {
interface HTMLElementTagNameMap {
@@ -30,7 +31,7 @@
}
@customElement('gr-alert')
-class GrAlert extends GestureEventListeners(
+export class GrAlert extends GestureEventListeners(
LegacyElementMixin(PolymerElement)
) {
static get template() {
@@ -50,7 +51,7 @@
actionText?: string;
@property({type: String})
- type?: string;
+ type?: ErrorType;
@property({type: Boolean, reflectToAttribute: true})
shown = true;
@@ -88,11 +89,11 @@
}
}
- show(text: string, opt_actionText: string, opt_actionCallback?: () => void) {
+ show(text: string, actionText?: string, actionCallback?: () => void) {
this.text = text;
- this.actionText = opt_actionText;
- this._hideActionButton = !opt_actionText;
- this._actionCallback = opt_actionCallback;
+ this.actionText = actionText;
+ this._hideActionButton = !actionText;
+ this._actionCallback = actionCallback;
getRootElement().appendChild(this);
this.shown = true;
}