From 41fa50557eaa5a40972b4a155a98f952262056f8 Mon Sep 17 00:00:00 2001 From: ifirmawan Date: Tue, 9 Aug 2022 16:00:17 +0700 Subject: [PATCH 1/3] [#5068] Fix see all submissions modal in mobile view --- .../app/components/AllSubmissionsModal.jsx | 23 +++++++++---------- .../spa/app/modules/results/enumerator.scss | 14 ++++++----- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/akvo/rsr/spa/app/components/AllSubmissionsModal.jsx b/akvo/rsr/spa/app/components/AllSubmissionsModal.jsx index 481266581a..98ccd3d23e 100644 --- a/akvo/rsr/spa/app/components/AllSubmissionsModal.jsx +++ b/akvo/rsr/spa/app/components/AllSubmissionsModal.jsx @@ -1,6 +1,6 @@ /* global document */ import React from 'react' -import { Modal } from 'antd' +import { Modal, Row, Col } from 'antd' import moment from 'moment' import SVGInline from 'react-svg-inline' import { nicenum } from '../utils/misc' @@ -18,7 +18,7 @@ export const AllSubmissionsModal = ({ visible, onCancel, period }) => { } return ( - +
{period.updates.map(update => { const dsgGroups = {} update.disaggregations.forEach(item => { @@ -31,8 +31,8 @@ export const AllSubmissionsModal = ({ visible, onCancel, period }) => { }) const dsgKeys = Object.keys(dsgGroups) return ( -
-
@@ -40,10 +40,9 @@ export const AllSubmissionsModal = ({ visible, onCancel, period }) => { {moment(update.createdAt).format('DD MMM YYYY')}
- - + {dsgKeys.map(dsgKey => [ -
{dsgKey}
@@ -60,16 +59,16 @@ export const AllSubmissionsModal = ({ visible, onCancel, period }) => { ])}
- + ])} -
{nicenum(update.value)}
- - + + ) } )} -
+ +
  +
+
+
) } diff --git a/akvo/rsr/spa/app/modules/results/enumerator.scss b/akvo/rsr/spa/app/modules/results/enumerator.scss index 9dc119f9fd..de9f659dcd 100644 --- a/akvo/rsr/spa/app/modules/results/enumerator.scss +++ b/akvo/rsr/spa/app/modules/results/enumerator.scss @@ -538,9 +538,9 @@ .ant-modal-body { overflow-x: auto; } - .ant-modal-body>table{ + .ant-modal-body>div{ width: 100%; - &>tr{ + &>.ant-row-flex{ &:not(:last-child){ border-bottom: 1px solid #d8d8d8; } @@ -588,13 +588,15 @@ margin-left: 10px; color: rgb(49, 49, 49); } - .h-holder{ - position: absolute; - top: -10px; - display: flex; + .h-holder { + margin: 8px 0; } ul{ + border: 1px solid #b6b6b6; + padding: 8px; + border-radius: 4px; display: flex; + overflow-x: scroll; li{ margin-left: 15px; white-space: nowrap; From 037876f3e262d73a69ab5ef5e2ed7206d25333d4 Mon Sep 17 00:00:00 2001 From: ifirmawan Date: Thu, 9 Mar 2023 20:37:55 +0700 Subject: [PATCH 2/3] [#5068] Re-introduce the modal component to show history on mobile view History modal only available for mobile and tab view : 1. Mobile view (max-width: 480px) 2. Tab view (max-width: 767px) --- .../app/components/AllSubmissionsModal.jsx | 25 ++++++++----- .../rsr/spa/app/components/UpdatesHistory.jsx | 34 ++++++++++++++++-- .../components/DisaggregationsInput.jsx | 2 +- .../components/ReportedEdit.scss | 36 +++++++++++++++++++ .../spa/app/modules/results/enumerator.jsx | 4 +-- 5 files changed, 86 insertions(+), 15 deletions(-) diff --git a/akvo/rsr/spa/app/components/AllSubmissionsModal.jsx b/akvo/rsr/spa/app/components/AllSubmissionsModal.jsx index 98ccd3d23e..3bb8d3bef1 100644 --- a/akvo/rsr/spa/app/components/AllSubmissionsModal.jsx +++ b/akvo/rsr/spa/app/components/AllSubmissionsModal.jsx @@ -8,10 +8,16 @@ import statusPending from '../images/status-pending.svg' import statusApproved from '../images/status-approved.svg' import statusRevision from '../images/status-revision.svg' -export const AllSubmissionsModal = ({ visible, onCancel, period }) => { - let width = 460 - if (period.disaggregations) { - width += period.disaggregations.length * 100 +export const AllSubmissionsModal = ({ + visible, + onCancel, + updates, + disaggregations, + disaggregationTargets, + width = 460, +}) => { + if (disaggregations) { + width += disaggregations.length * 100 } if (width > document.body.clientWidth - 100) { width = document.body.clientWidth - 100 @@ -19,20 +25,21 @@ export const AllSubmissionsModal = ({ visible, onCancel, period }) => { return (
- {period.updates.map(update => { + {updates.map(update => { const dsgGroups = {} update.disaggregations.forEach(item => { if (!dsgGroups[item.category]) dsgGroups[item.category] = [] dsgGroups[item.category].push(item) - if (period.disaggregationTargets.length > 0) { - const target = period.disaggregationTargets.find(it => it.typeId === item.typeId) + if (disaggregationTargets.length > 0) { + const target = disaggregationTargets.find(it => it.typeId === item.typeId) if (target != null) dsgGroups[item.category][dsgGroups[item.category].length - 1].targetValue = target.value } }) const dsgKeys = Object.keys(dsgGroups) + const colSize = dsgKeys?.length ? 5 : 8 return ( - +
@@ -61,7 +68,7 @@ export const AllSubmissionsModal = ({ visible, onCancel, period }) => {
])} - +
{nicenum(update.value)}
diff --git a/akvo/rsr/spa/app/components/UpdatesHistory.jsx b/akvo/rsr/spa/app/components/UpdatesHistory.jsx index 4b293d58e2..8507eed45c 100644 --- a/akvo/rsr/spa/app/components/UpdatesHistory.jsx +++ b/akvo/rsr/spa/app/components/UpdatesHistory.jsx @@ -1,15 +1,18 @@ -import React from 'react' +import React, { useState } from 'react' import { Row, Col, Collapse, Table, Tooltip, + Button, + Icon, } from 'antd' import classNames from 'classnames' import ExpandIcon from './ExpandIcon' import { toCapitalize } from '../utils/string' +import { AllSubmissionsModal } from './AllSubmissionsModal' const { Panel } = Collapse const { Column } = Table @@ -30,9 +33,14 @@ const setColumns = (value, key) => ({ const UpdatesHistory = ({ columns, tables, + updates, + disaggregations, + disaggregationTargets, activeKeys = DEFAULT_ACTIVE_KEYS, mneView = false, }) => { + const [visible, setVisible] = useState(false) + const getActiveKeys = (value) => activeKeys?.length ? [...activeKeys, ...DEFAULT_ACTIVE_KEYS]?.includes(value) : value @@ -68,11 +76,31 @@ const UpdatesHistory = ({ const tableProps = mneView ? { pagination: false, scroll: { x: 500 } } : { pagination: false } return ( - + + + + + setVisible(false)} + /> + + } + expandIcon={({ isActive }) => ( + + + + )} className="collapse-history" > diff --git a/akvo/rsr/spa/app/modules/results-admin/components/DisaggregationsInput.jsx b/akvo/rsr/spa/app/modules/results-admin/components/DisaggregationsInput.jsx index df887502f0..4b8ff894f0 100644 --- a/akvo/rsr/spa/app/modules/results-admin/components/DisaggregationsInput.jsx +++ b/akvo/rsr/spa/app/modules/results-admin/components/DisaggregationsInput.jsx @@ -32,7 +32,7 @@ const DisaggregationsInput = ({ /> ) : (
-
{dsg.value}
+
{dsg.value}
it.typeId === dsg.id && group.id === it.groupId)}].numerator`} control="input-number" diff --git a/akvo/rsr/spa/app/modules/results-admin/components/ReportedEdit.scss b/akvo/rsr/spa/app/modules/results-admin/components/ReportedEdit.scss index 5feffae3e5..a6a8db2a80 100644 --- a/akvo/rsr/spa/app/modules/results-admin/components/ReportedEdit.scss +++ b/akvo/rsr/spa/app/modules/results-admin/components/ReportedEdit.scss @@ -100,4 +100,40 @@ white-space: nowrap; } } + .table-history-sm { + display: none; + text-align: right; + .ant-btn-link { + color: rgba(0, 0, 0, 0.85); + } + } + .table-history-md { + display: block; + } +} + +/* +* Device = Low Resolution Tablets, Mobiles (Landscape) +* Screen = B/w 481px to 767px +*/ +@media (min-width: 481px) and (max-width: 767px) { + #rsr-form-container .table-history-sm { + display: block; + } + #rsr-form-container .table-history-md { + display: none; + } } + +/** +* Device = Most of the Smartphones Mobiles (Portrait) +* Screen = B/w 320px to 479px +*/ +@media (min-width: 320px) and (max-width: 480px) { + #rsr-form-container .table-history-sm { + display: block; + } + #rsr-form-container .table-history-md { + display: none; + } +} \ No newline at end of file diff --git a/akvo/rsr/spa/app/modules/results/enumerator.jsx b/akvo/rsr/spa/app/modules/results/enumerator.jsx index 552d13b6ac..609ce5b222 100644 --- a/akvo/rsr/spa/app/modules/results/enumerator.jsx +++ b/akvo/rsr/spa/app/modules/results/enumerator.jsx @@ -591,7 +591,7 @@ const AddUpdate = ({ period, indicator, addUpdateToPeriod, patchUpdateInPeriod, precision={2} verticalGuides={1} {...period} - /> + /> ) }} @@ -732,7 +732,7 @@ const PrevUpdate = ({ update, period, indicator }) => {
} - setShowSubmissionsModal(false)} /> + setShowSubmissionsModal(false)} />
) } From 4a5e943e970ef7d353d0d3ef2104b160ed9adc83 Mon Sep 17 00:00:00 2001 From: ifirmawan Date: Fri, 10 Mar 2023 14:56:30 +0700 Subject: [PATCH 3/3] [#5068] Set color value and dsg by update status --- .../app/components/AllSubmissionsModal.jsx | 101 ++++++++++-------- .../rsr/spa/app/components/UpdatesHistory.jsx | 3 + akvo/rsr/spa/app/images/status-pending.svg | 2 +- akvo/rsr/spa/app/images/status-revision.svg | 2 +- .../components/ReportedEdit.scss | 2 +- .../spa/app/modules/results/enumerator.scss | 36 ++++++- 6 files changed, 92 insertions(+), 54 deletions(-) diff --git a/akvo/rsr/spa/app/components/AllSubmissionsModal.jsx b/akvo/rsr/spa/app/components/AllSubmissionsModal.jsx index 3bb8d3bef1..b07ee78397 100644 --- a/akvo/rsr/spa/app/components/AllSubmissionsModal.jsx +++ b/akvo/rsr/spa/app/components/AllSubmissionsModal.jsx @@ -1,75 +1,84 @@ -/* global document */ import React from 'react' -import { Modal, Row, Col } from 'antd' +import { Modal, Row, Col, Tag, Badge } from 'antd' import moment from 'moment' import SVGInline from 'react-svg-inline' +import { groupBy, isEmpty } from 'lodash' +import classNames from 'classnames' import { nicenum } from '../utils/misc' import statusPending from '../images/status-pending.svg' import statusApproved from '../images/status-approved.svg' import statusRevision from '../images/status-revision.svg' +const StatusIcon = ({ status }) => { + if (status === 'A') { + return + } + if (['D', 'P'].includes(status)) { + return + } + if (status === 'R') { + return + } + return null +} + export const AllSubmissionsModal = ({ visible, onCancel, updates, - disaggregations, - disaggregationTargets, - width = 460, + width = 520, + activeKeys = [], + dsgOnly = false, }) => { - if (disaggregations) { - width += disaggregations.length * 100 - } - if (width > document.body.clientWidth - 100) { - width = document.body.clientWidth - 100 - } + const _updates = updates?.filter((u) => ( + (dsgOnly && u?.disaggregations?.length) || + (!dsgOnly) + )) return (
- {updates.map(update => { - const dsgGroups = {} - update.disaggregations.forEach(item => { - if (!dsgGroups[item.category]) dsgGroups[item.category] = [] - dsgGroups[item.category].push(item) - if (disaggregationTargets.length > 0) { - const target = disaggregationTargets.find(it => it.typeId === item.typeId) - if (target != null) dsgGroups[item.category][dsgGroups[item.category].length - 1].targetValue = target.value - } - }) - const dsgKeys = Object.keys(dsgGroups) - const colSize = dsgKeys?.length ? 5 : 8 + {_updates?.map(update => { + const _disaggregations = update?.disaggregations?.filter((dg) => activeKeys?.includes(dg?.type)) + const dsgGroups = groupBy(_disaggregations, 'category') + const userName = ( + isEmpty(update?.userDetails?.firstName) && + isEmpty(update?.userDetails?.lastName) + ) + ? update?.userDetails?.email + : `${update.userDetails.firstName} ${update.userDetails.lastName}` return ( - +
- +
- {update.userDetails.firstName} {update.userDetails.lastName} + {userName} {moment(update.createdAt).format('DD MMM YYYY')}
- {dsgKeys.map(dsgKey => [ - -
-
-
{dsgKey}
-
-
    - {dsgGroups[dsgKey].map((dsg) => [ -
  • -
    {dsg.type}
    + + { + Object.keys(dsgGroups).map((dsgKey, dx) => ( +
    +
    {dsgKey}
    + {dsgGroups[dsgKey]?.map((dsg, ix) => ( +
    - {nicenum(dsg.value)} - {dsg.targetValue && ({Math.round(((dsg.value / dsg.targetValue) * 100 * 10) / 10)}%)} + {dsg?.type}
    -
  • - ])} -
-
- - ])} - -
{nicenum(update.value)}
+
+ +
+ + ))} +
+ )) + } + + +
Value
+
{nicenum(update.value)}
) diff --git a/akvo/rsr/spa/app/components/UpdatesHistory.jsx b/akvo/rsr/spa/app/components/UpdatesHistory.jsx index 8507eed45c..673f2847d4 100644 --- a/akvo/rsr/spa/app/components/UpdatesHistory.jsx +++ b/akvo/rsr/spa/app/components/UpdatesHistory.jsx @@ -9,6 +9,7 @@ import { Icon, } from 'antd' import classNames from 'classnames' +import isEqual from 'lodash/isEqual' import ExpandIcon from './ExpandIcon' import { toCapitalize } from '../utils/string' @@ -86,10 +87,12 @@ const UpdatesHistory = ({ {...{ visible, updates, + activeKeys, disaggregations, disaggregationTargets, }} onCancel={() => setVisible(false)} + dsgOnly={!(isEqual(activeKeys, DEFAULT_ACTIVE_KEYS))} /> diff --git a/akvo/rsr/spa/app/images/status-pending.svg b/akvo/rsr/spa/app/images/status-pending.svg index c2ebb4aed7..d63382c455 100644 --- a/akvo/rsr/spa/app/images/status-pending.svg +++ b/akvo/rsr/spa/app/images/status-pending.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/akvo/rsr/spa/app/images/status-revision.svg b/akvo/rsr/spa/app/images/status-revision.svg index d632410c84..1af19ed2f3 100644 --- a/akvo/rsr/spa/app/images/status-revision.svg +++ b/akvo/rsr/spa/app/images/status-revision.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/akvo/rsr/spa/app/modules/results-admin/components/ReportedEdit.scss b/akvo/rsr/spa/app/modules/results-admin/components/ReportedEdit.scss index a6a8db2a80..c87b5da192 100644 --- a/akvo/rsr/spa/app/modules/results-admin/components/ReportedEdit.scss +++ b/akvo/rsr/spa/app/modules/results-admin/components/ReportedEdit.scss @@ -129,7 +129,7 @@ * Device = Most of the Smartphones Mobiles (Portrait) * Screen = B/w 320px to 479px */ -@media (min-width: 320px) and (max-width: 480px) { +@media (min-width: 280px) and (max-width: 480px) { #rsr-form-container .table-history-sm { display: block; } diff --git a/akvo/rsr/spa/app/modules/results/enumerator.scss b/akvo/rsr/spa/app/modules/results/enumerator.scss index de9f659dcd..e0f042bb21 100644 --- a/akvo/rsr/spa/app/modules/results/enumerator.scss +++ b/akvo/rsr/spa/app/modules/results/enumerator.scss @@ -382,7 +382,7 @@ color: #009B8F; } &.pending{ - color: #e36f3c; + color: #F79009; } &.returned{ color: #961417; @@ -537,12 +537,36 @@ .all-submissions-modal{ .ant-modal-body { overflow-x: auto; + padding: 1rem; } .ant-modal-body>div{ width: 100%; &>.ant-row-flex{ + .ant-col { + line-height: 1.5rem; + &.dsg-tags .ant-tag { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px; + margin: 8px 0; + } + &.dsg-tags .ant-tag .badge.D .ant-badge-count, + &.dsg-tags .ant-tag .badge.P .ant-badge-count { + background-color: #F79009; + } + &.dsg-tags .ant-tag .badge.R .ant-badge-count { + background-color: #D92D20; + + } + &.dsg-tags .ant-tag .badge.A .ant-badge-count { + background-color: #42998e; + } + } &:not(:last-child){ border-bottom: 1px solid #d8d8d8; + padding: .5rem 0 2.5rem; } svg{ width: 24px; @@ -561,9 +585,6 @@ margin-left: 10px; font-size: 13px; white-space: nowrap; - } - td{ - } td.spacer{ width: 100%; @@ -617,8 +638,13 @@ color: #42998e; font-weight: 600; font-size: 30px; - text-align: right; margin-right: 24px; + &.D, &.P { + color: #F79009; + } + &.R { + color: #D92D20; + } } } }