feat(ui) - dashboard - wip

This commit is contained in:
Shekar Siri 2022-04-07 11:29:40 +02:00
parent ad706ededd
commit 4602de3caf
7 changed files with 102 additions and 121 deletions

View file

@ -35,8 +35,7 @@ function CustomMetricPieChart(props: Props) {
}
}
return (
<div>
<NoContent size="small" show={data.values && data.values.length === 0} >
<NoContent size="small" show={!data.values || data.values.length === 0} >
<ResponsiveContainer height={ 220 } width="100%">
<PieChart>
<Pie
@ -52,105 +51,77 @@ function CustomMetricPieChart(props: Props) {
activeIndex={1}
onClick={onClickHandler}
labelLine={({
cx,
cy,
midAngle,
innerRadius,
outerRadius,
value,
index
}) => {
const RADIAN = Math.PI / 180;
let radius1 = 15 + innerRadius + (outerRadius - innerRadius);
let radius2 = innerRadius + (outerRadius - innerRadius);
let x2 = cx + radius1 * Math.cos(-midAngle * RADIAN);
let y2 = cy + radius1 * Math.sin(-midAngle * RADIAN);
let x1 = cx + radius2 * Math.cos(-midAngle * RADIAN);
let y1 = cy + radius2 * Math.sin(-midAngle * RADIAN);
cx,
cy,
midAngle,
innerRadius,
outerRadius,
value,
index
}) => {
const RADIAN = Math.PI / 180;
let radius1 = 15 + innerRadius + (outerRadius - innerRadius);
let radius2 = innerRadius + (outerRadius - innerRadius);
let x2 = cx + radius1 * Math.cos(-midAngle * RADIAN);
let y2 = cy + radius1 * Math.sin(-midAngle * RADIAN);
let x1 = cx + radius2 * Math.cos(-midAngle * RADIAN);
let y1 = cy + radius2 * Math.sin(-midAngle * RADIAN);
const percentage = value * 100 / data.values.reduce((a, b) => a + b.sessionCount, 0);
if (percentage<3){
return null;
}
return(
<line x1={x1} y1={y1} x2={x2} y2={y2} stroke="#3EAAAF" strokeWidth={1} />
)
}}
label={({
cx,
cy,
midAngle,
innerRadius,
outerRadius,
value,
index
}) => {
const RADIAN = Math.PI / 180;
let radius = 20 + innerRadius + (outerRadius - innerRadius);
let x = cx + radius * Math.cos(-midAngle * RADIAN);
let y = cy + radius * Math.sin(-midAngle * RADIAN);
const percentage = (value / data.values.reduce((a, b) => a + b.sessionCount, 0)) * 100;
let name = data.values[index].name || 'Unidentified';
name = name.length > 20 ? name.substring(0, 20) + '...' : name;
if (percentage<3){
return null;
}
return (
<text
x={x}
y={y}
fontWeight="400"
fontSize="12px"
// fontFamily="'Source Sans Pro', 'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif'"
textAnchor={x > cx ? "start" : "end"}
dominantBaseline="central"
fill='#666'
>
{name || 'Unidentified'} {numberWithCommas(value)}
</text>
);
}}
// label={({
// cx,
// cy,
// midAngle,
// innerRadius,
// outerRadius,
// value,
// index
// }) => {
// const RADIAN = Math.PI / 180;
// const radius = 30 + innerRadius + (outerRadius - innerRadius);
// const x = cx + radius * Math.cos(-midAngle * RADIAN);
// const y = cy + radius * Math.sin(-midAngle * RADIAN);
// return (
// <text
// x={x}
// y={y}
// fill="#3EAAAF"
// textAnchor={x > cx ? "start" : "end"}
// dominantBaseline="top"
// fontSize={10}
// >
// {data.values[index].name} ({value})
// </text>
// );
// }}
const percentage = value * 100 / data.values.reduce((a, b) => a + b.sessionCount, 0);
if (percentage<3){
return null;
}
return(
<line x1={x1} y1={y1} x2={x2} y2={y2} stroke="#3EAAAF" strokeWidth={1} />
)
}}
label={({
cx,
cy,
midAngle,
innerRadius,
outerRadius,
value,
index
}) => {
const RADIAN = Math.PI / 180;
let radius = 20 + innerRadius + (outerRadius - innerRadius);
let x = cx + radius * Math.cos(-midAngle * RADIAN);
let y = cy + radius * Math.sin(-midAngle * RADIAN);
const percentage = (value / data.values.reduce((a, b) => a + b.sessionCount, 0)) * 100;
let name = data.values[index].name || 'Unidentified';
name = name.length > 20 ? name.substring(0, 20) + '...' : name;
if (percentage<3){
return null;
}
return (
<text
x={x}
y={y}
fontWeight="400"
fontSize="12px"
// fontFamily="'Source Sans Pro', 'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif'"
textAnchor={x > cx ? "start" : "end"}
dominantBaseline="central"
fill='#666'
>
{name || 'Unidentified'} {numberWithCommas(value)}
</text>
);
}}
>
{data.values.map((entry, index) => (
{data && data.values && data.values.map((entry, index) => (
<Cell key={`cell-${index}`} fill={Styles.colorsPie[index % Styles.colorsPie.length]} />
))}
))}
</Pie>
<Tooltip {...Styles.tooltip} />
</PieChart>
</ResponsiveContainer>
<div className="text-sm color-gray-medium">Top 5 </div>
</NoContent>
</div>
</NoContent>
)
}

View file

@ -4,17 +4,22 @@ import { NoContent, Pagination } from 'UI';
import { useStore } from 'App/mstore';
import { getRE } from 'App/utils';
import MetricListItem from '../MetricListItem';
import { sliceListPerPage } from 'App/utils';
interface Props { }
function MetricsList(props: Props) {
const { metricStore } = useStore();
const metrics = useObserver(() => metricStore.metrics);
const lenth = metrics.length;
const metricsSearch = useObserver(() => metricStore.metricsSearch);
const filterRE = getRE(metricsSearch, 'i');
const list = useObserver(() => metrics.filter(w => filterRE.test(w.name)));
const filterList = (list) => {
const filterRE = getRE(metricsSearch, 'i');
let _list = list.filter(w => {
return filterRE.test(w.name) || filterRE.test(w.metricType) || filterRE.test(w.owner) ;
});
return _list
}
const list: any = metricsSearch !== '' ? filterList(metrics) : metrics;
const lenth = list.length;
return useObserver(() => (
<NoContent show={lenth === 0} icon="exclamation-circle">
@ -28,7 +33,7 @@ function MetricsList(props: Props) {
<div className="col-span-2">Last Modified</div>
</div>
{list.map((metric: any) => (
{sliceListPerPage(list, metricStore.page - 1, metricStore.pageSize).map((metric: any) => (
<MetricListItem metric={metric} />
))}
</div>

View file

@ -1,22 +1,31 @@
import { useObserver } from 'mobx-react-lite';
import React from 'react';
import React, { useEffect, useState } from 'react';
import { useStore } from 'App/mstore';
import { Icon } from 'UI';
import { debounce } from 'App/utils';
let debounceUpdate: any = () => {}
function MetricsSearch(props) {
const { dashboardStore } = useStore();
const metricsSearch = useObserver(() => dashboardStore.metricsSearch);
const { metricStore } = useStore();
const [query, setQuery] = useState(metricStore.metricsSearch);
useEffect(() => {
debounceUpdate = debounce((key, value) => metricStore.updateKey(key, value), 500);
}, [])
const write = ({ target: { name, value } }) => {
setQuery(value);
debounceUpdate('metricsSearch', value);
}
return useObserver(() => (
<div className="relative">
<Icon name="search" className="absolute top-0 bottom-0 ml-2 m-auto" size="18" />
<input
value={metricsSearch}
value={query}
name="metricsSearch"
className="bg-white p-2 border rounded w-full pl-10"
placeholder="Filter by title, type, dashboard and owner"
onChange={({ target: { name, value } }) => dashboardStore.updateKey(name, value)}
onChange={write}
/>
</div>
));

View file

@ -59,10 +59,8 @@ function WidgetForm(props: Props) {
if (wasCreating) {
if (parseInt(dashboardId) > 0) {
history.push(withSiteId(dashboardMetricDetails(parseInt(dashboardId), metric.metricId), siteId));
history.go(0)
} else {
history.push(withSiteId(metricDetails(metric.metricId), siteId));
history.go(0)
}
}

View file

@ -18,11 +18,7 @@ function WidgetView(props: Props) {
const { metricStore } = useStore();
const widget = useObserver(() => metricStore.instance);
const loading = useObserver(() => metricStore.isLoading);
const [expanded, setExpanded] = useState(false);
useEffect(() => {
setExpanded(!widget.exists())
}, [widget])
const [expanded, setExpanded] = useState(!metricId || metricId === 'create');
React.useEffect(() => {
if (metricId && metricId !== 'create') {

View file

@ -43,7 +43,7 @@ export default class MetricStore implements IMetricStore {
instance: IWidget = new Widget()
page: number = 1
pageSize: number = 10
pageSize: number = 4
metricsSearch: string = ""
sort: any = {}
@ -74,14 +74,14 @@ export default class MetricStore implements IMetricStore {
paginatedList: computed,
})
// reaction(
// () => this.metricsSearch,
// (metricsSearch) => { // TODO filter the list for View
// console.log('metricsSearch', metricsSearch)
// this.page = 1
// this.paginatedList()
// }
// )
reaction(
() => this.metricsSearch,
(metricsSearch) => { // TODO filter the list for View
console.log('metricsSearch', metricsSearch)
this.page = 1
this.paginatedList
}
)
}
// State Actions
@ -140,6 +140,7 @@ export default class MetricStore implements IMetricStore {
if (wasCreating) {
toast.success('Metric created successfully')
this.addToList(_metric)
this.instance = _metric
} else {
toast.success('Metric updated successfully')
this.updateInList(_metric)

View file

@ -112,7 +112,8 @@ export default class Widget implements IWidget {
this.series = json.series ? json.series.map((series: any) => new FilterSeries().fromJson(series)) : [],
this.dashboards = json.dashboards
this.owner = json.ownerEmail
this.lastModified = DateTime.fromMillis(json.editedAt || json.createdAt)
// this.lastModified = json.editedAt || json.createdAt ? DateTime.fromMillis(json.editedAt || json.createdAt) : null
this.lastModified = DateTime.fromMillis(1649319074)
this.config = json.config
this.position = json.config.position
})