diff --git a/apps/backend/pom.xml b/apps/backend/pom.xml index f9cd19934..62918fe3f 100644 --- a/apps/backend/pom.xml +++ b/apps/backend/pom.xml @@ -31,15 +31,15 @@ 1.14.0 - 1.24.0 + 1.25.0 2.15.0 32.1.3-jre 5.13.0 - 24.0.1 + 24.1.0 4.2.2 - 1.19.1 + 1.19.2 2.27.2 11.4.9 diff --git a/apps/backend/src/main/java/no/nav/data/etterlevelse/graphql/resolver/EtterlevelseDokumentasjonFieldResolver.java b/apps/backend/src/main/java/no/nav/data/etterlevelse/graphql/resolver/EtterlevelseDokumentasjonFieldResolver.java index 3cb8d1a4b..bf7b7a2be 100644 --- a/apps/backend/src/main/java/no/nav/data/etterlevelse/graphql/resolver/EtterlevelseDokumentasjonFieldResolver.java +++ b/apps/backend/src/main/java/no/nav/data/etterlevelse/graphql/resolver/EtterlevelseDokumentasjonFieldResolver.java @@ -90,15 +90,11 @@ public EtterlevelseDokumentasjonStats stats(EtterlevelseDokumentasjonResponse et } }); - var fylt = filter(krav, k -> etterlevelser.stream().anyMatch(e -> e.isEtterleves() && e.kravId().equals(k.kravId()))); var ikkeFylt = filter(krav, k -> !fylt.contains(k)); var irrelevant = filter(irrelevantKrav, i -> !fylt.contains(i) && !ikkeFylt.contains(i)); - //filtering for only newest version for utgaatt krav - - return EtterlevelseDokumentasjonStats.builder() .fyltKrav(fylt) .ikkeFyltKrav(ikkeFylt) diff --git a/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/KravPrioriteringController.java b/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/KravPrioriteringController.java index 21cc6ec61..b249c2e10 100644 --- a/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/KravPrioriteringController.java +++ b/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/KravPrioriteringController.java @@ -11,7 +11,9 @@ import no.nav.data.common.rest.RestResponsePage; import no.nav.data.etterlevelse.codelist.CodelistService; import no.nav.data.etterlevelse.codelist.domain.ListName; +import no.nav.data.etterlevelse.krav.domain.KravStatus; import no.nav.data.etterlevelse.kravprioritering.domain.KravPrioritering; +import no.nav.data.etterlevelse.kravprioritering.dto.KravPrioriteringFilter; import no.nav.data.etterlevelse.kravprioritering.dto.KravPrioriteringRequest; import no.nav.data.etterlevelse.kravprioritering.dto.KravPrioriteringResponse; import org.springframework.data.domain.Page; @@ -24,6 +26,7 @@ import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.List; @@ -80,6 +83,28 @@ public ResponseEntity> getByTemaCode( return ResponseEntity.ok(new RestResponsePage<>(kravPrioriteringList).convert(KravPrioritering::toResponse)); } + @Operation(summary = "Get krav prioritering by filter") + @ApiResponse(description = "ok") + @GetMapping("/filter") + public ResponseEntity> getByFilter( + @RequestParam(name="id",required = false) String id, + @RequestParam(name="kravNummer",required = false) Integer kravNummer, + @RequestParam(name="temaCode",required = false) String temaCode, + @RequestParam(name="kravStatus",required = false) KravStatus kravStatus + ) { + KravPrioriteringFilter filter = KravPrioriteringFilter.builder() + .id(id) + .kravNummer(kravNummer) + .temaCode(temaCode) + .kravStatus(kravStatus) + .build(); + log.info("Get krav prioritering with filter={}", filter); + if(filter.getTemaCode() != null) { + codelistService.validateListNameAndCode(ListName.TEMA.name(), filter.getTemaCode()); + } + return ResponseEntity.ok(new RestResponsePage<>(service.getByFilter(filter))); + } + @Operation(summary = "Get one krav prioritering") @ApiResponse(description = "ok") @GetMapping("/{id}") diff --git a/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/KravPrioriteringService.java b/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/KravPrioriteringService.java index a63fd971e..4dc64fe1f 100644 --- a/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/KravPrioriteringService.java +++ b/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/KravPrioriteringService.java @@ -3,24 +3,33 @@ import no.nav.data.common.rest.PageParameters; import no.nav.data.common.storage.domain.GenericStorage; import no.nav.data.etterlevelse.common.domain.DomainService; +import no.nav.data.etterlevelse.krav.KravService; +import no.nav.data.etterlevelse.krav.domain.Krav; +import no.nav.data.etterlevelse.krav.domain.KravStatus; import no.nav.data.etterlevelse.kravprioritering.domain.KravPrioritering; import no.nav.data.etterlevelse.kravprioritering.domain.KravPrioriteringRepo; +import no.nav.data.etterlevelse.kravprioritering.dto.KravPrioriteringFilter; import no.nav.data.etterlevelse.kravprioritering.dto.KravPrioriteringRequest; +import no.nav.data.etterlevelse.kravprioritering.dto.KravPrioriteringResponse; +import org.apache.commons.lang3.StringUtils; import org.springframework.data.domain.Page; import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Optional; import java.util.UUID; @Service public class KravPrioriteringService extends DomainService { private final KravPrioriteringRepo repo; + private final KravService kravService; - public KravPrioriteringService(KravPrioriteringRepo repo) { + public KravPrioriteringService(KravPrioriteringRepo repo, KravService kravService) { super(KravPrioritering.class); this.repo = repo; + this.kravService = kravService; } public Page getAll(PageParameters pageParameters) { @@ -42,6 +51,47 @@ public List getByTema(String tema) { return GenericStorage.to(repo.findByTema(tema.substring(0, 3)), KravPrioritering.class); } + public List getByFilter(KravPrioriteringFilter filter) { + if (!StringUtils.isBlank(filter.getId())) { + KravPrioritering kravPrioritering = storage.get(UUID.fromString(filter.getId()), KravPrioritering.class); + if (kravPrioritering != null) { + KravPrioriteringResponse kravPrioriteringResponse = kravPrioritering.toResponse(); + setKravStatus(kravPrioriteringResponse); + return List.of(kravPrioriteringResponse); + } + return List.of(); + } else if (filter.getKravNummer() != null) { + List kravPrioriteringList = GenericStorage.to(repo.findByKravNummer(filter.getKravNummer()), KravPrioritering.class).stream().map(KravPrioritering::toResponse).toList(); + kravPrioriteringList.forEach(this::setKravStatus); + return filterForKravStatus(kravPrioriteringList, filter); + } else if(filter.getTemaCode() != null) { + List kravPrioriteringerResp = GenericStorage.to(repo.findByTema(filter.getTemaCode().substring(0, 3)), KravPrioritering.class).stream().map(KravPrioritering::toResponse).toList(); + kravPrioriteringerResp.forEach(this::setKravStatus); + return filterForKravStatus(kravPrioriteringerResp, filter); + } + + List kravPrioriteringer = GenericStorage.to(repo.getAll(),KravPrioritering.class).stream().map(KravPrioritering::toResponse).toList(); + kravPrioriteringer.forEach(this::setKravStatus); + + return filterForKravStatus(kravPrioriteringer, filter); + } + + private List filterForKravStatus(List kravPrioriteringResponse, KravPrioriteringFilter filter) { + if(filter.getKravStatus() != null) { + return kravPrioriteringResponse.stream().filter(kp-> kp.getKravStatus().equals(filter.getKravStatus())).toList(); + } + return kravPrioriteringResponse; + } + + private void setKravStatus(KravPrioriteringResponse kravPrioriteringResponse) { + Optional krav = kravService.getByKravNummer(kravPrioriteringResponse.getKravNummer(), kravPrioriteringResponse.getKravVersjon()); + if(krav.isPresent()) { + kravPrioriteringResponse.setKravStatus(krav.get().getStatus()); + } else { + kravPrioriteringResponse.setKravStatus(KravStatus.UTGAATT); + } + } + public KravPrioritering save(KravPrioriteringRequest request) { var kravprioritering = request.isUpdate() ? storage.get(request.getIdAsUUID(), KravPrioritering.class) : new KravPrioritering(); diff --git a/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/domain/KravPrioriteringRepo.java b/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/domain/KravPrioriteringRepo.java index 163899349..3c2e76a8e 100644 --- a/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/domain/KravPrioriteringRepo.java +++ b/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/domain/KravPrioriteringRepo.java @@ -28,6 +28,9 @@ public interface KravPrioriteringRepo extends JpaRepository findByTema(String tema); + @Query(value = "select * from generic_storage where type = 'KravPrioritering'", nativeQuery = true) + List getAll(); + @Modifying(clearAutomatically = true) @Transactional @Query(value = "update generic_storage set DATA = jsonb_set(DATA, '{kravVersjon}', to_jsonb(?1) , false ) where data -> 'kravNummer' = to_jsonb(?2) and type = 'KravPrioritering'", nativeQuery = true) diff --git a/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/dto/KravPrioriteringFilter.java b/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/dto/KravPrioriteringFilter.java new file mode 100644 index 000000000..561d90e6b --- /dev/null +++ b/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/dto/KravPrioriteringFilter.java @@ -0,0 +1,39 @@ +package no.nav.data.etterlevelse.kravprioritering.dto; + +import graphql.schema.DataFetchingEnvironment; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.FieldNameConstants; +import no.nav.data.etterlevelse.krav.domain.KravStatus; +import org.apache.commons.lang3.StringUtils; + +import java.util.Map; + +import static no.nav.data.etterlevelse.graphql.support.GraphQlResolverUtil.getFilter; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@FieldNameConstants +public class KravPrioriteringFilter { + + private String id; + private Integer kravNummer; + private String temaCode; + private KravStatus kravStatus; + + public boolean isEmpty() { + return StringUtils.isBlank(id) + && kravNummer == null + && kravStatus == null + && temaCode == null; + } + + public static T get(DataFetchingEnvironment env, String field) { + Map vars = getFilter(env.getExecutionStepInfo()); + return vars.get(field); + } +} \ No newline at end of file diff --git a/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/dto/KravPrioriteringResponse.java b/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/dto/KravPrioriteringResponse.java index 359cf60ad..08ce38855 100644 --- a/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/dto/KravPrioriteringResponse.java +++ b/apps/backend/src/main/java/no/nav/data/etterlevelse/kravprioritering/dto/KravPrioriteringResponse.java @@ -6,6 +6,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import no.nav.data.common.rest.ChangeStampResponse; +import no.nav.data.etterlevelse.krav.domain.KravStatus; import java.util.UUID; @@ -22,4 +23,6 @@ public class KravPrioriteringResponse { private Integer kravVersjon; private String prioriteringsId; + private KravStatus kravStatus; + } diff --git a/apps/frontend/readme.md b/apps/frontend/readme.md index 76248493a..9d665658b 100644 --- a/apps/frontend/readme.md +++ b/apps/frontend/readme.md @@ -3,9 +3,68 @@ ### Requires node 17 ### Install deps + `yarn install` +### Login with Google Cloud with @nav.no user + +Do this in Google Chrome as it doesn't work in Firefox on Mac + +`gcloud auth login` + +Remember to flush sockets when you can't login + +`chrome://net-internals/#sockets` + ### Run local, with port forward to dev-gcp + `kubectl port-forward deployment/etterlevelse-backend` -`yarn run start` \ No newline at end of file +`yarn run start` + +## Other + +### To use Yarn you need to + +1. `brew install yarn` +2. `brew install node` + +## Common errors + +### + +#### Kubernetes error + +``` +frontend git:(master) ✗ kubectl port-forward deployment/etterlevelse-backend +error: TYPE/NAME and list of ports are required for port-forward +See 'kubectl port-forward -h' for help and examples +``` + +1. You need to add config (see below) in `.zshrc`. +2. Run `gcloud auth login` +3. Run `kpfe` +4. Then run in separate window `yarn run start` +5. Go to `http://localhost:3000/` +6. Done! + +##### `.bashrc` or `.zshrc` config + +``` +# etterlevelse-back end proxy connection +kpfe() { + while true; do + kubectl port-forward deployment/etterlevelse-backend 8080 --namespace teamdatajegerne; + done +} + +# behandlingskatalog-backend proxy connection +kpfb() { + while true; do + kubectl port-forward deployment/behandlingskatalog-backend 8080 --namespace teamdatajegerne; + done +} + +# logge inn i gcloud for å ha tilgang til gcp clusters +alias gli="gcloud auth login" +``` diff --git a/apps/frontend/src/api/KravApi.ts b/apps/frontend/src/api/KravApi.ts index 851b3a9ea..3ca190d0b 100644 --- a/apps/frontend/src/api/KravApi.ts +++ b/apps/frontend/src/api/KravApi.ts @@ -200,6 +200,7 @@ export const kravMapToFormVal = (krav: Partial): KravQL => ({ etterlevelser: [], kravIdRelasjoner: [], aktivertDato: krav.aktivertDato || '', + prioriteringsId: '' }) export const kravFullQuery = gql` @@ -301,6 +302,7 @@ export const etterlevelseDokumentasjonKravQuery = gql` status aktivertDato kravIdRelasjoner + prioriteringsId kravRelasjoner { id kravNummer @@ -341,6 +343,38 @@ export const etterlevelseDokumentasjonKravQuery = gql` } ` +export const KravMedPrioriteringOgEtterlevelseQuery = gql` + query getKravByFilter($etterlevelseDokumentasjonId: String, $lover: [String!], $gjeldendeKrav: Boolean, $etterlevelseDokumentasjonIrrevantKrav: Boolean, $status: [String!]) { + krav( + filter: { + etterlevelseDokumentasjonId: $etterlevelseDokumentasjonId + lover: $lover + gjeldendeKrav: $gjeldendeKrav + etterlevelseDokumentasjonIrrevantKrav: $etterlevelseDokumentasjonIrrevantKrav + status: $status + } + ) { + content { + navn + kravNummer + kravVersjon + status + prioriteringsId + etterlevelser(onlyForEtterlevelseDokumentasjon: true) { + id + etterleves + fristForFerdigstillelse + status + changeStamp { + lastModifiedBy + lastModifiedDate + } + } + } + } + } +` + export const statsQuery = gql` query getBehandlingStats($behandlingId: ID) { behandling(filter: { id: $behandlingId }) { diff --git a/apps/frontend/src/api/KravPriorityApi.ts b/apps/frontend/src/api/KravPriorityApi.ts index c73978c8d..15721652c 100644 --- a/apps/frontend/src/api/KravPriorityApi.ts +++ b/apps/frontend/src/api/KravPriorityApi.ts @@ -35,6 +35,17 @@ export const getKravPriorityByKravNumberAndVersion = async (kravNummer: number | }) } +export const getKravPriorityByTemaCode = async (temaCode: string) => { + return await axios + .get(`${env.backendBaseUrl}/kravprioritering/tema/${temaCode}`) + .then((resp) => { + return resp.data + }) + .catch(() => { + return undefined + }) +} + export const getKravPriorityByKravNummer = async (kravNummer: number | string) => { return (await axios.get>(`${env.backendBaseUrl}/kravprioritering/kravnummer/${kravNummer}`)).data } diff --git a/apps/frontend/src/constants.ts b/apps/frontend/src/constants.ts index e699f4663..a90b685e8 100644 --- a/apps/frontend/src/constants.ts +++ b/apps/frontend/src/constants.ts @@ -410,6 +410,7 @@ export type KravQL = Replace< begreper: Begrep[] virkemidler: Virkemiddel[] kravRelasjoner: Krav[] + prioriteringsId: string } > diff --git a/apps/frontend/src/pages/EtterlevelseDokumentasjonPage.tsx b/apps/frontend/src/pages/EtterlevelseDokumentasjonPage.tsx index 1966a2019..7efe471fd 100644 --- a/apps/frontend/src/pages/EtterlevelseDokumentasjonPage.tsx +++ b/apps/frontend/src/pages/EtterlevelseDokumentasjonPage.tsx @@ -4,14 +4,15 @@ import { useParams } from 'react-router-dom' import { ettlevColors } from '../util/theme' import { codelist, ListName, TemaCode } from '../services/Codelist' import { Layout2 } from '../components/scaffold/Page' -import { KravId } from '../api/KravApi' +import { KravId, KravMedPrioriteringOgEtterlevelseQuery } from '../api/KravApi' import { breadcrumbPaths } from '../components/common/CustomizedBreadcrumbs' import { Helmet } from 'react-helmet' import { ampli } from '../services/Amplitude' -import { KRAV_FILTER_TYPE } from '../constants' +import { KRAV_FILTER_TYPE, KravQL, KravStatus, PageResponse } from '../constants' import { useEtterlevelseDokumentasjon } from '../api/EtterlevelseDokumentasjonApi' import { getMainHeader } from '../components/etterlevelseDokumentasjon/common/utils' import { KravView } from '../components/etterlevelseDokumentasjonTema/KravView' +import { useQuery } from '@apollo/client' export type Section = 'dokumentasjon' | 'etterlevelser' | 'tilbakemeldinger' @@ -29,6 +30,30 @@ export const EtterlevelseDokumentasjonPage = () => { const params = useParams<{ id: string; tema: string; kravNummer: string; kravVersjon: string; filter: string }>() const temaData: TemaCode | undefined = codelist.getCode(ListName.TEMA, params.tema?.replace('i', '')) const [etterlevelseDokumentasjon] = useEtterlevelseDokumentasjon(params.id) + const lover = codelist.getCodesForTema(params.tema) + + + //CODE FOR GETTING KRAV LIST WITH PRIORTY + const { data, loading } = useQuery<{ krav: PageResponse }>(KravMedPrioriteringOgEtterlevelseQuery, { + variables: { + etterlevelseDokumentasjonId: params.id, + lover: lover.map((l) => l.code), + status: KravStatus.AKTIV + }, + skip: !params.tema || !params.id, + fetchPolicy: 'no-cache', + }) + + // CODE FOR SORTING WITH PRIORITY + // console.log(data?.krav.content.sort((a, b) => { + // if (a.prioriteringsId === '') { + // return 1 + // } else if (b.prioriteringsId === '') { + // return -1 + // } else { + // return a.prioriteringsId.localeCompare(b.prioriteringsId) + // } + // })) const [kravId, setKravId] = useState()