PromucFlow_constructor/app/client/src/pages/common/PageHeader.tsx
Abhinav Jha d6f2d7ed7a
fix: Changes for Anvil Alpha release (#34211)
## Description
This PR makes the following changes to prepare for the Anvil Alpha
release
- Add a toggle to the applications page header that allows us to toggle
the Anvil feature flag from the UI.
- Enable the above toggle if the toggle feature flag is enabled
- When the toggle is enabled the following changes occur in the UX
- Import application via Git is disabled and a callout is shown to the
user
  - Git features are unavailable for users in Anvil applications
- Copying and pasting widgets between two different layout systems is
disabled and a warning message is shown to the user
- Partial import export of widgets between two different layout systems
is disabled and a warning message is shown to the user
  - CRUD page generation is disabled from datasources
- Anvil applications and classic applications are separated into their
own sections in the workspace.
- In case any of the above sections are empty, an appropriate message is
displayed in the empty section

### Screenshots

![Alpha
Toggle](https://github.com/appsmithorg/appsmith/assets/103687/6bc887e7-eff6-41c2-98a9-ddd5826d4d1a)
![Import from Git
Callout](https://github.com/appsmithorg/appsmith/assets/103687/42cd05c8-da90-4e2e-93be-f4038b1f21f3)

![Paste-callout](https://github.com/appsmithorg/appsmith/assets/103687/031ee732-4ad5-4a03-88bf-d02bab1d3faa)
![Screenshot from 2024-07-03
14-39-13](https://github.com/appsmithorg/appsmith/assets/103687/037585d0-1470-47f7-81b2-c0cf4c7901f9)

### Other details  
- Toggle feature flag - `release_anvil_toggle_enabled`
- Anvil feature flag - `release_anvil_enabled`


Fixes #34578 
Fixes #34576 
Fixes #34575 
Fixes #33718

## Automation

/ok-to-test tags="@tag.All"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!CAUTION]
> 🔴 🔴 🔴 Some tests have failed.
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/9793128338>
> Commit: 09401272c1d52c915aee3b68925406f2f5f962ba
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=9793128338&attempt=2&selectiontype=test&testsstatus=failed&specsstatus=fail"
target="_blank">Cypress dashboard</a>.
> Tags: @tag.All
> The following are new failures, please fix them before merging the PR:
<ol>
>
<li>cypress/e2e/Regression/ClientSide/PartialImportExport/PartialExport_spec.ts</ol>
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/identified-flaky-tests-65890b3c81d7400d08fa9ee3?branch=master"
target="_blank">List of identified flaky tests</a>.
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
  - Added Anvil toggle functionality to the page header.
  - Introduced layout compatibility checks for pasting widgets.

- **Enhancements**
  - Updated widget paste action to verify layout system compatibility.
- Improved handling and processing of user-uploaded JSON files for
widget import.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2024-07-05 13:57:59 +05:30

136 lines
4.4 KiB
TypeScript

import React, { useEffect } from "react";
import { useRouteMatch } from "react-router-dom";
import { connect, useDispatch, useSelector } from "react-redux";
import { getCurrentUser } from "selectors/usersSelectors";
import styled from "styled-components";
import StyledHeader from "components/designSystems/appsmith/StyledHeader";
import type { AppState } from "@appsmith/reducers";
import type { User } from "constants/userConstants";
import { useIsMobileDevice } from "utils/hooks/useDeviceDetect";
import { getTemplateNotificationSeenAction } from "actions/templateActions";
import { shouldShowLicenseBanner } from "@appsmith/selectors/tenantSelectors";
import { Banner } from "@appsmith/utils/licenseHelpers";
import bootIntercom from "utils/bootIntercom";
import EntitySearchBar from "pages/common/SearchBar/EntitySearchBar";
import { Switch, Tooltip } from "design-system";
import { getIsAnvilLayoutEnabled } from "layoutSystems/anvil/integrations/selectors";
import { useFeatureFlag } from "utils/hooks/useFeatureFlag";
import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag";
import { setFeatureFlagOverrideValues } from "utils/storage";
import { updateFeatureFlagOverrideAction } from "actions/featureFlagActions";
const StyledPageHeader = styled(StyledHeader)<{
hideShadow?: boolean;
isMobile?: boolean;
showSeparator?: boolean;
isBannerVisible?: boolean;
}>`
justify-content: space-between;
background: var(--ads-v2-color-bg);
height: 48px;
color: var(--ads-v2-color-bg);
position: fixed;
top: 0;
z-index: var(--ads-v2-z-index-9);
border-bottom: 1px solid var(--ads-v2-color-border);
${({ isMobile }) =>
isMobile &&
`
padding: 0 12px;
padding-left: 10px;
`};
${({ isBannerVisible, isMobile }) =>
isBannerVisible ? (isMobile ? `top: 70px;` : `top: 40px;`) : ""};
/* intentionally "hacky" approach to show the Anvil toggle in the header. This will be removed once all features work well with Anvil */
& .ads-v2-switch {
display: block;
width: 100%;
position: absolute;
left: 175px;
top: 12px;
width: 30px;
& > label {
min-width: 0;
flex-direction: row-reverse;
}
}
`;
interface PageHeaderProps {
user?: User;
hideShadow?: boolean;
showSeparator?: boolean;
hideEditProfileLink?: boolean;
}
export function PageHeader(props: PageHeaderProps) {
const { user } = props;
const dispatch = useDispatch();
const isMobile = useIsMobileDevice();
useEffect(() => {
dispatch(getTemplateNotificationSeenAction());
}, []);
useEffect(() => {
bootIntercom(user);
}, [user?.email]);
const showBanner = useSelector(shouldShowLicenseBanner);
const isHomePage = useRouteMatch("/applications")?.isExact;
const isLicensePage = useRouteMatch("/license")?.isExact;
const isAnvilEnabled = useSelector(getIsAnvilLayoutEnabled);
const shouldShowAnvilToggle = useFeatureFlag(
FEATURE_FLAG.release_anvil_toggle_enabled,
);
/*
If Anvil toggle is enabled, the switch allows us to enable or disable Anvil
We pass the anvil feature's value via the toggle. We also passthrough the original
anvil toggle feature flag value as-is.
*/
function handleAnvilToggle(isSelected: boolean) {
const featureFlags = {
release_anvil_enabled: isSelected,
release_anvil_toggle_enabled: shouldShowAnvilToggle,
};
dispatch(updateFeatureFlagOverrideAction(featureFlags));
setFeatureFlagOverrideValues(featureFlags);
}
return (
<>
<Banner />
<StyledPageHeader
data-testid="t--appsmith-page-header"
hideShadow={props.hideShadow || false}
isBannerVisible={showBanner && (isHomePage || isLicensePage)}
isMobile={isMobile}
showSeparator={props.showSeparator || false}
>
{
// Based on a feature flag, show the switch that enables/disables Anvil
shouldShowAnvilToggle && (
<Switch isSelected={isAnvilEnabled} onChange={handleAnvilToggle}>
<Tooltip content="Toggles Anvil Layout System" trigger="hover">
<b>&alpha;</b>
</Tooltip>
</Switch>
)
}
<EntitySearchBar user={user} />
</StyledPageHeader>
</>
);
}
const mapStateToProps = (state: AppState) => ({
user: getCurrentUser(state),
hideShadow: state.ui.theme.hideHeaderShadow,
showSeparator: state.ui.theme.showHeaderSeparator,
});
export default connect(mapStateToProps)(PageHeader);