2021-12-12 14:56:12 -08:00
|
|
|
/*
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2022-09-20 18:41:51 -07:00
|
|
|
import type { Stats } from './types';
|
2021-12-12 14:56:12 -08:00
|
|
|
import * as React from 'react';
|
2021-12-13 18:30:48 -08:00
|
|
|
import './colors.css';
|
2021-12-13 15:37:01 -08:00
|
|
|
import './common.css';
|
2021-12-13 18:30:48 -08:00
|
|
|
import './headerView.css';
|
2021-12-13 15:37:01 -08:00
|
|
|
import * as icons from './icons';
|
|
|
|
import { Link, navigate } from './links';
|
2021-12-12 14:56:12 -08:00
|
|
|
import { statusIcon } from './statusIcon';
|
2022-12-20 17:13:10 -05:00
|
|
|
import { msToString } from './uiUtils';
|
2021-12-12 14:56:12 -08:00
|
|
|
|
2022-06-06 21:05:47 -07:00
|
|
|
export const HeaderView: React.FC<React.PropsWithChildren<{
|
2021-12-13 15:37:01 -08:00
|
|
|
stats: Stats,
|
|
|
|
filterText: string,
|
|
|
|
setFilterText: (filterText: string) => void,
|
2023-01-10 17:11:38 +01:00
|
|
|
projectNames: string[],
|
2023-02-07 14:22:10 -08:00
|
|
|
reportLoaderError?: string,
|
|
|
|
}>> = ({ stats, filterText, setFilterText, projectNames, reportLoaderError }) => {
|
2021-12-13 15:37:01 -08:00
|
|
|
React.useEffect(() => {
|
|
|
|
(async () => {
|
|
|
|
window.addEventListener('popstate', () => {
|
|
|
|
const params = new URLSearchParams(window.location.hash.slice(1));
|
|
|
|
setFilterText(params.get('q') || '');
|
|
|
|
});
|
|
|
|
})();
|
|
|
|
});
|
|
|
|
|
2022-12-20 17:13:10 -05:00
|
|
|
return (<>
|
|
|
|
<div className='pt-3'>
|
|
|
|
<div className='header-view-status-container ml-2 pl-2 d-flex'>
|
|
|
|
<StatsNavView stats={stats}></StatsNavView>
|
|
|
|
</div>
|
|
|
|
<form className='subnav-search' onSubmit={
|
|
|
|
event => {
|
|
|
|
event.preventDefault();
|
|
|
|
navigate(`#?q=${filterText ? encodeURIComponent(filterText) : ''}`);
|
|
|
|
}
|
|
|
|
}>
|
|
|
|
{icons.search()}
|
|
|
|
{/* Use navigationId to reset defaultValue */}
|
|
|
|
<input type='search' spellCheck={false} className='form-control subnav-search-input input-contrast width-full' value={filterText} onChange={e => {
|
|
|
|
setFilterText(e.target.value);
|
|
|
|
}}></input>
|
|
|
|
</form>
|
2021-12-13 15:37:01 -08:00
|
|
|
</div>
|
2023-02-07 14:22:10 -08:00
|
|
|
{reportLoaderError && <div className='header-view-status-line pt-2' data-testid='loader-error' style={{ color: 'var(--color-danger-emphasis)', textAlign: 'right' }}>{reportLoaderError}</div>}
|
|
|
|
<div className='header-view-status-line pt-2'>
|
2023-02-08 01:07:25 +01:00
|
|
|
{projectNames.length === 1 && !!projectNames[0] && <span data-testid="project-name" style={{ color: 'var(--color-fg-subtle)', float: 'left' }}>Project: {projectNames[0]}</span>}
|
2023-02-07 14:22:10 -08:00
|
|
|
<span data-testid="overall-duration" style={{ color: 'var(--color-fg-subtle)', float: 'right' }}>Total time: {msToString(stats.duration)}</span>
|
2023-01-10 17:11:38 +01:00
|
|
|
</div>
|
2022-12-20 17:13:10 -05:00
|
|
|
</>);
|
2021-12-13 15:37:01 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
const StatsNavView: React.FC<{
|
2021-12-12 14:56:12 -08:00
|
|
|
stats: Stats
|
|
|
|
}> = ({ stats }) => {
|
|
|
|
return <nav className='d-flex no-wrap'>
|
|
|
|
<Link className='subnav-item' href='#?'>
|
|
|
|
All <span className='d-inline counter'>{stats.total}</span>
|
|
|
|
</Link>
|
|
|
|
<Link className='subnav-item' href='#?q=s:passed'>
|
|
|
|
Passed <span className='d-inline counter'>{stats.expected}</span>
|
|
|
|
</Link>
|
|
|
|
<Link className='subnav-item' href='#?q=s:failed'>
|
|
|
|
{!!stats.unexpected && statusIcon('unexpected')} Failed <span className='d-inline counter'>{stats.unexpected}</span>
|
|
|
|
</Link>
|
|
|
|
<Link className='subnav-item' href='#?q=s:flaky'>
|
|
|
|
{!!stats.flaky && statusIcon('flaky')} Flaky <span className='d-inline counter'>{stats.flaky}</span>
|
|
|
|
</Link>
|
|
|
|
<Link className='subnav-item' href='#?q=s:skipped'>
|
|
|
|
Skipped <span className='d-inline counter'>{stats.skipped}</span>
|
|
|
|
</Link>
|
|
|
|
</nav>;
|
|
|
|
};
|