feat(ui): one CountBadge for all counters; counters on tab corners
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m30s

- CountBadge component (accent / muted, inline / corner, 99+, showZero);
  used in the nav bar, task list and list tabs, admin organizations and
  numeric badges of the mobile menu; old badge-count removed
- Counters sit on the top right corner of tabs; "Alle Aufgaben" gets one
  (desktop tab and mobile menu)
- Open/done task counters include tasks in shared lists, matching what
  "Alle Aufgaben" shows (nav counter was too low)
- Theme template derives --accent-dim/--accent-border from the accent
- Docs: ui-patterns counters section

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-10-28 22:54:15 +01:00
1 parent a354f3d008
commit a62b204e14
12 files changed
+167 -55

No files matched your search

+11 -6
View File
@@ -32,6 +32,7 @@ import { UnifiedShareModal } from '../../components/UnifiedShareModal';
import { TaskDetailModal } from './TaskDetailModal';
import { ManageColumnsModal, DEFAULT_KANBAN_COLUMNS } from './ManageColumnsModal';
import { AvatarStack, AvatarPerson } from '../../components/AvatarStack';
import { CountBadge } from '../../components/CountBadge';
import { useMobileActions } from '../../context/MobileActionContext';
interface TasksViewProps {
@@ -40,6 +41,7 @@ interface TasksViewProps {
onOpenDocument: (docId: string, blockId?: string) => void;
refreshTrigger?: number;
initialSelectedTaskId?: string | null;
openTasksCount?: number; // all open tasks incl. shared lists (same as the nav bar counter)
}
export const TasksView: React.FC<TasksViewProps> = ({
@@ -48,6 +50,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
onOpenDocument,
refreshTrigger = 0,
initialSelectedTaskId,
openTasksCount,
}) => {
const [viewMode, setViewMode] = useState<'list' | 'kanban'>('list');
const [filter, setFilter] = useState<'open' | 'done' | 'discarded'>('open');
@@ -1036,6 +1039,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
id: 'list-all',
label: 'Alle Aufgaben',
icon: <Layers className="w-4 h-4" />,
badge: openTasksCount || undefined,
active: selectedListId === 'all',
onClick: () => setSelectedListId('all'),
},
@@ -1086,6 +1090,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
safeDiscarded.length,
kanbanTasks.length,
safeTaskLists,
openTasksCount,
currentSelectedList,
isSelectedListReadOnly,
setPrimaryAction,
@@ -1368,17 +1373,18 @@ export const TasksView: React.FC<TasksViewProps> = ({
<div className="w-full space-y-3">
{/* Top Header: Task Lists Tabs & View Mode Switcher (Desktop) */}
<div className="hidden sm:flex flex-wrap items-center justify-between gap-2 border-b border-border pb-2 !mt-0">
{/* Task Lists selector tabs */}
<div className="flex flex-wrap items-center gap-1">
{/* Task Lists selector tabs (counters sit on the top right corner, hence the extra gap) */}
<div className="flex flex-wrap items-center gap-x-3 gap-y-3 pt-2">
<button
onClick={() => setSelectedListId('all')}
className={`h-8 px-3 text-xs font-medium border rounded-btn transition-colors ${
className={`relative h-8 px-3 text-xs font-medium border rounded-btn transition-colors ${
selectedListId === 'all'
? 'bg-panel border-accent text-main'
: 'bg-canvas border-border text-muted hover:text-main'
}`}
>
Alle Aufgaben
<CountBadge count={openTasksCount} position="corner" />
</button>
{safeTaskLists.map((tl) => (
@@ -1394,9 +1400,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
>
<span>{tl.icon}</span>
<span>{tl.title}</span>
{tl.tasksCount !== undefined && tl.tasksCount > 0 && (
<span className="ml-1 badge-count">{tl.tasksCount}</span>
)}
{(() => {
const isShared = (tl.shares && tl.shares.length > 0) || (tl.members && tl.members.length > 1);
if (!isShared) return null;
@@ -1418,6 +1422,7 @@ export const TasksView: React.FC<TasksViewProps> = ({
);
})()}
</button>
<CountBadge count={tl.tasksCount} position="corner" />
{selectedListId === tl.id && (
<button
onClick={() => handleDeleteTaskList(tl.id)}