+
Source
-
Version
- setVersionId(e.target.value)} className="border border-gray-600 rounded px-2 py-1 text-sm bg-gray-800 text-gray-200" disabled={!versions.length}>
+ setVersionId(e.target.value)} className="border border-gray-200 rounded px-2 py-1 text-sm bg-white" disabled={!versions.length}>
{versions.length === 0
?
: versions.map(v => )}
{selectedVersion && (
-
+
{selectedVersion.status}
)}
-
-
- {/* Toolbar bar */}
-
-
- {/* Layouts group */}
-
-
Layout
- {layouts.map(l => (
-
applyLayout(l)}
- className={`flex items-center gap-1 rounded px-2 py-0.5 cursor-pointer border transition-colors
- ${activeLayoutId === l.id ? 'bg-blue-900 border-blue-600 text-blue-300' : 'bg-gray-800 border-gray-600 text-gray-400 hover:border-gray-400 hover:text-gray-200'}`}>
- {l.name}
-
-
- ))}
- {showSaveAs ? (
-
- setSaveAsName(e.target.value)}
- onKeyDown={e => { if (e.key === 'Enter') handleSaveAs(); if (e.key === 'Escape') { setShowSaveAs(false); setSaveAsName('') } }}
- placeholder="Layout name…" className="border border-gray-600 rounded px-2 py-0.5 w-32 bg-gray-800 text-gray-200 focus:outline-none focus:border-blue-500 placeholder:text-gray-600" />
-
-
-
- ) : (
- <>
- {activeLayoutId !== null && (
-
- )}
-
- {activeLayoutId !== null && (
-
- )}
- >
- )}
-
-
-
-
- {/* Expand depth group */}
-
- Expand
- {[0, 1, 2, 3].map(d => (
-
- ))}
-
-
-
-
- {/* Data group */}
-
-
-
-
-
{msg && (
-
+
{msg.text}
)}
+
+ {/* Layout / depth bar */}
+
+
Layouts
+
+ {layouts.map(l => (
+
applyLayout(l)}
+ className={`flex items-center gap-1 text-xs rounded px-2 py-0.5 cursor-pointer border transition-colors
+ ${activeLayoutId === l.id ? 'bg-blue-50 border-blue-300 text-blue-700' : 'bg-white border-gray-200 text-gray-600 hover:border-gray-400'}`}>
+ {l.name}
+
+
+ ))}
+
+ {activeLayoutId !== null && !showSaveAs && (
+
+ )}
+
+ {showSaveAs ? (
+
+ setSaveAsName(e.target.value)}
+ onKeyDown={e => { if (e.key === 'Enter') handleSaveAs(); if (e.key === 'Escape') { setShowSaveAs(false); setSaveAsName('') } }}
+ placeholder="Layout name…" className="text-xs border border-gray-300 rounded px-2 py-0.5 w-32 focus:outline-none focus:border-blue-400" />
+
+
+
+ ) : (
+
+ )}
+
+ {activeLayoutId !== null && (
+
+ )}
+
+
+
+ {/* Depth controls */}
+
+ depth
+ {[0, 1, 2, 3].map(d => (
+
+ ))}
+
+
{/* History modal */}
{showLog && (
-
setShowLog(false)}>
-
e.stopPropagation()}>
-
-
Change log
-
+
setShowLog(false)}>
+
e.stopPropagation()}>
+
+ Change History
+
{logLoading ? (
-
Loading…
+
Loading…
) : logEntries.length === 0 ? (
-
No log entries yet.
+
No log entries yet.
) : (
-
+
| Time |
Op |
@@ -509,15 +493,15 @@ export default function Forecast() {
{logEntries.map(entry => (
-
- | {fmtStamp(entry.stamp)} |
+
+ | {fmtStamp(entry.stamp)} |
{entry.operation}
|
- {fmtSlice(entry.slice)} |
-
+ | {fmtSlice(entry.slice)} |
+
{editingNote?.id === entry.id ? (
-
-
+ className="border border-blue-300 rounded px-1.5 py-0.5 text-xs flex-1 focus:outline-none" />
+
+
) : (
setEditingNote({ id: entry.id, text: entry.note || '' })}
- className="cursor-text hover:bg-gray-700 rounded px-1 -mx-1 block truncate"
+ className="cursor-text hover:bg-blue-50 rounded px-1 -mx-1 block truncate"
title={entry.note || 'Click to add note'}>
- {entry.note || add note}
+ {entry.note || add note}
)}
|
@@ -543,7 +527,7 @@ export default function Forecast() {
@@ -562,40 +546,40 @@ export default function Forecast() {
{/* Perspective viewer */}
{loading && (
-
-
Loading…
+
+ Loading…
)}
{/* Drag handle */}
-
+
{/* Operation panel */}
-
-
-
Slice
+
+
+
Slice
{!hasSlice ? (
-
Click a pivot row to select a slice
+
Click a pivot row to select a slice
) : (
{Object.entries(slice).map(([k, v]) => (
-
-
{k} =
{v}
+
+ {k} = {v}
))}
-
+
)}
{hasSlice && (
<>
-
+
{['scale', 'recode', 'clone'].map(op => (
))}
@@ -604,10 +588,10 @@ export default function Forecast() {
{activeOp === 'scale' && <>
{/* Mode toggle */}
-
+
{[['target','= Target'],['delta','Δ Increment']].map(([m, label]) => (
))}
@@ -616,9 +600,9 @@ export default function Forecast() {
{/* Value row */}
{currentTotals?.valueCol && (
-
+
{currentTotals.valueCol}
- {currentTotals.value?.toLocaleString(undefined, {maximumFractionDigits:2})}
+ {currentTotals.value?.toLocaleString(undefined, {maximumFractionDigits:2})}
setScaleValue(e.target.value)}
@@ -630,9 +614,9 @@ export default function Forecast() {
{/* Units row */}
{currentTotals?.unitsCol && (
-
+
{currentTotals.unitsCol}
- {currentTotals.units?.toLocaleString(undefined, {maximumFractionDigits:2})}
+ {currentTotals.units?.toLocaleString(undefined, {maximumFractionDigits:2})}
setScaleUnits(e.target.value)}
@@ -652,7 +636,7 @@ export default function Forecast() {
>}
{activeOp === 'recode' && <>
-
New values for dimensions to replace. Leave blank to keep.
+
New values for dimensions to replace. Leave blank to keep.
{dimCols.map(c => (
setRecodeSet(s => ({ ...s, [c.cname]: e.target.value }))}
@@ -664,7 +648,7 @@ export default function Forecast() {
>}
{activeOp === 'clone' && <>
- Override dimensions on cloned rows. Leave blank to keep.
+ Override dimensions on cloned rows. Leave blank to keep.
{dimCols.map(c => (
setCloneSet(s => ({ ...s, [c.cname]: e.target.value }))}
@@ -684,7 +668,7 @@ export default function Forecast() {
)
}
-const inp = 'border border-gray-700 rounded px-2 py-1 text-xs flex-1 bg-gray-800 text-gray-200 placeholder:text-gray-600 min-w-0 focus:outline-none focus:border-blue-600'
+const inp = 'border border-gray-200 rounded px-2 py-1 text-xs flex-1 bg-white min-w-0'
function fmtStamp(stamp) {
return new Date(stamp).toLocaleString(undefined, { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' })
@@ -696,18 +680,18 @@ function fmtSlice(slice) {
}
const OP_BADGE = {
- baseline: 'bg-gray-700 text-gray-300',
- reference: 'bg-blue-900 text-blue-300',
- scale: 'bg-green-900 text-green-400',
- recode: 'bg-amber-900 text-amber-400',
- clone: 'bg-purple-900 text-purple-400',
+ baseline: 'bg-gray-100 text-gray-600',
+ reference: 'bg-blue-50 text-blue-600',
+ scale: 'bg-green-50 text-green-700',
+ recode: 'bg-amber-50 text-amber-700',
+ clone: 'bg-purple-50 text-purple-700',
}
-function opBadge(op) { return OP_BADGE[op] || 'bg-gray-700 text-gray-400' }
+function opBadge(op) { return OP_BADGE[op] || 'bg-gray-100 text-gray-500' }
function Row({ label, children }) {
return (
- {label}
+ {label}
{children}
)
@@ -715,7 +699,7 @@ function Row({ label, children }) {
function Submit({ onClick, children }) {
return (
-