go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/build/legacy/build_page/steps_tab/steps_tab.tsx (about) 1 // Copyright 2020 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 import '@material/mwc-button'; 16 import { css, html } from 'lit'; 17 import { customElement } from 'lit/decorators.js'; 18 import { makeObservable, observable } from 'mobx'; 19 20 import '@/generic_libs/components/hotkey'; 21 import './step_display_config'; 22 import './step_list'; 23 import { RecoverableErrorBoundary } from '@/common/components/error_handling'; 24 import { consumeStore, StoreInstance } from '@/common/store'; 25 import { commonStyles } from '@/common/styles/stylesheets'; 26 import { MobxExtLitElement } from '@/generic_libs/components/lit_mobx_ext'; 27 import { useTabId } from '@/generic_libs/components/routed_tabs'; 28 import { 29 errorHandler, 30 forwardWithoutMsg, 31 reportRenderError, 32 } from '@/generic_libs/tools/error_handler'; 33 import { consumer } from '@/generic_libs/tools/lit_context'; 34 35 import { BuildPageStepListElement } from './step_list'; 36 37 @customElement('milo-steps-tab') 38 @errorHandler(forwardWithoutMsg) 39 @consumer 40 export class StepsTabElement extends MobxExtLitElement { 41 @observable.ref 42 @consumeStore() 43 store!: StoreInstance; 44 45 private allStepsWereExpanded = false; 46 private toggleAllSteps(expand: boolean) { 47 this.allStepsWereExpanded = expand; 48 this.shadowRoot!.querySelector<BuildPageStepListElement>( 49 'milo-bp-step-list', 50 )!.toggleAllSteps(expand); 51 } 52 private readonly toggleAllStepsByHotkey = () => 53 this.toggleAllSteps(!this.allStepsWereExpanded); 54 55 constructor() { 56 super(); 57 makeObservable(this); 58 } 59 60 protected render = reportRenderError(this, () => { 61 return html` 62 <div id="header"> 63 <milo-bp-step-display-config></milo-bp-step-display-config> 64 <milo-hotkey 65 .key=${'x'} 66 .handler=${this.toggleAllStepsByHotkey} 67 title="press x to expand/collapse all entries" 68 > 69 <mwc-button 70 class="action-button" 71 dense 72 unelevated 73 @click=${() => this.toggleAllSteps(true)} 74 > 75 Expand All 76 </mwc-button> 77 <mwc-button 78 class="action-button" 79 dense 80 unelevated 81 @click=${() => this.toggleAllSteps(false)} 82 > 83 Collapse All 84 </mwc-button> 85 </milo-hotkey> 86 </div> 87 <milo-bp-step-list id="main" tabindex="0"></milo-bp-step-list> 88 `; 89 }); 90 91 static styles = [ 92 commonStyles, 93 css` 94 #header { 95 display: grid; 96 grid-template-columns: 1fr auto; 97 grid-gap: 5px; 98 height: 30px; 99 padding: 5px 10px 3px 10px; 100 position: sticky; 101 top: 0px; 102 background: white; 103 border-bottom: 1px solid var(--divider-color); 104 } 105 106 mwc-button { 107 margin-top: 1px; 108 width: var(--expand-button-width); 109 } 110 111 milo-bp-step-list { 112 padding-top: 5px; 113 padding-left: 10px; 114 outline: none; 115 } 116 `, 117 ]; 118 } 119 120 declare global { 121 // eslint-disable-next-line @typescript-eslint/no-namespace 122 namespace JSX { 123 interface IntrinsicElements { 124 'milo-steps-tab': Record<string, never>; 125 } 126 } 127 } 128 129 export function StepsTab() { 130 return <milo-steps-tab />; 131 } 132 133 export function Component() { 134 useTabId('steps'); 135 136 return ( 137 // See the documentation for `<LoginPage />` for why we handle error this 138 // way. 139 <RecoverableErrorBoundary key="steps"> 140 <StepsTab /> 141 </RecoverableErrorBoundary> 142 ); 143 }