Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenbal committed Feb 4, 2025
1 parent aec40e4 commit 2752021
Show file tree
Hide file tree
Showing 13 changed files with 256 additions and 315 deletions.
8 changes: 4 additions & 4 deletions src/components/builder/values/referentielijsten/code.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ function transformItems(items: ReferentielijstenTabelOption[]) {
});
}

interface ComponentWithReferentielijsten {
export interface ComponentWithReferentielijsten {
openForms?: {
dataSrc: 'referentielijsten';
service?: string;
code?: string;
service: string;
code: string;
};
}

Expand Down Expand Up @@ -63,7 +63,7 @@ export const ReferentielijstenTabelCode: React.FC = () => {

return (
<Select
name={'openForms.code'}
name="openForms.code"
label={
<FormattedMessage
description="Label for 'openForms.code' builder field"
Expand Down
46 changes: 15 additions & 31 deletions src/components/builder/values/referentielijsten/service.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import {useField} from 'formik';
import {useFormikContext} from 'formik';
import {useContext} from 'react';
import {FormattedMessage, useIntl} from 'react-intl';
import useAsync from 'react-use/esm/useAsync';

import Select, {Option} from '@/components/formio/select';
import Select from '@/components/formio/select';
import {BuilderContext} from '@/context';

import {ComponentWithReferentielijsten} from './code';

export interface ReferentielijstenServiceOption {
url: string;
slug: string;
Expand All @@ -14,12 +16,6 @@ export interface ReferentielijstenServiceOption {
apiType: string;
}

function isServiceOptions(
options: ReferentielijstenServiceOption[] | undefined
): options is ReferentielijstenServiceOption[] {
return options !== undefined;
}

/**
* Fetch the available Referentielijsten Services and display them in a Select
*
Expand All @@ -33,32 +29,19 @@ function isServiceOptions(
*/
const ReferentielijstenServiceSelect: React.FC = () => {
const intl = useIntl();
const {values, setFieldValue} = useFormikContext<ComponentWithReferentielijsten>();
const {getServices} = useContext(BuilderContext);
const {
value: options,
loading,
error,
} = useAsync(async () => await getServices('referentielijsten'), []);
if (error) {
throw error;
}
const _options = isServiceOptions(options) ? options : [];
const transformedOptions: Option[] = _options.map(({slug, label}) => ({
value: slug,
label: label,
}));

// react-select doesn't update the defaultValue if it is initially `null`,
// so instead we update the value of the Formik field to ensure the correct default
// is selected
const [field, , {setValue}] = useField('openForms.service');
if (transformedOptions && transformedOptions.length == 1 && !field.value) {
setValue(transformedOptions[0].value);
}
const {value: options = [], loading} = useAsync(async () => {
const options = await getServices('referentielijsten');
if (options.length === 1 && !values?.openForms?.service) {
setFieldValue('openForms.service', options[0].slug);
}
return options;
}, [getServices, setFieldValue]); // values is deliberately excluded from the dependency array

return (
<Select
name={'openForms.service'}
name="openForms.service"
label={
<FormattedMessage
description="Label for 'openForms.service' builder field"
Expand All @@ -70,7 +53,8 @@ const ReferentielijstenServiceSelect: React.FC = () => {
defaultMessage: `The identifier of the Referentielijsten service from which the options will be retrieved.`,
})}
isLoading={loading}
options={transformedOptions}
valueProperty="slug"
options={options}
required
/>
);
Expand Down
20 changes: 6 additions & 14 deletions src/components/builder/values/values-config.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import ValuesConfig from './values-config';
export default {
title: 'Formio/Builder/Values/ValuesConfig',
component: ValuesConfig,
decorators: [withFormik],
parameters: {
controls: {hideNoControlsWarning: true},
modal: {noModal: true},
Expand Down Expand Up @@ -44,12 +45,9 @@ type SelectStory = StoryObj<typeof ValuesConfig<SelectComponentSchema>>;
/**
* Variant pinned to the `SelectboxesComponentSchema` component type.
*/
export const SelectBoxes: SelectboxesStory = {
decorators: [withFormik],
};
export const SelectBoxes: SelectboxesStory = {};

export const SelectBoxesManual: SelectboxesStory = {
decorators: [withFormik],
parameters: {
formik: {
initialValues: {
Expand All @@ -72,7 +70,6 @@ export const SelectBoxesManual: SelectboxesStory = {
};

export const SelectBoxesVariable: SelectboxesStory = {
decorators: [withFormik],
parameters: {
formik: {
initialValues: {
Expand Down Expand Up @@ -211,12 +208,9 @@ export const SelectBoxesResetState: StoryObj<{
/**
* Variant pinned to the `RadioComponentSchema` component type.
*/
export const Radio: RadioStory = {
decorators: [withFormik],
};
export const Radio: RadioStory = {};

export const RadioManual: RadioStory = {
decorators: [withFormik],
parameters: {
formik: {
initialValues: {
Expand All @@ -239,7 +233,6 @@ export const RadioManual: RadioStory = {
};

export const RadioVariable: RadioStory = {
decorators: [withFormik],
parameters: {
formik: {
initialValues: {
Expand All @@ -256,7 +249,6 @@ export const RadioVariable: RadioStory = {
* Variant pinned to the `SelectComponentSchema` component type.
*/
export const Select: SelectStory = {
decorators: [withFormik],
args: {
name: 'data.values',
},
Expand Down Expand Up @@ -307,7 +299,7 @@ export const SelectVariable: SelectStory = {
export const SelectReferentielijsten: SelectStory = {
...Select,

decorators: [withFormik, BuilderContextDecorator],
decorators: [BuilderContextDecorator],
parameters: {
formik: {
initialValues: {
Expand All @@ -325,7 +317,7 @@ export const SelectReferentielijsten: SelectStory = {
export const SelectboxesReferentielijsten: SelectboxesStory = {
...SelectBoxes,

decorators: [withFormik, BuilderContextDecorator],
decorators: [BuilderContextDecorator],
parameters: {
formik: {
initialValues: {
Expand All @@ -343,7 +335,7 @@ export const SelectboxesReferentielijsten: SelectboxesStory = {
export const RadioReferentielijsten: RadioStory = {
...Radio,

decorators: [withFormik, BuilderContextDecorator],
decorators: [BuilderContextDecorator],
parameters: {
formik: {
initialValues: {
Expand Down
2 changes: 2 additions & 0 deletions src/registry/radio/edit-validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ const buildValuesSchema = (intl: IntlShape) =>
]),
// TODO: wire up infernologic type checking
itemsExpression: jsonSchema.optional(),
service: z.string().optional(),
code: z.string().optional(),
}),
});

Expand Down
11 changes: 6 additions & 5 deletions src/registry/radio/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import {RadioComponentSchema} from '@open-formulieren/types';
import {Option} from '@open-formulieren/types/lib/formio/common';
import {JSONObject} from '@open-formulieren/types/lib/types';

import {ComponentWithReferentielijsten} from '@/components/builder/values/referentielijsten/code';

// A type guard is needed because TS cannot figure out it's a discriminated union
// when the discriminator is nested.
// See https://github.com/microsoft/TypeScript/issues/18758
Expand All @@ -16,10 +18,10 @@ export const checkIsManualOptions = (
// See https://github.com/microsoft/TypeScript/issues/18758
export const checkIsReferentielijstenOptions = (
component: RadioComponentSchema
): component is RadioComponentSchema & {
data: {values: Option[] | undefined};
openForms: {code: string; service: string};
} => {
): component is RadioComponentSchema &
ComponentWithReferentielijsten & {
openForms: {code: string; service: string};
} => {
return component.openForms.dataSrc === 'referentielijsten';
};

Expand All @@ -29,7 +31,6 @@ export const checkIsReferentielijstenOptions = (
export const checkIsVariableOptions = (
component: RadioComponentSchema
): component is RadioComponentSchema & {
data: {values: Option[] | undefined};
openForms: {itemsExpression: string | JSONObject};
} => {
return component.openForms.dataSrc === 'variable';
Expand Down
Loading

0 comments on commit 2752021

Please sign in to comment.