aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2019-05-06 15:59:07 +0200
committerSonarTech <sonartech@sonarsource.com>2019-05-07 20:21:28 +0200
commit84e8de22330886ae02907ae86e250e486e3ddfd4 (patch)
tree68b0087a60e726a533af41d2b9883be5fa4a7a5c /server/sonar-web/src
parente620cd39b96428241cb71a19abf8c80b776e605f (diff)
downloadsonarqube-84e8de22330886ae02907ae86e250e486e3ddfd4.tar.gz
sonarqube-84e8de22330886ae02907ae86e250e486e3ddfd4.zip
Create and use ClearButton component
Diffstat (limited to 'server/sonar-web/src')
-rw-r--r--server/sonar-web/src/main/js/app/components/notifications/NotificationsSidebar.tsx12
-rw-r--r--server/sonar-web/src/main/js/app/components/notifications/__tests__/__snapshots__/NotificationsSidebar-test.tsx.snap34
-rw-r--r--server/sonar-web/src/main/js/apps/create/organization/AutoOrganizationCreate.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/create/organization/AutoPersonalOrganizationBind.tsx7
-rw-r--r--server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoOrganizationCreate-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoPersonalOrganizationBind-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoOrganizationCreate-test.tsx.snap12
-rw-r--r--server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoPersonalOrganizationBind-test.tsx.snap6
-rw-r--r--server/sonar-web/src/main/js/apps/overview/meta/MetaLink.tsx9
-rw-r--r--server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaLink-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/overview/meta/__tests__/__snapshots__/MetaLink-test.tsx.snap8
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendItem.tsx13
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendItem-test.tsx.snap14
-rw-r--r--server/sonar-web/src/main/js/apps/tutorials/components/__tests__/TokenStep-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/components/controls/DateInput.tsx13
-rw-r--r--server/sonar-web/src/main/js/components/controls/GlobalMessages.tsx65
-rw-r--r--server/sonar-web/src/main/js/components/controls/SearchBox.tsx13
-rw-r--r--server/sonar-web/src/main/js/components/controls/Select.tsx10
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/GlobalMessages-test.tsx50
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateInput-test.tsx.snap28
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/GlobalMessages-test.tsx.snap44
-rw-r--r--server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SearchBox-test.tsx.snap14
-rw-r--r--server/sonar-web/src/main/js/components/ui/NewsBox.tsx12
-rw-r--r--server/sonar-web/src/main/js/components/ui/__tests__/NewsBox-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/components/ui/__tests__/__snapshots__/NewsBox-test.tsx.snap17
-rw-r--r--server/sonar-web/src/main/js/components/ui/buttons.tsx25
-rw-r--r--server/sonar-web/src/main/js/components/workspace/WorkspaceNavItem.tsx11
-rw-r--r--server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceNavItem-test.tsx2
-rw-r--r--server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceNavItem-test.tsx.snap13
-rw-r--r--server/sonar-web/src/main/js/helpers/__tests__/path-test.ts14
-rw-r--r--server/sonar-web/src/main/js/helpers/path.ts7
31 files changed, 280 insertions, 190 deletions
diff --git a/server/sonar-web/src/main/js/app/components/notifications/NotificationsSidebar.tsx b/server/sonar-web/src/main/js/app/components/notifications/NotificationsSidebar.tsx
index 443987abc97..660678a7552 100644
--- a/server/sonar-web/src/main/js/app/components/notifications/NotificationsSidebar.tsx
+++ b/server/sonar-web/src/main/js/app/components/notifications/NotificationsSidebar.tsx
@@ -19,12 +19,10 @@
*/
import * as React from 'react';
import * as classNames from 'classnames';
-import * as theme from '../../../app/theme';
-import ClearIcon from '../../../components/icons-components/ClearIcon';
import DateFormatter from '../../../components/intl/DateFormatter';
import DeferredSpinner from '../../../components/common/DeferredSpinner';
import Modal from '../../../components/controls/Modal';
-import { ButtonIcon } from '../../../components/ui/buttons';
+import { ClearButton } from '../../../components/ui/buttons';
import { PrismicFeatureNews } from '../../../api/news';
import { differenceInSeconds } from '../../../helpers/dates';
import { translate } from '../../../helpers/l10n';
@@ -46,9 +44,11 @@ export default function NotificationsSidebar(props: Props) {
<div className="notifications-sidebar">
<div className="notifications-sidebar-top">
<h3>{translate('embed_docs.whats_new')}</h3>
- <ButtonIcon className="button-tiny" color={theme.gray80} onClick={props.onClose}>
- <ClearIcon fill={theme.baseFontColor} size={12} thin={true} />
- </ButtonIcon>
+ <ClearButton
+ className="button-tiny"
+ iconProps={{ size: 12, thin: true }}
+ onClick={props.onClose}
+ />
</div>
<div className="notifications-sidebar-content">
{loading ? (
diff --git a/server/sonar-web/src/main/js/app/components/notifications/__tests__/__snapshots__/NotificationsSidebar-test.tsx.snap b/server/sonar-web/src/main/js/app/components/notifications/__tests__/__snapshots__/NotificationsSidebar-test.tsx.snap
index 321569b2d0b..ddcd230ef57 100644
--- a/server/sonar-web/src/main/js/app/components/notifications/__tests__/__snapshots__/NotificationsSidebar-test.tsx.snap
+++ b/server/sonar-web/src/main/js/app/components/notifications/__tests__/__snapshots__/NotificationsSidebar-test.tsx.snap
@@ -135,17 +135,16 @@ exports[`#NotificationSidebar should render correctly if there are new features
<h3>
embed_docs.whats_new
</h3>
- <ButtonIcon
+ <ClearButton
className="button-tiny"
- color="#cdcdcd"
+ iconProps={
+ Object {
+ "size": 12,
+ "thin": true,
+ }
+ }
onClick={[MockFunction]}
- >
- <ClearIcon
- fill="#444"
- size={12}
- thin={true}
- />
- </ButtonIcon>
+ />
</div>
<div
className="notifications-sidebar-content"
@@ -176,17 +175,16 @@ exports[`#NotificationSidebar should render correctly if there are new features
<h3>
embed_docs.whats_new
</h3>
- <ButtonIcon
+ <ClearButton
className="button-tiny"
- color="#cdcdcd"
+ iconProps={
+ Object {
+ "size": 12,
+ "thin": true,
+ }
+ }
onClick={[MockFunction]}
- >
- <ClearIcon
- fill="#444"
- size={12}
- thin={true}
- />
- </ButtonIcon>
+ />
</div>
<div
className="notifications-sidebar-content"
diff --git a/server/sonar-web/src/main/js/apps/create/organization/AutoOrganizationCreate.tsx b/server/sonar-web/src/main/js/apps/create/organization/AutoOrganizationCreate.tsx
index a9193117774..99c5c5028e7 100644
--- a/server/sonar-web/src/main/js/apps/create/organization/AutoOrganizationCreate.tsx
+++ b/server/sonar-web/src/main/js/apps/create/organization/AutoOrganizationCreate.tsx
@@ -25,8 +25,7 @@ import OrganizationDetailsStep from './OrganizationDetailsStep';
import PlanStep from './PlanStep';
import { Step } from './utils';
import { Alert } from '../../../components/ui/Alert';
-import { ButtonIcon } from '../../../components/ui/buttons';
-import ClearIcon from '../../../components/icons-components/ClearIcon';
+import { ClearButton } from '../../../components/ui/buttons';
import RadioToggle from '../../../components/controls/RadioToggle';
import { bindAlmOrganization } from '../../../api/alm-integration';
import { sanitizeAlmId, getAlmMembersUrl, isGithub } from '../../../helpers/almIntegrations';
@@ -137,9 +136,7 @@ export default class AutoOrganizationCreate extends React.PureComponent<Props, S
name: <strong>{almOrganization.name}</strong>
}}
/>
- <ButtonIcon className="little-spacer-left" onClick={this.props.handleCancelImport}>
- <ClearIcon />
- </ButtonIcon>
+ <ClearButton className="little-spacer-left" onClick={this.props.handleCancelImport} />
</p>
{hasUnboundOrgs && (
diff --git a/server/sonar-web/src/main/js/apps/create/organization/AutoPersonalOrganizationBind.tsx b/server/sonar-web/src/main/js/apps/create/organization/AutoPersonalOrganizationBind.tsx
index a97e49ed951..9a1afec98b4 100644
--- a/server/sonar-web/src/main/js/apps/create/organization/AutoPersonalOrganizationBind.tsx
+++ b/server/sonar-web/src/main/js/apps/create/organization/AutoPersonalOrganizationBind.tsx
@@ -23,9 +23,8 @@ import OrganizationDetailsForm from './OrganizationDetailsForm';
import OrganizationDetailsStep from './OrganizationDetailsStep';
import PlanStep from './PlanStep';
import { Step } from './utils';
-import ClearIcon from '../../../components/icons-components/ClearIcon';
+import { ClearButton } from '../../../components/ui/buttons';
import OrganizationAvatar from '../../../components/common/OrganizationAvatar';
-import { ButtonIcon } from '../../../components/ui/buttons';
import { getBaseUrl } from '../../../helpers/urls';
import { translate } from '../../../helpers/l10n';
import { sanitizeAlmId } from '../../../helpers/almIntegrations';
@@ -98,9 +97,7 @@ export default class AutoPersonalOrganizationBind extends React.PureComponent<Pr
personalName: importPersonalOrg && <strong>{importPersonalOrg.name}</strong>
}}
/>
- <ButtonIcon className="little-spacer-left" onClick={this.props.handleCancelImport}>
- <ClearIcon />
- </ButtonIcon>
+ <ClearButton className="little-spacer-left" onClick={this.props.handleCancelImport} />
</div>
<OrganizationDetailsForm
keyReadOnly={true}
diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoOrganizationCreate-test.tsx b/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoOrganizationCreate-test.tsx
index 0e5500e5160..1ce72fbeece 100644
--- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoOrganizationCreate-test.tsx
+++ b/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoOrganizationCreate-test.tsx
@@ -62,7 +62,7 @@ it('should allow to cancel org import', () => {
const handleCancelImport = jest.fn().mockResolvedValue({ key: 'foo' });
const wrapper = shallowRender({ handleCancelImport });
- click(wrapper.find('ButtonIcon'));
+ click(wrapper.find('ClearButton'));
expect(handleCancelImport).toBeCalled();
});
diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoPersonalOrganizationBind-test.tsx b/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoPersonalOrganizationBind-test.tsx
index 8d9282c3f10..a66aa36b757 100644
--- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoPersonalOrganizationBind-test.tsx
+++ b/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoPersonalOrganizationBind-test.tsx
@@ -56,7 +56,7 @@ it('should allow to cancel org import', () => {
handleCancelImport
});
- click(wrapper.find('ButtonIcon'));
+ click(wrapper.find('ClearButton'));
expect(handleCancelImport).toBeCalled();
});
diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoOrganizationCreate-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoOrganizationCreate-test.tsx.snap
index 89856c1c8b3..9b74fb68d47 100644
--- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoOrganizationCreate-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoOrganizationCreate-test.tsx.snap
@@ -31,12 +31,10 @@ exports[`should display choice between import or creation 1`] = `
}
}
/>
- <ButtonIcon
+ <ClearButton
className="little-spacer-left"
onClick={[MockFunction]}
- >
- <ClearIcon />
- </ButtonIcon>
+ />
</p>
<RadioToggle
disabled={false}
@@ -132,12 +130,10 @@ exports[`should render prefilled and create org 1`] = `
}
}
/>
- <ButtonIcon
+ <ClearButton
className="little-spacer-left"
onClick={[MockFunction]}
- >
- <ClearIcon />
- </ButtonIcon>
+ />
</p>
</div>
<OrganizationDetailsForm
diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoPersonalOrganizationBind-test.tsx.snap b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoPersonalOrganizationBind-test.tsx.snap
index 0d4420b06ce..d9ad62a78b2 100644
--- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoPersonalOrganizationBind-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/create/organization/__tests__/__snapshots__/AutoPersonalOrganizationBind-test.tsx.snap
@@ -40,12 +40,10 @@ exports[`should render correctly 1`] = `
}
}
/>
- <ButtonIcon
+ <ClearButton
className="little-spacer-left"
onClick={[MockFunction]}
- >
- <ClearIcon />
- </ButtonIcon>
+ />
</div>
<OrganizationDetailsForm
keyReadOnly={true}
diff --git a/server/sonar-web/src/main/js/apps/overview/meta/MetaLink.tsx b/server/sonar-web/src/main/js/apps/overview/meta/MetaLink.tsx
index 0ce5d2b5419..aff3dd00055 100644
--- a/server/sonar-web/src/main/js/apps/overview/meta/MetaLink.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/meta/MetaLink.tsx
@@ -18,10 +18,9 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import ClearIcon from '../../../components/icons-components/ClearIcon';
import ProjectLinkIcon from '../../../components/icons-components/ProjectLinkIcon';
import isValidUri from '../../../app/utils/isValidUri';
-import { ButtonIcon } from '../../../components/ui/buttons';
+import { ClearButton } from '../../../components/ui/buttons';
import { getLinkName } from '../../projectLinks/utils';
interface Props {
@@ -65,7 +64,7 @@ export default class MetaLink extends React.PureComponent<Props, State> {
{!iconOnly && linkTitle}
</a>
{this.state.expanded && (
- <div className="little-spacer-top">
+ <div className="little-spacer-top display-flex-center">
<input
className="overview-key width-80"
onClick={this.handleSelect}
@@ -73,9 +72,7 @@ export default class MetaLink extends React.PureComponent<Props, State> {
type="text"
value={link.url}
/>
- <ButtonIcon className="little-spacer-left" onClick={this.handleCollapse}>
- <ClearIcon />
- </ButtonIcon>
+ <ClearButton className="little-spacer-left" onClick={this.handleCollapse} />
</div>
)}
</li>
diff --git a/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaLink-test.tsx b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaLink-test.tsx
index 3f3cea24583..e7b0ad368d0 100644
--- a/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaLink-test.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/MetaLink-test.tsx
@@ -67,6 +67,6 @@ it('should expand and collapse dangerous link', () => {
// collapse with button
click(wrapper.find('a'));
expect(wrapper.state('expanded')).toBe(true);
- click(wrapper.find('ButtonIcon'));
+ click(wrapper.find('ClearButton'));
expect(wrapper.state('expanded')).toBe(false);
});
diff --git a/server/sonar-web/src/main/js/apps/overview/meta/__tests__/__snapshots__/MetaLink-test.tsx.snap b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/__snapshots__/MetaLink-test.tsx.snap
index eeef601d561..773b22685c1 100644
--- a/server/sonar-web/src/main/js/apps/overview/meta/__tests__/__snapshots__/MetaLink-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/overview/meta/__tests__/__snapshots__/MetaLink-test.tsx.snap
@@ -36,7 +36,7 @@ exports[`should expand and collapse dangerous link 2`] = `
Dangerous
</a>
<div
- className="little-spacer-top"
+ className="little-spacer-top display-flex-center"
>
<input
className="overview-key width-80"
@@ -45,12 +45,10 @@ exports[`should expand and collapse dangerous link 2`] = `
type="text"
value="javascript:alert(\\"hi\\")"
/>
- <ButtonIcon
+ <ClearButton
className="little-spacer-left"
onClick={[Function]}
- >
- <ClearIcon />
- </ButtonIcon>
+ />
</div>
</li>
`;
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendItem.tsx b/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendItem.tsx
index 7fd415ce9e5..5d440346cb5 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendItem.tsx
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendItem.tsx
@@ -19,11 +19,9 @@
*/
import * as React from 'react';
import * as classNames from 'classnames';
-import * as theme from '../../../app/theme';
import AlertWarnIcon from '../../../components/icons-components/AlertWarnIcon';
import ChartLegendIcon from '../../../components/icons-components/ChartLegendIcon';
-import { ButtonIcon } from '../../../components/ui/buttons';
-import ClearIcon from '../../../components/icons-components/ClearIcon';
+import { ClearButton } from '../../../components/ui/buttons';
interface Props {
className?: string;
@@ -56,12 +54,11 @@ export default class GraphsLegendItem extends React.PureComponent<Props> {
)}
<span className="text-middle">{this.props.name}</span>
{isActionable && (
- <ButtonIcon
+ <ClearButton
className="button-tiny spacer-left text-middle"
- color={theme.gray60}
- onClick={this.handleClick}>
- <ClearIcon size={12} />
- </ButtonIcon>
+ iconProps={{ size: 12 }}
+ onClick={this.handleClick}
+ />
)}
</span>
);
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendItem-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendItem-test.tsx.snap
index 19d9bb6c1d8..68c3c7d6f24 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendItem-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendItem-test.tsx.snap
@@ -29,15 +29,15 @@ exports[`should render correctly an actionable legend 1`] = `
>
Foo
</span>
- <ButtonIcon
+ <ClearButton
className="button-tiny spacer-left text-middle"
- color="#999"
+ iconProps={
+ Object {
+ "size": 12,
+ }
+ }
onClick={[Function]}
- >
- <ClearIcon
- size={12}
- />
- </ButtonIcon>
+ />
</span>
`;
diff --git a/server/sonar-web/src/main/js/apps/tutorials/components/__tests__/TokenStep-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/components/__tests__/TokenStep-test.tsx
index bdac3e8dc93..a51a10d3f3a 100644
--- a/server/sonar-web/src/main/js/apps/tutorials/components/__tests__/TokenStep-test.tsx
+++ b/server/sonar-web/src/main/js/apps/tutorials/components/__tests__/TokenStep-test.tsx
@@ -28,8 +28,6 @@ jest.mock('../../../../api/user-tokens', () => ({
revokeToken: () => Promise.resolve()
}));
-jest.mock('../../../../components/icons-components/ClearIcon');
-
const currentUser = { login: 'user' };
it('generates token', async () => {
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 93ad3ac3910..f7155206822 100644
--- a/server/sonar-web/src/main/js/components/controls/DateInput.tsx
+++ b/server/sonar-web/src/main/js/components/controls/DateInput.tsx
@@ -29,12 +29,10 @@ import * as subMonths from 'date-fns/sub_months';
import OutsideClickHandler from './OutsideClickHandler';
import Select from './Select';
import { lazyLoad } from '../lazyLoad';
-import * as theme from '../../app/theme';
import CalendarIcon from '../icons-components/CalendarIcon';
import ChevronLeftIcon from '../icons-components/ChevronLeftIcon';
import ChevronRightIcon from '../icons-components/ChevronRightcon';
-import ClearIcon from '../icons-components/ClearIcon';
-import { ButtonIcon } from '../ui/buttons';
+import { ButtonIcon, ClearButton } from '../ui/buttons';
import { getShortMonthName, getWeekDayName, getShortWeekDayName } from '../../helpers/l10n';
import './DayPicker.css';
import './styles.css';
@@ -164,12 +162,11 @@ export default class DateInput extends React.PureComponent<Props, State> {
/>
<CalendarIcon className="date-input-control-icon" fill="" />
{this.props.value !== undefined && (
- <ButtonIcon
+ <ClearButton
className="button-tiny date-input-control-reset"
- color={theme.gray60}
- onClick={this.handleResetClick}>
- <ClearIcon size={12} />
- </ButtonIcon>
+ iconProps={{ size: 12 }}
+ onClick={this.handleResetClick}
+ />
)}
{this.state.open && (
<div className="date-input-calendar">
diff --git a/server/sonar-web/src/main/js/components/controls/GlobalMessages.tsx b/server/sonar-web/src/main/js/components/controls/GlobalMessages.tsx
index f72d57e1360..037aabf5ff3 100644
--- a/server/sonar-web/src/main/js/components/controls/GlobalMessages.tsx
+++ b/server/sonar-web/src/main/js/components/controls/GlobalMessages.tsx
@@ -19,8 +19,8 @@
*/
import * as React from 'react';
import * as classNames from 'classnames';
-import ClearIcon from '../icons-components/ClearIcon';
-import { ButtonIcon } from '../ui/buttons';
+import { ClearButton } from '../ui/buttons';
+import { cutLongWords } from '../../helpers/path';
import './GlobalMessages.css';
interface Message {
@@ -29,44 +29,49 @@ interface Message {
message: string;
}
-interface Props {
+export interface Props {
closeGlobalMessage: (id: string) => void;
messages: Message[];
}
-export default class GlobalMessages extends React.PureComponent<Props> {
- cutLongWords = (message: string) => {
- return message
- .split(' ')
- .map(word => (word.length > 35 ? word.substr(0, 35) + '...' : word))
- .join(' ');
+export default function GlobalMessages({ closeGlobalMessage, messages }: Props) {
+ if (messages.length === 0) {
+ return null;
+ }
+
+ return (
+ <div className="processes-container">
+ {messages.map(message => (
+ <GlobalMessage closeGlobalMessage={closeGlobalMessage} key={message.id} message={message} />
+ ))}
+ </div>
+ );
+}
+
+export class GlobalMessage extends React.PureComponent<{
+ closeGlobalMessage: (id: string) => void;
+ message: Message;
+}> {
+ handleClose = () => {
+ this.props.closeGlobalMessage(this.props.message.id);
};
- renderMessage = (message: Message) => {
- const className = classNames('process-spinner', 'shown', {
- 'process-spinner-failed': message.level === 'ERROR',
- 'process-spinner-success': message.level === 'SUCCESS'
- });
+ render() {
+ const { message } = this.props;
return (
- <div className={className} key={message.id}>
- {this.cutLongWords(message.message)}
- <ButtonIcon
+ <div
+ className={classNames('process-spinner', 'shown', {
+ 'process-spinner-failed': message.level === 'ERROR',
+ 'process-spinner-success': message.level === 'SUCCESS'
+ })}
+ key={message.id}>
+ {cutLongWords(message.message)}
+ <ClearButton
className="button-small process-spinner-close"
color="#fff"
- onClick={() => this.props.closeGlobalMessage(message.id)}>
- <ClearIcon />
- </ButtonIcon>
+ onClick={this.handleClose}
+ />
</div>
);
- };
-
- render() {
- const { messages } = this.props;
-
- if (messages.length === 0) {
- return null;
- }
-
- return <div className="processes-container">{messages.map(this.renderMessage)}</div>;
}
}
diff --git a/server/sonar-web/src/main/js/components/controls/SearchBox.tsx b/server/sonar-web/src/main/js/components/controls/SearchBox.tsx
index 2d2b5669917..0a6d8e62f09 100644
--- a/server/sonar-web/src/main/js/components/controls/SearchBox.tsx
+++ b/server/sonar-web/src/main/js/components/controls/SearchBox.tsx
@@ -20,11 +20,9 @@
import * as React from 'react';
import * as classNames from 'classnames';
import { debounce, Cancelable } from 'lodash';
-import ClearIcon from '../icons-components/ClearIcon';
import SearchIcon from '../icons-components/SearchIcon';
import DeferredSpinner from '../common/DeferredSpinner';
-import { ButtonIcon } from '../ui/buttons';
-import * as theme from '../../app/theme';
+import { ClearButton } from '../ui/buttons';
import { translateWithParameters, translate } from '../../helpers/l10n';
import './SearchBox.css';
@@ -156,12 +154,11 @@ export default class SearchBox extends React.PureComponent<Props, State> {
</DeferredSpinner>
{value && (
- <ButtonIcon
+ <ClearButton
className="button-tiny search-box-clear"
- color={theme.gray60}
- onClick={this.handleResetClick}>
- <ClearIcon size={12} />
- </ButtonIcon>
+ iconProps={{ size: 12 }}
+ onClick={this.handleResetClick}
+ />
)}
{tooShort && (
diff --git a/server/sonar-web/src/main/js/components/controls/Select.tsx b/server/sonar-web/src/main/js/components/controls/Select.tsx
index 28ce819edbf..05be7b0c5e3 100644
--- a/server/sonar-web/src/main/js/components/controls/Select.tsx
+++ b/server/sonar-web/src/main/js/components/controls/Select.tsx
@@ -19,9 +19,7 @@
*/
import * as React from 'react';
import { ReactSelectProps, ReactCreatableSelectProps, ReactAsyncSelectProps } from 'react-select';
-import * as theme from '../../app/theme';
-import ClearIcon from '../icons-components/ClearIcon';
-import { ButtonIcon } from '../ui/buttons';
+import { ClearButton } from '../ui/buttons';
import { lazyLoad } from '../lazyLoad';
import './react-select.css';
@@ -31,11 +29,7 @@ const ReactCreatable = lazyLoad(() => ReactSelectLib.then(lib => ({ default: lib
const ReactAsync = lazyLoad(() => ReactSelectLib.then(lib => ({ default: lib.Async })));
function renderInput() {
- return (
- <ButtonIcon className="button-tiny spacer-left text-middle" color={theme.gray60}>
- <ClearIcon size={12} />
- </ButtonIcon>
- );
+ return <ClearButton className="button-tiny spacer-left text-middle" iconProps={{ size: 12 }} />;
}
interface WithInnerRef {
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/GlobalMessages-test.tsx b/server/sonar-web/src/main/js/components/controls/__tests__/GlobalMessages-test.tsx
new file mode 100644
index 00000000000..f4632492e35
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/controls/__tests__/GlobalMessages-test.tsx
@@ -0,0 +1,50 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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 { shallow } from 'enzyme';
+import GlobalMessages, { Props } from '../GlobalMessages';
+
+it('should not render when no message', () => {
+ expect(shallowRender({ messages: [] }).type()).toBeNull();
+});
+
+it('should render correctly with a message', () => {
+ const wrapper = shallowRender();
+ expect(wrapper).toMatchSnapshot();
+ expect(
+ wrapper
+ .find('GlobalMessage')
+ .first()
+ .dive()
+ ).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<Props> = {}) {
+ return shallow(
+ <GlobalMessages
+ closeGlobalMessage={jest.fn()}
+ messages={[
+ { id: '1', level: 'ERROR', message: 'Test' },
+ { id: '2', level: 'ERROR', message: 'Test 2' }
+ ]}
+ {...props}
+ />
+ );
+}
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateInput-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateInput-test.tsx.snap
index f4dc4048d63..5b49a50d0f5 100644
--- a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateInput-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/DateInput-test.tsx.snap
@@ -43,15 +43,15 @@ exports[`should render 2`] = `
className="date-input-control-icon"
fill=""
/>
- <ButtonIcon
+ <ClearButton
className="button-tiny date-input-control-reset"
- color="#999"
+ iconProps={
+ Object {
+ "size": 12,
+ }
+ }
onClick={[Function]}
- >
- <ClearIcon
- size={12}
- />
- </ButtonIcon>
+ />
</span>
</OutsideClickHandler>
`;
@@ -76,15 +76,15 @@ exports[`should render 3`] = `
className="date-input-control-icon"
fill=""
/>
- <ButtonIcon
+ <ClearButton
className="button-tiny date-input-control-reset"
- color="#999"
+ iconProps={
+ Object {
+ "size": 12,
+ }
+ }
onClick={[Function]}
- >
- <ClearIcon
- size={12}
- />
- </ButtonIcon>
+ />
<div
className="date-input-calendar"
>
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/GlobalMessages-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/GlobalMessages-test.tsx.snap
new file mode 100644
index 00000000000..cf1235d7cd2
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/GlobalMessages-test.tsx.snap
@@ -0,0 +1,44 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly with a message 1`] = `
+<div
+ className="processes-container"
+>
+ <GlobalMessage
+ closeGlobalMessage={[MockFunction]}
+ key="1"
+ message={
+ Object {
+ "id": "1",
+ "level": "ERROR",
+ "message": "Test",
+ }
+ }
+ />
+ <GlobalMessage
+ closeGlobalMessage={[MockFunction]}
+ key="2"
+ message={
+ Object {
+ "id": "2",
+ "level": "ERROR",
+ "message": "Test 2",
+ }
+ }
+ />
+</div>
+`;
+
+exports[`should render correctly with a message 2`] = `
+<div
+ className="process-spinner shown process-spinner-failed"
+ key="1"
+>
+ Test
+ <ClearButton
+ className="button-small process-spinner-close"
+ color="#fff"
+ onClick={[Function]}
+ />
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SearchBox-test.tsx.snap b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SearchBox-test.tsx.snap
index e7183478c77..3a61b8d4358 100644
--- a/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SearchBox-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/SearchBox-test.tsx.snap
@@ -24,14 +24,14 @@ exports[`renders 1`] = `
className="search-box-magnifier"
/>
</DeferredSpinner>
- <ButtonIcon
+ <ClearButton
className="button-tiny search-box-clear"
- color="#999"
+ iconProps={
+ Object {
+ "size": 12,
+ }
+ }
onClick={[Function]}
- >
- <ClearIcon
- size={12}
- />
- </ButtonIcon>
+ />
</div>
`;
diff --git a/server/sonar-web/src/main/js/components/ui/NewsBox.tsx b/server/sonar-web/src/main/js/components/ui/NewsBox.tsx
index 8fe54f49495..b9ba6bca68e 100644
--- a/server/sonar-web/src/main/js/components/ui/NewsBox.tsx
+++ b/server/sonar-web/src/main/js/components/ui/NewsBox.tsx
@@ -19,9 +19,7 @@
*/
import * as React from 'react';
import * as classNames from 'classnames';
-import { ButtonIcon } from './buttons';
-import ClearIcon from '../icons-components/ClearIcon';
-import * as theme from '../../app/theme';
+import { ClearButton } from './buttons';
import { translate } from '../../helpers/l10n';
import './NewsBox.css';
@@ -40,9 +38,11 @@ export default function NewsBox({ children, className, onClose, title }: Props)
<span className="badge badge-new spacer-right">{translate('new')}</span>
<strong>{title}</strong>
</div>
- <ButtonIcon className="button-tiny" color={theme.gray80} onClick={onClose}>
- <ClearIcon fill={theme.baseFontColor} size={12} thin={true} />
- </ButtonIcon>
+ <ClearButton
+ className="button-tiny"
+ iconProps={{ size: 12, then: true }}
+ onClick={onClose}
+ />
</div>
<div className="big-spacer-top note">{children}</div>
</div>
diff --git a/server/sonar-web/src/main/js/components/ui/__tests__/NewsBox-test.tsx b/server/sonar-web/src/main/js/components/ui/__tests__/NewsBox-test.tsx
index e6758a4ec54..e3e93e0e266 100644
--- a/server/sonar-web/src/main/js/components/ui/__tests__/NewsBox-test.tsx
+++ b/server/sonar-web/src/main/js/components/ui/__tests__/NewsBox-test.tsx
@@ -29,7 +29,7 @@ it('should render correctly', () => {
it('should call onClose', () => {
const onClose = jest.fn();
const wrapper = shallowRender({ onClose });
- click(wrapper.find('ButtonIcon'));
+ click(wrapper.find('ClearButton'));
expect(onClose).toBeCalled();
});
diff --git a/server/sonar-web/src/main/js/components/ui/__tests__/__snapshots__/NewsBox-test.tsx.snap b/server/sonar-web/src/main/js/components/ui/__tests__/__snapshots__/NewsBox-test.tsx.snap
index 068bf719d63..05b01c0a492 100644
--- a/server/sonar-web/src/main/js/components/ui/__tests__/__snapshots__/NewsBox-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/ui/__tests__/__snapshots__/NewsBox-test.tsx.snap
@@ -20,17 +20,16 @@ exports[`should render correctly 1`] = `
title
</strong>
</div>
- <ButtonIcon
+ <ClearButton
className="button-tiny"
- color="#cdcdcd"
+ iconProps={
+ Object {
+ "size": 12,
+ "then": true,
+ }
+ }
onClick={[MockFunction]}
- >
- <ClearIcon
- fill="#444"
- size={12}
- thin={true}
- />
- </ButtonIcon>
+ />
</div>
<div
className="big-spacer-top note"
diff --git a/server/sonar-web/src/main/js/components/ui/buttons.tsx b/server/sonar-web/src/main/js/components/ui/buttons.tsx
index c8866c5ac4a..d4d15ae9475 100644
--- a/server/sonar-web/src/main/js/components/ui/buttons.tsx
+++ b/server/sonar-web/src/main/js/components/ui/buttons.tsx
@@ -21,10 +21,12 @@ import * as React from 'react';
import * as classNames from 'classnames';
import * as theme from '../../app/theme';
import ChevronRightIcon from '../icons-components/ChevronRightcon';
+import ClearIcon from '../icons-components/ClearIcon';
import DeleteIcon from '../icons-components/DeleteIcon';
import EditIcon from '../icons-components/EditIcon';
import Tooltip from '../controls/Tooltip';
import './buttons.css';
+import { IconProps } from '../icons-components/Icon';
type AllowedButtonAttributes = Pick<
React.ButtonHTMLAttributes<HTMLButtonElement>,
@@ -90,12 +92,11 @@ export function ResetButtonLink(props: T.Omit<ButtonProps, 'type'>) {
return <ButtonLink {...props} type="reset" />;
}
-interface ButtonIconProps {
+interface ButtonIconProps extends ButtonProps {
className?: string;
color?: string;
onClick?: () => void;
tooltip?: string;
- [x: string]: any;
}
export function ButtonIcon(props: ButtonIconProps) {
@@ -118,24 +119,32 @@ export function ButtonIcon(props: ButtonIconProps) {
return buttonComponent;
}
-interface ActionButtonProps {
+interface ActionButtonProps extends ButtonIconProps {
className?: string;
+ iconProps?: IconProps;
onClick?: () => void;
- [x: string]: any;
}
-export function DeleteButton(props: ActionButtonProps) {
+export function ClearButton({ color = theme.gray60, iconProps = {}, ...props }: ActionButtonProps) {
+ return (
+ <ButtonIcon color={color} {...props}>
+ <ClearIcon {...iconProps} />
+ </ButtonIcon>
+ );
+}
+
+export function DeleteButton({ iconProps = {}, ...props }: ActionButtonProps) {
return (
<ButtonIcon color={theme.red} {...props}>
- <DeleteIcon />
+ <DeleteIcon {...iconProps} />
</ButtonIcon>
);
}
-export function EditButton(props: ActionButtonProps) {
+export function EditButton({ iconProps = {}, ...props }: ActionButtonProps) {
return (
<ButtonIcon {...props}>
- <EditIcon />
+ <EditIcon {...iconProps} />
</ButtonIcon>
);
}
diff --git a/server/sonar-web/src/main/js/components/workspace/WorkspaceNavItem.tsx b/server/sonar-web/src/main/js/components/workspace/WorkspaceNavItem.tsx
index 51505c7dbaa..bb94c03bc04 100644
--- a/server/sonar-web/src/main/js/components/workspace/WorkspaceNavItem.tsx
+++ b/server/sonar-web/src/main/js/components/workspace/WorkspaceNavItem.tsx
@@ -18,8 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import ClearIcon from '../icons-components/ClearIcon';
-import { ButtonIcon } from '../ui/buttons';
+import { ClearButton } from '../ui/buttons';
export interface Props {
children: React.ReactNode;
@@ -40,12 +39,12 @@ export default class WorkspaceNavItem extends React.PureComponent<Props> {
<a className="workspace-nav-item-link" href="#" onClick={this.handleNameClick}>
{this.props.children}
</a>
- <ButtonIcon
+ <ClearButton
className="js-close workspace-nav-item-close workspace-header-icon button-small little-spacer-left"
color="#fff"
- onClick={this.props.onClose}>
- <ClearIcon fill={undefined} size={12} />
- </ButtonIcon>
+ iconProps={{ size: 12 }}
+ onClick={this.props.onClose}
+ />
</li>
);
}
diff --git a/server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceNavItem-test.tsx b/server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceNavItem-test.tsx
index fabed55b690..90ec99f0db8 100644
--- a/server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceNavItem-test.tsx
+++ b/server/sonar-web/src/main/js/components/workspace/__tests__/WorkspaceNavItem-test.tsx
@@ -29,7 +29,7 @@ it('should render', () => {
it('should close', () => {
const onClose = jest.fn();
const wrapper = shallowRender({ onClose });
- click(wrapper.find('ButtonIcon'));
+ click(wrapper.find('ClearButton'));
expect(onClose).toBeCalled();
});
diff --git a/server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceNavItem-test.tsx.snap b/server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceNavItem-test.tsx.snap
index 3834b942dba..92280457eef 100644
--- a/server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceNavItem-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/workspace/__tests__/__snapshots__/WorkspaceNavItem-test.tsx.snap
@@ -13,14 +13,15 @@ exports[`should render 1`] = `
id="workspace-nav-item"
/>
</a>
- <ButtonIcon
+ <ClearButton
className="js-close workspace-nav-item-close workspace-header-icon button-small little-spacer-left"
color="#fff"
+ iconProps={
+ Object {
+ "size": 12,
+ }
+ }
onClick={[MockFunction]}
- >
- <ClearIcon
- size={12}
- />
- </ButtonIcon>
+ />
</li>
`;
diff --git a/server/sonar-web/src/main/js/helpers/__tests__/path-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/path-test.ts
index ffd53ce4df0..a7f4b1dd993 100644
--- a/server/sonar-web/src/main/js/helpers/__tests__/path-test.ts
+++ b/server/sonar-web/src/main/js/helpers/__tests__/path-test.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { collapsedDirFromPath, fileFromPath } from '../path';
+import { collapsedDirFromPath, cutLongWords, fileFromPath } from '../path';
describe('#collapsedDirFromPath()', () => {
it('should return null when pass null', () => {
@@ -66,3 +66,15 @@ describe('#fileFromPath()', () => {
expect(fileFromPath('src/main/file')).toBe('file');
});
});
+
+describe('#cutLongWords', () => {
+ it('should cut the long work in the middle', () => {
+ expect(cutLongWords('This is a reallylongwordthatdontexistforthe test')).toBe(
+ 'This is a reallylongwordthatdontexistfor... test'
+ );
+ });
+
+ it('should not cut anything', () => {
+ expect(cutLongWords('This is a test')).toBe('This is a test');
+ });
+});
diff --git a/server/sonar-web/src/main/js/helpers/path.ts b/server/sonar-web/src/main/js/helpers/path.ts
index bbb2ca4b8c6..56a5be1bcdc 100644
--- a/server/sonar-web/src/main/js/helpers/path.ts
+++ b/server/sonar-web/src/main/js/helpers/path.ts
@@ -95,6 +95,13 @@ export function splitPath(path: string) {
};
}
+export function cutLongWords(str: string, limit = 30) {
+ return str
+ .split(' ')
+ .map(word => (word.length > limit ? word.substr(0, limit) + '...' : word))
+ .join(' ');
+}
+
export function limitComponentName(str: string, limit = 30): string {
if (typeof str === 'string') {
return str.length > limit ? str.substr(0, limit) + '...' : str;