commit
76becb234d
50 changed files with 2170 additions and 389 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -13,6 +13,7 @@
|
|||
!.nvmrc
|
||||
!.npmrc
|
||||
!.plop
|
||||
!.prettierignore
|
||||
!.pylintrc
|
||||
!.travis*
|
||||
!.testcafe
|
||||
|
|
1
.prettierignore
Normal file
1
.prettierignore
Normal file
|
@ -0,0 +1 @@
|
|||
types/
|
|
@ -13,6 +13,7 @@ All notable, unreleased changes to this project will be documented in this file.
|
|||
- Fix disappearing products description - #259 by @dominik-zeglen
|
||||
- Improve mobile appearance - #240 by @benekex2 and @dominik-zeglen
|
||||
- Use searches as hooks instead of components - #262 by @dominik-zeglen
|
||||
- Add navigator - #267 by @dominik-zeglen
|
||||
|
||||
## 2.0.0
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2019-11-13T13:13:30.128Z\n"
|
||||
"POT-Creation-Date: 2019-11-26T14:34:48.426Z\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -167,14 +167,6 @@ msgctxt "page header"
|
|||
msgid "Add Collection"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/customers/components/CustomerCreatePage/CustomerCreatePage.json
|
||||
#. [src.customers.components.CustomerCreatePage.2622255457] - page header
|
||||
#. defaultMessage is:
|
||||
#. Add Customer
|
||||
msgctxt "page header"
|
||||
msgid "Add Customer"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Filter/Filter.json
|
||||
#. [src.components.Filter.2852521946] - button
|
||||
#. defaultMessage is:
|
||||
|
@ -263,14 +255,6 @@ msgctxt "button"
|
|||
msgid "Add authentication"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/customers/components/CustomerListPage/CustomerListPage.json
|
||||
#. [src.customers.components.CustomerListPage.1934221653] - button
|
||||
#. defaultMessage is:
|
||||
#. Add customer
|
||||
msgctxt "button"
|
||||
msgid "Add customer"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Filter/FilterContent.json
|
||||
#. [src.components.Filter.2851720415] - button
|
||||
#. defaultMessage is:
|
||||
|
@ -856,21 +840,9 @@ msgid "Are you sure you want to delete {counter,plural,one{this attribute} other
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/categories/views/CategoryDetails.json
|
||||
#. [src.categories.views.982216972]
|
||||
#. [src.categories.views.1592907702]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this attribute} other{{displayQuantity} categories}}?
|
||||
msgctxt "description"
|
||||
msgid "Are you sure you want to delete {counter,plural,one{this attribute} other{{displayQuantity} categories}}?"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/categories/views/CategoryDetails.json
|
||||
#. [src.categories.views.3920301974]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this attribute} other{{displayQuantity} products}}?
|
||||
msgctxt "description"
|
||||
msgid "Are you sure you want to delete {counter,plural,one{this attribute} other{{displayQuantity} products}}?"
|
||||
msgstr ""
|
||||
|
||||
#. Are you sure you want to delete {counter,plural,one{this category} other{{displayQuantity} categories}}?
|
||||
#: build/locale/src/categories/views/CategoryList/CategoryList.json
|
||||
#. [src.categories.views.CategoryList.1592907702]
|
||||
#. defaultMessage is:
|
||||
|
@ -927,6 +899,14 @@ msgctxt "dialog content"
|
|||
msgid "Are you sure you want to delete {counter,plural,one{this product type} other{{displayQuantity} product types}}?"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/categories/views/CategoryDetails.json
|
||||
#. [src.categories.views.785143617]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this product} other{{displayQuantity} products}}?
|
||||
msgctxt "description"
|
||||
msgid "Are you sure you want to delete {counter,plural,one{this product} other{{displayQuantity} products}}?"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/products/views/ProductList/ProductList.json
|
||||
#. [src.products.views.ProductList.785143617] - dialog content
|
||||
#. defaultMessage is:
|
||||
|
@ -1803,6 +1783,10 @@ msgctxt "number of categories"
|
|||
msgid "Categories ({quantity})"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.category]
|
||||
#. defaultMessage is:
|
||||
#. Category
|
||||
#: build/locale/src/products/components/ProductCategoryAndCollectionsForm/ProductCategoryAndCollectionsForm.json
|
||||
#. [src.products.components.ProductCategoryAndCollectionsForm.1755013298]
|
||||
#. defaultMessage is:
|
||||
|
@ -1967,6 +1951,14 @@ msgctxt "voucher code"
|
|||
msgid "Code"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.collection]
|
||||
#. defaultMessage is:
|
||||
#. Collection
|
||||
msgctxt "description"
|
||||
msgid "Collection"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/translations/components/TranslationsCollectionsPage/TranslationsCollectionsPage.json
|
||||
#. [src.translations.components.TranslationsCollectionsPage.2759199473]
|
||||
#. defaultMessage is:
|
||||
|
@ -2347,6 +2339,38 @@ msgctxt "create service token, button"
|
|||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.createCategory] - button
|
||||
#. defaultMessage is:
|
||||
#. Create Category
|
||||
msgctxt "button"
|
||||
msgid "Create Category"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.createCollection] - button
|
||||
#. defaultMessage is:
|
||||
#. Create Collection
|
||||
msgctxt "button"
|
||||
msgid "Create Collection"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.createCustomer] - button
|
||||
#. defaultMessage is:
|
||||
#. Create Customer
|
||||
msgctxt "button"
|
||||
msgid "Create Customer"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/customers/components/CustomerCreatePage/CustomerCreatePage.json
|
||||
#. [src.customers.components.CustomerCreatePage.4025686004] - page header
|
||||
#. defaultMessage is:
|
||||
#. Create Customer
|
||||
msgctxt "page header"
|
||||
msgid "Create Customer"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/navigation/components/MenuCreateDialog/MenuCreateDialog.json
|
||||
#. [menuCreateDialogHeader] - dialog header
|
||||
#. defaultMessage is:
|
||||
|
@ -2395,6 +2419,14 @@ msgctxt "header"
|
|||
msgid "Create New Shipping Zone"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.createOrder] - button
|
||||
#. defaultMessage is:
|
||||
#. Create Order
|
||||
msgctxt "button"
|
||||
msgid "Create Order"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/pages/components/PageDetailsPage/PageDetailsPage.json
|
||||
#. [src.pages.components.PageDetailsPage.1068617485] - page header
|
||||
#. defaultMessage is:
|
||||
|
@ -2411,14 +2443,10 @@ msgctxt "header"
|
|||
msgid "Create Page"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/orders/components/OrderProductAddDialog/OrderProductAddDialog.json
|
||||
#. [src.orders.components.OrderProductAddDialog.1542417144] - dialog header
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.createProduct] - button
|
||||
#. defaultMessage is:
|
||||
#. Create Product
|
||||
msgctxt "dialog header"
|
||||
msgid "Create Product"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/products/components/ProductListPage/ProductListPage.json
|
||||
#. [src.products.components.ProductListPage.1542417144] - button
|
||||
#. defaultMessage is:
|
||||
|
@ -2427,6 +2455,14 @@ msgctxt "button"
|
|||
msgid "Create Product"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/orders/components/OrderProductAddDialog/OrderProductAddDialog.json
|
||||
#. [src.orders.components.OrderProductAddDialog.1542417144] - dialog header
|
||||
#. defaultMessage is:
|
||||
#. Create Product
|
||||
msgctxt "dialog header"
|
||||
msgid "Create Product"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/products/views/ProductCreate.json
|
||||
#. [src.products.views.1542417144] - window title
|
||||
#. defaultMessage is:
|
||||
|
@ -2499,6 +2535,14 @@ msgctxt "header"
|
|||
msgid "Create Variant"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.createVoucher] - button
|
||||
#. defaultMessage is:
|
||||
#. Create Voucher
|
||||
msgctxt "button"
|
||||
msgid "Create Voucher"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/discounts/components/VoucherCreatePage/VoucherCreatePage.json
|
||||
#. [src.discounts.components.VoucherCreatePage.1357216572] - page header
|
||||
#. defaultMessage is:
|
||||
|
@ -2571,6 +2615,14 @@ msgctxt "window title"
|
|||
msgid "Create collection"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/customers/components/CustomerListPage/CustomerListPage.json
|
||||
#. [src.customers.components.CustomerListPage.2859116187] - button
|
||||
#. defaultMessage is:
|
||||
#. Create customer
|
||||
msgctxt "button"
|
||||
msgid "Create customer"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/customers/views/CustomerCreate.json
|
||||
#. [src.customers.views.2859116187] - window title
|
||||
#. defaultMessage is:
|
||||
|
@ -3451,6 +3503,14 @@ msgctxt "description"
|
|||
msgid "Discounts"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.helpMode] - navigator help mode description
|
||||
#. defaultMessage is:
|
||||
#. Display Help
|
||||
msgctxt "navigator help mode description"
|
||||
msgid "Display Help"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/taxes/components/CountryTaxesPage/CountryTaxesPage.json
|
||||
#. [src.taxes.components.CountryTaxesPage.3500730003] - tax rate
|
||||
#. defaultMessage is:
|
||||
|
@ -4047,6 +4107,14 @@ msgctxt "button"
|
|||
msgid "Go back to dashboard"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.goToOrder] - navigator action
|
||||
#. defaultMessage is:
|
||||
#. Go to order #{orderNumber}
|
||||
msgctxt "navigator action"
|
||||
msgid "Go to order #{orderNumber}"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/home/components/HomeHeader/HomeHeader.json
|
||||
#. [homeHeaderText] - header
|
||||
#. defaultMessage is:
|
||||
|
@ -4811,6 +4879,14 @@ msgctxt "description"
|
|||
msgid "Name of your store is shown on tab in web browser"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/Navigator.json
|
||||
#. [src.components.Navigator.3060198201] - navigator section header
|
||||
#. defaultMessage is:
|
||||
#. Navigate to
|
||||
msgctxt "navigator section header"
|
||||
msgid "Navigate to"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/intl.json
|
||||
#. [src.navigation] - navigation section name
|
||||
#. defaultMessage is:
|
||||
|
@ -4819,6 +4895,14 @@ msgctxt "navigation section name"
|
|||
msgid "Navigation"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/Navigator.json
|
||||
#. [src.components.Navigator.4290208300] - navigator notification title
|
||||
#. defaultMessage is:
|
||||
#. Navigator is here to help
|
||||
msgctxt "navigator notification title"
|
||||
msgid "Navigator is here to help"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/auth/components/NewPasswordPage/NewPasswordPage.json
|
||||
#. [src.auth.components.NewPasswordPage.1254879564]
|
||||
#. defaultMessage is:
|
||||
|
@ -4875,6 +4959,14 @@ msgctxt "description"
|
|||
msgid "No Products added to Order"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.noResults]
|
||||
#. defaultMessage is:
|
||||
#. No Results
|
||||
msgctxt "description"
|
||||
msgid "No Results"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/home/components/HomeActivityCard/HomeActivityCard.json
|
||||
#. [homeActivityCardNoActivities]
|
||||
#. defaultMessage is:
|
||||
|
@ -5315,6 +5407,14 @@ msgctxt "voucher has no requirements"
|
|||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.collectionUnpublished] - collection
|
||||
#. defaultMessage is:
|
||||
#. Not Published
|
||||
msgctxt "collection"
|
||||
msgid "Not Published"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/pages/components/PageList/PageList.json
|
||||
#. [src.pages.components.PageList.3767550649] - page status
|
||||
#. defaultMessage is:
|
||||
|
@ -5511,6 +5611,14 @@ msgctxt "description"
|
|||
msgid "Order History"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/NavigatorInput.json
|
||||
#. [src.components.Navigator.1116468870] - navigator placeholder
|
||||
#. defaultMessage is:
|
||||
#. Order Number
|
||||
msgctxt "navigator placeholder"
|
||||
msgid "Order Number"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/orders/components/OrderListFilter/OrderListFilter.json
|
||||
#. [src.orders.components.OrderListFilter.2222765704]
|
||||
#. defaultMessage is:
|
||||
|
@ -5715,6 +5823,14 @@ msgctxt "description"
|
|||
msgid "Original String"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/Navigator.json
|
||||
#. [src.components.Navigator.3384551821] - navigator notification
|
||||
#. defaultMessage is:
|
||||
#. Our new feature to help you with your daily tasks. Run Navigator using {keyboardShortcut} shortcut.
|
||||
msgctxt "navigator notification"
|
||||
msgid "Our new feature to help you with your daily tasks. Run Navigator using {keyboardShortcut} shortcut."
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/products/components/ProductListFilter/ProductListFilter.json
|
||||
#. [src.products.components.ProductListFilter.1640493122] - product status
|
||||
#. defaultMessage is:
|
||||
|
@ -6251,6 +6367,10 @@ msgctxt "page header"
|
|||
msgid "Primary Address"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.product]
|
||||
#. defaultMessage is:
|
||||
#. Product
|
||||
#: build/locale/src/orders/components/OrderDraftDetailsProducts/OrderDraftDetailsProducts.json
|
||||
#. [src.orders.components.OrderDraftDetailsProducts.1895667608]
|
||||
#. defaultMessage is:
|
||||
|
@ -6599,6 +6719,14 @@ msgctxt "product is published"
|
|||
msgid "Published"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.collectionPublished] - collection
|
||||
#. defaultMessage is:
|
||||
#. Published
|
||||
msgctxt "collection"
|
||||
msgid "Published"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/pages/components/PageList/PageList.json
|
||||
#. [src.pages.components.PageList.3640454975] - page status
|
||||
#. defaultMessage is:
|
||||
|
@ -6655,6 +6783,14 @@ msgctxt "ordered products"
|
|||
msgid "Quantity"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/Navigator.json
|
||||
#. [src.components.Navigator.3636839115] - navigator section header
|
||||
#. defaultMessage is:
|
||||
#. Quick Actions
|
||||
msgctxt "navigator section header"
|
||||
msgid "Quick Actions"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/shipping/components/ShippingZoneCountriesAssignDialog/ShippingZoneCountriesAssignDialog.json
|
||||
#. [src.shipping.components.ShippingZoneCountriesAssignDialog.1440682557]
|
||||
#. defaultMessage is:
|
||||
|
@ -7043,6 +7179,14 @@ msgctxt "description"
|
|||
msgid "Search Collection"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.helpCommandsMode] - navigator command mode description
|
||||
#. defaultMessage is:
|
||||
#. Search Command
|
||||
msgctxt "navigator command mode description"
|
||||
msgid "Search Command"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/shipping/components/ShippingZoneCountriesAssignDialog/ShippingZoneCountriesAssignDialog.json
|
||||
#. [src.shipping.components.ShippingZoneCountriesAssignDialog.3510295703]
|
||||
#. defaultMessage is:
|
||||
|
@ -7051,6 +7195,14 @@ msgctxt "description"
|
|||
msgid "Search Countries"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/NavigatorInput.json
|
||||
#. [src.components.Navigator.1643417013] - navigator placeholder
|
||||
#. defaultMessage is:
|
||||
#. Search Customer
|
||||
msgctxt "navigator placeholder"
|
||||
msgid "Search Customer"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/customers/components/CustomerListPage/CustomerListPage.json
|
||||
#. [src.customers.components.CustomerListPage.1643417013]
|
||||
#. defaultMessage is:
|
||||
|
@ -7059,6 +7211,14 @@ msgctxt "description"
|
|||
msgid "Search Customer"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.helpCustomersMode] - navigator customer mode description
|
||||
#. defaultMessage is:
|
||||
#. Search Customers
|
||||
msgctxt "navigator customer mode description"
|
||||
msgid "Search Customers"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/orders/components/OrderCustomer/OrderCustomer.json
|
||||
#. [src.orders.components.OrderCustomer.2433460203]
|
||||
#. defaultMessage is:
|
||||
|
@ -7147,6 +7307,14 @@ msgctxt "save search tab"
|
|||
msgid "Search Name"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.helpOrdersMode] - navigator order mode description
|
||||
#. defaultMessage is:
|
||||
#. Search Orders
|
||||
msgctxt "navigator order mode description"
|
||||
msgid "Search Orders"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/orders/components/OrderListPage/OrderListPage.json
|
||||
#. [src.orders.components.OrderListPage.355376157]
|
||||
#. defaultMessage is:
|
||||
|
@ -7231,6 +7399,14 @@ msgctxt "description"
|
|||
msgid "Search Staff Member"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.helpDefaultMode] - navigator default mode description
|
||||
#. defaultMessage is:
|
||||
#. Search Views and Actions
|
||||
msgctxt "navigator default mode description"
|
||||
msgid "Search Views and Actions"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/discounts/components/VoucherListPage/VoucherListPage.json
|
||||
#. [src.discounts.components.VoucherListPage.1930485532]
|
||||
#. defaultMessage is:
|
||||
|
@ -7319,6 +7495,38 @@ msgctxt "description"
|
|||
msgid "Search engine title"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.helpCatalogMode] - navigator catalog mode description
|
||||
#. defaultMessage is:
|
||||
#. Search in Catalog
|
||||
msgctxt "navigator catalog mode description"
|
||||
msgid "Search in Catalog"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/Navigator.json
|
||||
#. [src.components.Navigator.2935523260] - navigator section header
|
||||
#. defaultMessage is:
|
||||
#. Search in Catalog
|
||||
msgctxt "navigator section header"
|
||||
msgid "Search in Catalog"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/NavigatorInput.json
|
||||
#. [src.components.Navigator.2935523260] - navigator placeholder
|
||||
#. defaultMessage is:
|
||||
#. Search in Catalog
|
||||
msgctxt "navigator placeholder"
|
||||
msgid "Search in Catalog"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/Navigator.json
|
||||
#. [src.components.Navigator.1809988825] - navigator section header
|
||||
#. defaultMessage is:
|
||||
#. Search in Customers
|
||||
msgctxt "navigator section header"
|
||||
msgid "Search in Customers"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/attributes/components/AttributeList/AttributeList.json
|
||||
#. [src.attributes.components.AttributeList.2235596452] - attribute can be searched in dashboard
|
||||
#. defaultMessage is:
|
||||
|
@ -8603,6 +8811,14 @@ msgctxt "product type is either simple or configurable"
|
|||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/NavigatorInput.json
|
||||
#. [src.components.Navigator.1167695965] - navigator placeholder
|
||||
#. defaultMessage is:
|
||||
#. Type Command
|
||||
msgctxt "navigator placeholder"
|
||||
msgid "Type Command"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/productTypes/components/ProductTypeList/ProductTypeList.json
|
||||
#. [src.productTypes.components.ProductTypeList.2253986440] - product type name
|
||||
#. defaultMessage is:
|
||||
|
@ -8611,6 +8827,14 @@ msgctxt "product type name"
|
|||
msgid "Type Name"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/NavigatorInput.json
|
||||
#. [src.components.Navigator.2874620973] - navigator placeholder
|
||||
#. defaultMessage is:
|
||||
#. Type {key} to see available actions
|
||||
msgctxt "navigator placeholder"
|
||||
msgid "Type {key} to see available actions"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/pages/components/PageSlug/PageSlug.json
|
||||
#. [src.pages.components.PageSlug.1324178587]
|
||||
#. defaultMessage is:
|
||||
|
@ -9715,6 +9939,14 @@ msgctxt "translation progress"
|
|||
msgid "{current} of {max}"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/Navigator/modes/messages.json
|
||||
#. [src.components.Navigator.modes.customerWithName]
|
||||
#. defaultMessage is:
|
||||
#. {firstName} {lastName}
|
||||
msgctxt "description"
|
||||
msgid "{firstName} {lastName}"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/components/MoneyRange/MoneyRange.json
|
||||
#. [src.components.MoneyRange.1316359951] - money
|
||||
#. defaultMessage is:
|
||||
|
|
13
package-lock.json
generated
13
package-lock.json
generated
|
@ -3286,6 +3286,11 @@
|
|||
"integrity": "sha512-YesPanU1+WCigC/Aj1Mga8UCOjHIfMNHZ3zzDsUY7lI8GlKnh/Kv2QwJOQ+jNQ36Ru7IfzSedlG14hppYaN13A==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/semver-compare": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/semver-compare/-/semver-compare-1.0.1.tgz",
|
||||
"integrity": "sha512-wx2LQVvKlEkhXp/HoKIZ/aSL+TvfJdKco8i0xJS3aR877mg4qBHzNT6+B5a61vewZHo79EdZavskGnRXEC2H6A=="
|
||||
},
|
||||
"@types/shallowequal": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/shallowequal/-/shallowequal-1.1.1.tgz",
|
||||
|
@ -11333,6 +11338,11 @@
|
|||
"integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==",
|
||||
"dev": true
|
||||
},
|
||||
"hotkeys-js": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/hotkeys-js/-/hotkeys-js-3.7.2.tgz",
|
||||
"integrity": "sha512-LJIPBgejlklphThig2edlYUiPq3iFDHdsXftvZ0VWrpi330dRwD2YxPlzOYv0UQEatvZdgwG3ZLCfJ020ix8vQ=="
|
||||
},
|
||||
"hpack.js": {
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
|
||||
|
@ -18050,8 +18060,7 @@
|
|||
"semver-compare": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
|
||||
"integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
|
||||
"dev": true
|
||||
"integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w="
|
||||
},
|
||||
"send": {
|
||||
"version": "0.17.1",
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
"fuzzaldrin": "^2.1.0",
|
||||
"graphql": "^14.4.2",
|
||||
"graphql-tag": "^2.10.1",
|
||||
"hotkeys-js": "^3.7.2",
|
||||
"is-url": "^1.2.4",
|
||||
"jss": "^9.8.7",
|
||||
"keycode": "^2.2.0",
|
||||
|
@ -62,6 +63,7 @@
|
|||
"react-sortable-hoc": "^0.6.8",
|
||||
"react-sortable-tree": "^2.6.2",
|
||||
"react-svg": "^2.2.11",
|
||||
"semver-compare": "^1.0.0",
|
||||
"slugify": "^1.3.4",
|
||||
"typescript": "^3.6.4",
|
||||
"url-join": "^4.0.1",
|
||||
|
@ -97,6 +99,7 @@
|
|||
"@types/react-sortable-hoc": "^0.6.5",
|
||||
"@types/react-sortable-tree": "^0.3.6",
|
||||
"@types/react-test-renderer": "^16.8.2",
|
||||
"@types/semver-compare": "^1.0.1",
|
||||
"@types/storybook__addon-storyshots": "^3.4.9",
|
||||
"@types/storybook__react": "^4.0.2",
|
||||
"@types/url-join": "^0.8.3",
|
||||
|
|
206
src/components/Navigator/Navigator.tsx
Normal file
206
src/components/Navigator/Navigator.tsx
Normal file
|
@ -0,0 +1,206 @@
|
|||
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 hotkeys from "hotkeys-js";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
import cmp from "semver-compare";
|
||||
|
||||
import { APP_VERSION } from "@saleor/config";
|
||||
import useLocalStorage from "@saleor/hooks/useLocalStorage";
|
||||
import useNotifier from "@saleor/hooks/useNotifier";
|
||||
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: {
|
||||
height: 500,
|
||||
maxWidth: 600,
|
||||
outline: 0,
|
||||
width: "100%"
|
||||
}
|
||||
}),
|
||||
{
|
||||
name: "Navigator"
|
||||
}
|
||||
);
|
||||
|
||||
const Navigator: React.FC = () => {
|
||||
const [visible, setVisible] = React.useState(false);
|
||||
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();
|
||||
setVisible(!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={() => setVisible(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) {
|
||||
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>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navigator;
|
112
src/components/Navigator/NavigatorInput.tsx
Normal file
112
src/components/Navigator/NavigatorInput.tsx
Normal file
|
@ -0,0 +1,112 @@
|
|||
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
import { QuickSearchMode } from "./types";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => {
|
||||
const typography = {
|
||||
color: theme.palette.text.primary,
|
||||
fontSize: 24,
|
||||
lineHeight: 1.33
|
||||
};
|
||||
|
||||
return {
|
||||
adornment: {
|
||||
...typography,
|
||||
color: theme.palette.text.secondary,
|
||||
paddingRight: theme.spacing(1)
|
||||
},
|
||||
input: {
|
||||
...typography,
|
||||
background: "transparent",
|
||||
border: "none",
|
||||
outline: 0,
|
||||
padding: 0,
|
||||
width: "100%"
|
||||
},
|
||||
root: {
|
||||
background: theme.palette.background.default,
|
||||
display: "flex",
|
||||
padding: theme.spacing(2, 3)
|
||||
}
|
||||
};
|
||||
},
|
||||
{
|
||||
name: "NavigatorInput"
|
||||
}
|
||||
);
|
||||
|
||||
interface NavigatorInputProps
|
||||
extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||
mode: QuickSearchMode;
|
||||
}
|
||||
|
||||
const NavigatorInput = React.forwardRef<HTMLInputElement, NavigatorInputProps>(
|
||||
(props, ref) => {
|
||||
const { mode, ...rest } = props;
|
||||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
{mode !== "default" && (
|
||||
<span className={classes.adornment}>
|
||||
{mode === "orders"
|
||||
? "#"
|
||||
: mode === "customers"
|
||||
? "@"
|
||||
: mode === "catalog"
|
||||
? "$"
|
||||
: mode === "help"
|
||||
? "?"
|
||||
: ">"}
|
||||
</span>
|
||||
)}
|
||||
<input
|
||||
autoFocus
|
||||
autoComplete="off"
|
||||
className={classes.input}
|
||||
placeholder={
|
||||
mode === "orders"
|
||||
? intl.formatMessage({
|
||||
defaultMessage: "Order Number",
|
||||
description: "navigator placeholder"
|
||||
})
|
||||
: mode === "commands"
|
||||
? intl.formatMessage({
|
||||
defaultMessage: "Type Command",
|
||||
description: "navigator placeholder"
|
||||
})
|
||||
: mode === "catalog"
|
||||
? intl.formatMessage({
|
||||
defaultMessage: "Search in Catalog",
|
||||
description: "navigator placeholder"
|
||||
})
|
||||
: mode === "customers"
|
||||
? intl.formatMessage({
|
||||
defaultMessage: "Search Customer",
|
||||
description: "navigator placeholder"
|
||||
})
|
||||
: mode === "default"
|
||||
? intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "Type {key} to see available actions",
|
||||
description: "navigator placeholder"
|
||||
},
|
||||
{
|
||||
key: "'?'"
|
||||
}
|
||||
)
|
||||
: null
|
||||
}
|
||||
ref={ref}
|
||||
{...rest}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
NavigatorInput.displayName = "NavigatorInput";
|
||||
export default NavigatorInput;
|
104
src/components/Navigator/NavigatorSection.tsx
Normal file
104
src/components/Navigator/NavigatorSection.tsx
Normal file
|
@ -0,0 +1,104 @@
|
|||
import MenuItem from "@material-ui/core/MenuItem";
|
||||
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { GetItemPropsOptions } from "downshift";
|
||||
import React from "react";
|
||||
|
||||
import Hr from "../Hr";
|
||||
import { QuickSearchAction } from "./types";
|
||||
|
||||
interface NavigatorSectionProps {
|
||||
getItemProps: (options: GetItemPropsOptions) => any;
|
||||
highlightedIndex: number;
|
||||
label: string;
|
||||
items: QuickSearchAction[];
|
||||
offset: number;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
item: {
|
||||
"&&&&": {
|
||||
color: theme.palette.text.secondary,
|
||||
fontWeight: 400
|
||||
},
|
||||
display: "flex",
|
||||
margin: theme.spacing(1, 0)
|
||||
},
|
||||
itemLabel: {
|
||||
display: "inline-block"
|
||||
},
|
||||
label: {
|
||||
paddingLeft: theme.spacing(2),
|
||||
textTransform: "uppercase"
|
||||
},
|
||||
root: {
|
||||
"&:last-child": {
|
||||
marginBottom: 0
|
||||
},
|
||||
margin: theme.spacing(2, 0),
|
||||
padding: theme.spacing(0, 1)
|
||||
},
|
||||
spacer: {
|
||||
flex: 1
|
||||
},
|
||||
symbol: {
|
||||
display: "inline-block",
|
||||
fontWeight: 600,
|
||||
width: theme.spacing(4)
|
||||
}
|
||||
}),
|
||||
{
|
||||
name: "NavigatorSection"
|
||||
}
|
||||
);
|
||||
|
||||
const NavigatorSection: React.FC<NavigatorSectionProps> = props => {
|
||||
const { getItemProps, highlightedIndex, label, items, offset } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<Typography
|
||||
className={classes.label}
|
||||
variant="body2"
|
||||
color="textSecondary"
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
<Hr />
|
||||
{items.map((item, itemIndex) => {
|
||||
const index = offset + itemIndex;
|
||||
const itemProps = getItemProps({
|
||||
index,
|
||||
item
|
||||
});
|
||||
|
||||
return (
|
||||
<MenuItem
|
||||
{...itemProps}
|
||||
className={classes.item}
|
||||
selected={highlightedIndex === index}
|
||||
key={[item.label, item.type].join(":")}
|
||||
>
|
||||
<span className={classes.itemLabel}>
|
||||
{item.symbol && (
|
||||
<span className={classes.symbol}>{item.symbol}</span>
|
||||
)}
|
||||
<span>{item.label}</span>
|
||||
{item.caption && (
|
||||
<Typography variant="caption">{item.caption}</Typography>
|
||||
)}
|
||||
</span>
|
||||
<span className={classes.spacer} />
|
||||
{item.extraInfo}
|
||||
</MenuItem>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
NavigatorSection.displayName = "NavigatorSection";
|
||||
export default NavigatorSection;
|
2
src/components/Navigator/index.ts
Normal file
2
src/components/Navigator/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export { default } from "./Navigator";
|
||||
export * from "./Navigator";
|
102
src/components/Navigator/modes/catalog.ts
Normal file
102
src/components/Navigator/modes/catalog.ts
Normal file
|
@ -0,0 +1,102 @@
|
|||
import { score } from "fuzzaldrin";
|
||||
import { IntlShape } from "react-intl";
|
||||
|
||||
import { categoryUrl } from "@saleor/categories/urls";
|
||||
import { collectionUrl } from "@saleor/collections/urls";
|
||||
import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
|
||||
import { maybe } from "@saleor/misc";
|
||||
import { productUrl } from "@saleor/products/urls";
|
||||
import { SearchCatalog } from "../queries/types/SearchCatalog";
|
||||
import { QuickSearchAction, QuickSearchActionInput } from "../types";
|
||||
import messages from "./messages";
|
||||
import { sortScores } from "./utils";
|
||||
|
||||
const maxActions = 5;
|
||||
|
||||
export function searchInCatalog(
|
||||
search: string,
|
||||
intl: IntlShape,
|
||||
navigate: UseNavigatorResult,
|
||||
catalog: SearchCatalog
|
||||
): QuickSearchAction[] {
|
||||
const categories: QuickSearchActionInput[] = maybe(
|
||||
() => catalog.categories.edges.map(edge => edge.node),
|
||||
[]
|
||||
)
|
||||
.map<QuickSearchActionInput>(category => ({
|
||||
caption: intl.formatMessage(messages.category),
|
||||
label: category.name,
|
||||
onClick: () => {
|
||||
navigate(categoryUrl(category.id));
|
||||
return false;
|
||||
},
|
||||
score: score(category.name, search),
|
||||
text: category.name,
|
||||
type: "catalog"
|
||||
}))
|
||||
.sort(sortScores);
|
||||
|
||||
const collections: QuickSearchActionInput[] = maybe(
|
||||
() => catalog.collections.edges.map(edge => edge.node),
|
||||
[]
|
||||
)
|
||||
.map<QuickSearchActionInput>(collection => ({
|
||||
caption: intl.formatMessage(messages.collection),
|
||||
extraInfo: intl.formatMessage(
|
||||
collection.isPublished
|
||||
? messages.collectionPublished
|
||||
: messages.collectionUnpublished
|
||||
),
|
||||
label: collection.name,
|
||||
onClick: () => {
|
||||
navigate(collectionUrl(collection.id));
|
||||
return false;
|
||||
},
|
||||
score: score(collection.name, search),
|
||||
text: collection.name,
|
||||
type: "catalog"
|
||||
}))
|
||||
.sort(sortScores);
|
||||
|
||||
const products: QuickSearchActionInput[] = maybe(
|
||||
() => catalog.products.edges.map(edge => edge.node),
|
||||
[]
|
||||
)
|
||||
.map<QuickSearchActionInput>(product => ({
|
||||
caption: intl.formatMessage(messages.product),
|
||||
extraInfo: product.category.name,
|
||||
label: product.name,
|
||||
onClick: () => {
|
||||
navigate(productUrl(product.id));
|
||||
return false;
|
||||
},
|
||||
score: score(product.name, search),
|
||||
text: product.name,
|
||||
type: "catalog"
|
||||
}))
|
||||
.sort(sortScores);
|
||||
|
||||
const baseActions = [
|
||||
...categories.slice(0, 1),
|
||||
...collections.slice(0, 1),
|
||||
...products.slice(0, 1)
|
||||
];
|
||||
|
||||
return [
|
||||
...baseActions,
|
||||
...[...categories.slice(1), ...collections.slice(1), ...products.slice(1)]
|
||||
.sort(sortScores)
|
||||
.slice(0, maxActions - baseActions.length)
|
||||
].sort(sortScores);
|
||||
}
|
||||
|
||||
function getCatalogModeActions(
|
||||
query: string,
|
||||
intl: IntlShape,
|
||||
navigate: UseNavigatorResult,
|
||||
catalog: SearchCatalog
|
||||
): QuickSearchAction[] {
|
||||
return searchInCatalog(query, intl, navigate, catalog);
|
||||
}
|
||||
|
||||
export default getCatalogModeActions;
|
104
src/components/Navigator/modes/commands/actions.ts
Normal file
104
src/components/Navigator/modes/commands/actions.ts
Normal file
|
@ -0,0 +1,104 @@
|
|||
import { score } from "fuzzaldrin";
|
||||
import { IntlShape } from "react-intl";
|
||||
|
||||
import { categoryAddUrl } from "@saleor/categories/urls";
|
||||
import { collectionAddUrl } from "@saleor/collections/urls";
|
||||
import { customerAddUrl } from "@saleor/customers/urls";
|
||||
import { voucherAddUrl } from "@saleor/discounts/urls";
|
||||
import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
|
||||
import { OrderDraftCreate } from "@saleor/orders/types/OrderDraftCreate";
|
||||
import { productAddUrl } from "@saleor/products/urls";
|
||||
import { MutationFunction } from "react-apollo";
|
||||
import { QuickSearchActionInput, QuickSearchMode } from "../../types";
|
||||
import messages from "../messages";
|
||||
import { sortScores } from "../utils";
|
||||
|
||||
const threshold = 0.05;
|
||||
const maxActions = 5;
|
||||
|
||||
interface Command {
|
||||
label: string;
|
||||
onClick: () => boolean;
|
||||
}
|
||||
export function searchInCommands(
|
||||
search: string,
|
||||
intl: IntlShape,
|
||||
navigate: UseNavigatorResult,
|
||||
createOrder: MutationFunction<OrderDraftCreate, {}>,
|
||||
setMode: (mode: QuickSearchMode) => void
|
||||
): QuickSearchActionInput[] {
|
||||
const actions: Command[] = [
|
||||
{
|
||||
label: intl.formatMessage(messages.createCategory),
|
||||
onClick: () => {
|
||||
navigate(categoryAddUrl());
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(messages.createCollection),
|
||||
onClick: () => {
|
||||
navigate(collectionAddUrl);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(messages.createProduct),
|
||||
onClick: () => {
|
||||
navigate(productAddUrl);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(messages.createCustomer),
|
||||
onClick: () => {
|
||||
navigate(customerAddUrl);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(messages.createVoucher),
|
||||
onClick: () => {
|
||||
navigate(voucherAddUrl);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(messages.createOrder),
|
||||
onClick: () => {
|
||||
createOrder();
|
||||
return false;
|
||||
}
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(messages.helpMode),
|
||||
onClick: () => {
|
||||
setMode("help");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
return actions.map(action => ({
|
||||
label: action.label,
|
||||
onClick: action.onClick,
|
||||
score: score(action.label, search),
|
||||
text: action.label,
|
||||
type: "action"
|
||||
}));
|
||||
}
|
||||
|
||||
function getCommandModeActions(
|
||||
query: string,
|
||||
intl: IntlShape,
|
||||
navigate: UseNavigatorResult,
|
||||
createOrder: MutationFunction<OrderDraftCreate, {}>,
|
||||
setMode: (mode: QuickSearchMode) => void
|
||||
): QuickSearchActionInput[] {
|
||||
return [...searchInCommands(query, intl, navigate, createOrder, setMode)]
|
||||
.filter(action => action.score >= threshold)
|
||||
.sort(sortScores)
|
||||
.slice(0, maxActions);
|
||||
}
|
||||
|
||||
export default getCommandModeActions;
|
2
src/components/Navigator/modes/commands/index.ts
Normal file
2
src/components/Navigator/modes/commands/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export * from "./actions";
|
||||
export { default } from "./actions";
|
40
src/components/Navigator/modes/customers.ts
Normal file
40
src/components/Navigator/modes/customers.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
import { IntlShape } from "react-intl";
|
||||
|
||||
import { customerUrl } from "@saleor/customers/urls";
|
||||
import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
|
||||
import { SearchCustomers_search_edges_node } from "@saleor/searches/types/SearchCustomers";
|
||||
import { QuickSearchAction } from "../types";
|
||||
import messages from "./messages";
|
||||
|
||||
export function searchInCustomers(
|
||||
intl: IntlShape,
|
||||
navigate: UseNavigatorResult,
|
||||
customers: SearchCustomers_search_edges_node[]
|
||||
): QuickSearchAction[] {
|
||||
return customers.map(customer => ({
|
||||
caption: customer.email,
|
||||
label:
|
||||
customer.firstName && customer.lastName
|
||||
? intl.formatMessage(messages.customerWithName, {
|
||||
firstName: customer.firstName,
|
||||
lastName: customer.lastName
|
||||
})
|
||||
: customer.email,
|
||||
onClick: () => {
|
||||
navigate(customerUrl(customer.id));
|
||||
return false;
|
||||
},
|
||||
score: 1,
|
||||
type: "customer"
|
||||
}));
|
||||
}
|
||||
|
||||
function getCustomersModeActions(
|
||||
intl: IntlShape,
|
||||
navigate: UseNavigatorResult,
|
||||
customers: SearchCustomers_search_edges_node[]
|
||||
): QuickSearchAction[] {
|
||||
return searchInCustomers(intl, navigate, customers);
|
||||
}
|
||||
|
||||
export default getCustomersModeActions;
|
30
src/components/Navigator/modes/default/default.ts
Normal file
30
src/components/Navigator/modes/default/default.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { MutationFunction } from "react-apollo";
|
||||
import { IntlShape } from "react-intl";
|
||||
|
||||
import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
|
||||
import { OrderDraftCreate } from "@saleor/orders/types/OrderDraftCreate";
|
||||
import { QuickSearchAction, QuickSearchMode } from "../../types";
|
||||
import { searchInCommands } from "../commands";
|
||||
import { sortScores } from "../utils";
|
||||
import searchInViews from "./views";
|
||||
|
||||
const threshold = 0.05;
|
||||
const maxActions = 5;
|
||||
|
||||
function getDefaultModeActions(
|
||||
query: string,
|
||||
intl: IntlShape,
|
||||
navigate: UseNavigatorResult,
|
||||
createOrder: MutationFunction<OrderDraftCreate, {}>,
|
||||
setMode: (mode: QuickSearchMode) => void
|
||||
): QuickSearchAction[] {
|
||||
return [
|
||||
...searchInViews(query, intl, navigate),
|
||||
...searchInCommands(query, intl, navigate, createOrder, setMode)
|
||||
]
|
||||
.filter(action => action.score >= threshold)
|
||||
.sort(sortScores)
|
||||
.slice(0, maxActions);
|
||||
}
|
||||
|
||||
export default getDefaultModeActions;
|
3
src/components/Navigator/modes/default/index.ts
Normal file
3
src/components/Navigator/modes/default/index.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export * from "./default";
|
||||
export { default } from "./default";
|
||||
export * from "./views";
|
134
src/components/Navigator/modes/default/views.ts
Normal file
134
src/components/Navigator/modes/default/views.ts
Normal file
|
@ -0,0 +1,134 @@
|
|||
import { score } from "fuzzaldrin";
|
||||
import { IntlShape } from "react-intl";
|
||||
|
||||
import { attributeListUrl } from "@saleor/attributes/urls";
|
||||
import { categoryListUrl } from "@saleor/categories/urls";
|
||||
import { collectionListUrl } from "@saleor/collections/urls";
|
||||
import { customerListUrl } from "@saleor/customers/urls";
|
||||
import { saleListUrl, voucherListUrl } from "@saleor/discounts/urls";
|
||||
import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
|
||||
import { sectionNames } from "@saleor/intl";
|
||||
import { menuListUrl } from "@saleor/navigation/urls";
|
||||
import { orderDraftListUrl, orderListUrl } from "@saleor/orders/urls";
|
||||
import { pageListUrl } from "@saleor/pages/urls";
|
||||
import { pluginsListUrl } from "@saleor/plugins/urls";
|
||||
import { productListUrl } from "@saleor/products/urls";
|
||||
import { productTypeListUrl } from "@saleor/productTypes/urls";
|
||||
import { serviceListUrl } from "@saleor/services/urls";
|
||||
import { shippingZonesListUrl } from "@saleor/shipping/urls";
|
||||
import { siteSettingsUrl } from "@saleor/siteSettings/urls";
|
||||
import { staffListUrl } from "@saleor/staff/urls";
|
||||
import { countryListUrl } from "@saleor/taxes/urls";
|
||||
import { languageListUrl } from "@saleor/translations/urls";
|
||||
import { webhooksListUrl } from "@saleor/webhooks/urls";
|
||||
import { QuickSearchActionInput } from "../../types";
|
||||
|
||||
interface View {
|
||||
label: string;
|
||||
url: string;
|
||||
}
|
||||
function searchInViews(
|
||||
search: string,
|
||||
intl: IntlShape,
|
||||
navigate: UseNavigatorResult
|
||||
): QuickSearchActionInput[] {
|
||||
const views: View[] = [
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.attributes),
|
||||
url: attributeListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.categories),
|
||||
url: categoryListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.collections),
|
||||
url: collectionListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.customers),
|
||||
url: customerListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.draftOrders),
|
||||
url: orderDraftListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.home),
|
||||
url: "/"
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.navigation),
|
||||
url: menuListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.orders),
|
||||
url: orderListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.pages),
|
||||
url: pageListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.plugins),
|
||||
url: pluginsListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.productTypes),
|
||||
url: productTypeListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.products),
|
||||
url: productListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.sales),
|
||||
url: saleListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.serviceAccounts),
|
||||
url: serviceListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.shipping),
|
||||
url: shippingZonesListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.siteSettings),
|
||||
url: siteSettingsUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.staff),
|
||||
url: staffListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.taxes),
|
||||
url: countryListUrl
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.translations),
|
||||
url: languageListUrl
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.vouchers),
|
||||
url: voucherListUrl()
|
||||
},
|
||||
{
|
||||
label: intl.formatMessage(sectionNames.webhooks),
|
||||
url: webhooksListUrl()
|
||||
}
|
||||
];
|
||||
|
||||
return views.map(view => ({
|
||||
label: view.label,
|
||||
onClick: () => {
|
||||
navigate(view.url);
|
||||
return false;
|
||||
},
|
||||
score: score(view.label, search),
|
||||
text: view.label,
|
||||
type: "view"
|
||||
}));
|
||||
}
|
||||
|
||||
export default searchInViews;
|
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;
|
54
src/components/Navigator/modes/index.ts
Normal file
54
src/components/Navigator/modes/index.ts
Normal file
|
@ -0,0 +1,54 @@
|
|||
import { IntlShape } from "react-intl";
|
||||
|
||||
import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
|
||||
import { OrderDraftCreate } from "@saleor/orders/types/OrderDraftCreate";
|
||||
import { MutationFunction } from "react-apollo";
|
||||
import { QuickSearchAction, QuickSearchMode } from "../types";
|
||||
import getCatalogModeActions from "./catalog";
|
||||
import getCommandModeActions from "./commands";
|
||||
import getCustomersModeActions from "./customers";
|
||||
import getDefaultModeActions from "./default";
|
||||
import getHelpModeActions from "./help";
|
||||
import getOrdersModeActions from "./orders";
|
||||
import { ActionQueries } from "./types";
|
||||
|
||||
function getModeActions(
|
||||
mode: QuickSearchMode,
|
||||
query: string,
|
||||
intl: IntlShape,
|
||||
queries: ActionQueries,
|
||||
cbs: {
|
||||
createOrder: MutationFunction<OrderDraftCreate, {}>;
|
||||
navigate: UseNavigatorResult;
|
||||
setMode: (mode: QuickSearchMode) => void;
|
||||
}
|
||||
): QuickSearchAction[] {
|
||||
switch (mode) {
|
||||
case "catalog":
|
||||
return getCatalogModeActions(query, intl, cbs.navigate, queries.catalog);
|
||||
case "commands":
|
||||
return getCommandModeActions(
|
||||
query,
|
||||
intl,
|
||||
cbs.navigate,
|
||||
cbs.createOrder,
|
||||
cbs.setMode
|
||||
);
|
||||
case "customers":
|
||||
return getCustomersModeActions(intl, cbs.navigate, queries.customers);
|
||||
case "help":
|
||||
return getHelpModeActions(query, intl, cbs.setMode);
|
||||
case "orders":
|
||||
return getOrdersModeActions(query, intl, cbs.navigate, queries.order);
|
||||
default:
|
||||
return getDefaultModeActions(
|
||||
query,
|
||||
intl,
|
||||
cbs.navigate,
|
||||
cbs.createOrder,
|
||||
cbs.setMode
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default getModeActions;
|
81
src/components/Navigator/modes/messages.ts
Normal file
81
src/components/Navigator/modes/messages.ts
Normal file
|
@ -0,0 +1,81 @@
|
|||
import { defineMessages } from "react-intl";
|
||||
|
||||
const messages = defineMessages({
|
||||
category: {
|
||||
defaultMessage: "Category"
|
||||
},
|
||||
collection: {
|
||||
defaultMessage: "Collection"
|
||||
},
|
||||
collectionPublished: {
|
||||
defaultMessage: "Published",
|
||||
description: "collection"
|
||||
},
|
||||
collectionUnpublished: {
|
||||
defaultMessage: "Not Published",
|
||||
description: "collection"
|
||||
},
|
||||
createCategory: {
|
||||
defaultMessage: "Create Category",
|
||||
description: "button"
|
||||
},
|
||||
createCollection: {
|
||||
defaultMessage: "Create Collection",
|
||||
description: "button"
|
||||
},
|
||||
createCustomer: {
|
||||
defaultMessage: "Create Customer",
|
||||
description: "button"
|
||||
},
|
||||
createOrder: {
|
||||
defaultMessage: "Create Order",
|
||||
description: "button"
|
||||
},
|
||||
createProduct: {
|
||||
defaultMessage: "Create Product",
|
||||
description: "button"
|
||||
},
|
||||
createVoucher: {
|
||||
defaultMessage: "Create Voucher",
|
||||
description: "button"
|
||||
},
|
||||
customerWithName: {
|
||||
defaultMessage: "{firstName} {lastName}"
|
||||
},
|
||||
goToOrder: {
|
||||
defaultMessage: "Go to order #{orderNumber}",
|
||||
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: {
|
||||
defaultMessage: "Product"
|
||||
}
|
||||
});
|
||||
|
||||
export default messages;
|
45
src/components/Navigator/modes/orders.ts
Normal file
45
src/components/Navigator/modes/orders.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { IntlShape } from "react-intl";
|
||||
|
||||
import { UseNavigatorResult } from "@saleor/hooks/useNavigator";
|
||||
import { maybe, transformOrderStatus } from "@saleor/misc";
|
||||
import { orderUrl } from "@saleor/orders/urls";
|
||||
import { CheckIfOrderExists_order } from "../queries/types/CheckIfOrderExists";
|
||||
import { QuickSearchAction } from "../types";
|
||||
import messages from "./messages";
|
||||
|
||||
export function isQueryValidOrderNumber(query: string): boolean {
|
||||
return query === parseInt(query, 0).toString();
|
||||
}
|
||||
|
||||
export function getGqlOrderId(orderNumber: string): string {
|
||||
return btoa(`Order:${orderNumber}`);
|
||||
}
|
||||
|
||||
function getOrdersModeActions(
|
||||
query: string,
|
||||
intl: IntlShape,
|
||||
navigate: UseNavigatorResult,
|
||||
order: CheckIfOrderExists_order
|
||||
): QuickSearchAction[] {
|
||||
const gqlId = getGqlOrderId(query);
|
||||
|
||||
if (isQueryValidOrderNumber(query) && maybe(() => order.id === gqlId)) {
|
||||
return [
|
||||
{
|
||||
extraInfo: transformOrderStatus(order.status, intl).localized,
|
||||
label: intl.formatMessage(messages.goToOrder, {
|
||||
orderNumber: query
|
||||
}),
|
||||
onClick: () => {
|
||||
navigate(orderUrl(gqlId));
|
||||
return false;
|
||||
},
|
||||
type: "action"
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
export default getOrdersModeActions;
|
9
src/components/Navigator/modes/types.ts
Normal file
9
src/components/Navigator/modes/types.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { SearchCustomers_search_edges_node } from "@saleor/searches/types/SearchCustomers";
|
||||
import { CheckIfOrderExists_order } from "../queries/types/CheckIfOrderExists";
|
||||
import { SearchCatalog } from "../queries/types/SearchCatalog";
|
||||
|
||||
export interface ActionQueries {
|
||||
catalog: SearchCatalog;
|
||||
customers: SearchCustomers_search_edges_node[];
|
||||
order: CheckIfOrderExists_order;
|
||||
}
|
60
src/components/Navigator/modes/utils.ts
Normal file
60
src/components/Navigator/modes/utils.ts
Normal file
|
@ -0,0 +1,60 @@
|
|||
import {
|
||||
QuickSearchAction,
|
||||
QuickSearchActionInput,
|
||||
QuickSearchMode
|
||||
} from "../types";
|
||||
|
||||
export function getActions(actions: QuickSearchAction[]): QuickSearchAction[] {
|
||||
return actions.filter(action => action.type === "action");
|
||||
}
|
||||
export function hasActions(actions: QuickSearchAction[]): boolean {
|
||||
return getActions(actions).length > 0;
|
||||
}
|
||||
|
||||
export function getViews(actions: QuickSearchAction[]): QuickSearchAction[] {
|
||||
return actions.filter(action => action.type === "view");
|
||||
}
|
||||
export function hasViews(actions: QuickSearchAction[]): boolean {
|
||||
return getViews(actions).length > 0;
|
||||
}
|
||||
|
||||
export function getCustomers(
|
||||
actions: QuickSearchAction[]
|
||||
): QuickSearchAction[] {
|
||||
return actions.filter(action => action.type === "customer");
|
||||
}
|
||||
export function hasCustomers(actions: QuickSearchAction[]): boolean {
|
||||
return getCustomers(actions).length > 0;
|
||||
}
|
||||
|
||||
export function getCatalog(actions: QuickSearchAction[]): QuickSearchAction[] {
|
||||
return actions.filter(action => action.type === "catalog");
|
||||
}
|
||||
export function hasCatalog(actions: QuickSearchAction[]): boolean {
|
||||
return getCatalog(actions).length > 0;
|
||||
}
|
||||
|
||||
export function sortScores(
|
||||
a: QuickSearchActionInput,
|
||||
b: QuickSearchActionInput
|
||||
) {
|
||||
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;
|
||||
}
|
||||
}
|
23
src/components/Navigator/queries/types/CheckIfOrderExists.ts
Normal file
23
src/components/Navigator/queries/types/CheckIfOrderExists.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { OrderStatus } from "./../../../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: CheckIfOrderExists
|
||||
// ====================================================
|
||||
|
||||
export interface CheckIfOrderExists_order {
|
||||
__typename: "Order";
|
||||
id: string;
|
||||
status: OrderStatus;
|
||||
}
|
||||
|
||||
export interface CheckIfOrderExists {
|
||||
order: CheckIfOrderExists_order | null;
|
||||
}
|
||||
|
||||
export interface CheckIfOrderExistsVariables {
|
||||
id: string;
|
||||
}
|
75
src/components/Navigator/queries/types/SearchCatalog.ts
Normal file
75
src/components/Navigator/queries/types/SearchCatalog.ts
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: SearchCatalog
|
||||
// ====================================================
|
||||
|
||||
export interface SearchCatalog_categories_edges_node {
|
||||
__typename: "Category";
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface SearchCatalog_categories_edges {
|
||||
__typename: "CategoryCountableEdge";
|
||||
node: SearchCatalog_categories_edges_node;
|
||||
}
|
||||
|
||||
export interface SearchCatalog_categories {
|
||||
__typename: "CategoryCountableConnection";
|
||||
edges: SearchCatalog_categories_edges[];
|
||||
}
|
||||
|
||||
export interface SearchCatalog_collections_edges_node {
|
||||
__typename: "Collection";
|
||||
id: string;
|
||||
name: string;
|
||||
isPublished: boolean;
|
||||
publicationDate: any | null;
|
||||
}
|
||||
|
||||
export interface SearchCatalog_collections_edges {
|
||||
__typename: "CollectionCountableEdge";
|
||||
node: SearchCatalog_collections_edges_node;
|
||||
}
|
||||
|
||||
export interface SearchCatalog_collections {
|
||||
__typename: "CollectionCountableConnection";
|
||||
edges: SearchCatalog_collections_edges[];
|
||||
}
|
||||
|
||||
export interface SearchCatalog_products_edges_node_category {
|
||||
__typename: "Category";
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface SearchCatalog_products_edges_node {
|
||||
__typename: "Product";
|
||||
id: string;
|
||||
category: SearchCatalog_products_edges_node_category;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface SearchCatalog_products_edges {
|
||||
__typename: "ProductCountableEdge";
|
||||
node: SearchCatalog_products_edges_node;
|
||||
}
|
||||
|
||||
export interface SearchCatalog_products {
|
||||
__typename: "ProductCountableConnection";
|
||||
edges: SearchCatalog_products_edges[];
|
||||
}
|
||||
|
||||
export interface SearchCatalog {
|
||||
categories: SearchCatalog_categories | null;
|
||||
collections: SearchCatalog_collections | null;
|
||||
products: SearchCatalog_products | null;
|
||||
}
|
||||
|
||||
export interface SearchCatalogVariables {
|
||||
first: number;
|
||||
query: string;
|
||||
}
|
66
src/components/Navigator/queries/useCatalogSearch.ts
Normal file
66
src/components/Navigator/queries/useCatalogSearch.ts
Normal file
|
@ -0,0 +1,66 @@
|
|||
import gql from "graphql-tag";
|
||||
import { useState } from "react";
|
||||
|
||||
import makeQuery, { UseQueryResult } from "@saleor/hooks/makeQuery";
|
||||
import useDebounce from "@saleor/hooks/useDebounce";
|
||||
import { SearchCatalog, SearchCatalogVariables } from "./types/SearchCatalog";
|
||||
|
||||
const searchCatalog = gql`
|
||||
query SearchCatalog($first: Int!, $query: String!) {
|
||||
categories(first: $first, filter: { search: $query }) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collections(first: $first, filter: { search: $query }) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
name
|
||||
isPublished
|
||||
publicationDate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
products(first: $first, filter: { search: $query }) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
category {
|
||||
id
|
||||
name
|
||||
}
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const useSearchCatalogQuery = makeQuery<SearchCatalog, SearchCatalogVariables>(
|
||||
searchCatalog
|
||||
);
|
||||
|
||||
type UseSearchCatalog = [
|
||||
UseQueryResult<SearchCatalog, SearchCatalogVariables>,
|
||||
(query: string) => void
|
||||
];
|
||||
function useSearchCatalog(first: number): UseSearchCatalog {
|
||||
const [query, setQuery] = useState("");
|
||||
const setQueryDebounced = useDebounce(setQuery);
|
||||
const result = useSearchCatalogQuery({
|
||||
skip: query === "",
|
||||
variables: {
|
||||
first,
|
||||
query
|
||||
}
|
||||
});
|
||||
|
||||
return [result, setQueryDebounced];
|
||||
}
|
||||
export default useSearchCatalog;
|
41
src/components/Navigator/queries/useCheckIfOrderExists.ts
Normal file
41
src/components/Navigator/queries/useCheckIfOrderExists.ts
Normal file
|
@ -0,0 +1,41 @@
|
|||
import gql from "graphql-tag";
|
||||
import { useState } from "react";
|
||||
|
||||
import makeQuery, { UseQueryResult } from "@saleor/hooks/makeQuery";
|
||||
import useDebounce from "@saleor/hooks/useDebounce";
|
||||
import {
|
||||
CheckIfOrderExists,
|
||||
CheckIfOrderExistsVariables
|
||||
} from "./types/CheckIfOrderExists";
|
||||
|
||||
const checkIfOrderExists = gql`
|
||||
query CheckIfOrderExists($id: ID!) {
|
||||
order(id: $id) {
|
||||
id
|
||||
status
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const useCheckIfOrderExistsQuery = makeQuery<
|
||||
CheckIfOrderExists,
|
||||
CheckIfOrderExistsVariables
|
||||
>(checkIfOrderExists);
|
||||
|
||||
type UseCheckIfOrderExists = [
|
||||
UseQueryResult<CheckIfOrderExists, CheckIfOrderExistsVariables>,
|
||||
(query: string) => void
|
||||
];
|
||||
function useCheckIfOrderExists(): UseCheckIfOrderExists {
|
||||
const [id, setId] = useState("");
|
||||
const setIdDebounced = useDebounce(setId);
|
||||
const result = useCheckIfOrderExistsQuery({
|
||||
skip: id === "",
|
||||
variables: {
|
||||
id
|
||||
}
|
||||
});
|
||||
|
||||
return [result, setIdDebounced];
|
||||
}
|
||||
export default useCheckIfOrderExists;
|
24
src/components/Navigator/types.ts
Normal file
24
src/components/Navigator/types.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
export type QuickSearchActionType = "action" | "catalog" | "customer" | "view";
|
||||
|
||||
export interface QuickSearchAction {
|
||||
caption?: string;
|
||||
extraInfo?: string;
|
||||
label: string;
|
||||
price?: number;
|
||||
symbol?: string;
|
||||
type: QuickSearchActionType;
|
||||
onClick: () => boolean;
|
||||
}
|
||||
|
||||
export interface QuickSearchActionInput extends QuickSearchAction {
|
||||
score: number;
|
||||
text: string;
|
||||
}
|
||||
|
||||
export type QuickSearchMode =
|
||||
| "default"
|
||||
| "catalog"
|
||||
| "commands"
|
||||
| "customers"
|
||||
| "help"
|
||||
| "orders";
|
125
src/components/Navigator/useQuickSearch.ts
Normal file
125
src/components/Navigator/useQuickSearch.ts
Normal file
|
@ -0,0 +1,125 @@
|
|||
import { RefObject, useEffect, useState } from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { DEFAULT_INITIAL_SEARCH_DATA } from "@saleor/config";
|
||||
import { ChangeEvent, FormChange } from "@saleor/hooks/useForm";
|
||||
import useModalDialogOpen from "@saleor/hooks/useModalDialogOpen";
|
||||
import useNavigator from "@saleor/hooks/useNavigator";
|
||||
import { maybe } from "@saleor/misc";
|
||||
import { useOrderDraftCreateMutation } from "@saleor/orders/mutations";
|
||||
import { orderUrl } from "@saleor/orders/urls";
|
||||
import useCustomerSearch from "@saleor/searches/useCustomerSearch";
|
||||
import getModeActions from "./modes";
|
||||
import { getGqlOrderId, isQueryValidOrderNumber } from "./modes/orders";
|
||||
import { getMode } from "./modes/utils";
|
||||
import useSearchCatalog from "./queries/useCatalogSearch";
|
||||
import useCheckIfOrderExists from "./queries/useCheckIfOrderExists";
|
||||
import { QuickSearchAction, QuickSearchMode } from "./types";
|
||||
|
||||
type UseQuickSearch = [
|
||||
string,
|
||||
QuickSearchMode,
|
||||
FormChange,
|
||||
QuickSearchAction[]
|
||||
];
|
||||
function useQuickSearch(
|
||||
open: boolean,
|
||||
input: RefObject<HTMLInputElement>
|
||||
): UseQuickSearch {
|
||||
const [query, setQuery] = useState("");
|
||||
const [mode, setMode] = useState<QuickSearchMode>("default");
|
||||
const intl = useIntl();
|
||||
const navigate = useNavigator();
|
||||
const [{ data: orderData }, getOrderData] = useCheckIfOrderExists();
|
||||
const { result: customers, search: searchCustomers } = useCustomerSearch({
|
||||
variables: {
|
||||
...DEFAULT_INITIAL_SEARCH_DATA,
|
||||
first: 5
|
||||
}
|
||||
});
|
||||
const [{ data: catalog }, searchCatalog] = useSearchCatalog(5);
|
||||
const [createOrder] = useOrderDraftCreateMutation({
|
||||
onCompleted: result => {
|
||||
if (result.draftOrderCreate.errors.length === 0) {
|
||||
navigate(orderUrl(result.draftOrderCreate.order.id));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
useModalDialogOpen(open, {
|
||||
onClose: () => {
|
||||
setMode("default");
|
||||
setQuery("");
|
||||
}
|
||||
});
|
||||
|
||||
const handleBack = (event: KeyboardEvent) => {
|
||||
// `any` type because of poorly typed `KeyboardEvent.EventTarget` which
|
||||
// has no `value` key. Which it would have if `KeyboardEvent` and
|
||||
// `EventTarget` would be generic types accepting HTMLDOM element types.
|
||||
if ((event.target as any).value === "" && event.keyCode === 8) {
|
||||
setMode("default");
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setQuery("");
|
||||
if (mode !== "default" && input.current) {
|
||||
input.current.addEventListener("keyup", handleBack);
|
||||
|
||||
return () => {
|
||||
if (input.current) {
|
||||
input.current.removeEventListener("keyup", handleBack);
|
||||
}
|
||||
};
|
||||
}
|
||||
}, [mode, open]);
|
||||
|
||||
const change = (event: ChangeEvent) => {
|
||||
const value = event.target.value;
|
||||
|
||||
if (mode === "default" || mode === "help") {
|
||||
const newMode = getMode(value);
|
||||
if (newMode) {
|
||||
setMode(newMode);
|
||||
}
|
||||
}
|
||||
if (mode === "orders" && isQueryValidOrderNumber(value)) {
|
||||
getOrderData(getGqlOrderId(value));
|
||||
}
|
||||
if (mode === "catalog") {
|
||||
searchCatalog(value);
|
||||
}
|
||||
if (mode === "customers") {
|
||||
searchCustomers(value);
|
||||
}
|
||||
|
||||
setQuery(value);
|
||||
};
|
||||
|
||||
return [
|
||||
query,
|
||||
mode,
|
||||
change,
|
||||
getModeActions(
|
||||
mode,
|
||||
query,
|
||||
intl,
|
||||
{
|
||||
catalog,
|
||||
customers: maybe(
|
||||
() => customers.data.search.edges.map(edge => edge.node),
|
||||
[]
|
||||
),
|
||||
order: maybe(() => orderData.order)
|
||||
},
|
||||
{
|
||||
createOrder,
|
||||
navigate,
|
||||
setMode
|
||||
}
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
export default useQuickSearch;
|
|
@ -1,6 +1,7 @@
|
|||
import Button from "@material-ui/core/Button";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import Snackbar from "@material-ui/core/Snackbar";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import CloseIcon from "@material-ui/icons/Close";
|
||||
import React from "react";
|
||||
|
||||
|
@ -15,7 +16,7 @@ interface MessageManagerState {
|
|||
}
|
||||
|
||||
export class MessageManager extends React.Component<{}, MessageManagerState> {
|
||||
state = {
|
||||
state: MessageManagerState = {
|
||||
message: { text: "", key: "0", onUndo: undefined },
|
||||
opened: false
|
||||
};
|
||||
|
@ -55,7 +56,7 @@ export class MessageManager extends React.Component<{}, MessageManagerState> {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { text, key, onUndo } = this.state.message;
|
||||
const { autohide = 3000, title, text, key, onUndo } = this.state.message;
|
||||
return (
|
||||
<>
|
||||
<Snackbar
|
||||
|
@ -65,7 +66,7 @@ export class MessageManager extends React.Component<{}, MessageManagerState> {
|
|||
vertical: "top"
|
||||
}}
|
||||
open={this.state.opened}
|
||||
autoHideDuration={3000}
|
||||
autoHideDuration={autohide}
|
||||
onClose={this.handleClose}
|
||||
onExited={this.handleExited}
|
||||
ContentProps={{
|
||||
|
@ -73,9 +74,15 @@ export class MessageManager extends React.Component<{}, MessageManagerState> {
|
|||
}}
|
||||
message={
|
||||
<span id="message-id" data-tc="notification">
|
||||
{title && (
|
||||
<Typography variant="h5" style={{ marginBottom: "1rem" }}>
|
||||
{title}
|
||||
</Typography>
|
||||
)}
|
||||
{text}
|
||||
</span>
|
||||
}
|
||||
title={title}
|
||||
action={[
|
||||
!!onUndo ? (
|
||||
<Button
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { createContext } from "react";
|
||||
|
||||
export interface IMessage {
|
||||
autohide?: number;
|
||||
title?: string;
|
||||
text: string;
|
||||
onUndo?: () => void;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import packageInfo from "../package.json";
|
||||
import { SearchVariables } from "./hooks/makeSearch";
|
||||
import { ListSettings, ListViews } from "./types";
|
||||
|
||||
|
@ -74,3 +75,5 @@ export const defaultListSettings: AppListViewSettings = {
|
|||
rowNumber: PAGINATE_BY
|
||||
}
|
||||
};
|
||||
|
||||
export const APP_VERSION = packageInfo.version;
|
||||
|
|
|
@ -150,7 +150,7 @@ const CustomerCreatePage: React.FC<CustomerCreatePageProps> = ({
|
|||
</AppHeader>
|
||||
<PageHeader
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Add Customer",
|
||||
defaultMessage: "Create Customer",
|
||||
description: "page header"
|
||||
})}
|
||||
/>
|
||||
|
|
|
@ -50,7 +50,7 @@ const CustomerListPage: React.FC<CustomerListPageProps> = ({
|
|||
onClick={onAdd}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Add customer"
|
||||
defaultMessage="Create customer"
|
||||
description="button"
|
||||
/>
|
||||
</Button>
|
||||
|
|
|
@ -11,15 +11,15 @@ import { commonMessages } from "@saleor/intl";
|
|||
import { maybe } from "@saleor/misc";
|
||||
import useNotifier from "./useNotifier";
|
||||
|
||||
type UseMutation<TData, TVariables> = [
|
||||
export type UseMutation<TData, TVariables> = [
|
||||
MutationFunction<TData, TVariables>,
|
||||
MutationResult<TData>
|
||||
];
|
||||
type UseMutationCbs<TData> = Partial<{
|
||||
export type UseMutationCbs<TData> = Partial<{
|
||||
onCompleted: (data: TData) => void;
|
||||
onError: (error: ApolloError) => void;
|
||||
}>;
|
||||
type UseMutationHook<TData, TVariables> = (
|
||||
export type UseMutationHook<TData, TVariables> = (
|
||||
cbs: UseMutationCbs<TData>
|
||||
) => UseMutation<TData, TVariables>;
|
||||
|
||||
|
|
|
@ -6,12 +6,13 @@ function useDebounce<T>(
|
|||
time = 200
|
||||
): UseDebounceFn<T> {
|
||||
const timer = useRef(null);
|
||||
useEffect(() => () => clearTimeout(timer.current));
|
||||
useEffect(() => () => clearTimeout(timer.current), []);
|
||||
|
||||
return (...args: T[]) => {
|
||||
if (timer.current) {
|
||||
clearTimeout(timer.current);
|
||||
}
|
||||
|
||||
timer.current = setTimeout(() => debounceFn(...args), time);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import ErrorBoundary from "react-error-boundary";
|
|||
import { useIntl } from "react-intl";
|
||||
import { BrowserRouter, Route, Switch } from "react-router-dom";
|
||||
|
||||
import Navigator from "@saleor/components/Navigator";
|
||||
import useAppState from "@saleor/hooks/useAppState";
|
||||
import AttributeSection from "./attributes";
|
||||
import { attributeSection } from "./attributes/urls";
|
||||
|
@ -153,6 +154,7 @@ const Routes: React.FC = () => {
|
|||
}) =>
|
||||
isAuthenticated && !tokenAuthLoading && !tokenVerifyLoading ? (
|
||||
<AppLayout>
|
||||
<Navigator />
|
||||
<ErrorBoundary
|
||||
onError={() =>
|
||||
dispatchAppState({
|
||||
|
|
|
@ -26,8 +26,7 @@ import OrderUnfulfilledItems from "../OrderUnfulfilledItems/OrderUnfulfilledItem
|
|||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
date: {
|
||||
marginBottom: theme.spacing(3),
|
||||
marginTop: -theme.spacing(2)
|
||||
marginBottom: theme.spacing(3)
|
||||
},
|
||||
header: {
|
||||
display: "flex",
|
||||
|
|
|
@ -15,22 +15,30 @@ export const clients: SearchCustomers_search_edges_node[] = [
|
|||
{
|
||||
__typename: "User" as "User",
|
||||
email: "test.client1@example.com",
|
||||
id: "c1"
|
||||
firstName: "John",
|
||||
id: "c1",
|
||||
lastName: "Doe"
|
||||
},
|
||||
{
|
||||
__typename: "User" as "User",
|
||||
email: "test.client2@example.com",
|
||||
id: "c2"
|
||||
firstName: "Dough",
|
||||
id: "c2",
|
||||
lastName: "Jones"
|
||||
},
|
||||
{
|
||||
__typename: "User" as "User",
|
||||
email: "test.client3@example.com",
|
||||
id: "c3"
|
||||
firstName: "Jonas",
|
||||
id: "c3",
|
||||
lastName: "Dough"
|
||||
},
|
||||
{
|
||||
__typename: "User" as "User",
|
||||
email: "test.client4@example.com",
|
||||
id: "c4"
|
||||
firstName: "Bill",
|
||||
id: "c4",
|
||||
lastName: "Jonas"
|
||||
}
|
||||
];
|
||||
export const orders: OrderList_orders_edges_node[] = [
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import gql from "graphql-tag";
|
||||
|
||||
import makeMutation from "@saleor/hooks/makeMutation";
|
||||
import { TypedMutation } from "../mutations";
|
||||
import {
|
||||
fragmentAddress,
|
||||
|
@ -409,10 +410,9 @@ const orderDraftCreateMutation = gql`
|
|||
}
|
||||
}
|
||||
`;
|
||||
export const TypedOrderDraftCreateMutation = TypedMutation<
|
||||
OrderDraftCreate,
|
||||
{}
|
||||
>(orderDraftCreateMutation);
|
||||
export const useOrderDraftCreateMutation = makeMutation<OrderDraftCreate, {}>(
|
||||
orderDraftCreateMutation
|
||||
);
|
||||
|
||||
const orderLineDeleteMutation = gql`
|
||||
${fragmentOrderDetails}
|
||||
|
|
|
@ -21,7 +21,7 @@ import { ListViews } from "@saleor/types";
|
|||
import OrderDraftListPage from "../../components/OrderDraftListPage";
|
||||
import {
|
||||
TypedOrderDraftBulkCancelMutation,
|
||||
TypedOrderDraftCreateMutation
|
||||
useOrderDraftCreateMutation
|
||||
} from "../../mutations";
|
||||
import { TypedOrderDraftListQuery } from "../../queries";
|
||||
import { OrderDraftBulkCancel } from "../../types/OrderDraftBulkCancel";
|
||||
|
@ -58,6 +58,19 @@ export const OrderDraftList: React.FC<OrderDraftListProps> = ({ params }) => {
|
|||
);
|
||||
const intl = useIntl();
|
||||
|
||||
const handleCreateOrderCreateSuccess = (data: OrderDraftCreate) => {
|
||||
notify({
|
||||
text: intl.formatMessage({
|
||||
defaultMessage: "Order draft succesfully created"
|
||||
})
|
||||
});
|
||||
navigate(orderUrl(data.draftOrderCreate.order.id));
|
||||
};
|
||||
|
||||
const [createOrder] = useOrderDraftCreateMutation({
|
||||
onCompleted: handleCreateOrderCreateSuccess
|
||||
});
|
||||
|
||||
const tabs = getFilterTabs();
|
||||
|
||||
const currentTab =
|
||||
|
@ -88,15 +101,6 @@ export const OrderDraftList: React.FC<OrderDraftListProps> = ({ params }) => {
|
|||
true
|
||||
);
|
||||
|
||||
const handleCreateOrderCreateSuccess = (data: OrderDraftCreate) => {
|
||||
notify({
|
||||
text: intl.formatMessage({
|
||||
defaultMessage: "Order draft succesfully created"
|
||||
})
|
||||
});
|
||||
navigate(orderUrl(data.draftOrderCreate.order.id));
|
||||
};
|
||||
|
||||
const openModal = (action: OrderDraftListUrlDialog, ids?: string[]) =>
|
||||
navigate(
|
||||
orderDraftListUrl({
|
||||
|
@ -137,8 +141,6 @@ export const OrderDraftList: React.FC<OrderDraftListProps> = ({ params }) => {
|
|||
);
|
||||
|
||||
return (
|
||||
<TypedOrderDraftCreateMutation onCompleted={handleCreateOrderCreateSuccess}>
|
||||
{createOrder => (
|
||||
<TypedOrderDraftListQuery displayLoader variables={queryVariables}>
|
||||
{({ data, loading, refetch }) => {
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
|
@ -170,8 +172,7 @@ export const OrderDraftList: React.FC<OrderDraftListProps> = ({ params }) => {
|
|||
orderDraftBulkDeleteOpts.loading,
|
||||
maybe(
|
||||
() =>
|
||||
orderDraftBulkDeleteOpts.data.draftOrderBulkDelete
|
||||
.errors
|
||||
orderDraftBulkDeleteOpts.data.draftOrderBulkDelete.errors
|
||||
)
|
||||
);
|
||||
const onOrderDraftBulkDelete = () =>
|
||||
|
@ -241,9 +242,7 @@ export const OrderDraftList: React.FC<OrderDraftListProps> = ({ params }) => {
|
|||
values={{
|
||||
counter: maybe(() => params.ids.length),
|
||||
displayQuantity: (
|
||||
<strong>
|
||||
{maybe(() => params.ids.length)}
|
||||
</strong>
|
||||
<strong>{maybe(() => params.ids.length)}</strong>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
|
@ -269,8 +268,6 @@ export const OrderDraftList: React.FC<OrderDraftListProps> = ({ params }) => {
|
|||
);
|
||||
}}
|
||||
</TypedOrderDraftListQuery>
|
||||
)}
|
||||
</TypedOrderDraftCreateMutation>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import OrderBulkCancelDialog from "../../components/OrderBulkCancelDialog";
|
|||
import OrderListPage from "../../components/OrderListPage/OrderListPage";
|
||||
import {
|
||||
TypedOrderBulkCancelMutation,
|
||||
TypedOrderDraftCreateMutation
|
||||
useOrderDraftCreateMutation
|
||||
} from "../../mutations";
|
||||
import { TypedOrderListQuery } from "../../queries";
|
||||
import { OrderBulkCancel } from "../../types/OrderBulkCancel";
|
||||
|
@ -62,6 +62,19 @@ export const OrderList: React.FC<OrderListProps> = ({ params }) => {
|
|||
);
|
||||
const intl = useIntl();
|
||||
|
||||
const handleCreateOrderCreateSuccess = (data: OrderDraftCreate) => {
|
||||
notify({
|
||||
text: intl.formatMessage({
|
||||
defaultMessage: "Order draft succesfully created"
|
||||
})
|
||||
});
|
||||
navigate(orderUrl(data.draftOrderCreate.order.id));
|
||||
};
|
||||
|
||||
const [createOrder] = useOrderDraftCreateMutation({
|
||||
onCompleted: handleCreateOrderCreateSuccess
|
||||
});
|
||||
|
||||
const tabs = getFilterTabs();
|
||||
|
||||
const currentTab =
|
||||
|
@ -130,15 +143,6 @@ export const OrderList: React.FC<OrderListProps> = ({ params }) => {
|
|||
const paginationState = createPaginationState(settings.rowNumber, params);
|
||||
const currencySymbol = maybe(() => shop.defaultCurrency, "USD");
|
||||
|
||||
const handleCreateOrderCreateSuccess = (data: OrderDraftCreate) => {
|
||||
notify({
|
||||
text: intl.formatMessage({
|
||||
defaultMessage: "Order draft succesfully created"
|
||||
})
|
||||
});
|
||||
navigate(orderUrl(data.draftOrderCreate.order.id));
|
||||
};
|
||||
|
||||
const queryVariables = React.useMemo(
|
||||
() => ({
|
||||
...paginationState,
|
||||
|
@ -148,8 +152,6 @@ export const OrderList: React.FC<OrderListProps> = ({ params }) => {
|
|||
);
|
||||
|
||||
return (
|
||||
<TypedOrderDraftCreateMutation onCompleted={handleCreateOrderCreateSuccess}>
|
||||
{createOrder => (
|
||||
<TypedOrderListQuery displayLoader variables={queryVariables}>
|
||||
{({ data, loading, refetch }) => {
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
|
@ -271,8 +273,6 @@ export const OrderList: React.FC<OrderListProps> = ({ params }) => {
|
|||
);
|
||||
}}
|
||||
</TypedOrderListQuery>
|
||||
)}
|
||||
</TypedOrderDraftCreateMutation>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -2,10 +2,7 @@
|
|||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import {
|
||||
PluginUpdateInput,
|
||||
ConfigurationTypeFieldEnum
|
||||
} from "./../../types/globalTypes";
|
||||
import { PluginUpdateInput, ConfigurationTypeFieldEnum } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL mutation operation: PluginUpdate
|
||||
|
@ -32,9 +29,7 @@ export interface PluginUpdate_pluginUpdate_plugin {
|
|||
name: string;
|
||||
description: string;
|
||||
active: boolean;
|
||||
configuration:
|
||||
| (PluginUpdate_pluginUpdate_plugin_configuration | null)[]
|
||||
| null;
|
||||
configuration: (PluginUpdate_pluginUpdate_plugin_configuration | null)[] | null;
|
||||
}
|
||||
|
||||
export interface PluginUpdate_pluginUpdate {
|
||||
|
|
|
@ -10,6 +10,8 @@ export interface SearchCustomers_search_edges_node {
|
|||
__typename: "User";
|
||||
id: string;
|
||||
email: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
}
|
||||
|
||||
export interface SearchCustomers_search_edges {
|
||||
|
|
|
@ -22,9 +22,7 @@ export interface SearchProductTypes_search_edges_node_productAttributes {
|
|||
slug: string | null;
|
||||
name: string | null;
|
||||
valueRequired: boolean;
|
||||
values:
|
||||
| (SearchProductTypes_search_edges_node_productAttributes_values | null)[]
|
||||
| null;
|
||||
values: (SearchProductTypes_search_edges_node_productAttributes_values | null)[] | null;
|
||||
}
|
||||
|
||||
export interface SearchProductTypes_search_edges_node {
|
||||
|
@ -32,9 +30,7 @@ export interface SearchProductTypes_search_edges_node {
|
|||
id: string;
|
||||
name: string;
|
||||
hasVariants: boolean;
|
||||
productAttributes:
|
||||
| (SearchProductTypes_search_edges_node_productAttributes | null)[]
|
||||
| null;
|
||||
productAttributes: (SearchProductTypes_search_edges_node_productAttributes | null)[] | null;
|
||||
}
|
||||
|
||||
export interface SearchProductTypes_search_edges {
|
||||
|
|
|
@ -15,6 +15,8 @@ export const searchCustomers = gql`
|
|||
node {
|
||||
id
|
||||
email
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
}
|
||||
pageInfo {
|
||||
|
|
|
@ -2,12 +2,7 @@
|
|||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import {
|
||||
SiteDomainInput,
|
||||
ShopSettingsInput,
|
||||
AddressInput,
|
||||
AuthorizationKeyType
|
||||
} from "./../../types/globalTypes";
|
||||
import { SiteDomainInput, ShopSettingsInput, AddressInput, AuthorizationKeyType } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL mutation operation: ShopSettingsUpdate
|
||||
|
|
|
@ -29700,7 +29700,7 @@ exports[`Storyshots Views / Customers / Create customer default 1`] = `
|
|||
<div
|
||||
class="MuiTypography-root-id makeStyles-title-id MuiTypography-h5-id"
|
||||
>
|
||||
Add Customer
|
||||
Create Customer
|
||||
</div>
|
||||
<div
|
||||
class="ExtendedPageHeader-action-id"
|
||||
|
@ -30406,7 +30406,7 @@ exports[`Storyshots Views / Customers / Create customer form errors 1`] = `
|
|||
<div
|
||||
class="MuiTypography-root-id makeStyles-title-id MuiTypography-h5-id"
|
||||
>
|
||||
Add Customer
|
||||
Create Customer
|
||||
</div>
|
||||
<div
|
||||
class="ExtendedPageHeader-action-id"
|
||||
|
@ -31172,7 +31172,7 @@ exports[`Storyshots Views / Customers / Create customer loading 1`] = `
|
|||
<div
|
||||
class="MuiTypography-root-id makeStyles-title-id MuiTypography-h5-id"
|
||||
>
|
||||
Add Customer
|
||||
Create Customer
|
||||
</div>
|
||||
<div
|
||||
class="ExtendedPageHeader-action-id"
|
||||
|
@ -36701,7 +36701,7 @@ exports[`Storyshots Views / Customers / Customer list default 1`] = `
|
|||
<span
|
||||
class="MuiButton-label-id"
|
||||
>
|
||||
Add customer
|
||||
Create customer
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -37802,7 +37802,7 @@ exports[`Storyshots Views / Customers / Customer list loading 1`] = `
|
|||
<span
|
||||
class="MuiButton-label-id"
|
||||
>
|
||||
Add customer
|
||||
Create customer
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -38131,7 +38131,7 @@ exports[`Storyshots Views / Customers / Customer list no data 1`] = `
|
|||
<span
|
||||
class="MuiButton-label-id"
|
||||
>
|
||||
Add customer
|
||||
Create customer
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -340,7 +340,8 @@ export default (colors: IThemeColors): Theme =>
|
|||
"& svg": {
|
||||
color: colors.font.default
|
||||
}
|
||||
}
|
||||
},
|
||||
alignSelf: "baseline"
|
||||
},
|
||||
message: {
|
||||
fontSize: 16
|
||||
|
@ -349,7 +350,10 @@ export default (colors: IThemeColors): Theme =>
|
|||
backgroundColor: colors.background.paper,
|
||||
boxShadow:
|
||||
"0 6px 10px 0px rgba(0, 0, 0, 0.15), 0 1px 18px 0px rgba(0, 0, 0, 0.12), 0 3px 5px -1px rgba(0, 0, 0, 0.10)",
|
||||
color: colors.font.default
|
||||
color: colors.font.default,
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 56px",
|
||||
maxWidth: 480
|
||||
}
|
||||
},
|
||||
MuiSwitch: {
|
||||
|
|
|
@ -8,41 +8,41 @@
|
|||
|
||||
export enum AddressTypeEnum {
|
||||
BILLING = "BILLING",
|
||||
SHIPPING = "SHIPPING"
|
||||
SHIPPING = "SHIPPING",
|
||||
}
|
||||
|
||||
export enum AttributeInputTypeEnum {
|
||||
DROPDOWN = "DROPDOWN",
|
||||
MULTISELECT = "MULTISELECT"
|
||||
MULTISELECT = "MULTISELECT",
|
||||
}
|
||||
|
||||
export enum AttributeTypeEnum {
|
||||
PRODUCT = "PRODUCT",
|
||||
VARIANT = "VARIANT"
|
||||
VARIANT = "VARIANT",
|
||||
}
|
||||
|
||||
export enum AttributeValueType {
|
||||
COLOR = "COLOR",
|
||||
GRADIENT = "GRADIENT",
|
||||
STRING = "STRING",
|
||||
URL = "URL"
|
||||
URL = "URL",
|
||||
}
|
||||
|
||||
export enum AuthorizationKeyType {
|
||||
FACEBOOK = "FACEBOOK",
|
||||
GOOGLE_OAUTH2 = "GOOGLE_OAUTH2"
|
||||
GOOGLE_OAUTH2 = "GOOGLE_OAUTH2",
|
||||
}
|
||||
|
||||
export enum CollectionPublished {
|
||||
HIDDEN = "HIDDEN",
|
||||
PUBLISHED = "PUBLISHED"
|
||||
PUBLISHED = "PUBLISHED",
|
||||
}
|
||||
|
||||
export enum ConfigurationTypeFieldEnum {
|
||||
BOOLEAN = "BOOLEAN",
|
||||
PASSWORD = "PASSWORD",
|
||||
SECRET = "SECRET",
|
||||
STRING = "STRING"
|
||||
STRING = "STRING",
|
||||
}
|
||||
|
||||
export enum CountryCode {
|
||||
|
@ -295,23 +295,23 @@ export enum CountryCode {
|
|||
YT = "YT",
|
||||
ZA = "ZA",
|
||||
ZM = "ZM",
|
||||
ZW = "ZW"
|
||||
ZW = "ZW",
|
||||
}
|
||||
|
||||
export enum DiscountStatusEnum {
|
||||
ACTIVE = "ACTIVE",
|
||||
EXPIRED = "EXPIRED",
|
||||
SCHEDULED = "SCHEDULED"
|
||||
SCHEDULED = "SCHEDULED",
|
||||
}
|
||||
|
||||
export enum DiscountValueTypeEnum {
|
||||
FIXED = "FIXED",
|
||||
PERCENTAGE = "PERCENTAGE"
|
||||
PERCENTAGE = "PERCENTAGE",
|
||||
}
|
||||
|
||||
export enum FulfillmentStatus {
|
||||
CANCELED = "CANCELED",
|
||||
FULFILLED = "FULFILLED"
|
||||
FULFILLED = "FULFILLED",
|
||||
}
|
||||
|
||||
export enum LanguageCodeEnum {
|
||||
|
@ -357,19 +357,19 @@ export enum LanguageCodeEnum {
|
|||
UK = "UK",
|
||||
VI = "VI",
|
||||
ZH_HANS = "ZH_HANS",
|
||||
ZH_HANT = "ZH_HANT"
|
||||
ZH_HANT = "ZH_HANT",
|
||||
}
|
||||
|
||||
export enum OrderAction {
|
||||
CAPTURE = "CAPTURE",
|
||||
MARK_AS_PAID = "MARK_AS_PAID",
|
||||
REFUND = "REFUND",
|
||||
VOID = "VOID"
|
||||
VOID = "VOID",
|
||||
}
|
||||
|
||||
export enum OrderDirection {
|
||||
ASC = "ASC",
|
||||
DESC = "DESC"
|
||||
DESC = "DESC",
|
||||
}
|
||||
|
||||
export enum OrderEventsEmailsEnum {
|
||||
|
@ -378,7 +378,7 @@ export enum OrderEventsEmailsEnum {
|
|||
ORDER_CONFIRMATION = "ORDER_CONFIRMATION",
|
||||
PAYMENT_CONFIRMATION = "PAYMENT_CONFIRMATION",
|
||||
SHIPPING_CONFIRMATION = "SHIPPING_CONFIRMATION",
|
||||
TRACKING_UPDATED = "TRACKING_UPDATED"
|
||||
TRACKING_UPDATED = "TRACKING_UPDATED",
|
||||
}
|
||||
|
||||
export enum OrderEventsEnum {
|
||||
|
@ -402,7 +402,7 @@ export enum OrderEventsEnum {
|
|||
PLACED = "PLACED",
|
||||
PLACED_FROM_DRAFT = "PLACED_FROM_DRAFT",
|
||||
TRACKING_UPDATED = "TRACKING_UPDATED",
|
||||
UPDATED_ADDRESS = "UPDATED_ADDRESS"
|
||||
UPDATED_ADDRESS = "UPDATED_ADDRESS",
|
||||
}
|
||||
|
||||
export enum OrderStatus {
|
||||
|
@ -410,7 +410,7 @@ export enum OrderStatus {
|
|||
DRAFT = "DRAFT",
|
||||
FULFILLED = "FULFILLED",
|
||||
PARTIALLY_FULFILLED = "PARTIALLY_FULFILLED",
|
||||
UNFULFILLED = "UNFULFILLED"
|
||||
UNFULFILLED = "UNFULFILLED",
|
||||
}
|
||||
|
||||
export enum OrderStatusFilter {
|
||||
|
@ -419,7 +419,7 @@ export enum OrderStatusFilter {
|
|||
PARTIALLY_FULFILLED = "PARTIALLY_FULFILLED",
|
||||
READY_TO_CAPTURE = "READY_TO_CAPTURE",
|
||||
READY_TO_FULFILL = "READY_TO_FULFILL",
|
||||
UNFULFILLED = "UNFULFILLED"
|
||||
UNFULFILLED = "UNFULFILLED",
|
||||
}
|
||||
|
||||
export enum PaymentChargeStatusEnum {
|
||||
|
@ -427,7 +427,7 @@ export enum PaymentChargeStatusEnum {
|
|||
FULLY_REFUNDED = "FULLY_REFUNDED",
|
||||
NOT_CHARGED = "NOT_CHARGED",
|
||||
PARTIALLY_CHARGED = "PARTIALLY_CHARGED",
|
||||
PARTIALLY_REFUNDED = "PARTIALLY_REFUNDED"
|
||||
PARTIALLY_REFUNDED = "PARTIALLY_REFUNDED",
|
||||
}
|
||||
|
||||
export enum PermissionEnum {
|
||||
|
@ -445,7 +445,7 @@ export enum PermissionEnum {
|
|||
MANAGE_STAFF = "MANAGE_STAFF",
|
||||
MANAGE_TRANSLATIONS = "MANAGE_TRANSLATIONS",
|
||||
MANAGE_USERS = "MANAGE_USERS",
|
||||
MANAGE_WEBHOOKS = "MANAGE_WEBHOOKS"
|
||||
MANAGE_WEBHOOKS = "MANAGE_WEBHOOKS",
|
||||
}
|
||||
|
||||
export enum ProductErrorCode {
|
||||
|
@ -459,7 +459,7 @@ export enum ProductErrorCode {
|
|||
NOT_PRODUCTS_IMAGE = "NOT_PRODUCTS_IMAGE",
|
||||
REQUIRED = "REQUIRED",
|
||||
UNIQUE = "UNIQUE",
|
||||
VARIANT_NO_DIGITAL_CONTENT = "VARIANT_NO_DIGITAL_CONTENT"
|
||||
VARIANT_NO_DIGITAL_CONTENT = "VARIANT_NO_DIGITAL_CONTENT",
|
||||
}
|
||||
|
||||
export enum ProductOrderField {
|
||||
|
@ -468,37 +468,37 @@ export enum ProductOrderField {
|
|||
NAME = "NAME",
|
||||
PRICE = "PRICE",
|
||||
PUBLISHED = "PUBLISHED",
|
||||
TYPE = "TYPE"
|
||||
TYPE = "TYPE",
|
||||
}
|
||||
|
||||
export enum ProductTypeConfigurable {
|
||||
CONFIGURABLE = "CONFIGURABLE",
|
||||
SIMPLE = "SIMPLE"
|
||||
SIMPLE = "SIMPLE",
|
||||
}
|
||||
|
||||
export enum ProductTypeEnum {
|
||||
DIGITAL = "DIGITAL",
|
||||
SHIPPABLE = "SHIPPABLE"
|
||||
SHIPPABLE = "SHIPPABLE",
|
||||
}
|
||||
|
||||
export enum SaleType {
|
||||
FIXED = "FIXED",
|
||||
PERCENTAGE = "PERCENTAGE"
|
||||
PERCENTAGE = "PERCENTAGE",
|
||||
}
|
||||
|
||||
export enum ShippingMethodTypeEnum {
|
||||
PRICE = "PRICE",
|
||||
WEIGHT = "WEIGHT"
|
||||
WEIGHT = "WEIGHT",
|
||||
}
|
||||
|
||||
export enum StaffMemberStatus {
|
||||
ACTIVE = "ACTIVE",
|
||||
DEACTIVATED = "DEACTIVATED"
|
||||
DEACTIVATED = "DEACTIVATED",
|
||||
}
|
||||
|
||||
export enum StockAvailability {
|
||||
IN_STOCK = "IN_STOCK",
|
||||
OUT_OF_STOCK = "OUT_OF_STOCK"
|
||||
OUT_OF_STOCK = "OUT_OF_STOCK",
|
||||
}
|
||||
|
||||
export enum TaxRateType {
|
||||
|
@ -526,19 +526,19 @@ export enum TaxRateType {
|
|||
SOCIAL_HOUSING = "SOCIAL_HOUSING",
|
||||
STANDARD = "STANDARD",
|
||||
WATER = "WATER",
|
||||
WINE = "WINE"
|
||||
WINE = "WINE",
|
||||
}
|
||||
|
||||
export enum VoucherDiscountType {
|
||||
FIXED = "FIXED",
|
||||
PERCENTAGE = "PERCENTAGE",
|
||||
SHIPPING = "SHIPPING"
|
||||
SHIPPING = "SHIPPING",
|
||||
}
|
||||
|
||||
export enum VoucherTypeEnum {
|
||||
ENTIRE_ORDER = "ENTIRE_ORDER",
|
||||
SHIPPING = "SHIPPING",
|
||||
SPECIFIC_PRODUCT = "SPECIFIC_PRODUCT"
|
||||
SPECIFIC_PRODUCT = "SPECIFIC_PRODUCT",
|
||||
}
|
||||
|
||||
export enum WebhookErrorCode {
|
||||
|
@ -546,7 +546,7 @@ export enum WebhookErrorCode {
|
|||
INVALID = "INVALID",
|
||||
NOT_FOUND = "NOT_FOUND",
|
||||
REQUIRED = "REQUIRED",
|
||||
UNIQUE = "UNIQUE"
|
||||
UNIQUE = "UNIQUE",
|
||||
}
|
||||
|
||||
export enum WebhookEventTypeEnum {
|
||||
|
@ -557,14 +557,14 @@ export enum WebhookEventTypeEnum {
|
|||
ORDER_FULFILLED = "ORDER_FULFILLED",
|
||||
ORDER_FULLY_PAID = "ORDER_FULLY_PAID",
|
||||
ORDER_UPDATED = "ORDER_UPDATED",
|
||||
PRODUCT_CREATED = "PRODUCT_CREATED"
|
||||
PRODUCT_CREATED = "PRODUCT_CREATED",
|
||||
}
|
||||
|
||||
export enum WeightUnitsEnum {
|
||||
G = "G",
|
||||
KG = "KG",
|
||||
LB = "LB",
|
||||
OZ = "OZ"
|
||||
OZ = "OZ",
|
||||
}
|
||||
|
||||
export interface AddressInput {
|
||||
|
|
Loading…
Reference in a new issue