Add refresh icon for reloading flows

https://imgur.com/a/z9q2g6y

Release-Notes: skip
Bug: Google b/431939712
Change-Id: I8fde1b7fc5351c2215487c1e79d0816685c3947f
diff --git a/polygerrit-ui/app/elements/change/gr-flows/gr-flows.ts b/polygerrit-ui/app/elements/change/gr-flows/gr-flows.ts
index ef8e3f4..59bb121 100644
--- a/polygerrit-ui/app/elements/change/gr-flows/gr-flows.ts
+++ b/polygerrit-ui/app/elements/change/gr-flows/gr-flows.ts
@@ -79,6 +79,10 @@
           align-items: center;
           margin-bottom: var(--spacing-s);
         }
+        .heading-with-button {
+          display: flex;
+          align-items: center;
+        }
         .hidden {
           display: none;
         }
@@ -126,6 +130,9 @@
           align-items: center;
           gap: var(--spacing-s);
         }
+        .refresh {
+          top: -4px;
+        }
       `,
     ];
   }
@@ -142,7 +149,7 @@
     );
   }
 
-  private async loadFlows() {
+  async loadFlows() {
     if (!this.changeNum) return;
     this.loading = true;
     const flows = await this.restApiService.listFlows(this.changeNum);
@@ -217,7 +224,18 @@
     }
     return html`
       <div>
-        <h2 class="main-heading">Existing Flows</h2>
+        <div class="heading-with-button">
+          <h2 class="main-heading">Existing Flows</h2>
+          <gr-button
+            link
+            @click=${this.loadFlows}
+            aria-label="Refresh flows"
+            title="Refresh flows"
+            class="refresh"
+          >
+            <gr-icon icon="refresh"></gr-icon>
+          </gr-button>
+        </div>
         ${this.flows.map(
           (flow: FlowInfo) => html`
             <div class="flow">
diff --git a/polygerrit-ui/app/elements/change/gr-flows/gr-flows_test.ts b/polygerrit-ui/app/elements/change/gr-flows/gr-flows_test.ts
index 3530c7a..9119b78 100644
--- a/polygerrit-ui/app/elements/change/gr-flows/gr-flows_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-flows/gr-flows_test.ts
@@ -98,7 +98,16 @@
           <gr-create-flow></gr-create-flow>
           <hr />
           <div>
-            <h2 class="main-heading">Existing Flows</h2>
+            <div class="heading-with-button">
+              <h2 class="main-heading">Existing Flows</h2>
+              <gr-button
+                aria-label="Refresh flows"
+                link=""
+                title="Refresh flows"
+              >
+                <gr-icon icon="refresh"></gr-icon>
+              </gr-button>
+            </div>
             <div class="flow">
               <div class="flow-header">
                 <gr-button link title="Delete flow">
@@ -280,4 +289,35 @@
 
     assert.isTrue(listFlowsStub.calledTwice);
   });
+
+  test('refreshes flows on button click', async () => {
+    const flows: FlowInfo[] = [
+      {
+        uuid: 'flow1',
+        owner: {name: 'owner1'},
+        created: '2025-01-01T10:00:00.000Z' as Timestamp,
+        stages: [
+          {
+            expression: {condition: 'label:Code-Review=+1'},
+            state: FlowStageState.DONE,
+          },
+        ],
+      },
+    ];
+    const listFlowsStub = stubRestApi('listFlows').returns(
+      Promise.resolve(flows)
+    );
+    await element.loadFlows();
+    await element.updateComplete;
+
+    assert.isTrue(listFlowsStub.calledOnce);
+    const refreshButton = queryAndAssert<GrButton>(
+      element,
+      '.heading-with-button gr-button'
+    );
+    refreshButton.click();
+    await element.updateComplete;
+
+    assert.isTrue(listFlowsStub.calledTwice);
+  });
 });