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  }