Omnibar UI/UX improvements (#4677)
- Open omnibar on cmd + p as well - Add analytics event for opening discord link - Update api icon to keep same width - Click anywhere on search result row will now open the link instead of just clicking on the icon - Change text from "Recents" to "Recent Entities" - Show a footer with a few instructions.
This commit is contained in:
parent
5bca743790
commit
8e7b95fd62
|
|
@ -0,0 +1,49 @@
|
||||||
|
import React from "react";
|
||||||
|
import styled from "styled-components";
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
span {
|
||||||
|
color: white;
|
||||||
|
font-variant: all-small-caps;
|
||||||
|
font-size: ${(props) => props.theme.fontSizes[2]}px;
|
||||||
|
margin-right: ${(props) => props.theme.spaces[1]}px;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
margin-right: ${(props) => props.theme.spaces[7]}px;
|
||||||
|
font-size: ${(props) => props.theme.fontSizes[2]}px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
color: ${(props) => props.theme.colors.globalSearch.searchItemText};
|
||||||
|
padding: ${(props) => props.theme.spaces[1]}px
|
||||||
|
${(props) => props.theme.spaces[6]}px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const FOOTER_INFO = [
|
||||||
|
{
|
||||||
|
action: "\u2191\u2193",
|
||||||
|
description: "Select",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: "ENTER",
|
||||||
|
description: "Open",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function Footer() {
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
{FOOTER_INFO.map((info) => {
|
||||||
|
return (
|
||||||
|
<div key={info.action}>
|
||||||
|
<span>{info.action}</span>
|
||||||
|
{info.description}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Footer;
|
||||||
|
|
@ -4,6 +4,7 @@ import NoSearchDataImage from "assets/images/no_search_data.png";
|
||||||
import { NO_SEARCH_DATA_TEXT } from "constants/messages";
|
import { NO_SEARCH_DATA_TEXT } from "constants/messages";
|
||||||
import { getTypographyByKey } from "constants/DefaultTheme";
|
import { getTypographyByKey } from "constants/DefaultTheme";
|
||||||
import { ReactComponent as DiscordIcon } from "assets/icons/help/discord.svg";
|
import { ReactComponent as DiscordIcon } from "assets/icons/help/discord.svg";
|
||||||
|
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -49,6 +50,7 @@ function ResultsNotFound() {
|
||||||
className="discord-link"
|
className="discord-link"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
window.open("https://discord.gg/rBTTVJp", "_blank");
|
window.open("https://discord.gg/rBTTVJp", "_blank");
|
||||||
|
AnalyticsUtil.logEvent("DISCORD_LINK_CLICK");
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<StyledDiscordIcon color="red" height={22} width={24} />
|
<StyledDiscordIcon color="red" height={22} width={24} />
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import { getActionConfig } from "pages/Editor/Explorer/Actions/helpers";
|
||||||
import { AppState } from "reducers";
|
import { AppState } from "reducers";
|
||||||
import { keyBy, noop } from "lodash";
|
import { keyBy, noop } from "lodash";
|
||||||
import { getPageList } from "selectors/editorSelectors";
|
import { getPageList } from "selectors/editorSelectors";
|
||||||
|
import { PluginType } from "entities/Action";
|
||||||
|
|
||||||
const DocumentIcon = HelpIcons.DOCUMENT;
|
const DocumentIcon = HelpIcons.DOCUMENT;
|
||||||
|
|
||||||
|
|
@ -158,7 +159,10 @@ function ActionItem(props: {
|
||||||
return state.entities.plugins.list;
|
return state.entities.plugins.list;
|
||||||
});
|
});
|
||||||
const pluginGroups = useMemo(() => keyBy(plugins, "id"), [plugins]);
|
const pluginGroups = useMemo(() => keyBy(plugins, "id"), [plugins]);
|
||||||
const icon = getActionConfig(pluginType)?.getIcon(
|
const icon =
|
||||||
|
pluginType === PluginType.API
|
||||||
|
? getActionConfig(pluginType)?.icon
|
||||||
|
: getActionConfig(pluginType)?.getIcon(
|
||||||
item.config,
|
item.config,
|
||||||
pluginGroups[item.config.datasource.pluginId],
|
pluginGroups[item.config.datasource.pluginId],
|
||||||
);
|
);
|
||||||
|
|
@ -293,10 +297,8 @@ function SearchItemComponent(props: ItemProps) {
|
||||||
itemType !== SEARCH_ITEM_TYPES.placeholder
|
itemType !== SEARCH_ITEM_TYPES.placeholder
|
||||||
) {
|
) {
|
||||||
setActiveItemIndex(index);
|
setActiveItemIndex(index);
|
||||||
if (itemType !== SEARCH_ITEM_TYPES.document) {
|
|
||||||
searchContext?.handleItemLinkClick(item, "SEARCH_ITEM");
|
searchContext?.handleItemLinkClick(item, "SEARCH_ITEM");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
ref={itemRef}
|
ref={itemRef}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ import { keyBy, noop } from "lodash";
|
||||||
import EntitiesIcon from "assets/icons/ads/entities.svg";
|
import EntitiesIcon from "assets/icons/ads/entities.svg";
|
||||||
import DocsIcon from "assets/icons/ads/docs.svg";
|
import DocsIcon from "assets/icons/ads/docs.svg";
|
||||||
import RecentIcon from "assets/icons/ads/recent.svg";
|
import RecentIcon from "assets/icons/ads/recent.svg";
|
||||||
|
import Footer from "./Footer";
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
width: 750px;
|
width: 750px;
|
||||||
|
|
@ -204,7 +205,7 @@ function GlobalSearch() {
|
||||||
);
|
);
|
||||||
}, [pages, query]);
|
}, [pages, query]);
|
||||||
|
|
||||||
const recentsSectionTitle = getSectionTitle("Recents", RecentIcon);
|
const recentsSectionTitle = getSectionTitle("Recent Entities", RecentIcon);
|
||||||
const docsSectionTitle = getSectionTitle("Documentation Links", DocsIcon);
|
const docsSectionTitle = getSectionTitle("Documentation Links", DocsIcon);
|
||||||
const entitiesSectionTitle = getSectionTitle("Entities", EntitiesIcon);
|
const entitiesSectionTitle = getSectionTitle("Entities", EntitiesIcon);
|
||||||
|
|
||||||
|
|
@ -397,6 +398,7 @@ function GlobalSearch() {
|
||||||
<ResultsNotFound />
|
<ResultsNotFound />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
{!query && <Footer />}
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
</AlgoliaSearchWrapper>
|
</AlgoliaSearchWrapper>
|
||||||
</SearchModal>
|
</SearchModal>
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,12 @@ class GlobalHotKeys extends React.Component<Props> {
|
||||||
return !!multipleWidgetsSelected;
|
return !!multipleWidgetsSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public onOnmnibarHotKeyDown(e: KeyboardEvent) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.props.toggleShowGlobalSearchModal();
|
||||||
|
AnalyticsUtil.logEvent("OPEN_OMNIBAR", { source: "HOTKEY_COMBO" });
|
||||||
|
}
|
||||||
|
|
||||||
public renderHotkeys() {
|
public renderHotkeys() {
|
||||||
return (
|
return (
|
||||||
<Hotkeys>
|
<Hotkeys>
|
||||||
|
|
@ -96,12 +102,14 @@ class GlobalHotKeys extends React.Component<Props> {
|
||||||
combo="mod + k"
|
combo="mod + k"
|
||||||
global
|
global
|
||||||
label="Show omnibar"
|
label="Show omnibar"
|
||||||
onKeyDown={(e: KeyboardEvent) => {
|
onKeyDown={(e) => this.onOnmnibarHotKeyDown(e)}
|
||||||
console.log("toggleShowGlobalSearchModal");
|
/>
|
||||||
e.preventDefault();
|
<Hotkey
|
||||||
this.props.toggleShowGlobalSearchModal();
|
allowInInput={false}
|
||||||
AnalyticsUtil.logEvent("OPEN_OMNIBAR", { source: "HOTKEY_COMBO" });
|
combo="mod + p"
|
||||||
}}
|
global
|
||||||
|
label="Show omnibar"
|
||||||
|
onKeyDown={(e) => this.onOnmnibarHotKeyDown(e)}
|
||||||
/>
|
/>
|
||||||
<Hotkey
|
<Hotkey
|
||||||
combo="mod + d"
|
combo="mod + d"
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,8 @@ export type EventName =
|
||||||
| "DEBUGGER_ENTITY_NAVIGATION"
|
| "DEBUGGER_ENTITY_NAVIGATION"
|
||||||
| "GSHEET_AUTH_INIT"
|
| "GSHEET_AUTH_INIT"
|
||||||
| "GSHEET_AUTH_COMPLETE"
|
| "GSHEET_AUTH_COMPLETE"
|
||||||
| "CYCLICAL_DEPENDENCY_ERROR";
|
| "CYCLICAL_DEPENDENCY_ERROR"
|
||||||
|
| "DISCORD_LINK_CLICK";
|
||||||
|
|
||||||
function getApplicationId(location: Location) {
|
function getApplicationId(location: Location) {
|
||||||
const pathSplit = location.pathname.split("/");
|
const pathSplit = location.pathname.split("/");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user