Skip to content

Commit

Permalink
Group questions (#1166)
Browse files Browse the repository at this point in the history
* WIP

* Move modal to PageContent

* validation

* Remove h4

* Test

* console.log, unnecessary if/else

* A little more testing

---------

Co-authored-by: Michael Peels <[email protected]>
  • Loading branch information
mpeels and Michael Peels authored Mar 12, 2024
1 parent b92244f commit d7bb7ac
Show file tree
Hide file tree
Showing 33 changed files with 1,007 additions and 814 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
/* eslint-disable */

export type Batch = {
batchTableAppearIndCd?: string;
batchTableColumnWidth?: number;
batchTableHeader?: string;
id?: number;
appearsInTable: boolean;
id: number;
label?: string;
width?: number;
};

Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
import type { Batch } from './Batch';

export type GroupSubSectionRequest = {
batches?: Array<Batch>;
blockName?: string;
id?: number;
repeatingNbr?: number;
batches: Array<Batch>;
blockName: string;
repeatingNbr: number;
};

Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,16 @@ export class SubSectionControllerService {
}

/**
* groupSubSection
* @returns any OK
* updateSubSection
* @returns SubSection OK
* @returns any Created
* @throws ApiError
*/
public static groupSubSectionUsingPost({
public static updateSubSectionUsingPut({
authorization,
page,
request,
subSectionId,
}: {
authorization: string,
/**
Expand All @@ -69,13 +71,18 @@ export class SubSectionControllerService {
/**
* request
*/
request: GroupSubSectionRequest,
}): CancelablePromise<any> {
request: UpdateSubSectionRequest,
/**
* subSectionId
*/
subSectionId: number,
}): CancelablePromise<SubSection | any> {
return __request(OpenAPI, {
method: 'POST',
url: '/nbs/page-builder/api/v1/pages/{page}/subsections/group',
method: 'PUT',
url: '/nbs/page-builder/api/v1/pages/{page}/subsections/{subSectionId}',
path: {
'page': page,
'subSectionId': subSectionId,
},
headers: {
'Authorization': authorization,
Expand All @@ -90,33 +97,27 @@ export class SubSectionControllerService {
}

/**
* updateSubSection
* @returns SubSection OK
* @returns any Created
* deleteSubSection
* @returns any OK
* @throws ApiError
*/
public static updateSubSectionUsingPut({
public static deleteSubSectionUsingDelete({
authorization,
page,
request,
subSectionId,
}: {
authorization: string,
/**
* page
*/
page: number,
/**
* request
*/
request: UpdateSubSectionRequest,
/**
* subSectionId
*/
subSectionId: number,
}): CancelablePromise<SubSection | any> {
}): CancelablePromise<any> {
return __request(OpenAPI, {
method: 'PUT',
method: 'DELETE',
url: '/nbs/page-builder/api/v1/pages/{page}/subsections/{subSectionId}',
path: {
'page': page,
Expand All @@ -125,21 +126,19 @@ export class SubSectionControllerService {
headers: {
'Authorization': authorization,
},
body: request,
errors: {
401: `Unauthorized`,
403: `Forbidden`,
404: `Not Found`,
},
});
}

/**
* deleteSubSection
* unGroupSubSection
* @returns any OK
* @throws ApiError
*/
public static deleteSubSectionUsingDelete({
public static unGroupSubSectionUsingGet({
authorization,
page,
subSectionId,
Expand All @@ -155,8 +154,8 @@ export class SubSectionControllerService {
subSectionId: number,
}): CancelablePromise<any> {
return __request(OpenAPI, {
method: 'DELETE',
url: '/nbs/page-builder/api/v1/pages/{page}/subsections/{subSectionId}',
method: 'GET',
url: '/nbs/page-builder/api/v1/pages/{page}/subsections/{subSectionId}/un-group',
path: {
'page': page,
'subSectionId': subSectionId,
Expand All @@ -167,16 +166,17 @@ export class SubSectionControllerService {
errors: {
401: `Unauthorized`,
403: `Forbidden`,
404: `Not Found`,
},
});
}

/**
* unGroupSubSection
* validateSubSection
* @returns any OK
* @throws ApiError
*/
public static unGroupSubSectionUsingGet({
public static validateSubSectionUsingGet({
authorization,
page,
subSectionId,
Expand All @@ -193,7 +193,7 @@ export class SubSectionControllerService {
}): CancelablePromise<any> {
return __request(OpenAPI, {
method: 'GET',
url: '/nbs/page-builder/api/v1/pages/{page}/subsections/{subSectionId}/un-group',
url: '/nbs/page-builder/api/v1/pages/{page}/subsections/{subSectionId}/validate',
path: {
'page': page,
'subSectionId': subSectionId,
Expand All @@ -210,35 +210,41 @@ export class SubSectionControllerService {
}

/**
* validateSubSection
* groupSubSection
* @returns any OK
* @throws ApiError
*/
public static validateSubSectionUsingGet({
public static groupSubSectionUsingPost({
authorization,
page,
subSectionId,
request,
subsection,
}: {
authorization: string,
/**
* page
*/
page: number,
/**
* subSectionId
* request
*/
subSectionId: number,
request: GroupSubSectionRequest,
/**
* subsection
*/
subsection: number,
}): CancelablePromise<any> {
return __request(OpenAPI, {
method: 'GET',
url: '/nbs/page-builder/api/v1/pages/{page}/subsections/{subSectionId}/validate',
method: 'POST',
url: '/nbs/page-builder/api/v1/pages/{page}/subsections/{subsection}/group',
path: {
'page': page,
'subSectionId': subSectionId,
'subsection': subsection,
},
headers: {
'Authorization': authorization,
},
body: request,
errors: {
401: `Unauthorized`,
403: `Forbidden`,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { useEffect, useReducer } from 'react';

import {
GroupSubSectionRequest,
SubSectionControllerService,
UpdateSubSectionRequest
} from 'apps/page-builder/generated';
import { authorization } from 'authorization';

export type GroupRequest = GroupSubSectionRequest & UpdateSubSectionRequest;

type State =
| { status: 'idle' }
| { status: 'grouping'; page: number; subsection: number; request: GroupRequest }
| { status: 'complete' }
| { status: 'error'; error: string };

type Action =
| { type: 'group'; page: number; subsection: number; request: GroupRequest }
| { type: 'complete' }
| { type: 'error'; error: string };

const initial: State = { status: 'idle' };

const reducer = (_state: State, action: Action): State => {
switch (action.type) {
case 'group':
return {
status: 'grouping',
page: action.page,
subsection: action.subsection,
request: action.request
};
case 'complete':
return { status: 'complete' };
case 'error':
return { status: 'error', error: action.error };
default:
return { ...initial };
}
};

export const useGroupSubsection = () => {
const [state, dispatch] = useReducer(reducer, initial);

useEffect(() => {
if (state.status === 'grouping') {
// group allows editing the subsection as well as performing the actual grouping
SubSectionControllerService.updateSubSectionUsingPut({
authorization: authorization(),
page: state.page,
subSectionId: state.subsection,
request: state.request
})
.then(() => {
SubSectionControllerService.groupSubSectionUsingPost({
authorization: authorization(),
page: state.page,
subsection: state.subsection,
request: state.request
})
.then(() => dispatch({ type: 'complete' }))
.catch((error) => dispatch({ type: 'error', error: error.message }));
})
.catch((error) => dispatch({ type: 'error', error: error.message }));
}
}, [state.status]);

const value = {
error: state.status === 'error' ? state.error : undefined,
isLoading: state.status === 'grouping',
response: state.status === 'complete',
group: (page: number, subsection: number, request: GroupRequest) =>
dispatch({ type: 'group', page, subsection, request })
};

return value;
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ModalRef } from '@trussworks/react-uswds';
import { useAlert } from 'alert';
import { PagesQuestion, PagesTab } from 'apps/page-builder/generated';
import { PagesQuestion, PagesSubSection, PagesTab } from 'apps/page-builder/generated';
import { useAddQuestionsToPage } from 'apps/page-builder/hooks/api/useAddQuestionsToPage';
import { useEffect, useRef, useState } from 'react';
import { usePageManagement } from '../../usePageManagement';
Expand All @@ -12,6 +12,7 @@ import { EditValuesetModal } from '../edit-valueset/EditValuesetModal';
import { Sections } from '../section/Sections';
import { PageSideMenu } from './PageSideMenu';
import styles from './page-content.module.scss';
import { GroupQuestionModal } from '../question/GroupQuestion/GroupQuestionModal';

type Props = {
tab: PagesTab;
Expand All @@ -31,6 +32,7 @@ const staticTypes = [hyperlinkId, commentsReadOnlyId, lineSeparatorId, originalE
const questionTypes = [1001, 1006, 1007, 1008, 1009, 1013, 1017, 1019, 1024, 1025, 1026, 1027, 1028, 1029, 1031, 1032];

export const PageContent = ({ tab, handleAddSection, handleManageSection, handleReorderModal }: Props) => {
const [currentGroupSubsection, setCurrentGroupSubsection] = useState<PagesSubSection | undefined>(undefined);
const [currentEditQuestion, setCurrentEditQuestion] = useState<PagesQuestion>();
const [currentEditValueset, setCurrentEditValueset] = useState<string | undefined>(undefined);
const [subsectionId, setSubsectionId] = useState<number>(-1);
Expand All @@ -43,6 +45,7 @@ export const PageContent = ({ tab, handleAddSection, handleManageSection, handle
const editQuestionModalRef = useRef<ModalRef>(null);
const editValuesetModalRef = useRef<ModalRef>(null);
const changeValuesetModalRef = useRef<ModalRef>(null);
const groupQuestionModalRef = useRef<ModalRef>(null);

const handleAddQuestion = (subsection: number) => {
setSubsectionId(subsection);
Expand Down Expand Up @@ -87,6 +90,11 @@ export const PageContent = ({ tab, handleAddSection, handleManageSection, handle
changeValuesetModalRef.current?.toggleModal();
};

const handleGroupQuestion = (subsection: PagesSubSection) => {
setCurrentGroupSubsection(subsection);
groupQuestionModalRef.current?.toggleModal();
};

useEffect(() => {
if (response) {
showAlert({
Expand All @@ -112,6 +120,7 @@ export const PageContent = ({ tab, handleAddSection, handleManageSection, handle
onAddQuestion={handleAddQuestion}
onEditValueset={handleEditValueset}
onChangeValueset={handleChangeValueset}
onGroupQuestion={handleGroupQuestion}
/>
<PageSideMenu
onAddSection={() => handleAddSection?.()}
Expand Down Expand Up @@ -141,6 +150,7 @@ export const PageContent = ({ tab, handleAddSection, handleManageSection, handle
modal={changeValuesetModalRef}
question={currentEditQuestion}
/>
<GroupQuestionModal modal={groupQuestionModalRef} subsection={currentGroupSubsection} />
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ type Additional = {
repeatNumber: number;
visibleText: string;
};
const modalRef = { current: null };

const page: PagesResponse = {
id: 12039120,
Expand Down Expand Up @@ -52,9 +51,9 @@ const Wrapper = ({ children }: { children: ReactNode }) => {
name: 'subsection.name',
batches: [
{
batchTableAppearIndCd: undefined,
batchTableColumnWidth: undefined,
batchTableHeader: undefined,
appearsInTable: undefined,
width: undefined,
label: undefined,
id: 1234
}
],
Expand All @@ -78,7 +77,13 @@ const Wrapper = ({ children }: { children: ReactNode }) => {
const setup = () => {
return render(
<Wrapper>
<GroupQuestion subsection={subSections} questions={subSections.questions} modalRef={modalRef} />
<GroupQuestion
page={1}
subsection={subSections}
questions={subSections.questions}
onSuccess={jest.fn()}
onCancel={jest.fn()}
/>
</Wrapper>
);
};
Expand Down
Loading

0 comments on commit d7bb7ac

Please sign in to comment.