diff --git a/app/scripts/modules/core/src/pipeline/config/stages/script/ScriptExecutionDetails.tsx b/app/scripts/modules/core/src/pipeline/config/stages/script/ScriptExecutionDetails.tsx index 0c4c4258bdd..3e916ca1f04 100644 --- a/app/scripts/modules/core/src/pipeline/config/stages/script/ScriptExecutionDetails.tsx +++ b/app/scripts/modules/core/src/pipeline/config/stages/script/ScriptExecutionDetails.tsx @@ -1,3 +1,4 @@ +import { RenderOutputFile } from 'core/presentation/RenderOutputFile'; import * as React from 'react'; import { get } from 'lodash'; @@ -32,12 +33,7 @@ export function ScriptExecutionDetails(props: IExecutionDetailsSectionProps) {
Property File
-
- {Object.keys(stage.context.propertyFileContents).map((key: string) => { - const val = stage.context.propertyFileContents[key]; - return [
{key}
,
{val}
]; - })} -
+
)} diff --git a/app/scripts/modules/core/src/presentation/RenderOutputFile.tsx b/app/scripts/modules/core/src/presentation/RenderOutputFile.tsx new file mode 100644 index 00000000000..6c4912050a8 --- /dev/null +++ b/app/scripts/modules/core/src/presentation/RenderOutputFile.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import { dump as dumpYaml } from 'js-yaml'; + +interface IRenderOutputFileProps { + outputFileObject: object; +} + +/** + * Renders an object as YAML. + * Transforms strings that look like URLs into links + * The intention is to render the output file from a Script or Run Job stage + */ +export const RenderOutputFile = React.memo(({ outputFileObject }: IRenderOutputFileProps) => { + const linkRegex = /(https?:\/\/[^$\s'"]+)/; + const isLink = (str: string) => `'${str}'`.match(linkRegex); + + const yaml = dumpYaml(outputFileObject); + + let linkCount = 0; + const segments = yaml.split(linkRegex); + const renderLink = (url: string) => ( + + {url} + + ); + const renderSegment = (segment: string) => (isLink(segment) ? renderLink(segment) : segment); + return
{segments.map(renderSegment)}
; +}); diff --git a/app/scripts/modules/core/src/presentation/index.ts b/app/scripts/modules/core/src/presentation/index.ts index eea10c632ae..baf8e34bc9a 100644 --- a/app/scripts/modules/core/src/presentation/index.ts +++ b/app/scripts/modules/core/src/presentation/index.ts @@ -5,6 +5,7 @@ export * from './LabelComponent'; export * from './Markdown'; export * from './Placement'; export * from './ReactModal'; +export * from './RenderOutputFile'; export * from './SpanDropdownTrigger'; export * from './TetheredSelect'; export * from './Tooltip'; diff --git a/app/scripts/modules/titus/src/pipeline/stages/runJob/RunJobExecutionDetails.tsx b/app/scripts/modules/titus/src/pipeline/stages/runJob/RunJobExecutionDetails.tsx index 878cd6a2df9..4a6b540b941 100644 --- a/app/scripts/modules/titus/src/pipeline/stages/runJob/RunJobExecutionDetails.tsx +++ b/app/scripts/modules/titus/src/pipeline/stages/runJob/RunJobExecutionDetails.tsx @@ -6,6 +6,7 @@ import { AccountTag, ExecutionDetailsSection, IExecutionDetailsSectionProps, + RenderOutputFile, StageFailureMessage, } from '@spinnaker/core'; @@ -55,20 +56,6 @@ export class RunJobExecutionDetails extends React.Component< const jobId = cluster ? get(context['deploy.jobs'], cluster.region, [])[0] : null; const taskId = get(context, 'jobStatus.completionDetails.taskId'); - const renderProperty = (entry: any) => { - if (typeof entry === 'object' && !Array.isArray(entry)) { - return
{JSON.stringify(entry, null, 2)}
; - } - const linkPattern = /^https?:\/\/([^\s])*$/; - return linkPattern.test(entry) ? ( - - {entry} - - ) : ( - {entry} - ); - }; - return (
@@ -145,22 +132,8 @@ export class RunJobExecutionDetails extends React.Component< {context.propertyFileContents && (
-
Property File
-
- {Object.keys(context.propertyFileContents) - .sort((a: string, b: string) => - context.propertyFileContents[a].toString().length > - context.propertyFileContents[b].toString().length - ? 1 - : -1, - ) - .map(key => ( - -
{key}
-
{renderProperty(context.propertyFileContents[key])}
-
- ))} -
+
Property File
+
)}