Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(auth-admin): View delegation and refactor access card #16243

Merged
merged 34 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
19f96d3
refactor AccessCard component and make change to modal to view delega…
magnearun Oct 2, 2024
0296d1f
remove unused createdBy
magnearun Oct 2, 2024
512ba57
Merge branch 'main' into feat/view-delegation-and-refactor-access-card
magnearun Oct 2, 2024
7290910
chore: nx format:write update dirty files
andes-it Oct 2, 2024
8cee9be
Merge branch 'main' into feat/view-delegation-and-refactor-access-card
magnearun Oct 3, 2024
e91f452
Merge branch 'main' into feat/view-delegation-and-refactor-access-card
magnearun Oct 3, 2024
2303c7d
refactor
magnearun Oct 3, 2024
6959a33
fix typo
magnearun Oct 3, 2024
c84172e
Merge branch 'main' into feat/view-delegation-and-refactor-access-card
magnearun Oct 3, 2024
bde8db5
chore: nx format:write update dirty files
andes-it Oct 3, 2024
ce27735
fix type
magnearun Oct 3, 2024
0da454c
Merge branch 'feat/view-delegation-and-refactor-access-card' of githu…
magnearun Oct 3, 2024
4d049bf
Merge branch 'main' into feat/view-delegation-and-refactor-access-card
magnearun Oct 3, 2024
caedd71
Merge branch 'main' into feat/view-delegation-and-refactor-access-card
magnearun Oct 3, 2024
64a1340
small refactor
magnearun Oct 4, 2024
1a26eec
fix delete function
magnearun Oct 4, 2024
c5d0ec0
chore: nx format:write update dirty files
andes-it Oct 4, 2024
a7dba72
Adds delete modal
magnearun Oct 7, 2024
31170ed
Merge branch 'feat/view-delegation-and-refactor-access-card' of githu…
magnearun Oct 7, 2024
a139245
chore: nx format:write update dirty files
andes-it Oct 7, 2024
28e3a1b
Update DelegationDeleteModal.tsx
magnearun Oct 7, 2024
c6da799
Merge branch 'main' into feat/view-delegation-and-refactor-access-card
magnearun Oct 7, 2024
497f618
adds loading to create modal
magnearun Oct 7, 2024
3fd7778
Merge branch 'feat/view-delegation-and-refactor-access-card' of githu…
magnearun Oct 7, 2024
338d608
chore: nx format:write update dirty files
andes-it Oct 7, 2024
c4f800b
small fixes and use view delegation modal in admin portal
magnearun Oct 8, 2024
33d0b14
Update AccessCard.tsx
magnearun Oct 8, 2024
937c10e
Merge branch 'main' into feat/view-delegation-and-refactor-access-card
magnearun Oct 8, 2024
09f8e28
chore: nx format:write update dirty files
andes-it Oct 8, 2024
34d9e2d
Merge branch 'main' into feat/view-delegation-and-refactor-access-card
magnearun Oct 8, 2024
31fd8d9
fix query and types
magnearun Oct 9, 2024
e7596c1
Merge branch 'main' into feat/view-delegation-and-refactor-access-card
magnearun Oct 9, 2024
7895f49
chore: nx format:write update dirty files
andes-it Oct 9, 2024
1d9272b
Merge branch 'main' into feat/view-delegation-and-refactor-access-card
kodiakhq[bot] Oct 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,17 @@ export class DelegationAdminResolver {
return identityLoader.load(customDelegation.toNationalId)
}

@ResolveField('createdBy', () => Identity, { nullable: true })
resolveCreatedByIdentity(
@Loader(IdentityLoader) identityLoader: IdentityDataLoader,
@Parent() customDelegation: DelegationDTO,
) {
if (!customDelegation.createdByNationalId) {
return null
}
return identityLoader.load(customDelegation.createdByNationalId)
}

@ResolveField('validTo', () => Date, { nullable: true })
resolveValidTo(@Parent() delegation: DelegationDTO): Date | undefined {
if (!delegation.validTo) {
Expand Down
3 changes: 3 additions & 0 deletions libs/api/domains/auth/src/lib/models/delegation.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ export abstract class Delegation {
@Field(() => Identity)
to!: Identity

@Field(() => Identity, { nullable: true })
createdBy?: Identity

@Field(() => AuthDelegationType)
type!: AuthDelegationType

Expand Down
11 changes: 11 additions & 0 deletions libs/api/domains/auth/src/lib/resolvers/delegation.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,17 @@ export class DelegationResolver {
)
}

@ResolveField('createdBy', () => Identity, { nullable: true })
async resolveCreatedBy(
@Parent() delegation: DelegationDTO,
): Promise<Identity | null> {
if (!delegation.createdByNationalId) {
return null
}

return this.identityService.getIdentity(delegation.createdByNationalId)
}

@ResolveField('validTo', () => Date, { nullable: true })
resolveValidTo(@Parent() delegation: DelegationDTO): Date | undefined {
if (!delegation.validTo) {
Expand Down
5 changes: 5 additions & 0 deletions libs/api/mocks/src/domains/auth/factories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ export const customDelegation = factory<AuthCustomDelegation>({
name: faker.name.findName(),
type: 'Person',
}),
createdBy: () => ({
nationalId: createNationalId('person'),
name: faker.name.findName(),
type: 'Person',
}),
type: 'Custom',
provider: 'delegationdb',
scopes: () => delegationScope.list(5),
Expand Down
5 changes: 5 additions & 0 deletions libs/auth-api-lib/src/lib/delegations/dto/delegation.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ export class DelegationDTO {
@IsString()
referenceId?: string | null

@IsOptional()
@IsString()
@ApiPropertyOptional({ nullable: true, type: String })
createdByNationalId?: string | null

@IsOptional()
@ApiPropertyOptional({ type: [DelegationScopeDTO] })
@IsArray()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export class Delegation extends Model<
fromNationalId: this.fromNationalId,
toNationalId: this.toNationalId,
toName: this.toName,
createdByNationalId: this.createdByNationalId,
validTo: this.validTo,
scopes: this.delegationScopes
? this.delegationScopes.map((scope) => scope.toDTO())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ type CreateDelegationConfirmModalProps = Pick<
referenceId: string
validTo?: string | undefined
} | null
loading: boolean
onConfirm(): void
}

export const CreateDelegationConfirmModal = ({
fromIdentity,
toIdentity,
data,
loading,
onClose,
onConfirm,
...rest
Expand All @@ -43,10 +45,6 @@ export const CreateDelegationConfirmModal = ({
isDisabled: !rest.isVisible,
})

const typeLabels: Record<string, string> = {
general: formatMessage(m.typeGeneral), // Todo: use enum yet to be created
}

return (
<Modal
id="access-confirm-modal"
Expand Down Expand Up @@ -86,7 +84,7 @@ export const CreateDelegationConfirmModal = ({
{data?.type && (
<IdentityCard
label={formatMessage(m.type)}
title={typeLabels[data.type]}
title={formatMessage(m.generalMandateLabel)}
imgSrc="./assets/images/skjaldarmerki.svg"
/>
)}
Expand Down Expand Up @@ -120,6 +118,7 @@ export const CreateDelegationConfirmModal = ({
<Box position="sticky" bottom={0}>
<DelegationsFormFooter
showShadow={showShadow}
loading={loading}
onCancel={onClose}
onConfirm={onConfirm}
confirmLabel={formatMessage(coreMessages.codeConfirmation)}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { Box, useBreakpoint } from '@island.is/island-ui/core'
import { useLocale } from '@island.is/localization'
import { formatNationalId, m as coreMessages } from '@island.is/portals/core'
import { Modal, ModalProps } from '@island.is/react/components'
import { m } from '../lib/messages'
import {
DelegationsFormFooter,
IdentityCard,
useDynamicShadow,
} from '@island.is/portals/shared-modules/delegations'
import { AuthCustomDelegation } from '@island.is/api/schema'
import format from 'date-fns/format'
import isValid from 'date-fns/isValid'
import { AuthDelegationType } from '@island.is/shared/types'

type DelegationDeleteModalProps = Pick<
ModalProps,
'id' | 'onClose' | 'isVisible'
> & {
loading: boolean
delegation?: AuthCustomDelegation
onDelete(): void
}

export const DelegationDeleteModal = ({
id,
loading,
delegation,
onClose,
onDelete,
...rest
}: DelegationDeleteModalProps) => {
const { formatMessage } = useLocale()
const { md } = useBreakpoint()

const { showShadow, pxProps } = useDynamicShadow({
rootMargin: md ? '-128px' : '-104px',
isDisabled: !rest.isVisible,
})

return (
<Modal
id={id}
label={formatMessage(m.deleteDelegationModalTitle)}
title={formatMessage(m.deleteDelegationModalTitle)}
onClose={onClose}
noPaddingBottom
scrollType="inside"
closeButtonLabel={formatMessage(m.cancel)}
{...rest}
>
<Box marginY={4} display="flex" flexDirection="column" rowGap={3}>
<Box
width="full"
display="flex"
flexDirection={['column', 'column', 'column', 'row']}
rowGap={[3, 3, 3, 0]}
columnGap={[0, 0, 0, 3]}
>
{delegation?.from?.name && delegation?.from?.nationalId && (
<IdentityCard
label={formatMessage(m.fromNationalId)}
title={delegation?.from?.name}
description={formatNationalId(delegation?.from?.nationalId)}
color="blue"
/>
)}
{delegation?.to?.name && delegation?.to?.nationalId && (
<IdentityCard
label={formatMessage(m.toNationalId)}
title={delegation?.to.name}
description={formatNationalId(delegation?.to.nationalId)}
color="purple"
/>
)}
</Box>
{delegation?.type &&
delegation.type === AuthDelegationType.GeneralMandate && (
<IdentityCard
label={formatMessage(m.type)}
title={formatMessage(m.generalMandateLabel)}
imgSrc="./assets/images/skjaldarmerki.svg"
/>
)}

<Box
display="flex"
flexDirection={['column', 'row']}
justifyContent="spaceBetween"
columnGap={[0, 3]}
rowGap={[3, 0]}
>
<IdentityCard
label={formatMessage(m.validTo)}
title={
delegation?.validTo && isValid(delegation.validTo)
? format(new Date(delegation?.validTo), 'dd.MM.yyyy')
: formatMessage(m.noEndDate)
}
/>
{delegation?.referenceId && (
<IdentityCard
label={formatMessage(m.referenceId)}
title={delegation?.referenceId}
/>
)}
</Box>
</Box>

<div {...pxProps} />

<Box position="sticky" bottom={0}>
<DelegationsFormFooter
loading={loading}
showShadow={showShadow}
confirmButtonColorScheme="destructive"
onCancel={onClose}
onConfirm={onDelete}
confirmLabel={formatMessage(coreMessages.buttonDestroy)}
containerPaddingBottom={[3, 3, 6]}
/>
</Box>
</Modal>
)
}
Original file line number Diff line number Diff line change
@@ -1,45 +1,86 @@
import { AuthCustomDelegation } from '@island.is/api/schema'
import { Box, Stack } from '@island.is/island-ui/core'
import { AccessCard } from '@island.is/portals/shared-modules/delegations'
import {
AccessCard,
DelegationViewModal,
} from '@island.is/portals/shared-modules/delegations'
import { useDeleteCustomDelegationAdminMutation } from '../screens/DelegationAdminDetails/DelegationAdmin.generated'
import { useRevalidator } from 'react-router-dom'
import React, { useState } from 'react'
import { DelegationDeleteModal } from './DelegationDeleteModal'

interface DelegationProps {
direction: 'incoming' | 'outgoing'
delegationsList: AuthCustomDelegation[]
}

const DelegationList = ({ delegationsList, direction }: DelegationProps) => {
const [deleteCustomDelegationAdminMutation] =
const [deleteCustomDelegationAdminMutation, { loading }] =
useDeleteCustomDelegationAdminMutation()
const { revalidate } = useRevalidator()
const [delegationToDelete, setDelegationToDelete] =
useState<AuthCustomDelegation | null>(null)
const [delegationView, setDelegationView] =
useState<AuthCustomDelegation | null>(null)

const deleteHandler = async (id: string) => {
const { data } = await deleteCustomDelegationAdminMutation({
variables: {
id,
},
})
if (data) {
revalidate()
setDelegationToDelete(null)
}
}

return (
<Box marginTop={2}>
<Stack space={3}>
{delegationsList.map((delegation) => {
return (
<AccessCard
canModify={!!delegation.referenceId} // only allow deletion of paper delegations
direction={direction}
key={delegation.id}
delegation={delegation}
isAdminView={true}
onDelete={async () => {
const { data } = await deleteCustomDelegationAdminMutation({
variables: {
id: delegation.id as string,
},
})
if (data) {
revalidate()
<>
<Box marginTop={2}>
<Stack space={3}>
{delegationsList.map((delegation) => {
return (
<AccessCard
magnearun marked this conversation as resolved.
Show resolved Hide resolved
key={delegation.id}
delegation={delegation}
isAdminView
variant={direction}
onView={
delegation.referenceId
? (d) => setDelegationView(d)
: undefined
}
onDelete={
delegation.referenceId
? () => setDelegationToDelete(delegation)
: undefined
}
}}
/>
)
})}
</Stack>
</Box>
/>
)
})}
</Stack>
</Box>
<DelegationDeleteModal
id={`${direction}-delegation-delete-modal`}
delegation={delegationToDelete as AuthCustomDelegation}
loading={loading}
onClose={() => setDelegationToDelete(null)}
onDelete={() => {
if (delegationToDelete) {
deleteHandler(delegationToDelete.id as string)
}
}}
isVisible={!!delegationToDelete}
/>
<DelegationViewModal
onClose={() => setDelegationView(null)}
isVisible={!!delegationView}
delegation={delegationView || undefined}
direction={direction}
isAdminView
/>
</>
)
}

Expand Down
14 changes: 11 additions & 3 deletions libs/portals/admin/delegation-admin/src/lib/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,13 @@ export const m = defineMessages({
id: 'admin.delegationAdmin:create',
defaultMessage: 'Skrá umboð',
},
delete: {
id: 'admin.delegationAdmin:delete',
defaultMessage: 'Eyða umboði',
},
noEndDate: {
id: 'admin.delegationAdmin:noEndDate',
defaultMessage: 'Gildis tími óendanlegur',
defaultMessage: 'Gildistími óendanlegur',
},
validTo: {
id: 'admin.delegationAdmin:validTo',
Expand All @@ -73,8 +77,8 @@ export const m = defineMessages({
id: 'admin.delegationAdmin:type',
defaultMessage: 'Aðgangstegund',
},
typeGeneral: {
id: 'admin.delegationAdmin:typeGeneral',
generalMandateLabel: {
id: 'admin.delegationAdmin:generalMandateLabel',
defaultMessage: 'Allsherjarumboð',
},
referenceId: {
Expand Down Expand Up @@ -117,6 +121,10 @@ export const m = defineMessages({
id: 'admin.delegationAdmin:createDelegationConfirmModalTitle',
defaultMessage: 'Þú ert að skrá nýtt umboð',
},
deleteDelegationModalTitle: {
id: 'admin.delegationAdmin:deleteDelegationModalTitle',
defaultMessage: 'Eyða umboði',
},
createDelegationSuccessToast: {
id: 'admin.delegationAdmin:createDelegationSuccessToast',
defaultMessage: 'Umboð var skráð',
Expand Down
Loading