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

363 lines
12 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-06-11 11:31:32 +00:00
import { Card, Icon, Dialog, Classes } 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,
getUserApplicationsOrgs,
2020-06-01 05:12:10 +00:00
getUserApplicationsOrgsList,
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 { getApplicationPayloads } from "mockComponentProps/ApplicationPayloads";
import ApplicationCard from "./ApplicationCard";
import CreateApplicationForm from "./CreateApplicationForm";
import InviteUsersFormv2 from "pages/organization/InviteUsersFromv2";
2019-11-21 10:52:49 +00:00
import { CREATE_APPLICATION_FORM_NAME } from "constants/forms";
import { PERMISSION_TYPE, isPermitted } from "./permissionHelpers";
import { MenuIcons } from "icons/MenuIcons";
2020-02-03 12:19:10 +00:00
import { DELETING_APPLICATION } from "constants/messages";
import { AppToaster } from "components/editorComponents/ToastComponent";
2020-03-06 04:59:24 +00:00
import AnalyticsUtil from "utils/AnalyticsUtil";
import FormDialogComponent from "components/editorComponents/form/FormDialogComponent";
import OrganizationListMockResponse from "mockResponses/OrganisationListResponse";
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 Badge from "pages/common/CustomizedDropdown/Badge";
import {
getOnSelectAction,
DropdownOnSelectActions,
} from "pages/common/CustomizedDropdown/dropdownHelpers";
import { Directions } from "utils/helpers";
import { IntentColors } from "constants/DefaultTheme";
const OrgDropDown = styled.div`
display: flex;
padding: 0px 30px;
font-size: ${props => props.theme.fontSizes[1]}px;
justify-content: space-between;
`;
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 OrgName = styled.div`
display: flex;
font-size: ${props => props.theme.fontSizes[3]}px;
padding-top: ${props => props.theme.spaces[4]}px;
padding-left: ${props => props.theme.spaces[6]}px;
& > div {
margin-right: 20px;
}
`;
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;
margin: ${props => props.theme.spaces[5]}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%;
}
:hover {
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[];
fetchApplications: () => void;
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;
2020-02-03 12:19:10 +00:00
deletingApplication: 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() {
2019-11-21 10:52:49 +00:00
const applicationList = this.props.isFetchingApplications
? getApplicationPayloads(8)
2019-11-21 10:52:49 +00:00
: this.props.applicationList;
2020-06-11 11:31:32 +00:00
const Form: any = InviteUsersFormv2;
const DropdownProps = (
user: User,
orgName: string,
orgId: string,
): CustomizedDropdownProps => {
return {
sections: [
{
options: [
{
content: (
<Badge
text={orgName}
imageURL="https://via.placeholder.com/32"
/>
),
disabled: true,
shouldCloseDropdown: false,
},
{
content: "Organization Settings",
onSelect: () =>
getOnSelectAction(DropdownOnSelectActions.REDIRECT, {
path: `/org/${orgId}/settings`,
}),
},
{
content: "Share",
onSelect: () =>
this.setState({
selectedOrgId: orgId,
}),
},
{
content: "Members",
onSelect: () =>
getOnSelectAction(DropdownOnSelectActions.REDIRECT, {
path: `/org/${orgId}/settings`,
}),
},
],
},
],
trigger: {
icon: "ORG_ICON",
text: orgName,
outline: false,
},
openDirection: Directions.DOWN,
};
};
return (
<PageWrapper displayName="Applications">
2020-02-03 12:19:10 +00:00
{this.props.deletingApplication
? AppToaster.show({ message: DELETING_APPLICATION })
: AppToaster.clear()}
<SubHeader
add={{
form: CreateOrganizationForm,
title: "Create Organization",
formName: CREATE_ORGANIZATION_FORM_NAME,
formSubmitIntent: "primary",
isAdding: false,
formSubmitText: "Create",
onClick: () => {
return null;
},
}}
search={{
placeholder: "Search",
queryFn: this.props.searchApplications,
}}
/>
<PageSectionDivider />
{this.props.userOrgs &&
this.props.userOrgs.length != 0 &&
this.props.userOrgs.map((organizationObject: any) => {
const { organization, applications } = organizationObject;
return (
<>
{!isPermitted(
organization.userPermissions,
PERMISSION_TYPE.CREATE_APPLICATION,
) ? (
<OrgName>
{MenuIcons.ORG_ICON({
color: IntentColors["secondary"],
width: 16,
height: 16,
})}
{organization.name}
</OrgName>
) : (
<OrgDropDown>
{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>
<FormDialogComponent
trigger={
<Button text="Share" intent={"primary"} filled />
}
Form={InviteUsersFormv2}
orgId={organization.id}
title={`Invite Users to ${organization.name}`}
setMaxWidth
/>
</OrgDropDown>
)}
<ApplicationCardsWrapper key={organization.id}>
<FormDialogComponent
permissions={organization.userPermissions}
permissionRequired={PERMISSION_TYPE.CREATE_APPLICATION}
trigger={
<ApplicationAddCardWrapper>
<Icon
icon="plus"
iconSize={70}
className="createIcon"
/>
<div className="createnew">Create New</div>
</ApplicationAddCardWrapper>
}
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}
/>
)
);
})}
<PageSectionDivider />
</ApplicationCardsWrapper>
</>
);
})}
</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),
userOrgs: getUserApplicationsOrgsList(state),
currentUser: getCurrentUser(state),
});
const mapDispatchToProps = (dispatch: any) => ({
fetchApplications: () =>
dispatch({ type: ReduxActionTypes.FETCH_APPLICATION_LIST_INIT }),
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,
},
});
}
},
});
export default connect(mapStateToProps, mapDispatchToProps)(Applications);