From 960e0187826723d56d4188185306d72519edf59f Mon Sep 17 00:00:00 2001 From: PupoSDC Date: Tue, 6 Feb 2024 11:36:46 +0000 Subject: [PATCH] feat: add new question editor (#133) Adds a more modular question editor where different parts can be reused. --- .../questions/[questionId].page.tsx | 109 +- .../001-welcome-to-chair-flight-blog/page.md | 3 +- .../search/src/entities/question-search.ts | 6 +- .../src/question-bank/question-search.ts | 10 +- .../src/question-list/question-list.mock.ts | 930 ++++++++++++++++++ .../question-list/question-list.stories.tsx | 340 +------ .../src/question-list/question-list.tsx | 59 +- .../question-multiple-choice.stories.tsx | 8 +- .../question-multiple-choice.test.tsx | 8 +- .../question-multiple-choice.tsx | 16 +- .../src/blog/blog-post/blog-post.tsx | 2 - libs/react/containers/src/index.ts | 4 +- .../questions/question-explanation/index.ts | 1 + .../question-explanation.mock.ts | 9 + .../question-explanation.stories.tsx | 35 + .../question-explanation.tsx | 65 ++ .../src/questions/question-meta/index.ts | 1 + .../question-meta/question-meta.mock.ts | 21 + .../question-meta/question-meta.stories.tsx | 33 + .../questions/question-meta/question-meta.tsx | 103 ++ .../src/questions/question-overview/index.ts | 1 - .../question-overview.mock.ts | 47 - .../question-overview.stories.tsx | 39 - .../question-overview/question-overview.tsx | 360 ------- .../questions/question-stand-alone/index.ts | 1 + .../question-stand-alone.mock.ts | 24 + .../question-stand-alone.stories.tsx | 40 + .../question-stand-alone.tsx | 148 +++ .../routers/containers/questions-router.ts | 87 +- 29 files changed, 1633 insertions(+), 877 deletions(-) create mode 100644 libs/react/components/src/question-list/question-list.mock.ts create mode 100644 libs/react/containers/src/questions/question-explanation/index.ts create mode 100644 libs/react/containers/src/questions/question-explanation/question-explanation.mock.ts create mode 100644 libs/react/containers/src/questions/question-explanation/question-explanation.stories.tsx create mode 100644 libs/react/containers/src/questions/question-explanation/question-explanation.tsx create mode 100644 libs/react/containers/src/questions/question-meta/index.ts create mode 100644 libs/react/containers/src/questions/question-meta/question-meta.mock.ts create mode 100644 libs/react/containers/src/questions/question-meta/question-meta.stories.tsx create mode 100644 libs/react/containers/src/questions/question-meta/question-meta.tsx delete mode 100644 libs/react/containers/src/questions/question-overview/index.ts delete mode 100644 libs/react/containers/src/questions/question-overview/question-overview.mock.ts delete mode 100644 libs/react/containers/src/questions/question-overview/question-overview.stories.tsx delete mode 100644 libs/react/containers/src/questions/question-overview/question-overview.tsx create mode 100644 libs/react/containers/src/questions/question-stand-alone/index.ts create mode 100644 libs/react/containers/src/questions/question-stand-alone/question-stand-alone.mock.ts create mode 100644 libs/react/containers/src/questions/question-stand-alone/question-stand-alone.stories.tsx create mode 100644 libs/react/containers/src/questions/question-stand-alone/question-stand-alone.tsx diff --git a/apps/next-app/pages/modules/[questionBank]/questions/[questionId].page.tsx b/apps/next-app/pages/modules/[questionBank]/questions/[questionId].page.tsx index 15554978a..203710a79 100644 --- a/apps/next-app/pages/modules/[questionBank]/questions/[questionId].page.tsx +++ b/apps/next-app/pages/modules/[questionBank]/questions/[questionId].page.tsx @@ -1,41 +1,52 @@ import { useRouter } from "next/router"; +import { Box, Tab, TabList, TabPanel, Tabs, tabClasses } from "@mui/joy"; import { getRandomId } from "@chair-flight/base/utils"; import { AppHead } from "@chair-flight/react/components"; -import { LayoutModule, QuestionOverview } from "@chair-flight/react/containers"; +import { + LayoutModule, + QuestionExplanation, + QuestionMeta, + QuestionStandAlone, +} from "@chair-flight/react/containers"; import { ssrHandler } from "@chair-flight/trpc/server"; import type { QuestionBankName } from "@chair-flight/core/question-bank"; import type { Breadcrumbs } from "@chair-flight/react/containers"; import type { NextPage } from "next"; -type PageParams = { +type QueryParams = { seed?: string; - variantId?: string; + tab?: string; +}; + +type PageParams = QueryParams & { questionBank: QuestionBankName; questionId: string; }; type PageProps = { - seed: string; - variantId: string | null; questionBank: QuestionBankName; questionId: string; + seed: string; + tab: string; }; const Page: NextPage = ({ - seed: initialSeed, - variantId: initialVariantId, questionBank, questionId, + tab: initialTab, + seed: initialSeed, }) => { const router = useRouter(); const query = router.query as PageParams; const seed = query.seed ?? initialSeed; - const variantId = query.variantId ?? initialVariantId ?? undefined; + const tab = query.tab ?? initialTab; - const updateVariantAndSeed = (query: { variantId: string; seed: string }) => { - router.push({ pathname: router.pathname, query }, undefined, { - shallow: true, - }); + const updateQuery = (query: QueryParams) => { + router.push( + { ...router, query: { ...router.query, ...query } }, + undefined, + { shallow: true }, + ); }; const crumbs = [ @@ -50,15 +61,65 @@ const Page: NextPage = ({ // ); return ( - - - + + updateQuery({ tab: v as string })} + sx={{ backgroundColor: "transparent", flex: 1 }} + > + `calc(${theme.spacing(5)} + 2px)`, + + [`& .${tabClasses.selected}`]: { + color: "primary.plainColor", + }, + }} + > + Question + Explanation + Meta + + `calc(${theme.spacing(5)} + 2px)` }} /> + + + + + + + + + + ); }; @@ -66,12 +127,14 @@ const Page: NextPage = ({ export const getServerSideProps = ssrHandler( async ({ params, helper, context }) => { const seed = (context.query?.["seed"] ?? getRandomId()) as string; - const variantId = (context.query?.["variantId"] as string) ?? null; - const allParams = { ...params, seed, variantId }; + const tab = (context.query?.["tab"] ?? "question") as string; + const allParams = { ...params, seed, tab }; await Promise.all([ LayoutModule.getData({ params: allParams, helper }), - QuestionOverview.getData({ params: allParams, helper }), + QuestionStandAlone.getData({ params: allParams, helper }), + QuestionExplanation.getData({ params: allParams, helper }), + QuestionMeta.getData({ params: allParams, helper }), ]); return { props: allParams }; diff --git a/libs/content/blog/posts/001-welcome-to-chair-flight-blog/page.md b/libs/content/blog/posts/001-welcome-to-chair-flight-blog/page.md index 2dd00677f..46a1530c7 100644 --- a/libs/content/blog/posts/001-welcome-to-chair-flight-blog/page.md +++ b/libs/content/blog/posts/001-welcome-to-chair-flight-blog/page.md @@ -59,7 +59,8 @@ incorrect. For this simple question, it's possible to write 18 variations! That's 16 times more seeing this question than you really need to see it. In Chair Flight, these question variants are combined into a single question: -```tsx eval +```tsx +// TODO FIXME ; + relatedQuestions: Array<{ + id: string; href: string; }>; externalIds: string[]; diff --git a/libs/providers/search/src/question-bank/question-search.ts b/libs/providers/search/src/question-bank/question-search.ts index 8431f36d7..51ec9959f 100644 --- a/libs/providers/search/src/question-bank/question-search.ts +++ b/libs/providers/search/src/question-bank/question-search.ts @@ -71,9 +71,13 @@ export class QuestionSearch extends QuestionBankSearchProvider< questionBank: bank.getName(), text: getQuestionPreview(q), subjects: uniqueSubjects, - learningObjectives: q.learningObjectives.map((name) => ({ - name, - href: `/modules/${bank.getName()}/learning-objectives/${name}`, + learningObjectives: q.learningObjectives.map((id) => ({ + id, + href: `/modules/${bank.getName()}/learning-objectives/${id}`, + })), + relatedQuestions: q.relatedQuestions.map((id) => ({ + id, + href: `/modules/${bank.getName()}/questions/${id}`, })), externalIds: q.externalIds, href: `/modules/${bank.getName()}/questions/${q.id}`, diff --git a/libs/react/components/src/question-list/question-list.mock.ts b/libs/react/components/src/question-list/question-list.mock.ts new file mode 100644 index 000000000..820538c41 --- /dev/null +++ b/libs/react/components/src/question-list/question-list.mock.ts @@ -0,0 +1,930 @@ +import type { QuestionListProps } from "./question-list"; + +export const itemsMock: QuestionListProps["items"] = [ + { + id: "K7HuwYXz", + text: "Which statement is correct?\n\n- :white_check_mark: The short period oscillation should always be heavily damped.\n- :x: When the phugoid is slightly unstable, an aeroplane becomes uncontrollable.\n- :x: The phugoid should always be heavily damped.\n- :x: A slightly unstable short period oscillation is no problem for an aeroplane.", + externalIds: ["BGS-810670", "BGS-812108", "AVEXAM-7288"], + href: "/modules/atpl/questions/K7HuwYXz", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "ezh4CuEv", + text: "Which statement is correct?\n\n- :white_check_mark: VR must not be less than 1.05 VMCA and not less than V1.\n- :x: VR must not be less than 1.05 VMCA and not less than 1.1 V1.\n- :x: VR must not be less than 1.1 VMCA and not less than V1.\n- :x: VR must not be less than VMCA and not less than 1.05 V1.", + externalIds: [ + "BGS-320653", + "AVEXAM-57312", + "ATPLGS-625808", + "ATPLQ-321025", + ], + href: "/modules/atpl/questions/ezh4CuEv", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "Ax7FFF3g", + text: "Which statement is correct?\n\n- :white_check_mark: Oxygen diffusion from the blood into the cells depends on the partial oxygen pressure gradient.\n- :x: The gradient of diffusion is higher at altitude than it is at sea level.\n- :x: Oxygen is mainly transported in plasma.\n- :x: Oxygen diffusion from the lungs into the blood is independent of the partial oxygen pressure.", + externalIds: ["ATPLGS-626755"], + href: "/modules/atpl/questions/Ax7FFF3g", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "SxFJ91nN", + text: "Which statement is correct?\n\n- :white_check_mark: V~R~ must not be less than 1.05 V~MCA~ and not less than V~1~.\n- :x: V~R~ must not be less than 1.1 V~MCA ~and not less than V~1~.\n- :x: V~R~ must not be less than V~MCA~ and not less than 1.05 V~1~.\n- :x: V~R~ must not be less than 1.05 V~MCA~ and not less than 1.1 V~1~.", + externalIds: [ + "ATPLQ-321025", + "ATPLGS-625808", + "AVEXAM-57312", + "BGS-320653", + ], + href: "/modules/atpl/questions/SxFJ91nN", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "uV7RVfAr", + text: "Which statement is correct?\n\n- :white_check_mark: Spoiler extension increases the stall speed, the minimum rate of descent and the minimum angle of descent.\n- :x: Flap extension reduces the maximum lift/drag ratio thus reducing the minimum rate of descent.\n- :x: Flap extension reduces the stall speed, which increases the maximum glide distance.\n- :x: Flap extension has no effect on the minimum rate of descent as this is only affected by TAS.", + externalIds: ["BGS-811633", "BGS-810466", "AVEXAM-68132"], + href: "/modules/atpl/questions/uV7RVfAr", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "2qQjMgG1", + text: "Which statement is correct?\n\n- :white_check_mark: As the angle of attack increases, the stagnation point on the aerofoil's profile moves downwards on the profiles leading edge.\n- :x: The stagnation point is always situated on the chord line, the centre of pressure is not.\n- :x: The centre of pressure is the point on the aerofoil leading edge where the airflow splits up.\n- :x: The stagnation point is another name for centre of pressure.", + externalIds: ["AVEXAM-54692"], + href: "/modules/atpl/questions/2qQjMgG1", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "UrGzEwAj", + text: "Which statement is correct?\n\n- :white_check_mark: A ridge is an elongated area of relatively high pressure, a trough is a elongated area of relatively low pressure and a col is a region between two highs and two lows.\n- :x: A ridge is an elongated area of relatively high pressure, a col is a elongated area of relatively low pressure and a trough is a region between two highs and two lows.\n- :x: A col is an elongated area of relatively high pressure, a trough is a elongated area of relatively low pressure and a ridge is a region between two highs and two lows.\n- :x: A trough is an elongated area of relatively high pressure, a ridge is a elongated area of relatively low pressure and a col is a region between two highs and two lows.", + externalIds: ["BGS-995620"], + href: "/modules/atpl/questions/UrGzEwAj", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "kA7q1I98", + text: "Which statement is correct?\n\n- :white_check_mark: The climb limited take-off mass depends on pressure altitude and outer air temperature.\n- :x: The performance limited take-off mass is the highest of: field length limited take-off mass climb limited take-off mass obstacle limited take-off mass.\n- :x: The climb limited take-off mass will increase if the headwind component increases.\n- :x: The climb limited take-off mass increases when a larger take-off flap setting is used.", + externalIds: [ + "BGS-320656", + "ATPLGS-107415", + "ATPLGS-107575", + "ATPLGS-114227", + "ATPLQ-322985", + "AVEXAM-56017", + "AVEXAM-90038", + "AVEXAM-13194", + "AVEXAM-80302", + "ATPLQ-326469", + "ATPLGS-625115", + "ATPLQ-329553", + "ATPLQ-329630", + "ATPLQ-321955", + "ATPLGS-107438", + "ATPLQ-324938", + "AVEXAM-26125", + ], + href: "/modules/atpl/questions/kA7q1I98", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "IJKUxABS", + text: "Which statement is correct?\n\n- :white_check_mark: Fog can be supercooled and can also contain ice crystals.\n- :x: Mist and haze consist of water droplets.\n- :x: Fog and haze do not occur in the tropics.\n- :x: Mist and haze only differ by different values of visibility.", + externalIds: ["AVEXAM-69003", "ATPLQ-505558"], + href: "/modules/atpl/questions/IJKUxABS", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "fklnIxec", + text: "Which statement is correct?\n\n- :white_check_mark: The lower limit of a TMA shall be established at a height of at least 700 ft AGL.\n- :x: The upper limit of a CTR shall be established at a height of at least 3 000 ft AMSL.\n- :x: The lower limit of a CTA shall be established at a height of at least 1 500 ft AGL.\n- :x: The lower limit of an UIR may coincide with an IFR cruising level.", + externalIds: ["AVEXAM-21315", "ATPLGS-621989"], + href: "/modules/atpl/questions/fklnIxec", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "lapzBT5F", + text: "Which statement is correct?\n\n- :white_check_mark: Flap extension causes a reduction in stall speed and the maximum glide distance.\n- :x: Flap extension will increase (CL/CD)max thus causing a reduction in the minimum rate of descent.\n- :x: Flap extension has no influence on the minimum rate of descent, as only TAS has to be taken into account.\n- :x: Spoiler extension causes a reduction in stall speed and the minimum rate of descent, but increases the minimum descent angle.", + externalIds: ["ATPLGS-625875", "BGS-810432"], + href: "/modules/atpl/questions/lapzBT5F", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "BRYanzNr", + text: "Which statement is correct?\n\n- :white_check_mark: Dynamic stability is possible only when the aeroplane is statically stable about the relevant axis.\n- :x: A dynamically stable aeroplane would be almost impossible to fly manually.\n- :x: Dynamic stability about the lateral axis implies that after being displaced from its original equilibrium condition, the aeroplane will return to that condition without oscillation.\n- :x: Static stability means that the aeroplane is also dynamically stable about the relevant axis.", + externalIds: ["ATPLQ-814951", "BGS-810648"], + href: "/modules/atpl/questions/BRYanzNr", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "1sAtIFk2", + text: "Which statement is correct?\n\n- :white_check_mark: Problems in the personal relationships between crew members are likely to hamper the communication process.\n- :x: Inconsistent communication improves flight safety.\n- :x: Personal conflict that takes place prior to take-off should wait to be addressed until the end of the flight.\n- :x: There is no relation between inadequate communication and incidents or accidents.", + externalIds: ["ATPLQ-402286", "AVEXAM-66724", "ATPLGS-626752"], + href: "/modules/atpl/questions/1sAtIFk2", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "8oFqQuHL", + text: "Which statement is correct?\n\n- :white_check_mark: The Solar System consists of the Sun, planets and stars.\n- :x: The planets move around the Sun like all stars of the Solar System.\n- :x: The Earth is one of the planets which are all moving in elliptical orbit around the Sun.\n- :x: The Sun moves in an elliptical orbit around the Earth.", + externalIds: ["AVEXAM-10586"], + href: "/modules/atpl/questions/8oFqQuHL", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "BgHXCT7I", + text: "Which statement is correct?\n\n- :white_check_mark: The climb limited take-off mass depends on pressure altitude and outer air temperature.\n- :x: The climb limited take-off mass will increase if the headwind component increases.\n- :x: The performance limited take-off mass is the highest of field length limited take-off mass climb limited take-off mass obstacle limited take-off mass.\n- :x: The climb limited take-off mass increases when a larger take-off flap setting is used.", + externalIds: [ + "ATPLQ-323595", + "ATPLGS-107415", + "ATPLGS-107575", + "ATPLGS-114227", + "BGS-320264", + "BGS-320248", + "BGS-320224", + "BGS-320656", + "AVEXAM-41520", + "AVEXAM-56017", + "AVEXAM-90038", + "AVEXAM-13194", + "AVEXAM-80302", + "ATPLGS-625115", + "ATPLGS-107438", + "AVEXAM-26125", + ], + href: "/modules/atpl/questions/BgHXCT7I", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "Y5RD4ZDw", + text: "Which statement is correct?\n\n- :white_check_mark: During a phugoid altitude varies significantly, but during a short period oscillation it remains approximately constant.\n- :x: During both a phugoid and a short period oscillation altitude remains approximately constant.\n- :x: During both a phugoid and a short period oscillation altitude varies significantly.\n- :x: During a phugoid altitude remains approximately constant, but during a short period oscillation it varies significantly.", + externalIds: ["BGS-810669", "AVEXAM-17048"], + href: "/modules/atpl/questions/Y5RD4ZDw", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "ZeQuarz6", + text: "Which statement is correct?\n\n- :white_check_mark: The climb limited Take-off Mass depends on pressure altitude and outside air temperature.\n- :x: The climb limited Take-off Mass increases when a larger take-off flap setting is used.\n- :x: The performance limited Take-off Mass is the highest of:\ni) field length limited Take-off Mass;\nii) climb limited Take-off Mass;\niii) obstacle limited Take-off Mass.\n- :x: The climb limited Take-off Mass will increase if the headwind component increases.", + externalIds: [ + "AVEXAM-80302", + "ATPLGS-114227", + "BGS-320248", + "ATPLQ-322985", + "ATPLQ-329553", + "ATPLQ-321955", + "ATPLGS-107438", + ], + href: "/modules/atpl/questions/ZeQuarz6", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "FkDh9o1x", + text: "Which statement is correct?\n\n- :white_check_mark: Obstacle limited takeoff mass\n- :x: Climb limited takeoff mass\n- :x: Tyre speed limited takeoff mass\n- :x: Field length limited takeoff mass", + externalIds: [ + "AVEXAM-13194", + "BGS-320215", + "ATPLQ-329010", + "ATPLGS-107455", + ], + href: "/modules/atpl/questions/FkDh9o1x", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "gid9ddHM", href: "/modules/atpl/questions/gid9ddHM" }, + ], + }, + { + id: "gid9ddHM", + text: "Which statement is correct?\n\n- :white_check_mark: Extension of flaps causes a reduction of the stall speed, the maximum glide distance also reduces.\n- :x: Extension of flaps has no influence on the minimum rate of descent, as only the TAS has to be taken into account.\n- :x: Extension of flaps will increase (CL/CD MAX), causing the minimum rate of descent to decrease.\n- :x: Spoiler extension decreases the stall speed and the minimum rate of descent, but increases the minimum descent angle.", + externalIds: ["AVEXAM-41717"], + href: "/modules/atpl/questions/gid9ddHM", + learningObjectives: [ + { id: "010.07", href: "/modules/atpl/learning-objectives/010.07" }, + { id: "032.04", href: "/modules/atpl/learning-objectives/032.04" }, + { id: "040.02", href: "/modules/atpl/learning-objectives/040.02" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.07", href: "/modules/atpl/learning-objectives/050.07" }, + { id: "061.01", href: "/modules/atpl/learning-objectives/061.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.04", href: "/modules/atpl/learning-objectives/081.04" }, + ], + relatedQuestions: [ + { id: "K7HuwYXz", href: "/modules/atpl/questions/K7HuwYXz" }, + { id: "ezh4CuEv", href: "/modules/atpl/questions/ezh4CuEv" }, + { id: "Ax7FFF3g", href: "/modules/atpl/questions/Ax7FFF3g" }, + { id: "SxFJ91nN", href: "/modules/atpl/questions/SxFJ91nN" }, + { id: "uV7RVfAr", href: "/modules/atpl/questions/uV7RVfAr" }, + { id: "2qQjMgG1", href: "/modules/atpl/questions/2qQjMgG1" }, + { id: "UrGzEwAj", href: "/modules/atpl/questions/UrGzEwAj" }, + { id: "kA7q1I98", href: "/modules/atpl/questions/kA7q1I98" }, + { id: "IJKUxABS", href: "/modules/atpl/questions/IJKUxABS" }, + { id: "fklnIxec", href: "/modules/atpl/questions/fklnIxec" }, + { id: "lapzBT5F", href: "/modules/atpl/questions/lapzBT5F" }, + { id: "BRYanzNr", href: "/modules/atpl/questions/BRYanzNr" }, + { id: "1sAtIFk2", href: "/modules/atpl/questions/1sAtIFk2" }, + { id: "8oFqQuHL", href: "/modules/atpl/questions/8oFqQuHL" }, + { id: "BgHXCT7I", href: "/modules/atpl/questions/BgHXCT7I" }, + { id: "Y5RD4ZDw", href: "/modules/atpl/questions/Y5RD4ZDw" }, + { id: "ZeQuarz6", href: "/modules/atpl/questions/ZeQuarz6" }, + { id: "FkDh9o1x", href: "/modules/atpl/questions/FkDh9o1x" }, + ], + }, + { + id: "qAHZS9GQ", + text: "Which of the following statements is true?\n\n- :white_check_mark: Mist is a reduction of visibility due to the presence of (liquid) water droplets in the air.\n- :x: Standing waves are always accompanied by severe turbulence.\n- :x: Airframe icing cannot occur in clear air.\n- :x: An isotach is a line joining all points of equal windshear.", + externalIds: ["BGS-501393"], + href: "/modules/atpl/questions/qAHZS9GQ", + learningObjectives: [ + { id: "010.08", href: "/modules/atpl/learning-objectives/010.08" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.01", href: "/modules/atpl/learning-objectives/050.01" }, + { id: "050.02", href: "/modules/atpl/learning-objectives/050.02" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.08", href: "/modules/atpl/learning-objectives/050.08" }, + { id: "050.10", href: "/modules/atpl/learning-objectives/050.10" }, + { id: "071.01", href: "/modules/atpl/learning-objectives/071.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.06", href: "/modules/atpl/learning-objectives/081.06" }, + ], + relatedQuestions: [ + { id: "0lrHJ0lU", href: "/modules/atpl/questions/0lrHJ0lU" }, + { id: "L4p38s2q", href: "/modules/atpl/questions/L4p38s2q" }, + { id: "HDxA6ffA", href: "/modules/atpl/questions/HDxA6ffA" }, + { id: "Ks1U1MM0", href: "/modules/atpl/questions/Ks1U1MM0" }, + { id: "KHg6zlxZ", href: "/modules/atpl/questions/KHg6zlxZ" }, + { id: "MgOxggSM", href: "/modules/atpl/questions/MgOxggSM" }, + { id: "fNBcOqtM", href: "/modules/atpl/questions/fNBcOqtM" }, + { id: "rMK91GJp", href: "/modules/atpl/questions/rMK91GJp" }, + { id: "KQPeOPbH", href: "/modules/atpl/questions/KQPeOPbH" }, + { id: "ufkqwFph", href: "/modules/atpl/questions/ufkqwFph" }, + { id: "PFzI3zxJ", href: "/modules/atpl/questions/PFzI3zxJ" }, + { id: "jq6VSU7z", href: "/modules/atpl/questions/jq6VSU7z" }, + { id: "dgWvnRpl", href: "/modules/atpl/questions/dgWvnRpl" }, + ], + }, + { + id: "L4p38s2q", + text: "Which of the following statements is true?\n\n- :white_check_mark: Stressors accumulate thus increasing the likelihood to exhaustion.\n- :x: Stressors are independent from each other.\n- :x: Stress should always be avoided under any circumstances.\n- :x: People are capable of living without stress.", + externalIds: ["AVEXAM-80839"], + href: "/modules/atpl/questions/L4p38s2q", + learningObjectives: [ + { id: "010.08", href: "/modules/atpl/learning-objectives/010.08" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.01", href: "/modules/atpl/learning-objectives/050.01" }, + { id: "050.02", href: "/modules/atpl/learning-objectives/050.02" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.08", href: "/modules/atpl/learning-objectives/050.08" }, + { id: "050.10", href: "/modules/atpl/learning-objectives/050.10" }, + { id: "071.01", href: "/modules/atpl/learning-objectives/071.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.06", href: "/modules/atpl/learning-objectives/081.06" }, + ], + relatedQuestions: [ + { id: "qAHZS9GQ", href: "/modules/atpl/questions/qAHZS9GQ" }, + { id: "0lrHJ0lU", href: "/modules/atpl/questions/0lrHJ0lU" }, + { id: "HDxA6ffA", href: "/modules/atpl/questions/HDxA6ffA" }, + { id: "Ks1U1MM0", href: "/modules/atpl/questions/Ks1U1MM0" }, + { id: "KHg6zlxZ", href: "/modules/atpl/questions/KHg6zlxZ" }, + { id: "MgOxggSM", href: "/modules/atpl/questions/MgOxggSM" }, + { id: "fNBcOqtM", href: "/modules/atpl/questions/fNBcOqtM" }, + { id: "rMK91GJp", href: "/modules/atpl/questions/rMK91GJp" }, + { id: "KQPeOPbH", href: "/modules/atpl/questions/KQPeOPbH" }, + { id: "ufkqwFph", href: "/modules/atpl/questions/ufkqwFph" }, + { id: "PFzI3zxJ", href: "/modules/atpl/questions/PFzI3zxJ" }, + { id: "jq6VSU7z", href: "/modules/atpl/questions/jq6VSU7z" }, + { id: "dgWvnRpl", href: "/modules/atpl/questions/dgWvnRpl" }, + ], + }, + { + id: "HDxA6ffA", + text: "Which of the following statements is true?\n\n- :white_check_mark: QNH can be equal to QFE.\n- :x: QNH is always equal to QFE.\n- :x: QNH is always higher than QFE.\n- :x: QNH is always lower than QFE.", + externalIds: ["BGS-500978", "AVEXAM-34930"], + href: "/modules/atpl/questions/HDxA6ffA", + learningObjectives: [ + { id: "010.08", href: "/modules/atpl/learning-objectives/010.08" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.01", href: "/modules/atpl/learning-objectives/050.01" }, + { id: "050.02", href: "/modules/atpl/learning-objectives/050.02" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.08", href: "/modules/atpl/learning-objectives/050.08" }, + { id: "050.10", href: "/modules/atpl/learning-objectives/050.10" }, + { id: "071.01", href: "/modules/atpl/learning-objectives/071.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.06", href: "/modules/atpl/learning-objectives/081.06" }, + ], + relatedQuestions: [ + { id: "qAHZS9GQ", href: "/modules/atpl/questions/qAHZS9GQ" }, + { id: "0lrHJ0lU", href: "/modules/atpl/questions/0lrHJ0lU" }, + { id: "L4p38s2q", href: "/modules/atpl/questions/L4p38s2q" }, + { id: "Ks1U1MM0", href: "/modules/atpl/questions/Ks1U1MM0" }, + { id: "KHg6zlxZ", href: "/modules/atpl/questions/KHg6zlxZ" }, + { id: "MgOxggSM", href: "/modules/atpl/questions/MgOxggSM" }, + { id: "fNBcOqtM", href: "/modules/atpl/questions/fNBcOqtM" }, + { id: "rMK91GJp", href: "/modules/atpl/questions/rMK91GJp" }, + { id: "KQPeOPbH", href: "/modules/atpl/questions/KQPeOPbH" }, + { id: "ufkqwFph", href: "/modules/atpl/questions/ufkqwFph" }, + { id: "PFzI3zxJ", href: "/modules/atpl/questions/PFzI3zxJ" }, + { id: "jq6VSU7z", href: "/modules/atpl/questions/jq6VSU7z" }, + { id: "dgWvnRpl", href: "/modules/atpl/questions/dgWvnRpl" }, + ], + }, + { + id: "Ks1U1MM0", + text: "Which of the following statements is true?\n\n- :white_check_mark: Aircraft Basic Mass tends to increase slightly over\ntime\n- :x: Aircraft mass does not affect aircraft\nperformance\n- :x: Aircraft Basic Mass tends to decrease slightly over\ntime\n- :x: Aircraft Basic Mass is always the same", + externalIds: ["BGS-991461"], + href: "/modules/atpl/questions/Ks1U1MM0", + learningObjectives: [ + { id: "010.08", href: "/modules/atpl/learning-objectives/010.08" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.01", href: "/modules/atpl/learning-objectives/050.01" }, + { id: "050.02", href: "/modules/atpl/learning-objectives/050.02" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.08", href: "/modules/atpl/learning-objectives/050.08" }, + { id: "050.10", href: "/modules/atpl/learning-objectives/050.10" }, + { id: "071.01", href: "/modules/atpl/learning-objectives/071.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.06", href: "/modules/atpl/learning-objectives/081.06" }, + ], + relatedQuestions: [ + { id: "qAHZS9GQ", href: "/modules/atpl/questions/qAHZS9GQ" }, + { id: "0lrHJ0lU", href: "/modules/atpl/questions/0lrHJ0lU" }, + { id: "L4p38s2q", href: "/modules/atpl/questions/L4p38s2q" }, + { id: "HDxA6ffA", href: "/modules/atpl/questions/HDxA6ffA" }, + { id: "KHg6zlxZ", href: "/modules/atpl/questions/KHg6zlxZ" }, + { id: "MgOxggSM", href: "/modules/atpl/questions/MgOxggSM" }, + { id: "fNBcOqtM", href: "/modules/atpl/questions/fNBcOqtM" }, + { id: "rMK91GJp", href: "/modules/atpl/questions/rMK91GJp" }, + { id: "KQPeOPbH", href: "/modules/atpl/questions/KQPeOPbH" }, + { id: "ufkqwFph", href: "/modules/atpl/questions/ufkqwFph" }, + { id: "PFzI3zxJ", href: "/modules/atpl/questions/PFzI3zxJ" }, + { id: "jq6VSU7z", href: "/modules/atpl/questions/jq6VSU7z" }, + { id: "dgWvnRpl", href: "/modules/atpl/questions/dgWvnRpl" }, + ], + }, + { + id: "KHg6zlxZ", + text: "Which of the following statements is true?\n\n- :white_check_mark: VRA must be less than or equal to VB\n- :x: VRA and VB are the same thing\n- :x: VRA must be greater than VB\n- :x: VRA must be less than VB", + externalIds: ["BGS-991467"], + href: "/modules/atpl/questions/KHg6zlxZ", + learningObjectives: [ + { id: "010.08", href: "/modules/atpl/learning-objectives/010.08" }, + { id: "040.03", href: "/modules/atpl/learning-objectives/040.03" }, + { id: "050.01", href: "/modules/atpl/learning-objectives/050.01" }, + { id: "050.02", href: "/modules/atpl/learning-objectives/050.02" }, + { id: "050.04", href: "/modules/atpl/learning-objectives/050.04" }, + { id: "050.08", href: "/modules/atpl/learning-objectives/050.08" }, + { id: "050.10", href: "/modules/atpl/learning-objectives/050.10" }, + { id: "071.01", href: "/modules/atpl/learning-objectives/071.01" }, + { id: "081.01", href: "/modules/atpl/learning-objectives/081.01" }, + { id: "081.06", href: "/modules/atpl/learning-objectives/081.06" }, + ], + relatedQuestions: [ + { id: "qAHZS9GQ", href: "/modules/atpl/questions/qAHZS9GQ" }, + { id: "0lrHJ0lU", href: "/modules/atpl/questions/0lrHJ0lU" }, + { id: "L4p38s2q", href: "/modules/atpl/questions/L4p38s2q" }, + { id: "HDxA6ffA", href: "/modules/atpl/questions/HDxA6ffA" }, + { id: "Ks1U1MM0", href: "/modules/atpl/questions/Ks1U1MM0" }, + { id: "MgOxggSM", href: "/modules/atpl/questions/MgOxggSM" }, + { id: "fNBcOqtM", href: "/modules/atpl/questions/fNBcOqtM" }, + { id: "rMK91GJp", href: "/modules/atpl/questions/rMK91GJp" }, + { id: "KQPeOPbH", href: "/modules/atpl/questions/KQPeOPbH" }, + { id: "ufkqwFph", href: "/modules/atpl/questions/ufkqwFph" }, + { id: "PFzI3zxJ", href: "/modules/atpl/questions/PFzI3zxJ" }, + { id: "jq6VSU7z", href: "/modules/atpl/questions/jq6VSU7z" }, + { id: "dgWvnRpl", href: "/modules/atpl/questions/dgWvnRpl" }, + ], + }, +]; diff --git a/libs/react/components/src/question-list/question-list.stories.tsx b/libs/react/components/src/question-list/question-list.stories.tsx index f2ae33831..05291d9ac 100644 --- a/libs/react/components/src/question-list/question-list.stories.tsx +++ b/libs/react/components/src/question-list/question-list.stories.tsx @@ -1,4 +1,5 @@ import { QuestionList } from "./question-list"; +import { itemsMock } from "./question-list.mock"; import type { Meta, StoryObj } from "@storybook/react"; type Story = StoryObj; @@ -13,344 +14,7 @@ const meta: Meta = { loading: false, error: false, forceMode: undefined, - items: [ - { - id: "gdjhd", - questionId: "26mpt", - variantId: "gdjhd", - text: "With bleed air supplied from the APU (APU bleed value open or same pack operation) the pack flow is automatically selected to:\n\n- :white_check_mark: High\n- :x: Normal\n- :x: Low\n- :x: ECON", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/26mpt?variantId=gdjhd", - }, - { - id: "tsz4e", - questionId: "tlxkb", - variantId: "tsz4e", - text: "The zone controller or the air conditioning system controllers (ACSC) optimize temperature by acting on the?\n\n- :white_check_mark: Trim air valves\n- :x: Skin air valves\n- :x: Isolation valves\n- :x: Pack valves", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/tlxkb?variantId=tsz4e", - }, - { - id: "bjx1i", - questionId: "8ai7y", - variantId: "bjx1i", - text: "What would cause an amber PACK FAULT light on the PACK pb-sw to illuminate?\n\n- :x: Pack outlet overheat\n- :x: Compressor outlet overheat\n- :x: Switch position disagreement in comparison to the pack flow control valve\n- :white_check_mark: All answers are correct", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/8ai7y?variantId=bjx1i", - }, - { - id: "g7gea", - questionId: "yaqc4", - variantId: "g7gea", - text: "The two cabin pressure controllers receive signals from:\n\n- :x: ADIRS only\n- :x: ADIRS and FMGC only\n- :white_check_mark: ADIRS, FMGC, LGCIU and EIU\n- :x: ADIRS, FMGC and EIU only", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/yaqc4?variantId=g7gea", - }, - { - id: "7d7lv", - questionId: "ns2wdk", - variantId: "7d7lv", - text: "Under what conditions should the pack flow controller on an A319 be set to HI?\n\n- :x: In cold conditions to achieve a higher cabin temperature range\n- :x: If the number of Passengers is below 115\n- :white_check_mark: For abnormal hot and humid conditions\n- :x: If the number of occupants is above 138", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/ns2wdk?variantId=7d7lv", - }, - { - id: "bfwrh", - questionId: "ukrp6", - variantId: "bfwrh", - text: "With both the BLOWER and EXTRACT pushbutton switches in OVRD, what happens to the ventilation system?\n\n- :x: The system goes into open configuration and the blower fan stops\n- :white_check_mark: The system goes into smoke configuration and the blower fan stops\n- :x: The system goes into open configuration and the extract fan stops\n- :x: The system goes into intermediate configuration and the extract fan stops", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/ukrp6?variantId=bfwrh", - }, - { - id: "g2udk", - questionId: "k4cum", - variantId: "g2udk", - text: "The pack flow control valve closes automatically in case of:\n\n- :white_check_mark: Pack overheat, engine fire push button operation, engine start, ditching push button pressed\n- :x: Bleed valve failure, pack outlet pressure increase\n- :x: All Answers are correct\n- :x: Takeoff when takeoff power is set and the main landing gear struts are compressed", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/k4cum?variantId=g2udk", - }, - { - id: "hec5l", - questionId: "6rpyu", - variantId: "hec5l", - text: "The cabin pressure during lift-off and at touchdown is ________ ambient pressure\n\n- :white_check_mark: Higher than\n- :x: Lower than\n- :x: Equal to\n- :x: Irrespective to", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/6rpyu?variantId=hec5l", - }, - { - id: "037r8", - questionId: "qi743", - variantId: "037r8", - text: "Having manually set the LDG ELEV the cabin altitude is…\n\n- :x: Only controllable manually through the MAN V/S CTL\n- :white_check_mark: Still controlled automatically through the outflow valve\n- :x: Still controlled normally through the safety valve\n- :x: Only controllable manually through the LDG ELEV selector", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/qi743?variantId=037r8", - }, - { - id: "em1ms", - questionId: "11tl3", - variantId: "em1ms", - text: "The PACK FLOW selector on an A320 is in LO position. Which statement is correct?\n\n- :x: The pack valve flow selection is 80%\n- :x: The pack flow can be automatically selected up to 100% when the cooling demand cannot be satisfied\n- :x: With APU bleed supply or single Pack operation, HI pack valve flow is automatically selected\n- :white_check_mark: All answers are correct", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/11tl3?variantId=em1ms", - }, - { - id: "t67q9", - questionId: "9a944", - variantId: "t67q9", - text: "The RAM AIR INLET is powered via…\n\n- :x: AC BUS 1\n- :x: AC BUS 2\n- :white_check_mark: DC ESS BUS\n- :x: DC BUS 1", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/9a944?variantId=t67q9", - }, - { - id: "6dgpsi", - questionId: "gqqbm", - variantId: "6dgpsi", - text: "The PACK FLOW controller is set to NORM and yet the ECAM display shows PACK FLOW to be high. How is this possible?\n\n- :x: As the engines are not running the PACK FLOW indicators are at the position they were selected to at the last shut down\n- :x: As no bleed air is available the PACK FLOW valves are spring loaded to the fully open position\n- :white_check_mark: HI flow is automatically selected regardless of PACK FLOW selector position because air is only being supplied by the APU\n- :x: With cold outside air conditions the PACK FLOW is automatically increased to help increase the cabin temperature", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/gqqbm?variantId=6dgpsi", - }, - { - id: "kfw5s", - questionId: "fdodfi", - variantId: "kfw5s", - text: "Emergency evacuation checklist. Why do you have to check Δp = 0 if MAN CAB PR has been used?\n\n- :white_check_mark: Because the outflow valve does not open automatically at touchdown\n- :x: To facilitate the opening of the cargo doors by fire brigad\n- :x: Because the safety valves are closed\n- :x: Because of an possible non indicated failure of the Residual Pressure Control Unit (RPCU)", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/fdodfi?variantId=kfw5s", - }, - { - id: "65xza", - questionId: "e4fr1", - variantId: "65xza", - text: "When the BLOWER pb is on OVRD:\n\n- :x: The system goes to open circuit configuration\n- :white_check_mark: The system goes to closed circuit configuration\n- :x: The blower fan will continue to run\n- :x: The blower fan is de-energized for the remainder of the flight", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/e4fr1?variantId=65xza", - }, - { - id: "k216y", - questionId: "kggt3", - variantId: "k216y", - text: "The avionics ventilation system is fully automatic. The normal operation configurations are:\n\n- :x: Open-circuit configuration, close-circuit configuration, smoke configuration\n- :x: Open-circuit configuration, close-circuit configuration\n- :white_check_mark: Open-circuit configuration, intermediate configuration, close-circuit configuration\n- :x: Open-circuit configuration, partially-open configuration, bypass-circuit configuration", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/kggt3?variantId=k216y", - }, - { - id: "459qv", - questionId: "htb5m", - variantId: "459qv", - text: "The temperature of each aircraft zone is optimized by means of …?\n\n- :x: A hot air valve\n- :x: A zone control valve\n- :x: A pack valve\n- :white_check_mark: A trim air valve", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/htb5m?variantId=459qv", - }, - { - id: "76a26", - questionId: "ggz8", - variantId: "76a26", - text: "The cabin pressurization system consists, among others, of:\n\n- :x: One outflow valve, one cabin pressure controller and two safety valves\n- :x: One outflow valve, two cabin pressure controllers and one safety valve\n- :white_check_mark: One outflow valve, two cabin pressure controllers and two safety valves\n- :x: Two outflow valves, one cabin pressure controller and two safety valves", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/ggz8?variantId=76a26", - }, - { - id: "fql2i", - questionId: "ou9i2", - variantId: "fql2i", - text: "Which answer about the two zone controller or ACSC (Air Conditioning System Controller) of the air conditioning system is correct?\n\n- :white_check_mark: Controller 1 regulates the cockpit temperature, controller 2 the temperature in the two cabin zones\n- :x: Controller 1 regulates the temperature in the two cabin zones, controller 2 the cockpit temperature\n- :x: Controller 1 regulates the cockpit temperature, controller 2 the temperature in the three cabin zones\n- :x: Controller 1 regulates the temperature in the the three cabin zones, controller 2 the cockpit temperature", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/ou9i2?variantId=fql2i", - }, - { - id: "buw18k", - questionId: "4m7d0j", - variantId: "buw18k", - text: "The MODE SEL pb sw in MAN mode allows you to use the MAN V/S CTL in order to…\n\n- :x: Manually alter the air inlet valve setting\n- :x: Manually adjust the pack flow valve\n- :white_check_mark: Manually adjust the outflow valve\n- :x: Manually alter the pack outflow valve setting", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/4m7d0j?variantId=buw18k", - }, - { - id: "ozwn3", - questionId: "dloyb", - variantId: "ozwn3", - text: "What is the limiting factor for opening the RAM AIR valve?\n\n- :x: Aircraft at or below 10’000ft\n- :white_check_mark: Cabin differential pressure below 1 PSI\n- :x: Aircraft must be on ground\n- :x: Aircraft must be fully depressurized", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/dloyb?variantId=ozwn3", - }, - { - id: "290a1", - questionId: "ygjsu", - variantId: "290a1", - text: "The ram air inlet flap of the air conditioning pack:\n\n- :x: Closes during takeoffwhen takeoff power is set and the main landing gear struts are compressed\n- :x: Opens during landing they closes as soon as the main landing gear struts are compressed, as long as speed is at or above 70 knots\n- :x: It opens 20 seconds after the speed drops below 70 knot\n- :white_check_mark: All answers are correct", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/ygjsu?variantId=290a1", - }, - { - id: "rrgbd", - questionId: "t5t1cj", - variantId: "rrgbd", - text: "The input of the QNH in the FMGS for the approach influences, among others….\n\n- :x: The GS mini\n- :white_check_mark: The pressurization schedule of the CPC Cabin Pressure Controllers\n- :x: The pressurization schedule and the GS mini\n- :x: The BARO minimum for NON-PROC. Appr", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/t5t1cj?variantId=rrgbd", - }, - { - id: "55yct", - questionId: "ze2ak", - variantId: "55yct", - text: "On ECAM CAB PRESS page, the outflow valve indicator changes to amber when the valve\n\n- :x: is fully closed\n- :white_check_mark: open more than 95% during flight\n- :x: is fully closed\n- :x: is in transit", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/ze2ak?variantId=55yct", - }, - { - id: "hi5df", - questionId: "lcl4a", - variantId: "hi5df", - text: "What is the maximum negative differential pressure for the cabin:\n\n- :x: 0 PSI\n- :white_check_mark: - 1 PSI\n- :x: - 2 PSI\n- :x: + 1 PSI", - learningObjectives: [ - { - name: "A320.01", - href: "/modules/type/learning-objectives/A320.01", - }, - ], - externalIds: [], - href: "/modules/type/questions/lcl4a?variantId=hi5df", - }, - ], + items: itemsMock, sx: { height: "500px", overflow: "hidden", diff --git a/libs/react/components/src/question-list/question-list.tsx b/libs/react/components/src/question-list/question-list.tsx index d041673f2..dcca92e1a 100644 --- a/libs/react/components/src/question-list/question-list.tsx +++ b/libs/react/components/src/question-list/question-list.tsx @@ -6,15 +6,17 @@ import type { SearchListProps } from "../search-list"; export type QuestionListItem = { id: string; - questionId: string; - variantId: string; href: string; text: string; + externalIds: string[]; learningObjectives: Array<{ - name: string; + id: string; + href: string; + }>; + relatedQuestions: Array<{ + id: string; href: string; }>; - externalIds: string[]; }; export type QuestionListProps = Omit< @@ -26,7 +28,7 @@ export type QuestionListProps = Omit< | "errorMessage" | "noDataMessage" > & { - items?: SearchListProps["items"]; + items?: QuestionListItem[]; }; export const QuestionList = forwardRef( @@ -44,6 +46,7 @@ export const QuestionList = forwardRef( ID Question Learning Objectives + Related Questions External IDs @@ -52,47 +55,67 @@ export const QuestionList = forwardRef( - {result.questionId} -
- {result.variantId} + {result.id} {result.text} - {result.learningObjectives.map(({ name, href }) => ( + {result.learningObjectives.slice(0, 5).map(({ id, href }) => ( ))} + {result.learningObjectives.length > 5 && ( + + {`+ ${result.learningObjectives.length - 5} more`} + + )} - {result.externalIds.map((id) => ( + {result.relatedQuestions.slice(0, 5).map(({ id, href }) => ( + + ))} + {result.relatedQuestions.length > 5 && ( + + {`+ ${result.relatedQuestions.length - 5} more`} + + )} + + + {result.externalIds.slice(0, 5).map((id) => ( {id} ))} + {result.externalIds.length > 5 && ( + + {`+ ${result.externalIds.length - 5} more`} + + )} )} renderListItemContent={(result) => ( - {result.questionId} + {result.id} - - {result.variantId} - - {result.learningObjectives.map((lo) => lo.name).join(", ")} + {result.learningObjectives.map((lo) => lo.id).join(", ")} { selectedOptionId={"123"} status={"in-progress"} options={[ - { optionId: "123", text: "John" }, - { optionId: "456", text: "Jane" }, - { optionId: "789", text: "Jack" }, - { optionId: "102", text: "Jill" }, + { id: "123", text: "John" }, + { id: "456", text: "Jane" }, + { id: "789", text: "Jack" }, + { id: "102", text: "Jill" }, ]} />, ); diff --git a/libs/react/components/src/question-multiple-choice/question-multiple-choice.tsx b/libs/react/components/src/question-multiple-choice/question-multiple-choice.tsx index da5c291f4..cf741d755 100644 --- a/libs/react/components/src/question-multiple-choice/question-multiple-choice.tsx +++ b/libs/react/components/src/question-multiple-choice/question-multiple-choice.tsx @@ -79,7 +79,7 @@ export type QuestionMultipleChoiceStatus = "in-progress" | "show-result"; export type QuestionMultipleChoiceProps = { question?: string; - options?: Array<{ optionId: string; text: string }>; + options?: Array<{ id: string; text: string }>; status?: QuestionMultipleChoiceStatus; correctOptionId?: string; selectedOptionId?: string; @@ -87,7 +87,7 @@ export type QuestionMultipleChoiceProps = { loading?: boolean; compact?: boolean; disabled?: boolean; - annexHrefs?: string[]; + annexesHref?: string[]; onAnnexClicked?: (annexId: string) => void; onOptionClicked?: (optionId: string) => void; component?: React.ElementType; @@ -108,7 +108,7 @@ export const QuestionMultipleChoice = forwardRef< hideIrrelevant, options = [], disabled, - annexHrefs, + annexesHref, onAnnexClicked, onOptionClicked, ...others @@ -127,15 +127,15 @@ export const QuestionMultipleChoice = forwardRef< <> {question} - {annexHrefs?.map((annexHref) => ( + {annexesHref?.map((annex) => ( ))} @@ -152,7 +152,7 @@ export const QuestionMultipleChoice = forwardRef< /> ))} {!loading && - options.map(({ optionId, text }, index) => { + options.map(({ id: optionId, text }, index) => { const isRelevantOption = [ correctOptionId, selectedOptionId, diff --git a/libs/react/containers/src/blog/blog-post/blog-post.tsx b/libs/react/containers/src/blog/blog-post/blog-post.tsx index d7b849281..bbdbccd59 100644 --- a/libs/react/containers/src/blog/blog-post/blog-post.tsx +++ b/libs/react/containers/src/blog/blog-post/blog-post.tsx @@ -14,7 +14,6 @@ import { import { trpc } from "@chair-flight/trpc/client"; import { AnnexSearch } from "../../annexes/annex-search"; import { BugReportButton } from "../../layouts/components/app-buttons/app-buttons"; -import { QuestionOverview } from "../../questions/question-overview"; import { QuestionSearch } from "../../questions/question-search"; import { useUserVoyage } from "../../user/hooks/use-user-voyage"; import { container, getRequiredParam } from "../../wraper"; @@ -76,7 +75,6 @@ export const BlogPost: Container = container< Link, AnnexSearch, ModuleSelectionButton, - QuestionOverview, AirplaneTicketIcon, ChevronRightIcon, FlightTakeoffIcon, diff --git a/libs/react/containers/src/index.ts b/libs/react/containers/src/index.ts index 460b5fa52..769813a3b 100644 --- a/libs/react/containers/src/index.ts +++ b/libs/react/containers/src/index.ts @@ -14,8 +14,10 @@ export * from "./learning-objectives/learning-objective-questions"; export * from "./learning-objectives/learning-objectives-search"; export * from "./overviews/overview-modules"; export * from "./overviews/overview-welcome"; -export * from "./questions/question-overview"; +export * from "./questions/question-explanation"; +export * from "./questions/question-meta"; export * from "./questions/question-search"; +export * from "./questions/question-stand-alone"; export * from "./tests/test-exam"; export * from "./tests/test-maker"; export * from "./tests/test-review"; diff --git a/libs/react/containers/src/questions/question-explanation/index.ts b/libs/react/containers/src/questions/question-explanation/index.ts new file mode 100644 index 000000000..4c729638c --- /dev/null +++ b/libs/react/containers/src/questions/question-explanation/index.ts @@ -0,0 +1 @@ +export { QuestionExplanation } from "./question-explanation"; diff --git a/libs/react/containers/src/questions/question-explanation/question-explanation.mock.ts b/libs/react/containers/src/questions/question-explanation/question-explanation.mock.ts new file mode 100644 index 000000000..7c60da1ea --- /dev/null +++ b/libs/react/containers/src/questions/question-explanation/question-explanation.mock.ts @@ -0,0 +1,9 @@ +import type { AppRouterOutput } from "@chair-flight/trpc/server"; + +export const mockData: AppRouterOutput["containers"]["questions"]["getQuestionExplanation"] = + { + explanation: { + content: + '"use strict";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n hr: "hr",\n li: "li",\n ul: "ul",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsx(_components.hr, {}), "\\n", _jsxs(_components.ul, {\n children: ["\\n", _jsx(_components.li, {\n children: "The A/T automatically disengages approximately 2 seconds after touchdown."\n }), "\\n", _jsx(_components.li, {\n children: "the A/P must be manually disengaged after touchdown. Landing roll-out is executed manually after disengaging the A/P."\n }), "\\n"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n', + }, + }; diff --git a/libs/react/containers/src/questions/question-explanation/question-explanation.stories.tsx b/libs/react/containers/src/questions/question-explanation/question-explanation.stories.tsx new file mode 100644 index 000000000..47fa11930 --- /dev/null +++ b/libs/react/containers/src/questions/question-explanation/question-explanation.stories.tsx @@ -0,0 +1,35 @@ +import { trpcMsw } from "@chair-flight/trpc/mock"; +import { QuestionExplanation } from "./question-explanation"; +import { mockData } from "./question-explanation.mock"; +import type { Meta, StoryObj } from "@storybook/react"; + +type Story = StoryObj; + +export const Playground: Story = {}; + +const meta: Meta = { + title: "Containers/Questions/QuestionExplanation", + component: QuestionExplanation, + tags: ["autodocs"], + args: { + questionId: "Q00YQLC8JS", + questionBank: "atpl", + }, + argTypes: { + questionId: { + control: "select", + options: ["Q00YQLC8JS"], + }, + questionBank: { + control: "select", + options: ["atpl"], + }, + }, + parameters: { + msw: [ + trpcMsw.containers.questions.getQuestionExplanation.query(() => mockData), + ], + }, +}; + +export default meta; diff --git a/libs/react/containers/src/questions/question-explanation/question-explanation.tsx b/libs/react/containers/src/questions/question-explanation/question-explanation.tsx new file mode 100644 index 000000000..bc09a9c90 --- /dev/null +++ b/libs/react/containers/src/questions/question-explanation/question-explanation.tsx @@ -0,0 +1,65 @@ +import { Stack } from "@mui/joy"; +import { Markdown, Ups } from "@chair-flight/react/components"; +import { trpc } from "@chair-flight/trpc/client"; +import { container, getRequiredParam } from "../../wraper/container"; +import type { CommonComponentProps } from "../../wraper/container"; +import type { + QuestionBankName, + QuestionTemplateId, +} from "@chair-flight/core/question-bank"; +import type { AppRouterOutput } from "@chair-flight/trpc/client"; +import type { FunctionComponent } from "react"; + +type Props = { + questionBank: QuestionBankName; + questionId: QuestionTemplateId; +}; + +type Params = { + questionBank: QuestionBankName; + questionId: QuestionTemplateId; +}; + +type Data = + AppRouterOutput["containers"]["questions"]["getQuestionExplanation"]; + +export const QuestionExplanationComponent: FunctionComponent< + CommonComponentProps & Props & Data +> = ({ sx, component = "section", explanation }) => { + return ( + + {explanation ? ( + + ) : ( + + )} + + ); +}; + +export const QuestionExplanation = container((props) => { + const params = QuestionExplanation.useData(props); + return ; +}); + +QuestionExplanation.displayName = "QuestionExplanation"; + +QuestionExplanation.getData = async ({ helper, params }) => { + const router = helper.containers.questions; + const questionBank = getRequiredParam(params, "questionBank"); + const questionId = getRequiredParam(params, "questionId"); + return await router.getQuestionExplanation.fetch({ + questionBank, + questionId, + }); +}; + +QuestionExplanation.useData = (params) => { + const router = trpc.containers.questions; + const questionBank = getRequiredParam(params, "questionBank"); + const questionId = getRequiredParam(params, "questionId"); + return router.getQuestionExplanation.useSuspenseQuery({ + questionBank, + questionId, + })[0]; +}; diff --git a/libs/react/containers/src/questions/question-meta/index.ts b/libs/react/containers/src/questions/question-meta/index.ts new file mode 100644 index 000000000..705efd50d --- /dev/null +++ b/libs/react/containers/src/questions/question-meta/index.ts @@ -0,0 +1 @@ +export { QuestionMeta } from "./question-meta"; diff --git a/libs/react/containers/src/questions/question-meta/question-meta.mock.ts b/libs/react/containers/src/questions/question-meta/question-meta.mock.ts new file mode 100644 index 000000000..76b2bac09 --- /dev/null +++ b/libs/react/containers/src/questions/question-meta/question-meta.mock.ts @@ -0,0 +1,21 @@ +import type { AppRouterOutput } from "@chair-flight/trpc/server"; + +export const mockData: AppRouterOutput["containers"]["questions"]["getQuestionMeta"] = + { + annexes: [], + learningObjectives: [ + { + id: "B737.04", + href: "/modules/type/learning-objectives/B737.04", + parentId: "B737", + courses: [{ id: "B737", text: "B737" }], + text: "Automatic Flight", + source: "B737 FCOM", + questionBank: "type", + subject: "B737", + numberOfQuestions: 31, + }, + ], + relatedQuestions: [], + externalIds: [], + }; diff --git a/libs/react/containers/src/questions/question-meta/question-meta.stories.tsx b/libs/react/containers/src/questions/question-meta/question-meta.stories.tsx new file mode 100644 index 000000000..257b5cedc --- /dev/null +++ b/libs/react/containers/src/questions/question-meta/question-meta.stories.tsx @@ -0,0 +1,33 @@ +import { trpcMsw } from "@chair-flight/trpc/mock"; +import { QuestionMeta } from "./question-meta"; +import { mockData } from "./question-meta.mock"; +import type { Meta, StoryObj } from "@storybook/react"; + +type Story = StoryObj; + +export const Playground: Story = {}; + +const meta: Meta = { + title: "Containers/Questions/QuestionMeta", + component: QuestionMeta, + tags: ["autodocs"], + args: { + questionId: "Q00YQLC8JS", + questionBank: "atpl", + }, + argTypes: { + questionId: { + control: "select", + options: ["Q00YQLC8JS"], + }, + questionBank: { + control: "select", + options: ["ATPL"], + }, + }, + parameters: { + msw: [trpcMsw.containers.questions.getQuestionMeta.query(() => mockData)], + }, +}; + +export default meta; diff --git a/libs/react/containers/src/questions/question-meta/question-meta.tsx b/libs/react/containers/src/questions/question-meta/question-meta.tsx new file mode 100644 index 000000000..f707eb15e --- /dev/null +++ b/libs/react/containers/src/questions/question-meta/question-meta.tsx @@ -0,0 +1,103 @@ +import { Grid, Link, Sheet, Stack, Typography } from "@mui/joy"; +import { + LearningObjectiveList, + QuestionList, + QuestionMultipleChoice, + Ups, +} from "@chair-flight/react/components"; +import { trpc } from "@chair-flight/trpc/client"; +import { container, getRequiredParam } from "../../wraper/container"; +import type { CommonComponentProps } from "../../wraper/container"; +import type { + QuestionBankName, + QuestionTemplateId, +} from "@chair-flight/core/question-bank"; +import type { AppRouterOutput } from "@chair-flight/trpc/client"; +import type { FunctionComponent } from "react"; + +type Props = { + questionBank: QuestionBankName; + questionId: QuestionTemplateId; + onNavigateToNewSeed?: (args: { seed: string }) => void; +}; + +type Params = { + questionBank: QuestionBankName; + questionId: QuestionTemplateId; +}; + +type Data = AppRouterOutput["containers"]["questions"]["getQuestionMeta"]; + +export const QuestionMetaComponent: FunctionComponent< + CommonComponentProps & Props & Data +> = ({ + sx, + component = "section", + learningObjectives, + relatedQuestions, + externalIds, +}) => { + return ( + + + Learning Objectives + + + + Related Questions + + + + External References + + + {externalIds.length > 0 ? ( + + {externalIds.map((ref) => ( + + + {ref.id} + + + ))} + + ) : ( + + )} + + + ); +}; + +export const QuestionMeta = container((props) => { + const data = QuestionMeta.useData(props); + return ; +}); + +QuestionMeta.displayName = "QuestionMeta"; + +QuestionMeta.getData = async ({ helper, params }) => { + const router = helper.containers.questions; + const questionBank = getRequiredParam(params, "questionBank"); + const questionId = getRequiredParam(params, "questionId"); + return await router.getQuestionMeta.fetch({ + questionBank, + questionId, + }); +}; + +QuestionMeta.useData = (params) => { + const router = trpc.containers.questions; + const questionBank = getRequiredParam(params, "questionBank"); + const questionId = getRequiredParam(params, "questionId"); + return router.getQuestionMeta.useSuspenseQuery({ + questionBank, + questionId, + })[0]; +}; + +QuestionMeta.LoadingFallback = ({ sx }) => ( + + + +); diff --git a/libs/react/containers/src/questions/question-overview/index.ts b/libs/react/containers/src/questions/question-overview/index.ts deleted file mode 100644 index 01438ad9e..000000000 --- a/libs/react/containers/src/questions/question-overview/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { QuestionOverview } from "./question-overview"; diff --git a/libs/react/containers/src/questions/question-overview/question-overview.mock.ts b/libs/react/containers/src/questions/question-overview/question-overview.mock.ts deleted file mode 100644 index 6bce299e6..000000000 --- a/libs/react/containers/src/questions/question-overview/question-overview.mock.ts +++ /dev/null @@ -1,47 +0,0 @@ -import type { AppRouterOutput } from "@chair-flight/trpc/server"; - -export const mockData: AppRouterOutput["containers"]["questions"]["getQuestionOverview"] = - { - template: { - id: "Q000YBA1ON", - learningObjectives: ["010.01"], - explanation: "", - variants: { - dsLWKxr9: { - type: "simple", - id: "dsLWKxr9", - question: - "Annex 14 to the convention on international civil aviation contains SARPS for:", - options: [ - { id: "AIXXXDXGUH", text: "aerodromes.", correct: true, why: "" }, - { id: "A18NL7DOHU", text: "security.", correct: false, why: "" }, - { - id: "AC0EHU7TT6", - text: "facilitation.", - correct: false, - why: "", - }, - { - id: "A55C2LXDYK", - text: "none of the above.", - correct: false, - why: "", - }, - ], - annexes: [], - externalIds: ["ATPLGS-622143", "AVEXAM-67778", "AVEXAM-67778"], - explanation: "", - }, - }, - srcLocation: "libs/content/question-bank-atpl/questions/010/010.01.json", - }, - annexes: {}, - learningObjectives: [ - { - id: "010.01", - text: "International Law:\n- Conventions, Agreements And Organisations", - href: "/modules/atpl/learning-objectives/010.01", - }, - ], - editLink: "/modules/atpl/questions/Q000YBA1ON/edit", - }; diff --git a/libs/react/containers/src/questions/question-overview/question-overview.stories.tsx b/libs/react/containers/src/questions/question-overview/question-overview.stories.tsx deleted file mode 100644 index ac7ed7b10..000000000 --- a/libs/react/containers/src/questions/question-overview/question-overview.stories.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { trpcMsw } from "@chair-flight/trpc/mock"; -import { QuestionOverview } from "./question-overview"; -import { mockData } from "./question-overview.mock"; -import type { Meta, StoryObj } from "@storybook/react"; - -type Story = StoryObj; - -export const Playground: Story = { - args: { - questionId: "Q00YQLC8JS", - }, -}; - -const meta: Meta = { - title: "Containers/Questions/QuestionOverview", - component: QuestionOverview, - tags: ["autodocs"], - argTypes: { - questionId: { - control: "select", - options: ["Q00YQLC8JS"], - }, - variantId: { - control: "select", - options: [undefined], - }, - seed: { - control: "select", - options: [undefined], - }, - }, - parameters: { - msw: [ - trpcMsw.containers.questions.getQuestionOverview.query(() => mockData), - ], - }, -}; - -export default meta; diff --git a/libs/react/containers/src/questions/question-overview/question-overview.tsx b/libs/react/containers/src/questions/question-overview/question-overview.tsx deleted file mode 100644 index 6be5f5cbc..000000000 --- a/libs/react/containers/src/questions/question-overview/question-overview.tsx +++ /dev/null @@ -1,360 +0,0 @@ -import { Fragment, useEffect, useMemo, useState } from "react"; -import { tabPanelClasses } from "@mui/base"; -import { default as OpenInNewIcon } from "@mui/icons-material/OpenInNew"; -import { default as RefreshIcon } from "@mui/icons-material/Refresh"; -import { - Button, - CircularProgress, - Divider, - Link, - List, - ListItem, - Tab, - TabList, - TabPanel, - Table, - Tabs, - Typography, - dividerClasses, - tabClasses, - tabListClasses, -} from "@mui/joy"; -import { getRandomId, getRandomShuffler } from "@chair-flight/base/utils"; -import { - getQuestion, - getQuestionPreview, -} from "@chair-flight/core/question-bank"; -import { - ImageViewer, - MarkdownClient, - QuestionMultipleChoice, - Ups, -} from "@chair-flight/react/components"; -import { trpc } from "@chair-flight/trpc/client"; -import { container, getRequiredParam } from "../../wraper/container"; -import type { - QuestionBankName, - QuestionTemplateId, - QuestionVariantId, -} from "@chair-flight/core/question-bank"; -import type { - DrawingPoints, - QuestionMultipleChoiceStatus as Status, -} from "@chair-flight/react/components"; -import type { AppRouterOutput } from "@chair-flight/trpc/client"; - -type DrawingPointsMap = Record; - -type TabName = "question" | "explanation" | "meta" | "variants"; - -type Props = { - questionBank: QuestionBankName; - questionId: QuestionTemplateId; - variantId?: QuestionVariantId; - seed?: string; - onQuestionChanged?: (args: { variantId: string; seed: string }) => void; -}; - -type Params = { - questionBank: QuestionBankName; - questionId: QuestionTemplateId; -}; - -type Data = AppRouterOutput["containers"]["questions"]["getQuestionOverview"]; - -const shuffle = getRandomShuffler("123"); - -export const QuestionOverview = container( - ({ - questionId, - questionBank, - seed: initialSeed, - variantId: initialVariantId, - onQuestionChanged, - sx, - component = "section", - }) => { - const [tab, setTab] = useState("question"); - const [seed, setSeed] = useState(initialSeed ?? getRandomId()); - const [variantId, setVariantId] = useState(initialVariantId); - const [selectedOption, setSelectedOption] = useState(); - const [currentAnnex, setCurrentAnnex] = useState(); - const [selectedStatus, setSelectedStatus] = useState("in-progress"); - const [annexDrawings, setAnnexDrawings] = useState({}); - const questionOverview = QuestionOverview.useData({ - questionBank, - questionId, - }); - - const questionTemplate = questionOverview.template; - const allVariantsMap = questionOverview.template.variants; - const learningObjectives = questionOverview.learningObjectives; - const allVariantsArray = Object.values(allVariantsMap); - const variant = allVariantsMap[variantId ?? ""] ?? allVariantsArray[0]; - const externalReferences = variant.externalIds; - const showMeta = !!learningObjectives.length; - const showExplanation = !!questionTemplate.explanation; - const dividerWidth = "sm" as const; - - const question = useMemo( - () => getQuestion(questionTemplate, { variantId, seed }), - [variantId, questionTemplate, seed], - ); - - const randomizedOptions = useMemo( - () => getRandomShuffler(seed ?? "")(question.options), - [question, seed], - ); - - const navigateToVariant = (variantId: string, seed: string) => { - setSelectedOption(undefined); - setVariantId(variantId); - setTab("question"); - setSelectedStatus("in-progress"); - setSeed(seed); - onQuestionChanged?.({ seed, variantId }); - }; - - useEffect(() => { - if (initialSeed) setSeed(initialSeed); - if (initialVariantId) setVariantId(initialVariantId); - }, [initialSeed, initialVariantId]); - - return ( - setTab(v as TabName)} - sx={{ - backgroundColor: "initial", - - [`& .${tabClasses.root}`]: { - backgroundColor: "transparent", - flex: "initial", - height: (t) => t.spacing(5), - border: "none", - fontWeight: 500, - - "&:hover": { - backgroundColor: "transparent", - }, - - [`&.${tabClasses.selected}`]: { - color: "primary.plainColor", - backgroundColor: "initial", - "&::after": { - height: 2, - borderTopLeftRadius: 3, - borderTopRightRadius: 3, - bgcolor: "primary.500", - }, - }, - }, - - [`& .${tabListClasses.root}`]: { - justifyContent: "center", - width: "100%", - maxWidth: dividerWidth, - margin: "auto", - }, - - [`& .${tabPanelClasses.root}`]: { - backgroundColor: "initial", - width: "100%", - margin: "auto", - }, - - [`& .${dividerClasses.root}`]: { - maxWidth: dividerWidth, - margin: "auto", - my: 2, - }, - - ...sx, - }} - > - - - Question - - - Explanation - - {showMeta && Meta} - - Variants - - - Edit - - - - ({ - optionId: option.id, - text: option.text, - }))} - onOptionClicked={(optionId) => { - setSelectedOption(optionId); - setSelectedStatus("show-result"); - }} - annexHrefs={question.annexes.map( - (a) => questionOverview.annexes[a].href, - )} - onAnnexClicked={(annex) => setCurrentAnnex(annex)} - /> - setCurrentAnnex(undefined)} - drawings={annexDrawings[currentAnnex ?? ""] ?? []} - onDrawingsChanged={(newDrawings) => - setAnnexDrawings((oldDrawings) => ({ - ...oldDrawings, - [currentAnnex ?? ""]: newDrawings, - })) - } - onUndo={() => - setAnnexDrawings((old) => ({ - ...old, - [currentAnnex ?? ""]: (old[currentAnnex ?? ""] ?? []).slice( - 0, - -1, - ), - })) - } - onReset={() => - setAnnexDrawings((old) => ({ - ...old, - [currentAnnex ?? ""]: [], - })) - } - imgSrc={currentAnnex ?? ""} - /> -