Skip to content

Commit

Permalink
[Feat] Implemented new feature flag by passing features flags prop (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
igorDykhta committed Aug 24, 2022
1 parent 50eda73 commit 99b38d2
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 41 deletions.
3 changes: 2 additions & 1 deletion examples/demo-app/src/app.js
Expand Up @@ -30,7 +30,7 @@ import Announcement, {FormLink} from './components/announcement';
import {replaceLoadDataModal} from './factories/load-data-modal';
import {replaceMapControl} from './factories/map-control';
import {replacePanelHeader} from './factories/panel-header';
import {AUTH_TOKENS} from './constants/default-settings';
import {AUTH_TOKENS, DEFAULT_FEATURE_FLAGS} from './constants/default-settings';
import {messages} from './constants/localization';

import {
Expand Down Expand Up @@ -401,6 +401,7 @@ class App extends Component {
localeMessages={messages}
onExportToCloudSuccess={onExportFileSuccess}
onLoadCloudMapSuccess={onLoadCloudMapSuccess}
featureFlags={DEFAULT_FEATURE_FLAGS}
/>
)}
</AutoSizer>
Expand Down
6 changes: 2 additions & 4 deletions examples/demo-app/src/reducers/index.js
Expand Up @@ -34,7 +34,7 @@ import {
SET_SAMPLE_LOADING_STATUS
} from '../actions';

import {AUTH_TOKENS, DEFAULT_FEATURE_FLAGS} from '../constants/default-settings';
import {AUTH_TOKENS} from '../constants/default-settings';
import {generateHashId} from '../utils/strings';

// INITIAL_APP_STATE
Expand All @@ -43,13 +43,11 @@ const initialAppState = {
loaded: false,
sampleMaps: [], // this is used to store sample maps fetch from a remote json file
isMapLoading: false, // determine whether we are loading a sample map,
error: null, // contains error when loading/retrieving data/configuration
error: null // contains error when loading/retrieving data/configuration
// {
// status: null,
// message: null
// }
// eventually we may have an async process to fetch these from a remote location
featureFlags: DEFAULT_FEATURE_FLAGS
};

// App reducer
Expand Down
19 changes: 18 additions & 1 deletion src/components/context.ts → src/components/context.tsx
Expand Up @@ -18,7 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import {createContext, RefObject} from 'react';
import React, {createContext, RefObject, ReactNode, ReactElement} from 'react';

const identity = state => state;
// New Context API only supported after 16.3
Expand All @@ -27,6 +27,23 @@ const KeplerGlContext = createContext({
id: 'map'
});

export const FeatureFlagsContext = createContext<object | null>({});

export type FeatureFlags = {[key: string]: string | boolean};

export type FeatureFlagsContextProviderProps = {
children: ReactNode;
featureFlags?: FeatureFlags;
};

export const FeatureFlagsContextProvider = (
props: FeatureFlagsContextProviderProps
): ReactElement => (
<FeatureFlagsContext.Provider value={props.featureFlags || null}>
{props.children}
</FeatureFlagsContext.Provider>
);

export const RootContext = createContext<RefObject<HTMLDivElement> | null>(null);

export default KeplerGlContext;
6 changes: 6 additions & 0 deletions src/components/hooks/useFeatureFlags.ts
@@ -0,0 +1,6 @@
import {useContext} from 'react';
import {FeatureFlagsContext} from '../context';

const useFeatureFlags = () => useContext(FeatureFlagsContext);

export default useFeatureFlags;
77 changes: 42 additions & 35 deletions src/components/kepler-gl.tsx
Expand Up @@ -26,7 +26,7 @@ import {createSelector} from 'reselect';
import {connect as keplerGlConnect} from 'connect/keplergl-connect';
import {IntlProvider} from 'react-intl';
import {messages} from '@kepler.gl/localization';
import {RootContext} from 'components/context';
import {RootContext, FeatureFlagsContextProvider, FeatureFlags} from 'components/context';
import {OnErrorCallBack, OnSuccessCallBack} from 'actions/provider-actions';

import * as VisStateActions from 'actions/vis-state-actions';
Expand Down Expand Up @@ -259,7 +259,8 @@ export const DEFAULT_KEPLER_GL_PROPS = {
sidePanelWidth: DIMENSIONS.sidePanel.width,
theme: {},
cloudProviders: [],
readOnly: false
readOnly: false,
featureFlags: {}
};

type KeplerGLBasicProps = {
Expand Down Expand Up @@ -288,6 +289,7 @@ type KeplerGLBasicProps = {
onExportToCloudSuccess?: OnSuccessCallBack;
onExportToCloudError?: OnErrorCallBack;
readOnly?: boolean;
featureFlags?: FeatureFlags;

localeMessages?: {[key: string]: {[key: string]: string}};
dispatch: Dispatch<any>;
Expand Down Expand Up @@ -426,7 +428,10 @@ function KeplerGlFactory(
uiState,
visState,
// readOnly override
readOnly
readOnly,

// features
featureFlags
} = this.props;

const dimensions = this.state.dimensions || {width, height};
Expand Down Expand Up @@ -458,40 +463,42 @@ function KeplerGlFactory(

return (
<RootContext.Provider value={this.root}>
<IntlProvider locale={uiState.locale} messages={localeMessages[uiState.locale]}>
<ThemeProvider theme={theme}>
<GlobalStyle
className="kepler-gl"
id={`kepler-gl__${id}`}
style={{
display: 'flex',
flexDirection: 'column',
position: 'relative',
width: `${width}px`,
height: `${height}px`
}}
ref={this.root}
>
<NotificationPanel {...notificationPanelFields} />
{!uiState.readOnly && !readOnly && <SidePanel {...sideFields} />}
<MapsLayout className="maps">{mapContainers}</MapsLayout>
{isExportingImage && <PlotContainer {...plotContainerFields} />}
{interactionConfig.geocoder.enabled && <GeoCoderPanel {...geoCoderPanelFields} />}
<BottomWidgetOuter absolute>
<BottomWidget
ref={this.bottomWidgetRef}
{...bottomWidgetFields}
<FeatureFlagsContextProvider featureFlags={featureFlags}>
<IntlProvider locale={uiState.locale} messages={localeMessages[uiState.locale]}>
<ThemeProvider theme={theme}>
<GlobalStyle
className="kepler-gl"
id={`kepler-gl__${id}`}
style={{
display: 'flex',
flexDirection: 'column',
position: 'relative',
width: `${width}px`,
height: `${height}px`
}}
ref={this.root}
>
<NotificationPanel {...notificationPanelFields} />
{!uiState.readOnly && !readOnly && <SidePanel {...sideFields} />}
<MapsLayout className="maps">{mapContainers}</MapsLayout>
{isExportingImage && <PlotContainer {...plotContainerFields} />}
{interactionConfig.geocoder.enabled && <GeoCoderPanel {...geoCoderPanelFields} />}
<BottomWidgetOuter absolute>
<BottomWidget
ref={this.bottomWidgetRef}
{...bottomWidgetFields}
containerW={dimensions.width}
/>
</BottomWidgetOuter>
<ModalContainer
{...modalContainerFields}
containerW={dimensions.width}
containerH={dimensions.height}
/>
</BottomWidgetOuter>
<ModalContainer
{...modalContainerFields}
containerW={dimensions.width}
containerH={dimensions.height}
/>
</GlobalStyle>
</ThemeProvider>
</IntlProvider>
</GlobalStyle>
</ThemeProvider>
</IntlProvider>
</FeatureFlagsContextProvider>
</RootContext.Provider>
);
}
Expand Down
2 changes: 2 additions & 0 deletions src/constants/src/default-settings.ts
Expand Up @@ -945,6 +945,8 @@ export const LOADING_METHODS = keyMirror({
storage: null
});

export const DEFAULT_FEATURE_FLAGS = {};

export const DATASET_FORMATS = keyMirror({
row: null,
geojson: null,
Expand Down

0 comments on commit 99b38d2

Please sign in to comment.