From 19201345c23b52c3090d29712335936e4e11cbfa Mon Sep 17 00:00:00 2001 From: Jindrich Susen Date: Mon, 28 Aug 2023 11:13:40 +0200 Subject: [PATCH 1/2] Shortcuts were not activated when focus was in an editor --- .../src/gui/connections/CDataViewHeader.tsx | 28 +++---------- .../MobileComponents/Grid/DataViewHeader.tsx | 14 +++---- frontend-html/src/index.tsx | 22 ++++++++++ .../DataView/TableView/onFieldKeyDown.ts | 23 +++++++++++ frontend-html/src/utils/shortcuts.ts | 40 +++++++++++++++++++ 5 files changed, 98 insertions(+), 29 deletions(-) create mode 100644 frontend-html/src/utils/shortcuts.ts diff --git a/frontend-html/src/gui/connections/CDataViewHeader.tsx b/frontend-html/src/gui/connections/CDataViewHeader.tsx index 315badce4c..ebc658951e 100644 --- a/frontend-html/src/gui/connections/CDataViewHeader.tsx +++ b/frontend-html/src/gui/connections/CDataViewHeader.tsx @@ -71,6 +71,12 @@ import { getTrueSelectedRowIndex } from "model/selectors/DataView/getTrueSelecte import { getAreCrudButtonsEnabled } from "model/selectors/DataView/getAreCrudButtonsEnabled"; import { IDataView } from "model/entities/types/IDataView"; import { saveColumnConfigurationsAsync } from "model/actions/DataView/TableView/saveColumnConfigurations"; +import { + isAddRecordShortcut, + isDeleteRecordShortcut, + isDuplicateRecordShortcut, + isFilterRecordShortcut +} from "utils/shortcuts"; @observer export class CDataViewHeaderInner extends React.Component<{ @@ -485,25 +491,3 @@ export function CDataViewHeader(props: { isVisible: boolean }) { const extension = useContext(CtxDataViewHeaderExtension); return ; } - -export function isAddRecordShortcut(event: any) { - return ( - ((event.ctrlKey || event.metaKey) && !event.shiftKey && event.key === "i") || - ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === "j") || - event.key === "Insert" - ); -} - -export function isDeleteRecordShortcut(event: any) { - return (event.ctrlKey || event.metaKey) && !event.shiftKey && event.key === "Delete"; -} - -export function isDuplicateRecordShortcut(event: any) { - return ( - (event.ctrlKey || event.metaKey) && !event.shiftKey && (event.key === "d" || event.key === "k") - ); -} - -export function isFilterRecordShortcut(event: any) { - return (event.ctrlKey || event.metaKey) && event.key === "f"; -} diff --git a/frontend-html/src/gui/connections/MobileComponents/Grid/DataViewHeader.tsx b/frontend-html/src/gui/connections/MobileComponents/Grid/DataViewHeader.tsx index 765e4f58ec..a42539607d 100644 --- a/frontend-html/src/gui/connections/MobileComponents/Grid/DataViewHeader.tsx +++ b/frontend-html/src/gui/connections/MobileComponents/Grid/DataViewHeader.tsx @@ -54,13 +54,7 @@ import { action, computed } from "mobx"; import { getPanelMenuActions } from "model/selectors/DataView/getPanelMenuActions"; import { DropdownDivider } from "gui/Components/Dropdown/DropdownDivider"; import { getAreCrudButtonsEnabled } from "model/selectors/DataView/getAreCrudButtonsEnabled"; -import { - isAddRecordShortcut, - isDeleteRecordShortcut, - isDuplicateRecordShortcut, - isFilterRecordShortcut, - renderRowCount -} from "gui/connections/CDataViewHeader"; +import { renderRowCount} from "gui/connections/CDataViewHeader"; import { DataViewHeader } from "gui/Components/DataViewHeader/DataViewHeader"; import "gui/connections/MobileComponents/Grid/DataViewHeader.module.scss" import { getMobileState } from "model/selectors/getMobileState"; @@ -71,6 +65,12 @@ import { getColumnConfigurationModel } from "model/selectors/getColumnConfigurat import { saveColumnConfigurationsAsync } from "model/actions/DataView/TableView/saveColumnConfigurations"; import { getRecordInfo } from "model/selectors/RecordInfo/getRecordInfo"; import { RecordInfo } from "gui/connections/MobileComponents/Grid/RecordInfo"; +import { + isAddRecordShortcut, + isDeleteRecordShortcut, + isDuplicateRecordShortcut, + isFilterRecordShortcut +} from "utils/shortcuts"; @observer export class DataViewHeaderInner extends React.Component<{ diff --git a/frontend-html/src/index.tsx b/frontend-html/src/index.tsx index 509625192c..627d1c3e03 100644 --- a/frontend-html/src/index.tsx +++ b/frontend-html/src/index.tsx @@ -44,6 +44,12 @@ import { preventDoubleclickSelect } from "utils/mouse"; import { RootError } from "RootError"; // eslint-disable-next-line @typescript-eslint/no-unused-vars import { ArrayPrototypes } from "@origam/utils" +import { + isAddRecordShortcut, + isDeleteRecordShortcut, + isDuplicateRecordShortcut, + isFilterRecordShortcut +} from "utils/shortcuts"; if (import.meta.env.DEV) { axios.defaults.timeout = 3600000; @@ -63,9 +69,25 @@ function disableAutoZoomingOnIPhone(){ } } +function disableCollidingBrowserShortcuts() { + const ignoreShortcuts = (event: KeyboardEvent) => { + if ( + isAddRecordShortcut(event) || + isDuplicateRecordShortcut(event) || + isDeleteRecordShortcut(event) || + isFilterRecordShortcut(event) + ) { + event.preventDefault(); + } + }; + + window.addEventListener("keydown", ignoreShortcuts); +} + async function main() { disableAutoZoomingOnIPhone(); preventDoubleclickSelect(); + disableCollidingBrowserShortcuts(); const locationHash = window.location.hash; const TOKEN_OVR_HASH = "#origamAuthTokenOverride="; if (locationHash.startsWith(TOKEN_OVR_HASH)) { diff --git a/frontend-html/src/model/actions-ui/DataView/TableView/onFieldKeyDown.ts b/frontend-html/src/model/actions-ui/DataView/TableView/onFieldKeyDown.ts index b5352b1aee..afd82110ea 100644 --- a/frontend-html/src/model/actions-ui/DataView/TableView/onFieldKeyDown.ts +++ b/frontend-html/src/model/actions-ui/DataView/TableView/onFieldKeyDown.ts @@ -29,6 +29,16 @@ import { getDataView } from "model/selectors/DataView/getDataView"; import { shouldProceedToChangeRow } from "model/actions-ui/DataView/TableView/shouldProceedToChangeRow"; import { getGridFocusManager } from "model/entities/GridFocusManager"; import { isSaveShortcut } from "utils/keyShortcuts"; +import { + isAddRecordShortcut, + isDeleteRecordShortcut, + isDuplicateRecordShortcut, + isFilterRecordShortcut +} from "utils/shortcuts"; +import { onDeleteRowClick } from "model/actions-ui/DataView/onDeleteRowClick"; +import { onCreateRowClick } from "model/actions-ui/DataView/onCreateRowClick"; +import { onCopyRowClick } from "model/actions-ui/DataView/onCopyRowClick"; +import { onFilterButtonClick } from "model/actions-ui/DataView/onFilterButtonClick"; export function onFieldKeyDown(ctx: any) { @@ -118,6 +128,19 @@ export function onFieldKeyDown(ctx: any) { tablePanelView.triggerOnFocusTable(); break; } + default: + if(isAddRecordShortcut(event)){ + yield onCreateRowClick(dataView)(event); + } + else if(isDeleteRecordShortcut(event) ){ + yield onDeleteRowClick(dataView)(event); + } + else if(isDuplicateRecordShortcut(event)){ + yield onCopyRowClick(dataView)(event); + } + else if(isFilterRecordShortcut(event)){ + yield onFilterButtonClick(dataView)(event); + } } } catch (e) { yield*handleError(ctx)(e); diff --git a/frontend-html/src/utils/shortcuts.ts b/frontend-html/src/utils/shortcuts.ts new file mode 100644 index 0000000000..12bd1a1100 --- /dev/null +++ b/frontend-html/src/utils/shortcuts.ts @@ -0,0 +1,40 @@ +/* +Copyright 2005 - 2023 Advantage Solutions, s. r. o. + +This file is part of ORIGAM (http://www.origam.org). + +ORIGAM is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +ORIGAM is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with ORIGAM. If not, see . +*/ + +export function isAddRecordShortcut(event: any) { + return ( + ((event.ctrlKey || event.metaKey) && !event.shiftKey && event.key === "i") || + ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === "j") || + event.key === "Insert" + ); +} + +export function isDeleteRecordShortcut(event: any) { + return (event.ctrlKey || event.metaKey) && !event.shiftKey && event.key === "Delete"; +} + +export function isDuplicateRecordShortcut(event: any) { + return ( + (event.ctrlKey || event.metaKey) && !event.shiftKey && (event.key === "d" || event.key === "k") + ); +} + +export function isFilterRecordShortcut(event: any) { + return (event.ctrlKey || event.metaKey) && event.key === "f"; +} \ No newline at end of file From 7d47069801b3661173525db35a873aa0b920aa17 Mon Sep 17 00:00:00 2001 From: Jindrich Susen Date: Mon, 28 Aug 2023 11:13:40 +0200 Subject: [PATCH 2/2] Shortcut functions moved to a single file --- .../src/gui/connections/CDataViewHeader.tsx | 2 +- .../MobileComponents/Grid/DataViewHeader.tsx | 2 +- frontend-html/src/index.tsx | 2 +- .../DataView/TableView/onFieldKeyDown.ts | 26 +++++------- frontend-html/src/utils/keyShortcuts.ts | 22 ++++++++++ frontend-html/src/utils/shortcuts.ts | 40 ------------------- 6 files changed, 36 insertions(+), 58 deletions(-) delete mode 100644 frontend-html/src/utils/shortcuts.ts diff --git a/frontend-html/src/gui/connections/CDataViewHeader.tsx b/frontend-html/src/gui/connections/CDataViewHeader.tsx index ebc658951e..79f46b3d2f 100644 --- a/frontend-html/src/gui/connections/CDataViewHeader.tsx +++ b/frontend-html/src/gui/connections/CDataViewHeader.tsx @@ -76,7 +76,7 @@ import { isDeleteRecordShortcut, isDuplicateRecordShortcut, isFilterRecordShortcut -} from "utils/shortcuts"; +} from "utils/keyShortcuts"; @observer export class CDataViewHeaderInner extends React.Component<{ diff --git a/frontend-html/src/gui/connections/MobileComponents/Grid/DataViewHeader.tsx b/frontend-html/src/gui/connections/MobileComponents/Grid/DataViewHeader.tsx index a42539607d..1a6dca319a 100644 --- a/frontend-html/src/gui/connections/MobileComponents/Grid/DataViewHeader.tsx +++ b/frontend-html/src/gui/connections/MobileComponents/Grid/DataViewHeader.tsx @@ -70,7 +70,7 @@ import { isDeleteRecordShortcut, isDuplicateRecordShortcut, isFilterRecordShortcut -} from "utils/shortcuts"; +} from "utils/keyShortcuts"; @observer export class DataViewHeaderInner extends React.Component<{ diff --git a/frontend-html/src/index.tsx b/frontend-html/src/index.tsx index 627d1c3e03..2bfc6aadb1 100644 --- a/frontend-html/src/index.tsx +++ b/frontend-html/src/index.tsx @@ -49,7 +49,7 @@ import { isDeleteRecordShortcut, isDuplicateRecordShortcut, isFilterRecordShortcut -} from "utils/shortcuts"; +} from "utils/keyShortcuts"; if (import.meta.env.DEV) { axios.defaults.timeout = 3600000; diff --git a/frontend-html/src/model/actions-ui/DataView/TableView/onFieldKeyDown.ts b/frontend-html/src/model/actions-ui/DataView/TableView/onFieldKeyDown.ts index afd82110ea..947340abb1 100644 --- a/frontend-html/src/model/actions-ui/DataView/TableView/onFieldKeyDown.ts +++ b/frontend-html/src/model/actions-ui/DataView/TableView/onFieldKeyDown.ts @@ -28,13 +28,13 @@ import { handleError } from "model/actions/handleError"; import { getDataView } from "model/selectors/DataView/getDataView"; import { shouldProceedToChangeRow } from "model/actions-ui/DataView/TableView/shouldProceedToChangeRow"; import { getGridFocusManager } from "model/entities/GridFocusManager"; -import { isSaveShortcut } from "utils/keyShortcuts"; import { + isSaveShortcut, isAddRecordShortcut, isDeleteRecordShortcut, isDuplicateRecordShortcut, isFilterRecordShortcut -} from "utils/shortcuts"; +} from "utils/keyShortcuts"; import { onDeleteRowClick } from "model/actions-ui/DataView/onDeleteRowClick"; import { onCreateRowClick } from "model/actions-ui/DataView/onCreateRowClick"; import { onCopyRowClick } from "model/actions-ui/DataView/onCopyRowClick"; @@ -52,11 +52,6 @@ export function onFieldKeyDown(ctx: any) { const dataView = getDataView(ctx); const tablePanelView = getTablePanelView(ctx); tablePanelView.handleEditorKeyDown(event); - if( isSaveShortcut(event)){ - tablePanelView.setEditing(false); - yield*flushCurrentRowData(ctx)(); - return; - } switch (event.key) { case "Tab": { if (isGoingToChangeRow(event)) { @@ -128,19 +123,20 @@ export function onFieldKeyDown(ctx: any) { tablePanelView.triggerOnFocusTable(); break; } - default: - if(isAddRecordShortcut(event)){ + default: { + if (isSaveShortcut(event)) { + tablePanelView.setEditing(false); + yield*flushCurrentRowData(ctx)(); + } else if (isAddRecordShortcut(event)) { yield onCreateRowClick(dataView)(event); - } - else if(isDeleteRecordShortcut(event) ){ + } else if (isDeleteRecordShortcut(event)) { yield onDeleteRowClick(dataView)(event); - } - else if(isDuplicateRecordShortcut(event)){ + } else if (isDuplicateRecordShortcut(event)) { yield onCopyRowClick(dataView)(event); - } - else if(isFilterRecordShortcut(event)){ + } else if (isFilterRecordShortcut(event)) { yield onFilterButtonClick(dataView)(event); } + } } } catch (e) { yield*handleError(ctx)(e); diff --git a/frontend-html/src/utils/keyShortcuts.ts b/frontend-html/src/utils/keyShortcuts.ts index a9aaba84cd..01c7971e46 100644 --- a/frontend-html/src/utils/keyShortcuts.ts +++ b/frontend-html/src/utils/keyShortcuts.ts @@ -24,3 +24,25 @@ export function isSaveShortcut(event: any) { export function isRefreshShortcut(event: any) { return event.key === "r" && (event.ctrlKey || event.metaKey); } + +export function isAddRecordShortcut(event: any) { + return ( + ((event.ctrlKey || event.metaKey) && !event.shiftKey && event.key === "i") || + ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === "j") || + event.key === "Insert" + ); +} + +export function isDeleteRecordShortcut(event: any) { + return (event.ctrlKey || event.metaKey) && !event.shiftKey && event.key === "Delete"; +} + +export function isDuplicateRecordShortcut(event: any) { + return ( + (event.ctrlKey || event.metaKey) && !event.shiftKey && (event.key === "d" || event.key === "k") + ); +} + +export function isFilterRecordShortcut(event: any) { + return (event.ctrlKey || event.metaKey) && event.key === "f"; +} \ No newline at end of file diff --git a/frontend-html/src/utils/shortcuts.ts b/frontend-html/src/utils/shortcuts.ts deleted file mode 100644 index 12bd1a1100..0000000000 --- a/frontend-html/src/utils/shortcuts.ts +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 2005 - 2023 Advantage Solutions, s. r. o. - -This file is part of ORIGAM (http://www.origam.org). - -ORIGAM is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -ORIGAM is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with ORIGAM. If not, see . -*/ - -export function isAddRecordShortcut(event: any) { - return ( - ((event.ctrlKey || event.metaKey) && !event.shiftKey && event.key === "i") || - ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === "j") || - event.key === "Insert" - ); -} - -export function isDeleteRecordShortcut(event: any) { - return (event.ctrlKey || event.metaKey) && !event.shiftKey && event.key === "Delete"; -} - -export function isDuplicateRecordShortcut(event: any) { - return ( - (event.ctrlKey || event.metaKey) && !event.shiftKey && (event.key === "d" || event.key === "k") - ); -} - -export function isFilterRecordShortcut(event: any) { - return (event.ctrlKey || event.metaKey) && event.key === "f"; -} \ No newline at end of file