mirror of
https://github.com/harness/drone.git
synced 2025-05-16 08:59:56 +08:00
Merge branch 'add-list' of _OKE5H2PQKOUfzFFDuD4FA/default/CODE/gitness (#626)
This commit is contained in:
commit
032a7a89c8
23
web/src/components/MultiList/MultiList.module.scss
Normal file
23
web/src/components/MultiList/MultiList.module.scss
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2023 Harness, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
.addBtn {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.deleteRowBtn {
|
||||
cursor: pointer;
|
||||
}
|
20
web/src/components/MultiList/MultiList.module.scss.d.ts
vendored
Normal file
20
web/src/components/MultiList/MultiList.module.scss.d.ts
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2023 Harness, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* eslint-disable */
|
||||
// This is an auto-generated file
|
||||
export declare const addBtn: string
|
||||
export declare const deleteRowBtn: string
|
167
web/src/components/MultiList/MultiList.tsx
Normal file
167
web/src/components/MultiList/MultiList.tsx
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 2023 Harness, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { debounce, has, omit } from 'lodash'
|
||||
import { FormikContextType, connect } from 'formik'
|
||||
import { Layout, Text, FormInput, Button, ButtonVariation, ButtonSize, Container } from '@harnessio/uicore'
|
||||
import { FontVariation } from '@harnessio/design-system'
|
||||
import { Icon } from '@harnessio/icons'
|
||||
import { useStrings } from 'framework/strings'
|
||||
|
||||
import css from './MultiList.module.scss'
|
||||
|
||||
interface MultiListConnectedProps extends MultiListProps {
|
||||
formik?: FormikContextType<any>
|
||||
}
|
||||
|
||||
interface MultiListProps {
|
||||
name: string
|
||||
label: string
|
||||
readOnly?: boolean
|
||||
}
|
||||
|
||||
/* Allows user to create following structure:
|
||||
<field-name>:
|
||||
- <field-value-1>,
|
||||
- <field-value-2>,
|
||||
...
|
||||
*/
|
||||
export const MultiList = ({ name, label, readOnly, formik }: MultiListConnectedProps): JSX.Element => {
|
||||
const { getString } = useStrings()
|
||||
const [valueMap, setValueMap] = useState<Map<string, string>>(new Map<string, string>([]))
|
||||
/*
|
||||
<field-name-1>: <field-value-1>,
|
||||
<field-name-2>: <field-value-2>,
|
||||
...
|
||||
*/
|
||||
const counter = useRef<number>(0)
|
||||
|
||||
useEffect(() => {
|
||||
const values = Array.from(valueMap.values())
|
||||
if (values.length > 0) {
|
||||
formik?.setFieldValue(name, values)
|
||||
} else {
|
||||
cleanupField()
|
||||
}
|
||||
}, [valueMap])
|
||||
|
||||
const cleanupField = useCallback((): void => {
|
||||
formik?.setValues(omit({ ...formik?.values }, name))
|
||||
}, [formik?.values])
|
||||
|
||||
const getFieldName = useCallback(
|
||||
(index: number): string => {
|
||||
return `${name}-${index}`
|
||||
},
|
||||
[name]
|
||||
)
|
||||
|
||||
const handleAddRowToList = useCallback((): void => {
|
||||
setValueMap((existingValueMap: Map<string, string>) => {
|
||||
const rowKeyToAdd = getFieldName(counter.current)
|
||||
if (!existingValueMap.has(rowKeyToAdd)) {
|
||||
const existingValueMapClone = new Map(existingValueMap)
|
||||
existingValueMapClone.set(rowKeyToAdd, '') /* Add key <field-name-1>, <field-name-2>, ... */
|
||||
counter.current++ /* this counter always increases, even if a row is removed. This ensures no key collision in the existing value map. */
|
||||
return existingValueMapClone
|
||||
}
|
||||
return existingValueMap
|
||||
})
|
||||
}, [])
|
||||
|
||||
const handleRemoveRowFromList = useCallback((removedRowKey: string): void => {
|
||||
setValueMap((existingValueMap: Map<string, string>) => {
|
||||
if (existingValueMap.has(removedRowKey)) {
|
||||
const existingValueMapClone = new Map(existingValueMap)
|
||||
existingValueMapClone.delete(removedRowKey)
|
||||
return existingValueMapClone
|
||||
}
|
||||
return existingValueMap
|
||||
})
|
||||
/* remove <field-name-1>, <field-name-2>, ... from formik values, if exist */
|
||||
if (removedRowKey && has(formik?.values, removedRowKey)) {
|
||||
formik?.setValues(omit({ ...formik?.values }, removedRowKey))
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleAddItemToRow = useCallback((rowKey: string, insertedValue: string): void => {
|
||||
setValueMap((existingValueMap: Map<string, string>) => {
|
||||
if (existingValueMap.has(rowKey)) {
|
||||
const existingValueMapClone = new Map(existingValueMap)
|
||||
existingValueMapClone.set(rowKey, insertedValue)
|
||||
return existingValueMapClone
|
||||
}
|
||||
return existingValueMap
|
||||
})
|
||||
}, [])
|
||||
|
||||
const debouncedAddItemToList = useCallback(debounce(handleAddItemToRow, 500), [handleAddItemToRow])
|
||||
|
||||
const renderRow = useCallback((rowKey: string): React.ReactElement => {
|
||||
return (
|
||||
<Layout.Horizontal margin={{ bottom: 'none' }} flex={{ justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<Container width="90%">
|
||||
<FormInput.Text
|
||||
name={rowKey}
|
||||
disabled={readOnly}
|
||||
onChange={event => {
|
||||
const value = (event.target as HTMLInputElement).value
|
||||
debouncedAddItemToList(rowKey, value)
|
||||
}}
|
||||
/>
|
||||
</Container>
|
||||
<Icon
|
||||
name="code-delete"
|
||||
size={25}
|
||||
padding={{ bottom: 'medium' }}
|
||||
className={css.deleteRowBtn}
|
||||
onClick={event => {
|
||||
event.preventDefault()
|
||||
handleRemoveRowFromList(rowKey)
|
||||
}}
|
||||
/>
|
||||
</Layout.Horizontal>
|
||||
)
|
||||
}, [])
|
||||
|
||||
const renderRows = useCallback((): React.ReactElement => {
|
||||
const rows: React.ReactElement[] = []
|
||||
valueMap.forEach((_value: string, key: string) => {
|
||||
rows.push(renderRow(key))
|
||||
})
|
||||
return <Layout.Vertical>{rows}</Layout.Vertical>
|
||||
}, [valueMap])
|
||||
|
||||
return (
|
||||
<Layout.Vertical spacing="small">
|
||||
<Layout.Vertical>
|
||||
<Text font={{ variation: FontVariation.FORM_LABEL }}>{label}</Text>
|
||||
{valueMap.size > 0 && <Container padding={{ top: 'small' }}>{renderRows()}</Container>}
|
||||
</Layout.Vertical>
|
||||
<Button
|
||||
text={getString('addLabel')}
|
||||
rightIcon="plus"
|
||||
variation={ButtonVariation.PRIMARY}
|
||||
size={ButtonSize.SMALL}
|
||||
className={css.addBtn}
|
||||
onClick={handleAddRowToList}
|
||||
/>
|
||||
</Layout.Vertical>
|
||||
)
|
||||
}
|
||||
|
||||
export default connect(MultiList)
|
@ -68,6 +68,10 @@
|
||||
.formFields {
|
||||
height: calc(100% - var(--spacing-xlarge));
|
||||
overflow-y: scroll;
|
||||
|
||||
.toggle {
|
||||
margin-left: var(--spacing-1) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
|
@ -29,3 +29,4 @@ export declare const pluginDetailsPanel: string
|
||||
export declare const pluginIcon: string
|
||||
export declare const plugins: string
|
||||
export declare const search: string
|
||||
export declare const toggle: string
|
||||
|
@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { Formik } from 'formik'
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { Formik, FormikContextType } from 'formik'
|
||||
import { parse } from 'yaml'
|
||||
import { capitalize, get, has, omit, set } from 'lodash-es'
|
||||
import { capitalize, get, has, omit, pick, set } from 'lodash-es'
|
||||
import { Classes, PopoverInteractionKind, PopoverPosition } from '@blueprintjs/core'
|
||||
import { Color, FontVariation } from '@harnessio/design-system'
|
||||
import { Icon, IconProps } from '@harnessio/icons'
|
||||
@ -36,6 +36,7 @@ import {
|
||||
} from '@harnessio/uicore'
|
||||
import type { TypesPlugin } from 'services/code'
|
||||
import { useStrings } from 'framework/strings'
|
||||
import { MultiList } from 'components/MultiList/MultiList'
|
||||
|
||||
import css from './PluginsPanel.module.scss'
|
||||
|
||||
@ -47,8 +48,16 @@ export interface PluginForm {
|
||||
[key: string]: string | boolean | object
|
||||
}
|
||||
|
||||
enum ValueType {
|
||||
STRING = 'string',
|
||||
BOOLEAN = 'boolean',
|
||||
NUMBER = 'number',
|
||||
ARRAY = 'array',
|
||||
OBJECT = 'object'
|
||||
}
|
||||
|
||||
interface PluginInput {
|
||||
type: 'string'
|
||||
type: ValueType
|
||||
description?: string
|
||||
default?: string
|
||||
options?: { isExtended?: boolean }
|
||||
@ -114,6 +123,7 @@ export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX.
|
||||
const [plugins, setPlugins] = useState<TypesPlugin[]>([])
|
||||
const [query, setQuery] = useState<string>('')
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const formikRef = useRef<FormikContextType<PluginForm>>()
|
||||
|
||||
const PluginCategories: PluginCategoryInterface[] = [
|
||||
{
|
||||
@ -315,20 +325,52 @@ export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX.
|
||||
|
||||
const renderPluginFormField = ({ name, properties }: { name: string; properties: PluginInput }): JSX.Element => {
|
||||
const { type, options } = properties
|
||||
const { isExtended } = options || {}
|
||||
const WrapperComponent = isExtended ? FormInput.TextArea : FormInput.Text
|
||||
return type === 'string' ? (
|
||||
<WrapperComponent
|
||||
name={name}
|
||||
label={generateLabelForPluginField({ name, properties })}
|
||||
style={{ width: '100%' }}
|
||||
key={name}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
)
|
||||
|
||||
switch (type) {
|
||||
case ValueType.STRING: {
|
||||
const { isExtended } = options || {}
|
||||
const WrapperComponent = isExtended ? FormInput.TextArea : FormInput.Text
|
||||
return (
|
||||
<WrapperComponent
|
||||
name={name}
|
||||
label={generateLabelForPluginField({ name, properties })}
|
||||
style={{ width: '100%' }}
|
||||
key={name}
|
||||
/>
|
||||
)
|
||||
}
|
||||
case ValueType.BOOLEAN:
|
||||
return (
|
||||
<Container className={css.toggle}>
|
||||
<FormInput.Toggle
|
||||
name={name}
|
||||
label={generateLabelForPluginField({ name, properties }) as string}
|
||||
style={{ width: '100%' }}
|
||||
key={name}
|
||||
/>
|
||||
</Container>
|
||||
)
|
||||
case ValueType.ARRAY:
|
||||
return (
|
||||
<Container margin={{ bottom: 'large' }}>
|
||||
<MultiList
|
||||
name={name}
|
||||
label={generateLabelForPluginField({ name, properties }) as string}
|
||||
formik={formikRef.current}
|
||||
/>
|
||||
</Container>
|
||||
)
|
||||
|
||||
default:
|
||||
return <></>
|
||||
}
|
||||
}
|
||||
|
||||
/* Ensures no junk/unrecognized form values are set in the YAML */
|
||||
const sanitizeFormData = useCallback((existingFormData: PluginForm, pluginInputs: PluginInputs): PluginForm => {
|
||||
return pick(existingFormData, Object.keys(pluginInputs))
|
||||
}, [])
|
||||
|
||||
const constructPayloadForYAMLInsertion = (pluginFormData: PluginForm, pluginMetadata?: TypesPlugin): PluginForm => {
|
||||
const { name, container = {} } = pluginFormData
|
||||
let payload = { ...PluginInsertionTemplate }
|
||||
@ -422,151 +464,165 @@ export const PluginsPanel = ({ onPluginAddUpdate }: PluginsPanelInterface): JSX.
|
||||
<Formik<PluginForm>
|
||||
initialValues={getInitialFormValues(pluginInputs)}
|
||||
onSubmit={(formData: PluginForm) => {
|
||||
onPluginAddUpdate?.(false, constructPayloadForYAMLInsertion(formData, plugin))
|
||||
}}>
|
||||
<FormikForm height="100%" flex={{ justifyContent: 'space-between', alignItems: 'baseline' }}>
|
||||
<Layout.Vertical flex={{ alignItems: 'flex-start' }} height="inherit" spacing="medium">
|
||||
<Layout.Vertical
|
||||
width="100%"
|
||||
className={css.formFields}
|
||||
spacing="xsmall"
|
||||
flex={{ justifyContent: 'space-between' }}>
|
||||
{category === PluginCategory.Harness ? (
|
||||
<Layout.Vertical width="inherit">
|
||||
<FormInput.Text name={'name'} label={getString('name')} style={{ width: '100%' }} key={'name'} />
|
||||
<FormInput.TextArea
|
||||
name={'script'}
|
||||
label={getString('pluginsPanel.run.script')}
|
||||
style={{ width: '100%' }}
|
||||
key={'script'}
|
||||
/>
|
||||
<FormInput.Select
|
||||
name={'shell'}
|
||||
label={getString('pluginsPanel.run.shell')}
|
||||
style={{ width: '100%' }}
|
||||
key={'shell'}
|
||||
items={[
|
||||
{ label: getString('pluginsPanel.run.sh'), value: 'sh' },
|
||||
{ label: getString('pluginsPanel.run.bash'), value: 'bash' },
|
||||
{ label: getString('pluginsPanel.run.powershell'), value: 'powershell' },
|
||||
{ label: getString('pluginsPanel.run.pwsh'), value: 'pwsh' }
|
||||
]}
|
||||
/>
|
||||
<Accordion activeId="">
|
||||
<Accordion.Panel
|
||||
id="container"
|
||||
summary="Container"
|
||||
details={
|
||||
<Layout.Vertical className={css.indent}>
|
||||
<FormInput.Text
|
||||
name={'container.image'}
|
||||
label={getString('pluginsPanel.run.image')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.image'}
|
||||
/>
|
||||
<FormInput.Select
|
||||
name={'container.pull'}
|
||||
label={getString('pluginsPanel.run.pull')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.pull'}
|
||||
items={[
|
||||
{ label: getString('pluginsPanel.run.always'), value: 'always' },
|
||||
{ label: getString('pluginsPanel.run.never'), value: 'never' },
|
||||
{ label: getString('pluginsPanel.run.ifNotExists'), value: 'if-not-exists' }
|
||||
]}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name={'container.entrypoint'}
|
||||
label={getString('pluginsPanel.run.entrypoint')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.entrypoint'}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name={'container.network'}
|
||||
label={getString('pluginsPanel.run.network')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.network'}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name={'container.networkMode'}
|
||||
label={getString('pluginsPanel.run.networkMode')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.networkMode'}
|
||||
/>
|
||||
<FormInput.Toggle
|
||||
name={'container.privileged'}
|
||||
label={getString('pluginsPanel.run.privileged')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.privileged'}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name={'container.user'}
|
||||
label={getString('user')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.user'}
|
||||
/>
|
||||
<Accordion activeId="">
|
||||
<Accordion.Panel
|
||||
id="container.credentials"
|
||||
summary={getString('pluginsPanel.run.credentials')}
|
||||
details={
|
||||
<Layout.Vertical className={css.indent}>
|
||||
<FormInput.Text
|
||||
name={'container.credentials.username'}
|
||||
label={getString('pluginsPanel.run.username')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.credentials.username'}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name={'container.credentials.password'}
|
||||
label={getString('pluginsPanel.run.password')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.credentials.password'}
|
||||
/>
|
||||
</Layout.Vertical>
|
||||
}
|
||||
/>
|
||||
</Accordion>
|
||||
</Layout.Vertical>
|
||||
}
|
||||
/>
|
||||
<Accordion.Panel
|
||||
id="mount"
|
||||
summary="Mount"
|
||||
details={
|
||||
<Layout.Vertical className={css.indent}>
|
||||
<FormInput.Text
|
||||
name={'mount.name'}
|
||||
label={getString('name')}
|
||||
style={{ width: '100%' }}
|
||||
key={'mount.name'}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name={'mount.path'}
|
||||
label={getString('pluginsPanel.run.path')}
|
||||
style={{ width: '100%' }}
|
||||
key={'mount.path'}
|
||||
/>
|
||||
</Layout.Vertical>
|
||||
}
|
||||
/>
|
||||
</Accordion>
|
||||
onPluginAddUpdate?.(
|
||||
false,
|
||||
constructPayloadForYAMLInsertion(sanitizeFormData(formData, pluginInputs), plugin)
|
||||
)
|
||||
}}
|
||||
validate={(formData: PluginForm) => console.log(formData)}>
|
||||
{formik => {
|
||||
formikRef.current = formik
|
||||
return (
|
||||
<FormikForm height="100%" flex={{ justifyContent: 'space-between', alignItems: 'baseline' }}>
|
||||
<Layout.Vertical flex={{ alignItems: 'flex-start' }} height="inherit" spacing="medium">
|
||||
<Layout.Vertical
|
||||
width="100%"
|
||||
className={css.formFields}
|
||||
spacing="xsmall"
|
||||
flex={{ justifyContent: 'space-between' }}>
|
||||
{category === PluginCategory.Harness ? (
|
||||
<Layout.Vertical width="inherit">
|
||||
<FormInput.Text
|
||||
name={'name'}
|
||||
label={getString('name')}
|
||||
style={{ width: '100%' }}
|
||||
key={'name'}
|
||||
/>
|
||||
<FormInput.TextArea
|
||||
name={'script'}
|
||||
label={getString('pluginsPanel.run.script')}
|
||||
style={{ width: '100%' }}
|
||||
key={'script'}
|
||||
/>
|
||||
<FormInput.Select
|
||||
name={'shell'}
|
||||
label={getString('pluginsPanel.run.shell')}
|
||||
style={{ width: '100%' }}
|
||||
key={'shell'}
|
||||
items={[
|
||||
{ label: getString('pluginsPanel.run.sh'), value: 'sh' },
|
||||
{ label: getString('pluginsPanel.run.bash'), value: 'bash' },
|
||||
{ label: getString('pluginsPanel.run.powershell'), value: 'powershell' },
|
||||
{ label: getString('pluginsPanel.run.pwsh'), value: 'pwsh' }
|
||||
]}
|
||||
/>
|
||||
<Accordion activeId="">
|
||||
<Accordion.Panel
|
||||
id="container"
|
||||
summary="Container"
|
||||
details={
|
||||
<Layout.Vertical className={css.indent}>
|
||||
<FormInput.Text
|
||||
name={'container.image'}
|
||||
label={getString('pluginsPanel.run.image')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.image'}
|
||||
/>
|
||||
<FormInput.Select
|
||||
name={'container.pull'}
|
||||
label={getString('pluginsPanel.run.pull')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.pull'}
|
||||
items={[
|
||||
{ label: getString('pluginsPanel.run.always'), value: 'always' },
|
||||
{ label: getString('pluginsPanel.run.never'), value: 'never' },
|
||||
{ label: getString('pluginsPanel.run.ifNotExists'), value: 'if-not-exists' }
|
||||
]}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name={'container.entrypoint'}
|
||||
label={getString('pluginsPanel.run.entrypoint')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.entrypoint'}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name={'container.network'}
|
||||
label={getString('pluginsPanel.run.network')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.network'}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name={'container.networkMode'}
|
||||
label={getString('pluginsPanel.run.networkMode')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.networkMode'}
|
||||
/>
|
||||
<FormInput.Toggle
|
||||
name={'container.privileged'}
|
||||
label={getString('pluginsPanel.run.privileged')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.privileged'}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name={'container.user'}
|
||||
label={getString('user')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.user'}
|
||||
/>
|
||||
<Accordion activeId="">
|
||||
<Accordion.Panel
|
||||
id="container.credentials"
|
||||
summary={getString('pluginsPanel.run.credentials')}
|
||||
details={
|
||||
<Layout.Vertical className={css.indent}>
|
||||
<FormInput.Text
|
||||
name={'container.credentials.username'}
|
||||
label={getString('pluginsPanel.run.username')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.credentials.username'}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name={'container.credentials.password'}
|
||||
label={getString('pluginsPanel.run.password')}
|
||||
style={{ width: '100%' }}
|
||||
key={'container.credentials.password'}
|
||||
/>
|
||||
</Layout.Vertical>
|
||||
}
|
||||
/>
|
||||
</Accordion>
|
||||
</Layout.Vertical>
|
||||
}
|
||||
/>
|
||||
<Accordion.Panel
|
||||
id="mount"
|
||||
summary="Mount"
|
||||
details={
|
||||
<Layout.Vertical className={css.indent}>
|
||||
<FormInput.Text
|
||||
name={'mount.name'}
|
||||
label={getString('name')}
|
||||
style={{ width: '100%' }}
|
||||
key={'mount.name'}
|
||||
/>
|
||||
<FormInput.Text
|
||||
name={'mount.path'}
|
||||
label={getString('pluginsPanel.run.path')}
|
||||
style={{ width: '100%' }}
|
||||
key={'mount.path'}
|
||||
/>
|
||||
</Layout.Vertical>
|
||||
}
|
||||
/>
|
||||
</Accordion>
|
||||
</Layout.Vertical>
|
||||
) : Object.keys(pluginInputs).length > 0 ? (
|
||||
<Layout.Vertical width="inherit">
|
||||
{Object.keys(allPluginInputs).map((field: string) => {
|
||||
return renderPluginFormField({ name: field, properties: get(allPluginInputs, field) })
|
||||
})}
|
||||
</Layout.Vertical>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Layout.Vertical>
|
||||
) : Object.keys(pluginInputs).length > 0 ? (
|
||||
<Layout.Vertical width="inherit">
|
||||
{Object.keys(allPluginInputs).map((field: string) => {
|
||||
return renderPluginFormField({ name: field, properties: get(allPluginInputs, field) })
|
||||
})}
|
||||
</Layout.Vertical>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Layout.Vertical>
|
||||
<Container margin={{ top: 'small', bottom: 'small' }}>
|
||||
<Button variation={ButtonVariation.PRIMARY} text={getString('addLabel')} type="submit" />
|
||||
</Container>
|
||||
</Layout.Vertical>
|
||||
</FormikForm>
|
||||
<Container margin={{ top: 'small', bottom: 'small' }}>
|
||||
<Button variation={ButtonVariation.PRIMARY} text={getString('addLabel')} type="submit" />
|
||||
</Container>
|
||||
</Layout.Vertical>
|
||||
</FormikForm>
|
||||
)
|
||||
}}
|
||||
</Formik>
|
||||
</Container>
|
||||
</Layout.Vertical>
|
||||
|
Loading…
Reference in New Issue
Block a user