1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as React from 'react';
import { clsx } from '@web/uiUtils';
import { formatUrl, hashStringToInt } from './utils';
import { navigate, ProjectLink, useSearchParams } from './links';
import { filterWithQuery } from './filter';
import './labels.css';
export const Label: React.FC<{
label: string,
trimAtSymbolPrefix?: boolean,
href?: string,
onClick?: (e: React.MouseEvent, label: string) => void,
colorIndex?: number,
}> = ({ label, href, onClick, colorIndex, trimAtSymbolPrefix }) => {
const baseLabel = <span className={clsx('label', 'label-color-' + (colorIndex !== undefined ? colorIndex : hashStringToInt(label)))} onClick={onClick ? e => onClick(e, label) : undefined}>
{trimAtSymbolPrefix && label.startsWith('@') ? label.slice(1) : label}
</span>;
return href
? <a className='label-anchor' href={formatUrl(href)}>{baseLabel}</a>
: baseLabel;
};
export const ProjectAndTagLabelsView: React.FC<{
projectNames: string[],
activeProjectName: string,
otherLabels: string[],
style?: React.CSSProperties,
}> = ({ projectNames, activeProjectName, otherLabels, style }) => {
// We can have an empty project name if we have no projects specified in the config
const hasProjectNames = projectNames.length > 0 && !!activeProjectName;
return (hasProjectNames || otherLabels.length > 0) && <span className='label-row' style={style ?? {}}>
<ProjectLink projectNames={projectNames} projectName={activeProjectName} />
<LabelsClickView labels={otherLabels} />
</span>;
};
const LabelsClickView: React.FC<{
labels: string[],
}> = ({ labels }) => {
const searchParams = useSearchParams();
const onClickHandle = React.useCallback((e: React.MouseEvent, label: string) => {
const params = new URLSearchParams(searchParams);
e.preventDefault();
if (params.has('testId'))
params.delete('speedboard');
params.delete('testId');
navigate(filterWithQuery(params, label, e.metaKey || e.ctrlKey));
}, [searchParams]);
return <>
{labels.map(label => <Label key={label} label={label} trimAtSymbolPrefix={true} onClick={onClickHandle} />)}
</>;
};