diff --git a/client/src/app/components/Icons/IconWithLabel.tsx b/client/src/app/components/Icons/IconWithLabel.tsx
new file mode 100644
index 0000000000..e3725f5d68
--- /dev/null
+++ b/client/src/app/components/Icons/IconWithLabel.tsx
@@ -0,0 +1,24 @@
+import React, { FC, ReactElement, ReactNode } from "react";
+import { Flex, FlexItem } from "@patternfly/react-core";
+import { IconWithOptionalTooltip } from "./IconWithOptionalTooltip";
+
+export const IconWithLabel: FC<{
+ iconTooltipMessage?: string;
+ icon: ReactElement;
+ label: ReactNode;
+ hasTrailingItem?: boolean;
+ trailingItem?: ReactElement;
+}> = ({ iconTooltipMessage, icon, label, hasTrailingItem, trailingItem }) => (
+
+
+
+ {icon}
+
+
+ {label}
+ {hasTrailingItem && {trailingItem}}
+
+);
diff --git a/client/src/app/components/Icons/IconWithOptionalTooltip.tsx b/client/src/app/components/Icons/IconWithOptionalTooltip.tsx
new file mode 100644
index 0000000000..afd432c10e
--- /dev/null
+++ b/client/src/app/components/Icons/IconWithOptionalTooltip.tsx
@@ -0,0 +1,12 @@
+import React from "react";
+import { Tooltip } from "@patternfly/react-core";
+
+export const IconWithOptionalTooltip: React.FC<{
+ tooltipMessage?: string;
+ children: React.ReactElement;
+}> = ({ children, tooltipMessage }) =>
+ tooltipMessage ? (
+ {children}
+ ) : (
+ <>{children}>
+ );
diff --git a/client/src/app/components/IconedStatus.tsx b/client/src/app/components/Icons/IconedStatus.tsx
similarity index 80%
rename from client/src/app/components/IconedStatus.tsx
rename to client/src/app/components/Icons/IconedStatus.tsx
index 6dbf102e9c..0c26d8ee86 100644
--- a/client/src/app/components/IconedStatus.tsx
+++ b/client/src/app/components/Icons/IconedStatus.tsx
@@ -1,5 +1,5 @@
import React from "react";
-import { Flex, FlexItem, Icon, Tooltip } from "@patternfly/react-core";
+import { Icon, Tooltip } from "@patternfly/react-core";
import { useTranslation } from "react-i18next";
import CheckCircleIcon from "@patternfly/react-icons/dist/esm/icons/check-circle-icon";
import TimesCircleIcon from "@patternfly/react-icons/dist/esm/icons/times-circle-icon";
@@ -7,6 +7,7 @@ import InProgressIcon from "@patternfly/react-icons/dist/esm/icons/in-progress-i
import ExclamationCircleIcon from "@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon";
import UnknownIcon from "@patternfly/react-icons/dist/esm/icons/unknown-icon";
import TopologyIcon from "@patternfly/react-icons/dist/esm/icons/topology-icon";
+import { IconWithLabel } from "./IconWithLabel";
export type IconedStatusPreset =
| "InheritedReviews"
@@ -129,14 +130,6 @@ export const IconedStatus: React.FC = ({
},
};
const presetProps = preset && presets[preset];
- const IconWithOptionalTooltip: React.FC<{ children: React.ReactElement }> = ({
- children,
- }) =>
- presetProps?.tooltipMessage ? (
- {children}
- ) : (
- <>{children}>
- );
const getTooltipContent = () => {
switch (preset) {
@@ -164,28 +157,25 @@ export const IconedStatus: React.FC = ({
};
return (
-
-
-
-
- {icon || presetProps?.icon || }
-
-
-
- {label || presetProps?.label}
- {(preset === "InheritedReviews" ||
+
+ {icon || presetProps?.icon || }
+
+ }
+ label={label || presetProps?.label}
+ hasTrailingItem={
+ preset === "InheritedReviews" ||
preset === "InheritedAssessments" ||
preset === "InProgressInheritedAssessments" ||
- preset === "InProgressInheritedReviews") && (
-
-
-
-
-
- )}
-
+ preset === "InProgressInheritedReviews"
+ }
+ trailingItem={
+
+
+
+ }
+ />
);
};
diff --git a/client/src/app/components/Icons/index.ts b/client/src/app/components/Icons/index.ts
new file mode 100644
index 0000000000..6f6ef23d0c
--- /dev/null
+++ b/client/src/app/components/Icons/index.ts
@@ -0,0 +1,3 @@
+export * from "./IconWithOptionalTooltip";
+export * from "./IconedStatus";
+export * from "./IconWithLabel";
diff --git a/client/src/app/components/answer-table/answer-table.tsx b/client/src/app/components/answer-table/answer-table.tsx
index 8f015fe588..f94aa5e59e 100644
--- a/client/src/app/components/answer-table/answer-table.tsx
+++ b/client/src/app/components/answer-table/answer-table.tsx
@@ -12,7 +12,7 @@ import { NoDataEmptyState } from "@app/components/NoDataEmptyState";
import { Answer } from "@app/api/models";
import { Label, Text, Tooltip } from "@patternfly/react-core";
import spacing from "@patternfly/react-styles/css/utilities/Spacing/spacing";
-import { IconedStatus } from "@app/components/IconedStatus";
+import { IconedStatus } from "@app/components/Icons";
import { TimesCircleIcon } from "@patternfly/react-icons";
import { WarningTriangleIcon } from "@patternfly/react-icons";
import { List, ListItem } from "@patternfly/react-core";
diff --git a/client/src/app/components/risk-icon/risk-icon.tsx b/client/src/app/components/risk-icon/risk-icon.tsx
index d4a7ddf52d..23f5f1562c 100644
--- a/client/src/app/components/risk-icon/risk-icon.tsx
+++ b/client/src/app/components/risk-icon/risk-icon.tsx
@@ -1,6 +1,6 @@
import React from "react";
import { TimesCircleIcon, WarningTriangleIcon } from "@patternfly/react-icons";
-import { IconedStatus } from "@app/components/IconedStatus";
+import { IconedStatus } from "@app/components/Icons";
interface RiskIconProps {
risk: string;
diff --git a/client/src/app/components/tests/StatusIcon.test.tsx b/client/src/app/components/tests/StatusIcon.test.tsx
index a9f2da90e4..a8edc6dff8 100644
--- a/client/src/app/components/tests/StatusIcon.test.tsx
+++ b/client/src/app/components/tests/StatusIcon.test.tsx
@@ -1,6 +1,6 @@
import { render } from "@app/test-config/test-utils";
import React from "react";
-import { IconedStatus } from "../IconedStatus";
+import { IconedStatus } from "../Icons";
describe("StatusIcon", () => {
it("Renders without crashing", () => {
diff --git a/client/src/app/pages/applications/applications-table/applications-table.tsx b/client/src/app/pages/applications/applications-table/applications-table.tsx
index 61942abc7f..cf19bf8eac 100644
--- a/client/src/app/pages/applications/applications-table/applications-table.tsx
+++ b/client/src/app/pages/applications/applications-table/applications-table.tsx
@@ -108,6 +108,7 @@ import { useFetchArchetypes } from "@app/queries/archetypes";
import { ApplicationFormModal } from "../components/application-form";
import { ManageColumnsToolbar } from "./components/manage-columns-toolbar";
import dayjs from "dayjs";
+import { IconWithLabel } from "@app/components/Icons";
export const ApplicationsTable: React.FC = () => {
const { t } = useTranslation();
@@ -950,8 +951,12 @@ export const ApplicationsTable: React.FC = () => {
modifier="truncate"
{...getTdProps({ columnKey: "tags" })}
>
-
- {application.tags ? application.tags.length : 0}
+ }
+ label={
+ application.tags ? application.tags.length : 0
+ }
+ />
)}
{getColumnVisibility("effort") && (
diff --git a/client/src/app/pages/applications/components/application-analysis-status.tsx b/client/src/app/pages/applications/components/application-analysis-status.tsx
index 3734811642..5759c4293d 100644
--- a/client/src/app/pages/applications/components/application-analysis-status.tsx
+++ b/client/src/app/pages/applications/components/application-analysis-status.tsx
@@ -1,7 +1,7 @@
import React from "react";
import { TaskState } from "@app/api/models";
-import { IconedStatus } from "@app/components/IconedStatus";
+import { IconedStatus } from "@app/components/Icons";
export interface ApplicationAnalysisStatusProps {
state: TaskState;
diff --git a/client/src/app/pages/applications/components/application-assessment-status/application-assessment-status.tsx b/client/src/app/pages/applications/components/application-assessment-status/application-assessment-status.tsx
index 00894e5a4a..2c92c5cbb2 100644
--- a/client/src/app/pages/applications/components/application-assessment-status/application-assessment-status.tsx
+++ b/client/src/app/pages/applications/components/application-assessment-status/application-assessment-status.tsx
@@ -1,6 +1,6 @@
import React from "react";
import { Application } from "@app/api/models";
-import { IconedStatus, IconedStatusPreset } from "@app/components/IconedStatus";
+import { IconedStatus, IconedStatusPreset } from "@app/components/Icons";
import { Spinner } from "@patternfly/react-core";
import { useAssessmentStatus } from "@app/hooks/useAssessmentStatus";
interface ApplicationAssessmentStatusProps {
diff --git a/client/src/app/pages/applications/components/application-review-status/application-review-status.tsx b/client/src/app/pages/applications/components/application-review-status/application-review-status.tsx
index 37b629306d..e8a57002ad 100644
--- a/client/src/app/pages/applications/components/application-review-status/application-review-status.tsx
+++ b/client/src/app/pages/applications/components/application-review-status/application-review-status.tsx
@@ -1,6 +1,6 @@
import React from "react";
import { Application } from "@app/api/models";
-import { IconedStatus, IconedStatusPreset } from "@app/components/IconedStatus";
+import { IconedStatus, IconedStatusPreset } from "@app/components/Icons";
import { Spinner } from "@patternfly/react-core";
import { EmptyTextMessage } from "@app/components/EmptyTextMessage";
import { useTranslation } from "react-i18next";
diff --git a/client/src/app/pages/applications/manage-imports/manage-imports.tsx b/client/src/app/pages/applications/manage-imports/manage-imports.tsx
index cc20d3d4cf..3bcf7d0a23 100644
--- a/client/src/app/pages/applications/manage-imports/manage-imports.tsx
+++ b/client/src/app/pages/applications/manage-imports/manage-imports.tsx
@@ -27,7 +27,7 @@ import { AppPlaceholder } from "@app/components/AppPlaceholder";
import { ConditionalRender } from "@app/components/ConditionalRender";
import { ConfirmDialog } from "@app/components/ConfirmDialog";
import { FilterType, FilterToolbar } from "@app/components/FilterToolbar";
-import { IconedStatus } from "@app/components/IconedStatus";
+import { IconedStatus } from "@app/components/Icons";
import { KebabDropdown } from "@app/components/KebabDropdown";
import { NotificationsContext } from "@app/components/NotificationsContext";
import { SimplePagination } from "@app/components/SimplePagination";
diff --git a/client/src/app/pages/archetypes/archetypes-page.tsx b/client/src/app/pages/archetypes/archetypes-page.tsx
index 6911b91426..ccbfbc9c60 100644
--- a/client/src/app/pages/archetypes/archetypes-page.tsx
+++ b/client/src/app/pages/archetypes/archetypes-page.tsx
@@ -71,7 +71,7 @@ import {
} from "@app/rbac";
import { checkAccess } from "@app/utils/rbac-utils";
import keycloak from "@app/keycloak";
-import { IconedStatus } from "@app/components/IconedStatus";
+import { IconedStatus } from "@app/components/Icons";
import { useQueryClient } from "@tanstack/react-query";
const Archetypes: React.FC = () => {
diff --git a/client/src/app/pages/external/jira/components/tracker-status.tsx b/client/src/app/pages/external/jira/components/tracker-status.tsx
index ec94cb1153..88c463684e 100644
--- a/client/src/app/pages/external/jira/components/tracker-status.tsx
+++ b/client/src/app/pages/external/jira/components/tracker-status.tsx
@@ -13,7 +13,7 @@ import {
Spinner,
} from "@patternfly/react-core";
import ExclamationCircleIcon from "@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon";
-import { IconedStatus } from "@app/components/IconedStatus";
+import { IconedStatus } from "@app/components/Icons";
interface ITrackerStatusProps {
name: string;