-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add search input className * Expose client side grid filter hook api * Style tweak of filter on location inventory page * Refactor commodity list view to filter data clientside * Revert "Add search input className" This reverts commit fa2e027. * Fix lint errors * Update fhir user management with active filter * Fix lint errors * Update snap regressions
- Loading branch information
1 parent
13f57fe
commit c4fcd61
Showing
12 changed files
with
448 additions
and
68 deletions.
There are no files selected for viewing
150 changes: 150 additions & 0 deletions
150
...oup-management/src/components/BaseComponents/BaseGroupsListView/ClientSideActionsGrid.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import React, { ChangeEvent, ReactNode } from 'react'; | ||
import { Helmet } from 'react-helmet'; | ||
import { Row, Col } from 'antd'; | ||
import { | ||
BodyLayout, | ||
FilterDescription, | ||
RegisterFilter, | ||
useClientSideActionsDataGrid, | ||
} from '@opensrp/react-utils'; | ||
import { parseGroup, ViewDetailsProps, ViewDetailsWrapper } from '../GroupDetail'; | ||
import { groupResourceType } from '../../../constants'; | ||
import { | ||
SearchForm, | ||
BrokenPage, | ||
TableLayout, | ||
Column, | ||
viewDetailsQuery, | ||
useSearchParams, | ||
} from '@opensrp/react-utils'; | ||
import { useTranslation } from '../../../mls'; | ||
import { TFunction } from '@opensrp/i18n'; | ||
import { IBundle } from '@smile-cdr/fhirts/dist/FHIR-R4/interfaces/IBundle'; | ||
|
||
export type DefaultTableData = ReturnType<typeof parseGroup> & Record<string, unknown>; | ||
|
||
export type ExtendableTableData = Pick< | ||
ReturnType<typeof parseGroup>, | ||
'id' | 'name' | 'active' | 'identifier' | 'lastUpdated' | ||
>; | ||
|
||
export type ClientSideActionsBaseListViewProps< | ||
TableData extends ExtendableTableData = DefaultTableData | ||
> = Partial<Pick<ViewDetailsProps, 'keyValueMapperRenderProp'>> & { | ||
fhirBaseURL: string; | ||
getColumns: (t: TFunction) => Column<TableData>[]; | ||
extraQueryFilters?: Record<string, string>; | ||
addGroupBtnRender?: () => ReactNode; | ||
pageTitle: string; | ||
dataTransformer?: (groups: IBundle) => TableData[]; | ||
viewDetailsRender?: (fhirBaseURL: string, resourceId?: string) => ReactNode; | ||
filterRowRender?: ( | ||
registerFilter: RegisterFilter<TableData>, | ||
filterRegistry: FilterDescription<TableData> | ||
) => ReactNode; | ||
}; | ||
|
||
/** | ||
* Shows the list of all group and there details | ||
* | ||
* @param props - GroupList component props | ||
* @returns returns healthcare display | ||
*/ | ||
export function ClientSideActionsBaseListView< | ||
TableData extends ExtendableTableData = DefaultTableData | ||
>(props: ClientSideActionsBaseListViewProps<TableData>) { | ||
const { | ||
fhirBaseURL, | ||
extraQueryFilters, | ||
filterRowRender, | ||
getColumns, | ||
addGroupBtnRender, | ||
keyValueMapperRenderProp, | ||
pageTitle, | ||
viewDetailsRender, | ||
dataTransformer, | ||
} = props; | ||
|
||
const { sParams } = useSearchParams(); | ||
const resourceId = sParams.get(viewDetailsQuery) ?? undefined; | ||
const { t } = useTranslation(); | ||
|
||
const { | ||
queryValues: { data, isFetching, isLoading, error }, | ||
tablePaginationProps, | ||
searchFormProps, | ||
filterOptions: { registerFilter, filterRegistry, deregisterFilter }, | ||
} = useClientSideActionsDataGrid<TableData>( | ||
fhirBaseURL, | ||
groupResourceType, | ||
extraQueryFilters, | ||
dataTransformer | ||
); | ||
|
||
if (error && !data.length) { | ||
return <BrokenPage errorMessage={(error as Error).message} />; | ||
} | ||
|
||
const tableData = data; | ||
|
||
const columns = getColumns(t); | ||
|
||
const tableProps = { | ||
datasource: tableData, | ||
columns, | ||
loading: isFetching || isLoading, | ||
pagination: tablePaginationProps, | ||
}; | ||
const headerProps = { | ||
pageHeaderProps: { | ||
title: pageTitle, | ||
onBack: undefined, | ||
}, | ||
}; | ||
|
||
const nameFilterKey = 'name'; | ||
const searchInputProps = { | ||
...searchFormProps, | ||
wrapperClassName: 'elongate-search-bar', | ||
onChangeHandler: (event: ChangeEvent<HTMLInputElement>) => { | ||
searchFormProps.onChangeHandler(event); | ||
const searchText = event.target.value; | ||
if (searchText) { | ||
registerFilter( | ||
nameFilterKey, | ||
(el) => { | ||
return (el.name ?? '').toLowerCase().includes(searchText.toLowerCase()); | ||
}, | ||
searchText | ||
); | ||
} else { | ||
deregisterFilter(nameFilterKey); | ||
} | ||
}, | ||
}; | ||
|
||
return ( | ||
<BodyLayout headerProps={headerProps}> | ||
<Helmet> | ||
<title>{pageTitle}</title> | ||
</Helmet> | ||
<Row className="list-view"> | ||
<Col className="main-content"> | ||
<div className="main-content__header"> | ||
<SearchForm data-testid="search-form" {...searchInputProps} /> | ||
{addGroupBtnRender?.()} | ||
</div> | ||
{filterRowRender?.(registerFilter, filterRegistry)} | ||
<TableLayout {...tableProps} /> | ||
</Col> | ||
{viewDetailsRender?.(fhirBaseURL, resourceId) ?? ( | ||
<ViewDetailsWrapper | ||
resourceId={resourceId} | ||
fhirBaseURL={fhirBaseURL} | ||
keyValueMapperRenderProp={keyValueMapperRenderProp} | ||
/> | ||
)} | ||
</Row> | ||
</BodyLayout> | ||
); | ||
} |
83 changes: 83 additions & 0 deletions
83
packages/fhir-group-management/src/components/CommodityList/Eusm/GroupGridFilterRow.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { Space, Radio } from 'antd'; | ||
import React from 'react'; | ||
import { FilterDescription, RegisterFilter } from '@opensrp/react-utils'; | ||
import { useTranslation } from '../../../mls'; | ||
import { Trans } from '@opensrp/i18n'; | ||
import { parseEusmCommodity } from './ViewDetails'; | ||
|
||
export type TableData = ReturnType<typeof parseEusmCommodity>; | ||
|
||
export interface GroupGridFilerRowProps { | ||
updateFilterParams: RegisterFilter<TableData>; | ||
currentFilters: FilterDescription<TableData>; | ||
} | ||
|
||
const isAnAssetDataIdx = 'isAnAsset'; | ||
const statusFilterDataIdx = 'status'; | ||
|
||
export const GroupGridFilerRow = (props: GroupGridFilerRowProps) => { | ||
const { t } = useTranslation(); | ||
const { updateFilterParams, currentFilters } = props; | ||
return ( | ||
<div className="filter-row" data-testid="filter-row"> | ||
<Space size={'large'}> | ||
<Trans t={t} i18nKey="attractiveFilter"> | ||
<Space> | ||
Asset: | ||
<Radio.Group | ||
size="small" | ||
value={currentFilters[isAnAssetDataIdx]?.value} | ||
buttonStyle="solid" | ||
onChange={(event) => { | ||
const val = event.target.value; | ||
if (val !== undefined) { | ||
updateFilterParams( | ||
isAnAssetDataIdx, | ||
(el: TableData) => { | ||
return el.attractive === val; | ||
}, | ||
val | ||
); | ||
} else { | ||
updateFilterParams(isAnAssetDataIdx, undefined); | ||
} | ||
}} | ||
> | ||
<Radio.Button value={true}>{t('Yes')}</Radio.Button> | ||
<Radio.Button value={false}>{t('No')}</Radio.Button> | ||
<Radio.Button value={undefined}>{t('Show all')}</Radio.Button> | ||
</Radio.Group> | ||
</Space> | ||
</Trans> | ||
<Trans t={t} i18nKey="groupStatusFilter"> | ||
<Space> | ||
Status: | ||
<Radio.Group | ||
size="small" | ||
value={currentFilters[statusFilterDataIdx]?.value} | ||
buttonStyle="solid" | ||
onChange={(event) => { | ||
const val = event.target.value; | ||
if (val !== undefined) { | ||
updateFilterParams( | ||
statusFilterDataIdx, | ||
(el: TableData) => { | ||
return el.active === val; | ||
}, | ||
val | ||
); | ||
} else { | ||
updateFilterParams(statusFilterDataIdx, undefined); | ||
} | ||
}} | ||
> | ||
<Radio.Button value={true}>{t('Active')}</Radio.Button> | ||
<Radio.Button value={false}>{t('Inactive')}</Radio.Button> | ||
<Radio.Button value={undefined}>{t('Show all')}</Radio.Button> | ||
</Radio.Group> | ||
</Space> | ||
</Trans> | ||
</Space> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.