go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/ui/src/common/layouts/side_bar/pages.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 AccessTimeIcon from '@mui/icons-material/AccessTime';
    16  import BuildIcon from '@mui/icons-material/Build';
    17  import EngineeringIcon from '@mui/icons-material/Engineering';
    18  import GrainTwoToneIcon from '@mui/icons-material/GrainTwoTone';
    19  import HouseIcon from '@mui/icons-material/House';
    20  import LineAxisIcon from '@mui/icons-material/LineAxis';
    21  import LineStyleIcon from '@mui/icons-material/LineStyle';
    22  import ScheduleIcon from '@mui/icons-material/Schedule';
    23  import SearchIcon from '@mui/icons-material/Search';
    24  import SpeedIcon from '@mui/icons-material/Speed';
    25  import SpokeIcon from '@mui/icons-material/Spoke';
    26  import TableViewIcon from '@mui/icons-material/TableView';
    27  import VisibilityIcon from '@mui/icons-material/Visibility';
    28  import React from 'react';
    29  
    30  import { UiPage } from '@/common/constants/view';
    31  import { getProjectURLPath } from '@/common/tools/url_utils';
    32  
    33  export interface SidebarPage {
    34    readonly page: UiPage;
    35    readonly url: string;
    36    readonly icon: React.ReactNode;
    37    readonly external?: boolean;
    38  }
    39  
    40  export interface SidebarSection {
    41    readonly title: 'Builds' | 'Tests' | 'Monitoring' | 'Releases';
    42    readonly pages: SidebarPage[];
    43  }
    44  
    45  export function generateSidebarSections(project: string | undefined) {
    46    return (
    47      [
    48        generateBuildsSection(project),
    49        generateTestsSection(project),
    50        generateMonitoringSection(project),
    51        generateReleasesSection(project),
    52      ]
    53        // Remove empty sections.
    54        .filter((sec) => sec.pages.length)
    55    );
    56  }
    57  
    58  function generateBuildsSection(project: string | undefined): SidebarSection {
    59    const pages: SidebarPage[] = [];
    60    pages.push({
    61      page: UiPage.BuilderSearch,
    62      url: '/ui/builder-search',
    63      icon: <SearchIcon />,
    64    });
    65    if (project) {
    66      pages.push({
    67        page: UiPage.Builders,
    68        url: `/ui/p/${project}/builders`,
    69        icon: <BuildIcon />,
    70      });
    71  
    72      pages.push({
    73        page: UiPage.BuilderGroups,
    74        url: getProjectURLPath(project),
    75        icon: <TableViewIcon />,
    76      });
    77  
    78      pages.push({
    79        page: UiPage.Scheduler,
    80        url: `https://luci-scheduler.appspot.com/jobs/${project}`,
    81        icon: <ScheduleIcon />,
    82        external: true,
    83      });
    84  
    85      if (project === 'chromium') {
    86        pages.push({
    87          page: UiPage.Bisection,
    88          url: `/ui/p/${project}/bisection`,
    89          icon: <GrainTwoToneIcon />,
    90        });
    91      }
    92    }
    93  
    94    return {
    95      title: 'Builds',
    96      pages,
    97    };
    98  }
    99  
   100  function generateTestsSection(project: string | undefined): SidebarSection {
   101    const pages: SidebarPage[] = [];
   102  
   103    if (project) {
   104      pages.push(
   105        {
   106          page: UiPage.TestHistory,
   107          url: `/ui/p/${project}/test-search`,
   108          icon: <AccessTimeIcon />,
   109        },
   110        {
   111          page: UiPage.FailureClusters,
   112          url: `https://${SETTINGS.luciAnalysis.host}/p/${project}/clusters`,
   113          icon: <SpokeIcon />,
   114          external: true,
   115        },
   116      );
   117    }
   118  
   119    // Add ChromeOS specific Test tools.
   120    if (project?.startsWith('chromeos')) {
   121      pages.push(
   122        {
   123          page: UiPage.Testhaus,
   124          url: `https://tests.chromeos.goog`,
   125          icon: <HouseIcon />,
   126          external: true,
   127        },
   128        {
   129          page: UiPage.Crosbolt,
   130          url: `https://healthmon.chromeos.goog/time_series`,
   131          icon: <SpeedIcon />,
   132          external: true,
   133        },
   134      );
   135    }
   136  
   137    return {
   138      title: 'Tests',
   139      pages,
   140    };
   141  }
   142  
   143  function generateMonitoringSection(
   144    project: string | undefined,
   145  ): SidebarSection {
   146    const pages: SidebarPage[] = [];
   147  
   148    const somProject = getSomProject(project);
   149    if (somProject) {
   150      pages.push({
   151        page: UiPage.SoM,
   152        url: `https://sheriff-o-matic.appspot.com/${somProject}`,
   153        icon: <EngineeringIcon />,
   154        external: true,
   155      });
   156    }
   157  
   158    if (project?.startsWith('chromeos')) {
   159      pages.push({
   160        page: UiPage.CQStatus,
   161        url: `http://go/cros-cq-status`,
   162        icon: <LineAxisIcon />,
   163        external: true,
   164      });
   165    }
   166  
   167    return {
   168      title: 'Monitoring',
   169      pages,
   170    };
   171  }
   172  
   173  export function getSomProject(project: string | undefined): string | null {
   174    if (!project) {
   175      return null;
   176    }
   177  
   178    if (project.startsWith('chromeos')) {
   179      return 'chromeos';
   180    }
   181    if (project.startsWith('chromium') || project.startsWith('chrome')) {
   182      return 'chromium';
   183    }
   184    if (project === 'fuchsia' || project === 'turquoise') {
   185      return 'fuchsia';
   186    }
   187  
   188    return null;
   189  }
   190  
   191  function generateReleasesSection(project: string | undefined): SidebarSection {
   192    const pages: SidebarPage[] = [];
   193  
   194    if (project?.startsWith('chromeos')) {
   195      pages.push({
   196        page: UiPage.Goldeneye,
   197        url: 'https://cros-goldeneye.corp.google.com/',
   198        icon: <VisibilityIcon />,
   199        external: true,
   200      });
   201    } else if (project?.startsWith('chrome') || project?.startsWith('chromium')) {
   202      pages.push({
   203        page: UiPage.ChromiumDash,
   204        url: 'https://chromiumdash.appspot.com/',
   205        icon: <LineStyleIcon />,
   206        external: true,
   207      });
   208    }
   209  
   210    return {
   211      title: 'Releases',
   212      pages,
   213    };
   214  }