From 290ab71b1160ac0d761816fb71108c680ff84912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yhoan=20Alejandro=20Guzm=C3=A1n=20Garc=C3=ADa?= <41337901+yaguzmang@users.noreply.github.com> Date: Tue, 28 Jan 2025 00:56:04 -0500 Subject: [PATCH 01/38] 4206 - Data History - Authorizer canViewHistoryLastApproved (#4275) * 4206 - Add Authorizer canViewHistoryLastApproved * 4206 - Add missing nullish check --- src/client/store/user/hooks/index.ts | 9 ++++++++ src/meta/user/authorizer/index.ts | 32 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/client/store/user/hooks/index.ts b/src/client/store/user/hooks/index.ts index d330e279ce..8b5d068b1f 100644 --- a/src/client/store/user/hooks/index.ts +++ b/src/client/store/user/hooks/index.ts @@ -111,6 +111,15 @@ export const useCanViewHistory = (): boolean => { return Authorizer.canViewHistory({ country, cycle, section, user }) } +export const useCanViewHistoryLastApproved = (): boolean => { + const user = useUser() + const section = useSection() + const country = useAssessmentCountry() + const cycle = useCycle() + + return Authorizer.canViewHistoryLastApproved({ country, cycle, section, user }) +} + export const useCanViewGeo = (): boolean => { const cycle = useCycle() const { countryIso } = useCountryRouteParams() diff --git a/src/meta/user/authorizer/index.ts b/src/meta/user/authorizer/index.ts index 6dd649fc9f..bc99a4dbc8 100644 --- a/src/meta/user/authorizer/index.ts +++ b/src/meta/user/authorizer/index.ts @@ -215,6 +215,37 @@ const canViewHistory = (props: { return Users.isReviewer(user, country.countryIso, cycle) && canEditCycleData(props) } +/** + * canViewHistoryLastApproved + * Viewer or non loggedin user: never + * Administrator: if status >=review + * NationalCorrespondant and AlternateNationalCorrespondant: never + * Collaborator: never + * Reviewer: if country status = review + * @param props + * @param props.country + * @param props.cycle + * @param props.section + * @param props.user + * @returns boolean + */ +const canViewHistoryLastApproved = (props: { + country: Country + cycle: Cycle + section: Section | SubSection + user: User +}): boolean => { + const { country, cycle, user } = props + const { status } = country?.props ?? {} + + if (Users.isReviewer(user, country?.countryIso, cycle) && status === AssessmentStatus.review) return true + + return ( + Users.isAdministrator(user) && + [AssessmentStatus.review, AssessmentStatus.approval, AssessmentStatus.accepted].includes(status) + ) +} + export const canViewGeo = (props: { cycle: Cycle; countryIso: AreaCode; user: User }): boolean => Users.hasRoleInCountry(props) @@ -226,6 +257,7 @@ export const Authorizer = { canView, canViewGeo, canViewHistory, + canViewHistoryLastApproved, canViewRepositoryItem, canViewReview, // user From 37ab7e4749c0aeaa5825949324793dd648a05034 Mon Sep 17 00:00:00 2001 From: Mino Togna Date: Tue, 28 Jan 2025 08:29:14 +0100 Subject: [PATCH 02/38] 4248: Data History: Toolbar -> History Button (#4276) --- .../Toolbar/ButtonHistory/ButtonHistory.scss | 17 +++++++ .../Toolbar/ButtonHistory/ButtonHistory.tsx | 46 +++++++++++++++++ .../PageLayout/Toolbar/ButtonHistory/index.ts | 1 + .../Toolbar/EditorOptions/EditorOptions.scss | 9 +--- .../Toolbar/EditorOptions/EditorOptions.tsx | 15 ++++-- .../PageLayout/Toolbar/Lock/Lock.tsx | 19 ++++--- .../TablePaginated/hooks/useFetchData.tsx | 50 +++++++++---------- .../hooks/useHistoryLastApprovedIsActive.ts | 6 +++ src/client/store/data/index.ts | 1 + .../reducers/toggleHistoryLastApproved.ts | 13 +++++ src/client/store/data/selectors/index.ts | 8 +++ src/client/store/data/slice.ts | 7 ++- src/client/store/data/state.ts | 1 + src/client/store/user/hooks/index.ts | 3 +- src/meta/user/authorizer/index.ts | 17 ++----- 15 files changed, 156 insertions(+), 57 deletions(-) create mode 100644 src/client/components/PageLayout/Toolbar/ButtonHistory/ButtonHistory.scss create mode 100644 src/client/components/PageLayout/Toolbar/ButtonHistory/ButtonHistory.tsx create mode 100644 src/client/components/PageLayout/Toolbar/ButtonHistory/index.ts create mode 100644 src/client/store/data/hooks/useHistoryLastApprovedIsActive.ts create mode 100644 src/client/store/data/reducers/toggleHistoryLastApproved.ts diff --git a/src/client/components/PageLayout/Toolbar/ButtonHistory/ButtonHistory.scss b/src/client/components/PageLayout/Toolbar/ButtonHistory/ButtonHistory.scss new file mode 100644 index 0000000000..1461292bf2 --- /dev/null +++ b/src/client/components/PageLayout/Toolbar/ButtonHistory/ButtonHistory.scss @@ -0,0 +1,17 @@ +@import 'src/client/style/partials'; + +button.btn-history-last-approved { + height: $spacing-m; + padding: unset; + width: $spacing-l; + justify-content: center; + + svg { + height: 18px; + width: 18px; + } + + &.inverse { + background-color: transparent; + } +} diff --git a/src/client/components/PageLayout/Toolbar/ButtonHistory/ButtonHistory.tsx b/src/client/components/PageLayout/Toolbar/ButtonHistory/ButtonHistory.tsx new file mode 100644 index 0000000000..b8edac1559 --- /dev/null +++ b/src/client/components/PageLayout/Toolbar/ButtonHistory/ButtonHistory.tsx @@ -0,0 +1,46 @@ +import './ButtonHistory.scss' +import React, { useCallback } from 'react' +import MediaQuery from 'react-responsive' + +import { useAppDispatch } from 'client/store' +import { DataActions, useHistoryLastApprovedIsActive } from 'client/store/data' +import { DataLockActions, useIsDataLocked } from 'client/store/ui/dataLock' +import { useOnUpdate } from 'client/hooks' +import { useCountryRouteParams } from 'client/hooks/useRouteParams' +import Button, { ButtonSize, ButtonType } from 'client/components/Buttons/Button' +import { Breakpoints } from 'client/utils' + +const ButtonHistory: React.FC = () => { + const { countryIso } = useCountryRouteParams() + const dispatch = useAppDispatch() + const locked = useIsDataLocked() + const historyActive = useHistoryLastApprovedIsActive() + + const toggleHistory = useCallback(() => { + // if activating historyLastApproved and data edit is unlocked -> lock data edit + if (!historyActive && !locked) { + dispatch(DataLockActions.toggleDataLock()) + } + dispatch(DataActions.toggleHistoryLastApproved()) + }, [dispatch, historyActive, locked]) + + // if navigating to a different country, close history lastApproved + useOnUpdate(() => { + dispatch(DataActions.toggleHistoryLastApproved(false)) + }, [countryIso]) + + return ( + +