forked from validatedpatterns/patterns-operator
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSecretFormExpandableSections.tsx
More file actions
101 lines (95 loc) · 3.82 KB
/
Copy pathSecretFormExpandableSections.tsx
File metadata and controls
101 lines (95 loc) · 3.82 KB
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
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { Card, CardBody, CardTitle, ExpandableSection, FormGroup } from '@patternfly/react-core';
import { SecretDefinition, SecretField, SecretFormData } from '../../types';
import { getSecretFieldKind } from '../../vaultSecrets';
import { GenerateField } from './GenerateField';
import { FileField } from './FileField';
import { IniField } from './IniField';
import { StaticField } from './StaticField';
import './SecretForm.css';
export type SecretFormExpandableSectionsProps = {
secrets: SecretDefinition[];
secretFormData: SecretFormData;
expandedSections: Record<string, boolean>;
onToggleSection: (sectionName: string) => void;
onFieldChange: (secretName: string, fieldName: string, value: string | null) => void;
/** When true, empty `file` / `ini` fields show validation errors (after a blocked submit). */
secretsValidationAttempted?: boolean;
};
/**
* Expandable cards per secret definition with typed fields (generate, file, ini, static).
*/
export function SecretFormExpandableSections({
secrets,
secretFormData,
expandedSections,
onToggleSection,
onFieldChange,
secretsValidationAttempted = false,
}: SecretFormExpandableSectionsProps) {
const { t } = useTranslation('plugin__patterns-operator-console-plugin');
const renderField = (secret: SecretDefinition, field: SecretField, uploadFieldError?: string) => {
const fieldType = getSecretFieldKind(field);
const value = secretFormData[secret.name]?.[field.name] || '';
const commonProps = {
field,
value,
onChange: (newValue: string | null) => onFieldChange(secret.name, field.name, newValue),
};
switch (fieldType) {
case 'generate':
return <GenerateField key={field.name} {...commonProps} />;
case 'file':
return <FileField key={field.name} {...commonProps} fieldError={uploadFieldError} />;
case 'ini':
return <IniField key={field.name} {...commonProps} fieldError={uploadFieldError} />;
case 'static':
return <StaticField key={field.name} {...commonProps} />;
default:
return <StaticField key={field.name} {...commonProps} />;
}
};
return (
<div className="patterns-operator__secret-form">
{secrets.map((secret) => (
<ExpandableSection
key={secret.name}
toggleText={secret.name}
isExpanded={expandedSections[secret.name] || false}
onToggle={() => onToggleSection(secret.name)}
className="patterns-operator__secret-section"
>
<Card>
<CardTitle>{secret.name}</CardTitle>
<CardBody>
{secret.fields.map((field) => {
const fieldType = getSecretFieldKind(field);
const rawVal = secretFormData[secret.name]?.[field.name];
const emptyFileIni =
(fieldType === 'file' || fieldType === 'ini') &&
(rawVal === null || rawVal === undefined || rawVal === '');
const showFileIniError = secretsValidationAttempted && emptyFileIni;
const helperInvalid =
fieldType === 'file'
? t('A file upload is required.')
: t('An INI file upload is required.');
return (
<FormGroup
key={field.name}
label={field.name}
isRequired={true}
fieldId={`secret-${secret.name}-${field.name}`}
className="patterns-operator__secret-field"
>
{renderField(secret, field, showFileIniError ? helperInvalid : undefined)}
</FormGroup>
);
})}
</CardBody>
</Card>
</ExpandableSection>
))}
</div>
);
}