Skip to content

Commit

Permalink
refactor(md): split artifactDetail to smaller files (#8922)
Browse files Browse the repository at this point in the history
Co-authored-by: Chris Thielen <christopherthielen@users.noreply.github.com>
  • Loading branch information
Rani and christopherthielen committed Feb 17, 2021
1 parent 78f7d5a commit acac332
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 143 deletions.
12 changes: 7 additions & 5 deletions app/scripts/modules/core/src/domain/IManagedEntity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,20 @@ export interface IVerification {
link?: string;
}

export interface IPinned {
at: string;
by: string;
comment?: string;
}

export interface IManagedArtifactVersion {
version: string;
displayName: string;
createdAt?: string;
environments: Array<{
name: string;
state: 'current' | 'deploying' | 'approved' | 'pending' | 'previous' | 'vetoed' | 'skipped';
pinned?: {
at: string;
by: string;
comment?: string;
};
pinned?: IPinned;
vetoed?: {
at: string;
by: string;
Expand Down
148 changes: 10 additions & 138 deletions app/scripts/modules/core/src/managed/artifactDetail/ArtifactDetail.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,29 @@
import React, { memo, useMemo } from 'react';
import React, { useMemo } from 'react';
import classNames from 'classnames';
import { useRouter } from '@uirouter/react';
import { DateTime } from 'luxon';

import {
IManagedArtifactSummary,
IManagedArtifactVersion,
IManagedEnvironmentSummary,
IManagedResourceSummary,
IManagedArtifactVersionEnvironment,
} from '../../domain';
} from 'core/domain';

import { Application } from '../../application';
import { useEventListener, Markdown, CollapsibleElement } from '../../presentation';

import { AbsoluteTimestamp } from '../AbsoluteTimestamp';
import { ArtifactDetailHeader } from './ArtifactDetailHeader';
import { ManagedResourceObject } from '../ManagedResourceObject';
import { EnvironmentRow } from '../environment/EnvironmentRow';
import { PreDeploymentRow } from './PreDeploymentRow';
import { PreDeploymentStepCard } from './PreDeploymentStepCard';
import { VersionStateCard } from './VersionStateCard';
import { StatusCard } from '../StatusCard';
import { Button } from '../Button';
import { showPinArtifactModal } from './PinArtifactModal';
import { showUnpinArtifactModal } from './UnpinArtifactModal';
import { showMarkArtifactAsBadModal } from './MarkArtifactAsBadModal';

import { ConstraintCard } from './constraints/ConstraintCard';
import { isConstraintSupported } from './constraints/constraintRegistry';
import { EnvironmentCards } from './EnvironmentCards';
import { isResourceKindSupported } from '../resources/resourceRegistry';
import { VerificationCard } from './verifications/VerificationCard';
import { logCategories, useLogEvent } from '../utils/logging';

import { useLogEvent } from '../utils/logging';
import './ArtifactDetail.less';

const SUPPORTED_PRE_DEPLOYMENT_TYPES = ['BUILD', 'BAKE'];
Expand All @@ -40,128 +32,6 @@ function shouldDisplayResource(reference: string, resource: IManagedResourceSumm
return isResourceKindSupported(resource.kind) && reference === resource.artifact?.reference;
}

type IEnvironmentCardsProps = Pick<
IArtifactDetailProps,
'application' | 'reference' | 'version' | 'allVersions' | 'resourcesByEnvironment'
> & {
environment: IManagedArtifactVersionEnvironment;
pinnedVersion: string;
};

const LOG_CATEGORY = 'Environments - artifact details';

const EnvironmentCards = memo(
({
application,
environment,
reference,
version: versionDetails,
allVersions,
pinnedVersion,
resourcesByEnvironment,
}: IEnvironmentCardsProps) => {
const {
name: environmentName,
state,
deployedAt,
replacedAt,
replacedBy,
pinned,
vetoed,
statefulConstraints,
statelessConstraints,
compareLink,
} = environment;
const {
stateService: { go },
} = useRouter();

const logEvent = useLogEvent(LOG_CATEGORY);

const differentVersionPinnedCard = pinnedVersion &&
pinnedVersion !== versionDetails.version &&
!['vetoed', 'skipped'].includes(state) && (
<StatusCard
iconName="cloudWaiting"
appearance="warning"
background={true}
title="A different version is pinned here"
actions={<Button onClick={() => go('.', { version: pinnedVersion })}>See version</Button>}
/>
);

const pinnedCard = pinned && (
<StatusCard
iconName="pin"
appearance="warning"
background={true}
timestamp={pinned?.at ? DateTime.fromISO(pinned.at) : null}
title={
<span className="sp-group-margin-xs-xaxis">
<span>Pinned</span> <span className="text-regular"></span>{' '}
<span className="text-regular">by {pinned.by}</span>
</span>
}
description={pinned.comment && <Markdown message={pinned.comment} tag="span" />}
actions={
<Button
iconName="unpin"
onClick={() =>
showUnpinArtifactModal({
application,
reference,
version: versionDetails,
resourcesByEnvironment,
environment: environmentName,
}).then(({ status }) => status === 'CLOSED' && application.getDataSource('environments').refresh())
}
>
Unpin
</Button>
}
/>
);

return (
<>
{differentVersionPinnedCard}
{pinnedCard}
<VersionStateCard
key="versionStateCard"
state={state}
deployedAt={deployedAt}
replacedAt={replacedAt}
replacedBy={replacedBy}
vetoed={vetoed}
compareLink={compareLink}
allVersions={allVersions}
logClick={(action) => logEvent({ action, label: `${environmentName}:${reference}` })}
/>
{environment.verifications?.map((verification) => (
<VerificationCard
key={verification.id}
verification={verification}
wasHalted={environment.state === 'skipped'}
logClick={(action) => logEvent({ action, label: `${environmentName}:${reference}` })}
/>
))}
{[...(statelessConstraints || []), ...(statefulConstraints || [])]
.filter(({ type }) => isConstraintSupported(type))
.map((constraint) => (
<ConstraintCard
key={constraint.type}
application={application}
environment={environment}
reference={reference}
version={versionDetails.version}
constraint={constraint}
/>
))}
</>
);
},
);

const VersionMetadataItem = ({ label, value }: { label: string; value: JSX.Element | string }) => (
<div className="flex-container-h sp-margin-xs-bottom">
<div className="metadata-label text-bold text-right sp-margin-l-right flex-none">{label}</div>
Expand Down Expand Up @@ -192,10 +62,12 @@ export const ArtifactDetail = ({
onRequestClose,
}: IArtifactDetailProps) => {
const { environments, lifecycleSteps, git, createdAt } = versionDetails;
const logEvent = useLogEvent(LOG_CATEGORY);
const logEvent = useLogEvent(logCategories.artifactDetails);

const keydownCallback = ({ keyCode }: KeyboardEvent) => {
if (keyCode === 27 /* esc */) {
const keydownCallback = ({ key }: KeyboardEvent) => {
if (key === 'Esc') {
// eslint-disable-next-line no-console
console.log('here');
onRequestClose();
}
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React from 'react';
import { useRouter } from '@uirouter/react';

import { IManagedArtifactVersionEnvironment } from 'core/domain';

import { Button } from '../Button';
import { StatusCard } from '../StatusCard';
import { logCategories, useLogEvent } from '../utils/logging';
import { IArtifactDetailProps } from './ArtifactDetail';
import { ConstraintCard } from './constraints/ConstraintCard';
import { isConstraintSupported } from './constraints/constraintRegistry';
import { PinnedCard } from './PinnedCard';
import { VerificationCard } from './verifications/VerificationCard';
import { VersionStateCard } from './VersionStateCard';

interface IEnvironmentCardsProps
extends Pick<
IArtifactDetailProps,
'application' | 'reference' | 'version' | 'allVersions' | 'resourcesByEnvironment'
> {
environment: IManagedArtifactVersionEnvironment;
pinnedVersion: string;
}

export const EnvironmentCards: React.FC<IEnvironmentCardsProps> = ({
application,
environment,
reference,
version: versionDetails,
allVersions,
pinnedVersion,
resourcesByEnvironment,
}) => {
const {
name: environmentName,
state,
deployedAt,
replacedAt,
replacedBy,
pinned,
vetoed,
statefulConstraints,
statelessConstraints,
compareLink,
} = environment;
const {
stateService: { go },
} = useRouter();

const logEvent = useLogEvent(logCategories.artifactDetails);

const differentVersionPinnedCard = pinnedVersion &&
pinnedVersion !== versionDetails.version &&
!['vetoed', 'skipped'].includes(state) && (
<StatusCard
iconName="cloudWaiting"
appearance="warning"
background={true}
title="A different version is pinned here"
actions={<Button onClick={() => go('.', { version: pinnedVersion })}>See version</Button>}
/>
);

const pinnedCard = pinned && (
<PinnedCard
resourcesByEnvironment={resourcesByEnvironment}
environmentName={environmentName}
pinned={environment.pinned}
reference={reference}
version={versionDetails}
/>
);

return (
<>
{differentVersionPinnedCard}
{pinnedCard}
<VersionStateCard
key="versionStateCard"
state={state}
deployedAt={deployedAt}
replacedAt={replacedAt}
replacedBy={replacedBy}
vetoed={vetoed}
compareLink={compareLink}
allVersions={allVersions}
logClick={(action) => logEvent({ action, label: `${environmentName}:${reference}` })}
/>
{environment.verifications?.map((verification) => (
<VerificationCard
key={verification.id}
verification={verification}
wasHalted={environment.state === 'skipped'}
logClick={(action) => logEvent({ action, label: `${environmentName}:${reference}` })}
/>
))}
{[...(statelessConstraints || []), ...(statefulConstraints || [])]
.filter(({ type }) => isConstraintSupported(type))
.map((constraint) => (
<ConstraintCard
key={constraint.type}
application={application}
environment={environment}
reference={reference}
version={versionDetails.version}
constraint={constraint}
/>
))}
</>
);
};
57 changes: 57 additions & 0 deletions app/scripts/modules/core/src/managed/artifactDetail/PinnedCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react';
import { DateTime } from 'luxon';

import { IPinned } from 'core/domain';

import { Markdown } from '../../presentation';
import { useApplicationContext } from '../../presentation/hooks/useApplicationContext.hook';
import { Button } from '../Button';
import { StatusCard } from '../StatusCard';
import { IArtifactDetailProps } from './ArtifactDetail';
import { showUnpinArtifactModal } from './UnpinArtifactModal';

interface PinnedCardProps extends Pick<IArtifactDetailProps, 'resourcesByEnvironment' | 'reference' | 'version'> {
environmentName: string;
pinned?: IPinned;
}

export const PinnedCard: React.FC<PinnedCardProps> = ({
version,
environmentName,
pinned,
resourcesByEnvironment,
reference,
}) => {
const application = useApplicationContext();
return (
<StatusCard
iconName="pin"
appearance="warning"
background={true}
timestamp={pinned?.at ? DateTime.fromISO(pinned.at) : null}
title={
<span className="sp-group-margin-xs-xaxis">
<span>Pinned</span> <span className="text-regular"></span>{' '}
<span className="text-regular">by {pinned.by}</span>
</span>
}
description={pinned.comment && <Markdown message={pinned.comment} tag="span" />}
actions={
<Button
iconName="unpin"
onClick={() =>
showUnpinArtifactModal({
application,
reference,
version,
resourcesByEnvironment,
environment: environmentName,
}).then(({ status }) => status === 'CLOSED' && application.getDataSource('environments').refresh())
}
>
Unpin
</Button>
}
/>
);
};
4 changes: 4 additions & 0 deletions app/scripts/modules/core/src/managed/utils/logging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ export const useLogEvent = (category: string) => {
logEvent({ ...props, category, application: app?.name });
};
};

export const logCategories = {
artifactDetails: 'Environments - artifact details',
};

0 comments on commit acac332

Please sign in to comment.