Skip to content

Commit

Permalink
feat(admin-ui): fix maximum actives users page #2
Browse files Browse the repository at this point in the history
  • Loading branch information
syntrydy committed Feb 5, 2022
1 parent c7b4fa4 commit ad157e3
Show file tree
Hide file tree
Showing 9 changed files with 310 additions and 43 deletions.
8 changes: 8 additions & 0 deletions admin-ui/app/routes/Apps/Gluu/styles/applicationstyle.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ export default {
buttonStyle: {
background: 'linear-gradient(90deg, #00C9FF 0%, #92FE9D 100%)',
},
customButtonStyle: {
background: 'linear-gradient(90deg, #00C9FF 0%, #92FE9D 100%)',
paddingLeft: '20px',
paddingRight: '30px',
color: 'white',
fontSize:'1.5em',
fontWeight: 'bold'
},
healthDown: {
background: 'linear-gradient(90deg, #fc575e 0%, #f7b42c 100%)',
},
Expand Down
15 changes: 1 addition & 14 deletions admin-ui/build/webpack.config.client.dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,7 @@ module.exports = {
},
{
test: /\.css$/i,
use: [
MiniCssExtractPlugin.loader,
'style-loader',
'css-loader',
'postcss-loader',
],
exclude: [path.resolve(config.srcDir, 'styles')],
include: [config.srcDir],
use: ["style-loader", "css-loader", "postcss-loader"],
},
{
test: /\.scss$/,
Expand All @@ -102,12 +95,6 @@ module.exports = {
exclude: [path.resolve(config.srcDir, 'styles')],
include: [config.srcDir],
},
// Global Styles
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader','postcss-loader'],
include: [path.resolve(config.srcDir, 'styles')],
},
{
test: /\.scss$/,
use: [
Expand Down
26 changes: 2 additions & 24 deletions admin-ui/build/webpack.config.client.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,20 +102,8 @@ module.exports = {
},
// Modular Styles
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
},
},
{ loader: 'postcss-loader' },
],
exclude: [path.resolve(config.srcDir, 'styles')],
include: [config.srcDir],
test: /\.css$/i,
use: ["style-loader", "css-loader", "postcss-loader"],
},
{
test: /\.scss$/,
Expand All @@ -137,16 +125,6 @@ module.exports = {
exclude: [path.resolve(config.srcDir, 'styles')],
include: [config.srcDir],
},
// Global Styles
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader' },
{ loader: 'postcss-loader' },
],
include: [path.resolve(config.srcDir, 'styles')],
},
{
test: /\.scss$/,
use: [
Expand Down
244 changes: 244 additions & 0 deletions admin-ui/plugins/admin/components/ActiveUsers/ActiveUsers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
import React, { useState, useEffect } from 'react'
import { addMonths, subMonths } from 'date-fns'
import moment from 'moment'
import CustomPieGraph from './CustomPieGraph'
import DatePicker from 'react-datepicker'
import 'react-datepicker/dist/react-datepicker.css'
import GluuLoader from '../../../../app/routes/Apps/Gluu/GluuLoader'
import GluuViewWrapper from '../../../../app/routes/Apps/Gluu/GluuViewWrapper'
import { getMau } from './../../redux/actions/MauActions'
import applicationstyle from '../../../../app/routes/Apps/Gluu/styles/applicationstyle'
import GluuLabel from '../../../../app/routes/Apps/Gluu/GluuLabel'
import GluuRibbon from '../../../../app/routes/Apps/Gluu/GluuRibbon'
import {
Button,
Card,
CardFooter,
CardBody,
FormGroup,
Col,
Row,
} from '../../../../app/components'
import {
hasBoth,
buildPayload,
STAT_READ,
STAT_JANS_READ,
} from '../../../../app/utils/PermChecker'
import {
LineChart,
XAxis,
YAxis,
Line,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
} from 'recharts'
import { useTranslation } from 'react-i18next'
import { connect } from 'react-redux'

function ActiveUsers({ statData, permissions, loading, dispatch }) {
//console.log('=====================>' + JSON.stringify(statData))
statData.push({ month: 202201, mau: 5, cc_at: 68, ac_at: 785, ac_id: 567 })
const { t } = useTranslation()
const [startDate, setStartDate] = useState(subMonths(new Date(), 2))
const [endDate, setEndDate] = useState(addMonths(new Date(), 2))
const userAction = {}
const options = {}
useEffect(() => {
search()
}, [])

function search() {
options['month'] = getFormattedMonth()
buildPayload(userAction, 'GET MAU', options)
dispatch(getMau(userAction))
}

function doDataAugmentation(input) {
let stat = input
if (stat && stat.length >= 1) {
let flattendStat = stat.map((entry) => entry['month'])
let aRange = generateDateRange(moment(startDate), moment(endDate))
for (const ele of aRange) {
const currentMonth = getYearMonth(new Date(ele))
if (flattendStat.indexOf(parseInt(currentMonth, 10)) === -1) {
let newEntry = new Object()
newEntry['month'] = parseInt(getYearMonth(new Date(ele)), 10)
newEntry['mau'] = 0
newEntry['cc_at'] = 0
newEntry['ac_at'] = 0
newEntry['ac_id'] = 0
stat.push(newEntry)
}
}
return Array.from(new Set(stat)).sort(
(a, b) => parseInt(a.month, 10) - parseInt(b.month, 10),
)
}
return stat
}
function getYearMonth(date) {
return date.getFullYear() + getMonth(date)
}
function getFormattedMonth() {
return getYearMonth(startDate) + '%' + getYearMonth(endDate)
}
function getMonth(aDate) {
let value = String(aDate.getMonth() + 1)
if (value.length > 1) {
return value
} else {
return '0' + value
}
}

function generateDateRange(start, end) {
var result = []
while (start.isBefore(end)) {
result.push(start.format('YYYY-MM-01'))
start.add(1, 'month')
}
return result
}

const CustomButton = React.forwardRef(({ value, onClick }, ref) => (
<Button
color="primary"
outline
style={applicationstyle.customButtonStyle}
className="example-custom-input"
onClick={onClick}
ref={ref}
>
{value}
</Button>
))

return (
<GluuLoader blocking={loading}>
<GluuViewWrapper
canShow={hasBoth(permissions, STAT_READ, STAT_JANS_READ)}
>
<Card>
<GluuRibbon title={t('titles.active_users')} fromLeft />
<FormGroup row />
<FormGroup row />
<FormGroup row />
<CardBody>
<Row>
<Col sm={2}></Col>
<Col sm={10}>
<GluuLabel label="Select a date range" size="4" />
<DatePicker
selected={startDate}
onChange={(date) => setStartDate(date)}
selectsStart
isClearable
startDate={startDate}
dateFormat="MM/yyyy"
showMonthYearPicker
endDate={endDate}
customInput={<CustomButton />}
/>
&nbsp;&nbsp;
<DatePicker
selected={endDate}
onChange={(date) => setEndDate(date)}
selectsEnd
isClearable
startDate={startDate}
endDate={endDate}
dateFormat="MM/yyyy"
showMonthYearPicker
minDate={startDate}
maxDate={new Date()}
customInput={<CustomButton />}
/>
&nbsp;&nbsp;
<Button
style={applicationstyle.customButtonStyle}
color="primary"
onClick={search}
>
<i className="fa fa-search mr-2"></i>
{t('actions.view')}
</Button>
</Col>
</Row>
<FormGroup row />
<FormGroup row />
<FormGroup row>
<ResponsiveContainer className="mau" width="80%" height={350}>
<LineChart height={400} data={doDataAugmentation(statData)}>
<XAxis dataKey="month" />
<YAxis />
<CartesianGrid stroke="#eee" strokeDasharray="5 5" />
<Line
name={t('fields.monthly_active_users')}
type="monotone"
dataKey="mau"
stroke="#8884d8"
/>
<Tooltip />
<Legend />
</LineChart>
</ResponsiveContainer>
</FormGroup>
<FormGroup row>
<Col sm={6}>
<CustomPieGraph data={statData} />
</Col>
<Col sm={6}>
<ResponsiveContainer className="bar" width="100%" height={400}>
<LineChart
width={400}
height={400}
data={doDataAugmentation(statData)}
>
<XAxis dataKey="month" />
<YAxis />
<CartesianGrid stroke="#eee" strokeDasharray="5 5" />
<Line
name="Client credentials access token"
type="monotone"
dataKey="cc_at"
stroke="#8884d8"
/>
<Line
name="Authorization code access token"
type="monotone"
dataKey="ac_at"
stroke="#82ca9d"
/>
<Line
name="Authorization code id token"
type="monotone"
dataKey="ac_id"
stroke="#00C9FF"
/>
<Legend />
</LineChart>
</ResponsiveContainer>
</Col>
</FormGroup>
<FormGroup row>
<Col sm={6}></Col>
<Col sm={6}></Col>
</FormGroup>
</CardBody>
<CardFooter className="p-4 bt-0"></CardFooter>
</Card>
</GluuViewWrapper>
</GluuLoader>
)
}
const mapStateToProps = (state) => {
return {
statData: state.mauReducer.stat,
loading: state.mauReducer.loading,
permissions: state.authReducer.permissions,
}
}
export default connect(mapStateToProps)(ActiveUsers)
36 changes: 36 additions & 0 deletions admin-ui/plugins/admin/components/ActiveUsers/CustomPieGraph.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react'
import {
BarChart,
Bar,
XAxis,
YAxis,
Tooltip,
Legend,
CartesianGrid,
ResponsiveContainer,
} from 'recharts'

function CustomPieGraph({ data }) {
return (
<ResponsiveContainer width={400} height={400}>
<BarChart
width={400}
height={400}
data={data.sort(
(a, b) => parseInt(a.month, 10) - parseInt(b.month, 10),
)}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="month" />
<YAxis />
<Tooltip />
<Legend />
<Bar dataKey="cc_at" fill="#00C9FF" />
<Bar dataKey="ac_at" fill="#82ca9d" />
<Bar dataKey="ac_id" fill="#92FE9D" />
</BarChart>
</ResponsiveContainer>
)
}

export default CustomPieGraph
3 changes: 2 additions & 1 deletion admin-ui/plugins/admin/components/MonthlyActiveUsersPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from '../../../app/components'
import GluuLoader from '../../../app/routes/Apps/Gluu/GluuLoader'
import GluuRibbon from '../../../app/routes/Apps/Gluu/GluuRibbon'
import {addMonths, differenceInMonths } from 'date-fns'
import { addMonths, differenceInMonths } from 'date-fns'
import applicationStyle from '../../../app/routes/Apps/Gluu/styles/applicationstyle'
import GluuViewWrapper from '../../../app/routes/Apps/Gluu/GluuViewWrapper'
import {
Expand Down Expand Up @@ -64,6 +64,7 @@ class MonthBox extends Component {
}
}
function MonthlyActiveUsersPage({ stat, permissions, loading, dispatch }) {
console.log('==========================Stat ' + JSON.stringify(stat))
const { t } = useTranslation()
const userAction = {}
const options = {}
Expand Down
3 changes: 2 additions & 1 deletion admin-ui/plugins/admin/plugin-metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import ScriptListPage from './components/CustomScripts/ScriptListPage'
import CustomScriptAddPage from './components/CustomScripts/CustomScriptAddPage'
import CustomScriptEditPage from './components/CustomScripts/CustomScriptEditPage'
import SettingsPage from './components/Settings/SettingsPage'
import ActiveUsersPage from './components/ActiveUsers/ActiveUsers'

import mauSaga from './redux/sagas/MauSaga'
import scriptSaga from './redux/sagas/CustomScriptSaga'
Expand Down Expand Up @@ -95,7 +96,7 @@ const pluginMetadata = {
permission: ACR_READ,
},
{
component: MonthlyActiveUsersPage,
component: ActiveUsersPage,
path: PLUGIN_BASE_APTH + '/mau',
permission: ACR_READ,
},
Expand Down
Loading

0 comments on commit ad157e3

Please sign in to comment.