|
4 | 4 | import { onMount } from 'svelte';
|
5 | 5 | import { v4 } from 'uuid';
|
6 | 6 |
|
7 |
| - import { goto } from '$app/navigation'; |
8 | 7 | import { page } from '$app/stores';
|
9 | 8 |
|
10 | 9 | import PayloadInput, {
|
|
15 | 14 | import Button from '$lib/holocene/button.svelte';
|
16 | 15 | import Input from '$lib/holocene/input/input.svelte';
|
17 | 16 | import Link from '$lib/holocene/link.svelte';
|
18 |
| - import Loading from '$lib/holocene/loading.svelte'; |
19 | 17 | import { translate } from '$lib/i18n/translate';
|
20 | 18 | import { getPollers } from '$lib/services/pollers-service';
|
21 | 19 | import {
|
|
26 | 24 | customSearchAttributes,
|
27 | 25 | type SearchAttributeInput,
|
28 | 26 | } from '$lib/stores/search-attributes';
|
| 27 | + import { toaster } from '$lib/stores/toaster'; |
29 | 28 | import { workflowsSearchParams } from '$lib/stores/workflows';
|
30 | 29 | import { pluralize } from '$lib/utilities/pluralize';
|
31 | 30 | import {
|
| 31 | + routeForEventHistory, |
32 | 32 | routeForTaskQueue,
|
33 | 33 | routeForWorkflows,
|
34 | 34 | } from '$lib/utilities/route-for';
|
|
37 | 37 |
|
38 | 38 | $: ({ namespace } = $page.params);
|
39 | 39 |
|
40 |
| - let loading = false; |
41 |
| -
|
42 | 40 | let workflowId = '';
|
43 | 41 | let taskQueue = '';
|
44 | 42 | let workflowType = '';
|
|
70 | 68 | });
|
71 | 69 |
|
72 | 70 | const onWorkflowStart = async () => {
|
73 |
| - loading = true; |
74 | 71 | try {
|
75 | 72 | error = '';
|
76 |
| - await startWorkflow({ |
| 73 | + const { runId } = await startWorkflow({ |
77 | 74 | namespace,
|
78 | 75 | workflowId,
|
79 | 76 | taskQueue,
|
|
82 | 79 | encoding: $encoding,
|
83 | 80 | searchAttributes,
|
84 | 81 | });
|
85 |
| - await new Promise((resolve) => setTimeout(resolve, 2000)); |
86 |
| - goto(routeForWorkflows({ namespace })); |
| 82 | + toaster.push({ |
| 83 | + variant: 'success', |
| 84 | + duration: 5000, |
| 85 | + message: translate('workflows.start-workflow-success'), |
| 86 | + link: routeForEventHistory({ |
| 87 | + namespace, |
| 88 | + workflow: workflowId, |
| 89 | + run: runId, |
| 90 | + }), |
| 91 | + }); |
87 | 92 | } catch (e) {
|
88 |
| - error = e?.message || 'Error starting Workflow'; |
89 |
| - loading = false; |
| 93 | + error = e?.message || translate('workflows.start-workflow-error'); |
| 94 | + toaster.push({ |
| 95 | + variant: 'error', |
| 96 | + message: translate('workflows.start-workflow-error'), |
| 97 | + }); |
90 | 98 | }
|
91 | 99 | };
|
92 | 100 |
|
|
161 | 169 | </script>
|
162 | 170 |
|
163 | 171 | <div class="flex w-full flex-col items-center pb-24">
|
164 |
| - {#if loading} |
165 |
| - <Loading title={translate('workflows.starting-workflow')} /> |
166 |
| - {:else} |
167 |
| - <div class="mb-6 flex w-full items-start"> |
168 |
| - <Link |
169 |
| - href={`${routeForWorkflows({ |
170 |
| - namespace, |
171 |
| - })}?${$workflowsSearchParams}`} |
172 |
| - data-testid="back-to-workflows" |
173 |
| - icon="chevron-left" |
| 172 | + <div class="mb-6 flex w-full items-start"> |
| 173 | + <Link |
| 174 | + href={`${routeForWorkflows({ |
| 175 | + namespace, |
| 176 | + })}?${$workflowsSearchParams}`} |
| 177 | + data-testid="back-to-workflows" |
| 178 | + icon="chevron-left" |
| 179 | + > |
| 180 | + {translate('workflows.back-to-workflows')} |
| 181 | + </Link> |
| 182 | + </div> |
| 183 | + <div class="flex w-full flex-col gap-4 lg:w-2/3 2xl:w-1/2"> |
| 184 | + <h1 class="mb-4 overflow-hidden" data-testid="start-workflow"> |
| 185 | + Start a Workflow |
| 186 | + </h1> |
| 187 | + <div |
| 188 | + class="flex w-full flex-col items-center justify-between gap-2 md:flex-row md:gap-4" |
| 189 | + > |
| 190 | + <Input |
| 191 | + id="workflowId" |
| 192 | + required |
| 193 | + bind:value={workflowId} |
| 194 | + label="Workflow ID" |
| 195 | + class="w-full grow" |
| 196 | + on:blur={(e) => onInputChange(e, 'workflowId')} |
| 197 | + /> |
| 198 | + <Button |
| 199 | + class="mt-0 md:mt-6" |
| 200 | + variant="secondary" |
| 201 | + leadingIcon="retry" |
| 202 | + on:click={generateRandomWorkflowId}>Random UUID</Button |
174 | 203 | >
|
175 |
| - {translate('workflows.back-to-workflows')} |
176 |
| - </Link> |
177 | 204 | </div>
|
178 |
| - <div class="flex w-full flex-col gap-4 lg:w-2/3 2xl:w-1/2"> |
179 |
| - <h1 class="mb-4 overflow-hidden" data-testid="start-workflow"> |
180 |
| - Start a Workflow |
181 |
| - </h1> |
182 |
| - <div |
183 |
| - class="flex w-full flex-col items-center justify-between gap-2 md:flex-row md:gap-4" |
184 |
| - > |
185 |
| - <Input |
186 |
| - id="workflowId" |
187 |
| - required |
188 |
| - bind:value={workflowId} |
189 |
| - label="Workflow ID" |
190 |
| - class="w-full grow" |
191 |
| - on:blur={(e) => onInputChange(e, 'workflowId')} |
192 |
| - /> |
193 |
| - <Button |
194 |
| - class="mt-0 md:mt-6" |
195 |
| - variant="secondary" |
196 |
| - leadingIcon="retry" |
197 |
| - on:click={generateRandomWorkflowId}>Random UUID</Button |
198 |
| - > |
199 |
| - </div> |
200 |
| - <div class="flex w-full items-center justify-between gap-4"> |
201 |
| - <Input |
202 |
| - id="taskQueue" |
203 |
| - required |
204 |
| - bind:value={taskQueue} |
205 |
| - label="Task Queue" |
206 |
| - class="grow" |
207 |
| - on:blur={(e) => onInputChange(e, 'taskQueue')} |
208 |
| - /> |
209 |
| - </div> |
210 |
| - {#if pollerCount !== undefined} |
211 |
| - <Alert |
212 |
| - intent={pollerCount > 0 ? 'success' : 'warning'} |
213 |
| - title={pollerCount |
214 |
| - ? 'Task Queue is Active' |
215 |
| - : 'Task Queue is Inactive'} |
216 |
| - > |
217 |
| - <div class="flex w-full items-center justify-between"> |
218 |
| - <p> |
219 |
| - {pollerCount} |
220 |
| - {pluralize('Worker', pollerCount)} |
221 |
| - </p> |
222 |
| - <Link |
223 |
| - href={routeForTaskQueue({ namespace, queue: taskQueue })} |
224 |
| - newTab |
225 |
| - > |
226 |
| - View Task Queue |
227 |
| - </Link> |
228 |
| - </div></Alert |
229 |
| - > |
230 |
| - {/if} |
| 205 | + <div class="flex w-full items-center justify-between gap-4"> |
231 | 206 | <Input
|
232 |
| - id="workflowType" |
| 207 | + id="taskQueue" |
233 | 208 | required
|
234 |
| - bind:value={workflowType} |
235 |
| - label="Workflow Type" |
236 |
| - on:blur={(e) => onInputChange(e, 'workflowType')} |
| 209 | + bind:value={taskQueue} |
| 210 | + label="Task Queue" |
| 211 | + class="grow" |
| 212 | + on:blur={(e) => onInputChange(e, 'taskQueue')} |
237 | 213 | />
|
238 |
| - {#key inputRetrieved} |
239 |
| - <PayloadInput bind:input bind:encoding /> |
240 |
| - {/key} |
241 |
| - {#if viewAdvancedOptions} |
242 |
| - <AddSearchAttributes bind:attributesToAdd={searchAttributes} /> |
243 |
| - {/if} |
244 |
| - <div class="mt-4 flex w-full justify-between"> |
245 |
| - <Button |
246 |
| - variant="ghost" |
247 |
| - trailingIcon={viewAdvancedOptions ? 'chevron-up' : 'chevron-down'} |
248 |
| - on:click={() => (viewAdvancedOptions = !viewAdvancedOptions)} |
249 |
| - >{translate('common.more-options')}</Button |
250 |
| - > |
251 |
| - <Button |
252 |
| - disabled={!enableStart} |
253 |
| - on:click={onWorkflowStart} |
254 |
| - data-testid="start-workflow-button" |
255 |
| - >{translate('workflows.start-workflow')}</Button |
256 |
| - > |
257 |
| - </div> |
258 |
| - {#if error} |
259 |
| - <Alert intent="error" title={error} /> |
260 |
| - {/if} |
261 | 214 | </div>
|
262 |
| - {/if} |
| 215 | + {#if pollerCount !== undefined} |
| 216 | + <Alert |
| 217 | + intent={pollerCount > 0 ? 'success' : 'warning'} |
| 218 | + title={pollerCount ? 'Task Queue is Active' : 'Task Queue is Inactive'} |
| 219 | + > |
| 220 | + <div class="flex w-full items-center justify-between"> |
| 221 | + <p> |
| 222 | + {pollerCount} |
| 223 | + {pluralize('Worker', pollerCount)} |
| 224 | + </p> |
| 225 | + <Link |
| 226 | + href={routeForTaskQueue({ namespace, queue: taskQueue })} |
| 227 | + newTab |
| 228 | + > |
| 229 | + View Task Queue |
| 230 | + </Link> |
| 231 | + </div></Alert |
| 232 | + > |
| 233 | + {/if} |
| 234 | + <Input |
| 235 | + id="workflowType" |
| 236 | + required |
| 237 | + bind:value={workflowType} |
| 238 | + label="Workflow Type" |
| 239 | + on:blur={(e) => onInputChange(e, 'workflowType')} |
| 240 | + /> |
| 241 | + {#key inputRetrieved} |
| 242 | + <PayloadInput bind:input bind:encoding /> |
| 243 | + {/key} |
| 244 | + {#if viewAdvancedOptions} |
| 245 | + <AddSearchAttributes bind:attributesToAdd={searchAttributes} /> |
| 246 | + {/if} |
| 247 | + <div class="mt-4 flex w-full justify-between"> |
| 248 | + <Button |
| 249 | + variant="ghost" |
| 250 | + trailingIcon={viewAdvancedOptions ? 'chevron-up' : 'chevron-down'} |
| 251 | + on:click={() => (viewAdvancedOptions = !viewAdvancedOptions)} |
| 252 | + >{translate('common.more-options')}</Button |
| 253 | + > |
| 254 | + <Button |
| 255 | + disabled={!enableStart} |
| 256 | + on:click={onWorkflowStart} |
| 257 | + data-testid="start-workflow-button" |
| 258 | + >{translate('workflows.start-workflow')}</Button |
| 259 | + > |
| 260 | + </div> |
| 261 | + {#if error} |
| 262 | + <Alert intent="error" title={error} /> |
| 263 | + {/if} |
| 264 | + </div> |
263 | 265 | </div>
|
0 commit comments