All files / modules/70-pipeline/components/TemplateVariablesContext TemplateVariablesContext.tsx

100% Statements 24/24
100% Branches 46/46
100% Functions 4/4
100% Lines 24/24

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              218x 218x 218x 218x 218x   218x 218x                                     218x                 218x 2386x     218x     38x 37x           37x 37x 37x   37x                             37x                           37x 8x 1x       37x 8x           37x                              
/*
 * 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 from 'react'
import { useParams } from 'react-router-dom'
import { defaultTo, get } from 'lodash-es'
import { parse } from 'yaml'
import { useMutateAsGet, useQueryParams } from '@common/hooks'
import type { GitQueryParams, TemplateStudioPathProps } from '@common/interfaces/RouteInterfaces'
import { yamlStringify } from '@common/utils/YamlHelperMethods'
import {
  Failure,
  NGTemplateInfoConfig,
  useCreateVariables,
  useGetYamlWithTemplateRefsResolved,
  VariableMergeServiceResponse
} from 'services/template-ng'
import type { UseMutateAsGetReturn } from '@common/hooks/useMutateAsGet'
import type { StageElementConfig, StepElementConfig } from 'services/cd-ng'
 
export interface TemplateVariablesData {
  variablesTemplate: StepElementConfig | StageElementConfig
  originalTemplate: NGTemplateInfoConfig
  metadataMap: Required<VariableMergeServiceResponse>['metadataMap']
  error?: UseMutateAsGetReturn<Failure | Error>['error'] | null
  initLoading: boolean
  loading: boolean
}
 
export const TemplateVariablesContext = React.createContext<TemplateVariablesData>({
  variablesTemplate: { name: '', identifier: '' },
  originalTemplate: { name: '', identifier: '', versionLabel: '', type: 'Step' },
  metadataMap: {},
  error: null,
  initLoading: true,
  loading: false
})
 
export function useTemplateVariables(): TemplateVariablesData {
  return React.useContext(TemplateVariablesContext)
}
 
export function TemplateVariablesContextProvider(
  props: React.PropsWithChildren<{ template: NGTemplateInfoConfig }>
): React.ReactElement {
  const { template: originalTemplate } = props
  const [{ variablesTemplate, metadataMap }, setTemplateVariablesData] = React.useState<
    Pick<TemplateVariablesData, 'metadataMap' | 'variablesTemplate'>
  >({
    variablesTemplate: { name: '', identifier: '' },
    metadataMap: {}
  })
  const { accountId, orgIdentifier, projectIdentifier } = useParams<TemplateStudioPathProps>()
  const { repoIdentifier, branch } = useQueryParams<GitQueryParams>()
  const [resolvedTemplate, setResolvedTemplate] = React.useState<NGTemplateInfoConfig>(originalTemplate)
 
  const { data, error, initLoading, loading } = useMutateAsGet(useCreateVariables, {
    body: yamlStringify({ template: resolvedTemplate }) as unknown as void,
    requestOptions: {
      headers: {
        'content-type': 'application/yaml'
      }
    },
    queryParams: { accountIdentifier: accountId, orgIdentifier, projectIdentifier },
    debounce: 800
  })
 
  const {
    data: resolvedTemplateResponse,
    initLoading: initLoadingResolvedTemplate,
    loading: loadingResolvedTemplate
  } = useMutateAsGet(useGetYamlWithTemplateRefsResolved, {
    queryParams: {
      accountIdentifier: accountId,
      orgIdentifier,
      projectIdentifier,
      repoIdentifier,
      branch,
      getDefaultFromOtherRepo: true
    },
    body: {
      originalEntityYaml: yamlStringify(originalTemplate)
    }
  })
 
  React.useEffect(() => {
    if (resolvedTemplateResponse?.data?.mergedPipelineYaml) {
      setResolvedTemplate(parse(resolvedTemplateResponse.data.mergedPipelineYaml))
    }
  }, [resolvedTemplateResponse])
 
  React.useEffect(() => {
    setTemplateVariablesData({
      metadataMap: defaultTo(data?.data?.metadataMap, {}),
      variablesTemplate: get(parse(defaultTo(data?.data?.yaml, '')), resolvedTemplate.type.toLowerCase())
    })
  }, [data?.data?.metadataMap, data?.data?.yaml])
 
  return (
    <TemplateVariablesContext.Provider
      value={{
        variablesTemplate,
        originalTemplate: resolvedTemplate,
        metadataMap,
        error,
        initLoading: initLoading || initLoadingResolvedTemplate,
        loading: loading || loadingResolvedTemplate
      }}
    >
      {props.children}
    </TemplateVariablesContext.Provider>
  )
}