fix: test
This commit is contained in:
@@ -35,15 +35,15 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="exam-question-builder__col exam-question-builder__col--score">
|
||||
<label class="exam-question-builder__label">ترتیب</label>
|
||||
<label class="exam-question-builder__label">بارم نمره</label>
|
||||
<input
|
||||
:value="question.position"
|
||||
:value="question.score"
|
||||
:disabled="disabled || isLocked(question)"
|
||||
type="text"
|
||||
inputmode="numeric"
|
||||
placeholder="1"
|
||||
class="exam-question-builder__input"
|
||||
@input="updateQuestion(question.id, { position: $event.target.value })"
|
||||
@input="updateQuestion(question.id, { score: $event.target.value })"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -147,7 +147,7 @@ const createOption = () => ({ id: createId('option'), optionText: '', isCorrect:
|
||||
const createQuestion = () => ({
|
||||
id: createId('question'),
|
||||
questionText: '',
|
||||
position: questions.value.length + 1,
|
||||
score: '',
|
||||
options: [createOption(), createOption()],
|
||||
__local: true,
|
||||
})
|
||||
|
||||
@@ -7,6 +7,18 @@
|
||||
</template>
|
||||
</TextField>
|
||||
<SelectField
|
||||
v-model="form.termId"
|
||||
name="termId"
|
||||
label="ترم"
|
||||
:options="termOptions"
|
||||
option-label="title"
|
||||
option-value="id"
|
||||
:searchable="true"
|
||||
:on-search="searchTerms"
|
||||
@update:modelValue="onTermChange"
|
||||
/>
|
||||
<SelectField
|
||||
v-if="form.termId"
|
||||
v-model="form.courseId"
|
||||
name="courseId"
|
||||
label="دوره"
|
||||
@@ -15,6 +27,18 @@
|
||||
option-value="id"
|
||||
:searchable="true"
|
||||
:on-search="searchTemplates"
|
||||
@update:modelValue="onCourseChange"
|
||||
/>
|
||||
<SelectField
|
||||
v-if="form.courseId"
|
||||
v-model="form.sessionId"
|
||||
name="sessionId"
|
||||
label="جلسه"
|
||||
:options="sessionOptions"
|
||||
option-label="title"
|
||||
option-value="id"
|
||||
:searchable="true"
|
||||
:on-search="searchSessions"
|
||||
/>
|
||||
<DatePickerField v-model="form.fromDate" name="fromDate" label="از تاریخ" :max="todayIso" />
|
||||
<DatePickerField v-model="form.toDate" name="toDate" label="تا تاریخ" :max="todayIso" />
|
||||
@@ -55,18 +79,34 @@ import TextField from '@/components/form/TextField.vue'
|
||||
import CircleButton from '@/components/CircleButton.vue'
|
||||
import SelectField from '@/components/form/SelectField.vue'
|
||||
import DatePickerField from '@/components/form/DatePickerField.vue'
|
||||
import { useAdminTermsListQuery } from '@/services/query/admin-terms'
|
||||
import { useAdminCoursesListQuery } from '@/services/query/admin-courses'
|
||||
import { useAdminSessionsListQuery } from '@/services/query/admin-sessions'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Object,
|
||||
default: () => ({ title: '', courseId: '', fromDate: '', toDate: '' }),
|
||||
default: () => ({
|
||||
title: '',
|
||||
termId: '',
|
||||
courseId: '',
|
||||
sessionId: '',
|
||||
fromDate: '',
|
||||
toDate: '',
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'apply', 'reset'])
|
||||
|
||||
const emptyForm = () => ({ title: '', courseId: '', fromDate: '', toDate: '' })
|
||||
const emptyForm = () => ({
|
||||
title: '',
|
||||
termId: '',
|
||||
courseId: '',
|
||||
sessionId: '',
|
||||
fromDate: '',
|
||||
toDate: '',
|
||||
})
|
||||
const form = ref({ ...emptyForm(), ...props.modelValue })
|
||||
|
||||
watch(
|
||||
@@ -79,15 +119,52 @@ watch(
|
||||
|
||||
const todayIso = new Date().toISOString()
|
||||
|
||||
const termSearch = ref('')
|
||||
const termFilters = computed(() => ({ title: termSearch.value }))
|
||||
const termPagination = ref({ page: 1, perPage: 100 })
|
||||
const { data: termsResponse } = useAdminTermsListQuery(termFilters, termPagination)
|
||||
const termOptions = computed(() => termsResponse.value?.data ?? [])
|
||||
|
||||
const templateSearch = ref('')
|
||||
const templateFilters = computed(() => ({ title: templateSearch.value }))
|
||||
const templateFilters = computed(() => ({
|
||||
title: templateSearch.value,
|
||||
termId: form.value.termId || undefined,
|
||||
}))
|
||||
const templatePagination = ref({ page: 1, perPage: 10 })
|
||||
const { data: templatesResponse } = useAdminCoursesListQuery(templateFilters, templatePagination)
|
||||
const { data: templatesResponse } = useAdminCoursesListQuery(templateFilters, templatePagination, {
|
||||
enabled: () => !!form.value.termId,
|
||||
})
|
||||
const templateOptions = computed(() => templatesResponse.value?.data ?? [])
|
||||
|
||||
const sessionSearch = ref('')
|
||||
const sessionListFilters = computed(() => ({
|
||||
title: sessionSearch.value,
|
||||
courseId: form.value.courseId || undefined,
|
||||
}))
|
||||
const sessionPagination = ref({ page: 1, perPage: 10 })
|
||||
const { data: sessionsResponse } = useAdminSessionsListQuery(sessionListFilters, sessionPagination, {
|
||||
enabled: () => !!form.value.courseId,
|
||||
})
|
||||
const sessionOptions = computed(() => sessionsResponse.value?.data ?? [])
|
||||
|
||||
const searchTerms = useDebounce((q) => {
|
||||
termSearch.value = q || ''
|
||||
}, 400)
|
||||
const searchTemplates = useDebounce((q) => {
|
||||
templateSearch.value = q || ''
|
||||
}, 400)
|
||||
const searchSessions = useDebounce((q) => {
|
||||
sessionSearch.value = q || ''
|
||||
}, 400)
|
||||
|
||||
const onTermChange = () => {
|
||||
form.value.courseId = ''
|
||||
form.value.sessionId = ''
|
||||
}
|
||||
|
||||
const onCourseChange = () => {
|
||||
form.value.sessionId = ''
|
||||
}
|
||||
|
||||
const hasFilters = computed(() =>
|
||||
Object.values(form.value).some((v) => v !== '' && v !== null && v !== undefined)
|
||||
@@ -118,7 +195,11 @@ const onReset = () => {
|
||||
gap: 0.5rem;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
@media (min-width: 1280px) {
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ const blankOption = () => ({ id: createId('option'), optionText: '', isCorrect:
|
||||
const blankQuestion = () => ({
|
||||
id: createId('question'),
|
||||
questionText: '',
|
||||
position: 1,
|
||||
score: '',
|
||||
options: [blankOption(), { ...blankOption(), id: createId('option') }],
|
||||
__local: true,
|
||||
})
|
||||
@@ -172,7 +172,7 @@ const normalizeExistingQuestions = (raw = []) => {
|
||||
return {
|
||||
id: q.id ?? createId(`question-${qIdx}`),
|
||||
questionText: q.questionText || '',
|
||||
position: q.position ?? qIdx + 1,
|
||||
score: q.score ?? '',
|
||||
options: options.map((o, oIdx) => ({
|
||||
id: o.id ?? createId(`option-${qIdx}-${oIdx}`),
|
||||
optionText: o.optionText || '',
|
||||
@@ -220,7 +220,8 @@ const validateLocalQuestions = () => {
|
||||
questionError.value = ''
|
||||
return localOnes.map((q, idx) => ({
|
||||
questionText: q.questionText.trim(),
|
||||
position: Number(q.position) || idx + 1,
|
||||
position: idx + 1,
|
||||
score: Number(q.score) || 0,
|
||||
options: q.options
|
||||
.filter((o) => String(o.optionText || '').trim())
|
||||
.map((o) => ({
|
||||
|
||||
@@ -75,7 +75,14 @@ const router = useRouter()
|
||||
const queryClient = useQueryClient()
|
||||
const { openModal, isModal } = useModal()
|
||||
|
||||
const filters = ref({ title: '', courseId: '', fromDate: '', toDate: '' })
|
||||
const filters = ref({
|
||||
title: '',
|
||||
termId: '',
|
||||
courseId: '',
|
||||
sessionId: '',
|
||||
fromDate: '',
|
||||
toDate: '',
|
||||
})
|
||||
const { pagination, setPage, reset: resetPagination } = usePagination({ page: 1, perPage: 10 })
|
||||
|
||||
const { data, isLoading } = useAdminExamsListQuery(filters, pagination, {
|
||||
|
||||
Reference in New Issue
Block a user