@directivsys/angular-sdk
v0.1.10
Published
Angular bindings for DirectivSys built on top of @directivsys/core-sdk.
Maintainers
Readme
@directivsys/angular-sdk
Enterprise-grade Angular SDK for DirectivSys conversation management, analytics, and business intelligence dashboards.
@directivsys/angular-sdk provides Angular-native components and services for intelligent chat, search, real-time analytics, and comprehensive reporting. It builds on @directivsys/core-sdk with dependency injection, reactive state management, and production-ready UI components.
📦 23 Pre-built Components | ⚡ OnPush Optimization | 🎨 Fully Themeable | ♿ Accessible | 📱 Responsive
Table of Contents
- Overview
- Installation
- Quick Start
- Architecture
- Chat Components
- Analytics Dashboard
- Reports & Dashboards
- Session Management
- Theming
- Advanced Usage
- API Reference
- Common Patterns
- Troubleshooting
- FAQ
Overview
What's Included
| Feature | Components | |---------|-----------| | Chat & Search | 2 components with voice input, file upload, persistence | | Analytics | 7 components with KPIs, observations, directives tracking | | Reports | 14 components including dashboards, visualizations, audit trails | | Utilities | Session service, theme support, storage adapters |
Architecture
Your Angular App
↓
@directivsys/angular-sdk (Components, Services, DI)
↓
@directivsys/core-sdk (Transport, Controller, Voice)
↓
DirectivSys APIRelationship to core package:
| Concern | Package |
|---------|---------|
| Transport, conversation controller, shared contracts, voice adapters | @directivsys/core-sdk |
| Angular components, dependency injection, session service | @directivsys/angular-sdk |
Installation
Prerequisites
- Angular 17+
- TypeScript 5.0+
- Node.js 16+
- RxJS 7+
Setup
npm install @directivsys/angular-sdk @directivsys/core-sdkThis automatically installs peer dependencies (@angular/core, @angular/common, rxjs).
Configure Provider
Add the provider to your Angular application configuration:
main.ts (Standalone API):
import { bootstrapApplication } from '@angular/platform-browser';
import { ApplicationConfig } from '@angular/core';
import { provideDirectivSys } from '@directivsys/angular-sdk';
import { AppComponent } from './app/app.component';
const appConfig: ApplicationConfig = {
providers: [
...provideDirectivSys({
apiKey: 'your-api-key-here',
config: {
timeout: 30000,
retries: 3,
baseUrl: 'https://api.directivsys.com', // Optional
},
}),
],
};
bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err));app.module.ts (NgModule):
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { provideDirectivSys } from '@directivsys/angular-sdk';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [
...provideDirectivSys({
apiKey: 'your-api-key-here',
config: { timeout: 30000 },
}),
],
bootstrap: [AppComponent],
})
export class AppModule {}Quick Start
1. Add Chat Widget to Your Component
import { Component } from '@angular/core';
import { DirectivSysChatboxComponent } from '@directivsys/angular-sdk';
@Component({
selector: 'app-dashboard',
standalone: true,
imports: [DirectivSysChatboxComponent],
template: `
<div class="app-container">
<h1>My Dashboard</h1>
<!-- Floating Chat Widget -->
<directivsys-chatbox
[onIntentDetected]="handleUserIntent"
[currentContext]="userContext"
renderMode="standard"
[defaultOpen]="true"
></directivsys-chatbox>
</div>
`,
styles: [`
.app-container {
padding: 24px;
font-family: system-ui, sans-serif;
}
`],
})
export class DashboardComponent {
// User context passed to the conversation
userContext = {
userId: 'user-12345',
userName: 'John Doe',
role: 'Manager',
department: 'Operations',
currentPage: 'Dashboard',
timestamp: new Date().toISOString(),
};
// Handle user intents (directives, questions, etc.)
handleUserIntent = async (intent: any, files?: File[]) => {
console.log('User intent:', intent);
console.log('Attached files:', files);
// Process the intent and return a response
return {
status: 'success',
message: 'Intent processed successfully',
data: { /* your response */ },
};
};
}2. Add Analytics Dashboard
import { Component } from '@angular/core';
import { AnalyticsDashboardComponent } from '@directivsys/angular-sdk';
@Component({
selector: 'app-analytics-page',
standalone: true,
imports: [AnalyticsDashboardComponent],
template: `
<directivsys-analytics-dashboard
selectedAnalytics="all"
[theme]="{ colors: { primary: '#007bff' } }"
></directivsys-analytics-dashboard>
`,
})
export class AnalyticsPageComponent {}3. Add Reports Dashboard
import { Component } from '@angular/core';
import { ReportsDashboardComponent } from '@directivsys/angular-sdk';
@Component({
selector: 'app-reports',
standalone: true,
imports: [ReportsDashboardComponent],
template: `
<directivsys-reports-dashboard></directivsys-reports-dashboard>
`,
})
export class ReportsComponent {}Architecture
Component Structure
Foundation Layer (no dependencies)
├── StatusBadgeComponent
├── HealthGaugeComponent
├── ProgressBarComponent
├── MetricCardComponent
└── ... 5 more utility components
Composite Layer (uses foundation)
├── ReportLayoutComponent
├── MetricsPanelComponent
├── TrendChartComponent
└── ... analytics panels
Dashboard Layer (full-featured)
├── AnalyticsDashboardComponent
├── ExecutiveDashboardComponent
├── ReportsDashboardComponent
└── 4 more dashboard components
Top-Level (standalone)
├── DirectivSysChatboxComponent
└── DirectivSysSearchComponentState Management
All components use RxJS Observables for reactive state:
// Behind the scenes
DirectivSysChatboxComponent
├── Subscribes to DirectivSysSessionService.state$
├── OnPush change detection
├── Automatic cleanup with takeUntil(destroy$)
└── No memory leaksChat & Search Components
Chat & Search Components
DirectiveSysChatboxComponent
Full-featured chat widget with message persistence, voice input, and file upload.
Basic Usage
<directivsys-chatbox
[onIntentDetected]="handleIntent"
[currentContext]="userContext"
renderMode="standard"
></directivsys-chatbox>Complete Example
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DirectivSysChatboxComponent } from '@directivsys/angular-sdk';
@Component({
selector: 'app-chat-demo',
standalone: true,
imports: [CommonModule, DirectivSysChatboxComponent],
template: `
<div class="chat-container">
<h2>Chat Assistant</h2>
<directivsys-chatbox
[onIntentDetected]="handleIntent"
[currentContext]="context"
renderMode="standard"
[defaultOpen]="true"
placeholder="Ask anything..."
[width]="'500px'"
[height]="'600px'"
[theme]="customTheme"
[voice]="true"
(onError)="handleError($event)"
(onSpeechStart)="onSpeechStart()"
(onSpeechEnd)="onSpeechEnd()"
></directivsys-chatbox>
</div>
`,
styles: [`
.chat-container {
display: flex;
flex-direction: column;
height: 100vh;
padding: 20px;
}
`],
})
export class ChatDemoComponent {
context = {
userId: 'user-123',
userName: 'John Doe',
role: 'Manager',
department: 'Operations',
currentPage: 'Dashboard',
metadata: {
timezone: 'UTC',
language: 'en-US',
},
};
customTheme = {
colors: {
primary: '#007bff',
background: '#ffffff',
text: '#333333',
border: '#e0e0e0',
},
spacing: {
xs: '4px',
sm: '8px',
md: '16px',
lg: '24px',
},
};
// Handle user intents (required callback)
handleIntent = async (intent: any, files?: File[]) => {
console.log('User sent:', intent);
if (files?.length) {
console.log('With files:', files);
}
// Process intent and return response
return {
status: 'success',
message: 'Intent received',
data: { /* your response */ },
};
};
handleError(error: Error) {
console.error('Chat error:', error);
}
onSpeechStart() {
console.log('Voice input started');
}
onSpeechEnd() {
console.log('Voice input ended');
}
}Render Modes
Standard Mode (Floating Widget):
<directivsys-chatbox
renderMode="standard"
[defaultOpen]="false"
boxLocation="bottom-right"
titleText="AI Assistant"
headerBgColor="#007bff"
></directivsys-chatbox>Basic Mode (Embedded):
<div class="chat-wrapper">
<directivsys-chatbox
renderMode="basic"
[height]="'600px'"
[width]="'100%'"
></directivsys-chatbox>
</div>Props Reference
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| onIntentDetected | Function | Required | Callback when user sends message |
| currentContext | Object | Required | User & interface context |
| renderMode | 'basic' \| 'standard' | 'standard' | Embedded or floating widget |
| defaultOpen | boolean | false | Auto-open on load |
| boxLocation | 'bottom-right' \| 'bottom-left' | 'bottom-right' | Widget position |
| titleText | string | 'AI Assistant' | Header title |
| headerBgColor | string | '#007bff' | Header background |
| titleTextColor | string | '#ffffff' | Header text color |
| placeholder | string | 'Type your message...' | Input placeholder |
| height | string | '600px' | Container height |
| width | string | '100%' | Container width |
| theme | Partial<Theme> | undefined | Custom theme override |
| storageAdapter | StorageAdapter | localStorage | Message persistence |
| voice | boolean | true | Enable voice input |
| onError | EventEmitter | — | Error event |
| onSpeechStart | EventEmitter | — | Voice input started |
| onSpeechEnd | EventEmitter | — | Voice input ended |
Message Persistence
Messages are automatically saved to localStorage:
// Automatic: Messages persist across page reloads
// Previous conversation loads when component initializes
// Custom storage adapter for SSR or database
import { StorageAdapter } from '@directivsys/angular-sdk';
class DatabaseStorageAdapter implements StorageAdapter {
async getItem(key: string): Promise<string | null> {
// Fetch from database
}
async setItem(key: string, value: string): Promise<void> {
// Save to database
}
async removeItem(key: string): Promise<void> {
// Delete from database
}
}
// Use custom adapter
<directivsys-chatbox
[storageAdapter]="new DatabaseStorageAdapter()"
...
></directivsys-chatbox>File Upload Support
Users can attach files to messages:
handleIntent = async (intent: any, files?: File[]) => {
if (files?.length) {
// Handle file uploads
for (const file of files) {
console.log(`File: ${file.name}, Size: ${file.size} bytes, Type: ${file.type}`);
// Upload to your server
await this.uploadFile(file);
}
}
return { status: 'success' };
};
async uploadFile(file: File) {
const formData = new FormData();
formData.append('file', file);
return fetch('/api/upload', {
method: 'POST',
body: formData,
});
}Supported file types:
- Images: PNG, JPG, JPEG, WebP, GIF
- Documents: PDF, DOCX, XLSX, PPTX, TXT
DirectiveSysSearchComponent
Intelligent search bar with dropdown results and voice support.
Basic Usage
<directivsys-search
[onIntentDetected]="handleSearch"
[currentContext]="userContext"
placeholder="Search documents..."
[maxResults]="5"
></directivsys-search>Complete Example
import { Component } from '@angular/core';
import { DirectivSysSearchComponent } from '@directivsys/angular-sdk';
@Component({
selector: 'app-search-demo',
standalone: true,
imports: [DirectivSysSearchComponent],
template: `
<div class="search-wrapper">
<directivsys-search
[onIntentDetected]="handleSearch"
[currentContext]="context"
placeholder="Search documents, issues, reports..."
[maxResults]="10"
width="100%"
[theme]="customTheme"
></directivsys-search>
</div>
`,
styles: [`
.search-wrapper {
width: 100%;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
`],
})
export class SearchDemoComponent {
context = {
userId: 'user-123',
domain: 'documents',
searchIndex: 'elastic',
};
customTheme = {
colors: { primary: '#007bff' },
};
handleSearch = async (query: string, files?: File[]) => {
console.log('Search query:', query);
// Perform search
const results = await this.performSearch(query);
return {
status: 'success',
results: results,
};
};
async performSearch(query: string) {
// Your search logic
return [];
}
}Props Reference
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| onIntentDetected | Function | Required | Search handler callback |
| currentContext | Object | Required | User & interface context |
| placeholder | string | 'Search...' | Input placeholder |
| maxResults | number | 5 | Max results in dropdown |
| width | string | '100%' | Component width |
| theme | Partial<Theme> | undefined | Custom theme |
| voice | boolean | true | Enable voice search |
| onError | EventEmitter | — | Error event |
Analytics Dashboard
Analytics Dashboard
Real-time analytics with KPIs, system observations, and directives management.
Basic Usage
<directivsys-analytics-dashboard
selectedAnalytics="all"
[theme]="theme"
></directivsys-analytics-dashboard>Complete Example
import { Component } from '@angular/core';
import { AnalyticsDashboardComponent } from '@directivsys/angular-sdk';
@Component({
selector: 'app-analytics',
standalone: true,
imports: [AnalyticsDashboardComponent],
template: `
<div class="analytics-container">
<directivsys-analytics-dashboard
selectedAnalytics="all"
[theme]="customTheme"
></directivsys-analytics-dashboard>
</div>
`,
styles: [`
.analytics-container {
padding: 20px;
height: 100vh;
overflow: auto;
}
`],
})
export class AnalyticsComponent {
customTheme = {
colors: {
primary: '#007bff',
background: '#f5f5f5',
text: '#333',
},
spacing: {
md: '16px',
},
};
}Included Panels
The dashboard automatically includes:
Metrics Panel - Key performance indicators
- Total Directives
- Success Rate
- Average Execution Time
- Auto-Executed Percentage
Observations Panel - System insights and alerts
- Pattern detections
- Performance changes
- Optimization updates
Directives Panel - Recent directive actions
- Directive ID
- Status (Proposed, Executed, Declined)
- User who performed action
- Timestamp
Compose Individual Panels
import { Component } from '@angular/core';
import {
MetricsPanelComponent,
ObservationsPanelComponent,
DirectivesPanelComponent,
} from '@directivsys/angular-sdk';
@Component({
selector: 'app-custom-analytics',
standalone: true,
imports: [
MetricsPanelComponent,
ObservationsPanelComponent,
DirectivesPanelComponent,
],
template: `
<div class="grid">
<directivsys-metrics-panel></directivsys-metrics-panel>
<directivsys-observations-panel></directivsys-observations-panel>
<directivsys-directives-panel
selectedFilter="all"
(onFilterChange)="filterDirectives($event)"
></directivsys-directives-panel>
</div>
`,
styles: [`
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
padding: 20px;
}
`],
})
export class CustomAnalyticsComponent {
filterDirectives(filter: string) {
console.log('Filter by:', filter);
}
}Reports & Dashboards
Pre-built Report Dashboards
Complete reports system with executive dashboards, risk matrices, and audit trails.
Main Reports Dashboard
import { Component } from '@angular/core';
import { ReportsDashboardComponent } from '@directivsys/angular-sdk';
@Component({
selector: 'app-reports',
standalone: true,
imports: [ReportsDashboardComponent],
template: `
<directivsys-reports-dashboard
[theme]="{ colors: { primary: '#007bff' } }"
></directivsys-reports-dashboard>
`,
})
export class ReportsComponent {}Includes:
- ✅ Executive Dashboard with business KPIs
- ✅ Risk Matrix (2D probability vs impact)
- ✅ Portfolio Health metrics
- ✅ Supply Chain Risk assessment
- ✅ Data Quality monitoring
- ✅ Execution Audit Trail
Custom Report Layout
Create custom report layouts by composing components:
import { Component } from '@angular/core';
import {
ReportLayoutComponent,
ExecutiveDashboardComponent,
RiskMatrixComponent,
TrendChartComponent,
} from '@directivsys/angular-sdk';
@Component({
selector: 'app-custom-report',
standalone: true,
imports: [
ReportLayoutComponent,
ExecutiveDashboardComponent,
RiskMatrixComponent,
TrendChartComponent,
],
template: `
<directivsys-report-layout
title="Q2 Business Report"
description="Key metrics and KPIs for Q2 2026"
[selectedDateRange]="'past-month'"
[loading]="isLoading"
[error]="error"
[showDateSelector]="true"
[showRefresh]="true"
(onDateRangeChange)="onDateChange($event)"
(onRefresh)="loadReport()"
>
<div class="report-content">
<h3>Executive Summary</h3>
<directivsys-executive-dashboard></directivsys-executive-dashboard>
<h3>Risk Assessment</h3>
<directivsys-risk-matrix></directivsys-risk-matrix>
<h3>Trends</h3>
<directivsys-trend-chart
[data]="trendData"
></directivsys-trend-chart>
</div>
</directivsys-report-layout>
`,
styles: [`
.report-content {
display: flex;
flex-direction: column;
gap: 40px;
}
h3 {
margin-top: 40px;
padding-bottom: 12px;
border-bottom: 2px solid #e0e0e0;
}
`],
})
export class CustomReportComponent {
isLoading = false;
error: string | null = null;
trendData = [
{ label: 'Jan', value: 65 },
{ label: 'Feb', value: 72 },
{ label: 'Mar', value: 68 },
{ label: 'Apr', value: 78 },
{ label: 'May', value: 85 },
];
loadReport() {
this.isLoading = true;
// Load report data
setTimeout(() => {
this.isLoading = false;
}, 1000);
}
onDateChange(event: Event) {
const select = event.target as HTMLSelectElement;
console.log('Date range changed to:', select.value);
this.loadReport();
}
}Foundation Components for Custom Dashboards
Build custom reports using foundation components:
Metric Card
<directivsys-metric-card
label="Total Revenue"
value="$2.4M"
unit="USD"
trend="up"
[trendValue]="18"
(onClick)="showDetails()"
></directivsys-metric-card>Health Gauge
<directivsys-health-gauge
[score]="8.5"
label="System Health"
size="large"
></directivsys-health-gauge>Progress Bar
<directivsys-progress-bar
[percentage]="75"
label="Completion"
[showPercentage]="true"
size="medium"
></directivsys-progress-bar>Status Badge
<directivsys-status-badge
status="critical"
label="Critical Risk"
></directivsys-status-badge>Data Table
<directivsys-data-table
[columns]="['Date', 'Type', 'Value', 'Status']"
[rows]="tableData"
></directivsys-data-table>Trend Chart
<directivsys-trend-chart
[data]="chartData"
></directivsys-trend-chart>Session Management
Session Management
DirectivSysSessionService
For low-level access, inject DirectivSysSessionService directly:
import { Component, inject, OnInit, OnDestroy } from '@angular/core';
import { DirectivSysSessionService } from '@directivsys/angular-sdk';
@Component({
selector: 'app-custom-chat',
standalone: true,
template: `
<div class="chat-area">
<div class="messages">
<div *ngFor="let msg of messages" [class.user]="msg.role === 'user'">
<strong>{{ msg.role }}</strong>: {{ msg.content }}
</div>
</div>
<textarea
[(ngModel)]="userMessage"
(keyup.enter)="sendMessage()"
placeholder="Type message..."
></textarea>
<button (click)="sendMessage()" [disabled]="!userMessage">Send</button>
<button
*ngIf="hasMoreMessages && !isLoadingHistory"
(click)="loadOlderMessages()"
>
← Load Older Messages
</button>
<p *ngIf="isLoadingHistory">Loading...</p>
</div>
`,
})
export class CustomChatComponent implements OnInit, OnDestroy {
private session = inject(DirectivSysSessionService);
messages: any[] = [];
userMessage = '';
hasMoreMessages = false;
isLoadingHistory = false;
ngOnInit() {
// Initialize session
this.session.connect({
currentContext: {
userId: 'user-123',
currentPage: 'CustomChat',
},
onIntentDetected: async (intent) => {
console.log('Intent:', intent);
return { status: 'success' };
},
});
// Subscribe to state changes
this.session.state$.subscribe((state) => {
this.messages = state.messages;
this.hasMoreMessages = state.hasMoreMessages;
this.isLoadingHistory = state.isLoadingHistory;
});
}
async sendMessage() {
if (!this.userMessage.trim()) return;
try {
await this.session.sendChatQuery(this.userMessage);
this.userMessage = '';
} catch (error) {
console.error('Failed to send message:', error);
}
}
async loadOlderMessages() {
try {
await this.session.loadMoreMessages();
} catch (error) {
console.error('Failed to load history:', error);
}
}
ngOnDestroy() {
this.session.dispose();
}
}Available Methods & Properties
// Properties
session.state$: Observable<ConversationState>
session.snapshot: ConversationState
// Methods
session.connect(options: ConnectOptions): Promise<void>
session.sendChatQuery(query: string): Promise<void>
session.loadMoreMessages(): Promise<void>
session.clearMessages(): Promise<void>
session.startVoiceInput(): Promise<void>
session.stopVoiceInput(): Promise<void>
session.dispose(): void
// ConversationState interface
interface ConversationState {
messages: Message[];
isLoading: boolean;
error: string | null;
isListening: boolean;
sessionId: string | null;
hasMoreMessages: boolean;
isLoadingHistory: boolean;
}Theming & Customization
Global Theme
Apply theme to all components:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `<router-outlet></router-outlet>`,
styles: [`
:host {
--primary-color: #007bff;
--secondary-color: #6c757d;
--success-color: #28a745;
--danger-color: #dc3545;
--warning-color: #ffc107;
--info-color: #17a2b8;
--light-color: #f8f9fa;
--dark-color: #343a40;
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
--text-primary: #333333;
--text-secondary: #666666;
--background-primary: #ffffff;
--background-secondary: #f5f5f5;
--border-color: #e0e0e0;
}
`],
})
export class AppComponent {}Component-Level Theme
Override theme for specific component:
const customTheme = {
colors: {
primary: '#007bff',
secondary: '#6c757d',
background: '#ffffff',
text: '#333333',
border: '#e0e0e0',
success: '#28a745',
danger: '#dc3545',
warning: '#ffc107',
},
spacing: {
xs: '4px',
sm: '8px',
md: '16px',
lg: '24px',
xl: '32px',
},
typography: {
fontFamily: 'system-ui, -apple-system, sans-serif',
fontSize: '14px',
fontWeight: '400',
lineHeight: '1.5',
},
};
<directivsys-analytics-dashboard
[theme]="customTheme"
></directivsys-analytics-dashboard>
<directivsys-reports-dashboard
[theme]="customTheme"
></directivsys-reports-dashboard>Dark Mode Example
import { Component } from '@angular/core';
@Component({
selector: 'app-dashboard',
template: `
<button (click)="toggleDarkMode()">Toggle Dark Mode</button>
<directivsys-analytics-dashboard
[theme]="isDarkMode ? darkTheme : lightTheme"
></directivsys-analytics-dashboard>
`,
})
export class DashboardComponent {
isDarkMode = false;
lightTheme = {
colors: {
primary: '#007bff',
background: '#ffffff',
text: '#333333',
border: '#e0e0e0',
},
};
darkTheme = {
colors: {
primary: '#0d6efd',
background: '#1a1a1a',
text: '#e0e0e0',
border: '#333333',
},
};
toggleDarkMode() {
this.isDarkMode = !this.isDarkMode;
}
}Advanced Usage
Custom Intent Handling
import { Component } from '@angular/core';
import { DirectivSysChatboxComponent } from '@directivsys/angular-sdk';
@Component({
selector: 'app-advanced-chat',
standalone: true,
imports: [DirectivSysChatboxComponent],
template: `
<directivsys-chatbox
[onIntentDetected]="handleComplexIntent"
[currentContext]="context"
></directivsys-chatbox>
`,
})
export class AdvancedChatComponent {
context = { userId: 'user-123' };
// Complex intent handling with different flows
handleComplexIntent = async (intent: any, files?: File[]) => {
try {
// Route based on intent type
switch (intent.type) {
case 'query':
return await this.handleQuery(intent);
case 'directive':
return await this.handleDirective(intent, files);
case 'analysis':
return await this.handleAnalysis(intent);
default:
return { status: 'unknown_intent' };
}
} catch (error) {
console.error('Intent processing failed:', error);
return {
status: 'error',
message: 'Failed to process intent',
};
}
};
private async handleQuery(intent: any) {
// Query processing
return { status: 'success', data: {} };
}
private async handleDirective(intent: any, files?: File[]) {
// Directive execution
if (files?.length) {
// Process file uploads
}
return { status: 'success', executionId: 'exec-123' };
}
private async handleAnalysis(intent: any) {
// Analysis processing
return { status: 'success', analysis: {} };
}
}Voice Input Handling
<directivsys-chatbox
[onIntentDetected]="handleIntent"
[currentContext]="context"
[voice]="true"
(onSpeechStart)="onVoiceStart()"
(onSpeechEnd)="onVoiceEnd()"
></directivsys-chatbox>
// In component
onVoiceStart() {
console.log('🎤 Listening...');
this.isListening = true;
}
onVoiceEnd() {
console.log('✓ Voice input received');
this.isListening = false;
}Error Handling
<directivsys-chatbox
[onIntentDetected]="handleIntent"
[currentContext]="context"
(onError)="handleError($event)"
></directivsys-chatbox>
// In component
handleError(error: Error) {
switch (error.constructor.name) {
case 'TimeoutError':
console.error('Request timeout');
break;
case 'NetworkError':
console.error('Network connection failed');
break;
default:
console.error('Unknown error:', error);
}
}API Reference
Core Types
// Conversation message
interface Message {
id: string;
role: 'user' | 'assistant';
content: string;
timestamp: Date;
metadata?: Record<string, any>;
}
// Conversation state
interface ConversationState {
messages: Message[];
isLoading: boolean;
error: string | null;
isListening: boolean;
sessionId: string | null;
hasMoreMessages: boolean;
isLoadingHistory: boolean;
}
// Theme configuration
interface Theme {
colors?: {
primary?: string;
secondary?: string;
background?: string;
text?: string;
border?: string;
success?: string;
danger?: string;
warning?: string;
};
spacing?: {
xs?: string;
sm?: string;
md?: string;
lg?: string;
xl?: string;
};
typography?: {
fontFamily?: string;
fontSize?: string;
fontWeight?: string;
lineHeight?: string;
};
}
// Storage adapter for custom message persistence
interface StorageAdapter {
getItem(key: string): Promise<string | null>;
setItem(key: string, value: string): Promise<void>;
removeItem(key: string): Promise<void>;
}Common Patterns
Pattern 1: Dashboard with Chat & Reports
import { Component } from '@angular/core';
import {
DirectivSysChatboxComponent,
ReportsDashboardComponent,
} from '@directivsys/angular-sdk';
@Component({
selector: 'app-integrated-dashboard',
standalone: true,
imports: [DirectivSysChatboxComponent, ReportsDashboardComponent],
template: `
<div class="dashboard-grid">
<div class="reports-section">
<directivsys-reports-dashboard></directivsys-reports-dashboard>
</div>
<div class="chat-section">
<directivsys-chatbox
[onIntentDetected]="handleIntent"
[currentContext]="context"
renderMode="basic"
[height]="'100%'"
></directivsys-chatbox>
</div>
</div>
`,
styles: [`
.dashboard-grid {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 20px;
height: 100vh;
}
.reports-section,
.chat-section {
overflow: auto;
border: 1px solid #e0e0e0;
border-radius: 8px;
}
`],
})
export class IntegratedDashboardComponent {
context = { userId: 'user-123' };
handleIntent = async (intent: any) => {
// Sync between chat and reports
return { status: 'success' };
};
}Pattern 2: Analytics with Custom Filters
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AnalyticsDashboardComponent } from '@directivsys/angular-sdk';
@Component({
selector: 'app-filtered-analytics',
standalone: true,
imports: [FormsModule, AnalyticsDashboardComponent],
template: `
<div class="analytics-wrapper">
<div class="filters">
<select [(ngModel)]="selectedDepartment">
<option value="all">All Departments</option>
<option value="operations">Operations</option>
<option value="sales">Sales</option>
<option value="engineering">Engineering</option>
</select>
<select [(ngModel)]="selectedPeriod">
<option value="day">Today</option>
<option value="week">This Week</option>
<option value="month">This Month</option>
</select>
<button (click)="applyFilters()">Apply</button>
</div>
<directivsys-analytics-dashboard
*ngIf="showDashboard"
></directivsys-analytics-dashboard>
</div>
`,
})
export class FilteredAnalyticsComponent {
selectedDepartment = 'all';
selectedPeriod = 'month';
showDashboard = true;
applyFilters() {
// Trigger dashboard refresh
this.showDashboard = false;
setTimeout(() => {
this.showDashboard = true;
}, 100);
}
}Troubleshooting
Issue: Chat Widget Not Appearing
Solution: Check that DirectivSysChatboxComponent is imported in your component
// ✅ Correct
import { DirectivSysChatboxComponent } from '@directivsys/angular-sdk';
@Component({
imports: [DirectivSysChatboxComponent], // Must include in imports
standalone: true,
})
export class MyComponent {}Issue: "onIntentDetected is not a function"
Solution: Ensure you're passing a function (arrow function or method)
// ✅ Correct
handleIntent = async (intent: any) => {
return { status: 'success' };
};
<directivsys-chatbox
[onIntentDetected]="handleIntent"
></directivsys-chatbox>
// ❌ Wrong
<directivsys-chatbox
onIntentDetected="handleIntent" // String instead of function
></directivsys-chatbox>Issue: Messages Not Persisting
Solution: Messages are saved to localStorage by default. Check browser storage limits
// Check localStorage
console.log(localStorage.getItem('directivsys_chat_user-123'));
// For SSR, provide custom storage adapter
<directivsys-chatbox
[storageAdapter]="databaseStorage"
></directivsys-chatbox>Issue: Theme Not Applied
Solution: Ensure theme object matches expected structure
// ✅ Correct
const theme = {
colors: {
primary: '#007bff',
background: '#ffffff',
},
};
// ❌ Wrong
const theme = { primary: '#007bff' }; // Missing colors objectIssue: High Memory Usage
Solution: Ensure proper cleanup with ngOnDestroy
export class MyComponent implements OnDestroy {
private session = inject(DirectivSysSessionService);
ngOnDestroy() {
this.session.dispose(); // Clean up
}
}FAQ
Q: Can I use multiple chat components on the same page?
A: Yes. Each component maintains its own session state. Use different storageAdapter keys for each to isolate messages.
Q: How do I customize component styling?
A: Use the theme input prop. All components support theme customization.
Q: Is SSR supported?
A: Yes, with a custom StorageAdapter. The default localStorage won't work on server, but components handle it gracefully.
Q: Can I use components in NgModules? A: Yes! Components are standalone but work in NgModule imports too.
Q: What's the maximum message history size? A: Default is 50 messages per conversation. Configure in storage adapter.
Q: Do components support internationalization (i18n)? A: Components use English by default. Customize text via component props/theme.
Q: Can I disable voice input?
A: Yes, set [voice]="false" on chatbox component.
Q: How do I handle file uploads on backend?
A: Use the files parameter in handleIntent callback to upload to your server.
Additional Resources
- COMPONENTS_INVENTORY.md - Complete component reference
- ARCHITECTURE.md - Technical architecture guide
- IMPLEMENTATION_SUMMARY.md - Implementation details
- DirectivSys Docs - Main documentation
Support
- 📧 Email: [email protected]
- 💬 Slack: Community Channel
- 🐛 Issues: GitHub Issues
