mirror of
				https://github.com/Fabio286/antares.git
				synced 2025-06-05 21:59:22 +02:00 
			
		
		
		
	feat(UI): new context menu and some minor improvements to query tabs, closes #867
This commit is contained in:
		| @@ -141,8 +141,11 @@ onMounted(() => { | ||||
|  | ||||
|       while (node) { | ||||
|          if (node.nodeName.match(/^(input|textarea)$/i) || node.isContentEditable) { | ||||
|             InputMenu.popup({ window: getCurrentWindow() }); | ||||
|             break; | ||||
|             if (!node.parentNode.className.split(' ').includes('editor-query')) { | ||||
|                InputMenu.popup({ window: getCurrentWindow() }); | ||||
|                console.log(node.parentNode.className); | ||||
|                break; | ||||
|             } | ||||
|          } | ||||
|          node = node.parentNode; | ||||
|       } | ||||
|   | ||||
| @@ -612,7 +612,7 @@ const otherContributors = computed(() => { | ||||
|    return contributors | ||||
|       .split(',') | ||||
|       .filter(c => !c.includes(appAuthor)) | ||||
|       .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())); | ||||
|       .sort((a, b) => a.toLowerCase().trim().localeCompare(b.toLowerCase())); | ||||
| }); | ||||
|  | ||||
| const selectTab = (tab: string) => { | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
|       <div | ||||
|          :id="`editor-${id}`" | ||||
|          class="editor" | ||||
|          :class="editorClasses" | ||||
|          :style="{height: `${height}px`}" | ||||
|       /> | ||||
|    </div> | ||||
| @@ -54,7 +55,8 @@ const props = defineProps({ | ||||
|    schema: { type: String, default: '' }, | ||||
|    autoFocus: { type: Boolean, default: false }, | ||||
|    readOnly: { type: Boolean, default: false }, | ||||
|    height: { type: Number, default: 200 } | ||||
|    height: { type: Number, default: 200 }, | ||||
|    editorClasses: { type: String, default: '' } | ||||
| }); | ||||
|  | ||||
| const emit = defineEmits(['update:modelValue']); | ||||
| @@ -405,18 +407,17 @@ defineExpose({ editor }); | ||||
|  | ||||
| .ace_gutter-cell.ace_breakpoint { | ||||
|   &::before { | ||||
|     content: '\F0403'; | ||||
|     content: ''; | ||||
|     position: absolute; | ||||
|     left: 3px; | ||||
|     top: 2px; | ||||
|     color: var(--primary-color); | ||||
|     left: 0px; | ||||
|     top: 8px; | ||||
|     display: inline-block; | ||||
|     font: normal normal normal 24px/1 "Material Design Icons", sans-serif; | ||||
|     font-size: inherit; | ||||
|     text-rendering: auto; | ||||
|     line-height: inherit; | ||||
|     -webkit-font-smoothing: antialiased; | ||||
|     -moz-osx-font-smoothing: grayscale; | ||||
|     width: 0; | ||||
|     height: 0; | ||||
|     border-left: 8px solid transparent; | ||||
|     border-top: 8px solid transparent; | ||||
|     border-right: 8px solid var(--primary-color); | ||||
|     transform: rotate(-45deg); | ||||
|   } | ||||
| } | ||||
| </style> | ||||
|   | ||||
| @@ -15,6 +15,7 @@ | ||||
|             :schema="breadcrumbsSchema" | ||||
|             :is-selected="isSelected" | ||||
|             :height="editorHeight" | ||||
|             editor-classes="editor-query" | ||||
|          /> | ||||
|          <div ref="resizer" class="query-area-resizer" /> | ||||
|          <div ref="queryAreaFooter" class="workspace-query-runner-footer"> | ||||
| @@ -273,6 +274,7 @@ | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { getCurrentWindow, Menu } from '@electron/remote'; | ||||
| import { Ace } from 'ace-builds'; | ||||
| import { ConnectionParams } from 'common/interfaces/antares'; | ||||
| import { uidGen } from 'common/libs/uidGen'; | ||||
| @@ -475,6 +477,8 @@ const runQuery = async (query: string) => { | ||||
|          saveHistory(params); | ||||
|          if (!autocommit.value) | ||||
|             setUnsavedChanges({ uid: props.connection.uid, tUid: props.tabUid, isChanged: true }); | ||||
|  | ||||
|          queryEditor.value.editor.focus(); | ||||
|       } | ||||
|       else | ||||
|          addNotification({ status: 'error', message: response }); | ||||
| @@ -739,7 +743,11 @@ const openFile = async () => { | ||||
|  | ||||
| const saveFileAs = async () => { | ||||
|    // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||||
|    const result: any = await Application.showSaveDialog({ filters: [{ name: 'SQL', extensions: ['sql'] }], defaultPath: `${queryName.value || 'query'}.sql` }); | ||||
|    const result: any = await Application.showSaveDialog({ | ||||
|       filters: [{ name: 'SQL', extensions: ['sql'] }], | ||||
|       defaultPath: (!queryName.value.includes('.sql') ? `${queryName.value}.sql` :queryName.value) || 'query.sql' | ||||
|    }); | ||||
|  | ||||
|    if (result && !result.canceled) { | ||||
|       await Application.writeFile(result.filePath, query.value); | ||||
|       addNotification({ status: 'success', message: t('general.actionSuccessful', { action: t('application.saveFile') }) }); | ||||
| @@ -750,9 +758,13 @@ const saveFileAs = async () => { | ||||
| }; | ||||
|  | ||||
| const saveFile = async () => { | ||||
|    await Application.writeFile(filePath.value, query.value); | ||||
|    addNotification({ status: 'success', message: t('general.actionSuccessful', { action: t('application.saveFile') }) }); | ||||
|    lastSavedQuery.value = toRaw(query.value); | ||||
|    if (filePath.value) { | ||||
|       await Application.writeFile(filePath.value, query.value); | ||||
|       addNotification({ status: 'success', message: t('general.actionSuccessful', { action: t('application.saveFile') }) }); | ||||
|       lastSavedQuery.value = toRaw(query.value); | ||||
|    } | ||||
|    else | ||||
|       saveFileAs(); | ||||
| }; | ||||
|  | ||||
| const loadFileContent = async (file: string) => { | ||||
| @@ -785,6 +797,67 @@ onMounted(() => { | ||||
|  | ||||
|    if (props.tab.filePath) | ||||
|       loadFileContent(props.tab.filePath); | ||||
|  | ||||
|    queryEditor.value.editor.container.addEventListener('contextmenu', (e) => { | ||||
|       const InputMenu = Menu.buildFromTemplate([ | ||||
|          { | ||||
|             label: t('general.run'), | ||||
|             click: () => runQuery(query.value) | ||||
|          }, | ||||
|          { | ||||
|             label: t('general.clear'), | ||||
|             click: () => clear() | ||||
|          }, | ||||
|          { | ||||
|             type: 'separator' | ||||
|          }, | ||||
|          { | ||||
|             label: t('application.saveFile'), | ||||
|             click: () => saveFile() | ||||
|          }, | ||||
|          { | ||||
|             label: t('application.saveFileAs'), | ||||
|             click: () => saveFileAs() | ||||
|          }, | ||||
|          { | ||||
|             label: t('application.openFile'), | ||||
|             click: () => openFile() | ||||
|          }, | ||||
|          { | ||||
|             type: 'separator' | ||||
|          }, | ||||
|          { | ||||
|             label: t('general.cut'), | ||||
|             role: 'cut' | ||||
|          }, | ||||
|          { | ||||
|             label: t('general.copy'), | ||||
|             role: 'copy' | ||||
|          }, | ||||
|          { | ||||
|             label: t('general.paste'), | ||||
|             role: 'paste' | ||||
|          }, | ||||
|          { | ||||
|             type: 'separator' | ||||
|          }, | ||||
|          { | ||||
|             label: t('general.selectAll'), | ||||
|             role: 'selectAll' | ||||
|          } | ||||
|       ]); | ||||
|       e.preventDefault(); | ||||
|  | ||||
|       // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||||
|       let node: any = e.target; | ||||
|       while (node) { | ||||
|          if (node.nodeName.match(/^(input|textarea)$/i) || node.isContentEditable) { | ||||
|             InputMenu.popup({ window: getCurrentWindow() }); | ||||
|             break; | ||||
|          } | ||||
|          node = node.parentNode; | ||||
|       } | ||||
|    }); | ||||
| }); | ||||
|  | ||||
| onBeforeUnmount(() => { | ||||
|   | ||||
| @@ -9,7 +9,7 @@ export const localesNames: Record<string, string> = { | ||||
|    'vi-VN': 'Tiếng Việt', | ||||
|    'ja-JP': '日本語', | ||||
|    'zh-CN': '简体中文', | ||||
|    'zh-TW': '繁體中文', | ||||
|    'zh-TW': '正體中文', | ||||
|    'ru-RU': 'Русский', | ||||
|    'id-ID': 'Bahasa Indonesia', | ||||
|    'ko-KR': '한국어', | ||||
|   | ||||
| @@ -256,6 +256,10 @@ option:checked { | ||||
|     } | ||||
|  | ||||
|     &.active { | ||||
|       a { | ||||
|         border-bottom-color: transparent; | ||||
|       } | ||||
|  | ||||
|       .tab-link { | ||||
|         border-color: transparent; | ||||
|       } | ||||
|   | ||||
| @@ -255,6 +255,11 @@ | ||||
|           } | ||||
|         } | ||||
|  | ||||
|          | ||||
|         &.result-tabs .tab-item { | ||||
|           background: transparent; | ||||
|         } | ||||
|  | ||||
|         .workspace-query-runner .workspace-query-runner-footer .workspace-query-buttons .btn { | ||||
|           color: $body-font-color-dark; | ||||
|         } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user