1 parent
5c75c2391c
commit
cd18b7a3db
14 files changed
+313
-3
No files matched your search
@@ -182,7 +182,7 @@ import { temporalCellEditorConfig, type TemporalCellEditorConfig } from "@/lib/d
|
||||
import { BOOLEAN_CELL_EDITOR_VALUES, booleanCellEditorValue, isBooleanCellValue, isBooleanColumnType, isPointInBooleanCheckbox, nextBooleanCellValue, normalizeBooleanCellValue, parseBooleanCellEditorValue } from "@/lib/dataGrid/dataGridBooleanColumn";
|
||||
import { resolveDataGridColumnNullability, resolveDataGridColumnsByResultIndex } from "@/lib/dataGrid/dataGridColumnMetadata";
|
||||
import { resolveDataGridNewRowCellPlaceholder } from "@/lib/dataGrid/dataGridDefaultPlaceholder";
|
||||
import { isCancelSearchShortcut, isCopyCurrentRowShortcut, isDeleteCurrentRowShortcut, isFocusSearchShortcut, isModRShortcut, isSaveShortcut, isToggleTransposeShortcut } from "@/lib/editor/keyboardShortcuts";
|
||||
import { isCancelSearchShortcut, isCopyCurrentRowShortcut, isDeleteCurrentRowShortcut, isFocusSearchShortcut, isGoToColumnShortcut, isModRShortcut, isSaveShortcut, isToggleTransposeShortcut } from "@/lib/editor/keyboardShortcuts";
|
||||
import { dataGridHeaderContentWidth, scrollbarGutterWidth } from "@/lib/dataGrid/dataGridScrollGutter";
|
||||
import { canFetchNextDataGridSegment, canGoNextDataGridPage, dataGridTotalRowCountLabelKey, dataGridTruncationHintKey, hasCompleteLocalDataGridResult, resolveDataGridPaginationTotal, type DataGridInexactTotalRowCountMode } from "@/lib/dataGrid/dataGridPagination";
|
||||
import { dataGridCountQueryOptions } from "@/lib/dataGrid/dataGridQueryOptions";
|
||||
@@ -8980,6 +8980,13 @@ function openCellDetailSearch(): boolean {
|
||||
async function onGridKeydown(event: KeyboardEvent) {
|
||||
if (event.defaultPrevented) return;
|
||||
|
||||
const targetAllowsNativeClipboard = eventTargetAllowsNativeClipboard(event);
|
||||
if (!targetAllowsNativeClipboard && displayableColumnIndexes.value.length > 0 && isGoToColumnShortcut(event, settingsStore.editorSettings.shortcuts)) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
goToColumnOpen.value = true;
|
||||
return;
|
||||
}
|
||||
if (isFocusSearchShortcut(event)) {
|
||||
event.preventDefault();
|
||||
focusSearch();
|
||||
@@ -8991,7 +8998,7 @@ async function onGridKeydown(event: KeyboardEvent) {
|
||||
await onToolbarRefresh();
|
||||
return;
|
||||
}
|
||||
if (eventTargetAllowsNativeClipboard(event)) return;
|
||||
if (targetAllowsNativeClipboard) return;
|
||||
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "z") {
|
||||
const handled = event.shiftKey ? redoGridChange() : undoGridChange();
|
||||
if (handled) {
|
||||
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import { createApp, defineComponent, h, markRaw, nextTick, type App, type PropType } from "vue";
|
||||
import { createPinia, setActivePinia } from "pinia";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import i18n from "@/i18n";
|
||||
import type { QueryResult } from "@/types/database";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
|
||||
vi.mock("@/composables/useDataGridColumnResize", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("@/composables/useDataGridColumnResize")>();
|
||||
const { ref } = await import("vue");
|
||||
return {
|
||||
...actual,
|
||||
useDataGridColumnResize: () => ({
|
||||
initColumnWidths: vi.fn(),
|
||||
onResizeStart: vi.fn(),
|
||||
autoFitColumn: vi.fn(),
|
||||
renderedColumnWidths: ref([120]),
|
||||
totalWidth: ref(120),
|
||||
columnVars: ref({ "--total-w": "120px" }),
|
||||
getIsResizing: () => false,
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
import DataGrid from "../DataGrid.vue";
|
||||
import { useSettingsStore } from "@/stores/settingsStore";
|
||||
|
||||
const dataGridSource = readFileSync(resolve(process.cwd(), "apps/desktop/src/components/grid/DataGrid.vue"), "utf8");
|
||||
const mountedApps: Array<{ app: App; host: HTMLElement }> = [];
|
||||
|
||||
const RecycleScroller = defineComponent({
|
||||
props: {
|
||||
items: {
|
||||
type: Array as PropType<unknown[]>,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
setup(props, { attrs, slots }) {
|
||||
return () =>
|
||||
h(
|
||||
"div",
|
||||
attrs,
|
||||
props.items.map((item) => slots.default?.({ item })),
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
function mountGrid(options: { displayableColumns?: boolean } = {}) {
|
||||
const pinia = createPinia();
|
||||
setActivePinia(pinia);
|
||||
const settingsStore = useSettingsStore();
|
||||
settingsStore.updateEditorSettings({
|
||||
dataGridRenderMode: "canvas",
|
||||
shortcuts: {
|
||||
...settingsStore.editorSettings.shortcuts,
|
||||
goToColumn: "Mod+G",
|
||||
},
|
||||
});
|
||||
const result = markRaw<QueryResult>({
|
||||
columns: ["id"],
|
||||
rows: [[1]],
|
||||
affected_rows: 0,
|
||||
execution_time_ms: 0,
|
||||
hidden_column_indexes: options.displayableColumns === false ? [0] : undefined,
|
||||
});
|
||||
|
||||
const host = document.createElement("div");
|
||||
document.body.append(host);
|
||||
const Root = defineComponent({
|
||||
setup() {
|
||||
return () =>
|
||||
h(
|
||||
TooltipProvider,
|
||||
{ delayDuration: 0 },
|
||||
{
|
||||
default: () =>
|
||||
h(DataGrid, {
|
||||
result,
|
||||
databaseType: "mysql",
|
||||
context: "table-data",
|
||||
}),
|
||||
},
|
||||
);
|
||||
},
|
||||
});
|
||||
const app = createApp(Root);
|
||||
app.use(pinia);
|
||||
app.use(i18n);
|
||||
app.component("RecycleScroller", RecycleScroller);
|
||||
app.mount(host);
|
||||
const mounted = { app, host };
|
||||
mountedApps.push(mounted);
|
||||
return mounted;
|
||||
}
|
||||
|
||||
async function settle() {
|
||||
await nextTick();
|
||||
await Promise.resolve();
|
||||
await nextTick();
|
||||
}
|
||||
|
||||
function gridRoot(host: HTMLElement): HTMLElement {
|
||||
const root = host.querySelector<HTMLElement>("[data-grid-root]");
|
||||
if (!root) throw new Error("Data grid root not found");
|
||||
return root;
|
||||
}
|
||||
|
||||
function goToColumnButton(host: HTMLElement): HTMLButtonElement {
|
||||
const button = [...host.querySelectorAll<HTMLButtonElement>("button")].find((candidate) => candidate.textContent?.trim() === "Go to column");
|
||||
if (!button) throw new Error("Go-to-column button not found");
|
||||
return button;
|
||||
}
|
||||
|
||||
function goToColumnEvent(target: HTMLElement): KeyboardEvent {
|
||||
const event = new KeyboardEvent("keydown", { bubbles: true, cancelable: true, ctrlKey: true, key: "g" });
|
||||
target.dispatchEvent(event);
|
||||
return event;
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
for (const { app, host } of mountedApps.splice(0)) {
|
||||
app.unmount();
|
||||
host.remove();
|
||||
}
|
||||
});
|
||||
|
||||
function functionBody(name: string, nextName: string): string {
|
||||
const start = dataGridSource.indexOf(`function ${name}`);
|
||||
const end = dataGridSource.indexOf(`function ${nextName}`, start + 1);
|
||||
return start >= 0 && end > start ? dataGridSource.slice(start, end) : "";
|
||||
}
|
||||
|
||||
describe("DataGrid go-to-column shortcut", () => {
|
||||
it("opens and consumes the configured shortcut when a column is displayable", async () => {
|
||||
const { host } = mountGrid();
|
||||
await settle();
|
||||
const root = gridRoot(host);
|
||||
const bubbled = vi.fn();
|
||||
host.addEventListener("keydown", bubbled);
|
||||
root.focus();
|
||||
expect(document.activeElement).toBe(root);
|
||||
|
||||
const event = goToColumnEvent(root);
|
||||
await settle();
|
||||
|
||||
expect(event.defaultPrevented).toBe(true);
|
||||
expect(bubbled).not.toHaveBeenCalled();
|
||||
expect(goToColumnButton(host).getAttribute("aria-expanded")).toBe("true");
|
||||
expect(document.activeElement?.getAttribute("placeholder")).toBe("Search column/comment...");
|
||||
});
|
||||
|
||||
it("does not consume the configured shortcut without a displayable column", async () => {
|
||||
const { host } = mountGrid({ displayableColumns: false });
|
||||
await settle();
|
||||
const root = gridRoot(host);
|
||||
const bubbled = vi.fn();
|
||||
host.addEventListener("keydown", bubbled);
|
||||
|
||||
const event = goToColumnEvent(root);
|
||||
await settle();
|
||||
|
||||
expect(event.defaultPrevented).toBe(false);
|
||||
expect(bubbled).toHaveBeenCalledOnce();
|
||||
expect(goToColumnButton(host).getAttribute("aria-expanded")).toBe("false");
|
||||
});
|
||||
|
||||
it("does not trigger or consume shortcuts from editable targets", async () => {
|
||||
const { host } = mountGrid();
|
||||
await settle();
|
||||
const root = gridRoot(host);
|
||||
const bubbled = vi.fn();
|
||||
host.addEventListener("keydown", bubbled);
|
||||
const targets = [document.createElement("input"), document.createElement("textarea"), document.createElement("div"), document.createElement("div")];
|
||||
targets[2]!.setAttribute("contenteditable", "true");
|
||||
targets[3]!.setAttribute("role", "textbox");
|
||||
|
||||
for (const target of targets) {
|
||||
root.append(target);
|
||||
const event = goToColumnEvent(target);
|
||||
expect(event.defaultPrevented).toBe(false);
|
||||
}
|
||||
await settle();
|
||||
|
||||
expect(bubbled).toHaveBeenCalledTimes(targets.length);
|
||||
expect(goToColumnButton(host).getAttribute("aria-expanded")).toBe("false");
|
||||
});
|
||||
|
||||
it("leaves an unmatched root event untouched", async () => {
|
||||
const { host } = mountGrid();
|
||||
await settle();
|
||||
const root = gridRoot(host);
|
||||
const bubbled = vi.fn();
|
||||
host.addEventListener("keydown", bubbled);
|
||||
const event = new KeyboardEvent("keydown", { bubbles: true, cancelable: true, ctrlKey: true, key: "j" });
|
||||
|
||||
root.dispatchEvent(event);
|
||||
await settle();
|
||||
|
||||
expect(event.defaultPrevented).toBe(false);
|
||||
expect(bubbled).toHaveBeenCalledOnce();
|
||||
expect(goToColumnButton(host).getAttribute("aria-expanded")).toBe("false");
|
||||
});
|
||||
|
||||
it("opens the existing popover only for a handled root shortcut", () => {
|
||||
const keydown = functionBody("onGridKeydown", "copyDetailValue");
|
||||
|
||||
expect(dataGridSource).toMatch(/<div\b(?=[^>]*\bdata-grid-root)(?=[^>]*\btabindex="0")(?=[^>]*@keydown="onGridKeydown")[^>]*>/);
|
||||
expect(keydown).toMatch(
|
||||
/const targetAllowsNativeClipboard = eventTargetAllowsNativeClipboard\(event\);[\s\S]*?if \(!targetAllowsNativeClipboard && displayableColumnIndexes\.value\.length > 0 && isGoToColumnShortcut\(event, settingsStore\.editorSettings\.shortcuts\)\) \{[\s\S]*?event\.preventDefault\(\);[\s\S]*?event\.stopPropagation\(\);[\s\S]*?goToColumnOpen\.value = true;[\s\S]*?return;[\s\S]*?\}/,
|
||||
);
|
||||
});
|
||||
|
||||
it("leaves editable targets and unhandled events untouched by the shortcut", () => {
|
||||
const keydown = functionBody("onGridKeydown", "copyDetailValue");
|
||||
const shortcutStart = keydown.indexOf("if (!targetAllowsNativeClipboard && displayableColumnIndexes.value.length > 0 && isGoToColumnShortcut");
|
||||
const shortcutEnd = keydown.indexOf("if (isFocusSearchShortcut", shortcutStart);
|
||||
const shortcutBranch = keydown.slice(shortcutStart, shortcutEnd);
|
||||
|
||||
expect(shortcutStart).toBeGreaterThan(-1);
|
||||
expect(shortcutBranch).not.toContain("else");
|
||||
expect(shortcutBranch.match(/preventDefault/g)).toHaveLength(1);
|
||||
expect(shortcutBranch.match(/stopPropagation/g)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("keeps toolbar navigation and the existing search/filter/reveal path", () => {
|
||||
const selectColumn = functionBody("scrollToColumn", "onGoToColumnKeydown");
|
||||
const escape = functionBody("onGoToColumnKeydown", "matchesTableInfoColumn");
|
||||
const scroll = functionBody("scrollToColumnIndex", "measureColumnHeaderText");
|
||||
|
||||
expect(dataGridSource.match(/<Popover v-model:open="goToColumnOpen">/g)).toHaveLength(1);
|
||||
expect(dataGridSource).toContain('>{{ t("grid.goToColumn") }}</span');
|
||||
expect(dataGridSource).toContain('v-model="goToColumnSearch"');
|
||||
expect(dataGridSource).toContain("filterDataGridColumnLookupItems(goToColumnItems.value, goToColumnSearch.value)");
|
||||
expect(selectColumn).toContain('goToColumnSearch.value = ""');
|
||||
expect(selectColumn).toContain("scrollToColumnIndex(columnIndex)");
|
||||
expect(escape).toMatch(/event\.key === "Escape"[\s\S]*?goToColumnOpen\.value = false;[\s\S]*?goToColumnSearch\.value = ""/);
|
||||
expect(scroll).toContain("if (hiddenColumnIndexes.value.has(columnIndex))");
|
||||
expect(scroll).toContain("showColumn(columnIndex)");
|
||||
expect(scroll).toContain("highlightedColumnIndex.value = columnIndex");
|
||||
expect(scroll).toContain("scroller.scrollLeft = targetLeft");
|
||||
expect(scroll).toContain("updateGridHorizontalViewport(scroller)");
|
||||
});
|
||||
});
|
||||
@@ -6518,6 +6518,7 @@ export default {
|
||||
shortcutExtendSelection: "Extend selection",
|
||||
shortcutCopyCurrentRow: "Copy current data row",
|
||||
shortcutDeleteCurrentRow: "Delete current data row",
|
||||
shortcutGoToColumn: "Go to column",
|
||||
shortcutNewQuery: "New query",
|
||||
shortcutOpenSettings: "Open settings",
|
||||
shortcutCloseTab: "Close tab",
|
||||
|
||||
@@ -6189,6 +6189,7 @@ export default withEnglishFallback({
|
||||
shortcutExtendSelection: "Ampliar selección",
|
||||
shortcutCopyCurrentRow: "Copiar fila de datos actual",
|
||||
shortcutDeleteCurrentRow: "Eliminar fila de datos actual",
|
||||
shortcutGoToColumn: "Ir a la columna",
|
||||
shortcutNewQuery: "Nueva consulta",
|
||||
shortcutOpenSettings: "Abrir configuración",
|
||||
shortcutCloseTab: "Cerrar pestaña",
|
||||
|
||||
@@ -6189,6 +6189,7 @@ export default withEnglishFallback({
|
||||
shortcutExtendSelection: "Estendi selezione",
|
||||
shortcutCopyCurrentRow: "Copia riga dati corrente",
|
||||
shortcutDeleteCurrentRow: "Elimina riga dati corrente",
|
||||
shortcutGoToColumn: "Vai alla colonna",
|
||||
shortcutNewQuery: "Nuova query",
|
||||
shortcutOpenSettings: "Apri impostazioni",
|
||||
shortcutCloseTab: "Chiudi scheda",
|
||||
|
||||
@@ -6203,6 +6203,7 @@ export default withEnglishFallback({
|
||||
shortcutExtendSelection: "選択範囲を拡張",
|
||||
shortcutCopyCurrentRow: "現在のデータ行をコピー",
|
||||
shortcutDeleteCurrentRow: "現在のデータ行を削除",
|
||||
shortcutGoToColumn: "列へ移動",
|
||||
shortcutNewQuery: "新しいクエリ",
|
||||
shortcutOpenSettings: "設定を開く",
|
||||
shortcutCloseTab: "タブを閉じる",
|
||||
|
||||
@@ -5900,6 +5900,7 @@ export default withEnglishFallback({
|
||||
shortcutSelectAll: "모두 선택",
|
||||
shortcutCopyCurrentRow: "현재 데이터 행 복사",
|
||||
shortcutDeleteCurrentRow: "현재 데이터 행 삭제",
|
||||
shortcutGoToColumn: "컬럼으로 이동",
|
||||
shortcutNewQuery: "새 쿼리",
|
||||
shortcutOpenSettings: "설정 열기",
|
||||
shortcutCloseTab: "탭 닫기",
|
||||
|
||||
@@ -6191,6 +6191,7 @@ export default withEnglishFallback({
|
||||
shortcutExtendSelection: "Expandir seleção",
|
||||
shortcutCopyCurrentRow: "Copiar linha de dados atual",
|
||||
shortcutDeleteCurrentRow: "Excluir linha de dados atual",
|
||||
shortcutGoToColumn: "Ir para a coluna",
|
||||
shortcutNewQuery: "Nova consulta",
|
||||
shortcutOpenSettings: "Abrir configurações",
|
||||
shortcutCloseTab: "Fechar aba",
|
||||
|
||||
@@ -6504,6 +6504,7 @@ export default withEnglishFallback({
|
||||
shortcutExPasteSqlInCondition: "ExPaste:粘贴为 IN 条件",
|
||||
shortcutCopyCurrentRow: "复制当前数据行",
|
||||
shortcutDeleteCurrentRow: "删除当前数据行",
|
||||
shortcutGoToColumn: "跳转列",
|
||||
shortcutNewQuery: "新建查询",
|
||||
shortcutOpenSettings: "打开设置",
|
||||
shortcutCloseTab: "关闭标签页",
|
||||
|
||||
@@ -5496,6 +5496,7 @@ export default withEnglishFallback({
|
||||
shortcutExtendSelection: "擴展選取範圍",
|
||||
shortcutCopyCurrentRow: "複製目前資料列",
|
||||
shortcutDeleteCurrentRow: "刪除目前資料列",
|
||||
shortcutGoToColumn: "跳轉欄",
|
||||
shortcutNewQuery: "建立查詢",
|
||||
shortcutOpenSettings: "開啟設定",
|
||||
shortcutCloseTab: "關閉分頁",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { eventToModifierOnlyShortcut, eventToShortcut, isExecuteSqlInNewResultTabShortcut, matchesModifierOnlyShortcut, matchesShortcut, tabSwitcherDirectionFromShortcut } from "@/lib/editor/keyboardShortcuts";
|
||||
import { eventToModifierOnlyShortcut, eventToShortcut, isExecuteSqlInNewResultTabShortcut, isGoToColumnShortcut, matchesModifierOnlyShortcut, matchesShortcut, tabSwitcherDirectionFromShortcut } from "@/lib/editor/keyboardShortcuts";
|
||||
import { formatShortcutDisplay, isMacShortcutPlatform } from "@/lib/editor/shortcutDisplay";
|
||||
|
||||
describe("keyboard shortcut matching", () => {
|
||||
@@ -82,6 +82,18 @@ describe("keyboard shortcut matching", () => {
|
||||
expect(matchesShortcut({ key: "+", ctrlKey: true }, "Mod++", "Win32")).toBe(true);
|
||||
expect(matchesShortcut({ key: "+", ctrlKey: true, shiftKey: true }, "Shift+Mod++", "Win32")).toBe(true);
|
||||
});
|
||||
|
||||
it("matches only the configured go-to-column shortcut", () => {
|
||||
expect(isGoToColumnShortcut({ key: "g", ctrlKey: true }, { goToColumn: "Mod+G" })).toBe(true);
|
||||
expect(isGoToColumnShortcut({ key: "g", ctrlKey: true, shiftKey: true }, { goToColumn: "Mod+G" })).toBe(false);
|
||||
expect(isGoToColumnShortcut({ key: "j", ctrlKey: true }, { goToColumn: "Mod+G" })).toBe(false);
|
||||
});
|
||||
|
||||
it("does not match an empty or composing go-to-column shortcut", () => {
|
||||
expect(isGoToColumnShortcut({ key: "g", ctrlKey: true })).toBe(false);
|
||||
expect(isGoToColumnShortcut({ key: "g", ctrlKey: true }, { goToColumn: "" })).toBe(false);
|
||||
expect(isGoToColumnShortcut({ key: "g", ctrlKey: true, isComposing: true }, { goToColumn: "Mod+G" })).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("tabSwitcherDirectionFromShortcut", () => {
|
||||
|
||||
@@ -25,6 +25,31 @@ describe("shortcutRegistry editor actions", () => {
|
||||
];
|
||||
const sidebarShortcutActionIds: ShortcutActionId[] = ["copySidebarSelection", "pasteSidebarSelection", "editSidebarConnection", "viewTableDdl"];
|
||||
|
||||
it("registers go to column as an unassigned grid shortcut", () => {
|
||||
const definition = SHORTCUT_DEFINITIONS.find((item) => item.id === "goToColumn");
|
||||
|
||||
expect(definition).toMatchObject({
|
||||
labelKey: "settings.shortcutGoToColumn",
|
||||
scope: "grid",
|
||||
defaultShortcut: "",
|
||||
});
|
||||
expect(DEFAULT_SHORTCUT_SETTINGS.goToColumn).toBe("");
|
||||
});
|
||||
|
||||
it("normalizes missing, legacy, cleared, and configured go-to-column settings", () => {
|
||||
expect(normalizeShortcutSettings().goToColumn).toBe("");
|
||||
expect(normalizeShortcutSettings({ executeSql: "Mod+Shift+Enter" }).goToColumn).toBe("");
|
||||
expect(normalizeShortcutSettings({ goToColumn: "" }).goToColumn).toBe("");
|
||||
expect(normalizeShortcutSettings({ goToColumn: "Mod+G" }).goToColumn).toBe("Mod+G");
|
||||
});
|
||||
|
||||
it("detects go-to-column conflicts only within the grid scope", () => {
|
||||
const shortcuts = normalizeShortcutSettings({ goToColumn: "Mod+D" });
|
||||
|
||||
expect(findShortcutConflict("goToColumn", shortcuts.goToColumn, shortcuts)).toBe("copyCurrentRow");
|
||||
expect(findShortcutConflict("goToColumn", "Mod+F", shortcuts)).toBeNull();
|
||||
});
|
||||
|
||||
it("registers the new-data-tab mouse modifier as a configurable sidebar shortcut", () => {
|
||||
const definition = SHORTCUT_DEFINITIONS.find((item) => item.id === "openDataInNewTab");
|
||||
|
||||
|
||||
@@ -207,6 +207,10 @@ export function isDeleteCurrentRowShortcut(event: ShortcutLikeEvent, shortcuts?:
|
||||
return matchesShortcut(event, actionShortcut("deleteCurrentRow", shortcuts));
|
||||
}
|
||||
|
||||
export function isGoToColumnShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
||||
return matchesShortcut(event, actionShortcut("goToColumn", shortcuts));
|
||||
}
|
||||
|
||||
export function isCancelSearchShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>): boolean {
|
||||
return matchesShortcut(event, actionShortcut("cancelSearch", shortcuts));
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ export type ShortcutActionId =
|
||||
| "toggleFold"
|
||||
| "copyCurrentRow"
|
||||
| "deleteCurrentRow"
|
||||
| "goToColumn"
|
||||
| "newQuery"
|
||||
| "openSettings"
|
||||
| "closeTab"
|
||||
@@ -280,6 +281,12 @@ export const SHORTCUT_DEFINITIONS: ShortcutDefinition[] = [
|
||||
scope: "grid",
|
||||
defaultShortcut: "Delete",
|
||||
},
|
||||
{
|
||||
id: "goToColumn",
|
||||
labelKey: "settings.shortcutGoToColumn",
|
||||
scope: "grid",
|
||||
defaultShortcut: "",
|
||||
},
|
||||
{
|
||||
id: "newQuery",
|
||||
labelKey: "settings.shortcutNewQuery",
|
||||
|
||||
Reference in new issue
Block a user