Skip to content

Commit

Permalink
Merge branch '354-generic-resource-list' of github.com:beda-software/…
Browse files Browse the repository at this point in the history
…fhir-emr into update-app-layout
  • Loading branch information
vesnushka committed Dec 16, 2024
2 parents 8cff01f + b66ec50 commit 531711a
Show file tree
Hide file tree
Showing 9 changed files with 271 additions and 152 deletions.
94 changes: 82 additions & 12 deletions src/components/AudioRecorder/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,29 @@ import { RecorderControls } from './hooks';
import { S } from './styles';
import { uuid4 } from '@beda.software/fhir-react';
import { Upload, type UploadFile } from 'antd';
import React from 'react';
import { RcFile } from 'antd/lib/upload/interface';
import { DeleteOutlined } from '@ant-design/icons';
import { Text } from 'src/components/Typography';

interface AudioRecorderProps {
onChange: (url: RcFile) => Promise<void>;
recorderControls: RecorderControls;
}

function checkIfSafari() {
const userAgent = navigator.userAgent;
const isSafari = userAgent.includes('Safari') && !userAgent.includes('Chrome');
return isSafari;
}

export function AudioRecorder(props: AudioRecorderProps) {
const { recorderControls, onChange } = props;

const onRecordingComplete = async (blob: Blob) => {
const uuid = uuid4();
const audioFile = new File([blob], `${uuid}.webm`, { type: blob.type }) as RcFile;
const audioTypeWithoutCodecs = blob.type.split(';')[0] ?? '';
const audioExt = audioTypeWithoutCodecs.split('/')[1];
const audioFile = new File([blob], `${uuid}.${audioExt}`, { type: blob.type }) as RcFile;
audioFile.uid = uuid;
onChange(audioFile);
};
Expand All @@ -29,6 +38,7 @@ export function AudioRecorder(props: AudioRecorderProps) {
<S.Title $danger>
<Trans>Capture in progress</Trans>
</S.Title>
{/* Do not include downloadFileExtension so Safari could record mp4 and Chrome webm */}
<AudioRecorderControl
showVisualizer
onRecordingComplete={onRecordingComplete}
Expand All @@ -50,24 +60,84 @@ interface AudioPlayerProps {
}

export function AudioPlayer(props: AudioPlayerProps) {
const { files, onRemove } = props;
const { files } = props;

return (
<S.Scriber>
<S.Title>
<Trans>Listen to the audio</Trans>
</S.Title>
{files.map((file) => (
<React.Fragment key={file.uid}>
<S.Audio controls src={file.url} />
<Upload
listType="text"
showUploadList={{ showRemoveIcon: !!onRemove }}
fileList={[file]}
onRemove={() => onRemove?.(file)}
/>
</React.Fragment>
<AudioPlayerRecord key={file.name} file={file} {...props} />
))}
</S.Scriber>
);
}

interface AudioPlayerRecordProps {
file: UploadFile;
onRemove?: (file: UploadFile) => void;
}

export function AudioPlayerRecord(props: AudioPlayerRecordProps) {
const { file, onRemove } = props;
const audioExt = file.name.split('.')[1];
const isSafari = checkIfSafari();
const isWebm = audioExt === 'webm';

return (
<>
{file.url && file.name === file.uid ? (
<>
{isSafari && isWebm ? (
<Text>
<Trans>
This audio cannot be played in Safari, please download the audio or use the Chrome browser
</Trans>
</Text>
) : (
<S.Audio controls preload="none">
<source src={file.url} type={`audio/${audioExt}`} />
<Text>
<Trans>Your browser does not support the audio element</Trans>
</Text>
</S.Audio>
)}
</>
) : null}
<Upload
listType="text"
showUploadList={{ showRemoveIcon: !!onRemove }}
fileList={[file]}
onRemove={() => onRemove?.(file)}
itemRender={(originNode, file) => {
if (file.url) {
return (
<S.File>
<a
target="_blank"
rel="noopener noreferrer"
className="ant-upload-list-item-name"
title={file.name}
href={file.url}
>
<Trans>Download audio</Trans>
</a>
{onRemove ? (
<S.Button
type="text"
onClick={() => onRemove(file)}
icon={<DeleteOutlined />}
size="small"
/>
) : null}
</S.File>
);
}

return originNode;
}}
/>
</>
);
}
10 changes: 10 additions & 0 deletions src/components/AudioRecorder/styles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import styled, { css } from 'styled-components';

import { Text } from 'src/components/Typography';
import { Button } from 'antd';

export const S = {
Scriber: styled.div`
Expand Down Expand Up @@ -47,4 +48,13 @@ export const S = {
height: 52px;
width: 100%;
`,
File: styled.div`
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 7px;
`,
Button: styled(Button)`
padding: 0;
`,
};
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Upload } from 'antd';
import { QuestionItemProps } from 'sdc-qrf';
import classNames from 'classnames';

import s from './ReadonlyWidgets.module.scss';
import { S } from './ReadonlyWidgets.styles';
import { useUploader } from '../widgets/UploadFileControl/hooks';
import React from 'react';
import { AudioPlayerRecord } from 'src/components/AudioRecorder';

export function AudioAttachment(props: QuestionItemProps) {
const { questionItem } = props;
Expand All @@ -20,12 +19,7 @@ export function AudioAttachment(props: QuestionItemProps) {
<S.Question className={classNames(s.question, s.column, 'form__question')}>
<span className={s.questionText}>{text}</span>
{fileList.length ? (
fileList.map((file) => (
<React.Fragment key={file.url}>
<S.Audio controls src={file.url} />
<Upload listType="text" showUploadList={{ showRemoveIcon: false }} fileList={fileList} />
</React.Fragment>
))
fileList.map((file) => <AudioPlayerRecord key={file.name} file={file} />)
) : (
<span>-</span>
)}
Expand Down
2 changes: 1 addition & 1 deletion src/components/QuestionnaireResponseForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export function onFormResponse(props: {
const warnings: string[] = [];
response.data.extractedBundle.forEach((bundle, index) => {
bundle.entry?.forEach((entry, jndex) => {
if (entry.resource.resourceType === 'OperationOutcome') {
if (entry.resource?.resourceType === 'OperationOutcome') {
warnings.push(`Error extracting on ${index}, ${jndex}`);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,14 @@ export function usePatientDocument(props: Props): {
}

if (isSuccess(provenanceResponse)) {
const provenance = provenanceResponse.data[0];
const descSortedProvenances = [...provenanceResponse.data].sort((a, b) =>
b.recorded.localeCompare(a.recorded),
);
const lastProvenance = descSortedProvenances[0];

const formInitialParams = prepareFormInitialParams({
...props,
provenance,
provenance: lastProvenance,
});

const onSubmit = async (formData: QuestionnaireResponseFormData) =>
Expand All @@ -165,7 +169,7 @@ export function usePatientDocument(props: Props): {
return {
formData,
onSubmit,
provenance,
provenance: lastProvenance,
};
},
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ interface LinkToEditProps {
export function LinkToEdit(props: LinkToEditProps) {
const { name, resource, provenanceList, to } = props;
const location = useLocation();
const provenance = provenanceList.find(
(p) =>
fromFHIRReference(p.target[0])?.id === resource.id &&
fromFHIRReference(p.target[0])?.resourceType === resource.resourceType,
);
const provenance = provenanceList.find((provenance) => {
const targets = provenance.target || [];

return targets.find((target) => {
return (
fromFHIRReference(target)?.id === resource.id &&
fromFHIRReference(target)?.resourceType === resource.resourceType
);
});
});
const entity = provenance?.entity?.[0]?.what;
const qrId = fromFHIRReference(entity)?.id;

Expand Down
Loading

0 comments on commit 531711a

Please sign in to comment.