From 19f5bf3dd42c2c34379194b24e13b776fb19cb56 Mon Sep 17 00:00:00 2001 From: rique223 Date: Sat, 29 Nov 2025 17:07:51 -0300 Subject: [PATCH 1/8] feat(store): :sparkles: add saved queries store with persistence Add Pinia store for saved queries with CRUD actions and marker utilities --- src/renderer/stores/savedQueries.ts | 244 ++++++++++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 src/renderer/stores/savedQueries.ts diff --git a/src/renderer/stores/savedQueries.ts b/src/renderer/stores/savedQueries.ts new file mode 100644 index 00000000..3722958e --- /dev/null +++ b/src/renderer/stores/savedQueries.ts @@ -0,0 +1,244 @@ +import { uidGen } from 'common/libs/uidGen'; +import * as Store from 'electron-store'; +import { defineStore } from 'pinia'; + +const persistentStore = new Store({ name: 'saved-queries' }); + +export const SAVED_QUERY_MARKER_PREFIX = 'saved-query:'; +export const getSavedQueryMarker = (queryUid: string): string => `${SAVED_QUERY_MARKER_PREFIX}${queryUid}`; +export const isSavedQueryMarker = (elementType?: string): boolean => + elementType?.startsWith(SAVED_QUERY_MARKER_PREFIX) ?? false; +export const extractQueryUidFromMarker = (elementType: string): string | null => + isSavedQueryMarker(elementType) ? elementType.replace(SAVED_QUERY_MARKER_PREFIX, '') : null; + +export interface SavedQuery { + uid: string; + name: string; + sql: string; + folderId: string | null; + connectionUid: string; + schema?: string; + database?: string; + createdAt: string; + updatedAt: string; +} + +export interface QueryFolder { + uid: string; + name: string; + connectionUid: string; + parentId: string | null; + isExpanded?: boolean; + createdAt: string; +} + +export interface ConnectionQueries { + queries: SavedQuery[]; + folders: QueryFolder[]; +} + +export const useSavedQueriesStore = defineStore('savedQueries', { + state: () => ({ + queriesByConnection: persistentStore.get('queriesByConnection', {}) as Record + }), + getters: { + getQueriesByConnection: (state) => (connectionUid: string): ConnectionQueries => { + return state.queriesByConnection[connectionUid] || { queries: [], folders: [] }; + }, + getQueryById: (state) => (connectionUid: string, queryUid: string): SavedQuery | undefined => { + const connectionData = state.queriesByConnection[connectionUid]; + if (!connectionData) return undefined; + return connectionData.queries.find(q => q.uid === queryUid); + }, + getFolderById: (state) => (connectionUid: string, folderUid: string): QueryFolder | undefined => { + const connectionData = state.queriesByConnection[connectionUid]; + if (!connectionData) return undefined; + return connectionData.folders.find(f => f.uid === folderUid); + }, + getRootQueries: (state) => (connectionUid: string): SavedQuery[] => { + const connectionData = state.queriesByConnection[connectionUid]; + if (!connectionData) return []; + return connectionData.queries.filter(q => q.folderId === null); + }, + getRootFolders: (state) => (connectionUid: string): QueryFolder[] => { + const connectionData = state.queriesByConnection[connectionUid]; + if (!connectionData) return []; + return connectionData.folders.filter(f => f.parentId === null); + }, + getQueriesInFolder: (state) => (connectionUid: string, folderId: string): SavedQuery[] => { + const connectionData = state.queriesByConnection[connectionUid]; + if (!connectionData) return []; + return connectionData.queries.filter(q => q.folderId === folderId); + }, + getSubfolders: (state) => (connectionUid: string, parentId: string): QueryFolder[] => { + const connectionData = state.queriesByConnection[connectionUid]; + if (!connectionData) return []; + return connectionData.folders.filter(f => f.parentId === parentId); + }, + getQueryCount: (state) => (connectionUid: string): number => { + const connectionData = state.queriesByConnection[connectionUid]; + if (!connectionData) return 0; + return connectionData.queries.length; + } + }, + actions: { + _ensureConnectionData (connectionUid: string): void { + if (!this.queriesByConnection[connectionUid]) this.queriesByConnection[connectionUid] = { queries: [], folders: [] }; + }, + _persist (): void { + persistentStore.set('queriesByConnection', this.queriesByConnection); + }, + addQuery (args: { connectionUid: string; name: string; sql: string; folderId?: string; schema?: string; database?: string }): SavedQuery { + this._ensureConnectionData(args.connectionUid); + + const now = new Date().toISOString(); + const newQuery: SavedQuery = { + uid: uidGen('SQ'), + name: args.name, + sql: args.sql, + folderId: args.folderId ?? null, + connectionUid: args.connectionUid, + schema: args.schema, + database: args.database, + createdAt: now, + updatedAt: now + }; + + this.queriesByConnection[args.connectionUid].queries.push(newQuery); + this._persist(); + return newQuery; + }, + updateQuery (args: { connectionUid: string; queryUid: string; name?: string; sql?: string; folderId?: string; schema?: string; database?: string }): void { + const connectionData = this.queriesByConnection[args.connectionUid]; + if (!connectionData) return; + + const queryIndex = connectionData.queries.findIndex((q: SavedQuery) => q.uid === args.queryUid); + if (queryIndex === -1) return; + + const existingQuery = connectionData.queries[queryIndex]; + + const updatedQuery: SavedQuery = { + ...existingQuery, + name: args.name !== undefined ? args.name : existingQuery.name, + sql: args.sql !== undefined ? args.sql : existingQuery.sql, + folderId: args.folderId !== undefined ? args.folderId : existingQuery.folderId, + schema: args.schema !== undefined ? args.schema : existingQuery.schema, + database: args.database !== undefined ? args.database : existingQuery.database, + updatedAt: new Date().toISOString() + }; + + connectionData.queries[queryIndex] = updatedQuery; + + this._persist(); + }, + renameQuery (args: { connectionUid: string; queryUid: string; name: string }): void { + this.updateQuery({ connectionUid: args.connectionUid, queryUid: args.queryUid, name: args.name }); + }, + deleteQuery (args: { connectionUid: string; queryUid: string }): void { + const connectionData = this.queriesByConnection[args.connectionUid]; + if (!connectionData) return; + + connectionData.queries = connectionData.queries.filter((q: SavedQuery) => q.uid !== args.queryUid); + this._persist(); + }, + duplicateQuery (args: { connectionUid: string; queryUid: string }): SavedQuery | undefined { + const query = this.getQueryById(args.connectionUid, args.queryUid); + if (!query) return undefined; + + return this.addQuery({ + connectionUid: args.connectionUid, + name: `${query.name} (copy)`, + sql: query.sql, + folderId: query.folderId, + schema: query.schema, + database: query.database + }); + }, + moveQueryToFolder (args: { connectionUid: string; queryUid: string; folderId: string | null }): void { + this.updateQuery({ connectionUid: args.connectionUid, queryUid: args.queryUid, folderId: args.folderId }); + }, + addFolder (args: { connectionUid: string; name: string; parentId?: string }): QueryFolder { + this._ensureConnectionData(args.connectionUid); + + const newFolder: QueryFolder = { + uid: uidGen('QF'), + name: args.name, + connectionUid: args.connectionUid, + parentId: args.parentId ?? null, + isExpanded: false, + createdAt: new Date().toISOString() + }; + + this.queriesByConnection[args.connectionUid].folders.push(newFolder); + this._persist(); + return newFolder; + }, + renameFolder (args: { connectionUid: string; folderUid: string; name: string }): void { + const connectionData = this.queriesByConnection[args.connectionUid]; + if (!connectionData) return; + + const folder = connectionData.folders.find((f: QueryFolder) => f.uid === args.folderUid); + if (folder) { + folder.name = args.name; + this._persist(); + } + }, + toggleFolderExpanded (args: { connectionUid: string; folderUid: string }): void { + const connectionData = this.queriesByConnection[args.connectionUid]; + if (!connectionData) return; + + const folder = connectionData.folders.find((f: QueryFolder) => f.uid === args.folderUid); + if (folder) { + folder.isExpanded = !folder.isExpanded; + this._persist(); + } + }, + deleteFolder (args: { connectionUid: string; folderUid: string; deleteContents?: boolean }): void { + const connectionData = this.queriesByConnection[args.connectionUid]; + if (!connectionData) return; + + if (args.deleteContents) { + connectionData.queries = connectionData.queries.filter((q: SavedQuery) => q.folderId !== args.folderUid); + + const deleteSubfolders = (parentId: string) => { + const subfolders = connectionData.folders.filter((f: QueryFolder) => f.parentId === parentId); + for (const subfolder of subfolders) { + connectionData.queries = connectionData.queries.filter((q: SavedQuery) => q.folderId !== subfolder.uid); + deleteSubfolders(subfolder.uid); + } + connectionData.folders = connectionData.folders.filter((f: QueryFolder) => f.parentId !== parentId); + }; + deleteSubfolders(args.folderUid); + } + else { + const folder = connectionData.folders.find((f: QueryFolder) => f.uid === args.folderUid); + const parentId = folder?.parentId ?? null; + connectionData.queries = connectionData.queries.map((q: SavedQuery) => { + if (q.folderId === args.folderUid) return { ...q, folderId: parentId }; + return q; + }); + + connectionData.folders = connectionData.folders.map((f: QueryFolder) => { + if (f.parentId === args.folderUid) return { ...f, parentId }; + return f; + }); + } + + connectionData.folders = connectionData.folders.filter((f: QueryFolder) => f.uid !== args.folderUid); + this._persist(); + }, + getFolderDepth (connectionUid: string, folderId: string): number { + let depth = 0; + let currentId: string | null = folderId; + + while (currentId) { + const folder = this.getFolderById(connectionUid, currentId); + if (!folder) break; + currentId = folder.parentId; + depth++; + } + + return depth; + } + } +}); From 5f078851ec973f677b9ab61fc2d30ba3f9901cd1 Mon Sep 17 00:00:00 2001 From: rique223 Date: Sat, 29 Nov 2025 17:08:59 -0300 Subject: [PATCH 2/8] feat(i18n): :speech_balloon: add saved queries translations Add translation strings for saved queries UI --- src/renderer/i18n/en-US.ts | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/renderer/i18n/en-US.ts b/src/renderer/i18n/en-US.ts index c6ec0374..f01a1646 100644 --- a/src/renderer/i18n/en-US.ts +++ b/src/renderer/i18n/en-US.ts @@ -80,7 +80,9 @@ export const enUS = { title: 'Title', archive: 'Archive', // verb undo: 'Undo', - moveTo: 'Move to' + moveTo: 'Move to', + rename: 'Rename', + root: 'Root' }, connection: { // Database connection connection: 'Connection', @@ -118,7 +120,8 @@ export const enUS = { allConnections: 'All connections', searchForConnections: 'Search for connections', keepAliveInterval: 'Keep alive interval', - singleConnection: 'Single connection' + singleConnection: 'Single connection', + databases: 'Databses' }, database: { // Database related terms schema: 'Schema', @@ -291,7 +294,18 @@ export const enUS = { switchDatabase: 'Switch the database', searchForElements: 'Search for elements', searchForSchemas: 'Search for schemas', - savedQueries: 'Saved queries' + savedQueries: 'Saved queries', + newQuery: 'New query', + newFolder: 'New folder', + newSubfolder: 'New subfolder', + createNewQuery: 'Create new query', + noSavedQueries: 'No saved queries', + openInNewTab: 'Open in new tab', + deleteFolderContents: 'Delete folder contents', + emptyQuery: 'Empty query', + rename: 'Rename', + autoSaving: 'Saving...', + autoSaved: 'Saved' }, application: { // Application related terms settings: 'Settings', From 97530c51e7713256b856edadbde664d165862cfd Mon Sep 17 00:00:00 2001 From: rique223 Date: Sat, 29 Nov 2025 17:09:57 -0300 Subject: [PATCH 3/8] feat(store): :sparkles: support elementType in tab content updates Extend updateTabContent to persist elementType for linking tabs to saved queries --- src/renderer/stores/workspaces.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/stores/workspaces.ts b/src/renderer/stores/workspaces.ts index 8fe61967..f510021f 100644 --- a/src/renderer/stores/workspaces.ts +++ b/src/renderer/stores/workspaces.ts @@ -761,8 +761,8 @@ export const useWorkspacesStore = defineStore('workspaces', { this.selectTab({ uid, tab: workspace.tabs[workspace.tabs.length - 1].uid }); } }, - updateTabContent ({ uid, tab, type, schema, content, elementName, filePath }: WorkspaceTab) { - this._replaceTab({ uid, tab, type, schema, content, elementName, filePath }); + updateTabContent ({ uid, tab, type, schema, content, elementName, elementType, filePath }: WorkspaceTab) { + this._replaceTab({ uid, tab, type, schema, content, elementName, elementType, filePath }); }, renameTabs ({ uid, schema, elementName, elementNewName }: WorkspaceTab) { this.workspaces = (this.workspaces as Workspace[]).map(workspace => { From c4722fcf7c7dca2ce4ffe93185328cafe3f93632 Mon Sep 17 00:00:00 2001 From: rique223 Date: Sat, 29 Nov 2025 17:10:41 -0300 Subject: [PATCH 4/8] feat(composables): :sparkles: add query-tab sync utilities Add composable for syncing saved query renames with open tabs --- src/renderer/composables/useSavedQuerySync.ts | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/renderer/composables/useSavedQuerySync.ts diff --git a/src/renderer/composables/useSavedQuerySync.ts b/src/renderer/composables/useSavedQuerySync.ts new file mode 100644 index 00000000..bcc88081 --- /dev/null +++ b/src/renderer/composables/useSavedQuerySync.ts @@ -0,0 +1,52 @@ +import { + getSavedQueryMarker, + useSavedQueriesStore +} from '@/stores/savedQueries'; +import { useWorkspacesStore } from '@/stores/workspaces'; + +export function useSavedQuerySync () { + const savedQueriesStore = useSavedQueriesStore(); + const workspacesStore = useWorkspacesStore(); + + const renameQueryAndSyncTab = (connectionUid: string, queryUid: string, newName: string): void => { + savedQueriesStore.renameQuery({ connectionUid, queryUid, name: newName }); + + const workspace = workspacesStore.getWorkspace(connectionUid); + if (!workspace) return; + + const savedQueryMarker = getSavedQueryMarker(queryUid); + const openTab = workspace.tabs.find( + tab => tab.type === 'query' && tab.elementType === savedQueryMarker + ); + + if (openTab) { + workspacesStore.updateTabContent({ + uid: connectionUid, + tab: openTab.uid, + type: openTab.type, + schema: openTab.schema, + content: openTab.content, + elementName: newName, + elementType: openTab.elementType, + filePath: openTab.filePath + }); + } + }; + + const closeTabForQuery = (connectionUid: string, queryUid: string): void => { + const workspace = workspacesStore.getWorkspace(connectionUid); + if (!workspace) return; + + const savedQueryMarker = getSavedQueryMarker(queryUid); + const openTab = workspace.tabs.find( + tab => tab.type === 'query' && tab.elementType === savedQueryMarker + ); + + if (openTab) workspacesStore.removeTab({ uid: connectionUid, tab: openTab.uid }); + }; + + return { + renameQueryAndSyncTab, + closeTabForQuery + }; +} From 8576aba5103100ea3b9845c8fe3e7ce4d1056eb5 Mon Sep 17 00:00:00 2001 From: rique223 Date: Sat, 29 Nov 2025 17:11:34 -0300 Subject: [PATCH 5/8] feat(components): :sparkles: add saved queries explorer components Add sidebar components for browsing and managing saved queries --- .../WorkspaceExploreSavedQueries.vue | 710 ++++++++++++++++++ .../WorkspaceExploreSavedQueriesFolder.vue | 214 ++++++ .../WorkspaceExploreSavedQueriesItem.vue | 195 +++++ 3 files changed, 1119 insertions(+) create mode 100644 src/renderer/components/WorkspaceExploreSavedQueries.vue create mode 100644 src/renderer/components/WorkspaceExploreSavedQueriesFolder.vue create mode 100644 src/renderer/components/WorkspaceExploreSavedQueriesItem.vue diff --git a/src/renderer/components/WorkspaceExploreSavedQueries.vue b/src/renderer/components/WorkspaceExploreSavedQueries.vue new file mode 100644 index 00000000..5b061320 --- /dev/null +++ b/src/renderer/components/WorkspaceExploreSavedQueries.vue @@ -0,0 +1,710 @@ + + + + + diff --git a/src/renderer/components/WorkspaceExploreSavedQueriesFolder.vue b/src/renderer/components/WorkspaceExploreSavedQueriesFolder.vue new file mode 100644 index 00000000..21f2f85b --- /dev/null +++ b/src/renderer/components/WorkspaceExploreSavedQueriesFolder.vue @@ -0,0 +1,214 @@ + + + + + diff --git a/src/renderer/components/WorkspaceExploreSavedQueriesItem.vue b/src/renderer/components/WorkspaceExploreSavedQueriesItem.vue new file mode 100644 index 00000000..ea04fd67 --- /dev/null +++ b/src/renderer/components/WorkspaceExploreSavedQueriesItem.vue @@ -0,0 +1,195 @@ + + + + + From 48ed1d864097e5b870e697266f5b579e541fb5ff Mon Sep 17 00:00:00 2001 From: rique223 Date: Sat, 29 Nov 2025 17:12:20 -0300 Subject: [PATCH 6/8] feat(UI): :sparkles: add saved queries tab to sidebar Add database/queries tab switcher to explore bar --- .../components/WorkspaceExploreBar.vue | 78 ++++++++++++++++++- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/src/renderer/components/WorkspaceExploreBar.vue b/src/renderer/components/WorkspaceExploreBar.vue index 30f17a18..0ffd0ffa 100644 --- a/src/renderer/components/WorkspaceExploreBar.vue +++ b/src/renderer/components/WorkspaceExploreBar.vue @@ -53,7 +53,25 @@ -
+
+ + {{ t('database.autoSaving') }} +
+
+ + {{ t('database.autoSaved') }} +
('idle'); const workspace = computed(() => getWorkspace(props.connection.uid)); const breadcrumbsSchema = computed(() => workspace.value.breadcrumbs.schema || null); @@ -373,45 +388,113 @@ const isChanged = computed(() => { }); watch(query, (val) => { - clearTimeout(debounceTimeout.value); + clearTimeout(queryDebounceTimeout.value); + + const elementType = props.tab.elementType; + const connectionUid = props.connection.uid; + const tabUid = props.tab.uid; + const currentSchema = selectedSchema.value; + const currentElementName = queryName.value; + const currentFilePath = filePath.value; + const isTabSavedQuery = isSavedQueryMarker(elementType); + const queryUid = extractQueryUidFromMarker(elementType); + + if (isTabSavedQuery) { + saveStatus.value = 'saving'; + isSaving.value = true; + } - debounceTimeout.value = setTimeout(() => { + queryDebounceTimeout.value = setTimeout(() => { updateTabContent({ - elementName: queryName.value, - filePath: filePath.value, - uid: props.connection.uid, - tab: props.tab.uid, + elementName: currentElementName, + filePath: currentFilePath, + uid: connectionUid, + tab: tabUid, type: 'query', - schema: selectedSchema.value, - content: val - + schema: currentSchema, + content: val, + elementType }); - isQuerySaved.value = false; - }, 200); + if (isTabSavedQuery && queryUid) { + updateQuery({ + connectionUid, + queryUid, + sql: val, + schema: currentSchema + }); + isQuerySaved.value = true; + saveStatus.value = 'saved'; + isSaving.value = false; + + setTimeout(() => { + if (saveStatus.value === 'saved') + saveStatus.value = 'idle'; + }, 2000); + } + else { + isQuerySaved.value = false; + saveStatus.value = 'idle'; + isSaving.value = false; + } + }, 500); }); watch(queryName, (val) => { - clearTimeout(debounceTimeout.value); + clearTimeout(nameDebounceTimeout.value); + + const elementType = props.tab.elementType; + const connectionUid = props.connection.uid; + const tabUid = props.tab.uid; + const currentSchema = selectedSchema.value; + const currentFilePath = filePath.value; + const currentQuery = query.value; + const isTabSavedQuery = isSavedQueryMarker(elementType); + const queryUid = extractQueryUidFromMarker(elementType); + + if (isTabSavedQuery) { + saveStatus.value = 'saving'; + isSaving.value = true; + } - debounceTimeout.value = setTimeout(() => { + nameDebounceTimeout.value = setTimeout(() => { updateTabContent({ elementName: val, - filePath: filePath.value, - uid: props.connection.uid, - tab: props.tab.uid, + filePath: currentFilePath, + uid: connectionUid, + tab: tabUid, type: 'query', - schema: selectedSchema.value, - content: query.value + schema: currentSchema, + content: currentQuery, + elementType }); - isQuerySaved.value = false; - }, 200); + if (isTabSavedQuery && queryUid) { + updateQuery({ + connectionUid, + queryUid, + name: val + }); + isQuerySaved.value = true; + saveStatus.value = 'saved'; + isSaving.value = false; + + setTimeout(() => { + if (saveStatus.value === 'saved') + saveStatus.value = 'idle'; + }, 2000); + } + else { + isQuerySaved.value = false; + saveStatus.value = 'idle'; + isSaving.value = false; + } + }, 500); }); watch(() => props.isSelected, (val) => { if (val) { - changeBreadcrumbs({ schema: selectedSchema.value, query: `Query #${props.tab.index}` }); + changeBreadcrumbs({ schema: selectedSchema.value, query: 'New Query' }); setTimeout(() => { if (queryEditor.value) queryEditor.value.editor.focus(); @@ -420,7 +503,7 @@ watch(() => props.isSelected, (val) => { }); watch(selectedSchema, () => { - changeBreadcrumbs({ schema: selectedSchema.value, query: `Query #${props.tab.index}` }); + changeBreadcrumbs({ schema: selectedSchema.value, query: 'New Query' }); }); watch(databaseSchemas, () => { @@ -436,6 +519,11 @@ watch(() => props.tab.content, () => { queryEditor.value.editor.session.setValue(query.value); }); +watch(() => props.tab.elementName, (newName) => { + if (newName !== queryName.value) + queryName.value = newName as string; +}); + watch(isChanged, (val) => { setUnsavedChanges({ uid: props.connection.uid, tUid: props.tabUid, isChanged: val }); }); @@ -588,20 +676,15 @@ const openHistoryModal = () => { }; const saveQuery = () => { - addNote({ - uid: uidGen('N'), - cUid: workspace.value.uid, - type: 'query', - date: new Date(), - note: query.value, - isArchived: false, - title: queryName.value + addQuery({ + connectionUid: workspace.value.uid, + name: queryName.value || t('database.newQuery'), + sql: query.value, + schema: breadcrumbsSchema.value, + database: workspace.value.database }); isQuerySaved.value = true; -}; - -const openSavedModal = () => { - showScratchpad('query'); + addNotification({ status: 'success', message: t('general.actionSuccessful', { action: t('general.save') }) }); }; const selectQuery = (sql: string) => { @@ -662,7 +745,30 @@ const rollbackTab = async () => { defineExpose({ resizeResults }); query.value = props.tab.content as string; -queryName.value = props.tab.elementName as string; +if (isSavedQueryMarker(props.tab.elementType)) { + const queryUid = extractQueryUidFromMarker(props.tab.elementType); + + const savedQuery = queryUid ? savedQueriesStore.getQueryById(props.connection.uid, queryUid) : null; + if (savedQuery) { + query.value = savedQuery.sql; + queryName.value = savedQuery.name; + updateTabContent({ + elementName: savedQuery.name, + filePath: filePath.value, + uid: props.connection.uid, + tab: props.tab.uid, + type: 'query', + schema: selectedSchema.value, + content: query.value, + elementType: props.tab.elementType + }); + } + else + queryName.value = props.tab.elementName as string; +} +else + queryName.value = props.tab.elementName as string; + filePath.value = props.tab.filePath as string; selectedSchema.value = props.tab.schema || breadcrumbsSchema.value; @@ -926,6 +1032,23 @@ onBeforeUnmount(() => { > div + div { padding-left: 0.6rem; } + + .save-status { + font-size: 0.75rem; + align-items: center; + + &.saving { + color: var(--primary-color); + } + + &.saved { + color: var(--success-color, #28a745); + } + + .rotating { + animation: rotate 1s linear infinite; + } + } } } } @@ -934,4 +1057,13 @@ onBeforeUnmount(() => { min-height: 200px; } } -filePathsfilePathsfilePaths + +@keyframes rotate { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + From 6426987ae096e6326f99f6068e9722b03b70f28f Mon Sep 17 00:00:00 2001 From: rique223 Date: Sat, 29 Nov 2025 17:13:50 -0300 Subject: [PATCH 8/8] refactor(UI): :recycle: exclude query type from notes Filter out query notes since they're now in saved queries panel --- src/renderer/components/TheScratchpad.vue | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/renderer/components/TheScratchpad.vue b/src/renderer/components/TheScratchpad.vue index dc8e46f9..7f8caff6 100644 --- a/src/renderer/components/TheScratchpad.vue +++ b/src/renderer/components/TheScratchpad.vue @@ -209,10 +209,10 @@ const selectedNote = ref(null); const noteTags: ComputedRef<{code: TagCode; name: string}[]> = computed(() => [ { code: 'note', name: t('application.note') }, - { code: 'todo', name: 'TODO' }, - { code: 'query', name: 'Query' } + { code: 'todo', name: 'TODO' } ]); const filteredNotes = computed(() => connectionNotes.value.filter(n => ( + n.type !== 'query' && (n.type === selectedTag.value || selectedTag.value === 'all') && (n.cUid === localConnection.value || localConnection.value === null) && (!n.isArchived || showArchived.value) && @@ -291,7 +291,8 @@ const selectQuery = (query: string) => { uid: selectedWorkspace.value, type: 'query', content: query, - schema: workspace.breadcrumbs.schema + schema: workspace.breadcrumbs.schema, + elementType: selectedTab.elementType }); } else {