diff --git a/chat-widget/.eslintrc.json b/chat-widget/.eslintrc.json index 3f6b24058..499a662be 100644 --- a/chat-widget/.eslintrc.json +++ b/chat-widget/.eslintrc.json @@ -23,6 +23,11 @@ "react", "@typescript-eslint" ], + "settings": { + "react": { + "version": "detect" + } + }, "rules": { "indent": [ "error", diff --git a/chat-widget/package.json b/chat-widget/package.json index 8b1fbf5d5..96fb857d7 100644 --- a/chat-widget/package.json +++ b/chat-widget/package.json @@ -6,8 +6,7 @@ "types": "lib/types/index.d.ts", "repository": "https://github.com/microsoft/omnichannel-chat-widget", "author": "Microsoft", - "license": "MIT", - "type": "module", + "license": "ISC", "files": [ "lib" ], @@ -22,8 +21,8 @@ "devDependencies": { "@babel/core": "^7.15.8", "@babel/preset-env": "^7.15.8", - "@babel/preset-react": "^7.14.5", - "@babel/preset-typescript": "^7.15.0", + "@babel/preset-react": "^7.24.7", + "@babel/preset-typescript": "^7.24.7", "@storybook/addon-a11y": "^6.4.8", "@storybook/addon-actions": "^6.4.8", "@storybook/addon-essentials": "^6.4.8", @@ -39,13 +38,13 @@ "@types/jest": "^27.0.2", "@types/jest-image-snapshot": "^4.3.1", "@types/markdown-it": "^12.2.3", - "@types/react": "^17.0.30", - "@types/react-dom": "^17.0.10", + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", "@types/styled-components": "^5.1.15", "@typescript-eslint/eslint-plugin": "^5.3.0", "@typescript-eslint/parser": "^5.2.0", "babel-jest": "^27.3.1", - "babel-loader": "^8.2.3", + "babel-loader": "^9.1.0", "botframework-directlinejs": "^0.15.0", "copyfiles": "^2.4.1", "eslint": "^7.32.0", @@ -62,16 +61,22 @@ "json": "^11.0.0", "playwright": "^1.16.3", "postcss": "^8.3.9", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-test-renderer": "^17.0.2", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-test-renderer": "^18.3.1", "storybook-addon-playwright": "^4.9.2", "swiper": "^9.0.5", - "terser-webpack-plugin": "^4.2.3", - "ts-loader": "^9.2.6", - "typescript": "4.6.4", - "webpack": "^4.44.2", - "webpack-cli": "^4.9.2" + "terser-webpack-plugin": "^5.3.10", + "ts-loader": "^9.5.1", + "typescript": "5.5.4", + "webpack": "^5.94.0", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^5.1.0", + "clean-webpack-plugin": "^4.0.0", + "crypto-browserify": "^3.12.0", + "stream-browserify": "^3.0.0", + "thread-loader": "^4.0.4", + "fork-ts-checker-webpack-plugin": "^9.0.2" }, "dependencies": { "@microsoft/omnichannel-chat-components": "1.1.5", diff --git a/chat-widget/samples/javascript-sample/Common/MemoryDataStore.js b/chat-widget/samples/javascript-sample/Common/MemoryDataStore.js index 78f8d715f..6d776f044 100644 --- a/chat-widget/samples/javascript-sample/Common/MemoryDataStore.js +++ b/chat-widget/samples/javascript-sample/Common/MemoryDataStore.js @@ -1,4 +1,4 @@ -import { Constants } from "./Constants"; +import { Constants } from "./Constants.js"; export const memoryDataStore = () => { var internalCache = {}; diff --git a/chat-widget/samples/javascript-sample/Common/clientDataStoreProvider.js b/chat-widget/samples/javascript-sample/Common/clientDataStoreProvider.js index 5fcaaa3bc..f78b832d8 100644 --- a/chat-widget/samples/javascript-sample/Common/clientDataStoreProvider.js +++ b/chat-widget/samples/javascript-sample/Common/clientDataStoreProvider.js @@ -1,5 +1,5 @@ -import { Constants } from "./Constants"; -import { memoryDataStore } from "./MemoryDataStore"; +import { Constants } from "./Constants.js"; +import { memoryDataStore } from "./MemoryDataStore.js"; export const clientDataStoreProvider = () => { const _memoryDataStore = memoryDataStore(); diff --git a/chat-widget/samples/javascript-sample/SampleWidget.js b/chat-widget/samples/javascript-sample/SampleWidget.js index d4d478562..ba5ee1a40 100644 --- a/chat-widget/samples/javascript-sample/SampleWidget.js +++ b/chat-widget/samples/javascript-sample/SampleWidget.js @@ -2,7 +2,7 @@ import * as React from "react"; -import { getUnreadMessageCount, registerVisibilityListener } from "./getUnreadMessageCount"; +import { getUnreadMessageCount, registerVisibilityListener } from "./getUnreadMessageCount.js"; import { BroadcastService } from "../../lib/esm/index.js"; import LiveChatWidget from "../../lib/esm/components/livechatwidget/LiveChatWidget.js"; @@ -11,9 +11,9 @@ import ReactDOM from "react-dom"; import { version as chatComponentVersion } from "@microsoft/omnichannel-chat-components/package.json"; import { version as chatSdkVersion } from "@microsoft/omnichannel-chat-sdk/package.json"; import { version as chatWidgetVersion } from "../../package.json"; -import { getCustomizationJson } from "./getCustomizationJson"; -import { memoryDataStore } from "./Common/MemoryDataStore"; -import getMockChatSDKIfApplicable from "./getMockChatSDKIfApplicable"; +import { getCustomizationJson } from "./getCustomizationJson.js"; +import { memoryDataStore } from "./Common/MemoryDataStore.js"; +import getMockChatSDKIfApplicable from "./getMockChatSDKIfApplicable.js"; let liveChatWidgetProps; diff --git a/chat-widget/samples/javascript-sample/cacheWidgetState.js b/chat-widget/samples/javascript-sample/cacheWidgetState.js index 48def0bb8..ba9201c9c 100644 --- a/chat-widget/samples/javascript-sample/cacheWidgetState.js +++ b/chat-widget/samples/javascript-sample/cacheWidgetState.js @@ -1,6 +1,6 @@ import { BroadcastService } from "@microsoft/omnichannel-chat-components"; -import { clientDataStoreProvider } from "./Common/clientDataStoreProvider"; -import { Constants } from "./Common/Constants"; +import { clientDataStoreProvider } from "./Common/clientDataStoreProvider.js"; +import { Constants } from "./Common/Constants.js"; export const registerCacheWidgetStateEvent = async () => { BroadcastService.getMessageByEventName(Constants.WidgetStateChangedEventName).subscribe((msg) => { diff --git a/chat-widget/samples/javascript-sample/test.html b/chat-widget/samples/javascript-sample/test.html index 06db36239..003ab82c8 100644 --- a/chat-widget/samples/javascript-sample/test.html +++ b/chat-widget/samples/javascript-sample/test.html @@ -67,8 +67,14 @@ }
- + \ No newline at end of file diff --git a/chat-widget/src/components/callingcontainerstateful/CallingContainerStateful.tsx b/chat-widget/src/components/callingcontainerstateful/CallingContainerStateful.tsx index 6b24cfd4a..6ebbdea4b 100644 --- a/chat-widget/src/components/callingcontainerstateful/CallingContainerStateful.tsx +++ b/chat-widget/src/components/callingcontainerstateful/CallingContainerStateful.tsx @@ -1,7 +1,6 @@ import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants"; -import React, { Dispatch, useCallback, useEffect } from "react"; +import React, { Dispatch, Suspense, lazy, useCallback, useEffect } from "react"; -import { CallingContainer } from "@microsoft/omnichannel-chat-components"; import { ICallingContainerControlProps } from "@microsoft/omnichannel-chat-components/lib/types/components/callingcontainer/interfaces/ICallingContainerControlProps"; import { ICallingContainerStatefulProps } from "./ICallingContainerStatefulProps"; import { ILiveChatWidgetAction } from "../../contexts/common/ILiveChatWidgetAction"; @@ -13,7 +12,7 @@ import useChatSDKStore from "../../hooks/useChatSDKStore"; export const CallingContainerStateful = (props: ICallingContainerStatefulProps) => { - //TODO : Close button confirmation implmentation is pending + const CallingContainer = lazy(() => import(/* webpackChunkName: "CallingContainer" */ "@microsoft/omnichannel-chat-components").then(module => ({ default: module.CallingContainer }))); const [state, dispatch]: [ILiveChatWidgetContext, Dispatch] = useChatContextStore(); // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -281,7 +280,9 @@ export const CallingContainerStateful = (props: ICallingContainerStatefulProps) return ( <> {state.uiStates.showCallingPopup && - + Loading...}> + + } ); diff --git a/chat-widget/src/components/chatbuttonstateful/ChatButtonStateful.tsx b/chat-widget/src/components/chatbuttonstateful/ChatButtonStateful.tsx index 31c975f92..475583358 100644 --- a/chat-widget/src/components/chatbuttonstateful/ChatButtonStateful.tsx +++ b/chat-widget/src/components/chatbuttonstateful/ChatButtonStateful.tsx @@ -1,7 +1,6 @@ import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants"; -import React, { Dispatch, useEffect, useRef, useState } from "react"; +import React, { Dispatch, Suspense, lazy, useEffect, useRef, useState } from "react"; -import { ChatButton } from "@microsoft/omnichannel-chat-components"; import { Constants } from "../../common/Constants"; import { ConversationState } from "../../contexts/common/ConversationState"; import { IChatButtonControlProps } from "@microsoft/omnichannel-chat-components/lib/types/components/chatbutton/interfaces/IChatButtonControlProps"; @@ -18,6 +17,9 @@ import useChatContextStore from "../../hooks/useChatContextStore"; export const ChatButtonStateful = (props: IChatButtonStatefulParams) => { + const ChatButton = lazy(() => import(/* webpackChunkName: "ChatButton" */ "@microsoft/omnichannel-chat-components").then((module) => ({ default: module.ChatButton }))); + + const [state, dispatch]: [ILiveChatWidgetContext, Dispatch] = useChatContextStore(); const { buttonProps, outOfOfficeButtonProps, startChat } = props; //Setting OutOfOperatingHours Flag @@ -88,11 +90,13 @@ export const ChatButtonStateful = (props: IChatButtonStatefulParams) => { }, []); return ( - + Loading..}> + + ); }; diff --git a/chat-widget/src/components/confirmationpanestateful/ConfirmationPaneStateful.tsx b/chat-widget/src/components/confirmationpanestateful/ConfirmationPaneStateful.tsx index cb9125914..0d9236fd9 100644 --- a/chat-widget/src/components/confirmationpanestateful/ConfirmationPaneStateful.tsx +++ b/chat-widget/src/components/confirmationpanestateful/ConfirmationPaneStateful.tsx @@ -1,8 +1,8 @@ import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants"; -import { ConfirmationPane } from "@microsoft/omnichannel-chat-components"; -import React, { Dispatch, useEffect } from "react"; +import React, { Dispatch, Suspense, lazy, useEffect } from "react"; import { findAllFocusableElement, findParentFocusableElementsWithoutChildContainer, preventFocusToMoveOutOfElement, setFocusOnElement, setFocusOnSendBox, setTabIndices } from "../../common/utils"; -import { DimLayer } from "../dimlayer/DimLayer"; + +import { ConfirmationState } from "../../common/Constants"; import { IConfirmationPaneControlProps } from "@microsoft/omnichannel-chat-components/lib/types/components/confirmationpane/interfaces/IConfirmationPaneControlProps"; import { IConfirmationPaneStatefulParams } from "./interfaces/IConfirmationPaneStatefulParams"; import { ILiveChatWidgetAction } from "../../contexts/common/ILiveChatWidgetAction"; @@ -10,11 +10,13 @@ import { ILiveChatWidgetContext } from "../../contexts/common/ILiveChatWidgetCon import { LiveChatWidgetActionType } from "../../contexts/common/LiveChatWidgetActionType"; import { TelemetryHelper } from "../../common/telemetry/TelemetryHelper"; import useChatContextStore from "../../hooks/useChatContextStore"; -import { ConfirmationState } from "../../common/Constants"; // eslint-disable-next-line @typescript-eslint/no-explicit-any export const ConfirmationPaneStateful = (props: IConfirmationPaneStatefulParams) => { + const ConfirmationPane = lazy(() => import(/* webpackChunkName: "ConfirmationPane" */ "@microsoft/omnichannel-chat-components").then(module => ({ default: module.ConfirmationPane }))); + const DimLayer = lazy(() => import(/* webpackChunkName: "DimLayer" */ "../dimlayer/DimLayer").then(module => ({ default: module.DimLayer }))); + const initialTabIndexMap: Map = new Map(); let elements: HTMLElement[] | null = []; @@ -72,11 +74,13 @@ export const ConfirmationPaneStateful = (props: IConfirmationPaneStatefulParams) return ( <> - - + Loading..}> + + + ); }; diff --git a/chat-widget/src/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.tsx b/chat-widget/src/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.tsx index 36311cc02..fd747a35e 100644 --- a/chat-widget/src/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.tsx +++ b/chat-widget/src/components/emailtranscriptpanestateful/EmailTranscriptPaneStateful.tsx @@ -1,5 +1,5 @@ import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants"; -import React, { Dispatch, useCallback, useEffect, useState } from "react"; +import React, { Dispatch, Suspense, lazy, useCallback, useEffect, useState } from "react"; import { findAllFocusableElement, findParentFocusableElementsWithoutChildContainer, formatTemplateString, preventFocusToMoveOutOfElement, setFocusOnElement, setFocusOnSendBox, setTabIndices } from "../../common/utils"; import { DimLayer } from "../dimlayer/DimLayer"; @@ -8,17 +8,19 @@ import { IEmailTranscriptPaneProps } from "./interfaces/IEmailTranscriptPaneProp import { IInputValidationPaneControlProps } from "@microsoft/omnichannel-chat-components/lib/types/components/inputvalidationpane/interfaces/IInputValidationPaneControlProps"; import { ILiveChatWidgetAction } from "../../contexts/common/ILiveChatWidgetAction"; import { ILiveChatWidgetContext } from "../../contexts/common/ILiveChatWidgetContext"; -import { InputValidationPane } from "@microsoft/omnichannel-chat-components"; import { LiveChatWidgetActionType } from "../../contexts/common/LiveChatWidgetActionType"; import { NotificationHandler } from "../webchatcontainerstateful/webchatcontroller/notification/NotificationHandler"; import { NotificationScenarios } from "../webchatcontainerstateful/webchatcontroller/enums/NotificationScenarios"; import { Regex } from "../../common/Constants"; import { TelemetryHelper } from "../../common/telemetry/TelemetryHelper"; +import { defaultMiddlewareLocalizedTexts } from "../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts"; import useChatContextStore from "../../hooks/useChatContextStore"; import useChatSDKStore from "../../hooks/useChatSDKStore"; -import { defaultMiddlewareLocalizedTexts } from "../webchatcontainerstateful/common/defaultProps/defaultMiddlewareLocalizedTexts"; export const EmailTranscriptPaneStateful = (props: IEmailTranscriptPaneProps) => { + + const InputValidationPane = lazy(() => import(/* webpackChunkName: "InputValidationPane" */ "@microsoft/omnichannel-chat-components").then(module => ({ default: module.InputValidationPane }))); + const initialTabIndexMap: Map = new Map(); let elements: HTMLElement[] | null = []; const [state, dispatch]: [ILiveChatWidgetContext, Dispatch] = useChatContextStore(); @@ -96,10 +98,12 @@ export const EmailTranscriptPaneStateful = (props: IEmailTranscriptPaneProps) => return ( <> - + Loading..}> + + ); }; diff --git a/chat-widget/src/components/footerstateful/FooterStateful.tsx b/chat-widget/src/components/footerstateful/FooterStateful.tsx index 346b14e0b..7a6fba865 100644 --- a/chat-widget/src/components/footerstateful/FooterStateful.tsx +++ b/chat-widget/src/components/footerstateful/FooterStateful.tsx @@ -1,9 +1,7 @@ import { LogLevel, TelemetryEvent } from "../../common/telemetry/TelemetryConstants"; -import React, { Dispatch } from "react"; +import React, { Dispatch, Suspense, lazy } from "react"; -import AudioNotificationStateful from "./audionotificationstateful/AudioNotificationStateful"; import { Constants } from "../../common/Constants"; -import { Footer } from "@microsoft/omnichannel-chat-components"; import { IFooterControlProps } from "@microsoft/omnichannel-chat-components/lib/types/components/footer/interfaces/IFooterControlProps"; import { ILiveChatWidgetAction } from "../../contexts/common/ILiveChatWidgetAction"; import { ILiveChatWidgetContext } from "../../contexts/common/ILiveChatWidgetContext"; @@ -19,6 +17,8 @@ import useChatSDKStore from "../../hooks/useChatSDKStore"; // eslint-disable-next-line @typescript-eslint/no-explicit-any export const FooterStateful = (props: any) => { const [state, dispatch]: [ILiveChatWidgetContext, Dispatch] = useChatContextStore(); + const AudioNotificationStateful = lazy(() => import(/* webpackChunkName: "AudioNotificationStateful" */ "./audionotificationstateful/AudioNotificationStateful").then(module => ({ default: module.AudioNotificationStateful }))); + const Footer = lazy(() => import(/* webpackChunkName: "Footer" */ "@microsoft/omnichannel-chat-components").then(module => ({ default: module.Footer }))); // hideFooterDisplay - the purpose of this is to keep the footer always "active", // but hide it visually in certain states (e.g., loading state) and show in some other states (e.g. active state). // The reason for this approach is to make sure that state variables for audio notification work correctly after minimizing @@ -66,18 +66,23 @@ export const FooterStateful = (props: any) => { return ( <> {!hideFooterDisplay && -