mirror of https://github.com/portainer/portainer
fix(template): app template v3 error [BE-11998] (#854)
parent
8ffe4e284a
commit
c20a8b5a68
|
@ -40,11 +40,13 @@ func (handler *Handler) fetchTemplates() (*listResponse, *httperror.HandlerError
|
|||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&body)
|
||||
if err != nil {
|
||||
if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
|
||||
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
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
const user = userEvent.setup();
|
||||
await user.type(getByRole('textbox', { name: 'Name *' }), 'my-stack');
|
||||
await user.type(
|
||||
getByRole('textbox', { name: 'License key *' }),
|
||||
'license-123'
|
||||
);
|
||||
await user.type(getByRole('textbox', { name: 'License key' }), 'license-123');
|
||||
const selectElement = getByLabelText('Edge groups');
|
||||
await selectEvent.select(selectElement, 'docker');
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ test('calls onChange when input value changes', async () => {
|
|||
|
||||
const inputElement = screen.getByDisplayValue(value.VAR1);
|
||||
await user.clear(inputElement);
|
||||
expect(onChange).toHaveBeenCalledWith({ VAR1: '' });
|
||||
expect(onChange).toHaveBeenCalledWith({ VAR1: undefined });
|
||||
|
||||
const newValue = 'New Value';
|
||||
await user.type(inputElement, newValue);
|
||||
|
@ -107,11 +107,14 @@ test('validates env vars fieldset', () => {
|
|||
]);
|
||||
|
||||
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 invalidResult = schema.isValidSync(invalidData);
|
||||
const emptyResult = schema.isValidSync(emptyData);
|
||||
const undefinedResult = schema.isValidSync(undefinedData);
|
||||
|
||||
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 { Input, Select } from '@@/form-components/Input';
|
||||
|
||||
type Value = Record<string, string>;
|
||||
type Value = Record<string, string | undefined>;
|
||||
|
||||
export { type Value as EnvVarsValue };
|
||||
|
||||
|
@ -27,7 +27,7 @@ export function EnvVarsFieldset({
|
|||
<Item
|
||||
key={env.name}
|
||||
option={env}
|
||||
value={values[env.name]}
|
||||
value={values[env.name] || ''}
|
||||
onChange={(value) => handleChange(env.name, value)}
|
||||
errors={errors?.[env.name]}
|
||||
/>
|
||||
|
@ -36,7 +36,7 @@ export function EnvVarsFieldset({
|
|||
);
|
||||
|
||||
function handleChange(name: string, envValue: string) {
|
||||
onChange({ ...values, [name]: envValue });
|
||||
onChange({ ...values, [name]: envValue || undefined });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ function Item({
|
|||
return (
|
||||
<FormControl
|
||||
label={option.label || option.name}
|
||||
required={!option.preset}
|
||||
required={false}
|
||||
errors={errors}
|
||||
inputId={inputId}
|
||||
>
|
||||
|
@ -101,7 +101,9 @@ export function envVarsFieldsetValidation(
|
|||
): SchemaOf<Value> {
|
||||
return object(
|
||||
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 {
|
||||
name: string;
|
||||
envVars: Record<string, string>;
|
||||
envVars: Record<string, string | undefined>;
|
||||
accessControl: AccessControlFormData;
|
||||
}
|
||||
|
|
|
@ -88,10 +88,8 @@ function setTemplatesV3(this: TemplateViewModel, template: AppTemplate) {
|
|||
this.Id = template.id;
|
||||
}
|
||||
|
||||
let templateV2ID = 0;
|
||||
|
||||
function setTemplatesV2(this: TemplateViewModel, template: AppTemplate) {
|
||||
this.Id = templateV2ID++;
|
||||
this.Id = template.id;
|
||||
this.Title = template.title;
|
||||
this.Type = template.type;
|
||||
this.Description = template.description;
|
||||
|
|
Loading…
Reference in New Issue