kpi-header
Version:
KPI-header plugin for KPI NINJA react UI
508 lines (471 loc) • 16 kB
JavaScript
import React, {Fragment} from "react";
import Ionicon from "react-ionicons";
import {
Button,
Col,
Dropdown,
DropdownMenu,
DropdownToggle,
Modal,
ModalBody,
ModalFooter,
ModalHeader,
Row,
UncontrolledDropdown
} from "reactstrap";
import Select from "react-select";
import PerfectScrollbar from "react-perfect-scrollbar";
import Tabs from "react-responsive-tabs";
// Dropdown Tabs Content
import TimelineEx from "../TabsContent/TimelineExample";
import TimelineExNotification from "../TabsContent/TimelineExampleNotification";
import {getOrgModulesAPI} from '../Services/OrgModuleService';
import {getTimezonesAPI} from '../Services/TimezoneService';
import {
notificationAfterLoginAPI,
notificationAfterLoginEventAPI,
notificationByIdAfterLoginAPI,
notificationReadByIdAPI,
downloadNotificationAttachmentAPI
} from '../Services/NotificationService';
class HeaderDots extends React.Component {
constructor(props) {
super(props);
this.state = {
active: false,
selectedTimezone: {},
selectedItem: {},
quickAccess: "",
logo: "",
flag: false,
showTabs: false,
timezoneList: [],
companyTimezone: null,
numberOfNotifications: 0,
readNotificationStatus: false,
unreadNotificationCount: 0
};
}
setTabs = () => {
this.setState({
tabs: [
{
title: "Notification",
content: <TimelineExNotification openModal={this.openModal}
userApi={this.props['userApi']}
authApi={this.props['authApi']}
authUrl={this.props['authUrl']}/>
},
{
title: "Events",
content: <TimelineEx openModal={this.openModal}
userApi={this.props['userApi']}
authApi={this.props['authApi']}
authUrl={this.props['authUrl']}
/>
}
]
});
};
dashboardAPI = () => {
getOrgModulesAPI(this.props['userApi']).then(response => {
this.setState({
quickAccess: response.data.modules,
flag: true
});
});
};
getTimeZone = () => {
getTimezonesAPI(this.props['userApi']).then(response => {
let timezoneList = [];
let companyTimezone = {};
let flag = false;
let browserTz = "";
let selectedTz = "";
if (
response.status &&
response.data != null &&
response.data["companyTimezone"] != null
) {
companyTimezone = response.data["companyTimezone"];
selectedTz = {
label: companyTimezone["name"] + " GMT" + companyTimezone["value"],
name: companyTimezone["name"],
timezoneid: companyTimezone["id"],
value: companyTimezone["value"] + "&" + companyTimezone["id"],
finalValue: companyTimezone["value"]
};
} else {
let offset = new Date().getTimezoneOffset();
let o = Math.abs(offset);
browserTz =
(offset < 0 ? "+" : "-") +
("00" + Math.floor(o / 60)).slice(-2) +
":" +
("00" + (o % 60)).slice(-2);
}
if (
response.status &&
response.data != null &&
response.data["timezone"] != null
) {
for (let k in response.data["timezone"]) {
let timezoneObj = response.data["timezone"][k];
let obj = {
label: timezoneObj["name"],
name: timezoneObj["name"],
timezoneid: timezoneObj["id"],
value: timezoneObj["value"] + "&" + timezoneObj["id"]
};
if (!flag && timezoneObj["value"] === browserTz) {
selectedTz = obj;
}
timezoneList.push(obj);
}
}
this.setState({
timezoneList: timezoneList,
companyTimezone: companyTimezone,
selectedItem: selectedTz
});
});
};
async componentDidMount() {
if (this.props['userApi'] && this.props['userApi'] !== ''
&& this.props['authApi'] && this.props['authApi'] !== ''
&& this.props['authUrl'] && this.props['authUrl'] !== '') {
this.setTabs();
this.dashboardAPI();
this.getTimeZone();
this.getNotificationCount();
} else {
console.error("Please provide valid props in component: userApi, authApi, authUrl");
}
}
changeSelect = selectedItem => {
this.setState({
selectedItem: selectedItem
});
localStorage.setItem("timezone", selectedItem);
};
handleTimezone = tz => {
localStorage.setItem("timezone", tz.name);
this.setState({selectedTimezone: tz});
};
openModal = item => {
this.setState({
notificationId: item.id,
readNotificationStatus: item.read_status,
showTabs: !this.state.showTabs
});
notificationByIdAfterLoginAPI(this.props['userApi'], item.id).then(response => {
this.setState({
header: "Notification Details",
title: response.data.categoriesList[0].rootNotifications.title,
cat: response.data.categoriesList[0].rootCategory.category,
time:
response.data.categoriesList[0].rootNotifications.root_companies
.created_on,
logo: response.data.categoriesList[0].rootCategory.logo,
description: response.data.notificationList.notificationDescription,
attachment: response.data.notificationList.attachmentLink,
notes: response.data.notificationList.notes,
modal: !this.state.modal
});
if (!this.state.readNotificationStatus) {
notificationReadByIdAPI(this.props['userApi'], item.id);
}
});
};
downloadNotification = id => {
downloadNotificationAttachmentAPI(this.props['authApi'], id).then(response => {
window.open(response.data, "_blank");
});
};
getTabs = () => {
let x = [
{
title: "Notification",
content: (
<TimelineExNotification
changeNumberOfNotifications={this.changeNumberOfNotifications}
openModal={this.openModal}
userApi={this.props['userApi']}
authApi={this.props['authApi']}
authUrl={this.props['authUrl']}
/>
)
},
{
title: "Events",
content: <TimelineEx openModal={this.openModal}
userApi={this.props['userApi']}
authApi={this.props['authApi']}
authUrl={this.props['authUrl']}
/>
}
];
return x.map((tab, index) => ({
title: tab.title,
getContent: () => tab.content,
key: index
}));
};
showTabs = () => {
this.setState({
showTabs: true
});
};
toggleModal = () => {
this.setState(
{
modal: !this.state.modal
},
this.toggleTab()
);
};
toggleTab = () => {
this.setState({
showTabs: !this.state.showTabs
});
};
closeModal = () => {
this.setState({
modal: !this.state.modal
});
};
changeNumberOfNotifications = numberOfNotifications => {
this.setState({
numberOfNotifications: numberOfNotifications
});
};
getNotificationCount = () => {
let count = 0;
notificationAfterLoginAPI(this.props['userApi'], 0)
.then(response => {
count =
count + response.data.unReadCountList[0].root_notification_count;
})
.then(() => {
notificationAfterLoginEventAPI(this.props['userApi'], 0).then(response => {
count =
count + response.data.unReadCountList[0].root_notification_count;
});
})
.then(() => {
this.setState({
unreadNotificationCount: count
});
});
};
render() {
return (
<Fragment>
<div className="header-dots">
<UncontrolledDropdown>
<DropdownToggle className="p-0 mr-2" color="default">
<div className="icon-wrapper icon-wrapper-alt rounded-circle round-bg-gray">
<div
className="icon-wrapper-bg bg-danger"
style={{backgroundColor: "#ffffff !important"}}
/>
<i className="fal fa-clock" style={{fontSize: "24px"}}/>
</div>
</DropdownToggle>
<DropdownMenu right className="dropdown-menu-xl rm-pointers p-2">
<Select
options={this.state.timezoneList}
value={this.state.selectedItem}
onChange={this.changeSelect}
/>
</DropdownMenu>
</UncontrolledDropdown>
<UncontrolledDropdown>
<Dropdown
isOpen={this.state.showTabs}
toggle={() => this.toggleTab()}
>
<DropdownToggle className="p-0 mr-2" color="link">
<div className="icon-wrapper icon-wrapper-alt rounded-circle round-bg-gray">
<div
className="icon-wrapper-bg bg-danger"
style={{backgroundColor: "#ffffff !important"}}
/>
<Ionicon
beat={false}
color="#d92550"
fontSize="23px"
icon="md-notifications-outline"
/>
{this.state.unreadNotificationCount !== 0 && (
<div className="badge badge-dot badge-dot-sm badge-danger">
Notifications1
</div>
)}
</div>
</DropdownToggle>
<DropdownMenu right className="dropdown-menu-xl rm-pointers">
<div className="dropdown-menu-header">
<div className="dropdown-menu-header-inner bg-deep-blue">
<div
className="menu-header-image opacity-1"
/>
<div className="menu-header-content text-dark">
<h5 className="menu-header-title">Notifications</h5>
<h6 className="menu-header-subtitle">
You have <b>{this.state.numberOfNotifications}</b>{" "}
unread messages
</h6>
</div>
</div>
</div>
<div>
{this.state.showTabs && (
<Tabs
tabsWrapperClass="body-tabs body-tabs-alt"
transform={false}
showInkBar={true}
items={this.getTabs()}
/>
)}
</div>
</DropdownMenu>
</Dropdown>
</UncontrolledDropdown>
<UncontrolledDropdown>
<DropdownToggle className="p-0 mr-2" color="link">
<div className="icon-wrapper icon-wrapper-alt rounded-circle round-bg-gray">
<div
className="icon-wrapper-bg bg-primary"
style={{backgroundColor: "#ffffff !important"}}
/>
<Ionicon color="#3f6ad8" fontSize="23px" icon="md-grid"/>
</div>
</DropdownToggle>
<DropdownMenu right className="dropdown-menu-xl rm-pointers">
<div className="scroll-area-md">
<PerfectScrollbar>
<div className="grid-menu grid-menu-xl grid-menu-3col">
<Row className="no-gutters">
<Col xl="4" sm="6">
<a
style={{textDecoration: "none", color: "#474f56"}}
href={this.props['authUrl']}
>
<Button
className="btn-icon-vertical btn-square btn-transition"
outline
color="link"
>
<i
className="fal fa-home fa-3x mt-2"
style={{color: "#6437ff"}}
/>
<br/>
<span className="mt-1">Universe</span>
</Button>
</a>
</Col>
{this.state.quickAccess &&
this.state.quickAccess.map(items => {
return (
<Col xl="4" sm="6" key={items.id}>
<a
href={items.root_modules_id.moduleUrl}
style={{
textDecoration: "none",
color: "#474f56"
}}
>
<Button
className="btn-icon-vertical btn-square btn-transition"
outline
color="link"
>
<i
className={`${
items.root_modules_id.icon
} fa-3x mt-2`}
style={{color: "#6437ff"}}
/>
<br/>
<span className="mt-1">
{items.root_modules_id.name}
</span>
</Button>
</a>
</Col>
);
})}
</Row>
</div>
</PerfectScrollbar>
</div>
</DropdownMenu>
</UncontrolledDropdown>
</div>
<Modal isOpen={this.state.modal} toggle={this.closeModal} size={"lg"}>
<ModalHeader toggle={this.toggleModal}>
{this.state.header}
</ModalHeader>
<ModalBody>
<b>Title: </b> {this.state.title}
<br/>
<b>Category: </b> {this.state.header} -
{this.state.logo &&
this.state.logo.split(",").map(i => {
return (
<i key={i} className={i}>
{" "}
</i>
);
})}
<br/>
{this.state.attachment ? (
<span>
<b>Download: </b>
<i
style={{cursor: "pointer"}}
className={"fa fa-download"}
onClick={() =>
this.downloadNotification(this.state.notificationId)
}
/>
</span>
) : null}
<div className={"divider"}/>
{this.state.description && (
<div
dangerouslySetInnerHTML={{__html: this.state.description}}
/>
)}
{this.state.notes && (
<span className={"mt-2"}>
<textarea
rows="3"
cols="100"
className="form-control"
id="notesDetails"
name="notes"
readOnly="readonly"
value={this.state.notes}
/>
</span>
)}
{this.state.description}
</ModalBody>
<ModalFooter>
<Button
color="secondary"
className=""
onClick={() => this.toggleModal()}
>
Cancel
</Button>
</ModalFooter>
</Modal>
</Fragment>
);
}
}
export default HeaderDots;