mirror of https://github.com/portainer/portainer
fix(custom-templates): render template
parent
578f3d34a1
commit
ba67f4be3b
|
@ -1,6 +1,5 @@
|
||||||
import { AccessControlFormData } from '@/portainer/components/accessControlForm/porAccessControlFormModel';
|
import { AccessControlFormData } from '@/portainer/components/accessControlForm/porAccessControlFormModel';
|
||||||
import { getTemplateVariables, intersectVariables } from '@/react/portainer/custom-templates/components/utils';
|
import { getTemplateVariables, intersectVariables, isTemplateVariablesEnabled } from '@/react/portainer/custom-templates/components/utils';
|
||||||
import { isBE } from '@/react/portainer/feature-flags/feature-flags.service';
|
|
||||||
import { editor, upload, git } from '@@/BoxSelector/common-options/build-methods';
|
import { editor, upload, git } from '@@/BoxSelector/common-options/build-methods';
|
||||||
import { confirmWebEditorDiscard } from '@@/modals/confirm';
|
import { confirmWebEditorDiscard } from '@@/modals/confirm';
|
||||||
import { KUBE_TEMPLATE_NAME_VALIDATION_REGEX } from '@/constants';
|
import { KUBE_TEMPLATE_NAME_VALIDATION_REGEX } from '@/constants';
|
||||||
|
@ -13,7 +12,7 @@ class KubeCreateCustomTemplateViewController {
|
||||||
this.methodOptions = [editor, upload, git];
|
this.methodOptions = [editor, upload, git];
|
||||||
|
|
||||||
this.templates = null;
|
this.templates = null;
|
||||||
this.isTemplateVariablesEnabled = isBE;
|
this.isTemplateVariablesEnabled = isTemplateVariablesEnabled;
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
method: 'editor',
|
method: 'editor',
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { ResourceControlViewModel } from '@/react/portainer/access-control/models/ResourceControlViewModel';
|
import { ResourceControlViewModel } from '@/react/portainer/access-control/models/ResourceControlViewModel';
|
||||||
import { AccessControlFormData } from '@/portainer/components/accessControlForm/porAccessControlFormModel';
|
import { AccessControlFormData } from '@/portainer/components/accessControlForm/porAccessControlFormModel';
|
||||||
import { isBE } from '@/react/portainer/feature-flags/feature-flags.service';
|
import { getTemplateVariables, intersectVariables, isTemplateVariablesEnabled } from '@/react/portainer/custom-templates/components/utils';
|
||||||
import { getTemplateVariables, intersectVariables } from '@/react/portainer/custom-templates/components/utils';
|
|
||||||
import { confirmWebEditorDiscard } from '@@/modals/confirm';
|
import { confirmWebEditorDiscard } from '@@/modals/confirm';
|
||||||
import { getFilePreview } from '@/react/portainer/gitops/gitops.service';
|
import { getFilePreview } from '@/react/portainer/gitops/gitops.service';
|
||||||
import { KUBE_TEMPLATE_NAME_VALIDATION_REGEX } from '@/constants';
|
import { KUBE_TEMPLATE_NAME_VALIDATION_REGEX } from '@/constants';
|
||||||
|
@ -11,7 +10,7 @@ class KubeEditCustomTemplateViewController {
|
||||||
constructor($async, $state, Authentication, CustomTemplateService, FormValidator, Notifications, ResourceControlService) {
|
constructor($async, $state, Authentication, CustomTemplateService, FormValidator, Notifications, ResourceControlService) {
|
||||||
Object.assign(this, { $async, $state, Authentication, CustomTemplateService, FormValidator, Notifications, ResourceControlService });
|
Object.assign(this, { $async, $state, Authentication, CustomTemplateService, FormValidator, Notifications, ResourceControlService });
|
||||||
|
|
||||||
this.isTemplateVariablesEnabled = isBE;
|
this.isTemplateVariablesEnabled = isTemplateVariablesEnabled;
|
||||||
|
|
||||||
this.formValues = {
|
this.formValues = {
|
||||||
Variables: [],
|
Variables: [],
|
||||||
|
|
|
@ -4,14 +4,14 @@ import stripAnsi from 'strip-ansi';
|
||||||
|
|
||||||
import PortainerError from '@/portainer/error';
|
import PortainerError from '@/portainer/error';
|
||||||
import { KubernetesDeployManifestTypes, KubernetesDeployBuildMethods, KubernetesDeployRequestMethods, RepositoryMechanismTypes } from 'Kubernetes/models/deploy';
|
import { KubernetesDeployManifestTypes, KubernetesDeployBuildMethods, KubernetesDeployRequestMethods, RepositoryMechanismTypes } from 'Kubernetes/models/deploy';
|
||||||
import { renderTemplate } from '@/react/portainer/custom-templates/components/utils';
|
import { isTemplateVariablesEnabled, renderTemplate } from '@/react/portainer/custom-templates/components/utils';
|
||||||
import { getDeploymentOptions } from '@/react/portainer/environments/environment.service';
|
import { getDeploymentOptions } from '@/react/portainer/environments/environment.service';
|
||||||
import { isBE } from '@/react/portainer/feature-flags/feature-flags.service';
|
|
||||||
import { kubernetes } from '@@/BoxSelector/common-options/deployment-methods';
|
import { kubernetes } from '@@/BoxSelector/common-options/deployment-methods';
|
||||||
import { editor, git, customTemplate, url, helm } from '@@/BoxSelector/common-options/build-methods';
|
import { editor, git, customTemplate, url, helm } from '@@/BoxSelector/common-options/build-methods';
|
||||||
import { parseAutoUpdateResponse, transformAutoUpdateViewModel } from '@/react/portainer/gitops/AutoUpdateFieldset/utils';
|
import { parseAutoUpdateResponse, transformAutoUpdateViewModel } from '@/react/portainer/gitops/AutoUpdateFieldset/utils';
|
||||||
import { baseStackWebhookUrl, createWebhookId } from '@/portainer/helpers/webhookHelper';
|
import { baseStackWebhookUrl, createWebhookId } from '@/portainer/helpers/webhookHelper';
|
||||||
import { confirmWebEditorDiscard } from '@@/modals/confirm';
|
import { confirmWebEditorDiscard } from '@@/modals/confirm';
|
||||||
|
import { getVariablesFieldDefaultValues } from '@/react/portainer/custom-templates/components/CustomTemplatesVariablesField';
|
||||||
|
|
||||||
class KubernetesDeployController {
|
class KubernetesDeployController {
|
||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
|
@ -25,7 +25,7 @@ class KubernetesDeployController {
|
||||||
this.StackService = StackService;
|
this.StackService = StackService;
|
||||||
this.CustomTemplateService = CustomTemplateService;
|
this.CustomTemplateService = CustomTemplateService;
|
||||||
|
|
||||||
this.isTemplateVariablesEnabled = isBE;
|
this.isTemplateVariablesEnabled = isTemplateVariablesEnabled;
|
||||||
|
|
||||||
this.deployOptions = [{ ...kubernetes, value: KubernetesDeployManifestTypes.KUBERNETES }];
|
this.deployOptions = [{ ...kubernetes, value: KubernetesDeployManifestTypes.KUBERNETES }];
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ class KubernetesDeployController {
|
||||||
RepositoryPassword: '',
|
RepositoryPassword: '',
|
||||||
AdditionalFiles: [],
|
AdditionalFiles: [],
|
||||||
ComposeFilePathInRepository: '',
|
ComposeFilePathInRepository: '',
|
||||||
Variables: {},
|
Variables: [],
|
||||||
AutoUpdate: parseAutoUpdateResponse(),
|
AutoUpdate: parseAutoUpdateResponse(),
|
||||||
TLSSkipVerify: false,
|
TLSSkipVerify: false,
|
||||||
Name: '',
|
Name: '',
|
||||||
|
@ -220,7 +220,7 @@ class KubernetesDeployController {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (template.Variables && template.Variables.length > 0) {
|
if (template.Variables && template.Variables.length > 0) {
|
||||||
const variables = Object.fromEntries(template.Variables.map((variable) => [variable.name, '']));
|
const variables = getVariablesFieldDefaultValues(template.Variables);
|
||||||
this.onChangeTemplateVariables(variables);
|
this.onChangeTemplateVariables(variables);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
@ -26,6 +26,7 @@ export const ngModule = angular
|
||||||
'value',
|
'value',
|
||||||
'onChange',
|
'onChange',
|
||||||
'definitions',
|
'definitions',
|
||||||
|
'errors',
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
.component('customTemplatesVariablesField', VariablesFieldAngular)
|
.component('customTemplatesVariablesField', VariablesFieldAngular)
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { AccessControlFormData } from 'Portainer/components/accessControlForm/porAccessControlFormModel';
|
import { AccessControlFormData } from 'Portainer/components/accessControlForm/porAccessControlFormModel';
|
||||||
import { TEMPLATE_NAME_VALIDATION_REGEX } from '@/constants';
|
import { TEMPLATE_NAME_VALIDATION_REGEX } from '@/constants';
|
||||||
import { getTemplateVariables, intersectVariables } from '@/react/portainer/custom-templates/components/utils';
|
import { getTemplateVariables, intersectVariables, isTemplateVariablesEnabled } from '@/react/portainer/custom-templates/components/utils';
|
||||||
import { isBE } from '@/react/portainer/feature-flags/feature-flags.service';
|
|
||||||
import { editor, upload, git } from '@@/BoxSelector/common-options/build-methods';
|
import { editor, upload, git } from '@@/BoxSelector/common-options/build-methods';
|
||||||
import { confirmWebEditorDiscard } from '@@/modals/confirm';
|
import { confirmWebEditorDiscard } from '@@/modals/confirm';
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ class CreateCustomTemplateViewController {
|
||||||
|
|
||||||
this.buildMethods = [editor, upload, git];
|
this.buildMethods = [editor, upload, git];
|
||||||
|
|
||||||
this.isTemplateVariablesEnabled = isBE;
|
this.isTemplateVariablesEnabled = isTemplateVariablesEnabled;
|
||||||
|
|
||||||
this.formValues = {
|
this.formValues = {
|
||||||
Title: '',
|
Title: '',
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import _ from 'lodash-es';
|
import _ from 'lodash-es';
|
||||||
import { AccessControlFormData } from 'Portainer/components/accessControlForm/porAccessControlFormModel';
|
import { AccessControlFormData } from 'Portainer/components/accessControlForm/porAccessControlFormModel';
|
||||||
import { TEMPLATE_NAME_VALIDATION_REGEX } from '@/constants';
|
import { TEMPLATE_NAME_VALIDATION_REGEX } from '@/constants';
|
||||||
import { renderTemplate } from '@/react/portainer/custom-templates/components/utils';
|
import { isTemplateVariablesEnabled, renderTemplate } from '@/react/portainer/custom-templates/components/utils';
|
||||||
import { isBE } from '@/react/portainer/feature-flags/feature-flags.service';
|
|
||||||
import { confirmDelete } from '@@/modals/confirm';
|
import { confirmDelete } from '@@/modals/confirm';
|
||||||
|
import { getVariablesFieldDefaultValues } from '@/react/portainer/custom-templates/components/CustomTemplatesVariablesField';
|
||||||
|
|
||||||
class CustomTemplatesViewController {
|
class CustomTemplatesViewController {
|
||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
|
@ -34,7 +34,7 @@ class CustomTemplatesViewController {
|
||||||
this.StateManager = StateManager;
|
this.StateManager = StateManager;
|
||||||
this.StackService = StackService;
|
this.StackService = StackService;
|
||||||
|
|
||||||
this.isTemplateVariablesEnabled = isBE;
|
this.isTemplateVariablesEnabled = isTemplateVariablesEnabled;
|
||||||
|
|
||||||
this.DOCKER_STANDALONE = 'DOCKER_STANDALONE';
|
this.DOCKER_STANDALONE = 'DOCKER_STANDALONE';
|
||||||
this.DOCKER_SWARM_MODE = 'DOCKER_SWARM_MODE';
|
this.DOCKER_SWARM_MODE = 'DOCKER_SWARM_MODE';
|
||||||
|
@ -221,7 +221,7 @@ class CustomTemplatesViewController {
|
||||||
this.state.deployable = this.isDeployable(applicationState.endpoint, template.Type);
|
this.state.deployable = this.isDeployable(applicationState.endpoint, template.Type);
|
||||||
|
|
||||||
if (template.Variables && template.Variables.length > 0) {
|
if (template.Variables && template.Variables.length > 0) {
|
||||||
const variables = Object.fromEntries(template.Variables.map((variable) => [variable.name, '']));
|
const variables = getVariablesFieldDefaultValues(template.Variables);
|
||||||
this.onChangeTemplateVariables(variables);
|
this.onChangeTemplateVariables(variables);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,7 @@ import { ResourceControlViewModel } from '@/react/portainer/access-control/model
|
||||||
import { TEMPLATE_NAME_VALIDATION_REGEX } from '@/constants';
|
import { TEMPLATE_NAME_VALIDATION_REGEX } from '@/constants';
|
||||||
|
|
||||||
import { AccessControlFormData } from 'Portainer/components/accessControlForm/porAccessControlFormModel';
|
import { AccessControlFormData } from 'Portainer/components/accessControlForm/porAccessControlFormModel';
|
||||||
import { getTemplateVariables, intersectVariables } from '@/react/portainer/custom-templates/components/utils';
|
import { getTemplateVariables, intersectVariables, isTemplateVariablesEnabled } from '@/react/portainer/custom-templates/components/utils';
|
||||||
import { isBE } from '@/react/portainer/feature-flags/feature-flags.service';
|
|
||||||
import { confirmWebEditorDiscard } from '@@/modals/confirm';
|
import { confirmWebEditorDiscard } from '@@/modals/confirm';
|
||||||
|
|
||||||
class EditCustomTemplateViewController {
|
class EditCustomTemplateViewController {
|
||||||
|
@ -13,7 +12,7 @@ class EditCustomTemplateViewController {
|
||||||
constructor($async, $state, $window, Authentication, CustomTemplateService, FormValidator, Notifications, ResourceControlService) {
|
constructor($async, $state, $window, Authentication, CustomTemplateService, FormValidator, Notifications, ResourceControlService) {
|
||||||
Object.assign(this, { $async, $state, $window, Authentication, CustomTemplateService, FormValidator, Notifications, ResourceControlService });
|
Object.assign(this, { $async, $state, $window, Authentication, CustomTemplateService, FormValidator, Notifications, ResourceControlService });
|
||||||
|
|
||||||
this.isTemplateVariablesEnabled = isBE;
|
this.isTemplateVariablesEnabled = isTemplateVariablesEnabled;
|
||||||
|
|
||||||
this.formValues = {
|
this.formValues = {
|
||||||
Variables: [],
|
Variables: [],
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { VariableDefinition } from '../CustomTemplatesVariablesDefinitionField/C
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CustomTemplatesVariablesField,
|
CustomTemplatesVariablesField,
|
||||||
Variables,
|
Values,
|
||||||
} from './CustomTemplatesVariablesField';
|
} from './CustomTemplatesVariablesField';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -34,10 +34,8 @@ const definitions: VariableDefinition[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
function Template() {
|
function Template() {
|
||||||
const [value, setValue] = useState<Variables>(
|
const [value, setValue] = useState<Values>(
|
||||||
Object.fromEntries(
|
definitions.map((def) => ({ key: def.name, value: def.defaultValue || '' }))
|
||||||
definitions.map((def) => [def.name, def.defaultValue || ''])
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,18 +1,24 @@
|
||||||
|
import { SchemaOf, array, object, string } from 'yup';
|
||||||
|
|
||||||
import { FormControl } from '@@/form-components/FormControl';
|
import { FormControl } from '@@/form-components/FormControl';
|
||||||
import { FormSection } from '@@/form-components/FormSection/FormSection';
|
import { FormSection } from '@@/form-components/FormSection/FormSection';
|
||||||
import { Input } from '@@/form-components/Input';
|
import { Input } from '@@/form-components/Input';
|
||||||
|
import { ArrayError } from '@@/form-components/InputList/InputList';
|
||||||
|
import { FormError } from '@@/form-components/FormError';
|
||||||
|
|
||||||
import { VariableDefinition } from '../CustomTemplatesVariablesDefinitionField/CustomTemplatesVariablesDefinitionField';
|
import { VariableDefinition } from '../CustomTemplatesVariablesDefinitionField/CustomTemplatesVariablesDefinitionField';
|
||||||
|
|
||||||
export type Variables = Record<string, string>;
|
export type Values = Array<{ key: string; value?: string }>;
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
value: Variables;
|
errors?: ArrayError<Values>;
|
||||||
definitions?: VariableDefinition[];
|
value: Values;
|
||||||
onChange: (value: Variables) => void;
|
definitions: VariableDefinition[] | undefined;
|
||||||
|
onChange: (value: Values) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CustomTemplatesVariablesField({
|
export function CustomTemplatesVariablesField({
|
||||||
|
errors,
|
||||||
value,
|
value,
|
||||||
definitions,
|
definitions,
|
||||||
onChange,
|
onChange,
|
||||||
|
@ -23,32 +29,91 @@ export function CustomTemplatesVariablesField({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormSection title="Template Variables">
|
<FormSection title="Template Variables">
|
||||||
{definitions.map((def) => {
|
{definitions.map((definition, index) => (
|
||||||
const inputId = `${def.name}-input`;
|
<VariableFieldItem
|
||||||
const variable = value[def.name] || '';
|
key={definition.name}
|
||||||
return (
|
definition={definition}
|
||||||
<FormControl
|
value={value.find((v) => v.key === definition.name)?.value || ''}
|
||||||
required={!def.defaultValue}
|
error={getError(errors, index)}
|
||||||
label={def.label}
|
onChange={(fieldValue) => {
|
||||||
key={def.name}
|
onChange(
|
||||||
inputId={inputId}
|
value.map((v) =>
|
||||||
tooltip={def.description}
|
v.key === definition.name ? { ...v, value: fieldValue } : v
|
||||||
size="small"
|
)
|
||||||
>
|
|
||||||
<Input
|
|
||||||
name={`variables.${def.name}`}
|
|
||||||
value={variable}
|
|
||||||
id={inputId}
|
|
||||||
onChange={(e) =>
|
|
||||||
onChange({
|
|
||||||
...value,
|
|
||||||
[def.name]: e.target.value,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
);
|
);
|
||||||
})}
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{typeof errors === 'string' && <FormError>{errors}</FormError>}
|
||||||
</FormSection>
|
</FormSection>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function VariableFieldItem({
|
||||||
|
definition,
|
||||||
|
value,
|
||||||
|
error,
|
||||||
|
onChange,
|
||||||
|
}: {
|
||||||
|
definition: VariableDefinition;
|
||||||
|
value: string;
|
||||||
|
error?: string;
|
||||||
|
onChange: (value: string) => void;
|
||||||
|
}) {
|
||||||
|
const inputId = `${definition.name}-input`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormControl
|
||||||
|
required={!definition.defaultValue}
|
||||||
|
label={definition.label}
|
||||||
|
key={definition.name}
|
||||||
|
inputId={inputId}
|
||||||
|
tooltip={definition.description}
|
||||||
|
size="small"
|
||||||
|
errors={error}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
name={`variables.${definition.name}`}
|
||||||
|
value={value}
|
||||||
|
id={inputId}
|
||||||
|
onChange={(e) => onChange(e.target.value)}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getError(errors: ArrayError<Values> | undefined, index: number) {
|
||||||
|
if (!errors || typeof errors !== 'object') {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const error = errors[index];
|
||||||
|
if (!error) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeof error === 'object' ? error.value : error;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validation(
|
||||||
|
definitions: VariableDefinition[]
|
||||||
|
): SchemaOf<Values> {
|
||||||
|
return array(
|
||||||
|
object({
|
||||||
|
key: string().required(),
|
||||||
|
value: string().default(''),
|
||||||
|
}).test('required-if-no-default-value', 'This field is required', (obj) => {
|
||||||
|
const definition = definitions.find((d) => d.name === obj.key);
|
||||||
|
if (!definition) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!definition.defaultValue && !obj.value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
import { VariableDefinition } from '../CustomTemplatesVariablesDefinitionField';
|
||||||
|
|
||||||
|
import { Values } from './CustomTemplatesVariablesField';
|
||||||
|
|
||||||
|
export function getDefaultValues(definitions: VariableDefinition[]): Values {
|
||||||
|
return definitions.map((v) => ({
|
||||||
|
key: v.name,
|
||||||
|
value: v.defaultValue,
|
||||||
|
}));
|
||||||
|
}
|
|
@ -1 +1,7 @@
|
||||||
export { CustomTemplatesVariablesField } from './CustomTemplatesVariablesField';
|
export {
|
||||||
|
CustomTemplatesVariablesField,
|
||||||
|
type Values as VariablesFieldValue,
|
||||||
|
validation as variablesFieldValidation,
|
||||||
|
} from './CustomTemplatesVariablesField';
|
||||||
|
|
||||||
|
export { getDefaultValues as getVariablesFieldDefaultValues } from './getDefaultValues';
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import Mustache from 'mustache';
|
import Mustache from 'mustache';
|
||||||
|
|
||||||
|
import { isBE } from '../../feature-flags/feature-flags.service';
|
||||||
|
|
||||||
import { VariableDefinition } from './CustomTemplatesVariablesDefinitionField/CustomTemplatesVariablesDefinitionField';
|
import { VariableDefinition } from './CustomTemplatesVariablesDefinitionField/CustomTemplatesVariablesDefinitionField';
|
||||||
|
import { VariablesFieldValue } from './CustomTemplatesVariablesField';
|
||||||
|
|
||||||
|
export const isTemplateVariablesEnabled = isBE;
|
||||||
|
|
||||||
export function getTemplateVariables(templateStr: string) {
|
export function getTemplateVariables(templateStr: string) {
|
||||||
const [template, error] = validateAndParse(templateStr);
|
const [template, error] = validateAndParse(templateStr);
|
||||||
|
@ -60,22 +65,22 @@ export function intersectVariables(
|
||||||
|
|
||||||
export function renderTemplate(
|
export function renderTemplate(
|
||||||
template: string,
|
template: string,
|
||||||
variables: Record<string, string>,
|
variables: VariablesFieldValue,
|
||||||
definitions: VariableDefinition[]
|
definitions: VariableDefinition[]
|
||||||
) {
|
) {
|
||||||
const state = Object.fromEntries(
|
const state = Object.fromEntries(
|
||||||
_.compact(
|
_.compact(
|
||||||
Object.entries(variables).map(([name, value]) => {
|
variables.map(({ key, value }) => {
|
||||||
if (value) {
|
if (value) {
|
||||||
return [name, value];
|
return [key, value];
|
||||||
}
|
}
|
||||||
|
|
||||||
const definition = definitions.find((def) => def.name === name);
|
const definition = definitions.find((def) => def.name === key);
|
||||||
if (!definition) {
|
if (!definition) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [name, definition.defaultValue || `{{ ${definition.name} }}`];
|
return [key, definition.defaultValue || `{{ ${definition.name} }}`];
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue