| import { define } from 'elements-sk/define'; |
| import { html } from 'lit-html'; |
| import { ElementSk } from '../../../infra-sk/modules/ElementSk'; |
| |
| import 'elements-sk/radio-sk'; |
| import 'elements-sk/styles/select'; |
| import 'elements-sk/icon/find-in-page-icon-sk'; |
| |
| const patchSet = (ps, ele) => html` |
| <option ?selected=${ele.ps_order === ps.order}>PS ${ps.order}</option> |
| `; |
| |
| const tryJob = (tj) => html` |
| <div class=tryjob title=${tj.name}> |
| <a href=${tj.url} target=_blank rel=noopener> |
| ${limitString(tj.name, 60)} |
| </a> |
| </div> |
| `; |
| |
| const template = (ele) => { |
| if (!ele._summary) { |
| return ''; |
| } |
| const cl = ele._summary.cl; |
| const ps = ele._selectedPS(); |
| return html` |
| <div class=info> |
| <span class=title>${cl.system} issue:</span> |
| <a href=${cl.url} target=_blank rel=noopener> |
| ${limitString(cl.subject, 48)} |
| </a> |
| |
| <span>${limitString(cl.owner, 32)}</span> |
| |
| <a href="/triagelog?issue=${cl.id}&system=${cl.system}"> |
| <find-in-page-icon-sk></find-in-page-icon-sk>Triagelog |
| </a> |
| </div> |
| |
| <div class=inputs> |
| <select @input=${ele._onSelectPS}> |
| ${ele._summary.patch_sets.map((ps) => patchSet(ps, ele))} |
| </select> |
| <span class=spacer></span> |
| <div class=radiogroup> |
| <radio-sk label="exclude results from master" name=include_master |
| ?checked=${!ele.include_master} @change=${() => ele._masterChange(false)}></radio-sk> |
| <radio-sk label="show all results" name=include_master |
| ?checked=${ele.include_master} @change=${() => ele._masterChange(true)}></radio-sk> |
| </div> |
| </div> |
| |
| <div class=tryjob-container> |
| ${ps.try_jobs.map((tj) => tryJob(tj))} |
| </div> |
| `; |
| }; |
| |
| function limitString(s, maxLength) { |
| if (s.length <= maxLength) { |
| return s; |
| } |
| return `${s.substring(0, maxLength - 3)}...`; |
| } |
| |
| define('changelist-controls-sk', class extends ElementSk { |
| constructor() { |
| super(template); |
| this._psOrder = 0; // default to use the last PatchSet. |
| this._includeMaser = false; |
| this._summary = null; |
| } |
| |
| connectedCallback() { |
| super.connectedCallback(); |
| this._render(); |
| } |
| |
| /** @prop ps_order {int} the order of the PatchSet currently being shown. */ |
| get ps_order() { return this._psOrder; } |
| |
| set ps_order(val) { |
| this._psOrder = +val; |
| this._render(); |
| } |
| |
| /** @prop include_master {bool} if we should show results that are also |
| * on master, as opposed to those that are exclusive . */ |
| get include_master() { return this._includeMaser; } |
| |
| set include_master(val) { |
| this._includeMaser = val !== 'false' && !!val; |
| this._render(); |
| } |
| |
| _masterChange(newVal) { |
| this.include_master = newVal; // calls _render() |
| this._sendUpdateEvent(); |
| } |
| |
| _onSelectPS(e) { |
| const xps = this._summary.patch_sets; |
| const ps = xps[e.target.selectedIndex]; |
| this.ps_order = ps.order; // calls _render() |
| this._sendUpdateEvent(); |
| } |
| |
| /* _selectedPS returns the PatchSet object which matches _psOrder. if _psOrder is 0 |
| (match latest), _psOrder will be updated to whatever the latest order is. |
| */ |
| _selectedPS() { |
| if (!this._summary || !this._summary.patch_sets || !this._summary.patch_sets.length) { |
| return null; |
| } |
| const xps = this._summary.patch_sets; |
| if (!this._psOrder) { |
| const o = xps[xps.length - 1]; |
| this._psOrder = o.order; |
| return o; |
| } |
| for (let i = 0; i < xps.length; i++) { |
| if (xps[i].order === this._psOrder) { |
| return xps[i]; |
| } |
| } |
| return null; |
| } |
| |
| _sendUpdateEvent() { |
| this.dispatchEvent(new CustomEvent('cl-control-change', { |
| detail: { |
| include_master: this.include_master, |
| ps_order: this.ps_order, |
| }, |
| bubbles: true, |
| })); |
| } |
| |
| /** setSummary sets the frontend.ChangeListSummary for this element to display. */ |
| setSummary(sum) { |
| this._summary = sum; |
| this._render(); |
| } |
| }); |