diff --git a/src/api/question.ts b/src/api/question.ts index 56983d76..74a46745 100644 --- a/src/api/question.ts +++ b/src/api/question.ts @@ -5,6 +5,7 @@ import { GetQuestionListRequest, GetQuestionListResponse } from "@model/question import { EditQuestionRequest, EditQuestionResponse } from "@model/question/edit"; import { DeleteQuestionRequest, DeleteQuestionResponse } from "@model/question/delete"; import { CopyQuestionRequest, CopyQuestionResponse } from "@model/question/copy"; +import { replaceSpacesToEmptyLines } from "../utils/replaceSpacesToEmptyLines"; const baseUrl = process.env.NODE_ENV === "production" ? "/squiz" : "https://squiz.pena.digital/squiz"; @@ -26,7 +27,7 @@ async function getQuestionList(body?: Partial) { method: "POST", }); - return response.items; + return replaceSpacesToEmptyLines(response.items); } function editQuestion(body: EditQuestionRequest, signal?: AbortSignal) { diff --git a/src/pages/Questions/AnswerDraggableList/AnswerItem.tsx b/src/pages/Questions/AnswerDraggableList/AnswerItem.tsx index 841728a8..da351340 100644 --- a/src/pages/Questions/AnswerDraggableList/AnswerItem.tsx +++ b/src/pages/Questions/AnswerDraggableList/AnswerItem.tsx @@ -82,11 +82,11 @@ export const AnswerItem = ({ setQuestionVariantAnswer(target.value || " "); }} onKeyDown={(event: KeyboardEvent) => { - if (disableKeyDown) { - enqueueSnackbar("100 максимальное количество вопросов"); - } else if (event.code === "Enter" && !largeCheck) { + // if (disableKeyDown) { + // enqueueSnackbar("100 максимальное количество вопросов"); + // } else if (event.code === "Enter" && !largeCheck) { addQuestionVariant(questionId); - } + // } }} InputProps={{ startAdornment: ( diff --git a/src/pages/Questions/BranchingMap/CsComponent.tsx b/src/pages/Questions/BranchingMap/CsComponent.tsx index 3ecb1118..c2cb3168 100644 --- a/src/pages/Questions/BranchingMap/CsComponent.tsx +++ b/src/pages/Questions/BranchingMap/CsComponent.tsx @@ -128,8 +128,6 @@ function CsComponent({ if ((parentQuestion?.type === "date" || parentQuestion?.type === "text" || parentQuestion?.type === "number" || parentQuestion?.type === "page") && parentQuestion.content.rule.children.length === 1 ) { - console.log(parentQuestion.content.rule.children) - console.log("parentQuestion.content.rule.children.length === 1",parentQuestion.content.rule.children.length === 1) enqueueSnackbar("у вопроса этого типа может быть только 1 потомок") return } @@ -140,8 +138,6 @@ function CsComponent({ clearDataAfterAddNode({ parentNodeContentId, targetQuestion, parentNodeChildren }) cy?.data('changed', true) createResult(quiz.backendId, targetQuestion.content.id) - console.log("Я собираюсь добавить узел из такого вопроса ", targetQuestion) - console.log("Я собираюсь добавить узел у которого папаша вот такой ", parentNodeContentId) const es = cy?.add([ { data: { @@ -268,7 +264,12 @@ function CsComponent({ return ( <> + sx={{ + mb:"20px", + display:'flex', + justifyContent:"space-between" + }} + > - } + )} - - ); }; diff --git a/src/pages/startPage/EditPage.tsx b/src/pages/startPage/EditPage.tsx index 397c6f17..7092d9ce 100755 --- a/src/pages/startPage/EditPage.tsx +++ b/src/pages/startPage/EditPage.tsx @@ -130,7 +130,7 @@ export default function EditPage() { ); const updateQuestionHint = useDebouncedCallback((questions: AnyTypedQuizQuestion[]) => { - const problems = checkQuestionHint(questions); + const problems = checkQuestionHint(questions, quiz); useUiTools.setState({ whyCantCreatePublic: problems }); if (Object.keys(problems).length > 0) { updateQuiz(quiz?.id, (state) => { @@ -187,8 +187,6 @@ export default function EditPage() { } }; - console.log(quiz?.status); - return ( <> {/*хедер*/} @@ -223,6 +221,12 @@ export default function EditPage() { + updateQuiz(quiz.id, (quiz) => { + quiz.name = e.target.value; + }) + } fullWidth id="project-name" placeholder="Название проекта окно" @@ -461,7 +465,7 @@ export default function EditPage() { fontSize: "14px", lineHeight: "18px", height: "34px", - background: quiz?.status === "start" ? "#7E2AEA" : "#FA5B0E", + background: buttonText === "Опубликовано" ? "#FA5B0E" : "#7E2AEA", }} onClick={handleClickStatusQuiz} > diff --git a/src/pages/startPage/ModalInfoWhyCantCreate.tsx b/src/pages/startPage/ModalInfoWhyCantCreate.tsx index 51ea68a1..cf2e362e 100644 --- a/src/pages/startPage/ModalInfoWhyCantCreate.tsx +++ b/src/pages/startPage/ModalInfoWhyCantCreate.tsx @@ -7,6 +7,14 @@ import { useLayoutEffect } from "react"; export const ModalInfoWhyCantCreate = () => { const { whyCantCreatePublic, openModalInfoWhyCantCreate } = useUiTools(); + useLayoutEffect(() => { + console.log(whyCantCreatePublic) +if (Object.values(whyCantCreatePublic).length===0) { + console.log("нет проблем") + updateModalInfoWhyCantCreate(false) +} + }, [openModalInfoWhyCantCreate]) + return ( updateModalInfoWhyCantCreate(false)}> { {Object.values(whyCantCreatePublic).map((data) => { return ( - У вопроса "{data.name}" + {data.name === "quiz" ? "У квиза" : `У вопроса "${data.name}"`} {data.problems.map((problem) => ( {problem} ))} diff --git a/src/pages/startPage/StartPageSettings.tsx b/src/pages/startPage/StartPageSettings.tsx index fa1cc2d4..55ff8842 100755 --- a/src/pages/startPage/StartPageSettings.tsx +++ b/src/pages/startPage/StartPageSettings.tsx @@ -285,7 +285,7 @@ export default function StartPageSettings() { Изображение updateQuiz(quiz.id, (quiz) => { quiz.config.startpage.background.video = e.target.value; @@ -396,7 +396,7 @@ export default function StartPageSettings() { Логотип updateQuiz(quiz.id, (quiz) => { quiz.name = e.target.value; @@ -529,7 +529,7 @@ export default function StartPageSettings() { updateQuiz(quiz.id, (quiz) => { quiz.config.startpage.description = e.target.value; @@ -549,7 +549,7 @@ export default function StartPageSettings() { updateQuiz(quiz.id, (quiz) => { quiz.config.startpage.button = e.target.value; @@ -569,7 +569,8 @@ export default function StartPageSettings() { updateQuiz(quiz.id, (quiz) => { quiz.config.info.phonenumber = e.target.value; @@ -599,7 +600,7 @@ export default function StartPageSettings() { updateQuiz(quiz.id, (quiz) => { quiz.config.info.orgname = e.target.value; @@ -619,7 +620,7 @@ export default function StartPageSettings() { updateQuiz(quiz.id, (quiz) => { quiz.config.info.site = e.target.value; @@ -639,7 +640,7 @@ export default function StartPageSettings() { updateQuiz(quiz.id, (quiz) => { quiz.config.info.law = e.target.value; diff --git a/src/stores/questions/actions.ts b/src/stores/questions/actions.ts index a5dcd65c..9ec02047 100644 --- a/src/stores/questions/actions.ts +++ b/src/stores/questions/actions.ts @@ -16,6 +16,7 @@ import { QuestionsStore, useQuestionsStore } from "./store"; import { useUiTools } from "../uiTools/store"; import { withErrorBoundary } from "react-error-boundary"; import { QuizQuestionResult } from "@model/questionTypes/result"; +import { replaceEmptyLinesToSpace } from "../../utils/replaceEmptyLinesToSpace"; export const setQuestions = (questions: RawQuestion[] | null) => setProducedState(state => { @@ -202,7 +203,7 @@ export const updateQuestion = async ( if (q.type === null) throw new Error("Cannot send update request for untyped question"); try { - const response = await questionApi.edit(questionToEditQuestionRequest(q)); + const response = await questionApi.edit(questionToEditQuestionRequest(replaceEmptyLinesToSpace(q))); //Если мы делаем листочек веточкой - удаляем созданный к нему результ const questionResult = useQuestionsStore.getState().questions.find(questionResult => questionResult.type === "result" && questionResult.content.rule.parentId === q.content.id); @@ -488,7 +489,6 @@ export const clearRuleForAll = () => { || question.content.rule.default.length > 0 || question.content.rule.parentId.length > 0) && question.type !== "result") { - console.log("вызываю очистку рул вопросов") updateQuestion(question.content.id, question => { question.content.rule.parentId = ""; question.content.rule.main = []; @@ -510,8 +510,6 @@ export const createResult = async ( //Мы получили запрос на создание резулта. Анализируем существует ли такой. Если да - просто делаем его активным const question = useQuestionsStore.getState().questions.find(q => q.type !== null && q?.content.rule.parentId === parentContentId) - console.log("Получил запрос на создание результа родителю ", parentContentId) - console.log("Ищу такой же результ в списке ", question) if (question) {//существует, делаем активным updateQuestion(question.id, (q) => { @@ -539,6 +537,7 @@ export const createResult = async ( type: "createBackResult", createdQuestion, }); + return createdQuestion } catch (error) { devlog("Error creating question", error); enqueueSnackbar("Не удалось создать вопрос"); diff --git a/src/ui_kit/CustomTextField.tsx b/src/ui_kit/CustomTextField.tsx index c9023f40..b8c09298 100755 --- a/src/ui_kit/CustomTextField.tsx +++ b/src/ui_kit/CustomTextField.tsx @@ -21,6 +21,7 @@ interface CustomTextFieldProps { maxLength?: number; sx?: SxProps; InputProps?: Partial; + type?:string } export default function CustomTextField({ @@ -35,6 +36,7 @@ export default function CustomTextField({ emptyError, InputProps, maxLength = 200, + type="" }: CustomTextFieldProps) { const theme = useTheme(); @@ -47,7 +49,13 @@ export default function CustomTextField({ const handleInputChange = (event: React.ChangeEvent) => { const inputValue = event.target.value; - setInputValue(inputValue); + + if (type === "number" ) { + setInputValue(inputValue .replace (/\D/g, '')); + } else { + setInputValue(inputValue); + } + if (onChange) { onChange(event); diff --git a/src/ui_kit/QuizPreview/QuizPreviewLayout.tsx b/src/ui_kit/QuizPreview/QuizPreviewLayout.tsx index 003d76b7..61241370 100644 --- a/src/ui_kit/QuizPreview/QuizPreviewLayout.tsx +++ b/src/ui_kit/QuizPreview/QuizPreviewLayout.tsx @@ -38,7 +38,7 @@ export default function QuizPreviewLayout() { const questions = useQuestionsStore((state) => state.questions); const currentQuizStep = useQuizPreviewStore((state) => state.currentQuestionIndex); - const nonDeletedQuizQuestions = questions.filter((question) => !question.deleted); + const nonDeletedQuizQuestions = questions.filter((question) => !question.deleted && question.type !== "result" ); const maxCurrentQuizStep = nonDeletedQuizQuestions.length > 0 ? nonDeletedQuizQuestions.length - 1 : 0; const currentProgress = Math.floor((currentQuizStep / maxCurrentQuizStep) * 100); @@ -135,7 +135,7 @@ export default function QuizPreviewLayout() { }} IconComponent={(props) => } > - {Object.values(questions).map(({ id, title }, index) => ( + {Object.values(questions.filter(q=>q.type!=="result")).map(({ id, title }, index) => ( => { +export const checkQuestionHint = (questions: AnyTypedQuizQuestion, quiz:Quiz): Record => { const problems: any = {} + if (quiz.config.startpageType === null) problems.quiz = {name: "quiz", problems: ["Не выбран тип стартовой страницы"]} + const pushProblem = (id: string, problem: string, title: string) => { //Если первый вопрос с проблемой - создаём запись. Если не первый - добавляем проблему if (id in problems) { diff --git a/src/utils/deleteFunc.ts b/src/utils/deleteFunc.ts index 27098b9d..cdb05e39 100644 --- a/src/utils/deleteFunc.ts +++ b/src/utils/deleteFunc.ts @@ -1,5 +1,5 @@ import { AnyTypedQuizQuestion } from "@model/questionTypes/shared"; -import { clearRuleForAll, deleteQuestion, getQuestionByContentId, updateQuestion } from "@root/questions/actions"; +import { clearRuleForAll, createResult, deleteQuestion, getQuestionByContentId, updateQuestion } from "@root/questions/actions"; import { updateRootContentId } from "@root/quizes/actions"; //Всё здесь нужно сделать последовательно. И пусть весь мир ждёт. @@ -11,11 +11,13 @@ export const DeleteFunction = async (questions: any, question: any, quiz: any) = if (question.content.rule.parentId === "root") { //удалить из стора root и очистить rule всем вопросам updateRootContentId(quiz.id, ""); await clearRuleForAll(); - console.log("очистка рулов закончилась") await deleteQuestion(question.id); } else if (question.content.rule.parentId.length > 0) { //удалить из стора вопрос из дерева и очистить его потомков const clearQuestions = [] as string[]; + const parentQuestion = getQuestionByContentId(question.content.rule.parentId); + let startCountParentChildren = parentQuestion.content.rule.children + //записываем потомков , а их результаты удаляем const getChildren = (parentQuestion: AnyTypedQuizQuestion) => { questions.forEach((targetQuestion) => { @@ -41,18 +43,54 @@ export const DeleteFunction = async (questions: any, question: any, quiz: any) = ) + //чистим rule родителя - const parentQuestion = getQuestionByContentId(question.content.rule.parentId); const newRule = {}; + const parentChildren = [...parentQuestion.content.rule.children]; + + + + console.log("_________________УДАЛЯЕМЫЙ ВОПРОС_________________", question.content.id) + console.log(parentChildren) + console.log(question.content.id) + console.log(parentChildren.includes(question.content.id)) + + + if (parentChildren.includes(question.content.id)) + parentChildren.splice(parentQuestion.content.rule.children.indexOf(question.content.id), 1) + + console.log("получившийся массив ", parentChildren) newRule.main = parentQuestion.content.rule.main.filter((data) => data.next !== question.content.id); //удаляем условия перехода от родителя к этому вопросу newRule.parentId = parentQuestion.content.rule.parentId; newRule.default = parentQuestion.content.rule.parentId === question.content.id ? "" : parentQuestion.content.rule.parentId; - newRule.children = [...parentQuestion.content.rule.children].splice(parentQuestion.content.rule.children.indexOf(question.content.id), 1); + newRule.children = parentChildren await updateQuestion(question.content.rule.parentId, (PQ) => { PQ.content.rule = newRule; }); await deleteQuestion(question.id); + + const parentResult = questions.find(q => q.type === "result" && q.content.rule.parentId === parentQuestion.content.id) + + + + //сделать результ родителя видимым если у него не осталось потомков + console.log("пришло время анализировать сделать ли результат родителя видимым") + console.log("количество детей ", startCountParentChildren.length) + + + if (startCountParentChildren.length === 1) { + if (parentResult) { + console.log("я нашел результат родителя") + await updateQuestion(parentResult.content.id, q => { + q.content.usage = true + }) + } else { //почему-то не существует результа у родителя. Создаём. Новосозданные результы видны сразу + console.log("я не нашел результат родителя") + await createResult(quiz.backendId, parentQuestion.content.id) + } + } + } await deleteQuestion(question.id); @@ -60,8 +98,6 @@ export const DeleteFunction = async (questions: any, question: any, quiz: any) = const result = questions.find(q => q.type === "result" && q.content.rule.parentId === question.content.id) if (result) await deleteQuestion(result.id); - } else { - await deleteQuestion(question.id); } } \ No newline at end of file diff --git a/src/utils/deleteTimeoutedQuestions.ts b/src/utils/deleteTimeoutedQuestions.ts index 19c18322..134faafb 100644 --- a/src/utils/deleteTimeoutedQuestions.ts +++ b/src/utils/deleteTimeoutedQuestions.ts @@ -6,12 +6,10 @@ import { DeleteFunction } from "@utils/deleteFunc"; type allQuestionsTypes = AnyTypedQuizQuestion | UntypedQuizQuestion export const deleteTimeoutedQuestions = async (questions: allQuestionsTypes[], quiz: Quiz|undefined) => { - console.log("Я отвечаю за удаление неудалёнышей при переключении. Привет, буде знакомы") const questionsForDeletion = questions.filter( ({ type, deleted }) => type && type !== "result" && deleted ) as AnyTypedQuizQuestion[]; if (questionsForDeletion.length > 0) { - console.log("меняю занятость беком на true") updateSomeWorkBackend(true) @@ -19,7 +17,6 @@ export const deleteTimeoutedQuestions = async (questions: allQuestionsTypes[], q questionsForDeletion.map(question => DeleteFunction(questions, question, quiz)) ) - console.log("______________меняю на 'можно редактировать дальше'______________") updateSomeWorkBackend(false) } }; \ No newline at end of file diff --git a/src/utils/hooks/useAddAnswer.ts b/src/utils/hooks/useAddAnswer.ts index e73cb096..d37c1e6a 100644 --- a/src/utils/hooks/useAddAnswer.ts +++ b/src/utils/hooks/useAddAnswer.ts @@ -6,11 +6,11 @@ export const useAddAnswer = () => { const { enqueueSnackbar } = useSnackbar(); const onClickAddAnAnswer = (question: QuizQuestionsWithVariants) => { - if (question.content.variants.length >= 10) { - enqueueSnackbar("100 максимальное количество вопросов"); - } else { + // if (question.content.variants.length >= 10) { + // enqueueSnackbar("100 максимальное количество вопросов"); + // } else { addQuestionVariant(question.id); - } + // } }; return onClickAddAnAnswer; diff --git a/src/utils/replaceEmptyLinesToSpace.ts b/src/utils/replaceEmptyLinesToSpace.ts new file mode 100644 index 00000000..0ac97782 --- /dev/null +++ b/src/utils/replaceEmptyLinesToSpace.ts @@ -0,0 +1,33 @@ +export const replaceEmptyLinesToSpace = (object: T): T => { + if (Array.isArray(object)) { + return object.map(replaceEmptyLinesToSpace) as T; + } + + if (!object || typeof object !== "object") { + return object; + } + + const result: Record = {}; + + for (const [key, value] of Object.entries(object)) { + if (typeof value === "string") { + if (value === "") { + result[key] = " "; + } else { + result[key] = value; + } + + continue; + } + + if (typeof value === "object") { + result[key] = replaceEmptyLinesToSpace(value); + + continue; + } + + result[key] = value; + } + + return result as T; +}; diff --git a/src/utils/replaceSpacesToEmptyLines.ts b/src/utils/replaceSpacesToEmptyLines.ts new file mode 100644 index 00000000..e6310b3b --- /dev/null +++ b/src/utils/replaceSpacesToEmptyLines.ts @@ -0,0 +1,29 @@ +export const replaceSpacesToEmptyLines = (object: T): T => { + if (Array.isArray(object)) { + return object.map(replaceSpacesToEmptyLines) as T; + } + + if (!object || typeof object !== "object") { + return object; + } + + const result: Record = {}; + + for (const [key, value] of Object.entries(object)) { + if (typeof value === "string") { + result[key] = value.replace(/ /g, ""); + + continue; + } + + if (typeof value === "object") { + result[key] = replaceSpacesToEmptyLines(value); + + continue; + } + + result[key] = value; + } + + return result as T; +};