Merge "Add parsing from raw flow to flow stages"
diff --git a/polygerrit-ui/app/elements/change/gr-flows/gr-create-flow.ts b/polygerrit-ui/app/elements/change/gr-flows/gr-create-flow.ts
index ad0c067..866a297 100644
--- a/polygerrit-ui/app/elements/change/gr-flows/gr-create-flow.ts
+++ b/polygerrit-ui/app/elements/change/gr-flows/gr-create-flow.ts
@@ -212,6 +212,33 @@
     this.flowString = this.stages.map(stageToString).join(STAGE_SEPARATOR);
   }
 
+  private parseStagesFromRawFlow(rawFlow: string) {
+    if (!rawFlow) {
+      this.stages = [];
+      return;
+    }
+    const stageStrings = rawFlow.split(STAGE_SEPARATOR);
+    this.stages = stageStrings.map(stageStr => {
+      const stage = {
+        condition: '',
+        action: '',
+        parameterStr: '',
+      };
+      if (stageStr.includes('->')) {
+        const [condition, actionStr] = stageStr.split('->').map(s => s.trim());
+        stage.condition = condition;
+        const actionParts = actionStr.split(' ').filter(part => part);
+        stage.action = actionParts[0] ?? '';
+        if (actionParts.length > 1) {
+          stage.parameterStr = actionParts.slice(1).join(' ');
+        }
+      } else {
+        stage.condition = stageStr.trim();
+      }
+      return stage;
+    });
+  }
+
   override render() {
     return html`
       <div class="raw-flow-container">
@@ -219,6 +246,10 @@
           placeholder="raw flow"
           label="Raw Flow"
           .value=${this.flowString}
+          @input=${(e: InputEvent) => {
+            this.flowString = (e.target as HTMLTextAreaElement).value;
+            this.parseStagesFromRawFlow(this.flowString);
+          }}
         ></gr-autogrow-textarea>
         <gr-copy-clipboard
           .text=${this.flowString}
diff --git a/polygerrit-ui/app/elements/change/gr-flows/gr-create-flow_test.ts b/polygerrit-ui/app/elements/change/gr-flows/gr-create-flow_test.ts
index 331bd2f..6e88d11 100644
--- a/polygerrit-ui/app/elements/change/gr-flows/gr-create-flow_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-flows/gr-create-flow_test.ts
@@ -371,4 +371,93 @@
       'https://gerrit-review.googlesource.com/c/plugins/code-owners/+/441321 is cond 2 -> act-2 param'
     );
   });
+
+  suite('parseStagesFromRawFlow tests', () => {
+    test('parses a single condition', async () => {
+      const rawFlow = 'cond 1';
+      element['parseStagesFromRawFlow'](rawFlow);
+      await element.updateComplete;
+      assert.deepEqual(element['stages'], [
+        {
+          condition: 'cond 1',
+          action: '',
+          parameterStr: '',
+        },
+      ]);
+    });
+
+    test('parses a single condition with action', async () => {
+      const rawFlow = 'cond 1 -> act-1';
+      element['parseStagesFromRawFlow'](rawFlow);
+      await element.updateComplete;
+      assert.deepEqual(element['stages'], [
+        {
+          condition: 'cond 1',
+          action: 'act-1',
+          parameterStr: '',
+        },
+      ]);
+    });
+
+    test('parses a single condition with action and params', async () => {
+      const rawFlow = 'cond 1 -> act-1 param1 param2';
+      element['parseStagesFromRawFlow'](rawFlow);
+      await element.updateComplete;
+      assert.deepEqual(element['stages'], [
+        {
+          condition: 'cond 1',
+          action: 'act-1',
+          parameterStr: 'param1 param2',
+        },
+      ]);
+    });
+
+    test('parses multiple stages', async () => {
+      const rawFlow = 'cond 1 -> act-1; cond 2 -> act-2 p2; cond 3';
+      element['parseStagesFromRawFlow'](rawFlow);
+      await element.updateComplete;
+      assert.deepEqual(element['stages'], [
+        {
+          condition: 'cond 1',
+          action: 'act-1',
+          parameterStr: '',
+        },
+        {
+          condition: 'cond 2',
+          action: 'act-2',
+          parameterStr: 'p2',
+        },
+        {
+          condition: 'cond 3',
+          action: '',
+          parameterStr: '',
+        },
+      ]);
+    });
+
+    test('parses an empty string', async () => {
+      const rawFlow = '';
+      element['parseStagesFromRawFlow'](rawFlow);
+      await element.updateComplete;
+      assert.deepEqual(element['stages'], []);
+    });
+
+    test('parses with extra spacing', async () => {
+      const rawFlow = '  cond 1   ->  act-1  p1 ;  cond 2  ';
+      element['parseStagesFromRawFlow'](rawFlow);
+      await element.updateComplete;
+      assert.deepEqual(element['stages'], [
+        {
+          condition: 'cond 1',
+          action: 'act-1',
+          parameterStr: 'p1',
+        },
+        {
+          condition: 'cond 2',
+          action: '',
+          parameterStr: '',
+        },
+      ]);
+    });
+  });
 });