From 744aa40696dd6bcb21f78fb90694c0083abbf666 Mon Sep 17 00:00:00 2001 From: Andreas Ellewsen <andreas@ellewsen.no> Date: Thu, 21 Jul 2022 14:18:52 +0200 Subject: [PATCH] Show identity info on guest info page Sponsosr can now click a button next to passport/fnr values on the guest info page to see the source and verifier of the value. Resolves: GREG-275 --- frontend/public/locales/en/common.json | 4 ++ frontend/public/locales/nb/common.json | 4 ++ frontend/public/locales/nn/common.json | 4 ++ .../src/components/identityLine/index.tsx | 71 ++++++++++++++----- frontend/src/interfaces/index.ts | 8 +++ frontend/src/utils/index.ts | 3 + gregui/api/serializers/identity.py | 16 ++++- 7 files changed, 92 insertions(+), 18 deletions(-) diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json index e298c202..47d8d8e2 100644 --- a/frontend/public/locales/en/common.json +++ b/frontend/public/locales/en/common.json @@ -55,6 +55,10 @@ "roleInfoHead": "Roles and periods", "roleInfoTableText": "Guest roles", "roleInfoBody": "You can only change roles connected to units that you have given.", + "verifier": "Verified by", + "verified": "Verified", + "source": "Source", + "viewInfo": "View info", "identityCheck": { "failure": "<strong>Warning</strong>: Unable to check if person already exists in IGA.", "text": "<strong>Warning</strong>: <1>matches</1> already has this ID registerered to them. Please stop if this is not the same person." diff --git a/frontend/public/locales/nb/common.json b/frontend/public/locales/nb/common.json index b142ab0b..8db7af58 100644 --- a/frontend/public/locales/nb/common.json +++ b/frontend/public/locales/nb/common.json @@ -55,6 +55,10 @@ "roleInfoHead": "Roller og perioder", "roleInfoBody": "Du kan endre på tidsperioden, men kun på gjesteroller tilknyttet enheter du er vert for.", "roleInfoTableText": "Gjesteroller", + "verifier": "Godkjent av", + "verified": "Godkjent", + "source": "Kilde", + "viewInfo": "Se info", "identityCheck": { "failure": "<strong>Advarsel</strong>: Kunne ikke sjekke IGA om personen allerede er registrert.", "text": "<strong>Advarsel</strong>: <1>matches</1> har allerede denne ID-en registrert på seg i IGA. Stop dersom dette ikke er samme person." diff --git a/frontend/public/locales/nn/common.json b/frontend/public/locales/nn/common.json index 28d7a797..12ff6ef2 100644 --- a/frontend/public/locales/nn/common.json +++ b/frontend/public/locales/nn/common.json @@ -55,6 +55,10 @@ "roleInfoTableText": "Gjesteroller", "roleInfoHead": "Roller og periodar", "roleInfoBody": "Du kan endre på tidsperioden, men berre på gjesteroller knytta til eininger du er vert for.", + "verifier": "Godkjend av", + "verified": "Godkjend", + "source": "Kjelde", + "viewInfo": "Se info", "identityCheck": { "failure": "<strong>Advarsel</strong>: Kunne ikkje sjekke om personen allereie er registrert i andre system.", "text": "<strong>Advarsel</strong>: <1>matches</1> er allereie registrert med denne ID-en. Stopp dersom dette ikkje er same person." diff --git a/frontend/src/components/identityLine/index.tsx b/frontend/src/components/identityLine/index.tsx index 48f39df3..5c152a03 100644 --- a/frontend/src/components/identityLine/index.tsx +++ b/frontend/src/components/identityLine/index.tsx @@ -1,4 +1,5 @@ -import { Box, Button, TableRow, Typography } from '@mui/material' +import * as React from 'react' +import { Box, Button, Popper, TableRow } from '@mui/material' import ConfirmDialog from 'components/confirmDialog' import { Identity } from 'interfaces' import { useEffect, useState } from 'react' @@ -32,6 +33,14 @@ const IdentityLine = ({ reloadGuest() reloadGuests() } + const [verifiedBoxAnchor, setVerifiedBoxAnchor] = + React.useState<null | HTMLElement>(null) + const verifiedBoxOpen = Boolean(verifiedBoxAnchor) + const verifiedBoxId = verifiedBoxOpen ? 'verified-popper' : undefined + + const handleVerifiedInfo = (event: React.MouseEvent<HTMLElement>) => { + setVerifiedBoxAnchor(verifiedBoxAnchor ? null : event.currentTarget) + } const [identityCheckText, setIdentityCheckText] = useState<string | null>( null @@ -100,18 +109,10 @@ const IdentityLine = ({ justifyContent: 'flex-start', }} > - {/* Setting flex grow to 1 to push the verify button to the right on large screens */} - <Box - sx={{ - flexGrow: 1, - }} - > + <Box> {identity ? identity.value : ''} - </Box> - - {!identity.verified_at ? ( - <Box> - <Typography> + {!identity.verified ? ( + <> <Button aria-label={t('button.verify')} sx={{ @@ -137,11 +138,47 @@ const IdentityLine = ({ <IdentityCheckText /> {getDialogText()} </ConfirmDialog> - </Typography> - </Box> - ) : ( - <CheckIcon sx={{ fill: (theme) => theme.palette.success.main }} /> - )} + </> + ) : ( + <> + <CheckIcon + sx={{ + fill: (theme) => theme.palette.success.main, + verticalAlign: 'text-bottom', + border: 0, + }} + titleAccess={t('guestInfo.verified')} + /> + </> + )} + <Button + onClick={handleVerifiedInfo} + sx={{ + alignSelf: { xs: 'auto', md: 'flex-end' }, + marginLeft: { xs: '0rem', md: '1rem' }, + marginTop: { xs: '0.3rem', md: '0rem' }, + }} + > + {t('guestInfo.viewInfo')} + </Button> + <Popper + id={verifiedBoxId} + open={Boolean(verifiedBoxAnchor)} + anchorEl={verifiedBoxAnchor} + > + <Box sx={{ border: 1, p: 1, bgcolor: 'background.paper' }}> + {identity ? `${t('guestInfo.source')}: ${identity.source}` : ''} + <br /> + {identity && identity.verified !== '' + ? `${t('guestInfo.verifier')}: ${ + identity.verified === 'manual' + ? identity.verified_by + : identity.source + }` + : ''} + </Box> + </Popper> + </Box> </Box> </TableCell> </TableRow> diff --git a/frontend/src/interfaces/index.ts b/frontend/src/interfaces/index.ts index 311b4170..e0fcf7a2 100644 --- a/frontend/src/interfaces/index.ts +++ b/frontend/src/interfaces/index.ts @@ -14,10 +14,15 @@ export type Guest = { roles: Role[] } +type VerifiedChoices = "manual" | "automatic" | "" + export type Identity = { id: string type: string verified_at: Date | null + verified_by: string | null + verified: VerifiedChoices + source: string | null value: string } @@ -25,6 +30,9 @@ export type FetchedIdentity = { id: string type: string verified_at: string | null + verified_by: string | null + verified: VerifiedChoices + source: string | null value: string } diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index 645504e5..262f09f9 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -176,6 +176,9 @@ export function parseIdentity( type: identity.type, value: identity.value, verified_at: identity.verified_at ? parseISO(identity.verified_at) : null, + verified: identity.verified, + verified_by: identity.verified_by, + source: identity.source, } } diff --git a/gregui/api/serializers/identity.py b/gregui/api/serializers/identity.py index 6189d620..85edcf9a 100644 --- a/gregui/api/serializers/identity.py +++ b/gregui/api/serializers/identity.py @@ -82,6 +82,20 @@ class IdentitySerializer(serializers.ModelSerializer): class PartialIdentitySerializer(serializers.ModelSerializer): + verified_by = serializers.SerializerMethodField() + class Meta: model = Identity - fields = ["id", "value", "type", "verified_at"] + fields = [ + "id", + "value", + "type", + "source", + "verified", + "verified_by", + "verified_at", + ] + + def get_verified_by(self, obj): + sponsor = obj.verified_by + return " ".join((sponsor.first_name, sponsor.last_name)) if sponsor else None -- GitLab