diff --git a/airbyte-webapp/.gitignore b/airbyte-webapp/.gitignore index 4c2aede53775..970b7323e235 100644 --- a/airbyte-webapp/.gitignore +++ b/airbyte-webapp/.gitignore @@ -11,11 +11,8 @@ # misc .DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local +# Log files npm-debug.log* yarn-debug.log* yarn-error.log* @@ -23,9 +20,16 @@ yarn-error.log* *.iml /.idea -.npmrc +# Environment overwrites .env.development .env.production +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Local overwrites +.experiments.json storybook-static/ diff --git a/airbyte-webapp/package.json b/airbyte-webapp/package.json index 113e822c4a84..b5f62ab1726b 100644 --- a/airbyte-webapp/package.json +++ b/airbyte-webapp/package.json @@ -8,9 +8,9 @@ "scripts": { "prepare": "cd .. && husky install airbyte-webapp/.husky", "prestart": "npm run generate-client", - "start": "craco start", + "start": "node -r ./scripts/dev-overwrites.js ./node_modules/.bin/craco start", "prestart:cloud": "npm run generate-client", - "start:cloud": "AB_ENV=${AB_ENV-frontend-dev} node -r ./scripts/environment.js ./node_modules/.bin/craco start", + "start:cloud": "AB_ENV=${AB_ENV-frontend-dev} node -r ./scripts/environment.js -r ./scripts/dev-overwrites.js ./node_modules/.bin/craco start", "prebuild": "npm run generate-client", "build": "BUILD_PATH='./build/app' craco build", "pretest": "npm run generate-client", diff --git a/airbyte-webapp/scripts/dev-overwrites.js b/airbyte-webapp/scripts/dev-overwrites.js new file mode 100644 index 000000000000..9633cc484699 --- /dev/null +++ b/airbyte-webapp/scripts/dev-overwrites.js @@ -0,0 +1,14 @@ +const fs = require("fs"); +const path = require("path"); + +const EXPERIMENTS_FILE = path.resolve(__dirname, "../.experiments.json"); + +if (fs.existsSync(EXPERIMENTS_FILE)) { + console.log("\nOverwriting experiments from .experiments.json ..."); + const overwrites = require(EXPERIMENTS_FILE); + + if (Object.keys(overwrites).length) { + console.log(`Overwriting experiments with the following values:\n\n${JSON.stringify(overwrites, null, 2)}`); + process.env.REACT_APP_EXPERIMENT_OVERWRITES = JSON.stringify(overwrites); + } +} diff --git a/airbyte-webapp/src/hooks/services/Experiment/ExperimentService.tsx b/airbyte-webapp/src/hooks/services/Experiment/ExperimentService.tsx index 96649e5bda88..6529d0fad3b7 100644 --- a/airbyte-webapp/src/hooks/services/Experiment/ExperimentService.tsx +++ b/airbyte-webapp/src/hooks/services/Experiment/ExperimentService.tsx @@ -4,6 +4,10 @@ import { createContext, useContext, useMemo } from "react"; import { useObservable } from "react-use"; import { EMPTY, Observable } from "rxjs"; +const devOverwrites = process.env.REACT_APP_EXPERIMENT_OVERWRITES + ? (JSON.parse(process.env.REACT_APP_EXPERIMENT_OVERWRITES) as Record) + : {}; + const experimentContext = createContext(null); /** @@ -15,7 +19,7 @@ export interface ExperimentService { getExperimentChanges$(key: K): Observable; } -export function useExperiment(key: K, defaultValue: Experiments[K]): Experiments[K] { +function useExperimentHook(key: K, defaultValue: Experiments[K]): Experiments[K] { const experimentService = useContext(experimentContext); // Get the observable for the changes of the experiment or an empty (never emitting) observable in case the // experiment service doesn't exist (e.g. we're running in OSS or it failed to initialize) @@ -25,4 +29,17 @@ export function useExperiment(key: K, defaultValue: return useObservable(onChanges$, experimentService?.getExperiment(key, defaultValue) ?? defaultValue); } +function useExperimentWithOverwrites( + key: K, + defaultValue: Experiments[K] +): Experiments[K] { + // Load the regular experiments value via the prod hook + const value = useExperimentHook(key, defaultValue); + // Use the overwrite value if it's available, otherwise the proper value + return key in devOverwrites ? (devOverwrites[key] as Experiments[K]) : value; +} + +// Allow overwriting values via the .experiments.dev file (and thus the REACT_APP_EXPERIMENT_OVERWRITES env variable) only during development +export const useExperiment = process.env.NODE_ENV === "development" ? useExperimentWithOverwrites : useExperimentHook; + export const ExperimentProvider = experimentContext.Provider;