From efbdf77a33c52bd0539edb873c7c49e5cf5b3ef5 Mon Sep 17 00:00:00 2001 From: Martin Gunnerud Date: Wed, 18 Dec 2024 11:56:03 +0100 Subject: [PATCH] PR change requests --- .../policy-editor/src/PolicyEditor.tsx | 2 +- .../AllAccessPackages.tsx | 37 ++++++ .../ChosenAccessPackages.tsx | 51 ++++++++ .../PolicyAccessPackageAccordion.module.css | 2 +- .../PolicyAccessPackageAccordion.test.tsx | 5 +- .../PolicyAccessPackageAccordion.tsx | 116 ++---------------- .../PolicyAccessPackageAccordionCheckbox.tsx | 37 ++++++ .../PolicyAccessPackageAccordionContent.tsx | 34 +++++ .../PolicyAccessPackageServiceLogo.tsx | 24 ++++ .../PolicyAccessPackageServices.tsx | 32 +++++ .../PolicyAccessPackages.test.tsx | 20 +-- .../PolicyAccessPackages.tsx | 98 +++------------ .../PolicyAccordion/PolicyAccordion.tsx | 8 +- .../policyAccessPackageUtils.ts | 54 ++++++-- .../PolicyEditorContext.tsx | 9 +- frontend/packages/policy-editor/src/index.ts | 4 - .../packages/policy-editor/src/types/index.ts | 39 ------ frontend/packages/shared/src/api/queries.ts | 3 +- .../useResourceAccessPackageServicesQuery.ts | 2 +- .../queries/useResourceAccessPackagesQuery.ts | 2 +- .../shared/src/types/PolicyAccessPackages.ts | 40 ++++++ .../shared/src/types/ResourceLanguage.ts | 0 22 files changed, 350 insertions(+), 269 deletions(-) create mode 100644 frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/AllAccessPackages.tsx create mode 100644 frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/ChosenAccessPackages.tsx create mode 100644 frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordionCheckbox.tsx create mode 100644 frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordionContent.tsx create mode 100644 frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageServiceLogo.tsx create mode 100644 frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageServices.tsx create mode 100644 frontend/packages/shared/src/types/PolicyAccessPackages.ts delete mode 100644 frontend/packages/shared/src/types/ResourceLanguage.ts diff --git a/frontend/packages/policy-editor/src/PolicyEditor.tsx b/frontend/packages/policy-editor/src/PolicyEditor.tsx index f731281a23b..3fc3b40a646 100644 --- a/frontend/packages/policy-editor/src/PolicyEditor.tsx +++ b/frontend/packages/policy-editor/src/PolicyEditor.tsx @@ -8,7 +8,6 @@ import type { PolicySubject, RequiredAuthLevel, PolicyEditorUsage, - PolicyAccessPackageAreaGroup, } from './types'; import { mapPolicyRulesBackendObjectToPolicyRuleCard, @@ -21,6 +20,7 @@ import { useTranslation } from 'react-i18next'; import { SecurityLevelSelect } from './components/SecurityLevelSelect'; import { PolicyEditorContextProvider } from './contexts/PolicyEditorContext'; import { PolicyCardRules } from './components/PolicyCardRules'; +import type { PolicyAccessPackageAreaGroup } from 'app-shared/types/PolicyAccessPackages'; export type PolicyEditorProps = { policy: Policy; diff --git a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/AllAccessPackages.tsx b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/AllAccessPackages.tsx new file mode 100644 index 00000000000..c6f802e00e3 --- /dev/null +++ b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/AllAccessPackages.tsx @@ -0,0 +1,37 @@ +import React, { type ReactElement } from 'react'; +import { PolicyAccessPackageAccordion } from './PolicyAccessPackageAccordion'; +import { PolicyAccordion } from './PolicyAccordion'; +import { isAccessPackageSelected } from './policyAccessPackageUtils'; +import type { PolicyAccessPackageArea } from 'app-shared/types/PolicyAccessPackages'; + +type AllAccessPackagesProps = { + chosenAccessPackages: string[]; + accessPackagesToRender: PolicyAccessPackageArea[]; + searchValue: string; + handleSelectAccessPackage: (accessPackageUrn: string) => void; +}; +export const AllAccessPackages = ({ + chosenAccessPackages, + accessPackagesToRender, + searchValue, + handleSelectAccessPackage, +}: AllAccessPackagesProps): ReactElement[] => { + return accessPackagesToRender.map((area) => ( + + {area.packages.map((accessPackage) => ( + + ))} + + )); +}; diff --git a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/ChosenAccessPackages.tsx b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/ChosenAccessPackages.tsx new file mode 100644 index 00000000000..6d14deb0a48 --- /dev/null +++ b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/ChosenAccessPackages.tsx @@ -0,0 +1,51 @@ +import React, { type ReactElement } from 'react'; +import { useTranslation } from 'react-i18next'; +import { StudioLabelAsParagraph } from '@studio/components'; +import { PolicyAccessPackageAccordion } from './PolicyAccessPackageAccordion'; +import { filterAccessPackagesById, flatMapAreaPackageList } from './policyAccessPackageUtils'; +import type { + PolicyAccessPackage, + PolicyAccessPackageArea, +} from 'app-shared/types/PolicyAccessPackages'; + +type ChosenAccessPackagesProps = { + chosenAccessPackages: string[]; + groupedAccessPackagesByArea: PolicyAccessPackageArea[]; + handleSelectAccessPackage: (accessPackageUrn: string) => void; +}; +export const ChosenAccessPackages = ({ + chosenAccessPackages, + groupedAccessPackagesByArea, + handleSelectAccessPackage, +}: ChosenAccessPackagesProps): ReactElement => { + const { t } = useTranslation(); + + const flatMappedAreaList: PolicyAccessPackage[] = flatMapAreaPackageList( + groupedAccessPackagesByArea, + ); + const selectedAccessPackageList: PolicyAccessPackage[] = filterAccessPackagesById( + flatMappedAreaList, + chosenAccessPackages, + ); + + if (chosenAccessPackages.length > 0) { + return ( + <> + + {t('policy_editor.access_package_chosen_packages')} + + {selectedAccessPackageList.map((accessPackage: PolicyAccessPackage) => { + return ( + + ); + })} + + ); + } + return null; +}; diff --git a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordion.module.css b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordion.module.css index c2fbebef45c..63389e47f2e 100644 --- a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordion.module.css +++ b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordion.module.css @@ -1,5 +1,5 @@ :root { - --logo-size: 20px; + --logo-size: var(--fds-sizing-5); } .accessPackageAccordion { diff --git a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordion.test.tsx b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordion.test.tsx index 589f20249b5..c04b5fdc14c 100644 --- a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordion.test.tsx +++ b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordion.test.tsx @@ -98,11 +98,8 @@ const renderPolicyAccessPackageAccordion = (queries: Partial { - /** */ - }} + handleSelectChange={jest.fn()} /> - , , ); }; diff --git a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordion.tsx b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordion.tsx index 489505b0e29..cc17696a8ae 100644 --- a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordion.tsx +++ b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordion.tsx @@ -1,136 +1,36 @@ import React, { type ReactElement } from 'react'; -import { useTranslation } from 'react-i18next'; import classes from './PolicyAccessPackageAccordion.module.css'; -import type { AccessPackageResource, PolicyAccessPackage } from '@altinn/policy-editor'; import { PolicyAccordion } from '../PolicyAccordion'; -import { useResourceAccessPackageServicesQuery } from 'app-shared/hooks/queries/useResourceAccessPackageServicesQuery'; -import { StudioCheckbox, StudioParagraph, StudioSpinner } from '@studio/components'; +import { PolicyAccessPackageAccordionContent } from './PolicyAccessPackageAccordionContent'; +import { PolicyAccessPackageAccordionCheckBox } from './PolicyAccessPackageAccordionCheckbox'; +import type { PolicyAccessPackage } from 'app-shared/types/PolicyAccessPackages'; -const selectedLanguage = 'nb'; - -interface PolicyAccessPackageAccordionProps { +type PolicyAccessPackageAccordionProps = { accessPackage: PolicyAccessPackage; isChecked: boolean; handleSelectChange: (accessPackageUrn: string) => void; -} +}; export const PolicyAccessPackageAccordion = ({ accessPackage, isChecked, handleSelectChange, -}: PolicyAccessPackageAccordionProps): React.ReactElement => { +}: PolicyAccessPackageAccordionProps): ReactElement => { return (
} > - +
); }; - -type AccordionContentProps = { accessPackageUrn: string }; -const AccordionContent = ({ accessPackageUrn }: AccordionContentProps): ReactElement => { - const { t } = useTranslation(); - // Determine enviroment to load resources/apps connected to each access packages from. Option to override this - // value with a localStorage setting is for testing. Valid options are 'at22', 'at23', 'at24', 'tt02' - const accessPackageResourcesEnv = localStorage.getItem('accessPackageResourcesEnv') || 'prod'; - - const { data: services, isLoading } = useResourceAccessPackageServicesQuery( - accessPackageUrn, - accessPackageResourcesEnv, - ); - - const hasServices: boolean = services?.length > 0; - const serviceListIsEmpty: boolean = services?.length === 0; - return ( - <> - {isLoading && ( - - )} - {hasServices && } - {serviceListIsEmpty && ( - {t('policy_editor.access_package_no_services')} - )} - - ); -}; - -type ServicesProps = { - services: AccessPackageResource[]; -}; -const Services = ({ services }: ServicesProps): ReactElement => { - const { t } = useTranslation(); - - return ( - <> - - {t('policy_editor.access_package_services')} - - {services.map((resource) => ( -
- -
{resource.title[selectedLanguage]}
-
{resource.hasCompetentAuthority.name[selectedLanguage]}
-
- ))} - - ); -}; - -type ResourceImageProps = { - resource: AccessPackageResource; -}; -const ResourceImage = ({ resource }: ResourceImageProps): ReactElement => { - if (resource.logoUrl) { - return ( - {resource.hasCompetentAuthority.name[selectedLanguage]} - ); - } - return
; -}; - -type PolicyAccordionCheckBoxProps = Pick< - PolicyAccessPackageAccordionProps, - 'accessPackage' | 'isChecked' | 'handleSelectChange' ->; -const PolicyAccordionCheckBox = ({ - accessPackage, - isChecked, - handleSelectChange, -}: PolicyAccordionCheckBoxProps): ReactElement => { - const { t } = useTranslation(); - const CHECKED_VALUE = 'on'; - - const checkboxLabel = t( - isChecked ? 'policy_editor.access_package_remove' : 'policy_editor.access_package_add', - { - packageName: accessPackage.name, - }, - ); - - return ( - handleSelectChange(accessPackage.urn)} - > - - - ); -}; diff --git a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordionCheckbox.tsx b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordionCheckbox.tsx new file mode 100644 index 00000000000..d973a547363 --- /dev/null +++ b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordionCheckbox.tsx @@ -0,0 +1,37 @@ +import React, { type ReactElement } from 'react'; +import { useTranslation } from 'react-i18next'; +import classes from './PolicyAccessPackageAccordion.module.css'; +import { StudioCheckbox } from '@studio/components'; +import type { PolicyAccessPackage } from 'app-shared/types/PolicyAccessPackages'; + +type PolicyAccessPackageAccordionCheckBoxProps = { + accessPackage: PolicyAccessPackage; + isChecked: boolean; + handleSelectChange: (accessPackageUrn: string) => void; +}; +export const PolicyAccessPackageAccordionCheckBox = ({ + accessPackage, + isChecked, + handleSelectChange, +}: PolicyAccessPackageAccordionCheckBoxProps): ReactElement => { + const { t } = useTranslation(); + const CHECKED_VALUE = 'on'; + + const checkboxLabel = t( + isChecked ? 'policy_editor.access_package_remove' : 'policy_editor.access_package_add', + { + packageName: accessPackage.name, + }, + ); + + return ( + handleSelectChange(accessPackage.urn)} + > + + + ); +}; diff --git a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordionContent.tsx b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordionContent.tsx new file mode 100644 index 00000000000..1024632ea2b --- /dev/null +++ b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageAccordionContent.tsx @@ -0,0 +1,34 @@ +import React, { type ReactElement } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useResourceAccessPackageServicesQuery } from 'app-shared/hooks/queries/useResourceAccessPackageServicesQuery'; +import { StudioParagraph, StudioSpinner } from '@studio/components'; +import { PolicyAccessPackageServices } from './PolicyAccessPackageServices'; + +type PolicyAccessPackageAccordionContentProps = { accessPackageUrn: string }; +export const PolicyAccessPackageAccordionContent = ({ + accessPackageUrn, +}: PolicyAccessPackageAccordionContentProps): ReactElement => { + const { t } = useTranslation(); + // Determine enviroment to load resources/apps connected to each access packages from. Option to override this + // value with a localStorage setting is for testing. Valid options are 'at22', 'at23', 'at24', 'tt02' + const accessPackageResourcesEnv = localStorage.getItem('accessPackageResourcesEnv') || 'prod'; + + const { data: services, isLoading } = useResourceAccessPackageServicesQuery( + accessPackageUrn, + accessPackageResourcesEnv, + ); + + const hasServices: boolean = services?.length > 0; + const serviceListIsEmpty: boolean = services?.length === 0; + return ( + <> + {isLoading && ( + + )} + {hasServices && } + {serviceListIsEmpty && ( + {t('policy_editor.access_package_no_services')} + )} + + ); +}; diff --git a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageServiceLogo.tsx b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageServiceLogo.tsx new file mode 100644 index 00000000000..7f913b186ab --- /dev/null +++ b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageServiceLogo.tsx @@ -0,0 +1,24 @@ +import React, { type ReactElement } from 'react'; +import classes from './PolicyAccessPackageAccordion.module.css'; +import type { AccessPackageResource } from 'app-shared/types/PolicyAccessPackages'; + +type PolicyAccessPackageServiceLogoProps = { + resource: AccessPackageResource; + selectedLanguage: string; +}; +export const PolicyAccessPackageServiceLogo = ({ + resource, + selectedLanguage, +}: PolicyAccessPackageServiceLogoProps): ReactElement => { + if (resource.logoUrl) { + return ( + {resource.hasCompetentAuthority.name[selectedLanguage]} + ); + } + return
; +}; diff --git a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageServices.tsx b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageServices.tsx new file mode 100644 index 00000000000..54fe66ac709 --- /dev/null +++ b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackageAccordion/PolicyAccessPackageServices.tsx @@ -0,0 +1,32 @@ +import React, { type ReactElement } from 'react'; +import { useTranslation } from 'react-i18next'; +import classes from './PolicyAccessPackageAccordion.module.css'; +import { StudioParagraph } from '@studio/components'; +import { PolicyAccessPackageServiceLogo } from './PolicyAccessPackageServiceLogo'; +import type { AccessPackageResource } from 'app-shared/types/PolicyAccessPackages'; + +const selectedLanguage = 'nb'; + +type PolicyAccessPackageServicesProps = { + services: AccessPackageResource[]; +}; +export const PolicyAccessPackageServices = ({ + services, +}: PolicyAccessPackageServicesProps): ReactElement => { + const { t } = useTranslation(); + + return ( + <> + + {t('policy_editor.access_package_services')} + + {services.map((resource) => ( +
+ +
{resource.title[selectedLanguage]}
+
{resource.hasCompetentAuthority.name[selectedLanguage]}
+
+ ))} + + ); +}; diff --git a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackages.test.tsx b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackages.test.tsx index 1d48a720bfa..be0389e00cd 100644 --- a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackages.test.tsx +++ b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackages.test.tsx @@ -7,40 +7,44 @@ import { PolicyRuleContext } from '@altinn/policy-editor/contexts/PolicyRuleCont import { textMock } from '@studio/testing/mocks/i18nMock'; import { mockPolicyRuleContextValue } from '../../../../../test/mocks/policyRuleContextMock'; import { mockPolicyEditorContextValue } from '../../../../../test/mocks/policyEditorContextMock'; -import type { PolicyAccessPackageAreaGroup } from '@altinn/policy-editor'; import { ServicesContextProvider } from 'app-shared/contexts/ServicesContext'; import { createQueryClientMock } from 'app-shared/mocks/queryClientMock'; import { queriesMock } from 'app-shared/mocks/queriesMock'; +import type { + PolicyAccessPackage, + PolicyAccessPackageArea, + PolicyAccessPackageAreaGroup, +} from 'app-shared/types/PolicyAccessPackages'; -const skattPackage = { +const skattPackage: PolicyAccessPackage = { id: 'urn:altinn:accesspackage:skatt', urn: 'urn:altinn:accesspackage:skatt', name: 'Skatt', description: '', }; -const sjofartPackage = { +const sjofartPackage: PolicyAccessPackage = { id: 'urn:altinn:accesspackage:sjofart', urn: 'urn:altinn:accesspackage:sjofart', name: 'Sjøfart', description: '', }; -const lufttransportPackage = { +const lufttransportPackage: PolicyAccessPackage = { id: 'urn:altinn:accesspackage:lufttransport', urn: 'urn:altinn:accesspackage:lufttransport', name: 'Lufttransport', description: '', }; -const revisorPackage = { +const revisorPackage: PolicyAccessPackage = { id: 'urn:altinn:accesspackage:revisor', urn: 'urn:altinn:accesspackage:revisor', name: 'Revisor', description: '', }; -const accessPackageAreaSkatt = { +const accessPackageAreaSkatt: PolicyAccessPackageArea = { id: 'skatt-area', urn: 'accesspackage:area:skatt_avgift_regnskap_og_toll', name: 'Skatt', @@ -50,7 +54,7 @@ const accessPackageAreaSkatt = { packages: [skattPackage], }; -const accessPackageAreaTransport = { +const accessPackageAreaTransport: PolicyAccessPackageArea = { id: 'transport-area', urn: 'accesspackage:area:transport', name: 'Lagring og transport', @@ -60,7 +64,7 @@ const accessPackageAreaTransport = { packages: [sjofartPackage, lufttransportPackage], }; -const accessPackageAreaOther = { +const accessPackageAreaOther: PolicyAccessPackageArea = { id: 'other-area', urn: 'accesspackage:area:annet', name: 'Annet', diff --git a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackages.tsx b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackages.tsx index 0777bf48d1c..a5d27df6a72 100644 --- a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackages.tsx +++ b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccessPackages.tsx @@ -10,13 +10,13 @@ import { getUpdatedRules } from '../../../../utils/PolicyRuleUtils'; import { usePolicyEditorContext } from '../../../../contexts/PolicyEditorContext'; import { usePolicyRuleContext } from '../../../../contexts/PolicyRuleContext'; import classes from './PolicyAccessPackages.module.css'; -import { PolicyAccessPackageAccordion } from './PolicyAccessPackageAccordion'; -import { PolicyAccordion } from './PolicyAccordion'; import { filterAccessPackagesBySearchString, groupAccessPackagesByArea, + isAccessPackageSelected, } from './policyAccessPackageUtils'; -import type { PolicyAccessPackageArea } from '@altinn/policy-editor'; +import { ChosenAccessPackages } from './ChosenAccessPackages'; +import { AllAccessPackages } from './AllAccessPackages'; export const PolicyAccessPackages = (): ReactElement => { const { t } = useTranslation(); @@ -33,18 +33,27 @@ export const PolicyAccessPackages = (): ReactElement => { }, [accessPackages]); const handleSelectAccessPackage = (packageUrn: string): void => { - const isChecked = chosenAccessPackages.includes(packageUrn); + const isChecked = isAccessPackageSelected(packageUrn, chosenAccessPackages); + if (isChecked) { - setChosenAccessPackages((oldUrns) => oldUrns.filter((urn) => urn !== packageUrn)); - const urnsToSave = policyRule.accessPackages.filter((x) => x !== packageUrn); - handleAccessPackageChange(urnsToSave); + handleDeselectAccessPackage(packageUrn); } else { - setChosenAccessPackages((oldUrns) => [...oldUrns, packageUrn]); - const urnsToSave = [...policyRule.accessPackages, packageUrn]; - handleAccessPackageChange(urnsToSave); + handleSelectNewAccessPackage(packageUrn); } }; + const handleDeselectAccessPackage = (packageUrn: string): void => { + setChosenAccessPackages((oldUrns) => oldUrns.filter((urn) => urn !== packageUrn)); + const urnsToSave = policyRule.accessPackages.filter((x) => x !== packageUrn); + handleAccessPackageChange(urnsToSave); + }; + + const handleSelectNewAccessPackage = (packageUrn: string): void => { + setChosenAccessPackages((oldUrns) => [...oldUrns, packageUrn]); + const urnsToSave = [...policyRule.accessPackages, packageUrn]; + handleAccessPackageChange(urnsToSave); + }; + const handleAccessPackageChange = (newSelectedAccessPackageUrns: string[]): void => { const updatedRules = getUpdatedRules( { @@ -109,72 +118,3 @@ export const PolicyAccessPackages = (): ReactElement => {
); }; - -interface ChosenAccessPackagesProps { - chosenAccessPackages: string[]; - groupedAccessPackagesByArea: PolicyAccessPackageArea[]; - handleSelectAccessPackage: (accessPackageUrn: string) => void; -} -const ChosenAccessPackages = ({ - chosenAccessPackages, - groupedAccessPackagesByArea, - handleSelectAccessPackage, -}: ChosenAccessPackagesProps): ReactElement => { - const { t } = useTranslation(); - - if (chosenAccessPackages.length > 0) { - return ( - <> - - {t('policy_editor.access_package_chosen_packages')} - - {groupedAccessPackagesByArea - .flatMap((area) => area.packages) - .filter((accessPackage) => chosenAccessPackages.includes(accessPackage.urn)) - .map((accessPackage) => { - return ( - - ); - })} - - ); - } - return null; -}; - -interface AllAccessPackagesProps { - chosenAccessPackages: string[]; - accessPackagesToRender: PolicyAccessPackageArea[]; - searchValue: string; - handleSelectAccessPackage: (accessPackageUrn: string) => void; -} -const AllAccessPackages = ({ - chosenAccessPackages, - accessPackagesToRender, - searchValue, - handleSelectAccessPackage, -}: AllAccessPackagesProps): ReactElement[] => { - return accessPackagesToRender.map((area) => ( - - {area.packages.map((accessPackage) => ( - - ))} - - )); -}; diff --git a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccordion/PolicyAccordion.tsx b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccordion/PolicyAccordion.tsx index a682d317097..f9bf47e051e 100644 --- a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccordion/PolicyAccordion.tsx +++ b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/PolicyAccordion/PolicyAccordion.tsx @@ -1,17 +1,17 @@ -import React, { type ReactNode, useId, useState } from 'react'; +import React, { type ReactNode, type ReactElement, useId, useState } from 'react'; import cn from 'classnames'; import { StudioButton, StudioLabelAsParagraph } from '@studio/components'; import * as StudioIcons from '@studio/icons'; import classes from './PolicyAccordion.module.css'; -interface PolicyAccordion { +type PolicyAccordion = { icon?: string; title: string; subTitle: string; extraHeaderContent?: ReactNode; defaultOpen?: boolean; children: ReactNode; -} +}; export const PolicyAccordion = ({ icon, @@ -20,7 +20,7 @@ export const PolicyAccordion = ({ extraHeaderContent, defaultOpen, children, -}: PolicyAccordion): ReactNode => { +}: PolicyAccordion): ReactElement => { const contentId = useId(); const initialExpandedState: boolean = defaultOpen || false; const [isExpanded, setIsExpanded] = useState(initialExpandedState); diff --git a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/policyAccessPackageUtils.ts b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/policyAccessPackageUtils.ts index bf1ccb6e3ae..3bf1e13e648 100644 --- a/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/policyAccessPackageUtils.ts +++ b/frontend/packages/policy-editor/src/components/PolicyCardRules/PolicyRule/PolicyAccessPackages/policyAccessPackageUtils.ts @@ -1,26 +1,36 @@ -import type { PolicyAccessPackageArea, PolicyAccessPackageAreaGroup } from '@altinn/policy-editor'; +import type { + PolicyAccessPackage, + PolicyAccessPackageArea, + PolicyAccessPackageAreaGroup, +} from 'app-shared/types/PolicyAccessPackages'; const isStringMatch = (matchString: string, searchString: string): boolean => { return matchString.toLowerCase().includes(searchString.toLowerCase()); }; +const filterAreaPackagesBySearchString = ( + area: PolicyAccessPackageArea, + searchString: string, +): PolicyAccessPackage[] => { + return area.packages.filter( + (pack) => + !searchString || + isStringMatch(pack.name, searchString) || + isStringMatch(pack.description, searchString), + ); +}; + export const filterAccessPackagesBySearchString = ( accessPackageAreas: PolicyAccessPackageArea[], searchString: string, ): PolicyAccessPackageArea[] => { return accessPackageAreas.reduce( (areas: PolicyAccessPackageArea[], area): PolicyAccessPackageArea[] => { - const matchingPackages = area.packages.filter( - (pack) => - !searchString || - isStringMatch(pack.name, searchString) || - isStringMatch(pack.description, searchString), - ); - const returnAreas = [...areas]; + const matchingPackages = filterAreaPackagesBySearchString(area, searchString); if (matchingPackages.length > 0) { - returnAreas.push({ ...area, packages: matchingPackages }); + return [...areas, { ...area, packages: matchingPackages }]; } - return returnAreas; + return areas; }, [], ); @@ -29,5 +39,27 @@ export const filterAccessPackagesBySearchString = ( export const groupAccessPackagesByArea = ( accessPackageAreaGroups: PolicyAccessPackageAreaGroup[], ): PolicyAccessPackageArea[] => { - return accessPackageAreaGroups.flatMap((group) => group.areas); + return accessPackageAreaGroups.flatMap((group: PolicyAccessPackageAreaGroup) => group.areas); +}; + +export const flatMapAreaPackageList = ( + areaList: PolicyAccessPackageArea[], +): PolicyAccessPackage[] => { + return areaList.flatMap((area: PolicyAccessPackageArea) => area.packages); +}; + +export const filterAccessPackagesById = ( + accessPackageList: PolicyAccessPackage[], + chosenAccessPackageUrns: string[], +): PolicyAccessPackage[] => { + return accessPackageList.filter((accessPackage: PolicyAccessPackage) => + isAccessPackageSelected(accessPackage.urn, chosenAccessPackageUrns), + ); +}; + +export const isAccessPackageSelected = ( + accessPackageUrn: string, + chosenAccessPackageUrns: string[], +): boolean => { + return chosenAccessPackageUrns.includes(accessPackageUrn); }; diff --git a/frontend/packages/policy-editor/src/contexts/PolicyEditorContext/PolicyEditorContext.tsx b/frontend/packages/policy-editor/src/contexts/PolicyEditorContext/PolicyEditorContext.tsx index 2709acd2e25..692375d87d0 100644 --- a/frontend/packages/policy-editor/src/contexts/PolicyEditorContext/PolicyEditorContext.tsx +++ b/frontend/packages/policy-editor/src/contexts/PolicyEditorContext/PolicyEditorContext.tsx @@ -1,11 +1,6 @@ import React, { createContext, useContext } from 'react'; -import type { - PolicyAccessPackageAreaGroup, - PolicyAction, - PolicyEditorUsage, - PolicyRuleCard, - PolicySubject, -} from '../../types'; +import type { PolicyAction, PolicyEditorUsage, PolicyRuleCard, PolicySubject } from '../../types'; +import type { PolicyAccessPackageAreaGroup } from 'app-shared/types/PolicyAccessPackages'; export type PolicyEditorContextProps = { policyRules: PolicyRuleCard[]; diff --git a/frontend/packages/policy-editor/src/index.ts b/frontend/packages/policy-editor/src/index.ts index 33410510090..a1142e85eb9 100644 --- a/frontend/packages/policy-editor/src/index.ts +++ b/frontend/packages/policy-editor/src/index.ts @@ -3,10 +3,6 @@ export type { Policy, PolicyAction, PolicySubject, - PolicyAccessPackage, - PolicyAccessPackageArea, - PolicyAccessPackageAreaGroup, - AccessPackageResource, PolicyRule, PolicyRuleResource, RequiredAuthLevel, diff --git a/frontend/packages/policy-editor/src/types/index.ts b/frontend/packages/policy-editor/src/types/index.ts index 82266e3ce3d..2ea89b6760a 100644 --- a/frontend/packages/policy-editor/src/types/index.ts +++ b/frontend/packages/policy-editor/src/types/index.ts @@ -19,45 +19,6 @@ export interface PolicySubject { subjectDescription: string; } -export interface PolicyAccessPackage { - id: string; - urn: string; - name: string; - description: string; -} - -export interface PolicyAccessPackageArea { - id: string; - urn: string; - name: string; - description: string; - icon: string; - areaGroup: string; - packages: PolicyAccessPackage[]; -} - -export interface PolicyAccessPackageAreaGroup { - id: string; - urn: string; - name: string; - description: string; - type: string; - areas: PolicyAccessPackageArea[]; -} - -type AccessPackageResourceLanguage = 'nb' | 'nn' | 'en'; - -export interface AccessPackageResource { - identifier: string; - title: AccessPackageResourceLanguage; - hasCompetentAuthority?: { - name: AccessPackageResourceLanguage; - organization: string; - orgcode: string; - }; - logoUrl: string; -} - export interface PolicyAction { actionId: string; actionTitle: string; diff --git a/frontend/packages/shared/src/api/queries.ts b/frontend/packages/shared/src/api/queries.ts index 9c9e5e7d0cb..c61ac86d61a 100644 --- a/frontend/packages/shared/src/api/queries.ts +++ b/frontend/packages/shared/src/api/queries.ts @@ -78,7 +78,7 @@ import type { WidgetSettingsResponse } from 'app-shared/types/widgetTypes'; import { buildQueryParams } from 'app-shared/utils/urlUtils'; import { orgListUrl } from '../cdn-paths'; import type { JsonSchema } from 'app-shared/types/JsonSchema'; -import type { PolicyAction, PolicySubject, AccessPackageResource, PolicyAccessPackageAreaGroup } from '@altinn/policy-editor'; +import type { PolicyAction, PolicySubject } from '@altinn/policy-editor'; import type { BrregPartySearchResult, BrregSubPartySearchResult, AccessList, Resource, ResourceListItem, ResourceVersionStatus, Validation, AccessListsResponse, AccessListMembersResponse, DelegationCountOverview } from 'app-shared/types/ResourceAdm'; import type { AppConfig } from 'app-shared/types/AppConfig'; import type { ApplicationMetadata } from 'app-shared/types/ApplicationMetadata'; @@ -91,6 +91,7 @@ import type { ExternalImageUrlValidationResponse } from 'app-shared/types/api/Ex import type { MaskinportenScopes } from 'app-shared/types/MaskinportenScope'; import type { OptionsLists } from 'app-shared/types/api/OptionsLists'; import type { LayoutSetsModel } from '../types/api/dto/LayoutSetsModel'; +import type { AccessPackageResource, PolicyAccessPackageAreaGroup } from 'app-shared/types/PolicyAccessPackages'; export const getIsLoggedInWithAnsattporten = () => get<{ isLoggedIn: boolean }>(authStatusAnsattporten()); export const getMaskinportenScopes = (org: string, app: string) => get(availableMaskinportenScopesPath(org, app)); diff --git a/frontend/packages/shared/src/hooks/queries/useResourceAccessPackageServicesQuery.ts b/frontend/packages/shared/src/hooks/queries/useResourceAccessPackageServicesQuery.ts index 3088201886a..3c148a2599f 100644 --- a/frontend/packages/shared/src/hooks/queries/useResourceAccessPackageServicesQuery.ts +++ b/frontend/packages/shared/src/hooks/queries/useResourceAccessPackageServicesQuery.ts @@ -1,7 +1,7 @@ import type { UseQueryResult } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query'; import { useServicesContext } from 'app-shared/contexts/ServicesContext'; -import type { AccessPackageResource } from '@altinn/policy-editor'; +import type { AccessPackageResource } from 'app-shared/types/PolicyAccessPackages'; import { QueryKey } from 'app-shared/types/QueryKey'; import type { AxiosError } from 'axios'; diff --git a/frontend/packages/shared/src/hooks/queries/useResourceAccessPackagesQuery.ts b/frontend/packages/shared/src/hooks/queries/useResourceAccessPackagesQuery.ts index f11d291a328..6c709c10d18 100644 --- a/frontend/packages/shared/src/hooks/queries/useResourceAccessPackagesQuery.ts +++ b/frontend/packages/shared/src/hooks/queries/useResourceAccessPackagesQuery.ts @@ -1,7 +1,7 @@ import type { UseQueryResult } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query'; import { useServicesContext } from 'app-shared/contexts/ServicesContext'; -import type { PolicyAccessPackageAreaGroup } from '@altinn/policy-editor'; +import type { PolicyAccessPackageAreaGroup } from 'app-shared/types/PolicyAccessPackages'; import { QueryKey } from 'app-shared/types/QueryKey'; import type { AxiosError } from 'axios'; diff --git a/frontend/packages/shared/src/types/PolicyAccessPackages.ts b/frontend/packages/shared/src/types/PolicyAccessPackages.ts new file mode 100644 index 00000000000..97ec26941ea --- /dev/null +++ b/frontend/packages/shared/src/types/PolicyAccessPackages.ts @@ -0,0 +1,40 @@ +export type PolicyAccessPackage = { + id: string; + urn: string; + name: string; + description: string; +}; + +export type PolicyAccessPackageArea = { + id: string; + urn: string; + name: string; + description: string; + icon: string; + areaGroup: string; + packages: PolicyAccessPackage[]; +}; + +export type PolicyAccessPackageAreaGroup = { + id: string; + urn: string; + name: string; + description: string; + type: string; + areas: PolicyAccessPackageArea[]; +}; + +type AccessPackageResourceLanguage = 'nb' | 'nn' | 'en'; + +type CompetentAuthority = { + name: AccessPackageResourceLanguage; + organization: string; + orgcode: string; +}; + +export type AccessPackageResource = { + identifier: string; + title: AccessPackageResourceLanguage; + hasCompetentAuthority?: CompetentAuthority; + logoUrl: string; +}; diff --git a/frontend/packages/shared/src/types/ResourceLanguage.ts b/frontend/packages/shared/src/types/ResourceLanguage.ts deleted file mode 100644 index e69de29bb2d..00000000000