diff --git a/web/src/app/app/crm/tasks/page.tsx b/web/src/app/app/crm/tasks/page.tsx index 3940b3117..0198be9dd 100644 --- a/web/src/app/app/crm/tasks/page.tsx +++ b/web/src/app/app/crm/tasks/page.tsx @@ -799,15 +799,22 @@ function TaskTypeTag({ if (!type) { return compact ? null : —; } - const color = taskTypeColor(type, types); + // Render the type as a colour-tinted chip (faint background in the type's + // colour + a solid dot + text in the colour) so the colour is unmistakable, + // not a single 8px dot. Done tasks fade to grey. Colours are DB-enforced hex. + const color = done ? "#94a3b8" : taskTypeColor(type, types); return ( - + {type} ); @@ -1044,12 +1051,14 @@ function TypeFacet({ closeOnSelect={false} icon={ } > - {t.name} + + {t.name} + )) )} diff --git a/web/src/components/app/crm/taskTypes.tsx b/web/src/components/app/crm/taskTypes.tsx index 73dabe93d..2e0afe9e4 100644 --- a/web/src/components/app/crm/taskTypes.tsx +++ b/web/src/components/app/crm/taskTypes.tsx @@ -18,5 +18,13 @@ export function taskTypeColor( types: { name: string; color: string }[], ): string { if (!name) return "#94a3b8"; - return types.find((t) => t.name === name)?.color ?? "#94a3b8"; + const key = name.trim().toLowerCase(); + const found = types.find((t) => t.name.trim().toLowerCase() === key)?.color; + if (found) return found; + // No matching type (renamed/removed, or a case/whitespace mismatch between the + // task's stored type string and the type list): hash the name into the palette + // so it still gets a stable, DISTINCT colour instead of one grey for everything. + let h = 0; + for (let i = 0; i < key.length; i++) h = (h * 31 + key.charCodeAt(i)) >>> 0; + return TASK_TYPE_COLORS[h % TASK_TYPE_COLORS.length]; }