Skip to content

Commit

Permalink
#1231 - moved code from UI, service, and reducer to model objects. us…
Browse files Browse the repository at this point in the history
…e voiding to for card mapping and section instead of remove. use card mapping to keep display order. removed some stories.
  • Loading branch information
petmongrels committed Jun 4, 2024
1 parent bbd85cf commit ca1455e
Show file tree
Hide file tree
Showing 15 changed files with 228 additions and 281 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"material-table": "1.43.0",
"moment": "^2.22.2",
"openchs-idi": "git+https://github.com/avniproject/openchs-idi#b6c57e051b91ed4bc2634f4f087dba51cc3a01c8",
"openchs-models": "1.31.77",
"openchs-models": "1.31.79",
"popper.js": "^1.14.3",
"prismjs": "^1.17.1",
"prop-types": "^15.7.2",
Expand Down
56 changes: 56 additions & 0 deletions src/common/model/reports/WebDashboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import _ from "lodash";
import WebDashboardSection from "./WebDashboardSection";

class WebDashboard {
static createNew() {
return { name: "", description: "", sections: [], filters: [] };
}

static removeSection(dashboard, section) {
const dashboardSection = _.find(dashboard.sections, x => x.uuid === section.uuid);
dashboardSection.voided = true;
dashboard.sections = [...dashboard.sections];
return { ...dashboard };
}

static updateSection(dashboard, section) {
const index = _.findIndex(dashboard.sections, x => x.uuid === section.uuid);
dashboard.sections[index] = section;
return { ...dashboard };
}

static reOrderSections(dashboard, sourceIndex, destIndex) {
const result = [...dashboard.sections];
const [removed] = result.splice(sourceIndex, 1);
result.splice(destIndex, 0, removed);
dashboard.sections = result;
return { ...dashboard };
}

static addNewSection(dashboard) {
dashboard.sections.push(WebDashboardSection.newSection());
dashboard.sections = _.sortBy(dashboard.sections, "displayOrder");
return { ...dashboard };
}

static toResource(dashboard) {
const resource = {
uuid: dashboard.uuid,
id: dashboard.id,
name: dashboard.name,
description: dashboard.description
};
resource.sections = WebDashboardSection.toResources(dashboard.sections);
resource.filters = dashboard.filters.map(x => {
return {
name: x.name,
voided: x.voided,
uuid: x.uuid,
filterConfig: x.filterConfig.toServerRequest()
};
});
return resource;
}
}

export default WebDashboard;
82 changes: 82 additions & 0 deletions src/common/model/reports/WebDashboardSection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { ModelGeneral as General } from "openchs-models";
import _ from "lodash";
import WebDashboardSectionCardMapping from "./WebDashboardSectionCardMapping";

class WebDashboardSection {
dashboardSectionCardMappings;

static getReportCards(section) {
return section.dashboardSectionCardMappings.filter(x => !x.voided).map(x => x.card);
}

static newSection() {
return {
name: "",
description: "",
viewType: "",
displayOrder: 100,
dashboardSectionCardMappings: [],
uuid: General.randomUUID(),
voided: false
};
}

static removeCard(section, card) {
const mapping = _.find(section.dashboardSectionCardMappings, x => x.card.uuid === card.uuid);
mapping.voided = true;
section.dashboardSectionCardMappings = [...section.dashboardSectionCardMappings];
return { ...section };
}

static reorderCards(section, startIndex, endIndex) {
const result = [...section.dashboardSectionCardMappings];
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
section.dashboardSectionCardMappings = result;
return { ...section };
}

static addCards(section, cards) {
//get max display order
let nextDisplayOrder =
_.reduce(
section.dashboardSectionCardMappings,
(max, dashboardSectionCardMapping) => {
return dashboardSectionCardMapping.displayOrder > max ? dashboardSectionCardMapping.displayOrder : max;
},
0
) + 1;

cards.forEach(card => {
section.dashboardSectionCardMappings.push({
card: card,
displayOrder: nextDisplayOrder
});
nextDisplayOrder++;
});

section.dashboardSectionCardMappings = [...section.dashboardSectionCardMappings];
return { ...section };
}

static getCardsNotAdded(section, allCards) {
const cardsAdded = WebDashboardSection.getReportCards(section);
return _.differenceBy(allCards, cardsAdded, "uuid");
}

static toResources(sections) {
return sections.map(section => {
return {
name: section.name,
description: section.description,
viewType: section.viewType,
displayOrder: section.displayOrder,
uuid: section.uuid,
voided: section.voided,
dashboardSectionCardMappings: WebDashboardSectionCardMapping.toResources(section.dashboardSectionCardMappings)
};
});
}
}

export default WebDashboardSection;
14 changes: 14 additions & 0 deletions src/common/model/reports/WebDashboardSectionCardMapping.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class WebDashboardSectionCardMapping {
static toResources(dashboardSectionCardMappings) {
return dashboardSectionCardMappings.map(dashboardSectionCardMapping => {
return {
reportCardUUID: dashboardSectionCardMapping.card.uuid,
displayOrder: dashboardSectionCardMapping.displayOrder,
uuid: dashboardSectionCardMapping.uuid,
voided: dashboardSectionCardMapping.voided
};
});
}
}

export default WebDashboardSectionCardMapping;
14 changes: 4 additions & 10 deletions src/common/service/DashboardService.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import EntityService from "./EntityService";
import _ from "lodash";
import WebReportCard from "../model/WebReportCard";
import WebStandardReportCardType from "../model/WebStandardReportCardType";
import WebDashboard from "../model/reports/WebDashboard";
import WebDashboardSection from "../model/reports/WebDashboardSection";

const dashboardEndpoint = "/web/dashboard";

Expand All @@ -30,7 +32,7 @@ class DashboardService {
message: "Section view type cannot be blank. Please select a view type"
});
}
if (!!find(sections, ({ cards }) => isEmpty(cards))) {
if (!!find(sections, section => isEmpty(WebDashboardSection.getReportCards(section)))) {
errors.push({ key: "EMPTY_SECTIONS", message: "Please add cards to the section." });
}
return errors;
Expand All @@ -39,15 +41,7 @@ class DashboardService {
static save(dashboard, edit, id) {
const url = edit ? `${dashboardEndpoint}/${id}` : "/web/dashboard";
const methodName = edit ? "put" : "post";
const payload = { ...dashboard };
payload.filters = dashboard.filters.map(x => {
return {
name: x.name,
voided: x.voided,
uuid: x.uuid,
filterConfig: x.filterConfig.toServerRequest()
};
});
const payload = WebDashboard.toResource(dashboard);
return http[methodName](url, payload).then(res => {
if (res.status === 200) {
return res.data;
Expand Down
22 changes: 5 additions & 17 deletions src/formDesigner/components/Dashboard/CreateEditDashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,10 @@ import ShowDashboardFilters from "./ShowDashboardFilters";
import { CreateEditFilterDialog } from "./CreateEditFilterDialog";
import DashboardService from "../../../common/service/DashboardService";
import OperationalModules from "../../../common/model/OperationalModules";
import WebDashboard from "../../../common/model/reports/WebDashboard";

const initialState = { name: "", description: "", sections: [], filters: [] };
const CreateEditDashboard = ({
edit,
history,
operationalModules,
getOperationalModules,
...props
}) => {
const initialState = WebDashboard.createNew();
const CreateEditDashboard = ({ edit, history, operationalModules, getOperationalModules, ...props }) => {
const [dashboard, dispatch] = React.useReducer(DashboardReducer, initialState);
const [error, setError] = React.useState([]);
const [id, setId] = React.useState();
Expand Down Expand Up @@ -93,9 +88,7 @@ const CreateEditDashboard = ({
setError([
{
key: "SERVER_ERROR",
message: `${get(error, "response.data") ||
get(error, "message") ||
"error while saving dashboard"}`
message: `${get(error, "response.data") || get(error, "message") || "error while saving dashboard"}`
}
])
);
Expand Down Expand Up @@ -148,12 +141,7 @@ const CreateEditDashboard = ({
{getErrorByKey(error, "EMPTY_SECTIONS")}
</Grid>
<Grid item>
<CreateEditDashboardSections
sections={dashboard.sections}
dispatch={dispatch}
history={history}
error={error}
/>
<CreateEditDashboardSections sections={dashboard.sections} dispatch={dispatch} history={history} error={error} />
</Grid>
{getErrorByKey(error, "EMPTY_CARDS")}
<br />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
import React, { Component } from "react";
import {
IconButton,
List,
ListItem,
ListItemSecondaryAction,
ListItemText
} from "@material-ui/core";
import { IconButton, List, ListItem, ListItemSecondaryAction, ListItemText } from "@material-ui/core";
import DeleteIcon from "@material-ui/icons/Delete";
import VisibilityIcon from "@material-ui/icons/Visibility";
import { isEmpty } from "lodash";
import { DragNDropComponent } from "../../common/DragNDropComponent";

const reorder = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};
import PropTypes from "prop-types";
import WebDashboardSection from "../../../common/model/reports/WebDashboardSection";

class CreateEditDashboardSectionCards extends Component {
constructor(props) {
super(props);
this.onDragEnd = this.onDragEnd.bind(this);
}

static propTypes = {
section: PropTypes.object.isRequired,
sectionUpdated: PropTypes.func.isRequired
};

onDragEnd(result) {
if (!result.destination) {
return;
}
const cards = reorder(this.props.cards, result.source.index, result.destination.index);
this.props.changeDisplayOrder(cards);
const section = WebDashboardSection.reorderCards(this.props.section, result.source.index, result.destination.index);
this.props.sectionUpdated(section);
}

renderCard(card) {
Expand All @@ -38,9 +32,7 @@ class CreateEditDashboardSectionCards extends Component {
<ListItem>
<ListItemText primary={card.name} secondary={card.description} />
<ListItemSecondaryAction>
<IconButton
onClick={() => this.props.history.push(`/appDesigner/reportCard/${card.id}/show`)}
>
<IconButton onClick={() => this.props.history.push(`/appDesigner/reportCard/${card.id}/show`)}>
<VisibilityIcon />
</IconButton>
<IconButton onClick={() => this.props.deleteCard(card)}>
Expand All @@ -53,11 +45,11 @@ class CreateEditDashboardSectionCards extends Component {
}

render() {
const cards = this.props.cards;
const cards = WebDashboardSection.getReportCards(this.props.section);
return (
!isEmpty(cards) && (
<DragNDropComponent
dataList={this.props.cards}
dataList={cards}
onDragEnd={this.onDragEnd}
renderOtherSummary={card => this.renderCard(card)}
summaryDirection={"column"}
Expand Down
Loading

0 comments on commit ca1455e

Please sign in to comment.