From 113a4e50d288651cb80c132c7b6d5e419841c662 Mon Sep 17 00:00:00 2001 From: Tomi Korkalainen <77731851+tkork@users.noreply.github.com> Date: Tue, 14 Jun 2022 12:46:02 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20Lis=C3=A4=C3=A4=20oma=20virheilmoitus=20?= =?UTF-8?q?virheelliselle=20vastuuhenkil=C3=B6s=C3=A4hk=C3=B6postille=20(#?= =?UTF-8?q?268)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: Lisää oma virheilmoitus virheelliselle vastuuhenkilösähköpostille * korjaa case importista --- backend/src/handler/kayttoOikeudetManager.ts | 8 ++--- backend/src/handler/projektiAdapter.ts | 3 +- backend/src/handler/projektiHandler.ts | 26 +++++++++++--- graphql/types.graphql | 15 ++++++++ .../projekti/KayttoOikeusHallinta.tsx | 4 --- .../projekti/ProjektiErrorNotification.tsx | 35 +++++++++++++------ src/pages/yllapito/perusta/[oid].tsx | 24 ++++++++----- src/schemas/projekti.ts | 12 ++++--- src/services/api/commonApi.ts | 5 +-- src/services/api/fragmentTypes.json | 18 ++++++++++ 10 files changed, 111 insertions(+), 39 deletions(-) diff --git a/backend/src/handler/kayttoOikeudetManager.ts b/backend/src/handler/kayttoOikeudetManager.ts index 213b61fc3..8b04d10a9 100644 --- a/backend/src/handler/kayttoOikeudetManager.ts +++ b/backend/src/handler/kayttoOikeudetManager.ts @@ -73,7 +73,7 @@ export class KayttoOikeudetManager { this.users = resultUsers; } - getKayttoOikeudet() : DBVaylaUser[]{ + getKayttoOikeudet(): DBVaylaUser[] { return this.users; } @@ -84,11 +84,11 @@ export class KayttoOikeudetManager { })); } - addProjektiPaallikkoFromEmail(vastuuhenkiloEmail: string) : DBVaylaUser|undefined{ + addProjektiPaallikkoFromEmail(vastuuhenkiloEmail: string): DBVaylaUser | undefined { return this.resolveProjektiPaallikkoFromVelhoVastuuhenkilo(vastuuhenkiloEmail); } - resolveProjektiPaallikkoFromVelhoVastuuhenkilo(vastuuhenkiloEmail: string): DBVaylaUser|undefined { + resolveProjektiPaallikkoFromVelhoVastuuhenkilo(vastuuhenkiloEmail: string): DBVaylaUser | undefined { // Replace or create new projektipaallikko this.removeProjektiPaallikko(); const projektiPaallikko = this.fillInUserInfoFromUserManagement({ @@ -105,7 +105,7 @@ export class KayttoOikeudetManager { } } - addUserByKayttajatunnus(kayttajatunnus: string, rooli: ProjektiRooli) : DBVaylaUser | undefined{ + addUserByKayttajatunnus(kayttajatunnus: string, rooli: ProjektiRooli): DBVaylaUser | undefined { const user = this.fillInUserInfoFromUserManagement({ user: { kayttajatunnus, rooli } as Partial, searchMode: SearchMode.UID, diff --git a/backend/src/handler/projektiAdapter.ts b/backend/src/handler/projektiAdapter.ts index ca39f4fd7..a41852a24 100644 --- a/backend/src/handler/projektiAdapter.ts +++ b/backend/src/handler/projektiAdapter.ts @@ -42,7 +42,7 @@ export type ProjektiAdaptationResult = { }; export class ProjektiAdapter { - public adaptProjekti(dbProjekti: DBProjekti): API.Projekti { + public adaptProjekti(dbProjekti: DBProjekti, virhetiedot?: API.ProjektiVirhe): API.Projekti { const { kayttoOikeudet, aloitusKuulutus, @@ -74,6 +74,7 @@ export class ProjektiAdapter { kielitiedot: adaptKielitiedot(kielitiedot), suunnitteluVaihe: adaptSuunnitteluVaihe(suunnitteluVaihe, vuorovaikutukset, palautteet), nahtavillaoloVaihe: adaptNahtavillaoloVaihe(nahtavillaoloVaihe), + virhetiedot, ...fieldsToCopyAsIs, }) as API.Projekti; if (apiProjekti.tallennettu) { diff --git a/backend/src/handler/projektiHandler.ts b/backend/src/handler/projektiHandler.ts index 677521bcb..b87a7cc1e 100644 --- a/backend/src/handler/projektiHandler.ts +++ b/backend/src/handler/projektiHandler.ts @@ -50,8 +50,13 @@ async function loadProjektiYllapito(oid: string, vaylaUser: NykyinenKayttaja): P return projektiAdapter.adaptProjekti(projektiFromDB); } else { requirePermissionLuonti(); - const projekti = await createProjektiFromVelho(oid, vaylaUser); - return projektiAdapter.adaptProjekti(projekti); + const { projekti, virhetiedot: projektipaallikkoVirhetieto } = await createProjektiFromVelho(oid, vaylaUser); + let virhetiedot: API.ProjektiVirhe | undefined; + if (projektipaallikkoVirhetieto) { + virhetiedot = { __typename: "ProjektiVirhe", projektipaallikko: projektipaallikkoVirhetieto }; + } + + return projektiAdapter.adaptProjekti(projekti, virhetiedot); } } @@ -87,7 +92,7 @@ export async function createOrUpdateProjekti(input: TallennaProjektiInput): Prom await vuorovaikutusService.handleAineistot(projektiAdaptationResult); } else { requirePermissionLuonti(); - const projekti = await createProjektiFromVelho(input.oid, requireVaylaUser(), input); + const { projekti } = await createProjektiFromVelho(input.oid, requireVaylaUser(), input); log.info("Creating projekti to Hassu", { oid }); await projektiDatabase.createProjekti(projekti); log.info("Created projekti to Hassu", { projekti }); @@ -106,10 +111,11 @@ export async function createProjektiFromVelho( oid: string, vaylaUser: NykyinenKayttaja, input?: TallennaProjektiInput -): Promise { +): Promise<{ projekti: DBProjekti; virhetiedot?: API.ProjektipaallikkoVirhe }> { try { log.info("Loading projekti from Velho", { oid }); const { projekti, vastuuhenkilo } = await velho.loadProjekti(oid); + const result: { projekti: DBProjekti; virhetiedot?: API.ProjektipaallikkoVirhe } = { projekti }; const kayttoOikeudet = new KayttoOikeudetManager([], await personSearch.getKayttajas()); @@ -123,6 +129,16 @@ export async function createProjektiFromVelho( // Loading a projekti from Velho for a first time const projektiPaallikko = kayttoOikeudet.addProjektiPaallikkoFromEmail(vastuuhenkilo); + if (!vastuuhenkilo) { + result.virhetiedot = { __typename: "ProjektipaallikkoVirhe", tyyppi: API.ProjektiPaallikkoVirheTyyppi.PUUTTUU }; + } else if (!projektiPaallikko) { + result.virhetiedot = { + __typename: "ProjektipaallikkoVirhe", + tyyppi: API.ProjektiPaallikkoVirheTyyppi.EI_LOYDY, + sahkoposti: vastuuhenkilo, + }; + } + // Prefill current user as sihteeri if it is different from project manager if ((!projektiPaallikko || projektiPaallikko.kayttajatunnus !== vaylaUser.uid) && vaylaUser.uid) { kayttoOikeudet.addUserByKayttajatunnus(vaylaUser.uid, ProjektiRooli.OMISTAJA); @@ -130,7 +146,7 @@ export async function createProjektiFromVelho( } projekti.kayttoOikeudet = kayttoOikeudet.getKayttoOikeudet(); - return projekti; + return result; } catch (e) { log.error(e); throw e; diff --git a/graphql/types.graphql b/graphql/types.graphql index 5f913db4e..fa2957851 100644 --- a/graphql/types.graphql +++ b/graphql/types.graphql @@ -63,6 +63,20 @@ interface IProjekti { paivitetty: String } +enum ProjektiPaallikkoVirheTyyppi { + PUUTTUU + EI_LOYDY +} + +type ProjektipaallikkoVirhe { + tyyppi: ProjektiPaallikkoVirheTyyppi! + sahkoposti: String +} + +type ProjektiVirhe { + projektipaallikko: ProjektipaallikkoVirhe +} + type Projekti implements IProjekti { oid: String! muistiinpano: String @@ -85,6 +99,7 @@ type Projekti implements IProjekti { liittyvatSuunnitelmat: [Suunnitelma!] kielitiedot: Kielitiedot paivitetty: String + virhetiedot: ProjektiVirhe } type SuunnitteluVaihe { diff --git a/src/components/projekti/KayttoOikeusHallinta.tsx b/src/components/projekti/KayttoOikeusHallinta.tsx index e1d75bc11..d0e17e3ea 100644 --- a/src/components/projekti/KayttoOikeusHallinta.tsx +++ b/src/components/projekti/KayttoOikeusHallinta.tsx @@ -193,10 +193,6 @@ const UserFields = ({ [getKayttajaNimi, disableFields, minSearchLength, kayttaja] ); - if (!kayttaja || isLoadingKayttajat) { - return <>; - } - return ( diff --git a/src/components/projekti/ProjektiErrorNotification.tsx b/src/components/projekti/ProjektiErrorNotification.tsx index 621894657..5d15e9e4e 100644 --- a/src/components/projekti/ProjektiErrorNotification.tsx +++ b/src/components/projekti/ProjektiErrorNotification.tsx @@ -1,5 +1,5 @@ import React, { ReactElement, ReactNode, useState } from "react"; -import { Projekti } from "../../../common/graphql/apiModel"; +import { Projekti, ProjektiPaallikkoVirheTyyppi } from "../../../common/graphql/apiModel"; import Notification, { NotificationType } from "@components/notification/Notification"; import { ProjektiSchema, ProjektiTestType } from "src/schemas/projekti"; import { ValidationError } from "yup"; @@ -21,17 +21,32 @@ type ErrorNotificationFunction = (projekti?: Projekti | null) => ErrorNotificati const projektiErrorToNotificationMap = new Map([ [ ProjektiTestType.PROJEKTI_IS_LOADED, - () => "Projektin tietoja hakiessa tapahtui virhe. Tarkista tiedot velhosta ja yritä myöhemmin uudelleen.", + () => "Projektin tietoja hakiessa tapahtui virhe. Tarkista tiedot Projektivelhosta ja yritä myöhemmin uudelleen.", ], [ ProjektiTestType.PROJEKTI_HAS_PAALLIKKO, - (projekti) => ( -

- Projektilta puuttuu projektipäällikkö- / vastuuhenkilötieto projektivelhosta. Lisää vastuuhenkilötieto - projektivelhossa ja yritä projektin perustamista uudelleen. - Projektin sivu Projektivelhossa -

- ), + (projekti) => { + const virhetieto = projekti?.virhetiedot?.projektipaallikko; + let message = ( +

+ Projektilta puuttuu projektipäällikkö- / vastuuhenkilötieto projektivelhosta. Lisää vastuuhenkilötieto + projektivelhossa ja yritä projektin perustamista uudelleen. + Projektin sivu Projektivelhossa +

+ ); + if (virhetieto?.tyyppi === ProjektiPaallikkoVirheTyyppi.EI_LOYDY) { + message = ( +

+ {`Projektille asetettua vastuuhenkilön sähköpostia '${ + virhetieto.sahkoposti || "" + }' ei löydy käyttäjähallinnasta tai kyseinen käyttäjä ei täytä projektipäällikön edellytyksiä. `} + {"Korjaa vastuuhenkilötieto Projektivelhossa ja yritä projektin perustamista uudelleen."} + Projektin sivu Projektivelhossa +

+ ); + } + return message; + }, ], [ ProjektiTestType.PROJEKTI_IS_CREATED, @@ -73,7 +88,7 @@ export default function ProjektiErrorNotification({ } setNotificationMessage(null); } catch (err) { - let message: ErrorNotification; + let message: ErrorNotification = null; if (err instanceof ValidationError && Object.values(ProjektiTestType).includes(err.type as ProjektiTestType)) { message = projektiErrorToNotificationMap.get(err.type as ProjektiTestType)?.(projekti); } diff --git a/src/pages/yllapito/perusta/[oid].tsx b/src/pages/yllapito/perusta/[oid].tsx index ead240570..9d278dbdc 100644 --- a/src/pages/yllapito/perusta/[oid].tsx +++ b/src/pages/yllapito/perusta/[oid].tsx @@ -105,9 +105,12 @@ export default function PerustaProjekti({ setRouteLabels }: PageProps): ReactEle } }, [projekti, reset]); - const onKayttajatUpdate = useCallback((kayttajat : Kayttaja[]) => { - setFormContext({ kayttajat }); - }, [setFormContext]); + const onKayttajatUpdate = useCallback( + (kayttajat: Kayttaja[]) => { + setFormContext({ kayttajat }); + }, + [setFormContext] + ); return (
@@ -124,16 +127,19 @@ export default function PerustaProjekti({ setRouteLabels }: PageProps): ReactEle />
- +
Takaisin -
); } diff --git a/src/schemas/projekti.ts b/src/schemas/projekti.ts index dcf76169b..6a04990ef 100644 --- a/src/schemas/projekti.ts +++ b/src/schemas/projekti.ts @@ -28,7 +28,11 @@ const projektiTestMap = new Map([ [ ProjektiTestType.PROJEKTI_IS_LOADED, (objectSchema) => - objectSchema.test(ProjektiTestType.PROJEKTI_IS_LOADED, "Projekti ei latautunut oikein", (projekti) => !!projekti), + objectSchema.test( + ProjektiTestType.PROJEKTI_IS_LOADED, + "Projekti ei latautunut oikein", + (projekti) => !!projekti?.oid + ), ], [ ProjektiTestType.PROJEKTI_HAS_PAALLIKKO, @@ -37,7 +41,7 @@ const projektiTestMap = new Map([ ProjektiTestType.PROJEKTI_HAS_PAALLIKKO, "Projektille ei ole asetettu projektipäällikköä", (projekti) => - !projekti || !!projekti?.kayttoOikeudet?.some(({ rooli }) => rooli === ProjektiRooli.PROJEKTIPAALLIKKO) + !projekti?.oid || !!projekti?.kayttoOikeudet?.some(({ rooli }) => rooli === ProjektiRooli.PROJEKTIPAALLIKKO) ), ], [ @@ -46,7 +50,7 @@ const projektiTestMap = new Map([ objectSchema.test( ProjektiTestType.PROJEKTI_IS_CREATED, "Projektia ei ole perustettu", - (projekti) => !projekti || !!projekti?.tallennettu + (projekti) => !projekti?.oid || !!projekti?.tallennettu ), ], [ @@ -55,7 +59,7 @@ const projektiTestMap = new Map([ objectSchema.test( ProjektiTestType.PROJEKTI_NOT_CREATED, "Projekti on jo perustettu", - (projekti) => !projekti || !projekti?.tallennettu + (projekti) => !projekti?.oid || !projekti?.tallennettu ), ], ]); diff --git a/src/services/api/commonApi.ts b/src/services/api/commonApi.ts index 3580cb774..0bf86a76d 100644 --- a/src/services/api/commonApi.ts +++ b/src/services/api/commonApi.ts @@ -100,11 +100,12 @@ export class API extends AbstractApi { errorPolicy: "all", fetchResults: true, }); - if (queryResponse.errors && !queryResponse.data) { + const data = queryResponse.data?.[operation.name]; + if (queryResponse.errors && !data) { log.warn(queryResponse.errors); throw new Error("API palautti virheen."); } - return queryResponse.data?.[operation.name]; + return data; case OperationType.Mutation: const fetchResponse: FetchResult = await client.mutate({ mutation: gql(operation.graphql), diff --git a/src/services/api/fragmentTypes.json b/src/services/api/fragmentTypes.json index ff344039c..e0851f61e 100644 --- a/src/services/api/fragmentTypes.json +++ b/src/services/api/fragmentTypes.json @@ -373,6 +373,18 @@ "possibleTypes": null, "__typename": "__Type" }, + { + "kind": "OBJECT", + "name": "ProjektipaallikkoVirhe", + "possibleTypes": null, + "__typename": "__Type" + }, + { + "kind": "ENUM", + "name": "ProjektiPaallikkoVirheTyyppi", + "possibleTypes": null, + "__typename": "__Type" + }, { "kind": "ENUM", "name": "ProjektiRooli", @@ -391,6 +403,12 @@ "possibleTypes": null, "__typename": "__Type" }, + { + "kind": "OBJECT", + "name": "ProjektiVirhe", + "possibleTypes": null, + "__typename": "__Type" + }, { "kind": "OBJECT", "name": "Query",