Add full shell, replaceable Omics adapter and bilingual interaction
Implement approved specification #32 and tickets #33-#37. Keep host authentication server-verified and pin session interaction language. Compile scoped base selectors for browser compatibility and retain full gutters during CSS pruning.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { useI18n } from "../i18n";
|
||||
import { useState } from "react";
|
||||
import { ChevronDown, Cpu, Layers, LockKeyhole, SlidersHorizontal } from "lucide-react";
|
||||
import { Button } from "../components/ui/button";
|
||||
@@ -8,33 +9,34 @@ export function WorkingContextShelf({ context, locked, onWorkspace, onModel }: {
|
||||
context: ReturnType<typeof useWorkingContext>; locked: boolean;
|
||||
onWorkspace: (id: string) => void; onModel: (id: string) => void;
|
||||
}) {
|
||||
const { t: translate } = useI18n();
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const open = expanded || !context.ready;
|
||||
return <section className="thot-context-shelf" aria-label="Global working context">
|
||||
return <section className="thot-context-shelf" aria-label={translate("Global working context")}>
|
||||
<button className="thot-context-trigger" aria-expanded={open} aria-controls="thoth-working-context"
|
||||
onClick={() => setExpanded(!open)}>
|
||||
<SlidersHorizontal size={18} aria-hidden />
|
||||
<span className="thot-context-summary"><small>WORKING CONTEXT</small><strong>{context.workspace?.displayName ?? "Choose workspace"}<span aria-hidden> / </span>{context.model?.name ?? "Choose model"}</strong></span>
|
||||
<span className="thot-context-action">{locked && <LockKeyhole size={15} aria-hidden />}<span>{locked ? "Locked" : open ? "Close" : "Change context"}</span><ChevronDown size={16} aria-hidden /></span>
|
||||
<span className="thot-context-summary"><small>{translate("WORKING CONTEXT")}</small><strong>{context.workspace?.displayName ?? translate("Choose workspace")}<span aria-hidden> / </span>{context.model?.name ?? translate("Choose model")}</strong></span>
|
||||
<span className="thot-context-action">{locked && <LockKeyhole size={15} aria-hidden />}<span>{locked ? translate("Locked") : open ? translate("Close") : translate("Change context")}</span><ChevronDown size={16} aria-hidden /></span>
|
||||
</button>
|
||||
<div id="thoth-working-context" hidden={!open} className="thot-context-body">
|
||||
<p className="thot-context-explanation">Your last choices take precedence over installation defaults. Workspace and model are remembered independently.</p>
|
||||
<p className="thot-context-explanation">{translate("Your last choices take precedence over installation defaults. Workspace and model are remembered independently.")}</p>
|
||||
<div className="thot-context-fields">
|
||||
<label><span><Layers size={15} aria-hidden />Workspace</span>
|
||||
<select aria-label="Workspace" value={context.workspace ? context.workspaceId : ""} disabled={locked || context.loading} onChange={event => onWorkspace(event.target.value)}>
|
||||
<option value="" disabled>Choose a workspace</option>{context.workspaces.map(workspace => <option key={workspace.id} value={workspace.id}>{workspace.displayName}</option>)}
|
||||
</select><small>{context.origins.workspace}</small>
|
||||
<label><span><Layers size={15} aria-hidden />{translate("Workspace")}</span>
|
||||
<select aria-label={translate("Workspace")} value={context.workspace ? context.workspaceId : ""} disabled={locked || context.loading} onChange={event => onWorkspace(event.target.value)}>
|
||||
<option value="" disabled>{translate("Choose a workspace")}</option>{context.workspaces.map(workspace => <option key={workspace.id} value={workspace.id}>{workspace.displayName}</option>)}
|
||||
</select><small>{translate(context.origins.workspace)}</small>
|
||||
</label>
|
||||
<label><span><Cpu size={15} aria-hidden />AI interaction model</span>
|
||||
<select aria-label="Model" value={context.model ? context.modelId : ""} disabled={locked || context.loading} onChange={event => onModel(event.target.value)}>
|
||||
<option value="" disabled>Choose a model</option>{context.models.map(model => <option key={`${model.provider}/${model.id}`} value={`${model.provider}/${model.id}`}>{model.name}</option>)}
|
||||
</select><small>{context.origins.model}</small>
|
||||
<label><span><Cpu size={15} aria-hidden />{translate("AI interaction model")}</span>
|
||||
<select aria-label={translate("Model")} value={context.model ? context.modelId : ""} disabled={locked || context.loading} onChange={event => onModel(event.target.value)}>
|
||||
<option value="" disabled>{translate("Choose a model")}</option>{context.models.map(model => <option key={`${model.provider}/${model.id}`} value={`${model.provider}/${model.id}`}>{model.name}</option>)}
|
||||
</select><small>{translate(context.origins.model)}</small>
|
||||
</label>
|
||||
</div>
|
||||
{locked && <p role="status">Workspace and model are locked until the current operation finishes.</p>}
|
||||
{context.ready && context.error && <p role="status">Context refresh failed. Your current choices and unsaved work have been retained.</p>}
|
||||
{!context.ready && <p role="status">{context.loading ? "Loading working context…" : context.error ? "Working context is unavailable. Retry or ask the installation operator to check configuration." : "Select an available workspace and model to enable Core and Administration. Unavailable saved choices are not replaced automatically."}</p>}
|
||||
<div className="thot-context-footer">{context.error && <Button variant="outline" onClick={context.retry}>Retry context</Button>}{context.ready && <Button variant="outline" onClick={() => setExpanded(false)}>Done</Button>}</div>
|
||||
{locked && <p role="status">{translate("Workspace and model are locked until the current operation finishes.")}</p>}
|
||||
{context.ready && context.error && <p role="status">{translate("Context refresh failed. Your current choices and unsaved work have been retained.")}</p>}
|
||||
{!context.ready && <p role="status">{context.loading ? translate("Loading working context…") : context.error ? translate("Working context is unavailable. Retry or ask the installation operator to check configuration.") : translate("Select an available workspace and model to enable Core and Administration. Unavailable saved choices are not replaced automatically.")}</p>}
|
||||
<div className="thot-context-footer">{context.error && <Button variant="outline" onClick={context.retry}>{translate("Retry context")}</Button>}{context.ready && <Button variant="outline" onClick={() => setExpanded(false)}>{translate("Done")}</Button>}</div>
|
||||
</div>
|
||||
</section>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user