diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json index e298c202361e0ab9080cf7c5adc308af7db36770..47d8d8e20098e7ab59b28b4f58e67c4bc7f870ba 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 b142ab0bd836e6885f4b1659943e46342c12c9f6..8db7af58c9ab06b6ef0b7478850dd1f0ef63a89c 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 28d7a797b56102c66a7f540d1e1092c83640df62..12ff6ef2bdf7a07f206f17a7f1dffcf5bd46d467 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 48f39df3b6950a07af9a44099800c3ada35589db..5c152a03e52300b2ecf4158ce39cf54313e29a4a 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 311b4170ba9c5fd173086e9179facee45a9fad38..e0fcf7a2885f153d2c80a826c7ec7bf491a61d36 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 645504e55beb4276756a035a8a522601fd81d727..262f09f9244ee6a1bb4a739fd4717bbe8f8dacda 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 6189d620e9cfdbcda7c365c954fd9bbe80640500..85edcf9a000414dbc98ac05a3fc90e4638a8f7c9 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