src/pages/Home/Sidebar/index.tsx (148 lines of code) (raw):

import React, { useContext } from 'react'; import { Scrollbars } from 'react-custom-scrollbars-2'; import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; import { isDefaultParams } from '@pages/Home/Home.utils'; import SidebarStatusSelection from '@pages/Home/Sidebar/SidebarStatusSelection'; import { TagParameterList } from '@pages/Home/Sidebar/SidebarTags'; import SidebarTimerangeSelection from '@pages/Home/Sidebar/SidebarTimerangeSelection'; import Button from '@components/Button'; import FilterInput from '@components/FilterInput'; import DropdownField from '@components/Form/Dropdown'; import { Text } from '@components/Text'; import { TimezoneContext } from '@components/TimezoneProvider'; import FEATURE_FLAGS from '@utils/FEATURE'; import { getHeaderSizeRem } from '@utils/style'; // // Typedef // type Props = { // Update queryparameter handleParamChange: (key: string, value: string) => void; // Update parameter that is type of list updateListValue: (key: string, value: string) => void; // Current active parameters params: Record<string, string>; // Reset all params resetAllFilters: () => void; }; // // Component // const HomeSidebar: React.FC<Props> = ({ handleParamChange, updateListValue, params, resetAllFilters }) => { const { t } = useTranslation(); const { timezone } = useContext(TimezoneContext); return ( <Sidebar className="sidebar"> {/* Add sidebar size to be 100% viewheight - (header size + 1 rem for padding) */} <StyledScrollbars autoHide> <SidebarContent> {FEATURE_FLAGS.RUN_GROUPS && ( <SidebarSectionWrapper> <DropdownField label={t('filters.group-by') ?? ''} value={params._group || ''} onChange={(e) => e && handleParamChange('_group', e.target.value)} options={[ ['', t('fields.group.none')], ['flow_id', t('fields.group.flow')], ['user', t('fields.group.user')], ]} /> </SidebarSectionWrapper> )} <SidebarStatusSelection updateField={updateListValue} status={params.status} /> <SidebarTimerangeSelection updateField={handleParamChange} params={params} /> <SidebarSectionWrapper data-testid="filter-input-flow"> <FilterInput onSubmit={(v) => updateListValue('flow_id', v)} sectionLabel={t('fields.flow')} autoCompleteSettings={{ url: '/flows/autocomplete', params: (str) => ({ 'flow_id:co': str }), }} /> <TagParameterList paramKey="flow_id" updateList={updateListValue} value={params.flow_id} /> </SidebarSectionWrapper> <SidebarSectionWrapper data-testid="filter-input-project"> <FilterInput onSubmit={(v) => updateListValue('_tags', v.startsWith('project:') ? v : `project:${v}`)} sectionLabel={t('fields.project')} autoCompleteSettings={{ url: '/tags/autocomplete', params: (input: string) => ({ 'tag:re': `project:.*${input}.*` }), }} /> <TagParameterList paramKey="_tags" mapList={(xs) => xs.filter((x) => x.startsWith('project:')).map((x) => x.substr('project:'.length))} mapValue={(x) => `project:${x}`} updateList={updateListValue} value={params._tags} /> </SidebarSectionWrapper> <SidebarSectionWrapper data-testid="filter-input-branch"> <FilterInput onSubmit={(v) => updateListValue('_tags', v.startsWith('project_branch:') ? v : `project_branch:${v}`)} sectionLabel={t('fields.branch')} autoCompleteSettings={{ url: '/tags/autocomplete', params: (input: string) => ({ 'tag:re': `project_branch:.*${input}.*` }), }} /> <TagParameterList paramKey="_tags" mapList={(xs) => xs.filter((x) => x.startsWith('project_branch:')).map((x) => x.substr('project_branch:'.length)) } mapValue={(x) => `project_branch:${x}`} updateList={updateListValue} value={params._tags} /> </SidebarSectionWrapper> <SidebarSectionWrapper data-testid="filter-input-user"> <FilterInput onSubmit={(v) => updateListValue('user', omitFromString('user', v))} sectionLabel={t('fields.user')} autoCompleteSettings={{ url: '/tags/autocomplete', params: (input: string) => ({ 'tag:re': `user:.*${input}.*` }), }} /> <TagParameterList paramKey="user" updateList={updateListValue} value={params.user ? params.user.replace('null', 'None') : ''} /> </SidebarSectionWrapper> <SidebarSectionWrapper data-testid="filter-input-tag"> <FilterInput onSubmit={(v) => updateListValue('_tags', v)} sectionLabel={t('fields.tag')} autoCompleteSettings={{ url: '/tags/autocomplete', params: (input: string) => ({ 'tag:co': input }), }} /> <TagParameterList paramKey="_tags" mapList={(xs) => xs.filter((x) => !/^project:|project_branch:/.test(x))} updateList={updateListValue} value={params._tags} /> </SidebarSectionWrapper> {!isDefaultParams(params, true, timezone) && ( <div> <ButtonResetAll size="sm" onClick={() => resetAllFilters()} disabled={isDefaultParams(params, true, timezone)} > <Text>{t('filters.reset-all')}</Text> </ButtonResetAll> </div> )} </SidebarContent> </StyledScrollbars> </Sidebar> ); }; // // Utils // function omitFromString(partToOmit: string, str: string): string { return str.startsWith(partToOmit + ':') ? str.split(':').slice(1, str.split(':').length).join('') : str; } // // Styles // const ButtonResetAll = styled(Button)` color: var(--reset-button-color); border-color: var(--reset-button-border-color); height: var(--reset-button-height); font-weight: var(--reset-button-font-weight); width: 100%; span { display: inline-block; width: 100%; } `; const Sidebar = styled.div` position: fixed; width: var(--sidebar-width-md); @media (max-width: var(--layout-breakpoint-sm)) { width: var(--sidebar-width-sm); } top: var(--layout-application-bar-height); font-size: var(--font-size-primary); padding-top: 6px; `; const SidebarContent = styled.div` width: var(--sidebar-width-md); @media (max-width: var(--layout-breakpoint-sm)) { width: var(--sidebar-width-sm); } padding-top: 0.5rem; padding-left: 0.25rem; `; const StyledScrollbars = styled(Scrollbars)` height: calc(100vh - ${getHeaderSizeRem() + 1}rem) !important; width: calc(var(--sidebar-width-md) + 1rem) !important; @media (max-width: var(--layout-breakpoint-sm)) { width: calc(var(--sidebar-width-sm) + 1rem) !important; } padding-top: 0.25rem; `; export const SidebarSectionWrapper = styled.div` margin: var(--sidebar-section-margin); `; export default HomeSidebar;