PromucFlow_constructor/app/client/src/pages/AppViewer/viewer/AppViewerHeader.tsx

238 lines
7.7 KiB
TypeScript
Raw Normal View History

import React from "react";
import { Link, useLocation } from "react-router-dom";
2020-12-15 11:24:44 +00:00
import { Helmet } from "react-helmet";
import styled, { ThemeProvider } from "styled-components";
2019-11-25 05:07:27 +00:00
import StyledHeader from "components/designSystems/appsmith/StyledHeader";
import AppsmithLogo from "assets/images/appsmith_logo.png";
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, AUTH_LOGIN_URL } from "constants/routes";
2020-08-06 11:06:53 +00:00
import { connect } from "react-redux";
import { AppState } from "reducers";
import { getEditorURL } from "selectors/appViewSelectors";
2021-02-24 13:47:37 +00:00
import { getViewModePageList } from "selectors/editorSelectors";
2020-08-06 11:06:53 +00:00
import { FormDialogComponent } from "components/editorComponents/form/FormDialogComponent";
import AppInviteUsersForm from "pages/organization/AppInviteUsersForm";
2020-08-06 11:06:53 +00:00
import { getCurrentOrgId } from "selectors/organizationSelectors";
import { getCurrentUser } from "selectors/usersSelectors";
import { ANONYMOUS_USERNAME, User } from "constants/userConstants";
import Text, { TextType } from "components/ads/Text";
import { Classes } from "components/ads/common";
import { getTypographyByKey, Theme } from "constants/DefaultTheme";
import { IconWrapper } from "components/ads/Icon";
import Button, { Size } from "components/ads/Button";
import ProfileDropdown from "pages/common/ProfileDropdown";
import { Profile } from "pages/common/ProfileImage";
import PageTabsContainer from "./PageTabsContainer";
import { getThemeDetails, ThemeMode } from "selectors/themeSelectors";
Initialise comments (#3328) * Initial scaffolding for comments CRUD APIs * add actions * add assets * state management for existing comments and creating new * add ui components * add overlay comments wrapper to baseWidget * add toggle comment mode button at editor header * trigger tests * Disallow commenting as someone else * Add applicationId for comments * lint * Add overlay blacklist to prevent component interaction while adding comments * Comment thread style updates * Placeholder comment context menu * Controlled comment thread visibility for making new comments visible by default * Update comment type description * Reset input on save * Resolve comment thread button ui * fix close on esc key, dont create new comment on outside click * Submit on enter * add emoji picker * Attempt at adding a websocket server in Java * CRUD APIs for comment threads * Add API for getting all threads in application * Move types to a separate file * Initial commit for real time server (RTS) * Add script to start RTS * Fix position property * Use create comment thread API * Use add comment to thread API * Add custom cursor * Dispatch logout init on 401 errors * Allow CORS for real time connection * Add more logs to RTS * Fix construction of MongoClient * WIP: Real time comments * Enable comments * Minor updates * Read backend API base URL from environment * Escape to reset comments mode * Set popover position as auto and boundary as scroll parent * Disable warning * Added permissions for comment threads * Add resolved API for comment threads * Migration to set commenting permission on existing apps * Fix updates bringing the RTS down * Show view latest button, scroll to bottom on creating a new comment * Cleanup comment reducer * Move to typescript for RTS * Add missing server.ts and tsconfig files * Resolve / unresolve comment * Scaffold app comments * Minor fixes: comment on top of all widgets, add toggle button at viewer header * Reconnect socket on creating a new app, set connected status in store * Retry socket connection flow * Integration tests for comments with api mocks using msw * Fix circular depependency * rm file * Minor cleanup and comments * Minor refactors: move isScrolledToBottom to common hooks, decouple prevent interactions overlay from comments wrapper * Use policies when pushing updates in RTS * ENV var to set if comments are enabled * Fix: check if editor/viewer is initialised before waiting for init action * Add tests for comments reducer * Revert "ENV var to set if comments are enabled" This reverts commit 988efeaa69d378d943a387e1e73510334958adc5. * Enable comments for users with appsmith email * lint * fix * Try running a socket.io server inside backend * Update comment reducer tests * Init mentions within comments * Fix comment thread updates with email rooms * Minor fixes * Refactors / review suggestions * lint * increase cache limit for builds * Comment out tests for feature that's under development * Add Dockerfile for RTS * Fix policies missing for first comment in threads * Use draftJS for comments input with mentions support * fix fixtures * Use thread's policies when querying for threads * Update socket.io to v4 * Add support for richer body with mentions * Update comment body type to RawDraftContentState * fix stale method * Fix mentions search * Minor cleanups * Comment context menu and thread UI updates * revert: Scaffold app comments * Yarn dependencies * Delete comment using id api added * Init app comments * Add test for creating thread * Api for delete comment with id * Test comment creation response and policies * Copy comment links * Fix reset editor state * Delete valid comment testcase added * Delete comment TC : code refactor * Don't allow creating comments with an empty body * Pin comments WIP[] * Ignore dependency-reduced-pom.xml files from VCS * Cleanup of some dev-only files, for review * Delete comment * Update socket.io to v4 in RTS * Pin and resolve comment thread object added in commentThread * Pin and resolve comment thread object added in commentThread * Update comment thread API * Added creationTime and updationTime in comment thread response * Added creationTime and updationTime in comment thread response * Added human readable id to comment threads, fallback to username for null name in user document * Refactor * lint * fix test, rm duplicate selector * comment out saga used for dev * CommentThread viewed status, username fallback for getName=null, username field added in pin & resolve status * lint * trigger tests Co-authored-by: Shrikant Sharat Kandula <shrikant@appsmith.com> Co-authored-by: Abhijeet <abhi.nagarnaik@gmail.com>
2021-04-29 10:33:51 +00:00
import ToggleCommentModeButton from "comments/ToggleCommentModeButton";
import getAppViewerHeaderCTA from "./getAppViewerHeaderCTA";
2020-08-06 11:06:53 +00:00
const HeaderWrapper = styled(StyledHeader)<{ hasPages: boolean }>`
box-shadow: unset;
height: unset;
padding: 0;
background-color: ${(props) => props.theme.colors.header.background};
2020-08-06 11:06:53 +00:00
color: white;
flex-direction: column;
.${Classes.TEXT} {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
${(props) => getTypographyByKey(props, "h4")}
color: ${(props) => props.theme.colors.header.appName};
}
& .header__application-share-btn {
background-color: ${(props) => props.theme.colors.header.background};
border-color: ${(props) => props.theme.colors.header.background};
color: ${(props) => props.theme.colors.header.shareBtn};
${IconWrapper} path {
fill: ${(props) => props.theme.colors.header.shareBtn};
}
}
& .header__application-share-btn:hover {
color: ${(props) => props.theme.colors.header.shareBtnHighlight};
${IconWrapper} path {
fill: ${(props) => props.theme.colors.header.shareBtnHighlight};
}
}
.header__application-fork-btn-wrapper {
height: 100%;
}
.header__application-fork-btn-wrapper .ads-dialog-trigger {
height: 100%;
}
& ${Profile} {
width: 24px;
height: 24px;
}
& .current-app-name {
overflow: auto;
}
`;
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;
2020-12-24 04:32:25 +00:00
justify-content: ${(props) => props.justify};
height: ${(props) => `calc(${props.theme.smallHeaderHeight})`};
border-bottom: 1px solid
${(props) => props.theme.colors.header.tabsHorizontalSeparator};
`;
2020-08-06 11:06:53 +00:00
const HeaderSection = styled.div<{ justify: string }>`
display: flex;
2020-08-06 11:06:53 +00:00
flex: 1;
align-items: center;
2020-12-24 04:32:25 +00:00
justify-content: ${(props) => props.justify};
2020-08-06 11:06:53 +00:00
`;
const AppsmithLogoImg = styled.img`
padding-left: ${(props) => props.theme.spaces[7]}px;
2020-08-06 11:06:53 +00:00
max-width: 110px;
`;
const HeaderRightItemContainer = styled.div`
2020-08-06 11:06:53 +00:00
display: flex;
align-items: center;
margin-right: ${(props) => props.theme.spaces[7]}px;
height: 100%;
2020-08-06 11:06:53 +00:00
`;
const PrimaryLogoLink = styled(Link)`
display: flex;
align-items: center;
`;
2020-05-14 06:06:20 +00:00
type AppViewerHeaderProps = {
url?: string;
currentApplicationDetails?: ApplicationPayload;
2020-08-06 11:06:53 +00:00
pages: PageListPayload;
currentOrgId: string;
currentUser?: User;
lightTheme: Theme;
2020-05-14 06:06:20 +00:00
};
export function AppViewerHeader(props: AppViewerHeaderProps) {
2021-02-24 13:47:37 +00:00
const { currentApplicationDetails, currentOrgId, currentUser, pages } = props;
2020-08-06 11:06:53 +00:00
const userPermissions = currentApplicationDetails?.userPermissions ?? [];
const permissionRequired = PERMISSION_TYPE.MANAGE_APPLICATION;
const canEdit = isPermitted(userPermissions, permissionRequired);
const { search } = useLocation();
const queryParams = new URLSearchParams(search);
const isEmbed = queryParams.get("embed");
const hideHeader = !!isEmbed;
function HtmlTitle() {
2020-12-15 11:24:44 +00:00
if (!currentApplicationDetails?.name) return null;
return (
<Helmet>
<title>{currentApplicationDetails?.name}</title>
</Helmet>
);
}
2020-12-15 11:24:44 +00:00
if (hideHeader) return <HtmlTitle />;
const forkUrl = `${AUTH_LOGIN_URL}?redirectUrl=${window.location.href}/fork`;
const loginUrl = `${AUTH_LOGIN_URL}?redirectUrl=${window.location.href}`;
2020-08-13 09:33:44 +00:00
const CTA = getAppViewerHeaderCTA({
url: props.url,
canEdit,
currentApplicationDetails,
currentUser,
forkUrl,
loginUrl,
});
2020-08-13 09:33:44 +00:00
2020-05-14 06:06:20 +00:00
return (
<ThemeProvider theme={props.lightTheme}>
<HeaderWrapper hasPages={pages.length > 1}>
<HtmlTitle />
<HeaderRow justify={"space-between"}>
<HeaderSection justify={"flex-start"}>
<PrimaryLogoLink to={APPLICATIONS_URL}>
<AppsmithLogoImg alt="Appsmith logo" src={AppsmithLogo} />
</PrimaryLogoLink>
</HeaderSection>
<HeaderSection className="current-app-name" justify={"center"}>
{currentApplicationDetails && (
<Text type={TextType.H4}>{currentApplicationDetails.name}</Text>
)}
</HeaderSection>
<HeaderSection justify={"flex-end"}>
Initialise comments (#3328) * Initial scaffolding for comments CRUD APIs * add actions * add assets * state management for existing comments and creating new * add ui components * add overlay comments wrapper to baseWidget * add toggle comment mode button at editor header * trigger tests * Disallow commenting as someone else * Add applicationId for comments * lint * Add overlay blacklist to prevent component interaction while adding comments * Comment thread style updates * Placeholder comment context menu * Controlled comment thread visibility for making new comments visible by default * Update comment type description * Reset input on save * Resolve comment thread button ui * fix close on esc key, dont create new comment on outside click * Submit on enter * add emoji picker * Attempt at adding a websocket server in Java * CRUD APIs for comment threads * Add API for getting all threads in application * Move types to a separate file * Initial commit for real time server (RTS) * Add script to start RTS * Fix position property * Use create comment thread API * Use add comment to thread API * Add custom cursor * Dispatch logout init on 401 errors * Allow CORS for real time connection * Add more logs to RTS * Fix construction of MongoClient * WIP: Real time comments * Enable comments * Minor updates * Read backend API base URL from environment * Escape to reset comments mode * Set popover position as auto and boundary as scroll parent * Disable warning * Added permissions for comment threads * Add resolved API for comment threads * Migration to set commenting permission on existing apps * Fix updates bringing the RTS down * Show view latest button, scroll to bottom on creating a new comment * Cleanup comment reducer * Move to typescript for RTS * Add missing server.ts and tsconfig files * Resolve / unresolve comment * Scaffold app comments * Minor fixes: comment on top of all widgets, add toggle button at viewer header * Reconnect socket on creating a new app, set connected status in store * Retry socket connection flow * Integration tests for comments with api mocks using msw * Fix circular depependency * rm file * Minor cleanup and comments * Minor refactors: move isScrolledToBottom to common hooks, decouple prevent interactions overlay from comments wrapper * Use policies when pushing updates in RTS * ENV var to set if comments are enabled * Fix: check if editor/viewer is initialised before waiting for init action * Add tests for comments reducer * Revert "ENV var to set if comments are enabled" This reverts commit 988efeaa69d378d943a387e1e73510334958adc5. * Enable comments for users with appsmith email * lint * fix * Try running a socket.io server inside backend * Update comment reducer tests * Init mentions within comments * Fix comment thread updates with email rooms * Minor fixes * Refactors / review suggestions * lint * increase cache limit for builds * Comment out tests for feature that's under development * Add Dockerfile for RTS * Fix policies missing for first comment in threads * Use draftJS for comments input with mentions support * fix fixtures * Use thread's policies when querying for threads * Update socket.io to v4 * Add support for richer body with mentions * Update comment body type to RawDraftContentState * fix stale method * Fix mentions search * Minor cleanups * Comment context menu and thread UI updates * revert: Scaffold app comments * Yarn dependencies * Delete comment using id api added * Init app comments * Add test for creating thread * Api for delete comment with id * Test comment creation response and policies * Copy comment links * Fix reset editor state * Delete valid comment testcase added * Delete comment TC : code refactor * Don't allow creating comments with an empty body * Pin comments WIP[] * Ignore dependency-reduced-pom.xml files from VCS * Cleanup of some dev-only files, for review * Delete comment * Update socket.io to v4 in RTS * Pin and resolve comment thread object added in commentThread * Pin and resolve comment thread object added in commentThread * Update comment thread API * Added creationTime and updationTime in comment thread response * Added creationTime and updationTime in comment thread response * Added human readable id to comment threads, fallback to username for null name in user document * Refactor * lint * fix test, rm duplicate selector * comment out saga used for dev * CommentThread viewed status, username fallback for getName=null, username field added in pin & resolve status * lint * trigger tests Co-authored-by: Shrikant Sharat Kandula <shrikant@appsmith.com> Co-authored-by: Abhijeet <abhi.nagarnaik@gmail.com>
2021-04-29 10:33:51 +00:00
<ToggleCommentModeButton />
{currentApplicationDetails && (
<>
<FormDialogComponent
Form={AppInviteUsersForm}
applicationId={currentApplicationDetails.id}
canOutsideClickClose
orgId={currentOrgId}
title={currentApplicationDetails.name}
trigger={
<Button
className="t--application-share-btn header__application-share-btn"
icon={"share"}
size={Size.small}
text={"Share"}
/>
}
/>
{CTA && (
<HeaderRightItemContainer>{CTA}</HeaderRightItemContainer>
)}
</>
)}
{currentUser && currentUser.username !== ANONYMOUS_USERNAME && (
<HeaderRightItemContainer>
<ProfileDropdown
hideThemeSwitch
modifiers={{
offset: {
enabled: true,
offset: `0, ${pages.length > 1 ? 35 : 0}`,
},
}}
name={currentUser.name}
userName={currentUser?.username || ""}
/>
</HeaderRightItemContainer>
)}
</HeaderSection>
</HeaderRow>
<PageTabsContainer
currentApplicationDetails={currentApplicationDetails}
pages={pages}
/>
</HeaderWrapper>
</ThemeProvider>
2020-05-14 06:06:20 +00:00
);
}
2020-08-06 11:06:53 +00:00
const mapStateToProps = (state: AppState): AppViewerHeaderProps => ({
2021-02-24 13:47:37 +00:00
pages: getViewModePageList(state),
2020-08-06 11:06:53 +00:00
url: getEditorURL(state),
currentApplicationDetails: state.ui.applications.currentApplication,
currentOrgId: getCurrentOrgId(state),
currentUser: getCurrentUser(state),
lightTheme: getThemeDetails(state, ThemeMode.LIGHT),
2020-08-06 11:06:53 +00:00
});
export default connect(mapStateToProps)(AppViewerHeader);