Skip to content
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

Add shared files for Cloud to override user settings / feature flags #23485

Merged
merged 3 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {Box} from '@dagster-io/ui-components';
import {ReactNode} from 'react';
import {useHistory} from 'react-router-dom';
import {FeatureFlag} from 'shared/app/FeatureFlags.oss';

import {TopNavLink} from './AppTopNav';
import {
Expand All @@ -11,7 +12,7 @@ import {
locationPathMatcher,
} from './activePathMatchers';
import {DeploymentStatusIcon} from '../../nav/DeploymentStatusIcon';
import {FeatureFlag, featureEnabled} from '../Flags';
import {featureEnabled} from '../Flags';
import {ShortcutHandler} from '../ShortcutHandler';

export type AppNavLinkType = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export enum FeatureFlag {
flagDebugConsoleLogging = 'flagDebugConsoleLogging',
flagDisableWebsockets = 'flagDisableWebsockets',
flagSidebarResources = 'flagSidebarResources',
flagDisableAutoLoadDefaults = 'flagDisableAutoLoadDefaults',
flagSettingsPage = 'flagSettingsPage',
}
21 changes: 6 additions & 15 deletions js_modules/dagster-ui/packages/ui-core/src/app/Flags.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,33 @@
import memoize from 'lodash/memoize';
import {useMemo} from 'react';
import {FeatureFlag} from 'shared/app/FeatureFlags.oss';

import {getJSONForKey} from '../hooks/useStateWithStorage';

export const DAGSTER_FLAGS_KEY = 'DAGSTER_FLAGS';

// Use const because we need to extend this in cloud. https://blog.logrocket.com/extend-enums-typescript/
export const FeatureFlag = {
flagDebugConsoleLogging: 'flagDebugConsoleLogging' as const,
flagDisableWebsockets: 'flagDisableWebsockets' as const,
flagSidebarResources: 'flagSidebarResources' as const,
flagDisableAutoLoadDefaults: 'flagDisableAutoLoadDefaults' as const,
flagSettingsPage: 'flagSettingsPage' as const,
};
export type FeatureFlagType = keyof typeof FeatureFlag;

export const getFeatureFlags: () => FeatureFlagType[] = memoize(
export const getFeatureFlags: () => FeatureFlag[] = memoize(
() => getJSONForKey(DAGSTER_FLAGS_KEY) || [],
);

export const featureEnabled = memoize((flag: FeatureFlagType) => getFeatureFlags().includes(flag));
export const featureEnabled = memoize((flag: FeatureFlag) => getFeatureFlags().includes(flag));

type FlagMap = {
readonly [F in FeatureFlagType]: boolean;
readonly [F in FeatureFlag]: boolean;
};

export const useFeatureFlags = () => {
return useMemo(() => {
const flagSet = new Set(getFeatureFlags());
const all: Record<string, boolean> = {};
for (const flag in FeatureFlag) {
all[flag] = flagSet.has(flag as FeatureFlagType);
all[flag] = flagSet.has(flag as FeatureFlag);
}
return all as FlagMap;
}, []);
};

export const setFeatureFlags = (flags: FeatureFlagType[]) => {
export const setFeatureFlags = (flags: FeatureFlag[]) => {
if (!(flags instanceof Array)) {
throw new Error('flags must be an array');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {Icon} from '@dagster-io/ui-components';
import {useState} from 'react';
import {getVisibleFeatureFlagRows} from 'shared/app/getVisibleFeatureFlagRows.oss';

import {useFeatureFlags} from './Flags';
import {TopNavButton} from './TopNavButton';
import {UserSettingsDialog} from './UserSettingsDialog/UserSettingsDialog';
import {getVisibleFeatureFlagRows} from './getVisibleFeatureFlagRows';

export const UserSettingsButton = () => {
const {flagSettingsPage} = useFeatureFlags();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import {
Tooltip,
} from '@dagster-io/ui-components';
import * as React from 'react';
import {FeatureFlag} from 'shared/app/FeatureFlags.oss';
import {UserPreferences} from 'shared/app/UserSettingsDialog/UserPreferences.oss';

import {CodeLinkProtocolSelect} from '../../code-links/CodeLinkProtocol';
import {FeatureFlagType, getFeatureFlags, setFeatureFlags} from '../Flags';
import {getFeatureFlags, setFeatureFlags} from '../Flags';

type OnCloseFn = (event: React.SyntheticEvent<HTMLElement>) => void;
type VisibleFlag = {key: string; label?: React.ReactNode; flagType: FeatureFlagType};
type VisibleFlag = {key: string; label?: React.ReactNode; flagType: FeatureFlag};

interface DialogProps {
isOpen: boolean;
Expand All @@ -40,15 +41,15 @@ export const UserSettingsDialog = ({isOpen, onClose, visibleFlags}: DialogProps)

interface DialogContentProps {
onClose: OnCloseFn;
visibleFlags: {key: string; label?: React.ReactNode; flagType: FeatureFlagType}[];
visibleFlags: {key: string; label?: React.ReactNode; flagType: FeatureFlag}[];
}

/**
* Separate the content from the `Dialog` so that we don't prepare its state before
* we want to render it.
*/
const UserSettingsDialogContent = ({onClose, visibleFlags}: DialogContentProps) => {
const [flags, setFlags] = React.useState<FeatureFlagType[]>(() => getFeatureFlags());
const [flags, setFlags] = React.useState<FeatureFlag[]>(() => getFeatureFlags());
const [reloading, setReloading] = React.useState(false);

const initialFlagState = React.useRef(JSON.stringify([...getFeatureFlags().sort()]));
Expand All @@ -57,7 +58,7 @@ const UserSettingsDialogContent = ({onClose, visibleFlags}: DialogContentProps)
setFeatureFlags(flags);
});

const toggleFlag = (flag: FeatureFlagType) => {
const toggleFlag = (flag: FeatureFlag) => {
setFlags(flags.includes(flag) ? flags.filter((f) => f !== flag) : [...flags, flag]);
};

Expand Down
3 changes: 2 additions & 1 deletion js_modules/dagster-ui/packages/ui-core/src/app/Util.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {cache} from 'idb-lru-cache';
import memoize from 'lodash/memoize';
import LRU from 'lru-cache';
import {FeatureFlag} from 'shared/app/FeatureFlags.oss';

import {FeatureFlag, featureEnabled} from './Flags';
import {featureEnabled} from './Flags';
import {timeByParts} from './timeByParts';

function twoDigit(v: number) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {FeatureFlag} from './Flags';
import {FeatureFlag} from 'shared/app/FeatureFlags.oss';

/**
* Open-source feature flags to be displayed in Dagster UI "User settings"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {Box, Icon} from '@dagster-io/ui-components';
import {useState} from 'react';
import {useLocation} from 'react-router-dom';
import {getVisibleFeatureFlagRows} from 'shared/app/getVisibleFeatureFlagRows.oss';

import {UserSettingsDialog} from '../app/UserSettingsDialog/UserSettingsDialog';
import {getVisibleFeatureFlagRows} from '../app/getVisibleFeatureFlagRows';
import {SideNavItem, SideNavItemConfig} from '../ui/SideNavItem';

const items: SideNavItemConfig[] = [
Expand Down