]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19248 Add Hotspot Rating to component library
authorstanislavh <stanislav.honcharov@sonarsource.com>
Tue, 9 May 2023 13:04:46 +0000 (15:04 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 10 May 2023 20:05:28 +0000 (20:05 +0000)
server/sonar-web/design-system/src/components/HotspotRating.tsx [new file with mode: 0644]
server/sonar-web/design-system/src/components/__tests__/HotspotRating-test.tsx [new file with mode: 0644]
server/sonar-web/design-system/src/components/__tests__/__snapshots__/HotspotRating-test.tsx.snap [new file with mode: 0644]
server/sonar-web/design-system/src/components/icons/FilterIcon.tsx [new file with mode: 0644]
server/sonar-web/design-system/src/components/icons/index.ts
server/sonar-web/design-system/src/components/index.ts
server/sonar-web/design-system/src/types/measures.ts

diff --git a/server/sonar-web/design-system/src/components/HotspotRating.tsx b/server/sonar-web/design-system/src/components/HotspotRating.tsx
new file mode 100644 (file)
index 0000000..db2c788
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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 { HotspotRatingEnum, HotspotRatingLabel } from '../types/measures';
+import { SeverityCriticalIcon, SeverityMajorIcon, SeverityMinorIcon } from './icons';
+
+interface Props extends React.AriaAttributes {
+  className?: string;
+  rating?: HotspotRatingLabel;
+}
+
+export function HotspotRating({ className, rating = HotspotRatingEnum.LOW, ...rest }: Props) {
+  const ratings = {
+    [HotspotRatingEnum.HIGH]: HotspotRatingHigh,
+    [HotspotRatingEnum.MEDIUM]: HotspotRatingMedium,
+    [HotspotRatingEnum.LOW]: HotspotRatingLow,
+  };
+
+  const Rating = ratings[rating];
+
+  return <Rating className={className} {...rest} />;
+}
+
+function HotspotRatingHigh(props: Props) {
+  return <SeverityCriticalIcon {...props} fill="rating.E" />;
+}
+
+function HotspotRatingMedium(props: Props) {
+  return <SeverityMajorIcon {...props} fill="rating.D" />;
+}
+
+function HotspotRatingLow(props: Props) {
+  return <SeverityMinorIcon {...props} fill="rating.C" />;
+}
diff --git a/server/sonar-web/design-system/src/components/__tests__/HotspotRating-test.tsx b/server/sonar-web/design-system/src/components/__tests__/HotspotRating-test.tsx
new file mode 100644 (file)
index 0000000..e3cd439
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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 { screen } from '@testing-library/react';
+import { render } from '../../helpers/testUtils';
+import { HotspotRatingEnum } from '../../types/measures';
+import { HotspotRating } from '../HotspotRating';
+
+it('should render HotspotRating with default LOW rating', () => {
+  renderHotspotRating(undefined, 'label');
+  expect(screen.getByLabelText('label')).toMatchSnapshot();
+});
+
+it.each(Object.values(HotspotRatingEnum))(
+  'should render HotspotRating with %s rating',
+  (rating) => {
+    renderHotspotRating(rating, 'label');
+    expect(screen.getByLabelText('label')).toMatchSnapshot();
+  }
+);
+
+function renderHotspotRating(rating?: HotspotRatingEnum, label?: string) {
+  return render(<HotspotRating aria-label={label} rating={rating} />);
+}
diff --git a/server/sonar-web/design-system/src/components/__tests__/__snapshots__/HotspotRating-test.tsx.snap b/server/sonar-web/design-system/src/components/__tests__/__snapshots__/HotspotRating-test.tsx.snap
new file mode 100644 (file)
index 0000000..454aec9
--- /dev/null
@@ -0,0 +1,118 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render HotspotRating with HIGH rating 1`] = `
+<svg
+  aria-hidden="false"
+  aria-label="label"
+  fill="none"
+  height="1rem"
+  role="img"
+  style="clip-rule: evenodd; display: inline-block; fill-rule: evenodd; user-select: none; vertical-align: middle; stroke-linejoin: round; stroke-miterlimit: 1.414;"
+  version="1.1"
+  viewBox="0 0 16 16"
+  width="1rem"
+  xml:space="preserve"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+>
+  <circle
+    cx="8"
+    cy="8"
+    fill="rgb(254,205,202)"
+    r="7"
+  />
+  <path
+    d="M5 6.67113C5 6.56986 5.05583 6.47727 5.14421 6.43198L7.88334 5.02823C7.95678 4.99059 8.04322 4.99059 8.11666 5.02823L10.8558 6.43198C10.9442 6.47727 11 6.56986 11 6.67113V10.7324C11 10.9191 10.8181 11.0483 10.6475 10.9827L8.0916 10.0003C8.03254 9.97763 7.96746 9.97763 7.9084 10.0003L5.35247 10.9827C5.18192 11.0483 5 10.9191 5 10.7324V6.67113Z"
+    fill="rgb(93,29,19)"
+  />
+</svg>
+`;
+
+exports[`should render HotspotRating with LOW rating 1`] = `
+<svg
+  aria-hidden="false"
+  aria-label="label"
+  fill="none"
+  height="1rem"
+  role="img"
+  style="clip-rule: evenodd; display: inline-block; fill-rule: evenodd; user-select: none; vertical-align: middle; stroke-linejoin: round; stroke-miterlimit: 1.414;"
+  version="1.1"
+  viewBox="0 0 16 16"
+  width="1rem"
+  xml:space="preserve"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+>
+  <circle
+    cx="8"
+    cy="8"
+    fill="rgb(252,233,163)"
+    r="7"
+  />
+  <path
+    d="M5.23223 6.93223L8 9.7L10.7678 6.93223"
+    stroke="rgb(102,64,15)"
+    stroke-linecap="round"
+    stroke-linejoin="round"
+    stroke-width="1.5"
+  />
+</svg>
+`;
+
+exports[`should render HotspotRating with MEDIUM rating 1`] = `
+<svg
+  aria-hidden="false"
+  aria-label="label"
+  fill="none"
+  height="1rem"
+  role="img"
+  style="clip-rule: evenodd; display: inline-block; fill-rule: evenodd; user-select: none; vertical-align: middle; stroke-linejoin: round; stroke-miterlimit: 1.414;"
+  version="1.1"
+  viewBox="0 0 16 16"
+  width="1rem"
+  xml:space="preserve"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+>
+  <circle
+    cx="8"
+    cy="8"
+    fill="rgb(255,214,175)"
+    r="7"
+  />
+  <path
+    d="M10.7678 9.5 8 6.73223 5.23223 9.5"
+    stroke="rgb(122,46,14)"
+    stroke-linecap="round"
+    stroke-linejoin="round"
+    stroke-width="1.5"
+  />
+</svg>
+`;
+
+exports[`should render HotspotRating with default LOW rating 1`] = `
+<svg
+  aria-hidden="false"
+  aria-label="label"
+  fill="none"
+  height="1rem"
+  role="img"
+  style="clip-rule: evenodd; display: inline-block; fill-rule: evenodd; user-select: none; vertical-align: middle; stroke-linejoin: round; stroke-miterlimit: 1.414;"
+  version="1.1"
+  viewBox="0 0 16 16"
+  width="1rem"
+  xml:space="preserve"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+>
+  <circle
+    cx="8"
+    cy="8"
+    fill="rgb(252,233,163)"
+    r="7"
+  />
+  <path
+    d="M5.23223 6.93223L8 9.7L10.7678 6.93223"
+    stroke="rgb(102,64,15)"
+    stroke-linecap="round"
+    stroke-linejoin="round"
+    stroke-width="1.5"
+  />
+</svg>
+`;
diff --git a/server/sonar-web/design-system/src/components/icons/FilterIcon.tsx b/server/sonar-web/design-system/src/components/icons/FilterIcon.tsx
new file mode 100644 (file)
index 0000000..652e541
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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 { FilterIcon as Icon } from '@primer/octicons-react';
+import { OcticonHoc } from './Icon';
+
+export const FilterIcon = OcticonHoc(Icon, 'FilterIcon');
index 5b4edbb95a4b92299bde1a89b122ecdd94dd2aec..9703f6660fbee594a84ed6907f01d1c3a3afcbbe 100644 (file)
@@ -28,6 +28,7 @@ export { CommentIcon } from './CommentIcon';
 export { DirectoryIcon } from './DirectoryIcon';
 export { ExecutionFlowIcon } from './ExecutionFlowIcon';
 export { FileIcon } from './FileIcon';
+export { FilterIcon } from './FilterIcon';
 export { FlagErrorIcon } from './FlagErrorIcon';
 export { FlagInfoIcon } from './FlagInfoIcon';
 export { FlagSuccessIcon } from './FlagSuccessIcon';
index 9164936c0486a34b510320d4e17329681ed04a5b..3a244823b8f1d77e245ae2f9145556e74cddfb53 100644 (file)
@@ -34,6 +34,7 @@ export { FailedQGConditionLink } from './FailedQGConditionLink';
 export { FlagMessage } from './FlagMessage';
 export * from './GenericAvatar';
 export * from './HighlightedSection';
+export { HotspotRating } from './HotspotRating';
 export { InputSearch } from './InputSearch';
 export * from './InputSelect';
 export * from './InteractiveIcon';
index 807118abe9499b7d784a2a74925f948d1d13d8d2..47afbd0b924f6b8d527687708bcc00e1c875e046 100644 (file)
@@ -47,3 +47,11 @@ export enum SizeEnum {
   XL = 'XL',
 }
 export type SizeLabel = keyof typeof SizeEnum;
+
+export enum HotspotRatingEnum {
+  LOW = 'LOW',
+  MEDIUM = 'MEDIUM',
+  HIGH = 'HIGH',
+}
+
+export type HotspotRatingLabel = keyof typeof HotspotRatingEnum;