2021-03-08 08:24:12 +00:00
|
|
|
import React from "react";
|
|
|
|
|
import { connect } from "react-redux";
|
|
|
|
|
import { AppState } from "reducers";
|
|
|
|
|
import { Hotkey, Hotkeys } from "@blueprintjs/core";
|
|
|
|
|
import { HotkeysTarget } from "@blueprintjs/core/lib/esnext/components/hotkeys/hotkeysTarget.js";
|
|
|
|
|
import {
|
2021-05-18 18:29:39 +00:00
|
|
|
closePropertyPane,
|
2021-07-20 05:18:58 +00:00
|
|
|
closeTableFilterPane,
|
2021-03-08 08:24:12 +00:00
|
|
|
copyWidget,
|
|
|
|
|
cutWidget,
|
|
|
|
|
deleteSelectedWidget,
|
2021-08-25 05:00:31 +00:00
|
|
|
groupWidgets,
|
2021-03-08 08:24:12 +00:00
|
|
|
pasteWidget,
|
|
|
|
|
} from "actions/widgetActions";
|
2021-06-17 13:26:54 +00:00
|
|
|
import {
|
2021-08-16 09:24:42 +00:00
|
|
|
deselectAllInitAction,
|
2021-06-28 07:11:47 +00:00
|
|
|
selectAllWidgetsInCanvasInitAction,
|
2021-06-17 13:26:54 +00:00
|
|
|
} from "actions/widgetSelectionActions";
|
2021-08-29 03:50:16 +00:00
|
|
|
import { toggleShowGlobalSearchModal } from "actions/globalSearchActions";
|
2021-03-08 08:24:12 +00:00
|
|
|
import { isMac } from "utils/helpers";
|
2021-05-18 18:29:39 +00:00
|
|
|
import { getSelectedWidget, getSelectedWidgets } from "selectors/ui";
|
2021-03-08 08:24:12 +00:00
|
|
|
import { MAIN_CONTAINER_WIDGET_ID } from "constants/WidgetConstants";
|
|
|
|
|
import { getSelectedText } from "utils/helpers";
|
|
|
|
|
import AnalyticsUtil from "utils/AnalyticsUtil";
|
2021-06-09 12:20:15 +00:00
|
|
|
import { WIDGETS_SEARCH_ID } from "constants/Explorer";
|
2021-07-26 16:44:10 +00:00
|
|
|
import { resetSnipingMode as resetSnipingModeAction } from "actions/propertyPaneActions";
|
2021-04-23 13:50:55 +00:00
|
|
|
import { showDebugger } from "actions/debuggerActions";
|
2021-03-08 08:24:12 +00:00
|
|
|
|
2021-05-20 12:03:08 +00:00
|
|
|
import { setCommentModeInUrl } from "pages/Editor/ToggleModeButton";
|
2021-08-27 09:25:28 +00:00
|
|
|
import { runActionViaShortcut } from "actions/pluginActionActions";
|
2021-08-11 06:48:57 +00:00
|
|
|
import {
|
|
|
|
|
filterCategories,
|
|
|
|
|
SearchCategory,
|
|
|
|
|
SEARCH_CATEGORY_ID,
|
|
|
|
|
} from "components/editorComponents/GlobalSearch/utils";
|
2021-09-02 08:37:27 +00:00
|
|
|
import { Toaster } from "components/ads/Toast";
|
|
|
|
|
import { Variant } from "components/ads/common";
|
2021-05-20 12:03:08 +00:00
|
|
|
|
2021-08-23 09:25:16 +00:00
|
|
|
import { getAppMode } from "selectors/applicationSelectors";
|
|
|
|
|
import { APP_MODE } from "entities/App";
|
|
|
|
|
|
|
|
|
|
import { commentModeSelector } from "selectors/commentsSelectors";
|
|
|
|
|
import getFeatureFlags from "utils/featureFlags";
|
2021-09-02 08:37:27 +00:00
|
|
|
import { createMessage, SAVE_HOTKEY_TOASTER_MESSAGE } from "constants/messages";
|
2021-08-23 09:25:16 +00:00
|
|
|
|
2021-03-08 08:24:12 +00:00
|
|
|
type Props = {
|
|
|
|
|
copySelectedWidget: () => void;
|
|
|
|
|
pasteCopiedWidget: () => void;
|
|
|
|
|
deleteSelectedWidget: () => void;
|
|
|
|
|
cutSelectedWidget: () => void;
|
2021-08-25 05:00:31 +00:00
|
|
|
groupSelectedWidget: () => void;
|
2021-08-11 06:48:57 +00:00
|
|
|
toggleShowGlobalSearchModal: (category: SearchCategory) => void;
|
2021-07-26 16:44:10 +00:00
|
|
|
resetSnipingMode: () => void;
|
2021-04-23 13:50:55 +00:00
|
|
|
openDebugger: () => void;
|
2021-05-18 18:29:39 +00:00
|
|
|
closeProppane: () => void;
|
2021-07-20 05:18:58 +00:00
|
|
|
closeTableFilterProppane: () => void;
|
2021-05-31 15:40:21 +00:00
|
|
|
executeAction: () => void;
|
2021-05-18 18:29:39 +00:00
|
|
|
selectAllWidgetsInit: () => void;
|
|
|
|
|
deselectAllWidgets: () => void;
|
2021-03-08 08:24:12 +00:00
|
|
|
selectedWidget?: string;
|
2021-05-18 18:29:39 +00:00
|
|
|
selectedWidgets: string[];
|
2021-05-03 08:08:49 +00:00
|
|
|
isDebuggerOpen: boolean;
|
2021-03-08 08:24:12 +00:00
|
|
|
children: React.ReactNode;
|
2021-08-23 09:25:16 +00:00
|
|
|
appMode?: APP_MODE;
|
|
|
|
|
isCommentMode: boolean;
|
2021-03-08 08:24:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@HotkeysTarget
|
|
|
|
|
class GlobalHotKeys extends React.Component<Props> {
|
|
|
|
|
public stopPropagationIfWidgetSelected(e: KeyboardEvent): boolean {
|
2021-05-18 18:29:39 +00:00
|
|
|
const multipleWidgetsSelected =
|
|
|
|
|
this.props.selectedWidgets && this.props.selectedWidgets.length;
|
|
|
|
|
const singleWidgetSelected =
|
2021-03-08 08:24:12 +00:00
|
|
|
this.props.selectedWidget &&
|
2021-05-18 18:29:39 +00:00
|
|
|
this.props.selectedWidget != MAIN_CONTAINER_WIDGET_ID;
|
|
|
|
|
if (
|
|
|
|
|
(singleWidgetSelected || multipleWidgetsSelected) &&
|
2021-03-08 08:24:12 +00:00
|
|
|
!getSelectedText()
|
|
|
|
|
) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-07 13:14:35 +00:00
|
|
|
public onOnmnibarHotKeyDown(e: KeyboardEvent) {
|
|
|
|
|
e.preventDefault();
|
2021-08-11 06:48:57 +00:00
|
|
|
this.props.toggleShowGlobalSearchModal(
|
|
|
|
|
filterCategories[SEARCH_CATEGORY_ID.NAVIGATION],
|
|
|
|
|
);
|
2021-06-07 13:14:35 +00:00
|
|
|
AnalyticsUtil.logEvent("OPEN_OMNIBAR", { source: "HOTKEY_COMBO" });
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-08 08:24:12 +00:00
|
|
|
public renderHotkeys() {
|
|
|
|
|
return (
|
|
|
|
|
<Hotkeys>
|
|
|
|
|
<Hotkey
|
|
|
|
|
combo="mod + f"
|
2021-04-28 10:28:39 +00:00
|
|
|
global
|
2021-03-08 08:24:12 +00:00
|
|
|
label="Search entities"
|
|
|
|
|
onKeyDown={(e: any) => {
|
|
|
|
|
const widgetSearchInput = document.getElementById(
|
|
|
|
|
WIDGETS_SEARCH_ID,
|
|
|
|
|
);
|
2021-06-09 12:20:15 +00:00
|
|
|
if (widgetSearchInput) {
|
|
|
|
|
widgetSearchInput.focus();
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
}
|
2021-03-08 08:24:12 +00:00
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<Hotkey
|
2021-04-28 10:28:39 +00:00
|
|
|
allowInInput={false}
|
2021-03-08 08:24:12 +00:00
|
|
|
combo="mod + k"
|
2021-04-28 10:28:39 +00:00
|
|
|
global
|
|
|
|
|
label="Show omnibar"
|
2021-06-07 13:14:35 +00:00
|
|
|
onKeyDown={(e) => this.onOnmnibarHotKeyDown(e)}
|
|
|
|
|
/>
|
|
|
|
|
<Hotkey
|
|
|
|
|
allowInInput={false}
|
|
|
|
|
combo="mod + p"
|
|
|
|
|
global
|
|
|
|
|
label="Show omnibar"
|
|
|
|
|
onKeyDown={(e) => this.onOnmnibarHotKeyDown(e)}
|
2021-03-08 08:24:12 +00:00
|
|
|
/>
|
2021-04-23 13:50:55 +00:00
|
|
|
<Hotkey
|
|
|
|
|
combo="mod + d"
|
2021-04-28 10:28:39 +00:00
|
|
|
global
|
2021-04-23 13:50:55 +00:00
|
|
|
group="Canvas"
|
2021-04-28 10:28:39 +00:00
|
|
|
label="Open Debugger"
|
2021-04-23 13:50:55 +00:00
|
|
|
onKeyDown={() => {
|
|
|
|
|
this.props.openDebugger();
|
2021-05-03 08:08:49 +00:00
|
|
|
if (this.props.isDebuggerOpen) {
|
|
|
|
|
AnalyticsUtil.logEvent("OPEN_DEBUGGER", {
|
|
|
|
|
source: "CANVAS",
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-04-23 13:50:55 +00:00
|
|
|
}}
|
|
|
|
|
preventDefault
|
|
|
|
|
/>
|
2021-03-08 08:24:12 +00:00
|
|
|
<Hotkey
|
|
|
|
|
combo="mod + c"
|
2021-04-28 10:28:39 +00:00
|
|
|
global
|
2021-03-08 08:24:12 +00:00
|
|
|
group="Canvas"
|
2021-04-28 10:28:39 +00:00
|
|
|
label="Copy Widget"
|
2021-03-08 08:24:12 +00:00
|
|
|
onKeyDown={(e: any) => {
|
2021-06-28 07:11:47 +00:00
|
|
|
if (this.stopPropagationIfWidgetSelected(e)) {
|
2021-03-08 08:24:12 +00:00
|
|
|
this.props.copySelectedWidget();
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<Hotkey
|
|
|
|
|
combo="mod + v"
|
2021-04-28 10:28:39 +00:00
|
|
|
global
|
2021-03-08 08:24:12 +00:00
|
|
|
group="Canvas"
|
2021-04-28 10:28:39 +00:00
|
|
|
label="Paste Widget"
|
2021-03-08 08:24:12 +00:00
|
|
|
onKeyDown={() => {
|
|
|
|
|
this.props.pasteCopiedWidget();
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<Hotkey
|
|
|
|
|
combo="backspace"
|
2021-04-28 10:28:39 +00:00
|
|
|
global
|
2021-03-08 08:24:12 +00:00
|
|
|
group="Canvas"
|
2021-04-28 10:28:39 +00:00
|
|
|
label="Delete Widget"
|
2021-03-08 08:24:12 +00:00
|
|
|
onKeyDown={(e: any) => {
|
|
|
|
|
if (this.stopPropagationIfWidgetSelected(e) && isMac()) {
|
|
|
|
|
this.props.deleteSelectedWidget();
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<Hotkey
|
|
|
|
|
combo="del"
|
2021-04-28 10:28:39 +00:00
|
|
|
global
|
2021-03-08 08:24:12 +00:00
|
|
|
group="Canvas"
|
2021-04-28 10:28:39 +00:00
|
|
|
label="Delete Widget"
|
2021-03-08 08:24:12 +00:00
|
|
|
onKeyDown={(e: any) => {
|
|
|
|
|
if (this.stopPropagationIfWidgetSelected(e)) {
|
|
|
|
|
this.props.deleteSelectedWidget();
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
<Hotkey
|
|
|
|
|
combo="mod + x"
|
2021-04-28 10:28:39 +00:00
|
|
|
global
|
2021-03-08 08:24:12 +00:00
|
|
|
group="Canvas"
|
2021-04-28 10:28:39 +00:00
|
|
|
label="Cut Widget"
|
2021-03-08 08:24:12 +00:00
|
|
|
onKeyDown={(e: any) => {
|
2021-06-28 07:11:47 +00:00
|
|
|
if (this.stopPropagationIfWidgetSelected(e)) {
|
2021-03-08 08:24:12 +00:00
|
|
|
this.props.cutSelectedWidget();
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
2021-05-18 18:29:39 +00:00
|
|
|
<Hotkey
|
|
|
|
|
combo="mod + a"
|
|
|
|
|
global
|
|
|
|
|
group="Canvas"
|
|
|
|
|
label="Select all Widget"
|
|
|
|
|
onKeyDown={(e: any) => {
|
|
|
|
|
this.props.selectAllWidgetsInit();
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
}}
|
|
|
|
|
/>
|
Initialise comments (#3328)
* Initial scaffolding for comments CRUD APIs
* add actions
* add assets
* state management for existing comments and creating new
* add ui components
* add overlay comments wrapper to baseWidget
* add toggle comment mode button at editor header
* trigger tests
* Disallow commenting as someone else
* Add applicationId for comments
* lint
* Add overlay blacklist to prevent component interaction while adding comments
* Comment thread style updates
* Placeholder comment context menu
* Controlled comment thread visibility for making new comments visible by default
* Update comment type description
* Reset input on save
* Resolve comment thread button ui
* fix close on esc key, dont create new comment on outside click
* Submit on enter
* add emoji picker
* Attempt at adding a websocket server in Java
* CRUD APIs for comment threads
* Add API for getting all threads in application
* Move types to a separate file
* Initial commit for real time server (RTS)
* Add script to start RTS
* Fix position property
* Use create comment thread API
* Use add comment to thread API
* Add custom cursor
* Dispatch logout init on 401 errors
* Allow CORS for real time connection
* Add more logs to RTS
* Fix construction of MongoClient
* WIP: Real time comments
* Enable comments
* Minor updates
* Read backend API base URL from environment
* Escape to reset comments mode
* Set popover position as auto and boundary as scroll parent
* Disable warning
* Added permissions for comment threads
* Add resolved API for comment threads
* Migration to set commenting permission on existing apps
* Fix updates bringing the RTS down
* Show view latest button, scroll to bottom on creating a new comment
* Cleanup comment reducer
* Move to typescript for RTS
* Add missing server.ts and tsconfig files
* Resolve / unresolve comment
* Scaffold app comments
* Minor fixes: comment on top of all widgets, add toggle button at viewer header
* Reconnect socket on creating a new app, set connected status in store
* Retry socket connection flow
* Integration tests for comments with api mocks using msw
* Fix circular depependency
* rm file
* Minor cleanup and comments
* Minor refactors: move isScrolledToBottom to common hooks, decouple prevent interactions overlay from comments wrapper
* Use policies when pushing updates in RTS
* ENV var to set if comments are enabled
* Fix: check if editor/viewer is initialised before waiting for init action
* Add tests for comments reducer
* Revert "ENV var to set if comments are enabled"
This reverts commit 988efeaa69d378d943a387e1e73510334958adc5.
* Enable comments for users with appsmith email
* lint
* fix
* Try running a socket.io server inside backend
* Update comment reducer tests
* Init mentions within comments
* Fix comment thread updates with email rooms
* Minor fixes
* Refactors / review suggestions
* lint
* increase cache limit for builds
* Comment out tests for feature that's under development
* Add Dockerfile for RTS
* Fix policies missing for first comment in threads
* Use draftJS for comments input with mentions support
* fix fixtures
* Use thread's policies when querying for threads
* Update socket.io to v4
* Add support for richer body with mentions
* Update comment body type to RawDraftContentState
* fix stale method
* Fix mentions search
* Minor cleanups
* Comment context menu and thread UI updates
* revert: Scaffold app comments
* Yarn dependencies
* Delete comment using id api added
* Init app comments
* Add test for creating thread
* Api for delete comment with id
* Test comment creation response and policies
* Copy comment links
* Fix reset editor state
* Delete valid comment testcase added
* Delete comment TC : code refactor
* Don't allow creating comments with an empty body
* Pin comments WIP[]
* Ignore dependency-reduced-pom.xml files from VCS
* Cleanup of some dev-only files, for review
* Delete comment
* Update socket.io to v4 in RTS
* Pin and resolve comment thread object added in commentThread
* Pin and resolve comment thread object added in commentThread
* Update comment thread API
* Added creationTime and updationTime in comment thread response
* Added creationTime and updationTime in comment thread response
* Added human readable id to comment threads, fallback to username for null name in user document
* Refactor
* lint
* fix test, rm duplicate selector
* comment out saga used for dev
* CommentThread viewed status, username fallback for getName=null, username field added in pin & resolve status
* lint
* trigger tests
Co-authored-by: Shrikant Sharat Kandula <shrikant@appsmith.com>
Co-authored-by: Abhijeet <abhi.nagarnaik@gmail.com>
2021-04-29 10:33:51 +00:00
|
|
|
<Hotkey
|
|
|
|
|
combo="esc"
|
|
|
|
|
global
|
2021-05-18 18:29:39 +00:00
|
|
|
group="Canvas"
|
|
|
|
|
label="Deselect all Widget"
|
|
|
|
|
onKeyDown={(e: any) => {
|
2021-08-23 09:25:16 +00:00
|
|
|
if (this.props.isCommentMode && getFeatureFlags().COMMENT) {
|
|
|
|
|
AnalyticsUtil.logEvent("COMMENTS_TOGGLE_MODE", {
|
|
|
|
|
mode: this.props.appMode,
|
|
|
|
|
source: "HOTKEY",
|
|
|
|
|
combo: "esc",
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-08-05 13:27:48 +00:00
|
|
|
setCommentModeInUrl(false);
|
2021-07-26 16:44:10 +00:00
|
|
|
this.props.resetSnipingMode();
|
2021-05-18 18:29:39 +00:00
|
|
|
this.props.deselectAllWidgets();
|
|
|
|
|
this.props.closeProppane();
|
2021-07-20 05:18:58 +00:00
|
|
|
this.props.closeTableFilterProppane();
|
2021-05-18 18:29:39 +00:00
|
|
|
e.preventDefault();
|
|
|
|
|
}}
|
Initialise comments (#3328)
* Initial scaffolding for comments CRUD APIs
* add actions
* add assets
* state management for existing comments and creating new
* add ui components
* add overlay comments wrapper to baseWidget
* add toggle comment mode button at editor header
* trigger tests
* Disallow commenting as someone else
* Add applicationId for comments
* lint
* Add overlay blacklist to prevent component interaction while adding comments
* Comment thread style updates
* Placeholder comment context menu
* Controlled comment thread visibility for making new comments visible by default
* Update comment type description
* Reset input on save
* Resolve comment thread button ui
* fix close on esc key, dont create new comment on outside click
* Submit on enter
* add emoji picker
* Attempt at adding a websocket server in Java
* CRUD APIs for comment threads
* Add API for getting all threads in application
* Move types to a separate file
* Initial commit for real time server (RTS)
* Add script to start RTS
* Fix position property
* Use create comment thread API
* Use add comment to thread API
* Add custom cursor
* Dispatch logout init on 401 errors
* Allow CORS for real time connection
* Add more logs to RTS
* Fix construction of MongoClient
* WIP: Real time comments
* Enable comments
* Minor updates
* Read backend API base URL from environment
* Escape to reset comments mode
* Set popover position as auto and boundary as scroll parent
* Disable warning
* Added permissions for comment threads
* Add resolved API for comment threads
* Migration to set commenting permission on existing apps
* Fix updates bringing the RTS down
* Show view latest button, scroll to bottom on creating a new comment
* Cleanup comment reducer
* Move to typescript for RTS
* Add missing server.ts and tsconfig files
* Resolve / unresolve comment
* Scaffold app comments
* Minor fixes: comment on top of all widgets, add toggle button at viewer header
* Reconnect socket on creating a new app, set connected status in store
* Retry socket connection flow
* Integration tests for comments with api mocks using msw
* Fix circular depependency
* rm file
* Minor cleanup and comments
* Minor refactors: move isScrolledToBottom to common hooks, decouple prevent interactions overlay from comments wrapper
* Use policies when pushing updates in RTS
* ENV var to set if comments are enabled
* Fix: check if editor/viewer is initialised before waiting for init action
* Add tests for comments reducer
* Revert "ENV var to set if comments are enabled"
This reverts commit 988efeaa69d378d943a387e1e73510334958adc5.
* Enable comments for users with appsmith email
* lint
* fix
* Try running a socket.io server inside backend
* Update comment reducer tests
* Init mentions within comments
* Fix comment thread updates with email rooms
* Minor fixes
* Refactors / review suggestions
* lint
* increase cache limit for builds
* Comment out tests for feature that's under development
* Add Dockerfile for RTS
* Fix policies missing for first comment in threads
* Use draftJS for comments input with mentions support
* fix fixtures
* Use thread's policies when querying for threads
* Update socket.io to v4
* Add support for richer body with mentions
* Update comment body type to RawDraftContentState
* fix stale method
* Fix mentions search
* Minor cleanups
* Comment context menu and thread UI updates
* revert: Scaffold app comments
* Yarn dependencies
* Delete comment using id api added
* Init app comments
* Add test for creating thread
* Api for delete comment with id
* Test comment creation response and policies
* Copy comment links
* Fix reset editor state
* Delete valid comment testcase added
* Delete comment TC : code refactor
* Don't allow creating comments with an empty body
* Pin comments WIP[]
* Ignore dependency-reduced-pom.xml files from VCS
* Cleanup of some dev-only files, for review
* Delete comment
* Update socket.io to v4 in RTS
* Pin and resolve comment thread object added in commentThread
* Pin and resolve comment thread object added in commentThread
* Update comment thread API
* Added creationTime and updationTime in comment thread response
* Added creationTime and updationTime in comment thread response
* Added human readable id to comment threads, fallback to username for null name in user document
* Refactor
* lint
* fix test, rm duplicate selector
* comment out saga used for dev
* CommentThread viewed status, username fallback for getName=null, username field added in pin & resolve status
* lint
* trigger tests
Co-authored-by: Shrikant Sharat Kandula <shrikant@appsmith.com>
Co-authored-by: Abhijeet <abhi.nagarnaik@gmail.com>
2021-04-29 10:33:51 +00:00
|
|
|
/>
|
2021-05-20 12:03:08 +00:00
|
|
|
<Hotkey
|
|
|
|
|
combo="v"
|
|
|
|
|
global
|
|
|
|
|
label="Edit Mode"
|
2021-07-26 16:44:10 +00:00
|
|
|
onKeyDown={(e: any) => {
|
2021-08-23 09:25:16 +00:00
|
|
|
if (getFeatureFlags().COMMENT && this.props.isCommentMode)
|
|
|
|
|
AnalyticsUtil.logEvent("COMMENTS_TOGGLE_MODE", {
|
|
|
|
|
mode: this.props.appMode,
|
|
|
|
|
source: "HOTKEY",
|
|
|
|
|
combo: "v",
|
|
|
|
|
});
|
2021-08-05 13:27:48 +00:00
|
|
|
setCommentModeInUrl(false);
|
2021-07-26 16:44:10 +00:00
|
|
|
this.props.resetSnipingMode();
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
}}
|
2021-05-20 12:03:08 +00:00
|
|
|
/>
|
|
|
|
|
<Hotkey
|
|
|
|
|
combo="c"
|
|
|
|
|
global
|
|
|
|
|
label="Comment Mode"
|
2021-08-23 09:25:16 +00:00
|
|
|
onKeyDown={() => {
|
|
|
|
|
if (getFeatureFlags().COMMENT && !this.props.isCommentMode)
|
|
|
|
|
AnalyticsUtil.logEvent("COMMENTS_TOGGLE_MODE", {
|
|
|
|
|
mode: "COMMENT",
|
|
|
|
|
source: "HOTKEY",
|
|
|
|
|
combo: "c",
|
|
|
|
|
});
|
|
|
|
|
setCommentModeInUrl(true);
|
|
|
|
|
}}
|
2021-05-20 12:03:08 +00:00
|
|
|
/>
|
2021-05-31 15:40:21 +00:00
|
|
|
<Hotkey
|
|
|
|
|
allowInInput
|
|
|
|
|
combo="mod + enter"
|
|
|
|
|
global
|
|
|
|
|
label="Execute Action"
|
|
|
|
|
onKeyDown={this.props.executeAction}
|
|
|
|
|
preventDefault
|
|
|
|
|
stopPropagation
|
|
|
|
|
/>
|
2021-08-25 05:00:31 +00:00
|
|
|
<Hotkey
|
|
|
|
|
combo="mod + g"
|
|
|
|
|
global
|
|
|
|
|
group="Canvas"
|
|
|
|
|
label="Cut Widgets for grouping"
|
|
|
|
|
onKeyDown={(e: any) => {
|
|
|
|
|
if (this.stopPropagationIfWidgetSelected(e)) {
|
|
|
|
|
this.props.groupSelectedWidget();
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
2021-09-02 08:37:27 +00:00
|
|
|
<Hotkey
|
|
|
|
|
combo="mod + s"
|
|
|
|
|
global
|
|
|
|
|
label="Save progress"
|
|
|
|
|
onKeyDown={() => {
|
|
|
|
|
Toaster.show({
|
|
|
|
|
text: createMessage(SAVE_HOTKEY_TOASTER_MESSAGE),
|
|
|
|
|
variant: Variant.info,
|
|
|
|
|
});
|
|
|
|
|
}}
|
|
|
|
|
preventDefault
|
|
|
|
|
stopPropagation
|
|
|
|
|
/>
|
2021-03-08 08:24:12 +00:00
|
|
|
</Hotkeys>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
render() {
|
|
|
|
|
return <div>{this.props.children}</div>;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const mapStateToProps = (state: AppState) => ({
|
|
|
|
|
selectedWidget: getSelectedWidget(state),
|
2021-05-18 18:29:39 +00:00
|
|
|
selectedWidgets: getSelectedWidgets(state),
|
2021-05-03 08:08:49 +00:00
|
|
|
isDebuggerOpen: state.ui.debugger.isOpen,
|
2021-08-23 09:25:16 +00:00
|
|
|
appMode: getAppMode(state),
|
|
|
|
|
isCommentMode: commentModeSelector(state),
|
2021-03-08 08:24:12 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const mapDispatchToProps = (dispatch: any) => {
|
|
|
|
|
return {
|
|
|
|
|
copySelectedWidget: () => dispatch(copyWidget(true)),
|
|
|
|
|
pasteCopiedWidget: () => dispatch(pasteWidget()),
|
|
|
|
|
deleteSelectedWidget: () => dispatch(deleteSelectedWidget(true)),
|
|
|
|
|
cutSelectedWidget: () => dispatch(cutWidget()),
|
2021-08-25 05:00:31 +00:00
|
|
|
groupSelectedWidget: () => dispatch(groupWidgets()),
|
2021-08-11 06:48:57 +00:00
|
|
|
toggleShowGlobalSearchModal: (category: SearchCategory) =>
|
|
|
|
|
dispatch(toggleShowGlobalSearchModal(category)),
|
2021-07-26 16:44:10 +00:00
|
|
|
resetSnipingMode: () => dispatch(resetSnipingModeAction()),
|
2021-04-23 13:50:55 +00:00
|
|
|
openDebugger: () => dispatch(showDebugger()),
|
2021-05-18 18:29:39 +00:00
|
|
|
closeProppane: () => dispatch(closePropertyPane()),
|
2021-07-20 05:18:58 +00:00
|
|
|
closeTableFilterProppane: () => dispatch(closeTableFilterPane()),
|
2021-06-28 07:11:47 +00:00
|
|
|
selectAllWidgetsInit: () => dispatch(selectAllWidgetsInCanvasInitAction()),
|
2021-08-16 09:24:42 +00:00
|
|
|
deselectAllWidgets: () => dispatch(deselectAllInitAction()),
|
2021-05-31 15:40:21 +00:00
|
|
|
executeAction: () => dispatch(runActionViaShortcut()),
|
2021-03-08 08:24:12 +00:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(GlobalHotKeys);
|