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:
@ -15,6 +15,7 @@ import { useEffect, useRef, useState } from "react";
|
||||
|
||||
import type { LayoutInfo } from "@/domain";
|
||||
import { cn } from "@/shared";
|
||||
import { PluginLayoutSelectorSection, usePluginRuntime } from "@/features/plugins";
|
||||
import { useLayouts } from "./useLayouts";
|
||||
|
||||
interface LayoutTabsProps {
|
||||
@ -43,6 +44,10 @@ export function LayoutTabs({ projectId, onActiveLayoutChange }: LayoutTabsProps)
|
||||
const renameInputRef = useRef<HTMLInputElement | null>(null);
|
||||
// Show/hide the create-kind dropdown.
|
||||
const [showCreateMenu, setShowCreateMenu] = useState(false);
|
||||
const { registry: pluginRegistry } = usePluginRuntime();
|
||||
// Plugin layouts need a `create_layout` backend extension that doesn't exist
|
||||
// yet (#43, F4 open point) — surfaced rather than silently swallowed.
|
||||
const [pluginLayoutNotice, setPluginLayoutNotice] = useState<string | null>(null);
|
||||
|
||||
async function handleSelect(id: string) {
|
||||
// The effect above propagates the new active layout (id + kind) to the parent.
|
||||
@ -196,13 +201,22 @@ export function LayoutTabs({ projectId, onActiveLayoutChange }: LayoutTabsProps)
|
||||
>
|
||||
⎇ Git graph
|
||||
</button>
|
||||
<PluginLayoutSelectorSection
|
||||
registry={pluginRegistry}
|
||||
onSelect={(choice) => {
|
||||
setShowCreateMenu(false);
|
||||
setPluginLayoutNotice(
|
||||
`« ${choice.layout.label} » (${choice.pluginDisplayName}) : la création de layouts plugins nécessite une extension backend pas encore livrée.`,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{vm.error && (
|
||||
{(vm.error || pluginLayoutNotice) && (
|
||||
<span className="ml-2 text-xs text-danger" role="alert">
|
||||
{vm.error}
|
||||
{vm.error ?? pluginLayoutNotice}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user