saleor-dashboard/src/components/Navigator/Navigator.tsx
Dominik Żegleń 62817568a7
Use MacawUI (#1229)
* Replace withStyleswith useStyles (#1100)

* Replace withStyleswith useStyles

* Update messages

* Use rem as a spacing unit (#1101)

* Use rems as spacing units

* Fix visual bugs

* Update stories

* Use macaw-ui as theme provider (#1108)

* Use macaw ui as a theme provider

* Add react-dom to aliases

* Fix jest module resolution

* Update useTheme hook usage

* Fix test wrapper

* Use macaw from git repo

* Fix CI

* Update stories

* Fix aliasing

* Extract savebar to macaw ui (#1146)

* wip

* Use savebar from macaw

* Use confirm button from macaw

* Improve file structure

* Use sidebar context from macaw

* Update macaw

* Update macaw version

* Remove savebar from storybook

* Update stories

* Use alerts and notifications from macaw (#1166)

* Use alerts from macaw

* Add notifications from macaw

* Update stories

* Pin macaw version

* Encapsulate limit reached in one component

* Remove unused imports

* Use backlinks from macaw (#1183)

* Use backlink from macaw

* Update macaw version

* Use macaw sidebar (#1148)

* Use sidebar from macaw

* Use shipped logo

* Use lowercase

* Update stories

* Use user chip from macaw (#1191)

* Use user chip from macaw

* Use dedicated components for menu items

* Simplify code

* Bump version and fix types (#1210)

* Rename onBack to onClick

* Rename UserChip to UserChipMenu

* Rename IMenuItem to SidebarMenuItem

* Update macaw version

* Fix tables after changes in macaw (#1220)

* Update macaw version

* Update changelog

* Update stories

* Fix after rebase

* Update to macaw 0.2.0

* Lint files

* Update macaw to 0.2.2
2021-07-21 10:59:52 +02:00

211 lines
6.4 KiB
TypeScript

import { Fade, Modal, Paper } from "@material-ui/core";
import { APP_VERSION } from "@saleor/config";
import useLocalStorage from "@saleor/hooks/useLocalStorage";
import useNotifier from "@saleor/hooks/useNotifier";
import { useTheme } from "@saleor/macaw-ui";
import { makeStyles } from "@saleor/macaw-ui";
import Downshift from "downshift";
import hotkeys from "hotkeys-js";
import React from "react";
import { useIntl } from "react-intl";
import cmp from "semver-compare";
import {
getActions,
getCatalog,
getCustomers,
getViews,
hasActions,
hasCatalog,
hasCustomers,
hasViews
} from "./modes/utils";
import NavigatorInput from "./NavigatorInput";
import NavigatorSection from "./NavigatorSection";
import { QuickSearchAction } from "./types";
import useQuickSearch from "./useQuickSearch";
const navigatorHotkey = "ctrl+k, command+k";
const navigatorNotificationStorageKey = "notifiedAboutNavigator";
function getItemOffset(
actions: QuickSearchAction[],
cbs: Array<typeof getViews>
): number {
return cbs.reduce((acc, cb) => cb(actions).length + acc, 0);
}
const useStyles = makeStyles(
theme => ({
modal: {
alignItems: "center",
display: "flex",
justifyContent: "center",
padding: theme.spacing(3)
},
paper: {
overflow: "hidden"
},
root: {
[theme.breakpoints.down("sm")]: {
height: "auto"
},
height: 500,
maxWidth: 600,
outline: 0,
width: "100%"
}
}),
{
name: "Navigator"
}
);
export interface NavigatorProps {
visible: boolean;
setVisibility: (state: boolean) => void;
}
const Navigator: React.FC<NavigatorProps> = ({ visible, setVisibility }) => {
const input = React.useRef(null);
const [query, mode, change, actions] = useQuickSearch(visible, input);
const intl = useIntl();
const notify = useNotifier();
const [notifiedAboutNavigator, setNotifiedAboutNavigator] = useLocalStorage(
navigatorNotificationStorageKey,
false
);
const classes = useStyles({});
const theme = useTheme();
React.useEffect(() => {
hotkeys(navigatorHotkey, event => {
event.preventDefault();
setVisibility(!visible);
});
if (cmp(APP_VERSION, "2.1.0") !== 1 && !notifiedAboutNavigator) {
notify({
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"
}
),
title: intl.formatMessage({
defaultMessage: "Navigator is here to help",
description: "navigator notification title"
})
});
setNotifiedAboutNavigator(true);
}
return () => hotkeys.unbind(navigatorHotkey);
}, []);
return (
<Modal
className={classes.modal}
open={visible}
onClose={() => setVisibility(false)}
>
<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) {
setVisibility(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>
);
};
export default Navigator;