Fix edit and fork buttons visible simultaneously on the viewer header (#3723)
This commit is contained in:
parent
c37adc0a4d
commit
d8f2211b70
|
|
@ -4,7 +4,6 @@ import { Helmet } from "react-helmet";
|
|||
import styled, { ThemeProvider } from "styled-components";
|
||||
import StyledHeader from "components/designSystems/appsmith/StyledHeader";
|
||||
import AppsmithLogo from "assets/images/appsmith_logo.png";
|
||||
import { createMessage, EDIT_APP, FORK_APP, SIGN_IN } from "constants/messages";
|
||||
import {
|
||||
isPermitted,
|
||||
PERMISSION_TYPE,
|
||||
|
|
@ -33,7 +32,7 @@ import ProfileDropdown from "pages/common/ProfileDropdown";
|
|||
import { Profile } from "pages/common/ProfileImage";
|
||||
import PageTabsContainer from "./PageTabsContainer";
|
||||
import { getThemeDetails, ThemeMode } from "selectors/themeSelectors";
|
||||
import ForkApplicationModal from "pages/Applications/ForkApplicationModal";
|
||||
import getAppViewerHeaderCTA from "./getAppViewerHeaderCTA";
|
||||
|
||||
const HeaderWrapper = styled(StyledHeader)<{ hasPages: boolean }>`
|
||||
box-shadow: unset;
|
||||
|
|
@ -107,17 +106,6 @@ const AppsmithLogoImg = styled.img`
|
|||
max-width: 110px;
|
||||
`;
|
||||
|
||||
const Cta = styled(Button)`
|
||||
${(props) => getTypographyByKey(props, "btnLarge")}
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
const ForkButton = styled(Cta)`
|
||||
svg {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
height: ${(props) => `calc(${props.theme.smallHeaderHeight})`};
|
||||
`;
|
||||
const HeaderRightItemContainer = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -162,42 +150,14 @@ export const AppViewerHeader = (props: AppViewerHeaderProps) => {
|
|||
const forkUrl = `${AUTH_LOGIN_URL}?redirectUrl=${window.location.href}/fork`;
|
||||
const loginUrl = `${AUTH_LOGIN_URL}?redirectUrl=${window.location.href}`;
|
||||
|
||||
let CTA = null;
|
||||
|
||||
if (props.url && canEdit) {
|
||||
CTA = (
|
||||
<Cta
|
||||
className="t--back-to-editor"
|
||||
href={props.url}
|
||||
icon="arrow-left"
|
||||
text={createMessage(EDIT_APP)}
|
||||
/>
|
||||
);
|
||||
} else if (
|
||||
currentApplicationDetails?.forkingEnabled &&
|
||||
currentApplicationDetails?.isPublic &&
|
||||
currentUser?.username === ANONYMOUS_USERNAME
|
||||
) {
|
||||
CTA = (
|
||||
<ForkButton
|
||||
className="t--fork-app"
|
||||
href={forkUrl}
|
||||
text={createMessage(FORK_APP)}
|
||||
icon="fork"
|
||||
/>
|
||||
);
|
||||
} else if (
|
||||
currentApplicationDetails?.isPublic &&
|
||||
currentUser?.username === ANONYMOUS_USERNAME
|
||||
) {
|
||||
CTA = (
|
||||
<Cta
|
||||
className="t--sign-in"
|
||||
href={loginUrl}
|
||||
text={createMessage(SIGN_IN)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
const CTA = getAppViewerHeaderCTA({
|
||||
url: props.url,
|
||||
canEdit,
|
||||
currentApplicationDetails,
|
||||
currentUser,
|
||||
forkUrl,
|
||||
loginUrl,
|
||||
});
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={props.lightTheme}>
|
||||
|
|
@ -232,15 +192,6 @@ export const AppViewerHeader = (props: AppViewerHeaderProps) => {
|
|||
title={currentApplicationDetails.name}
|
||||
canOutsideClickClose={true}
|
||||
/>
|
||||
{currentUser &&
|
||||
currentUser.username !== ANONYMOUS_USERNAME &&
|
||||
currentApplicationDetails?.forkingEnabled && (
|
||||
<div className="header__application-fork-btn-wrapper">
|
||||
<ForkApplicationModal
|
||||
applicationId={currentApplicationDetails.id}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{CTA && (
|
||||
<HeaderRightItemContainer>{CTA}</HeaderRightItemContainer>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,143 @@
|
|||
import { unmountComponentAtNode } from "react-dom";
|
||||
import { render } from "test/testUtils";
|
||||
import getAppViewerHeaderCTA from "./getAppViewerHeaderCTA";
|
||||
import { waitFor } from "@testing-library/dom";
|
||||
import { ANONYMOUS_USERNAME } from "constants/userConstants";
|
||||
|
||||
const sampleProps = {
|
||||
url:
|
||||
"/applications/606ad816c7a35467ac887f87/pages/606ad816c7a35467ac887f89/edit",
|
||||
canEdit: true,
|
||||
currentApplicationDetails: {
|
||||
id: "606ad816c7a35467ac887f87",
|
||||
userPermissions: [
|
||||
"manage:applications",
|
||||
"canComment:applications",
|
||||
"read:applications",
|
||||
"publish:applications",
|
||||
"makePublic:applications",
|
||||
],
|
||||
name: "Untitled application 1",
|
||||
organizationId: "606ad7eec7a35467ac887f84",
|
||||
isPublic: false,
|
||||
pages: [
|
||||
{
|
||||
id: "606ad816c7a35467ac887f89",
|
||||
isDefault: true,
|
||||
default: true,
|
||||
},
|
||||
],
|
||||
appIsExample: false,
|
||||
color: "#C03C3C",
|
||||
icon: "flag",
|
||||
new: false,
|
||||
},
|
||||
currentUser: {
|
||||
userPermissions: [],
|
||||
email: "b1@appsmith.com",
|
||||
source: "FORM",
|
||||
isEnabled: true,
|
||||
currentOrganizationId: "606ad7eec7a35467ac887f84",
|
||||
organizationIds: ["606ad7eec7a35467ac887f84"],
|
||||
groupIds: [],
|
||||
permissions: [],
|
||||
isAnonymous: false,
|
||||
username: "b1@appsmith.com",
|
||||
accountNonExpired: true,
|
||||
accountNonLocked: true,
|
||||
credentialsNonExpired: true,
|
||||
claims: {},
|
||||
enabled: true,
|
||||
address: {},
|
||||
new: true,
|
||||
},
|
||||
forkUrl:
|
||||
"/user/login?redirectUrl=https://dev.appsmith.com/applications/606ad816c7a35467ac887f87/pages/606ad816c7a35467ac887f89/fork",
|
||||
loginUrl:
|
||||
"/user/login?redirectUrl=https://dev.appsmith.com/applications/606ad816c7a35467ac887f87/pages/606ad816c7a35467ac887f89",
|
||||
};
|
||||
|
||||
let container: any = null;
|
||||
describe("get app viewer header CTA", () => {
|
||||
beforeEach(async () => {
|
||||
// setup a DOM element as a render target
|
||||
container = document.createElement("div");
|
||||
document.body.appendChild(container);
|
||||
});
|
||||
it("renders the edit app button and does not render the fork app button", async () => {
|
||||
const CTA = getAppViewerHeaderCTA(sampleProps);
|
||||
if (CTA) {
|
||||
render(CTA);
|
||||
const result = await waitFor(() =>
|
||||
document.querySelector(".t--back-to-editor"),
|
||||
);
|
||||
expect(!!result).toBeTruthy();
|
||||
|
||||
const forkButton = await waitFor(() =>
|
||||
document.querySelector(".t--fork-app"),
|
||||
);
|
||||
expect(!!forkButton).toBeFalsy();
|
||||
}
|
||||
});
|
||||
it("renders the fork app button", async () => {
|
||||
const CTA = getAppViewerHeaderCTA({
|
||||
...sampleProps,
|
||||
canEdit: false,
|
||||
currentApplicationDetails: {
|
||||
...sampleProps.currentApplicationDetails,
|
||||
forkingEnabled: true,
|
||||
isPublic: true,
|
||||
},
|
||||
currentUser: {
|
||||
...sampleProps.currentUser,
|
||||
username: ANONYMOUS_USERNAME,
|
||||
},
|
||||
});
|
||||
if (CTA) {
|
||||
render(CTA);
|
||||
const result = await waitFor(() =>
|
||||
document.querySelector(".t--fork-app"),
|
||||
);
|
||||
expect(!!result).toBeTruthy();
|
||||
}
|
||||
});
|
||||
it("renders the fork app link", async () => {
|
||||
const CTA = getAppViewerHeaderCTA({
|
||||
...sampleProps,
|
||||
canEdit: false,
|
||||
currentApplicationDetails: {
|
||||
...sampleProps.currentApplicationDetails,
|
||||
forkingEnabled: true,
|
||||
isPublic: true,
|
||||
},
|
||||
});
|
||||
if (CTA) {
|
||||
render(CTA);
|
||||
const result = await waitFor(() =>
|
||||
document.querySelector(".t--fork-btn-wrapper"),
|
||||
);
|
||||
expect(!!result).toBeTruthy();
|
||||
}
|
||||
});
|
||||
it("renders the sign in link", async () => {
|
||||
const CTA = getAppViewerHeaderCTA({
|
||||
...sampleProps,
|
||||
canEdit: false,
|
||||
currentApplicationDetails: {
|
||||
...sampleProps.currentApplicationDetails,
|
||||
isPublic: true,
|
||||
},
|
||||
});
|
||||
if (CTA) {
|
||||
render(CTA);
|
||||
const result = await waitFor(() => document.querySelector(".t--sign-in"));
|
||||
expect(!!result).toBeTruthy();
|
||||
}
|
||||
});
|
||||
afterEach(() => {
|
||||
// cleanup on exiting
|
||||
unmountComponentAtNode(container);
|
||||
container.remove();
|
||||
container = null;
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { createMessage, EDIT_APP, FORK_APP, SIGN_IN } from "constants/messages";
|
||||
import { ANONYMOUS_USERNAME } from "constants/userConstants";
|
||||
import { getTypographyByKey } from "constants/DefaultTheme";
|
||||
import Button from "components/ads/Button";
|
||||
import ForkApplicationModal from "pages/Applications/ForkApplicationModal";
|
||||
|
||||
const Cta = styled(Button)`
|
||||
${(props) => getTypographyByKey(props, "btnLarge")}
|
||||
height: 100%;
|
||||
`;
|
||||
|
||||
const ForkButton = styled(Cta)`
|
||||
svg {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
height: ${(props) => `calc(${props.theme.smallHeaderHeight})`};
|
||||
`;
|
||||
|
||||
const getAppViewerHeaderCTA = ({
|
||||
url,
|
||||
canEdit,
|
||||
currentApplicationDetails,
|
||||
currentUser,
|
||||
forkUrl,
|
||||
loginUrl,
|
||||
}: any) => {
|
||||
let CTA = null;
|
||||
|
||||
if (url && canEdit) {
|
||||
CTA = (
|
||||
<Cta
|
||||
className="t--back-to-editor"
|
||||
href={url}
|
||||
icon="arrow-left"
|
||||
text={createMessage(EDIT_APP)}
|
||||
/>
|
||||
);
|
||||
} else if (
|
||||
currentApplicationDetails?.forkingEnabled &&
|
||||
currentApplicationDetails?.isPublic
|
||||
) {
|
||||
if (currentUser?.username === ANONYMOUS_USERNAME) {
|
||||
CTA = (
|
||||
<ForkButton
|
||||
className="t--fork-app"
|
||||
href={forkUrl}
|
||||
text={createMessage(FORK_APP)}
|
||||
icon="fork"
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
CTA = (
|
||||
<div className="header__application-fork-btn-wrapper t--fork-btn-wrapper">
|
||||
<ForkApplicationModal applicationId={currentApplicationDetails.id} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
} else if (
|
||||
currentApplicationDetails?.isPublic &&
|
||||
currentUser?.username === ANONYMOUS_USERNAME
|
||||
) {
|
||||
CTA = (
|
||||
<Cta
|
||||
className="t--sign-in"
|
||||
href={loginUrl}
|
||||
text={createMessage(SIGN_IN)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return CTA;
|
||||
};
|
||||
|
||||
export default getAppViewerHeaderCTA;
|
||||
|
|
@ -29,7 +29,6 @@ const TriggerButton = styled(Button)`
|
|||
svg {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
margin-right: ${(props) => props.theme.spaces[7]}px;
|
||||
`;
|
||||
|
||||
const StyledDialog = styled(Dialog)`
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user