From c13b0a311680a38ef51c37dd2bf007686cdf6fd2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20G=C3=B6bel?= <dgoebel@techfak.uni-bielefeld.de>
Date: Thu, 21 Mar 2024 16:33:48 +0100
Subject: [PATCH] Load instance specific default parameters from parameter
 extension

#105
---
 src/App.vue                                   |  2 +-
 src/client/workflow/index.ts                  |  5 +--
 ...tension_Input.ts => ParameterExtension.ts} |  7 ++-
 .../models/ParameterExtension_Output.ts       | 16 -------
 .../workflow/models/ResourcePath_Input.ts     | 16 -------
 .../workflow/models/ResourcePath_Output.ts    | 16 -------
 src/client/workflow/models/WorkflowVersion.ts |  4 +-
 .../services/WorkflowVersionService.ts        |  4 +-
 .../ParameterSchemaFormComponent.vue          | 19 ++++++--
 .../form-mode/ParameterInput.vue              |  9 +---
 .../form-mode/ParameterResourceInput.vue      | 43 ++++++++-----------
 src/router/workflowRoutes.ts                  |  1 -
 src/stores/workflows.ts                       |  4 +-
 src/types/WorkflowParameters.ts               |  4 +-
 .../CreateParameterTranslationView.vue        | 35 +++------------
 src/views/workflows/StartWorkflowView.vue     |  4 ++
 16 files changed, 58 insertions(+), 131 deletions(-)
 rename src/client/workflow/models/{ParameterExtension_Input.ts => ParameterExtension.ts} (58%)
 delete mode 100644 src/client/workflow/models/ParameterExtension_Output.ts
 delete mode 100644 src/client/workflow/models/ResourcePath_Input.ts
 delete mode 100644 src/client/workflow/models/ResourcePath_Output.ts

diff --git a/src/App.vue b/src/App.vue
index 72b4a33..88d98f8 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -15,7 +15,7 @@ import AppFooter from "@/components/AppFooter.vue";
 import { useResourceStore } from "@/stores/resources";
 import { useWorkflowStore } from "@/stores/workflows";
 import { useBucketStore } from "@/stores/buckets";
-import {useS3KeyStore} from "@/stores/s3keys";
+import { useS3KeyStore } from "@/stores/s3keys";
 
 const { cookies } = useCookies();
 const router = useRouter();
diff --git a/src/client/workflow/index.ts b/src/client/workflow/index.ts
index 77c1f48..dbfd769 100644
--- a/src/client/workflow/index.ts
+++ b/src/client/workflow/index.ts
@@ -14,10 +14,7 @@ export { DocumentationEnum } from './models/DocumentationEnum';
 export type { ErrorDetail } from './models/ErrorDetail';
 export type { HTTPValidationError } from './models/HTTPValidationError';
 export type { IconUpdateOut } from './models/IconUpdateOut';
-export type { ParameterExtension_Input } from './models/ParameterExtension_Input';
-export type { ParameterExtension_Output } from './models/ParameterExtension_Output';
-export type { ResourcePath_Input } from './models/ResourcePath_Input';
-export type { ResourcePath_Output } from './models/ResourcePath_Output';
+export type { ParameterExtension } from './models/ParameterExtension';
 export { Status } from './models/Status';
 export type { ValidationError } from './models/ValidationError';
 export type { WorkflowCredentialsIn } from './models/WorkflowCredentialsIn';
diff --git a/src/client/workflow/models/ParameterExtension_Input.ts b/src/client/workflow/models/ParameterExtension.ts
similarity index 58%
rename from src/client/workflow/models/ParameterExtension_Input.ts
rename to src/client/workflow/models/ParameterExtension.ts
index 2ff25b5..6c96a7e 100644
--- a/src/client/workflow/models/ParameterExtension_Input.ts
+++ b/src/client/workflow/models/ParameterExtension.ts
@@ -2,15 +2,14 @@
 /* istanbul ignore file */
 /* tslint:disable */
 /* eslint-disable */
-import type { ResourcePath_Input } from './ResourcePath_Input';
-export type ParameterExtension_Input = {
+export type ParameterExtension = {
     /**
      * The inner dictionary contains the display name as key and the parameter value as value. The outer dictionary has the parameter name as key.
      */
-    mapping?: Record<string, Record<string, (ResourcePath_Input | string | number)>>;
+    mapping?: Record<string, Record<string, (string | number)>>;
     /**
      * Dictionary with parameter name as key and default value as value
      */
-    defaults?: Record<string, (ResourcePath_Input | string | number | boolean)>;
+    defaults?: Record<string, (string | number | boolean)>;
 };
 
diff --git a/src/client/workflow/models/ParameterExtension_Output.ts b/src/client/workflow/models/ParameterExtension_Output.ts
deleted file mode 100644
index 83175b8..0000000
--- a/src/client/workflow/models/ParameterExtension_Output.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-import type { ResourcePath_Output } from './ResourcePath_Output';
-export type ParameterExtension_Output = {
-    /**
-     * The inner dictionary contains the display name as key and the parameter value as value. The outer dictionary has the parameter name as key.
-     */
-    mapping?: Record<string, Record<string, (ResourcePath_Output | string | number)>>;
-    /**
-     * Dictionary with parameter name as key and default value as value
-     */
-    defaults?: Record<string, (ResourcePath_Output | string | number | boolean)>;
-};
-
diff --git a/src/client/workflow/models/ResourcePath_Input.ts b/src/client/workflow/models/ResourcePath_Input.ts
deleted file mode 100644
index 6d0b669..0000000
--- a/src/client/workflow/models/ResourcePath_Input.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export type ResourcePath_Input = {
-    /**
-     * ID of the resource version
-     */
-    resource_version_id: string;
-    /**
-     * ID of the resource
-     */
-    resource_id: string;
-    suffix?: (string | null);
-};
-
diff --git a/src/client/workflow/models/ResourcePath_Output.ts b/src/client/workflow/models/ResourcePath_Output.ts
deleted file mode 100644
index 4b7a73a..0000000
--- a/src/client/workflow/models/ResourcePath_Output.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-/* generated using openapi-typescript-codegen -- do not edit */
-/* istanbul ignore file */
-/* tslint:disable */
-/* eslint-disable */
-export type ResourcePath_Output = {
-    /**
-     * ID of the resource version
-     */
-    resource_version_id: string;
-    /**
-     * ID of the resource
-     */
-    resource_id: string;
-    suffix?: (string | null);
-};
-
diff --git a/src/client/workflow/models/WorkflowVersion.ts b/src/client/workflow/models/WorkflowVersion.ts
index 69cfbee..da35ffd 100644
--- a/src/client/workflow/models/WorkflowVersion.ts
+++ b/src/client/workflow/models/WorkflowVersion.ts
@@ -2,7 +2,7 @@
 /* istanbul ignore file */
 /* tslint:disable */
 /* eslint-disable */
-import type { ParameterExtension_Output } from './ParameterExtension_Output';
+import type { ParameterExtension } from './ParameterExtension';
 import type { Status } from './Status';
 export type WorkflowVersion = {
     /**
@@ -36,6 +36,6 @@ export type WorkflowVersion = {
     /**
      * Parameter extension specific for this CloWM instance
      */
-    parameter_extension?: (ParameterExtension_Output | null);
+    parameter_extension?: (ParameterExtension | null);
 };
 
diff --git a/src/client/workflow/services/WorkflowVersionService.ts b/src/client/workflow/services/WorkflowVersionService.ts
index 289e210..814605e 100644
--- a/src/client/workflow/services/WorkflowVersionService.ts
+++ b/src/client/workflow/services/WorkflowVersionService.ts
@@ -5,7 +5,7 @@
 import type { Body_Workflow_Version_upload_workflow_version_icon } from '../models/Body_Workflow_Version_upload_workflow_version_icon';
 import type { DocumentationEnum } from '../models/DocumentationEnum';
 import type { IconUpdateOut } from '../models/IconUpdateOut';
-import type { ParameterExtension_Input } from '../models/ParameterExtension_Input';
+import type { ParameterExtension } from '../models/ParameterExtension';
 import type { Status } from '../models/Status';
 import type { WorkflowVersion } from '../models/WorkflowVersion';
 import type { WorkflowVersionStatus } from '../models/WorkflowVersionStatus';
@@ -156,7 +156,7 @@ export class WorkflowVersionService {
     public static workflowVersionUpdateWorkflowVersionParameterExtension(
         wid: string,
         gitCommitHash: string,
-        requestBody: ParameterExtension_Input,
+        requestBody: ParameterExtension,
     ): CancelablePromise<WorkflowVersion> {
         return __request(OpenAPI, {
             method: 'PATCH',
diff --git a/src/components/parameter-schema/ParameterSchemaFormComponent.vue b/src/components/parameter-schema/ParameterSchemaFormComponent.vue
index 4dad354..7ecdc09 100644
--- a/src/components/parameter-schema/ParameterSchemaFormComponent.vue
+++ b/src/components/parameter-schema/ParameterSchemaFormComponent.vue
@@ -19,6 +19,7 @@ import type {
   WorkflowParameters,
 } from "@/types/WorkflowParameters";
 import { useWorkflowExecutionStore } from "@/stores/workflowExecutions";
+import type { ParameterExtension } from "@/client/workflow";
 
 const bucketRepository = useBucketStore();
 const resourceRepository = useResourceStore();
@@ -37,6 +38,10 @@ const props = defineProps({
     type: Object as PropType<ClowmInfo>,
     required: false,
   },
+  parameterExtension: {
+    type: Object as PropType<ParameterExtension>,
+    required: false,
+  },
   loading: {
     type: Boolean,
   },
@@ -185,6 +190,7 @@ function updateSchema(schema: Record<string, any>) {
     return { ...acc, ...val };
   });
   loadParameters(executionRepository.popTemporaryParameters());
+  loadParameters({ params: props.parameterExtension?.defaults });
 }
 
 function startWorkflow() {
@@ -207,16 +213,21 @@ function startWorkflow() {
 }
 
 function loadParameters(tempParams?: TemporaryParams) {
-  if (tempParams) {
+  if (tempParams?.params) {
     for (const param in tempParams.params) {
       if (param in formState.formInput) {
         formState.formInput[param] = tempParams.params[param];
       }
     }
+  }
+  if (tempParams?.metaParams) {
     formState.metaParameters = tempParams.metaParams;
-    if (Object.keys(tempParams?.params ?? {}).length > 0) {
-      parameterLoadToast?.show();
-    }
+  }
+  if (
+    Object.keys(tempParams?.params ?? {}).length > 0 ||
+    Object.keys(tempParams?.metaParams ?? {}).length > 0
+  ) {
+    parameterLoadToast?.show();
   }
 }
 
diff --git a/src/components/parameter-schema/form-mode/ParameterInput.vue b/src/components/parameter-schema/form-mode/ParameterInput.vue
index fb35a11..e0a1b3a 100644
--- a/src/components/parameter-schema/form-mode/ParameterInput.vue
+++ b/src/components/parameter-schema/form-mode/ParameterInput.vue
@@ -7,11 +7,8 @@ import ParameterEnumInput from "@/components/parameter-schema/form-mode/Paramete
 import ParameterFileInput from "@/components/parameter-schema/form-mode/ParameterFileInput.vue";
 import ParameterStringInput from "@/components/parameter-schema/form-mode/ParameterStringInput.vue";
 import type { SizeModifierType, ExtendedColors } from "@/types/PropTypes";
-import type { ResourcePath_Input } from "@/client/workflow";
 
-const model = defineModel<
-  number | string | boolean | ResourcePath_Input | undefined
->({
+const model = defineModel<number | string | boolean | undefined>({
   required: true,
 });
 
@@ -22,7 +19,6 @@ const props = defineProps<{
   parameter: Record<string, any>;
   required?: boolean;
   resourceParameter?: boolean;
-  rawModel?: boolean;
   sizeModifier?: SizeModifierType;
   border?: ExtendedColors;
   allowRaw?: boolean;
@@ -62,8 +58,7 @@ const parameterType = computed<string>(
       v-if="resourceParameter && !rawInput"
       :parameter="parameter"
       :required="required"
-      v-model="model as ResourcePath_Input"
-      :rawModel="rawModel"
+      v-model="model as string"
       :size-modifier="sizeModifier"
       :border="border"
       @switch-to-raw="rawInput = true"
diff --git a/src/components/parameter-schema/form-mode/ParameterResourceInput.vue b/src/components/parameter-schema/form-mode/ParameterResourceInput.vue
index a57d6c5..120b034 100644
--- a/src/components/parameter-schema/form-mode/ParameterResourceInput.vue
+++ b/src/components/parameter-schema/form-mode/ParameterResourceInput.vue
@@ -1,11 +1,10 @@
 <script setup lang="ts">
-import type { ResourcePath_Input } from "@/client/workflow";
 import { Status } from "@/client/resource";
 import { computed, onMounted, reactive, watch } from "vue";
 import { useResourceStore } from "@/stores/resources";
 import type { ExtendedColors, SizeModifierType } from "@/types/PropTypes";
 
-const model = defineModel<string | ResourcePath_Input | undefined>({
+const model = defineModel<string | undefined>({
   required: true,
 });
 
@@ -15,7 +14,6 @@ const props = defineProps<{
   // eslint-disable-next-line @typescript-eslint/no-explicit-any
   parameter: Record<string, any>;
   required?: boolean;
-  rawModel?: boolean;
   sizeModifier?: SizeModifierType;
   border?: ExtendedColors;
   allowRaw?: boolean;
@@ -28,7 +26,13 @@ const emit = defineEmits<{
 const resourceRepository = useResourceStore();
 const randomIDSuffix = Math.random().toString(16).substring(2, 8);
 
-const resource = reactive<ResourcePath_Input>({
+type ResourcePath = {
+  resource_id: string;
+  resource_version_id: string;
+  suffix?: string;
+};
+
+const resource = reactive<ResourcePath>({
   resource_id: "",
   resource_version_id: "",
   suffix: undefined,
@@ -76,17 +80,17 @@ watch(model, (newVal, oldVal) => {
   }
 });
 
-function parseModel(val?: string | ResourcePath_Input) {
-  if (val == undefined || (typeof val === "string" && val.length === 0)) {
+function parseModel(val?: string) {
+  if (val == undefined || val.length === 0) {
     Object.assign(resource, {
       resource_id: "",
       resource_version_id: "",
       suffix: undefined,
     });
-  } else if (typeof val === "string") {
+  } else {
     const match = resourceRegex.exec(val);
     if (match) {
-      const tempResource: ResourcePath_Input = {
+      const tempResource: ResourcePath = {
         resource_id: "",
         resource_version_id: "",
       };
@@ -97,8 +101,9 @@ function parseModel(val?: string | ResourcePath_Input) {
           ? hexToUUID(match[2])
           : resourceRepository.getLatestVersion(resource.resource_id);
       if (
-        resourceRepository.resourceMapping[resource.resource_id] == undefined ||
-        resourceRepository.versionMapping[resource.resource_version_id] ==
+        resourceRepository.resourceMapping[tempResource.resource_id] ==
+          undefined ||
+        resourceRepository.versionMapping[tempResource.resource_version_id] ==
           undefined
       ) {
         // Missing resource
@@ -108,20 +113,9 @@ function parseModel(val?: string | ResourcePath_Input) {
       Object.assign(resource, tempResource);
     } else {
       // Not resource path
+      console.log("Not resource path");
       emit("switch-to-raw");
     }
-  } else {
-    if (
-      (val.resource_id.length > 0 &&
-        resourceRepository.resourceMapping[val.resource_id] == undefined) ||
-      (val.resource_version_id.length > 0 &&
-        resourceRepository.versionMapping[val.resource_version_id] == undefined)
-    ) {
-      // Missing resource
-      emit("switch-to-raw");
-      return;
-    }
-    Object.assign(resource, JSON.parse(JSON.stringify(val)));
   }
 }
 
@@ -141,10 +135,7 @@ watch(
   },
 );
 
-function translateToModel(): string | ResourcePath_Input {
-  if (props.rawModel) {
-    return resource;
-  }
+function translateToModel(): string {
   if (resource.resource_version_id.length === 0) {
     return "";
   }
diff --git a/src/router/workflowRoutes.ts b/src/router/workflowRoutes.ts
index c7d238e..a0e896a 100644
--- a/src/router/workflowRoutes.ts
+++ b/src/router/workflowRoutes.ts
@@ -80,7 +80,6 @@ export const workflowRoutes: RouteRecordRaw[] = [
         props: (route) => ({
           versionId: route.params.versionId,
           workflowId: route.params.workflowId,
-          activeTab: route.query.tab ?? "description",
           workflowModeId: route.query.workflowModeId ?? undefined,
         }),
       },
diff --git a/src/stores/workflows.ts b/src/stores/workflows.ts
index b00d127..d200f3e 100644
--- a/src/stores/workflows.ts
+++ b/src/stores/workflows.ts
@@ -2,7 +2,7 @@ import { defineStore } from "pinia";
 import type {
   Body_Workflow_Version_upload_workflow_version_icon,
   IconUpdateOut,
-  ParameterExtension_Input,
+  ParameterExtension,
   WorkflowCredentialsIn,
   WorkflowIn,
   WorkflowModeOut,
@@ -538,7 +538,7 @@ export const useWorkflowStore = defineStore({
     updateWorkflowExtension(
       workflow_id: string,
       version_id: string,
-      extension: ParameterExtension_Input,
+      extension: ParameterExtension,
     ): Promise<WorkflowVersion> {
       return WorkflowVersionService.workflowVersionUpdateWorkflowVersionParameterExtension(
         workflow_id,
diff --git a/src/types/WorkflowParameters.ts b/src/types/WorkflowParameters.ts
index 0fd1398..7201b00 100644
--- a/src/types/WorkflowParameters.ts
+++ b/src/types/WorkflowParameters.ts
@@ -11,6 +11,6 @@ export type WorkflowMetaParameters = {
 };
 
 export type TemporaryParams = {
-  params: WorkflowParameters;
-  metaParams: WorkflowMetaParameters;
+  params?: WorkflowParameters;
+  metaParams?: WorkflowMetaParameters;
 };
diff --git a/src/views/workflows/CreateParameterTranslationView.vue b/src/views/workflows/CreateParameterTranslationView.vue
index a2db38a..7394582 100644
--- a/src/views/workflows/CreateParameterTranslationView.vue
+++ b/src/views/workflows/CreateParameterTranslationView.vue
@@ -2,13 +2,8 @@
 import { useNameStore } from "@/stores/names";
 import { useWorkflowStore } from "@/stores/workflows";
 import { computed, onMounted, reactive, ref, watch } from "vue";
-import {
-  DocumentationEnum,
-  type ParameterExtension_Input,
-  type ResourcePath_Input,
-} from "@/client/workflow";
+import { DocumentationEnum, type ParameterExtension } from "@/client/workflow";
 import type { ClowmInfo } from "@/types/ClowmInfo";
-import { useResourceStore } from "@/stores/resources";
 import ParameterInput from "@/components/parameter-schema/form-mode/ParameterInput.vue";
 import BootstrapToast from "@/components/BootstrapToast.vue";
 import { Toast } from "bootstrap";
@@ -31,14 +26,13 @@ let deleteToast: Toast | null = null;
 // =============================================================================
 const nameRepository = useNameStore();
 const workflowRepository = useWorkflowStore();
-const resourceRepository = useResourceStore();
 
 // Reactive State
 // =============================================================================
 const parameterState = reactive<{
   loading: boolean;
   makingRequest: boolean;
-  extension: ParameterExtension_Input;
+  extension: ParameterExtension;
   resourceParametersDefault: Set<string>;
   resourceParametersMapping: Set<string>;
   mappingParameterValues: Record<string, string>;
@@ -184,9 +178,7 @@ function getParameterSchemaDefault(
   return parameterSchema.value[param]?.["default"];
 }
 
-function getParamDefault(
-  param: string,
-): string | boolean | number | ResourcePath_Input {
+function getParamDefault(param: string): string | boolean | number {
   switch (getParameterType(param)) {
     case "integer": {
       return getParameterSchemaDefault(param) ?? 0;
@@ -199,10 +191,7 @@ function getParamDefault(
     }
     case "string": {
       if (parameterState.resourceParametersDefault.has(param)) {
-        return {
-          resource_id: "",
-          resource_version_id: "",
-        };
+        return "";
       }
       return (
         getParameterSchemaDefault(param) ??
@@ -228,20 +217,14 @@ function addDefaultParameter(param: string, index: number) {
 function makeResourceParameterDefault(param: string) {
   parameterState.formValidated = false;
   parameterState.resourceParametersDefault.add(param);
-  parameterState.extension.defaults![param] = {
-    resource_id: "",
-    resource_version_id: "",
-  };
+  parameterState.extension.defaults![param] = "";
 }
 
 function makeResourceParameterMapping(param: string, val: string) {
   if (parameterState.extension.mapping?.[param]?.[val]) {
     parameterState.formValidated = false;
     parameterState.resourceParametersMapping.add(param);
-    parameterState.extension.mapping[param][val] = {
-      resource_id: "",
-      resource_version_id: "",
-    };
+    parameterState.extension.mapping[param][val] = "";
   }
 }
 
@@ -279,8 +262,7 @@ function addMappingParameterValue(param: string, val: string) {
   if (parameterState.extension.mapping?.[param] != undefined) {
     parameterState.extension.mapping[param][val] = getParamDefault(param) as
       | string
-      | number
-      | ResourcePath_Input;
+      | number;
     parameterState.mappingParameterValues[param] = "";
   }
 }
@@ -374,7 +356,6 @@ onMounted(() => {
         );
       });
   });
-
 });
 </script>
 
@@ -501,7 +482,6 @@ onMounted(() => {
                 :resource-parameter="
                   parameterState.resourceParametersDefault.has(param)
                 "
-                raw-model
                 force-raw-file
               />
             </div>
@@ -616,7 +596,6 @@ onMounted(() => {
               <parameter-input
                 :parameter="parameterSchema[param]"
                 force-raw-file
-                raw-model
                 required
                 size-modifier="sm"
                 border="secondary-subtle"
diff --git a/src/views/workflows/StartWorkflowView.vue b/src/views/workflows/StartWorkflowView.vue
index 99f1f6d..42eecf8 100644
--- a/src/views/workflows/StartWorkflowView.vue
+++ b/src/views/workflows/StartWorkflowView.vue
@@ -138,6 +138,10 @@ onMounted(() => {
         DocumentationEnum.CLOWM_INFO
       ]
     "
+    :parameter-extension="
+      workflowRepository.versionMapping[versionId]?.parameter_extension ??
+      undefined
+    "
   />
 </template>
 
-- 
GitLab