Skip to content

Commit

Permalink
Merge branch 'master' into detail-page
Browse files Browse the repository at this point in the history
  • Loading branch information
pavlushkin committed Jan 30, 2025
2 parents c889d1c + ac35cb0 commit 93c4771
Show file tree
Hide file tree
Showing 20 changed files with 469 additions and 131 deletions.
100 changes: 100 additions & 0 deletions resources/seeds/Questionnaire/repeatable-group-full-example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
id: repeatable-group-full-example
name: Repeatable Group Full Example
title: Repeatable Group Full Example
status: active
meta:
profile:
- https://beda.software/beda-emr-questionnaire
subjectType:
- Encounter
- Patient
item:
- type: group
linkId: main-group
item:
- type: group
text: Main card
linkId: main-group-card
itemControl:
coding:
- code: main-card
item:
- text: Text01
type: string
linkId: text01
- text: Text02
type: string
linkId: text02
- type: group
text: Sub card
linkId: sub-group-card
itemControl:
coding:
- code: sub-card
item:
- text: Text03
type: string
linkId: text03
- text: Text04
type: string
linkId: text04
- type: group
linkId: primary-group
text: "Example 1: main-card + row + section-with-divider"
itemControl:
coding:
- code: section-with-divider
item:
- type: group
linkId: group11
repeats: true
text: Main card
itemControl:
coding:
- code: main-card
item:
- type: group
linkId: group12
repeats: true
text: service
itemControl:
coding:
- code: row
item:
- text: Text1
type: string
linkId: text11
- text: Text2
type: string
linkId: text12
- type: group
linkId: secondary-group
text: "Example 2: sub-card + section"
itemControl:
coding:
- code: section
item:
- type: group
linkId: group21
repeats: true
text: Sub card
itemControl:
coding:
- code: sub-card
item:
- text: Text1
type: string
linkId: text21
- type: group
linkId: group22
itemControl:
coding:
- code: row
item:
- text: Text2
type: string
linkId: text22
- text: Text3
type: string
linkId: text23
resourceType: Questionnaire
2 changes: 1 addition & 1 deletion resources/seeds/Questionnaire/repeatable-group.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ item:
type: group
linkId: repeatable-group
repeats: true
resourceType: Questionnaire
resourceType: Questionnaire
10 changes: 9 additions & 1 deletion src/components/BaseQuestionnaireResponseForm/controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,19 @@ import {
QuestionQuantity,
Grid,
MDEditorControl,
Section,
SectionWithDivider,
MainCard,
SubCard,
} from './widgets';
import { AudioRecorderUploader } from './widgets/AudioRecorderUploader';
import { Display } from './widgets/display';
import { GroupWizard, GroupWizardWithTooltips } from './widgets/GroupWizard';
import { PasswordInput } from './widgets/PasswordInput';
import { QuestionReference } from './widgets/reference';
import { ReferenceRadioButton } from './widgets/ReferenceRadioButton';
import { UploadFileControl } from './widgets/UploadFileControl';
import { TextWithMacroFill } from '../TextWithMacroFill';
import { AudioRecorderUploader } from './widgets/AudioRecorderUploader';

export const itemComponents: QuestionItemComponentMapping = {
text: QuestionText,
Expand Down Expand Up @@ -76,6 +80,10 @@ export const groupControlComponents: ItemControlGroupItemComponentMapping = {
gtable: Gtable,
table: Gtable,
grid: Grid,
section: Section,
'section-with-divider': SectionWithDivider,
'main-card': MainCard,
'sub-card': SubCard,
'blood-pressure': BloodPressure,
'time-range-picker': TimeRangePickerControl,
wizard: GroupWizard,
Expand Down
3 changes: 2 additions & 1 deletion src/components/BaseQuestionnaireResponseForm/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export function useFieldController(fieldName: any, questionItem: QuestionnaireIt

const onMultiChange = useCallback(
(option: any) => {
// NOTE: it's used online in inline-choice
if (repeats) {
const arrayValue = (field.value ?? []) as any[];
const valueIndex = arrayValue.findIndex((v) => _.isEqual(v?.value, option.value));
Expand All @@ -49,7 +50,7 @@ export function useFieldController(fieldName: any, questionItem: QuestionnaireIt
field.onChange(arrayValue);
}
} else {
field.onChange(option);
field.onChange([option]);
}
},
[repeats, field],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { DeleteOutlined } from '@ant-design/icons';
import { t, Trans } from '@lingui/macro';
import { Button } from 'antd';
import React from 'react';
import { GroupItemProps, QuestionItems } from 'sdc-qrf';

import { Title } from 'src/components/Typography';

import { S } from './styles';
import { RepeatableGroupCard, RepeatableGroups } from '../RepeatableGroups';

interface GroupCardProps extends GroupItemProps {
variant?: 'main-card' | 'sub-card';
}

export function GroupCard(props: GroupCardProps) {
const { parentPath, questionItem, context, variant = 'main-card' } = props;
const { linkId, item, repeats, text, hidden } = questionItem;

if (hidden) {
return null;
}

const renderCardContent = () => {
return (
item && (
<QuestionItems
questionItems={item}
parentPath={[...parentPath, linkId, 'items']}
context={context[0]!}
/>
)
);
};

// TODO: display helpText

if (repeats) {
if (variant === 'sub-card') {
return (
<RepeatableGroups
groupItem={props}
renderGroup={(p) => <RepeatableGroupCard {...p} variant="sub-card" />}
/>
);
}

return <RepeatableGroups groupItem={props} />;
}

if (variant === 'sub-card') {
return <GroupSubCard title={text}>{renderCardContent()}</GroupSubCard>;
}

return <GroupMainCard title={text}>{renderCardContent()}</GroupMainCard>;
}

interface CardProps {
children: React.ReactNode;
title?: React.ReactNode;
onRemove?: () => void;
readOnly?: boolean;
}

export function GroupMainCard(props: CardProps) {
const { title = t`Group`, children, readOnly, onRemove: initialOnRemove } = props;
const onRemove = readOnly ? undefined : initialOnRemove;

return (
<S.Card
title={<Title level={4}>{title}</Title>}
$variant={'main-card'}
extra={
onRemove ? (
<Button type="default" onClick={onRemove} size="middle" icon={<DeleteOutlined />}>
<span>
<Trans>Remove</Trans>
</span>
</Button>
) : null
}
>
<S.GroupContent>{children}</S.GroupContent>
</S.Card>
);
}

export function GroupSubCard(props: CardProps) {
const { title = t`Group`, children, readOnly, onRemove: initialOnRemove } = props;
const onRemove = readOnly ? undefined : initialOnRemove;

return (
<S.Card
title={<Title level={5}>{title}</Title>}
$variant={'sub-card'}
extra={
onRemove ? <Button icon={<DeleteOutlined />} type="default" onClick={onRemove} size="middle" /> : null
}
>
<S.GroupContent>{children}</S.GroupContent>
</S.Card>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Card } from 'antd';
import styled, { css } from 'styled-components';

export const S = {
Card: styled(Card)<{ $variant: 'main-card' | 'sub-card' }>`
.ant-card-head {
background-color: ${({ theme }) => theme.neutralPalette.gray_3};
}
${({ $variant }) =>
$variant === 'sub-card' &&
css`
.ant-card-head {
background-color: ${({ theme }) => theme.neutralPalette.gray_2};
}
`}
`,
GroupContent: styled.div`
display: flex;
flex-direction: column;
gap: 16px;
width: 100%;
`,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { t } from '@lingui/macro';
import { QuestionItems } from 'sdc-qrf';

import { useRepeatableGroup, type RepeatableGroupProps } from '.';
import { GroupMainCard, GroupSubCard } from '../GroupCard';

interface Props extends RepeatableGroupProps {
variant?: 'main-card' | 'sub-card';
}

export function RepeatableGroupCard(props: Props) {
const { index, groupItem, variant } = props;
const { questionItem } = groupItem;
const { item, text, readOnly } = questionItem;
const { onRemove, parentPath, context } = useRepeatableGroup(props);

const getTitle = () => {
if (text) {
return `${text} ${index + 1}`;
}

return t`Item ${index + 1}`;
};

if (variant === 'sub-card') {
return (
<GroupSubCard title={getTitle()} onRemove={onRemove} readOnly={readOnly}>
<QuestionItems questionItems={item!} parentPath={parentPath} context={context} />
</GroupSubCard>
);
}

return (
<GroupMainCard title={getTitle()} onRemove={onRemove} readOnly={readOnly}>
<QuestionItems questionItems={item!} parentPath={parentPath} context={context} />
</GroupMainCard>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { DeleteOutlined } from '@ant-design/icons';
import { Button } from 'antd';
import { QuestionItems } from 'sdc-qrf';

import { RepeatableGroupProps, useRepeatableGroup } from '.';
import { S } from './styles';

export function RepeatableGroupRow(props: RepeatableGroupProps) {
const { groupItem } = props;
const { questionItem } = groupItem;
const { item, readOnly } = questionItem;
const { onRemove, parentPath, context } = useRepeatableGroup(props);

return (
<S.Row>
<S.RowItems>
<QuestionItems questionItems={item!} parentPath={parentPath} context={context} />
</S.RowItems>
{!readOnly ? (
<S.RowControls>
<Button icon={<DeleteOutlined />} type="default" onClick={onRemove} size="middle" />
</S.RowControls>
) : null}
</S.Row>
);
}

This file was deleted.

Loading

0 comments on commit 93c4771

Please sign in to comment.