Skip to content

INDICATOR Extensions

INDICATOR extensions add visual badges, status markers, and quick-glance indicators to list items, cards, and entity displays.

  • Status indicators (active, urgent, blocked)
  • Notification badges (unread count)
  • Progress indicators
  • Warning/error markers
  • Quick-glance metrics
{
point: 'work-unit.indicators',
plugin: 'timer',
priority: 50,
match: {
businessType: ['SERVICE', 'PROJECT']
},
extension: {
type: ExtensionType.INDICATOR,
id: 'timer-status',
component: TimerIndicator,
position: 'end'
}
}
  • type: ExtensionType.INDICATOR
  • id: Unique identifier
  • component: Indicator component
  • position: 'start' | 'end' - Indicator placement
  • priority: Display order when multiple indicators
  • tooltip: Tooltip text
export function TimerIndicator({ item }: { item: any }) {
const [isRunning, setIsRunning] = useState(false);
useEffect(() => {
const checkTimer = () => {
const timers = getTimersFromStorage();
setIsRunning(!!timers[item.id]?.isRunning);
};
window.addEventListener('storage', checkTimer);
checkTimer();
return () => window.removeEventListener('storage', checkTimer);
}, [item.id]);
if (!isRunning) return null;
return (
<Badge color="green" variant="dot">
Timer Running
</Badge>
);
}
// Dot indicator
<Badge variant="dot" color="green">Active</Badge>
// Filled badge
<Badge color="error">Urgent</Badge>
// Count badge
<Badge color="blue">{unreadCount}</Badge>
// Icon badge
<Badge leftSection={<IconClock size={12} />}>
In Progress
</Badge>

Show indicators only when relevant:

export function UrgentIndicator({ item }: { item: any }) {
// Only show for urgent items
if (!item.isUrgent) return null;
return (
<Badge color="error" variant="filled">
Urgent
</Badge>
);
}
export function ProgressIndicator({ item }: { item: any }) {
const progress = item.completionPercentage || 0;
// Only show if in progress
if (progress === 0 || progress === 100) return null;
return (
<Badge color="blue">
{progress}% Complete
</Badge>
);
}
export function StatusIndicators({ item }: { item: any }) {
return (
<Group gap="xs">
{item.isBlocked && (
<Badge color="error">Blocked</Badge>
)}
{item.isOverdue && (
<Badge color="orange">Overdue</Badge>
)}
{item.hasUnreadComments && (
<Badge color="blue">{item.unreadCommentCount}</Badge>
)}
</Group>
);
}
export function DetailedIndicator({ item }: { item: any }) {
const status = getDetailedStatus(item);
return (
<Tooltip label={status.description}>
<Badge color={status.color}>
{status.label}
</Badge>
</Tooltip>
);
}
  • Return null when indicator shouldn’t display
  • Keep indicators concise (1-2 words)
  • Use consistent colors for similar states
  • Provide tooltips for complex indicators
  • Clean up event listeners in useEffect
  • green: Success, active, running
  • blue: Information, in progress
  • orange: Warning, attention needed
  • error: Urgent, blocked, failed
  • gray: Neutral, inactive