| /** |
| * @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); |