2019-11-26 14:14:21 +00:00
|
|
|
import Fade from "@material-ui/core/Fade";
|
|
|
|
import Modal from "@material-ui/core/Modal";
|
|
|
|
import Paper from "@material-ui/core/Paper";
|
|
|
|
import makeStyles from "@material-ui/core/styles/makeStyles";
|
|
|
|
import useTheme from "@material-ui/core/styles/useTheme";
|
2020-05-14 09:30:32 +00:00
|
|
|
import { APP_VERSION } from "@saleor/config";
|
|
|
|
import useLocalStorage from "@saleor/hooks/useLocalStorage";
|
|
|
|
import useNotifier from "@saleor/hooks/useNotifier";
|
2019-11-20 15:58:17 +00:00
|
|
|
import Downshift from "downshift";
|
|
|
|
import hotkeys from "hotkeys-js";
|
|
|
|
import React from "react";
|
|
|
|
import { useIntl } from "react-intl";
|
2019-11-25 16:23:52 +00:00
|
|
|
import cmp from "semver-compare";
|
2019-11-20 15:58:17 +00:00
|
|
|
|
2019-11-25 11:29:07 +00:00
|
|
|
import {
|
|
|
|
getActions,
|
2019-11-25 14:32:10 +00:00
|
|
|
getCatalog,
|
2019-11-25 11:29:07 +00:00
|
|
|
getCustomers,
|
|
|
|
getViews,
|
|
|
|
hasActions,
|
2019-11-25 14:32:10 +00:00
|
|
|
hasCatalog,
|
2019-11-25 11:29:07 +00:00
|
|
|
hasCustomers,
|
|
|
|
hasViews
|
|
|
|
} from "./modes/utils";
|
2019-11-20 15:58:17 +00:00
|
|
|
import NavigatorInput from "./NavigatorInput";
|
|
|
|
import NavigatorSection from "./NavigatorSection";
|
|
|
|
import { QuickSearchAction } from "./types";
|
|
|
|
import useQuickSearch from "./useQuickSearch";
|
|
|
|
|
2019-11-25 15:42:24 +00:00
|
|
|
const navigatorHotkey = "ctrl+k, command+k";
|
2019-11-25 16:23:52 +00:00
|
|
|
const navigatorNotificationStorageKey = "notifiedAboutNavigator";
|
2019-11-20 15:58:17 +00:00
|
|
|
|
2019-11-25 11:29:07 +00:00
|
|
|
function getItemOffset(
|
|
|
|
actions: QuickSearchAction[],
|
|
|
|
cbs: Array<typeof getViews>
|
|
|
|
): number {
|
|
|
|
return cbs.reduce((acc, cb) => cb(actions).length + acc, 0);
|
|
|
|
}
|
|
|
|
|
2019-11-26 14:14:21 +00:00
|
|
|
const useStyles = makeStyles(
|
|
|
|
theme => ({
|
|
|
|
modal: {
|
|
|
|
alignItems: "center",
|
|
|
|
display: "flex",
|
|
|
|
justifyContent: "center",
|
|
|
|
padding: theme.spacing(3)
|
|
|
|
},
|
|
|
|
paper: {
|
|
|
|
overflow: "hidden"
|
|
|
|
},
|
|
|
|
root: {
|
|
|
|
height: 500,
|
|
|
|
maxWidth: 600,
|
|
|
|
outline: 0,
|
|
|
|
width: "100%"
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
{
|
|
|
|
name: "Navigator"
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2019-11-20 15:58:17 +00:00
|
|
|
const Navigator: React.FC = () => {
|
|
|
|
const [visible, setVisible] = React.useState(false);
|
2019-11-21 12:13:41 +00:00
|
|
|
const input = React.useRef(null);
|
|
|
|
const [query, mode, change, actions] = useQuickSearch(visible, input);
|
2019-11-20 15:58:17 +00:00
|
|
|
const intl = useIntl();
|
2019-11-25 16:23:52 +00:00
|
|
|
const notify = useNotifier();
|
|
|
|
const [notifiedAboutNavigator, setNotifiedAboutNavigator] = useLocalStorage(
|
|
|
|
navigatorNotificationStorageKey,
|
|
|
|
false
|
|
|
|
);
|
2019-11-26 14:14:21 +00:00
|
|
|
const classes = useStyles({});
|
|
|
|
const theme = useTheme();
|
2019-11-20 15:58:17 +00:00
|
|
|
|
|
|
|
React.useEffect(() => {
|
2019-11-25 15:42:24 +00:00
|
|
|
hotkeys(navigatorHotkey, event => {
|
|
|
|
event.preventDefault();
|
|
|
|
setVisible(!visible);
|
|
|
|
});
|
2019-11-20 15:58:17 +00:00
|
|
|
|
2019-11-25 16:23:52 +00:00
|
|
|
if (cmp(APP_VERSION, "2.1.0") !== 1 && !notifiedAboutNavigator) {
|
|
|
|
notify({
|
2019-11-25 16:53:10 +00:00
|
|
|
autohide: null,
|
|
|
|
text: intl.formatMessage(
|
|
|
|
{
|
|
|
|
defaultMessage:
|
|
|
|
"Our new feature to help you with your daily tasks. Run Navigator using {keyboardShortcut} shortcut.",
|
|
|
|
description: "navigator notification"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
keyboardShortcut:
|
|
|
|
navigator.platform.toLowerCase().indexOf("mac") >= 0
|
|
|
|
? "⌘+K"
|
|
|
|
: "Ctrl+K"
|
|
|
|
}
|
|
|
|
),
|
2019-11-25 16:23:52 +00:00
|
|
|
title: intl.formatMessage({
|
|
|
|
defaultMessage: "Navigator is here to help",
|
|
|
|
description: "navigator notification title"
|
|
|
|
})
|
|
|
|
});
|
|
|
|
setNotifiedAboutNavigator(true);
|
|
|
|
}
|
|
|
|
|
2019-11-20 15:58:17 +00:00
|
|
|
return () => hotkeys.unbind(navigatorHotkey);
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
return (
|
2019-11-26 14:14:21 +00:00
|
|
|
<Modal
|
|
|
|
className={classes.modal}
|
2019-11-20 15:58:17 +00:00
|
|
|
open={visible}
|
|
|
|
onClose={() => setVisible(false)}
|
|
|
|
>
|
2019-11-26 14:14:21 +00:00
|
|
|
<Fade appear in={visible} timeout={theme.transitions.duration.short}>
|
|
|
|
<div className={classes.root}>
|
|
|
|
<Paper className={classes.paper}>
|
|
|
|
<Downshift
|
|
|
|
itemToString={(item: QuickSearchAction) =>
|
|
|
|
item ? item.label : ""
|
|
|
|
}
|
|
|
|
onSelect={(item: QuickSearchAction) => {
|
|
|
|
const shouldRemainVisible = item.onClick();
|
|
|
|
if (!shouldRemainVisible) {
|
|
|
|
setVisible(false);
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
onInputValueChange={value =>
|
|
|
|
change({
|
|
|
|
target: {
|
|
|
|
name: "query",
|
|
|
|
value
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
defaultHighlightedIndex={0}
|
|
|
|
>
|
|
|
|
{({ getInputProps, getItemProps, highlightedIndex }) => (
|
|
|
|
<div>
|
|
|
|
<NavigatorInput
|
|
|
|
mode={mode}
|
|
|
|
value={query}
|
|
|
|
{...getInputProps({
|
|
|
|
value: query
|
|
|
|
})}
|
|
|
|
ref={input}
|
|
|
|
/>
|
|
|
|
{hasViews(actions) && (
|
|
|
|
<NavigatorSection
|
|
|
|
label={intl.formatMessage({
|
|
|
|
defaultMessage: "Navigate to",
|
|
|
|
description: "navigator section header"
|
|
|
|
})}
|
|
|
|
getItemProps={getItemProps}
|
|
|
|
highlightedIndex={highlightedIndex}
|
|
|
|
items={getViews(actions)}
|
|
|
|
offset={0}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
{hasActions(actions) && (
|
|
|
|
<NavigatorSection
|
|
|
|
label={intl.formatMessage({
|
|
|
|
defaultMessage: "Quick Actions",
|
|
|
|
description: "navigator section header"
|
|
|
|
})}
|
|
|
|
getItemProps={getItemProps}
|
|
|
|
highlightedIndex={highlightedIndex}
|
|
|
|
items={getActions(actions)}
|
|
|
|
offset={getItemOffset(actions, [getViews])}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
{hasCustomers(actions) && (
|
|
|
|
<NavigatorSection
|
|
|
|
label={intl.formatMessage({
|
|
|
|
defaultMessage: "Search in Customers",
|
|
|
|
description: "navigator section header"
|
|
|
|
})}
|
|
|
|
getItemProps={getItemProps}
|
|
|
|
highlightedIndex={highlightedIndex}
|
|
|
|
items={getCustomers(actions)}
|
|
|
|
offset={getItemOffset(actions, [getViews, getActions])}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
{hasCatalog(actions) && (
|
|
|
|
<NavigatorSection
|
|
|
|
label={intl.formatMessage({
|
|
|
|
defaultMessage: "Search in Catalog",
|
|
|
|
description: "navigator section header"
|
|
|
|
})}
|
|
|
|
getItemProps={getItemProps}
|
|
|
|
highlightedIndex={highlightedIndex}
|
|
|
|
items={getCatalog(actions)}
|
|
|
|
offset={0}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
</Downshift>
|
|
|
|
</Paper>
|
|
|
|
</div>
|
|
|
|
</Fade>
|
|
|
|
</Modal>
|
2019-11-20 15:58:17 +00:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default Navigator;
|