mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-18 00:56:02 +00:00
SYNC: widget configuration saved to storage
This commit is contained in:
committed by
Diflow
parent
b12c79462e
commit
149611041e
@@ -141,11 +141,10 @@
|
||||
/>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="2">
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBar storageName="diagramSettingsWidget">
|
||||
<WidgetColumnBarItem
|
||||
title="Settings"
|
||||
name="diagramSettings"
|
||||
storageName="diagramSettingsWidget"
|
||||
onClose={() => {
|
||||
styleStore.update(x => ({ ...x, settingsVisible: false }));
|
||||
}}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
const cache = {};
|
||||
|
||||
export function getLocalStorage(key, defaultValue = undefined) {
|
||||
if (!key) return defaultValue;
|
||||
if (key in cache) return cache[key];
|
||||
const item = localStorage.getItem(key);
|
||||
if (item) {
|
||||
@@ -16,11 +17,13 @@ export function getLocalStorage(key, defaultValue = undefined) {
|
||||
}
|
||||
|
||||
export function setLocalStorage(key, value) {
|
||||
if (!key) return;
|
||||
localStorage.setItem(key, JSON.stringify(value));
|
||||
delete cache[key];
|
||||
}
|
||||
|
||||
export function removeLocalStorage(key) {
|
||||
if (!key) return;
|
||||
localStorage.removeItem(key);
|
||||
delete cache[key];
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
import WidgetColumnBarItem from './WidgetColumnBarItem.svelte';
|
||||
</script>
|
||||
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem title="Archive folders, DB models" name="folders" height="50%" storageName='archiveFoldersWidget'>
|
||||
<WidgetColumnBar storageName="archiveWidget">
|
||||
<WidgetColumnBarItem title="Archive folders, DB models" name="folders" height="50%">
|
||||
<ArchiveFolderList />
|
||||
</WidgetColumnBarItem>
|
||||
<WidgetColumnBarItem title="Files, Tables, Views, Functions" name="files" storageName='archiveFilesWidget'>
|
||||
<WidgetColumnBarItem title="Files, Tables, Views, Functions" name="files">
|
||||
<ArchiveFilesList />
|
||||
</WidgetColumnBarItem>
|
||||
</WidgetColumnBar>
|
||||
|
||||
@@ -17,14 +17,9 @@
|
||||
$: cloudContentList = useCloudContentList();
|
||||
</script>
|
||||
|
||||
<WidgetColumnBar {hidden}>
|
||||
<WidgetColumnBar {hidden} storageName="databaseWidget">
|
||||
{#if $config?.singleConnection}
|
||||
<WidgetColumnBarItem
|
||||
title={_t('widget.databases', { defaultMessage: 'Databases' })}
|
||||
name="databases"
|
||||
height="35%"
|
||||
storageName="databasesWidget"
|
||||
>
|
||||
<WidgetColumnBarItem title={_t('widget.databases', { defaultMessage: 'Databases' })} name="databases" height="35%">
|
||||
<SingleConnectionDatabaseList connection={$config?.singleConnection} />
|
||||
</WidgetColumnBarItem>
|
||||
{:else if !$config?.singleDbConnection}
|
||||
@@ -32,7 +27,6 @@
|
||||
title={_t('common.connections', { defaultMessage: 'Connections' })}
|
||||
name="connections"
|
||||
height="35%"
|
||||
storageName="connectionsWidget"
|
||||
>
|
||||
<ConnectionList
|
||||
passProps={{
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
title={_t('widget.pinned', { defaultMessage: 'Pinned' })}
|
||||
name="pinned"
|
||||
height="15%"
|
||||
storageName="pinnedItemsWidget"
|
||||
skip={!_.compact($pinnedDatabases).length &&
|
||||
!$pinnedTables.some(x => x && x.conid == conid && x.database == $currentDatabase?.name)}
|
||||
positiveCondition={correctCloudStatus}
|
||||
@@ -47,7 +46,6 @@
|
||||
? _t('widget.collectionsContainers', { defaultMessage: 'Collections/containers' })
|
||||
: _t('widget.tablesViewsFunctions', { defaultMessage: 'Tables, views, functions' })}
|
||||
name="dbObjectsSql"
|
||||
storageName="dbObjectsWidget"
|
||||
skip={!(
|
||||
conid &&
|
||||
(database || singleDatabase) &&
|
||||
@@ -61,7 +59,6 @@
|
||||
<WidgetColumnBarItem
|
||||
title={_t('widget.keys', { defaultMessage: 'Keys' })}
|
||||
name="dbObjectsKeyValue"
|
||||
storageName="dbObjectsWidget"
|
||||
skip={!(conid && (database || singleDatabase) && driver?.databaseEngineTypes?.includes('keyvalue'))}
|
||||
positiveCondition={correctCloudStatus}
|
||||
>
|
||||
@@ -71,7 +68,6 @@
|
||||
<WidgetColumnBarItem
|
||||
title={_t('widget.databaseContent', { defaultMessage: 'Database content' })}
|
||||
name="dbObjectsFocused"
|
||||
storageName="dbObjectsWidget"
|
||||
skip={conid && (database || singleDatabase)}
|
||||
positiveCondition={correctCloudStatus}
|
||||
>
|
||||
@@ -85,7 +81,6 @@
|
||||
<WidgetColumnBarItem
|
||||
title={_t('widget.databaseContent', { defaultMessage: 'Database content' })}
|
||||
name="dbObjectsError"
|
||||
storageName="dbObjectsWidget"
|
||||
skip={!(conid && (database || singleDatabase) && !driver)}
|
||||
positiveCondition={correctCloudStatus}
|
||||
>
|
||||
@@ -102,7 +97,6 @@
|
||||
title={_t('widget.databaseContent', { defaultMessage: 'Database content' })}
|
||||
name="incorrectClaudStatus"
|
||||
height="15%"
|
||||
storageName="incorrectClaudStatusWidget"
|
||||
skip={correctCloudStatus}
|
||||
>
|
||||
<WidgetsInnerContainer>
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
$: favorites = useFavorites();
|
||||
</script>
|
||||
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem title={_t('files.savedFiles', { defaultMessage: "Saved files" })} name="files" height="70%" storageName="savedFilesWidget">
|
||||
<WidgetColumnBar storageName="filesWidget">
|
||||
<WidgetColumnBarItem title={_t('files.savedFiles', { defaultMessage: 'Saved files' })} name="files" height="70%">
|
||||
<SavedFilesList />
|
||||
</WidgetColumnBarItem>
|
||||
|
||||
{#if hasPermission('files/favorites/read')}
|
||||
<WidgetColumnBarItem title={_t('files.favorites', { defaultMessage: "Favorites" })} name="favorites" storageName="favoritesWidget">
|
||||
<WidgetColumnBarItem title={_t('files.favorites', { defaultMessage: 'Favorites' })} name="favorites">
|
||||
<WidgetsInnerContainer>
|
||||
<AppObjectList list={$favorites || []} module={favoriteFileAppObject} />
|
||||
</WidgetsInnerContainer>
|
||||
|
||||
@@ -16,11 +16,13 @@
|
||||
import { _t } from '../translations';
|
||||
|
||||
$: favorites = useFavorites();
|
||||
|
||||
</script>
|
||||
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem title={_t('history.recentlyClosedTabs', { defaultMessage: "Recently closed tabs" })} name="closedTabs" storageName='closedTabsWidget'>
|
||||
<WidgetColumnBar storageName="historyWidget">
|
||||
<WidgetColumnBarItem
|
||||
title={_t('history.recentlyClosedTabs', { defaultMessage: 'Recently closed tabs' })}
|
||||
name="closedTabs"
|
||||
>
|
||||
<WidgetsInnerContainer>
|
||||
<AppObjectList
|
||||
list={_.sortBy(
|
||||
@@ -31,7 +33,7 @@
|
||||
/>
|
||||
</WidgetsInnerContainer>
|
||||
</WidgetColumnBarItem>
|
||||
<WidgetColumnBarItem title={_t('history.queryHistory', { defaultMessage: "Query history" })} name="queryHistory" storageName='queryHistoryWidget'>
|
||||
<WidgetColumnBarItem title={_t('history.queryHistory', { defaultMessage: 'Query history' })} name="queryHistory">
|
||||
<QueryHistoryList />
|
||||
</WidgetColumnBarItem>
|
||||
</WidgetColumnBar>
|
||||
|
||||
@@ -8,11 +8,15 @@
|
||||
import { _t } from '../translations';
|
||||
</script>
|
||||
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem title={_t('widgets.installedExtensions', { defaultMessage: 'Installed extensions' })} name="installed" height="50%" storageName='installedPluginsWidget'>
|
||||
<WidgetColumnBar storageName="pluginsWidget">
|
||||
<WidgetColumnBarItem
|
||||
title={_t('widgets.installedExtensions', { defaultMessage: 'Installed extensions' })}
|
||||
name="installed"
|
||||
height="50%"
|
||||
>
|
||||
<InstalledPluginsList />
|
||||
</WidgetColumnBarItem>
|
||||
<WidgetColumnBarItem title={_t('widgets.availableExtensions', { defaultMessage: 'Available extensions' })} name="all" storageName='allPluginsWidget'>
|
||||
<WidgetColumnBarItem title={_t('widgets.availableExtensions', { defaultMessage: 'Available extensions' })} name="all">
|
||||
<AvailablePluginsList />
|
||||
</WidgetColumnBarItem>
|
||||
</WidgetColumnBar>
|
||||
|
||||
@@ -162,7 +162,9 @@
|
||||
text: _t('privateCloudWidget.addExistingFolder', { defaultMessage: 'Add existing folder (from link)' }),
|
||||
onClick: () => {
|
||||
showModal(InputTextModal, {
|
||||
label: _t('privateCloudWidget.yourInviteLink', { defaultMessage: 'Your invite link (in form dbgate://folder/xxx)' }),
|
||||
label: _t('privateCloudWidget.yourInviteLink', {
|
||||
defaultMessage: 'Your invite link (in form dbgate://folder/xxx)',
|
||||
}),
|
||||
header: _t('privateCloudWidget.addExistingSharedFolder', { defaultMessage: 'Add existing shared folder' }),
|
||||
onConfirm: async newFolder => {
|
||||
apiCall('cloud/grant-folder', {
|
||||
@@ -192,7 +194,10 @@
|
||||
|
||||
const handleDelete = () => {
|
||||
showModal(ConfirmModal, {
|
||||
message: _t('privateCloudWidget.deleteFolderConfirm', { defaultMessage: 'Really delete folder {folder}? All folder content will be deleted!', values: { folder: contentGroupMap[folder]?.name } }),
|
||||
message: _t('privateCloudWidget.deleteFolderConfirm', {
|
||||
defaultMessage: 'Really delete folder {folder}? All folder content will be deleted!',
|
||||
values: { folder: contentGroupMap[folder]?.name },
|
||||
}),
|
||||
header: _t('privateCloudWidget.deleteFolder', { defaultMessage: 'Delete folder' }),
|
||||
onConfirm: () => {
|
||||
apiCall('cloud/delete-folder', {
|
||||
@@ -240,19 +245,26 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem
|
||||
title="DbGate Cloud"
|
||||
name="privateCloud"
|
||||
height="50%"
|
||||
storageName="privateCloudItems"
|
||||
skip={!$cloudSigninTokenHolder}
|
||||
>
|
||||
<WidgetColumnBar storageName="privateCloudItems">
|
||||
<WidgetColumnBarItem title="DbGate Cloud" name="privateCloud" height="50%" skip={!$cloudSigninTokenHolder}>
|
||||
<SearchBoxWrapper>
|
||||
<SearchInput placeholder={_t('privateCloudWidget.searchPlaceholder', { defaultMessage: 'Search cloud connections and files' })} bind:value={filter} />
|
||||
<SearchInput
|
||||
placeholder={_t('privateCloudWidget.searchPlaceholder', {
|
||||
defaultMessage: 'Search cloud connections and files',
|
||||
})}
|
||||
bind:value={filter}
|
||||
/>
|
||||
<CloseSearchButton bind:filter />
|
||||
<DropDownButton icon="icon plus-thick" menu={createAddItemMenu} title={_t('privateCloudWidget.addNewConnectionOrFile', { defaultMessage: 'Add new connection or file' })} />
|
||||
<DropDownButton icon="icon add-folder" menu={createAddFolderMenu} title={_t('privateCloudWidget.addNewFolder', { defaultMessage: 'Add new folder' })} />
|
||||
<DropDownButton
|
||||
icon="icon plus-thick"
|
||||
menu={createAddItemMenu}
|
||||
title={_t('privateCloudWidget.addNewConnectionOrFile', { defaultMessage: 'Add new connection or file' })}
|
||||
/>
|
||||
<DropDownButton
|
||||
icon="icon add-folder"
|
||||
menu={createAddFolderMenu}
|
||||
title={_t('privateCloudWidget.addNewFolder', { defaultMessage: 'Add new folder' })}
|
||||
/>
|
||||
<InlineButton
|
||||
on:click={handleRefreshContent}
|
||||
title={_t('privateCloudWidget.refreshFiles', { defaultMessage: 'Refresh files' })}
|
||||
@@ -289,7 +301,10 @@
|
||||
/>
|
||||
|
||||
{#if !cloudContentFlat?.length}
|
||||
<ErrorInfo message={_t('privateCloudWidget.noContent', { defaultMessage: 'You have no content on DbGate cloud' })} icon="img info" />
|
||||
<ErrorInfo
|
||||
message={_t('privateCloudWidget.noContent', { defaultMessage: 'You have no content on DbGate cloud' })}
|
||||
icon="img info"
|
||||
/>
|
||||
<div class="error-info">
|
||||
<div class="m-1"></div>
|
||||
<FormStyledButton
|
||||
|
||||
@@ -26,15 +26,21 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem title={_t('publicCloudWidget.publicKnowledgeBase', { defaultMessage: "Public Knowledge Base" })} name="publicCloud" storageName="publicCloudItems">
|
||||
<WidgetColumnBar storageName="publicCloudItems">
|
||||
<WidgetColumnBarItem
|
||||
title={_t('publicCloudWidget.publicKnowledgeBase', { defaultMessage: 'Public Knowledge Base' })}
|
||||
name="publicCloud"
|
||||
>
|
||||
<WidgetsInnerContainer>
|
||||
<SearchBoxWrapper>
|
||||
<SearchInput placeholder={_t('publicCloudWidget.searchPublicFiles', { defaultMessage: "Search public files" })} bind:value={filter} />
|
||||
<SearchInput
|
||||
placeholder={_t('publicCloudWidget.searchPublicFiles', { defaultMessage: 'Search public files' })}
|
||||
bind:value={filter}
|
||||
/>
|
||||
<CloseSearchButton bind:filter />
|
||||
<InlineButton
|
||||
on:click={handleRefreshPublic}
|
||||
title={_t('publicCloudWidget.refreshFiles', { defaultMessage: "Refresh files" })}
|
||||
title={_t('publicCloudWidget.refreshFiles', { defaultMessage: 'Refresh files' })}
|
||||
data-testid="CloudItemsWidget_buttonRefreshPublic"
|
||||
>
|
||||
<FontIcon icon="icon refresh" />
|
||||
@@ -49,12 +55,21 @@
|
||||
/>
|
||||
|
||||
{#if !$publicFiles?.length}
|
||||
<ErrorInfo message={_t('publicCloudWidget.noFilesFound', { defaultMessage: "No files found for your configuration" })} />
|
||||
<ErrorInfo
|
||||
message={_t('publicCloudWidget.noFilesFound', { defaultMessage: 'No files found for your configuration' })}
|
||||
/>
|
||||
<div class="error-info">
|
||||
<div class="m-1">
|
||||
{_t('publicCloudWidget.onlyRelevantFilesListed', { defaultMessage: "Only files relevant for your connections, platform and DbGate edition are listed. Please define connections at first." })}
|
||||
{_t('publicCloudWidget.onlyRelevantFilesListed', {
|
||||
defaultMessage:
|
||||
'Only files relevant for your connections, platform and DbGate edition are listed. Please define connections at first.',
|
||||
})}
|
||||
</div>
|
||||
<FormStyledButton value={_t('publicCloudWidget.refreshList', { defaultMessage: "Refresh list" })} skipWidth on:click={handleRefreshPublic} />
|
||||
<FormStyledButton
|
||||
value={_t('publicCloudWidget.refreshList', { defaultMessage: 'Refresh list' })}
|
||||
skipWidth
|
||||
on:click={handleRefreshPublic}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</WidgetsInnerContainer>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { onMount, setContext } from 'svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
import _ from 'lodash';
|
||||
import { getLocalStorage, setLocalStorage } from '../utility/storageCache';
|
||||
|
||||
export let hidden = false;
|
||||
export let storageName = null;
|
||||
@@ -12,7 +13,10 @@
|
||||
|
||||
// const widgetColumnBarHeight = writable(0);
|
||||
const widgetColumnBarComputed = writable({});
|
||||
let deltaHeights = {};
|
||||
const fromStorage = getLocalStorage(storageName);
|
||||
let deltaHeights = fromStorage?.deltaHeights || {};
|
||||
|
||||
$: setLocalStorage(storageName, { deltaHeights });
|
||||
|
||||
// setContext('widgetColumnBarHeight', widgetColumnBarHeight);
|
||||
setContext('pushWidgetItemDefinition', (name, item) => {
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
import { getContext } from 'svelte';
|
||||
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
import WidgetTitle from './WidgetTitle.svelte';
|
||||
import splitterDrag from '../utility/splitterDrag';
|
||||
import { getLocalStorage, setLocalStorage } from '../utility/storageCache';
|
||||
|
||||
Reference in New Issue
Block a user