update owliver skill
This commit is contained in:
@@ -6,6 +6,10 @@ import {
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { ProgressBar, toneForScore } from '@/components/ds/Progress';
|
||||
import { SECTION_COMPONENTS } from '@/components/skills/SkillSections';
|
||||
import { useSkillDataContext } from '@/components/skills/SkillSurface';
|
||||
import { resolveSkillData } from '@/lib/skills/dataResolver';
|
||||
import { usePageAction } from './PageContext';
|
||||
|
||||
/**
|
||||
* Renderers for response blocks.
|
||||
@@ -441,8 +445,55 @@ const NoteBlock = React.memo(({ block }) => (
|
||||
));
|
||||
NoteBlock.displayName = 'NoteBlock';
|
||||
|
||||
/**
|
||||
* A section a skill declared, drawn by the component the page uses for it.
|
||||
*
|
||||
* There is no chat-specific renderer for a skill's shapes, and there must not
|
||||
* be: `SECTION_COMPONENTS` is the single table from a declared type to a
|
||||
* component, and this block goes through it exactly as `SkillSurface` does. A
|
||||
* definition that gains a new shape gains it in both places at once, and a
|
||||
* shape the table does not carry renders nothing rather than something
|
||||
* improvised.
|
||||
*/
|
||||
const SkillSectionBlock = React.memo(({ block }) => {
|
||||
const section = block.section;
|
||||
const Component = SECTION_COMPONENTS[section?.shape || section?.type];
|
||||
|
||||
/**
|
||||
* A settable answer is re-read, never replayed.
|
||||
*
|
||||
* An ordinary answer is a record of what was true when it was given, and the
|
||||
* stored blocks are exactly right for that. A section offering *controls* is
|
||||
* different: it is a live view of a value the reader can still change, from
|
||||
* here or on the page behind the panel. Replaying the stored copy would show
|
||||
* a weight of 25% next to a form that now says 30%, and the control would
|
||||
* write the stale figure back.
|
||||
*
|
||||
* So an editable section resolves from the current context on every render,
|
||||
* through the same resolver the page's own card uses. There is one value and
|
||||
* one place it lives; this is a second window onto it, not a second copy.
|
||||
*/
|
||||
const live = Boolean(section?.editable);
|
||||
const context = useSkillDataContext(null);
|
||||
const data = React.useMemo(
|
||||
() => (live && section ? resolveSkillData(section, context) : block.data),
|
||||
[live, section, context, block.data]
|
||||
);
|
||||
const apply = usePageAction(live ? section?.source : null);
|
||||
|
||||
if (!Component) return null;
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border border-border bg-surface-subtle/60 p-3">
|
||||
<Component data={data} section={section} onApply={apply} compact />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
SkillSectionBlock.displayName = 'SkillSectionBlock';
|
||||
|
||||
const RENDERERS = {
|
||||
text: TextBlock,
|
||||
skillSection: SkillSectionBlock,
|
||||
heading: HeadingBlock,
|
||||
kpis: KpisBlock,
|
||||
status: StatusBlock,
|
||||
|
||||
Reference in New Issue
Block a user