Skip to content

Commit

Permalink
Fix pages component render logic (#3)
Browse files Browse the repository at this point in the history
* Changes color to string literal instead of custom palette

* Rename FormBodyPage to FormTopLevelPage for top level renderer

* Add Renderer Logic for Page Container

* Add Renderer Logic for Page Container - Non Single Top Level

* Changes Page Button design
  • Loading branch information
ryuuzake authored Aug 2, 2024
1 parent f006102 commit 0702876
Show file tree
Hide file tree
Showing 13 changed files with 746 additions and 50 deletions.
2 changes: 1 addition & 1 deletion packages/smart-forms-renderer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aehrc/smart-forms-renderer",
"version": "0.37.0",
"version": "0.37.1",
"description": "FHIR Structured Data Captured (SDC) rendering engine for Smart Forms",
"main": "lib/index.js",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { styled } from '@mui/material/styles';
import Fab from '@mui/material/Fab';

export const StandardFab = styled(Fab)(({ theme }) => ({
color: theme.palette.customButton.foreground,
background: theme.palette.customButton.background,
export const StandardFab = styled(Fab)(() => ({
color: '#161C26',
background: '#0ABDC3',
'&:hover': {
background: theme.palette.customButton.backgroundHover
background: '#08979C'
}
}));
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ function GroupItemView(props: GroupItemViewProps) {
onQrItemChange,
onQrRepeatGroupChange
} = props;
console.log({ pages, currentPageIndex });

const readOnly = useReadOnly(qItem, parentIsReadOnly);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { memo } from 'react';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import type { Pages } from '../../../interfaces/page.interface';
import { useQuestionnaireStore } from '../../../stores';
import NextPageButton from './NextPageButton';
Expand Down Expand Up @@ -57,20 +58,17 @@ const PageButtonsWrapper = memo(function PageButtonsWrapper(props: PageButtonsWr
const pageButtonsDisabled = numOfVisiblePages <= 1;

return (
<Box display="flex" mt={3}>
{previousPageButtonHidden ? null : (
<PreviousPageButton
isDisabled={pageButtonsDisabled}
onPreviousPageClick={handlePreviousPageButtonClick}
/>
)}
<Box display="flex" mt={3} gap={2} alignItems="center">
<Box flexGrow={1} />
{nextPageButtonHidden ? null : (
<NextPageButton
isDisabled={pageButtonsDisabled}
onNextPageClick={handleNextPageButtonClick}
/>
)}
<Typography variant="subtitle1">{`${currentPageIndex + 1} / ${numOfVisiblePages}`}</Typography>
<PreviousPageButton
isDisabled={pageButtonsDisabled || previousPageButtonHidden}
onPreviousPageClick={handlePreviousPageButtonClick}
/>
<NextPageButton
isDisabled={pageButtonsDisabled || nextPageButtonHidden}
onNextPageClick={handleNextPageButtonClick}
/>
</Box>
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { getQrItemsIndex, mapQItemsIndex } from '../../utils/mapItem';
import { updateQrItemsInGroup } from '../../utils/qrItem';
import { everyIsPages } from '../../utils/page';
import type { QrRepeatGroup } from '../../interfaces/repeatGroup.interface';
import FormBodyPage from './FormBodyPage';
import FormTopLevelPage from './FormTopLevelPage';

/**
* Main component of the form-rendering engine.
Expand Down Expand Up @@ -82,7 +82,7 @@ function BaseRenderer() {
return (
<Fade in={true} timeout={500}>
<Container maxWidth="xl">
<FormBodyPage
<FormTopLevelPage
topLevelQItems={topLevelQItems}
topLevelQRItems={topLevelQRItemsByIndex}
parentIsReadOnly={readOnly}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useMemo } from 'react';
import Grid from '@mui/material/Grid';
import type { QuestionnaireItem, QuestionnaireResponseItem } from 'fhir/r4';
import TabContext from '@mui/lab/TabContext';
Expand All @@ -9,26 +9,49 @@ import type {
PropsWithQrItemChangeHandler
} from '../../interfaces/renderProps.interface';
import { useQuestionnaireStore } from '../../stores';
import { getQrItemsIndex, mapQItemsIndex } from '../../utils/mapItem';
import { createEmptyQrGroup, updateQrItemsInGroup } from '../../utils/qrItem';

interface FormBodyPageProps
extends PropsWithQrItemChangeHandler,
PropsWithParentIsReadOnlyAttribute {
topLevelQItems: QuestionnaireItem[];
topLevelQRItems: (QuestionnaireResponseItem | QuestionnaireResponseItem[] | undefined)[];
topLevelQItem: QuestionnaireItem;
topLevelQRItem: QuestionnaireResponseItem | null;
}

function FormBodyPage(props: FormBodyPageProps) {
const { topLevelQItems, topLevelQRItems, parentIsReadOnly, onQrItemChange } = props;
const { topLevelQItem, topLevelQRItem, parentIsReadOnly, onQrItemChange } = props;

const pages = useQuestionnaireStore.use.pages();
const currentPage = useQuestionnaireStore.use.currentPageIndex();

const indexMap: Record<string, number> = useMemo(
() => mapQItemsIndex(topLevelQItem),
[topLevelQItem]
);

const nonNullTopLevelQRItem = topLevelQRItem ?? createEmptyQrGroup(topLevelQItem);

const qItems = topLevelQItem.item;
const qrItems = nonNullTopLevelQRItem.item;

function handleQrGroupChange(qrItem: QuestionnaireResponseItem) {
updateQrItemsInGroup(qrItem, null, nonNullTopLevelQRItem, indexMap);
onQrItemChange(nonNullTopLevelQRItem);
}

if (!qItems || !qrItems) {
return <>Unable to load form</>;
}

const qrItemsByIndex = getQrItemsIndex(qItems, qrItems, indexMap);

return (
<Grid container spacing={1.5}>
<TabContext value={currentPage.toString()}>
<Grid item xs={12} md={12} lg={12}>
{topLevelQItems.map((qItem, i) => {
const qrItem = topLevelQRItems[i];
{qItems.map((qItem, i) => {
const qrItem = qrItemsByIndex[i];

const isNotRepeatGroup = !Array.isArray(qrItem);
const isPage = !!pages[qItem.linkId];
Expand Down Expand Up @@ -56,7 +79,7 @@ function FormBodyPage(props: FormBodyPageProps) {
pages={pages}
currentPageIndex={currentPage}
parentIsReadOnly={parentIsReadOnly}
onQrItemChange={onQrItemChange}
onQrItemChange={handleQrGroupChange}
/>
</TabPanel>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type { QuestionnaireItem, QuestionnaireResponseItem } from 'fhir/r4';
import FormBodyTabbed from './FormBodyTabbed';
import FormBodyPage from './FormBodyPage';
import { containsTabs, isTabContainer } from '../../utils/tabs';
import { containsPages, isPage } from '../../utils/page';
import GroupItem from '../FormComponents/GroupItem/GroupItem';
import SingleItem from '../FormComponents/SingleItem/SingleItem';
import type {
Expand Down Expand Up @@ -54,6 +55,9 @@ function FormTopLevelItem(props: FormTopLevelItemProps) {
const itemIsTabContainer = isTabContainer(topLevelQItem);
const itemContainsTabs = containsTabs(topLevelQItem);

const itemIsPageContainer = isPage(topLevelQItem);
const itemContainsPages = containsPages(topLevelQItem);

const isTablet = useResponsive('up', 'md');

const itemIsGroup = topLevelQItem.type === 'group';
Expand Down Expand Up @@ -107,6 +111,18 @@ function FormTopLevelItem(props: FormTopLevelItemProps) {
);
}

if (itemContainsPages || itemIsPageContainer) {
return (
<FormBodyPage
key={topLevelQItem.linkId}
topLevelQItem={topLevelQItem}
topLevelQRItem={topLevelQRItem}
parentIsReadOnly={readOnly}
onQrItemChange={onQrItemChange}
/>
);
}

// If form is untabbed, it is rendered as a regular group
if (itemIsGroup) {
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import Grid from '@mui/material/Grid';
import type { QuestionnaireItem, QuestionnaireResponseItem } from 'fhir/r4';
import TabContext from '@mui/lab/TabContext';
import TabPanel from '@mui/lab/TabPanel';
import GroupItem from '../FormComponents/GroupItem/GroupItem';
import type {
PropsWithParentIsReadOnlyAttribute,
PropsWithQrItemChangeHandler
} from '../../interfaces/renderProps.interface';
import { useQuestionnaireStore } from '../../stores';

interface FormTopLevelPageProps
extends PropsWithQrItemChangeHandler,
PropsWithParentIsReadOnlyAttribute {
topLevelQItems: QuestionnaireItem[];
topLevelQRItems: (QuestionnaireResponseItem | QuestionnaireResponseItem[] | undefined)[];
}

function FormTopLevelPage(props: FormTopLevelPageProps) {
const { topLevelQItems, topLevelQRItems, parentIsReadOnly, onQrItemChange } = props;

const pages = useQuestionnaireStore.use.pages();
const currentPage = useQuestionnaireStore.use.currentPageIndex();

return (
<Grid container spacing={1.5}>
<TabContext value={currentPage.toString()}>
<Grid item xs={12} md={12} lg={12}>
{topLevelQItems.map((qItem, i) => {
const qrItem = topLevelQRItems[i];

const isNotRepeatGroup = !Array.isArray(qrItem);
const isPage = !!pages[qItem.linkId];

if (!isPage || !isNotRepeatGroup) {
// Something has gone horribly wrong
return null;
}

const isRepeated = qItem.repeats ?? false;
const pageIsMarkedAsComplete = pages[qItem.linkId].isComplete ?? false;

return (
<TabPanel
key={qItem.linkId}
sx={{ p: 0 }}
value={i.toString()}
data-test="renderer-page-panel">
<GroupItem
qItem={qItem}
qrItem={qrItem ?? null}
isRepeated={isRepeated}
groupCardElevation={1}
pageIsMarkedAsComplete={pageIsMarkedAsComplete}
pages={pages}
currentPageIndex={currentPage}
parentIsReadOnly={parentIsReadOnly}
onQrItemChange={onQrItemChange}
/>
</TabPanel>
);
})}
</Grid>
</TabContext>
</Grid>
);
}

export default FormTopLevelPage;
Loading

0 comments on commit 0702876

Please sign in to comment.