feat: copy element names on sidebar from context menu, closes #718

This commit is contained in:
Fabio Di Stasio 2023-11-29 18:15:22 +01:00
parent 879de91516
commit f13d4e6dce
10 changed files with 73 additions and 19 deletions

View File

@ -133,6 +133,7 @@ import BaseIcon from '@/components/BaseIcon.vue';
import BaseVirtualScroll from '@/components/BaseVirtualScroll.vue';
import { useFilters } from '@/composables/useFilters';
import { useFocusTrap } from '@/composables/useFocusTrap';
import { copyText } from '@/libs/copyText';
import { useConnectionsStore } from '@/stores/connections';
import { HistoryRecord, useHistoryStore } from '@/stores/history';
@ -173,7 +174,7 @@ watch(searchTerm, () => {
});
const copyQuery = (sql: string) => {
navigator.clipboard.writeText(sql);
copyText(sql);
};
const deleteQuery = (query: HistoryRecord[]) => {

View File

@ -161,6 +161,7 @@ import ModalProcessesListContext from '@/components/ModalProcessesListContext.vu
import ModalProcessesListRow from '@/components/ModalProcessesListRow.vue';
import { useFocusTrap } from '@/composables/useFocusTrap';
import Schema from '@/ipc-api/Schema';
import { copyText } from '@/libs/copyText';
import { useConnectionsStore } from '@/stores/connections';
import { useNotificationsStore } from '@/stores/notifications';
@ -322,13 +323,13 @@ const closeContext = () => {
const copyCell = () => {
const row = results.value.find(row => Number(row.id) === selectedRow.value);
const valueToCopy = row[selectedCell.value.field];
navigator.clipboard.writeText(valueToCopy);
copyText(valueToCopy);
};
const copyRow = () => {
const row = results.value.find(row => Number(row.id) === selectedRow.value);
const rowToCopy = JSON.parse(JSON.stringify(row));
navigator.clipboard.writeText(JSON.stringify(rowToCopy));
copyText(JSON.stringify(rowToCopy));
};
const closeModal = () => emit('close');

View File

@ -15,6 +15,14 @@
:size="18"
/> {{ t('connection.disconnect') }}</span>
</div>
<div class="context-element" @click.stop="showAppearanceModal">
<span class="d-flex">
<BaseIcon
class="text-light mt-1 mr-1"
icon-name="mdiBrushVariant"
:size="18"
/> {{ t('application.appearance') }}</span>
</div>
<div
v-if="!contextConnection.isFolder"
class="context-element"
@ -27,14 +35,6 @@
:size="18"
/> {{ t('general.duplicate') }}</span>
</div>
<div class="context-element" @click.stop="showAppearanceModal">
<span class="d-flex">
<BaseIcon
class="text-light mt-1 mr-1"
icon-name="mdiBrushVariant"
:size="18"
/> {{ t('application.appearance') }}</span>
</div>
<div class="context-element" @click="showConfirmModal">
<span class="d-flex">
<BaseIcon

View File

@ -55,6 +55,14 @@
/> {{ t('general.disable') }}
</span>
</div>
<div class="context-element" @click="copyName(selectedMisc.name)">
<span class="d-flex">
<BaseIcon
class="text-light mt-1 mr-1"
icon-name="mdiContentCopy"
:size="18"
/> {{ t('general.copyName') }}</span>
</div>
<div class="context-element" @click="showDeleteModal">
<span class="d-flex">
<BaseIcon
@ -108,6 +116,7 @@ import Functions from '@/ipc-api/Functions';
import Routines from '@/ipc-api/Routines';
import Schedulers from '@/ipc-api/Schedulers';
import Triggers from '@/ipc-api/Triggers';
import { copyText } from '@/libs/copyText';
import { useNotificationsStore } from '@/stores/notifications';
import { useWorkspacesStore } from '@/stores/workspaces';
@ -163,6 +172,11 @@ const deleteMessage = computed(() => {
}
});
const copyName = (name: string) => {
copyText(name);
closeContext();
};
const showDeleteModal = () => {
isDeleteModal.value = true;
};

View File

@ -102,6 +102,14 @@
</div>
</div>
</div>
<div class="context-element" @click="copyName(selectedSchema)">
<span class="d-flex">
<BaseIcon
class="text-light mt-1 mr-1"
icon-name="mdiContentCopy"
:size="18"
/> {{ t('general.copyName') }}</span>
</div>
<div
v-if="workspace.customizations.schemaExport"
class="context-element"
@ -198,6 +206,7 @@ import ModalEditSchema from '@/components/ModalEditSchema.vue';
import ModalImportSchema from '@/components/ModalImportSchema.vue';
import Application from '@/ipc-api/Application';
import Schema from '@/ipc-api/Schema';
import { copyText } from '@/libs/copyText';
import { useNotificationsStore } from '@/stores/notifications';
import { useSchemaExportStore } from '@/stores/schemaExport';
import { useWorkspacesStore } from '@/stores/workspaces';
@ -268,6 +277,11 @@ const openCreateSchedulerTab = () => {
emit('open-create-scheduler-tab');
};
const copyName = (name: string) => {
copyText(name);
closeContext();
};
const showDeleteModal = () => {
isDeleteModal.value = true;
};

View File

@ -15,6 +15,14 @@
:size="18"
/> {{ t('application.settings') }}</span>
</div>
<div class="context-element" @click="copyName(selectedTable.name)">
<span class="d-flex">
<BaseIcon
class="text-light mt-1 mr-1"
icon-name="mdiContentCopy"
:size="18"
/> {{ t('general.copyName') }}</span>
</div>
<div
v-if="selectedTable && selectedTable.type === 'table' && customizations.schemaExport"
class="context-element"
@ -130,6 +138,7 @@ import ConfirmModal from '@/components/BaseConfirmModal.vue';
import BaseContextMenu from '@/components/BaseContextMenu.vue';
import BaseIcon from '@/components/BaseIcon.vue';
import Tables from '@/ipc-api/Tables';
import { copyText } from '@/libs/copyText';
import { useNotificationsStore } from '@/stores/notifications';
import { useSchemaExportStore } from '@/stores/schemaExport';
import { useWorkspacesStore } from '@/stores/workspaces';
@ -170,6 +179,11 @@ const showTableExportModal = () => {
closeContext();
};
const copyName = (name: string) => {
copyText(name);
closeContext();
};
const showDeleteModal = () => {
isDeleteModal.value = true;
};

View File

@ -52,6 +52,7 @@ import { useI18n } from 'vue-i18n';
import BaseContextMenu from '@/components/BaseContextMenu.vue';
import BaseIcon from '@/components/BaseIcon.vue';
import { copyText } from '@/libs/copyText';
import { useConsoleStore } from '@/stores/console';
const { t } = useI18n();
@ -100,7 +101,7 @@ const contextMenu = (event: MouseEvent, wLog: {date: Date; sql: string}) => {
};
const copyQuery = () => {
navigator.clipboard.writeText(contextQuery.value);
copyText(contextQuery.value);
isContext.value = false;
};

View File

@ -270,6 +270,7 @@ import BaseSelect from '@/components/BaseSelect.vue';
import BaseVirtualScroll from '@/components/BaseVirtualScroll.vue';
import TableContext from '@/components/WorkspaceTabQueryTableContext.vue';
import WorkspaceTabQueryTableRow from '@/components/WorkspaceTabQueryTableRow.vue';
import { copyText } from '@/libs/copyText';
import { unproxify } from '@/libs/unproxify';
import { useConsoleStore } from '@/stores/console';
import { useSettingsStore } from '@/stores/settings';
@ -571,7 +572,7 @@ const copyCell = () => {
let valueToCopy = row[cellName];
if (typeof valueToCopy === 'object')
valueToCopy = JSON.stringify(valueToCopy);
navigator.clipboard.writeText(valueToCopy);
copyText(valueToCopy);
};
const copyRow = (format: string) => {
@ -593,7 +594,7 @@ const copyRow = (format: string) => {
}
if (format === 'json')
navigator.clipboard.writeText(JSON.stringify(contentToCopy));
copyText(JSON.stringify(contentToCopy));
else if (format === 'sql') {
if (!Array.isArray(contentToCopy)) contentToCopy = [contentToCopy];
@ -605,7 +606,7 @@ const copyRow = (format: string) => {
},
table: getTable(resultsetIndex.value)
});
navigator.clipboard.writeText(sqlInserts);
copyText(sqlInserts);
}
else if (format === 'csv') {
const csv = [];
@ -617,7 +618,7 @@ const copyRow = (format: string) => {
for (const row of contentToCopy)
csv.push(Object.values(row).map(col => typeof col === 'string' ? `"${col}"` : col).join(';'));
navigator.clipboard.writeText(csv.join('\n'));
copyText(csv.join('\n'));
}
else if (format === 'html') {
const arrayContent = new Array<string[]>();
@ -640,7 +641,7 @@ const copyRow = (format: string) => {
if (!Array.isArray(contentToCopy)) contentToCopy = [contentToCopy];
const printer = json2php.make({ linebreak: '\n', indent: '\t', shortArraySyntax: true });
const phpString = printer(contentToCopy);
navigator.clipboard.writeText(phpString);
copyText(phpString);
}
};
@ -878,7 +879,7 @@ const onKey = async (e: KeyboardEvent) => {
const copyType = defaultCopyType.value;
if (selectedRows.value.length >= 1) {
if (selectedRows.value.length === 1 && copyType === 'cell')
await navigator.clipboard.writeText(scrollElement.value.querySelector('.td.selected').innerText);
await copyText(scrollElement.value.querySelector('.td.selected').innerText);
else if (selectedRows.value.length > 1 && copyType === 'cell')
copyRow('html');
else

View File

@ -65,7 +65,8 @@ export const enUS = {
actionSuccessful: '{action} successful',
outputFormat: 'Output format',
singleFile: 'Single {ext} file',
zipCompressedFile: 'ZIP compressed {ext} file'
zipCompressedFile: 'ZIP compressed {ext} file',
copyName: 'Copy name'
},
connection: { // Database connection
connectionName: 'Connection name',

View File

@ -0,0 +1,7 @@
/**
* Copy a string on clipboard
* @param text
*/
export const copyText = (text: string) => {
navigator.clipboard.writeText(text);
};