diff --git a/packages/contact-center/ui-logging/src/withMetrics.tsx b/packages/contact-center/ui-logging/src/withMetrics.tsx
index 77354d3dd..41da8814f 100644
--- a/packages/contact-center/ui-logging/src/withMetrics.tsx
+++ b/packages/contact-center/ui-logging/src/withMetrics.tsx
@@ -1,9 +1,11 @@
import React, {useEffect, useRef} from 'react';
import {havePropsChanged, logMetrics} from './metricsLogger';
-export default function withMetrics
(Component: any, widgetName: string) {
+export default function withMetrics
(Component: any, widgetName: string, propsToWatch?: string[]) {
return React.memo(
(props: P) => {
+ const prevWatchedPropsRef = useRef | null>(null);
+
useEffect(() => {
logMetrics({
widgetName,
@@ -20,7 +22,25 @@ export default function withMetrics(Component: any, widgetName
};
}, []);
- // TODO: https://jira-eng-sjc12.cisco.com/jira/browse/CAI-6890 PROPS_UPDATED event
+ useEffect(() => {
+ if (!propsToWatch || propsToWatch.length === 0) return;
+
+ const currentWatchedProps: Record = {};
+ for (const key of propsToWatch) {
+ currentWatchedProps[key] = (props as Record)[key];
+ }
+
+ if (prevWatchedPropsRef.current !== null && havePropsChanged(prevWatchedPropsRef.current, currentWatchedProps)) {
+ logMetrics({
+ widgetName,
+ event: 'PROPS_UPDATED',
+ props: currentWatchedProps,
+ timestamp: Date.now(),
+ });
+ }
+
+ prevWatchedPropsRef.current = currentWatchedProps;
+ });
return ;
},
diff --git a/packages/contact-center/ui-logging/tests/withMetrics.test.tsx b/packages/contact-center/ui-logging/tests/withMetrics.test.tsx
index 23ec71691..d86aa91f9 100644
--- a/packages/contact-center/ui-logging/tests/withMetrics.test.tsx
+++ b/packages/contact-center/ui-logging/tests/withMetrics.test.tsx
@@ -102,4 +102,89 @@ describe('withMetrics HOC', () => {
rerender();
expect(renderSpy).toHaveBeenCalledTimes(2);
});
+
+ describe('PROPS_UPDATED event', () => {
+ it('should log PROPS_UPDATED when watched props change', () => {
+ const mockTime = 1234567890;
+ jest.setSystemTime(mockTime);
+
+ const WrappedWithWatch = withMetrics(TestComponent, 'TestWidget', ['name']);
+
+ const {rerender} = render();
+ logMetricsSpy.mockClear();
+
+ rerender();
+
+ expect(logMetricsSpy).toHaveBeenCalledWith({
+ widgetName: 'TestWidget',
+ event: 'PROPS_UPDATED',
+ props: {name: 'updated'},
+ timestamp: mockTime,
+ });
+ });
+
+ it('should not log PROPS_UPDATED when only unwatched props change', () => {
+ const mockTime = 1234567890;
+ jest.setSystemTime(mockTime);
+
+ const WrappedWithWatch = withMetrics(TestComponent, 'TestWidget', ['name']);
+
+ const {rerender} = render();
+ logMetricsSpy.mockClear();
+
+ rerender();
+
+ expect(logMetricsSpy).not.toHaveBeenCalledWith(
+ expect.objectContaining({event: 'PROPS_UPDATED'})
+ );
+ });
+
+ it('should not log PROPS_UPDATED when no propsToWatch is provided', () => {
+ const mockTime = 1234567890;
+ jest.setSystemTime(mockTime);
+
+ const WrappedNoWatch = withMetrics(TestComponent, 'TestWidget');
+
+ const {rerender} = render();
+ logMetricsSpy.mockClear();
+
+ rerender();
+
+ expect(logMetricsSpy).not.toHaveBeenCalledWith(
+ expect.objectContaining({event: 'PROPS_UPDATED'})
+ );
+ });
+
+ it('should not log PROPS_UPDATED on initial render', () => {
+ const mockTime = 1234567890;
+ jest.setSystemTime(mockTime);
+
+ const WrappedWithWatch = withMetrics(TestComponent, 'TestWidget', ['name']);
+
+ render();
+
+ expect(logMetricsSpy).not.toHaveBeenCalledWith(
+ expect.objectContaining({event: 'PROPS_UPDATED'})
+ );
+ });
+
+ it('should only include watched props in the log payload', () => {
+ const mockTime = 1234567890;
+ jest.setSystemTime(mockTime);
+
+ const WrappedWithWatch = withMetrics(TestComponent, 'TestWidget', ['name']);
+
+ const {rerender} = render();
+ logMetricsSpy.mockClear();
+
+ rerender();
+
+ const propsUpdatedCall = logMetricsSpy.mock.calls.find(
+ (call) => call[0].event === 'PROPS_UPDATED'
+ );
+ expect(propsUpdatedCall).toBeDefined();
+ expect(propsUpdatedCall[0].props).toEqual({name: 'updated'});
+ expect(propsUpdatedCall[0].props).not.toHaveProperty('otherProp');
+ });
+ });
});