1
0

Правки

This commit is contained in:
2026-01-21 12:46:43 +07:00
parent 8e3cd770df
commit 88189a3f04
6 changed files with 88 additions and 30 deletions

View File

@@ -434,8 +434,6 @@ defineExpose({ saveTask, deleteTask, archiveTask })
-ms-overflow-style: none;
/* Предотвращаем системные жесты (pull-to-refresh) */
overscroll-behavior: contain;
/* Разрешаем и горизонтальный и вертикальный pan - колонки внутри скроллятся вертикально */
touch-action: pan-x pan-y;
}
.board.mobile .columns::-webkit-scrollbar {

View File

@@ -142,17 +142,33 @@ const handleDrop = (e) => {
.column.mobile {
width: 100vw;
min-width: 100vw;
height: 100%;
max-height: none;
/* Высота по контенту, но ограничена доступным пространством */
height: fit-content;
max-height: calc(100% - 20px);
padding: 0 16px;
scroll-snap-align: start;
scroll-snap-stop: always;
flex-shrink: 0;
/* Вертикальный скролл на уровне колонки - убирает вложенные скроллы */
overflow-y: auto;
overflow-x: hidden;
}
/* Скрываем скроллбар в мобильной версии - пользователи свайпают пальцем */
.column.mobile {
scrollbar-width: none;
-ms-overflow-style: none;
}
.column.mobile::-webkit-scrollbar {
display: none;
}
.column.mobile .cards {
max-height: calc(100vh - 320px);
overflow-y: auto;
/* Без overflow - скролл на уровне .column */
max-height: none;
overflow: visible;
min-height: auto;
}
.column.drag-over .cards {

View File

@@ -772,6 +772,13 @@ const handleSave = async () => {
try {
if (isNew.value) {
// Проверяем что у всех колонок есть имена
const emptyColumnNew = form.value.columns.find(c => !c.name_columns?.trim())
if (emptyColumnNew) {
toast.error('Укажите название для всех колонок')
return
}
// Проверяем что у всех отделов есть имена (для нового проекта тоже)
const emptyDeptNew = form.value.departments.find(d => !d.name_departments?.trim())
if (emptyDeptNew) {
@@ -826,6 +833,13 @@ const handleSave = async () => {
}
} else {
// Редактирование проекта
// Проверяем что у всех колонок есть имена
const emptyColumn = form.value.columns.find(c => !c.name_columns?.trim())
if (emptyColumn) {
toast.error('Укажите название для всех колонок')
return
}
// Обновляем название если изменилось
if (form.value.name !== initialForm.value.name) {
await store.updateProject(props.project.id, form.value.name)

View File

@@ -9,6 +9,7 @@
:alt="selectedOption.label"
class="option-avatar"
>
<span v-else-if="selectedOption?.label" class="avatar-placeholder">{{ selectedOption.label[0] }}</span>
<span v-else-if="!selectedOption" class="no-selection-icon"></span>
<span class="selected-label">{{ selectedOption?.label || placeholder }}</span>
</slot>
@@ -54,6 +55,7 @@
:alt="option.label"
class="option-avatar"
>
<span v-else class="avatar-placeholder">{{ (option.label || '?')[0] }}</span>
<div class="option-content">
<span class="option-label">{{ option.label }}</span>
<a
@@ -127,13 +129,14 @@
:class="{ active: isActive(option.value) }"
@click="selectOption(option.value)"
>
<img
v-if="option.avatar"
:src="option.avatar"
:alt="option.label"
class="option-avatar"
>
<div class="option-content">
<img
v-if="option.avatar"
:src="option.avatar"
:alt="option.label"
class="option-avatar"
>
<span v-else class="avatar-placeholder">{{ (option.label || '?')[0] }}</span>
<div class="option-content">
<span class="option-label">{{ option.label }}</span>
<a
v-if="option.subtitle"
@@ -498,11 +501,31 @@ onUpdated(refreshIcons)
.option-avatar {
width: 28px;
height: 28px;
border-radius: 6px;
border-radius: 50%;
object-fit: cover;
flex-shrink: 0;
}
.avatar-placeholder {
width: 28px;
height: 28px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 600;
color: var(--text-secondary);
background: rgba(255, 255, 255, 0.1);
text-transform: uppercase;
flex-shrink: 0;
}
.dropdown-item.active .avatar-placeholder {
background: rgba(0, 0, 0, 0.15);
color: #000;
}
.option-content {
display: flex;
flex-direction: column;
@@ -703,7 +726,14 @@ onUpdated(refreshIcons)
.mobile-select-item .option-avatar {
width: 40px;
height: 40px;
border-radius: 10px;
border-radius: 50%;
}
.mobile-select-item .avatar-placeholder {
width: 40px;
height: 40px;
border-radius: 50%;
font-size: 16px;
}
.mobile-select-item .option-content {

View File

@@ -316,15 +316,15 @@ onUnmounted(() => {
border-top: 1px solid rgba(255, 255, 255, 0.06);
}
/* Transition — плавное появление */
/* Transition — выезд справа для десктопа */
.panel-enter-active,
.panel-leave-active {
transition: opacity 0.2s ease;
transition: opacity 0.25s ease;
}
.panel-enter-active .panel,
.panel-leave-active .panel {
transition: opacity 0.2s ease, transform 0.2s ease;
transition: transform 0.25s ease;
}
.panel-enter-from,
@@ -334,8 +334,7 @@ onUnmounted(() => {
.panel-enter-from .panel,
.panel-leave-to .panel {
opacity: 0;
transform: scale(0.98);
transform: translateX(100%);
}
/* На мобильных убираем transform из анимации - он ломает layout в iOS PWA */