blob: 66115c0fc01121bc7a8173e9975e09c076356fd5 [file] [log] [blame]
/**
* @module module/diff-page-sk
* @description <h2><code>diff-page-sk</code></h2>
*
* Page to view a specific diff between two digests. This does not include trace data.
*/
import { define } from 'elements-sk/define';
import { html } from 'lit-html';
import { jsonOrThrow } from 'common-sk/modules/jsonOrThrow';
import { stateReflector } from 'common-sk/modules/stateReflector';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import '../digest-details-sk';
import { sendBeginTask, sendEndTask, sendFetchError } from '../common';
import { DigestComparison, LeftDiffInfo, SRDiffDigest } from '../rpc_types';
export class DiffPageSk extends ElementSk {
private static template = (ele: DiffPageSk) => {
if (!ele.didInitialLoad) {
return html`<p>Loading...</p>`;
}
if (!ele.leftDetails) {
return html`<p>Could not load diff.</p>`;
}
return html`
<digest-details-sk .details=${ele.leftDetails}
.right=${ele.rightDetails}
.changeListID=${ele.changeListID}
.crs=${ele.crs}>
</digest-details-sk>
`;
};
private grouping = '';
private leftDigest = '';
private rightDigest = '';
private crs = '';
private changeListID = '';
private leftDetails: LeftDiffInfo | null = null;
private rightDetails: SRDiffDigest | null = null;
private didInitialLoad = false;
private readonly _stateChanged: ()=> void;
// Allows us to abort fetches if we fetch again.
private _fetchController?: AbortController;
constructor() {
super(DiffPageSk.template);
this._stateChanged = stateReflector(
/* getState */() => ({
// provide empty values
test: this.grouping, // TODO(kjlubick) rename test -> grouping
left: this.leftDigest,
right: this.rightDigest,
changelist_id: this.changeListID,
crs: this.crs,
}), /* setState */(newState) => {
if (!this._connected) {
return;
}
// default values if not specified.
this.grouping = newState.test as string || '';
this.leftDigest = newState.left as string || '';
this.rightDigest = newState.right as string || '';
this.changeListID = newState.changelist_id as string || '';
this.crs = newState.crs as string || '';
this.fetch();
this._render();
},
);
}
connectedCallback(): void {
super.connectedCallback();
this._render();
}
private fetch() {
// Kill any outstanding requests
this._fetchController?.abort();
// Make a fresh abort controller for each set of fetches.
// They cannot be re-used once aborted.
this._fetchController = new AbortController();
const extra = {
signal: this._fetchController.signal,
};
sendBeginTask(this);
const urlBase = '/json/v2/diff';
const url = `${urlBase}?test=${encodeURIComponent(this.grouping)}`
+ `&left=${encodeURIComponent(this.leftDigest)}`
+ `&right=${encodeURIComponent(this.rightDigest)}`
+ `&changelist_id=${this.changeListID}&crs=${this.crs}`;
fetch(url, extra)
.then(jsonOrThrow)
.then((obj: DigestComparison) => {
this.leftDetails = obj.left;
this.rightDetails = obj.right;
this.didInitialLoad = true;
this._render();
sendEndTask(this);
})
.catch((e) => {
this.leftDetails = null;
this.rightDetails = null;
this.didInitialLoad = false;
this._render();
sendFetchError(this, e, 'diff-details');
});
}
}
define('diff-page-sk', DiffPageSk);