2019-11-07 04:59:40 +00:00
|
|
|
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";
|
2020-06-03 13:54:42 +00:00
|
|
|
import Button from "components/editorComponents/Button";
|
2019-11-07 04:59:40 +00:00
|
|
|
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,
|
2019-11-25 05:07:27 +00:00
|
|
|
} from "selectors/applicationSelectors";
|
2019-11-07 04:59:40 +00:00
|
|
|
import {
|
|
|
|
|
ReduxActionTypes,
|
|
|
|
|
ApplicationPayload,
|
2019-11-25 05:07:27 +00:00
|
|
|
} from "constants/ReduxActionConstants";
|
2019-12-23 12:16:33 +00:00
|
|
|
import PageWrapper from "pages/common/PageWrapper";
|
2019-11-21 10:52:49 +00:00
|
|
|
import SubHeader from "pages/common/SubHeader";
|
2019-12-23 12:16:33 +00:00
|
|
|
import PageSectionDivider from "pages/common/PageSectionDivider";
|
2019-11-21 10:52:49 +00:00
|
|
|
import ApplicationCard from "./ApplicationCard";
|
2019-11-07 04:59:40 +00:00
|
|
|
import CreateApplicationForm from "./CreateApplicationForm";
|
2020-06-03 13:54:42 +00:00
|
|
|
import InviteUsersFormv2 from "pages/organization/InviteUsersFromv2";
|
2020-06-17 04:17:25 +00:00
|
|
|
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";
|
2020-05-14 10:47:13 +00:00
|
|
|
import FormDialogComponent from "components/editorComponents/form/FormDialogComponent";
|
|
|
|
|
import OrganizationListMockResponse from "mockResponses/OrganisationListResponse";
|
2020-05-27 13:36:06 +00:00
|
|
|
import { User } from "constants/userConstants";
|
2020-06-11 11:31:32 +00:00
|
|
|
import CustomizedDropdown, {
|
|
|
|
|
CustomizedDropdownProps,
|
|
|
|
|
} from "pages/common/CustomizedDropdown";
|
2020-05-27 13:36:06 +00:00
|
|
|
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";
|
2020-06-17 04:17:25 +00:00
|
|
|
import { IntentColors } from "constants/DefaultTheme";
|
2020-05-27 13:36:06 +00:00
|
|
|
|
|
|
|
|
const OrgDropDown = styled.div`
|
|
|
|
|
display: flex;
|
|
|
|
|
padding: 0px 30px;
|
|
|
|
|
font-size: ${props => props.theme.fontSizes[1]}px;
|
2020-06-03 13:54:42 +00:00
|
|
|
justify-content: space-between;
|
2020-05-27 13:36:06 +00:00
|
|
|
`;
|
2019-11-07 04:59:40 +00:00
|
|
|
|
|
|
|
|
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;
|
2020-05-20 14:09:51 +00:00
|
|
|
font-size: ${props => props.theme.fontSizes[4]}px;
|
2019-11-07 04:59:40 +00:00
|
|
|
`;
|
|
|
|
|
|
2020-05-20 14:09:51 +00:00
|
|
|
const OrgName = styled.div`
|
2020-06-17 04:17:25 +00:00
|
|
|
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;
|
|
|
|
|
}
|
2020-05-20 14:09:51 +00:00
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const ApplicationAddCardWrapper = styled(Card)`
|
2020-05-14 10:47:13 +00:00
|
|
|
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%;
|
|
|
|
|
}
|
2020-06-18 12:31:56 +00:00
|
|
|
cursor: pointer;
|
2020-05-14 10:47:13 +00:00
|
|
|
`;
|
|
|
|
|
|
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;`}
|
|
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
2019-11-07 04:59:40 +00:00
|
|
|
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;
|
2020-05-27 13:36:06 +00:00
|
|
|
getAllApplication: () => void;
|
2020-06-10 08:29:21 +00:00
|
|
|
userOrgs: any;
|
2020-05-27 13:36:06 +00:00
|
|
|
currentUser?: User;
|
2019-11-07 04:59:40 +00:00
|
|
|
};
|
2020-06-11 11:31:32 +00:00
|
|
|
class Applications extends Component<
|
|
|
|
|
ApplicationProps,
|
|
|
|
|
{ selectedOrgId: string }
|
|
|
|
|
> {
|
|
|
|
|
constructor(props: ApplicationProps) {
|
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
|
selectedOrgId: "",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-07 04:59:40 +00:00
|
|
|
componentDidMount() {
|
2020-05-27 13:36:06 +00:00
|
|
|
this.props.getAllApplication();
|
2019-11-07 04:59:40 +00:00
|
|
|
}
|
2020-06-11 11:31:32 +00:00
|
|
|
|
2019-11-07 04:59:40 +00:00
|
|
|
public render() {
|
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,
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2019-11-07 04:59:40 +00:00
|
|
|
return (
|
2019-12-23 12:16:33 +00:00
|
|
|
<PageWrapper displayName="Applications">
|
2020-02-03 12:19:10 +00:00
|
|
|
{this.props.deletingApplication
|
|
|
|
|
? AppToaster.show({ message: DELETING_APPLICATION })
|
|
|
|
|
: AppToaster.clear()}
|
2019-12-23 12:16:33 +00:00
|
|
|
<SubHeader
|
2020-05-27 13:36:06 +00:00
|
|
|
add={{
|
|
|
|
|
form: CreateOrganizationForm,
|
|
|
|
|
title: "Create Organization",
|
|
|
|
|
formName: CREATE_ORGANIZATION_FORM_NAME,
|
|
|
|
|
formSubmitIntent: "primary",
|
|
|
|
|
isAdding: false,
|
|
|
|
|
formSubmitText: "Create",
|
|
|
|
|
onClick: () => {
|
|
|
|
|
return null;
|
|
|
|
|
},
|
|
|
|
|
}}
|
2019-12-23 12:16:33 +00:00
|
|
|
search={{
|
|
|
|
|
placeholder: "Search",
|
2020-01-20 08:07:00 +00:00
|
|
|
queryFn: this.props.searchApplications,
|
2019-12-23 12:16:33 +00:00
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<PageSectionDivider />
|
2020-06-10 08:29:21 +00:00
|
|
|
{this.props.userOrgs &&
|
2020-06-18 12:16:46 +00:00
|
|
|
this.props.userOrgs.length !== 0 &&
|
2020-06-10 08:29:21 +00:00
|
|
|
this.props.userOrgs.map((organizationObject: any) => {
|
2020-05-27 13:36:06 +00:00
|
|
|
const { organization, applications } = organizationObject;
|
2020-05-14 10:47:13 +00:00
|
|
|
|
2020-05-27 13:36:06 +00:00
|
|
|
return (
|
|
|
|
|
<>
|
2020-06-17 04:17:25 +00:00
|
|
|
{!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
|
|
|
|
2020-06-17 04:17:25 +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>
|
|
|
|
|
)}
|
2020-05-27 13:36:06 +00:00
|
|
|
<ApplicationCardsWrapper key={organization.id}>
|
2020-05-14 10:47:13 +00:00
|
|
|
<FormDialogComponent
|
2020-05-27 13:36:06 +00:00
|
|
|
permissions={organization.userPermissions}
|
|
|
|
|
permissionRequired={PERMISSION_TYPE.CREATE_APPLICATION}
|
2020-05-14 10:47:13 +00:00
|
|
|
trigger={
|
2020-05-20 14:09:51 +00:00
|
|
|
<ApplicationAddCardWrapper>
|
2020-05-27 13:36:06 +00:00
|
|
|
<Icon
|
2020-05-14 10:47:13 +00:00
|
|
|
icon="plus"
|
2020-05-20 14:09:51 +00:00
|
|
|
iconSize={70}
|
2020-05-14 10:47:13 +00:00
|
|
|
className="createIcon"
|
|
|
|
|
/>
|
2020-05-20 14:09:51 +00:00
|
|
|
<div className="createnew">Create New</div>
|
|
|
|
|
</ApplicationAddCardWrapper>
|
2020-05-14 10:47:13 +00:00
|
|
|
}
|
|
|
|
|
Form={CreateApplicationForm}
|
2020-05-27 13:36:06 +00:00
|
|
|
orgId={organization.id}
|
2020-05-14 10:47:13 +00:00
|
|
|
title={"Create Application"}
|
|
|
|
|
/>
|
2020-05-27 13:36:06 +00:00
|
|
|
{applications.map((application: any) => {
|
|
|
|
|
return (
|
|
|
|
|
application.pages?.length > 0 && (
|
|
|
|
|
<ApplicationCard
|
|
|
|
|
key={application.id}
|
|
|
|
|
application={application}
|
|
|
|
|
delete={this.props.deleteApplication}
|
|
|
|
|
/>
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
})}
|
|
|
|
|
<PageSectionDivider />
|
|
|
|
|
</ApplicationCardsWrapper>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
})}
|
2019-12-23 12:16:33 +00:00
|
|
|
</PageWrapper>
|
2019-11-07 04:59:40 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
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),
|
2020-06-10 08:29:21 +00:00
|
|
|
userOrgs: getUserApplicationsOrgsList(state),
|
2020-05-27 13:36:06 +00:00
|
|
|
currentUser: getCurrentUser(state),
|
2019-11-07 04:59:40 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const mapDispatchToProps = (dispatch: any) => ({
|
|
|
|
|
fetchApplications: () =>
|
|
|
|
|
dispatch({ type: ReduxActionTypes.FETCH_APPLICATION_LIST_INIT }),
|
2020-05-27 13:36:06 +00:00
|
|
|
getAllApplication: () =>
|
|
|
|
|
dispatch({ type: ReduxActionTypes.GET_ALL_APPLICATION_INIT }),
|
2019-11-07 04:59:40 +00:00
|
|
|
createApplication: (appName: string) => {
|
|
|
|
|
dispatch({
|
|
|
|
|
type: ReduxActionTypes.CREATE_APPLICATION_INIT,
|
|
|
|
|
payload: {
|
|
|
|
|
name: appName,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
},
|
2020-01-20 08:07:00 +00:00
|
|
|
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,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
2019-11-07 04:59:40 +00:00
|
|
|
});
|
|
|
|
|
|
2019-11-22 14:02:55 +00:00
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(Applications);
|