sposchedule

Форк
1
/
TeachersView.vue 
201 строка · 5.7 Кб
1
<script setup lang="ts">
2
  import { ref } from 'vue';
3
  import DataTable from 'primevue/datatable';
4
  import Column from 'primevue/column';
5
  import InputText from 'primevue/inputtext';
6
  import MultiSelect from 'primevue/multiselect';
7
  import Button from 'primevue/button';
8
  import { useDateFormat } from '@vueuse/core';
9
  import { useToast } from 'primevue/usetoast';
10
  import {
11
    useTeachersQuery,
12
    useDestroyTeacher,
13
    useStoreTeacher,
14
    useUpdateTeacher,
15
  } from '../../queries/teachers';
16
  import { useSubjectsQuery } from '../../queries/subjects';
17
  import Chip from 'primevue/chip';
18
  import { FilterMatchMode } from '@primevue/core/api';
19

20
  const { data: teachers } = useTeachersQuery();
21

22
  const toast = useToast();
23

24
  const newTeacherName = ref('');
25

26
  const newTeacherError = ref(false);
27

28
  const editingRows = ref([]);
29
  const selectedTeachers = ref([]);
30

31
  const { mutateAsync: updateTeacher, isPending: isUpdated } =
32
    useUpdateTeacher();
33

34
  const onRowEditSave = async event => {
35
    let { newData } = event;
36
    try {
37
      await updateTeacher({ id: newData.id, body: newData });
38
    } catch (e) {
39
      toast.add({
40
        severity: 'error',
41
        summary: 'Ошибка',
42
        detail: e?.response.data.message,
43
        life: 3000,
44
        closable: true,
45
      });
46
      return;
47
    }
48
  };
49

50
  const { mutateAsync: destroyTeacher, isPending: isDestroyed } =
51
    useDestroyTeacher();
52
  const deleteTeachers = async () => {
53
    if (!selectedTeachers.value.length) return;
54

55
    for (let i = 0; i < selectedTeachers.value.length; i++) {
56
      try {
57
        await destroyTeacher(selectedTeachers.value[i].id);
58
      } catch (e) {
59
        toast.add({
60
          severity: 'error',
61
          summary: 'Ошибка',
62
          detail: e?.response.data.message,
63
          life: 3000,
64
          closable: true,
65
        });
66
        return;
67
      }
68
    }
69
    selectedTeachers.value = [];
70
  };
71

72
  const { mutateAsync: storeTeacher, isPending: isStored } = useStoreTeacher();
73
  const addTeacher = async () => {
74
    try {
75
      await storeTeacher({
76
        name: newTeacherName.value,
77
      });
78
    } catch (e) {
79
      newTeacherError.value = true;
80
      toast.add({
81
        severity: 'error',
82
        summary: 'Ошибка',
83
        detail: e?.response.data.message,
84
        life: 3000,
85
        closable: true,
86
      });
87
      newTeacherName.value = '';
88
      return;
89
    }
90
    newTeacherError.value = false;
91
    newTeacherName.value = '';
92
  };
93

94
  const { data: subjects } = useSubjectsQuery();
95

96
  const filters = ref({
97
    global: { value: null, matchMode: FilterMatchMode.CONTAINS },
98
    name: { value: null, matchMode: FilterMatchMode.STARTS_WITH },
99
  });
100
</script>
101

102
<template>
103
  <div class="flex flex-col gap-4">
104
    <div class="flex flex-wrap justify-between items-baseline">
105
      <h1 class="text-2xl">Преподаватели</h1>
106
    </div>
107
    <div class="">
108
      <form
109
        class="flex flex-wrap items-center gap-4 p-4 rounded-lg bg-surface-100 dark:bg-surface-800"
110
      >
111
        <InputText
112
          v-model="newTeacherName"
113
          :invalid="newTeacherError"
114
          placeholder="ФИО"
115
          class="w-full md:w-60"
116
        />
117

118
        <Button
119
          type="submit"
120
          :disabled="!newTeacherName"
121
          @click.prevent="addTeacher"
122
        >
123
          Добавить преподавателя
124
        </Button>
125
      </form>
126
    </div>
127
    <div class="">
128
      <DataTable
129
        v-model:filters="filters"
130
        v-model:selection="selectedTeachers"
131
        v-model:editing-rows="editingRows"
132
        paginator
133
        :rows="10"
134
        :loading="isUpdated || isDestroyed || isStored"
135
        :value="teachers"
136
        edit-mode="row"
137
        data-key="id"
138
        :pt="{
139
          table: { style: 'min-width: 50rem' },
140
        }"
141
        @row-edit-save="onRowEditSave"
142
      >
143
        <template #header>
144
          <div class="flex justify-between flex-wrap gap-2">
145
            <Button
146
              severity="danger"
147
              :disabled="!selectedTeachers.length || !teachers.length"
148
              type="button"
149
              icon="pi pi-trash"
150
              label="Удалить"
151
              outlined
152
              @click="deleteTeachers"
153
            />
154
            <InputText v-model="filters['global'].value" placeholder="Поиск" />
155
          </div>
156
        </template>
157
        <Column selection-mode="multiple" header-style="width: 3rem" />
158

159
        <Column field="name" header="ФИО">
160
          <template #editor="{ data, field }">
161
            <InputText v-model="data[field]" class="w-full" />
162
          </template>
163
        </Column>
164
        <Column field="subjects" header="Предметы">
165
          <template #body="slotProps">
166
            <div class="flex gap-2 flex-wrap">
167
              <Chip
168
                v-for="subject in slotProps.data.subjects"
169
                :label="subject.name"
170
              />
171
            </div>
172
          </template>
173
          <template #editor="{ data, field }">
174
            <MultiSelect
175
              v-model="data.subjects"
176
              display="chip"
177
              :options="subjects"
178
              option-label="name"
179
              filter
180
              placeholder="Выберите предметы"
181
              :max-selected-labels="3"
182
              class="w-48"
183
            />
184
            <!-- <InputText class="w-full" v-model="data[field]" /> -->
185
          </template>
186
        </Column>
187

188
        <Column field="updated_at" header="Дата изменения" style="width: 20%">
189
          <template #body="slotProps">
190
            {{ useDateFormat(slotProps.data.updated_at, 'DD.MM.YY HH:mm:ss') }}
191
          </template>
192
        </Column>
193
        <Column
194
          :row-editor="true"
195
          style="width: 10%; min-width: 8rem"
196
          body-style="text-align:center"
197
        />
198
      </DataTable>
199
    </div>
200
  </div>
201
</template>
202

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.