diff --git a/src/shared/schema/bi/types/forms.ts b/src/shared/schema/bi/types/forms.ts index ad956b886d..20ef4f8a32 100644 --- a/src/shared/schema/bi/types/forms.ts +++ b/src/shared/schema/bi/types/forms.ts @@ -122,6 +122,14 @@ export type HiddenItem = BaseItem & { defaultValue?: ConnectionData[keyof ConnectionData]; }; +export type KeyValueItem = BaseItem & { + id: 'key_value'; + keys: SelectProps['options']; + keySelectProps?: Partial; + valueInputProps?: Partial; + secret?: boolean; +}; + export type ConnectorFormItem = | LabelItem | InputItem @@ -133,7 +141,8 @@ export type ConnectorFormItem = | PlainTextItem | DescriptionItem | FileInputItem - | HiddenItem; + | HiddenItem + | KeyValueItem; export type CustomizableRow = { items: ConnectorFormItem[]; diff --git a/src/shared/types/connections.ts b/src/shared/types/connections.ts index 3ea390c128..ad4c6b6ec5 100644 --- a/src/shared/types/connections.ts +++ b/src/shared/types/connections.ts @@ -2,7 +2,7 @@ import type {ConnectionQueryTypeValues} from '../constants'; export type ConnectionData = Record< string, - string | number | boolean | unknown[] | null | undefined | ConnectionOptions + string | number | boolean | unknown[] | null | undefined | Record >; export type ConnectionOptions = { diff --git a/src/ui/units/connections/components/ConnectorForm/FormRow/FormItem.tsx b/src/ui/units/connections/components/ConnectorForm/FormRow/FormItem.tsx index 8cdf5705af..9e9ba91e97 100644 --- a/src/ui/units/connections/components/ConnectorForm/FormRow/FormItem.tsx +++ b/src/ui/units/connections/components/ConnectorForm/FormRow/FormItem.tsx @@ -9,6 +9,7 @@ import { Description, FileInput, Input, + KeyValue, Label, PlainText, RadioButton, @@ -82,6 +83,10 @@ export const FormItem = ({item, readonly}: {item: ConnectorFormItem; readonly?: case 'hidden': { return null; } + case 'key_value': { + const {id: _id, ...itemProps} = item; + return ; + } default: { logger.logError(`FormItem (conn): unknown item id "${(item as ConnectorFormItem).id}"`); return null; diff --git a/src/ui/units/connections/components/ConnectorForm/components/KeyValue/KeyValue.scss b/src/ui/units/connections/components/ConnectorForm/components/KeyValue/KeyValue.scss new file mode 100644 index 0000000000..06fe593cdf --- /dev/null +++ b/src/ui/units/connections/components/ConnectorForm/components/KeyValue/KeyValue.scss @@ -0,0 +1,25 @@ +.conn-form-key-value { + display: flex; + flex-direction: column; + row-gap: 10px; + width: 100%; + + &__add-button { + width: fit-content; + } + + &__entry { + display: flex; + column-gap: 10px; + } + + &__key-select { + flex-shrink: 0; + max-width: 40%; + } + + &__value-input { + flex-shrink: 1; + flex-basis: auto; + } +} diff --git a/src/ui/units/connections/components/ConnectorForm/components/KeyValue/KeyValue.tsx b/src/ui/units/connections/components/ConnectorForm/components/KeyValue/KeyValue.tsx new file mode 100644 index 0000000000..4c8f5dbb9d --- /dev/null +++ b/src/ui/units/connections/components/ConnectorForm/components/KeyValue/KeyValue.tsx @@ -0,0 +1,110 @@ +import React from 'react'; + +import {Plus, Xmark} from '@gravity-ui/icons'; +import {Button, Icon, PasswordInput, Select, TextInput} from '@gravity-ui/uikit'; +import block from 'bem-cn-lite'; +import type {KeyValueItem} from 'shared/schema/types'; + +import {i18n10647} from '../../../../constants'; + +import {useKeyValueProps, useKeyValueState} from './hooks'; +import type {KeyValueEntry, KeyValueProps} from './types'; + +import './KeyValue.scss'; + +const b = block('conn-form-key-value'); +const ICON_SIZE = 18; + +type KeyValueEntryViewProps = Omit & { + index: number; + entry: KeyValueEntry; + onDelete: (index: number) => void; + onUpdate: (index: number, updates: Partial) => void; +}; + +const KeyValueEntryView = (props: KeyValueEntryViewProps) => { + const {index, keys, entry, keySelectProps, valueInputProps, secret, onDelete, onUpdate} = props; + let placeholder = valueInputProps?.placeholder; + + if (entry.initial && secret && !placeholder) { + placeholder = i18n10647['label_secret-value']; + } + + if (entry.value === null) { + return null; + } + + return ( +
+