diff --git a/package.json b/package.json
index 25eb44e2..5bc809c4 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "th2-rpt-viewer",
- "version": "5.1.28",
+ "version": "5.1.29",
"description": "",
"main": "index.tsx",
"private": true,
diff --git a/src/components/message/message-card/MessageBodyCard.tsx b/src/components/message/message-card/MessageBodyCard.tsx
index 4cb45e2c..39d48a0f 100644
--- a/src/components/message/message-card/MessageBodyCard.tsx
+++ b/src/components/message/message-card/MessageBodyCard.tsx
@@ -26,16 +26,20 @@ import MessageBody, {
isMessageValue,
isNullValue,
} from '../../../models/MessageBody';
+import { HighlightColorManager } from '../../../helpers/highlightUtils';
const BEAUTIFIED_PAD_VALUE = 15;
const DEFAULT_HIGHLIGHT_COLOR = '#e2dfdf';
const SELECTED_HIGHLIGHT_COLOR = '#fff';
+const highlightColorManager = new HighlightColorManager();
+
interface Props {
isBeautified: boolean;
body: MessageBody | null;
isSelected: boolean;
sortOrderItems: string[];
+ filterBodyValues: string[] | undefined;
}
const getSortedFields = (fields: MessageBodyFields, sortOrder: string[]) => {
@@ -64,7 +68,13 @@ const getSortedFields = (fields: MessageBodyFields, sortOrder: string[]) => {
return [...primarySortedFields, ...secondarySortedFields, ...tertiarySortedFields];
};
-function MessageBodyCard({ isBeautified, body, isSelected, sortOrderItems }: Props) {
+function MessageBodyCard({
+ isBeautified,
+ body,
+ isSelected,
+ sortOrderItems,
+ filterBodyValues,
+}: Props) {
const [areSameContext, highlightSameContext] = React.useState(false);
const fields = React.useMemo(
@@ -93,6 +103,7 @@ function MessageBodyCard({ isBeautified, body, isSelected, sortOrderItems }: Pro
field={value}
isBeautified={isBeautified}
setIsHighlighted={highlightSameContext}
+ filterBodyValues={filterBodyValues}
/>
{isBeautified || idx === arr.length - 1 ? null : ', '}
@@ -116,6 +127,7 @@ interface FieldProps {
highlightColor: string;
primarySort: string[];
renderInfo?: () => React.ReactNode;
+ filterBodyValues: string[] | undefined;
}
function MessageBodyCardField(props: FieldProps) {
@@ -127,12 +139,23 @@ function MessageBodyCardField(props: FieldProps) {
isRoot = true,
setIsHighlighted,
highlightColor,
+ filterBodyValues,
} = props;
const [areSameContext, highlightSameContext] = React.useState(false);
const highlight = React.useMemo(() => debounce(() => setIsHighlighted(true), 60), []);
+ const fieldColor = React.useMemo(() => {
+ if (!isSimpleValue(field)) {
+ return '';
+ }
+ if (filterBodyValues?.some(filter => field?.simpleValue?.includes(filter) || false)) {
+ return highlightColorManager.getHighlightColor(field.simpleValue);
+ }
+ return '';
+ }, [filterBodyValues]);
+
const removeHighlight = React.useCallback(() => {
highlight.cancel();
setIsHighlighted(false);
@@ -148,6 +171,7 @@ function MessageBodyCardField(props: FieldProps) {
label={label}
isRoot={false}
setIsHighlighted={setIsHighlighted}
+ filterBodyValues={filterBodyValues}
/>
);
}
@@ -165,6 +189,7 @@ function MessageBodyCardField(props: FieldProps) {
className='mc-body__field'
style={{
display: isBeautified ? 'block' : undefined,
+ backgroundColor: fieldColor,
}}>
{isBeautified || idx === arr.length - 1 ? null : ', '}
@@ -251,6 +277,7 @@ function MessageBodyCardField(props: FieldProps) {
isRoot={false}
setIsHighlighted={highlightSameContext}
highlightColor={highlightColor}
+ filterBodyValues={filterBodyValues}
/>
{isBeautified || idx === arr.length - 1 ? null : ', '}
diff --git a/src/components/message/message-card/MessageCard.tsx b/src/components/message/message-card/MessageCard.tsx
index 01d69ddb..b1823c94 100644
--- a/src/components/message/message-card/MessageCard.tsx
+++ b/src/components/message/message-card/MessageCard.tsx
@@ -44,6 +44,7 @@ const MessageCard = observer(({ message, viewType, setViewType }: Props) => {
const { messageId } = message;
const messagesStore = useMessagesWorkspaceStore();
+ const { filterStore } = messagesStore;
const messagesDataStore = useMessagesDataStore();
const bookmarksStore = useBookmarksStore();
const { sortOrderItems } = useMessageBodySortStore();
@@ -51,6 +52,8 @@ const MessageCard = observer(({ message, viewType, setViewType }: Props) => {
const [isHighlighted, setHighlighted] = React.useState(false);
+ const [filterBodyValues, setFilterBodyValues] = React.useState();
+
const hoverTimeout = React.useRef();
const isContentBeautified = viewType === MessageViewType.FORMATTED;
@@ -60,6 +63,12 @@ const MessageCard = observer(({ message, viewType, setViewType }: Props) => {
const isSoftFiltered = messagesDataStore.isSoftFiltered.get(messageId);
+ React.useEffect(() => {
+ if (filterStore.isMessagesFilterApplied) {
+ setFilterBodyValues(filterStore.filterParams['body-values']);
+ }
+ }, [filterStore.isMessagesFilterApplied]);
+
React.useEffect(() => {
const abortController = new AbortController();
@@ -113,6 +122,7 @@ const MessageCard = observer(({ message, viewType, setViewType }: Props) => {
viewType={viewType}
setViewType={setViewType}
isHighlighted={isHighlighted}
+ filterBodyValues={filterBodyValues}
hoverMessage={hoverMessage}
unhoverMessage={unhoverMessage}
isBookmarked={isBookmarked}
diff --git a/src/components/message/message-card/MessageCardBase.tsx b/src/components/message/message-card/MessageCardBase.tsx
index 03cc374b..7347ac18 100644
--- a/src/components/message/message-card/MessageCardBase.tsx
+++ b/src/components/message/message-card/MessageCardBase.tsx
@@ -39,6 +39,7 @@ export interface MessageCardBaseProps {
isExported?: boolean;
isExport?: boolean;
sortOrderItems?: string[];
+ filterBodyValues?: string[] | undefined;
viewType: MessageViewType;
setViewType: (viewType: MessageViewType) => void;
addMessageToExport?: () => void;
@@ -61,6 +62,7 @@ const MessageCardBase = React.memo(
isExport,
sortOrderItems,
addMessageToExport,
+ filterBodyValues,
}: MessageCardBaseProps) => {
const { messageId, bodyBase64, body } = message;
@@ -90,6 +92,7 @@ const MessageCardBase = React.memo(
rawContent: bodyBase64,
isSelected: isAttached || false,
sortOrderItems: sortOrderItems || [],
+ filterBodyValues,
};
const messageCardToolsConfig: MessageCardToolsConfig = {
diff --git a/src/components/message/message-card/MessageCardViewTypeRenderer.tsx b/src/components/message/message-card/MessageCardViewTypeRenderer.tsx
index cf4314b2..1ef64f93 100644
--- a/src/components/message/message-card/MessageCardViewTypeRenderer.tsx
+++ b/src/components/message/message-card/MessageCardViewTypeRenderer.tsx
@@ -32,6 +32,7 @@ export type MessageCardViewTypeRendererProps = {
isEmbedded?: boolean;
isDetailed?: boolean;
sortOrderItems: string[];
+ filterBodyValues: string[] | undefined;
};
const MessageCardViewTypeRenderer = ({
@@ -41,6 +42,7 @@ const MessageCardViewTypeRenderer = ({
isSelected,
messageBody,
sortOrderItems,
+ filterBodyValues,
}: MessageCardViewTypeRendererProps) => {
switch (viewType) {
case MessageViewType.FORMATTED:
@@ -53,6 +55,7 @@ const MessageCardViewTypeRenderer = ({
isSelected={isSelected}
body={messageBody}
sortOrderItems={sortOrderItems}
+ filterBodyValues={filterBodyValues}
/>
}>
);
diff --git a/src/helpers/highlightUtils.ts b/src/helpers/highlightUtils.ts
new file mode 100644
index 00000000..ed99d1eb
--- /dev/null
+++ b/src/helpers/highlightUtils.ts
@@ -0,0 +1,46 @@
+/** ****************************************************************************
+ * Copyright 2020-2020 Exactpro (Exactpro Systems Limited)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ***************************************************************************** */
+
+export function randomHighlightColor(alpha = 0.5): string {
+ const r = Math.floor(Math.random() * 150 + 50);
+ const g = Math.floor(Math.random() * 150 + 50);
+ const b = Math.floor(Math.random() * 150 + 50);
+ return `rgba(${r},${g},${b},${alpha})`;
+}
+
+export class HighlightColorManager {
+ private predefinedColors: string[] = [
+ 'rgba(255, 0, 0, 0.5)',
+ 'rgba(0, 255, 0, 0.5)',
+ 'rgba(0, 255, 255, 0.5)',
+ 'rgba(255, 255, 0, 0.5)',
+ 'rgba(255, 0, 255, 0.5)',
+ ];
+
+ private colorMap: Map = new Map();
+
+ public getHighlightColor(value: string): string {
+ const color = this.colorMap.get(value);
+ if (color) {
+ return color;
+ }
+
+ const newColor = this.predefinedColors.pop() || randomHighlightColor();
+
+ this.colorMap.set(value, newColor);
+ return newColor;
+ }
+}