mirror of
https://github.com/portainer/portainer.git
synced 2025-07-19 05:19:39 +02:00
fix(template): app template v3 error [BE-11998] (#854)
This commit is contained in:
parent
8ffe4e284a
commit
c20a8b5a68
6 changed files with 21 additions and 19 deletions
|
@ -40,11 +40,13 @@ func (handler *Handler) fetchTemplates() (*listResponse, *httperror.HandlerError
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
err = json.NewDecoder(resp.Body).Decode(&body)
|
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, httperror.InternalServerError("Unable to parse template file", err)
|
return nil, httperror.InternalServerError("Unable to parse template file", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i := range body.Templates {
|
||||||
|
body.Templates[i].ID = portainer.TemplateID(i + 1)
|
||||||
|
}
|
||||||
return body, nil
|
return body, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,10 +80,7 @@ test('The form should submit the correct request body for a given app template',
|
||||||
// fill in the name and select the docker edge group
|
// fill in the name and select the docker edge group
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
await user.type(getByRole('textbox', { name: 'Name *' }), 'my-stack');
|
await user.type(getByRole('textbox', { name: 'Name *' }), 'my-stack');
|
||||||
await user.type(
|
await user.type(getByRole('textbox', { name: 'License key' }), 'license-123');
|
||||||
getByRole('textbox', { name: 'License key *' }),
|
|
||||||
'license-123'
|
|
||||||
);
|
|
||||||
const selectElement = getByLabelText('Edge groups');
|
const selectElement = getByLabelText('Edge groups');
|
||||||
await selectEvent.select(selectElement, 'docker');
|
await selectEvent.select(selectElement, 'docker');
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@ test('calls onChange when input value changes', async () => {
|
||||||
|
|
||||||
const inputElement = screen.getByDisplayValue(value.VAR1);
|
const inputElement = screen.getByDisplayValue(value.VAR1);
|
||||||
await user.clear(inputElement);
|
await user.clear(inputElement);
|
||||||
expect(onChange).toHaveBeenCalledWith({ VAR1: '' });
|
expect(onChange).toHaveBeenCalledWith({ VAR1: undefined });
|
||||||
|
|
||||||
const newValue = 'New Value';
|
const newValue = 'New Value';
|
||||||
await user.type(inputElement, newValue);
|
await user.type(inputElement, newValue);
|
||||||
|
@ -107,11 +107,14 @@ test('validates env vars fieldset', () => {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const validData = { VAR1: 'Value 1', VAR2: 'Value 2' };
|
const validData = { VAR1: 'Value 1', VAR2: 'Value 2' };
|
||||||
const invalidData = { VAR1: '', VAR2: 'Value 2' };
|
const emptyData = { VAR1: '', VAR2: 'Value 2' };
|
||||||
|
const undefinedData = { VAR1: undefined, VAR2: 'Value 2' };
|
||||||
|
|
||||||
const validResult = schema.isValidSync(validData);
|
const validResult = schema.isValidSync(validData);
|
||||||
const invalidResult = schema.isValidSync(invalidData);
|
const emptyResult = schema.isValidSync(emptyData);
|
||||||
|
const undefinedResult = schema.isValidSync(undefinedData);
|
||||||
|
|
||||||
expect(validResult).toBe(true);
|
expect(validResult).toBe(true);
|
||||||
expect(invalidResult).toBe(false);
|
expect(emptyResult).toBe(true);
|
||||||
|
expect(undefinedResult).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { TemplateEnv } from '@/react/portainer/templates/app-templates/types';
|
||||||
import { FormControl } from '@@/form-components/FormControl';
|
import { FormControl } from '@@/form-components/FormControl';
|
||||||
import { Input, Select } from '@@/form-components/Input';
|
import { Input, Select } from '@@/form-components/Input';
|
||||||
|
|
||||||
type Value = Record<string, string>;
|
type Value = Record<string, string | undefined>;
|
||||||
|
|
||||||
export { type Value as EnvVarsValue };
|
export { type Value as EnvVarsValue };
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ export function EnvVarsFieldset({
|
||||||
<Item
|
<Item
|
||||||
key={env.name}
|
key={env.name}
|
||||||
option={env}
|
option={env}
|
||||||
value={values[env.name]}
|
value={values[env.name] || ''}
|
||||||
onChange={(value) => handleChange(env.name, value)}
|
onChange={(value) => handleChange(env.name, value)}
|
||||||
errors={errors?.[env.name]}
|
errors={errors?.[env.name]}
|
||||||
/>
|
/>
|
||||||
|
@ -36,7 +36,7 @@ export function EnvVarsFieldset({
|
||||||
);
|
);
|
||||||
|
|
||||||
function handleChange(name: string, envValue: string) {
|
function handleChange(name: string, envValue: string) {
|
||||||
onChange({ ...values, [name]: envValue });
|
onChange({ ...values, [name]: envValue || undefined });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ function Item({
|
||||||
return (
|
return (
|
||||||
<FormControl
|
<FormControl
|
||||||
label={option.label || option.name}
|
label={option.label || option.name}
|
||||||
required={!option.preset}
|
required={false}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
inputId={inputId}
|
inputId={inputId}
|
||||||
>
|
>
|
||||||
|
@ -101,7 +101,9 @@ export function envVarsFieldsetValidation(
|
||||||
): SchemaOf<Value> {
|
): SchemaOf<Value> {
|
||||||
return object(
|
return object(
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
definitions.map((v) => [v.name, string().required('Required')])
|
definitions
|
||||||
|
.filter((v) => !v.preset)
|
||||||
|
.map((v) => [v.name, string().optional()])
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,6 @@ import { AccessControlFormData } from '@/react/portainer/access-control/types';
|
||||||
|
|
||||||
export interface FormValues {
|
export interface FormValues {
|
||||||
name: string;
|
name: string;
|
||||||
envVars: Record<string, string>;
|
envVars: Record<string, string | undefined>;
|
||||||
accessControl: AccessControlFormData;
|
accessControl: AccessControlFormData;
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,10 +88,8 @@ function setTemplatesV3(this: TemplateViewModel, template: AppTemplate) {
|
||||||
this.Id = template.id;
|
this.Id = template.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
let templateV2ID = 0;
|
|
||||||
|
|
||||||
function setTemplatesV2(this: TemplateViewModel, template: AppTemplate) {
|
function setTemplatesV2(this: TemplateViewModel, template: AppTemplate) {
|
||||||
this.Id = templateV2ID++;
|
this.Id = template.id;
|
||||||
this.Title = template.title;
|
this.Title = template.title;
|
||||||
this.Type = template.type;
|
this.Type = template.type;
|
||||||
this.Description = template.description;
|
this.Description = template.description;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue