Skip to content

Commit

Permalink
Allow modifying grouped subsection (#1191)
Browse files Browse the repository at this point in the history
* provide required fields in page request

* Fix block_pivot_nbr

* Fix reset when deselecting

* Clear if changed from appears to not

* Testing

---------

Co-authored-by: Michael Peels <[email protected]>
  • Loading branch information
mpeels and Michael Peels authored Mar 18, 2024
1 parent e54f0b6 commit c1d81ee
Show file tree
Hide file tree
Showing 28 changed files with 382 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@
export type PagesQuestion = {
adminComments?: string;
allowFutureDates?: boolean;
appearsInBatch?: boolean;
batchLabel?: string;
batchWidth?: number;
blockName?: string;
coInfection?: boolean;
dataMartColumnName?: string;
dataMartRepeatNumber?: number;
dataType?: string;
defaultLabelInReport?: string;
defaultRdbTableName?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import type { PagesQuestion } from './PagesQuestion';

export type PagesSubSection = {
blockName?: string;
id: number;
isGroupable: boolean;
isGrouped: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export const PageContent = ({ tab, handleAddSection, handleManageSection, handle
onEditValueset={handleEditValueset}
onChangeValueset={handleChangeValueset}
onGroupQuestion={handleGroupQuestion}
onEditGroupedSubsection={handleGroupQuestion}
/>
<PageSideMenu
onAddSection={() => handleAddSection?.()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { AlertProvider } from 'alert';
import { GroupSubSectionRequest, PagesQuestion, PagesResponse, PagesSubSection } from 'apps/page-builder/generated';
import { ReactNode } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { PageManagementProvider } from '../../../usePageManagement';
import { PageManagementProvider } from '../../../../usePageManagement';
import { GroupQuestion } from './GroupQuestion';

type Additional = {
Expand Down Expand Up @@ -78,13 +78,7 @@ const Wrapper = ({ children }: { children: ReactNode }) => {
const setup = () => {
return render(
<Wrapper>
<GroupQuestion
page={1}
subsection={subSections}
questions={subSections.questions}
onSuccess={jest.fn()}
onCancel={jest.fn()}
/>
<GroupQuestion page={1} subsection={subSections} onSuccess={jest.fn()} onCancel={jest.fn()} />
</Wrapper>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,31 @@ import { Button } from '@trussworks/react-uswds';
import { useAlert } from 'alert';
import { ButtonBar } from 'apps/page-builder/components/ButtonBar/ButtonBar';
import { CloseableHeader } from 'apps/page-builder/components/CloseableHeader/CloseableHeader';
import { PagesQuestion, PagesSubSection } from 'apps/page-builder/generated';
import { PagesSubSection } from 'apps/page-builder/generated';
import { GroupRequest, useGroupSubsection } from 'apps/page-builder/hooks/api/useGroupSubsection';
import { Spinner } from 'components/Spinner';
import { useEffect, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { RepeatingBlock } from './RepeatingBlock';
import { SubsectionDetails } from './SubsectionDetails';
import { RepeatingBlock } from '../RepeatingBlock';
import { SubsectionDetails } from '../SubsectionDetails';
import styles from './group-question.module.scss';

type Props = {
page: number;
subsection: PagesSubSection;
questions: PagesQuestion[];
onSuccess: () => void;
onCancel: () => void;
};

export const GroupQuestion = ({ page, subsection, questions, onSuccess, onCancel }: Props) => {
export const GroupQuestion = ({ page, subsection, onSuccess, onCancel }: Props) => {
const { showAlert } = useAlert();
const { isLoading, error, response, group } = useGroupSubsection();
const [valid, setValid] = useState(false);
const form = useForm<GroupRequest>({
mode: 'onChange',
defaultValues: {
name: subsection.name,
batches: questions.map((question) => ({
batches: subsection.questions.map((question) => ({
appearsInTable: true,
width: 0,
label: question.name,
Expand Down Expand Up @@ -77,7 +76,7 @@ export const GroupQuestion = ({ page, subsection, questions, onSuccess, onCancel
<div className={styles.content}>
<FormProvider {...form}>
<SubsectionDetails />
<RepeatingBlock questions={questions} valid={valid} setValid={setValid} />
<RepeatingBlock questions={subsection.questions} valid={valid} setValid={setValid} />
</FormProvider>
</div>
<ButtonBar>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Modal, ModalRef } from '@trussworks/react-uswds';
import { PagesSubSection } from 'apps/page-builder/generated';
import { RefObject } from 'react';
import { GroupQuestion } from './GroupQuestion';
import { GroupQuestion } from './Create/GroupQuestion';
import './GroupQuestionModal.scss';
import styles from './group-question-modal.module.scss';
import { usePageManagement } from '../../../usePageManagement';
import { UpdateGroupedQuestion } from './Update/UpdateGroupedQuestion';

type Props = {
modal: RefObject<ModalRef>;
Expand All @@ -31,13 +32,27 @@ export const GroupQuestionModal = ({ modal, subsection }: Props) => {
aria-describedby="group-question-modal">
<div className={styles.modal}>
{subsection && (
<GroupQuestion
page={page.id}
subsection={subsection}
questions={subsection.questions}
onCancel={handleCancel}
onSuccess={handleSuccess}
/>
<>
{!subsection.isGrouped ? (
<>
<GroupQuestion
page={page.id}
subsection={subsection}
onCancel={handleCancel}
onSuccess={handleSuccess}
/>
</>
) : (
<>
<UpdateGroupedQuestion
page={page.id}
subsection={subsection}
onCancel={handleCancel}
onSuccess={handleSuccess}
/>
</>
)}
</>
)}
</div>
</Modal>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type Props = {

export const RepeatingBlock = ({ questions, valid, setValid }: Props) => {
const [total, setTotal] = useState<number | undefined>(undefined);
const { control, resetField } = useFormContext<GroupRequest & { batches: Batch[] }>();
const { control, setValue } = useFormContext<GroupRequest & { batches: Batch[] }>();
const { fields } = useFieldArray({
control,
name: 'batches'
Expand All @@ -29,8 +29,8 @@ export const RepeatingBlock = ({ questions, valid, setValid }: Props) => {
validateWidths();
batches.forEach((b, i) => {
if (!b.appearsInTable) {
resetField(`batches.${i}.label`);
resetField(`batches.${i}.width`);
setValue(`batches.${i}.label`, '');
setValue(`batches.${i}.width`, 0);
}
});
}, [JSON.stringify(batches)]);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Button } from '@trussworks/react-uswds';
import { useAlert } from 'alert';
import { ButtonBar } from 'apps/page-builder/components/ButtonBar/ButtonBar';
import { CloseableHeader } from 'apps/page-builder/components/CloseableHeader/CloseableHeader';
import { PagesSubSection } from 'apps/page-builder/generated';
import { GroupRequest, useGroupSubsection } from 'apps/page-builder/hooks/api/useGroupSubsection';
import { Spinner } from 'components/Spinner';
import { useEffect, useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { RepeatingBlock } from '../RepeatingBlock';
import { SubsectionDetails } from '../SubsectionDetails';
import styles from './update-group-question.module.scss';

type Props = {
page: number;
subsection: PagesSubSection;
onSuccess: () => void;
onCancel: () => void;
};
export const UpdateGroupedQuestion = ({ page, subsection, onSuccess, onCancel }: Props) => {
const { showAlert } = useAlert();
const { isLoading, error, response, group } = useGroupSubsection();
const [valid, setValid] = useState(false);
const form = useForm<GroupRequest>({
mode: 'onChange',
defaultValues: {
name: subsection.name,
batches: subsection.questions.map((question) => ({
appearsInTable: question.appearsInBatch,
width: question.batchWidth,
label: question.batchLabel,
id: question.id
})),
blockName: subsection.blockName,
visible: subsection.visible,
repeatingNbr: subsection.questions[0]?.dataMartRepeatNumber ?? 0
}
});

useEffect(() => {
form.reset({
name: subsection.name,
batches: subsection.questions.map((question) => ({
appearsInTable: question.appearsInBatch,
width: question.batchWidth,
label: question.batchLabel,
id: question.id
})),
blockName: subsection.blockName,
visible: subsection.visible,
repeatingNbr: subsection.questions[0]?.dataMartRepeatNumber ?? 0
});
}, [JSON.stringify(subsection)]);

const handleCancel = () => {
form.reset();
onCancel();
};

const handleSubmit = () => {
group(page, subsection.id, { ...form.getValues() });
};

useEffect(() => {
if (response) {
showAlert({
type: 'success',
header: 'Grouped',
message: `You've successfully grouped ${form.getValues('blockName')} subsection`
});
form.reset();
onSuccess();
} else if (error) {
showAlert({
type: 'error',
header: 'error',
message: 'Failed to group subsection'
});
}
}, [error, response]);

return (
<div className={styles.groupQuestion}>
{isLoading && (
<div className={styles.loadingIndicator}>
<Spinner />
</div>
)}
<CloseableHeader title="Edit subsection" onClose={handleCancel} />
<div className={styles.content}>
<FormProvider {...form}>
<SubsectionDetails />
<RepeatingBlock questions={subsection.questions} valid={valid} setValid={setValid} />
</FormProvider>
</div>
<ButtonBar>
<Button onClick={handleCancel} type="button" outline>
Cancel
</Button>
<Button onClick={handleSubmit} type="button" disabled={!valid || !form.formState.isValid}>
Submit
</Button>
</ButtonBar>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@use 'styles/colors';

.groupQuestion {
height: 100%;
display: flex;
flex-direction: column;

.loadingIndicator div {
max-height: 80svh;
}

.content {
height: 100%;
overflow-y: auto;
padding: 1.25rem;
}

.form {
height: 100%;
overflow-y: auto;

width: 100%;
min-width: 100%;
max-width: unset;
overflow-y: auto;
height: calc(100% - 5.5rem);
padding: 1.5rem;
}
.footer {
display: flex;
align-items: center;
justify-content: flex-end;
margin: 0 -1.5rem;
padding: 0 1.5rem;
gap: 0.5rem;
position: absolute;
bottom: 0;
height: 5rem;
width: 100%;
background-color: colors.$base-white;
border-top: 1px solid colors.$base-lighter;
button {
margin: 0;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Props = {
onEditValueset: (valuesetName: string) => void;
onChangeValueset: (question: PagesQuestion) => void;
onGroupQuestion: (subsection: PagesSubSection) => void;
onEditGroupedSubsection: (subsection: PagesSubSection) => void;
};

export const Section = ({
Expand All @@ -33,7 +34,8 @@ export const Section = ({
onDeleteStatus,
onEditValueset,
onChangeValueset,
onGroupQuestion
onGroupQuestion,
onEditGroupedSubsection
}: Props) => {
const [isExpanded, setIsExpanded] = useState<boolean>(true);

Expand Down Expand Up @@ -67,8 +69,12 @@ export const Section = ({
};

const handleEditSubsection = (subsection: PagesSubSection) => {
setEditSubsection(subsection);
editSubsectionModalRef.current?.toggleModal(undefined, true);
if (subsection.isGrouped) {
onEditGroupedSubsection(subsection);
} else {
setEditSubsection(subsection);
editSubsectionModalRef.current?.toggleModal(undefined, true);
}
};

const onCloseEditSubsectionModal = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type Props = {
onEditValueset: (valuesetName: string) => void;
onChangeValueset: (question: PagesQuestion) => void;
onGroupQuestion: (subsection: PagesSubSection) => void;
onEditGroupedSubsection: (subsection: PagesSubSection) => void;
};

export const Sections = ({
Expand All @@ -23,7 +24,8 @@ export const Sections = ({
onEditQuestion,
onEditValueset,
onChangeValueset,
onGroupQuestion
onGroupQuestion,
onEditGroupedSubsection
}: Props) => {
const { page, refresh } = usePageManagement();

Expand Down Expand Up @@ -65,6 +67,7 @@ export const Sections = ({
onEditValueset={onEditValueset}
onChangeValueset={onChangeValueset}
onGroupQuestion={onGroupQuestion}
onEditGroupedSubsection={onEditGroupedSubsection}
/>
))}
<StatusModal
Expand Down
Loading

0 comments on commit c1d81ee

Please sign in to comment.