From 94135099045e8ae44d84e8acb6a870110ba0659d Mon Sep 17 00:00:00 2001 From: Mike Turley Date: Wed, 12 Jul 2023 13:21:46 -0400 Subject: [PATCH] :sparkles: Issues table: Add description column, render expanded description as markdown, render links under markdown in table and incident viewer, add alert text to all incidents tab (#1116) This PR contains four presentation tweaks to the Issues page from recent discussions: 1. From a recent email discussion, it was decided that the although the issue description can be long, the first line of it is the most meaningful "title" for an issue or issue-based report and it should be included in the table. This change adds the first line of the description to the table, truncated with a tooltip. 2. The issue description in the expanded row content was being rendered in plain text, and now its value can contain markdown. This change wraps it using ReactMarkdown like the incident message. 3. The issue object (and now the issue-related reports as of https://github.com/konveyor/tackle2-hub/pull/434) contains a `links` array that we were not rendering. This change adds external links for these URLs under the issue description in the expanded rows of the issues table, and under the incident message in the incident viewer modal. 4. There was a placeholder TODO string in the info alert above the "all incidents" table in the incident viewer modal. This change adds a first pass of that message: "Full details are only available for the first 5 incidents per file due to performance constraints". We can revisit this if there are any objections to this text. --------- Signed-off-by: Mike Turley Co-authored-by: Ian Bolton --- client/src/app/api/models.ts | 6 +++ .../issue-description-and-links.tsx | 45 +++++++++++++++++++ .../file-incidents-detail-modal.tsx | 20 +++------ client/src/app/pages/issues/issues-table.tsx | 29 +++++++++--- 4 files changed, 80 insertions(+), 20 deletions(-) create mode 100644 client/src/app/pages/issues/components/issue-description-and-links.tsx diff --git a/client/src/app/api/models.ts b/client/src/app/api/models.ts index 1f450f372a..c00f6f54df 100644 --- a/client/src/app/api/models.ts +++ b/client/src/app/api/models.ts @@ -580,6 +580,11 @@ export interface AnalysisAppDependency { }; } +export interface AnalysisIssueLink { + url: string; + title: string; +} + interface AnalysisIssuesCommonFields { name: string; description: string; @@ -588,6 +593,7 @@ interface AnalysisIssuesCommonFields { category: string; effort: number; labels: string[]; + links?: AnalysisIssueLink[]; } // Hub type: Issue diff --git a/client/src/app/pages/issues/components/issue-description-and-links.tsx b/client/src/app/pages/issues/components/issue-description-and-links.tsx new file mode 100644 index 0000000000..3e3d031ae6 --- /dev/null +++ b/client/src/app/pages/issues/components/issue-description-and-links.tsx @@ -0,0 +1,45 @@ +import * as React from "react"; +import ReactMarkdown from "react-markdown"; +import { TextContent, List, ListItem, Button } from "@patternfly/react-core"; +import spacing from "@patternfly/react-styles/css/utilities/Spacing/spacing"; +import ExternalLinkSquareAltIcon from "@patternfly/react-icons/dist/esm/icons/external-link-square-alt-icon"; + +import { AnalysisIssueLink } from "@app/api/models"; +import { markdownPFComponents } from "@app/components/markdown-pf-components"; + +export interface IIssueDescriptionAndLinksProps { + description: string; + links?: AnalysisIssueLink[]; + className?: string; +} + +export const IssueDescriptionAndLinks: React.FC< + IIssueDescriptionAndLinksProps +> = ({ description, links, className = "" }) => ( +
+ + + {description} + + + {links?.length ? ( + + {links.map((link) => ( + + + + ))} + + ) : null} +
+); diff --git a/client/src/app/pages/issues/issue-detail-drawer/file-incidents-detail-modal/file-incidents-detail-modal.tsx b/client/src/app/pages/issues/issue-detail-drawer/file-incidents-detail-modal/file-incidents-detail-modal.tsx index 377665e563..6e46861646 100644 --- a/client/src/app/pages/issues/issue-detail-drawer/file-incidents-detail-modal/file-incidents-detail-modal.tsx +++ b/client/src/app/pages/issues/issue-detail-drawer/file-incidents-detail-modal/file-incidents-detail-modal.tsx @@ -1,6 +1,5 @@ import * as React from "react"; import { useTranslation } from "react-i18next"; -import ReactMarkdown from "react-markdown"; import { Button, Grid, @@ -20,9 +19,9 @@ import { NoDataEmptyState, StateError, } from "@app/shared/components"; -import { markdownPFComponents } from "@app/components/markdown-pf-components"; import { IncidentCodeSnipViewer } from "./incident-code-snip-viewer"; import { FileAllIncidentsTable } from "./file-all-incidents-table"; +import { IssueDescriptionAndLinks } from "../../components/issue-description-and-links"; export interface IFileIncidentsDetailModalProps { issue: AnalysisIssue; @@ -59,11 +58,6 @@ export const FileIncidentsDetailModal: React.FC< isFetching || (firstFiveIncidents.length > 0 && activeTabIncidentId === undefined); - // TODO render incident facts? - // TODO render documentation links? are those part of the markdown? where do we get them from the hub? - - console.log({ activeTabIncidentId }); - return ( {issue.name} Line {incident.line} - - - {incident.message} - - + ) : null} @@ -134,7 +128,7 @@ export const FileIncidentsDetailModal: React.FC< isInline variant="info" className={spacing.mtMd} - title="TODO" + title="Highlights available for the first 5 incidents per file to enhance system performance." // TODO i18n /> , diff --git a/client/src/app/pages/issues/issues-table.tsx b/client/src/app/pages/issues/issues-table.tsx index ce413b92b3..fade7de7e9 100644 --- a/client/src/app/pages/issues/issues-table.tsx +++ b/client/src/app/pages/issues/issues-table.tsx @@ -11,7 +11,6 @@ import { Text, Label, LabelGroup, - TextVariants, EmptyState, EmptyStateBody, EmptyStateIcon, @@ -71,6 +70,7 @@ import { Paths } from "@app/Paths"; import { AffectedAppsLink } from "./affected-apps-link"; import { ConditionalTooltip } from "@app/shared/components/ConditionalTooltip"; import { IssueDetailDrawer } from "./issue-detail-drawer"; +import { IssueDescriptionAndLinks } from "./components/issue-description-and-links"; export interface IIssuesTableProps { mode: "allIssues" | "singleApp"; @@ -100,6 +100,7 @@ export const IssuesTable: React.FC = ({ mode }) => { urlParamKeyPrefix: TableURLParamKeyPrefix.issues, columnNames: { name: "Issue", + description: "Description", category: "Category", source: "Source", target: "Target(s)", @@ -309,6 +310,7 @@ export const IssuesTable: React.FC = ({ mode }) => { + @@ -351,10 +353,21 @@ export const IssuesTable: React.FC = ({ mode }) => { item={report} rowIndex={rowIndex} > - + {report.name} - + + {report.description.split("\n")[0]} + + {report.category} = ({ mode }) => { /> = ({ mode }) => { - - {report.description} - +