From bf49cd7f09a7b81622ec4efb673666021749cbbb Mon Sep 17 00:00:00 2001 From: seluianova Date: Tue, 5 Nov 2024 18:32:38 +0100 Subject: [PATCH 1/8] 1430: Add query params to card self service form --- .../self-service/CardSelfServiceForm.tsx | 42 ++++++++++++++++++- .../self-service/CardSelfServiceView.tsx | 3 ++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/administration/src/bp-modules/self-service/CardSelfServiceForm.tsx b/administration/src/bp-modules/self-service/CardSelfServiceForm.tsx index d7a193387..4c8377770 100644 --- a/administration/src/bp-modules/self-service/CardSelfServiceForm.tsx +++ b/administration/src/bp-modules/self-service/CardSelfServiceForm.tsx @@ -1,13 +1,14 @@ import { Checkbox, FormGroup, InputGroup, Intent } from '@blueprintjs/core' import InfoOutlined from '@mui/icons-material/InfoOutlined' import { Alert, styled } from '@mui/material' -import React, { ReactElement, useContext, useState } from 'react' +import React, { ReactElement, useContext, useEffect, useRef, useState } from 'react' import { Card, isFullNameValid, isValid } from '../../cards/Card' import ClearInputButton from '../../cards/extensions/components/ClearInputButton' import useWindowDimensions from '../../hooks/useWindowDimensions' import BasicDialog from '../../mui-modules/application/BasicDialog' import { ProjectConfigContext } from '../../project-configs/ProjectConfigContext' +import PlainDate from '../../util/PlainDate' import ExtensionForms from '../cards/ExtensionForms' import { ActionButton } from './components/ActionButton' import { IconTextButton } from './components/IconTextButton' @@ -30,6 +31,7 @@ const Container = styled('div')` type CardSelfServiceFormProps = { card: Card + cardQueryParams: URLSearchParams updateCard: (card: Partial) => void dataPrivacyAccepted: boolean setDataPrivacyAccepted: (value: boolean) => void @@ -47,8 +49,44 @@ const getTooltipMessage = (cardsValid: boolean, dataPrivacyAccepted: boolean): s return tooltipMessages.join('\n') } + +const useInitializeCard = (cardQueryParams: URLSearchParams, updateCard: (card: Partial) => void) => { + const hasInitialized = useRef(false) + + useEffect(() => { + if (!hasInitialized.current) { + hasInitialized.current = true + + const fullName = cardQueryParams.get('name') + const birthday = cardQueryParams.get('geburtsdatum') + + const parsedBirthday: PlainDate | null = (() => { + if (!birthday) { + return null + } + try { + return PlainDate.from(birthday) + } catch { + return null + } + })() + + const referenceNumber = cardQueryParams.get('ref') + + updateCard({ + ...(fullName !== null && { fullName }), + extensions: { + ...(referenceNumber !== null && { koblenzReferenceNumber: referenceNumber }), + ...(parsedBirthday !== null && { birthday: parsedBirthday }), + }, + }) + } + }, [cardQueryParams, updateCard]) +} + const CardSelfServiceForm = ({ card, + cardQueryParams, updateCard, dataPrivacyAccepted, setDataPrivacyAccepted, @@ -61,6 +99,8 @@ const CardSelfServiceForm = ({ const cardValid = isValid(card, { expirationDateNullable: true }) const cardCreationDisabled = !cardValid || !dataPrivacyAccepted + useInitializeCard(cardQueryParams, updateCard) + return ( <> diff --git a/administration/src/bp-modules/self-service/CardSelfServiceView.tsx b/administration/src/bp-modules/self-service/CardSelfServiceView.tsx index 93c85452e..4eb480142 100644 --- a/administration/src/bp-modules/self-service/CardSelfServiceView.tsx +++ b/administration/src/bp-modules/self-service/CardSelfServiceView.tsx @@ -1,5 +1,6 @@ import { Spinner } from '@blueprintjs/core' import React, { ReactElement, useContext, useState } from 'react' +import { useSearchParams } from 'react-router-dom' import styled from 'styled-components' import KoblenzLogo from '../../assets/koblenz_logo.svg' @@ -73,6 +74,7 @@ const HeaderLogo = styled.img` // TODO 1646 Add tests for CardSelfService const CardSelfServiceView = (): ReactElement => { const projectConfig = useContext(ProjectConfigContext) + const [queryParams] = useSearchParams() const [dataPrivacyAccepted, setDataPrivacyAccepted] = useState(false) const { selfServiceState, @@ -113,6 +115,7 @@ const CardSelfServiceView = (): ReactElement => { {selfServiceState === CardSelfServiceStep.form && ( setSelfServiceCard(updateCard(selfServiceCard, updatedCard))} From 34cb958ab7abe71dc247a1fb0d6bfd1934f0d4ea Mon Sep 17 00:00:00 2001 From: seluianova Date: Mon, 11 Nov 2024 12:17:42 +0100 Subject: [PATCH 2/8] 1430: Init card from query params in useCardGeneratorSelfService --- .../self-service/CardSelfServiceForm.tsx | 41 +------------------ .../self-service/CardSelfServiceView.tsx | 3 -- .../hooks/useCardGeneratorSelfService.ts | 40 +++++++++++++++++- .../cards/extensions/BirthdayExtension.tsx | 2 +- 4 files changed, 40 insertions(+), 46 deletions(-) diff --git a/administration/src/bp-modules/self-service/CardSelfServiceForm.tsx b/administration/src/bp-modules/self-service/CardSelfServiceForm.tsx index 4c8377770..809791756 100644 --- a/administration/src/bp-modules/self-service/CardSelfServiceForm.tsx +++ b/administration/src/bp-modules/self-service/CardSelfServiceForm.tsx @@ -1,14 +1,13 @@ import { Checkbox, FormGroup, InputGroup, Intent } from '@blueprintjs/core' import InfoOutlined from '@mui/icons-material/InfoOutlined' import { Alert, styled } from '@mui/material' -import React, { ReactElement, useContext, useEffect, useRef, useState } from 'react' +import React, { ReactElement, useContext, useState } from 'react' import { Card, isFullNameValid, isValid } from '../../cards/Card' import ClearInputButton from '../../cards/extensions/components/ClearInputButton' import useWindowDimensions from '../../hooks/useWindowDimensions' import BasicDialog from '../../mui-modules/application/BasicDialog' import { ProjectConfigContext } from '../../project-configs/ProjectConfigContext' -import PlainDate from '../../util/PlainDate' import ExtensionForms from '../cards/ExtensionForms' import { ActionButton } from './components/ActionButton' import { IconTextButton } from './components/IconTextButton' @@ -31,7 +30,6 @@ const Container = styled('div')` type CardSelfServiceFormProps = { card: Card - cardQueryParams: URLSearchParams updateCard: (card: Partial) => void dataPrivacyAccepted: boolean setDataPrivacyAccepted: (value: boolean) => void @@ -50,43 +48,8 @@ const getTooltipMessage = (cardsValid: boolean, dataPrivacyAccepted: boolean): s return tooltipMessages.join('\n') } -const useInitializeCard = (cardQueryParams: URLSearchParams, updateCard: (card: Partial) => void) => { - const hasInitialized = useRef(false) - - useEffect(() => { - if (!hasInitialized.current) { - hasInitialized.current = true - - const fullName = cardQueryParams.get('name') - const birthday = cardQueryParams.get('geburtsdatum') - - const parsedBirthday: PlainDate | null = (() => { - if (!birthday) { - return null - } - try { - return PlainDate.from(birthday) - } catch { - return null - } - })() - - const referenceNumber = cardQueryParams.get('ref') - - updateCard({ - ...(fullName !== null && { fullName }), - extensions: { - ...(referenceNumber !== null && { koblenzReferenceNumber: referenceNumber }), - ...(parsedBirthday !== null && { birthday: parsedBirthday }), - }, - }) - } - }, [cardQueryParams, updateCard]) -} - const CardSelfServiceForm = ({ card, - cardQueryParams, updateCard, dataPrivacyAccepted, setDataPrivacyAccepted, @@ -99,8 +62,6 @@ const CardSelfServiceForm = ({ const cardValid = isValid(card, { expirationDateNullable: true }) const cardCreationDisabled = !cardValid || !dataPrivacyAccepted - useInitializeCard(cardQueryParams, updateCard) - return ( <> diff --git a/administration/src/bp-modules/self-service/CardSelfServiceView.tsx b/administration/src/bp-modules/self-service/CardSelfServiceView.tsx index 4eb480142..93c85452e 100644 --- a/administration/src/bp-modules/self-service/CardSelfServiceView.tsx +++ b/administration/src/bp-modules/self-service/CardSelfServiceView.tsx @@ -1,6 +1,5 @@ import { Spinner } from '@blueprintjs/core' import React, { ReactElement, useContext, useState } from 'react' -import { useSearchParams } from 'react-router-dom' import styled from 'styled-components' import KoblenzLogo from '../../assets/koblenz_logo.svg' @@ -74,7 +73,6 @@ const HeaderLogo = styled.img` // TODO 1646 Add tests for CardSelfService const CardSelfServiceView = (): ReactElement => { const projectConfig = useContext(ProjectConfigContext) - const [queryParams] = useSearchParams() const [dataPrivacyAccepted, setDataPrivacyAccepted] = useState(false) const { selfServiceState, @@ -115,7 +113,6 @@ const CardSelfServiceView = (): ReactElement => { {selfServiceState === CardSelfServiceStep.form && ( setSelfServiceCard(updateCard(selfServiceCard, updatedCard))} diff --git a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.ts b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.ts index 041edde93..af858cd53 100644 --- a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.ts +++ b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.ts @@ -1,5 +1,6 @@ import { ApolloError } from '@apollo/client' -import { useCallback, useContext, useState } from 'react' +import { useCallback, useContext, useEffect, useState } from 'react' +import { useSearchParams } from 'react-router-dom' import { Card, generateCardInfo, initializeCard } from '../../../cards/Card' import { generatePdf } from '../../../cards/PdfFactory' @@ -8,6 +9,7 @@ import getMessageFromApolloError from '../../../errors/getMessageFromApolloError import { DynamicActivationCode, StaticVerificationCode } from '../../../generated/card_pb' import { useCreateCardsFromSelfServiceMutation } from '../../../generated/graphql' import { ProjectConfigContext } from '../../../project-configs/ProjectConfigContext' +import PlainDate from '../../../util/PlainDate' import { base64ToUint8Array, uint8ArrayToBase64 } from '../../../util/base64' import downloadDataUri from '../../../util/downloadDataUri' import getCustomDeepLinkFromQrCode from '../../../util/getCustomDeepLinkFromQrCode' @@ -31,12 +33,46 @@ type UseCardGeneratorSelfServiceReturn = { downloadPdf: (code: CreateCardsResult, fileName: string) => Promise } +const parseDate = (dateString: string): PlainDate | undefined => { + try { + return PlainDate.from(dateString) + } catch { + return undefined + } +} + +const handleQueryParams = ( + cardQueryParams: URLSearchParams +): { + fullName?: string + birthday?: PlainDate + koblenzReferenceNumber?: string +} => { + const fullName = cardQueryParams.get('name') ?? undefined + const birthday = cardQueryParams.get('geburtsdatum') ?? undefined + const referenceNumber = cardQueryParams.get('ref') ?? undefined + return { + fullName, + birthday: birthday ? parseDate(birthday) : undefined, + koblenzReferenceNumber: referenceNumber, + } +} + const useCardGeneratorSelfService = (): UseCardGeneratorSelfServiceReturn => { const projectConfig = useContext(ProjectConfigContext) const appToaster = useAppToaster() + const [cardQueryParams, setSearchParams] = useSearchParams() + const { fullName, birthday, koblenzReferenceNumber } = handleQueryParams(cardQueryParams) const [selfServiceCard, setSelfServiceCard] = useState( - initializeCard(projectConfig.card, undefined, { expirationDate: null }) + initializeCard(projectConfig.card, undefined, { + fullName, + expirationDate: null, + extensions: { birthday, koblenzReferenceNumber }, + }) ) + useEffect(() => { + setSearchParams(undefined, { replace: true }) + }, [setSearchParams]) const [isLoading, setIsLoading] = useState(false) const [selfServiceState, setSelfServiceState] = useState(CardSelfServiceStep.form) const [deepLink, setDeepLink] = useState('') diff --git a/administration/src/cards/extensions/BirthdayExtension.tsx b/administration/src/cards/extensions/BirthdayExtension.tsx index 358c43a6d..db6f90294 100644 --- a/administration/src/cards/extensions/BirthdayExtension.tsx +++ b/administration/src/cards/extensions/BirthdayExtension.tsx @@ -57,7 +57,7 @@ const BirthdayExtension: Extension = { }, }), isValid: ({ birthday }: BirthdayExtensionState) => { - if (birthday === null) { + if (birthday == null) { return false } const today = PlainDate.fromLocalDate(new Date()) From 6224bbba67bf70d67c553f95daab85933c203dbc Mon Sep 17 00:00:00 2001 From: seluianova Date: Mon, 11 Nov 2024 14:09:42 +0100 Subject: [PATCH 3/8] 1430: Use PlainDate.safeFrom() function to parse birthday from query param --- .../hooks/useCardGeneratorSelfService.ts | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.ts b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.ts index af858cd53..ece97a497 100644 --- a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.ts +++ b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.ts @@ -33,14 +33,6 @@ type UseCardGeneratorSelfServiceReturn = { downloadPdf: (code: CreateCardsResult, fileName: string) => Promise } -const parseDate = (dateString: string): PlainDate | undefined => { - try { - return PlainDate.from(dateString) - } catch { - return undefined - } -} - const handleQueryParams = ( cardQueryParams: URLSearchParams ): { @@ -49,13 +41,9 @@ const handleQueryParams = ( koblenzReferenceNumber?: string } => { const fullName = cardQueryParams.get('name') ?? undefined - const birthday = cardQueryParams.get('geburtsdatum') ?? undefined - const referenceNumber = cardQueryParams.get('ref') ?? undefined - return { - fullName, - birthday: birthday ? parseDate(birthday) : undefined, - koblenzReferenceNumber: referenceNumber, - } + const birthday = PlainDate.safeFrom(cardQueryParams.get('geburtsdatum')) ?? undefined + const koblenzReferenceNumber = cardQueryParams.get('ref') ?? undefined + return { fullName, birthday, koblenzReferenceNumber } } const useCardGeneratorSelfService = (): UseCardGeneratorSelfServiceReturn => { From de0acbaa25542155d74f518adfbdc4db55f76361 Mon Sep 17 00:00:00 2001 From: seluianova Date: Mon, 11 Nov 2024 17:16:32 +0100 Subject: [PATCH 4/8] 1430: Fix code style --- .../self-service/hooks/useCardGeneratorSelfService.ts | 8 +++++--- administration/src/cards/extensions/BirthdayExtension.tsx | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.ts b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.ts index ece97a497..465384a39 100644 --- a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.ts +++ b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.ts @@ -58,13 +58,15 @@ const useCardGeneratorSelfService = (): UseCardGeneratorSelfServiceReturn => { extensions: { birthday, koblenzReferenceNumber }, }) ) - useEffect(() => { - setSearchParams(undefined, { replace: true }) - }, [setSearchParams]) const [isLoading, setIsLoading] = useState(false) const [selfServiceState, setSelfServiceState] = useState(CardSelfServiceStep.form) const [deepLink, setDeepLink] = useState('') const [code, setCode] = useState(null) + + useEffect(() => { + setSearchParams(undefined, { replace: true }) + }, [setSearchParams]) + const [createCardsSelfService] = useCreateCardsFromSelfServiceMutation() const handleErrors = useCallback( diff --git a/administration/src/cards/extensions/BirthdayExtension.tsx b/administration/src/cards/extensions/BirthdayExtension.tsx index db6f90294..8468484e4 100644 --- a/administration/src/cards/extensions/BirthdayExtension.tsx +++ b/administration/src/cards/extensions/BirthdayExtension.tsx @@ -57,7 +57,7 @@ const BirthdayExtension: Extension = { }, }), isValid: ({ birthday }: BirthdayExtensionState) => { - if (birthday == null) { + if (!birthday) { return false } const today = PlainDate.fromLocalDate(new Date()) From 64eba615d938d7833264ebeec9b5b55d9a7b4c29 Mon Sep 17 00:00:00 2001 From: seluianova Date: Wed, 20 Nov 2024 16:42:07 +0100 Subject: [PATCH 5/8] 1430: Resolve merge conflicts --- .../hooks/useCardGeneratorSelfService.tsx | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx index a7469dbed..11b2a207d 100644 --- a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx +++ b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx @@ -1,5 +1,6 @@ import { ApolloError } from '@apollo/client' -import React, { useCallback, useContext, useState } from 'react' +import React, { useCallback, useContext, useEffect, useState } from 'react' +import { useSearchParams } from 'react-router-dom' import { Card, generateCardInfo, initializeCard } from '../../../cards/Card' import { generatePdf } from '../../../cards/PdfFactory' @@ -8,6 +9,7 @@ import getMessageFromApolloError from '../../../errors/getMessageFromApolloError import { DynamicActivationCode, StaticVerificationCode } from '../../../generated/card_pb' import { useCreateCardsFromSelfServiceMutation } from '../../../generated/graphql' import { ProjectConfigContext } from '../../../project-configs/ProjectConfigContext' +import PlainDate from '../../../util/PlainDate' import { base64ToUint8Array, uint8ArrayToBase64 } from '../../../util/base64' import downloadDataUri from '../../../util/downloadDataUri' import getCustomDeepLinkFromQrCode from '../../../util/getCustomDeepLinkFromQrCode' @@ -32,16 +34,40 @@ type UseCardGeneratorSelfServiceReturn = { downloadPdf: (code: CreateCardsResult, fileName: string) => Promise } +const handleQueryParams = ( + cardQueryParams: URLSearchParams +): { + fullName?: string + birthday?: PlainDate + koblenzReferenceNumber?: string +} => { + const fullName = cardQueryParams.get('name') ?? undefined + const birthday = PlainDate.safeFrom(cardQueryParams.get('geburtsdatum')) ?? undefined + const koblenzReferenceNumber = cardQueryParams.get('ref') ?? undefined + return { fullName, birthday, koblenzReferenceNumber } +} + const useCardGeneratorSelfService = (): UseCardGeneratorSelfServiceReturn => { const projectConfig = useContext(ProjectConfigContext) const appToaster = useAppToaster() + const [cardQueryParams, setSearchParams] = useSearchParams() + const { fullName, birthday, koblenzReferenceNumber } = handleQueryParams(cardQueryParams) const [selfServiceCard, setSelfServiceCard] = useState( - initializeCard(projectConfig.card, undefined, { expirationDate: null }) + initializeCard(projectConfig.card, undefined, { + fullName, + expirationDate: null, + extensions: { birthday, koblenzReferenceNumber }, + }) ) const [isLoading, setIsLoading] = useState(false) const [selfServiceState, setSelfServiceState] = useState(CardSelfServiceStep.form) const [deepLink, setDeepLink] = useState('') const [code, setCode] = useState(null) + + useEffect(() => { + setSearchParams(undefined, { replace: true }) + }, [setSearchParams]) + const [createCardsSelfService] = useCreateCardsFromSelfServiceMutation() const handleErrors = useCallback( From ee12261d82f47b95b505dd36125819dc5245a480 Mon Sep 17 00:00:00 2001 From: seluianova Date: Wed, 20 Nov 2024 18:08:31 +0100 Subject: [PATCH 6/8] 1430: Refactor card initialization --- .../hooks/useCardGeneratorSelfService.tsx | 30 +++++-------------- administration/src/cards/Card.ts | 4 +-- 2 files changed, 9 insertions(+), 25 deletions(-) diff --git a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx index 11b2a207d..1bf37275b 100644 --- a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx +++ b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx @@ -2,18 +2,18 @@ import { ApolloError } from '@apollo/client' import React, { useCallback, useContext, useEffect, useState } from 'react' import { useSearchParams } from 'react-router-dom' -import { Card, generateCardInfo, initializeCard } from '../../../cards/Card' +import { Card, generateCardInfo, initializeCardFromCSV } from '../../../cards/Card' import { generatePdf } from '../../../cards/PdfFactory' import { CreateCardsError, CreateCardsResult } from '../../../cards/createCards' import getMessageFromApolloError from '../../../errors/getMessageFromApolloError' import { DynamicActivationCode, StaticVerificationCode } from '../../../generated/card_pb' import { useCreateCardsFromSelfServiceMutation } from '../../../generated/graphql' import { ProjectConfigContext } from '../../../project-configs/ProjectConfigContext' -import PlainDate from '../../../util/PlainDate' import { base64ToUint8Array, uint8ArrayToBase64 } from '../../../util/base64' import downloadDataUri from '../../../util/downloadDataUri' import getCustomDeepLinkFromQrCode from '../../../util/getCustomDeepLinkFromQrCode' import { useAppToaster } from '../../AppToaster' +import { getHeaders } from '../../cards/ImportCardsController' import FormErrorMessage from '../components/FormErrorMessage' export enum CardSelfServiceStep { @@ -34,31 +34,15 @@ type UseCardGeneratorSelfServiceReturn = { downloadPdf: (code: CreateCardsResult, fileName: string) => Promise } -const handleQueryParams = ( - cardQueryParams: URLSearchParams -): { - fullName?: string - birthday?: PlainDate - koblenzReferenceNumber?: string -} => { - const fullName = cardQueryParams.get('name') ?? undefined - const birthday = PlainDate.safeFrom(cardQueryParams.get('geburtsdatum')) ?? undefined - const koblenzReferenceNumber = cardQueryParams.get('ref') ?? undefined - return { fullName, birthday, koblenzReferenceNumber } -} - const useCardGeneratorSelfService = (): UseCardGeneratorSelfServiceReturn => { const projectConfig = useContext(ProjectConfigContext) const appToaster = useAppToaster() const [cardQueryParams, setSearchParams] = useSearchParams() - const { fullName, birthday, koblenzReferenceNumber } = handleQueryParams(cardQueryParams) - const [selfServiceCard, setSelfServiceCard] = useState( - initializeCard(projectConfig.card, undefined, { - fullName, - expirationDate: null, - extensions: { birthday, koblenzReferenceNumber }, - }) - ) + const [selfServiceCard, setSelfServiceCard] = useState(() => { + const headers = getHeaders(projectConfig) + const values = headers.map(header => cardQueryParams.get(header)) + return initializeCardFromCSV(projectConfig.card, values, headers, undefined, true) + }) const [isLoading, setIsLoading] = useState(false) const [selfServiceState, setSelfServiceState] = useState(CardSelfServiceStep.form) const [deepLink, setDeepLink] = useState('') diff --git a/administration/src/cards/Card.ts b/administration/src/cards/Card.ts index 20dfbb017..5c57bbb34 100644 --- a/administration/src/cards/Card.ts +++ b/administration/src/cards/Card.ts @@ -162,12 +162,12 @@ export const initializeCardFromCSV = ( cardConfig: CardConfig, line: (string | null)[], headers: string[], - region: Region, + region: Region | undefined, withDefaults = false ): Card => { const defaultCard = withDefaults ? initializeCard(cardConfig, region) - : { fullName: '', expirationDate: null, extensions: { [REGION_EXTENSION_NAME]: region.id } } + : { fullName: '', expirationDate: null, extensions: region ? { [REGION_EXTENSION_NAME]: region.id } : {} } const extensions = headers.reduce((acc, header, index) => { const value = line[index] const extension = Extensions.find(extension => extension.name === getExtensionNameByCSVHeader(cardConfig, header)) From db61b2334048313d47a5aaf3ce8bbfd1adae7e9b Mon Sep 17 00:00:00 2001 From: seluianova Date: Sat, 23 Nov 2024 12:45:20 +0100 Subject: [PATCH 7/8] 1430: Draft --- .../self-service/hooks/useCardGeneratorSelfService.tsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx index 1bf37275b..62ec7c53d 100644 --- a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx +++ b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx @@ -37,10 +37,11 @@ type UseCardGeneratorSelfServiceReturn = { const useCardGeneratorSelfService = (): UseCardGeneratorSelfServiceReturn => { const projectConfig = useContext(ProjectConfigContext) const appToaster = useAppToaster() - const [cardQueryParams, setSearchParams] = useSearchParams() + const [searchParams, setSearchParams] = useSearchParams() const [selfServiceCard, setSelfServiceCard] = useState(() => { const headers = getHeaders(projectConfig) - const values = headers.map(header => cardQueryParams.get(header)) + const values = headers.map(header => searchParams.get(header)) + setSearchParams(undefined, { replace: true }) return initializeCardFromCSV(projectConfig.card, values, headers, undefined, true) }) const [isLoading, setIsLoading] = useState(false) @@ -48,10 +49,6 @@ const useCardGeneratorSelfService = (): UseCardGeneratorSelfServiceReturn => { const [deepLink, setDeepLink] = useState('') const [code, setCode] = useState(null) - useEffect(() => { - setSearchParams(undefined, { replace: true }) - }, [setSearchParams]) - const [createCardsSelfService] = useCreateCardsFromSelfServiceMutation() const handleErrors = useCallback( From 0dbdae929f0acfc6302c949a0624d3947611fc77 Mon Sep 17 00:00:00 2001 From: seluianova Date: Mon, 25 Nov 2024 11:01:26 +0100 Subject: [PATCH 8/8] 1430: Remove card creation params only after the form submission --- .../src/bp-modules/self-service/CardSelfServiceForm.tsx | 3 +++ .../self-service/hooks/useCardGeneratorSelfService.tsx | 6 ++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/administration/src/bp-modules/self-service/CardSelfServiceForm.tsx b/administration/src/bp-modules/self-service/CardSelfServiceForm.tsx index 400c8a0e8..874314a42 100644 --- a/administration/src/bp-modules/self-service/CardSelfServiceForm.tsx +++ b/administration/src/bp-modules/self-service/CardSelfServiceForm.tsx @@ -2,6 +2,7 @@ import { Checkbox, FormGroup, InputGroup, Intent } from '@blueprintjs/core' import InfoOutlined from '@mui/icons-material/InfoOutlined' import { styled } from '@mui/material' import React, { ReactElement, useContext, useState } from 'react' +import { useSearchParams } from 'react-router-dom' import { Card, getFullNameValidationErrorMessage, isFullNameValid, isValid } from '../../cards/Card' import ClearInputButton from '../../cards/extensions/components/ClearInputButton' @@ -48,6 +49,7 @@ const CardSelfServiceForm = ({ const [touchedFullName, setTouchedFullName] = useState(false) const [openDataPrivacy, setOpenDataPrivacy] = useState(false) const [openReferenceInformation, setOpenReferenceInformation] = useState(false) + const [_, setSearchParams] = useSearchParams() const cardValid = isValid(card, { expirationDateNullable: true }) const appToaster = useAppToaster() const showErrorMessage = touchedFullName || formSendAttempt @@ -68,6 +70,7 @@ const CardSelfServiceForm = ({ return } await generateCards() + setSearchParams(undefined, { replace: true }) } return ( diff --git a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx index 62ec7c53d..9916ea13f 100644 --- a/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx +++ b/administration/src/bp-modules/self-service/hooks/useCardGeneratorSelfService.tsx @@ -1,5 +1,5 @@ import { ApolloError } from '@apollo/client' -import React, { useCallback, useContext, useEffect, useState } from 'react' +import React, { useCallback, useContext, useState } from 'react' import { useSearchParams } from 'react-router-dom' import { Card, generateCardInfo, initializeCardFromCSV } from '../../../cards/Card' @@ -37,18 +37,16 @@ type UseCardGeneratorSelfServiceReturn = { const useCardGeneratorSelfService = (): UseCardGeneratorSelfServiceReturn => { const projectConfig = useContext(ProjectConfigContext) const appToaster = useAppToaster() - const [searchParams, setSearchParams] = useSearchParams() + const [searchParams] = useSearchParams() const [selfServiceCard, setSelfServiceCard] = useState(() => { const headers = getHeaders(projectConfig) const values = headers.map(header => searchParams.get(header)) - setSearchParams(undefined, { replace: true }) return initializeCardFromCSV(projectConfig.card, values, headers, undefined, true) }) const [isLoading, setIsLoading] = useState(false) const [selfServiceState, setSelfServiceState] = useState(CardSelfServiceStep.form) const [deepLink, setDeepLink] = useState('') const [code, setCode] = useState(null) - const [createCardsSelfService] = useCreateCardsFromSelfServiceMutation() const handleErrors = useCallback(