Skip to content

Commit

Permalink
DRAFT: convert dashboard to functional
Browse files Browse the repository at this point in the history
committing very in progress work just to save
  • Loading branch information
mshriver committed Dec 3, 2024
1 parent 770c768 commit 9bfc2a2
Showing 1 changed file with 133 additions and 111 deletions.
244 changes: 133 additions & 111 deletions frontend/src/dashboard.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
/* eslint-disable no-unused-vars */
import React, { useContext, useEffect, useState } from 'react';
import PropTypes from 'prop-types';

import {
Expand Down Expand Up @@ -46,107 +47,70 @@ import {
ResultSummaryWidget
} from './widgets';
import { IbutsuContext } from './services/context.js';


export class Dashboard extends React.Component {
static contextType = IbutsuContext;
static propTypes = {
eventEmitter: PropTypes.object,
navigate: PropTypes.func,
params: PropTypes.object,
}

constructor(props) {
super(props);
this.state = {
widgets: [],
filteredDashboards: [],
dashboards: [],
selectedDashboard: null,
isDashboardSelectorOpen: false,
isNewDashboardOpen: false,
isWidgetWizardOpen: false,
isEditModalOpen: false,
editWidgetData: {},
dashboardInputValue: '',
filterValueDashboard: ''
};
props.eventEmitter.on('projectChange', (value) => {
this.getDashboards(value);
this.getDefaultDashboard(value);
});
}

sync_context = () => {
// Active dashboard
const { activeDashboard, setActiveDashboard } = this.context;
const { selectedDashboard } = this.state;
const paramDash = this.props.params?.dashboard_id;
if (!paramDash) {
// No dashboard in the URL, clear context
setActiveDashboard();
}
let updatedDash = undefined;
// API call to update context
if ( paramDash != null && activeDashboard?.id !== paramDash) {
HttpClient.get([Settings.serverUrl, 'dashboard', paramDash])
.then(response => HttpClient.handleResponse(response))
.then(data => {
const { setActiveDashboard } = this.context;
setActiveDashboard(data);
updatedDash = data;
this.setState({
selectedDashboard: data,
isDashboardSelectorOpen: false,
filterValueDashboard: '',
dashboardInputValue: data.title,
}); // callback within class component won't have updated context
// TODO don't pass value when converting to functional component
this.getWidgets(data);
})
.catch(error => console.log(error));
}

if (updatedDash && !selectedDashboard ) {
this.setState({
selectedDashboard: updatedDash,
dashboardInputValue: updatedDash.title
})
}
}

getDashboards = (handledOject = null) => {
// value is checked because of handler scope not seeing context state updates
import { useParams } from 'react-router-dom';


function Dashboard() {
const context = useContext(IbutsuContext);
const params = useParams();

const [dashboards, setDashboards] = useState([]);
const [filteredDBs, setFilteredDBs] = useState([]);
const [selectedDB, setSelectedDB] = useState();

const [widgets, setWidgets] = useState([]);

const [isDBSelectorOpen, setIsDBSelectorOpen] = useState(false);
const [isNewDBOpen, setIsNewDBOpen] = useState(false);
const [isNewWidgetOpen, setIsNewWidgetOpen] = useState(false);
const [isEditModalOpen, setIsEditModalOpen] = useState(false);


const [editWidgetData, setEditWidgetData] = useState({});
const [selectDBInputValue, setSelectDBInputValue] = useState('');
const [filterDBValue, setFilterDBValue] = useState('');

useEffect(() => {
// TODO: react-router loaders instead of making API calls on render
sync_context();
getDashboards();
getDefaultDashboard();
getWidgets();
}, [selectedDB]);

const getDashboards = () => {
// TODO: react-router loaders would be way better
const { primaryObject } = this.context;
const paramProject = this.props.params?.project_id;
const primaryObjectId = handledOject?.id ?? primaryObject?.id ?? paramProject;
const { primaryObject } = context;
const paramProject = params?.project_id;
const primaryObjectId = primaryObject?.id ?? paramProject;

if (!primaryObjectId) {
this.setState({dashboardInputValue: ''})
setSelectDBInputValue('')
return;
}
let params = {
let api_params = {
'project_id': primaryObjectId,
'pageSize': 10
};

if (this.state.filterValueDashboard) {
params['filter'] = ['title%' + this.state.filterValueDashboard];
if (filterDBValue) {
api_params['filter'] = ['title%' + filterDBValue];
}
HttpClient.get([Settings.serverUrl, 'dashboard'], params)
HttpClient.get([Settings.serverUrl, 'dashboard'], api_params)
.then(response => HttpClient.handleResponse(response))
.then(data => {
this.setState({dashboards: data['dashboards'], filteredDashboards: data['dashboards']});
setDashboards(data['dashboards']);
setFilteredDBs(data['dashboards']);
})
.catch(error => console.log(error));
}

getDefaultDashboard = (handledObject = null) => {
const { primaryObject, activeDashboard, setActiveDashboard } = this.context;
const paramProject = this.props.params?.project_id;

let targetObject = handledObject ?? primaryObject ?? paramProject;
const getDefaultDashboard = () => {
const { primaryObject, activeDashboard, setActiveDashboard } = context;
const paramProject = params?.project_id;

let targetObject = primaryObject ?? paramProject;

if (typeof(targetObject) === 'string') {
HttpClient.get([Settings.serverUrl, 'project', paramProject])
Expand All @@ -158,46 +122,38 @@ export class Dashboard extends React.Component {

}

// Maybe change this behavior for last-visted preference on dashboard page
if ( !activeDashboard && targetObject?.defaultDashboard ){
setActiveDashboard(targetObject.defaultDashboard);
this.setState({
'selectedDashboard': targetObject.defaultDashboard,
'dashboardInputValue': targetObject.defaultDashboard?.title
})
setSelectedDB(targetObject.defaultDashboard);
setSelectDBInputValue(targetObject.defaultDashboard?.title);
}
}
}

getWidgets = (dashboard) => {
const getWidgets = () => {
let params = {'type': 'widget'};
const { activeDashboard } = this.context;
// TODO don't pass value when converting to functional component
let target_dash = null;
if (dashboard === undefined) {
target_dash = activeDashboard;
} else {
target_dash = dashboard;
}
if (!target_dash) {
const { activeDashboard } = context;
if (!activeDashboard) {
return;
}
params['filter'] = 'dashboard_id=' + target_dash.id;
params['filter'] = 'dashboard_id=' + activeDashboard.id;
HttpClient.get([Settings.serverUrl, 'widget-config'], params)
.then(response => HttpClient.handleResponse(response))
.then(data => {
// set the widget project param
data.widgets.forEach(widget => {
widget.params['project'] = target_dash.project_id;
widget.params['project'] = activeDashboard.project_id;
});
this.setState({widgets: data.widgets});
setWidgets(data.widgets);
})
.catch(error => console.log(error));
}

onDashboardToggle = () => {
this.setState({isDashboardSelectorOpen: !this.state.isDashboardSelectorOpen});
const onDashboardToggle = () => {
setIsDBSelectorOpen(!isDBSelectorOpen);
};

onDashboardSelect = (_event, value) => {
const onDashboardSelect = (_event, value) => {
const { setActiveDashboard } = this.context;
setActiveDashboard(value);
this.setState({
Expand All @@ -214,6 +170,75 @@ export class Dashboard extends React.Component {
this.props.navigate('/project/' + this.props.params?.project_id + '/dashboard/' + value?.id)
};

}

Dashboard.propTypes = {
navigate: PropTypes.func,
params: PropTypes.object,
};

export default Dashboard;

export class OLDDashboard extends React.Component {
static contextType = IbutsuContext;
static propTypes = {
eventEmitter: PropTypes.object,
navigate: PropTypes.func,
params: PropTypes.object,
}


props.eventEmitter.on('projectChange', (value) => {
this.getDashboards(value);
this.getDefaultDashboard(value);
});
}

sync_context = () => {
// Active dashboard
const { activeDashboard, setActiveDashboard } = this.context;
const { selectedDashboard } = this.state;
const paramDash = this.props.params?.dashboard_id;
if (!paramDash) {
// No dashboard in the URL, clear context
setActiveDashboard();
}
let updatedDash = undefined;
// API call to update context
if ( paramDash != null && activeDashboard?.id !== paramDash) {
HttpClient.get([Settings.serverUrl, 'dashboard', paramDash])
.then(response => HttpClient.handleResponse(response))
.then(data => {
const { setActiveDashboard } = this.context;
setActiveDashboard(data);
updatedDash = data;
this.setState({
selectedDashboard: data,
isDashboardSelectorOpen: false,
filterValueDashboard: '',
dashboardInputValue: data.title,
}); // callback within class component won't have updated context
// TODO don't pass value when converting to functional component
this.getWidgets(data);
})
.catch(error => console.log(error));
}

if (updatedDash && !selectedDashboard ) {
this.setState({
selectedDashboard: updatedDash,
dashboardInputValue: updatedDash.title
})
}
}








onDashboardClear = () => {
const { setActiveDashboard } = this.context;
setActiveDashboard();
Expand Down Expand Up @@ -353,10 +378,7 @@ export class Dashboard extends React.Component {
}

componentDidMount() {
this.sync_context();
this.getDashboards();
this.getDefaultDashboard();
this.getWidgets();

}

componentDidUpdate(prevProps, prevState) {
Expand Down

0 comments on commit 9bfc2a2

Please sign in to comment.