fix: relation chips now show type color instead of default blue (#68)

* fix: relation chips now display correct type color instead of default blue

Root cause: resolveRef matched entries by path/filename only, while
wiki-links used findEntryByTarget (title, filename, aliases). When a
wikilink target used the note title (differing from filename), resolveRef
failed → null type → default blue.

Changes:
- resolveRef now calls findEntryByTarget first (title/alias match)
- Default color for typeless notes changed from blue to neutral grey
- TypeSelector passes custom color key from Type entries
- DynamicPropertiesPanel refactored to reduce cyclomatic complexity

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* design: add before/after visual for relations type color fix

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add task completion summary

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Luca Rossi
2026-02-25 15:02:33 +01:00
committed by GitHub
parent f84ebbe662
commit ca9ede51d5
8 changed files with 144 additions and 36 deletions

View File

@@ -0,0 +1,49 @@
import { describe, it, expect } from 'vitest'
import { getTypeColor, getTypeLightColor } from './typeColors'
describe('getTypeColor', () => {
it('returns hardcoded color for known types', () => {
expect(getTypeColor('Project')).toBe('var(--accent-red)')
expect(getTypeColor('Person')).toBe('var(--accent-yellow)')
expect(getTypeColor('Topic')).toBe('var(--accent-green)')
})
it('returns neutral muted color for null type', () => {
expect(getTypeColor(null)).toBe('var(--muted-foreground)')
})
it('returns neutral muted color for unknown type without custom key', () => {
expect(getTypeColor('UnknownType')).toBe('var(--muted-foreground)')
})
it('uses custom color key over hardcoded map', () => {
expect(getTypeColor('Project', 'green')).toBe('var(--accent-green)')
})
it('uses custom color key for unknown type', () => {
expect(getTypeColor('Recipe', 'orange')).toBe('var(--accent-orange)')
})
it('ignores invalid custom color key', () => {
expect(getTypeColor('Project', 'invalid')).toBe('var(--accent-red)')
})
})
describe('getTypeLightColor', () => {
it('returns hardcoded light color for known types', () => {
expect(getTypeLightColor('Project')).toBe('var(--accent-red-light)')
expect(getTypeLightColor('Person')).toBe('var(--accent-yellow-light)')
})
it('returns neutral muted light color for null type', () => {
expect(getTypeLightColor(null)).toBe('var(--muted)')
})
it('returns neutral muted light color for unknown type without custom key', () => {
expect(getTypeLightColor('UnknownType')).toBe('var(--muted)')
})
it('uses custom color key for light variant', () => {
expect(getTypeLightColor('Recipe', 'purple')).toBe('var(--accent-purple-light)')
})
})

View File

@@ -25,8 +25,8 @@ const TYPE_LIGHT_COLOR_MAP: Record<string, string> = {
Type: 'var(--accent-blue-light)',
}
const DEFAULT_COLOR = 'var(--accent-blue)'
const DEFAULT_LIGHT_COLOR = 'var(--accent-blue-light)'
const DEFAULT_COLOR = 'var(--muted-foreground)'
const DEFAULT_LIGHT_COLOR = 'var(--muted)'
/** Color key → CSS variable mapping for the design system accent palette */
export const ACCENT_COLORS: { key: string; label: string; css: string; cssLight: string }[] = [

View File

@@ -87,8 +87,8 @@ describe('lookupColorForEntry', () => {
expect(lookupColorForEntry(allEntries, recipeEntry)).toBe('var(--accent-orange)')
})
it('returns default blue for an entry with no type', () => {
expect(lookupColorForEntry(allEntries, untypedEntry)).toBe('var(--accent-blue)')
it('returns neutral color for an entry with no type', () => {
expect(lookupColorForEntry(allEntries, untypedEntry)).toBe('var(--muted-foreground)')
})
})
@@ -105,16 +105,16 @@ describe('resolveWikilinkColor', () => {
expect(result.color).toBe('var(--text-muted)')
})
it('returns default color for an untyped note', () => {
it('returns neutral color for an untyped note', () => {
const result = resolveWikilinkColor(allEntries, 'Random Thought')
expect(result.isBroken).toBe(false)
expect(result.color).toBe('var(--accent-blue)')
expect(result.color).toBe('var(--muted-foreground)')
})
it('returns default color when entries list is empty', () => {
it('returns neutral color when entries list is empty', () => {
const result = resolveWikilinkColor([], 'Anything')
expect(result.isBroken).toBe(false)
expect(result.color).toBe('var(--accent-blue)')
expect(result.color).toBe('var(--muted-foreground)')
})
it('resolves alias-based wikilink target', () => {