aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-web/src/main/js/apps/audit-logs/components/AuditAppRenderer.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/background-tasks/background-tasks.css4
-rw-r--r--server/sonar-web/src/main/js/apps/background-tasks/components/CurrentsFilter.tsx36
-rw-r--r--server/sonar-web/src/main/js/apps/background-tasks/components/Search.tsx46
-rw-r--r--server/sonar-web/src/main/js/apps/background-tasks/components/StatusFilter.tsx63
-rw-r--r--server/sonar-web/src/main/js/apps/background-tasks/components/TypesFilter.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityDateInput.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageFilters.tsx76
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageHeader.tsx72
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityPageFilters-test.tsx (renamed from server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityPageHeader-test.tsx)4
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityApp-test.tsx.snap2
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityDateInput-test.tsx.snap4
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityPageFilters-test.tsx.snap50
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityPageHeader-test.tsx.snap40
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.tsx23
-rw-r--r--server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/__snapshots__/ChangelogSearch-test.tsx.snap2
-rw-r--r--server/sonar-web/src/main/js/components/controls/DateInput.tsx3
-rw-r--r--server/sonar-web/src/main/js/components/controls/DateRangeInput.tsx60
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateRangeInput-test.tsx.snap182
20 files changed, 401 insertions, 277 deletions
diff --git a/server/sonar-web/src/main/js/apps/audit-logs/components/AuditAppRenderer.tsx b/server/sonar-web/src/main/js/apps/audit-logs/components/AuditAppRenderer.tsx
index 668cb99c8e4..d191cc46fb3 100644
--- a/server/sonar-web/src/main/js/apps/audit-logs/components/AuditAppRenderer.tsx
+++ b/server/sonar-web/src/main/js/apps/audit-logs/components/AuditAppRenderer.tsx
@@ -119,7 +119,6 @@ export default function AuditAppRenderer(props: AuditAppRendererProps) {
</ul>
<DateRangeInput
- className="big-spacer-left"
onChange={props.handleDateSelection}
minDate={subDays(now(), HOUSEKEEPING_POLICY_VALUES[housekeepingPolicy])}
maxDate={now()}
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/background-tasks.css b/server/sonar-web/src/main/js/apps/background-tasks/background-tasks.css
index 5fb4b9ad748..f08c5d60023 100644
--- a/server/sonar-web/src/main/js/apps/background-tasks/background-tasks.css
+++ b/server/sonar-web/src/main/js/apps/background-tasks/background-tasks.css
@@ -26,10 +26,6 @@
margin-left: 16px;
}
-.bt-search-form-label {
- margin-bottom: 4px;
-}
-
.bt-search-form-field {
padding: 4px 0;
}
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/CurrentsFilter.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/CurrentsFilter.tsx
index a6ab2a113b6..d9343452025 100644
--- a/server/sonar-web/src/main/js/apps/background-tasks/components/CurrentsFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/background-tasks/components/CurrentsFilter.tsx
@@ -22,25 +22,29 @@ import Checkbox from '../../../components/controls/Checkbox';
import { translate } from '../../../helpers/l10n';
import { CURRENTS } from '../constants';
-interface Props {
+interface CurrentsFilterProps {
value?: string;
+ id: string;
onChange: (value: string) => void;
}
-export default class CurrentsFilter extends React.PureComponent<Props> {
- handleChange = (value: boolean) => {
- const newValue = value ? CURRENTS.ONLY_CURRENTS : CURRENTS.ALL;
- this.props.onChange(newValue);
- };
+export default function CurrentsFilter(props: CurrentsFilterProps) {
+ const { id, value, onChange } = props;
+ const checked = value === CURRENTS.ONLY_CURRENTS;
- render() {
- const checked = this.props.value === CURRENTS.ONLY_CURRENTS;
- return (
- <div className="bt-search-form-field">
- <Checkbox checked={checked} onCheck={this.handleChange}>
- <span className="little-spacer-left">{translate('yes')}</span>
- </Checkbox>
- </div>
- );
- }
+ const handleChange = React.useCallback(
+ (value: boolean) => {
+ const newValue = value ? CURRENTS.ONLY_CURRENTS : CURRENTS.ALL;
+ onChange(newValue);
+ },
+ [onChange]
+ );
+
+ return (
+ <div className="bt-search-form-field">
+ <Checkbox id={id} checked={checked} onCheck={handleChange}>
+ <span className="little-spacer-left">{translate('yes')}</span>
+ </Checkbox>
+ </div>
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/Search.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/Search.tsx
index 198317542dc..bede447ef59 100644
--- a/server/sonar-web/src/main/js/apps/background-tasks/components/Search.tsx
+++ b/server/sonar-web/src/main/js/apps/background-tasks/components/Search.tsx
@@ -102,29 +102,49 @@ export default class Search extends React.PureComponent<Props> {
<section className="big-spacer-top big-spacer-bottom">
<ul className="bt-search-form">
<li>
- <h6 id="background-task-status-filter-label" className="bt-search-form-label">
- {translate('status')}
- </h6>
- <StatusFilter onChange={this.handleStatusChange} value={status} />
+ <div className="display-flex-column">
+ <label
+ id="background-task-status-filter-label"
+ className="text-bold little-spacer-bottom"
+ htmlFor="status-filter">
+ {translate('status')}
+ </label>
+ <StatusFilter id="status-filter" onChange={this.handleStatusChange} value={status} />
+ </div>
</li>
{types.length > 1 && (
<li>
- <h6 id="background-task-type-filter-label" className="bt-search-form-label">
- {translate('type')}
- </h6>
- <TypesFilter onChange={this.handleTypeChange} types={types} value={taskType} />
+ <div className="display-flex-column">
+ <label
+ id="background-task-type-filter-label"
+ className="text-bold little-spacer-bottom"
+ htmlFor="types-filter">
+ {translate('type')}
+ </label>
+ <TypesFilter
+ id="types-filter"
+ onChange={this.handleTypeChange}
+ types={types}
+ value={taskType}
+ />
+ </div>
</li>
)}
{!component && (
<li>
- <h6 className="bt-search-form-label">
- {translate('background_tasks.currents_filter.ONLY_CURRENTS')}
- </h6>
- <CurrentsFilter onChange={this.handleCurrentsChange} value={currents} />
+ <div className="display-flex-column">
+ <label className="text-bold little-spacer-bottom" htmlFor="currents-filter">
+ {translate('background_tasks.currents_filter.ONLY_CURRENTS')}
+ </label>
+ <CurrentsFilter
+ id="currents-filter"
+ onChange={this.handleCurrentsChange}
+ value={currents}
+ />
+ </div>
</li>
)}
<li>
- <h6 className="bt-search-form-label">{translate('date')}</h6>
<DateFilter
maxExecutedAt={maxExecutedAt}
minSubmittedAt={minSubmittedAt}
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/StatusFilter.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/StatusFilter.tsx
index 6e248342f54..f797b433719 100644
--- a/server/sonar-web/src/main/js/apps/background-tasks/components/StatusFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/background-tasks/components/StatusFilter.tsx
@@ -23,39 +23,44 @@ import { translate } from '../../../helpers/l10n';
import { TaskStatuses } from '../../../types/tasks';
import { STATUSES } from '../constants';
-interface Props {
+interface StatusFilterProps {
value?: string;
+ id: string;
onChange: (value?: string) => void;
}
-export default class StatusFilter extends React.PureComponent<Props> {
- handleChange = ({ value }: BasicSelectOption) => {
- this.props.onChange(value);
- };
+export default function StatusFilter(props: StatusFilterProps) {
+ const { id, value, onChange } = props;
- render() {
- const options: BasicSelectOption[] = [
- { value: STATUSES.ALL, label: translate('background_task.status.ALL') },
- {
- value: STATUSES.ALL_EXCEPT_PENDING,
- label: translate('background_task.status.ALL_EXCEPT_PENDING')
- },
- { value: TaskStatuses.Pending, label: translate('background_task.status.PENDING') },
- { value: TaskStatuses.InProgress, label: translate('background_task.status.IN_PROGRESS') },
- { value: TaskStatuses.Success, label: translate('background_task.status.SUCCESS') },
- { value: TaskStatuses.Failed, label: translate('background_task.status.FAILED') },
- { value: TaskStatuses.Canceled, label: translate('background_task.status.CANCELED') }
- ];
+ const options: BasicSelectOption[] = [
+ { value: STATUSES.ALL, label: translate('background_task.status.ALL') },
+ {
+ value: STATUSES.ALL_EXCEPT_PENDING,
+ label: translate('background_task.status.ALL_EXCEPT_PENDING')
+ },
+ { value: TaskStatuses.Pending, label: translate('background_task.status.PENDING') },
+ { value: TaskStatuses.InProgress, label: translate('background_task.status.IN_PROGRESS') },
+ { value: TaskStatuses.Success, label: translate('background_task.status.SUCCESS') },
+ { value: TaskStatuses.Failed, label: translate('background_task.status.FAILED') },
+ { value: TaskStatuses.Canceled, label: translate('background_task.status.CANCELED') }
+ ];
- return (
- <Select
- aria-labelledby="background-task-status-filter-label"
- className="input-medium"
- onChange={this.handleChange}
- options={options}
- value={options.find(o => o.value === this.props.value)}
- isSearchable={false}
- />
- );
- }
+ const handleChange = React.useCallback(
+ ({ value }: BasicSelectOption) => {
+ onChange(value);
+ },
+ [onChange]
+ );
+
+ return (
+ <Select
+ aria-labelledby="background-task-status-filter-label"
+ className="input-medium"
+ id={id}
+ onChange={handleChange}
+ options={options}
+ value={options.find(o => o.value === value)}
+ isSearchable={false}
+ />
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/background-tasks/components/TypesFilter.tsx b/server/sonar-web/src/main/js/apps/background-tasks/components/TypesFilter.tsx
index b84b2150539..4ef1522f76d 100644
--- a/server/sonar-web/src/main/js/apps/background-tasks/components/TypesFilter.tsx
+++ b/server/sonar-web/src/main/js/apps/background-tasks/components/TypesFilter.tsx
@@ -24,6 +24,7 @@ import { ALL_TYPES } from '../constants';
interface Props {
value: string;
+ id: string;
onChange: Function;
types: string[];
}
@@ -34,7 +35,7 @@ export default class TypesFilter extends React.PureComponent<Props> {
};
render() {
- const { value, types } = this.props;
+ const { value, types, id } = this.props;
const options = types.map(t => {
return {
value: t,
@@ -51,6 +52,7 @@ export default class TypesFilter extends React.PureComponent<Props> {
<Select
aria-labelledby="background-task-type-filter-label"
className="input-large"
+ id={id}
isClearable={false}
onChange={this.handleChange}
options={allOptions}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.tsx b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.tsx
index b1fa4fa47ad..fe2c2d21886 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.tsx
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.tsx
@@ -29,7 +29,7 @@ import { Query } from '../utils';
import './projectActivity.css';
import ProjectActivityAnalysesList from './ProjectActivityAnalysesList';
import ProjectActivityGraphs from './ProjectActivityGraphs';
-import ProjectActivityPageHeader from './ProjectActivityPageHeader';
+import ProjectActivityPageFilters from './ProjectActivityPageFilters';
interface Props {
addCustomEvent: (analysis: string, name: string, category?: string) => Promise<void>;
@@ -62,7 +62,7 @@ export default function ProjectActivityApp(props: Props) {
<A11ySkipTarget anchor="activity_main" />
- <ProjectActivityPageHeader
+ <ProjectActivityPageFilters
category={query.category}
from={query.from}
project={props.project}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityDateInput.tsx b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityDateInput.tsx
index e8ef04cf8c9..03fa34586d9 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityDateInput.tsx
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityDateInput.tsx
@@ -40,7 +40,7 @@ export default class ProjectActivityDateInput extends React.PureComponent<Props>
render() {
return (
- <div>
+ <div className="display-flex-end">
<DateRangeInput
onChange={this.handleChange}
value={{ from: this.props.from, to: this.props.to }}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageFilters.tsx b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageFilters.tsx
new file mode 100644
index 00000000000..4e6dd15c6f8
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageFilters.tsx
@@ -0,0 +1,76 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import * as React from 'react';
+import Select from '../../../components/controls/Select';
+import { translate } from '../../../helpers/l10n';
+import { ComponentQualifier } from '../../../types/component';
+import { Component } from '../../../types/types';
+import { APPLICATION_EVENT_TYPES, EVENT_TYPES, Query } from '../utils';
+import ProjectActivityDateInput from './ProjectActivityDateInput';
+
+interface ProjectActivityPageFiltersProps {
+ category?: string;
+ from?: Date;
+ project: Pick<Component, 'qualifier'>;
+ to?: Date;
+ updateQuery: (changes: Partial<Query>) => void;
+}
+
+export default function ProjectActivityPageFilters(props: ProjectActivityPageFiltersProps) {
+ const { project, category, from, to, updateQuery } = props;
+
+ const isApp = project.qualifier === ComponentQualifier.Application;
+ const eventTypes = isApp ? APPLICATION_EVENT_TYPES : EVENT_TYPES;
+ const options = eventTypes.map(category => ({
+ label: translate('event.category', category),
+ value: category
+ }));
+
+ const handleCategoryChange = React.useCallback(
+ (option: { value: string } | null) => {
+ updateQuery({ category: option ? option.value : '' });
+ },
+ [updateQuery]
+ );
+
+ return (
+ <div className="page-header display-flex-start">
+ {!([ComponentQualifier.Portfolio, ComponentQualifier.SubPortfolio] as string[]).includes(
+ project.qualifier
+ ) && (
+ <div className="display-flex-column big-spacer-right">
+ <label className="text-bold little-spacer-bottom" htmlFor="filter-events">
+ {translate('project_activity.filter_events')}
+ </label>
+ <Select
+ className={isApp ? 'input-large' : 'input-medium'}
+ id="filter-events"
+ isClearable={true}
+ isSearchable={false}
+ onChange={handleCategoryChange}
+ options={options}
+ value={options.filter(o => o.value === category)}
+ />
+ </div>
+ )}
+ <ProjectActivityDateInput from={from} onChange={props.updateQuery} to={to} />
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageHeader.tsx b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageHeader.tsx
deleted file mode 100644
index 57f22d99298..00000000000
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityPageHeader.tsx
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2022 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import classNames from 'classnames';
-import * as React from 'react';
-import Select from '../../../components/controls/Select';
-import { translate } from '../../../helpers/l10n';
-import { Component } from '../../../types/types';
-import { APPLICATION_EVENT_TYPES, EVENT_TYPES, Query } from '../utils';
-import ProjectActivityDateInput from './ProjectActivityDateInput';
-
-interface Props {
- category?: string;
- from?: Date;
- project: Pick<Component, 'qualifier'>;
- to?: Date;
- updateQuery: (changes: Partial<Query>) => void;
-}
-
-export default class ProjectActivityPageHeader extends React.PureComponent<Props> {
- handleCategoryChange = (option: { value: string } | null) =>
- this.props.updateQuery({ category: option ? option.value : '' });
-
- render() {
- const isApp = this.props.project.qualifier === 'APP';
- const eventTypes = isApp ? APPLICATION_EVENT_TYPES : EVENT_TYPES;
- const options = eventTypes.map(category => ({
- label: translate('event.category', category),
- value: category
- }));
-
- return (
- <header className="page-header">
- {!['VW', 'SVW'].includes(this.props.project.qualifier) && (
- <Select
- className={classNames('pull-left big-spacer-right', {
- 'input-medium': !isApp,
- 'input-large': isApp
- })}
- placeholder={translate('project_activity.filter_events') + '...'}
- isClearable={true}
- isSearchable={false}
- onChange={this.handleCategoryChange}
- options={options}
- value={options.filter(o => o.value === this.props.category)}
- />
- )}
- <ProjectActivityDateInput
- from={this.props.from}
- onChange={this.props.updateQuery}
- to={this.props.to}
- />
- </header>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityPageHeader-test.tsx b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityPageFilters-test.tsx
index 209ef357749..54beadc9fc6 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityPageHeader-test.tsx
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityPageFilters-test.tsx
@@ -20,12 +20,12 @@
import { shallow } from 'enzyme';
import * as React from 'react';
import { parseDate } from '../../../../helpers/dates';
-import ProjectActivityPageHeader from '../ProjectActivityPageHeader';
+import ProjectActivityPageFilters from '../ProjectActivityPageFilters';
it('should render correctly the list of series', () => {
expect(
shallow(
- <ProjectActivityPageHeader
+ <ProjectActivityPageFilters
category=""
from={parseDate('2016-10-27T12:21:15+0200')}
project={{ qualifier: 'TRK' }}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityApp-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityApp-test.tsx.snap
index bcb41a66916..3f89e7becc1 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityApp-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityApp-test.tsx.snap
@@ -17,7 +17,7 @@ exports[`should render correctly 1`] = `
<A11ySkipTarget
anchor="activity_main"
/>
- <ProjectActivityPageHeader
+ <ProjectActivityPageFilters
category=""
project={
Object {
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityDateInput-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityDateInput-test.tsx.snap
index d10a64ba95c..7ebe7e54805 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityDateInput-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityDateInput-test.tsx.snap
@@ -1,7 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should render correctly the date inputs 1`] = `
-<div>
+<div
+ className="display-flex-end"
+>
<DateRangeInput
onChange={[Function]}
value={
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityPageFilters-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityPageFilters-test.tsx.snap
new file mode 100644
index 00000000000..56f0a23bc2f
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityPageFilters-test.tsx.snap
@@ -0,0 +1,50 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly the list of series 1`] = `
+<div
+ className="page-header display-flex-start"
+>
+ <div
+ className="display-flex-column big-spacer-right"
+ >
+ <label
+ className="text-bold little-spacer-bottom"
+ htmlFor="filter-events"
+ >
+ project_activity.filter_events
+ </label>
+ <Select
+ className="input-medium"
+ id="filter-events"
+ isClearable={true}
+ isSearchable={false}
+ onChange={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "event.category.VERSION",
+ "value": "VERSION",
+ },
+ Object {
+ "label": "event.category.QUALITY_GATE",
+ "value": "QUALITY_GATE",
+ },
+ Object {
+ "label": "event.category.QUALITY_PROFILE",
+ "value": "QUALITY_PROFILE",
+ },
+ Object {
+ "label": "event.category.OTHER",
+ "value": "OTHER",
+ },
+ ]
+ }
+ value={Array []}
+ />
+ </div>
+ <ProjectActivityDateInput
+ from={2016-10-27T10:21:15.000Z}
+ onChange={[Function]}
+ />
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityPageHeader-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityPageHeader-test.tsx.snap
deleted file mode 100644
index 5659e62e451..00000000000
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityPageHeader-test.tsx.snap
+++ /dev/null
@@ -1,40 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly the list of series 1`] = `
-<header
- className="page-header"
->
- <Select
- className="pull-left big-spacer-right input-medium"
- isClearable={true}
- isSearchable={false}
- onChange={[Function]}
- options={
- Array [
- Object {
- "label": "event.category.VERSION",
- "value": "VERSION",
- },
- Object {
- "label": "event.category.QUALITY_GATE",
- "value": "QUALITY_GATE",
- },
- Object {
- "label": "event.category.QUALITY_PROFILE",
- "value": "QUALITY_PROFILE",
- },
- Object {
- "label": "event.category.OTHER",
- "value": "OTHER",
- },
- ]
- }
- placeholder="project_activity.filter_events..."
- value={Array []}
- />
- <ProjectActivityDateInput
- from={2016-10-27T10:21:15.000Z}
- onChange={[Function]}
- />
-</header>
-`;
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.tsx b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.tsx
index 9b34dcf77f6..0a59ac50f23 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.tsx
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.tsx
@@ -22,21 +22,20 @@ import { Button } from '../../../components/controls/buttons';
import DateRangeInput from '../../../components/controls/DateRangeInput';
import { translate } from '../../../helpers/l10n';
-interface Props {
+interface ChangelogSearchProps {
dateRange: { from?: Date; to?: Date } | undefined;
onDateRangeChange: (range: { from?: Date; to?: Date }) => void;
onReset: () => void;
}
-export default class ChangelogSearch extends React.PureComponent<Props> {
- render() {
- return (
- <div className="display-inline-block" id="quality-profile-changelog-form">
- <DateRangeInput onChange={this.props.onDateRangeChange} value={this.props.dateRange} />
- <Button className="spacer-left text-top" onClick={this.props.onReset}>
- {translate('reset_verb')}
- </Button>
- </div>
- );
- }
+export default function ChangelogSearch(props: ChangelogSearchProps) {
+ const { dateRange } = props;
+ return (
+ <div className="display-flex-end" id="quality-profile-changelog-form">
+ <DateRangeInput onChange={props.onDateRangeChange} value={dateRange} />
+ <Button className="spacer-left text-top" onClick={props.onReset}>
+ {translate('reset_verb')}
+ </Button>
+ </div>
+ );
}
diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/__snapshots__/ChangelogSearch-test.tsx.snap b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/__snapshots__/ChangelogSearch-test.tsx.snap
index 457151fcb76..91386121e4e 100644
--- a/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/__snapshots__/ChangelogSearch-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/quality-profiles/changelog/__tests__/__snapshots__/ChangelogSearch-test.tsx.snap
@@ -2,7 +2,7 @@
exports[`should render 1`] = `
<div
- className="display-inline-block"
+ className="display-flex-end"
id="quality-profile-changelog-form"
>
<DateRangeInput
diff --git a/server/sonar-web/src/main/js/components/controls/DateInput.tsx b/server/sonar-web/src/main/js/components/controls/DateInput.tsx
index 9ed6b165b10..166d7717aee 100644
--- a/server/sonar-web/src/main/js/components/controls/DateInput.tsx
+++ b/server/sonar-web/src/main/js/components/controls/DateInput.tsx
@@ -47,6 +47,7 @@ interface Props {
maxDate?: Date;
minDate?: Date;
name?: string;
+ id?: string;
onChange: (date: Date | undefined) => void;
placeholder: string;
value?: Date;
@@ -128,6 +129,7 @@ export default class DateInput extends React.PureComponent<Props, State> {
name,
className,
inputClassName,
+ id,
placeholder
} = this.props;
const { lastHovered, currentMonth, open } = this.state;
@@ -166,6 +168,7 @@ export default class DateInput extends React.PureComponent<Props, State> {
className={classNames('date-input-control-input', inputClassName, {
'is-filled': value !== undefined
})}
+ id={id}
innerRef={(node: HTMLInputElement | null) => (this.input = node)}
name={name}
onFocus={this.openCalendar}
diff --git a/server/sonar-web/src/main/js/components/controls/DateRangeInput.tsx b/server/sonar-web/src/main/js/components/controls/DateRangeInput.tsx
index 4d3aee13173..a2f13e9b635 100644
--- a/server/sonar-web/src/main/js/components/controls/DateRangeInput.tsx
+++ b/server/sonar-web/src/main/js/components/controls/DateRangeInput.tsx
@@ -63,29 +63,43 @@ export default class DateRangeInput extends React.PureComponent<Props> {
const { minDate, maxDate } = this.props;
return (
- <div className={classNames('display-inline-flex-center', this.props.className)}>
- <DateInput
- currentMonth={this.to}
- data-test="from"
- highlightTo={this.to}
- minDate={minDate}
- maxDate={maxDate && this.to ? min([maxDate, this.to]) : maxDate || this.to}
- onChange={this.handleFromChange}
- placeholder={translate('start_date')}
- value={this.from}
- />
- <span className="note little-spacer-left little-spacer-right">{translate('to_')}</span>
- <DateInput
- currentMonth={this.from}
- data-test="to"
- highlightFrom={this.from}
- minDate={minDate && this.from ? max([minDate, this.from]) : minDate || this.from}
- maxDate={maxDate}
- onChange={this.handleToChange}
- placeholder={translate('end_date')}
- ref={element => (this.toDateInput = element)}
- value={this.to}
- />
+ <div className={classNames('display-flex-end', this.props.className)}>
+ <div className="display-flex-column">
+ <label className="text-bold little-spacer-bottom" htmlFor="date-from">
+ {translate('start_date')}
+ </label>
+ <DateInput
+ currentMonth={this.to}
+ data-test="from"
+ id="date-from"
+ highlightTo={this.to}
+ minDate={minDate}
+ maxDate={maxDate && this.to ? min([maxDate, this.to]) : maxDate || this.to}
+ onChange={this.handleFromChange}
+ placeholder={translate('start_date')}
+ value={this.from}
+ />
+ </div>
+ <span className="note little-spacer-left little-spacer-right little-spacer-bottom">
+ {translate('to_')}
+ </span>
+ <div className="display-flex-column">
+ <label className="text-bold little-spacer-bottom" htmlFor="date-to">
+ {translate('end_date')}
+ </label>
+ <DateInput
+ currentMonth={this.from}
+ data-test="to"
+ id="date-to"
+ highlightFrom={this.from}
+ minDate={minDate && this.from ? max([minDate, this.from]) : minDate || this.from}
+ maxDate={maxDate}
+ onChange={this.handleToChange}
+ placeholder={translate('end_date')}
+ ref={element => (this.toDateInput = element)}
+ value={this.to}
+ />
+ </div>
</div>
);
}
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateRangeInput-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateRangeInput-test.tsx.snap
index dbc2f7cb5a2..19e4e6ab487 100644
--- a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateRangeInput-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateRangeInput-test.tsx.snap
@@ -2,88 +2,154 @@
exports[`should render 1`] = `
<div
- className="display-inline-flex-center"
+ className="display-flex-end"
>
- <DateInput
- currentMonth={2018-02-05T00:00:00.000Z}
- data-test="from"
- highlightTo={2018-02-05T00:00:00.000Z}
- maxDate={2018-02-05T00:00:00.000Z}
- onChange={[Function]}
- placeholder="start_date"
- value={2018-01-17T00:00:00.000Z}
- />
+ <div
+ className="display-flex-column"
+ >
+ <label
+ className="text-bold little-spacer-bottom"
+ htmlFor="date-from"
+ >
+ start_date
+ </label>
+ <DateInput
+ currentMonth={2018-02-05T00:00:00.000Z}
+ data-test="from"
+ highlightTo={2018-02-05T00:00:00.000Z}
+ id="date-from"
+ maxDate={2018-02-05T00:00:00.000Z}
+ onChange={[Function]}
+ placeholder="start_date"
+ value={2018-01-17T00:00:00.000Z}
+ />
+ </div>
<span
- className="note little-spacer-left little-spacer-right"
+ className="note little-spacer-left little-spacer-right little-spacer-bottom"
>
to_
</span>
- <DateInput
- currentMonth={2018-01-17T00:00:00.000Z}
- data-test="to"
- highlightFrom={2018-01-17T00:00:00.000Z}
- minDate={2018-01-17T00:00:00.000Z}
- onChange={[Function]}
- placeholder="end_date"
- value={2018-02-05T00:00:00.000Z}
- />
+ <div
+ className="display-flex-column"
+ >
+ <label
+ className="text-bold little-spacer-bottom"
+ htmlFor="date-to"
+ >
+ end_date
+ </label>
+ <DateInput
+ currentMonth={2018-01-17T00:00:00.000Z}
+ data-test="to"
+ highlightFrom={2018-01-17T00:00:00.000Z}
+ id="date-to"
+ minDate={2018-01-17T00:00:00.000Z}
+ onChange={[Function]}
+ placeholder="end_date"
+ value={2018-02-05T00:00:00.000Z}
+ />
+ </div>
</div>
`;
exports[`should render: with min/max 1`] = `
<div
- className="display-inline-flex-center"
+ className="display-flex-end"
>
- <DateInput
- data-test="from"
- maxDate={2018-02-05T00:00:00.000Z}
- minDate={2018-01-17T00:00:00.000Z}
- onChange={[Function]}
- placeholder="start_date"
- />
+ <div
+ className="display-flex-column"
+ >
+ <label
+ className="text-bold little-spacer-bottom"
+ htmlFor="date-from"
+ >
+ start_date
+ </label>
+ <DateInput
+ data-test="from"
+ id="date-from"
+ maxDate={2018-02-05T00:00:00.000Z}
+ minDate={2018-01-17T00:00:00.000Z}
+ onChange={[Function]}
+ placeholder="start_date"
+ />
+ </div>
<span
- className="note little-spacer-left little-spacer-right"
+ className="note little-spacer-left little-spacer-right little-spacer-bottom"
>
to_
</span>
- <DateInput
- data-test="to"
- maxDate={2018-02-05T00:00:00.000Z}
- minDate={2018-01-17T00:00:00.000Z}
- onChange={[Function]}
- placeholder="end_date"
- />
+ <div
+ className="display-flex-column"
+ >
+ <label
+ className="text-bold little-spacer-bottom"
+ htmlFor="date-to"
+ >
+ end_date
+ </label>
+ <DateInput
+ data-test="to"
+ id="date-to"
+ maxDate={2018-02-05T00:00:00.000Z}
+ minDate={2018-01-17T00:00:00.000Z}
+ onChange={[Function]}
+ placeholder="end_date"
+ />
+ </div>
</div>
`;
exports[`should render: with min/max and value 1`] = `
<div
- className="display-inline-flex-center"
+ className="display-flex-end"
>
- <DateInput
- currentMonth={2018-02-05T00:00:00.000Z}
- data-test="from"
- highlightTo={2018-02-05T00:00:00.000Z}
- maxDate={2018-02-05T00:00:00.000Z}
- minDate={2018-01-17T00:00:00.000Z}
- onChange={[Function]}
- placeholder="start_date"
- value={2018-01-17T00:00:00.000Z}
- />
+ <div
+ className="display-flex-column"
+ >
+ <label
+ className="text-bold little-spacer-bottom"
+ htmlFor="date-from"
+ >
+ start_date
+ </label>
+ <DateInput
+ currentMonth={2018-02-05T00:00:00.000Z}
+ data-test="from"
+ highlightTo={2018-02-05T00:00:00.000Z}
+ id="date-from"
+ maxDate={2018-02-05T00:00:00.000Z}
+ minDate={2018-01-17T00:00:00.000Z}
+ onChange={[Function]}
+ placeholder="start_date"
+ value={2018-01-17T00:00:00.000Z}
+ />
+ </div>
<span
- className="note little-spacer-left little-spacer-right"
+ className="note little-spacer-left little-spacer-right little-spacer-bottom"
>
to_
</span>
- <DateInput
- currentMonth={2018-01-17T00:00:00.000Z}
- data-test="to"
- highlightFrom={2018-01-17T00:00:00.000Z}
- maxDate={2018-02-05T00:00:00.000Z}
- minDate={2018-01-17T00:00:00.000Z}
- onChange={[Function]}
- placeholder="end_date"
- value={2018-02-05T00:00:00.000Z}
- />
+ <div
+ className="display-flex-column"
+ >
+ <label
+ className="text-bold little-spacer-bottom"
+ htmlFor="date-to"
+ >
+ end_date
+ </label>
+ <DateInput
+ currentMonth={2018-01-17T00:00:00.000Z}
+ data-test="to"
+ highlightFrom={2018-01-17T00:00:00.000Z}
+ id="date-to"
+ maxDate={2018-02-05T00:00:00.000Z}
+ minDate={2018-01-17T00:00:00.000Z}
+ onChange={[Function]}
+ placeholder="end_date"
+ value={2018-02-05T00:00:00.000Z}
+ />
+ </div>
</div>
`;