add question VariableSizeList
This commit is contained in:
parent
869e857f2c
commit
cda04660bf
67
src/Pages/Admin/question/Model/Malty/components/Question.tsx
Normal file
67
src/Pages/Admin/question/Model/Malty/components/Question.tsx
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import React, { useCallback } from "react";
|
||||
import { Choice } from "../../../../../../types/Item";
|
||||
import QuestionFIeld from "../QuestionFIeld/QuestionFIeld";
|
||||
import Choices from "../ChoiceField/Choices";
|
||||
import { FaCirclePlus } from "react-icons/fa6";
|
||||
import ValidationField from "../../../../../../Components/ValidationField/ValidationField";
|
||||
import MaltySelectTag from "../Tags/MaltySelectTag";
|
||||
import { toast } from "react-toastify";
|
||||
|
||||
export const Question: React.FC<any> = React.memo(({ index, style, data }) => {
|
||||
const { values, setFieldValue, ShowHint, t } = data;
|
||||
|
||||
const handleAddChoice = useCallback((
|
||||
parent_index: number,
|
||||
fromKeyCombination: boolean = false,
|
||||
) => {
|
||||
setFieldValue(`Questions.[${parent_index}].answers`, [
|
||||
...(values?.Questions?.[parent_index]?.answers as Choice[]),
|
||||
{
|
||||
answer: null,
|
||||
content_image: null,
|
||||
content: null,
|
||||
isCorrect: 0,
|
||||
},
|
||||
]);
|
||||
|
||||
if (fromKeyCombination) {
|
||||
toast.success(t("header.new_choice_have_been_added"));
|
||||
}
|
||||
}, [setFieldValue, values, t]);
|
||||
|
||||
return (
|
||||
<div style={style}>
|
||||
<div className="exercise_form QuestionFIeld">
|
||||
<QuestionFIeld setFieldValue={setFieldValue} values={values} key={index} index={index} />
|
||||
</div>
|
||||
|
||||
<Choices setFieldValue={setFieldValue} values={values} parent_index={index} />
|
||||
|
||||
{values?.Questions?.[index]?.answers?.length < 5 && (
|
||||
<p className="add_new_button">
|
||||
<FaCirclePlus
|
||||
onClick={() => handleAddChoice(index)}
|
||||
size={23}
|
||||
/>{" "}
|
||||
{t("header.add_new_choice")}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="exercise_form_width">
|
||||
{ShowHint && (
|
||||
<ValidationField
|
||||
className=" "
|
||||
placeholder="_"
|
||||
name={`Questions.${index}.hint`}
|
||||
label="hint_question"
|
||||
type="TextArea"
|
||||
style={{ width: "100%", height: 60, resize: "none" }}
|
||||
autoSize={{ minRows: 2, maxRows: 10 }}
|
||||
showCount={false}
|
||||
/>
|
||||
)}
|
||||
<MaltySelectTag parent_index={index} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
import React, { useCallback, useMemo } from 'react';
|
||||
import { FixedSizeList as List, areEqual } from 'react-window';
|
||||
import { Choice } from '../../../../../../types/Item';
|
||||
import QuestionFIeld from '../QuestionFIeld/QuestionFIeld';
|
||||
import Choices from '../ChoiceField/Choices';
|
||||
import { FaCirclePlus } from 'react-icons/fa6';
|
||||
import ValidationField from '../../../../../../Components/ValidationField/ValidationField';
|
||||
import MaltySelectTag from '../Tags/MaltySelectTag';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useObjectToEdit } from '../../../../../../zustand/ObjectToEditState';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
interface QuestionsProps {
|
||||
setFieldValue: (field: string, value: any) => void;
|
||||
values: {
|
||||
Questions: Choice[];
|
||||
};
|
||||
}
|
||||
|
||||
const Row: React.FC<any> = React.memo(({ index, data }) => {
|
||||
const { values, setFieldValue } = data;
|
||||
const { ShowHint } = useObjectToEdit();
|
||||
const [t] = useTranslation();
|
||||
|
||||
const handleAddChoice = useCallback((
|
||||
parent_index: number,
|
||||
fromKeyCombination: boolean = false,
|
||||
) => {
|
||||
setFieldValue(`Questions.[${parent_index}].answers`, [
|
||||
...(values?.Questions?.[parent_index]?.answers as Choice[]),
|
||||
{
|
||||
answer: null,
|
||||
content_image: null,
|
||||
content: null,
|
||||
isCorrect: 0,
|
||||
},
|
||||
]);
|
||||
|
||||
if (fromKeyCombination) {
|
||||
toast.success(t("header.new_choice_have_been_added"));
|
||||
}
|
||||
}, [setFieldValue, values, t]);
|
||||
|
||||
return (
|
||||
<div key={index}>
|
||||
<div className="exercise_form QuestionFIeld">
|
||||
<QuestionFIeld setFieldValue={setFieldValue} values={values} key={index} index={index} />
|
||||
</div>
|
||||
|
||||
<Choices setFieldValue={setFieldValue} values={values} parent_index={index} />
|
||||
|
||||
{values?.Questions?.[index]?.answers?.length < 5 && (
|
||||
<p className="add_new_button">
|
||||
<FaCirclePlus
|
||||
onClick={() => handleAddChoice(index)}
|
||||
size={23}
|
||||
/>{" "}
|
||||
{t("header.add_new_choice")}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="exercise_form_width">
|
||||
{ShowHint && (
|
||||
<ValidationField
|
||||
className=" "
|
||||
placeholder="_"
|
||||
name={`Questions.${index}.hint`}
|
||||
label="hint_question"
|
||||
type="TextArea"
|
||||
style={{ width: "100%", height: 60, resize: "none" }}
|
||||
autoSize={{ minRows: 2, maxRows: 10 }}
|
||||
showCount={false}
|
||||
/>
|
||||
)}
|
||||
<MaltySelectTag parent_index={index} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}, areEqual);
|
||||
|
||||
const Questions: React.FC<QuestionsProps> = React.memo(({ setFieldValue, values }) => {
|
||||
const questions = values.Questions || [];
|
||||
|
||||
const itemData = useMemo(() => ({ values, setFieldValue }), [values, setFieldValue]);
|
||||
const itemSize = 1100;
|
||||
const listHeight = useMemo(() => {
|
||||
return Math.min(1300, questions.length * itemSize); // Adjust 400 to your desired max height
|
||||
}, [questions.length]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<List
|
||||
height={listHeight}
|
||||
itemCount={questions.length}
|
||||
itemSize={itemSize}
|
||||
width="100%"
|
||||
itemData={itemData}
|
||||
direction='rtl'
|
||||
>
|
||||
{Row}
|
||||
</List>
|
||||
|
||||
{/* {(values?.Questions || [])?.map(
|
||||
(item: Choice, parent_index: number) => {
|
||||
return (
|
||||
<Row key={parent_index} index={parent_index} data={{values, setFieldValue}} />
|
||||
);
|
||||
}
|
||||
)} */}
|
||||
|
||||
</>
|
||||
);
|
||||
}, (prevProps, nextProps) => prevProps.values.Questions === nextProps.values.Questions);
|
||||
|
||||
export default Questions;
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
import React from 'react'
|
||||
import QuestionFIeld from '../QuestionFIeld/QuestionFIeld';
|
||||
import { Choice } from '../../../../../../types/Item';
|
||||
import Choices from '../ChoiceField/Choices';
|
||||
import { FaCirclePlus } from 'react-icons/fa6';
|
||||
import ValidationField from '../../../../../../Components/ValidationField/ValidationField';
|
||||
import MaltySelectTag from '../Tags/MaltySelectTag';
|
||||
import { useObjectToEdit } from '../../../../../../zustand/ObjectToEditState';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
// Memoized Questions Component
|
||||
const Questions = React.memo(({setFieldValue,values}:any) => {
|
||||
const { ShowHint } = useObjectToEdit();
|
||||
const [t] = useTranslation();
|
||||
|
||||
const handleAddChoice = (
|
||||
parent_index: number,
|
||||
fromKeyCombination: boolean = false,
|
||||
) => {
|
||||
setFieldValue(`Questions.[${parent_index}].answers`, [
|
||||
...((values as any)?.Questions?.[parent_index]
|
||||
?.answers as Choice[]),
|
||||
{
|
||||
answer: null,
|
||||
content_image: null,
|
||||
content: null,
|
||||
isCorrect: 0,
|
||||
},
|
||||
]);
|
||||
|
||||
if (fromKeyCombination) {
|
||||
toast.success(t("header.new_choice_have_been_added"));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{(values?.Questions || [])?.map(
|
||||
(item: Choice, parent_index: number) => {
|
||||
return (
|
||||
<div key={parent_index}>
|
||||
<div className="exercise_form QuestionFIeld">
|
||||
<QuestionFIeld setFieldValue={setFieldValue} values={values} key={parent_index} index={parent_index} />
|
||||
</div>
|
||||
|
||||
<Choices setFieldValue={setFieldValue} values={values} parent_index={parent_index} />
|
||||
|
||||
{values?.Questions?.[parent_index]?.answers?.length < 5 && (
|
||||
<p className="add_new_button">
|
||||
<FaCirclePlus
|
||||
onClick={() => handleAddChoice(parent_index)}
|
||||
size={23}
|
||||
/>{" "}
|
||||
{t("header.add_new_choice")}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="exercise_form_width">
|
||||
{ShowHint && (
|
||||
<ValidationField
|
||||
className=" "
|
||||
placeholder="_"
|
||||
name={`Questions.${parent_index}.hint`}
|
||||
label="hint_question"
|
||||
type="TextArea"
|
||||
style={{ width: "100%", height: 60, resize: "none" }}
|
||||
autoSize={{ minRows: 2, maxRows: 10 }}
|
||||
showCount={false}
|
||||
/>
|
||||
)}
|
||||
<MaltySelectTag parent_index={parent_index} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}, (prevProps, nextProps) => {
|
||||
|
||||
return prevProps.values.Questions === nextProps.values.Questions;
|
||||
});
|
||||
|
||||
export default Questions;
|
||||
|
|
@ -1,14 +1,8 @@
|
|||
import React, { useCallback, useMemo, useRef, useEffect } from 'react';
|
||||
import { VariableSizeList as List } from 'react-window';
|
||||
import { Choice } from '../../../../../../types/Item';
|
||||
import QuestionFIeld from '../QuestionFIeld/QuestionFIeld';
|
||||
import Choices from '../ChoiceField/Choices';
|
||||
import { FaCirclePlus } from 'react-icons/fa6';
|
||||
import ValidationField from '../../../../../../Components/ValidationField/ValidationField';
|
||||
import MaltySelectTag from '../Tags/MaltySelectTag';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useObjectToEdit } from '../../../../../../zustand/ObjectToEditState';
|
||||
import { toast } from 'react-toastify';
|
||||
import { Question } from './Question';
|
||||
|
||||
interface QuestionsProps {
|
||||
setFieldValue: (field: string, value: any) => void;
|
||||
|
|
@ -17,67 +11,8 @@ interface QuestionsProps {
|
|||
};
|
||||
}
|
||||
|
||||
const Row: React.FC<any> = React.memo(({ index, style, data }) => {
|
||||
const { values, setFieldValue, ShowHint, t } = data;
|
||||
|
||||
const handleAddChoice = useCallback((
|
||||
parent_index: number,
|
||||
fromKeyCombination: boolean = false,
|
||||
) => {
|
||||
setFieldValue(`Questions.[${parent_index}].answers`, [
|
||||
...(values?.Questions?.[parent_index]?.answers as Choice[]),
|
||||
{
|
||||
answer: null,
|
||||
content_image: null,
|
||||
content: null,
|
||||
isCorrect: 0,
|
||||
},
|
||||
]);
|
||||
|
||||
if (fromKeyCombination) {
|
||||
toast.success(t("header.new_choice_have_been_added"));
|
||||
}
|
||||
}, [setFieldValue, values, t]);
|
||||
|
||||
return (
|
||||
<div style={style}>
|
||||
<div className="exercise_form QuestionFIeld">
|
||||
<QuestionFIeld setFieldValue={setFieldValue} values={values} key={index} index={index} />
|
||||
</div>
|
||||
|
||||
<Choices setFieldValue={setFieldValue} values={values} parent_index={index} />
|
||||
|
||||
{values?.Questions?.[index]?.answers?.length < 5 && (
|
||||
<p className="add_new_button">
|
||||
<FaCirclePlus
|
||||
onClick={() => handleAddChoice(index)}
|
||||
size={23}
|
||||
/>{" "}
|
||||
{t("header.add_new_choice")}
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="exercise_form_width">
|
||||
{ShowHint && (
|
||||
<ValidationField
|
||||
className=" "
|
||||
placeholder="_"
|
||||
name={`Questions.${index}.hint`}
|
||||
label="hint_question"
|
||||
type="TextArea"
|
||||
style={{ width: "100%", height: 60, resize: "none" }}
|
||||
autoSize={{ minRows: 2, maxRows: 10 }}
|
||||
showCount={false}
|
||||
/>
|
||||
)}
|
||||
<MaltySelectTag parent_index={index} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
const Questions: React.FC<QuestionsProps> = React.memo(({ setFieldValue, values }) => {
|
||||
const questions = values.Questions || [];
|
||||
const questions = values?.Questions || [];
|
||||
const { ShowHint } = useObjectToEdit();
|
||||
const [t] = useTranslation();
|
||||
const listRef = useRef<List>(null);
|
||||
|
|
@ -111,16 +46,16 @@ const Questions: React.FC<QuestionsProps> = React.memo(({ setFieldValue, values
|
|||
<List
|
||||
ref={listRef}
|
||||
height={window.innerHeight - 20} // Adjust based on your layout
|
||||
itemCount={questions.length}
|
||||
itemCount={questions?.length}
|
||||
itemSize={getItemSize}
|
||||
width="100%"
|
||||
itemData={itemData}
|
||||
direction='rtl'
|
||||
className='ListQuestions'
|
||||
className=' '
|
||||
>
|
||||
{Row}
|
||||
{Question}
|
||||
</List>
|
||||
);
|
||||
}, (prevProps, nextProps) => prevProps.values.Questions === nextProps.values.Questions);
|
||||
}, (prevProps, nextProps) => prevProps?.values?.Questions === nextProps?.values?.Questions);
|
||||
|
||||
export default Questions;
|
||||
|
|
@ -357,5 +357,6 @@
|
|||
|
||||
|
||||
.ListQuestions{
|
||||
@include Scrollbar()
|
||||
@include Scrollbar();
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user