Skip to content

Commit

Permalink
✨ Issues table: Add description column, render expanded description a…
Browse files Browse the repository at this point in the history
…s 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
konveyor/tackle2-hub#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 <mike.turley@alum.cs.umass.edu>
Co-authored-by: Ian Bolton <ibolton@redhat.com>
  • Loading branch information
mturley and ibolton336 authored Jul 12, 2023
1 parent aedaf9c commit 9413509
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 20 deletions.
6 changes: 6 additions & 0 deletions client/src/app/api/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,11 @@ export interface AnalysisAppDependency {
};
}

export interface AnalysisIssueLink {
url: string;
title: string;
}

interface AnalysisIssuesCommonFields {
name: string;
description: string;
Expand All @@ -588,6 +593,7 @@ interface AnalysisIssuesCommonFields {
category: string;
effort: number;
labels: string[];
links?: AnalysisIssueLink[];
}

// Hub type: Issue
Expand Down
Original file line number Diff line number Diff line change
@@ -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 = "" }) => (
<div className={className}>
<TextContent className={spacing.mbMd}>
<ReactMarkdown components={markdownPFComponents}>
{description}
</ReactMarkdown>
</TextContent>
{links?.length ? (
<List isPlain>
{links.map((link) => (
<ListItem key={link.url}>
<Button
variant="link"
component="a"
icon={<ExternalLinkSquareAltIcon />}
iconPosition="right"
href={link.url}
target="_blank"
rel="noreferrer"
>
{link.title}
</Button>
</ListItem>
))}
</List>
) : null}
</div>
);
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from "react";
import { useTranslation } from "react-i18next";
import ReactMarkdown from "react-markdown";
import {
Button,
Grid,
Expand All @@ -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;
Expand Down Expand Up @@ -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 (
<Modal
title={fileReport.file}
Expand Down Expand Up @@ -114,11 +108,11 @@ export const FileIncidentsDetailModal: React.FC<
<Text component="h2">{issue.name}</Text>
<Text component="small">Line {incident.line}</Text>
</TextContent>
<TextContent className={spacing.mtLg}>
<ReactMarkdown components={markdownPFComponents}>
{incident.message}
</ReactMarkdown>
</TextContent>
<IssueDescriptionAndLinks
className={spacing.mtLg}
description={incident.message}
links={issue.links}
/>
</GridItem>
</Grid>
) : null}
Expand All @@ -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
/>
<FileAllIncidentsTable fileReport={fileReport} />
</Tab>,
Expand Down
29 changes: 22 additions & 7 deletions client/src/app/pages/issues/issues-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
Text,
Label,
LabelGroup,
TextVariants,
EmptyState,
EmptyStateBody,
EmptyStateIcon,
Expand Down Expand Up @@ -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";
Expand Down Expand Up @@ -100,6 +100,7 @@ export const IssuesTable: React.FC<IIssuesTableProps> = ({ mode }) => {
urlParamKeyPrefix: TableURLParamKeyPrefix.issues,
columnNames: {
name: "Issue",
description: "Description",
category: "Category",
source: "Source",
target: "Target(s)",
Expand Down Expand Up @@ -309,6 +310,7 @@ export const IssuesTable: React.FC<IIssuesTableProps> = ({ mode }) => {
<Tr>
<TableHeaderContentWithControls {...tableControls}>
<Th {...getThProps({ columnKey: "name" })} />
<Th {...getThProps({ columnKey: "description" })} />
<Th {...getThProps({ columnKey: "category" })} />
<Th {...getThProps({ columnKey: "source" })} />
<Th {...getThProps({ columnKey: "target" })} />
Expand Down Expand Up @@ -351,10 +353,21 @@ export const IssuesTable: React.FC<IIssuesTableProps> = ({ mode }) => {
item={report}
rowIndex={rowIndex}
>
<Td width={25} {...getTdProps({ columnKey: "name" })}>
<Td
width={15}
{...getTdProps({ columnKey: "name" })}
modifier="truncate"
>
{report.name}
</Td>
<Td width={15} {...getTdProps({ columnKey: "category" })}>
<Td
width={25}
{...getTdProps({ columnKey: "description" })}
modifier="truncate"
>
{report.description.split("\n")[0]}
</Td>
<Td width={10} {...getTdProps({ columnKey: "category" })}>
{report.category}
</Td>
<Td
Expand All @@ -369,7 +382,7 @@ export const IssuesTable: React.FC<IIssuesTableProps> = ({ mode }) => {
/>
</Td>
<Td
width={20}
width={10}
modifier="nowrap"
noPadding
{...getTdProps({ columnKey: "target" })}
Expand Down Expand Up @@ -527,9 +540,11 @@ export const IssuesTable: React.FC<IIssuesTableProps> = ({ mode }) => {
</div>
</FlexItem>
<FlexItem flex={{ default: "flex_1" }}>
<Text component={TextVariants.h4}>
{report.description}
</Text>
<IssueDescriptionAndLinks
className={spacing.mrLg}
description={report.description}
links={report.links}
/>
</FlexItem>
</Flex>
</ExpandableRowContent>
Expand Down

0 comments on commit 9413509

Please sign in to comment.