๐Ÿ“ฆ microsoft / playwright

๐Ÿ“„ labels.tsx ยท 73 lines
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} />)}
  </>;
};