-
Notifications
You must be signed in to change notification settings - Fork 2
Feature Flags Basic Implementation #289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 7 commits
e28ed5d
4635ca3
0cd0cd7
4586d99
163de5a
cc6ca5d
d3e7634
9d1f4e2
a66883d
5c01276
6355b31
3f6354f
41a26d6
97f58a7
ec6eb4a
78522ff
eddf7f9
bde4275
fd6c354
306f51e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| .nav_feature_div { | ||
| display: inline-block; | ||
| } | ||
|
|
||
| .nav_feature_div:not(:empty) { | ||
| padding-right: 2em; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| // React imports | ||
| import React from "react"; | ||
| import { useDispatch, useSelector } from "react-redux"; | ||
| import { toggleFeatureFlag } from "../../../lib/featureFlagSlice"; | ||
|
|
||
| const Dashboard = () => { | ||
| const dispatch = useDispatch(); | ||
| const featureFlagState = useSelector((state) => state.featureFlagState); | ||
|
|
||
| const handleToggle = (flag) => { | ||
| dispatch(toggleFeatureFlag(flag)); | ||
| }; | ||
|
|
||
| return ( | ||
| <div> | ||
| <p>dashboard</p> | ||
| {Object.entries(featureFlagState).map(([key, value]) => | ||
| key[0] === "_" ? null : ( | ||
| <button key={key} onClick={() => handleToggle(key)}> | ||
| {value | ||
| ? "Toggle " + key.slice(6, key.length) + " Off" | ||
| : "Toggle " + key.slice(6, key.length) + " On"} | ||
| </button> | ||
| ) | ||
| )} | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| // return ( | ||
| // <div> | ||
| // <p>Enable About: {String(enableAbout)}</p> | ||
| // <button onClick={handleToggleAbout}>Toggle Enable About</button> | ||
| // </div> | ||
| // ); | ||
| // }; | ||
|
|
||
| export default Dashboard; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| import { createSlice, PayloadAction } from "@reduxjs/toolkit"; | ||
|
|
||
| // const API_ADDRESS = "http://localhost:8080"; | ||
mlaws21 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| interface FeatureFlagsState { | ||
| enableAbout: boolean; | ||
| enableWiki: boolean; | ||
| enableFAQ: boolean; | ||
|
|
||
| // Add more feature flags as needed | ||
| } | ||
|
|
||
| export const initialState: FeatureFlagsState = { | ||
| enableAbout: false, | ||
| enableWiki: false, | ||
| enableFAQ: false, | ||
|
|
||
| // Initialize other feature flags | ||
| }; | ||
mlaws21 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| const featureFlagSlice = createSlice({ | ||
| name: "featureFlags", | ||
| initialState, | ||
| reducers: { | ||
| toggleFeatureFlag: ( | ||
mlaws21 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| state, | ||
| action: PayloadAction<keyof FeatureFlagsState> | ||
| ) => { | ||
| const flagKey = action.payload; | ||
| if (flagKey in state) { | ||
| state[flagKey] = !state[flagKey]; | ||
| } | ||
| }, | ||
|
||
| }, | ||
| }); | ||
|
|
||
| export const { toggleFeatureFlag } = featureFlagSlice.actions; | ||
|
|
||
| // export const getFeatureFlag = (state: FeatureFlagsState, flag: keyof FeatureFlagsState) => featureFlagsState[flag]; | ||
mlaws21 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| export default featureFlagSlice.reducer; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,31 @@ | ||
| import courseReducer from "./course"; | ||
| import schedulerUtilReducer from "./schedulerUtils"; | ||
| import authReducer from "../lib/authSlice"; | ||
| import featureFlagReducer from "../lib/featureFlagSlice"; | ||
|
|
||
| import goodrichReducer from "./goodrich"; | ||
|
|
||
| const rootReducer = { | ||
| courseState: courseReducer, | ||
| schedulerUtilState: schedulerUtilReducer, | ||
| authState: authReducer, | ||
| goodrichState: goodrichReducer, | ||
| featureFlagState: featureFlagReducer, | ||
| }; | ||
|
|
||
| export interface RootState { | ||
| courseState: ReturnType<typeof courseReducer>; | ||
| schedulerUtilState: ReturnType<typeof schedulerUtilReducer>; | ||
| authState: ReturnType<typeof authReducer>; | ||
| goodrichState: ReturnType<typeof goodrichReducer>; | ||
| featureFlagState: ReturnType<typeof featureFlagReducer>; | ||
| } | ||
|
|
||
mlaws21 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| export default rootReducer; | ||
| export { courseReducer, schedulerUtilReducer, authReducer, goodrichReducer }; | ||
| export { | ||
| courseReducer, | ||
| schedulerUtilReducer, | ||
| authReducer, | ||
| goodrichReducer, | ||
| featureFlagReducer, | ||
| }; | ||
Uh oh!
There was an error while loading. Please reload this page.