Add help mode
This commit is contained in:
parent
19021040f0
commit
6faffa24ff
15 changed files with 369 additions and 139 deletions
|
@ -1,4 +1,8 @@
|
||||||
import Dialog from "@material-ui/core/Dialog";
|
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";
|
||||||
import Downshift from "downshift";
|
import Downshift from "downshift";
|
||||||
import hotkeys from "hotkeys-js";
|
import hotkeys from "hotkeys-js";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
@ -33,6 +37,29 @@ function getItemOffset(
|
||||||
return cbs.reduce((acc, cb) => cb(actions).length + acc, 0);
|
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: {
|
||||||
|
height: 500,
|
||||||
|
maxWidth: 600,
|
||||||
|
outline: 0,
|
||||||
|
width: "100%"
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: "Navigator"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const Navigator: React.FC = () => {
|
const Navigator: React.FC = () => {
|
||||||
const [visible, setVisible] = React.useState(false);
|
const [visible, setVisible] = React.useState(false);
|
||||||
const input = React.useRef(null);
|
const input = React.useRef(null);
|
||||||
|
@ -43,6 +70,8 @@ const Navigator: React.FC = () => {
|
||||||
navigatorNotificationStorageKey,
|
navigatorNotificationStorageKey,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
const classes = useStyles({});
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
hotkeys(navigatorHotkey, event => {
|
hotkeys(navigatorHotkey, event => {
|
||||||
|
@ -78,90 +107,99 @@ const Navigator: React.FC = () => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Modal
|
||||||
|
className={classes.modal}
|
||||||
open={visible}
|
open={visible}
|
||||||
onClose={() => setVisible(false)}
|
onClose={() => setVisible(false)}
|
||||||
fullWidth
|
|
||||||
maxWidth="sm"
|
|
||||||
>
|
>
|
||||||
<Downshift
|
<Fade appear in={visible} timeout={theme.transitions.duration.short}>
|
||||||
itemToString={(item: QuickSearchAction) => (item ? item.label : "")}
|
<div className={classes.root}>
|
||||||
onSelect={(item: QuickSearchAction) => {
|
<Paper className={classes.paper}>
|
||||||
setVisible(false);
|
<Downshift
|
||||||
item.onClick();
|
itemToString={(item: QuickSearchAction) =>
|
||||||
}}
|
item ? item.label : ""
|
||||||
onInputValueChange={value =>
|
}
|
||||||
change({
|
onSelect={(item: QuickSearchAction) => {
|
||||||
target: {
|
const shouldRemainVisible = item.onClick();
|
||||||
name: "query",
|
if (!shouldRemainVisible) {
|
||||||
value
|
setVisible(false);
|
||||||
}
|
}
|
||||||
})
|
}}
|
||||||
}
|
onInputValueChange={value =>
|
||||||
defaultHighlightedIndex={0}
|
change({
|
||||||
>
|
target: {
|
||||||
{({ getInputProps, getItemProps, highlightedIndex }) => (
|
name: "query",
|
||||||
<div>
|
value
|
||||||
<NavigatorInput
|
}
|
||||||
mode={mode}
|
})
|
||||||
value={query}
|
}
|
||||||
{...getInputProps({
|
defaultHighlightedIndex={0}
|
||||||
value: query
|
>
|
||||||
})}
|
{({ getInputProps, getItemProps, highlightedIndex }) => (
|
||||||
ref={input}
|
<div>
|
||||||
/>
|
<NavigatorInput
|
||||||
{hasViews(actions) && (
|
mode={mode}
|
||||||
<NavigatorSection
|
value={query}
|
||||||
label={intl.formatMessage({
|
{...getInputProps({
|
||||||
defaultMessage: "Navigate to",
|
value: query
|
||||||
description: "navigator section header"
|
})}
|
||||||
})}
|
ref={input}
|
||||||
getItemProps={getItemProps}
|
/>
|
||||||
highlightedIndex={highlightedIndex}
|
{hasViews(actions) && (
|
||||||
items={getViews(actions)}
|
<NavigatorSection
|
||||||
offset={0}
|
label={intl.formatMessage({
|
||||||
/>
|
defaultMessage: "Navigate to",
|
||||||
)}
|
description: "navigator section header"
|
||||||
{hasActions(actions) && (
|
})}
|
||||||
<NavigatorSection
|
getItemProps={getItemProps}
|
||||||
label={intl.formatMessage({
|
highlightedIndex={highlightedIndex}
|
||||||
defaultMessage: "Quick Actions",
|
items={getViews(actions)}
|
||||||
description: "navigator section header"
|
offset={0}
|
||||||
})}
|
/>
|
||||||
getItemProps={getItemProps}
|
)}
|
||||||
highlightedIndex={highlightedIndex}
|
{hasActions(actions) && (
|
||||||
items={getActions(actions)}
|
<NavigatorSection
|
||||||
offset={getItemOffset(actions, [getViews])}
|
label={intl.formatMessage({
|
||||||
/>
|
defaultMessage: "Quick Actions",
|
||||||
)}
|
description: "navigator section header"
|
||||||
{hasCustomers(actions) && (
|
})}
|
||||||
<NavigatorSection
|
getItemProps={getItemProps}
|
||||||
label={intl.formatMessage({
|
highlightedIndex={highlightedIndex}
|
||||||
defaultMessage: "Search in Customers",
|
items={getActions(actions)}
|
||||||
description: "navigator section header"
|
offset={getItemOffset(actions, [getViews])}
|
||||||
})}
|
/>
|
||||||
getItemProps={getItemProps}
|
)}
|
||||||
highlightedIndex={highlightedIndex}
|
{hasCustomers(actions) && (
|
||||||
items={getCustomers(actions)}
|
<NavigatorSection
|
||||||
offset={getItemOffset(actions, [getViews, getActions])}
|
label={intl.formatMessage({
|
||||||
/>
|
defaultMessage: "Search in Customers",
|
||||||
)}
|
description: "navigator section header"
|
||||||
{hasCatalog(actions) && (
|
})}
|
||||||
<NavigatorSection
|
getItemProps={getItemProps}
|
||||||
label={intl.formatMessage({
|
highlightedIndex={highlightedIndex}
|
||||||
defaultMessage: "Search in Catalog",
|
items={getCustomers(actions)}
|
||||||
description: "navigator section header"
|
offset={getItemOffset(actions, [getViews, getActions])}
|
||||||
})}
|
/>
|
||||||
getItemProps={getItemProps}
|
)}
|
||||||
highlightedIndex={highlightedIndex}
|
{hasCatalog(actions) && (
|
||||||
items={getCatalog(actions)}
|
<NavigatorSection
|
||||||
offset={0}
|
label={intl.formatMessage({
|
||||||
/>
|
defaultMessage: "Search in Catalog",
|
||||||
)}
|
description: "navigator section header"
|
||||||
</div>
|
})}
|
||||||
)}
|
getItemProps={getItemProps}
|
||||||
</Downshift>
|
highlightedIndex={highlightedIndex}
|
||||||
</Dialog>
|
items={getCatalog(actions)}
|
||||||
|
offset={0}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Downshift>
|
||||||
|
</Paper>
|
||||||
|
</div>
|
||||||
|
</Fade>
|
||||||
|
</Modal>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,8 @@ const NavigatorInput = React.forwardRef<HTMLInputElement, NavigatorInputProps>(
|
||||||
? "@"
|
? "@"
|
||||||
: mode === "catalog"
|
: mode === "catalog"
|
||||||
? "$"
|
? "$"
|
||||||
|
: mode === "help"
|
||||||
|
? "?"
|
||||||
: ">"}
|
: ">"}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -33,14 +33,19 @@ const useStyles = makeStyles(
|
||||||
textTransform: "uppercase"
|
textTransform: "uppercase"
|
||||||
},
|
},
|
||||||
root: {
|
root: {
|
||||||
"&:not(:last-child)": {
|
"&:last-child": {
|
||||||
marginBottom: theme.spacing(3)
|
marginBottom: 0
|
||||||
},
|
},
|
||||||
margin: theme.spacing(2, 0),
|
margin: theme.spacing(2, 0),
|
||||||
padding: theme.spacing(0, 1)
|
padding: theme.spacing(0, 1)
|
||||||
},
|
},
|
||||||
spacer: {
|
spacer: {
|
||||||
flex: 1
|
flex: 1
|
||||||
|
},
|
||||||
|
symbol: {
|
||||||
|
display: "inline-block",
|
||||||
|
fontWeight: 600,
|
||||||
|
width: theme.spacing(4)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
|
@ -78,6 +83,9 @@ const NavigatorSection: React.FC<NavigatorSectionProps> = props => {
|
||||||
key={[item.label, item.type].join(":")}
|
key={[item.label, item.type].join(":")}
|
||||||
>
|
>
|
||||||
<span className={classes.itemLabel}>
|
<span className={classes.itemLabel}>
|
||||||
|
{item.symbol && (
|
||||||
|
<span className={classes.symbol}>{item.symbol}</span>
|
||||||
|
)}
|
||||||
<span>{item.label}</span>
|
<span>{item.label}</span>
|
||||||
{item.caption && (
|
{item.caption && (
|
||||||
<Typography variant="caption">{item.caption}</Typography>
|
<Typography variant="caption">{item.caption}</Typography>
|
||||||
|
|
|
@ -26,7 +26,10 @@ export function searchInCatalog(
|
||||||
.map<QuickSearchActionInput>(category => ({
|
.map<QuickSearchActionInput>(category => ({
|
||||||
caption: intl.formatMessage(messages.category),
|
caption: intl.formatMessage(messages.category),
|
||||||
label: category.name,
|
label: category.name,
|
||||||
onClick: () => navigate(categoryUrl(category.id)),
|
onClick: () => {
|
||||||
|
navigate(categoryUrl(category.id));
|
||||||
|
return false;
|
||||||
|
},
|
||||||
score: score(category.name, search),
|
score: score(category.name, search),
|
||||||
text: category.name,
|
text: category.name,
|
||||||
type: "catalog"
|
type: "catalog"
|
||||||
|
@ -45,7 +48,10 @@ export function searchInCatalog(
|
||||||
: messages.collectionUnpublished
|
: messages.collectionUnpublished
|
||||||
),
|
),
|
||||||
label: collection.name,
|
label: collection.name,
|
||||||
onClick: () => navigate(collectionUrl(collection.id)),
|
onClick: () => {
|
||||||
|
navigate(collectionUrl(collection.id));
|
||||||
|
return false;
|
||||||
|
},
|
||||||
score: score(collection.name, search),
|
score: score(collection.name, search),
|
||||||
text: collection.name,
|
text: collection.name,
|
||||||
type: "catalog"
|
type: "catalog"
|
||||||
|
@ -60,7 +66,10 @@ export function searchInCatalog(
|
||||||
caption: intl.formatMessage(messages.product),
|
caption: intl.formatMessage(messages.product),
|
||||||
extraInfo: product.category.name,
|
extraInfo: product.category.name,
|
||||||
label: product.name,
|
label: product.name,
|
||||||
onClick: () => navigate(productUrl(product.id)),
|
onClick: () => {
|
||||||
|
navigate(productUrl(product.id));
|
||||||
|
return false;
|
||||||
|
},
|
||||||
score: score(product.name, search),
|
score: score(product.name, search),
|
||||||
text: product.name,
|
text: product.name,
|
||||||
type: "catalog"
|
type: "catalog"
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
|
||||||
import { OrderDraftCreate } from "@saleor/orders/types/OrderDraftCreate";
|
import { OrderDraftCreate } from "@saleor/orders/types/OrderDraftCreate";
|
||||||
import { productAddUrl } from "@saleor/products/urls";
|
import { productAddUrl } from "@saleor/products/urls";
|
||||||
import { MutationFunction } from "react-apollo";
|
import { MutationFunction } from "react-apollo";
|
||||||
import { QuickSearchActionInput } from "../../types";
|
import { QuickSearchActionInput, QuickSearchMode } from "../../types";
|
||||||
import messages from "../messages";
|
import messages from "../messages";
|
||||||
import { sortScores } from "../utils";
|
import { sortScores } from "../utils";
|
||||||
|
|
||||||
|
@ -18,38 +18,64 @@ const maxActions = 5;
|
||||||
|
|
||||||
interface Command {
|
interface Command {
|
||||||
label: string;
|
label: string;
|
||||||
onClick: () => void;
|
onClick: () => boolean;
|
||||||
}
|
}
|
||||||
export function searchInCommands(
|
export function searchInCommands(
|
||||||
search: string,
|
search: string,
|
||||||
intl: IntlShape,
|
intl: IntlShape,
|
||||||
navigate: UseNavigatorResult,
|
navigate: UseNavigatorResult,
|
||||||
createOrder: MutationFunction<OrderDraftCreate, {}>
|
createOrder: MutationFunction<OrderDraftCreate, {}>,
|
||||||
|
setMode: (mode: QuickSearchMode) => void
|
||||||
): QuickSearchActionInput[] {
|
): QuickSearchActionInput[] {
|
||||||
const actions: Command[] = [
|
const actions: Command[] = [
|
||||||
{
|
{
|
||||||
label: intl.formatMessage(messages.addCategory),
|
label: intl.formatMessage(messages.addCategory),
|
||||||
onClick: () => navigate(categoryAddUrl())
|
onClick: () => {
|
||||||
|
navigate(categoryAddUrl());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: intl.formatMessage(messages.addCollection),
|
label: intl.formatMessage(messages.addCollection),
|
||||||
onClick: () => navigate(collectionAddUrl)
|
onClick: () => {
|
||||||
|
navigate(collectionAddUrl);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: intl.formatMessage(messages.addProduct),
|
label: intl.formatMessage(messages.addProduct),
|
||||||
onClick: () => navigate(productAddUrl)
|
onClick: () => {
|
||||||
|
navigate(productAddUrl);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: intl.formatMessage(messages.addCustomer),
|
label: intl.formatMessage(messages.addCustomer),
|
||||||
onClick: () => navigate(customerAddUrl)
|
onClick: () => {
|
||||||
|
navigate(customerAddUrl);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: intl.formatMessage(messages.addVoucher),
|
label: intl.formatMessage(messages.addVoucher),
|
||||||
onClick: () => navigate(voucherAddUrl)
|
onClick: () => {
|
||||||
|
navigate(voucherAddUrl);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: intl.formatMessage(messages.createOrder),
|
label: intl.formatMessage(messages.createOrder),
|
||||||
onClick: createOrder
|
onClick: () => {
|
||||||
|
createOrder();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: intl.formatMessage(messages.helpMode),
|
||||||
|
onClick: () => {
|
||||||
|
setMode("help");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -66,9 +92,10 @@ function getCommandModeActions(
|
||||||
query: string,
|
query: string,
|
||||||
intl: IntlShape,
|
intl: IntlShape,
|
||||||
navigate: UseNavigatorResult,
|
navigate: UseNavigatorResult,
|
||||||
createOrder: MutationFunction<OrderDraftCreate, {}>
|
createOrder: MutationFunction<OrderDraftCreate, {}>,
|
||||||
|
setMode: (mode: QuickSearchMode) => void
|
||||||
): QuickSearchActionInput[] {
|
): QuickSearchActionInput[] {
|
||||||
return [...searchInCommands(query, intl, navigate, createOrder)]
|
return [...searchInCommands(query, intl, navigate, createOrder, setMode)]
|
||||||
.filter(action => action.score >= threshold)
|
.filter(action => action.score >= threshold)
|
||||||
.sort(sortScores)
|
.sort(sortScores)
|
||||||
.slice(0, maxActions);
|
.slice(0, maxActions);
|
||||||
|
|
|
@ -20,7 +20,10 @@ export function searchInCustomers(
|
||||||
lastName: customer.lastName
|
lastName: customer.lastName
|
||||||
})
|
})
|
||||||
: customer.email,
|
: customer.email,
|
||||||
onClick: () => navigate(customerUrl(customer.id)),
|
onClick: () => {
|
||||||
|
navigate(customerUrl(customer.id));
|
||||||
|
return false;
|
||||||
|
},
|
||||||
score: 1,
|
score: 1,
|
||||||
type: "customer"
|
type: "customer"
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { IntlShape } from "react-intl";
|
||||||
|
|
||||||
import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
|
import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
|
||||||
import { OrderDraftCreate } from "@saleor/orders/types/OrderDraftCreate";
|
import { OrderDraftCreate } from "@saleor/orders/types/OrderDraftCreate";
|
||||||
import { QuickSearchAction } from "../../types";
|
import { QuickSearchAction, QuickSearchMode } from "../../types";
|
||||||
import { searchInCommands } from "../commands";
|
import { searchInCommands } from "../commands";
|
||||||
import { sortScores } from "../utils";
|
import { sortScores } from "../utils";
|
||||||
import searchInViews from "./views";
|
import searchInViews from "./views";
|
||||||
|
@ -15,11 +15,12 @@ function getDefaultModeActions(
|
||||||
query: string,
|
query: string,
|
||||||
intl: IntlShape,
|
intl: IntlShape,
|
||||||
navigate: UseNavigatorResult,
|
navigate: UseNavigatorResult,
|
||||||
createOrder: MutationFunction<OrderDraftCreate, {}>
|
createOrder: MutationFunction<OrderDraftCreate, {}>,
|
||||||
|
setMode: (mode: QuickSearchMode) => void
|
||||||
): QuickSearchAction[] {
|
): QuickSearchAction[] {
|
||||||
return [
|
return [
|
||||||
...searchInViews(query, intl, navigate),
|
...searchInViews(query, intl, navigate),
|
||||||
...searchInCommands(query, intl, navigate, createOrder)
|
...searchInCommands(query, intl, navigate, createOrder, setMode)
|
||||||
]
|
]
|
||||||
.filter(action => action.score >= threshold)
|
.filter(action => action.score >= threshold)
|
||||||
.sort(sortScores)
|
.sort(sortScores)
|
||||||
|
|
|
@ -121,7 +121,10 @@ function searchInViews(
|
||||||
|
|
||||||
return views.map(view => ({
|
return views.map(view => ({
|
||||||
label: view.label,
|
label: view.label,
|
||||||
onClick: () => navigate(view.url),
|
onClick: () => {
|
||||||
|
navigate(view.url);
|
||||||
|
return false;
|
||||||
|
},
|
||||||
score: score(view.label, search),
|
score: score(view.label, search),
|
||||||
text: view.label,
|
text: view.label,
|
||||||
type: "view"
|
type: "view"
|
||||||
|
|
79
src/components/Navigator/modes/help.ts
Normal file
79
src/components/Navigator/modes/help.ts
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
import { IntlShape } from "react-intl";
|
||||||
|
|
||||||
|
import { QuickSearchAction, QuickSearchMode } from "../types";
|
||||||
|
import messages from "./messages";
|
||||||
|
|
||||||
|
function getHelpModeActions(
|
||||||
|
query: string,
|
||||||
|
intl: IntlShape,
|
||||||
|
setMode: (mode: QuickSearchMode) => void
|
||||||
|
): QuickSearchAction[] {
|
||||||
|
if (query !== "") {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: intl.formatMessage(messages.noResults),
|
||||||
|
onClick: () => true,
|
||||||
|
type: "action"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: intl.formatMessage(messages.helpDefaultMode),
|
||||||
|
onClick: () => {
|
||||||
|
setMode("default");
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
symbol: "...",
|
||||||
|
type: "action"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: intl.formatMessage(messages.helpCommandsMode),
|
||||||
|
onClick: () => {
|
||||||
|
setMode("commands");
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
symbol: ">",
|
||||||
|
type: "action"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: intl.formatMessage(messages.helpOrdersMode),
|
||||||
|
onClick: () => {
|
||||||
|
setMode("orders");
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
symbol: "#",
|
||||||
|
type: "action"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: intl.formatMessage(messages.helpCustomersMode),
|
||||||
|
onClick: () => {
|
||||||
|
setMode("customers");
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
symbol: "@",
|
||||||
|
type: "action"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: intl.formatMessage(messages.helpCatalogMode),
|
||||||
|
onClick: () => {
|
||||||
|
setMode("catalog");
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
symbol: "$",
|
||||||
|
type: "action"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: intl.formatMessage(messages.helpMode),
|
||||||
|
onClick: () => {
|
||||||
|
setMode("help");
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
symbol: "?",
|
||||||
|
type: "action"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getHelpModeActions;
|
|
@ -8,6 +8,7 @@ import getCatalogModeActions from "./catalog";
|
||||||
import getCommandModeActions from "./commands";
|
import getCommandModeActions from "./commands";
|
||||||
import getCustomersModeActions from "./customers";
|
import getCustomersModeActions from "./customers";
|
||||||
import getDefaultModeActions from "./default";
|
import getDefaultModeActions from "./default";
|
||||||
|
import getHelpModeActions from "./help";
|
||||||
import getOrdersModeActions from "./orders";
|
import getOrdersModeActions from "./orders";
|
||||||
import { ActionQueries } from "./types";
|
import { ActionQueries } from "./types";
|
||||||
|
|
||||||
|
@ -17,21 +18,36 @@ function getModeActions(
|
||||||
intl: IntlShape,
|
intl: IntlShape,
|
||||||
queries: ActionQueries,
|
queries: ActionQueries,
|
||||||
cbs: {
|
cbs: {
|
||||||
navigate: UseNavigatorResult;
|
|
||||||
createOrder: MutationFunction<OrderDraftCreate, {}>;
|
createOrder: MutationFunction<OrderDraftCreate, {}>;
|
||||||
|
navigate: UseNavigatorResult;
|
||||||
|
setMode: (mode: QuickSearchMode) => void;
|
||||||
}
|
}
|
||||||
): QuickSearchAction[] {
|
): QuickSearchAction[] {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case "catalog":
|
case "catalog":
|
||||||
return getCatalogModeActions(query, intl, cbs.navigate, queries.catalog);
|
return getCatalogModeActions(query, intl, cbs.navigate, queries.catalog);
|
||||||
case "commands":
|
case "commands":
|
||||||
return getCommandModeActions(query, intl, cbs.navigate, cbs.createOrder);
|
return getCommandModeActions(
|
||||||
|
query,
|
||||||
|
intl,
|
||||||
|
cbs.navigate,
|
||||||
|
cbs.createOrder,
|
||||||
|
cbs.setMode
|
||||||
|
);
|
||||||
case "customers":
|
case "customers":
|
||||||
return getCustomersModeActions(intl, cbs.navigate, queries.customers);
|
return getCustomersModeActions(intl, cbs.navigate, queries.customers);
|
||||||
|
case "help":
|
||||||
|
return getHelpModeActions(query, intl, cbs.setMode);
|
||||||
case "orders":
|
case "orders":
|
||||||
return getOrdersModeActions(query, intl, cbs.navigate, queries.order);
|
return getOrdersModeActions(query, intl, cbs.navigate, queries.order);
|
||||||
default:
|
default:
|
||||||
return getDefaultModeActions(query, intl, cbs.navigate, cbs.createOrder);
|
return getDefaultModeActions(
|
||||||
|
query,
|
||||||
|
intl,
|
||||||
|
cbs.navigate,
|
||||||
|
cbs.createOrder,
|
||||||
|
cbs.setMode
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,33 @@ const messages = defineMessages({
|
||||||
defaultMessage: "Go to order #{orderNumber}",
|
defaultMessage: "Go to order #{orderNumber}",
|
||||||
description: "navigator action"
|
description: "navigator action"
|
||||||
},
|
},
|
||||||
|
helpCatalogMode: {
|
||||||
|
defaultMessage: "Search in Catalog",
|
||||||
|
description: "navigator catalog mode description"
|
||||||
|
},
|
||||||
|
helpCommandsMode: {
|
||||||
|
defaultMessage: "Search Command",
|
||||||
|
description: "navigator command mode description"
|
||||||
|
},
|
||||||
|
helpCustomersMode: {
|
||||||
|
defaultMessage: "Search Customers",
|
||||||
|
description: "navigator customer mode description"
|
||||||
|
},
|
||||||
|
helpDefaultMode: {
|
||||||
|
defaultMessage: "Search Views and Actions",
|
||||||
|
description: "navigator default mode description"
|
||||||
|
},
|
||||||
|
helpMode: {
|
||||||
|
defaultMessage: "Display Help",
|
||||||
|
description: "navigator help mode description"
|
||||||
|
},
|
||||||
|
helpOrdersMode: {
|
||||||
|
defaultMessage: "Search Orders",
|
||||||
|
description: "navigator order mode description"
|
||||||
|
},
|
||||||
|
noResults: {
|
||||||
|
defaultMessage: "No Results"
|
||||||
|
},
|
||||||
product: {
|
product: {
|
||||||
defaultMessage: "Product",
|
defaultMessage: "Product",
|
||||||
description: "catalog item type"
|
description: "catalog item type"
|
||||||
|
|
|
@ -30,7 +30,10 @@ function getOrdersModeActions(
|
||||||
label: intl.formatMessage(messages.goToOrder, {
|
label: intl.formatMessage(messages.goToOrder, {
|
||||||
orderNumber: query
|
orderNumber: query
|
||||||
}),
|
}),
|
||||||
onClick: () => navigate(orderUrl(gqlId)),
|
onClick: () => {
|
||||||
|
navigate(orderUrl(gqlId));
|
||||||
|
return false;
|
||||||
|
},
|
||||||
type: "action"
|
type: "action"
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
import { QuickSearchAction, QuickSearchActionInput } from "../types";
|
import {
|
||||||
|
QuickSearchAction,
|
||||||
|
QuickSearchActionInput,
|
||||||
|
QuickSearchMode
|
||||||
|
} from "../types";
|
||||||
|
|
||||||
export function getActions(actions: QuickSearchAction[]): QuickSearchAction[] {
|
export function getActions(actions: QuickSearchAction[]): QuickSearchAction[] {
|
||||||
return actions.filter(action => action.type === "action");
|
return actions.filter(action => action.type === "action");
|
||||||
|
@ -36,3 +40,21 @@ export function sortScores(
|
||||||
) {
|
) {
|
||||||
return a.score <= b.score ? 1 : -1;
|
return a.score <= b.score ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getMode(command: string): QuickSearchMode {
|
||||||
|
switch (command) {
|
||||||
|
case ">":
|
||||||
|
return "commands";
|
||||||
|
case "@":
|
||||||
|
return "customers";
|
||||||
|
case "#":
|
||||||
|
return "orders";
|
||||||
|
case "$":
|
||||||
|
return "catalog";
|
||||||
|
case "?":
|
||||||
|
return "help";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,8 +5,9 @@ export interface QuickSearchAction {
|
||||||
extraInfo?: string;
|
extraInfo?: string;
|
||||||
label: string;
|
label: string;
|
||||||
price?: number;
|
price?: number;
|
||||||
|
symbol?: string;
|
||||||
type: QuickSearchActionType;
|
type: QuickSearchActionType;
|
||||||
onClick: () => void;
|
onClick: () => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QuickSearchActionInput extends QuickSearchAction {
|
export interface QuickSearchActionInput extends QuickSearchAction {
|
||||||
|
@ -18,5 +19,6 @@ export type QuickSearchMode =
|
||||||
| "default"
|
| "default"
|
||||||
| "catalog"
|
| "catalog"
|
||||||
| "commands"
|
| "commands"
|
||||||
| "orders"
|
| "customers"
|
||||||
| "customers";
|
| "help"
|
||||||
|
| "orders";
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { orderUrl } from "@saleor/orders/urls";
|
||||||
import useCustomerSearch from "@saleor/searches/useCustomerSearch";
|
import useCustomerSearch from "@saleor/searches/useCustomerSearch";
|
||||||
import getModeActions from "./modes";
|
import getModeActions from "./modes";
|
||||||
import { getGqlOrderId, isQueryValidOrderNumber } from "./modes/orders";
|
import { getGqlOrderId, isQueryValidOrderNumber } from "./modes/orders";
|
||||||
|
import { getMode } from "./modes/utils";
|
||||||
import useSearchCatalog from "./queries/useCatalogSearch";
|
import useSearchCatalog from "./queries/useCatalogSearch";
|
||||||
import useCheckIfOrderExists from "./queries/useCheckIfOrderExists";
|
import useCheckIfOrderExists from "./queries/useCheckIfOrderExists";
|
||||||
import { QuickSearchAction, QuickSearchMode } from "./types";
|
import { QuickSearchAction, QuickSearchMode } from "./types";
|
||||||
|
@ -77,35 +78,23 @@ function useQuickSearch(
|
||||||
const change = (event: ChangeEvent) => {
|
const change = (event: ChangeEvent) => {
|
||||||
const value = event.target.value;
|
const value = event.target.value;
|
||||||
|
|
||||||
if (mode === "default") {
|
if (mode === "default" || mode === "help") {
|
||||||
switch (value) {
|
const newMode = getMode(value);
|
||||||
case "> ":
|
if (newMode) {
|
||||||
setMode("commands");
|
setMode(newMode);
|
||||||
break;
|
|
||||||
case "@ ":
|
|
||||||
setMode("customers");
|
|
||||||
break;
|
|
||||||
case "# ":
|
|
||||||
setMode("orders");
|
|
||||||
break;
|
|
||||||
case "$ ":
|
|
||||||
setMode("catalog");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
setQuery(value);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (mode === "orders" && isQueryValidOrderNumber(value)) {
|
|
||||||
getOrderData(getGqlOrderId(value));
|
|
||||||
}
|
|
||||||
if (mode === "catalog") {
|
|
||||||
searchCatalog(value);
|
|
||||||
}
|
|
||||||
if (mode === "customers") {
|
|
||||||
searchCustomers(value);
|
|
||||||
}
|
|
||||||
setQuery(value);
|
|
||||||
}
|
}
|
||||||
|
if (mode === "orders" && isQueryValidOrderNumber(value)) {
|
||||||
|
getOrderData(getGqlOrderId(value));
|
||||||
|
}
|
||||||
|
if (mode === "catalog") {
|
||||||
|
searchCatalog(value);
|
||||||
|
}
|
||||||
|
if (mode === "customers") {
|
||||||
|
searchCustomers(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
setQuery(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
@ -126,7 +115,8 @@ function useQuickSearch(
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
createOrder,
|
createOrder,
|
||||||
navigate
|
navigate,
|
||||||
|
setMode
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in a new issue