Skip to content

Commit

Permalink
Merge branch 'master' into medication-management
Browse files Browse the repository at this point in the history
  • Loading branch information
projkov committed Nov 28, 2023
2 parents fe6a868 + 41cdd00 commit 9225456
Show file tree
Hide file tree
Showing 14 changed files with 160 additions and 69 deletions.
5 changes: 4 additions & 1 deletion .env.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ CHROMATIC_PROJECT_TOKEN=
# Set up variable below if you'd to configure video calls service
AUTH_JWT_SECRET=
AUTH_JWT_ACCEPTED_ISSUERS=
AUTH_JWT_ACCEPTED_AUDIENCES=f
AUTH_JWT_ACCEPTED_AUDIENCES=

# DATASEQUENCE service JWT generation secret
DATASEQUENCE_JWT_SECRET=
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ __Promo web page__: [beda.software/emr](https://beda.software/emr)

__Design__: [Figma](https://www.figma.com/file/2bxMDfG3lRPEZpRwDC4gTB/SaaS-EMR-System)

__Documentation__: https://doc.emr.beda.software/
__Documentation__: https://docs.emr.beda.software/

## Benefits

Expand Down
14 changes: 5 additions & 9 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,8 @@ services:
depends_on:
datastream-timescaledb:
condition: service_healthy
environment:
TIMESCALEDB_SERVICE_NAME: datastream-timescaledb
PGUSER: postgres
PGPASSWORD: postgres
env_file:
- ./env/ingestion
datastream:
image: bedasoftware/fhir-datasequence:latest
depends_on:
Expand All @@ -100,14 +98,12 @@ services:
condition: service_completed_successfully
ports:
- '8082:8081'
env_file:
- ./env/ingestion
environment:
- TIMESCALEDB_SERVICE_NAME=datastream-timescaledb
- PGUSER=postgres
- PGPASSWORD=postgres
- EMR_WEB_URL=http://localhost:3000
- METRIPORT_USE_SANDBOX=true
- METRIPORT_WEBHOOK_AUTH_KEY
- METRIPORT_API_SECRET
- JWT_TOKEN_ENCODE_SECRET=${DATASEQUENCE_JWT_SECRET}
jute:
image: bedasoftware/jute-microservice:latest
ports:
Expand Down
4 changes: 4 additions & 0 deletions env/ingestion
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
TIMESCALEDB_SERVICE_NAME=datastream-timescaledb
PGUSER=postgres
PGPASSWORD=postgres
EMR_WEB_URL=http://localhost:3000
8 changes: 4 additions & 4 deletions resources/seeds/Questionnaire/data-sharing-consent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ item:
answerOption:
- value:
Coding:
code: "deny"
code: "permit"
system: http://hl7.org/fhir/consent-provision-type
display: Deny
display: Allow access
- value:
Coding:
code: "permit"
code: "deny"
system: http://hl7.org/fhir/consent-provision-type
display: Permit
display: Deny access
- text: Date start
type: date
linkId: date-start
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ item:
expression: "Patient?_count=25"
choiceColumn:
- forDisplay: true
path: "name.given.first() + ' ' + name.family"
path: "name.first().given.first() + ' ' + name.first().family"
- text: Start time
required: true
type: dateTime
Expand Down
4 changes: 2 additions & 2 deletions resources/seeds/Questionnaire/new-appointment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ item:
boolean: false
answerExpression:
language: application/x-fhir-query
expression: "Patient"
expression: "Patient?_count=25"
choiceColumn:
- forDisplay: true
path: "name.given.first() + ' ' + name.family"
path: "name.first().given.first() + ' ' + name.first().family"
- text: Service
type: reference
referenceResource:
Expand Down
2 changes: 0 additions & 2 deletions src/containers/QuestionnaireBuilder/Builder/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ export function Builder(props: Props) {
resourceType: 'QuestionnaireResponse',
status: 'completed',
});
console.log('FHIR Questionnaire', questionnaire);
console.log('formData', formData);
const title = formData.context.questionnaire.title || formData.context.questionnaire.name;

if (questionnaire.item) {
Expand Down
48 changes: 38 additions & 10 deletions src/containers/QuestionnaireBuilder/PromptForm.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DeleteOutlined } from '@ant-design/icons';
import { t } from '@lingui/macro';
import { Button, Form, Input } from 'antd';
import { Button, Form, Input, Timeline } from 'antd';
import { FormProps } from 'antd/lib/form';
import { useState } from 'react';

import s from './QuestionnaireBuilder.module.scss';

Expand All @@ -13,24 +13,56 @@ interface PromptFormInterface {

interface Props extends FormProps {
onSubmit: (prompt: string) => Promise<any>;
onPromptSelect: (prompt: string) => void;
editHistory: object;
onPromptDelete: (prompt: string) => void;
selectedPrompt?: string;
isLoading?: boolean;
visible?: boolean;
}

export function PromptForm(props: Props) {
const { onSubmit, isLoading, visible, ...rest } = props;
const { onSubmit, onPromptSelect, selectedPrompt, editHistory, onPromptDelete, isLoading, visible, ...rest } =
props;
const [promptForm] = Form.useForm<PromptFormInterface>();
const [prompts, setPrompts] = useState<string[]>([]);
const disabled = isLoading;

const items = Object.keys(editHistory).map((prompt, index) => {
return {
color: isLoading ? 'gray' : prompt === selectedPrompt ? 'green' : 'blue',
children: (
<div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between' }}>
<div
key={`${prompt}-${index}-div`}
onClick={() => onPromptSelect(prompt)}
className={s.singlePromptContainer}
style={disabled ? { pointerEvents: 'none' } : {}}
>
<pre key={`${prompt} - ${index}`} className={s.prompt}>
{prompt}
</pre>
</div>
<div>
<Button
onClick={() => onPromptDelete(prompt)}
type="primary"
disabled={isLoading || Object.keys(editHistory).length === 1}
>
<DeleteOutlined />
</Button>
</div>
</div>
),
};
});

return (
<Form<PromptFormInterface>
layout="vertical"
form={promptForm}
onFinish={(values) => {
if (values.prompt) {
onSubmit(values.prompt);
setPrompts([values.prompt, ...prompts]);
promptForm.resetFields();
}
}}
Expand All @@ -44,11 +76,7 @@ export function PromptForm(props: Props) {
<Button htmlType="submit" disabled={disabled}>{t`Submit`}</Button>
</Form.Item>
<div className={s.prompts}>
{prompts.map((prompt, index) => (
<pre key={`${prompt}-${index}`} className={s.prompt}>
{prompt}
</pre>
))}
<Timeline items={items} />
</div>
</Form>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
margin: -4px 0 16px;
}

.singlePromptContainer {
cursor: pointer;
}

.prompt {
padding: 4px 0;
font-size: 14px;
Expand Down
32 changes: 30 additions & 2 deletions src/containers/QuestionnaireBuilder/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ export function useQuestionnaireBuilder() {
const [response, setResponse] = useState<RemoteData<FHIRQuestionnaire>>(notAsked);
const [updateResponse, setUpdateResponse] = useState<RemoteData<FHIRQuestionnaire>>(notAsked);
const [error, setError] = useState<string | undefined>();
const [editHistory, setEditHistory] = useState({});
const [selectedPrompt, setSelectedPrompt] = useState<string | undefined>(undefined);

useEffect(() => {
(async () => {
Expand Down Expand Up @@ -89,12 +91,13 @@ export function useQuestionnaireBuilder() {
setError(undefined);
const questionnaire = response.data;
const saveResponse = await generateQuestionnaire(prompt, JSON.stringify(questionnaire));
console.log('saveResponse', saveResponse);

setUpdateResponse(saveResponse);
if (isSuccess(saveResponse)) {
const newQuestionnaire = saveResponse.data;
setResponse(success(newQuestionnaire));
setEditHistory({ ...{ [prompt]: newQuestionnaire }, ...editHistory });
setSelectedPrompt(prompt);
}

if (isFailure(saveResponse)) {
Expand All @@ -105,7 +108,7 @@ export function useQuestionnaireBuilder() {
}
}
},
[response],
[editHistory, response],
);

const onItemChange = useCallback(
Expand Down Expand Up @@ -160,6 +163,26 @@ export function useQuestionnaireBuilder() {
[response],
);

const onPromptSelect = useCallback(
(prompt: string) => {
setResponse(success(editHistory[prompt]));
setSelectedPrompt(prompt);
},
[editHistory],
);

const onPromptDelete = useCallback(
(prompt: string) => {
const currentPrompts = editHistory;
delete currentPrompts[prompt];
setEditHistory(currentPrompts);
const activePrompt = Object.keys(currentPrompts)[0]!;
onPromptSelect(activePrompt);
setResponse(success(editHistory[activePrompt]));
},
[editHistory, onPromptSelect],
);

return {
response,
updateResponse,
Expand All @@ -169,5 +192,10 @@ export function useQuestionnaireBuilder() {
onItemDrag,
onItemDelete,
error,
editHistory,
setEditHistory,
onPromptSelect,
selectedPrompt,
onPromptDelete,
};
}
9 changes: 8 additions & 1 deletion src/containers/QuestionnaireBuilder/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,13 @@ export function QuestionnaireBuilder() {
onItemDrag,
onSaveQuestionnaire,
onItemDelete,
onPromptSelect,
selectedPrompt,
editHistory,
onPromptDelete,
} = useQuestionnaireBuilder();
const [questionnaireItem, setQuestionnaireItem] = useState<QuestionItemProps | undefined>();
const [groupItem, setGroupItem] = useState<GroupItemProps | undefined>();
console.log(response, updateResponse);

return (
<>
Expand Down Expand Up @@ -126,7 +129,11 @@ export function QuestionnaireBuilder() {
className={s.promptForm}
visible={!questionnaireItem && !groupItem}
onSubmit={(prompt) => onSubmitPrompt(prompt)}
onPromptSelect={(prompt) => onPromptSelect(prompt)}
selectedPrompt={selectedPrompt}
isLoading={isLoading(response) || isLoading(updateResponse)}
editHistory={editHistory}
onPromptDelete={onPromptDelete}
/>
</S.LeftColumn>
</S.Content>
Expand Down
Loading

0 comments on commit 9225456

Please sign in to comment.