This is an automated email from the ASF dual-hosted git repository.

yasithdev pushed a commit to branch feat/generic-experiment-launcher
in repository https://gitbox.apache.org/repos/asf/airavata-portals.git

commit 5a3db3915a4e380fd9a8f8543b52c3db2555b179
Author: yasithdev <[email protected]>
AuthorDate: Fri Apr 24 22:16:40 2026 -0400

    fix(launcher): add setStorages/setProfile + honor optional outputs + reset 
previewLoading
---
 .../tests/unit/stores/launch.spec.ts               | 38 ++++++++++++++++++++++
 .../static/common/js/stores/launch.ts              | 17 +++++++++-
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git 
a/airavata-django-portal/django_airavata/apps/workspace/static/django_airavata_workspace/tests/unit/stores/launch.spec.ts
 
b/airavata-django-portal/django_airavata/apps/workspace/static/django_airavata_workspace/tests/unit/stores/launch.spec.ts
index 9046aacea..b064e646f 100644
--- 
a/airavata-django-portal/django_airavata/apps/workspace/static/django_airavata_workspace/tests/unit/stores/launch.spec.ts
+++ 
b/airavata-django-portal/django_airavata/apps/workspace/static/django_airavata_workspace/tests/unit/stores/launch.spec.ts
@@ -64,3 +64,41 @@ describe("useLaunchStore", () => {
     expect(s.draftHash).toBe(h2);
   });
 });
+
+describe("setters and reset", () => {
+  beforeEach(() => setActivePinia(createPinia()));
+
+  it("setStorages and setProfile populate state", () => {
+    const s = useLaunchStore();
+    s.setStorages([{ storage_id: "x", name: "X", is_primary: true }]);
+    s.setProfile({ project_id: "p1", allocation_id: "A1", compute_resources: 
[] });
+    expect(s.storages).toHaveLength(1);
+    expect(s.profile?.allocation_id).toBe("A1");
+  });
+
+  it("reset clears all state including previewLoading", () => {
+    const s = useLaunchStore();
+    s.setMeta({ name: "x", project_id: "p1", description: "" });
+    s.previewLoading = true;
+    s.reset();
+    expect(s.draft.name).toBe("");
+    expect(s.draft.project_id).toBeNull();
+    expect(s.previewLoading).toBe(false);
+  });
+
+  it("optional outputs do not block tab1 validity", () => {
+    const s = useLaunchStore();
+    const iface = {
+      name: "run",
+      inputs: [{ name: "x", type: "int" as const, required: true }],
+      outputs: [{ name: "log", type: "file" as const, required: false }],
+    };
+    s.setMeta({ name: "x", project_id: "p1", description: "" });
+    s.pickApp({ app_id: "a", name: "A", category: "C",
+                content: { kind: "github", url: "g" }, interfaces: [iface] });
+    s.pickInterface("run");
+    s.setInput("x", 1);
+    // No output set, but it's not required
+    expect(s.tab1Valid).toBe(true);
+  });
+});
diff --git 
a/airavata-django-portal/django_airavata/static/common/js/stores/launch.ts 
b/airavata-django-portal/django_airavata/static/common/js/stores/launch.ts
index e249d41ab..5e34c91b8 100644
--- a/airavata-django-portal/django_airavata/static/common/js/stores/launch.ts
+++ b/airavata-django-portal/django_airavata/static/common/js/stores/launch.ts
@@ -109,7 +109,11 @@ export const useLaunchStore = defineStore("launch", () => {
     for (const io of iface.outputs) {
       if (io.type !== "file" && io.type !== "dir") continue;
       const v = draft.outputs[io.name];
-      if (!v || !v.path || !v.storage_id) return false;
+      if (!v) {
+        if (io.required) return false;
+        continue;
+      }
+      if (!v.path || !v.storage_id) return false;
     }
     return true;
   });
@@ -130,12 +134,21 @@ export const useLaunchStore = defineStore("launch", () => 
{
     return (h >>> 0).toString(16);
   });
 
+  function setStorages(s: UserStorage[]) {
+    storages.value = s;
+  }
+
+  function setProfile(p: ResourceProfile | null) {
+    profile.value = p;
+  }
+
   function reset() {
     Object.assign(draft, makeDraft());
     pickedApp.value = null;
     profile.value = null;
     preview.value = null;
     previewError.value = null;
+    previewLoading.value = false;
     lastPreviewedHash.value = null;
   }
 
@@ -158,6 +171,8 @@ export const useLaunchStore = defineStore("launch", () => {
     setInput,
     setOutput,
     setRuntime,
+    setStorages,
+    setProfile,
     reset,
   };
 });

Reply via email to