- +
-

{{projectName}}

- +

{{ projectName }}

+
- - -
- +
+
+

Интервал выполнения

+ + - + +
+ + +
- stage.name.includes(this.search)); + return this.stages.filter(stage => + stage.name.includes(this.search) && + (!this.startDate || new Date(stage.startDate) >= new Date(this.startDate)) && + (!this.endDate || new Date(stage.endDate) <= new Date(this.endDate)) + ); }, }, methods: { @@ -89,7 +102,7 @@ export default { })); // console.log(this.stages); } catch (error) { - if(error.response.status === 401){ + if (error.response.status === 401) { this.$store.commit('removeUsers'); // Изменяем состояние clearAllCookies(); this.$router.push("/login"); @@ -104,6 +117,46 @@ export default { const year = date.getFullYear(); return `${year}-${month}-${day}`; }, + formatToDateTime(date) { + return `${date}T00:00:00`; + }, + async applyFilters() { + try { + const params = new URLSearchParams({ + }); + + if (this.endDate) { + params.append('end_date', this.formatToDateTime(this.endDate)); + } + if(this.startDate) { + params.append('start_date', this.formatToDateTime(this.startDate)); + } + if (this.stageName) { + params.append('name', this.stageName); + } + const response = await axios.get(`/api/projects/${getProjectId()}/get_stages/?${params.toString()}`); + this.stages = Object.values(response.data.stages).map(stage => ({ + name: stage.name, + startDate: this.formatDate(stage.start_date), + endDate: this.formatDate(stage.end_date), + stageId: stage.id, + })); + // console.log(this.stages); + } catch (error) { + if (error.response.status === 401) { + this.$store.commit('removeUsers'); // Изменяем состояние + clearAllCookies(); + this.$router.push("/login"); + } + console.error('Ошибка при загрузке Этапов:', error); + } + }, + resetFilters() { + this.startDate = ''; + this.endDate = ''; + this.selectedStatus = ''; + this.fetchStageData(); + }, }, beforeMount() { this.fetchStageData(); @@ -132,26 +185,63 @@ export default { .header-container { display: flex; - justify-content: space-between; /* Располагаем элементы на разных сторонах */ - align-items: center; /* Центрируем элементы по вертикали */ + align-items: center; /* Выравниваем элементы по вертикали */ margin-bottom: 16px; } .header-left { + margin-right: 20px; /* Добавляем отступ между заголовком и фильтрами */ +} + +.filter-container { display: flex; - flex-direction: column; + align-items: center; + gap: 20px; } -.header-right { +.date-filter, +.project-filter, +.status-filter { display: flex; align-items: center; + gap: 10px; +} + +.date-filter input { + margin-left: 5px; +} + +.project-filter label, +.status-filter label { + margin-right: 10px; } -.stages-container input { - padding: 12px; - border-radius: 4px; +.large-input { + padding: 10px; + margin-left: 5px; border: 1px solid #ccc; - margin-left: 8%; + border-radius: 5px; + font-size: 16px; +} + +input, +select { + padding: 5px; + border: 1px solid #ccc; + border-radius: 5px; +} + +button { + background-color: #6e6b93; + color: white; + padding: 8px 15px; + border: none; + border-radius: 5px; + cursor: pointer; +} + +button:hover { + background-color: #5c5583; } .add-stage-button { diff --git a/frontend/src/src/components/statics/StatisticsPage.vue b/frontend/src/src/components/statics/StatisticsPage.vue index a49674b..8a53660 100644 --- a/frontend/src/src/components/statics/StatisticsPage.vue +++ b/frontend/src/src/components/statics/StatisticsPage.vue @@ -65,6 +65,7 @@
+

{{ errorMessage }}