Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DONT MERGE #376

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
1 change: 0 additions & 1 deletion resources/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,5 @@ def main():
f.write(ndjson.dumps(resources).encode())



if __name__ == "__main__":
main()
5 changes: 3 additions & 2 deletions src/components/BaseLayout/Sidebar/SidebarBottom/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ interface Props extends React.HTMLAttributes<HTMLDivElement> {
collapsed: boolean;
toggleCollapsed?: () => void;
onItemClick?: () => void;
enableLocaleSwitcher?: boolean;
}

export function SidebarBottom(props: Props) {
const { collapsed, toggleCollapsed, onItemClick, ...other } = props;
const { collapsed, toggleCollapsed, onItemClick, enableLocaleSwitcher = true, ...other } = props;
const appToken = getToken();
const isAnonymousUser = !appToken;

Expand All @@ -50,7 +51,7 @@ export function SidebarBottom(props: Props) {
{...other}
>
<S.Divider $hidden={collapsed} />
<LocaleSwitcher onItemClick={onItemClick} />
{enableLocaleSwitcher && <LocaleSwitcher onItemClick={onItemClick} />}
{!isAnonymousUser ? (
<>
<S.Divider $hidden={collapsed} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import s from './RepeatableGroups.module.scss';
interface RepeatableGroupsProps {
groupItem: GroupItemProps;
renderGroup?: (props: RepeatableGroupProps) => ReactNode;
buildValue?: (existingItems:Array<any>, value:any) => any;
}

function defaultBuildValue(exisingItems:Array<any>, _value:any) {
return [...exisingItems, {}];
}

export function RepeatableGroups(props: RepeatableGroupsProps) {
Expand All @@ -22,6 +27,7 @@ export function RepeatableGroups(props: RepeatableGroupsProps) {
const fieldName = [...parentPath, linkId];
const { value, onChange } = useFieldController(fieldName, questionItem);
const items = value.items && value.items.length ? value.items : required ? [{}] : [];
const buildValue = props.buildValue ?? defaultBuildValue;

return (
<div className={s.group}>
Expand Down Expand Up @@ -57,7 +63,7 @@ export function RepeatableGroups(props: RepeatableGroupsProps) {
className={s.addButton}
onClick={() => {
const existingItems = items || [];
const updatedInput = { items: [...existingItems, {}] };
const updatedInput = { items: buildValue(existingItems, value) };
onChange(updatedInput);
}}
size="small"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import _, { debounce } from 'lodash';
import { useCallback, useContext } from 'react';
import { QuestionItemProps } from 'sdc-qrf';

import { QuestionnaireItemAnswerOption, QuestionnaireResponseItemAnswer } from '@beda.software/aidbox-types';
import {
QuestionnaireItemAnswerOption,
QuestionnaireItemChoiceColumn,
QuestionnaireResponseItemAnswer,
} from '@beda.software/aidbox-types';

import { AsyncSelect, Select } from 'src/components/Select';
import { ValueSetExpandProvider } from 'src/contexts';
Expand Down Expand Up @@ -43,7 +47,7 @@ export function ChoiceQuestionSelect(props: ChoiceQuestionSelectProps) {
}

export function QuestionChoice({ parentPath, questionItem }: QuestionItemProps) {
const { linkId, answerOption, repeats, answerValueSet } = questionItem;
const { linkId, answerOption, repeats, answerValueSet, choiceColumn } = questionItem;
const fieldName = [...parentPath, linkId];

const { value, formItem, onChange, placeholder } = useFieldController(fieldName, questionItem);
Expand All @@ -55,6 +59,7 @@ export function QuestionChoice({ parentPath, questionItem }: QuestionItemProps)
<Form.Item {...formItem} data-testid="question-choice">
<ChoiceQuestionValueSet
answerValueSet={answerValueSet}
choiceColumn={choiceColumn}
value={value}
onChange={onSelect}
repeats={repeats}
Expand Down Expand Up @@ -83,10 +88,11 @@ interface ChoiceQuestionValueSetProps {
onChange: (option: any) => void;
repeats?: boolean;
placeholder?: string;
choiceColumn?: QuestionnaireItemChoiceColumn[];
}

export function ChoiceQuestionValueSet(props: ChoiceQuestionValueSetProps) {
const { answerValueSet, value, onChange, repeats = false, placeholder } = props;
const { answerValueSet, value, onChange, repeats = false, placeholder, choiceColumn } = props;
const expand = useContext(ValueSetExpandProvider);

const loadOptions = useCallback(
Expand All @@ -108,7 +114,7 @@ export function ChoiceQuestionValueSet(props: ChoiceQuestionValueSetProps) {
onChange={(v) => onChange(v)}
isOptionSelected={(option) => !!value && value?.findIndex((v) => _.isEqual(v?.value, option.value)) !== -1}
isMulti={repeats}
getOptionLabel={(o) => (getDisplay(o.value) as string) || ''}
getOptionLabel={(o) => (getDisplay(o.value, choiceColumn) as string) || ''}
placeholder={placeholder}
/>
);
Expand Down
5 changes: 3 additions & 2 deletions src/components/BaseQuestionnaireResponseForm/widgets/date.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useCallback, useMemo } from 'react';
import { QuestionItemProps } from 'sdc-qrf';

import {
FHIRDateFormat,
FHIRTimeFormat,
FHIRDateTimeFormat,
formatFHIRDate,
Expand All @@ -17,6 +16,8 @@ import { TimePicker } from 'src/components/TimePicker';

import { useFieldController } from '../hooks';

const USDateFormat = 'MM/DD/YYYY';

export function QuestionDateTime({ parentPath, questionItem }: QuestionItemProps) {
const { linkId, type } = questionItem;
const fieldName = [...parentPath, linkId, 0, 'value', type];
Expand Down Expand Up @@ -63,7 +64,7 @@ function DateTimePickerWrapper(props: DateTimePickerWrapperProps) {
let formatFunction: (value: Moment) => string;

if (type === 'date') {
format = FHIRDateFormat;
format = USDateFormat;
showTime = false;
formatFunction = formatFHIRDate;
} else if (type === 'time') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ function QuestionReferenceUnsafe<R extends Resource = any, IR extends Resource =
props: AnswerReferenceProps<R, IR>,
) {
const { debouncedLoadOptions, fieldController, repeats, placeholder } = useAnswerReference(props);
const { formItem } = fieldController;
const { formItem, disabled } = fieldController;

return (
<Form.Item {...formItem}>
Expand All @@ -200,6 +200,7 @@ function QuestionReferenceUnsafe<R extends Resource = any, IR extends Resource =
getOptionValue={(option) => getAnswerCode(option.value)}
isMulti={repeats}
placeholder={placeholder}
isDisabled={disabled}
/>
</Form.Item>
);
Expand Down
21 changes: 15 additions & 6 deletions src/components/QuestionnaireResponseForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ interface Props extends QuestionnaireResponseFormProps {
FormFooterComponent?: React.ElementType<FormFooterComponentProps>;
saveButtonTitle?: string;
cancelButtonTitle?: string;
autoSave?: boolean;
}

export const saveQuestionnaireResponseDraft = async (
Expand Down Expand Up @@ -79,18 +80,26 @@ export function onFormResponse(props: {

if (isSuccess(response)) {
if (response.data.extracted) {

let warnings: string[] = [];
response.data.extractedBundle.forEach((bundle, index) => {
bundle.entry?.forEach((entry, jndex) => {
if (entry.resource.resourceType === "OperationOutcome") {
warnings.push(`Error extrating on ${index}, ${jndex}`);
}
});
if (entry.resource.resourceType === 'OperationOutcome') {
warnings.push(`Error extrating on ${index}, ${jndex}`);
}
});
});
if (warnings.length > 0) {
notification.warning({
message: (<div>{warnings.map((w) => <div key={w}><span>{w}</span><br/></div>)}</div>),
message: (
<div>
{warnings.map((w) => (
<div key={w}>
<span>{w}</span>
<br />
</div>
))}
</div>
),
});
}

Expand Down
10 changes: 5 additions & 5 deletions src/theme/palette.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import _ from 'lodash';
import { DefaultTheme } from 'styled-components';

export const brandColors: Pick<DefaultTheme, 'primary' | 'secondary'> = {
primary: '#3366ff',
primary: '#892CE2',
secondary: '#05BDB1',
};

Expand Down Expand Up @@ -98,12 +98,12 @@ export function getPalette({ dark }: { dark?: boolean }): DefaultTheme {
dark: DefaultTheme['iconColors'];
} = {
light: {
primary: primaryPalette.bcp_6,
secondary: secondaryPalette.bcs_2,
primary: '#4E1AEF',
secondary: '#D4B3F5',
},
dark: {
primary: neutralPalette.dark.gray_12,
secondary: neutralPalette.dark.gray_6,
primary: '#49B5FF',
secondary: '#A76EB1',
},
};

Expand Down
35 changes: 35 additions & 0 deletions src/utils/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ export const humanDateYearMonth = 'MMM YYYY';
export const humanTime = 'HH:mm';
export const humanDateTime = 'DD MMM YYYY HH:mm';

export const humanDateUS = 'MM/DD/YYYY';
export const humanDateYearMonthUS = 'MM/YYYY';
export const humanTimeUS = 'hh:mm A';
export const humanDateTimeUS = 'MM/DD/YYYY hh:mm A';

export const formatHumanDateTime = (date?: string) => {
if (!date) {
return '';
Expand All @@ -16,6 +21,14 @@ export const formatHumanDateTime = (date?: string) => {
return parseFHIRDateTime(date).format(humanDateTime);
};

export const formatHumanDateTimeUS = (date?: string) => {
if (!date) {
return '';
}

return parseFHIRDateTime(date).format(humanDateTimeUS);
};

export const formatHumanDate = (date?: string) => {
if (!date) {
return '';
Expand All @@ -38,6 +51,28 @@ export const formatHumanDate = (date?: string) => {
return parseFHIRDateTime(date).format(humanDate);
};

export const formatHumanDateUS = (date?: string) => {
if (!date) {
return '';
}

// Year only 2000
if (date.length === 4) {
return date;
}

// Year and month 2000-01
if (date.length === 7) {
return parseFHIRDate(date + '-01').format(humanDateYearMonthUS);
}

if (date.length === 10) {
return parseFHIRDate(date).format(humanDateUS);
}

return parseFHIRDateTime(date).format(humanDateUS);
};

export function formatPeriodDateTime(period?: Period) {
const timeRange = _.compact([
period?.start ? parseFHIRDateTime(period.start).format('HH:mm') : undefined,
Expand Down
2 changes: 1 addition & 1 deletion src/utils/fhir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export function renderHumanName(name?: HumanName) {
}

return (
`${name?.prefix?.[0] ?? ''} ${name?.given?.[0] ?? ''} ${name?.family ?? ''} ${
`${name?.prefix?.[0] ?? ''} ${name?.given?.[0] ?? ''} ${name?.given?.[1] ?? ''} ${name?.family ?? ''} ${
name?.suffix?.[0] ?? ''
} `.trim() ||
name.text ||
Expand Down
14 changes: 13 additions & 1 deletion src/utils/questionnaire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,31 @@ import * as yup from 'yup';
import {
Questionnaire,
QuestionnaireItemAnswerOption,
QuestionnaireItemChoiceColumn,
QuestionnaireResponseItemAnswer,
QuestionnaireResponseItemAnswerValue,
} from '@beda.software/aidbox-types';
import { parseFHIRTime } from '@beda.software/fhir-react';

import { formatHumanDate, formatHumanDateTime } from './date';
import fhirpath from 'fhirpath';

export function getDisplay(value?: QuestionnaireResponseItemAnswerValue): string | number | null {
export function getDisplay(
value?: QuestionnaireResponseItemAnswerValue,
choiceColumn?: QuestionnaireItemChoiceColumn[],
): string | number | null {
if (!value) {
return null;
}

if (value.Coding) {
if (choiceColumn && choiceColumn.length) {
const expression = choiceColumn[0]!.path;
if (expression) {
const calculatedValue = fhirpath.evaluate(value.Coding, expression)[0];
return calculatedValue ?? '';
}
}
return value.Coding.display ?? '';
}

Expand Down