chore: remove feature flag for ramps (#26448)

## Description
PR to show ramps to everyone on CE, removing feature flag.

#### PR fixes following issue(s)
Fixes #26443

#### Media
> A video or a GIF is preferred. when using Loom, don’t embed because it
looks like it’s a GIF. instead, just link to the video
>
>
#### Type of change

- New feature (non-breaking change which adds functionality)

## Testing
>
#### How Has This Been Tested?
> Please describe the tests that you ran to verify your changes. Also
list any relevant details for your test configuration.
> Delete anything that is not relevant
- [x] Manual
- [ ] Jest
- [ ] Cypress
>
>
#### Test Plan
1. Give a non appsmith user Administrator rights -
[adminuser1@app.in](mailto:adminuser1@app.in) - administrator - able to
login with this user and see ramps for canvas/preview/deploy modes, on
Edit DS page and on Queries page
2. [devuser1@app.in](mailto:devuser1@app.in) - developer - able to login
with this user and see ramps for canvas/preview/deploy modes, on Edit DS
page and on Queries page
3. [viewuser1@app.in](mailto:viewuser1@app.in) - appviewer - able to
login with this user - and only launch the app - where no ramps are
visible and no switch env dropdown
4. Make application public - no ramps should be visible - and no switch
dropdown should be present
5. Gave above permissions to appsmith user as well and tried if same
behavior. Works fine.
6. Detailed cases - https://github.com/appsmithorg/TestSmith/issues/2489
>
>
#### Issues raised during DP testing
> Link issues raised during DP testing for better visiblity and tracking
(copy link from comments dropped on this PR)
>
>
>
## Checklist:
#### Dev activity
- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag


#### QA activity:
- [ ] [Speedbreak
features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-)
have been covered
- [ ] Test plan covers all impacted features and [areas of
interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-)
- [ ] Test plan has been peer reviewed by project stakeholders and other
QA members
- [x] Manually tested functionality on DP
- [ ] We had an implementation alignment call with stakeholders post QA
Round 2
- [ ] Cypress test cases have been added and approved by SDET/manual QA
- [ ] Added `Test Plan Approved` label after Cypress tests were reviewed
- [ ] Added `Test Plan Approved` label after JUnit tests were reviewed

---------

Co-authored-by: Aishwarya UR <aishwarya@appsmith.com>
This commit is contained in:
Ayush Pahwa 2023-09-05 15:23:44 +07:00 committed by GitHub
parent ac5262cbfc
commit 62d05cdba1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 48 additions and 112 deletions

View File

@ -59,7 +59,7 @@ Object.entries(widgetsToTest).forEach(([widgetSelector, testConfig]) => {
cy.updateCodeInput(PROPERTY_SELECTOR.text, testConfig.textBindingValue);
cy.closePropertyPane();
cy.get(".rc-select-selector").click({ force: true });
agHelper.GetNClick(".rc-select-selector", 0, true);
cy.wait(1000);
cy.get('.rc-select-item-option:contains("Blue")').click({ force: true });
cy.wait(1000);

View File

@ -280,8 +280,7 @@ function multiTreeSelectAndReset() {
}
function radiogroupAndReset() {
cy.get("input").last().click({ force: true });
cy.wait(1000);
_.agHelper.GetNClick("input", 1, true, 1000);
_.agHelper.GetNAssertElementText(
_.locators._textWidgetInDeployed,
"N",
@ -350,8 +349,7 @@ function checkboxGroupAndReset() {
}
function checkboxAndReset() {
cy.get("input").last().click({ force: true });
cy.wait(1000);
_.agHelper.GetNClick("input", 0, true, 1000);
_.agHelper.GetNAssertElementText(
_.locators._textWidgetInDeployed,
"false",

View File

@ -141,7 +141,7 @@ describe("App Theming funtionality", function () {
//Change the font //Commenting below since expanded by default
//cy.contains("Font").click({ force: true });
cy.get(".rc-select-selection-search-input").then(($elem) => {
_.agHelper.GetNClick(".rc-select-selection-search-input").then(($elem) => {
cy.get($elem).click({ force: true });
cy.wait(250);
cy.get(".rc-virtual-list-holder div")
@ -200,7 +200,7 @@ describe("App Theming funtionality", function () {
// cy.contains("Font")
// .click({ force: true })
// .wait(200);//Commenting below since expanded by default
cy.get(".rc-select-selection-search-input").then(($elem) => {
_.agHelper.GetNClick(".rc-select-selection-search-input").then(($elem) => {
cy.get($elem).click({ force: true });
cy.wait(250);
cy.get(".rc-virtual-list-holder div")

View File

@ -52,7 +52,7 @@ describe("Table Widget property pane feature validation", function () {
deployMode.DeployApp(locators._widgetInDeployed("tablewidget"));
table.WaitUntilTableLoad(0, 0, "v1");
// Change the Search text
cy.get(widgetsPage.searchField).type("Hello");
cy.get(widgetsPage.searchField).first().type("Hello");
// Verify the search text is changed
cy.get(commonlocators.toastmsg).contains("Search Text Changed");
deployMode.NavigateBacktoEditor();

View File

@ -82,7 +82,7 @@ describe("Table Widget V2 property pane feature validation", function () {
deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.TABLE));
table.WaitUntilTableLoad(0, 0, "v2");
// Change the Search text
cy.get(widgetsPage.searchField).type("Hello");
cy.get(widgetsPage.searchField).first().type("Hello");
// Verify the search text is changed
agHelper.ValidateToastMessage("Search Text Changed");
deployMode.NavigateBacktoEditor();

View File

@ -28,11 +28,11 @@ describe("Switch datasource", function () {
it("4. By switching datasources execute a query with both the datasources", function () {
dataSources.CreateQueryFromActiveTab(dsName_1);
cy.get(".rc-select-show-arrow").click();
agHelper.GetNClick(".rc-select-show-arrow");
cy.contains(".rc-select-item-option-content", dsName_2).click().wait(1000);
cy.runQuery();
// Confirm mongo datasource is not present in the switch datasources dropdown
cy.get(".rc-select-show-arrow").click();
agHelper.GetNClick(".rc-select-show-arrow");
cy.get(".rc-select-item-option-content").should("not.have", MongoDB);
});

View File

@ -1,6 +1,4 @@
import React, { useEffect, useState } from "react";
import { datasourceEnvEnabled } from "@appsmith/selectors/featureFlagsSelectors";
import { useSelector } from "react-redux";
import styled from "styled-components";
import { Link, Tag, Text, Tooltip } from "design-system";
import {
@ -19,6 +17,7 @@ import {
RampFeature,
RampSection,
} from "utils/ProductRamps/RampsControlList";
import { useSelector } from "react-redux";
const Container = styled.div`
display: flex;
@ -54,12 +53,10 @@ const TooltipLink = styled(Link)`
`;
type DSDataFilterProps = {
datasourceId: string;
updateFilter: (
id: string,
name: string,
userPermissions: string[],
showFilterPane: boolean,
) => boolean;
pluginType: string;
pluginName: string;
@ -90,14 +87,9 @@ const environments: Array<EnvironmentType> = [
},
];
function DSDataFilter({
isInsideReconnectModal,
updateFilter,
viewMode,
}: DSDataFilterProps) {
function DSDataFilter({ isInsideReconnectModal, viewMode }: DSDataFilterProps) {
const [showFilterPane, setShowFilterPane] = useState(false);
const datasourceEnv: boolean = useSelector(datasourceEnvEnabled);
const showRampSelector = showProductRamps(RAMP_NAME.MULTIPLE_ENV);
const showRampSelector = showProductRamps(RAMP_NAME.MULTIPLE_ENV, true);
const canShowRamp = useSelector(showRampSelector);
const rampLinkSelector = getRampLink({
@ -110,7 +102,6 @@ function DSDataFilter({
useEffect(() => {
const isRenderAllowed =
environments.length > 0 &&
datasourceEnv &&
canShowRamp &&
!viewMode &&
!isInsideReconnectModal;
@ -118,16 +109,6 @@ function DSDataFilter({
if (showFilterPane !== isRenderAllowed) setShowFilterPane(isRenderAllowed);
// If there are no environments, do nothing
if (!environments.length) return;
const defaultSelectedEnvironment = environments[0];
const updateSuccess = updateFilter(
defaultSelectedEnvironment.id,
defaultSelectedEnvironment.name,
defaultSelectedEnvironment?.userPermissions || [],
isRenderAllowed,
);
if (!updateSuccess) return;
}, [environments.length, viewMode, isInsideReconnectModal]);
if (!showFilterPane) return null;

View File

@ -1,6 +1,5 @@
import React, { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { datasourceEnvEnabled } from "@appsmith/selectors/featureFlagsSelectors";
import styled from "styled-components";
import { Icon, Link, Option, Select, Text, Tooltip } from "design-system";
import { capitalizeFirstLetter } from "utils/helpers";
@ -77,8 +76,7 @@ const TooltipLink = styled(Link)`
export default function SwitchEnvironment({}: Props) {
const [diableSwitchEnvironment, setDiableSwitchEnvironment] = useState(false);
// Fetching feature flags from the store and checking if the feature is enabled
const allowedToRender = useSelector(datasourceEnvEnabled);
const showRampSelector = showProductRamps(RAMP_NAME.MULTIPLE_ENV);
const showRampSelector = showProductRamps(RAMP_NAME.MULTIPLE_ENV, true);
const canShowRamp = useSelector(showRampSelector);
const rampLinkSelector = getRampLink({
section: RampSection.BottomBarEnvSwitcher,
@ -97,7 +95,7 @@ export default function SwitchEnvironment({}: Props) {
//this parameter helps us to differentiate between the two.
const isDatasourceViewMode = useSelector(isDatasourceInViewMode);
if (!allowedToRender || !canShowRamp) return null;
if (!canShowRamp) return null;
const renderEnvOption = (env: EnvironmentType) => {
return (

View File

@ -7,6 +7,10 @@ import {
RAMP_FOR_ROLES,
} from "utils/ProductRamps/RampsControlList";
import type { EnvTypes } from "utils/ProductRamps/RampTypes";
import {
isPermitted,
PERMISSION_TYPE,
} from "@appsmith/utils/permissionHelpers";
const { cloudHosting, pricingUrl } = getAppsmithConfigs();
@ -27,10 +31,12 @@ export const getRampLink = ({
return `${RAMP_LINK_TO}&feature=${feature}&section=${section}`;
});
export const showProductRamps = (rampName: string) =>
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const showProductRamps = (rampName: string, useCESelector = false) =>
createSelector(uiState, (ui) => {
function getUserRoleInWorkspace() {
const { currentUser } = ui?.users;
const { currentApplication } = ui?.applications;
const isSuperUser = currentUser?.isSuperUser;
if (isSuperUser) return RAMP_FOR_ROLES.SUPER_USER;
const workspaceUsers = ui?.workspaces?.workspaceUsers;
@ -47,6 +53,17 @@ export const showProductRamps = (rampName: string) =>
}
}
}
} else if (
!!currentApplication &&
currentApplication.hasOwnProperty("userPermissions") &&
!!currentApplication.userPermissions
) {
return isPermitted(
currentApplication.userPermissions,
PERMISSION_TYPE.MANAGE_APPLICATION,
)
? RAMP_FOR_ROLES.DEVELOPER
: RAMP_FOR_ROLES.APP_VIEWER;
}
}

View File

@ -1,3 +1,3 @@
import DSDataFilter from "ce/components/editorComponents/DSDataFilter";
import DSDataFilter from "ce/components/DSDataFilter";
export default DSDataFilter;

View File

@ -51,7 +51,6 @@ import {
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { RAMP_NAME } from "utils/ProductRamps/RampsControlList";
import { showProductRamps } from "@appsmith/selectors/rampSelectors";
import { isCEMode } from "@appsmith/utils";
const AppViewerBody = styled.section<{
hasPages: boolean;
@ -112,15 +111,14 @@ function AppViewer(props: Props) {
});
const focusRef = useWidgetFocus();
const showRampSelector = showProductRamps(RAMP_NAME.MULTIPLE_ENV);
const showRampSelector = showProductRamps(RAMP_NAME.MULTIPLE_ENV, true);
const canShowRamp = useSelector(showRampSelector);
const workspaceId = currentApplicationDetails?.workspaceId || "";
const showBottomBar = useSelector((state: AppState) => {
return (
areEnvironmentsFetched(state, workspaceId) &&
datasourceEnvEnabled(state) &&
(isCEMode() ? canShowRamp : true)
(datasourceEnvEnabled(state) || canShowRamp)
);
});

View File

@ -41,7 +41,6 @@ interface DatasourceDBEditorProps extends JSONtoFormProps {
datasource: Datasource;
hiddenHeader?: boolean;
datasourceName?: string;
showFilterComponent: boolean;
isEnabledForDSViewModeSchema: boolean;
isDatasourceValid: boolean;
isPluginAllowedToPreviewData: boolean;
@ -52,7 +51,6 @@ type Props = DatasourceDBEditorProps &
InjectedFormProps<Datasource, DatasourceDBEditorProps>;
export const Form = styled.form<{
showFilterComponent: boolean;
viewMode: boolean;
}>`
display: flex;
@ -61,7 +59,7 @@ export const Form = styled.form<{
!props.viewMode && `height: ${`calc(100% - ${props?.theme.backBanner})`};`}
overflow-y: scroll;
padding-bottom: 20px;
margin-left: ${(props) => (props.showFilterComponent ? "24px" : "0px")};
margin-left: ${(props) => (props.viewMode ? "0px" : "24px")};
`;
export const ViewModeWrapper = styled.div`
@ -108,7 +106,6 @@ class DatasourceDBEditor extends JSONtoForm<Props> {
formConfig,
messages,
pluginType,
showFilterComponent,
viewMode,
} = this.props;
@ -117,7 +114,6 @@ class DatasourceDBEditor extends JSONtoForm<Props> {
onSubmit={(e) => {
e.preventDefault();
}}
showFilterComponent={showFilterComponent}
viewMode={viewMode}
>
{messages &&

View File

@ -70,7 +70,6 @@ interface DatasourceRestApiEditorProps {
formMeta: any;
messages?: Array<string>;
datasourceName: string;
showFilterComponent: boolean;
createDatasource: (
data: Datasource,
onSuccess?: ReduxAction<unknown>,
@ -259,7 +258,6 @@ class DatasourceRestAPIEditor extends React.Component<Props> {
onSubmit={(e) => {
e.preventDefault();
}}
showFilterComponent={this.props.showFilterComponent}
viewMode={this.props.viewMode}
>
{this.renderEditor()}

View File

@ -161,18 +161,17 @@ export const DSEditorWrapper = styled.div`
`;
export const CalloutContainer = styled.div<{
isSideBarPresent: boolean;
viewMode: boolean;
}>`
width: 30vw;
width: 30vw;
margin-top: 24px;
margin-left ${(props) => (props.isSideBarPresent ? "24px" : "0px")}
margin-left: ${(props) => (!props.viewMode ? "24px" : "0px")};
`;
export type DatasourceFilterState = {
id: string;
name: string;
userPermissions: string[];
showFilterPane: boolean;
};
/*
@ -232,7 +231,6 @@ class DatasourceEditorRouter extends React.Component<Props, State> {
id: DEFAULT_ENV_ID,
name: "",
userPermissions: [],
showFilterPane: false,
},
unblock: () => {
return undefined;
@ -509,12 +507,7 @@ class DatasourceEditorRouter extends React.Component<Props, State> {
}
}
updateFilter = (
id: string,
name: string,
userPermissions: string[],
showFilterPane: boolean,
) => {
updateFilter = (id: string, name: string, userPermissions: string[]) => {
if (id.length > 0 && this.state.filterParams.id !== id) {
if (
!isEmpty(this.props.formData) &&
@ -525,36 +518,18 @@ class DatasourceEditorRouter extends React.Component<Props, State> {
showDialog: true,
switchFilterBlocked: true,
navigation: () => {
this.updateFilterSuccess(id, name, userPermissions, showFilterPane);
this.updateFilterSuccess(id, name, userPermissions);
},
});
return false;
} else {
this.props.resetForm(this.props.formName);
}
return this.updateFilterSuccess(
id,
name,
userPermissions,
showFilterPane,
);
return this.updateFilterSuccess(id, name, userPermissions);
} else if (
!isStorageEnvironmentCreated(this.props.formData as Datasource, id)
) {
return this.updateFilterSuccess(
id,
name,
userPermissions,
showFilterPane,
);
} else if (showFilterPane !== this.state.filterParams.showFilterPane) {
// In case just the viewmode changes but the id remains the same
this.setState({
filterParams: {
...this.state.filterParams,
showFilterPane,
},
});
return this.updateFilterSuccess(id, name, userPermissions);
}
return true;
};
@ -563,7 +538,6 @@ class DatasourceEditorRouter extends React.Component<Props, State> {
id: string,
name: string,
userPermissions: string[],
showFilterPane: boolean,
) => {
onUpdateFilterSuccess(id);
const { datasourceStorages } = this.props.datasource as Datasource;
@ -629,7 +603,6 @@ class DatasourceEditorRouter extends React.Component<Props, State> {
id,
name,
userPermissions,
showFilterPane,
},
});
this.blockRoutes();
@ -675,7 +648,7 @@ class DatasourceEditorRouter extends React.Component<Props, State> {
// function to render toast message.
renderToast() {
const { datasource } = this.props;
const { datasource, viewMode } = this.props;
const environmentId = this.getEnvironmentId() || "";
const path = `datasourceStorages.${environmentId}.toastMessage`;
const toastMessage = this.decodeToastMessage(
@ -685,7 +658,7 @@ class DatasourceEditorRouter extends React.Component<Props, State> {
);
if (toastMessage.message)
return (
<CalloutContainer isSideBarPresent={!!this.state.filterParams.name}>
<CalloutContainer viewMode={viewMode}>
<Callout
isClosable
kind={toastMessage.kind as CalloutKind}
@ -744,7 +717,6 @@ class DatasourceEditorRouter extends React.Component<Props, State> {
pageId={pageId}
pluginName={pluginName}
pluginPackageName={pluginPackageName}
showFilterComponent={this.state.filterParams.showFilterPane}
/>
{this.renderSaveDisacardModal()}
</>
@ -768,7 +740,6 @@ class DatasourceEditorRouter extends React.Component<Props, State> {
pageId={pageId}
pluginType={pluginType}
setupConfig={this.setupConfig}
showFilterComponent={this.state.filterParams.showFilterPane}
viewMode={viewMode && !isInsideReconnectModal}
/>
{this.renderSaveDisacardModal()}
@ -886,7 +857,6 @@ class DatasourceEditorRouter extends React.Component<Props, State> {
<ResizerContentContainer className="db-form-resizer-content">
<DSEditorWrapper>
<DSDataFilter
datasourceId={datasourceId}
filterId={this.state.filterParams.id}
isInsideReconnectModal={!!isInsideReconnectModal}
pluginName={pluginName}
@ -918,7 +888,6 @@ class DatasourceEditorRouter extends React.Component<Props, State> {
pluginPackageName={pluginPackageName}
pluginType={pluginType as PluginType}
setDatasourceViewMode={setDatasourceViewMode}
showFilterComponent={this.state.filterParams.showFilterPane}
triggerSave={triggerSave}
viewMode={viewMode}
/>

View File

@ -244,7 +244,6 @@ class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
id: "",
name: "",
userPermissions: [],
showFilterPane: false,
},
unblock: () => {
return undefined;
@ -330,17 +329,8 @@ class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
}
}
updateFilter(
id: string,
name: string,
userPermissions: string[],
showFilterPane: boolean,
) {
if (
this.state.filterParams.id === id &&
this.state.filterParams.showFilterPane === showFilterPane
)
return false;
updateFilter(id: string, name: string, userPermissions: string[]) {
if (this.state.filterParams.id === id) return false;
AnalyticsUtil.logEvent("SWITCH_ENVIRONMENT", {
fromEnvId: this.state.filterParams.id,
@ -354,7 +344,6 @@ class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
id,
name,
userPermissions,
showFilterPane,
},
});
return true;
@ -555,7 +544,6 @@ class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
<ResizerContentContainer className="db-form-resizer-content">
<DSEditorWrapper>
<DSDataFilter
datasourceId={datasourceId}
filterId={this.state.filterParams.id}
isInsideReconnectModal={!!isInsideReconnectModal}
pluginName={plugin?.name || ""}
@ -568,7 +556,6 @@ class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
onSubmit={(e) => {
e.preventDefault();
}}
showFilterComponent={this.state.filterParams.showFilterPane}
viewMode={viewMode}
>
{(!viewMode || createFlow || isInsideReconnectModal) && (
@ -658,7 +645,6 @@ class DatasourceSaaSEditor extends JSONtoForm<Props, State> {
scopeValue={scopeValue}
setDatasourceViewMode={setDatasourceViewMode}
shouldDisplayAuthMessage={!isGoogleSheetPlugin}
showFilterComponent={this.state.filterParams.showFilterPane}
triggerSave={this.props.isDatasourceBeingSavedFromPopup}
viewMode={viewMode}
/>

View File

@ -65,7 +65,6 @@ interface Props {
triggerSave?: boolean;
isFormDirty?: boolean;
scopeValue?: string;
showFilterComponent: boolean;
onCancel: () => void;
}
@ -96,13 +95,11 @@ export const DatasourceButtonType: Record<
export const ActionButton = styled(Button)<{
floatLeft: boolean;
showFilterComponent: boolean;
}>`
&&& {
// Pulling button to the left if floatLeft is set as true
margin-right: ${(props) => (props.floatLeft ? "auto" : "9px")};
// If filter component is present, then we need to push the button to the right
margin-left: ${(props) => (props.showFilterComponent ? "24px" : "0px")};
margin-left: ${(props) => (props.floatLeft ? "16px" : "0px")};
}
`;
@ -151,7 +148,6 @@ function DatasourceAuth({
isFormDirty,
scopeValue,
isInsideReconnectModal,
showFilterComponent,
onCancel,
}: Props) {
const shouldRender = !viewMode || isInsideReconnectModal;
@ -331,7 +327,6 @@ function DatasourceAuth({
key={buttonType}
kind="secondary"
onClick={handleDatasourceTest}
showFilterComponent={showFilterComponent}
size="md"
>
{createMessage(TEST_BUTTON_TEXT)}