diff --git a/src/App.tsx b/src/App.tsx
index 59ee713..c9995f6 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -574,6 +574,7 @@ export default function App()
const [tableMetaData, setTableMetaData] = useState(null);
const [tableProcesses, setTableProcesses] = useState(null);
const [dotMenuOpen, setDotMenuOpen] = useState(false);
+ const [keyboardHelpOpen, setKeyboardHelpOpen] = useState(false);
return (
appRoutes && (
@@ -583,11 +584,13 @@ export default function App()
tableMetaData: tableMetaData,
tableProcesses: tableProcesses,
dotMenuOpen: dotMenuOpen,
+ keyboardHelpOpen: keyboardHelpOpen,
setPageHeader: (header: string | JSX.Element) => setPageHeader(header),
setAccentColor: (accentColor: string) => setAccentColor(accentColor),
setTableMetaData: (tableMetaData: QTableMetaData) => setTableMetaData(tableMetaData),
setTableProcesses: (tableProcesses: QProcessMetaData[]) => setTableProcesses(tableProcesses),
setDotMenuOpen: (dotMenuOpent: boolean) => setDotMenuOpen(dotMenuOpent),
+ setKeyboardHelpOpen: (keyboardHelpOpen: boolean) => setKeyboardHelpOpen(keyboardHelpOpen),
pathToLabelMap: pathToLabelMap,
branding: branding
}}>
diff --git a/src/CommandMenu.tsx b/src/CommandMenu.tsx
index 6d672f2..f368813 100644
--- a/src/CommandMenu.tsx
+++ b/src/CommandMenu.tsx
@@ -67,9 +67,8 @@ const CommandMenu = ({metaData}: Props) =>
const navigate = useNavigate();
const pathParts = location.pathname.replace(/\/+$/, "").split("/");
- const {accentColor, tableMetaData, dotMenuOpen, setDotMenuOpen, setTableMetaData, tableProcesses} = useContext(QContext);
+ const {accentColor, tableMetaData, dotMenuOpen, setDotMenuOpen, keyboardHelpOpen, setKeyboardHelpOpen, setTableMetaData, tableProcesses} = useContext(QContext);
- const [keyboardHelpOpen, setKeyboardHelpOpen] = useState(false)
const classes = useStyles();
function evalueKeyPress(e: KeyboardEvent)
@@ -351,6 +350,14 @@ const CommandMenu = ({metaData}: Props) =>
?Open Keyboard Shortcuts Help
+ Table Query
+
+ nCreate a New Record
+ rRefresh the Query
+ cOpen the Columns Panel
+ fOpen the Filter Panel
+
+
Record View
nCreate a New Record
diff --git a/src/QContext.tsx b/src/QContext.tsx
index 2cd7ca5..b13c8e5 100644
--- a/src/QContext.tsx
+++ b/src/QContext.tsx
@@ -37,6 +37,9 @@ interface QContext
dotMenuOpen: boolean;
setDotMenuOpen?: (dotMenuOpen: boolean) => void;
+ keyboardHelpOpen: boolean;
+ setKeyboardHelpOpen?: (keyboardHelpOpen: boolean) => void;
+
tableMetaData?: QTableMetaData;
setTableMetaData?: (tableMetaData: QTableMetaData) => void;
@@ -54,6 +57,7 @@ const defaultState = {
pageHeader: "",
accentColor: "#0062FF",
dotMenuOpen: false,
+ keyboardHelpOpen: false,
pathToLabelMap: {},
};
diff --git a/src/qqq/pages/records/query/RecordQuery.tsx b/src/qqq/pages/records/query/RecordQuery.tsx
index 0a121f8..9ebef6d 100644
--- a/src/qqq/pages/records/query/RecordQuery.tsx
+++ b/src/qqq/pages/records/query/RecordQuery.tsx
@@ -51,7 +51,7 @@ import MenuItem from "@mui/material/MenuItem";
import Modal from "@mui/material/Modal";
import TextField from "@mui/material/TextField";
import Tooltip from "@mui/material/Tooltip";
-import {DataGridPro, GridCallbackDetails, GridColDef, GridColumnMenuContainer, GridColumnMenuProps, GridColumnOrderChangeParams, GridColumnPinningMenuItems, GridColumnsMenuItem, GridColumnVisibilityModel, GridDensity, GridEventListener, GridExportMenuItemProps, GridFilterMenuItem, GridFilterModel, GridPinnedColumns, gridPreferencePanelStateSelector, GridRowId, GridRowParams, GridRowsProp, GridSelectionModel, GridSortItem, GridSortModel, GridState, GridToolbarColumnsButton, GridToolbarContainer, GridToolbarDensitySelector, GridToolbarExportContainer, GridToolbarFilterButton, HideGridColMenuItem, MuiEvent, SortGridMenuItems, useGridApiContext, useGridApiEventHandler, useGridSelector} from "@mui/x-data-grid-pro";
+import {DataGridPro, GridCallbackDetails, GridColDef, GridColumnMenuContainer, GridColumnMenuProps, GridColumnOrderChangeParams, GridColumnPinningMenuItems, GridColumnsMenuItem, GridColumnVisibilityModel, GridDensity, GridEventListener, GridExportMenuItemProps, GridFilterMenuItem, GridFilterModel, GridPinnedColumns, gridPreferencePanelStateSelector, GridRowId, GridRowParams, GridRowsProp, GridSelectionModel, GridSortItem, GridSortModel, GridState, GridToolbarColumnsButton, GridToolbarContainer, GridToolbarDensitySelector, GridToolbarExportContainer, GridToolbarFilterButton, HideGridColMenuItem, MuiEvent, SortGridMenuItems, useGridApiContext, useGridApiEventHandler, useGridSelector, useGridApiRef, GridPreferencePanelsValue} from "@mui/x-data-grid-pro";
import {GridRowModel} from "@mui/x-data-grid/models/gridRows";
import FormData from "form-data";
import React, {forwardRef, useContext, useEffect, useReducer, useRef, useState} from "react";
@@ -252,12 +252,65 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
const [queryErrors, setQueryErrors] = useState({} as any);
const [receivedQueryErrorTimestamp, setReceivedQueryErrorTimestamp] = useState(new Date());
- const {setPageHeader} = useContext(QContext);
+ const {setPageHeader, dotMenuOpen, keyboardHelpOpen} = useContext(QContext);
const [, forceUpdate] = useReducer((x) => x + 1, 0);
const openActionsMenu = (event: any) => setActionsMenu(event.currentTarget);
const closeActionsMenu = () => setActionsMenu(null);
+ const gridApiRef = useGridApiRef();
+
+ ///////////////////////
+ // Keyboard handling //
+ ///////////////////////
+ useEffect(() =>
+ {
+ if(tableMetaData == null)
+ {
+ (async() =>
+ {
+ const tableMetaData = await qController.loadTableMetaData(tableName);
+ setTableMetaData(tableMetaData);
+ })();
+ }
+
+ const down = (e: KeyboardEvent) =>
+ {
+ const type = (e.target as any).type;
+ const validType = (type !== "text" && type !== "textarea" && type !== "input" && type !== "search");
+
+ if(validType && !dotMenuOpen && !keyboardHelpOpen && !activeModalProcess)
+ {
+ if (! e.metaKey && e.key === "n" && table.capabilities.has(Capability.TABLE_INSERT) && table.insertPermission)
+ {
+ e.preventDefault()
+ navigate(`${metaData?.getTablePathByName(tableName)}/create`);
+ }
+ else if (! e.metaKey && e.key === "r")
+ {
+ e.preventDefault()
+ updateTable();
+ }
+ else if (! e.metaKey && e.key === "c")
+ {
+ e.preventDefault()
+ gridApiRef.current.showPreferences(GridPreferencePanelsValue.columns)
+ }
+ else if (! e.metaKey && e.key === "f")
+ {
+ e.preventDefault()
+ gridApiRef.current.showFilterPanel()
+ }
+ }
+ }
+
+ document.addEventListener("keydown", down)
+ return () =>
+ {
+ document.removeEventListener("keydown", down)
+ }
+ }, [dotMenuOpen, keyboardHelpOpen, metaData, activeModalProcess])
+
/////////////////////////////////////////////////////////////////////////////////////////
// monitor location changes - if our url looks like a process, then open that process. //
/////////////////////////////////////////////////////////////////////////////////////////
@@ -1934,6 +1987,7 @@ function RecordQuery({table, launchProcess}: Props): JSX.Element
setActionsMenu(event.currentTarget);
const closeActionsMenu = () => setActionsMenu(null);
- const {accentColor, setPageHeader, tableMetaData, setTableMetaData, tableProcesses, setTableProcesses, dotMenuOpen} = useContext(QContext);
+ const {accentColor, setPageHeader, tableMetaData, setTableMetaData, tableProcesses, setTableProcesses, dotMenuOpen, keyboardHelpOpen} = useContext(QContext);
if (localStorage.getItem(tableVariantLocalStorageKey))
{
@@ -138,7 +138,9 @@ function RecordView({table, launchProcess}: Props): JSX.Element
setShowAudit(false);
};
- // Toggle the menu when ⌘K is pressed
+ ///////////////////////
+ // Keyboard handling //
+ ///////////////////////
useEffect(() =>
{
if(tableMetaData == null)
@@ -155,7 +157,7 @@ function RecordView({table, launchProcess}: Props): JSX.Element
const type = (e.target as any).type;
const validType = (type !== "text" && type !== "textarea" && type !== "input" && type !== "search");
- if(validType && !dotMenuOpen && !showAudit && !showEditChildForm)
+ if(validType && !dotMenuOpen && !keyboardHelpOpen && !showAudit && !showEditChildForm)
{
if (! e.metaKey && e.key === "n" && table.capabilities.has(Capability.TABLE_INSERT) && table.insertPermission)
{
@@ -190,7 +192,7 @@ function RecordView({table, launchProcess}: Props): JSX.Element
{
document.removeEventListener("keydown", down)
}
- }, [dotMenuOpen, showEditChildForm, showAudit, metaData])
+ }, [dotMenuOpen, keyboardHelpOpen, showEditChildForm, showAudit, metaData])
const gotoCreate = () =>
{