--
This commit is contained in:
parent
cceafeb615
commit
cc20575a78
93
package-lock.json
generated
93
package-lock.json
generated
@ -40,6 +40,7 @@
|
||||
"react": "^18.2.0",
|
||||
"react-beautiful-dnd": "^13.1.1",
|
||||
"react-cytoscapejs": "^2.0.0",
|
||||
"react-datepicker": "^4.24.0",
|
||||
"react-dnd": "^16.0.1",
|
||||
"react-dnd-html5-backend": "^16.0.1",
|
||||
"react-dom": "^18.2.0",
|
||||
@ -61,7 +62,8 @@
|
||||
"@emoji-mart/react": "^1.1.1",
|
||||
"@types/cytoscape-popper": "^2.0.4",
|
||||
"@types/react-beautiful-dnd": "^13.1.4",
|
||||
"@types/react-cytoscapejs": "^1.2.5",
|
||||
"@types/react-cytoscapejs": "^1.2.4",
|
||||
"@types/react-datepicker": "^4.19.3",
|
||||
"craco-alias": "^3.0.1",
|
||||
"cypress": "^13.4.0"
|
||||
}
|
||||
@ -4524,6 +4526,18 @@
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-datepicker": {
|
||||
"version": "4.19.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-datepicker/-/react-datepicker-4.19.3.tgz",
|
||||
"integrity": "sha512-85F9eKWu9fGiD9r4KVVMPYAdkJJswR3Wci9PvqplmB6T+D+VbUqPeKtifg96NZ4nEhufjehW+SX4JLrEWVplWw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.9.2",
|
||||
"@types/react": "*",
|
||||
"date-fns": "^2.0.1",
|
||||
"react-popper": "^2.2.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-dnd": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dnd/-/react-dnd-3.0.2.tgz",
|
||||
@ -6374,6 +6388,11 @@
|
||||
"integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/classnames": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
|
||||
"integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
|
||||
},
|
||||
"node_modules/clean-css": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz",
|
||||
@ -7438,6 +7457,21 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/date-fns": {
|
||||
"version": "2.30.0",
|
||||
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
|
||||
"integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.11"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/date-fns"
|
||||
}
|
||||
},
|
||||
"node_modules/dayjs": {
|
||||
"version": "1.11.10",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz",
|
||||
@ -15126,6 +15160,23 @@
|
||||
"react": ">=15.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-datepicker": {
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-4.24.0.tgz",
|
||||
"integrity": "sha512-2QUC2pP+x4v3Jp06gnFllxKsJR0yoT/K6y86ItxEsveTXUpsx+NBkChWXjU0JsGx/PL8EQnsxN0wHl4zdA1m/g==",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"classnames": "^2.2.6",
|
||||
"date-fns": "^2.30.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"react-onclickoutside": "^6.13.0",
|
||||
"react-popper": "^2.3.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.9.0 || ^17 || ^18",
|
||||
"react-dom": "^16.9.0 || ^17 || ^18"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dev-utils": {
|
||||
"version": "12.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz",
|
||||
@ -15308,6 +15359,38 @@
|
||||
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-onclickoutside": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.13.0.tgz",
|
||||
"integrity": "sha512-ty8So6tcUpIb+ZE+1HAhbLROvAIJYyJe/1vRrrcmW+jLsaM+/powDRqxzo6hSh9CuRZGSL1Q8mvcF5WRD93a0A==",
|
||||
"funding": {
|
||||
"type": "individual",
|
||||
"url": "https://github.com/Pomax/react-onclickoutside/blob/master/FUNDING.md"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^15.5.x || ^16.x || ^17.x || ^18.x",
|
||||
"react-dom": "^15.5.x || ^16.x || ^17.x || ^18.x"
|
||||
}
|
||||
},
|
||||
"node_modules/react-popper": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
|
||||
"integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==",
|
||||
"dependencies": {
|
||||
"react-fast-compare": "^3.0.1",
|
||||
"warning": "^4.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@popperjs/core": "^2.0.0",
|
||||
"react": "^16.8.0 || ^17 || ^18",
|
||||
"react-dom": "^16.8.0 || ^17 || ^18"
|
||||
}
|
||||
},
|
||||
"node_modules/react-popper/node_modules/react-fast-compare": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
|
||||
"integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
|
||||
},
|
||||
"node_modules/react-redux": {
|
||||
"version": "7.2.9",
|
||||
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz",
|
||||
@ -18037,6 +18120,14 @@
|
||||
"makeerror": "1.0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/warning": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/watchpack": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { MessageIcon } from "@icons/messagIcon";
|
||||
import { PointsIcon } from "@icons/questionsPage/PointsIcon";
|
||||
import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
|
||||
import TextareaAutosize from "@mui/base/TextareaAutosize";
|
||||
import {TextareaAutosize} from "@mui/base/TextareaAutosize";
|
||||
import {
|
||||
Box,
|
||||
FormControl,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useEffect, useLayoutEffect, useRef, useState } from "react";
|
||||
import Cytoscape from "cytoscape";
|
||||
import CytoscapeComponent from "react-cytoscapejs";
|
||||
import popper from "cytoscape-popper";
|
||||
@ -122,6 +122,9 @@ export const CsComponent = ({
|
||||
const crossesContainer = useRef<HTMLDivElement | null>(null);
|
||||
const gearsContainer = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
// useLayoutEffect(() => {
|
||||
// updateOpenedModalSettingsId()
|
||||
// }, [])
|
||||
useEffect(() => {
|
||||
if (modalQuestionTargetContentId.length !== 0 && modalQuestionParentContentId.length !== 0) {
|
||||
addNode({ parentNodeContentId: modalQuestionParentContentId, targetNodeContentId: modalQuestionTargetContentId })
|
||||
@ -166,8 +169,8 @@ export const CsComponent = ({
|
||||
})
|
||||
|
||||
//Если детей больше 1 - предупреждаем стор вопросов об открытии модалки ветвления
|
||||
if (parentNodeChildren > 1) {
|
||||
updateOpenedModalSettingsId(parentNodeContentId)
|
||||
if (parentNodeChildren >= 1) {
|
||||
updateOpenedModalSettingsId(targetQuestion.content.id)
|
||||
} else {
|
||||
//Если ребёнок первый - добавляем его родителю как дефолтный
|
||||
updateQuestion(parentNodeContentId, question => question.content.rule.default = targetQuestion.content.id)
|
||||
@ -200,12 +203,15 @@ export const CsComponent = ({
|
||||
const targetQuestion = getQuestionByContentId(targetNodeContentId)
|
||||
|
||||
if (targetQuestion.content.rule.parentId === "root" && quiz) {
|
||||
console.log("ROOT")
|
||||
console.log(quiz)
|
||||
updateRootContentId(quiz?.id, "")
|
||||
updateQuestion(targetNodeContentId, question => {
|
||||
question.content.rule.parentId = ""
|
||||
question.content.rule.main = []
|
||||
question.content.rule.default = ""
|
||||
})
|
||||
console.log(quiz, getQuestionByContentId(targetNodeContentId))
|
||||
} else {
|
||||
const parentQuestionContentId = cy?.$('edge[target = "' + targetNodeContentId + '"]')?.toArray()?.[0]?.data()?.source
|
||||
if (targetNodeContentId && parentQuestionContentId) {
|
||||
@ -242,7 +248,9 @@ export const CsComponent = ({
|
||||
question.content.rule.main = []
|
||||
question.content.rule.default = ""
|
||||
})
|
||||
|
||||
updateQuestion(parentQuestionContentId, question => {
|
||||
//Заменяем id удаляемого вопроса либо на id одного из оставшихся, либо на пустую строку
|
||||
if (question.content.rule.default === targetQuestionContentId) question.content.rule.default = ""
|
||||
})
|
||||
|
||||
|
@ -2,8 +2,8 @@ import { Box } from "@mui/material"
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { updateDragQuestionContentId, updateQuestion } from "@root/questions/actions"
|
||||
import { updateRootContentId } from "@root/quizes/actions"
|
||||
import { useCurrentQuiz } from "@root/quizes/hooks"
|
||||
import { useQuestionsStore } from "@root/questions/store"
|
||||
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
|
||||
interface Props {
|
||||
@ -11,9 +11,10 @@ interface Props {
|
||||
modalQuestionTargetContentId: string;
|
||||
}
|
||||
export const FirstNodeField = ({ setOpenedModalQuestions, modalQuestionTargetContentId }: Props) => {
|
||||
const { dragQuestionContentId } = useQuestionsStore()
|
||||
const Container = useRef<HTMLDivElement | null>(null);
|
||||
const quiz = useCurrentQuiz();
|
||||
const { dragQuestionContentId, questions } = useQuestionsStore()
|
||||
console.log(questions)
|
||||
const Container = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const modalOpen = () => setOpenedModalQuestions(true)
|
||||
|
||||
@ -26,6 +27,7 @@ export const FirstNodeField = ({ setOpenedModalQuestions, modalQuestionTargetCon
|
||||
} else {
|
||||
enqueueSnackbar("Нет информации о взятом опроснике")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
@ -50,6 +52,7 @@ export const FirstNodeField = ({ setOpenedModalQuestions, modalQuestionTargetCon
|
||||
|
||||
}, [modalQuestionTargetContentId])
|
||||
|
||||
|
||||
return (
|
||||
<Box
|
||||
ref={Container}
|
||||
|
@ -14,6 +14,8 @@ export const BranchingMap = () => {
|
||||
const [modalQuestionTargetContentId, setModalQuestionTargetContentId] = useState<string>("")
|
||||
const [openedModalQuestions, setOpenedModalQuestions] = useState<boolean>(false)
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<Box
|
||||
id="cytoscape-container"
|
||||
|
@ -33,6 +33,9 @@ export default function BranchingQuestions() {
|
||||
const { openedModalSettingsId } = useQuestionsStore();
|
||||
const [targetQuestion, setTargetQuestion] = useState<AnyQuizQuestion | null>(getQuestionById(openedModalSettingsId) || getQuestionByContentId(openedModalSettingsId))
|
||||
const [parentQuestion, setParentQuestion] = useState<AnyQuizQuestion | null>(getQuestionByContentId(targetQuestion?.content.rule.parentId))
|
||||
console.log(parentQuestion.content.rule.default)
|
||||
console.log(targetQuestion.content.id)
|
||||
console.log(parentQuestion.content.rule.default === targetQuestion.content.id)
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (parentQuestion === null) return
|
||||
@ -51,6 +54,7 @@ export default function BranchingQuestions() {
|
||||
})
|
||||
|
||||
|
||||
console.log({targetQuestion, parentQuestion})
|
||||
|
||||
if (targetQuestion === null || parentQuestion === null) {
|
||||
enqueueSnackbar("Невозможно найти данные ветвления для этого вопроса")
|
||||
@ -163,7 +167,7 @@ export default function BranchingQuestions() {
|
||||
sx={{
|
||||
margin: 0
|
||||
}}
|
||||
checked={parentQuestion.content.rule.default === targetQuestion.id}
|
||||
checked={parentQuestion.content.rule.default === targetQuestion.content.id}
|
||||
|
||||
onClick={() => {
|
||||
let mutate = JSON.parse(JSON.stringify(parentQuestion))
|
||||
|
@ -10,6 +10,8 @@ import { nanoid } from "nanoid";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { isAxiosCanceledError } from "../../utils/isAxiosCanceledError";
|
||||
import { RequestQueue } from "../../utils/requestQueue";
|
||||
import { updateRootContentId } from "@root/quizes/actions"
|
||||
import { useCurrentQuiz } from "@root/quizes/hooks"
|
||||
import { QuestionsStore, useQuestionsStore } from "./store";
|
||||
|
||||
|
||||
@ -136,22 +138,20 @@ export const updateQuestion = (
|
||||
|
||||
// clearTimeout(requestTimeoutId);
|
||||
// requestTimeoutId = setTimeout(() => {
|
||||
requestQueue.enqueue(async () => {
|
||||
const q = useQuestionsStore.getState().questions.find(q => q.id === questionId) || useQuestionsStore.getState().questions.find(q => q.content.id === questionId);
|
||||
console.log("мы пытаемся найти вопрос ")
|
||||
if (!q) return;
|
||||
if (q.type === null) throw new Error("Cannot send update request for untyped question");
|
||||
console.log(q.title)
|
||||
requestQueue.enqueue(async () => {
|
||||
const q = useQuestionsStore.getState().questions.find(q => q.id === questionId) || useQuestionsStore.getState().questions.find(q => q.content.id === questionId);
|
||||
if (!q) return;
|
||||
if (q.type === null) throw new Error("Cannot send update request for untyped question");
|
||||
|
||||
const response = await questionApi.edit(questionToEditQuestionRequest(q));
|
||||
const response = await questionApi.edit(questionToEditQuestionRequest(q));
|
||||
|
||||
setQuestionBackendId(questionId, response.updated);
|
||||
}).catch(error => {
|
||||
if (isAxiosCanceledError(error)) return;
|
||||
setQuestionBackendId(questionId, response.updated);
|
||||
}).catch(error => {
|
||||
if (isAxiosCanceledError(error)) return;
|
||||
|
||||
devlog("Error editing question", { error, questionId });
|
||||
enqueueSnackbar("Не удалось сохранить вопрос");
|
||||
});
|
||||
devlog("Error editing question", { error, questionId });
|
||||
enqueueSnackbar("Не удалось сохранить вопрос");
|
||||
});
|
||||
// }, REQUEST_DEBOUNCE);
|
||||
};
|
||||
|
||||
@ -261,8 +261,10 @@ export const changeQuestionType = (
|
||||
type: QuestionType,
|
||||
) => {
|
||||
updateQuestion(questionId, question => {
|
||||
const oldId = question.content.id
|
||||
question.type = type;
|
||||
question.content = defaultQuestionByType[type].content;
|
||||
question.content.id = oldId
|
||||
});
|
||||
};
|
||||
|
||||
@ -273,7 +275,7 @@ export const createTypedQuestion = async (
|
||||
const question = useQuestionsStore.getState().questions.find(q => q.id === questionId);
|
||||
if (!question) return;
|
||||
if (question.type !== null) throw new Error("Cannot upgrade already typed question");
|
||||
|
||||
|
||||
try {
|
||||
const createdQuestion = await questionApi.create({
|
||||
quiz_id: question.quizId,
|
||||
@ -303,11 +305,16 @@ export const createTypedQuestion = async (
|
||||
});
|
||||
|
||||
export const deleteQuestion = async (questionId: string) => requestQueue.enqueue(async () => {
|
||||
|
||||
const question = useQuestionsStore.getState().questions.find(q => q.id === questionId);
|
||||
if (!question) return;
|
||||
|
||||
if (question.type === null) {
|
||||
removeQuestion(questionId);
|
||||
if (question.content.rule.parentId === "root") { //удалить из стора root и очистить rule всем вопросам
|
||||
clearRoleForAll()
|
||||
updateRootContentId(quiz.id, "")
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -325,9 +332,11 @@ export const copyQuestion = async (questionId: string, quizId: number) => reques
|
||||
const question = useQuestionsStore.getState().questions.find(q => q.id === questionId);
|
||||
if (!question) return;
|
||||
|
||||
const frontId = nanoid();
|
||||
if (question.type === null) {
|
||||
const copiedQuestion = structuredClone(question);
|
||||
copiedQuestion.id = nanoid();
|
||||
copiedQuestion.id = frontId
|
||||
copiedQuestion.content.id = frontId
|
||||
|
||||
setProducedState(state => {
|
||||
state.questions.push(copiedQuestion);
|
||||
@ -369,7 +378,7 @@ function setProducedState<A extends string | { type: unknown; }>(
|
||||
|
||||
|
||||
export const cleardragQuestionContentId = () => {
|
||||
useQuestionsStore.setState({dragQuestionContentId: null});
|
||||
useQuestionsStore.setState({ dragQuestionContentId: null });
|
||||
};
|
||||
|
||||
export const getQuestionById = (questionId: string | null) => {
|
||||
@ -377,16 +386,26 @@ export const getQuestionById = (questionId: string | null) => {
|
||||
return useQuestionsStore.getState().questions.find(q => q.id === questionId) || null;
|
||||
};
|
||||
export const getQuestionByContentId = (questionContentId: string | null) => {
|
||||
console.log("questionContentId " + questionContentId)
|
||||
if (questionContentId === null) return null;
|
||||
return useQuestionsStore.getState().questions.find(q => {
|
||||
console.log(q.content.id)
|
||||
console.log(q.content.id === questionContentId)
|
||||
return ( q.content.id === questionContentId)}) || null;
|
||||
return (q.content.id === questionContentId)
|
||||
}) || null;
|
||||
};
|
||||
|
||||
export const updateOpenedModalSettingsId = (id?: string) => useQuestionsStore.setState({openedModalSettingsId: id ? id : null});
|
||||
export const updateOpenedModalSettingsId = (id?: string) => useQuestionsStore.setState({ openedModalSettingsId: id ? id : null });
|
||||
export const updateDragQuestionContentId = (contentId?: string) => {
|
||||
console.log("contentId " + contentId)
|
||||
useQuestionsStore.setState({dragQuestionContentId: contentId ? contentId : null});
|
||||
useQuestionsStore.setState({ dragQuestionContentId: contentId ? contentId : null });
|
||||
}
|
||||
|
||||
export const clearRoleForAll = () => {
|
||||
const { questions } = useQuestionsStore.getState()
|
||||
questions.forEach(question => {
|
||||
if (question.type !== null && (question.content.rule.main.length > 0 || question.content.rule.default.length > 0 || question.content.rule.parentId.length > 0)) {
|
||||
updateQuestion(question.content.id, question => {
|
||||
question.content.rule.parentId = ""
|
||||
question.content.rule.main = []
|
||||
question.content.rule.default = ""
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
@ -4,7 +4,7 @@ import { devtools } from "zustand/middleware";
|
||||
|
||||
|
||||
export type QuestionsStore = {
|
||||
questions: (AnyTypedQuizQuestion | UntypedQuizQuestion);
|
||||
questions: (AnyTypedQuizQuestion | UntypedQuizQuestion)[];
|
||||
openedModalSettingsId: string | null;
|
||||
dragQuestionContentId: string | null;
|
||||
};
|
||||
|
@ -10,6 +10,7 @@ import { isAxiosCanceledError } from "../../utils/isAxiosCanceledError";
|
||||
import { RequestQueue } from "../../utils/requestQueue";
|
||||
import { QuizStore, useQuizStore } from "./store";
|
||||
import { createUntypedQuestion } from "@root/questions/actions";
|
||||
import { useCurrentQuiz } from "./hooks"
|
||||
|
||||
|
||||
export const setEditQuizId = (quizId: number | null) => setProducedState(state => {
|
||||
@ -127,6 +128,7 @@ export const updateQuiz = async (
|
||||
requestTimeoutId = setTimeout(async () => {
|
||||
requestQueue.enqueue(async () => {
|
||||
const quiz = useQuizStore.getState().quizes.find(q => q.id === quizId);
|
||||
console.log("измененный квиз", quiz)
|
||||
if (!quiz) return;
|
||||
|
||||
const response = await quizApi.edit(quizToEditQuizRequest(quiz));
|
||||
@ -178,10 +180,11 @@ export const deleteQuiz = async (quizId: string) => requestQueue.enqueue(async (
|
||||
export const updateRootContentId = (quizId: string, id:string) => updateQuiz(
|
||||
quizId,
|
||||
quiz => {
|
||||
quiz.config.haveRoot = id;
|
||||
quiz.config.haveRoot = id
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
// TODO copy quiz
|
||||
|
||||
export const uploadQuizImage = async (
|
||||
|
Loading…
Reference in New Issue
Block a user