PromucFlow_constructor/app/client/src/pages/Applications/index.tsx

393 lines
13 KiB
TypeScript
Raw Normal View History

import React, { Component } from "react";
import styled from "styled-components";
import { connect } from "react-redux";
2019-11-25 05:07:27 +00:00
import { AppState } from "reducers";
2020-08-18 06:40:11 +00:00
import { Card, Icon, Dialog, Classes, Colors } from "@blueprintjs/core";
import Button from "components/editorComponents/Button";
import {
getApplicationList,
getIsFetchingApplications,
getIsCreatingApplication,
2019-11-21 10:52:49 +00:00
getCreateApplicationError,
2020-02-03 12:19:10 +00:00
getIsDeletingApplication,
2020-06-01 05:12:10 +00:00
getUserApplicationsOrgsList,
getIsDuplicatingApplication,
2019-11-25 05:07:27 +00:00
} from "selectors/applicationSelectors";
import {
ReduxActionTypes,
ApplicationPayload,
2019-11-25 05:07:27 +00:00
} from "constants/ReduxActionConstants";
import PageWrapper from "pages/common/PageWrapper";
2019-11-21 10:52:49 +00:00
import SubHeader from "pages/common/SubHeader";
import PageSectionDivider from "pages/common/PageSectionDivider";
2019-11-21 10:52:49 +00:00
import ApplicationCard from "./ApplicationCard";
import CreateApplicationForm from "./CreateApplicationForm";
import OrgInviteUsersForm from "pages/organization/OrgInviteUsersForm";
import { PERMISSION_TYPE, isPermitted } from "./permissionHelpers";
import FormDialogComponent from "components/editorComponents/form/FormDialogComponent";
import { User } from "constants/userConstants";
2020-06-11 11:31:32 +00:00
import CustomizedDropdown, {
CustomizedDropdownProps,
} from "pages/common/CustomizedDropdown";
import { getCurrentUser } from "selectors/usersSelectors";
import CreateOrganizationForm from "pages/organization/CreateOrganizationForm";
import { CREATE_ORGANIZATION_FORM_NAME } from "constants/forms";
2020-06-11 11:31:32 +00:00
import {
getOnSelectAction,
DropdownOnSelectActions,
} from "pages/common/CustomizedDropdown/dropdownHelpers";
import { Directions } from "utils/helpers";
2020-08-18 06:40:11 +00:00
import { HeaderIcons } from "icons/HeaderIcons";
import { duplicateApplication } from "actions/applicationActions";
import HelpModal from "components/designSystems/appsmith/help/HelpModal";
const OrgDropDown = styled.div`
display: flex;
padding: ${props => props.theme.spaces[4]}px
${props => props.theme.spaces[4]}px;
font-size: ${props => props.theme.fontSizes[1]}px;
justify-content: space-between;
`;
2020-08-18 06:40:11 +00:00
const CreateNew = styled.div`
font-size: 16px;
font-weight: 500;
margin-top: 20px;
`;
const ApplicationCardsWrapper = styled.div`
display: flex;
flex-flow: row wrap;
2019-11-21 10:52:49 +00:00
justify-content: flex-start;
align-items: space-evenly;
font-size: ${props => props.theme.fontSizes[4]}px;
`;
const OrgSection = styled.div``;
const OrgName = styled.div`
display: flex;
font-size: ${props => props.theme.fontSizes[4]}px;
font-weight: ${props => props.theme.fontWeights[3]};
padding-top: ${props => props.theme.spaces[4]}px;
padding-left: ${props => props.theme.spaces[6]}px;
& > span {
margin-right: 10px;
}
`;
const DropDownTrigger = styled.div`
font-size: ${props => props.theme.fontSizes[4]}px;
font-weight: ${props => props.theme.fontWeights[3]};
cursor: pointer;
`;
2020-08-18 06:40:11 +00:00
const PaddingWrapper = styled.div`
width: ${props => props.theme.card.minWidth + props.theme.spaces[5] * 2}px;
margin: ${props => props.theme.spaces[5]}px
${props => props.theme.spaces[5]}px;
`;
const ApplicationAddCardWrapper = styled(Card)`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: ${props => props.theme.card.minWidth}px;
height: ${props => props.theme.card.minHeight}px;
position: relative;
border-radius: ${props => props.theme.radii[1]}px;
2020-08-18 06:40:11 +00:00
box-shadow: none;
border: 1px dashed #d0d7dd;
margin: ${props => props.theme.spaces[11]}px
${props => props.theme.spaces[5]}px;
a {
display: block;
position: absolute;
left: 0;
top: 0;
height: calc(100% - ${props => props.theme.card.titleHeight}px);
width: 100%;
}
2020-06-18 12:31:56 +00:00
cursor: pointer;
`;
2020-06-11 11:31:32 +00:00
const StyledDialog = styled(Dialog)<{ setMaxWidth?: boolean }>`
&& {
background: white;
& .bp3-dialog-header {
padding: ${props => props.theme.spaces[4]}px
${props => props.theme.spaces[4]}px;
}
& .bp3-dialog-footer-actions {
display: block;
}
${props => props.setMaxWidth && `width: 100vh;`}
}
`;
type ApplicationProps = {
applicationList: ApplicationPayload[];
createApplication: (appName: string) => void;
isCreatingApplication: boolean;
2019-11-21 10:52:49 +00:00
isFetchingApplications: boolean;
createApplicationError?: string;
2020-01-27 08:24:58 +00:00
searchApplications: (keyword: string) => void;
deleteApplication: (id: string) => void;
duplicateApplication: (id: string) => void;
2020-02-03 12:19:10 +00:00
deletingApplication: boolean;
duplicatingApplication: boolean;
getAllApplication: () => void;
userOrgs: any;
currentUser?: User;
};
2020-06-11 11:31:32 +00:00
class Applications extends Component<
ApplicationProps,
{ selectedOrgId: string }
> {
constructor(props: ApplicationProps) {
super(props);
this.state = {
selectedOrgId: "",
};
}
componentDidMount() {
this.props.getAllApplication();
}
2020-06-11 11:31:32 +00:00
public render() {
const Form: any = OrgInviteUsersForm;
2020-06-11 11:31:32 +00:00
const DropdownProps = (
user: User,
orgName: string,
orgId: string,
): CustomizedDropdownProps => {
return {
sections: [
{
options: [
{
2020-08-18 06:40:11 +00:00
content: orgName,
2020-06-11 11:31:32 +00:00
disabled: true,
shouldCloseDropdown: false,
},
{
content: "Organization Settings",
onSelect: () =>
getOnSelectAction(DropdownOnSelectActions.REDIRECT, {
path: `/org/${orgId}/settings/general`,
2020-06-11 11:31:32 +00:00
}),
},
{
content: "Share",
onSelect: () =>
this.setState({
selectedOrgId: orgId,
}),
},
{
content: "Members",
onSelect: () =>
getOnSelectAction(DropdownOnSelectActions.REDIRECT, {
path: `/org/${orgId}/settings/members`,
2020-06-11 11:31:32 +00:00
}),
},
],
},
],
trigger: {
content: (
<DropDownTrigger className="t--org-name">
{orgName} <Icon icon="chevron-down" color={"black"} />
</DropDownTrigger>
),
2020-06-11 11:31:32 +00:00
outline: false,
},
openDirection: Directions.DOWN,
};
};
return (
<PageWrapper displayName="Applications">
<SubHeader
add={{
form: CreateOrganizationForm,
title: "Create Organization",
formName: CREATE_ORGANIZATION_FORM_NAME,
formSubmitIntent: "primary",
isAdding: false,
formSubmitText: "Create",
onClick: () => {
return null;
},
}}
search={{
placeholder: "Search App Name",
queryFn: this.props.searchApplications,
}}
/>
<PageSectionDivider />
{this.props.userOrgs &&
2020-06-18 12:16:46 +00:00
this.props.userOrgs.length !== 0 &&
this.props.userOrgs.map((organizationObject: any, index: number) => {
const { organization, applications } = organizationObject;
return (
<OrgSection className="t--org-section" key={index}>
<OrgDropDown>
{!isPermitted(
organization.userPermissions,
PERMISSION_TYPE.MANAGE_ORGANIZATION,
) ? (
2020-08-18 06:40:11 +00:00
<OrgName>{organization.name}</OrgName>
) : (
<>
{this.props.currentUser && (
<CustomizedDropdown
{...DropdownProps(
this.props.currentUser,
organization.name,
organization.id,
)}
/>
)}
2020-06-11 11:31:32 +00:00
<StyledDialog
canOutsideClickClose={false}
canEscapeKeyClose={false}
title={`Invite Users to ${organization.name}`}
onClose={() =>
this.setState({
selectedOrgId: "",
})
}
isOpen={this.state.selectedOrgId === organization.id}
setMaxWidth
>
<div className={Classes.DIALOG_BODY}>
<Form orgId={organization.id} />
</div>
</StyledDialog>
</>
)}
{isPermitted(
organization.userPermissions,
PERMISSION_TYPE.INVITE_USER_TO_ORGANIZATION,
) && (
<FormDialogComponent
trigger={
<Button
2020-08-18 06:40:11 +00:00
icon={
<HeaderIcons.SHARE
color={Colors.WHITE}
width={16}
height={16}
/>
}
text="Share"
intent={"primary"}
className="t--org-share-btn"
filled
/>
}
canOutsideClickClose={true}
Form={OrgInviteUsersForm}
orgId={organization.id}
title={`Invite Users to ${organization.name}`}
/>
)}
</OrgDropDown>
<ApplicationCardsWrapper key={organization.id}>
<FormDialogComponent
permissions={organization.userPermissions}
permissionRequired={PERMISSION_TYPE.CREATE_APPLICATION}
trigger={
2020-08-18 06:40:11 +00:00
<PaddingWrapper>
<ApplicationAddCardWrapper>
<Icon
color={"#9F9F9F"}
icon="plus"
iconSize={17}
className="t--create-app-popup"
/>
<CreateNew className="createnew">
Create New
</CreateNew>
</ApplicationAddCardWrapper>
</PaddingWrapper>
}
Form={CreateApplicationForm}
orgId={organization.id}
title={"Create Application"}
/>
{applications.map((application: any) => {
return (
application.pages?.length > 0 && (
<ApplicationCard
key={application.id}
application={application}
delete={this.props.deleteApplication}
duplicate={this.props.duplicateApplication}
/>
)
);
})}
<PageSectionDivider />
</ApplicationCardsWrapper>
</OrgSection>
);
})}
<HelpModal page={"Applications"} />
</PageWrapper>
);
}
}
const mapStateToProps = (state: AppState) => ({
applicationList: getApplicationList(state),
isFetchingApplications: getIsFetchingApplications(state),
isCreatingApplication: getIsCreatingApplication(state),
2019-11-21 10:52:49 +00:00
createApplicationError: getCreateApplicationError(state),
2020-02-03 12:19:10 +00:00
deletingApplication: getIsDeletingApplication(state),
duplicatingApplication: getIsDuplicatingApplication(state),
userOrgs: getUserApplicationsOrgsList(state),
currentUser: getCurrentUser(state),
});
const mapDispatchToProps = (dispatch: any) => ({
getAllApplication: () =>
dispatch({ type: ReduxActionTypes.GET_ALL_APPLICATION_INIT }),
createApplication: (appName: string) => {
dispatch({
type: ReduxActionTypes.CREATE_APPLICATION_INIT,
payload: {
name: appName,
},
});
},
searchApplications: (keyword: string) => {
dispatch({
type: ReduxActionTypes.SEARCH_APPLICATIONS,
payload: {
keyword,
},
});
},
2020-01-27 08:24:58 +00:00
deleteApplication: (applicationId: string) => {
if (applicationId && applicationId.length > 0) {
dispatch({
type: ReduxActionTypes.DELETE_APPLICATION_INIT,
payload: {
applicationId,
},
});
}
},
duplicateApplication: (applicationId: string) => {
dispatch(duplicateApplication(applicationId));
},
});
export default connect(mapStateToProps, mapDispatchToProps)(Applications);