@@ -42,9 +51,11 @@ async function handleSubmit() {
-
+
{{ submitTitle }}
+
+
diff --git a/client/src/components/ConfigTemplates/formUtil.ts b/client/src/components/ConfigTemplates/formUtil.ts
index e211cb301729..fec6b6400467 100644
--- a/client/src/components/ConfigTemplates/formUtil.ts
+++ b/client/src/components/ConfigTemplates/formUtil.ts
@@ -1,4 +1,5 @@
import type {
+ CreateInstancePayload,
Instance,
PluginStatus,
SecretData,
@@ -139,7 +140,7 @@ export function createTemplateForm(template: TemplateSummary, what: string): For
return form;
}
-export function createFormDataToPayload(template: TemplateSummary, formData: any) {
+export function createFormDataToPayload(template: TemplateSummary, formData: any): CreateInstancePayload {
const variables = template.variables ?? [];
const secrets = template.secrets ?? [];
const variableData: VariableData = {};
diff --git a/client/src/components/ConfigTemplates/routing.ts b/client/src/components/ConfigTemplates/routing.ts
new file mode 100644
index 000000000000..d8b63d60ca8d
--- /dev/null
+++ b/client/src/components/ConfigTemplates/routing.ts
@@ -0,0 +1,18 @@
+import { useRouter } from "vue-router/composables";
+
+export function buildInstanceRoutingComposable(index: string) {
+ return () => {
+ const router = useRouter();
+
+ async function goToIndex(query: Record<"message", string>) {
+ router.push({
+ path: index,
+ query: query,
+ });
+ }
+
+ return {
+ goToIndex,
+ };
+ };
+}
diff --git a/client/src/components/ConfigTemplates/test_fixtures.ts b/client/src/components/ConfigTemplates/test_fixtures.ts
index f29e8d5bd598..93feec2a79b6 100644
--- a/client/src/components/ConfigTemplates/test_fixtures.ts
+++ b/client/src/components/ConfigTemplates/test_fixtures.ts
@@ -1,3 +1,4 @@
+import type { PluginStatus } from "@/api/configTemplates";
import type { FileSourceTemplateSummary } from "@/api/fileSources";
import type { UserConcreteObjectStore } from "@/components/ObjectStore/Instances/types";
import type { ObjectStoreTemplateSummary } from "@/components/ObjectStore/Templates/types";
@@ -119,3 +120,18 @@ export const OBJECT_STORE_INSTANCE: UserConcreteObjectStore = {
hidden: false,
purged: false,
};
+
+export const OK_PLUGIN_STATUS: PluginStatus = {
+ template_definition: {
+ state: "ok",
+ message: "ok",
+ },
+ template_settings: {
+ state: "ok",
+ message: "ok",
+ },
+ connection: {
+ state: "ok",
+ message: "ok",
+ },
+};
diff --git a/client/src/components/ConfigTemplates/useConfigurationTesting.ts b/client/src/components/ConfigTemplates/useConfigurationTesting.ts
new file mode 100644
index 000000000000..9c2de8a60c7f
--- /dev/null
+++ b/client/src/components/ConfigTemplates/useConfigurationTesting.ts
@@ -0,0 +1,311 @@
+import { computed, type Ref, ref } from "vue";
+
+import type {
+ CreateInstancePayload,
+ Instance,
+ PluginStatus,
+ TemplateSummary,
+ TestUpdateInstancePayload,
+ TestUpgradeInstancePayload,
+ UpdateInstancePayload,
+ UpgradeInstancePayload,
+} from "@/api/configTemplates";
+import { buildInstanceRoutingComposable } from "@/components/ConfigTemplates/routing";
+import { errorMessageAsString } from "@/utils/simple-error";
+
+import {
+ createFormDataToPayload,
+ createTemplateForm,
+ editFormDataToPayload,
+ editTemplateForm,
+ type FormEntry,
+ pluginStatusToErrorMessage,
+ upgradeForm,
+ upgradeFormDataToPayload,
+} from "./formUtil";
+
+import ActionSummary from "./ActionSummary.vue";
+import ConfigurationTestSummaryModal from "@/components/ConfigTemplates/ConfigurationTestSummaryModal.vue";
+import InstanceForm from "@/components/ConfigTemplates/InstanceForm.vue";
+
+type InstanceRoutingComposableType = ReturnType