Lot en un seul commit: les deux features partagent les mêmes contrats (domain/settings.rs, DTO, commandes Tauri/HTTP, web-server) et les mêmes surfaces UI — la séparation par fichiers était impossible sans chirurgie de hunks risquant des états intermédiaires non compilables (convention lot des batches #310-#313 et #315). #325 — icône configurable par projet, watermark CLI custom: - domaine: ProjectIconSet (devicon, simple-icons, lucide, idea), ProjectIconRef validé (nom ASCII 1..=64, -_. internes), champ icon optionnel sur ProjectSettings; sérialisation camelCase et try_from strict - application: UpdateProjectSettings.execute accepte un patch theme_color OU icon (absent = inchangé, null = défaut produit), tests in-dependants avec store mémoire - backend/app-tauri/web-server: ProjectIconRefDto, UpdateProjectSettingsRequestDto avec icon optionnel (désérialisation additive), commandes update_project_settings alignées Tauri/HTTP, tests DTO et HTTP (défaut null, set, clear, nom invalide rejeté) - frontend: catalogue projectIcons (recherche EN), ProjectIconPicker en grille multi-lignes dans Paramètres projet, affichage de l'icône dans ProjectTabs et watermark grand format à faible opacité en fond de CLI custom; ports ProjectSettings.icon, Partial<ProjectSettings>, adapters tauri/mock/http et tests alignés #326 — localisation FR/EN et traduction des textes IdeA: - domaine: IdeaLanguage (fr | en), champ language optionnel sur IdeaUserSettings (absence = défaut produit, série additive validée) - backend/web-server: UserSettingsDto.language, update_user_settings accepte language, tests HTTP alignés; fixtures structured_launch_d3 mises à jour - frontend: i18n/ (catalogue FR/EN, I18nProvider, scan anti-régression des sources visibles), GeneralSettings avec sélecteur de langue dans les paramètres, setupI18n dans vitest; migration de l'ensemble des textes hardcodés vers le catalogue sur toutes les surfaces (agents, layout, projets, tickets, sprints, web, plugins, permissions, git, templates, skills, mémoire, model servers, embedder, first-run, devices, scheduled tasks, workstate, dialogs), FR conservé par défaut; recherche d'icônes #325 en anglais conformément au ticket QA verte sur feature/batch-325-326-project-icons-localisation. Aucun push.
61 lines
2.4 KiB
TypeScript
61 lines
2.4 KiB
TypeScript
/** React bootstrap: mounts the app inside the DI provider. */
|
|
|
|
import React from "react";
|
|
import ReactDOM from "react-dom/client";
|
|
|
|
import { App } from "./App";
|
|
import { PluginLayoutWindow, ViewWindow, parseViewWindowParams } from "./ViewWindow";
|
|
import { WebApp, WebSurfaceWindow, parseWebSurfaceWindowParams } from "@/features/web";
|
|
import { DIProvider, resolveTransport } from "./di";
|
|
import { RootErrorBoundary, installGlobalErrorLogging } from "./RootErrorBoundary";
|
|
import { I18nProvider } from "@/i18n";
|
|
import "@/shared/styles/theme.css";
|
|
|
|
const root = document.getElementById("root");
|
|
if (!root) {
|
|
throw new Error("missing #root element");
|
|
}
|
|
|
|
// #23/#47: a detached view window loads the SPA with `?panel=` (panel-only, no
|
|
// project id). When the param is present and valid, render only that view — it
|
|
// follows the main window's focused project; otherwise the full app.
|
|
const viewParams = parseViewWindowParams(window.location.search);
|
|
const webSurfaceParams = parseWebSurfaceWindowParams(window.location.search);
|
|
|
|
// Ticket #74, F1: publish the transport this bundle was built for. `define`
|
|
// inlines it as a literal, and assigning it is a side effect, so it survives
|
|
// minification and tree-shaking — a built bundle can be identified (by QA, or
|
|
// from devtools) without grepping for a minified symbol. Both adapter sets ship
|
|
// in either bundle, so their mere presence proves nothing.
|
|
(window as unknown as { __IDEA_TRANSPORT__?: string }).__IDEA_TRANSPORT__ =
|
|
__IDEA_TRANSPORT__;
|
|
|
|
// Ticket #13, F2: in web (HTTP) transport mode the browser client renders the
|
|
// pairing-gated, read-only `WebApp`. Desktop (Tauri) is unchanged — it renders
|
|
// the full `App` (or a detached view window). Detached windows are desktop-only.
|
|
const isWeb = resolveTransport() === "http";
|
|
|
|
installGlobalErrorLogging();
|
|
|
|
ReactDOM.createRoot(root).render(
|
|
<React.StrictMode>
|
|
<RootErrorBoundary>
|
|
<DIProvider>
|
|
<I18nProvider>
|
|
{isWeb && webSurfaceParams ? (
|
|
<WebSurfaceWindow params={webSurfaceParams} />
|
|
) : isWeb ? (
|
|
<WebApp />
|
|
) : viewParams?.kind === "panel" ? (
|
|
<ViewWindow panel={viewParams.panel} />
|
|
) : viewParams?.kind === "pluginLayout" ? (
|
|
<PluginLayoutWindow plugin={viewParams.plugin} />
|
|
) : (
|
|
<App />
|
|
)}
|
|
</I18nProvider>
|
|
</DIProvider>
|
|
</RootErrorBoundary>
|
|
</React.StrictMode>,
|
|
);
|