Skip to content

Commit

Permalink
Merge pull request #384 from beda-software/354-generic-resource-list
Browse files Browse the repository at this point in the history
WIP Add ResourceList component. Refs #354
  • Loading branch information
ir4y authored Jan 17, 2025
2 parents eaac4bd + 90c86bb commit 6356f9c
Show file tree
Hide file tree
Showing 34 changed files with 1,172 additions and 35 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
"exports": {
".": null,
"./components": "./dist/components/index.js",
"./uberComponents": "./dist/uberComponents/index.js",
"./containers": "./dist/containers/index.js",
"./services": "./dist/services/index.js",
"./hooks": "./dist/hooks/index.js",
Expand Down
6 changes: 3 additions & 3 deletions src/components/QuestionnaireResponseForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { saveFHIRResource, updateFHIRResource } from 'src/services/fhir';
import { FormFooterComponentProps } from '../BaseQuestionnaireResponseForm/FormFooter';
import { Spinner } from '../Spinner';

interface Props extends QuestionnaireResponseFormProps {
export interface QRFProps extends QuestionnaireResponseFormProps {
onSuccess?: (response: QuestionnaireResponseFormSaveResponse) => void;
onFailure?: (error: any) => void;
readOnly?: boolean;
Expand Down Expand Up @@ -126,7 +126,7 @@ export function onFormResponse(props: {
}
}

export function useQuestionnaireResponseForm(props: Props) {
export function useQuestionnaireResponseForm(props: QRFProps) {
// TODO find what cause rerender and fix it
// remove this temporary hack
const memoizedProps = useMemo(() => props, [JSON.stringify(props)]);
Expand All @@ -152,7 +152,7 @@ export function useQuestionnaireResponseForm(props: Props) {
return { response, onSubmit, readOnly, onCancel };
}

export function QuestionnaireResponseForm(props: Props) {
export function QuestionnaireResponseForm(props: QRFProps) {
const { response, onSubmit, readOnly, onCancel } = useQuestionnaireResponseForm(props);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { SearchBarColumnChoiceTypeProps } from '../../types';
import { useChoiceColumn } from '../hooks';

export function SelectChoiceColumn(props: SearchBarColumnChoiceTypeProps) {
const { columnFilterValue } = props;
const { columnFilterValue, defaultOpen } = props;
const { options, placeholder, repeats } = columnFilterValue.column;

const { onSelect, getOptionLabel, isOptionSelected } = useChoiceColumn(props);
Expand All @@ -23,6 +23,8 @@ export function SelectChoiceColumn(props: SearchBarColumnChoiceTypeProps) {
getOptionLabel={getOptionLabel}
classNamePrefix="react-select"
placeholder={placeholder}
defaultMenuIsOpen={defaultOpen}
isClearable
/>
</Col>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { SearchBarColumnChoiceTypeProps } from '../../types';
import { useChoiceColumn } from '../hooks';

export function ValueSetColumn(props: SearchBarColumnChoiceTypeProps) {
const { columnFilterValue } = props;
const { columnFilterValue, defaultOpen } = props;
const { placeholder, repeats } = columnFilterValue.column;

const { onSelect, isOptionSelected, getOptionLabel, debouncedLoadOptions } = useChoiceColumn(props);
Expand All @@ -22,6 +22,8 @@ export function ValueSetColumn(props: SearchBarColumnChoiceTypeProps) {
isOptionSelected={isOptionSelected}
getOptionLabel={getOptionLabel}
placeholder={placeholder}
defaultMenuIsOpen={defaultOpen}
isClearable
/>
</Col>
);
Expand Down
2 changes: 2 additions & 0 deletions src/components/SearchBar/SearchBarColumn/DateColumn/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export function useDateColumn(props: SearchBarColumnDateTypeProps) {
const momentValues = values.map((value) => moment(value!.format())) as DateColumnFilterValue;

onChange(momentValues, columnFilterValue.column.id);
} else {
onChange(undefined, columnFilterValue.column.id);
}
},
[onChange, columnFilterValue],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { SearchBarColumnDateTypeProps } from '../types';
const { RangePicker } = DatePicker;

export function DateColumn(props: SearchBarColumnDateTypeProps) {
const { columnFilterValue } = props;
const { columnFilterValue, defaultOpen } = props;

const { onColumnChange } = useDateColumn(props);

Expand All @@ -18,6 +18,8 @@ export function DateColumn(props: SearchBarColumnDateTypeProps) {
placeholder={columnFilterValue.column.placeholder}
value={columnFilterValue.value}
onChange={onColumnChange}
defaultOpen={defaultOpen}
allowClear
/>
</Col>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useReferenceColumn } from './hooks';
import { SearchBarColumnReferenceTypeProps } from '../types';

export function ReferenceColumn(props: SearchBarColumnReferenceTypeProps) {
const { columnFilterValue } = props;
const { columnFilterValue, defaultOpen } = props;

const { debouncedLoadOptions, onOptionChange } = useReferenceColumn(props);

Expand All @@ -22,6 +22,8 @@ export function ReferenceColumn(props: SearchBarColumnReferenceTypeProps) {
getOptionValue={(option) => getAnswerCode(option.value)}
isMulti={false}
placeholder={columnFilterValue.column.placeholder}
defaultMenuIsOpen={defaultOpen}
isClearable
/>
</Col>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export function StringColumn(props: SearchBarColumnStringTypeProps) {
placeholder={columnFilterValue.column.placeholder}
value={columnFilterValue.value}
onChange={onColumnChange}
allowClear
/>
</Col>
);
Expand Down
8 changes: 4 additions & 4 deletions src/components/SearchBar/SearchBarColumn/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from '../types';

export function SearchBarColumn(props: SearchBarColumnProps) {
const { columnFilterValue } = props;
const { columnFilterValue, defaultOpen } = props;

if (isStringColumnFilterValue(columnFilterValue)) {
const stringProps = {
Expand All @@ -26,23 +26,23 @@ export function SearchBarColumn(props: SearchBarColumnProps) {
...props,
columnFilterValue,
};
return <DateColumn {...dateProps} />;
return <DateColumn {...dateProps} defaultOpen={defaultOpen} />;
}

if (isReferenceColumnFilterValue(columnFilterValue)) {
const referenceProps = {
...props,
columnFilterValue,
};
return <ReferenceColumn {...referenceProps} />;
return <ReferenceColumn {...referenceProps} defaultOpen={defaultOpen} />;
}

if (isChoiceColumnFilterValue(columnFilterValue)) {
const choiceProps = {
...props,
columnFilterValue,
};
return <ChoiceColumn {...choiceProps} />;
return <ChoiceColumn {...choiceProps} defaultOpen={defaultOpen} />;
}

return null;
Expand Down
4 changes: 4 additions & 0 deletions src/components/SearchBar/SearchBarColumn/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
export type SearchBarColumnProps = {
columnFilterValue: ColumnFilterValue;
onChange: (value: ColumnFilterValue['value'], key: string) => void;
defaultOpen?: boolean;
};

export interface SearchBarColumnStringTypeProps {
Expand All @@ -19,14 +20,17 @@ export interface SearchBarColumnStringTypeProps {
export interface SearchBarColumnDateTypeProps {
columnFilterValue: DateTypeColumnFilterValue;
onChange: (value: DateTypeColumnFilterValue['value'], key: string) => void;
defaultOpen?: boolean;
}

export interface SearchBarColumnReferenceTypeProps {
columnFilterValue: ReferenceTypeColumnFilterValue;
onChange: (value: ReferenceTypeColumnFilterValue['value'], key: string) => void;
defaultOpen?: boolean;
}

export interface SearchBarColumnChoiceTypeProps {
columnFilterValue: ChoiceTypeColumnFilterValue;
onChange: (value: ChoiceTypeColumnFilterValue['value'], key: string) => void;
defaultOpen?: boolean;
}
8 changes: 7 additions & 1 deletion src/components/SearchBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@ import { Button, Row } from 'antd';
import { S } from './SearchBar.styles';
import { SearchBarColumn } from './SearchBarColumn';
import { SearchBarData } from './types';
import { isSearchBarFilter } from './utils';
import { useMemo } from 'react';

export function SearchBar(props: SearchBarData) {
const { columnsFilterValues, onChangeColumnFilter, onResetFilters } = props;
const searchBarFilterValues = useMemo(
() => columnsFilterValues.filter((filter) => isSearchBarFilter(filter)),
[JSON.stringify(columnsFilterValues)],
);

return (
<S.Container>
<Row gutter={[32, 16]}>
{columnsFilterValues.map((columnFilterValue) => (
{searchBarFilterValues.map((columnFilterValue) => (
<SearchBarColumn
key={`search-bar-column-${columnFilterValue.column.id}`}
columnFilterValue={columnFilterValue}
Expand Down
36 changes: 21 additions & 15 deletions src/components/SearchBar/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,44 @@ export enum SearchBarColumnType {
export interface SearchBarProps {
columns: SearchBarColumn[];
}
export type SearchBarStringColumn = {

type SearchBarColumnBase = {
// if placement is table then id should be matched with table column key
id: string;
searchParam?: string;
// placement = 'search-bar' by default
placement?: Array<'search-bar' | 'table'>;
};

export type SearchBarStringColumn = SearchBarColumnBase & {
type: SearchBarColumnType.STRING;
placeholder: string;
};
export type SearchBarDateColumn = {
id: string;
export type SearchBarDateColumn = SearchBarColumnBase & {
type: SearchBarColumnType.DATE;
placeholder: [string, string];
};
export type SearchBarReferenceColumn = {
export type SearchBarReferenceColumn = SearchBarColumnBase & {
id: string;
type: SearchBarColumnType.REFERENCE;
expression: Expression['expression'];
path: QuestionnaireItemChoiceColumn['path'];
placeholder: string;
};
export type SearchBarChoiceColumn = {
id: string;
export type SearchBarChoiceColumn = SearchBarColumnBase & {
type: SearchBarColumnType.CHOICE;
repeats?: boolean;
placeholder: string;
} & (
| {
options: ValueSetOption[];
valueSet?: never;
}
| {
options?: never;
valueSet: ValueSet['id'];
}
);
| {
options: ValueSetOption[];
valueSet?: never;
}
| {
options?: never;
valueSet: ValueSet['id'];
}
);

export type SearchBarColumn =
| SearchBarStringColumn
Expand Down
16 changes: 16 additions & 0 deletions src/components/SearchBar/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export function getSearchBarFilterValue(filterValues: ColumnFilterValue[] | unde
throw new Error('Filter value not found');
}

return getSearchBarColumnFilterValue(filterValue);
}

export function getSearchBarColumnFilterValue(filterValue: ColumnFilterValue) {
if (isStringColumnFilterValue(filterValue)) {
return filterValue.value;
}
Expand All @@ -39,3 +43,15 @@ export function getSearchBarFilterValue(filterValues: ColumnFilterValue[] | unde

throw new Error('Unsupported column type');
}

export function isSearchBarFilter(filter: ColumnFilterValue) {
const { placement = ['search-bar'] } = filter.column;

return placement.includes('search-bar');
}

export function isTableFilter(filter: ColumnFilterValue) {
const { placement = ['search-bar'] } = filter.column;

return placement.includes('table');
}
45 changes: 45 additions & 0 deletions src/components/Table/TableFilter/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { ColumnFilterValue, isStringColumn } from 'src/components/SearchBar/types';
import { SearchBarColumn } from 'src/components/SearchBar/SearchBarColumn';
import { S } from './styles';
import { FilterDropdownProps } from 'antd/lib/table/interface';
import _ from 'lodash';

interface Props {
filter: ColumnFilterValue;
onChange: (value: ColumnFilterValue['value'], key: string) => void;
}

interface TableFilterProps extends FilterDropdownProps, Props {}

export function TableFilter(props: TableFilterProps) {
const { filter, onChange: onInitialChange, close, visible } = props;

const onChange = (value: ColumnFilterValue['value'], key: string) => {
if (isStringColumn(filter.column)) {
onInitialChange(value, key);

return;
}

onInitialChange(value, key);
close();
};

// if (isSingleDateColumn(filter.column)) {
// return (
// <S.Container>
// <S.DatePickerFilter>
// <SearchBarColumn columnFilterValue={filter} onChange={onChange} defaultOpen={visible} />
// </S.DatePickerFilter>
// </S.Container>
// );
// }

return (
<S.Container>
<S.Filter>
<SearchBarColumn columnFilterValue={filter} onChange={onChange} defaultOpen={visible} />
</S.Filter>
</S.Container>
);
}
Loading

0 comments on commit 6356f9c

Please sign in to comment.