unsaved file marker

This commit is contained in:
Jan Prochazka
2022-09-29 13:58:09 +02:00
parent 1382461bdc
commit 7604889b72
7 changed files with 59 additions and 14 deletions

View File

@@ -0,0 +1,31 @@
<script lang="ts">
import FontIcon from '../icons/FontIcon.svelte';
export let unsaved = false;
let mousein = false;
</script>
<span
class="close-button tabCloseButton"
on:click
on:mouseenter={() => {
mousein = true;
}}
on:mouseleave={() => {
mousein = false;
}}
>
<FontIcon icon={unsaved && !mousein ? 'icon unsaved' : 'icon close'} />
</span>
<style>
.close-button {
margin-left: 5px;
color: var(--theme-font-3);
}
.close-button:hover {
color: var(--theme-font-1);
}
</style>

View File

@@ -46,6 +46,7 @@
'icon file': 'mdi mdi-file', 'icon file': 'mdi mdi-file',
'icon loading': 'mdi mdi-loading mdi-spin', 'icon loading': 'mdi mdi-loading mdi-spin',
'icon close': 'mdi mdi-close', 'icon close': 'mdi mdi-close',
'icon unsaved': 'mdi mdi-record',
'icon stop': 'mdi mdi-close-octagon', 'icon stop': 'mdi mdi-close-octagon',
'icon filter': 'mdi mdi-filter', 'icon filter': 'mdi mdi-filter',
'icon filter-off': 'mdi mdi-filter-off', 'icon filter-off': 'mdi mdi-filter-off',

View File

@@ -554,6 +554,7 @@
editor.on('focus', () => dispatch('focus')); editor.on('focus', () => dispatch('focus'));
editor.setReadOnly(readOnly); editor.setReadOnly(readOnly);
editor.on('change', () => { editor.on('change', () => {
const content = editor.getValue(); const content = editor.getValue();
value = content; value = content;

View File

@@ -52,7 +52,7 @@
import useEditorData from '../query/useEditorData'; import useEditorData from '../query/useEditorData';
import { extensions } from '../stores'; import { extensions } from '../stores';
import applyScriptTemplate from '../utility/applyScriptTemplate'; import applyScriptTemplate from '../utility/applyScriptTemplate';
import { changeTab } from '../utility/common'; import { changeTab, markTabUnsaved } from '../utility/common';
import { getDatabaseInfo, useConnectionInfo } from '../utility/metadataLoaders'; import { getDatabaseInfo, useConnectionInfo } from '../utility/metadataLoaders';
import SocketMessageView from '../query/SocketMessageView.svelte'; import SocketMessageView from '../query/SocketMessageView.svelte';
import useEffect from '../utility/useEffect'; import useEffect from '../utility/useEffect';
@@ -283,6 +283,8 @@
} }
const quickExportHandlerRef = createQuickExportHandlerRef(); const quickExportHandlerRef = createQuickExportHandlerRef();
let isInitialized = false;
</script> </script>
<ToolStripContainer> <ToolStripContainer>
@@ -298,11 +300,17 @@
menu={createMenu()} menu={createMenu()}
on:input={e => { on:input={e => {
setEditorData(e.detail); setEditorData(e.detail);
if (isInitialized) {
markTabUnsaved(tabid);
}
errorMessages = []; errorMessages = [];
}} }}
on:focus={() => { on:focus={() => {
activator.activate(); activator.activate();
invalidateCommands(); invalidateCommands();
setTimeout(() => {
isInitialized = true;
}, 100);
}} }}
bind:this={domEditor} bind:this={domEditor}
onExecuteFragment={(sql, startLine) => executeCore(sql, startLine)} onExecuteFragment={(sql, startLine) => executeCore(sql, startLine)}

View File

@@ -1,4 +1,4 @@
import { openedTabs } from '../stores'; import { getOpenedTabs, openedTabs } from '../stores';
import _ from 'lodash'; import _ from 'lodash';
import getElectron from './getElectron'; import getElectron from './getElectron';
@@ -18,6 +18,16 @@ export function changeTab(tabid, changeFunc) {
openedTabs.update(files => files.map(tab => (tab.tabid == tabid ? changeFunc(tab) : tab))); openedTabs.update(files => files.map(tab => (tab.tabid == tabid ? changeFunc(tab) : tab)));
} }
export function markTabUnsaved(tabid) {
const tab = getOpenedTabs().find(x => x.tabid == tabid);
if (tab.unsaved) return;
openedTabs.update(files => files.map(tab => (tab.tabid == tabid ? { ...tab, unsaved: true } : tab)));
}
export function markTabSaved(tabid) {
openedTabs.update(files => files.map(tab => (tab.tabid == tabid ? { ...tab, unsaved: false } : tab)));
}
export function setSelectedTabFunc(files, tabid) { export function setSelectedTabFunc(files, tabid) {
return [ return [
...(files || []).filter(x => x.tabid != tabid).map(x => ({ ...x, selected: false })), ...(files || []).filter(x => x.tabid != tabid).map(x => ({ ...x, selected: false })),

View File

@@ -1,7 +1,7 @@
import { derived, get } from 'svelte/store'; import { derived, get } from 'svelte/store';
import { showModal } from '../modals/modalTools'; import { showModal } from '../modals/modalTools';
import { openedTabs } from '../stores'; import { openedTabs } from '../stores';
import { changeTab } from './common'; import { changeTab, markTabSaved } from './common';
import SaveFileModal from '../modals/SaveFileModal.svelte'; import SaveFileModal from '../modals/SaveFileModal.svelte';
import registerCommand from '../commands/registerCommand'; import registerCommand from '../commands/registerCommand';
import { apiCall } from './api'; import { apiCall } from './api';
@@ -24,12 +24,14 @@ export default async function saveTabFile(editor, saveMode, folder, format, file
if (savedFilePath) { if (savedFilePath) {
await apiCall('files/save-as', { filePath: savedFilePath, data, format }); await apiCall('files/save-as', { filePath: savedFilePath, data, format });
} }
markTabSaved(tabid);
}; };
const onSave = (title, newProps) => { const onSave = (title, newProps) => {
changeTab(tabid, tab => ({ changeTab(tabid, tab => ({
...tab, ...tab,
title, title,
unsaved: false,
props: { props: {
...tab.props, ...tab.props,
savedFormat: format, savedFormat: format,

View File

@@ -212,6 +212,7 @@
import { getConnectionInfo, useConnectionList } from '../utility/metadataLoaders'; import { getConnectionInfo, useConnectionList } from '../utility/metadataLoaders';
import { duplicateTab, getTabDbKey, sortTabs, groupTabs } from '../utility/openNewTab'; import { duplicateTab, getTabDbKey, sortTabs, groupTabs } from '../utility/openNewTab';
import { useConnectionColorFactory } from '../utility/useConnectionColor'; import { useConnectionColorFactory } from '../utility/useConnectionColor';
import TabCloseButton from '../elements/TabCloseButton.svelte';
$: connectionList = useConnectionList(); $: connectionList = useConnectionList();
@@ -434,7 +435,7 @@
<FontIcon icon="icon lock" /> <FontIcon icon="icon lock" />
{/if} {/if}
</div> </div>
22
<div <div
class="close-button-right tabCloseButton" class="close-button-right tabCloseButton"
on:click={e => closeMultipleTabs(tab => tabGroup.tabs.find(x => x.tabid == tab.tabid))} on:click={e => closeMultipleTabs(tab => tabGroup.tabs.find(x => x.tabid == tab.tabid))}
@@ -479,9 +480,7 @@
<span class="file-name"> <span class="file-name">
{tab.title} {tab.title}
</span> </span>
<span class="close-button tabCloseButton" on:click={e => closeTab(tab.tabid)}> <TabCloseButton unsaved={tab.unsaved} on:click={e => closeTab(tab.tabid)} />
<FontIcon icon="icon close" />
</span>
</div> </div>
{/each} {/each}
</div> </div>
@@ -582,19 +581,12 @@
white-space: nowrap; white-space: nowrap;
flex-grow: 1; flex-grow: 1;
} }
.close-button {
margin-left: 5px;
color: var(--theme-font-3);
}
.close-button-right { .close-button-right {
margin-left: 5px; margin-left: 5px;
margin-right: 5px; margin-right: 5px;
color: var(--theme-font-3); color: var(--theme-font-3);
} }
.close-button:hover {
color: var(--theme-font-1);
}
.close-button-right:hover { .close-button-right:hover {
color: var(--theme-font-1); color: var(--theme-font-1);
} }