diff --git a/web/src/components/PluginsPanel/PluginsPanel.tsx b/web/src/components/PluginsPanel/PluginsPanel.tsx index 72a328d1b..8aba360bd 100644 --- a/web/src/components/PluginsPanel/PluginsPanel.tsx +++ b/web/src/components/PluginsPanel/PluginsPanel.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useEffect, useState } from 'react' import { Formik } from 'formik' import { parse } from 'yaml' -import { capitalize, get, omit, set } from 'lodash-es' +import { capitalize, get, has, omit, set } from 'lodash-es' import { Classes, PopoverInteractionKind, PopoverPosition } from '@blueprintjs/core' import { Color, FontVariation } from '@harnessio/design-system' import { Icon, IconProps } from '@harnessio/icons' @@ -23,15 +23,12 @@ import { useStrings } from 'framework/strings' import css from './PluginsPanel.module.scss' -enum PluginCategory { - Harness, - Drone +export interface PluginsPanelInterface { + onPluginAddUpdate: (isUpdate: boolean, pluginFormData: PluginForm) => void } -enum PluginPanelView { - Category, - Listing, - Configuration +export interface PluginForm { + [key: string]: string | boolean | object } interface PluginInput { @@ -41,6 +38,10 @@ interface PluginInput { options?: { isExtended?: boolean } } +interface PluginInputs { + [key: string]: PluginInput +} + interface PluginCategoryInterface { category: PluginCategory name: string @@ -57,6 +58,17 @@ interface PluginInsertionTemplateInterface { } } +enum PluginCategory { + Harness, + Drone +} + +enum PluginPanelView { + Category, + Listing, + Configuration +} + const PluginInsertionTemplate: PluginInsertionTemplateInterface = { name: '', type: 'plugin', @@ -78,10 +90,6 @@ const RunStep: TypesPlugin = { uid: 'run' } -export interface PluginsPanelInterface { - onPluginAddUpdate: (isUpdate: boolean, pluginFormData: Record) => void -} - export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX.Element => { const { getString } = useStrings() const [category, setCategory] = useState() @@ -157,11 +165,10 @@ export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX. {PluginCategories.map((item: PluginCategoryInterface) => { const { name, category: pluginCategory, description, icon } = item return ( - + handlePluginCategoryClick(pluginCategory)} - key={pluginCategory} flex={{ justifyContent: 'flex-start' }} className={css.plugin}> @@ -306,14 +313,11 @@ export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX. ) } - const constructPayloadForYAMLInsertion = ( - pluginFormData: Record, - pluginMetadata?: TypesPlugin - ): Record => { + const constructPayloadForYAMLInsertion = (pluginFormData: PluginForm, pluginMetadata?: TypesPlugin): PluginForm => { const { name, container = {} } = pluginFormData + let payload = { ...PluginInsertionTemplate } switch (category) { case PluginCategory.Drone: - let payload = { ...PluginInsertionTemplate } /* Step name is optional, set only if specified by user */ if (name) { set(payload, 'name', name) @@ -322,12 +326,12 @@ export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX. } set(payload, PluginNameFieldPath, pluginMetadata?.uid) set(payload, PluginInputsFieldPath, omit(pluginFormData, 'name')) - return payload as PluginInsertionTemplateInterface + return payload case PluginCategory.Harness: return { ...(name && { name }), type: 'run', - ...(Object.keys(container).length === 1 && container?.image + ...(Object.keys(container).length === 1 && has(container, 'image') ? { spec: { ...pluginFormData, container: get(container, 'image') } } : { spec: pluginFormData }) } @@ -351,28 +355,30 @@ export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX. return inputsClone } - const getPluginInputsFromSpec = useCallback((pluginSpec: string): Record => { + const getPluginInputsFromSpec = useCallback((pluginSpec: string): PluginInputs => { if (!pluginSpec) { return {} } try { const pluginSpecAsObj = parse(pluginSpec) return get(pluginSpecAsObj, 'spec.inputs', {}) - } catch (ex) {} + } catch (ex) { + /* ignore error */ + } return {} }, []) - const getInitialFormValues = useCallback((pluginInputs: Record): Record => { + const getInitialFormValues = useCallback((pluginInputs: PluginInputs): PluginInputs => { return Object.entries(pluginInputs).reduce((acc, [field, inputObj]) => { if (inputObj?.default) { - acc[field] = inputObj.default + set(acc, field, inputObj.default) } return acc - }, {} as Record) + }, {} as PluginInputs) }, []) const renderPluginConfigForm = useCallback((): JSX.Element => { - const pluginInputs = getPluginInputsFromSpec(get(plugin, 'spec', '') as string) + const pluginInputs = getPluginInputsFromSpec(get(plugin, 'spec', '') as string) as PluginInputs const allPluginInputs = insertNameFieldToPluginInputs(pluginInputs) return ( @@ -397,9 +403,9 @@ export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX. )} - initialValues={getInitialFormValues(pluginInputs)} - onSubmit={formData => { + onSubmit={(formData: PluginForm) => { onPluginAddUpdate?.(false, constructPayloadForYAMLInsertion(formData, plugin)) }}> diff --git a/web/src/pages/AddUpdatePipeline/AddUpdatePipeline.tsx b/web/src/pages/AddUpdatePipeline/AddUpdatePipeline.tsx index 34901b9e0..7b51d1590 100644 --- a/web/src/pages/AddUpdatePipeline/AddUpdatePipeline.tsx +++ b/web/src/pages/AddUpdatePipeline/AddUpdatePipeline.tsx @@ -12,7 +12,7 @@ import { useStrings } from 'framework/strings' import { useGetRepositoryMetadata } from 'hooks/useGetRepositoryMetadata' import { useGetResourceContent } from 'hooks/useGetResourceContent' import MonacoSourceCodeEditor from 'components/SourceCodeEditor/MonacoSourceCodeEditor' -import { PluginsPanel } from 'components/PluginsPanel/PluginsPanel' +import { PluginForm, PluginsPanel } from 'components/PluginsPanel/PluginsPanel' import useRunPipelineModal from 'components/RunPipelineModal/RunPipelineModal' import { LoadingSpinner } from 'components/LoadingSpinner/LoadingSpinner' import { useAppContext } from 'AppContext' @@ -26,7 +26,7 @@ import { DRONE_CONFIG_YAML_FILE_SUFFIXES, YamlVersion } from './Constants' import css from './AddUpdatePipeline.module.scss' -const StarterPipelineV1: Record = { +const StarterPipelineV1: Record = { version: 1, kind: 'pipeline', spec: { @@ -51,7 +51,7 @@ const StarterPipelineV1: Record = { } } -const StarterPipelineV0: Record = { +const StarterPipelineV0: Record = { kind: 'pipeline', type: 'docker', name: 'default', @@ -210,13 +210,13 @@ const AddUpdatePipeline = (): JSX.Element => { } const updatePipelineWithPluginData = ( - existingPipeline: Record, - payload: Record - ): Record => { + existingPipeline: Record, + payload: Record + ): Record => { const pipelineAsObjClone = { ...existingPipeline } if (Object.keys(pipelineAsObjClone).length > 0) { const stepInsertPath = 'spec.stages.0.spec.steps' - let existingSteps: [unknown] = get(pipelineAsObjClone, stepInsertPath, []) + let existingSteps = get(pipelineAsObjClone, stepInsertPath, []) as unknown[] if (existingSteps.length > 0) { existingSteps.push(payload) } else { @@ -234,7 +234,7 @@ const AddUpdatePipeline = (): JSX.Element => { existingYAML }: { isUpdate: boolean - pluginFormData: Record + pluginFormData: PluginForm existingYAML: string }): void => { try { @@ -408,7 +408,7 @@ const AddUpdatePipeline = (): JSX.Element => { {yamlVersion === YamlVersion.V1 && ( ) => + onPluginAddUpdate={(isUpdate: boolean, pluginFormData: PluginForm) => handlePluginAddUpdateToPipeline({ isUpdate, pluginFormData,