Merge branch 'some-fix' into view-answers-fixes

This commit is contained in:
Nastya 2023-12-14 20:10:10 +03:00
commit a5897a38b7
21 changed files with 72 additions and 53 deletions

@ -19,6 +19,7 @@ import EditPage from "./pages/startPage/EditPage";
import { clearAuthToken, getMessageFromFetchError, useUserFetcher } from "@frontend/kitui"; import { clearAuthToken, getMessageFromFetchError, useUserFetcher } from "@frontend/kitui";
import { clearUserData, setUser, useUserStore } from "@root/user"; import { clearUserData, setUser, useUserStore } from "@root/user";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
import PrivateRoute from "@ui_kit/PrivateRoute";
dayjs.locale("ru"); dayjs.locale("ru");
@ -34,8 +35,8 @@ const routeslink = [
export default function App() { export default function App() {
const userId = useUserStore((state) => state.userId); const userId = useUserStore((state) => state.userId);
const location = useLocation() const location = useLocation();
const navigate = useNavigate() const navigate = useNavigate();
useUserFetcher({ useUserFetcher({
url: `https://hub.pena.digital/user/${userId}`, url: `https://hub.pena.digital/user/${userId}`,
@ -51,7 +52,7 @@ export default function App() {
}, },
}); });
if (location.state?.redirectTo) if (location.state?.redirectTo)
return <Navigate to={location.state.redirectTo} replace state={{ backgroundLocation: location }} /> return <Navigate to={location.state.redirectTo} replace state={{ backgroundLocation: location }} />;
return ( return (
<> <>
@ -62,18 +63,18 @@ export default function App() {
<Route path="/signup" element={<SignupDialog />} /> <Route path="/signup" element={<SignupDialog />} />
</Routes> </Routes>
)} )}
<Routes location={location.state?.backgroundLocation || location}> <Routes location={location.state?.backgroundLocation || location}>
<Route path="/" element={<Landing />} />
<Route path="/signin" element={<Navigate to="/" replace state={{ redirectTo: "/signin" }} />} />
<Route path="/signup" element={<Navigate to="/" replace state={{ redirectTo: "/signup" }} />} />
<Route element={<PrivateRoute />}>
{routeslink.map((e, i) => ( {routeslink.map((e, i) => (
<Route key={i} path={e.path} element={<Main page={e.page} header={e.header} sidebar={e.sidebar} />} /> <Route key={i} path={e.path} element={<Main page={e.page} header={e.header} sidebar={e.sidebar} />} />
))} ))}
<Route path="edit" element={<EditPage />} /> <Route path="edit" element={<EditPage />} />
<Route path="crop" element={<ImageCrop />} /> <Route path="crop" element={<ImageCrop />} />
<Route path="/" element={<Landing />} />
<Route path="/signin" element={<Navigate to="/" replace state={{ redirectTo: "/signin" }} />} />
<Route path="/signup" element={<Navigate to="/" replace state={{ redirectTo: "/signup" }} />} />/>
<Route path="/view" element={<ViewPage />} /> <Route path="/view" element={<ViewPage />} />
</Route>
</Routes> </Routes>
</> </>
); );

@ -77,7 +77,7 @@ export const AnswerItem = ({
placeholder={"Добавьте ответ"} placeholder={"Добавьте ответ"}
multiline={largeCheck} multiline={largeCheck}
onChange={({ target }) => { onChange={({ target }) => {
setQuestionVariantAnswer(target.value); setQuestionVariantAnswer(target.value || " ");
}} }}
onKeyDown={(event: KeyboardEvent<HTMLInputElement>) => { onKeyDown={(event: KeyboardEvent<HTMLInputElement>) => {
if (event.code === "Enter" && !largeCheck) { if (event.code === "Enter" && !largeCheck) {
@ -124,7 +124,7 @@ export const AnswerItem = ({
style={{ margin: "10px" }} style={{ margin: "10px" }}
placeholder="Подсказка для этого ответа" placeholder="Подсказка для этого ответа"
value={variant.hints} value={variant.hints}
onChange={e => setQuestionVariantAnswer(e.target.value)} onChange={e => setQuestionVariantAnswer(e.target.value || " ")}
onKeyDown={( onKeyDown={(
event: KeyboardEvent<HTMLTextAreaElement> event: KeyboardEvent<HTMLTextAreaElement>
) => event.stopPropagation()} ) => event.stopPropagation()}

@ -7,7 +7,8 @@ import { useCurrentQuiz } from "@root/quizes/hooks";
import { updateRootContentId } from "@root/quizes/actions" import { updateRootContentId } from "@root/quizes/actions"
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared" import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"
import { useQuestionsStore } from "@root/questions/store"; import { useQuestionsStore } from "@root/questions/store";
import { deleteQuestion, updateQuestion, updateOpenedModalSettingsId, getQuestionByContentId, clearRuleForAll } from "@root/questions/actions"; import { deleteQuestion, updateQuestion, getQuestionByContentId, clearRuleForAll } from "@root/questions/actions";
import { updateOpenedModalSettingsId, } from "@root/uiTools/actions";
import { cleardragQuestionContentId } from "@root/uiTools/actions"; import { cleardragQuestionContentId } from "@root/uiTools/actions";
import { withErrorBoundary } from "react-error-boundary"; import { withErrorBoundary } from "react-error-boundary";
@ -660,6 +661,7 @@ let gearsPopper = null
gearElement.style.zIndex = "1" gearElement.style.zIndex = "1"
gearsContainer.current?.appendChild(gearElement); gearsContainer.current?.appendChild(gearElement);
gearElement.addEventListener("mouseup", (e) => { gearElement.addEventListener("mouseup", (e) => {
console.log("up")
updateOpenedModalSettingsId(item.id()) updateOpenedModalSettingsId(item.id())
}); });
@ -811,7 +813,7 @@ let gearsPopper = null
}} }}
autoungrabify={true} autoungrabify={true}
/> />
<button onClick={() => { {/* <button onClick={() => {
console.log("NODES____________________________") console.log("NODES____________________________")
cyRef.current?.elements().forEach((ele: any) => { cyRef.current?.elements().forEach((ele: any) => {
console.log(ele.data()) console.log(ele.data())
@ -820,7 +822,7 @@ let gearsPopper = null
<button onClick={() => { <button onClick={() => {
console.log("ELEMENTS____________________________") console.log("ELEMENTS____________________________")
console.log(questions) console.log(questions)
}}>elements</button> }}>elements</button> */}
</> </>
); );
}; };

@ -1,6 +1,7 @@
import { Box } from "@mui/material" import { Box } from "@mui/material"
import { useEffect, useRef, useLayoutEffect } from "react"; import { useEffect, useRef, useLayoutEffect } from "react";
import { deleteQuestion, clearRuleForAll, updateQuestion, updateOpenedModalSettingsId } from "@root/questions/actions" import { deleteQuestion, clearRuleForAll, updateQuestion } from "@root/questions/actions"
import { updateOpenedModalSettingsId } from "@root/uiTools/actions"
import { updateRootContentId } from "@root/quizes/actions" import { updateRootContentId } from "@root/quizes/actions"
import { useCurrentQuiz } from "@root/quizes/hooks" import { useCurrentQuiz } from "@root/quizes/hooks"
import { useQuestionsStore } from "@root/questions/store" import { useQuestionsStore } from "@root/questions/store"

@ -22,8 +22,8 @@ import InfoIcon from "@icons/Info";
import { DeleteIcon } from "@icons/questionsPage/deleteIcon"; import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
import { TypeSwitch, BlockRule } from "./Settings"; import { TypeSwitch, BlockRule } from "./Settings";
import { getQuestionById, getQuestionByContentId, updateOpenedModalSettingsId, updateQuestion } from "@root/questions/actions"; import { getQuestionById, getQuestionByContentId, updateQuestion } from "@root/questions/actions";
import { useQuestionsStore } from "@root/questions/store"; import { updateOpenedModalSettingsId } from "@root/uiTools/actions";
import { useUiTools } from "@root/uiTools/store"; import { useUiTools } from "@root/uiTools/store";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
@ -166,7 +166,7 @@ export default function BranchingQuestions() {
onClick={() => { onClick={() => {
let mutate = JSON.parse(JSON.stringify(parentQuestion)) let mutate = JSON.parse(JSON.stringify(parentQuestion))
mutate.content.rule.default = targetQuestion.id mutate.content.rule.default = parentQuestion.content.rule.default === targetQuestion.content.id ? "" : targetQuestion.content.id
setParentQuestion(mutate) setParentQuestion(mutate)
}} }}
/>} label="Следующий вопрос по-умолчанию" /> />} label="Следующий вопрос по-умолчанию" />

@ -25,9 +25,10 @@ export const BranchingQuestionsModal = ({
}; };
const typedQuestions: AnyTypedQuizQuestion[] = questions.filter( const typedQuestions: AnyTypedQuizQuestion[] = questions.filter(
(question) => question.type && !question.content.rule.parentId (question) => question.type && !question.content.rule.parentId && question.type !== "result"
) as AnyTypedQuizQuestion[]; ) as AnyTypedQuizQuestion[];
if (typedQuestions.length === 0) return <></>
return ( return (
<Modal open={openedModalQuestions} onClose={handleClose}> <Modal open={openedModalQuestions} onClose={handleClose}>
<Box <Box

@ -23,7 +23,7 @@ import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared";
import { useCurrentQuiz } from "@root/quizes/hooks"; import { useCurrentQuiz } from "@root/quizes/hooks";
import { enqueueSnackbar } from "notistack"; import { enqueueSnackbar } from "notistack";
import { useQuestionsStore } from "@root/questions/store"; import { useQuestionsStore } from "@root/questions/store";
import { updateOpenedModalSettingsId } from "@root/questions/actions"; import { updateOpenedModalSettingsId } from "@root/uiTools/actions";
import { updateRootContentId } from "@root/quizes/actions"; import { updateRootContentId } from "@root/quizes/actions";
import { useUiTools } from "@root/uiTools/store"; import { useUiTools } from "@root/uiTools/store";
@ -88,7 +88,7 @@ export default function ButtonsOptions({
title: "Ветвление", title: "Ветвление",
value: "branching", value: "branching",
myFunc: (question) => { myFunc: (question) => {
updateOpenBranchingPanel(true); // updateOpenBranchingPanel(true);
updateDesireToOpenABranchingModal(question.content.id); updateDesireToOpenABranchingModal(question.content.id);
} }
}, },

@ -191,7 +191,7 @@ export default function ButtonsOptionsAndPict({
onMouseEnter={() => setButtonHover("branching")} onMouseEnter={() => setButtonHover("branching")}
onMouseLeave={() => setButtonHover("")} onMouseLeave={() => setButtonHover("")}
onClick={() => { onClick={() => {
updateOpenBranchingPanel(true); // updateOpenBranchingPanel(true);
updateDesireToOpenABranchingModal(question.content.id); updateDesireToOpenABranchingModal(question.content.id);
}} }}
sx={{ sx={{

@ -125,7 +125,7 @@ export default function SettingsData({ question }: SettingsDataProps) {
<CustomTextField <CustomTextField
placeholder={"Развёрнутое описание вопроса"} placeholder={"Развёрнутое описание вопроса"}
text={question.content.innerName} text={question.content.innerName}
onChange={({ target }) => setInnerName(target.value)} onChange={({ target }) => setInnerName(target.value || " ")}
/> />
)} )}
</Box> </Box>

@ -102,7 +102,7 @@ export default function QuestionsPageCard({ question, draggableProps, isDragging
<TextField <TextField
defaultValue={question.title} defaultValue={question.title}
placeholder={"Заголовок вопроса"} placeholder={"Заголовок вопроса"}
onChange={({ target }: { target: HTMLInputElement; }) => setTitle(target.value)} onChange={({ target }: { target: HTMLInputElement; }) => setTitle(target.value || " ")}
InputProps={{ InputProps={{
startAdornment: ( startAdornment: (
<Box> <Box>

@ -184,7 +184,7 @@ export default function SettingDropDown({ question }: SettingDropDownProps) {
<CustomTextField <CustomTextField
placeholder={"Развёрнутое описание вопроса"} placeholder={"Развёрнутое описание вопроса"}
text={question.content.innerName} text={question.content.innerName}
onChange={({ target }) => debounced(target.value)} onChange={({ target }) => debounced(target.value || " ")}
/> />
)} )}
</Box> </Box>

@ -3,10 +3,13 @@ import { reorderQuestions } from "@root/questions/actions";
import type { DropResult } from "react-beautiful-dnd"; import type { DropResult } from "react-beautiful-dnd";
import { DragDropContext, Droppable } from "react-beautiful-dnd"; import { DragDropContext, Droppable } from "react-beautiful-dnd";
import FormDraggableListItem from "./FormDraggableListItem"; import FormDraggableListItem from "./FormDraggableListItem";
import { useQuestions } from "@root/questions/hooks";
export const FormDraggableList = () => { export const FormDraggableList = () => {
const { questions } = useQuestions()
const onDragEnd = ({ destination, source }: DropResult) => { const onDragEnd = ({ destination, source }: DropResult) => {
if (destination) reorderQuestions(source.index, destination.index); if (destination) reorderQuestions(source.index, destination.index);
}; };
@ -16,7 +19,7 @@ export const FormDraggableList = () => {
<Droppable droppableId="droppable-list"> <Droppable droppableId="droppable-list">
{(provided) => ( {(provided) => (
<Box ref={provided.innerRef} {...provided.droppableProps}> <Box ref={provided.innerRef} {...provided.droppableProps}>
{questions.map((question, index) => ( {questions?.map((question, index) => (
<FormDraggableListItem <FormDraggableListItem
key={question.id} key={question.id}
question={question} question={question}

@ -99,7 +99,7 @@ export const UploadVideoModal = ({
<CustomTextField <CustomTextField
placeholder={"http://example.com"} placeholder={"http://example.com"}
text={video} text={video}
onChange={({ target }) => onUpload(target.value)} onChange={({ target }) => onUpload(target.value || " ")}
/> />
</Box> </Box>
) : ( ) : (
@ -114,7 +114,7 @@ export const UploadVideoModal = ({
<input <input
onChange={({ target }) => { onChange={({ target }) => {
if (target.files?.length) { if (target.files?.length) {
onUpload(URL.createObjectURL(target.files[0])); onUpload(URL.createObjectURL(target.files[0] || " "));
} }
}} }}
hidden hidden

@ -82,7 +82,7 @@ export default function ResponseSettings({ question }: Props) {
}); });
}} }}
/> />
<CustomCheckbox {/* <CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }} sx={{ mr: isMobile ? "0px" : "16px" }}
label={'Вариант "свой ответ"'} label={'Вариант "свой ответ"'}
checked={question.content.own} checked={question.content.own}
@ -93,7 +93,7 @@ export default function ResponseSettings({ question }: Props) {
question.content.own = target.checked; question.content.own = target.checked;
}); });
}} }}
/> /> */}
</Box> </Box>
<Box <Box
sx={{ sx={{
@ -168,7 +168,7 @@ export default function ResponseSettings({ question }: Props) {
sx={{ mr: isMobile ? "0px" : "16px" }} sx={{ mr: isMobile ? "0px" : "16px" }}
placeholder={"Развёрнутое описание вопроса"} placeholder={"Развёрнутое описание вопроса"}
text={question.content.innerName} text={question.content.innerName}
onChange={({ target }) => updateQuestionInnerName(target.value)} onChange={({ target }) => updateQuestionInnerName(target.value || " ")}
/> />
)} )}
</Box> </Box>

@ -62,7 +62,7 @@ export default function HelpQuestions({ question }: HelpQuestionsProps) {
<CustomTextField <CustomTextField
placeholder={"Текст консультанта"} placeholder={"Текст консультанта"}
text={question.content.hint.text} text={question.content.hint.text}
onChange={({ target }) => updateQuestionHint(target.value)} onChange={({ target }) => updateQuestionHint(target.value || " ")}
/> />
</> </>
) : ( ) : (

@ -144,7 +144,7 @@ export const StartPageViewPublication = ({setVisualStartPage}:Props) => {
padding: "10px 15px", padding: "10px 15px",
width: quiz.config.startpageType === "standard" ? "100%" : "auto" width: quiz.config.startpageType === "standard" ? "100%" : "auto"
}} }}
onClick={() => setVisualStartPage(false)} onClick={() => setVisualStartPage(true)}
> >
{quiz.config.startpage.button.trim() ? quiz.config.startpage.button : "Пройти тест"} {quiz.config.startpage.button.trim() ? quiz.config.startpage.button : "Пройти тест"}
</Button> </Button>

@ -32,10 +32,10 @@ export const ViewPage = () => {
setQuestions(questions) setQuestions(questions)
} }
getData() getData()
}, []) }, [])
useEffect(() => { useEffect(() => {
setVisualStartPage(quiz?.config.noStartPage) setVisualStartPage(quiz?.config.noStartPage)
}, [questions]) }, [questions])
const [visualStartPage, setVisualStartPage] = useState<boolean>(); const [visualStartPage, setVisualStartPage] = useState<boolean>();
@ -56,8 +56,8 @@ useEffect(() => {
if (visualStartPage === undefined) return <></> if (visualStartPage === undefined) return <></>
return ( return (
<Box> <Box>
{visualStartPage ? ( {!visualStartPage ? (
<StartPageViewPublication setVisualStartPage={setVisualStartPage}/> <StartPageViewPublication setVisualStartPage={setVisualStartPage} />
) : ( ) : (
<Question questions={filteredQuestions} /> <Question questions={filteredQuestions} />
)} )}

@ -156,7 +156,7 @@ export default function QuizCard({
anchorOrigin={{ vertical: "top", horizontal: "right" }} anchorOrigin={{ vertical: "top", horizontal: "right" }}
> >
<Box onClick={() => setSubMenuOpen(false)}> <Box onClick={() => setSubMenuOpen(false)}>
<Button {/* <Button
sx={{ sx={{
display: "block", display: "block",
width: "100%", width: "100%",
@ -165,7 +165,7 @@ export default function QuizCard({
onClick={()=>{}} onClick={()=>{}}
> >
Копировать Копировать
</Button> </Button> */}
<Button <Button
sx={{ sx={{
display: "block", display: "block",

@ -146,7 +146,7 @@ export const deleteQuestionWithTimeout = (questionId: string, deleteFn: (questio
const question = state.questions.find(q => q.id === questionId); const question = state.questions.find(q => q.id === questionId);
if (!question) return; if (!question) return;
if (question.type === null || question.type === "result") { if (question.type === null || question.type === "result") {
deleteFn(questionId); queueMicrotask(() => deleteFn(questionId));
return; return;
} }
@ -479,7 +479,6 @@ export const getQuestionByContentId = (questionContentId: string | null) => {
}) || null; }) || null;
}; };
export const updateOpenedModalSettingsId = (id?: string) => useUiTools.setState({ openedModalSettingsId: id ? id : null });
export const clearRuleForAll = () => { export const clearRuleForAll = () => {

@ -29,3 +29,6 @@ export const clearDesireToOpenABranchingModal = () => {
export const updateEditSomeQuestion = (contentId?: string) => { export const updateEditSomeQuestion = (contentId?: string) => {
useUiTools.setState({ editSomeQuestion: contentId === undefined ? null : contentId }); useUiTools.setState({ editSomeQuestion: contentId === undefined ? null : contentId });
}; };
export const updateOpenedModalSettingsId = (id?: string) => useUiTools.setState({ openedModalSettingsId: id ? id : null });

@ -0,0 +1,9 @@
import { useUserStore } from "@root/user";
import { Navigate, Outlet } from "react-router-dom"
export default function PrivateRoute() {
const user = useUserStore(state => state.user)
return user ? <Outlet /> : <Navigate to="/" replace />
}