Skip to content

Commit

Permalink
Merge branch 'main' into 1478-servicepoint-parent
Browse files Browse the repository at this point in the history
  • Loading branch information
peterMuriuki authored Oct 14, 2024
2 parents b9727bc + bf6dad9 commit 0035e9b
Show file tree
Hide file tree
Showing 10 changed files with 660 additions and 100 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { useState } from 'react';
import { Form, Button, Input, DatePicker, Space, Switch } from 'antd';
import {
PaginatedAsyncSelect,
formItemLayout,
tailLayout,
SelectOption as ProductSelectOption,
ValueSetAsyncSelect,
ClientSideActionsSelect,
} from '@opensrp/react-utils';
import { useTranslation } from '../../mls';
import { useQueryClient, useMutation } from 'react-query';
Expand Down Expand Up @@ -162,12 +162,12 @@ const AddLocationInventoryForm = (props: LocationInventoryFormProps) => {
initialValues={initialValues}
>
<FormItem id={product} name={product} label={t('Product name')}>
<PaginatedAsyncSelect<IGroup>
baseUrl={fhirBaseURL}
<ClientSideActionsSelect<IGroup>
fhirBaseUrl={fhirBaseURL}
resourceType={groupResourceType}
transformOption={processProductOptions}
extraQueryParams={productQueryFilters}
showSearch={false}
showSearch={true}
placeholder={t('Select product')}
getFullOptionOnChange={productChangeHandler}
disabled={editMode}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,13 @@ test('creates new inventory as expected', async () => {
const preFetchScope = nock(props.fhirBaseURL)
.get(`/${groupResourceType}/_search`)
.query({
_getpagesoffset: 0,
_summary: 'count',
code: 'http://snomed.info/sct|386452003',
'_has:List:item:_id': props.commodityListId,
})
.reply(200, { total: 20 })
.get(`/${groupResourceType}/_search`)
.query({
_count: 20,
code: 'http://snomed.info/sct|386452003',
'_has:List:item:_id': props.commodityListId,
Expand Down Expand Up @@ -194,29 +200,32 @@ test('creates new inventory as expected', async () => {
render(<AppWrapper {...thisProps}></AppWrapper>);

await waitFor(() => {
expect(preFetchScope.isDone()).toBeTruthy();
expect(preFetchScope.pendingMocks()).toEqual([]);
});

// simulate value selection for product
const productSelectComponent = document.querySelector(`input#${product}`)!;
fireEvent.mouseDown(productSelectComponent);

const optionTexts = [
...document.querySelectorAll(
`#${product}_list+div.rc-virtual-list .ant-select-item-option-content`
),
].map((option) => {
return option.textContent;
await waitFor(() => {
// simulate value selection for product
const productSelectComponent = document.querySelector(`input#${product}`)!;
fireEvent.mouseDown(productSelectComponent);

const optionTexts = [
...document.querySelectorAll(
`#${product}_list+div.rc-virtual-list .ant-select-item-option-content`
),
].map((option) => {
return option.textContent;
});

expect(optionTexts).toEqual([
'Yellow sunshine',
'Fig tree',
'Lumpy nuts',
'Happy Feet',
'Lilly Flowers',
'Smartphone TEST',
]);
});

expect(optionTexts).toEqual([
'Yellow sunshine',
'Fig tree',
'Lumpy nuts',
'Happy Feet',
'Lilly Flowers',
'Smartphone TEST',
]);
fireEvent.click(document.querySelector(`[title="${'Lumpy nuts'}"]`)!);

const quantity = screen.getByLabelText('Quantity');
Expand Down Expand Up @@ -269,7 +278,13 @@ test('#1384 - correctly updates location inventory', async () => {
const preFetchScope = nock(props.fhirBaseURL)
.get(`/${groupResourceType}/_search`)
.query({
_getpagesoffset: 0,
_summary: 'count',
code: 'http://snomed.info/sct|386452003',
'_has:List:item:_id': props.commodityListId,
})
.reply(200, { total: 20 })
.get(`/${groupResourceType}/_search`)
.query({
_count: 20,
code: 'http://snomed.info/sct|386452003',
'_has:List:item:_id': props.commodityListId,
Expand Down Expand Up @@ -322,26 +337,28 @@ test('#1384 - correctly updates location inventory', async () => {
// serial number is initially not shown on the form
expect(screen.queryByText('Serial number')).not.toBeInTheDocument();

// simulate value selection for product
const productSelectComponent = document.querySelector(`input#${product}`)!;
fireEvent.mouseDown(productSelectComponent);

const optionTexts = [
...document.querySelectorAll(
`#${product}_list+div.rc-virtual-list .ant-select-item-option-content`
),
].map((option) => {
return option.textContent;
await waitFor(() => {
// simulate value selection for product
const productSelectComponent = document.querySelector(`input#${product}`)!;
fireEvent.mouseDown(productSelectComponent);

const optionTexts = [
...document.querySelectorAll(
`#${product}_list+div.rc-virtual-list .ant-select-item-option-content`
),
].map((option) => {
return option.textContent;
});

expect(optionTexts).toEqual([
'Yellow sunshine',
'Fig tree',
'Lumpy nuts',
'Happy Feet',
'Lilly Flowers',
'Smartphone TEST',
]);
});

expect(optionTexts).toEqual([
'Yellow sunshine',
'Fig tree',
'Lumpy nuts',
'Happy Feet',
'Lilly Flowers',
'Smartphone TEST',
]);
fireEvent.click(document.querySelector(`[title="${'Lumpy nuts'}"]`)!);

const quantity = screen.getByLabelText('Quantity');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ function CommodityForm<
await postSuccess?.(mutationEffectResponse, isEdit).catch((err) => {
sendErrorNotification(err.message);
});
queryClient.refetchQueries([groupResourceType]).catch(() => {
queryClient.invalidateQueries([groupResourceType]).catch(() => {
sendInfoNotification(t('Failed to refresh data, please refresh the page'));
});
goTo(successUrl);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React from 'react';
import { URLParams } from '@opensrp/server-service';
import { useQuery } from 'react-query';
import { Divider, Select, Empty, Spin, Alert } from 'antd';
import { IResource } from '@smile-cdr/fhirts/dist/FHIR-R4/interfaces/IResource';
import { getResourcesFromBundle } from '../../../helpers/utils';
import { useTranslation } from '../../../mls';
import { loadAllResources } from '../../../helpers/fhir-utils';
import {
AbstractedSelectOptions,
defaultSelectFilterFunction,
SelectOption,
TransformOptions,
} from '../utils';

export interface ClientSideActionsSelectProps<ResourceT extends IResource>
extends AbstractedSelectOptions<ResourceT> {
fhirBaseUrl: string;
resourceType: string;
extraQueryParams?: URLParams;
transformOption: TransformOptions<ResourceT>;
getFullOptionOnChange?: (obj: SelectOption<ResourceT> | SelectOption<ResourceT>[]) => void;
}

/**
* Select component that loads all options as a single resource
*
* @param props - component props
*/
export function ClientSideActionsSelect<ResourceT extends IResource>(
props: ClientSideActionsSelectProps<ResourceT>
) {
const {
fhirBaseUrl,
resourceType,
extraQueryParams = {},
transformOption,
onChange,
getFullOptionOnChange,
...restProps
} = props;

const { t } = useTranslation();

const {
data: options,
isLoading,
error,
} = useQuery({
queryKey: [ClientSideActionsSelect.name, resourceType],
queryFn: async () => {
return await loadAllResources(fhirBaseUrl, resourceType, extraQueryParams);
},
refetchOnWindowFocus: false,
select: (bundle) => {
const options = getResourcesFromBundle<ResourceT>(bundle).map((resource) =>
transformOption(resource)
);
return options as SelectOption<ResourceT>[];
},
});

const changeHandler = (
value: string,
fullOption: SelectOption<ResourceT> | SelectOption<ResourceT>[]
) => {
const saneFullOption = Array.isArray(fullOption) ? fullOption.slice() : fullOption;
props.onChange?.(value, saneFullOption);
getFullOptionOnChange?.(saneFullOption);
};

const propsToSelect = {
className: 'asyncSelect',
filterOption: defaultSelectFilterFunction,
...restProps,
onChange: changeHandler,
loading: isLoading,
notFoundContent: isLoading ? <Spin size="small" /> : <Empty description={t('No data')} />,
options,
dropdownRender: (menu: React.ReactNode) => (
<>
{!error && options?.length && menu}
<Divider style={{ margin: '8px 0' }} />
{error && <Alert message={t('Unable to load dropdown options.')} type="error" showIcon />}
</>
),
};

return <Select {...propsToSelect}></Select>;
}
Loading

0 comments on commit 0035e9b

Please sign in to comment.