feat: добавил типы мероприятий

This commit is contained in:
2026-05-12 00:13:19 +03:00
parent 34334e9a8d
commit fb8ad6de7c
3 changed files with 55 additions and 7 deletions
+11 -1
View File
@@ -144,11 +144,21 @@ export interface SyncStatusDto {
lastResult?: SyncResultDto | null
}
export type ApiScheduleTypeId =
| 'MID_CHECK'
| 'CONS'
| 'LAB'
| 'LECT'
| 'SEMI'
| 'EVENT_OTHER'
| 'SELF'
| 'CUR_CHECK'
export interface SyncScheduleRequest {
specialtyCode?: string | null
timeMin?: string | null
timeMax?: string | null
typeId?: string | null
typeId?: ApiScheduleTypeId[] | null
}
export interface SyncResultDto {
+43 -5
View File
@@ -1,7 +1,15 @@
<script setup lang="ts">
import { computed, inject, onMounted, ref } from 'vue'
import { coursesApi, lecturesApi, locationsApi, syncApi, tagsApi } from '@/api'
import type { CourseDto, LectureDto, LocationDto, SyncResultDto, SyncStatusDto, TagDto } from '@/api/types'
import type {
ApiScheduleTypeId,
CourseDto,
LectureDto,
LocationDto,
SyncResultDto,
SyncStatusDto,
TagDto,
} from '@/api/types'
import GlassCard from '@/components/ui/GlassCard.vue'
import DataTable from '@/components/ui/DataTable.vue'
import EmptyState from '@/components/ui/EmptyState.vue'
@@ -25,6 +33,16 @@ const syncError = ref('')
const syncStatus = ref<SyncStatusDto | null>(null)
const syncResult = ref<SyncResultDto | null>(null)
const addToast = inject('addToast') as ((message: string, type?: 'success' | 'error' | 'info') => void) | undefined
const scheduleTypeOptions: Array<{ id: ApiScheduleTypeId; label: string }> = [
{ id: 'MID_CHECK', label: 'Аттестация' },
{ id: 'CONS', label: 'Консультация' },
{ id: 'LAB', label: 'Лабораторное занятие' },
{ id: 'LECT', label: 'Лекционное занятие' },
{ id: 'SEMI', label: 'Практическое занятие' },
{ id: 'EVENT_OTHER', label: 'Прочее' },
{ id: 'SELF', label: 'Самостоятельная работа' },
{ id: 'CUR_CHECK', label: 'Текущий контроль' },
]
function toInputDateTime(date: Date) {
const offsetMs = date.getTimezoneOffset() * 60000
@@ -37,7 +55,7 @@ inTwoWeeks.setDate(inTwoWeeks.getDate() + 14)
const syncForm = ref({
specialtyCode: '',
typeId: '',
typeIds: [] as ApiScheduleTypeId[],
timeMin: toInputDateTime(now),
timeMax: toInputDateTime(inTwoWeeks),
})
@@ -168,7 +186,7 @@ async function runScheduleSync() {
try {
syncResult.value = await syncApi.schedule({
specialtyCode: syncForm.value.specialtyCode.trim() || null,
typeId: syncForm.value.typeId.trim() || null,
typeId: syncForm.value.typeIds.length ? syncForm.value.typeIds : null,
timeMin: syncForm.value.timeMin ? new Date(syncForm.value.timeMin).toISOString() : null,
timeMax: syncForm.value.timeMax ? new Date(syncForm.value.timeMax).toISOString() : null,
})
@@ -248,8 +266,13 @@ onMounted(() => {
<input v-model="syncForm.timeMax" class="glass-input" type="datetime-local" />
<label>Код специальности</label>
<input v-model="syncForm.specialtyCode" class="glass-input" placeholder="Например, 09.03.04" />
<label>Тип занятия</label>
<input v-model="syncForm.typeId" class="glass-input" placeholder="Оставьте пустым для всех типов" />
<label>Типы пар</label>
<div class="type-grid">
<label v-for="type in scheduleTypeOptions" :key="type.id" class="type-option">
<input v-model="syncForm.typeIds" type="checkbox" :value="type.id" />
<span>{{ type.label }}</span>
</label>
</div>
<div v-if="visibleSyncResult" class="sync-result">
Создано: {{ visibleSyncResult.created }},
@@ -285,6 +308,21 @@ onMounted(() => {
.form { display: flex; flex-direction: column; gap: 10px; }
.form label { font-size: 12px; font-weight: 600; color: var(--color-text-secondary); }
.form-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.type-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 8px; }
.type-option {
min-height: 38px;
display: flex;
align-items: center;
gap: 8px;
padding: 8px 10px;
border: 1px solid var(--color-border-glass);
border-radius: var(--radius-sm);
background: rgba(255,255,255,0.72);
color: var(--color-text-primary);
cursor: pointer;
}
.type-option input { flex: 0 0 auto; }
.type-option span { font-size: 13px; line-height: 1.2; }
.sync-meta { font-size: 12px; color: var(--color-text-secondary); margin-top: 4px; }
.sync-result { font-size: 13px; color: var(--color-text-secondary); }
.sync-error { font-size: 13px; color: var(--color-error); }