chore: Add an extra feature flag to control App sidebar rollout (#28876)

Adds a new feature flag to control the rollout of the App sidebar. It
needs to be different as the earlier feature flag was shipped to users
already and they may not be on the latest version.

fixes: #28877
This commit is contained in:
Hetu Nandu 2023-11-15 16:49:41 +05:30 committed by GitHub
parent bd558937aa
commit b26a954d94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 45 additions and 44 deletions

View File

@ -37,6 +37,7 @@ export const FEATURE_FLAG = {
ab_create_new_apps_enabled: "ab_create_new_apps_enabled", ab_create_new_apps_enabled: "ab_create_new_apps_enabled",
release_show_new_sidebar_announcement_enabled: release_show_new_sidebar_announcement_enabled:
"release_show_new_sidebar_announcement_enabled", "release_show_new_sidebar_announcement_enabled",
rollout_app_sidebar_enabled: "rollout_app_sidebar_enabled",
} as const; } as const;
export type FeatureFlag = keyof typeof FEATURE_FLAG; export type FeatureFlag = keyof typeof FEATURE_FLAG;
@ -71,6 +72,7 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = {
ab_onboarding_flow_start_with_data_dev_only_enabled: false, ab_onboarding_flow_start_with_data_dev_only_enabled: false,
ab_create_new_apps_enabled: false, ab_create_new_apps_enabled: false,
release_show_new_sidebar_announcement_enabled: false, release_show_new_sidebar_announcement_enabled: false,
rollout_app_sidebar_enabled: false,
}; };
export const AB_TESTING_EVENT_KEYS = { export const AB_TESTING_EVENT_KEYS = {

View File

@ -26,18 +26,15 @@ import { SaaSEditorRoutes } from "pages/Editor/SaaSEditor/routes";
import OnboardingChecklist from "pages/Editor/FirstTimeUserOnboarding/Checklist"; import OnboardingChecklist from "pages/Editor/FirstTimeUserOnboarding/Checklist";
import { DatasourceEditorRoutes } from "pages/routes"; import { DatasourceEditorRoutes } from "pages/routes";
import CurlImportEditor from "pages/Editor/APIEditor/CurlImportEditor"; import CurlImportEditor from "pages/Editor/APIEditor/CurlImportEditor";
import { useFeatureFlag } from "../../../utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "../../entities/FeatureFlag";
import CreateNewDatasourceTab from "../../../pages/Editor/IntegrationEditor/CreateNewDatasourceTab"; import CreateNewDatasourceTab from "../../../pages/Editor/IntegrationEditor/CreateNewDatasourceTab";
import { useIsAppSidebarEnabled } from "../../../navigation/featureFlagHooks";
const SentryRoute = Sentry.withSentryRouting(Route); const SentryRoute = Sentry.withSentryRouting(Route);
function EditorRoutes() { function EditorRoutes() {
const { path } = useRouteMatch(); const { path } = useRouteMatch();
const { pathname } = useLocation(); const { pathname } = useLocation();
const isAppSidebarEnabled = useFeatureFlag( const isAppSidebarEnabled = useIsAppSidebarEnabled();
FEATURE_FLAG.release_app_sidebar_enabled,
);
useEffect(() => { useEffect(() => {
return () => { return () => {

View File

@ -32,7 +32,7 @@ import { getEditingEntityName } from "@appsmith/selectors/entitiesSelector";
import styled from "styled-components"; import styled from "styled-components";
import moment from "moment"; import moment from "moment";
import AnalyticsUtil from "../../utils/AnalyticsUtil"; import AnalyticsUtil from "../../utils/AnalyticsUtil";
import { getIsAppSidebarEnabled } from "../../selectors/ideSelectors"; import { useIsAppSidebarEnabled } from "../../navigation/featureFlagHooks";
const StyledResizer = styled.div<{ resizing: boolean }>` const StyledResizer = styled.div<{ resizing: boolean }>`
${(props) => ${(props) =>
@ -60,7 +60,7 @@ export const EntityExplorerSidebar = memo(({ children }: Props) => {
const active = useSelector(getExplorerActive); const active = useSelector(getExplorerActive);
const sidebarRef = useRef<HTMLDivElement>(null); const sidebarRef = useRef<HTMLDivElement>(null);
const pinned = useSelector(getExplorerPinned); const pinned = useSelector(getExplorerPinned);
const isAppSidebarEnabled = useSelector(getIsAppSidebarEnabled); const isAppSidebarEnabled = useIsAppSidebarEnabled();
/** /**
* on entity explorer sidebar width change * on entity explorer sidebar width change

View File

@ -0,0 +1,14 @@
import { useFeatureFlag } from "../utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag";
export const useIsAppSidebarEnabled = () => {
const isAppSidebarEnabled = useFeatureFlag(
FEATURE_FLAG.release_app_sidebar_enabled,
);
const isAppSidebarRolloutEnabled = useFeatureFlag(
FEATURE_FLAG.rollout_app_sidebar_enabled,
);
return isAppSidebarEnabled || isAppSidebarRolloutEnabled;
};

View File

@ -6,10 +6,10 @@ import {
APP_SETTINGS_PANE_HEADER, APP_SETTINGS_PANE_HEADER,
} from "@appsmith/constants/messages"; } from "@appsmith/constants/messages";
import { Tooltip } from "design-system"; import { Tooltip } from "design-system";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch } from "react-redux";
import { Button } from "design-system"; import { Button } from "design-system";
import { getIsAppSidebarEnabled } from "selectors/ideSelectors";
import classNames from "classnames"; import classNames from "classnames";
import { useIsAppSidebarEnabled } from "../../../navigation/featureFlagHooks";
const StyledHeader = styled.div` const StyledHeader = styled.div`
height: 48px; height: 48px;
@ -25,7 +25,7 @@ const StyledText = styled.div`
function PaneHeader() { function PaneHeader() {
const dispatch = useDispatch(); const dispatch = useDispatch();
const isAppSidebarEnabled = useSelector(getIsAppSidebarEnabled); const isAppSidebarEnabled = useIsAppSidebarEnabled();
return ( return (
<StyledHeader <StyledHeader

View File

@ -14,8 +14,7 @@ import {
useLayoutSystemFeatures, useLayoutSystemFeatures,
} from "../../../layoutSystems/common/useLayoutSystemFeatures"; } from "../../../layoutSystems/common/useLayoutSystemFeatures";
import { MainContainerWidthToggles } from "../MainContainerWidthToggles"; import { MainContainerWidthToggles } from "../MainContainerWidthToggles";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { useIsAppSidebarEnabled } from "../../../navigation/featureFlagHooks";
import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag";
const Title = styled.p` const Title = styled.p`
color: var(--ads-v2-color-fg); color: var(--ads-v2-color-fg);
@ -25,9 +24,7 @@ const MainHeading = styled.h3`
`; `;
export function CanvasPropertyPane() { export function CanvasPropertyPane() {
const dispatch = useDispatch(); const dispatch = useDispatch();
const isAppSidebarEnabled = useFeatureFlag( const isAppSidebarEnabled = useIsAppSidebarEnabled();
FEATURE_FLAG.release_app_sidebar_enabled,
);
const openAppSettingsPane = () => { const openAppSettingsPane = () => {
AnalyticsUtil.logEvent("APP_SETTINGS_BUTTON_CLICK"); AnalyticsUtil.logEvent("APP_SETTINGS_BUTTON_CLICK");

View File

@ -9,6 +9,7 @@ import { isHidden, isKVArray } from "components/formControls/utils";
import log from "loglevel"; import log from "loglevel";
import CloseEditor from "components/editorComponents/CloseEditor"; import CloseEditor from "components/editorComponents/CloseEditor";
import type { FeatureFlags } from "@appsmith/entities/FeatureFlag"; import type { FeatureFlags } from "@appsmith/entities/FeatureFlag";
import { useIsAppSidebarEnabled } from "../../../navigation/featureFlagHooks";
export const FormContainer = styled.div` export const FormContainer = styled.div`
display: flex; display: flex;
@ -48,13 +49,11 @@ export class JSONtoForm<
SS = any, SS = any,
> extends React.Component<JSONtoFormProps & P, S, SS> { > extends React.Component<JSONtoFormProps & P, S, SS> {
renderForm = (formContent: any) => { renderForm = (formContent: any) => {
const isAppSidebarEnabled = useIsAppSidebarEnabled();
return ( return (
// <MainContainer> // <MainContainer>
<FormContainer className="t--json-to-form-wrapper"> <FormContainer className="t--json-to-form-wrapper">
{this.props.featureFlags?.release_app_sidebar_enabled === {isAppSidebarEnabled === true ? null : <CloseEditor />}
true ? null : (
<CloseEditor />
)}
<FormContainerBody className="t--json-to-form-body"> <FormContainerBody className="t--json-to-form-body">
{formContent} {formContent}
</FormContainerBody> </FormContainerBody>

View File

@ -83,7 +83,7 @@ import { HelperBarInHeader } from "./HelpBarInHeader";
import { AppsmithLink } from "./AppsmithLink"; import { AppsmithLink } from "./AppsmithLink";
import { getIsFirstTimeUserOnboardingEnabled } from "selectors/onboardingSelectors"; import { getIsFirstTimeUserOnboardingEnabled } from "selectors/onboardingSelectors";
import { GetNavigationMenuData } from "./EditorName/NavigationMenuData"; import { GetNavigationMenuData } from "./EditorName/NavigationMenuData";
import { getIsAppSidebarEnabled } from "selectors/ideSelectors"; import { useIsAppSidebarEnabled } from "../../navigation/featureFlagHooks";
const { cloudHosting } = getAppsmithConfigs(); const { cloudHosting } = getAppsmithConfigs();
@ -123,7 +123,7 @@ export function EditorHeader() {
setShowPublishCommunityTemplateModal, setShowPublishCommunityTemplateModal,
] = useState(false); ] = useState(false);
const isAppSidebarEnabled = useSelector(getIsAppSidebarEnabled); const isAppSidebarEnabled = useIsAppSidebarEnabled();
const showEntityExplorerLock = !isAppSidebarEnabled && !signpostingEnabled; const showEntityExplorerLock = !isAppSidebarEnabled && !signpostingEnabled;

View File

@ -23,9 +23,8 @@ import { openAppSettingsPaneAction } from "actions/appSettingsPaneActions";
import { toast } from "design-system"; import { toast } from "design-system";
import type { ThemeProp } from "WidgetProvider/constants"; import type { ThemeProp } from "WidgetProvider/constants";
import { DISCORD_URL, DOCS_BASE_URL } from "constants/ThirdPartyConstants"; import { DISCORD_URL, DOCS_BASE_URL } from "constants/ThirdPartyConstants";
import { useFeatureFlag } from "../../../utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag";
import { protectedModeSelector } from "selectors/gitSyncSelectors"; import { protectedModeSelector } from "selectors/gitSyncSelectors";
import { useIsAppSidebarEnabled } from "../../../navigation/featureFlagHooks";
export interface NavigationMenuDataProps extends ThemeProp { export interface NavigationMenuDataProps extends ThemeProp {
editMode: typeof noop; editMode: typeof noop;
@ -38,9 +37,7 @@ export const GetNavigationMenuData = ({
}: NavigationMenuDataProps): MenuItemData[] => { }: NavigationMenuDataProps): MenuItemData[] => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const history = useHistory(); const history = useHistory();
const isAppSidebarEnabled = useFeatureFlag( const isAppSidebarEnabled = useIsAppSidebarEnabled();
FEATURE_FLAG.release_app_sidebar_enabled,
);
const isProtectedMode = useSelector(protectedModeSelector); const isProtectedMode = useSelector(protectedModeSelector);
const applicationId = useSelector(getCurrentApplicationId); const applicationId = useSelector(getCurrentApplicationId);

View File

@ -31,10 +31,9 @@ import {
saveExplorerStatus, saveExplorerStatus,
} from "@appsmith/pages/Editor/Explorer/helpers"; } from "@appsmith/pages/Editor/Explorer/helpers";
import { integrationEditorURL } from "@appsmith/RouteBuilder"; import { integrationEditorURL } from "@appsmith/RouteBuilder";
import { useFeatureFlag } from "../../../utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag";
import WalkthroughContext from "components/featureWalkthrough/walkthroughContext"; import WalkthroughContext from "components/featureWalkthrough/walkthroughContext";
import DatasourceStarterLayoutPrompt from "./Datasources/DatasourceStarterLayoutPrompt"; import DatasourceStarterLayoutPrompt from "./Datasources/DatasourceStarterLayoutPrompt";
import { useIsAppSidebarEnabled } from "../../../navigation/featureFlagHooks";
const NoEntityFoundSvg = importSvg( const NoEntityFoundSvg = importSvg(
async () => import("assets/svg/no_entities_found.svg"), async () => import("assets/svg/no_entities_found.svg"),
@ -97,9 +96,7 @@ function EntityExplorer({ isActive }: { isActive: boolean }) {
useContext(WalkthroughContext) || {}; useContext(WalkthroughContext) || {};
const applicationId = useSelector(getCurrentApplicationId); const applicationId = useSelector(getCurrentApplicationId);
const isDatasourcesOpen = getExplorerStatus(applicationId, "datasource"); const isDatasourcesOpen = getExplorerStatus(applicationId, "datasource");
const isAppSidebarEnabled = useFeatureFlag( const isAppSidebarEnabled = useIsAppSidebarEnabled();
FEATURE_FLAG.release_app_sidebar_enabled,
);
const closeWalkthrough = useCallback(() => { const closeWalkthrough = useCallback(() => {
if (isWalkthroughOpened && popFeature) { if (isWalkthroughOpened && popFeature) {

View File

@ -1,7 +1,6 @@
import React from "react"; import React from "react";
import WidgetsEditorEntityExplorer from "../../WidgetsEditorEntityExplorer"; import WidgetsEditorEntityExplorer from "../../WidgetsEditorEntityExplorer";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { getIsAppSidebarEnabled } from "selectors/ideSelectors";
import styled from "styled-components"; import styled from "styled-components";
import { Switch, useRouteMatch } from "react-router"; import { Switch, useRouteMatch } from "react-router";
import { SentryRoute } from "@appsmith/AppRouter"; import { SentryRoute } from "@appsmith/AppRouter";
@ -17,6 +16,7 @@ import AppSettingsPane from "./AppSettings";
import DataSidePane from "./DataSidePane"; import DataSidePane from "./DataSidePane";
import LibrarySidePane from "./LibrarySidePane"; import LibrarySidePane from "./LibrarySidePane";
import { inGuidedTour } from "selectors/onboardingSelectors"; import { inGuidedTour } from "selectors/onboardingSelectors";
import { useIsAppSidebarEnabled } from "../../../../navigation/featureFlagHooks";
const LeftPaneContainer = styled.div` const LeftPaneContainer = styled.div`
height: 100%; height: 100%;
@ -26,7 +26,7 @@ const LeftPaneContainer = styled.div`
`; `;
const LeftPane = () => { const LeftPane = () => {
const isAppSidebarEnabled = useSelector(getIsAppSidebarEnabled); const isAppSidebarEnabled = useIsAppSidebarEnabled();
const { path } = useRouteMatch(); const { path } = useRouteMatch();
const guidedTourEnabled = useSelector(inGuidedTour); const guidedTourEnabled = useSelector(inGuidedTour);
if (!isAppSidebarEnabled || guidedTourEnabled) { if (!isAppSidebarEnabled || guidedTourEnabled) {

View File

@ -3,13 +3,12 @@ import { BUILDER_PATH } from "constants/routes";
import { Route, Switch, useRouteMatch } from "react-router"; import { Route, Switch, useRouteMatch } from "react-router";
import * as Sentry from "@sentry/react"; import * as Sentry from "@sentry/react";
import routes from "./routes"; import routes from "./routes";
import { useSelector } from "react-redux"; import { useIsAppSidebarEnabled } from "../../../../navigation/featureFlagHooks";
import { getIsAppSidebarEnabled } from "selectors/ideSelectors";
const SentryRoute = Sentry.withSentryRouting(Route); const SentryRoute = Sentry.withSentryRouting(Route);
export const MainPane = (props: { id: string }) => { export const MainPane = (props: { id: string }) => {
const { path } = useRouteMatch(); const { path } = useRouteMatch();
const isAppSidebarEnabled = useSelector(getIsAppSidebarEnabled); const isAppSidebarEnabled = useIsAppSidebarEnabled();
return ( return (
<div <div
className="relative flex flex-col flex-1 overflow-auto z-2" className="relative flex flex-col flex-1 overflow-auto z-2"

View File

@ -1,8 +1,5 @@
import React, { useCallback, useState, useEffect } from "react"; import React, { useCallback, useState, useEffect } from "react";
import { import { getIsAppSidebarAnnouncementEnabled } from "selectors/ideSelectors";
getIsAppSidebarAnnouncementEnabled,
getIsAppSidebarEnabled,
} from "selectors/ideSelectors";
import { useSelector, useDispatch } from "react-redux"; import { useSelector, useDispatch } from "react-redux";
import styled from "styled-components"; import styled from "styled-components";
import SidebarButton from "./SidebarButton"; import SidebarButton from "./SidebarButton";
@ -20,6 +17,7 @@ import {
Button, Button,
} from "design-system"; } from "design-system";
import { inGuidedTour } from "selectors/onboardingSelectors"; import { inGuidedTour } from "selectors/onboardingSelectors";
import { useIsAppSidebarEnabled } from "../../../../navigation/featureFlagHooks";
const Container = styled.div` const Container = styled.div`
width: 50px; width: 50px;
@ -44,7 +42,7 @@ function Sidebar() {
const dispatch = useDispatch(); const dispatch = useDispatch();
const appState = useCurrentAppState(); const appState = useCurrentAppState();
const [isPopoverOpen, setIsPopoverOpen] = useState(true); const [isPopoverOpen, setIsPopoverOpen] = useState(true);
const isAppSidebarEnabled = useSelector(getIsAppSidebarEnabled); const isAppSidebarEnabled = useIsAppSidebarEnabled();
const isAppSidebarAnnouncementEnabled = useSelector( const isAppSidebarAnnouncementEnabled = useSelector(
getIsAppSidebarAnnouncementEnabled, getIsAppSidebarAnnouncementEnabled,
); );

View File

@ -3,7 +3,8 @@ import { selectFeatureFlags } from "@appsmith/selectors/featureFlagsSelectors";
export const getIsAppSidebarEnabled = createSelector( export const getIsAppSidebarEnabled = createSelector(
selectFeatureFlags, selectFeatureFlags,
(flags) => !!flags?.release_app_sidebar_enabled, (flags) =>
!!flags?.release_app_sidebar_enabled || flags?.rollout_app_sidebar_enabled,
); );
export const getIsAppSidebarAnnouncementEnabled = createSelector( export const getIsAppSidebarAnnouncementEnabled = createSelector(

View File

@ -45,7 +45,7 @@ import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
import { useLocation } from "react-router"; import { useLocation } from "react-router";
import { CANVAS_VIEWPORT } from "constants/componentClassNameConstants"; import { CANVAS_VIEWPORT } from "constants/componentClassNameConstants";
import { getLayoutSystemType } from "selectors/layoutSystemSelectors"; import { getLayoutSystemType } from "selectors/layoutSystemSelectors";
import { getIsAppSidebarEnabled } from "../../selectors/ideSelectors"; import { useIsAppSidebarEnabled } from "../../navigation/featureFlagHooks";
const GUTTER_WIDTH = 72; const GUTTER_WIDTH = 72;
export const AUTOLAYOUT_RESIZER_WIDTH_BUFFER = 40; export const AUTOLAYOUT_RESIZER_WIDTH_BUFFER = 40;
@ -79,7 +79,7 @@ export const useDynamicAppLayout = () => {
const queryParams = new URLSearchParams(search); const queryParams = new URLSearchParams(search);
const isEmbed = queryParams.get("embed"); const isEmbed = queryParams.get("embed");
const isNavbarVisibleInEmbeddedApp = queryParams.get("navbar"); const isNavbarVisibleInEmbeddedApp = queryParams.get("navbar");
const isAppSidebarEnabled = useSelector(getIsAppSidebarEnabled); const isAppSidebarEnabled = useIsAppSidebarEnabled();
const isPreviewing = isPreviewMode; const isPreviewing = isPreviewMode;