import { ConfigMetadata } from '../core'; /** * Central registry for web components with enhanced metadata. * * The WebComponentRegistry provides a way to associate rich metadata with web components, * making them discoverable and configurable within the Lime CRM platform. While most * custom elements don't require registration, registering a component allows it to: * - Appear in component selection UIs with titles and descriptions * - Show a custom icon where components are picked * - Be tagged for context-aware filtering and organization * - Expose configuration interfaces for end-user customization * * Registration is particularly useful for: * - Dashboard widgets and panels * - Configurable custom views * - Plugin components that need discovery * - Extension points with metadata-driven UIs * * Components are registered by their tag name and can include metadata like title, * description, icon, tags, and optional configuration UI components. * * @example * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const registry = platform.get(PlatformServiceName.WebComponentRegistry); * * registry.register('sales-dashboard', { * title: 'Sales Dashboard', * description: 'Real-time overview of sales metrics', * icon: 'chart-line', * tags: ['start-page'], * }); * * const components = registry.getAll(); * ``` * * @see {@link WebComponentMetadata} for metadata structure * @see {@link ConfigMetadata} for inherited metadata properties * * @public * @group Web components */ export interface WebComponentRegistry { /** * Registers a web component with optional metadata. * * This method associates the component tag name with metadata that can be used * for discovery, display, and configuration purposes. The metadata includes * human-readable information like title and description, as well as organizational * data like icons and tags. * * Register during application setup, before any UI reads the registry. * A component that registers itself when it loads can never appear in the * picker used to choose it, because that picker lists components which have * not been created yet. * * If the same name is registered more than once, the last registration wins. * * @param name - The tag name of the web component (e.g., 'sales-dashboard'). * Must match the actual custom element tag name. * @param config - Optional metadata configuration for the component. * Includes title, description, icon, tags, and configuration UI settings. * If omitted, only the component name is registered. * * @example * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const registry = platform.get(PlatformServiceName.WebComponentRegistry); * * registry.register('my-list-view', { * title: 'List', * description: 'View your items in a simple and organized list format', * icon: { name: 'activity_feed_2' }, * tags: ['explorer-view'], * configComponent: { * name: 'my-list-view-configuration', * }, * }); * ``` * * @see {@link WebComponentMetadata} */ register(name: string, config?: Omit): void; /** * Retrieves all registered web components with their metadata. * * This method returns the complete list of components that have been registered * with the registry, including all their metadata. This is useful for: * - Building component selection UIs * - Displaying available widgets in configuration screens * - Filtering and organizing components by tags * * The returned array includes both components registered with full metadata * and those registered with just a name. * * @returns An array of {@link WebComponentMetadata} objects representing all * registered components. * * @example * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const registry = platform.get(PlatformServiceName.WebComponentRegistry); * * const startPageWidgets = registry * .getAll() * .filter((component) => component.tags?.includes('start-page')); * * const salesDashboard = registry * .getAll() * .find((component) => component.name === 'sales-dashboard'); * ``` * * @see {@link WebComponentMetadata} */ getAll(): WebComponentMetadata[]; } /** * Metadata describing a registered web component. * * This type extends {@link ConfigMetadata} to include the component's tag name, * providing a complete description of a web component for discovery and configuration * purposes within the Lime CRM platform. * * The metadata combines: * - Component identity (name/tag) * - Display information (title, description, icon) * - Organizational data (tags) * - Configuration interface (optional configComponent) * * @example * ```ts * import { WebComponentMetadata } from '@limetech/lime-web-components'; * * // Everything a dashboard widget can declare * const widgetMetadata: WebComponentMetadata = { * name: 'revenue-chart', * title: 'Revenue Chart', * description: 'Monthly revenue trends with year-over-year comparison', * icon: 'chart-area', * tags: ['start-page', 'card-widget'], * configComponent: { * name: 'revenue-chart-config', * props: { * timeRange: '12months', * includeComparison: true, * }, * }, * }; * * // Only `name` is required * const simpleMetadata: WebComponentMetadata = { * name: 'hello-world', * title: 'Hello World Widget', * }; * ``` * * @see {@link ConfigMetadata} for inherited properties * @see {@link WebComponentRegistry.register} for registration * * @public * @group Web components */ export type WebComponentMetadata = ConfigMetadata & { /** * The tag name of the web component. * * This is the custom element tag name used in HTML (e.g., 'sales-dashboard'). * It must match the tag defined in the component's `@Component` decorator. * * Tag names must follow custom element naming rules: * - Contain at least one hyphen (-) * - Start with a lowercase letter * - Not be a reserved name */ name: string; };