fix(dashboard): fix Memory view dead space, unlabeled toolbar, and toggle-row alignment

- Working/Insights/Engines tabs now render a centered 960px content
  column instead of leaving the right half of wide viewports empty.
- The file editor's collapsed chevron-only toolbar (an unlabeled mystery
  control) now always shows its labeled actions in MemoryView.
- 'Process dreams' / 'Auto-summarize memory' rows share one aligned
  layout, sentence case, and a tooltip explaining dream processing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-07-10 16:05:47 -07:00
parent ed163cfc81
commit c73094ec7f
9 changed files with 67 additions and 7 deletions

View File

@@ -0,0 +1,7 @@
---
"@runfusion/fusion": patch
---
summary: Polish the Memory view: centered layout, labeled editor toolbar, aligned toggle rows.
category: fix
dev: MemoryView tabs get a 960px centered column; FileEditor instances pass forceToolbarActionsVisible; new i18n key memory.dreamsEnabledTooltip.

View File

@@ -59,6 +59,12 @@ After the header migrated to the shared .view-header (which is flex-shrink:0), t
padding: 0 var(--space-lg) var(--space-lg); padding: 0 var(--space-lg) var(--space-lg);
} }
/*
FNXC:MemoryView 2026-07-10-14:30:
First-run review on a wide desktop viewport: the Working Memory content hugged the left half of the view and the entire right half was empty background.
Cap each tab pane to a readable content-column width and center it with auto inline margins, matching the app convention for wide layouts (e.g. .project-overview__body caps and centers its scroll body).
The pane stays the scroll owner; width:100% keeps narrow/mobile viewports (max-width: 768px / max-height: 480px breakpoint) unchanged because the cap only bites above it.
*/
.memory-working-tab, .memory-working-tab,
.memory-insights-tab, .memory-insights-tab,
.memory-engines-tab { .memory-engines-tab {
@@ -67,6 +73,9 @@ After the header migrated to the shared .view-header (which is flex-shrink:0), t
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow-y: auto; overflow-y: auto;
width: 100%;
max-width: 960px;
margin-inline: auto;
} }
/* /*
@@ -435,6 +444,23 @@ The memory editor box is CAPPED to about a page (max-height: 60vh) so a long mem
padding: var(--space-sm) 0; padding: var(--space-sm) 0;
} }
/*
FNXC:MemoryView 2026-07-10-14:30:
Shared layout for the automation checkbox rows ("Process dreams from daily memory", "Auto-summarize memory").
Both rows must render identically: checkbox and label on one line, and the hint text indented to start where the label text starts (checkbox width 16px + the .checkbox-label gap), instead of hanging at the form-group edge with row-dependent spacing.
Scoped under .memory-working-tab so these rules out-specify same-name form rules from SettingsModal.css (imported after this file).
*/
.memory-working-tab .memory-toggle-row .checkbox-label {
align-items: center;
}
.memory-working-tab .memory-toggle-row > small {
display: block;
margin-top: var(--space-xs);
margin-left: calc(16px + var(--space-sm));
color: var(--text-muted);
}
.memory-flex-spacer { .memory-flex-spacer {
flex: 1; flex: 1;
} }

View File

@@ -450,11 +450,17 @@ export function MemoryView({ projectId, addToast, onSendSelectionToTask }: Memor
<label>{selectedMemoryFile?.label || t("memory.editorLabel", "Memory Editor")}</label> <label>{selectedMemoryFile?.label || t("memory.editorLabel", "Memory Editor")}</label>
<small>{selectedLayerDescription}</small> <small>{selectedLayerDescription}</small>
<div className="memory-editor-container"> <div className="memory-editor-container">
{/*
FNXC:MemoryView 2026-07-10-14:30:
First-run review: the FileEditor's collapsed toolbar rendered as an unlabeled empty bar with only a chevron above the editor, and a user asked "what is this button?".
Force the toolbar actions (Edit/Preview/Wrap) to stay visible so the toolbar always shows labeled controls instead of a mystery chevron-only bar.
*/}
<FileEditor <FileEditor
content={selectedFileContent} content={selectedFileContent}
onChange={setSelectedFileContent} onChange={setSelectedFileContent}
readOnly={!isWritable} readOnly={!isWritable}
filePath={selectedFilePath} filePath={selectedFilePath}
forceToolbarActionsVisible
onSendSelectionToTask={onSendSelectionToTask} onSendSelectionToTask={onSendSelectionToTask}
/> />
</div> </div>
@@ -501,9 +507,19 @@ export function MemoryView({ projectId, addToast, onSendSelectionToTask }: Memor
</div> </div>
<div className="memory-config-section"> <div className="memory-config-section">
{/*
FNXC:MemoryView 2026-07-10-14:30:
First-run review: the two automation checkbox rows ("Process dreams from daily memory" / "Auto-Summarize Memory") had inconsistent checkbox/label/hint alignment and mixed casing (sentence case vs Title Case).
Both rows now share the .memory-toggle-row layout (hint indented under the label text, aligned past the checkbox) and use sentence-case labels.
The dreams row also carries a hover tooltip (title attr) explaining the pipeline: daily notes are distilled into DREAMS.md and reusable lessons are promoted into MEMORY.md.
*/}
<div className="memory-settings-group"> <div className="memory-settings-group">
<div className="form-group"> <div className="form-group memory-toggle-row">
<label htmlFor="memoryDreamsEnabled" className="checkbox-label"> <label
htmlFor="memoryDreamsEnabled"
className="checkbox-label"
title={t("memory.dreamsEnabledTooltip", "Daily notes are distilled into DREAMS.md and reusable lessons are promoted into MEMORY.md.")}
>
<input <input
id="memoryDreamsEnabled" id="memoryDreamsEnabled"
type="checkbox" type="checkbox"
@@ -564,7 +580,7 @@ export function MemoryView({ projectId, addToast, onSendSelectionToTask }: Memor
</div> </div>
<div className="memory-settings-group"> <div className="memory-settings-group">
<div className="form-group"> <div className="form-group memory-toggle-row">
<label htmlFor="memoryAutoSummarizeEnabled" className="checkbox-label"> <label htmlFor="memoryAutoSummarizeEnabled" className="checkbox-label">
<input <input
id="memoryAutoSummarizeEnabled" id="memoryAutoSummarizeEnabled"
@@ -578,9 +594,9 @@ export function MemoryView({ projectId, addToast, onSendSelectionToTask }: Memor
}} }}
disabled={!memorySettingsDraft.memoryEnabled || settingsLoading} disabled={!memorySettingsDraft.memoryEnabled || settingsLoading}
/> />
{t("memory.autoSummarizeLabel", "Auto-Summarize Memory")} {t("memory.autoSummarizeLabel", "Auto-summarize memory")}
</label> </label>
<small>{t("memory.autoSummarizeHint", "Automatically compact memory when it exceeds the threshold on a schedule")}</small> <small>{t("memory.autoSummarizeHint", "Automatically compacts memory when it exceeds the threshold on a schedule.")}</small>
</div> </div>
{memorySettingsDraft.memoryEnabled && memorySettingsDraft.memoryAutoSummarizeEnabled && ( {memorySettingsDraft.memoryEnabled && memorySettingsDraft.memoryAutoSummarizeEnabled && (
@@ -668,11 +684,16 @@ export function MemoryView({ projectId, addToast, onSendSelectionToTask }: Memor
// Raw editor mode // Raw editor mode
<div className="memory-insights-editor-layout"> <div className="memory-insights-editor-layout">
<div className="memory-editor-container"> <div className="memory-editor-container">
{/*
FNXC:MemoryView 2026-07-10-14:30:
Same as the working-memory editor: keep toolbar actions visible so no unlabeled chevron-only bar renders above the raw insights editor.
*/}
<FileEditor <FileEditor
content={insightsEditorContent ?? ""} content={insightsEditorContent ?? ""}
onChange={setInsightsEditorContent} onChange={setInsightsEditorContent}
readOnly={false} readOnly={false}
filePath=".fusion/memory/INSIGHTS.md" filePath=".fusion/memory/INSIGHTS.md"
forceToolbarActionsVisible
onSendSelectionToTask={onSendSelectionToTask} onSendSelectionToTask={onSendSelectionToTask}
/> />
</div> </div>

View File

@@ -3405,8 +3405,8 @@
}, },
"memory": { "memory": {
"auditChecksTitle": "Audit Checks", "auditChecksTitle": "Audit Checks",
"autoSummarizeHint": "Automatically compact memory when it exceeds the threshold on a schedule", "autoSummarizeHint": "Automatically compacts memory when it exceeds the threshold on a schedule.",
"autoSummarizeLabel": "Auto-Summarize Memory", "autoSummarizeLabel": "Auto-summarize memory",
"autoSummarizeScheduleHint": "Cron expression for auto-summarize schedule (default: daily at 3 AM)", "autoSummarizeScheduleHint": "Cron expression for auto-summarize schedule (default: daily at 3 AM)",
"autoSummarizeScheduleLabel": "Schedule (cron)", "autoSummarizeScheduleLabel": "Schedule (cron)",
"backendFile": "File (.fusion/memory/, agent/<agent-name>/memory/)", "backendFile": "File (.fusion/memory/, agent/<agent-name>/memory/)",
@@ -3435,6 +3435,7 @@
"dreamProcessingFailed": "Failed to run dream processing", "dreamProcessingFailed": "Failed to run dream processing",
"dreamsEnabledHint": "Turns daily notes into DREAMS.md and promotes reusable lessons into MEMORY.md.", "dreamsEnabledHint": "Turns daily notes into DREAMS.md and promotes reusable lessons into MEMORY.md.",
"dreamsEnabledLabel": "Process dreams from daily memory", "dreamsEnabledLabel": "Process dreams from daily memory",
"dreamsEnabledTooltip": "Daily notes are distilled into DREAMS.md and reusable lessons are promoted into MEMORY.md.",
"dreamsScheduleHint": "Cron expression for dream processing.", "dreamsScheduleHint": "Cron expression for dream processing.",
"dreamsScheduleLabel": "Dream Schedule", "dreamsScheduleLabel": "Dream Schedule",
"editorDefaultDescription": "Edits the selected memory file.", "editorDefaultDescription": "Edits the selected memory file.",

View File

@@ -3425,6 +3425,7 @@
"dreamProcessingFailed": "Error al ejecutar el procesamiento de sueños", "dreamProcessingFailed": "Error al ejecutar el procesamiento de sueños",
"dreamsEnabledHint": "Convierte las notas diarias en DREAMS.md y promueve las lecciones reutilizables en MEMORY.md.", "dreamsEnabledHint": "Convierte las notas diarias en DREAMS.md y promueve las lecciones reutilizables en MEMORY.md.",
"dreamsEnabledLabel": "Procesar sueños desde la memoria diaria", "dreamsEnabledLabel": "Procesar sueños desde la memoria diaria",
"dreamsEnabledTooltip": "Las notas diarias se destilan en DREAMS.md y las lecciones reutilizables se promueven a MEMORY.md.",
"dreamsScheduleHint": "Expresión cron para el procesamiento de sueños.", "dreamsScheduleHint": "Expresión cron para el procesamiento de sueños.",
"dreamsScheduleLabel": "Programación de sueños", "dreamsScheduleLabel": "Programación de sueños",
"editorDefaultDescription": "Edita el archivo de memoria seleccionado.", "editorDefaultDescription": "Edita el archivo de memoria seleccionado.",

View File

@@ -3425,6 +3425,7 @@
"dreamProcessingFailed": "Échec du traitement des rêves", "dreamProcessingFailed": "Échec du traitement des rêves",
"dreamsEnabledHint": "Transforme les notes quotidiennes en DREAMS.md et promeut les leçons réutilisables dans MEMORY.md.", "dreamsEnabledHint": "Transforme les notes quotidiennes en DREAMS.md et promeut les leçons réutilisables dans MEMORY.md.",
"dreamsEnabledLabel": "Traiter les rêves depuis la mémoire quotidienne", "dreamsEnabledLabel": "Traiter les rêves depuis la mémoire quotidienne",
"dreamsEnabledTooltip": "Les notes quotidiennes sont distillées dans DREAMS.md et les leçons réutilisables sont promues dans MEMORY.md.",
"dreamsScheduleHint": "Expression cron pour le traitement des rêves.", "dreamsScheduleHint": "Expression cron pour le traitement des rêves.",
"dreamsScheduleLabel": "Planification des rêves", "dreamsScheduleLabel": "Planification des rêves",
"editorDefaultDescription": "Modifie le fichier mémoire sélectionné.", "editorDefaultDescription": "Modifie le fichier mémoire sélectionné.",

View File

@@ -3425,6 +3425,7 @@
"dreamProcessingFailed": "드림 처리 실행에 실패했습니다", "dreamProcessingFailed": "드림 처리 실행에 실패했습니다",
"dreamsEnabledHint": "일일 메모를 DREAMS.md로 변환하고 재사용 가능한 교훈을 MEMORY.md로 승격합니다.", "dreamsEnabledHint": "일일 메모를 DREAMS.md로 변환하고 재사용 가능한 교훈을 MEMORY.md로 승격합니다.",
"dreamsEnabledLabel": "일일 메모리에서 드림 처리", "dreamsEnabledLabel": "일일 메모리에서 드림 처리",
"dreamsEnabledTooltip": "일일 노트는 DREAMS.md로 정제되고 재사용 가능한 교훈은 MEMORY.md로 승격됩니다.",
"dreamsScheduleHint": "드림 처리의 크론 표현식입니다.", "dreamsScheduleHint": "드림 처리의 크론 표현식입니다.",
"dreamsScheduleLabel": "드림 일정", "dreamsScheduleLabel": "드림 일정",
"editorDefaultDescription": "선택한 메모리 파일을 편집합니다.", "editorDefaultDescription": "선택한 메모리 파일을 편집합니다.",

View File

@@ -3425,6 +3425,7 @@
"dreamProcessingFailed": "运行梦境处理失败", "dreamProcessingFailed": "运行梦境处理失败",
"dreamsEnabledHint": "将每日笔记转换为 DREAMS.md,并将可复用的经验提升到 MEMORY.md。", "dreamsEnabledHint": "将每日笔记转换为 DREAMS.md,并将可复用的经验提升到 MEMORY.md。",
"dreamsEnabledLabel": "从每日记忆中处理梦境", "dreamsEnabledLabel": "从每日记忆中处理梦境",
"dreamsEnabledTooltip": "每日笔记会被提炼到 DREAMS.md,可复用的经验会被提升到 MEMORY.md。",
"dreamsScheduleHint": "梦境处理的 Cron 表达式。", "dreamsScheduleHint": "梦境处理的 Cron 表达式。",
"dreamsScheduleLabel": "梦境计划", "dreamsScheduleLabel": "梦境计划",
"editorDefaultDescription": "编辑所选记忆文件。", "editorDefaultDescription": "编辑所选记忆文件。",

View File

@@ -3425,6 +3425,7 @@
"dreamProcessingFailed": "執行夢境處理失敗", "dreamProcessingFailed": "執行夢境處理失敗",
"dreamsEnabledHint": "將每日筆記轉換為 DREAMS.md,並將可重用的經驗提升至 MEMORY.md。", "dreamsEnabledHint": "將每日筆記轉換為 DREAMS.md,並將可重用的經驗提升至 MEMORY.md。",
"dreamsEnabledLabel": "從每日記憶中處理夢境", "dreamsEnabledLabel": "從每日記憶中處理夢境",
"dreamsEnabledTooltip": "每日筆記會被提煉到 DREAMS.md,可重複使用的經驗會被提升到 MEMORY.md。",
"dreamsScheduleHint": "夢境處理的 Cron 表達式。", "dreamsScheduleHint": "夢境處理的 Cron 表達式。",
"dreamsScheduleLabel": "夢境排程", "dreamsScheduleLabel": "夢境排程",
"editorDefaultDescription": "編輯所選記憶檔案。", "editorDefaultDescription": "編輯所選記憶檔案。",