Merge pull request #234 from mirumee/ref/update-mui
Update @material-ui to v4
This commit is contained in:
commit
12659ef660
357 changed files with 47829 additions and 49678 deletions
|
@ -3,7 +3,7 @@ language: node_js
|
|||
sudo: false
|
||||
|
||||
node_js:
|
||||
- "11.15"
|
||||
- "12.12"
|
||||
|
||||
branches:
|
||||
only:
|
||||
|
|
|
@ -55,3 +55,4 @@ All notable, unreleased changes to this project will be documented in this file.
|
|||
- Fix minor bugs - #230 by @dominik-zeglen
|
||||
- Fix permission handling - #231 by @dominik-zeglen
|
||||
- Use React.FC instead of deprecated React.StatelessComponent type - #245 by @dominik-zeglen
|
||||
- Update @material-ui to v4 - #234 by @dominik-zeglen
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
module.exports = api => {
|
||||
const isExtract = api.env("extract");
|
||||
const isTest = api.env("test");
|
||||
const isStorybook = api.env("storybook");
|
||||
|
||||
|
@ -30,16 +31,20 @@ module.exports = api => {
|
|||
}
|
||||
],
|
||||
"@babel/plugin-proposal-object-rest-spread",
|
||||
"react-intl-auto",
|
||||
[
|
||||
"react-intl-auto"
|
||||
];
|
||||
|
||||
if (isExtract) {
|
||||
plugins.push([
|
||||
"react-intl",
|
||||
{
|
||||
extractFromFormatMessageCall: true,
|
||||
messagesDir: "build/locale/"
|
||||
}
|
||||
],
|
||||
"macros"
|
||||
];
|
||||
]);
|
||||
}
|
||||
|
||||
plugins.push("macros");
|
||||
|
||||
return {
|
||||
presets,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2019-11-06T13:15:56.589Z\n"
|
||||
"POT-Creation-Date: 2019-11-07T13:41:50.654Z\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -28,7 +28,7 @@ msgid "*Optional. Adding product to collection helps users find it."
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/attributes/views/AttributeCreate/AttributeCreate.json
|
||||
#. [src.attributes.views.AttributeCreate.2348058468] - attribute value edit error
|
||||
#. [src.attributes.views.AttributeCreate.354316953] - attribute value edit error
|
||||
#. defaultMessage is:
|
||||
#. A value named {name} already exists
|
||||
msgctxt "attribute value edit error"
|
||||
|
@ -623,6 +623,14 @@ msgctxt "product attribute error"
|
|||
msgid "All attributes should have value"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/webhooks/components/WebhookEvents/WebhookEvents.json
|
||||
#. [src.webhooks.components.WebhookEvents.2454751033] - event
|
||||
#. defaultMessage is:
|
||||
#. All events
|
||||
msgctxt "event"
|
||||
msgid "All events"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/taxes/components/TaxConfiguration/TaxConfiguration.json
|
||||
#. [src.taxes.components.TaxConfiguration.142803418]
|
||||
#. defaultMessage is:
|
||||
|
@ -663,14 +671,6 @@ msgctxt "description"
|
|||
msgid "Anonymous user"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/webhooks/components/WebhookEvents/WebhookEvents.json
|
||||
#. [src.webhooks.components.WebhookEvents.3053363669] - event
|
||||
#. defaultMessage is:
|
||||
#. Any events
|
||||
msgctxt "event"
|
||||
msgid "Any events"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/discounts/components/VoucherSummary/VoucherSummary.json
|
||||
#. [src.discounts.components.VoucherSummary.2735425668] - voucher
|
||||
#. defaultMessage is:
|
||||
|
@ -728,7 +728,7 @@ msgid "Are you sure you want to cancel this fulfillment?"
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/orders/components/OrderBulkCancelDialog/OrderBulkCancelDialog.json
|
||||
#. [src.orders.components.OrderBulkCancelDialog.276130122]
|
||||
#. [src.orders.components.OrderBulkCancelDialog.3011571869]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to cancel {counter,plural,one{this order} other{{displayQuantity} orders}}?
|
||||
msgctxt "description"
|
||||
|
@ -736,7 +736,7 @@ msgid "Are you sure you want to cancel {counter,plural,one{this order} other{{di
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/attributes/components/AttributeValueDeleteDialog/AttributeValueDeleteDialog.json
|
||||
#. [src.attributes.components.AttributeValueDeleteDialog.273524270] - delete attribute value
|
||||
#. [src.attributes.components.AttributeValueDeleteDialog.1326420604] - delete attribute value
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete "{name}" value?
|
||||
msgctxt "delete attribute value"
|
||||
|
@ -744,7 +744,7 @@ msgid "Are you sure you want to delete \"{name}\" value?"
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/attributes/components/AttributeValueDeleteDialog/AttributeValueDeleteDialog.json
|
||||
#. [src.attributes.components.AttributeValueDeleteDialog.1934550550]
|
||||
#. [src.attributes.components.AttributeValueDeleteDialog.4031078167]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete "{name}" value? If you delete it you won’t be able to assign it to any of the products with "{attributeName}" attribute.
|
||||
msgctxt "description"
|
||||
|
@ -760,11 +760,11 @@ msgid "Are you sure you want to delete collection's image?"
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/orders/components/OrderDraftCancelDialog/OrderDraftCancelDialog.json
|
||||
#. [src.orders.components.OrderDraftCancelDialog.36681973]
|
||||
#. [src.orders.components.OrderDraftCancelDialog.66064347]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete draft #{number}?
|
||||
#. Are you sure you want to delete draft #{orderNumber}?
|
||||
msgctxt "description"
|
||||
msgid "Are you sure you want to delete draft #{number}?"
|
||||
msgid "Are you sure you want to delete draft #{orderNumber}?"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/navigation/views/MenuDetails/index.json
|
||||
|
@ -832,7 +832,7 @@ msgid "Are you sure you want to delete {collectionName}?"
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/attributes/components/AttributeBulkDeleteDialog/AttributeBulkDeleteDialog.json
|
||||
#. [src.attributes.components.AttributeBulkDeleteDialog.2916860383] - dialog content
|
||||
#. [src.attributes.components.AttributeBulkDeleteDialog.1860138828] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this attribute} other{{displayQuantity} attributes}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -840,7 +840,7 @@ msgid "Are you sure you want to delete {counter,plural,one{this attribute} other
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/categories/views/CategoryDetails.json
|
||||
#. [src.categories.views.299584400]
|
||||
#. [src.categories.views.982216972]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this attribute} other{{displayQuantity} categories}}?
|
||||
msgctxt "description"
|
||||
|
@ -848,7 +848,7 @@ msgid "Are you sure you want to delete {counter,plural,one{this attribute} other
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/categories/views/CategoryDetails.json
|
||||
#. [src.categories.views.3231188861]
|
||||
#. [src.categories.views.3920301974]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this attribute} other{{displayQuantity} products}}?
|
||||
msgctxt "description"
|
||||
|
@ -856,7 +856,7 @@ msgid "Are you sure you want to delete {counter,plural,one{this attribute} other
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/categories/views/CategoryList/CategoryList.json
|
||||
#. [src.categories.views.CategoryList.2144707585]
|
||||
#. [src.categories.views.CategoryList.1592907702]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this category} other{{displayQuantity} categories}}?
|
||||
msgctxt "description"
|
||||
|
@ -864,7 +864,7 @@ msgid "Are you sure you want to delete {counter,plural,one{this category} other{
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/collections/views/CollectionList/CollectionList.json
|
||||
#. [src.collections.views.CollectionList.2497542455]
|
||||
#. [src.collections.views.CollectionList.1421224348]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this collection} other{{displayQuantity} collections}}?
|
||||
msgctxt "description"
|
||||
|
@ -872,7 +872,7 @@ msgid "Are you sure you want to delete {counter,plural,one{this collection} othe
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/customers/views/CustomerList/CustomerList.json
|
||||
#. [src.customers.views.CustomerList.409347866]
|
||||
#. [src.customers.views.CustomerList.3616300497]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this customer} other{{displayQuantity} customers}}?
|
||||
msgctxt "description"
|
||||
|
@ -888,7 +888,7 @@ msgid "Are you sure you want to delete {counter,plural,one{this menu} other{{dis
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/orders/views/OrderDraftList/OrderDraftList.json
|
||||
#. [src.orders.views.OrderDraftList.1389231130] - dialog content
|
||||
#. [src.orders.views.OrderDraftList.1398914741] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this order draft} other{{displayQuantity} orderDrafts}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -896,7 +896,7 @@ msgid "Are you sure you want to delete {counter,plural,one{this order draft} oth
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/pages/views/PageList.json
|
||||
#. [src.pages.views.3382708469] - dialog content
|
||||
#. [src.pages.views.808633099] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this page} other{{displayQuantity} pages}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -904,7 +904,7 @@ msgid "Are you sure you want to delete {counter,plural,one{this page} other{{dis
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/productTypes/views/ProductTypeList/ProductTypeList.json
|
||||
#. [src.productTypes.views.ProductTypeList.2294091098] - dialog content
|
||||
#. [src.productTypes.views.ProductTypeList.2787668922] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this product type} other{{displayQuantity} product types}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -912,7 +912,7 @@ msgid "Are you sure you want to delete {counter,plural,one{this product type} ot
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/products/views/ProductList/ProductList.json
|
||||
#. [src.products.views.ProductList.2742463171] - dialog content
|
||||
#. [src.products.views.ProductList.785143617] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this product} other{{displayQuantity} products}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -920,7 +920,7 @@ msgid "Are you sure you want to delete {counter,plural,one{this product} other{{
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/discounts/views/SaleList/SaleList.json
|
||||
#. [src.discounts.views.SaleList.2516361175] - dialog content
|
||||
#. [src.discounts.views.SaleList.315033130] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this sale} other{{displayQuantity} sales}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -928,7 +928,7 @@ msgid "Are you sure you want to delete {counter,plural,one{this sale} other{{dis
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/shipping/views/ShippingZonesList.json
|
||||
#. [src.shipping.views.3698270769] - dialog content
|
||||
#. [src.shipping.views.226833304] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this shipping zone} other{{displayQuantity} shipping zones}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -936,7 +936,7 @@ msgid "Are you sure you want to delete {counter,plural,one{this shipping zone} o
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/products/views/ProductUpdate/ProductUpdate.json
|
||||
#. [src.products.views.ProductUpdate.2446451819] - dialog content
|
||||
#. [src.products.views.ProductUpdate.408018316] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this variant} other{{displayQuantity} variants}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -944,7 +944,7 @@ msgid "Are you sure you want to delete {counter,plural,one{this variant} other{{
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/discounts/views/VoucherList/VoucherList.json
|
||||
#. [src.discounts.views.VoucherList.1791926983] - dialog content
|
||||
#. [src.discounts.views.VoucherList.3263927472] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to delete {counter,plural,one{this voucher} other{{displayQuantity} vouchers}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -1080,11 +1080,11 @@ msgid "Are you sure you want to delete {voucherCode}?"
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/orders/components/OrderDraftFinalizeDialog/OrderDraftFinalizeDialog.json
|
||||
#. [src.orders.components.OrderDraftFinalizeDialog.1489195029]
|
||||
#. [src.orders.components.OrderDraftFinalizeDialog.3358029330]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to finalize draft #{number}?
|
||||
#. Are you sure you want to finalize draft #{orderNumber}?
|
||||
msgctxt "description"
|
||||
msgid "Are you sure you want to finalize draft #{number}?"
|
||||
msgid "Are you sure you want to finalize draft #{orderNumber}?"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/orders/components/OrderMarkAsPaidDialog/OrderMarkAsPaidDialog.json
|
||||
|
@ -1096,7 +1096,7 @@ msgid "Are you sure you want to mark this order as paid?"
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/collections/views/CollectionList/CollectionList.json
|
||||
#. [src.collections.views.CollectionList.1348793822]
|
||||
#. [src.collections.views.CollectionList.3216529047]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to publish {counter,plural,one{this collection} other{{displayQuantity} collections}}?
|
||||
msgctxt "description"
|
||||
|
@ -1104,7 +1104,7 @@ msgid "Are you sure you want to publish {counter,plural,one{this collection} oth
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/pages/views/PageList.json
|
||||
#. [src.pages.views.504298570] - dialog content
|
||||
#. [src.pages.views.64432778] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to publish {counter,plural,one{this page} other{{displayQuantity} pages}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -1112,7 +1112,7 @@ msgid "Are you sure you want to publish {counter,plural,one{this page} other{{di
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/products/views/ProductList/ProductList.json
|
||||
#. [src.products.views.ProductList.740606822] - dialog content
|
||||
#. [src.products.views.ProductList.4099592898] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to publish {counter,plural,one{this product} other{{displayQuantity} products}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -1136,19 +1136,19 @@ msgid "Are you sure you want to unassign {attributeName} from {productTypeName}?
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/productTypes/components/ProductTypeBulkAttributeUnassignDialog/ProductTypeBulkAttributeUnassignDialog.json
|
||||
#. [src.productTypes.components.ProductTypeBulkAttributeUnassignDialog.2500510112] - unassign multiple attributes from product type
|
||||
#. [src.productTypes.components.ProductTypeBulkAttributeUnassignDialog.1465383223] - unassign multiple attributes from product type
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to unassign {counter,plural,one{this attribute} other{{displayQuantity} attributes}} from {productTypeName}?
|
||||
#. Are you sure you want to unassign {counter,plural,one{this attribute} other{{attributeQuantity} attributes}} from {productTypeName}?
|
||||
msgctxt "unassign multiple attributes from product type"
|
||||
msgid "Are you sure you want to unassign {counter,plural,one{this attribute} other{{displayQuantity} attributes}} from {productTypeName}?"
|
||||
msgid "Are you sure you want to unassign {counter,plural,one{this attribute} other{{attributeQuantity} attributes}} from {productTypeName}?"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/discounts/views/SaleDetails.json
|
||||
#. [src.discounts.views.376977560] - dialog content
|
||||
#. [src.discounts.views.1169376180] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to unassign {counter,plural,one{this category} other{{displayQuantity} categories}}?
|
||||
#: build/locale/src/discounts/views/VoucherDetails.json
|
||||
#. [src.discounts.views.376977560] - dialog content
|
||||
#. [src.discounts.views.1169376180] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to unassign {counter,plural,one{this category} other{{displayQuantity} categories}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -1156,11 +1156,11 @@ msgid "Are you sure you want to unassign {counter,plural,one{this category} othe
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/discounts/views/SaleDetails.json
|
||||
#. [src.discounts.views.396618268] - dialog content
|
||||
#. [src.discounts.views.3809911073] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to unassign {counter,plural,one{this collection} other{{displayQuantity} collections}}?
|
||||
#: build/locale/src/discounts/views/VoucherDetails.json
|
||||
#. [src.discounts.views.396618268] - dialog content
|
||||
#. [src.discounts.views.3809911073] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to unassign {counter,plural,one{this collection} other{{displayQuantity} collections}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -1168,7 +1168,7 @@ msgid "Are you sure you want to unassign {counter,plural,one{this collection} ot
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/collections/views/CollectionDetails.json
|
||||
#. [src.collections.views.1908998638]
|
||||
#. [src.collections.views.735691989]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to unassign {counter,plural,one{this product} other{{displayQuantity} products}}?
|
||||
msgctxt "description"
|
||||
|
@ -1176,11 +1176,11 @@ msgid "Are you sure you want to unassign {counter,plural,one{this product} other
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/discounts/views/SaleDetails.json
|
||||
#. [src.discounts.views.786949385] - dialog content
|
||||
#. [src.discounts.views.735691989] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to unassign {counter,plural,one{this product} other{{displayQuantity} products}}?
|
||||
#: build/locale/src/discounts/views/VoucherDetails.json
|
||||
#. [src.discounts.views.786949385] - dialog content
|
||||
#. [src.discounts.views.735691989] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to unassign {counter,plural,one{this product} other{{displayQuantity} products}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -1188,7 +1188,7 @@ msgid "Are you sure you want to unassign {counter,plural,one{this product} other
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/collections/views/CollectionList/CollectionList.json
|
||||
#. [src.collections.views.CollectionList.3944356444]
|
||||
#. [src.collections.views.CollectionList.3449136787]
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to unpublish {counter,plural,one{this collection} other{{displayQuantity} collections}}?
|
||||
msgctxt "description"
|
||||
|
@ -1196,7 +1196,7 @@ msgid "Are you sure you want to unpublish {counter,plural,one{this collection} o
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/pages/views/PageList.json
|
||||
#. [src.pages.views.691980200] - dialog content
|
||||
#. [src.pages.views.1265636351] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to unpublish {counter,plural,one{this page} other{{displayQuantity} pages}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -1204,7 +1204,7 @@ msgid "Are you sure you want to unpublish {counter,plural,one{this page} other{{
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/products/views/ProductList/ProductList.json
|
||||
#. [src.products.views.ProductList.193914731] - dialog content
|
||||
#. [src.products.views.ProductList.1752069132] - dialog content
|
||||
#. defaultMessage is:
|
||||
#. Are you sure you want to unpublish {counter,plural,one{this product} other{{displayQuantity} products}}?
|
||||
msgctxt "dialog content"
|
||||
|
@ -1484,7 +1484,7 @@ msgid "Authentication Type"
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/siteSettings/components/SiteSettingsPage/SiteSettingsPage.json
|
||||
#. [src.siteSettings.components.SiteSettingsPage.3619898341]
|
||||
#. [src.siteSettings.components.SiteSettingsPage.1214877701]
|
||||
#. defaultMessage is:
|
||||
#. Authentication method defines additional ways that customers can log in to your ecommerce.
|
||||
msgctxt "description"
|
||||
|
@ -5507,6 +5507,14 @@ msgctxt "description"
|
|||
msgid "Order draft succesfully created"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/webhooks/components/WebhookEvents/WebhookEvents.json
|
||||
#. [src.webhooks.components.WebhookEvents.3907151399] - event
|
||||
#. defaultMessage is:
|
||||
#. Order fulfilled
|
||||
msgctxt "event"
|
||||
msgid "Order fulfilled"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/webhooks/components/WebhookEvents/WebhookEvents.json
|
||||
#. [src.webhooks.components.WebhookEvents.3345061702] - event
|
||||
#. defaultMessage is:
|
||||
|
@ -8436,11 +8444,11 @@ msgid "Translation"
|
|||
msgstr ""
|
||||
|
||||
#: build/locale/src/translations/components/TranslationsCategoriesPage/TranslationsCategoriesPage.json
|
||||
#. [src.translations.components.TranslationsCategoriesPage.2043581404]
|
||||
#. [src.translations.components.TranslationsCategoriesPage.1611537010]
|
||||
#. defaultMessage is:
|
||||
#. Translation Category "{categoryNane}" - {languageCode}
|
||||
#. Translation Category "{categoryName}" - {languageCode}
|
||||
msgctxt "description"
|
||||
msgid "Translation Category \"{categoryNane}\" - {languageCode}"
|
||||
msgid "Translation Category \"{categoryName}\" - {languageCode}"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/translations/components/TranslationsCollectionsPage/TranslationsCollectionsPage.json
|
||||
|
@ -9598,33 +9606,45 @@ msgstr ""
|
|||
#: build/locale/src/home/components/HomeProductListCard/HomeProductListCard.json
|
||||
#. [homeProductListCardOrders] - number of ordered products
|
||||
#. defaultMessage is:
|
||||
#. {amount,plural,one{One ordered} other{{amount} Ordered}}
|
||||
#. {amount, plural,
|
||||
#. one {One ordered}
|
||||
#. other {{amount} Ordered}
|
||||
#. }
|
||||
msgctxt "number of ordered products"
|
||||
msgid "{amount,plural,one{One ordered} other{{amount} Ordered}}"
|
||||
msgid "{amount, plural,\n one {One ordered}\n other {{amount} Ordered}\n }"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/home/components/HomeNotificationTable/HomeNotificationTable.json
|
||||
#. [homeNotificationTableOrders]
|
||||
#. defaultMessage is:
|
||||
#. {amount,plural,one{One order} other{{amount} Orders}} are ready to fulfill
|
||||
#. {amount, plural,
|
||||
#. one {One order}
|
||||
#. other {{amount} Orders}
|
||||
#. } are ready to fulfill
|
||||
msgctxt "description"
|
||||
msgid "{amount,plural,one{One order} other{{amount} Orders}} are ready to fulfill"
|
||||
msgid "{amount, plural,\n one {One order}\n other {{amount} Orders}\n } are ready to fulfill"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/home/components/HomeNotificationTable/HomeNotificationTable.json
|
||||
#. [homeNotificationTablePayments]
|
||||
#. defaultMessage is:
|
||||
#. {amount,plural,one{One payment} other{{amount} Payments}} to capture
|
||||
#. {amount, plural,
|
||||
#. one {One payment}
|
||||
#. other {{amount} Payments}
|
||||
#. } to capture
|
||||
msgctxt "description"
|
||||
msgid "{amount,plural,one{One payment} other{{amount} Payments}} to capture"
|
||||
msgid "{amount, plural,\n one {One payment}\n other {{amount} Payments}\n } to capture"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/home/components/HomeNotificationTable/HomeNotificationTable.json
|
||||
#. [homeNotificationTableProducts]
|
||||
#. defaultMessage is:
|
||||
#. {amount,plural,one{One product} other{{amount} Products}} out of stock
|
||||
#. {amount, plural,
|
||||
#. one {One product}
|
||||
#. other {{amount} Products}
|
||||
#. } out of stock
|
||||
msgctxt "description"
|
||||
msgid "{amount,plural,one{One product} other{{amount} Products}} out of stock"
|
||||
msgid "{amount, plural,\n one {One product}\n other {{amount} Products}\n } out of stock"
|
||||
msgstr ""
|
||||
|
||||
#: build/locale/src/translations/components/TranslationsEntitiesList/TranslationsEntitiesList.json
|
||||
|
|
8103
package-lock.json
generated
8103
package-lock.json
generated
File diff suppressed because it is too large
Load diff
17
package.json
17
package.json
|
@ -13,13 +13,13 @@
|
|||
},
|
||||
"homepage": "http://getsaleor.com/",
|
||||
"engines": {
|
||||
"node": ">=10.6.0",
|
||||
"npm": ">=6.1.0"
|
||||
"node": ">=12.12.0",
|
||||
"npm": ">=6.11.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@material-ui/core": "^3.9.3",
|
||||
"@material-ui/icons": "^3.0.2",
|
||||
"@material-ui/styles": "^3.0.0-alpha.10",
|
||||
"@material-ui/core": "^4.5.1",
|
||||
"@material-ui/icons": "^4.5.1",
|
||||
"@material-ui/styles": "^4.5.2",
|
||||
"apollo": "^2.17.2",
|
||||
"apollo-cache-inmemory": "^1.6.2",
|
||||
"apollo-client": "^2.6.4",
|
||||
|
@ -45,7 +45,7 @@
|
|||
"lodash": "^4.17.14",
|
||||
"lodash-es": "^4.17.14",
|
||||
"moment-timezone": "^0.5.26",
|
||||
"qs": "^6.7.0",
|
||||
"qs": "^6.9.0",
|
||||
"react": "^16.9.0",
|
||||
"react-apollo": "^3.0.0",
|
||||
"react-dom": "^16.9.0",
|
||||
|
@ -63,7 +63,7 @@
|
|||
"react-sortable-tree": "^2.6.2",
|
||||
"react-svg": "^2.2.11",
|
||||
"slugify": "^1.3.4",
|
||||
"typescript": "^3.5.3",
|
||||
"typescript": "^3.6.4",
|
||||
"url-join": "^4.0.1",
|
||||
"use-react-router": "^1.0.7"
|
||||
},
|
||||
|
@ -108,6 +108,7 @@
|
|||
"babel-plugin-react-intl-auto": "^2.3.0",
|
||||
"codecov": "^3.5.0",
|
||||
"core-js": "^3.2.1",
|
||||
"cross-env": "^6.0.3",
|
||||
"enzyme": "^3.10.0",
|
||||
"enzyme-adapter-react-16": "^1.14.0",
|
||||
"enzyme-to-json": "^3.3.5",
|
||||
|
@ -174,7 +175,7 @@
|
|||
},
|
||||
"scripts": {
|
||||
"build": "webpack -p",
|
||||
"extract-json-messages": "rimraf build/locale && babel src 'src/**/*.{ts,tsx}' -o build/dashboard.bundle.js",
|
||||
"extract-json-messages": "rimraf build/locale && cross-env NODE_ENV=extract babel src 'src/**/*.{ts,tsx}' -o build/dashboard.bundle.js",
|
||||
"extract-pot-messages": "rip json2pot \"build/locale/**/*.json\" -c description -o locale/messages.pot",
|
||||
"extract-messages": "npm run extract-json-messages && npm run extract-pot-messages",
|
||||
"build-messages": "rip po2json 'locale/**/*.po' -m 'build/locale/**/*.json' -o 'locale' -c 'description'",
|
||||
|
|
|
@ -36,10 +36,7 @@ const AttributeBulkDeleteDialog: React.FC<AttributeBulkDeleteDialogProps> = ({
|
|||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {counter, plural,
|
||||
one {this attribute}
|
||||
other {{displayQuantity} attributes}
|
||||
}?"
|
||||
defaultMessage="Are you sure you want to delete {counter,plural,one{this attribute} other{{displayQuantity} attributes}}?"
|
||||
description="dialog content"
|
||||
values={{
|
||||
counter: quantity,
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './AttributeBulkDeleteDialog';
|
||||
export * from './AttributeBulkDeleteDialog';
|
||||
export { default } from "./AttributeBulkDeleteDialog";
|
||||
export * from "./AttributeBulkDeleteDialog";
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './AttributeDeleteDialog';
|
||||
export * from './AttributeDeleteDialog';
|
||||
export { default } from "./AttributeDeleteDialog";
|
||||
export * from "./AttributeDeleteDialog";
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './AttributeDetails';
|
||||
export * from './AttributeDetails';
|
||||
export { default } from "./AttributeDetails";
|
||||
export * from "./AttributeDetails";
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import { Theme } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Table from "@material-ui/core/Table";
|
||||
import TableBody from "@material-ui/core/TableBody";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
import TableFooter from "@material-ui/core/TableFooter";
|
||||
import TableRow from "@material-ui/core/TableRow";
|
||||
import makeStyles from "@material-ui/styles/makeStyles";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
|
@ -21,7 +20,7 @@ export interface AttributeListProps extends ListProps, ListActions {
|
|||
attributes: AttributeList_attributes_edges_node[];
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) => ({
|
||||
const useStyles = makeStyles(theme => ({
|
||||
[theme.breakpoints.up("lg")]: {
|
||||
colFaceted: {
|
||||
width: 150
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './AttributeList';
|
||||
export * from './AttributeList';
|
||||
export { default } from "./AttributeList";
|
||||
export * from "./AttributeList";
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './AttributeListPage';
|
||||
export * from './AttributeListPage';
|
||||
export { default } from "./AttributeListPage";
|
||||
export * from "./AttributeListPage";
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './AttributePage';
|
||||
export * from './AttributePage';
|
||||
export { default } from "./AttributePage";
|
||||
export * from "./AttributePage";
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './AttributeProperties';
|
||||
export * from './AttributeProperties';
|
||||
export { default } from "./AttributeProperties";
|
||||
export * from "./AttributeProperties";
|
||||
|
|
|
@ -41,7 +41,7 @@ const AttributeValueDeleteDialog: React.FC<AttributeValueDeleteDialogProps> = ({
|
|||
<DialogContentText>
|
||||
{useName ? (
|
||||
<FormattedMessage
|
||||
defaultMessage='Are you sure you want to delete "{ name }" value? If you delete it you won’t be able to assign it to any of the products with "{ attributeName }" attribute.'
|
||||
defaultMessage='Are you sure you want to delete "{name}" value? If you delete it you won’t be able to assign it to any of the products with "{attributeName}" attribute.'
|
||||
values={{
|
||||
attributeName,
|
||||
name
|
||||
|
@ -49,7 +49,7 @@ const AttributeValueDeleteDialog: React.FC<AttributeValueDeleteDialogProps> = ({
|
|||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
defaultMessage='Are you sure you want to delete "{ name }" value?'
|
||||
defaultMessage='Are you sure you want to delete "{name}" value?'
|
||||
description="delete attribute value"
|
||||
values={{
|
||||
name
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './AttributeValueDeleteDialog';
|
||||
export * from './AttributeValueDeleteDialog';
|
||||
export { default } from "./AttributeValueDeleteDialog";
|
||||
export * from "./AttributeValueDeleteDialog";
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './AttributeValueEditDialog';
|
||||
export * from './AttributeValueEditDialog';
|
||||
export { default } from "./AttributeValueEditDialog";
|
||||
export * from "./AttributeValueEditDialog";
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import Button from "@material-ui/core/Button";
|
||||
import Card from "@material-ui/core/Card";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import { Theme } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Table from "@material-ui/core/Table";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
import TableHead from "@material-ui/core/TableHead";
|
||||
import TableRow from "@material-ui/core/TableRow";
|
||||
import DeleteIcon from "@material-ui/icons/Delete";
|
||||
import makeStyles from "@material-ui/styles/makeStyles";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
|
@ -30,12 +29,12 @@ export interface AttributeValuesProps {
|
|||
onValueUpdate: (id: string) => void;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) => ({
|
||||
const useStyles = makeStyles(theme => ({
|
||||
columnAdmin: {
|
||||
width: "50%"
|
||||
},
|
||||
columnDrag: {
|
||||
width: 48 + theme.spacing.unit * 1.5
|
||||
width: 48 + theme.spacing(1.5)
|
||||
},
|
||||
columnStore: {
|
||||
width: "50%"
|
||||
|
@ -45,9 +44,9 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
},
|
||||
iconCell: {
|
||||
"&:last-child": {
|
||||
paddingRight: theme.spacing.unit
|
||||
paddingRight: theme.spacing()
|
||||
},
|
||||
width: 48 + theme.spacing.unit * 1.5
|
||||
width: 48 + theme.spacing(1.5)
|
||||
},
|
||||
link: {
|
||||
cursor: "pointer"
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './AttributeValues';
|
||||
export * from './AttributeValues';
|
||||
export { default } from "./AttributeValues";
|
||||
export * from "./AttributeValues";
|
||||
|
|
|
@ -91,7 +91,7 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
|
|||
field: "name",
|
||||
message: intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "A value named { name } already exists",
|
||||
defaultMessage: "A value named {name} already exists",
|
||||
description: "attribute value edit error"
|
||||
},
|
||||
{
|
||||
|
@ -112,7 +112,7 @@ const AttributeDetails: React.FC<AttributeDetailsProps> = ({ params }) => {
|
|||
field: "name",
|
||||
message: intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "A value named { name } already exists",
|
||||
defaultMessage: "A value named {name} already exists",
|
||||
description: "attribute value edit error"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -12,12 +12,12 @@ import {
|
|||
export const PRODUCT_FILTERS_KEY = "productFilters";
|
||||
|
||||
export function getFilterVariables(
|
||||
params: AttributeListUrlFilters
|
||||
): AttributeFilterInput {
|
||||
return {
|
||||
search: params.query
|
||||
};
|
||||
}
|
||||
params: AttributeListUrlFilters
|
||||
): AttributeFilterInput {
|
||||
return {
|
||||
search: params.query
|
||||
};
|
||||
}
|
||||
|
||||
export const {
|
||||
deleteFilterTab,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Theme } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import React from "react";
|
||||
import SVG from "react-inlinesvg";
|
||||
|
||||
|
@ -9,24 +8,24 @@ import saleorLightLogo from "@assets/images/logo-light.svg";
|
|||
import useTheme from "@saleor/hooks/useTheme";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
(theme: Theme) => ({
|
||||
theme => ({
|
||||
logo: {
|
||||
"& svg": {
|
||||
display: "block",
|
||||
height: 40,
|
||||
marginBottom: theme.spacing.unit * 4
|
||||
marginBottom: theme.spacing(4)
|
||||
}
|
||||
},
|
||||
mainPanel: {
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
padding: theme.spacing.unit * 2
|
||||
padding: theme.spacing(2)
|
||||
},
|
||||
background: theme.palette.background.paper,
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
height: "100vh",
|
||||
justifyContent: "center",
|
||||
padding: theme.spacing.unit * 6,
|
||||
padding: theme.spacing(6),
|
||||
width: "100%"
|
||||
},
|
||||
mainPanelContent: {
|
||||
|
|
|
@ -1,21 +1,26 @@
|
|||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
import { createStyles, withStyles, WithStyles } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import React from "react";
|
||||
|
||||
const styles = createStyles({
|
||||
root: {
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
height: "100vh",
|
||||
justifyContent: "center"
|
||||
}
|
||||
});
|
||||
const LoginLoading = withStyles(styles, { name: "LoginLoading" })(
|
||||
({ classes }: WithStyles<typeof styles>) => (
|
||||
const useStyles = makeStyles(
|
||||
{
|
||||
root: {
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
height: "100vh",
|
||||
justifyContent: "center"
|
||||
}
|
||||
},
|
||||
{ name: "LoginLoading" }
|
||||
);
|
||||
const LoginLoading: React.FC = props => {
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<CircularProgress size={128} />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
LoginLoading.displayName = "LoginLoading";
|
||||
export default LoginLoading;
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
import Button from "@material-ui/core/Button";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import React from "react";
|
||||
|
@ -19,8 +14,8 @@ export interface FormData {
|
|||
password: string;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
buttonContainer: {
|
||||
display: "flex",
|
||||
justifyContent: "flex-end"
|
||||
|
@ -38,93 +33,90 @@ const styles = (theme: Theme) =>
|
|||
color: theme.palette.error.contrastText
|
||||
},
|
||||
background: theme.palette.error.main,
|
||||
borderRadius: theme.spacing.unit,
|
||||
marginBottom: theme.spacing.unit * 3,
|
||||
padding: theme.spacing.unit * 1.5
|
||||
borderRadius: theme.spacing(),
|
||||
marginBottom: theme.spacing(3),
|
||||
padding: theme.spacing(1.5)
|
||||
}
|
||||
});
|
||||
}),
|
||||
{ name: "LoginCard" }
|
||||
);
|
||||
|
||||
export interface LoginCardProps extends WithStyles<typeof styles> {
|
||||
export interface LoginCardProps {
|
||||
error: boolean;
|
||||
disableLoginButton: boolean;
|
||||
onPasswordRecovery: () => void;
|
||||
onSubmit?(event: FormData);
|
||||
}
|
||||
|
||||
const LoginCard = withStyles(styles, { name: "LoginCard" })(
|
||||
({
|
||||
classes,
|
||||
error,
|
||||
disableLoginButton,
|
||||
onPasswordRecovery,
|
||||
onSubmit
|
||||
}: LoginCardProps) => {
|
||||
const intl = useIntl();
|
||||
const LoginCard: React.FC<LoginCardProps> = props => {
|
||||
const { error, disableLoginButton, onPasswordRecovery, onSubmit } = props;
|
||||
|
||||
return (
|
||||
<Form initial={{ email: "", password: "" }} onSubmit={onSubmit}>
|
||||
{({ change: handleChange, data, submit: handleSubmit }) => (
|
||||
<>
|
||||
{error && (
|
||||
<div className={classes.panel}>
|
||||
<Typography variant="caption">
|
||||
<FormattedMessage defaultMessage="Sorry, your username and/or password are incorrect. Please try again." />
|
||||
</Typography>
|
||||
</div>
|
||||
)}
|
||||
<TextField
|
||||
autoFocus
|
||||
fullWidth
|
||||
autoComplete="username"
|
||||
label={intl.formatMessage(commonMessages.email)}
|
||||
name="email"
|
||||
onChange={handleChange}
|
||||
value={data.email}
|
||||
inputProps={{
|
||||
"data-tc": "email"
|
||||
}}
|
||||
/>
|
||||
<FormSpacer />
|
||||
<TextField
|
||||
fullWidth
|
||||
autoComplete="password"
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Password"
|
||||
})}
|
||||
name="password"
|
||||
onChange={handleChange}
|
||||
type="password"
|
||||
value={data.password}
|
||||
inputProps={{
|
||||
"data-tc": "password"
|
||||
}}
|
||||
/>
|
||||
<FormSpacer />
|
||||
<div className={classes.buttonContainer}>
|
||||
<Button
|
||||
className={classes.loginButton}
|
||||
color="primary"
|
||||
disabled={disableLoginButton}
|
||||
variant="contained"
|
||||
onClick={handleSubmit}
|
||||
type="submit"
|
||||
data-tc="submit"
|
||||
>
|
||||
<FormattedMessage defaultMessage="Login" description="button" />
|
||||
</Button>
|
||||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<Form initial={{ email: "", password: "" }} onSubmit={onSubmit}>
|
||||
{({ change: handleChange, data, submit: handleSubmit }) => (
|
||||
<>
|
||||
{error && (
|
||||
<div className={classes.panel}>
|
||||
<Typography variant="caption">
|
||||
<FormattedMessage defaultMessage="Sorry, your username and/or password are incorrect. Please try again." />
|
||||
</Typography>
|
||||
</div>
|
||||
<FormSpacer />
|
||||
<Typography className={classes.link} onClick={onPasswordRecovery}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Reset your password"
|
||||
description="button"
|
||||
/>
|
||||
</Typography>
|
||||
</>
|
||||
)}
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
);
|
||||
)}
|
||||
<TextField
|
||||
autoFocus
|
||||
fullWidth
|
||||
autoComplete="username"
|
||||
label={intl.formatMessage(commonMessages.email)}
|
||||
name="email"
|
||||
onChange={handleChange}
|
||||
value={data.email}
|
||||
inputProps={{
|
||||
"data-tc": "email"
|
||||
}}
|
||||
/>
|
||||
<FormSpacer />
|
||||
<TextField
|
||||
fullWidth
|
||||
autoComplete="password"
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Password"
|
||||
})}
|
||||
name="password"
|
||||
onChange={handleChange}
|
||||
type="password"
|
||||
value={data.password}
|
||||
inputProps={{
|
||||
"data-tc": "password"
|
||||
}}
|
||||
/>
|
||||
<FormSpacer />
|
||||
<div className={classes.buttonContainer}>
|
||||
<Button
|
||||
className={classes.loginButton}
|
||||
color="primary"
|
||||
disabled={disableLoginButton}
|
||||
variant="contained"
|
||||
onClick={handleSubmit}
|
||||
type="submit"
|
||||
data-tc="submit"
|
||||
>
|
||||
<FormattedMessage defaultMessage="Login" description="button" />
|
||||
</Button>
|
||||
</div>
|
||||
<FormSpacer />
|
||||
<Typography className={classes.link} onClick={onPasswordRecovery}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Reset your password"
|
||||
description="button"
|
||||
/>
|
||||
</Typography>
|
||||
</>
|
||||
)}
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
LoginCard.displayName = "LoginCard";
|
||||
export default LoginCard;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Button from "@material-ui/core/Button";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { makeStyles } from "@material-ui/styles";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import Button from "@material-ui/core/Button";
|
||||
import { Theme } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { makeStyles } from "@material-ui/styles";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
|
@ -11,15 +10,15 @@ import FormSpacer from "@saleor/components/FormSpacer";
|
|||
import { commonMessages } from "@saleor/intl";
|
||||
|
||||
const useStyles = makeStyles(
|
||||
(theme: Theme) => ({
|
||||
theme => ({
|
||||
errorText: {
|
||||
color: theme.palette.error.contrastText
|
||||
},
|
||||
panel: {
|
||||
"& span": {
|
||||
color: theme.palette.error.contrastText
|
||||
},
|
||||
background: theme.palette.error.main,
|
||||
borderRadius: theme.spacing.unit,
|
||||
marginBottom: theme.spacing.unit * 3,
|
||||
padding: theme.spacing.unit * 1.5
|
||||
borderRadius: theme.spacing(),
|
||||
marginBottom: theme.spacing(3),
|
||||
padding: theme.spacing(1.5)
|
||||
},
|
||||
submit: {
|
||||
width: "100%"
|
||||
|
@ -51,7 +50,9 @@ const ResetPasswordPage: React.FC<ResetPasswordPageProps> = props => {
|
|||
<>
|
||||
{!!error && (
|
||||
<div className={classes.panel}>
|
||||
<Typography variant="caption">{error}</Typography>
|
||||
<Typography variant="caption" className={classes.errorText}>
|
||||
{error}
|
||||
</Typography>
|
||||
</div>
|
||||
)}
|
||||
<Typography>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import Button from "@material-ui/core/Button";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { makeStyles } from "@material-ui/styles";
|
||||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { PermissionEnum } from '../types/globalTypes'
|
||||
import { PermissionEnum } from "../types/globalTypes";
|
||||
import { User } from "./types/User";
|
||||
|
||||
export const hasPermission = (permission: PermissionEnum, user: User) =>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { Theme } from "@material-ui/core/styles";
|
||||
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import makeStyles from "@material-ui/styles/makeStyles";
|
||||
import React from "react";
|
||||
|
||||
import Button from "@material-ui/core/Button";
|
||||
|
@ -16,7 +15,7 @@ import { FormattedMessage, useIntl } from "react-intl";
|
|||
import { CategoryDetails_category_backgroundImage } from "../../types/CategoryDetails";
|
||||
import { FormData } from "../CategoryUpdatePage";
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) => ({
|
||||
const useStyles = makeStyles(theme => ({
|
||||
fileField: {
|
||||
display: "none"
|
||||
},
|
||||
|
@ -29,11 +28,11 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
imageContainer: {
|
||||
background: "#ffffff",
|
||||
border: "1px solid #eaeaea",
|
||||
borderRadius: theme.spacing.unit,
|
||||
borderRadius: theme.spacing(),
|
||||
height: 148,
|
||||
justifySelf: "start",
|
||||
overflow: "hidden",
|
||||
padding: theme.spacing.unit * 2,
|
||||
padding: theme.spacing(2),
|
||||
position: "relative",
|
||||
width: 148
|
||||
}
|
||||
|
|
|
@ -4,19 +4,14 @@ import DialogActions from "@material-ui/core/DialogActions";
|
|||
import DialogContent from "@material-ui/core/DialogContent";
|
||||
import DialogContentText from "@material-ui/core/DialogContentText";
|
||||
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import { buttonMessages } from "@saleor/intl";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
deleteButton: {
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.error.main
|
||||
|
@ -24,49 +19,58 @@ const styles = (theme: Theme) =>
|
|||
backgroundColor: theme.palette.error.main,
|
||||
color: theme.palette.error.contrastText
|
||||
}
|
||||
});
|
||||
}),
|
||||
{
|
||||
name: "CategoryDeleteDialog"
|
||||
}
|
||||
);
|
||||
|
||||
export interface CategoryDeleteDialogProps extends WithStyles<typeof styles> {
|
||||
export interface CategoryDeleteDialogProps {
|
||||
open: boolean;
|
||||
name: string;
|
||||
onClose();
|
||||
onConfirm();
|
||||
}
|
||||
|
||||
const CategoryDeleteDialog = withStyles(styles, {
|
||||
name: "CategoryDeleteDialog"
|
||||
})(({ classes, name, open, onConfirm, onClose }: CategoryDeleteDialogProps) => (
|
||||
<Dialog onClose={onClose} open={open}>
|
||||
<DialogTitle>
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete category"
|
||||
description="dialog title"
|
||||
/>
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
const CategoryDeleteDialog: React.FC<CategoryDeleteDialogProps> = props => {
|
||||
const { name, open, onConfirm, onClose } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<Dialog onClose={onClose} open={open}>
|
||||
<DialogTitle>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {categoryName}?"
|
||||
description="delete category"
|
||||
values={{
|
||||
categoryName: <strong>{name}</strong>
|
||||
}}
|
||||
defaultMessage="Delete category"
|
||||
description="dialog title"
|
||||
/>
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose}>
|
||||
<FormattedMessage {...buttonMessages.back} />
|
||||
</Button>
|
||||
<Button
|
||||
className={classes.deleteButton}
|
||||
variant="contained"
|
||||
onClick={onConfirm}
|
||||
>
|
||||
<FormattedMessage {...buttonMessages.save} />
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
));
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {categoryName}?"
|
||||
description="delete category"
|
||||
values={{
|
||||
categoryName: <strong>{name}</strong>
|
||||
}}
|
||||
/>
|
||||
</DialogContentText>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose}>
|
||||
<FormattedMessage {...buttonMessages.back} />
|
||||
</Button>
|
||||
<Button
|
||||
className={classes.deleteButton}
|
||||
variant="contained"
|
||||
onClick={onConfirm}
|
||||
>
|
||||
<FormattedMessage {...buttonMessages.save} />
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
CategoryDeleteDialog.displayName = "CategoryDeleteDialog";
|
||||
export default CategoryDeleteDialog;
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Table from "@material-ui/core/Table";
|
||||
import TableBody from "@material-ui/core/TableBody";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
|
@ -20,8 +15,8 @@ import TablePagination from "@saleor/components/TablePagination";
|
|||
import { maybe, renderCollection } from "@saleor/misc";
|
||||
import { ListActions, ListProps } from "@saleor/types";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
[theme.breakpoints.up("lg")]: {
|
||||
colName: {
|
||||
width: 840
|
||||
|
@ -45,7 +40,9 @@ const styles = (theme: Theme) =>
|
|||
tableRow: {
|
||||
cursor: "pointer"
|
||||
}
|
||||
});
|
||||
}),
|
||||
{ name: "CategoryList" }
|
||||
);
|
||||
|
||||
interface CategoryListProps extends ListProps, ListActions {
|
||||
categories?: CategoryFragment[];
|
||||
|
@ -55,10 +52,9 @@ interface CategoryListProps extends ListProps, ListActions {
|
|||
|
||||
const numberOfColumns = 4;
|
||||
|
||||
const CategoryList = withStyles(styles, { name: "CategoryList" })(
|
||||
({
|
||||
const CategoryList: React.FC<CategoryListProps> = props => {
|
||||
const {
|
||||
categories,
|
||||
classes,
|
||||
disabled,
|
||||
settings,
|
||||
pageInfo,
|
||||
|
@ -72,7 +68,11 @@ const CategoryList = withStyles(styles, { name: "CategoryList" })(
|
|||
onPreviousPage,
|
||||
onUpdateListSettings,
|
||||
onRowClick
|
||||
}: CategoryListProps & WithStyles<typeof styles>) => (
|
||||
} = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<Table>
|
||||
<TableHead
|
||||
colSpan={numberOfColumns}
|
||||
|
@ -175,7 +175,8 @@ const CategoryList = withStyles(styles, { name: "CategoryList" })(
|
|||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
CategoryList.displayName = "CategoryList";
|
||||
export default CategoryList;
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Table from "@material-ui/core/Table";
|
||||
import TableBody from "@material-ui/core/TableBody";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
|
@ -25,8 +20,8 @@ import { ListActions, ListProps } from "@saleor/types";
|
|||
import React from "react";
|
||||
import { CategoryDetails_category_products_edges_node } from "../../types/CategoryDetails";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
[theme.breakpoints.up("lg")]: {
|
||||
colName: {
|
||||
width: "auto"
|
||||
|
@ -69,20 +64,20 @@ const styles = (theme: Theme) =>
|
|||
textRight: {
|
||||
textAlign: "right"
|
||||
}
|
||||
});
|
||||
}),
|
||||
{
|
||||
name: "CategoryProductList"
|
||||
}
|
||||
);
|
||||
|
||||
interface CategoryProductListProps
|
||||
extends ListProps,
|
||||
ListActions,
|
||||
WithStyles<typeof styles> {
|
||||
interface CategoryProductListProps extends ListProps, ListActions {
|
||||
products: CategoryDetails_category_products_edges_node[];
|
||||
}
|
||||
|
||||
export const CategoryProductList = withStyles(styles, {
|
||||
name: "CategoryProductList"
|
||||
})(
|
||||
({
|
||||
classes,
|
||||
export const CategoryProductList: React.FC<
|
||||
CategoryProductListProps
|
||||
> = props => {
|
||||
const {
|
||||
disabled,
|
||||
isChecked,
|
||||
pageInfo,
|
||||
|
@ -94,150 +89,150 @@ export const CategoryProductList = withStyles(styles, {
|
|||
onNextPage,
|
||||
onPreviousPage,
|
||||
onRowClick
|
||||
}: CategoryProductListProps) => {
|
||||
const intl = useIntl();
|
||||
} = props;
|
||||
|
||||
const numberOfColumns = 5;
|
||||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<div className={classes.tableContainer}>
|
||||
<Table className={classes.table}>
|
||||
<colgroup>
|
||||
<col />
|
||||
<col className={classes.colName} />
|
||||
<col className={classes.colType} />
|
||||
<col className={classes.colPublished} />
|
||||
<col className={classes.colPrice} />
|
||||
</colgroup>
|
||||
<TableHead
|
||||
colSpan={numberOfColumns}
|
||||
selected={selected}
|
||||
disabled={disabled}
|
||||
items={products}
|
||||
toggleAll={toggleAll}
|
||||
toolbar={toolbar}
|
||||
>
|
||||
<TableCell className={classes.colName}>
|
||||
<span className={classes.colNameHeader}>
|
||||
<FormattedMessage defaultMessage="Name" description="product" />
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colType}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Type"
|
||||
description="product type"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colPublished}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Published"
|
||||
description="product status"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colPrice}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Price"
|
||||
description="product price"
|
||||
/>
|
||||
</TableCell>
|
||||
</TableHead>
|
||||
<TableFooter>
|
||||
<TableRow>
|
||||
<TablePagination
|
||||
colSpan={numberOfColumns}
|
||||
hasNextPage={
|
||||
pageInfo && !disabled ? pageInfo.hasNextPage : false
|
||||
}
|
||||
onNextPage={onNextPage}
|
||||
hasPreviousPage={
|
||||
pageInfo && !disabled ? pageInfo.hasPreviousPage : false
|
||||
}
|
||||
onPreviousPage={onPreviousPage}
|
||||
/>
|
||||
</TableRow>
|
||||
</TableFooter>
|
||||
<TableBody>
|
||||
{renderCollection(
|
||||
products,
|
||||
product => {
|
||||
const isSelected = product ? isChecked(product.id) : false;
|
||||
const numberOfColumns = 5;
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
selected={isSelected}
|
||||
hover={!!product}
|
||||
key={product ? product.id : "skeleton"}
|
||||
onClick={product && onRowClick(product.id)}
|
||||
className={classes.link}
|
||||
return (
|
||||
<div className={classes.tableContainer}>
|
||||
<Table className={classes.table}>
|
||||
<colgroup>
|
||||
<col />
|
||||
<col className={classes.colName} />
|
||||
<col className={classes.colType} />
|
||||
<col className={classes.colPublished} />
|
||||
<col className={classes.colPrice} />
|
||||
</colgroup>
|
||||
<TableHead
|
||||
colSpan={numberOfColumns}
|
||||
selected={selected}
|
||||
disabled={disabled}
|
||||
items={products}
|
||||
toggleAll={toggleAll}
|
||||
toolbar={toolbar}
|
||||
>
|
||||
<TableCell className={classes.colName}>
|
||||
<span className={classes.colNameHeader}>
|
||||
<FormattedMessage defaultMessage="Name" description="product" />
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colType}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Type"
|
||||
description="product type"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colPublished}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Published"
|
||||
description="product status"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colPrice}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Price"
|
||||
description="product price"
|
||||
/>
|
||||
</TableCell>
|
||||
</TableHead>
|
||||
<TableFooter>
|
||||
<TableRow>
|
||||
<TablePagination
|
||||
colSpan={numberOfColumns}
|
||||
hasNextPage={pageInfo && !disabled ? pageInfo.hasNextPage : false}
|
||||
onNextPage={onNextPage}
|
||||
hasPreviousPage={
|
||||
pageInfo && !disabled ? pageInfo.hasPreviousPage : false
|
||||
}
|
||||
onPreviousPage={onPreviousPage}
|
||||
/>
|
||||
</TableRow>
|
||||
</TableFooter>
|
||||
<TableBody>
|
||||
{renderCollection(
|
||||
products,
|
||||
product => {
|
||||
const isSelected = product ? isChecked(product.id) : false;
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
selected={isSelected}
|
||||
hover={!!product}
|
||||
key={product ? product.id : "skeleton"}
|
||||
onClick={product && onRowClick(product.id)}
|
||||
className={classes.link}
|
||||
>
|
||||
<TableCell padding="checkbox">
|
||||
<Checkbox
|
||||
checked={isSelected}
|
||||
disabled={disabled}
|
||||
disableClickPropagation
|
||||
onChange={() => toggle(product.id)}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCellAvatar
|
||||
className={classes.colName}
|
||||
thumbnail={maybe(() => product.thumbnail.url)}
|
||||
>
|
||||
<TableCell padding="checkbox">
|
||||
<Checkbox
|
||||
checked={isSelected}
|
||||
disabled={disabled}
|
||||
disableClickPropagation
|
||||
onChange={() => toggle(product.id)}
|
||||
{product ? product.name : <Skeleton />}
|
||||
</TableCellAvatar>
|
||||
<TableCell className={classes.colType}>
|
||||
{product && product.productType ? (
|
||||
product.productType.name
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colPublished}>
|
||||
{product &&
|
||||
maybe(() => product.isAvailable !== undefined) ? (
|
||||
<StatusLabel
|
||||
label={
|
||||
product.isAvailable
|
||||
? intl.formatMessage({
|
||||
defaultMessage: "Published",
|
||||
description: "product",
|
||||
id: "productStatusLabel"
|
||||
})
|
||||
: intl.formatMessage({
|
||||
defaultMessage: "Not published",
|
||||
description: "product"
|
||||
})
|
||||
}
|
||||
status={product.isAvailable ? "success" : "error"}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCellAvatar
|
||||
className={classes.colName}
|
||||
thumbnail={maybe(() => product.thumbnail.url)}
|
||||
>
|
||||
{product ? product.name : <Skeleton />}
|
||||
</TableCellAvatar>
|
||||
<TableCell className={classes.colType}>
|
||||
{product && product.productType ? (
|
||||
product.productType.name
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colPublished}>
|
||||
{product &&
|
||||
maybe(() => product.isAvailable !== undefined) ? (
|
||||
<StatusLabel
|
||||
label={
|
||||
product.isAvailable
|
||||
? intl.formatMessage({
|
||||
defaultMessage: "Published",
|
||||
description: "product",
|
||||
id: "productStatusLabel"
|
||||
})
|
||||
: intl.formatMessage({
|
||||
defaultMessage: "Not published",
|
||||
description: "product"
|
||||
})
|
||||
}
|
||||
status={product.isAvailable ? "success" : "error"}
|
||||
/>
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colPrice}>
|
||||
{maybe(() => product.basePrice) &&
|
||||
maybe(() => product.basePrice.amount) !== undefined &&
|
||||
maybe(() => product.basePrice.currency) !== undefined ? (
|
||||
<Money money={product.basePrice} />
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
},
|
||||
() => (
|
||||
<TableRow>
|
||||
<TableCell colSpan={numberOfColumns}>
|
||||
<FormattedMessage defaultMessage="No products found" />
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colPrice}>
|
||||
{maybe(() => product.basePrice) &&
|
||||
maybe(() => product.basePrice.amount) !== undefined &&
|
||||
maybe(() => product.basePrice.currency) !== undefined ? (
|
||||
<Money money={product.basePrice} />
|
||||
) : (
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
);
|
||||
},
|
||||
() => (
|
||||
<TableRow>
|
||||
<TableCell colSpan={numberOfColumns}>
|
||||
<FormattedMessage defaultMessage="No products found" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
CategoryProductList.displayName = "CategoryProductList";
|
||||
export default CategoryProductList;
|
||||
|
|
|
@ -369,10 +369,7 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
|
|||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {counter, plural,
|
||||
one {this attribute}
|
||||
other {{displayQuantity} categories}
|
||||
}?"
|
||||
defaultMessage="Are you sure you want to delete {counter,plural,one{this attribute} other{{displayQuantity} categories}}?"
|
||||
values={{
|
||||
counter: maybe(
|
||||
() => params.ids.length
|
||||
|
@ -409,10 +406,7 @@ export const CategoryDetails: React.FC<CategoryDetailsProps> = ({
|
|||
{" "}
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {counter, plural,
|
||||
one {this attribute}
|
||||
other {{displayQuantity} products}
|
||||
}?"
|
||||
defaultMessage="Are you sure you want to delete {counter,plural,one{this attribute} other{{displayQuantity} products}}?"
|
||||
values={{
|
||||
counter: maybe(
|
||||
() => params.ids.length
|
||||
|
|
|
@ -222,10 +222,7 @@ export const CategoryList: React.FC<CategoryListProps> = ({ params }) => {
|
|||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {counter, plural,
|
||||
one {this category}
|
||||
other {{displayQuantity} categories}
|
||||
}?"
|
||||
defaultMessage="Are you sure you want to delete {counter,plural,one{this category} other{{displayQuantity} categories}}?"
|
||||
values={{
|
||||
counter: maybe(() => params.ids.length),
|
||||
displayQuantity: (
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
@ -19,15 +14,15 @@ import Skeleton from "@saleor/components/Skeleton";
|
|||
import { commonMessages } from "@saleor/intl";
|
||||
import { CollectionDetails_collection_backgroundImage } from "../../types/CollectionDetails";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
PhotosIcon: {
|
||||
height: "64px",
|
||||
margin: "0 auto",
|
||||
width: "64px"
|
||||
},
|
||||
PhotosIconContainer: {
|
||||
margin: `${theme.spacing.unit * 5}px 0`,
|
||||
margin: theme.spacing(5, 0),
|
||||
textAlign: "center"
|
||||
},
|
||||
fileField: {
|
||||
|
@ -42,15 +37,19 @@ const styles = (theme: Theme) =>
|
|||
imageContainer: {
|
||||
background: "#ffffff",
|
||||
border: "1px solid #eaeaea",
|
||||
borderRadius: theme.spacing.unit,
|
||||
borderRadius: theme.spacing(),
|
||||
height: 148,
|
||||
justifySelf: "start",
|
||||
overflow: "hidden",
|
||||
padding: theme.spacing.unit * 2,
|
||||
padding: theme.spacing(2),
|
||||
position: "relative",
|
||||
width: 148
|
||||
}
|
||||
});
|
||||
}),
|
||||
{
|
||||
name: "CollectionImage"
|
||||
}
|
||||
);
|
||||
|
||||
export interface CollectionImageProps {
|
||||
data: {
|
||||
|
@ -62,83 +61,78 @@ export interface CollectionImageProps {
|
|||
onImageUpload: (file: File) => void;
|
||||
}
|
||||
|
||||
export const CollectionImage = withStyles(styles)(
|
||||
({
|
||||
classes,
|
||||
data,
|
||||
onImageUpload,
|
||||
image,
|
||||
onChange,
|
||||
onImageDelete
|
||||
}: CollectionImageProps & WithStyles<typeof styles>) => {
|
||||
const anchor = React.useRef<HTMLInputElement>();
|
||||
const intl = useIntl();
|
||||
export const CollectionImage: React.FC<CollectionImageProps> = props => {
|
||||
const { data, onImageUpload, image, onChange, onImageDelete } = props;
|
||||
|
||||
const handleImageUploadButtonClick = () => anchor.current.click();
|
||||
const anchor = React.useRef<HTMLInputElement>();
|
||||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Background Image (optional)",
|
||||
description: "section header"
|
||||
})}
|
||||
toolbar={
|
||||
<>
|
||||
<Button
|
||||
variant="text"
|
||||
color="primary"
|
||||
onClick={handleImageUploadButtonClick}
|
||||
>
|
||||
<FormattedMessage {...commonMessages.uploadImage} />
|
||||
</Button>
|
||||
<input
|
||||
className={classes.fileField}
|
||||
id="fileUpload"
|
||||
onChange={event => onImageUpload(event.target.files[0])}
|
||||
type="file"
|
||||
ref={anchor}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
{image === undefined ? (
|
||||
<CardContent>
|
||||
<div>
|
||||
<div className={classes.imageContainer}>
|
||||
<Skeleton />
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
) : image === null ? (
|
||||
<ImageUpload onImageUpload={onImageUpload} />
|
||||
) : (
|
||||
<CardContent>
|
||||
<ImageTile image={image} onImageDelete={onImageDelete} />
|
||||
</CardContent>
|
||||
)}
|
||||
{image && (
|
||||
const handleImageUploadButtonClick = () => anchor.current.click();
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Background Image (optional)",
|
||||
description: "section header"
|
||||
})}
|
||||
toolbar={
|
||||
<>
|
||||
<Hr />
|
||||
<CardContent>
|
||||
<TextField
|
||||
name="backgroundImageAlt"
|
||||
label={intl.formatMessage(commonMessages.description)}
|
||||
helperText={intl.formatMessage({
|
||||
defaultMessage: "(Optional)",
|
||||
description: "field is optional"
|
||||
})}
|
||||
value={data.backgroundImageAlt}
|
||||
onChange={onChange}
|
||||
fullWidth
|
||||
multiline
|
||||
/>
|
||||
</CardContent>
|
||||
<Button
|
||||
variant="text"
|
||||
color="primary"
|
||||
onClick={handleImageUploadButtonClick}
|
||||
>
|
||||
<FormattedMessage {...commonMessages.uploadImage} />
|
||||
</Button>
|
||||
<input
|
||||
className={classes.fileField}
|
||||
id="fileUpload"
|
||||
onChange={event => onImageUpload(event.target.files[0])}
|
||||
type="file"
|
||||
ref={anchor}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
/>
|
||||
{image === undefined ? (
|
||||
<CardContent>
|
||||
<div>
|
||||
<div className={classes.imageContainer}>
|
||||
<Skeleton />
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
) : image === null ? (
|
||||
<ImageUpload onImageUpload={onImageUpload} />
|
||||
) : (
|
||||
<CardContent>
|
||||
<ImageTile image={image} onImageDelete={onImageDelete} />
|
||||
</CardContent>
|
||||
)}
|
||||
{image && (
|
||||
<>
|
||||
<Hr />
|
||||
<CardContent>
|
||||
<TextField
|
||||
name="backgroundImageAlt"
|
||||
label={intl.formatMessage(commonMessages.description)}
|
||||
helperText={intl.formatMessage({
|
||||
defaultMessage: "(Optional)",
|
||||
description: "field is optional"
|
||||
})}
|
||||
value={data.backgroundImageAlt}
|
||||
onChange={onChange}
|
||||
fullWidth
|
||||
multiline
|
||||
/>
|
||||
</CardContent>
|
||||
</>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
CollectionImage.displayName = "CollectionImage";
|
||||
export default CollectionImage;
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Table from "@material-ui/core/Table";
|
||||
import TableBody from "@material-ui/core/TableBody";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
|
@ -21,8 +16,8 @@ import { maybe, renderCollection } from "@saleor/misc";
|
|||
import { ListActions, ListProps } from "@saleor/types";
|
||||
import { CollectionList_collections_edges_node } from "../../types/CollectionList";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
[theme.breakpoints.up("lg")]: {
|
||||
colAvailability: {
|
||||
width: 240
|
||||
|
@ -42,20 +37,18 @@ const styles = (theme: Theme) =>
|
|||
tableRow: {
|
||||
cursor: "pointer" as "pointer"
|
||||
}
|
||||
});
|
||||
}),
|
||||
{ name: "CollectionList" }
|
||||
);
|
||||
|
||||
interface CollectionListProps
|
||||
extends ListProps,
|
||||
ListActions,
|
||||
WithStyles<typeof styles> {
|
||||
interface CollectionListProps extends ListProps, ListActions {
|
||||
collections: CollectionList_collections_edges_node[];
|
||||
}
|
||||
|
||||
const numberOfColumns = 5;
|
||||
|
||||
const CollectionList = withStyles(styles, { name: "CollectionList" })(
|
||||
({
|
||||
classes,
|
||||
const CollectionList: React.FC<CollectionListProps> = props => {
|
||||
const {
|
||||
collections,
|
||||
disabled,
|
||||
settings,
|
||||
|
@ -69,122 +62,121 @@ const CollectionList = withStyles(styles, { name: "CollectionList" })(
|
|||
toggle,
|
||||
toggleAll,
|
||||
toolbar
|
||||
}: CollectionListProps) => {
|
||||
const intl = useIntl();
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Table>
|
||||
<TableHead
|
||||
colSpan={numberOfColumns}
|
||||
selected={selected}
|
||||
disabled={disabled}
|
||||
items={collections}
|
||||
toggleAll={toggleAll}
|
||||
toolbar={toolbar}
|
||||
>
|
||||
<TableCell className={classes.colName}>
|
||||
<FormattedMessage defaultMessage="Category Name" />
|
||||
</TableCell>
|
||||
<TableCell className={classes.colProducts}>
|
||||
<FormattedMessage defaultMessage="No. of Products" />
|
||||
</TableCell>
|
||||
<TableCell className={classes.colAvailability}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Availability"
|
||||
description="collection availability"
|
||||
/>
|
||||
</TableCell>
|
||||
</TableHead>
|
||||
<TableFooter>
|
||||
<TableRow>
|
||||
<TablePagination
|
||||
colSpan={numberOfColumns}
|
||||
settings={settings}
|
||||
hasNextPage={pageInfo && !disabled ? pageInfo.hasNextPage : false}
|
||||
onNextPage={onNextPage}
|
||||
onUpdateListSettings={onUpdateListSettings}
|
||||
hasPreviousPage={
|
||||
pageInfo && !disabled ? pageInfo.hasPreviousPage : false
|
||||
}
|
||||
onPreviousPage={onPreviousPage}
|
||||
/>
|
||||
</TableRow>
|
||||
</TableFooter>
|
||||
<TableBody>
|
||||
{renderCollection(
|
||||
collections,
|
||||
collection => {
|
||||
const isSelected = collection ? isChecked(collection.id) : false;
|
||||
return (
|
||||
<TableRow
|
||||
className={classes.tableRow}
|
||||
hover={!!collection}
|
||||
onClick={collection ? onRowClick(collection.id) : undefined}
|
||||
key={collection ? collection.id : "skeleton"}
|
||||
selected={isSelected}
|
||||
data-tc="id"
|
||||
data-tc-id={maybe(() => collection.id)}
|
||||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<Table>
|
||||
<TableHead
|
||||
colSpan={numberOfColumns}
|
||||
selected={selected}
|
||||
disabled={disabled}
|
||||
items={collections}
|
||||
toggleAll={toggleAll}
|
||||
toolbar={toolbar}
|
||||
>
|
||||
<TableCell className={classes.colName}>
|
||||
<FormattedMessage defaultMessage="Category Name" />
|
||||
</TableCell>
|
||||
<TableCell className={classes.colProducts}>
|
||||
<FormattedMessage defaultMessage="No. of Products" />
|
||||
</TableCell>
|
||||
<TableCell className={classes.colAvailability}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Availability"
|
||||
description="collection availability"
|
||||
/>
|
||||
</TableCell>
|
||||
</TableHead>
|
||||
<TableFooter>
|
||||
<TableRow>
|
||||
<TablePagination
|
||||
colSpan={numberOfColumns}
|
||||
settings={settings}
|
||||
hasNextPage={pageInfo && !disabled ? pageInfo.hasNextPage : false}
|
||||
onNextPage={onNextPage}
|
||||
onUpdateListSettings={onUpdateListSettings}
|
||||
hasPreviousPage={
|
||||
pageInfo && !disabled ? pageInfo.hasPreviousPage : false
|
||||
}
|
||||
onPreviousPage={onPreviousPage}
|
||||
/>
|
||||
</TableRow>
|
||||
</TableFooter>
|
||||
<TableBody>
|
||||
{renderCollection(
|
||||
collections,
|
||||
collection => {
|
||||
const isSelected = collection ? isChecked(collection.id) : false;
|
||||
return (
|
||||
<TableRow
|
||||
className={classes.tableRow}
|
||||
hover={!!collection}
|
||||
onClick={collection ? onRowClick(collection.id) : undefined}
|
||||
key={collection ? collection.id : "skeleton"}
|
||||
selected={isSelected}
|
||||
data-tc="id"
|
||||
data-tc-id={maybe(() => collection.id)}
|
||||
>
|
||||
<TableCell padding="checkbox">
|
||||
<Checkbox
|
||||
checked={isSelected}
|
||||
disabled={disabled}
|
||||
disableClickPropagation
|
||||
onChange={() => toggle(collection.id)}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colName} data-tc="name">
|
||||
{maybe<React.ReactNode>(() => collection.name, <Skeleton />)}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colProducts}>
|
||||
{maybe<React.ReactNode>(
|
||||
() => collection.products.totalCount,
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className={classes.colAvailability}
|
||||
data-tc="published"
|
||||
data-tc-published={maybe(() => collection.isPublished)}
|
||||
>
|
||||
<TableCell padding="checkbox">
|
||||
<Checkbox
|
||||
checked={isSelected}
|
||||
disabled={disabled}
|
||||
disableClickPropagation
|
||||
onChange={() => toggle(collection.id)}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colName} data-tc="name">
|
||||
{maybe<React.ReactNode>(
|
||||
() => collection.name,
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colProducts}>
|
||||
{maybe<React.ReactNode>(
|
||||
() => collection.products.totalCount,
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className={classes.colAvailability}
|
||||
data-tc="published"
|
||||
data-tc-published={maybe(() => collection.isPublished)}
|
||||
>
|
||||
{maybe(
|
||||
() => (
|
||||
<StatusLabel
|
||||
status={collection.isPublished ? "success" : "error"}
|
||||
label={
|
||||
collection.isPublished
|
||||
? intl.formatMessage({
|
||||
defaultMessage: "Published",
|
||||
description: "collection is published"
|
||||
})
|
||||
: intl.formatMessage({
|
||||
defaultMessage: "Not published",
|
||||
description: "collection is not published"
|
||||
})
|
||||
}
|
||||
/>
|
||||
),
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
},
|
||||
() => (
|
||||
<TableRow>
|
||||
<TableCell colSpan={numberOfColumns}>
|
||||
<FormattedMessage defaultMessage="No collections found" />
|
||||
{maybe(
|
||||
() => (
|
||||
<StatusLabel
|
||||
status={collection.isPublished ? "success" : "error"}
|
||||
label={
|
||||
collection.isPublished
|
||||
? intl.formatMessage({
|
||||
defaultMessage: "Published",
|
||||
description: "collection is published"
|
||||
})
|
||||
: intl.formatMessage({
|
||||
defaultMessage: "Not published",
|
||||
description: "collection is not published"
|
||||
})
|
||||
}
|
||||
/>
|
||||
),
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
);
|
||||
);
|
||||
},
|
||||
() => (
|
||||
<TableRow>
|
||||
<TableCell colSpan={numberOfColumns}>
|
||||
<FormattedMessage defaultMessage="No collections found" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
);
|
||||
};
|
||||
|
||||
CollectionList.displayName = "CollectionList";
|
||||
export default CollectionList;
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import Button from "@material-ui/core/Button";
|
||||
import Card from "@material-ui/core/Card";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Table from "@material-ui/core/Table";
|
||||
import TableBody from "@material-ui/core/TableBody";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
|
@ -29,13 +24,13 @@ import { maybe, renderCollection } from "../../../misc";
|
|||
import { ListActions, PageListProps } from "../../../types";
|
||||
import { CollectionDetails_collection } from "../../types/CollectionDetails";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
colActions: {
|
||||
"&:last-child": {
|
||||
paddingRight: 0
|
||||
},
|
||||
width: 76 + theme.spacing.unit / 2
|
||||
width: 76 + theme.spacing(0.5)
|
||||
},
|
||||
colName: {
|
||||
paddingLeft: 0,
|
||||
|
@ -56,21 +51,19 @@ const styles = (theme: Theme) =>
|
|||
tableRow: {
|
||||
cursor: "pointer"
|
||||
}
|
||||
});
|
||||
}),
|
||||
{ name: "CollectionProducts" }
|
||||
);
|
||||
|
||||
export interface CollectionProductsProps
|
||||
extends PageListProps,
|
||||
ListActions,
|
||||
WithStyles<typeof styles> {
|
||||
export interface CollectionProductsProps extends PageListProps, ListActions {
|
||||
collection: CollectionDetails_collection;
|
||||
onProductUnassign: (id: string, event: React.MouseEvent<any>) => void;
|
||||
}
|
||||
|
||||
const numberOfColumns = 5;
|
||||
|
||||
const CollectionProducts = withStyles(styles, { name: "CollectionProducts" })(
|
||||
({
|
||||
classes,
|
||||
const CollectionProducts: React.FC<CollectionProductsProps> = props => {
|
||||
const {
|
||||
collection,
|
||||
disabled,
|
||||
onAdd,
|
||||
|
@ -84,165 +77,165 @@ const CollectionProducts = withStyles(styles, { name: "CollectionProducts" })(
|
|||
toggle,
|
||||
toggleAll,
|
||||
toolbar
|
||||
}: CollectionProductsProps) => {
|
||||
const intl = useIntl();
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={
|
||||
!!collection ? (
|
||||
intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "Products in {name}",
|
||||
description: "products in collection"
|
||||
},
|
||||
{
|
||||
name: maybe(() => collection.name, "...")
|
||||
}
|
||||
)
|
||||
) : (
|
||||
<Skeleton />
|
||||
)
|
||||
}
|
||||
toolbar={
|
||||
<Button
|
||||
disabled={disabled}
|
||||
variant="text"
|
||||
color="primary"
|
||||
onClick={onAdd}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign product"
|
||||
description="button"
|
||||
/>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<Table className={classes.table}>
|
||||
<TableHead
|
||||
colSpan={numberOfColumns}
|
||||
selected={selected}
|
||||
disabled={disabled}
|
||||
items={maybe(() =>
|
||||
collection.products.edges.map(edge => edge.node)
|
||||
)}
|
||||
toggleAll={toggleAll}
|
||||
toolbar={toolbar}
|
||||
>
|
||||
<TableCell className={classes.colName}>
|
||||
<span className={classes.colNameLabel}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Name"
|
||||
description="product name"
|
||||
/>
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colType}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Type"
|
||||
description="product type"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colPublished}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Published"
|
||||
description="product is published"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colActions} />
|
||||
</TableHead>
|
||||
<TableFooter>
|
||||
<TableRow>
|
||||
<TablePagination
|
||||
colSpan={numberOfColumns}
|
||||
hasNextPage={maybe(() => pageInfo.hasNextPage)}
|
||||
onNextPage={onNextPage}
|
||||
hasPreviousPage={maybe(() => pageInfo.hasPreviousPage)}
|
||||
onPreviousPage={onPreviousPage}
|
||||
/>
|
||||
</TableRow>
|
||||
</TableFooter>
|
||||
<TableBody>
|
||||
{renderCollection(
|
||||
maybe(() => collection.products.edges.map(edge => edge.node)),
|
||||
product => {
|
||||
const isSelected = product ? isChecked(product.id) : false;
|
||||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
className={classes.tableRow}
|
||||
hover={!!product}
|
||||
onClick={!!product ? onRowClick(product.id) : undefined}
|
||||
key={product ? product.id : "skeleton"}
|
||||
selected={isSelected}
|
||||
>
|
||||
<TableCell padding="checkbox">
|
||||
<Checkbox
|
||||
checked={isSelected}
|
||||
disabled={disabled}
|
||||
disableClickPropagation
|
||||
onChange={() => toggle(product.id)}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCellAvatar
|
||||
className={classes.colName}
|
||||
thumbnail={maybe(() => product.thumbnail.url)}
|
||||
>
|
||||
{maybe<React.ReactNode>(() => product.name, <Skeleton />)}
|
||||
</TableCellAvatar>
|
||||
<TableCell className={classes.colType}>
|
||||
{maybe<React.ReactNode>(
|
||||
() => product.productType.name,
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colPublished}>
|
||||
{maybe(
|
||||
() => (
|
||||
<StatusLabel
|
||||
label={
|
||||
product.isPublished
|
||||
? intl.formatMessage({
|
||||
defaultMessage: "Published",
|
||||
description: "product is published"
|
||||
})
|
||||
: intl.formatMessage({
|
||||
defaultMessage: "Not published",
|
||||
description: "product is not published"
|
||||
})
|
||||
}
|
||||
status={product.isPublished ? "success" : "error"}
|
||||
/>
|
||||
),
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colActions}>
|
||||
<IconButton
|
||||
disabled={!product}
|
||||
onClick={event => onProductUnassign(product.id, event)}
|
||||
>
|
||||
<DeleteIcon color="primary" />
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={
|
||||
!!collection ? (
|
||||
intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "Products in {name}",
|
||||
description: "products in collection"
|
||||
},
|
||||
() => (
|
||||
<TableRow>
|
||||
<TableCell />
|
||||
<TableCell colSpan={numberOfColumns}>
|
||||
<FormattedMessage defaultMessage="No products found" />
|
||||
{
|
||||
name: maybe(() => collection.name, "...")
|
||||
}
|
||||
)
|
||||
) : (
|
||||
<Skeleton />
|
||||
)
|
||||
}
|
||||
toolbar={
|
||||
<Button
|
||||
disabled={disabled}
|
||||
variant="text"
|
||||
color="primary"
|
||||
onClick={onAdd}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign product"
|
||||
description="button"
|
||||
/>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<Table className={classes.table}>
|
||||
<TableHead
|
||||
colSpan={numberOfColumns}
|
||||
selected={selected}
|
||||
disabled={disabled}
|
||||
items={maybe(() => collection.products.edges.map(edge => edge.node))}
|
||||
toggleAll={toggleAll}
|
||||
toolbar={toolbar}
|
||||
>
|
||||
<TableCell className={classes.colName}>
|
||||
<span className={classes.colNameLabel}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Name"
|
||||
description="product name"
|
||||
/>
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colType}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Type"
|
||||
description="product type"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colPublished}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Published"
|
||||
description="product is published"
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.colActions} />
|
||||
</TableHead>
|
||||
<TableFooter>
|
||||
<TableRow>
|
||||
<TablePagination
|
||||
colSpan={numberOfColumns}
|
||||
hasNextPage={maybe(() => pageInfo.hasNextPage)}
|
||||
onNextPage={onNextPage}
|
||||
hasPreviousPage={maybe(() => pageInfo.hasPreviousPage)}
|
||||
onPreviousPage={onPreviousPage}
|
||||
/>
|
||||
</TableRow>
|
||||
</TableFooter>
|
||||
<TableBody>
|
||||
{renderCollection(
|
||||
maybe(() => collection.products.edges.map(edge => edge.node)),
|
||||
product => {
|
||||
const isSelected = product ? isChecked(product.id) : false;
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
className={classes.tableRow}
|
||||
hover={!!product}
|
||||
onClick={!!product ? onRowClick(product.id) : undefined}
|
||||
key={product ? product.id : "skeleton"}
|
||||
selected={isSelected}
|
||||
>
|
||||
<TableCell padding="checkbox">
|
||||
<Checkbox
|
||||
checked={isSelected}
|
||||
disabled={disabled}
|
||||
disableClickPropagation
|
||||
onChange={() => toggle(product.id)}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCellAvatar
|
||||
className={classes.colName}
|
||||
thumbnail={maybe(() => product.thumbnail.url)}
|
||||
>
|
||||
{maybe<React.ReactNode>(() => product.name, <Skeleton />)}
|
||||
</TableCellAvatar>
|
||||
<TableCell className={classes.colType}>
|
||||
{maybe<React.ReactNode>(
|
||||
() => product.productType.name,
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colPublished}>
|
||||
{maybe(
|
||||
() => (
|
||||
<StatusLabel
|
||||
label={
|
||||
product.isPublished
|
||||
? intl.formatMessage({
|
||||
defaultMessage: "Published",
|
||||
description: "product is published"
|
||||
})
|
||||
: intl.formatMessage({
|
||||
defaultMessage: "Not published",
|
||||
description: "product is not published"
|
||||
})
|
||||
}
|
||||
status={product.isPublished ? "success" : "error"}
|
||||
/>
|
||||
),
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className={classes.colActions}>
|
||||
<IconButton
|
||||
disabled={!product}
|
||||
onClick={event => onProductUnassign(product.id, event)}
|
||||
>
|
||||
<DeleteIcon color="primary" />
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
);
|
||||
);
|
||||
},
|
||||
() => (
|
||||
<TableRow>
|
||||
<TableCell />
|
||||
<TableCell colSpan={numberOfColumns}>
|
||||
<FormattedMessage defaultMessage="No products found" />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
CollectionProducts.displayName = "CollectionProducts";
|
||||
export default CollectionProducts;
|
||||
|
|
|
@ -231,7 +231,7 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
|||
onAdd={() => openModal("assign")}
|
||||
onBack={() => navigate(collectionListUrl())}
|
||||
disabled={loading}
|
||||
collection={data.collection}
|
||||
collection={maybe(() => data.collection)}
|
||||
isFeatured={maybe(
|
||||
() =>
|
||||
data.shop.homepageCollection.id === data.collection.id,
|
||||
|
@ -349,10 +349,7 @@ export const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
|||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to unassign {counter, plural,
|
||||
one {this product}
|
||||
other {{displayQuantity} products}
|
||||
}?"
|
||||
defaultMessage="Are you sure you want to unassign {counter,plural,one{this product} other{{displayQuantity} products}}?"
|
||||
values={{
|
||||
counter: maybe(() => params.ids.length),
|
||||
displayQuantity: (
|
||||
|
|
|
@ -268,10 +268,7 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
|
|||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to publish {counter, plural,
|
||||
one {this collection}
|
||||
other {{displayQuantity} collections}
|
||||
}?"
|
||||
defaultMessage="Are you sure you want to publish {counter,plural,one{this collection} other{{displayQuantity} collections}}?"
|
||||
values={{
|
||||
counter: maybe(() => params.ids.length),
|
||||
displayQuantity: (
|
||||
|
@ -306,10 +303,7 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
|
|||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to unpublish {counter, plural,
|
||||
one {this collection}
|
||||
other {{displayQuantity} collections}
|
||||
}?"
|
||||
defaultMessage="Are you sure you want to unpublish {counter,plural,one{this collection} other{{displayQuantity} collections}}?"
|
||||
values={{
|
||||
counter: maybe(() => params.ids.length),
|
||||
displayQuantity: (
|
||||
|
@ -343,10 +337,7 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
|
|||
>
|
||||
<DialogContentText>
|
||||
<FormattedMessage
|
||||
defaultMessage="Are you sure you want to delete {counter, plural,
|
||||
one {this collection}
|
||||
other {{displayQuantity} collections}
|
||||
}?"
|
||||
defaultMessage="Are you sure you want to delete {counter,plural,one{this collection} other{{displayQuantity} collections}}?"
|
||||
values={{
|
||||
counter: maybe(() => params.ids.length),
|
||||
displayQuantity: (
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
import Card from "@material-ui/core/Card";
|
||||
import CardContent from "@material-ui/core/CardContent";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
@ -15,21 +10,23 @@ import { ControlledCheckbox } from "@saleor/components/ControlledCheckbox";
|
|||
import { ShopInfo_shop_permissions } from "@saleor/components/Shop/types/ShopInfo";
|
||||
import Skeleton from "@saleor/components/Skeleton";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
checkboxContainer: {
|
||||
marginTop: theme.spacing.unit
|
||||
marginTop: theme.spacing()
|
||||
},
|
||||
hr: {
|
||||
backgroundColor: theme.overrides.MuiCard.root.borderColor,
|
||||
backgroundColor: theme.palette.divider,
|
||||
border: "none",
|
||||
height: 1,
|
||||
marginBottom: 0,
|
||||
marginTop: 0
|
||||
}
|
||||
});
|
||||
}),
|
||||
{ name: "AccountPermissions" }
|
||||
);
|
||||
|
||||
interface AccountPermissionsProps extends WithStyles<typeof styles> {
|
||||
interface AccountPermissionsProps {
|
||||
permissions: ShopInfo_shop_permissions[];
|
||||
data: {
|
||||
hasFullAccess: boolean;
|
||||
|
@ -39,89 +36,85 @@ interface AccountPermissionsProps extends WithStyles<typeof styles> {
|
|||
onChange: (event: React.ChangeEvent<any>, cb?: () => void) => void;
|
||||
}
|
||||
|
||||
const AccountPermissions = withStyles(styles, { name: "AccountPermissions" })(
|
||||
({
|
||||
classes,
|
||||
data,
|
||||
disabled,
|
||||
permissions,
|
||||
onChange
|
||||
}: AccountPermissionsProps) => {
|
||||
const intl = useIntl();
|
||||
const AccountPermissions: React.FC<AccountPermissionsProps> = props => {
|
||||
const { data, disabled, permissions, onChange } = props;
|
||||
|
||||
const handleFullAccessChange = (event: React.ChangeEvent<any>) =>
|
||||
onChange(event, () =>
|
||||
onChange({
|
||||
target: {
|
||||
name: "permissions",
|
||||
value: event.target.value ? permissions.map(perm => perm.code) : []
|
||||
}
|
||||
} as any)
|
||||
);
|
||||
const handlePermissionChange = (event: React.ChangeEvent<any>) => {
|
||||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
|
||||
const handleFullAccessChange = (event: React.ChangeEvent<any>) =>
|
||||
onChange(event, () =>
|
||||
onChange({
|
||||
target: {
|
||||
name: "permissions",
|
||||
value: event.target.value
|
||||
? data.permissions.concat([event.target.name])
|
||||
: data.permissions.filter(perm => perm !== event.target.name)
|
||||
value: event.target.value ? permissions.map(perm => perm.code) : []
|
||||
}
|
||||
} as any);
|
||||
};
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Permissions",
|
||||
description: "dialog header"
|
||||
})}
|
||||
/>
|
||||
<CardContent>
|
||||
<Typography>
|
||||
<FormattedMessage defaultMessage="Expand or restrict user's permissions to access certain part of saleor system." />
|
||||
</Typography>
|
||||
<div className={classes.checkboxContainer}>
|
||||
<ControlledCheckbox
|
||||
checked={data.hasFullAccess}
|
||||
disabled={disabled}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "User has full access to the store",
|
||||
description: "checkbox label"
|
||||
})}
|
||||
name="hasFullAccess"
|
||||
onChange={handleFullAccessChange}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
{!data.hasFullAccess && (
|
||||
<>
|
||||
<hr className={classes.hr} />
|
||||
<CardContent>
|
||||
{permissions === undefined ? (
|
||||
<Skeleton />
|
||||
) : (
|
||||
permissions.map(perm => (
|
||||
<div key={perm.code}>
|
||||
<ControlledCheckbox
|
||||
checked={
|
||||
data.permissions.filter(
|
||||
userPerm => userPerm === perm.code
|
||||
).length === 1
|
||||
}
|
||||
disabled={disabled}
|
||||
label={perm.name.replace(/\./, "")}
|
||||
name={perm.code}
|
||||
onChange={handlePermissionChange}
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</CardContent>
|
||||
</>
|
||||
)}
|
||||
</Card>
|
||||
} as any)
|
||||
);
|
||||
}
|
||||
);
|
||||
const handlePermissionChange = (event: React.ChangeEvent<any>) => {
|
||||
onChange({
|
||||
target: {
|
||||
name: "permissions",
|
||||
value: event.target.value
|
||||
? data.permissions.concat([event.target.name])
|
||||
: data.permissions.filter(perm => perm !== event.target.name)
|
||||
}
|
||||
} as any);
|
||||
};
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={intl.formatMessage({
|
||||
defaultMessage: "Permissions",
|
||||
description: "dialog header"
|
||||
})}
|
||||
/>
|
||||
<CardContent>
|
||||
<Typography>
|
||||
<FormattedMessage defaultMessage="Expand or restrict user's permissions to access certain part of saleor system." />
|
||||
</Typography>
|
||||
<div className={classes.checkboxContainer}>
|
||||
<ControlledCheckbox
|
||||
checked={data.hasFullAccess}
|
||||
disabled={disabled}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "User has full access to the store",
|
||||
description: "checkbox label"
|
||||
})}
|
||||
name="hasFullAccess"
|
||||
onChange={handleFullAccessChange}
|
||||
/>
|
||||
</div>
|
||||
</CardContent>
|
||||
{!data.hasFullAccess && (
|
||||
<>
|
||||
<hr className={classes.hr} />
|
||||
<CardContent>
|
||||
{permissions === undefined ? (
|
||||
<Skeleton />
|
||||
) : (
|
||||
permissions.map(perm => (
|
||||
<div key={perm.code}>
|
||||
<ControlledCheckbox
|
||||
checked={
|
||||
data.permissions.filter(
|
||||
userPerm => userPerm === perm.code
|
||||
).length === 1
|
||||
}
|
||||
disabled={disabled}
|
||||
label={perm.name.replace(/\./, "")}
|
||||
name={perm.code}
|
||||
onChange={handlePermissionChange}
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</CardContent>
|
||||
</>
|
||||
)}
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
AccountPermissions.displayName = "AccountPermissions";
|
||||
export default AccountPermissions;
|
||||
|
|
|
@ -3,12 +3,7 @@ import Dialog from "@material-ui/core/Dialog";
|
|||
import DialogActions from "@material-ui/core/DialogActions";
|
||||
import DialogContent from "@material-ui/core/DialogContent";
|
||||
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
@ -18,8 +13,8 @@ import ConfirmButton, {
|
|||
ConfirmButtonTransitionState
|
||||
} from "../ConfirmButton/ConfirmButton";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
deleteButton: {
|
||||
"&:hover": {
|
||||
backgroundColor: theme.palette.error.main
|
||||
|
@ -27,12 +22,15 @@ const styles = (theme: Theme) =>
|
|||
backgroundColor: theme.palette.error.main,
|
||||
color: theme.palette.error.contrastText
|
||||
}
|
||||
});
|
||||
}),
|
||||
{ name: "ActionDialog" }
|
||||
);
|
||||
|
||||
interface ActionDialogProps extends WithStyles<typeof styles> {
|
||||
interface ActionDialogProps {
|
||||
children?: React.ReactNode;
|
||||
confirmButtonLabel?: string;
|
||||
confirmButtonState: ConfirmButtonTransitionState;
|
||||
maxWidth?: "xs" | "sm" | "md" | "lg" | "xl" | false;
|
||||
open: boolean;
|
||||
title: string;
|
||||
variant?: "default" | "delete";
|
||||
|
@ -40,46 +38,52 @@ interface ActionDialogProps extends WithStyles<typeof styles> {
|
|||
onConfirm();
|
||||
}
|
||||
|
||||
const ActionDialog = withStyles(styles, { name: "ActionDialog" })(
|
||||
({
|
||||
const ActionDialog: React.FC<ActionDialogProps> = props => {
|
||||
const {
|
||||
children,
|
||||
classes,
|
||||
confirmButtonLabel,
|
||||
confirmButtonState,
|
||||
open,
|
||||
title,
|
||||
variant,
|
||||
onConfirm,
|
||||
onClose
|
||||
}: ActionDialogProps) => {
|
||||
const intl = useIntl();
|
||||
onClose,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<Dialog onClose={onClose} open={open}>
|
||||
<DialogTitle>{title}</DialogTitle>
|
||||
<DialogContent>{children}</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose}>
|
||||
<FormattedMessage {...buttonMessages.back} />
|
||||
</Button>
|
||||
<ConfirmButton
|
||||
transitionState={confirmButtonState}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
onClick={onConfirm}
|
||||
className={classNames({
|
||||
[classes.deleteButton]: variant === "delete"
|
||||
})}
|
||||
>
|
||||
{confirmButtonLabel ||
|
||||
(variant === "delete"
|
||||
? intl.formatMessage(buttonMessages.delete)
|
||||
: intl.formatMessage(buttonMessages.confirm))}
|
||||
</ConfirmButton>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
);
|
||||
const classes = useStyles(props);
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<Dialog fullWidth onClose={onClose} open={open} {...rest}>
|
||||
<DialogTitle>{title}</DialogTitle>
|
||||
<DialogContent>{children}</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose}>
|
||||
<FormattedMessage {...buttonMessages.back} />
|
||||
</Button>
|
||||
<ConfirmButton
|
||||
transitionState={confirmButtonState}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
onClick={onConfirm}
|
||||
className={classNames({
|
||||
[classes.deleteButton]: variant === "delete"
|
||||
})}
|
||||
>
|
||||
{confirmButtonLabel ||
|
||||
(variant === "delete"
|
||||
? intl.formatMessage(buttonMessages.delete)
|
||||
: intl.formatMessage(buttonMessages.confirm))}
|
||||
</ConfirmButton>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
ActionDialog.defaultProps = {
|
||||
maxWidth: "xs",
|
||||
variant: "default"
|
||||
};
|
||||
ActionDialog.displayName = "ActionDialog";
|
||||
export default ActionDialog;
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
|
@ -16,16 +11,15 @@ import SingleAutocompleteSelectField, {
|
|||
SingleAutocompleteChoiceType
|
||||
} from "../SingleAutocompleteSelectField";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
display: "grid",
|
||||
gridColumnGap: `${theme.spacing.unit * 2}px`,
|
||||
gridTemplateColumns: "1fr 1fr"
|
||||
}
|
||||
});
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {
|
||||
display: "grid",
|
||||
gridColumnGap: theme.spacing(2),
|
||||
gridTemplateColumns: "1fr 1fr"
|
||||
}
|
||||
}));
|
||||
|
||||
interface AddressEditProps extends WithStyles<typeof styles> {
|
||||
interface AddressEditProps {
|
||||
countries: SingleAutocompleteChoiceType[];
|
||||
countryDisplayValue: string;
|
||||
data: AddressTypeInput;
|
||||
|
@ -35,9 +29,8 @@ interface AddressEditProps extends WithStyles<typeof styles> {
|
|||
onCountryChange(event: React.ChangeEvent<any>);
|
||||
}
|
||||
|
||||
const AddressEdit = withStyles(styles, { name: "AddressEdit" })(
|
||||
({
|
||||
classes,
|
||||
const AddressEdit: React.FC<AddressEditProps> = props => {
|
||||
const {
|
||||
countries,
|
||||
countryDisplayValue,
|
||||
data,
|
||||
|
@ -45,164 +38,165 @@ const AddressEdit = withStyles(styles, { name: "AddressEdit" })(
|
|||
errors,
|
||||
onChange,
|
||||
onCountryChange
|
||||
}: AddressEditProps) => {
|
||||
const intl = useIntl();
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={classes.root}>
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.firstName}
|
||||
helperText={errors.firstName}
|
||||
label={intl.formatMessage(commonMessages.firstName)}
|
||||
name="firstName"
|
||||
onChange={onChange}
|
||||
value={data.firstName}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.lastName}
|
||||
helperText={errors.lastName}
|
||||
label={intl.formatMessage(commonMessages.lastName)}
|
||||
name="lastName"
|
||||
onChange={onChange}
|
||||
value={data.lastName}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<FormSpacer />
|
||||
<div className={classes.root}>
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.companyName}
|
||||
helperText={errors.companyName}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Company"
|
||||
})}
|
||||
name="companyName"
|
||||
onChange={onChange}
|
||||
value={data.companyName}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.phone}
|
||||
fullWidth
|
||||
helperText={errors.phone}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Phone"
|
||||
})}
|
||||
name="phone"
|
||||
value={data.phone}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<FormSpacer />
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.streetAddress1}
|
||||
helperText={errors.streetAddress1}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Address line 1"
|
||||
})}
|
||||
name="streetAddress1"
|
||||
onChange={onChange}
|
||||
value={data.streetAddress1}
|
||||
fullWidth
|
||||
/>
|
||||
<FormSpacer />
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.streetAddress2}
|
||||
helperText={errors.streetAddress2}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Address line 2"
|
||||
})}
|
||||
name="streetAddress2"
|
||||
onChange={onChange}
|
||||
value={data.streetAddress2}
|
||||
fullWidth
|
||||
/>
|
||||
<FormSpacer />
|
||||
<div className={classes.root}>
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.city}
|
||||
helperText={errors.city}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "City"
|
||||
})}
|
||||
name="city"
|
||||
onChange={onChange}
|
||||
value={data.city}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.postalCode}
|
||||
helperText={errors.postalCode}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "ZIP / Postal code"
|
||||
})}
|
||||
name="postalCode"
|
||||
onChange={onChange}
|
||||
value={data.postalCode}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
const intl = useIntl();
|
||||
|
||||
<FormSpacer />
|
||||
<div className={classes.root}>
|
||||
<div>
|
||||
<SingleAutocompleteSelectField
|
||||
disabled={disabled}
|
||||
displayValue={countryDisplayValue}
|
||||
error={!!errors.country}
|
||||
helperText={errors.country}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Country"
|
||||
})}
|
||||
name="country"
|
||||
onChange={onCountryChange}
|
||||
value={data.country}
|
||||
choices={countries}
|
||||
InputProps={{
|
||||
autoComplete: "off"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.countryArea}
|
||||
helperText={errors.countryArea}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Country area"
|
||||
})}
|
||||
name="countryArea"
|
||||
onChange={onChange}
|
||||
value={data.countryArea}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
return (
|
||||
<>
|
||||
<div className={classes.root}>
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.firstName}
|
||||
helperText={errors.firstName}
|
||||
label={intl.formatMessage(commonMessages.firstName)}
|
||||
name="firstName"
|
||||
onChange={onChange}
|
||||
value={data.firstName}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
);
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.lastName}
|
||||
helperText={errors.lastName}
|
||||
label={intl.formatMessage(commonMessages.lastName)}
|
||||
name="lastName"
|
||||
onChange={onChange}
|
||||
value={data.lastName}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<FormSpacer />
|
||||
<div className={classes.root}>
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.companyName}
|
||||
helperText={errors.companyName}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Company"
|
||||
})}
|
||||
name="companyName"
|
||||
onChange={onChange}
|
||||
value={data.companyName}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.phone}
|
||||
fullWidth
|
||||
helperText={errors.phone}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Phone"
|
||||
})}
|
||||
name="phone"
|
||||
value={data.phone}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<FormSpacer />
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.streetAddress1}
|
||||
helperText={errors.streetAddress1}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Address line 1"
|
||||
})}
|
||||
name="streetAddress1"
|
||||
onChange={onChange}
|
||||
value={data.streetAddress1}
|
||||
fullWidth
|
||||
/>
|
||||
<FormSpacer />
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.streetAddress2}
|
||||
helperText={errors.streetAddress2}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Address line 2"
|
||||
})}
|
||||
name="streetAddress2"
|
||||
onChange={onChange}
|
||||
value={data.streetAddress2}
|
||||
fullWidth
|
||||
/>
|
||||
<FormSpacer />
|
||||
<div className={classes.root}>
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.city}
|
||||
helperText={errors.city}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "City"
|
||||
})}
|
||||
name="city"
|
||||
onChange={onChange}
|
||||
value={data.city}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.postalCode}
|
||||
helperText={errors.postalCode}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "ZIP / Postal code"
|
||||
})}
|
||||
name="postalCode"
|
||||
onChange={onChange}
|
||||
value={data.postalCode}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FormSpacer />
|
||||
<div className={classes.root}>
|
||||
<div>
|
||||
<SingleAutocompleteSelectField
|
||||
disabled={disabled}
|
||||
displayValue={countryDisplayValue}
|
||||
error={!!errors.country}
|
||||
helperText={errors.country}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Country"
|
||||
})}
|
||||
name="country"
|
||||
onChange={onCountryChange}
|
||||
value={data.country}
|
||||
choices={countries}
|
||||
InputProps={{
|
||||
autoComplete: "off"
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<TextField
|
||||
disabled={disabled}
|
||||
error={!!errors.countryArea}
|
||||
helperText={errors.countryArea}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Country area"
|
||||
})}
|
||||
name="countryArea"
|
||||
onChange={onChange}
|
||||
value={data.countryArea}
|
||||
fullWidth
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
AddressEdit.displayName = "AddressEdit";
|
||||
export default AddressEdit;
|
||||
|
|
|
@ -18,23 +18,23 @@ const AddressFormatter: React.FC<AddressFormatterProps> = ({ address }) => {
|
|||
fontStyle: "inherit"
|
||||
}}
|
||||
>
|
||||
<Typography component="span">
|
||||
<Typography component="p">
|
||||
{address.firstName} {address.lastName}
|
||||
</Typography>
|
||||
{address.companyName && (
|
||||
<Typography component="span">{address.companyName}</Typography>
|
||||
<Typography component="p">{address.companyName}</Typography>
|
||||
)}
|
||||
<Typography component="span">
|
||||
<Typography component="p">
|
||||
{address.streetAddress1}
|
||||
<br />
|
||||
{address.streetAddress2}
|
||||
</Typography>
|
||||
<Typography component="span">
|
||||
<Typography component="p">
|
||||
{" "}
|
||||
{address.postalCode} {address.city}
|
||||
{address.cityArea ? ", " + address.cityArea : ""}
|
||||
</Typography>
|
||||
<Typography component="span">
|
||||
<Typography component="p">
|
||||
{address.countryArea
|
||||
? address.countryArea + ", " + address.country.country
|
||||
: address.country.country}
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
import Portal from "@material-ui/core/Portal";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import ArrowBackIcon from "@material-ui/icons/ArrowBack";
|
||||
import React from "react";
|
||||
|
@ -16,45 +11,44 @@ export interface AppHeaderProps {
|
|||
onBack();
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
backArrow: {
|
||||
fontSize: 30
|
||||
const useStyles = makeStyles(theme => ({
|
||||
backArrow: {
|
||||
fontSize: 30
|
||||
},
|
||||
menuButton: {
|
||||
flex: "0 0 auto",
|
||||
marginLeft: -theme.spacing(2),
|
||||
marginRight: theme.spacing(),
|
||||
marginTop: -theme.spacing(2)
|
||||
},
|
||||
root: {
|
||||
"&:hover": {
|
||||
color: theme.typography.body1.color
|
||||
},
|
||||
menuButton: {
|
||||
flex: "0 0 auto",
|
||||
marginLeft: theme.spacing.unit * -2,
|
||||
marginRight: theme.spacing.unit,
|
||||
marginTop: -theme.spacing.unit * 2
|
||||
},
|
||||
root: {
|
||||
"&:hover": {
|
||||
color: theme.typography.body2.color
|
||||
},
|
||||
alignItems: "center",
|
||||
color: theme.palette.grey[500],
|
||||
cursor: "pointer",
|
||||
display: "flex",
|
||||
marginTop: theme.spacing.unit / 2,
|
||||
transition: theme.transitions.duration.standard + "ms"
|
||||
},
|
||||
skeleton: {
|
||||
marginBottom: theme.spacing.unit * 2,
|
||||
width: "10rem"
|
||||
},
|
||||
title: {
|
||||
color: "inherit",
|
||||
flex: 1,
|
||||
marginLeft: theme.spacing.unit,
|
||||
textTransform: "uppercase"
|
||||
}
|
||||
});
|
||||
const AppHeader = withStyles(styles, { name: "AppHeader" })(
|
||||
({
|
||||
children,
|
||||
classes,
|
||||
onBack
|
||||
}: AppHeaderProps & WithStyles<typeof styles>) => (
|
||||
alignItems: "center",
|
||||
color: theme.palette.grey[500],
|
||||
cursor: "pointer",
|
||||
display: "flex",
|
||||
marginTop: theme.spacing(0.5),
|
||||
transition: theme.transitions.duration.standard + "ms"
|
||||
},
|
||||
skeleton: {
|
||||
marginBottom: theme.spacing(2),
|
||||
width: "10rem"
|
||||
},
|
||||
title: {
|
||||
color: "inherit",
|
||||
flex: 1,
|
||||
marginLeft: theme.spacing(),
|
||||
textTransform: "uppercase"
|
||||
}
|
||||
}));
|
||||
const AppHeader: React.FC<AppHeaderProps> = props => {
|
||||
const { children, onBack } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<AppHeaderContext.Consumer>
|
||||
{anchor =>
|
||||
anchor ? (
|
||||
|
@ -71,7 +65,7 @@ const AppHeader = withStyles(styles, { name: "AppHeader" })(
|
|||
) : null
|
||||
}
|
||||
</AppHeaderContext.Consumer>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
AppHeader.displayName = "AppHeader";
|
||||
export default AppHeader;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './AppHeader';
|
||||
export * from './AppHeader';
|
||||
export { default } from "./AppHeader";
|
||||
export * from "./AppHeader";
|
||||
|
|
|
@ -8,12 +8,7 @@ import MenuItem from "@material-ui/core/MenuItem";
|
|||
import Menu from "@material-ui/core/MenuList";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import Popper from "@material-ui/core/Popper";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
import SVG from "react-inlinesvg";
|
||||
|
@ -41,8 +36,8 @@ import createMenuStructure from "./menuStructure";
|
|||
import ResponsiveDrawer from "./ResponsiveDrawer";
|
||||
import ThemeSwitch from "./ThemeSwitch";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
appAction: {
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
left: 0,
|
||||
|
@ -56,15 +51,15 @@ const styles = (theme: Theme) =>
|
|||
},
|
||||
appLoader: {
|
||||
height: appLoaderHeight,
|
||||
marginBottom: theme.spacing.unit * 2,
|
||||
marginBottom: theme.spacing(2),
|
||||
zIndex: 1201
|
||||
},
|
||||
appLoaderPlaceholder: {
|
||||
height: appLoaderHeight,
|
||||
marginBottom: theme.spacing.unit * 2
|
||||
marginBottom: theme.spacing(2)
|
||||
},
|
||||
arrow: {
|
||||
marginLeft: theme.spacing.unit * 2,
|
||||
marginLeft: theme.spacing(2),
|
||||
transition: theme.transitions.duration.standard + "ms"
|
||||
},
|
||||
content: {
|
||||
|
@ -82,12 +77,12 @@ const styles = (theme: Theme) =>
|
|||
paddingLeft: drawerWidth
|
||||
},
|
||||
darkThemeSwitch: {
|
||||
marginRight: theme.spacing.unit * 2
|
||||
marginRight: theme.spacing(2)
|
||||
},
|
||||
header: {
|
||||
display: "flex",
|
||||
height: 40,
|
||||
marginBottom: theme.spacing.unit * 3
|
||||
marginBottom: theme.spacing(3)
|
||||
},
|
||||
isMenuSmall: {
|
||||
"& path": {
|
||||
|
@ -186,8 +181,8 @@ const styles = (theme: Theme) =>
|
|||
borderRadius: "50%",
|
||||
cursor: "pointer",
|
||||
height: 42,
|
||||
left: theme.spacing.unit,
|
||||
marginRight: theme.spacing.unit * 2,
|
||||
left: theme.spacing(),
|
||||
marginRight: theme.spacing(2),
|
||||
position: "relative",
|
||||
transform: "rotate(0deg)",
|
||||
transition: `${theme.transitions.duration.shorter}ms ease-in-out`,
|
||||
|
@ -236,7 +231,7 @@ const styles = (theme: Theme) =>
|
|||
padding: 0
|
||||
},
|
||||
background: theme.palette.background.paper,
|
||||
padding: `0 ${theme.spacing.unit * 4}px`
|
||||
padding: `0 ${theme.spacing(4)}px`
|
||||
},
|
||||
spacer: {
|
||||
flex: 1
|
||||
|
@ -260,259 +255,240 @@ const styles = (theme: Theme) =>
|
|||
flex: 1,
|
||||
flexGrow: 1,
|
||||
marginLeft: 0,
|
||||
paddingBottom: theme.spacing.unit,
|
||||
paddingBottom: theme.spacing(),
|
||||
[theme.breakpoints.up("sm")]: {
|
||||
paddingBottom: theme.spacing.unit * 3
|
||||
paddingBottom: theme.spacing(3)
|
||||
}
|
||||
},
|
||||
viewContainer: {
|
||||
minHeight: `calc(100vh - ${theme.spacing.unit * 2 +
|
||||
appLoaderHeight +
|
||||
70}px)`
|
||||
minHeight: `calc(100vh - ${theme.spacing(2) + appLoaderHeight + 70}px)`
|
||||
}
|
||||
});
|
||||
}),
|
||||
{
|
||||
name: "AppLayout"
|
||||
}
|
||||
);
|
||||
|
||||
interface AppLayoutProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const AppLayout = withStyles(styles, {
|
||||
name: "AppLayout"
|
||||
})(
|
||||
withRouter<AppLayoutProps & RouteComponentProps<any>, any>(
|
||||
({
|
||||
classes,
|
||||
children,
|
||||
location
|
||||
}: AppLayoutProps &
|
||||
WithStyles<typeof styles> &
|
||||
RouteComponentProps<any>) => {
|
||||
const { isDark, toggleTheme } = useTheme();
|
||||
const [isMenuSmall, setMenuSmall] = useLocalStorage("isMenuSmall", false);
|
||||
const [isDrawerOpened, setDrawerState] = React.useState(false);
|
||||
const [isMenuOpened, setMenuState] = React.useState(false);
|
||||
const appActionAnchor = React.useRef<HTMLDivElement>();
|
||||
const appHeaderAnchor = React.useRef<HTMLDivElement>();
|
||||
const anchor = React.useRef<HTMLDivElement>();
|
||||
const { logout, user } = useUser();
|
||||
const navigate = useNavigator();
|
||||
const intl = useIntl();
|
||||
const AppLayout = withRouter<AppLayoutProps & RouteComponentProps<any>, any>(
|
||||
({ children, location }: AppLayoutProps & RouteComponentProps<any>) => {
|
||||
const classes = useStyles({});
|
||||
const { isDark, toggleTheme } = useTheme();
|
||||
const [isMenuSmall, setMenuSmall] = useLocalStorage("isMenuSmall", false);
|
||||
const [isDrawerOpened, setDrawerState] = React.useState(false);
|
||||
const [isMenuOpened, setMenuState] = React.useState(false);
|
||||
const appActionAnchor = React.useRef<HTMLDivElement>();
|
||||
const appHeaderAnchor = React.useRef<HTMLDivElement>();
|
||||
const anchor = React.useRef<HTMLDivElement>();
|
||||
const { logout, user } = useUser();
|
||||
const navigate = useNavigator();
|
||||
const intl = useIntl();
|
||||
|
||||
const menuStructure = createMenuStructure(intl);
|
||||
const configurationMenu = createConfigurationMenu(intl);
|
||||
const userPermissions = maybe(() => user.permissions, []);
|
||||
const menuStructure = createMenuStructure(intl);
|
||||
const configurationMenu = createConfigurationMenu(intl);
|
||||
const userPermissions = maybe(() => user.permissions, []);
|
||||
|
||||
const renderConfigure = configurationMenu.some(section =>
|
||||
section.menuItems.some(
|
||||
menuItem =>
|
||||
!!userPermissions.find(
|
||||
userPermission => userPermission.code === menuItem.permission
|
||||
)
|
||||
)
|
||||
);
|
||||
const renderConfigure = configurationMenu.some(section =>
|
||||
section.menuItems.some(
|
||||
menuItem =>
|
||||
!!userPermissions.find(
|
||||
userPermission => userPermission.code === menuItem.permission
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const handleLogout = () => {
|
||||
setMenuState(false);
|
||||
logout();
|
||||
};
|
||||
const handleLogout = () => {
|
||||
setMenuState(false);
|
||||
logout();
|
||||
};
|
||||
|
||||
const handleViewerProfile = () => {
|
||||
setMenuState(false);
|
||||
navigate(staffMemberDetailsUrl(user.id));
|
||||
};
|
||||
const handleViewerProfile = () => {
|
||||
setMenuState(false);
|
||||
navigate(staffMemberDetailsUrl(user.id));
|
||||
};
|
||||
|
||||
const handleMenuItemClick = (
|
||||
url: string,
|
||||
event: React.MouseEvent<any>
|
||||
) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
setDrawerState(false);
|
||||
navigate(url);
|
||||
};
|
||||
const handleMenuItemClick = (url: string, event: React.MouseEvent<any>) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
setDrawerState(false);
|
||||
navigate(url);
|
||||
};
|
||||
|
||||
const handleIsMenuSmall = () => {
|
||||
setMenuSmall(!isMenuSmall);
|
||||
};
|
||||
const handleIsMenuSmall = () => {
|
||||
setMenuSmall(!isMenuSmall);
|
||||
};
|
||||
|
||||
return (
|
||||
<AppProgressProvider>
|
||||
{({ isProgress }) => (
|
||||
<AppHeaderContext.Provider value={appHeaderAnchor}>
|
||||
<AppActionContext.Provider value={appActionAnchor}>
|
||||
<div className={classes.root}>
|
||||
<div className={classes.sideBar}>
|
||||
<ResponsiveDrawer
|
||||
onClose={() => setDrawerState(false)}
|
||||
open={isDrawerOpened}
|
||||
small={!isMenuSmall}
|
||||
>
|
||||
<div
|
||||
className={classNames(classes.logo, {
|
||||
[classes.logoSmall]: isMenuSmall,
|
||||
[classes.logoDark]: isDark
|
||||
})}
|
||||
>
|
||||
<SVG
|
||||
src={
|
||||
isMenuSmall ? saleorDarkLogoSmall : saleorDarkLogo
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Hidden smDown>
|
||||
<div
|
||||
className={classNames(classes.isMenuSmall, {
|
||||
[classes.isMenuSmallHide]: isMenuSmall,
|
||||
[classes.isMenuSmallDark]: isDark
|
||||
})}
|
||||
onClick={handleIsMenuSmall}
|
||||
>
|
||||
<SVG src={menuArrowIcon} />
|
||||
</div>
|
||||
</Hidden>
|
||||
<MenuList
|
||||
className={
|
||||
isMenuSmall ? classes.menuSmall : classes.menu
|
||||
}
|
||||
menuItems={menuStructure}
|
||||
isMenuSmall={!isMenuSmall}
|
||||
location={location.pathname}
|
||||
user={user}
|
||||
renderConfigure={renderConfigure}
|
||||
onMenuItemClick={handleMenuItemClick}
|
||||
/>
|
||||
</ResponsiveDrawer>
|
||||
</div>
|
||||
<div
|
||||
className={classNames(classes.content, {
|
||||
[classes.contentToggle]: isMenuSmall
|
||||
})}
|
||||
return (
|
||||
<AppProgressProvider>
|
||||
{({ isProgress }) => (
|
||||
<AppHeaderContext.Provider value={appHeaderAnchor}>
|
||||
<AppActionContext.Provider value={appActionAnchor}>
|
||||
<div className={classes.root}>
|
||||
<div className={classes.sideBar}>
|
||||
<ResponsiveDrawer
|
||||
onClose={() => setDrawerState(false)}
|
||||
open={isDrawerOpened}
|
||||
small={!isMenuSmall}
|
||||
>
|
||||
{isProgress ? (
|
||||
<LinearProgress
|
||||
className={classes.appLoader}
|
||||
color="primary"
|
||||
<div
|
||||
className={classNames(classes.logo, {
|
||||
[classes.logoSmall]: isMenuSmall,
|
||||
[classes.logoDark]: isDark
|
||||
})}
|
||||
>
|
||||
<SVG
|
||||
src={isMenuSmall ? saleorDarkLogoSmall : saleorDarkLogo}
|
||||
/>
|
||||
) : (
|
||||
<div className={classes.appLoaderPlaceholder} />
|
||||
)}
|
||||
<div className={classes.viewContainer}>
|
||||
<div>
|
||||
<Container>
|
||||
<div className={classes.header}>
|
||||
</div>
|
||||
<Hidden smDown>
|
||||
<div
|
||||
className={classNames(classes.isMenuSmall, {
|
||||
[classes.isMenuSmallHide]: isMenuSmall,
|
||||
[classes.isMenuSmallDark]: isDark
|
||||
})}
|
||||
onClick={handleIsMenuSmall}
|
||||
>
|
||||
<SVG src={menuArrowIcon} />
|
||||
</div>
|
||||
</Hidden>
|
||||
<MenuList
|
||||
className={isMenuSmall ? classes.menuSmall : classes.menu}
|
||||
menuItems={menuStructure}
|
||||
isMenuSmall={!isMenuSmall}
|
||||
location={location.pathname}
|
||||
user={user}
|
||||
renderConfigure={renderConfigure}
|
||||
onMenuItemClick={handleMenuItemClick}
|
||||
/>
|
||||
</ResponsiveDrawer>
|
||||
</div>
|
||||
<div
|
||||
className={classNames(classes.content, {
|
||||
[classes.contentToggle]: isMenuSmall
|
||||
})}
|
||||
>
|
||||
{isProgress ? (
|
||||
<LinearProgress
|
||||
className={classes.appLoader}
|
||||
color="primary"
|
||||
/>
|
||||
) : (
|
||||
<div className={classes.appLoaderPlaceholder} />
|
||||
)}
|
||||
<div className={classes.viewContainer}>
|
||||
<div>
|
||||
<Container>
|
||||
<div className={classes.header}>
|
||||
<div
|
||||
className={classNames(classes.menuIcon, {
|
||||
[classes.menuIconOpen]: isDrawerOpened,
|
||||
[classes.menuIconDark]: isDark
|
||||
})}
|
||||
onClick={() => setDrawerState(!isDrawerOpened)}
|
||||
>
|
||||
<span />
|
||||
<span />
|
||||
<span />
|
||||
<span />
|
||||
</div>
|
||||
<div ref={appHeaderAnchor} />
|
||||
<div className={classes.spacer} />
|
||||
<div className={classes.userBar}>
|
||||
<ThemeSwitch
|
||||
className={classes.darkThemeSwitch}
|
||||
checked={isDark}
|
||||
onClick={toggleTheme}
|
||||
/>
|
||||
<div
|
||||
className={classNames(classes.menuIcon, {
|
||||
[classes.menuIconOpen]: isDrawerOpened,
|
||||
[classes.menuIconDark]: isDark
|
||||
})}
|
||||
onClick={() => setDrawerState(!isDrawerOpened)}
|
||||
className={classes.userMenuContainer}
|
||||
ref={anchor}
|
||||
>
|
||||
<span />
|
||||
<span />
|
||||
<span />
|
||||
<span />
|
||||
</div>
|
||||
<div ref={appHeaderAnchor} />
|
||||
<div className={classes.spacer} />
|
||||
<div className={classes.userBar}>
|
||||
<ThemeSwitch
|
||||
className={classes.darkThemeSwitch}
|
||||
checked={isDark}
|
||||
onClick={toggleTheme}
|
||||
<Chip
|
||||
avatar={
|
||||
user.avatar && (
|
||||
<Avatar alt="user" src={user.avatar.url} />
|
||||
)
|
||||
}
|
||||
className={classes.userChip}
|
||||
label={
|
||||
<>
|
||||
{user.email}
|
||||
<ArrowDropdown
|
||||
className={classNames(classes.arrow, {
|
||||
[classes.rotate]: isMenuOpened
|
||||
})}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
onClick={() => setMenuState(!isMenuOpened)}
|
||||
/>
|
||||
<div
|
||||
className={classes.userMenuContainer}
|
||||
ref={anchor}
|
||||
<Popper
|
||||
className={classes.popover}
|
||||
open={isMenuOpened}
|
||||
anchorEl={anchor.current}
|
||||
transition
|
||||
disablePortal
|
||||
placement="bottom-end"
|
||||
>
|
||||
<Chip
|
||||
avatar={
|
||||
user.avatar && (
|
||||
<Avatar
|
||||
alt="user"
|
||||
src={user.avatar.url}
|
||||
/>
|
||||
)
|
||||
}
|
||||
className={classes.userChip}
|
||||
label={
|
||||
<>
|
||||
{user.email}
|
||||
<ArrowDropdown
|
||||
className={classNames(classes.arrow, {
|
||||
[classes.rotate]: isMenuOpened
|
||||
})}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
onClick={() => setMenuState(!isMenuOpened)}
|
||||
/>
|
||||
<Popper
|
||||
className={classes.popover}
|
||||
open={isMenuOpened}
|
||||
anchorEl={anchor.current}
|
||||
transition
|
||||
disablePortal
|
||||
placement="bottom-end"
|
||||
>
|
||||
{({ TransitionProps, placement }) => (
|
||||
<Grow
|
||||
{...TransitionProps}
|
||||
style={{
|
||||
transformOrigin:
|
||||
placement === "bottom"
|
||||
? "right top"
|
||||
: "right bottom"
|
||||
}}
|
||||
>
|
||||
<Paper>
|
||||
<ClickAwayListener
|
||||
onClickAway={() =>
|
||||
setMenuState(false)
|
||||
}
|
||||
mouseEvent="onClick"
|
||||
>
|
||||
<Menu>
|
||||
<MenuItem
|
||||
className={classes.userMenuItem}
|
||||
onClick={handleViewerProfile}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Account Settings"
|
||||
description="button"
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
className={classes.userMenuItem}
|
||||
onClick={handleLogout}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Log out"
|
||||
description="button"
|
||||
/>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</ClickAwayListener>
|
||||
</Paper>
|
||||
</Grow>
|
||||
)}
|
||||
</Popper>
|
||||
</div>
|
||||
{({ TransitionProps, placement }) => (
|
||||
<Grow
|
||||
{...TransitionProps}
|
||||
style={{
|
||||
transformOrigin:
|
||||
placement === "bottom"
|
||||
? "right top"
|
||||
: "right bottom"
|
||||
}}
|
||||
>
|
||||
<Paper>
|
||||
<ClickAwayListener
|
||||
onClickAway={() => setMenuState(false)}
|
||||
mouseEvent="onClick"
|
||||
>
|
||||
<Menu>
|
||||
<MenuItem
|
||||
className={classes.userMenuItem}
|
||||
onClick={handleViewerProfile}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Account Settings"
|
||||
description="button"
|
||||
/>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
className={classes.userMenuItem}
|
||||
onClick={handleLogout}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Log out"
|
||||
description="button"
|
||||
/>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</ClickAwayListener>
|
||||
</Paper>
|
||||
</Grow>
|
||||
)}
|
||||
</Popper>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
</div>
|
||||
<main className={classes.view}>{children}</main>
|
||||
</div>
|
||||
</Container>
|
||||
</div>
|
||||
<div className={classes.appAction} ref={appActionAnchor} />
|
||||
<main className={classes.view}>{children}</main>
|
||||
</div>
|
||||
<div className={classes.appAction} ref={appActionAnchor} />
|
||||
</div>
|
||||
</AppActionContext.Provider>
|
||||
</AppHeaderContext.Provider>
|
||||
)}
|
||||
</AppProgressProvider>
|
||||
);
|
||||
}
|
||||
)
|
||||
</div>
|
||||
</AppActionContext.Provider>
|
||||
</AppHeaderContext.Provider>
|
||||
)}
|
||||
</AppProgressProvider>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export default AppLayout;
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
@ -24,92 +19,41 @@ import { orderDraftListUrl, orderListUrl } from "../../orders/urls";
|
|||
import MenuNested from "./MenuNested";
|
||||
import { IMenuItem } from "./menuStructure";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
menuIcon: {
|
||||
"& svg": {
|
||||
height: 32,
|
||||
width: 32
|
||||
},
|
||||
display: "inline-block",
|
||||
position: "relative",
|
||||
top: 8
|
||||
const useStyles = makeStyles(theme => ({
|
||||
menuIcon: {
|
||||
"& svg": {
|
||||
height: 32,
|
||||
width: 32
|
||||
},
|
||||
menuIconDark: {
|
||||
"& path": {
|
||||
fill: theme.palette.common.white
|
||||
}
|
||||
display: "inline-block",
|
||||
position: "relative",
|
||||
top: 8
|
||||
},
|
||||
menuIconDark: {
|
||||
"& path": {
|
||||
fill: theme.palette.common.white
|
||||
}
|
||||
},
|
||||
menuIconSmall: {
|
||||
left: -5
|
||||
},
|
||||
menuIsActive: {
|
||||
boxShadow: "0px 0px 12px 1px rgba(0,0,0,0.2)"
|
||||
},
|
||||
menuItemHover: {
|
||||
"& p": {
|
||||
fontSize: 14,
|
||||
transition: "color 0.5s ease, opacity 0.3s ease-out"
|
||||
},
|
||||
menuIconSmall: {
|
||||
left: -5
|
||||
"& path": {
|
||||
transition: "fill 0.5s ease"
|
||||
},
|
||||
menuIsActive: {
|
||||
boxShadow: "0px 0px 12px 1px rgba(0,0,0,0.2)"
|
||||
},
|
||||
menuItemHover: {
|
||||
"&:hover": {
|
||||
"& p": {
|
||||
fontSize: 14,
|
||||
transition: "color 0.5s ease, opacity 0.3s ease-out"
|
||||
},
|
||||
"& path": {
|
||||
transition: "fill 0.5s ease"
|
||||
},
|
||||
"&:hover": {
|
||||
"& p": {
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
"& path": {
|
||||
fill: theme.palette.primary.main
|
||||
},
|
||||
"&:before": {
|
||||
borderLeft: `solid 2px ${theme.palette.primary.main}`,
|
||||
content: "''",
|
||||
height: 33,
|
||||
left: -20,
|
||||
position: "absolute",
|
||||
top: 8
|
||||
},
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
cursor: "pointer",
|
||||
position: "relative"
|
||||
},
|
||||
menuList: {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
height: "100%",
|
||||
marginLeft: theme.spacing.unit * 4,
|
||||
marginTop: theme.spacing.unit * 2,
|
||||
paddingBottom: theme.spacing.unit * 3
|
||||
},
|
||||
menuListItem: {
|
||||
alignItems: "center",
|
||||
display: "block",
|
||||
marginBottom: theme.spacing.unit * 5,
|
||||
paddingLeft: 0,
|
||||
textDecoration: "none",
|
||||
transition: theme.transitions.duration.standard + "ms"
|
||||
},
|
||||
menuListItemActive: {
|
||||
"& $menuListItemText": {
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
"& path": {
|
||||
color: theme.palette.primary.main,
|
||||
fill: theme.palette.primary.main
|
||||
}
|
||||
},
|
||||
menuListItemOpen: {
|
||||
"&:after": {
|
||||
borderBottom: `10px solid transparent`,
|
||||
borderLeft: `10px solid ${theme.palette.background.paper}`,
|
||||
borderTop: `10px solid transparent`,
|
||||
content: "''",
|
||||
height: 0,
|
||||
position: "absolute",
|
||||
right: -35,
|
||||
top: 15,
|
||||
width: 0
|
||||
},
|
||||
"&:before": {
|
||||
borderLeft: `solid 2px ${theme.palette.primary.main}`,
|
||||
|
@ -119,47 +63,97 @@ const styles = (theme: Theme) =>
|
|||
position: "absolute",
|
||||
top: 8
|
||||
},
|
||||
position: "relative"
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
menuListItemText: {
|
||||
"&:hover": {
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
bottom: 0,
|
||||
cursor: "pointer",
|
||||
fontSize: "1rem",
|
||||
fontWeight: 500,
|
||||
left: 30,
|
||||
opacity: 1,
|
||||
paddingLeft: 16,
|
||||
position: "absolute",
|
||||
textTransform: "uppercase",
|
||||
transition: "opacity 0.5s ease"
|
||||
cursor: "pointer",
|
||||
position: "relative"
|
||||
},
|
||||
menuList: {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
height: "100%",
|
||||
marginLeft: theme.spacing(4),
|
||||
marginTop: theme.spacing(2),
|
||||
paddingBottom: theme.spacing(3)
|
||||
},
|
||||
menuListItem: {
|
||||
alignItems: "center",
|
||||
display: "block",
|
||||
marginBottom: theme.spacing(5),
|
||||
paddingLeft: 0,
|
||||
textDecoration: "none",
|
||||
transition: theme.transitions.duration.standard + "ms"
|
||||
},
|
||||
menuListItemActive: {
|
||||
"& $menuListItemText": {
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
menuListItemTextHide: {
|
||||
bottom: 0,
|
||||
left: 30,
|
||||
opacity: 0,
|
||||
position: "absolute"
|
||||
},
|
||||
subMenu: {
|
||||
padding: "0 15px"
|
||||
},
|
||||
subMenuDrawer: {
|
||||
background: "#000",
|
||||
cursor: "pointer",
|
||||
height: "100vh",
|
||||
left: 0,
|
||||
opacity: 0.2,
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
width: 0,
|
||||
zIndex: -2
|
||||
},
|
||||
subMenuDrawerOpen: {
|
||||
width: `100vw`
|
||||
"& path": {
|
||||
color: theme.palette.primary.main,
|
||||
fill: theme.palette.primary.main
|
||||
}
|
||||
});
|
||||
},
|
||||
menuListItemOpen: {
|
||||
"&:after": {
|
||||
borderBottom: `10px solid transparent`,
|
||||
borderLeft: `10px solid ${theme.palette.background.paper}`,
|
||||
borderTop: `10px solid transparent`,
|
||||
content: "''",
|
||||
height: 0,
|
||||
position: "absolute",
|
||||
right: -35,
|
||||
top: 15,
|
||||
width: 0
|
||||
},
|
||||
"&:before": {
|
||||
borderLeft: `solid 2px ${theme.palette.primary.main}`,
|
||||
content: "''",
|
||||
height: 33,
|
||||
left: -20,
|
||||
position: "absolute",
|
||||
top: 8
|
||||
},
|
||||
position: "relative"
|
||||
},
|
||||
menuListItemText: {
|
||||
"&:hover": {
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
bottom: 0,
|
||||
cursor: "pointer",
|
||||
fontSize: "1rem",
|
||||
fontWeight: 500,
|
||||
left: 30,
|
||||
opacity: 1,
|
||||
paddingLeft: 16,
|
||||
position: "absolute",
|
||||
textTransform: "uppercase",
|
||||
transition: "opacity 0.5s ease"
|
||||
},
|
||||
menuListItemTextHide: {
|
||||
bottom: 0,
|
||||
left: 30,
|
||||
opacity: 0,
|
||||
position: "absolute"
|
||||
},
|
||||
subMenu: {
|
||||
padding: "0 15px"
|
||||
},
|
||||
subMenuDrawer: {
|
||||
background: "#000",
|
||||
cursor: "pointer",
|
||||
height: "100vh",
|
||||
left: 0,
|
||||
opacity: 0.2,
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
width: 0,
|
||||
zIndex: -2
|
||||
},
|
||||
subMenuDrawerOpen: {
|
||||
width: `100vw`
|
||||
}
|
||||
}));
|
||||
|
||||
interface MenuListProps {
|
||||
className?: string;
|
||||
|
@ -176,9 +170,8 @@ export interface IActiveSubMenu {
|
|||
label: string | null;
|
||||
}
|
||||
|
||||
const MenuList = withStyles(styles, { name: "MenuList" })(
|
||||
({
|
||||
classes,
|
||||
const MenuList: React.FC<MenuListProps> = props => {
|
||||
const {
|
||||
className,
|
||||
menuItems,
|
||||
isMenuSmall,
|
||||
|
@ -186,134 +179,89 @@ const MenuList = withStyles(styles, { name: "MenuList" })(
|
|||
user,
|
||||
renderConfigure,
|
||||
onMenuItemClick
|
||||
}: MenuListProps & WithStyles<typeof styles>) => {
|
||||
const { isDark } = useTheme();
|
||||
const [activeSubMenu, setActiveSubMenu] = React.useState<IActiveSubMenu>({
|
||||
} = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
const { isDark } = useTheme();
|
||||
const [activeSubMenu, setActiveSubMenu] = React.useState<IActiveSubMenu>({
|
||||
isActive: false,
|
||||
label: null
|
||||
});
|
||||
const intl = useIntl();
|
||||
|
||||
const configutationMenu = createConfigurationMenu(intl).map(menu => {
|
||||
menu.menuItems.map(item =>
|
||||
user.permissions.map(perm => perm.code).includes(item.permission)
|
||||
);
|
||||
});
|
||||
|
||||
const handleSubMenu = itemLabel => {
|
||||
setActiveSubMenu({
|
||||
isActive:
|
||||
itemLabel === activeSubMenu.label ? !activeSubMenu.isActive : true,
|
||||
label: itemLabel
|
||||
});
|
||||
};
|
||||
|
||||
const closeSubMenu = (menuItemUrl, event) => {
|
||||
setActiveSubMenu({
|
||||
isActive: false,
|
||||
label: null
|
||||
});
|
||||
const intl = useIntl();
|
||||
if (menuItemUrl && event) {
|
||||
onMenuItemClick(menuItemUrl, event);
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
const configutationMenu = createConfigurationMenu(intl).map(menu => {
|
||||
menu.menuItems.map(item =>
|
||||
user.permissions.map(perm => perm.code).includes(item.permission)
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div
|
||||
className={classNames(className, {
|
||||
[classes.menuIsActive]: activeSubMenu.isActive
|
||||
})}
|
||||
>
|
||||
{/* FIXME: this .split("?")[0] looks gross */}
|
||||
{menuItems.map(menuItem => {
|
||||
const isActive = (menuItem: IMenuItem) =>
|
||||
location.split("?")[0] === orderDraftListUrl().split("?")[0] &&
|
||||
menuItem.url.split("?")[0] === orderListUrl().split("?")[0]
|
||||
? false
|
||||
: !!matchPath(location.split("?")[0], {
|
||||
exact: menuItem.url.split("?")[0] === "/",
|
||||
path: menuItem.url.split("?")[0]
|
||||
});
|
||||
|
||||
const handleSubMenu = itemLabel => {
|
||||
setActiveSubMenu({
|
||||
isActive:
|
||||
itemLabel === activeSubMenu.label ? !activeSubMenu.isActive : true,
|
||||
label: itemLabel
|
||||
});
|
||||
};
|
||||
if (
|
||||
menuItem.permission &&
|
||||
!user.permissions.map(perm => perm.code).includes(menuItem.permission)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const closeSubMenu = (menuItemUrl, event) => {
|
||||
setActiveSubMenu({
|
||||
isActive: false,
|
||||
label: null
|
||||
});
|
||||
if (menuItemUrl && event) {
|
||||
onMenuItemClick(menuItemUrl, event);
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(className, {
|
||||
[classes.menuIsActive]: activeSubMenu.isActive
|
||||
})}
|
||||
>
|
||||
{/* FIXME: this .split("?")[0] looks gross */}
|
||||
{menuItems.map(menuItem => {
|
||||
const isActive = (menuItem: IMenuItem) =>
|
||||
location.split("?")[0] === orderDraftListUrl().split("?")[0] &&
|
||||
menuItem.url.split("?")[0] === orderListUrl().split("?")[0]
|
||||
? false
|
||||
: !!matchPath(location.split("?")[0], {
|
||||
exact: menuItem.url.split("?")[0] === "/",
|
||||
path: menuItem.url.split("?")[0]
|
||||
});
|
||||
|
||||
if (
|
||||
menuItem.permission &&
|
||||
!user.permissions
|
||||
.map(perm => perm.code)
|
||||
.includes(menuItem.permission)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!menuItem.url) {
|
||||
const isAnyChildActive = menuItem.children.reduce(
|
||||
(acc, child) => acc || isActive(child),
|
||||
false
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(classes.menuListItem, {
|
||||
[classes.menuListItemActive]: isAnyChildActive
|
||||
})}
|
||||
key={menuItem.label}
|
||||
>
|
||||
<div
|
||||
className={classNames(classes.menuItemHover, {
|
||||
[classes.menuListItemOpen]:
|
||||
menuItem.ariaLabel === activeSubMenu.label &&
|
||||
activeSubMenu.isActive
|
||||
})}
|
||||
data-tc={menuItem.label}
|
||||
onClick={() => handleSubMenu(menuItem.ariaLabel)}
|
||||
>
|
||||
<SVG
|
||||
className={classNames(classes.menuIcon, {
|
||||
[classes.menuIconDark]: isDark,
|
||||
[classes.menuIconSmall]: !isMenuSmall
|
||||
})}
|
||||
src={menuItem.icon}
|
||||
/>
|
||||
<Typography
|
||||
aria-label={menuItem.ariaLabel}
|
||||
className={classNames(classes.menuListItemText, {
|
||||
[classes.menuListItemTextHide]: !isMenuSmall
|
||||
})}
|
||||
>
|
||||
{menuItem.label}
|
||||
</Typography>
|
||||
</div>
|
||||
<MenuNested
|
||||
activeItem={activeSubMenu}
|
||||
closeSubMenu={setActiveSubMenu}
|
||||
menuItem={menuItem}
|
||||
onMenuItemClick={onMenuItemClick}
|
||||
handleSubMenu={handleSubMenu}
|
||||
title={menuItem.label}
|
||||
icon={menuItem.icon}
|
||||
ariaLabel={menuItem.ariaLabel}
|
||||
/>
|
||||
<div
|
||||
onClick={event => closeSubMenu(null, event)}
|
||||
className={classNames(classes.subMenuDrawer, {
|
||||
[classes.subMenuDrawerOpen]: activeSubMenu.isActive
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if (!menuItem.url) {
|
||||
const isAnyChildActive = menuItem.children.reduce(
|
||||
(acc, child) => acc || isActive(child),
|
||||
false
|
||||
);
|
||||
|
||||
return (
|
||||
<a
|
||||
<div
|
||||
className={classNames(classes.menuListItem, {
|
||||
[classes.menuListItemActive]: isActive(menuItem)
|
||||
[classes.menuListItemActive]: isAnyChildActive
|
||||
})}
|
||||
href={createHref(menuItem.url)}
|
||||
onClick={event => closeSubMenu(menuItem.url, event)}
|
||||
key={menuItem.label}
|
||||
>
|
||||
<div className={classes.menuItemHover}>
|
||||
<div
|
||||
className={classNames(classes.menuItemHover, {
|
||||
[classes.menuListItemOpen]:
|
||||
menuItem.ariaLabel === activeSubMenu.label &&
|
||||
activeSubMenu.isActive
|
||||
})}
|
||||
data-tc={menuItem.label}
|
||||
onClick={() => handleSubMenu(menuItem.ariaLabel)}
|
||||
>
|
||||
<SVG
|
||||
className={classNames(classes.menuIcon, {
|
||||
[classes.menuIconDark]: isDark,
|
||||
|
@ -330,14 +278,34 @@ const MenuList = withStyles(styles, { name: "MenuList" })(
|
|||
{menuItem.label}
|
||||
</Typography>
|
||||
</div>
|
||||
</a>
|
||||
<MenuNested
|
||||
activeItem={activeSubMenu}
|
||||
closeSubMenu={setActiveSubMenu}
|
||||
menuItem={menuItem}
|
||||
onMenuItemClick={onMenuItemClick}
|
||||
handleSubMenu={handleSubMenu}
|
||||
title={menuItem.label}
|
||||
icon={menuItem.icon}
|
||||
ariaLabel={menuItem.ariaLabel}
|
||||
/>
|
||||
<div
|
||||
onClick={event => closeSubMenu(null, event)}
|
||||
className={classNames(classes.subMenuDrawer, {
|
||||
[classes.subMenuDrawerOpen]: activeSubMenu.isActive
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{renderConfigure && configutationMenu.length > 0 && (
|
||||
}
|
||||
|
||||
return (
|
||||
<a
|
||||
className={classes.menuListItem}
|
||||
href={createHref(configurationMenuUrl)}
|
||||
onClick={event => closeSubMenu(configurationMenuUrl, event)}
|
||||
className={classNames(classes.menuListItem, {
|
||||
[classes.menuListItemActive]: isActive(menuItem)
|
||||
})}
|
||||
href={createHref(menuItem.url)}
|
||||
onClick={event => closeSubMenu(menuItem.url, event)}
|
||||
key={menuItem.label}
|
||||
>
|
||||
<div className={classes.menuItemHover}>
|
||||
<SVG
|
||||
|
@ -345,21 +313,48 @@ const MenuList = withStyles(styles, { name: "MenuList" })(
|
|||
[classes.menuIconDark]: isDark,
|
||||
[classes.menuIconSmall]: !isMenuSmall
|
||||
})}
|
||||
src={configureIcon}
|
||||
src={menuItem.icon}
|
||||
/>
|
||||
<Typography
|
||||
aria-label="configuration"
|
||||
aria-label={menuItem.ariaLabel}
|
||||
className={classNames(classes.menuListItemText, {
|
||||
[classes.menuListItemTextHide]: !isMenuSmall
|
||||
})}
|
||||
>
|
||||
<FormattedMessage {...sectionNames.configuration} />
|
||||
{menuItem.label}
|
||||
</Typography>
|
||||
</div>
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
);
|
||||
})}
|
||||
{renderConfigure && configutationMenu.length > 0 && (
|
||||
<a
|
||||
className={classes.menuListItem}
|
||||
href={createHref(configurationMenuUrl)}
|
||||
onClick={event => closeSubMenu(configurationMenuUrl, event)}
|
||||
>
|
||||
<div className={classes.menuItemHover}>
|
||||
<SVG
|
||||
className={classNames(classes.menuIcon, {
|
||||
[classes.menuIconDark]: isDark,
|
||||
[classes.menuIconSmall]: !isMenuSmall
|
||||
})}
|
||||
src={configureIcon}
|
||||
/>
|
||||
<Typography
|
||||
aria-label="configuration"
|
||||
className={classNames(classes.menuListItemText, {
|
||||
[classes.menuListItemTextHide]: !isMenuSmall
|
||||
})}
|
||||
>
|
||||
<FormattedMessage {...sectionNames.configuration} />
|
||||
</Typography>
|
||||
</div>
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
MenuList.displayName = "MenuList";
|
||||
export default MenuList;
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
import Hidden from "@material-ui/core/Hidden";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
@ -17,89 +12,88 @@ import { drawerWidthExpanded } from "./consts";
|
|||
import { IActiveSubMenu } from "./MenuList";
|
||||
import { IMenuItem } from "./menuStructure";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
menuListNested: {
|
||||
background: theme.palette.background.paper,
|
||||
height: "100vh",
|
||||
position: "absolute",
|
||||
right: 0,
|
||||
top: 0,
|
||||
transition: `right ${theme.transitions.duration.shorter}ms ease`,
|
||||
width: 300,
|
||||
zIndex: -1
|
||||
const useStyles = makeStyles(theme => ({
|
||||
menuListNested: {
|
||||
background: theme.palette.background.paper,
|
||||
height: "100vh",
|
||||
position: "absolute",
|
||||
right: 0,
|
||||
top: 0,
|
||||
transition: `right ${theme.transitions.duration.shorter}ms ease`,
|
||||
width: 300,
|
||||
zIndex: -1
|
||||
},
|
||||
menuListNestedClose: {
|
||||
"& svg": {
|
||||
fill: theme.palette.primary.main,
|
||||
left: 7,
|
||||
position: "relative",
|
||||
top: -2
|
||||
},
|
||||
menuListNestedClose: {
|
||||
"& svg": {
|
||||
fill: theme.palette.primary.main,
|
||||
left: 7,
|
||||
position: "relative",
|
||||
top: -2
|
||||
},
|
||||
border: `solid 1px #EAEAEA`,
|
||||
borderRadius: "100%",
|
||||
cursor: "pointer",
|
||||
height: 32,
|
||||
position: "absolute",
|
||||
right: 32,
|
||||
top: 35,
|
||||
transform: "rotate(180deg)",
|
||||
width: 32
|
||||
border: `solid 1px #EAEAEA`,
|
||||
borderRadius: "100%",
|
||||
cursor: "pointer",
|
||||
height: 32,
|
||||
position: "absolute",
|
||||
right: 32,
|
||||
top: 35,
|
||||
transform: "rotate(180deg)",
|
||||
width: 32
|
||||
},
|
||||
menuListNestedCloseDark: {
|
||||
border: `solid 1px #252728`
|
||||
},
|
||||
menuListNestedHide: {
|
||||
opacity: 0
|
||||
},
|
||||
menuListNestedIcon: {
|
||||
"& path": {
|
||||
fill: "initial"
|
||||
},
|
||||
menuListNestedCloseDark: {
|
||||
border: `solid 1px #252728`
|
||||
},
|
||||
menuListNestedHide: {
|
||||
opacity: 0
|
||||
},
|
||||
menuListNestedIcon: {
|
||||
"& path": {
|
||||
fill: "initial"
|
||||
},
|
||||
"& svg": { height: 32, position: "relative", top: 7, width: 32 }
|
||||
},
|
||||
menuListNestedIconDark: {
|
||||
"& path": {
|
||||
fill: theme.palette.common.white
|
||||
"& svg": { height: 32, position: "relative", top: 7, width: 32 }
|
||||
},
|
||||
menuListNestedIconDark: {
|
||||
"& path": {
|
||||
fill: theme.palette.common.white
|
||||
}
|
||||
},
|
||||
menuListNestedItem: {
|
||||
"&:hover": {
|
||||
"& p": {
|
||||
color: theme.palette.primary.main
|
||||
}
|
||||
},
|
||||
menuListNestedItem: {
|
||||
"&:hover": {
|
||||
"& p": {
|
||||
color: theme.palette.primary.main
|
||||
}
|
||||
},
|
||||
display: "block",
|
||||
marginBottom: theme.spacing.unit * 2,
|
||||
padding: "0px 30px",
|
||||
textDecoration: "none"
|
||||
display: "block",
|
||||
marginBottom: theme.spacing(2),
|
||||
padding: "0px 30px",
|
||||
textDecoration: "none"
|
||||
},
|
||||
menuListNestedOpen: {
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
right: 0,
|
||||
width: drawerWidthExpanded,
|
||||
zIndex: 2
|
||||
},
|
||||
menuListNestedOpen: {
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
right: 0,
|
||||
width: drawerWidthExpanded,
|
||||
zIndex: 2
|
||||
},
|
||||
right: -300,
|
||||
zIndex: -1
|
||||
right: -300,
|
||||
zIndex: -1
|
||||
},
|
||||
subHeader: {
|
||||
borderBottom: "solid 1px #EAEAEA",
|
||||
margin: "30px",
|
||||
marginBottom: 39,
|
||||
paddingBottom: 22
|
||||
},
|
||||
subHeaderDark: {
|
||||
borderBottom: "solid 1px #252728"
|
||||
},
|
||||
subHeaderTitle: {
|
||||
[theme.breakpoints.up("md")]: {
|
||||
paddingLeft: 0
|
||||
},
|
||||
subHeader: {
|
||||
borderBottom: "solid 1px #EAEAEA",
|
||||
margin: "30px",
|
||||
marginBottom: 39,
|
||||
paddingBottom: 22
|
||||
},
|
||||
subHeaderDark: {
|
||||
borderBottom: "solid 1px #252728"
|
||||
},
|
||||
subHeaderTitle: {
|
||||
[theme.breakpoints.up("md")]: {
|
||||
paddingLeft: 0
|
||||
},
|
||||
display: "inline",
|
||||
paddingLeft: 10
|
||||
}
|
||||
});
|
||||
display: "inline",
|
||||
paddingLeft: 10
|
||||
}
|
||||
}));
|
||||
|
||||
export interface MenuNestedProps {
|
||||
activeItem: IActiveSubMenu;
|
||||
|
@ -112,86 +106,85 @@ export interface MenuNestedProps {
|
|||
onMenuItemClick: (url: string, event: React.MouseEvent<any>) => void;
|
||||
}
|
||||
|
||||
const MenuNested = withStyles(styles, { name: "MenuNested" })(
|
||||
({
|
||||
const MenuNested: React.FC<MenuNestedProps> = props => {
|
||||
const {
|
||||
activeItem,
|
||||
ariaLabel,
|
||||
classes,
|
||||
|
||||
closeSubMenu,
|
||||
icon,
|
||||
menuItem,
|
||||
onMenuItemClick,
|
||||
title
|
||||
}: MenuNestedProps & WithStyles<typeof styles>) => {
|
||||
const menuItems = menuItem.children;
|
||||
const { isDark } = useTheme();
|
||||
const closeMenu = (menuItemUrl, event) => {
|
||||
onMenuItemClick(menuItemUrl, event);
|
||||
closeSubMenu({
|
||||
isActive: false,
|
||||
label: null
|
||||
});
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={classNames(classes.menuListNested, {
|
||||
[classes.menuListNestedOpen]:
|
||||
activeItem.label === ariaLabel && activeItem.isActive
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
const menuItems = menuItem.children;
|
||||
const { isDark } = useTheme();
|
||||
const closeMenu = (menuItemUrl, event) => {
|
||||
onMenuItemClick(menuItemUrl, event);
|
||||
closeSubMenu({
|
||||
isActive: false,
|
||||
label: null
|
||||
});
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={classNames(classes.menuListNested, {
|
||||
[classes.menuListNestedOpen]:
|
||||
activeItem.label === ariaLabel && activeItem.isActive
|
||||
})}
|
||||
>
|
||||
<Typography
|
||||
className={classNames(classes.subHeader, {
|
||||
[classes.subHeaderDark]: isDark
|
||||
})}
|
||||
variant="h5"
|
||||
>
|
||||
<Typography
|
||||
className={classNames(classes.subHeader, {
|
||||
[classes.subHeaderDark]: isDark
|
||||
})}
|
||||
variant="h5"
|
||||
<Hidden mdUp>
|
||||
<SVG
|
||||
className={classNames(classes.menuListNestedIcon, {
|
||||
[classes.menuListNestedIconDark]: isDark
|
||||
})}
|
||||
src={icon}
|
||||
/>
|
||||
</Hidden>
|
||||
<div className={classes.subHeaderTitle}>{title}</div>
|
||||
<Hidden mdUp>
|
||||
<div
|
||||
className={classNames(classes.menuListNestedClose, {
|
||||
[classes.menuListNestedCloseDark]: isDark
|
||||
})}
|
||||
data-tc={ariaLabel}
|
||||
onClick={() =>
|
||||
closeSubMenu({
|
||||
isActive: false,
|
||||
label: null
|
||||
})
|
||||
}
|
||||
>
|
||||
<SVG src={menuArrowIcon} />
|
||||
</div>
|
||||
</Hidden>
|
||||
</Typography>
|
||||
{menuItems.map(item => (
|
||||
<a
|
||||
className={classNames(classes.menuListNestedItem)}
|
||||
href={createHref(item.url)}
|
||||
data-tc={ariaLabel}
|
||||
onClick={event => closeMenu(item.url, event)}
|
||||
key={item.label}
|
||||
>
|
||||
<Hidden mdUp>
|
||||
<SVG
|
||||
className={classNames(classes.menuListNestedIcon, {
|
||||
[classes.menuListNestedIconDark]: isDark
|
||||
})}
|
||||
src={icon}
|
||||
/>
|
||||
</Hidden>
|
||||
<div className={classes.subHeaderTitle}>{title}</div>
|
||||
<Hidden mdUp>
|
||||
<div
|
||||
className={classNames(classes.menuListNestedClose, {
|
||||
[classes.menuListNestedCloseDark]: isDark
|
||||
})}
|
||||
data-tc={ariaLabel}
|
||||
onClick={() =>
|
||||
closeSubMenu({
|
||||
isActive: false,
|
||||
label: null
|
||||
})
|
||||
}
|
||||
>
|
||||
<SVG src={menuArrowIcon} />
|
||||
</div>
|
||||
</Hidden>
|
||||
</Typography>
|
||||
{menuItems.map(item => {
|
||||
return (
|
||||
<a
|
||||
className={classNames(classes.menuListNestedItem)}
|
||||
href={createHref(item.url)}
|
||||
data-tc={ariaLabel}
|
||||
onClick={event => closeMenu(item.url, event)}
|
||||
key={item.label}
|
||||
>
|
||||
<Typography aria-label={item.ariaLabel}>
|
||||
{item.label}
|
||||
</Typography>
|
||||
</a>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
);
|
||||
<Typography aria-label={item.ariaLabel}>{item.label}</Typography>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
MenuNested.displayName = "MenuNested";
|
||||
export default MenuNested;
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
import Drawer from "@material-ui/core/Drawer";
|
||||
import Hidden from "@material-ui/core/Hidden";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import React from "react";
|
||||
import { drawerWidth, drawerWidthExpanded } from "./consts";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
drawerDesktop: {
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
border: "none",
|
||||
|
@ -29,17 +24,23 @@ const styles = (theme: Theme) =>
|
|||
drawerMobile: {
|
||||
width: drawerWidthExpanded
|
||||
}
|
||||
});
|
||||
}),
|
||||
{ name: "ResponsiveDrawer" }
|
||||
);
|
||||
|
||||
interface ResponsiveDrawerProps extends WithStyles<typeof styles> {
|
||||
interface ResponsiveDrawerProps {
|
||||
children?: React.ReactNode;
|
||||
open: boolean;
|
||||
small: boolean;
|
||||
onClose?();
|
||||
}
|
||||
|
||||
const ResponsiveDrawer = withStyles(styles, { name: "ResponsiveDrawer" })(
|
||||
({ children, classes, onClose, open, small }: ResponsiveDrawerProps) => (
|
||||
const ResponsiveDrawer: React.FC<ResponsiveDrawerProps> = props => {
|
||||
const { children, onClose, open, small } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Hidden smDown>
|
||||
<Drawer
|
||||
|
@ -63,6 +64,6 @@ const ResponsiveDrawer = withStyles(styles, { name: "ResponsiveDrawer" })(
|
|||
</Drawer>
|
||||
</Hidden>
|
||||
</>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
export default ResponsiveDrawer;
|
||||
|
|
|
@ -1,43 +1,51 @@
|
|||
import { Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Switch, { SwitchProps } from "@material-ui/core/Switch";
|
||||
import React from "react";
|
||||
|
||||
import MoonIcon from "../../icons/Moon";
|
||||
import SunIcon from "../../icons/Sun";
|
||||
|
||||
const switchStyles = (theme: Theme) => ({
|
||||
bar: {
|
||||
"$colorPrimary$checked + &": {
|
||||
backgroundColor: theme.palette.background.paper
|
||||
const useStyles = makeStyles(
|
||||
theme => ({
|
||||
checked: {
|
||||
"& svg": {
|
||||
background: theme.palette.primary.main,
|
||||
color: theme.palette.background.paper
|
||||
}
|
||||
},
|
||||
background: theme.palette.background.paper
|
||||
},
|
||||
checked: {
|
||||
"& svg": {
|
||||
background: theme.palette.primary.main,
|
||||
color: theme.palette.background.paper
|
||||
colorPrimary: {},
|
||||
root: {
|
||||
"& svg": {
|
||||
background: theme.palette.primary.main,
|
||||
borderRadius: "100%",
|
||||
height: 20,
|
||||
width: 20
|
||||
}
|
||||
},
|
||||
track: {
|
||||
"$colorPrimary$checked + &": {
|
||||
backgroundColor: theme.palette.background.paper
|
||||
},
|
||||
background: theme.palette.background.paper
|
||||
}
|
||||
},
|
||||
colorPrimary: {},
|
||||
root: {
|
||||
"& svg": {
|
||||
background: theme.palette.primary.main,
|
||||
borderRadius: "100%",
|
||||
height: 20,
|
||||
width: 20
|
||||
},
|
||||
width: 58
|
||||
}),
|
||||
{
|
||||
name: "ThemeSwitch"
|
||||
}
|
||||
});
|
||||
const ThemeSwitch = withStyles(switchStyles, {
|
||||
name: "ThemeSwitch"
|
||||
})((props: SwitchProps) => (
|
||||
<Switch
|
||||
{...props}
|
||||
color="primary"
|
||||
icon={<SunIcon />}
|
||||
checkedIcon={<MoonIcon />}
|
||||
/>
|
||||
));
|
||||
);
|
||||
const ThemeSwitch: React.FC<SwitchProps> = props => {
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<Switch
|
||||
{...props}
|
||||
classes={classes}
|
||||
color="primary"
|
||||
icon={<SunIcon />}
|
||||
checkedIcon={<MoonIcon />}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
ThemeSwitch.displayName = "ThemeSwitch";
|
||||
export default ThemeSwitch;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './AppLayout';
|
||||
export * from './AppLayout';
|
||||
export { default } from "./AppLayout";
|
||||
export * from "./AppLayout";
|
||||
|
|
|
@ -4,7 +4,7 @@ import Dialog from "@material-ui/core/Dialog";
|
|||
import DialogActions from "@material-ui/core/DialogActions";
|
||||
import DialogContent from "@material-ui/core/DialogContent";
|
||||
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||
import { createStyles, withStyles, WithStyles } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Table from "@material-ui/core/Table";
|
||||
import TableBody from "@material-ui/core/TableBody";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
|
@ -27,7 +27,7 @@ export interface FormData {
|
|||
query: string;
|
||||
}
|
||||
|
||||
const styles = createStyles({
|
||||
const useStyles = makeStyles({
|
||||
avatar: {
|
||||
"&:first-child": {
|
||||
paddingLeft: 0
|
||||
|
@ -44,7 +44,7 @@ const styles = createStyles({
|
|||
}
|
||||
});
|
||||
|
||||
interface AssignCategoriesDialogProps extends WithStyles<typeof styles> {
|
||||
interface AssignCategoriesDialogProps {
|
||||
categories: SearchCategories_search_edges_node[];
|
||||
confirmButtonState: ConfirmButtonTransitionState;
|
||||
open: boolean;
|
||||
|
@ -71,11 +71,8 @@ function handleCategoryAssign(
|
|||
}
|
||||
}
|
||||
|
||||
const AssignCategoriesDialog = withStyles(styles, {
|
||||
name: "AssignCategoriesDialog"
|
||||
})(
|
||||
({
|
||||
classes,
|
||||
const AssignCategoriesDialog: React.FC<AssignCategoriesDialogProps> = props => {
|
||||
const {
|
||||
confirmButtonState,
|
||||
open,
|
||||
loading,
|
||||
|
@ -83,102 +80,103 @@ const AssignCategoriesDialog = withStyles(styles, {
|
|||
onClose,
|
||||
onFetch,
|
||||
onSubmit
|
||||
}: AssignCategoriesDialogProps) => {
|
||||
const intl = useIntl();
|
||||
const [query, onQueryChange] = useSearchQuery(onFetch);
|
||||
const [selectedCategories, setSelectedCategories] = React.useState<
|
||||
SearchCategories_search_edges_node[]
|
||||
>([]);
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
const handleSubmit = () => onSubmit(selectedCategories);
|
||||
const intl = useIntl();
|
||||
const [query, onQueryChange] = useSearchQuery(onFetch);
|
||||
const [selectedCategories, setSelectedCategories] = React.useState<
|
||||
SearchCategories_search_edges_node[]
|
||||
>([]);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
classes={{ paper: classes.overflow }}
|
||||
fullWidth
|
||||
maxWidth="sm"
|
||||
>
|
||||
<DialogTitle>
|
||||
const handleSubmit = () => onSubmit(selectedCategories);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open={open}
|
||||
onClose={onClose}
|
||||
classes={{ paper: classes.overflow }}
|
||||
fullWidth
|
||||
maxWidth="sm"
|
||||
>
|
||||
<DialogTitle>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign Categories"
|
||||
description="dialog header"
|
||||
/>
|
||||
</DialogTitle>
|
||||
<DialogContent className={classes.overflow}>
|
||||
<TextField
|
||||
name="query"
|
||||
value={query}
|
||||
onChange={onQueryChange}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Search Categories"
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
defaultMessage: "Search by category name, etc..."
|
||||
})}
|
||||
fullWidth
|
||||
InputProps={{
|
||||
autoComplete: "off",
|
||||
endAdornment: loading && <CircularProgress size={16} />
|
||||
}}
|
||||
/>
|
||||
<FormSpacer />
|
||||
<Table>
|
||||
<TableBody>
|
||||
{categories &&
|
||||
categories.map(category => {
|
||||
const isSelected = !!selectedCategories.find(
|
||||
selectedCategories => selectedCategories.id === category.id
|
||||
);
|
||||
|
||||
return (
|
||||
<TableRow key={category.id}>
|
||||
<TableCell
|
||||
padding="checkbox"
|
||||
className={classes.checkboxCell}
|
||||
>
|
||||
<Checkbox
|
||||
checked={isSelected}
|
||||
onChange={() =>
|
||||
handleCategoryAssign(
|
||||
category,
|
||||
isSelected,
|
||||
selectedCategories,
|
||||
setSelectedCategories
|
||||
)
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.wideCell}>
|
||||
{category.name}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose}>
|
||||
<FormattedMessage {...buttonMessages.back} />
|
||||
</Button>
|
||||
<ConfirmButton
|
||||
transitionState={confirmButtonState}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign Categories"
|
||||
description="dialog header"
|
||||
defaultMessage="Assign categories"
|
||||
description="button"
|
||||
/>
|
||||
</DialogTitle>
|
||||
<DialogContent className={classes.overflow}>
|
||||
<TextField
|
||||
name="query"
|
||||
value={query}
|
||||
onChange={onQueryChange}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Search Categories"
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
defaultMessage: "Search by category name, etc..."
|
||||
})}
|
||||
fullWidth
|
||||
InputProps={{
|
||||
autoComplete: "off",
|
||||
endAdornment: loading && <CircularProgress size={16} />
|
||||
}}
|
||||
/>
|
||||
<FormSpacer />
|
||||
<Table>
|
||||
<TableBody>
|
||||
{categories &&
|
||||
categories.map(category => {
|
||||
const isSelected = !!selectedCategories.find(
|
||||
selectedCategories => selectedCategories.id === category.id
|
||||
);
|
||||
|
||||
return (
|
||||
<TableRow key={category.id}>
|
||||
<TableCell
|
||||
padding="checkbox"
|
||||
className={classes.checkboxCell}
|
||||
>
|
||||
<Checkbox
|
||||
checked={isSelected}
|
||||
onChange={() =>
|
||||
handleCategoryAssign(
|
||||
category,
|
||||
isSelected,
|
||||
selectedCategories,
|
||||
setSelectedCategories
|
||||
)
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.wideCell}>
|
||||
{category.name}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose}>
|
||||
<FormattedMessage {...buttonMessages.back} />
|
||||
</Button>
|
||||
<ConfirmButton
|
||||
transitionState={confirmButtonState}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign categories"
|
||||
description="button"
|
||||
/>
|
||||
</ConfirmButton>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
);
|
||||
</ConfirmButton>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
AssignCategoriesDialog.displayName = "AssignCategoriesDialog";
|
||||
export default AssignCategoriesDialog;
|
||||
|
|
|
@ -4,7 +4,7 @@ import Dialog from "@material-ui/core/Dialog";
|
|||
import DialogActions from "@material-ui/core/DialogActions";
|
||||
import DialogContent from "@material-ui/core/DialogContent";
|
||||
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||
import { createStyles, withStyles, WithStyles } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Table from "@material-ui/core/Table";
|
||||
import TableBody from "@material-ui/core/TableBody";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
|
@ -27,7 +27,7 @@ export interface FormData {
|
|||
query: string;
|
||||
}
|
||||
|
||||
const styles = createStyles({
|
||||
const useStyles = makeStyles({
|
||||
avatar: {
|
||||
"&:first-child": {
|
||||
paddingLeft: 0
|
||||
|
@ -44,7 +44,7 @@ const styles = createStyles({
|
|||
}
|
||||
});
|
||||
|
||||
interface AssignCollectionDialogProps extends WithStyles<typeof styles> {
|
||||
interface AssignCollectionDialogProps {
|
||||
collections: SearchCollections_search_edges_node[];
|
||||
confirmButtonState: ConfirmButtonTransitionState;
|
||||
open: boolean;
|
||||
|
@ -71,11 +71,8 @@ function handleCollectionAssign(
|
|||
}
|
||||
}
|
||||
|
||||
const AssignCollectionDialog = withStyles(styles, {
|
||||
name: "AssignCollectionDialog"
|
||||
})(
|
||||
({
|
||||
classes,
|
||||
const AssignCollectionDialog: React.FC<AssignCollectionDialogProps> = props => {
|
||||
const {
|
||||
confirmButtonState,
|
||||
open,
|
||||
loading,
|
||||
|
@ -83,103 +80,103 @@ const AssignCollectionDialog = withStyles(styles, {
|
|||
onClose,
|
||||
onFetch,
|
||||
onSubmit
|
||||
}: AssignCollectionDialogProps) => {
|
||||
const intl = useIntl();
|
||||
const [query, onQueryChange] = useSearchQuery(onFetch);
|
||||
const [selectedCollections, setSelectedCollections] = React.useState<
|
||||
SearchCollections_search_edges_node[]
|
||||
>([]);
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
const handleSubmit = () => onSubmit(selectedCollections);
|
||||
const intl = useIntl();
|
||||
const [query, onQueryChange] = useSearchQuery(onFetch);
|
||||
const [selectedCollections, setSelectedCollections] = React.useState<
|
||||
SearchCollections_search_edges_node[]
|
||||
>([]);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
onClose={onClose}
|
||||
open={open}
|
||||
classes={{ paper: classes.overflow }}
|
||||
fullWidth
|
||||
maxWidth="sm"
|
||||
>
|
||||
<DialogTitle>
|
||||
const handleSubmit = () => onSubmit(selectedCollections);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
onClose={onClose}
|
||||
open={open}
|
||||
classes={{ paper: classes.overflow }}
|
||||
fullWidth
|
||||
maxWidth="sm"
|
||||
>
|
||||
<DialogTitle>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign Collection"
|
||||
description="dialog header"
|
||||
/>
|
||||
</DialogTitle>
|
||||
<DialogContent className={classes.overflow}>
|
||||
<TextField
|
||||
name="query"
|
||||
value={query}
|
||||
onChange={onQueryChange}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Search Collection"
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
defaultMessage: "Search by collection name, etc..."
|
||||
})}
|
||||
fullWidth
|
||||
InputProps={{
|
||||
autoComplete: "off",
|
||||
endAdornment: loading && <CircularProgress size={16} />
|
||||
}}
|
||||
/>
|
||||
<FormSpacer />
|
||||
<Table>
|
||||
<TableBody>
|
||||
{collections &&
|
||||
collections.map(collection => {
|
||||
const isSelected = !!selectedCollections.find(
|
||||
selectedCollection => selectedCollection.id === collection.id
|
||||
);
|
||||
|
||||
return (
|
||||
<TableRow key={collection.id}>
|
||||
<TableCell
|
||||
padding="checkbox"
|
||||
className={classes.checkboxCell}
|
||||
>
|
||||
<Checkbox
|
||||
checked={isSelected}
|
||||
onChange={() =>
|
||||
handleCollectionAssign(
|
||||
collection,
|
||||
isSelected,
|
||||
selectedCollections,
|
||||
setSelectedCollections
|
||||
)
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.wideCell}>
|
||||
{collection.name}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose}>
|
||||
<FormattedMessage {...buttonMessages.back} />
|
||||
</Button>
|
||||
<ConfirmButton
|
||||
transitionState={confirmButtonState}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign Collection"
|
||||
description="dialog header"
|
||||
defaultMessage="Assign collections"
|
||||
description="button"
|
||||
/>
|
||||
</DialogTitle>
|
||||
<DialogContent className={classes.overflow}>
|
||||
<TextField
|
||||
name="query"
|
||||
value={query}
|
||||
onChange={onQueryChange}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Search Collection"
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
defaultMessage: "Search by collection name, etc..."
|
||||
})}
|
||||
fullWidth
|
||||
InputProps={{
|
||||
autoComplete: "off",
|
||||
endAdornment: loading && <CircularProgress size={16} />
|
||||
}}
|
||||
/>
|
||||
<FormSpacer />
|
||||
<Table>
|
||||
<TableBody>
|
||||
{collections &&
|
||||
collections.map(collection => {
|
||||
const isSelected = !!selectedCollections.find(
|
||||
selectedCollection =>
|
||||
selectedCollection.id === collection.id
|
||||
);
|
||||
|
||||
return (
|
||||
<TableRow key={collection.id}>
|
||||
<TableCell
|
||||
padding="checkbox"
|
||||
className={classes.checkboxCell}
|
||||
>
|
||||
<Checkbox
|
||||
checked={isSelected}
|
||||
onChange={() =>
|
||||
handleCollectionAssign(
|
||||
collection,
|
||||
isSelected,
|
||||
selectedCollections,
|
||||
setSelectedCollections
|
||||
)
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.wideCell}>
|
||||
{collection.name}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose}>
|
||||
<FormattedMessage {...buttonMessages.back} />
|
||||
</Button>
|
||||
<ConfirmButton
|
||||
transitionState={confirmButtonState}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign collections"
|
||||
description="button"
|
||||
/>
|
||||
</ConfirmButton>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
);
|
||||
</ConfirmButton>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
AssignCollectionDialog.displayName = "AssignCollectionDialog";
|
||||
export default AssignCollectionDialog;
|
||||
|
|
|
@ -4,7 +4,7 @@ import Dialog from "@material-ui/core/Dialog";
|
|||
import DialogActions from "@material-ui/core/DialogActions";
|
||||
import DialogContent from "@material-ui/core/DialogContent";
|
||||
import DialogTitle from "@material-ui/core/DialogTitle";
|
||||
import { createStyles, withStyles, WithStyles } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Table from "@material-ui/core/Table";
|
||||
import TableBody from "@material-ui/core/TableBody";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
|
@ -29,7 +29,7 @@ export interface FormData {
|
|||
query: string;
|
||||
}
|
||||
|
||||
const styles = createStyles({
|
||||
const useStyles = makeStyles({
|
||||
avatar: {
|
||||
"&:first-child": {
|
||||
paddingLeft: 0
|
||||
|
@ -77,11 +77,8 @@ function handleProductAssign(
|
|||
}
|
||||
}
|
||||
|
||||
const AssignProductDialog = withStyles(styles, {
|
||||
name: "AssignProductDialog"
|
||||
})(
|
||||
({
|
||||
classes,
|
||||
const AssignProductDialog: React.FC<AssignProductDialogProps> = props => {
|
||||
const {
|
||||
confirmButtonState,
|
||||
open,
|
||||
loading,
|
||||
|
@ -89,109 +86,110 @@ const AssignProductDialog = withStyles(styles, {
|
|||
onClose,
|
||||
onFetch,
|
||||
onSubmit
|
||||
}: AssignProductDialogProps & WithStyles<typeof styles>) => {
|
||||
const intl = useIntl();
|
||||
const [query, onQueryChange] = useSearchQuery(onFetch);
|
||||
const [selectedProducts, setSelectedProducts] = React.useState<
|
||||
SearchProducts_search_edges_node[]
|
||||
>([]);
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
const handleSubmit = () => onSubmit(selectedProducts);
|
||||
const intl = useIntl();
|
||||
const [query, onQueryChange] = useSearchQuery(onFetch);
|
||||
const [selectedProducts, setSelectedProducts] = React.useState<
|
||||
SearchProducts_search_edges_node[]
|
||||
>([]);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
onClose={onClose}
|
||||
open={open}
|
||||
classes={{ paper: classes.overflow }}
|
||||
fullWidth
|
||||
maxWidth="sm"
|
||||
>
|
||||
<DialogTitle>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign Product"
|
||||
description="dialog header"
|
||||
/>
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<TextField
|
||||
name="query"
|
||||
value={query}
|
||||
onChange={onQueryChange}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Search Products"
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
defaultMessage:
|
||||
"Search by product name, attribute, product type etc..."
|
||||
})}
|
||||
fullWidth
|
||||
InputProps={{
|
||||
autoComplete: "off",
|
||||
endAdornment: loading && <CircularProgress size={16} />
|
||||
}}
|
||||
/>
|
||||
<FormSpacer />
|
||||
<div className={classes.scrollArea}>
|
||||
<Table>
|
||||
<TableBody>
|
||||
{products &&
|
||||
products.map(product => {
|
||||
const isSelected = selectedProducts.some(
|
||||
selectedProduct => selectedProduct.id === product.id
|
||||
);
|
||||
const handleSubmit = () => onSubmit(selectedProducts);
|
||||
|
||||
return (
|
||||
<TableRow key={product.id}>
|
||||
<TableCellAvatar
|
||||
className={classes.avatar}
|
||||
thumbnail={maybe(() => product.thumbnail.url)}
|
||||
return (
|
||||
<Dialog
|
||||
onClose={onClose}
|
||||
open={open}
|
||||
classes={{ paper: classes.overflow }}
|
||||
fullWidth
|
||||
maxWidth="sm"
|
||||
>
|
||||
<DialogTitle>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign Product"
|
||||
description="dialog header"
|
||||
/>
|
||||
</DialogTitle>
|
||||
<DialogContent>
|
||||
<TextField
|
||||
name="query"
|
||||
value={query}
|
||||
onChange={onQueryChange}
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Search Products"
|
||||
})}
|
||||
placeholder={intl.formatMessage({
|
||||
defaultMessage:
|
||||
"Search by product name, attribute, product type etc..."
|
||||
})}
|
||||
fullWidth
|
||||
InputProps={{
|
||||
autoComplete: "off",
|
||||
endAdornment: loading && <CircularProgress size={16} />
|
||||
}}
|
||||
/>
|
||||
<FormSpacer />
|
||||
<div className={classes.scrollArea}>
|
||||
<Table>
|
||||
<TableBody>
|
||||
{products &&
|
||||
products.map(product => {
|
||||
const isSelected = selectedProducts.some(
|
||||
selectedProduct => selectedProduct.id === product.id
|
||||
);
|
||||
|
||||
return (
|
||||
<TableRow key={product.id}>
|
||||
<TableCellAvatar
|
||||
className={classes.avatar}
|
||||
thumbnail={maybe(() => product.thumbnail.url)}
|
||||
/>
|
||||
<TableCell className={classes.wideCell}>
|
||||
{product.name}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
padding="checkbox"
|
||||
className={classes.checkboxCell}
|
||||
>
|
||||
<Checkbox
|
||||
checked={isSelected}
|
||||
onChange={() =>
|
||||
handleProductAssign(
|
||||
product,
|
||||
isSelected,
|
||||
selectedProducts,
|
||||
setSelectedProducts
|
||||
)
|
||||
}
|
||||
/>
|
||||
<TableCell className={classes.wideCell}>
|
||||
{product.name}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
padding="checkbox"
|
||||
className={classes.checkboxCell}
|
||||
>
|
||||
<Checkbox
|
||||
checked={isSelected}
|
||||
onChange={() =>
|
||||
handleProductAssign(
|
||||
product,
|
||||
isSelected,
|
||||
selectedProducts,
|
||||
setSelectedProducts
|
||||
)
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose}>
|
||||
<FormattedMessage {...buttonMessages.back} />
|
||||
</Button>
|
||||
<ConfirmButton
|
||||
transitionState={confirmButtonState}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign products"
|
||||
description="button"
|
||||
/>
|
||||
</ConfirmButton>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
);
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={onClose}>
|
||||
<FormattedMessage {...buttonMessages.back} />
|
||||
</Button>
|
||||
<ConfirmButton
|
||||
transitionState={confirmButtonState}
|
||||
color="primary"
|
||||
variant="contained"
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign products"
|
||||
description="button"
|
||||
/>
|
||||
</ConfirmButton>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
AssignProductDialog.displayName = "AssignProductDialog";
|
||||
export default AssignProductDialog;
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
import MenuItem from "@material-ui/core/MenuItem";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import ArrowBack from "@material-ui/icons/ArrowBack";
|
||||
import Downshift from "downshift";
|
||||
|
@ -43,31 +38,27 @@ const DebounceAutocomplete: React.ComponentType<
|
|||
DebounceProps<string>
|
||||
> = Debounce;
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
container: {
|
||||
flexGrow: 1,
|
||||
position: "relative"
|
||||
},
|
||||
menuBack: {
|
||||
marginLeft: -theme.spacing.unit / 2,
|
||||
marginRight: theme.spacing.unit
|
||||
},
|
||||
paper: {
|
||||
left: 0,
|
||||
marginTop: theme.spacing.unit,
|
||||
padding: theme.spacing.unit,
|
||||
position: "absolute",
|
||||
right: 0,
|
||||
zIndex: 2
|
||||
},
|
||||
root: {}
|
||||
});
|
||||
const AutocompleteSelectMenu = withStyles(styles, {
|
||||
name: "AutocompleteSelectMenu"
|
||||
})(
|
||||
({
|
||||
classes,
|
||||
const useStyles = makeStyles(theme => ({
|
||||
container: {
|
||||
flexGrow: 1,
|
||||
position: "relative"
|
||||
},
|
||||
menuBack: {
|
||||
marginLeft: -theme.spacing(0.5),
|
||||
marginRight: theme.spacing(1)
|
||||
},
|
||||
paper: {
|
||||
left: 0,
|
||||
marginTop: theme.spacing(),
|
||||
padding: theme.spacing(),
|
||||
position: "absolute",
|
||||
right: 0,
|
||||
zIndex: 2
|
||||
},
|
||||
root: {}
|
||||
}));
|
||||
const AutocompleteSelectMenu: React.FC<AutocompleteSelectMenuProps> = props => {
|
||||
const {
|
||||
disabled,
|
||||
displayValue,
|
||||
error,
|
||||
|
@ -79,117 +70,118 @@ const AutocompleteSelectMenu = withStyles(styles, {
|
|||
placeholder,
|
||||
onChange,
|
||||
onInputChange
|
||||
}: AutocompleteSelectMenuProps & WithStyles<typeof styles>) => {
|
||||
const [inputValue, setInputValue] = React.useState(displayValue || "");
|
||||
const [menuPath, setMenuPath] = React.useState<number[]>([]);
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
const handleChange = (value: string) =>
|
||||
onChange({
|
||||
target: {
|
||||
name,
|
||||
value
|
||||
}
|
||||
} as any);
|
||||
const [inputValue, setInputValue] = React.useState(displayValue || "");
|
||||
const [menuPath, setMenuPath] = React.useState<number[]>([]);
|
||||
|
||||
// Validate if option values are duplicated
|
||||
React.useEffect(() => {
|
||||
if (!validateMenuOptions(options)) {
|
||||
throw validationError;
|
||||
const handleChange = (value: string) =>
|
||||
onChange({
|
||||
target: {
|
||||
name,
|
||||
value
|
||||
}
|
||||
}, []);
|
||||
} as any);
|
||||
|
||||
// Navigate back to main menu after input field change
|
||||
React.useEffect(() => setMenuPath([]), [options]);
|
||||
// Validate if option values are duplicated
|
||||
React.useEffect(() => {
|
||||
if (!validateMenuOptions(options)) {
|
||||
throw validationError;
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Reset input value after displayValue change
|
||||
React.useEffect(() => setInputValue(displayValue), [displayValue]);
|
||||
// Navigate back to main menu after input field change
|
||||
React.useEffect(() => setMenuPath([]), [options]);
|
||||
|
||||
return (
|
||||
<DebounceAutocomplete debounceFn={onInputChange}>
|
||||
{debounceFn => (
|
||||
<Downshift
|
||||
itemToString={item => (item ? item.label : "")}
|
||||
onSelect={handleChange}
|
||||
>
|
||||
{({ getItemProps, isOpen, openMenu, closeMenu, selectItem }) => {
|
||||
return (
|
||||
<div className={classes.container}>
|
||||
<TextField
|
||||
InputProps={{
|
||||
endAdornment: loading && <CircularProgress size={16} />,
|
||||
id: undefined,
|
||||
onBlur: () => {
|
||||
closeMenu();
|
||||
setMenuPath([]);
|
||||
setInputValue(displayValue);
|
||||
},
|
||||
onChange: event => {
|
||||
debounceFn(event.target.value);
|
||||
setInputValue(event.target.value);
|
||||
},
|
||||
onFocus: () => openMenu(),
|
||||
placeholder
|
||||
}}
|
||||
disabled={disabled}
|
||||
error={error}
|
||||
helperText={helperText}
|
||||
label={label}
|
||||
fullWidth={true}
|
||||
value={inputValue}
|
||||
/>
|
||||
{isOpen && (
|
||||
<Paper className={classes.paper} square>
|
||||
{options.length ? (
|
||||
<>
|
||||
{menuPath.length > 0 && (
|
||||
<MenuItem
|
||||
component="div"
|
||||
{...getItemProps({
|
||||
item: null
|
||||
})}
|
||||
onClick={() =>
|
||||
setMenuPath(
|
||||
menuPath.slice(0, menuPath.length - 2)
|
||||
)
|
||||
}
|
||||
>
|
||||
<ArrowBack className={classes.menuBack} />
|
||||
<FormattedMessage {...buttonMessages.back} />
|
||||
</MenuItem>
|
||||
)}
|
||||
{(menuPath.length
|
||||
? getMenuItemByPath(options, menuPath).children
|
||||
: options
|
||||
).map((suggestion, index) => (
|
||||
<MenuItem
|
||||
key={suggestion.value}
|
||||
component="div"
|
||||
{...getItemProps({ item: suggestion })}
|
||||
onClick={() =>
|
||||
suggestion.value
|
||||
? selectItem(suggestion.value)
|
||||
: setMenuPath([...menuPath, index])
|
||||
}
|
||||
>
|
||||
{suggestion.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<MenuItem disabled component="div">
|
||||
<FormattedMessage defaultMessage="No results" />
|
||||
</MenuItem>
|
||||
)}
|
||||
</Paper>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</Downshift>
|
||||
)}
|
||||
</DebounceAutocomplete>
|
||||
);
|
||||
}
|
||||
);
|
||||
// Reset input value after displayValue change
|
||||
React.useEffect(() => setInputValue(displayValue), [displayValue]);
|
||||
|
||||
return (
|
||||
<DebounceAutocomplete debounceFn={onInputChange}>
|
||||
{debounceFn => (
|
||||
<Downshift
|
||||
itemToString={item => (item ? item.label : "")}
|
||||
onSelect={handleChange}
|
||||
>
|
||||
{({ getItemProps, isOpen, openMenu, closeMenu, selectItem }) => {
|
||||
return (
|
||||
<div className={classes.container}>
|
||||
<TextField
|
||||
InputProps={{
|
||||
endAdornment: loading && <CircularProgress size={16} />,
|
||||
id: undefined,
|
||||
onBlur: () => {
|
||||
closeMenu();
|
||||
setMenuPath([]);
|
||||
setInputValue(displayValue);
|
||||
},
|
||||
onChange: event => {
|
||||
debounceFn(event.target.value);
|
||||
setInputValue(event.target.value);
|
||||
},
|
||||
onFocus: () => openMenu(),
|
||||
placeholder
|
||||
}}
|
||||
disabled={disabled}
|
||||
error={error}
|
||||
helperText={helperText}
|
||||
label={label}
|
||||
fullWidth={true}
|
||||
value={inputValue}
|
||||
/>
|
||||
{isOpen && (
|
||||
<Paper className={classes.paper} square>
|
||||
{options.length ? (
|
||||
<>
|
||||
{menuPath.length > 0 && (
|
||||
<MenuItem
|
||||
component="div"
|
||||
{...getItemProps({
|
||||
item: null
|
||||
})}
|
||||
onClick={() =>
|
||||
setMenuPath(
|
||||
menuPath.slice(0, menuPath.length - 2)
|
||||
)
|
||||
}
|
||||
>
|
||||
<ArrowBack className={classes.menuBack} />
|
||||
<FormattedMessage {...buttonMessages.back} />
|
||||
</MenuItem>
|
||||
)}
|
||||
{(menuPath.length
|
||||
? getMenuItemByPath(options, menuPath).children
|
||||
: options
|
||||
).map((suggestion, index) => (
|
||||
<MenuItem
|
||||
key={suggestion.value}
|
||||
component="div"
|
||||
{...getItemProps({ item: suggestion })}
|
||||
onClick={() =>
|
||||
suggestion.value
|
||||
? selectItem(suggestion.value)
|
||||
: setMenuPath([...menuPath, index])
|
||||
}
|
||||
>
|
||||
{suggestion.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<MenuItem disabled component="div">
|
||||
<FormattedMessage defaultMessage="No results" />
|
||||
</MenuItem>
|
||||
)}
|
||||
</Paper>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</Downshift>
|
||||
)}
|
||||
</DebounceAutocomplete>
|
||||
);
|
||||
};
|
||||
AutocompleteSelectMenu.displayName = "AutocompleteSelectMenu";
|
||||
export default AutocompleteSelectMenu;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './AutocompleteSelectMenu';
|
||||
export * from './AutocompleteSelectMenu';
|
||||
export { default } from "./AutocompleteSelectMenu";
|
||||
export * from "./AutocompleteSelectMenu";
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
import IconButton from "@material-ui/core/IconButton";
|
||||
import Menu from "@material-ui/core/Menu";
|
||||
import MenuItem from "@material-ui/core/MenuItem";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import MoreVertIcon from "@material-ui/icons/MoreVert";
|
||||
import React from "react";
|
||||
|
||||
|
@ -23,80 +18,73 @@ export interface CardMenuProps {
|
|||
menuItems: CardMenuItem[];
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
iconButton: {
|
||||
background: theme.palette.background.paper,
|
||||
borderRadius: "100%",
|
||||
height: 32,
|
||||
padding: 0,
|
||||
width: 32
|
||||
}
|
||||
});
|
||||
|
||||
const CardMenu = withStyles(styles, {
|
||||
name: "CardMenu"
|
||||
})(
|
||||
({
|
||||
className,
|
||||
classes,
|
||||
disabled,
|
||||
menuItems
|
||||
}: CardMenuProps & WithStyles<typeof styles>) => {
|
||||
const [anchorEl, setAnchor] = React.useState<HTMLElement | null>(null);
|
||||
|
||||
const handleClick = (event: React.MouseEvent<any>) => {
|
||||
setAnchor(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setAnchor(null);
|
||||
};
|
||||
|
||||
const handleMenuClick = (menuItemIndex: number) => {
|
||||
menuItems[menuItemIndex].onSelect();
|
||||
handleClose();
|
||||
};
|
||||
|
||||
const open = !!anchorEl;
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<IconButton
|
||||
aria-label="More"
|
||||
aria-owns={open ? "long-menu" : null}
|
||||
aria-haspopup="true"
|
||||
className={classes.iconButton}
|
||||
color="primary"
|
||||
disabled={disabled}
|
||||
onClick={handleClick}
|
||||
>
|
||||
<MoreVertIcon />
|
||||
</IconButton>
|
||||
<Menu
|
||||
id="long-menu"
|
||||
anchorEl={anchorEl}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
PaperProps={{
|
||||
style: {
|
||||
maxHeight: ITEM_HEIGHT * 4.5
|
||||
// width: 200
|
||||
}
|
||||
}}
|
||||
>
|
||||
{menuItems.map((menuItem, menuItemIndex) => (
|
||||
<MenuItem
|
||||
onClick={() => handleMenuClick(menuItemIndex)}
|
||||
key={menuItem.label}
|
||||
>
|
||||
{menuItem.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
const useStyles = makeStyles(theme => ({
|
||||
iconButton: {
|
||||
background: theme.palette.background.paper,
|
||||
borderRadius: "100%",
|
||||
height: 32,
|
||||
padding: 0,
|
||||
width: 32
|
||||
}
|
||||
);
|
||||
}));
|
||||
|
||||
const CardMenu: React.FC<CardMenuProps> = props => {
|
||||
const { className, disabled, menuItems } = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
const [anchorEl, setAnchor] = React.useState<HTMLElement | null>(null);
|
||||
|
||||
const handleClick = (event: React.MouseEvent<any>) => {
|
||||
setAnchor(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleClose = () => {
|
||||
setAnchor(null);
|
||||
};
|
||||
|
||||
const handleMenuClick = (menuItemIndex: number) => {
|
||||
menuItems[menuItemIndex].onSelect();
|
||||
handleClose();
|
||||
};
|
||||
|
||||
const open = !!anchorEl;
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
<IconButton
|
||||
aria-label="More"
|
||||
aria-owns={open ? "long-menu" : null}
|
||||
aria-haspopup="true"
|
||||
className={classes.iconButton}
|
||||
color="primary"
|
||||
disabled={disabled}
|
||||
onClick={handleClick}
|
||||
>
|
||||
<MoreVertIcon />
|
||||
</IconButton>
|
||||
<Menu
|
||||
id="long-menu"
|
||||
anchorEl={anchorEl}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
PaperProps={{
|
||||
style: {
|
||||
maxHeight: ITEM_HEIGHT * 4.5
|
||||
// width: 200
|
||||
}
|
||||
}}
|
||||
>
|
||||
{menuItems.map((menuItem, menuItemIndex) => (
|
||||
<MenuItem
|
||||
onClick={() => handleMenuClick(menuItemIndex)}
|
||||
key={menuItem.label}
|
||||
>
|
||||
{menuItem.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
CardMenu.displayName = "CardMenu";
|
||||
export default CardMenu;
|
||||
|
|
|
@ -1,29 +1,25 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import React from "react";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
spacer: {
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
marginTop: theme.spacing.unit
|
||||
},
|
||||
marginTop: theme.spacing.unit * 3
|
||||
}
|
||||
});
|
||||
const useStyles = makeStyles(theme => ({
|
||||
spacer: {
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
marginTop: theme.spacing(1)
|
||||
},
|
||||
marginTop: theme.spacing(3)
|
||||
}
|
||||
}));
|
||||
|
||||
interface CardSpacerProps extends WithStyles<typeof styles> {
|
||||
interface CardSpacerProps {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const CardSpacer = withStyles(styles, { name: "CardSpacer" })(
|
||||
({ classes, children }: CardSpacerProps) => (
|
||||
<div className={classes.spacer}>{children}</div>
|
||||
)
|
||||
);
|
||||
export const CardSpacer: React.FC<CardSpacerProps> = props => {
|
||||
const { children } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return <div className={classes.spacer}>{children}</div>;
|
||||
};
|
||||
CardSpacer.displayName = "CardSpacer";
|
||||
export default CardSpacer;
|
||||
|
|
|
@ -1,42 +1,36 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
children: theme.mixins.gutters({}),
|
||||
constantHeight: {
|
||||
height: 56
|
||||
},
|
||||
hr: {
|
||||
border: "none",
|
||||
borderTop: `1px solid ${theme.overrides.MuiCard.root.borderColor}`,
|
||||
height: 0,
|
||||
marginBottom: 0,
|
||||
marginTop: 0,
|
||||
width: "100%"
|
||||
},
|
||||
root: theme.mixins.gutters({
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
minHeight: 56
|
||||
}),
|
||||
title: {
|
||||
flex: 1,
|
||||
lineHeight: 1
|
||||
},
|
||||
toolbar: {
|
||||
marginRight: -theme.spacing.unit
|
||||
}
|
||||
});
|
||||
const useStyles = makeStyles(theme => ({
|
||||
children: theme.mixins.gutters({}),
|
||||
constantHeight: {
|
||||
height: 56
|
||||
},
|
||||
hr: {
|
||||
border: "none",
|
||||
borderTop: `1px solid ${theme.palette.divider}`,
|
||||
height: 0,
|
||||
marginBottom: 0,
|
||||
marginTop: 0,
|
||||
width: "100%"
|
||||
},
|
||||
root: theme.mixins.gutters({
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
minHeight: 56
|
||||
}),
|
||||
title: {
|
||||
flex: 1,
|
||||
lineHeight: 1
|
||||
},
|
||||
toolbar: {
|
||||
marginRight: -theme.spacing(1)
|
||||
}
|
||||
}));
|
||||
|
||||
interface CardTitleProps extends WithStyles<typeof styles> {
|
||||
interface CardTitleProps {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
height?: "default" | "const";
|
||||
|
@ -45,24 +39,27 @@ interface CardTitleProps extends WithStyles<typeof styles> {
|
|||
onClick?: (event: React.MouseEvent<any>) => void;
|
||||
}
|
||||
|
||||
const CardTitle = withStyles(styles, { name: "CardTitle" })(
|
||||
({
|
||||
classes,
|
||||
const CardTitle: React.FC<CardTitleProps> = props => {
|
||||
const {
|
||||
className,
|
||||
children,
|
||||
height,
|
||||
title,
|
||||
toolbar,
|
||||
onClick,
|
||||
...props
|
||||
}: CardTitleProps) => (
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={classNames(classes.root, {
|
||||
[className]: !!className,
|
||||
[classes.constantHeight]: height === "const"
|
||||
})}
|
||||
{...props}
|
||||
{...rest}
|
||||
>
|
||||
<Typography
|
||||
className={classes.title}
|
||||
|
@ -77,7 +74,7 @@ const CardTitle = withStyles(styles, { name: "CardTitle" })(
|
|||
<div className={classes.children}>{children}</div>
|
||||
<hr className={classes.hr} />
|
||||
</>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
CardTitle.displayName = "CardTitle";
|
||||
export default CardTitle;
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
import { Omit } from "@material-ui/core";
|
||||
import ButtonBase from "@material-ui/core/ButtonBase";
|
||||
import { CheckboxProps as MuiCheckboxProps } from "@material-ui/core/Checkbox";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
@ -25,116 +19,116 @@ export type CheckboxProps = Omit<
|
|||
onChange?: (event: React.ChangeEvent<any>) => void;
|
||||
};
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
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
|
||||
},
|
||||
const useStyles = makeStyles(theme => ({
|
||||
box: {
|
||||
"&$checked": {
|
||||
"&:before": {
|
||||
background: "rgba(0, 0, 0, 0)",
|
||||
content: '""',
|
||||
height: 14,
|
||||
left: -1,
|
||||
position: "absolute",
|
||||
top: -1,
|
||||
transition: theme.transitions.duration.short + "ms",
|
||||
width: 14
|
||||
background: theme.palette.primary.main,
|
||||
color: theme.palette.background.paper,
|
||||
content: '"\\2713"',
|
||||
fontWeight: "bold",
|
||||
textAlign: "center"
|
||||
},
|
||||
|
||||
WebkitAppearance: "none",
|
||||
border: `1px solid ${theme.palette.action.active}`,
|
||||
boxSizing: "border-box",
|
||||
cursor: "pointer",
|
||||
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,
|
||||
outline: "0",
|
||||
position: "relative",
|
||||
userSelect: "none",
|
||||
left: -1,
|
||||
position: "absolute",
|
||||
top: -1,
|
||||
transition: theme.transitions.duration.short + "ms",
|
||||
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
|
||||
}
|
||||
});
|
||||
const Checkbox = withStyles(styles, { name: "Checkbox" })(
|
||||
({
|
||||
|
||||
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
|
||||
}
|
||||
}));
|
||||
const Checkbox: React.FC<CheckboxProps> = props => {
|
||||
const {
|
||||
checked,
|
||||
className,
|
||||
classes,
|
||||
|
||||
disabled,
|
||||
disableClickPropagation,
|
||||
indeterminate,
|
||||
onChange,
|
||||
value,
|
||||
name,
|
||||
...props
|
||||
}: CheckboxProps & WithStyles<typeof styles>) => {
|
||||
const inputRef = React.useRef<HTMLInputElement>(null);
|
||||
const handleClick = React.useCallback(
|
||||
disableClickPropagation
|
||||
? event => {
|
||||
event.stopPropagation();
|
||||
inputRef.current.click();
|
||||
}
|
||||
: () => inputRef.current.click(),
|
||||
[]
|
||||
);
|
||||
...rest
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<ButtonBase
|
||||
{...props}
|
||||
centerRipple
|
||||
className={classNames(classes.root, className)}
|
||||
const inputRef = React.useRef<HTMLInputElement>(null);
|
||||
const handleClick = React.useCallback(
|
||||
disableClickPropagation
|
||||
? event => {
|
||||
event.stopPropagation();
|
||||
inputRef.current.click();
|
||||
}
|
||||
: () => inputRef.current.click(),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<ButtonBase
|
||||
{...rest}
|
||||
centerRipple
|
||||
className={classNames(classes.root, className)}
|
||||
disabled={disabled}
|
||||
onClick={handleClick}
|
||||
>
|
||||
<input
|
||||
className={classNames(classes.box, {
|
||||
[classes.checked]: checked,
|
||||
[classes.disabled]: disabled,
|
||||
[classes.indeterminate]: indeterminate
|
||||
})}
|
||||
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>
|
||||
);
|
||||
}
|
||||
);
|
||||
type="checkbox"
|
||||
name={name}
|
||||
value={checked !== undefined && checked.toString()}
|
||||
ref={inputRef}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</ButtonBase>
|
||||
);
|
||||
};
|
||||
Checkbox.displayName = "Checkbox";
|
||||
export default Checkbox;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './Checkbox';
|
||||
export * from './Checkbox';
|
||||
export { default } from "./Checkbox";
|
||||
export * from "./Checkbox";
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import CloseIcon from "@material-ui/icons/Close";
|
||||
|
@ -16,32 +11,30 @@ export interface ChipProps {
|
|||
onClose?: () => void;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
closeIcon: {
|
||||
cursor: "pointer",
|
||||
fontSize: 16,
|
||||
marginLeft: theme.spacing.unit,
|
||||
verticalAlign: "middle"
|
||||
},
|
||||
label: {
|
||||
color: theme.palette.common.white
|
||||
},
|
||||
root: {
|
||||
background: fade(theme.palette.secondary.main, 0.8),
|
||||
borderRadius: 8,
|
||||
display: "inline-block",
|
||||
marginRight: theme.spacing.unit * 2,
|
||||
padding: "6px 12px"
|
||||
}
|
||||
});
|
||||
const Chip = withStyles(styles, { name: "Chip" })(
|
||||
({
|
||||
classes,
|
||||
className,
|
||||
label,
|
||||
onClose
|
||||
}: ChipProps & WithStyles<typeof styles>) => (
|
||||
const useStyles = makeStyles(theme => ({
|
||||
closeIcon: {
|
||||
cursor: "pointer",
|
||||
fontSize: 16,
|
||||
marginLeft: theme.spacing(),
|
||||
verticalAlign: "middle"
|
||||
},
|
||||
label: {
|
||||
color: theme.palette.common.white
|
||||
},
|
||||
root: {
|
||||
background: fade(theme.palette.secondary.main, 0.8),
|
||||
borderRadius: 8,
|
||||
display: "inline-block",
|
||||
marginRight: theme.spacing(2),
|
||||
padding: "6px 12px"
|
||||
}
|
||||
}));
|
||||
const Chip: React.FC<ChipProps> = props => {
|
||||
const { className, label, onClose } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<div className={classNames(classes.root, className)}>
|
||||
<Typography className={classes.label} variant="caption">
|
||||
{label}
|
||||
|
@ -50,7 +43,7 @@ const Chip = withStyles(styles, { name: "Chip" })(
|
|||
)}
|
||||
</Typography>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
Chip.displayName = "Chip";
|
||||
export default Chip;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './Chip';
|
||||
export * from './Chip';
|
||||
export { default } from "./Chip";
|
||||
export * from "./Chip";
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
|
||||
import Grow from "@material-ui/core/Grow";
|
||||
import Popper from "@material-ui/core/Popper";
|
||||
import { Theme } from "@material-ui/core/styles";
|
||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
||||
import makeStyles from "@material-ui/styles/makeStyles";
|
||||
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||
import React from "react";
|
||||
|
||||
import useStateFromProps from "@saleor/hooks/useStateFromProps";
|
||||
|
@ -26,10 +25,10 @@ export interface ColumnPickerProps
|
|||
}
|
||||
|
||||
const useStyles = makeStyles(
|
||||
(theme: Theme) => ({
|
||||
theme => ({
|
||||
popper: {
|
||||
boxShadow: `0px 5px 10px 0 ${fade(theme.palette.common.black, 0.05)}`,
|
||||
marginTop: theme.spacing.unit * 2,
|
||||
marginTop: theme.spacing(2),
|
||||
zIndex: 1
|
||||
}
|
||||
}),
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import Button from "@material-ui/core/Button";
|
||||
import { Theme } from "@material-ui/core/styles";
|
||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
||||
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||
import ArrowDropDownIcon from "@material-ui/icons/ArrowDropDown";
|
||||
import makeStyles from "@material-ui/styles/makeStyles";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
@ -14,16 +13,16 @@ interface ColumnPickerButtonProps {
|
|||
}
|
||||
|
||||
const useStyles = makeStyles(
|
||||
(theme: Theme) => ({
|
||||
theme => ({
|
||||
icon: {
|
||||
marginLeft: theme.spacing.unit * 2,
|
||||
marginLeft: theme.spacing(2),
|
||||
transition: theme.transitions.duration.short + "ms"
|
||||
},
|
||||
root: {
|
||||
"& span": {
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
paddingRight: theme.spacing.unit
|
||||
paddingRight: theme.spacing(1)
|
||||
},
|
||||
rootActive: {
|
||||
background: fade(theme.palette.primary.main, 0.1)
|
||||
|
|
|
@ -2,9 +2,8 @@ import Button from "@material-ui/core/Button";
|
|||
import Card from "@material-ui/core/Card";
|
||||
import CardContent from "@material-ui/core/CardContent";
|
||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
import { Theme } from "@material-ui/core/styles";
|
||||
import makeStyles from "@material-ui/core/styles/makeStyles";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import makeStyles from "@material-ui/styles/makeStyles";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
import InfiniteScroll from "react-infinite-scroller";
|
||||
|
@ -31,7 +30,7 @@ export interface ColumnPickerContentProps extends Partial<FetchMoreProps> {
|
|||
onSave: () => void;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) => ({
|
||||
const useStyles = makeStyles(theme => ({
|
||||
actionBar: {
|
||||
display: "flex",
|
||||
justifyContent: "space-between"
|
||||
|
@ -41,28 +40,28 @@ const useStyles = makeStyles((theme: Theme) => ({
|
|||
transition: theme.transitions.duration.short + "ms"
|
||||
},
|
||||
cancelButton: {
|
||||
marginRight: theme.spacing.unit * 2
|
||||
marginRight: theme.spacing(2)
|
||||
},
|
||||
content: {
|
||||
display: "grid",
|
||||
gridColumnGap: theme.spacing.unit * 3,
|
||||
gridColumnGap: theme.spacing(3),
|
||||
gridTemplateColumns: "repeat(3, 1fr)",
|
||||
maxHeight: 256,
|
||||
overflowX: "visible",
|
||||
overflowY: "scroll",
|
||||
padding: `${theme.spacing.unit * 2}px ${theme.spacing.unit * 3}px`
|
||||
padding: theme.spacing(2, 3)
|
||||
},
|
||||
contentContainer: {
|
||||
padding: 0
|
||||
},
|
||||
dropShadow: {
|
||||
boxShadow: `0px -5px 10px 0px ${theme.overrides.MuiCard.root.borderColor}`
|
||||
boxShadow: `0px -5px 10px 0px ${theme.palette.divider}`
|
||||
},
|
||||
loadMoreLoaderContainer: {
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
gridColumnEnd: "span 3",
|
||||
height: theme.spacing.unit * 3,
|
||||
height: theme.spacing(3),
|
||||
justifyContent: "center"
|
||||
},
|
||||
root: {
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import { Omit } from "@material-ui/core";
|
||||
import Button, { ButtonProps } from "@material-ui/core/Button";
|
||||
import CircularProgress from "@material-ui/core/CircularProgress";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
WithStyles,
|
||||
withStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import CheckIcon from "@material-ui/icons/Check";
|
||||
import { buttonMessages } from "@saleor/intl";
|
||||
|
|
|
@ -1,35 +1,31 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
[theme.breakpoints.up("lg")]: {
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto",
|
||||
maxWidth: theme.breakpoints.width("lg")
|
||||
},
|
||||
[theme.breakpoints.up("sm")]: {
|
||||
padding: `0 ${theme.spacing.unit * 3}px`
|
||||
},
|
||||
padding: `0 ${theme.spacing.unit}px`
|
||||
}
|
||||
});
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {
|
||||
[theme.breakpoints.up("lg")]: {
|
||||
marginLeft: "auto",
|
||||
marginRight: "auto",
|
||||
maxWidth: theme.breakpoints.width("lg")
|
||||
},
|
||||
[theme.breakpoints.up("sm")]: {
|
||||
padding: theme.spacing(0, 3)
|
||||
},
|
||||
padding: theme.spacing(0, 1)
|
||||
}
|
||||
}));
|
||||
|
||||
interface ContainerProps extends WithStyles<typeof styles> {
|
||||
interface ContainerProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const Container = withStyles(styles, {
|
||||
name: "Container"
|
||||
})(({ classes, className, ...props }: ContainerProps) => (
|
||||
<div className={classNames(classes.root, className)} {...props} />
|
||||
));
|
||||
export const Container: React.FC<ContainerProps> = props => {
|
||||
const { className, ...rest } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return <div className={classNames(classes.root, className)} {...rest} />;
|
||||
};
|
||||
Container.displayName = "Container";
|
||||
export default Container;
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
import { createStyles, Theme, withStyles, WithStyles } from "@material-ui/core";
|
||||
import { makeStyles } from "@material-ui/core";
|
||||
import FormControlLabel from "@material-ui/core/FormControlLabel";
|
||||
import Switch from "@material-ui/core/Switch";
|
||||
import React from "react";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
label: {
|
||||
marginLeft: theme.spacing.unit * 3.5
|
||||
},
|
||||
labelText: {
|
||||
fontSize: 14
|
||||
}
|
||||
});
|
||||
const useStyles = makeStyles(theme => ({
|
||||
label: {
|
||||
marginLeft: theme.spacing(3.5)
|
||||
},
|
||||
labelText: {
|
||||
fontSize: 14
|
||||
}
|
||||
}));
|
||||
|
||||
interface ControlledSwitchProps extends WithStyles<typeof styles> {
|
||||
interface ControlledSwitchProps {
|
||||
checked: boolean;
|
||||
disabled?: boolean;
|
||||
label: string | React.ReactNode;
|
||||
|
@ -23,11 +22,8 @@ interface ControlledSwitchProps extends WithStyles<typeof styles> {
|
|||
onChange?(event: React.ChangeEvent<any>);
|
||||
}
|
||||
|
||||
export const ControlledSwitch = withStyles(styles, {
|
||||
name: "ControlledSwitch"
|
||||
})(
|
||||
({
|
||||
classes,
|
||||
export const ControlledSwitch: React.FC<ControlledSwitchProps> = props => {
|
||||
const {
|
||||
checked,
|
||||
disabled,
|
||||
onChange,
|
||||
|
@ -35,7 +31,11 @@ export const ControlledSwitch = withStyles(styles, {
|
|||
name,
|
||||
secondLabel,
|
||||
uncheckedLabel
|
||||
}: ControlledSwitchProps) => (
|
||||
} = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch
|
||||
|
@ -65,7 +65,7 @@ export const ControlledSwitch = withStyles(styles, {
|
|||
}
|
||||
disabled={disabled}
|
||||
/>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
ControlledSwitch.displayName = "ControlledSwitch";
|
||||
export default ControlledSwitch;
|
||||
|
|
|
@ -2,12 +2,7 @@ import Button from "@material-ui/core/Button";
|
|||
import Card from "@material-ui/core/Card";
|
||||
import CardContent from "@material-ui/core/CardContent";
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Table from "@material-ui/core/Table";
|
||||
import TableBody from "@material-ui/core/TableBody";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
|
@ -32,158 +27,155 @@ export interface CountryListProps {
|
|||
onCountryUnassign: (country: string) => void;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
iconCell: {
|
||||
"&:last-child": {
|
||||
paddingRight: 0
|
||||
},
|
||||
width: 48 + theme.spacing.unit / 2
|
||||
const useStyles = makeStyles(theme => ({
|
||||
iconCell: {
|
||||
"&:last-child": {
|
||||
paddingRight: 0
|
||||
},
|
||||
indicator: {
|
||||
color: theme.palette.text.disabled,
|
||||
display: "inline-block",
|
||||
left: 0,
|
||||
marginRight: theme.spacing.unit * 2,
|
||||
position: "absolute"
|
||||
width: 48 + theme.spacing(2)
|
||||
},
|
||||
indicator: {
|
||||
color: theme.palette.text.disabled,
|
||||
display: "inline-block",
|
||||
left: 0,
|
||||
marginRight: theme.spacing(0.5),
|
||||
position: "absolute"
|
||||
},
|
||||
offsetCell: {
|
||||
"&:first-child": {
|
||||
paddingLeft: theme.spacing(3)
|
||||
},
|
||||
offsetCell: {
|
||||
"&:first-child": {
|
||||
paddingLeft: theme.spacing.unit * 3
|
||||
},
|
||||
position: "relative"
|
||||
position: "relative"
|
||||
},
|
||||
pointer: {
|
||||
cursor: "pointer"
|
||||
},
|
||||
root: {
|
||||
"&:last-child": {
|
||||
paddingBottom: 0
|
||||
},
|
||||
pointer: {
|
||||
cursor: "pointer"
|
||||
},
|
||||
root: {
|
||||
"&:last-child": {
|
||||
paddingBottom: 0
|
||||
},
|
||||
paddingTop: 0
|
||||
},
|
||||
rotate: {
|
||||
transform: "rotate(180deg)"
|
||||
},
|
||||
textRight: {
|
||||
textAlign: "right"
|
||||
},
|
||||
toLeft: {
|
||||
"&:first-child": {
|
||||
paddingLeft: 0
|
||||
}
|
||||
},
|
||||
wideColumn: {
|
||||
width: "100%"
|
||||
paddingTop: 0
|
||||
},
|
||||
rotate: {
|
||||
transform: "rotate(180deg)"
|
||||
},
|
||||
textRight: {
|
||||
textAlign: "right"
|
||||
},
|
||||
toLeft: {
|
||||
"&:first-child": {
|
||||
paddingLeft: 0
|
||||
}
|
||||
});
|
||||
},
|
||||
wideColumn: {
|
||||
width: "100%"
|
||||
}
|
||||
}));
|
||||
|
||||
const CountryList = withStyles(styles, {
|
||||
name: "CountryList"
|
||||
})(
|
||||
({
|
||||
classes,
|
||||
const CountryList: React.FC<CountryListProps> = props => {
|
||||
const {
|
||||
countries,
|
||||
disabled,
|
||||
emptyText,
|
||||
title,
|
||||
onCountryAssign,
|
||||
onCountryUnassign
|
||||
}: CountryListProps & WithStyles<typeof styles>) => {
|
||||
const [isCollapsed, setCollapseStatus] = React.useState(true);
|
||||
const toggleCollapse = () => setCollapseStatus(!isCollapsed);
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={title}
|
||||
toolbar={
|
||||
<Button color="primary" onClick={onCountryAssign}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign countries"
|
||||
description="button"
|
||||
/>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<CardContent className={classes.root}>
|
||||
<Table>
|
||||
<TableBody>
|
||||
<TableRow className={classes.pointer} onClick={toggleCollapse}>
|
||||
<TableCell
|
||||
className={classNames(classes.wideColumn, classes.toLeft)}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="{number} Countries"
|
||||
description="number of countries"
|
||||
values={{
|
||||
number: maybe(() => countries.length.toString(), "...")
|
||||
}}
|
||||
const [isCollapsed, setCollapseStatus] = React.useState(true);
|
||||
const toggleCollapse = () => setCollapseStatus(!isCollapsed);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardTitle
|
||||
title={title}
|
||||
toolbar={
|
||||
<Button color="primary" onClick={onCountryAssign}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Assign countries"
|
||||
description="button"
|
||||
/>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<CardContent className={classes.root}>
|
||||
<Table>
|
||||
<TableBody>
|
||||
<TableRow className={classes.pointer} onClick={toggleCollapse}>
|
||||
<TableCell
|
||||
className={classNames(classes.wideColumn, classes.toLeft)}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="{number} Countries"
|
||||
description="number of countries"
|
||||
values={{
|
||||
number: maybe(() => countries.length.toString(), "...")
|
||||
}}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className={classNames(classes.textRight, classes.iconCell)}
|
||||
>
|
||||
<IconButton>
|
||||
<ArrowDropDownIcon
|
||||
className={classNames({
|
||||
[classes.rotate]: !isCollapsed
|
||||
})}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className={classNames(classes.textRight, classes.iconCell)}
|
||||
>
|
||||
<IconButton>
|
||||
<ArrowDropDownIcon
|
||||
className={classNames({
|
||||
[classes.rotate]: !isCollapsed
|
||||
})}
|
||||
/>
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{!isCollapsed &&
|
||||
renderCollection(
|
||||
countries,
|
||||
(country, countryIndex) => (
|
||||
<TableRow key={country ? country.code : "skeleton"}>
|
||||
<TableCell className={classes.offsetCell}>
|
||||
{maybe<React.ReactNode>(
|
||||
() => (
|
||||
<>
|
||||
{(countryIndex === 0 ||
|
||||
countries[countryIndex].country[0] !==
|
||||
countries[countryIndex - 1].country[0]) && (
|
||||
<span className={classes.indicator}>
|
||||
{country.country[0]}
|
||||
</span>
|
||||
)}
|
||||
{country.country}
|
||||
</>
|
||||
),
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className={classNames(
|
||||
classes.textRight,
|
||||
classes.iconCell
|
||||
)}
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
{!isCollapsed &&
|
||||
renderCollection(
|
||||
countries,
|
||||
(country, countryIndex) => (
|
||||
<TableRow key={country ? country.code : "skeleton"}>
|
||||
<TableCell className={classes.offsetCell}>
|
||||
{maybe<React.ReactNode>(
|
||||
() => (
|
||||
<>
|
||||
{(countryIndex === 0 ||
|
||||
countries[countryIndex].country[0] !==
|
||||
countries[countryIndex - 1].country[0]) && (
|
||||
<span className={classes.indicator}>
|
||||
{country.country[0]}
|
||||
</span>
|
||||
)}
|
||||
{country.country}
|
||||
</>
|
||||
),
|
||||
<Skeleton />
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell
|
||||
className={classNames(
|
||||
classes.textRight,
|
||||
classes.iconCell
|
||||
)}
|
||||
>
|
||||
<IconButton
|
||||
color="primary"
|
||||
disabled={!country || disabled}
|
||||
onClick={() => onCountryUnassign(country.code)}
|
||||
>
|
||||
<IconButton
|
||||
color="primary"
|
||||
disabled={!country || disabled}
|
||||
onClick={() => onCountryUnassign(country.code)}
|
||||
>
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
),
|
||||
() => (
|
||||
<TableRow>
|
||||
<TableCell className={classes.toLeft} colSpan={2}>
|
||||
{emptyText}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
);
|
||||
<DeleteIcon />
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
),
|
||||
() => (
|
||||
<TableRow>
|
||||
<TableCell className={classes.toLeft} colSpan={2}>
|
||||
{emptyText}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
export default CountryList;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React from "react";
|
||||
|
||||
export interface DebounceProps<T> {
|
||||
children: ((props: (...args: T[]) => void) => React.ReactNode);
|
||||
children: (props: (...args: T[]) => void) => React.ReactNode;
|
||||
debounceFn: (...args: T[]) => void;
|
||||
time?: number;
|
||||
}
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './DeleteFilterTabDialog';
|
||||
export * from './DeleteFilterTabDialog';
|
||||
export { default } from "./DeleteFilterTabDialog";
|
||||
export * from "./DeleteFilterTabDialog";
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
import Card from "@material-ui/core/Card";
|
||||
import CardContent from "@material-ui/core/CardContent";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
import TextField, { TextFieldProps } from "@material-ui/core/TextField";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
|
@ -14,38 +9,37 @@ import React from "react";
|
|||
|
||||
import useForm from "@saleor/hooks/useForm";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
card: {
|
||||
border: `1px solid ${theme.overrides.MuiCard.root.borderColor}`
|
||||
},
|
||||
container: {
|
||||
position: "relative"
|
||||
},
|
||||
overlay: {
|
||||
cursor: "pointer",
|
||||
height: "100vh",
|
||||
left: 0,
|
||||
position: "fixed",
|
||||
top: 0,
|
||||
width: "100vw",
|
||||
zIndex: 1
|
||||
},
|
||||
root: {
|
||||
left: 0,
|
||||
minWidth: theme.spacing.unit * 20,
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
width: `calc(100% + ${4 * theme.spacing.unit}px)`,
|
||||
zIndex: 2
|
||||
},
|
||||
text: {
|
||||
cursor: "pointer",
|
||||
fontSize: "0.8125rem"
|
||||
}
|
||||
});
|
||||
const useStyles = makeStyles(theme => ({
|
||||
card: {
|
||||
border: `1px solid ${theme.palette.divider}`
|
||||
},
|
||||
container: {
|
||||
position: "relative"
|
||||
},
|
||||
overlay: {
|
||||
cursor: "pointer",
|
||||
height: "100vh",
|
||||
left: 0,
|
||||
position: "fixed",
|
||||
top: 0,
|
||||
width: "100vw",
|
||||
zIndex: 1
|
||||
},
|
||||
root: {
|
||||
left: 0,
|
||||
minWidth: theme.spacing(20),
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
width: `calc(100% + ${theme.spacing(4)}px)`,
|
||||
zIndex: 2
|
||||
},
|
||||
text: {
|
||||
cursor: "pointer",
|
||||
fontSize: "0.8125rem"
|
||||
}
|
||||
}));
|
||||
|
||||
interface EditableTableCellProps extends WithStyles<typeof styles> {
|
||||
interface EditableTableCellProps {
|
||||
className?: string;
|
||||
defaultValue?: string;
|
||||
focused?: boolean;
|
||||
|
@ -54,54 +48,52 @@ interface EditableTableCellProps extends WithStyles<typeof styles> {
|
|||
onConfirm(value: string): any;
|
||||
}
|
||||
|
||||
export const EditableTableCell = withStyles(styles, {
|
||||
name: "EditableTableCell"
|
||||
})(
|
||||
({
|
||||
classes,
|
||||
export const EditableTableCell: React.FC<EditableTableCellProps> = props => {
|
||||
const {
|
||||
className,
|
||||
defaultValue,
|
||||
focused,
|
||||
InputProps,
|
||||
value,
|
||||
onConfirm
|
||||
}: EditableTableCellProps) => {
|
||||
const handleConfirm = (data: { value: string }) => {
|
||||
disable();
|
||||
onConfirm(data.value);
|
||||
};
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
const [opened, setOpenStatus] = React.useState(focused);
|
||||
const { change, data } = useForm({ value }, [], handleConfirm);
|
||||
const enable = () => setOpenStatus(true);
|
||||
const disable = () => setOpenStatus(false);
|
||||
const handleConfirm = (data: { value: string }) => {
|
||||
disable();
|
||||
onConfirm(data.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<TableCell className={classNames(classes.container, className)}>
|
||||
{opened && <div className={classes.overlay} onClick={disable} />}
|
||||
<Typography variant="caption" onClick={enable} className={classes.text}>
|
||||
{value || defaultValue}
|
||||
</Typography>
|
||||
{opened && (
|
||||
<div className={classes.root}>
|
||||
<Card className={classes.card}>
|
||||
<CardContent>
|
||||
<TextField
|
||||
name="value"
|
||||
autoFocus
|
||||
fullWidth
|
||||
onChange={change}
|
||||
value={data.value}
|
||||
variant="standard"
|
||||
{...InputProps}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)}
|
||||
</TableCell>
|
||||
);
|
||||
}
|
||||
);
|
||||
const [opened, setOpenStatus] = React.useState(focused);
|
||||
const { change, data } = useForm({ value }, [], handleConfirm);
|
||||
const enable = () => setOpenStatus(true);
|
||||
const disable = () => setOpenStatus(false);
|
||||
|
||||
return (
|
||||
<TableCell className={classNames(classes.container, className)}>
|
||||
{opened && <div className={classes.overlay} onClick={disable} />}
|
||||
<Typography variant="caption" onClick={enable} className={classes.text}>
|
||||
{value || defaultValue}
|
||||
</Typography>
|
||||
{opened && (
|
||||
<div className={classes.root}>
|
||||
<Card className={classes.card}>
|
||||
<CardContent>
|
||||
<TextField
|
||||
name="value"
|
||||
autoFocus
|
||||
fullWidth
|
||||
onChange={change}
|
||||
value={data.value}
|
||||
variant="standard"
|
||||
{...InputProps}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
)}
|
||||
</TableCell>
|
||||
);
|
||||
};
|
||||
EditableTableCell.displayName = "EditableTableCell";
|
||||
export default EditableTableCell;
|
||||
|
|
|
@ -13,7 +13,7 @@ const ErrorMessageCard: React.FC<ErrorMessageCardProps> = ({ message }) => (
|
|||
<Typography variant="h5" component="h2">
|
||||
<FormattedMessage defaultMessage="Error" description="header" />
|
||||
</Typography>
|
||||
<Typography variant="body2">{message}</Typography>
|
||||
<Typography variant="body1">{message}</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
import Button from "@material-ui/core/Button";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import React from "react";
|
||||
import SVG from "react-inlinesvg";
|
||||
|
@ -12,57 +7,60 @@ import { FormattedMessage } from "react-intl";
|
|||
|
||||
import notFoundImage from "@assets/images/what.svg";
|
||||
|
||||
export interface ErrorPageProps extends WithStyles<typeof styles> {
|
||||
export interface ErrorPageProps {
|
||||
onBack: () => void;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
bottomHeader: {
|
||||
fontWeight: 600 as 600,
|
||||
textTransform: "uppercase"
|
||||
const useStyles = makeStyles(theme => ({
|
||||
bottomHeader: {
|
||||
fontWeight: 600 as 600,
|
||||
textTransform: "uppercase"
|
||||
},
|
||||
button: {
|
||||
marginTop: theme.spacing(2),
|
||||
padding: 20
|
||||
},
|
||||
container: {
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
gridTemplateColumns: "1fr",
|
||||
padding: theme.spacing(3),
|
||||
width: "100%"
|
||||
},
|
||||
button: {
|
||||
marginTop: theme.spacing.unit * 2,
|
||||
padding: 20
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 487px",
|
||||
margin: "0 auto",
|
||||
width: 830
|
||||
},
|
||||
innerContainer: {
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
order: 1,
|
||||
textAlign: "center"
|
||||
},
|
||||
container: {
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
gridTemplateColumns: "1fr",
|
||||
padding: theme.spacing.unit * 3,
|
||||
width: "100%"
|
||||
},
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 487px",
|
||||
margin: "0 auto",
|
||||
width: 830
|
||||
},
|
||||
innerContainer: {
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
order: 1,
|
||||
textAlign: "center"
|
||||
},
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center"
|
||||
},
|
||||
notFoundImage: {
|
||||
"& svg": {
|
||||
width: "100%"
|
||||
}
|
||||
},
|
||||
root: {
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
height: "calc(100vh - 88px)"
|
||||
},
|
||||
upperHeader: {
|
||||
fontWeight: 600 as 600
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center"
|
||||
},
|
||||
notFoundImage: {
|
||||
"& svg": {
|
||||
width: "100%"
|
||||
}
|
||||
});
|
||||
},
|
||||
root: {
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
height: "calc(100vh - 88px)"
|
||||
},
|
||||
upperHeader: {
|
||||
fontWeight: 600 as 600
|
||||
}
|
||||
}));
|
||||
|
||||
const ErrorPage = withStyles(styles, { name: "NotFoundPage" })(
|
||||
({ classes, onBack }: ErrorPageProps) => (
|
||||
const ErrorPage: React.FC<ErrorPageProps> = props => {
|
||||
const { onBack } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<div className={classes.container}>
|
||||
<div className={classes.innerContainer}>
|
||||
|
@ -99,7 +97,7 @@ const ErrorPage = withStyles(styles, { name: "NotFoundPage" })(
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
ErrorPage.displayName = "ErrorPage";
|
||||
export default ErrorPage;
|
||||
|
|
|
@ -1,55 +1,53 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
action: {
|
||||
flex: "0 0 auto"
|
||||
},
|
||||
grid: {
|
||||
padding: theme.spacing.unit * 2
|
||||
},
|
||||
menuButton: {
|
||||
flex: "0 0 auto",
|
||||
marginLeft: theme.spacing.unit * -2,
|
||||
marginRight: theme.spacing.unit * 3,
|
||||
marginTop: -theme.spacing.unit * 2
|
||||
},
|
||||
root: {
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
marginBottom: theme.spacing.unit * 3
|
||||
},
|
||||
subtitle: {
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
marginBottom: theme.spacing.unit * 2
|
||||
},
|
||||
title: {
|
||||
flex: 1,
|
||||
paddingBottom: theme.spacing.unit * 2
|
||||
}
|
||||
});
|
||||
const useStyles = makeStyles(theme => ({
|
||||
action: {
|
||||
flex: "0 0 auto"
|
||||
},
|
||||
grid: {
|
||||
padding: theme.spacing(2)
|
||||
},
|
||||
menuButton: {
|
||||
flex: "0 0 auto",
|
||||
marginLeft: -theme.spacing(2),
|
||||
marginRight: theme.spacing(3),
|
||||
marginTop: -theme.spacing(2)
|
||||
},
|
||||
root: {
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
marginBottom: theme.spacing(3)
|
||||
},
|
||||
subtitle: {
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
marginBottom: theme.spacing(2)
|
||||
},
|
||||
title: {
|
||||
flex: 1,
|
||||
paddingBottom: theme.spacing(2)
|
||||
}
|
||||
}));
|
||||
|
||||
interface ExtendedPageHeaderProps extends WithStyles<typeof styles> {
|
||||
interface ExtendedPageHeaderProps {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
title?: React.ReactNode;
|
||||
}
|
||||
|
||||
const ExtendedPageHeader = withStyles(styles, { name: "ExtendedPageHeader" })(
|
||||
({ children, classes, className, title }: ExtendedPageHeaderProps) => (
|
||||
const ExtendedPageHeader: React.FC<ExtendedPageHeaderProps> = props => {
|
||||
const { children, className, title } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<div className={classNames(classes.root, className)}>
|
||||
{title}
|
||||
<div className={classes.action}>{children}</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
ExtendedPageHeader.displayName = "ExtendedPageHeader";
|
||||
export default ExtendedPageHeader;
|
||||
|
|
|
@ -1,36 +1,31 @@
|
|||
import { createStyles, withStyles, WithStyles } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Typography, { TypographyProps } from "@material-ui/core/Typography";
|
||||
import React from "react";
|
||||
|
||||
const styles = createStyles({
|
||||
const useStyles = makeStyles({
|
||||
link: {
|
||||
textDecoration: "none"
|
||||
}
|
||||
});
|
||||
|
||||
interface ExternalLinkProps
|
||||
extends React.HTMLProps<HTMLAnchorElement>,
|
||||
WithStyles<typeof styles> {
|
||||
interface ExternalLinkProps extends React.HTMLProps<HTMLAnchorElement> {
|
||||
href: string;
|
||||
className?: string;
|
||||
typographyProps?: TypographyProps;
|
||||
}
|
||||
|
||||
const ExternalLink = withStyles(styles, { name: "ExternalLink" })(
|
||||
({
|
||||
classes,
|
||||
className,
|
||||
children,
|
||||
href,
|
||||
typographyProps,
|
||||
...props
|
||||
}: ExternalLinkProps) => (
|
||||
<a href={href} className={classes.link} {...props}>
|
||||
const ExternalLink: React.FC<ExternalLinkProps> = props => {
|
||||
const { className, children, href, typographyProps, ...rest } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<a href={href} className={classes.link} {...rest}>
|
||||
<Typography className={className} color="primary" {...typographyProps}>
|
||||
{children}
|
||||
</Typography>
|
||||
</a>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
ExternalLink.displayName = "ExternalLink";
|
||||
export default ExternalLink;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import Button from "@material-ui/core/Button";
|
||||
import { createStyles, withStyles, WithStyles } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
const styles = createStyles({
|
||||
const useStyles = makeStyles({
|
||||
fileUploadField: {
|
||||
display: "none"
|
||||
},
|
||||
|
@ -16,15 +16,19 @@ const styles = createStyles({
|
|||
}
|
||||
});
|
||||
|
||||
interface FileUploadProps extends WithStyles<typeof styles> {
|
||||
interface FileUploadProps {
|
||||
disabled?: boolean;
|
||||
name?: string;
|
||||
value?: any;
|
||||
onChange?(event: React.ChangeEvent<any>);
|
||||
}
|
||||
|
||||
const FileUpload = withStyles(styles, { name: "FileUpload" })(
|
||||
({ classes, disabled, name, value, onChange }: FileUploadProps) => (
|
||||
const FileUpload: React.FC<FileUploadProps> = props => {
|
||||
const { disabled, name, value, onChange } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<input
|
||||
disabled={disabled}
|
||||
|
@ -48,7 +52,7 @@ const FileUpload = withStyles(styles, { name: "FileUpload" })(
|
|||
/>
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
FileUpload.displayName = "FileUpload";
|
||||
export default FileUpload;
|
||||
|
|
|
@ -2,12 +2,7 @@ import ButtonBase from "@material-ui/core/ButtonBase";
|
|||
import Grow from "@material-ui/core/Grow";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import Popper from "@material-ui/core/Popper";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import ArrowDropDownIcon from "@material-ui/icons/ArrowDropDown";
|
||||
|
@ -26,130 +21,120 @@ export interface FilterProps<TFilterKeys = string> {
|
|||
onFilterAdd: (filter: FilterContentSubmitData) => void;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
addFilterButton: {
|
||||
"&$filterButton": {
|
||||
"&:hover, &:focus": {
|
||||
backgroundColor: fade(theme.palette.primary.main, 0.1)
|
||||
},
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
border: `1px solid ${theme.palette.primary.main}`,
|
||||
cursor: "pointer",
|
||||
marginBottom: 0,
|
||||
marginRight: theme.spacing.unit * 2,
|
||||
marginTop: 0,
|
||||
transition: theme.transitions.duration.short + "ms"
|
||||
}
|
||||
},
|
||||
addFilterButtonActive: {
|
||||
"&$addFilterButton": {
|
||||
const useStyles = makeStyles(theme => ({
|
||||
addFilterButton: {
|
||||
"&$filterButton": {
|
||||
"&:hover, &:focus": {
|
||||
backgroundColor: fade(theme.palette.primary.main, 0.1)
|
||||
}
|
||||
},
|
||||
addFilterIcon: {
|
||||
transition: theme.transitions.duration.short + "ms"
|
||||
},
|
||||
addFilterText: {
|
||||
color: theme.palette.primary.main,
|
||||
fontSize: 14,
|
||||
fontWeight: 600 as 600,
|
||||
marginRight: 4,
|
||||
textTransform: "uppercase"
|
||||
},
|
||||
filterButton: {
|
||||
alignItems: "center",
|
||||
backgroundColor: fade(theme.palette.primary.main, 0.6),
|
||||
borderRadius: "4px",
|
||||
display: "flex",
|
||||
height: "45px",
|
||||
justifyContent: "space-around",
|
||||
margin: `0 ${theme.spacing.unit * 2}px ${theme.spacing.unit}px`,
|
||||
marginLeft: 0,
|
||||
padding: "0 16px",
|
||||
position: "relative",
|
||||
top: -5
|
||||
},
|
||||
paper: {
|
||||
"& p": {
|
||||
paddingBottom: 10
|
||||
},
|
||||
marginTop: theme.spacing.unit * 2,
|
||||
padding: theme.spacing.unit * 2,
|
||||
width: 240
|
||||
},
|
||||
popover: {
|
||||
zIndex: 1
|
||||
},
|
||||
rotate: {
|
||||
transform: "rotate(180deg)"
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
border: `1px solid ${theme.palette.primary.main}`,
|
||||
cursor: "pointer",
|
||||
marginBottom: 0,
|
||||
marginRight: theme.spacing(2),
|
||||
marginTop: 0,
|
||||
transition: theme.transitions.duration.short + "ms"
|
||||
}
|
||||
});
|
||||
const Filter = withStyles(styles, { name: "Filter" })(
|
||||
({
|
||||
classes,
|
||||
currencySymbol,
|
||||
filterLabel,
|
||||
menu,
|
||||
onFilterAdd
|
||||
}: FilterProps & WithStyles<typeof styles>) => {
|
||||
const anchor = React.useRef<HTMLDivElement>();
|
||||
const [isFilterMenuOpened, setFilterMenuOpened] = React.useState(false);
|
||||
|
||||
return (
|
||||
<div ref={anchor}>
|
||||
<ButtonBase
|
||||
className={classNames(classes.filterButton, classes.addFilterButton, {
|
||||
[classes.addFilterButtonActive]: isFilterMenuOpened
|
||||
})}
|
||||
onClick={() => setFilterMenuOpened(!isFilterMenuOpened)}
|
||||
>
|
||||
<Typography className={classes.addFilterText}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Add Filter"
|
||||
description="button"
|
||||
/>
|
||||
</Typography>
|
||||
<ArrowDropDownIcon
|
||||
color="primary"
|
||||
className={classNames(classes.addFilterIcon, {
|
||||
[classes.rotate]: isFilterMenuOpened
|
||||
})}
|
||||
/>
|
||||
</ButtonBase>
|
||||
<Popper
|
||||
className={classes.popover}
|
||||
open={isFilterMenuOpened}
|
||||
anchorEl={anchor.current}
|
||||
transition
|
||||
disablePortal
|
||||
placement="bottom-start"
|
||||
>
|
||||
{({ TransitionProps, placement }) => (
|
||||
<Grow
|
||||
{...TransitionProps}
|
||||
style={{
|
||||
transformOrigin:
|
||||
placement === "bottom" ? "right top" : "right bottom"
|
||||
}}
|
||||
>
|
||||
<Paper className={classes.paper}>
|
||||
<Typography>{filterLabel}</Typography>
|
||||
<FilterContent
|
||||
currencySymbol={currencySymbol}
|
||||
filters={menu}
|
||||
onSubmit={data => {
|
||||
onFilterAdd(data);
|
||||
setFilterMenuOpened(false);
|
||||
}}
|
||||
/>
|
||||
</Paper>
|
||||
</Grow>
|
||||
)}
|
||||
</Popper>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
addFilterButtonActive: {
|
||||
"&$addFilterButton": {
|
||||
backgroundColor: fade(theme.palette.primary.main, 0.1)
|
||||
}
|
||||
},
|
||||
addFilterIcon: {
|
||||
transition: theme.transitions.duration.short + "ms"
|
||||
},
|
||||
addFilterText: {
|
||||
color: theme.palette.primary.main,
|
||||
fontSize: 14,
|
||||
fontWeight: 600 as 600,
|
||||
marginRight: 4,
|
||||
textTransform: "uppercase"
|
||||
},
|
||||
filterButton: {
|
||||
alignItems: "center",
|
||||
backgroundColor: fade(theme.palette.primary.main, 0.6),
|
||||
borderRadius: "4px",
|
||||
display: "flex",
|
||||
height: 40,
|
||||
justifyContent: "space-around",
|
||||
margin: theme.spacing(2, 1),
|
||||
marginLeft: 0,
|
||||
padding: theme.spacing(0, 2),
|
||||
position: "relative"
|
||||
},
|
||||
paper: {
|
||||
"& p": {
|
||||
paddingBottom: 10
|
||||
},
|
||||
marginTop: theme.spacing(2),
|
||||
padding: theme.spacing(2),
|
||||
width: 240
|
||||
},
|
||||
popover: {
|
||||
zIndex: 1
|
||||
},
|
||||
rotate: {
|
||||
transform: "rotate(180deg)"
|
||||
}
|
||||
);
|
||||
}));
|
||||
const Filter: React.FC<FilterProps> = props => {
|
||||
const { currencySymbol, filterLabel, menu, onFilterAdd } = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
const anchor = React.useRef<HTMLDivElement>();
|
||||
const [isFilterMenuOpened, setFilterMenuOpened] = React.useState(false);
|
||||
|
||||
return (
|
||||
<div ref={anchor}>
|
||||
<ButtonBase
|
||||
className={classNames(classes.filterButton, classes.addFilterButton, {
|
||||
[classes.addFilterButtonActive]: isFilterMenuOpened
|
||||
})}
|
||||
onClick={() => setFilterMenuOpened(!isFilterMenuOpened)}
|
||||
>
|
||||
<Typography className={classes.addFilterText}>
|
||||
<FormattedMessage defaultMessage="Add Filter" description="button" />
|
||||
</Typography>
|
||||
<ArrowDropDownIcon
|
||||
color="primary"
|
||||
className={classNames(classes.addFilterIcon, {
|
||||
[classes.rotate]: isFilterMenuOpened
|
||||
})}
|
||||
/>
|
||||
</ButtonBase>
|
||||
<Popper
|
||||
className={classes.popover}
|
||||
open={isFilterMenuOpened}
|
||||
anchorEl={anchor.current}
|
||||
transition
|
||||
disablePortal
|
||||
placement="bottom-start"
|
||||
>
|
||||
{({ TransitionProps, placement }) => (
|
||||
<Grow
|
||||
{...TransitionProps}
|
||||
style={{
|
||||
transformOrigin:
|
||||
placement === "bottom" ? "right top" : "right bottom"
|
||||
}}
|
||||
>
|
||||
<Paper className={classes.paper}>
|
||||
<Typography>{filterLabel}</Typography>
|
||||
<FilterContent
|
||||
currencySymbol={currencySymbol}
|
||||
filters={menu}
|
||||
onSubmit={data => {
|
||||
onFilterAdd(data);
|
||||
setFilterMenuOpened(false);
|
||||
}}
|
||||
/>
|
||||
</Paper>
|
||||
</Grow>
|
||||
)}
|
||||
</Popper>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Filter.displayName = "Filter";
|
||||
export default Filter;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Theme } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import TextField, { TextFieldProps } from "@material-ui/core/TextField";
|
||||
import { makeStyles } from "@material-ui/styles";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
||||
import { FilterContentSubmitData, IFilter } from "../Filter";
|
||||
|
@ -8,7 +8,7 @@ import Filter from "./Filter";
|
|||
|
||||
const useInputStyles = makeStyles({
|
||||
input: {
|
||||
padding: "10px 12px"
|
||||
padding: "10.5px 12px"
|
||||
},
|
||||
root: {
|
||||
flex: 1
|
||||
|
@ -17,6 +17,7 @@ const useInputStyles = makeStyles({
|
|||
|
||||
const Search: React.FC<TextFieldProps> = props => {
|
||||
const classes = useInputStyles({});
|
||||
|
||||
return (
|
||||
<TextField
|
||||
{...props}
|
||||
|
@ -29,13 +30,14 @@ const Search: React.FC<TextFieldProps> = props => {
|
|||
};
|
||||
|
||||
const useStyles = makeStyles(
|
||||
(theme: Theme) => ({
|
||||
theme => ({
|
||||
actionContainer: {
|
||||
display: "flex",
|
||||
flexWrap: "wrap",
|
||||
padding: `${theme.spacing.unit * 1.5}px ${theme.spacing.unit * 3}px ${
|
||||
theme.spacing.unit
|
||||
}px`
|
||||
padding: theme.spacing(1, 3)
|
||||
},
|
||||
searchOnly: {
|
||||
paddingBottom: theme.spacing(1.5)
|
||||
}
|
||||
}),
|
||||
{
|
||||
|
@ -62,7 +64,7 @@ export const FilterActionsOnlySearch: React.FC<
|
|||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<div className={classes.actionContainer}>
|
||||
<div className={classNames(classes.actionContainer, classes.searchOnly)}>
|
||||
<Search
|
||||
fullWidth
|
||||
placeholder={placeholder}
|
||||
|
|
|
@ -3,7 +3,7 @@ import Typography from "@material-ui/core/Typography";
|
|||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
import { makeStyles } from "@material-ui/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import { getMenuItemByValue, isLeaf, walkToRoot } from "../../utils/menu";
|
||||
import FormSpacer from "../FormSpacer";
|
||||
import SingleSelectField from "../SingleSelectField";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { makeStyles } from "@material-ui/styles";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Theme } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
|
@ -17,7 +16,7 @@ export interface FilterSearchProps extends SearchPageProps {
|
|||
}
|
||||
|
||||
const useStyles = makeStyles(
|
||||
(theme: Theme) => ({
|
||||
theme => ({
|
||||
tabAction: {
|
||||
display: "inline-block"
|
||||
},
|
||||
|
@ -25,8 +24,8 @@ const useStyles = makeStyles(
|
|||
borderBottom: `1px solid ${theme.palette.divider}`,
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
marginTop: theme.spacing.unit,
|
||||
padding: `0 ${theme.spacing.unit * 3}px ${theme.spacing.unit}px`
|
||||
marginTop: theme.spacing(),
|
||||
padding: theme.spacing(0, 1, 3, 1)
|
||||
}
|
||||
}),
|
||||
{
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './FilterBar';
|
||||
export * from './FilterBar';
|
||||
export { default } from "./FilterBar";
|
||||
export * from "./FilterBar";
|
||||
|
|
|
@ -1,27 +1,23 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import React from "react";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
spacer: {
|
||||
marginTop: theme.spacing.unit * 3
|
||||
}
|
||||
});
|
||||
const useStyles = makeStyles(theme => ({
|
||||
spacer: {
|
||||
marginTop: theme.spacing(3)
|
||||
}
|
||||
}));
|
||||
|
||||
interface FormSpacerProps extends WithStyles<typeof styles> {
|
||||
interface FormSpacerProps {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
export const FormSpacer = withStyles(styles, { name: "FormSpacer" })(
|
||||
({ classes, children }: FormSpacerProps) => (
|
||||
<div className={classes.spacer}>{children}</div>
|
||||
)
|
||||
);
|
||||
export const FormSpacer: React.FC<FormSpacerProps> = props => {
|
||||
const { children } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return <div className={classes.spacer}>{children}</div>;
|
||||
};
|
||||
|
||||
FormSpacer.displayName = "FormSpacer";
|
||||
export default FormSpacer;
|
||||
|
|
|
@ -1,43 +1,41 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
||||
export type GridVariant = "default" | "inverted" | "uniform";
|
||||
export interface GridProps extends WithStyles<typeof styles> {
|
||||
export interface GridProps {
|
||||
children: React.ReactNodeArray | React.ReactNode;
|
||||
className?: string;
|
||||
variant?: GridVariant;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
default: {
|
||||
gridTemplateColumns: "9fr 4fr"
|
||||
},
|
||||
inverted: {
|
||||
gridTemplateColumns: "4fr 9fr"
|
||||
},
|
||||
root: {
|
||||
display: "grid",
|
||||
gridColumnGap: theme.spacing.unit * 3 + "px",
|
||||
gridRowGap: theme.spacing.unit * 3 + "px",
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
gridRowGap: theme.spacing.unit + "px",
|
||||
gridTemplateColumns: "1fr"
|
||||
}
|
||||
},
|
||||
uniform: {
|
||||
gridTemplateColumns: "1fr 1fr"
|
||||
const useStyles = makeStyles(theme => ({
|
||||
default: {
|
||||
gridTemplateColumns: "9fr 4fr"
|
||||
},
|
||||
inverted: {
|
||||
gridTemplateColumns: "4fr 9fr"
|
||||
},
|
||||
root: {
|
||||
display: "grid",
|
||||
gridColumnGap: theme.spacing(3),
|
||||
gridRowGap: theme.spacing(3),
|
||||
[theme.breakpoints.down("sm")]: {
|
||||
gridRowGap: theme.spacing(1),
|
||||
gridTemplateColumns: "1fr"
|
||||
}
|
||||
});
|
||||
},
|
||||
uniform: {
|
||||
gridTemplateColumns: "1fr 1fr"
|
||||
}
|
||||
}));
|
||||
|
||||
export const Grid = withStyles(styles, { name: "Grid" })(
|
||||
({ className, children, classes, variant }: GridProps) => (
|
||||
export const Grid: React.FC<GridProps> = props => {
|
||||
const { className, children, variant } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(className, classes.root, {
|
||||
[classes.default]: variant === "default",
|
||||
|
@ -47,8 +45,8 @@ export const Grid = withStyles(styles, { name: "Grid" })(
|
|||
>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
Grid.displayName = "Grid";
|
||||
Grid.defaultProps = {
|
||||
variant: "default"
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
||||
|
@ -11,22 +6,23 @@ interface HrProps {
|
|||
className?: string;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
backgroundColor: theme.overrides.MuiCard.root.borderColor,
|
||||
border: "none",
|
||||
display: "block",
|
||||
height: 1,
|
||||
margin: 0,
|
||||
width: "100%"
|
||||
}
|
||||
});
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {
|
||||
backgroundColor: theme.palette.divider,
|
||||
border: "none",
|
||||
display: "block",
|
||||
height: 1,
|
||||
margin: 0,
|
||||
width: "100%"
|
||||
}
|
||||
}));
|
||||
|
||||
export const Hr = withStyles(styles, { name: "Hr" })(
|
||||
({ className, classes }: HrProps & WithStyles<typeof styles>) => (
|
||||
<hr className={classNames(classes.root, className)} />
|
||||
)
|
||||
);
|
||||
export const Hr: React.FC<HrProps> = props => {
|
||||
const { className } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return <hr className={classNames(classes.root, className)} />;
|
||||
};
|
||||
Hr.displayName = "Hr";
|
||||
export default Hr;
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
import IconButton from "@material-ui/core/IconButton";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
import React from "react";
|
||||
|
||||
|
@ -17,23 +12,26 @@ export interface IconButtonTableCellProps {
|
|||
onClick: () => void;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
"&:last-child": {
|
||||
paddingRight: 0
|
||||
},
|
||||
paddingRight: 0,
|
||||
width: ICONBUTTON_SIZE + theme.spacing.unit / 2
|
||||
}
|
||||
});
|
||||
const IconButtonTableCell = withStyles(styles, { name: "IconButtonTableCell" })(
|
||||
({
|
||||
const useStyles = makeStyles(theme => ({
|
||||
root: {
|
||||
"&:last-child": {
|
||||
paddingRight: 0
|
||||
},
|
||||
paddingRight: 0,
|
||||
width: ICONBUTTON_SIZE + theme.spacing(0.5)
|
||||
}
|
||||
}));
|
||||
const IconButtonTableCell: React.FC<IconButtonTableCellProps> = props => {
|
||||
const {
|
||||
children,
|
||||
classes,
|
||||
|
||||
disabled,
|
||||
onClick
|
||||
}: IconButtonTableCellProps & WithStyles<typeof styles>) => (
|
||||
} = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<TableCell className={classes.root}>
|
||||
<IconButton
|
||||
color="primary"
|
||||
|
@ -43,7 +41,7 @@ const IconButtonTableCell = withStyles(styles, { name: "IconButtonTableCell" })(
|
|||
{children}
|
||||
</IconButton>
|
||||
</TableCell>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
IconButtonTableCell.displayName = "IconButtonTableCell";
|
||||
export default IconButtonTableCell;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './IconButtonTableCell';
|
||||
export * from './IconButtonTableCell';
|
||||
export { default } from "./IconButtonTableCell";
|
||||
export * from "./IconButtonTableCell";
|
||||
|
|
|
@ -1,55 +1,49 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import React from "react";
|
||||
|
||||
import IconButton from "@material-ui/core/IconButton";
|
||||
import DeleteIcon from "@material-ui/icons/Delete";
|
||||
import EditIcon from "@material-ui/icons/Edit";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
image: {
|
||||
height: "100%",
|
||||
objectFit: "contain",
|
||||
userSelect: "none",
|
||||
width: "100%"
|
||||
const useStyles = makeStyles(theme => ({
|
||||
image: {
|
||||
height: "100%",
|
||||
objectFit: "contain",
|
||||
userSelect: "none",
|
||||
width: "100%"
|
||||
},
|
||||
imageContainer: {
|
||||
"&:hover, &.dragged": {
|
||||
"& $imageOverlay": {
|
||||
display: "block"
|
||||
}
|
||||
},
|
||||
imageContainer: {
|
||||
"&:hover, &.dragged": {
|
||||
"& $imageOverlay": {
|
||||
display: "block"
|
||||
}
|
||||
},
|
||||
background: theme.palette.background.paper,
|
||||
border: `1px solid ${theme.overrides.MuiCard.root.borderColor}`,
|
||||
borderRadius: theme.spacing.unit,
|
||||
height: 148,
|
||||
overflow: "hidden",
|
||||
padding: theme.spacing.unit * 2,
|
||||
position: "relative",
|
||||
width: 148
|
||||
},
|
||||
imageOverlay: {
|
||||
background: "rgba(0, 0, 0, 0.6)",
|
||||
cursor: "move",
|
||||
display: "none",
|
||||
height: 148,
|
||||
left: 0,
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
width: 148
|
||||
},
|
||||
imageOverlayToolbar: {
|
||||
display: "flex",
|
||||
justifyContent: "flex-end"
|
||||
}
|
||||
});
|
||||
background: theme.palette.background.paper,
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
borderRadius: theme.spacing(),
|
||||
height: 148,
|
||||
overflow: "hidden",
|
||||
padding: theme.spacing(2),
|
||||
position: "relative",
|
||||
width: 148
|
||||
},
|
||||
imageOverlay: {
|
||||
background: "rgba(0, 0, 0, 0.6)",
|
||||
cursor: "move",
|
||||
display: "none",
|
||||
height: 148,
|
||||
left: 0,
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
width: 148
|
||||
},
|
||||
imageOverlayToolbar: {
|
||||
display: "flex",
|
||||
justifyContent: "flex-end"
|
||||
}
|
||||
}));
|
||||
|
||||
interface ImageTileProps extends WithStyles<typeof styles> {
|
||||
interface ImageTileProps {
|
||||
image: {
|
||||
alt?: string;
|
||||
url: string;
|
||||
|
@ -58,8 +52,12 @@ interface ImageTileProps extends WithStyles<typeof styles> {
|
|||
onImageEdit?: (event: React.ChangeEvent<any>) => void;
|
||||
}
|
||||
|
||||
const ImageTile = withStyles(styles, { name: "ImageTile" })(
|
||||
({ classes, onImageDelete, onImageEdit, image }: ImageTileProps) => (
|
||||
const ImageTile: React.FC<ImageTileProps> = props => {
|
||||
const { onImageDelete, onImageEdit, image } = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<div className={classes.imageContainer} data-tc="product-image">
|
||||
<div className={classes.imageOverlay}>
|
||||
<div className={classes.imageOverlayToolbar}>
|
||||
|
@ -77,7 +75,7 @@ const ImageTile = withStyles(styles, { name: "ImageTile" })(
|
|||
</div>
|
||||
<img className={classes.image} src={image.url} alt={image.alt} />
|
||||
</div>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
ImageTile.displayName = "ImageTile";
|
||||
export default ImageTile;
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import { fade } from "@material-ui/core/styles/colorManipulator";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import classNames from "classnames";
|
||||
|
@ -22,55 +17,58 @@ interface ImageUploadProps {
|
|||
onImageUpload: (file: File) => void;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
containerDragActive: {
|
||||
background: fade(theme.palette.primary.main, 0.1),
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
fileField: {
|
||||
display: "none"
|
||||
},
|
||||
imageContainer: {
|
||||
background: "#ffffff",
|
||||
border: "1px solid #eaeaea",
|
||||
borderRadius: theme.spacing.unit,
|
||||
height: 148,
|
||||
justifySelf: "start",
|
||||
overflow: "hidden",
|
||||
padding: theme.spacing.unit * 2,
|
||||
position: "relative",
|
||||
transition: theme.transitions.duration.standard + "s",
|
||||
width: 148
|
||||
},
|
||||
photosIcon: {
|
||||
height: "64px",
|
||||
margin: "0 auto",
|
||||
width: "64px"
|
||||
},
|
||||
photosIconContainer: {
|
||||
padding: `${theme.spacing.unit * 5}px 0`,
|
||||
textAlign: "center"
|
||||
},
|
||||
uploadText: {
|
||||
color: theme.typography.body2.color,
|
||||
fontSize: 12,
|
||||
fontWeight: 600,
|
||||
textTransform: "uppercase"
|
||||
}
|
||||
});
|
||||
const useStyles = makeStyles(theme => ({
|
||||
containerDragActive: {
|
||||
background: fade(theme.palette.primary.main, 0.1),
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
fileField: {
|
||||
display: "none"
|
||||
},
|
||||
imageContainer: {
|
||||
background: "#ffffff",
|
||||
border: "1px solid #eaeaea",
|
||||
borderRadius: theme.spacing(),
|
||||
height: 148,
|
||||
justifySelf: "start",
|
||||
overflow: "hidden",
|
||||
padding: theme.spacing(2),
|
||||
position: "relative",
|
||||
transition: theme.transitions.duration.standard + "s",
|
||||
width: 148
|
||||
},
|
||||
photosIcon: {
|
||||
height: "64px",
|
||||
margin: "0 auto",
|
||||
width: "64px"
|
||||
},
|
||||
photosIconContainer: {
|
||||
padding: theme.spacing(5, 0),
|
||||
textAlign: "center"
|
||||
},
|
||||
uploadText: {
|
||||
color: theme.typography.body1.color,
|
||||
fontSize: 12,
|
||||
fontWeight: 600,
|
||||
textTransform: "uppercase"
|
||||
}
|
||||
}));
|
||||
|
||||
export const ImageUpload = withStyles(styles, { name: "ImageUpload" })(
|
||||
({
|
||||
export const ImageUpload: React.FC<ImageUploadProps> = props => {
|
||||
const {
|
||||
children,
|
||||
classes,
|
||||
|
||||
className,
|
||||
disableClick,
|
||||
isActiveClassName,
|
||||
iconContainerActiveClassName,
|
||||
iconContainerClassName,
|
||||
onImageUpload
|
||||
}: ImageUploadProps & WithStyles<typeof styles>) => (
|
||||
} = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<Dropzone
|
||||
disableClick={disableClick}
|
||||
onDrop={files => onImageUpload(files[0])}
|
||||
|
@ -107,7 +105,7 @@ export const ImageUpload = withStyles(styles, { name: "ImageUpload" })(
|
|||
</>
|
||||
)}
|
||||
</Dropzone>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
ImageUpload.displayName = "ImageUpload";
|
||||
export default ImageUpload;
|
||||
|
|
|
@ -5,12 +5,7 @@ import MenuItem from "@material-ui/core/MenuItem";
|
|||
import Menu from "@material-ui/core/MenuList";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import Popper from "@material-ui/core/Popper";
|
||||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import ArrowDropDown from "@material-ui/icons/ArrowDropDown";
|
||||
import classNames from "classnames";
|
||||
|
@ -26,109 +21,104 @@ export interface LanguageSwitchProps {
|
|||
onLanguageChange: (lang: LanguageCodeEnum) => void;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
arrow: {
|
||||
color: theme.palette.primary.main,
|
||||
transition: theme.transitions.duration.standard + "ms"
|
||||
},
|
||||
container: {
|
||||
paddingBottom: theme.spacing.unit
|
||||
},
|
||||
menuContainer: {
|
||||
cursor: "pointer",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
minWidth: 90,
|
||||
padding: theme.spacing.unit,
|
||||
position: "relative"
|
||||
},
|
||||
menuItem: {
|
||||
textAlign: "justify"
|
||||
},
|
||||
menuPaper: {
|
||||
maxHeight: `calc(100vh - ${theme.spacing.unit * 2}px)`,
|
||||
overflow: "scroll"
|
||||
},
|
||||
popover: {
|
||||
zIndex: 1
|
||||
},
|
||||
rotate: {
|
||||
transform: "rotate(180deg)"
|
||||
}
|
||||
});
|
||||
const LanguageSwitch = withStyles(styles, { name: "LanguageSwitch" })(
|
||||
({
|
||||
classes,
|
||||
currentLanguage,
|
||||
languages,
|
||||
onLanguageChange
|
||||
}: LanguageSwitchProps & WithStyles<typeof styles>) => {
|
||||
const [isExpanded, setExpandedState] = React.useState(false);
|
||||
const anchor = React.useRef();
|
||||
|
||||
return (
|
||||
<div className={classes.container} ref={anchor}>
|
||||
<Card
|
||||
className={classes.menuContainer}
|
||||
onClick={() => setExpandedState(!isExpanded)}
|
||||
>
|
||||
<Typography>{currentLanguage}</Typography>
|
||||
<ArrowDropDown
|
||||
className={classNames(classes.arrow, {
|
||||
[classes.rotate]: isExpanded
|
||||
})}
|
||||
/>
|
||||
</Card>
|
||||
<Popper
|
||||
className={classes.popover}
|
||||
open={isExpanded}
|
||||
anchorEl={anchor.current}
|
||||
transition
|
||||
disablePortal
|
||||
placement="bottom-end"
|
||||
>
|
||||
{({ TransitionProps, placement }) => (
|
||||
<Grow
|
||||
{...TransitionProps}
|
||||
style={{
|
||||
transformOrigin:
|
||||
placement === "bottom" ? "right top" : "right bottom"
|
||||
}}
|
||||
>
|
||||
<Paper className={classes.menuPaper}>
|
||||
<ClickAwayListener
|
||||
onClickAway={() => setExpandedState(false)}
|
||||
mouseEvent="onClick"
|
||||
>
|
||||
{languages.map(lang => (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
className={classes.menuItem}
|
||||
onClick={() => {
|
||||
setExpandedState(false);
|
||||
onLanguageChange(lang.code);
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="{languageName} - {languageCode}"
|
||||
description="button"
|
||||
values={{
|
||||
languageCode: lang.code,
|
||||
languageName: lang.language
|
||||
}}
|
||||
/>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
))}
|
||||
</ClickAwayListener>
|
||||
</Paper>
|
||||
</Grow>
|
||||
)}
|
||||
</Popper>
|
||||
</div>
|
||||
);
|
||||
const useStyles = makeStyles(theme => ({
|
||||
arrow: {
|
||||
color: theme.palette.primary.main,
|
||||
transition: theme.transitions.duration.standard + "ms"
|
||||
},
|
||||
container: {
|
||||
paddingBottom: theme.spacing(1)
|
||||
},
|
||||
menuContainer: {
|
||||
cursor: "pointer",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
minWidth: 90,
|
||||
padding: theme.spacing(),
|
||||
position: "relative"
|
||||
},
|
||||
menuItem: {
|
||||
textAlign: "justify"
|
||||
},
|
||||
menuPaper: {
|
||||
maxHeight: `calc(100vh - ${theme.spacing(2)}px)`,
|
||||
overflow: "scroll"
|
||||
},
|
||||
popover: {
|
||||
zIndex: 1
|
||||
},
|
||||
rotate: {
|
||||
transform: "rotate(180deg)"
|
||||
}
|
||||
);
|
||||
}));
|
||||
const LanguageSwitch: React.FC<LanguageSwitchProps> = props => {
|
||||
const { currentLanguage, languages, onLanguageChange } = props;
|
||||
const classes = useStyles(props);
|
||||
|
||||
const [isExpanded, setExpandedState] = React.useState(false);
|
||||
const anchor = React.useRef();
|
||||
|
||||
return (
|
||||
<div className={classes.container} ref={anchor}>
|
||||
<Card
|
||||
className={classes.menuContainer}
|
||||
onClick={() => setExpandedState(!isExpanded)}
|
||||
>
|
||||
<Typography>{currentLanguage}</Typography>
|
||||
<ArrowDropDown
|
||||
className={classNames(classes.arrow, {
|
||||
[classes.rotate]: isExpanded
|
||||
})}
|
||||
/>
|
||||
</Card>
|
||||
<Popper
|
||||
className={classes.popover}
|
||||
open={isExpanded}
|
||||
anchorEl={anchor.current}
|
||||
transition
|
||||
disablePortal
|
||||
placement="bottom-end"
|
||||
>
|
||||
{({ TransitionProps, placement }) => (
|
||||
<Grow
|
||||
{...TransitionProps}
|
||||
style={{
|
||||
transformOrigin:
|
||||
placement === "bottom" ? "right top" : "right bottom"
|
||||
}}
|
||||
>
|
||||
<Paper className={classes.menuPaper}>
|
||||
<ClickAwayListener
|
||||
onClickAway={() => setExpandedState(false)}
|
||||
mouseEvent="onClick"
|
||||
>
|
||||
{languages.map(lang => (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
className={classes.menuItem}
|
||||
onClick={() => {
|
||||
setExpandedState(false);
|
||||
onLanguageChange(lang.code);
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
defaultMessage="{languageName} - {languageCode}"
|
||||
description="button"
|
||||
values={{
|
||||
languageCode: lang.code,
|
||||
languageName: lang.language
|
||||
}}
|
||||
/>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
))}
|
||||
</ClickAwayListener>
|
||||
</Paper>
|
||||
</Grow>
|
||||
)}
|
||||
</Popper>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
LanguageSwitch.displayName = "LanguageSwitch";
|
||||
export default LanguageSwitch;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './LanguageSwitch';
|
||||
export * from './LanguageSwitch';
|
||||
export { default } from "./LanguageSwitch";
|
||||
export * from "./LanguageSwitch";
|
||||
|
|
|
@ -1,49 +1,44 @@
|
|||
import {
|
||||
createStyles,
|
||||
Theme,
|
||||
withStyles,
|
||||
WithStyles
|
||||
} from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/core/styles";
|
||||
import Typography, { TypographyProps } from "@material-ui/core/Typography";
|
||||
import classNames from "classnames";
|
||||
import React from "react";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
primary: {
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
root: {
|
||||
cursor: "pointer",
|
||||
display: "inline"
|
||||
},
|
||||
secondary: {
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
underline: {
|
||||
textDecoration: "underline"
|
||||
}
|
||||
});
|
||||
const useStyles = makeStyles(theme => ({
|
||||
primary: {
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
root: {
|
||||
cursor: "pointer",
|
||||
display: "inline"
|
||||
},
|
||||
secondary: {
|
||||
color: theme.palette.primary.main
|
||||
},
|
||||
underline: {
|
||||
textDecoration: "underline"
|
||||
}
|
||||
}));
|
||||
|
||||
interface LinkProps
|
||||
extends React.AnchorHTMLAttributes<HTMLAnchorElement>,
|
||||
WithStyles<typeof styles> {
|
||||
interface LinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
||||
color?: "primary" | "secondary";
|
||||
underline?: boolean;
|
||||
typographyProps?: TypographyProps;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
const Link = withStyles(styles, { name: "Link" })(
|
||||
({
|
||||
classes,
|
||||
const Link: React.FC<LinkProps> = props => {
|
||||
const {
|
||||
className,
|
||||
children,
|
||||
color = "primary",
|
||||
underline = false,
|
||||
onClick,
|
||||
...linkProps
|
||||
}: LinkProps) => (
|
||||
} = props;
|
||||
|
||||
const classes = useStyles(props);
|
||||
|
||||
return (
|
||||
<Typography
|
||||
component="a"
|
||||
className={classNames({
|
||||
|
@ -59,7 +54,7 @@ const Link = withStyles(styles, { name: "Link" })(
|
|||
>
|
||||
{children}
|
||||
</Typography>
|
||||
)
|
||||
);
|
||||
);
|
||||
};
|
||||
Link.displayName = "Link";
|
||||
export default Link;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { Omit } from "@material-ui/core";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import {
|
||||
createStyles,
|
||||
|
@ -20,10 +19,10 @@ interface ListFieldState {
|
|||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
chip: {
|
||||
marginBottom: theme.spacing.unit
|
||||
marginBottom: theme.spacing(1)
|
||||
},
|
||||
chipContainer: {
|
||||
marginTop: theme.spacing.unit * 2,
|
||||
marginTop: theme.spacing(2),
|
||||
width: 552
|
||||
}
|
||||
});
|
||||
|
|
|
@ -2,15 +2,13 @@ import React from "react";
|
|||
|
||||
interface MenuToggleProps {
|
||||
ariaOwns?: string;
|
||||
children: ((
|
||||
props: {
|
||||
actions: {
|
||||
open: () => void;
|
||||
close: () => void;
|
||||
};
|
||||
open: boolean;
|
||||
}
|
||||
) => React.ReactElement<any>);
|
||||
children: (props: {
|
||||
actions: {
|
||||
open: () => void;
|
||||
close: () => void;
|
||||
};
|
||||
open: boolean;
|
||||
}) => React.ReactElement<any>;
|
||||
}
|
||||
|
||||
interface MenuToggleState {
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import Money from "./Money";
|
||||
import { IMoney } from "./Money";
|
||||
|
||||
export { default } from "./Money";
|
||||
export * from "./Money";
|
||||
|
||||
export function addMoney(init: Money, ...args: Money[]): Money {
|
||||
export function addMoney(init: IMoney, ...args: IMoney[]): IMoney {
|
||||
return {
|
||||
amount: args.reduce((acc, curr) => acc + curr.amount, init.amount),
|
||||
currency: init.currency
|
||||
};
|
||||
}
|
||||
export function subtractMoney(init: Money, ...args: Money[]): Money {
|
||||
export function subtractMoney(init: IMoney, ...args: IMoney[]): IMoney {
|
||||
return {
|
||||
amount: args.reduce((acc, curr) => acc - curr.amount, init.amount),
|
||||
currency: init.currency
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from "react";
|
|||
import { useIntl } from "react-intl";
|
||||
|
||||
import { LocaleConsumer } from "../Locale";
|
||||
import IMoney from "../Money";
|
||||
import { IMoney } from "../Money";
|
||||
|
||||
export interface MoneyRangeProps {
|
||||
from?: IMoney;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { default } from './MoneyRange';
|
||||
export * from './MoneyRange';
|
||||
export { default } from "./MoneyRange";
|
||||
export * from "./MoneyRange";
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue