feat(ui) - dashboards wip

This commit is contained in:
Shekar Siri 2022-03-28 15:07:08 +02:00
parent b551fd5084
commit 81e0aff1fd
8 changed files with 113 additions and 25 deletions

View file

@ -0,0 +1,59 @@
import { useObserver } from 'mobx-react-lite';
import React from 'react';
import { Input } from 'UI';
import { useDashboardStore } from '../../store/store';
import cn from 'classnames';
interface Props {
}
function DashboardForm(props) {
const store: any = useDashboardStore();
const dashboard = store.newDashboard;
const write = ({ target: { value, name } }) => dashboard.update({ [ name ]: value })
const writeRadio = ({ target: { value, name } }) => {
dashboard.update({ [name]: value === 'team' });
}
return useObserver(() => (
<div className="mb-8 grid grid-cols-2 gap-8">
<div className="form-field flex flex-col">
<label htmlFor="name" className="font-medium mb-2">Title</label>
<Input type="text" name="name" onChange={write} value={dashboard.name} />
</div>
<div className="form-field flex flex-col">
<label htmlFor="name" className="font-medium mb-2">Visibility and Editing</label>
<div className="flex items-center py-2">
<label className="inline-flex items-center mr-6">
<input
type="radio"
className="form-radio h-5 w-5"
name="isPublic"
value="team"
checked={dashboard.isPublic}
onChange={writeRadio}
/>
<span className={cn("ml-2", { 'color-teal' : dashboard.isPublic})}>Team</span>
</label>
<label className="inline-flex items-center">
<input
type="radio"
className="form-radio h-5 w-5"
name="isPublic"
value="personal"
checked={!dashboard.isPublic}
onChange={writeRadio}
/>
<span className={cn("ml-2", { 'color-teal' : !dashboard.isPublic})}>Personal</span>
</label>
</div>
</div>
</div>
));
}
export default DashboardForm;

View file

@ -0,0 +1 @@
export { default } from './DashboardForm';

View file

@ -103,7 +103,7 @@ function DashboardMetricSelection(props) {
</div>
</div>
<div className="col-span-9">
<div className="grid grid-cols-2 gap-4 -mx-4 px-4">
<div className="grid grid-cols-2 gap-4 -mx-4 px-4 lg:grid-cols-2 sm:grid-cols-1">
{activeCategory.widgets.map((widget: any) => (
<div
key={widget.widgetId}
@ -116,12 +116,6 @@ function DashboardMetricSelection(props) {
</div>
</div>
</div>
<div className="flex absolute bottom-0 left-0 right-0 bg-white border-t p-3">
<Button primary className="">
Add Selected to Dashboard
</Button>
</div>
</div>
));
}

View file

@ -1,25 +1,31 @@
import React from 'react';
import WidgetWrapper from '../../WidgetWrapper';
import { useDashboardStore } from '../../store/store';
import { observer, useObserver } from 'mobx-react-lite';
import cn from 'classnames';
import { Button } from 'UI';
import { useObserver } from 'mobx-react-lite';
import DashboardMetricSelection from '../DashboardMetricSelection';
import DashboardForm from '../DashboardForm';
import { Button } from 'UI';
function DashboardModal(props) {
const store: any = useDashboardStore();
const dashbaord = useObserver(() => store.newDashboard);
return useObserver(() => (
<div className="fixed border-r shadow p-4 h-screen" style={{ backgroundColor: '#FAFAFA', zIndex: '9999', width: '80%'}}>
<div className="mb-6">
<h1 className="text-2xl">Add Metric to Dashboard</h1>
<h1 className="text-2xl">Create Dashboard</h1>
</div>
<DashboardForm />
<p>Create new dashboard by choosing from the range of predefined metrics that you care about. You can always add your custom metrics later.</p>
<DashboardMetricSelection />
<div className="flex absolute bottom-0 left-0 right-0 bg-white border-t p-3">
<Button primary className="" disabled={!dashbaord.isValid} onClick={() => store.save(dashbaord)}>
Add Selected to Dashboard
</Button>
</div>
</div>
));
}
export default observer(DashboardModal);
export default DashboardModal;

View file

@ -13,8 +13,7 @@ function DashboardView(props) {
const dashboard = store.selectedDashboard
const list = dashboard?.widgets;
useEffect(() => {
// handleModal(<ModalContent />)
props.showModal(DashboardModal)
// props.showModal(DashboardModal)
}, [])
return (
<div>

View file

@ -8,6 +8,13 @@ function MetricsList(props: Props) {
const store: any = useDashboardStore();
const widgets = store.widgets;
const lenth = widgets.length;
const currentPage = store.metricsPage;
const totalPages = widgets.length;
const pageSize = store.metricsPageSize;
const start = (currentPage - 1) * pageSize;
const end = currentPage * pageSize;
const list = widgets.slice(start, end);
return useObserver(() => (
<NoContent show={lenth === 0} icon="exclamation-circle">
@ -21,7 +28,7 @@ function MetricsList(props: Props) {
<div>Last Modified</div>
</div>
{widgets.map((metric: any) => (
{list.map((metric: any) => (
<div className="grid grid-cols-7 p-3 border-t select-none">
<div className="col-span-2">
<Link to="/dashboard/metrics/create" className="link">

View file

@ -5,7 +5,7 @@ import Widget from "./widget"
export default class Dashboard {
dashboardId: any = undefined
name: string = "New Dashboard"
isPriavte: boolean = false
isPublic: boolean = false
widgets: Widget[] = []
isValid: boolean = false
isPinned: boolean = false
@ -14,7 +14,7 @@ export default class Dashboard {
constructor() {
makeAutoObservable(this, {
name: observable,
isPriavte: observable,
isPublic: observable,
widgets: observable,
isValid: observable,
@ -31,14 +31,24 @@ export default class Dashboard {
validate: action,
sortWidgets: action,
swapWidgetPosition: action,
update: action,
})
this.validate();
}
update(data: any) {
runInAction(() => {
Object.assign(this, data)
})
this.validate()
}
toJson() {
return {
dashboardId: this.dashboardId,
name: this.name,
isPrivate: this.isPriavte,
isPrivate: this.isPublic,
widgets: this.widgets.map(w => w.toJson())
}
}
@ -47,14 +57,15 @@ export default class Dashboard {
runInAction(() => {
this.dashboardId = json.dashboardId
this.name = json.name
this.isPriavte = json.isPrivate
this.isPublic = json.isPrivate
this.widgets = json.widgets.map(w => new Widget().fromJson(w))
})
return this
}
validate() {
this.isValid = this.name.length > 0
console.log('called...')
return this.isValid = this.name.length > 0
}
addWidget(widget: Widget) {

View file

@ -6,10 +6,14 @@ export default class DashboardStore {
dashboards: Dashboard[] = []
widgetTemplates: any[] = []
selectedDashboard: Dashboard | null = new Dashboard()
newDashboard: Dashboard = new Dashboard()
isLoading: boolean = false
siteId: any = null
currentWidget: Widget = new Widget()
widgetCategories: any[] = []
widgets: Widget[] = []
metricsPage: number = 1
metricsPageSize: number = 10
private client = new APIClient()
@ -50,6 +54,14 @@ export default class DashboardStore {
// this.selectedDashboard?.swapWidgetPosition(2, 0)
// }, 3000)
for (let i = 0; i < 20; i++) {
const widget: any= {};
widget.widgetId = `${i}`
widget.name = `Widget ${i}`;
widget.metricType = ['timeseries', 'table'][Math.floor(Math.random() * 2)];
this.widgets.push(widget)
}
for (let i = 0; i < 4; i++) {
const cat: any = {
name: `Category ${i + 1}`,
@ -57,9 +69,8 @@ export default class DashboardStore {
description: `Category ${i + 1} description`,
widgets: []
}
// const randomBumberBetween = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min
const randomNumber = Math.floor(Math.random() * (5 - 2 + 1)) + 2
const randomNumber = Math.floor(Math.random() * (5 - 2 + 1)) + 2
for (let j = 0; j < randomNumber; j++) {
const widget: any= {};
widget.widgetId = `${i}-${j}`