export default {
name: 'text-input',
- props: ['label', 'name', 'readonly', 'type', 'value'],
+ props: ['disabled', 'label', 'name', 'readonly', 'type', 'value'],
methods: {
onInputChange(...args) {
this.$emit('input', ...args);
diff --git a/client/constants.js b/client/constants.js
index 1b31ead8c..8b5c3d536 100644
--- a/client/constants.js
+++ b/client/constants.js
@@ -38,6 +38,10 @@ export const LOCAL_STORAGE_SETTINGS = {
dateFormat: 'settings-date-format',
timeFormat: 'settings-time-format',
timezone: 'settings-timezone',
+ workflowHistoryEventHighlightList:
+ 'settings-workflow-history-event-highlight-list',
+ workflowHistoryEventHighlightListEnabled:
+ 'settings-workflow-history-event-highlight-list-enabled',
};
export const MAXIMUM_JSON_CHARACTER_LIMIT = 5000;
@@ -64,3 +68,55 @@ export const TIMEZONE_OPTIONS = [
{ label: 'Local', value: TIMEZONE_LOCAL },
{ label: 'UTC', value: TIMEZONE_UTC },
];
+
+export const WORKFLOW_EVENT_TYPE = {
+ ActivityTaskCanceled: 'ActivityTaskCanceled',
+ ActivityTaskCancelRequested: 'ActivityTaskCancelRequested',
+ ActivityTaskCompleted: 'ActivityTaskCompleted',
+ ActivityTaskFailed: 'ActivityTaskFailed',
+ ActivityTaskScheduled: 'ActivityTaskScheduled',
+ ActivityTaskStarted: 'ActivityTaskStarted',
+ ActivityTaskTimedOut: 'ActivityTaskTimedOut',
+ CancelTimerFailed: 'CancelTimerFailed',
+ ChildWorkflowExecutionCanceled: 'ChildWorkflowExecutionCanceled',
+ ChildWorkflowExecutionCompleted: 'ChildWorkflowExecutionCompleted',
+ ChildWorkflowExecutionFailed: 'ChildWorkflowExecutionFailed',
+ ChildWorkflowExecutionStarted: 'ChildWorkflowExecutionStarted',
+ ChildWorkflowExecutionTerminated: 'ChildWorkflowExecutionTerminated',
+ ChildWorkflowExecutionTimedOut: 'ChildWorkflowExecutionTimedOut',
+ DecisionTaskCompleted: 'DecisionTaskCompleted',
+ DecisionTaskFailed: 'DecisionTaskFailed',
+ DecisionTaskScheduled: 'DecisionTaskScheduled',
+ DecisionTaskStarted: 'DecisionTaskStarted',
+ DecisionTaskTimedOut: 'DecisionTaskTimedOut',
+ ExternalWorkflowExecutionCancelRequested:
+ 'ExternalWorkflowExecutionCancelRequested',
+ ExternalWorkflowExecutionSignaled: 'ExternalWorkflowExecutionSignaled',
+ MarkerRecorded: 'MarkerRecorded',
+ RequestCancelActivityTaskFailed: 'RequestCancelActivityTaskFailed',
+ RequestCancelExternalWorkflowExecutionFailed:
+ 'RequestCancelExternalWorkflowExecutionFailed',
+ RequestCancelExternalWorkflowExecutionInitiated:
+ 'RequestCancelExternalWorkflowExecutionInitiated',
+ SignalExternalWorkflowExecutionFailed:
+ 'SignalExternalWorkflowExecutionFailed',
+ SignalExternalWorkflowExecutionInitiated:
+ 'SignalExternalWorkflowExecutionInitiated',
+ StartChildWorkflowExecutionFailed: 'StartChildWorkflowExecutionFailed',
+ StartChildWorkflowExecutionInitiated: 'StartChildWorkflowExecutionInitiated',
+ TimerCanceled: 'TimerCanceled',
+ TimerFired: 'TimerFired',
+ TimerStarted: 'TimerStarted',
+ UpsertWorkflowSearchAttributes: 'UpsertWorkflowSearchAttributes',
+ WorkflowExecutionCanceled: 'WorkflowExecutionCanceled',
+ WorkflowExecutionCancelRequested: 'WorkflowExecutionCancelRequested',
+ WorkflowExecutionCompleted: 'WorkflowExecutionCompleted',
+ WorkflowExecutionContinuedAsNew: 'WorkflowExecutionContinuedAsNew',
+ WorkflowExecutionFailed: 'WorkflowExecutionFailed',
+ WorkflowExecutionSignaled: 'WorkflowExecutionSignaled',
+ WorkflowExecutionStarted: 'WorkflowExecutionStarted',
+ WorkflowExecutionTerminated: 'WorkflowExecutionTerminated',
+ WorkflowExecutionTimedOut: 'WorkflowExecutionTimedOut',
+};
+
+export const WORKFLOW_EVENT_TYPES = Object.values(WORKFLOW_EVENT_TYPE);
diff --git a/client/helpers/get-query-string-from-object.js b/client/helpers/get-query-string-from-object.js
index cd7c7ee5a..113e7a842 100644
--- a/client/helpers/get-query-string-from-object.js
+++ b/client/helpers/get-query-string-from-object.js
@@ -1,11 +1,21 @@
const getQueryStringFromObject = (params = {}) => {
const paramKeys = Object.keys(params);
+
if (paramKeys.length === 0) {
return '';
}
- return '?' + paramKeys.map((queryName) =>
- encodeURIComponent(queryName) + '=' + encodeURIComponent(params[queryName])
- ).join('&');
+
+ return (
+ '?' +
+ paramKeys
+ .map(
+ queryName =>
+ encodeURIComponent(queryName) +
+ '=' +
+ encodeURIComponent(params[queryName])
+ )
+ .join('&')
+ );
};
export default getQueryStringFromObject;
diff --git a/client/helpers/get-query-string-from-object.spec.js b/client/helpers/get-query-string-from-object.spec.js
index ce032837d..89ebf3a1d 100644
--- a/client/helpers/get-query-string-from-object.spec.js
+++ b/client/helpers/get-query-string-from-object.spec.js
@@ -3,6 +3,7 @@ import getQueryStringFromObject from './get-query-string-from-object';
describe('getQueryStringFromObject', () => {
it('should return empty string when no params are passed.', () => {
const output = getQueryStringFromObject();
+
expect(output).toEqual('');
});
@@ -12,6 +13,9 @@ describe('getQueryStringFromObject', () => {
booleanParam: true,
numberParam: 20,
});
- expect(output).toEqual('?stringParam=string&booleanParam=true&numberParam=20');
+
+ expect(output).toEqual(
+ '?stringParam=string&booleanParam=true&numberParam=20'
+ );
});
});
diff --git a/client/helpers/index.js b/client/helpers/index.js
index dcbb36c55..8a3840b72 100644
--- a/client/helpers/index.js
+++ b/client/helpers/index.js
@@ -14,4 +14,7 @@ export { default as http } from './http';
export { default as injectMomentDurationFormat } from './inject-moment-duration-format';
export { default as jsonTryParse } from './json-try-parse';
export { default as mapDomainDescription } from './map-domain-description';
+export { default as parseStringToBoolean } from './parse-string-to-boolean';
export { default as shortName } from './short-name';
+export { default as workflowHistoryEventHighlightListAddOrUpdate } from './workflow-history-event-highlight-list-add-or-update';
+export { default as workflowHistoryEventHighlightListRemove } from './workflow-history-event-highlight-list-remove';
diff --git a/client/helpers/parse-string-to-boolean.js b/client/helpers/parse-string-to-boolean.js
new file mode 100644
index 000000000..0097d1974
--- /dev/null
+++ b/client/helpers/parse-string-to-boolean.js
@@ -0,0 +1,13 @@
+const parseStringToBoolean = (value, defaultValue = false) => {
+ if (value === 'true') {
+ return true;
+ }
+
+ if (value === 'false') {
+ return false;
+ }
+
+ return defaultValue;
+};
+
+export default parseStringToBoolean;
diff --git a/client/helpers/parse-string-to-boolean.spec.js b/client/helpers/parse-string-to-boolean.spec.js
new file mode 100644
index 000000000..6f7158f3f
--- /dev/null
+++ b/client/helpers/parse-string-to-boolean.spec.js
@@ -0,0 +1,27 @@
+import parseStringToBoolean from './parse-string-to-boolean';
+
+describe('parseStringToBoolean', () => {
+ it('should return true when passed value = "true".', () => {
+ const output = parseStringToBoolean('true');
+
+ expect(output).toEqual(true);
+ });
+
+ it('should return false when passed value = "false".', () => {
+ const output = parseStringToBoolean('false');
+
+ expect(output).toEqual(false);
+ });
+
+ it('should return false when nothing is passed.', () => {
+ const output = parseStringToBoolean();
+
+ expect(output).toEqual(false);
+ });
+
+ it('should return true when passed value = null and defaultValue = true.', () => {
+ const output = parseStringToBoolean(null, true);
+
+ expect(output).toEqual(true);
+ });
+});
diff --git a/client/helpers/workflow-history-event-highlight-list-add-or-update.js b/client/helpers/workflow-history-event-highlight-list-add-or-update.js
new file mode 100644
index 000000000..830e696d1
--- /dev/null
+++ b/client/helpers/workflow-history-event-highlight-list-add-or-update.js
@@ -0,0 +1,49 @@
+import findIndexById from './workflow-history-event-highlight-list-find-index-by-id';
+
+const findIndexByTypeAndParamName = ({
+ eventType,
+ eventParamName,
+}) => eventParam =>
+ eventParam.eventType === eventType &&
+ eventParam.eventParamName === eventParamName;
+
+const workflowHistoryEventHighlightListAddOrUpdate = ({
+ eventParamName,
+ eventType,
+ id,
+ isEnabled,
+ workflowHistoryEventHighlightList,
+}) => {
+ const findIndexHandler = id
+ ? findIndexById({ id })
+ : findIndexByTypeAndParamName({ eventParamName, eventType });
+
+ const index = workflowHistoryEventHighlightList.findIndex(findIndexHandler);
+
+ if (index === -1) {
+ return [
+ {
+ eventParamName,
+ eventType,
+ id: Date.now(),
+ isEnabled,
+ },
+ ...workflowHistoryEventHighlightList,
+ ];
+ }
+
+ const event = workflowHistoryEventHighlightList[index];
+
+ return [
+ ...workflowHistoryEventHighlightList.slice(0, index),
+ {
+ ...event,
+ eventParamName,
+ eventType,
+ isEnabled,
+ },
+ ...workflowHistoryEventHighlightList.slice(index + 1),
+ ];
+};
+
+export default workflowHistoryEventHighlightListAddOrUpdate;
diff --git a/client/helpers/workflow-history-event-highlight-list-add-or-update.spec.js b/client/helpers/workflow-history-event-highlight-list-add-or-update.spec.js
new file mode 100644
index 000000000..7b74e50b4
--- /dev/null
+++ b/client/helpers/workflow-history-event-highlight-list-add-or-update.spec.js
@@ -0,0 +1,151 @@
+import addOrUpdate from './workflow-history-event-highlight-list-add-or-update';
+
+describe('workflowHistoryEventHighlightListAddOrUpdate', () => {
+ it('should add an item to start of list if not found with id = 1.', () => {
+ jest.spyOn(Date, 'now').mockImplementationOnce(() => 1);
+
+ const workflowHistoryEventHighlightList = [
+ {
+ id: 0,
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskCanceled',
+ isEnabled: false,
+ },
+ {
+ id: 2,
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskCompleted',
+ isEnabled: false,
+ },
+ {
+ id: 3,
+ eventParamName: 'eventId',
+ eventType: 'DecisionTaskCompleted',
+ isEnabled: false,
+ },
+ {
+ id: 4,
+ eventParamName: 'eventId',
+ eventType: 'DecisionTaskScheduled',
+ isEnabled: false,
+ },
+ ];
+
+ const output = addOrUpdate({
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskScheduled',
+ id: 1,
+ isEnabled: true,
+ workflowHistoryEventHighlightList,
+ });
+
+ expect(output.length).toEqual(5);
+ expect(output[0]).toEqual({
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskScheduled',
+ id: 1,
+ isEnabled: true,
+ });
+ });
+
+ it('should update item in list with id = 1.', () => {
+ const workflowHistoryEventHighlightList = [
+ {
+ id: 0,
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskCanceled',
+ isEnabled: false,
+ },
+ {
+ id: 1,
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskScheduled',
+ isEnabled: false,
+ },
+ {
+ id: 2,
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskCompleted',
+ isEnabled: false,
+ },
+ {
+ id: 3,
+ eventParamName: 'eventId',
+ eventType: 'DecisionTaskCompleted',
+ isEnabled: false,
+ },
+ {
+ id: 4,
+ eventParamName: 'eventId',
+ eventType: 'DecisionTaskScheduled',
+ isEnabled: false,
+ },
+ ];
+
+ const output = addOrUpdate({
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskScheduled',
+ id: 1,
+ isEnabled: true,
+ workflowHistoryEventHighlightList,
+ });
+
+ expect(output.length).toEqual(5);
+ expect(output[1]).toEqual({
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskScheduled',
+ id: 1,
+ isEnabled: true,
+ });
+ });
+
+ it('should update item in list with eventType = "ActivityTaskScheduled" and eventParamName = "eventId" (no id specified).', () => {
+ const workflowHistoryEventHighlightList = [
+ {
+ id: 0,
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskCanceled',
+ isEnabled: false,
+ },
+ {
+ id: 1,
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskScheduled',
+ isEnabled: false,
+ },
+ {
+ id: 2,
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskCompleted',
+ isEnabled: false,
+ },
+ {
+ id: 3,
+ eventParamName: 'eventId',
+ eventType: 'DecisionTaskCompleted',
+ isEnabled: false,
+ },
+ {
+ id: 4,
+ eventParamName: 'eventId',
+ eventType: 'DecisionTaskScheduled',
+ isEnabled: false,
+ },
+ ];
+
+ const output = addOrUpdate({
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskScheduled',
+ isEnabled: true,
+ workflowHistoryEventHighlightList,
+ });
+
+ expect(output.length).toEqual(5);
+ expect(output[1]).toEqual({
+ eventParamName: 'eventId',
+ eventType: 'ActivityTaskScheduled',
+ id: 1,
+ isEnabled: true,
+ });
+ });
+});
diff --git a/client/helpers/workflow-history-event-highlight-list-find-index-by-id.js b/client/helpers/workflow-history-event-highlight-list-find-index-by-id.js
new file mode 100644
index 000000000..6db25b942
--- /dev/null
+++ b/client/helpers/workflow-history-event-highlight-list-find-index-by-id.js
@@ -0,0 +1,4 @@
+const workflowHistoryEventHighlightListFindIndexById = ({ id }) => eventParam =>
+ eventParam.id === id;
+
+export default workflowHistoryEventHighlightListFindIndexById;
diff --git a/client/helpers/workflow-history-event-highlight-list-find-index-by-id.spec.js b/client/helpers/workflow-history-event-highlight-list-find-index-by-id.spec.js
new file mode 100644
index 000000000..86a9cdc91
--- /dev/null
+++ b/client/helpers/workflow-history-event-highlight-list-find-index-by-id.spec.js
@@ -0,0 +1,34 @@
+import findIndexById from './workflow-history-event-highlight-list-find-index-by-id';
+
+describe('workflowHistoryEventHighlightListFindIndexById', () => {
+ it('should return -1 if it cant find item in the list.', () => {
+ const workflowHistoryEventHighlightList = [
+ { id: 0 },
+ { id: 2 },
+ { id: 3 },
+ { id: 4 },
+ ];
+
+ const output = workflowHistoryEventHighlightList.findIndex(
+ findIndexById({ id: 1 })
+ );
+
+ expect(output).toEqual(-1);
+ });
+
+ it('should return index = 1 when id = 1 and matching item with id = 1 is the second in the list.', () => {
+ const workflowHistoryEventHighlightList = [
+ { id: 0 },
+ { id: 1 },
+ { id: 2 },
+ { id: 3 },
+ { id: 4 },
+ ];
+
+ const output = workflowHistoryEventHighlightList.findIndex(
+ findIndexById({ id: 1 })
+ );
+
+ expect(output).toEqual(1);
+ });
+});
diff --git a/client/helpers/workflow-history-event-highlight-list-remove.js b/client/helpers/workflow-history-event-highlight-list-remove.js
new file mode 100644
index 000000000..6d73011ed
--- /dev/null
+++ b/client/helpers/workflow-history-event-highlight-list-remove.js
@@ -0,0 +1,21 @@
+import findIndexById from './workflow-history-event-highlight-list-find-index-by-id';
+
+const workflowHistoryEventHighlightListRemove = ({
+ id,
+ workflowHistoryEventHighlightList,
+}) => {
+ const index = workflowHistoryEventHighlightList.findIndex(
+ findIndexById({ id })
+ );
+
+ if (index === -1) {
+ return workflowHistoryEventHighlightList;
+ }
+
+ return [
+ ...workflowHistoryEventHighlightList.slice(0, index),
+ ...workflowHistoryEventHighlightList.slice(index + 1),
+ ];
+};
+
+export default workflowHistoryEventHighlightListRemove;
diff --git a/client/helpers/workflow-history-event-highlight-list-remove.spec.js b/client/helpers/workflow-history-event-highlight-list-remove.spec.js
new file mode 100644
index 000000000..507f85b1d
--- /dev/null
+++ b/client/helpers/workflow-history-event-highlight-list-remove.spec.js
@@ -0,0 +1,36 @@
+import remove from './workflow-history-event-highlight-list-remove';
+
+describe('workflowHistoryEventHighlightListRemove', () => {
+ it('list is unchanged when no item with id = 1 in list and passed id = 1.', () => {
+ const workflowHistoryEventHighlightList = [
+ { id: 0 },
+ { id: 2 },
+ { id: 3 },
+ { id: 4 },
+ ];
+
+ const output = remove({
+ id: 1,
+ workflowHistoryEventHighlightList,
+ });
+
+ expect(output).toEqual(workflowHistoryEventHighlightList);
+ });
+
+ it('removes item with id = 1 from list when passed id = 1.', () => {
+ const workflowHistoryEventHighlightList = [
+ { id: 0 },
+ { id: 1 },
+ { id: 2 },
+ { id: 3 },
+ { id: 4 },
+ ];
+
+ const output = remove({
+ id: 1,
+ workflowHistoryEventHighlightList,
+ });
+
+ expect(output).toEqual([{ id: 0 }, { id: 2 }, { id: 3 }, { id: 4 }]);
+ });
+});
diff --git a/client/routes/index.vue b/client/routes/index.vue
index f912941b8..106b25385 100644
--- a/client/routes/index.vue
+++ b/client/routes/index.vue
@@ -14,7 +14,11 @@
/>
-
+
@@ -32,6 +36,9 @@ export default {
onNotification(event) {
this.$emit('onNotification', event);
},
+ onWorkflowHistoryEventParamToggle(event) {
+ this.$emit('onWorkflowHistoryEventParamToggle', event);
+ },
},
};
diff --git a/client/routes/workflow/components/event-detail.vue b/client/routes/workflow/components/event-detail.vue
index a04dc858b..7e08b4dd8 100644
--- a/client/routes/workflow/components/event-detail.vue
+++ b/client/routes/workflow/components/event-detail.vue
@@ -3,7 +3,7 @@ import { DetailList } from '~components';
export default {
name: 'event-detail',
- props: ['event', 'compact', 'highlight'],
+ props: ['event', 'isHighlightEnabled', 'compact'],
components: {
'detail-list': DetailList,
},
@@ -14,11 +14,16 @@ export default {
return h('detail-list', {
props: {
+ isHighlightEnabled: this.isHighlightEnabled,
item: this.event,
- highlight: this.highlight,
compact: this.compact,
title: `Event #${this.event.eventId} ${this.event.eventType}`,
},
+ on: {
+ onWorkflowHistoryEventParamToggle: event => {
+ this.$emit('onWorkflowHistoryEventParamToggle', event);
+ },
+ },
});
},
};
diff --git a/client/routes/workflow/helpers/event-full-transforms.js b/client/routes/workflow/helpers/event-full-transforms.js
index 1de6b7a4b..115d05f7e 100644
--- a/client/routes/workflow/helpers/event-full-transforms.js
+++ b/client/routes/workflow/helpers/event-full-transforms.js
@@ -1,5 +1,7 @@
+import { WORKFLOW_EVENT_TYPE } from '~constants';
+
export const eventFullTransforms = {
- MarkerRecorded: d => {
+ [WORKFLOW_EVENT_TYPE.MarkerRecorded]: d => {
if (d.markerName === 'SideEffect') {
return {
sideEffectID: d.details[0],
diff --git a/client/routes/workflow/helpers/get-event-details.js b/client/routes/workflow/helpers/get-event-details.js
index 0c864618e..16d3e5d96 100644
--- a/client/routes/workflow/helpers/get-event-details.js
+++ b/client/routes/workflow/helpers/get-event-details.js
@@ -1,17 +1,29 @@
+import getEventKvpsHighlight from './get-event-kvps-highlight';
import { getKeyValuePairs } from '~helpers';
-const getEventDetails = event => {
+const getEventDetails = ({
+ event,
+ workflowHistoryEventHighlightList = [],
+ workflowHistoryEventHighlightListEnabled = false,
+}) => {
const { details, eventId, eventType, timeStampDisplay } = event;
- const kvps = getKeyValuePairs({
- timestamp: timeStampDisplay,
- eventId,
- ...details,
+
+ const { kvps, isHighlighted } = getEventKvpsHighlight({
+ eventType,
+ kvps: getKeyValuePairs({
+ timestamp: timeStampDisplay,
+ eventId,
+ ...details,
+ }),
+ workflowHistoryEventHighlightList,
+ workflowHistoryEventHighlightListEnabled,
});
return {
...details,
eventId,
eventType,
+ isHighlighted,
kvps,
timestamp: timeStampDisplay,
};
diff --git a/client/routes/workflow/helpers/get-event-details.spec.js b/client/routes/workflow/helpers/get-event-details.spec.js
index fac71de4b..c576a89ef 100644
--- a/client/routes/workflow/helpers/get-event-details.spec.js
+++ b/client/routes/workflow/helpers/get-event-details.spec.js
@@ -17,25 +17,25 @@ describe('getEventDetails', () => {
});
it('should return an object with a copy of details.', () => {
- const output = getEventDetails(event);
+ const output = getEventDetails({ event });
expect(output.key).toEqual('value');
});
it('should return an object with eventId.', () => {
- const output = getEventDetails(event);
+ const output = getEventDetails({ event });
expect(output.eventId).toEqual('eventIdValue');
});
it('should return an object with eventType.', () => {
- const output = getEventDetails(event);
+ const output = getEventDetails({ event });
expect(output.eventType).toEqual('eventTypeValue');
});
it('should return an object with kvps.', () => {
- const output = getEventDetails(event);
+ const output = getEventDetails({ event });
expect(output.kvps).toEqual('kvpsMock');
});
diff --git a/client/routes/workflow/helpers/get-event-full-details.js b/client/routes/workflow/helpers/get-event-full-details.js
index 9e37bf0e2..bc765ac5e 100644
--- a/client/routes/workflow/helpers/get-event-full-details.js
+++ b/client/routes/workflow/helpers/get-event-full-details.js
@@ -1,7 +1,12 @@
import { eventFullTransforms } from './event-full-transforms';
+import getEventKvpsHighlight from './get-event-kvps-highlight';
import { getKeyValuePairs } from '~helpers';
-const getEventFullDetails = event => {
+const getEventFullDetails = ({
+ event,
+ workflowHistoryEventHighlightList,
+ workflowHistoryEventHighlightListEnabled,
+} = {}) => {
if (!event) {
return event;
}
@@ -15,12 +20,18 @@ const getEventFullDetails = event => {
? maps[event.eventType](event.details)
: event.details;
- const kvps = getKeyValuePairs(item);
+ const { kvps, isHighlighted } = getEventKvpsHighlight({
+ eventType,
+ kvps: getKeyValuePairs(item),
+ workflowHistoryEventHighlightList,
+ workflowHistoryEventHighlightListEnabled,
+ });
return {
...item,
eventId,
eventType,
+ isHighlighted,
kvps,
};
};
diff --git a/client/routes/workflow/helpers/get-event-full-details.spec.js b/client/routes/workflow/helpers/get-event-full-details.spec.js
index 4f0874f33..4c40dff1c 100644
--- a/client/routes/workflow/helpers/get-event-full-details.spec.js
+++ b/client/routes/workflow/helpers/get-event-full-details.spec.js
@@ -5,9 +5,9 @@ jest.mock('~helpers');
describe('getEventFullDetails', () => {
describe('When passed no event', () => {
it('should return what was passed.', () => {
- const output = getEventFullDetails(false);
+ const output = getEventFullDetails();
- expect(output).toEqual(false);
+ expect(output).toEqual(undefined);
});
});
@@ -25,25 +25,25 @@ describe('getEventFullDetails', () => {
});
it('should return an object with a copy of details.', () => {
- const output = getEventFullDetails(event);
+ const output = getEventFullDetails({ event });
expect(output.key).toEqual('value');
});
it('should return an object with eventId.', () => {
- const output = getEventFullDetails(event);
+ const output = getEventFullDetails({ event });
expect(output.eventId).toEqual('eventIdValue');
});
it('should return an object with eventType.', () => {
- const output = getEventFullDetails(event);
+ const output = getEventFullDetails({ event });
expect(output.eventType).toEqual('eventTypeValue');
});
it('should return an object with kvps.', () => {
- const output = getEventFullDetails(event);
+ const output = getEventFullDetails({ event });
expect(output.kvps).toEqual('kvpsMock');
});
diff --git a/client/routes/workflow/helpers/get-event-kvps-highlight.js b/client/routes/workflow/helpers/get-event-kvps-highlight.js
new file mode 100644
index 000000000..58ba4a573
--- /dev/null
+++ b/client/routes/workflow/helpers/get-event-kvps-highlight.js
@@ -0,0 +1,47 @@
+const getEventKvpsHighlight = ({
+ eventType,
+ kvps,
+ workflowHistoryEventHighlightList,
+ workflowHistoryEventHighlightListEnabled,
+}) => {
+ let eventIsHighlighted = false;
+
+ if (!workflowHistoryEventHighlightListEnabled) {
+ return {
+ kvps,
+ isHighlighted: false,
+ };
+ }
+
+ const filteredWorkflowHistoryEventHighlightList = workflowHistoryEventHighlightList.filter(
+ highlight => highlight.isEnabled && highlight.eventType === eventType
+ );
+
+ if (!filteredWorkflowHistoryEventHighlightList.length) {
+ return {
+ kvps,
+ isHighlighted: false,
+ };
+ }
+
+ return {
+ kvps: kvps.map(kvp => {
+ const isHighlighted =
+ filteredWorkflowHistoryEventHighlightList.find(
+ ({ eventParamName }) => eventParamName === kvp.key
+ ) !== undefined;
+
+ if (isHighlighted) {
+ eventIsHighlighted = true;
+ }
+
+ return {
+ ...kvp,
+ isHighlighted,
+ };
+ }),
+ isHighlighted: eventIsHighlighted,
+ };
+};
+
+export default getEventKvpsHighlight;
diff --git a/client/routes/workflow/helpers/get-event-kvps-highlight.spec.js b/client/routes/workflow/helpers/get-event-kvps-highlight.spec.js
new file mode 100644
index 000000000..b3e7c0db7
--- /dev/null
+++ b/client/routes/workflow/helpers/get-event-kvps-highlight.spec.js
@@ -0,0 +1,116 @@
+import getEventKvpsHighlight from './get-event-kvps-highlight';
+
+describe('getEventKvpsHighlight', () => {
+ it('should return isHighlighted = false when workflowHistoryEventHighlightListEnabled = false.', () => {
+ const output = getEventKvpsHighlight({
+ eventType: 'ActivityTaskScheduled',
+ kvps: [],
+ workflowHistoryEventHighlightList: [],
+ workflowHistoryEventHighlightListEnabled: false,
+ });
+
+ expect(output).toEqual({
+ kvps: [],
+ isHighlighted: false,
+ });
+ });
+
+ it('should return isHighlighted = false when workflowHistoryEventHighlightListEnabled = true and workflowHistoryEventHighlightList items are not enabled.', () => {
+ const workflowHistoryEventHighlightList = [
+ {
+ eventType: 'ActivityTaskScheduled',
+ eventParamName: 'eventId',
+ isEnabled: false,
+ },
+ ];
+
+ const output = getEventKvpsHighlight({
+ eventType: 'ActivityTaskScheduled',
+ kvps: [],
+ workflowHistoryEventHighlightList,
+ workflowHistoryEventHighlightListEnabled: true,
+ });
+
+ expect(output).toEqual({
+ kvps: [],
+ isHighlighted: false,
+ });
+ });
+
+ it('should return isHighlighted = true and kvp.isHighlighted = true when workflowHistoryEventHighlightListEnabled = true and workflowHistoryEventHighlightList items are matching and enabled.', () => {
+ const workflowHistoryEventHighlightList = [
+ {
+ eventType: 'ActivityTaskScheduled',
+ eventParamName: 'eventId',
+ isEnabled: true,
+ },
+ ];
+ const kvps = [
+ {
+ key: 'eventId',
+ value: 1,
+ },
+ {
+ key: 'scheduledEventId',
+ value: 0,
+ },
+ ];
+
+ const output = getEventKvpsHighlight({
+ eventType: 'ActivityTaskScheduled',
+ kvps,
+ workflowHistoryEventHighlightList,
+ workflowHistoryEventHighlightListEnabled: true,
+ });
+
+ expect(output).toEqual({
+ kvps: [
+ {
+ isHighlighted: true,
+ key: 'eventId',
+ value: 1,
+ },
+ {
+ isHighlighted: false,
+ key: 'scheduledEventId',
+ value: 0,
+ },
+ ],
+ isHighlighted: true,
+ });
+ });
+
+ it('should return isHighlighted = false and kvp.isHighlighted = false when workflowHistoryEventHighlightListEnabled = true and workflowHistoryEventHighlightList items are not matching and enabled.', () => {
+ const workflowHistoryEventHighlightList = [
+ {
+ eventType: 'ActivityTaskScheduled',
+ eventParamName: 'eventId',
+ isEnabled: true,
+ },
+ ];
+ const kvps = [
+ {
+ key: 'scheduledEventId',
+ value: 0,
+ },
+ ];
+
+ const output = getEventKvpsHighlight({
+ eventType: 'ActivityTaskScheduled',
+ kvps,
+ workflowHistoryEventHighlightList,
+ workflowHistoryEventHighlightListEnabled: true,
+ });
+
+ expect(output).toEqual({
+ kvps: [
+ {
+ isHighlighted: false,
+ key: 'scheduledEventId',
+ value: 0,
+ },
+ ],
+ isHighlighted: false,
+ });
+ });
+});
diff --git a/client/routes/workflow/helpers/get-history-events.js b/client/routes/workflow/helpers/get-history-events.js
index 1481a5d0b..da16f0345 100644
--- a/client/routes/workflow/helpers/get-history-events.js
+++ b/client/routes/workflow/helpers/get-history-events.js
@@ -5,7 +5,14 @@ import getEventDetails from './get-event-details';
import getEventFullDetails from './get-event-full-details';
import getEventSummary from './get-event-summary';
-const getHistoryEvents = ({ dateFormat, events, timeFormat, timezone }) => {
+const getHistoryEvents = ({
+ dateFormat,
+ events,
+ timeFormat,
+ timezone,
+ workflowHistoryEventHighlightList,
+ workflowHistoryEventHighlightListEnabled,
+}) => {
if (!events) {
return [];
}
@@ -43,9 +50,17 @@ const getHistoryEvents = ({ dateFormat, events, timeFormat, timezone }) => {
};
})
.map(event => {
- const details = getEventDetails(event);
+ const details = getEventDetails({
+ event,
+ workflowHistoryEventHighlightList,
+ workflowHistoryEventHighlightListEnabled,
+ });
const eventSummary = getEventSummary(event);
- const eventFullDetails = getEventFullDetails(event);
+ const eventFullDetails = getEventFullDetails({
+ event,
+ workflowHistoryEventHighlightList,
+ workflowHistoryEventHighlightListEnabled,
+ });
return {
...event,
diff --git a/client/routes/workflow/helpers/get-history-timeline-events.js b/client/routes/workflow/helpers/get-history-timeline-events.js
index 78b393947..8e4356002 100644
--- a/client/routes/workflow/helpers/get-history-timeline-events.js
+++ b/client/routes/workflow/helpers/get-history-timeline-events.js
@@ -3,7 +3,7 @@ import mapTimelineEvents from './map-timeline-events';
const getHistoryTimelineEvents = ({ historyEvents }) =>
mapTimelineEvents(historyEvents).map(event => {
- const details = getEventDetails(event);
+ const details = getEventDetails({ event });
return { ...event, details };
});
diff --git a/client/routes/workflow/helpers/get-summary-workflow-status.js b/client/routes/workflow/helpers/get-summary-workflow-status.js
index 9180a8785..9888d4072 100644
--- a/client/routes/workflow/helpers/get-summary-workflow-status.js
+++ b/client/routes/workflow/helpers/get-summary-workflow-status.js
@@ -1,3 +1,5 @@
+import { WORKFLOW_EVENT_TYPE } from '~constants';
+
const getSummaryWorkflowStatus = ({
isWorkflowRunning,
workflow,
@@ -14,7 +16,10 @@ const getSummaryWorkflowStatus = ({
).toLowerCase();
}
- if (workflowCompletedEvent.eventType === 'WorkflowExecutionContinuedAsNew') {
+ if (
+ workflowCompletedEvent.eventType ===
+ WORKFLOW_EVENT_TYPE.WorkflowExecutionContinuedAsNew
+ ) {
return {
to: {
name: 'workflow/summary',
diff --git a/client/routes/workflow/helpers/map-timeline-events.js b/client/routes/workflow/helpers/map-timeline-events.js
index 5d1635a08..d46b832cf 100644
--- a/client/routes/workflow/helpers/map-timeline-events.js
+++ b/client/routes/workflow/helpers/map-timeline-events.js
@@ -1,5 +1,6 @@
import moment from 'moment';
import { summarizeEvents } from './summarize-events';
+import { WORKFLOW_EVENT_TYPE } from '~constants';
import { shortName } from '~helpers';
export default function(historyEvents) {
@@ -51,14 +52,14 @@ export default function(historyEvents) {
} else {
item.eventIds.push(e.eventId);
- if (e.eventType !== 'ActivityTaskStarted') {
+ if (e.eventType !== WORKFLOW_EVENT_TYPE.ActivityTaskStarted) {
Object.assign(item.details, summarizeEvents[e.eventType](e.details));
}
}
if (
- e.eventType !== 'ActivityTaskScheduled' &&
- e.eventType !== 'ActivityTaskStarted'
+ e.eventType !== WORKFLOW_EVENT_TYPE.ActivityTaskScheduled &&
+ e.eventType !== WORKFLOW_EVENT_TYPE.ActivityTaskStarted
) {
assignEnd(item, e.timestamp);
item.className = `activity ${e.eventType
@@ -104,15 +105,16 @@ export default function(historyEvents) {
}
if (
- e.eventType !== 'StartChildWorkflowExecutionInitiated' &&
- e.eventType !== 'ChildWorkflowExecutionStarted'
+ e.eventType !==
+ WORKFLOW_EVENT_TYPE.StartChildWorkflowExecutionInitiated &&
+ e.eventType !== WORKFLOW_EVENT_TYPE.ChildWorkflowExecutionStarted
) {
assignEnd(item, e.timestamp);
item.className = `child-workflow ${e.eventType
.replace('ChildWorkflowExecution', '')
.toLowerCase()}`;
}
- } else if (e.eventType === 'TimerStarted') {
+ } else if (e.eventType === WORKFLOW_EVENT_TYPE.TimerStarted) {
add({
id: `timer${e.details.timerId}`,
className: 'timer',
@@ -126,13 +128,13 @@ export default function(historyEvents) {
.duration(e.details.startToFireTimeoutSeconds, 'seconds')
.format()})`,
});
- } else if (e.eventType === 'TimerFired') {
+ } else if (e.eventType === WORKFLOW_EVENT_TYPE.TimerFired) {
const timerStartedEvent = hash[`timer${e.details.timerId}`];
if (timerStartedEvent) {
timerStartedEvent.eventIds.push(e.eventId);
}
- } else if (e.eventType === 'MarkerRecorded') {
+ } else if (e.eventType === WORKFLOW_EVENT_TYPE.MarkerRecorded) {
const markerName =
e.details.markerName !== undefined
? e.details.markerName.toLowerCase()
@@ -149,9 +151,9 @@ export default function(historyEvents) {
SideEffect: 'Side Effect',
LocalActivity: 'Local Activity',
}[e.details.markerName] || `${e.details.markerName} Marker`,
- details: summarizeEvents.MarkerRecorded(e.details),
+ details: summarizeEvents[WORKFLOW_EVENT_TYPE.MarkerRecorded](e.details),
});
- } else if (e.eventType === 'WorkflowExecutionSignaled') {
+ } else if (e.eventType === WORKFLOW_EVENT_TYPE.WorkflowExecutionSignaled) {
add({
id: `signal${e.eventId}`,
className: 'signal',
@@ -162,18 +164,23 @@ export default function(historyEvents) {
input: e.details.input,
},
});
- } else if (e.eventType === 'SignalExternalWorkflowExecutionInitiated') {
+ } else if (
+ e.eventType ===
+ WORKFLOW_EVENT_TYPE.SignalExternalWorkflowExecutionInitiated
+ ) {
add({
id: `extsignal${e.eventId}`,
className: 'external-signal',
eventIds: [e.eventId],
start: moment(e.timestamp),
content: 'External Workflow Signaled',
- details: summarizeEvents.SignalExternalWorkflowExecutionInitiated(
- e.details
- ),
+ details: summarizeEvents[
+ WORKFLOW_EVENT_TYPE.SignalExternalWorkflowExecutionInitiated
+ ](e.details),
});
- } else if (e.eventType === 'ExternalWorkflowExecutionSignaled') {
+ } else if (
+ e.eventType === WORKFLOW_EVENT_TYPE.ExternalWorkflowExecutionSignaled
+ ) {
const initiatedEvent = hash[`extsignal${e.eventId}`];
if (initiatedEvent) {
@@ -182,8 +189,8 @@ export default function(historyEvents) {
// assignEnd(item, e.timestamp);
}
} else if (
- e.eventType === 'DecisionTaskFailed' ||
- e.eventType === 'DecisionTaskTimedOut'
+ e.eventType === WORKFLOW_EVENT_TYPE.DecisionTaskFailed ||
+ e.eventType === WORKFLOW_EVENT_TYPE.DecisionTaskTimedOut
) {
add({
id: `decision${e.eventId}`,
diff --git a/client/routes/workflow/helpers/summarize-events.js b/client/routes/workflow/helpers/summarize-events.js
index 39f85bb18..400f22dd0 100644
--- a/client/routes/workflow/helpers/summarize-events.js
+++ b/client/routes/workflow/helpers/summarize-events.js
@@ -1,17 +1,20 @@
import moment from 'moment';
import parentWorkflowLink from './parent-workflow-link';
import workflowLink from './workflow-link';
+import { WORKFLOW_EVENT_TYPE } from '~constants';
import { shortName } from '~helpers';
export const summarizeEvents = {
- ActivityTaskCancelRequested: d => ({ ID: d.activityId }),
- ActivityTaskCompleted: d => ({ result: d.result }),
- ActivityTaskCanceled: d => ({}),
- ActivityTaskFailed: d => ({
+ [WORKFLOW_EVENT_TYPE.ActivityTaskCanceled]: d => ({}),
+ [WORKFLOW_EVENT_TYPE.ActivityTaskCancelRequested]: d => ({
+ ID: d.activityId,
+ }),
+ [WORKFLOW_EVENT_TYPE.ActivityTaskCompleted]: d => ({ result: d.result }),
+ [WORKFLOW_EVENT_TYPE.ActivityTaskFailed]: d => ({
details: d.details,
reason: d.reason,
}),
- ActivityTaskScheduled: d => ({
+ [WORKFLOW_EVENT_TYPE.ActivityTaskScheduled]: d => ({
'Close Timeout': moment
.duration(d.scheduleToCloseTimeoutSeconds, 'seconds')
.format(),
@@ -19,30 +22,34 @@ export const summarizeEvents = {
input: d.input,
Name: shortName(d.activityType.name),
}),
- ActivityTaskStarted: d => ({
+ [WORKFLOW_EVENT_TYPE.ActivityTaskStarted]: d => ({
attempt: d.attempt,
identity: d.identity,
requestId: d.requestId,
}),
- ActivityTaskTimedOut: d => ({ 'Timeout Type': d.timeoutType }),
- ChildWorkflowExecutionCompleted: d => ({
+ [WORKFLOW_EVENT_TYPE.ActivityTaskTimedOut]: d => ({
+ 'Timeout Type': d.timeoutType,
+ }),
+ [WORKFLOW_EVENT_TYPE.ChildWorkflowExecutionCompleted]: d => ({
result: d.result,
Workflow: workflowLink(d, true),
}),
- ChildWorkflowExecutionStarted: d => ({
+ [WORKFLOW_EVENT_TYPE.ChildWorkflowExecutionStarted]: d => ({
Workflow: workflowLink(d),
}),
- DecisionTaskCompleted: d => ({ identity: d.identity }),
- DecisionTaskScheduled: d => ({
+ [WORKFLOW_EVENT_TYPE.DecisionTaskCompleted]: d => ({ identity: d.identity }),
+ [WORKFLOW_EVENT_TYPE.DecisionTaskScheduled]: d => ({
Tasklist: d.taskList.name,
Timeout: moment.duration(d.startToCloseTimeoutSeconds, 'seconds').format(),
}),
- DecisionTaskStarted: d => ({ requestId: d.requestId }),
- DecisionTaskTimedOut: d => ({ 'Timeout Type': d.timeoutType }),
- ExternalWorkflowExecutionSignaled: d => ({
+ [WORKFLOW_EVENT_TYPE.DecisionTaskStarted]: d => ({ requestId: d.requestId }),
+ [WORKFLOW_EVENT_TYPE.DecisionTaskTimedOut]: d => ({
+ 'Timeout Type': d.timeoutType,
+ }),
+ [WORKFLOW_EVENT_TYPE.ExternalWorkflowExecutionSignaled]: d => ({
Workflow: workflowLink(d),
}),
- MarkerRecorded: d => {
+ [WORKFLOW_EVENT_TYPE.MarkerRecorded]: d => {
const details = d.details || {};
if (d.markerName === 'LocalActivity') {
@@ -79,23 +86,23 @@ export const summarizeEvents = {
return d;
},
- StartChildWorkflowExecutionInitiated: d => ({
- input: d.input,
- Tasklist: d.taskList.name,
- Workflow: shortName(d.workflowType.name),
- }),
- SignalExternalWorkflowExecutionInitiated: d => ({
+ [WORKFLOW_EVENT_TYPE.SignalExternalWorkflowExecutionInitiated]: d => ({
input: d.input,
signal: d.signalName,
Workflow: workflowLink(d),
}),
- TimerStarted: d => ({
+ [WORKFLOW_EVENT_TYPE.StartChildWorkflowExecutionInitiated]: d => ({
+ input: d.input,
+ Tasklist: d.taskList.name,
+ Workflow: shortName(d.workflowType.name),
+ }),
+ [WORKFLOW_EVENT_TYPE.TimerStarted]: d => ({
'Fire Timeout': moment
.duration(d.startToFireTimeoutSeconds, 'seconds')
.format(),
'Timer ID': d.timerId,
}),
- WorkflowExecutionStarted: d => {
+ [WORKFLOW_EVENT_TYPE.WorkflowExecutionStarted]: d => {
const summary = {
'Close Timeout': moment
.duration(d.executionStartToCloseTimeoutSeconds, 'seconds')
diff --git a/client/routes/workflow/history.vue b/client/routes/workflow/history.vue
index be91d801b..18ef9f1c3 100644
--- a/client/routes/workflow/history.vue
+++ b/client/routes/workflow/history.vue
@@ -147,7 +147,12 @@
"
>
{{ item.eventId }}
-
{{ item.eventType }}
+
+
+
{{
tsFormat === 'elapsed'
@@ -162,8 +167,19 @@
? item.eventSummary
: item.eventFullDetails
"
+ :is-highlight-enabled="
+ compactDetails && !item.expanded
+ ? false
+ : workflowHistoryEventHighlightListEnabled
+ "
:compact="compactDetails && !item.expanded"
- :highlight="events.length < 100"
+ @onWorkflowHistoryEventParamToggle="
+ eventParam =>
+ onWorkflowHistoryEventParamToggle({
+ eventParam,
+ eventType: item.eventType,
+ })
+ "
/>
@@ -201,6 +217,7 @@