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/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];
+};