Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OBPIH-4277 Add option to make separate dashboard pages #3374

Merged
merged 2 commits into from Jul 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
394 changes: 200 additions & 194 deletions grails-app/conf/Config.groovy

Large diffs are not rendered by default.

12 changes: 11 additions & 1 deletion grails-app/conf/UrlMappings.groovy
Expand Up @@ -432,7 +432,17 @@ class UrlMappings {

"/api/dashboard/config"(parseRequest: true) {
controller = { "dashboardApi" }
action = [GET: "config", POST: "updateConfig"]
action = [POST: "updateConfig"]
}

"/api/dashboard/$id/config"(parseRequest: true) {
controller = { "dashboardApi" }
action = [GET: "config"]
}

"/api/dashboard/$id/subdashboardKeys"(parseRequest: true) {
controller = { "dashboardApi" }
action = [GET: "getSubdashboardKeys"]
}

"/api/dashboard/breadcrumbsConfig"(parseRequest: true) {
Expand Down
Expand Up @@ -17,11 +17,17 @@ class DashboardApiController {

def config = {
User user = User.get(session.user.id)
def config = userService.getDashboardConfig(user)
def config = userService.getDashboardConfig(user, params.id)

render(config as JSON)
}

def getSubdashboardKeys = {
def mainDashboardId = grailsApplication.config.openboxes.dashboardConfig.mainDashboardId
def config = grailsApplication.config.openboxes.dashboardConfig.dashboards[params.id ?: mainDashboardId]
render(config.keySet() as JSON)
}

def updateConfig = {
User user = User.get(session.user.id)
def config = userService.updateDashboardConfig(user, request.JSON)
Expand Down
32 changes: 17 additions & 15 deletions grails-app/services/org/pih/warehouse/core/UserService.groovy
Expand Up @@ -402,27 +402,29 @@ class UserService {
return false
}

def getDashboardConfig(User user) {
def config = grailsApplication.config.openboxes.dashboardConfig
def getDashboardConfig(User user, String id) {
def fullConfig = grailsApplication.config.openboxes.dashboardConfig
def mainDashboardId = grailsApplication.config.openboxes.dashboardConfig.mainDashboardId
def resultConfig = [
dashboard: fullConfig.dashboards[id ?: mainDashboardId],
dashboardWidgets: fullConfig.dashboardWidgets
]
def userConfig = user.deserializeDashboardConfig()
Boolean configChanged = false

if (userConfig != null) {
int userConfigSize = userConfig.size()
int configSize = config.dashboards.size()
// If the size is different, that mean that the config has changed
if (userConfigSize != configSize) {
return config
}
if (!configChanged) {
config = [
dashboards : userConfig,
dashboardWidgets : config.dashboardWidgets
]
if (id == mainDashboardId) {
int userConfigSize = userConfig.size()
int resultConfigSize = resultConfig.dashboard.size()
if (userConfigSize == resultConfigSize) {
resultConfig = [
dashboard : userConfig,
dashboardWidgets : resultConfig.dashboardWidgets
]
}
}
}

return config
return resultConfig
}

def updateDashboardConfig(User user, Object config) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -13,7 +13,7 @@
"test": "test"
},
"scripts": {
"watch": "webpack --watch --colors --progress --mode=development",
"watch": "webpack --watch --progress --mode=development",
"bundle": "webpack --no-color --mode=production",
"test": "jest",
"styleguide": "styleguidist server",
Expand Down
10 changes: 5 additions & 5 deletions src/js/actions/index.js
Expand Up @@ -310,7 +310,7 @@ export function reloadIndicator(indicatorConfig, params, locationId) {
function getData(dispatch, dashboardConfig, locationId, config = 'personal', userId = '') {
// new reference so that the original config is not modified

const dashboard = dashboardConfig.dashboards[config] || {};
const dashboard = dashboardConfig.dashboard[config] || {};
const widgets = _.map(dashboard.widgets, widget => ({
...dashboardConfig.dashboardWidgets[widget.widgetId],
order: widget.order,
Expand Down Expand Up @@ -377,9 +377,9 @@ export function reorderIndicators({ oldIndex, newIndex }, e, type) {
};
}

export function fetchConfigAndData(locationId, config = 'personal', userId, filterSelected) {
export function fetchConfigAndData(locationId, config = 'personal', userId, id, filterSelected) {
return (dispatch) => {
apiClient.get('/openboxes/api/dashboard/config').then((res) => {
apiClient.get(`/openboxes/api/dashboard/${id}/config`).then((res) => {
dispatch({
type: FETCH_CONFIG_AND_SET_ACTIVE,
payload: {
Expand All @@ -392,9 +392,9 @@ export function fetchConfigAndData(locationId, config = 'personal', userId, filt
};
}

export function fetchConfig() {
export function fetchConfig(id) {
return (dispatch) => {
apiClient.get('/openboxes/api/dashboard/config').then((res) => {
apiClient.get(`/openboxes/api/dashboard/${id}/config`).then((res) => {
dispatch({
type: FETCH_CONFIG,
payload: {
Expand Down
66 changes: 46 additions & 20 deletions src/js/components/dashboard/Dashboard.jsx
Expand Up @@ -138,6 +138,8 @@ const ConfigurationsList = ({
);
};

const MAIN_DASHBOARD_CONFIG = 'mainDashboard';


class Dashboard extends Component {
constructor(props) {
Expand All @@ -151,45 +153,67 @@ class Dashboard extends Component {
configModified: false,
allLocations: [],
pageFilters: [],
subdashboardKeys: [],
};
this.config = 'personal';
this.fetchLocations();
}

componentDidMount() {
this.config = this.getConfigIdFromParams() || sessionStorage.getItem('dashboardKey') || this.config;
if (this.props.currentLocation !== '') {
this.fetchData(this.config);
this.getSubdashboardKeys().then(() => this.fetchData(this.determineActiveConfig()));
}
this.loadPageFilters(this.props.activeConfig);
}

componentDidUpdate(prevProps) {
this.config = this.getConfigIdFromParams() || sessionStorage.getItem('dashboardKey') || this.config;
const prevLocation = prevProps.currentLocation;
const newLocation = this.props.currentLocation;
if (prevLocation !== newLocation) {
this.fetchData(this.config);
this.getSubdashboardKeys().then(() => this.fetchData(this.determineActiveConfig()));
}
if (prevProps.dashboardConfig.dashboards !== this.props.dashboardConfig.dashboards) {
if (prevProps.dashboardConfig.dashboard !== this.props.dashboardConfig.dashboard) {
this.loadPageFilters(this.props.activeConfig);
}
}

getConfigIdFromParams() {
if (this.props.match.params.configId) {
return this.props.match.params.configId === 'index' ? this.props.activeConfig : this.props.match.params.configId;
getDashboardIdFromParams() {
const dashboardId = this.props.match.params.configId;
if (dashboardId && dashboardId !== 'index') {
return dashboardId;
}
return MAIN_DASHBOARD_CONFIG;
}

return '';
getSubdashboardKeys() {
const dashboardId = this.getDashboardIdFromParams();
const url = `/openboxes/api/dashboard/${dashboardId}/subdashboardKeys`;
return apiClient.get(url)
.then((res) => {
const subdashboardKeys = res.data;
if (subdashboardKeys) {
this.setState({ subdashboardKeys });
}
});
}

determineActiveConfig() {
if (this.props.match.params.configId && this.props.match.params.configId !== 'index') {
return this.props.match.params.configId;
}
const configFromSessionStorage = sessionStorage.getItem('dashboardKey');
// eslint-disable-next-line max-len
if (configFromSessionStorage && this.state.subdashboardKeys.includes(configFromSessionStorage)) {
return configFromSessionStorage;
}
return 'personal';
}

dataFetched = false;

loadPageFilters(config = '') {
let pageFilters = [];
if (this.props.dashboardConfig.dashboards) {
const allPages = Object.entries(this.props.dashboardConfig.dashboards)
if (this.props.dashboardConfig.dashboard) {
const allPages = Object.entries(this.props.dashboardConfig.dashboard)
.map(([key, value]) => [key, value]);
allPages.forEach((page) => {
const filters = Object.entries(page[1].filters)
Expand Down Expand Up @@ -223,7 +247,7 @@ class Dashboard extends Component {
fetchData = (config = 'personal') => {
sessionStorage.setItem('dashboardKey', config);
this.props.resetIndicators();
if (this.props.dashboardConfig && this.props.dashboardConfig.dashboards) {
if (this.props.dashboardConfig && this.props.dashboardConfig.dashboard) {
this.props.fetchIndicators(
this.props.dashboardConfig,
config,
Expand All @@ -236,6 +260,8 @@ class Dashboard extends Component {
this.props.currentLocation,
config,
this.props.currentUser,
// Determine which dashboard (id) to fetch
this.getDashboardIdFromParams(),
);
}
};
Expand All @@ -253,21 +279,21 @@ class Dashboard extends Component {

const url = '/openboxes/api/dashboard/config';
const payload = {
...this.props.dashboardConfig.dashboards,
...this.props.dashboardConfig.dashboard,
[this.props.activeConfig]: {
...this.props.dashboardConfig.dashboards[this.props.activeConfig],
...this.props.dashboardConfig.dashboard[this.props.activeConfig],
widgets,
},
};

apiClient.post(url, payload).then(() => {
this.props.fetchConfig();
this.props.fetchConfig(this.getDashboardIdFromParams());
this.setState({ configModified: false });
});
};

loadIndicator = (widgetId, params) => {
const dashboardConf = this.props.dashboardConfig.dashboards[this.props.activeConfig];
const dashboardConf = this.props.dashboardConfig.dashboard[this.props.activeConfig];
const widget = _.find(dashboardConf.widgets, w => w.widgetId === widgetId);
const widgetConf = {
...this.props.dashboardConfig.dashboardWidgets[widgetId],
Expand Down Expand Up @@ -366,7 +392,7 @@ class Dashboard extends Component {
return (
<div className="dashboard-container">
<ConfigurationsList
configs={this.props.dashboardConfig.dashboards || {}}
configs={this.props.dashboardConfig.dashboard || {}}
loadConfigData={this.fetchData}
activeConfig={this.props.activeConfig}
showNav={this.state.showNav}
Expand All @@ -384,7 +410,7 @@ class Dashboard extends Component {

<div className="filter-and-cards-container">
<Filter
configs={this.props.dashboardConfig.dashboards || {}}
configs={this.props.dashboardConfig.dashboard || {}}
activeConfig={this.props.activeConfig}
fetchData={this.fetchData}
pageFilters={this.state.pageFilters}
Expand Down Expand Up @@ -460,7 +486,7 @@ Dashboard.propTypes = {
id: PropTypes.number,
})).isRequired,
dashboardConfig: PropTypes.shape({
dashboards: PropTypes.shape({}),
dashboard: PropTypes.shape({}),
dashboardWidgets: PropTypes.shape({}),
}).isRequired,
activeConfig: PropTypes.string.isRequired,
Expand Down
2 changes: 1 addition & 1 deletion src/js/components/dashboard/UnarchiveIndicators.jsx
Expand Up @@ -195,7 +195,7 @@ UnarchiveIndicators.propTypes = {
graphData: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
numberData: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
dashboardConfig: PropTypes.shape({
dashboards: PropTypes.shape({}),
dashboard: PropTypes.shape({}),
dashboardWidgets: PropTypes.shape({}),
}).isRequired,
unarchiveHandler: PropTypes.func.isRequired,
Expand Down