Skip to content

Commit

Permalink
DT-1740 - update workflow reset UI for new reapply types in 1.24 (#2014)
Browse files Browse the repository at this point in the history
* update wf reset for new reapply types in 1.24

* consistent capitalization/wording on reset strings

* fix import from commonJS @temporalio/proto package

* fix tests

* fix tests

* add tests for server version 1.24.0, fix version checks

* handle unspecified

* rm console.log

* add isCloud checks

* send resetReapplyType = 3 (all elligible)
  • Loading branch information
rossedfort authored Sep 30, 2024
1 parent 7bf4fc6 commit c9415a2
Show file tree
Hide file tree
Showing 8 changed files with 251 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
import Checkbox from '$lib/holocene/checkbox.svelte';
import Input from '$lib/holocene/input/input.svelte';
import Modal from '$lib/holocene/modal.svelte';
import RadioGroup from '$lib/holocene/radio-input/radio-group.svelte';
import RadioInput from '$lib/holocene/radio-input/radio-input.svelte';
import Option from '$lib/holocene/select/option.svelte';
import Select from '$lib/holocene/select/select.svelte';
import { translate } from '$lib/i18n/translate';
import { ResetReapplyType } from '$lib/models/workflow-actions';
import { resetWorkflow } from '$lib/services/workflow-service';
import { isCloud } from '$lib/stores/advanced-visibility';
import { resetEvents } from '$lib/stores/events';
import { resetWorkflows } from '$lib/stores/reset-workflows';
import { temporalVersion } from '$lib/stores/versions';
import type { WorkflowExecution } from '$lib/types/workflows';
import { isNetworkError } from '$lib/utilities/is-network-error';
import { minimumVersionRequired } from '$lib/utilities/version-check';
export let open: boolean;
export let workflow: WorkflowExecution;
Expand All @@ -23,11 +25,15 @@
let loading = false;
let eventId: Writable<string> = writable('');
let reason: string;
let reapplySignals = false;
let includeSignals = true;
let excludeSignals = false;
let excludeUpdates = false;
const hideResetModal = () => {
open = false;
reapplySignals = false;
includeSignals = true;
excludeSignals = false;
excludeUpdates = false;
$eventId = '';
reason = '';
};
Expand All @@ -41,9 +47,9 @@
workflow,
eventId: $eventId,
reason,
reapplyType: reapplySignals
? ResetReapplyType.Signal
: ResetReapplyType.None,
includeSignals,
excludeSignals,
excludeUpdates,
});
if (response && response.runId) {
Expand Down Expand Up @@ -75,30 +81,43 @@
{loading}
on:confirmModal={reset}
on:cancelModal={hideResetModal}
confirmDisabled={!eventId}
confirmDisabled={!$eventId}
>
<h3 slot="title">{translate('workflows.reset-modal-title')}</h3>
<svelte:fragment slot="content">
<div class="flex w-full flex-col gap-4">
<RadioGroup
name="reset-event-id"
group={eventId}
class="max-h-40 overflow-auto"
description={translate('workflows.reset-event-radio-group-description')}
<Select
data-testid="workflow-reset-event-id-select"
menuClass="max-h-[16rem]"
label={translate('workflows.reset-event-radio-group-description')}
bind:value={$eventId}
id="reset-event-id"
>
{#each $resetEvents as event}
<RadioInput
id="reset-event-{event.id}"
value={event.id}
label="{event.id} - {event.eventType}"
/>
<Option value={event.id}>{event.id} - {event.eventType}</Option>
{/each}
</RadioGroup>
<Checkbox
id="reset-reapply-type-checkbox"
bind:checked={reapplySignals}
label={translate('workflows.reset-reapply-type-label')}
/>
</Select>
{#if $isCloud || minimumVersionRequired('1.24.0', $temporalVersion)}
<Checkbox
id="reset-exclude-signals-checkbox"
data-testid="reset-exclude-signals-checkbox"
bind:checked={excludeSignals}
label={translate('workflows.reset-exclude-signals')}
/>
<Checkbox
id="reset-exclude-updates-checkbox"
data-testid="reset-exclude-updates-checkbox"
bind:checked={excludeUpdates}
label={translate('workflows.reset-exclude-updates')}
/>
{:else}
<Checkbox
id="reset-include-signals-checkbox"
data-testid="reset-include-signals-checkbox"
bind:checked={includeSignals}
label={translate('workflows.reset-reapply-type-label')}
/>
{/if}

<Input
id="reset-reason"
Expand Down
2 changes: 1 addition & 1 deletion src/lib/holocene/menu/menu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
<ul
in:fly={{ duration: 100 }}
role="menu"
class={merge(['menu', 'max-h-[320px]'], position, className)}
class={merge('menu', 'max-h-[20rem]', position, className)}
class:hidden={!$open}
aria-labelledby={id}
tabindex={-1}
Expand Down
4 changes: 3 additions & 1 deletion src/lib/holocene/select/select.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
leadingIcon?: IconName;
onChange?: (value: T) => void;
'data-testid'?: string;
menuClass?: string;
variant?: MenuButtonVariant;
required?: boolean;
};
Expand All @@ -56,6 +57,7 @@
export let disabled = false;
export let leadingIcon: IconName = null;
export let onChange: (value: T) => void = noop;
export let menuClass: string | undefined = undefined;
export let variant: MenuButtonVariant = 'secondary';
export let required = false;
Expand Down Expand Up @@ -131,7 +133,7 @@
{/if}
</MenuButton>
{/key}
<Menu role="listbox" id="{id}-select">
<Menu role="listbox" id="{id}-select" class={menuClass}>
<slot />
</Menu>
</MenuContainer>
Expand Down
4 changes: 4 additions & 0 deletions src/lib/i18n/locales/en/workflows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ export const Strings = {
'reset-event-radio-group-description': 'Choose an Event to reset to',
'reset-reapply-type-label':
'Reapply Signals that happened after the Reset point',
'reset-exclude-signals':
'Exclude Signals that happened after the Reset point.',
'reset-exclude-updates':
'Exclude Updates that happened after the Reset point.',
'cancel-modal-title': 'Cancel Workflow',
'cancel-modal-confirmation':
'Are you sure you want to cancel this workflow? This action cannot be undone.',
Expand Down
6 changes: 0 additions & 6 deletions src/lib/models/workflow-actions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
export enum ResetReapplyType {
Unspecified = 0,
Signal = 1,
None = 2,
}

export enum Action {
Cancel,
Reset,
Expand Down
65 changes: 58 additions & 7 deletions src/lib/services/workflow-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,22 @@ import { v4 } from 'uuid';

import { page } from '$app/stores';

import { Action, type ResetReapplyType } from '$lib/models/workflow-actions';
import { Action } from '$lib/models/workflow-actions';
import {
toWorkflowExecution,
toWorkflowExecutions,
} from '$lib/models/workflow-execution';
import { isCloud } from '$lib/stores/advanced-visibility';
import { authUser } from '$lib/stores/auth-user';
import type { SearchAttributeInput } from '$lib/stores/search-attributes';
import { temporalVersion } from '$lib/stores/versions';
import { canFetchChildWorkflows } from '$lib/stores/workflows';
import type { ResetWorkflowRequest, SearchAttribute } from '$lib/types';
import {
ResetReapplyExcludeType,
ResetReapplyType,
type ResetWorkflowRequest,
type SearchAttribute,
} from '$lib/types';
import type {
ValidWorkflowEndpoints,
ValidWorkflowParameters,
Expand Down Expand Up @@ -46,7 +53,10 @@ import { toListWorkflowQuery } from '$lib/utilities/query/list-workflow-query';
import type { ErrorCallback } from '$lib/utilities/request-from-api';
import { requestFromAPI } from '$lib/utilities/request-from-api';
import { base, pathForApi, routeForApi } from '$lib/utilities/route-for-api';
import { isVersionNewer } from '$lib/utilities/version-check';
import {
isVersionNewer,
minimumVersionRequired,
} from '$lib/utilities/version-check';
import { formatReason } from '$lib/utilities/workflow-actions';

import { fetchInitialEvent } from './events-service';
Expand Down Expand Up @@ -94,7 +104,11 @@ export type ResetWorkflowOptions = {
workflow: WorkflowExecution;
eventId: string;
reason: string;
reapplyType: ResetReapplyType;
// used pre temporal server v1.24
includeSignals: boolean;
// used post temporal server v1.24
excludeSignals: boolean;
excludeUpdates: boolean;
};

export type FetchWorkflow =
Expand Down Expand Up @@ -347,7 +361,9 @@ export async function resetWorkflow({
workflow: { id: workflowId, runId },
eventId,
reason,
reapplyType,
includeSignals,
excludeSignals,
excludeUpdates,
}: ResetWorkflowOptions): Promise<{ runId: string }> {
const route = routeForApi('workflow.reset', {
namespace,
Expand All @@ -363,18 +379,53 @@ export async function resetWorkflow({

const body: Replace<
ResetWorkflowRequest,
{ workflowTaskFinishEventId: string; resetReapplyType: ResetReapplyType }
{ workflowTaskFinishEventId: string }
> = {
workflowExecution: {
workflowId,
runId,
},
workflowTaskFinishEventId: eventId,
resetReapplyType: reapplyType,
requestId: v4(),
reason: formattedReason,
};

if (get(isCloud) || minimumVersionRequired('1.24.0', get(temporalVersion))) {
const resetReapplyExcludeTypes: ResetWorkflowRequest['resetReapplyExcludeTypes'] =
[];

if (!excludeSignals && !excludeUpdates) {
resetReapplyExcludeTypes.push(
ResetReapplyExcludeType.RESET_REAPPLY_EXCLUDE_TYPE_UNSPECIFIED,
);
}

if (excludeSignals) {
resetReapplyExcludeTypes.push(
ResetReapplyExcludeType.RESET_REAPPLY_EXCLUDE_TYPE_SIGNAL,
);
}

if (excludeUpdates) {
resetReapplyExcludeTypes.push(
ResetReapplyExcludeType.RESET_REAPPLY_EXCLUDE_TYPE_UPDATE,
);
}

body.resetReapplyExcludeTypes = resetReapplyExcludeTypes;
body.resetReapplyType = ResetReapplyType.RESET_REAPPLY_TYPE_ALL_ELIGIBLE;
} else {
let resetReapplyType: ResetWorkflowRequest['resetReapplyType'];

if (includeSignals) {
resetReapplyType = ResetReapplyType.RESET_REAPPLY_TYPE_SIGNAL;
} else {
resetReapplyType = ResetReapplyType.RESET_REAPPLY_TYPE_NONE;
}

body.resetReapplyType = resetReapplyType;
}

return requestFromAPI<{ runId: string }>(route, {
notifyOnError: false,
options: {
Expand Down
15 changes: 15 additions & 0 deletions src/lib/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,21 @@ export type CallbackState = temporal.api.enums.v1.CallbackState;
export type PendingWorkflowTaskInfo =
temporal.api.workflow.v1.IPendingWorkflowTaskInfo;

// temporal.api.enums.v1.ResetReapplyExcludeType
export enum ResetReapplyExcludeType {
RESET_REAPPLY_EXCLUDE_TYPE_UNSPECIFIED = 0,
RESET_REAPPLY_EXCLUDE_TYPE_SIGNAL = 1,
RESET_REAPPLY_EXCLUDE_TYPE_UPDATE = 2,
}

// temporal.api.enums.v1.ResetReapplyType
export enum ResetReapplyType {
RESET_REAPPLY_TYPE_UNSPECIFIED = 0,
RESET_REAPPLY_TYPE_SIGNAL = 1,
RESET_REAPPLY_TYPE_NONE = 2,
RESET_REAPPLY_TYPE_ALL_ELIGIBLE = 3,
}

// api.workflow

export type PendingActivityInfo = temporal.api.workflow.v1.IPendingActivityInfo;
Expand Down
Loading

0 comments on commit c9415a2

Please sign in to comment.