feat(frontend): système de plugins — runtime, menus, layouts custom (#43)
Lots F1-F4 : runtime de chargement/registre plugin, extension des menus existants, panneau de gestion des plugins, types de layout custom (sélecteur, fallback, cellule dédiée) branchés sur le port plugin. Suite npm typecheck/test verte (947/947). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
36
frontend/src/features/plugins/layoutAvailability.ts
Normal file
36
frontend/src/features/plugins/layoutAvailability.ts
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Plugin layout availability resolution (ticket #43, F4, carnet v2 §3.4).
|
||||
*
|
||||
* A `customPluginLayout` top-level {@link LayoutNode} is opaque domain state —
|
||||
* the provider plugin may be missing, disabled, or incompatible with the
|
||||
* running IdeA version at any given session. Availability is never stored in
|
||||
* the layout itself; it's derived here, purely, from the loaded runtime
|
||||
* registry, so it's trivially testable without React.
|
||||
*/
|
||||
|
||||
import type { CustomPluginLayoutCell, PluginAdmin, PluginLayoutAvailability } from "@/domain";
|
||||
import type { PluginRuntimeRegistry } from "@/plugins/runtime";
|
||||
|
||||
export function resolvePluginLayoutAvailability(
|
||||
registry: PluginRuntimeRegistry,
|
||||
cell: CustomPluginLayoutCell,
|
||||
/**
|
||||
* Optional admin list (from `PluginGateway.listPlugins()`) to tell "known but
|
||||
* disabled" apart from "not installed at all" — the runtime registry alone
|
||||
* only ever holds *loaded* (enabled) plugins (carnet §1.3), so it can't make
|
||||
* that distinction by itself. Omit it to fall back to "plugin-missing" for
|
||||
* both cases (still correct, just less precise fallback copy).
|
||||
*/
|
||||
installedPlugins?: PluginAdmin[],
|
||||
): PluginLayoutAvailability {
|
||||
const plugin = registry.get(cell.pluginId);
|
||||
if (!plugin) {
|
||||
const known = installedPlugins?.find((p) => p.id === cell.pluginId);
|
||||
return known && !known.enabled ? "plugin-disabled" : "plugin-missing";
|
||||
}
|
||||
const declaresType = plugin.contributes.layouts.some((l) => l.type === cell.layoutType);
|
||||
if (!declaresType) return "incompatible";
|
||||
const component = plugin.layouts.get(cell.layoutType);
|
||||
if (!component) return "incompatible";
|
||||
return "available";
|
||||
}
|
||||
Reference in New Issue
Block a user