diff --git a/.example.env b/.example.env index dd4a8865878..127db15e710 100644 --- a/.example.env +++ b/.example.env @@ -69,7 +69,6 @@ REACT_STILL_WATCHING_PROMPT_DURATION= # Feature flags REACT_ENABLE_HCX=true REACT_ENABLE_ABDM=true -REACT_ENABLE_SCRIBE=true REACT_WARTIME_SHIFTING=true # JWT token refresh interval (in milliseconds) (default: 5 minutes) diff --git a/care.config.ts b/care.config.ts index 4341a03dd48..e3effeca1b0 100644 --- a/care.config.ts +++ b/care.config.ts @@ -103,10 +103,6 @@ const careConfig = { abdm: { enabled: (env.REACT_ENABLE_ABDM ?? "true") === "true", }, - - scribe: { - enabled: env.REACT_ENABLE_SCRIBE === "true", - }, } as const; export default careConfig; diff --git a/package-lock.json b/package-lock.json index 051c12bd2b4..5bb1a8b35e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@headlessui/react": "^2.1.2", "@pnotify/core": "^5.2.0", "@pnotify/mobile": "^5.2.0", - "@sentry/browser": "^8.29.0", + "@sentry/browser": "^8.33.0", "@yudiel/react-qr-scanner": "^2.0.0-beta.3", "axios": "^1.7.7", "bowser": "^2.11.0", @@ -3765,178 +3765,178 @@ ] }, "node_modules/@sentry-internal/browser-utils": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.29.0.tgz", - "integrity": "sha512-6HpyQkaqPvK6Lnigjlarq/LDYgXT2OBNf24RK7z0ipJSxSIpmtelfzHbnwWYnypNDXfTDdPm97fZEenQHryYJA==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.33.0.tgz", + "integrity": "sha512-zwjmD+XI3pgxxiqKGLXYDGSd+zfO7az9zzbLn1le8Vv9cRL2lZyMLcwiwEaTpwz3B0pPONeDZMT8+bzMGRs8zw==", "dependencies": { - "@sentry/core": "8.29.0", - "@sentry/types": "8.29.0", - "@sentry/utils": "8.29.0" + "@sentry/core": "8.33.0", + "@sentry/types": "8.33.0", + "@sentry/utils": "8.33.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/browser-utils/node_modules/@sentry/core": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.29.0.tgz", - "integrity": "sha512-scMbZaJ0Ov8NPgWn86EdjhyTLrhvRVbTxjg0imJAvhIvRbblH3xyqye/17Qnk2fOp8TNDOl7TBZHi0NCFQ5HUw==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.33.0.tgz", + "integrity": "sha512-618PQGHQLBVCpAq1s+e/rpIUaLUnj19IPUgn97rUGXLLna8ETIAoyQoG70wz4q9niw4Z4GlS5kZNrael2O3+2w==", "dependencies": { - "@sentry/types": "8.29.0", - "@sentry/utils": "8.29.0" + "@sentry/types": "8.33.0", + "@sentry/utils": "8.33.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/browser-utils/node_modules/@sentry/types": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.29.0.tgz", - "integrity": "sha512-j4gX3ctzgD4xVWllXAhm6M+kHFEvrFoUPFq60X/pgkjsWCocGuhtNfB0rW43ICG8hCnlz8IYl7O7b8V8qY7SPg==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.33.0.tgz", + "integrity": "sha512-V/A+72ZdnfGtXeXIpz1kUo3LRdq3WKEYYFUR2RKpCdPh9yeOrHq6u/rmzTWx49+om0yhZN+JhVoxDzt75UoFRg==", "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/browser-utils/node_modules/@sentry/utils": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.29.0.tgz", - "integrity": "sha512-nb93/m3SjQChQJFqJj3oNW3Rz/12yrT7jypTCire3c2hpYWG2uR5n8VY9UUMTA6HLNvdom6tckK7p3bXGXlF0w==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.33.0.tgz", + "integrity": "sha512-TdwtGdevJij2wq2x/hDUr+x5TXt47ZhWxZ8zluai/lnIDTUB3Xs/L9yHtj1J+H9hr8obkMASE9IanUrWXzrP6Q==", "dependencies": { - "@sentry/types": "8.29.0" + "@sentry/types": "8.33.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/feedback": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.29.0.tgz", - "integrity": "sha512-yAL5YMEFk4XaeVRUGEguydahRzaQrNPAaWRv6k+XRzCv9CGBhxb14KXQc9X/penlauMFcDfgelCPKcTqcf6wDw==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.33.0.tgz", + "integrity": "sha512-KSW/aiNgmJc8PDl2NsM+ONvGure4tPaluj7O1Nw+947Dh8W6CJnQ9srB7xPyoYYWyQW8Hyl1vzxY9W0J+fjlhA==", "dependencies": { - "@sentry/core": "8.29.0", - "@sentry/types": "8.29.0", - "@sentry/utils": "8.29.0" + "@sentry/core": "8.33.0", + "@sentry/types": "8.33.0", + "@sentry/utils": "8.33.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/feedback/node_modules/@sentry/core": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.29.0.tgz", - "integrity": "sha512-scMbZaJ0Ov8NPgWn86EdjhyTLrhvRVbTxjg0imJAvhIvRbblH3xyqye/17Qnk2fOp8TNDOl7TBZHi0NCFQ5HUw==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.33.0.tgz", + "integrity": "sha512-618PQGHQLBVCpAq1s+e/rpIUaLUnj19IPUgn97rUGXLLna8ETIAoyQoG70wz4q9niw4Z4GlS5kZNrael2O3+2w==", "dependencies": { - "@sentry/types": "8.29.0", - "@sentry/utils": "8.29.0" + "@sentry/types": "8.33.0", + "@sentry/utils": "8.33.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/feedback/node_modules/@sentry/types": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.29.0.tgz", - "integrity": "sha512-j4gX3ctzgD4xVWllXAhm6M+kHFEvrFoUPFq60X/pgkjsWCocGuhtNfB0rW43ICG8hCnlz8IYl7O7b8V8qY7SPg==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.33.0.tgz", + "integrity": "sha512-V/A+72ZdnfGtXeXIpz1kUo3LRdq3WKEYYFUR2RKpCdPh9yeOrHq6u/rmzTWx49+om0yhZN+JhVoxDzt75UoFRg==", "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/feedback/node_modules/@sentry/utils": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.29.0.tgz", - "integrity": "sha512-nb93/m3SjQChQJFqJj3oNW3Rz/12yrT7jypTCire3c2hpYWG2uR5n8VY9UUMTA6HLNvdom6tckK7p3bXGXlF0w==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.33.0.tgz", + "integrity": "sha512-TdwtGdevJij2wq2x/hDUr+x5TXt47ZhWxZ8zluai/lnIDTUB3Xs/L9yHtj1J+H9hr8obkMASE9IanUrWXzrP6Q==", "dependencies": { - "@sentry/types": "8.29.0" + "@sentry/types": "8.33.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.29.0.tgz", - "integrity": "sha512-Xgv/eYucsm7GaGKms2ClQ02NpD07MxjoTjp1/vYZm0H4Q08dVphVZrQp7hL1oX/VD9mb5SFyyKuuIRqIu7S8RA==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.33.0.tgz", + "integrity": "sha512-GFBaDA4yhlEf3wTXOVXnJVG/diuKxeqZuXcuhsAwJb+YcFR0NhgsRn3wIGuYOZZF8GBXzx9PFnb9yIuFgx5Nbw==", "dependencies": { - "@sentry-internal/browser-utils": "8.29.0", - "@sentry/core": "8.29.0", - "@sentry/types": "8.29.0", - "@sentry/utils": "8.29.0" + "@sentry-internal/browser-utils": "8.33.0", + "@sentry/core": "8.33.0", + "@sentry/types": "8.33.0", + "@sentry/utils": "8.33.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.29.0.tgz", - "integrity": "sha512-W2YbZRvp2lYC50V51fNLcnoIiK1Km4vSc+v6SL7c//lv2qpyumoUAAIDKY+14s8Lgt1RsR6rfZhfheD4O/6WSQ==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.33.0.tgz", + "integrity": "sha512-9fEhMP+gQYQrtn/SQd1Vd7U7emTSGBpLKc5h5f0iV0yDmjYAhNVbq4RgPTYAgnBEcdVo3qgboL6UIz9Dv+dYRQ==", "dependencies": { - "@sentry-internal/replay": "8.29.0", - "@sentry/core": "8.29.0", - "@sentry/types": "8.29.0", - "@sentry/utils": "8.29.0" + "@sentry-internal/replay": "8.33.0", + "@sentry/core": "8.33.0", + "@sentry/types": "8.33.0", + "@sentry/utils": "8.33.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay-canvas/node_modules/@sentry/core": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.29.0.tgz", - "integrity": "sha512-scMbZaJ0Ov8NPgWn86EdjhyTLrhvRVbTxjg0imJAvhIvRbblH3xyqye/17Qnk2fOp8TNDOl7TBZHi0NCFQ5HUw==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.33.0.tgz", + "integrity": "sha512-618PQGHQLBVCpAq1s+e/rpIUaLUnj19IPUgn97rUGXLLna8ETIAoyQoG70wz4q9niw4Z4GlS5kZNrael2O3+2w==", "dependencies": { - "@sentry/types": "8.29.0", - "@sentry/utils": "8.29.0" + "@sentry/types": "8.33.0", + "@sentry/utils": "8.33.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay-canvas/node_modules/@sentry/types": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.29.0.tgz", - "integrity": "sha512-j4gX3ctzgD4xVWllXAhm6M+kHFEvrFoUPFq60X/pgkjsWCocGuhtNfB0rW43ICG8hCnlz8IYl7O7b8V8qY7SPg==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.33.0.tgz", + "integrity": "sha512-V/A+72ZdnfGtXeXIpz1kUo3LRdq3WKEYYFUR2RKpCdPh9yeOrHq6u/rmzTWx49+om0yhZN+JhVoxDzt75UoFRg==", "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay-canvas/node_modules/@sentry/utils": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.29.0.tgz", - "integrity": "sha512-nb93/m3SjQChQJFqJj3oNW3Rz/12yrT7jypTCire3c2hpYWG2uR5n8VY9UUMTA6HLNvdom6tckK7p3bXGXlF0w==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.33.0.tgz", + "integrity": "sha512-TdwtGdevJij2wq2x/hDUr+x5TXt47ZhWxZ8zluai/lnIDTUB3Xs/L9yHtj1J+H9hr8obkMASE9IanUrWXzrP6Q==", "dependencies": { - "@sentry/types": "8.29.0" + "@sentry/types": "8.33.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay/node_modules/@sentry/core": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.29.0.tgz", - "integrity": "sha512-scMbZaJ0Ov8NPgWn86EdjhyTLrhvRVbTxjg0imJAvhIvRbblH3xyqye/17Qnk2fOp8TNDOl7TBZHi0NCFQ5HUw==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.33.0.tgz", + "integrity": "sha512-618PQGHQLBVCpAq1s+e/rpIUaLUnj19IPUgn97rUGXLLna8ETIAoyQoG70wz4q9niw4Z4GlS5kZNrael2O3+2w==", "dependencies": { - "@sentry/types": "8.29.0", - "@sentry/utils": "8.29.0" + "@sentry/types": "8.33.0", + "@sentry/utils": "8.33.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay/node_modules/@sentry/types": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.29.0.tgz", - "integrity": "sha512-j4gX3ctzgD4xVWllXAhm6M+kHFEvrFoUPFq60X/pgkjsWCocGuhtNfB0rW43ICG8hCnlz8IYl7O7b8V8qY7SPg==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.33.0.tgz", + "integrity": "sha512-V/A+72ZdnfGtXeXIpz1kUo3LRdq3WKEYYFUR2RKpCdPh9yeOrHq6u/rmzTWx49+om0yhZN+JhVoxDzt75UoFRg==", "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay/node_modules/@sentry/utils": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.29.0.tgz", - "integrity": "sha512-nb93/m3SjQChQJFqJj3oNW3Rz/12yrT7jypTCire3c2hpYWG2uR5n8VY9UUMTA6HLNvdom6tckK7p3bXGXlF0w==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.33.0.tgz", + "integrity": "sha512-TdwtGdevJij2wq2x/hDUr+x5TXt47ZhWxZ8zluai/lnIDTUB3Xs/L9yHtj1J+H9hr8obkMASE9IanUrWXzrP6Q==", "dependencies": { - "@sentry/types": "8.29.0" + "@sentry/types": "8.33.0" }, "engines": { "node": ">=14.18" @@ -3957,48 +3957,48 @@ } }, "node_modules/@sentry/browser": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.29.0.tgz", - "integrity": "sha512-aKTy4H/3RI0q9LIeepesjWGlGNeh4HGFfwQjzHME8gcWCQ5LSlzYX4U+hu2yp7r1Jfd9MUTFfOuuLih2HGLGsQ==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.33.0.tgz", + "integrity": "sha512-qu/g20ZskywEU8BWc4Fts1kXFFBtw1vS+XvPq7Ta9zCeRG5dlXhhYDVQ4/v4nAL/cs0o6aLCq73m109CFF0Kig==", "dependencies": { - "@sentry-internal/browser-utils": "8.29.0", - "@sentry-internal/feedback": "8.29.0", - "@sentry-internal/replay": "8.29.0", - "@sentry-internal/replay-canvas": "8.29.0", - "@sentry/core": "8.29.0", - "@sentry/types": "8.29.0", - "@sentry/utils": "8.29.0" + "@sentry-internal/browser-utils": "8.33.0", + "@sentry-internal/feedback": "8.33.0", + "@sentry-internal/replay": "8.33.0", + "@sentry-internal/replay-canvas": "8.33.0", + "@sentry/core": "8.33.0", + "@sentry/types": "8.33.0", + "@sentry/utils": "8.33.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/browser/node_modules/@sentry/core": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.29.0.tgz", - "integrity": "sha512-scMbZaJ0Ov8NPgWn86EdjhyTLrhvRVbTxjg0imJAvhIvRbblH3xyqye/17Qnk2fOp8TNDOl7TBZHi0NCFQ5HUw==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.33.0.tgz", + "integrity": "sha512-618PQGHQLBVCpAq1s+e/rpIUaLUnj19IPUgn97rUGXLLna8ETIAoyQoG70wz4q9niw4Z4GlS5kZNrael2O3+2w==", "dependencies": { - "@sentry/types": "8.29.0", - "@sentry/utils": "8.29.0" + "@sentry/types": "8.33.0", + "@sentry/utils": "8.33.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/browser/node_modules/@sentry/types": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.29.0.tgz", - "integrity": "sha512-j4gX3ctzgD4xVWllXAhm6M+kHFEvrFoUPFq60X/pgkjsWCocGuhtNfB0rW43ICG8hCnlz8IYl7O7b8V8qY7SPg==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.33.0.tgz", + "integrity": "sha512-V/A+72ZdnfGtXeXIpz1kUo3LRdq3WKEYYFUR2RKpCdPh9yeOrHq6u/rmzTWx49+om0yhZN+JhVoxDzt75UoFRg==", "engines": { "node": ">=14.18" } }, "node_modules/@sentry/browser/node_modules/@sentry/utils": { - "version": "8.29.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.29.0.tgz", - "integrity": "sha512-nb93/m3SjQChQJFqJj3oNW3Rz/12yrT7jypTCire3c2hpYWG2uR5n8VY9UUMTA6HLNvdom6tckK7p3bXGXlF0w==", + "version": "8.33.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.33.0.tgz", + "integrity": "sha512-TdwtGdevJij2wq2x/hDUr+x5TXt47ZhWxZ8zluai/lnIDTUB3Xs/L9yHtj1J+H9hr8obkMASE9IanUrWXzrP6Q==", "dependencies": { - "@sentry/types": "8.29.0" + "@sentry/types": "8.33.0" }, "engines": { "node": ">=14.18" diff --git a/package.json b/package.json index 62cdc8a0fb9..8eead0e45a3 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@headlessui/react": "^2.1.2", "@pnotify/core": "^5.2.0", "@pnotify/mobile": "^5.2.0", - "@sentry/browser": "^8.29.0", + "@sentry/browser": "^8.33.0", "@yudiel/react-qr-scanner": "^2.0.0-beta.3", "axios": "^1.7.7", "bowser": "^2.11.0", diff --git a/src/App.tsx b/src/App.tsx index 2e7f185f80b..6c6d5255b4d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,10 +1,11 @@ import { Suspense } from "react"; import Routers from "./Routers"; import ThemedFavicon from "./CAREUI/misc/ThemedFavicon"; -import Intergrations from "./Integrations"; +import Integrations from "./Integrations"; import Loading from "./Components/Common/Loading"; import HistoryAPIProvider from "./Providers/HistoryAPIProvider"; import AuthUserProvider from "./Providers/AuthUserProvider"; +import { FeatureFlagsProvider } from "./Utils/featureFlags"; const App = () => { return ( @@ -12,12 +13,14 @@ const App = () => { }> - + + + {/* Integrations */} - - + + ); diff --git a/src/Components/Facility/models.tsx b/src/Components/Facility/models.tsx index 97d81674658..56c70f2ac94 100644 --- a/src/Components/Facility/models.tsx +++ b/src/Components/Facility/models.tsx @@ -7,6 +7,7 @@ import { PATIENT_NOTES_THREADS, UserRole, } from "../../Common/constants"; +import { FeatureFlag } from "../../Utils/featureFlags"; import { ConsultationDiagnosis, CreateDiagnosis } from "../Diagnosis/types"; import { AssignedToObjectModel, @@ -80,6 +81,7 @@ export interface FacilityModel { local_body?: number; ward?: number; pincode?: string; + facility_flags?: FeatureFlag[]; latitude?: string; longitude?: string; kasp_empanelled?: boolean; diff --git a/src/Components/Patient/DailyRounds.tsx b/src/Components/Patient/DailyRounds.tsx index c0cd7fe803c..ef1281fb62b 100644 --- a/src/Components/Patient/DailyRounds.tsx +++ b/src/Components/Patient/DailyRounds.tsx @@ -542,6 +542,7 @@ export const DailyRounds = (props: any) => { >
{ setDiagnosisSuggestions([]); diff --git a/src/Components/Scribe/Scribe.tsx b/src/Components/Scribe/Scribe.tsx index d952ff7b1b2..384bf519a04 100644 --- a/src/Components/Scribe/Scribe.tsx +++ b/src/Components/Scribe/Scribe.tsx @@ -7,8 +7,8 @@ import * as Notify from "../../Utils/Notifications"; import request from "../../Utils/request/request"; import { UserModel } from "../Users/models"; import useSegmentedRecording from "../../Utils/useSegmentedRecorder"; -import careConfig from "@careConfig"; import uploadFile from "../../Utils/request/uploadFile"; +import { useFeatureFlags } from "../../Utils/featureFlags"; interface FieldOption { id: string | number; @@ -52,6 +52,7 @@ export type ScribeModel = { }; interface ScribeProps { + facilityId: string; form: ScribeForm; existingData?: { [key: string]: any }; onFormUpdate: (fields: any) => void; @@ -62,7 +63,11 @@ const SCRIBE_FILE_TYPES = { SCRIBE: 1, }; -export const Scribe: React.FC = ({ form, onFormUpdate }) => { +export const Scribe: React.FC = ({ + form, + onFormUpdate, + facilityId, +}) => { const [open, setOpen] = useState(false); const [_progress, setProgress] = useState(0); const [stage, setStage] = useState("start"); @@ -80,6 +85,8 @@ export const Scribe: React.FC = ({ form, onFormUpdate }) => { const stageRef = useRef(stage); const [fields, setFields] = useState([]); + const featureFlags = useFeatureFlags(facilityId); + useEffect(() => { const loadFields = async () => { const fields = await form.fields(); @@ -544,7 +551,7 @@ export const Scribe: React.FC = ({ form, onFormUpdate }) => { } } - if (!careConfig.scribe.enabled) return null; + if (!featureFlags.includes("SCRIBE_ENABLED")) return null; return ( diff --git a/src/Components/Users/models.tsx b/src/Components/Users/models.tsx index 1bbe494b9ed..790826022b5 100644 --- a/src/Components/Users/models.tsx +++ b/src/Components/Users/models.tsx @@ -1,4 +1,5 @@ import { GENDER_TYPES, UserRole } from "../../Common/constants"; +import { FeatureFlag } from "../../Utils/featureFlags"; import { DistrictModel, LocalBodyModel, StateModel } from "../Facility/models"; interface HomeFacilityObjectModel { @@ -44,6 +45,7 @@ export type UserModel = UserBareMinimum & { doctor_experience_commenced_on?: string; doctor_medical_council_registration?: string; weekly_working_hours?: string | null; + user_flags?: FeatureFlag[]; }; export type UserBaseModel = { diff --git a/src/Integrations/index.tsx b/src/Integrations/index.tsx index aeb0399a452..9b2b1e156fd 100644 --- a/src/Integrations/index.tsx +++ b/src/Integrations/index.tsx @@ -1,6 +1,6 @@ import Sentry from "./Sentry"; import Plausible from "./Plausible"; -const Intergrations = { Sentry, Plausible }; +const Integrations = { Sentry, Plausible }; -export default Intergrations; +export default Integrations; diff --git a/src/Utils/featureFlags.tsx b/src/Utils/featureFlags.tsx new file mode 100644 index 00000000000..739d49e821a --- /dev/null +++ b/src/Utils/featureFlags.tsx @@ -0,0 +1,78 @@ +import { createContext, useContext, useState, useEffect } from "react"; +import useQuery from "./request/useQuery"; +import routes from "../Redux/api"; +import useAuthUser from "../Common/hooks/useAuthUser"; +import { FacilityModel } from "../Components/Facility/models"; + +export type FeatureFlag = "SCRIBE_ENABLED"; // "HCX_ENABLED" | "ABDM_ENABLED" | + +export interface FeatureFlagsResponse { + user_flags: FeatureFlag[]; + facility_flags: { + facility: string; + features: FeatureFlag[]; + }[]; +} + +const defaultFlags: FeatureFlag[] = []; + +const FeatureFlagsContext = createContext({ + user_flags: defaultFlags, + facility_flags: [], +}); + +export const FeatureFlagsProvider = (props: { children: React.ReactNode }) => { + const [featureFlags, setFeatureFlags] = useState({ + user_flags: defaultFlags, + facility_flags: [], + }); + + const user = useAuthUser(); + + useEffect(() => { + if (user.user_flags) { + setFeatureFlags((ff) => ({ + ...ff, + user_flags: [...defaultFlags, ...(user.user_flags || [])], + })); + } + }, [user]); + + return ( + + {props.children} + + ); +}; + +export const useFeatureFlags = (facility?: FacilityModel | string) => { + const [facilityObject, setFacilityObject] = useState< + FacilityModel | undefined + >(typeof facility === "string" ? undefined : facility); + + const context = useContext(FeatureFlagsContext); + if (context === undefined) { + throw new Error( + "useFeatureFlags must be used within a FeatureFlagsProvider", + ); + } + + const facilityQuery = useQuery(routes.getPermittedFacility, { + pathParams: { + id: typeof facility === "string" ? facility : "", + }, + prefetch: false, + silent: true, + onResponse: (res) => { + setFacilityObject(res.data); + }, + }); + + const facilityFlags = facilityObject?.facility_flags || []; + + useEffect(() => { + facilityQuery.refetch(); + }, [facility]); + + return [...context.user_flags, ...facilityFlags]; +};