Skip to content

Commit

Permalink
Merge pull request #1156 from akvo/bug/1152-cleanup-error-on-fe-pages
Browse files Browse the repository at this point in the history
Bug/1152 cleanup error on fe pages
  • Loading branch information
ifirmawan authored Feb 12, 2024
2 parents 3f526ca + b47212f commit e03ed44
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 38 deletions.
2 changes: 1 addition & 1 deletion frontend/src/components/EditableCell.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ EditableCell.propTypes = {
record: PropTypes.shape({
id: PropTypes.number.isRequired,
type: PropTypes.string.isRequired,
value: PropTypes.any.isRequired,
value: PropTypes.oneOfType([PropTypes.any, PropTypes.oneOf([null])]),
option: PropTypes.array,
newValue: PropTypes.any,
}),
Expand Down
46 changes: 29 additions & 17 deletions frontend/src/pages/approvals/ApprovalDetail.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
LoadingOutlined,
HistoryOutlined,
} from "@ant-design/icons";
import { api, store, config } from "../../lib";
import { api, store, config, uiText } from "../../lib";
import { EditableCell } from "../../components";
import { isEqual, flatten } from "lodash";
import { useNotification } from "../../util/hooks";
Expand Down Expand Up @@ -112,9 +112,12 @@ const ApprovalDetail = ({
new Array(record.form?.approval_instructions?.action.length).fill(false)
);
const [resetButton, setresetButton] = useState({});

const { user: authUser } = store.useState((s) => s);
const { user: authUser, language } = store.useState((s) => s);
const { approvalsLiteral } = config;
const { active: activeLang } = language;
const text = useMemo(() => {
return uiText[activeLang];
}, [activeLang]);

//for checking the null value
const approveButtonEnable = useMemo(() => {
Expand Down Expand Up @@ -158,6 +161,12 @@ const ApprovalDetail = ({
resetObj[d.question] = false;
});
setresetButton({ ...resetButton, ...resetObj });
const indexToUpdate = rawValues.findIndex((row) => row.id === data.id);
if (indexToUpdate !== -1) {
const updatedRawValues = [...rawValues];
updatedRawValues[indexToUpdate].edited = false;
setRawValues(updatedRawValues);
}
})
.catch((e) => {
console.error(e);
Expand All @@ -166,6 +175,7 @@ const ApprovalDetail = ({
setSaving(null);
});
};

const handleApprove = (id, status) => {
let payload = {
batch: id,
Expand Down Expand Up @@ -436,6 +446,22 @@ const ApprovalDetail = ({
</Space>
) : (
<div className={`pending-data-outer`}>
<div className="save-edit-button">
<Button
onClick={() => handleSave(record)}
type="primary"
shape="round"
loading={record.id === saving}
disabled={
!approve ||
selectedTab !== "raw-data" ||
record.id === dataLoading ||
isEdited(record.id) === false
}
>
{text.saveEditButton}
</Button>
</div>
{record.data?.map((r, rI) => (
<div className="pending-data-wrapper" key={rI}>
<h3>{r.name}</h3>
Expand Down Expand Up @@ -492,20 +518,6 @@ const ApprovalDetail = ({
/>
</div>
))}
<Button
onClick={() => handleSave(record)}
type="primary"
shape="round"
loading={record.id === saving}
disabled={
!approve ||
selectedTab !== "raw-data" ||
record.id === dataLoading ||
isEdited(record.id) === false
}
>
Save Edits
</Button>
</div>
)}
</div>
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/pages/approvals/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,13 @@
.pending-data-outer {
height: 500px;
overflow-y: scroll;
margin-top: 2rem;

.save-edit-button {
position: absolute;
top: 5px;
right: 16px;
}
.pending-data-wrapper {
border: solid #e9e9e9 1px;
margin-bottom: 20px;
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/pages/control-center/ControlCenter.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo } from "react";
import React, { Fragment, useMemo } from "react";
import "./style.scss";
import { Row, Col, Button } from "antd";
import { store, config, uiText } from "../../lib";
Expand Down Expand Up @@ -113,7 +113,7 @@ const ControlCenter = () => {
<Row gutter={[16, 32]}>
{selectedPanels.map((panel, index) => {
if (panel?.render) {
return panel.render;
return <Fragment key={index}>{panel.render}</Fragment>;
}
const cardOnly = selectedPanels.filter((x) => !x?.render);
const isFullWidth =
Expand All @@ -124,7 +124,7 @@ const ControlCenter = () => {
<Col
className="card-wrapper"
span={isFullWidth ? 24 : 12}
key={index}
key={panel.key}
>
<div hoverable>
<div className="row">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,11 @@ const PanelApprovals = () => {
api
.get(url)
.then((res) => {
setApprovalsPending(res.data.batch);
const newData = res.data.batch.map((item, index) => ({
...item,
key: index.toString(),
}));
setApprovalsPending(newData);
setLoading(false);
})
.catch((e) => {
Expand Down
40 changes: 32 additions & 8 deletions frontend/src/pages/manage-data/DataDetail.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Table, Button, Space, Spin, Alert } from "antd";
import { LoadingOutlined, HistoryOutlined } from "@ant-design/icons";
import { EditableCell } from "../../components";
import { api, config, store } from "../../lib";
import { api, config, store, uiText } from "../../lib";
import { useNotification } from "../../util/hooks";
import { flatten, isEqual } from "lodash";
import { HistoryTable } from "../../components";
Expand All @@ -14,6 +14,8 @@ const DataDetail = ({
updateRecord,
setDeleteData,
isPublic = false,
editedRecord,
setEditedRecord,
}) => {
const [dataset, setDataset] = useState([]);
const [loading, setLoading] = useState(false);
Expand All @@ -22,31 +24,44 @@ const DataDetail = ({
const pendingData = record?.pending_data?.created_by || false;
const { user: authUser, forms } = store.useState((state) => state);
const { notify } = useNotification();
const { language } = store.useState((s) => s);
const { active: activeLang } = language;
const text = useMemo(() => {
return uiText[activeLang];
}, [activeLang]);

const updateCell = (key, parentId, value) => {
setresetButton({ ...resetButton, [key]: true });
let prev = JSON.parse(JSON.stringify(dataset));
let hasEdits = false;
prev = prev.map((qg) =>
qg.id === parentId
? {
...qg,
question: qg.question.map((qi) => {
if (qi.id === key) {
if (
isEqual(qi.value, value) &&
(qi.newValue || qi.newValue === 0)
) {
delete qi.newValue;
if (isEqual(qi.value, value)) {
if (qi.newValue) {
delete qi.newValue;
}
} else {
qi.newValue = value;
}
const edited = !isEqual(qi.value, value);
if (edited && !hasEdits) {
hasEdits = true;
}
return qi;
}
return qi;
}),
}
: qg
);
const hasNewValue = prev
.find((p) => p.id === parentId)
?.question?.some((q) => typeof q.newValue !== "undefined");
setEditedRecord({ ...editedRecord, [record.id]: hasNewValue });
setDataset(prev);
};

Expand All @@ -65,6 +80,14 @@ const DataDetail = ({
}
: qg
);
/**
* Check whether it still has newValue or not
* in all groups of questions
*/
const hasNewValue = prev
?.flatMap((p) => p?.question)
?.find((q) => q?.newValue);
setEditedRecord({ ...editedRecord, [record.id]: hasNewValue });
setDataset(prev);
};

Expand Down Expand Up @@ -112,6 +135,7 @@ const DataDetail = ({
resetObj[d.question] = false;
});
setresetButton({ ...resetButton, ...resetObj });
setEditedRecord({ ...editedRecord, [record.id]: false });
})
.catch((e) => {
console.error(e);
Expand Down Expand Up @@ -262,15 +286,15 @@ const DataDetail = ({
loading={saving}
shape="round"
>
Save Edits
{text.saveEditButton}
</Button>
{deleteData && (
<Button
type="danger"
onClick={() => setDeleteData(record)}
shape="round"
>
Delete
{text.deleteText}
</Button>
)}
</Space>
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/pages/manage-data/ManageData.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const ManageData = () => {
const [updateRecord, setUpdateRecord] = useState(false);
const [deleteData, setDeleteData] = useState(null);
const [deleting, setDeleting] = useState(false);
const [editedRecord, setEditedRecord] = useState({});
const [editable, setEditable] = useState(false);
const { language, advancedFilters } = store.useState((s) => s);
const { active: activeLang } = language;
Expand Down Expand Up @@ -213,6 +214,9 @@ const ManageData = () => {
showTotal: (total, range) =>
`Results: ${range[0]} - ${range[1]} of ${total} data`,
}}
rowClassName={(record) =>
editedRecord[record.id] ? "row-edited" : "row-normal sticky"
}
rowKey="id"
expandable={{
expandedRowRender: (record) => (
Expand All @@ -222,6 +226,8 @@ const ManageData = () => {
updateRecord={updateRecord}
updater={setUpdateRecord}
setDeleteData={setDeleteData}
setEditedRecord={setEditedRecord}
editedRecord={editedRecord}
isPublic={editable}
/>
),
Expand Down
9 changes: 9 additions & 0 deletions frontend/src/pages/manage-data/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,14 @@
top: 0px;
right: 22px;
}
.ant-table {
tr.row-edited td {
background-color: #fefebe;
}
tr.ant-table-row.row-edited:hover > td,
tr.row-edited > td.ant-table-cell-row-hover {
background: #fefebe;
}
}
}
}
33 changes: 28 additions & 5 deletions frontend/src/pages/submissions/BatchDetail.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ import { api, store, uiText } from "../../lib";
import { isEqual, flatten } from "lodash";
import { useNotification } from "../../util/hooks";

const BatchDetail = ({ expanded, setReload, deleting, handleDelete }) => {
const BatchDetail = ({
expanded,
setReload,
deleting,
handleDelete,
editedRecord,
setEditedRecord,
}) => {
const [dataLoading, setDataLoading] = useState(true);
const [saving, setSaving] = useState(null);
const [rawValue, setRawValue] = useState(null);
Expand Down Expand Up @@ -79,23 +86,23 @@ const BatchDetail = ({ expanded, setReload, deleting, handleDelete }) => {
question: rq.id,
value: value,
});
delete rq.newValue;
}
});
});

api
.put(
`form-pending-data/${expanded.form}?pending_data_id=${data.id}`,
formData
)
.then(() => {
setReload(data.id);

const resetObj = {};
formData.map((data) => {
resetObj[data.question] = false;
});
setresetButton({ ...resetButton, ...resetObj });
setEditedRecord({ ...editedRecord, [expanded.id]: false });
notify({
type: "success",
message: text.successDataUpdated,
Expand All @@ -116,8 +123,10 @@ const BatchDetail = ({ expanded, setReload, deleting, handleDelete }) => {
...rd,
question: rd.question.map((rq) => {
if (rq.id === key && expanded.id === parentId) {
if (isEqual(rq.value, value) && (rq.newValue || rq.newValue === 0)) {
delete rq.newValue;
if (isEqual(rq.value, value)) {
if (rq.newValue) {
delete rq.newValue;
}
} else {
rq.newValue = value;
}
Expand All @@ -137,6 +146,12 @@ const BatchDetail = ({ expanded, setReload, deleting, handleDelete }) => {
return rq;
}),
}));
const hasNewValue = data.some((d) => {
return d.question?.some((q) => {
return typeof q.newValue !== "undefined";
});
});
setEditedRecord({ ...editedRecord, [expanded.id]: hasNewValue });
setRawValue({
...rawValue,
data,
Expand Down Expand Up @@ -164,6 +179,14 @@ const BatchDetail = ({ expanded, setReload, deleting, handleDelete }) => {
return rq;
}),
}));
/**
* Check whether it still has newValue or not
* in all groups of questions
*/
const hasNewValue = data
?.flatMap((d) => d?.question)
?.find((q) => q?.newValue);
setEditedRecord({ ...editedRecord, [expanded.id]: hasNewValue });
setRawValue({
...prev,
data,
Expand Down
Loading

0 comments on commit e03ed44

Please sign in to comment.