Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Refactor ZGW options components structure #4869

Merged
merged 1 commit into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/openforms/js/compiled-lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2517,6 +2517,12 @@
"value": "Add variable"
}
],
"LbiXCA": [
{
"type": 0,
"value": "Something went wrong while retrieving the available products defined in the selected case. Please check that the services in the selected API group are configured correctly."
}
],
"LeVpdf": [
{
"type": 0,
Expand Down Expand Up @@ -5337,12 +5343,6 @@
"value": "Add item"
}
],
"ln2iyc": [
{
"type": 0,
"value": "Something went wrong while retrieving the available catalogues or products defined in the selected case. Please check that the services in the selected API group are configured correctly."
}
],
"ln72CJ": [
{
"type": 0,
Expand Down
18 changes: 6 additions & 12 deletions src/openforms/js/compiled-lang/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -2538,6 +2538,12 @@
"value": "Variabele toevoegen"
}
],
"LbiXCA": [
{
"type": 0,
"value": "Er ging iets fout bij het ophalen van de beschikbare producten binnen het geselecteerde zaaktype. Controleer of de services in de geselecteerde API-groep goed ingesteld zijn."
}
],
"LeVpdf": [
{
"type": 0,
Expand Down Expand Up @@ -5109,12 +5115,6 @@
"value": "optie 2: € 15,99"
}
],
"jtWzSW": [
{
"type": 0,
"value": "optie 2: € 15,99"
}
],
"jy1jTd": [
{
"offset": 0,
Expand Down Expand Up @@ -5365,12 +5365,6 @@
"value": "Item toevoegen"
}
],
"ln2iyc": [
{
"type": 0,
"value": "Er ging iets fout bij het ophalen van de beschikbare catalogi of geselecteerde zaak producten. Controleer of de services in de geselecteerde API-groep goed ingesteld zijn."
}
],
"ln72CJ": [
{
"type": 0,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import {useFormikContext} from 'formik';
import PropTypes from 'prop-types';
import {FormattedMessage, useIntl} from 'react-intl';
import {useAsync, usePrevious, useUpdateEffect} from 'react-use';
import {FormattedMessage} from 'react-intl';

import useConfirm from 'components/admin/form_design/useConfirm';
import Fieldset from 'components/admin/forms/Fieldset';
import {getCatalogueOption} from 'components/admin/forms/zgw';
import {CatalogueSelectOptions} from 'components/admin/forms/zgw';
import ErrorBoundary from 'components/errors/ErrorBoundary';

import {CaseTypeSelect, CatalogueSelect, DocumentTypeSelect, ZGWAPIGroup} from './fields';
import {getCatalogues} from './utils';

// Components

const BasicOptionsFieldset = ({apiGroupChoices}) => {
const BasicOptionsFieldset = ({
apiGroupChoices,
loadingCatalogues,
catalogueOptionGroups = [],
cataloguesError = undefined,
catalogueUrl = '',
}) => {
const {
values: {
caseTypeIdentification,
Expand Down Expand Up @@ -61,7 +65,10 @@ const BasicOptionsFieldset = ({apiGroupChoices}) => {
/>
}
>
<CatalogiApiFields />
<MaybeThrowError error={cataloguesError} />
<CatalogueSelect loading={loadingCatalogues} optionGroups={catalogueOptionGroups} />
<CaseTypeSelect catalogueUrl={catalogueUrl} />
<DocumentTypeSelect catalogueUrl={catalogueUrl} />
</ErrorBoundary>
<ConfirmationModal
{...confirmationModalProps}
Expand All @@ -86,74 +93,23 @@ BasicOptionsFieldset.propTypes = {
])
)
).isRequired,
loadingCatalogues: PropTypes.bool.isRequired,
catalogueOptionGroups: CatalogueSelectOptions.isRequired,
cataloguesError: PropTypes.any,
catalogueUrl: PropTypes.string,
};

const CatalogiApiFields = () => {
const {
values: {
zgwApiGroup = null,
catalogue = undefined,
caseTypeIdentification = '',
documentTypeDescription = '',
productUrl = '',
},
setFieldValue,
} = useFormikContext();

const previousCatalogue = usePrevious(catalogue);
const previousCaseTypeIdentification = usePrevious(caseTypeIdentification);

// fetch available catalogues and re-use the result
const {
loading: loadingCatalogues,
value: catalogueOptionGroups = [],
error: cataloguesError,
} = useAsync(async () => {
if (!zgwApiGroup) return [];
return await getCatalogues(zgwApiGroup);
}, [zgwApiGroup]);
if (cataloguesError) throw cataloguesError;

const catalogueValue = getCatalogueOption(catalogueOptionGroups, catalogue || {});
const catalogueUrl = catalogueValue?.url;

// Synchronize dependent fields when dependencies change.
// 1. Clear case type when catalogue changes.
useUpdateEffect(() => {
const catalogueChanged = catalogue !== previousCatalogue;
if (previousCatalogue && catalogueChanged && caseTypeIdentification) {
setFieldValue('caseTypeIdentification', '');
}
}, [setFieldValue, previousCatalogue, catalogue, caseTypeIdentification]);

// 2. Clear document type when case type changes
useUpdateEffect(() => {
const caseTypeChanged = caseTypeIdentification !== previousCaseTypeIdentification;
if (previousCaseTypeIdentification && caseTypeChanged && documentTypeDescription) {
setFieldValue('documentTypeDescription', '');
}
}, [
setFieldValue,
previousCaseTypeIdentification,
caseTypeIdentification,
documentTypeDescription,
]);

// 3. Clear selected product when case type changes
useUpdateEffect(() => {
const caseTypeChanged = caseTypeIdentification !== previousCaseTypeIdentification;
if (previousCaseTypeIdentification && caseTypeChanged && productUrl) {
setFieldValue('productUrl', '');
}
}, [setFieldValue, previousCaseTypeIdentification, caseTypeIdentification, productUrl]);
/**
* Component that only throws an error if it's not undefined, intended to trigger a
* parent error boundary.
*/
const MaybeThrowError = ({error = undefined}) => {
if (error) throw error;
return null;
};

return (
<>
<CatalogueSelect loading={loadingCatalogues} optionGroups={catalogueOptionGroups} />
<CaseTypeSelect catalogueUrl={catalogueUrl} />
<DocumentTypeSelect catalogueUrl={catalogueUrl} />
</>
);
MaybeThrowError.propTypes = {
error: PropTypes.any,
};

export default BasicOptionsFieldset;
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {FormattedMessage} from 'react-intl';

import Fieldset from 'components/admin/forms/Fieldset';

import {LegacyCaseType, LegacyDocumentType} from './fields';

/**
* @deprecated
*/
const LegacyOptionsFieldset = () => (
<Fieldset
title={
<FormattedMessage
description="ZGw APIs registration: legacy configuration options fieldset title"
defaultMessage="Legacy configuration"
/>
}
fieldNames={['zaaktype', 'informatieobjecttype']}
collapsible
>
<div className="description">
<FormattedMessage
description="ZGW APIs legacy config options informative message"
defaultMessage={`The configuration options here are legacy options. They
will continue working, but you should upgrade to the new configuration
options above. If a new configuration option is specified, the matching
legacy option will be ignored.`}
/>
</div>
<LegacyCaseType />
<LegacyDocumentType />
</Fieldset>
);

export default LegacyOptionsFieldset;
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {useFormikContext} from 'formik';
import PropTypes from 'prop-types';
import {FormattedMessage} from 'react-intl';

import {ContentJSON} from 'components/admin/form_design/registrations/objectsapi/LegacyConfigFields';
import Fieldset from 'components/admin/forms/Fieldset';
import {ObjectsAPIGroup} from 'components/admin/forms/objects_api';

import {ObjectType, ObjectTypeVersion} from './fields';

/**
* Callback to invoke when the API group changes - used to reset the dependent fields.
*/
const onApiGroupChange = prevValues => ({
...prevValues,
objecttype: '',
objecttypeVersion: undefined,
});

/**
* Configuration fields related to the Objects API (template based) integration.
*/
const ObjectsAPIOptionsFieldset = ({objectsApiGroupChoices}) => {
const {
values: {objecttype = ''},
} = useFormikContext();
return (
<Fieldset
title={
<FormattedMessage
description="ZGW APIs registration: Objects API fieldset title"
defaultMessage="Objects API integration"
/>
}
collapsible
fieldNames={['objecttype', 'objecttypeVersion', 'contentJson']}
>
<ObjectsAPIGroup
apiGroupChoices={objectsApiGroupChoices}
onApiGroupChange={onApiGroupChange}
required={!!objecttype}
isClearable
/>
<ObjectType />
<ObjectTypeVersion />
<ContentJSON />
</Fieldset>
);
};

ObjectsAPIOptionsFieldset.propTypes = {
objectsApiGroupChoices: PropTypes.arrayOf(
PropTypes.arrayOf(
PropTypes.oneOfType([
PropTypes.number, // value
PropTypes.string, // label
])
)
),
};

export default ObjectsAPIOptionsFieldset;
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
import {useFormikContext} from 'formik';
import PropTypes from 'prop-types';
import {FormattedMessage} from 'react-intl';
import {useAsync} from 'react-use';

import Fieldset from 'components/admin/forms/Fieldset';
import {getCatalogueOption} from 'components/admin/forms/zgw';
import ErrorBoundary from 'components/errors/ErrorBoundary';

import {ConfidentialityLevel, MedewerkerRoltype, OrganisationRSIN, ProductSelect} from './fields';
import {getCatalogues} from './utils';

const OptionalOptionsFieldset = ({confidentialityLevelChoices}) => {
const OptionalOptionsFieldset = ({confidentialityLevelChoices, catalogueUrl}) => {
return (
<Fieldset
title={
Expand Down Expand Up @@ -42,38 +38,22 @@ const OptionalOptionsFieldset = ({confidentialityLevelChoices}) => {
<FormattedMessage
description="ZGW APIs registrations options: case product error"
defaultMessage={`Something went wrong while retrieving the available
catalogues or products defined in the selected case. Please
check that the services in the selected API group are configured correctly.`}
products defined in the selected case. Please check that the services in
the selected API group are configured correctly.`}
/>
}
>
<CatalogiApiField />
<ProductSelect catalogueUrl={catalogueUrl} />
</ErrorBoundary>
</Fieldset>
);
};

const CatalogiApiField = () => {
const {
values: {zgwApiGroup = null, catalogue = undefined},
} = useFormikContext();

// fetch available catalogues and re-use the result
const {value: catalogueOptionGroups = [], error: cataloguesError} = useAsync(async () => {
if (!zgwApiGroup) return [];
return await getCatalogues(zgwApiGroup);
}, [zgwApiGroup]);
if (cataloguesError) throw cataloguesError;

const catalogueValue = getCatalogueOption(catalogueOptionGroups, catalogue || {});
const catalogueUrl = catalogueValue?.url;
return <ProductSelect catalogueUrl={catalogueUrl} />;
};

OptionalOptionsFieldset.propTypes = {
confidentialityLevelChoices: PropTypes.arrayOf(
PropTypes.arrayOf(PropTypes.string) // value & label are both string
).isRequired,
catalogueUrl: PropTypes.string,
};

export default OptionalOptionsFieldset;
Loading
Loading