From 839b3e3bb6c0ce4fc90a1118011dfb70431197e8 Mon Sep 17 00:00:00 2001 From: Vardan Bansal Date: Tue, 19 Sep 2023 16:32:17 -0700 Subject: [PATCH 01/20] integrate api, parsing spec to get plugin inputs --- .../components/PluginsPanel/PluginsPanel.tsx | 126 ++++++++++-------- 1 file changed, 70 insertions(+), 56 deletions(-) diff --git a/web/src/components/PluginsPanel/PluginsPanel.tsx b/web/src/components/PluginsPanel/PluginsPanel.tsx index 2f598e204..67454a3bd 100644 --- a/web/src/components/PluginsPanel/PluginsPanel.tsx +++ b/web/src/components/PluginsPanel/PluginsPanel.tsx @@ -1,16 +1,17 @@ import React, { useCallback, useEffect, useState } from 'react' +import { useGet } from 'restful-react' import { Formik } from 'formik' +import { parse } from 'yaml' import { capitalize, get, omit, set } from 'lodash-es' import { Classes, PopoverInteractionKind, PopoverPosition } from '@blueprintjs/core' +import type { TypesPlugin } from 'services/code' import { Color, FontVariation } from '@harnessio/design-system' import { Icon, type IconName } from '@harnessio/icons' import { Button, ButtonVariation, Container, FormInput, FormikForm, Layout, Popover, Text } from '@harnessio/uicore' import { useStrings } from 'framework/strings' - -import pluginList from './plugins/plugins.json' +import { LIST_FETCHING_LIMIT } from 'utils/Utils' import css from './PluginsPanel.module.scss' - enum PluginCategory { Harness, Drone @@ -29,15 +30,6 @@ interface PluginInput { options?: { isExtended?: boolean } } -interface Plugin { - name: string - spec: { - name: string - description?: string - inputs: { [key: string]: PluginInput } - } -} - interface PluginCategoryInterface { category: PluginCategory name: string @@ -60,26 +52,26 @@ const StepNameInput: PluginInput = { description: 'Name of the step' } -const RunStep: Plugin = { - name: 'run', - spec: { - name: 'Run', - inputs: { - name: StepNameInput, - image: { - type: 'string' - }, - script: { - type: 'string', - options: { isExtended: true } - } - } - } -} +// const RunStep: Plugin = { +// name: 'run', +// spec: { +// name: 'Run', +// inputs: { +// name: StepNameInput, +// image: { +// type: 'string' +// }, +// script: { +// type: 'string', +// options: { isExtended: true } +// } +// } +// } +// } interface PluginInsertionTemplateInterface { name?: string - type: 'plugin' + type: 'plugins' spec: { name: string inputs: { [key: string]: string } @@ -88,7 +80,7 @@ interface PluginInsertionTemplateInterface { const PluginInsertionTemplate: PluginInsertionTemplateInterface = { name: '', - type: 'plugin', + type: 'plugins', spec: { name: '', inputs: { @@ -109,16 +101,20 @@ export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX. const { getString } = useStrings() const [category, setCategory] = useState() const [panelView, setPanelView] = useState(PluginPanelView.Category) - const [plugin, setPlugin] = useState() - const [plugins, setPlugins] = useState() - const [loading] = useState(false) + const [plugin, setPlugin] = useState() - const fetchPlugins = () => { - /* temporarily done till api response gets available */ - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - //@ts-ignore - setPlugins(pluginList) - } + const { + data: plugins, + refetch: fetchPlugins, + loading + } = useGet({ + path: `/api/v1/plugins`, + queryParams: { + limit: LIST_FETCHING_LIMIT, + page: 1 + }, + lazy: true + }) useEffect(() => { if (category === PluginCategory.Drone) { @@ -138,7 +134,7 @@ export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX. if (pluginCategory === PluginCategory.Drone) { setPanelView(PluginPanelView.Listing) } else if (pluginCategory === PluginCategory.Harness) { - setPlugin(RunStep) + // setPlugin(RunStep) setPanelView(PluginPanelView.Configuration) } }} @@ -183,8 +179,8 @@ export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX. /> - {plugins?.map((pluginItem: Plugin) => { - const { name: uid, description } = pluginItem.spec + {plugins?.map((pluginItem: TypesPlugin) => { + const { uid, description } = pluginItem return ( , - pluginMetadata?: Plugin + pluginMetadata?: TypesPlugin ): Record => { const { name, image, script } = pluginFormData switch (category) { case PluginCategory.Drone: - const payload = { ...PluginInsertionTemplate } - set(payload, 'name', name) - set(payload, PluginNameFieldPath, pluginMetadata?.name) + let payload = { ...PluginInsertionTemplate } + /* Step name is optional, set only if specified by user */ + if (name) { + set(payload, 'name', name) + } else { + payload = omit(payload, 'name') + } + set(payload, PluginNameFieldPath, pluginMetadata?.uid) set(payload, PluginInputsFieldPath, omit(pluginFormData, 'name')) return payload as PluginInsertionTemplateInterface case PluginCategory.Harness: @@ -298,8 +299,23 @@ export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX. return inputsClone } + const getPluginInputsFromSpec = useCallback((pluginSpec: string): Record => { + if (!pluginSpec) { + return {} + } + try { + const pluginSpecAsObj = parse(pluginSpec) + return get(pluginSpecAsObj, 'spec.inputs', {}) + } catch (ex) {} + return {} + }, []) + const renderPluginConfigForm = useCallback((): JSX.Element => { - const inputs: { [key: string]: PluginInput } = insertNameFieldToPluginInputs(get(plugin, 'spec.inputs', {})) + const pluginInputs = getPluginInputsFromSpec(get(plugin, 'spec', '') as string) + if (Object.keys(pluginInputs).length === 0) { + return <> + } + const allPluginInputs = insertNameFieldToPluginInputs(pluginInputs) return ( - {plugin?.spec?.name && ( + {plugin?.uid && ( - {getString('addLabel')} {plugin.spec.name} {getString('plugins.stepLabel')} + {getString('addLabel')} {plugin.uid} {getString('plugins.stepLabel')} )} @@ -333,13 +349,11 @@ export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX. }}> - {inputs && ( - - {Object.keys(inputs).map((field: string) => { - return renderPluginFormField({ name: field, properties: get(inputs, field) }) - })} - - )} + + {Object.keys(allPluginInputs).map((field: string) => { + return renderPluginFormField({ name: field, properties: get(allPluginInputs, field) }) + })} +