Improve task board filters and sidebar scrolling

This commit is contained in:
lizerk 2026-08-26 11:40:31 +03:00
parent 22ecf40d46
commit 207022fd55
5 changed files with 70 additions and 63 deletions

View File

@ -1329,7 +1329,8 @@ html[data-bs-theme="dark"] .tasks-board-group-header-sticky {
}
.tasks-board-scroll,
.tasks-column-scroll {
.tasks-column-scroll,
.app-list-scroll {
scrollbar-width: thin;
scrollbar-color: color-mix(in srgb, var(--accent-primary) 42%, var(--surface-tertiary)) transparent;
-ms-overflow-style: auto;
@ -1343,7 +1344,8 @@ html[data-bs-theme="dark"] .tasks-board-group-header-sticky {
}
.tasks-board-scroll::-webkit-scrollbar,
.tasks-column-scroll::-webkit-scrollbar {
.tasks-column-scroll::-webkit-scrollbar,
.app-list-scroll::-webkit-scrollbar {
display: block;
}
@ -1352,23 +1354,27 @@ html[data-bs-theme="dark"] .tasks-board-group-header-sticky {
height: 8px;
}
.tasks-column-scroll::-webkit-scrollbar {
.tasks-column-scroll::-webkit-scrollbar,
.app-list-scroll::-webkit-scrollbar {
width: 6px;
}
.tasks-board-scroll::-webkit-scrollbar-track,
.tasks-column-scroll::-webkit-scrollbar-track {
.tasks-column-scroll::-webkit-scrollbar-track,
.app-list-scroll::-webkit-scrollbar-track {
background: transparent;
}
.tasks-board-scroll::-webkit-scrollbar-thumb,
.tasks-column-scroll::-webkit-scrollbar-thumb {
.tasks-column-scroll::-webkit-scrollbar-thumb,
.app-list-scroll::-webkit-scrollbar-thumb {
border-radius: 9999px;
background: color-mix(in srgb, var(--accent-primary) 38%, var(--surface-tertiary));
}
.tasks-board-scroll::-webkit-scrollbar-thumb:hover,
.tasks-column-scroll::-webkit-scrollbar-thumb:hover {
.tasks-column-scroll::-webkit-scrollbar-thumb:hover,
.app-list-scroll::-webkit-scrollbar-thumb:hover {
background: var(--accent-primary);
}

View File

@ -7970,68 +7970,68 @@ function TasksPageContent() {
</label>
</div>
<HorizontalChipScroller
className="mt-4"
contentClassName="items-center"
ariaLabel="Фильтры доски задач"
>
<button
type="button"
onClick={() => setOnlyMine((current) => !current)}
className={`inline-flex items-center gap-1.5 rounded-full px-3 py-1.5 text-xs font-medium transition ${
onlyMine ? "app-pill-active" : "app-pill"
}`}
<div className="mt-4 flex min-w-0 items-start gap-2">
<HorizontalChipScroller
className="min-w-0 flex-1"
contentClassName="items-center"
ariaLabel="Фильтры доски задач"
>
<UserRound size={14} />
<span>Мои задачи</span>
<span className={`app-badge px-1.5 py-0.5 text-[10px] font-bold ${
onlyMine ? "app-pill-count-active" : "app-pill-count"
}`}>
{mineCount}
</span>
</button>
{onlyMine ? (
<button
type="button"
onClick={() => setOnlyMine(false)}
className="app-action-ghost inline-flex h-7 w-7 items-center justify-center rounded-full"
title="Сбросить фильтр"
aria-label="Сбросить фильтр моих задач"
onClick={() => setOnlyMine((current) => !current)}
className={`inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full px-3 py-1.5 text-xs font-medium transition ${
onlyMine ? "app-pill-active" : "app-pill"
}`}
>
<X size={13} />
<UserRound size={14} />
<span>Мои задачи</span>
<span className={`app-badge shrink-0 whitespace-nowrap px-1.5 py-0.5 text-[10px] font-bold ${
onlyMine ? "app-pill-count-active" : "app-pill-count"
}`}>
{mineCount}
</span>
</button>
{onlyMine ? (
<button
type="button"
onClick={() => setOnlyMine(false)}
className="app-action-ghost inline-flex h-7 w-7 shrink-0 items-center justify-center rounded-full"
title="Сбросить фильтр"
aria-label="Сбросить фильтр моих задач"
>
<X size={13} />
</button>
) : null}
<button
type="button"
onClick={() => setMobileColumnFiltersOpen(true)}
className={`inline-flex h-8 shrink-0 items-center justify-center rounded-full px-2.5 transition xl:hidden ${
selectedColumnTarget === "all" ? "app-pill" : "app-pill-active"
}`}
title="Фильтры колонок"
aria-label="Открыть фильтры колонок"
aria-expanded={mobileColumnFiltersOpen}
aria-haspopup="dialog"
>
<span className="flex -space-x-1" aria-hidden="true">
{topLevelColumns.slice(0, 6).map((column) => (
<span
key={column.id}
className="h-3 w-3 rounded-full border-2 border-[var(--surface-elevated)]"
style={{ backgroundColor: column.color || "#38bdf8" }}
/>
))}
</span>
</button>
) : null}
<button
type="button"
onClick={() => setMobileColumnFiltersOpen(true)}
className={`inline-flex h-8 items-center justify-center rounded-full px-2.5 transition xl:hidden ${
selectedColumnTarget === "all" ? "app-pill" : "app-pill-active"
}`}
title="Фильтры колонок"
aria-label="Открыть фильтры колонок"
aria-expanded={mobileColumnFiltersOpen}
aria-haspopup="dialog"
>
<span className="flex -space-x-1" aria-hidden="true">
{topLevelColumns.slice(0, 6).map((column) => (
<span
key={column.id}
className="h-3 w-3 rounded-full border-2 border-[var(--surface-elevated)]"
style={{ backgroundColor: column.color || "#38bdf8" }}
/>
))}
</span>
</button>
<div className="hidden xl:contents">
<button
type="button"
onClick={focusAllColumns}
className={`inline-flex items-center gap-1.5 rounded-full px-3 py-1.5 text-xs font-medium transition ${
className={`hidden shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full px-3 py-1.5 text-xs font-medium transition xl:inline-flex ${
selectedColumnTarget === "all" ? "app-pill-active" : "app-pill"
}`}
>
<span>Все</span>
<span className={`app-badge px-1.5 py-0.5 text-[10px] font-bold ${
<span className={`app-badge shrink-0 whitespace-nowrap px-1.5 py-0.5 text-[10px] font-bold ${
selectedColumnTarget === "all" ? "app-pill-count-active" : "app-pill-count"
}`}>
{filteredTasks.length}
@ -8044,7 +8044,7 @@ function TasksPageContent() {
key={column.id}
type="button"
onClick={() => focusColumn(column.id)}
className={`inline-flex max-w-48 items-center gap-1.5 rounded-full px-3 py-1.5 text-xs font-medium transition ${
className={`hidden max-w-48 shrink-0 items-center gap-1.5 whitespace-nowrap rounded-full px-3 py-1.5 text-xs font-medium transition xl:inline-flex ${
active ? "app-pill-active" : "app-pill"
}`}
>
@ -8053,7 +8053,7 @@ function TasksPageContent() {
style={{ backgroundColor: column.color || "#38bdf8" }}
/>
<span className="truncate">{column.name}</span>
<span className={`app-badge px-1.5 py-0.5 text-[10px] font-bold ${
<span className={`app-badge shrink-0 whitespace-nowrap px-1.5 py-0.5 text-[10px] font-bold ${
active ? "app-pill-count-active" : "app-pill-count"
}`}>
{columnCounts.get(column.id) || 0}
@ -8061,7 +8061,7 @@ function TasksPageContent() {
</button>
);
})}
</div>
</HorizontalChipScroller>
<button
type="button"
onClick={() => openCreateColumn()}
@ -8071,7 +8071,7 @@ function TasksPageContent() {
>
<Plus size={14} />
</button>
</HorizontalChipScroller>
</div>
{error ? (
<div className="app-feedback-danger mt-3 rounded-xl px-4 py-3 text-sm">

View File

@ -191,10 +191,10 @@ export default function MessagesChatListItem({
<>
<div
data-testid="messages-chat-list-item"
className={`relative w-full rounded-xl border text-left transition ${
className={`relative w-full rounded-lg text-left transition ${
active
? "app-selected"
: "border-transparent hover:border-[var(--border-subtle)] hover:bg-[var(--surface-secondary)]"
: "hover:bg-[var(--surface-secondary)]"
}`}
>
<Link href={`/messages/${chat.id}`} className="block w-full p-3 pr-10">

View File

@ -112,7 +112,7 @@ export default function MessagesFocusSidebar({
<MessagesChatListControls userId={user?.id} chatTypeCounts={chatTypeCounts} />
</div> : null}
<div className={`min-h-0 flex-1 space-y-2 overflow-y-auto overscroll-y-contain pb-4 ${sidebarCollapsed ? "px-2 pt-2" : "px-4"}`}>
<div className={`app-list-scroll min-h-0 flex-1 space-y-2 overflow-y-auto overscroll-y-contain pb-4 ${sidebarCollapsed ? "px-2 pt-2" : "px-4"}`}>
{loading ? (
<p className="app-text-muted px-3 py-6 text-center text-xs">Загрузка чатов...</p>
) : visibleChats.length === 0 ? (

View File

@ -853,6 +853,7 @@ export default function TaskBoardNavigator({
/>
</label>
<button
id="task-boards-filter-trigger"
type="button"
onClick={() => setFiltersOpen((current) => !current)}
className={`relative inline-flex shrink-0 items-center justify-center rounded-lg p-2.5 transition ${