blob: 8f01e8dfbc4c99748a5b977baf45f8115e8b9f5a [file] [log] [blame]
/**
* @module modules/domain-picker-sk
* @description <h2><code>domain-picker-sk</code></h2>
*
* Allows picking either a date range for commits, or for
* picking a number of commits to show before a selected
* date.
*
* @attr {string} force_request_type - A value of 'dense' or 'range' will
* force the corresponding request_type to be always set.
*
*/
import { define } from 'elements-sk/define';
import { html } from 'lit-html';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import { RequestType } from '../json';
import 'elements-sk/radio-sk';
import 'elements-sk/styles/buttons';
import '../calendar-input-sk';
// Types of domain ranges we can choose.
// TODO(jcgregorio) Make the underlying dataframe.RequestType a string.
const RANGE = 0; // Specify a begin and end time.
const DENSE = 1; // Specify an end time and the number of commits with data.
type ForceRequestType = 'range' | 'dense' | '';
const toDate = (seconds: number) => new Date(seconds * 1000);
const toForceRequestType = (s: string | null): ForceRequestType => {
if (s === 'range') {
return 'range';
} if (s === 'dense') {
return 'dense';
}
return '';
};
/** The state of the DomainPickerSk control. */
export interface DomainPickerState {
/** Beginning of time range in Unix timestamp seconds. */
begin: number;
/** End of time range in Unix timestamp seconds. */
end: number;
/**
* If RequestType is REQUEST_COMPACT (1), then this value is the number of
* commits to show before End, and the value of Begin is ignored.
*/
num_commits: number;
request_type: RequestType;
}
export class DomainPickerSk extends ElementSk {
private _state: DomainPickerState;
constructor() {
super(DomainPickerSk.template);
const now = Date.now();
this._state = {
begin: Math.floor(now / 1000 - 24 * 60 * 60),
end: Math.floor(now / 1000),
num_commits: 50,
request_type: RANGE,
};
}
private static template = (ele: DomainPickerSk) => html`
${DomainPickerSk._showRadio(ele)}
<div class="ranges">
${DomainPickerSk._requestType(ele)}
<label>
<span class="prefix">End:</span>
<calendar-input-sk
@input=${ele.endChange}
.displayDate=${toDate(ele._state.end)}
></calendar-input-sk>
</label>
</div>
`;
private static _showRadio = (ele: DomainPickerSk) => {
if (!ele.force_request_type) {
return html`
<radio-sk
@change=${ele.typeRange}
?checked=${ele._state.request_type === RANGE}
label="Date Range"
name="daterange"
></radio-sk>
<radio-sk
@change=${ele.typeDense}
?checked=${ele._state.request_type === DENSE}
label="Dense"
name="daterange"
></radio-sk>
`;
}
return html``;
};
private static _requestType = (ele: DomainPickerSk) => {
if (ele._state.request_type === RANGE) {
return html`
<p>Display all points in the date range.</p>
<label>
<span class="prefix">Begin:</span>
<calendar-input-sk
@input=${ele.beginChange}
.displayDate=${toDate(ele._state.begin)}
></calendar-input-sk>
</label>
`;
}
return html`
<p>Display only the points that have data before the date.</p>
<label>
<span class="prefix">Points</span>
<input
@change=${ele.numChanged}
type="number"
.value="${ele._state.num_commits}"
min="1"
max="5000"
list="defaultNumbers"
title="The number of points."
/>
</label>
<datalist id="defaultNumbers">
<option value="50"></option>
<option value="100"></option>
<option value="250"></option>
<option value="500"></option>
</datalist>
`;
};
connectedCallback(): void {
super.connectedCallback();
this._upgradeProperty('state');
this._upgradeProperty('force_request_type');
this.render();
}
attributeChangedCallback(): void {
this.render();
}
render(): void {
if (this.force_request_type === 'dense') {
this._state.request_type = DENSE;
} else if (this.force_request_type === 'range') {
this._state.request_type = RANGE;
}
super._render();
}
private typeRange() {
this._state.request_type = RANGE;
this.render();
}
private typeDense() {
this._state.request_type = DENSE;
this.render();
}
private beginChange(e: CustomEvent<Date>) {
this._state.begin = Math.floor(e.detail.valueOf() / 1000);
this.render();
}
private endChange(e: CustomEvent<Date>) {
this._state.end = Math.floor(e.detail.valueOf() / 1000);
this.render();
}
private numChanged(e: MouseEvent) {
this._state.num_commits = +(e.target! as HTMLInputElement).value;
this.render();
}
static get observedAttributes(): string[] {
return ['force_request_type'];
}
get state(): DomainPickerState {
return this._state;
}
set state(val: DomainPickerState) {
if (!val) {
return;
}
this._state = {
begin: val.begin,
end: val.end,
num_commits: val.num_commits,
request_type: val.request_type,
};
this.render();
}
/** A value of DENSE or RANGE will force the corresponding request_type to be always set.
*/
get force_request_type(): ForceRequestType {
return toForceRequestType(this.getAttribute('force_request_type'));
}
set force_request_type(val: ForceRequestType) {
this.setAttribute('force_request_type', toForceRequestType(val));
}
}
define('domain-picker-sk', DomainPickerSk);