Skip to content

Commit

Permalink
feat: before moving stuff around again
Browse files Browse the repository at this point in the history
  • Loading branch information
PupoSDC committed Feb 7, 2024
1 parent c36fbde commit 1be6979
Show file tree
Hide file tree
Showing 8 changed files with 581 additions and 324 deletions.
360 changes: 246 additions & 114 deletions libs/react/containers/src/questions/hooks/use-question-editor.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,10 @@ export const QuestionEditorAnnexes = container<Props, Params, Data>(
({ sx, component = "div", questionId, questionBank }) => {
const [search, setSearch] = useState("");

const annexes = useQuestionEditor((s) => {
return s[questionBank].afterState[questionId]?.annexes ?? [];
});

const setAnnexes = useQuestionEditor((s) => {
return s.setQuestionAnnexes;
});
const { annexes, setAnnexes } = useQuestionEditor((s) => ({
annexes: s[questionBank].afterState[questionId]?.annexes ?? [],
setAnnexes: s.setQuestionAnnexes,
}));

const serverData = QuestionEditorAnnexes.useData({
questionBank,
Expand All @@ -74,15 +71,13 @@ export const QuestionEditorAnnexes = container<Props, Params, Data>(
);

const addAnnex = (id: string) => {
setAnnexes(questionBank, questionId, [...new Set([...annexes, id])]);
const newAnnexes = [...new Set([...annexes, id])];
setAnnexes({ questionBank, questionId, annexes: newAnnexes });
};

const removeAnnex = (id: string) => {
setAnnexes(
questionBank,
questionId,
annexes.filter((lo) => lo !== id),
);
const newAnnexes = annexes.filter((a) => a !== id);
setAnnexes({ questionBank, questionId, annexes: newAnnexes });
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,20 @@ type Data =
AppRouterOutput["containers"]["questions"]["getQuestionEditorDiffTool"];

const SearchListItem = memo<{
id: QuestionId;
bank: QuestionBankName;
}>(({ id, bank }) => {
const initialState = useQuestionEditor((s) => s[bank].beforeState[id]);
const currentState = useQuestionEditor((s) => s[bank].afterState[id]);
const deleteQuestion = useQuestionEditor((s) => s.markQuestionAsDeleted);
const recoverQuestion = useQuestionEditor((s) => s.undoMarkQuestionAsDeleted);
questionId: QuestionId;
questionBank: QuestionBankName;
}>(({ questionId, questionBank }) => {
const {
initialState,
currentState,
markQuestionAsDeleted,
undoMarkQuestionAsDeleted,
} = useQuestionEditor((s) => ({
initialState: s[questionBank].beforeState[questionId],
currentState: s[questionBank].afterState[questionId],
markQuestionAsDeleted: s.markQuestionAsDeleted,
undoMarkQuestionAsDeleted: s.undoMarkQuestionAsDeleted,
}));

const initial = {
preview: getQuestionPreview(initialState.variant),
Expand Down Expand Up @@ -67,7 +74,7 @@ const SearchListItem = memo<{
<ListItemContent sx={{ display: "flex" }}>
<Stack flex={1}>
<Typography level="h5" sx={{ fontSize: "sm" }}>
{id}
{questionId}
</Typography>
<MarkdownClientCompressed sx={{ fontSize: "xs" }}>
{initial.preview}
Expand Down Expand Up @@ -98,17 +105,17 @@ const SearchListItem = memo<{
...(isDeleted && {
textDecoration: "line-through",
background: `repeating-linear-gradient(
45deg,
rgba(0, 0, 0, 0),
rgba(0, 0, 0, 0) 10px,
rgba(196, 28, 28, 0.3) 10px,
rgba(196, 28, 28, 0.3) 20px
)`,
45deg,
rgba(0, 0, 0, 0),
rgba(0, 0, 0, 0) 10px,
rgba(196, 28, 28, 0.3) 10px,
rgba(196, 28, 28, 0.3) 20px
)`,
}),
}}
>
<Typography level="h5" sx={{ fontSize: "sm" }}>
{id}
{questionId}
</Typography>
<MarkdownClientCompressed sx={{ fontSize: "xs" }}>
{current.preview}
Expand Down Expand Up @@ -168,7 +175,9 @@ const SearchListItem = memo<{
size="sm"
variant="plain"
color="success"
onClick={() => recoverQuestion(bank, id)}
onClick={() =>
undoMarkQuestionAsDeleted({ questionBank, questionId })
}
children={<UndoIcon />}
/>
</Tooltip>
Expand All @@ -179,7 +188,9 @@ const SearchListItem = memo<{
size="sm"
variant="plain"
color="danger"
onClick={() => deleteQuestion(bank, id)}
onClick={() =>
markQuestionAsDeleted({ questionBank, questionId })
}
children={<DeleteIcon />}
/>
</Tooltip>
Expand All @@ -200,7 +211,7 @@ export const QuestionEditorDiffTool = container<Props, Params, Data>(
<SearchList
forceMode="mobile"
sx={{ flex: 1, overflow: "hidden" }}
items={items.map((id) => ({ id, bank: questionBank }))}
items={items.map((id) => ({ id, questionBank, questionId: id }))}
noDataMessage={"No changes so far!"}
renderThead={() => null}
renderTableRow={() => null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,10 @@ type Data =

export const QuestionEditorExplanation = container<Props, Params, Data>(
({ questionId, questionBank, sx, component = "div" }) => {
const explanation = useQuestionEditor((s) => {
return s[questionBank].afterState[questionId]?.explanation ?? "";
});

const setQuestionExplanation = useQuestionEditor((s) => {
return s.setQuestionExplanation;
});
const { explanation, setQuestionExplanation } = useQuestionEditor((s) => ({
explanation: s[questionBank].afterState[questionId]?.explanation ?? "",
setQuestionExplanation: s.setQuestionExplanation,
}));

const [thisExplanation, setThisExplanation] = useState(explanation);
const [isPending, startTransition] = useTransition();
Expand All @@ -36,10 +33,10 @@ export const QuestionEditorExplanation = container<Props, Params, Data>(
value={thisExplanation}
sx={{ height: "100%", flex: 1 }}
onChange={(e) => {
const val = e.target.value;
setThisExplanation(val);
const explanation = e.target.value;
setThisExplanation(explanation);
startTransition(() =>
setQuestionExplanation(questionBank, questionId, val),
setQuestionExplanation({ questionBank, questionId, explanation }),
);
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,10 @@ export const QuestionEditorLearningObjectives = container<Props, Params, Data>(
({ sx, component = "div", questionId, questionBank }) => {
const [search, setSearch] = useState("");

const los = useQuestionEditor((s) => {
return s[questionBank].afterState[questionId]?.learningObjectives ?? [];
});

const setLos = useQuestionEditor((s) => {
return s.setQuestionLearningObjectives;
});
const { los, setLos } = useQuestionEditor((s) => ({
los: s[questionBank].afterState[questionId]?.learningObjectives ?? [],
setLos: s.setQuestionLearningObjectives,
}));

const serverData = QuestionEditorLearningObjectives.useData({
questionBank,
Expand All @@ -74,15 +71,13 @@ export const QuestionEditorLearningObjectives = container<Props, Params, Data>(
);

const addLo = (id: string) => {
setLos(questionBank, questionId, [...new Set([...los, id])]);
const learningObjectives = [...new Set([...los, id])];
setLos({ questionBank, questionId, learningObjectives });
};

const removeLo = (id: string) => {
setLos(
questionBank,
questionId,
los.filter((i) => i !== id),
);
const learningObjectives = los.filter((i) => i !== id);
setLos({ questionBank, questionId, learningObjectives });
};

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from "react";
import { memo, useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { default as AddIcon } from "@mui/icons-material/Add";
Expand All @@ -11,8 +11,14 @@ import {
Tooltip,
Typography,
} from "@mui/joy";
import {
getQuestionPreview,
type QuestionBankName,
type QuestionId,
} from "@chair-flight/core/question-bank";
import { questionSearchFilters } from "@chair-flight/core/search";
import {
LoadingButton,
MarkdownClientCompressed,
SearchHeader,
SearchList,
Expand All @@ -21,7 +27,6 @@ import { trpc } from "@chair-flight/trpc/client";
import { container, getRequiredParam } from "../../wraper";
import { VerticalDivider } from "../components/vertical-divider";
import { useQuestionEditor } from "../hooks/use-question-editor";
import type { QuestionBankName } from "@chair-flight/core/question-bank";
import type { AppRouterOutput } from "@chair-flight/trpc/server";

type Props = {
Expand All @@ -36,17 +41,78 @@ type Data =

const search = trpc.common.search;
const useSearchQuestions = search.searchQuestions.useInfiniteQuery;
const useRetrieveQuestions = search.retrieveQuestions.useQuery;
const filterFormDefaultValues = questionSearchFilters.parse({});
const filterFormResolver = zodResolver(questionSearchFilters);
type FilterKeys = keyof Data["filters"];

const SearchListItem = memo<{
id: QuestionId;
parentId: QuestionId;
bank: QuestionBankName;
}>(({ parentId, id, bank }) => {
const utils = trpc.useUtils();
const currentState = useQuestionEditor((s) => s[bank].afterState[id]);

const { connectTwoQuestions, deleteQuestion } = useQuestionEditor((s) => ({
connectTwoQuestions: s.connectTwoQuestions,
deleteQuestion: s.markQuestionAsDeleted,
}));

const current = currentState
? {
preview: getQuestionPreview(currentState.variant),
los: currentState.learningObjectives.join(", "),
annexes: currentState.annexes.join(", ") || "None",
relatedQs: currentState.relatedQuestions.join(", "),
}
: null;

if (!current) return null;

return (
<ListItemContent sx={{ display: "flex" }}>
<Box sx={{ flex: 1, px: 1 }}>
<Typography level="h5" sx={{ fontSize: "sm" }}>
{id}
</Typography>
<MarkdownClientCompressed sx={{ fontSize: "xs" }}>
{current.preview}
</MarkdownClientCompressed>
</Box>
<Box>
<Tooltip title="Disconnect Question">
<LoadingButton
sx={{ px: 1 }}
size="sm"
variant="plain"
children={<DeleteIcon />}
onClick={() =>
connectTwoQuestions({ trpc: utils, bank, parentId, id })
}
/>
</Tooltip>
<Tooltip title="Delete Question">
<LoadingButton
sx={{ px: 1 }}
size="sm"
variant="plain"
color="danger"
onClick={() => deleteQuestion(bank, id)}
children={<DeleteIcon />}
/>
</Tooltip>
</Box>
</ListItemContent>
);
});

export const QuestionEditorRelatedQuestions = container<Props, Params, Data>(
({ sx, component = "div", questionId, questionBank }) => {
const [search, setSearch] = useState("");
const editor = useQuestionEditor({ questionBank });
const question = editor.getQuestionState(questionId);
const questions = question?.relatedQuestions ?? [];

const relatedQs = useQuestionEditor((s) => {
return s[questionBank].afterState[questionId]?.learningObjectives ?? [];
});

const serverData = QuestionEditorRelatedQuestions.useData({
questionBank,
Expand All @@ -63,10 +129,10 @@ export const QuestionEditorRelatedQuestions = container<Props, Params, Data>(
{ getNextPageParam: (l) => l.nextCursor, initialCursor: 0 },
);

const retrieveQuestions = useRetrieveQuestions(
{ ids: questions ?? [], questionBank },
{ keepPreviousData: true },
);
const { connectTwoQuestions, deleteQuestion } = useQuestionEditor((s) => ({
connectTwoQuestions: s.connectTwoQuestions,
deleteQuestion: s.markQuestionAsDeleted,
}));

return (
<Stack direction="row" component={component} sx={sx}>
Expand Down Expand Up @@ -108,11 +174,7 @@ export const QuestionEditorRelatedQuestions = container<Props, Params, Data>(
sx={{ px: 1 }}
size="sm"
variant="plain"
disabled={questions.includes(result.id)}
children={<AddIcon />}
onClick={() =>
editor.addRelatedQuestion(questionId, result.id)
}
/>
</Tooltip>
</Box>
Expand All @@ -124,38 +186,16 @@ export const QuestionEditorRelatedQuestions = container<Props, Params, Data>(
<Stack height="100%" flex={1}>
<SearchList
forceMode={"mobile"}
noDataMessage="No Annexes selected"
loading={retrieveQuestions.isLoading}
error={retrieveQuestions.isError}
items={retrieveQuestions.data?.items ?? []}
noDataMessage="No Related Questions"
items={relatedQs.map((id) => ({
id,
parentId: questionId,
bank: questionBank,
}))}
sx={{ flex: 1, overflow: "hidden", width: "100%" }}
renderThead={() => null}
renderTableRow={() => null}
renderListItemContent={(result) => (
<ListItemContent sx={{ display: "flex" }}>
<Box sx={{ flex: 1, px: 1 }}>
<Typography level="h5" sx={{ fontSize: "sm" }}>
{result.id}
</Typography>
<MarkdownClientCompressed sx={{ fontSize: "xs" }}>
{result.text}
</MarkdownClientCompressed>
</Box>
<Box>
<Tooltip title="Remove from Question">
<Button
sx={{ px: 1 }}
size="sm"
variant="plain"
children={<DeleteIcon />}
onClick={() =>
editor.removeRelatedQuestion(questionId, result.id)
}
/>
</Tooltip>
</Box>
</ListItemContent>
)}
renderListItemContent={SearchListItem}
/>
</Stack>
</Stack>
Expand Down
Loading

0 comments on commit 1be6979

Please sign in to comment.