-
Notifications
You must be signed in to change notification settings - Fork 5
fix: kanban title fallback chain and board visual improvements #572
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -133,7 +133,7 @@ function SortableCard({ card, onCardClick, conditionalFormatting }: { card: Kanb | |||||||||||
| <div ref={setNodeRef} style={style} {...attributes} {...listeners} role="listitem" aria-label={card.title} | ||||||||||||
| onClick={() => onCardClick?.(card)} | ||||||||||||
| > | ||||||||||||
| <Card className="mb-2 cursor-grab active:cursor-grabbing border-border bg-card/60 hover:border-primary/40 hover:shadow-lg hover:shadow-primary/10 transition-all duration-300 group touch-manipulation" style={cardStyles}> | ||||||||||||
| <Card className="mb-2 cursor-grab active:cursor-grabbing border-border border-l-4 border-l-primary/40 bg-card/60 hover:border-primary/40 hover:shadow-lg hover:shadow-primary/10 transition-all duration-300 group touch-manipulation" style={cardStyles}> | ||||||||||||
| {card.coverImage && ( | ||||||||||||
| <div className="w-full h-32 overflow-hidden rounded-t-lg"> | ||||||||||||
| <img | ||||||||||||
|
|
@@ -260,14 +260,14 @@ function KanbanColumnView({ | |||||||||||
| column.className | ||||||||||||
| )} | ||||||||||||
| > | ||||||||||||
| <div className="p-3 sm:p-4 border-b border-border/50 bg-muted/20"> | ||||||||||||
| <div className="p-3 sm:p-4 border-b border-border/50 bg-muted/30 rounded-t-lg"> | ||||||||||||
| <div className="flex items-center justify-between"> | ||||||||||||
| <h3 id={`kanban-col-${column.id}`} className="font-mono text-xs sm:text-sm font-semibold tracking-wider text-primary/90 uppercase truncate">{column.title}</h3> | ||||||||||||
| <div className="flex items-center gap-2"> | ||||||||||||
| <span className="font-mono text-xs text-muted-foreground" aria-label={`${safeCards.length} cards${column.limit ? ` of ${column.limit} maximum` : ''}`}> | ||||||||||||
| <Badge variant="secondary" className="text-xs font-mono tabular-nums"> | ||||||||||||
| {safeCards.length} | ||||||||||||
| {column.limit && ` / ${column.limit}`} | ||||||||||||
| </span> | ||||||||||||
| </Badge> | ||||||||||||
| {isLimitExceeded && ( | ||||||||||||
| <Badge variant="destructive" className="text-xs"> | ||||||||||||
| Full | ||||||||||||
|
|
@@ -282,6 +282,11 @@ function KanbanColumnView({ | |||||||||||
| strategy={verticalListSortingStrategy} | ||||||||||||
| > | ||||||||||||
| <div className="space-y-2" role="list" aria-label={`${column.title} cards`}> | ||||||||||||
| {safeCards.length === 0 && ( | ||||||||||||
| <div className="flex flex-col items-center justify-center py-8 text-muted-foreground/50"> | ||||||||||||
|
||||||||||||
| <div className="flex flex-col items-center justify-center py-8 text-muted-foreground/50"> | |
| <div | |
| role="listitem" | |
| className="flex flex-col items-center justify-center py-8 text-muted-foreground/50" | |
| > |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,93 @@ | ||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||
| * ObjectUI | ||||||||||||||||||||||||||||||
| * Copyright (c) 2024-present ObjectStack Inc. | ||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||
| * This source code is licensed under the MIT license found in the | ||||||||||||||||||||||||||||||
| * LICENSE file in the root directory of this source tree. | ||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| import { describe, it, expect, vi } from 'vitest'; | ||||||||||||||||||||||||||||||
| import { renderHook } from '@testing-library/react'; | ||||||||||||||||||||||||||||||
| import { useMemo } from 'react'; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||
| * Tests for the title resolution fallback chain in ObjectKanban. | ||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||
|
Comment on lines
+9
to
+15
|
||||||||||||||||||||||||||||||
| import { describe, it, expect, vi } from 'vitest'; | |
| import { renderHook } from '@testing-library/react'; | |
| import { useMemo } from 'react'; | |
| /** | |
| * Tests for the title resolution fallback chain in ObjectKanban. | |
| * | |
| import { describe, it, expect } from 'vitest'; | |
| /** | |
| * Tests for the title resolution fallback chain in ObjectKanban. | |
| * | |
| * Tests for the title resolution fallback chain in ObjectKanban. | |
| * |
Copilot
AI
Feb 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The block comment claims the production title resolution order includes objectDef.titleFormat and objectDef.NAME_FIELD_KEY, but the resolveTitle helper below doesn’t implement or test those branches. Either update the comment to match what’s actually covered here, or extend the helper/tests to include the objectDef-based resolution to avoid misleading documentation.
| * The effectiveData logic tries fields in this order: | |
| * 1. Explicit cardTitle / titleField from schema | |
| * 2. objectDef.titleFormat (e.g. "{subject}") | |
| * 3. objectDef.NAME_FIELD_KEY | |
| * 4. Fallback chain: name → title → subject → label → display_name | |
| * 5. 'Untitled' | |
| * This helper covers the data-driven title resolution used by ObjectKanban | |
| * after any higher-level schema or object definition logic has been applied. | |
| * | |
| * The logic tested here tries fields in this order: | |
| * 1. Explicit cardTitle / titleField from schema | |
| * 2. Fallback chain: name → title → subject → label → display_name | |
| * 3. 'Untitled' |
Copilot
AI
Feb 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests re-implement the title resolution logic locally instead of exercising the actual ObjectKanban implementation. That means a future regression in ObjectKanban.tsx could still leave this test suite passing. Consider extracting the resolver (and TITLE_FALLBACK_FIELDS) into a shared exported utility that both ObjectKanban and this test import, or test effectiveData via rendering ObjectKanban with a minimal schema/dataSource setup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Swapping the card count from a
<span>with a descriptivearia-labelto a<Badge>drops the accessible context (screen readers will likely announce just the number). Add anaria-labelto the Badge (e.g., "N cards" / "N of limit maximum") or include visually-hidden text so the meaning is preserved.