Merge branch 'master' into fix/unassign_user
This commit is contained in:
commit
6f3c8647f0
78 changed files with 18442 additions and 8419 deletions
4
.github/workflows/test-env-cleanup.yml
vendored
4
.github/workflows/test-env-cleanup.yml
vendored
|
@ -14,7 +14,7 @@ jobs:
|
||||||
- name: Set domain
|
- name: Set domain
|
||||||
# Set test instance domain based on branch name slug
|
# Set test instance domain based on branch name slug
|
||||||
run: |
|
run: |
|
||||||
echo "::set-env name=domain::${{ env.GITHUB_HEAD_REF_SLUG }}.dashboard.saleor.rocks"
|
echo "::set-env name=domain::${{ env.GITHUB_HEAD_REF_SLUG_URL }}.dashboard.saleor.rocks"
|
||||||
|
|
||||||
- name: Configure AWS credentials
|
- name: Configure AWS credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v1
|
uses: aws-actions/configure-aws-credentials@v1
|
||||||
|
@ -34,4 +34,4 @@ jobs:
|
||||||
with:
|
with:
|
||||||
step: deactivate-env
|
step: deactivate-env
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
env: ${{ env.GITHUB_HEAD_REF_SLUG }}
|
env: ${{ env.GITHUB_HEAD_REF_SLUG_URL }}
|
||||||
|
|
4
.github/workflows/test-env-deploy.yml
vendored
4
.github/workflows/test-env-deploy.yml
vendored
|
@ -22,7 +22,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
step: start
|
step: start
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
env: ${{ env.GITHUB_HEAD_REF_SLUG }}
|
env: ${{ env.GITHUB_HEAD_REF_SLUG_URL }}
|
||||||
ref: ${{ github.head_ref }}
|
ref: ${{ github.head_ref }}
|
||||||
|
|
||||||
- name: Cache node modules
|
- name: Cache node modules
|
||||||
|
@ -63,7 +63,7 @@ jobs:
|
||||||
- name: Set domain
|
- name: Set domain
|
||||||
# Set test instance domain based on branch name slug
|
# Set test instance domain based on branch name slug
|
||||||
run: |
|
run: |
|
||||||
echo "::set-env name=domain::${{ env.GITHUB_HEAD_REF_SLUG }}.dashboard.saleor.rocks"
|
echo "::set-env name=domain::${{ env.GITHUB_HEAD_REF_SLUG_URL }}.dashboard.saleor.rocks"
|
||||||
|
|
||||||
- name: Configure AWS credentials
|
- name: Configure AWS credentials
|
||||||
uses: aws-actions/configure-aws-credentials@v1
|
uses: aws-actions/configure-aws-credentials@v1
|
||||||
|
|
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
|
@ -81,8 +81,8 @@ jobs:
|
||||||
env:
|
env:
|
||||||
API_URI: https://pwa.demo.saleor.rocks/graphql/
|
API_URI: https://pwa.demo.saleor.rocks/graphql/
|
||||||
with:
|
with:
|
||||||
start: |
|
build: npm run build
|
||||||
npm start
|
start: npx http-server -a localhost -p 9000 build/dashboard
|
||||||
wait-on: http://localhost:9000/
|
wait-on: http://localhost:9000/
|
||||||
wait-on-timeout: 120
|
wait-on-timeout: 120
|
||||||
- uses: actions/upload-artifact@v1
|
- uses: actions/upload-artifact@v1
|
||||||
|
|
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -16,6 +16,16 @@ All notable, unreleased changes to this project will be documented in this file.
|
||||||
- Refactor authorization - #624 by @dominik-zeglen
|
- Refactor authorization - #624 by @dominik-zeglen
|
||||||
- Fix minor bugs - #628 by @dominik-zeglen
|
- Fix minor bugs - #628 by @dominik-zeglen
|
||||||
- Add navigator button - #635 by @dominik-zeglen
|
- Add navigator button - #635 by @dominik-zeglen
|
||||||
|
- Update to newest schema - #638 by @dominik-zeglen
|
||||||
|
- Fix missing save button - #636 by @dominik-zeglen
|
||||||
|
- Fix user avatars - #639 by @dominik-zeglen
|
||||||
|
- Reset modal state after closing - #644 by @dominik-zeglen
|
||||||
|
- Fix incorrect messages - #643 by @dominik-zeglen
|
||||||
|
- Do not use devserver to run cypress tests - #650 by @dominik-zeglen
|
||||||
|
- Fix updating product that has no variants - #649 by @dominik-zeglen
|
||||||
|
- Update checkbox design - #651 by @dominik-zeglen
|
||||||
|
- Add warehouse choice - #646 by @dominik-zeglen
|
||||||
|
- Fix user management modal actions - #637 by @eaglesemanation
|
||||||
|
|
||||||
## 2.10.1
|
## 2.10.1
|
||||||
|
|
||||||
|
|
1
assets/images/navigator.svg
Normal file
1
assets/images/navigator.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg width="12" height="18" viewBox="0 0 12 18" fill="none" xmlns="http://www.w3.org/2000/svg" ><path d="M0 11.2324L6.99609 0L6.1875 6.78516H11.6895L4.79883 18L5.51953 11.2324H0Z" fill="currentColor" /></svg>
|
After Width: | Height: | Size: 208 B |
|
@ -205,6 +205,62 @@
|
||||||
"context": "vat not included in order price",
|
"context": "vat not included in order price",
|
||||||
"string": "does not apply"
|
"string": "does not apply"
|
||||||
},
|
},
|
||||||
|
"productExportFieldCategory": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Category"
|
||||||
|
},
|
||||||
|
"productExportFieldCollections": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Collections"
|
||||||
|
},
|
||||||
|
"productExportFieldDescription": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Description"
|
||||||
|
},
|
||||||
|
"productExportFieldName": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Name"
|
||||||
|
},
|
||||||
|
"productExportFieldPrice": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Cost Price"
|
||||||
|
},
|
||||||
|
"productExportFieldProductImages": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Product Images"
|
||||||
|
},
|
||||||
|
"productExportFieldProductWeight": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Export Product Weight"
|
||||||
|
},
|
||||||
|
"productExportFieldTaxes": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Charge Taxes"
|
||||||
|
},
|
||||||
|
"productExportFieldType": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Type"
|
||||||
|
},
|
||||||
|
"productExportFieldVariantImages": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Variant Images"
|
||||||
|
},
|
||||||
|
"productExportFieldVariantPrice": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Variant Price"
|
||||||
|
},
|
||||||
|
"productExportFieldVariantSku": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Export Variant SKU"
|
||||||
|
},
|
||||||
|
"productExportFieldVariantWeight": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Export Variant Weight"
|
||||||
|
},
|
||||||
|
"productExportFieldVisibility": {
|
||||||
|
"context": "product field",
|
||||||
|
"string": "Visibility"
|
||||||
|
},
|
||||||
"productStatusLabel": {
|
"productStatusLabel": {
|
||||||
"context": "product",
|
"context": "product",
|
||||||
"string": "Published"
|
"string": "Published"
|
||||||
|
@ -557,9 +613,9 @@
|
||||||
"context": "apps content",
|
"context": "apps content",
|
||||||
"string": "You don’t have any installed apps in your dashboard"
|
"string": "You don’t have any installed apps in your dashboard"
|
||||||
},
|
},
|
||||||
"src_dot_apps_dot_components_dot_InstalledApps_dot_2008086393": {
|
"src_dot_apps_dot_components_dot_InstalledApps_dot_3504763431": {
|
||||||
"context": "section header",
|
"context": "section header",
|
||||||
"string": "Thirdparty Apps"
|
"string": "Third-party Apps"
|
||||||
},
|
},
|
||||||
"src_dot_apps_dot_components_dot_Marketplace_dot_2932910073": {
|
"src_dot_apps_dot_components_dot_Marketplace_dot_2932910073": {
|
||||||
"context": "section header",
|
"context": "section header",
|
||||||
|
@ -1055,6 +1111,9 @@
|
||||||
"context": "dialog title",
|
"context": "dialog title",
|
||||||
"string": "Delete products"
|
"string": "Delete products"
|
||||||
},
|
},
|
||||||
|
"src_dot_categories_dot_views_dot_3296953393": {
|
||||||
|
"string": "Remember this will also unpin all products assigned to this category, making them unavailable in storefront."
|
||||||
|
},
|
||||||
"src_dot_categories_dot_views_dot_3488150607": {
|
"src_dot_categories_dot_views_dot_3488150607": {
|
||||||
"string": "Remember this will also delete all products assigned to this category."
|
"string": "Remember this will also delete all products assigned to this category."
|
||||||
},
|
},
|
||||||
|
@ -1512,6 +1571,9 @@
|
||||||
"src_dot_components_dot_MultiSelectField_dot_4205644805": {
|
"src_dot_components_dot_MultiSelectField_dot_4205644805": {
|
||||||
"string": "No results found"
|
"string": "No results found"
|
||||||
},
|
},
|
||||||
|
"src_dot_components_dot_NavigatorButton_dot_154826674": {
|
||||||
|
"string": "Navigator"
|
||||||
|
},
|
||||||
"src_dot_components_dot_Navigator_dot_1116468870": {
|
"src_dot_components_dot_Navigator_dot_1116468870": {
|
||||||
"context": "navigator placeholder",
|
"context": "navigator placeholder",
|
||||||
"string": "Order Number"
|
"string": "Order Number"
|
||||||
|
@ -3922,34 +3984,22 @@
|
||||||
"context": "product name",
|
"context": "product name",
|
||||||
"string": "Name"
|
"string": "Name"
|
||||||
},
|
},
|
||||||
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_1004476569": {
|
||||||
|
"context": "option",
|
||||||
|
"string": "Export stock for all warehouses"
|
||||||
|
},
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_108342258": {
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_108342258": {
|
||||||
"context": "button",
|
"context": "button",
|
||||||
"string": "Load More"
|
"string": "Load More"
|
||||||
},
|
},
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_1459686496": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "Visibility"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_1547327218": {
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_1547327218": {
|
||||||
"context": "there are more elements of list that are hidden",
|
"context": "there are more elements of list that are hidden",
|
||||||
"string": "and {number} more"
|
"string": "and {number} more"
|
||||||
},
|
},
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_1755013298": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "Category"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_1890035856": {
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_1890035856": {
|
||||||
"context": "informations about product organization, header",
|
"context": "informations about product organization, header",
|
||||||
"string": "Product Organization"
|
"string": "Product Organization"
|
||||||
},
|
},
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_1952810469": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "Type"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_2051669917": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "Cost Price"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_2119710854": {
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_2119710854": {
|
||||||
"context": "informations about product seo, header",
|
"context": "informations about product seo, header",
|
||||||
"string": "SEO Information"
|
"string": "SEO Information"
|
||||||
|
@ -3958,10 +4008,6 @@
|
||||||
"context": "export selected products to csv file",
|
"context": "export selected products to csv file",
|
||||||
"string": "Selected products ({number})"
|
"string": "Selected products ({number})"
|
||||||
},
|
},
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_222873645": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "Collections"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_2318723509": {
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_2318723509": {
|
||||||
"context": "export products to csv file, choice field label",
|
"context": "export products to csv file, choice field label",
|
||||||
"string": "Export information for:"
|
"string": "Export information for:"
|
||||||
|
@ -3970,6 +4016,10 @@
|
||||||
"context": "export all products to csv file",
|
"context": "export all products to csv file",
|
||||||
"string": "All products ({number})"
|
"string": "All products ({number})"
|
||||||
},
|
},
|
||||||
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_2474350154": {
|
||||||
|
"context": "list of warehouses",
|
||||||
|
"string": "Warehouses A to Z"
|
||||||
|
},
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_2659464408": {
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_2659464408": {
|
||||||
"context": "product export to csv file, header",
|
"context": "product export to csv file, header",
|
||||||
"string": "Information exported"
|
"string": "Information exported"
|
||||||
|
@ -3982,10 +4032,6 @@
|
||||||
"context": "export products to csv file, button",
|
"context": "export products to csv file, button",
|
||||||
"string": "export products"
|
"string": "export products"
|
||||||
},
|
},
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_2949617129": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "Product Images"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_3012202273": {
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_3012202273": {
|
||||||
"context": "export products to csv file, dialog header",
|
"context": "export products to csv file, dialog header",
|
||||||
"string": "Export Information"
|
"string": "Export Information"
|
||||||
|
@ -3994,14 +4040,6 @@
|
||||||
"context": "product export to csv file, header",
|
"context": "product export to csv file, header",
|
||||||
"string": "Export Settings"
|
"string": "Export Settings"
|
||||||
},
|
},
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_3374163063": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "Description"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_3441755345": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "Charge Taxes"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_3443345452": {
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_3443345452": {
|
||||||
"context": "selectt all options",
|
"context": "selectt all options",
|
||||||
"string": "Select All"
|
"string": "Select All"
|
||||||
|
@ -4010,13 +4048,12 @@
|
||||||
"context": "export products as spreadsheet",
|
"context": "export products as spreadsheet",
|
||||||
"string": "Spreadsheet for Excel, Numbers etc."
|
"string": "Spreadsheet for Excel, Numbers etc."
|
||||||
},
|
},
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_3544554440": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "Variant Weight"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_3599582104": {
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_3599582104": {
|
||||||
"string": "Search Atrtibuttes"
|
"string": "Search Atrtibuttes"
|
||||||
},
|
},
|
||||||
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_3902059658": {
|
||||||
|
"string": "Export Product Stock Quantity to CSV"
|
||||||
|
},
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_3919525499": {
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_3919525499": {
|
||||||
"context": "informations about product stock, header",
|
"context": "informations about product stock, header",
|
||||||
"string": "Inventory Information"
|
"string": "Inventory Information"
|
||||||
|
@ -4025,10 +4062,6 @@
|
||||||
"context": "export products as csv file",
|
"context": "export products as csv file",
|
||||||
"string": "Plain CSV file"
|
"string": "Plain CSV file"
|
||||||
},
|
},
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_4160582036": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "Variant Price"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_472026385": {
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_472026385": {
|
||||||
"context": "select product informations to be exported",
|
"context": "select product informations to be exported",
|
||||||
"string": "Information exported:"
|
"string": "Information exported:"
|
||||||
|
@ -4037,14 +4070,6 @@
|
||||||
"context": "input helper text, search attributes",
|
"context": "input helper text, search attributes",
|
||||||
"string": "Search by attribute name"
|
"string": "Search by attribute name"
|
||||||
},
|
},
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_636461959": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "Name"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_693960049": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "SKU"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_700651641": {
|
"src_dot_products_dot_components_dot_ProductExportDialog_dot_700651641": {
|
||||||
"context": "export filtered products to csv file",
|
"context": "export filtered products to csv file",
|
||||||
"string": "Current search ({number})"
|
"string": "Current search ({number})"
|
||||||
|
@ -4053,14 +4078,6 @@
|
||||||
"context": "informations about product prices etc, header",
|
"context": "informations about product prices etc, header",
|
||||||
"string": "Financial Information"
|
"string": "Financial Information"
|
||||||
},
|
},
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_746695941": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "Weight"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductExportDialog_dot_897437458": {
|
|
||||||
"context": "product field",
|
|
||||||
"string": "Variant Images"
|
|
||||||
},
|
|
||||||
"src_dot_products_dot_components_dot_ProductImageNavigation_dot_3060635772": {
|
"src_dot_products_dot_components_dot_ProductImageNavigation_dot_3060635772": {
|
||||||
"context": "section header",
|
"context": "section header",
|
||||||
"string": "All Photos"
|
"string": "All Photos"
|
||||||
|
@ -5731,6 +5748,10 @@
|
||||||
"context": "dialog header",
|
"context": "dialog header",
|
||||||
"string": "Delete Webhook"
|
"string": "Delete Webhook"
|
||||||
},
|
},
|
||||||
|
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1087314240": {
|
||||||
|
"context": "event",
|
||||||
|
"string": "Checkout updated"
|
||||||
|
},
|
||||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1368317066": {
|
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_1368317066": {
|
||||||
"context": "event",
|
"context": "event",
|
||||||
"string": "Invoice deleted"
|
"string": "Invoice deleted"
|
||||||
|
@ -5743,6 +5764,10 @@
|
||||||
"context": "event",
|
"context": "event",
|
||||||
"string": "Order updated"
|
"string": "Order updated"
|
||||||
},
|
},
|
||||||
|
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2240725235": {
|
||||||
|
"context": "event",
|
||||||
|
"string": "Checkout created"
|
||||||
|
},
|
||||||
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2454751033": {
|
"src_dot_webhooks_dot_components_dot_WebhookEvents_dot_2454751033": {
|
||||||
"context": "event",
|
"context": "event",
|
||||||
"string": "All events"
|
"string": "All events"
|
||||||
|
|
2621
schema.graphql
2621
schema.graphql
File diff suppressed because it is too large
Load diff
|
@ -47,7 +47,7 @@ const InstalledApps: React.FC<InstalledAppsProps> = ({
|
||||||
header={
|
header={
|
||||||
<CardTitle
|
<CardTitle
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
defaultMessage: "Thirdparty Apps",
|
defaultMessage: "Third-party Apps",
|
||||||
description: "section header"
|
description: "section header"
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -17,7 +17,7 @@ import {
|
||||||
AttributeListUrlQueryParams
|
AttributeListUrlQueryParams
|
||||||
} from "../../urls";
|
} from "../../urls";
|
||||||
|
|
||||||
export const PRODUCT_FILTERS_KEY = "productFilters";
|
export const ATTRIBUTE_FILTERS_KEY = "attributeFilters";
|
||||||
|
|
||||||
export function getFilterOpts(
|
export function getFilterOpts(
|
||||||
params: AttributeListUrlFilters
|
params: AttributeListUrlFilters
|
||||||
|
@ -130,7 +130,7 @@ export const {
|
||||||
deleteFilterTab,
|
deleteFilterTab,
|
||||||
getFilterTabs,
|
getFilterTabs,
|
||||||
saveFilterTab
|
saveFilterTab
|
||||||
} = createFilterTabUtils<AttributeListUrlFilters>(PRODUCT_FILTERS_KEY);
|
} = createFilterTabUtils<AttributeListUrlFilters>(ATTRIBUTE_FILTERS_KEY);
|
||||||
|
|
||||||
export const { areFiltersApplied, getActiveFilters } = createFilterUtils<
|
export const { areFiltersApplied, getActiveFilters } = createFilterUtils<
|
||||||
AttributeListUrlQueryParams,
|
AttributeListUrlQueryParams,
|
||||||
|
|
|
@ -8,7 +8,14 @@ export enum JWTError {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isJwtError(error: GraphQLError): boolean {
|
export function isJwtError(error: GraphQLError): boolean {
|
||||||
return !!findValueInEnum(error.extensions.exception.code, JWTError);
|
let jwtError: boolean;
|
||||||
|
try {
|
||||||
|
jwtError = !!findValueInEnum(error.extensions.exception.code, JWTError);
|
||||||
|
} catch (e) {
|
||||||
|
jwtError = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return jwtError;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isTokenExpired(error: GraphQLError): boolean {
|
export function isTokenExpired(error: GraphQLError): boolean {
|
||||||
|
|
|
@ -285,7 +285,7 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
|
||||||
/>
|
/>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
<DialogContentText>
|
<DialogContentText>
|
||||||
<FormattedMessage defaultMessage="Remember this will also delete all products assigned to this category." />
|
<FormattedMessage defaultMessage="Remember this will also unpin all products assigned to this category, making them unavailable in storefront." />
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
</ActionDialog>
|
</ActionDialog>
|
||||||
<ActionDialog
|
<ActionDialog
|
||||||
|
|
|
@ -28,6 +28,8 @@ import useRouter from "use-react-router";
|
||||||
|
|
||||||
import Container from "../Container";
|
import Container from "../Container";
|
||||||
import ErrorPage from "../ErrorPage";
|
import ErrorPage from "../ErrorPage";
|
||||||
|
import Navigator from "../Navigator";
|
||||||
|
import NavigatorButton from "../NavigatorButton/NavigatorButton";
|
||||||
import AppActionContext from "./AppActionContext";
|
import AppActionContext from "./AppActionContext";
|
||||||
import AppHeaderContext from "./AppHeaderContext";
|
import AppHeaderContext from "./AppHeaderContext";
|
||||||
import { appLoaderHeight, drawerWidth, drawerWidthExpanded } from "./consts";
|
import { appLoaderHeight, drawerWidth, drawerWidthExpanded } from "./consts";
|
||||||
|
@ -310,6 +312,7 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const [appState, dispatchAppState] = useAppState();
|
const [appState, dispatchAppState] = useAppState();
|
||||||
const { location } = useRouter();
|
const { location } = useRouter();
|
||||||
|
const [isNavigatorVisible, setNavigatorVisibility] = React.useState(false);
|
||||||
|
|
||||||
const menuStructure = createMenuStructure(intl);
|
const menuStructure = createMenuStructure(intl);
|
||||||
const configurationMenu = createConfigurationMenu(intl);
|
const configurationMenu = createConfigurationMenu(intl);
|
||||||
|
@ -356,170 +359,184 @@ const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppHeaderContext.Provider value={appHeaderAnchor}>
|
<>
|
||||||
<AppActionContext.Provider value={appActionAnchor}>
|
<Navigator
|
||||||
<div className={classes.root}>
|
visible={isNavigatorVisible}
|
||||||
<div className={classes.sideBar}>
|
setVisibility={setNavigatorVisibility}
|
||||||
<ResponsiveDrawer
|
/>
|
||||||
onClose={() => setDrawerState(false)}
|
<AppHeaderContext.Provider value={appHeaderAnchor}>
|
||||||
open={isDrawerOpened}
|
<AppActionContext.Provider value={appActionAnchor}>
|
||||||
small={!isMenuSmall}
|
<div className={classes.root}>
|
||||||
>
|
<div className={classes.sideBar}>
|
||||||
<div
|
<ResponsiveDrawer
|
||||||
className={classNames(classes.logo, {
|
onClose={() => setDrawerState(false)}
|
||||||
[classes.logoSmall]: isMenuSmall,
|
open={isDrawerOpened}
|
||||||
[classes.logoDark]: isDark
|
small={!isMenuSmall}
|
||||||
})}
|
|
||||||
>
|
>
|
||||||
<SVG src={isMenuSmall ? saleorDarkLogoSmall : saleorDarkLogo} />
|
|
||||||
</div>
|
|
||||||
<Hidden smDown>
|
|
||||||
<div
|
<div
|
||||||
className={classNames(classes.isMenuSmall, {
|
className={classNames(classes.logo, {
|
||||||
[classes.isMenuSmallHide]: isMenuSmall,
|
[classes.logoSmall]: isMenuSmall,
|
||||||
[classes.isMenuSmallDark]: isDark
|
[classes.logoDark]: isDark
|
||||||
})}
|
})}
|
||||||
onClick={handleIsMenuSmall}
|
|
||||||
>
|
>
|
||||||
<SVG src={menuArrowIcon} />
|
<SVG
|
||||||
|
src={isMenuSmall ? saleorDarkLogoSmall : saleorDarkLogo}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Hidden>
|
<Hidden smDown>
|
||||||
<MenuList
|
<div
|
||||||
className={isMenuSmall ? classes.menuSmall : classes.menu}
|
className={classNames(classes.isMenuSmall, {
|
||||||
menuItems={menuStructure}
|
[classes.isMenuSmallHide]: isMenuSmall,
|
||||||
isMenuSmall={!isMenuSmall}
|
[classes.isMenuSmallDark]: isDark
|
||||||
location={location.pathname}
|
})}
|
||||||
user={user}
|
onClick={handleIsMenuSmall}
|
||||||
renderConfigure={renderConfigure}
|
>
|
||||||
onMenuItemClick={handleMenuItemClick}
|
<SVG src={menuArrowIcon} />
|
||||||
/>
|
</div>
|
||||||
</ResponsiveDrawer>
|
</Hidden>
|
||||||
</div>
|
<MenuList
|
||||||
<div
|
className={isMenuSmall ? classes.menuSmall : classes.menu}
|
||||||
className={classNames(classes.content, {
|
menuItems={menuStructure}
|
||||||
[classes.contentToggle]: isMenuSmall
|
isMenuSmall={!isMenuSmall}
|
||||||
})}
|
location={location.pathname}
|
||||||
>
|
user={user}
|
||||||
{appState.loading ? (
|
renderConfigure={renderConfigure}
|
||||||
<LinearProgress className={classes.appLoader} color="primary" />
|
onMenuItemClick={handleMenuItemClick}
|
||||||
) : (
|
/>
|
||||||
<div className={classes.appLoaderPlaceholder} />
|
</ResponsiveDrawer>
|
||||||
)}
|
</div>
|
||||||
<div className={classes.viewContainer}>
|
<div
|
||||||
<div>
|
className={classNames(classes.content, {
|
||||||
<Container>
|
[classes.contentToggle]: isMenuSmall
|
||||||
<div className={classes.header}>
|
})}
|
||||||
<div
|
>
|
||||||
className={classNames(classes.menuIcon, {
|
{appState.loading ? (
|
||||||
[classes.menuIconOpen]: isDrawerOpened,
|
<LinearProgress className={classes.appLoader} color="primary" />
|
||||||
[classes.menuIconDark]: isDark
|
) : (
|
||||||
})}
|
<div className={classes.appLoaderPlaceholder} />
|
||||||
onClick={() => setDrawerState(!isDrawerOpened)}
|
)}
|
||||||
>
|
<div className={classes.viewContainer}>
|
||||||
<span />
|
<div>
|
||||||
<span />
|
<Container>
|
||||||
<span />
|
<div className={classes.header}>
|
||||||
<span />
|
<div
|
||||||
</div>
|
className={classNames(classes.menuIcon, {
|
||||||
<div ref={appHeaderAnchor} />
|
[classes.menuIconOpen]: isDrawerOpened,
|
||||||
<div className={classes.spacer} />
|
[classes.menuIconDark]: isDark
|
||||||
<div className={classes.userBar}>
|
})}
|
||||||
<ThemeSwitch
|
onClick={() => setDrawerState(!isDrawerOpened)}
|
||||||
className={classes.darkThemeSwitch}
|
>
|
||||||
checked={isDark}
|
<span />
|
||||||
onClick={toggleTheme}
|
<span />
|
||||||
/>
|
<span />
|
||||||
<div className={classes.userMenuContainer} ref={anchor}>
|
<span />
|
||||||
<Chip
|
</div>
|
||||||
avatar={
|
<div ref={appHeaderAnchor} />
|
||||||
user.avatar && (
|
<div className={classes.spacer} />
|
||||||
<Avatar alt="user" src={user.avatar.url} />
|
<div className={classes.userBar}>
|
||||||
)
|
<ThemeSwitch
|
||||||
}
|
className={classes.darkThemeSwitch}
|
||||||
classes={{
|
checked={isDark}
|
||||||
avatar: classes.avatar
|
onClick={toggleTheme}
|
||||||
}}
|
|
||||||
className={classes.userChip}
|
|
||||||
label={
|
|
||||||
<>
|
|
||||||
{user.email}
|
|
||||||
<ArrowDropdown
|
|
||||||
className={classNames(classes.arrow, {
|
|
||||||
[classes.rotate]: isMenuOpened
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
onClick={() => setMenuState(!isMenuOpened)}
|
|
||||||
data-test="userMenu"
|
|
||||||
/>
|
/>
|
||||||
<Popper
|
<NavigatorButton
|
||||||
className={classes.popover}
|
isMac={navigator.platform
|
||||||
open={isMenuOpened}
|
.toLowerCase()
|
||||||
anchorEl={anchor.current}
|
.includes("mac")}
|
||||||
transition
|
onClick={() => setNavigatorVisibility(true)}
|
||||||
placement="bottom-end"
|
/>
|
||||||
>
|
<div className={classes.userMenuContainer} ref={anchor}>
|
||||||
{({ TransitionProps, placement }) => (
|
<Chip
|
||||||
<Grow
|
avatar={
|
||||||
{...TransitionProps}
|
user.avatar && (
|
||||||
style={{
|
<Avatar alt="user" src={user.avatar.url} />
|
||||||
transformOrigin:
|
)
|
||||||
placement === "bottom"
|
}
|
||||||
? "right top"
|
classes={{
|
||||||
: "right bottom"
|
avatar: classes.avatar
|
||||||
}}
|
}}
|
||||||
>
|
className={classes.userChip}
|
||||||
<Paper>
|
label={
|
||||||
<ClickAwayListener
|
<>
|
||||||
onClickAway={() => setMenuState(false)}
|
{user.email}
|
||||||
mouseEvent="onClick"
|
<ArrowDropdown
|
||||||
>
|
className={classNames(classes.arrow, {
|
||||||
<Menu>
|
[classes.rotate]: isMenuOpened
|
||||||
<MenuItem
|
})}
|
||||||
className={classes.userMenuItem}
|
/>
|
||||||
onClick={handleViewerProfile}
|
</>
|
||||||
data-test="accountSettingsButton"
|
}
|
||||||
>
|
onClick={() => setMenuState(!isMenuOpened)}
|
||||||
<FormattedMessage
|
data-test="userMenu"
|
||||||
defaultMessage="Account Settings"
|
/>
|
||||||
description="button"
|
<Popper
|
||||||
/>
|
className={classes.popover}
|
||||||
</MenuItem>
|
open={isMenuOpened}
|
||||||
<MenuItem
|
anchorEl={anchor.current}
|
||||||
className={classes.userMenuItem}
|
transition
|
||||||
onClick={handleLogout}
|
placement="bottom-end"
|
||||||
data-test="logOutButton"
|
>
|
||||||
>
|
{({ TransitionProps, placement }) => (
|
||||||
<FormattedMessage
|
<Grow
|
||||||
defaultMessage="Log out"
|
{...TransitionProps}
|
||||||
description="button"
|
style={{
|
||||||
/>
|
transformOrigin:
|
||||||
</MenuItem>
|
placement === "bottom"
|
||||||
</Menu>
|
? "right top"
|
||||||
</ClickAwayListener>
|
: "right bottom"
|
||||||
</Paper>
|
}}
|
||||||
</Grow>
|
>
|
||||||
)}
|
<Paper>
|
||||||
</Popper>
|
<ClickAwayListener
|
||||||
|
onClickAway={() => setMenuState(false)}
|
||||||
|
mouseEvent="onClick"
|
||||||
|
>
|
||||||
|
<Menu>
|
||||||
|
<MenuItem
|
||||||
|
className={classes.userMenuItem}
|
||||||
|
onClick={handleViewerProfile}
|
||||||
|
data-test="accountSettingsButton"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Account Settings"
|
||||||
|
description="button"
|
||||||
|
/>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
className={classes.userMenuItem}
|
||||||
|
onClick={handleLogout}
|
||||||
|
data-test="logOutButton"
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Log out"
|
||||||
|
description="button"
|
||||||
|
/>
|
||||||
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
</ClickAwayListener>
|
||||||
|
</Paper>
|
||||||
|
</Grow>
|
||||||
|
)}
|
||||||
|
</Popper>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</Container>
|
||||||
</Container>
|
</div>
|
||||||
|
<main className={classes.view}>
|
||||||
|
{appState.error
|
||||||
|
? appState.error === "unhandled" && (
|
||||||
|
<ErrorPage onBack={handleErrorBack} />
|
||||||
|
)
|
||||||
|
: children}
|
||||||
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<main className={classes.view}>
|
<div className={classes.appAction} ref={appActionAnchor} />
|
||||||
{appState.error
|
|
||||||
? appState.error === "unhandled" && (
|
|
||||||
<ErrorPage onBack={handleErrorBack} />
|
|
||||||
)
|
|
||||||
: children}
|
|
||||||
</main>
|
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.appAction} ref={appActionAnchor} />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</AppActionContext.Provider>
|
||||||
</AppActionContext.Provider>
|
</AppHeaderContext.Provider>
|
||||||
</AppHeaderContext.Provider>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,136 +1,25 @@
|
||||||
import ButtonBase from "@material-ui/core/ButtonBase";
|
import MuiCheckbox, {
|
||||||
import { CheckboxProps as MuiCheckboxProps } from "@material-ui/core/Checkbox";
|
CheckboxProps as MuiCheckboxProps
|
||||||
import { makeStyles } from "@material-ui/core/styles";
|
} from "@material-ui/core/Checkbox";
|
||||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
|
||||||
import classNames from "classnames";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
export type CheckboxProps = Omit<
|
export type CheckboxProps = Omit<
|
||||||
MuiCheckboxProps,
|
MuiCheckboxProps,
|
||||||
| "checkedIcon"
|
"checkedIcon" | "color" | "icon" | "indeterminateIcon" | "classes" | "onClick"
|
||||||
| "color"
|
|
||||||
| "icon"
|
|
||||||
| "indeterminateIcon"
|
|
||||||
| "classes"
|
|
||||||
| "onChange"
|
|
||||||
| "onClick"
|
|
||||||
> & {
|
> & {
|
||||||
disableClickPropagation?: boolean;
|
disableClickPropagation?: boolean;
|
||||||
onChange?: (event: React.ChangeEvent<any>) => void;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
|
||||||
theme => ({
|
|
||||||
box: {
|
|
||||||
"&$checked": {
|
|
||||||
"&:before": {
|
|
||||||
background: theme.palette.primary.main,
|
|
||||||
color: theme.palette.background.paper,
|
|
||||||
content: '"\\2713"',
|
|
||||||
fontWeight: "bold",
|
|
||||||
textAlign: "center"
|
|
||||||
},
|
|
||||||
borderColor: theme.palette.primary.main
|
|
||||||
},
|
|
||||||
"&$disabled": {
|
|
||||||
borderColor: theme.palette.grey[200]
|
|
||||||
},
|
|
||||||
"&$indeterminate": {
|
|
||||||
"&:before": {
|
|
||||||
background: theme.palette.primary.main,
|
|
||||||
height: 2,
|
|
||||||
top: 5
|
|
||||||
},
|
|
||||||
borderColor: theme.palette.primary.main
|
|
||||||
},
|
|
||||||
"&:before": {
|
|
||||||
background: "rgba(0, 0, 0, 0)",
|
|
||||||
content: '""',
|
|
||||||
height: 14,
|
|
||||||
left: -1,
|
|
||||||
position: "absolute",
|
|
||||||
top: -1,
|
|
||||||
transition: theme.transitions.duration.short + "ms",
|
|
||||||
width: 14
|
|
||||||
},
|
|
||||||
|
|
||||||
WebkitAppearance: "none",
|
|
||||||
border: `1px solid ${theme.palette.action.active}`,
|
|
||||||
boxSizing: "border-box",
|
|
||||||
cursor: "pointer",
|
|
||||||
height: 14,
|
|
||||||
outline: "0",
|
|
||||||
position: "relative",
|
|
||||||
userSelect: "none",
|
|
||||||
width: 14
|
|
||||||
},
|
|
||||||
checked: {},
|
|
||||||
disabled: {},
|
|
||||||
indeterminate: {},
|
|
||||||
root: {
|
|
||||||
"&:hover": {
|
|
||||||
background: fade(theme.palette.primary.main, 0.1)
|
|
||||||
},
|
|
||||||
alignSelf: "start",
|
|
||||||
borderRadius: "100%",
|
|
||||||
cursor: "pointer",
|
|
||||||
display: "flex",
|
|
||||||
height: 30,
|
|
||||||
justifyContent: "center",
|
|
||||||
margin: "5px 9px",
|
|
||||||
width: 30
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
{ name: "Checkbox" }
|
|
||||||
);
|
|
||||||
const Checkbox: React.FC<CheckboxProps> = props => {
|
const Checkbox: React.FC<CheckboxProps> = props => {
|
||||||
const {
|
const { disableClickPropagation, ...rest } = props;
|
||||||
checked,
|
|
||||||
className,
|
|
||||||
|
|
||||||
disabled,
|
|
||||||
disableClickPropagation,
|
|
||||||
indeterminate,
|
|
||||||
onChange,
|
|
||||||
value,
|
|
||||||
name,
|
|
||||||
...rest
|
|
||||||
} = props;
|
|
||||||
const classes = useStyles(props);
|
|
||||||
|
|
||||||
const inputRef = React.useRef<HTMLInputElement>(null);
|
|
||||||
const handleClick = React.useCallback(
|
|
||||||
disableClickPropagation
|
|
||||||
? event => {
|
|
||||||
event.stopPropagation();
|
|
||||||
inputRef.current.click();
|
|
||||||
}
|
|
||||||
: () => inputRef.current.click(),
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ButtonBase
|
<MuiCheckbox
|
||||||
{...rest}
|
{...rest}
|
||||||
centerRipple
|
onClick={
|
||||||
className={classNames(classes.root, className)}
|
disableClickPropagation ? event => event.stopPropagation() : undefined
|
||||||
disabled={disabled}
|
}
|
||||||
onClick={handleClick}
|
/>
|
||||||
>
|
|
||||||
<input
|
|
||||||
className={classNames(classes.box, {
|
|
||||||
[classes.checked]: checked,
|
|
||||||
[classes.disabled]: disabled,
|
|
||||||
[classes.indeterminate]: indeterminate
|
|
||||||
})}
|
|
||||||
disabled={disabled}
|
|
||||||
type="checkbox"
|
|
||||||
name={name}
|
|
||||||
value={checked !== undefined && checked.toString()}
|
|
||||||
ref={inputRef}
|
|
||||||
onChange={onChange}
|
|
||||||
/>
|
|
||||||
</ButtonBase>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
Checkbox.displayName = "Checkbox";
|
Checkbox.displayName = "Checkbox";
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
|
import Checkbox from "@material-ui/core/Checkbox";
|
||||||
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import Checkbox from "./Checkbox";
|
|
||||||
|
|
||||||
interface ControlledCheckboxProps {
|
interface ControlledCheckboxProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -27,7 +26,6 @@ export const ControlledCheckbox: React.FC<ControlledCheckboxProps> = ({
|
||||||
checked={checked}
|
checked={checked}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
name={name}
|
name={name}
|
||||||
disableClickPropagation
|
|
||||||
onChange={() => onChange({ target: { name, value: !checked } })}
|
onChange={() => onChange({ target: { name, value: !checked } })}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,8 +60,12 @@ const useStyles = makeStyles(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const Navigator: React.FC = () => {
|
export interface NavigatorProps {
|
||||||
const [visible, setVisible] = React.useState(false);
|
visible: boolean;
|
||||||
|
setVisibility: (state: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Navigator: React.FC<NavigatorProps> = ({ visible, setVisibility }) => {
|
||||||
const input = React.useRef(null);
|
const input = React.useRef(null);
|
||||||
const [query, mode, change, actions] = useQuickSearch(visible, input);
|
const [query, mode, change, actions] = useQuickSearch(visible, input);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
@ -76,7 +80,7 @@ const Navigator: React.FC = () => {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
hotkeys(navigatorHotkey, event => {
|
hotkeys(navigatorHotkey, event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
setVisible(!visible);
|
setVisibility(!visible);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (cmp(APP_VERSION, "2.1.0") !== 1 && !notifiedAboutNavigator) {
|
if (cmp(APP_VERSION, "2.1.0") !== 1 && !notifiedAboutNavigator) {
|
||||||
|
@ -110,7 +114,7 @@ const Navigator: React.FC = () => {
|
||||||
<Modal
|
<Modal
|
||||||
className={classes.modal}
|
className={classes.modal}
|
||||||
open={visible}
|
open={visible}
|
||||||
onClose={() => setVisible(false)}
|
onClose={() => setVisibility(false)}
|
||||||
>
|
>
|
||||||
<Fade appear in={visible} timeout={theme.transitions.duration.short}>
|
<Fade appear in={visible} timeout={theme.transitions.duration.short}>
|
||||||
<div className={classes.root}>
|
<div className={classes.root}>
|
||||||
|
@ -122,7 +126,7 @@ const Navigator: React.FC = () => {
|
||||||
onSelect={(item: QuickSearchAction) => {
|
onSelect={(item: QuickSearchAction) => {
|
||||||
const shouldRemainVisible = item.onClick();
|
const shouldRemainVisible = item.onClick();
|
||||||
if (!shouldRemainVisible) {
|
if (!shouldRemainVisible) {
|
||||||
setVisible(false);
|
setVisibility(false);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onInputValueChange={value =>
|
onInputValueChange={value =>
|
||||||
|
|
12
src/components/NavigatorButton/NavigatorButton.stories.tsx
Normal file
12
src/components/NavigatorButton/NavigatorButton.stories.tsx
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import CardDecorator from "@saleor/storybook/CardDecorator";
|
||||||
|
import Decorator from "@saleor/storybook/Decorator";
|
||||||
|
import { storiesOf } from "@storybook/react";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import NavigatorButton from "./NavigatorButton";
|
||||||
|
|
||||||
|
storiesOf("Generics / NavigatorButton", module)
|
||||||
|
.addDecorator(Decorator)
|
||||||
|
.addDecorator(CardDecorator)
|
||||||
|
.add("mac", () => <NavigatorButton isMac={true} />)
|
||||||
|
.add("other", () => <NavigatorButton isMac={false} />);
|
153
src/components/NavigatorButton/NavigatorButton.tsx
Normal file
153
src/components/NavigatorButton/NavigatorButton.tsx
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
import navigatorIcon from "@assets/images/navigator.svg";
|
||||||
|
import Grow from "@material-ui/core/Grow";
|
||||||
|
import IconButton, { IconButtonProps } from "@material-ui/core/IconButton";
|
||||||
|
import Paper from "@material-ui/core/Paper";
|
||||||
|
import Popper from "@material-ui/core/Popper";
|
||||||
|
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||||
|
import classNames from "classnames";
|
||||||
|
import React from "react";
|
||||||
|
import ReactSVG from "react-inlinesvg";
|
||||||
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
|
const useStyles = makeStyles(
|
||||||
|
theme => {
|
||||||
|
const triangle = (color: string, width: number) => ({
|
||||||
|
borderBottom: `${width}px solid ${color}`,
|
||||||
|
borderLeft: `${width}px solid transparent`,
|
||||||
|
borderRight: `${width}px solid transparent`,
|
||||||
|
height: 0,
|
||||||
|
width: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
keyTile: {
|
||||||
|
"&:first-child": {
|
||||||
|
marginLeft: theme.spacing()
|
||||||
|
},
|
||||||
|
alignItems: "center",
|
||||||
|
background: theme.palette.background.default,
|
||||||
|
borderRadius: 8,
|
||||||
|
display: "inline-flex",
|
||||||
|
height: 32,
|
||||||
|
justifyContent: "center",
|
||||||
|
marginLeft: theme.spacing(0.5),
|
||||||
|
padding: theme.spacing(),
|
||||||
|
width: 32
|
||||||
|
},
|
||||||
|
keyTileLabel: {
|
||||||
|
verticalAlign: "middle"
|
||||||
|
},
|
||||||
|
paper: {
|
||||||
|
"&:after": {
|
||||||
|
...triangle(theme.palette.background.paper, 7),
|
||||||
|
content: "''",
|
||||||
|
left: theme.spacing(2) + 2,
|
||||||
|
position: "absolute",
|
||||||
|
top: -theme.spacing() + 1
|
||||||
|
},
|
||||||
|
"&:before": {
|
||||||
|
...triangle(theme.palette.divider, 8),
|
||||||
|
content: "''",
|
||||||
|
left: theme.spacing(2) + 1,
|
||||||
|
position: "absolute",
|
||||||
|
top: -theme.spacing()
|
||||||
|
},
|
||||||
|
border: `1px solid ${theme.palette.divider}`,
|
||||||
|
borderRadius: 6,
|
||||||
|
marginTop: theme.spacing(2),
|
||||||
|
padding: theme.spacing(2),
|
||||||
|
position: "relative"
|
||||||
|
},
|
||||||
|
|
||||||
|
root: {
|
||||||
|
"& path": {
|
||||||
|
color: theme.palette.primary.main
|
||||||
|
},
|
||||||
|
"&:not(:hover)": {
|
||||||
|
backgroundColor: theme.palette.background.paper
|
||||||
|
},
|
||||||
|
border: `1px solid ${theme.palette.divider}`,
|
||||||
|
height: 40,
|
||||||
|
marginRight: theme.spacing(2),
|
||||||
|
width: 40
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "NavigatorButton"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export interface NavigatorButtonProps extends IconButtonProps {
|
||||||
|
isMac: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NavigatorButton: React.FC<NavigatorButtonProps> = ({
|
||||||
|
className,
|
||||||
|
isMac,
|
||||||
|
...props
|
||||||
|
}) => {
|
||||||
|
const classes = useStyles({});
|
||||||
|
const helperTimer = React.useRef(null);
|
||||||
|
const [helperVisibility, setHelperVisibility] = React.useState(false);
|
||||||
|
const anchor = React.useRef<HTMLButtonElement>();
|
||||||
|
|
||||||
|
const setHelper = () => {
|
||||||
|
helperTimer.current = setTimeout(() => setHelperVisibility(true), 2 * 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const clearHelper = () => {
|
||||||
|
if (helperTimer.current) {
|
||||||
|
clearTimeout(helperTimer.current);
|
||||||
|
helperTimer.current = null;
|
||||||
|
}
|
||||||
|
setHelperVisibility(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<IconButton
|
||||||
|
className={classNames(className, classes.root)}
|
||||||
|
data-test="navigator"
|
||||||
|
onMouseEnter={setHelper}
|
||||||
|
onMouseLeave={clearHelper}
|
||||||
|
{...props}
|
||||||
|
ref={anchor}
|
||||||
|
>
|
||||||
|
<ReactSVG src={navigatorIcon} />
|
||||||
|
</IconButton>
|
||||||
|
<Popper
|
||||||
|
open={helperVisibility}
|
||||||
|
anchorEl={anchor.current}
|
||||||
|
transition
|
||||||
|
disablePortal
|
||||||
|
placement="bottom-start"
|
||||||
|
>
|
||||||
|
{({ TransitionProps, placement }) => (
|
||||||
|
<Grow
|
||||||
|
{...TransitionProps}
|
||||||
|
style={{
|
||||||
|
transformOrigin:
|
||||||
|
placement === "bottom" ? "right top" : "right bottom"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Paper className={classes.paper} elevation={0}>
|
||||||
|
<FormattedMessage defaultMessage="Navigator" />
|
||||||
|
<div className={classes.keyTile}>
|
||||||
|
<span className={classes.keyTileLabel}>
|
||||||
|
{isMac ? "⌘" : "Ctrl"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className={classes.keyTile}>
|
||||||
|
<span className={classes.keyTileLabel}>K</span>
|
||||||
|
</div>
|
||||||
|
</Paper>
|
||||||
|
</Grow>
|
||||||
|
)}
|
||||||
|
</Popper>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
NavigatorButton.displayName = "NavigatorButton";
|
||||||
|
export default NavigatorButton;
|
|
@ -28,23 +28,6 @@ const useStyles = makeStyles(
|
||||||
cell: {
|
cell: {
|
||||||
padding: 0
|
padding: 0
|
||||||
},
|
},
|
||||||
checkboxPartialSelect: {
|
|
||||||
"& input": {
|
|
||||||
"&:before": {
|
|
||||||
background: [theme.palette.background.paper, "!important"] as any,
|
|
||||||
border: `solid 1px ${theme.palette.primary.main}`,
|
|
||||||
content: "''"
|
|
||||||
},
|
|
||||||
background: theme.palette.background.paper
|
|
||||||
},
|
|
||||||
"&:after": {
|
|
||||||
background: theme.palette.primary.main,
|
|
||||||
content: "''",
|
|
||||||
height: 2,
|
|
||||||
position: "absolute",
|
|
||||||
width: 6
|
|
||||||
}
|
|
||||||
},
|
|
||||||
checkboxSelected: {
|
checkboxSelected: {
|
||||||
backgroundColor: fade(theme.palette.primary.main, 0.05)
|
backgroundColor: fade(theme.palette.primary.main, 0.05)
|
||||||
},
|
},
|
||||||
|
@ -113,10 +96,7 @@ const TableHead: React.FC<TableHeadProps> = props => {
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
className={classNames({
|
indeterminate={items && items.length > selected && selected > 0}
|
||||||
[classes.checkboxPartialSelect]:
|
|
||||||
items && items.length > selected && selected > 0
|
|
||||||
})}
|
|
||||||
checked={selected === 0 ? false : true}
|
checked={selected === 0 ? false : true}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onChange={() => toggleAll(items, selected)}
|
onChange={() => toggleAll(items, selected)}
|
||||||
|
|
|
@ -117,4 +117,7 @@ export const {
|
||||||
export const { areFiltersApplied, getActiveFilters } = createFilterUtils<
|
export const { areFiltersApplied, getActiveFilters } = createFilterUtils<
|
||||||
SaleListUrlQueryParams,
|
SaleListUrlQueryParams,
|
||||||
SaleListUrlFilters
|
SaleListUrlFilters
|
||||||
>(SaleListUrlFiltersEnum);
|
>({
|
||||||
|
...SaleListUrlFiltersEnum,
|
||||||
|
...SaleListUrlFiltersWithMultipleValues
|
||||||
|
});
|
||||||
|
|
|
@ -149,4 +149,7 @@ export const {
|
||||||
export const { areFiltersApplied, getActiveFilters } = createFilterUtils<
|
export const { areFiltersApplied, getActiveFilters } = createFilterUtils<
|
||||||
VoucherListUrlQueryParams,
|
VoucherListUrlQueryParams,
|
||||||
VoucherListUrlFilters
|
VoucherListUrlFilters
|
||||||
>(VoucherListUrlFiltersEnum);
|
>({
|
||||||
|
...VoucherListUrlFiltersEnum,
|
||||||
|
...VoucherListUrlFiltersWithMultipleValues
|
||||||
|
});
|
||||||
|
|
|
@ -33,6 +33,9 @@ export const permissionGroupDetailsFragment = gql`
|
||||||
}
|
}
|
||||||
users {
|
users {
|
||||||
...StaffMemberFragment
|
...StaffMemberFragment
|
||||||
|
avatar(size: 48) {
|
||||||
|
url
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -7,9 +7,6 @@ export const staffMemberFragment = gql`
|
||||||
firstName
|
firstName
|
||||||
isActive
|
isActive
|
||||||
lastName
|
lastName
|
||||||
avatar {
|
|
||||||
url
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
export const staffMemberDetailsFragment = gql`
|
export const staffMemberDetailsFragment = gql`
|
||||||
|
@ -25,5 +22,8 @@ export const staffMemberDetailsFragment = gql`
|
||||||
code
|
code
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
|
avatar(size: 120) {
|
||||||
|
url
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeInputTypeEnum } from "./../../types/globalTypes";
|
import { AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL fragment: Product
|
// GraphQL fragment: Product
|
||||||
|
@ -170,7 +170,7 @@ export interface Product_variants {
|
||||||
|
|
||||||
export interface Product_weight {
|
export interface Product_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL fragment: ProductTypeDetailsFragment
|
// GraphQL fragment: ProductTypeDetailsFragment
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
@ -34,7 +36,7 @@ export interface ProductTypeDetailsFragment_variantAttributes {
|
||||||
|
|
||||||
export interface ProductTypeDetailsFragment_weight {
|
export interface ProductTypeDetailsFragment_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL fragment: ProductVariant
|
// GraphQL fragment: ProductVariant
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
@ -105,7 +107,7 @@ export interface ProductVariant_stocks {
|
||||||
|
|
||||||
export interface ProductVariant_weight {
|
export interface ProductVariant_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
import { WeightUnitsEnum, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL fragment: ShippingMethodFragment
|
// GraphQL fragment: ShippingMethodFragment
|
||||||
|
@ -16,7 +16,7 @@ export interface ShippingMethodFragment_minimumOrderPrice {
|
||||||
|
|
||||||
export interface ShippingMethodFragment_minimumOrderWeight {
|
export interface ShippingMethodFragment_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ export interface ShippingMethodFragment_maximumOrderPrice {
|
||||||
|
|
||||||
export interface ShippingMethodFragment_maximumOrderWeight {
|
export interface ShippingMethodFragment_maximumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
import { WeightUnitsEnum, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL fragment: ShippingZoneDetailsFragment
|
// GraphQL fragment: ShippingZoneDetailsFragment
|
||||||
|
@ -22,7 +22,7 @@ export interface ShippingZoneDetailsFragment_shippingMethods_minimumOrderPrice {
|
||||||
|
|
||||||
export interface ShippingZoneDetailsFragment_shippingMethods_minimumOrderWeight {
|
export interface ShippingZoneDetailsFragment_shippingMethods_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ export interface ShippingZoneDetailsFragment_shippingMethods_maximumOrderPrice {
|
||||||
|
|
||||||
export interface ShippingZoneDetailsFragment_shippingMethods_maximumOrderWeight {
|
export interface ShippingZoneDetailsFragment_shippingMethods_maximumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,6 @@ import { PermissionEnum } from "./../../types/globalTypes";
|
||||||
// GraphQL fragment: StaffMemberDetailsFragment
|
// GraphQL fragment: StaffMemberDetailsFragment
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface StaffMemberDetailsFragment_avatar {
|
|
||||||
__typename: "Image";
|
|
||||||
url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StaffMemberDetailsFragment_permissionGroups {
|
export interface StaffMemberDetailsFragment_permissionGroups {
|
||||||
__typename: "Group";
|
__typename: "Group";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -26,6 +21,11 @@ export interface StaffMemberDetailsFragment_userPermissions {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface StaffMemberDetailsFragment_avatar {
|
||||||
|
__typename: "Image";
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface StaffMemberDetailsFragment {
|
export interface StaffMemberDetailsFragment {
|
||||||
__typename: "User";
|
__typename: "User";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -33,7 +33,7 @@ export interface StaffMemberDetailsFragment {
|
||||||
firstName: string;
|
firstName: string;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
avatar: StaffMemberDetailsFragment_avatar | null;
|
|
||||||
permissionGroups: (StaffMemberDetailsFragment_permissionGroups | null)[] | null;
|
permissionGroups: (StaffMemberDetailsFragment_permissionGroups | null)[] | null;
|
||||||
userPermissions: (StaffMemberDetailsFragment_userPermissions | null)[] | null;
|
userPermissions: (StaffMemberDetailsFragment_userPermissions | null)[] | null;
|
||||||
|
avatar: StaffMemberDetailsFragment_avatar | null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,6 @@
|
||||||
// GraphQL fragment: StaffMemberFragment
|
// GraphQL fragment: StaffMemberFragment
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface StaffMemberFragment_avatar {
|
|
||||||
__typename: "Image";
|
|
||||||
url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StaffMemberFragment {
|
export interface StaffMemberFragment {
|
||||||
__typename: "User";
|
__typename: "User";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -18,5 +13,4 @@ export interface StaffMemberFragment {
|
||||||
firstName: string;
|
firstName: string;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
avatar: StaffMemberFragment_avatar | null;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL fragment: WeightFragment
|
// GraphQL fragment: WeightFragment
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface WeightFragment {
|
export interface WeightFragment {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
18
src/icons/Checkbox.tsx
Normal file
18
src/icons/Checkbox.tsx
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import createSvgIcon from "@material-ui/icons/utils/createSvgIcon";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const Checkbox = createSvgIcon(
|
||||||
|
<>
|
||||||
|
<rect
|
||||||
|
x="5"
|
||||||
|
y="5"
|
||||||
|
width="14"
|
||||||
|
height="14"
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
/>
|
||||||
|
</>,
|
||||||
|
"Checkbox"
|
||||||
|
);
|
||||||
|
|
||||||
|
export default Checkbox;
|
17
src/icons/CheckboxChecked.tsx
Normal file
17
src/icons/CheckboxChecked.tsx
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import createSvgIcon from "@material-ui/icons/utils/createSvgIcon";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const CheckboxChecked = createSvgIcon(
|
||||||
|
<>
|
||||||
|
<rect x="5" y="5" width="14" height="14" fill="currentColor" />
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
clipRule="evenodd"
|
||||||
|
d="M 16.7527 9.33783 L 10.86618 15.7595 L 8 12.32006 L 8.76822 11.67988 L 10.90204 14.24046 L 16.0155 8.66211 L 16.7527 9.33783 Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
</>,
|
||||||
|
"CheckboxChecked"
|
||||||
|
);
|
||||||
|
|
||||||
|
export default CheckboxChecked;
|
19
src/icons/CheckboxIndeterminate.tsx
Normal file
19
src/icons/CheckboxIndeterminate.tsx
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import createSvgIcon from "@material-ui/icons/utils/createSvgIcon";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const CheckboxIndeterminate = createSvgIcon(
|
||||||
|
<>
|
||||||
|
<rect
|
||||||
|
x="5"
|
||||||
|
y="5"
|
||||||
|
width="14"
|
||||||
|
height="14"
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
/>
|
||||||
|
<rect x="8" y="11" width="8" height="2" fill="currentColor" />
|
||||||
|
</>,
|
||||||
|
"CheckboxIndeterminate"
|
||||||
|
);
|
||||||
|
|
||||||
|
export default CheckboxIndeterminate;
|
|
@ -1,4 +1,3 @@
|
||||||
import Navigator from "@saleor/components/Navigator";
|
|
||||||
import useAppState from "@saleor/hooks/useAppState";
|
import useAppState from "@saleor/hooks/useAppState";
|
||||||
import { defaultDataIdFromObject, InMemoryCache } from "apollo-cache-inmemory";
|
import { defaultDataIdFromObject, InMemoryCache } from "apollo-cache-inmemory";
|
||||||
import { ApolloClient } from "apollo-client";
|
import { ApolloClient } from "apollo-client";
|
||||||
|
@ -139,7 +138,6 @@ const Routes: React.FC = () => {
|
||||||
<WindowTitle title={intl.formatMessage(commonMessages.dashboard)} />
|
<WindowTitle title={intl.formatMessage(commonMessages.dashboard)} />
|
||||||
{isAuthenticated && !tokenAuthLoading && !tokenVerifyLoading ? (
|
{isAuthenticated && !tokenAuthLoading && !tokenVerifyLoading ? (
|
||||||
<AppLayout>
|
<AppLayout>
|
||||||
<Navigator />
|
|
||||||
<ErrorBoundary
|
<ErrorBoundary
|
||||||
onError={() =>
|
onError={() =>
|
||||||
dispatchAppState({
|
dispatchAppState({
|
||||||
|
|
|
@ -306,10 +306,10 @@ export function createHref(url: string) {
|
||||||
interface AnyEvent {
|
interface AnyEvent {
|
||||||
stopPropagation: () => void;
|
stopPropagation: () => void;
|
||||||
}
|
}
|
||||||
export function stopPropagation(cb: () => void) {
|
export function stopPropagation(cb: (event?: AnyEvent) => void) {
|
||||||
return (event: AnyEvent) => {
|
return (event: AnyEvent) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
cb();
|
cb(event);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,8 @@ const useStyles = makeStyles(
|
||||||
width: 47
|
width: 47
|
||||||
},
|
},
|
||||||
avatarDefault: {
|
avatarDefault: {
|
||||||
"& p": {
|
"& div": {
|
||||||
color: "#fff",
|
color: theme.palette.primary.contrastText,
|
||||||
lineHeight: "47px"
|
lineHeight: "47px"
|
||||||
},
|
},
|
||||||
background: theme.palette.primary.main,
|
background: theme.palette.primary.main,
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {
|
||||||
SearchProductTypes_search_edges_node_productAttributes
|
SearchProductTypes_search_edges_node_productAttributes
|
||||||
} from "@saleor/searches/types/SearchProductTypes";
|
} from "@saleor/searches/types/SearchProductTypes";
|
||||||
|
|
||||||
import { AttributeInputTypeEnum } from "../types/globalTypes";
|
import { AttributeInputTypeEnum, WeightUnitsEnum } from "../types/globalTypes";
|
||||||
import { ProductTypeDetails_productType } from "./types/ProductTypeDetails";
|
import { ProductTypeDetails_productType } from "./types/ProductTypeDetails";
|
||||||
import { ProductTypeList_productTypes_edges_node } from "./types/ProductTypeList";
|
import { ProductTypeList_productTypes_edges_node } from "./types/ProductTypeList";
|
||||||
|
|
||||||
|
@ -601,7 +601,7 @@ export const productType: ProductTypeDetails_productType = {
|
||||||
],
|
],
|
||||||
weight: {
|
weight: {
|
||||||
__typename: "Weight",
|
__typename: "Weight",
|
||||||
unit: "kg",
|
unit: WeightUnitsEnum.KG,
|
||||||
value: 7.82
|
value: 7.82
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeAssignInput } from "./../../types/globalTypes";
|
import { AttributeAssignInput, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: AssignAttribute
|
// GraphQL mutation operation: AssignAttribute
|
||||||
|
@ -42,7 +42,7 @@ export interface AssignAttribute_attributeAssign_productType_variantAttributes {
|
||||||
|
|
||||||
export interface AssignAttribute_attributeAssign_productType_weight {
|
export interface AssignAttribute_attributeAssign_productType_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ReorderInput, AttributeTypeEnum } from "./../../types/globalTypes";
|
import { ReorderInput, AttributeTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: ProductTypeAttributeReorder
|
// GraphQL mutation operation: ProductTypeAttributeReorder
|
||||||
|
@ -42,7 +42,7 @@ export interface ProductTypeAttributeReorder_productTypeReorderAttributes_produc
|
||||||
|
|
||||||
export interface ProductTypeAttributeReorder_productTypeReorderAttributes_productType_weight {
|
export interface ProductTypeAttributeReorder_productTypeReorderAttributes_productType_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductTypeInput } from "./../../types/globalTypes";
|
import { ProductTypeInput, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: ProductTypeCreate
|
// GraphQL mutation operation: ProductTypeCreate
|
||||||
|
@ -42,7 +42,7 @@ export interface ProductTypeCreate_productTypeCreate_productType_variantAttribut
|
||||||
|
|
||||||
export interface ProductTypeCreate_productTypeCreate_productType_weight {
|
export interface ProductTypeCreate_productTypeCreate_productType_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ export interface ProductTypeDetails_productType_variantAttributes {
|
||||||
|
|
||||||
export interface ProductTypeDetails_productType_weight {
|
export interface ProductTypeDetails_productType_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductTypeInput } from "./../../types/globalTypes";
|
import { ProductTypeInput, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: ProductTypeUpdate
|
// GraphQL mutation operation: ProductTypeUpdate
|
||||||
|
@ -42,7 +42,7 @@ export interface ProductTypeUpdate_productTypeUpdate_productType_variantAttribut
|
||||||
|
|
||||||
export interface ProductTypeUpdate_productTypeUpdate_productType_weight {
|
export interface ProductTypeUpdate_productTypeUpdate_productType_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: UnassignAttribute
|
// GraphQL mutation operation: UnassignAttribute
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
@ -40,7 +42,7 @@ export interface UnassignAttribute_attributeUnassign_productType_variantAttribut
|
||||||
|
|
||||||
export interface UnassignAttribute_attributeUnassign_productType_weight {
|
export interface UnassignAttribute_attributeUnassign_productType_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {
|
||||||
ExportErrorCode,
|
ExportErrorCode,
|
||||||
ExportProductsInput
|
ExportProductsInput
|
||||||
} from "@saleor/types/globalTypes";
|
} from "@saleor/types/globalTypes";
|
||||||
|
import { warehouseList } from "@saleor/warehouses/fixtures";
|
||||||
import { storiesOf } from "@storybook/react";
|
import { storiesOf } from "@storybook/react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
|
@ -30,7 +31,8 @@ const props: ProductExportDialogProps = {
|
||||||
all: 100,
|
all: 100,
|
||||||
filter: 32
|
filter: 32
|
||||||
},
|
},
|
||||||
selectedProducts: 18
|
selectedProducts: 18,
|
||||||
|
warehouses: warehouseList
|
||||||
};
|
};
|
||||||
|
|
||||||
storiesOf("Views / Products / Export / Export settings", module)
|
storiesOf("Views / Products / Export / Export settings", module)
|
||||||
|
|
|
@ -8,11 +8,11 @@ import ConfirmButton, {
|
||||||
ConfirmButtonTransitionState
|
ConfirmButtonTransitionState
|
||||||
} from "@saleor/components/ConfirmButton";
|
} from "@saleor/components/ConfirmButton";
|
||||||
import makeCreatorSteps, { Step } from "@saleor/components/CreatorSteps";
|
import makeCreatorSteps, { Step } from "@saleor/components/CreatorSteps";
|
||||||
import Form from "@saleor/components/Form";
|
|
||||||
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField";
|
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField";
|
||||||
import { ExportErrorFragment } from "@saleor/fragments/types/ExportErrorFragment";
|
import { ExportErrorFragment } from "@saleor/fragments/types/ExportErrorFragment";
|
||||||
import { FormChange } from "@saleor/hooks/useForm";
|
import useForm, { FormChange } from "@saleor/hooks/useForm";
|
||||||
import useModalDialogErrors from "@saleor/hooks/useModalDialogErrors";
|
import useModalDialogErrors from "@saleor/hooks/useModalDialogErrors";
|
||||||
|
import useModalDialogOpen from "@saleor/hooks/useModalDialogOpen";
|
||||||
import useWizard from "@saleor/hooks/useWizard";
|
import useWizard from "@saleor/hooks/useWizard";
|
||||||
import { buttonMessages } from "@saleor/intl";
|
import { buttonMessages } from "@saleor/intl";
|
||||||
import { SearchAttributes_search_edges_node } from "@saleor/searches/types/SearchAttributes";
|
import { SearchAttributes_search_edges_node } from "@saleor/searches/types/SearchAttributes";
|
||||||
|
@ -25,11 +25,13 @@ import {
|
||||||
import getExportErrorMessage from "@saleor/utils/errors/export";
|
import getExportErrorMessage from "@saleor/utils/errors/export";
|
||||||
import { toggle } from "@saleor/utils/lists";
|
import { toggle } from "@saleor/utils/lists";
|
||||||
import { mapNodeToChoice } from "@saleor/utils/maps";
|
import { mapNodeToChoice } from "@saleor/utils/maps";
|
||||||
|
import { WarehouseList_warehouses_edges_node } from "@saleor/warehouses/types/WarehouseList";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import ProductExportDialogInfo, {
|
import ProductExportDialogInfo, {
|
||||||
attributeNamePrefix
|
attributeNamePrefix,
|
||||||
|
warehouseNamePrefix
|
||||||
} from "./ProductExportDialogInfo";
|
} from "./ProductExportDialogInfo";
|
||||||
import ProductExportDialogSettings, {
|
import ProductExportDialogSettings, {
|
||||||
ProductQuantity
|
ProductQuantity
|
||||||
|
@ -64,7 +66,8 @@ function useSteps(): Array<Step<ProductExportStep>> {
|
||||||
const initialForm: ExportProductsInput = {
|
const initialForm: ExportProductsInput = {
|
||||||
exportInfo: {
|
exportInfo: {
|
||||||
attributes: [],
|
attributes: [],
|
||||||
fields: []
|
fields: [],
|
||||||
|
warehouses: []
|
||||||
},
|
},
|
||||||
fileType: FileTypesEnum.CSV,
|
fileType: FileTypesEnum.CSV,
|
||||||
scope: ExportScope.ALL
|
scope: ExportScope.ALL
|
||||||
|
@ -78,6 +81,7 @@ export interface ProductExportDialogProps extends DialogProps, FetchMoreProps {
|
||||||
errors: ExportErrorFragment[];
|
errors: ExportErrorFragment[];
|
||||||
productQuantity: ProductQuantity;
|
productQuantity: ProductQuantity;
|
||||||
selectedProducts: number;
|
selectedProducts: number;
|
||||||
|
warehouses: WarehouseList_warehouses_edges_node[];
|
||||||
onFetch: (query: string) => void;
|
onFetch: (query: string) => void;
|
||||||
onSubmit: (data: ExportProductsInput) => void;
|
onSubmit: (data: ExportProductsInput) => void;
|
||||||
}
|
}
|
||||||
|
@ -91,6 +95,7 @@ const ProductExportDialog: React.FC<ProductExportDialogProps> = ({
|
||||||
onSubmit,
|
onSubmit,
|
||||||
open,
|
open,
|
||||||
selectedProducts,
|
selectedProducts,
|
||||||
|
warehouses,
|
||||||
...fetchMoreProps
|
...fetchMoreProps
|
||||||
}) => {
|
}) => {
|
||||||
const [step, { next, prev, set: setStep }] = useWizard(
|
const [step, { next, prev, set: setStep }] = useWizard(
|
||||||
|
@ -104,121 +109,153 @@ const ProductExportDialog: React.FC<ProductExportDialogProps> = ({
|
||||||
const [selectedAttributes, setSelectedAttributes] = React.useState<
|
const [selectedAttributes, setSelectedAttributes] = React.useState<
|
||||||
MultiAutocompleteChoiceType[]
|
MultiAutocompleteChoiceType[]
|
||||||
>([]);
|
>([]);
|
||||||
|
const { change, data, reset, submit } = useForm(initialForm, onSubmit);
|
||||||
|
|
||||||
|
useModalDialogOpen(open, {
|
||||||
|
onClose: () => {
|
||||||
|
reset();
|
||||||
|
setStep(ProductExportStep.INFO);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const attributeChoices = mapNodeToChoice(attributes);
|
const attributeChoices = mapNodeToChoice(attributes);
|
||||||
|
const warehouseChoices = mapNodeToChoice(warehouses);
|
||||||
|
|
||||||
|
const handleAttributeSelect: FormChange = event => {
|
||||||
|
const id = event.target.name.substr(attributeNamePrefix.length);
|
||||||
|
|
||||||
|
change({
|
||||||
|
target: {
|
||||||
|
name: "exportInfo",
|
||||||
|
value: {
|
||||||
|
...data.exportInfo,
|
||||||
|
attributes: toggle(id, data.exportInfo.attributes, (a, b) => a === b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const choice = attributeChoices.find(choice => choice.value === id);
|
||||||
|
|
||||||
|
setSelectedAttributes(
|
||||||
|
toggle(choice, selectedAttributes, (a, b) => a.value === b.value)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleWarehouseSelect: FormChange = event =>
|
||||||
|
change({
|
||||||
|
target: {
|
||||||
|
name: "exportInfo",
|
||||||
|
value: {
|
||||||
|
...data.exportInfo,
|
||||||
|
warehouses: toggle(
|
||||||
|
event.target.name.substr(warehouseNamePrefix.length),
|
||||||
|
data.exportInfo.warehouses,
|
||||||
|
(a, b) => a === b
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleToggleAllWarehouses: FormChange = () =>
|
||||||
|
change({
|
||||||
|
target: {
|
||||||
|
name: "exportInfo",
|
||||||
|
value: {
|
||||||
|
...data.exportInfo,
|
||||||
|
warehouses:
|
||||||
|
data.exportInfo.warehouses.length === warehouses.length
|
||||||
|
? []
|
||||||
|
: warehouses.map(warehouse => warehouse.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog onClose={onClose} open={open} maxWidth="sm" fullWidth>
|
<Dialog onClose={onClose} open={open} maxWidth="sm" fullWidth>
|
||||||
<Form initial={initialForm} onSubmit={onSubmit}>
|
<>
|
||||||
{({ change, data }) => {
|
<DialogTitle>
|
||||||
const handleAttributeSelect: FormChange = event => {
|
<FormattedMessage
|
||||||
const id = event.target.name.substr(attributeNamePrefix.length);
|
defaultMessage="Export Information"
|
||||||
|
description="export products to csv file, dialog header"
|
||||||
|
/>
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<ProductExportSteps
|
||||||
|
currentStep={step}
|
||||||
|
steps={steps}
|
||||||
|
onStepClick={setStep}
|
||||||
|
/>
|
||||||
|
{step === ProductExportStep.INFO && (
|
||||||
|
<ProductExportDialogInfo
|
||||||
|
attributes={attributeChoices}
|
||||||
|
data={data}
|
||||||
|
selectedAttributes={selectedAttributes}
|
||||||
|
onAttrtibuteSelect={handleAttributeSelect}
|
||||||
|
onWarehouseSelect={handleWarehouseSelect}
|
||||||
|
onChange={change}
|
||||||
|
warehouses={warehouseChoices}
|
||||||
|
onSelectAllWarehouses={handleToggleAllWarehouses}
|
||||||
|
{...fetchMoreProps}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{step === ProductExportStep.SETTINGS && (
|
||||||
|
<ProductExportDialogSettings
|
||||||
|
data={data}
|
||||||
|
errors={dialogErrors}
|
||||||
|
productQuantity={productQuantity}
|
||||||
|
selectedProducts={selectedProducts}
|
||||||
|
onChange={change}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</DialogContent>
|
||||||
|
|
||||||
change({
|
{notFormErrors.length > 0 && (
|
||||||
target: {
|
<DialogContent>
|
||||||
name: "exportInfo",
|
{notFormErrors.map(err => (
|
||||||
value: {
|
<Typography color="error" key={err.field + err.code}>
|
||||||
...data.exportInfo,
|
{getExportErrorMessage(err, intl)}
|
||||||
attributes: toggle(
|
</Typography>
|
||||||
id,
|
))}
|
||||||
data.exportInfo.attributes,
|
</DialogContent>
|
||||||
(a, b) => a === b
|
)}
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const choice = attributeChoices.find(choice => choice.value === id);
|
<DialogActions>
|
||||||
|
{step === ProductExportStep.INFO && (
|
||||||
setSelectedAttributes(
|
<Button onClick={onClose} data-test="cancel">
|
||||||
toggle(choice, selectedAttributes, (a, b) => a.value === b.value)
|
<FormattedMessage {...buttonMessages.cancel} />
|
||||||
);
|
</Button>
|
||||||
};
|
)}
|
||||||
|
{step === ProductExportStep.SETTINGS && (
|
||||||
return (
|
<Button onClick={prev} data-test="back">
|
||||||
<>
|
<FormattedMessage {...buttonMessages.back} />
|
||||||
<DialogTitle>
|
</Button>
|
||||||
<FormattedMessage
|
)}
|
||||||
defaultMessage="Export Information"
|
{step === ProductExportStep.INFO && (
|
||||||
description="export products to csv file, dialog header"
|
<Button
|
||||||
/>
|
color="primary"
|
||||||
</DialogTitle>
|
variant="contained"
|
||||||
<DialogContent>
|
onClick={next}
|
||||||
<ProductExportSteps
|
data-test="next"
|
||||||
currentStep={step}
|
>
|
||||||
steps={steps}
|
<FormattedMessage {...buttonMessages.nextStep} />
|
||||||
onStepClick={setStep}
|
</Button>
|
||||||
/>
|
)}
|
||||||
{step === ProductExportStep.INFO && (
|
{step === ProductExportStep.SETTINGS && (
|
||||||
<ProductExportDialogInfo
|
<ConfirmButton
|
||||||
attributes={attributeChoices}
|
transitionState={confirmButtonState}
|
||||||
data={data}
|
variant="contained"
|
||||||
selectedAttributes={selectedAttributes}
|
type="submit"
|
||||||
onAttrtibuteSelect={handleAttributeSelect}
|
data-test="submit"
|
||||||
onChange={change}
|
onClick={submit}
|
||||||
{...fetchMoreProps}
|
>
|
||||||
/>
|
<FormattedMessage
|
||||||
)}
|
defaultMessage="export products"
|
||||||
{step === ProductExportStep.SETTINGS && (
|
description="export products to csv file, button"
|
||||||
<ProductExportDialogSettings
|
/>
|
||||||
data={data}
|
</ConfirmButton>
|
||||||
errors={dialogErrors}
|
)}
|
||||||
productQuantity={productQuantity}
|
</DialogActions>
|
||||||
selectedProducts={selectedProducts}
|
</>
|
||||||
onChange={change}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</DialogContent>
|
|
||||||
|
|
||||||
{notFormErrors.length > 0 && (
|
|
||||||
<DialogContent>
|
|
||||||
{notFormErrors.map(err => (
|
|
||||||
<Typography color="error" key={err.field + err.code}>
|
|
||||||
{getExportErrorMessage(err, intl)}
|
|
||||||
</Typography>
|
|
||||||
))}
|
|
||||||
</DialogContent>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<DialogActions>
|
|
||||||
{step === ProductExportStep.INFO && (
|
|
||||||
<Button onClick={onClose} data-test="cancel">
|
|
||||||
<FormattedMessage {...buttonMessages.cancel} />
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
{step === ProductExportStep.SETTINGS && (
|
|
||||||
<Button onClick={prev} data-test="back">
|
|
||||||
<FormattedMessage {...buttonMessages.back} />
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
{step === ProductExportStep.INFO && (
|
|
||||||
<Button
|
|
||||||
color="primary"
|
|
||||||
variant="contained"
|
|
||||||
onClick={next}
|
|
||||||
data-test="next"
|
|
||||||
>
|
|
||||||
<FormattedMessage {...buttonMessages.nextStep} />
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
{step === ProductExportStep.SETTINGS && (
|
|
||||||
<ConfirmButton
|
|
||||||
transitionState={confirmButtonState}
|
|
||||||
variant="contained"
|
|
||||||
type="submit"
|
|
||||||
data-test="submit"
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
defaultMessage="export products"
|
|
||||||
description="export products to csv file, button"
|
|
||||||
/>
|
|
||||||
</ConfirmButton>
|
|
||||||
)}
|
|
||||||
</DialogActions>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Form>
|
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import Button from "@material-ui/core/Button";
|
import Button from "@material-ui/core/Button";
|
||||||
import Checkbox from "@material-ui/core/Checkbox";
|
|
||||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||||
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
||||||
import makeStyles from "@material-ui/core/styles/makeStyles";
|
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||||
import TextField from "@material-ui/core/TextField";
|
import TextField from "@material-ui/core/TextField";
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
import Accordion, { AccordionProps } from "@saleor/components/Accordion";
|
import Accordion, { AccordionProps } from "@saleor/components/Accordion";
|
||||||
|
import Checkbox from "@saleor/components/Checkbox";
|
||||||
import Chip from "@saleor/components/Chip";
|
import Chip from "@saleor/components/Chip";
|
||||||
import Hr from "@saleor/components/Hr";
|
import Hr from "@saleor/components/Hr";
|
||||||
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField";
|
import { MultiAutocompleteChoiceType } from "@saleor/components/MultiAutocompleteSelectField";
|
||||||
import { ChangeEvent } from "@saleor/hooks/useForm";
|
import { ChangeEvent, FormChange } from "@saleor/hooks/useForm";
|
||||||
import useSearchQuery from "@saleor/hooks/useSearchQuery";
|
import useSearchQuery from "@saleor/hooks/useSearchQuery";
|
||||||
import { sectionNames } from "@saleor/intl";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { FetchMoreProps } from "@saleor/types";
|
import { FetchMoreProps } from "@saleor/types";
|
||||||
|
@ -22,9 +22,18 @@ import React from "react";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
|
import useProductExportFieldMessages from "./messages";
|
||||||
|
|
||||||
export const attributeNamePrefix = "attribute-";
|
export const attributeNamePrefix = "attribute-";
|
||||||
|
export const warehouseNamePrefix = "warehouse-";
|
||||||
const maxChips = 4;
|
const maxChips = 4;
|
||||||
|
|
||||||
|
const inventoryFields = [
|
||||||
|
ProductFieldEnum.PRODUCT_WEIGHT,
|
||||||
|
ProductFieldEnum.VARIANT_SKU,
|
||||||
|
ProductFieldEnum.VARIANT_WEIGHT
|
||||||
|
];
|
||||||
|
|
||||||
const useStyles = makeStyles(
|
const useStyles = makeStyles(
|
||||||
theme => ({
|
theme => ({
|
||||||
accordion: {
|
accordion: {
|
||||||
|
@ -45,12 +54,23 @@ const useStyles = makeStyles(
|
||||||
marginBottom: theme.spacing(3),
|
marginBottom: theme.spacing(3),
|
||||||
marginTop: theme.spacing(3)
|
marginTop: theme.spacing(3)
|
||||||
},
|
},
|
||||||
|
hrWarehouses: {
|
||||||
|
marginBottom: theme.spacing(3),
|
||||||
|
marginTop: theme.spacing(1)
|
||||||
|
},
|
||||||
label: {
|
label: {
|
||||||
"&&": {
|
"&&": {
|
||||||
overflow: "visible"
|
overflow: "visible"
|
||||||
},
|
},
|
||||||
|
"&:first-of-type": {
|
||||||
|
paddingTop: 0
|
||||||
|
},
|
||||||
|
"&:not(:last-of-type)": {
|
||||||
|
borderBottom: `1px solid ${theme.palette.divider}`
|
||||||
|
},
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
margin: theme.spacing(0),
|
margin: theme.spacing(0),
|
||||||
|
padding: theme.spacing(1, 0),
|
||||||
width: "100%"
|
width: "100%"
|
||||||
},
|
},
|
||||||
loadMoreContainer: {
|
loadMoreContainer: {
|
||||||
|
@ -62,8 +82,14 @@ const useStyles = makeStyles(
|
||||||
display: "inline-block",
|
display: "inline-block",
|
||||||
marginBottom: theme.spacing()
|
marginBottom: theme.spacing()
|
||||||
},
|
},
|
||||||
|
optionLabel: {
|
||||||
|
marginLeft: 0
|
||||||
|
},
|
||||||
quickPeekContainer: {
|
quickPeekContainer: {
|
||||||
marginBottom: theme.spacing(-1)
|
marginBottom: theme.spacing(-1)
|
||||||
|
},
|
||||||
|
warehousesLabel: {
|
||||||
|
marginBottom: theme.spacing(2)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
|
@ -80,12 +106,14 @@ const Option: React.FC<{
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
|
classes={{
|
||||||
|
label: classes.optionLabel
|
||||||
|
}}
|
||||||
color="primary"
|
color="primary"
|
||||||
control={
|
control={
|
||||||
<Checkbox
|
<Checkbox
|
||||||
className={classes.checkbox}
|
className={classes.checkbox}
|
||||||
checked={checked}
|
checked={checked}
|
||||||
color="primary"
|
|
||||||
name={name}
|
name={name}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
|
@ -104,66 +132,7 @@ const FieldAccordion: React.FC<AccordionProps & {
|
||||||
onToggleAll: (field: ProductFieldEnum[], setTo: boolean) => void;
|
onToggleAll: (field: ProductFieldEnum[], setTo: boolean) => void;
|
||||||
}> = ({ data, fields, onChange, onToggleAll, ...props }) => {
|
}> = ({ data, fields, onChange, onToggleAll, ...props }) => {
|
||||||
const classes = useStyles({});
|
const classes = useStyles({});
|
||||||
const intl = useIntl();
|
const getFieldLabel = useProductExportFieldMessages();
|
||||||
|
|
||||||
const fieldNames: Record<ProductFieldEnum, string> = {
|
|
||||||
[ProductFieldEnum.CATEGORY]: intl.formatMessage({
|
|
||||||
defaultMessage: "Category",
|
|
||||||
description: "product field"
|
|
||||||
}),
|
|
||||||
[ProductFieldEnum.CHARGE_TAXES]: intl.formatMessage({
|
|
||||||
defaultMessage: "Charge Taxes",
|
|
||||||
description: "product field"
|
|
||||||
}),
|
|
||||||
[ProductFieldEnum.COLLECTIONS]: intl.formatMessage({
|
|
||||||
defaultMessage: "Collections",
|
|
||||||
description: "product field"
|
|
||||||
}),
|
|
||||||
[ProductFieldEnum.COST_PRICE]: intl.formatMessage({
|
|
||||||
defaultMessage: "Cost Price",
|
|
||||||
description: "product field"
|
|
||||||
}),
|
|
||||||
[ProductFieldEnum.DESCRIPTION]: intl.formatMessage({
|
|
||||||
defaultMessage: "Description",
|
|
||||||
description: "product field"
|
|
||||||
}),
|
|
||||||
[ProductFieldEnum.NAME]: intl.formatMessage({
|
|
||||||
defaultMessage: "Name",
|
|
||||||
description: "product field"
|
|
||||||
}),
|
|
||||||
[ProductFieldEnum.PRODUCT_IMAGES]: intl.formatMessage({
|
|
||||||
defaultMessage: "Product Images",
|
|
||||||
description: "product field"
|
|
||||||
}),
|
|
||||||
[ProductFieldEnum.PRODUCT_TYPE]: intl.formatMessage({
|
|
||||||
defaultMessage: "Type",
|
|
||||||
description: "product field"
|
|
||||||
}),
|
|
||||||
[ProductFieldEnum.PRODUCT_WEIGHT]: intl.formatMessage({
|
|
||||||
defaultMessage: "Weight",
|
|
||||||
description: "product field"
|
|
||||||
}),
|
|
||||||
[ProductFieldEnum.VARIANT_IMAGES]: intl.formatMessage({
|
|
||||||
defaultMessage: "Variant Images",
|
|
||||||
description: "product field"
|
|
||||||
}),
|
|
||||||
[ProductFieldEnum.VARIANT_PRICE]: intl.formatMessage({
|
|
||||||
defaultMessage: "Variant Price",
|
|
||||||
description: "product field"
|
|
||||||
}),
|
|
||||||
[ProductFieldEnum.VARIANT_SKU]: intl.formatMessage({
|
|
||||||
defaultMessage: "SKU",
|
|
||||||
description: "product field"
|
|
||||||
}),
|
|
||||||
[ProductFieldEnum.VARIANT_WEIGHT]: intl.formatMessage({
|
|
||||||
defaultMessage: "Variant Weight",
|
|
||||||
description: "product field"
|
|
||||||
}),
|
|
||||||
[ProductFieldEnum.VISIBLE]: intl.formatMessage({
|
|
||||||
defaultMessage: "Visibility",
|
|
||||||
description: "product field"
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
const selectedAll = fields.every(field =>
|
const selectedAll = fields.every(field =>
|
||||||
data.exportInfo.fields.includes(field)
|
data.exportInfo.fields.includes(field)
|
||||||
|
@ -181,7 +150,7 @@ const FieldAccordion: React.FC<AccordionProps & {
|
||||||
{selectedFields.slice(0, maxChips).map(field => (
|
{selectedFields.slice(0, maxChips).map(field => (
|
||||||
<Chip
|
<Chip
|
||||||
className={classes.chip}
|
className={classes.chip}
|
||||||
label={fieldNames[field]}
|
label={getFieldLabel(field)}
|
||||||
onClose={() =>
|
onClose={() =>
|
||||||
onChange({
|
onChange({
|
||||||
target: {
|
target: {
|
||||||
|
@ -190,6 +159,7 @@ const FieldAccordion: React.FC<AccordionProps & {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
key={field}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{selectedFields.length > maxChips && (
|
{selectedFields.length > maxChips && (
|
||||||
|
@ -225,7 +195,7 @@ const FieldAccordion: React.FC<AccordionProps & {
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
key={field}
|
key={field}
|
||||||
>
|
>
|
||||||
{fieldNames[field]}
|
{getFieldLabel(field)}
|
||||||
</Option>
|
</Option>
|
||||||
))}
|
))}
|
||||||
</Accordion>
|
</Accordion>
|
||||||
|
@ -234,11 +204,14 @@ const FieldAccordion: React.FC<AccordionProps & {
|
||||||
|
|
||||||
export interface ProductExportDialogInfoProps extends FetchMoreProps {
|
export interface ProductExportDialogInfoProps extends FetchMoreProps {
|
||||||
attributes: MultiAutocompleteChoiceType[];
|
attributes: MultiAutocompleteChoiceType[];
|
||||||
|
warehouses: MultiAutocompleteChoiceType[];
|
||||||
data: ExportProductsInput;
|
data: ExportProductsInput;
|
||||||
selectedAttributes: MultiAutocompleteChoiceType[];
|
selectedAttributes: MultiAutocompleteChoiceType[];
|
||||||
onAttrtibuteSelect: (event: ChangeEvent) => void;
|
onAttrtibuteSelect: FormChange;
|
||||||
onChange: (event: ChangeEvent) => void;
|
onWarehouseSelect: FormChange;
|
||||||
|
onChange: FormChange;
|
||||||
onFetch: (query: string) => void;
|
onFetch: (query: string) => void;
|
||||||
|
onSelectAllWarehouses: FormChange;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProductExportDialogInfo: React.FC<ProductExportDialogInfoProps> = ({
|
const ProductExportDialogInfo: React.FC<ProductExportDialogInfoProps> = ({
|
||||||
|
@ -247,14 +220,18 @@ const ProductExportDialogInfo: React.FC<ProductExportDialogInfoProps> = ({
|
||||||
hasMore,
|
hasMore,
|
||||||
selectedAttributes,
|
selectedAttributes,
|
||||||
loading,
|
loading,
|
||||||
|
warehouses,
|
||||||
onAttrtibuteSelect,
|
onAttrtibuteSelect,
|
||||||
|
onWarehouseSelect,
|
||||||
onChange,
|
onChange,
|
||||||
onFetch,
|
onFetch,
|
||||||
onFetchMore
|
onFetchMore,
|
||||||
|
onSelectAllWarehouses
|
||||||
}) => {
|
}) => {
|
||||||
const classes = useStyles({});
|
const classes = useStyles({});
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const [query, onQueryChange] = useSearchQuery(onFetch);
|
const [query, onQueryChange] = useSearchQuery(onFetch);
|
||||||
|
const getFieldLabel = useProductExportFieldMessages();
|
||||||
|
|
||||||
const handleFieldChange = (event: ChangeEvent) =>
|
const handleFieldChange = (event: ChangeEvent) =>
|
||||||
onChange({
|
onChange({
|
||||||
|
@ -289,6 +266,12 @@ const ProductExportDialogInfo: React.FC<ProductExportDialogInfoProps> = ({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const selectedInventoryFields = data.exportInfo.fields.filter(field =>
|
||||||
|
inventoryFields.includes(field)
|
||||||
|
);
|
||||||
|
const selectedAllInventoryFields =
|
||||||
|
selectedInventoryFields.length === inventoryFields.length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Typography className={classes.dialogLabel}>
|
<Typography className={classes.dialogLabel}>
|
||||||
|
@ -331,6 +314,7 @@ const ProductExportDialogInfo: React.FC<ProductExportDialogInfoProps> = ({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
key={attribute.value}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{selectedAttributes.length > maxChips && (
|
{selectedAttributes.length > maxChips && (
|
||||||
|
@ -408,22 +392,134 @@ const ProductExportDialogInfo: React.FC<ProductExportDialogInfoProps> = ({
|
||||||
onToggleAll={handleToggleAllFields}
|
onToggleAll={handleToggleAllFields}
|
||||||
data-test="financial"
|
data-test="financial"
|
||||||
/>
|
/>
|
||||||
<FieldAccordion
|
<Accordion
|
||||||
className={classes.accordion}
|
className={classes.accordion}
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
defaultMessage: "Inventory Information",
|
defaultMessage: "Inventory Information",
|
||||||
description: "informations about product stock, header"
|
description: "informations about product stock, header"
|
||||||
})}
|
})}
|
||||||
data={data}
|
quickPeek={
|
||||||
fields={[
|
(data.exportInfo.warehouses.length > 0 ||
|
||||||
ProductFieldEnum.PRODUCT_WEIGHT,
|
selectedInventoryFields.length > 0) && (
|
||||||
ProductFieldEnum.VARIANT_SKU,
|
<div className={classes.quickPeekContainer}>
|
||||||
ProductFieldEnum.VARIANT_WEIGHT
|
{selectedInventoryFields.slice(0, maxChips).map(field => (
|
||||||
]}
|
<Chip
|
||||||
onChange={handleFieldChange}
|
className={classes.chip}
|
||||||
onToggleAll={handleToggleAllFields}
|
label={getFieldLabel(field)}
|
||||||
|
onClose={() =>
|
||||||
|
onChange({
|
||||||
|
target: {
|
||||||
|
name: field,
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
{data.exportInfo.warehouses
|
||||||
|
.slice(0, maxChips - selectedInventoryFields.length)
|
||||||
|
.map(warehouseId => (
|
||||||
|
<Chip
|
||||||
|
className={classes.chip}
|
||||||
|
label={
|
||||||
|
warehouses.find(
|
||||||
|
warehouse => warehouse.value === warehouseId
|
||||||
|
).label
|
||||||
|
}
|
||||||
|
onClose={() =>
|
||||||
|
onWarehouseSelect({
|
||||||
|
target: {
|
||||||
|
name: warehouseNamePrefix + warehouseId,
|
||||||
|
value: undefined
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
{data.exportInfo.warehouses.length +
|
||||||
|
selectedInventoryFields.length >
|
||||||
|
maxChips && (
|
||||||
|
<Typography className={classes.moreLabel} variant="caption">
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="and {number} more"
|
||||||
|
description="there are more elements of list that are hidden"
|
||||||
|
values={{
|
||||||
|
number:
|
||||||
|
data.exportInfo.warehouses.length +
|
||||||
|
selectedInventoryFields.length -
|
||||||
|
maxChips
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
data-test="inventory"
|
data-test="inventory"
|
||||||
/>
|
>
|
||||||
|
<div>
|
||||||
|
<Option
|
||||||
|
checked={selectedAllInventoryFields}
|
||||||
|
name="all"
|
||||||
|
onChange={() =>
|
||||||
|
handleToggleAllFields(
|
||||||
|
inventoryFields,
|
||||||
|
!selectedAllInventoryFields
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Select All"
|
||||||
|
description="selectt all options"
|
||||||
|
/>
|
||||||
|
</Option>
|
||||||
|
{inventoryFields.map(field => (
|
||||||
|
<Option
|
||||||
|
checked={data.exportInfo.fields.includes(field)}
|
||||||
|
name={field}
|
||||||
|
onChange={handleFieldChange}
|
||||||
|
key={field}
|
||||||
|
>
|
||||||
|
{getFieldLabel(field)}
|
||||||
|
</Option>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<Hr className={classes.hrWarehouses} />
|
||||||
|
<Typography>
|
||||||
|
<FormattedMessage defaultMessage="Export Product Stock Quantity to CSV" />
|
||||||
|
</Typography>
|
||||||
|
<div>
|
||||||
|
<Option
|
||||||
|
checked={warehouses.every(warehouse =>
|
||||||
|
data.exportInfo.warehouses.includes(warehouse.value)
|
||||||
|
)}
|
||||||
|
name="all-warehouses"
|
||||||
|
onChange={onSelectAllWarehouses}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Export stock for all warehouses"
|
||||||
|
description="option"
|
||||||
|
/>
|
||||||
|
</Option>
|
||||||
|
</div>
|
||||||
|
<Hr className={classes.hrWarehouses} />
|
||||||
|
<Typography className={classes.warehousesLabel} variant="subtitle1">
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="Warehouses A to Z"
|
||||||
|
description="list of warehouses"
|
||||||
|
/>
|
||||||
|
</Typography>
|
||||||
|
{warehouses.map(warehouse => (
|
||||||
|
<Option
|
||||||
|
checked={data.exportInfo.warehouses.includes(warehouse.value)}
|
||||||
|
name={warehouseNamePrefix + warehouse.value}
|
||||||
|
onChange={onWarehouseSelect}
|
||||||
|
key={warehouse.value}
|
||||||
|
>
|
||||||
|
{warehouse.label}
|
||||||
|
</Option>
|
||||||
|
))}
|
||||||
|
</Accordion>
|
||||||
<FieldAccordion
|
<FieldAccordion
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
defaultMessage: "SEO Information",
|
defaultMessage: "SEO Information",
|
||||||
|
|
83
src/products/components/ProductExportDialog/messages.ts
Normal file
83
src/products/components/ProductExportDialog/messages.ts
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
import { ProductFieldEnum } from "@saleor/types/globalTypes";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
|
function useProductExportFieldMessages() {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
const messages = {
|
||||||
|
[ProductFieldEnum.CATEGORY]: intl.formatMessage({
|
||||||
|
defaultMessage: "Category",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldCategory"
|
||||||
|
}),
|
||||||
|
[ProductFieldEnum.CHARGE_TAXES]: intl.formatMessage({
|
||||||
|
defaultMessage: "Charge Taxes",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldTaxes"
|
||||||
|
}),
|
||||||
|
[ProductFieldEnum.COLLECTIONS]: intl.formatMessage({
|
||||||
|
defaultMessage: "Collections",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldCollections"
|
||||||
|
}),
|
||||||
|
[ProductFieldEnum.COST_PRICE]: intl.formatMessage({
|
||||||
|
defaultMessage: "Cost Price",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldPrice"
|
||||||
|
}),
|
||||||
|
[ProductFieldEnum.DESCRIPTION]: intl.formatMessage({
|
||||||
|
defaultMessage: "Description",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldDescription"
|
||||||
|
}),
|
||||||
|
[ProductFieldEnum.NAME]: intl.formatMessage({
|
||||||
|
defaultMessage: "Name",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldName"
|
||||||
|
}),
|
||||||
|
[ProductFieldEnum.PRODUCT_IMAGES]: intl.formatMessage({
|
||||||
|
defaultMessage: "Product Images",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldProductImages"
|
||||||
|
}),
|
||||||
|
[ProductFieldEnum.PRODUCT_TYPE]: intl.formatMessage({
|
||||||
|
defaultMessage: "Type",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldType"
|
||||||
|
}),
|
||||||
|
[ProductFieldEnum.PRODUCT_WEIGHT]: intl.formatMessage({
|
||||||
|
defaultMessage: "Export Product Weight",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldProductWeight"
|
||||||
|
}),
|
||||||
|
[ProductFieldEnum.VARIANT_IMAGES]: intl.formatMessage({
|
||||||
|
defaultMessage: "Variant Images",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldVariantImages"
|
||||||
|
}),
|
||||||
|
[ProductFieldEnum.VARIANT_PRICE]: intl.formatMessage({
|
||||||
|
defaultMessage: "Variant Price",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldVariantPrice"
|
||||||
|
}),
|
||||||
|
[ProductFieldEnum.VARIANT_SKU]: intl.formatMessage({
|
||||||
|
defaultMessage: "Export Variant SKU",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldVariantSku"
|
||||||
|
}),
|
||||||
|
[ProductFieldEnum.VARIANT_WEIGHT]: intl.formatMessage({
|
||||||
|
defaultMessage: "Export Variant Weight",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldVariantWeight"
|
||||||
|
}),
|
||||||
|
[ProductFieldEnum.VISIBLE]: intl.formatMessage({
|
||||||
|
defaultMessage: "Visibility",
|
||||||
|
description: "product field",
|
||||||
|
id: "productExportFieldVisibility"
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
return (field: ProductFieldEnum) => messages[field];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useProductExportFieldMessages;
|
|
@ -167,23 +167,33 @@ export const ProductUpdatePage: React.FC<ProductUpdatePageProps> = ({
|
||||||
const hasVariants = maybe(() => product.productType.hasVariants, false);
|
const hasVariants = maybe(() => product.productType.hasVariants, false);
|
||||||
|
|
||||||
const handleSubmit = (data: ProductUpdatePageFormData) => {
|
const handleSubmit = (data: ProductUpdatePageFormData) => {
|
||||||
const dataStocks = stocks.map(stock => stock.id);
|
if (product.productType.hasVariants) {
|
||||||
const variantStocks = product.variants[0].stocks.map(
|
onSubmit({
|
||||||
stock => stock.warehouse.id
|
...data,
|
||||||
);
|
addStocks: [],
|
||||||
const stockDiff = diff(variantStocks, dataStocks);
|
attributes,
|
||||||
|
removeStocks: [],
|
||||||
|
updateStocks: []
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const dataStocks = stocks.map(stock => stock.id);
|
||||||
|
const variantStocks = product.variants[0]?.stocks.map(
|
||||||
|
stock => stock.warehouse.id
|
||||||
|
);
|
||||||
|
const stockDiff = diff(variantStocks, dataStocks);
|
||||||
|
|
||||||
onSubmit({
|
onSubmit({
|
||||||
...data,
|
...data,
|
||||||
addStocks: stocks.filter(stock =>
|
addStocks: stocks.filter(stock =>
|
||||||
stockDiff.added.some(addedStock => addedStock === stock.id)
|
stockDiff.added.some(addedStock => addedStock === stock.id)
|
||||||
),
|
),
|
||||||
attributes,
|
attributes,
|
||||||
removeStocks: stockDiff.removed,
|
removeStocks: stockDiff.removed,
|
||||||
updateStocks: stocks.filter(
|
updateStocks: stocks.filter(
|
||||||
stock => !stockDiff.added.some(addedStock => addedStock === stock.id)
|
stock => !stockDiff.added.some(addedStock => addedStock === stock.id)
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import { ProductVariant } from "@saleor/fragments/types/ProductVariant";
|
import { ProductVariant } from "@saleor/fragments/types/ProductVariant";
|
||||||
import { AttributeInputTypeEnum } from "@saleor/types/globalTypes";
|
import {
|
||||||
|
AttributeInputTypeEnum,
|
||||||
|
WeightUnitsEnum
|
||||||
|
} from "@saleor/types/globalTypes";
|
||||||
import { warehouseList } from "@saleor/warehouses/fixtures";
|
import { warehouseList } from "@saleor/warehouses/fixtures";
|
||||||
|
|
||||||
import { content } from "../storybook/stories/components/RichTextEditor";
|
import { content } from "../storybook/stories/components/RichTextEditor";
|
||||||
|
@ -281,7 +284,7 @@ export const product: (
|
||||||
trackInventory: true,
|
trackInventory: true,
|
||||||
weight: {
|
weight: {
|
||||||
__typename: "Weight",
|
__typename: "Weight",
|
||||||
unit: "kg",
|
unit: WeightUnitsEnum.KG,
|
||||||
value: 3
|
value: 3
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -316,14 +319,14 @@ export const product: (
|
||||||
trackInventory: false,
|
trackInventory: false,
|
||||||
weight: {
|
weight: {
|
||||||
__typename: "Weight",
|
__typename: "Weight",
|
||||||
unit: "kg",
|
unit: WeightUnitsEnum.KG,
|
||||||
value: 4
|
value: 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
weight: {
|
weight: {
|
||||||
__typename: "Weight",
|
__typename: "Weight",
|
||||||
unit: "kg",
|
unit: WeightUnitsEnum.KG,
|
||||||
value: 5
|
value: 5
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1672,7 +1675,7 @@ export const variant = (placeholderImage: string): ProductVariant => ({
|
||||||
trackInventory: true,
|
trackInventory: true,
|
||||||
weight: {
|
weight: {
|
||||||
__typename: "Weight",
|
__typename: "Weight",
|
||||||
unit: "kg",
|
unit: WeightUnitsEnum.KG,
|
||||||
value: 6
|
value: 6
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -52,7 +52,10 @@ const ProductUpdate: React.FC<RouteComponentProps<any>> = ({ match }) => {
|
||||||
return (
|
return (
|
||||||
<ProductUpdateComponent
|
<ProductUpdateComponent
|
||||||
id={decodeURIComponent(match.params.id)}
|
id={decodeURIComponent(match.params.id)}
|
||||||
params={params}
|
params={{
|
||||||
|
...params,
|
||||||
|
ids: getArrayQueryParam(qs.ids)
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeValueInput, SeoInput, StockInput, ProductErrorCode, AttributeInputTypeEnum } from "./../../types/globalTypes";
|
import { AttributeValueInput, SeoInput, StockInput, ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: ProductCreate
|
// GraphQL mutation operation: ProductCreate
|
||||||
|
@ -176,7 +176,7 @@ export interface ProductCreate_productCreate_product_variants {
|
||||||
|
|
||||||
export interface ProductCreate_productCreate_product_weight {
|
export interface ProductCreate_productCreate_product_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeInputTypeEnum } from "./../../types/globalTypes";
|
import { AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: ProductDetails
|
// GraphQL query operation: ProductDetails
|
||||||
|
@ -170,7 +170,7 @@ export interface ProductDetails_product_variants {
|
||||||
|
|
||||||
export interface ProductDetails_product_weight {
|
export interface ProductDetails_product_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductErrorCode, AttributeInputTypeEnum } from "./../../types/globalTypes";
|
import { ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: ProductImageCreate
|
// GraphQL mutation operation: ProductImageCreate
|
||||||
|
@ -176,7 +176,7 @@ export interface ProductImageCreate_productImageCreate_product_variants {
|
||||||
|
|
||||||
export interface ProductImageCreate_productImageCreate_product_weight {
|
export interface ProductImageCreate_productImageCreate_product_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductErrorCode, AttributeInputTypeEnum } from "./../../types/globalTypes";
|
import { ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: ProductImageUpdate
|
// GraphQL mutation operation: ProductImageUpdate
|
||||||
|
@ -176,7 +176,7 @@ export interface ProductImageUpdate_productImageUpdate_product_variants {
|
||||||
|
|
||||||
export interface ProductImageUpdate_productImageUpdate_product_weight {
|
export interface ProductImageUpdate_productImageUpdate_product_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeValueInput, SeoInput, ProductErrorCode, AttributeInputTypeEnum } from "./../../types/globalTypes";
|
import { AttributeValueInput, SeoInput, ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: ProductUpdate
|
// GraphQL mutation operation: ProductUpdate
|
||||||
|
@ -176,7 +176,7 @@ export interface ProductUpdate_productUpdate_product_variants {
|
||||||
|
|
||||||
export interface ProductUpdate_productUpdate_product_weight {
|
export interface ProductUpdate_productUpdate_product_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
import { WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: ProductVariantDetails
|
// GraphQL query operation: ProductVariantDetails
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
@ -105,7 +107,7 @@ export interface ProductVariantDetails_productVariant_stocks {
|
||||||
|
|
||||||
export interface ProductVariantDetails_productVariant_weight {
|
export interface ProductVariantDetails_productVariant_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { AttributeValueInput, ProductVariantInput, SeoInput, StockInput, ProductErrorCode, AttributeInputTypeEnum, StockErrorCode } from "./../../types/globalTypes";
|
import { AttributeValueInput, ProductVariantInput, SeoInput, StockInput, ProductErrorCode, AttributeInputTypeEnum, WeightUnitsEnum, StockErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: SimpleProductUpdate
|
// GraphQL mutation operation: SimpleProductUpdate
|
||||||
|
@ -176,7 +176,7 @@ export interface SimpleProductUpdate_productUpdate_product_variants {
|
||||||
|
|
||||||
export interface SimpleProductUpdate_productUpdate_product_weight {
|
export interface SimpleProductUpdate_productUpdate_product_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +314,7 @@ export interface SimpleProductUpdate_productVariantUpdate_productVariant_stocks
|
||||||
|
|
||||||
export interface SimpleProductUpdate_productVariantUpdate_productVariant_weight {
|
export interface SimpleProductUpdate_productVariantUpdate_productVariant_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,7 +445,7 @@ export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_s
|
||||||
|
|
||||||
export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_weight {
|
export interface SimpleProductUpdate_productVariantStocksCreate_productVariant_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,7 +575,7 @@ export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_s
|
||||||
|
|
||||||
export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_weight {
|
export interface SimpleProductUpdate_productVariantStocksDelete_productVariant_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,7 +706,7 @@ export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_s
|
||||||
|
|
||||||
export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_weight {
|
export interface SimpleProductUpdate_productVariantStocksUpdate_productVariant_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductVariantCreateInput, ProductErrorCode } from "./../../types/globalTypes";
|
import { ProductVariantCreateInput, ProductErrorCode, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: VariantCreate
|
// GraphQL mutation operation: VariantCreate
|
||||||
|
@ -113,7 +113,7 @@ export interface VariantCreate_productVariantCreate_productVariant_stocks {
|
||||||
|
|
||||||
export interface VariantCreate_productVariantCreate_productVariant_weight {
|
export interface VariantCreate_productVariantCreate_productVariant_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductErrorCode } from "./../../types/globalTypes";
|
import { ProductErrorCode, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: VariantImageAssign
|
// GraphQL mutation operation: VariantImageAssign
|
||||||
|
@ -113,7 +113,7 @@ export interface VariantImageAssign_variantImageAssign_productVariant_stocks {
|
||||||
|
|
||||||
export interface VariantImageAssign_variantImageAssign_productVariant_weight {
|
export interface VariantImageAssign_variantImageAssign_productVariant_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ProductErrorCode } from "./../../types/globalTypes";
|
import { ProductErrorCode, WeightUnitsEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: VariantImageUnassign
|
// GraphQL mutation operation: VariantImageUnassign
|
||||||
|
@ -113,7 +113,7 @@ export interface VariantImageUnassign_variantImageUnassign_productVariant_stocks
|
||||||
|
|
||||||
export interface VariantImageUnassign_variantImageUnassign_productVariant_weight {
|
export interface VariantImageUnassign_variantImageUnassign_productVariant_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { StockInput, AttributeValueInput, ProductErrorCode, StockErrorCode } from "./../../types/globalTypes";
|
import { StockInput, AttributeValueInput, ProductErrorCode, WeightUnitsEnum, StockErrorCode } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: VariantUpdate
|
// GraphQL mutation operation: VariantUpdate
|
||||||
|
@ -113,7 +113,7 @@ export interface VariantUpdate_productVariantUpdate_productVariant_stocks {
|
||||||
|
|
||||||
export interface VariantUpdate_productVariantUpdate_productVariant_weight {
|
export interface VariantUpdate_productVariantUpdate_productVariant_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ export interface VariantUpdate_productVariantStocksUpdate_productVariant_stocks
|
||||||
|
|
||||||
export interface VariantUpdate_productVariantStocksUpdate_productVariant_weight {
|
export interface VariantUpdate_productVariantStocksUpdate_productVariant_weight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ import { ListViews } from "@saleor/types";
|
||||||
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
import createDialogActionHandlers from "@saleor/utils/handlers/dialogActionHandlers";
|
||||||
import createFilterHandlers from "@saleor/utils/handlers/filterHandlers";
|
import createFilterHandlers from "@saleor/utils/handlers/filterHandlers";
|
||||||
import { getSortUrlVariables } from "@saleor/utils/sort";
|
import { getSortUrlVariables } from "@saleor/utils/sort";
|
||||||
|
import { useWarehouseList } from "@saleor/warehouses/queries";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
|
@ -124,6 +125,11 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
first: 10
|
first: 10
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const warehouses = useWarehouseList({
|
||||||
|
variables: {
|
||||||
|
first: 100
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
React.useEffect(
|
React.useEffect(
|
||||||
() =>
|
() =>
|
||||||
|
@ -551,6 +557,11 @@ export const ProductList: React.FC<ProductListProps> = ({ params }) => {
|
||||||
filter: data?.products.totalCount
|
filter: data?.products.totalCount
|
||||||
}}
|
}}
|
||||||
selectedProducts={listElements.length}
|
selectedProducts={listElements.length}
|
||||||
|
warehouses={
|
||||||
|
warehouses.data?.warehouses.edges.map(
|
||||||
|
edge => edge.node
|
||||||
|
) || []
|
||||||
|
}
|
||||||
onClose={closeModal}
|
onClose={closeModal}
|
||||||
onSubmit={data =>
|
onSubmit={data =>
|
||||||
exportProducts({
|
exportProducts({
|
||||||
|
|
|
@ -41,6 +41,7 @@ import {
|
||||||
} from "../../../utils/filters";
|
} from "../../../utils/filters";
|
||||||
import {
|
import {
|
||||||
ProductListUrlFilters,
|
ProductListUrlFilters,
|
||||||
|
ProductListUrlFiltersAsDictWithMultipleValues,
|
||||||
ProductListUrlFiltersEnum,
|
ProductListUrlFiltersEnum,
|
||||||
ProductListUrlFiltersWithMultipleValues,
|
ProductListUrlFiltersWithMultipleValues,
|
||||||
ProductListUrlQueryParams
|
ProductListUrlQueryParams
|
||||||
|
@ -295,4 +296,8 @@ export const {
|
||||||
export const { areFiltersApplied, getActiveFilters } = createFilterUtils<
|
export const { areFiltersApplied, getActiveFilters } = createFilterUtils<
|
||||||
ProductListUrlQueryParams,
|
ProductListUrlQueryParams,
|
||||||
ProductListUrlFilters
|
ProductListUrlFilters
|
||||||
>(ProductListUrlFiltersEnum);
|
>({
|
||||||
|
...ProductListUrlFiltersEnum,
|
||||||
|
...ProductListUrlFiltersWithMultipleValues,
|
||||||
|
...ProductListUrlFiltersAsDictWithMultipleValues
|
||||||
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { ShippingZoneDetailsFragment } from "@saleor/fragments/types/ShippingZoneDetailsFragment";
|
import { ShippingZoneDetailsFragment } from "@saleor/fragments/types/ShippingZoneDetailsFragment";
|
||||||
import { ShippingZoneFragment } from "@saleor/fragments/types/ShippingZoneFragment";
|
import { ShippingZoneFragment } from "@saleor/fragments/types/ShippingZoneFragment";
|
||||||
|
|
||||||
import { ShippingMethodTypeEnum } from "../types/globalTypes";
|
import { ShippingMethodTypeEnum, WeightUnitsEnum } from "../types/globalTypes";
|
||||||
|
|
||||||
export const shippingZones: ShippingZoneFragment[] = [
|
export const shippingZones: ShippingZoneFragment[] = [
|
||||||
{
|
{
|
||||||
|
@ -1554,7 +1554,7 @@ export const shippingZone: ShippingZoneDetailsFragment = {
|
||||||
maximumOrderPrice: null,
|
maximumOrderPrice: null,
|
||||||
maximumOrderWeight: {
|
maximumOrderWeight: {
|
||||||
__typename: "Weight",
|
__typename: "Weight",
|
||||||
unit: "kg",
|
unit: WeightUnitsEnum.KG,
|
||||||
value: 80
|
value: 80
|
||||||
},
|
},
|
||||||
minimumOrderPrice: {
|
minimumOrderPrice: {
|
||||||
|
@ -1564,7 +1564,7 @@ export const shippingZone: ShippingZoneDetailsFragment = {
|
||||||
},
|
},
|
||||||
minimumOrderWeight: {
|
minimumOrderWeight: {
|
||||||
__typename: "Weight",
|
__typename: "Weight",
|
||||||
unit: "kg",
|
unit: WeightUnitsEnum.KG,
|
||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
name: "DB Schenker",
|
name: "DB Schenker",
|
||||||
|
@ -1587,7 +1587,7 @@ export const shippingZone: ShippingZoneDetailsFragment = {
|
||||||
},
|
},
|
||||||
minimumOrderWeight: {
|
minimumOrderWeight: {
|
||||||
__typename: "Weight",
|
__typename: "Weight",
|
||||||
unit: "kg",
|
unit: WeightUnitsEnum.KG,
|
||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
name: "Registred priority",
|
name: "Registred priority",
|
||||||
|
@ -1610,7 +1610,7 @@ export const shippingZone: ShippingZoneDetailsFragment = {
|
||||||
},
|
},
|
||||||
minimumOrderWeight: {
|
minimumOrderWeight: {
|
||||||
__typename: "Weight",
|
__typename: "Weight",
|
||||||
unit: "kg",
|
unit: WeightUnitsEnum.KG,
|
||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1634,7 +1634,7 @@ export const shippingZone: ShippingZoneDetailsFragment = {
|
||||||
},
|
},
|
||||||
minimumOrderWeight: {
|
minimumOrderWeight: {
|
||||||
__typename: "Weight",
|
__typename: "Weight",
|
||||||
unit: "kg",
|
unit: WeightUnitsEnum.KG,
|
||||||
value: 0
|
value: 0
|
||||||
},
|
},
|
||||||
name: "DHL",
|
name: "DHL",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ShippingPriceInput, ShippingErrorCode, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
import { ShippingPriceInput, ShippingErrorCode, WeightUnitsEnum, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: CreateShippingRate
|
// GraphQL mutation operation: CreateShippingRate
|
||||||
|
@ -28,7 +28,7 @@ export interface CreateShippingRate_shippingPriceCreate_shippingZone_shippingMet
|
||||||
|
|
||||||
export interface CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods_minimumOrderWeight {
|
export interface CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ export interface CreateShippingRate_shippingPriceCreate_shippingZone_shippingMet
|
||||||
|
|
||||||
export interface CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods_maximumOrderWeight {
|
export interface CreateShippingRate_shippingPriceCreate_shippingZone_shippingMethods_maximumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ShippingErrorCode, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
import { ShippingErrorCode, WeightUnitsEnum, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: DeleteShippingRate
|
// GraphQL mutation operation: DeleteShippingRate
|
||||||
|
@ -28,7 +28,7 @@ export interface DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMet
|
||||||
|
|
||||||
export interface DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods_minimumOrderWeight {
|
export interface DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ export interface DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMet
|
||||||
|
|
||||||
export interface DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods_maximumOrderWeight {
|
export interface DeleteShippingRate_shippingPriceDelete_shippingZone_shippingMethods_maximumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
import { WeightUnitsEnum, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: ShippingZone
|
// GraphQL query operation: ShippingZone
|
||||||
|
@ -22,7 +22,7 @@ export interface ShippingZone_shippingZone_shippingMethods_minimumOrderPrice {
|
||||||
|
|
||||||
export interface ShippingZone_shippingZone_shippingMethods_minimumOrderWeight {
|
export interface ShippingZone_shippingZone_shippingMethods_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ export interface ShippingZone_shippingZone_shippingMethods_maximumOrderPrice {
|
||||||
|
|
||||||
export interface ShippingZone_shippingZone_shippingMethods_maximumOrderWeight {
|
export interface ShippingZone_shippingZone_shippingMethods_maximumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { ShippingPriceInput, ShippingErrorCode, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
import { ShippingPriceInput, ShippingErrorCode, WeightUnitsEnum, ShippingMethodTypeEnum } from "./../../types/globalTypes";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL mutation operation: UpdateShippingRate
|
// GraphQL mutation operation: UpdateShippingRate
|
||||||
|
@ -22,7 +22,7 @@ export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod_minimumOr
|
||||||
|
|
||||||
export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod_minimumOrderWeight {
|
export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod_minimumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod_maximumOr
|
||||||
|
|
||||||
export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod_maximumOrderWeight {
|
export interface UpdateShippingRate_shippingPriceUpdate_shippingMethod_maximumOrderWeight {
|
||||||
__typename: "Weight";
|
__typename: "Weight";
|
||||||
unit: string;
|
unit: WeightUnitsEnum;
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,8 @@ const useStyles = makeStyles(
|
||||||
width: 47
|
width: 47
|
||||||
},
|
},
|
||||||
avatarDefault: {
|
avatarDefault: {
|
||||||
"& p": {
|
"& div": {
|
||||||
color: "#fff",
|
color: theme.palette.primary.contrastText,
|
||||||
lineHeight: "47px"
|
lineHeight: "47px"
|
||||||
},
|
},
|
||||||
background: theme.palette.primary.main,
|
background: theme.palette.primary.main,
|
||||||
|
|
|
@ -35,7 +35,7 @@ const useStyles = makeStyles(
|
||||||
width: 120
|
width: 120
|
||||||
},
|
},
|
||||||
avatarDefault: {
|
avatarDefault: {
|
||||||
"& p": {
|
"& div": {
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
fontSize: 35,
|
fontSize: 35,
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
|
|
|
@ -34,6 +34,9 @@ const staffList = gql`
|
||||||
cursor
|
cursor
|
||||||
node {
|
node {
|
||||||
...StaffMemberFragment
|
...StaffMemberFragment
|
||||||
|
avatar(size: 48) {
|
||||||
|
url
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pageInfo {
|
pageInfo {
|
||||||
|
|
|
@ -14,11 +14,6 @@ export interface StaffMemberAdd_staffCreate_errors {
|
||||||
field: string | null;
|
field: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StaffMemberAdd_staffCreate_user_avatar {
|
|
||||||
__typename: "Image";
|
|
||||||
url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StaffMemberAdd_staffCreate_user_permissionGroups {
|
export interface StaffMemberAdd_staffCreate_user_permissionGroups {
|
||||||
__typename: "Group";
|
__typename: "Group";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -32,6 +27,11 @@ export interface StaffMemberAdd_staffCreate_user_userPermissions {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface StaffMemberAdd_staffCreate_user_avatar {
|
||||||
|
__typename: "Image";
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface StaffMemberAdd_staffCreate_user {
|
export interface StaffMemberAdd_staffCreate_user {
|
||||||
__typename: "User";
|
__typename: "User";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -39,9 +39,9 @@ export interface StaffMemberAdd_staffCreate_user {
|
||||||
firstName: string;
|
firstName: string;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
avatar: StaffMemberAdd_staffCreate_user_avatar | null;
|
|
||||||
permissionGroups: (StaffMemberAdd_staffCreate_user_permissionGroups | null)[] | null;
|
permissionGroups: (StaffMemberAdd_staffCreate_user_permissionGroups | null)[] | null;
|
||||||
userPermissions: (StaffMemberAdd_staffCreate_user_userPermissions | null)[] | null;
|
userPermissions: (StaffMemberAdd_staffCreate_user_userPermissions | null)[] | null;
|
||||||
|
avatar: StaffMemberAdd_staffCreate_user_avatar | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StaffMemberAdd_staffCreate {
|
export interface StaffMemberAdd_staffCreate {
|
||||||
|
|
|
@ -8,11 +8,6 @@ import { PermissionEnum } from "./../../types/globalTypes";
|
||||||
// GraphQL query operation: StaffMemberDetails
|
// GraphQL query operation: StaffMemberDetails
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
export interface StaffMemberDetails_user_avatar {
|
|
||||||
__typename: "Image";
|
|
||||||
url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StaffMemberDetails_user_permissionGroups {
|
export interface StaffMemberDetails_user_permissionGroups {
|
||||||
__typename: "Group";
|
__typename: "Group";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -26,6 +21,11 @@ export interface StaffMemberDetails_user_userPermissions {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface StaffMemberDetails_user_avatar {
|
||||||
|
__typename: "Image";
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface StaffMemberDetails_user {
|
export interface StaffMemberDetails_user {
|
||||||
__typename: "User";
|
__typename: "User";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -33,9 +33,9 @@ export interface StaffMemberDetails_user {
|
||||||
firstName: string;
|
firstName: string;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
avatar: StaffMemberDetails_user_avatar | null;
|
|
||||||
permissionGroups: (StaffMemberDetails_user_permissionGroups | null)[] | null;
|
permissionGroups: (StaffMemberDetails_user_permissionGroups | null)[] | null;
|
||||||
userPermissions: (StaffMemberDetails_user_userPermissions | null)[] | null;
|
userPermissions: (StaffMemberDetails_user_userPermissions | null)[] | null;
|
||||||
|
avatar: StaffMemberDetails_user_avatar | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StaffMemberDetails {
|
export interface StaffMemberDetails {
|
||||||
|
|
|
@ -14,11 +14,6 @@ export interface StaffMemberUpdate_staffUpdate_errors {
|
||||||
field: string | null;
|
field: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StaffMemberUpdate_staffUpdate_user_avatar {
|
|
||||||
__typename: "Image";
|
|
||||||
url: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StaffMemberUpdate_staffUpdate_user_permissionGroups {
|
export interface StaffMemberUpdate_staffUpdate_user_permissionGroups {
|
||||||
__typename: "Group";
|
__typename: "Group";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -32,6 +27,11 @@ export interface StaffMemberUpdate_staffUpdate_user_userPermissions {
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface StaffMemberUpdate_staffUpdate_user_avatar {
|
||||||
|
__typename: "Image";
|
||||||
|
url: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface StaffMemberUpdate_staffUpdate_user {
|
export interface StaffMemberUpdate_staffUpdate_user {
|
||||||
__typename: "User";
|
__typename: "User";
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -39,9 +39,9 @@ export interface StaffMemberUpdate_staffUpdate_user {
|
||||||
firstName: string;
|
firstName: string;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
avatar: StaffMemberUpdate_staffUpdate_user_avatar | null;
|
|
||||||
permissionGroups: (StaffMemberUpdate_staffUpdate_user_permissionGroups | null)[] | null;
|
permissionGroups: (StaffMemberUpdate_staffUpdate_user_permissionGroups | null)[] | null;
|
||||||
userPermissions: (StaffMemberUpdate_staffUpdate_user_userPermissions | null)[] | null;
|
userPermissions: (StaffMemberUpdate_staffUpdate_user_userPermissions | null)[] | null;
|
||||||
|
avatar: StaffMemberUpdate_staffUpdate_user_avatar | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StaffMemberUpdate_staffUpdate {
|
export interface StaffMemberUpdate_staffUpdate {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
12
src/theme.ts
12
src/theme.ts
|
@ -1,10 +1,15 @@
|
||||||
import Card from "@material-ui/core/Card";
|
import Card from "@material-ui/core/Card";
|
||||||
|
import Checkbox from "@material-ui/core/Checkbox";
|
||||||
import { createMuiTheme, Theme } from "@material-ui/core/styles";
|
import { createMuiTheme, Theme } from "@material-ui/core/styles";
|
||||||
import { darken, fade } from "@material-ui/core/styles/colorManipulator";
|
import { darken, fade } from "@material-ui/core/styles/colorManipulator";
|
||||||
import TextField from "@material-ui/core/TextField";
|
import TextField from "@material-ui/core/TextField";
|
||||||
import Typography from "@material-ui/core/Typography";
|
import Typography from "@material-ui/core/Typography";
|
||||||
|
import { createElement } from "react";
|
||||||
|
|
||||||
import { IThemeColors } from "./components/Theme/themes";
|
import { IThemeColors } from "./components/Theme/themes";
|
||||||
|
import CheckboxIcon from "./icons/Checkbox";
|
||||||
|
import CheckboxCheckedIcon from "./icons/CheckboxChecked";
|
||||||
|
import CheckboxIndeterminateIcon from "./icons/CheckboxIndeterminate";
|
||||||
|
|
||||||
const createShadow = (pv, pb, ps, uv, ub, us, av, ab, as) =>
|
const createShadow = (pv, pb, ps, uv, ub, us, av, ab, as) =>
|
||||||
[
|
[
|
||||||
|
@ -562,3 +567,10 @@ Card.defaultProps = {
|
||||||
Typography.defaultProps = {
|
Typography.defaultProps = {
|
||||||
component: "div"
|
component: "div"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Checkbox.defaultProps = {
|
||||||
|
checkedIcon: createElement(CheckboxCheckedIcon),
|
||||||
|
color: "primary",
|
||||||
|
icon: createElement(CheckboxIcon),
|
||||||
|
indeterminateIcon: createElement(CheckboxIndeterminateIcon)
|
||||||
|
};
|
||||||
|
|
|
@ -865,7 +865,9 @@ export enum WebhookErrorCode {
|
||||||
|
|
||||||
export enum WebhookEventTypeEnum {
|
export enum WebhookEventTypeEnum {
|
||||||
ANY_EVENTS = "ANY_EVENTS",
|
ANY_EVENTS = "ANY_EVENTS",
|
||||||
|
CHECKOUT_CREATED = "CHECKOUT_CREATED",
|
||||||
CHECKOUT_QUANTITY_CHANGED = "CHECKOUT_QUANTITY_CHANGED",
|
CHECKOUT_QUANTITY_CHANGED = "CHECKOUT_QUANTITY_CHANGED",
|
||||||
|
CHECKOUT_UPDATED = "CHECKOUT_UPDATED",
|
||||||
CUSTOMER_CREATED = "CUSTOMER_CREATED",
|
CUSTOMER_CREATED = "CUSTOMER_CREATED",
|
||||||
FULFILLMENT_CREATED = "FULFILLMENT_CREATED",
|
FULFILLMENT_CREATED = "FULFILLMENT_CREATED",
|
||||||
INVOICE_DELETED = "INVOICE_DELETED",
|
INVOICE_DELETED = "INVOICE_DELETED",
|
||||||
|
|
|
@ -32,6 +32,14 @@ const WebhookEvents: React.FC<WebhookEventsProps> = ({
|
||||||
defaultMessage: "All events",
|
defaultMessage: "All events",
|
||||||
description: "event"
|
description: "event"
|
||||||
}),
|
}),
|
||||||
|
[WebhookEventTypeEnum.CHECKOUT_CREATED]: intl.formatMessage({
|
||||||
|
defaultMessage: "Checkout created",
|
||||||
|
description: "event"
|
||||||
|
}),
|
||||||
|
[WebhookEventTypeEnum.CHECKOUT_UPDATED]: intl.formatMessage({
|
||||||
|
defaultMessage: "Checkout updated",
|
||||||
|
description: "event"
|
||||||
|
}),
|
||||||
[WebhookEventTypeEnum.CUSTOMER_CREATED]: intl.formatMessage({
|
[WebhookEventTypeEnum.CUSTOMER_CREATED]: intl.formatMessage({
|
||||||
defaultMessage: "Customer created",
|
defaultMessage: "Customer created",
|
||||||
description: "event"
|
description: "event"
|
||||||
|
|
Loading…
Reference in a new issue