This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
// 负责人头像: 姓氏首字 + 按名字稳定的底色; 未指派灰色圆点
|
||||||
|
const COLORS = ['#1677ff', '#00b578', '#ff8f1f', '#a855f7', '#14b8a6', '#f43f9e', '#5a6a80']
|
||||||
|
|
||||||
|
export default function Avatar({ name, size = 18 }) {
|
||||||
|
const seed = [...(name || '')].reduce((a, ch) => a + ch.charCodeAt(0), 0)
|
||||||
|
const color = COLORS[seed % COLORS.length]
|
||||||
|
return (
|
||||||
|
<span
|
||||||
|
className="avatar"
|
||||||
|
title={name || '未指派'}
|
||||||
|
style={{
|
||||||
|
width: size,
|
||||||
|
height: size,
|
||||||
|
fontSize: Math.round(size * 0.52),
|
||||||
|
background: name ? color : '#eef1f5',
|
||||||
|
color: name ? '#fff' : '#b6bcc4',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{name ? name.slice(0, 1) : '·'}
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import StatusDot from './StatusDot.jsx'
|
import StatusDot from './StatusDot.jsx'
|
||||||
|
import Avatar from './Avatar.jsx'
|
||||||
import { kindColor } from '../../pages/task/kind.js'
|
import { kindColor } from '../../pages/task/kind.js'
|
||||||
|
|
||||||
// 看板卡片 (T-UI-02): 轻量化
|
// 看板卡片 (T-UI-02): 轻量化
|
||||||
@@ -50,9 +51,7 @@ export default function TaskCard({
|
|||||||
<span className="kind-tag" style={{ background: kindColor(task.kind) }}>{task.kind}</span>
|
<span className="kind-tag" style={{ background: kindColor(task.kind) }}>{task.kind}</span>
|
||||||
)}
|
)}
|
||||||
<span style={{ display: 'flex', alignItems: 'center', gap: 6, marginLeft: 'auto', minWidth: 0, justifyContent: 'flex-end' }}>
|
<span style={{ display: 'flex', alignItems: 'center', gap: 6, marginLeft: 'auto', minWidth: 0, justifyContent: 'flex-end' }}>
|
||||||
<span className={`bassignee${task.assignee ? '' : ' none'}`}>
|
<Avatar name={task.assignee?.name} size={18} />
|
||||||
{task.assignee?.name || '未指派'}
|
|
||||||
</span>
|
|
||||||
{task.members?.length > 0 && (
|
{task.members?.length > 0 && (
|
||||||
<span className="bmembers">+ {task.members.map((m) => m.name).join('、')}</span>
|
<span className="bmembers">+ {task.members.map((m) => m.name).join('、')}</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import StatusDot from './StatusDot.jsx'
|
import StatusDot from './StatusDot.jsx'
|
||||||
|
import Avatar from './Avatar.jsx'
|
||||||
import { kindColor } from '../../pages/task/kind.js'
|
import { kindColor } from '../../pages/task/kind.js'
|
||||||
|
|
||||||
const statusLabel = (s) => (s === 'done' ? '完成' : s === 'doing' ? '执行中' : '未开始')
|
const statusLabel = (s) => (s === 'done' ? '完成' : s === 'doing' ? '执行中' : '未开始')
|
||||||
@@ -65,9 +66,7 @@ export default function TaskRow({
|
|||||||
onClick={(e) => { e.stopPropagation(); onMore?.(task) }}
|
onClick={(e) => { e.stopPropagation(); onMore?.(task) }}
|
||||||
onPointerDown={(e) => e.stopPropagation()}
|
onPointerDown={(e) => e.stopPropagation()}
|
||||||
>⋯</span>
|
>⋯</span>
|
||||||
<span className={`assignee${task.assignee ? '' : ' none'}`}>
|
<Avatar name={task.assignee?.name} size={20} />
|
||||||
{task.assignee?.name || '未指派'}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user