All files / modules/72-templates-library/components/TemplateStudio/TemplateVariables TemplateVariables.tsx

78.38% Statements 29/37
76.92% Branches 20/26
33.33% Functions 2/6
78.38% Lines 29/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124              14x 14x 14x 14x 14x 14x   14x 14x   14x 14x 14x 14x 14x 14x 14x 14x 14x 14x   14x         4x 3x 3x 3x   3x                                         3x 1x     2x                                                                                                         14x 4x            
/*
 * Copyright 2022 Harness Inc. All rights reserved.
 * Use of this source code is governed by the PolyForm Shield 1.0.0 license
 * that can be found in the licenses directory at the root of this repository, also available at
 * https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt.
 */
 
import React, { useCallback } from 'react'
import { MultiTypeInputType, NestedAccordionProvider, PageError } from '@wings-software/uicore'
import { isEmpty, omit, set } from 'lodash-es'
import { produce } from 'immer'
import { useTemplateVariables } from '@pipeline/components/TemplateVariablesContext/TemplateVariablesContext'
import { PageSpinner } from '@common/components'
import type { NGTemplateInfoConfig } from 'services/template-ng'
import StageCard from '@pipeline/components/PipelineStudio/PipelineVariables/Cards/StageCard'
import { TemplateContext } from '@templates-library/components/TemplateStudio/TemplateContext/TemplateContext'
import type { PipelineInfoConfig, StageElementConfig, StepElementConfig } from 'services/cd-ng'
import { StepCardPanel } from '@pipeline/components/PipelineStudio/PipelineVariables/Cards/StepCard'
import factory from '@pipeline/components/PipelineSteps/PipelineStepFactory'
import { DefaultNewStageId } from '@templates-library/components/TemplateStudio/StageTemplateCanvas/StageTemplateForm/StageTemplateForm'
import { GitSyncStoreProvider } from 'framework/GitRepoStore/GitSyncStoreContext'
import { sanitize } from '@common/utils/JSONUtils'
import { VariablesHeader } from '@pipeline/components/PipelineStudio/PipelineVariables/VariablesHeader/VariablesHeader'
import { TemplateType } from '@templates-library/utils/templatesUtils'
import { PipelineCardPanel } from '@pipeline/components/PipelineStudio/PipelineVariables/PipelineVariables'
import { DrawerTypes } from '../TemplateContext/TemplateActions'
import css from '@pipeline/components/PipelineStudio/PipelineVariables/PipelineVariables.module.scss'
 
const TemplateVariables: React.FC = (): JSX.Element => {
  const {
    state: { template, templateView },
    updateTemplate,
    updateTemplateView
  } = React.useContext(TemplateContext)
  const { originalTemplate, variablesTemplate, metadataMap, error, initLoading } = useTemplateVariables()
  const allowableTypes = [MultiTypeInputType.FIXED, MultiTypeInputType.RUNTIME, MultiTypeInputType.EXPRESSION]
  const [templateAtState, setTemplateAtState] = React.useState<NGTemplateInfoConfig>(originalTemplate)
 
  const onUpdate = useCallback(
    async (values: PipelineInfoConfig | StageElementConfig | StepElementConfig) => {
      const processNode = omit(values, 'name', 'identifier', 'description', 'tags')
      sanitize(processNode, { removeEmptyArray: false, removeEmptyObject: false, removeEmptyString: false })
      const updatedTemplate = produce(templateAtState, draft => {
        set(draft, 'spec', processNode)
      })
      setTemplateAtState(updatedTemplate)
    },
    [templateAtState]
  )
 
  async function applyChanges(): Promise<void> {
    await updateTemplate(templateAtState)
    updateTemplateView({ ...templateView, isDrawerOpened: false, drawerData: { type: DrawerTypes.AddStep } })
  }
 
  async function discardChanges(): Promise<void> {
    updateTemplateView({ ...templateView, isDrawerOpened: false, drawerData: { type: DrawerTypes.AddStep } })
  }
 
  if (initLoading) {
    return <PageSpinner />
  }
 
  return (
    <div className={css.pipelineVariables}>
      {error ? (
        <PageError message={(error?.data as Error)?.message || error?.message} />
      ) : !isEmpty(variablesTemplate) ? (
        <div className={css.content}>
          <VariablesHeader enableSearch={false} applyChanges={applyChanges} discardChanges={discardChanges} />
          <div className={css.variableList}>
            <GitSyncStoreProvider>
              {originalTemplate.type === TemplateType.Pipeline && (
                <PipelineCardPanel
                  variablePipeline={variablesTemplate as PipelineInfoConfig}
                  pipeline={template.spec as PipelineInfoConfig}
                  originalPipeline={originalTemplate.spec as PipelineInfoConfig}
                  metadataMap={metadataMap}
                  allowableTypes={allowableTypes}
                  stepsFactory={factory}
                  updatePipeline={onUpdate}
                />
              )}
              {originalTemplate.type === TemplateType.Stage && (
                <StageCard
                  stage={variablesTemplate as StageElementConfig}
                  unresolvedStage={{ ...template.spec, identifier: DefaultNewStageId } as StageElementConfig}
                  originalStage={{ ...originalTemplate.spec, identifier: DefaultNewStageId } as StageElementConfig}
                  metadataMap={metadataMap}
                  path="template"
                  allowableTypes={allowableTypes}
                  stepsFactory={factory}
                  updateStage={onUpdate}
                />
              )}
              {originalTemplate.type === TemplateType.Step && (
                <StepCardPanel
                  step={variablesTemplate as StepElementConfig}
                  originalStep={originalTemplate.spec as StepElementConfig}
                  metadataMap={metadataMap}
                  readonly={true}
                  stepPath="template"
                  allowableTypes={allowableTypes}
                  stageIdentifier={DefaultNewStageId}
                  onUpdateStep={onUpdate}
                  stepsFactory={factory}
                />
              )}
            </GitSyncStoreProvider>
          </div>
        </div>
      ) : null}
    </div>
  )
}
 
export default function TemplateVariablesWrapper(): React.ReactElement {
  return (
    <NestedAccordionProvider>
      <TemplateVariables />
    </NestedAccordionProvider>
  )
}