Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import formatWorkflowHistoryEvent from '@/utils/data-formatters/format-workflow-history-event';
import { startWorkflowExecutionEvent } from '@/views/workflow-history/__fixtures__/workflow-history-single-events';

import { type FormattedFirstHistoryEvent } from '../workflow-summary-details/workflow-summary-details.types';

export const mockFormattedFirstEvent = formatWorkflowHistoryEvent(
startWorkflowExecutionEvent
) as FormattedFirstHistoryEvent;
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import WorkflowStatusTag from '@/views/shared/workflow-status-tag/workflow-statu
import getWorkflowStatusTagProps from '@/views/workflow-page/helpers/get-workflow-status-tag-props';

import WorkflowEventDetailsExecutionLink from '../../shared/workflow-event-details-execution-link/workflow-event-details-execution-link';
import getActiveClusterSelectionPolicy from '../workflow-summary-details/helpers/get-active-cluster-selection-policy';
import { ACTIVE_CLUSTER_SELECTION_STRATEGY_LABEL_MAP } from '../workflow-summary-details/workflow-summary-details.constants';
import { type WorkflowSummaryDetailsConfig } from '../workflow-summary-details/workflow-summary-details.types';

const workflowSummaryDetailsConfig: WorkflowSummaryDetailsConfig[] = [
Expand Down Expand Up @@ -144,6 +146,69 @@ const workflowSummaryDetailsConfig: WorkflowSummaryDetailsConfig[] = [
return !(runId && workflowId && domain && decodedPageUrlParams.cluster);
},
},
{
key: 'activeClusterSelectionStrategy',
getLabel: () => 'Cluster Strategy',
valueComponent: (args) => {
const policy = getActiveClusterSelectionPolicy(args);

return policy
? ACTIVE_CLUSTER_SELECTION_STRATEGY_LABEL_MAP[policy.strategy]
: null;
},
hide: (args) => getActiveClusterSelectionPolicy(args) === null,
},
{
key: 'stickyRegion',
getLabel: () => 'Sticky Region',
valueComponent: (args) => {
const policy = getActiveClusterSelectionPolicy(args);

if (
policy?.strategy !== 'ACTIVE_CLUSTER_SELECTION_STRATEGY_REGION_STICKY'
)
return null;

return policy.activeClusterStickyRegionConfig?.stickyRegion;
},
hide: (args) =>
getActiveClusterSelectionPolicy(args)?.strategy !==
'ACTIVE_CLUSTER_SELECTION_STRATEGY_REGION_STICKY',
},
{
key: 'externalEntityType',
getLabel: () => 'Entity Type',
valueComponent: (args) => {
const policy = getActiveClusterSelectionPolicy(args);

if (
policy?.strategy !== 'ACTIVE_CLUSTER_SELECTION_STRATEGY_EXTERNAL_ENTITY'
)
return null;

return policy.activeClusterExternalEntityConfig?.externalEntityType;
},
hide: (args) =>
getActiveClusterSelectionPolicy(args)?.strategy !==
'ACTIVE_CLUSTER_SELECTION_STRATEGY_EXTERNAL_ENTITY',
},
{
key: 'externalEntityKey',
getLabel: () => 'Entity Key',
valueComponent: (args) => {
const policy = getActiveClusterSelectionPolicy(args);

if (
policy?.strategy !== 'ACTIVE_CLUSTER_SELECTION_STRATEGY_EXTERNAL_ENTITY'
)
return null;

return policy.activeClusterExternalEntityConfig?.externalEntityKey;
},
hide: (args) =>
getActiveClusterSelectionPolicy(args)?.strategy !==
'ACTIVE_CLUSTER_SELECTION_STRATEGY_EXTERNAL_ENTITY',
},
];

export default workflowSummaryDetailsConfig;
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { render, screen } from '@/test-utils/rtl';

import { type DescribeWorkflowResponse } from '@/route-handlers/describe-workflow/describe-workflow.types';
import formatWorkflowHistoryEvent from '@/utils/data-formatters/format-workflow-history-event';
import { type FormattedHistoryEventForType } from '@/utils/data-formatters/schema/format-history-event-schema';
import {
completeWorkflowExecutionEvent,
startWorkflowExecutionEvent,
} from '@/views/workflow-history/__fixtures__/workflow-history-single-events';

import { mockFormattedFirstEvent } from '../../__fixtures__/formatted-first-history-event';
import WorkflowSummaryDetails from '../workflow-summary-details';
import {
type WorkflowSummaryDetailsConfig,
Expand Down Expand Up @@ -57,10 +57,6 @@ const mockWorkflowDetails: DescribeWorkflowResponse = {
};

describe('WorkflowSummaryDetails', () => {
// TODO @assem.hafez enhance typing for formattedFirstHistoryEvent
//@ts-expect-error - TS is complaining about the type of formattedFirstHistoryEvent
const formattedFirstHistoryEvent: FormattedHistoryEventForType<'WorkflowExecutionStarted'> =
formatWorkflowHistoryEvent(startWorkflowExecutionEvent);
const formattedCloseHistoryEvent = formatWorkflowHistoryEvent(
completeWorkflowExecutionEvent
);
Expand All @@ -69,7 +65,7 @@ describe('WorkflowSummaryDetails', () => {
<WorkflowSummaryDetails
firstHistoryEvent={startWorkflowExecutionEvent}
closeHistoryEvent={completeWorkflowExecutionEvent}
formattedFirstHistoryEvent={formattedFirstHistoryEvent}
formattedFirstHistoryEvent={mockFormattedFirstEvent}
formattedCloseHistoryEvent={formattedCloseHistoryEvent}
workflowDetails={mockWorkflowDetails}
decodedPageUrlParams={params}
Expand All @@ -85,7 +81,7 @@ describe('WorkflowSummaryDetails', () => {
<WorkflowSummaryDetails
firstHistoryEvent={startWorkflowExecutionEvent}
closeHistoryEvent={completeWorkflowExecutionEvent}
formattedFirstHistoryEvent={formattedFirstHistoryEvent}
formattedFirstHistoryEvent={mockFormattedFirstEvent}
formattedCloseHistoryEvent={formattedCloseHistoryEvent}
workflowDetails={mockWorkflowDetails}
decodedPageUrlParams={params}
Expand All @@ -103,7 +99,7 @@ describe('WorkflowSummaryDetails', () => {
<WorkflowSummaryDetails
firstHistoryEvent={startWorkflowExecutionEvent}
closeHistoryEvent={completeWorkflowExecutionEvent}
formattedFirstHistoryEvent={formattedFirstHistoryEvent}
formattedFirstHistoryEvent={mockFormattedFirstEvent}
formattedCloseHistoryEvent={formattedCloseHistoryEvent}
workflowDetails={mockWorkflowDetails}
decodedPageUrlParams={params}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { type ActiveClusterSelectionPolicy } from '@/__generated__/proto-ts/uber/cadence/api/v1/ActiveClusterSelectionPolicy';
import { mockDescribeWorkflowResponse } from '@/views/workflow-page/__fixtures__/describe-workflow-response';
import { mockFormattedFirstEvent } from '@/views/workflow-summary/__fixtures__/formatted-first-history-event';

import getActiveClusterSelectionPolicy from '../get-active-cluster-selection-policy';

const mockRegionStickyPolicy: ActiveClusterSelectionPolicy = {
strategyConfig: 'activeClusterStickyRegionConfig',
strategy: 'ACTIVE_CLUSTER_SELECTION_STRATEGY_REGION_STICKY',
activeClusterStickyRegionConfig: {
stickyRegion: 'us-west-1',
},
};

const mockExternalEntityPolicy: ActiveClusterSelectionPolicy = {
strategyConfig: 'activeClusterExternalEntityConfig',
strategy: 'ACTIVE_CLUSTER_SELECTION_STRATEGY_EXTERNAL_ENTITY',
activeClusterExternalEntityConfig: {
externalEntityType: 'customer',
externalEntityKey: 'customer-123',
},
};

describe(getActiveClusterSelectionPolicy.name, () => {
it('returns policy from workflowDetails when available', () => {
const result = getActiveClusterSelectionPolicy({
workflowDetails: {
...mockDescribeWorkflowResponse,
workflowExecutionInfo: {
...mockDescribeWorkflowResponse.workflowExecutionInfo,
activeClusterSelectionPolicy: mockRegionStickyPolicy,
},
},
formattedFirstEvent: mockFormattedFirstEvent,
});

expect(result).toEqual(mockRegionStickyPolicy);
});

it('returns policy from formattedFirstEvent when workflowDetails has no policy', () => {
const formattedFirstEvent = Object.assign({}, mockFormattedFirstEvent);
formattedFirstEvent.activeClusterSelectionPolicy = mockExternalEntityPolicy;

const result = getActiveClusterSelectionPolicy({
workflowDetails: mockDescribeWorkflowResponse,
formattedFirstEvent,
});

expect(result).toEqual(mockExternalEntityPolicy);
});

it('returns null when no policy is available in either source', () => {
const result = getActiveClusterSelectionPolicy({
workflowDetails: mockDescribeWorkflowResponse,
formattedFirstEvent: mockFormattedFirstEvent,
});

expect(result).toBeNull();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { type ActiveClusterSelectionPolicy } from '@/__generated__/proto-ts/uber/cadence/api/v1/ActiveClusterSelectionPolicy';

import { type WorkflowSummaryFieldArgs } from '../workflow-summary-details.types';

export default function getActiveClusterSelectionPolicy({
workflowDetails,
formattedFirstEvent,
}: Pick<
WorkflowSummaryFieldArgs,
'workflowDetails' | 'formattedFirstEvent'
>): ActiveClusterSelectionPolicy | null {
const policy =
workflowDetails.workflowExecutionInfo?.activeClusterSelectionPolicy ||
formattedFirstEvent?.activeClusterSelectionPolicy;

return policy ?? null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { type ActiveClusterSelectionStrategy } from '@/__generated__/proto-ts/uber/cadence/api/v1/ActiveClusterSelectionStrategy';

export const ACTIVE_CLUSTER_SELECTION_STRATEGY_LABEL_MAP = {
ACTIVE_CLUSTER_SELECTION_STRATEGY_INVALID: 'Invalid',
ACTIVE_CLUSTER_SELECTION_STRATEGY_REGION_STICKY: 'Region Sticky',
ACTIVE_CLUSTER_SELECTION_STRATEGY_EXTERNAL_ENTITY: 'External Entity',
} as const satisfies Record<ActiveClusterSelectionStrategy, string>;
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import {
} from '@/utils/data-formatters/schema/format-history-event-schema';
import type { WorkflowPageTabContentProps } from '@/views/workflow-page/workflow-page-tab-content/workflow-page-tab-content.types';

type FormattedFirstHistoryEvent =
export type FormattedFirstHistoryEvent =
FormattedHistoryEventForType<'WorkflowExecutionStarted'> | null;

export type Props = {
firstHistoryEvent: HistoryEvent;
closeHistoryEvent: HistoryEvent | null;
Expand All @@ -21,23 +22,18 @@ export type WorkflowSummaryDetailsComponent =
| keyof JSX.IntrinsicElements
| React.JSXElementConstructor<any>;

export type WorkflowSummaryFieldArgs = {
firstEvent: HistoryEvent;
closeEvent: HistoryEvent | null;
formattedFirstEvent: FormattedFirstHistoryEvent;
formattedCloseEvent: FormattedHistoryEvent | null;
workflowDetails: DescribeWorkflowResponse;
decodedPageUrlParams: Props['decodedPageUrlParams'];
};

export type WorkflowSummaryDetailsConfig = {
key: string;
getLabel: () => string;
valueComponent: React.ComponentType<{
firstEvent: HistoryEvent;
closeEvent: HistoryEvent | null;
formattedFirstEvent: FormattedFirstHistoryEvent;
formattedCloseEvent: FormattedHistoryEvent | null;
workflowDetails: DescribeWorkflowResponse;
decodedPageUrlParams: Props['decodedPageUrlParams'];
}>;
hide?: (args: {
firstEvent: HistoryEvent;
closeEvent: HistoryEvent | null;
formattedFirstEvent: FormattedFirstHistoryEvent;
formattedCloseEvent: FormattedHistoryEvent | null;
workflowDetails: DescribeWorkflowResponse;
decodedPageUrlParams: Props['decodedPageUrlParams'];
}) => boolean;
valueComponent: React.ComponentType<WorkflowSummaryFieldArgs>;
hide?: (args: WorkflowSummaryFieldArgs) => boolean;
};