@dendelion/paper-camp 0.23.1 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/assets/{index-CKO_a_mt.js → index-B5TCF8_a.js} +2 -2
- package/dist/app/assets/{index-CKO_a_mt.js.map → index-B5TCF8_a.js.map} +1 -1
- package/dist/app/assets/{index-DC_F8eQU.js → index-BY8Yo_l0.js} +2 -2
- package/dist/app/assets/{index-DC_F8eQU.js.map → index-BY8Yo_l0.js.map} +1 -1
- package/dist/app/assets/{index-DoH_Ktpt.js → index-BxRIu8zx.js} +2 -2
- package/dist/app/assets/{index-DoH_Ktpt.js.map → index-BxRIu8zx.js.map} +1 -1
- package/dist/app/assets/{index-CFMhKXQf.js → index-C1ORGbU3.js} +2 -2
- package/dist/app/assets/{index-CFMhKXQf.js.map → index-C1ORGbU3.js.map} +1 -1
- package/dist/app/assets/{index-CeEpQji6.js → index-C3R9IAt7.js} +2 -2
- package/dist/app/assets/{index-CeEpQji6.js.map → index-C3R9IAt7.js.map} +1 -1
- package/dist/app/assets/{index-Twqzhu_o.js → index-CR8PI9q6.js} +2 -2
- package/dist/app/assets/{index-Twqzhu_o.js.map → index-CR8PI9q6.js.map} +1 -1
- package/dist/app/assets/{index-CTHTRX-O.js → index-Ddz2TPW1.js} +2 -2
- package/dist/app/assets/{index-CTHTRX-O.js.map → index-Ddz2TPW1.js.map} +1 -1
- package/dist/app/assets/{index-B0T4zOOc.js → index-rxWn42R9.js} +2 -2
- package/dist/app/assets/{index-B0T4zOOc.js.map → index-rxWn42R9.js.map} +1 -1
- package/dist/app/assets/{main-CDkrPxrg.js → main-DkQCGPBX.js} +120 -120
- package/dist/app/assets/main-DkQCGPBX.js.map +1 -0
- package/dist/app/assets/main-o2BbWpF4.css +1 -0
- package/dist/app/assets/{sidebar-section-7T-4hlR4.js → sidebar-section-Cqk2bPNP.js} +2 -2
- package/dist/app/assets/{sidebar-section-7T-4hlR4.js.map → sidebar-section-Cqk2bPNP.js.map} +1 -1
- package/dist/app/index.html +2 -2
- package/dist/app/toolbar.js +3030 -2968
- package/dist/app/toolbar.js.map +1 -1
- package/dist/cli/index.js +2526 -2522
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/app/assets/main-BAlJ6w7u.css +0 -1
- package/dist/app/assets/main-CDkrPxrg.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-B0T4zOOc.js","sources":["../../../src/app/features/roadmap/hooks/use-roadmap-page.ts","../../../src/app/features/roadmap/hooks/use-roadmap-sidebar.ts","../../../src/app/features/roadmap/modals/add-roadmap-item-modal.tsx","../../../src/app/features/roadmap/modals/promote-roadmap-item-modal.tsx","../../../src/app/features/roadmap/views/add-candidate-form.tsx","../../../src/app/features/roadmap/views/candidate-row.tsx","../../../src/app/features/roadmap/views/goal-banner.tsx","../../../src/app/features/roadmap/constants.ts","../../../src/app/features/roadmap/views/idea-row.tsx","../../../src/app/features/roadmap/views/progress-bar.tsx","../../../src/app/features/roadmap/views/roadmap-item-row.tsx","../../../src/app/features/roadmap/views/horizon-section.tsx","../../../src/app/features/roadmap/roadmap-page.tsx","../../../src/app/features/roadmap/roadmap-sidebar.tsx"],"sourcesContent":["import { useOpenEntity } from '@/app/hooks';\nimport { addRoadmapCandidate } from '@/app/services/content/docs-api';\nimport { useAppStore } from '@/app/stores/app-store';\nimport type { PlanEntry, ResolvedRoadmapItem } from '@/types/index';\nimport { useSearch } from '@tanstack/react-router';\nimport { useEffect, useRef, useState } from 'react';\nimport { filterHorizons } from '../helpers';\n\ninterface Promoting {\n horizonTitle: string;\n item: ResolvedRoadmapItem;\n candidateName?: string;\n}\n\nexport const useRoadmapPage = () => {\n const roadmap = useAppStore((s) => s.roadmap);\n const roadmapError = useAppStore((s) => s.roadmapError);\n const loadRoadmap = useAppStore((s) => s.loadRoadmap);\n const filters = useAppStore((s) => s.roadmapFilters);\n const plans = useAppStore((s) => s.plans);\n const openEntity = useOpenEntity();\n const { item: highlightedItem } = useSearch({ from: '/roadmap' });\n const containerRef = useRef<HTMLDivElement>(null);\n const [promoting, setPromoting] = useState<Promoting | null>(null);\n\n useEffect(() => {\n loadRoadmap();\n }, [loadRoadmap]);\n\n useEffect(() => {\n if (!highlightedItem || !roadmap) return;\n const row = containerRef.current?.querySelector('.roadmap-item-highlighted');\n row?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }, [highlightedItem, roadmap]);\n\n const graduatedByItem = (item: ResolvedRoadmapItem): PlanEntry[] =>\n plans?.entries.filter((p) => p.subject === item.name) ?? [];\n\n const handleAddCandidate = async (horizonTitle: string, itemName: string, name: string) => {\n await addRoadmapCandidate(horizonTitle, itemName, name);\n await loadRoadmap();\n };\n\n const handlePromote = (\n horizonTitle: string,\n item: ResolvedRoadmapItem,\n candidateName?: string,\n ) => {\n setPromoting({ horizonTitle, item, candidateName });\n };\n\n const horizons = roadmap ? filterHorizons(roadmap, filters) : [];\n const totalVisible = horizons.reduce((count, horizon) => count + horizon.items.length, 0);\n const hasActiveFilters = filters.horizons.length > 0 || filters.statuses.length > 0;\n\n return {\n roadmap,\n roadmapError,\n loadRoadmap,\n horizons,\n totalVisible,\n hasActiveFilters,\n highlightedItem,\n containerRef,\n promoting,\n setPromoting,\n graduatedByItem,\n handleAddCandidate,\n handlePromote,\n onOpenGraduated: openEntity,\n };\n};\n","import { useAppStore } from '@/app/stores/app-store';\nimport type { PlanStatus } from '@/types/index';\nimport { useState } from 'react';\nimport { horizonItemCounts, statusItemCounts } from '../helpers';\n\nconst STATUS_CHIP_ORDER: PlanStatus[] = [\n 'in-progress',\n 'review',\n 'planned',\n 'idea',\n 'done',\n 'dropped',\n];\n\nexport const useRoadmapSidebar = () => {\n const roadmap = useAppStore((s) => s.roadmap);\n const filters = useAppStore((s) => s.roadmapFilters);\n const toggleRoadmapHorizon = useAppStore((s) => s.toggleRoadmapHorizon);\n const toggleRoadmapStatus = useAppStore((s) => s.toggleRoadmapStatus);\n const [addOpen, setAddOpen] = useState(false);\n\n const horizonTitles = roadmap?.horizons.map((horizon) => horizon.title) ?? [];\n const horizonCounts = roadmap ? horizonItemCounts(roadmap, filters) : {};\n const statusCounts = roadmap ? statusItemCounts(roadmap, filters) : {};\n const activeHorizons = new Set(filters.horizons);\n const activeStatuses = new Set(filters.statuses);\n const visibleStatuses = STATUS_CHIP_ORDER.filter(\n (status) => (statusCounts[status] ?? 0) > 0 || activeStatuses.has(status),\n );\n\n return {\n roadmap,\n horizonTitles,\n horizonCounts,\n statusCounts,\n activeHorizons,\n activeStatuses,\n visibleStatuses,\n addOpen,\n setAddOpen,\n toggleRoadmapHorizon,\n toggleRoadmapStatus,\n };\n};\n","import { addRoadmapItem } from '@/app/services/content/docs-api';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { Button, Input, Modal, Select } from '@dendelion/paper-ui';\nimport { useEffect, useRef, useState } from 'react';\n\ninterface AddRoadmapItemModalProps {\n open: boolean;\n horizonTitles: string[];\n onClose: () => void;\n}\n\nexport const AddRoadmapItemModal = ({ open, horizonTitles, onClose }: AddRoadmapItemModalProps) => {\n const loadRoadmap = useAppStore((s) => s.loadRoadmap);\n const [horizon, setHorizon] = useState(horizonTitles[0] ?? '');\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const horizonTitlesRef = useRef(horizonTitles);\n horizonTitlesRef.current = horizonTitles;\n\n useEffect(() => {\n if (open) {\n setHorizon(horizonTitlesRef.current[0] ?? '');\n setName('');\n setDescription('');\n setError(null);\n setSaving(false);\n }\n }, [open]);\n\n const handleAdd = async () => {\n if (!name.trim() || !horizon) return;\n setSaving(true);\n setError(null);\n try {\n await addRoadmapItem(horizon, name.trim(), description.trim());\n await loadRoadmap();\n onClose();\n } catch (err) {\n setError((err as Error).message);\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <Modal open={open} onClose={onClose} title=\"Add roadmap item\" size=\"small\">\n <div className=\"flex flex-col gap-4\">\n <Select\n size=\"small\"\n value={horizon}\n onChange={setHorizon}\n disabled={saving}\n options={horizonTitles.map((title) => ({ value: title, label: title }))}\n />\n <Input\n size=\"small\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"Item name…\"\n disabled={saving}\n autoFocus\n />\n <Input\n size=\"small\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAdd();\n }}\n placeholder=\"Description…\"\n disabled={saving}\n />\n {error && <p className=\"m-0 text-watercolor-rose-dark text-sm\">{error}</p>}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" onClick={onClose} disabled={saving}>\n Cancel\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n onClick={handleAdd}\n disabled={saving || !name.trim() || !horizon}\n >\n {saving ? 'Adding…' : 'Add item'}\n </Button>\n </div>\n </div>\n </Modal>\n );\n};\n","import { buildRoadmapPromotePrompt } from '@/app/features/plans/prompts';\nimport { useSubjectVocabulary } from '@/app/hooks/use-subject-vocabulary';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { oneLineErrorSummary } from '@/app/utils/error-summary';\nimport type { RoadmapItem } from '@/types/index';\nimport { Button, Modal, Select, useToast } from '@dendelion/paper-ui';\nimport { useEffect, useState } from 'react';\n\nconst NO_SUBJECT = '__no-subject__';\n\ninterface PromoteRoadmapItemModalProps {\n horizonTitle: string | null;\n item: RoadmapItem | null;\n candidateName?: string | null;\n onClose: () => void;\n onPromoted: () => void;\n}\n\nexport const PromoteRoadmapItemModal = ({\n horizonTitle,\n item,\n candidateName,\n onClose,\n onPromoted,\n}: PromoteRoadmapItemModalProps) => {\n const promoteRoadmapItem = useAppStore((s) => s.promoteRoadmapItem);\n const launchIdeaExtend = useAppStore((s) => s.launchIdeaExtend);\n const { subjects, available: subjectsAvailable } = useSubjectVocabulary();\n const [subject, setSubject] = useState(NO_SUBJECT);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const { toast } = useToast();\n\n useEffect(() => {\n if (item) {\n // A candidate defaults to its parent item's name — the \"big bet becomes a\n // Subject\" rule — but the picker still lets the user override it.\n setSubject(candidateName ? item.name : NO_SUBJECT);\n setLoading(false);\n setError(null);\n }\n }, [item, candidateName]);\n\n const handlePromote = async () => {\n if (!item || !horizonTitle) return;\n setLoading(true);\n setError(null);\n try {\n const id = await promoteRoadmapItem(\n horizonTitle,\n item,\n subject === NO_SUBJECT ? undefined : subject,\n candidateName ?? undefined,\n );\n const idea = useAppStore.getState().ideaEntries.find((e) => e.id === id);\n if (idea) {\n try {\n await launchIdeaExtend(id, buildRoadmapPromotePrompt(idea, horizonTitle));\n } catch (err) {\n // The idea was created either way — a failed refine launch just means\n // no background research ran, not that the promotion itself failed.\n toast({\n title: 'Idea created, but the refine agent failed to launch',\n description: oneLineErrorSummary((err as Error).message),\n variant: 'error',\n });\n }\n }\n onPromoted();\n onClose();\n } catch (err) {\n setError((err as Error).message);\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <Modal\n open={item !== null}\n onClose={onClose}\n title={candidateName ?? item?.name ?? ''}\n size=\"small\"\n >\n <div className=\"flex flex-col gap-4\">\n {!candidateName && <p className=\"m-0 opacity-80\">{item?.description}</p>}\n <div>\n <Select\n size=\"small\"\n value={subject}\n onChange={setSubject}\n disabled={loading || !subjectsAvailable}\n options={[\n { value: NO_SUBJECT, label: 'No subject' },\n ...(!subjectsAvailable && subject !== NO_SUBJECT\n ? [{ value: subject, label: subject }]\n : []),\n ...subjects.map((s) => ({ value: s, label: s })),\n ]}\n />\n </div>\n {error && <p className=\"m-0 text-watercolor-rose-dark text-sm\">{error}</p>}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" onClick={onClose} disabled={loading}>\n Cancel\n </Button>\n <Button type=\"button\" variant=\"primary\" onClick={handlePromote} disabled={loading}>\n {loading ? 'Promoting…' : 'Promote to idea'}\n </Button>\n </div>\n </div>\n </Modal>\n );\n};\n","import { Button, Input } from '@dendelion/paper-ui';\nimport { useState } from 'react';\n\ninterface AddCandidateFormProps {\n onAdd: (name: string) => Promise<void>;\n}\n\nexport const AddCandidateForm = ({ onAdd }: AddCandidateFormProps) => {\n const [name, setName] = useState('');\n const [saving, setSaving] = useState(false);\n\n const handleAdd = async () => {\n if (!name.trim()) return;\n setSaving(true);\n try {\n await onAdd(name.trim());\n setName('');\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <div className=\"flex gap-2\">\n <Input\n size=\"small\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAdd();\n }}\n placeholder=\"Add option…\"\n disabled={saving}\n className=\"flex-1\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"small\"\n onClick={handleAdd}\n disabled={saving || !name.trim()}\n >\n Add\n </Button>\n </div>\n );\n};\n","import { Button, Card } from '@dendelion/paper-ui';\n\ninterface CandidateRowProps {\n name: string;\n onPromote: () => void;\n}\n\nexport const CandidateRow = ({ name, onPromote }: CandidateRowProps) => (\n <Card size=\"small\" texture=\"kraft\" className=\"plan-row-card\">\n <div className=\"flex items-center gap-3\">\n <span className=\"flex-1\">{name}</span>\n <Button type=\"button\" variant=\"ghost\" size=\"small\" onClick={onPromote}>\n Promote to idea\n </Button>\n </div>\n </Card>\n);\n","import { Markdown } from '@/app/components/markdown';\nimport { useState } from 'react';\n\ninterface GoalBannerProps {\n goal: string;\n}\n\nexport const GoalBanner = ({ goal }: GoalBannerProps) => {\n const [expanded, setExpanded] = useState(false);\n const [firstParagraph, ...restParagraphs] = goal.split(/\\n{2,}/);\n const hasMore = restParagraphs.length > 0;\n\n return (\n <div className=\"mb-6 pb-4 border-b border-black/[8%]\">\n <span className=\"font-handwritten text-xs font-semibold opacity-[0.55]\">The goal</span>\n <div className=\"text-sm leading-relaxed opacity-80 mt-2\">\n <Markdown>{firstParagraph}</Markdown>\n {expanded && hasMore && <Markdown>{restParagraphs.join('\\n\\n')}</Markdown>}\n </div>\n {hasMore && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n className=\"bg-transparent border-none p-0 mt-2 cursor-pointer text-2xs opacity-[0.65] underline\"\n >\n {expanded ? 'Show less' : 'Show more'}\n </button>\n )}\n </div>\n );\n};\n","export const HIGHLIGHT_OUTLINE_CLASS = 'outline-[rgba(200,154,90,0.5)]';\n\nexport const CANDIDATE_STAMP = {\n fill: 'rgba(0, 0, 0, 0.06)',\n text: 'rgba(0, 0, 0, 0.55)',\n};\n","import { PrBadge } from '@/app/features/plans/components/pr-badge';\nimport { STATUS_LABEL, STATUS_STAMP } from '@/app/features/plans/constants';\nimport type { PlanEntry, PlanStatus, PrInfo, RoadmapLink } from '@/types/index';\nimport { Card, Stamp } from '@dendelion/paper-ui';\n\nexport interface MergedIdea {\n key: string;\n label: string;\n status: PlanStatus;\n pr?: PrInfo;\n planId?: string;\n planTitle?: string;\n}\n\nexport const mergeIdeas = (links: RoadmapLink[], graduated: PlanEntry[]): MergedIdea[] => {\n const represented = new Set<string>();\n const merged: MergedIdea[] = graduated.map((plan) => {\n if (plan.id) represented.add(plan.id);\n if (plan.idea) represented.add(plan.idea);\n return {\n key: plan.title,\n label: plan.title,\n status: plan.status,\n pr: plan.pr,\n planId: plan.id,\n planTitle: plan.title,\n };\n });\n for (const link of links) {\n if (represented.has(link.id)) continue;\n merged.push({ key: link.id, label: link.id, status: link.status, pr: link.pr });\n }\n return merged;\n};\n\ninterface IdeaRowProps {\n idea: MergedIdea;\n onOpen?: () => void;\n}\n\nexport const IdeaRow = ({ idea, onOpen }: IdeaRowProps) => (\n <Card size=\"small\" texture=\"kraft\" className=\"plan-row-card\">\n <div className=\"flex items-center gap-3\">\n {onOpen ? (\n <button\n type=\"button\"\n onClick={onOpen}\n className=\"flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap bg-transparent border-none p-0 cursor-pointer [font:inherit] text-inherit text-left\"\n >\n {idea.label}\n </button>\n ) : (\n <span className=\"flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap\">\n {idea.label}\n </span>\n )}\n {idea.pr && <PrBadge pr={idea.pr} />}\n <Stamp\n size=\"small\"\n fillColor={STATUS_STAMP[idea.status].fill}\n textColor={STATUS_STAMP[idea.status].text}\n >\n {STATUS_LABEL[idea.status]}\n </Stamp>\n </div>\n </Card>\n);\n","interface ProgressBarProps {\n done: number;\n total: number;\n}\n\nexport const ProgressBar = ({ done, total }: ProgressBarProps) => {\n const percent = total > 0 ? Math.round((done / total) * 100) : 0;\n return (\n <div className=\"w-24 h-1.5 rounded-full bg-black/[0.08] overflow-hidden shrink-0\">\n <div\n className={`h-full rounded-full ${total > 0 ? 'bg-watercolor-green' : 'bg-transparent'}`}\n style={{ width: `${percent}%` }}\n />\n </div>\n );\n};\n","import { STATUS_STAMP } from '@/app/features/plans/constants';\nimport type { PlanEntry, ResolvedRoadmapItem } from '@/types/index';\nimport { Button, Stamp } from '@dendelion/paper-ui';\nimport { useEffect, useState } from 'react';\nimport { CANDIDATE_STAMP, HIGHLIGHT_OUTLINE_CLASS } from '../constants';\nimport { AddCandidateForm } from './add-candidate-form';\nimport { CandidateRow } from './candidate-row';\nimport { IdeaRow, mergeIdeas } from './idea-row';\nimport { ProgressBar } from './progress-bar';\n\nconst graduationCounts = (graduated: PlanEntry[]) => ({\n shipped: graduated.filter((p) => p.status === 'done').length,\n queued: graduated.filter((p) => p.status !== 'done' && p.status !== 'dropped').length,\n});\n\nconst ChevronRightIcon = ({ size = 14 }: { size?: number }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n);\n\ninterface RoadmapItemRowProps {\n item: ResolvedRoadmapItem;\n graduated: PlanEntry[];\n highlighted: boolean;\n onPromote: () => void;\n onPromoteCandidate: (candidateName: string) => void;\n onAddCandidate: (name: string) => Promise<void>;\n onOpenGraduated: (id: string | undefined, title: string) => void;\n}\n\nexport const RoadmapItemRow = ({\n item,\n graduated,\n highlighted,\n onPromote,\n onPromoteCandidate,\n onAddCandidate,\n onOpenGraduated,\n}: RoadmapItemRowProps) => {\n const [expanded, setExpanded] = useState(highlighted);\n const { shipped, queued } = graduationCounts(graduated);\n const candidates = item.candidates.length;\n const ideas = mergeIdeas(item.links, graduated);\n\n useEffect(() => {\n if (highlighted) setExpanded(true);\n }, [highlighted]);\n\n return (\n <div\n className={`border-b border-black/10 last:border-b-0 ${highlighted ? `roadmap-item-highlighted outline outline-2 outline-offset-[-2px] ${HIGHLIGHT_OUTLINE_CLASS}` : ''}`}\n >\n <button\n type=\"button\"\n aria-expanded={expanded}\n onClick={() => setExpanded((v) => !v)}\n className=\"flex w-full items-center gap-3 py-2.5 px-0 bg-transparent border-none cursor-pointer text-left [font:inherit] text-inherit\"\n >\n <span\n className={`inline-flex items-center opacity-50 shrink-0 ${expanded ? 'rotate-90' : ''}`}\n >\n <ChevronRightIcon />\n </span>\n <span className=\"font-semibold flex-1 min-w-0 truncate\">{item.name}</span>\n <ProgressBar done={item.rollup.done} total={item.rollup.total} />\n {queued > 0 && (\n <Stamp\n size=\"small\"\n fillColor={STATUS_STAMP.planned.fill}\n textColor={STATUS_STAMP.planned.text}\n >\n {queued} in queue\n </Stamp>\n )}\n {shipped > 0 && (\n <Stamp size=\"small\" fillColor={STATUS_STAMP.done.fill} textColor={STATUS_STAMP.done.text}>\n {shipped} shipped\n </Stamp>\n )}\n {candidates > 0 && (\n <Stamp size=\"small\" fillColor={CANDIDATE_STAMP.fill} textColor={CANDIDATE_STAMP.text}>\n {candidates} candidate{candidates === 1 ? '' : 's'}\n </Stamp>\n )}\n </button>\n {expanded && (\n <div className=\"flex flex-col gap-1 pl-6 pb-4\">\n <span className=\"text-sm opacity-70\">{item.description}</span>\n {ideas.map((idea) => (\n <IdeaRow\n key={idea.key}\n idea={idea}\n onOpen={\n idea.planTitle\n ? () => onOpenGraduated(idea.planId, idea.planTitle as string)\n : undefined\n }\n />\n ))}\n {item.candidates.map((candidateName) => (\n <CandidateRow\n key={candidateName}\n name={candidateName}\n onPromote={() => onPromoteCandidate(candidateName)}\n />\n ))}\n <AddCandidateForm onAdd={onAddCandidate} />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"small\"\n onClick={onPromote}\n className=\"self-start\"\n >\n Promote to idea\n </Button>\n </div>\n )}\n </div>\n );\n};\n","import type { PlanEntry, ResolvedRoadmapHorizon, ResolvedRoadmapItem } from '@/types/index';\nimport { RoadmapItemRow } from './roadmap-item-row';\n\nconst HORIZON_HEADER_CLASSES =\n 'font-handwritten text-md font-semibold opacity-70 leading-none pt-2 px-1 pb-0';\n\ninterface HorizonSectionProps {\n horizon: ResolvedRoadmapHorizon;\n highlightedItem: string | undefined;\n graduatedByItem: (item: ResolvedRoadmapItem) => PlanEntry[];\n onPromote: (item: ResolvedRoadmapItem, candidateName?: string) => void;\n onAddCandidate: (itemName: string, name: string) => Promise<void>;\n onOpenGraduated: (id: string | undefined, title: string) => void;\n}\n\nexport const HorizonSection = ({\n horizon,\n highlightedItem,\n graduatedByItem,\n onPromote,\n onAddCandidate,\n onOpenGraduated,\n}: HorizonSectionProps) => (\n <div className=\"flex flex-col gap-1\">\n <div className={HORIZON_HEADER_CLASSES}>{horizon.title}</div>\n <div className=\"flex flex-col\">\n {horizon.items.map((item) => (\n <RoadmapItemRow\n key={item.name}\n item={item}\n graduated={graduatedByItem(item)}\n highlighted={item.name === highlightedItem}\n onPromote={() => onPromote(item)}\n onPromoteCandidate={(candidateName) => onPromote(item, candidateName)}\n onAddCandidate={(name) => onAddCandidate(item.name, name)}\n onOpenGraduated={onOpenGraduated}\n />\n ))}\n </div>\n </div>\n);\n","import { PageTitle } from '@/app/components/page-title';\nimport { useRoadmapPage } from './hooks';\nimport { PromoteRoadmapItemModal } from './modals';\nimport { GoalBanner, HorizonSection } from './views';\n\nexport const RoadmapPage = () => {\n const {\n roadmap,\n roadmapError,\n loadRoadmap,\n horizons,\n totalVisible,\n hasActiveFilters,\n highlightedItem,\n containerRef,\n promoting,\n setPromoting,\n graduatedByItem,\n handleAddCandidate,\n handlePromote,\n onOpenGraduated,\n } = useRoadmapPage();\n\n if (roadmapError) {\n return (\n <div>\n <PageTitle>Roadmap</PageTitle>\n <p className=\"opacity-50\">\n Couldn't load the roadmap — the server may need a restart to pick up new routes.\n </p>\n </div>\n );\n }\n\n if (!roadmap) {\n return (\n <div>\n <PageTitle>Roadmap</PageTitle>\n <p className=\"opacity-50\">Loading…</p>\n </div>\n );\n }\n\n if (roadmap.horizons.length === 0) {\n return (\n <div>\n <PageTitle>Roadmap</PageTitle>\n <p className=\"opacity-50\">No `ROADMAP.md` found at the project root.</p>\n </div>\n );\n }\n\n return (\n <div ref={containerRef}>\n <PageTitle>Roadmap</PageTitle>\n <GoalBanner goal={roadmap.goal} />\n {totalVisible === 0 ? (\n <p className=\"opacity-50 py-6 px-0 text-center\">\n {hasActiveFilters\n ? 'Nothing matches these filters — clear one from the sidebar to see more.'\n : 'No roadmap items yet — add one from the sidebar.'}\n </p>\n ) : (\n <div className=\"flex flex-col gap-6\">\n {horizons\n .filter((horizon) => horizon.items.length > 0)\n .map((horizon) => (\n <HorizonSection\n key={horizon.title}\n horizon={horizon}\n highlightedItem={highlightedItem}\n graduatedByItem={graduatedByItem}\n onPromote={(item, candidateName) =>\n handlePromote(horizon.title, item, candidateName)\n }\n onAddCandidate={(itemName, name) =>\n handleAddCandidate(horizon.title, itemName, name)\n }\n onOpenGraduated={onOpenGraduated}\n />\n ))}\n </div>\n )}\n <PromoteRoadmapItemModal\n horizonTitle={promoting?.horizonTitle ?? null}\n item={promoting?.item ?? null}\n candidateName={promoting?.candidateName}\n onClose={() => setPromoting(null)}\n onPromoted={loadRoadmap}\n />\n </div>\n );\n};\n","import { STATUS_LABEL, STATUS_STAMP } from '@/app/features/plans/constants';\nimport { Button, ListItem } from '@dendelion/paper-ui';\nimport { useRoadmapSidebar } from './hooks';\nimport { AddRoadmapItemModal } from './modals';\n\n// Matches SidebarSection — handwritten, no caps, one grid cell.\nconst sectionLabelClass = 'pc-row-label font-handwritten text-xs font-semibold opacity-[0.45]';\n\nexport const RoadmapSidebar = () => {\n const {\n roadmap,\n horizonTitles,\n horizonCounts,\n statusCounts,\n activeHorizons,\n activeStatuses,\n visibleStatuses,\n addOpen,\n setAddOpen,\n toggleRoadmapHorizon,\n toggleRoadmapStatus,\n } = useRoadmapSidebar();\n\n if (!roadmap) return null;\n\n return (\n <div className=\"flex flex-col\">\n <div className=\"flex h-[64px] items-center\">\n <Button\n type=\"button\"\n variant=\"primary\"\n size=\"small\"\n onClick={() => setAddOpen(true)}\n disabled={horizonTitles.length === 0}\n >\n + Add item\n </Button>\n </div>\n\n <div>\n <div className={sectionLabelClass}>Horizon</div>\n <div className=\"flex flex-col\">\n {horizonTitles.map((title) => (\n <ListItem\n key={title}\n size=\"small\"\n active={activeHorizons.has(title)}\n onClick={() => toggleRoadmapHorizon(title)}\n className=\"pc-row text-xs\"\n action={<span className=\"text-2xs text-ink-500\">{horizonCounts[title] ?? 0}</span>}\n >\n {title}\n </ListItem>\n ))}\n </div>\n </div>\n\n <div>\n <div className={sectionLabelClass}>Status</div>\n <div className=\"flex flex-col\">\n {visibleStatuses.length === 0 && (\n <span className=\"opacity-50 text-2xs\">No linked ideas</span>\n )}\n {visibleStatuses.map((status) => (\n <ListItem\n key={status}\n size=\"small\"\n active={activeStatuses.has(status)}\n onClick={() => toggleRoadmapStatus(status)}\n className=\"pc-row text-xs\"\n icon={\n <span\n className=\"w-[9px] h-[9px] rounded-full shrink-0\"\n style={{ background: STATUS_STAMP[status].text }}\n />\n }\n action={<span className=\"text-2xs text-ink-500\">{statusCounts[status] ?? 0}</span>}\n >\n {STATUS_LABEL[status]}\n </ListItem>\n ))}\n </div>\n </div>\n\n <AddRoadmapItemModal\n open={addOpen}\n horizonTitles={horizonTitles}\n onClose={() => setAddOpen(false)}\n />\n </div>\n );\n};\n"],"names":["useRoadmapPage","roadmap","useAppStore","s","roadmapError","loadRoadmap","filters","plans","openEntity","useOpenEntity","highlightedItem","useSearch","containerRef","useRef","promoting","setPromoting","useState","useEffect","row","_a","graduatedByItem","item","p","handleAddCandidate","horizonTitle","itemName","name","addRoadmapCandidate","handlePromote","candidateName","horizons","filterHorizons","totalVisible","count","horizon","hasActiveFilters","STATUS_CHIP_ORDER","useRoadmapSidebar","toggleRoadmapHorizon","toggleRoadmapStatus","addOpen","setAddOpen","horizonTitles","horizonCounts","horizonItemCounts","statusCounts","statusItemCounts","activeHorizons","activeStatuses","visibleStatuses","status","AddRoadmapItemModal","open","onClose","setHorizon","setName","description","setDescription","saving","setSaving","error","setError","horizonTitlesRef","handleAdd","addRoadmapItem","err","jsx","Modal","jsxs","Select","title","Input","e","Button","NO_SUBJECT","PromoteRoadmapItemModal","onPromoted","promoteRoadmapItem","launchIdeaExtend","subjects","subjectsAvailable","useSubjectVocabulary","subject","setSubject","loading","setLoading","toast","useToast","id","idea","buildRoadmapPromotePrompt","oneLineErrorSummary","AddCandidateForm","onAdd","CandidateRow","onPromote","Card","GoalBanner","goal","expanded","setExpanded","firstParagraph","restParagraphs","hasMore","Markdown","v","HIGHLIGHT_OUTLINE_CLASS","CANDIDATE_STAMP","mergeIdeas","links","graduated","represented","merged","plan","link","IdeaRow","onOpen","PrBadge","Stamp","STATUS_STAMP","STATUS_LABEL","ProgressBar","done","total","percent","graduationCounts","ChevronRightIcon","size","RoadmapItemRow","highlighted","onPromoteCandidate","onAddCandidate","onOpenGraduated","shipped","queued","candidates","ideas","HORIZON_HEADER_CLASSES","HorizonSection","RoadmapPage","PageTitle","sectionLabelClass","RoadmapSidebar","ListItem"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-rxWn42R9.js","sources":["../../../src/app/features/roadmap/hooks/use-roadmap-page.ts","../../../src/app/features/roadmap/hooks/use-roadmap-sidebar.ts","../../../src/app/features/roadmap/modals/add-roadmap-item-modal.tsx","../../../src/app/features/roadmap/modals/promote-roadmap-item-modal.tsx","../../../src/app/features/roadmap/views/add-candidate-form.tsx","../../../src/app/features/roadmap/views/candidate-row.tsx","../../../src/app/features/roadmap/views/goal-banner.tsx","../../../src/app/features/roadmap/constants.ts","../../../src/app/features/roadmap/views/idea-row.tsx","../../../src/app/features/roadmap/views/progress-bar.tsx","../../../src/app/features/roadmap/views/roadmap-item-row.tsx","../../../src/app/features/roadmap/views/horizon-section.tsx","../../../src/app/features/roadmap/roadmap-page.tsx","../../../src/app/features/roadmap/roadmap-sidebar.tsx"],"sourcesContent":["import { useOpenEntity } from '@/app/hooks';\nimport { addRoadmapCandidate } from '@/app/services/content/docs-api';\nimport { useAppStore } from '@/app/stores/app-store';\nimport type { PlanEntry, ResolvedRoadmapItem } from '@/types/index';\nimport { useSearch } from '@tanstack/react-router';\nimport { useEffect, useRef, useState } from 'react';\nimport { filterHorizons } from '../helpers';\n\ninterface Promoting {\n horizonTitle: string;\n item: ResolvedRoadmapItem;\n candidateName?: string;\n}\n\nexport const useRoadmapPage = () => {\n const roadmap = useAppStore((s) => s.roadmap);\n const roadmapError = useAppStore((s) => s.roadmapError);\n const loadRoadmap = useAppStore((s) => s.loadRoadmap);\n const filters = useAppStore((s) => s.roadmapFilters);\n const plans = useAppStore((s) => s.plans);\n const openEntity = useOpenEntity();\n const { item: highlightedItem } = useSearch({ from: '/roadmap' });\n const containerRef = useRef<HTMLDivElement>(null);\n const [promoting, setPromoting] = useState<Promoting | null>(null);\n\n useEffect(() => {\n loadRoadmap();\n }, [loadRoadmap]);\n\n useEffect(() => {\n if (!highlightedItem || !roadmap) return;\n const row = containerRef.current?.querySelector('.roadmap-item-highlighted');\n row?.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }, [highlightedItem, roadmap]);\n\n const graduatedByItem = (item: ResolvedRoadmapItem): PlanEntry[] =>\n plans?.entries.filter((p) => p.subject === item.name) ?? [];\n\n const handleAddCandidate = async (horizonTitle: string, itemName: string, name: string) => {\n await addRoadmapCandidate(horizonTitle, itemName, name);\n await loadRoadmap();\n };\n\n const handlePromote = (\n horizonTitle: string,\n item: ResolvedRoadmapItem,\n candidateName?: string,\n ) => {\n setPromoting({ horizonTitle, item, candidateName });\n };\n\n const horizons = roadmap ? filterHorizons(roadmap, filters) : [];\n const totalVisible = horizons.reduce((count, horizon) => count + horizon.items.length, 0);\n const hasActiveFilters = filters.horizons.length > 0 || filters.statuses.length > 0;\n\n return {\n roadmap,\n roadmapError,\n loadRoadmap,\n horizons,\n totalVisible,\n hasActiveFilters,\n highlightedItem,\n containerRef,\n promoting,\n setPromoting,\n graduatedByItem,\n handleAddCandidate,\n handlePromote,\n onOpenGraduated: openEntity,\n };\n};\n","import { useAppStore } from '@/app/stores/app-store';\nimport type { PlanStatus } from '@/types/index';\nimport { useState } from 'react';\nimport { horizonItemCounts, statusItemCounts } from '../helpers';\n\nconst STATUS_CHIP_ORDER: PlanStatus[] = [\n 'in-progress',\n 'review',\n 'planned',\n 'idea',\n 'done',\n 'dropped',\n];\n\nexport const useRoadmapSidebar = () => {\n const roadmap = useAppStore((s) => s.roadmap);\n const filters = useAppStore((s) => s.roadmapFilters);\n const toggleRoadmapHorizon = useAppStore((s) => s.toggleRoadmapHorizon);\n const toggleRoadmapStatus = useAppStore((s) => s.toggleRoadmapStatus);\n const [addOpen, setAddOpen] = useState(false);\n\n const horizonTitles = roadmap?.horizons.map((horizon) => horizon.title) ?? [];\n const horizonCounts = roadmap ? horizonItemCounts(roadmap, filters) : {};\n const statusCounts = roadmap ? statusItemCounts(roadmap, filters) : {};\n const activeHorizons = new Set(filters.horizons);\n const activeStatuses = new Set(filters.statuses);\n const visibleStatuses = STATUS_CHIP_ORDER.filter(\n (status) => (statusCounts[status] ?? 0) > 0 || activeStatuses.has(status),\n );\n\n return {\n roadmap,\n horizonTitles,\n horizonCounts,\n statusCounts,\n activeHorizons,\n activeStatuses,\n visibleStatuses,\n addOpen,\n setAddOpen,\n toggleRoadmapHorizon,\n toggleRoadmapStatus,\n };\n};\n","import { addRoadmapItem } from '@/app/services/content/docs-api';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { Button, Input, Modal, Select } from '@dendelion/paper-ui';\nimport { useEffect, useRef, useState } from 'react';\n\ninterface AddRoadmapItemModalProps {\n open: boolean;\n horizonTitles: string[];\n onClose: () => void;\n}\n\nexport const AddRoadmapItemModal = ({ open, horizonTitles, onClose }: AddRoadmapItemModalProps) => {\n const loadRoadmap = useAppStore((s) => s.loadRoadmap);\n const [horizon, setHorizon] = useState(horizonTitles[0] ?? '');\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const horizonTitlesRef = useRef(horizonTitles);\n horizonTitlesRef.current = horizonTitles;\n\n useEffect(() => {\n if (open) {\n setHorizon(horizonTitlesRef.current[0] ?? '');\n setName('');\n setDescription('');\n setError(null);\n setSaving(false);\n }\n }, [open]);\n\n const handleAdd = async () => {\n if (!name.trim() || !horizon) return;\n setSaving(true);\n setError(null);\n try {\n await addRoadmapItem(horizon, name.trim(), description.trim());\n await loadRoadmap();\n onClose();\n } catch (err) {\n setError((err as Error).message);\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <Modal open={open} onClose={onClose} title=\"Add roadmap item\" size=\"small\">\n <div className=\"flex flex-col gap-4\">\n <Select\n size=\"small\"\n value={horizon}\n onChange={setHorizon}\n disabled={saving}\n options={horizonTitles.map((title) => ({ value: title, label: title }))}\n />\n <Input\n size=\"small\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"Item name…\"\n disabled={saving}\n autoFocus\n />\n <Input\n size=\"small\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAdd();\n }}\n placeholder=\"Description…\"\n disabled={saving}\n />\n {error && <p className=\"m-0 text-watercolor-rose-dark text-sm\">{error}</p>}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" onClick={onClose} disabled={saving}>\n Cancel\n </Button>\n <Button\n type=\"button\"\n variant=\"primary\"\n onClick={handleAdd}\n disabled={saving || !name.trim() || !horizon}\n >\n {saving ? 'Adding…' : 'Add item'}\n </Button>\n </div>\n </div>\n </Modal>\n );\n};\n","import { buildRoadmapPromotePrompt } from '@/app/features/plans/prompts';\nimport { useSubjectVocabulary } from '@/app/hooks/use-subject-vocabulary';\nimport { useAppStore } from '@/app/stores/app-store';\nimport { oneLineErrorSummary } from '@/app/utils/error-summary';\nimport type { RoadmapItem } from '@/types/index';\nimport { Button, Modal, Select, useToast } from '@dendelion/paper-ui';\nimport { useEffect, useState } from 'react';\n\nconst NO_SUBJECT = '__no-subject__';\n\ninterface PromoteRoadmapItemModalProps {\n horizonTitle: string | null;\n item: RoadmapItem | null;\n candidateName?: string | null;\n onClose: () => void;\n onPromoted: () => void;\n}\n\nexport const PromoteRoadmapItemModal = ({\n horizonTitle,\n item,\n candidateName,\n onClose,\n onPromoted,\n}: PromoteRoadmapItemModalProps) => {\n const promoteRoadmapItem = useAppStore((s) => s.promoteRoadmapItem);\n const launchIdeaExtend = useAppStore((s) => s.launchIdeaExtend);\n const { subjects, available: subjectsAvailable } = useSubjectVocabulary();\n const [subject, setSubject] = useState(NO_SUBJECT);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const { toast } = useToast();\n\n useEffect(() => {\n if (item) {\n // A candidate defaults to its parent item's name — the \"big bet becomes a\n // Subject\" rule — but the picker still lets the user override it.\n setSubject(candidateName ? item.name : NO_SUBJECT);\n setLoading(false);\n setError(null);\n }\n }, [item, candidateName]);\n\n const handlePromote = async () => {\n if (!item || !horizonTitle) return;\n setLoading(true);\n setError(null);\n try {\n const id = await promoteRoadmapItem(\n horizonTitle,\n item,\n subject === NO_SUBJECT ? undefined : subject,\n candidateName ?? undefined,\n );\n const idea = useAppStore.getState().ideaEntries.find((e) => e.id === id);\n if (idea) {\n try {\n await launchIdeaExtend(id, buildRoadmapPromotePrompt(idea, horizonTitle));\n } catch (err) {\n // The idea was created either way — a failed refine launch just means\n // no background research ran, not that the promotion itself failed.\n toast({\n title: 'Idea created, but the refine agent failed to launch',\n description: oneLineErrorSummary((err as Error).message),\n variant: 'error',\n });\n }\n }\n onPromoted();\n onClose();\n } catch (err) {\n setError((err as Error).message);\n } finally {\n setLoading(false);\n }\n };\n\n return (\n <Modal\n open={item !== null}\n onClose={onClose}\n title={candidateName ?? item?.name ?? ''}\n size=\"small\"\n >\n <div className=\"flex flex-col gap-4\">\n {!candidateName && <p className=\"m-0 opacity-80\">{item?.description}</p>}\n <div>\n <Select\n size=\"small\"\n value={subject}\n onChange={setSubject}\n disabled={loading || !subjectsAvailable}\n options={[\n { value: NO_SUBJECT, label: 'No subject' },\n ...(!subjectsAvailable && subject !== NO_SUBJECT\n ? [{ value: subject, label: subject }]\n : []),\n ...subjects.map((s) => ({ value: s, label: s })),\n ]}\n />\n </div>\n {error && <p className=\"m-0 text-watercolor-rose-dark text-sm\">{error}</p>}\n <div className=\"flex justify-end gap-2\">\n <Button type=\"button\" variant=\"ghost\" onClick={onClose} disabled={loading}>\n Cancel\n </Button>\n <Button type=\"button\" variant=\"primary\" onClick={handlePromote} disabled={loading}>\n {loading ? 'Promoting…' : 'Promote to idea'}\n </Button>\n </div>\n </div>\n </Modal>\n );\n};\n","import { Button, Input } from '@dendelion/paper-ui';\nimport { useState } from 'react';\n\ninterface AddCandidateFormProps {\n onAdd: (name: string) => Promise<void>;\n}\n\nexport const AddCandidateForm = ({ onAdd }: AddCandidateFormProps) => {\n const [name, setName] = useState('');\n const [saving, setSaving] = useState(false);\n\n const handleAdd = async () => {\n if (!name.trim()) return;\n setSaving(true);\n try {\n await onAdd(name.trim());\n setName('');\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <div className=\"flex gap-2\">\n <Input\n size=\"small\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAdd();\n }}\n placeholder=\"Add option…\"\n disabled={saving}\n className=\"flex-1\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"small\"\n onClick={handleAdd}\n disabled={saving || !name.trim()}\n >\n Add\n </Button>\n </div>\n );\n};\n","import { Button, Card } from '@dendelion/paper-ui';\n\ninterface CandidateRowProps {\n name: string;\n onPromote: () => void;\n}\n\nexport const CandidateRow = ({ name, onPromote }: CandidateRowProps) => (\n <Card size=\"small\" texture=\"kraft\" className=\"plan-row-card\">\n <div className=\"flex items-center gap-3\">\n <span className=\"flex-1\">{name}</span>\n <Button type=\"button\" variant=\"ghost\" size=\"small\" onClick={onPromote}>\n Promote to idea\n </Button>\n </div>\n </Card>\n);\n","import { Markdown } from '@/app/components/markdown';\nimport { useState } from 'react';\n\ninterface GoalBannerProps {\n goal: string;\n}\n\nexport const GoalBanner = ({ goal }: GoalBannerProps) => {\n const [expanded, setExpanded] = useState(false);\n const [firstParagraph, ...restParagraphs] = goal.split(/\\n{2,}/);\n const hasMore = restParagraphs.length > 0;\n\n return (\n <div className=\"mb-6 pb-4 border-b border-black/[8%]\">\n <span className=\"font-handwritten text-xs font-semibold opacity-[0.55]\">The goal</span>\n <div className=\"text-sm leading-relaxed opacity-80 mt-2\">\n <Markdown>{firstParagraph}</Markdown>\n {expanded && hasMore && <Markdown>{restParagraphs.join('\\n\\n')}</Markdown>}\n </div>\n {hasMore && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n className=\"bg-transparent border-none p-0 mt-2 cursor-pointer text-2xs opacity-[0.65] underline\"\n >\n {expanded ? 'Show less' : 'Show more'}\n </button>\n )}\n </div>\n );\n};\n","export const HIGHLIGHT_OUTLINE_CLASS = 'outline-[rgba(200,154,90,0.5)]';\n\nexport const CANDIDATE_STAMP = {\n fill: 'rgba(0, 0, 0, 0.06)',\n text: 'rgba(0, 0, 0, 0.55)',\n};\n","import { PrBadge } from '@/app/features/plans/components/pr-badge';\nimport { STATUS_LABEL, STATUS_STAMP } from '@/app/features/plans/constants';\nimport type { PlanEntry, PlanStatus, PrInfo, RoadmapLink } from '@/types/index';\nimport { Card, Stamp } from '@dendelion/paper-ui';\n\nexport interface MergedIdea {\n key: string;\n label: string;\n status: PlanStatus;\n pr?: PrInfo;\n planId?: string;\n planTitle?: string;\n}\n\nexport const mergeIdeas = (links: RoadmapLink[], graduated: PlanEntry[]): MergedIdea[] => {\n const represented = new Set<string>();\n const merged: MergedIdea[] = graduated.map((plan) => {\n if (plan.id) represented.add(plan.id);\n if (plan.idea) represented.add(plan.idea);\n return {\n key: plan.title,\n label: plan.title,\n status: plan.status,\n pr: plan.pr,\n planId: plan.id,\n planTitle: plan.title,\n };\n });\n for (const link of links) {\n if (represented.has(link.id)) continue;\n merged.push({ key: link.id, label: link.id, status: link.status, pr: link.pr });\n }\n return merged;\n};\n\ninterface IdeaRowProps {\n idea: MergedIdea;\n onOpen?: () => void;\n}\n\nexport const IdeaRow = ({ idea, onOpen }: IdeaRowProps) => (\n <Card size=\"small\" texture=\"kraft\" className=\"plan-row-card\">\n <div className=\"flex items-center gap-3\">\n {onOpen ? (\n <button\n type=\"button\"\n onClick={onOpen}\n className=\"flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap bg-transparent border-none p-0 cursor-pointer [font:inherit] text-inherit text-left\"\n >\n {idea.label}\n </button>\n ) : (\n <span className=\"flex-1 min-w-0 overflow-hidden text-ellipsis whitespace-nowrap\">\n {idea.label}\n </span>\n )}\n {idea.pr && <PrBadge pr={idea.pr} />}\n <Stamp\n size=\"small\"\n fillColor={STATUS_STAMP[idea.status].fill}\n textColor={STATUS_STAMP[idea.status].text}\n >\n {STATUS_LABEL[idea.status]}\n </Stamp>\n </div>\n </Card>\n);\n","interface ProgressBarProps {\n done: number;\n total: number;\n}\n\nexport const ProgressBar = ({ done, total }: ProgressBarProps) => {\n const percent = total > 0 ? Math.round((done / total) * 100) : 0;\n return (\n <div className=\"w-24 h-1.5 rounded-full bg-black/[0.08] overflow-hidden shrink-0\">\n <div\n className={`h-full rounded-full ${total > 0 ? 'bg-watercolor-green' : 'bg-transparent'}`}\n style={{ width: `${percent}%` }}\n />\n </div>\n );\n};\n","import { STATUS_STAMP } from '@/app/features/plans/constants';\nimport type { PlanEntry, ResolvedRoadmapItem } from '@/types/index';\nimport { Button, Stamp } from '@dendelion/paper-ui';\nimport { useEffect, useState } from 'react';\nimport { CANDIDATE_STAMP, HIGHLIGHT_OUTLINE_CLASS } from '../constants';\nimport { AddCandidateForm } from './add-candidate-form';\nimport { CandidateRow } from './candidate-row';\nimport { IdeaRow, mergeIdeas } from './idea-row';\nimport { ProgressBar } from './progress-bar';\n\nconst graduationCounts = (graduated: PlanEntry[]) => ({\n shipped: graduated.filter((p) => p.status === 'done').length,\n queued: graduated.filter((p) => p.status !== 'done' && p.status !== 'dropped').length,\n});\n\nconst ChevronRightIcon = ({ size = 14 }: { size?: number }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n);\n\ninterface RoadmapItemRowProps {\n item: ResolvedRoadmapItem;\n graduated: PlanEntry[];\n highlighted: boolean;\n onPromote: () => void;\n onPromoteCandidate: (candidateName: string) => void;\n onAddCandidate: (name: string) => Promise<void>;\n onOpenGraduated: (id: string | undefined, title: string) => void;\n}\n\nexport const RoadmapItemRow = ({\n item,\n graduated,\n highlighted,\n onPromote,\n onPromoteCandidate,\n onAddCandidate,\n onOpenGraduated,\n}: RoadmapItemRowProps) => {\n const [expanded, setExpanded] = useState(highlighted);\n const { shipped, queued } = graduationCounts(graduated);\n const candidates = item.candidates.length;\n const ideas = mergeIdeas(item.links, graduated);\n\n useEffect(() => {\n if (highlighted) setExpanded(true);\n }, [highlighted]);\n\n return (\n <div\n className={`border-b border-black/10 last:border-b-0 ${highlighted ? `roadmap-item-highlighted outline outline-2 outline-offset-[-2px] ${HIGHLIGHT_OUTLINE_CLASS}` : ''}`}\n >\n <button\n type=\"button\"\n aria-expanded={expanded}\n onClick={() => setExpanded((v) => !v)}\n className=\"flex w-full items-center gap-3 py-2.5 px-0 bg-transparent border-none cursor-pointer text-left [font:inherit] text-inherit\"\n >\n <span\n className={`inline-flex items-center opacity-50 shrink-0 ${expanded ? 'rotate-90' : ''}`}\n >\n <ChevronRightIcon />\n </span>\n <span className=\"font-semibold flex-1 min-w-0 truncate\">{item.name}</span>\n <ProgressBar done={item.rollup.done} total={item.rollup.total} />\n {queued > 0 && (\n <Stamp\n size=\"small\"\n fillColor={STATUS_STAMP.planned.fill}\n textColor={STATUS_STAMP.planned.text}\n >\n {queued} in queue\n </Stamp>\n )}\n {shipped > 0 && (\n <Stamp size=\"small\" fillColor={STATUS_STAMP.done.fill} textColor={STATUS_STAMP.done.text}>\n {shipped} shipped\n </Stamp>\n )}\n {candidates > 0 && (\n <Stamp size=\"small\" fillColor={CANDIDATE_STAMP.fill} textColor={CANDIDATE_STAMP.text}>\n {candidates} candidate{candidates === 1 ? '' : 's'}\n </Stamp>\n )}\n </button>\n {expanded && (\n <div className=\"flex flex-col gap-1 pl-6 pb-4\">\n <span className=\"text-sm opacity-70\">{item.description}</span>\n {ideas.map((idea) => (\n <IdeaRow\n key={idea.key}\n idea={idea}\n onOpen={\n idea.planTitle\n ? () => onOpenGraduated(idea.planId, idea.planTitle as string)\n : undefined\n }\n />\n ))}\n {item.candidates.map((candidateName) => (\n <CandidateRow\n key={candidateName}\n name={candidateName}\n onPromote={() => onPromoteCandidate(candidateName)}\n />\n ))}\n <AddCandidateForm onAdd={onAddCandidate} />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"small\"\n onClick={onPromote}\n className=\"self-start\"\n >\n Promote to idea\n </Button>\n </div>\n )}\n </div>\n );\n};\n","import type { PlanEntry, ResolvedRoadmapHorizon, ResolvedRoadmapItem } from '@/types/index';\nimport { RoadmapItemRow } from './roadmap-item-row';\n\nconst HORIZON_HEADER_CLASSES =\n 'font-handwritten text-md font-semibold opacity-70 leading-none pt-2 px-1 pb-0';\n\ninterface HorizonSectionProps {\n horizon: ResolvedRoadmapHorizon;\n highlightedItem: string | undefined;\n graduatedByItem: (item: ResolvedRoadmapItem) => PlanEntry[];\n onPromote: (item: ResolvedRoadmapItem, candidateName?: string) => void;\n onAddCandidate: (itemName: string, name: string) => Promise<void>;\n onOpenGraduated: (id: string | undefined, title: string) => void;\n}\n\nexport const HorizonSection = ({\n horizon,\n highlightedItem,\n graduatedByItem,\n onPromote,\n onAddCandidate,\n onOpenGraduated,\n}: HorizonSectionProps) => (\n <div className=\"flex flex-col gap-1\">\n <div className={HORIZON_HEADER_CLASSES}>{horizon.title}</div>\n <div className=\"flex flex-col\">\n {horizon.items.map((item) => (\n <RoadmapItemRow\n key={item.name}\n item={item}\n graduated={graduatedByItem(item)}\n highlighted={item.name === highlightedItem}\n onPromote={() => onPromote(item)}\n onPromoteCandidate={(candidateName) => onPromote(item, candidateName)}\n onAddCandidate={(name) => onAddCandidate(item.name, name)}\n onOpenGraduated={onOpenGraduated}\n />\n ))}\n </div>\n </div>\n);\n","import { PageTitle } from '@/app/components/page-title';\nimport { useRoadmapPage } from './hooks';\nimport { PromoteRoadmapItemModal } from './modals';\nimport { GoalBanner, HorizonSection } from './views';\n\nexport const RoadmapPage = () => {\n const {\n roadmap,\n roadmapError,\n loadRoadmap,\n horizons,\n totalVisible,\n hasActiveFilters,\n highlightedItem,\n containerRef,\n promoting,\n setPromoting,\n graduatedByItem,\n handleAddCandidate,\n handlePromote,\n onOpenGraduated,\n } = useRoadmapPage();\n\n if (roadmapError) {\n return (\n <div>\n <PageTitle>Roadmap</PageTitle>\n <p className=\"opacity-50\">\n Couldn't load the roadmap — the server may need a restart to pick up new routes.\n </p>\n </div>\n );\n }\n\n if (!roadmap) {\n return (\n <div>\n <PageTitle>Roadmap</PageTitle>\n <p className=\"opacity-50\">Loading…</p>\n </div>\n );\n }\n\n if (roadmap.horizons.length === 0) {\n return (\n <div>\n <PageTitle>Roadmap</PageTitle>\n <p className=\"opacity-50\">No `ROADMAP.md` found at the project root.</p>\n </div>\n );\n }\n\n return (\n <div ref={containerRef}>\n <PageTitle>Roadmap</PageTitle>\n <GoalBanner goal={roadmap.goal} />\n {totalVisible === 0 ? (\n <p className=\"opacity-50 py-6 px-0 text-center\">\n {hasActiveFilters\n ? 'Nothing matches these filters — clear one from the sidebar to see more.'\n : 'No roadmap items yet — add one from the sidebar.'}\n </p>\n ) : (\n <div className=\"flex flex-col gap-6\">\n {horizons\n .filter((horizon) => horizon.items.length > 0)\n .map((horizon) => (\n <HorizonSection\n key={horizon.title}\n horizon={horizon}\n highlightedItem={highlightedItem}\n graduatedByItem={graduatedByItem}\n onPromote={(item, candidateName) =>\n handlePromote(horizon.title, item, candidateName)\n }\n onAddCandidate={(itemName, name) =>\n handleAddCandidate(horizon.title, itemName, name)\n }\n onOpenGraduated={onOpenGraduated}\n />\n ))}\n </div>\n )}\n <PromoteRoadmapItemModal\n horizonTitle={promoting?.horizonTitle ?? null}\n item={promoting?.item ?? null}\n candidateName={promoting?.candidateName}\n onClose={() => setPromoting(null)}\n onPromoted={loadRoadmap}\n />\n </div>\n );\n};\n","import { STATUS_LABEL, STATUS_STAMP } from '@/app/features/plans/constants';\nimport { Button, ListItem } from '@dendelion/paper-ui';\nimport { useRoadmapSidebar } from './hooks';\nimport { AddRoadmapItemModal } from './modals';\n\n// Matches SidebarSection — handwritten, no caps, one grid cell.\nconst sectionLabelClass = 'pc-row-label font-handwritten text-xs font-semibold opacity-[0.45]';\n\nexport const RoadmapSidebar = () => {\n const {\n roadmap,\n horizonTitles,\n horizonCounts,\n statusCounts,\n activeHorizons,\n activeStatuses,\n visibleStatuses,\n addOpen,\n setAddOpen,\n toggleRoadmapHorizon,\n toggleRoadmapStatus,\n } = useRoadmapSidebar();\n\n if (!roadmap) return null;\n\n return (\n <div className=\"flex flex-col\">\n <div className=\"flex h-[64px] items-center\">\n <Button\n type=\"button\"\n variant=\"primary\"\n size=\"small\"\n onClick={() => setAddOpen(true)}\n disabled={horizonTitles.length === 0}\n >\n + Add item\n </Button>\n </div>\n\n <div>\n <div className={sectionLabelClass}>Horizon</div>\n <div className=\"flex flex-col\">\n {horizonTitles.map((title) => (\n <ListItem\n key={title}\n size=\"small\"\n active={activeHorizons.has(title)}\n onClick={() => toggleRoadmapHorizon(title)}\n className=\"pc-row text-xs\"\n action={<span className=\"text-2xs text-ink-500\">{horizonCounts[title] ?? 0}</span>}\n >\n {title}\n </ListItem>\n ))}\n </div>\n </div>\n\n <div>\n <div className={sectionLabelClass}>Status</div>\n <div className=\"flex flex-col\">\n {visibleStatuses.length === 0 && (\n <span className=\"opacity-50 text-2xs\">No linked ideas</span>\n )}\n {visibleStatuses.map((status) => (\n <ListItem\n key={status}\n size=\"small\"\n active={activeStatuses.has(status)}\n onClick={() => toggleRoadmapStatus(status)}\n className=\"pc-row text-xs\"\n icon={\n <span\n className=\"w-[9px] h-[9px] rounded-full shrink-0\"\n style={{ background: STATUS_STAMP[status].text }}\n />\n }\n action={<span className=\"text-2xs text-ink-500\">{statusCounts[status] ?? 0}</span>}\n >\n {STATUS_LABEL[status]}\n </ListItem>\n ))}\n </div>\n </div>\n\n <AddRoadmapItemModal\n open={addOpen}\n horizonTitles={horizonTitles}\n onClose={() => setAddOpen(false)}\n />\n </div>\n );\n};\n"],"names":["useRoadmapPage","roadmap","useAppStore","s","roadmapError","loadRoadmap","filters","plans","openEntity","useOpenEntity","highlightedItem","useSearch","containerRef","useRef","promoting","setPromoting","useState","useEffect","row","_a","graduatedByItem","item","p","handleAddCandidate","horizonTitle","itemName","name","addRoadmapCandidate","handlePromote","candidateName","horizons","filterHorizons","totalVisible","count","horizon","hasActiveFilters","STATUS_CHIP_ORDER","useRoadmapSidebar","toggleRoadmapHorizon","toggleRoadmapStatus","addOpen","setAddOpen","horizonTitles","horizonCounts","horizonItemCounts","statusCounts","statusItemCounts","activeHorizons","activeStatuses","visibleStatuses","status","AddRoadmapItemModal","open","onClose","setHorizon","setName","description","setDescription","saving","setSaving","error","setError","horizonTitlesRef","handleAdd","addRoadmapItem","err","jsx","Modal","jsxs","Select","title","Input","e","Button","NO_SUBJECT","PromoteRoadmapItemModal","onPromoted","promoteRoadmapItem","launchIdeaExtend","subjects","subjectsAvailable","useSubjectVocabulary","subject","setSubject","loading","setLoading","toast","useToast","id","idea","buildRoadmapPromotePrompt","oneLineErrorSummary","AddCandidateForm","onAdd","CandidateRow","onPromote","Card","GoalBanner","goal","expanded","setExpanded","firstParagraph","restParagraphs","hasMore","Markdown","v","HIGHLIGHT_OUTLINE_CLASS","CANDIDATE_STAMP","mergeIdeas","links","graduated","represented","merged","plan","link","IdeaRow","onOpen","PrBadge","Stamp","STATUS_STAMP","STATUS_LABEL","ProgressBar","done","total","percent","graduationCounts","ChevronRightIcon","size","RoadmapItemRow","highlighted","onPromoteCandidate","onAddCandidate","onOpenGraduated","shipped","queued","candidates","ideas","HORIZON_HEADER_CLASSES","HorizonSection","RoadmapPage","PageTitle","sectionLabelClass","RoadmapSidebar","ListItem"],"mappings":"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"}
|