refactor(block-h): message block types resolve via plugin-contributable registry
This commit is contained in:
@@ -6,14 +6,8 @@ import ImageBlock from './ImageBlock';
|
|||||||
import AudioBlock from './AudioBlock';
|
import AudioBlock from './AudioBlock';
|
||||||
import VideoBlock from './VideoBlock';
|
import VideoBlock from './VideoBlock';
|
||||||
import FileBlock from './FileBlock';
|
import FileBlock from './FileBlock';
|
||||||
import ActionCardBlock from './ActionCardBlock';
|
import { getBlockComponent } from './registry';
|
||||||
import ContactCardBlock from './ContactCardBlock';
|
import './registrations'; // plugin-contributed block registrations
|
||||||
import MiniAppBlock from './MiniAppBlock';
|
|
||||||
import AgentResultBlock from './AgentResultBlock';
|
|
||||||
import ApprovalRequestBlock from './ApprovalRequestBlock';
|
|
||||||
import TaskCardBlock from './TaskCardBlock';
|
|
||||||
import WorkflowCardBlock from './WorkflowCardBlock';
|
|
||||||
import KnowledgeCardBlock from './KnowledgeCardBlock';
|
|
||||||
|
|
||||||
interface BlockRendererProps {
|
interface BlockRendererProps {
|
||||||
blocks: MessageBlock[];
|
blocks: MessageBlock[];
|
||||||
@@ -51,23 +45,13 @@ const BlockRenderer: React.FC<BlockRendererProps> = ({ blocks }) => {
|
|||||||
return <VideoBlock block={block} />;
|
return <VideoBlock block={block} />;
|
||||||
case 'file':
|
case 'file':
|
||||||
return <FileBlock block={block} />;
|
return <FileBlock block={block} />;
|
||||||
case 'action_card':
|
default: {
|
||||||
return <ActionCardBlock block={block} />;
|
// Plugin-contributed block types (Block H / HC-F)
|
||||||
case 'contact_card':
|
const Contributed = getBlockComponent(block.block_type);
|
||||||
return <ContactCardBlock block={block} />;
|
if (Contributed) {
|
||||||
case 'miniapp':
|
const ContributedBlock = Contributed as React.FC<{ block: MessageBlock }>;
|
||||||
return <MiniAppBlock block={block} />;
|
return <ContributedBlock block={block} />;
|
||||||
case 'agent_result':
|
}
|
||||||
return <AgentResultBlock block={block} />;
|
|
||||||
case 'approval_request':
|
|
||||||
return <ApprovalRequestBlock block={block} />;
|
|
||||||
case 'task_card':
|
|
||||||
return <TaskCardBlock block={block} />;
|
|
||||||
case 'workflow_card':
|
|
||||||
return <WorkflowCardBlock block={block} />;
|
|
||||||
case 'knowledge_card':
|
|
||||||
return <KnowledgeCardBlock block={block} />;
|
|
||||||
default:
|
|
||||||
// Fallback for unknown block types
|
// Fallback for unknown block types
|
||||||
return (
|
return (
|
||||||
<div className="text-xs text-secondary-400 italic p-2 rounded bg-secondary-50">
|
<div className="text-xs text-secondary-400 italic p-2 rounded bg-secondary-50">
|
||||||
@@ -75,6 +59,7 @@ const BlockRenderer: React.FC<BlockRendererProps> = ({ blocks }) => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* Plugin block registrations.
|
||||||
|
*
|
||||||
|
* Currently a static import list; the dynamic plugin loader (ARCH-019 fix)
|
||||||
|
* will replace this file with manifest-driven registration. Plugins register
|
||||||
|
* their block renderers via ``registerBlockType`` with an owner tag so that
|
||||||
|
* ``unregisterBlockTypes(owner)`` can clean up on deactivation.
|
||||||
|
*/
|
||||||
|
import { registerBlockType } from './registry';
|
||||||
|
import ActionCardBlock from './ActionCardBlock';
|
||||||
|
import ContactCardBlock from './ContactCardBlock';
|
||||||
|
import MiniAppBlock from './MiniAppBlock';
|
||||||
|
import AgentResultBlock from './AgentResultBlock';
|
||||||
|
import ApprovalRequestBlock from './ApprovalRequestBlock';
|
||||||
|
import TaskCardBlock from './TaskCardBlock';
|
||||||
|
import WorkflowCardBlock from './WorkflowCardBlock';
|
||||||
|
import KnowledgeCardBlock from './KnowledgeCardBlock';
|
||||||
|
|
||||||
|
registerBlockType('action_card', ActionCardBlock, 'core-comm');
|
||||||
|
registerBlockType('contact_card', ContactCardBlock, 'contacts');
|
||||||
|
registerBlockType('miniapp', MiniAppBlock, 'kommunikation');
|
||||||
|
registerBlockType('agent_result', AgentResultBlock, 'automation');
|
||||||
|
registerBlockType('approval_request', ApprovalRequestBlock, 'core-approvals');
|
||||||
|
registerBlockType('task_card', TaskCardBlock, 'tasks');
|
||||||
|
registerBlockType('workflow_card', WorkflowCardBlock, 'workflows');
|
||||||
|
registerBlockType('knowledge_card', KnowledgeCardBlock, 'knowledge');
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* Message block type registry.
|
||||||
|
*
|
||||||
|
* Core owns the base block types; plugins can contribute additional block
|
||||||
|
* renderers via ``registerBlockType`` / ``unregisterBlockTypes`` during their
|
||||||
|
* frontend activation lifecycle (Block H / HC-F).
|
||||||
|
*/
|
||||||
|
import type { ComponentType } from 'react';
|
||||||
|
import type { MessageBlock } from '@/store/commStore';
|
||||||
|
|
||||||
|
export type BlockComponent = ComponentType<{ block: MessageBlock }>;
|
||||||
|
|
||||||
|
const _registry = new Map<string, BlockComponent>();
|
||||||
|
|
||||||
|
export function registerBlockType(blockType: string, component: BlockComponent, owner = ''): void {
|
||||||
|
if (_registry.has(blockType)) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn(`[blockRegistry] block type '${blockType}' re-registered by '${owner || 'unknown'}' — overwriting`);
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(component as any).__block_owner__ = owner;
|
||||||
|
_registry.set(blockType, component);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unregisterBlockTypes(owner: string): void {
|
||||||
|
for (const [key, component] of _registry.entries()) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
if ((component as any).__block_owner__ === owner) {
|
||||||
|
_registry.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBlockComponent(blockType: string): BlockComponent | undefined {
|
||||||
|
return _registry.get(blockType);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user