diff --git a/pkg/ui/react-app/src/thanos/pages/blocks/BlockFilterCompaction.tsx b/pkg/ui/react-app/src/thanos/pages/blocks/BlockFilterCompaction.tsx new file mode 100644 index 0000000000..ebed6357aa --- /dev/null +++ b/pkg/ui/react-app/src/thanos/pages/blocks/BlockFilterCompaction.tsx @@ -0,0 +1,34 @@ +import React, { FC, ChangeEvent } from 'react'; +import Checkbox from '../../../components/Checkbox'; +import { Input } from 'reactstrap'; +import styles from './blocks.module.css'; + +interface BlockFilterCompactionProps { + id: string; + defaultChecked: boolean; + onChangeCheckbox: ({ target }: ChangeEvent) => void; + onChangeInput: ({ target }: ChangeEvent) => void; + defaultValue: string; +} + +export const BlockFilterCompaction: FC = ({ + id, + defaultChecked, + onChangeCheckbox, + onChangeInput, + defaultValue, +}) => { + return ( +
+ +

Filter by compaction level

+ +
+ ); +}; diff --git a/pkg/ui/react-app/src/thanos/pages/blocks/Blocks.tsx b/pkg/ui/react-app/src/thanos/pages/blocks/Blocks.tsx index 5c43a2cdb4..033fc4352e 100644 --- a/pkg/ui/react-app/src/thanos/pages/blocks/Blocks.tsx +++ b/pkg/ui/react-app/src/thanos/pages/blocks/Blocks.tsx @@ -9,6 +9,7 @@ import { Block } from './block'; import { SourceView } from './SourceView'; import { BlockDetails } from './BlockDetails'; import { BlockSearchInput } from './BlockSearchInput'; +import { BlockFilterCompaction } from './BlockFilterCompaction'; import { sortBlocks } from './helpers'; import styles from './blocks.module.css'; import TimeRange from './TimeRange'; @@ -24,6 +25,10 @@ export interface BlockListProps { export const BlocksContent: FC<{ data: BlockListProps }> = ({ data }) => { const [selectedBlock, selectBlock] = useState(); const [searchState, setSearchState] = useState(''); + const [filterCompaction, setFilterCompaction] = useState(false); + const [compactionLevel, setCompactionLevel] = useState(0); + const [compactionLevelInput, setCompactionLevelInput] = useState('0'); + const { blocks, label, err } = data; const [gridMinTime, gridMaxTime] = useMemo(() => { @@ -95,6 +100,25 @@ export const BlocksContent: FC<{ data: BlockListProps }> = ({ data }) => { > Enable finding overlapping blocks + { + setFilterCompaction(target.checked); + if (target.checked) { + setCompactionLevel(parseInt(compactionLevelInput)); + } else { + setCompactionLevel(0); + } + }} + onChangeInput={({ target }: ChangeEvent): void => { + if (filterCompaction) { + setCompactionLevel(parseInt(target.value)); + } + setCompactionLevelInput(target.value); + }} + defaultValue={compactionLevelInput} + />
@@ -107,6 +131,7 @@ export const BlocksContent: FC<{ data: BlockListProps }> = ({ data }) => { gridMinTime={viewMinTime} gridMaxTime={viewMaxTime} blockSearch={blockSearch} + compactionLevel={compactionLevel} /> ))}
diff --git a/pkg/ui/react-app/src/thanos/pages/blocks/SourceView.test.tsx b/pkg/ui/react-app/src/thanos/pages/blocks/SourceView.test.tsx index 5ce121d571..46ec451562 100644 --- a/pkg/ui/react-app/src/thanos/pages/blocks/SourceView.test.tsx +++ b/pkg/ui/react-app/src/thanos/pages/blocks/SourceView.test.tsx @@ -17,6 +17,7 @@ describe('Blocks SourceView', () => { gridMinTime: 1596096000000, gridMaxTime: 1595108031471, blockSearch: '', + compactionLevel: 0, }; const sourceView = mount(); diff --git a/pkg/ui/react-app/src/thanos/pages/blocks/SourceView.tsx b/pkg/ui/react-app/src/thanos/pages/blocks/SourceView.tsx index 54ab4314e7..c7127b6b0a 100644 --- a/pkg/ui/react-app/src/thanos/pages/blocks/SourceView.tsx +++ b/pkg/ui/react-app/src/thanos/pages/blocks/SourceView.tsx @@ -2,7 +2,7 @@ import React, { FC } from 'react'; import { Block, BlocksPool } from './block'; import { BlockSpan } from './BlockSpan'; import styles from './blocks.module.css'; -import { getBlockByUlid } from './helpers'; +import { getBlockByUlid, getBlocksByCompactionLevel } from './helpers'; export const BlocksRow: FC<{ blocks: Block[]; @@ -10,8 +10,10 @@ export const BlocksRow: FC<{ gridMaxTime: number; selectBlock: React.Dispatch>; blockSearch: string; -}> = ({ blocks, gridMinTime, gridMaxTime, selectBlock, blockSearch }) => { - const blockSearchValue = getBlockByUlid(blocks, blockSearch); + compactionLevel: number; +}> = ({ blocks, gridMinTime, gridMaxTime, selectBlock, blockSearch, compactionLevel }) => { + let blockSearchValue = getBlockByUlid(blocks, blockSearch); + blockSearchValue = getBlocksByCompactionLevel(blockSearchValue, compactionLevel); return (
@@ -29,9 +31,18 @@ export interface SourceViewProps { gridMaxTime: number; selectBlock: React.Dispatch>; blockSearch: string; + compactionLevel: number; } -export const SourceView: FC = ({ data, title, gridMaxTime, gridMinTime, selectBlock, blockSearch }) => { +export const SourceView: FC = ({ + data, + title, + gridMaxTime, + gridMinTime, + selectBlock, + blockSearch, + compactionLevel, +}) => { return ( <>
@@ -49,6 +60,7 @@ export const SourceView: FC = ({ data, title, gridMaxTime, grid gridMaxTime={gridMaxTime} gridMinTime={gridMinTime} blockSearch={blockSearch} + compactionLevel={compactionLevel} /> ))} diff --git a/pkg/ui/react-app/src/thanos/pages/blocks/blocks.module.css b/pkg/ui/react-app/src/thanos/pages/blocks/blocks.module.css index 8a704e4bb8..896d3ac62f 100644 --- a/pkg/ui/react-app/src/thanos/pages/blocks/blocks.module.css +++ b/pkg/ui/react-app/src/thanos/pages/blocks/blocks.module.css @@ -194,3 +194,9 @@ .blockInput { margin-bottom: 12px; } + +.blockFilter { + display: flex; + flex-direction: row; + align-items: center; +} diff --git a/pkg/ui/react-app/src/thanos/pages/blocks/helpers.ts b/pkg/ui/react-app/src/thanos/pages/blocks/helpers.ts index 8b8cc35a78..5e8c353d05 100644 --- a/pkg/ui/react-app/src/thanos/pages/blocks/helpers.ts +++ b/pkg/ui/react-app/src/thanos/pages/blocks/helpers.ts @@ -137,3 +137,12 @@ export const getBlockByUlid = (blocks: Block[], ulid: string): Block[] => { const blockResult = blocks.filter((block, index) => resultIndex.includes(index)); return blockResult; }; + +export const getBlocksByCompactionLevel = (blocks: Block[], compactionLevel: number): Block[] => { + if (compactionLevel === 0 || Number.isNaN(compactionLevel)) { + return blocks; + } + + const blockResult = blocks.filter((block) => block.compaction.level === compactionLevel); + return blockResult; +};