#68 reorder questions
This commit is contained in:
parent
0cf4026a08
commit
5638be0664
|
|
@ -68,7 +68,7 @@ const ImageBoxFieldMemo = memo(
|
|||
console.log(name);
|
||||
|
||||
return (
|
||||
<div className="ImageBoxField">
|
||||
<div className="ImageBoxField" key={name}>
|
||||
<div className="ImageHeader">
|
||||
{imagePreview ? (
|
||||
<>
|
||||
|
|
@ -99,10 +99,11 @@ const ImageBoxFieldMemo = memo(
|
|||
/>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
(prevProps, nextProps) => {
|
||||
return areFieldPropsEqual(prevProps, nextProps);
|
||||
},
|
||||
}
|
||||
// ,
|
||||
// (prevProps, nextProps) => {
|
||||
// return areFieldPropsEqual(prevProps, nextProps);
|
||||
// },
|
||||
);
|
||||
|
||||
export default ImageBoxFieldMemo;
|
||||
|
|
|
|||
43
src/Hooks/useReOrderQuestions.ts
Normal file
43
src/Hooks/useReOrderQuestions.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import { useFormikContext } from 'formik';
|
||||
import React from 'react'
|
||||
import { moveToBottom, moveToTop } from '../utils/reOrder';
|
||||
type FormValues = {
|
||||
Questions: Array<{ id: string; sub_order?: number } & Record<string, any>>;
|
||||
};
|
||||
|
||||
export function useReOrderQuestions() {
|
||||
const {setFieldValue,values} = useFormikContext<FormValues>()
|
||||
|
||||
const withSubOrder = (arr: any[]) => arr.map((it, i) => ({ ...it, sub_order: i }));
|
||||
|
||||
const scrollToIdWithOffset = (id: string) => {
|
||||
const el = document.getElementById(id);
|
||||
if (!el) return;
|
||||
const top = el.getBoundingClientRect().top ;
|
||||
console.log(el.getBoundingClientRect())
|
||||
window.scrollBy({ top, behavior: "smooth" });
|
||||
};
|
||||
|
||||
const afterLayout = (fn: () => void) => {
|
||||
requestAnimationFrame(() => requestAnimationFrame(fn));
|
||||
};
|
||||
|
||||
const moveItemUp = (item:any,index: number) => {
|
||||
if (index <= 0) return;
|
||||
const next = moveToTop(index, values.Questions);
|
||||
setFieldValue("Questions", withSubOrder(next));
|
||||
afterLayout(() => scrollToIdWithOffset(`q-${item.id}`));
|
||||
|
||||
};
|
||||
|
||||
const moveItemDown = (item:any,index: number) => {
|
||||
if (index >= values.Questions.length - 1) return;
|
||||
const next = moveToBottom(index, values.Questions);
|
||||
setFieldValue("Questions", withSubOrder(next));
|
||||
afterLayout(() => scrollToIdWithOffset(`q-${item.id}`));
|
||||
|
||||
};
|
||||
|
||||
return { moveItemDown , moveItemUp }
|
||||
}
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ const CheckboxField = ({
|
|||
);
|
||||
};
|
||||
return (
|
||||
<div className={Group ? "d-inline mt-5 Checkbox" : ``}>
|
||||
<div className={Group ? "d-inline mt-5 Checkbox" : ``} key={name}>
|
||||
<Checkbox
|
||||
onChange={onChange || CheckboxhandleChange}
|
||||
disabled={isDisabled}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import ValidationField from "../../../../../../Components/ValidationField/ValidationField";
|
||||
import { Field } from "formik";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
|
@ -9,17 +9,21 @@ import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
|||
import LaTeXInputMemo from "../../../../../../Components/LatextInput/LaTeXInputMemo";
|
||||
import ImageBoxFieldMemo from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxFieldMemo";
|
||||
|
||||
|
||||
|
||||
const ChoiceFields = React.memo(
|
||||
({
|
||||
index,
|
||||
parent_index,
|
||||
setFieldValue,
|
||||
values,
|
||||
choiceId,
|
||||
}: {
|
||||
index: number;
|
||||
parent_index: number;
|
||||
setFieldValue: any;
|
||||
values: any;
|
||||
choiceId:number | string
|
||||
}) => {
|
||||
const [t] = useTranslation();
|
||||
const { ShowHint } = useObjectToEdit();
|
||||
|
|
@ -49,6 +53,11 @@ const ChoiceFields = React.memo(
|
|||
}
|
||||
return false;
|
||||
};
|
||||
const nameTxt = `Questions[${parent_index}].answers[${index}].content`;
|
||||
const nameImg = `Questions[${parent_index}].answers[${index}].content_image`;
|
||||
// useEffect(()=>{
|
||||
|
||||
// })a
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -58,13 +67,15 @@ const ChoiceFields = React.memo(
|
|||
>
|
||||
<Field
|
||||
component={LaTeXInputMemo}
|
||||
name={`Questions[${parent_index}].answers[${index}].content`}
|
||||
name={nameTxt}
|
||||
key={nameTxt}
|
||||
label={t(`input.choice`) + ` ` + `( ${index + 1} )`}
|
||||
/>
|
||||
|
||||
<Field
|
||||
component={ImageBoxFieldMemo}
|
||||
name={`Questions.${parent_index}.answers.${index}.content_image`}
|
||||
name={nameImg}
|
||||
key={nameImg}
|
||||
/>
|
||||
|
||||
<div className="answer_status">
|
||||
|
|
@ -106,26 +117,27 @@ const ChoiceFields = React.memo(
|
|||
</div>
|
||||
</>
|
||||
);
|
||||
},
|
||||
(prevProps, nextProps) => {
|
||||
console.log(
|
||||
prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[
|
||||
prevProps?.index
|
||||
] ===
|
||||
nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[
|
||||
prevProps?.index
|
||||
],
|
||||
);
|
||||
}
|
||||
// areEqual
|
||||
// (prevProps, nextProps) => {
|
||||
// console.log(
|
||||
// prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[
|
||||
// prevProps?.index
|
||||
// ] ===
|
||||
// nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[
|
||||
// prevProps?.index
|
||||
// ],
|
||||
// );
|
||||
|
||||
return (
|
||||
prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[
|
||||
prevProps?.index
|
||||
] ===
|
||||
nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[
|
||||
prevProps?.index
|
||||
]
|
||||
);
|
||||
},
|
||||
// return (
|
||||
// prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[
|
||||
// prevProps?.index
|
||||
// ] ===
|
||||
// nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[
|
||||
// prevProps?.index
|
||||
// ]
|
||||
// );
|
||||
// },
|
||||
);
|
||||
|
||||
export default ChoiceFields;
|
||||
|
|
|
|||
|
|
@ -45,9 +45,10 @@ const Choices = React.memo(
|
|||
{(values?.Questions?.[parent_index]?.answers || []).map(
|
||||
(item: Choice, index: number) => {
|
||||
return (
|
||||
<div className="Choices ChoicesMalty" key={index}>
|
||||
<div className="Choices ChoicesMalty" key={item?.id} onClick={() => console.log(item)}>
|
||||
<ChoiceFields
|
||||
key={index}
|
||||
key={item?.id}
|
||||
choiceId={item.id} // جديد
|
||||
parent_index={parent_index}
|
||||
index={index}
|
||||
setFieldValue={setFieldValue}
|
||||
|
|
@ -104,13 +105,14 @@ const Choices = React.memo(
|
|||
</DragDropContext> */}
|
||||
</>
|
||||
);
|
||||
},
|
||||
(prevProps, nextProps) => {
|
||||
return (
|
||||
prevProps.values?.Questions?.[prevProps?.parent_index]?.answers ===
|
||||
nextProps.values?.Questions?.[nextProps?.parent_index]?.answers
|
||||
);
|
||||
},
|
||||
}
|
||||
// ,
|
||||
// (prevProps, nextProps) => {
|
||||
// return (
|
||||
// prevProps.values?.Questions?.[prevProps?.parent_index]?.answers ===
|
||||
// nextProps.values?.Questions?.[nextProps?.parent_index]?.answers
|
||||
// );
|
||||
// },
|
||||
);
|
||||
|
||||
export default Choices;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ const QuestionFIeld = ({
|
|||
const formik = useFormikContext<any>();
|
||||
const { setDeletedQuestions, DeletedQuestions } = useObjectToEdit();
|
||||
|
||||
// const path = git
|
||||
const [t] = useTranslation();
|
||||
useEffect(() => {
|
||||
setDeletedQuestions([]);
|
||||
|
|
@ -46,9 +47,14 @@ const QuestionFIeld = ({
|
|||
return false;
|
||||
};
|
||||
|
||||
const nameImg = `Questions[${index}].content_image`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="exercise_forms">
|
||||
<div className="exercise_forms" onClick={() => {
|
||||
console.log(values.Questions[index])
|
||||
console.log(index)
|
||||
}}>
|
||||
<div className="ChoiceFields">
|
||||
<Field
|
||||
component={LaTeXInputMemo}
|
||||
|
|
@ -57,8 +63,10 @@ const QuestionFIeld = ({
|
|||
label={t(`input.question`) + ` ` + `( ${index + 1} )`}
|
||||
/>
|
||||
<Field
|
||||
onClick={ () => console.log(index)}
|
||||
component={ImageBoxFieldMemo}
|
||||
name={`Questions.${index}.content_image`}
|
||||
name={nameImg}
|
||||
|
||||
/>
|
||||
{handelCanDeleteAnswers() ? (
|
||||
<div className="answer_status">
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { toast } from "react-toastify";
|
|||
import SelectTagV2 from "../../../../../../Components/CustomFields/SelectTagV2";
|
||||
import LaTeXInputMemo from "../../../../../../Components/LatextInput/LaTeXInputMemo";
|
||||
import { Field } from "formik";
|
||||
import { uid } from "../../../../../../utils/reOrder";
|
||||
|
||||
export const Question: React.FC<any> = React.memo(({ index, data }) => {
|
||||
const { values, setFieldValue, ShowHint, t } = data;
|
||||
|
|
@ -18,6 +19,7 @@ export const Question: React.FC<any> = React.memo(({ index, data }) => {
|
|||
setFieldValue(`Questions.[${parent_index}].answers`, [
|
||||
...(values?.Questions?.[parent_index]?.answers as Choice[]),
|
||||
{
|
||||
id: uid(),
|
||||
answer: null,
|
||||
content_image: null,
|
||||
content: null,
|
||||
|
|
@ -38,7 +40,6 @@ export const Question: React.FC<any> = React.memo(({ index, data }) => {
|
|||
<QuestionFIeld
|
||||
setFieldValue={setFieldValue}
|
||||
values={values}
|
||||
key={index}
|
||||
index={index}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -65,9 +66,9 @@ export const Question: React.FC<any> = React.memo(({ index, data }) => {
|
|||
name={`Questions[${index}].hint`}
|
||||
label={t("input.hint_question")}
|
||||
type="TextArea"
|
||||
style={{ width: "100%", height: 60, resize: "none" }}
|
||||
// style={{ width: "100%", height: 60, resize: "none" }}
|
||||
showCount={false}
|
||||
autoSize={{ minRows: 2, maxRows: 10 }}
|
||||
// autoSize={{ minRows: 2, maxRows: 10 }}
|
||||
/>
|
||||
)}
|
||||
<MaltySelectTag parent_index={index} />
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ import { VariableSizeList as List } from "react-window";
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
||||
import { Question } from "./Question";
|
||||
import { moveToBottom, moveToTop } from "../../../../../../utils/reOrder";
|
||||
import { FaArrowRightLong } from "react-icons/fa6";
|
||||
import { useReOrderQuestions } from "../../../../../../Hooks/useReOrderQuestions";
|
||||
|
||||
interface QuestionsProps {
|
||||
setFieldValue: (field: string, value: any) => void;
|
||||
|
|
@ -16,7 +19,9 @@ const Questions: React.FC<QuestionsProps> = React.memo(
|
|||
const questions = values?.Questions || [];
|
||||
const { ShowHint } = useObjectToEdit();
|
||||
const [t] = useTranslation();
|
||||
const listRef = useRef<List>(null);
|
||||
// const listRef = useRef<List>(null);
|
||||
const rowRefs = useRef<Record<string, HTMLDivElement | null>>({});
|
||||
|
||||
|
||||
const getItemSize = useCallback(
|
||||
(index: number) => {
|
||||
|
|
@ -33,22 +38,24 @@ const Questions: React.FC<QuestionsProps> = React.memo(
|
|||
},
|
||||
[questions, ShowHint],
|
||||
);
|
||||
// == we don use it ==
|
||||
// const itemData = useMemo(
|
||||
// () => ({
|
||||
// values,
|
||||
// setFieldValue,
|
||||
// ShowHint,
|
||||
// t,
|
||||
// }),
|
||||
// [values, setFieldValue, ShowHint, t],
|
||||
// );
|
||||
|
||||
const itemData = useMemo(
|
||||
() => ({
|
||||
values,
|
||||
setFieldValue,
|
||||
ShowHint,
|
||||
t,
|
||||
}),
|
||||
[values, setFieldValue, ShowHint, t],
|
||||
);
|
||||
// useEffect(() => {
|
||||
// if (listRef.current) {
|
||||
// listRef.current.resetAfterIndex(0);
|
||||
// }
|
||||
// }, [questions, ShowHint]);
|
||||
|
||||
useEffect(() => {
|
||||
if (listRef.current) {
|
||||
listRef.current.resetAfterIndex(0);
|
||||
}
|
||||
}, [questions, ShowHint]);
|
||||
const { moveItemDown , moveItemUp} = useReOrderQuestions()
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -66,12 +73,25 @@ const Questions: React.FC<QuestionsProps> = React.memo(
|
|||
{Question}
|
||||
</List> */}
|
||||
{questions?.map((item: any, index: number) => {
|
||||
console.log(item)
|
||||
console.log(questions)
|
||||
return (
|
||||
<Question
|
||||
key={index}
|
||||
<div
|
||||
key={item.id}
|
||||
id={`q-${item.id}`}
|
||||
onClick={() => console.log(questions)}
|
||||
ref={(el) => (rowRefs.current[item.id] = el)}
|
||||
> <Question
|
||||
// key={questions[index]?.content}
|
||||
index={index}
|
||||
data={{ values, setFieldValue, ShowHint, t }}
|
||||
/>
|
||||
|
||||
<div className="positionButtons">
|
||||
<FaArrowRightLong className="toTop" onClick={() => moveItemUp(item,index)}/>
|
||||
<FaArrowRightLong className="toBotton" onClick={() => moveItemDown(item,index)}/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
|
|
|
|||
36
src/utils/reOrder.ts
Normal file
36
src/utils/reOrder.ts
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// export function moveToTop(index:number,array:any[]){
|
||||
// const indexItemBefore = index - 1
|
||||
// if(indexItemBefore == -1)return array;
|
||||
// const currentItem = array[index]
|
||||
// array[index] = array[indexItemBefore]
|
||||
// array[indexItemBefore] = currentItem
|
||||
// return array
|
||||
|
||||
// }
|
||||
// export function moveToBottom(index:number,array:any[]){
|
||||
// const indexItemAfter = index + 1
|
||||
// if(indexItemAfter == array.length)return array;
|
||||
// const currentItem = array[index]
|
||||
// array[index] = array[indexItemAfter]
|
||||
// array[indexItemAfter] = currentItem
|
||||
// return array
|
||||
// }
|
||||
|
||||
function swapImmutable<T>(arr: T[], i: number, j: number): T[] {
|
||||
if (i === j) return arr.slice();
|
||||
const copy = arr.slice();
|
||||
[copy[i], copy[j]] = [copy[j], copy[i]];
|
||||
return copy;
|
||||
}
|
||||
|
||||
export function moveToTop(index: number, array: any[]) {
|
||||
if (index <= 0) return array.slice();
|
||||
return swapImmutable(array, index, index - 1);
|
||||
}
|
||||
|
||||
export function moveToBottom(index: number, array: any[]) {
|
||||
if (index >= array.length - 1) return array.slice();
|
||||
return swapImmutable(array, index, index + 1);
|
||||
}
|
||||
|
||||
export const uid = () => Date.now().toString() + Math.random().toString(36).slice(2,9);
|
||||
Loading…
Reference in New Issue
Block a user