@devalok/shilp-sutra-karm 0.18.0 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/components/admin/admin-dashboard.md +215 -0
- package/docs/components/admin/admin-types.md +167 -0
- package/docs/components/admin/admin-utils.md +165 -0
- package/docs/components/admin/break-admin.md +167 -0
- package/docs/components/board/board-column.md +35 -0
- package/docs/components/board/board-provider.md +73 -0
- package/docs/components/board/board-toolbar.md +36 -0
- package/docs/components/board/board-types.md +62 -0
- package/docs/components/board/bulk-action-bar.md +38 -0
- package/docs/components/board/column-empty.md +33 -0
- package/docs/components/board/column-header.md +36 -0
- package/docs/components/board/kanban-board.md +53 -0
- package/docs/components/board/task-card.md +58 -0
- package/docs/components/board/task-context-menu.md +36 -0
- package/docs/components/chat/chat-input.md +37 -0
- package/docs/components/chat/chat-panel.md +58 -0
- package/docs/components/chat/conversation-list.md +47 -0
- package/docs/components/chat/message-list.md +44 -0
- package/docs/components/chat/streaming-text.md +29 -0
- package/docs/components/client/accent-provider.md +29 -0
- package/docs/components/client/client-portal-header.md +40 -0
- package/docs/components/client/project-card.md +39 -0
- package/docs/components/dashboard/attendance-cta.md +47 -0
- package/docs/components/dashboard/daily-brief.md +45 -0
- package/docs/components/dashboard/scratchpad-widget.md +52 -0
- package/docs/components/dashboard/sidebar-scratchpad.md +39 -0
- package/docs/components/other/karm-command-registry.md +61 -0
- package/docs/components/other/page-skeletons.md +52 -0
- package/docs/components/tasks/activity-tab.md +41 -0
- package/docs/components/tasks/conversation-tab.md +52 -0
- package/docs/components/tasks/files-tab.md +51 -0
- package/docs/components/tasks/review-tab.md +49 -0
- package/docs/components/tasks/subtasks-tab.md +56 -0
- package/docs/components/tasks/task-detail-panel.md +103 -0
- package/docs/components/tasks/task-properties.md +79 -0
- package/package.json +4 -2
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# ChatPanel
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm/chat
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: chat
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
isOpen: boolean (REQUIRED)
|
|
9
|
+
onOpenChange: (open: boolean) => void (REQUIRED)
|
|
10
|
+
messages: ChatMessage[] (REQUIRED)
|
|
11
|
+
conversations: Conversation[] (REQUIRED)
|
|
12
|
+
agents: Agent[] (default: DEFAULT_AGENTS — Devadoot, Prahari, Sutradhar, Sahayak, Vidwan, Sanchalak, Dwar-Palak)
|
|
13
|
+
selectedAgentId: string (default: "devadoot")
|
|
14
|
+
activeConversationId: string | null
|
|
15
|
+
isStreaming: boolean (default: false)
|
|
16
|
+
streamingText: string (default: "")
|
|
17
|
+
isLoadingMessages: boolean (default: false)
|
|
18
|
+
isLoadingConversations: boolean (default: false)
|
|
19
|
+
onSendMessage: (message: string) => void (REQUIRED)
|
|
20
|
+
onCancelStream: () => void
|
|
21
|
+
onSelectAgent: (agentId: string) => void
|
|
22
|
+
onStartNewChat: () => void
|
|
23
|
+
onSelectConversation: (id: string) => void
|
|
24
|
+
onArchiveConversation: (id: string) => void
|
|
25
|
+
onDeleteConversation: (id: string) => void
|
|
26
|
+
className: string
|
|
27
|
+
|
|
28
|
+
## Related Types
|
|
29
|
+
Agent: { id: string; name: string; desc: string }
|
|
30
|
+
ChatMessage: { id: string; role: "USER" | "ASSISTANT" | "SYSTEM"; content: string }
|
|
31
|
+
Conversation: { id: string; title: string | null; updatedAt: string }
|
|
32
|
+
|
|
33
|
+
## Defaults
|
|
34
|
+
agents=DEFAULT_AGENTS, selectedAgentId="devadoot", isStreaming=false, streamingText="", isLoadingMessages=false, isLoadingConversations=false
|
|
35
|
+
|
|
36
|
+
## Example
|
|
37
|
+
```jsx
|
|
38
|
+
<ChatPanel
|
|
39
|
+
isOpen={chatOpen}
|
|
40
|
+
onOpenChange={setChatOpen}
|
|
41
|
+
messages={messages}
|
|
42
|
+
conversations={conversations}
|
|
43
|
+
selectedAgentId="devadoot"
|
|
44
|
+
onSendMessage={(msg) => sendMessage(msg)}
|
|
45
|
+
onSelectConversation={(id) => loadConversation(id)}
|
|
46
|
+
/>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Gotchas
|
|
50
|
+
- Renders inside a Sheet (right side panel), capped at 480px max-width
|
|
51
|
+
- Toggles between MessageList (chat view) and ConversationList (history view) internally
|
|
52
|
+
- The Agent type is exported from this module — use it for custom agent arrays
|
|
53
|
+
- ChatMessage and Conversation types are re-exported from message-list and conversation-list respectively
|
|
54
|
+
- Extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> — children are not accepted
|
|
55
|
+
|
|
56
|
+
## Changes
|
|
57
|
+
### v0.18.0
|
|
58
|
+
- **Added** Initial release
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# ConversationList
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm/chat
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: chat
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
conversations: Conversation[] (REQUIRED)
|
|
9
|
+
activeConversationId: string | null
|
|
10
|
+
isLoading: boolean (default: false)
|
|
11
|
+
onSelect: (id: string) => void (REQUIRED)
|
|
12
|
+
onNewChat: () => void (REQUIRED)
|
|
13
|
+
onArchive: (id: string) => void
|
|
14
|
+
onDelete: (id: string) => void
|
|
15
|
+
className: string
|
|
16
|
+
|
|
17
|
+
## Related Types
|
|
18
|
+
Conversation: { id: string; title: string | null; updatedAt: string }
|
|
19
|
+
|
|
20
|
+
## Defaults
|
|
21
|
+
isLoading=false
|
|
22
|
+
|
|
23
|
+
## Example
|
|
24
|
+
```jsx
|
|
25
|
+
<ConversationList
|
|
26
|
+
conversations={conversations}
|
|
27
|
+
activeConversationId={currentConvoId}
|
|
28
|
+
onSelect={(id) => loadConversation(id)}
|
|
29
|
+
onNewChat={() => startNewChat()}
|
|
30
|
+
onArchive={(id) => archiveConversation(id)}
|
|
31
|
+
onDelete={(id) => deleteConversation(id)}
|
|
32
|
+
/>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Gotchas
|
|
36
|
+
- Extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect'> — the native onSelect is replaced
|
|
37
|
+
- Archive and delete buttons appear on hover for each conversation row
|
|
38
|
+
- If onArchive or onDelete are not provided, the corresponding action buttons are hidden
|
|
39
|
+
- Conversations with null title display as "Untitled conversation"
|
|
40
|
+
- updatedAt is formatted using formatRelativeTime (e.g., "2 hours ago")
|
|
41
|
+
- The active conversation is highlighted with bg-surface-2
|
|
42
|
+
- Shows a loading spinner when isLoading=true
|
|
43
|
+
- Shows "No conversations yet" empty state when the array is empty
|
|
44
|
+
|
|
45
|
+
## Changes
|
|
46
|
+
### v0.18.0
|
|
47
|
+
- **Added** Initial release
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# MessageList
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm/chat
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: chat
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
messages: ChatMessage[] (REQUIRED)
|
|
9
|
+
isStreaming: boolean (default: false)
|
|
10
|
+
streamingText: string (default: "")
|
|
11
|
+
isLoadingMessages: boolean (default: false)
|
|
12
|
+
emptyTitle: string (default: "Karm AI")
|
|
13
|
+
emptyDescription: string (default: "Ask me about tasks, projects, attendance, or anything else.")
|
|
14
|
+
className: string
|
|
15
|
+
|
|
16
|
+
## Related Types
|
|
17
|
+
ChatMessage: { id: string; role: "USER" | "ASSISTANT" | "SYSTEM"; content: string }
|
|
18
|
+
|
|
19
|
+
## Defaults
|
|
20
|
+
isStreaming=false, streamingText="", isLoadingMessages=false, emptyTitle="Karm AI", emptyDescription="Ask me about tasks, projects, attendance, or anything else."
|
|
21
|
+
|
|
22
|
+
## Example
|
|
23
|
+
```jsx
|
|
24
|
+
<MessageList
|
|
25
|
+
messages={messages}
|
|
26
|
+
isStreaming={isStreaming}
|
|
27
|
+
streamingText={currentStreamText}
|
|
28
|
+
isLoadingMessages={loading}
|
|
29
|
+
/>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Gotchas
|
|
33
|
+
- Auto-scrolls to bottom when messages or streamingText change
|
|
34
|
+
- Three message roles render differently: USER (right-aligned, accent bubble), ASSISTANT (left-aligned, markdown-rendered), SYSTEM (centered, error-styled)
|
|
35
|
+
- When isStreaming=true and streamingText is non-empty, renders a StreamingText component below the message list
|
|
36
|
+
- When isStreaming=true and streamingText is empty, shows animated bouncing dots
|
|
37
|
+
- ASSISTANT messages are rendered with ReactMarkdown — supports markdown formatting
|
|
38
|
+
- Shows a loading spinner when isLoadingMessages=true
|
|
39
|
+
- Shows an empty state with robot icon when no messages and not streaming
|
|
40
|
+
- Uses framer-motion AnimatePresence for enter/exit animations
|
|
41
|
+
|
|
42
|
+
## Changes
|
|
43
|
+
### v0.18.0
|
|
44
|
+
- **Added** Initial release
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# StreamingText
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm/chat
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: chat
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
text: string (REQUIRED)
|
|
9
|
+
isComplete: boolean (default: false)
|
|
10
|
+
className: string
|
|
11
|
+
|
|
12
|
+
## Defaults
|
|
13
|
+
isComplete=false
|
|
14
|
+
|
|
15
|
+
## Example
|
|
16
|
+
```jsx
|
|
17
|
+
<StreamingText text={partialResponse} isComplete={!isStreaming} />
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Gotchas
|
|
21
|
+
- Shows a pulsing cursor block after the text while isComplete=false
|
|
22
|
+
- When isComplete=true, the cursor disappears and the full text is announced to screen readers via aria-live="polite"
|
|
23
|
+
- While streaming (isComplete=false), aria-live is set to "off" to avoid flooding screen readers
|
|
24
|
+
- Text is rendered with ReactMarkdown — supports markdown formatting
|
|
25
|
+
- Extends React.HTMLAttributes<HTMLDivElement>
|
|
26
|
+
|
|
27
|
+
## Changes
|
|
28
|
+
### v0.18.0
|
|
29
|
+
- **Added** Initial release
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# AccentProvider
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm/client
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: client
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
accentCss: string | null (default: undefined)
|
|
9
|
+
|
|
10
|
+
## Defaults
|
|
11
|
+
(no visual defaults — renders nothing)
|
|
12
|
+
|
|
13
|
+
## Example
|
|
14
|
+
```jsx
|
|
15
|
+
<AccentProvider accentCss="--color-accent: #d33163; --color-accent-light: #f7e9e9;" />
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Gotchas
|
|
19
|
+
- Renders null — this is a headless component with no visual output
|
|
20
|
+
- Does NOT accept children — it is not a wrapper/provider component in the React context sense
|
|
21
|
+
- Injects CSS custom properties directly onto document.documentElement via useEffect
|
|
22
|
+
- Properties are cleaned up (removed) when the component unmounts or when accentCss changes
|
|
23
|
+
- Pass a semicolon-separated CSS custom property string (e.g., "--color-accent: #d33163; --color-accent-light: #f7e9e9;")
|
|
24
|
+
- If accentCss is null or undefined, no properties are applied
|
|
25
|
+
- Does NOT extend React.HTMLAttributes — only accepts the accentCss prop
|
|
26
|
+
|
|
27
|
+
## Changes
|
|
28
|
+
### v0.18.0
|
|
29
|
+
- **Added** Initial release
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# ClientPortalHeader
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm/client
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: client
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
orgName: string (REQUIRED)
|
|
9
|
+
orgLogo: string | null
|
|
10
|
+
userName: string (REQUIRED)
|
|
11
|
+
userAvatar: string | null
|
|
12
|
+
children: ReactNode
|
|
13
|
+
className: string
|
|
14
|
+
|
|
15
|
+
## Defaults
|
|
16
|
+
(no prop defaults)
|
|
17
|
+
|
|
18
|
+
## Example
|
|
19
|
+
```jsx
|
|
20
|
+
<ClientPortalHeader
|
|
21
|
+
orgName="Acme Corp"
|
|
22
|
+
orgLogo="/logos/acme.png"
|
|
23
|
+
userName="Jane Doe"
|
|
24
|
+
userAvatar="/avatars/jane.jpg"
|
|
25
|
+
>
|
|
26
|
+
<Button variant="ghost" size="sm">Settings</Button>
|
|
27
|
+
</ClientPortalHeader>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Gotchas
|
|
31
|
+
- Renders a <header> element — extends React.HTMLAttributes<HTMLElement>
|
|
32
|
+
- If orgLogo is null/undefined, shows a fallback with the first two initials of orgName on an accent background
|
|
33
|
+
- If userAvatar is null/undefined, shows an Avatar fallback with the first two initials of userName
|
|
34
|
+
- children are rendered between the org branding (left) and user avatar (right) — use this slot for action buttons or navigation
|
|
35
|
+
- The user's full name is hidden on small screens (shown only on sm: and above)
|
|
36
|
+
- Fixed height of h-ds-lg with bottom border
|
|
37
|
+
|
|
38
|
+
## Changes
|
|
39
|
+
### v0.18.0
|
|
40
|
+
- **Added** Initial release
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# ProjectCard
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm/client
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: client
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
name: string (REQUIRED)
|
|
9
|
+
description: string | null
|
|
10
|
+
status: "active" | "completed" | "paused" (REQUIRED)
|
|
11
|
+
taskCount: number (default: 0)
|
|
12
|
+
completedTasks: number (default: 0)
|
|
13
|
+
className: string
|
|
14
|
+
|
|
15
|
+
## Defaults
|
|
16
|
+
taskCount=0, completedTasks=0
|
|
17
|
+
|
|
18
|
+
## Example
|
|
19
|
+
```jsx
|
|
20
|
+
<ProjectCard
|
|
21
|
+
name="Website Redesign"
|
|
22
|
+
description="Complete overhaul of the marketing site"
|
|
23
|
+
status="active"
|
|
24
|
+
taskCount={24}
|
|
25
|
+
completedTasks={18}
|
|
26
|
+
/>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Gotchas
|
|
30
|
+
- Status maps to Badge colors: active=success, completed=info, paused=warning
|
|
31
|
+
- Progress bar shows completedTasks/taskCount as a percentage (rounded)
|
|
32
|
+
- If taskCount is 0, progress is 0% regardless of completedTasks
|
|
33
|
+
- Description is clamped to 2 lines with line-clamp-2
|
|
34
|
+
- Has cursor-pointer and hover shadow — attach onClick via spread props for navigation
|
|
35
|
+
- Extends React.HTMLAttributes<HTMLDivElement>
|
|
36
|
+
|
|
37
|
+
## Changes
|
|
38
|
+
### v0.18.0
|
|
39
|
+
- **Added** Initial release
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# AttendanceCTA
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm/dashboard
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: dashboard
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
userName: string (REQUIRED)
|
|
9
|
+
attendance: AttendanceData | null (REQUIRED)
|
|
10
|
+
canMarkAttendance: boolean (REQUIRED)
|
|
11
|
+
onMarkAttendance: () => void
|
|
12
|
+
isSubmitting: boolean (default: false)
|
|
13
|
+
formatTime: (timeStr: string) => string (default: IST toLocaleTimeString)
|
|
14
|
+
className: string
|
|
15
|
+
|
|
16
|
+
## Related Types
|
|
17
|
+
AttendanceData: { attendance: { id: string; status: string; timeIn: string | null; timeOut: string | null }; breakReason: string | null }
|
|
18
|
+
|
|
19
|
+
## Defaults
|
|
20
|
+
isSubmitting=false, formatTime=defaultFormatTime (IST, 12-hour)
|
|
21
|
+
|
|
22
|
+
## Example
|
|
23
|
+
```jsx
|
|
24
|
+
<AttendanceCTA
|
|
25
|
+
userName="Mudit Sharma"
|
|
26
|
+
attendance={attendanceData}
|
|
27
|
+
canMarkAttendance={true}
|
|
28
|
+
onMarkAttendance={() => markAttendance()}
|
|
29
|
+
isSubmitting={isMarking}
|
|
30
|
+
/>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Gotchas
|
|
34
|
+
- Renders four different states based on attendance data:
|
|
35
|
+
1. **Unmarked + canMark**: Large greeting card with gradient background and "Mark Attendance" button
|
|
36
|
+
2. **Marked (PRESENT)**: Compact strip showing check-in time in a success badge
|
|
37
|
+
3. **On Break (BREAK)**: Compact strip with warning badge showing break reason
|
|
38
|
+
4. **Unmarked + cannot mark**: Compact strip with "Attendance window closed" message
|
|
39
|
+
- Greeting is time-based: "Good morning" (before 12), "Good afternoon" (12-17), "Good evening" (after 17)
|
|
40
|
+
- Only the first name (split on space) is displayed in the greeting
|
|
41
|
+
- Date is formatted in en-IN locale with IST timezone
|
|
42
|
+
- The default formatTime uses en-IN locale with IST timezone and 12-hour format
|
|
43
|
+
- Extends React.HTMLAttributes<HTMLDivElement>
|
|
44
|
+
|
|
45
|
+
## Changes
|
|
46
|
+
### v0.18.0
|
|
47
|
+
- **Added** Initial release
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# DailyBrief
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm/dashboard
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: dashboard
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
data: BriefData | null (REQUIRED)
|
|
9
|
+
loading: boolean (default: false)
|
|
10
|
+
onRefresh: () => void
|
|
11
|
+
unavailable: boolean (default: false)
|
|
12
|
+
collapsible: boolean (default: true)
|
|
13
|
+
defaultCollapsed: boolean (default: false)
|
|
14
|
+
title: string (default: "Morning Brief")
|
|
15
|
+
className: string
|
|
16
|
+
|
|
17
|
+
## Related Types
|
|
18
|
+
BriefData: { brief: string[]; generatedAt: string }
|
|
19
|
+
|
|
20
|
+
## Defaults
|
|
21
|
+
loading=false, unavailable=false, collapsible=true, defaultCollapsed=false, title="Morning Brief"
|
|
22
|
+
|
|
23
|
+
## Example
|
|
24
|
+
```jsx
|
|
25
|
+
<DailyBrief
|
|
26
|
+
data={{ brief: ["3 tasks due today", "Team standup at 10am"], generatedAt: new Date().toISOString() }}
|
|
27
|
+
onRefresh={() => refetchBrief()}
|
|
28
|
+
loading={isRefreshing}
|
|
29
|
+
/>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Gotchas
|
|
33
|
+
- Returns null if data is null or data.brief is empty (and not loading/unavailable)
|
|
34
|
+
- When loading=true and data is null, shows a shimmer skeleton placeholder
|
|
35
|
+
- When unavailable=true, shows a minimal "AI brief unavailable" strip
|
|
36
|
+
- Each brief item is rendered with ReactMarkdown — supports inline markdown (bold, code, links)
|
|
37
|
+
- Brief items get rotating colored dots (amber, teal, cyan, accent)
|
|
38
|
+
- Shows "Generated X ago" timestamp using formatRelativeTime
|
|
39
|
+
- The refresh button only appears when onRefresh is provided; it spins while loading=true
|
|
40
|
+
- Collapse/expand uses framer-motion AnimatePresence for smooth height animation
|
|
41
|
+
- Extends React.HTMLAttributes<HTMLDivElement>
|
|
42
|
+
|
|
43
|
+
## Changes
|
|
44
|
+
### v0.18.0
|
|
45
|
+
- **Added** Initial release
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# ScratchpadWidget
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm/dashboard
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: dashboard
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
items: ScratchpadItem[] (REQUIRED)
|
|
9
|
+
maxItems: number (default: 5)
|
|
10
|
+
onToggle: (id: string, done: boolean) => void (REQUIRED)
|
|
11
|
+
onAdd: (text: string) => void (REQUIRED)
|
|
12
|
+
onDelete: (id: string) => void (REQUIRED)
|
|
13
|
+
title: string (default: "My Scratchpad")
|
|
14
|
+
resetLabel: string
|
|
15
|
+
emptyText: string (default: "Nothing here yet. Add a task!")
|
|
16
|
+
emptyIcon: React.ComponentType<{ className?: string }>
|
|
17
|
+
loading: boolean (default: false)
|
|
18
|
+
className: string
|
|
19
|
+
|
|
20
|
+
## Related Types
|
|
21
|
+
ScratchpadItem: { id: string; text: string; done: boolean }
|
|
22
|
+
|
|
23
|
+
## Defaults
|
|
24
|
+
maxItems=5, title="My Scratchpad", emptyText="Nothing here yet. Add a task!", loading=false
|
|
25
|
+
|
|
26
|
+
## Example
|
|
27
|
+
```jsx
|
|
28
|
+
<ScratchpadWidget
|
|
29
|
+
items={scratchpadItems}
|
|
30
|
+
onToggle={(id, done) => toggleItem(id, done)}
|
|
31
|
+
onAdd={(text) => addItem(text)}
|
|
32
|
+
onDelete={(id) => deleteItem(id)}
|
|
33
|
+
maxItems={5}
|
|
34
|
+
/>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Gotchas
|
|
38
|
+
- Extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> — the native title attribute is replaced by the title prop
|
|
39
|
+
- The "Add a task" input appears only when items.length < maxItems
|
|
40
|
+
- After adding an item, the input stays open for rapid entry; press Escape to close
|
|
41
|
+
- Enter submits the new item; Escape cancels the add flow
|
|
42
|
+
- Blurring the input with empty text closes the add flow
|
|
43
|
+
- Shows a progress ring in the header displaying items.length / maxItems with accent/success color
|
|
44
|
+
- When all items are done, the progress ring pulses with a scale animation
|
|
45
|
+
- Each item has a delete button that appears on hover
|
|
46
|
+
- resetLabel renders as footer text below the item list (e.g., "Resets daily at midnight")
|
|
47
|
+
- When loading=true, shows a shimmer skeleton placeholder
|
|
48
|
+
- Uses framer-motion AnimatePresence for item enter/exit animations
|
|
49
|
+
|
|
50
|
+
## Changes
|
|
51
|
+
### v0.18.0
|
|
52
|
+
- **Added** Initial release
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# SidebarScratchpad
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm/dashboard
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: dashboard
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
items: ScratchpadItem[] (REQUIRED)
|
|
9
|
+
onToggle: (id: string, done: boolean) => void (REQUIRED)
|
|
10
|
+
defaultOpen: boolean (default: true)
|
|
11
|
+
badgeCount: number
|
|
12
|
+
className: string
|
|
13
|
+
|
|
14
|
+
## Related Types
|
|
15
|
+
ScratchpadItem: { id: string; text: string; done: boolean } (imported from scratchpad-widget)
|
|
16
|
+
|
|
17
|
+
## Defaults
|
|
18
|
+
defaultOpen=true
|
|
19
|
+
|
|
20
|
+
## Example
|
|
21
|
+
```jsx
|
|
22
|
+
<SidebarScratchpad
|
|
23
|
+
items={scratchpadItems}
|
|
24
|
+
onToggle={(id, done) => toggleItem(id, done)}
|
|
25
|
+
badgeCount={scratchpadItems.filter(i => !i.done).length}
|
|
26
|
+
/>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Gotchas
|
|
30
|
+
- This is a compact, read-only version of ScratchpadWidget designed for the app sidebar
|
|
31
|
+
- Does NOT support adding or deleting items — use ScratchpadWidget for full CRUD
|
|
32
|
+
- Only supports toggling done state via checkboxes
|
|
33
|
+
- Collapsible header with chevron; uses CSS grid-rows transition for smooth collapse
|
|
34
|
+
- badgeCount shows a pill badge in the header; hidden when badgeCount is undefined, null, or 0
|
|
35
|
+
- Extends React.HTMLAttributes<HTMLDivElement>
|
|
36
|
+
|
|
37
|
+
## Changes
|
|
38
|
+
### v0.18.0
|
|
39
|
+
- **Added** Initial release
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# karmCommandRegistry
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm (top-level export)
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: shell
|
|
6
|
+
|
|
7
|
+
Pre-configured command registry for the Karm app's AppCommandPalette. Contains all page routes and admin routes.
|
|
8
|
+
|
|
9
|
+
Exports: karmCommandRegistry
|
|
10
|
+
|
|
11
|
+
## Type
|
|
12
|
+
```ts
|
|
13
|
+
const karmCommandRegistry: CommandRegistry
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Where `CommandRegistry` is `{ pages: CommandPageItem[], adminPages: CommandPageItem[] }` from `@devalok/shilp-sutra/shell/command-registry`.
|
|
17
|
+
|
|
18
|
+
## Pages
|
|
19
|
+
| id | label | path | keywords |
|
|
20
|
+
|----|-------|------|----------|
|
|
21
|
+
| nav-dashboard | Dashboard | / | home |
|
|
22
|
+
| nav-attendance | Attendance | /attendance | clock, time |
|
|
23
|
+
| nav-breaks | Breaks | /breaks | leave, vacation |
|
|
24
|
+
| nav-projects | Projects | /projects | board, kanban |
|
|
25
|
+
| nav-my-tasks | My Tasks | /my-tasks | todo |
|
|
26
|
+
| nav-devsabha | Devsabha | /devsabha | standup, meeting |
|
|
27
|
+
| nav-adjustments | Adjustments | /adjustments | corrections |
|
|
28
|
+
| nav-profile | Profile | /profile | account, settings |
|
|
29
|
+
|
|
30
|
+
## Admin Pages
|
|
31
|
+
| id | label | path | keywords |
|
|
32
|
+
|----|-------|------|----------|
|
|
33
|
+
| nav-admin-dashboard | Admin Dashboard | /admin | admin, overview |
|
|
34
|
+
| nav-admin-breaks | Manage Breaks | /admin/breaks | admin, leave |
|
|
35
|
+
| nav-admin-attendance | Manage Attendance | /admin/attendance | admin, time |
|
|
36
|
+
| nav-admin-lokwasi | Lokwasi | /admin/lokwasi | admin, onboarding |
|
|
37
|
+
| nav-admin-onboarding | Onboarding | /admin/onboarding | admin, new hire |
|
|
38
|
+
| nav-admin-config | System Config | /admin/system-config | admin, settings, configuration |
|
|
39
|
+
|
|
40
|
+
## Example
|
|
41
|
+
```jsx
|
|
42
|
+
import { CommandRegistryProvider } from '@devalok/shilp-sutra/shell/command-registry'
|
|
43
|
+
import { karmCommandRegistry } from '@devalok/shilp-sutra-karm'
|
|
44
|
+
|
|
45
|
+
<CommandRegistryProvider registry={karmCommandRegistry}>
|
|
46
|
+
<AppCommandPalette
|
|
47
|
+
user={user}
|
|
48
|
+
onNavigate={(path) => router.push(path)}
|
|
49
|
+
/>
|
|
50
|
+
</CommandRegistryProvider>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Gotchas
|
|
54
|
+
- Each entry includes a Tabler icon (e.g. `IconLayoutDashboard`, `IconUmbrella`) — these are bundled, not tree-shaken
|
|
55
|
+
- The registry is a plain object, not a React component — pass it to `CommandRegistryProvider`
|
|
56
|
+
- Admin pages are only shown in the command palette when the user has admin role (handled by AppCommandPalette)
|
|
57
|
+
- To add new routes, extend the registry object in your app rather than modifying this export
|
|
58
|
+
|
|
59
|
+
## Changes
|
|
60
|
+
### v0.9.0
|
|
61
|
+
- **Added** Initial release with 8 pages and 6 admin pages
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Page Skeletons (Karm)
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: other
|
|
6
|
+
|
|
7
|
+
Domain-specific loading skeleton components for Karm pages.
|
|
8
|
+
|
|
9
|
+
Exports: DevsabhaSkeleton, BandwidthSkeleton
|
|
10
|
+
|
|
11
|
+
## Props
|
|
12
|
+
|
|
13
|
+
### DevsabhaSkeleton
|
|
14
|
+
...HTMLDivElement attributes (className, etc.)
|
|
15
|
+
|
|
16
|
+
Renders a 5-section skeleton grid mimicking the Devsabha (standup) page layout:
|
|
17
|
+
1. Main large card (lg:col-span-2) with 4 rows
|
|
18
|
+
2. Side card with 3 avatar rows
|
|
19
|
+
3. Full-width card (lg:col-span-3) with 3 sub-cards
|
|
20
|
+
4. Stats row (lg:col-span-2) with 4 stat blocks
|
|
21
|
+
5. Timeline card with 3 entries
|
|
22
|
+
|
|
23
|
+
### BandwidthSkeleton
|
|
24
|
+
...HTMLDivElement attributes (className, etc.)
|
|
25
|
+
|
|
26
|
+
Renders a skeleton mimicking the Bandwidth page layout:
|
|
27
|
+
1. 3 summary cards (sm:grid-cols-3) with progress bars
|
|
28
|
+
2. Table with 5-column header and 6 rows with avatar + name
|
|
29
|
+
|
|
30
|
+
## Defaults
|
|
31
|
+
None
|
|
32
|
+
|
|
33
|
+
## Example
|
|
34
|
+
```jsx
|
|
35
|
+
import { DevsabhaSkeleton, BandwidthSkeleton } from '@devalok/shilp-sutra-karm'
|
|
36
|
+
|
|
37
|
+
// Use while data loads
|
|
38
|
+
if (isLoading) return <DevsabhaSkeleton />
|
|
39
|
+
|
|
40
|
+
// Bandwidth page loading
|
|
41
|
+
if (isLoading) return <BandwidthSkeleton className="p-6" />
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Gotchas
|
|
45
|
+
- These are top-level exports from the karm package, not from the admin sub-path
|
|
46
|
+
- Both use the core `Skeleton` component internally
|
|
47
|
+
- Layout uses `gap-ds-06` spacing and `rounded-ds-xl` border radius
|
|
48
|
+
- Pass `className` to customize outer container styles
|
|
49
|
+
|
|
50
|
+
## Changes
|
|
51
|
+
### v0.9.0
|
|
52
|
+
- **Added** Initial release
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# ActivityTab
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm/tasks
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: tasks
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
activities: AuditLogEntry[] (REQUIRED)
|
|
9
|
+
...HTMLAttributes<HTMLDivElement>
|
|
10
|
+
|
|
11
|
+
## AuditLogEntry Shape
|
|
12
|
+
id: string
|
|
13
|
+
timestamp: string
|
|
14
|
+
actorType: 'USER' | 'CLIENT' | 'SYSTEM' | 'AGENT'
|
|
15
|
+
actorId: string | null
|
|
16
|
+
action: string
|
|
17
|
+
entityType: string
|
|
18
|
+
entityId: string
|
|
19
|
+
projectId: string | null
|
|
20
|
+
metadata: Record<string, unknown> | null
|
|
21
|
+
|
|
22
|
+
## Supported Actions
|
|
23
|
+
task.created, task.updated, task.moved, task.assigned, task.unassigned,
|
|
24
|
+
task.commented, task.file_uploaded, task.review_requested, task.review_completed,
|
|
25
|
+
task.visibility_changed, task.priority_changed, task.labels_changed, task.due_date_changed
|
|
26
|
+
|
|
27
|
+
## Example
|
|
28
|
+
```jsx
|
|
29
|
+
<ActivityTab activities={auditLogEntries} />
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Gotchas
|
|
33
|
+
- Renders a vertical timeline with colored dots and icons per action type.
|
|
34
|
+
- Unknown actions fall back to a generic icon and use entry.action as the description.
|
|
35
|
+
- Actor name is derived from metadata.actorName, falling back to "System", "AI Agent", or "Someone".
|
|
36
|
+
- Empty state uses EmptyState component: "No activity yet".
|
|
37
|
+
- Forwards ref to outer div.
|
|
38
|
+
|
|
39
|
+
## Changes
|
|
40
|
+
### v0.18.0
|
|
41
|
+
- **Added** Initial release
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# ConversationTab
|
|
2
|
+
|
|
3
|
+
- Import: @devalok/shilp-sutra-karm/tasks
|
|
4
|
+
- Server-safe: No
|
|
5
|
+
- Category: tasks
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
comments: Comment[] (REQUIRED)
|
|
9
|
+
taskVisibility: 'INTERNAL' | 'EVERYONE' (REQUIRED)
|
|
10
|
+
onPostComment: (content: string, authorType: 'INTERNAL' | 'CLIENT') => void (REQUIRED)
|
|
11
|
+
clientMode: boolean (default: false)
|
|
12
|
+
richText: boolean (default: true) — enable built-in RichTextEditor/Viewer
|
|
13
|
+
renderEditor: (props: { content: string; onChange: (content: string) => void; placeholder: string }) => ReactNode
|
|
14
|
+
renderViewer: (props: { content: string; className?: string }) => ReactNode
|
|
15
|
+
...HTMLAttributes<HTMLDivElement>
|
|
16
|
+
|
|
17
|
+
## Comment Shape
|
|
18
|
+
id: string
|
|
19
|
+
taskId: string
|
|
20
|
+
authorType: 'INTERNAL' | 'CLIENT'
|
|
21
|
+
authorId: string
|
|
22
|
+
content: string
|
|
23
|
+
createdAt: string
|
|
24
|
+
updatedAt: string
|
|
25
|
+
internalAuthor: { id: string; name: string; email?: string; image?: string | null } | null (optional)
|
|
26
|
+
clientAuthor: { id: string; name: string; email: string } | null (optional)
|
|
27
|
+
|
|
28
|
+
## Defaults
|
|
29
|
+
clientMode=false, richText=true
|
|
30
|
+
|
|
31
|
+
## Example
|
|
32
|
+
```jsx
|
|
33
|
+
<ConversationTab
|
|
34
|
+
comments={task.comments}
|
|
35
|
+
taskVisibility={task.visibility}
|
|
36
|
+
onPostComment={(content, type) => postComment(content, type)}
|
|
37
|
+
/>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Gotchas
|
|
41
|
+
- In clientMode, comments are posted with authorType='CLIENT'. In staff mode, authorType='INTERNAL'.
|
|
42
|
+
- When taskVisibility='EVERYONE' and not clientMode, a warning is shown: "Comments may be seen by external users."
|
|
43
|
+
- In clientMode, staff comments show a "Team" badge. In staff mode, client comments show a "Client" badge.
|
|
44
|
+
- Editor resolution priority: renderEditor prop > built-in RichTextEditor (when richText=true) > plain textarea fallback.
|
|
45
|
+
- Viewer resolution priority: renderViewer prop > built-in RichTextViewer (when richText=true) > plain text with HTML stripped.
|
|
46
|
+
- Auto-scrolls to bottom when new comments arrive.
|
|
47
|
+
- Empty state: "No comments yet".
|
|
48
|
+
- Forwards ref to outer div.
|
|
49
|
+
|
|
50
|
+
## Changes
|
|
51
|
+
### v0.18.0
|
|
52
|
+
- **Added** Initial release
|