ai-design-system 0.1.73 → 0.1.75
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/components/ai-elements/node.tsx +9 -9
- package/components/ai-elements/prompt-input.tsx +2 -2
- package/components/blocks/AIConversation/AIConversation.tsx +36 -3
- package/components/blocks/BmcCanvas/bmc-layout.ts +115 -0
- package/components/blocks/BmcCanvas/bmc-tooltips.ts +63 -0
- package/components/blocks/BmcCanvas/index.ts +3 -0
- package/components/blocks/BmcCanvas/interfaces.ts +58 -0
- package/components/blocks/WorkflowCanvas/WorkflowCanvas.tsx +1 -1
- package/components/blocks/index.ts +3 -0
- package/components/composites/AgentIndicator/AgentIndicator.tsx +1 -1
- package/components/composites/AuthCard/AuthCard.stories.tsx +65 -0
- package/components/composites/AuthCard/AuthCard.tsx +360 -0
- package/components/composites/AuthCard/index.ts +2 -0
- package/components/composites/SpatialContainerNode/SpatialContainerNode.tsx +84 -21
- package/components/composites/SpecialistMessage/SpecialistMessage.tsx +1 -1
- package/components/composites/SystemMessage/SystemMessage.stories.tsx +46 -0
- package/components/composites/SystemMessage/SystemMessage.tsx +54 -0
- package/components/composites/SystemMessage/index.ts +2 -0
- package/components/composites/ToolCallDisplay/ToolCallDisplay.tsx +1 -1
- package/components/composites/WorkflowToolbar/WorkflowToolbar.tsx +8 -9
- package/components/composites/WorkflowToolbar/interfaces.ts +1 -0
- package/components/composites/index.ts +8 -0
- package/components/features/AuthFeature/AuthFeature.behaviors.stories.tsx +80 -0
- package/components/features/AuthFeature/AuthFeature.mocks.ts +41 -0
- package/components/features/AuthFeature/AuthFeature.stories.tsx +102 -0
- package/components/features/AuthFeature/AuthFeature.tsx +186 -0
- package/components/features/AuthFeature/README.md +33 -0
- package/components/features/AuthFeature/index.ts +10 -0
- package/components/features/AuthFeature/useAuthFeature.d.ts +57 -0
- package/components/features/AuthFeature/useAuthFeature.mock.ts +113 -0
- package/components/features/ChatPanel/ChatPanel.tsx +18 -2
- package/components/features/ChatPanel/useChatPanel.d.ts +1 -1
- package/components/features/NodeEditor/NodeEditor.mocks.ts +51 -123
- package/components/features/NodeEditor/NodeEditor.stories.tsx +1 -1
- package/components/features/NodeEditor/NodeEditor.tsx +13 -6
- package/components/features/NodeEditor/useNodeEditor.d.ts +1 -0
- package/components/features/NodeEditor/useNodeEditor.mock.ts +5 -0
- package/components/features/index.ts +5 -0
- package/components/index.ts +1 -1
- package/components/ui/button.tsx +2 -0
- package/dist/index.cjs +743 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +235 -22
- package/dist/index.d.ts +309 -39
- package/dist/index.js +742 -45
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -23,7 +23,7 @@ export type NodeProps = ComponentProps<typeof Card> & {
|
|
|
23
23
|
export const Node = ({ handles, className, status, ...props }: NodeProps) => (
|
|
24
24
|
<Card
|
|
25
25
|
className={cn(
|
|
26
|
-
"node-container relative h-[52px] w-[180px] gap-0 overflow-hidden rounded-md bg-card p-0 transition-all duration-200",
|
|
26
|
+
"node-container group relative h-[52px] w-[180px] gap-0 overflow-hidden rounded-md bg-card p-0 transition-all duration-200",
|
|
27
27
|
status === "success" && "border-green-500 border-2",
|
|
28
28
|
status === "error" && "border-red-500 border-2",
|
|
29
29
|
className
|
|
@@ -33,18 +33,18 @@ export const Node = ({ handles, className, status, ...props }: NodeProps) => (
|
|
|
33
33
|
{status === "running" && <AnimatedBorder />}
|
|
34
34
|
{handles.target && (
|
|
35
35
|
<>
|
|
36
|
-
<Handle id="target-top" position={Position.Top} type="target" />
|
|
37
|
-
<Handle id="target-right" position={Position.Right} type="target" />
|
|
38
|
-
<Handle id="target-bottom" position={Position.Bottom} type="target" />
|
|
39
|
-
<Handle id="target-left" position={Position.Left} type="target" />
|
|
36
|
+
<Handle id="target-top" position={Position.Top} type="target" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
|
|
37
|
+
<Handle id="target-right" position={Position.Right} type="target" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
|
|
38
|
+
<Handle id="target-bottom" position={Position.Bottom} type="target" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
|
|
39
|
+
<Handle id="target-left" position={Position.Left} type="target" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
|
|
40
40
|
</>
|
|
41
41
|
)}
|
|
42
42
|
{handles.source && (
|
|
43
43
|
<>
|
|
44
|
-
<Handle id="source-top" position={Position.Top} type="source" />
|
|
45
|
-
<Handle id="source-right" position={Position.Right} type="source" />
|
|
46
|
-
<Handle id="source-bottom" position={Position.Bottom} type="source" />
|
|
47
|
-
<Handle id="source-left" position={Position.Left} type="source" />
|
|
44
|
+
<Handle id="source-top" position={Position.Top} type="source" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
|
|
45
|
+
<Handle id="source-right" position={Position.Right} type="source" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
|
|
46
|
+
<Handle id="source-bottom" position={Position.Bottom} type="source" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
|
|
47
|
+
<Handle id="source-left" position={Position.Left} type="source" className="opacity-0 group-hover:opacity-100 group-[.selected]:opacity-100 transition-opacity duration-150" />
|
|
48
48
|
</>
|
|
49
49
|
)}
|
|
50
50
|
{props.children}
|
|
@@ -969,8 +969,8 @@ export const PromptInputSubmit = ({
|
|
|
969
969
|
if (status === "submitted") {
|
|
970
970
|
Icon = <Loader2Icon className="size-4 animate-spin" />;
|
|
971
971
|
} else if (status === "streaming") {
|
|
972
|
-
Icon = <SquareIcon className="size-3.5 fill-
|
|
973
|
-
buttonVariant = "
|
|
972
|
+
Icon = <SquareIcon className="size-3.5 fill-white text-white" />;
|
|
973
|
+
buttonVariant = "outline-primary";
|
|
974
974
|
customClass = cn("rounded-full", className);
|
|
975
975
|
} else if (status === "error") {
|
|
976
976
|
Icon = <XIcon className="size-4" />;
|
|
@@ -10,6 +10,7 @@ import type { ToolCall, SubAgent } from "@/components/composites"
|
|
|
10
10
|
import { UserMessage } from "@/components/composites/UserMessage"
|
|
11
11
|
import { SpecialistMessage } from "@/components/composites/SpecialistMessage"
|
|
12
12
|
import { OrchestratorMessage } from "@/components/composites/OrchestratorMessage"
|
|
13
|
+
import { SystemMessage } from "@/components/composites/SystemMessage"
|
|
13
14
|
import { ToolCallDisplay } from "@/components/composites/ToolCallDisplay"
|
|
14
15
|
import { ReasoningDisplay } from "@/components/composites/ReasoningDisplay"
|
|
15
16
|
|
|
@@ -71,6 +72,11 @@ export interface AIConversationProps
|
|
|
71
72
|
* Callback fired when a tool action (like a link click) is triggered
|
|
72
73
|
*/
|
|
73
74
|
onToolAction?: (toolCall: ToolCall, action: string) => void
|
|
75
|
+
/**
|
|
76
|
+
* Custom renderer for system messages.
|
|
77
|
+
* Receives the raw content string and returns a ReactNode.
|
|
78
|
+
*/
|
|
79
|
+
renderSystemMessage?: (content: string) => React.ReactNode
|
|
74
80
|
}
|
|
75
81
|
|
|
76
82
|
/**
|
|
@@ -84,6 +90,7 @@ export const AIConversation = React.memo<AIConversationProps>(
|
|
|
84
90
|
selectedSubAgent,
|
|
85
91
|
emptyState,
|
|
86
92
|
onToolAction,
|
|
93
|
+
renderSystemMessage,
|
|
87
94
|
...conversationProps
|
|
88
95
|
}) => {
|
|
89
96
|
const isEmpty = React.useMemo(
|
|
@@ -117,6 +124,15 @@ export const AIConversation = React.memo<AIConversationProps>(
|
|
|
117
124
|
(!msg.toolCalls || msg.toolCalls.length === 0) &&
|
|
118
125
|
(!msg.subAgents || msg.subAgents.length === 0);
|
|
119
126
|
|
|
127
|
+
const currentGroupHasTools =
|
|
128
|
+
currentGroup &&
|
|
129
|
+
((currentGroup.toolCalls && currentGroup.toolCalls.length > 0) ||
|
|
130
|
+
(currentGroup.subAgents && currentGroup.subAgents.length > 0));
|
|
131
|
+
|
|
132
|
+
if (currentGroupHasTools && isFinalResponse) {
|
|
133
|
+
currentGroup = null;
|
|
134
|
+
}
|
|
135
|
+
|
|
120
136
|
if (currentGroup) {
|
|
121
137
|
if (msg.content) {
|
|
122
138
|
currentGroup.content = currentGroup.content
|
|
@@ -221,6 +237,23 @@ export const AIConversation = React.memo<AIConversationProps>(
|
|
|
221
237
|
const contentStr = toMessageString(message.content)
|
|
222
238
|
|
|
223
239
|
// Render based on role field
|
|
240
|
+
if (message.role === "system") {
|
|
241
|
+
if (!contentStr || !contentStr.trim()) {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
return (
|
|
245
|
+
<SystemMessage
|
|
246
|
+
key={message.id}
|
|
247
|
+
message={{
|
|
248
|
+
id: message.id,
|
|
249
|
+
content: contentStr,
|
|
250
|
+
avatarName: message.avatarName,
|
|
251
|
+
}}
|
|
252
|
+
renderContent={renderSystemMessage}
|
|
253
|
+
/>
|
|
254
|
+
)
|
|
255
|
+
}
|
|
256
|
+
|
|
224
257
|
if (message.role === "user") {
|
|
225
258
|
return (
|
|
226
259
|
<UserMessage
|
|
@@ -252,9 +285,9 @@ export const AIConversation = React.memo<AIConversationProps>(
|
|
|
252
285
|
const directToolCalls = allToolCalls.filter((tc) => tc.visibility !== "reasoning")
|
|
253
286
|
|
|
254
287
|
const hasReasoning = reasoningCalls.length > 0 || subAgents.length > 0 || directToolCalls.length > 0 || (message.isLoading && contentStr.trim() !== "");
|
|
255
|
-
const reasoningText = (hasReasoning && (!message.blocks || message.blocks.length === 0)) ? contentStr : undefined
|
|
256
|
-
const displayContentStr = hasReasoning ? "" : contentStr
|
|
257
|
-
const hasDisplayContent = displayContentStr.trim() !== ""
|
|
288
|
+
const reasoningText = (hasReasoning && (!message.blocks || message.blocks.length === 0)) ? contentStr : undefined;
|
|
289
|
+
const displayContentStr = hasReasoning ? "" : contentStr;
|
|
290
|
+
const hasDisplayContent = displayContentStr.trim() !== "";
|
|
258
291
|
|
|
259
292
|
if (!hasDisplayContent && directToolCalls.length === 0 && reasoningCalls.length === 0 && subAgents.length === 0 && !message.isLoading && (!message.blocks || message.blocks.length === 0)) {
|
|
260
293
|
return null;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { WorkflowNode, WorkflowEdge } from "@/components/blocks/WorkflowCanvas";
|
|
2
|
+
import type { SpatialContainerColorTheme, SpatialContainerVariant } from "@/components/composites/SpatialContainerNode";
|
|
3
|
+
import type { BmcBlock, BmcBlockId, BmcCanvasView, CompiledBmc } from "./interfaces";
|
|
4
|
+
|
|
5
|
+
interface BlockLayout {
|
|
6
|
+
id: string;
|
|
7
|
+
themeColor: SpatialContainerColorTheme;
|
|
8
|
+
variant: SpatialContainerVariant;
|
|
9
|
+
icon: string;
|
|
10
|
+
position: { x: number; y: number };
|
|
11
|
+
size: { width: number; height: number };
|
|
12
|
+
layout: 'column' | 'row';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const BLOCK_LAYOUTS: Record<BmcBlockId, BlockLayout> = {
|
|
16
|
+
key_partnerships: { id: 'cp', themeColor: 'blue', variant: 'extruded3d', icon: 'handshake', position: { x: 40, y: 40 }, size: { width: 280, height: 400 }, layout: 'column' },
|
|
17
|
+
key_activities: { id: 'ka', themeColor: 'emerald', variant: 'extruded3d', icon: 'activity', position: { x: 350, y: 40 }, size: { width: 280, height: 190 }, layout: 'column' },
|
|
18
|
+
key_resources: { id: 'kr', themeColor: 'emerald', variant: 'extruded3d', icon: 'database', position: { x: 350, y: 250 }, size: { width: 280, height: 190 }, layout: 'column' },
|
|
19
|
+
value_propositions: { id: 'vp', themeColor: 'indigo', variant: 'extruded3d', icon: 'box', position: { x: 660, y: 40 }, size: { width: 300, height: 400 }, layout: 'column' },
|
|
20
|
+
customer_relationships: { id: 'cr', themeColor: 'purple', variant: 'extruded3d', icon: 'heart', position: { x: 990, y: 40 }, size: { width: 300, height: 190 }, layout: 'column' },
|
|
21
|
+
channels: { id: 'ch', themeColor: 'amber', variant: 'extruded3d', icon: 'truck', position: { x: 990, y: 250 }, size: { width: 300, height: 190 }, layout: 'column' },
|
|
22
|
+
customer_segments: { id: 'cs', themeColor: 'purple', variant: 'extruded3d', icon: 'users', position: { x: 1320, y: 40 }, size: { width: 280, height: 400 }, layout: 'column' },
|
|
23
|
+
cost_structure: { id: 'cost', themeColor: 'rose', variant: 'extruded3d', icon: 'wallet', position: { x: 40, y: 465 }, size: { width: 760, height: 180 }, layout: 'row' },
|
|
24
|
+
revenue_streams: { id: 'rev', themeColor: 'cyan', variant: 'extruded3d', icon: 'wallet', position: { x: 840, y: 465 }, size: { width: 760, height: 180 }, layout: 'row' },
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
function blockEntries(bmc: CompiledBmc): Array<{ block: BmcBlock; layout: BlockLayout }> {
|
|
28
|
+
return [
|
|
29
|
+
{ block: bmc.keyPartnerships, layout: BLOCK_LAYOUTS.key_partnerships },
|
|
30
|
+
{ block: bmc.keyActivities, layout: BLOCK_LAYOUTS.key_activities },
|
|
31
|
+
{ block: bmc.keyResources, layout: BLOCK_LAYOUTS.key_resources },
|
|
32
|
+
{ block: bmc.valuePropositions, layout: BLOCK_LAYOUTS.value_propositions },
|
|
33
|
+
{ block: bmc.customerRelationships, layout: BLOCK_LAYOUTS.customer_relationships },
|
|
34
|
+
{ block: bmc.channels, layout: BLOCK_LAYOUTS.channels },
|
|
35
|
+
{ block: bmc.customerSegments, layout: BLOCK_LAYOUTS.customer_segments },
|
|
36
|
+
{ block: bmc.costStructure, layout: BLOCK_LAYOUTS.cost_structure },
|
|
37
|
+
{ block: bmc.revenueStreams, layout: BLOCK_LAYOUTS.revenue_streams },
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
import { BMC_TOOLTIPS } from "./bmc-tooltips";
|
|
42
|
+
|
|
43
|
+
export function bmcToCanvas(bmc: CompiledBmc | null, message?: string): BmcCanvasView {
|
|
44
|
+
if (!bmc) {
|
|
45
|
+
return {
|
|
46
|
+
canvasName: null,
|
|
47
|
+
nodes: [],
|
|
48
|
+
edges: [],
|
|
49
|
+
emptyBlocks: [],
|
|
50
|
+
message: message ?? 'No business model data available for this session',
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const nodes: WorkflowNode[] = [];
|
|
55
|
+
|
|
56
|
+
for (const { block, layout } of blockEntries(bmc)) {
|
|
57
|
+
const itemCount = block.items.length;
|
|
58
|
+
const badgeText = block.empty || itemCount === 0 ? 'empty' : `${itemCount} item${itemCount === 1 ? '' : 's'}`;
|
|
59
|
+
|
|
60
|
+
const items = block.items.map((item, idx) => ({
|
|
61
|
+
id: `${layout.id}-${idx + 1}`,
|
|
62
|
+
label: item.name,
|
|
63
|
+
description: item.description,
|
|
64
|
+
}));
|
|
65
|
+
|
|
66
|
+
const blockId = layout.id === 'cp' ? 'key_partnerships'
|
|
67
|
+
: layout.id === 'ka' ? 'key_activities'
|
|
68
|
+
: layout.id === 'kr' ? 'key_resources'
|
|
69
|
+
: layout.id === 'vp' ? 'value_propositions'
|
|
70
|
+
: layout.id === 'cr' ? 'customer_relationships'
|
|
71
|
+
: layout.id === 'ch' ? 'channels'
|
|
72
|
+
: layout.id === 'cs' ? 'customer_segments'
|
|
73
|
+
: layout.id === 'cost' ? 'cost_structure'
|
|
74
|
+
: layout.id === 'rev' ? 'revenue_streams'
|
|
75
|
+
: '';
|
|
76
|
+
|
|
77
|
+
const tooltipInfo = BMC_TOOLTIPS[blockId];
|
|
78
|
+
const description = tooltipInfo
|
|
79
|
+
? `${tooltipInfo.description}\n\nKey Question: "${tooltipInfo.question}"\n\nExamples: ${tooltipInfo.examples.join(', ')}`
|
|
80
|
+
: block.name;
|
|
81
|
+
|
|
82
|
+
nodes.push({
|
|
83
|
+
id: layout.id,
|
|
84
|
+
type: 'spatialContainer',
|
|
85
|
+
position: layout.position,
|
|
86
|
+
style: layout.size,
|
|
87
|
+
data: {
|
|
88
|
+
label: block.name,
|
|
89
|
+
description,
|
|
90
|
+
type: 'spatialContainer',
|
|
91
|
+
themeColor: layout.themeColor,
|
|
92
|
+
variant: layout.variant,
|
|
93
|
+
icon: layout.icon,
|
|
94
|
+
badgeText,
|
|
95
|
+
items,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const edges: WorkflowEdge[] = [
|
|
101
|
+
{ id: 'e-ka-vp', source: 'ka', target: 'vp', type: 'animated' },
|
|
102
|
+
{ id: 'e-vp-cr', source: 'vp', target: 'cr', type: 'animated' },
|
|
103
|
+
{ id: 'e-cr-cs', source: 'cr', target: 'cs', type: 'animated' },
|
|
104
|
+
{ id: 'e-vp-ch', source: 'vp', target: 'ch', type: 'straight' },
|
|
105
|
+
{ id: 'e-ch-cs', source: 'ch', target: 'cs', type: 'animated' },
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
canvasName: bmc.canvas.name,
|
|
110
|
+
nodes,
|
|
111
|
+
edges,
|
|
112
|
+
emptyBlocks: bmc.emptyBlocks,
|
|
113
|
+
message,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export interface BmcTooltipContent {
|
|
2
|
+
title: string;
|
|
3
|
+
description: string;
|
|
4
|
+
question: string;
|
|
5
|
+
examples: string[];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const BMC_TOOLTIPS: Record<string, BmcTooltipContent> = {
|
|
9
|
+
key_partnerships: {
|
|
10
|
+
title: "Key Partnerships",
|
|
11
|
+
description: "The external companies, suppliers, or vendors that help your business operate and grow.",
|
|
12
|
+
question: "Who do we rely on outside our company to make this business work?",
|
|
13
|
+
examples: ["Cloud hosting providers", "Payment gateways", "Material suppliers", "Strategic alliances"]
|
|
14
|
+
},
|
|
15
|
+
key_activities: {
|
|
16
|
+
title: "Key Activities",
|
|
17
|
+
description: "The most critical daily tasks and operations your team must execute to deliver your offer.",
|
|
18
|
+
question: "What core things must we do every day to operate and succeed?",
|
|
19
|
+
examples: ["Software development", "AI model training", "Content creation", "Customer support"]
|
|
20
|
+
},
|
|
21
|
+
key_resources: {
|
|
22
|
+
title: "Key Resources",
|
|
23
|
+
description: "The most vital assets—physical, intellectual, human, or financial—needed to run your business.",
|
|
24
|
+
question: "What essential assets do we need to own or access to deliver our value?",
|
|
25
|
+
examples: ["Skilled engineers", "Proprietary algorithms", "Brand identity", "Capital"]
|
|
26
|
+
},
|
|
27
|
+
value_propositions: {
|
|
28
|
+
title: "Value Propositions",
|
|
29
|
+
description: "The collection of products, services, and benefits that solve customer problems or satisfy their needs.",
|
|
30
|
+
question: "Why do customers choose us over competitors? What problem are we solving?",
|
|
31
|
+
examples: ["Time savings", "Cost reduction", "Ease of use", "Premium quality"]
|
|
32
|
+
},
|
|
33
|
+
customer_relationships: {
|
|
34
|
+
title: "Customer Relationships",
|
|
35
|
+
description: "The type of interaction and ongoing relationship you establish with each customer group.",
|
|
36
|
+
question: "How do we interact with our customers across their lifecycle?",
|
|
37
|
+
examples: ["Self-service onboarding", "Dedicated account management", "Automated support"]
|
|
38
|
+
},
|
|
39
|
+
channels: {
|
|
40
|
+
title: "Channels",
|
|
41
|
+
description: "The touchpoints and pathways you use to communicate with, sell to, and deliver value to customers.",
|
|
42
|
+
question: "How do customers find, evaluate, buy, and receive our product or service?",
|
|
43
|
+
examples: ["Direct web platform", "Sales team", "Mobile app", "Partner marketplaces"]
|
|
44
|
+
},
|
|
45
|
+
customer_segments: {
|
|
46
|
+
title: "Customer Segments",
|
|
47
|
+
description: "The specific groups of people or organizations your business aims to reach and serve.",
|
|
48
|
+
question: "Who are we creating value for? Who is our ideal buyer?",
|
|
49
|
+
examples: ["Enterprise B2B teams", "Thought leaders", "Small business owners"]
|
|
50
|
+
},
|
|
51
|
+
cost_structure: {
|
|
52
|
+
title: "Cost Structure",
|
|
53
|
+
description: "All major fixed and variable expenses required to operate your business model.",
|
|
54
|
+
question: "What are the biggest costs inherent in running our business?",
|
|
55
|
+
examples: ["Server/compute costs", "Team salaries", "R&D licensing", "Marketing"]
|
|
56
|
+
},
|
|
57
|
+
revenue_streams: {
|
|
58
|
+
title: "Revenue Streams",
|
|
59
|
+
description: "The different ways your business earns cash and captures value from each customer segment.",
|
|
60
|
+
question: "How does money flow into the business? What are customers paying for?",
|
|
61
|
+
examples: ["Monthly SaaS subscriptions", "Usage-based fees", "One-time setup charges"]
|
|
62
|
+
}
|
|
63
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { WorkflowEdge, WorkflowNode } from "@/components/blocks/WorkflowCanvas";
|
|
2
|
+
|
|
3
|
+
export type BmcBlockId =
|
|
4
|
+
| 'customer_segments'
|
|
5
|
+
| 'value_propositions'
|
|
6
|
+
| 'channels'
|
|
7
|
+
| 'customer_relationships'
|
|
8
|
+
| 'revenue_streams'
|
|
9
|
+
| 'key_resources'
|
|
10
|
+
| 'key_activities'
|
|
11
|
+
| 'key_partnerships'
|
|
12
|
+
| 'cost_structure';
|
|
13
|
+
|
|
14
|
+
export interface BmcItem {
|
|
15
|
+
id: string;
|
|
16
|
+
name: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
sourceRefs: string[];
|
|
19
|
+
[k: string]: unknown;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface BmcBlock {
|
|
23
|
+
key: BmcBlockId;
|
|
24
|
+
name: string;
|
|
25
|
+
items: BmcItem[];
|
|
26
|
+
empty: boolean;
|
|
27
|
+
derived: boolean;
|
|
28
|
+
sourceRefs: string[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface CompiledBmc {
|
|
32
|
+
canvas: {
|
|
33
|
+
id: string;
|
|
34
|
+
name: string;
|
|
35
|
+
description: string;
|
|
36
|
+
derived: boolean;
|
|
37
|
+
source: { businessDocId?: string; productDocId?: string };
|
|
38
|
+
generatedAt: string;
|
|
39
|
+
};
|
|
40
|
+
customerSegments: BmcBlock;
|
|
41
|
+
valuePropositions: BmcBlock;
|
|
42
|
+
channels: BmcBlock;
|
|
43
|
+
customerRelationships: BmcBlock;
|
|
44
|
+
revenueStreams: BmcBlock;
|
|
45
|
+
keyResources: BmcBlock;
|
|
46
|
+
keyActivities: BmcBlock;
|
|
47
|
+
keyPartnerships: BmcBlock;
|
|
48
|
+
costStructure: BmcBlock & { strategicFocus?: string; drivers: string[] };
|
|
49
|
+
emptyBlocks: BmcBlockId[];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface BmcCanvasView {
|
|
53
|
+
canvasName: string | null;
|
|
54
|
+
nodes: WorkflowNode[];
|
|
55
|
+
edges: WorkflowEdge[];
|
|
56
|
+
emptyBlocks: BmcBlockId[];
|
|
57
|
+
message?: string;
|
|
58
|
+
}
|
|
@@ -81,7 +81,7 @@ function WorkflowCanvasInner({
|
|
|
81
81
|
}}
|
|
82
82
|
>
|
|
83
83
|
<Canvas
|
|
84
|
-
className="bg-background"
|
|
84
|
+
className="bg-background [&_.react-flow\_\_handle]:opacity-0 [&_.react-flow\_\_handle]:pointer-events-none [&_.react-flow\_\_node:hover_.react-flow\_\_handle]:opacity-100 [&_.react-flow\_\_node:hover_.react-flow\_\_handle]:pointer-events-auto [&_.react-flow\_\_node.selected_.react-flow\_\_handle]:opacity-100 [&_.react-flow\_\_node.selected_.react-flow\_\_handle]:pointer-events-auto [&_.react-flow\_\_handle]:transition-opacity [&_.react-flow\_\_handle]:duration-150"
|
|
85
85
|
connectionLineComponent={ConnectionLine}
|
|
86
86
|
connectionMode={ConnectionMode.Strict}
|
|
87
87
|
edges={edges}
|
|
@@ -16,6 +16,9 @@ export * from './SectionLayout'
|
|
|
16
16
|
export { WorkflowCanvas, getLayoutedElements } from './WorkflowCanvas'
|
|
17
17
|
export type { WorkflowCanvasProps, WorkflowNode, WorkflowEdge, WorkflowNodeData } from './WorkflowCanvas'
|
|
18
18
|
|
|
19
|
+
export { bmcToCanvas } from './BmcCanvas'
|
|
20
|
+
export type { BmcBlockId, BmcItem, BmcBlock, CompiledBmc, BmcCanvasView } from './BmcCanvas'
|
|
21
|
+
|
|
19
22
|
export { DashboardMetrics } from './DashboardMetrics'
|
|
20
23
|
export type { DashboardMetricsProps } from './DashboardMetrics'
|
|
21
24
|
|
|
@@ -16,7 +16,7 @@ export interface SubAgent {
|
|
|
16
16
|
subAgentName: string
|
|
17
17
|
input: string | Record<string, unknown>
|
|
18
18
|
output?: string | Record<string, unknown>
|
|
19
|
-
status: "pending" | "active" | "completed" | "error"
|
|
19
|
+
status: "pending" | "active" | "completed" | "error" | "running" | "in_progress"
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export interface AgentIndicatorProps {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { AuthCard } from "./AuthCard";
|
|
3
|
+
import { fn } from "@storybook/test";
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof AuthCard> = {
|
|
6
|
+
title: "Composites/AuthCard",
|
|
7
|
+
component: AuthCard,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: "centered",
|
|
10
|
+
},
|
|
11
|
+
args: {
|
|
12
|
+
appName: "Waypoint",
|
|
13
|
+
mode: "login",
|
|
14
|
+
email: "",
|
|
15
|
+
isLoading: false,
|
|
16
|
+
allowSso: true,
|
|
17
|
+
socialProviders: ["apple", "google"],
|
|
18
|
+
onEmailChange: fn(),
|
|
19
|
+
onNameChange: fn(),
|
|
20
|
+
onPasswordChange: fn(),
|
|
21
|
+
onConfirmPasswordChange: fn(),
|
|
22
|
+
onSubmit: fn(),
|
|
23
|
+
onSsoClick: fn(),
|
|
24
|
+
onSocialClick: fn(),
|
|
25
|
+
onToggleMode: fn(),
|
|
26
|
+
},
|
|
27
|
+
} satisfies Meta<typeof AuthCard>;
|
|
28
|
+
|
|
29
|
+
export default meta;
|
|
30
|
+
type Story = StoryObj<typeof AuthCard>;
|
|
31
|
+
|
|
32
|
+
export const LoginDefault: Story = {
|
|
33
|
+
args: {
|
|
34
|
+
mode: "login",
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const LoginFilled: Story = {
|
|
39
|
+
args: {
|
|
40
|
+
mode: "login",
|
|
41
|
+
email: "alex@example.com",
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const SignupDefault: Story = {
|
|
46
|
+
args: {
|
|
47
|
+
mode: "signup",
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const LoadingState: Story = {
|
|
52
|
+
args: {
|
|
53
|
+
mode: "login",
|
|
54
|
+
email: "alex@example.com",
|
|
55
|
+
isLoading: true,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const WithError: Story = {
|
|
60
|
+
args: {
|
|
61
|
+
mode: "login",
|
|
62
|
+
email: "alex@example.com",
|
|
63
|
+
error: "Invalid email or authentication session expired. Please try again.",
|
|
64
|
+
},
|
|
65
|
+
};
|