5.8.0: Окно переноса и логика next_show_at
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m22s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m22s
This commit is contained in:
@@ -319,8 +319,8 @@
|
||||
.task-postpone-modal {
|
||||
background: white;
|
||||
border-radius: 0.5rem;
|
||||
max-width: 400px;
|
||||
width: 90%;
|
||||
width: fit-content;
|
||||
max-width: 90%;
|
||||
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
@@ -491,6 +491,16 @@
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.5rem;
|
||||
overflow-x: auto;
|
||||
flex-wrap: nowrap;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.task-postpone-quick-buttons::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.task-postpone-quick-button {
|
||||
@@ -503,6 +513,8 @@
|
||||
background: white;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
flex-shrink: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.task-postpone-quick-button:hover:not(:disabled) {
|
||||
|
||||
@@ -508,6 +508,42 @@ function TaskList({ onNavigate, data, loading, backgroundLoading, error, onRetry
|
||||
}
|
||||
}
|
||||
|
||||
const handleWithoutDateClick = async () => {
|
||||
if (!selectedTaskForPostpone) return
|
||||
|
||||
setIsPostponing(true)
|
||||
try {
|
||||
const response = await authFetch(`${API_URL}/${selectedTaskForPostpone.id}/postpone`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ next_show_at: null }),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}))
|
||||
throw new Error(errorData.message || 'Ошибка при переносе задачи')
|
||||
}
|
||||
|
||||
if (onRefresh) {
|
||||
onRefresh()
|
||||
}
|
||||
|
||||
if (historyPushedForPostponeRef.current) {
|
||||
window.history.back()
|
||||
} else {
|
||||
setSelectedTaskForPostpone(null)
|
||||
setPostponeDate('')
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error postponing task:', err)
|
||||
setToast({ message: err.message || 'Ошибка при переносе задачи', type: 'error' })
|
||||
} finally {
|
||||
setIsPostponing(false)
|
||||
}
|
||||
}
|
||||
|
||||
const toggleCompletedExpanded = (projectName) => {
|
||||
setExpandedCompleted(prev => ({
|
||||
...prev,
|
||||
@@ -622,7 +658,8 @@ function TaskList({ onNavigate, data, loading, backgroundLoading, error, onRetry
|
||||
nextShowDate.setHours(0, 0, 0, 0)
|
||||
isCompleted = nextShowDate.getTime() > today.getTime()
|
||||
} else {
|
||||
isCompleted = false
|
||||
// Задачи без даты (next_show_at = null) идут в выполненные
|
||||
isCompleted = true
|
||||
}
|
||||
|
||||
groupKeys.forEach(groupKey => {
|
||||
@@ -670,10 +707,10 @@ function TaskList({ onNavigate, data, loading, backgroundLoading, error, onRetry
|
||||
if (!isInfiniteA && isInfiniteB) return 1
|
||||
if (isInfiniteA && isInfiniteB) return 0
|
||||
|
||||
// Для остальных: NULL значения идут первыми
|
||||
// Для остальных: NULL значения идут последними
|
||||
if (!a.next_show_at && !b.next_show_at) return 0
|
||||
if (!a.next_show_at) return -1
|
||||
if (!b.next_show_at) return 1
|
||||
if (!a.next_show_at) return 1
|
||||
if (!b.next_show_at) return -1
|
||||
|
||||
// Сравниваем даты
|
||||
const dateA = new Date(a.next_show_at).getTime()
|
||||
@@ -1182,6 +1219,15 @@ function TaskList({ onNavigate, data, loading, backgroundLoading, error, onRetry
|
||||
По плану
|
||||
</button>
|
||||
)}
|
||||
{selectedTaskForPostpone?.next_show_at && (
|
||||
<button
|
||||
onClick={handleWithoutDateClick}
|
||||
className="task-postpone-quick-button"
|
||||
disabled={isPostponing}
|
||||
>
|
||||
Без даты
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user