Skip to content

Commit fb530c2

Browse files
larrydarko1Copilot
andcommitted
feat: added unsaved changes message, since there's no autosave
Co-authored-by: Copilot <copilot@github.com>
1 parent 626c0e0 commit fb530c2

6 files changed

Lines changed: 44 additions & 2 deletions

File tree

src/renderer/components/CanvasTabs.vue

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ function ctxDelete() {
223223

224224
<!-- Zoom controls -->
225225
<div class="canvas-tabs-spacer"></div>
226+
<span v-if="ss.isDirty.value" class="unsaved-message" title="You have unsaved changes (⌘S to save)"
227+
>Unsaved changes</span
228+
>
226229
<div class="zoom-controls">
227230
<button
228231
class="zoom-btn"
@@ -433,7 +436,7 @@ function ctxDelete() {
433436
align-items: center;
434437
gap: 2px;
435438
flex-shrink: 0;
436-
margin-right: 2px;
439+
margin-right: 8px;
437440
}
438441
439442
.zoom-btn {
@@ -528,4 +531,37 @@ function ctxDelete() {
528531
}
529532
}
530533
}
534+
535+
.unsaved-message {
536+
display: inline-flex;
537+
align-items: center;
538+
gap: 6px;
539+
font-size: 11px;
540+
font-weight: 500;
541+
padding: 0 9px;
542+
height: 22px;
543+
border-radius: 11px;
544+
background: rgba(245, 158, 11, 0.1);
545+
border: 1px solid rgba(245, 158, 11, 0.35);
546+
color: #b45309;
547+
flex-shrink: 0;
548+
margin-right: 8px;
549+
cursor: default;
550+
-webkit-app-region: no-drag;
551+
552+
[data-theme='dark'] & {
553+
background: rgba(245, 158, 11, 0.12);
554+
border-color: rgba(245, 158, 11, 0.3);
555+
color: #fbbf24;
556+
}
557+
558+
&::before {
559+
content: '';
560+
width: 6px;
561+
height: 6px;
562+
border-radius: 50%;
563+
background: #f59e0b;
564+
flex-shrink: 0;
565+
}
566+
}
531567
</style>

src/renderer/components/Toolbar.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,6 @@ function applyTheme() {
647647
</template>
648648

649649
<div class="toolbar-spacer"></div>
650-
651650
<div class="toolbar-group">
652651
<button class="tb theme-toggle" :title="isDark ? 'Light mode' : 'Dark mode'" @click="toggleTheme">
653652
<!-- Sun icon (shown in dark mode) -->

src/renderer/composables/spreadsheet/state.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export function createState() {
7070
const formulaRefs = ref<FormulaRef[]>([]);
7171
const canUndo = ref(false);
7272
const canRedo = ref(false);
73+
const isDirty = ref(false);
7374
const chartSelectionMode = ref<string | null>(null);
7475
const chartSelectionActive = computed(() => chartSelectionMode.value !== null);
7576
const currentFilePath = ref<string | null>(null);
@@ -94,6 +95,7 @@ export function createState() {
9495
formulaRefs,
9596
canUndo,
9697
canRedo,
98+
isDirty,
9799
chartSelectionMode,
98100
chartSelectionActive,
99101
currentFilePath,

src/renderer/composables/spreadsheet/useFileOps.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ export function createFileOps(state: SpreadsheetCoreState, deps: FileOpsDeps) {
146146
state.activeTextBoxId.value = null;
147147
state.activeChartId.value = null;
148148
state.isEditing.value = false;
149+
state.isDirty.value = false;
149150
deps.recalculate();
150151
return true;
151152
} catch (error) {
@@ -175,6 +176,7 @@ export function createFileOps(state: SpreadsheetCoreState, deps: FileOpsDeps) {
175176

176177
if (result.success) {
177178
state.currentFilePath.value = targetPath;
179+
state.isDirty.value = false;
178180
return true;
179181
} else {
180182
alert(`Failed to save file: ${result.error}`);
@@ -227,6 +229,7 @@ export function createFileOps(state: SpreadsheetCoreState, deps: FileOpsDeps) {
227229
state.activeChartId.value = null;
228230
state.isEditing.value = false;
229231
state.currentFilePath.value = null;
232+
state.isDirty.value = false;
230233
state.counters.maxZ = 0;
231234
state.counters.tableCount = 0;
232235
state.counters.canvasCount = 1;

src/renderer/composables/spreadsheet/useUndoRedo.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export function createUndoRedo(state: SpreadsheetCoreState, deps: UndoRedoDeps)
3737
redoStack.length = 0;
3838
state.canUndo.value = undoStack.length > 0;
3939
state.canRedo.value = false;
40+
state.isDirty.value = true;
4041
queueMicrotask(() => {
4142
undoNesting = 0;
4243
});

src/renderer/composables/useSpreadsheet.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ export function useSpreadsheet() {
137137
formulaRefs: state.formulaRefs,
138138
canUndo: state.canUndo,
139139
canRedo: state.canRedo,
140+
isDirty: state.isDirty,
140141
chartSelectionMode: state.chartSelectionMode,
141142
chartSelectionActive: state.chartSelectionActive,
142143

0 commit comments

Comments
 (0)