Skip to content

Commit

Permalink
refactor(dashboard): dashboard to react [unstable]
Browse files Browse the repository at this point in the history
  • Loading branch information
polonel committed Jul 2, 2022
1 parent b38a81e commit 2dad102
Show file tree
Hide file tree
Showing 33 changed files with 1,257 additions and 840 deletions.
4 changes: 3 additions & 1 deletion gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ module.exports = function (grunt) {
'src/public/js/vendor/shepherd/css/shepherd-theme-square.css',
'src/public/js/vendor/shepherd/css/shepherd-theme-square-dark.css',
'src/public/js/vendor/easymde/dist/easymde.min.css',
'src/public/js/vendor/grapesjs/css/grapes.min.css'
'src/public/js/vendor/grapesjs/css/grapes.min.css',
'node_modules/react-grid-layout/css/styles.css',
'node_modules/react-resizable/css/styles.css'
]
}
},
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@
"react": "17.0.2",
"react-colorful": "5.5.1",
"react-dom": "17.0.2",
"react-grid-layout": "1.3.4",
"react-html-parser": "2.0.2",
"react-infinite-scroller": "1.2.5",
"react-redux": "7.2.6",
"react-singleton-hook": "3.4.0",
"react-sizeme": "3.0.2",
"redis": "4.0.3",
"redux": "4.1.2",
"redux-actions": "2.6.5",
Expand Down
2 changes: 1 addition & 1 deletion public/css/plugins.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/css/plugins.min.css

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions src/client/actions/dashboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* . .o8 oooo
* .o8 "888 `888
* .o888oo oooo d8b oooo oooo .oooo888 .ooooo. .oooo.o 888 oooo
* 888 `888""8P `888 `888 d88' `888 d88' `88b d88( "8 888 .8P'
* 888 888 888 888 888 888 888ooo888 `"Y88b. 888888.
* 888 . 888 888 888 888 888 888 .o o. )88b 888 `88b.
* "888" d888b `V88V"V8P' `Y8bod88P" `Y8bod8P' 8""888P' o888o o888o
* ========================================================================
* Author: Chris Brame
* Updated: 7/2/22 5:23 AM
* Copyright (c) 2014-2022. Trudesk Inc (Chris Brame) All rights reserved.
*/

import { createAction } from 'redux-actions'
import {
FETCH_DASHBOARD_DATA,
FETCH_DASHBOARD_TOP_GROUPS,
FETCH_DASHBOARD_TOP_TAGS,
FETCH_DASHBOARD_OVERDUE_TICKETS
} from 'actions/types'

export const fetchDashboardData = createAction(
FETCH_DASHBOARD_DATA.ACTION,
payload => payload,
() => ({ thunk: true })
)

export const fetchDashboardTopGroups = createAction(FETCH_DASHBOARD_TOP_GROUPS.ACTION, payload => payload)
export const fetchDashboardTopTags = createAction(FETCH_DASHBOARD_TOP_TAGS.ACTION, payload => payload)
export const fetchDashboardOverdueTickets = createAction(FETCH_DASHBOARD_OVERDUE_TICKETS.ACTION)
10 changes: 10 additions & 0 deletions src/client/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ export const FETCH_VIEWDATA = defineAction('FETCH_VIEWDATA', [SUCCESS, PENDING,
// Common Nav Change
export const NAV_CHANGE = defineAction('NAV_CHANGE')

// Dashboard
export const FETCH_DASHBOARD_DATA = defineAction('FETCH_DASHBOARD_DATA', [SUCCESS, PENDING, ERROR])
export const FETCH_DASHBOARD_TOP_GROUPS = defineAction('FETCH_DASHBOARD_TOP_GROUPS', [SUCCESS, PENDING, ERROR])
export const FETCH_DASHBOARD_TOP_TAGS = defineAction('FETCH_DASHBOARD_TOP_TAGS', [SUCCESS, PENDING, ERROR])
export const FETCH_DASHBOARD_OVERDUE_TICKETS = defineAction('FETCH_DASHBOARD_OVERDUE_TICKETS', [
SUCCESS,
PENDING,
ERROR
])

// Tickets
export const FETCH_TICKETS = defineAction('FETCH_TICKETS', [SUCCESS, PENDING, ERROR])
export const CREATE_TICKET = defineAction('CREATE_TICKET', [PENDING, SUCCESS, ERROR])
Expand Down
25 changes: 25 additions & 0 deletions src/client/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,31 @@ axios.defaults.headers['CSRF-TOKEN'] = token

const api = {}

api.dashboard = {}
api.dashboard.getData = payload => {
const timespan = payload.timespan || 30
return axios.get(`/api/v1/tickets/stats/${timespan}`).then(res => {
return res.data
})
}
api.dashboard.getTopGroups = payload => {
const timespan = payload.timespan || 30
return axios.get(`/api/v1/tickets/count/topgroups/${timespan}`).then(res => {
return res.data
})
}
api.dashboard.getTopTags = payload => {
const timespan = payload.timespan || 30
return axios.get(`/api/v1/tickets/count/tags/${timespan}`).then(res => {
return res.data
})
}
api.dashboard.getOverdueTickets = () => {
return axios.get('/api/v1/tickets/overdue').then(res => {
return res.data
})
}

api.tickets = {}
api.tickets.getWithPage = payload => {
const limit = payload.limit ? payload.limit : 50
Expand Down
48 changes: 48 additions & 0 deletions src/client/components/CountUp/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { useRef, useEffect } from 'react'
import PropTypes from 'prop-types'
import useTrudeskReady from 'lib2/useTrudeskReady'

import CountUpJS from 'countup'

export default function CountUp (props) {
const textRef = useRef()
let animation = useRef()

// useTrudeskReady(() => {
// if (textRef.current) {
// textRef.current.innerText = '--'
// animation = new CountUpJS(textRef.current, props.startNumber, props.endNumber, 0, props.duration)
// setTimeout(() => {
// animation.start()
// }, 500)
// }
// })

useEffect(() => {
if (textRef.current) {
textRef.current.innerText = '--'
animation = new CountUpJS(textRef.current, props.startNumber, props.endNumber, 0, props.duration)
animation.start()
}
}, [props.startNumber, props.endNumber])

return (
<div>
<span ref={textRef}>--</span>
{props.extraText && ` ${props.extraText}`}
</div>
)
}

CountUp.propTypes = {
startNumber: PropTypes.number,
endNumber: PropTypes.number,
extraText: PropTypes.string,
duration: PropTypes.number
}

CountUp.defaultProps = {
startNumber: 0,
endNumber: 0,
duration: 1.5
}
79 changes: 79 additions & 0 deletions src/client/components/D3/d3pie.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React, { useRef, useEffect } from 'react'
import PropTypes from 'prop-types'
import { shuffle, map, zipObject } from 'lodash'

import * as d3 from 'vendor/d3/d3.min'
import 'd3pie'
import * as c3 from 'c3'

export default function D3Pie (props) {
const pieChart = useRef()
let mappedColors = []

useEffect(() => {
if (pieChart.current && props.data.length > 0) {
mappedColors = shuffle(props.colors)
mappedColors = zipObject(
map(props.data, v => v[0]),
mappedColors
)

c3.generate({
bindto: d3.select(pieChart.current),
size: {
height: props.size
},
data: {
columns: props.data,
type: props.type,
colors: mappedColors,
empty: { label: { text: props.emptyLabel } }
},
donut: {
label: {
format: () => ''
}
}
})
}
}, [pieChart.current, props.data])

return (
<div>
<div ref={pieChart}></div>
</div>
)
}

D3Pie.propTypes = {
data: PropTypes.array.isRequired,
type: PropTypes.string,
size: PropTypes.number,
emptyLabel: PropTypes.string,
colors: PropTypes.arrayOf(PropTypes.string)
}

D3Pie.defaultProps = {
data: [],
type: 'pie',
size: 200,
emptyLabel: 'No Data Available',
colors: [
'#e74c3c',
'#3498db',
'#9b59b6',
'#34495e',
'#1abc9c',
'#2ecc71',
'#03A9F4',
'#00BCD4',
'#009688',
'#4CAF50',
'#FF5722',
'#CDDC39',
'#FFC107',
'#00E5FF',
'#E040FB',
'#607D8B'
]
}
60 changes: 60 additions & 0 deletions src/client/components/MGraph/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useRef, useEffect } from 'react'
import PropTypes from 'prop-types'

import d3 from 'd3'
import MG from 'metricsgraphics'

const noDataDiv = <div className='no-data-available-text'>No Data Available</div>

export default function MGraph (props) {
const graphRef = useRef()
let graphParams = {}

useEffect(() => {
if (props.data && graphRef.current && props.data.length > 0) {
graphRef.current.innerHTML = ''
graphParams = {
full_width: props.fullWidth,
height: props.height,
x_accessor: props.x_accessor,
y_accessor: props.y_accessor,
y_extended_ticks: props.y_extended_ticks,
show_tooltips: props.showTooltips,
aggregate_rollover: props.aggregate_rollover,
transition_on_update: props.transition_on_update,
colors: props.colors,
target: graphRef.current
}
if (props.area) graphParams.area = [1]

graphParams.data = MG.convert.date(props.data, 'date')
MG.data_graphic(graphParams)
}
}, [props.data])

return <div ref={graphRef}>{props.data && props.data.length < 1 && noDataDiv}</div>
}

MGraph.propTypes = {
data: PropTypes.arrayOf(PropTypes.object),
fullWidth: PropTypes.bool,
height: PropTypes.number,
area: PropTypes.bool,
x_accessor: PropTypes.string,
y_accessor: PropTypes.string,
y_extended_ticks: PropTypes.bool,
showTooltips: PropTypes.bool,
aggregate_rollover: PropTypes.bool,
transition_on_update: PropTypes.bool,
colors: PropTypes.arrayOf(PropTypes.string)
}

MGraph.defaultProps = {
fullWidth: true,
area: true,
y_extended_ticks: true,
showTooltips: false,
aggregate_rollover: true,
transition_on_update: false,
colors: ['#2196f3']
}
41 changes: 41 additions & 0 deletions src/client/components/Peity/peity-bar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React, { useEffect, useRef } from 'react'

import $ from 'jquery'
import 'peity'
import PropTypes from 'prop-types'

export default function PeityBar (props) {
const barRef = useRef()

useEffect(() => {
if (barRef.current) {
$(barRef.current).peity('bar', {
height: props.height,
width: props.width,
fill: props.fill,
padding: props.padding
})
}
}, [])

return (
<div>
<span ref={barRef}>{props.values}</span>
</div>
)
}

PeityBar.propTypes = {
values: PropTypes.string.isRequired,
height: PropTypes.number,
width: PropTypes.number,
fill: PropTypes.arrayOf(PropTypes.string),
padding: PropTypes.number
}

PeityBar.defaultProps = {
height: 28,
width: 48,
fill: ['#e74c3c'],
padding: 0.2
}
40 changes: 40 additions & 0 deletions src/client/components/Peity/peity-line.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { useEffect, useRef } from 'react'

import $ from 'jquery'
import 'peity'
import PropTypes from 'prop-types'

export default function PeityLine ({ height, width, fill, stroke, values }) {
const lineRef = useRef()
useEffect(() => {
if (lineRef.current) {
$(lineRef.current).peity('line', {
height,
width,
fill,
stroke
})
}
}, [])

return (
<div>
<span ref={lineRef}>{values}</span>
</div>
)
}

PeityLine.propTypes = {
values: PropTypes.string.isRequired,
height: PropTypes.number,
width: PropTypes.number,
fill: PropTypes.string,
stroke: PropTypes.string
}

PeityLine.defaultProps = {
height: 28,
width: 64,
fill: '#d1e4f6',
stroke: '#0288d1'
}
Loading

0 comments on commit 2dad102

Please sign in to comment.