aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJeremy Davis <jeremy.davis@sonarsource.com>2022-07-26 15:05:37 +0200
committersonartech <sonartech@sonarsource.com>2022-07-28 20:02:55 +0000
commitd2d1034e10a78992a9d3aa3267dc770832646af1 (patch)
treed5b5b69794ea3e8a7254912a42beeddb2ce04601 /server
parent76b594f966759863e4b6763c6f6cc01fadf2fba9 (diff)
downloadsonarqube-d2d1034e10a78992a9d3aa3267dc770832646af1.tar.gz
sonarqube-d2d1034e10a78992a9d3aa3267dc770832646af1.zip
SONAR-16683 [891539] Semantic html for the search results
Diffstat (limited to 'server')
-rw-r--r--server/sonar-web/src/main/js/app/components/search/Search.tsx2
-rw-r--r--server/sonar-web/src/main/js/app/components/search/SearchResult.tsx10
-rw-r--r--server/sonar-web/src/main/js/app/components/search/SearchResults.tsx47
-rw-r--r--server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResult-test.tsx.snap12
-rw-r--r--server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResults-test.tsx.snap124
-rw-r--r--server/sonar-web/src/main/js/app/styles/components/menu.css4
6 files changed, 110 insertions, 89 deletions
diff --git a/server/sonar-web/src/main/js/app/components/search/Search.tsx b/server/sonar-web/src/main/js/app/components/search/Search.tsx
index eb716f341e7..98996b99490 100644
--- a/server/sonar-web/src/main/js/app/components/search/Search.tsx
+++ b/server/sonar-web/src/main/js/app/components/search/Search.tsx
@@ -378,7 +378,7 @@ export class Search extends React.PureComponent<Props, State> {
selected={this.state.selected}
/>
<div className="dropdown-bottom-hint">
- <div className="pull-right">
+ <div className="pull-right" aria-hidden={true}>
<ClockIcon className="little-spacer-right" size={12} />
{translate('recently_browsed')}
</div>
diff --git a/server/sonar-web/src/main/js/app/components/search/SearchResult.tsx b/server/sonar-web/src/main/js/app/components/search/SearchResult.tsx
index 16f946915d7..c155d0bb86f 100644
--- a/server/sonar-web/src/main/js/app/components/search/SearchResult.tsx
+++ b/server/sonar-web/src/main/js/app/components/search/SearchResult.tsx
@@ -41,6 +41,7 @@ interface State {
}
const TOOLTIP_DELAY = 1000;
+const MILLISECONDS_PER_SECOND = 1000;
export default class SearchResult extends React.PureComponent<Props, State> {
interval?: number;
@@ -101,9 +102,11 @@ export default class SearchResult extends React.PureComponent<Props, State> {
<li
className={this.props.selected ? 'active' : undefined}
key={component.key}
- ref={node => this.props.innerRef(component.key, node)}>
+ ref={node => this.props.innerRef(component.key, node)}
+ role="option"
+ aria-selected={this.props.selected}>
<Tooltip
- mouseEnterDelay={TOOLTIP_DELAY / 1000}
+ mouseEnterDelay={TOOLTIP_DELAY / MILLISECONDS_PER_SECOND}
overlay={component.key}
placement="left"
visible={this.state.tooltipVisible}>
@@ -118,7 +121,8 @@ export default class SearchResult extends React.PureComponent<Props, State> {
{component.match ? (
<span
className="navbar-search-item-match"
- // Safe: comes from the backend
+ // Safe: comes from the search engine, that injects bold tags into component names
+ // eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: component.match }}
/>
) : (
diff --git a/server/sonar-web/src/main/js/app/components/search/SearchResults.tsx b/server/sonar-web/src/main/js/app/components/search/SearchResults.tsx
index 4b12eff31df..c0ccf411c86 100644
--- a/server/sonar-web/src/main/js/app/components/search/SearchResults.tsx
+++ b/server/sonar-web/src/main/js/app/components/search/SearchResults.tsx
@@ -41,39 +41,30 @@ export default function SearchResults(props: Props): React.ReactElement<Props> {
sortQualifiers(qualifiers).forEach(qualifier => {
const components = props.results[qualifier];
- if (components.length > 0 && renderedComponents.length > 0) {
- renderedComponents.push(<li className="divider" key={`divider-${qualifier}`} />);
- }
-
if (components.length > 0) {
- renderedComponents.push(
- <li className="menu-header" key={`header-${qualifier}`}>
- {translate('qualifiers', qualifier)}
- </li>
- );
- }
-
- components.forEach(component => renderedComponents.push(props.renderResult(component)));
+ const more = props.more[qualifier];
- const more = props.more[qualifier];
- if (more !== undefined && more > 0) {
renderedComponents.push(
- <SearchShowMore
- allowMore={props.allowMore}
- key={`more-${qualifier}`}
- loadingMore={props.loadingMore}
- onMoreClick={props.onMoreClick}
- onSelect={props.onSelect}
- qualifier={qualifier}
- selected={props.selected === `qualifier###${qualifier}`}
- />
+ <ul className="menu" key={`header-${qualifier}`} role="group">
+ <li className="menu-header" role="presentation">
+ {translate('qualifiers', qualifier)}
+ </li>
+ {components.map(component => props.renderResult(component))}
+ {more !== undefined && more > 0 && (
+ <SearchShowMore
+ allowMore={props.allowMore}
+ key={`more-${qualifier}`}
+ loadingMore={props.loadingMore}
+ onMoreClick={props.onMoreClick}
+ onSelect={props.onSelect}
+ qualifier={qualifier}
+ selected={props.selected === `qualifier###${qualifier}`}
+ />
+ )}
+ </ul>
);
}
});
- return renderedComponents.length > 0 ? (
- <ul className="menu">{renderedComponents}</ul>
- ) : (
- props.renderNoResults()
- );
+ return renderedComponents.length > 0 ? <div>{renderedComponents}</div> : props.renderNoResults();
}
diff --git a/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResult-test.tsx.snap b/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResult-test.tsx.snap
index d4e19eaf97b..4cee1218fcd 100644
--- a/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResult-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResult-test.tsx.snap
@@ -2,7 +2,9 @@
exports[`renders favorite 1`] = `
<li
+ aria-selected={false}
key="foo"
+ role="option"
>
<Tooltip
mouseEnterDelay={1}
@@ -49,7 +51,9 @@ exports[`renders favorite 1`] = `
exports[`renders match 1`] = `
<li
+ aria-selected={false}
key="foo"
+ role="option"
>
<Tooltip
mouseEnterDelay={1}
@@ -95,7 +99,9 @@ exports[`renders match 1`] = `
exports[`renders projects 1`] = `
<li
+ aria-selected={false}
key="qwe"
+ role="option"
>
<Tooltip
mouseEnterDelay={1}
@@ -146,7 +152,9 @@ exports[`renders projects 1`] = `
exports[`renders recently browsed 1`] = `
<li
+ aria-selected={false}
key="foo"
+ role="option"
>
<Tooltip
mouseEnterDelay={1}
@@ -192,7 +200,9 @@ exports[`renders recently browsed 1`] = `
exports[`renders selected 1`] = `
<li
+ aria-selected={false}
key="foo"
+ role="option"
>
<Tooltip
mouseEnterDelay={1}
@@ -235,8 +245,10 @@ exports[`renders selected 1`] = `
exports[`renders selected 2`] = `
<li
+ aria-selected={true}
className="active"
key="foo"
+ role="option"
>
<Tooltip
mouseEnterDelay={1}
diff --git a/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResults-test.tsx.snap b/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResults-test.tsx.snap
index 54e23479104..c0668213eed 100644
--- a/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResults-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/search/__tests__/__snapshots__/SearchResults-test.tsx.snap
@@ -1,72 +1,82 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders "Show More" link 1`] = `
-<ul
- className="menu"
->
- <li
- className="menu-header"
+<div>
+ <ul
+ className="menu"
key="header-TRK"
+ role="group"
>
- qualifiers.TRK
- </li>
- <span
- key="foo"
- >
- foo
- </span>
- <span
- key="bar"
- >
- bar
- </span>
- <SearchShowMore
- allowMore={true}
- key="more-TRK"
- onMoreClick={[MockFunction]}
- onSelect={[MockFunction]}
- qualifier="TRK"
- selected={false}
- />
-</ul>
+ <li
+ className="menu-header"
+ role="presentation"
+ >
+ qualifiers.TRK
+ </li>
+ <span
+ key="foo"
+ >
+ foo
+ </span>
+ <span
+ key="bar"
+ >
+ bar
+ </span>
+ <SearchShowMore
+ allowMore={true}
+ key="more-TRK"
+ onMoreClick={[MockFunction]}
+ onSelect={[MockFunction]}
+ qualifier="TRK"
+ selected={false}
+ />
+ </ul>
+</div>
`;
exports[`renders different components and dividers between them 1`] = `
-<ul
- className="menu"
->
- <li
- className="menu-header"
+<div>
+ <ul
+ className="menu"
key="header-FIL"
+ role="group"
>
- qualifiers.FIL
- </li>
- <span
- key="zux"
- >
- zux
- </span>
- <li
- className="divider"
- key="divider-TRK"
- />
- <li
- className="menu-header"
+ <li
+ className="menu-header"
+ role="presentation"
+ >
+ qualifiers.FIL
+ </li>
+ <span
+ key="zux"
+ >
+ zux
+ </span>
+ </ul>
+ <ul
+ className="menu"
key="header-TRK"
+ role="group"
>
- qualifiers.TRK
- </li>
- <span
- key="foo"
- >
- foo
- </span>
- <span
- key="bar"
- >
- bar
- </span>
-</ul>
+ <li
+ className="menu-header"
+ role="presentation"
+ >
+ qualifiers.TRK
+ </li>
+ <span
+ key="foo"
+ >
+ foo
+ </span>
+ <span
+ key="bar"
+ >
+ bar
+ </span>
+ </ul>
+</div>
`;
exports[`should render no results 1`] = `
diff --git a/server/sonar-web/src/main/js/app/styles/components/menu.css b/server/sonar-web/src/main/js/app/styles/components/menu.css
index 6ed64f7f2e6..567e5f9a18c 100644
--- a/server/sonar-web/src/main/js/app/styles/components/menu.css
+++ b/server/sonar-web/src/main/js/app/styles/components/menu.css
@@ -27,6 +27,10 @@
background-clip: padding-box;
}
+.menu + .menu {
+ border-top: 1px solid var(--barBorderColor);
+}
+
.menu:focus {
outline: none;
}