go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/build/legacy/build_page/overview_tab/overview_tab.tsx (about) 1 // Copyright 2023 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 styled from '@emotion/styled'; 16 import { observer } from 'mobx-react-lite'; 17 import { useState } from 'react'; 18 19 import { RecoverableErrorBoundary } from '@/common/components/error_handling'; 20 import { useStore } from '@/common/store'; 21 import { useTabId } from '@/generic_libs/components/routed_tabs'; 22 23 import { ActionsSection, Dialog } from './actions_section'; 24 import { AlertsSection } from './alerts_section'; 25 import { BuildLogSection } from './build_log_section'; 26 import { BuildPackagesInfoSection } from './build_packages_info_section'; 27 import { BuilderInfoSection } from './builder_info_section'; 28 import { CancelBuildDialog } from './cancel_build_dialog'; 29 import { ExperimentsSection } from './experiments_section'; 30 import { FailedTestSection } from './failed_tests_section'; 31 import { InfraSection } from './infra_section'; 32 import { InputSection } from './input_section'; 33 import { OutputSection } from './output_section'; 34 import { PropertiesSection } from './properties_section'; 35 import { RetryBuildDialog } from './retry_build_dialog'; 36 import { StepsSection } from './steps_section'; 37 import { SummarySection } from './summary_section'; 38 import { TagsSection } from './tags_section'; 39 import { TimingSection } from './timing_section'; 40 41 const ContainerDiv = styled.div({ 42 margin: '10px 16px', 43 '@media screen and (min-width: 1300px)': { 44 display: 'grid', 45 gridTemplateColumns: '1fr 20px 40vw', 46 }, 47 '& > h3': { 48 marginBlock: '15px 10px', 49 }, 50 }); 51 52 const FirstColumn = styled.div({ 53 overflow: 'hidden', 54 gridColumn: 1, 55 }); 56 57 const SecondColumn = styled.div({ 58 overflow: 'hidden', 59 gridColumn: 3, 60 }); 61 62 export const OverviewTab = observer(() => { 63 const store = useStore(); 64 65 const [activeDialog, setActiveDialog] = useState(Dialog.None); 66 67 return ( 68 <> 69 <RetryBuildDialog 70 open={activeDialog === Dialog.RetryBuild} 71 onClose={() => setActiveDialog(Dialog.None)} 72 /> 73 <CancelBuildDialog 74 open={activeDialog === Dialog.CancelBuild} 75 onClose={() => setActiveDialog(Dialog.None)} 76 /> 77 <ContainerDiv> 78 <FirstColumn> 79 <AlertsSection /> 80 <SummarySection /> 81 <FailedTestSection /> 82 <StepsSection /> 83 </FirstColumn> 84 <SecondColumn> 85 {store.buildPage.build?.data.builderInfo?.description && ( 86 <BuilderInfoSection 87 descriptionHtml={ 88 store.buildPage.build.data.builderInfo.description 89 } 90 /> 91 )} 92 <InputSection /> 93 <OutputSection /> 94 <InfraSection /> 95 <TimingSection /> 96 <BuildLogSection /> 97 <ActionsSection openDialog={(dialog) => setActiveDialog(dialog)} /> 98 <TagsSection /> 99 <ExperimentsSection /> 100 <PropertiesSection /> 101 <BuildPackagesInfoSection /> 102 </SecondColumn> 103 </ContainerDiv> 104 </> 105 ); 106 }); 107 108 export function Component() { 109 useTabId('overview'); 110 111 return ( 112 // See the documentation for `<LoginPage />` for why we handle error this 113 // way. 114 <RecoverableErrorBoundary key="overview"> 115 <OverviewTab /> 116 </RecoverableErrorBoundary> 117 ); 118 }