Skip to content

Commit

Permalink
[RHOAIENG-2987] Artifacts - Details Page
Browse files Browse the repository at this point in the history
  • Loading branch information
jpuzz0 committed Apr 30, 2024
1 parent 95fb721 commit 0d90b66
Show file tree
Hide file tree
Showing 9 changed files with 389 additions and 21 deletions.
12 changes: 12 additions & 0 deletions frontend/src/pages/pipelines/GlobalArtifactsRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import ProjectsRoutes from '~/concepts/projects/ProjectsRoutes';
import GlobalPipelineCoreLoader from '~/pages/pipelines/global/GlobalPipelineCoreLoader';
import { artifactsBaseRoute } from '~/routes';
import { GlobalArtifactsPage } from './global/experiments/artifacts';
import GlobalPipelineCoreDetails from './global/GlobalPipelineCoreDetails';
import { ArtifactDetails } from './global/experiments/artifacts/ArtifactDetails';

const GlobalArtifactsRoutes: React.FC = () => (
<ProjectsRoutes>
Expand All @@ -13,6 +15,16 @@ const GlobalArtifactsRoutes: React.FC = () => (
element={<GlobalPipelineCoreLoader getInvalidRedirectPath={artifactsBaseRoute} />}
>
<Route index element={<GlobalArtifactsPage />} />
<Route
path=":artifactId"
element={
<GlobalPipelineCoreDetails
pageName="Artifacts"
redirectPath={artifactsBaseRoute}
BreadcrumbDetailsComponent={ArtifactDetails}
/>
}
/>
<Route path="*" element={<Navigate to="." />} />
</Route>
</ProjectsRoutes>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import React from 'react';
import { useParams } from 'react-router';

import {
Breadcrumb,
BreadcrumbItem,
Bullseye,
DescriptionList,
DescriptionListDescription,
DescriptionListGroup,
DescriptionListTerm,
EmptyState,
EmptyStateBody,
EmptyStateHeader,
EmptyStateIcon,
EmptyStateVariant,
Flex,
FlexItem,
Spinner,
Stack,
Tab,
TabTitleText,
Tabs,
Title,
Truncate,
} from '@patternfly/react-core';
import { ExclamationCircleIcon } from '@patternfly/react-icons';

import { PipelineCoreDetailsPageComponent } from '~/concepts/pipelines/content/types';
import ApplicationsPage from '~/pages/ApplicationsPage';
import { useGetArtifactById } from './useGetArtifactById';
import { getArtifactName } from './utils';
import { ArtifactDetailsTabKey } from './constants';
import { ArtifactUriLink } from './ArtifactUriLink';

export const ArtifactDetails: PipelineCoreDetailsPageComponent = ({ breadcrumbPath }) => {
const { artifactId } = useParams();
const [artifactResponse, isArtifactLoaded, artifactError] = useGetArtifactById(
Number(artifactId),
);
const artifact = artifactResponse?.toObject();
const artifactName = getArtifactName(artifact);

if (artifactError) {
return (
<EmptyState variant={EmptyStateVariant.lg}>
<EmptyStateHeader
titleText="Error loading artifact details"
icon={<EmptyStateIcon icon={ExclamationCircleIcon} />}
headingLevel="h4"
/>
<EmptyStateBody>{artifactError.message}</EmptyStateBody>
</EmptyState>
);
}

if (!isArtifactLoaded) {
return (
<Bullseye>
<Spinner />
</Bullseye>
);
}

return (
<ApplicationsPage
title={artifactName ?? 'Error loading artifact'}
loaded={isArtifactLoaded}
loadError={artifactError}
breadcrumb={
<Breadcrumb>
{breadcrumbPath}
<BreadcrumbItem isActive style={{ maxWidth: 300 }}>
<Truncate content={artifactName ?? 'Loading...'} />
</BreadcrumbItem>
</Breadcrumb>
}
empty={false}
provideChildrenPadding
>
<Tabs aria-label="Artifact details tabs" activeKey={ArtifactDetailsTabKey.Overview}>
<Tab
eventKey={ArtifactDetailsTabKey.Overview}
title={<TabTitleText>Overview</TabTitleText>}
aria-label="Overview"
>
<Flex
spaceItems={{ default: 'spaceItems2xl' }}
direction={{ default: 'column' }}
className="pf-v5-u-pt-lg pf-v5-u-pb-lg"
>
<FlexItem>
<Stack hasGutter>
<Title headingLevel="h3">Live system dataset</Title>
<DescriptionList isHorizontal data-testid="dataset-description-list">
<DescriptionListGroup>
{artifact?.uri && (
<>
<DescriptionListTerm>URI</DescriptionListTerm>
<DescriptionListDescription>
<ArtifactUriLink artifact={artifact} />
</DescriptionListDescription>
</>
)}
</DescriptionListGroup>
</DescriptionList>
</Stack>
</FlexItem>

{!!artifact?.propertiesMap.length && (
<FlexItem>
<Stack hasGutter>
<Title headingLevel="h3">Properties</Title>
<DescriptionList isHorizontal data-testid="props-description-list">
<DescriptionListGroup>
{artifact.propertiesMap.map(([propKey, propValue]) => (
<React.Fragment key={propKey}>
<DescriptionListTerm>{propKey}</DescriptionListTerm>
<DescriptionListDescription>
{propValue.stringValue}
</DescriptionListDescription>
</React.Fragment>
))}
</DescriptionListGroup>
</DescriptionList>
</Stack>
</FlexItem>
)}

{!!artifact?.customPropertiesMap.length && (
<FlexItem>
<Stack hasGutter>
<Title headingLevel="h3">Custom properties</Title>
<DescriptionList isHorizontal data-testid="custom-props-description-list">
<DescriptionListGroup>
{artifact.customPropertiesMap.map(([customPropKey, customPropValue]) => (
<React.Fragment key={customPropKey}>
<DescriptionListTerm>{customPropKey}</DescriptionListTerm>
<DescriptionListDescription>
{customPropValue.stringValue}
</DescriptionListDescription>
</React.Fragment>
))}
</DescriptionListGroup>
</DescriptionList>
</Stack>
</FlexItem>
)}
</Flex>
</Tab>
<Tab
eventKey={ArtifactDetailsTabKey.LineageExplorer}
title={<TabTitleText>Lineage explorer</TabTitleText>}
isAriaDisabled
/>
</Tabs>
</ApplicationsPage>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { Link } from 'react-router-dom';

import { Flex, FlexItem, Truncate } from '@patternfly/react-core';
import { ExternalLinkAltIcon } from '@patternfly/react-icons';

import { Artifact } from '~/third_party/mlmd';

export const ArtifactUriLink: React.FC<{ artifact: Artifact.AsObject }> = ({ artifact }) => (
<Link to={artifact.uri} target="_blank">
<Flex
alignItems={{ default: 'alignItemsCenter' }}
spaceItems={{ default: 'spaceItemsSm' }}
flexWrap={{ default: 'nowrap' }}
>
<FlexItem>
<Truncate content={artifact.uri} />
</FlexItem>

<FlexItem>
<ExternalLinkAltIcon />
</FlexItem>
</Flex>
</Link>
);
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React from 'react';
import { Link } from 'react-router-dom';

import { Flex, FlexItem, TextInput, Truncate } from '@patternfly/react-core';
import { ExternalLinkAltIcon } from '@patternfly/react-icons';
import { TextInput } from '@patternfly/react-core';
import { TableVariant, Td, Tr } from '@patternfly/react-table';

import { Artifact } from '~/third_party/mlmd';
Expand All @@ -12,8 +11,11 @@ import PipelinesTableRowTime from '~/concepts/pipelines/content/tables/Pipelines
import { FilterToolbar } from '~/concepts/pipelines/content/tables/PipelineFilterBar';
import SimpleDropdownSelect from '~/components/SimpleDropdownSelect';
import { ArtifactType } from '~/concepts/pipelines/kfTypes';
import { useMlmdListContext } from '~/concepts/pipelines/context';
import { useMlmdListContext, usePipelinesAPI } from '~/concepts/pipelines/context';
import { artifactsDetailsRoute } from '~/routes';
import { FilterOptions, columns, initialFilterData, options } from './constants';
import { getArtifactName } from './utils';
import { ArtifactUriLink } from './ArtifactUriLink';

interface ArtifactsTableProps {
artifacts: Artifact[] | null | undefined;
Expand All @@ -32,6 +34,7 @@ export const ArtifactsTable: React.FC<ArtifactsTableProps> = ({
setPageToken: setRequestToken,
setMaxResultSize,
} = useMlmdListContext(nextPageToken);
const { namespace } = usePipelinesAPI();
const [page, setPage] = React.useState(1);
const [filterData, setFilterData] = React.useState(initialFilterData);
const onClearFilters = React.useCallback(() => setFilterData(initialFilterData), []);
Expand Down Expand Up @@ -141,34 +144,21 @@ export const ArtifactsTable: React.FC<ArtifactsTableProps> = ({
(artifact: Artifact.AsObject) => (
<Tr key={artifact.id}>
<Td>
{artifact.name ||
artifact.customPropertiesMap.find(([name]) => name === 'display_name')?.[1].stringValue}
<Link to={artifactsDetailsRoute(namespace, artifact.id)}>
{getArtifactName(artifact)}
</Link>
</Td>
<Td>{artifact.id}</Td>
<Td>{artifact.type}</Td>
<Td>
<Link to={artifact.uri} target="_blank">
<Flex
alignItems={{ default: 'alignItemsCenter' }}
spaceItems={{ default: 'spaceItemsSm' }}
flexWrap={{ default: 'nowrap' }}
>
<FlexItem>
<Truncate content={artifact.uri} />
</FlexItem>

<FlexItem>
<ExternalLinkAltIcon />
</FlexItem>
</Flex>
</Link>
<ArtifactUriLink artifact={artifact} />
</Td>
<Td>
<PipelinesTableRowTime date={new Date(artifact.createTimeSinceEpoch)} />
</Td>
</Tr>
),
[],
[namespace],
);

return (
Expand Down
Loading

0 comments on commit 0d90b66

Please sign in to comment.