chore: add rollup config for wds (#39397)
With this PR, we want to publish WDS as a npm package. To do that, we are now adding a rollup setup to compile and build the package. One thing to note: Rollup needed `7.24.0` version of browserlist and we had to update browserlist version in resolutions in root package.json. Now since we updated browserlist, certain code that was written with old format ( code was coming from blueprint's hotkeys component ) started failing and we had to refactor. It included the code around hotkeys component. It was deprecatdd by blueprint and we were still using. We have now refactored those part of code to use the `useHotKeys` hook. /ok-to-test tags="@tag.All" <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/13538917574> > Commit: 9b0b51791e4a95574c9729245ba09994ab371b71 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=13538917574&attempt=2" target="_blank">Cypress dashboard</a>. > Tags: `@tag.All` > Spec: > <hr>Wed, 26 Feb 2025 09:12:45 UTC <!-- end of auto-generated comment: Cypress test results -->
This commit is contained in:
parent
3df028d5a4
commit
d2dc01dc99
|
|
@ -306,7 +306,7 @@
|
|||
"babel-plugin-module-resolver": "^4.1.0",
|
||||
"babel-plugin-named-asset-import": "^0.3.8",
|
||||
"babel-preset-react-app": "^10.0.1",
|
||||
"browserslist": "^4.18.1",
|
||||
"browserslist": "^4.24.4",
|
||||
"case-sensitive-paths-webpack-plugin": "^2.4.0",
|
||||
"chalk": "^4.1.1",
|
||||
"compression-webpack-plugin": "^10.0.0",
|
||||
|
|
@ -399,7 +399,7 @@
|
|||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz"
|
||||
},
|
||||
"resolutions": {
|
||||
"browserslist": "4.20.3",
|
||||
"browserslist": "4.24.4",
|
||||
"chokidar": "3.5.3",
|
||||
"css-select": "4.1.3",
|
||||
"ejs": "3.1.10",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
const esModules = ["remark-gfm"].join("|");
|
||||
|
||||
module.exports = {
|
||||
export default {
|
||||
preset: "ts-jest",
|
||||
roots: ["<rootDir>/src"],
|
||||
setupFiles: ["<rootDir>../../../test/__mocks__/reactMarkdown.tsx"],
|
||||
|
|
|
|||
|
|
@ -4,11 +4,16 @@
|
|||
"main": "src/index.ts",
|
||||
"author": "Valera Melnikov <valera@appsmith.com>, Pawan Kumar <pawan@appsmith.com>",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"build"
|
||||
],
|
||||
"scripts": {
|
||||
"lint": "yarn g:lint",
|
||||
"prettier": "yarn g:prettier",
|
||||
"test:unit": "yarn g:jest",
|
||||
"build:icons": "npx tsx ./src/scripts/build-icons.ts"
|
||||
"build:icons": "npx tsx ./src/scripts/build-icons.ts",
|
||||
"build:package": "rm -rf build && rollup -c rollup.config.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@appsmith/wds-headless": "workspace:^",
|
||||
|
|
@ -34,12 +39,32 @@
|
|||
"usehooks-ts": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.26.9",
|
||||
"@babel/helper-compilation-targets": "^7.26.5",
|
||||
"@babel/preset-env": "^7.26.9",
|
||||
"@babel/preset-react": "^7.26.3",
|
||||
"@babel/preset-typescript": "^7.26.0",
|
||||
"@babel/runtime": "^7.26.9",
|
||||
"@rollup/plugin-babel": "^6.0.4",
|
||||
"@rollup/plugin-commonjs": "^28.0.2",
|
||||
"@rollup/plugin-image": "^3.0.3",
|
||||
"@rollup/plugin-node-resolve": "^16.0.0",
|
||||
"@rollup/plugin-replace": "^6.0.2",
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"@rollup/plugin-typescript": "^12.1.2",
|
||||
"@rollup/plugin-url": "^8.0.2",
|
||||
"@types/fs-extra": "^11.0.4",
|
||||
"@types/react-syntax-highlighter": "^15.5.13",
|
||||
"@types/react-transition-group": "^4.4.11",
|
||||
"eslint-plugin-storybook": "^0.6.10"
|
||||
"@types/react-transition-group": "^4.4.12",
|
||||
"browserslist": "^4.24.4",
|
||||
"eslint-plugin-storybook": "^0.11.3",
|
||||
"postcss-import": "^16.1.0",
|
||||
"rollup": "^4.34.8",
|
||||
"rollup-plugin-copy": "^3.5.0",
|
||||
"rollup-plugin-postcss": "^4.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
|
||||
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0",
|
||||
"react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
93
app/client/packages/design-system/widgets/rollup.config.js
Normal file
93
app/client/packages/design-system/widgets/rollup.config.js
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import path from "path";
|
||||
import { dirname } from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { defineConfig } from "rollup";
|
||||
|
||||
import postcssNesting from "postcss-nesting";
|
||||
import postcssImport from "postcss-import";
|
||||
import postcssAtRulesVariables from "postcss-at-rules-variables";
|
||||
import postcssEach from "postcss-each";
|
||||
import postcssModulesValues from "postcss-modules-values";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
import json from "@rollup/plugin-json";
|
||||
import resolve from "@rollup/plugin-node-resolve";
|
||||
import commonjs from "@rollup/plugin-commonjs";
|
||||
import typescript from "@rollup/plugin-typescript";
|
||||
import postcss from "rollup-plugin-postcss";
|
||||
import babel from "@rollup/plugin-babel";
|
||||
import replace from "@rollup/plugin-replace";
|
||||
|
||||
const BUILD_DIR = path.resolve(__dirname, "build");
|
||||
|
||||
const EXTERNALS = ["react", "react-dom"];
|
||||
|
||||
export default defineConfig({
|
||||
input: path.resolve(__dirname, "src/index.ts"),
|
||||
output: {
|
||||
file: path.resolve(BUILD_DIR, "bundle.js"),
|
||||
format: "esm",
|
||||
sourcemap: true,
|
||||
inlineDynamicImports: true,
|
||||
globals: {
|
||||
react: "React",
|
||||
"react-dom": "ReactDOM",
|
||||
},
|
||||
},
|
||||
external: EXTERNALS,
|
||||
plugins: [
|
||||
json(),
|
||||
replace({
|
||||
preventAssignment: true,
|
||||
values: {
|
||||
"process.env.NODE_ENV": JSON.stringify("production"),
|
||||
"process.env.REACT_APP_ENV": JSON.stringify("production"),
|
||||
},
|
||||
}),
|
||||
commonjs({
|
||||
include: /node_modules/,
|
||||
transformMixedEsModules: true,
|
||||
requireReturnsDefault: "preferred",
|
||||
esmExternals: true,
|
||||
}),
|
||||
babel({
|
||||
exclude: "node_modules/**",
|
||||
babelHelpers: "bundled",
|
||||
extensions: [".js", ".jsx", ".ts", ".tsx"],
|
||||
presets: [
|
||||
["@babel/preset-react", { runtime: "automatic" }],
|
||||
["@babel/preset-typescript", { isTSX: true, allExtensions: true }],
|
||||
],
|
||||
skipPreflightCheck: true,
|
||||
babelrc: false,
|
||||
configFile: false,
|
||||
}),
|
||||
postcss({
|
||||
modules: true,
|
||||
minimize: true,
|
||||
sourceMap: true,
|
||||
plugins: [
|
||||
postcssNesting(),
|
||||
postcssImport(),
|
||||
postcssAtRulesVariables(),
|
||||
postcssEach(),
|
||||
postcssModulesValues(),
|
||||
],
|
||||
}),
|
||||
typescript({
|
||||
tsconfig: "./tsconfig.json",
|
||||
declaration: true,
|
||||
declarationDir: path.resolve(BUILD_DIR),
|
||||
rootDir: "src",
|
||||
outDir: path.resolve(BUILD_DIR),
|
||||
}),
|
||||
resolve({
|
||||
extensions: [".js", ".jsx", ".ts", ".tsx"],
|
||||
browser: true,
|
||||
preferBuiltins: false,
|
||||
dedupe: EXTERNALS,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import { Hotkey, Hotkeys, HotkeysTarget } from "@blueprintjs/core";
|
||||
import React, { useMemo } from "react";
|
||||
import { useHotkeys, type HotkeyConfig } from "@blueprintjs/core";
|
||||
import type { SearchItem, SelectEvent } from "./utils";
|
||||
|
||||
interface Props {
|
||||
|
|
@ -15,70 +15,64 @@ interface Props {
|
|||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
@HotkeysTarget
|
||||
class GlobalSearchHotKeys extends React.Component<Props> {
|
||||
get hotKeysConfig() {
|
||||
return [
|
||||
{
|
||||
combo: "up",
|
||||
onKeyDown: this.props.handleUpKey,
|
||||
hideWhenModalClosed: true,
|
||||
allowInInput: true,
|
||||
group: "Omnibar",
|
||||
label: "Move up the list",
|
||||
},
|
||||
{
|
||||
combo: "down",
|
||||
onKeyDown: this.props.handleDownKey,
|
||||
hideWhenModalClosed: true,
|
||||
allowInInput: true,
|
||||
group: "Omnibar",
|
||||
label: "Move down the list",
|
||||
},
|
||||
{
|
||||
combo: "return",
|
||||
onKeyDown: (event: KeyboardEvent) => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const activeElement = document.activeElement as any;
|
||||
|
||||
activeElement?.blur(); // scroll into view doesn't work with the search input focused
|
||||
this.props.handleItemLinkClick(event, null, "ENTER_KEY");
|
||||
const GlobalSearchHotKeys: React.FC<Props> = ({
|
||||
children,
|
||||
handleDownKey,
|
||||
handleItemLinkClick,
|
||||
handleUpKey,
|
||||
modalOpen,
|
||||
}) => {
|
||||
const hotkeys: HotkeyConfig[] = useMemo(
|
||||
() =>
|
||||
[
|
||||
{
|
||||
combo: "up",
|
||||
onKeyDown: handleUpKey,
|
||||
hideWhenModalClosed: true,
|
||||
allowInInput: true,
|
||||
group: "Omnibar",
|
||||
label: "Move up the list",
|
||||
global: false,
|
||||
},
|
||||
hideWhenModalClosed: true,
|
||||
allowInInput: true,
|
||||
group: "Omnibar",
|
||||
label: "Navigate",
|
||||
},
|
||||
].filter(
|
||||
({ hideWhenModalClosed }) =>
|
||||
!hideWhenModalClosed || (hideWhenModalClosed && this.props.modalOpen),
|
||||
);
|
||||
}
|
||||
{
|
||||
combo: "down",
|
||||
onKeyDown: handleDownKey,
|
||||
hideWhenModalClosed: true,
|
||||
allowInInput: true,
|
||||
group: "Omnibar",
|
||||
label: "Move down the list",
|
||||
global: false,
|
||||
},
|
||||
{
|
||||
combo: "return",
|
||||
onKeyDown: (event: KeyboardEvent) => {
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const activeElement = document.activeElement as any;
|
||||
|
||||
renderHotkeys() {
|
||||
return (
|
||||
<Hotkeys>
|
||||
{this.hotKeysConfig.map(
|
||||
({ allowInInput, combo, group, label, onKeyDown }, index) => (
|
||||
<Hotkey
|
||||
allowInInput={allowInInput}
|
||||
combo={combo}
|
||||
global={false}
|
||||
group={group}
|
||||
key={index}
|
||||
label={label}
|
||||
onKeyDown={onKeyDown}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</Hotkeys>
|
||||
);
|
||||
}
|
||||
activeElement?.blur(); // scroll into view doesn't work with the search input focused
|
||||
handleItemLinkClick(event, null, "ENTER_KEY");
|
||||
},
|
||||
hideWhenModalClosed: true,
|
||||
allowInInput: true,
|
||||
group: "Omnibar",
|
||||
label: "Navigate",
|
||||
global: false,
|
||||
},
|
||||
].filter(
|
||||
({ hideWhenModalClosed }) =>
|
||||
!hideWhenModalClosed || (hideWhenModalClosed && modalOpen),
|
||||
),
|
||||
[handleUpKey, handleDownKey, handleItemLinkClick, modalOpen],
|
||||
);
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
const { handleKeyDown, handleKeyUp } = useHotkeys(hotkeys);
|
||||
|
||||
return (
|
||||
<div onKeyDown={handleKeyDown} onKeyUp={handleKeyUp}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default GlobalSearchHotKeys;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import { Hotkey, Hotkeys, HotkeysTarget } from "@blueprintjs/core";
|
||||
import { useHotkeys } from "@blueprintjs/core";
|
||||
|
||||
interface Props {
|
||||
handleUpKey: () => void;
|
||||
|
|
@ -9,78 +9,66 @@ interface Props {
|
|||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
@HotkeysTarget
|
||||
class GlobalSearchHotKeys extends React.Component<Props> {
|
||||
get hotKeysConfig() {
|
||||
return [
|
||||
function BranchListHotKeys({
|
||||
children,
|
||||
handleDownKey,
|
||||
handleEscKey,
|
||||
handleSubmitKey,
|
||||
handleUpKey,
|
||||
}: Props) {
|
||||
const hotkeys = React.useMemo(
|
||||
() => [
|
||||
{
|
||||
combo: "up",
|
||||
onKeyDown: () => {
|
||||
this.props.handleUpKey();
|
||||
},
|
||||
global: true,
|
||||
label: "Move up the list",
|
||||
onKeyDown: handleUpKey,
|
||||
allowInInput: true,
|
||||
group: "Branches",
|
||||
label: "Move up the list",
|
||||
},
|
||||
{
|
||||
combo: "down",
|
||||
onKeyDown: this.props.handleDownKey,
|
||||
global: true,
|
||||
label: "Move down the list",
|
||||
onKeyDown: handleDownKey,
|
||||
allowInInput: true,
|
||||
group: "Branches",
|
||||
label: "Move down the list",
|
||||
},
|
||||
{
|
||||
combo: "return",
|
||||
onKeyDown: this.props.handleSubmitKey,
|
||||
global: true,
|
||||
label: "Submit",
|
||||
onKeyDown: handleSubmitKey,
|
||||
allowInInput: true,
|
||||
group: "Branches",
|
||||
label: "Submit",
|
||||
},
|
||||
{
|
||||
combo: "ESC",
|
||||
onKeyDown: this.props.handleEscKey,
|
||||
combo: "esc",
|
||||
global: true,
|
||||
label: "ESC",
|
||||
onKeyDown: handleEscKey,
|
||||
allowInInput: true,
|
||||
group: "Branches",
|
||||
label: "ESC",
|
||||
},
|
||||
];
|
||||
}
|
||||
],
|
||||
[handleUpKey, handleDownKey, handleSubmitKey, handleEscKey],
|
||||
);
|
||||
|
||||
renderHotkeys() {
|
||||
return (
|
||||
<Hotkeys>
|
||||
{this.hotKeysConfig.map(
|
||||
({ allowInInput, combo, group, label, onKeyDown }, index) => (
|
||||
<Hotkey
|
||||
allowInInput={allowInInput}
|
||||
combo={combo}
|
||||
global={false}
|
||||
group={group}
|
||||
key={index}
|
||||
label={label}
|
||||
onKeyDown={onKeyDown}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</Hotkeys>
|
||||
);
|
||||
}
|
||||
useHotkeys(hotkeys);
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flex: 1,
|
||||
flexDirection: "column",
|
||||
minHeight: 0,
|
||||
overflow: "auto",
|
||||
}}
|
||||
>
|
||||
{this.props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flex: 1,
|
||||
flexDirection: "column",
|
||||
minHeight: 0,
|
||||
overflow: "auto",
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default GlobalSearchHotKeys;
|
||||
export default BranchListHotKeys;
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
import { Hotkey } from "@blueprintjs/core";
|
||||
import { GitOpsTab } from "git/constants/enums";
|
||||
import noop from "lodash/noop";
|
||||
import React, { useCallback } from "react";
|
||||
|
||||
interface HotKeysViewProps {
|
||||
toggleOpsModal: (show: boolean, tab?: GitOpsTab.Deploy) => void;
|
||||
}
|
||||
|
||||
function HotKeysView({ toggleOpsModal = noop }: HotKeysViewProps) {
|
||||
const handleCommitModal = useCallback(() => {
|
||||
toggleOpsModal(true, GitOpsTab.Deploy);
|
||||
}, [toggleOpsModal]);
|
||||
|
||||
return (
|
||||
<Hotkey
|
||||
combo="ctrl + shift + g"
|
||||
global
|
||||
label="Show git commit modal"
|
||||
onKeyDown={handleCommitModal}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default HotKeysView;
|
||||
|
|
@ -1,11 +1,8 @@
|
|||
import React from "react";
|
||||
import HotKeysView from "./HotKeysView";
|
||||
import { useHotKeysView } from "./useHotKeysView";
|
||||
import useOps from "git/hooks/useOps";
|
||||
|
||||
function HotKeys() {
|
||||
export function useHotKeys() {
|
||||
const { toggleOpsModal } = useOps();
|
||||
|
||||
return <HotKeysView toggleOpsModal={toggleOpsModal} />;
|
||||
return useHotKeysView({ toggleOpsModal });
|
||||
}
|
||||
|
||||
export default HotKeys;
|
||||
|
|
|
|||
27
app/client/src/git/components/HotKeys/useHotKeysView.ts
Normal file
27
app/client/src/git/components/HotKeys/useHotKeysView.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { GitOpsTab } from "git/constants/enums";
|
||||
import noop from "lodash/noop";
|
||||
import { useCallback, useMemo } from "react";
|
||||
|
||||
interface HotKeysViewProps {
|
||||
toggleOpsModal: (show: boolean, tab?: GitOpsTab.Deploy) => void;
|
||||
}
|
||||
|
||||
export function useHotKeysView({ toggleOpsModal = noop }: HotKeysViewProps) {
|
||||
const handleCommitModal = useCallback(() => {
|
||||
toggleOpsModal(true, GitOpsTab.Deploy);
|
||||
}, [toggleOpsModal]);
|
||||
|
||||
const hotKeys = useMemo(
|
||||
() => [
|
||||
{
|
||||
combo: "ctrl + shift + g",
|
||||
global: true,
|
||||
label: "Show git commit modal",
|
||||
onKeyDown: handleCommitModal,
|
||||
},
|
||||
],
|
||||
[handleCommitModal],
|
||||
);
|
||||
|
||||
return hotKeys;
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
export { GitArtifactType, GitOpsTab } from "./constants/enums";
|
||||
|
||||
// components
|
||||
export { useHotKeys } from "./components/HotKeys";
|
||||
export { default as GitContextProvider } from "./components/GitContextProvider";
|
||||
export { default as GitModals } from "./ee/components/GitModals";
|
||||
export { default as GitImportModal } from "./components/ImportModal";
|
||||
|
|
@ -10,7 +11,6 @@ export { default as GitQuickActions } from "./components/QuickActions";
|
|||
export { default as GitProtectedBranchCallout } from "./components/ProtectedBranchCallout";
|
||||
export { default as GitGlobalProfile } from "./components/GlobalProfile";
|
||||
export { default as GitDeployMenuItems } from "./components/DeployMenuItems";
|
||||
export { default as GitHotKeys } from "./components/HotKeys";
|
||||
export { default as GitCardBadge } from "./components/CardBadge";
|
||||
|
||||
export type { ConnectSuccessPayload as GitConnectSuccessPayload } from "./store/actions/connectActions";
|
||||
|
|
|
|||
|
|
@ -1,20 +1,17 @@
|
|||
import React, { useCallback } from "react";
|
||||
import { connect, useDispatch, useSelector } from "react-redux";
|
||||
import type { AppState } from "ee/reducers";
|
||||
import { Hotkey, Hotkeys, HotkeysTarget } from "@blueprintjs/core";
|
||||
import React, { useCallback, useContext, useMemo } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import {
|
||||
closePropertyPane,
|
||||
closeTableFilterPane,
|
||||
copyWidget,
|
||||
cutWidget,
|
||||
deleteSelectedWidget,
|
||||
deleteSelectedWidget as _deleteSelectedWidget,
|
||||
groupWidgets,
|
||||
pasteWidget,
|
||||
} from "actions/widgetActions";
|
||||
import { selectWidgetInitAction } from "actions/widgetSelectionActions";
|
||||
import { setGlobalSearchCategory } from "actions/globalSearchActions";
|
||||
import { setGlobalSearchCategory as _setGlobalSearchCategory } from "actions/globalSearchActions";
|
||||
import { getSelectedText, isMacOrIOS } from "utils/helpers";
|
||||
import { getLastSelectedWidget, getSelectedWidgets } from "selectors/ui";
|
||||
import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants";
|
||||
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
|
||||
import { WIDGETS_SEARCH_ID } from "constants/Explorer";
|
||||
|
|
@ -28,33 +25,105 @@ import {
|
|||
} from "components/editorComponents/GlobalSearch/utils";
|
||||
import { redoAction, undoAction } from "actions/pageActions";
|
||||
|
||||
import { getAppMode } from "ee/selectors/applicationSelectors";
|
||||
import type { APP_MODE } from "entities/App";
|
||||
|
||||
import {
|
||||
createMessage,
|
||||
SAVE_HOTKEY_TOASTER_MESSAGE,
|
||||
} from "ee/constants/messages";
|
||||
import { previewModeSelector } from "selectors/editorSelectors";
|
||||
import { matchBuilderPath } from "constants/routes";
|
||||
import { toggleInstaller } from "actions/JSLibraryActions";
|
||||
import { SelectionRequestType } from "sagas/WidgetSelectUtils";
|
||||
import { toast } from "@appsmith/ads";
|
||||
import { showDebuggerFlag } from "selectors/debuggerSelectors";
|
||||
import { getIsFirstTimeUserOnboardingEnabled } from "selectors/onboardingSelectors";
|
||||
import WalkthroughContext from "components/featureWalkthrough/walkthroughContext";
|
||||
import { setPreviewModeInitAction } from "actions/editorActions";
|
||||
import { setPreviewModeInitAction as _setPreviewModeInitAction } from "actions/editorActions";
|
||||
import { setIsGitSyncModalOpen } from "actions/gitSyncActions";
|
||||
import { GitSyncModalTab } from "entities/GitSync";
|
||||
import {
|
||||
selectGitApplicationProtectedMode,
|
||||
selectGitModEnabled,
|
||||
selectGitApplicationProtectedMode,
|
||||
} from "selectors/gitModSelectors";
|
||||
import { GitHotKeys as GitHotKeysNew } from "git";
|
||||
import { useHotkeys } from "@blueprintjs/core";
|
||||
import { useHotKeys as useGitHotKeys } from "git";
|
||||
import { getSelectedWidgets, getLastSelectedWidget } from "selectors/ui";
|
||||
import { previewModeSelector } from "selectors/editorSelectors";
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode;
|
||||
getMousePosition: () => { x: number; y: number };
|
||||
toggleDebugger: () => void;
|
||||
}
|
||||
|
||||
function GlobalHotKeys(props: Props) {
|
||||
const { children, getMousePosition, toggleDebugger } = props;
|
||||
|
||||
function GitHotKeys() {
|
||||
const isGitModEnabled = useSelector(selectGitModEnabled);
|
||||
const dispatch = useDispatch();
|
||||
const isGitModEnabled = useSelector(selectGitModEnabled);
|
||||
const isWalkthroughOpened = useContext(WalkthroughContext)?.isOpened;
|
||||
const gitHotKeys = useGitHotKeys();
|
||||
|
||||
const selectedWidget = useSelector(getLastSelectedWidget);
|
||||
const selectedWidgets = useSelector(getSelectedWidgets);
|
||||
const isPreviewMode = useSelector(previewModeSelector);
|
||||
const isProtectedMode = useSelector(selectGitApplicationProtectedMode);
|
||||
|
||||
const copySelectedWidget = useCallback(
|
||||
() => dispatch(copyWidget(true)),
|
||||
[dispatch],
|
||||
);
|
||||
const pasteCopiedWidget = useCallback(
|
||||
(mouseLocation: { x: number; y: number }) =>
|
||||
dispatch(pasteWidget({ groupWidgets: false, mouseLocation })),
|
||||
[dispatch],
|
||||
);
|
||||
const deleteSelectedWidget = useCallback(
|
||||
() => dispatch(_deleteSelectedWidget(true)),
|
||||
[dispatch],
|
||||
);
|
||||
const cutSelectedWidget = useCallback(
|
||||
() => dispatch(cutWidget()),
|
||||
[dispatch],
|
||||
);
|
||||
const groupSelectedWidget = useCallback(
|
||||
() => dispatch(groupWidgets()),
|
||||
[dispatch],
|
||||
);
|
||||
const setGlobalSearchCategory = useCallback(
|
||||
(category: SearchCategory) => dispatch(_setGlobalSearchCategory(category)),
|
||||
[dispatch],
|
||||
);
|
||||
const resetSnipingMode = useCallback(
|
||||
() => dispatch(resetSnipingModeAction()),
|
||||
[dispatch],
|
||||
);
|
||||
const closeProppane = useCallback(
|
||||
() => dispatch(closePropertyPane()),
|
||||
[dispatch],
|
||||
);
|
||||
const closeTableFilterProppane = useCallback(
|
||||
() => dispatch(closeTableFilterPane()),
|
||||
[dispatch],
|
||||
);
|
||||
const selectAllWidgetsInit = useCallback(
|
||||
() => dispatch(selectWidgetInitAction(SelectionRequestType.All)),
|
||||
[dispatch],
|
||||
);
|
||||
const deselectAllWidgets = useCallback(
|
||||
() => dispatch(selectWidgetInitAction(SelectionRequestType.Empty)),
|
||||
[dispatch],
|
||||
);
|
||||
const executeAction = useCallback(
|
||||
() => dispatch(runActionViaShortcut()),
|
||||
[dispatch],
|
||||
);
|
||||
const undo = useCallback(() => dispatch(undoAction()), [dispatch]);
|
||||
const redo = useCallback(() => dispatch(redoAction()), [dispatch]);
|
||||
const hideInstaller = useCallback(
|
||||
() => dispatch(toggleInstaller(false)),
|
||||
[dispatch],
|
||||
);
|
||||
const setPreviewModeInitAction = useCallback(
|
||||
(shouldSet: boolean) => dispatch(_setPreviewModeInitAction(shouldSet)),
|
||||
[dispatch],
|
||||
);
|
||||
|
||||
const showCommitModal = useCallback(() => {
|
||||
dispatch(
|
||||
|
|
@ -65,104 +134,58 @@ function GitHotKeys() {
|
|||
);
|
||||
}, [dispatch]);
|
||||
|
||||
return isGitModEnabled ? (
|
||||
<GitHotKeysNew />
|
||||
) : (
|
||||
<Hotkey
|
||||
combo="ctrl + shift + g"
|
||||
global
|
||||
label="Show git commit modal"
|
||||
onKeyDown={showCommitModal}
|
||||
/>
|
||||
const stopPropagationIfWidgetSelected = useCallback(
|
||||
(e: KeyboardEvent): boolean => {
|
||||
const multipleWidgetsSelected = selectedWidgets && selectedWidgets.length;
|
||||
const singleWidgetSelected =
|
||||
selectedWidget && selectedWidget != MAIN_CONTAINER_WIDGET_ID;
|
||||
|
||||
if (
|
||||
(singleWidgetSelected || multipleWidgetsSelected) &&
|
||||
!getSelectedText()
|
||||
) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
[selectedWidgets, selectedWidget],
|
||||
);
|
||||
}
|
||||
|
||||
interface Props {
|
||||
copySelectedWidget: () => void;
|
||||
pasteCopiedWidget: (mouseLocation: { x: number; y: number }) => void;
|
||||
deleteSelectedWidget: () => void;
|
||||
cutSelectedWidget: () => void;
|
||||
groupSelectedWidget: () => void;
|
||||
setGlobalSearchCategory: (category: SearchCategory) => void;
|
||||
resetSnipingMode: () => void;
|
||||
closeProppane: () => void;
|
||||
closeTableFilterProppane: () => void;
|
||||
executeAction: () => void;
|
||||
selectAllWidgetsInit: () => void;
|
||||
deselectAllWidgets: () => void;
|
||||
selectedWidget?: string;
|
||||
selectedWidgets: string[];
|
||||
isDebuggerOpen: boolean;
|
||||
children: React.ReactNode;
|
||||
undo: () => void;
|
||||
redo: () => void;
|
||||
appMode?: APP_MODE;
|
||||
isPreviewMode: boolean;
|
||||
isProtectedMode: boolean;
|
||||
setPreviewModeInitAction: (shouldSet: boolean) => void;
|
||||
isSignpostingEnabled: boolean;
|
||||
getMousePosition: () => { x: number; y: number };
|
||||
hideInstaller: () => void;
|
||||
toggleDebugger: () => void;
|
||||
}
|
||||
|
||||
@HotkeysTarget
|
||||
class GlobalHotKeys extends React.Component<Props> {
|
||||
public stopPropagationIfWidgetSelected(e: KeyboardEvent): boolean {
|
||||
const multipleWidgetsSelected =
|
||||
this.props.selectedWidgets && this.props.selectedWidgets.length;
|
||||
const singleWidgetSelected =
|
||||
this.props.selectedWidget &&
|
||||
this.props.selectedWidget != MAIN_CONTAINER_WIDGET_ID;
|
||||
|
||||
if (
|
||||
(singleWidgetSelected || multipleWidgetsSelected) &&
|
||||
!getSelectedText()
|
||||
) {
|
||||
const onOnmnibarHotKeyDown = useCallback(
|
||||
(
|
||||
e: KeyboardEvent,
|
||||
categoryId: SEARCH_CATEGORY_ID = SEARCH_CATEGORY_ID.NAVIGATION,
|
||||
) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
return true;
|
||||
}
|
||||
if (isPreviewMode) return;
|
||||
|
||||
return false;
|
||||
}
|
||||
const category = filterCategories[categoryId];
|
||||
|
||||
public onOnmnibarHotKeyDown(
|
||||
e: KeyboardEvent,
|
||||
categoryId: SEARCH_CATEGORY_ID = SEARCH_CATEGORY_ID.NAVIGATION,
|
||||
) {
|
||||
e.preventDefault();
|
||||
setGlobalSearchCategory(category);
|
||||
hideInstaller();
|
||||
AnalyticsUtil.logEvent("OPEN_OMNIBAR", {
|
||||
source: "HOTKEY_COMBO",
|
||||
category: category.title,
|
||||
});
|
||||
},
|
||||
[isPreviewMode, setGlobalSearchCategory, hideInstaller, AnalyticsUtil],
|
||||
);
|
||||
|
||||
// don't open omnibar if preview mode is on
|
||||
if (this.props.isPreviewMode) return;
|
||||
|
||||
const category = filterCategories[categoryId];
|
||||
|
||||
this.props.setGlobalSearchCategory(category);
|
||||
this.props.hideInstaller();
|
||||
AnalyticsUtil.logEvent("OPEN_OMNIBAR", {
|
||||
source: "HOTKEY_COMBO",
|
||||
category: category.title,
|
||||
});
|
||||
}
|
||||
|
||||
public renderHotkeys() {
|
||||
const { isOpened: isWalkthroughOpened } = this.context ?? {};
|
||||
const { isProtectedMode } = this.props;
|
||||
|
||||
// If walkthrough is open disable shortcuts
|
||||
if (isWalkthroughOpened || isProtectedMode) return <Hotkeys />;
|
||||
|
||||
return (
|
||||
<Hotkeys>
|
||||
<Hotkey
|
||||
combo="mod + f"
|
||||
global
|
||||
label="Search entities"
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onKeyDown={(e: any) => {
|
||||
const hotkeys = useMemo(() => {
|
||||
if (isWalkthroughOpened || isProtectedMode) {
|
||||
return [];
|
||||
} else {
|
||||
return [
|
||||
{
|
||||
combo: "mod + f",
|
||||
global: true,
|
||||
label: "Search entities",
|
||||
onKeyDown: (e: KeyboardEvent) => {
|
||||
const widgetSearchInput =
|
||||
document.getElementById(WIDGETS_SEARCH_ID);
|
||||
|
||||
|
|
@ -171,273 +194,239 @@ class GlobalHotKeys extends React.Component<Props> {
|
|||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Hotkey
|
||||
allowInInput
|
||||
combo="mod + p"
|
||||
global
|
||||
label="Navigate"
|
||||
onKeyDown={(e) => this.onOnmnibarHotKeyDown(e)}
|
||||
/>
|
||||
<Hotkey
|
||||
allowInInput
|
||||
combo="mod + plus"
|
||||
global
|
||||
label="Create new"
|
||||
onKeyDown={(e) =>
|
||||
this.onOnmnibarHotKeyDown(e, SEARCH_CATEGORY_ID.ACTION_OPERATION)
|
||||
}
|
||||
/>
|
||||
<Hotkey
|
||||
allowInInput
|
||||
combo="mod + k"
|
||||
global
|
||||
label="Show omnibar"
|
||||
onKeyDown={(e) =>
|
||||
this.onOnmnibarHotKeyDown(e, SEARCH_CATEGORY_ID.INIT)
|
||||
}
|
||||
/>
|
||||
<Hotkey
|
||||
allowInInput
|
||||
combo="mod + d"
|
||||
global
|
||||
group="Canvas"
|
||||
label="Open Debugger"
|
||||
onKeyDown={this.props.toggleDebugger}
|
||||
preventDefault
|
||||
/>
|
||||
<Hotkey
|
||||
combo="mod + c"
|
||||
global
|
||||
group="Canvas"
|
||||
label="Copy widget"
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onKeyDown={(e: any) => {
|
||||
if (this.stopPropagationIfWidgetSelected(e)) {
|
||||
this.props.copySelectedWidget();
|
||||
},
|
||||
},
|
||||
{
|
||||
allowInInput: true,
|
||||
combo: "mod + p",
|
||||
global: true,
|
||||
label: "Navigate",
|
||||
onKeyDown: (e: KeyboardEvent) => onOnmnibarHotKeyDown(e),
|
||||
},
|
||||
{
|
||||
allowInInput: true,
|
||||
combo: "mod + plus",
|
||||
global: true,
|
||||
label: "Create new",
|
||||
onKeyDown: (e: KeyboardEvent) =>
|
||||
onOnmnibarHotKeyDown(e, SEARCH_CATEGORY_ID.ACTION_OPERATION),
|
||||
},
|
||||
{
|
||||
allowInInput: true,
|
||||
combo: "mod + k",
|
||||
global: true,
|
||||
label: "Show omnibar",
|
||||
onKeyDown: (e: KeyboardEvent) =>
|
||||
onOnmnibarHotKeyDown(e, SEARCH_CATEGORY_ID.INIT),
|
||||
},
|
||||
{
|
||||
allowInInput: true,
|
||||
combo: "mod + d",
|
||||
global: true,
|
||||
group: "Canvas",
|
||||
label: "Open Debugger",
|
||||
onKeyDown: toggleDebugger,
|
||||
preventDefault: true,
|
||||
},
|
||||
{
|
||||
combo: "mod + c",
|
||||
global: true,
|
||||
group: "Canvas",
|
||||
label: "Copy widget",
|
||||
onKeyDown: (e: KeyboardEvent) => {
|
||||
if (stopPropagationIfWidgetSelected(e)) {
|
||||
copySelectedWidget();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Hotkey
|
||||
combo="mod + v"
|
||||
global
|
||||
group="Canvas"
|
||||
label="Paste Widget"
|
||||
onKeyDown={() => {
|
||||
},
|
||||
},
|
||||
{
|
||||
combo: "mod + v",
|
||||
global: true,
|
||||
group: "Canvas",
|
||||
label: "Paste Widget",
|
||||
onKeyDown: () => {
|
||||
if (matchBuilderPath(window.location.pathname)) {
|
||||
this.props.pasteCopiedWidget(
|
||||
this.props.getMousePosition() || { x: 0, y: 0 },
|
||||
);
|
||||
pasteCopiedWidget(getMousePosition() || { x: 0, y: 0 });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Hotkey
|
||||
combo="backspace"
|
||||
global
|
||||
group="Canvas"
|
||||
label="Delete widget"
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onKeyDown={(e: any) => {
|
||||
if (this.stopPropagationIfWidgetSelected(e) && isMacOrIOS()) {
|
||||
this.props.deleteSelectedWidget();
|
||||
},
|
||||
},
|
||||
{
|
||||
combo: "backspace",
|
||||
global: true,
|
||||
group: "Canvas",
|
||||
label: "Delete widget",
|
||||
onKeyDown: (e: KeyboardEvent) => {
|
||||
if (stopPropagationIfWidgetSelected(e) && isMacOrIOS()) {
|
||||
deleteSelectedWidget();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Hotkey
|
||||
combo="del"
|
||||
global
|
||||
group="Canvas"
|
||||
label="Delete widget"
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onKeyDown={(e: any) => {
|
||||
if (this.stopPropagationIfWidgetSelected(e)) {
|
||||
this.props.deleteSelectedWidget();
|
||||
},
|
||||
},
|
||||
{
|
||||
combo: "del",
|
||||
global: true,
|
||||
group: "Canvas",
|
||||
label: "Delete widget",
|
||||
onKeyDown: (e: KeyboardEvent) => {
|
||||
if (stopPropagationIfWidgetSelected(e)) {
|
||||
deleteSelectedWidget();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Hotkey
|
||||
combo="mod + x"
|
||||
global
|
||||
group="Canvas"
|
||||
label="Cut Widget"
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onKeyDown={(e: any) => {
|
||||
if (this.stopPropagationIfWidgetSelected(e)) {
|
||||
this.props.cutSelectedWidget();
|
||||
},
|
||||
},
|
||||
{
|
||||
combo: "mod + x",
|
||||
global: true,
|
||||
group: "Canvas",
|
||||
label: "Cut Widget",
|
||||
onKeyDown: (e: KeyboardEvent) => {
|
||||
if (stopPropagationIfWidgetSelected(e)) {
|
||||
cutSelectedWidget();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<Hotkey
|
||||
combo="mod + a"
|
||||
global
|
||||
group="Canvas"
|
||||
label="Select all Widget"
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onKeyDown={(e: any) => {
|
||||
},
|
||||
},
|
||||
{
|
||||
combo: "mod + a",
|
||||
global: true,
|
||||
group: "Canvas",
|
||||
label: "Select all Widget",
|
||||
onKeyDown: (e: KeyboardEvent) => {
|
||||
if (matchBuilderPath(window.location.pathname)) {
|
||||
this.props.selectAllWidgetsInit();
|
||||
selectAllWidgetsInit();
|
||||
e.preventDefault();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Hotkey
|
||||
combo="esc"
|
||||
global
|
||||
group="Canvas"
|
||||
label="Deselect all Widget"
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onKeyDown={(e: any) => {
|
||||
this.props.resetSnipingMode();
|
||||
},
|
||||
},
|
||||
{
|
||||
combo: "esc",
|
||||
global: true,
|
||||
group: "Canvas",
|
||||
label: "Deselect all Widget",
|
||||
onKeyDown: (e: KeyboardEvent) => {
|
||||
resetSnipingMode();
|
||||
|
||||
if (matchBuilderPath(window.location.pathname)) {
|
||||
this.props.deselectAllWidgets();
|
||||
this.props.closeProppane();
|
||||
this.props.closeTableFilterProppane();
|
||||
deselectAllWidgets();
|
||||
closeProppane();
|
||||
closeTableFilterProppane();
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
}}
|
||||
/>
|
||||
<Hotkey
|
||||
combo="v"
|
||||
global
|
||||
label="Edit Mode"
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onKeyDown={(e: any) => {
|
||||
this.props.resetSnipingMode();
|
||||
},
|
||||
},
|
||||
{
|
||||
combo: "v",
|
||||
global: true,
|
||||
label: "Edit Mode",
|
||||
onKeyDown: (e: KeyboardEvent) => {
|
||||
resetSnipingMode();
|
||||
e.preventDefault();
|
||||
}}
|
||||
/>
|
||||
<Hotkey
|
||||
allowInInput
|
||||
combo="mod + enter"
|
||||
global
|
||||
label="Execute Action"
|
||||
onKeyDown={this.props.executeAction}
|
||||
preventDefault
|
||||
stopPropagation
|
||||
/>
|
||||
<Hotkey
|
||||
combo="mod + z"
|
||||
global
|
||||
label="Undo change in canvas"
|
||||
onKeyDown={this.props.undo}
|
||||
preventDefault
|
||||
stopPropagation
|
||||
/>
|
||||
<Hotkey
|
||||
combo="mod + shift + z"
|
||||
global
|
||||
label="Redo change in canvas"
|
||||
onKeyDown={this.props.redo}
|
||||
preventDefault
|
||||
stopPropagation
|
||||
/>
|
||||
<Hotkey
|
||||
combo="mod + y"
|
||||
global
|
||||
label="Redo change in canvas"
|
||||
onKeyDown={this.props.redo}
|
||||
preventDefault
|
||||
stopPropagation
|
||||
/>
|
||||
<Hotkey
|
||||
combo="mod + g"
|
||||
global
|
||||
group="Canvas"
|
||||
label="Cut Widgets for grouping"
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
onKeyDown={(e: any) => {
|
||||
if (this.stopPropagationIfWidgetSelected(e)) {
|
||||
this.props.groupSelectedWidget();
|
||||
},
|
||||
},
|
||||
{
|
||||
allowInInput: true,
|
||||
combo: "mod + enter",
|
||||
global: true,
|
||||
label: "Execute Action",
|
||||
onKeyDown: executeAction,
|
||||
preventDefault: true,
|
||||
stopPropagation: true,
|
||||
},
|
||||
{
|
||||
combo: "mod + z",
|
||||
global: true,
|
||||
label: "Undo change in canvas",
|
||||
onKeyDown: undo,
|
||||
preventDefault: true,
|
||||
stopPropagation: true,
|
||||
},
|
||||
{
|
||||
combo: "mod + shift + z",
|
||||
global: true,
|
||||
label: "Redo change in canvas",
|
||||
onKeyDown: redo,
|
||||
preventDefault: true,
|
||||
stopPropagation: true,
|
||||
},
|
||||
{
|
||||
combo: "mod + y",
|
||||
global: true,
|
||||
label: "Redo change in canvas",
|
||||
onKeyDown: redo,
|
||||
preventDefault: true,
|
||||
stopPropagation: true,
|
||||
},
|
||||
{
|
||||
combo: "mod + g",
|
||||
global: true,
|
||||
group: "Canvas",
|
||||
label: "Cut Widgets for grouping",
|
||||
onKeyDown: (e: KeyboardEvent) => {
|
||||
if (stopPropagationIfWidgetSelected(e)) {
|
||||
groupSelectedWidget();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Hotkey
|
||||
combo="mod + s"
|
||||
global
|
||||
label="Save progress"
|
||||
onKeyDown={() => {
|
||||
},
|
||||
},
|
||||
{
|
||||
combo: "mod + s",
|
||||
global: true,
|
||||
label: "Save progress",
|
||||
onKeyDown: () => {
|
||||
toast.show(createMessage(SAVE_HOTKEY_TOASTER_MESSAGE), {
|
||||
kind: "info",
|
||||
});
|
||||
}}
|
||||
preventDefault
|
||||
stopPropagation
|
||||
/>
|
||||
<Hotkey
|
||||
combo="alt + p"
|
||||
global
|
||||
label="Preview Mode"
|
||||
onKeyDown={() => {
|
||||
this.props.setPreviewModeInitAction(!this.props.isPreviewMode);
|
||||
}}
|
||||
/>
|
||||
<GitHotKeys />
|
||||
</Hotkeys>
|
||||
);
|
||||
}
|
||||
},
|
||||
preventDefault: true,
|
||||
stopPropagation: true,
|
||||
},
|
||||
{
|
||||
combo: "alt + p",
|
||||
global: true,
|
||||
label: "Preview Mode",
|
||||
onKeyDown: () => {
|
||||
setPreviewModeInitAction(!isPreviewMode);
|
||||
},
|
||||
},
|
||||
...(isGitModEnabled
|
||||
? gitHotKeys
|
||||
: [
|
||||
{
|
||||
combo: "ctrl + shift + g",
|
||||
global: true,
|
||||
label: "Show git commit modal",
|
||||
onKeyDown: showCommitModal,
|
||||
},
|
||||
]),
|
||||
];
|
||||
}
|
||||
}, [
|
||||
isWalkthroughOpened,
|
||||
isProtectedMode,
|
||||
isGitModEnabled,
|
||||
gitHotKeys,
|
||||
showCommitModal,
|
||||
isPreviewMode,
|
||||
getMousePosition,
|
||||
toggleDebugger,
|
||||
copySelectedWidget,
|
||||
pasteCopiedWidget,
|
||||
deleteSelectedWidget,
|
||||
cutSelectedWidget,
|
||||
selectAllWidgetsInit,
|
||||
deselectAllWidgets,
|
||||
closeProppane,
|
||||
closeTableFilterProppane,
|
||||
resetSnipingMode,
|
||||
executeAction,
|
||||
undo,
|
||||
redo,
|
||||
groupSelectedWidget,
|
||||
setPreviewModeInitAction,
|
||||
onOnmnibarHotKeyDown,
|
||||
stopPropagationIfWidgetSelected,
|
||||
]);
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
useHotkeys(hotkeys, { showDialogKeyCombo: "?" });
|
||||
|
||||
return <div>{children}</div>;
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: AppState) => {
|
||||
return {
|
||||
selectedWidget: getLastSelectedWidget(state),
|
||||
selectedWidgets: getSelectedWidgets(state),
|
||||
isDebuggerOpen: showDebuggerFlag(state),
|
||||
appMode: getAppMode(state),
|
||||
isPreviewMode: previewModeSelector(state),
|
||||
isProtectedMode: selectGitApplicationProtectedMode(state),
|
||||
isSignpostingEnabled: getIsFirstTimeUserOnboardingEnabled(state),
|
||||
};
|
||||
};
|
||||
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const mapDispatchToProps = (dispatch: any) => {
|
||||
return {
|
||||
copySelectedWidget: () => dispatch(copyWidget(true)),
|
||||
pasteCopiedWidget: (mouseLocation: { x: number; y: number }) =>
|
||||
dispatch(
|
||||
pasteWidget({
|
||||
groupWidgets: false,
|
||||
mouseLocation,
|
||||
}),
|
||||
),
|
||||
deleteSelectedWidget: () => dispatch(deleteSelectedWidget(true)),
|
||||
cutSelectedWidget: () => dispatch(cutWidget()),
|
||||
groupSelectedWidget: () => dispatch(groupWidgets()),
|
||||
setGlobalSearchCategory: (category: SearchCategory) =>
|
||||
dispatch(setGlobalSearchCategory(category)),
|
||||
resetSnipingMode: () => dispatch(resetSnipingModeAction()),
|
||||
closeProppane: () => dispatch(closePropertyPane()),
|
||||
closeTableFilterProppane: () => dispatch(closeTableFilterPane()),
|
||||
selectAllWidgetsInit: () =>
|
||||
dispatch(selectWidgetInitAction(SelectionRequestType.All)),
|
||||
deselectAllWidgets: () =>
|
||||
dispatch(selectWidgetInitAction(SelectionRequestType.Empty)),
|
||||
executeAction: () => dispatch(runActionViaShortcut()),
|
||||
undo: () => dispatch(undoAction()),
|
||||
redo: () => dispatch(redoAction()),
|
||||
hideInstaller: () => dispatch(toggleInstaller(false)),
|
||||
setPreviewModeInitAction: (shouldSet: boolean) =>
|
||||
dispatch(setPreviewModeInitAction(shouldSet)),
|
||||
};
|
||||
};
|
||||
|
||||
GlobalHotKeys.contextType = WalkthroughContext;
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(GlobalHotKeys);
|
||||
export default GlobalHotKeys;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import GlobalHotKeys from "./GlobalHotKeys";
|
|||
import React from "react";
|
||||
import { useMouseLocation } from "./useMouseLocation";
|
||||
import useDebuggerTriggerClick from "components/editorComponents/Debugger/hooks/useDebuggerTriggerClick";
|
||||
import { HotkeysProvider } from "@blueprintjs/core";
|
||||
|
||||
//HOC to track user's mouse location, separated out so that it doesn't render the component on every mouse move
|
||||
// TODO: Fix this the next time the file is edited
|
||||
|
|
@ -11,13 +12,15 @@ function HotKeysHOC(props: any) {
|
|||
const toggleDebugger = useDebuggerTriggerClick();
|
||||
|
||||
return (
|
||||
<GlobalHotKeys
|
||||
{...props}
|
||||
getMousePosition={getMousePosition}
|
||||
toggleDebugger={toggleDebugger}
|
||||
>
|
||||
{props.children}
|
||||
</GlobalHotKeys>
|
||||
<HotkeysProvider>
|
||||
<GlobalHotKeys
|
||||
{...props}
|
||||
getMousePosition={getMousePosition}
|
||||
toggleDebugger={toggleDebugger}
|
||||
>
|
||||
{props.children}
|
||||
</GlobalHotKeys>
|
||||
</HotkeysProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import { Hotkey, Hotkeys, HotkeysTarget } from "@blueprintjs/core";
|
||||
import React, { useMemo } from "react";
|
||||
import { useHotkeys } from "@blueprintjs/core";
|
||||
import { JS_OBJECT_HOTKEYS_CLASSNAME } from "./constants";
|
||||
|
||||
interface Props {
|
||||
|
|
@ -7,31 +7,23 @@ interface Props {
|
|||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
@HotkeysTarget
|
||||
class JSObjectHotKeys extends React.Component<Props> {
|
||||
public renderHotkeys() {
|
||||
return (
|
||||
<Hotkeys>
|
||||
<Hotkey
|
||||
allowInInput
|
||||
combo="mod + enter"
|
||||
global
|
||||
label="Run Js Function"
|
||||
onKeyDown={this.props.runActiveJSFunction}
|
||||
/>
|
||||
</Hotkeys>
|
||||
);
|
||||
}
|
||||
function JSObjectHotKeys({ children, runActiveJSFunction }: Props) {
|
||||
const hotkeys = useMemo(
|
||||
() => [
|
||||
{
|
||||
combo: "mod + enter",
|
||||
global: true,
|
||||
label: "Run Js Function",
|
||||
onKeyDown: runActiveJSFunction,
|
||||
allowInInput: true,
|
||||
},
|
||||
],
|
||||
[runActiveJSFunction],
|
||||
);
|
||||
|
||||
render() {
|
||||
/*
|
||||
Blueprint's v3 decorated component must return a single DOM element in its render() method, not a custom React component.
|
||||
This constraint allows HotkeysTarget to inject event handlers without creating an extra wrapper element.
|
||||
*/
|
||||
return (
|
||||
<div className={JS_OBJECT_HOTKEYS_CLASSNAME}>{this.props.children}</div>
|
||||
);
|
||||
}
|
||||
useHotkeys(hotkeys);
|
||||
|
||||
return <div className={JS_OBJECT_HOTKEYS_CLASSNAME}>{children}</div>;
|
||||
}
|
||||
|
||||
export default JSObjectHotKeys;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import { Hotkey, Hotkeys, HotkeysTarget } from "@blueprintjs/core";
|
||||
import React, { useMemo } from "react";
|
||||
import { useHotkeys } from "@blueprintjs/core";
|
||||
|
||||
interface Props {
|
||||
handleUpKey: () => void;
|
||||
|
|
@ -9,78 +9,66 @@ interface Props {
|
|||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
@HotkeysTarget
|
||||
class GlobalSearchHotKeys extends React.Component<Props> {
|
||||
get hotKeysConfig() {
|
||||
return [
|
||||
function BranchListHotkeys({
|
||||
children,
|
||||
handleDownKey,
|
||||
handleEscKey,
|
||||
handleSubmitKey,
|
||||
handleUpKey,
|
||||
}: Props) {
|
||||
const hotkeys = useMemo(
|
||||
() => [
|
||||
{
|
||||
combo: "up",
|
||||
onKeyDown: () => {
|
||||
this.props.handleUpKey();
|
||||
},
|
||||
global: false,
|
||||
label: "Move up the list",
|
||||
onKeyDown: handleUpKey,
|
||||
allowInInput: true,
|
||||
group: "Branches",
|
||||
label: "Move up the list",
|
||||
},
|
||||
{
|
||||
combo: "down",
|
||||
onKeyDown: this.props.handleDownKey,
|
||||
global: false,
|
||||
label: "Move down the list",
|
||||
onKeyDown: handleDownKey,
|
||||
allowInInput: true,
|
||||
group: "Branches",
|
||||
label: "Move down the list",
|
||||
},
|
||||
{
|
||||
combo: "return",
|
||||
onKeyDown: this.props.handleSubmitKey,
|
||||
global: false,
|
||||
label: "Submit",
|
||||
onKeyDown: handleSubmitKey,
|
||||
allowInInput: true,
|
||||
group: "Branches",
|
||||
label: "Submit",
|
||||
},
|
||||
{
|
||||
combo: "ESC",
|
||||
onKeyDown: this.props.handleEscKey,
|
||||
global: false,
|
||||
label: "ESC",
|
||||
onKeyDown: handleEscKey,
|
||||
allowInInput: true,
|
||||
group: "Branches",
|
||||
label: "ESC",
|
||||
},
|
||||
];
|
||||
}
|
||||
],
|
||||
[handleUpKey, handleDownKey, handleSubmitKey, handleEscKey],
|
||||
);
|
||||
|
||||
renderHotkeys() {
|
||||
return (
|
||||
<Hotkeys>
|
||||
{this.hotKeysConfig.map(
|
||||
({ allowInInput, combo, group, label, onKeyDown }, index) => (
|
||||
<Hotkey
|
||||
allowInInput={allowInInput}
|
||||
combo={combo}
|
||||
global={false}
|
||||
group={group}
|
||||
key={index}
|
||||
label={label}
|
||||
onKeyDown={onKeyDown}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
</Hotkeys>
|
||||
);
|
||||
}
|
||||
useHotkeys(hotkeys);
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flex: 1,
|
||||
flexDirection: "column",
|
||||
minHeight: 0,
|
||||
overflow: "auto",
|
||||
}}
|
||||
>
|
||||
{this.props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flex: 1,
|
||||
flexDirection: "column",
|
||||
minHeight: 0,
|
||||
overflow: "auto",
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default GlobalSearchHotKeys;
|
||||
export default BranchListHotkeys;
|
||||
|
|
|
|||
2456
app/client/yarn.lock
2456
app/client/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user