2019-10-31 08:36:04 +00:00
|
|
|
import React from "react";
|
2020-08-06 11:06:53 +00:00
|
|
|
import { Link, NavLink } from "react-router-dom";
|
2019-10-31 08:36:04 +00:00
|
|
|
import styled from "styled-components";
|
2019-11-25 05:07:27 +00:00
|
|
|
import StyledHeader from "components/designSystems/appsmith/StyledHeader";
|
2020-08-06 11:06:53 +00:00
|
|
|
import AppsmithLogo from "assets/images/appsmith_logo_white.png";
|
2020-05-14 06:06:20 +00:00
|
|
|
import Button from "components/editorComponents/Button";
|
2020-08-13 09:33:44 +00:00
|
|
|
import { EDIT_APP, FORK_APP } from "constants/messages";
|
2020-08-06 11:06:53 +00:00
|
|
|
import {
|
|
|
|
|
isPermitted,
|
|
|
|
|
PERMISSION_TYPE,
|
|
|
|
|
} from "pages/Applications/permissionHelpers";
|
|
|
|
|
import {
|
|
|
|
|
ApplicationPayload,
|
|
|
|
|
PageListPayload,
|
|
|
|
|
} from "constants/ReduxActionConstants";
|
|
|
|
|
import {
|
|
|
|
|
APPLICATIONS_URL,
|
|
|
|
|
getApplicationViewerPageURL,
|
2020-08-13 09:33:44 +00:00
|
|
|
SIGN_UP_URL,
|
2020-08-06 11:06:53 +00:00
|
|
|
} from "constants/routes";
|
|
|
|
|
import { connect } from "react-redux";
|
|
|
|
|
import { AppState } from "reducers";
|
|
|
|
|
import { getEditorURL } from "selectors/appViewSelectors";
|
|
|
|
|
import { getPageList } from "selectors/editorSelectors";
|
|
|
|
|
import { FormDialogComponent } from "components/editorComponents/form/FormDialogComponent";
|
2020-08-12 11:41:56 +00:00
|
|
|
import AppInviteUsersForm from "pages/organization/AppInviteUsersForm";
|
2020-08-06 11:06:53 +00:00
|
|
|
import { getCurrentOrgId } from "selectors/organizationSelectors";
|
|
|
|
|
import { HeaderIcons } from "icons/HeaderIcons";
|
|
|
|
|
import { Colors } from "constants/Colors";
|
2020-07-23 12:28:02 +00:00
|
|
|
|
2020-08-06 11:06:53 +00:00
|
|
|
const HeaderWrapper = styled(StyledHeader)<{ hasPages: boolean }>`
|
|
|
|
|
background: ${Colors.BALTIC_SEA};
|
|
|
|
|
height: ${props => (props.hasPages ? "90px" : "48px")};
|
|
|
|
|
color: white;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.05);
|
2020-07-23 12:28:02 +00:00
|
|
|
`;
|
|
|
|
|
|
2020-08-06 11:06:53 +00:00
|
|
|
const HeaderRow = styled.div<{ justify: string }>`
|
|
|
|
|
width: 100%;
|
2020-05-14 06:06:20 +00:00
|
|
|
display: flex;
|
2020-08-06 11:06:53 +00:00
|
|
|
flex: 1;
|
|
|
|
|
flex-direction: row;
|
|
|
|
|
justify-content: ${props => props.justify};
|
2019-10-31 08:36:04 +00:00
|
|
|
`;
|
2020-06-17 06:29:09 +00:00
|
|
|
|
2020-08-06 11:06:53 +00:00
|
|
|
const HeaderSection = styled.div<{ justify: string }>`
|
2020-07-23 12:28:02 +00:00
|
|
|
display: flex;
|
2020-08-06 11:06:53 +00:00
|
|
|
flex: 1;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: ${props => props.justify};
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const AppsmithLogoImg = styled.img`
|
|
|
|
|
max-width: 110px;
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const BackToEditorButton = styled(Button)`
|
|
|
|
|
max-width: 200px;
|
|
|
|
|
height: 32px;
|
|
|
|
|
margin: 5px 10px;
|
|
|
|
|
`;
|
|
|
|
|
|
2020-08-13 09:33:44 +00:00
|
|
|
const ForkButton = styled(Button)`
|
|
|
|
|
max-width: 200px;
|
|
|
|
|
height: 32px;
|
|
|
|
|
margin: 5px 10px;
|
|
|
|
|
`;
|
|
|
|
|
|
2020-08-06 11:06:53 +00:00
|
|
|
const ShareButton = styled(Button)`
|
|
|
|
|
height: 32px;
|
|
|
|
|
margin: 5px 10px;
|
|
|
|
|
color: white !important;
|
2020-07-23 12:28:02 +00:00
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const StyledApplicationName = styled.span`
|
|
|
|
|
font-size: 15px;
|
2020-08-06 11:06:53 +00:00
|
|
|
font-weight: 500;
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
line-height: 14px;
|
2020-06-17 06:29:09 +00:00
|
|
|
`;
|
2020-08-06 11:06:53 +00:00
|
|
|
|
|
|
|
|
const PageTab = styled(NavLink)`
|
|
|
|
|
display: flex;
|
|
|
|
|
height: 30px;
|
2020-08-18 12:36:45 +00:00
|
|
|
flex: 0 0 150px;
|
2020-08-06 11:06:53 +00:00
|
|
|
margin-right: 1px;
|
|
|
|
|
align-self: flex-end;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
background-color: rgb(49, 48, 51);
|
2020-08-18 12:36:45 +00:00
|
|
|
padding: 0px 10px;
|
2020-08-06 11:06:53 +00:00
|
|
|
&& span {
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
line-height: 20px;
|
|
|
|
|
letter-spacing: 0.04em;
|
|
|
|
|
color: #fff;
|
|
|
|
|
}
|
|
|
|
|
&&&:hover {
|
|
|
|
|
text-decoration: none;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
span {
|
|
|
|
|
color: #2e3d49;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
&&&.is-active {
|
|
|
|
|
background-color: white;
|
|
|
|
|
span {
|
|
|
|
|
color: #2e3d49;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
2020-05-14 06:06:20 +00:00
|
|
|
type AppViewerHeaderProps = {
|
|
|
|
|
url?: string;
|
2020-07-23 12:28:02 +00:00
|
|
|
currentApplicationDetails?: ApplicationPayload;
|
2020-08-06 11:06:53 +00:00
|
|
|
pages: PageListPayload;
|
|
|
|
|
currentOrgId: string;
|
2020-05-14 06:06:20 +00:00
|
|
|
};
|
2019-10-31 08:36:04 +00:00
|
|
|
|
|
|
|
|
export const AppViewerHeader = (props: AppViewerHeaderProps) => {
|
2020-08-06 11:06:53 +00:00
|
|
|
const { currentApplicationDetails, pages, currentOrgId } = props;
|
2020-08-13 09:33:44 +00:00
|
|
|
const isExampleApp = currentApplicationDetails?.appIsExample;
|
2020-08-06 11:06:53 +00:00
|
|
|
const userPermissions = currentApplicationDetails?.userPermissions ?? [];
|
|
|
|
|
const permissionRequired = PERMISSION_TYPE.MANAGE_APPLICATION;
|
|
|
|
|
const canEdit = isPermitted(userPermissions, permissionRequired);
|
2020-08-18 08:48:06 +00:00
|
|
|
// Mark default page as first page
|
|
|
|
|
const appPages = pages;
|
|
|
|
|
if (appPages.length > 1) {
|
|
|
|
|
appPages.forEach(function(item, i) {
|
|
|
|
|
if (item.isDefault) {
|
|
|
|
|
appPages.splice(i, 1);
|
|
|
|
|
appPages.unshift(item);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2020-06-17 10:19:56 +00:00
|
|
|
|
2020-08-13 09:33:44 +00:00
|
|
|
const forkAppUrl = `${window.location.origin}${SIGN_UP_URL}?appId=${currentApplicationDetails?.id}`;
|
|
|
|
|
|
|
|
|
|
let CTA = null;
|
|
|
|
|
|
|
|
|
|
if (props.url && canEdit) {
|
|
|
|
|
CTA = (
|
|
|
|
|
<BackToEditorButton
|
|
|
|
|
className="t--back-to-editor"
|
|
|
|
|
href={props.url}
|
|
|
|
|
intent="primary"
|
|
|
|
|
icon="arrow-left"
|
|
|
|
|
iconAlignment="left"
|
|
|
|
|
text={EDIT_APP}
|
|
|
|
|
filled
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
} else if (isExampleApp) {
|
|
|
|
|
CTA = (
|
|
|
|
|
<ForkButton
|
|
|
|
|
className="t--fork-app"
|
|
|
|
|
href={forkAppUrl}
|
|
|
|
|
intent="primary"
|
|
|
|
|
icon="fork"
|
|
|
|
|
iconAlignment="left"
|
|
|
|
|
text={FORK_APP}
|
|
|
|
|
filled
|
|
|
|
|
/>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-14 06:06:20 +00:00
|
|
|
return (
|
2020-08-06 11:06:53 +00:00
|
|
|
<HeaderWrapper hasPages={pages.length > 1}>
|
|
|
|
|
<HeaderRow justify={"space-between"}>
|
|
|
|
|
<HeaderSection justify={"flex-start"}>
|
2020-07-23 12:28:02 +00:00
|
|
|
<Link to={APPLICATIONS_URL}>
|
2020-08-06 11:06:53 +00:00
|
|
|
<AppsmithLogoImg src={AppsmithLogo} alt="Appsmith logo" />
|
|
|
|
|
</Link>
|
|
|
|
|
</HeaderSection>
|
|
|
|
|
<HeaderSection justify={"center"}>
|
|
|
|
|
{currentApplicationDetails && (
|
2020-07-23 12:28:02 +00:00
|
|
|
<StyledApplicationName>
|
|
|
|
|
{currentApplicationDetails.name}
|
|
|
|
|
</StyledApplicationName>
|
2020-08-06 11:06:53 +00:00
|
|
|
)}
|
|
|
|
|
</HeaderSection>
|
|
|
|
|
<HeaderSection justify={"flex-end"}>
|
|
|
|
|
{currentApplicationDetails && (
|
|
|
|
|
<>
|
2020-08-12 11:41:56 +00:00
|
|
|
<FormDialogComponent
|
|
|
|
|
trigger={
|
|
|
|
|
<ShareButton
|
|
|
|
|
text="Share"
|
|
|
|
|
intent="none"
|
|
|
|
|
outline
|
|
|
|
|
size="small"
|
|
|
|
|
className="t--application-share-btn"
|
|
|
|
|
icon={
|
|
|
|
|
<HeaderIcons.SHARE
|
|
|
|
|
color={Colors.WHITE}
|
|
|
|
|
width={13}
|
|
|
|
|
height={13}
|
|
|
|
|
/>
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
}
|
|
|
|
|
Form={AppInviteUsersForm}
|
|
|
|
|
orgId={currentOrgId}
|
|
|
|
|
applicationId={currentApplicationDetails.id}
|
|
|
|
|
title={currentApplicationDetails.name}
|
|
|
|
|
/>
|
2020-08-13 09:33:44 +00:00
|
|
|
{CTA}
|
2020-08-06 11:06:53 +00:00
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</HeaderSection>
|
|
|
|
|
</HeaderRow>
|
2020-08-18 08:48:06 +00:00
|
|
|
{appPages.length > 1 && (
|
2020-08-06 11:06:53 +00:00
|
|
|
<HeaderRow justify={"flex-start"}>
|
2020-08-18 08:48:06 +00:00
|
|
|
{appPages.map(page => (
|
2020-08-06 11:06:53 +00:00
|
|
|
<PageTab
|
|
|
|
|
key={page.pageId}
|
|
|
|
|
to={getApplicationViewerPageURL(
|
|
|
|
|
currentApplicationDetails?.id,
|
|
|
|
|
page.pageId,
|
|
|
|
|
)}
|
|
|
|
|
activeClassName="is-active"
|
|
|
|
|
>
|
|
|
|
|
<span>{page.pageName}</span>
|
|
|
|
|
</PageTab>
|
|
|
|
|
))}
|
|
|
|
|
</HeaderRow>
|
2020-05-14 06:06:20 +00:00
|
|
|
)}
|
|
|
|
|
</HeaderWrapper>
|
|
|
|
|
);
|
2019-10-31 08:36:04 +00:00
|
|
|
};
|
|
|
|
|
|
2020-08-06 11:06:53 +00:00
|
|
|
const mapStateToProps = (state: AppState): AppViewerHeaderProps => ({
|
|
|
|
|
pages: getPageList(state),
|
|
|
|
|
url: getEditorURL(state),
|
|
|
|
|
currentApplicationDetails: state.ui.applications.currentApplication,
|
|
|
|
|
currentOrgId: getCurrentOrgId(state),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export default connect(mapStateToProps)(AppViewerHeader);
|