@mounaji_npm/knowledge-base
v0.4.2
Published
Knowledge base and document management UI components for Mounaji-based projects
Maintainers
Readme
@mounaji_npm/knowledge-base
Document management and RAG (Retrieval-Augmented Generation) upload UI components for Mounaji-based projects. Styled via @mounaji_npm/tokens.
Install
npm install @mounaji_npm/tokens @mounaji_npm/knowledge-baseQuick Start
import { TokensProvider } from '@mounaji_npm/tokens';
import { UploadZone, DocumentList, EmbeddingStatus } from '@mounaji_npm/knowledge-base';
export default function KnowledgeBasePage() {
const [docs, setDocs] = useState([]);
const [uploading, setUploading] = useState(false);
async function handleUpload(files) {
setUploading(true);
const formData = new FormData();
files.forEach(f => formData.append('files', f));
const result = await fetch('/api/documents', { method: 'POST', body: formData }).then(r => r.json());
setDocs(prev => [...prev, ...result.documents]);
setUploading(false);
}
return (
<TokensProvider>
<UploadZone
accept=".pdf,.txt,.md,.docx"
onUpload={handleUpload}
loading={uploading}
/>
<DocumentList
documents={docs}
onDelete={(id) => setDocs(prev => prev.filter(d => d.id !== id))}
/>
</TokensProvider>
);
}Components
UploadZone
Drag-and-drop file upload zone with click-to-browse fallback.
import { UploadZone } from '@mounaji_npm/knowledge-base';
<UploadZone
accept=".pdf,.txt,.md,.docx,.xlsx"
multiple={true}
maxSize={20}
onUpload={(files) => handleUpload(files)}
loading={isUploading}
/>| Prop | Type | Default | Description |
|---|---|---|---|
| accept | string | '*' | File types (HTML accept format) |
| multiple | boolean | true | Allow multiple files at once |
| maxSize | number | 50 | Max file size in MB per file |
| onUpload | function | — | (files: File[]) => void — called after file selection |
| loading | boolean | false | Shows loading overlay on the zone |
Drag-and-drop behavior: files dragged over the zone trigger a highlight state. On drop, onUpload is called with the File[] array. Invalid files (wrong type or oversized) are filtered out and a warning is shown.
DocumentList
Stacked list of DocumentCard components.
import { DocumentList } from '@mounaji_npm/knowledge-base';
<DocumentList
documents={documents}
onDelete={(id) => handleDelete(id)}
onView={(doc) => openPreview(doc)}
loading={isFetching}
emptyState={<p>No documents yet. Upload your first file above.</p>}
/>| Prop | Type | Default | Description |
|---|---|---|---|
| documents | array | [] | Document objects (see shape below) |
| onDelete | function | — | (id: string) => void |
| onView | function | — | (doc: object) => void |
| loading | boolean | false | Shows skeleton rows |
| emptyState | ReactNode | default | Shown when list is empty |
DocumentCard
Single document row with file type icon, status indicator, and metadata.
import { DocumentCard } from '@mounaji_npm/knowledge-base';
<DocumentCard
document={{
id: 'doc_1',
name: 'Q4 Report.pdf',
type: 'pdf',
size: 2048000, // bytes
status: 'ready', // 'uploading' | 'processing' | 'ready' | 'error'
chunks: 42,
createdAt: '2026-04-20T10:00:00Z',
}}
onDelete={(id) => handleDelete(id)}
onView={(doc) => openPreview(doc)}
/>Document object shape:
| Field | Type | Description |
|---|---|---|
| id | string | Unique identifier |
| name | string | File name with extension |
| type | string | pdf txt md docx xlsx csv |
| size | number | File size in bytes — auto-formatted (KB/MB) |
| status | string | uploading processing ready error |
| chunks | number | Number of embedding chunks |
| createdAt | string | ISO date string |
Status colors:
| Status | Color |
|---|---|
| ready | Green |
| processing | Blue (pulsing) |
| uploading | Yellow |
| error | Red |
EmbeddingStatus
Progress bar showing the embedding/processing status of a document or batch.
import { EmbeddingStatus } from '@mounaji_npm/knowledge-base';
// Single document processing
<EmbeddingStatus status="processing" progress={65} label="Embedding chunks…" />
// Completed
<EmbeddingStatus status="ready" progress={100} label="Ready" />
// Error state
<EmbeddingStatus status="error" label="Processing failed" />| Prop | Type | Default | Description |
|---|---|---|---|
| status | string | 'processing' | uploading processing ready error |
| progress | number | 0 | 0–100 |
| label | string | — | Status message |
Full Example with API Integration
import { useState, useEffect } from 'react';
import { TokensProvider } from '@mounaji_npm/tokens';
import { UploadZone, DocumentList, EmbeddingStatus } from '@mounaji_npm/knowledge-base';
export default function KnowledgeBasePage({ knowledgeBaseId }) {
const [docs, setDocs] = useState([]);
const [uploading, setUploading] = useState(false);
const [processingDoc, setProcessingDoc] = useState(null);
useEffect(() => {
fetch(`/api/knowledge-bases/${knowledgeBaseId}/documents`)
.then(r => r.json())
.then(data => setDocs(data.documents));
}, [knowledgeBaseId]);
async function handleUpload(files) {
setUploading(true);
const formData = new FormData();
files.forEach(f => formData.append('files', f));
const { documents } = await fetch(
`/api/knowledge-bases/${knowledgeBaseId}/documents`,
{ method: 'POST', body: formData }
).then(r => r.json());
setDocs(prev => [...prev, ...documents]);
setUploading(false);
// Poll for processing status
const pending = documents.find(d => d.status === 'processing');
if (pending) pollStatus(pending.id);
}
async function pollStatus(docId) {
const interval = setInterval(async () => {
const doc = await fetch(`/api/documents/${docId}`).then(r => r.json());
setDocs(prev => prev.map(d => d.id === docId ? doc : d));
if (doc.status === 'ready' || doc.status === 'error') {
clearInterval(interval);
setProcessingDoc(null);
}
}, 2000);
}
async function handleDelete(id) {
await fetch(`/api/documents/${id}`, { method: 'DELETE' });
setDocs(prev => prev.filter(d => d.id !== id));
}
return (
<TokensProvider>
<h1>Knowledge Base</h1>
<UploadZone
accept=".pdf,.txt,.md,.docx"
onUpload={handleUpload}
loading={uploading}
/>
{processingDoc && (
<EmbeddingStatus
status="processing"
progress={processingDoc.progress}
label={`Processing ${processingDoc.name}…`}
/>
)}
<DocumentList
documents={docs}
onDelete={handleDelete}
loading={!docs.length && uploading}
/>
</TokensProvider>
);
}