fix(edge/stacks): load template [EE-7109] (#11848)
parent
a28bd349ae
commit
0f5988af49
|
@ -120,10 +120,10 @@ function useTemplate(
|
|||
id: number | undefined
|
||||
) {
|
||||
const customTemplateQuery = useCustomTemplate(id, {
|
||||
enabled: !!id && type === 'custom',
|
||||
enabled: type === 'custom',
|
||||
});
|
||||
const appTemplateQuery = useAppTemplate(id, {
|
||||
enabled: !!id && type === 'app',
|
||||
enabled: type === 'app',
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
@ -13,12 +13,12 @@ import {
|
|||
edgeStackTemplate,
|
||||
upload,
|
||||
} from '@@/BoxSelector/common-options/build-methods';
|
||||
import { WebEditorForm } from '@@/WebEditorForm';
|
||||
import { FileUploadForm } from '@@/form-components/FileUpload';
|
||||
|
||||
import { TemplateFieldset } from './TemplateFieldset/TemplateFieldset';
|
||||
import { useRenderTemplate } from './useRenderTemplate';
|
||||
import { DockerFormValues } from './types';
|
||||
import { DockerContentField } from './DockerContentField';
|
||||
|
||||
const buildMethods = [editor, upload, git, edgeStackTemplate] as const;
|
||||
|
||||
|
@ -78,26 +78,12 @@ export function DockerComposeForm({
|
|||
|
||||
{(method === editor.value ||
|
||||
(method === edgeStackTemplate.value && template)) && (
|
||||
<WebEditorForm
|
||||
id="stack-creation-editor"
|
||||
<DockerContentField
|
||||
value={values.fileContent}
|
||||
onChange={(value) => handleChange({ fileContent: value })}
|
||||
yaml
|
||||
placeholder="Define or paste the content of your docker compose file here"
|
||||
error={errors?.fileContent}
|
||||
readonly={method === edgeStackTemplate.value && !!template?.GitConfig}
|
||||
data-cy="stack-creation-editor"
|
||||
>
|
||||
You can get more information about Compose file format in the{' '}
|
||||
<a
|
||||
href="https://docs.docker.com/compose/compose-file/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
official documentation
|
||||
</a>
|
||||
.
|
||||
</WebEditorForm>
|
||||
error={errors?.fileContent}
|
||||
/>
|
||||
)}
|
||||
|
||||
{method === upload.value && (
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
import { WebEditorForm } from '@@/WebEditorForm';
|
||||
|
||||
export function DockerContentField({
|
||||
error,
|
||||
onChange,
|
||||
readonly,
|
||||
value,
|
||||
}: {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
error?: string;
|
||||
readonly?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<WebEditorForm
|
||||
id="stack-creation-editor"
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
yaml
|
||||
placeholder="Define or paste the content of your docker compose file here"
|
||||
error={error}
|
||||
readonly={readonly}
|
||||
data-cy="stack-creation-editor"
|
||||
>
|
||||
You can get more information about Compose file format in the{' '}
|
||||
<a
|
||||
href="https://docs.docker.com/compose/compose-file/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
official documentation
|
||||
</a>
|
||||
.
|
||||
</WebEditorForm>
|
||||
);
|
||||
}
|
|
@ -24,7 +24,7 @@ export function TemplateSelector({
|
|||
) => void;
|
||||
error?: string;
|
||||
}) {
|
||||
const { options, getTemplate } = useOptions();
|
||||
const { options, getTemplate, selectedValue } = useOptions(value);
|
||||
|
||||
return (
|
||||
<FormControl label="Template" inputId="template_selector" errors={error}>
|
||||
|
@ -32,10 +32,8 @@ export function TemplateSelector({
|
|||
inputId="template_selector"
|
||||
formatGroupLabel={GroupLabel}
|
||||
placeholder="Select an Edge stack template"
|
||||
value={{
|
||||
templateId: value.templateId,
|
||||
type: value.type,
|
||||
}}
|
||||
options={options}
|
||||
value={selectedValue}
|
||||
onChange={(value) => {
|
||||
if (!value) {
|
||||
onChange(undefined, undefined);
|
||||
|
@ -48,14 +46,19 @@ export function TemplateSelector({
|
|||
}
|
||||
onChange(getTemplate({ type, id: templateId }), type);
|
||||
}}
|
||||
options={options}
|
||||
data-cy="edge-stacks-create-template-selector"
|
||||
/>
|
||||
</FormControl>
|
||||
);
|
||||
}
|
||||
|
||||
function useOptions() {
|
||||
interface Option {
|
||||
label: string;
|
||||
templateId?: number;
|
||||
type: 'app' | 'custom';
|
||||
}
|
||||
|
||||
function useOptions(value: SelectedTemplateValue) {
|
||||
const customTemplatesQuery = useCustomTemplates({
|
||||
params: {
|
||||
edge: true,
|
||||
|
@ -71,43 +74,75 @@ function useOptions() {
|
|||
),
|
||||
});
|
||||
|
||||
const appTemplateOptions: Array<Option> = useMemo(
|
||||
() =>
|
||||
appTemplatesQuery.data?.map(
|
||||
(template) =>
|
||||
({
|
||||
label: `${template.Title} - ${template.Description}`,
|
||||
|
||||
templateId: template.Id,
|
||||
type: 'app',
|
||||
}) satisfies Option
|
||||
) || [],
|
||||
[appTemplatesQuery.data]
|
||||
);
|
||||
|
||||
const customTemplateOptions: Array<Option> = useMemo(
|
||||
() =>
|
||||
customTemplatesQuery.data && customTemplatesQuery.data.length > 0
|
||||
? customTemplatesQuery.data.map(
|
||||
(template) =>
|
||||
({
|
||||
label: `${template.Title} - ${template.Description}`,
|
||||
|
||||
templateId: template.Id,
|
||||
type: 'custom' as 'app' | 'custom',
|
||||
}) satisfies Option
|
||||
)
|
||||
: [
|
||||
{
|
||||
label: 'No edge custom templates available',
|
||||
|
||||
templateId: undefined,
|
||||
type: 'custom' as 'app' | 'custom',
|
||||
} satisfies Option,
|
||||
],
|
||||
[customTemplatesQuery.data]
|
||||
);
|
||||
|
||||
const options = useMemo(
|
||||
() =>
|
||||
[
|
||||
{
|
||||
label: 'Edge App Templates',
|
||||
options:
|
||||
appTemplatesQuery.data?.map((template) => ({
|
||||
label: `${template.Title} - ${template.Description}`,
|
||||
|
||||
templateId: template.Id,
|
||||
type: 'app' as 'app' | 'custom',
|
||||
})) || [],
|
||||
options: appTemplateOptions,
|
||||
},
|
||||
{
|
||||
label: 'Edge Custom Templates',
|
||||
options:
|
||||
customTemplatesQuery.data && customTemplatesQuery.data.length > 0
|
||||
? customTemplatesQuery.data.map((template) => ({
|
||||
label: `${template.Title} - ${template.Description}`,
|
||||
|
||||
templateId: template.Id,
|
||||
type: 'custom' as 'app' | 'custom',
|
||||
}))
|
||||
: [
|
||||
{
|
||||
label: 'No edge custom templates available',
|
||||
|
||||
templateId: undefined,
|
||||
type: undefined,
|
||||
},
|
||||
],
|
||||
options: customTemplateOptions,
|
||||
},
|
||||
] as const,
|
||||
[appTemplatesQuery.data, customTemplatesQuery.data]
|
||||
[appTemplateOptions, customTemplateOptions]
|
||||
);
|
||||
|
||||
return { options, getTemplate };
|
||||
const selectedValue: Option | undefined = useMemo(() => {
|
||||
if (!value.templateId) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (value.type === 'app') {
|
||||
return appTemplateOptions.find(
|
||||
(template) => template.templateId === value.templateId
|
||||
);
|
||||
}
|
||||
|
||||
return customTemplateOptions.find(
|
||||
(template) => template.templateId === value.templateId
|
||||
);
|
||||
}, [value.templateId, value.type, customTemplateOptions, appTemplateOptions]);
|
||||
|
||||
return { options, getTemplate, selectedValue };
|
||||
|
||||
function getTemplate({ type, id }: { type: 'app' | 'custom'; id: number }) {
|
||||
if (type === 'app') {
|
||||
|
|
|
@ -16,13 +16,18 @@ export function useRenderTemplate(
|
|||
templateValues: DockerFormValues['templateValues'],
|
||||
setValues: (values: SetStateAction<DockerFormValues>) => void
|
||||
) {
|
||||
const templateQuery = useCustomTemplate(templateValues.templateId);
|
||||
const templateQuery = useCustomTemplate(templateValues.templateId, {
|
||||
enabled: templateValues.type === 'custom',
|
||||
});
|
||||
|
||||
const template = templateQuery.data;
|
||||
|
||||
const templateFileQuery = useCustomTemplateFile(
|
||||
templateValues.templateId,
|
||||
!!template?.GitConfig
|
||||
!!template?.GitConfig,
|
||||
{
|
||||
enabled: templateValues.type === 'custom',
|
||||
}
|
||||
);
|
||||
const [renderedFile, setRenderedFile] = useState<string>('');
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ export function useAppTemplates<T = Array<TemplateViewModel>>({
|
|||
|
||||
export function useAppTemplate(
|
||||
id: AppTemplate['id'] | undefined,
|
||||
{ enabled = true }: { enabled?: boolean } = {}
|
||||
{ enabled }: { enabled?: boolean } = {}
|
||||
) {
|
||||
const templateListQuery = useAppTemplates({ enabled: !!id && enabled });
|
||||
|
||||
|
@ -39,7 +39,7 @@ export function useAppTemplate(
|
|||
|
||||
return {
|
||||
data: template,
|
||||
isLoading: templateListQuery.isLoading,
|
||||
isLoading: templateListQuery.isInitialLoading,
|
||||
error: templateListQuery.error,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ export async function getCustomTemplate(id: CustomTemplate['Id']) {
|
|||
|
||||
export function useCustomTemplate(
|
||||
id?: CustomTemplate['Id'],
|
||||
{ enabled = true }: { enabled?: boolean } = {}
|
||||
{ enabled }: { enabled?: boolean } = {}
|
||||
) {
|
||||
return useQuery(queryKeys.item(id!), () => getCustomTemplate(id!), {
|
||||
...withGlobalError('Unable to retrieve custom template'),
|
||||
|
|
|
@ -12,13 +12,17 @@ type CustomTemplateFileContent = {
|
|||
FileContent: string;
|
||||
};
|
||||
|
||||
export function useCustomTemplateFile(id?: CustomTemplate['Id'], git = false) {
|
||||
export function useCustomTemplateFile(
|
||||
id?: CustomTemplate['Id'],
|
||||
git = false,
|
||||
{ enabled }: { enabled?: boolean } = {}
|
||||
) {
|
||||
return useQuery(
|
||||
id ? queryKeys.file(id, { git }) : [],
|
||||
queryKeys.file(id!, { git }),
|
||||
() => getCustomTemplateFile({ id: id!, git }),
|
||||
{
|
||||
...withGlobalError('Failed to get custom template file'),
|
||||
enabled: !!id,
|
||||
enabled: !!id && enabled,
|
||||
// there's nothing to do with a new file content, so we're disabling refetch
|
||||
refetchOnReconnect: false,
|
||||
refetchOnWindowFocus: false,
|
||||
|
|
Loading…
Reference in New Issue