diff --git a/.changeset/angry-jeans-battle.md b/.changeset/angry-jeans-battle.md
deleted file mode 100644
index 438fbf6dfe9..00000000000
--- a/.changeset/angry-jeans-battle.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-E2E Fixing flaky navigation tests
diff --git a/.changeset/angry-lemons-wave.md b/.changeset/angry-lemons-wave.md
deleted file mode 100644
index 063124e826d..00000000000
--- a/.changeset/angry-lemons-wave.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Adding CodeInspector plugin
diff --git a/.changeset/beige-ducks-matter.md b/.changeset/beige-ducks-matter.md
deleted file mode 100644
index 628409d8377..00000000000
--- a/.changeset/beige-ducks-matter.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Now you can see columns and their ordering that you previously selected when swtich betetween listing pages.
diff --git a/.changeset/beige-moose-greet.md b/.changeset/beige-moose-greet.md
deleted file mode 100644
index 0c96fc86c31..00000000000
--- a/.changeset/beige-moose-greet.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Product edition no longer change the others work when changing different fields simultaneously. This means UI sends only form fields that were changed.
diff --git a/.changeset/big-beds-bathe.md b/.changeset/big-beds-bathe.md
deleted file mode 100644
index 93157702d09..00000000000
--- a/.changeset/big-beds-bathe.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-The legacy multiselect are not longer present within the codebase. this means you should use the ones from new macaw when developing the UI
diff --git a/.changeset/bright-ants-obey.md b/.changeset/bright-ants-obey.md
deleted file mode 100644
index 2a4bc75b2e5..00000000000
--- a/.changeset/bright-ants-obey.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Login via API in order to setup playwright tests is working in serial mode
diff --git a/.changeset/bright-phones-agree.md b/.changeset/bright-phones-agree.md
deleted file mode 100644
index 3ac4b282dc5..00000000000
--- a/.changeset/bright-phones-agree.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Add tests for thirdparty apps
diff --git a/.changeset/bright-tips-hang.md b/.changeset/bright-tips-hang.md
deleted file mode 100644
index e108c53cc01..00000000000
--- a/.changeset/bright-tips-hang.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Swap new refund with with old one when feature flag toggle
diff --git a/.changeset/brown-mayflies-check.md b/.changeset/brown-mayflies-check.md
deleted file mode 100644
index f22d8a52943..00000000000
--- a/.changeset/brown-mayflies-check.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-E2E tests for customer CRUD
diff --git a/.changeset/calm-mice-stare.md b/.changeset/calm-mice-stare.md
deleted file mode 100644
index 0dd0620c692..00000000000
--- a/.changeset/calm-mice-stare.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Manual transaction modal has now improved design that matches other modals.
diff --git a/.changeset/chatty-forks-vanish.md b/.changeset/chatty-forks-vanish.md
deleted file mode 100644
index 085e28f5896..00000000000
--- a/.changeset/chatty-forks-vanish.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-You can now see Marketplace app list on automation deployment.
diff --git a/.changeset/cold-grapes-compete.md b/.changeset/cold-grapes-compete.md
deleted file mode 100644
index b6306983ea7..00000000000
--- a/.changeset/cold-grapes-compete.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Adding e2e tests for promotion CRUD
diff --git a/.changeset/cold-wasps-repeat.md b/.changeset/cold-wasps-repeat.md
deleted file mode 100644
index 0900a7c4473..00000000000
--- a/.changeset/cold-wasps-repeat.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Now selected columns on the product list are being saved when browsing order details.
diff --git a/.changeset/cold-waves-joke.md b/.changeset/cold-waves-joke.md
deleted file mode 100644
index 1c0c84500de..00000000000
--- a/.changeset/cold-waves-joke.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Migrate dashboard to new font tokens
diff --git a/.changeset/cool-beers-rule.md b/.changeset/cool-beers-rule.md
deleted file mode 100644
index 4fd1cb2e050..00000000000
--- a/.changeset/cool-beers-rule.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fix flaky test - TC: SALEOR_3 Create basic product with variant
diff --git a/.changeset/cool-doors-drum.md b/.changeset/cool-doors-drum.md
deleted file mode 100644
index 53dd3178b9d..00000000000
--- a/.changeset/cool-doors-drum.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-You can now run e2e tests without flakiness
diff --git a/.changeset/cool-lizards-compete.md b/.changeset/cool-lizards-compete.md
deleted file mode 100644
index f5a15f09d72..00000000000
--- a/.changeset/cool-lizards-compete.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Replace back icon with cloud one in sidebar return to cloud link, update copy to just Saleor Cloud
diff --git a/.changeset/dirty-adults-rush.md b/.changeset/dirty-adults-rush.md
deleted file mode 100644
index 0d31e5442d8..00000000000
--- a/.changeset/dirty-adults-rush.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Fix building docker image after move service worker to assets dir
diff --git a/.changeset/dry-geckos-laugh.md b/.changeset/dry-geckos-laugh.md
deleted file mode 100644
index ed41cc18c11..00000000000
--- a/.changeset/dry-geckos-laugh.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Now, the developer can access sidebar components on each page directly.
diff --git a/.changeset/dry-tigers-worry.md b/.changeset/dry-tigers-worry.md
deleted file mode 100644
index 0e744f169e9..00000000000
--- a/.changeset/dry-tigers-worry.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Introduces new refund flow for orders that allow users to refund items base on transactions. Grant refund and send refund is a single flow. User first has to create draft refund and then can transfer funds in one flow.
diff --git a/.changeset/dull-jobs-sneeze.md b/.changeset/dull-jobs-sneeze.md
deleted file mode 100644
index 5932bd487c3..00000000000
--- a/.changeset/dull-jobs-sneeze.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-The list of transactions is now placed under the new section called "Transactions" when you visit order details page
\ No newline at end of file
diff --git a/.changeset/early-vans-relate.md b/.changeset/early-vans-relate.md
deleted file mode 100644
index c84b13edc81..00000000000
--- a/.changeset/early-vans-relate.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-You can now run e2e test for a manual refund type
diff --git a/.changeset/eight-pillows-fly.md b/.changeset/eight-pillows-fly.md
deleted file mode 100644
index 51cf228fbd7..00000000000
--- a/.changeset/eight-pillows-fly.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Order Refund views no longer display duplicated errors or no errors at all when submitting the form.
diff --git a/.changeset/eighty-insects-repeat.md b/.changeset/eighty-insects-repeat.md
deleted file mode 100644
index da8c4cc11b2..00000000000
--- a/.changeset/eighty-insects-repeat.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-You can now run E2E Playwright tests for staff members CRUD
diff --git a/.changeset/eighty-years-exercise.md b/.changeset/eighty-years-exercise.md
deleted file mode 100644
index 67cc13811cb..00000000000
--- a/.changeset/eighty-years-exercise.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-You can now browse listing pages without additional reloadings
diff --git a/.changeset/fair-brooms-drop.md b/.changeset/fair-brooms-drop.md
deleted file mode 100644
index 1688670bf94..00000000000
--- a/.changeset/fair-brooms-drop.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-This change adds a reusable GridTable component for ephemeral data edition.
diff --git a/.changeset/famous-bikes-check.md b/.changeset/famous-bikes-check.md
deleted file mode 100644
index 7352cf794a8..00000000000
--- a/.changeset/famous-bikes-check.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-You can no longer see a duplicated cancel button when canceling the transaction. This means you now can go back to edition by using "back" button and "cancel" to continue your intention
diff --git a/.changeset/famous-grapes-stare.md b/.changeset/famous-grapes-stare.md
deleted file mode 100644
index 2b546a10ffb..00000000000
--- a/.changeset/famous-grapes-stare.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Remove brackets next to each order status title due to cause confusing for the clients
diff --git a/.changeset/famous-pigs-camp.md b/.changeset/famous-pigs-camp.md
deleted file mode 100644
index 7e36970c5b0..00000000000
--- a/.changeset/famous-pigs-camp.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Fixes a bug where order and gift card details views show incorrect avatar in history component. Notes added by apps will now show app's name and avatar. All events will now use the same date format to improve consistency.
diff --git a/.changeset/few-crabs-guess.md b/.changeset/few-crabs-guess.md
deleted file mode 100644
index dbddd03b47c..00000000000
--- a/.changeset/few-crabs-guess.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-The selected value is no longer filtering the options when using any select list with autocomplete
diff --git a/.changeset/few-pots-relate.md b/.changeset/few-pots-relate.md
deleted file mode 100644
index 6296b27af66..00000000000
--- a/.changeset/few-pots-relate.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Fix showing empty tooltip when no content by bumping macaw-ui to newest
diff --git a/.changeset/fifty-gifts-join.md b/.changeset/fifty-gifts-join.md
deleted file mode 100644
index fd4c1b3b25b..00000000000
--- a/.changeset/fifty-gifts-join.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Adding tests for promotion rules CRUD
diff --git a/.changeset/fluffy-dryers-learn.md b/.changeset/fluffy-dryers-learn.md
deleted file mode 100644
index 3266c7588e9..00000000000
--- a/.changeset/fluffy-dryers-learn.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-You can now create refund with lines even if all lines have been previously refunded.
diff --git a/.changeset/forty-lobsters-give.md b/.changeset/forty-lobsters-give.md
deleted file mode 100644
index 471a6739c64..00000000000
--- a/.changeset/forty-lobsters-give.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Dashboard will now allow to set publication date and availability date with time. This change also replaces deprecated date fileds with datetime fields.
diff --git a/.changeset/four-humans-reply.md b/.changeset/four-humans-reply.md
deleted file mode 100644
index ff579708d67..00000000000
--- a/.changeset/four-humans-reply.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-The API_URI is no longer used across the codebase. API_URI stays in workflows for backward compatibility
diff --git a/.changeset/friendly-bats-wonder.md b/.changeset/friendly-bats-wonder.md
deleted file mode 100644
index 290ec7b400d..00000000000
--- a/.changeset/friendly-bats-wonder.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Always show charge and authorized amount in payment section of order details
diff --git a/.changeset/funny-moles-design.md b/.changeset/funny-moles-design.md
deleted file mode 100644
index d6e1860bee6..00000000000
--- a/.changeset/funny-moles-design.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Cypress tests are no longer possible to be executed
\ No newline at end of file
diff --git a/.changeset/gentle-mice-move.md b/.changeset/gentle-mice-move.md
deleted file mode 100644
index 494af1fb81d..00000000000
--- a/.changeset/gentle-mice-move.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-This change disallows creating refund for orders created in transaction flow channels that have no transactions, as well as orders that have no refundable transactions
diff --git a/.changeset/giant-dancers-raise.md b/.changeset/giant-dancers-raise.md
deleted file mode 100644
index f875e76f5e4..00000000000
--- a/.changeset/giant-dancers-raise.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Read-only metadata keys and values will now be displayed as regular inputs, making them easier to read and preventing them from looking disabled.
diff --git a/.changeset/giant-students-pull.md b/.changeset/giant-students-pull.md
deleted file mode 100644
index 532d01b1894..00000000000
--- a/.changeset/giant-students-pull.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Allow to manually override number of shards to use during manual re-runs
diff --git a/.changeset/gold-masks-explain.md b/.changeset/gold-masks-explain.md
deleted file mode 100644
index 41aa95557a1..00000000000
--- a/.changeset/gold-masks-explain.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Refund add dialog no longer allows proceeding to refund with lines view when all lines have been refunded and manual refund view when user doesn't have payment permissions.
diff --git a/.changeset/good-crabs-repair.md b/.changeset/good-crabs-repair.md
deleted file mode 100644
index cb1ea20b984..00000000000
--- a/.changeset/good-crabs-repair.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-You can now select created at column in product list
diff --git a/.changeset/great-bottles-retire.md b/.changeset/great-bottles-retire.md
deleted file mode 100644
index 8c4787b840b..00000000000
--- a/.changeset/great-bottles-retire.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Refactoring playwright setup file and moving auth specs
diff --git a/.changeset/green-starfishes-raise.md b/.changeset/green-starfishes-raise.md
deleted file mode 100644
index 0b8a3806b92..00000000000
--- a/.changeset/green-starfishes-raise.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Transaction titles in order details now include its ordinal number and creation date. This means that all titles now follow the same format.
diff --git a/.changeset/grumpy-laws-leave.md b/.changeset/grumpy-laws-leave.md
deleted file mode 100644
index d001c7e116f..00000000000
--- a/.changeset/grumpy-laws-leave.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Modal for refund reason now has an improved copy
diff --git a/.changeset/itchy-queens-sit.md b/.changeset/itchy-queens-sit.md
deleted file mode 100644
index be18c7e3666..00000000000
--- a/.changeset/itchy-queens-sit.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Fix showing empty price when value is zero
-Improve showing discount type in order payment details
diff --git a/.changeset/khaki-shrimps-play.md b/.changeset/khaki-shrimps-play.md
deleted file mode 100644
index 599feaea49d..00000000000
--- a/.changeset/khaki-shrimps-play.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-App and User avatars in order details now all have the same color.
diff --git a/.changeset/kind-dolphins-dance.md b/.changeset/kind-dolphins-dance.md
deleted file mode 100644
index bc6dd750f37..00000000000
--- a/.changeset/kind-dolphins-dance.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Grid peersistance implementation
diff --git a/.changeset/lemon-bats-repeat.md b/.changeset/lemon-bats-repeat.md
deleted file mode 100644
index 109b55eea0b..00000000000
--- a/.changeset/lemon-bats-repeat.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-You can now open issue gift card modal without any flickering
diff --git a/.changeset/little-seals-happen.md b/.changeset/little-seals-happen.md
deleted file mode 100644
index ba4160996ea..00000000000
--- a/.changeset/little-seals-happen.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Adding prettier for code formatting
diff --git a/.changeset/little-singers-brake.md b/.changeset/little-singers-brake.md
deleted file mode 100644
index 7bbf5ad411b..00000000000
--- a/.changeset/little-singers-brake.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fixing flaky tests - TC: SALEOR_32 and TC: SALEOR_33
diff --git a/.changeset/long-countries-kneel.md b/.changeset/long-countries-kneel.md
deleted file mode 100644
index 5799179391d..00000000000
--- a/.changeset/long-countries-kneel.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Refund with lines view no longer allows creating/editing a refund with amount exceeding charged amount for selected transaction
diff --git a/.changeset/long-keys-compare.md b/.changeset/long-keys-compare.md
deleted file mode 100644
index e368e85fae5..00000000000
--- a/.changeset/long-keys-compare.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Changed trigger to workflow_dispatch and switched from issues to pr as a source of metrics
diff --git a/.changeset/loud-rice-hug.md b/.changeset/loud-rice-hug.md
deleted file mode 100644
index 20b85f37568..00000000000
--- a/.changeset/loud-rice-hug.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Fix product list crash when description contains empty object
-Improve description by removing html tags and
diff --git a/.changeset/lovely-deers-cross.md b/.changeset/lovely-deers-cross.md
deleted file mode 100644
index f1d7c1a2524..00000000000
--- a/.changeset/lovely-deers-cross.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Manipulating timeouts of Playwright tests
diff --git a/.changeset/lovely-hairs-smell.md b/.changeset/lovely-hairs-smell.md
deleted file mode 100644
index fd636ebcb43..00000000000
--- a/.changeset/lovely-hairs-smell.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-The boolean attribute has been changed from a toggle to a select. This change helps visualize when the attribute has not been set.
diff --git a/.changeset/lucky-cameras-taste.md b/.changeset/lucky-cameras-taste.md
deleted file mode 100644
index 0a21be3f862..00000000000
--- a/.changeset/lucky-cameras-taste.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-You can now properly edit permission groups when you have full access
diff --git a/.changeset/many-deers-brush.md b/.changeset/many-deers-brush.md
deleted file mode 100644
index f8345824c52..00000000000
--- a/.changeset/many-deers-brush.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Warning message on manual refund view is no longer unreadable on dark mode
diff --git a/.changeset/many-vans-itch.md b/.changeset/many-vans-itch.md
deleted file mode 100644
index 3565732a720..00000000000
--- a/.changeset/many-vans-itch.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Implement refund add modal
diff --git a/.changeset/many-years-care.md b/.changeset/many-years-care.md
deleted file mode 100644
index 3f31c3187d9..00000000000
--- a/.changeset/many-years-care.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Refund table now displays user initials on the avatar and full name on hover instead of an email.
diff --git a/.changeset/mean-lizards-explode.md b/.changeset/mean-lizards-explode.md
deleted file mode 100644
index 4c61b256416..00000000000
--- a/.changeset/mean-lizards-explode.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Product details view will not show product categories with its ancestors. It will make it easier to choose product's category.
diff --git a/.changeset/mean-phones-hide.md b/.changeset/mean-phones-hide.md
deleted file mode 100644
index a4c459b7e73..00000000000
--- a/.changeset/mean-phones-hide.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Add clarity to order cancel dialog
diff --git a/.changeset/metal-chicken-build.md b/.changeset/metal-chicken-build.md
deleted file mode 100644
index aa194bdd026..00000000000
--- a/.changeset/metal-chicken-build.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Adding e2e tests for permission groups
diff --git a/.changeset/metal-vans-begin.md b/.changeset/metal-vans-begin.md
deleted file mode 100644
index 2a283fc4d4d..00000000000
--- a/.changeset/metal-vans-begin.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fixing flaky test - TC: SALEOR_106 Issue gift card with specific customer and expiry date
diff --git a/.changeset/nasty-chefs-applaud.md b/.changeset/nasty-chefs-applaud.md
deleted file mode 100644
index 273d92bd20e..00000000000
--- a/.changeset/nasty-chefs-applaud.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Add product analytics on cloud
diff --git a/.changeset/neat-shoes-approve.md b/.changeset/neat-shoes-approve.md
deleted file mode 100644
index 8ec5df3c948..00000000000
--- a/.changeset/neat-shoes-approve.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Add playwright tests for edit and remove product types
diff --git a/.changeset/nervous-ducks-fix.md b/.changeset/nervous-ducks-fix.md
deleted file mode 100644
index d0dd8434419..00000000000
--- a/.changeset/nervous-ducks-fix.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-History component's texts will now have unified colors
diff --git a/.changeset/nervous-toes-fail.md b/.changeset/nervous-toes-fail.md
deleted file mode 100644
index 1f0d3878f53..00000000000
--- a/.changeset/nervous-toes-fail.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Rewritten tests for setting balance and exporting gift cards
diff --git a/.changeset/nervous-weeks-nail.md b/.changeset/nervous-weeks-nail.md
deleted file mode 100644
index 2c28738f0c9..00000000000
--- a/.changeset/nervous-weeks-nail.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-E2E Test for adding promotion rules
diff --git a/.changeset/new-ants-shop.md b/.changeset/new-ants-shop.md
deleted file mode 100644
index dde52d97e65..00000000000
--- a/.changeset/new-ants-shop.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Adding tests for readonly access to Apps
diff --git a/.changeset/nice-emus-grin.md b/.changeset/nice-emus-grin.md
deleted file mode 100644
index e328b8df0a9..00000000000
--- a/.changeset/nice-emus-grin.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fixing flaky e2e tests
diff --git a/.changeset/nice-pets-hide.md b/.changeset/nice-pets-hide.md
deleted file mode 100644
index 01c5adfd69b..00000000000
--- a/.changeset/nice-pets-hide.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Introduce view for manual refund transaction
diff --git a/.changeset/old-pianos-hope.md b/.changeset/old-pianos-hope.md
deleted file mode 100644
index acf3d6fb235..00000000000
--- a/.changeset/old-pianos-hope.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Flow settings in channel creation will now persist after channel is created
diff --git a/.changeset/old-planes-trade.md b/.changeset/old-planes-trade.md
deleted file mode 100644
index 2bba8cc3a98..00000000000
--- a/.changeset/old-planes-trade.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-E2E Playwright tests: SALEOR_187, SALEOR_205, SALEOR_59, SALEOR_198, SALEOR_106 are no longer flaky
diff --git a/.changeset/olive-files-perform.md b/.changeset/olive-files-perform.md
deleted file mode 100644
index 565aa1a6613..00000000000
--- a/.changeset/olive-files-perform.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fixes incorrect button label for adding or editing refund reason
diff --git a/.changeset/olive-games-rush.md b/.changeset/olive-games-rush.md
deleted file mode 100644
index 4fb8d4eaff8..00000000000
--- a/.changeset/olive-games-rush.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fixing assertions in flaky Playwright tests
diff --git a/.changeset/orange-bulldogs-smoke.md b/.changeset/orange-bulldogs-smoke.md
deleted file mode 100644
index f9adec2a867..00000000000
--- a/.changeset/orange-bulldogs-smoke.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Adding the new variant as a row is no longer possible from the product details. This means "add new variant" button now leads you to the variant creation page
diff --git a/.changeset/orange-buses-scream.md b/.changeset/orange-buses-scream.md
deleted file mode 100644
index 558b4be5666..00000000000
--- a/.changeset/orange-buses-scream.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-For old verions tests with "old release" tag will be executing. Additionally adds more detailed title to results on slack and testmo"
diff --git a/.changeset/perfect-crews-speak.md b/.changeset/perfect-crews-speak.md
deleted file mode 100644
index df401ff5dad..00000000000
--- a/.changeset/perfect-crews-speak.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Searching for countries and other items is now more efficient, making it easier to find what you need. Additionally, the Dashboard Navigator UI has been improved to match the rest of the application, providing a more consistent experience.
diff --git a/.changeset/perfect-ears-drive.md b/.changeset/perfect-ears-drive.md
deleted file mode 100644
index 8df81b25728..00000000000
--- a/.changeset/perfect-ears-drive.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Previously we allowed user to select either flat rates or any tax app. To avoid problems if there are more tax apps installed this change adds ability to select tax app that will be used to calculated taxes per channel. User can also select tax app for country exception while configuring taxes. Related [RFC](https://github.com/saleor/saleor/issues/12942)
diff --git a/.changeset/perfect-geckos-occur.md b/.changeset/perfect-geckos-occur.md
deleted file mode 100644
index 91a6e7ae8e2..00000000000
--- a/.changeset/perfect-geckos-occur.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Amount input in refund form no longer displays incorrectly formatted prices after recalculation
diff --git a/.changeset/plenty-walls-prove.md b/.changeset/plenty-walls-prove.md
deleted file mode 100644
index b41f0a76091..00000000000
--- a/.changeset/plenty-walls-prove.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Transaction refund related views no longer display confusing descriptions.
diff --git a/.changeset/pretty-pets-doubt.md b/.changeset/pretty-pets-doubt.md
deleted file mode 100644
index 550249d590a..00000000000
--- a/.changeset/pretty-pets-doubt.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-You can now toggle improved refund flow in features preview
diff --git a/.changeset/purple-beans-deliver.md b/.changeset/purple-beans-deliver.md
deleted file mode 100644
index 714602def1f..00000000000
--- a/.changeset/purple-beans-deliver.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Addedd support for the BrokerProperties webhook header
diff --git a/.changeset/purple-dancers-confess.md b/.changeset/purple-dancers-confess.md
deleted file mode 100644
index 258293191ab..00000000000
--- a/.changeset/purple-dancers-confess.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Filters for orders now allow filtering by ID. This means its form handles one or multiple ID that you can attach by using comma, space, or enter for separation.
diff --git a/.changeset/rare-seas-pull.md b/.changeset/rare-seas-pull.md
deleted file mode 100644
index 0722bb3cddb..00000000000
--- a/.changeset/rare-seas-pull.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Products in a list of products to be excluded from shipping will no longer be selectable if not available in chosen channels.
diff --git a/.changeset/real-brooms-attack.md b/.changeset/real-brooms-attack.md
deleted file mode 100644
index 40ed6714c16..00000000000
--- a/.changeset/real-brooms-attack.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Fix showing promotion discount type in order summary
diff --git a/.changeset/red-guests-perform.md b/.changeset/red-guests-perform.md
deleted file mode 100644
index d27217a7e5a..00000000000
--- a/.changeset/red-guests-perform.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Increase playwright maxFailures to 10 (how many allowed failures, if exceeding skip remaining tests)
diff --git a/.changeset/red-hornets-impress.md b/.changeset/red-hornets-impress.md
deleted file mode 100644
index ff72cd40f1a..00000000000
--- a/.changeset/red-hornets-impress.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Manual refund form no longer allows values greater than charged amount for selected transaction and now allows positive values lower than 1
diff --git a/.changeset/rich-apes-buy.md b/.changeset/rich-apes-buy.md
deleted file mode 100644
index 8316697c0fe..00000000000
--- a/.changeset/rich-apes-buy.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fixing another batch of flaky E2E tests
diff --git a/.changeset/rotten-garlics-perform.md b/.changeset/rotten-garlics-perform.md
deleted file mode 100644
index 226a8c58d2e..00000000000
--- a/.changeset/rotten-garlics-perform.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-QA Adding back tests-nightly workflow
diff --git a/.changeset/selfish-walls-sit.md b/.changeset/selfish-walls-sit.md
deleted file mode 100644
index fd29f6bf454..00000000000
--- a/.changeset/selfish-walls-sit.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-You can now open channel selection by clicking "Select channel" within any price cell on the product list. This means the dash "-" sign is no longer displayed there
diff --git a/.changeset/serious-beans-try.md b/.changeset/serious-beans-try.md
deleted file mode 100644
index fea128da3cf..00000000000
--- a/.changeset/serious-beans-try.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Introduce menu items with sortcuts for GraphQL playground and search actions in sidebar.
-Move "Go to Saleor Cloud" button at bottom of sidebar
diff --git a/.changeset/serious-books-wave.md b/.changeset/serious-books-wave.md
deleted file mode 100644
index b9e86aff1f8..00000000000
--- a/.changeset/serious-books-wave.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Changed e2e test case ids to remove duplicate case ids and fix inconsistencies between repo and Testmo. Thanks to this, our QA reports will be more accurate
diff --git a/.changeset/serious-pandas-jam.md b/.changeset/serious-pandas-jam.md
deleted file mode 100644
index c59afe5c7fe..00000000000
--- a/.changeset/serious-pandas-jam.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Waits if editorjs is ready before it's destroyed. This change aims to lower number of alerts caused by editorjs
diff --git a/.changeset/sharp-cobras-obey.md b/.changeset/sharp-cobras-obey.md
deleted file mode 100644
index 249d1987188..00000000000
--- a/.changeset/sharp-cobras-obey.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-add playwright test for translations
diff --git a/.changeset/sharp-gorillas-cheat.md b/.changeset/sharp-gorillas-cheat.md
deleted file mode 100644
index 1800ac73091..00000000000
--- a/.changeset/sharp-gorillas-cheat.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Set codeowners based on new GH groups
diff --git a/.changeset/sharp-planets-jam.md b/.changeset/sharp-planets-jam.md
deleted file mode 100644
index 796a4b16a78..00000000000
--- a/.changeset/sharp-planets-jam.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Fixes an issue that prevented users from pasting values smaller than 10 into datagrid cells
diff --git a/.changeset/sharp-tables-peel.md b/.changeset/sharp-tables-peel.md
deleted file mode 100644
index 0c25ccfb4be..00000000000
--- a/.changeset/sharp-tables-peel.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Avatars in transaction events no longer show broken image instead of initials.
diff --git a/.changeset/short-garlics-brush.md b/.changeset/short-garlics-brush.md
deleted file mode 100644
index be1d8ebf6c8..00000000000
--- a/.changeset/short-garlics-brush.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Add site settings e2e test
diff --git a/.changeset/shy-dodos-exist.md b/.changeset/shy-dodos-exist.md
deleted file mode 100644
index 3f9cd59ec13..00000000000
--- a/.changeset/shy-dodos-exist.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fix duplicate validations on refund view
diff --git a/.changeset/shy-jars-flow.md b/.changeset/shy-jars-flow.md
deleted file mode 100644
index 290534e5a49..00000000000
--- a/.changeset/shy-jars-flow.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Show all transaction in manual refund view, disabled those that are not refundable
diff --git a/.changeset/shy-spoons-explain.md b/.changeset/shy-spoons-explain.md
deleted file mode 100644
index a8bc9d7d9fb..00000000000
--- a/.changeset/shy-spoons-explain.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Removing skips from e2e tests
diff --git a/.changeset/silver-donuts-crash.md b/.changeset/silver-donuts-crash.md
deleted file mode 100644
index abb0469637d..00000000000
--- a/.changeset/silver-donuts-crash.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-This change replaces refund datagrid on order details view with GridTable for better clarity and UX.
diff --git a/.changeset/six-hairs-cover.md b/.changeset/six-hairs-cover.md
deleted file mode 100644
index c383ec686f2..00000000000
--- a/.changeset/six-hairs-cover.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Now you can see the reason why shipping methods are incorrect when creating draft orders. This means creating new draft orders will pop up an error with the details of incorrect shipping.
diff --git a/.changeset/sixty-colts-cough.md b/.changeset/sixty-colts-cough.md
deleted file mode 100644
index 2307753da8f..00000000000
--- a/.changeset/sixty-colts-cough.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-# Optimizing playwright setup and playwright.config.ts files
-
--Adding a conditioning to auth.setup.ts file to use existing auth json file if it's applicable
--Added some optimizations to playwright config file
--Cleaned up gh action for playwright tests (removed Cypress references)
--Updating gh workflow for PR automation with extra test sharding
--General cleanup of redundant code
diff --git a/.changeset/sixty-kangaroos-cheer.md b/.changeset/sixty-kangaroos-cheer.md
deleted file mode 100644
index dcc83bdc3c1..00000000000
--- a/.changeset/sixty-kangaroos-cheer.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Implement refunds datagrid on order details
diff --git a/.changeset/slow-lemons-care.md b/.changeset/slow-lemons-care.md
deleted file mode 100644
index ca82915d695..00000000000
--- a/.changeset/slow-lemons-care.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-The selected value is no longer filtering the options when using any select list in product variant table
diff --git a/.changeset/smooth-frogs-play.md b/.changeset/smooth-frogs-play.md
deleted file mode 100644
index 4e4252ea24f..00000000000
--- a/.changeset/smooth-frogs-play.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-This change replaces old service worker with a noop service worker. Saleor Dashboard will no longer actively use service worker for caching and registering fonts.
diff --git a/.changeset/sour-rings-occur.md b/.changeset/sour-rings-occur.md
deleted file mode 100644
index 867a4a0d09e..00000000000
--- a/.changeset/sour-rings-occur.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Orders: In order list view you can now use new, easy to use and improved filters.
diff --git a/.changeset/spotty-spies-film.md b/.changeset/spotty-spies-film.md
deleted file mode 100644
index ea4fd1e51ff..00000000000
--- a/.changeset/spotty-spies-film.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Improve error color on datagrid
diff --git a/.changeset/stale-students-unite.md b/.changeset/stale-students-unite.md
deleted file mode 100644
index b0b43f09752..00000000000
--- a/.changeset/stale-students-unite.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-You can now run E2E tests for refunds
diff --git a/.changeset/stale-tigers-brush.md b/.changeset/stale-tigers-brush.md
deleted file mode 100644
index 375c99b6b5f..00000000000
--- a/.changeset/stale-tigers-brush.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Vertical lines are no longer visible for read-only grid tables
diff --git a/.changeset/strange-stingrays-shave.md b/.changeset/strange-stingrays-shave.md
deleted file mode 100644
index 5b6a3532521..00000000000
--- a/.changeset/strange-stingrays-shave.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-The action buttons in the transaction section of the order view are now unified with the other buttons in that view.
diff --git a/.changeset/stupid-seahorses-fix.md b/.changeset/stupid-seahorses-fix.md
deleted file mode 100644
index 7b59493dbe3..00000000000
--- a/.changeset/stupid-seahorses-fix.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-E2E fixing flaky gift cards tests
diff --git a/.changeset/sweet-baboons-beg.md b/.changeset/sweet-baboons-beg.md
deleted file mode 100644
index aec7ce2a9cb..00000000000
--- a/.changeset/sweet-baboons-beg.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Fixes an issue where product export threw an error due to invalid input data
diff --git a/.changeset/sweet-buttons-visit.md b/.changeset/sweet-buttons-visit.md
deleted file mode 100644
index 8fb1ca3b36a..00000000000
--- a/.changeset/sweet-buttons-visit.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Adding e2e navigation tests
diff --git a/.changeset/swift-pandas-guess.md b/.changeset/swift-pandas-guess.md
deleted file mode 100644
index a80d7a5501b..00000000000
--- a/.changeset/swift-pandas-guess.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Run tests from other repo
diff --git a/.changeset/tall-dodos-sit.md b/.changeset/tall-dodos-sit.md
deleted file mode 100644
index f18b24b4e0a..00000000000
--- a/.changeset/tall-dodos-sit.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-You can now see pending manual refunds on order details view.
diff --git a/.changeset/tame-foxes-breathe.md b/.changeset/tame-foxes-breathe.md
deleted file mode 100644
index 5b48208c6c1..00000000000
--- a/.changeset/tame-foxes-breathe.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fixing still flaky test - TC: SALEOR_205 Bulk delete customers
diff --git a/.changeset/tame-jars-add.md b/.changeset/tame-jars-add.md
deleted file mode 100644
index 9c6f31f0527..00000000000
--- a/.changeset/tame-jars-add.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fixing flaky test - TC: SALEOR_205 Bulk delete customers
diff --git a/.changeset/tasty-meals-grin.md b/.changeset/tasty-meals-grin.md
deleted file mode 100644
index 5c74b802eef..00000000000
--- a/.changeset/tasty-meals-grin.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Show info and disable checkbox in AssignProductDialog when product does have channels overlap with selected channels
diff --git a/.changeset/tasty-ties-listen.md b/.changeset/tasty-ties-listen.md
deleted file mode 100644
index 358ab1fbf83..00000000000
--- a/.changeset/tasty-ties-listen.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-This change replaces the datagrid on refund create & edit views with GridTable component
diff --git a/.changeset/ten-students-sneeze.md b/.changeset/ten-students-sneeze.md
deleted file mode 100644
index 5702f19b8e5..00000000000
--- a/.changeset/ten-students-sneeze.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Introduce new icons for menu, remove not used icons
diff --git a/.changeset/thick-moons-whisper.md b/.changeset/thick-moons-whisper.md
deleted file mode 100644
index 12fda975b80..00000000000
--- a/.changeset/thick-moons-whisper.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Now savebar is aligned with the rest of layout
diff --git a/.changeset/thick-tools-flash.md b/.changeset/thick-tools-flash.md
deleted file mode 100644
index c3489278504..00000000000
--- a/.changeset/thick-tools-flash.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Adding e2e tests for attributes
diff --git a/.changeset/thin-timers-grin.md b/.changeset/thin-timers-grin.md
deleted file mode 100644
index e328b8df0a9..00000000000
--- a/.changeset/thin-timers-grin.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fixing flaky e2e tests
diff --git a/.changeset/tiny-hairs-wink.md b/.changeset/tiny-hairs-wink.md
deleted file mode 100644
index f1ac4a22099..00000000000
--- a/.changeset/tiny-hairs-wink.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fixing flaky test: TC: SALEOR_87 Edit voucher Usage Limits: used in total, per customer, staff only, code used once
diff --git a/.changeset/tricky-radios-sin.md b/.changeset/tricky-radios-sin.md
deleted file mode 100644
index 5052f524344..00000000000
--- a/.changeset/tricky-radios-sin.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Open release PR after automation tests for core releases passes
diff --git a/.changeset/tricky-spies-study.md b/.changeset/tricky-spies-study.md
deleted file mode 100644
index bd7c9b0b088..00000000000
--- a/.changeset/tricky-spies-study.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fixes button font weights
diff --git a/.changeset/twelve-kids-pretend.md b/.changeset/twelve-kids-pretend.md
deleted file mode 100644
index 01d51af899e..00000000000
--- a/.changeset/twelve-kids-pretend.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Add playwright tests for page types
diff --git a/.changeset/twenty-seals-yawn.md b/.changeset/twenty-seals-yawn.md
deleted file mode 100644
index 79f247e7e2f..00000000000
--- a/.changeset/twenty-seals-yawn.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Fix release workflow
diff --git a/.changeset/unable-to-build-docker-image .md b/.changeset/unable-to-build-docker-image .md
deleted file mode 100644
index df7d5217458..00000000000
--- a/.changeset/unable-to-build-docker-image .md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Fix dockerfile build error caused by deleted file and bash script
diff --git a/.changeset/warm-balloons-call.md b/.changeset/warm-balloons-call.md
deleted file mode 100644
index 997a68464e1..00000000000
--- a/.changeset/warm-balloons-call.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-New github action gathering repo metrics
diff --git a/.changeset/warm-taxis-mate.md b/.changeset/warm-taxis-mate.md
deleted file mode 100644
index b5fdf0c269a..00000000000
--- a/.changeset/warm-taxis-mate.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Show all gift card used in order details
diff --git a/.changeset/weak-steaks-dream.md b/.changeset/weak-steaks-dream.md
deleted file mode 100644
index d18e45f4f46..00000000000
--- a/.changeset/weak-steaks-dream.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Now you can see the updated appearance of the bottom bar that holds save and back actions. This means functionality has not be changed
diff --git a/.changeset/wet-badgers-switch.md b/.changeset/wet-badgers-switch.md
deleted file mode 100644
index dbb363c0248..00000000000
--- a/.changeset/wet-badgers-switch.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fixing flaky E2E test for gift cards
diff --git a/.changeset/wicked-forks-agree.md b/.changeset/wicked-forks-agree.md
deleted file mode 100644
index bb701eac04b..00000000000
--- a/.changeset/wicked-forks-agree.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Remove branch name warning from pre-push
diff --git a/.changeset/wild-stingrays-walk.md b/.changeset/wild-stingrays-walk.md
deleted file mode 100644
index 4b9179161fa..00000000000
--- a/.changeset/wild-stingrays-walk.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Use dummy app in delete app test
diff --git a/.changeset/wise-pants-repeat.md b/.changeset/wise-pants-repeat.md
deleted file mode 100644
index 5a61e9a4e2a..00000000000
--- a/.changeset/wise-pants-repeat.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Fix typo in postTestsResults.js
-
diff --git a/.changeset/yellow-keys-admire.md b/.changeset/yellow-keys-admire.md
deleted file mode 100644
index 9e84c301727..00000000000
--- a/.changeset/yellow-keys-admire.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": patch
----
-
-Show discount name for promotion discount type
diff --git a/.changeset/young-fishes-applaud.md b/.changeset/young-fishes-applaud.md
deleted file mode 100644
index 47375d4fafe..00000000000
--- a/.changeset/young-fishes-applaud.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"saleor-dashboard": minor
----
-
-Refund views have now more consistent UI
diff --git a/.dependency-cruiser.js b/.dependency-cruiser.js
index 602a99ac350..87735b767cf 100644
--- a/.dependency-cruiser.js
+++ b/.dependency-cruiser.js
@@ -7,7 +7,8 @@ module.exports = {
comment: "Macaw UI migration",
from: {},
to: {
- path: "@saleor/macaw-ui/legacy",
+ path: "@saleor/macaw-ui",
+ pathNot: "@saleor/macaw-ui-next"
},
},
{
diff --git a/.env.template b/.env.template
index c8cbab7d31f..f7a6ed1e703 100644
--- a/.env.template
+++ b/.env.template
@@ -1,7 +1,7 @@
-API_URL=https://demo.saleor.io/graphql/
+API_URL=http://localhost:8000/
APP_MOUNT_URI=/
APPS_MARKETPLACE_API_URL=https://apps.saleor.io/api/v2/saleor-apps
-LOCALE_CODE="EN"
+LOCALE_CODE="EN"
DEMO_MODE=false
MAILPITURL=xxxx #For playwright
@@ -9,4 +9,6 @@ MAILPITURL=xxxx #For playwright
E2E_USER_NAME=xxxx
E2E_USER_PASSWORD=xxxx
E2E_PERMISSIONS_USERS_PASSWORD=xxxx
-BASE_URL=http://localhost:9000/
\ No newline at end of file
+BASE_URL=http://localhost:9000/
+
+ONBOARDING_USER_JOINED_DATE_THRESHOLD=2024-07-01
\ No newline at end of file
diff --git a/.eslintrc.json b/.eslintrc.json
index c4a5baf31d5..f676344cfc7 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -105,5 +105,5 @@
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-unused-vars": "off"
},
- "ignorePatterns": ["node_modules/", "**/types/**/*", "type-policies.ts"]
+ "ignorePatterns": ["node_modules/", "**/types/**/*", "type-policies.ts", "playwright/auth.js"]
}
diff --git a/.featureFlags/discounts-rules.md b/.featureFlags/discounts-rules.md
index 6da6c427284..f2f14adaae7 100644
--- a/.featureFlags/discounts-rules.md
+++ b/.featureFlags/discounts-rules.md
@@ -1,7 +1,7 @@
---
name: discounts_rules
displayName: Discounts rules
-enabled: false
+enabled: true
payload: "default"
visible: true
---
diff --git a/.featureFlags/generated.tsx b/.featureFlags/generated.tsx
index 36eb89dfd52..d4eca57a7a6 100644
--- a/.featureFlags/generated.tsx
+++ b/.featureFlags/generated.tsx
@@ -1,15 +1,13 @@
// @ts-nocheck
-import L19499 from "./images/discounts-list.png"
-import I59669 from "./images/improved_refunds.png"
-import M04994 from "./images/order-filters.png"
-import C77988 from "./images/filters.png"
+import A54222 from "./images/discounts-list.png"
+import M51879 from "./images/improved_refunds.png"
-const discounts_rules = () => (<>
+const discounts_rules = () => (<>
Apply the new discounts rules to narrow your promotions audience.
Set up conditions and channels that must be fulfilled to apply defined reward.
>)
-const improved_refunds = () => (<>
+const improved_refunds = () => (<>
Enable the enhanced refund feature to streamline your refund process:
>)
-const order_filters = () => (<>
-Experience the new look and enhanced abilities of new orders filtering mechanism.
-Easily combine any criteria you want, and quickly browse their values.
->)
-const product_filters = () => (<>
-Experience the new look and enhanced abilities of new fitering mechanism.
-Easily combine any criteria you want, and quickly browse their values.
+const new_filters = () => (<>Experience the new look and enhanced abilities of new filtering mechanism.
+Combine any criteria you want, and quickly browse their values.
+New filters have been added to the following pages:
+
+Collection list
+Customers list
+Vouchers list
+Draft orders list
+Gift cards list
+Content list
+Product types list
+Staff members list
+
>)
export const AVAILABLE_FLAGS = [{
@@ -34,7 +38,7 @@ export const AVAILABLE_FLAGS = [{
component: discounts_rules,
visible: true,
content: {
- enabled: false,
+ enabled: true,
payload: "default",
}
},{
@@ -47,18 +51,9 @@ export const AVAILABLE_FLAGS = [{
payload: "default",
}
},{
- name: "order_filters",
- displayName: "Orders filtering",
- component: order_filters,
- visible: true,
- content: {
- enabled: true,
- payload: "default",
- }
-},{
- name: "product_filters",
- displayName: "Products filtering",
- component: product_filters,
+ name: "new_filters",
+ displayName: "New filtering",
+ component: new_filters,
visible: true,
content: {
enabled: true,
diff --git a/.featureFlags/images/filters.png b/.featureFlags/images/filters.png
deleted file mode 100644
index 2c1ff0780a3..00000000000
Binary files a/.featureFlags/images/filters.png and /dev/null differ
diff --git a/.featureFlags/images/order-filters.png b/.featureFlags/images/order-filters.png
deleted file mode 100644
index db5ebcd30f8..00000000000
Binary files a/.featureFlags/images/order-filters.png and /dev/null differ
diff --git a/.featureFlags/new_filters.md b/.featureFlags/new_filters.md
new file mode 100644
index 00000000000..6bf66cd1477
--- /dev/null
+++ b/.featureFlags/new_filters.md
@@ -0,0 +1,19 @@
+---
+name: new_filters
+displayName: New filtering
+enabled: true
+payload: "default"
+visible: true
+---
+
+Experience the new look and enhanced abilities of new filtering mechanism.
+Combine any criteria you want, and quickly browse their values.
+New filters have been added to the following pages:
+- Collection list
+- Customers list
+- Vouchers list
+- Draft orders list
+- Gift cards list
+- Content list
+- Product types list
+- Staff members list
\ No newline at end of file
diff --git a/.featureFlags/order-filters.md b/.featureFlags/order-filters.md
deleted file mode 100644
index 6b67052efdc..00000000000
--- a/.featureFlags/order-filters.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-name: order_filters
-displayName: Orders filtering
-enabled: true
-payload: "default"
-visible: true
----
-
-
-
-Experience the new look and enhanced abilities of new orders filtering mechanism.
-Easily combine any criteria you want, and quickly browse their values.
\ No newline at end of file
diff --git a/.featureFlags/product-filters.md b/.featureFlags/product-filters.md
deleted file mode 100644
index 0eef2bcedf9..00000000000
--- a/.featureFlags/product-filters.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-name: product_filters
-displayName: Products filtering
-enabled: true
-payload: "default"
-visible: true
----
-
-
-
-Experience the new look and enhanced abilities of new fitering mechanism.
-Easily combine any criteria you want, and quickly browse their values.
\ No newline at end of file
diff --git a/.github/actions/cli-login/action.yml b/.github/actions/cli-login/action.yml
index 04c7dce4d83..a29f1792b18 100644
--- a/.github/actions/cli-login/action.yml
+++ b/.github/actions/cli-login/action.yml
@@ -15,4 +15,4 @@ runs:
run: |
jq --null-input \
--arg token "Token $ACCESS_TOKEN" \
- '{"token":$token,"telemetry":"false","saleor_env":"staging","cloud_api_url":"https://staging-cloud.saleor.io/platform/api","organization_slug":"saleor","organization_name":"Saleor"}' > ~/.config/saleor.json
+ '{"token":$token,"telemetry":"false","saleor_env":"staging","cloud_api_url":"https://cloud.staging.saleor.io/platform/api","organization_slug":"saleor","organization_name":"Saleor"}' > ~/.config/saleor.json
diff --git a/.github/actions/combineReportsFromE2E/action.yml b/.github/actions/combineReportsFromE2E/action.yml
deleted file mode 100644
index cc4f715332c..00000000000
--- a/.github/actions/combineReportsFromE2E/action.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-name: combine-e2e-results
-description: "Combines reports from matrix and upload them as one"
-runs:
- using: "composite"
- steps:
- - uses: actions/setup-node@v3
- with:
- node-version-file: ".nvmrc"
- cache: npm
- - name: Cache node modules
- uses: actions/cache@v3
- env:
- cache-name: cache-node-modules
- with:
- path: ~/.npm
- key: ${{ runner.os }}-qa-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
- restore-keys: |
- ${{ runner.os }}-qa-${{ env.cache-name }}-
- ${{ runner.os }}-qa-
- ${{ runner.os }}-
- - name: Install Dependencies
- if: steps.cache-node-modules.outputs.cache-hit != 'true'
- shell: bash
- run: NODE_OPTIONS=--max_old_space_size=4096 npm ci
- - run: npm ci
- shell: bash
- working-directory: .github/workflows
- - name: Download reports artifacts
- uses: actions/download-artifact@v3
- with:
- path: ./cypress/reports
- - name: Create reports dir
- shell: bash
- continue-on-error: true
- run: npm run qa:create-artifacts-dirs
- - name: Merge report files
- shell: bash
- continue-on-error: true
- run: npm run qa:generate-html-report
- - name: Move artifacts screenshots into reports dir
- shell: bash
- continue-on-error: true
- run: npm run qa:artifact-move-screenshots
- - name: Upload reports
- uses: actions/upload-artifact@v3
- if: always()
- with:
- name: combined-report
- path: ./cypress/reports
- retention-days: 5
- if-no-files-found: ignore
diff --git a/.github/actions/flaky-tests-report/action.yml b/.github/actions/flaky-tests-report/action.yml
new file mode 100644
index 00000000000..acbfa58948c
--- /dev/null
+++ b/.github/actions/flaky-tests-report/action.yml
@@ -0,0 +1,61 @@
+name: Flaky test report
+description: Extract flaky tests from PW test reports
+runs:
+ using: "composite"
+ steps:
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 20
+
+ - name: Install CTRF package globally
+ shell: bash
+ run: npm install -g ctrf
+
+ - name: Download CTRF reports
+ uses: actions/download-artifact@v4
+ with:
+ pattern: ctrf-report-*
+ path: ctrf-reports
+ merge-multiple: true
+
+ - name: Merge CTRF reports
+ shell: bash
+ run: npx ctrf merge ./ctrf-reports --output merged-report.json
+
+ - name: Add execution date to merged report
+ shell: bash
+ run: |
+ DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") # ISO format
+ jq --arg date "$DATE" '.results.summary.extra = { "data": $date }' ctrf-reports/merged-report.json > ctrf-reports/tmp.json && mv ctrf-reports/tmp.json ctrf-reports/merged-report.json
+
+ - name: Upload CTRF report
+ uses: actions/upload-artifact@v4
+ with:
+ name: merged-report.json
+ path: ctrf-reports
+ retention-days: 14
+
+ - name: Publish Test Report
+ uses: ctrf-io/github-test-reporter@v1
+ with:
+ report-path: ctrf-reports/merged-report.json
+ summary-report: true
+ commit-report: true
+ env:
+ GITHUB_TOKEN: ${{ inputs.github_token }}
+ if: always()
+
+ - name: Publish PR Comment
+ uses: ctrf-io/github-test-reporter@v1
+ with:
+ report-path: ctrf-reports/merged-report.json
+ pull-request-report: true
+ overwrite-comment: true
+ env:
+ GITHUB_TOKEN: ${{ inputs.github_token }}
+ if: always()
+
+inputs:
+ github_token:
+ description: "GitHub token for accessing APIs"
+ required: true
diff --git a/.github/actions/merge-pw-reports/action.yml b/.github/actions/merge-pw-reports/action.yml
index b646a9fe3f8..5f56a6ba893 100644
--- a/.github/actions/merge-pw-reports/action.yml
+++ b/.github/actions/merge-pw-reports/action.yml
@@ -1,6 +1,11 @@
name: Merge playwright reports
description: Merge reports from all shards
+inputs:
+ PASSWORD_FOR_DECODING_ARTIFACT:
+ description: "Password for decoding artifact"
+ required: true
+
runs:
using: "composite"
steps:
@@ -13,18 +18,23 @@ runs:
run: npm ci
- name: Download blob reports from GitHub Actions Artifacts
- uses: actions/download-artifact@v3
+ uses: actions/download-artifact@v4
with:
- name: all-blob-reports
path: all-blob-reports
+ pattern: all-blob-reports-*
+ merge-multiple: true
- name: Merge into HTML Report
shell: bash
- run: npx playwright merge-reports --reporter html ./all-blob-reports
+ env:
+ PASSWORD_FOR_DECODING_ARTIFACT: ${{ inputs.PASSWORD_FOR_DECODING_ARTIFACT }}
+ run: |
+ npx playwright merge-reports --reporter html ./all-blob-reports
+ zip -P $PASSWORD_FOR_DECODING_ARTIFACT secure-report.zip -r ./playwright-report
- name: Upload HTML report
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
name: html-report--attempt-${{ github.run_attempt }}
- path: playwright-report
+ path: secure-report.zip
retention-days: 14
diff --git a/.github/actions/prepare-accounts/action.yml b/.github/actions/prepare-accounts/action.yml
new file mode 100644
index 00000000000..af864f038a4
--- /dev/null
+++ b/.github/actions/prepare-accounts/action.yml
@@ -0,0 +1,48 @@
+name: Prepare accounts
+description: Prepare accounts that are used by Playwright
+inputs:
+ BASE_URL:
+ description: "Dashboard base url"
+ required: true
+ API_URL:
+ description: "API url"
+ required: true
+ E2E_USER_NAME:
+ description: "Username for e2e tests"
+ required: true
+ E2E_USER_PASSWORD:
+ description: "Password for e2e tests"
+ required: true
+ E2E_PERMISSIONS_USERS_PASSWORD:
+ description: "Permissions user password for e2e tests"
+ required: true
+ E2E_ENCODE_PASS:
+ description: "Password for encoding credentials"
+ required: true
+
+outputs:
+ ACCOUNTS:
+ description: "Encrypted accounts"
+ value: ${{ steps.accounts.outputs.ACCOUNTS }}
+
+
+runs:
+ using: "composite"
+ steps:
+ - uses: actions/setup-node@v3
+ with:
+ node-version-file: ".nvmrc"
+
+ - name: Prepare accounts
+ shell: bash
+ id: accounts
+ env:
+ BASE_URL: ${{ inputs.BASE_URL }}
+ API_URL: ${{ inputs.API_URL }}
+ E2E_USER_NAME: ${{ inputs.E2E_USER_NAME }}
+ E2E_USER_PASSWORD: ${{ inputs.E2E_USER_PASSWORD }}
+ E2E_ENCODE_PASS: ${{ inputs.E2E_ENCODE_PASS }}
+ E2E_PERMISSIONS_USERS_PASSWORD: ${{ inputs.E2E_PERMISSIONS_USERS_PASSWORD }}
+ run: |
+ ACCOUNTS=$(node playwright/auth.js login)
+ echo "ACCOUNTS=${ACCOUNTS}" >> "$GITHUB_OUTPUT"
diff --git a/.github/actions/restore-accounts/action.yml b/.github/actions/restore-accounts/action.yml
new file mode 100644
index 00000000000..d05958214ef
--- /dev/null
+++ b/.github/actions/restore-accounts/action.yml
@@ -0,0 +1,32 @@
+name: Restore accounts
+description: Restore accounts to be consumed by Playwright
+inputs:
+ ACCOUNTS:
+ description: "Accounts encrypted string"
+ required: true
+ E2E_ENCODE_PASS:
+ description: "Password for encoding credentials"
+ required: true
+ BASE_URL:
+ description: "Dashboard base url"
+ required: true
+ API_URL:
+ description: "API url"
+ required: true
+
+runs:
+ using: "composite"
+ steps:
+ - uses: actions/setup-node@v3
+ with:
+ node-version-file: ".nvmrc"
+
+ - name: Restore accounts
+ shell: bash
+ env:
+ E2E_ENCODE_PASS: ${{ inputs.E2E_ENCODE_PASS }}
+ ACCOUNTS: ${{ inputs.ACCOUNTS }}
+ API_URL: ${{ inputs.API_URL }}
+ BASE_URL: ${{ inputs.BASE_URL }}
+ run: |
+ node playwright/auth.js restore "$ACCOUNTS"
diff --git a/.github/actions/run-pw-tests/action.yml b/.github/actions/run-pw-tests/action.yml
index 7ae34ce81fc..3c62da470bc 100644
--- a/.github/actions/run-pw-tests/action.yml
+++ b/.github/actions/run-pw-tests/action.yml
@@ -31,6 +31,25 @@ inputs:
PW_RETRIES:
description: "Playwright retries"
required: true
+ PROJECT:
+ description: "Project name from playwright config"
+ required: false
+ default: "e2e"
+ ACCOUNTS:
+ description: "Accounts hash"
+ required: true
+ E2E_ENCODE_PASS:
+ description: "Password for encoding credentials"
+ required: true
+ BRANCH_NAME:
+ description: "Branch name"
+ required: true
+ SALEOR_CLOUD_SERVICE:
+ description: "Saleor Cloud service"
+ required: true
+ DASHBOARD_VERSION:
+ description: "Dashboard version"
+ required: false
runs:
using: "composite"
@@ -43,6 +62,14 @@ runs:
shell: bash
run: npm ci
+ - name: Restore accounts
+ uses: ./.github/actions/restore-accounts
+ with:
+ BASE_URL: ${{ inputs.BASE_URL }}
+ API_URL: ${{ inputs.API_URL }}
+ ACCOUNTS: ${{ inputs.ACCOUNTS }}
+ E2E_ENCODE_PASS: ${{ inputs.E2E_ENCODE_PASS }}
+
- name: Install Playwright Browsers
shell: bash
run: npx playwright install --with-deps
@@ -63,12 +90,33 @@ runs:
URL_TO_RUN: ${{ inputs.URL_TO_RUN }}
WORKERS: ${{ inputs.PW_WORKERS }}
RETRIES: ${{ inputs.PW_RETRIES }}
- run: npm run qa:pw-e2e -- --shard "$SHARD_NUMBER"
+ PROJECT: ${{ inputs.PROJECT }}
+ BRANCH_NAME: ${{ inputs.BRANCH_NAME }}
+ SALEOR_CLOUD_SERVICE: ${{ inputs.SALEOR_CLOUD_SERVICE }}
+ DASHBOARD_VERSION: ${{ inputs.DASHBOARD_VERSION }}
+
+ run: |
+ PROJECTS=($PROJECT)
+ PROJECT_PARAMS=""
+ for PROJECT in "${PROJECTS[@]}"; do
+ PROJECT_PARAMS+="--project=${PROJECT} "
+ done
+ echo "reportName=all-blob-reports-${SHARD_NUMBER%%/*}" >> $GITHUB_ENV
+ echo "ctrfReport=ctrf-report-${SHARD_NUMBER%%/*}" >> $GITHUB_ENV
+ npx playwright test --grep "#e2e" $PROJECT_PARAMS --shard "$SHARD_NUMBER"
- name: Upload blob report to GitHub Actions Artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
if: always()
with:
- name: all-blob-reports
+ name: ${{ env.reportName }}
path: blob-report
retention-days: 1
+
+ - name: Upload ctrf report to GitHub Actions Artifacts
+ uses: actions/upload-artifact@v4
+ if: always()
+ with:
+ name: ${{ env.ctrfReport }}
+ path: ctrf/ctrf-report-*.json
+ retention-days: 1
diff --git a/.github/actions/testmo/testmo-init/action.yml b/.github/actions/testmo/testmo-init/action.yml
index 121046a921e..04fe383d685 100644
--- a/.github/actions/testmo/testmo-init/action.yml
+++ b/.github/actions/testmo/testmo-init/action.yml
@@ -10,6 +10,9 @@ inputs:
testmoRunName:
description: "Displayed name in testmo"
required: true
+ source:
+ description: "Source for tests"
+ required: true
outputs:
testmo-run-id:
@@ -34,10 +37,11 @@ runs:
--instance "$TESTMO_URL" \
--project-id 1 \
--name "$RUN_NAME" \
- --source frontend-e2e-tests)
+ --source "$SOURCE")
echo "TESTMO_RUN_ID=$ID" >> $GITHUB_OUTPUT
env:
TESTMO_URL: ${{ inputs.testmoUrl }}
TESTMO_TOKEN: ${{ inputs.testmoToken }}
RUN_NAME: ${{inputs.testmoRunName}}
+ SOURCE: ${{inputs.source}}
id: run-tests
diff --git a/.github/workflows/check-licenses.yaml b/.github/workflows/check-licenses.yaml
new file mode 100644
index 00000000000..f5e1ad8e9c0
--- /dev/null
+++ b/.github/workflows/check-licenses.yaml
@@ -0,0 +1,48 @@
+name: Check Licenses
+on:
+ pull_request:
+ types:
+ - opened
+ - synchronize
+ # Labels are needed to handle external contributors
+ - labeled
+ - unlabeled
+ paths:
+ # Self
+ - ".github/workflows/check-licenses.yaml"
+ # Python Ecosystem
+ - "**/pyproject.toml"
+ - "**/setup.py"
+ - "**/requirements*.txt"
+ - "**/Pipfile.lock"
+ - "**/poetry.lock"
+ # JS/TS Ecosystem
+ - "**/package.json"
+ - "**/pnpm-lock.yaml"
+ - "**/package-lock.json"
+
+jobs:
+ default:
+ permissions:
+ contents: read
+ pull-requests: write
+ uses: saleor/saleor-internal-actions/.github/workflows/run-license-check.yaml@v1
+ with:
+ # List of ecosystems to scan.
+ ecosystems: >-
+ python
+ javascript
+ # Grant rules (https://github.com/anchore/grant/blob/4362dc22cf5ea9baeccfa59b2863879afe0c30d7/README.md#usage)
+ rules: |
+ # Explicitly allow LGPL as "*GPL*" rule will cause to reject them otherwise.
+ - pattern: "*lgpl*"
+ name: "allow-lgpl"
+ mode: "allow"
+ reason: "LGPL is allowed."
+ - pattern: "*gpl*"
+ name: "deny-gpl"
+ mode: "deny"
+ reason: "GPL licenses are not compatible with BSD-3-Clause"
+ - pattern: "*proprietary*"
+ name: "deny-proprietary"
+ mode: "deny"
diff --git a/.github/workflows/cleanEnvironments.js b/.github/workflows/cleanEnvironments.js
index 054c3f0b6f6..2b8cc2c95f4 100644
--- a/.github/workflows/cleanEnvironments.js
+++ b/.github/workflows/cleanEnvironments.js
@@ -4,7 +4,7 @@ const core = require("@actions/core");
const program = new Command();
-const pathToCloudAPI = "https://staging-cloud.saleor.io/platform/api/";
+const pathToCloudAPI = "https://cloud.staging.saleor.io/platform/api/";
const snapshotName = "snapshot-automation-tests";
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
deleted file mode 100644
index 15160c54031..00000000000
--- a/.github/workflows/codeql-analysis.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-name: "CodeQL"
-
-on:
- push:
- branches: [main, ]
- pull_request:
- # The branches below must be a subset of the branches above
- branches: [main]
- schedule:
- - cron: '0 10 * * 5'
-
-jobs:
- analyze:
- name: Analyze
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v2
- with:
- # We must fetch at least the immediate parents so that if this is
- # a pull request then we can checkout the head.
- fetch-depth: 2
-
- # If this run was triggered by a pull request event, then checkout
- # the head of the pull request instead of the merge commit.
- - run: git checkout HEAD^2
- if: ${{ github.event_name == 'pull_request' }}
-
- # Initializes the CodeQL tools for scanning.
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v1
- with:
- languages: javascript
-
- # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
- # If this step fails, then you should remove it and run the build manually (see below)
- - name: Autobuild
- uses: github/codeql-action/autobuild@v1
-
- # ℹ️ Command-line programs to run using the OS shell.
- # 📚 https://git.io/JvXDl
-
- # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
- # and modify them (or add more) to build your code if your project
- # uses a compiled language
-
- #- run: |
- # make bootstrap
- # make release
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v1
diff --git a/.github/workflows/cypressTestsHelpers/getEnvironmentVariables.js b/.github/workflows/cypressTestsHelpers/getEnvironmentVariables.js
index a9e944a9db9..967a02fc981 100644
--- a/.github/workflows/cypressTestsHelpers/getEnvironmentVariables.js
+++ b/.github/workflows/cypressTestsHelpers/getEnvironmentVariables.js
@@ -50,7 +50,7 @@ async function getTheNewestVersion(token) {
async function getServices(token) {
// us-east-1
const response = await fetch(
- `https://staging-cloud.saleor.io/platform/api/regions/us-east-1/services`,
+ `https://cloud.staging.saleor.io/platform/api/regions/us-east-1/services`,
{
method: "GET",
headers: {
diff --git a/.github/workflows/deploy-cloud.yaml b/.github/workflows/deploy-cloud.yaml
index 3f959b6471b..f2d9af9848e 100644
--- a/.github/workflows/deploy-cloud.yaml
+++ b/.github/workflows/deploy-cloud.yaml
@@ -26,6 +26,9 @@ jobs:
IS_CLOUD_INSTANCE: true
POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }}
+ POSTHOG_EXCLUDED_DOMAINS: ${{ vars.POSTHOG_EXCLUDED_DOMAINS }}
+ ENABLED_SERVICE_NAME_HEADER: true
+ ONBOARDING_USER_JOINED_DATE_THRESHOLD: ${{ vars.CLOUD_ONBOARDING_USER_JOINED_DATE_THRESHOLD }}
steps:
- name: Check region
if: ${{ !contains(fromJSON('["eu", "us"]'), env.REGION) }}
diff --git a/.github/workflows/deploy-dev.yaml b/.github/workflows/deploy-dev.yaml
index d6e6f70b06b..1630be2ac32 100644
--- a/.github/workflows/deploy-dev.yaml
+++ b/.github/workflows/deploy-dev.yaml
@@ -4,7 +4,9 @@ on:
inputs:
git_ref:
description: Git ref (tag, branch or commit hash) to deploy
+ type: string
required: true
+ default: main
jobs:
build:
@@ -24,9 +26,14 @@ jobs:
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
APPS_MARKETPLACE_API_URL: "https://apps.staging.saleor.io/api/v2/saleor-apps"
+ ENABLED_SERVICE_NAME_HEADER: true
+ ONBOARDING_USER_JOINED_DATE_THRESHOLD: ${{ vars.DEV_ONBOARDING_USER_JOINED_DATE_THRESHOLD }}
IS_CLOUD_INSTANCE: true
steps:
- uses: actions/checkout@v2
+ with:
+ ref: ${{ github.event.inputs.git_ref }}
+
- name: Set custom version
run: |
HASH=$(git rev-parse --short HEAD)
@@ -61,6 +68,15 @@ jobs:
aws s3 sync build/dashboard "s3://${DEPLOYMENT_BUCKET}/saleor-dev2/static/"
aws s3 cp build/dashboard/index.html "s3://${DEPLOYMENT_BUCKET}/saleor-dev2/"
+
+ aws s3 sync build/dashboard "s3://${DEPLOYMENT_BUCKET}/saleor-dev-load-test/static/"
+ aws s3 cp build/dashboard/index.html "s3://${DEPLOYMENT_BUCKET}/saleor-dev-load-test/"
+
+ aws s3 sync build/dashboard "s3://${DEPLOYMENT_BUCKET}/saleor-dev-load-test2/static/"
+ aws s3 cp build/dashboard/index.html "s3://${DEPLOYMENT_BUCKET}/saleor-dev-load-test2/"
+
+ aws s3 sync build/dashboard "s3://${DEPLOYMENT_BUCKET}/saleor-dev-data-test/static/"
+ aws s3 cp build/dashboard/index.html "s3://${DEPLOYMENT_BUCKET}/saleor-dev-data-test/"
env:
DEPLOYMENT_BUCKET: ${{ secrets.AWS_CLOUD_DEV_DEPLOYMENT_BUCKET }}
diff --git a/.github/workflows/deploy-master-staging.yaml b/.github/workflows/deploy-master-staging.yaml
index 3dc8aa4d6b0..3a33c541864 100644
--- a/.github/workflows/deploy-master-staging.yaml
+++ b/.github/workflows/deploy-master-staging.yaml
@@ -24,8 +24,8 @@ jobs:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
APPS_MARKETPLACE_API_URL: "https://apps.staging.saleor.io/api/v2/saleor-apps"
IS_CLOUD_INSTANCE: true
- POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
- POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }}
+ ENABLED_SERVICE_NAME_HEADER: true
+ ONBOARDING_USER_JOINED_DATE_THRESHOLD: ${{ vars.STAGING_ONBOARDING_USER_JOINED_DATE_THRESHOLD }}
steps:
- uses: actions/checkout@v2
- name: Set custom version
diff --git a/.github/workflows/deploy-staging-and-prepare-release.yaml b/.github/workflows/deploy-staging-and-prepare-release.yaml
index 12efae963bd..19565484063 100644
--- a/.github/workflows/deploy-staging-and-prepare-release.yaml
+++ b/.github/workflows/deploy-staging-and-prepare-release.yaml
@@ -59,8 +59,8 @@ jobs:
APPS_MARKETPLACE_API_URL: "https://apps.staging.saleor.io/api/v2/saleor-apps"
VERSION: ${{ github.event.inputs.git_ref || github.ref_name }}
IS_CLOUD_INSTANCE: true
- POSTHOG_KEY: ${{ secrets.POSTHOG_KEY }}
- POSTHOG_HOST: ${{ secrets.POSTHOG_HOST }}
+ ENABLED_SERVICE_NAME_HEADER: true
+ ONBOARDING_USER_JOINED_DATE_THRESHOLD: ${{ vars.STAGING_ONBOARDING_USER_JOINED_DATE_THRESHOLD }}
steps:
- uses: actions/checkout@v4
with:
diff --git a/.github/workflows/package-lock.json b/.github/workflows/package-lock.json
index 5473e130215..c3525acb07e 100644
--- a/.github/workflows/package-lock.json
+++ b/.github/workflows/package-lock.json
@@ -545,17 +545,17 @@
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
},
"node_modules/fast-xml-parser": {
- "version": "4.2.7",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.7.tgz",
- "integrity": "sha512-J8r6BriSLO1uj2miOk1NW0YVm8AGOOu3Si2HQp/cSmo6EA4m3fcwu2WKjJ4RK9wMLBtg69y1kS8baDiQBR41Ig==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz",
+ "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==",
"funding": [
- {
- "type": "paypal",
- "url": "https://paypal.me/naturalintelligence"
- },
{
"type": "github",
"url": "https://github.com/sponsors/NaturalIntelligence"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/naturalintelligence"
}
],
"dependencies": {
@@ -1877,9 +1877,9 @@
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
},
"fast-xml-parser": {
- "version": "4.2.7",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.2.7.tgz",
- "integrity": "sha512-J8r6BriSLO1uj2miOk1NW0YVm8AGOOu3Si2HQp/cSmo6EA4m3fcwu2WKjJ4RK9wMLBtg69y1kS8baDiQBR41Ig==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz",
+ "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==",
"requires": {
"strnum": "^1.0.5"
}
diff --git a/.github/workflows/pr-automation.yml b/.github/workflows/pr-automation.yml
index b9921eb4395..0dcb9966b4f 100644
--- a/.github/workflows/pr-automation.yml
+++ b/.github/workflows/pr-automation.yml
@@ -2,6 +2,7 @@ name: PR automation
on:
pull_request:
+ types: [opened, reopened, synchronize, labeled]
workflow_dispatch:
inputs:
shards:
@@ -27,6 +28,7 @@ jobs:
BACKUP_VER: ${{ steps.cloud_variables.outputs.BACKUP_VER }}
BACKUP_NAME: ${{ steps.cloud_variables.outputs.BACKUP_NAME }}
SHARD_MATRIX: ${{ steps.generate-shard-matrix.outputs.SHARD_MATRIX }}
+ SALEOR_CLOUD_SERVICE: ${{ steps.cloud_variables.outputs.SALEOR_CLOUD_SERVICE }}
steps:
- uses: actions/checkout@v4
with:
@@ -70,6 +72,10 @@ jobs:
deploy-dashboard:
if: github.event.pull_request.head.repo.full_name == 'saleor/saleor-dashboard'
+ outputs:
+ ACCOUNTS: ${{ steps.accounts.outputs.ACCOUNTS }}
+ TESTMO_RUN_ID: ${{ steps.init-testmo.outputs.testmo-run-id }}
+ DASHBOARD_VERSION: ${{ steps.build-dashboard.outputs.DASHBOARD_VERSION }}
runs-on: ubuntu-22.04
needs: initialize-cloud
permissions:
@@ -107,6 +113,7 @@ jobs:
run: npm ci
- name: Build dashboard
+ id: build-dashboard
env:
## backward compatibility for older versions
API_URI: ${{ needs.initialize-cloud.outputs.API_URL }}
@@ -118,7 +125,15 @@ jobs:
APP_MOUNT_URI: /
STATIC_URL: /
IS_CLOUD_INSTANCE: true
- run: npm run build
+ ENABLED_SERVICE_NAME_HEADER: true
+ ONBOARDING_USER_JOINED_DATE_THRESHOLD: ${{ vars.STAGING_ONBOARDING_USER_JOINED_DATE_THRESHOLD }}
+ run: |
+ npm run build
+ # Extract version from package.json
+ VERSION=$(cat package.json | jq -r .version)
+ echo "VERSION=$VERSION"
+ echo "VERSION=$VERSION" >> $GITHUB_ENV
+ echo "DASHBOARD_VERSION=$VERSION" >> $GITHUB_OUTPUT
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v3
@@ -150,13 +165,36 @@ jobs:
deployment_id: ${{ steps.deployment.outputs.deployment_id }}
env: ${{ needs.initialize-cloud.outputs.POOL_NAME }}
+ - uses: ./.github/actions/testmo/testmo-init
+ if: ${{ contains(github.event.pull_request.labels.*.name, 'run pw-e2e') }}
+ with:
+ testmoUrl: ${{ secrets.TESTMO_URL }}
+ testmoToken: ${{ secrets.TESTMO_TOKEN }}
+ testmoRunName: "Playwright run ${{github.ref_name}}"
+ source: "Playwright-tests"
+ id: init-testmo
+
+ - name: Prepare accounts
+ if: ${{ contains(github.event.pull_request.labels.*.name, 'run pw-e2e') }}
+ id: accounts
+ uses: ./.github/actions/prepare-accounts
+ with:
+ BASE_URL: ${{ needs.initialize-cloud.outputs.BASE_URL }}
+ API_URL: ${{ needs.initialize-cloud.outputs.API_URL }}
+ E2E_USER_NAME: ${{ secrets.E2E_USER_NAME }}
+ E2E_USER_PASSWORD: ${{ secrets.E2E_USER_PASSWORD }}
+ E2E_ENCODE_PASS: ${{ secrets.E2E_ENCODE_PASS }}
+ E2E_PERMISSIONS_USERS_PASSWORD: ${{ secrets.E2E_PERMISSIONS_USERS_PASSWORD }}
+
run-tests:
+ if: ${{ contains(github.event.pull_request.labels.*.name, 'run pw-e2e') }}
runs-on: ubuntu-22.04
needs: [initialize-cloud, deploy-dashboard]
strategy:
fail-fast: false
matrix:
shard: ${{ fromJson(needs.initialize-cloud.outputs.SHARD_MATRIX) }}
+
steps:
- uses: actions/checkout@v4
@@ -172,13 +210,42 @@ jobs:
MAILPITURL: ${{ secrets.MAILPITURL }}
PW_WORKERS: ${{ vars.PW_WORKERS }}
PW_RETRIES: ${{ vars.PW_RETRIES }}
+ ACCOUNTS: ${{ needs.deploy-dashboard.outputs.ACCOUNTS }}
+ E2E_ENCODE_PASS: ${{ secrets.E2E_ENCODE_PASS }}
+ DASHBOARD_VERSION: ${{ needs.deploy-dashboard.outputs.DASHBOARD_VERSION }}
+ BRANCH_NAME: ${{ github.ref}}
+ SALEOR_CLOUD_SERVICE: ${{ needs.initialize-cloud.outputs.SALEOR_CLOUD_SERVICE }}
+
+ - name: submit-results-to-testmo
+ if: always()
+ uses: ./.github/actions/testmo/testmo-threads-submit-playwright
+ with:
+ testmoUrl: ${{ secrets.TESTMO_URL }}
+ testmoToken: ${{ secrets.TESTMO_TOKEN }}
+ testmoRunId: ${{ needs.deploy-dashboard.outputs.TESTMO_RUN_ID }}
merge-reports:
- if: "!cancelled()"
- needs: run-tests
+ if: "!cancelled() && contains(github.event.pull_request.labels.*.name, 'run pw-e2e')"
+
+ needs: [run-tests, deploy-dashboard]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Merge playwright reports
uses: ./.github/actions/merge-pw-reports
+ with:
+ PASSWORD_FOR_DECODING_ARTIFACT: ${{ secrets.TESTS_RESULT_PASSWORD }}
+
+ - name: complete testmo report
+ uses: ./.github/actions/testmo/testmo-finish
+ with:
+ testmoUrl: ${{ secrets.TESTMO_URL }}
+ testmoToken: ${{ secrets.TESTMO_TOKEN }}
+ testmoRunId: ${{ needs.deploy-dashboard.outputs.TESTMO_RUN_ID }}
+
+
+ - name: Create flaky report
+ uses: ./.github/actions/flaky-tests-report
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/publish-containers.yml b/.github/workflows/publish-containers.yml
index dc91aaba13a..d7ecb44e4cb 100644
--- a/.github/workflows/publish-containers.yml
+++ b/.github/workflows/publish-containers.yml
@@ -7,53 +7,44 @@ on:
jobs:
docker:
runs-on: ubuntu-20.04
+
permissions:
contents: read
packages: write
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
# Outputs the name of the repository (owner/repo)
- - name: Get image name
+ - name: Build Image Name
id: image
run: |
IMAGE_NAME=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')
- echo "image_name=ghcr.io/${IMAGE_NAME}" >> $GITHUB_OUTPUT
-
- # Tags stable versions as :latest
- # Pre-releases, alphas, etc. as :snapshot
- - name: Output image tags from git tag events
- if: ${{ startsWith(github.ref, 'refs/tags/') }}
- env:
- GH_TOKEN: ${{ github.token }}
- run: |
- LATEST_VERSION=$(gh api repos/saleor/saleor-dashboard/releases/latest | jq -r .tag_name)
- CURRENT_TAG=${GITHUB_REF#refs/tags/}
+ echo "image_name=$IMAGE_NAME" >> $GITHUB_OUTPUT
- if [ "$LATEST_VERSION" = "$CURRENT_TAG" ]; then
- TAGS=${{ steps.image.outputs.image_name }}:${CURRENT_TAG},${{ steps.image.outputs.image_name }}:latest
- else
- TAGS=${{ steps.image.outputs.image_name }}:${CURRENT_TAG}
- fi
-
- echo "
- DASHBOARD_VERSION=${CURRENT_TAG}
- CONTAINER_TAGS=${TAGS}
- " >> "${GITHUB_ENV}"
+ - name: Docker meta
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: |
+ ghcr.io/${{ steps.image.outputs.image_name }}
+ tags: |
+ type=ref,event=branch
+ type=pep440,pattern={{version}}
+ type=pep440,pattern={{major}}.{{minor}}
- - name: Set up Docker QEMU
- uses: docker/setup-qemu-action@v1
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v3
with:
platforms: arm64
- name: Set up Docker Buildx
id: buildx
- uses: docker/setup-buildx-action@v1
+ uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
- uses: docker/login-action@v1
+ uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -61,21 +52,22 @@ jobs:
- name: Build and Push
id: docker_build
- uses: docker/build-push-action@v2
+ uses: docker/build-push-action@v5
with:
builder: ${{ steps.buildx.outputs.name }}
- context: ./
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+ context: .
+ labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
push: true
- tags: ${{ env.CONTAINER_TAGS }}
- cache-from: type=local,src=/tmp/.buildx-cache
- cache-to: type=local,dest=/tmp/.buildx-cache
+ tags: ${{ steps.meta.outputs.tags }}
build-args: |
COMMIT_ID=${{ github.sha }}
- PROJECT_VERSION=$DASHBOARD_VERSION
+ PROJECT_VERSION=${{ steps.meta.outputs.version }}
- - name: Output image digest
+ - name: Image digest
run: |
echo $"\
Digest: ${{ steps.docker_build.outputs.digest }}
- Tags: ${{ env.CONTAINER_TAGS }}"
+ Tags: ${{ steps.meta.outputs.tags }}"
diff --git a/.github/workflows/run-test-cron.yml b/.github/workflows/run-test-cron.yml
deleted file mode 100644
index 933367a9c04..00000000000
--- a/.github/workflows/run-test-cron.yml
+++ /dev/null
@@ -1,129 +0,0 @@
-name: Run test by cron
-
-on:
- schedule:
- # At 2:00 AM UTC on Monday, Wednesday, and Friday
- - cron: "00 2 * * 1,3,5"
-
-concurrency:
- group: ${{ github.ref }}
- cancel-in-progress: true
-
-jobs:
- initialize-cloud:
- runs-on: ubuntu-22.04
- outputs:
- POOL_NAME: ${{ steps.pool_variables.outputs.POOL_NAME }}
- POOL_INSTANCE: ${{ steps.pool_variables.outputs.POOL_INSTANCE }}
- BASE_URL: ${{ steps.cloud_variables.outputs.BASE_URL }}
- API_URL: ${{ steps.cloud_variables.outputs.API_URL }}
- BACKUP_ID: ${{ steps.cloud_variables.outputs.BACKUP_ID }}
- BACKUP_VER: ${{ steps.cloud_variables.outputs.BACKUP_VER }}
- BACKUP_NAME: ${{ steps.cloud_variables.outputs.BACKUP_NAME }}
- steps:
- - uses: actions/checkout@v4
- with:
- sparse-checkout: ./.github/actions
-
- - name: Generate variables
- id: cloud_variables
- uses: ./.github/actions/prepare-tests-variables
- with:
- CLI_TOKEN: ${{ secrets.STAGING_TOKEN }}
- MODE: main
-
- - name: Prepare instances
- id: pool_variables
- uses: ./.github/actions/prepare-instance
- with:
- STRATEGY: reload
- CLI_TOKEN: ${{ secrets.STAGING_TOKEN }}
- BASE_URL: ${{ steps.cloud_variables.outputs.BASE_URL }}
- API_URL: ${{ steps.cloud_variables.outputs.API_URL }}
- POOL_NAME: ${{ steps.cloud_variables.outputs.POOL_NAME }}
- POOL_INSTANCE: ${{ steps.cloud_variables.outputs.POOL_INSTANCE }}
- BACKUP_ID: ${{ steps.cloud_variables.outputs.BACKUP_ID }}
-
- create-run-on-testmo:
- runs-on: ubuntu-22.04
- needs: initialize-cloud
- outputs:
- testmo-run-id: ${{ steps.init-testmo.outputs.testmo-run-id }}
- steps:
- - uses: actions/checkout@v4
- - uses: ./.github/actions/testmo/testmo-init
- with:
- testmoUrl: ${{ secrets.TESTMO_URL }}
- testmoToken: ${{ secrets.TESTMO_TOKEN }}
- testmoRunName: "Playwright nightly run"
- id: init-testmo
-
- run-tests:
- runs-on: ubuntu-22.04
- needs: ["initialize-cloud", "create-run-on-testmo"]
- strategy:
- fail-fast: false
- matrix:
- shard: [1/2, 2/2]
- steps:
- - uses: actions/checkout@v4
-
- - name: Run playwright tests
- uses: ./.github/actions/run-pw-tests
- with:
- SHARD: ${{ matrix.shard }}
- BASE_URL: ${{ needs.initialize-cloud.outputs.BASE_URL }}
- API_URL: ${{ needs.initialize-cloud.outputs.API_URL }}
- E2E_USER_NAME: ${{ secrets.E2E_USER_NAME }}
- E2E_USER_PASSWORD: ${{ secrets.E2E_USER_PASSWORD }}
- E2E_PERMISSIONS_USERS_PASSWORD: ${{ secrets.E2E_PERMISSIONS_USERS_PASSWORD }}
- MAILPITURL: ${{ secrets.MAILPITURL }}
- PW_WORKERS: ${{ vars.PW_WORKERS }}
- PW_RETRIES: ${{ vars.PW_RETRIES }}
- URL_TO_RUN: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
-
- - name: submit-results-to-testmo
- if: always()
- uses: ./.github/actions/testmo/testmo-threads-submit-playwright
- with:
- testmoUrl: ${{ secrets.TESTMO_URL }}
- testmoToken: ${{ secrets.TESTMO_TOKEN }}
- testmoRunId: ${{ needs.create-run-on-testmo.outputs.testmo-run-id }}
-
- tests-complete:
- if: '!cancelled()'
- needs: ["initialize-cloud", "run-tests", "create-run-on-testmo"]
- runs-on: ubuntu-22.04
- steps:
- - uses: actions/checkout@v4
-
- - name: Merge playwright reports
- uses: ./.github/actions/merge-pw-reports
-
- - name: complete testmo report
- uses: ./.github/actions/testmo/testmo-finish
- with:
- testmoUrl: ${{ secrets.TESTMO_URL }}
- testmoToken: ${{ secrets.TESTMO_TOKEN }}
- testmoRunId: ${{ needs.create-run-on-testmo.outputs.testmo-run-id }}
-
- - name: send message on slack
- working-directory: ".github"
- env:
- run_id: ${{ needs.create-run-on-testmo.outputs.testmo-run-id }}
- url_to_action: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
- testmo_token: ${{ secrets.TESTMO_TOKEN }}
- environment: ${{ needs.initialize-cloud.outputs.BASE_URL }}
- slack_webhook_url: ${{ secrets.SLACK_QA_STATUSES_WEBHOOK_URL }}
- ref_name: ${{github.ref_name}}
-
- run: |
- node workflows/postTestsResults.js \
- --run_id "$run_id" \
- --testmo_token "$testmo_token" \
- --slack_webhook_url "$slack_webhook_url" \
- --environment "$environment" \
- --url_to_action "$url_to_action" \
- --ref_name "$ref_name"
-
-
diff --git a/.github/workflows/run-test-manual.yml b/.github/workflows/run-test-manual.yml
index 74a959e5c40..f76c861b2b0 100644
--- a/.github/workflows/run-test-manual.yml
+++ b/.github/workflows/run-test-manual.yml
@@ -17,10 +17,29 @@ jobs:
BACKUP_ID: ${{ steps.cloud_variables.outputs.BACKUP_ID }}
BACKUP_VER: ${{ steps.cloud_variables.outputs.BACKUP_VER }}
BACKUP_NAME: ${{ steps.cloud_variables.outputs.BACKUP_NAME }}
+ ACCOUNTS: ${{ steps.accounts.outputs.ACCOUNTS }}
steps:
- uses: actions/checkout@v4
+
+ - name: Setup Node
+ uses: actions/setup-node@v3
+ with:
+ node-version-file: ".nvmrc"
+
+ - name: Cache node modules
+ uses: actions/cache@v3
+ env:
+ cache-name: cache-node-modules
with:
- sparse-checkout: ./.github/actions
+ path: ~/.npm
+ key: ${{ runner.os }}-qa-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
+ restore-keys: |
+ ${{ runner.os }}-qa-${{ env.cache-name }}-
+ ${{ runner.os }}-qa-
+ ${{ runner.os }}-
+
+ - name: Install deps
+ run: npm ci
- name: Set variables mode
id: set_variables_mode
@@ -51,6 +70,18 @@ jobs:
POOL_INSTANCE: ${{ steps.cloud_variables.outputs.POOL_INSTANCE }}
BACKUP_ID: ${{ steps.cloud_variables.outputs.BACKUP_ID }}
+ - name: Prepare accounts
+ id: accounts
+ uses: ./.github/actions/prepare-accounts
+ with:
+ BASE_URL: ${{ steps.cloud_variables.outputs.BASE_URL }}
+ API_URL: ${{ steps.cloud_variables.outputs.API_URL }}
+ E2E_USER_NAME: ${{ secrets.E2E_USER_NAME }}
+ E2E_USER_PASSWORD: ${{ secrets.E2E_USER_PASSWORD }}
+ E2E_ENCODE_PASS: ${{ secrets.E2E_ENCODE_PASS }}
+ E2E_PERMISSIONS_USERS_PASSWORD: ${{ secrets.E2E_PERMISSIONS_USERS_PASSWORD }}
+
+
create-run-on-testmo:
runs-on: ubuntu-22.04
needs: initialize-cloud
@@ -63,6 +94,7 @@ jobs:
testmoUrl: ${{ secrets.TESTMO_URL }}
testmoToken: ${{ secrets.TESTMO_TOKEN }}
testmoRunName: "Playwright run ${{github.ref_name}}"
+ source: "Playwright-tests"
id: init-testmo
run-tests:
@@ -84,10 +116,14 @@ jobs:
E2E_USER_NAME: ${{ secrets.E2E_USER_NAME }}
E2E_USER_PASSWORD: ${{ secrets.E2E_USER_PASSWORD }}
E2E_PERMISSIONS_USERS_PASSWORD: ${{ secrets.E2E_PERMISSIONS_USERS_PASSWORD }}
+ E2E_ENCODE_PASS: ${{ secrets.E2E_ENCODE_PASS }}
+ ACCOUNTS: ${{ needs.initialize-cloud.outputs.ACCOUNTS }}
MAILPITURL: ${{ secrets.MAILPITURL }}
PW_WORKERS: ${{ vars.PW_WORKERS }}
PW_RETRIES: ${{ vars.PW_RETRIES }}
+ ENABLED_SERVICE_NAME_HEADER: true
URL_TO_RUN: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
+ PROJECT: "e2e apps-e2e"
- name: submit-results-to-testmo
if: always()
@@ -106,6 +142,8 @@ jobs:
- name: Merge playwright reports
uses: ./.github/actions/merge-pw-reports
+ with:
+ PASSWORD_FOR_DECODING_ARTIFACT: ${{ secrets.TESTS_RESULT_PASSWORD }}
- name: complete testmo report
uses: ./.github/actions/testmo/testmo-finish
diff --git a/.github/workflows/run-tests-on-release.yml b/.github/workflows/run-tests-on-release.yml
index bf46afd25a7..2b6b0966508 100644
--- a/.github/workflows/run-tests-on-release.yml
+++ b/.github/workflows/run-tests-on-release.yml
@@ -37,13 +37,17 @@ on:
TESTS_CONCLUSION:
value: ${{ jobs.tests-complete.outputs.TESTS_CONCLUSION }}
description: conclusion of tests
- RUN_URL:
+ RUN_URL:
value: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
description: Url to job run
-
+ PR_COMMENT:
+ value: ${{ jobs.tests-complete.outputs.PR_COMMENT }}
+ description: Comment for release PR
+
jobs:
add-check-and-prepare-instance:
runs-on: ubuntu-latest
+ timeout-minutes: 30
env:
VERSION: ${{inputs.VERSION}}
CUSTOM_VERSION: ${{inputs.CUSTOM_VERSION}}
@@ -60,21 +64,43 @@ jobs:
CHECK_ID: ${{ steps.create-check.outputs.CHECK_ID }}
FRAMEWORK: ${{ steps.check-framework.outputs.result }}
IS_OLD_VERSION: ${{ steps.get-environment-variables.outputs.IS_OLD_VERSION }}
+ ACCOUNTS: ${{ steps.accounts.outputs.ACCOUNTS }}
steps:
- uses: actions/checkout@v4
+ - name: Setup Node
+ uses: actions/setup-node@v3
+ with:
+ node-version-file: ".nvmrc"
+
+ - name: Cache node modules
+ uses: actions/cache@v3
+ env:
+ cache-name: cache-node-modules
+ with:
+ path: ~/.npm
+ key: ${{ runner.os }}-qa-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
+ restore-keys: |
+ ${{ runner.os }}-qa-${{ env.cache-name }}-
+ ${{ runner.os }}-qa-
+ ${{ runner.os }}-
+
+ - name: Install deps
+ run: npm ci
+
- id: check-framework
uses: actions/github-script@v7
env:
VERSION: "${{inputs.VERSION}}"
with:
+ result-encoding: string
script: |
const { VERSION } = process.env
const versionWithoutDot = VERSION.replaceAll(/\./g, "")
if(versionWithoutDot >= 319){
- return "playwright"
+ return "Playwright-tests"
}else{
- return "cypress"
+ return "Cypress-tests"
}
- name: Create check if release PR exists
@@ -112,6 +138,7 @@ jobs:
testmoUrl: ${{ secrets.TESTMO_URL }}
testmoToken: ${{ secrets.TESTMO_TOKEN }}
testmoRunName: "${{ steps.check-framework.outputs.result }} run ${{ env.CUSTOM_VERSION }}"
+ source: ${{ steps.check-framework.outputs.result }}
id: init-testmo
- name: get environment variables
@@ -126,13 +153,25 @@ jobs:
--repo_token "$REPO_TOKEN" \
--project "$PROJECT"
+ - name: Prepare accounts
+ id: accounts
+ uses: ./.github/actions/prepare-accounts
+ with:
+ BASE_URL: ${{ steps.cloud_variables.outputs.BASE_URL }}
+ API_URL: ${{ steps.cloud_variables.outputs.API_URL }}
+ E2E_USER_NAME: ${{ secrets.E2E_USER_NAME }}
+ E2E_USER_PASSWORD: ${{ secrets.E2E_USER_PASSWORD }}
+ E2E_ENCODE_PASS: ${{ secrets.E2E_ENCODE_PASS }}
+ E2E_PERMISSIONS_USERS_PASSWORD: ${{ secrets.E2E_PERMISSIONS_USERS_PASSWORD }}
+
run-cy-tests:
- if: needs.add-check-and-prepare-instance.outputs.FRAMEWORK == '"cypress"'
+ if: needs.add-check-and-prepare-instance.outputs.FRAMEWORK == 'Cypress-tests'
needs: add-check-and-prepare-instance
runs-on: ubuntu-22.04
- container:
+ timeout-minutes: 30
+ container:
image: cypress/browsers:node18.12.0-chrome106-ff106
- options: --user 1001
+ options: --user 1001
strategy:
fail-fast: false
matrix:
@@ -172,7 +211,7 @@ jobs:
mailpitUrl: ${{ secrets.CYPRESS_MAILPITURL }}
stripeSecretKey: ${{ secrets.STRIPE_SECRET_KEY }}
stripePublicKey: ${{ secrets.STRIPE_PUBLIC_KEY }}
- cypressGrepTags: ${{steps.set-tag-for-tests.outputs.result}}
+ cypressGrepTags: ${{steps.set-tag-for-tests.outputs.result}}
split: ${{ strategy.job-total }}
splitIndex: ${{ strategy.job-index }}
commitInfoMessage: All tests triggered via ${{ github.event_name}} on ${{ steps.get-env-uri.outputs.ENV_URI }}
@@ -189,7 +228,8 @@ jobs:
run-pw-tests:
runs-on: ubuntu-22.04
needs: "add-check-and-prepare-instance"
- if: needs.add-check-and-prepare-instance.outputs.FRAMEWORK == '"playwright"'
+ timeout-minutes: 30
+ if: needs.add-check-and-prepare-instance.outputs.FRAMEWORK == 'Playwright-tests'
strategy:
fail-fast: false
matrix:
@@ -208,10 +248,13 @@ jobs:
E2E_USER_NAME: ${{ secrets.E2E_USER_NAME }}
E2E_USER_PASSWORD: ${{ secrets.E2E_USER_PASSWORD }}
E2E_PERMISSIONS_USERS_PASSWORD: ${{ secrets.E2E_PERMISSIONS_USERS_PASSWORD }}
+ E2E_ENCODE_PASS: ${{ secrets.E2E_ENCODE_PASS }}
+ ACCOUNTS: ${{ needs.add-check-and-prepare-instance.outputs.ACCOUNTS }}
MAILPITURL: ${{ secrets.MAILPITURL }}
URL_TO_RUN: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
PW_WORKERS: ${{ vars.PW_WORKERS }}
PW_RETRIES: ${{ vars.PW_RETRIES }}
+ PROJECT: "e2e apps-e2e"
- name: submit-results-to-testmo
if: always()
@@ -226,6 +269,7 @@ jobs:
!cancelled() && always()
needs: ["add-check-and-prepare-instance", "run-cy-tests", "run-pw-tests"]
runs-on: ubuntu-22.04
+ timeout-minutes: 30
outputs:
TESTS_CONCLUSION: "${{ steps.send-slack-message.outputs.status }}"
steps:
@@ -240,11 +284,13 @@ jobs:
run: npm ci
- name: Merge playwright reports
- if: needs.add-check-and-prepare-instance.outputs.FRAMEWORK == '"playwright"'
+ if: needs.add-check-and-prepare-instance.outputs.FRAMEWORK == 'Playwright-tests'
uses: ./.github/actions/merge-pw-reports
+ with:
+ PASSWORD_FOR_DECODING_ARTIFACT: ${{ secrets.TESTS_RESULT_PASSWORD }}
- name: Merge cypress reports
- if: needs.add-check-and-prepare-instance.outputs.FRAMEWORK == '"cypress"'
+ if: needs.add-check-and-prepare-instance.outputs.FRAMEWORK == 'Cypress-tests'
uses: ./.github/actions/combineReportsFromE2E
- name: complete testmo report
@@ -273,7 +319,7 @@ jobs:
--environment "$ENVIRONMENT" \
--url_to_action "$URL_TO_ACTION" \
--ref_name "$REF_NAME" \
- --additional_title "$ADDITIONAL_TITLE"
+ --additional_title "$ADDITIONAL_TITLE"
- id: update-check
if: always() && ${{ needs.add-check-and-prepare-instance.outputs.CHECK_ID }}
@@ -293,7 +339,7 @@ jobs:
if: |
always() &&
(needs.tests-complete != 'success' && cancelled()) &&
- needs.add-check-and-prepare-instance.outputs.FRAMEWORK == '"playwright"'
+ needs.add-check-and-prepare-instance.outputs.FRAMEWORK == 'Playwright-tests'
steps:
- uses: actions/checkout@v4
@@ -318,4 +364,4 @@ jobs:
CONCLUSION: "failure"
TITLE: "Automation tests run"
SUMMARY: "Run failed"
- DETAILS_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
\ No newline at end of file
+ DETAILS_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 95b285b5cc0..d3ee07e651f 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -1,6 +1,6 @@
name: QA
-on: [pull_request]
+on: push
jobs:
check-lock:
@@ -42,6 +42,9 @@ jobs:
run: |
npm run lint
git diff --exit-code ./src
+
+ - name: Knip for unused files, dependencies and exports
+ run: npm run knip
jest-tests:
runs-on: ubuntu-latest
@@ -69,7 +72,13 @@ jobs:
- name: Run jest
run: |
- npm run test
+ npm run test:ci
+
+ - name: Upload coverage reports to Codecov
+ uses: codecov/codecov-action@v5
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ slug: saleor/saleor-dashboard
translation-messages:
runs-on: ubuntu-latest
diff --git a/.gitignore b/.gitignore
index 7ff7cb5621e..697d44c3706 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,7 @@
!.tx
!.husky
!.changeset
+!.knip.json
*.log
*.pyc
*.mo
diff --git a/.knip.json b/.knip.json
new file mode 100644
index 00000000000..ab764e07d29
--- /dev/null
+++ b/.knip.json
@@ -0,0 +1,50 @@
+{
+ "$schema": "https://unpkg.com/knip@5/schema.json",
+ "rules": {
+ "types": "off",
+ "enumMembers": "off",
+ "files": "off",
+ "exports": "off",
+ "duplicates": "off",
+ "classMembers": "error",
+ "nsTypes": "error",
+ "unresolved": "error",
+ "nsExports": "error",
+ "unlisted": "error",
+ "binaries": "off",
+ "optionalPeerDependencies": "error",
+ "dependencies": "error",
+ "devDependencies": "error"
+ },
+ "ignore": ["playwright/**", "**/*.js"],
+ "ignoreDependencies": [
+ "@graphql-codegen/typescript-apollo-client-helpers",
+ "@graphql-codegen/typescript-operations",
+ "@graphql-codegen/typescript-react-apollo",
+ "@graphql-codegen/add",
+ "@graphql-codegen/fragment-matcher",
+ "@graphql-codegen/import-types-preset",
+ "@graphql-codegen/typescript",
+ "@material-ui/styles",
+ "keycode",
+ "tslib",
+ "@swc/jest",
+ "@types/lodash-es",
+ "@types/webappsec-credential-management",
+ "core-js",
+ "identity-obj-proxy",
+ "moment",
+ "history",
+ "react-transition-group",
+ "@radix-ui/react-radio-group",
+ "@react-editor-js/core",
+ "@radix-ui/react-portal",
+ "@graphql-codegen/schema-ast",
+ "@sentry/cli",
+ "playwright-testmo-reporter",
+ "mocha",
+ "mochawesome",
+ "mochawesome-report-generator",
+ "mochawesome-merge"
+ ]
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 825c32f0d03..4012941b847 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1 +1,532 @@
# Changelog
+
+## 3.20.28
+
+### Patch Changes
+
+- 2ab3653: Product types list page uses now new filters. New filters are under feature flag and are enabled by default.
+- 6ece8a5: Test reports no longer mention users due to test tags matching GitHub usernames. Replace overlooked tag
+- 3fdd2b2: Staff members list page use now new filters. New filters are under feature flag and are enabled by default.
+- a04abc7: You can now save, update, and delete filter presets on a product types list
+- eb76fa3: Publish only the table with the summary on PRs, now includes a quick link to the job summary. Added ISO formatted date to the report for future flakiness measurement.
+- 402c88d: Modify menu tests to ensure the first item in the list is visible before proceeding.
+- 9078b4b: Gather all single feature flags for filters into one
+- 3b92997: Collection list filters have been ported to expression filtering. This means you can now use new filters in the Collection list.
+- 5640a9d: Test reports no longer mention users due to test tags matching GitHub usernames.
+- 5434419: You can now save, update and delete filter presets on the warehouse list page
+- b7bc6a9: Now, non-code related files are not included in codecov report.
+- 2d7fde8: Now tests results in ctrf scheme are attached to job and results are published in job summary and PR.
+- 50d6564: Now, the files for collecting coverage was explicitly set, this means we will include also files that are not covered.
+- 428bad7: Now the test coverage is being raported and tracked
+- f3e75bc: List of customers now uses conditional filters
+- 3862c59: Gift cards list page use now new filters. New filters are under feature flag and are enabled by default.
+- 24c613d: List of draft orders now use new filters
+- ceb1919: List of vouchers now use new filters
+- 3232550: Apply improvments for new filters so they looks align
+- 053be92: List of pages now uses conditional filters
+- 659a7c2: Attributes list page use now new filters. New filters are under feature flag and are enabled by default.
+- edf962c: Tests reports from artifacts will be protected by password
+
+## 3.20.27
+
+### Patch Changes
+
+- a4041bb: Now product links on the collection points to the correct url.
+
+## 3.20.26
+
+### Patch Changes
+
+- f0870c5: Opening item in new tab using cmd key on datagrid now takes into account mounting point
+- 87b8124: Now you can re-order products within the collection.
+- 19bdcd4: Order transaction list now displays the name of a transaction
+- e0f586e: Now you can see pageviews in the posthog.
+- 1c3a125: You can now edit note in order details. Notes in order details now show id of note, id of related note and type of note "added" or "updated"
+- 41dfb69: You can now open datagrid list item in new tab using cmd/ctrl button
+- a3a1eca: After creating a new collection, you should see a list of assigned channels
+- 79b8255: Modals in the Dashboard are now aligned, all have the same max height. Loading items on scroll works when the dialog is displayed in large screen.
+- 08e3449: Dashboard now sends source header to API, when ENABLED_SERVICE_NAME_HEADER=true. Requires core >=3.20.68.
+- 36bc1be: Activates list items on the welcome page no longer implies that they are clickable
+- 52cf576: Editor.js no more cause error during saving
+- 6a4f082: You can now navigate back from collection details to collection list
+
+## 3.20.25
+
+### Patch Changes
+
+- c9df392: Order sidebar now uses buttons from new macaw
+- 9737ff3: Collection details page uses now Buttons from new macaw
+- 616ad52: You can now see buttons from macaw-ui-next in customer details view and gift card details view.
+- cb5fd4f: Add tracking button on order details uses button from new macaw
+- 1053db7: Users are now properly anonymously identified
+- ba9d6f5: This Pr is separating sources in testmo for playwright and cypress tests, and adding results for runs on PR to testmo
+
+## 3.20.24
+
+### Patch Changes
+
+- f986ca7: You can now see contextual links to documentation in product, webhooks, order, staff members lists and Graphql Playground panel.
+- 3c9889b: Some sentry errors have been fixed.
+- 4ea5566: Now CI workflows use updated action to upload and download artifacts
+- b44516b: You can now use custom auth headers in graphiql dev mode panel.
+- 5717954: Now there can only be one login request running at a time. This means using a password manager to log in no longer cause an error. If there are too many login requests Dashboard now shows a corresponding error message.
+- e2ce3c4: Product data is now properly displayed in webhook dry run modal.
+ Add warning alert in webhook dry run modal for webhooks that don't have a valid object ids.
+- 65ae19b: Batch of sentry errors has been fixed
+- 109565e: Added explicit max width to transaction event tooltip. Thanks to that longer message won't overflow.
+- d939e6b: Added switch focus using tab button, that may delay saving before input is filled.
+- 0be566e: Posthog no longer collect the events from the staging environments. This means we track the data only in production environments.
+- d56c9a5: Prevent a call update channel after voucher create when no voucher id returns from response
+- f1f9898: App buttons no longer clip with app contents
+- d120bae: Removed waitFor and set expanded metadata section to avoid flakyness
+- 081c5c0: Now category and subcategories show proper description
+- ffaa00f: You can now close order manual transaction modal by clicking the close button
+- 4b42974: Split select link option into 2 different ones to avoid flakyness in tests
+- 184297b: Now it's possible to filter orders by its metadata.
+- 35b508d: Warning banner in tax settings and delete app modal now display properly in dark mode
+- 6a89f7a: Add GitHub Workflow to check licenses
+- 752b988: Playwright tests raport is generated even test failed
+- 85fd37c: Add explicit waits for draft order shipping carrier button interaction
+- f0cd832: Run test by cron workflow has been removed
+- 35a74fb: Now webhooks permission alert displays appropriately in dark mode
+- 47d93f0: Increased the maximum display length for `plainText` attribute to 10,000 characters.
+- 7b0c73b: Discounts no longer blocks the UI when the user has no permissions for managing channels.
+
+## 3.20.23
+
+### Patch Changes
+
+- 3c4462a: App buttons no longer clip with app contents
+- ea74e8a: Warning banner in tax settings and delete app modal now display properly in dark mode
+
+## 3.20.22
+
+### Patch Changes
+
+- e964e95: You can now see contextual links to documentation in product, webhooks, order, staff members lists and Graphql Playground panel.
+- fb56837: Now there can only be one login request running at a time. This means using a password manager to log in no longer cause an error. If there are too many login requests Dashboard now shows a corresponding error message.
+- 20b10c7: Removed waitFor and set expanded metadata section to avoid flakyness
+- 3299739: Run test by cron workflow has been removed
+- 1b5b001: Now webhooks permission alert displays appropriately in dark mode
+
+## 3.20.21
+
+### Patch Changes
+
+- 8d08677: Removing value from area input in address form no more cause error
+- c48e50b: The app no longer changes the url when it is already been updated.
+- 38d9a92: Selecting sale entries no longer fails when browsing the sales list
+- 315676c: The double success banner no longer appears during app installation
+- 3e89b07: Assign product dialog no more crash when product has no channels
+- 36fb327: Prevent a call update channel after voucher create when no voucher id returns from response
+- 917c0f8: Adding tranalstions to shipping methods no more cause error
+- 5013483: Assigning product to collection no more cause error
+- 749a09f: Update variant file attribute value no more cause error
+
+## 3.20.20
+
+### Patch Changes
+
+- a40691f: Environments created via Saleor Cloud now identify and report to PostHog. This means Dashboard now sends telemetry data regarding home page onboarding steps and links.
+- da3e53b: Removed unnecessary expect that was waiting for the success banner, as it was causing delays on CI. Instead, the test rely on other assertions to verify that changes have been applied
+- 3f2ca21: Onboarding state is now stored in user metadata, that means that onboarding state is persisted between logins on different machines
+- c40fdf7: Add environment variables to GitHub Workflow to control when to show onboarding for new users
+- d677431: Now the list app page shows footer that allows the user to sumbmit a demanded app.
+- 479ae66: Merged expectSuccessBannerMessage and expectSuccessBanner into a single method, removed the redundant method, and updated tests to use the new unified method.
+- 24691c4: Rename newHome to wecomePage to allow seamlessly removing a feature flag
+- 13f63c2: New home page layout is now reponsive, it means that layout adjusts to desktop, tablet and mobile devices
+- 67687b3: User onboardng steps are now checking when user does required actions
+- e947997: E2E tests are now updated for new home page meaing that they don't fail when new home page is enabled.
+- 18a4eae: Activity section in home page now has uniform padding with header, stock and sales.
+- f1e5f34: Enhanced success banner verification in basePage.ts by adding network idle state check and parallel assertions, while modernizing array operations in shipping methods tests using spread syntax instead of .concat()
+- 0c2971b: Add integration test for new home sidebar
+- fab4b4e: Refactored tests by replacing direct banner visibility checks with `expectSuccessBanner()`.
+ Removed unnecessary `waitForNetworkIdleAfterAction` wrappers.
+ Simplified test scope for `staffMembers` and removed explicit timeouts where appropriate.
+- f9130c4: You can now see an onboarding component that guides the user through Saleor Dashboard features.
+- 9cd4da2: You can now see new sidebar with analytics and activities
+- 981a0bc: Removed waitForNetworkIdleAfterAction and replaced it with a direct navigation call.Added blur actions on metadataKeyInput and metadataValueInput to ensure input stability before saving in scope of SALEOR_128
+- 6990b1e: New home page with onboarding is now enabled, old home page code has been removed
+- d9600ab: Removed waitForNetworkIdleAfterAction and added direct element waits to ensure readiness before actions.
+- e48622c: Test set now includes tests for welcome page onboarding component.
+- 8bc92e3: You can now see information tiles regarding Saleor Docs, community, and technical help in the home page.
+- 4d9d127: Adjust inline discount test for precise floating-point comparison with .toFixed(2)
+- 7250d03: Padding under home page tiles is now increased to prevent clipping
+
+## 3.20.19
+
+### Patch Changes
+
+- fd98d31: Selecting sale entries no longer fails when browsing the sales list
+- 05a2be7: Variant creation no longer reports an error when API call fails, this means this scenario is now handled gracefully.
+- bd125e8: List item links are no longer rendered outside of cursor. This means you can now copy the item's URL with mouse right click or use middle click to open page in new tab.
+- 747030e: Enhanced success banner verification in basePage.ts by adding network idle state check and parallel assertions, while modernizing array operations in shipping methods tests using spread syntax instead of .concat()
+- 73f4a95: Refactored tests by replacing direct banner visibility checks with `expectSuccessBanner()`.
+ Removed unnecessary `waitForNetworkIdleAfterAction` wrappers.
+ Simplified test scope for `staffMembers` and removed explicit timeouts where appropriate.
+- e1c0868: The "Save" button in Change Password form now submits the form data to Saleor.
+- f4466d9: Now, codeql action is no longer needed since we enabled code analysis via GH configuration with default settings.
+- a28cd97: Prepare base layout for new home, hide new home page under feature flag
+- 54e77d2: You can now select attribute value from dropdown in datagrid cell
+- 82cd647: Adjust inline discount test for precise floating-point comparison with .toFixed(2)
+
+## 3.20.18
+
+### Patch Changes
+
+- 9436450: Optimize test by reusing an existing order instead of creating a new one
+- 3db9f24: Increase global single test timeout to avoid false neagtive test results
+- abdd791: Refactor tests to replace `waitForDOMToFullyLoad` with `waitForLoaderToDisappear`, making the test shorter by waiting only for the loader to disappear instead of the entire DOM to load.
+- 711c368: Upgrade lz-string library to version that supports MIT license
+
+## 3.20.17
+
+### Patch Changes
+
+- 725ab22: `.env.template` no longer references Demo environment.
+- 4feda35: Increase global single test timeout to avoid false neagtive test results
+- 55988f0: Moving test cases for activation and deactivation staff members to other file and running it in serial mode to avoid login in two tests in the same time (it can cause error with code LOGIN_ATTEMPT_DELAYED)
+- 048b0fb: Added support for the new channel setting: `checkoutSettings.automaticallyCompleteFullyPaidCheckouts`. Setting can be changed in channel configuration page.
+- a230369: Link value input in Navigation no longer overrides input value with cached value.
+
+## 3.20.16
+
+### Patch Changes
+
+- 8f225fa: Fixes a bug when the text truncating breaks on undefined attribute value.
+
+## 3.20.15
+
+### Patch Changes
+
+- bfb6237: Mailpit service uses has been removed due to issues with checking email during E2E runs on PRs. This means the tests no longer check if export emails have been received.
+- 5b50332: The value of attribute type `plainText` is now capped. This prevents the UI from freezing when the value is very large.
+- 3948065: The tax app version no longer displayed in the tax select input because showing the initial installed app version caused confusing
+
+## 3.20.14
+
+### Patch Changes
+
+- 12edac4: Now dependencies are installed properly in our pipelines, this means auth scripts are no longer stopping.
+- d15aff5: Now, swatch presents the preview of the selected image.
+- 80869fb: When deleting product type with products the "View products" link now navigates to product list with correctly applied product type filter
+- b9c8291: Now cron-workflow that runs e2e tests takes proper urls to for preparing accounts action
+- 6c85d52: Back buttons now navigate to the list with previously used filters and pagination applied.
+- 89b9170: "changeset/cli" version is now bumped to the latest version
+- 75751b0: Now the create category button is consistent with the other views
+- 4ef03df: When navigating to order details from the order list, the back button will now return you to the previous page with the same filters and pagination applied.
+- 4e0a555: Now accounts are decoded using an encryption key
+
+## 3.20.13
+
+### Patch Changes
+
+- 04d16fc37: Add e2e for managing products on draft order. Add e2e for placing draft order for non-existing customer.
+- 8ea94af11: Enable by default feature flag for discount rules. Remove feature flags for product and order expression filters, so that expression filter will always show. Cleanup dead code after remove feature flags.
+- 1ff350a22: Assigning product to shipping method weight rate no more cause error
+- be5d5e65e: Modals in the Dashboard have been aligned, so that all contains close button
+- fc80e34ef: Knip was added to the codebase and workflow triggered on pull request. This means developers will now be informed about unused exports and files.
+
+## 3.20.12
+
+### Patch Changes
+
+- 8db152e60: Clicking a select channel on a product list and then click close button clear filter state, so when you click again select button, only one channel filter will be selected
+- 3f74d5cb2: You can now see app's webhooks' event delivery attempts in app settings. These include last 6 failed or pending deliveries with their details: payload, status and date.
+- c330adeb7: You can now provide 0 variant price value during product creation
+- 350194c3d: Removing not required dropdown attribue value no longer cause error
+
+## 3.20.11
+
+### Patch Changes
+
+- 9fb5665f1: Test for readonly access to apps are more table, so that should not check anything before content load.
+- 858439dd7: You can now see a new card in home page that can redirect you to Saleor solution engineers contact information if you need technical advice.
+- e831f9b95: Selecting channel from product list does not trigger URL change, so that clicking "Select channel" button without selecting channel will not be saved in URL.
+- cce3b2cba: Adds conditional logic to the Merge Playwright Reports workflow, ensuring that the merge and upload steps are only triggered when the pull request has the run pw-e2e label applied.
+- a5b84712a: Implementing timeouts ensures the workflow automatically terminates jobs taking too long, improving resource utilization and avoiding potential workflow hangs.
+- 7e1e6a10d: Some end-to-end Playwright tests now have extended timeouts for UI elements to load. This means that automation tests should fail less. Playwright retires value has been set to 0.
+- bd54e6b54: Fix a group of errors caused by reading property of undefined
+
+## 3.20.10
+
+### Patch Changes
+
+- 73387c130: History timeline sections now have a bolded, dark header without a line separating them from the events.
+- e91e592f7: E2E tests are no longer executed on every commit, this means performing e2e tests happens only when you add a label "run pw-e2e"
+- 660f6c119: Users with "MANAGE_STAFF" permission no longer get an error when entering order details. This means that to access `privateMetadata` in variant "MANAGE_PRODUCTS" permission is required.
+- 55d5a5f44: Shipping destination alert when creating a new order now has a correct link to shipping settings.
+- 3dc1c6d9b: Grid no longer crashes when removing row.
+
+## 3.20.9
+
+### Patch Changes
+
+- 069e6cc2c: You can now make a refund with shipping costs or custom shipping amount. This means you can make a refund without selecting line items.
+
+## 3.20.8
+
+### Patch Changes
+
+- 640d5f6f5: SALEOR_119 now has increased timeouts for app instalation. This means the test should fail less.
+- 09cf2adaf: SALEOR_191 now waits for the refund page to fully load
+- 0eb90df03: Menu item dialog now use components form new Macaw
+- bef2cbde2: Docker images will be automatically tag with with both the full version and just the minor
+- 331af3943: You can now see draft order alert messages when channel is inactive or has no products
+- ba5d47e8e: Modals for adding discounts and confirming deletion now use new MacawUI styles
+- 942bb01db: Now you can set proper attribute value when editting content page.
+- 762463819: Dashboard now scrolls the product list page to the top when you click on "Select channel" so that you can see the filter window
+- ece769a9a: The gift card modals now use new macaw-ui components.
+- 330012e11: MacawUI in Dashboard is now the newest available version. Dashboard no longer shows an error while installing packages. Price in shipping method select component now aligns to the right.
+- f1b06f8e8: Remove skip from installing app tests and update workflow to run it only on releases or manual
+- c052612f6: Now manual tests and tests on release can run on multiple projects
+
+## 3.20.7
+
+### Patch Changes
+
+- ce05ffba2: Order details page now displays the name of the applied voucher.
+- f8e6049fe: Now staging environments have changed domain, that means "staging-cloud.saleor.io" is no longer referenced in our pipelines
+- b428bcd9f: Legacy Dialog component is no longer used
+- e5bfa1218: You can now navigate on dropdown list. Dropdown stays close on focus.
+- bbba0d2dc: You can now see permission edit list use default list color instead of accent blue color.
+- 642e9f7cb: Showing negative amount in order details has been aligned
+- efbca2b00: Now, missing translations are properly added to the order details.
+- 037c67cb2: The stock settings no longer show a message that you need to create a warehouse when warehouses are already configured.
+- f879d525a: App install error page now uses macaw-ui-next styles meaning that MaterialUI is no longer used in this view.
+
+## 3.20.6
+
+### Patch Changes
+
+- c8a6d86d0: Login, password reset and error pages now use new Macaw buttons, text and styles.
+- 5e3cc3fa0: You can now see a message instead of a loading animation when there are no categories, collections, products or variants assigned in Discounts
+- 48b4146a0: You can now add and remove tags for gift cards without any application crash
+- edaf42b95: Gift card details page and customer details page no longer crash when you have only some required permissions. This means that you can now view gift card details page if you have only gift card permissions and customer details page if you have only customer permissions.
+- e73034386: You can click save button on voucher creation page to trigger validation
+- 6289fbde4: You can now delete draft voucher codes during creation of new voucher
+- 061412866: You can now update quantity per checkout in site settings
+- 9434aea16: Make MenuItems' container scrollable in navigation section
+
+## 3.20.5
+
+### Patch Changes
+
+- 0b9296f1c: You can now replace all environment variables instead of only API_URL in Docker and nginx
+- d29c3f89d: Tests for shipping methods now wait to content load to start test
+- fd29d47cb: Now developer can see the traces within Sentry
+- f89484cc4: Plugin details view now displays channel list with proper padding and text with proper size.
+- b464ee243: Now sentry sample rate sents only 10% of the traffic
+- cfe015ab2: You can now see errors when required attributes are empty during product or page edition
+- a1420b2c4: Page type page now displays section description in multiple lines.
+- 8b345e605: Transaction capture modal no longer shows "Error" text when API error occurs. This means that the modal closes when mutation finishes so that result is visible.
+- cf2eb131f: Now you can see initials in your account details when there is no avatar image set for your account.
+- ef1c9cba5: Subscription query editor no longer shows incorrect required permissions for inserted query.
+- 5098f2674: You can now assign more than 22 attribute for product and page type
+- 508e53e6f: Category input in product page is no longer collapsed when empty
+
+## 3.20.4
+
+### Patch Changes
+
+- 55d49ee01: You can now run all e2e tests without attributes.spec interference
+- e094fa61e: The migrated dropdown components and there types no longer exist within the codebase
+- e14df76d8: You can now run E2E tests locally with no issues
+- 54b212460: Rich text editor errors related to 'holder' no longer are sent to Sentry.
+- 4a593993c: You can run order e2e tests with updated test data
+- e635bc153: You can now view channel and product details pages on tablets
+- f29141acc: You can now search by order number in Navigator search.
+- a711406f2: Components that show app token now display text in multiple lines instead of one.
+
+## 3.20.3
+
+### Patch Changes
+
+- bd8fc8757: You can run e2e test for an order type discount in a draft order
+- b39b04c50: Text in Dashboard now is aligned and is displayed correctly
+
+## 3.20.2
+
+### Patch Changes
+
+- fd36e8e08: From now dashboard will be deployed to load test services in dev cloud
+- 6f45d4435: Drop legacy Dialog and replace it with new macaw Dialog component in action dialogs,
+ order change warehouse dialog, order payment dialog, add staff member dialog,
+ staff user password restart dialog, tax select country dialog.
+- 5b8262d72: Button for adding new refund now has a shorter label
+- a565113e6: Fix custom ref checkout in dev deployment CI workflow
+- 9f10e1bdb: Dashboard no longer uses Typography and Skeleton from Material. These components were replaced with MacawUI ones
+- 088842b70: You can run E2E tests for inline discounts in draft orders
+- a77ff9f9e: You can now see tax dropdown taking full width
+- 15d5b8747: Saleor Dashboard no longer uses MUI Card component, it uses DashboardCard instead.
+- 5a1025570: Add new service to dev deployment CI workflow
+
+## 3.20.1
+
+### Patch Changes
+
+- 81d909bd1: You can now see macaw ui migration progress
+- 125883658: Product variant forms now show missing price and name errors when these fields are empty.
+- 55e72b855: Edit refund view no longer display title with typo when edit refund with line items
+- 27a47265a: The legacy selects are no longer present within the codebase, this means you should use the ones from new macaw when developing the UI
+- d4e284996: You can run e2e for updating order with non-manual refunds in status draft/failure
+
+## 3.20.0
+
+### Minor Changes
+
+- 618bb01aa: E2E Fixing flaky navigation tests
+- f9d1b2b7c: Adding CodeInspector plugin
+- 8943ae241: Now you can see columns and their ordering that you previously selected when swtich betetween listing pages.
+- 563b86557: Add tests for thirdparty apps
+- 1fc4c348d: Swap new refund with with old one when feature flag toggle
+- cb5988f38: E2E tests for customer CRUD
+- 8856e2f03: You can now see Marketplace app list on automation deployment.
+- 1dcb956f4: Adding e2e tests for promotion CRUD
+- bdfb5e8e3: Now selected columns on the product list are being saved when browsing order details.
+- 12622c182: Migrate dashboard to new font tokens
+- 6c5be6662: Fix flaky test - TC: SALEOR_3 Create basic product with variant
+- 5c30c8d46: Replace back icon with cloud one in sidebar return to cloud link, update copy to just Saleor Cloud
+- 2111f9305: Now, the developer can access sidebar components on each page directly.
+- e08dd6420: Introduces new refund flow for orders that allow users to refund items base on transactions. Grant refund and send refund is a single flow. User first has to create draft refund and then can transfer funds in one flow.
+- bed0fa3b5: The list of transactions is now placed under the new section called "Transactions" when you visit order details page
+- 93f5dcebf: You can now run e2e test for a manual refund type
+- f1e716e86: Order Refund views no longer display duplicated errors or no errors at all when submitting the form.
+- c14402c4a: You can now run E2E Playwright tests for staff members CRUD
+- 687b1346e: You can now browse listing pages without additional reloadings
+- e02050a43: This change adds a reusable GridTable component for ephemeral data edition.
+- a9745e492: Remove brackets next to each order status title due to cause confusing for the clients
+- 66f565d24: Adding tests for promotion rules CRUD
+- ca23d8547: You can now create refund with lines even if all lines have been previously refunded.
+- f7bb80cbe: The API_URI is no longer used across the codebase. API_URI stays in workflows for backward compatibility
+- 0589970ef: Always show charge and authorized amount in payment section of order details
+- d9bc7544e: Cypress tests are no longer possible to be executed
+- 9c5e78652: This change disallows creating refund for orders created in transaction flow channels that have no transactions, as well as orders that have no refundable transactions
+- 92ed22708: Allow to manually override number of shards to use during manual re-runs
+- 68eb5cd62: Refund add dialog no longer allows proceeding to refund with lines view when all lines have been refunded and manual refund view when user doesn't have payment permissions.
+- 9b87e78d4: You can now select created at column in product list
+- 202b18fb5: Refactoring playwright setup file and moving auth specs
+- 1c01b463a: Modal for refund reason now has an improved copy
+- 4c919c106: Grid peersistance implementation
+- 172bbe089: Adding prettier for code formatting
+- be40ffd78: Fixing flaky tests - TC: SALEOR_32 and TC: SALEOR_33
+- 4603cc532: Refund with lines view no longer allows creating/editing a refund with amount exceeding charged amount for selected transaction
+- ceada3108: Changed trigger to workflow_dispatch and switched from issues to pr as a source of metrics
+- d65766193: Warning message on manual refund view is no longer unreadable on dark mode
+- b3a87cd5e: Implement refund add modal
+- 1c8df0f59: Refund table now displays user initials on the avatar and full name on hover instead of an email.
+- f25bf71fc: Adding e2e tests for permission groups
+- 06678d0bd: Fixing flaky test - TC: SALEOR_106 Issue gift card with specific customer and expiry date
+- e2e5c716c: Add playwright tests for edit and remove product types
+- dbfe9b7f7: Rewritten tests for setting balance and exporting gift cards
+- f84515021: E2E Test for adding promotion rules
+- 08b55d409: Fixing flaky e2e tests
+- d46265dfe: Introduce view for manual refund transaction
+- b41583432: E2E Playwright tests: SALEOR_187, SALEOR_205, SALEOR_59, SALEOR_198, SALEOR_106 are no longer flaky
+- 6597aaaef: Fixes incorrect button label for adding or editing refund reason
+- ae560bf9d: Fixing assertions in flaky Playwright tests
+- 1a3748728: Adding the new variant as a row is no longer possible from the product details. This means "add new variant" button now leads you to the variant creation page
+- 04ca14958: For old verions tests with "old release" tag will be executing. Additionally adds more detailed title to results on slack and testmo"
+- c0031af37: Amount input in refund form no longer displays incorrectly formatted prices after recalculation
+- 1bfc3f5ab: Transaction refund related views no longer display confusing descriptions.
+- c3ca12283: You can now toggle improved refund flow in features preview
+- 3af5ac04c: Filters for orders now allow filtering by ID. This means its form handles one or multiple ID that you can attach by using comma, space, or enter for separation.
+- ca83d3acb: Manual refund form no longer allows values greater than charged amount for selected transaction and now allows positive values lower than 1
+- 88138bef4: Fixing another batch of flaky E2E tests
+- d6c03b077: QA Adding back tests-nightly workflow
+- 2c84b7aee: You can now open channel selection by clicking "Select channel" within any price cell on the product list. This means the dash "-" sign is no longer displayed there
+- 5faad9ee3: Introduce menu items with sortcuts for GraphQL playground and search actions in sidebar.
+ Move "Go to Saleor Cloud" button at bottom of sidebar
+- bde2fe886: Changed e2e test case ids to remove duplicate case ids and fix inconsistencies between repo and Testmo. Thanks to this, our QA reports will be more accurate
+- 31e4575df: add playwright test for translations
+- d61fdb0b6: Add site settings e2e test
+- 16b47e2bf: Fix duplicate validations on refund view
+- 634265976: Show all transaction in manual refund view, disabled those that are not refundable
+- a6ed4570f: Removing skips from e2e tests
+- 2a091894f: This change replaces refund datagrid on order details view with GridTable for better clarity and UX.
+- 024f2d012: # Optimizing playwright setup and playwright.config.ts files
+
+ -Adding a conditioning to auth.setup.ts file to use existing auth json file if it's applicable
+ -Added some optimizations to playwright config file
+ -Cleaned up gh action for playwright tests (removed Cypress references)
+ -Updating gh workflow for PR automation with extra test sharding
+ -General cleanup of redundant code
+
+- 488c8e409: Implement refunds datagrid on order details
+- fb4d33a5c: Orders: In order list view you can now use new, easy to use and improved filters.
+- 855a97419: You can now run E2E tests for refunds
+- f95fcc447: Vertical lines are no longer visible for read-only grid tables
+- 151f42b3d: E2E fixing flaky gift cards tests
+- 2b0f7602f: Adding e2e navigation tests
+- 7a7f0e447: Run tests from other repo
+- bb16de58e: You can now see pending manual refunds on order details view.
+- 70b2c40d0: Fixing still flaky test - TC: SALEOR_205 Bulk delete customers
+- 434b169ab: Fixing flaky test - TC: SALEOR_205 Bulk delete customers
+- 6a2c4a0a4: This change replaces the datagrid on refund create & edit views with GridTable component
+- b048a5090: Introduce new icons for menu, remove not used icons
+- 005713e8e: Now savebar is aligned with the rest of layout
+- a47581e31: Adding e2e tests for attributes
+- 99a9c2837: Fixing flaky e2e tests
+- dd8d60a4e: Fixing flaky test: TC: SALEOR_87 Edit voucher Usage Limits: used in total, per customer, staff only, code used once
+- 12d7b9021: Open release PR after automation tests for core releases passes
+- fd8368fd4: Fixes button font weights
+- ec21ae379: Add playwright tests for page types
+- 7d7fd4e12: New github action gathering repo metrics
+- 18492763f: Now you can see the updated appearance of the bottom bar that holds save and back actions. This means functionality has not be changed
+- c956f3543: Fixing flaky E2E test for gift cards
+- 251e206f3: Remove branch name warning from pre-push
+- 7077d6a55: Use dummy app in delete app test
+- 99d1c6f83: Fix typo in postTestsResults.js
+- b8bd24297: Refund views have now more consistent UI
+
+### Patch Changes
+
+- 7ff18ac1e: Product edition no longer change the others work when changing different fields simultaneously. This means UI sends only form fields that were changed.
+- dfb19e5e2: The legacy multiselect are not longer present within the codebase. this means you should use the ones from new macaw when developing the UI
+- 9d8a21f51: Login via API in order to setup playwright tests is working in serial mode
+- f53973f2d: Manual transaction modal has now improved design that matches other modals.
+- 345eeb041: You can now run e2e tests without flakiness
+- f99fc51cd: Fix building docker image after move service worker to assets dir
+- a9c750a01: You can no longer see a duplicated cancel button when canceling the transaction. This means you now can go back to edition by using "back" button and "cancel" to continue your intention
+- 31a73ea21: Fixes a bug where order and gift card details views show incorrect avatar in history component. Notes added by apps will now show app's name and avatar. All events will now use the same date format to improve consistency.
+- 2952fe571: The selected value is no longer filtering the options when using any select list with autocomplete
+- a246798df: Fix showing empty tooltip when no content by bumping macaw-ui to newest
+- 7f729f2d2: Dashboard will now allow to set publication date and availability date with time. This change also replaces deprecated date fileds with datetime fields.
+- 97c0c844d: Read-only metadata keys and values will now be displayed as regular inputs, making them easier to read and preventing them from looking disabled.
+- ea3c28809: Transaction titles in order details now include its ordinal number and creation date. This means that all titles now follow the same format.
+- 9226dc965: Fix showing empty price when value is zero
+ Improve showing discount type in order payment details
+- d0ef1f3d8: App and User avatars in order details now all have the same color.
+- 1028d48d8: You can now open issue gift card modal without any flickering
+- 4eaa036cc: Fix product list crash when description contains empty object
+ Improve description by removing html tags and
+- f6d44a902: Manipulating timeouts of Playwright tests
+- ad3ad6d84: The boolean attribute has been changed from a toggle to a select. This change helps visualize when the attribute has not been set.
+- 3231bb525: You can now properly edit permission groups when you have full access
+- 528fef012: Product details view will not show product categories with its ancestors. It will make it easier to choose product's category.
+- c10dd8a6a: Add clarity to order cancel dialog
+- b475eb8b5: Add product analytics on cloud
+- 0fb6777c4: History component's texts will now have unified colors
+- 18cb0ec76: Adding tests for readonly access to Apps
+- db8b2d9b9: Flow settings in channel creation will now persist after channel is created
+- 56eb4d649: Searching for countries and other items is now more efficient, making it easier to find what you need. Additionally, the Dashboard Navigator UI has been improved to match the rest of the application, providing a more consistent experience.
+- 232cd2a12: Previously we allowed user to select either flat rates or any tax app. To avoid problems if there are more tax apps installed this change adds ability to select tax app that will be used to calculated taxes per channel. User can also select tax app for country exception while configuring taxes. Related [RFC](https://github.com/saleor/saleor/issues/12942)
+- e7e639b79: Addedd support for the BrokerProperties webhook header
+- 9edf2eabc: Products in a list of products to be excluded from shipping will no longer be selectable if not available in chosen channels.
+- e234ddc0f: Fix showing promotion discount type in order summary
+- ddd28ecf1: Increase playwright maxFailures to 10 (how many allowed failures, if exceeding skip remaining tests)
+- 290104119: Waits if editorjs is ready before it's destroyed. This change aims to lower number of alerts caused by editorjs
+- c8f4b0ad3: Set codeowners based on new GH groups
+- f82600a16: Fixes an issue that prevented users from pasting values smaller than 10 into datagrid cells
+- d1430ea40: Avatars in transaction events no longer show broken image instead of initials.
+- 4bd369b09: Now you can see the reason why shipping methods are incorrect when creating draft orders. This means creating new draft orders will pop up an error with the details of incorrect shipping.
+- 217cb106d: The selected value is no longer filtering the options when using any select list in product variant table
+- 69d2c6bec: This change replaces old service worker with a noop service worker. Saleor Dashboard will no longer actively use service worker for caching and registering fonts.
+- 51a360f2a: Improve error color on datagrid
+- dfedc1010: The action buttons in the transaction section of the order view are now unified with the other buttons in that view.
+- dfe8e1d20: Fixes an issue where product export threw an error due to invalid input data
+- 9edf2eabc: Show info and disable checkbox in AssignProductDialog when product does have channels overlap with selected channels
+- 2830c9cfe: Fix release workflow
+- 8e0e208fd9: Fix dockerfile build error caused by deleted file and bash script
+- 80b8c785e: Show all gift card used in order details
+- 756681f46: Show discount name for promotion discount type
diff --git a/Dockerfile b/Dockerfile
index 160b2c01268..f0c0959ba57 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -40,14 +40,15 @@ FROM nginx:stable-alpine as runner
WORKDIR /app
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
-COPY ./nginx/replace-api-url.sh /docker-entrypoint.d/50-replace-api-url.sh
+COPY ./nginx/replace-env-vars.sh /docker-entrypoint.d/50-replace-env-vars.sh
COPY --from=builder /app/build/ /app/
-LABEL org.opencontainers.image.title="saleor/saleor-dashboard" \
- org.opencontainers.image.description="A GraphQL-powered, single-page dashboard application for Saleor." \
- org.opencontainers.image.url="https://saleor.io/" \
- org.opencontainers.image.source="https://github.com/saleor/saleor-dashboard" \
- org.opencontainers.image.revision="$COMMIT_ID" \
- org.opencontainers.image.version="$PROJECT_VERSION" \
- org.opencontainers.image.authors="Saleor Commerce (https://saleor.io)" \
- org.opencontainers.image.licenses="BSD 3"
+LABEL \
+ org.opencontainers.image.title="saleor/saleor-dashboard" \
+ org.opencontainers.image.description="A GraphQL-powered, single-page dashboard application for Saleor." \
+ org.opencontainers.image.url="https://saleor.io/" \
+ org.opencontainers.image.source="https://github.com/saleor/saleor-dashboard" \
+ org.opencontainers.image.revision="$COMMIT_ID" \
+ org.opencontainers.image.version="$PROJECT_VERSION" \
+ org.opencontainers.image.authors="Saleor Commerce (https://saleor.io)" \
+ org.opencontainers.image.licenses="BSD 3"
diff --git a/assets/images/bag-icon.svg b/assets/images/bag-icon.svg
new file mode 100644
index 00000000000..2a455dfdd15
--- /dev/null
+++ b/assets/images/bag-icon.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/community-icon.svg b/assets/images/community-icon.svg
new file mode 100644
index 00000000000..64d8e221d98
--- /dev/null
+++ b/assets/images/community-icon.svg
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/assets/images/completed.svg b/assets/images/completed.svg
new file mode 100644
index 00000000000..fba33edffec
--- /dev/null
+++ b/assets/images/completed.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/discord-icon.svg b/assets/images/discord-icon.svg
new file mode 100644
index 00000000000..4e02197839c
--- /dev/null
+++ b/assets/images/discord-icon.svg
@@ -0,0 +1,5 @@
+
+
+
\ No newline at end of file
diff --git a/assets/images/extension-icon.svg b/assets/images/extension-icon.svg
new file mode 100644
index 00000000000..2f4dfb33d01
--- /dev/null
+++ b/assets/images/extension-icon.svg
@@ -0,0 +1,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/github-logo.svg b/assets/images/github-logo.svg
index c8a7210be3e..f50581f9425 100644
--- a/assets/images/github-logo.svg
+++ b/assets/images/github-logo.svg
@@ -1,3 +1,5 @@
-
-
-
+
+
+
\ No newline at end of file
diff --git a/assets/images/rounded-external-link-icon.svg b/assets/images/rounded-external-link-icon.svg
new file mode 100644
index 00000000000..bda342b2a00
--- /dev/null
+++ b/assets/images/rounded-external-link-icon.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/star-icon.svg b/assets/images/star-icon.svg
new file mode 100644
index 00000000000..40ca998dec4
--- /dev/null
+++ b/assets/images/star-icon.svg
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/assets/images/uncompleted.svg b/assets/images/uncompleted.svg
new file mode 100644
index 00000000000..54ef09d57cc
--- /dev/null
+++ b/assets/images/uncompleted.svg
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 00000000000..f2478853a4f
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,12 @@
+coverage:
+ status:
+ project:
+ default:
+ target: auto
+
+ignore:
+ - "src/graphql/**"
+ - ".featureFlags/**"
+ - "testUtils/**"
+ - "assets/**"
+
diff --git a/docs/docker.md b/docs/docker.md
index acef71fb256..4aaaedb75f4 100644
--- a/docs/docker.md
+++ b/docs/docker.md
@@ -17,5 +17,31 @@ Enter `http://localhost:8080/` to use the dashboard.
If you want to change `API_URL` in runtime, you can use (assuming you have a running container named `saleor-dashboard`):
```shell
-docker exec -it -e API_URL=NEW_URL saleor-dashboard /docker-entrypoint.d/50-replace-api-url.sh
+docker exec -it -e API_URL=NEW_URL saleor-dashboard /docker-entrypoint.d/50-replace-env-vars.sh
+```
+
+The replacement is not limited to `API_URL` only. You can also replace other environment variables in the same way.
+
+```shell
+docker exec -it \
+ -e "API_URL=NEW_API_URL" \
+ -e "APP_MOUNT_URI=NEW_APP_MOUNT_URI" \
+ -e "APPS_MARKETPLACE_API_URL=NEW_APPS_MARKETPLACE_API_URL" \
+ -e "APPS_TUNNEL_URL_KEYWORDS=NEW_APPS_TUNNEL_URL_KEYWORDS" \
+ -e "IS_CLOUD_INSTANCE=NEW_IS_CLOUD_INSTANCE" \
+ -e "LOCALE_CODE=NEW_LOCALE_CODE" \
+ saleor-dashboard /docker-entrypoint.d/50-replace-env-vars.sh
+```
+
+Of course you can also provide all the environment variables at the `docker run` command:
+
+```shell
+docker run --publish 8080:80 \
+ -e "API_URL=NEW_API_URL" \
+ -e "APP_MOUNT_URI=NEW_APP_MOUNT_URI" \
+ -e "APPS_MARKETPLACE_API_URL=NEW_APPS_MARKETPLACE_API_URL" \
+ -e "APPS_TUNNEL_URL_KEYWORDS=NEW_APPS_TUNNEL_URL_KEYWORDS" \
+ -e "IS_CLOUD_INSTANCE=NEW_IS_CLOUD_INSTANCE" \
+ -e "LOCALE_CODE=NEW_LOCALE_CODE" \
+ saleor-dashboard
```
diff --git a/introspection.json b/introspection.json
index 98e13d0eb03..cb18dbe7382 100644
--- a/introspection.json
+++ b/introspection.json
@@ -13,7 +13,7 @@
{
"kind": "OBJECT",
"name": "AccountAddressCreate",
- "description": "Create a new address for the customer. \n\nRequires one of the following permissions: AUTHENTICATED_USER.\n\nTriggers the following webhook events:\n- CUSTOMER_UPDATED (async): A customer account was updated.\n- ADDRESS_CREATED (async): An address was created.",
+ "description": "Create a new address for the customer.\n\nRequires one of following set of permissions: AUTHENTICATED_USER or AUTHENTICATED_APP + IMPERSONATE_USER.\n\nTriggers the following webhook events:\n- CUSTOMER_UPDATED (async): A customer account was updated.\n- ADDRESS_CREATED (async): An address was created.",
"fields": [
{
"name": "accountErrors",
@@ -1307,6 +1307,12 @@
"isDeprecated": false,
"deprecationReason": null
},
+ {
+ "name": "LOGIN_ATTEMPT_DELAYED",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "MISSING_CHANNEL_SLUG",
"description": null,
@@ -1378,6 +1384,12 @@
"description": null,
"isDeprecated": false,
"deprecationReason": null
+ },
+ {
+ "name": "UNKNOWN_IP_ADDRESS",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
}
],
"possibleTypes": null
@@ -1937,7 +1949,7 @@
{
"kind": "OBJECT",
"name": "AccountUpdate",
- "description": "Updates the account of the logged-in user. \n\nRequires one of the following permissions: AUTHENTICATED_USER.\n\nTriggers the following webhook events:\n- CUSTOMER_UPDATED (async): A customer account was updated.\n- CUSTOMER_METADATA_UPDATED (async): Optionally called when customer's metadata was updated.",
+ "description": "Updates the account of the logged-in user.\n\nRequires one of following set of permissions: AUTHENTICATED_USER or AUTHENTICATED_APP + IMPERSONATE_USER.\n\nTriggers the following webhook events:\n- CUSTOMER_UPDATED (async): A customer account was updated.\n- CUSTOMER_METADATA_UPDATED (async): Optionally called when customer's metadata was updated.",
"fields": [
{
"name": "accountErrors",
@@ -2865,6 +2877,18 @@
"isDeprecated": false,
"deprecationReason": null
},
+ {
+ "name": "skipValidation",
+ "description": "Determine if the address should be validated. By default, Saleor accepts only address inputs matching ruleset from [Google Address Data]{https://chromium-i18n.appspot.com/ssl-address), using [i18naddress](https://github.com/mirumee/google-i18n-address) library. Some mutations may require additional permissions to use the the field. More info about permissions can be found in relevant mutation.\n\nAdded in Saleor 3.19.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "defaultValue": "false",
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "streetAddress1",
"description": "Address.",
@@ -18364,7 +18388,7 @@
},
{
"name": "totalPrice",
- "description": "The sum of the the checkout line prices, with all the taxes,shipping costs, and discounts included.\n\nTriggers the following webhook events:\n- CHECKOUT_CALCULATE_TAXES (sync): Optionally triggered when checkout prices are expired.",
+ "description": "The sum of the checkout line prices, with all the taxes,shipping costs, and discounts included.\n\nTriggers the following webhook events:\n- CHECKOUT_CALCULATE_TAXES (sync): Optionally triggered when checkout prices are expired.",
"args": [],
"type": {
"kind": "NON_NULL",
@@ -18940,7 +18964,7 @@
{
"kind": "OBJECT",
"name": "CheckoutCreate",
- "description": "Create a new checkout.\n\nTriggers the following webhook events:\n- CHECKOUT_CREATED (async): A checkout was created.",
+ "description": "Create a new checkout.\n\n`skipValidation` field requires HANDLE_CHECKOUTS and AUTHENTICATED_APP permissions.\n\nTriggers the following webhook events:\n- CHECKOUT_CREATED (async): A checkout was created.",
"fields": [
{
"name": "checkout",
@@ -19309,7 +19333,7 @@
"inputFields": [
{
"name": "billingAddress",
- "description": "Billing address of the customer.",
+ "description": "Billing address of the customer. `skipValidation` requires HANDLE_CHECKOUTS and AUTHENTICATED_APP permissions.",
"type": {
"kind": "INPUT_OBJECT",
"name": "AddressInput",
@@ -19381,7 +19405,7 @@
},
{
"name": "shippingAddress",
- "description": "The mailing address to where the checkout will be shipped. Note: the address will be ignored if the checkout doesn't contain shippable items.",
+ "description": "The mailing address to where the checkout will be shipped. Note: the address will be ignored if the checkout doesn't contain shippable items. `skipValidation` requires HANDLE_CHECKOUTS and AUTHENTICATED_APP permissions.",
"type": {
"kind": "INPUT_OBJECT",
"name": "AddressInput",
@@ -20284,7 +20308,7 @@
{
"kind": "OBJECT",
"name": "CheckoutFullyPaid",
- "description": "Event sent when checkout is fully paid with transactions.\n\nAdded in Saleor 3.13.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "description": "Event sent when checkout is fully paid with transactions. The checkout is considered as fully paid when the checkout `charge_status` is `FULL` or `OVERCHARGED`. The event is not sent when the checkout authorization flow strategy is used.\n\nAdded in Saleor 3.13.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
"fields": [
{
"name": "checkout",
@@ -21655,6 +21679,22 @@
"name": "CheckoutSettings",
"description": "Represents the channel-specific checkout settings.\n\nAdded in Saleor 3.15.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
"fields": [
+ {
+ "name": "automaticallyCompleteFullyPaidCheckouts",
+ "description": "Default `false`. Determines if the paid checkouts should be automatically completed. This setting applies only to checkouts where payment was processed through transactions.When enabled, the checkout will be automatically completed once the checkout `charge_status` reaches `FULL`. This occurs when the total sum of charged and authorized transaction amounts equals or exceeds the checkout's total amount.\n\nAdded in Saleor 3.20.",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "useLegacyErrorFlow",
"description": "Default `true`. Determines if the checkout mutations should use legacy error flow. In legacy flow, all mutations can raise an exception unrelated to the requested action - (e.g. out-of-stock exception when updating checkoutShippingAddress.) If `false`, the errors will be aggregated in `checkout.problems` field. Some of the `problems` can block the finalizing checkout process. The legacy flow will be removed in Saleor 4.0. The flow with `checkout.problems` will be the default one.\n\nAdded in Saleor 3.15.This field will be removed in Saleor 4.0.",
@@ -21683,6 +21723,18 @@
"description": null,
"fields": null,
"inputFields": [
+ {
+ "name": "automaticallyCompleteFullyPaidCheckouts",
+ "description": "Default `false`. Determines if the paid checkouts should be automatically completed. This setting applies only to checkouts where payment was processed through transactions.When enabled, the checkout will be automatically completed once the checkout `charge_status` reaches `FULL`. This occurs when the total sum of charged and authorized transaction amounts equals or exceeds the checkout's total amount.\n\nAdded in Saleor 3.20.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "useLegacyErrorFlow",
"description": "Default `true`. Determines if the checkout mutations should use legacy error flow. In legacy flow, all mutations can raise an exception unrelated to the requested action - (e.g. out-of-stock exception when updating checkoutShippingAddress.) If `false`, the errors will be aggregated in `checkout.problems` field. Some of the `problems` can block the finalizing checkout process. The legacy flow will be removed in Saleor 4.0. The flow with `checkout.problems` will be the default one. \n\nAdded in Saleor 3.15.\n\nDEPRECATED: this field will be removed in Saleor 4.0.",
@@ -25248,7 +25300,7 @@
{
"kind": "ENUM",
"name": "CountryCode",
- "description": "An enumeration.",
+ "description": "Represents country codes defined by the ISO 3166-1 alpha-2 standard.\n\nThe `EU` value is DEPRECATED and will be removed in Saleor 3.21.",
"fields": null,
"inputFields": null,
"interfaces": null,
@@ -50767,8 +50819,20 @@
"fields": [
{
"name": "accountAddressCreate",
- "description": "Create a new address for the customer. \n\nRequires one of the following permissions: AUTHENTICATED_USER.\n\nTriggers the following webhook events:\n- CUSTOMER_UPDATED (async): A customer account was updated.\n- ADDRESS_CREATED (async): An address was created.",
+ "description": "Create a new address for the customer.\n\nRequires one of following set of permissions: AUTHENTICATED_USER or AUTHENTICATED_APP + IMPERSONATE_USER.\n\nTriggers the following webhook events:\n- CUSTOMER_UPDATED (async): A customer account was updated.\n- ADDRESS_CREATED (async): An address was created.",
"args": [
+ {
+ "name": "customerId",
+ "description": "ID of customer the application is impersonating. The field can be used and is required by apps only. Requires IMPERSONATE_USER and AUTHENTICATED_APP permission.\n\nAdded in Saleor 3.19.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "input",
"description": "Fields required to create address.",
@@ -51026,8 +51090,20 @@
},
{
"name": "accountUpdate",
- "description": "Updates the account of the logged-in user. \n\nRequires one of the following permissions: AUTHENTICATED_USER.\n\nTriggers the following webhook events:\n- CUSTOMER_UPDATED (async): A customer account was updated.\n- CUSTOMER_METADATA_UPDATED (async): Optionally called when customer's metadata was updated.",
+ "description": "Updates the account of the logged-in user.\n\nRequires one of following set of permissions: AUTHENTICATED_USER or AUTHENTICATED_APP + IMPERSONATE_USER.\n\nTriggers the following webhook events:\n- CUSTOMER_UPDATED (async): A customer account was updated.\n- CUSTOMER_METADATA_UPDATED (async): Optionally called when customer's metadata was updated.",
"args": [
+ {
+ "name": "customerId",
+ "description": "ID of customer the application is impersonating. The field can be used and is required by apps only. Requires IMPERSONATE_USER and AUTHENTICATED_APP permission.\n\nAdded in Saleor 3.19.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "ID",
+ "ofType": null
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "input",
"description": "Fields required to update the account of the logged-in user.",
@@ -53090,7 +53166,7 @@
},
{
"name": "checkoutCreate",
- "description": "Create a new checkout.\n\nTriggers the following webhook events:\n- CHECKOUT_CREATED (async): A checkout was created.",
+ "description": "Create a new checkout.\n\n`skipValidation` field requires HANDLE_CHECKOUTS and AUTHENTICATED_APP permissions.\n\nTriggers the following webhook events:\n- CHECKOUT_CREATED (async): A checkout was created.",
"args": [
{
"name": "input",
@@ -63472,19 +63548,15 @@
},
{
"name": "transactionEventReport",
- "description": "Report the event for the transaction.\n\nAdded in Saleor 3.13.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.\n\nRequires the following permissions: OWNER and HANDLE_PAYMENTS for apps, HANDLE_PAYMENTS for staff users. Staff user cannot update a transaction that is owned by the app.",
+ "description": "Report the event for the transaction.\n\nAdded in Saleor 3.13.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.\n\nRequires the following permissions: OWNER and HANDLE_PAYMENTS for apps, HANDLE_PAYMENTS for staff users. Staff user cannot update a transaction that is owned by the app.\n\nTriggers the following webhook events:\n- TRANSACTION_ITEM_METADATA_UPDATED (async): Optionally called when transaction's metadata was updated.\n- CHECKOUT_FULLY_PAID (async): Optionally called when the checkout charge status changed to `FULL` or `OVERCHARGED`.\n- ORDER_UPDATED (async): Optionally called when the transaction is related to the order and the order was updated.",
"args": [
{
"name": "amount",
- "description": "The amount of the event to report.",
+ "description": "The amount of the event to report. \n\nRequired for all `REQUEST`, `SUCCESS`, `ACTION_REQUIRED`, and `ADJUSTMENT` events. For other events, the amount will be calculated based on the previous events with the same pspReference. If not possible to calculate, the mutation will return an error.",
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "PositiveDecimal",
- "ofType": null
- }
+ "kind": "SCALAR",
+ "name": "PositiveDecimal",
+ "ofType": null
},
"defaultValue": null,
"isDeprecated": false,
@@ -63586,6 +63658,46 @@
"isDeprecated": false,
"deprecationReason": null
},
+ {
+ "name": "transactionMetadata",
+ "description": "Fields required to update the transaction metadata.\n\nAdded in Saleor 3.17.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "MetadataInput",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "transactionPrivateMetadata",
+ "description": "Fields required to update the transaction private metadata.\n\nAdded in Saleor 3.17.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "INPUT_OBJECT",
+ "name": "MetadataInput",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "type",
"description": "Current status of the event to report.",
@@ -67164,6 +67276,18 @@
"isDeprecated": true,
"deprecationReason": "This field will be removed in Saleor 4.0. Use the `discounts` field instead. "
},
+ {
+ "name": "undiscountedShippingPrice",
+ "description": "Undiscounted total price of shipping.\n\nAdded in Saleor 3.19.",
+ "args": [],
+ "type": {
+ "kind": "OBJECT",
+ "name": "Money",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "undiscountedTotal",
"description": "Undiscounted total amount of the order.",
@@ -71765,6 +71889,12 @@
"isDeprecated": false,
"deprecationReason": null
},
+ {
+ "name": "PLACED_AUTOMATICALLY_FROM_PAID_CHECKOUT",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "PLACED_FROM_DRAFT",
"description": null,
@@ -71985,6 +72115,26 @@
"isDeprecated": false,
"deprecationReason": null
},
+ {
+ "name": "checkoutTokens",
+ "description": null,
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "UUID",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "created",
"description": null,
@@ -73986,6 +74136,18 @@
"isDeprecated": false,
"deprecationReason": null
},
+ {
+ "name": "isPriceOverridden",
+ "description": "Returns True, if the line unit price was overridden.\n\nAdded in Saleor 3.14.",
+ "args": [],
+ "type": {
+ "kind": "SCALAR",
+ "name": "Boolean",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "isShippingRequired",
"description": "Whether the product variant requires shipping.",
@@ -82228,6 +82390,12 @@
"isDeprecated": false,
"deprecationReason": null
},
+ {
+ "name": "CHECKOUT_COMPLETION_IN_PROGRESS",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "CHECKOUT_EMAIL_NOT_SET",
"description": null,
@@ -100652,11 +100820,15 @@
},
{
"name": "type",
- "description": "Defines the promotion type. Implicate the required promotion rules predicate type and whether the promotion rules will give the catalogue or order discount. \n\nThe default value is `Catalogue`.\n\nThis field will be required from Saleor 3.20.\n\nAdded in Saleor 3.19.",
+ "description": "Defines the promotion type. Implicate the required promotion rules predicate type and whether the promotion rules will give the catalogue or order discount. \n\nAdded in Saleor 3.19.",
"type": {
- "kind": "ENUM",
- "name": "PromotionTypeEnum",
- "ofType": null
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "ENUM",
+ "name": "PromotionTypeEnum",
+ "ofType": null
+ }
},
"defaultValue": null,
"isDeprecated": false,
@@ -105355,7 +105527,7 @@
},
{
"name": "checkout",
- "description": "Look up a checkout by id.\n\nRequires one of the following permissions to query checkouts that belong to other users: MANAGE_CHECKOUTS, IMPERSONATE_USER. ",
+ "description": "Look up a checkout by id.\n\nRequires one of the following permissions to query a checkout, if a checkout is in inactive channel: MANAGE_CHECKOUTS, IMPERSONATE_USER, HANDLE_PAYMENTS. ",
"args": [
{
"name": "id",
@@ -105453,7 +105625,7 @@
},
{
"name": "checkouts",
- "description": "List of checkouts.\n\nRequires one of the following permissions: MANAGE_CHECKOUTS.",
+ "description": "List of checkouts.\n\nRequires one of the following permissions: MANAGE_CHECKOUTS, HANDLE_PAYMENTS.",
"args": [
{
"name": "after",
@@ -105708,7 +105880,7 @@
},
{
"name": "customers",
- "description": "List of the shop's customers.\n\nRequires one of the following permissions: MANAGE_ORDERS, MANAGE_USERS.",
+ "description": "List of the shop's customers. This list includes all users who registered through the accountRegister mutation. Additionally, staff users who have placed an order using their account will also appear in this list.\n\nRequires one of the following permissions: MANAGE_ORDERS, MANAGE_USERS.",
"args": [
{
"name": "after",
@@ -106694,7 +106866,7 @@
"args": [
{
"name": "externalReference",
- "description": "External ID of an order. \n\nAdded in Saleor 3.10.",
+ "description": "External ID of an order. \n\nAdded in Saleor 3.10..\n\nRequires one of the following permissions: MANAGE_ORDERS.",
"type": {
"kind": "SCALAR",
"name": "String",
@@ -108542,7 +108714,7 @@
"args": [
{
"name": "id",
- "description": "ID of an warehouse",
+ "description": "ID of a stock",
"type": {
"kind": "NON_NULL",
"name": null,
@@ -113710,13 +113882,9 @@
"description": "Translated shipping method name.",
"args": [],
"type": {
- "kind": "NON_NULL",
- "name": null,
- "ofType": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- }
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
},
"isDeprecated": false,
"deprecationReason": null
@@ -117391,8 +117559,8 @@
"ofType": null
}
},
- "isDeprecated": false,
- "deprecationReason": null
+ "isDeprecated": true,
+ "deprecationReason": "This field will be removed in Saleor 4.0."
},
{
"name": "metadata",
@@ -121480,6 +121648,105 @@
"name": "Subscription",
"description": null,
"fields": [
+ {
+ "name": "draftOrderCreated",
+ "description": "Event sent when new draft order is created.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "DraftOrderCreated",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "draftOrderDeleted",
+ "description": "Event sent when draft order is deleted.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "DraftOrderDeleted",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "draftOrderUpdated",
+ "description": "Event sent when draft order is updated.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "DraftOrderUpdated",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "event",
"description": "Look up subscription event.\n\nAdded in Saleor 3.2.",
@@ -121491,6 +121758,402 @@
},
"isDeprecated": false,
"deprecationReason": null
+ },
+ {
+ "name": "orderBulkCreated",
+ "description": "Event sent when orders are imported.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "OrderBulkCreated",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "orderCancelled",
+ "description": "Event sent when order is cancelled.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "OrderCancelled",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "orderConfirmed",
+ "description": "Event sent when order is confirmed.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "OrderConfirmed",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "orderCreated",
+ "description": "Event sent when new order is created.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "OrderCreated",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "orderExpired",
+ "description": "Event sent when order becomes expired.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "OrderExpired",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "orderFulfilled",
+ "description": "Event sent when order is fulfilled.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "OrderFulfilled",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "orderFullyPaid",
+ "description": "Event sent when order is fully paid.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "OrderFullyPaid",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "orderFullyRefunded",
+ "description": "The order is fully refunded.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "OrderFullyRefunded",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "orderMetadataUpdated",
+ "description": "Event sent when order metadata is updated.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "OrderMetadataUpdated",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "orderPaid",
+ "description": "Payment has been made. The order may be partially or fully paid.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "OrderPaid",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "orderRefunded",
+ "description": "The order received a refund. The order may be partially or fully refunded.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "OrderRefunded",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "orderUpdated",
+ "description": "Event sent when order is updated.\n\nAdded in Saleor 3.20.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "args": [
+ {
+ "name": "channels",
+ "description": "List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.",
+ "type": {
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ }
+ }
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "OrderUpdated",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
}
],
"inputFields": null,
@@ -124222,7 +124885,7 @@
},
{
"name": "shippingPrice",
- "description": "The price of shipping method.",
+ "description": "The price of shipping method, includes shipping voucher discount if applied.",
"args": [],
"type": {
"kind": "NON_NULL",
@@ -124290,6 +124953,22 @@
},
"isDeprecated": false,
"deprecationReason": null
+ },
+ {
+ "name": "type",
+ "description": "Indicates which part of the order the discount should affect: SUBTOTAL or SHIPPING.",
+ "args": [],
+ "type": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "ENUM",
+ "name": "TaxableObjectDiscountTypeEnum",
+ "ofType": null
+ }
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
}
],
"inputFields": null,
@@ -124297,6 +124976,29 @@
"enumValues": null,
"possibleTypes": null
},
+ {
+ "kind": "ENUM",
+ "name": "TaxableObjectDiscountTypeEnum",
+ "description": "Indicates which part of the order the discount should affect: SUBTOTAL or SHIPPING.",
+ "fields": null,
+ "inputFields": null,
+ "interfaces": null,
+ "enumValues": [
+ {
+ "name": "SHIPPING",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "SUBTOTAL",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "possibleTypes": null
+ },
{
"kind": "OBJECT",
"name": "TaxableObjectLine",
@@ -124380,7 +125082,7 @@
},
{
"name": "totalPrice",
- "description": "Price of the order line.",
+ "description": "Price of the order line. The price includes catalogue promotions, specific product and applied once per order voucher discounts. The price does not include the entire order discount.",
"args": [],
"type": {
"kind": "NON_NULL",
@@ -124396,7 +125098,7 @@
},
{
"name": "unitPrice",
- "description": "Price of the single item in the order line.",
+ "description": "Price of the single item in the order line. The price includes catalogue promotions, specific product and applied once per order voucher discounts. The price does not include the entire order discount.",
"args": [],
"type": {
"kind": "NON_NULL",
@@ -125787,7 +126489,7 @@
{
"kind": "OBJECT",
"name": "TransactionEventReport",
- "description": "Report the event for the transaction.\n\nAdded in Saleor 3.13.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.\n\nRequires the following permissions: OWNER and HANDLE_PAYMENTS for apps, HANDLE_PAYMENTS for staff users. Staff user cannot update a transaction that is owned by the app.",
+ "description": "Report the event for the transaction.\n\nAdded in Saleor 3.13.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.\n\nRequires the following permissions: OWNER and HANDLE_PAYMENTS for apps, HANDLE_PAYMENTS for staff users. Staff user cannot update a transaction that is owned by the app.\n\nTriggers the following webhook events:\n- TRANSACTION_ITEM_METADATA_UPDATED (async): Optionally called when transaction's metadata was updated.\n- CHECKOUT_FULLY_PAID (async): Optionally called when the checkout charge status changed to `FULL` or `OVERCHARGED`.\n- ORDER_UPDATED (async): Optionally called when the transaction is related to the order and the order was updated.",
"fields": [
{
"name": "alreadyProcessed",
@@ -125943,6 +126645,12 @@
"description": null,
"isDeprecated": false,
"deprecationReason": null
+ },
+ {
+ "name": "REQUIRED",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
}
],
"possibleTypes": null
@@ -126219,6 +126927,12 @@
"inputFields": null,
"interfaces": null,
"enumValues": [
+ {
+ "name": "CHECKOUT_COMPLETION_IN_PROGRESS",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "GRAPHQL_ERROR",
"description": null,
@@ -127286,6 +128000,12 @@
"inputFields": null,
"interfaces": null,
"enumValues": [
+ {
+ "name": "CHECKOUT_COMPLETION_IN_PROGRESS",
+ "description": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
{
"name": "GRAPHQL_ERROR",
"description": null,
@@ -135056,6 +135776,67 @@
},
"isDeprecated": false,
"deprecationReason": null
+ },
+ {
+ "name": "stocks",
+ "description": "Stocks that belong to this warehouse.\n\nAdded in Saleor 3.20.\n\nRequires one of the following permissions: MANAGE_PRODUCTS, MANAGE_ORDERS.",
+ "args": [
+ {
+ "name": "after",
+ "description": "Return the elements in the list that come after the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "before",
+ "description": "Return the elements in the list that come before the specified cursor.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "String",
+ "ofType": null
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "first",
+ "description": "Retrieve the first n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ },
+ {
+ "name": "last",
+ "description": "Retrieve the last n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query.",
+ "type": {
+ "kind": "SCALAR",
+ "name": "Int",
+ "ofType": null
+ },
+ "defaultValue": null,
+ "isDeprecated": false,
+ "deprecationReason": null
+ }
+ ],
+ "type": {
+ "kind": "OBJECT",
+ "name": "StockCountableConnection",
+ "ofType": null
+ },
+ "isDeprecated": false,
+ "deprecationReason": null
}
],
"inputFields": null,
@@ -136768,7 +137549,7 @@
},
{
"name": "customHeaders",
- "description": "Custom headers, which will be added to HTTP request. There is a limitation of 5 headers per webhook and 998 characters per header.Only \"X-*\" and \"Authorization*\" keys are allowed.\n\nAdded in Saleor 3.12.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "description": "Custom headers, which will be added to HTTP request. There is a limitation of 5 headers per webhook and 998 characters per header.Only `X-*`, `Authorization*`, and `BrokerProperties` keys are allowed.\n\nAdded in Saleor 3.12.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
"type": {
"kind": "SCALAR",
"name": "JSONString",
@@ -140530,7 +141311,7 @@
},
{
"name": "customHeaders",
- "description": "Custom headers, which will be added to HTTP request. There is a limitation of 5 headers per webhook and 998 characters per header.Only \"X-*\" and \"Authorization*\" keys are allowed.\n\nAdded in Saleor 3.12.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
+ "description": "Custom headers, which will be added to HTTP request. There is a limitation of 5 headers per webhook and 998 characters per header.Only `X-*`, `Authorization*`, and `BrokerProperties` keys are allowed.\n\nAdded in Saleor 3.12.\n\nNote: this API is currently in Feature Preview and can be subject to changes at later point.",
"type": {
"kind": "SCALAR",
"name": "JSONString",
diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json
index 51d503d9eef..d44e748fa3e 100644
--- a/locale/defaultMessages.json
+++ b/locale/defaultMessages.json
@@ -15,6 +15,10 @@
"context": "header",
"string": "Products in {categoryName}"
},
+ "+470FM": {
+ "context": "voucher status expired",
+ "string": "Expired"
+ },
"+5HkZN": {
"context": "order, button",
"string": "Mark as paid"
@@ -93,6 +97,10 @@
"context": "disabled status option label",
"string": "Disabled"
},
+ "+Wm2vY": {
+ "context": "discount type percentage",
+ "string": "Percentage"
+ },
"+a+2ug": {
"string": "Members"
},
@@ -225,8 +233,8 @@
"context": "section description",
"string": "Strategy defines the preference of warehouses for stock allocations and reservations."
},
- "/Fa+RP": {
- "string": "Couldn't load top products"
+ "/H9LeU": {
+ "string": "Explore Saleor App Store"
},
"/ILyIf": {
"context": "tax classes menu header",
@@ -266,6 +274,10 @@
"context": "collection name",
"string": "Name"
},
+ "/XGvYd": {
+ "context": "onboarding step description",
+ "string": "Webhooks are available in Saleor to both Local and External Apps. To create a Webhook you need to create a Local App first. You can do that in the Configuration > Webhooks & Events."
+ },
"/Xwjww": {
"context": "button",
"string": "Fulfill"
@@ -305,6 +317,9 @@
"context": "channels alphabetically title",
"string": "Channels from A to Z"
},
+ "/n+NRO": {
+ "string": "Note id"
+ },
"/nZy6A": {
"context": "page subtitle",
"string": "Issue refund"
@@ -344,6 +359,9 @@
"context": "order returned success message",
"string": "Successfully returned products!"
},
+ "0+zatS": {
+ "string": "Hello {userName}, welcome to your Store Dashboard"
+ },
"01+5kQ": {
"string": "Mark as paid"
},
@@ -422,6 +440,10 @@
"context": "column header",
"string": "Title"
},
+ "0YjGFG": {
+ "context": "alert message",
+ "string": "For subscription"
+ },
"0a0fLZ": {
"context": "countries list menu label when no countries are assigned",
"string": "There are no countries assigned"
@@ -491,6 +513,10 @@
"1+ROfp": {
"string": "Transaction"
},
+ "1/bAgt": {
+ "context": "discount type fixed",
+ "string": "Fixed"
+ },
"1/oG76": {
"context": "dialog header",
"string": "Delete Sale"
@@ -537,6 +563,9 @@
"19/lwV": {
"string": "Determine attributes used to create product types"
},
+ "19o9WS": {
+ "string": "Learn more about {userPermissions}"
+ },
"1BNKCZ": {
"context": "sale channel",
"string": "Channel"
@@ -553,10 +582,6 @@
"context": "expiry date section header",
"string": "Expiry date"
},
- "1KSqnn": {
- "context": "tab name",
- "string": "All Product Types"
- },
"1LBYpE": {
"context": "dialog header",
"string": "Delete Menus"
@@ -650,9 +675,6 @@
"context": "order status",
"string": "Partially returned"
},
- "28GZnc": {
- "string": "Start typing to begin search..."
- },
"29L5Yq": {
"context": "gift card not found message",
"string": "Couldn't find gift card"
@@ -774,9 +796,9 @@
"context": "card title",
"string": "Refund balance"
},
- "2yU+q9": {
- "context": "tab name",
- "string": "All Warehouses"
+ "2xkzcr": {
+ "context": "btn label",
+ "string": "Go to GraphQL Playground"
},
"2yV+s8": {
"context": "order history message",
@@ -847,10 +869,6 @@
"context": "navigator command mode description",
"string": "Search Command"
},
- "3Z8972": {
- "context": "product",
- "string": "Stock quantity"
- },
"3a5wL8": {
"string": "Active"
},
@@ -934,9 +952,6 @@
"context": "Transaction capture button - charge preauthorized transaction amount",
"string": "Capture"
},
- "450Fty": {
- "string": "None"
- },
"45aV8u": {
"context": "gift card bulk create modal bottom explanation",
"string": "After creation Saleor will create a list of gift card codes that you will be able to download."
@@ -972,6 +987,10 @@
"context": "datagrid title label",
"string": "Select transaction to refund"
},
+ "4IawKc": {
+ "context": "onboarding step description",
+ "string": "Go to all orders where you can create an fulfilment and refund and review corresponding statuses. View the order in GraphQL"
+ },
"4IgzXs": {
"context": "label",
"string": "App Manifest URL"
@@ -1012,10 +1031,6 @@
"context": "modal button",
"string": "Upload URL"
},
- "4XRIV5": {
- "context": "add new refund button",
- "string": "Add new refund"
- },
"4XhJY+": {
"context": "dialog header",
"string": "Add product from {channelName}"
@@ -1129,6 +1144,9 @@
"context": "vat not included in order price",
"string": "does not apply"
},
+ "5M+hLZ": {
+ "string": "User permissions"
+ },
"5O8EIz": {
"context": "Authorize transactions instead of charging",
"string": "Authorize transactions instead of charging"
@@ -1158,9 +1176,17 @@
"context": "product attribute entity type",
"string": "Products"
},
+ "5TzisG": {
+ "context": "btn label",
+ "string": "Go to Webhooks"
+ },
"5Vwnu+": {
"string": "You have reached your SKU limit, you will be no longer able to add SKUs to your store. If you would like to up your limit, contact your administration staff about raising your limits."
},
+ "5W3qxG": {
+ "context": "edit refund title",
+ "string": "Edit refund with line items"
+ },
"5XG1CO": {
"context": "acre-ft unit",
"string": "acre-ft"
@@ -1318,10 +1344,6 @@
"context": "order history message",
"string": "Note was added to the order"
},
- "6Y1nQd": {
- "context": "product is visible",
- "string": "Visible"
- },
"6aBkJm": {
"context": "section header",
"string": "Authorization"
@@ -1577,6 +1599,9 @@
"8oIbMI": {
"string": "Reached limit for this plan"
},
+ "8pVWve": {
+ "string": "This field cannot be blank"
+ },
"8qL/tV": {
"context": "CannotDefineChannelsAvailabilityCard subtitle",
"string": "You will be able to define availability of product after creating variants."
@@ -1604,6 +1629,9 @@
"context": "service accounts section name",
"string": "Service Accounts"
},
+ "91vQMc": {
+ "string": "order management"
+ },
"945a4a": {
"context": "column header",
"string": "Customer e-mail"
@@ -1650,6 +1678,10 @@
"9FGTOt": {
"string": "Allow access to orders of all channels"
},
+ "9IrVVZ": {
+ "context": "attribute can be searched in storefront",
+ "string": "Filterable in storefront"
+ },
"9MGrEp": {
"string": "Is available"
},
@@ -1690,6 +1722,9 @@
"context": "order number label",
"string": "Order number"
},
+ "9Th87u": {
+ "string": "Note successfully updated"
+ },
"9Tl/bT": {
"context": "export items as spreadsheet",
"string": "Spreadsheet for Excel, Numbers etc."
@@ -1786,6 +1821,10 @@
"A+g/VP": {
"string": "Unsaved preset"
},
+ "A02NDR": {
+ "context": "plain text attribute value was truncated",
+ "string": "Attribute value too long and truncated at {length} characters."
+ },
"A0Wlg7": {
"context": "product discount removed title",
"string": "{productName} discount was removed by"
@@ -1949,9 +1988,19 @@
"context": "dialog header",
"string": "Unassign Categories From Sale"
},
+ "B8PvdI": {
+ "string": "extending Saleor with Webhooks"
+ },
"B9yrkK": {
"string": "No Channels found"
},
+ "BA4leV": {
+ "string": "API guide"
+ },
+ "BBt3jD": {
+ "context": "btn label",
+ "string": "Invite members"
+ },
"BCPrmK": {
"context": "order history message",
"string": "Shipping details was sent to customer"
@@ -2012,6 +2061,10 @@
"context": "sale status",
"string": "Scheduled"
},
+ "BaxGjT": {
+ "context": "variant stocks section subtitle",
+ "string": "Assigning the stocks will be possible after the variant is saved."
+ },
"BbP+k3": {
"context": "variant availability in channel",
"string": "Available"
@@ -2053,17 +2106,13 @@
"BvGp1I": {
"string": "between"
},
- "Bx367s": {
- "context": "product is hidden",
- "string": "Hidden"
- },
- "By5ZBp": {
- "context": "header",
- "string": "Hello there, {userName}"
- },
"ByYtFB": {
"string": "Invalid or expired token. Please check your token in URL"
},
+ "C+WD8j": {
+ "context": "alert message",
+ "string": "all of"
+ },
"C035fF": {
"context": "grant refund, refund card explanation next to submit button",
"string": "Funds will be returned in a separate step"
@@ -2086,6 +2135,10 @@
"context": "button",
"string": "Add products"
},
+ "C5gcqL": {
+ "context": "btn label",
+ "string": "Mark as done"
+ },
"C6bb6x": {
"context": "order refund amount",
"string": "Refund total amount"
@@ -2101,6 +2154,9 @@
"context": "error with deactivatation alert message",
"string": "Errors deactivating gift {count,plural,one{card} other{cards}}"
},
+ "C9cgck": {
+ "string": "Learn more about {productConfigurations}"
+ },
"C9pcQx": {
"context": "dialog content",
"string": "{counter,plural,one{Are you sure you want to delete this shipping zone?} other{Are you sure you want to delete {displayQuantity} shipping zones?}}"
@@ -2161,6 +2217,9 @@
"CZmloB": {
"string": "Fulfillment successfully updated"
},
+ "Cc3Z40": {
+ "string": "Learn Saleor checkout process flow"
+ },
"CcEwXH": {
"context": "dialog header",
"string": "Delete Page Types"
@@ -2263,6 +2322,10 @@
"DGCzal": {
"string": "This token gives you access to your shop's API, which you'll find here: {url}"
},
+ "DGWVA9": {
+ "context": "variant created error message",
+ "string": "Variant creation failed"
+ },
"DHBlFi": {
"context": "navigator customer mode description",
"string": "Search Customers"
@@ -2368,6 +2431,10 @@
"context": "no card defuned alert message",
"string": "You haven’t defined a gift card product!"
},
+ "E4GW+N": {
+ "context": "fully paid checkout automatically completed message",
+ "string": "Order created automatically from fully paid checkout"
+ },
"E54eoT": {
"string": "Creating the navigation structure is done by dragging and dropping. Simply create a new menu item and then drag it into its destined place. You can move items inside one another to create a tree structure and drag items up and down to create a hierarchy"
},
@@ -2388,6 +2455,10 @@
"EEW+ND": {
"string": "Navigator"
},
+ "EGycu/": {
+ "context": "voucher status active",
+ "string": "Active"
+ },
"EHsnZX": {
"context": "dialog description",
"string": "Are you sure you want to approve this fullfillment?"
@@ -2410,6 +2481,10 @@
"context": "checkbox",
"string": "Refund shipment costs"
},
+ "EQfaUv": {
+ "context": "onboarding step title",
+ "string": "Check our GraphQL playground & make an API call"
+ },
"ER/yBq": {
"context": "max price in channel",
"string": "Max. value"
@@ -2438,6 +2513,9 @@
"context": "transaction reference",
"string": "Transaction reference"
},
+ "EcglP9": {
+ "string": "Key"
+ },
"Ediw6/": {
"context": "button label",
"string": "Assign references"
@@ -2597,6 +2675,10 @@
"FTYkgw": {
"string": "Delete collections"
},
+ "FWaL+x": {
+ "context": "gift card history message",
+ "string": "Gift card balance was reset"
+ },
"FWbv/u": {
"context": "page header",
"string": "Create Discount"
@@ -2672,6 +2754,9 @@
"FuAV5G": {
"string": "This name is already taken. Please provide another."
},
+ "FvmV6q": {
+ "string": "Discord"
+ },
"Fvvgoi": {
"string": "Your session has expired. Please log in again to continue."
},
@@ -2749,6 +2834,10 @@
"context": "dialog header",
"string": "Delete Variant"
},
+ "GFkb2t": {
+ "context": "automatically complete checkouts checkbox label",
+ "string": "Automatically complete checkouts when fully paid"
+ },
"GJAX0z": {
"context": "order history message",
"string": "Order was placed"
@@ -2860,6 +2949,9 @@
"GsBRWL": {
"string": "Languages"
},
+ "GufXy5": {
+ "string": "Value"
+ },
"GuihaP": {
"context": "order transaction refund summary label",
"string": "Shipping"
@@ -2895,6 +2987,10 @@
"context": "VariantDetailsChannelsAvailabilityCard item subtitle published",
"string": "Published since {getPublishedAt}"
},
+ "H1L1cc": {
+ "context": "url",
+ "string": "URL"
+ },
"H27/Gy": {
"context": "error message",
"string": "Maximum weight cannot be lower than minimum"
@@ -2919,6 +3015,10 @@
"context": "pages section name",
"string": "Pages"
},
+ "HADMte": {
+ "context": "onboarding step title",
+ "string": "Explore orders"
+ },
"HAlOn1": {
"string": "Name"
},
@@ -2948,6 +3048,10 @@
"context": "staff member's account",
"string": "Active"
},
+ "HRXLYk": {
+ "context": "cta button label",
+ "string": "Get in touch"
+ },
"HSmg1/": {
"context": "gift cards section name",
"string": "Gift Cards"
@@ -3044,6 +3148,10 @@
"context": "is filter range or value",
"string": "equal to"
},
+ "I/y4IU": {
+ "context": "alert message",
+ "string": "one of"
+ },
"I1Mz7h": {
"string": "Manage Collection Channel Availability"
},
@@ -3071,6 +3179,10 @@
"context": "product type",
"string": "Shippable"
},
+ "IDwsCU": {
+ "context": "onboarding step title",
+ "string": "Create a new product"
+ },
"IEpmGQ": {
"context": "description",
"string": "Use Saleor Cloud to access Saleor Apps"
@@ -3285,10 +3397,6 @@
"context": "csv file exporting has finished, header",
"string": "Exporting CSV finished"
},
- "JUQwne": {
- "context": "order",
- "string": "Gift Card"
- },
"JV+EiM": {
"context": "voucher value",
"string": "Value"
@@ -3301,10 +3409,6 @@
"context": "button",
"string": "Create Menu"
},
- "JYvf8/": {
- "context": "is preorder",
- "string": "Preorder"
- },
"Ja7gHc": {
"context": "button",
"string": "Edit"
@@ -3413,6 +3517,9 @@
"context": "tooltip",
"string": "This feature is in a preview state and can be subject to changes at later point"
},
+ "KHI/qv": {
+ "string": "You don't have permission to manage products"
+ },
"KHZlmi": {
"string": "Discount Type"
},
@@ -3461,10 +3568,6 @@
"context": "quantity of fulfilled products",
"string": "Quantity to fulfill"
},
- "Kgxlsf": {
- "context": "order",
- "string": "Paid with Gift Card"
- },
"KkufwD": {
"string": "No voucher codes found"
},
@@ -3487,6 +3590,10 @@
"context": "product field",
"string": "Category"
},
+ "Kv58Rx": {
+ "context": "default gift card delete description",
+ "string": "{selectedItemsCount,plural,one{Are you sure you want to delete this gift card?} other{Are you sure you want to delete {selectedItemsCount} gift cards?}}"
+ },
"Kw0jHS": {
"context": "created products counter",
"string": "{count}/{max} SKUs used"
@@ -3635,6 +3742,10 @@
"M59JhX": {
"string": "Manual"
},
+ "M61TN/": {
+ "context": "product type shippable",
+ "string": "Shippable"
+ },
"M6mWHL": {
"context": "tooltip helper text",
"string": "You do not have permissions to create a manual refund."
@@ -3904,6 +4015,10 @@
"context": "header field name, header",
"string": "Name"
},
+ "Nqh0na": {
+ "context": "Product types search input placeholder",
+ "string": "Search product types..."
+ },
"NqxvFh": {
"context": "navigator placeholder",
"string": "Type Command"
@@ -3916,6 +4031,10 @@
"context": "weight",
"string": "{value} {unit}"
},
+ "Ntk3CQ": {
+ "context": "footer title",
+ "string": "Missing something?"
+ },
"Nv/toB": {
"context": "button",
"string": "Assign and save"
@@ -3936,6 +4055,10 @@
"context": "image upload",
"string": "Drop here to upload"
},
+ "Nyxzpe": {
+ "context": "onboarding step description",
+ "string": "Saleor includes a GraphQL Playground, an interactive GraphQL editor, allowing access to your Saleor instance's API through the web browser. The Playground lets you quickly familiarize yourself with the API, perform example operations, and send your first queries and mutations."
+ },
"NzifUg": {
"context": "window title",
"string": "Fulfill Order"
@@ -4154,6 +4277,10 @@
"context": "window title",
"string": "Create Product"
},
+ "PaQFmR": {
+ "context": "onboarding step title",
+ "string": "Welcome to Dashboard!"
+ },
"PbqNhi": {
"context": "order status",
"string": "Partially fulfilled"
@@ -4218,10 +4345,6 @@
"Pyjarj": {
"string": "This shipping rate has no postal codes assigned"
},
- "PzXIXh": {
- "context": "order",
- "string": "Customer"
- },
"Q/Nbku": {
"context": "product field",
"string": "Type"
@@ -4403,6 +4526,10 @@
"QqnNUm": {
"string": "Visible in listing"
},
+ "QslFl8": {
+ "context": "add new refund button",
+ "string": "New refund"
+ },
"QzseV7": {
"context": "dialog header",
"string": "Delete Menu"
@@ -4411,6 +4538,12 @@
"context": "OrderCustomer Fulfillment from All Warehouses",
"string": "Fulfill from All Warehouses"
},
+ "RABrGb": {
+ "string": "Save hours of evaluating Saleor on your own by speaking with our solution engineer."
+ },
+ "RBkNPr": {
+ "string": "Full coverage of advanced checkout cases like split payments, split fulfillments, and orchestrated payments."
+ },
"RBxYJf": {
"context": "sale status",
"string": "Expired"
@@ -4419,10 +4552,6 @@
"context": "info text",
"string": "Set up an end date of preorder. When end date will be reached product will be automatically taken from preorder to standard selling"
},
- "RH+aOF": {
- "context": "use attribute in filtering",
- "string": "Use in Filtering"
- },
"RK6l3Z": {
"context": "radio button label",
"string": "Refund with manual amount"
@@ -4529,6 +4658,10 @@
"context": "order does not require shipping",
"string": "does not apply"
},
+ "RyZd9J": {
+ "context": "error message",
+ "string": "Please wait a moment before trying again."
+ },
"Ryh3iR": {
"context": "header",
"string": "Create Webhook"
@@ -4559,10 +4692,6 @@
"context": "grant refund table, column header",
"string": "Quantity"
},
- "S52JMl": {
- "context": "default gift card delete description",
- "string": "{selectedItemsCount,plural,one{Are you sure you want to delete this gift card?} other{Are you sure you want to delete {selectedItemsCount} giftCards?}}"
- },
"S7Rwl0": {
"context": "stock exceeded action question label",
"string": "Are you sure you want to fulfill those products anyway?"
@@ -4641,6 +4770,10 @@
"context": "product weight",
"string": "Weight"
},
+ "SV0FRm": {
+ "context": "attribute is filterable in storefront",
+ "string": "Filterable in storefront"
+ },
"SZH0fw": {
"context": "set variant as default, button",
"string": "Set as default"
@@ -4652,14 +4785,14 @@
"SceSNp": {
"string": "Remove following permissions:"
},
+ "SgFE10": {
+ "context": "product type digital",
+ "string": "Digital"
+ },
"Sjd7wm": {
"context": "product filter label",
"string": "Product"
},
- "Sna+WK": {
- "context": "product status",
- "string": "Out Of Stock"
- },
"SpngiS": {
"context": "sale status",
"string": "Status"
@@ -4833,6 +4966,9 @@
"context": "PageTypeDeleteWarningDialog with items multiple description",
"string": "You are about to delete multiple page types. Some of them are assigned to pages. Deleting those page types will also delete those pages"
},
+ "Tp5T7U": {
+ "string": "Join our OS community of industry experts and learn more about open source at Saleor."
+ },
"TpPx7V": {
"context": "navigator placeholder",
"string": "Search Customer"
@@ -4927,6 +5063,14 @@
"context": "filters error messages unknown error",
"string": "Unknown error occurred"
},
+ "UVDfTs": {
+ "context": "discount type shipping",
+ "string": "Shipping"
+ },
+ "UYKEsx": {
+ "context": "collection filter published",
+ "string": "Published"
+ },
"Uf3oHA": {
"context": "add new menu item",
"string": "Create new item"
@@ -4963,10 +5107,6 @@
"context": "product field",
"string": "Variant Images"
},
- "Urh2N3": {
- "context": "label",
- "string": "Link"
- },
"Us9cA1": {
"context": "profit margin",
"string": "Margin"
@@ -5125,6 +5265,10 @@
"VkYZQ8": {
"string": "Current Permissions"
},
+ "VlDG1B": {
+ "context": "Request integration",
+ "string": "Request integration"
+ },
"VmMDLN": {
"context": "permission list item description",
"string": "This group is last source of that permission"
@@ -5186,6 +5330,10 @@
"W6nwjo": {
"string": "Draft"
},
+ "W75xMz": {
+ "context": "attribute is visible in storefront",
+ "string": "Visible in storefront"
+ },
"W8i2Ez": {
"context": "product field",
"string": "Name"
@@ -5197,6 +5345,10 @@
"context": "change warehouse dialog search placeholder",
"string": "Search warehouses"
},
+ "WDrC7e": {
+ "context": "label",
+ "string": "Link value"
+ },
"WDy0tF": {
"context": "section header",
"string": "Webhook Information"
@@ -5288,6 +5440,9 @@
"context": "helper text",
"string": "All items refunded"
},
+ "Wk00wL": {
+ "string": "Join the open source community"
+ },
"WkxE8/": {
"context": "percentage or fixed, header",
"string": "Discount Type"
@@ -5369,6 +5524,9 @@
"context": "card update success alert title",
"string": "Successfully updated card balance"
},
+ "XAvER/": {
+ "string": "Product reordered"
+ },
"XB2Jj9": {
"context": "create app button",
"string": "Create App"
@@ -5388,9 +5546,6 @@
"context": "Refund pending status",
"string": "Pending"
},
- "XFKV5Z": {
- "string": "Created at: {date}"
- },
"XFtKV5": {
"context": "input placeholder tag",
"string": "Tag"
@@ -5445,6 +5600,9 @@
"context": "section header",
"string": "All Media"
},
+ "XVQpjm": {
+ "string": "Add new functionalities on top of Saleor and integrate it with third-party services. They can be installed, managed, and rendered in here in Saleor Dashboard."
+ },
"XVuPMw": {
"string": "Are you sure you want to delete this rule?"
},
@@ -5460,6 +5618,10 @@
"context": "sale value",
"string": "Value"
},
+ "XZpRr8": {
+ "context": "btn label",
+ "string": "Go to all products"
+ },
"Xb6BJ9": {
"context": "error message",
"string": "Manual payments can not be refunded"
@@ -5535,10 +5697,6 @@
"context": "table column header",
"string": "Price"
},
- "Y3pCRX": {
- "context": "attribute can be searched in storefront",
- "string": "Use as filter"
- },
"Y3zr/B": {
"context": "voucher application, switch button",
"string": "Apply only to a single cheapest eligible product"
@@ -5799,9 +5957,16 @@
"context": "note input subtitle",
"string": "Why was this gift card issued. This note will not be shown to the customer. Note will be stored in gift card history"
},
+ "Zvo5iu": {
+ "string": "API reference"
+ },
"Zz67wc": {
"string": "View and update your webhooks and events."
},
+ "a+WuZg": {
+ "context": "cta button label",
+ "string": "View Documentation"
+ },
"a+iRI1": {
"context": "single gift card title",
"string": "{selectedItemsCount,plural,one{Delete Gift Card} other{Delete Gift Cards}}"
@@ -5814,6 +5979,10 @@
"context": "select option, button",
"string": "Select"
},
+ "a/JR9Y": {
+ "context": "sale type order discount",
+ "string": "Sale"
+ },
"a/QJBx": {
"context": "user action bar",
"string": "Action"
@@ -5822,10 +5991,6 @@
"context": "draft created from replace products list title",
"string": "Products replaced"
},
- "a4qX2+": {
- "context": "order",
- "string": "Created"
- },
"a55zOn": {
"context": "section header",
"string": "Data privacy"
@@ -5849,10 +6014,6 @@
"context": "warehouse",
"string": "Name"
},
- "aCX8rl": {
- "context": "subheader",
- "string": "Here is some information we gathered about your store"
- },
"aEc9Ar": {
"context": "gift card history message",
"string": "Gift card balance was reset by {resetBy}"
@@ -5914,6 +6075,10 @@
"context": "price rates info",
"string": "This rate will apply to all orders"
},
+ "aasX8r": {
+ "context": "label",
+ "string": "Link type"
+ },
"abTH5q": {
"context": "error message",
"string": "Email address is not set"
@@ -6090,10 +6255,6 @@
"context": "voucher requirement",
"string": "Minimal order value"
},
- "biAxKR": {
- "context": "click and collect",
- "string": "Click&Collect"
- },
"biDgQS": {
"context": "button, opens modal to create transaction in order",
"string": "Manual transaction"
@@ -6241,9 +6402,6 @@
"context": "Webhook details events",
"string": "Events"
},
- "caMMWN": {
- "string": "Search Warehouse"
- },
"caqRmN": {
"context": "header",
"string": "Create Page Type"
@@ -6314,6 +6472,9 @@
"context": "volume units types",
"string": "Volume"
},
+ "d+qgix": {
+ "string": "Next step"
+ },
"d1PvC8": {
"context": "checkbox",
"string": "Grant refund for returned items"
@@ -6344,10 +6505,6 @@
"dHAwu8": {
"string": "Code already exists"
},
- "dJQxHt": {
- "context": "delete category",
- "string": "Are you sure you want to delete {categoryName}?"
- },
"dJVXIb": {
"context": "vat included in order price",
"string": "VAT included"
@@ -6377,6 +6534,12 @@
"context": "edit tracking button",
"string": "Edit tracking"
},
+ "dVSBW6": {
+ "string": "Related note id"
+ },
+ "dVk241": {
+ "string": "product configurations"
+ },
"dWK/Ck": {
"string": "Choose countries, you want voucher to be limited to, from the list below"
},
@@ -6387,10 +6550,6 @@
"context": "products export type label",
"string": "products"
},
- "diOQm7": {
- "context": "product status",
- "string": "Available"
- },
"dnbJKr": {
"string": "This transaction doesn't have any events"
},
@@ -6409,10 +6568,6 @@
"context": "current balance filter label",
"string": "Current balance"
},
- "e08xWz": {
- "context": "header",
- "string": "Top products"
- },
"e0RKe+": {
"context": "generate invoice button",
"string": "Generate"
@@ -6420,10 +6575,6 @@
"e0lt+l": {
"string": "See documentation"
},
- "e1vU/4": {
- "context": "attribute is filterable in storefront",
- "string": "Use as filter"
- },
"e4UtKH": {
"context": "Transaction event status - failure",
"string": "Failure"
@@ -6492,6 +6643,14 @@
"context": "button",
"string": "Choose file"
},
+ "eWrHmu": {
+ "context": "onboarding step title",
+ "string": "View webhooks functionalities"
+ },
+ "eaoi2W": {
+ "context": "tab name",
+ "string": "All warehouses"
+ },
"egBBQ/": {
"context": "all captured amount from transactions in order",
"string": "Captured"
@@ -6581,6 +6740,9 @@
"context": "gift card history message",
"string": "Gift card expiry date was updated"
},
+ "fM7xZh": {
+ "string": "updated"
+ },
"fNFEkh": {
"string": "No of Rows:"
},
@@ -6680,10 +6842,6 @@
"context": "product organization, header",
"string": "Organization"
},
- "fzDI3A": {
- "context": "add link to navigation",
- "string": "Link to: {url}"
- },
"fzk04H": {
"context": "dialog title",
"string": "Delete image"
@@ -6695,10 +6853,6 @@
"fzpXvv": {
"string": "Are you sure you want to remove {email} avatar?"
},
- "g+GAf4": {
- "context": "product visibility",
- "string": "Visibility"
- },
"g/BrOt": {
"string": "Url has invalid format"
},
@@ -6717,6 +6871,13 @@
"context": "export items to csv file, choice field label",
"string": "Export information for:"
},
+ "g8lXTL": {
+ "context": "swatch attribute",
+ "string": "Swatch"
+ },
+ "g9HrbF": {
+ "string": "Need technical help?"
+ },
"g9Mb+U": {
"context": "change warehouse dialog title",
"string": "Change warehouse"
@@ -6725,10 +6886,6 @@
"context": "gift card history message",
"string": "Gift card was deactivated by {deactivatedBy}"
},
- "gF6ueC": {
- "context": "edit refund title",
- "string": "Edit refund wiht line items"
- },
"gKdGxP": {
"context": "error message",
"string": "Only pre-authorized payments can be captured"
@@ -6814,13 +6971,13 @@
"grkY2V": {
"string": "You don't have access to any channels"
},
+ "gt05TH": {
+ "context": "tooltip message",
+ "string": "You don't have permission to manage staff"
+ },
"gvOzOl": {
"string": "Page Title"
},
- "gx4wCT": {
- "context": "swatch attribute type",
- "string": "Swatch"
- },
"gx6b6x": {
"context": "search shortcut",
"string": "Search"
@@ -6851,10 +7008,6 @@
"context": "caption",
"string": "If enabled, attribute will be accessible to customers."
},
- "h2hEKV": {
- "context": "search gift card placeholder",
- "string": "Search gift cards, e.g {exampleGiftCardCode}"
- },
"h2vipu": {
"string": "Code"
},
@@ -6876,6 +7029,10 @@
"context": "product type name",
"string": "Type Name"
},
+ "hIh8bm": {
+ "context": "automatically complete checkouts checkbox description",
+ "string": "When enabled, checkouts detected as fully paid will be completed automatically, without checkoutComplete mutation. ({link})"
+ },
"hJDnLg": {
"context": "section header",
"string": "Upcoming Apps"
@@ -6940,6 +7097,9 @@
"context": "docs link label",
"string": "Learn more..."
},
+ "hniz8Z": {
+ "string": "here"
+ },
"ho75Lr": {
"context": "status label deactivated",
"string": "Deactivated"
@@ -6963,6 +7123,10 @@
"context": "table head",
"string": "Collection Name"
},
+ "htGz4h": {
+ "context": "onboarding step description",
+ "string": "Invite team members and assign permissions on Product Information Management (PIM), Order Management System (OMS), Promotions engine, Integrations (Apps)"
+ },
"htvX+Z": {
"string": "Deny"
},
@@ -7023,6 +7187,10 @@
"context": "grant refund, refund card subtitle",
"string": "How much money do you want to return to the customer for the order?"
},
+ "iIPThY": {
+ "context": "onboarding title",
+ "string": "Let’s Get Started ({count}/{total})"
+ },
"iIfq2+": {
"context": "Transaction cancel button - return preauthorized amount to client",
"string": "Cancel"
@@ -7089,6 +7257,14 @@
"context": "header",
"string": "App Information"
},
+ "inWs4U": {
+ "context": "attribute visibility in storefront",
+ "string": "Visible in storefront"
+ },
+ "ipbT0Q": {
+ "context": "btn label",
+ "string": "Mark all as done"
+ },
"isM94c": {
"context": "create service token, button",
"string": "Create"
@@ -7100,6 +7276,10 @@
"ivJ1qt": {
"string": "Manage your permission groups and their permissions"
},
+ "ivmwpV": {
+ "context": "tab name",
+ "string": "All product types"
+ },
"ixjvkM": {
"string": "We’ve created your default token. Make sure to copy your new personal access token now. You won’t be able to see it again."
},
@@ -7134,6 +7314,10 @@
"context": "order history message",
"string": "Shipping tracking number was sent to customer"
},
+ "j5hGyJ": {
+ "context": "attribute is filterable in dashboard",
+ "string": "Filterable in dashboard"
+ },
"j8PV7E": {
"context": "attribute values",
"string": "Values"
@@ -7157,9 +7341,6 @@
"context": "page header",
"string": "Primary Address"
},
- "jHJmjf": {
- "string": "No results"
- },
"jMzyU8": {
"context": "tax classes card header",
"string": "Tax classes"
@@ -7186,6 +7367,10 @@
"context": "product availability",
"string": "Hide in product listings"
},
+ "jY80Gs": {
+ "context": "search gift card placeholder",
+ "string": "Search by code, e.g {exampleGiftCardCode}"
+ },
"ja+tNj": {
"string": "requests access to new permissions."
},
@@ -7243,6 +7428,10 @@
"context": "refunded fulfillment, section header",
"string": "Replaced"
},
+ "jzu97k": {
+ "context": "attribute product type",
+ "string": "Product type"
+ },
"k+HcTv": {
"context": "product type",
"string": "Type"
@@ -7272,10 +7461,6 @@
"context": "select label",
"string": "Unset"
},
- "k6WDZl": {
- "context": "attribute is visible",
- "string": "Visible"
- },
"k6sfZr": {
"context": "tooltip content when product is in preorder",
"string": "This product is still in preorder. You will be able to fulfill it after it reaches it’s release date"
@@ -7438,10 +7623,22 @@
"context": "dialog title",
"string": "Capture manual transaction"
},
+ "kv3FWU": {
+ "context": "btn label",
+ "string": "Go to orders"
+ },
"kvSYZh": {
"context": "replacement created order history message description",
"string": "was created for replaced products"
},
+ "kyNv+Y": {
+ "context": "footer description",
+ "string": "Are we missing an integration your project requires? Let us know here"
+ },
+ "l0a2tU": {
+ "context": "onboarding step description",
+ "string": "Go to all products from where you can create a new product and view it in all product list. View the product in GraphQL"
+ },
"l1/Hwb": {
"context": "invalid date in expirydate field header",
"string": "Incorrect date entered"
@@ -7454,6 +7651,10 @@
"context": "transaction event type, transaction was refunded to client",
"string": "Refund"
},
+ "l4o0ar": {
+ "context": "voucher type order discount",
+ "string": "Voucher: {voucherName}"
+ },
"l5V0QT": {
"context": "boolean attribute type",
"string": "Boolean"
@@ -7494,10 +7695,6 @@
"context": "table head",
"string": "Variant Name"
},
- "lJP1iw": {
- "context": "order",
- "string": "Channel"
- },
"lJXkFS": {
"context": "discount name",
"string": "Discount name"
@@ -7560,6 +7757,10 @@
"lfXze9": {
"string": "Delete vouchers"
},
+ "lhfPkc": {
+ "context": "variant stocks section subtitle",
+ "string": "Assigning the stocks will be possible after the product is saved."
+ },
"li1BBk": {
"context": "export items as csv file",
"string": "Plain CSV file"
@@ -7579,6 +7780,10 @@
"context": "country rates list label for the default rate",
"string": "Country default rate"
},
+ "loEfAh": {
+ "context": "onboarding completed message",
+ "string": "Onboarding completed 🎉"
+ },
"lqIzC8": {
"string": "This field needs to be unique"
},
@@ -7646,6 +7851,10 @@
"context": "NoChannels content",
"string": "No channels to assign. Please first assign them for the product."
},
+ "mU695h": {
+ "context": "onboarding step description",
+ "string": "We’ll guide you through the main features so you can start customizing your store. Explore products, orders, collections, customers, and discounts to get familiar with key functions and concepts."
+ },
"mWQt3s": {
"string": "No. of Products"
},
@@ -7732,6 +7941,9 @@
"context": "label",
"string": "External app"
},
+ "nABmvC": {
+ "string": "No. of rows"
+ },
"nBzIBG": {
"string": "Delete permission group"
},
@@ -7747,14 +7959,14 @@
"context": "expiration date label",
"string": "Expiration date"
},
+ "nG1+Cz": {
+ "context": "staff members status active",
+ "string": "Active"
+ },
"nHmugP": {
"context": "order history message",
"string": "Fulfilled {quantity} items"
},
- "nII/qB": {
- "context": "number of ordered products",
- "string": "{amount, plural,one {One ordered}other {{amount} ordered}}"
- },
"nIrjSR": {
"context": "section header",
"string": "Ongoing Installations"
@@ -7952,6 +8164,10 @@
"oYGfnY": {
"string": "ZIP / Postal code"
},
+ "oYV+Ru": {
+ "context": "staff members status deactivated",
+ "string": "Inactive"
+ },
"oboeOT": {
"string": "Add following permissions"
},
@@ -7990,6 +8206,10 @@
"context": "unassign products from shipping rate and save, button",
"string": "Unassign and save"
},
+ "p/m4dD": {
+ "context": "onboarding step title",
+ "string": "Invite staff members"
+ },
"p12BmC": {
"context": "transaction refund tiles disabled transaction",
"string": "This transaction is non-refundable."
@@ -8025,10 +8245,6 @@
"pAwBtz": {
"string": "Reward value"
},
- "pBTTtU": {
- "context": "product kind",
- "string": "Product Kind"
- },
"pC6/1z": {
"string": "Invalid manifest format"
},
@@ -8084,10 +8300,6 @@
"paa4m0": {
"string": "Successfully created product type"
},
- "pbGIUg": {
- "context": "sales channel",
- "string": "Channel"
- },
"phAZoj": {
"string": "Collection"
},
@@ -8171,6 +8383,9 @@
"context": "header",
"string": "Add Value to Authorization Field"
},
+ "qD1kvF": {
+ "string": "The timeline below shows the history of all events related to this order. Each entry represents a single event along with its content or readable description. For more information regarding order events, you can find {link}."
+ },
"qDfaDI": {
"string": "No app or plugin is configured to handle requested transaction action"
},
@@ -8214,9 +8429,17 @@
"qPSWmL": {
"string": "Enter usage"
},
+ "qQih8j": {
+ "context": "voucher status scheduled",
+ "string": "Scheduled"
+ },
"qSCmIG": {
"string": "lower than {value}"
},
+ "qT0qr/": {
+ "context": "attribute page type",
+ "string": "Page type"
+ },
"qT6YYk": {
"context": "order line total price",
"string": "Total"
@@ -8278,6 +8501,10 @@
"context": "dialog title",
"string": "Delete Token"
},
+ "qzDwLa": {
+ "context": "Invalid url value",
+ "string": "Invalid URL"
+ },
"r+8q4B": {
"context": "error message",
"string": "Only draft orders can be edited"
@@ -8375,9 +8602,6 @@
"context": "expires in label",
"string": "Expires in"
},
- "rpFdD1": {
- "string": "Search Product Type"
- },
"rqiCWU": {
"string": "Saved changes"
},
@@ -8429,10 +8653,6 @@
"context": "limit voucher",
"string": "Limit of Uses"
},
- "s5v6m0": {
- "context": "order",
- "string": "Gift Card ordered"
- },
"s6lW8R": {
"context": "option label",
"string": "Change address"
@@ -8449,10 +8669,6 @@
"context": "button",
"string": "OK"
},
- "sEjRyz": {
- "context": "voucher type order discount",
- "string": "Voucher"
- },
"sFynTT": {
"context": "grant refund, refund card title",
"string": "Refund"
@@ -8556,6 +8772,9 @@
"context": "variant pricing section subtitle",
"string": "There is no channel to define prices for. You need to first add variant to channels to define prices."
},
+ "swOKYO": {
+ "string": "Discover the latest enhancements, new features, fixes, and performance improvements that make your dashboard experience even better."
+ },
"szXISP": {
"context": "permission group name",
"string": "Permission Group Name"
@@ -8638,6 +8857,9 @@
"tiY7bx": {
"string": "Add new product"
},
+ "tl1/1E": {
+ "string": "Learn more about {orderManagement}"
+ },
"tlGXkh": {
"context": "input description",
"string": "Unlimited"
@@ -8793,6 +9015,10 @@
"ufD5Jr": {
"string": "Content type"
},
+ "ufahVh": {
+ "context": "collection filter hidden",
+ "string": "Hidden"
+ },
"ufmuTp": {
"context": "button",
"string": "Delete"
@@ -9099,6 +9325,9 @@
"wNQzS/": {
"string": "The primary address of this customer."
},
+ "wO9wb5": {
+ "string": "GitHub"
+ },
"wOeIR4": {
"context": "order history message",
"string": "Restocked {quantity} items"
@@ -9188,6 +9417,10 @@
"x0n6YG": {
"string": "This refund is currently being processed and cannot be edited"
},
+ "x0wum5": {
+ "context": "home sidebar card title",
+ "string": "Your store info"
+ },
"x2mg39": {
"context": "Transaction event description",
"string": "Used in order"
@@ -9200,10 +9433,6 @@
"context": "ProductTypeDeleteWarningDialog title",
"string": "Delete product {selectedTypesCount,plural,one{type} other{types}}"
},
- "x8V/xS": {
- "context": "attribute visibility in storefront",
- "string": "Public"
- },
"xAHOGV": {
"context": "dialog header",
"string": "Assign Variant"
@@ -9216,6 +9445,9 @@
"context": "gift card settings header",
"string": "Gift Cards Settings"
},
+ "xJEaxW": {
+ "string": "added"
+ },
"xJQX5t": {
"string": "No staff members found"
},
@@ -9287,6 +9519,9 @@
"context": "dialog title",
"string": "Delete category"
},
+ "xol6jX": {
+ "string": "You don't have permission to manage orders"
+ },
"xoyCZ/": {
"context": "error message",
"string": "Improper value"
@@ -9360,10 +9595,6 @@
"context": "discount value",
"string": "discount"
},
- "yKuba7": {
- "context": "attribute can be searched in dashboard",
- "string": "Searchable"
- },
"yLfbSh": {
"context": "support label",
"string": "Channel name"
@@ -9480,6 +9711,9 @@
"z9c6/C": {
"string": "Deprecated"
},
+ "z9f2oQ": {
+ "string": "Recent Dashboard Updates"
+ },
"z9wQ/U": {
"context": "no variant stock in warehouse",
"string": "No Stock"
@@ -9519,6 +9753,9 @@
"context": "select all channels label",
"string": "Select All Channels"
},
+ "zRIsjN": {
+ "string": "Learn more about {apiReference} and view {apiGuide}"
+ },
"zRrcOG": {
"context": "order history message",
"string": "Order was cancelled"
@@ -9529,6 +9766,9 @@
"zSOvI0": {
"string": "Filters"
},
+ "zT1CvH": {
+ "string": "Learn more about {extendingSaleor}"
+ },
"zWM89r": {
"context": "numeric attribute units of",
"string": "Units of"
@@ -9595,6 +9835,10 @@
"context": "product available for purchase date",
"string": "Will become available on {date}"
},
+ "zp9VHt": {
+ "context": "cta button label",
+ "string": "Explore Updates"
+ },
"zqarUF": {
"context": "modal information under title",
"string": "Select an address you want to use from the list below"
@@ -9602,6 +9846,10 @@
"ztQgD8": {
"string": "No attributes found"
},
+ "ztvvcm": {
+ "context": "swatch attribute type",
+ "string": "Swatch type"
+ },
"zxs6G3": {
"string": "Manage how you ship out orders"
},
diff --git a/nginx/replace-api-url.sh b/nginx/replace-api-url.sh
deleted file mode 100755
index 07aa5cbc640..00000000000
--- a/nginx/replace-api-url.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env sh
-
-# Replaces the API_URL from the bundle's index.html file with the $API_URL env var.
-# This script is automatically picked up by the nginx entrypoint on startup.
-
-set -e
-
-INDEX_BUNDLE_PATH="/app/dashboard/index.html"
-
-if [ -z "${API_URL}" ]; then
- echo "No API_URL provided, using defaults."
-else
- echo "Setting API_URL to: $API_URL"
-
- sed -i "s#API_URL:.*#API_URL: \"$API_URL\",#" "$INDEX_BUNDLE_PATH"
-fi
diff --git a/nginx/replace-env-vars.sh b/nginx/replace-env-vars.sh
new file mode 100755
index 00000000000..57cf63c6131
--- /dev/null
+++ b/nginx/replace-env-vars.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+# Replaces environment variables in the bundle's index.html file with their respective values.
+# This script is automatically picked up by the nginx entrypoint on startup.
+
+set -e
+
+INDEX_BUNDLE_PATH="/app/dashboard/index.html"
+
+# Function to replace environment variables
+replace_env_var() {
+ var_name=$1
+ var_value=$(eval echo \$"$var_name")
+ if [ -n "$var_value" ]; then
+ echo "Setting $var_name to: $var_value"
+ sed -i "s#$var_name: \".*\"#$var_name: \"$var_value\"#" "$INDEX_BUNDLE_PATH"
+ else
+ echo "No $var_name provided, using defaults."
+ fi
+}
+
+# Replace each environment variable
+replace_env_var "API_URL"
+replace_env_var "APP_MOUNT_URI"
+replace_env_var "APPS_MARKETPLACE_API_URL"
+replace_env_var "APPS_TUNNEL_URL_KEYWORDS"
+replace_env_var "IS_CLOUD_INSTANCE"
+replace_env_var "LOCALE_CODE"
+
+echo "Environment variable replacement complete."
diff --git a/package-lock.json b/package-lock.json
index d57bc066f88..584a6ae6000 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,21 +1,20 @@
{
"name": "saleor-dashboard",
- "version": "3.20.0-dev",
+ "version": "3.20.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "saleor-dashboard",
- "version": "3.20.0-dev",
+ "version": "3.20.3",
"license": "BSD-3-Clause",
"dependencies": {
"@apollo/client": "3.4.17",
- "@dnd-kit/core": "^6.0.8",
+ "@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^7.0.2",
"@dnd-kit/utilities": "^3.2.1",
- "@editorjs/editorjs": "^2.24.3",
+ "@editorjs/editorjs": "^2.30.7",
"@editorjs/header": "^2.6.2",
- "@editorjs/image": "^2.6.2",
"@editorjs/list": "^1.7.0",
"@editorjs/paragraph": "^2.8.0",
"@editorjs/quote": "^2.4.0",
@@ -31,20 +30,17 @@
"@material-ui/styles": "^4.11.4",
"@reach/auto-id": "^0.16.0",
"@saleor/macaw-ui": "npm:@saleor/macaw-ui@0.7.4",
- "@saleor/macaw-ui-next": "npm:@saleor/macaw-ui@1.1.5",
+ "@saleor/macaw-ui-next": "npm:@saleor/macaw-ui@1.1.15",
"@saleor/sdk": "0.6.0",
- "@sentry/react": "^7.83.0",
- "@sentry/vite-plugin": "^2.15.0",
+ "@sentry/react": "^8.21.0",
+ "@sentry/vite-plugin": "^2.21.1",
"@types/faker": "^5.1.6",
"@uiw/react-color-hue": "0.0.34",
- "@uiw/react-color-material": "^0.1.0",
"@uiw/react-color-saturation": "0.0.34",
- "@vanilla-extract/css-utils": "^0.1.3",
"apollo-upload-client": "^17.0.0",
"chroma-js": "^2.4.2",
"clsx": "^1.2.1",
"color-convert": "^2.0.1",
- "crc-32": "^1.2.2",
"currency-codes": "^2.1.0",
"currency.js": "^2.0.4",
"debug": "^4.3.4",
@@ -53,44 +49,35 @@
"eslint-plugin-prettier": "^5.1.3",
"faker": "^5.1.0",
"fast-array-diff": "^0.2.0",
- "find-test-names": "^1.17.1",
"front-matter": "^4.0.2",
"fuse.js": "^6.6.2",
"graphiql": "^2.2.0",
"graphql": "^15.4.0",
"hotkeys-js": "^3.8.1",
"is-url": "^1.2.4",
- "jss": "^9.8.7",
- "junit-report-merger": "^3.0.5",
"jwt-decode": "^3.1.2",
"keycode": "^2.2.1",
"lodash": "^4.17.21",
- "lz-string": "^1.4.4",
"marked": "^4.0.17",
"moment-timezone": "^0.5.32",
- "pixelmatch": "^5.3.0",
"posthog-js": "^1.105.9",
"qs": "^6.10.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
- "react-draggable": "^4.4.5",
"react-dropzone": "^11.2.4",
"react-editor-js": "^2.0.6",
"react-error-boundary": "^3.1.4",
- "react-github-btn": "^1.4.0",
"react-gtm-module": "^2.0.11",
"react-helmet": "^6.1.0",
"react-hook-form": "^7.48.2",
"react-infinite-scroll-component": "^6.1.0",
"react-inlinesvg": "^3.0.2",
"react-intl": "^5.21.2",
- "react-jss": "^10.0.0",
"react-moment": "^1.0.0",
"react-responsive-carousel": "^3.2.23",
"react-router": "^5.0.1",
"react-router-dom": "^5.0.1",
"react-sortable-hoc": "^1.10.1",
- "remark-gfm": "^3.0.1",
"slugify": "^1.4.6",
"tslib": "^2.4.1",
"url-join": "^4.0.1",
@@ -99,8 +86,7 @@
"zod": "^3.22.4"
},
"devDependencies": {
- "@changesets/changelog-github": "^0.4.8",
- "@changesets/cli": "^2.26.1",
+ "@changesets/cli": "^2.27.9",
"@editorjs/embed": "^2.5.3",
"@esbuild-plugins/node-globals-polyfill": "^0.1.1",
"@formatjs/cli": "^4.5.0",
@@ -113,15 +99,15 @@
"@graphql-codegen/typescript-apollo-client-helpers": "^2.1.10",
"@graphql-codegen/typescript-operations": "^2.2.4",
"@graphql-codegen/typescript-react-apollo": "^3.2.5",
- "@playwright/test": "^1.40.0",
+ "@playwright/test": "^1.47.0",
"@saleor/app-sdk": "0.47.2",
- "@sentry/cli": "^2.22.3",
+ "@sentry/cli": "^2.33.0",
"@swc/jest": "^0.2.26",
"@types/apollo-upload-client": "^17.0.2",
"@types/chroma-js": "^2.4.0",
"@types/color-convert": "^2.0.0",
"@types/debug": "^4.1.7",
- "@types/is-ci": "^3.0.0",
+ "@types/is-url": "^1.2.32",
"@types/lodash-es": "^4.17.3",
"@types/node": "^20.8.0",
"@types/qs": "^6.9.12",
@@ -130,7 +116,6 @@
"@types/react-dropzone": "^4.2.2",
"@types/react-gtm-module": "^2.0.3",
"@types/react-helmet": "^5.0.8",
- "@types/react-infinite-scroller": "^1.2.3",
"@types/react-router-dom": "^4.3.4",
"@types/react-sortable-hoc": "^0.7.1",
"@types/url-join": "^4.0.1",
@@ -139,15 +124,11 @@
"@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.41.0",
"@vitejs/plugin-react-swc": "^3.2.0",
- "ci-info": "^3.7.0",
"code-inspector-plugin": "^0.6.1",
- "codecov": "^3.7.1",
"core-js": "^3.7.0",
"cross-env": "^6.0.3",
"dependency-cruiser": "^12.10.0",
"dotenv": "^10.0.0",
- "env-var": "^7.3.0",
- "esbuild-loader": "^2.18.0",
"eslint": "^8.43.0",
"eslint-config-prettier": "^8.5.0",
"eslint-nibble": "^8.1.0",
@@ -158,21 +139,17 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.3.1",
"eslint-plugin-simple-import-sort": "^10.0.0",
- "graphql-request": "^3.7.0",
"html-to-react": "^1.6.0",
"identity-obj-proxy": "^3.0.0",
"is-ci": "^3.0.1",
- "junit-merge": "^2.0.0",
+ "knip": "^5.30.5",
"mocha": "^10.2.0",
"mochawesome": "^7.1.3",
"mochawesome-merge": "^4.3.0",
"mochawesome-report-generator": "^6.2.0",
+ "playwright-ctrf-json-reporter": "^0.0.18",
"playwright-testmo-reporter": "^1.8.4",
- "regenerator-runtime": "^0.11.1",
- "require-context.macro": "^1.1.1",
- "rimraf": "^3.0.0",
"rollup-plugin-polyfill-node": "^0.11.0",
- "start-server-and-test": "^1.11.0",
"typescript": "^5.0.4",
"typescript-strict-plugin": "^2.1.0",
"vite": "^3.2.7",
@@ -196,7 +173,7 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^12.1.5",
"@testing-library/react-hooks": "^8.0.1",
- "@testing-library/user-event": "^14.4.3",
+ "@testing-library/user-event": "^14.5.2",
"@types/jest": "^26.0.14",
"@types/setup-polly-jest": "^0.5.0",
"fsevents": "^1.2.9",
@@ -217,9 +194,9 @@
}
},
"node_modules/@adobe/css-tools": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.1.tgz",
- "integrity": "sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz",
+ "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==",
"optional": true
},
"node_modules/@ampproject/remapping": {
@@ -273,6 +250,183 @@
"node": ">=0.10"
}
},
+ "node_modules/@ardatan/relay-compiler": {
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/@ardatan/relay-compiler/-/relay-compiler-12.0.0.tgz",
+ "integrity": "sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.14.0",
+ "@babel/generator": "^7.14.0",
+ "@babel/parser": "^7.14.0",
+ "@babel/runtime": "^7.0.0",
+ "@babel/traverse": "^7.14.0",
+ "@babel/types": "^7.0.0",
+ "babel-preset-fbjs": "^3.4.0",
+ "chalk": "^4.0.0",
+ "fb-watchman": "^2.0.0",
+ "fbjs": "^3.0.0",
+ "glob": "^7.1.1",
+ "immutable": "~3.7.6",
+ "invariant": "^2.2.4",
+ "nullthrows": "^1.1.1",
+ "relay-runtime": "12.0.0",
+ "signedsource": "^1.0.0",
+ "yargs": "^15.3.1"
+ },
+ "bin": {
+ "relay-compiler": "bin/relay-compiler"
+ },
+ "peerDependencies": {
+ "graphql": "*"
+ }
+ },
+ "node_modules/@ardatan/relay-compiler/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@ardatan/relay-compiler/node_modules/cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "node_modules/@ardatan/relay-compiler/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@ardatan/relay-compiler/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@ardatan/relay-compiler/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@ardatan/relay-compiler/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@ardatan/relay-compiler/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@ardatan/relay-compiler/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@ardatan/relay-compiler/node_modules/wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@ardatan/relay-compiler/node_modules/yargs": {
+ "version": "15.4.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^6.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^4.1.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^4.2.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^18.1.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@ardatan/relay-compiler/node_modules/yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "dev": true,
+ "dependencies": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/@ardatan/sync-fetch": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/@ardatan/sync-fetch/-/sync-fetch-0.0.1.tgz",
@@ -286,11 +440,11 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.24.2",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
- "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
+ "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
"dependencies": {
- "@babel/highlight": "^7.24.2",
+ "@babel/highlight": "^7.24.7",
"picocolors": "^1.0.0"
},
"engines": {
@@ -298,9 +452,9 @@
}
},
"node_modules/@babel/compat-data": {
- "version": "7.24.4",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz",
- "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==",
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz",
+ "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==",
"engines": {
"node": ">=6.9.0"
}
@@ -348,13 +502,13 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
- "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
+ "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
"dependencies": {
- "@babel/types": "^7.23.0",
- "@jridgewell/gen-mapping": "^0.3.2",
- "@jridgewell/trace-mapping": "^0.3.17",
+ "@babel/types": "^7.25.6",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^2.5.1"
},
"engines": {
@@ -362,25 +516,25 @@
}
},
"node_modules/@babel/helper-annotate-as-pure": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
- "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz",
+ "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.22.5"
+ "@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-compilation-targets": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz",
- "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==",
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz",
+ "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==",
"dependencies": {
- "@babel/compat-data": "^7.23.5",
- "@babel/helper-validator-option": "^7.23.5",
- "browserslist": "^4.22.2",
+ "@babel/compat-data": "^7.25.2",
+ "@babel/helper-validator-option": "^7.24.8",
+ "browserslist": "^4.23.1",
"lru-cache": "^5.1.1",
"semver": "^6.3.1"
},
@@ -410,19 +564,17 @@
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
},
"node_modules/@babel/helper-create-class-features-plugin": {
- "version": "7.24.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.4.tgz",
- "integrity": "sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ==",
- "dev": true,
- "dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-member-expression-to-functions": "^7.23.0",
- "@babel/helper-optimise-call-expression": "^7.22.5",
- "@babel/helper-replace-supers": "^7.24.1",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz",
+ "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.24.7",
+ "@babel/helper-member-expression-to-functions": "^7.24.8",
+ "@babel/helper-optimise-call-expression": "^7.24.7",
+ "@babel/helper-replace-supers": "^7.25.0",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
+ "@babel/traverse": "^7.25.4",
"semver": "^6.3.1"
},
"engines": {
@@ -441,70 +593,40 @@
"semver": "bin/semver.js"
}
},
- "node_modules/@babel/helper-environment-visitor": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
- "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-function-name": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
- "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
- "dependencies": {
- "@babel/template": "^7.22.15",
- "@babel/types": "^7.23.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-hoist-variables": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
- "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
- "dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-member-expression-to-functions": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz",
- "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz",
+ "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.23.0"
+ "@babel/traverse": "^7.24.8",
+ "@babel/types": "^7.24.8"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-imports": {
- "version": "7.24.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz",
- "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
+ "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
"dependencies": {
- "@babel/types": "^7.24.0"
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
- "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz",
+ "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==",
"dependencies": {
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-module-imports": "^7.22.15",
- "@babel/helper-simple-access": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/helper-validator-identifier": "^7.22.20"
+ "@babel/helper-module-imports": "^7.24.7",
+ "@babel/helper-simple-access": "^7.24.7",
+ "@babel/helper-validator-identifier": "^7.24.7",
+ "@babel/traverse": "^7.25.2"
},
"engines": {
"node": ">=6.9.0"
@@ -514,34 +636,35 @@
}
},
"node_modules/@babel/helper-optimise-call-expression": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz",
- "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz",
+ "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.22.5"
+ "@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.24.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz",
- "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz",
+ "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==",
+ "devOptional": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-replace-supers": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz",
- "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==",
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz",
+ "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==",
"dev": true,
"dependencies": {
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-member-expression-to-functions": "^7.23.0",
- "@babel/helper-optimise-call-expression": "^7.22.5"
+ "@babel/helper-member-expression-to-functions": "^7.24.8",
+ "@babel/helper-optimise-call-expression": "^7.24.7",
+ "@babel/traverse": "^7.25.0"
},
"engines": {
"node": ">=6.9.0"
@@ -551,59 +674,50 @@
}
},
"node_modules/@babel/helper-simple-access": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
- "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
+ "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
"dependencies": {
- "@babel/types": "^7.22.5"
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz",
- "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz",
+ "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.22.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-split-export-declaration": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
- "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
- "dependencies": {
- "@babel/types": "^7.22.5"
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
- "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
+ "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
- "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
+ "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-option": {
- "version": "7.23.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz",
- "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz",
+ "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==",
"engines": {
"node": ">=6.9.0"
}
@@ -622,11 +736,11 @@
}
},
"node_modules/@babel/highlight": {
- "version": "7.24.2",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz",
- "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
+ "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.22.20",
+ "@babel/helper-validator-identifier": "^7.24.7",
"chalk": "^2.4.2",
"js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
@@ -636,9 +750,12 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.24.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz",
- "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==",
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
+ "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
+ "dependencies": {
+ "@babel/types": "^7.25.6"
+ },
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -650,6 +767,7 @@
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz",
"integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.",
"dev": true,
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.18.6",
@@ -666,6 +784,7 @@
"version": "7.20.7",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz",
"integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==",
+ "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.",
"dev": true,
"dependencies": {
"@babel/compat-data": "^7.20.5",
@@ -715,11 +834,15 @@
}
},
"node_modules/@babel/plugin-syntax-flow": {
- "version": "7.12.13",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.7.tgz",
+ "integrity": "sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
@@ -763,11 +886,12 @@
}
},
"node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.21.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz",
- "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz",
+ "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==",
+ "dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.20.2"
+ "@babel/helper-plugin-utils": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -869,12 +993,12 @@
}
},
"node_modules/@babel/plugin-transform-arrow-functions": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz",
- "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz",
+ "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -884,12 +1008,12 @@
}
},
"node_modules/@babel/plugin-transform-block-scoped-functions": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz",
- "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz",
+ "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -899,12 +1023,12 @@
}
},
"node_modules/@babel/plugin-transform-block-scoping": {
- "version": "7.24.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.4.tgz",
- "integrity": "sha512-nIFUZIpGKDf9O9ttyRXpHFpKC+X3Y5mtshZONuEUYBomAKoM4y029Jr+uB1bHGPhNmK8YXHevDtKDOLmtRrp6g==",
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz",
+ "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.8"
},
"engines": {
"node": ">=6.9.0"
@@ -914,18 +1038,16 @@
}
},
"node_modules/@babel/plugin-transform-classes": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz",
- "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==",
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz",
+ "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==",
"dev": true,
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-compilation-targets": "^7.23.6",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-plugin-utils": "^7.24.0",
- "@babel/helper-replace-supers": "^7.24.1",
- "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/helper-annotate-as-pure": "^7.24.7",
+ "@babel/helper-compilation-targets": "^7.25.2",
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/helper-replace-supers": "^7.25.0",
+ "@babel/traverse": "^7.25.4",
"globals": "^11.1.0"
},
"engines": {
@@ -936,13 +1058,13 @@
}
},
"node_modules/@babel/plugin-transform-computed-properties": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz",
- "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz",
+ "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0",
- "@babel/template": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/template": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -952,12 +1074,12 @@
}
},
"node_modules/@babel/plugin-transform-destructuring": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz",
- "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz",
+ "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.8"
},
"engines": {
"node": ">=6.9.0"
@@ -967,25 +1089,29 @@
}
},
"node_modules/@babel/plugin-transform-flow-strip-types": {
- "version": "7.13.0",
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.25.2.tgz",
+ "integrity": "sha512-InBZ0O8tew5V0K6cHcQ+wgxlrjOw1W4wDXLkOTjLRD8GYhTSkxTVBtdy3MMtvYBrbAWa1Qm3hNoTc1620Yj+Mg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.13.0",
- "@babel/plugin-syntax-flow": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/plugin-syntax-flow": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/plugin-transform-for-of": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz",
- "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz",
+ "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -995,14 +1121,14 @@
}
},
"node_modules/@babel/plugin-transform-function-name": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz",
- "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==",
+ "version": "7.25.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz",
+ "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==",
"dev": true,
"dependencies": {
- "@babel/helper-compilation-targets": "^7.23.6",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-compilation-targets": "^7.24.8",
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/traverse": "^7.25.1"
},
"engines": {
"node": ">=6.9.0"
@@ -1012,12 +1138,12 @@
}
},
"node_modules/@babel/plugin-transform-literals": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz",
- "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==",
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz",
+ "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.8"
},
"engines": {
"node": ">=6.9.0"
@@ -1027,12 +1153,12 @@
}
},
"node_modules/@babel/plugin-transform-member-expression-literals": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz",
- "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz",
+ "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1042,14 +1168,14 @@
}
},
"node_modules/@babel/plugin-transform-modules-commonjs": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz",
- "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz",
+ "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==",
"dev": true,
"dependencies": {
- "@babel/helper-module-transforms": "^7.23.3",
- "@babel/helper-plugin-utils": "^7.24.0",
- "@babel/helper-simple-access": "^7.22.5"
+ "@babel/helper-module-transforms": "^7.24.8",
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/helper-simple-access": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1059,13 +1185,13 @@
}
},
"node_modules/@babel/plugin-transform-object-super": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz",
- "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz",
+ "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0",
- "@babel/helper-replace-supers": "^7.24.1"
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-replace-supers": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1075,12 +1201,12 @@
}
},
"node_modules/@babel/plugin-transform-parameters": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz",
- "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz",
+ "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1090,12 +1216,12 @@
}
},
"node_modules/@babel/plugin-transform-property-literals": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz",
- "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz",
+ "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1105,27 +1231,31 @@
}
},
"node_modules/@babel/plugin-transform-react-display-name": {
- "version": "7.12.13",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz",
+ "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.24.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"node_modules/@babel/plugin-transform-react-jsx": {
- "version": "7.21.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.5.tgz",
- "integrity": "sha512-ELdlq61FpoEkHO6gFRpfj0kUgSwQTGoaEU8eMRoS8Dv3v6e7BjEAj5WMtIBRdHUeAioMhKP5HyxNzNnP+heKbA==",
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.2.tgz",
+ "integrity": "sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA==",
"dev": true,
"dependencies": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-module-imports": "^7.21.4",
- "@babel/helper-plugin-utils": "^7.21.5",
- "@babel/plugin-syntax-jsx": "^7.21.4",
- "@babel/types": "^7.21.5"
+ "@babel/helper-annotate-as-pure": "^7.24.7",
+ "@babel/helper-module-imports": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/plugin-syntax-jsx": "^7.24.7",
+ "@babel/types": "^7.25.2"
},
"engines": {
"node": ">=6.9.0"
@@ -1135,12 +1265,12 @@
}
},
"node_modules/@babel/plugin-transform-shorthand-properties": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz",
- "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz",
+ "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1150,13 +1280,13 @@
}
},
"node_modules/@babel/plugin-transform-spread": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz",
- "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz",
+ "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1166,12 +1296,12 @@
}
},
"node_modules/@babel/plugin-transform-template-literals": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz",
- "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz",
+ "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==",
"dev": true,
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -1181,48 +1311,45 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.21.0",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz",
- "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==",
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz",
+ "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==",
"dependencies": {
- "regenerator-runtime": "^0.13.11"
+ "regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/runtime/node_modules/regenerator-runtime": {
- "version": "0.13.11",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
- "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
},
"node_modules/@babel/template": {
- "version": "7.24.0",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
- "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
+ "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
"dependencies": {
- "@babel/code-frame": "^7.23.5",
- "@babel/parser": "^7.24.0",
- "@babel/types": "^7.24.0"
+ "@babel/code-frame": "^7.24.7",
+ "@babel/parser": "^7.25.0",
+ "@babel/types": "^7.25.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.23.2",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
- "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
- "dependencies": {
- "@babel/code-frame": "^7.22.13",
- "@babel/generator": "^7.23.0",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-hoist-variables": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/parser": "^7.23.0",
- "@babel/types": "^7.23.0",
- "debug": "^4.1.0",
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
+ "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
+ "dependencies": {
+ "@babel/code-frame": "^7.24.7",
+ "@babel/generator": "^7.25.6",
+ "@babel/parser": "^7.25.6",
+ "@babel/template": "^7.25.0",
+ "@babel/types": "^7.25.6",
+ "debug": "^4.3.1",
"globals": "^11.1.0"
},
"engines": {
@@ -1230,12 +1357,12 @@
}
},
"node_modules/@babel/types": {
- "version": "7.24.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
- "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
+ "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
"dependencies": {
- "@babel/helper-string-parser": "^7.23.4",
- "@babel/helper-validator-identifier": "^7.22.20",
+ "@babel/helper-string-parser": "^7.24.8",
+ "@babel/helper-validator-identifier": "^7.24.7",
"to-fast-properties": "^2.0.0"
},
"engines": {
@@ -1248,16 +1375,16 @@
"optional": true
},
"node_modules/@changesets/apply-release-plan": {
- "version": "6.1.3",
- "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-6.1.3.tgz",
- "integrity": "sha512-ECDNeoc3nfeAe1jqJb5aFQX7CqzQhD2klXRez2JDb/aVpGUbX673HgKrnrgJRuQR/9f2TtLoYIzrGB9qwD77mg==",
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.5.tgz",
+ "integrity": "sha512-1cWCk+ZshEkSVEZrm2fSj1Gz8sYvxgUL4Q78+1ZZqeqfuevPTPk033/yUZ3df8BKMohkqqHfzj0HOOrG0KtXTw==",
"dev": true,
"dependencies": {
- "@babel/runtime": "^7.20.1",
- "@changesets/config": "^2.3.0",
- "@changesets/get-version-range-type": "^0.3.2",
- "@changesets/git": "^2.0.0",
- "@changesets/types": "^5.2.1",
+ "@changesets/config": "^3.0.3",
+ "@changesets/get-version-range-type": "^0.4.0",
+ "@changesets/git": "^3.0.1",
+ "@changesets/should-skip-package": "^0.1.1",
+ "@changesets/types": "^6.0.0",
"@manypkg/get-packages": "^1.1.3",
"detect-indent": "^6.0.0",
"fs-extra": "^7.0.1",
@@ -1265,21 +1392,7 @@
"outdent": "^0.5.0",
"prettier": "^2.7.1",
"resolve-from": "^5.0.0",
- "semver": "^5.4.1"
- }
- },
- "node_modules/@changesets/apply-release-plan/node_modules/fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- },
- "engines": {
- "node": ">=6 <7 || >=8"
+ "semver": "^7.5.3"
}
},
"node_modules/@changesets/apply-release-plan/node_modules/prettier": {
@@ -1297,269 +1410,131 @@
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
- "node_modules/@changesets/apply-release-plan/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "bin": {
- "semver": "bin/semver"
- }
- },
"node_modules/@changesets/assemble-release-plan": {
- "version": "5.2.3",
- "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-5.2.3.tgz",
- "integrity": "sha512-g7EVZCmnWz3zMBAdrcKhid4hkHT+Ft1n0mLussFMcB1dE2zCuwcvGoy9ec3yOgPGF4hoMtgHaMIk3T3TBdvU9g==",
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.4.tgz",
+ "integrity": "sha512-nqICnvmrwWj4w2x0fOhVj2QEGdlUuwVAwESrUo5HLzWMI1rE5SWfsr9ln+rDqWB6RQ2ZyaMZHUcU7/IRaUJS+Q==",
"dev": true,
"dependencies": {
- "@babel/runtime": "^7.20.1",
- "@changesets/errors": "^0.1.4",
- "@changesets/get-dependents-graph": "^1.3.5",
- "@changesets/types": "^5.2.1",
+ "@changesets/errors": "^0.2.0",
+ "@changesets/get-dependents-graph": "^2.1.2",
+ "@changesets/should-skip-package": "^0.1.1",
+ "@changesets/types": "^6.0.0",
"@manypkg/get-packages": "^1.1.3",
- "semver": "^5.4.1"
- }
- },
- "node_modules/@changesets/assemble-release-plan/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "bin": {
- "semver": "bin/semver"
+ "semver": "^7.5.3"
}
},
"node_modules/@changesets/changelog-git": {
- "version": "0.1.14",
- "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.1.14.tgz",
- "integrity": "sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==",
- "dev": true,
- "dependencies": {
- "@changesets/types": "^5.2.1"
- }
- },
- "node_modules/@changesets/changelog-github": {
- "version": "0.4.8",
- "resolved": "https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-0.4.8.tgz",
- "integrity": "sha512-jR1DHibkMAb5v/8ym77E4AMNWZKB5NPzw5a5Wtqm1JepAuIF+hrKp2u04NKM14oBZhHglkCfrla9uq8ORnK/dw==",
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.0.tgz",
+ "integrity": "sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==",
"dev": true,
"dependencies": {
- "@changesets/get-github-info": "^0.5.2",
- "@changesets/types": "^5.2.1",
- "dotenv": "^8.1.0"
- }
- },
- "node_modules/@changesets/changelog-github/node_modules/dotenv": {
- "version": "8.6.0",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz",
- "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==",
- "dev": true,
- "engines": {
- "node": ">=10"
+ "@changesets/types": "^6.0.0"
}
},
"node_modules/@changesets/cli": {
- "version": "2.26.1",
- "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.26.1.tgz",
- "integrity": "sha512-XnTa+b51vt057fyAudvDKGB0Sh72xutQZNAdXkCqPBKO2zvs2yYZx5hFZj1u9cbtpwM6Sxtcr02/FQJfZOzemQ==",
- "dev": true,
- "dependencies": {
- "@babel/runtime": "^7.20.1",
- "@changesets/apply-release-plan": "^6.1.3",
- "@changesets/assemble-release-plan": "^5.2.3",
- "@changesets/changelog-git": "^0.1.14",
- "@changesets/config": "^2.3.0",
- "@changesets/errors": "^0.1.4",
- "@changesets/get-dependents-graph": "^1.3.5",
- "@changesets/get-release-plan": "^3.0.16",
- "@changesets/git": "^2.0.0",
- "@changesets/logger": "^0.0.5",
- "@changesets/pre": "^1.0.14",
- "@changesets/read": "^0.5.9",
- "@changesets/types": "^5.2.1",
- "@changesets/write": "^0.2.3",
+ "version": "2.27.9",
+ "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.27.9.tgz",
+ "integrity": "sha512-q42a/ZbDnxPpCb5Wkm6tMVIxgeI9C/bexntzTeCFBrQEdpisQqk8kCHllYZMDjYtEc1ZzumbMJAG8H0Z4rdvjg==",
+ "dev": true,
+ "dependencies": {
+ "@changesets/apply-release-plan": "^7.0.5",
+ "@changesets/assemble-release-plan": "^6.0.4",
+ "@changesets/changelog-git": "^0.2.0",
+ "@changesets/config": "^3.0.3",
+ "@changesets/errors": "^0.2.0",
+ "@changesets/get-dependents-graph": "^2.1.2",
+ "@changesets/get-release-plan": "^4.0.4",
+ "@changesets/git": "^3.0.1",
+ "@changesets/logger": "^0.1.1",
+ "@changesets/pre": "^2.0.1",
+ "@changesets/read": "^0.6.1",
+ "@changesets/should-skip-package": "^0.1.1",
+ "@changesets/types": "^6.0.0",
+ "@changesets/write": "^0.3.2",
"@manypkg/get-packages": "^1.1.3",
- "@types/is-ci": "^3.0.0",
- "@types/semver": "^6.0.0",
"ansi-colors": "^4.1.3",
- "chalk": "^2.1.0",
+ "ci-info": "^3.7.0",
"enquirer": "^2.3.0",
"external-editor": "^3.1.0",
"fs-extra": "^7.0.1",
- "human-id": "^1.0.2",
- "is-ci": "^3.0.1",
- "meow": "^6.0.0",
- "outdent": "^0.5.0",
+ "mri": "^1.2.0",
"p-limit": "^2.2.0",
- "preferred-pm": "^3.0.0",
+ "package-manager-detector": "^0.2.0",
+ "picocolors": "^1.1.0",
"resolve-from": "^5.0.0",
- "semver": "^5.4.1",
+ "semver": "^7.5.3",
"spawndamnit": "^2.0.0",
- "term-size": "^2.1.0",
- "tty-table": "^4.1.5"
+ "term-size": "^2.1.0"
},
"bin": {
"changeset": "bin.js"
}
},
- "node_modules/@changesets/cli/node_modules/@types/semver": {
- "version": "6.2.3",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.2.3.tgz",
- "integrity": "sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==",
- "dev": true
- },
- "node_modules/@changesets/cli/node_modules/ansi-colors": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
- "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/@changesets/cli/node_modules/fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- },
- "engines": {
- "node": ">=6 <7 || >=8"
- }
- },
- "node_modules/@changesets/cli/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "bin": {
- "semver": "bin/semver"
- }
- },
"node_modules/@changesets/config": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@changesets/config/-/config-2.3.0.tgz",
- "integrity": "sha512-EgP/px6mhCx8QeaMAvWtRrgyxW08k/Bx2tpGT+M84jEdX37v3VKfh4Cz1BkwrYKuMV2HZKeHOh8sHvja/HcXfQ==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.0.3.tgz",
+ "integrity": "sha512-vqgQZMyIcuIpw9nqFIpTSNyc/wgm/Lu1zKN5vECy74u95Qx/Wa9g27HdgO4NkVAaq+BGA8wUc/qvbvVNs93n6A==",
"dev": true,
"dependencies": {
- "@changesets/errors": "^0.1.4",
- "@changesets/get-dependents-graph": "^1.3.5",
- "@changesets/logger": "^0.0.5",
- "@changesets/types": "^5.2.1",
+ "@changesets/errors": "^0.2.0",
+ "@changesets/get-dependents-graph": "^2.1.2",
+ "@changesets/logger": "^0.1.1",
+ "@changesets/types": "^6.0.0",
"@manypkg/get-packages": "^1.1.3",
"fs-extra": "^7.0.1",
"micromatch": "^4.0.2"
}
},
- "node_modules/@changesets/config/node_modules/fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- },
- "engines": {
- "node": ">=6 <7 || >=8"
- }
- },
"node_modules/@changesets/errors": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.1.4.tgz",
- "integrity": "sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==",
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz",
+ "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==",
"dev": true,
"dependencies": {
"extendable-error": "^0.1.5"
}
},
"node_modules/@changesets/get-dependents-graph": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-1.3.5.tgz",
- "integrity": "sha512-w1eEvnWlbVDIY8mWXqWuYE9oKhvIaBhzqzo4ITSJY9hgoqQ3RoBqwlcAzg11qHxv/b8ReDWnMrpjpKrW6m1ZTA==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.2.tgz",
+ "integrity": "sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==",
"dev": true,
"dependencies": {
- "@changesets/types": "^5.2.1",
+ "@changesets/types": "^6.0.0",
"@manypkg/get-packages": "^1.1.3",
- "chalk": "^2.1.0",
- "fs-extra": "^7.0.1",
- "semver": "^5.4.1"
+ "picocolors": "^1.1.0",
+ "semver": "^7.5.3"
}
},
- "node_modules/@changesets/get-dependents-graph/node_modules/fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- },
- "engines": {
- "node": ">=6 <7 || >=8"
- }
- },
- "node_modules/@changesets/get-dependents-graph/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "bin": {
- "semver": "bin/semver"
- }
- },
- "node_modules/@changesets/get-github-info": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-0.5.2.tgz",
- "integrity": "sha512-JppheLu7S114aEs157fOZDjFqUDpm7eHdq5E8SSR0gUBTEK0cNSHsrSR5a66xs0z3RWuo46QvA3vawp8BxDHvg==",
- "dev": true,
- "dependencies": {
- "dataloader": "^1.4.0",
- "node-fetch": "^2.5.0"
- }
- },
- "node_modules/@changesets/get-github-info/node_modules/dataloader": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz",
- "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==",
- "dev": true
- },
"node_modules/@changesets/get-release-plan": {
- "version": "3.0.16",
- "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-3.0.16.tgz",
- "integrity": "sha512-OpP9QILpBp1bY2YNIKFzwigKh7Qe9KizRsZomzLe6pK8IUo8onkAAVUD8+JRKSr8R7d4+JRuQrfSSNlEwKyPYg==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.4.tgz",
+ "integrity": "sha512-SicG/S67JmPTrdcc9Vpu0wSQt7IiuN0dc8iR5VScnnTVPfIaLvKmEGRvIaF0kcn8u5ZqLbormZNTO77bCEvyWw==",
"dev": true,
"dependencies": {
- "@babel/runtime": "^7.20.1",
- "@changesets/assemble-release-plan": "^5.2.3",
- "@changesets/config": "^2.3.0",
- "@changesets/pre": "^1.0.14",
- "@changesets/read": "^0.5.9",
- "@changesets/types": "^5.2.1",
+ "@changesets/assemble-release-plan": "^6.0.4",
+ "@changesets/config": "^3.0.3",
+ "@changesets/pre": "^2.0.1",
+ "@changesets/read": "^0.6.1",
+ "@changesets/types": "^6.0.0",
"@manypkg/get-packages": "^1.1.3"
}
},
"node_modules/@changesets/get-version-range-type": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.3.2.tgz",
- "integrity": "sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==",
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz",
+ "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==",
"dev": true
},
"node_modules/@changesets/git": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@changesets/git/-/git-2.0.0.tgz",
- "integrity": "sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.1.tgz",
+ "integrity": "sha512-pdgHcYBLCPcLd82aRcuO0kxCDbw/yISlOtkmwmE8Odo1L6hSiZrBOsRl84eYG7DRCab/iHnOkWqExqc4wxk2LQ==",
"dev": true,
"dependencies": {
- "@babel/runtime": "^7.20.1",
- "@changesets/errors": "^0.1.4",
- "@changesets/types": "^5.2.1",
+ "@changesets/errors": "^0.2.0",
"@manypkg/get-packages": "^1.1.3",
"is-subdir": "^1.1.1",
"micromatch": "^4.0.2",
@@ -1567,114 +1542,79 @@
}
},
"node_modules/@changesets/logger": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.0.5.tgz",
- "integrity": "sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==",
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz",
+ "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==",
"dev": true,
"dependencies": {
- "chalk": "^2.1.0"
+ "picocolors": "^1.1.0"
}
},
"node_modules/@changesets/parse": {
- "version": "0.3.16",
- "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.3.16.tgz",
- "integrity": "sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==",
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.0.tgz",
+ "integrity": "sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==",
"dev": true,
"dependencies": {
- "@changesets/types": "^5.2.1",
+ "@changesets/types": "^6.0.0",
"js-yaml": "^3.13.1"
}
},
"node_modules/@changesets/pre": {
- "version": "1.0.14",
- "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-1.0.14.tgz",
- "integrity": "sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.1.tgz",
+ "integrity": "sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==",
"dev": true,
"dependencies": {
- "@babel/runtime": "^7.20.1",
- "@changesets/errors": "^0.1.4",
- "@changesets/types": "^5.2.1",
+ "@changesets/errors": "^0.2.0",
+ "@changesets/types": "^6.0.0",
"@manypkg/get-packages": "^1.1.3",
"fs-extra": "^7.0.1"
}
},
- "node_modules/@changesets/pre/node_modules/fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- },
- "engines": {
- "node": ">=6 <7 || >=8"
- }
- },
"node_modules/@changesets/read": {
- "version": "0.5.9",
- "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.5.9.tgz",
- "integrity": "sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==",
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.1.tgz",
+ "integrity": "sha512-jYMbyXQk3nwP25nRzQQGa1nKLY0KfoOV7VLgwucI0bUO8t8ZLCr6LZmgjXsiKuRDc+5A6doKPr9w2d+FEJ55zQ==",
"dev": true,
"dependencies": {
- "@babel/runtime": "^7.20.1",
- "@changesets/git": "^2.0.0",
- "@changesets/logger": "^0.0.5",
- "@changesets/parse": "^0.3.16",
- "@changesets/types": "^5.2.1",
- "chalk": "^2.1.0",
+ "@changesets/git": "^3.0.1",
+ "@changesets/logger": "^0.1.1",
+ "@changesets/parse": "^0.4.0",
+ "@changesets/types": "^6.0.0",
"fs-extra": "^7.0.1",
- "p-filter": "^2.1.0"
+ "p-filter": "^2.1.0",
+ "picocolors": "^1.1.0"
}
},
- "node_modules/@changesets/read/node_modules/fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+ "node_modules/@changesets/should-skip-package": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.1.tgz",
+ "integrity": "sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==",
"dev": true,
"dependencies": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- },
- "engines": {
- "node": ">=6 <7 || >=8"
+ "@changesets/types": "^6.0.0",
+ "@manypkg/get-packages": "^1.1.3"
}
},
"node_modules/@changesets/types": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/@changesets/types/-/types-5.2.1.tgz",
- "integrity": "sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.0.0.tgz",
+ "integrity": "sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==",
"dev": true
},
"node_modules/@changesets/write": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.2.3.tgz",
- "integrity": "sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==",
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.3.2.tgz",
+ "integrity": "sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==",
"dev": true,
"dependencies": {
- "@babel/runtime": "^7.20.1",
- "@changesets/types": "^5.2.1",
+ "@changesets/types": "^6.0.0",
"fs-extra": "^7.0.1",
"human-id": "^1.0.2",
"prettier": "^2.7.1"
}
},
- "node_modules/@changesets/write/node_modules/fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- },
- "engines": {
- "node": ">=6 <7 || >=8"
- }
- },
"node_modules/@changesets/write/node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
@@ -1729,9 +1669,9 @@
}
},
"node_modules/@dnd-kit/accessibility": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.1.tgz",
- "integrity": "sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz",
+ "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==",
"dependencies": {
"tslib": "^2.0.0"
},
@@ -1740,12 +1680,12 @@
}
},
"node_modules/@dnd-kit/core": {
- "version": "6.0.8",
- "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.0.8.tgz",
- "integrity": "sha512-lYaoP8yHTQSLlZe6Rr9qogouGUz9oRUj4AHhDQGQzq/hqaJRpFo65X+JKsdHf8oUFBzx5A+SJPUvxAwTF2OabA==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz",
+ "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==",
"dependencies": {
- "@dnd-kit/accessibility": "^3.0.0",
- "@dnd-kit/utilities": "^3.2.1",
+ "@dnd-kit/accessibility": "^3.1.1",
+ "@dnd-kit/utilities": "^3.2.2",
"tslib": "^2.0.0"
},
"peerDependencies": {
@@ -1767,9 +1707,9 @@
}
},
"node_modules/@dnd-kit/utilities": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.1.tgz",
- "integrity": "sha512-OOXqISfvBw/1REtkSK2N3Fi2EQiLMlWUlqnOK/UpOISqBZPWpE6TqL+jcPtMOkE8TqYGiURvRdPSI9hltNUjEA==",
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz",
+ "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==",
"dependencies": {
"tslib": "^2.0.0"
},
@@ -1778,13 +1718,9 @@
}
},
"node_modules/@editorjs/editorjs": {
- "version": "2.24.3",
- "license": "Apache-2.0",
- "dependencies": {
- "codex-notifier": "^1.1.2",
- "codex-tooltip": "^1.0.5",
- "nanoid": "^3.1.22"
- }
+ "version": "2.30.7",
+ "resolved": "https://registry.npmjs.org/@editorjs/editorjs/-/editorjs-2.30.7.tgz",
+ "integrity": "sha512-FfdeUqrgcKWC+Cy2GW6Dxup6s2TaRKokR4FL+HKXshu6h9Y//rrx4SQkURgkZOCSbV77t9btbmAXdFXWGB+diw=="
},
"node_modules/@editorjs/embed": {
"version": "2.5.3",
@@ -1796,10 +1732,6 @@
"version": "2.6.2",
"license": "MIT"
},
- "node_modules/@editorjs/image": {
- "version": "2.6.2",
- "license": "MIT"
- },
"node_modules/@editorjs/list": {
"version": "1.7.0",
"license": "MIT"
@@ -1882,17 +1814,6 @@
"version": "0.8.0",
"license": "MIT"
},
- "node_modules/@emotion/is-prop-valid": {
- "version": "0.7.3",
- "license": "MIT",
- "dependencies": {
- "@emotion/memoize": "0.7.1"
- }
- },
- "node_modules/@emotion/memoize": {
- "version": "0.7.1",
- "license": "MIT"
- },
"node_modules/@emotion/react": {
"version": "11.10.6",
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.6.tgz",
@@ -2110,11 +2031,11 @@
}
},
"node_modules/@floating-ui/react-dom": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz",
- "integrity": "sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz",
+ "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==",
"dependencies": {
- "@floating-ui/dom": "^1.5.1"
+ "@floating-ui/dom": "^1.0.0"
},
"peerDependencies": {
"react": ">=16.8.0",
@@ -2543,56 +2464,23 @@
}
},
"node_modules/@graphql-codegen/add": {
- "version": "3.1.1",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@graphql-codegen/plugin-helpers": "^2.3.2",
- "tslib": "~2.3.0"
- },
- "peerDependencies": {
- "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/@graphql-codegen/add/node_modules/@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/add/-/add-3.2.3.tgz",
+ "integrity": "sha512-sQOnWpMko4JLeykwyjFTxnhqjd/3NOG2OyMuvK76Wnnwh8DRrNf2VEs2kmSvLl7MndMlOj7Kh5U154dVcvhmKQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-tools/utils": "^8.5.2",
- "change-case-all": "1.0.14",
- "common-tags": "1.8.2",
- "import-from": "4.0.0",
- "lodash": "~4.17.0",
- "tslib": "~2.3.0"
+ "@graphql-codegen/plugin-helpers": "^3.1.1",
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
- "node_modules/@graphql-codegen/add/node_modules/@graphql-tools/utils": {
- "version": "8.6.1",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tslib": "~2.3.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/@graphql-codegen/add/node_modules/common-tags": {
- "version": "1.8.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
- }
- },
"node_modules/@graphql-codegen/add/node_modules/tslib": {
- "version": "2.3.1",
- "dev": true,
- "license": "0BSD"
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
+ "dev": true
},
"node_modules/@graphql-codegen/cli": {
"version": "2.16.5",
@@ -2646,36 +2534,6 @@
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
- "node_modules/@graphql-codegen/cli/node_modules/@graphql-codegen/plugin-helpers": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz",
- "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==",
- "dev": true,
- "dependencies": {
- "@graphql-tools/utils": "^9.0.0",
- "change-case-all": "1.0.15",
- "common-tags": "1.8.2",
- "import-from": "4.0.0",
- "lodash": "~4.17.0",
- "tslib": "~2.4.0"
- },
- "peerDependencies": {
- "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/@graphql-codegen/cli/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-codegen/cli/node_modules/chalk": {
"version": "4.1.2",
"dev": true,
@@ -2691,33 +2549,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/@graphql-codegen/cli/node_modules/change-case-all": {
- "version": "1.0.15",
- "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz",
- "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==",
- "dev": true,
- "dependencies": {
- "change-case": "^4.1.2",
- "is-lower-case": "^2.0.2",
- "is-upper-case": "^2.0.2",
- "lower-case": "^2.0.2",
- "lower-case-first": "^2.0.2",
- "sponge-case": "^1.0.1",
- "swap-case": "^2.0.2",
- "title-case": "^3.0.3",
- "upper-case": "^2.0.2",
- "upper-case-first": "^2.0.2"
- }
- },
- "node_modules/@graphql-codegen/cli/node_modules/common-tags": {
- "version": "1.8.2",
- "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
- "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
- "dev": true,
- "engines": {
- "node": ">=4.0.0"
- }
- },
"node_modules/@graphql-codegen/cli/node_modules/has-flag": {
"version": "4.0.0",
"dev": true,
@@ -2819,14 +2650,6 @@
"node": ">=12"
}
},
- "node_modules/@graphql-codegen/cli/node_modules/yargs-parser": {
- "version": "20.2.9",
- "dev": true,
- "license": "ISC",
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/@graphql-codegen/core": {
"version": "2.6.8",
"resolved": "https://registry.npmjs.org/@graphql-codegen/core/-/core-2.6.8.tgz",
@@ -2842,63 +2665,6 @@
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
- "node_modules/@graphql-codegen/core/node_modules/@graphql-codegen/plugin-helpers": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz",
- "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==",
- "dev": true,
- "dependencies": {
- "@graphql-tools/utils": "^9.0.0",
- "change-case-all": "1.0.15",
- "common-tags": "1.8.2",
- "import-from": "4.0.0",
- "lodash": "~4.17.0",
- "tslib": "~2.4.0"
- },
- "peerDependencies": {
- "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/@graphql-codegen/core/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
- "node_modules/@graphql-codegen/core/node_modules/change-case-all": {
- "version": "1.0.15",
- "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz",
- "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==",
- "dev": true,
- "dependencies": {
- "change-case": "^4.1.2",
- "is-lower-case": "^2.0.2",
- "is-upper-case": "^2.0.2",
- "lower-case": "^2.0.2",
- "lower-case-first": "^2.0.2",
- "sponge-case": "^1.0.1",
- "swap-case": "^2.0.2",
- "title-case": "^3.0.3",
- "upper-case": "^2.0.2",
- "upper-case-first": "^2.0.2"
- }
- },
- "node_modules/@graphql-codegen/core/node_modules/common-tags": {
- "version": "1.8.2",
- "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
- "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
- "dev": true,
- "engines": {
- "node": ">=4.0.0"
- }
- },
"node_modules/@graphql-codegen/core/node_modules/tslib": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
@@ -2906,95 +2672,73 @@
"dev": true
},
"node_modules/@graphql-codegen/fragment-matcher": {
- "version": "3.1.0",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/fragment-matcher/-/fragment-matcher-3.3.3.tgz",
+ "integrity": "sha512-lZjarTYQ+w0/TYyoKNFHgIUBI6//rxjo4CwNmOmqGQA0LL+p2nh+/ICJKMFuejPFdK9LI84Y+EEovEFTcDPC+Q==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-codegen/plugin-helpers": "^2.1.0",
- "tslib": "~2.3.0"
+ "@graphql-codegen/plugin-helpers": "^3.1.1",
+ "tslib": "~2.4.0"
},
"peerDependencies": {
- "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
+ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
"node_modules/@graphql-codegen/fragment-matcher/node_modules/tslib": {
- "version": "2.3.1",
- "dev": true,
- "license": "0BSD"
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
+ "dev": true
},
"node_modules/@graphql-codegen/import-types-preset": {
- "version": "2.1.12",
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/import-types-preset/-/import-types-preset-2.2.6.tgz",
+ "integrity": "sha512-Lo2ITOln3UVdyyEPiijj8bVhVg0Ghp/JzHXA2LXxrJVCRbXizQhVC2vjiaWTjMskPt9Zub0yIoce4+RrbsXKcg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-codegen/add": "^3.1.1",
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-codegen/visitor-plugin-common": "2.7.1",
- "tslib": "~2.3.0"
+ "@graphql-codegen/add": "^3.2.1",
+ "@graphql-codegen/plugin-helpers": "^2.7.2",
+ "@graphql-codegen/visitor-plugin-common": "2.13.1",
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
"node_modules/@graphql-codegen/import-types-preset/node_modules/@graphql-codegen/plugin-helpers": {
- "version": "2.4.1",
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.2.tgz",
+ "integrity": "sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-tools/utils": "^8.5.2",
+ "@graphql-tools/utils": "^8.8.0",
"change-case-all": "1.0.14",
"common-tags": "1.8.2",
"import-from": "4.0.0",
"lodash": "~4.17.0",
- "tslib": "~2.3.0"
- },
- "peerDependencies": {
- "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/@graphql-codegen/import-types-preset/node_modules/@graphql-codegen/visitor-plugin-common": {
- "version": "2.7.1",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-tools/optimize": "^1.0.1",
- "@graphql-tools/relay-operation-optimizer": "^6.3.7",
- "@graphql-tools/utils": "^8.3.0",
- "auto-bind": "~4.0.0",
- "change-case-all": "1.0.14",
- "dependency-graph": "^0.11.0",
- "graphql-tag": "^2.11.0",
- "parse-filepath": "^1.0.2",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
"node_modules/@graphql-codegen/import-types-preset/node_modules/@graphql-tools/utils": {
- "version": "8.6.1",
+ "version": "8.13.1",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz",
+ "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "tslib": "~2.3.0"
+ "tslib": "^2.4.0"
},
"peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/@graphql-codegen/import-types-preset/node_modules/common-tags": {
- "version": "1.8.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
+ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
"node_modules/@graphql-codegen/import-types-preset/node_modules/tslib": {
- "version": "2.3.1",
- "dev": true,
- "license": "0BSD"
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
+ "dev": true
},
"node_modules/@graphql-codegen/introspection": {
"version": "2.1.1",
@@ -3035,228 +2779,211 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
- "node_modules/@graphql-codegen/introspection/node_modules/common-tags": {
- "version": "1.8.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
- }
- },
"node_modules/@graphql-codegen/introspection/node_modules/tslib": {
"version": "2.3.1",
"dev": true,
"license": "0BSD"
},
"node_modules/@graphql-codegen/plugin-helpers": {
- "version": "2.1.0",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz",
+ "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-tools/utils": "^8.1.1",
- "change-case-all": "1.0.14",
- "common-tags": "1.8.0",
+ "@graphql-tools/utils": "^9.0.0",
+ "change-case-all": "1.0.15",
+ "common-tags": "1.8.2",
"import-from": "4.0.0",
"lodash": "~4.17.0",
- "tslib": "~2.3.0"
- },
- "peerDependencies": {
- "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0"
- }
- },
- "node_modules/@graphql-codegen/plugin-helpers/node_modules/tslib": {
- "version": "2.3.1",
- "dev": true,
- "license": "0BSD"
- },
- "node_modules/@graphql-codegen/schema-ast": {
- "version": "2.4.1",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@graphql-codegen/plugin-helpers": "^2.3.2",
- "@graphql-tools/utils": "^8.1.1",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
- "node_modules/@graphql-codegen/schema-ast/node_modules/@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
+ "node_modules/@graphql-codegen/plugin-helpers/node_modules/change-case-all": {
+ "version": "1.0.15",
+ "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz",
+ "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-tools/utils": "^8.5.2",
- "change-case-all": "1.0.14",
- "common-tags": "1.8.2",
- "import-from": "4.0.0",
- "lodash": "~4.17.0",
- "tslib": "~2.3.0"
- },
- "peerDependencies": {
- "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
+ "change-case": "^4.1.2",
+ "is-lower-case": "^2.0.2",
+ "is-upper-case": "^2.0.2",
+ "lower-case": "^2.0.2",
+ "lower-case-first": "^2.0.2",
+ "sponge-case": "^1.0.1",
+ "swap-case": "^2.0.2",
+ "title-case": "^3.0.3",
+ "upper-case": "^2.0.2",
+ "upper-case-first": "^2.0.2"
}
},
- "node_modules/@graphql-codegen/schema-ast/node_modules/@graphql-codegen/plugin-helpers/node_modules/@graphql-tools/utils": {
- "version": "8.6.1",
+ "node_modules/@graphql-codegen/plugin-helpers/node_modules/tslib": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
+ "dev": true
+ },
+ "node_modules/@graphql-codegen/schema-ast": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/schema-ast/-/schema-ast-2.6.1.tgz",
+ "integrity": "sha512-5TNW3b1IHJjCh07D2yQNGDQzUpUl2AD+GVe1Dzjqyx/d2Fn0TPMxLsHsKPS4Plg4saO8FK/QO70wLsP7fdbQ1w==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "tslib": "~2.3.0"
+ "@graphql-codegen/plugin-helpers": "^3.1.2",
+ "@graphql-tools/utils": "^9.0.0",
+ "tslib": "~2.4.0"
},
"peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/@graphql-codegen/schema-ast/node_modules/common-tags": {
- "version": "1.8.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
+ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
"node_modules/@graphql-codegen/schema-ast/node_modules/tslib": {
- "version": "2.3.1",
- "dev": true,
- "license": "0BSD"
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
+ "dev": true
},
"node_modules/@graphql-codegen/typescript": {
- "version": "2.4.3",
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-2.8.8.tgz",
+ "integrity": "sha512-A0oUi3Oy6+DormOlrTC4orxT9OBZkIglhbJBcDmk34jAKKUgesukXRd4yOhmTrnbchpXz2T8IAOFB3FWIaK4Rw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-codegen/schema-ast": "^2.4.1",
- "@graphql-codegen/visitor-plugin-common": "2.6.0",
+ "@graphql-codegen/plugin-helpers": "^3.1.2",
+ "@graphql-codegen/schema-ast": "^2.6.1",
+ "@graphql-codegen/visitor-plugin-common": "2.13.8",
"auto-bind": "~4.0.0",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
"node_modules/@graphql-codegen/typescript-apollo-client-helpers": {
- "version": "2.1.10",
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-apollo-client-helpers/-/typescript-apollo-client-helpers-2.2.6.tgz",
+ "integrity": "sha512-WEWtjg2D/Clmep7fflKmt6o70rZj/Mqf4ywIO5jF/PI91OHpKhLFM2aWm1ythkqALwQ6wJIFlAjdYqz/EOVYdQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-codegen/visitor-plugin-common": "2.6.0",
+ "@graphql-codegen/plugin-helpers": "^2.7.2",
+ "@graphql-codegen/visitor-plugin-common": "2.13.1",
"auto-bind": "~4.0.0",
"change-case-all": "1.0.14",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
"node_modules/@graphql-codegen/typescript-apollo-client-helpers/node_modules/@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.2.tgz",
+ "integrity": "sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-tools/utils": "^8.5.2",
+ "@graphql-tools/utils": "^8.8.0",
"change-case-all": "1.0.14",
"common-tags": "1.8.2",
"import-from": "4.0.0",
"lodash": "~4.17.0",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
"node_modules/@graphql-codegen/typescript-apollo-client-helpers/node_modules/@graphql-tools/utils": {
- "version": "8.6.1",
+ "version": "8.13.1",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz",
+ "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "tslib": "~2.3.0"
+ "tslib": "^2.4.0"
},
"peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/@graphql-codegen/typescript-apollo-client-helpers/node_modules/common-tags": {
- "version": "1.8.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
+ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
"node_modules/@graphql-codegen/typescript-apollo-client-helpers/node_modules/tslib": {
- "version": "2.3.1",
- "dev": true,
- "license": "0BSD"
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
+ "dev": true
},
"node_modules/@graphql-codegen/typescript-operations": {
- "version": "2.2.4",
+ "version": "2.5.13",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-operations/-/typescript-operations-2.5.13.tgz",
+ "integrity": "sha512-3vfR6Rx6iZU0JRt29GBkFlrSNTM6t+MSLF86ChvL4d/Jfo/JYAGuB3zNzPhirHYzJPCvLOAx2gy9ID1ltrpYiw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-codegen/typescript": "^2.4.3",
- "@graphql-codegen/visitor-plugin-common": "2.6.0",
+ "@graphql-codegen/plugin-helpers": "^3.1.2",
+ "@graphql-codegen/typescript": "^2.8.8",
+ "@graphql-codegen/visitor-plugin-common": "2.13.8",
"auto-bind": "~4.0.0",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
- "node_modules/@graphql-codegen/typescript-operations/node_modules/@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
+ "node_modules/@graphql-codegen/typescript-operations/node_modules/@graphql-codegen/visitor-plugin-common": {
+ "version": "2.13.8",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.13.8.tgz",
+ "integrity": "sha512-IQWu99YV4wt8hGxIbBQPtqRuaWZhkQRG2IZKbMoSvh0vGeWb3dB0n0hSgKaOOxDY+tljtOf9MTcUYvJslQucMQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-tools/utils": "^8.5.2",
- "change-case-all": "1.0.14",
- "common-tags": "1.8.2",
- "import-from": "4.0.0",
- "lodash": "~4.17.0",
- "tslib": "~2.3.0"
+ "@graphql-codegen/plugin-helpers": "^3.1.2",
+ "@graphql-tools/optimize": "^1.3.0",
+ "@graphql-tools/relay-operation-optimizer": "^6.5.0",
+ "@graphql-tools/utils": "^9.0.0",
+ "auto-bind": "~4.0.0",
+ "change-case-all": "1.0.15",
+ "dependency-graph": "^0.11.0",
+ "graphql-tag": "^2.11.0",
+ "parse-filepath": "^1.0.2",
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
- "node_modules/@graphql-codegen/typescript-operations/node_modules/@graphql-tools/utils": {
- "version": "8.6.1",
+ "node_modules/@graphql-codegen/typescript-operations/node_modules/change-case-all": {
+ "version": "1.0.15",
+ "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz",
+ "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "tslib": "~2.3.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/@graphql-codegen/typescript-operations/node_modules/common-tags": {
- "version": "1.8.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
+ "change-case": "^4.1.2",
+ "is-lower-case": "^2.0.2",
+ "is-upper-case": "^2.0.2",
+ "lower-case": "^2.0.2",
+ "lower-case-first": "^2.0.2",
+ "sponge-case": "^1.0.1",
+ "swap-case": "^2.0.2",
+ "title-case": "^3.0.3",
+ "upper-case": "^2.0.2",
+ "upper-case-first": "^2.0.2"
}
},
"node_modules/@graphql-codegen/typescript-operations/node_modules/tslib": {
- "version": "2.3.1",
- "dev": true,
- "license": "0BSD"
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
+ "dev": true
},
"node_modules/@graphql-codegen/typescript-react-apollo": {
- "version": "3.2.5",
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-react-apollo/-/typescript-react-apollo-3.3.7.tgz",
+ "integrity": "sha512-9DUiGE8rcwwEkf/S1kpBT/Py/UUs9Qak14bOnTT1JHWs1MWhiDA7vml+A8opU7YFI1EVbSSaE5jjRv11WHoikQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-codegen/visitor-plugin-common": "2.6.0",
+ "@graphql-codegen/plugin-helpers": "^2.7.2",
+ "@graphql-codegen/visitor-plugin-common": "2.13.1",
"auto-bind": "~4.0.0",
"change-case-all": "1.0.14",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
@@ -3264,144 +2991,140 @@
}
},
"node_modules/@graphql-codegen/typescript-react-apollo/node_modules/@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.2.tgz",
+ "integrity": "sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-tools/utils": "^8.5.2",
+ "@graphql-tools/utils": "^8.8.0",
"change-case-all": "1.0.14",
"common-tags": "1.8.2",
"import-from": "4.0.0",
"lodash": "~4.17.0",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
"node_modules/@graphql-codegen/typescript-react-apollo/node_modules/@graphql-tools/utils": {
- "version": "8.6.1",
+ "version": "8.13.1",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz",
+ "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "tslib": "~2.3.0"
+ "tslib": "^2.4.0"
},
"peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/@graphql-codegen/typescript-react-apollo/node_modules/common-tags": {
- "version": "1.8.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
+ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
"node_modules/@graphql-codegen/typescript-react-apollo/node_modules/tslib": {
- "version": "2.3.1",
- "dev": true,
- "license": "0BSD"
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
+ "dev": true
},
- "node_modules/@graphql-codegen/typescript/node_modules/@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
+ "node_modules/@graphql-codegen/typescript/node_modules/@graphql-codegen/visitor-plugin-common": {
+ "version": "2.13.8",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.13.8.tgz",
+ "integrity": "sha512-IQWu99YV4wt8hGxIbBQPtqRuaWZhkQRG2IZKbMoSvh0vGeWb3dB0n0hSgKaOOxDY+tljtOf9MTcUYvJslQucMQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-tools/utils": "^8.5.2",
- "change-case-all": "1.0.14",
- "common-tags": "1.8.2",
- "import-from": "4.0.0",
- "lodash": "~4.17.0",
- "tslib": "~2.3.0"
+ "@graphql-codegen/plugin-helpers": "^3.1.2",
+ "@graphql-tools/optimize": "^1.3.0",
+ "@graphql-tools/relay-operation-optimizer": "^6.5.0",
+ "@graphql-tools/utils": "^9.0.0",
+ "auto-bind": "~4.0.0",
+ "change-case-all": "1.0.15",
+ "dependency-graph": "^0.11.0",
+ "graphql-tag": "^2.11.0",
+ "parse-filepath": "^1.0.2",
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
- "node_modules/@graphql-codegen/typescript/node_modules/@graphql-tools/utils": {
- "version": "8.6.1",
+ "node_modules/@graphql-codegen/typescript/node_modules/change-case-all": {
+ "version": "1.0.15",
+ "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz",
+ "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "tslib": "~2.3.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/@graphql-codegen/typescript/node_modules/common-tags": {
- "version": "1.8.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
+ "change-case": "^4.1.2",
+ "is-lower-case": "^2.0.2",
+ "is-upper-case": "^2.0.2",
+ "lower-case": "^2.0.2",
+ "lower-case-first": "^2.0.2",
+ "sponge-case": "^1.0.1",
+ "swap-case": "^2.0.2",
+ "title-case": "^3.0.3",
+ "upper-case": "^2.0.2",
+ "upper-case-first": "^2.0.2"
}
},
"node_modules/@graphql-codegen/typescript/node_modules/tslib": {
- "version": "2.3.1",
- "dev": true,
- "license": "0BSD"
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
+ "dev": true
},
"node_modules/@graphql-codegen/visitor-plugin-common": {
- "version": "2.6.0",
+ "version": "2.13.1",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.13.1.tgz",
+ "integrity": "sha512-mD9ufZhDGhyrSaWQGrU1Q1c5f01TeWtSWy/cDwXYjJcHIj1Y/DG2x0tOflEfCvh5WcnmHNIw4lzDsg1W7iFJEg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-tools/optimize": "^1.0.1",
- "@graphql-tools/relay-operation-optimizer": "^6.3.7",
- "@graphql-tools/utils": "^8.3.0",
+ "@graphql-codegen/plugin-helpers": "^2.7.2",
+ "@graphql-tools/optimize": "^1.3.0",
+ "@graphql-tools/relay-operation-optimizer": "^6.5.0",
+ "@graphql-tools/utils": "^8.8.0",
"auto-bind": "~4.0.0",
"change-case-all": "1.0.14",
"dependency-graph": "^0.11.0",
"graphql-tag": "^2.11.0",
"parse-filepath": "^1.0.2",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
"node_modules/@graphql-codegen/visitor-plugin-common/node_modules/@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.2.tgz",
+ "integrity": "sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-tools/utils": "^8.5.2",
+ "@graphql-tools/utils": "^8.8.0",
"change-case-all": "1.0.14",
"common-tags": "1.8.2",
"import-from": "4.0.0",
"lodash": "~4.17.0",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"peerDependencies": {
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
}
},
"node_modules/@graphql-codegen/visitor-plugin-common/node_modules/@graphql-tools/utils": {
- "version": "8.6.1",
+ "version": "8.13.1",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz",
+ "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "tslib": "~2.3.0"
+ "tslib": "^2.4.0"
},
"peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
- }
- },
- "node_modules/@graphql-codegen/visitor-plugin-common/node_modules/common-tags": {
- "version": "1.8.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
+ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
"node_modules/@graphql-codegen/visitor-plugin-common/node_modules/tslib": {
- "version": "2.3.1",
- "dev": true,
- "license": "0BSD"
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
+ "dev": true
},
"node_modules/@graphql-tools/apollo-engine-loader": {
"version": "7.3.26",
@@ -3418,19 +3141,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/events": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz",
@@ -3484,19 +3194,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/batch-execute/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/code-file-loader": {
"version": "7.3.23",
"resolved": "https://registry.npmjs.org/@graphql-tools/code-file-loader/-/code-file-loader-7.3.23.tgz",
@@ -3513,19 +3210,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/code-file-loader/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/delegate": {
"version": "9.0.35",
"resolved": "https://registry.npmjs.org/@graphql-tools/delegate/-/delegate-9.0.35.tgz",
@@ -3544,19 +3228,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/delegate/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/executor": {
"version": "0.0.20",
"resolved": "https://registry.npmjs.org/@graphql-tools/executor/-/executor-0.0.20.tgz",
@@ -3591,19 +3262,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/executor-graphql-ws/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/executor-graphql-ws/node_modules/ws": {
"version": "8.13.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
@@ -3644,19 +3302,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/executor-http/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/events": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz",
@@ -3711,19 +3356,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/executor-legacy-ws/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/executor-legacy-ws/node_modules/ws": {
"version": "8.13.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
@@ -3745,19 +3377,6 @@
}
}
},
- "node_modules/@graphql-tools/executor/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/git-loader": {
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/@graphql-tools/git-loader/-/git-loader-7.3.0.tgz",
@@ -3775,19 +3394,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/git-loader/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/github-loader": {
"version": "7.3.28",
"resolved": "https://registry.npmjs.org/@graphql-tools/github-loader/-/github-loader-7.3.28.tgz",
@@ -3806,19 +3412,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/github-loader/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/github-loader/node_modules/@whatwg-node/events": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz",
@@ -3873,19 +3466,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/graphql-file-loader/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/graphql-tag-pluck": {
"version": "7.5.2",
"resolved": "https://registry.npmjs.org/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-7.5.2.tgz",
@@ -3903,19 +3483,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/graphql-tag-pluck/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/import": {
"version": "6.7.18",
"resolved": "https://registry.npmjs.org/@graphql-tools/import/-/import-6.7.18.tgz",
@@ -3930,19 +3497,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/import/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/json-file-loader": {
"version": "7.4.18",
"resolved": "https://registry.npmjs.org/@graphql-tools/json-file-loader/-/json-file-loader-7.4.18.tgz",
@@ -3958,19 +3512,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/json-file-loader/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/load": {
"version": "7.8.14",
"resolved": "https://registry.npmjs.org/@graphql-tools/load/-/load-7.8.14.tgz",
@@ -3986,19 +3527,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/load/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/load/node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -4027,35 +3555,18 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/merge/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
+ "node_modules/@graphql-tools/optimize": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/optimize/-/optimize-1.4.0.tgz",
+ "integrity": "sha512-dJs/2XvZp+wgHH8T5J2TqptT9/6uVzIYvA6uFACha+ufvdMBedkfR4b4GbT8jAKLRARiqRTxy3dctnwkTM2tdw==",
"dev": true,
"dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
"tslib": "^2.4.0"
},
"peerDependencies": {
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/optimize": {
- "version": "1.0.1",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tslib": "~2.0.1"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0"
- }
- },
- "node_modules/@graphql-tools/optimize/node_modules/tslib": {
- "version": "2.0.3",
- "dev": true,
- "license": "0BSD"
- },
"node_modules/@graphql-tools/prisma-loader": {
"version": "7.2.72",
"resolved": "https://registry.npmjs.org/@graphql-tools/prisma-loader/-/prisma-loader-7.2.72.tgz",
@@ -4085,19 +3596,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/prisma-loader/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/prisma-loader/node_modules/@whatwg-node/events": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz",
@@ -4255,23 +3753,19 @@
"dev": true
},
"node_modules/@graphql-tools/relay-operation-optimizer": {
- "version": "6.3.7",
+ "version": "6.5.18",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-6.5.18.tgz",
+ "integrity": "sha512-mc5VPyTeV+LwiM+DNvoDQfPqwQYhPV/cl5jOBjTgSniyaq8/86aODfMkrE2OduhQ5E00hqrkuL2Fdrgk0w1QJg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "@graphql-tools/utils": "^8.1.1",
- "relay-compiler": "11.0.2",
- "tslib": "~2.3.0"
+ "@ardatan/relay-compiler": "12.0.0",
+ "@graphql-tools/utils": "^9.2.1",
+ "tslib": "^2.4.0"
},
"peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0"
+ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/relay-operation-optimizer/node_modules/tslib": {
- "version": "2.3.1",
- "dev": true,
- "license": "0BSD"
- },
"node_modules/@graphql-tools/schema": {
"version": "9.0.19",
"resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.19.tgz",
@@ -4287,19 +3781,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/schema/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/url-loader": {
"version": "7.17.18",
"resolved": "https://registry.npmjs.org/@graphql-tools/url-loader/-/url-loader-7.17.18.tgz",
@@ -4324,19 +3805,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/url-loader/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/events": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz",
@@ -4397,21 +3865,18 @@
}
},
"node_modules/@graphql-tools/utils": {
- "version": "8.1.2",
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
+ "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "tslib": "~2.3.0"
+ "@graphql-typed-document-node/core": "^3.1.1",
+ "tslib": "^2.4.0"
},
"peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0"
+ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/utils/node_modules/tslib": {
- "version": "2.3.1",
- "dev": true,
- "license": "0BSD"
- },
"node_modules/@graphql-tools/wrap": {
"version": "9.4.2",
"resolved": "https://registry.npmjs.org/@graphql-tools/wrap/-/wrap-9.4.2.tgz",
@@ -4428,19 +3893,6 @@
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@graphql-tools/wrap/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/@graphql-typed-document-node/core": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz",
@@ -4449,19 +3901,6 @@
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
}
},
- "node_modules/@hapi/hoek": {
- "version": "9.1.1",
- "dev": true,
- "license": "BSD-3-Clause"
- },
- "node_modules/@hapi/topo": {
- "version": "5.0.0",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@hapi/hoek": "^9.0.0"
- }
- },
"node_modules/@hookform/resolvers": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.2.tgz",
@@ -4565,14 +4004,6 @@
"node": ">=8"
}
},
- "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": {
- "version": "4.0.0",
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/@istanbuljs/schema": {
"version": "0.1.3",
"license": "MIT",
@@ -4723,15 +4154,78 @@
}
},
"node_modules/@jest/create-cache-key-function": {
- "version": "27.5.1",
- "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz",
- "integrity": "sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==",
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz",
+ "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==",
"dev": true,
"dependencies": {
- "@jest/types": "^27.5.1"
+ "@jest/types": "^29.6.3"
},
"engines": {
- "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/create-cache-key-function/node_modules/@jest/types": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
+ "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/create-cache-key-function/node_modules/@types/yargs": {
+ "version": "17.0.33",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
+ "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@jest/create-cache-key-function/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@jest/create-cache-key-function/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/create-cache-key-function/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
}
},
"node_modules/@jest/environment": {
@@ -4862,6 +4356,18 @@
"node": ">=8"
}
},
+ "node_modules/@jest/schemas": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+ "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+ "dev": true,
+ "dependencies": {
+ "@sinclair/typebox": "^0.27.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
"node_modules/@jest/source-map": {
"version": "27.5.1",
"license": "MIT",
@@ -4999,8 +4505,8 @@
},
"node_modules/@jest/types": {
"version": "27.5.1",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
"@types/istanbul-lib-coverage": "^2.0.0",
"@types/istanbul-reports": "^3.0.0",
@@ -5014,8 +4520,8 @@
},
"node_modules/@jest/types/node_modules/chalk": {
"version": "4.1.2",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -5029,16 +4535,16 @@
},
"node_modules/@jest/types/node_modules/has-flag": {
"version": "4.0.0",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"engines": {
"node": ">=8"
}
},
"node_modules/@jest/types/node_modules/supports-color": {
"version": "7.2.0",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -5129,6 +4635,20 @@
"node": ">=8"
}
},
+ "node_modules/@manypkg/find-root/node_modules/fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
"node_modules/@manypkg/find-root/node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -5153,15 +4673,6 @@
"node": ">=8"
}
},
- "node_modules/@manypkg/find-root/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/@manypkg/get-packages": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz",
@@ -5182,6 +4693,20 @@
"integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==",
"dev": true
},
+ "node_modules/@manypkg/get-packages/node_modules/fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=6 <7 || >=8"
+ }
+ },
"node_modules/@material-ui/core": {
"version": "4.12.4",
"license": "MIT",
@@ -5241,7 +4766,9 @@
},
"node_modules/@material-ui/lab": {
"version": "4.0.0-alpha.61",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.61.tgz",
+ "integrity": "sha512-rSzm+XKiNUjKegj8bzt5+pygZeckNLOr+IjykH8sYdVk7dE9y2ZuUSofiMV2bJk3qU+JHwexmw+q0RyNZB9ugg==",
+ "deprecated": "Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5.",
"dependencies": {
"@babel/runtime": "^7.4.4",
"@material-ui/utils": "^4.11.3",
@@ -5388,6 +4915,7 @@
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
"dependencies": {
"@nodelib/fs.stat": "2.0.5",
"run-parallel": "^1.1.9"
@@ -5400,6 +4928,7 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
"engines": {
"node": ">= 8"
}
@@ -5408,6 +4937,7 @@
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
"dependencies": {
"@nodelib/fs.scandir": "2.1.5",
"fastq": "^1.6.0"
@@ -5416,46 +4946,6 @@
"node": ">= 8"
}
},
- "node_modules/@oozcitak/dom": {
- "version": "1.15.10",
- "license": "MIT",
- "dependencies": {
- "@oozcitak/infra": "1.0.8",
- "@oozcitak/url": "1.0.4",
- "@oozcitak/util": "8.3.8"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/@oozcitak/infra": {
- "version": "1.0.8",
- "license": "MIT",
- "dependencies": {
- "@oozcitak/util": "8.3.8"
- },
- "engines": {
- "node": ">=6.0"
- }
- },
- "node_modules/@oozcitak/url": {
- "version": "1.0.4",
- "license": "MIT",
- "dependencies": {
- "@oozcitak/infra": "1.0.8",
- "@oozcitak/util": "8.3.8"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/@oozcitak/util": {
- "version": "8.3.8",
- "license": "MIT",
- "engines": {
- "node": ">=8.0"
- }
- },
"node_modules/@opentelemetry/api": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz",
@@ -5525,49 +5015,45 @@
}
},
"node_modules/@playwright/test": {
- "version": "1.40.0",
- "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.40.0.tgz",
- "integrity": "sha512-PdW+kn4eV99iP5gxWNSDQCbhMaDVej+RXL5xr6t04nbKLCBwYtA046t7ofoczHOm8u6c+45hpDKQVZqtqwkeQg==",
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.0.tgz",
+ "integrity": "sha512-DMulbwQURa8rNIQrf94+jPJQ4FmOVdpE5ZppRNvWVjvhC+6sOeo28r8MgIpQRYouXRtt/FCCXU7zn20jnHR4Qw==",
"dev": true,
"dependencies": {
- "playwright": "1.40.0"
+ "playwright": "1.49.0"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
- "node": ">=16"
+ "node": ">=18"
}
},
"node_modules/@radix-ui/primitive": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz",
- "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==",
- "dependencies": {
- "@babel/runtime": "^7.13.10"
- }
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
+ "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA=="
},
"node_modules/@radix-ui/react-accordion": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.1.2.tgz",
- "integrity": "sha512-fDG7jcoNKVjSK6yfmuAs0EnPDro0WMXIhMtXdTBWqEioVW206ku+4Lw07e+13lUkFkpoEQ2PdeMIAGpdqEAmDg==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.0.tgz",
+ "integrity": "sha512-HJOzSX8dQqtsp/3jVxCU3CXEONF7/2jlGAB28oX8TTw1Dz8JYbEI1UcL8355PuLBE41/IRRMvCw7VkiK/jcUOQ==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-collapsible": "1.0.3",
- "@radix-ui/react-collection": "1.0.3",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-direction": "1.0.1",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-controllable-state": "1.0.1"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-collapsible": "1.1.0",
+ "@radix-ui/react-collection": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5579,18 +5065,17 @@
}
},
"node_modules/@radix-ui/react-arrow": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz",
- "integrity": "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz",
+ "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-primitive": "1.0.3"
+ "@radix-ui/react-primitive": "2.0.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5602,25 +5087,24 @@
}
},
"node_modules/@radix-ui/react-checkbox": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.0.4.tgz",
- "integrity": "sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.1.tgz",
+ "integrity": "sha512-0i/EKJ222Afa1FE0C6pNJxDq1itzcl3HChE9DwskA4th4KRse8ojx8a1nVcOjwJdbpDLcz7uol77yYnQNMHdKw==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-controllable-state": "1.0.1",
- "@radix-ui/react-use-previous": "1.0.1",
- "@radix-ui/react-use-size": "1.0.1"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-use-previous": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5632,25 +5116,24 @@
}
},
"node_modules/@radix-ui/react-collapsible": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.0.3.tgz",
- "integrity": "sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.0.tgz",
+ "integrity": "sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-controllable-state": "1.0.1",
- "@radix-ui/react-use-layout-effect": "1.0.1"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5662,21 +5145,20 @@
}
},
"node_modules/@radix-ui/react-collection": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz",
- "integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
+ "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-slot": "1.0.2"
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5688,15 +5170,12 @@
}
},
"node_modules/@radix-ui/react-compose-refs": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz",
- "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==",
- "dependencies": {
- "@babel/runtime": "^7.13.10"
- },
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
+ "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5705,15 +5184,12 @@
}
},
"node_modules/@radix-ui/react-context": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz",
- "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==",
- "dependencies": {
- "@babel/runtime": "^7.13.10"
- },
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
+ "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5722,31 +5198,30 @@
}
},
"node_modules/@radix-ui/react-dialog": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz",
- "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==",
- "dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-dismissable-layer": "1.0.5",
- "@radix-ui/react-focus-guards": "1.0.1",
- "@radix-ui/react-focus-scope": "1.0.4",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-portal": "1.0.4",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-slot": "1.0.2",
- "@radix-ui/react-use-controllable-state": "1.0.1",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz",
+ "integrity": "sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.0",
+ "@radix-ui/react-focus-guards": "1.1.0",
+ "@radix-ui/react-focus-scope": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-portal": "1.1.1",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
"aria-hidden": "^1.1.1",
- "react-remove-scroll": "2.5.5"
+ "react-remove-scroll": "2.5.7"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5758,15 +5233,12 @@
}
},
"node_modules/@radix-ui/react-direction": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz",
- "integrity": "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==",
- "dependencies": {
- "@babel/runtime": "^7.13.10"
- },
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz",
+ "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==",
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5775,22 +5247,21 @@
}
},
"node_modules/@radix-ui/react-dismissable-layer": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz",
- "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz",
+ "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1",
- "@radix-ui/react-use-escape-keydown": "1.0.3"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-escape-keydown": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5802,24 +5273,23 @@
}
},
"node_modules/@radix-ui/react-dropdown-menu": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz",
- "integrity": "sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz",
+ "integrity": "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-menu": "2.0.6",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-controllable-state": "1.0.1"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-menu": "2.1.1",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5831,15 +5301,12 @@
}
},
"node_modules/@radix-ui/react-focus-guards": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz",
- "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==",
- "dependencies": {
- "@babel/runtime": "^7.13.10"
- },
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz",
+ "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==",
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5848,20 +5315,19 @@
}
},
"node_modules/@radix-ui/react-focus-scope": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz",
- "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz",
+ "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1"
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5873,16 +5339,15 @@
}
},
"node_modules/@radix-ui/react-id": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz",
- "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
+ "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-use-layout-effect": "1.0.1"
+ "@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5891,35 +5356,34 @@
}
},
"node_modules/@radix-ui/react-menu": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.6.tgz",
- "integrity": "sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==",
- "dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-collection": "1.0.3",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-direction": "1.0.1",
- "@radix-ui/react-dismissable-layer": "1.0.5",
- "@radix-ui/react-focus-guards": "1.0.1",
- "@radix-ui/react-focus-scope": "1.0.4",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-popper": "1.1.3",
- "@radix-ui/react-portal": "1.0.4",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-roving-focus": "1.0.4",
- "@radix-ui/react-slot": "1.0.2",
- "@radix-ui/react-use-callback-ref": "1.0.1",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.1.tgz",
+ "integrity": "sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-collection": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.0",
+ "@radix-ui/react-focus-guards": "1.1.0",
+ "@radix-ui/react-focus-scope": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.0",
+ "@radix-ui/react-portal": "1.1.1",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-roving-focus": "1.1.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
"aria-hidden": "^1.1.1",
- "react-remove-scroll": "2.5.5"
+ "react-remove-scroll": "2.5.7"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5931,32 +5395,31 @@
}
},
"node_modules/@radix-ui/react-popover": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.7.tgz",
- "integrity": "sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==",
- "dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-dismissable-layer": "1.0.5",
- "@radix-ui/react-focus-guards": "1.0.1",
- "@radix-ui/react-focus-scope": "1.0.4",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-popper": "1.1.3",
- "@radix-ui/react-portal": "1.0.4",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-slot": "1.0.2",
- "@radix-ui/react-use-controllable-state": "1.0.1",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.1.tgz",
+ "integrity": "sha512-3y1A3isulwnWhvTTwmIreiB8CF4L+qRjZnK1wYLO7pplddzXKby/GnZ2M7OZY3qgnl6p9AodUIHRYGXNah8Y7g==",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.0",
+ "@radix-ui/react-focus-guards": "1.1.0",
+ "@radix-ui/react-focus-scope": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.0",
+ "@radix-ui/react-portal": "1.1.1",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
"aria-hidden": "^1.1.1",
- "react-remove-scroll": "2.5.5"
+ "react-remove-scroll": "2.5.7"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -5968,27 +5431,26 @@
}
},
"node_modules/@radix-ui/react-popper": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz",
- "integrity": "sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
+ "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
"@floating-ui/react-dom": "^2.0.0",
- "@radix-ui/react-arrow": "1.0.3",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1",
- "@radix-ui/react-use-layout-effect": "1.0.1",
- "@radix-ui/react-use-rect": "1.0.1",
- "@radix-ui/react-use-size": "1.0.1",
- "@radix-ui/rect": "1.0.1"
+ "@radix-ui/react-arrow": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0",
+ "@radix-ui/react-use-rect": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0",
+ "@radix-ui/rect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6000,18 +5462,18 @@
}
},
"node_modules/@radix-ui/react-portal": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz",
- "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz",
+ "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-primitive": "1.0.3"
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6023,19 +5485,18 @@
}
},
"node_modules/@radix-ui/react-presence": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz",
- "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz",
+ "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-use-layout-effect": "1.0.1"
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6047,18 +5508,17 @@
}
},
"node_modules/@radix-ui/react-primitive": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz",
- "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
+ "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-slot": "1.0.2"
+ "@radix-ui/react-slot": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6070,27 +5530,26 @@
}
},
"node_modules/@radix-ui/react-radio-group": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.1.3.tgz",
- "integrity": "sha512-x+yELayyefNeKeTx4fjK6j99Fs6c4qKm3aY38G3swQVTN6xMpsrbigC0uHs2L//g8q4qR7qOcww8430jJmi2ag==",
- "dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-direction": "1.0.1",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-roving-focus": "1.0.4",
- "@radix-ui/react-use-controllable-state": "1.0.1",
- "@radix-ui/react-use-previous": "1.0.1",
- "@radix-ui/react-use-size": "1.0.1"
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.2.0.tgz",
+ "integrity": "sha512-yv+oiLaicYMBpqgfpSPw6q+RyXlLdIpQWDHZbUKURxe+nEh53hFXPPlfhfQQtYkS5MMK/5IWIa76SksleQZSzw==",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-roving-focus": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-use-previous": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6102,26 +5561,25 @@
}
},
"node_modules/@radix-ui/react-roving-focus": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz",
- "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz",
+ "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-collection": "1.0.3",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-direction": "1.0.1",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1",
- "@radix-ui/react-use-controllable-state": "1.0.1"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-collection": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6133,16 +5591,15 @@
}
},
"node_modules/@radix-ui/react-slot": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
- "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+ "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-compose-refs": "1.0.1"
+ "@radix-ui/react-compose-refs": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6151,20 +5608,19 @@
}
},
"node_modules/@radix-ui/react-toggle": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.0.3.tgz",
- "integrity": "sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.0.tgz",
+ "integrity": "sha512-gwoxaKZ0oJ4vIgzsfESBuSgJNdc0rv12VhHgcqN0TEJmmZixXG/2XpsLK8kzNWYcnaoRIEEQc0bEi3dIvdUpjw==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-controllable-state": "1.0.1"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6176,29 +5632,28 @@
}
},
"node_modules/@radix-ui/react-tooltip": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz",
- "integrity": "sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==",
- "dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-dismissable-layer": "1.0.5",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-popper": "1.1.3",
- "@radix-ui/react-portal": "1.0.4",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-slot": "1.0.2",
- "@radix-ui/react-use-controllable-state": "1.0.1",
- "@radix-ui/react-visually-hidden": "1.0.3"
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz",
+ "integrity": "sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.0",
+ "@radix-ui/react-portal": "1.1.1",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-visually-hidden": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6210,15 +5665,12 @@
}
},
"node_modules/@radix-ui/react-use-callback-ref": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz",
- "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==",
- "dependencies": {
- "@babel/runtime": "^7.13.10"
- },
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6227,16 +5679,15 @@
}
},
"node_modules/@radix-ui/react-use-controllable-state": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz",
- "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
+ "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-use-callback-ref": "1.0.1"
+ "@radix-ui/react-use-callback-ref": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6245,16 +5696,15 @@
}
},
"node_modules/@radix-ui/react-use-escape-keydown": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz",
- "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
+ "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-use-callback-ref": "1.0.1"
+ "@radix-ui/react-use-callback-ref": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6263,15 +5713,12 @@
}
},
"node_modules/@radix-ui/react-use-layout-effect": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz",
- "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==",
- "dependencies": {
- "@babel/runtime": "^7.13.10"
- },
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6280,15 +5727,12 @@
}
},
"node_modules/@radix-ui/react-use-previous": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz",
- "integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==",
- "dependencies": {
- "@babel/runtime": "^7.13.10"
- },
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz",
+ "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==",
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6297,16 +5741,15 @@
}
},
"node_modules/@radix-ui/react-use-rect": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz",
- "integrity": "sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz",
+ "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/rect": "1.0.1"
+ "@radix-ui/rect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6315,16 +5758,15 @@
}
},
"node_modules/@radix-ui/react-use-size": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz",
- "integrity": "sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
+ "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-use-layout-effect": "1.0.1"
+ "@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6333,18 +5775,17 @@
}
},
"node_modules/@radix-ui/react-visually-hidden": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz",
- "integrity": "sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz",
+ "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-primitive": "1.0.3"
+ "@radix-ui/react-primitive": "2.0.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -6356,12 +5797,9 @@
}
},
"node_modules/@radix-ui/rect": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz",
- "integrity": "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==",
- "dependencies": {
- "@babel/runtime": "^7.13.10"
- }
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz",
+ "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg=="
},
"node_modules/@reach/auto-id": {
"version": "0.16.0",
@@ -6927,9 +6365,9 @@
},
"node_modules/@saleor/macaw-ui-next": {
"name": "@saleor/macaw-ui",
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-1.1.5.tgz",
- "integrity": "sha512-oCK5/n2KXnGthokSZQA5LKFK0sCe/DA3dJjjYHYVi/td7Hs+zUCvTsh3J+I19pKRI4IIHqieqK9DLLfmv+rpOg==",
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-1.1.15.tgz",
+ "integrity": "sha512-PsNs2gN9hqZhfVCFTaNiFw65p8sfvOb/PZSSIcPB05tg21y8Ze7OP4CJ9UcdYz6Lt0sDXorBYPsEHbT+3pVwYQ==",
"dependencies": {
"@dessert-box/react": "^0.4.0",
"@floating-ui/react-dom": "^2.0.2",
@@ -6944,11 +6382,11 @@
"@radix-ui/react-tooltip": "^1.0.6",
"@vanilla-extract/css-utils": "^0.1.3",
"@vanilla-extract/recipes": "^0.5.0",
- "downshift": "^7.6.0"
+ "downshift": "^9.0.8"
},
"engines": {
"node": "18 || 20",
- "pnpm": ">=8"
+ "pnpm": ">=9"
},
"peerDependencies": {
"@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0",
@@ -6958,25 +6396,35 @@
}
},
"node_modules/@saleor/macaw-ui-next/node_modules/compute-scroll-into-view": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-2.0.4.tgz",
- "integrity": "sha512-y/ZA3BGnxoM/QHHQ2Uy49CLtnWPbt4tTPpEEZiEmmiWBFKjej7nEyH8Ryz54jH0MLXflUYA3Er2zUxPSJu5R+g=="
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz",
+ "integrity": "sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg=="
},
"node_modules/@saleor/macaw-ui-next/node_modules/downshift": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/downshift/-/downshift-7.6.2.tgz",
- "integrity": "sha512-iOv+E1Hyt3JDdL9yYcOgW7nZ7GQ2Uz6YbggwXvKUSleetYhU2nXD482Rz6CzvM4lvI1At34BYruKAL4swRGxaA==",
+ "version": "9.0.8",
+ "resolved": "https://registry.npmjs.org/downshift/-/downshift-9.0.8.tgz",
+ "integrity": "sha512-59BWD7+hSUQIM1DeNPLirNNnZIO9qMdIK5GQ/Uo8q34gT4B78RBlb9dhzgnh0HfQTJj4T/JKYD8KoLAlMWnTsA==",
"dependencies": {
- "@babel/runtime": "^7.14.8",
- "compute-scroll-into-view": "^2.0.4",
- "prop-types": "^15.7.2",
- "react-is": "^17.0.2",
- "tslib": "^2.3.0"
+ "@babel/runtime": "^7.24.5",
+ "compute-scroll-into-view": "^3.1.0",
+ "prop-types": "^15.8.1",
+ "react-is": "18.2.0",
+ "tslib": "^2.6.2"
},
"peerDependencies": {
"react": ">=16.12.0"
}
},
+ "node_modules/@saleor/macaw-ui-next/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+ },
+ "node_modules/@saleor/macaw-ui-next/node_modules/tslib": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
+ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
+ },
"node_modules/@saleor/sdk": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@saleor/sdk/-/sdk-0.6.0.tgz",
@@ -6994,85 +6442,103 @@
"react": "^16.8.0 || ^17.0.0"
}
},
+ "node_modules/@sentry-internal/browser-utils": {
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.21.0.tgz",
+ "integrity": "sha512-qN95Yuc9csDW6H4LEET/qkAA87WIbYIq3x2EY8YzfmjyPvjgfGoOD3wz2ROiitKNgB291rCtnJiSMKE0GinSRg==",
+ "dependencies": {
+ "@sentry/core": "8.21.0",
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0"
+ },
+ "engines": {
+ "node": ">=14.18"
+ }
+ },
"node_modules/@sentry-internal/feedback": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.85.0.tgz",
- "integrity": "sha512-MlbIN+N8CWFJBjbqMmARe4+UPo9QRhRar0YoOfmNA2Xqk/EwXcjHWkealosHznXH7tqVbjB25QJpHtDystft/Q==",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.21.0.tgz",
+ "integrity": "sha512-vAArMtoYvsBbCvB2KGB4v6uzmBxHCimSkBtfq6CuAv0+mdPGFbhPd+pzKcMovXZD1tji4lY89DbFxRsuliskWw==",
"dependencies": {
- "@sentry/core": "7.85.0",
- "@sentry/types": "7.85.0",
- "@sentry/utils": "7.85.0"
+ "@sentry/core": "8.21.0",
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0"
},
"engines": {
- "node": ">=12"
+ "node": ">=14.18"
}
},
- "node_modules/@sentry-internal/tracing": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.85.0.tgz",
- "integrity": "sha512-p3YMUwkPCy2su9cm/3+7QYR4RiMI0+07DU1BZtht9NLTzY2O87/yvUbn1v2yHR3vJQTy/+7N0ud9/mPBFznRQQ==",
+ "node_modules/@sentry-internal/replay": {
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.21.0.tgz",
+ "integrity": "sha512-di2rLyya4yPA+5LybX5+52HBrW4D8e22yKpERu7cnwWi3+ZAjoDf3M/CmKM9kCPFfSE/tHWlm+CYDl2WhslFLA==",
"dependencies": {
- "@sentry/core": "7.85.0",
- "@sentry/types": "7.85.0",
- "@sentry/utils": "7.85.0"
+ "@sentry-internal/browser-utils": "8.21.0",
+ "@sentry/core": "8.21.0",
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=14.18"
+ }
+ },
+ "node_modules/@sentry-internal/replay-canvas": {
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.21.0.tgz",
+ "integrity": "sha512-vm0ZLY5DpjjFodKDhD79ZiLLQaHnA6XG5gTT5HcWhMwAykYNVfXRaNC0dq3ydOw0oDgPnOAnL/RuOXCgYahVdQ==",
+ "dependencies": {
+ "@sentry-internal/replay": "8.21.0",
+ "@sentry/core": "8.21.0",
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0"
+ },
+ "engines": {
+ "node": ">=14.18"
}
},
"node_modules/@sentry/babel-plugin-component-annotate": {
- "version": "2.15.0",
- "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.15.0.tgz",
- "integrity": "sha512-4AaRN2E1iqOPlceDE5ae4thnq717reEQkqOslSWpJf7FmJ+oDrp2bWQhO82xcW8ZBBMbtkOGw2wmrScq5TnMxw==",
+ "version": "2.21.1",
+ "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.21.1.tgz",
+ "integrity": "sha512-u1L8gZ4He0WdyiIsohYkA/YOY1b6Oa5yIMRtfZZ9U5TiWYLgOfMWyb88X0GotZeghSbgxrse/yI4WeHnhAUQDQ==",
"engines": {
"node": ">= 14"
}
},
"node_modules/@sentry/browser": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.85.0.tgz",
- "integrity": "sha512-x4sH7vTQnZQgy1U7NuN8XwhleAw7YMQitccHeC5m+kpIKGUO7w4Mdvu8rD3dnjmVmZvASpnwocAxy57/vCU6Ww==",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.21.0.tgz",
+ "integrity": "sha512-pYlnQQbkDZfULT8UjGOWY8U+z+8La4dvTtetWYW3SI/colFR3YuZyJvGAJQkwKJpxi4VxGAxQglqj+HgsQua1A==",
"dependencies": {
- "@sentry-internal/feedback": "7.85.0",
- "@sentry-internal/tracing": "7.85.0",
- "@sentry/core": "7.85.0",
- "@sentry/replay": "7.85.0",
- "@sentry/types": "7.85.0",
- "@sentry/utils": "7.85.0"
+ "@sentry-internal/browser-utils": "8.21.0",
+ "@sentry-internal/feedback": "8.21.0",
+ "@sentry-internal/replay": "8.21.0",
+ "@sentry-internal/replay-canvas": "8.21.0",
+ "@sentry/core": "8.21.0",
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=14.18"
}
},
"node_modules/@sentry/bundler-plugin-core": {
- "version": "2.15.0",
- "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.15.0.tgz",
- "integrity": "sha512-K6tEmo6ilUdR5uEQZ4P1uaXCvRoAeq5JsJAg7lRv0JSG5XG67jhoHu+mrpiDMB93FxbTgCQkPCT87Z0Bmqpmew==",
+ "version": "2.21.1",
+ "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.21.1.tgz",
+ "integrity": "sha512-F8FdL/bS8cy1SY1Gw0Mfo3ROTqlrq9Lvt5QGvhXi22dpVcDkWmoTWE2k+sMEnXOa8SdThMc/gyC8lMwHGd3kFQ==",
"dependencies": {
"@babel/core": "^7.18.5",
- "@sentry/babel-plugin-component-annotate": "2.15.0",
+ "@sentry/babel-plugin-component-annotate": "2.21.1",
"@sentry/cli": "^2.22.3",
"dotenv": "^16.3.1",
"find-up": "^5.0.0",
"glob": "^9.3.2",
- "magic-string": "0.27.0",
+ "magic-string": "0.30.8",
"unplugin": "1.0.1"
},
"engines": {
"node": ">= 14"
}
},
- "node_modules/@sentry/bundler-plugin-core/node_modules/acorn": {
- "version": "8.11.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
- "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
"node_modules/@sentry/bundler-plugin-core/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
@@ -7092,21 +6558,6 @@
"url": "https://dotenvx.com"
}
},
- "node_modules/@sentry/bundler-plugin-core/node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/@sentry/bundler-plugin-core/node_modules/glob": {
"version": "9.3.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz",
@@ -7124,26 +6575,12 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/@sentry/bundler-plugin-core/node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/@sentry/bundler-plugin-core/node_modules/magic-string": {
- "version": "0.27.0",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz",
- "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==",
+ "version": "0.30.8",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
+ "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
"dependencies": {
- "@jridgewell/sourcemap-codec": "^1.4.13"
+ "@jridgewell/sourcemap-codec": "^1.4.15"
},
"engines": {
"node": ">=12"
@@ -7163,65 +6600,11 @@
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/@sentry/bundler-plugin-core/node_modules/minipass": {
- "version": "4.2.8",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
- "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@sentry/bundler-plugin-core/node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@sentry/bundler-plugin-core/node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@sentry/bundler-plugin-core/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@sentry/bundler-plugin-core/node_modules/unplugin": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.0.1.tgz",
- "integrity": "sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==",
- "dependencies": {
- "acorn": "^8.8.1",
- "chokidar": "^3.5.3",
- "webpack-sources": "^3.2.3",
- "webpack-virtual-modules": "^0.5.0"
- }
- },
"node_modules/@sentry/cli": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.22.3.tgz",
- "integrity": "sha512-VFHdtrHsMyTRSZhDLeMyXvit7xB4e81KugIEwMve95c7h5HO672bfmCcM/403CAugj4NzvQ+IR2NKF/2SsEPlg==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.33.0.tgz",
+ "integrity": "sha512-9MOzQy1UunVBhPOfEuO0JH2ofWAMmZVavTTR/Bo2CkJwI1qjyVF0UKLTXE3l4ujiJnFufOoBsVyKmYWXFerbCw==",
+ "hasInstallScript": true,
"dependencies": {
"https-proxy-agent": "^5.0.0",
"node-fetch": "^2.6.7",
@@ -7236,19 +6619,19 @@
"node": ">= 10"
},
"optionalDependencies": {
- "@sentry/cli-darwin": "2.22.3",
- "@sentry/cli-linux-arm": "2.22.3",
- "@sentry/cli-linux-arm64": "2.22.3",
- "@sentry/cli-linux-i686": "2.22.3",
- "@sentry/cli-linux-x64": "2.22.3",
- "@sentry/cli-win32-i686": "2.22.3",
- "@sentry/cli-win32-x64": "2.22.3"
+ "@sentry/cli-darwin": "2.33.0",
+ "@sentry/cli-linux-arm": "2.33.0",
+ "@sentry/cli-linux-arm64": "2.33.0",
+ "@sentry/cli-linux-i686": "2.33.0",
+ "@sentry/cli-linux-x64": "2.33.0",
+ "@sentry/cli-win32-i686": "2.33.0",
+ "@sentry/cli-win32-x64": "2.33.0"
}
},
"node_modules/@sentry/cli-darwin": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.22.3.tgz",
- "integrity": "sha512-A1DwFTffg3+fF68qujaJI07dk/1H1pRuihlvS5WQ9sD7nQLnXZGoLUht4eULixhDzZYinWHKkcWzQ6k40UTvNA==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.33.0.tgz",
+ "integrity": "sha512-LQFvD7uCOQ2P/vYru7IBKqJDHwJ9Rr2vqqkdjbxe2YCQS/N3NPXvi3eVM9hDJ284oyV/BMZ5lrmVTuIicf/hhw==",
"optional": true,
"os": [
"darwin"
@@ -7258,9 +6641,9 @@
}
},
"node_modules/@sentry/cli-linux-arm": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.22.3.tgz",
- "integrity": "sha512-mDtLVbqbCu/5b/v2quTAMzY/atGlJVvrqO2Wvpro0Jb/LYhn7Y1pVBdoXEDcnOX82/pseFkLT8PFfq/OcezPhA==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.33.0.tgz",
+ "integrity": "sha512-gY1bFE7wjDJc7WiNq1AS0WrILqLLJUw6Ou4pFQS45KjaH3/XJ1eohHhGJNy/UBHJ/Gq32b/BA9vsnWTXClZJ7g==",
"cpu": [
"arm"
],
@@ -7274,9 +6657,9 @@
}
},
"node_modules/@sentry/cli-linux-arm64": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.22.3.tgz",
- "integrity": "sha512-PnBPb4LJ+A2LlqLjtVFn4mEizcVdxBSLZvB85pEGzq9DRXjZ6ZEuGWFHTVnWvjd79TB/s0me29QnLc3n4B6lgA==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.33.0.tgz",
+ "integrity": "sha512-mR2ZhqpU8RBVGLF5Ji19iOmVznk1B7Bzg5VhA8bVPuKsQmFN/3SyqE87IPMhwKoAsSRXyctwmbAkKs4240fxGA==",
"cpu": [
"arm64"
],
@@ -7290,9 +6673,9 @@
}
},
"node_modules/@sentry/cli-linux-i686": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.22.3.tgz",
- "integrity": "sha512-wxvbpQ2hiw4hwJWfJMp7K45BV40nXL62f91jLuftFXIbieKX1Li57NNKNu2JUVn7W1bJxkwz/PKGGTXSgeJlRw==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.33.0.tgz",
+ "integrity": "sha512-XPIy0XpqgAposHtWsy58qsX85QnZ8q0ktBuT4skrsCrLMzfhoQg4Ua+YbUr3RvE814Rt8Hzowx2ar2Rl3pyCyw==",
"cpu": [
"x86",
"ia32"
@@ -7307,9 +6690,9 @@
}
},
"node_modules/@sentry/cli-linux-x64": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.22.3.tgz",
- "integrity": "sha512-0GxsYNO5GyRWifeOpng+MmdUFZRA64bgA1n1prsEsXnoeLcm3Zj4Q63hBZmiwz9Qbhf5ibohkpf94a7dI7pv3A==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.33.0.tgz",
+ "integrity": "sha512-qe1DdCUv4tmqS03s8RtCkEX9vCW2G+NgOxX6jZ5jN/sKDwjUlquljqo7JHUGSupkoXmymnNPm5By3rNr6VyNHg==",
"cpu": [
"x64"
],
@@ -7323,9 +6706,9 @@
}
},
"node_modules/@sentry/cli-win32-i686": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.22.3.tgz",
- "integrity": "sha512-YERPsd7ClBrxKcmCUw+ZrAvQfbyIZFrqh269hgDuXFodpsB7LPGnI33ilo0uzmKdq2vGppTb6Z3gf1Rbq0Hadg==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.33.0.tgz",
+ "integrity": "sha512-VEXWtJ69C3b+kuSmXQJRwdQ0ypPGH88hpqyQuosbAOIqh/sv4g9B/u1ETHZc+whLdFDpPcTLVMbLDbXTGug0Yg==",
"cpu": [
"x86",
"ia32"
@@ -7339,9 +6722,9 @@
}
},
"node_modules/@sentry/cli-win32-x64": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.22.3.tgz",
- "integrity": "sha512-NUh56xWvgJo2KuC9lI6o6nTPXdzbpQUB4qGwJ73L9NP3HT2P1I27jtHyrC2zlXTVlYE23gQZGrL3wgW4Jy80QA==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.33.0.tgz",
+ "integrity": "sha512-GIUKysZ1xbSklY9h1aVaLMSYLsnMSd+JuwQLR+0wKw2wJC4O5kNCPFSGikhiOZM/kvh3GO1WnXNyazFp8nLAzw==",
"cpu": [
"x64"
],
@@ -7367,120 +6750,72 @@
}
},
"node_modules/@sentry/core": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.85.0.tgz",
- "integrity": "sha512-DFDAc4tWmHN5IWhr7XbHCiyF1Xgb95jz8Uj/JTX9atlgodId1UIbER77qpEmH3eQGid/QBdqrlR98zCixgSbwg==",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.21.0.tgz",
+ "integrity": "sha512-1eW0HKxpBz23oWR3yshl7kVpoJSq1DtqnSIRK3JkV72ytO+UD5sbGQ2iCzmXrefJHP555EOrui2eMm+akq2sDA==",
"dependencies": {
- "@sentry/types": "7.85.0",
- "@sentry/utils": "7.85.0"
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=14.18"
}
},
"node_modules/@sentry/react": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.85.0.tgz",
- "integrity": "sha512-digw63l1A9n+74rW8uiG575Xh3qWTkmvwgTfNRFvDokDRMqRTP0iQEqZRBrBEzMZ5JUa6s+5NLc1/dbMh1QQgA==",
- "dependencies": {
- "@sentry/browser": "7.85.0",
- "@sentry/types": "7.85.0",
- "@sentry/utils": "7.85.0",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.21.0.tgz",
+ "integrity": "sha512-ypAlRkkjRy/FggrCzf9N6tvuLu04QsC6vE6PCek9vPgTUE3lt25rjF8z34ieC+mzLLpfg/tWDvS4NghMwTgPPQ==",
+ "dependencies": {
+ "@sentry/browser": "8.21.0",
+ "@sentry/core": "8.21.0",
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0",
"hoist-non-react-statics": "^3.3.2"
},
"engines": {
- "node": ">=8"
+ "node": ">=14.18"
},
"peerDependencies": {
- "react": "15.x || 16.x || 17.x || 18.x"
- }
- },
- "node_modules/@sentry/replay": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.85.0.tgz",
- "integrity": "sha512-zVtTKfO+lu5qTwHpETI/oGo8hU3rdKHr3CdI1vRLw+d60PcAa/pWVlXsQeLRTw8PFwE358gHcpFZezj/11afew==",
- "dependencies": {
- "@sentry-internal/tracing": "7.85.0",
- "@sentry/core": "7.85.0",
- "@sentry/types": "7.85.0",
- "@sentry/utils": "7.85.0"
- },
- "engines": {
- "node": ">=12"
+ "react": "^16.14.0 || 17.x || 18.x || 19.x"
}
},
"node_modules/@sentry/types": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.85.0.tgz",
- "integrity": "sha512-R5jR4XkK5tBU2jDiPdSVqzkmjYRr666bcGaFGUHB/xDQCjPsjk+pEmCCL+vpuWoaZmQJUE1hVU7rgnVX81w8zg==",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.21.0.tgz",
+ "integrity": "sha512-2hF7lhDCGBN8VkIkHTuh9pL3QnJ3QBkIDAcKosFCS5tHGp68zGJgE0VWg2yQvqjZM06DnFT9CUKF9ZGv45FS3w==",
"engines": {
- "node": ">=8"
+ "node": ">=14.18"
}
},
"node_modules/@sentry/utils": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.85.0.tgz",
- "integrity": "sha512-JZ7seNOLvhjAQ8GeB3GYknPQJkuhF88xAYOaESZP3xPOWBMFUN+IO4RqjMqMLFDniOwsVQS7GB/MfP+hxufieg==",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.21.0.tgz",
+ "integrity": "sha512-Evq5goV8CKLISuULenqJm8VyIYaKa6wDAYIHfcDmSyCJIEDlEpRb8S7LcKdYsf6h0FdGy9ofv5ksgMPCqYq7eg==",
"dependencies": {
- "@sentry/types": "7.85.0"
+ "@sentry/types": "8.21.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=14.18"
}
},
"node_modules/@sentry/vite-plugin": {
- "version": "2.15.0",
- "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-2.15.0.tgz",
- "integrity": "sha512-Q1ML+6p0xBLEbk6pHnZoLs7gQctXrsyI/zzhEQsR/uyPIZIkrwSLcnZ6iCjSz570SvK9H0UVgp1bdLJK/Mpb7Q==",
+ "version": "2.21.1",
+ "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-2.21.1.tgz",
+ "integrity": "sha512-i2PqeLafGBcSROnmr9mS0dL2/JBJji/4rJZ2U2A+tqtAhDAAaCUNalbn6xLp/hawLExt/wRuBj1J7j46sGDOaA==",
"dependencies": {
- "@sentry/bundler-plugin-core": "2.15.0",
+ "@sentry/bundler-plugin-core": "2.21.1",
"unplugin": "1.0.1"
},
"engines": {
"node": ">= 14"
}
},
- "node_modules/@sentry/vite-plugin/node_modules/acorn": {
- "version": "8.11.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
- "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/@sentry/vite-plugin/node_modules/unplugin": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.0.1.tgz",
- "integrity": "sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==",
- "dependencies": {
- "acorn": "^8.8.1",
- "chokidar": "^3.5.3",
- "webpack-sources": "^3.2.3",
- "webpack-virtual-modules": "^0.5.0"
- }
- },
- "node_modules/@sideway/address": {
- "version": "4.1.1",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@hapi/hoek": "^9.0.0"
- }
- },
- "node_modules/@sideway/formula": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
- "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
+ "node_modules/@sinclair/typebox": {
+ "version": "0.27.8",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
+ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
"dev": true
},
- "node_modules/@sideway/pinpoint": {
- "version": "2.0.0",
- "dev": true,
- "license": "BSD-3-Clause"
- },
"node_modules/@sinonjs/commons": {
"version": "1.8.6",
"license": "BSD-3-Clause",
@@ -7497,6 +6832,47 @@
"@sinonjs/commons": "^1.7.0"
}
},
+ "node_modules/@snyk/github-codeowners": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@snyk/github-codeowners/-/github-codeowners-1.1.0.tgz",
+ "integrity": "sha512-lGFf08pbkEac0NYgVf4hdANpAgApRjNByLXB+WBip3qj1iendOIyAwP2GKkKbQMNVy2r1xxDf0ssfWscoiC+Vw==",
+ "dev": true,
+ "dependencies": {
+ "commander": "^4.1.1",
+ "ignore": "^5.1.8",
+ "p-map": "^4.0.0"
+ },
+ "bin": {
+ "github-codeowners": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=8.10"
+ }
+ },
+ "node_modules/@snyk/github-codeowners/node_modules/commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@snyk/github-codeowners/node_modules/p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "dev": true,
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/@swc/core": {
"version": "1.3.40",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.40.tgz",
@@ -7673,13 +7049,20 @@
"node": ">=10"
}
},
+ "node_modules/@swc/counter": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
+ "dev": true
+ },
"node_modules/@swc/jest": {
- "version": "0.2.26",
- "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.26.tgz",
- "integrity": "sha512-7lAi7q7ShTO3E5Gt1Xqf3pIhRbERxR1DUxvtVa9WKzIB+HGQ7wZP5sYx86zqnaEoKKGhmOoZ7gyW0IRu8Br5+A==",
+ "version": "0.2.36",
+ "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.36.tgz",
+ "integrity": "sha512-8X80dp81ugxs4a11z1ka43FPhP+/e+mJNXJSxiNYk8gIX/jPBtY4gQTrKu/KIoco8bzKuPI5lUxjfLiGsfvnlw==",
"dev": true,
"dependencies": {
- "@jest/create-cache-key-function": "^27.4.2",
+ "@jest/create-cache-key-function": "^29.7.0",
+ "@swc/counter": "^0.1.3",
"jsonc-parser": "^3.2.0"
},
"engines": {
@@ -7690,17 +7073,18 @@
}
},
"node_modules/@testing-library/dom": {
- "version": "8.19.0",
- "license": "MIT",
+ "version": "8.20.1",
+ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz",
+ "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==",
"optional": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5",
- "@types/aria-query": "^4.2.0",
- "aria-query": "^5.0.0",
+ "@types/aria-query": "^5.0.1",
+ "aria-query": "5.1.3",
"chalk": "^4.1.0",
"dom-accessibility-api": "^0.5.9",
- "lz-string": "^1.4.4",
+ "lz-string": "^1.5.0",
"pretty-format": "^27.0.2"
},
"engines": {
@@ -7709,7 +7093,8 @@
},
"node_modules/@testing-library/dom/node_modules/chalk": {
"version": "4.1.2",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"optional": true,
"dependencies": {
"ansi-styles": "^4.1.0",
@@ -7724,7 +7109,8 @@
},
"node_modules/@testing-library/dom/node_modules/has-flag": {
"version": "4.0.0",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"optional": true,
"engines": {
"node": ">=8"
@@ -7732,7 +7118,8 @@
},
"node_modules/@testing-library/dom/node_modules/supports-color": {
"version": "7.2.0",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"optional": true,
"dependencies": {
"has-flag": "^4.0.0"
@@ -7742,8 +7129,9 @@
}
},
"node_modules/@testing-library/jest-dom": {
- "version": "5.16.5",
- "license": "MIT",
+ "version": "5.17.0",
+ "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
+ "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==",
"optional": true,
"dependencies": {
"@adobe/css-tools": "^4.0.1",
@@ -7795,7 +7183,8 @@
},
"node_modules/@testing-library/react": {
"version": "12.1.5",
- "license": "MIT",
+ "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz",
+ "integrity": "sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==",
"optional": true,
"dependencies": {
"@babel/runtime": "^7.12.5",
@@ -7840,8 +7229,9 @@
}
},
"node_modules/@testing-library/user-event": {
- "version": "14.4.3",
- "license": "MIT",
+ "version": "14.5.2",
+ "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz",
+ "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==",
"optional": true,
"engines": {
"node": ">=12",
@@ -7880,8 +7270,8 @@
},
"node_modules/@tootallnate/once": {
"version": "1.1.2",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"engines": {
"node": ">= 6"
}
@@ -8006,8 +7396,9 @@
}
},
"node_modules/@types/aria-query": {
- "version": "4.2.2",
- "license": "MIT",
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
+ "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
"optional": true
},
"node_modules/@types/babel__core": {
@@ -8071,6 +7462,7 @@
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
"integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==",
+ "dev": true,
"dependencies": {
"@types/ms": "*"
}
@@ -8127,14 +7519,11 @@
"hoist-non-react-statics": "^3.3.0"
}
},
- "node_modules/@types/is-ci": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@types/is-ci/-/is-ci-3.0.0.tgz",
- "integrity": "sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==",
- "dev": true,
- "dependencies": {
- "ci-info": "^3.1.0"
- }
+ "node_modules/@types/is-url": {
+ "version": "1.2.32",
+ "resolved": "https://registry.npmjs.org/@types/is-url/-/is-url-1.2.32.tgz",
+ "integrity": "sha512-46VLdbWI8Sc+hPexQ6NLNR2YpoDyDZIpASHkJQ2Yr+Kf9Giw6LdCTkwOdsnHKPQeh7xTjTmSnxbE8qpxYuCiHA==",
+ "dev": true
},
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.3",
@@ -8290,49 +7679,31 @@
"dev": true
},
"node_modules/@types/lodash": {
- "version": "4.14.191",
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
- "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==",
+ "version": "4.17.9",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.9.tgz",
+ "integrity": "sha512-w9iWudx1XWOHW5lQRS9iKpK/XuRhnN+0T7HvdCCd802FYkT1AMTnxndJHGrNJwRoRHkslGr4S29tjm1cT7x/7w==",
"dev": true
},
"node_modules/@types/lodash-es": {
- "version": "4.17.6",
- "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.6.tgz",
- "integrity": "sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==",
+ "version": "4.17.12",
+ "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
+ "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
"dev": true,
"dependencies": {
"@types/lodash": "*"
}
},
- "node_modules/@types/mdast": {
- "version": "3.0.12",
- "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.12.tgz",
- "integrity": "sha512-DT+iNIRNX884cx0/Q1ja7NyUPpZuv0KPyL5rGNxm1WC1OtHstl7n4Jb7nk+xacNShQMbczJjt8uFzznpp6kYBg==",
- "dependencies": {
- "@types/unist": "^2"
- }
- },
- "node_modules/@types/minimist": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
- "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
- "dev": true
- },
"node_modules/@types/ms": {
"version": "0.7.31",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",
- "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
+ "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==",
+ "dev": true
},
"node_modules/@types/node": {
"version": "20.8.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.0.tgz",
- "integrity": "sha512-LzcWltT83s1bthcvjBmiBvGJiiUe84NWRHkw+ZV6Fr41z2FbIzvc815dk2nQ3RAKMuN2fkenM/z3Xv2QzEpYxQ=="
- },
- "node_modules/@types/normalize-package-data": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
- "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
- "dev": true
+ "integrity": "sha512-LzcWltT83s1bthcvjBmiBvGJiiUe84NWRHkw+ZV6Fr41z2FbIzvc815dk2nQ3RAKMuN2fkenM/z3Xv2QzEpYxQ==",
+ "devOptional": true
},
"node_modules/@types/parse-json": {
"version": "4.0.0",
@@ -8420,15 +7791,6 @@
"@types/react": "*"
}
},
- "node_modules/@types/react-infinite-scroller": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@types/react-infinite-scroller/-/react-infinite-scroller-1.2.3.tgz",
- "integrity": "sha512-l60JckVoO+dxmKW2eEG7jbliEpITsTJvRPTe97GazjF5+ylagAuyYdXl8YY9DQsTP9QjhqGKZROknzgscGJy0A==",
- "dev": true,
- "dependencies": {
- "@types/react": "*"
- }
- },
"node_modules/@types/react-router": {
"version": "5.1.13",
"dev": true,
@@ -8490,18 +7852,14 @@
"optional": true
},
"node_modules/@types/testing-library__jest-dom": {
- "version": "5.14.5",
- "license": "MIT",
+ "version": "5.14.9",
+ "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz",
+ "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==",
"optional": true,
"dependencies": {
"@types/jest": "*"
}
},
- "node_modules/@types/unist": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
- "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
- },
"node_modules/@types/url-join": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/url-join/-/url-join-4.0.1.tgz",
@@ -8516,13 +7874,8 @@
},
"node_modules/@types/webappsec-credential-management": {
"version": "0.5.1",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/webpack-env": {
- "version": "1.18.0",
- "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.0.tgz",
- "integrity": "sha512-56/MAlX5WMsPVbOg7tAxnYvNYMMWr/QJiIp6BxVSW3JJXUVzzOn64qW8TzQyMSqSUFM2+PVI4aUHcHOzIz/1tg==",
+ "resolved": "https://registry.npmjs.org/@types/webappsec-credential-management/-/webappsec-credential-management-0.5.1.tgz",
+ "integrity": "sha512-ZIl4fCJm3mo0jzivFnxhA4qYEY/HicVPxLbcqQTZ3JjnhEFJwYAEPEZft7AJo/MVxHU4mFdAauX+jo+a4m1Qkg==",
"dev": true
},
"node_modules/@types/ws": {
@@ -8536,8 +7889,8 @@
},
"node_modules/@types/yargs": {
"version": "16.0.5",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
"@types/yargs-parser": "*"
}
@@ -8770,62 +8123,6 @@
"version": "0.13.9",
"license": "MIT"
},
- "node_modules/@uiw/react-color-editable-input": {
- "version": "0.1.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "7.14.6"
- },
- "peerDependencies": {
- "react": ">=16.9.0",
- "react-dom": ">=16.9.0"
- }
- },
- "node_modules/@uiw/react-color-editable-input-rgba": {
- "version": "0.1.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "7.14.6",
- "@uiw/color-convert": "^0.1.0",
- "@uiw/react-color-editable-input": "^0.1.0"
- },
- "peerDependencies": {
- "react": ">=16.9.0",
- "react-dom": ">=16.9.0"
- }
- },
- "node_modules/@uiw/react-color-editable-input-rgba/node_modules/@babel/runtime": {
- "version": "7.14.6",
- "license": "MIT",
- "dependencies": {
- "regenerator-runtime": "^0.13.4"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@uiw/react-color-editable-input-rgba/node_modules/@uiw/color-convert": {
- "version": "0.1.0",
- "license": "MIT"
- },
- "node_modules/@uiw/react-color-editable-input-rgba/node_modules/regenerator-runtime": {
- "version": "0.13.9",
- "license": "MIT"
- },
- "node_modules/@uiw/react-color-editable-input/node_modules/@babel/runtime": {
- "version": "7.14.6",
- "license": "MIT",
- "dependencies": {
- "regenerator-runtime": "^0.13.4"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@uiw/react-color-editable-input/node_modules/regenerator-runtime": {
- "version": "0.13.9",
- "license": "MIT"
- },
"node_modules/@uiw/react-color-hue": {
"version": "0.0.34",
"license": "MIT",
@@ -8853,38 +8150,6 @@
"version": "0.13.9",
"license": "MIT"
},
- "node_modules/@uiw/react-color-material": {
- "version": "0.1.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "7.14.6",
- "@uiw/color-convert": "^0.1.0",
- "@uiw/react-color-editable-input": "^0.1.0",
- "@uiw/react-color-editable-input-rgba": "^0.1.0"
- },
- "peerDependencies": {
- "react": ">=16.9.0",
- "react-dom": ">=16.9.0"
- }
- },
- "node_modules/@uiw/react-color-material/node_modules/@babel/runtime": {
- "version": "7.14.6",
- "license": "MIT",
- "dependencies": {
- "regenerator-runtime": "^0.13.4"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@uiw/react-color-material/node_modules/@uiw/color-convert": {
- "version": "0.1.0",
- "license": "MIT"
- },
- "node_modules/@uiw/react-color-material/node_modules/regenerator-runtime": {
- "version": "0.13.9",
- "license": "MIT"
- },
"node_modules/@uiw/react-color-saturation": {
"version": "0.0.34",
"license": "MIT",
@@ -8943,9 +8208,9 @@
"integrity": "sha512-PZAcHROlgtCUGI2y0JntdNwvPwCNyeVnkQu6KTYKdmxBbK3w72XJUmLFYapfaFfgami4I9CTLnrJTPdtmS3gpw=="
},
"node_modules/@vanilla-extract/recipes": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/@vanilla-extract/recipes/-/recipes-0.5.0.tgz",
- "integrity": "sha512-NfdZ8XyqCDG2RsO3FmYPALDMKg5045dRD97NbBb0Fog3LMDVXZxYgDOct5FAWob8U6W4GbhVpRZt1X9hNnH6fA==",
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/@vanilla-extract/recipes/-/recipes-0.5.5.tgz",
+ "integrity": "sha512-VadU7+IFUwLNLMgks29AHav/K5h7DOEfTU91RItn5vwdPfzduodNg317YbgWCcpm7FSXkuR3B3X8ZOi95UOozA==",
"peerDependencies": {
"@vanilla-extract/css": "^1.0.0"
}
@@ -9280,9 +8545,9 @@
}
},
"node_modules/ansi-colors": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
- "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
"devOptional": true,
"engines": {
"node": ">=6"
@@ -9366,17 +8631,10 @@
"sprintf-js": "~1.0.2"
}
},
- "node_modules/argv": {
- "version": "0.0.2",
- "dev": true,
- "engines": {
- "node": ">=0.6.10"
- }
- },
"node_modules/aria-hidden": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz",
- "integrity": "sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==",
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz",
+ "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==",
"dependencies": {
"tslib": "^2.0.0"
},
@@ -9385,8 +8643,9 @@
}
},
"node_modules/aria-query": {
- "version": "5.1.1",
- "license": "Apache-2.0",
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
+ "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==",
"optional": true,
"dependencies": {
"deep-equal": "^2.0.5"
@@ -9451,6 +8710,7 @@
},
"node_modules/array-union": {
"version": "2.1.0",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -9505,18 +8765,11 @@
"get-intrinsic": "^1.1.3"
}
},
- "node_modules/arrify": {
- "version": "1.0.1",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/asap": {
"version": "2.0.6",
- "dev": true,
- "license": "MIT"
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
+ "dev": true
},
"node_modules/asn1js": {
"version": "3.0.5",
@@ -9548,8 +8801,8 @@
},
"node_modules/asynckit": {
"version": "0.4.0",
- "devOptional": true,
- "license": "MIT"
+ "license": "MIT",
+ "optional": true
},
"node_modules/attr-accept": {
"version": "2.2.2",
@@ -9560,8 +8813,9 @@
},
"node_modules/auto-bind": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz",
+ "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=8"
},
@@ -9580,14 +8834,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/axios": {
- "version": "0.21.4",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "follow-redirects": "^1.14.0"
- }
- },
"node_modules/babel-jest": {
"version": "27.5.1",
"license": "MIT",
@@ -9688,8 +8934,9 @@
},
"node_modules/babel-plugin-syntax-trailing-function-commas": {
"version": "7.0.0-beta.0",
- "dev": true,
- "license": "MIT"
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz",
+ "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==",
+ "dev": true
},
"node_modules/babel-preset-current-node-syntax": {
"version": "1.0.1",
@@ -9715,8 +8962,9 @@
},
"node_modules/babel-preset-fbjs": {
"version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz",
+ "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
@@ -9765,15 +9013,6 @@
"@babel/core": "^7.0.0"
}
},
- "node_modules/bail": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
- "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/balanced-match": {
"version": "1.0.2",
"license": "MIT"
@@ -9809,14 +9048,6 @@
"node": ">=4"
}
},
- "node_modules/big.js": {
- "version": "5.2.2",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
"node_modules/bindings": {
"version": "1.5.0",
"license": "MIT",
@@ -9858,11 +9089,6 @@
"ieee754": "^1.1.13"
}
},
- "node_modules/bluebird": {
- "version": "3.7.2",
- "dev": true,
- "license": "MIT"
- },
"node_modules/boolbase": {
"version": "1.0.0",
"dev": true,
@@ -9887,15 +9113,6 @@
"node": ">=8"
}
},
- "node_modules/breakword": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/breakword/-/breakword-1.0.5.tgz",
- "integrity": "sha512-ex5W9DoOQ/LUEU3PMdLs9ua/CYZl1678NUkKOdUSi8Aw5F1idieaiRURCBFJCwVcrD1J8Iy3vfWSloaMwO2qFg==",
- "dev": true,
- "dependencies": {
- "wcwidth": "^1.0.1"
- }
- },
"node_modules/browser-process-hrtime": {
"version": "1.0.0",
"license": "BSD-2-Clause",
@@ -9908,9 +9125,9 @@
"dev": true
},
"node_modules/browserslist": {
- "version": "4.23.0",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
- "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz",
+ "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==",
"funding": [
{
"type": "opencollective",
@@ -9926,10 +9143,10 @@
}
],
"dependencies": {
- "caniuse-lite": "^1.0.30001587",
- "electron-to-chromium": "^1.4.668",
- "node-releases": "^2.0.14",
- "update-browserslist-db": "^1.0.13"
+ "caniuse-lite": "^1.0.30001663",
+ "electron-to-chromium": "^1.5.28",
+ "node-releases": "^2.0.18",
+ "update-browserslist-db": "^1.1.0"
},
"bin": {
"browserslist": "cli.js"
@@ -10000,36 +9217,10 @@
"node": ">=6"
}
},
- "node_modules/camelcase-keys": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
- "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
- "dev": true,
- "dependencies": {
- "camelcase": "^5.3.1",
- "map-obj": "^4.0.0",
- "quick-lru": "^4.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/camelcase-keys/node_modules/quick-lru": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
- "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/caniuse-lite": {
- "version": "1.0.30001610",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001610.tgz",
- "integrity": "sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA==",
+ "version": "1.0.30001664",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz",
+ "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==",
"funding": [
{
"type": "opencollective",
@@ -10069,15 +9260,6 @@
"tslib": "^2.0.3"
}
},
- "node_modules/ccount": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
- "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/chalk": {
"version": "2.4.2",
"license": "MIT",
@@ -10182,15 +9364,6 @@
"node": ">=10"
}
},
- "node_modules/character-entities": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
- "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/chardet": {
"version": "0.7.0",
"dev": true,
@@ -10204,14 +9377,6 @@
"node": "*"
}
},
- "node_modules/check-more-types": {
- "version": "2.24.0",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8.0"
- }
- },
"node_modules/chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@@ -10526,36 +9691,6 @@
"node": ">=8"
}
},
- "node_modules/codecov": {
- "version": "3.8.1",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "argv": "0.0.2",
- "ignore-walk": "3.0.3",
- "js-yaml": "3.14.0",
- "teeny-request": "6.0.1",
- "urlgrey": "0.4.4"
- },
- "bin": {
- "codecov": "bin/codecov"
- },
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/codecov/node_modules/js-yaml": {
- "version": "3.14.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
"node_modules/codemirror": {
"version": "5.65.11",
"license": "MIT"
@@ -10586,14 +9721,6 @@
"graphql": "^15.5.0 || ^16.0.0"
}
},
- "node_modules/codex-notifier": {
- "version": "1.1.2",
- "license": "MIT"
- },
- "node_modules/codex-tooltip": {
- "version": "1.0.5",
- "license": "MIT"
- },
"node_modules/collect-v8-coverage": {
"version": "1.0.1",
"license": "MIT",
@@ -10621,8 +9748,8 @@
},
"node_modules/combined-stream": {
"version": "1.0.8",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
"delayed-stream": "~1.0.0"
},
@@ -10637,9 +9764,10 @@
"dev": true
},
"node_modules/common-tags": {
- "version": "1.8.0",
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
+ "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=4.0.0"
}
@@ -10704,10 +9832,11 @@
}
},
"node_modules/core-js": {
- "version": "3.10.1",
+ "version": "3.38.1",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz",
+ "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==",
"dev": true,
"hasInstallScript": true,
- "license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
@@ -10744,17 +9873,6 @@
"typescript": ">=3"
}
},
- "node_modules/crc-32": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
- "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
- "bin": {
- "crc32": "bin/crc32.njs"
- },
- "engines": {
- "node": ">=0.8"
- }
- },
"node_modules/create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
@@ -10842,34 +9960,6 @@
"node": "*"
}
},
- "node_modules/css-jss": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
- "jss-preset-default": "10.6.0"
- }
- },
- "node_modules/css-jss/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
- },
- "node_modules/css-jss/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/jss"
- }
- },
"node_modules/css-vendor": {
"version": "2.0.8",
"license": "MIT",
@@ -10913,39 +10003,6 @@
"version": "2.6.16",
"license": "MIT"
},
- "node_modules/csv": {
- "version": "5.5.3",
- "resolved": "https://registry.npmjs.org/csv/-/csv-5.5.3.tgz",
- "integrity": "sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==",
- "dev": true,
- "dependencies": {
- "csv-generate": "^3.4.3",
- "csv-parse": "^4.16.3",
- "csv-stringify": "^5.6.5",
- "stream-transform": "^2.1.3"
- },
- "engines": {
- "node": ">= 0.1.90"
- }
- },
- "node_modules/csv-generate": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-3.4.3.tgz",
- "integrity": "sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==",
- "dev": true
- },
- "node_modules/csv-parse": {
- "version": "4.16.3",
- "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.3.tgz",
- "integrity": "sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==",
- "dev": true
- },
- "node_modules/csv-stringify": {
- "version": "5.6.5",
- "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz",
- "integrity": "sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==",
- "dev": true
- },
"node_modules/currency-codes": {
"version": "2.1.0",
"license": "MIT",
@@ -11029,48 +10086,11 @@
"node": ">=0.10.0"
}
},
- "node_modules/decamelize-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
- "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
- "dev": true,
- "dependencies": {
- "decamelize": "^1.1.0",
- "map-obj": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/decamelize-keys/node_modules/map-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
- "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/decimal.js": {
"version": "10.4.3",
"license": "MIT",
"optional": true
},
- "node_modules/decode-named-character-reference": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
- "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==",
- "dependencies": {
- "character-entities": "^2.0.0"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/dedent": {
"version": "0.7.0",
"license": "MIT",
@@ -11114,8 +10134,8 @@
},
"node_modules/delayed-stream": {
"version": "1.0.0",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"engines": {
"node": ">=0.4.0"
}
@@ -11370,20 +10390,13 @@
},
"node_modules/dependency-graph": {
"version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
+ "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">= 0.6.0"
}
},
- "node_modules/dequal": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
- "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/detect-indent": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
@@ -11423,6 +10436,7 @@
},
"node_modules/dir-glob": {
"version": "3.0.1",
+ "dev": true,
"license": "MIT",
"dependencies": {
"path-type": "^4.0.0"
@@ -11443,8 +10457,9 @@
}
},
"node_modules/dom-accessibility-api": {
- "version": "0.5.14",
- "license": "MIT",
+ "version": "0.5.16",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
+ "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
"optional": true
},
"node_modules/dom-helpers": {
@@ -11614,10 +10629,17 @@
"node": ">=4"
}
},
- "node_modules/duplexer": {
- "version": "0.1.2",
+ "node_modules/easy-table": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.2.0.tgz",
+ "integrity": "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==",
"dev": true,
- "license": "MIT"
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "optionalDependencies": {
+ "wcwidth": "^1.0.1"
+ }
},
"node_modules/editorjs-inline-tool": {
"version": "0.4.0",
@@ -11642,9 +10664,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.737",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.737.tgz",
- "integrity": "sha512-QvLTxaLHKdy5YxvixAw/FfHq2eWLUL9KvsPjp0aHK1gI5d3EDuDgITkvj0nFO2c6zUY3ZqVAJQiBYyQP9tQpfw=="
+ "version": "1.5.29",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.29.tgz",
+ "integrity": "sha512-PF8n2AlIhCKXQ+gTpiJi0VhcHDb69kYX4MtCiivctc2QD3XuNZ/XIOlbGzt7WAjjEev0TtaH6Cu3arZExm5DOw=="
},
"node_modules/emittery": {
"version": "0.8.1",
@@ -11662,14 +10684,6 @@
"devOptional": true,
"license": "MIT"
},
- "node_modules/emojis-list": {
- "version": "3.0.0",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
"node_modules/end-of-stream": {
"version": "1.4.4",
"devOptional": true,
@@ -11678,6 +10692,19 @@
"once": "^1.4.0"
}
},
+ "node_modules/enhanced-resolve": {
+ "version": "5.17.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
+ "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
"node_modules/enquirer": {
"version": "2.3.6",
"devOptional": true,
@@ -11696,15 +10723,6 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
- "node_modules/env-var": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/env-var/-/env-var-7.3.0.tgz",
- "integrity": "sha512-qwtwYJ9d3XFxXRDudPEAMszaggpDgcfb1ZGYb9/cNyMugN2/a8EtviopnRL6c+petj2vp6/gxwYd9ExL1/iPcw==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/error-ex": {
"version": "1.3.2",
"license": "MIT",
@@ -11797,40 +10815,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/esbuild": {
- "version": "0.14.34",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=12"
- },
- "optionalDependencies": {
- "esbuild-android-64": "0.14.34",
- "esbuild-android-arm64": "0.14.34",
- "esbuild-darwin-64": "0.14.34",
- "esbuild-darwin-arm64": "0.14.34",
- "esbuild-freebsd-64": "0.14.34",
- "esbuild-freebsd-arm64": "0.14.34",
- "esbuild-linux-32": "0.14.34",
- "esbuild-linux-64": "0.14.34",
- "esbuild-linux-arm": "0.14.34",
- "esbuild-linux-arm64": "0.14.34",
- "esbuild-linux-mips64le": "0.14.34",
- "esbuild-linux-ppc64le": "0.14.34",
- "esbuild-linux-riscv64": "0.14.34",
- "esbuild-linux-s390x": "0.14.34",
- "esbuild-netbsd-64": "0.14.34",
- "esbuild-openbsd-64": "0.14.34",
- "esbuild-sunos-64": "0.14.34",
- "esbuild-windows-32": "0.14.34",
- "esbuild-windows-64": "0.14.34",
- "esbuild-windows-arm64": "0.14.34"
- }
- },
"node_modules/esbuild-android-64": {
"version": "0.15.15",
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.15.tgz",
@@ -11879,21 +10863,6 @@
"node": ">=12"
}
},
- "node_modules/esbuild-darwin-arm64": {
- "version": "0.14.34",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/esbuild-freebsd-64": {
"version": "0.15.15",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.15.tgz",
@@ -12054,45 +11023,6 @@
"node": ">=12"
}
},
- "node_modules/esbuild-loader": {
- "version": "2.18.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "esbuild": "^0.14.6",
- "joycon": "^3.0.1",
- "json5": "^2.2.0",
- "loader-utils": "^2.0.0",
- "tapable": "^2.2.0",
- "webpack-sources": "^2.2.0"
- },
- "funding": {
- "url": "https://github.com/privatenumber/esbuild-loader?sponsor=1"
- },
- "peerDependencies": {
- "webpack": "^4.40.0 || ^5.0.0"
- }
- },
- "node_modules/esbuild-loader/node_modules/source-map": {
- "version": "0.6.1",
- "dev": true,
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/esbuild-loader/node_modules/webpack-sources": {
- "version": "2.3.1",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "source-list-map": "^2.0.1",
- "source-map": "^0.6.1"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
"node_modules/esbuild-netbsd-64": {
"version": "0.15.15",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.15.tgz",
@@ -12189,313 +11119,10 @@
"node": ">=12"
}
},
- "node_modules/esbuild/node_modules/esbuild-android-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.34.tgz",
- "integrity": "sha512-XfxcfJqmMYsT/LXqrptzFxmaR3GWzXHDLdFNIhm6S00zPaQF1TBBWm+9t0RZ6LRR7iwH57DPjaOeW20vMqI4Yw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-android-arm64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.34.tgz",
- "integrity": "sha512-T02+NXTmSRL1Mc6puz+R9CB54rSPICkXKq6+tw8B6vxZFnCPzbJxgwIX4kcluz9p8nYBjF3+lSilTGWb7+Xgew==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-darwin-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.34.tgz",
- "integrity": "sha512-pLRip2Bh4Ng7Bf6AMgCrSp3pPe/qZyf11h5Qo2mOfJqLWzSVjxrXW+CFRJfrOVP7TCnh/gmZSM2AFdCPB72vtw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-freebsd-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.34.tgz",
- "integrity": "sha512-m0HBjePhe0hAQJgtMRMNV9kMgIyV4/qSnzPx42kRMQBcPhgjAq1JRu4Il26czC+9FgpMbFkUktb07f/Lwnc6CA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-freebsd-arm64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.34.tgz",
- "integrity": "sha512-cpRc2B94L1KvMPPYB4D6G39jLqpKlD3noAMY4/e86iXXXkhUYJJEtTuyNFTa9JRpWM0xCAp4mxjHjoIiLuoCLA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-linux-32": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.34.tgz",
- "integrity": "sha512-8nQaEaoW7MH/K/RlozJa+lE1ejHIr8fuPIHhc513UebRav7HtXgQvxHQ6VZRUkWtep23M6dd7UqhwO1tMOfzQQ==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-linux-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.34.tgz",
- "integrity": "sha512-Y3of4qQoLLlAgf042MlrY1P+7PnN9zWj8nVtw9XQG5hcLOZLz7IKpU35oeu7n4wvyaZHwvQqDJ93gRLqdJekcQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-linux-arm": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.34.tgz",
- "integrity": "sha512-9lpq1NcJqssAF7alCO6zL3gvBVVt/lKw4oetUM7OgNnRX0OWpB+ZIO9FwCrSj/dMdmgDhPLf+119zB8QxSMmAg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-linux-arm64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.34.tgz",
- "integrity": "sha512-IlWaGtj9ir7+Nrume1DGcyzBDlK8GcnJq0ANKwcI9pVw8tqr+6GD0eqyF9SF1mR8UmAp+odrx1H5NdR2cHdFHA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-linux-mips64le": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.34.tgz",
- "integrity": "sha512-k3or+01Rska1AjUyNjA4buEwB51eyN/xPQAoOx1CjzAQC3l8rpjUDw55kXyL63O/1MUi4ISvtNtl8gLwdyEcxw==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-linux-ppc64le": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.34.tgz",
- "integrity": "sha512-+qxb8M9FfM2CJaVU7GgYpJOHM1ngQOx+/VrtBjb4C8oVqaPcESCeg2anjl+HRZy8VpYc71q/iBYausPPbJ+Keg==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-linux-riscv64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.34.tgz",
- "integrity": "sha512-Y717ltBdQ5j5sZIHdy1DV9kieo0wMip0dCmVSTceowCPYSn1Cg33Kd6981+F/3b9FDMzNWldZFOBRILViENZSA==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-linux-s390x": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.34.tgz",
- "integrity": "sha512-bDDgYO4LhL4+zPs+WcBkXph+AQoPcQRTv18FzZS0WhjfH8TZx2QqlVPGhmhZ6WidrY+jKthUqO6UhGyIb4MpmA==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-netbsd-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.34.tgz",
- "integrity": "sha512-cfaFGXdRt0+vHsjNPyF0POM4BVSHPSbhLPe8mppDc7GDDxjIl08mV1Zou14oDWMp/XZMjYN1kWYRSfftiD0vvQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-openbsd-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.34.tgz",
- "integrity": "sha512-vmy9DxXVnRiI14s8GKuYBtess+EVcDALkbpTqd5jw4XITutIzyB7n4x0Tj5utAkKsgZJB22lLWGekr0ABnSLow==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-sunos-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.34.tgz",
- "integrity": "sha512-eNPVatNET1F7tRMhii7goL/eptfxc0ALRjrj9SPFNqp0zmxrehBFD6BaP3R4LjMn6DbMO0jOAnTLFKr8NqcJAA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-windows-32": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.34.tgz",
- "integrity": "sha512-EFhpXyHEcnqWYe2rAHFd8dRw8wkrd9U+9oqcyoEL84GbanAYjiiIjBZsnR8kl0sCQ5w6bLpk7vCEIA2VS32Vcg==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-windows-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.34.tgz",
- "integrity": "sha512-a8fbl8Ky7PxNEjf1aJmtxdDZj32/hC7S1OcA2ckEpCJRTjiKslI9vAdPpSjrKIWhws4Galpaawy0nB7fjHYf5Q==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/esbuild/node_modules/esbuild-windows-arm64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.34.tgz",
- "integrity": "sha512-EYvmKbSa2B3sPnpC28UEu9jBK5atGV4BaVRE7CYGUci2Hlz4AvtV/LML+TcDMT6gBgibnN2gcltWclab3UutMg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/escalade": {
- "version": "3.1.1",
- "license": "MIT",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"engines": {
"node": ">=6"
}
@@ -13382,22 +12009,6 @@
"url": "https://opencollective.com/eslint"
}
},
- "node_modules/eslint/node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/eslint/node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -13457,21 +12068,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/eslint/node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/eslint/node_modules/optionator": {
"version": "0.9.1",
"dev": true,
@@ -13488,45 +12084,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/eslint/node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint/node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/eslint/node_modules/prelude-ls": {
"version": "1.2.1",
"dev": true,
@@ -13661,20 +12218,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/event-stream": {
- "version": "3.3.4",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "duplexer": "~0.1.1",
- "from": "~0",
- "map-stream": "~0.1.0",
- "pause-stream": "0.0.11",
- "split": "0.3",
- "stream-combiner": "~0.0.4",
- "through": "~2.3.1"
- }
- },
"node_modules/execa": {
"version": "4.1.0",
"devOptional": true,
@@ -13724,6 +12267,7 @@
},
"node_modules/extend": {
"version": "3.0.2",
+ "dev": true,
"license": "MIT"
},
"node_modules/extendable-error": {
@@ -13781,6 +12325,7 @@
},
"node_modules/fast-glob": {
"version": "3.2.11",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
@@ -13828,9 +12373,9 @@
"dev": true
},
"node_modules/fast-xml-parser": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.6.tgz",
- "integrity": "sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==",
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz",
+ "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==",
"dev": true,
"funding": [
{
@@ -13851,6 +12396,7 @@
},
"node_modules/fastq": {
"version": "1.11.0",
+ "dev": true,
"license": "ISC",
"dependencies": {
"reusify": "^1.0.4"
@@ -13865,23 +12411,25 @@
}
},
"node_modules/fbjs": {
- "version": "3.0.0",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz",
+ "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "cross-fetch": "^3.0.4",
+ "cross-fetch": "^3.1.5",
"fbjs-css-vars": "^1.0.0",
"loose-envify": "^1.0.0",
"object-assign": "^4.1.0",
"promise": "^7.1.1",
"setimmediate": "^1.0.5",
- "ua-parser-js": "^0.7.18"
+ "ua-parser-js": "^1.0.35"
}
},
"node_modules/fbjs-css-vars": {
"version": "1.0.2",
- "dev": true,
- "license": "MIT"
+ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
+ "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==",
+ "dev": true
},
"node_modules/fflate": {
"version": "0.4.8",
@@ -13970,97 +12518,19 @@
"version": "1.1.0",
"license": "MIT"
},
- "node_modules/find-test-names": {
- "version": "1.28.13",
- "resolved": "https://registry.npmjs.org/find-test-names/-/find-test-names-1.28.13.tgz",
- "integrity": "sha512-hVatCLbiZmvBwqYNGTkVNbeJwK/8pvkXKQGji+23GzW8fVFHcEaRID77eQYItLKGwa1Tmu0AK2LjcUtuid57FQ==",
- "dependencies": {
- "@babel/parser": "^7.21.2",
- "@babel/plugin-syntax-jsx": "^7.18.6",
- "acorn-walk": "^8.2.0",
- "debug": "^4.3.3",
- "globby": "^11.0.4",
- "simple-bin-help": "^1.8.0"
- },
- "bin": {
- "find-test-names": "bin/find-test-names.js",
- "print-tests": "bin/print-tests.js",
- "update-test-count": "bin/update-test-count.js"
- }
- },
- "node_modules/find-test-names/node_modules/acorn-walk": {
- "version": "8.2.0",
- "license": "MIT",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/find-yarn-workspace-root2": {
- "version": "1.2.16",
- "resolved": "https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz",
- "integrity": "sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==",
- "dev": true,
- "dependencies": {
- "micromatch": "^4.0.2",
- "pkg-dir": "^4.2.0"
- }
- },
- "node_modules/find-yarn-workspace-root2/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/find-yarn-workspace-root2/node_modules/locate-path": {
+ "node_modules/find-up": {
"version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/find-yarn-workspace-root2/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dependencies": {
- "p-limit": "^2.2.0"
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
},
"engines": {
- "node": ">=8"
- }
- },
- "node_modules/find-yarn-workspace-root2/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/find-yarn-workspace-root2/node_modules/pkg-dir": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
- "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
- "dev": true,
- "dependencies": {
- "find-up": "^4.0.0"
+ "node": ">=10"
},
- "engines": {
- "node": ">=8"
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/first-match": {
@@ -14103,26 +12573,6 @@
"node": ">=10"
}
},
- "node_modules/follow-redirects": {
- "version": "1.15.2",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
- "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
- "dev": true,
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/RubenVerborgh"
- }
- ],
- "engines": {
- "node": ">=4.0"
- },
- "peerDependenciesMeta": {
- "debug": {
- "optional": true
- }
- }
- },
"node_modules/for-each": {
"version": "0.3.3",
"license": "MIT",
@@ -14131,11 +12581,6 @@
"is-callable": "^1.1.3"
}
},
- "node_modules/from": {
- "version": "0.1.7",
- "dev": true,
- "license": "MIT"
- },
"node_modules/front-matter": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz",
@@ -14145,11 +12590,12 @@
}
},
"node_modules/fs-extra": {
- "version": "8.1.0",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+ "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
"dev": true,
- "license": "MIT",
"dependencies": {
- "graceful-fs": "^4.2.0",
+ "graceful-fs": "^4.1.2",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
},
@@ -14157,11 +12603,6 @@
"node": ">=6 <7 || >=8"
}
},
- "node_modules/fs-readdir-recursive": {
- "version": "1.1.0",
- "dev": true,
- "license": "MIT"
- },
"node_modules/fs.realpath": {
"version": "1.0.0",
"license": "ISC"
@@ -14299,10 +12740,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/github-buttons": {
- "version": "2.22.1",
- "license": "BSD-2-Clause"
- },
"node_modules/glob": {
"version": "7.2.3",
"devOptional": true,
@@ -14365,6 +12802,7 @@
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
"dependencies": {
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
@@ -14460,19 +12898,6 @@
}
}
},
- "node_modules/graphql-config/node_modules/@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "dependencies": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- },
- "peerDependencies": {
- "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
- }
- },
"node_modules/graphql-config/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -14532,43 +12957,6 @@
"graphql": "^15.5.0 || ^16.0.0"
}
},
- "node_modules/graphql-request": {
- "version": "3.7.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cross-fetch": "^3.0.6",
- "extract-files": "^9.0.0",
- "form-data": "^3.0.0"
- },
- "peerDependencies": {
- "graphql": "14 - 16"
- }
- },
- "node_modules/graphql-request/node_modules/extract-files": {
- "version": "9.0.0",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^10.17.0 || ^12.0.0 || >= 13.7.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/jaydenseric"
- }
- },
- "node_modules/graphql-request/node_modules/form-data": {
- "version": "3.0.1",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/graphql-tag": {
"version": "2.12.6",
"resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz",
@@ -14625,19 +13013,11 @@
"node": ">=0.10.0"
}
},
- "node_modules/hard-rejection": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
- "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/harmony-reflect": {
"version": "1.6.2",
- "dev": true,
- "license": "(Apache-2.0 OR MPL-1.1)"
+ "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz",
+ "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==",
+ "dev": true
},
"node_modules/has": {
"version": "1.0.3",
@@ -14758,11 +13138,6 @@
"version": "16.13.1",
"license": "MIT"
},
- "node_modules/hosted-git-info": {
- "version": "2.8.9",
- "dev": true,
- "license": "ISC"
- },
"node_modules/hotkeys-js": {
"version": "3.8.3",
"license": "MIT"
@@ -14874,8 +13249,8 @@
},
"node_modules/http-proxy-agent": {
"version": "4.0.1",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
"@tootallnate/once": "1",
"agent-base": "6",
@@ -14942,8 +13317,9 @@
},
"node_modules/identity-obj-proxy": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz",
+ "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==",
"dev": true,
- "license": "MIT",
"dependencies": {
"harmony-reflect": "^1.4.6"
},
@@ -14974,22 +13350,16 @@
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
"integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+ "dev": true,
"engines": {
"node": ">= 4"
}
},
- "node_modules/ignore-walk": {
- "version": "3.0.3",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "minimatch": "^3.0.4"
- }
- },
"node_modules/immutable": {
"version": "3.7.6",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz",
+ "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==",
"dev": true,
- "license": "BSD-3-Clause",
"engines": {
"node": ">=0.8.0"
}
@@ -15081,14 +13451,6 @@
"node": ">=8"
}
},
- "node_modules/import-local/node_modules/path-exists": {
- "version": "4.0.0",
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/import-local/node_modules/pkg-dir": {
"version": "4.2.0",
"license": "MIT",
@@ -15253,8 +13615,9 @@
},
"node_modules/is-absolute": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
"dev": true,
- "license": "MIT",
"dependencies": {
"is-relative": "^1.0.0",
"is-windows": "^1.0.1"
@@ -15474,14 +13837,6 @@
"node": ">=8"
}
},
- "node_modules/is-plain-obj": {
- "version": "1.1.0",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/is-plain-object": {
"version": "2.0.4",
"license": "MIT",
@@ -15522,8 +13877,9 @@
},
"node_modules/is-relative": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
"dev": true,
- "license": "MIT",
"dependencies": {
"is-unc-path": "^1.0.0"
},
@@ -15623,8 +13979,9 @@
},
"node_modules/is-unc-path": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
"unc-path-regex": "^0.1.2"
},
@@ -17122,18 +15479,6 @@
"jiti": "bin/jiti.js"
}
},
- "node_modules/joi": {
- "version": "17.4.0",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@hapi/hoek": "^9.0.0",
- "@hapi/topo": "^5.0.0",
- "@sideway/address": "^4.1.0",
- "@sideway/formula": "^3.0.0",
- "@sideway/pinpoint": "^2.0.0"
- }
- },
"node_modules/jose": {
"version": "4.14.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.14.4.tgz",
@@ -17143,14 +15488,6 @@
"url": "https://github.com/sponsors/panva"
}
},
- "node_modules/joycon": {
- "version": "3.1.1",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/js-tokens": {
"version": "4.0.0",
"license": "MIT"
@@ -17304,9 +15641,9 @@
}
},
"node_modules/jsonc-parser": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
- "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
+ "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
"dev": true
},
"node_modules/jsonfile": {
@@ -17322,67 +15659,28 @@
"dev": true,
"license": "Public Domain"
},
- "node_modules/jss": {
- "version": "9.8.7",
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "is-in-browser": "^1.1.3",
- "symbol-observable": "^1.1.0",
- "warning": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/jss-plugin-camel-case": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz",
+ "integrity": "sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"hyphenate-style-name": "^1.0.3",
- "jss": "10.6.0"
+ "jss": "10.10.0"
}
},
"node_modules/jss-plugin-camel-case/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/jss-plugin-camel-case/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/jss"
- }
- },
- "node_modules/jss-plugin-compose": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
- "tiny-warning": "^1.0.2"
- }
- },
- "node_modules/jss-plugin-compose/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
- },
- "node_modules/jss-plugin-compose/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
},
@@ -17392,79 +15690,26 @@
}
},
"node_modules/jss-plugin-default-unit": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz",
+ "integrity": "sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==",
"dependencies": {
"@babel/runtime": "^7.3.1",
- "jss": "10.6.0"
+ "jss": "10.10.0"
}
},
"node_modules/jss-plugin-default-unit/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/jss-plugin-default-unit/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/jss"
- }
- },
- "node_modules/jss-plugin-expand": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0"
- }
- },
- "node_modules/jss-plugin-expand/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
- },
- "node_modules/jss-plugin-expand/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/jss"
- }
- },
- "node_modules/jss-plugin-extend": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
- "tiny-warning": "^1.0.2"
- }
- },
- "node_modules/jss-plugin-extend/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
- },
- "node_modules/jss-plugin-extend/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
},
@@ -17474,24 +15719,26 @@
}
},
"node_modules/jss-plugin-global": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz",
+ "integrity": "sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==",
"dependencies": {
"@babel/runtime": "^7.3.1",
- "jss": "10.6.0"
+ "jss": "10.10.0"
}
},
"node_modules/jss-plugin-global/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/jss-plugin-global/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
},
@@ -17501,25 +15748,27 @@
}
},
"node_modules/jss-plugin-nested": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz",
+ "integrity": "sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==",
"dependencies": {
"@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
+ "jss": "10.10.0",
"tiny-warning": "^1.0.2"
}
},
"node_modules/jss-plugin-nested/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/jss-plugin-nested/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
},
@@ -17529,24 +15778,26 @@
}
},
"node_modules/jss-plugin-props-sort": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz",
+ "integrity": "sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==",
"dependencies": {
"@babel/runtime": "^7.3.1",
- "jss": "10.6.0"
+ "jss": "10.10.0"
}
},
"node_modules/jss-plugin-props-sort/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/jss-plugin-props-sort/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
},
@@ -17556,81 +15807,27 @@
}
},
"node_modules/jss-plugin-rule-value-function": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz",
+ "integrity": "sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==",
"dependencies": {
"@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
+ "jss": "10.10.0",
"tiny-warning": "^1.0.2"
}
},
"node_modules/jss-plugin-rule-value-function/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/jss-plugin-rule-value-function/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/jss"
- }
- },
- "node_modules/jss-plugin-rule-value-observable": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
- "symbol-observable": "^1.2.0"
- }
- },
- "node_modules/jss-plugin-rule-value-observable/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
- },
- "node_modules/jss-plugin-rule-value-observable/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/jss"
- }
- },
- "node_modules/jss-plugin-template": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
- "tiny-warning": "^1.0.2"
- }
- },
- "node_modules/jss-plugin-template/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
- },
- "node_modules/jss-plugin-template/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
},
@@ -17640,64 +15837,27 @@
}
},
"node_modules/jss-plugin-vendor-prefixer": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz",
+ "integrity": "sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"css-vendor": "^2.0.8",
- "jss": "10.6.0"
+ "jss": "10.10.0"
}
},
"node_modules/jss-plugin-vendor-prefixer/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/jss-plugin-vendor-prefixer/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"dependencies": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/jss"
- }
- },
- "node_modules/jss-preset-default": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
- "jss-plugin-camel-case": "10.6.0",
- "jss-plugin-compose": "10.6.0",
- "jss-plugin-default-unit": "10.6.0",
- "jss-plugin-expand": "10.6.0",
- "jss-plugin-extend": "10.6.0",
- "jss-plugin-global": "10.6.0",
- "jss-plugin-nested": "10.6.0",
- "jss-plugin-props-sort": "10.6.0",
- "jss-plugin-rule-value-function": "10.6.0",
- "jss-plugin-rule-value-observable": "10.6.0",
- "jss-plugin-template": "10.6.0",
- "jss-plugin-vendor-prefixer": "10.6.0"
- }
- },
- "node_modules/jss-preset-default/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
- },
- "node_modules/jss-preset-default/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
},
@@ -17719,67 +15879,137 @@
"node": ">=4.0"
}
},
- "node_modules/junit-merge": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/junit-merge/-/junit-merge-2.0.0.tgz",
- "integrity": "sha512-qwENzBWcdHPazNqPO0fKyFIqEyaSKyO0iyBeIU4Y/scjkXYpwTi88P2S/PWecqgMhzG2MOCwXk8QB9ucvXeIPw==",
+ "node_modules/jwt-decode": {
+ "version": "3.1.2",
+ "license": "MIT"
+ },
+ "node_modules/keycode": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.1.tgz",
+ "integrity": "sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg=="
+ },
+ "node_modules/kleur": {
+ "version": "3.0.3",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/knip": {
+ "version": "5.30.5",
+ "resolved": "https://registry.npmjs.org/knip/-/knip-5.30.5.tgz",
+ "integrity": "sha512-opta1VVKAfIzhvj1iyOr/3SgSDC6jYPoUaYkvjftNqMTeURppYY5VqrAa5DOcJnIsdcAdyoIKHUFg9NRiFaM5w==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/webpro"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/knip"
+ },
+ {
+ "type": "polar",
+ "url": "https://polar.sh/webpro-nl"
+ }
+ ],
"dependencies": {
- "commander": "^2.18.0",
- "fs-readdir-recursive": "^1.1.0",
- "mkdirp": "^0.5.1",
- "xmldoc": "^1.1.2"
+ "@nodelib/fs.walk": "1.2.8",
+ "@snyk/github-codeowners": "1.1.0",
+ "easy-table": "1.2.0",
+ "enhanced-resolve": "^5.17.1",
+ "fast-glob": "^3.3.2",
+ "jiti": "^1.21.6",
+ "js-yaml": "^4.1.0",
+ "minimist": "^1.2.8",
+ "picocolors": "^1.0.0",
+ "picomatch": "^4.0.1",
+ "pretty-ms": "^9.0.0",
+ "smol-toml": "^1.3.0",
+ "strip-json-comments": "5.0.1",
+ "summary": "2.1.0",
+ "zod": "^3.22.4",
+ "zod-validation-error": "^3.0.3"
},
"bin": {
- "junit-merge": "bin/junit-merge"
+ "knip": "bin/knip.js",
+ "knip-bun": "bin/knip-bun.js"
+ },
+ "engines": {
+ "node": ">=18.6.0"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18",
+ "typescript": ">=5.0.4"
}
},
- "node_modules/junit-report-merger": {
- "version": "3.0.5",
- "license": "MIT",
+ "node_modules/knip/node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "node_modules/knip/node_modules/fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "dev": true,
"dependencies": {
- "fast-glob": "3.2.11",
- "xmlbuilder2": "3.0.2"
- },
- "bin": {
- "jrm": "cli.js",
- "junit-report-merger": "cli.js"
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
},
"engines": {
- "node": ">=12"
+ "node": ">=8.6.0"
}
},
- "node_modules/jwt-decode": {
- "version": "3.1.2",
- "license": "MIT"
- },
- "node_modules/keycode": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.1.tgz",
- "integrity": "sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg=="
+ "node_modules/knip/node_modules/jiti": {
+ "version": "1.21.6",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
+ "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
+ "dev": true,
+ "bin": {
+ "jiti": "bin/jiti.js"
+ }
},
- "node_modules/kind-of": {
- "version": "6.0.3",
+ "node_modules/knip/node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
}
},
- "node_modules/kleur": {
- "version": "3.0.3",
- "devOptional": true,
- "license": "MIT",
+ "node_modules/knip/node_modules/picomatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "dev": true,
"engines": {
- "node": ">=6"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/lazy-ass": {
- "version": "1.6.0",
+ "node_modules/knip/node_modules/strip-json-comments": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz",
+ "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==",
"dev": true,
- "license": "MIT",
"engines": {
- "node": "> 0.8"
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/leven": {
@@ -17941,33 +16171,18 @@
"node": ">=8"
}
},
- "node_modules/load-yaml-file": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz",
- "integrity": "sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==",
- "dev": true,
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dependencies": {
- "graceful-fs": "^4.1.5",
- "js-yaml": "^3.13.0",
- "pify": "^4.0.1",
- "strip-bom": "^3.0.0"
+ "p-locate": "^5.0.0"
},
"engines": {
- "node": ">=6"
- }
- },
- "node_modules/loader-utils": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
- "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
- "dev": true,
- "dependencies": {
- "big.js": "^5.2.2",
- "emojis-list": "^3.0.0",
- "json5": "^2.1.2"
+ "node": ">=10"
},
- "engines": {
- "node": ">=8.9.0"
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/lodash": {
@@ -18135,15 +16350,6 @@
"node": ">=8"
}
},
- "node_modules/longest-streak": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
- "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/loose-envify": {
"version": "1.4.0",
"license": "MIT",
@@ -18194,8 +16400,10 @@
}
},
"node_modules/lz-string": {
- "version": "1.4.4",
- "license": "WTFPL",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
+ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
+ "optional": true,
"bin": {
"lz-string": "bin/bin.js"
}
@@ -18223,28 +16431,13 @@
},
"node_modules/map-cache": {
"version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
- "node_modules/map-obj": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
- "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/map-stream": {
- "version": "0.1.0",
- "dev": true
- },
"node_modules/markdown-it": {
"version": "12.3.2",
"license": "MIT",
@@ -18270,15 +16463,6 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
- "node_modules/markdown-table": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz",
- "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/marked": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
@@ -18300,199 +16484,6 @@
"is-buffer": "~1.1.6"
}
},
- "node_modules/mdast-util-find-and-replace": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz",
- "integrity": "sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==",
- "dependencies": {
- "@types/mdast": "^3.0.0",
- "escape-string-regexp": "^5.0.0",
- "unist-util-is": "^5.0.0",
- "unist-util-visit-parents": "^5.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
- "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/mdast-util-from-markdown": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz",
- "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==",
- "dependencies": {
- "@types/mdast": "^3.0.0",
- "@types/unist": "^2.0.0",
- "decode-named-character-reference": "^1.0.0",
- "mdast-util-to-string": "^3.1.0",
- "micromark": "^3.0.0",
- "micromark-util-decode-numeric-character-reference": "^1.0.0",
- "micromark-util-decode-string": "^1.0.0",
- "micromark-util-normalize-identifier": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "unist-util-stringify-position": "^3.0.0",
- "uvu": "^0.5.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-from-markdown/node_modules/mdast-util-to-string": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz",
- "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==",
- "dependencies": {
- "@types/mdast": "^3.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-gfm": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz",
- "integrity": "sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==",
- "dependencies": {
- "mdast-util-from-markdown": "^1.0.0",
- "mdast-util-gfm-autolink-literal": "^1.0.0",
- "mdast-util-gfm-footnote": "^1.0.0",
- "mdast-util-gfm-strikethrough": "^1.0.0",
- "mdast-util-gfm-table": "^1.0.0",
- "mdast-util-gfm-task-list-item": "^1.0.0",
- "mdast-util-to-markdown": "^1.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-gfm-autolink-literal": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz",
- "integrity": "sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==",
- "dependencies": {
- "@types/mdast": "^3.0.0",
- "ccount": "^2.0.0",
- "mdast-util-find-and-replace": "^2.0.0",
- "micromark-util-character": "^1.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-gfm-footnote": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz",
- "integrity": "sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==",
- "dependencies": {
- "@types/mdast": "^3.0.0",
- "mdast-util-to-markdown": "^1.3.0",
- "micromark-util-normalize-identifier": "^1.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-gfm-strikethrough": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz",
- "integrity": "sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==",
- "dependencies": {
- "@types/mdast": "^3.0.0",
- "mdast-util-to-markdown": "^1.3.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-gfm-table": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz",
- "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==",
- "dependencies": {
- "@types/mdast": "^3.0.0",
- "markdown-table": "^3.0.0",
- "mdast-util-from-markdown": "^1.0.0",
- "mdast-util-to-markdown": "^1.3.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-gfm-task-list-item": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz",
- "integrity": "sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==",
- "dependencies": {
- "@types/mdast": "^3.0.0",
- "mdast-util-to-markdown": "^1.3.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-phrasing": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz",
- "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==",
- "dependencies": {
- "@types/mdast": "^3.0.0",
- "unist-util-is": "^5.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-to-markdown": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz",
- "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==",
- "dependencies": {
- "@types/mdast": "^3.0.0",
- "@types/unist": "^2.0.0",
- "longest-streak": "^3.0.0",
- "mdast-util-phrasing": "^3.0.0",
- "mdast-util-to-string": "^3.0.0",
- "micromark-util-decode-string": "^1.0.0",
- "unist-util-visit": "^4.0.0",
- "zwitch": "^2.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-to-markdown/node_modules/mdast-util-to-string": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz",
- "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==",
- "dependencies": {
- "@types/mdast": "^3.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
"node_modules/mdurl": {
"version": "1.0.1",
"license": "MIT"
@@ -18502,56 +16493,6 @@
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
},
- "node_modules/meow": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz",
- "integrity": "sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==",
- "dev": true,
- "dependencies": {
- "@types/minimist": "^1.2.0",
- "camelcase-keys": "^6.2.2",
- "decamelize-keys": "^1.1.0",
- "hard-rejection": "^2.1.0",
- "minimist-options": "^4.0.2",
- "normalize-package-data": "^2.5.0",
- "read-pkg-up": "^7.0.1",
- "redent": "^3.0.0",
- "trim-newlines": "^3.0.0",
- "type-fest": "^0.13.1",
- "yargs-parser": "^18.1.3"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/meow/node_modules/type-fest": {
- "version": "0.13.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
- "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/meow/node_modules/yargs-parser": {
- "version": "18.1.3",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
- "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
- "dev": true,
- "dependencies": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/merge-stream": {
"version": "2.0.0",
"devOptional": true,
@@ -18561,6 +16502,7 @@
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
"engines": {
"node": ">= 8"
}
@@ -18581,543 +16523,9 @@
}
}
},
- "node_modules/micromark": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz",
- "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "@types/debug": "^4.0.0",
- "debug": "^4.0.0",
- "decode-named-character-reference": "^1.0.0",
- "micromark-core-commonmark": "^1.0.1",
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-combine-extensions": "^1.0.0",
- "micromark-util-decode-numeric-character-reference": "^1.0.0",
- "micromark-util-encode": "^1.0.0",
- "micromark-util-normalize-identifier": "^1.0.0",
- "micromark-util-resolve-all": "^1.0.0",
- "micromark-util-sanitize-uri": "^1.0.0",
- "micromark-util-subtokenize": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.1",
- "uvu": "^0.5.0"
- }
- },
- "node_modules/micromark-core-commonmark": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz",
- "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "decode-named-character-reference": "^1.0.0",
- "micromark-factory-destination": "^1.0.0",
- "micromark-factory-label": "^1.0.0",
- "micromark-factory-space": "^1.0.0",
- "micromark-factory-title": "^1.0.0",
- "micromark-factory-whitespace": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-classify-character": "^1.0.0",
- "micromark-util-html-tag-name": "^1.0.0",
- "micromark-util-normalize-identifier": "^1.0.0",
- "micromark-util-resolve-all": "^1.0.0",
- "micromark-util-subtokenize": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.1",
- "uvu": "^0.5.0"
- }
- },
- "node_modules/micromark-extension-gfm": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz",
- "integrity": "sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==",
- "dependencies": {
- "micromark-extension-gfm-autolink-literal": "^1.0.0",
- "micromark-extension-gfm-footnote": "^1.0.0",
- "micromark-extension-gfm-strikethrough": "^1.0.0",
- "micromark-extension-gfm-table": "^1.0.0",
- "micromark-extension-gfm-tagfilter": "^1.0.0",
- "micromark-extension-gfm-task-list-item": "^1.0.0",
- "micromark-util-combine-extensions": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/micromark-extension-gfm-autolink-literal": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz",
- "integrity": "sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==",
- "dependencies": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-sanitize-uri": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/micromark-extension-gfm-footnote": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz",
- "integrity": "sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==",
- "dependencies": {
- "micromark-core-commonmark": "^1.0.0",
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-normalize-identifier": "^1.0.0",
- "micromark-util-sanitize-uri": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/micromark-extension-gfm-strikethrough": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz",
- "integrity": "sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==",
- "dependencies": {
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-classify-character": "^1.0.0",
- "micromark-util-resolve-all": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/micromark-extension-gfm-table": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz",
- "integrity": "sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==",
- "dependencies": {
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/micromark-extension-gfm-tagfilter": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz",
- "integrity": "sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==",
- "dependencies": {
- "micromark-util-types": "^1.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/micromark-extension-gfm-task-list-item": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz",
- "integrity": "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==",
- "dependencies": {
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/micromark-factory-destination": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz",
- "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "node_modules/micromark-factory-label": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz",
- "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
- }
- },
- "node_modules/micromark-factory-space": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz",
- "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "node_modules/micromark-factory-title": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz",
- "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "node_modules/micromark-factory-whitespace": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz",
- "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "node_modules/micromark-util-character": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz",
- "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "node_modules/micromark-util-chunked": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz",
- "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-symbol": "^1.0.0"
- }
- },
- "node_modules/micromark-util-classify-character": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz",
- "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "node_modules/micromark-util-combine-extensions": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz",
- "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "node_modules/micromark-util-decode-numeric-character-reference": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz",
- "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-symbol": "^1.0.0"
- }
- },
- "node_modules/micromark-util-decode-string": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz",
- "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "decode-named-character-reference": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-decode-numeric-character-reference": "^1.0.0",
- "micromark-util-symbol": "^1.0.0"
- }
- },
- "node_modules/micromark-util-encode": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz",
- "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ]
- },
- "node_modules/micromark-util-html-tag-name": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz",
- "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ]
- },
- "node_modules/micromark-util-normalize-identifier": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz",
- "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-symbol": "^1.0.0"
- }
- },
- "node_modules/micromark-util-resolve-all": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz",
- "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-types": "^1.0.0"
- }
- },
- "node_modules/micromark-util-sanitize-uri": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz",
- "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-encode": "^1.0.0",
- "micromark-util-symbol": "^1.0.0"
- }
- },
- "node_modules/micromark-util-subtokenize": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz",
- "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "dependencies": {
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
- }
- },
- "node_modules/micromark-util-symbol": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz",
- "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ]
- },
- "node_modules/micromark-util-types": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz",
- "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ]
- },
"node_modules/micromatch": {
"version": "4.0.5",
+ "devOptional": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.2",
@@ -19131,7 +16539,7 @@
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "devOptional": true,
+ "optional": true,
"engines": {
"node": ">= 0.6"
}
@@ -19140,7 +16548,7 @@
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "devOptional": true,
+ "optional": true,
"dependencies": {
"mime-db": "1.52.0"
},
@@ -19158,8 +16566,8 @@
},
"node_modules/min-indent": {
"version": "1.0.1",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"engines": {
"node": ">=4"
}
@@ -19197,37 +16605,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/minimist-options": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
- "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
- "dev": true,
- "dependencies": {
- "arrify": "^1.0.1",
- "is-plain-obj": "^1.1.0",
- "kind-of": "^6.0.3"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/minipass": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
- "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
+ "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
"engines": {
"node": ">=8"
}
},
- "node_modules/mixme": {
- "version": "0.5.5",
- "resolved": "https://registry.npmjs.org/mixme/-/mixme-0.5.5.tgz",
- "integrity": "sha512-/6IupbRx32s7jjEwHcycXikJwFD5UujbVNuJFkeKLYje+92OvtuPniF6JhnFm5JCTDUhS+kYK3W/4BWYQYXz7w==",
- "dev": true,
- "engines": {
- "node": ">= 8.0.0"
- }
- },
"node_modules/mkdirp": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
@@ -19241,32 +16626,31 @@
}
},
"node_modules/mocha": {
- "version": "10.2.0",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
- "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz",
+ "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==",
"dev": true,
"dependencies": {
- "ansi-colors": "4.1.1",
- "browser-stdout": "1.3.1",
- "chokidar": "3.5.3",
- "debug": "4.3.4",
- "diff": "5.0.0",
- "escape-string-regexp": "4.0.0",
- "find-up": "5.0.0",
- "glob": "7.2.0",
- "he": "1.2.0",
- "js-yaml": "4.1.0",
- "log-symbols": "4.1.0",
- "minimatch": "5.0.1",
- "ms": "2.1.3",
- "nanoid": "3.3.3",
- "serialize-javascript": "6.0.0",
- "strip-json-comments": "3.1.1",
- "supports-color": "8.1.1",
- "workerpool": "6.2.1",
- "yargs": "16.2.0",
- "yargs-parser": "20.2.4",
- "yargs-unparser": "2.0.0"
+ "ansi-colors": "^4.1.3",
+ "browser-stdout": "^1.3.1",
+ "chokidar": "^3.5.3",
+ "debug": "^4.3.5",
+ "diff": "^5.2.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-up": "^5.0.0",
+ "glob": "^8.1.0",
+ "he": "^1.2.0",
+ "js-yaml": "^4.1.0",
+ "log-symbols": "^4.1.0",
+ "minimatch": "^5.1.6",
+ "ms": "^2.1.3",
+ "serialize-javascript": "^6.0.2",
+ "strip-json-comments": "^3.1.1",
+ "supports-color": "^8.1.1",
+ "workerpool": "^6.5.1",
+ "yargs": "^16.2.0",
+ "yargs-parser": "^20.2.9",
+ "yargs-unparser": "^2.0.0"
},
"bin": {
"_mocha": "bin/_mocha",
@@ -19274,10 +16658,6 @@
},
"engines": {
"node": ">= 14.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/mochajs"
}
},
"node_modules/mocha-junit-reporter": {
@@ -19325,10 +16705,36 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
+ "node_modules/mocha/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/mocha/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
"node_modules/mocha/node_modules/diff": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
- "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
+ "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
"dev": true,
"engines": {
"node": ">=0.3.1"
@@ -19346,54 +16752,26 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/mocha/node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/mocha/node_modules/glob": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
- "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
},
"engines": {
- "node": "*"
+ "node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/mocha/node_modules/glob/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
"node_modules/mocha/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -19415,25 +16793,10 @@
"js-yaml": "bin/js-yaml.js"
}
},
- "node_modules/mocha/node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/mocha/node_modules/minimatch": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
- "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
@@ -19442,81 +16805,12 @@
"node": ">=10"
}
},
- "node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
"node_modules/mocha/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
- "node_modules/mocha/node_modules/nanoid": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
- "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
- "dev": true,
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/mocha/node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/mocha/node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/mocha/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/mocha/node_modules/serialize-javascript": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
- "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
- "dev": true,
- "dependencies": {
- "randombytes": "^2.1.0"
- }
- },
"node_modules/mocha/node_modules/supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
@@ -19592,19 +16886,6 @@
"node": ">=8"
}
},
- "node_modules/mochawesome-merge/node_modules/fs-extra": {
- "version": "7.0.1",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- },
- "engines": {
- "node": ">=6 <7 || >=8"
- }
- },
"node_modules/mochawesome-merge/node_modules/locate-path": {
"version": "5.0.0",
"dev": true,
@@ -19627,14 +16908,6 @@
"node": ">=8"
}
},
- "node_modules/mochawesome-merge/node_modules/path-exists": {
- "version": "4.0.0",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/mochawesome-merge/node_modules/strip-ansi": {
"version": "6.0.1",
"dev": true,
@@ -19910,6 +17183,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
"integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+ "dev": true,
"engines": {
"node": ">=4"
}
@@ -19932,6 +17206,7 @@
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+ "dev": true,
"funding": [
{
"type": "github",
@@ -20065,29 +17340,9 @@
"license": "MIT"
},
"node_modules/node-releases": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
- "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="
- },
- "node_modules/normalize-package-data": {
- "version": "2.5.0",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "hosted-git-info": "^2.1.4",
- "resolve": "^1.10.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
- }
- },
- "node_modules/normalize-package-data/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "bin": {
- "semver": "bin/semver"
- }
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
+ "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g=="
},
"node_modules/normalize-path": {
"version": "3.0.0",
@@ -20390,10 +17645,39 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate/node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/p-map": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+ "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -20406,6 +17690,12 @@
"node": ">=6"
}
},
+ "node_modules/package-manager-detector": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.2.tgz",
+ "integrity": "sha512-VgXbyrSNsml4eHWIvxxG/nTL4wgybMTXCV2Un/+yEc3aDKKU6nQBZjbeP3Pl3qm9Qg92X/1ng4ffvCeD/zwHgg==",
+ "dev": true
+ },
"node_modules/parent-module": {
"version": "1.0.1",
"license": "MIT",
@@ -20425,8 +17715,9 @@
},
"node_modules/parse-filepath": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
+ "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==",
"dev": true,
- "license": "MIT",
"dependencies": {
"is-absolute": "^1.0.0",
"map-cache": "^0.2.0",
@@ -20453,6 +17744,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/parse-ms": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz",
+ "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/parse5": {
"version": "6.0.1",
"license": "MIT",
@@ -20485,6 +17788,14 @@
"tslib": "^2.0.3"
}
},
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/path-is-absolute": {
"version": "1.0.1",
"devOptional": true,
@@ -20508,8 +17819,9 @@
},
"node_modules/path-root": {
"version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+ "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==",
"dev": true,
- "license": "MIT",
"dependencies": {
"path-root-regex": "^0.1.0"
},
@@ -20519,33 +17831,39 @@
},
"node_modules/path-root-regex": {
"version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/path-scurry": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
- "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dependencies": {
- "lru-cache": "^9.1.1 || ^10.0.0",
+ "lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
- "node": ">=16 || 14 >=14.17"
+ "node": ">=16 || 14 >=14.18"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/path-scurry/node_modules/lru-cache": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz",
- "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==",
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
+ },
+ "node_modules/path-scurry/node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"engines": {
- "node": "14 || >=16.14"
+ "node": ">=16 || 14 >=14.17"
}
},
"node_modules/path-to-regexp": {
@@ -20567,20 +17885,10 @@
"dev": true,
"license": "MIT"
},
- "node_modules/pause-stream": {
- "version": "0.0.11",
- "dev": true,
- "license": [
- "MIT",
- "Apache2"
- ],
- "dependencies": {
- "through": "~2.3"
- }
- },
"node_modules/picocolors": {
- "version": "1.0.0",
- "license": "ISC"
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
+ "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw=="
},
"node_modules/picomatch": {
"version": "2.3.1",
@@ -20594,8 +17902,9 @@
},
"node_modules/pify": {
"version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=6"
}
@@ -20608,54 +17917,50 @@
"node": ">= 6"
}
},
- "node_modules/pixelmatch": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.3.0.tgz",
- "integrity": "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==",
- "dependencies": {
- "pngjs": "^6.0.0"
- },
- "bin": {
- "pixelmatch": "bin/pixelmatch"
- }
- },
"node_modules/playwright": {
- "version": "1.40.0",
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.40.0.tgz",
- "integrity": "sha512-gyHAgQjiDf1m34Xpwzaqb76KgfzYrhK7iih+2IzcOCoZWr/8ZqmdBw+t0RU85ZmfJMgtgAiNtBQ/KS2325INXw==",
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0.tgz",
+ "integrity": "sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A==",
"dev": true,
"dependencies": {
- "playwright-core": "1.40.0"
+ "playwright-core": "1.49.0"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
- "node": ">=16"
+ "node": ">=18"
},
"optionalDependencies": {
"fsevents": "2.3.2"
}
},
"node_modules/playwright-core": {
- "version": "1.40.0",
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.40.0.tgz",
- "integrity": "sha512-fvKewVJpGeca8t0ipM56jkVSU6Eo0RmFvQ/MaCQNDYm+sdvKkMBBWTE1FdeMqIdumRaXXjZChWHvIzCGM/tA/Q==",
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0.tgz",
+ "integrity": "sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA==",
"dev": true,
"bin": {
"playwright-core": "cli.js"
},
"engines": {
- "node": ">=16"
+ "node": ">=18"
}
},
+ "node_modules/playwright-ctrf-json-reporter": {
+ "version": "0.0.18",
+ "resolved": "https://registry.npmjs.org/playwright-ctrf-json-reporter/-/playwright-ctrf-json-reporter-0.0.18.tgz",
+ "integrity": "sha512-AjFNpIMKI8zeyaktA2LBphYzy3ffiBjXobBXxEfrVUDov/Z8v5+y9FI0m3cBCr8yauk2brN+Er225vHsZDIu0g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/playwright-testmo-reporter": {
- "version": "1.8.4",
- "resolved": "https://registry.npmjs.org/playwright-testmo-reporter/-/playwright-testmo-reporter-1.8.4.tgz",
- "integrity": "sha512-j0q52X66NtV/Fikaq+dWBnNwP1pq1ouiEHmvMypohb+HHKvcVYw9yBs32A6s1BwzBn9SvaLCaG4F6QC6dr0taw==",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/playwright-testmo-reporter/-/playwright-testmo-reporter-1.11.0.tgz",
+ "integrity": "sha512-pGsh1VQ57sWOSdVCh/2PHJXTi9CDw1Tf72Gk97qd6gBxg9LK3kjXnL7nF0iRoKCL2ML890PgyayLgLIboWfLGQ==",
"dev": true,
"dependencies": {
- "fast-xml-parser": "^4.2.7"
+ "fast-xml-parser": "^4.4.1"
},
"peerDependencies": {
"@playwright/test": "^1.36.2",
@@ -20684,14 +17989,6 @@
"semver-compare": "^1.0.0"
}
},
- "node_modules/pngjs": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz",
- "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==",
- "engines": {
- "node": ">=12.13.0"
- }
- },
"node_modules/popper.js": {
"version": "1.16.1-lts",
"license": "MIT"
@@ -20774,91 +18071,6 @@
"url": "https://opencollective.com/preact"
}
},
- "node_modules/preferred-pm": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/preferred-pm/-/preferred-pm-3.0.3.tgz",
- "integrity": "sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==",
- "dev": true,
- "dependencies": {
- "find-up": "^5.0.0",
- "find-yarn-workspace-root2": "1.2.16",
- "path-exists": "^4.0.0",
- "which-pm": "2.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/preferred-pm/node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/preferred-pm/node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/preferred-pm/node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/preferred-pm/node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/preferred-pm/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/prettier": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
@@ -20909,6 +18121,21 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/pretty-ms": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.1.0.tgz",
+ "integrity": "sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==",
+ "dev": true,
+ "dependencies": {
+ "parse-ms": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/progress": {
"version": "2.0.3",
"license": "MIT",
@@ -20918,8 +18145,9 @@
},
"node_modules/promise": {
"version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
"dev": true,
- "license": "MIT",
"dependencies": {
"asap": "~2.0.3"
}
@@ -21027,20 +18255,6 @@
"version": "1.1.0",
"license": "MIT"
},
- "node_modules/ps-tree": {
- "version": "1.2.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "event-stream": "=3.3.4"
- },
- "bin": {
- "ps-tree": "bin/ps-tree.js"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
"node_modules/pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
@@ -21110,6 +18324,7 @@
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
"funding": [
{
"type": "github",
@@ -21127,8 +18342,9 @@
},
"node_modules/randombytes": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
- "license": "MIT",
"dependencies": {
"safe-buffer": "^5.1.0"
}
@@ -21154,10 +18370,6 @@
"react": "^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
}
},
- "node_modules/react-display-name": {
- "version": "0.2.5",
- "license": "MIT"
- },
"node_modules/react-dom": {
"version": "17.0.2",
"license": "MIT",
@@ -21178,18 +18390,6 @@
"object-assign": "^4.1.1"
}
},
- "node_modules/react-draggable": {
- "version": "4.4.5",
- "license": "MIT",
- "dependencies": {
- "clsx": "^1.1.1",
- "prop-types": "^15.8.1"
- },
- "peerDependencies": {
- "react": ">= 16.3.0",
- "react-dom": ">= 16.3.0"
- }
- },
"node_modules/react-dropzone": {
"version": "11.3.2",
"license": "MIT",
@@ -21268,16 +18468,6 @@
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
- "node_modules/react-github-btn": {
- "version": "1.4.0",
- "license": "BSD-2-Clause",
- "dependencies": {
- "github-buttons": "^2.22.0"
- },
- "peerDependencies": {
- "react": ">=16.3.0"
- }
- },
"node_modules/react-gtm-module": {
"version": "2.0.11",
"license": "MIT"
@@ -21372,45 +18562,6 @@
"version": "17.0.2",
"license": "MIT"
},
- "node_modules/react-jss": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "@emotion/is-prop-valid": "^0.7.3",
- "css-jss": "10.6.0",
- "hoist-non-react-statics": "^3.2.0",
- "is-in-browser": "^1.1.3",
- "jss": "10.6.0",
- "jss-preset-default": "10.6.0",
- "prop-types": "^15.6.0",
- "shallow-equal": "^1.2.0",
- "theming": "^3.3.0",
- "tiny-warning": "^1.0.2"
- },
- "peerDependencies": {
- "react": ">=15"
- }
- },
- "node_modules/react-jss/node_modules/csstype": {
- "version": "3.0.7",
- "license": "MIT"
- },
- "node_modules/react-jss/node_modules/jss": {
- "version": "10.6.0",
- "license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/jss"
- }
- },
"node_modules/react-moment": {
"version": "1.1.1",
"license": "MIT",
@@ -21433,10 +18584,11 @@
}
},
"node_modules/react-remove-scroll": {
- "version": "2.5.5",
- "license": "MIT",
+ "version": "2.5.7",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz",
+ "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==",
"dependencies": {
- "react-remove-scroll-bar": "^2.3.3",
+ "react-remove-scroll-bar": "^2.3.4",
"react-style-singleton": "^2.2.1",
"tslib": "^2.1.0",
"use-callback-ref": "^1.3.0",
@@ -21624,102 +18776,6 @@
"react-dom": ">=16.6.0"
}
},
- "node_modules/read-pkg": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
- "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
- "dev": true,
- "dependencies": {
- "@types/normalize-package-data": "^2.4.0",
- "normalize-package-data": "^2.5.0",
- "parse-json": "^5.0.0",
- "type-fest": "^0.6.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg-up": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
- "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
- "dev": true,
- "dependencies": {
- "find-up": "^4.1.0",
- "read-pkg": "^5.2.0",
- "type-fest": "^0.8.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/read-pkg-up/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg-up/node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg-up/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg-up/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg-up/node_modules/type-fest": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
- "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg/node_modules/type-fest": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
- "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/read-yaml-file": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz",
@@ -21762,8 +18818,8 @@
},
"node_modules/redent": {
"version": "3.0.0",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
"indent-string": "^4.0.0",
"strip-indent": "^3.0.0"
@@ -21772,11 +18828,6 @@
"node": ">=8"
}
},
- "node_modules/regenerator-runtime": {
- "version": "0.11.1",
- "dev": true,
- "license": "MIT"
- },
"node_modules/regexp-tree": {
"version": "0.1.24",
"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz",
@@ -21810,204 +18861,17 @@
"node": ">= 0.10"
}
},
- "node_modules/relay-compiler": {
- "version": "11.0.2",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.0.0",
- "@babel/generator": "^7.5.0",
- "@babel/parser": "^7.0.0",
- "@babel/runtime": "^7.0.0",
- "@babel/traverse": "^7.0.0",
- "@babel/types": "^7.0.0",
- "babel-preset-fbjs": "^3.3.0",
- "chalk": "^4.0.0",
- "fb-watchman": "^2.0.0",
- "fbjs": "^3.0.0",
- "glob": "^7.1.1",
- "immutable": "~3.7.6",
- "invariant": "^2.2.4",
- "nullthrows": "^1.1.1",
- "relay-runtime": "11.0.2",
- "signedsource": "^1.0.0",
- "yargs": "^15.3.1"
- },
- "bin": {
- "relay-compiler": "bin/relay-compiler"
- },
- "peerDependencies": {
- "graphql": "^15.0.0"
- }
- },
- "node_modules/relay-compiler/node_modules/chalk": {
- "version": "4.1.2",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/relay-compiler/node_modules/cliui": {
- "version": "6.0.0",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^6.2.0"
- }
- },
- "node_modules/relay-compiler/node_modules/find-up": {
- "version": "4.1.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/relay-compiler/node_modules/has-flag": {
- "version": "4.0.0",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/relay-compiler/node_modules/locate-path": {
- "version": "5.0.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/relay-compiler/node_modules/p-locate": {
- "version": "4.1.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/relay-compiler/node_modules/path-exists": {
- "version": "4.0.0",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/relay-compiler/node_modules/strip-ansi": {
- "version": "6.0.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^5.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/relay-compiler/node_modules/supports-color": {
- "version": "7.2.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/relay-compiler/node_modules/wrap-ansi": {
- "version": "6.2.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/relay-compiler/node_modules/yargs": {
- "version": "15.4.1",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cliui": "^6.0.0",
- "decamelize": "^1.2.0",
- "find-up": "^4.1.0",
- "get-caller-file": "^2.0.1",
- "require-directory": "^2.1.1",
- "require-main-filename": "^2.0.0",
- "set-blocking": "^2.0.0",
- "string-width": "^4.2.0",
- "which-module": "^2.0.0",
- "y18n": "^4.0.0",
- "yargs-parser": "^18.1.2"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/relay-compiler/node_modules/yargs-parser": {
- "version": "18.1.3",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/relay-runtime": {
- "version": "11.0.2",
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-12.0.0.tgz",
+ "integrity": "sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug==",
"dev": true,
- "license": "MIT",
"dependencies": {
"@babel/runtime": "^7.0.0",
"fbjs": "^3.0.0",
"invariant": "^2.2.4"
}
},
- "node_modules/remark-gfm": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz",
- "integrity": "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==",
- "dependencies": {
- "@types/mdast": "^3.0.0",
- "mdast-util-gfm": "^2.0.0",
- "micromark-extension-gfm": "^2.0.0",
- "unified": "^10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
"node_modules/remedial": {
"version": "1.0.8",
"dev": true,
@@ -22027,17 +18891,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/require-context.macro": {
- "version": "1.2.2",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/webpack-env": "^1.14.0"
- },
- "peerDependencies": {
- "babel-plugin-macros": "^2.4.2"
- }
- },
"node_modules/require-directory": {
"version": "2.1.1",
"devOptional": true,
@@ -22140,6 +18993,7 @@
},
"node_modules/reusify": {
"version": "1.0.4",
+ "dev": true,
"license": "MIT",
"engines": {
"iojs": ">=1.0.0",
@@ -22219,6 +19073,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
"funding": [
{
"type": "github",
@@ -22239,8 +19094,8 @@
},
"node_modules/rxjs": {
"version": "6.6.7",
- "devOptional": true,
"license": "Apache-2.0",
+ "optional": true,
"dependencies": {
"tslib": "^1.9.0"
},
@@ -22252,21 +19107,12 @@
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "devOptional": true
- },
- "node_modules/sade": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
- "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
- "dependencies": {
- "mri": "^1.1.0"
- },
- "engines": {
- "node": ">=6"
- }
+ "optional": true
},
"node_modules/safe-buffer": {
"version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true,
"funding": [
{
@@ -22281,8 +19127,7 @@
"type": "consulting",
"url": "https://feross.org/support"
}
- ],
- "license": "MIT"
+ ]
},
"node_modules/safe-regex-test": {
"version": "1.0.0",
@@ -22302,12 +19147,6 @@
"devOptional": true,
"license": "MIT"
},
- "node_modules/sax": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
- "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
- "dev": true
- },
"node_modules/saxes": {
"version": "5.0.1",
"license": "ISC",
@@ -22376,6 +19215,15 @@
"tslib": "^2.0.3"
}
},
+ "node_modules/serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "dev": true,
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
"node_modules/set-blocking": {
"version": "2.0.0",
"dev": true,
@@ -22383,8 +19231,9 @@
},
"node_modules/setimmediate": {
"version": "1.0.5",
- "dev": true,
- "license": "MIT"
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+ "dev": true
},
"node_modules/setprototypeof": {
"version": "1.2.0",
@@ -22400,14 +19249,11 @@
"@pollyjs/core": "*"
}
},
- "node_modules/shallow-equal": {
- "version": "1.2.1",
- "license": "MIT"
- },
"node_modules/shebang-command": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
"dev": true,
- "license": "MIT",
"dependencies": {
"shebang-regex": "^1.0.0"
},
@@ -22417,8 +19263,9 @@
},
"node_modules/shebang-regex": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -22452,16 +19299,9 @@
},
"node_modules/signedsource": {
"version": "1.0.0",
- "dev": true,
- "license": "BSD-3-Clause"
- },
- "node_modules/simple-bin-help": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/simple-bin-help/-/simple-bin-help-1.8.0.tgz",
- "integrity": "sha512-0LxHn+P1lF5r2WwVB/za3hLRIsYoLaNq1CXqjbrs3ZvLuvlWnRKrUjEWzV7umZL7hpQ7xULiQMV+0iXdRa5iFg==",
- "engines": {
- "node": ">=14.16"
- }
+ "resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz",
+ "integrity": "sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==",
+ "dev": true
},
"node_modules/sisteransi": {
"version": "1.0.5",
@@ -22470,6 +19310,7 @@
},
"node_modules/slash": {
"version": "3.0.0",
+ "devOptional": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -22496,142 +19337,16 @@
"node": ">=8.0.0"
}
},
- "node_modules/smartwrap": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/smartwrap/-/smartwrap-2.0.2.tgz",
- "integrity": "sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==",
- "dev": true,
- "dependencies": {
- "array.prototype.flat": "^1.2.3",
- "breakword": "^1.0.5",
- "grapheme-splitter": "^1.0.4",
- "strip-ansi": "^6.0.0",
- "wcwidth": "^1.0.1",
- "yargs": "^15.1.0"
- },
- "bin": {
- "smartwrap": "src/terminal-adapter.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/smartwrap/node_modules/cliui": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
- "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^6.2.0"
- }
- },
- "node_modules/smartwrap/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/smartwrap/node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "dependencies": {
- "p-locate": "^4.1.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/smartwrap/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/smartwrap/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/smartwrap/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/smartwrap/node_modules/wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/smartwrap/node_modules/yargs": {
- "version": "15.4.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
- "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "node_modules/smol-toml": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.0.tgz",
+ "integrity": "sha512-tWpi2TsODPScmi48b/OQZGi2lgUmBCHy6SZrhi/FdnnHiU1GwebbCfuQuxsC3nHaLwtYeJGPrDZDIeodDOc4pA==",
"dev": true,
- "dependencies": {
- "cliui": "^6.0.0",
- "decamelize": "^1.2.0",
- "find-up": "^4.1.0",
- "get-caller-file": "^2.0.1",
- "require-directory": "^2.1.1",
- "require-main-filename": "^2.0.0",
- "set-blocking": "^2.0.0",
- "string-width": "^4.2.0",
- "which-module": "^2.0.0",
- "y18n": "^4.0.0",
- "yargs-parser": "^18.1.2"
- },
"engines": {
- "node": ">=8"
- }
- },
- "node_modules/smartwrap/node_modules/yargs-parser": {
- "version": "18.1.3",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
- "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
- "dev": true,
- "dependencies": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
+ "node": ">= 18"
},
- "engines": {
- "node": ">=6"
+ "funding": {
+ "url": "https://github.com/sponsors/cyyynthia"
}
},
"node_modules/snake-case": {
@@ -22643,11 +19358,6 @@
"tslib": "^2.0.3"
}
},
- "node_modules/source-list-map": {
- "version": "2.0.1",
- "dev": true,
- "license": "MIT"
- },
"node_modules/source-map": {
"version": "0.5.7",
"license": "BSD-3-Clause",
@@ -22722,45 +19432,6 @@
"integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==",
"dev": true
},
- "node_modules/spdx-correct": {
- "version": "3.1.1",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-exceptions": {
- "version": "2.3.0",
- "dev": true,
- "license": "CC-BY-3.0"
- },
- "node_modules/spdx-expression-parse": {
- "version": "3.0.1",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-license-ids": {
- "version": "3.0.7",
- "dev": true,
- "license": "CC0-1.0"
- },
- "node_modules/split": {
- "version": "0.3.3",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "through": "2"
- },
- "engines": {
- "node": "*"
- }
- },
"node_modules/sponge-case": {
"version": "1.0.1",
"dev": true,
@@ -22792,73 +19463,6 @@
"node": ">=8"
}
},
- "node_modules/start-server-and-test": {
- "version": "1.12.1",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "bluebird": "3.7.2",
- "check-more-types": "2.24.0",
- "debug": "4.3.1",
- "execa": "3.4.0",
- "lazy-ass": "1.6.0",
- "ps-tree": "1.2.0",
- "wait-on": "5.3.0"
- },
- "bin": {
- "server-test": "src/bin/start.js",
- "start-server-and-test": "src/bin/start.js",
- "start-test": "src/bin/start.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/start-server-and-test/node_modules/debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "dev": true,
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/start-server-and-test/node_modules/execa": {
- "version": "3.4.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^7.0.0",
- "get-stream": "^5.0.0",
- "human-signals": "^1.1.1",
- "is-stream": "^2.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^4.0.0",
- "onetime": "^5.1.0",
- "p-finally": "^2.0.0",
- "signal-exit": "^3.0.2",
- "strip-final-newline": "^2.0.0"
- },
- "engines": {
- "node": "^8.12.0 || >=9.7.0"
- }
- },
- "node_modules/start-server-and-test/node_modules/p-finally": {
- "version": "2.0.1",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@@ -22868,31 +19472,6 @@
"node": ">= 0.8"
}
},
- "node_modules/stream-combiner": {
- "version": "0.0.4",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "duplexer": "~0.1.1"
- }
- },
- "node_modules/stream-events": {
- "version": "1.0.5",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "stubs": "^3.0.0"
- }
- },
- "node_modules/stream-transform": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/stream-transform/-/stream-transform-2.1.3.tgz",
- "integrity": "sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==",
- "dev": true,
- "dependencies": {
- "mixme": "^0.5.1"
- }
- },
"node_modules/streamsearch": {
"version": "1.1.0",
"dev": true,
@@ -23071,8 +19650,8 @@
},
"node_modules/strip-indent": {
"version": "3.0.0",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
"min-indent": "^1.0.0"
},
@@ -23097,16 +19676,17 @@
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==",
"dev": true
},
- "node_modules/stubs": {
- "version": "3.0.0",
- "dev": true,
- "license": "MIT"
- },
"node_modules/stylis": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
"integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
},
+ "node_modules/summary": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/summary/-/summary-2.1.0.tgz",
+ "integrity": "sha512-nMIjMrd5Z2nuB2RZCKJfFMjgS3fygbeyGk9PxPPaJR1RIcyN9yn4A63Isovzm3ZtQuEkLBVgMdPup8UeLH7aQw==",
+ "dev": true
+ },
"node_modules/supports-color": {
"version": "5.5.0",
"license": "MIT",
@@ -23220,48 +19800,6 @@
"integrity": "sha512-29aQwaHqm8RMX74u2o/h1KbMLP89FjNiMxD9wbF2BbWOnbM+q+d1sCEC+MqCc4QW3NJykn77OMpTFw/xTHIc0w==",
"dev": true
},
- "node_modules/teeny-request": {
- "version": "6.0.1",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "http-proxy-agent": "^4.0.0",
- "https-proxy-agent": "^4.0.0",
- "node-fetch": "^2.2.0",
- "stream-events": "^1.0.5",
- "uuid": "^3.3.2"
- }
- },
- "node_modules/teeny-request/node_modules/agent-base": {
- "version": "5.1.1",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 6.0.0"
- }
- },
- "node_modules/teeny-request/node_modules/https-proxy-agent": {
- "version": "4.0.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "agent-base": "5",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6.0.0"
- }
- },
- "node_modules/teeny-request/node_modules/uuid": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
- "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
- "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
- "dev": true,
- "bin": {
- "uuid": "bin/uuid"
- }
- },
"node_modules/term-size": {
"version": "2.2.1",
"dev": true,
@@ -23336,22 +19874,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/theming": {
- "version": "3.3.0",
- "license": "MIT",
- "dependencies": {
- "hoist-non-react-statics": "^3.3.0",
- "prop-types": "^15.5.8",
- "react-display-name": "^0.2.4",
- "tiny-warning": "^1.0.2"
- },
- "engines": {
- "node": ">=8"
- },
- "peerDependencies": {
- "react": ">=16.3"
- }
- },
"node_modules/throat": {
"version": "6.0.2",
"license": "MIT",
@@ -23456,24 +19978,6 @@
"node": ">= 4.0.0"
}
},
- "node_modules/trim-newlines": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
- "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/trough": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz",
- "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/ts-invariant": {
"version": "0.9.4",
"license": "MIT",
@@ -23526,14 +20030,6 @@
}
}
},
- "node_modules/ts-jest/node_modules/yargs-parser": {
- "version": "20.2.9",
- "license": "ISC",
- "optional": true,
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/ts-log": {
"version": "2.2.3",
"dev": true,
@@ -23652,135 +20148,6 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
},
- "node_modules/tty-table": {
- "version": "4.1.6",
- "resolved": "https://registry.npmjs.org/tty-table/-/tty-table-4.1.6.tgz",
- "integrity": "sha512-kRj5CBzOrakV4VRRY5kUWbNYvo/FpOsz65DzI5op9P+cHov3+IqPbo1JE1ZnQGkHdZgNFDsrEjrfqqy/Ply9fw==",
- "dev": true,
- "dependencies": {
- "chalk": "^4.1.2",
- "csv": "^5.5.0",
- "kleur": "^4.1.4",
- "smartwrap": "^2.0.2",
- "strip-ansi": "^6.0.0",
- "wcwidth": "^1.0.1",
- "yargs": "^17.1.1"
- },
- "bin": {
- "tty-table": "adapters/terminal-adapter.js"
- },
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/tty-table/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/tty-table/node_modules/cliui": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
- "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.1",
- "wrap-ansi": "^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/tty-table/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tty-table/node_modules/kleur": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
- "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/tty-table/node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tty-table/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/tty-table/node_modules/y18n": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
- "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/tty-table/node_modules/yargs": {
- "version": "17.7.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
- "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
- "dev": true,
- "dependencies": {
- "cliui": "^8.0.1",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.3",
- "y18n": "^5.0.5",
- "yargs-parser": "^21.1.1"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/tty-table/node_modules/yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "dev": true,
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/type-detect": {
"version": "4.0.8",
"license": "MIT",
@@ -23872,9 +20239,9 @@
}
},
"node_modules/ua-parser-js": {
- "version": "0.7.35",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz",
- "integrity": "sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g==",
+ "version": "1.0.39",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.39.tgz",
+ "integrity": "sha512-k24RCVWlEcjkdOxYmVJgeD/0a1TiSpqLg+ZalVGV9lsnr4yqu0w7tX/x2xX6G4zpkgQnRf89lxuZ1wsbjXM8lw==",
"dev": true,
"funding": [
{
@@ -23884,8 +20251,15 @@
{
"type": "paypal",
"url": "https://paypal.me/faisalman"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/faisalman"
}
],
+ "bin": {
+ "ua-parser-js": "script/cli.js"
+ },
"engines": {
"node": "*"
}
@@ -23923,8 +20297,9 @@
},
"node_modules/unc-path-regex": {
"version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==",
"dev": true,
- "license": "MIT",
"engines": {
"node": ">=0.10.0"
}
@@ -23944,108 +20319,6 @@
"integrity": "sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA==",
"dev": true
},
- "node_modules/unified": {
- "version": "10.1.2",
- "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz",
- "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==",
- "dependencies": {
- "@types/unist": "^2.0.0",
- "bail": "^2.0.0",
- "extend": "^3.0.0",
- "is-buffer": "^2.0.0",
- "is-plain-obj": "^4.0.0",
- "trough": "^2.0.0",
- "vfile": "^5.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/unified/node_modules/is-buffer": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
- "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/unified/node_modules/is-plain-obj": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
- "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/unist-util-is": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
- "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==",
- "dependencies": {
- "@types/unist": "^2.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/unist-util-stringify-position": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz",
- "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==",
- "dependencies": {
- "@types/unist": "^2.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/unist-util-visit": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz",
- "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==",
- "dependencies": {
- "@types/unist": "^2.0.0",
- "unist-util-is": "^5.0.0",
- "unist-util-visit-parents": "^5.1.1"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/unist-util-visit-parents": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz",
- "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==",
- "dependencies": {
- "@types/unist": "^2.0.0",
- "unist-util-is": "^5.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
"node_modules/universalify": {
"version": "0.1.2",
"dev": true,
@@ -24086,10 +20359,32 @@
"node": ">= 0.8"
}
},
+ "node_modules/unplugin": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.0.1.tgz",
+ "integrity": "sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==",
+ "dependencies": {
+ "acorn": "^8.8.1",
+ "chokidar": "^3.5.3",
+ "webpack-sources": "^3.2.3",
+ "webpack-virtual-modules": "^0.5.0"
+ }
+ },
+ "node_modules/unplugin/node_modules/acorn": {
+ "version": "8.12.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
+ "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/update-browserslist-db": {
- "version": "1.0.13",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
- "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
+ "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
"funding": [
{
"type": "opencollective",
@@ -24105,8 +20400,8 @@
}
],
"dependencies": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.0"
},
"bin": {
"update-browserslist-db": "cli.js"
@@ -24153,11 +20448,6 @@
"requires-port": "^1.0.0"
}
},
- "node_modules/urlgrey": {
- "version": "0.4.4",
- "dev": true,
- "license": "BSD-2-Clause"
- },
"node_modules/urlpattern-polyfill": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-6.0.2.tgz",
@@ -24251,39 +20541,6 @@
"uuid": "dist/bin/uuid"
}
},
- "node_modules/uvu": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
- "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==",
- "dependencies": {
- "dequal": "^2.0.0",
- "diff": "^5.0.0",
- "kleur": "^4.0.3",
- "sade": "^1.7.3"
- },
- "bin": {
- "uvu": "bin.js"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/uvu/node_modules/diff": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
- "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==",
- "engines": {
- "node": ">=0.3.1"
- }
- },
- "node_modules/uvu/node_modules/kleur": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
- "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
@@ -24311,15 +20568,6 @@
"node": ">= 8"
}
},
- "node_modules/validate-npm-package-license": {
- "version": "3.0.4",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
- }
- },
"node_modules/validator": {
"version": "13.7.0",
"dev": true,
@@ -24341,56 +20589,6 @@
"node": ">=12"
}
},
- "node_modules/vfile": {
- "version": "5.3.7",
- "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz",
- "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==",
- "dependencies": {
- "@types/unist": "^2.0.0",
- "is-buffer": "^2.0.0",
- "unist-util-stringify-position": "^3.0.0",
- "vfile-message": "^3.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/vfile-message": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz",
- "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==",
- "dependencies": {
- "@types/unist": "^2.0.0",
- "unist-util-stringify-position": "^3.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/vfile/node_modules/is-buffer": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
- "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/vite": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.7.tgz",
@@ -24736,24 +20934,6 @@
"node": ">=10"
}
},
- "node_modules/wait-on": {
- "version": "5.3.0",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "axios": "^0.21.1",
- "joi": "^17.3.0",
- "lodash": "^4.17.21",
- "minimist": "^1.2.5",
- "rxjs": "^6.6.3"
- },
- "bin": {
- "wait-on": "bin/wait-on"
- },
- "engines": {
- "node": ">=8.9.0"
- }
- },
"node_modules/walker": {
"version": "1.0.8",
"license": "Apache-2.0",
@@ -24762,13 +20942,6 @@
"makeerror": "1.0.12"
}
},
- "node_modules/warning": {
- "version": "3.0.0",
- "license": "BSD-3-Clause",
- "dependencies": {
- "loose-envify": "^1.0.0"
- }
- },
"node_modules/watskeburt": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/watskeburt/-/watskeburt-0.10.0.tgz",
@@ -24892,8 +21065,9 @@
},
"node_modules/which": {
"version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
- "license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
@@ -24935,28 +21109,6 @@
"dev": true,
"license": "ISC"
},
- "node_modules/which-pm": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-2.0.0.tgz",
- "integrity": "sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==",
- "dev": true,
- "dependencies": {
- "load-yaml-file": "^0.2.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=8.15"
- }
- },
- "node_modules/which-pm/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/which-typed-array": {
"version": "1.1.8",
"license": "MIT",
@@ -24992,9 +21144,9 @@
"dev": true
},
"node_modules/workerpool": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
- "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz",
+ "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==",
"dev": true
},
"node_modules/wrap-ansi": {
@@ -25059,45 +21211,11 @@
"license": "Apache-2.0",
"optional": true
},
- "node_modules/xmlbuilder2": {
- "version": "3.0.2",
- "license": "MIT",
- "dependencies": {
- "@oozcitak/dom": "1.15.10",
- "@oozcitak/infra": "1.0.8",
- "@oozcitak/util": "8.3.8",
- "@types/node": "*",
- "js-yaml": "3.14.0"
- },
- "engines": {
- "node": ">=12.0"
- }
- },
- "node_modules/xmlbuilder2/node_modules/js-yaml": {
- "version": "3.14.0",
- "license": "MIT",
- "dependencies": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
"node_modules/xmlchars": {
"version": "2.2.0",
"license": "MIT",
"optional": true
},
- "node_modules/xmldoc": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.3.0.tgz",
- "integrity": "sha512-y7IRWW6PvEnYQZNZFMRLNJw+p3pezM4nKYPfr15g4OOW9i8VpeydycFuipE2297OvZnh3jSb2pxOt9QpkZUVng==",
- "dev": true,
- "dependencies": {
- "sax": "^1.2.4"
- }
- },
"node_modules/y18n": {
"version": "4.0.3",
"dev": true,
@@ -25140,9 +21258,9 @@
}
},
"node_modules/yargs-parser": {
- "version": "20.2.4",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
- "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
"devOptional": true,
"engines": {
"node": ">=10"
@@ -25244,21 +21362,24 @@
"url": "https://github.com/sponsors/colinhacks"
}
},
- "node_modules/zwitch": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
- "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
+ "node_modules/zod-validation-error": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.4.0.tgz",
+ "integrity": "sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "zod": "^3.18.0"
}
}
},
"dependencies": {
"@adobe/css-tools": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.1.tgz",
- "integrity": "sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz",
+ "integrity": "sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==",
"optional": true
},
"@ampproject/remapping": {
@@ -25294,6 +21415,146 @@
}
}
},
+ "@ardatan/relay-compiler": {
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/@ardatan/relay-compiler/-/relay-compiler-12.0.0.tgz",
+ "integrity": "sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.14.0",
+ "@babel/generator": "^7.14.0",
+ "@babel/parser": "^7.14.0",
+ "@babel/runtime": "^7.0.0",
+ "@babel/traverse": "^7.14.0",
+ "@babel/types": "^7.0.0",
+ "babel-preset-fbjs": "^3.4.0",
+ "chalk": "^4.0.0",
+ "fb-watchman": "^2.0.0",
+ "fbjs": "^3.0.0",
+ "glob": "^7.1.1",
+ "immutable": "~3.7.6",
+ "invariant": "^2.2.4",
+ "nullthrows": "^1.1.1",
+ "relay-runtime": "12.0.0",
+ "signedsource": "^1.0.0",
+ "yargs": "^15.3.1"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "yargs": {
+ "version": "15.4.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "dev": true,
+ "requires": {
+ "cliui": "^6.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^4.1.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^4.2.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^18.1.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ },
"@ardatan/sync-fetch": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/@ardatan/sync-fetch/-/sync-fetch-0.0.1.tgz",
@@ -25304,18 +21565,18 @@
}
},
"@babel/code-frame": {
- "version": "7.24.2",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
- "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
+ "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
"requires": {
- "@babel/highlight": "^7.24.2",
+ "@babel/highlight": "^7.24.7",
"picocolors": "^1.0.0"
}
},
"@babel/compat-data": {
- "version": "7.24.4",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.4.tgz",
- "integrity": "sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ=="
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz",
+ "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ=="
},
"@babel/core": {
"version": "7.23.2",
@@ -25352,33 +21613,33 @@
}
},
"@babel/generator": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
- "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
+ "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
"requires": {
- "@babel/types": "^7.23.0",
- "@jridgewell/gen-mapping": "^0.3.2",
- "@jridgewell/trace-mapping": "^0.3.17",
+ "@babel/types": "^7.25.6",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^2.5.1"
}
},
"@babel/helper-annotate-as-pure": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
- "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz",
+ "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==",
"dev": true,
"requires": {
- "@babel/types": "^7.22.5"
+ "@babel/types": "^7.24.7"
}
},
"@babel/helper-compilation-targets": {
- "version": "7.23.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz",
- "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==",
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz",
+ "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==",
"requires": {
- "@babel/compat-data": "^7.23.5",
- "@babel/helper-validator-option": "^7.23.5",
- "browserslist": "^4.22.2",
+ "@babel/compat-data": "^7.25.2",
+ "@babel/helper-validator-option": "^7.24.8",
+ "browserslist": "^4.23.1",
"lru-cache": "^5.1.1",
"semver": "^6.3.1"
},
@@ -25404,19 +21665,17 @@
}
},
"@babel/helper-create-class-features-plugin": {
- "version": "7.24.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.4.tgz",
- "integrity": "sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ==",
- "dev": true,
- "requires": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-member-expression-to-functions": "^7.23.0",
- "@babel/helper-optimise-call-expression": "^7.22.5",
- "@babel/helper-replace-supers": "^7.24.1",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz",
+ "integrity": "sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.24.7",
+ "@babel/helper-member-expression-to-functions": "^7.24.8",
+ "@babel/helper-optimise-call-expression": "^7.24.7",
+ "@babel/helper-replace-supers": "^7.25.0",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7",
+ "@babel/traverse": "^7.25.4",
"semver": "^6.3.1"
},
"dependencies": {
@@ -25428,121 +21687,95 @@
}
}
},
- "@babel/helper-environment-visitor": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
- "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA=="
- },
- "@babel/helper-function-name": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
- "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
- "requires": {
- "@babel/template": "^7.22.15",
- "@babel/types": "^7.23.0"
- }
- },
- "@babel/helper-hoist-variables": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
- "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
- "requires": {
- "@babel/types": "^7.22.5"
- }
- },
"@babel/helper-member-expression-to-functions": {
- "version": "7.23.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz",
- "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz",
+ "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==",
"dev": true,
"requires": {
- "@babel/types": "^7.23.0"
+ "@babel/traverse": "^7.24.8",
+ "@babel/types": "^7.24.8"
}
},
"@babel/helper-module-imports": {
- "version": "7.24.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz",
- "integrity": "sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
+ "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
"requires": {
- "@babel/types": "^7.24.0"
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
}
},
"@babel/helper-module-transforms": {
- "version": "7.23.3",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
- "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz",
+ "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==",
"requires": {
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-module-imports": "^7.22.15",
- "@babel/helper-simple-access": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/helper-validator-identifier": "^7.22.20"
+ "@babel/helper-module-imports": "^7.24.7",
+ "@babel/helper-simple-access": "^7.24.7",
+ "@babel/helper-validator-identifier": "^7.24.7",
+ "@babel/traverse": "^7.25.2"
}
},
"@babel/helper-optimise-call-expression": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz",
- "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz",
+ "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==",
"dev": true,
"requires": {
- "@babel/types": "^7.22.5"
+ "@babel/types": "^7.24.7"
}
},
"@babel/helper-plugin-utils": {
- "version": "7.24.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz",
- "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w=="
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz",
+ "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==",
+ "devOptional": true
},
"@babel/helper-replace-supers": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz",
- "integrity": "sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==",
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz",
+ "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==",
"dev": true,
"requires": {
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-member-expression-to-functions": "^7.23.0",
- "@babel/helper-optimise-call-expression": "^7.22.5"
+ "@babel/helper-member-expression-to-functions": "^7.24.8",
+ "@babel/helper-optimise-call-expression": "^7.24.7",
+ "@babel/traverse": "^7.25.0"
}
},
"@babel/helper-simple-access": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
- "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
+ "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
"requires": {
- "@babel/types": "^7.22.5"
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
}
},
"@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz",
- "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz",
+ "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==",
"dev": true,
"requires": {
- "@babel/types": "^7.22.5"
- }
- },
- "@babel/helper-split-export-declaration": {
- "version": "7.22.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
- "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
- "requires": {
- "@babel/types": "^7.22.5"
+ "@babel/traverse": "^7.24.7",
+ "@babel/types": "^7.24.7"
}
},
"@babel/helper-string-parser": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
- "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ=="
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
+ "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ=="
},
"@babel/helper-validator-identifier": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
- "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A=="
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
+ "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w=="
},
"@babel/helper-validator-option": {
- "version": "7.23.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz",
- "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw=="
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz",
+ "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q=="
},
"@babel/helpers": {
"version": "7.23.2",
@@ -25555,20 +21788,23 @@
}
},
"@babel/highlight": {
- "version": "7.24.2",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz",
- "integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
+ "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
"requires": {
- "@babel/helper-validator-identifier": "^7.22.20",
+ "@babel/helper-validator-identifier": "^7.24.7",
"chalk": "^2.4.2",
"js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
}
},
"@babel/parser": {
- "version": "7.24.4",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz",
- "integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg=="
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
+ "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
+ "requires": {
+ "@babel/types": "^7.25.6"
+ }
},
"@babel/plugin-proposal-class-properties": {
"version": "7.18.6",
@@ -25615,10 +21851,12 @@
}
},
"@babel/plugin-syntax-flow": {
- "version": "7.12.13",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.7.tgz",
+ "integrity": "sha512-9G8GYT/dxn/D1IIKOUBmGX0mnmj46mGH9NnZyJLwtCpgh5f7D2VbuKodb+2s9m1Yavh1s7ASQN8lf0eqrb1LTw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.24.7"
}
},
"@babel/plugin-syntax-import-assertions": {
@@ -25645,11 +21883,12 @@
}
},
"@babel/plugin-syntax-jsx": {
- "version": "7.21.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz",
- "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz",
+ "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==",
+ "dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.20.2"
+ "@babel/helper-plugin-utils": "^7.24.7"
}
},
"@babel/plugin-syntax-logical-assignment-operators": {
@@ -25711,250 +21950,249 @@
}
},
"@babel/plugin-transform-arrow-functions": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz",
- "integrity": "sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz",
+ "integrity": "sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
}
},
"@babel/plugin-transform-block-scoped-functions": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz",
- "integrity": "sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz",
+ "integrity": "sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
}
},
"@babel/plugin-transform-block-scoping": {
- "version": "7.24.4",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.4.tgz",
- "integrity": "sha512-nIFUZIpGKDf9O9ttyRXpHFpKC+X3Y5mtshZONuEUYBomAKoM4y029Jr+uB1bHGPhNmK8YXHevDtKDOLmtRrp6g==",
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz",
+ "integrity": "sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.8"
}
},
"@babel/plugin-transform-classes": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz",
- "integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==",
+ "version": "7.25.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz",
+ "integrity": "sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg==",
"dev": true,
"requires": {
- "@babel/helper-annotate-as-pure": "^7.22.5",
- "@babel/helper-compilation-targets": "^7.23.6",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-plugin-utils": "^7.24.0",
- "@babel/helper-replace-supers": "^7.24.1",
- "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/helper-annotate-as-pure": "^7.24.7",
+ "@babel/helper-compilation-targets": "^7.25.2",
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/helper-replace-supers": "^7.25.0",
+ "@babel/traverse": "^7.25.4",
"globals": "^11.1.0"
}
},
"@babel/plugin-transform-computed-properties": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz",
- "integrity": "sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz",
+ "integrity": "sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0",
- "@babel/template": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/template": "^7.24.7"
}
},
"@babel/plugin-transform-destructuring": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz",
- "integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz",
+ "integrity": "sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.8"
}
},
"@babel/plugin-transform-flow-strip-types": {
- "version": "7.13.0",
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.25.2.tgz",
+ "integrity": "sha512-InBZ0O8tew5V0K6cHcQ+wgxlrjOw1W4wDXLkOTjLRD8GYhTSkxTVBtdy3MMtvYBrbAWa1Qm3hNoTc1620Yj+Mg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.13.0",
- "@babel/plugin-syntax-flow": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/plugin-syntax-flow": "^7.24.7"
}
},
"@babel/plugin-transform-for-of": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz",
- "integrity": "sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz",
+ "integrity": "sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7"
}
},
"@babel/plugin-transform-function-name": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz",
- "integrity": "sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==",
+ "version": "7.25.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz",
+ "integrity": "sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==",
"dev": true,
"requires": {
- "@babel/helper-compilation-targets": "^7.23.6",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-compilation-targets": "^7.24.8",
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/traverse": "^7.25.1"
}
},
"@babel/plugin-transform-literals": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz",
- "integrity": "sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==",
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz",
+ "integrity": "sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.8"
}
},
"@babel/plugin-transform-member-expression-literals": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz",
- "integrity": "sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz",
+ "integrity": "sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
}
},
"@babel/plugin-transform-modules-commonjs": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz",
- "integrity": "sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==",
+ "version": "7.24.8",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz",
+ "integrity": "sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==",
"dev": true,
"requires": {
- "@babel/helper-module-transforms": "^7.23.3",
- "@babel/helper-plugin-utils": "^7.24.0",
- "@babel/helper-simple-access": "^7.22.5"
+ "@babel/helper-module-transforms": "^7.24.8",
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/helper-simple-access": "^7.24.7"
}
},
"@babel/plugin-transform-object-super": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz",
- "integrity": "sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz",
+ "integrity": "sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0",
- "@babel/helper-replace-supers": "^7.24.1"
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-replace-supers": "^7.24.7"
}
},
"@babel/plugin-transform-parameters": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz",
- "integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz",
+ "integrity": "sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
}
},
"@babel/plugin-transform-property-literals": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz",
- "integrity": "sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz",
+ "integrity": "sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
}
},
"@babel/plugin-transform-react-display-name": {
- "version": "7.12.13",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz",
+ "integrity": "sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.12.13"
+ "@babel/helper-plugin-utils": "^7.24.7"
}
},
"@babel/plugin-transform-react-jsx": {
- "version": "7.21.5",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.5.tgz",
- "integrity": "sha512-ELdlq61FpoEkHO6gFRpfj0kUgSwQTGoaEU8eMRoS8Dv3v6e7BjEAj5WMtIBRdHUeAioMhKP5HyxNzNnP+heKbA==",
+ "version": "7.25.2",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.2.tgz",
+ "integrity": "sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA==",
"dev": true,
"requires": {
- "@babel/helper-annotate-as-pure": "^7.18.6",
- "@babel/helper-module-imports": "^7.21.4",
- "@babel/helper-plugin-utils": "^7.21.5",
- "@babel/plugin-syntax-jsx": "^7.21.4",
- "@babel/types": "^7.21.5"
+ "@babel/helper-annotate-as-pure": "^7.24.7",
+ "@babel/helper-module-imports": "^7.24.7",
+ "@babel/helper-plugin-utils": "^7.24.8",
+ "@babel/plugin-syntax-jsx": "^7.24.7",
+ "@babel/types": "^7.25.2"
}
},
"@babel/plugin-transform-shorthand-properties": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz",
- "integrity": "sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz",
+ "integrity": "sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
}
},
"@babel/plugin-transform-spread": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz",
- "integrity": "sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz",
+ "integrity": "sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0",
- "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
+ "@babel/helper-plugin-utils": "^7.24.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7"
}
},
"@babel/plugin-transform-template-literals": {
- "version": "7.24.1",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz",
- "integrity": "sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz",
+ "integrity": "sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==",
"dev": true,
"requires": {
- "@babel/helper-plugin-utils": "^7.24.0"
+ "@babel/helper-plugin-utils": "^7.24.7"
}
},
"@babel/runtime": {
- "version": "7.21.0",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz",
- "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==",
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz",
+ "integrity": "sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==",
"requires": {
- "regenerator-runtime": "^0.13.11"
+ "regenerator-runtime": "^0.14.0"
},
"dependencies": {
"regenerator-runtime": {
- "version": "0.13.11",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
- "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
}
}
},
"@babel/template": {
- "version": "7.24.0",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
- "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
+ "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
"requires": {
- "@babel/code-frame": "^7.23.5",
- "@babel/parser": "^7.24.0",
- "@babel/types": "^7.24.0"
+ "@babel/code-frame": "^7.24.7",
+ "@babel/parser": "^7.25.0",
+ "@babel/types": "^7.25.0"
}
},
"@babel/traverse": {
- "version": "7.23.2",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
- "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
- "requires": {
- "@babel/code-frame": "^7.22.13",
- "@babel/generator": "^7.23.0",
- "@babel/helper-environment-visitor": "^7.22.20",
- "@babel/helper-function-name": "^7.23.0",
- "@babel/helper-hoist-variables": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.6",
- "@babel/parser": "^7.23.0",
- "@babel/types": "^7.23.0",
- "debug": "^4.1.0",
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
+ "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
+ "requires": {
+ "@babel/code-frame": "^7.24.7",
+ "@babel/generator": "^7.25.6",
+ "@babel/parser": "^7.25.6",
+ "@babel/template": "^7.25.0",
+ "@babel/types": "^7.25.6",
+ "debug": "^4.3.1",
"globals": "^11.1.0"
}
},
"@babel/types": {
- "version": "7.24.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
- "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
+ "version": "7.25.6",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
+ "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
"requires": {
- "@babel/helper-string-parser": "^7.23.4",
- "@babel/helper-validator-identifier": "^7.22.20",
+ "@babel/helper-string-parser": "^7.24.8",
+ "@babel/helper-validator-identifier": "^7.24.7",
"to-fast-properties": "^2.0.0"
}
},
@@ -25963,16 +22201,16 @@
"optional": true
},
"@changesets/apply-release-plan": {
- "version": "6.1.3",
- "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-6.1.3.tgz",
- "integrity": "sha512-ECDNeoc3nfeAe1jqJb5aFQX7CqzQhD2klXRez2JDb/aVpGUbX673HgKrnrgJRuQR/9f2TtLoYIzrGB9qwD77mg==",
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.5.tgz",
+ "integrity": "sha512-1cWCk+ZshEkSVEZrm2fSj1Gz8sYvxgUL4Q78+1ZZqeqfuevPTPk033/yUZ3df8BKMohkqqHfzj0HOOrG0KtXTw==",
"dev": true,
"requires": {
- "@babel/runtime": "^7.20.1",
- "@changesets/config": "^2.3.0",
- "@changesets/get-version-range-type": "^0.3.2",
- "@changesets/git": "^2.0.0",
- "@changesets/types": "^5.2.1",
+ "@changesets/config": "^3.0.3",
+ "@changesets/get-version-range-type": "^0.4.0",
+ "@changesets/git": "^3.0.1",
+ "@changesets/should-skip-package": "^0.1.1",
+ "@changesets/types": "^6.0.0",
"@manypkg/get-packages": "^1.1.3",
"detect-indent": "^6.0.0",
"fs-extra": "^7.0.1",
@@ -25980,273 +22218,139 @@
"outdent": "^0.5.0",
"prettier": "^2.7.1",
"resolve-from": "^5.0.0",
- "semver": "^5.4.1"
+ "semver": "^7.5.3"
},
"dependencies": {
- "fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- }
- },
"prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"dev": true
- },
- "semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true
}
}
},
"@changesets/assemble-release-plan": {
- "version": "5.2.3",
- "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-5.2.3.tgz",
- "integrity": "sha512-g7EVZCmnWz3zMBAdrcKhid4hkHT+Ft1n0mLussFMcB1dE2zCuwcvGoy9ec3yOgPGF4hoMtgHaMIk3T3TBdvU9g==",
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.4.tgz",
+ "integrity": "sha512-nqICnvmrwWj4w2x0fOhVj2QEGdlUuwVAwESrUo5HLzWMI1rE5SWfsr9ln+rDqWB6RQ2ZyaMZHUcU7/IRaUJS+Q==",
"dev": true,
"requires": {
- "@babel/runtime": "^7.20.1",
- "@changesets/errors": "^0.1.4",
- "@changesets/get-dependents-graph": "^1.3.5",
- "@changesets/types": "^5.2.1",
+ "@changesets/errors": "^0.2.0",
+ "@changesets/get-dependents-graph": "^2.1.2",
+ "@changesets/should-skip-package": "^0.1.1",
+ "@changesets/types": "^6.0.0",
"@manypkg/get-packages": "^1.1.3",
- "semver": "^5.4.1"
- },
- "dependencies": {
- "semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true
- }
+ "semver": "^7.5.3"
}
},
"@changesets/changelog-git": {
- "version": "0.1.14",
- "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.1.14.tgz",
- "integrity": "sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA==",
- "dev": true,
- "requires": {
- "@changesets/types": "^5.2.1"
- }
- },
- "@changesets/changelog-github": {
- "version": "0.4.8",
- "resolved": "https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-0.4.8.tgz",
- "integrity": "sha512-jR1DHibkMAb5v/8ym77E4AMNWZKB5NPzw5a5Wtqm1JepAuIF+hrKp2u04NKM14oBZhHglkCfrla9uq8ORnK/dw==",
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.0.tgz",
+ "integrity": "sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==",
"dev": true,
"requires": {
- "@changesets/get-github-info": "^0.5.2",
- "@changesets/types": "^5.2.1",
- "dotenv": "^8.1.0"
- },
- "dependencies": {
- "dotenv": {
- "version": "8.6.0",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz",
- "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==",
- "dev": true
- }
+ "@changesets/types": "^6.0.0"
}
},
"@changesets/cli": {
- "version": "2.26.1",
- "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.26.1.tgz",
- "integrity": "sha512-XnTa+b51vt057fyAudvDKGB0Sh72xutQZNAdXkCqPBKO2zvs2yYZx5hFZj1u9cbtpwM6Sxtcr02/FQJfZOzemQ==",
- "dev": true,
- "requires": {
- "@babel/runtime": "^7.20.1",
- "@changesets/apply-release-plan": "^6.1.3",
- "@changesets/assemble-release-plan": "^5.2.3",
- "@changesets/changelog-git": "^0.1.14",
- "@changesets/config": "^2.3.0",
- "@changesets/errors": "^0.1.4",
- "@changesets/get-dependents-graph": "^1.3.5",
- "@changesets/get-release-plan": "^3.0.16",
- "@changesets/git": "^2.0.0",
- "@changesets/logger": "^0.0.5",
- "@changesets/pre": "^1.0.14",
- "@changesets/read": "^0.5.9",
- "@changesets/types": "^5.2.1",
- "@changesets/write": "^0.2.3",
+ "version": "2.27.9",
+ "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.27.9.tgz",
+ "integrity": "sha512-q42a/ZbDnxPpCb5Wkm6tMVIxgeI9C/bexntzTeCFBrQEdpisQqk8kCHllYZMDjYtEc1ZzumbMJAG8H0Z4rdvjg==",
+ "dev": true,
+ "requires": {
+ "@changesets/apply-release-plan": "^7.0.5",
+ "@changesets/assemble-release-plan": "^6.0.4",
+ "@changesets/changelog-git": "^0.2.0",
+ "@changesets/config": "^3.0.3",
+ "@changesets/errors": "^0.2.0",
+ "@changesets/get-dependents-graph": "^2.1.2",
+ "@changesets/get-release-plan": "^4.0.4",
+ "@changesets/git": "^3.0.1",
+ "@changesets/logger": "^0.1.1",
+ "@changesets/pre": "^2.0.1",
+ "@changesets/read": "^0.6.1",
+ "@changesets/should-skip-package": "^0.1.1",
+ "@changesets/types": "^6.0.0",
+ "@changesets/write": "^0.3.2",
"@manypkg/get-packages": "^1.1.3",
- "@types/is-ci": "^3.0.0",
- "@types/semver": "^6.0.0",
"ansi-colors": "^4.1.3",
- "chalk": "^2.1.0",
+ "ci-info": "^3.7.0",
"enquirer": "^2.3.0",
"external-editor": "^3.1.0",
"fs-extra": "^7.0.1",
- "human-id": "^1.0.2",
- "is-ci": "^3.0.1",
- "meow": "^6.0.0",
- "outdent": "^0.5.0",
+ "mri": "^1.2.0",
"p-limit": "^2.2.0",
- "preferred-pm": "^3.0.0",
+ "package-manager-detector": "^0.2.0",
+ "picocolors": "^1.1.0",
"resolve-from": "^5.0.0",
- "semver": "^5.4.1",
+ "semver": "^7.5.3",
"spawndamnit": "^2.0.0",
- "term-size": "^2.1.0",
- "tty-table": "^4.1.5"
- },
- "dependencies": {
- "@types/semver": {
- "version": "6.2.3",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.2.3.tgz",
- "integrity": "sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==",
- "dev": true
- },
- "ansi-colors": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
- "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
- "dev": true
- },
- "fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- }
- },
- "semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true
- }
+ "term-size": "^2.1.0"
}
},
"@changesets/config": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@changesets/config/-/config-2.3.0.tgz",
- "integrity": "sha512-EgP/px6mhCx8QeaMAvWtRrgyxW08k/Bx2tpGT+M84jEdX37v3VKfh4Cz1BkwrYKuMV2HZKeHOh8sHvja/HcXfQ==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.0.3.tgz",
+ "integrity": "sha512-vqgQZMyIcuIpw9nqFIpTSNyc/wgm/Lu1zKN5vECy74u95Qx/Wa9g27HdgO4NkVAaq+BGA8wUc/qvbvVNs93n6A==",
"dev": true,
"requires": {
- "@changesets/errors": "^0.1.4",
- "@changesets/get-dependents-graph": "^1.3.5",
- "@changesets/logger": "^0.0.5",
- "@changesets/types": "^5.2.1",
+ "@changesets/errors": "^0.2.0",
+ "@changesets/get-dependents-graph": "^2.1.2",
+ "@changesets/logger": "^0.1.1",
+ "@changesets/types": "^6.0.0",
"@manypkg/get-packages": "^1.1.3",
"fs-extra": "^7.0.1",
"micromatch": "^4.0.2"
- },
- "dependencies": {
- "fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- }
- }
}
},
"@changesets/errors": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.1.4.tgz",
- "integrity": "sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==",
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz",
+ "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==",
"dev": true,
"requires": {
"extendable-error": "^0.1.5"
}
},
"@changesets/get-dependents-graph": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-1.3.5.tgz",
- "integrity": "sha512-w1eEvnWlbVDIY8mWXqWuYE9oKhvIaBhzqzo4ITSJY9hgoqQ3RoBqwlcAzg11qHxv/b8ReDWnMrpjpKrW6m1ZTA==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.2.tgz",
+ "integrity": "sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==",
"dev": true,
"requires": {
- "@changesets/types": "^5.2.1",
+ "@changesets/types": "^6.0.0",
"@manypkg/get-packages": "^1.1.3",
- "chalk": "^2.1.0",
- "fs-extra": "^7.0.1",
- "semver": "^5.4.1"
- },
- "dependencies": {
- "fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- }
- },
- "semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true
- }
- }
- },
- "@changesets/get-github-info": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-0.5.2.tgz",
- "integrity": "sha512-JppheLu7S114aEs157fOZDjFqUDpm7eHdq5E8SSR0gUBTEK0cNSHsrSR5a66xs0z3RWuo46QvA3vawp8BxDHvg==",
- "dev": true,
- "requires": {
- "dataloader": "^1.4.0",
- "node-fetch": "^2.5.0"
- },
- "dependencies": {
- "dataloader": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz",
- "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==",
- "dev": true
- }
+ "picocolors": "^1.1.0",
+ "semver": "^7.5.3"
}
},
"@changesets/get-release-plan": {
- "version": "3.0.16",
- "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-3.0.16.tgz",
- "integrity": "sha512-OpP9QILpBp1bY2YNIKFzwigKh7Qe9KizRsZomzLe6pK8IUo8onkAAVUD8+JRKSr8R7d4+JRuQrfSSNlEwKyPYg==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.4.tgz",
+ "integrity": "sha512-SicG/S67JmPTrdcc9Vpu0wSQt7IiuN0dc8iR5VScnnTVPfIaLvKmEGRvIaF0kcn8u5ZqLbormZNTO77bCEvyWw==",
"dev": true,
"requires": {
- "@babel/runtime": "^7.20.1",
- "@changesets/assemble-release-plan": "^5.2.3",
- "@changesets/config": "^2.3.0",
- "@changesets/pre": "^1.0.14",
- "@changesets/read": "^0.5.9",
- "@changesets/types": "^5.2.1",
+ "@changesets/assemble-release-plan": "^6.0.4",
+ "@changesets/config": "^3.0.3",
+ "@changesets/pre": "^2.0.1",
+ "@changesets/read": "^0.6.1",
+ "@changesets/types": "^6.0.0",
"@manypkg/get-packages": "^1.1.3"
}
},
"@changesets/get-version-range-type": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.3.2.tgz",
- "integrity": "sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==",
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz",
+ "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==",
"dev": true
},
"@changesets/git": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@changesets/git/-/git-2.0.0.tgz",
- "integrity": "sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.1.tgz",
+ "integrity": "sha512-pdgHcYBLCPcLd82aRcuO0kxCDbw/yISlOtkmwmE8Odo1L6hSiZrBOsRl84eYG7DRCab/iHnOkWqExqc4wxk2LQ==",
"dev": true,
"requires": {
- "@babel/runtime": "^7.20.1",
- "@changesets/errors": "^0.1.4",
- "@changesets/types": "^5.2.1",
+ "@changesets/errors": "^0.2.0",
"@manypkg/get-packages": "^1.1.3",
"is-subdir": "^1.1.1",
"micromatch": "^4.0.2",
@@ -26254,109 +22358,79 @@
}
},
"@changesets/logger": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.0.5.tgz",
- "integrity": "sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==",
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz",
+ "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==",
"dev": true,
"requires": {
- "chalk": "^2.1.0"
+ "picocolors": "^1.1.0"
}
},
"@changesets/parse": {
- "version": "0.3.16",
- "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.3.16.tgz",
- "integrity": "sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==",
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.0.tgz",
+ "integrity": "sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==",
"dev": true,
"requires": {
- "@changesets/types": "^5.2.1",
+ "@changesets/types": "^6.0.0",
"js-yaml": "^3.13.1"
}
},
"@changesets/pre": {
- "version": "1.0.14",
- "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-1.0.14.tgz",
- "integrity": "sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.1.tgz",
+ "integrity": "sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==",
"dev": true,
"requires": {
- "@babel/runtime": "^7.20.1",
- "@changesets/errors": "^0.1.4",
- "@changesets/types": "^5.2.1",
+ "@changesets/errors": "^0.2.0",
+ "@changesets/types": "^6.0.0",
"@manypkg/get-packages": "^1.1.3",
"fs-extra": "^7.0.1"
- },
- "dependencies": {
- "fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- }
- }
}
},
"@changesets/read": {
- "version": "0.5.9",
- "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.5.9.tgz",
- "integrity": "sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==",
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.1.tgz",
+ "integrity": "sha512-jYMbyXQk3nwP25nRzQQGa1nKLY0KfoOV7VLgwucI0bUO8t8ZLCr6LZmgjXsiKuRDc+5A6doKPr9w2d+FEJ55zQ==",
"dev": true,
"requires": {
- "@babel/runtime": "^7.20.1",
- "@changesets/git": "^2.0.0",
- "@changesets/logger": "^0.0.5",
- "@changesets/parse": "^0.3.16",
- "@changesets/types": "^5.2.1",
- "chalk": "^2.1.0",
+ "@changesets/git": "^3.0.1",
+ "@changesets/logger": "^0.1.1",
+ "@changesets/parse": "^0.4.0",
+ "@changesets/types": "^6.0.0",
"fs-extra": "^7.0.1",
- "p-filter": "^2.1.0"
- },
- "dependencies": {
- "fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- }
- }
+ "p-filter": "^2.1.0",
+ "picocolors": "^1.1.0"
+ }
+ },
+ "@changesets/should-skip-package": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.1.tgz",
+ "integrity": "sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==",
+ "dev": true,
+ "requires": {
+ "@changesets/types": "^6.0.0",
+ "@manypkg/get-packages": "^1.1.3"
}
},
"@changesets/types": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/@changesets/types/-/types-5.2.1.tgz",
- "integrity": "sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.0.0.tgz",
+ "integrity": "sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==",
"dev": true
},
"@changesets/write": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.2.3.tgz",
- "integrity": "sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==",
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.3.2.tgz",
+ "integrity": "sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==",
"dev": true,
"requires": {
- "@babel/runtime": "^7.20.1",
- "@changesets/types": "^5.2.1",
+ "@changesets/types": "^6.0.0",
"fs-extra": "^7.0.1",
"human-id": "^1.0.2",
"prettier": "^2.7.1"
},
"dependencies": {
- "fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- }
- },
"prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
@@ -26400,20 +22474,20 @@
}
},
"@dnd-kit/accessibility": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.0.1.tgz",
- "integrity": "sha512-HXRrwS9YUYQO9lFRc/49uO/VICbM+O+ZRpFDe9Pd1rwVv2PCNkRiTZRdxrDgng/UkvdC3Re9r2vwPpXXrWeFzg==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz",
+ "integrity": "sha512-2P+YgaXF+gRsIihwwY1gCsQSYnu9Zyj2py8kY5fFvUM1qm2WA2u639R6YNVfU4GWr+ZM5mqEsfHZZLoRONbemw==",
"requires": {
"tslib": "^2.0.0"
}
},
"@dnd-kit/core": {
- "version": "6.0.8",
- "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.0.8.tgz",
- "integrity": "sha512-lYaoP8yHTQSLlZe6Rr9qogouGUz9oRUj4AHhDQGQzq/hqaJRpFo65X+JKsdHf8oUFBzx5A+SJPUvxAwTF2OabA==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/@dnd-kit/core/-/core-6.3.1.tgz",
+ "integrity": "sha512-xkGBRQQab4RLwgXxoqETICr6S5JlogafbhNsidmrkVv2YRs5MLwpjoF2qpiGjQt8S9AoxtIV603s0GIUpY5eYQ==",
"requires": {
- "@dnd-kit/accessibility": "^3.0.0",
- "@dnd-kit/utilities": "^3.2.1",
+ "@dnd-kit/accessibility": "^3.1.1",
+ "@dnd-kit/utilities": "^3.2.2",
"tslib": "^2.0.0"
}
},
@@ -26427,20 +22501,17 @@
}
},
"@dnd-kit/utilities": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.1.tgz",
- "integrity": "sha512-OOXqISfvBw/1REtkSK2N3Fi2EQiLMlWUlqnOK/UpOISqBZPWpE6TqL+jcPtMOkE8TqYGiURvRdPSI9hltNUjEA==",
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/@dnd-kit/utilities/-/utilities-3.2.2.tgz",
+ "integrity": "sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==",
"requires": {
"tslib": "^2.0.0"
}
},
"@editorjs/editorjs": {
- "version": "2.24.3",
- "requires": {
- "codex-notifier": "^1.1.2",
- "codex-tooltip": "^1.0.5",
- "nanoid": "^3.1.22"
- }
+ "version": "2.30.7",
+ "resolved": "https://registry.npmjs.org/@editorjs/editorjs/-/editorjs-2.30.7.tgz",
+ "integrity": "sha512-FfdeUqrgcKWC+Cy2GW6Dxup6s2TaRKokR4FL+HKXshu6h9Y//rrx4SQkURgkZOCSbV77t9btbmAXdFXWGB+diw=="
},
"@editorjs/embed": {
"version": "2.5.3",
@@ -26451,9 +22522,6 @@
"@editorjs/header": {
"version": "2.6.2"
},
- "@editorjs/image": {
- "version": "2.6.2"
- },
"@editorjs/list": {
"version": "1.7.0"
},
@@ -26528,15 +22596,6 @@
"@emotion/hash": {
"version": "0.8.0"
},
- "@emotion/is-prop-valid": {
- "version": "0.7.3",
- "requires": {
- "@emotion/memoize": "0.7.1"
- }
- },
- "@emotion/memoize": {
- "version": "0.7.1"
- },
"@emotion/react": {
"version": "11.10.6",
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.6.tgz",
@@ -26710,11 +22769,11 @@
}
},
"@floating-ui/react-dom": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz",
- "integrity": "sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz",
+ "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==",
"requires": {
- "@floating-ui/dom": "^1.5.1"
+ "@floating-ui/dom": "^1.0.0"
}
},
"@floating-ui/react-dom-interactions": {
@@ -27011,38 +23070,19 @@
}
},
"@graphql-codegen/add": {
- "version": "3.1.1",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/add/-/add-3.2.3.tgz",
+ "integrity": "sha512-sQOnWpMko4JLeykwyjFTxnhqjd/3NOG2OyMuvK76Wnnwh8DRrNf2VEs2kmSvLl7MndMlOj7Kh5U154dVcvhmKQ==",
"dev": true,
"requires": {
- "@graphql-codegen/plugin-helpers": "^2.3.2",
- "tslib": "~2.3.0"
+ "@graphql-codegen/plugin-helpers": "^3.1.1",
+ "tslib": "~2.4.0"
},
"dependencies": {
- "@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
- "dev": true,
- "requires": {
- "@graphql-tools/utils": "^8.5.2",
- "change-case-all": "1.0.14",
- "common-tags": "1.8.2",
- "import-from": "4.0.0",
- "lodash": "~4.17.0",
- "tslib": "~2.3.0"
- }
- },
- "@graphql-tools/utils": {
- "version": "8.6.1",
- "dev": true,
- "requires": {
- "tslib": "~2.3.0"
- }
- },
- "common-tags": {
- "version": "1.8.2",
- "dev": true
- },
"tslib": {
- "version": "2.3.1",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
"dev": true
}
}
@@ -27090,30 +23130,6 @@
"yargs": "^17.0.0"
},
"dependencies": {
- "@graphql-codegen/plugin-helpers": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz",
- "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==",
- "dev": true,
- "requires": {
- "@graphql-tools/utils": "^9.0.0",
- "change-case-all": "1.0.15",
- "common-tags": "1.8.2",
- "import-from": "4.0.0",
- "lodash": "~4.17.0",
- "tslib": "~2.4.0"
- }
- },
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- },
"chalk": {
"version": "4.1.2",
"dev": true,
@@ -27122,30 +23138,6 @@
"supports-color": "^7.1.0"
}
},
- "change-case-all": {
- "version": "1.0.15",
- "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz",
- "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==",
- "dev": true,
- "requires": {
- "change-case": "^4.1.2",
- "is-lower-case": "^2.0.2",
- "is-upper-case": "^2.0.2",
- "lower-case": "^2.0.2",
- "lower-case-first": "^2.0.2",
- "sponge-case": "^1.0.1",
- "swap-case": "^2.0.2",
- "title-case": "^3.0.3",
- "upper-case": "^2.0.2",
- "upper-case-first": "^2.0.2"
- }
- },
- "common-tags": {
- "version": "1.8.2",
- "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
- "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
- "dev": true
- },
"has-flag": {
"version": "4.0.0",
"dev": true
@@ -27213,10 +23205,6 @@
"y18n": "^5.0.5",
"yargs-parser": "^20.2.2"
}
- },
- "yargs-parser": {
- "version": "20.2.9",
- "dev": true
}
}
},
@@ -27232,54 +23220,6 @@
"tslib": "~2.4.0"
},
"dependencies": {
- "@graphql-codegen/plugin-helpers": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz",
- "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==",
- "dev": true,
- "requires": {
- "@graphql-tools/utils": "^9.0.0",
- "change-case-all": "1.0.15",
- "common-tags": "1.8.2",
- "import-from": "4.0.0",
- "lodash": "~4.17.0",
- "tslib": "~2.4.0"
- }
- },
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- },
- "change-case-all": {
- "version": "1.0.15",
- "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz",
- "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==",
- "dev": true,
- "requires": {
- "change-case": "^4.1.2",
- "is-lower-case": "^2.0.2",
- "is-upper-case": "^2.0.2",
- "lower-case": "^2.0.2",
- "lower-case-first": "^2.0.2",
- "sponge-case": "^1.0.1",
- "swap-case": "^2.0.2",
- "title-case": "^3.0.3",
- "upper-case": "^2.0.2",
- "upper-case-first": "^2.0.2"
- }
- },
- "common-tags": {
- "version": "1.8.2",
- "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
- "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
- "dev": true
- },
"tslib": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
@@ -27289,70 +23229,62 @@
}
},
"@graphql-codegen/fragment-matcher": {
- "version": "3.1.0",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/fragment-matcher/-/fragment-matcher-3.3.3.tgz",
+ "integrity": "sha512-lZjarTYQ+w0/TYyoKNFHgIUBI6//rxjo4CwNmOmqGQA0LL+p2nh+/ICJKMFuejPFdK9LI84Y+EEovEFTcDPC+Q==",
"dev": true,
"requires": {
- "@graphql-codegen/plugin-helpers": "^2.1.0",
- "tslib": "~2.3.0"
+ "@graphql-codegen/plugin-helpers": "^3.1.1",
+ "tslib": "~2.4.0"
},
"dependencies": {
"tslib": {
- "version": "2.3.1",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
"dev": true
}
}
},
"@graphql-codegen/import-types-preset": {
- "version": "2.1.12",
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/import-types-preset/-/import-types-preset-2.2.6.tgz",
+ "integrity": "sha512-Lo2ITOln3UVdyyEPiijj8bVhVg0Ghp/JzHXA2LXxrJVCRbXizQhVC2vjiaWTjMskPt9Zub0yIoce4+RrbsXKcg==",
"dev": true,
"requires": {
- "@graphql-codegen/add": "^3.1.1",
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-codegen/visitor-plugin-common": "2.7.1",
- "tslib": "~2.3.0"
+ "@graphql-codegen/add": "^3.2.1",
+ "@graphql-codegen/plugin-helpers": "^2.7.2",
+ "@graphql-codegen/visitor-plugin-common": "2.13.1",
+ "tslib": "~2.4.0"
},
"dependencies": {
"@graphql-codegen/plugin-helpers": {
- "version": "2.4.1",
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.2.tgz",
+ "integrity": "sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg==",
"dev": true,
"requires": {
- "@graphql-tools/utils": "^8.5.2",
+ "@graphql-tools/utils": "^8.8.0",
"change-case-all": "1.0.14",
"common-tags": "1.8.2",
"import-from": "4.0.0",
"lodash": "~4.17.0",
- "tslib": "~2.3.0"
- }
- },
- "@graphql-codegen/visitor-plugin-common": {
- "version": "2.7.1",
- "dev": true,
- "requires": {
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-tools/optimize": "^1.0.1",
- "@graphql-tools/relay-operation-optimizer": "^6.3.7",
- "@graphql-tools/utils": "^8.3.0",
- "auto-bind": "~4.0.0",
- "change-case-all": "1.0.14",
- "dependency-graph": "^0.11.0",
- "graphql-tag": "^2.11.0",
- "parse-filepath": "^1.0.2",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
}
},
"@graphql-tools/utils": {
- "version": "8.6.1",
+ "version": "8.13.1",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz",
+ "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==",
"dev": true,
"requires": {
- "tslib": "~2.3.0"
+ "tslib": "^2.4.0"
}
},
- "common-tags": {
- "version": "1.8.2",
- "dev": true
- },
"tslib": {
- "version": "2.3.1",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
"dev": true
}
}
@@ -27384,10 +23316,6 @@
"tslib": "~2.3.0"
}
},
- "common-tags": {
- "version": "1.8.2",
- "dev": true
- },
"tslib": {
"version": "2.3.1",
"dev": true
@@ -27395,264 +23323,311 @@
}
},
"@graphql-codegen/plugin-helpers": {
- "version": "2.1.0",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-3.1.2.tgz",
+ "integrity": "sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==",
"dev": true,
"requires": {
- "@graphql-tools/utils": "^8.1.1",
- "change-case-all": "1.0.14",
- "common-tags": "1.8.0",
+ "@graphql-tools/utils": "^9.0.0",
+ "change-case-all": "1.0.15",
+ "common-tags": "1.8.2",
"import-from": "4.0.0",
"lodash": "~4.17.0",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"dependencies": {
+ "change-case-all": {
+ "version": "1.0.15",
+ "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz",
+ "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==",
+ "dev": true,
+ "requires": {
+ "change-case": "^4.1.2",
+ "is-lower-case": "^2.0.2",
+ "is-upper-case": "^2.0.2",
+ "lower-case": "^2.0.2",
+ "lower-case-first": "^2.0.2",
+ "sponge-case": "^1.0.1",
+ "swap-case": "^2.0.2",
+ "title-case": "^3.0.3",
+ "upper-case": "^2.0.2",
+ "upper-case-first": "^2.0.2"
+ }
+ },
"tslib": {
- "version": "2.3.1",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
"dev": true
}
}
},
"@graphql-codegen/schema-ast": {
- "version": "2.4.1",
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/schema-ast/-/schema-ast-2.6.1.tgz",
+ "integrity": "sha512-5TNW3b1IHJjCh07D2yQNGDQzUpUl2AD+GVe1Dzjqyx/d2Fn0TPMxLsHsKPS4Plg4saO8FK/QO70wLsP7fdbQ1w==",
"dev": true,
"requires": {
- "@graphql-codegen/plugin-helpers": "^2.3.2",
- "@graphql-tools/utils": "^8.1.1",
- "tslib": "~2.3.0"
+ "@graphql-codegen/plugin-helpers": "^3.1.2",
+ "@graphql-tools/utils": "^9.0.0",
+ "tslib": "~2.4.0"
},
"dependencies": {
- "@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
- "dev": true,
- "requires": {
- "@graphql-tools/utils": "^8.5.2",
- "change-case-all": "1.0.14",
- "common-tags": "1.8.2",
- "import-from": "4.0.0",
- "lodash": "~4.17.0",
- "tslib": "~2.3.0"
- },
- "dependencies": {
- "@graphql-tools/utils": {
- "version": "8.6.1",
- "dev": true,
- "requires": {
- "tslib": "~2.3.0"
- }
- }
- }
- },
- "common-tags": {
- "version": "1.8.2",
- "dev": true
- },
"tslib": {
- "version": "2.3.1",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
"dev": true
}
}
},
"@graphql-codegen/typescript": {
- "version": "2.4.3",
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-2.8.8.tgz",
+ "integrity": "sha512-A0oUi3Oy6+DormOlrTC4orxT9OBZkIglhbJBcDmk34jAKKUgesukXRd4yOhmTrnbchpXz2T8IAOFB3FWIaK4Rw==",
"dev": true,
"requires": {
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-codegen/schema-ast": "^2.4.1",
- "@graphql-codegen/visitor-plugin-common": "2.6.0",
+ "@graphql-codegen/plugin-helpers": "^3.1.2",
+ "@graphql-codegen/schema-ast": "^2.6.1",
+ "@graphql-codegen/visitor-plugin-common": "2.13.8",
"auto-bind": "~4.0.0",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"dependencies": {
- "@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
+ "@graphql-codegen/visitor-plugin-common": {
+ "version": "2.13.8",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.13.8.tgz",
+ "integrity": "sha512-IQWu99YV4wt8hGxIbBQPtqRuaWZhkQRG2IZKbMoSvh0vGeWb3dB0n0hSgKaOOxDY+tljtOf9MTcUYvJslQucMQ==",
"dev": true,
"requires": {
- "@graphql-tools/utils": "^8.5.2",
- "change-case-all": "1.0.14",
- "common-tags": "1.8.2",
- "import-from": "4.0.0",
- "lodash": "~4.17.0",
- "tslib": "~2.3.0"
+ "@graphql-codegen/plugin-helpers": "^3.1.2",
+ "@graphql-tools/optimize": "^1.3.0",
+ "@graphql-tools/relay-operation-optimizer": "^6.5.0",
+ "@graphql-tools/utils": "^9.0.0",
+ "auto-bind": "~4.0.0",
+ "change-case-all": "1.0.15",
+ "dependency-graph": "^0.11.0",
+ "graphql-tag": "^2.11.0",
+ "parse-filepath": "^1.0.2",
+ "tslib": "~2.4.0"
}
},
- "@graphql-tools/utils": {
- "version": "8.6.1",
+ "change-case-all": {
+ "version": "1.0.15",
+ "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz",
+ "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==",
"dev": true,
"requires": {
- "tslib": "~2.3.0"
+ "change-case": "^4.1.2",
+ "is-lower-case": "^2.0.2",
+ "is-upper-case": "^2.0.2",
+ "lower-case": "^2.0.2",
+ "lower-case-first": "^2.0.2",
+ "sponge-case": "^1.0.1",
+ "swap-case": "^2.0.2",
+ "title-case": "^3.0.3",
+ "upper-case": "^2.0.2",
+ "upper-case-first": "^2.0.2"
}
},
- "common-tags": {
- "version": "1.8.2",
- "dev": true
- },
"tslib": {
- "version": "2.3.1",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
"dev": true
}
}
},
"@graphql-codegen/typescript-apollo-client-helpers": {
- "version": "2.1.10",
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-apollo-client-helpers/-/typescript-apollo-client-helpers-2.2.6.tgz",
+ "integrity": "sha512-WEWtjg2D/Clmep7fflKmt6o70rZj/Mqf4ywIO5jF/PI91OHpKhLFM2aWm1ythkqALwQ6wJIFlAjdYqz/EOVYdQ==",
"dev": true,
"requires": {
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-codegen/visitor-plugin-common": "2.6.0",
+ "@graphql-codegen/plugin-helpers": "^2.7.2",
+ "@graphql-codegen/visitor-plugin-common": "2.13.1",
"auto-bind": "~4.0.0",
"change-case-all": "1.0.14",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"dependencies": {
"@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.2.tgz",
+ "integrity": "sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg==",
"dev": true,
"requires": {
- "@graphql-tools/utils": "^8.5.2",
+ "@graphql-tools/utils": "^8.8.0",
"change-case-all": "1.0.14",
"common-tags": "1.8.2",
"import-from": "4.0.0",
"lodash": "~4.17.0",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
}
},
"@graphql-tools/utils": {
- "version": "8.6.1",
+ "version": "8.13.1",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz",
+ "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==",
"dev": true,
"requires": {
- "tslib": "~2.3.0"
+ "tslib": "^2.4.0"
}
},
- "common-tags": {
- "version": "1.8.2",
- "dev": true
- },
"tslib": {
- "version": "2.3.1",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
"dev": true
}
}
},
"@graphql-codegen/typescript-operations": {
- "version": "2.2.4",
+ "version": "2.5.13",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-operations/-/typescript-operations-2.5.13.tgz",
+ "integrity": "sha512-3vfR6Rx6iZU0JRt29GBkFlrSNTM6t+MSLF86ChvL4d/Jfo/JYAGuB3zNzPhirHYzJPCvLOAx2gy9ID1ltrpYiw==",
"dev": true,
"requires": {
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-codegen/typescript": "^2.4.3",
- "@graphql-codegen/visitor-plugin-common": "2.6.0",
+ "@graphql-codegen/plugin-helpers": "^3.1.2",
+ "@graphql-codegen/typescript": "^2.8.8",
+ "@graphql-codegen/visitor-plugin-common": "2.13.8",
"auto-bind": "~4.0.0",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"dependencies": {
- "@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
+ "@graphql-codegen/visitor-plugin-common": {
+ "version": "2.13.8",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.13.8.tgz",
+ "integrity": "sha512-IQWu99YV4wt8hGxIbBQPtqRuaWZhkQRG2IZKbMoSvh0vGeWb3dB0n0hSgKaOOxDY+tljtOf9MTcUYvJslQucMQ==",
"dev": true,
"requires": {
- "@graphql-tools/utils": "^8.5.2",
- "change-case-all": "1.0.14",
- "common-tags": "1.8.2",
- "import-from": "4.0.0",
- "lodash": "~4.17.0",
- "tslib": "~2.3.0"
+ "@graphql-codegen/plugin-helpers": "^3.1.2",
+ "@graphql-tools/optimize": "^1.3.0",
+ "@graphql-tools/relay-operation-optimizer": "^6.5.0",
+ "@graphql-tools/utils": "^9.0.0",
+ "auto-bind": "~4.0.0",
+ "change-case-all": "1.0.15",
+ "dependency-graph": "^0.11.0",
+ "graphql-tag": "^2.11.0",
+ "parse-filepath": "^1.0.2",
+ "tslib": "~2.4.0"
}
},
- "@graphql-tools/utils": {
- "version": "8.6.1",
+ "change-case-all": {
+ "version": "1.0.15",
+ "resolved": "https://registry.npmjs.org/change-case-all/-/change-case-all-1.0.15.tgz",
+ "integrity": "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==",
"dev": true,
"requires": {
- "tslib": "~2.3.0"
+ "change-case": "^4.1.2",
+ "is-lower-case": "^2.0.2",
+ "is-upper-case": "^2.0.2",
+ "lower-case": "^2.0.2",
+ "lower-case-first": "^2.0.2",
+ "sponge-case": "^1.0.1",
+ "swap-case": "^2.0.2",
+ "title-case": "^3.0.3",
+ "upper-case": "^2.0.2",
+ "upper-case-first": "^2.0.2"
}
},
- "common-tags": {
- "version": "1.8.2",
- "dev": true
- },
"tslib": {
- "version": "2.3.1",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
"dev": true
}
}
},
"@graphql-codegen/typescript-react-apollo": {
- "version": "3.2.5",
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/typescript-react-apollo/-/typescript-react-apollo-3.3.7.tgz",
+ "integrity": "sha512-9DUiGE8rcwwEkf/S1kpBT/Py/UUs9Qak14bOnTT1JHWs1MWhiDA7vml+A8opU7YFI1EVbSSaE5jjRv11WHoikQ==",
"dev": true,
"requires": {
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-codegen/visitor-plugin-common": "2.6.0",
+ "@graphql-codegen/plugin-helpers": "^2.7.2",
+ "@graphql-codegen/visitor-plugin-common": "2.13.1",
"auto-bind": "~4.0.0",
"change-case-all": "1.0.14",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"dependencies": {
"@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.2.tgz",
+ "integrity": "sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg==",
"dev": true,
"requires": {
- "@graphql-tools/utils": "^8.5.2",
+ "@graphql-tools/utils": "^8.8.0",
"change-case-all": "1.0.14",
"common-tags": "1.8.2",
"import-from": "4.0.0",
"lodash": "~4.17.0",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
}
},
"@graphql-tools/utils": {
- "version": "8.6.1",
+ "version": "8.13.1",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz",
+ "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==",
"dev": true,
"requires": {
- "tslib": "~2.3.0"
+ "tslib": "^2.4.0"
}
},
- "common-tags": {
- "version": "1.8.2",
- "dev": true
- },
"tslib": {
- "version": "2.3.1",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
"dev": true
}
}
},
"@graphql-codegen/visitor-plugin-common": {
- "version": "2.6.0",
+ "version": "2.13.1",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.13.1.tgz",
+ "integrity": "sha512-mD9ufZhDGhyrSaWQGrU1Q1c5f01TeWtSWy/cDwXYjJcHIj1Y/DG2x0tOflEfCvh5WcnmHNIw4lzDsg1W7iFJEg==",
"dev": true,
"requires": {
- "@graphql-codegen/plugin-helpers": "^2.4.0",
- "@graphql-tools/optimize": "^1.0.1",
- "@graphql-tools/relay-operation-optimizer": "^6.3.7",
- "@graphql-tools/utils": "^8.3.0",
+ "@graphql-codegen/plugin-helpers": "^2.7.2",
+ "@graphql-tools/optimize": "^1.3.0",
+ "@graphql-tools/relay-operation-optimizer": "^6.5.0",
+ "@graphql-tools/utils": "^8.8.0",
"auto-bind": "~4.0.0",
"change-case-all": "1.0.14",
"dependency-graph": "^0.11.0",
"graphql-tag": "^2.11.0",
"parse-filepath": "^1.0.2",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
},
"dependencies": {
"@graphql-codegen/plugin-helpers": {
- "version": "2.4.0",
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.7.2.tgz",
+ "integrity": "sha512-kln2AZ12uii6U59OQXdjLk5nOlh1pHis1R98cDZGFnfaiAbX9V3fxcZ1MMJkB7qFUymTALzyjZoXXdyVmPMfRg==",
"dev": true,
"requires": {
- "@graphql-tools/utils": "^8.5.2",
+ "@graphql-tools/utils": "^8.8.0",
"change-case-all": "1.0.14",
"common-tags": "1.8.2",
"import-from": "4.0.0",
"lodash": "~4.17.0",
- "tslib": "~2.3.0"
+ "tslib": "~2.4.0"
}
},
"@graphql-tools/utils": {
- "version": "8.6.1",
+ "version": "8.13.1",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.13.1.tgz",
+ "integrity": "sha512-qIh9yYpdUFmctVqovwMdheVNJqFh+DQNWIhX87FJStfXYnmweBUDATok9fWPleKeFwxnW8IapKmY8m8toJEkAw==",
"dev": true,
"requires": {
- "tslib": "~2.3.0"
+ "tslib": "^2.4.0"
}
},
- "common-tags": {
- "version": "1.8.2",
- "dev": true
- },
"tslib": {
- "version": "2.3.1",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz",
+ "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==",
"dev": true
}
}
@@ -27669,16 +23644,6 @@
"tslib": "^2.4.0"
},
"dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- },
"@whatwg-node/events": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz",
@@ -27729,18 +23694,6 @@
"dataloader": "^2.2.2",
"tslib": "^2.4.0",
"value-or-promise": "^1.0.12"
- },
- "dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- }
}
},
"@graphql-tools/code-file-loader": {
@@ -27754,18 +23707,6 @@
"globby": "^11.0.3",
"tslib": "^2.4.0",
"unixify": "^1.0.0"
- },
- "dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- }
}
},
"@graphql-tools/delegate": {
@@ -27781,18 +23722,6 @@
"dataloader": "^2.2.2",
"tslib": "^2.5.0",
"value-or-promise": "^1.0.12"
- },
- "dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- }
}
},
"@graphql-tools/executor": {
@@ -27806,18 +23735,6 @@
"@repeaterjs/repeater": "^3.0.4",
"tslib": "^2.4.0",
"value-or-promise": "^1.0.12"
- },
- "dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- }
}
},
"@graphql-tools/executor-graphql-ws": {
@@ -27835,16 +23752,6 @@
"ws": "8.13.0"
},
"dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- },
"ws": {
"version": "8.13.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
@@ -27869,16 +23776,6 @@
"value-or-promise": "^1.0.12"
},
"dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- },
"@whatwg-node/events": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz",
@@ -27932,16 +23829,6 @@
"ws": "8.13.0"
},
"dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- },
"ws": {
"version": "8.13.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
@@ -27962,18 +23849,6 @@
"micromatch": "^4.0.4",
"tslib": "^2.4.0",
"unixify": "^1.0.0"
- },
- "dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- }
}
},
"@graphql-tools/github-loader": {
@@ -27991,16 +23866,6 @@
"value-or-promise": "^1.0.12"
},
"dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- },
"@whatwg-node/events": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz",
@@ -28052,18 +23917,6 @@
"globby": "^11.0.3",
"tslib": "^2.4.0",
"unixify": "^1.0.0"
- },
- "dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- }
}
},
"@graphql-tools/graphql-tag-pluck": {
@@ -28078,18 +23931,6 @@
"@babel/types": "^7.16.8",
"@graphql-tools/utils": "^9.2.1",
"tslib": "^2.4.0"
- },
- "dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- }
}
},
"@graphql-tools/import": {
@@ -28101,18 +23942,6 @@
"@graphql-tools/utils": "^9.2.1",
"resolve-from": "5.0.0",
"tslib": "^2.4.0"
- },
- "dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- }
}
},
"@graphql-tools/json-file-loader": {
@@ -28125,18 +23954,6 @@
"globby": "^11.0.3",
"tslib": "^2.4.0",
"unixify": "^1.0.0"
- },
- "dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- }
}
},
"@graphql-tools/load": {
@@ -28151,16 +23968,6 @@
"tslib": "^2.4.0"
},
"dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- },
"p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -28180,31 +23987,15 @@
"requires": {
"@graphql-tools/utils": "^9.2.1",
"tslib": "^2.4.0"
- },
- "dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- }
}
},
"@graphql-tools/optimize": {
- "version": "1.0.1",
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/optimize/-/optimize-1.4.0.tgz",
+ "integrity": "sha512-dJs/2XvZp+wgHH8T5J2TqptT9/6uVzIYvA6uFACha+ufvdMBedkfR4b4GbT8jAKLRARiqRTxy3dctnwkTM2tdw==",
"dev": true,
"requires": {
- "tslib": "~2.0.1"
- },
- "dependencies": {
- "tslib": {
- "version": "2.0.3",
- "dev": true
- }
+ "tslib": "^2.4.0"
}
},
"@graphql-tools/prisma-loader": {
@@ -28233,16 +24024,6 @@
"yaml-ast-parser": "^0.0.43"
},
"dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- },
"@whatwg-node/events": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz",
@@ -28369,18 +24150,14 @@
}
},
"@graphql-tools/relay-operation-optimizer": {
- "version": "6.3.7",
+ "version": "6.5.18",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-6.5.18.tgz",
+ "integrity": "sha512-mc5VPyTeV+LwiM+DNvoDQfPqwQYhPV/cl5jOBjTgSniyaq8/86aODfMkrE2OduhQ5E00hqrkuL2Fdrgk0w1QJg==",
"dev": true,
"requires": {
- "@graphql-tools/utils": "^8.1.1",
- "relay-compiler": "11.0.2",
- "tslib": "~2.3.0"
- },
- "dependencies": {
- "tslib": {
- "version": "2.3.1",
- "dev": true
- }
+ "@ardatan/relay-compiler": "12.0.0",
+ "@graphql-tools/utils": "^9.2.1",
+ "tslib": "^2.4.0"
}
},
"@graphql-tools/schema": {
@@ -28393,18 +24170,6 @@
"@graphql-tools/utils": "^9.2.1",
"tslib": "^2.4.0",
"value-or-promise": "^1.0.12"
- },
- "dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- }
}
},
"@graphql-tools/url-loader": {
@@ -28428,16 +24193,6 @@
"ws": "^8.12.0"
},
"dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- },
"@whatwg-node/events": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.0.3.tgz",
@@ -28485,16 +24240,13 @@
}
},
"@graphql-tools/utils": {
- "version": "8.1.2",
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
+ "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
"dev": true,
"requires": {
- "tslib": "~2.3.0"
- },
- "dependencies": {
- "tslib": {
- "version": "2.3.1",
- "dev": true
- }
+ "@graphql-typed-document-node/core": "^3.1.1",
+ "tslib": "^2.4.0"
}
},
"@graphql-tools/wrap": {
@@ -28508,18 +24260,6 @@
"@graphql-tools/utils": "^9.2.1",
"tslib": "^2.4.0",
"value-or-promise": "^1.0.12"
- },
- "dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- }
}
},
"@graphql-typed-document-node/core": {
@@ -28527,17 +24267,6 @@
"resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz",
"integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ=="
},
- "@hapi/hoek": {
- "version": "9.1.1",
- "dev": true
- },
- "@hapi/topo": {
- "version": "5.0.0",
- "dev": true,
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- },
"@hookform/resolvers": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.2.tgz",
@@ -28608,10 +24337,6 @@
"requires": {
"p-limit": "^2.2.0"
}
- },
- "path-exists": {
- "version": "4.0.0",
- "optional": true
}
}
},
@@ -28715,12 +24440,62 @@
}
},
"@jest/create-cache-key-function": {
- "version": "27.5.1",
- "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz",
- "integrity": "sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==",
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz",
+ "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==",
"dev": true,
"requires": {
- "@jest/types": "^27.5.1"
+ "@jest/types": "^29.6.3"
+ },
+ "dependencies": {
+ "@jest/types": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
+ "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.6.3",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@types/yargs": {
+ "version": "17.0.33",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
+ "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
}
},
"@jest/environment": {
@@ -28810,6 +24585,15 @@
}
}
},
+ "@jest/schemas": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+ "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+ "dev": true,
+ "requires": {
+ "@sinclair/typebox": "^0.27.8"
+ }
+ },
"@jest/source-map": {
"version": "27.5.1",
"optional": true,
@@ -28907,7 +24691,7 @@
},
"@jest/types": {
"version": "27.5.1",
- "devOptional": true,
+ "optional": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
"@types/istanbul-reports": "^3.0.0",
@@ -28918,7 +24702,7 @@
"dependencies": {
"chalk": {
"version": "4.1.2",
- "devOptional": true,
+ "optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -28926,11 +24710,11 @@
},
"has-flag": {
"version": "4.0.0",
- "devOptional": true
+ "optional": true
},
"supports-color": {
"version": "7.2.0",
- "devOptional": true,
+ "optional": true,
"requires": {
"has-flag": "^4.0.0"
}
@@ -29007,6 +24791,17 @@
"path-exists": "^4.0.0"
}
},
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -29024,12 +24819,6 @@
"requires": {
"p-limit": "^2.2.0"
}
- },
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
}
}
},
@@ -29052,6 +24841,17 @@
"resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz",
"integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==",
"dev": true
+ },
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
}
}
},
@@ -29082,6 +24882,8 @@
},
"@material-ui/lab": {
"version": "4.0.0-alpha.61",
+ "resolved": "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.61.tgz",
+ "integrity": "sha512-rSzm+XKiNUjKegj8bzt5+pygZeckNLOr+IjykH8sYdVk7dE9y2ZuUSofiMV2bJk3qU+JHwexmw+q0RyNZB9ugg==",
"requires": {
"@babel/runtime": "^7.4.4",
"@material-ui/utils": "^4.11.3",
@@ -29155,6 +24957,7 @@
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
"requires": {
"@nodelib/fs.stat": "2.0.5",
"run-parallel": "^1.1.9"
@@ -29163,41 +24966,19 @@
"@nodelib/fs.stat": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true
},
"@nodelib/fs.walk": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
"requires": {
"@nodelib/fs.scandir": "2.1.5",
"fastq": "^1.6.0"
}
},
- "@oozcitak/dom": {
- "version": "1.15.10",
- "requires": {
- "@oozcitak/infra": "1.0.8",
- "@oozcitak/url": "1.0.4",
- "@oozcitak/util": "8.3.8"
- }
- },
- "@oozcitak/infra": {
- "version": "1.0.8",
- "requires": {
- "@oozcitak/util": "8.3.8"
- }
- },
- "@oozcitak/url": {
- "version": "1.0.4",
- "requires": {
- "@oozcitak/infra": "1.0.8",
- "@oozcitak/util": "8.3.8"
- }
- },
- "@oozcitak/util": {
- "version": "8.3.8"
- },
"@opentelemetry/api": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz",
@@ -29249,440 +25030,388 @@
"integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA=="
},
"@playwright/test": {
- "version": "1.40.0",
- "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.40.0.tgz",
- "integrity": "sha512-PdW+kn4eV99iP5gxWNSDQCbhMaDVej+RXL5xr6t04nbKLCBwYtA046t7ofoczHOm8u6c+45hpDKQVZqtqwkeQg==",
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.49.0.tgz",
+ "integrity": "sha512-DMulbwQURa8rNIQrf94+jPJQ4FmOVdpE5ZppRNvWVjvhC+6sOeo28r8MgIpQRYouXRtt/FCCXU7zn20jnHR4Qw==",
"dev": true,
"requires": {
- "playwright": "1.40.0"
+ "playwright": "1.49.0"
}
},
"@radix-ui/primitive": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz",
- "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==",
- "requires": {
- "@babel/runtime": "^7.13.10"
- }
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
+ "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA=="
},
"@radix-ui/react-accordion": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.1.2.tgz",
- "integrity": "sha512-fDG7jcoNKVjSK6yfmuAs0EnPDro0WMXIhMtXdTBWqEioVW206ku+4Lw07e+13lUkFkpoEQ2PdeMIAGpdqEAmDg==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.0.tgz",
+ "integrity": "sha512-HJOzSX8dQqtsp/3jVxCU3CXEONF7/2jlGAB28oX8TTw1Dz8JYbEI1UcL8355PuLBE41/IRRMvCw7VkiK/jcUOQ==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-collapsible": "1.0.3",
- "@radix-ui/react-collection": "1.0.3",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-direction": "1.0.1",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-controllable-state": "1.0.1"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-collapsible": "1.1.0",
+ "@radix-ui/react-collection": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
}
},
"@radix-ui/react-arrow": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz",
- "integrity": "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz",
+ "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-primitive": "1.0.3"
+ "@radix-ui/react-primitive": "2.0.0"
}
},
"@radix-ui/react-checkbox": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.0.4.tgz",
- "integrity": "sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.1.tgz",
+ "integrity": "sha512-0i/EKJ222Afa1FE0C6pNJxDq1itzcl3HChE9DwskA4th4KRse8ojx8a1nVcOjwJdbpDLcz7uol77yYnQNMHdKw==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-controllable-state": "1.0.1",
- "@radix-ui/react-use-previous": "1.0.1",
- "@radix-ui/react-use-size": "1.0.1"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-use-previous": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0"
}
},
"@radix-ui/react-collapsible": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.0.3.tgz",
- "integrity": "sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.0.tgz",
+ "integrity": "sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-controllable-state": "1.0.1",
- "@radix-ui/react-use-layout-effect": "1.0.1"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
}
},
"@radix-ui/react-collection": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz",
- "integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
+ "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-slot": "1.0.2"
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0"
}
},
"@radix-ui/react-compose-refs": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz",
- "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==",
- "requires": {
- "@babel/runtime": "^7.13.10"
- }
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
+ "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw=="
},
"@radix-ui/react-context": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz",
- "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==",
- "requires": {
- "@babel/runtime": "^7.13.10"
- }
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
+ "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A=="
},
"@radix-ui/react-dialog": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz",
- "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==",
- "requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-dismissable-layer": "1.0.5",
- "@radix-ui/react-focus-guards": "1.0.1",
- "@radix-ui/react-focus-scope": "1.0.4",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-portal": "1.0.4",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-slot": "1.0.2",
- "@radix-ui/react-use-controllable-state": "1.0.1",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz",
+ "integrity": "sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==",
+ "requires": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.0",
+ "@radix-ui/react-focus-guards": "1.1.0",
+ "@radix-ui/react-focus-scope": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-portal": "1.1.1",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
"aria-hidden": "^1.1.1",
- "react-remove-scroll": "2.5.5"
+ "react-remove-scroll": "2.5.7"
}
},
"@radix-ui/react-direction": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz",
- "integrity": "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==",
- "requires": {
- "@babel/runtime": "^7.13.10"
- }
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz",
+ "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg=="
},
"@radix-ui/react-dismissable-layer": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz",
- "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz",
+ "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1",
- "@radix-ui/react-use-escape-keydown": "1.0.3"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-escape-keydown": "1.1.0"
}
},
"@radix-ui/react-dropdown-menu": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz",
- "integrity": "sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz",
+ "integrity": "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-menu": "2.0.6",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-controllable-state": "1.0.1"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-menu": "2.1.1",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
}
},
"@radix-ui/react-focus-guards": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz",
- "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==",
- "requires": {
- "@babel/runtime": "^7.13.10"
- }
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz",
+ "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw=="
},
"@radix-ui/react-focus-scope": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz",
- "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz",
+ "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1"
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0"
}
},
"@radix-ui/react-id": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz",
- "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
+ "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-use-layout-effect": "1.0.1"
+ "@radix-ui/react-use-layout-effect": "1.1.0"
}
},
"@radix-ui/react-menu": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.6.tgz",
- "integrity": "sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==",
- "requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-collection": "1.0.3",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-direction": "1.0.1",
- "@radix-ui/react-dismissable-layer": "1.0.5",
- "@radix-ui/react-focus-guards": "1.0.1",
- "@radix-ui/react-focus-scope": "1.0.4",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-popper": "1.1.3",
- "@radix-ui/react-portal": "1.0.4",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-roving-focus": "1.0.4",
- "@radix-ui/react-slot": "1.0.2",
- "@radix-ui/react-use-callback-ref": "1.0.1",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.1.tgz",
+ "integrity": "sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==",
+ "requires": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-collection": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.0",
+ "@radix-ui/react-focus-guards": "1.1.0",
+ "@radix-ui/react-focus-scope": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.0",
+ "@radix-ui/react-portal": "1.1.1",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-roving-focus": "1.1.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
"aria-hidden": "^1.1.1",
- "react-remove-scroll": "2.5.5"
+ "react-remove-scroll": "2.5.7"
}
},
"@radix-ui/react-popover": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.7.tgz",
- "integrity": "sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==",
- "requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-dismissable-layer": "1.0.5",
- "@radix-ui/react-focus-guards": "1.0.1",
- "@radix-ui/react-focus-scope": "1.0.4",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-popper": "1.1.3",
- "@radix-ui/react-portal": "1.0.4",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-slot": "1.0.2",
- "@radix-ui/react-use-controllable-state": "1.0.1",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.1.tgz",
+ "integrity": "sha512-3y1A3isulwnWhvTTwmIreiB8CF4L+qRjZnK1wYLO7pplddzXKby/GnZ2M7OZY3qgnl6p9AodUIHRYGXNah8Y7g==",
+ "requires": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.0",
+ "@radix-ui/react-focus-guards": "1.1.0",
+ "@radix-ui/react-focus-scope": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.0",
+ "@radix-ui/react-portal": "1.1.1",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
"aria-hidden": "^1.1.1",
- "react-remove-scroll": "2.5.5"
+ "react-remove-scroll": "2.5.7"
}
},
"@radix-ui/react-popper": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz",
- "integrity": "sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
+ "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==",
"requires": {
- "@babel/runtime": "^7.13.10",
"@floating-ui/react-dom": "^2.0.0",
- "@radix-ui/react-arrow": "1.0.3",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1",
- "@radix-ui/react-use-layout-effect": "1.0.1",
- "@radix-ui/react-use-rect": "1.0.1",
- "@radix-ui/react-use-size": "1.0.1",
- "@radix-ui/rect": "1.0.1"
+ "@radix-ui/react-arrow": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0",
+ "@radix-ui/react-use-rect": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0",
+ "@radix-ui/rect": "1.1.0"
}
},
"@radix-ui/react-portal": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz",
- "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz",
+ "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-primitive": "1.0.3"
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
}
},
"@radix-ui/react-presence": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz",
- "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz",
+ "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-use-layout-effect": "1.0.1"
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
}
},
"@radix-ui/react-primitive": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz",
- "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
+ "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-slot": "1.0.2"
+ "@radix-ui/react-slot": "1.1.0"
}
},
"@radix-ui/react-radio-group": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.1.3.tgz",
- "integrity": "sha512-x+yELayyefNeKeTx4fjK6j99Fs6c4qKm3aY38G3swQVTN6xMpsrbigC0uHs2L//g8q4qR7qOcww8430jJmi2ag==",
- "requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-direction": "1.0.1",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-roving-focus": "1.0.4",
- "@radix-ui/react-use-controllable-state": "1.0.1",
- "@radix-ui/react-use-previous": "1.0.1",
- "@radix-ui/react-use-size": "1.0.1"
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.2.0.tgz",
+ "integrity": "sha512-yv+oiLaicYMBpqgfpSPw6q+RyXlLdIpQWDHZbUKURxe+nEh53hFXPPlfhfQQtYkS5MMK/5IWIa76SksleQZSzw==",
+ "requires": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-roving-focus": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-use-previous": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0"
}
},
"@radix-ui/react-roving-focus": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz",
- "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz",
+ "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-collection": "1.0.3",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-direction": "1.0.1",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1",
- "@radix-ui/react-use-controllable-state": "1.0.1"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-collection": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
}
},
"@radix-ui/react-slot": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
- "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+ "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-compose-refs": "1.0.1"
+ "@radix-ui/react-compose-refs": "1.1.0"
}
},
"@radix-ui/react-toggle": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.0.3.tgz",
- "integrity": "sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.0.tgz",
+ "integrity": "sha512-gwoxaKZ0oJ4vIgzsfESBuSgJNdc0rv12VhHgcqN0TEJmmZixXG/2XpsLK8kzNWYcnaoRIEEQc0bEi3dIvdUpjw==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-controllable-state": "1.0.1"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
}
},
"@radix-ui/react-tooltip": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz",
- "integrity": "sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==",
- "requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-dismissable-layer": "1.0.5",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-popper": "1.1.3",
- "@radix-ui/react-portal": "1.0.4",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-slot": "1.0.2",
- "@radix-ui/react-use-controllable-state": "1.0.1",
- "@radix-ui/react-visually-hidden": "1.0.3"
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz",
+ "integrity": "sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==",
+ "requires": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.0",
+ "@radix-ui/react-portal": "1.1.1",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-visually-hidden": "1.1.0"
}
},
"@radix-ui/react-use-callback-ref": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz",
- "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==",
- "requires": {
- "@babel/runtime": "^7.13.10"
- }
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw=="
},
"@radix-ui/react-use-controllable-state": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz",
- "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
+ "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-use-callback-ref": "1.0.1"
+ "@radix-ui/react-use-callback-ref": "1.1.0"
}
},
"@radix-ui/react-use-escape-keydown": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz",
- "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
+ "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-use-callback-ref": "1.0.1"
+ "@radix-ui/react-use-callback-ref": "1.1.0"
}
},
"@radix-ui/react-use-layout-effect": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz",
- "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==",
- "requires": {
- "@babel/runtime": "^7.13.10"
- }
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w=="
},
"@radix-ui/react-use-previous": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz",
- "integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==",
- "requires": {
- "@babel/runtime": "^7.13.10"
- }
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz",
+ "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og=="
},
"@radix-ui/react-use-rect": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz",
- "integrity": "sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz",
+ "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/rect": "1.0.1"
+ "@radix-ui/rect": "1.1.0"
}
},
"@radix-ui/react-use-size": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz",
- "integrity": "sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
+ "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-use-layout-effect": "1.0.1"
+ "@radix-ui/react-use-layout-effect": "1.1.0"
}
},
"@radix-ui/react-visually-hidden": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz",
- "integrity": "sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz",
+ "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==",
"requires": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-primitive": "1.0.3"
+ "@radix-ui/react-primitive": "2.0.0"
}
},
"@radix-ui/rect": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz",
- "integrity": "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==",
- "requires": {
- "@babel/runtime": "^7.13.10"
- }
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz",
+ "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg=="
},
"@reach/auto-id": {
"version": "0.16.0",
@@ -30052,9 +25781,9 @@
}
},
"@saleor/macaw-ui-next": {
- "version": "npm:@saleor/macaw-ui@1.1.5",
- "resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-1.1.5.tgz",
- "integrity": "sha512-oCK5/n2KXnGthokSZQA5LKFK0sCe/DA3dJjjYHYVi/td7Hs+zUCvTsh3J+I19pKRI4IIHqieqK9DLLfmv+rpOg==",
+ "version": "npm:@saleor/macaw-ui@1.1.15",
+ "resolved": "https://registry.npmjs.org/@saleor/macaw-ui/-/macaw-ui-1.1.15.tgz",
+ "integrity": "sha512-PsNs2gN9hqZhfVCFTaNiFw65p8sfvOb/PZSSIcPB05tg21y8Ze7OP4CJ9UcdYz6Lt0sDXorBYPsEHbT+3pVwYQ==",
"requires": {
"@dessert-box/react": "^0.4.0",
"@floating-ui/react-dom": "^2.0.2",
@@ -30069,25 +25798,35 @@
"@radix-ui/react-tooltip": "^1.0.6",
"@vanilla-extract/css-utils": "^0.1.3",
"@vanilla-extract/recipes": "^0.5.0",
- "downshift": "^7.6.0"
+ "downshift": "^9.0.8"
},
"dependencies": {
"compute-scroll-into-view": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-2.0.4.tgz",
- "integrity": "sha512-y/ZA3BGnxoM/QHHQ2Uy49CLtnWPbt4tTPpEEZiEmmiWBFKjej7nEyH8Ryz54jH0MLXflUYA3Er2zUxPSJu5R+g=="
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz",
+ "integrity": "sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg=="
},
"downshift": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/downshift/-/downshift-7.6.2.tgz",
- "integrity": "sha512-iOv+E1Hyt3JDdL9yYcOgW7nZ7GQ2Uz6YbggwXvKUSleetYhU2nXD482Rz6CzvM4lvI1At34BYruKAL4swRGxaA==",
+ "version": "9.0.8",
+ "resolved": "https://registry.npmjs.org/downshift/-/downshift-9.0.8.tgz",
+ "integrity": "sha512-59BWD7+hSUQIM1DeNPLirNNnZIO9qMdIK5GQ/Uo8q34gT4B78RBlb9dhzgnh0HfQTJj4T/JKYD8KoLAlMWnTsA==",
"requires": {
- "@babel/runtime": "^7.14.8",
- "compute-scroll-into-view": "^2.0.4",
- "prop-types": "^15.7.2",
- "react-is": "^17.0.2",
- "tslib": "^2.3.0"
+ "@babel/runtime": "^7.24.5",
+ "compute-scroll-into-view": "^3.1.0",
+ "prop-types": "^15.8.1",
+ "react-is": "18.2.0",
+ "tslib": "^2.6.2"
}
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+ },
+ "tslib": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
+ "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
}
}
},
@@ -30100,64 +25839,82 @@
"jwt-decode": "^3.1.2"
}
},
+ "@sentry-internal/browser-utils": {
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.21.0.tgz",
+ "integrity": "sha512-qN95Yuc9csDW6H4LEET/qkAA87WIbYIq3x2EY8YzfmjyPvjgfGoOD3wz2ROiitKNgB291rCtnJiSMKE0GinSRg==",
+ "requires": {
+ "@sentry/core": "8.21.0",
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0"
+ }
+ },
"@sentry-internal/feedback": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.85.0.tgz",
- "integrity": "sha512-MlbIN+N8CWFJBjbqMmARe4+UPo9QRhRar0YoOfmNA2Xqk/EwXcjHWkealosHznXH7tqVbjB25QJpHtDystft/Q==",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.21.0.tgz",
+ "integrity": "sha512-vAArMtoYvsBbCvB2KGB4v6uzmBxHCimSkBtfq6CuAv0+mdPGFbhPd+pzKcMovXZD1tji4lY89DbFxRsuliskWw==",
+ "requires": {
+ "@sentry/core": "8.21.0",
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0"
+ }
+ },
+ "@sentry-internal/replay": {
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.21.0.tgz",
+ "integrity": "sha512-di2rLyya4yPA+5LybX5+52HBrW4D8e22yKpERu7cnwWi3+ZAjoDf3M/CmKM9kCPFfSE/tHWlm+CYDl2WhslFLA==",
"requires": {
- "@sentry/core": "7.85.0",
- "@sentry/types": "7.85.0",
- "@sentry/utils": "7.85.0"
+ "@sentry-internal/browser-utils": "8.21.0",
+ "@sentry/core": "8.21.0",
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0"
}
},
- "@sentry-internal/tracing": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.85.0.tgz",
- "integrity": "sha512-p3YMUwkPCy2su9cm/3+7QYR4RiMI0+07DU1BZtht9NLTzY2O87/yvUbn1v2yHR3vJQTy/+7N0ud9/mPBFznRQQ==",
+ "@sentry-internal/replay-canvas": {
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.21.0.tgz",
+ "integrity": "sha512-vm0ZLY5DpjjFodKDhD79ZiLLQaHnA6XG5gTT5HcWhMwAykYNVfXRaNC0dq3ydOw0oDgPnOAnL/RuOXCgYahVdQ==",
"requires": {
- "@sentry/core": "7.85.0",
- "@sentry/types": "7.85.0",
- "@sentry/utils": "7.85.0"
+ "@sentry-internal/replay": "8.21.0",
+ "@sentry/core": "8.21.0",
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0"
}
},
"@sentry/babel-plugin-component-annotate": {
- "version": "2.15.0",
- "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.15.0.tgz",
- "integrity": "sha512-4AaRN2E1iqOPlceDE5ae4thnq717reEQkqOslSWpJf7FmJ+oDrp2bWQhO82xcW8ZBBMbtkOGw2wmrScq5TnMxw=="
+ "version": "2.21.1",
+ "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.21.1.tgz",
+ "integrity": "sha512-u1L8gZ4He0WdyiIsohYkA/YOY1b6Oa5yIMRtfZZ9U5TiWYLgOfMWyb88X0GotZeghSbgxrse/yI4WeHnhAUQDQ=="
},
"@sentry/browser": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.85.0.tgz",
- "integrity": "sha512-x4sH7vTQnZQgy1U7NuN8XwhleAw7YMQitccHeC5m+kpIKGUO7w4Mdvu8rD3dnjmVmZvASpnwocAxy57/vCU6Ww==",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.21.0.tgz",
+ "integrity": "sha512-pYlnQQbkDZfULT8UjGOWY8U+z+8La4dvTtetWYW3SI/colFR3YuZyJvGAJQkwKJpxi4VxGAxQglqj+HgsQua1A==",
"requires": {
- "@sentry-internal/feedback": "7.85.0",
- "@sentry-internal/tracing": "7.85.0",
- "@sentry/core": "7.85.0",
- "@sentry/replay": "7.85.0",
- "@sentry/types": "7.85.0",
- "@sentry/utils": "7.85.0"
+ "@sentry-internal/browser-utils": "8.21.0",
+ "@sentry-internal/feedback": "8.21.0",
+ "@sentry-internal/replay": "8.21.0",
+ "@sentry-internal/replay-canvas": "8.21.0",
+ "@sentry/core": "8.21.0",
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0"
}
},
"@sentry/bundler-plugin-core": {
- "version": "2.15.0",
- "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.15.0.tgz",
- "integrity": "sha512-K6tEmo6ilUdR5uEQZ4P1uaXCvRoAeq5JsJAg7lRv0JSG5XG67jhoHu+mrpiDMB93FxbTgCQkPCT87Z0Bmqpmew==",
+ "version": "2.21.1",
+ "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-2.21.1.tgz",
+ "integrity": "sha512-F8FdL/bS8cy1SY1Gw0Mfo3ROTqlrq9Lvt5QGvhXi22dpVcDkWmoTWE2k+sMEnXOa8SdThMc/gyC8lMwHGd3kFQ==",
"requires": {
"@babel/core": "^7.18.5",
- "@sentry/babel-plugin-component-annotate": "2.15.0",
+ "@sentry/babel-plugin-component-annotate": "2.21.1",
"@sentry/cli": "^2.22.3",
"dotenv": "^16.3.1",
"find-up": "^5.0.0",
"glob": "^9.3.2",
- "magic-string": "0.27.0",
+ "magic-string": "0.30.8",
"unplugin": "1.0.1"
},
"dependencies": {
- "acorn": {
- "version": "8.11.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
- "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg=="
- },
"brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
@@ -30171,15 +25928,6 @@
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
"integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg=="
},
- "find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "requires": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- }
- },
"glob": {
"version": "9.3.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz",
@@ -30191,20 +25939,12 @@
"path-scurry": "^1.6.1"
}
},
- "locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "requires": {
- "p-locate": "^5.0.0"
- }
- },
"magic-string": {
- "version": "0.27.0",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.27.0.tgz",
- "integrity": "sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==",
+ "version": "0.30.8",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
+ "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
"requires": {
- "@jridgewell/sourcemap-codec": "^1.4.13"
+ "@jridgewell/sourcemap-codec": "^1.4.15"
}
},
"minimatch": {
@@ -30214,58 +25954,21 @@
"requires": {
"brace-expansion": "^2.0.1"
}
- },
- "minipass": {
- "version": "4.2.8",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
- "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="
- },
- "p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "requires": {
- "yocto-queue": "^0.1.0"
- }
- },
- "p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "requires": {
- "p-limit": "^3.0.2"
- }
- },
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
- },
- "unplugin": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.0.1.tgz",
- "integrity": "sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==",
- "requires": {
- "acorn": "^8.8.1",
- "chokidar": "^3.5.3",
- "webpack-sources": "^3.2.3",
- "webpack-virtual-modules": "^0.5.0"
- }
}
}
},
"@sentry/cli": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.22.3.tgz",
- "integrity": "sha512-VFHdtrHsMyTRSZhDLeMyXvit7xB4e81KugIEwMve95c7h5HO672bfmCcM/403CAugj4NzvQ+IR2NKF/2SsEPlg==",
- "requires": {
- "@sentry/cli-darwin": "2.22.3",
- "@sentry/cli-linux-arm": "2.22.3",
- "@sentry/cli-linux-arm64": "2.22.3",
- "@sentry/cli-linux-i686": "2.22.3",
- "@sentry/cli-linux-x64": "2.22.3",
- "@sentry/cli-win32-i686": "2.22.3",
- "@sentry/cli-win32-x64": "2.22.3",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.33.0.tgz",
+ "integrity": "sha512-9MOzQy1UunVBhPOfEuO0JH2ofWAMmZVavTTR/Bo2CkJwI1qjyVF0UKLTXE3l4ujiJnFufOoBsVyKmYWXFerbCw==",
+ "requires": {
+ "@sentry/cli-darwin": "2.33.0",
+ "@sentry/cli-linux-arm": "2.33.0",
+ "@sentry/cli-linux-arm64": "2.33.0",
+ "@sentry/cli-linux-i686": "2.33.0",
+ "@sentry/cli-linux-x64": "2.33.0",
+ "@sentry/cli-win32-i686": "2.33.0",
+ "@sentry/cli-win32-x64": "2.33.0",
"https-proxy-agent": "^5.0.0",
"node-fetch": "^2.6.7",
"progress": "^2.0.3",
@@ -30282,133 +25985,94 @@
}
},
"@sentry/cli-darwin": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.22.3.tgz",
- "integrity": "sha512-A1DwFTffg3+fF68qujaJI07dk/1H1pRuihlvS5WQ9sD7nQLnXZGoLUht4eULixhDzZYinWHKkcWzQ6k40UTvNA==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.33.0.tgz",
+ "integrity": "sha512-LQFvD7uCOQ2P/vYru7IBKqJDHwJ9Rr2vqqkdjbxe2YCQS/N3NPXvi3eVM9hDJ284oyV/BMZ5lrmVTuIicf/hhw==",
"optional": true
},
"@sentry/cli-linux-arm": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.22.3.tgz",
- "integrity": "sha512-mDtLVbqbCu/5b/v2quTAMzY/atGlJVvrqO2Wvpro0Jb/LYhn7Y1pVBdoXEDcnOX82/pseFkLT8PFfq/OcezPhA==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.33.0.tgz",
+ "integrity": "sha512-gY1bFE7wjDJc7WiNq1AS0WrILqLLJUw6Ou4pFQS45KjaH3/XJ1eohHhGJNy/UBHJ/Gq32b/BA9vsnWTXClZJ7g==",
"optional": true
},
"@sentry/cli-linux-arm64": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.22.3.tgz",
- "integrity": "sha512-PnBPb4LJ+A2LlqLjtVFn4mEizcVdxBSLZvB85pEGzq9DRXjZ6ZEuGWFHTVnWvjd79TB/s0me29QnLc3n4B6lgA==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.33.0.tgz",
+ "integrity": "sha512-mR2ZhqpU8RBVGLF5Ji19iOmVznk1B7Bzg5VhA8bVPuKsQmFN/3SyqE87IPMhwKoAsSRXyctwmbAkKs4240fxGA==",
"optional": true
},
"@sentry/cli-linux-i686": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.22.3.tgz",
- "integrity": "sha512-wxvbpQ2hiw4hwJWfJMp7K45BV40nXL62f91jLuftFXIbieKX1Li57NNKNu2JUVn7W1bJxkwz/PKGGTXSgeJlRw==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.33.0.tgz",
+ "integrity": "sha512-XPIy0XpqgAposHtWsy58qsX85QnZ8q0ktBuT4skrsCrLMzfhoQg4Ua+YbUr3RvE814Rt8Hzowx2ar2Rl3pyCyw==",
"optional": true
},
"@sentry/cli-linux-x64": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.22.3.tgz",
- "integrity": "sha512-0GxsYNO5GyRWifeOpng+MmdUFZRA64bgA1n1prsEsXnoeLcm3Zj4Q63hBZmiwz9Qbhf5ibohkpf94a7dI7pv3A==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.33.0.tgz",
+ "integrity": "sha512-qe1DdCUv4tmqS03s8RtCkEX9vCW2G+NgOxX6jZ5jN/sKDwjUlquljqo7JHUGSupkoXmymnNPm5By3rNr6VyNHg==",
"optional": true
},
"@sentry/cli-win32-i686": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.22.3.tgz",
- "integrity": "sha512-YERPsd7ClBrxKcmCUw+ZrAvQfbyIZFrqh269hgDuXFodpsB7LPGnI33ilo0uzmKdq2vGppTb6Z3gf1Rbq0Hadg==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.33.0.tgz",
+ "integrity": "sha512-VEXWtJ69C3b+kuSmXQJRwdQ0ypPGH88hpqyQuosbAOIqh/sv4g9B/u1ETHZc+whLdFDpPcTLVMbLDbXTGug0Yg==",
"optional": true
},
"@sentry/cli-win32-x64": {
- "version": "2.22.3",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.22.3.tgz",
- "integrity": "sha512-NUh56xWvgJo2KuC9lI6o6nTPXdzbpQUB4qGwJ73L9NP3HT2P1I27jtHyrC2zlXTVlYE23gQZGrL3wgW4Jy80QA==",
+ "version": "2.33.0",
+ "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.33.0.tgz",
+ "integrity": "sha512-GIUKysZ1xbSklY9h1aVaLMSYLsnMSd+JuwQLR+0wKw2wJC4O5kNCPFSGikhiOZM/kvh3GO1WnXNyazFp8nLAzw==",
"optional": true
},
"@sentry/core": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.85.0.tgz",
- "integrity": "sha512-DFDAc4tWmHN5IWhr7XbHCiyF1Xgb95jz8Uj/JTX9atlgodId1UIbER77qpEmH3eQGid/QBdqrlR98zCixgSbwg==",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.21.0.tgz",
+ "integrity": "sha512-1eW0HKxpBz23oWR3yshl7kVpoJSq1DtqnSIRK3JkV72ytO+UD5sbGQ2iCzmXrefJHP555EOrui2eMm+akq2sDA==",
"requires": {
- "@sentry/types": "7.85.0",
- "@sentry/utils": "7.85.0"
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0"
}
},
"@sentry/react": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.85.0.tgz",
- "integrity": "sha512-digw63l1A9n+74rW8uiG575Xh3qWTkmvwgTfNRFvDokDRMqRTP0iQEqZRBrBEzMZ5JUa6s+5NLc1/dbMh1QQgA==",
- "requires": {
- "@sentry/browser": "7.85.0",
- "@sentry/types": "7.85.0",
- "@sentry/utils": "7.85.0",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.21.0.tgz",
+ "integrity": "sha512-ypAlRkkjRy/FggrCzf9N6tvuLu04QsC6vE6PCek9vPgTUE3lt25rjF8z34ieC+mzLLpfg/tWDvS4NghMwTgPPQ==",
+ "requires": {
+ "@sentry/browser": "8.21.0",
+ "@sentry/core": "8.21.0",
+ "@sentry/types": "8.21.0",
+ "@sentry/utils": "8.21.0",
"hoist-non-react-statics": "^3.3.2"
}
},
- "@sentry/replay": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.85.0.tgz",
- "integrity": "sha512-zVtTKfO+lu5qTwHpETI/oGo8hU3rdKHr3CdI1vRLw+d60PcAa/pWVlXsQeLRTw8PFwE358gHcpFZezj/11afew==",
- "requires": {
- "@sentry-internal/tracing": "7.85.0",
- "@sentry/core": "7.85.0",
- "@sentry/types": "7.85.0",
- "@sentry/utils": "7.85.0"
- }
- },
"@sentry/types": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.85.0.tgz",
- "integrity": "sha512-R5jR4XkK5tBU2jDiPdSVqzkmjYRr666bcGaFGUHB/xDQCjPsjk+pEmCCL+vpuWoaZmQJUE1hVU7rgnVX81w8zg=="
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry/types/-/types-8.21.0.tgz",
+ "integrity": "sha512-2hF7lhDCGBN8VkIkHTuh9pL3QnJ3QBkIDAcKosFCS5tHGp68zGJgE0VWg2yQvqjZM06DnFT9CUKF9ZGv45FS3w=="
},
"@sentry/utils": {
- "version": "7.85.0",
- "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.85.0.tgz",
- "integrity": "sha512-JZ7seNOLvhjAQ8GeB3GYknPQJkuhF88xAYOaESZP3xPOWBMFUN+IO4RqjMqMLFDniOwsVQS7GB/MfP+hxufieg==",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-8.21.0.tgz",
+ "integrity": "sha512-Evq5goV8CKLISuULenqJm8VyIYaKa6wDAYIHfcDmSyCJIEDlEpRb8S7LcKdYsf6h0FdGy9ofv5ksgMPCqYq7eg==",
"requires": {
- "@sentry/types": "7.85.0"
+ "@sentry/types": "8.21.0"
}
},
"@sentry/vite-plugin": {
- "version": "2.15.0",
- "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-2.15.0.tgz",
- "integrity": "sha512-Q1ML+6p0xBLEbk6pHnZoLs7gQctXrsyI/zzhEQsR/uyPIZIkrwSLcnZ6iCjSz570SvK9H0UVgp1bdLJK/Mpb7Q==",
+ "version": "2.21.1",
+ "resolved": "https://registry.npmjs.org/@sentry/vite-plugin/-/vite-plugin-2.21.1.tgz",
+ "integrity": "sha512-i2PqeLafGBcSROnmr9mS0dL2/JBJji/4rJZ2U2A+tqtAhDAAaCUNalbn6xLp/hawLExt/wRuBj1J7j46sGDOaA==",
"requires": {
- "@sentry/bundler-plugin-core": "2.15.0",
+ "@sentry/bundler-plugin-core": "2.21.1",
"unplugin": "1.0.1"
- },
- "dependencies": {
- "acorn": {
- "version": "8.11.3",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
- "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg=="
- },
- "unplugin": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.0.1.tgz",
- "integrity": "sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==",
- "requires": {
- "acorn": "^8.8.1",
- "chokidar": "^3.5.3",
- "webpack-sources": "^3.2.3",
- "webpack-virtual-modules": "^0.5.0"
- }
- }
}
},
- "@sideway/address": {
- "version": "4.1.1",
- "dev": true,
- "requires": {
- "@hapi/hoek": "^9.0.0"
- }
- },
- "@sideway/formula": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
- "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
- "dev": true
- },
- "@sideway/pinpoint": {
- "version": "2.0.0",
+ "@sinclair/typebox": {
+ "version": "0.27.8",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
+ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
"dev": true
},
"@sinonjs/commons": {
@@ -30425,6 +26089,34 @@
"@sinonjs/commons": "^1.7.0"
}
},
+ "@snyk/github-codeowners": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@snyk/github-codeowners/-/github-codeowners-1.1.0.tgz",
+ "integrity": "sha512-lGFf08pbkEac0NYgVf4hdANpAgApRjNByLXB+WBip3qj1iendOIyAwP2GKkKbQMNVy2r1xxDf0ssfWscoiC+Vw==",
+ "dev": true,
+ "requires": {
+ "commander": "^4.1.1",
+ "ignore": "^5.1.8",
+ "p-map": "^4.0.0"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+ "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+ "dev": true
+ },
+ "p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "dev": true,
+ "requires": {
+ "aggregate-error": "^3.0.0"
+ }
+ }
+ }
+ },
"@swc/core": {
"version": "1.3.40",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.40.tgz",
@@ -30503,32 +26195,43 @@
"integrity": "sha512-73DGsjsJYSzmoRbfomPj5jcQawtK2H0bCDi/1wgfl8NKVOuzrq+PpaTry3lzx+gvTHxUX6mUHV22i7C9ITL74Q==",
"optional": true
},
+ "@swc/counter": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
+ "dev": true
+ },
"@swc/jest": {
- "version": "0.2.26",
- "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.26.tgz",
- "integrity": "sha512-7lAi7q7ShTO3E5Gt1Xqf3pIhRbERxR1DUxvtVa9WKzIB+HGQ7wZP5sYx86zqnaEoKKGhmOoZ7gyW0IRu8Br5+A==",
+ "version": "0.2.36",
+ "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.36.tgz",
+ "integrity": "sha512-8X80dp81ugxs4a11z1ka43FPhP+/e+mJNXJSxiNYk8gIX/jPBtY4gQTrKu/KIoco8bzKuPI5lUxjfLiGsfvnlw==",
"dev": true,
"requires": {
- "@jest/create-cache-key-function": "^27.4.2",
+ "@jest/create-cache-key-function": "^29.7.0",
+ "@swc/counter": "^0.1.3",
"jsonc-parser": "^3.2.0"
}
},
"@testing-library/dom": {
- "version": "8.19.0",
+ "version": "8.20.1",
+ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz",
+ "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==",
"optional": true,
"requires": {
"@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5",
- "@types/aria-query": "^4.2.0",
- "aria-query": "^5.0.0",
+ "@types/aria-query": "^5.0.1",
+ "aria-query": "5.1.3",
"chalk": "^4.1.0",
"dom-accessibility-api": "^0.5.9",
- "lz-string": "^1.4.4",
+ "lz-string": "^1.5.0",
"pretty-format": "^27.0.2"
},
"dependencies": {
"chalk": {
"version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
@@ -30537,10 +26240,14 @@
},
"has-flag": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"optional": true
},
"supports-color": {
"version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"optional": true,
"requires": {
"has-flag": "^4.0.0"
@@ -30549,7 +26256,9 @@
}
},
"@testing-library/jest-dom": {
- "version": "5.16.5",
+ "version": "5.17.0",
+ "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz",
+ "integrity": "sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==",
"optional": true,
"requires": {
"@adobe/css-tools": "^4.0.1",
@@ -30586,6 +26295,8 @@
},
"@testing-library/react": {
"version": "12.1.5",
+ "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz",
+ "integrity": "sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==",
"optional": true,
"requires": {
"@babel/runtime": "^7.12.5",
@@ -30602,7 +26313,9 @@
}
},
"@testing-library/user-event": {
- "version": "14.4.3",
+ "version": "14.5.2",
+ "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz",
+ "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==",
"optional": true
},
"@toast-ui/editor": {
@@ -30631,7 +26344,7 @@
},
"@tootallnate/once": {
"version": "1.1.2",
- "devOptional": true
+ "optional": true
},
"@tsconfig/node10": {
"version": "1.0.9",
@@ -30725,7 +26438,9 @@
}
},
"@types/aria-query": {
- "version": "4.2.2",
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
+ "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
"optional": true
},
"@types/babel__core": {
@@ -30784,6 +26499,7 @@
"version": "4.1.7",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz",
"integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==",
+ "dev": true,
"requires": {
"@types/ms": "*"
}
@@ -30832,14 +26548,11 @@
"hoist-non-react-statics": "^3.3.0"
}
},
- "@types/is-ci": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@types/is-ci/-/is-ci-3.0.0.tgz",
- "integrity": "sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ==",
- "dev": true,
- "requires": {
- "ci-info": "^3.1.0"
- }
+ "@types/is-url": {
+ "version": "1.2.32",
+ "resolved": "https://registry.npmjs.org/@types/is-url/-/is-url-1.2.32.tgz",
+ "integrity": "sha512-46VLdbWI8Sc+hPexQ6NLNR2YpoDyDZIpASHkJQ2Yr+Kf9Giw6LdCTkwOdsnHKPQeh7xTjTmSnxbE8qpxYuCiHA==",
+ "dev": true
},
"@types/istanbul-lib-coverage": {
"version": "2.0.3",
@@ -30955,49 +26668,31 @@
"dev": true
},
"@types/lodash": {
- "version": "4.14.191",
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
- "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==",
+ "version": "4.17.9",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.9.tgz",
+ "integrity": "sha512-w9iWudx1XWOHW5lQRS9iKpK/XuRhnN+0T7HvdCCd802FYkT1AMTnxndJHGrNJwRoRHkslGr4S29tjm1cT7x/7w==",
"dev": true
},
"@types/lodash-es": {
- "version": "4.17.6",
- "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.6.tgz",
- "integrity": "sha512-R+zTeVUKDdfoRxpAryaQNRKk3105Rrgx2CFRClIgRGaqDTdjsm8h6IYA8ir584W3ePzkZfst5xIgDwYrlh9HLg==",
+ "version": "4.17.12",
+ "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
+ "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
"dev": true,
"requires": {
"@types/lodash": "*"
}
},
- "@types/mdast": {
- "version": "3.0.12",
- "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.12.tgz",
- "integrity": "sha512-DT+iNIRNX884cx0/Q1ja7NyUPpZuv0KPyL5rGNxm1WC1OtHstl7n4Jb7nk+xacNShQMbczJjt8uFzznpp6kYBg==",
- "requires": {
- "@types/unist": "^2"
- }
- },
- "@types/minimist": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
- "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==",
- "dev": true
- },
"@types/ms": {
"version": "0.7.31",
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",
- "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
+ "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==",
+ "dev": true
},
"@types/node": {
"version": "20.8.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.0.tgz",
- "integrity": "sha512-LzcWltT83s1bthcvjBmiBvGJiiUe84NWRHkw+ZV6Fr41z2FbIzvc815dk2nQ3RAKMuN2fkenM/z3Xv2QzEpYxQ=="
- },
- "@types/normalize-package-data": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
- "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
- "dev": true
+ "integrity": "sha512-LzcWltT83s1bthcvjBmiBvGJiiUe84NWRHkw+ZV6Fr41z2FbIzvc815dk2nQ3RAKMuN2fkenM/z3Xv2QzEpYxQ==",
+ "devOptional": true
},
"@types/parse-json": {
"version": "4.0.0"
@@ -31080,15 +26775,6 @@
"@types/react": "*"
}
},
- "@types/react-infinite-scroller": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@types/react-infinite-scroller/-/react-infinite-scroller-1.2.3.tgz",
- "integrity": "sha512-l60JckVoO+dxmKW2eEG7jbliEpITsTJvRPTe97GazjF5+ylagAuyYdXl8YY9DQsTP9QjhqGKZROknzgscGJy0A==",
- "dev": true,
- "requires": {
- "@types/react": "*"
- }
- },
"@types/react-router": {
"version": "5.1.13",
"dev": true,
@@ -31138,17 +26824,14 @@
"optional": true
},
"@types/testing-library__jest-dom": {
- "version": "5.14.5",
+ "version": "5.14.9",
+ "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz",
+ "integrity": "sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==",
"optional": true,
"requires": {
"@types/jest": "*"
}
},
- "@types/unist": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
- "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ=="
- },
"@types/url-join": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/url-join/-/url-join-4.0.1.tgz",
@@ -31163,12 +26846,8 @@
},
"@types/webappsec-credential-management": {
"version": "0.5.1",
- "dev": true
- },
- "@types/webpack-env": {
- "version": "1.18.0",
- "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.0.tgz",
- "integrity": "sha512-56/MAlX5WMsPVbOg7tAxnYvNYMMWr/QJiIp6BxVSW3JJXUVzzOn64qW8TzQyMSqSUFM2+PVI4aUHcHOzIz/1tg==",
+ "resolved": "https://registry.npmjs.org/@types/webappsec-credential-management/-/webappsec-credential-management-0.5.1.tgz",
+ "integrity": "sha512-ZIl4fCJm3mo0jzivFnxhA4qYEY/HicVPxLbcqQTZ3JjnhEFJwYAEPEZft7AJo/MVxHU4mFdAauX+jo+a4m1Qkg==",
"dev": true
},
"@types/ws": {
@@ -31182,7 +26861,7 @@
},
"@types/yargs": {
"version": "16.0.5",
- "devOptional": true,
+ "optional": true,
"requires": {
"@types/yargs-parser": "*"
}
@@ -31315,45 +26994,6 @@
}
}
},
- "@uiw/react-color-editable-input": {
- "version": "0.1.0",
- "requires": {
- "@babel/runtime": "7.14.6"
- },
- "dependencies": {
- "@babel/runtime": {
- "version": "7.14.6",
- "requires": {
- "regenerator-runtime": "^0.13.4"
- }
- },
- "regenerator-runtime": {
- "version": "0.13.9"
- }
- }
- },
- "@uiw/react-color-editable-input-rgba": {
- "version": "0.1.0",
- "requires": {
- "@babel/runtime": "7.14.6",
- "@uiw/color-convert": "^0.1.0",
- "@uiw/react-color-editable-input": "^0.1.0"
- },
- "dependencies": {
- "@babel/runtime": {
- "version": "7.14.6",
- "requires": {
- "regenerator-runtime": "^0.13.4"
- }
- },
- "@uiw/color-convert": {
- "version": "0.1.0"
- },
- "regenerator-runtime": {
- "version": "0.13.9"
- }
- }
- },
"@uiw/react-color-hue": {
"version": "0.0.34",
"requires": {
@@ -31373,29 +27013,6 @@
}
}
},
- "@uiw/react-color-material": {
- "version": "0.1.0",
- "requires": {
- "@babel/runtime": "7.14.6",
- "@uiw/color-convert": "^0.1.0",
- "@uiw/react-color-editable-input": "^0.1.0",
- "@uiw/react-color-editable-input-rgba": "^0.1.0"
- },
- "dependencies": {
- "@babel/runtime": {
- "version": "7.14.6",
- "requires": {
- "regenerator-runtime": "^0.13.4"
- }
- },
- "@uiw/color-convert": {
- "version": "0.1.0"
- },
- "regenerator-runtime": {
- "version": "0.13.9"
- }
- }
- },
"@uiw/react-color-saturation": {
"version": "0.0.34",
"requires": {
@@ -31438,9 +27055,9 @@
"integrity": "sha512-PZAcHROlgtCUGI2y0JntdNwvPwCNyeVnkQu6KTYKdmxBbK3w72XJUmLFYapfaFfgami4I9CTLnrJTPdtmS3gpw=="
},
"@vanilla-extract/recipes": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/@vanilla-extract/recipes/-/recipes-0.5.0.tgz",
- "integrity": "sha512-NfdZ8XyqCDG2RsO3FmYPALDMKg5045dRD97NbBb0Fog3LMDVXZxYgDOct5FAWob8U6W4GbhVpRZt1X9hNnH6fA=="
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/@vanilla-extract/recipes/-/recipes-0.5.5.tgz",
+ "integrity": "sha512-VadU7+IFUwLNLMgks29AHav/K5h7DOEfTU91RItn5vwdPfzduodNg317YbgWCcpm7FSXkuR3B3X8ZOi95UOozA=="
},
"@vitejs/plugin-react-swc": {
"version": "3.2.0",
@@ -31697,9 +27314,9 @@
}
},
"ansi-colors": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
- "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
"devOptional": true
},
"ansi-escapes": {
@@ -31747,20 +27364,18 @@
"sprintf-js": "~1.0.2"
}
},
- "argv": {
- "version": "0.0.2",
- "dev": true
- },
"aria-hidden": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz",
- "integrity": "sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==",
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz",
+ "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==",
"requires": {
"tslib": "^2.0.0"
}
},
"aria-query": {
- "version": "5.1.1",
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
+ "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==",
"optional": true,
"requires": {
"deep-equal": "^2.0.5"
@@ -31811,7 +27426,8 @@
}
},
"array-union": {
- "version": "2.1.0"
+ "version": "2.1.0",
+ "dev": true
},
"array.prototype.flat": {
"version": "1.3.1",
@@ -31850,12 +27466,10 @@
"get-intrinsic": "^1.1.3"
}
},
- "arrify": {
- "version": "1.0.1",
- "dev": true
- },
"asap": {
"version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==",
"dev": true
},
"asn1js": {
@@ -31881,26 +27495,21 @@
},
"asynckit": {
"version": "0.4.0",
- "devOptional": true
+ "optional": true
},
"attr-accept": {
"version": "2.2.2"
},
"auto-bind": {
"version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz",
+ "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==",
"dev": true
},
"available-typed-arrays": {
"version": "1.0.5",
"optional": true
},
- "axios": {
- "version": "0.21.4",
- "dev": true,
- "requires": {
- "follow-redirects": "^1.14.0"
- }
- },
"babel-jest": {
"version": "27.5.1",
"optional": true,
@@ -31969,6 +27578,8 @@
},
"babel-plugin-syntax-trailing-function-commas": {
"version": "7.0.0-beta.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz",
+ "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==",
"dev": true
},
"babel-preset-current-node-syntax": {
@@ -31991,6 +27602,8 @@
},
"babel-preset-fbjs": {
"version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.4.0.tgz",
+ "integrity": "sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==",
"dev": true,
"requires": {
"@babel/plugin-proposal-class-properties": "^7.0.0",
@@ -32030,11 +27643,6 @@
"babel-preset-current-node-syntax": "^1.0.0"
}
},
- "bail": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz",
- "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="
- },
"balanced-match": {
"version": "1.0.2"
},
@@ -32051,10 +27659,6 @@
"is-windows": "^1.0.0"
}
},
- "big.js": {
- "version": "5.2.2",
- "dev": true
- },
"bindings": {
"version": "1.5.0",
"optional": true,
@@ -32081,10 +27685,6 @@
}
}
},
- "bluebird": {
- "version": "3.7.2",
- "dev": true
- },
"boolbase": {
"version": "1.0.0",
"dev": true
@@ -32103,15 +27703,6 @@
"fill-range": "^7.0.1"
}
},
- "breakword": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/breakword/-/breakword-1.0.5.tgz",
- "integrity": "sha512-ex5W9DoOQ/LUEU3PMdLs9ua/CYZl1678NUkKOdUSi8Aw5F1idieaiRURCBFJCwVcrD1J8Iy3vfWSloaMwO2qFg==",
- "dev": true,
- "requires": {
- "wcwidth": "^1.0.1"
- }
- },
"browser-process-hrtime": {
"version": "1.0.0",
"optional": true
@@ -32123,14 +27714,14 @@
"dev": true
},
"browserslist": {
- "version": "4.23.0",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
- "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
+ "version": "4.24.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz",
+ "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==",
"requires": {
- "caniuse-lite": "^1.0.30001587",
- "electron-to-chromium": "^1.4.668",
- "node-releases": "^2.0.14",
- "update-browserslist-db": "^1.0.13"
+ "caniuse-lite": "^1.0.30001663",
+ "electron-to-chromium": "^1.5.28",
+ "node-releases": "^2.0.18",
+ "update-browserslist-db": "^1.1.0"
}
},
"bs-logger": {
@@ -32175,29 +27766,10 @@
"version": "5.3.1",
"devOptional": true
},
- "camelcase-keys": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
- "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
- "dev": true,
- "requires": {
- "camelcase": "^5.3.1",
- "map-obj": "^4.0.0",
- "quick-lru": "^4.0.1"
- },
- "dependencies": {
- "quick-lru": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
- "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==",
- "dev": true
- }
- }
- },
"caniuse-lite": {
- "version": "1.0.30001610",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001610.tgz",
- "integrity": "sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA=="
+ "version": "1.0.30001664",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz",
+ "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g=="
},
"canvas-hypertxt": {
"version": "0.0.7",
@@ -32223,11 +27795,6 @@
}
}
},
- "ccount": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
- "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="
- },
"chalk": {
"version": "2.4.2",
"requires": {
@@ -32317,11 +27884,6 @@
"version": "1.0.2",
"optional": true
},
- "character-entities": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
- "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="
- },
"chardet": {
"version": "0.7.0",
"dev": true
@@ -32330,10 +27892,6 @@
"version": "0.0.2",
"optional": true
},
- "check-more-types": {
- "version": "2.24.0",
- "dev": true
- },
"chokidar": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@@ -32558,27 +28116,6 @@
}
}
},
- "codecov": {
- "version": "3.8.1",
- "dev": true,
- "requires": {
- "argv": "0.0.2",
- "ignore-walk": "3.0.3",
- "js-yaml": "3.14.0",
- "teeny-request": "6.0.1",
- "urlgrey": "0.4.4"
- },
- "dependencies": {
- "js-yaml": {
- "version": "3.14.0",
- "dev": true,
- "requires": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- }
- }
- }
- },
"codemirror": {
"version": "5.65.11"
},
@@ -32597,12 +28134,6 @@
}
}
},
- "codex-notifier": {
- "version": "1.1.2"
- },
- "codex-tooltip": {
- "version": "1.0.5"
- },
"collect-v8-coverage": {
"version": "1.0.1",
"optional": true
@@ -32624,7 +28155,7 @@
},
"combined-stream": {
"version": "1.0.8",
- "devOptional": true,
+ "optional": true,
"requires": {
"delayed-stream": "~1.0.0"
}
@@ -32636,7 +28167,9 @@
"dev": true
},
"common-tags": {
- "version": "1.8.0",
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
+ "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
"dev": true
},
"compute-scroll-into-view": {
@@ -32691,7 +28224,9 @@
}
},
"core-js": {
- "version": "3.10.1",
+ "version": "3.38.1",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz",
+ "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==",
"dev": true
},
"cosmiconfig": {
@@ -32712,11 +28247,6 @@
"integrity": "sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==",
"dev": true
},
- "crc-32": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
- "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="
- },
"create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
@@ -32779,29 +28309,6 @@
"version": "0.0.2",
"optional": true
},
- "css-jss": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
- "jss-preset-default": "10.6.0"
- },
- "dependencies": {
- "csstype": {
- "version": "3.0.7"
- },
- "jss": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- }
- }
- }
- },
"css-vendor": {
"version": "2.0.8",
"requires": {
@@ -32837,36 +28344,6 @@
"csstype": {
"version": "2.6.16"
},
- "csv": {
- "version": "5.5.3",
- "resolved": "https://registry.npmjs.org/csv/-/csv-5.5.3.tgz",
- "integrity": "sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==",
- "dev": true,
- "requires": {
- "csv-generate": "^3.4.3",
- "csv-parse": "^4.16.3",
- "csv-stringify": "^5.6.5",
- "stream-transform": "^2.1.3"
- }
- },
- "csv-generate": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-3.4.3.tgz",
- "integrity": "sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==",
- "dev": true
- },
- "csv-parse": {
- "version": "4.16.3",
- "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.16.3.tgz",
- "integrity": "sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==",
- "dev": true
- },
- "csv-stringify": {
- "version": "5.6.5",
- "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.6.5.tgz",
- "integrity": "sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==",
- "dev": true
- },
"currency-codes": {
"version": "2.1.0",
"requires": {
@@ -32921,36 +28398,10 @@
"version": "1.2.0",
"dev": true
},
- "decamelize-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
- "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
- "dev": true,
- "requires": {
- "decamelize": "^1.1.0",
- "map-obj": "^1.0.0"
- },
- "dependencies": {
- "map-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
- "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
- "dev": true
- }
- }
- },
"decimal.js": {
"version": "10.4.3",
"optional": true
},
- "decode-named-character-reference": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
- "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==",
- "requires": {
- "character-entities": "^2.0.0"
- }
- },
"dedent": {
"version": "0.7.0",
"optional": true
@@ -32980,7 +28431,7 @@
},
"delayed-stream": {
"version": "1.0.0",
- "devOptional": true
+ "optional": true
},
"depd": {
"version": "2.0.0",
@@ -33165,13 +28616,10 @@
},
"dependency-graph": {
"version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
+ "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==",
"dev": true
},
- "dequal": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
- "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="
- },
"detect-indent": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
@@ -33195,6 +28643,7 @@
},
"dir-glob": {
"version": "3.0.1",
+ "dev": true,
"requires": {
"path-type": "^4.0.0"
}
@@ -33207,7 +28656,9 @@
}
},
"dom-accessibility-api": {
- "version": "0.5.14",
+ "version": "0.5.16",
+ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
+ "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
"optional": true
},
"dom-helpers": {
@@ -33331,9 +28782,15 @@
"integrity": "sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==",
"dev": true
},
- "duplexer": {
- "version": "0.1.2",
- "dev": true
+ "easy-table": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.2.0.tgz",
+ "integrity": "sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1",
+ "wcwidth": "^1.0.1"
+ }
},
"editorjs-inline-tool": {
"version": "0.4.0"
@@ -33348,9 +28805,9 @@
}
},
"electron-to-chromium": {
- "version": "1.4.737",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.737.tgz",
- "integrity": "sha512-QvLTxaLHKdy5YxvixAw/FfHq2eWLUL9KvsPjp0aHK1gI5d3EDuDgITkvj0nFO2c6zUY3ZqVAJQiBYyQP9tQpfw=="
+ "version": "1.5.29",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.29.tgz",
+ "integrity": "sha512-PF8n2AlIhCKXQ+gTpiJi0VhcHDb69kYX4MtCiivctc2QD3XuNZ/XIOlbGzt7WAjjEev0TtaH6Cu3arZExm5DOw=="
},
"emittery": {
"version": "0.8.1",
@@ -33360,10 +28817,6 @@
"version": "8.0.0",
"devOptional": true
},
- "emojis-list": {
- "version": "3.0.0",
- "dev": true
- },
"end-of-stream": {
"version": "1.4.4",
"devOptional": true,
@@ -33371,6 +28824,16 @@
"once": "^1.4.0"
}
},
+ "enhanced-resolve": {
+ "version": "5.17.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz",
+ "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ }
+ },
"enquirer": {
"version": "2.3.6",
"devOptional": true,
@@ -33381,12 +28844,6 @@
"entities": {
"version": "2.2.0"
},
- "env-var": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/env-var/-/env-var-7.3.0.tgz",
- "integrity": "sha512-qwtwYJ9d3XFxXRDudPEAMszaggpDgcfb1ZGYb9/cNyMugN2/a8EtviopnRL6c+petj2vp6/gxwYd9ExL1/iPcw==",
- "dev": true
- },
"error-ex": {
"version": "1.3.2",
"requires": {
@@ -33461,167 +28918,6 @@
"is-symbol": "^1.0.2"
}
},
- "esbuild": {
- "version": "0.14.34",
- "dev": true,
- "requires": {
- "esbuild-android-64": "0.14.34",
- "esbuild-android-arm64": "0.14.34",
- "esbuild-darwin-64": "0.14.34",
- "esbuild-darwin-arm64": "0.14.34",
- "esbuild-freebsd-64": "0.14.34",
- "esbuild-freebsd-arm64": "0.14.34",
- "esbuild-linux-32": "0.14.34",
- "esbuild-linux-64": "0.14.34",
- "esbuild-linux-arm": "0.14.34",
- "esbuild-linux-arm64": "0.14.34",
- "esbuild-linux-mips64le": "0.14.34",
- "esbuild-linux-ppc64le": "0.14.34",
- "esbuild-linux-riscv64": "0.14.34",
- "esbuild-linux-s390x": "0.14.34",
- "esbuild-netbsd-64": "0.14.34",
- "esbuild-openbsd-64": "0.14.34",
- "esbuild-sunos-64": "0.14.34",
- "esbuild-windows-32": "0.14.34",
- "esbuild-windows-64": "0.14.34",
- "esbuild-windows-arm64": "0.14.34"
- },
- "dependencies": {
- "esbuild-android-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.34.tgz",
- "integrity": "sha512-XfxcfJqmMYsT/LXqrptzFxmaR3GWzXHDLdFNIhm6S00zPaQF1TBBWm+9t0RZ6LRR7iwH57DPjaOeW20vMqI4Yw==",
- "dev": true,
- "optional": true
- },
- "esbuild-android-arm64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.34.tgz",
- "integrity": "sha512-T02+NXTmSRL1Mc6puz+R9CB54rSPICkXKq6+tw8B6vxZFnCPzbJxgwIX4kcluz9p8nYBjF3+lSilTGWb7+Xgew==",
- "dev": true,
- "optional": true
- },
- "esbuild-darwin-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.34.tgz",
- "integrity": "sha512-pLRip2Bh4Ng7Bf6AMgCrSp3pPe/qZyf11h5Qo2mOfJqLWzSVjxrXW+CFRJfrOVP7TCnh/gmZSM2AFdCPB72vtw==",
- "dev": true,
- "optional": true
- },
- "esbuild-freebsd-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.34.tgz",
- "integrity": "sha512-m0HBjePhe0hAQJgtMRMNV9kMgIyV4/qSnzPx42kRMQBcPhgjAq1JRu4Il26czC+9FgpMbFkUktb07f/Lwnc6CA==",
- "dev": true,
- "optional": true
- },
- "esbuild-freebsd-arm64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.34.tgz",
- "integrity": "sha512-cpRc2B94L1KvMPPYB4D6G39jLqpKlD3noAMY4/e86iXXXkhUYJJEtTuyNFTa9JRpWM0xCAp4mxjHjoIiLuoCLA==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-32": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.34.tgz",
- "integrity": "sha512-8nQaEaoW7MH/K/RlozJa+lE1ejHIr8fuPIHhc513UebRav7HtXgQvxHQ6VZRUkWtep23M6dd7UqhwO1tMOfzQQ==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.34.tgz",
- "integrity": "sha512-Y3of4qQoLLlAgf042MlrY1P+7PnN9zWj8nVtw9XQG5hcLOZLz7IKpU35oeu7n4wvyaZHwvQqDJ93gRLqdJekcQ==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-arm": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.34.tgz",
- "integrity": "sha512-9lpq1NcJqssAF7alCO6zL3gvBVVt/lKw4oetUM7OgNnRX0OWpB+ZIO9FwCrSj/dMdmgDhPLf+119zB8QxSMmAg==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-arm64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.34.tgz",
- "integrity": "sha512-IlWaGtj9ir7+Nrume1DGcyzBDlK8GcnJq0ANKwcI9pVw8tqr+6GD0eqyF9SF1mR8UmAp+odrx1H5NdR2cHdFHA==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-mips64le": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.34.tgz",
- "integrity": "sha512-k3or+01Rska1AjUyNjA4buEwB51eyN/xPQAoOx1CjzAQC3l8rpjUDw55kXyL63O/1MUi4ISvtNtl8gLwdyEcxw==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-ppc64le": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.34.tgz",
- "integrity": "sha512-+qxb8M9FfM2CJaVU7GgYpJOHM1ngQOx+/VrtBjb4C8oVqaPcESCeg2anjl+HRZy8VpYc71q/iBYausPPbJ+Keg==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-riscv64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.34.tgz",
- "integrity": "sha512-Y717ltBdQ5j5sZIHdy1DV9kieo0wMip0dCmVSTceowCPYSn1Cg33Kd6981+F/3b9FDMzNWldZFOBRILViENZSA==",
- "dev": true,
- "optional": true
- },
- "esbuild-linux-s390x": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.34.tgz",
- "integrity": "sha512-bDDgYO4LhL4+zPs+WcBkXph+AQoPcQRTv18FzZS0WhjfH8TZx2QqlVPGhmhZ6WidrY+jKthUqO6UhGyIb4MpmA==",
- "dev": true,
- "optional": true
- },
- "esbuild-netbsd-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.34.tgz",
- "integrity": "sha512-cfaFGXdRt0+vHsjNPyF0POM4BVSHPSbhLPe8mppDc7GDDxjIl08mV1Zou14oDWMp/XZMjYN1kWYRSfftiD0vvQ==",
- "dev": true,
- "optional": true
- },
- "esbuild-openbsd-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.34.tgz",
- "integrity": "sha512-vmy9DxXVnRiI14s8GKuYBtess+EVcDALkbpTqd5jw4XITutIzyB7n4x0Tj5utAkKsgZJB22lLWGekr0ABnSLow==",
- "dev": true,
- "optional": true
- },
- "esbuild-sunos-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.34.tgz",
- "integrity": "sha512-eNPVatNET1F7tRMhii7goL/eptfxc0ALRjrj9SPFNqp0zmxrehBFD6BaP3R4LjMn6DbMO0jOAnTLFKr8NqcJAA==",
- "dev": true,
- "optional": true
- },
- "esbuild-windows-32": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.34.tgz",
- "integrity": "sha512-EFhpXyHEcnqWYe2rAHFd8dRw8wkrd9U+9oqcyoEL84GbanAYjiiIjBZsnR8kl0sCQ5w6bLpk7vCEIA2VS32Vcg==",
- "dev": true,
- "optional": true
- },
- "esbuild-windows-64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.34.tgz",
- "integrity": "sha512-a8fbl8Ky7PxNEjf1aJmtxdDZj32/hC7S1OcA2ckEpCJRTjiKslI9vAdPpSjrKIWhws4Galpaawy0nB7fjHYf5Q==",
- "dev": true,
- "optional": true
- },
- "esbuild-windows-arm64": {
- "version": "0.14.34",
- "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.34.tgz",
- "integrity": "sha512-EYvmKbSa2B3sPnpC28UEu9jBK5atGV4BaVRE7CYGUci2Hlz4AvtV/LML+TcDMT6gBgibnN2gcltWclab3UutMg==",
- "dev": true,
- "optional": true
- }
- }
- },
"esbuild-android-64": {
"version": "0.15.15",
"resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.15.15.tgz",
@@ -33643,11 +28939,6 @@
"dev": true,
"optional": true
},
- "esbuild-darwin-arm64": {
- "version": "0.14.34",
- "dev": true,
- "optional": true
- },
"esbuild-freebsd-64": {
"version": "0.15.15",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.15.tgz",
@@ -33718,32 +29009,6 @@
"dev": true,
"optional": true
},
- "esbuild-loader": {
- "version": "2.18.0",
- "dev": true,
- "requires": {
- "esbuild": "^0.14.6",
- "joycon": "^3.0.1",
- "json5": "^2.2.0",
- "loader-utils": "^2.0.0",
- "tapable": "^2.2.0",
- "webpack-sources": "^2.2.0"
- },
- "dependencies": {
- "source-map": {
- "version": "0.6.1",
- "dev": true
- },
- "webpack-sources": {
- "version": "2.3.1",
- "dev": true,
- "requires": {
- "source-list-map": "^2.0.1",
- "source-map": "^0.6.1"
- }
- }
- }
- },
"esbuild-netbsd-64": {
"version": "0.15.15",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.15.tgz",
@@ -33787,7 +29052,9 @@
"optional": true
},
"escalade": {
- "version": "3.1.1"
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="
},
"escape-html": {
"version": "1.0.3",
@@ -33889,16 +29156,6 @@
"estraverse": "^5.2.0"
}
},
- "find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "requires": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- }
- },
"glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -33938,15 +29195,6 @@
"type-check": "~0.4.0"
}
},
- "locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "requires": {
- "p-locate": "^5.0.0"
- }
- },
"optionator": {
"version": "0.9.1",
"dev": true,
@@ -33959,30 +29207,6 @@
"word-wrap": "^1.2.3"
}
},
- "p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "requires": {
- "yocto-queue": "^0.1.0"
- }
- },
- "p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "requires": {
- "p-limit": "^3.0.2"
- }
- },
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
- },
"prelude-ls": {
"version": "1.2.1",
"dev": true
@@ -34614,19 +29838,6 @@
"version": "2.0.3",
"devOptional": true
},
- "event-stream": {
- "version": "3.3.4",
- "dev": true,
- "requires": {
- "duplexer": "~0.1.1",
- "from": "~0",
- "map-stream": "~0.1.0",
- "pause-stream": "0.0.11",
- "split": "0.3",
- "stream-combiner": "~0.0.4",
- "through": "~2.3.1"
- }
- },
"execa": {
"version": "4.1.0",
"devOptional": true,
@@ -34660,7 +29871,8 @@
}
},
"extend": {
- "version": "3.0.2"
+ "version": "3.0.2",
+ "dev": true
},
"extendable-error": {
"version": "0.1.7",
@@ -34703,6 +29915,7 @@
},
"fast-glob": {
"version": "3.2.11",
+ "dev": true,
"requires": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
@@ -34746,9 +29959,9 @@
}
},
"fast-xml-parser": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.6.tgz",
- "integrity": "sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==",
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz",
+ "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==",
"dev": true,
"requires": {
"strnum": "^1.0.5"
@@ -34756,6 +29969,7 @@
},
"fastq": {
"version": "1.11.0",
+ "dev": true,
"requires": {
"reusify": "^1.0.4"
}
@@ -34768,20 +29982,24 @@
}
},
"fbjs": {
- "version": "3.0.0",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-3.0.5.tgz",
+ "integrity": "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==",
"dev": true,
"requires": {
- "cross-fetch": "^3.0.4",
+ "cross-fetch": "^3.1.5",
"fbjs-css-vars": "^1.0.0",
"loose-envify": "^1.0.0",
"object-assign": "^4.1.0",
"promise": "^7.1.1",
"setimmediate": "^1.0.5",
- "ua-parser-js": "^0.7.18"
+ "ua-parser-js": "^1.0.35"
}
},
"fbjs-css-vars": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
+ "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==",
"dev": true
},
"fflate": {
@@ -34847,77 +30065,13 @@
"find-root": {
"version": "1.1.0"
},
- "find-test-names": {
- "version": "1.28.13",
- "resolved": "https://registry.npmjs.org/find-test-names/-/find-test-names-1.28.13.tgz",
- "integrity": "sha512-hVatCLbiZmvBwqYNGTkVNbeJwK/8pvkXKQGji+23GzW8fVFHcEaRID77eQYItLKGwa1Tmu0AK2LjcUtuid57FQ==",
- "requires": {
- "@babel/parser": "^7.21.2",
- "@babel/plugin-syntax-jsx": "^7.18.6",
- "acorn-walk": "^8.2.0",
- "debug": "^4.3.3",
- "globby": "^11.0.4",
- "simple-bin-help": "^1.8.0"
- },
- "dependencies": {
- "acorn-walk": {
- "version": "8.2.0"
- }
- }
- },
- "find-yarn-workspace-root2": {
- "version": "1.2.16",
- "resolved": "https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz",
- "integrity": "sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==",
- "dev": true,
+ "find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"requires": {
- "micromatch": "^4.0.2",
- "pkg-dir": "^4.2.0"
- },
- "dependencies": {
- "find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "requires": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- }
- },
- "locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "requires": {
- "p-locate": "^4.1.0"
- }
- },
- "p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "requires": {
- "p-limit": "^2.2.0"
- }
- },
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
- },
- "pkg-dir": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
- "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
- "dev": true,
- "requires": {
- "find-up": "^4.0.0"
- }
- }
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
}
},
"first-match": {
@@ -34947,12 +30101,6 @@
"tslib": "^2.0.3"
}
},
- "follow-redirects": {
- "version": "1.15.2",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
- "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
- "dev": true
- },
"for-each": {
"version": "0.3.3",
"optional": true,
@@ -34960,10 +30108,6 @@
"is-callable": "^1.1.3"
}
},
- "from": {
- "version": "0.1.7",
- "dev": true
- },
"front-matter": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz",
@@ -34973,18 +30117,16 @@
}
},
"fs-extra": {
- "version": "8.1.0",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+ "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
"dev": true,
"requires": {
- "graceful-fs": "^4.2.0",
+ "graceful-fs": "^4.1.2",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
- "fs-readdir-recursive": {
- "version": "1.1.0",
- "dev": true
- },
"fs.realpath": {
"version": "1.0.0"
},
@@ -35061,9 +30203,6 @@
"get-intrinsic": "^1.1.1"
}
},
- "github-buttons": {
- "version": "2.22.1"
- },
"glob": {
"version": "7.2.3",
"devOptional": true,
@@ -35102,6 +30241,7 @@
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
"requires": {
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
@@ -35162,16 +30302,6 @@
"tslib": "^2.4.0"
},
"dependencies": {
- "@graphql-tools/utils": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-9.2.1.tgz",
- "integrity": "sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==",
- "dev": true,
- "requires": {
- "@graphql-typed-document-node/core": "^3.1.1",
- "tslib": "^2.4.0"
- }
- },
"argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -35217,30 +30347,6 @@
"vscode-languageserver-types": "^3.17.1"
}
},
- "graphql-request": {
- "version": "3.7.0",
- "dev": true,
- "requires": {
- "cross-fetch": "^3.0.6",
- "extract-files": "^9.0.0",
- "form-data": "^3.0.0"
- },
- "dependencies": {
- "extract-files": {
- "version": "9.0.0",
- "dev": true
- },
- "form-data": {
- "version": "3.0.1",
- "dev": true,
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- }
- }
- }
- },
"graphql-tag": {
"version": "2.12.6",
"resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz",
@@ -35276,14 +30382,10 @@
}
}
},
- "hard-rejection": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
- "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
- "dev": true
- },
"harmony-reflect": {
"version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz",
+ "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==",
"dev": true
},
"has": {
@@ -35363,10 +30465,6 @@
}
}
},
- "hosted-git-info": {
- "version": "2.8.9",
- "dev": true
- },
"hotkeys-js": {
"version": "3.8.3"
},
@@ -35449,7 +30547,7 @@
},
"http-proxy-agent": {
"version": "4.0.1",
- "devOptional": true,
+ "optional": true,
"requires": {
"@tootallnate/once": "1",
"agent-base": "6",
@@ -35491,6 +30589,8 @@
},
"identity-obj-proxy": {
"version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz",
+ "integrity": "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA==",
"dev": true,
"requires": {
"harmony-reflect": "^1.4.6"
@@ -35503,17 +30603,13 @@
"ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
- "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ=="
- },
- "ignore-walk": {
- "version": "3.0.3",
- "dev": true,
- "requires": {
- "minimatch": "^3.0.4"
- }
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+ "dev": true
},
"immutable": {
"version": "3.7.6",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz",
+ "integrity": "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw==",
"dev": true
},
"import-fresh": {
@@ -35568,10 +30664,6 @@
"p-limit": "^2.2.0"
}
},
- "path-exists": {
- "version": "4.0.0",
- "optional": true
- },
"pkg-dir": {
"version": "4.2.0",
"optional": true,
@@ -35701,6 +30793,8 @@
},
"is-absolute": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
"dev": true,
"requires": {
"is-relative": "^1.0.0",
@@ -35819,10 +30913,6 @@
"version": "3.0.3",
"dev": true
},
- "is-plain-obj": {
- "version": "1.1.0",
- "dev": true
- },
"is-plain-object": {
"version": "2.0.4",
"requires": {
@@ -35847,6 +30937,8 @@
},
"is-relative": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
"dev": true,
"requires": {
"is-unc-path": "^1.0.0"
@@ -35907,6 +30999,8 @@
},
"is-unc-path": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
"dev": true,
"requires": {
"unc-path-regex": "^0.1.2"
@@ -36891,27 +31985,12 @@
"integrity": "sha512-NZIITw8uZQFuzQimqjUxIrIcEdxYDFIe/0xYfIlVXTkiBjjyBEvgasj5bb0/cHtPRD/NziPbT312sFrkI5ALpw==",
"dev": true
},
- "joi": {
- "version": "17.4.0",
- "dev": true,
- "requires": {
- "@hapi/hoek": "^9.0.0",
- "@hapi/topo": "^5.0.0",
- "@sideway/address": "^4.1.0",
- "@sideway/formula": "^3.0.0",
- "@sideway/pinpoint": "^2.0.0"
- }
- },
"jose": {
"version": "4.14.4",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.14.4.tgz",
"integrity": "sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g==",
"dev": true
},
- "joycon": {
- "version": "3.1.1",
- "dev": true
- },
"js-tokens": {
"version": "4.0.0"
},
@@ -37013,9 +32092,9 @@
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
},
"jsonc-parser": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
- "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
+ "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
"dev": true
},
"jsonfile": {
@@ -37029,54 +32108,28 @@
"version": "0.0.0",
"dev": true
},
- "jss": {
- "version": "9.8.7",
- "requires": {
- "is-in-browser": "^1.1.3",
- "symbol-observable": "^1.1.0",
- "warning": "^3.0.0"
- }
- },
"jss-plugin-camel-case": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz",
+ "integrity": "sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==",
"requires": {
"@babel/runtime": "^7.3.1",
"hyphenate-style-name": "^1.0.3",
- "jss": "10.6.0"
+ "jss": "10.10.0"
},
"dependencies": {
"csstype": {
- "version": "3.0.7"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"jss": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"requires": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- }
- }
- }
- },
- "jss-plugin-compose": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
- "tiny-warning": "^1.0.2"
- },
- "dependencies": {
- "csstype": {
- "version": "3.0.7"
- },
- "jss": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
}
@@ -37084,66 +32137,26 @@
}
},
"jss-plugin-default-unit": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0"
- },
- "dependencies": {
- "csstype": {
- "version": "3.0.7"
- },
- "jss": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- }
- }
- }
- },
- "jss-plugin-expand": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz",
+ "integrity": "sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==",
"requires": {
"@babel/runtime": "^7.3.1",
- "jss": "10.6.0"
+ "jss": "10.10.0"
},
"dependencies": {
"csstype": {
- "version": "3.0.7"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"jss": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"requires": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- }
- }
- }
- },
- "jss-plugin-extend": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
- "tiny-warning": "^1.0.2"
- },
- "dependencies": {
- "csstype": {
- "version": "3.0.7"
- },
- "jss": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
}
@@ -37151,21 +32164,26 @@
}
},
"jss-plugin-global": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz",
+ "integrity": "sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==",
"requires": {
"@babel/runtime": "^7.3.1",
- "jss": "10.6.0"
+ "jss": "10.10.0"
},
"dependencies": {
"csstype": {
- "version": "3.0.7"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"jss": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"requires": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
}
@@ -37173,22 +32191,27 @@
}
},
"jss-plugin-nested": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz",
+ "integrity": "sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==",
"requires": {
"@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
+ "jss": "10.10.0",
"tiny-warning": "^1.0.2"
},
"dependencies": {
"csstype": {
- "version": "3.0.7"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"jss": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"requires": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
}
@@ -37196,21 +32219,26 @@
}
},
"jss-plugin-props-sort": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz",
+ "integrity": "sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==",
"requires": {
"@babel/runtime": "^7.3.1",
- "jss": "10.6.0"
+ "jss": "10.10.0"
},
"dependencies": {
"csstype": {
- "version": "3.0.7"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"jss": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"requires": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
}
@@ -37218,68 +32246,27 @@
}
},
"jss-plugin-rule-value-function": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz",
+ "integrity": "sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==",
"requires": {
"@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
+ "jss": "10.10.0",
"tiny-warning": "^1.0.2"
},
"dependencies": {
"csstype": {
- "version": "3.0.7"
- },
- "jss": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- }
- }
- }
- },
- "jss-plugin-rule-value-observable": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
- "symbol-observable": "^1.2.0"
- },
- "dependencies": {
- "csstype": {
- "version": "3.0.7"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"jss": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"requires": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- }
- }
- }
- },
- "jss-plugin-template": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
- "tiny-warning": "^1.0.2"
- },
- "dependencies": {
- "csstype": {
- "version": "3.0.7"
- },
- "jss": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
}
@@ -37287,56 +32274,27 @@
}
},
"jss-plugin-vendor-prefixer": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz",
+ "integrity": "sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==",
"requires": {
"@babel/runtime": "^7.3.1",
"css-vendor": "^2.0.8",
- "jss": "10.6.0"
+ "jss": "10.10.0"
},
"dependencies": {
"csstype": {
- "version": "3.0.7"
- },
- "jss": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- }
- }
- }
- },
- "jss-preset-default": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "jss": "10.6.0",
- "jss-plugin-camel-case": "10.6.0",
- "jss-plugin-compose": "10.6.0",
- "jss-plugin-default-unit": "10.6.0",
- "jss-plugin-expand": "10.6.0",
- "jss-plugin-extend": "10.6.0",
- "jss-plugin-global": "10.6.0",
- "jss-plugin-nested": "10.6.0",
- "jss-plugin-props-sort": "10.6.0",
- "jss-plugin-rule-value-function": "10.6.0",
- "jss-plugin-rule-value-observable": "10.6.0",
- "jss-plugin-template": "10.6.0",
- "jss-plugin-vendor-prefixer": "10.6.0"
- },
- "dependencies": {
- "csstype": {
- "version": "3.0.7"
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"jss": {
- "version": "10.6.0",
+ "version": "10.10.0",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.10.0.tgz",
+ "integrity": "sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==",
"requires": {
"@babel/runtime": "^7.3.1",
"csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
}
@@ -37353,25 +32311,6 @@
"object.assign": "^4.1.3"
}
},
- "junit-merge": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/junit-merge/-/junit-merge-2.0.0.tgz",
- "integrity": "sha512-qwENzBWcdHPazNqPO0fKyFIqEyaSKyO0iyBeIU4Y/scjkXYpwTi88P2S/PWecqgMhzG2MOCwXk8QB9ucvXeIPw==",
- "dev": true,
- "requires": {
- "commander": "^2.18.0",
- "fs-readdir-recursive": "^1.1.0",
- "mkdirp": "^0.5.1",
- "xmldoc": "^1.1.2"
- }
- },
- "junit-report-merger": {
- "version": "3.0.5",
- "requires": {
- "fast-glob": "3.2.11",
- "xmlbuilder2": "3.0.2"
- }
- },
"jwt-decode": {
"version": "3.1.2"
},
@@ -37380,17 +32319,81 @@
"resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.1.tgz",
"integrity": "sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg=="
},
- "kind-of": {
- "version": "6.0.3",
- "dev": true
- },
"kleur": {
"version": "3.0.3",
"devOptional": true
},
- "lazy-ass": {
- "version": "1.6.0",
- "dev": true
+ "knip": {
+ "version": "5.30.5",
+ "resolved": "https://registry.npmjs.org/knip/-/knip-5.30.5.tgz",
+ "integrity": "sha512-opta1VVKAfIzhvj1iyOr/3SgSDC6jYPoUaYkvjftNqMTeURppYY5VqrAa5DOcJnIsdcAdyoIKHUFg9NRiFaM5w==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.walk": "1.2.8",
+ "@snyk/github-codeowners": "1.1.0",
+ "easy-table": "1.2.0",
+ "enhanced-resolve": "^5.17.1",
+ "fast-glob": "^3.3.2",
+ "jiti": "^1.21.6",
+ "js-yaml": "^4.1.0",
+ "minimist": "^1.2.8",
+ "picocolors": "^1.0.0",
+ "picomatch": "^4.0.1",
+ "pretty-ms": "^9.0.0",
+ "smol-toml": "^1.3.0",
+ "strip-json-comments": "5.0.1",
+ "summary": "2.1.0",
+ "zod": "^3.22.4",
+ "zod-validation-error": "^3.0.3"
+ },
+ "dependencies": {
+ "argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ }
+ },
+ "jiti": {
+ "version": "1.21.6",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
+ "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "requires": {
+ "argparse": "^2.0.1"
+ }
+ },
+ "picomatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-5.0.1.tgz",
+ "integrity": "sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==",
+ "dev": true
+ }
+ }
},
"leven": {
"version": "3.1.0",
@@ -37494,27 +32497,12 @@
}
}
},
- "load-yaml-file": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz",
- "integrity": "sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.5",
- "js-yaml": "^3.13.0",
- "pify": "^4.0.1",
- "strip-bom": "^3.0.0"
- }
- },
- "loader-utils": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz",
- "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
- "dev": true,
+ "locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"requires": {
- "big.js": "^5.2.2",
- "emojis-list": "^3.0.0",
- "json5": "^2.1.2"
+ "p-locate": "^5.0.0"
}
},
"lodash": {
@@ -37643,11 +32631,6 @@
}
}
},
- "longest-streak": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz",
- "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="
- },
"loose-envify": {
"version": "1.4.0",
"requires": {
@@ -37684,7 +32667,10 @@
}
},
"lz-string": {
- "version": "1.4.4"
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
+ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
+ "optional": true
},
"magic-string": {
"version": "0.25.7",
@@ -37706,16 +32692,8 @@
},
"map-cache": {
"version": "0.2.2",
- "dev": true
- },
- "map-obj": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
- "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
- "dev": true
- },
- "map-stream": {
- "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
"dev": true
},
"markdown-it": {
@@ -37736,11 +32714,6 @@
}
}
},
- "markdown-table": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz",
- "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw=="
- },
"marked": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
@@ -37755,151 +32728,6 @@
"is-buffer": "~1.1.6"
}
},
- "mdast-util-find-and-replace": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz",
- "integrity": "sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==",
- "requires": {
- "@types/mdast": "^3.0.0",
- "escape-string-regexp": "^5.0.0",
- "unist-util-is": "^5.0.0",
- "unist-util-visit-parents": "^5.0.0"
- },
- "dependencies": {
- "escape-string-regexp": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
- "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="
- }
- }
- },
- "mdast-util-from-markdown": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz",
- "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==",
- "requires": {
- "@types/mdast": "^3.0.0",
- "@types/unist": "^2.0.0",
- "decode-named-character-reference": "^1.0.0",
- "mdast-util-to-string": "^3.1.0",
- "micromark": "^3.0.0",
- "micromark-util-decode-numeric-character-reference": "^1.0.0",
- "micromark-util-decode-string": "^1.0.0",
- "micromark-util-normalize-identifier": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "unist-util-stringify-position": "^3.0.0",
- "uvu": "^0.5.0"
- },
- "dependencies": {
- "mdast-util-to-string": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz",
- "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==",
- "requires": {
- "@types/mdast": "^3.0.0"
- }
- }
- }
- },
- "mdast-util-gfm": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz",
- "integrity": "sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==",
- "requires": {
- "mdast-util-from-markdown": "^1.0.0",
- "mdast-util-gfm-autolink-literal": "^1.0.0",
- "mdast-util-gfm-footnote": "^1.0.0",
- "mdast-util-gfm-strikethrough": "^1.0.0",
- "mdast-util-gfm-table": "^1.0.0",
- "mdast-util-gfm-task-list-item": "^1.0.0",
- "mdast-util-to-markdown": "^1.0.0"
- }
- },
- "mdast-util-gfm-autolink-literal": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz",
- "integrity": "sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==",
- "requires": {
- "@types/mdast": "^3.0.0",
- "ccount": "^2.0.0",
- "mdast-util-find-and-replace": "^2.0.0",
- "micromark-util-character": "^1.0.0"
- }
- },
- "mdast-util-gfm-footnote": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz",
- "integrity": "sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==",
- "requires": {
- "@types/mdast": "^3.0.0",
- "mdast-util-to-markdown": "^1.3.0",
- "micromark-util-normalize-identifier": "^1.0.0"
- }
- },
- "mdast-util-gfm-strikethrough": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz",
- "integrity": "sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==",
- "requires": {
- "@types/mdast": "^3.0.0",
- "mdast-util-to-markdown": "^1.3.0"
- }
- },
- "mdast-util-gfm-table": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz",
- "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==",
- "requires": {
- "@types/mdast": "^3.0.0",
- "markdown-table": "^3.0.0",
- "mdast-util-from-markdown": "^1.0.0",
- "mdast-util-to-markdown": "^1.3.0"
- }
- },
- "mdast-util-gfm-task-list-item": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz",
- "integrity": "sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==",
- "requires": {
- "@types/mdast": "^3.0.0",
- "mdast-util-to-markdown": "^1.3.0"
- }
- },
- "mdast-util-phrasing": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz",
- "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==",
- "requires": {
- "@types/mdast": "^3.0.0",
- "unist-util-is": "^5.0.0"
- }
- },
- "mdast-util-to-markdown": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz",
- "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==",
- "requires": {
- "@types/mdast": "^3.0.0",
- "@types/unist": "^2.0.0",
- "longest-streak": "^3.0.0",
- "mdast-util-phrasing": "^3.0.0",
- "mdast-util-to-string": "^3.0.0",
- "micromark-util-decode-string": "^1.0.0",
- "unist-util-visit": "^4.0.0",
- "zwitch": "^2.0.0"
- },
- "dependencies": {
- "mdast-util-to-string": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz",
- "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==",
- "requires": {
- "@types/mdast": "^3.0.0"
- }
- }
- }
- },
"mdurl": {
"version": "1.0.1"
},
@@ -37908,43 +32736,6 @@
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
},
- "meow": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz",
- "integrity": "sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==",
- "dev": true,
- "requires": {
- "@types/minimist": "^1.2.0",
- "camelcase-keys": "^6.2.2",
- "decamelize-keys": "^1.1.0",
- "hard-rejection": "^2.1.0",
- "minimist-options": "^4.0.2",
- "normalize-package-data": "^2.5.0",
- "read-pkg-up": "^7.0.1",
- "redent": "^3.0.0",
- "trim-newlines": "^3.0.0",
- "type-fest": "^0.13.1",
- "yargs-parser": "^18.1.3"
- },
- "dependencies": {
- "type-fest": {
- "version": "0.13.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
- "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
- "dev": true
- },
- "yargs-parser": {
- "version": "18.1.3",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
- "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
- "dev": true,
- "requires": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- }
- }
- }
- },
"merge-stream": {
"version": "2.0.0",
"devOptional": true
@@ -37952,312 +32743,17 @@
"merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true
},
"meros": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/meros/-/meros-1.3.0.tgz",
"integrity": "sha512-2BNGOimxEz5hmjUG2FwoxCt5HN7BXdaWyFqEwxPTrJzVdABtrL4TiHTcsWSFAxPQ/tOnEaQEJh3qWq71QRMY+w=="
},
- "micromark": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz",
- "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==",
- "requires": {
- "@types/debug": "^4.0.0",
- "debug": "^4.0.0",
- "decode-named-character-reference": "^1.0.0",
- "micromark-core-commonmark": "^1.0.1",
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-combine-extensions": "^1.0.0",
- "micromark-util-decode-numeric-character-reference": "^1.0.0",
- "micromark-util-encode": "^1.0.0",
- "micromark-util-normalize-identifier": "^1.0.0",
- "micromark-util-resolve-all": "^1.0.0",
- "micromark-util-sanitize-uri": "^1.0.0",
- "micromark-util-subtokenize": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.1",
- "uvu": "^0.5.0"
- }
- },
- "micromark-core-commonmark": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz",
- "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==",
- "requires": {
- "decode-named-character-reference": "^1.0.0",
- "micromark-factory-destination": "^1.0.0",
- "micromark-factory-label": "^1.0.0",
- "micromark-factory-space": "^1.0.0",
- "micromark-factory-title": "^1.0.0",
- "micromark-factory-whitespace": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-classify-character": "^1.0.0",
- "micromark-util-html-tag-name": "^1.0.0",
- "micromark-util-normalize-identifier": "^1.0.0",
- "micromark-util-resolve-all": "^1.0.0",
- "micromark-util-subtokenize": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.1",
- "uvu": "^0.5.0"
- }
- },
- "micromark-extension-gfm": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz",
- "integrity": "sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==",
- "requires": {
- "micromark-extension-gfm-autolink-literal": "^1.0.0",
- "micromark-extension-gfm-footnote": "^1.0.0",
- "micromark-extension-gfm-strikethrough": "^1.0.0",
- "micromark-extension-gfm-table": "^1.0.0",
- "micromark-extension-gfm-tagfilter": "^1.0.0",
- "micromark-extension-gfm-task-list-item": "^1.0.0",
- "micromark-util-combine-extensions": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "micromark-extension-gfm-autolink-literal": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz",
- "integrity": "sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==",
- "requires": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-sanitize-uri": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "micromark-extension-gfm-footnote": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz",
- "integrity": "sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==",
- "requires": {
- "micromark-core-commonmark": "^1.0.0",
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-normalize-identifier": "^1.0.0",
- "micromark-util-sanitize-uri": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
- }
- },
- "micromark-extension-gfm-strikethrough": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz",
- "integrity": "sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==",
- "requires": {
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-classify-character": "^1.0.0",
- "micromark-util-resolve-all": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
- }
- },
- "micromark-extension-gfm-table": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz",
- "integrity": "sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==",
- "requires": {
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
- }
- },
- "micromark-extension-gfm-tagfilter": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz",
- "integrity": "sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==",
- "requires": {
- "micromark-util-types": "^1.0.0"
- }
- },
- "micromark-extension-gfm-task-list-item": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz",
- "integrity": "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==",
- "requires": {
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
- }
- },
- "micromark-factory-destination": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz",
- "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==",
- "requires": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "micromark-factory-label": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz",
- "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==",
- "requires": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
- }
- },
- "micromark-factory-space": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz",
- "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==",
- "requires": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "micromark-factory-title": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz",
- "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==",
- "requires": {
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "micromark-factory-whitespace": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz",
- "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==",
- "requires": {
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "micromark-util-character": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz",
- "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==",
- "requires": {
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "micromark-util-chunked": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz",
- "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==",
- "requires": {
- "micromark-util-symbol": "^1.0.0"
- }
- },
- "micromark-util-classify-character": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz",
- "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==",
- "requires": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "micromark-util-combine-extensions": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz",
- "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==",
- "requires": {
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-types": "^1.0.0"
- }
- },
- "micromark-util-decode-numeric-character-reference": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz",
- "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==",
- "requires": {
- "micromark-util-symbol": "^1.0.0"
- }
- },
- "micromark-util-decode-string": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz",
- "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==",
- "requires": {
- "decode-named-character-reference": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-decode-numeric-character-reference": "^1.0.0",
- "micromark-util-symbol": "^1.0.0"
- }
- },
- "micromark-util-encode": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz",
- "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw=="
- },
- "micromark-util-html-tag-name": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz",
- "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q=="
- },
- "micromark-util-normalize-identifier": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz",
- "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==",
- "requires": {
- "micromark-util-symbol": "^1.0.0"
- }
- },
- "micromark-util-resolve-all": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz",
- "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==",
- "requires": {
- "micromark-util-types": "^1.0.0"
- }
- },
- "micromark-util-sanitize-uri": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz",
- "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==",
- "requires": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-encode": "^1.0.0",
- "micromark-util-symbol": "^1.0.0"
- }
- },
- "micromark-util-subtokenize": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz",
- "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==",
- "requires": {
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
- }
- },
- "micromark-util-symbol": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz",
- "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag=="
- },
- "micromark-util-types": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz",
- "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg=="
- },
"micromatch": {
"version": "4.0.5",
+ "devOptional": true,
"requires": {
"braces": "^3.0.2",
"picomatch": "^2.3.1"
@@ -38267,13 +32763,13 @@
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "devOptional": true
+ "optional": true
},
"mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "devOptional": true,
+ "optional": true,
"requires": {
"mime-db": "1.52.0"
}
@@ -38284,7 +32780,7 @@
},
"min-indent": {
"version": "1.0.1",
- "devOptional": true
+ "optional": true
},
"mini-create-react-context": {
"version": "0.4.1",
@@ -38308,27 +32804,10 @@
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"devOptional": true
},
- "minimist-options": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
- "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
- "dev": true,
- "requires": {
- "arrify": "^1.0.1",
- "is-plain-obj": "^1.1.0",
- "kind-of": "^6.0.3"
- }
- },
"minipass": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
- "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="
- },
- "mixme": {
- "version": "0.5.5",
- "resolved": "https://registry.npmjs.org/mixme/-/mixme-0.5.5.tgz",
- "integrity": "sha512-/6IupbRx32s7jjEwHcycXikJwFD5UujbVNuJFkeKLYje+92OvtuPniF6JhnFm5JCTDUhS+kYK3W/4BWYQYXz7w==",
- "dev": true
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
+ "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="
},
"mkdirp": {
"version": "0.5.6",
@@ -38340,32 +32819,31 @@
}
},
"mocha": {
- "version": "10.2.0",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
- "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==",
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz",
+ "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==",
"dev": true,
"requires": {
- "ansi-colors": "4.1.1",
- "browser-stdout": "1.3.1",
- "chokidar": "3.5.3",
- "debug": "4.3.4",
- "diff": "5.0.0",
- "escape-string-regexp": "4.0.0",
- "find-up": "5.0.0",
- "glob": "7.2.0",
- "he": "1.2.0",
- "js-yaml": "4.1.0",
- "log-symbols": "4.1.0",
- "minimatch": "5.0.1",
- "ms": "2.1.3",
- "nanoid": "3.3.3",
- "serialize-javascript": "6.0.0",
- "strip-json-comments": "3.1.1",
- "supports-color": "8.1.1",
- "workerpool": "6.2.1",
- "yargs": "16.2.0",
- "yargs-parser": "20.2.4",
- "yargs-unparser": "2.0.0"
+ "ansi-colors": "^4.1.3",
+ "browser-stdout": "^1.3.1",
+ "chokidar": "^3.5.3",
+ "debug": "^4.3.5",
+ "diff": "^5.2.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-up": "^5.0.0",
+ "glob": "^8.1.0",
+ "he": "^1.2.0",
+ "js-yaml": "^4.1.0",
+ "log-symbols": "^4.1.0",
+ "minimatch": "^5.1.6",
+ "ms": "^2.1.3",
+ "serialize-javascript": "^6.0.2",
+ "strip-json-comments": "^3.1.1",
+ "supports-color": "^8.1.1",
+ "workerpool": "^6.5.1",
+ "yargs": "^16.2.0",
+ "yargs-parser": "^20.2.9",
+ "yargs-unparser": "^2.0.0"
},
"dependencies": {
"argparse": {
@@ -38374,10 +32852,28 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
+ "brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.3"
+ }
+ },
"diff": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
- "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
+ "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
"dev": true
},
"escape-string-regexp": {
@@ -38386,39 +32882,17 @@
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true
},
- "find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "requires": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- }
- },
"glob": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz",
- "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "dependencies": {
- "minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "requires": {
- "brace-expansion": "^1.1.7"
- }
- }
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
}
},
"has-flag": {
@@ -38436,33 +32910,13 @@
"argparse": "^2.0.1"
}
},
- "locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "requires": {
- "p-locate": "^5.0.0"
- }
- },
"minimatch": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
- "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dev": true,
"requires": {
"brace-expansion": "^2.0.1"
- },
- "dependencies": {
- "brace-expansion": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
- "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
- "dev": true,
- "requires": {
- "balanced-match": "^1.0.0"
- }
- }
}
},
"ms": {
@@ -38471,45 +32925,6 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
- "nanoid": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
- "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
- "dev": true
- },
- "p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "requires": {
- "yocto-queue": "^0.1.0"
- }
- },
- "p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "requires": {
- "p-limit": "^3.0.2"
- }
- },
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
- },
- "serialize-javascript": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
- "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
- "dev": true,
- "requires": {
- "randombytes": "^2.1.0"
- }
- },
"supports-color": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
@@ -38642,15 +33057,6 @@
"path-exists": "^4.0.0"
}
},
- "fs-extra": {
- "version": "7.0.1",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- }
- },
"locate-path": {
"version": "5.0.0",
"dev": true,
@@ -38665,10 +33071,6 @@
"p-limit": "^2.2.0"
}
},
- "path-exists": {
- "version": "4.0.0",
- "dev": true
- },
"strip-ansi": {
"version": "6.0.1",
"dev": true,
@@ -38818,7 +33220,8 @@
"mri": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
- "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="
+ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+ "dev": true
},
"ms": {
"version": "2.1.2"
@@ -38834,7 +33237,8 @@
"nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
- "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA=="
+ "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
+ "dev": true
},
"natural-compare": {
"version": "1.4.0",
@@ -38923,27 +33327,9 @@
"devOptional": true
},
"node-releases": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
- "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="
- },
- "normalize-package-data": {
- "version": "2.5.0",
- "dev": true,
- "requires": {
- "hosted-git-info": "^2.1.4",
- "resolve": "1.20.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
- },
- "dependencies": {
- "semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true
- }
- }
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
+ "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g=="
},
"normalize-path": {
"version": "3.0.0"
@@ -39145,14 +33531,40 @@
"p-try": "^2.0.0"
}
},
+ "p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "requires": {
+ "p-limit": "^3.0.2"
+ },
+ "dependencies": {
+ "p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ }
+ }
+ },
"p-map": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+ "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
"dev": true
},
"p-try": {
"version": "2.2.0",
"devOptional": true
},
+ "package-manager-detector": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.2.tgz",
+ "integrity": "sha512-VgXbyrSNsml4eHWIvxxG/nTL4wgybMTXCV2Un/+yEc3aDKKU6nQBZjbeP3Pl3qm9Qg92X/1ng4ffvCeD/zwHgg==",
+ "dev": true
+ },
"parent-module": {
"version": "1.0.1",
"requires": {
@@ -39166,6 +33578,8 @@
},
"parse-filepath": {
"version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
+ "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==",
"dev": true,
"requires": {
"is-absolute": "^1.0.0",
@@ -39184,6 +33598,12 @@
"lines-and-columns": "^1.1.6"
}
},
+ "parse-ms": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz",
+ "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==",
+ "dev": true
+ },
"parse5": {
"version": "6.0.1",
"optional": true
@@ -39214,6 +33634,11 @@
"tslib": "^2.0.3"
}
},
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
+ },
"path-is-absolute": {
"version": "1.0.1",
"devOptional": true
@@ -39229,6 +33654,8 @@
},
"path-root": {
"version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+ "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==",
"dev": true,
"requires": {
"path-root-regex": "^0.1.0"
@@ -39236,21 +33663,28 @@
},
"path-root-regex": {
"version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==",
"dev": true
},
"path-scurry": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
- "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"requires": {
- "lru-cache": "^9.1.1 || ^10.0.0",
+ "lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"dependencies": {
"lru-cache": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz",
- "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g=="
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
+ },
+ "minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="
}
}
},
@@ -39267,43 +33701,32 @@
"version": "0.2.0",
"dev": true
},
- "pause-stream": {
- "version": "0.0.11",
- "dev": true,
- "requires": {
- "through": "~2.3"
- }
- },
"picocolors": {
- "version": "1.0.0"
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
+ "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw=="
},
"picomatch": {
"version": "2.3.1"
},
"pify": {
"version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
"dev": true
},
"pirates": {
"version": "4.0.5",
"optional": true
},
- "pixelmatch": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.3.0.tgz",
- "integrity": "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==",
- "requires": {
- "pngjs": "^6.0.0"
- }
- },
"playwright": {
- "version": "1.40.0",
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.40.0.tgz",
- "integrity": "sha512-gyHAgQjiDf1m34Xpwzaqb76KgfzYrhK7iih+2IzcOCoZWr/8ZqmdBw+t0RU85ZmfJMgtgAiNtBQ/KS2325INXw==",
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.0.tgz",
+ "integrity": "sha512-eKpmys0UFDnfNb3vfsf8Vx2LEOtflgRebl0Im2eQQnYMA4Aqd+Zw8bEOB+7ZKvN76901mRnqdsiOGKxzVTbi7A==",
"dev": true,
"requires": {
"fsevents": "2.3.2",
- "playwright-core": "1.40.0"
+ "playwright-core": "1.49.0"
},
"dependencies": {
"fsevents": {
@@ -39316,18 +33739,24 @@
}
},
"playwright-core": {
- "version": "1.40.0",
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.40.0.tgz",
- "integrity": "sha512-fvKewVJpGeca8t0ipM56jkVSU6Eo0RmFvQ/MaCQNDYm+sdvKkMBBWTE1FdeMqIdumRaXXjZChWHvIzCGM/tA/Q==",
+ "version": "1.49.0",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.0.tgz",
+ "integrity": "sha512-R+3KKTQF3npy5GTiKH/T+kdhoJfJojjHESR1YEWhYuEKRVfVaxH3+4+GvXE5xyCngCxhxnykk0Vlah9v8fs3jA==",
+ "dev": true
+ },
+ "playwright-ctrf-json-reporter": {
+ "version": "0.0.18",
+ "resolved": "https://registry.npmjs.org/playwright-ctrf-json-reporter/-/playwright-ctrf-json-reporter-0.0.18.tgz",
+ "integrity": "sha512-AjFNpIMKI8zeyaktA2LBphYzy3ffiBjXobBXxEfrVUDov/Z8v5+y9FI0m3cBCr8yauk2brN+Er225vHsZDIu0g==",
"dev": true
},
"playwright-testmo-reporter": {
- "version": "1.8.4",
- "resolved": "https://registry.npmjs.org/playwright-testmo-reporter/-/playwright-testmo-reporter-1.8.4.tgz",
- "integrity": "sha512-j0q52X66NtV/Fikaq+dWBnNwP1pq1ouiEHmvMypohb+HHKvcVYw9yBs32A6s1BwzBn9SvaLCaG4F6QC6dr0taw==",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/playwright-testmo-reporter/-/playwright-testmo-reporter-1.11.0.tgz",
+ "integrity": "sha512-pGsh1VQ57sWOSdVCh/2PHJXTi9CDw1Tf72Gk97qd6gBxg9LK3kjXnL7nF0iRoKCL2ML890PgyayLgLIboWfLGQ==",
"dev": true,
"requires": {
- "fast-xml-parser": "^4.2.7"
+ "fast-xml-parser": "^4.4.1"
}
},
"please-upgrade-node": {
@@ -39337,11 +33766,6 @@
"semver-compare": "^1.0.0"
}
},
- "pngjs": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz",
- "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="
- },
"popper.js": {
"version": "1.16.1-lts"
},
@@ -39401,63 +33825,6 @@
"resolved": "https://registry.npmjs.org/preact/-/preact-10.19.4.tgz",
"integrity": "sha512-dwaX5jAh0Ga8uENBX1hSOujmKWgx9RtL80KaKUFLc6jb4vCEAc3EeZ0rnQO/FO4VgjfPMfoLFWnNG8bHuZ9VLw=="
},
- "preferred-pm": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/preferred-pm/-/preferred-pm-3.0.3.tgz",
- "integrity": "sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==",
- "dev": true,
- "requires": {
- "find-up": "^5.0.0",
- "find-yarn-workspace-root2": "1.2.16",
- "path-exists": "^4.0.0",
- "which-pm": "2.0.0"
- },
- "dependencies": {
- "find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "requires": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- }
- },
- "locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "requires": {
- "p-locate": "^5.0.0"
- }
- },
- "p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "requires": {
- "yocto-queue": "^0.1.0"
- }
- },
- "p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "requires": {
- "p-limit": "^3.0.2"
- }
- },
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
- }
- }
- },
"prettier": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
@@ -39487,11 +33854,22 @@
}
}
},
+ "pretty-ms": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.1.0.tgz",
+ "integrity": "sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==",
+ "dev": true,
+ "requires": {
+ "parse-ms": "^4.0.0"
+ }
+ },
"progress": {
"version": "2.0.3"
},
"promise": {
"version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
"dev": true,
"requires": {
"asap": "~2.0.3"
@@ -39596,13 +33974,6 @@
"proxy-from-env": {
"version": "1.1.0"
},
- "ps-tree": {
- "version": "1.2.0",
- "dev": true,
- "requires": {
- "event-stream": "=3.3.4"
- }
- },
"pseudomap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
@@ -39655,10 +34026,13 @@
"queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true
},
"randombytes": {
"version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
"dev": true,
"requires": {
"safe-buffer": "^5.1.0"
@@ -39677,9 +34051,6 @@
"@babel/runtime": "^7.12.13"
}
},
- "react-display-name": {
- "version": "0.2.5"
- },
"react-dom": {
"version": "17.0.2",
"requires": {
@@ -39697,13 +34068,6 @@
}
}
},
- "react-draggable": {
- "version": "4.4.5",
- "requires": {
- "clsx": "^1.1.1",
- "prop-types": "^15.8.1"
- }
- },
"react-dropzone": {
"version": "11.3.2",
"requires": {
@@ -39745,12 +34109,6 @@
"react-from-dom": {
"version": "0.6.2"
},
- "react-github-btn": {
- "version": "1.4.0",
- "requires": {
- "github-buttons": "^2.22.0"
- }
- },
"react-gtm-module": {
"version": "2.0.11"
},
@@ -39809,37 +34167,6 @@
"react-is": {
"version": "17.0.2"
},
- "react-jss": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "@emotion/is-prop-valid": "^0.7.3",
- "css-jss": "10.6.0",
- "hoist-non-react-statics": "^3.2.0",
- "is-in-browser": "^1.1.3",
- "jss": "10.6.0",
- "jss-preset-default": "10.6.0",
- "prop-types": "^15.6.0",
- "shallow-equal": "^1.2.0",
- "theming": "^3.3.0",
- "tiny-warning": "^1.0.2"
- },
- "dependencies": {
- "csstype": {
- "version": "3.0.7"
- },
- "jss": {
- "version": "10.6.0",
- "requires": {
- "@babel/runtime": "^7.3.1",
- "csstype": "^3.0.2",
- "indefinite-observable": "^2.0.1",
- "is-in-browser": "^1.1.3",
- "tiny-warning": "^1.0.2"
- }
- }
- }
- },
"react-moment": {
"version": "1.1.1"
},
@@ -39852,9 +34179,11 @@
}
},
"react-remove-scroll": {
- "version": "2.5.5",
+ "version": "2.5.7",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz",
+ "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==",
"requires": {
- "react-remove-scroll-bar": "^2.3.3",
+ "react-remove-scroll-bar": "^2.3.4",
"react-style-singleton": "^2.2.1",
"tslib": "^2.1.0",
"use-callback-ref": "^1.3.0",
@@ -39983,79 +34312,6 @@
"prop-types": "^15.6.2"
}
},
- "read-pkg": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
- "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
- "dev": true,
- "requires": {
- "@types/normalize-package-data": "^2.4.0",
- "normalize-package-data": "^2.5.0",
- "parse-json": "^5.0.0",
- "type-fest": "^0.6.0"
- },
- "dependencies": {
- "type-fest": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
- "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
- "dev": true
- }
- }
- },
- "read-pkg-up": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
- "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
- "dev": true,
- "requires": {
- "find-up": "^4.1.0",
- "read-pkg": "^5.2.0",
- "type-fest": "^0.8.1"
- },
- "dependencies": {
- "find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "requires": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- }
- },
- "locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "requires": {
- "p-locate": "^4.1.0"
- }
- },
- "p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "requires": {
- "p-limit": "^2.2.0"
- }
- },
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
- },
- "type-fest": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
- "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
- "dev": true
- }
- }
- },
"read-yaml-file": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz",
@@ -40089,16 +34345,12 @@
},
"redent": {
"version": "3.0.0",
- "devOptional": true,
+ "optional": true,
"requires": {
"indent-string": "^4.0.0",
"strip-indent": "^3.0.0"
}
},
- "regenerator-runtime": {
- "version": "0.11.1",
- "dev": true
- },
"regexp-tree": {
"version": "0.1.24",
"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz",
@@ -40118,128 +34370,10 @@
"version": "0.2.7",
"dev": true
},
- "relay-compiler": {
- "version": "11.0.2",
- "dev": true,
- "requires": {
- "@babel/core": "^7.0.0",
- "@babel/generator": "^7.5.0",
- "@babel/parser": "^7.0.0",
- "@babel/runtime": "^7.0.0",
- "@babel/traverse": "^7.0.0",
- "@babel/types": "^7.0.0",
- "babel-preset-fbjs": "^3.3.0",
- "chalk": "^4.0.0",
- "fb-watchman": "^2.0.0",
- "fbjs": "^3.0.0",
- "glob": "^7.1.1",
- "immutable": "~3.7.6",
- "invariant": "^2.2.4",
- "nullthrows": "^1.1.1",
- "relay-runtime": "11.0.2",
- "signedsource": "^1.0.0",
- "yargs": "^15.3.1"
- },
- "dependencies": {
- "chalk": {
- "version": "4.1.2",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "cliui": {
- "version": "6.0.0",
- "dev": true,
- "requires": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^6.2.0"
- }
- },
- "find-up": {
- "version": "4.1.0",
- "dev": true,
- "requires": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- }
- },
- "has-flag": {
- "version": "4.0.0",
- "dev": true
- },
- "locate-path": {
- "version": "5.0.0",
- "dev": true,
- "requires": {
- "p-locate": "^4.1.0"
- }
- },
- "p-locate": {
- "version": "4.1.0",
- "dev": true,
- "requires": {
- "p-limit": "^2.2.0"
- }
- },
- "path-exists": {
- "version": "4.0.0",
- "dev": true
- },
- "strip-ansi": {
- "version": "6.0.0",
- "dev": true,
- "requires": {
- "ansi-regex": "^5.0.0"
- }
- },
- "supports-color": {
- "version": "7.2.0",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
- "wrap-ansi": {
- "version": "6.2.0",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- }
- },
- "yargs": {
- "version": "15.4.1",
- "dev": true,
- "requires": {
- "cliui": "^6.0.0",
- "decamelize": "^1.2.0",
- "find-up": "^4.1.0",
- "get-caller-file": "^2.0.1",
- "require-directory": "^2.1.1",
- "require-main-filename": "^2.0.0",
- "set-blocking": "^2.0.0",
- "string-width": "^4.2.0",
- "which-module": "^2.0.0",
- "y18n": "^4.0.0",
- "yargs-parser": "^18.1.2"
- }
- },
- "yargs-parser": {
- "version": "18.1.3",
- "dev": true,
- "requires": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- }
- }
- }
- },
"relay-runtime": {
- "version": "11.0.2",
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-12.0.0.tgz",
+ "integrity": "sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug==",
"dev": true,
"requires": {
"@babel/runtime": "^7.0.0",
@@ -40247,17 +34381,6 @@
"invariant": "^2.2.4"
}
},
- "remark-gfm": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz",
- "integrity": "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==",
- "requires": {
- "@types/mdast": "^3.0.0",
- "mdast-util-gfm": "^2.0.0",
- "micromark-extension-gfm": "^2.0.0",
- "unified": "^10.0.0"
- }
- },
"remedial": {
"version": "1.0.8",
"dev": true
@@ -40272,13 +34395,6 @@
"version": "1.0.8",
"dev": true
},
- "require-context.macro": {
- "version": "1.2.2",
- "dev": true,
- "requires": {
- "@types/webpack-env": "^1.14.0"
- }
- },
"require-directory": {
"version": "2.1.1",
"devOptional": true
@@ -40347,7 +34463,8 @@
}
},
"reusify": {
- "version": "1.0.4"
+ "version": "1.0.4",
+ "dev": true
},
"rfdc": {
"version": "1.3.0",
@@ -40394,13 +34511,14 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
"requires": {
"queue-microtask": "^1.2.2"
}
},
"rxjs": {
"version": "6.6.7",
- "devOptional": true,
+ "optional": true,
"requires": {
"tslib": "^1.9.0"
},
@@ -40409,20 +34527,14 @@
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "devOptional": true
+ "optional": true
}
}
},
- "sade": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
- "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
- "requires": {
- "mri": "^1.1.0"
- }
- },
"safe-buffer": {
"version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true
},
"safe-regex-test": {
@@ -40438,12 +34550,6 @@
"version": "2.1.2",
"devOptional": true
},
- "sax": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
- "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
- "dev": true
- },
"saxes": {
"version": "5.0.1",
"optional": true,
@@ -40498,12 +34604,23 @@
}
}
},
+ "serialize-javascript": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
+ "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
+ },
"set-blocking": {
"version": "2.0.0",
"dev": true
},
"setimmediate": {
"version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
"dev": true
},
"setprototypeof": {
@@ -40516,11 +34633,10 @@
"version": "0.9.1",
"optional": true
},
- "shallow-equal": {
- "version": "1.2.1"
- },
"shebang-command": {
"version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
"dev": true,
"requires": {
"shebang-regex": "^1.0.0"
@@ -40528,6 +34644,8 @@
},
"shebang-regex": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
"dev": true
},
"shell-quote": {
@@ -40552,19 +34670,17 @@
},
"signedsource": {
"version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/signedsource/-/signedsource-1.0.0.tgz",
+ "integrity": "sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww==",
"dev": true
},
- "simple-bin-help": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/simple-bin-help/-/simple-bin-help-1.8.0.tgz",
- "integrity": "sha512-0LxHn+P1lF5r2WwVB/za3hLRIsYoLaNq1CXqjbrs3ZvLuvlWnRKrUjEWzV7umZL7hpQ7xULiQMV+0iXdRa5iFg=="
- },
"sisteransi": {
"version": "1.0.5",
"devOptional": true
},
"slash": {
- "version": "3.0.0"
+ "version": "3.0.0",
+ "devOptional": true
},
"slice-ansi": {
"version": "3.0.0",
@@ -40580,115 +34696,11 @@
"slugify": {
"version": "1.5.0"
},
- "smartwrap": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/smartwrap/-/smartwrap-2.0.2.tgz",
- "integrity": "sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==",
- "dev": true,
- "requires": {
- "array.prototype.flat": "^1.2.3",
- "breakword": "^1.0.5",
- "grapheme-splitter": "^1.0.4",
- "strip-ansi": "^6.0.0",
- "wcwidth": "^1.0.1",
- "yargs": "^15.1.0"
- },
- "dependencies": {
- "cliui": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
- "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
- "dev": true,
- "requires": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^6.2.0"
- }
- },
- "find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
- "requires": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
- }
- },
- "locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
- "requires": {
- "p-locate": "^4.1.0"
- }
- },
- "p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "requires": {
- "p-limit": "^2.2.0"
- }
- },
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
- },
- "strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "requires": {
- "ansi-regex": "^5.0.1"
- }
- },
- "wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- }
- },
- "yargs": {
- "version": "15.4.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
- "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
- "dev": true,
- "requires": {
- "cliui": "^6.0.0",
- "decamelize": "^1.2.0",
- "find-up": "^4.1.0",
- "get-caller-file": "^2.0.1",
- "require-directory": "^2.1.1",
- "require-main-filename": "^2.0.0",
- "set-blocking": "^2.0.0",
- "string-width": "^4.2.0",
- "which-module": "^2.0.0",
- "y18n": "^4.0.0",
- "yargs-parser": "^18.1.2"
- }
- },
- "yargs-parser": {
- "version": "18.1.3",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
- "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
- "dev": true,
- "requires": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- }
- }
- }
+ "smol-toml": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.0.tgz",
+ "integrity": "sha512-tWpi2TsODPScmi48b/OQZGi2lgUmBCHy6SZrhi/FdnnHiU1GwebbCfuQuxsC3nHaLwtYeJGPrDZDIeodDOc4pA==",
+ "dev": true
},
"snake-case": {
"version": "3.0.4",
@@ -40698,10 +34710,6 @@
"tslib": "^2.0.3"
}
},
- "source-list-map": {
- "version": "2.0.1",
- "dev": true
- },
"source-map": {
"version": "0.5.7"
},
@@ -40766,37 +34774,6 @@
}
}
},
- "spdx-correct": {
- "version": "3.1.1",
- "dev": true,
- "requires": {
- "spdx-expression-parse": "^3.0.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "spdx-exceptions": {
- "version": "2.3.0",
- "dev": true
- },
- "spdx-expression-parse": {
- "version": "3.0.1",
- "dev": true,
- "requires": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "spdx-license-ids": {
- "version": "3.0.7",
- "dev": true
- },
- "split": {
- "version": "0.3.3",
- "dev": true,
- "requires": {
- "through": "2"
- }
- },
"sponge-case": {
"version": "1.0.1",
"dev": true,
@@ -40820,79 +34797,12 @@
}
}
},
- "start-server-and-test": {
- "version": "1.12.1",
- "dev": true,
- "requires": {
- "bluebird": "3.7.2",
- "check-more-types": "2.24.0",
- "debug": "4.3.1",
- "execa": "3.4.0",
- "lazy-ass": "1.6.0",
- "ps-tree": "1.2.0",
- "wait-on": "5.3.0"
- },
- "dependencies": {
- "debug": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
- "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
- "dev": true,
- "requires": {
- "ms": "2.1.2"
- }
- },
- "execa": {
- "version": "3.4.0",
- "dev": true,
- "requires": {
- "cross-spawn": "^7.0.0",
- "get-stream": "^5.0.0",
- "human-signals": "^1.1.1",
- "is-stream": "^2.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^4.0.0",
- "onetime": "^5.1.0",
- "p-finally": "^2.0.0",
- "signal-exit": "^3.0.2",
- "strip-final-newline": "^2.0.0"
- }
- },
- "p-finally": {
- "version": "2.0.1",
- "dev": true
- }
- }
- },
"statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
"dev": true
},
- "stream-combiner": {
- "version": "0.0.4",
- "dev": true,
- "requires": {
- "duplexer": "~0.1.1"
- }
- },
- "stream-events": {
- "version": "1.0.5",
- "dev": true,
- "requires": {
- "stubs": "^3.0.0"
- }
- },
- "stream-transform": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/stream-transform/-/stream-transform-2.1.3.tgz",
- "integrity": "sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==",
- "dev": true,
- "requires": {
- "mixme": "^0.5.1"
- }
- },
"streamsearch": {
"version": "1.1.0",
"dev": true
@@ -41025,7 +34935,7 @@
},
"strip-indent": {
"version": "3.0.0",
- "devOptional": true,
+ "optional": true,
"requires": {
"min-indent": "^1.0.0"
}
@@ -41040,15 +34950,17 @@
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==",
"dev": true
},
- "stubs": {
- "version": "3.0.0",
- "dev": true
- },
"stylis": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
"integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
},
+ "summary": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/summary/-/summary-2.1.0.tgz",
+ "integrity": "sha512-nMIjMrd5Z2nuB2RZCKJfFMjgS3fygbeyGk9PxPPaJR1RIcyN9yn4A63Isovzm3ZtQuEkLBVgMdPup8UeLH7aQw==",
+ "dev": true
+ },
"supports-color": {
"version": "5.5.0",
"requires": {
@@ -41132,37 +35044,6 @@
"integrity": "sha512-29aQwaHqm8RMX74u2o/h1KbMLP89FjNiMxD9wbF2BbWOnbM+q+d1sCEC+MqCc4QW3NJykn77OMpTFw/xTHIc0w==",
"dev": true
},
- "teeny-request": {
- "version": "6.0.1",
- "dev": true,
- "requires": {
- "http-proxy-agent": "^4.0.0",
- "https-proxy-agent": "^4.0.0",
- "node-fetch": "^2.2.0",
- "stream-events": "^1.0.5",
- "uuid": "^3.3.2"
- },
- "dependencies": {
- "agent-base": {
- "version": "5.1.1",
- "dev": true
- },
- "https-proxy-agent": {
- "version": "4.0.0",
- "dev": true,
- "requires": {
- "agent-base": "5",
- "debug": "4"
- }
- },
- "uuid": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
- "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
- "dev": true
- }
- }
- },
"term-size": {
"version": "2.2.1",
"dev": true
@@ -41208,15 +35089,6 @@
"version": "0.2.0",
"dev": true
},
- "theming": {
- "version": "3.3.0",
- "requires": {
- "hoist-non-react-statics": "^3.3.0",
- "prop-types": "^15.5.8",
- "react-display-name": "^0.2.4",
- "tiny-warning": "^1.0.2"
- }
- },
"throat": {
"version": "6.0.2",
"optional": true
@@ -41292,17 +35164,6 @@
}
}
},
- "trim-newlines": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
- "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
- "dev": true
- },
- "trough": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz",
- "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g=="
- },
"ts-invariant": {
"version": "0.9.4",
"requires": {
@@ -41321,12 +35182,6 @@
"make-error": "1.x",
"semver": "7.x",
"yargs-parser": "20.x"
- },
- "dependencies": {
- "yargs-parser": {
- "version": "20.2.9",
- "optional": true
- }
}
},
"ts-log": {
@@ -41411,101 +35266,6 @@
}
}
},
- "tty-table": {
- "version": "4.1.6",
- "resolved": "https://registry.npmjs.org/tty-table/-/tty-table-4.1.6.tgz",
- "integrity": "sha512-kRj5CBzOrakV4VRRY5kUWbNYvo/FpOsz65DzI5op9P+cHov3+IqPbo1JE1ZnQGkHdZgNFDsrEjrfqqy/Ply9fw==",
- "dev": true,
- "requires": {
- "chalk": "^4.1.2",
- "csv": "^5.5.0",
- "kleur": "^4.1.4",
- "smartwrap": "^2.0.2",
- "strip-ansi": "^6.0.0",
- "wcwidth": "^1.0.1",
- "yargs": "^17.1.1"
- },
- "dependencies": {
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "cliui": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
- "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
- "dev": true,
- "requires": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.1",
- "wrap-ansi": "^7.0.0"
- }
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
- },
- "kleur": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
- "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
- "dev": true
- },
- "strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "requires": {
- "ansi-regex": "^5.0.1"
- }
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
- "y18n": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
- "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
- "dev": true
- },
- "yargs": {
- "version": "17.7.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
- "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
- "dev": true,
- "requires": {
- "cliui": "^8.0.1",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.3",
- "y18n": "^5.0.5",
- "yargs-parser": "^21.1.1"
- }
- },
- "yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "dev": true
- }
- }
- },
"type-detect": {
"version": "4.0.8",
"optional": true
@@ -41567,9 +35327,9 @@
}
},
"ua-parser-js": {
- "version": "0.7.35",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.35.tgz",
- "integrity": "sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g==",
+ "version": "1.0.39",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.39.tgz",
+ "integrity": "sha512-k24RCVWlEcjkdOxYmVJgeD/0a1TiSpqLg+ZalVGV9lsnr4yqu0w7tX/x2xX6G4zpkgQnRf89lxuZ1wsbjXM8lw==",
"dev": true
},
"uc.micro": {
@@ -41594,6 +35354,8 @@
},
"unc-path-regex": {
"version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==",
"dev": true
},
"unicode-emoji-utils": {
@@ -41613,67 +35375,6 @@
}
}
},
- "unified": {
- "version": "10.1.2",
- "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz",
- "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==",
- "requires": {
- "@types/unist": "^2.0.0",
- "bail": "^2.0.0",
- "extend": "^3.0.0",
- "is-buffer": "^2.0.0",
- "is-plain-obj": "^4.0.0",
- "trough": "^2.0.0",
- "vfile": "^5.0.0"
- },
- "dependencies": {
- "is-buffer": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
- "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ=="
- },
- "is-plain-obj": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
- "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="
- }
- }
- },
- "unist-util-is": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz",
- "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==",
- "requires": {
- "@types/unist": "^2.0.0"
- }
- },
- "unist-util-stringify-position": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz",
- "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==",
- "requires": {
- "@types/unist": "^2.0.0"
- }
- },
- "unist-util-visit": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz",
- "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==",
- "requires": {
- "@types/unist": "^2.0.0",
- "unist-util-is": "^5.0.0",
- "unist-util-visit-parents": "^5.1.1"
- }
- },
- "unist-util-visit-parents": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz",
- "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==",
- "requires": {
- "@types/unist": "^2.0.0",
- "unist-util-is": "^5.0.0"
- }
- },
"universalify": {
"version": "0.1.2",
"dev": true
@@ -41702,13 +35403,31 @@
"version": "1.0.0",
"dev": true
},
+ "unplugin": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.0.1.tgz",
+ "integrity": "sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==",
+ "requires": {
+ "acorn": "^8.8.1",
+ "chokidar": "^3.5.3",
+ "webpack-sources": "^3.2.3",
+ "webpack-virtual-modules": "^0.5.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "8.12.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
+ "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg=="
+ }
+ }
+ },
"update-browserslist-db": {
- "version": "1.0.13",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
- "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
+ "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
"requires": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.0"
}
},
"upper-case": {
@@ -41745,10 +35464,6 @@
"requires-port": "^1.0.0"
}
},
- "urlgrey": {
- "version": "0.4.4",
- "dev": true
- },
"urlpattern-polyfill": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-6.0.2.tgz",
@@ -41794,29 +35509,6 @@
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="
},
- "uvu": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
- "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==",
- "requires": {
- "dequal": "^2.0.0",
- "diff": "^5.0.0",
- "kleur": "^4.0.3",
- "sade": "^1.7.3"
- },
- "dependencies": {
- "diff": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz",
- "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw=="
- },
- "kleur": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
- "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="
- }
- }
- },
"v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
@@ -41838,14 +35530,6 @@
}
}
},
- "validate-npm-package-license": {
- "version": "3.0.4",
- "dev": true,
- "requires": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.0"
- }
- },
"validator": {
"version": "13.7.0",
"dev": true
@@ -41859,33 +35543,6 @@
"integrity": "sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==",
"dev": true
},
- "vfile": {
- "version": "5.3.7",
- "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz",
- "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==",
- "requires": {
- "@types/unist": "^2.0.0",
- "is-buffer": "^2.0.0",
- "unist-util-stringify-position": "^3.0.0",
- "vfile-message": "^3.0.0"
- },
- "dependencies": {
- "is-buffer": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz",
- "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ=="
- }
- }
- },
- "vfile-message": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz",
- "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==",
- "requires": {
- "@types/unist": "^2.0.0",
- "unist-util-stringify-position": "^3.0.0"
- }
- },
"vite": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.2.7.tgz",
@@ -42100,17 +35757,6 @@
"xml-name-validator": "^3.0.0"
}
},
- "wait-on": {
- "version": "5.3.0",
- "dev": true,
- "requires": {
- "axios": "^0.21.1",
- "joi": "^17.3.0",
- "lodash": "^4.17.21",
- "minimist": "^1.2.5",
- "rxjs": "^6.6.3"
- }
- },
"walker": {
"version": "1.0.8",
"optional": true,
@@ -42118,12 +35764,6 @@
"makeerror": "1.0.12"
}
},
- "warning": {
- "version": "3.0.0",
- "requires": {
- "loose-envify": "^1.0.0"
- }
- },
"watskeburt": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/watskeburt/-/watskeburt-0.10.0.tgz",
@@ -42221,6 +35861,8 @@
},
"which": {
"version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
@@ -42251,24 +35893,6 @@
"version": "2.0.0",
"dev": true
},
- "which-pm": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-2.0.0.tgz",
- "integrity": "sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==",
- "dev": true,
- "requires": {
- "load-yaml-file": "^0.2.0",
- "path-exists": "^4.0.0"
- },
- "dependencies": {
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
- }
- }
- },
"which-typed-array": {
"version": "1.1.8",
"optional": true,
@@ -42294,9 +35918,9 @@
"dev": true
},
"workerpool": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
- "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz",
+ "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==",
"dev": true
},
"wrap-ansi": {
@@ -42333,38 +35957,10 @@
"version": "3.0.0",
"optional": true
},
- "xmlbuilder2": {
- "version": "3.0.2",
- "requires": {
- "@oozcitak/dom": "1.15.10",
- "@oozcitak/infra": "1.0.8",
- "@oozcitak/util": "8.3.8",
- "@types/node": "*",
- "js-yaml": "3.14.0"
- },
- "dependencies": {
- "js-yaml": {
- "version": "3.14.0",
- "requires": {
- "argparse": "^1.0.7",
- "esprima": "^4.0.0"
- }
- }
- }
- },
"xmlchars": {
"version": "2.2.0",
"optional": true
},
- "xmldoc": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.3.0.tgz",
- "integrity": "sha512-y7IRWW6PvEnYQZNZFMRLNJw+p3pezM4nKYPfr15g4OOW9i8VpeydycFuipE2297OvZnh3jSb2pxOt9QpkZUVng==",
- "dev": true,
- "requires": {
- "sax": "^1.2.4"
- }
- },
"y18n": {
"version": "4.0.3",
"dev": true
@@ -42406,9 +36002,9 @@
}
},
"yargs-parser": {
- "version": "20.2.4",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
- "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
"devOptional": true
},
"yargs-unparser": {
@@ -42467,10 +36063,11 @@
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz",
"integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg=="
},
- "zwitch": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
- "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="
+ "zod-validation-error": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.4.0.tgz",
+ "integrity": "sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ==",
+ "dev": true
}
}
}
diff --git a/package.json b/package.json
index 32e3bad863b..2a475086a5f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "saleor-dashboard",
- "version": "3.20.0-dev",
+ "version": "3.20.28",
"main": "src/index.tsx",
"repository": {
"type": "git",
@@ -18,12 +18,11 @@
},
"dependencies": {
"@apollo/client": "3.4.17",
- "@dnd-kit/core": "^6.0.8",
+ "@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^7.0.2",
"@dnd-kit/utilities": "^3.2.1",
- "@editorjs/editorjs": "^2.24.3",
+ "@editorjs/editorjs": "^2.30.7",
"@editorjs/header": "^2.6.2",
- "@editorjs/image": "^2.6.2",
"@editorjs/list": "^1.7.0",
"@editorjs/paragraph": "^2.8.0",
"@editorjs/quote": "^2.4.0",
@@ -39,20 +38,17 @@
"@material-ui/styles": "^4.11.4",
"@reach/auto-id": "^0.16.0",
"@saleor/macaw-ui": "npm:@saleor/macaw-ui@0.7.4",
- "@saleor/macaw-ui-next": "npm:@saleor/macaw-ui@1.1.5",
+ "@saleor/macaw-ui-next": "npm:@saleor/macaw-ui@1.1.15",
"@saleor/sdk": "0.6.0",
- "@sentry/react": "^7.83.0",
- "@sentry/vite-plugin": "^2.15.0",
+ "@sentry/react": "^8.21.0",
+ "@sentry/vite-plugin": "^2.21.1",
"@types/faker": "^5.1.6",
"@uiw/react-color-hue": "0.0.34",
- "@uiw/react-color-material": "^0.1.0",
"@uiw/react-color-saturation": "0.0.34",
- "@vanilla-extract/css-utils": "^0.1.3",
"apollo-upload-client": "^17.0.0",
"chroma-js": "^2.4.2",
"clsx": "^1.2.1",
"color-convert": "^2.0.1",
- "crc-32": "^1.2.2",
"currency-codes": "^2.1.0",
"currency.js": "^2.0.4",
"debug": "^4.3.4",
@@ -61,44 +57,35 @@
"eslint-plugin-prettier": "^5.1.3",
"faker": "^5.1.0",
"fast-array-diff": "^0.2.0",
- "find-test-names": "^1.17.1",
"front-matter": "^4.0.2",
"fuse.js": "^6.6.2",
"graphiql": "^2.2.0",
"graphql": "^15.4.0",
"hotkeys-js": "^3.8.1",
"is-url": "^1.2.4",
- "jss": "^9.8.7",
- "junit-report-merger": "^3.0.5",
"jwt-decode": "^3.1.2",
"keycode": "^2.2.1",
"lodash": "^4.17.21",
- "lz-string": "^1.4.4",
"marked": "^4.0.17",
"moment-timezone": "^0.5.32",
- "pixelmatch": "^5.3.0",
"posthog-js": "^1.105.9",
"qs": "^6.10.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
- "react-draggable": "^4.4.5",
"react-dropzone": "^11.2.4",
"react-editor-js": "^2.0.6",
"react-error-boundary": "^3.1.4",
- "react-github-btn": "^1.4.0",
"react-gtm-module": "^2.0.11",
"react-helmet": "^6.1.0",
"react-hook-form": "^7.48.2",
"react-infinite-scroll-component": "^6.1.0",
"react-inlinesvg": "^3.0.2",
"react-intl": "^5.21.2",
- "react-jss": "^10.0.0",
"react-moment": "^1.0.0",
"react-responsive-carousel": "^3.2.23",
"react-router": "^5.0.1",
"react-router-dom": "^5.0.1",
"react-sortable-hoc": "^1.10.1",
- "remark-gfm": "^3.0.1",
"slugify": "^1.4.6",
"tslib": "^2.4.1",
"url-join": "^4.0.1",
@@ -107,8 +94,7 @@
"zod": "^3.22.4"
},
"devDependencies": {
- "@changesets/changelog-github": "^0.4.8",
- "@changesets/cli": "^2.26.1",
+ "@changesets/cli": "^2.27.9",
"@editorjs/embed": "^2.5.3",
"@esbuild-plugins/node-globals-polyfill": "^0.1.1",
"@formatjs/cli": "^4.5.0",
@@ -121,15 +107,15 @@
"@graphql-codegen/typescript-apollo-client-helpers": "^2.1.10",
"@graphql-codegen/typescript-operations": "^2.2.4",
"@graphql-codegen/typescript-react-apollo": "^3.2.5",
- "@playwright/test": "^1.40.0",
+ "@playwright/test": "^1.47.0",
"@saleor/app-sdk": "0.47.2",
- "@sentry/cli": "^2.22.3",
+ "@sentry/cli": "^2.33.0",
"@swc/jest": "^0.2.26",
"@types/apollo-upload-client": "^17.0.2",
"@types/chroma-js": "^2.4.0",
"@types/color-convert": "^2.0.0",
"@types/debug": "^4.1.7",
- "@types/is-ci": "^3.0.0",
+ "@types/is-url": "^1.2.32",
"@types/lodash-es": "^4.17.3",
"@types/node": "^20.8.0",
"@types/qs": "^6.9.12",
@@ -138,7 +124,6 @@
"@types/react-dropzone": "^4.2.2",
"@types/react-gtm-module": "^2.0.3",
"@types/react-helmet": "^5.0.8",
- "@types/react-infinite-scroller": "^1.2.3",
"@types/react-router-dom": "^4.3.4",
"@types/react-sortable-hoc": "^0.7.1",
"@types/url-join": "^4.0.1",
@@ -147,15 +132,11 @@
"@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.41.0",
"@vitejs/plugin-react-swc": "^3.2.0",
- "ci-info": "^3.7.0",
"code-inspector-plugin": "^0.6.1",
- "codecov": "^3.7.1",
"core-js": "^3.7.0",
"cross-env": "^6.0.3",
"dependency-cruiser": "^12.10.0",
"dotenv": "^10.0.0",
- "env-var": "^7.3.0",
- "esbuild-loader": "^2.18.0",
"eslint": "^8.43.0",
"eslint-config-prettier": "^8.5.0",
"eslint-nibble": "^8.1.0",
@@ -166,21 +147,17 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.3.1",
"eslint-plugin-simple-import-sort": "^10.0.0",
- "graphql-request": "^3.7.0",
"html-to-react": "^1.6.0",
"identity-obj-proxy": "^3.0.0",
"is-ci": "^3.0.1",
- "junit-merge": "^2.0.0",
+ "knip": "^5.30.5",
"mocha": "^10.2.0",
"mochawesome": "^7.1.3",
"mochawesome-merge": "^4.3.0",
"mochawesome-report-generator": "^6.2.0",
+ "playwright-ctrf-json-reporter": "^0.0.18",
"playwright-testmo-reporter": "^1.8.4",
- "regenerator-runtime": "^0.11.1",
- "require-context.macro": "^1.1.1",
- "rimraf": "^3.0.0",
"rollup-plugin-polyfill-node": "^0.11.0",
- "start-server-and-test": "^1.11.0",
"typescript": "^5.0.4",
"typescript-strict-plugin": "^2.1.0",
"vite": "^3.2.7",
@@ -200,7 +177,7 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^12.1.5",
"@testing-library/react-hooks": "^8.0.1",
- "@testing-library/user-event": "^14.4.3",
+ "@testing-library/user-event": "^14.5.2",
"@types/jest": "^26.0.14",
"@types/setup-polly-jest": "^0.5.0",
"fsevents": "^1.2.9",
@@ -256,7 +233,10 @@
"^@material-ui/icons$": "/node_modules/@material-ui/icons",
"^@material-ui/styles$": "/node_modules/@material-ui/styles",
"^react$": "/node_modules/react",
- "^react-dom$": "/node_modules/react-dom"
+ "^react-dom$": "/node_modules/react-dom",
+ "collectCoverageFrom": [
+ "/src/**/*.{ts,tsx}"
+ ]
}
},
"overrides": {
@@ -284,7 +264,7 @@
"serve:lhci": "cross-env NODE_ENV=production npm run server",
"prestart": "npm run build-types",
"test": "jest src/",
- "posttest": "node scripts/pika.js",
+ "test:ci": "jest src/ --coverage",
"test:watch": "jest --watch src/",
"lint": "eslint \"{src,playwright}/**/*.@(tsx|ts|jsx|js)\" --fix",
"lint:check-progress": "eslint-nibble \"src/**/*.@(tsx|ts|jsx|js)\"",
@@ -305,8 +285,10 @@
"qa:move-videos": "find cypress/videos -type f -name \"*.js.mp4\" -exec mv {} cypress/reports/mochareports/videos \\;",
"qa:artifact-move-screenshots": "find cypress/reports/*/mochareports -type d -name \"*.js\" -exec mv {} cypress/reports/mochareports \\;",
"qa:artifact-move-videos": "find cypress/reports/*/mochareports/videos -type f -name \"*.js.mp4\" -exec mv {} cypress/reports/mochareports/videos \\;",
- "qa:pw-e2e": "npx playwright test --grep @e2e",
- "qa:pw-ui": "npx playwright test --ui"
+ "qa:pw-e2e": "npx playwright test --grep \"#e2e\"",
+ "qa:pw-ui": "npx playwright test --ui",
+ "knip": "knip --reporter markdown",
+ "knip:fix": "knip --fix"
},
"description": ""
-}
+}
\ No newline at end of file
diff --git a/playwright.config.ts b/playwright.config.ts
index 4f304108f3c..1571ec1f539 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -4,39 +4,57 @@ import dotenv from "dotenv";
dotenv.config();
const env = process.env;
-const DEFAULT_RETRIES = "1";
const DEFAULT_WORKERS = "2";
+const shardNumber = env.SHARD_NUMBER?.match(/^\d*/)?.[0] || "0";
+
+// const DEFAULT_RETRIES = "1";
+
+// FIXME: High timeouts are a temporary solution to handle slower CI environments.
+// Local development on high-performance machines is much faster, but shared CI workers
+// can be overloaded, causing operations to take longer than expected.
+export const SUCCESS_BANNER_TIMEOUT = process.env.CI ? 20000 : 10000;
export default defineConfig({
testDir: "playwright/tests",
fullyParallel: true,
forbidOnly: !!env.CI,
- retries: parseInt(env.RETRIES || DEFAULT_RETRIES),
+ retries: 0,
+ // We are disabling retries for now as it prolongs the test run time
+ // as the test will most likely fail again. We can enable it later if needed.
+ // retries: parseInt(env.RETRIES || DEFAULT_RETRIES),
workers: parseInt(env.WORKERS || DEFAULT_WORKERS),
+
reporter: process.env.CI
? [
- ["blob"],
- ["github"],
- [
- "playwright-testmo-reporter",
- {
- outputFile: "testmo/testmo.xml", // Optional: Output file path. Defaults to 'testmo.xml'.
- embedBrowserType: true, // Optional: Embed browser type in the XML file. Defaults to false.
- embedTestSteps: true, // Optional: Embed test steps in the XML file. Defaults to true.
- testStepCategories: ["hook", "expect", "pw:api", "test.step"], // Optional: Test step categories to include in the XML file. Defaults to ["hook","expect","pw:api","test.step"]. Possible options are "hook", "expect", "pw:api", "test.step".
- testTitleDepth: 1, // Optional: Test case title depth to report in the XML file. Defaults to 1. Increase this to 2 include suite name. Increase this even further to include the path.
- attachmentBasePathCallback: () =>
- process.env.URL_TO_RUN ? process.env.URL_TO_RUN : "",
- },
- ],
- ]
+ ["blob"],
+ ["github"],
+ [
+ "playwright-testmo-reporter",
+ {
+ outputFile: "testmo/testmo.xml", // Optional: Output file path. Defaults to 'testmo.xml'.
+ embedBrowserType: true, // Optional: Embed browser type in the XML file. Defaults to false.
+ embedTestSteps: true, // Optional: Embed test steps in the XML file. Defaults to true.
+ testStepCategories: ["hook", "expect", "pw:api", "test.step"], // Optional: Test step categories to include in the XML file. Defaults to ["hook","expect","pw:api","test.step"]. Possible options are "hook", "expect", "pw:api", "test.step".
+ testTitleDepth: 1, // Optional: Test case title depth to report in the XML file. Defaults to 1. Increase this to 2 include suite name. Increase this even further to include the path.
+ attachmentBasePathCallback: () =>
+ process.env.URL_TO_RUN ? process.env.URL_TO_RUN : "",
+ },
+ ],
+ ['playwright-ctrf-json-reporter', {
+ outputFile: `ctrf-report-${shardNumber}.json`, // Optional: Output file name. Defaults to 'ctrf-report.json'.
+ minimal: true, // Optional: Generate a minimal report. Defaults to 'false'. Overrides screenshot and testType when set to true
+ appName: 'Saleor Dashboard', // Optional: Specify the name of the application under test.
+ appVersion: env.DASHBOARD_VERSION || '', // Optional: Specify the version of the application under test.
+ branchName: env.BRANCH_NAME || '', // Optional: Specify the branch name.
+ testEnvironment: env.SALEOR_CLOUD_SERVICE || '' // Optional: Specify the test environment (e.g. staging, production).
+ }]]
: [["html"], ["list"]],
- expect: { timeout: 5000 },
+ expect: { timeout: 10 * 1000 },
maxFailures: 10,
- timeout: 30000,
+ timeout: 35 * 1000,
use: {
baseURL: env.BASE_URL || "",
- trace: env.CI ? "on-all-retries" : "on",
+ trace: env.CI ? "retain-on-failure" : "on",
screenshot: "only-on-failure",
testIdAttribute: "data-test-id",
video: env.CI ? "retain-on-failure" : "off",
@@ -48,9 +66,16 @@ export default defineConfig({
testMatch: /.*\.setup\.ts/,
},
{
- name: "chromium",
+ name: "e2e",
+ dependencies: ["setup"],
+ use: { ...devices["Desktop Chrome"] },
+ testIgnore: "playwright/tests/apps.spec.ts",
+ },
+ {
+ name: "apps-e2e",
dependencies: ["setup"],
use: { ...devices["Desktop Chrome"] },
+ testMatch: "playwright/tests/apps.spec.ts",
},
],
});
diff --git a/playwright/auth.js b/playwright/auth.js
new file mode 100644
index 00000000000..de6310b1aff
--- /dev/null
+++ b/playwright/auth.js
@@ -0,0 +1,191 @@
+/* eslint-disable */
+
+const { request } = require("@playwright/test");
+const dotenv = require("dotenv");
+const process = require("process");
+const crypto = require("crypto");
+const path = require("path");
+const fs = require("fs");
+
+dotenv.config();
+
+const algorithm = 'aes-256-ctr';
+
+const PERMISSIONS = [
+ "admin",
+ "app",
+ "discount",
+ "order",
+ "channel",
+ "customer",
+ "giftCard",
+ "page",
+ "plugin",
+ "productTypeAndAttribute",
+ "product",
+ "settings",
+ "staff",
+ "shipping",
+ "translations",
+]
+
+const ACCOUNT_EMAILS = {
+ channel: "channel.manager@example.com",
+ shipping: "shipping.manager@example.com",
+ giftCard: "gift.card.manager@example.com",
+ app: "app.manager@example.com",
+ settings: "setting.manager@example.com",
+ page: "page.manager@example.com",
+ order: "order.manager@example.com",
+ translations: "translation.manager@example.com",
+ staff: "staff.manager@example.com",
+ customer: "user.manager@example.com",
+ productTypeAndAttribute: "product.type.and.attribute.manager@example.com",
+ discount: "discount.manager@example.com",
+ plugin: "plugin.manager@example.com",
+ product: "product.manager@example.com",
+};
+
+const createQuery = (email, password) => {
+ const query = `
+ mutation TokenAuth($email: String!, $password: String!) {
+ tokenCreate(email: $email, password: $password) {
+ token
+ refreshToken
+ errors {
+ code
+ message
+ }
+ user {
+ id
+ }
+ }
+ }
+ `
+
+ const variables = { email, password }
+
+ return { query, variables }
+};
+
+
+const getEmailForPermission = (permission) => {
+ if (permission === "admin") {
+ return process.env.E2E_USER_NAME;
+ }
+
+ return ACCOUNT_EMAILS[permission];
+};
+
+const getPasswordForPermission = (permission) => {
+ if (permission === "admin") {
+ return process.env.E2E_USER_PASSWORD;
+ }
+
+ return process.env.E2E_PERMISSIONS_USERS_PASSWORD;
+};
+
+const getAuthForPermission = async (permissionName) => {
+ const apiRequestContext = await request.newContext({
+ baseURL: process.env.BASE_URL,
+ });
+
+ const email = getEmailForPermission(permissionName);
+ const password = getPasswordForPermission(permissionName);
+
+ const response = await apiRequestContext.post(process.env.API_URL || "", {
+ data: createQuery(email, password),
+ });
+ const resposnseObj = await response.json()
+ const { errors } = resposnseObj.data.tokenCreate
+
+ if (errors && errors.length > 0) {
+ const errorMessages = errors
+ .map(e => e.message)
+ .join(", ");
+
+ throw new Error(`Login failed for permission ${permissionName}: ${errorMessages}`);
+ }
+
+ const loginJsonInfo = await apiRequestContext.storageState();
+
+ return loginJsonInfo
+}
+
+const encrypt = (password, text) => {
+ const key = Buffer.concat([Buffer.from(password), Buffer.alloc(32)], 32);
+ const iv = crypto.randomBytes(16);
+ const cipher = crypto.createCipheriv(algorithm, key, iv);
+ let encrypted = cipher.update(text);
+ encrypted = Buffer.concat([encrypted, cipher.final()]);
+ return iv.toString('hex') + encrypted.toString('hex');
+}
+
+const decrypt = (password, text) => {
+ const key = Buffer.concat([Buffer.from(password), Buffer.alloc(32)], 32);
+ const iv = Buffer.from(text.substring(0, 32), 'hex');
+ const encryptedText = Buffer.from(text.substring(32), 'hex');
+ const decipher = crypto.createDecipheriv(algorithm, key, iv);
+ let decrypted = decipher.update(encryptedText);
+ decrypted = Buffer.concat([decrypted, decipher.final()]);
+ return decrypted.toString();
+}
+
+(async () => {
+ const command = process.argv[2]
+
+ if (command == "login") {
+ let authString = ''
+
+ for (const permissionName of PERMISSIONS) {
+
+ const auth = await getAuthForPermission(permissionName)
+
+
+ authString = `${authString}${JSON.stringify(auth)}|`
+ }
+
+ const encodedString = encrypt(process.env.E2E_ENCODE_PASS, authString)
+
+ process.stdout.write(encodedString)
+ }
+
+
+ if (command == "restore") {
+ const tempDir = path.join(__dirname, "../playwright/.auth");
+
+ if (!fs.existsSync(tempDir)) {
+ fs.mkdirSync(tempDir, { recursive: true });
+ }
+
+
+ const encodedInput = process.argv[3]
+ console.log("Restoring...", encodedInput.length)
+
+
+ const decodedString = decrypt(process.env.E2E_ENCODE_PASS, encodedInput)
+ decodedString
+ .split("|")
+ .filter(Boolean)
+ .map(JSON.parse)
+ .map(obj => {
+ obj.origins.push({
+ origin: process.env.BASE_URL,
+ localStorage: [
+ {
+ name: "_saleorRefreshToken",
+ value: obj.cookies[0].value,
+ },
+ ],
+ });
+
+ return obj
+ })
+ .map(JSON.stringify)
+ .map((str, index) => ({ name: PERMISSIONS[index], str }))
+ .forEach(token => {
+ const storageStatePath = path.join(tempDir, `${token.name}.json`);
+ fs.writeFileSync(storageStatePath, token.str);
+ })
+ }
+})()
\ No newline at end of file
diff --git a/playwright/data/commonLocators.ts b/playwright/data/commonLocators.ts
index 40bad19ab70..e8556e8e11a 100644
--- a/playwright/data/commonLocators.ts
+++ b/playwright/data/commonLocators.ts
@@ -6,5 +6,5 @@ export const LOCATORS = {
dataGridTable: '[data-testid="data-grid-canvas"]',
deleteButton: '[data-test-id="button-bar-delete"]',
bulkDeleteButton: '[data-test-id="bulk-delete-button"]',
- loader: '[data-test-id="loader"]',
+ dataGridLoader: '[data-test-id="datagrid-loader"]',
};
diff --git a/playwright/data/e2eTestData.ts b/playwright/data/e2eTestData.ts
index fa564bfbb3e..147be7b566b 100644
--- a/playwright/data/e2eTestData.ts
+++ b/playwright/data/e2eTestData.ts
@@ -37,13 +37,13 @@ export const ATTRIBUTES = {
},
],
attributeTypesWithAbilityToAddValues: {
- names: ["DROPDOWN", "MULTISELECT", "SWATCH"],
+ names: ["Dropdown", "Multiple Select", "Swatch"],
},
attributeTypesWithoutAbilityToAddValues: {
- names: ["FILE", "NUMERIC", "RICH_TEXT", "PLAIN_TEXT", "BOOLEAN", "DATE", "DATE_TIME"],
+ names: ["File", "Numeric", "Rich Text", "Plain Text", "Boolean", "Date", "Date Time"],
},
attributeReferencesEntities: {
- names: ["PAGE", "PRODUCT", "PRODUCT_VARIANT"],
+ names: ["Page", "Product", "Product Variant"],
},
attributeToBeAssignedToPageType: {
name: "Attribute to be assigned to page type",
@@ -404,12 +404,45 @@ export const PRODUCTS = {
"a product to be deleted via bulk 3/3",
],
},
+ productWithPriceHigherThan20: {
+ id: "UHJvZHVjdDoxMjE=",
+ name: "Ocean Poems",
+ variantSKU: "ocean-poems-mp3",
+ price: 22,
+ },
+ productWithPriceLowerThan20: {
+ name: "Bean Juice",
+ variantSKU: "57423879",
+ price: 3,
+ },
+ giftProduct: {
+ name: "Power Juice",
+ },
+ productWithDiscountChannelPLN: {
+ id: "UHJvZHVjdDo3NzE=",
+ name: "e2e-do-not-touch",
+ rewardPercentageDiscountValue: 40,
+ variant: {
+ id: "UHJvZHVjdFZhcmlhbnQ6MTIzOQ==",
+ sku: "TEST-123",
+ undiscountedPrice: 100,
+ discountedPrice: 60,
+ },
+ },
};
export const ORDERS = {
draftOrdersToBeDeleted: {
ids: ["#3266", "#3265"],
},
+ draftOrderChannelPLN: {
+ id: "T3JkZXI6ZGZjMDRjOTEtNDYyNy00Y2FhLWE5MzAtYTA5ZTE1MTlkODI1",
+ productInBasket: {
+ productName: "Black Hoodie",
+ price: 20,
+ variantId: "UHJvZHVjdFZhcmlhbnQ6Mjk3",
+ },
+ },
ordersWithinTransactionFlow: {
markAsPaidOrder: {
orderId: "T3JkZXI6MDE4ZWM0NGUtNTgwMC00NGM0LTliMzAtZDE3YTIxYjljOTgz",
@@ -432,21 +465,15 @@ export const ORDERS = {
orderNotFulfilledToChangeShippingAddress: {
id: "T3JkZXI6ZWFhZjA0MzgtNzkyYi00ZTdlLWIyODUtMTBkMjViMjM0MzRk",
},
- fullyPaidOrdersWithSingleTransaction: {
- first: {
- id: "T3JkZXI6ZjZjZWUxMzItNDk2Zi00MWUyLWJkNTItYTk1MDM1YTVlZmVm",
- lineItems: [
- {
- name: "Bean Juice",
- quantity: "1",
- },
- { name: "Lake Tunes", quantity: "2" },
- ],
- },
- second: {
- id: "T3JkZXI6YzI4YjFmYmEtZWU1NS00YmU5LTg5MjktNTMyYzk5MDlkZGVk",
- lineItems: ["Blue Hoodie 2", "Black Hoodie", "Mustard Hoodie", "White Hoodie"],
- },
+ fullyPaidOrderWithSingleTransaction: {
+ id: "T3JkZXI6ZjZjZWUxMzItNDk2Zi00MWUyLWJkNTItYTk1MDM1YTVlZmVm",
+ lineItems: [
+ {
+ name: "Bean Juice",
+ quantity: "1",
+ },
+ { name: "Lake Tunes", quantity: "2" },
+ ],
},
fullyPaidOrderWithSeveralTransactions: {
id: "T3JkZXI6MTVhYTEwMzYtZWE3OS00MzJiLTliODctNDhlYTMwYmU1NmNl",
@@ -456,6 +483,25 @@ export const ORDERS = {
partiallyPaidOrder: {
id: "T3JkZXI6NmVlMDMwMTctZTViOS00OGNmLWFkYTQtODg4YTQ5MDI3ZjNk",
},
+ orderWithRefundsInStatusOtherThanSuccess: {
+ id: "T3JkZXI6YzI4YjFmYmEtZWU1NS00YmU5LTg5MjktNTMyYzk5MDlkZGVk",
+ lineItems: [
+ { name: "Blue Hoodie 2", quantity: "1" },
+ { name: "Black Hoodie", quantity: "1" },
+ { name: "Mustard Hoodie", quantity: "1" },
+ { name: "White Hoodie", quantity: "1" },
+ ],
+ refunds: [
+ {
+ id: "T3JkZXJHcmFudGVkUmVmdW5kOjEw",
+ status: "FAILURE",
+ },
+ {
+ id: "T3JkZXJHcmFudGVkUmVmdW5kOjg%3D",
+ status: "DRAFT",
+ },
+ ],
+ },
orderWithRefunds: {
id: "T3JkZXI6Y2YyY2EwNWYtZmQ3Yy00ODk5LThjZTktMzQ4NjYxYThjZDkx",
refunds: [
@@ -469,12 +515,16 @@ export const ORDERS = {
},
],
},
+ orderWithoutAddedCustomer: {
+ id: "T3JkZXI6MDM4MjM4NDMtYjg3My00ZTQ2LWE1NTItNjc0ZGIwZjE2ZGZh",
+ },
};
export const SHIPPING_METHODS = {
shippingMethodWithoutRates: {
id: "U2hpcHBpbmdab25lOjIzOTA%3D",
info: "Shipping method that is used to add rates",
+ name: "Shipping method that is used to add rates",
},
shippingMethodToBeUpdated: {
id: "U2hpcHBpbmdab25lOjIzOTI=",
diff --git a/playwright/data/userPermissions.ts b/playwright/data/userPermissions.ts
index bb7029c3463..d1e22ed74f4 100644
--- a/playwright/data/userPermissions.ts
+++ b/playwright/data/userPermissions.ts
@@ -32,7 +32,9 @@ export const USER_PERMISSION: UserPermissionType = {
product: "product.manager@example.com",
};
-export const permissions: Array = [
+export type UserPermission = keyof UserPermissionType;
+
+export const permissions: Array = [
"app",
"discount",
"order",
diff --git a/playwright/pages/appPageThirdparty.ts b/playwright/pages/appPageThirdparty.ts
index 39fc41ee994..3cf0ef01a04 100644
--- a/playwright/pages/appPageThirdparty.ts
+++ b/playwright/pages/appPageThirdparty.ts
@@ -1,6 +1,6 @@
import { URL_LIST } from "@data/url";
import { BasePage } from "@pages/basePage";
-import type { Page } from "@playwright/test";
+import { expect, Page } from "@playwright/test";
import { DeleteDialog } from "./dialogs/deleteDialog";
@@ -15,6 +15,7 @@ export class AppPage extends BasePage {
page: Page,
readonly deleteButton = page.getByText("Delete"),
readonly appSettingsButton = page.getByTestId("app-settings-button"),
+ readonly appPageLoader = page.getByTestId("app-page-loader"),
) {
super(page);
this.page = page;
@@ -31,4 +32,9 @@ export class AppPage extends BasePage {
async clickAppSettingsButton() {
await this.appSettingsButton.click();
}
+
+ async waitContentLoad() {
+ await expect(this.appPageLoader).toBeVisible();
+ await this.appPageLoader.waitFor({ state: "hidden" });
+ }
}
diff --git a/playwright/pages/appsPage.ts b/playwright/pages/appsPage.ts
index 040c2f1a99d..f239a2c0da8 100644
--- a/playwright/pages/appsPage.ts
+++ b/playwright/pages/appsPage.ts
@@ -1,6 +1,6 @@
import { URL_LIST } from "@data/url";
import { BasePage } from "@pages/basePage";
-import type { Page } from "@playwright/test";
+import { expect, Page } from "@playwright/test";
export class AppsPage extends BasePage {
readonly page: Page;
@@ -22,6 +22,7 @@ export class AppsPage extends BasePage {
readonly appAdyen = page.getByTestId("app-adyen"),
readonly appQA = page.getByTestId("app-saleorqa app"),
readonly installationPendingLabel = page.getByTestId("app-pending-label").first(),
+ readonly availableAppsLoader = page.getByTestId("available-apps-loader"),
) {
super(page);
this.page = page;
@@ -35,4 +36,8 @@ export class AppsPage extends BasePage {
async typeManifestUrl(manifestUrl: string) {
await this.appManifestUrlInput.fill(manifestUrl);
}
+
+ async waitForContentLoad() {
+ await this.availableAppsLoader.waitFor({ state: "hidden" });
+ }
}
diff --git a/playwright/pages/attributesPage.ts b/playwright/pages/attributesPage.ts
index 4774eac124e..1816902a1eb 100644
--- a/playwright/pages/attributesPage.ts
+++ b/playwright/pages/attributesPage.ts
@@ -39,7 +39,8 @@ export class AttributesPage extends BasePage {
readonly deleteAttrValueDialog = page.getByTestId("delete-attribute-value-dialog"),
readonly editAttrValueDialog = page.getByTestId("edit-attribute-value-dialog"),
readonly attrValuesSection = page.getByTestId("attribute-values-section"),
- readonly attrEntityTypeSelect = page.locator(`[id="mui-component-select-entityType"]`),
+ readonly attrEntityTypeSelect = page.getByTestId("attribute-entity-type-select"),
+ readonly attributeSelectOption = page.getByTestId("select-option"),
readonly attrVisibleInStorefrontSwitch = page.locator(`[name = "visibleInStorefront"]`),
readonly metadataSectionAccordionButton = page
.getByTestId("metadata-item")
@@ -121,7 +122,7 @@ export class AttributesPage extends BasePage {
async selectAttributeInputType(attributeType: string) {
await this.attributeSelect.click();
- await this.page.getByTestId(`select-field-option-${attributeType}`).click();
+ await this.attributeSelectOption.filter({ hasText: attributeType }).first().click();
}
async clickAssignAttributeValueButton() {
@@ -149,7 +150,7 @@ export class AttributesPage extends BasePage {
async selectAttributeEntityType(entityType: string) {
await this.attrEntityTypeSelect.click();
- await this.page.getByTestId(`select-field-option-${entityType}`).click();
+ await this.attributeSelectOption.filter({ hasText: entityType }).first().click();
}
async changeAttributeVisibility() {
diff --git a/playwright/pages/basePage.ts b/playwright/pages/basePage.ts
index dd012e59a07..e720faea4ed 100644
--- a/playwright/pages/basePage.ts
+++ b/playwright/pages/basePage.ts
@@ -2,6 +2,8 @@ import { LOCATORS } from "@data/commonLocators";
import type { Locator, Page } from "@playwright/test";
import { expect } from "@playwright/test";
+import { SUCCESS_BANNER_TIMEOUT } from "../../playwright.config";
+
export class BasePage {
readonly page: Page;
@@ -18,7 +20,7 @@ export class BasePage {
readonly errorBanner = page.locator(LOCATORS.errorBanner),
readonly saveButton = page.locator(LOCATORS.saveButton),
readonly infoBanner = page.locator(LOCATORS.infoBanner),
- readonly loader = page.locator(LOCATORS.loader),
+ readonly dataGridLoader = page.locator(LOCATORS.dataGridLoader),
readonly previousPagePaginationButton = page.getByTestId("button-pagination-back"),
readonly rowNumberButton = page.getByTestId("PaginationRowNumberSelect"),
readonly rowNumberOption = page.getByTestId("rowNumberOption"),
@@ -100,17 +102,21 @@ export class BasePage {
await this.saveButton.click();
}
- async expectSuccessBannerMessage(msg: string) {
- await this.successBanner.locator(`text=${msg}`).waitFor({ state: "visible", timeout: 10000 });
- await expect(this.errorBanner, "No error banner should be visible").not.toBeVisible();
- }
-
async expectErrorBannerMessage(msg: string) {
await this.errorBanner.locator(`text=${msg}`).waitFor({ state: "visible", timeout: 10000 });
}
- async expectSuccessBanner() {
- await this.successBanner.first().waitFor({ state: "visible", timeout: 15000 });
+ async expectSuccessBanner(
+ options: { message?: string; timeout?: number } = { timeout: SUCCESS_BANNER_TIMEOUT },
+ ) {
+ if (options.message) {
+ await this.successBanner
+ .locator(`text=${options.message}`)
+ .waitFor({ state: "visible", timeout: options.timeout });
+ } else {
+ await this.successBanner.first().waitFor({ state: "visible", timeout: options.timeout });
+ }
+
await expect(this.errorBanner, "No error banner should be visible").not.toBeVisible();
}
@@ -265,14 +271,12 @@ export class BasePage {
return await this.findRowIndexBasedOnText([searchItem]);
}
- // check row on grid list view
async checkListRowsBasedOnContainingText(searchText: string[]) {
const rowIndexes = await this.findRowIndexBasedOnText(searchText);
for (const rowIndex of rowIndexes) {
await this.clickGridCell(0, rowIndex);
}
- // make sure all searched texts were found and checked
await expect(searchText.length).toEqual(rowIndexes.length);
}
@@ -315,7 +319,6 @@ export class BasePage {
async waitForDOMToFullyLoad() {
await this.page.waitForLoadState("domcontentloaded", { timeout: 70000 });
- await this.loader.waitFor({ state: "hidden" });
}
async expectElementIsHidden(locator: Locator) {
@@ -323,9 +326,14 @@ export class BasePage {
state: "hidden",
timeout: 30000,
});
+ await this.waitForDOMToFullyLoad();
}
async waitForCanvasContainsText(text: string) {
await this.gridCanvas.getByText(text).waitFor({ state: "attached", timeout: 50000 });
}
+
+ async waitForDatagridLoaderToDisappear() {
+ await this.dataGridLoader.waitFor({ state: "hidden" });
+ }
}
diff --git a/playwright/pages/collectionsPage.ts b/playwright/pages/collectionsPage.ts
index 3782013ebac..e3f98a3b017 100644
--- a/playwright/pages/collectionsPage.ts
+++ b/playwright/pages/collectionsPage.ts
@@ -28,7 +28,7 @@ export class CollectionsPage extends BasePage {
readonly assignProductButton = page.getByTestId("add-product"),
readonly collectionImages = page.getByTestId("product-image"),
readonly uploadImageButton = page.getByTestId("upload-image-button"),
- readonly collectionNameInput = page.getByTestId("collection-name-input").locator("input"),
+ readonly collectionNameInput = page.getByTestId("collection-name-input"),
readonly collectionDescriptionEditor = page.getByTestId("rich-text-editor-description"),
readonly descriptionLoader = page.locator(".codex-editor__loader"),
) {
diff --git a/playwright/pages/customersPage.ts b/playwright/pages/customersPage.ts
index 02cbb6fd442..95efd4b54e4 100644
--- a/playwright/pages/customersPage.ts
+++ b/playwright/pages/customersPage.ts
@@ -26,7 +26,11 @@ export class CustomersPage extends BasePage {
readonly deleteButton = page.getByTestId("button-bar-delete"),
readonly issueNewGiftCardButton = page.getByTestId("issue-new-gift-card"),
readonly emailPageTitleText = page.getByTestId("user-email-title"),
- readonly customerActiveCheckbox = page.getByTestId("customer-active-checkbox").locator("input"),
+ readonly customerActiveCheckbox = page
+ .getByTestId("customer-active-checkbox")
+ .locator("button"),
+ readonly amountDropdown = page.locator('div[name="balanceCurrency"]'),
+ readonly customerList = page.locator('div[data-test-id="list"]'),
) {
super(page);
this.addressForm = new AddressForm(page);
@@ -36,9 +40,8 @@ export class CustomersPage extends BasePage {
}
async goToCustomersListView() {
- await this.waitForNetworkIdleAfterAction(async () => {
- await this.page.goto(URL_LIST.customers);
- });
+ await this.page.goto(URL_LIST.customers);
+ await this.customerList.waitFor({ state: "visible" });
}
async searchForCustomer(customer: string) {
@@ -46,9 +49,8 @@ export class CustomersPage extends BasePage {
}
async gotoCustomerDetailsPage(customerId: string) {
- await this.waitForNetworkIdleAfterAction(async () => {
- await this.page.goto(`${URL_LIST.customers}${customerId}`);
- });
+ await this.page.goto(`${URL_LIST.customers}${customerId}`);
+ await this.customerFirstNameInput.waitFor({ state: "visible" });
}
async clickOnCreateCustomer() {
@@ -77,9 +79,8 @@ export class CustomersPage extends BasePage {
}
async clickIssueNewGiftCard() {
- await this.waitForNetworkIdleAfterAction(async () => {
- await this.issueNewGiftCardButton.click();
- });
+ await this.issueNewGiftCardButton.waitFor({ state: "visible" });
+ await this.issueNewGiftCardButton.click();
}
async clickCustomerActiveCheckbox() {
diff --git a/playwright/pages/dialogs/addNavigationMenuItemDialog.ts b/playwright/pages/dialogs/addNavigationMenuItemDialog.ts
index eb74e9d03a4..6e1092f8f8f 100644
--- a/playwright/pages/dialogs/addNavigationMenuItemDialog.ts
+++ b/playwright/pages/dialogs/addNavigationMenuItemDialog.ts
@@ -5,36 +5,50 @@ import { BasePage } from "../basePage";
export class AddNavigationMenuItemDialog extends BasePage {
constructor(
page: Page,
- readonly menuNameInput = page.getByTestId("menu-item-name-input").locator("input"),
- readonly linkSelect = page.getByTestId("container-autocomplete-select").locator("input"),
- readonly backButton = page.getByTestId("back"),
+ readonly menuNameInput = page.getByTestId("menu-item-name-input"),
+ readonly menuLinkType = page.getByTestId("menu-item-link-type-input"),
+ readonly menuLinkValue = page.getByTestId("menu-item-link-value-input"),
readonly saveButton = page.getByTestId("submit"),
- readonly menuLinkOptions = page.getByTestId("menu-link-options"),
+ readonly menuLinkOptions = page.getByTestId("select-option"),
) {
super(page);
}
- async selectLinkOption(option: string, optionName: string) {
- await this.linkSelect.click();
- await this.waitForDOMToFullyLoad();
- await this.menuLinkOptions.waitFor({ state: "attached" });
- await this.menuLinkOptions
- .getByRole("option", { name: "Categories" })
- .waitFor({ state: "visible" });
- await this.menuLinkOptions
- .getByRole("option", { name: "Collections" })
- .waitFor({ state: "visible" });
- await this.menuLinkOptions.getByRole("option", { name: "Pages" }).waitFor({ state: "visible" });
- await expect(this.menuLinkOptions.getByRole("option", { name: "Categories" })).toBeEnabled();
- await this.menuLinkOptions.getByTestId(option).click({ force: true });
- await this.waitForDOMToFullyLoad();
- await this.menuLinkOptions
- .getByRole("option", { name: optionName })
- .waitFor({ state: "visible" });
- expect(this.menuLinkOptions.getByRole("option", { name: optionName })).toBeEnabled();
- await this.menuLinkOptions.getByRole("option", { name: optionName }).click({ force: true });
- await this.waitForDOMToFullyLoad();
- await expect(this.linkSelect).toHaveValue(optionName);
+ async selectLinkTypeOption(linkType: string) {
+ await expect(async () => {
+ await this.menuLinkType.click();
+ await this.menuLinkOptions.first().waitFor({ state: "visible" });
+ }).toPass();
+
+ // Ensure the link type option is visible and select it
+ const linkTypeOption = this.menuLinkOptions.filter({ hasText: linkType });
+
+ await linkTypeOption.waitFor({ state: "visible" });
+ await expect(linkTypeOption).toBeEnabled();
+ await linkTypeOption.click({ force: true });
+
+ // Verify the correct link type is selected
+ const selectedLinkType = await this.menuLinkType.inputValue();
+
+ if (selectedLinkType !== linkType) {
+ throw new Error(`Expected link type "${linkType}" but found "${selectedLinkType}"`);
+ }
+ }
+
+ async selectLinkTypeValue(optionName: string) {
+ await expect(async () => {
+ await this.menuLinkValue.click();
+ }).toPass();
+
+ // Ensure the option is present and select it
+ const option = this.menuLinkOptions.filter({ hasText: optionName });
+
+ await option.waitFor({ state: "visible" });
+ await expect(option).toBeEnabled();
+ await option.click({ force: true });
+
+ // Verify the correct option is selected
+ await expect(this.menuLinkValue).toHaveValue(optionName);
}
async typeMenuItemName(name: string) {
@@ -43,6 +57,5 @@ export class AddNavigationMenuItemDialog extends BasePage {
async clickSaveButton() {
await this.saveButton.click();
- await this.waitForDOMToFullyLoad();
}
}
diff --git a/playwright/pages/dialogs/addProductsDialog.ts b/playwright/pages/dialogs/addProductsDialog.ts
index 40c07766d20..8f9cb8ea933 100644
--- a/playwright/pages/dialogs/addProductsDialog.ts
+++ b/playwright/pages/dialogs/addProductsDialog.ts
@@ -18,6 +18,7 @@ export class AddProductsDialog extends BasePage {
async clickConfirmButton() {
await this.confirmButton.click();
+ await this.waitForDOMToFullyLoad();
}
async clickBackButton() {
@@ -26,12 +27,13 @@ export class AddProductsDialog extends BasePage {
async searchForProductInDialog(productName: string) {
await this.searchInput.fill(productName);
+ await this.waitForDOMToFullyLoad();
}
async selectVariantBySKU(sku: string) {
const variant = this.variantRow.filter({ hasText: `SKU ${sku}` });
await variant.waitFor({ state: "visible" });
- await variant.getByRole("checkbox").click();
+ await variant.getByRole("checkbox").first().click();
}
}
diff --git a/playwright/pages/dialogs/deleteDialog.ts b/playwright/pages/dialogs/deleteDialog.ts
index 9a13438007f..84156b63c04 100644
--- a/playwright/pages/dialogs/deleteDialog.ts
+++ b/playwright/pages/dialogs/deleteDialog.ts
@@ -5,7 +5,7 @@ export class DeleteDialog extends BasePage {
constructor(
page: Page,
readonly deleteButton = page.getByTestId("submit"),
- readonly confirmDeletionCheckbox = page.locator("[name='delete-assigned-items-consent']"),
+ readonly confirmDeletionCheckbox = page.getByTestId("delete-assigned-items-consent"),
readonly confirmDeleteButton = page.getByTestId("confirm-delete"),
) {
super(page);
diff --git a/playwright/pages/dialogs/draftOrderCreateDialog.ts b/playwright/pages/dialogs/draftOrderCreateDialog.ts
index bb7ddb17d7d..7baa648d0fc 100644
--- a/playwright/pages/dialogs/draftOrderCreateDialog.ts
+++ b/playwright/pages/dialogs/draftOrderCreateDialog.ts
@@ -7,7 +7,7 @@ export class DraftOrderCreateDialog {
page: Page,
readonly channelNameInput = page.getByTestId("channel-autocomplete"),
readonly confirmButton = page.getByTestId("submit"),
- readonly channelOption = page.locator("[data-test-id*='select-field-option']"),
+ readonly channelOption = page.getByTestId("select-option"),
) {
this.page = page;
}
@@ -25,4 +25,10 @@ export class DraftOrderCreateDialog {
await this.channelOption.first().click();
await this.clickConfirmButton();
}
+
+ async completeDraftOrderCreateDialogWithSpecificChannel(channel: string) {
+ await this.expandChannelsSearchList();
+ await this.channelOption.filter({ hasText: channel }).first().click();
+ await this.clickConfirmButton();
+ }
}
diff --git a/playwright/pages/dialogs/issueGiftCardDialog.ts b/playwright/pages/dialogs/issueGiftCardDialog.ts
index 35ef094a112..f2974e63f19 100644
--- a/playwright/pages/dialogs/issueGiftCardDialog.ts
+++ b/playwright/pages/dialogs/issueGiftCardDialog.ts
@@ -12,17 +12,19 @@ export class IssueGiftCardDialog extends BasePage {
readonly giftCardExpireFields = page.getByTestId("gift-card-expire-data-fields"),
readonly sendToCustomerCheckbox = page
.getByTestId("send-to-customer-section")
- .locator('input[type="checkbox"]'),
- readonly sendExpireDateCheckbox = page.getByTestId("expiry-section").locator("input"),
+ .locator('button[role="checkbox"]'),
+ readonly sendExpireDateCheckbox = page.getByTestId("expiry-section").locator("button"),
readonly customerInput = page.getByTestId("customer-field"),
- readonly noteTextArea = page.getByTestId("note-field").locator('[name="note"]'),
+ readonly noteTextArea = page.getByTestId("note-field"),
readonly requiresActivationCheckbox = page
.getByTestId("requires-activation-section")
- .locator("input"),
+ .locator('button[role="checkbox"]'),
readonly issueButton = page.getByTestId("submit"),
readonly okButton = page.getByTestId("submit"),
readonly copyCodeButton = page.getByTestId("copy-code-button"),
readonly option = page.getByTestId("select-option"),
+ readonly issueGiftCardDialog = page.getByTestId("gift-card-dialog"),
+ readonly amountDropdown = page.locator('div[name="balanceCurrency"]'),
) {
super(page);
}
@@ -57,6 +59,7 @@ export class IssueGiftCardDialog extends BasePage {
async typeCustomTag(tag: string) {
await this.tagsInput.fill(tag);
+ await expect(this.issueGiftCardDialog.getByText("Loading...")).not.toBeVisible();
await this.tagsInputOptions.filter({ hasText: `Add new value: ${tag}` }).click();
}
@@ -94,4 +97,8 @@ export class IssueGiftCardDialog extends BasePage {
return allTexts[0];
}
+
+ async tagsInputBlur() {
+ await this.tagsInput.blur();
+ }
}
diff --git a/playwright/pages/dialogs/orderCreateDialog.ts b/playwright/pages/dialogs/orderCreateDialog.ts
index 6591136a7d8..fb10c11d392 100644
--- a/playwright/pages/dialogs/orderCreateDialog.ts
+++ b/playwright/pages/dialogs/orderCreateDialog.ts
@@ -7,7 +7,7 @@ export class OrderCreateDialog {
page: Page,
readonly channelNameInput = page.getByTestId("channel-autocomplete"),
readonly confirmButton = page.getByTestId("submit"),
- readonly channelOption = page.locator("[data-test-id*='select-field-option']"),
+ readonly channelOption = page.getByTestId("select-option"),
) {
this.page = page;
}
diff --git a/playwright/pages/dialogs/productCreateDialog.ts b/playwright/pages/dialogs/productCreateDialog.ts
index e77e798d3db..5c7c6479549 100644
--- a/playwright/pages/dialogs/productCreateDialog.ts
+++ b/playwright/pages/dialogs/productCreateDialog.ts
@@ -14,7 +14,7 @@ export class ProductCreateDialog extends BasePage {
}
async selectProductTypeWithVariants(productType = "Beer") {
- await this.waitForNetworkIdleAfterAction(() => this.dialogProductTypeInput.fill(productType));
+ await this.dialogProductTypeInput.fill(productType);
await this.promptedOptions.filter({ hasText: productType }).waitFor({ state: "attached" });
await this.promptedOptions.filter({ hasText: productType }).click();
}
diff --git a/playwright/pages/dialogs/promotionRuleDialog.ts b/playwright/pages/dialogs/promotionRuleDialog.ts
index eadb674d89b..05b36a99247 100644
--- a/playwright/pages/dialogs/promotionRuleDialog.ts
+++ b/playwright/pages/dialogs/promotionRuleDialog.ts
@@ -86,7 +86,6 @@ export class PromotionRuleDialog {
}
async selectPredicate(predicate: string, index = 0) {
- await this.page.getByTestId(`condition-name-${index}`).click();
await this.page.getByRole("option", { name: predicate, exact: true }).click();
}
diff --git a/playwright/pages/dialogs/resendGiftCardCodeDialog.ts b/playwright/pages/dialogs/resendGiftCardCodeDialog.ts
index dff92b0318f..23937f4cb46 100644
--- a/playwright/pages/dialogs/resendGiftCardCodeDialog.ts
+++ b/playwright/pages/dialogs/resendGiftCardCodeDialog.ts
@@ -10,6 +10,10 @@ export class ResendGiftCardCodeDialog {
this.page = page;
}
+ async blur() {
+ await this.page.keyboard.press("Tab");
+ }
+
async clickResendButton() {
await this.resendButton.click();
await this.resendButton.waitFor({ state: "hidden" });
diff --git a/playwright/pages/dialogs/shippingMethodDialog.ts b/playwright/pages/dialogs/shippingMethodDialog.ts
index 0a8e7c76cfd..3601a5be518 100644
--- a/playwright/pages/dialogs/shippingMethodDialog.ts
+++ b/playwright/pages/dialogs/shippingMethodDialog.ts
@@ -4,10 +4,10 @@ import { expect, Page } from "@playwright/test";
export class ShippingAddressDialog extends BasePage {
constructor(
page: Page,
- readonly selectShippingMethodInput = page.locator('[id="mui-component-select-shippingMethod"]'),
+ readonly selectShippingMethodInput = page.getByTestId("shipping-method-select"),
readonly confirmButton = page.getByTestId("confirm-button"),
readonly backButton = page.getByTestId("back"),
- readonly shippingMethodOption = page.locator("[data-test-id*='select-field-option']"),
+ readonly shippingMethodOption = page.getByTestId("select-option"),
) {
super(page);
}
diff --git a/playwright/pages/draftOrdersPage.ts b/playwright/pages/draftOrdersPage.ts
index d86d9cfddb5..2b139d32bea 100644
--- a/playwright/pages/draftOrdersPage.ts
+++ b/playwright/pages/draftOrdersPage.ts
@@ -30,6 +30,7 @@ export class DraftOrdersPage extends BasePage {
readonly addProducts = page.getByTestId("add-products-button"),
readonly finalizeButton = page.getByTestId("button-bar-confirm"),
readonly addShippingCarrierLink = page.getByTestId("add-shipping-carrier"),
+ readonly basketProductList = page.getByTestId("list"),
) {
super(page);
this.page = page;
@@ -59,7 +60,9 @@ export class DraftOrdersPage extends BasePage {
}
async clickAddShippingCarrierButton() {
+ await this.addShippingCarrierLink.scrollIntoViewIfNeeded();
await this.addShippingCarrierLink.click();
+
await this.waitForDOMToFullyLoad();
}
diff --git a/playwright/pages/giftCardsPage.ts b/playwright/pages/giftCardsPage.ts
index 96f6b558b7a..04e5e8e192e 100644
--- a/playwright/pages/giftCardsPage.ts
+++ b/playwright/pages/giftCardsPage.ts
@@ -30,10 +30,13 @@ export class GiftCardsPage extends BasePage {
readonly resendCodeButton = page.getByTestId("resend-code"),
readonly deactivateButton = page.getByTestId("enable-button"),
readonly saveButton = page.getByTestId("button-bar-confirm"),
- readonly cardExpiresCheckboxOnModal = page.getByTestId("expiry-section").locator("input"),
+ readonly giftCardsCanvas = page.locator('[data-testid="data-grid-canvas"]'),
+ readonly cardExpiresCheckboxOnModal = page
+ .getByTestId("expiry-section")
+ .locator('button[role="checkbox"]'),
readonly giftCardExpiresCheckbox = page
.getByTestId("gift-card-expire-section")
- .locator("input"),
+ .locator("button"),
readonly exportCardCodesButton = page.getByTestId("exportCodesMenuItem"),
readonly setBalanceButton = page.getByTestId("set-balance-button"),
readonly showMoreMenuButton = page.getByTestId("show-more-button"),
@@ -41,6 +44,8 @@ export class GiftCardsPage extends BasePage {
readonly exportGiftCardsBanner = page.getByText(
"We are currently exporting your gift card codes. As soon as your file is available it will be sent to your email address",
),
+ readonly tagsInput = page.getByTestId("gift-card-tag-select-field"),
+ readonly tagsInputOptions = page.locator('[data-test-id*="select-option"]'),
) {
super(page);
this.page = page;
@@ -53,7 +58,8 @@ export class GiftCardsPage extends BasePage {
}
async clickIssueCardButton() {
- await this.waitForNetworkIdleAfterAction(async () => await this.issueCardButton.click());
+ await this.issueCardButton.waitFor({ state: "visible" });
+ await this.issueCardButton.click();
await this.giftCardDialog.waitFor({ state: "visible" });
await this.cardExpiresCheckboxOnModal.waitFor({ state: "visible" });
await expect(this.cardExpiresCheckboxOnModal).toBeEnabled();
@@ -95,11 +101,21 @@ export class GiftCardsPage extends BasePage {
await this.showMoreMenuButton.click();
}
+ async openTagInput() {
+ await this.tagsInput.click();
+ }
+
+ async closeTagInput() {
+ await this.tagsInput.blur();
+ }
+
+ async selectFirstTag() {
+ await this.tagsInputOptions.first().click();
+ }
+
async gotoGiftCardsListView() {
- await this.waitForNetworkIdleAfterAction(async () => {
- await this.page.goto(URL_LIST.giftCards);
- });
- await this.waitForDOMToFullyLoad();
+ await this.page.goto(URL_LIST.giftCards);
+ await this.giftCardsCanvas.waitFor({ state: "visible" });
}
async gotoExistingGiftCardView(giftCardId: string) {
diff --git a/playwright/pages/homePage.ts b/playwright/pages/homePage.ts
index 84f7c03254e..7465d2849b2 100644
--- a/playwright/pages/homePage.ts
+++ b/playwright/pages/homePage.ts
@@ -7,12 +7,11 @@ export class HomePage {
constructor(
page: Page,
readonly channelSelect = page.getByTestId("app-channel-select"),
- readonly channelOptions = page.locator("[data-test-id*='select-field-option']"),
+ readonly channelOptions = page.getByTestId("select-option"),
readonly welcomeMessage = page.getByTestId("home-header"),
readonly sales = page.getByTestId("sales-analytics"),
readonly orders = page.getByTestId("orders-analytics"),
readonly activity = page.getByTestId("activity-card"),
- readonly topProducts = page.getByTestId("top-products"),
readonly ordersReadyToFulfill = page.getByTestId("orders-to-fulfill"),
readonly paymentsWaitingForCapture = page.getByTestId("orders-to-capture"),
readonly productsOutOfStock = page.getByTestId("out-of-stock-analytics"),
@@ -35,7 +34,6 @@ export class HomePage {
async expectHomePageElementsToBeVisible() {
await expect(this.sales).toBeVisible();
await expect(this.activity).toBeVisible();
- await expect(this.topProducts).toBeVisible();
await expect(this.productsOutOfStock).toBeVisible();
}
}
diff --git a/playwright/pages/loginPage.ts b/playwright/pages/loginPage.ts
index b920e3db512..493a5566ca1 100644
--- a/playwright/pages/loginPage.ts
+++ b/playwright/pages/loginPage.ts
@@ -36,7 +36,8 @@ export class LoginPage {
await this.typeEmail(userEmail);
await this.typePassword(userPassword);
await this.clickSignInButton();
- await expect(this.homePage.welcomeMessage).toContainText("Hello there,", {
+ // This check shouldn't be tied to user's email or first/last name
+ await expect(this.homePage.welcomeMessage).toContainText("welcome to your Store Dashboard", {
timeout: 15000,
});
}
diff --git a/playwright/pages/ordersPage.ts b/playwright/pages/ordersPage.ts
index 8f9ec7a8d8e..261da28254a 100644
--- a/playwright/pages/ordersPage.ts
+++ b/playwright/pages/ordersPage.ts
@@ -56,7 +56,14 @@ export class OrdersPage extends BasePage {
readonly orderRefundModal = page.getByTestId("order-refund-dialog"),
readonly orderRefundSection = page.getByTestId("order-refund-section"),
readonly orderRefundList = page.getByTestId("refund-list"),
- readonly editRefundButton = page.getByTestId("edit-refund-button"),
+ readonly orderSummary = page.getByTestId("order-summary"),
+ readonly editRefundButton = page.getByTestId("edit-refund-button").locator("button"),
+ readonly totalPrice = page
+ .getByTestId("order-total-price")
+ .locator(page.getByTestId("money-value")),
+ readonly subTotalPrice = page
+ .getByTestId("order-total-price")
+ .locator(page.getByTestId("money-value")),
) {
super(page);
this.markOrderAsPaidDialog = new MarkOrderAsPaidDialog(page);
@@ -75,6 +82,11 @@ export class OrdersPage extends BasePage {
await this.createOrderButton.click();
}
+ async goToDraftOrdersListView() {
+ await this.page.goto(URL_LIST.draftOrders);
+ await this.waitForGrid();
+ }
+
async clickAddTrackingButton() {
await this.addTrackingButton.click();
}
@@ -111,9 +123,11 @@ export class OrdersPage extends BasePage {
async goToExistingOrderPage(orderId: string) {
const orderLink = URL_LIST.orders + orderId;
- await console.log("Navigating to order details view: " + orderLink);
+ console.log("Navigating to order details view: " + orderLink);
await this.page.goto(orderLink);
await this.waitForDOMToFullyLoad();
+ await this.waitForGrid();
+ await this.waitForGrid();
}
async clickAddRefundButton() {
@@ -122,14 +136,14 @@ export class OrdersPage extends BasePage {
}
async clickEditRefundButton(refundInfo: string) {
- const refund = await this.orderRefundList.locator("tr").filter({ hasText: refundInfo });
+ const refund = this.orderRefundList.locator("tr").filter({ hasText: refundInfo });
await refund.locator(this.editRefundButton).click();
await this.waitForDOMToFullyLoad();
}
async assertRefundOnList(refundInfo: string) {
- const refund = await this.orderRefundList.locator("tr").filter({ hasText: refundInfo });
+ const refund = this.orderRefundList.locator("tr").filter({ hasText: refundInfo });
await refund.waitFor({ state: "visible" });
}
diff --git a/playwright/pages/pageElements/rightSideDetailsSection.ts b/playwright/pages/pageElements/rightSideDetailsSection.ts
index e00bce293b5..83a958d1bdd 100644
--- a/playwright/pages/pageElements/rightSideDetailsSection.ts
+++ b/playwright/pages/pageElements/rightSideDetailsSection.ts
@@ -72,7 +72,9 @@ export class RightSideDetailsPage extends BasePage {
async expectOptionsSelected(section: Locator, names: string[]) {
for (const name of names) {
- await expect(section.getByText(name)).toBeVisible({ timeout: 30000 });
+ await expect(section.getByText(name)).toBeVisible({
+ timeout: 30 * 1000, // 30 seconds
+ });
}
}
@@ -183,6 +185,11 @@ export class RightSideDetailsPage extends BasePage {
await this.waitForDOMToFullyLoad();
}
+ async typeAndSelectCustomerEmail(customerEmail = "customer@example.com") {
+ await this.searchCustomerInput.fill(customerEmail);
+ await this.selectCustomerOption.locator(`text=${customerEmail}`).click();
+ }
+
async selectOneChannelAsAvailableWhenMoreSelected(channel: string) {
await this.manageChannelsButton.click();
await this.channelSelectDialog.clickAllChannelsCheckbox();
diff --git a/playwright/pages/productPage.ts b/playwright/pages/productPage.ts
index c3e01470e59..2c5ba9fe0c3 100644
--- a/playwright/pages/productPage.ts
+++ b/playwright/pages/productPage.ts
@@ -20,8 +20,6 @@ export class ProductPage extends BasePage {
readonly rightSideDetailsPage: RightSideDetailsPage;
- readonly basePage: BasePage;
-
readonly channelSelectDialog: ChannelSelectDialog;
readonly deleteProductDialog: DeleteDialog;
@@ -72,13 +70,12 @@ export class ProductPage extends BasePage {
readonly ratingInput = page.locator("[name='rating']"),
readonly warehouseOption = page.locator("[role='menuitem']"),
readonly costPriceInput = page.locator("[name*='costPrice']"),
- readonly sellingPriceInput = page.locator("[name*='channel-price']"),
+ readonly sellingPriceInput = page.locator("[name*='channelListing-price']"),
readonly firstRowDataGrid = page.locator("[data-testid='glide-cell-1-0']"),
readonly searchInput = page.getByTestId("search-input"),
readonly emptyDataGridListView = page.getByTestId("empty-data-grid-text"),
) {
super(page);
- this.basePage = new BasePage(page);
this.exportProductsDialog = new ExportProductsDialog(page);
this.deleteProductDialog = new DeleteDialog(page);
this.channelSelectDialog = new ChannelSelectDialog(page);
@@ -136,7 +133,7 @@ export class ProductPage extends BasePage {
}
async clickBulkDeleteButton() {
- await this.bulkDeleteButton.click();
+ await this.submitButton.click();
}
async addSeo() {
@@ -189,10 +186,6 @@ export class ProductPage extends BasePage {
await this.saveButton.click();
}
- async expectSuccessBanner() {
- await this.basePage.expectSuccessBanner();
- }
-
async clickCreateProductButton() {
await this.createProductButton.click();
}
@@ -211,7 +204,7 @@ export class ProductPage extends BasePage {
async gotoProductListPage() {
await this.page.goto(URL_LIST.products);
- await this.waitForDOMToFullyLoad();
+ await this.waitForGrid();
}
async uploadProductImage(fileName: string) {
diff --git a/playwright/pages/productTypePage.ts b/playwright/pages/productTypePage.ts
index 7eca628ff20..6d9aa8f60ad 100644
--- a/playwright/pages/productTypePage.ts
+++ b/playwright/pages/productTypePage.ts
@@ -4,10 +4,6 @@ import { DeleteDialog } from "@pages/dialogs/deleteDialog";
import type { Page } from "@playwright/test";
export class ProductTypePage extends BasePage {
- readonly page: Page;
-
- readonly basePage: BasePage;
-
readonly deleteProductTypeDialog: DeleteDialog;
constructor(
@@ -27,8 +23,6 @@ export class ProductTypePage extends BasePage {
readonly rowCheckbox = page.getByTestId("checkbox"),
) {
super(page);
- this.page = page;
- this.basePage = new BasePage(page);
this.deleteProductTypeDialog = new DeleteDialog(page);
}
@@ -59,10 +53,6 @@ export class ProductTypePage extends BasePage {
await this.page.goto(URL_LIST.productTypesAdd);
}
- async expectSuccessBanner() {
- await this.basePage.expectSuccessBanner();
- }
-
async gotoProductTypeListPage() {
await this.page.goto(URL_LIST.productTypes);
}
diff --git a/playwright/pages/refundPage.ts b/playwright/pages/refundPage.ts
index 0184f0dd73f..61b357b623c 100644
--- a/playwright/pages/refundPage.ts
+++ b/playwright/pages/refundPage.ts
@@ -27,7 +27,7 @@ export class RefundPage extends OrdersPage {
return await this.page.locator("table tr").filter({ hasText: productName });
}
- async expectLineItemsRefundPageOpen(orderId: string) {
+ async expectAddLineItemsRefundPageOpen(orderId: string) {
const orderLink = `${URL_LIST.orders}${orderId}/refund`;
await expect(this.page).toHaveURL(orderLink);
@@ -35,6 +35,14 @@ export class RefundPage extends OrdersPage {
await expect(this.pageHeader).toContainText("Create refund with line items");
}
+ async expectEditLineItemsRefundPageOpen(orderId: string, refundId: string) {
+ const orderLink = `${URL_LIST.orders}${orderId}/refund/${refundId}`;
+
+ await expect(this.page).toHaveURL(orderLink);
+ await this.waitForDOMToFullyLoad();
+ await expect(this.pageHeader).toContainText("Create refund with line items");
+ }
+
async expectManualRefundPageOpen(orderId: string) {
const orderLink = `${URL_LIST.orders}${orderId}/manual-refund`;
diff --git a/playwright/pages/setUpNewPasswordPage.ts b/playwright/pages/setUpNewPasswordPage.ts
deleted file mode 100644
index 41402c4c413..00000000000
--- a/playwright/pages/setUpNewPasswordPage.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { MailpitService } from "@api/mailpit";
-import type { APIRequestContext, Page } from "@playwright/test";
-
-export class SetUpNewPasswordPage {
- readonly page: Page;
-
- readonly mailpitService: MailpitService;
-
- constructor(
- page: Page,
- request: APIRequestContext,
- readonly passwordInput = page.getByTestId("password"),
- readonly confirmPasswordInput = page.getByTestId("confirm-password"),
- readonly setNewPasswordButton = page.getByTestId("button-bar-confirm"),
- ) {
- this.page = page;
- this.mailpitService = new MailpitService(request);
- }
-
- async typePassword(password: string) {
- await this.passwordInput.fill(password);
- }
-
- async typeConfirmedPassword(password: string) {
- await this.confirmPasswordInput.fill(password);
- }
-
- async clickSetNewPasswordButton() {
- await this.setNewPasswordButton.click();
- }
-
- async gotoUserResetPasswordPage(userEmail: string) {
- const resetPasswordPageUrl = await this.mailpitService.generateResetPasswordUrl(userEmail);
-
- await this.page.goto(resetPasswordPageUrl);
- }
-}
diff --git a/playwright/pages/shippingMethodsPage.ts b/playwright/pages/shippingMethodsPage.ts
index 703bc5a0e6e..3159209c6e3 100644
--- a/playwright/pages/shippingMethodsPage.ts
+++ b/playwright/pages/shippingMethodsPage.ts
@@ -71,22 +71,15 @@ export class ShippingMethodsPage extends BasePage {
});
}
- async gotoExistingShippingMethod(shippingMethodId: string) {
+ async gotoExistingShippingMethod(shippingMethodId: string, shippingMethodName: string) {
const existingShippingMethodUrl = `${URL_LIST.shippingMethods}${shippingMethodId}`;
await console.log(`Navigates to existing shipping method page: ${existingShippingMethodUrl}`);
await this.page.goto(existingShippingMethodUrl);
-
- const channels = await this.rightSideDetailsPage.channelSection
- .locator('[data-test-id*="selected-option-"]')
- .all();
-
- for (const channel of channels) {
- await channel.waitFor({
- state: "visible",
- timeout: 60000,
- });
- }
+ await this.page.getByText(shippingMethodName).first().waitFor({
+ state: "visible",
+ timeout: 60000,
+ });
}
async gotoExistingShippingRate(shippingMethodId: string, shippingRateId: string) {
diff --git a/playwright/pages/siteSettingsPage.ts b/playwright/pages/siteSettingsPage.ts
index 50e58082eb6..79a29699f46 100644
--- a/playwright/pages/siteSettingsPage.ts
+++ b/playwright/pages/siteSettingsPage.ts
@@ -17,7 +17,12 @@ export class SiteSettingsPage extends BasePage {
readonly addressLine2Input = page.getByTestId("company-address-line-2-input").locator("input"),
readonly city = page.getByTestId("company-city-input").locator("input"),
readonly countryInput = page.getByTestId("address-edit-country-select-field"),
- readonly autocompleteDropdown = page.getByTestId("autocomplete-dropdown"),
+ readonly autocompleteDropdownCountry = page.locator(
+ '[data-portal-for="autocomplete-dropdown-country"]',
+ ),
+ readonly autocompleteDropdownCountryArea = page.locator(
+ '[data-portal-for="autocomplete-dropdown-country-area"]',
+ ),
readonly countryAreaDropdown = page.getByTestId("address-edit-country-area-field"),
readonly zipInput = page.getByTestId("company-zip-input").locator("input"),
readonly phoneInput = page.getByTestId("company-phone-input").locator("input"),
@@ -58,9 +63,11 @@ export class SiteSettingsPage extends BasePage {
await this.addressLine2Input.fill(addressLine2);
await this.city.fill(city);
await this.countryInput.click();
- await this.autocompleteDropdown.getByText(country, { exact: true }).click();
+ await this.autocompleteDropdownCountry.getByText(country, { exact: true }).click();
+ await this.autocompleteDropdownCountry.blur();
await this.countryAreaDropdown.fill(countryArea);
- await this.autocompleteDropdown.getByText(countryArea, { exact: true }).click();
+ await this.autocompleteDropdownCountryArea.getByText(countryArea, { exact: true }).click();
+ await this.autocompleteDropdownCountryArea.blur();
await this.zipInput.fill(zip);
await this.phoneInput.fill(phone);
}
diff --git a/playwright/pages/staffMembersPage.ts b/playwright/pages/staffMembersPage.ts
index 7af5036f8cc..9b4457f24e4 100644
--- a/playwright/pages/staffMembersPage.ts
+++ b/playwright/pages/staffMembersPage.ts
@@ -1,4 +1,3 @@
-import { MailpitService } from "@api/mailpit";
import { URL_LIST } from "@data/url";
import { BasePage } from "@pages/basePage";
import { InviteStaffMembersDialog } from "@pages/dialogs/inviteStaffMemberDialog";
@@ -10,8 +9,6 @@ export class StaffMembersPage extends BasePage {
readonly basePage: BasePage;
- readonly mailpitService: MailpitService;
-
readonly inviteStaffMembersDialog: InviteStaffMembersDialog;
constructor(
@@ -30,7 +27,6 @@ export class StaffMembersPage extends BasePage {
super(page);
this.request = request;
this.basePage = new BasePage(page);
- this.mailpitService = new MailpitService(request);
this.inviteStaffMembersDialog = new InviteStaffMembersDialog(page);
}
diff --git a/playwright/pages/taxesPage.ts b/playwright/pages/taxesPage.ts
index 701e83f8be5..0b67c15aa5e 100644
--- a/playwright/pages/taxesPage.ts
+++ b/playwright/pages/taxesPage.ts
@@ -14,7 +14,7 @@ export class TaxesPage extends BasePage {
constructor(
page: Page,
- readonly appOrFlatRateSelect = page.getByTestId("app-flat-select").locator("[role='button']"),
+ readonly appOrFlatRateSelect = page.getByTestId("tax-calculation-strategy-select"),
readonly chanelListRow = page.getByTestId("channels-list-rows"),
readonly countriesListRow = page.getByTestId("countries-list-rows"),
readonly classListRow = page.getByTestId("class-list-rows"),
@@ -118,9 +118,9 @@ export class TaxesPage extends BasePage {
await this.createClassButton.click();
}
- async selectTaxCalculationMethod(method: "FLAT_RATES" | "saleor.app.dummy.tax") {
+ async selectTaxCalculationMethod(method: string) {
await this.clickSelectMethodField();
- await this.page.getByTestId(`select-field-option-${method}`).click();
+ await this.page.getByTestId("select-option").filter({ hasText: method }).first().click();
}
async selectPricesWithoutTaxes() {
diff --git a/playwright/pages/variantsPage.ts b/playwright/pages/variantsPage.ts
index 566a3b05dc7..f2aeb473d95 100644
--- a/playwright/pages/variantsPage.ts
+++ b/playwright/pages/variantsPage.ts
@@ -5,15 +5,11 @@ import { MetadataSeoPage } from "@pageElements/metadataSeoPage";
import { BasePage } from "@pages/basePage";
import type { Page } from "@playwright/test";
-export class VariantsPage {
- readonly page: Page;
-
+export class VariantsPage extends BasePage {
channelSelectDialog: ChannelSelectDialog;
metadataSeoPage: MetadataSeoPage;
- basePage: BasePage;
-
deleteVariantDialog: DeleteVariantDialog;
constructor(
@@ -40,8 +36,7 @@ export class VariantsPage {
readonly manageChannels = page.getByTestId("manage-channels-button"),
readonly allChannels = page.locator("[name='allChannels']"),
) {
- this.page = page;
- this.basePage = new BasePage(page);
+ super(page);
this.metadataSeoPage = new MetadataSeoPage(page);
this.channelSelectDialog = new ChannelSelectDialog(page);
this.deleteVariantDialog = new DeleteVariantDialog(page);
@@ -111,10 +106,6 @@ export class VariantsPage {
await this.saveButton.click();
}
- async expectSuccessBanner() {
- await this.basePage.expectSuccessBanner();
- }
-
async selectFirstAttributeValue() {
await this.attributeSelector.click();
await this.attributeOption.first().click();
@@ -122,7 +113,6 @@ export class VariantsPage {
async selectLastAttributeValue() {
await this.attributeSelector.locator("input").clear();
- await this.attributeSelector.click();
await this.attributeOption.last().click();
}
diff --git a/playwright/tests/apps.spec.ts b/playwright/tests/apps.spec.ts
index 367e387bb37..50b383ff36e 100644
--- a/playwright/tests/apps.spec.ts
+++ b/playwright/tests/apps.spec.ts
@@ -2,9 +2,10 @@ import { APPS } from "@data/e2eTestData";
import { AppInstallationPage } from "@pages/appInstallationPage";
import { AppPage } from "@pages/appPageThirdparty";
import { AppsPage } from "@pages/appsPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let appsPage: AppsPage;
let installationPage: AppInstallationPage;
@@ -15,41 +16,47 @@ test.beforeEach(({ page }) => {
installationPage = new AppInstallationPage(page);
appPage = new AppPage(page);
});
-// Adding temporary skip https://linear.app/saleor/issue/QAG-94/remove-skip-from-app-tests
-test.skip("TC: SALEOR_119 User should be able to install and configure app from manifest @e2e", async ({
+
+const PRE_INSTALLATION_TIMEOUT = 20 * 1000;
+const INSTALLATION_PENDING_TIMEOUT = 50 * 1000;
+const APP_EXPECT_UI_TIMEOUT = 15 * 1000;
+
+test("TC: SALEOR_119 User should be able to install and configure app from manifest #e2e", async ({
page,
}) => {
await appsPage.gotoAppsList();
- await appsPage.waitForDOMToFullyLoad();
- await expect(appsPage.installExternalAppButton).toBeVisible();
await appsPage.installExternalAppButton.click();
await appsPage.typeManifestUrl("https://klaviyo.saleor.app/api/manifest");
await appsPage.installAppFromManifestButton.click();
await expect(installationPage.appInstallationPageHeader).toHaveText(
"You are about to install Klaviyo",
+ {
+ // Klaviyo app can take a while to respond with manifest if it's
+ // cold-starting
+ timeout: PRE_INSTALLATION_TIMEOUT,
+ },
);
await installationPage.installAppButton.click();
- await appsPage.expectSuccessBanner();
+
+ await appsPage.expectSuccessBanner({ timeout: INSTALLATION_PENDING_TIMEOUT });
await expect(appsPage.installedAppRow.first()).toBeVisible();
- await appsPage.installationPendingLabel.waitFor({
- state: "hidden",
- timeout: 50000,
- });
+ await expect(appsPage.installationPendingLabel).not.toBeVisible();
+
await expect(appsPage.appKlaviyo).toContainText("Klaviyo");
- await appsPage.installedAppRow
- .filter({ hasText: "Klaviyo" })
- .first()
- .waitFor({ state: "visible", timeout: 50000 });
+ await expect(appsPage.installedAppRow.filter({ hasText: "Klaviyo" }).first()).toBeVisible();
await appsPage.appKlaviyo.click();
const iframeLocator = page.frameLocator("iframe");
- await expect(iframeLocator.getByLabel("PUBLIC_TOKEN")).toBeVisible();
+ await expect(iframeLocator.getByLabel("PUBLIC_TOKEN")).toBeVisible({
+ // Klavyio's UI can take a while to load initially
+ timeout: APP_EXPECT_UI_TIMEOUT,
+ });
await iframeLocator.getByLabel("PUBLIC_TOKEN").fill("test_token");
await iframeLocator.getByText("Save").click();
- await appsPage.expectSuccessBanner();
+ await appsPage.expectSuccessBanner({ timeout: INSTALLATION_PENDING_TIMEOUT });
});
-test("TC: SALEOR_120 User should be able to delete thirdparty app @e2e", async () => {
+test("TC: SALEOR_120 User should be able to delete thirdparty app #e2e", async () => {
await appPage.waitForNetworkIdleAfterAction(() =>
appPage.goToExistingAppPage(APPS.appToBeDeleted.id),
);
diff --git a/playwright/tests/attributes.spec.ts b/playwright/tests/attributes.spec.ts
index 7544f77ef77..ab5622bf487 100644
--- a/playwright/tests/attributes.spec.ts
+++ b/playwright/tests/attributes.spec.ts
@@ -1,10 +1,11 @@
import { ATTRIBUTES } from "@data/e2eTestData";
import { AttributesPage } from "@pages/attributesPage";
import { ConfigurationPage } from "@pages/configurationPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
import faker from "faker";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let attributesPage: AttributesPage;
let configurationPage: ConfigurationPage;
@@ -19,9 +20,9 @@ const attributeClasses = ["PRODUCT_TYPE", "PAGE_TYPE"];
for (const attr of attributeClasses) {
for (const type of ATTRIBUTES.attributeTypesWithAbilityToAddValues.names) {
- const uniqueSlug = `${attr}-${type}-${SALEOR_124_uuid}`;
+ const uniqueSlug = `${attr}-${type}-${SALEOR_124_uuid}`.replace(/\s+/g, "-");
- test(`TC: SALEOR_124 User should be able to create ${attr} ${type} attribute with ability to add values, required, public @e2e @attributes`, async ({
+ test(`TC: SALEOR_124 User should be able to create ${attr} ${type} attribute with ability to add values, required, public #e2e #attributes`, async ({
page,
}) => {
await page.context().storageState({ path: "./playwright/.auth/admin.json" });
@@ -35,7 +36,7 @@ for (const attr of attributeClasses) {
await expect(attributesPage.attrValuesSection).toBeVisible();
await attributesPage.clickAssignAttributeValueButton();
await attributesPage.addValueDialog.typeAndSaveAttributeValue();
- await attributesPage.waitForNetworkIdleAfterAction(() => attributesPage.clickSaveButton());
+ await attributesPage.clickSaveButton();
await attributesPage.expectSuccessBanner();
await expect(await attributesPage.attributesRows.count()).toEqual(1);
await attributesPage.valueRequiredCheckbox.waitFor({
@@ -53,9 +54,9 @@ const SALEOR_125_uuid = faker.datatype.uuid();
for (const attr of attributeClasses) {
for (const type of ATTRIBUTES.attributeTypesWithoutAbilityToAddValues.names) {
- const uniqueSlug = `${attr}-${type}-${SALEOR_125_uuid}`;
+ const uniqueSlug = `${attr}-${type}-${SALEOR_125_uuid}`.replace(/\s+/g, "-");
- test(`TC: SALEOR_125 User should be able to create ${attr} ${type} attribute without ability to add values, NOT required, private @e2e @attributes`, async ({
+ test(`TC: SALEOR_125 User should be able to create ${attr} ${type} attribute without ability to add values, NOT required, private #e2e #attributes`, async ({
page,
}) => {
await page.context().storageState({ path: "./playwright/.auth/admin.json" });
@@ -71,7 +72,7 @@ for (const attr of attributeClasses) {
await expect(attributesPage.assignAttributeValueButton).not.toBeVisible();
await attributesPage.clickValueRequiredCheckbox();
await attributesPage.changeAttributeVisibility();
- await attributesPage.waitForNetworkIdleAfterAction(() => attributesPage.clickSaveButton());
+ await attributesPage.clickSaveButton();
await attributesPage.expectSuccessBanner();
await attributesPage.valueRequiredCheckbox.waitFor({
state: "visible",
@@ -88,9 +89,9 @@ const SALEOR_126_uuid = faker.datatype.uuid();
for (const attr of attributeClasses) {
for (const entity of ATTRIBUTES.attributeReferencesEntities.names) {
- const uniqueSlug = `${attr}-${entity}-${SALEOR_126_uuid}`;
+ const uniqueSlug = `${attr}-${entity}-${SALEOR_126_uuid}`.replace(/\s+/g, "-");
- test(`TC: SALEOR_126 User should be able to create ${attr} References attribute for ${entity}, NOT required, public @e2e @attributes`, async ({
+ test(`TC: SALEOR_126 User should be able to create ${attr} References attribute for ${entity}, NOT required, public #e2e #attributes`, async ({
page,
}) => {
await page.context().storageState({ path: "./playwright/.auth/admin.json" });
@@ -104,7 +105,7 @@ for (const attr of attributeClasses) {
await attributesPage.selectAttributeInputType("REFERENCE");
await attributesPage.selectAttributeEntityType(entity);
await attributesPage.clickValueRequiredCheckbox();
- await attributesPage.waitForNetworkIdleAfterAction(() => attributesPage.clickSaveButton());
+ await attributesPage.clickSaveButton();
await attributesPage.expectSuccessBanner();
await attributesPage.valueRequiredCheckbox.waitFor({
state: "visible",
@@ -132,10 +133,8 @@ const contentAttrWithValues = {
const attributesWithValuesToBeUpdated = [productAttrWithValues, contentAttrWithValues];
for (const attribute of attributesWithValuesToBeUpdated) {
- test(`TC: SALEOR_127 User should be able to update attribute values in existing ${attribute.name} attribute @e2e @attributes`, async () => {
- await attributesPage.waitForNetworkIdleAfterAction(() =>
- attributesPage.gotoExistingAttributePage(attribute.id, attribute.name),
- );
+ test(`TC: SALEOR_127 User should be able to update attribute values in existing ${attribute.name} attribute #e2e #attributes`, async () => {
+ await attributesPage.gotoExistingAttributePage(attribute.id, attribute.name);
await attributesPage.clickDeleteAttrValueButton(attribute.valueToBeDeleted);
await expect(attributesPage.dialog).toBeVisible();
await attributesPage.deleteAttributeValueDialog.deleteAttributeValue();
@@ -150,7 +149,7 @@ for (const attribute of attributesWithValuesToBeUpdated) {
`new value for ${attribute.name}`,
);
await attributesPage.expectSuccessBanner();
- await attributesPage.waitForNetworkIdleAfterAction(() => attributesPage.clickSaveButton());
+ await attributesPage.clickSaveButton();
await attributesPage.expectSuccessBanner();
await expect(attributesPage.attrValuesSection).not.toContainText(attribute.valueToBeDeleted);
await expect(attributesPage.attrValuesSection).toContainText(
@@ -161,21 +160,27 @@ for (const attribute of attributesWithValuesToBeUpdated) {
}
for (const attr of ATTRIBUTES.attributesToBeUpdated) {
- test(`TC: SALEOR_128 User should be able to edit existing ${attr.name} attribute @e2e @attributes`, async () => {
- await attributesPage.waitForNetworkIdleAfterAction(() =>
- attributesPage.gotoExistingAttributePage(attr.id, attr.name),
- );
- await attributesPage.attributeDefaultLabelInput.clear();
- await attributesPage.typeAttributeDefaultLabel(`updated ${attr.name}`);
+ test(`TC: SALEOR_128 User should be able to edit existing ${attr.name} attribute #e2e #attributes`, async () => {
+ await attributesPage.gotoExistingAttributePage(attr.id, attr.name);
+
+ await attributesPage.attributeDefaultLabelInput.fill(`updated ${attr.name}`);
+
await attributesPage.expandMetadataSection();
await attributesPage.metadataAddFieldButton.click();
+
await attributesPage.fillMetadataFields("new key", "new value");
- await attributesPage.waitForNetworkIdleAfterAction(() => attributesPage.clickSaveButton());
+ //Clicking tab only to change focus from the input, allowing to save metadata
+ await attributesPage.page.keyboard.press("Tab");
+
+ await attributesPage.clickSaveButton();
await attributesPage.expectSuccessBanner();
- await expect(attributesPage.attributeSelect.getByRole("button")).toHaveAttribute(
- "aria-disabled",
- "true",
- );
+ await attributesPage.expectElementIsHidden(attributesPage.successBanner);
+
+ await attributesPage.expandMetadataSection();
+
+ await expect(attributesPage.attributeSelect).toBeVisible();
+ await expect(attributesPage.attributeSelect).toHaveAttribute("aria-disabled", "true");
+ await expect(attributesPage.metadataKeyInput).toBeVisible();
await expect(attributesPage.metadataKeyInput).toHaveValue("new key");
await expect(attributesPage.metadataValueInput).toHaveValue("new value");
await expect(attributesPage.attributeDefaultLabelInput).toHaveValue(`updated ${attr.name}`);
@@ -193,31 +198,28 @@ const contentAttribute = {
const attributesToBeDeleted = [productAttribute, contentAttribute];
for (const attribute of attributesToBeDeleted) {
- test(`TC: SALEOR_129 Delete a single ${attribute.name} @e2e @attributes`, async () => {
+ test(`TC: SALEOR_129 Delete a single ${attribute.name} #e2e #attributes`, async () => {
await attributesPage.gotoExistingAttributePage(attribute.id, attribute.name);
await attributesPage.clickDeleteButton();
await attributesPage.dialog.waitFor({
state: "visible",
timeout: 10000,
});
- await attributesPage.waitForNetworkIdleAfterAction(() =>
- attributesPage.deleteAttributeDialog.deleteAttribute(),
- );
+ await attributesPage.deleteAttributeDialog.deleteAttribute();
+ await attributesPage.page.getByText("Attribute deleted").waitFor({ state: "visible" });
await attributesPage.waitForGrid();
await expect(attributesPage.gridCanvas).not.toContainText(attribute.name);
});
}
-test("TC: SALEOR_130 Bulk delete attributes @e2e @attributes", async () => {
+test("TC: SALEOR_130 Bulk delete attributes #e2e #attributes", async () => {
await attributesPage.gotoListView();
await attributesPage.searchAndFindRowIndexes("e2e attribute to be bulk deleted");
await attributesPage.clickGridCell(0, 0);
await attributesPage.clickGridCell(0, 1);
await attributesPage.clickGridCell(0, 2);
await attributesPage.clickBulkDeleteGridRowsButton();
- await attributesPage.waitForNetworkIdleAfterAction(() =>
- attributesPage.deleteAttributesInBulkDialog.deleteSelectedAttributes(),
- );
+ await attributesPage.deleteAttributesInBulkDialog.deleteSelectedAttributes();
await attributesPage.expectSuccessBanner();
await expect(attributesPage.emptyDataGridListView).toBeVisible();
});
diff --git a/playwright/tests/categories.spec.ts b/playwright/tests/categories.spec.ts
index 6a80660058a..6ce9f498b62 100644
--- a/playwright/tests/categories.spec.ts
+++ b/playwright/tests/categories.spec.ts
@@ -1,17 +1,18 @@
import { CATEGORIES } from "@data/e2eTestData";
import { CategoriesPage } from "@pages/categoriesPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let categoriesPage: CategoriesPage;
test.beforeEach(({ page }) => {
categoriesPage = new CategoriesPage(page);
});
-test("TC: SALEOR_102 Create basic category @e2e @category", async () => {
+test("TC: SALEOR_102 Create basic category #e2e #category", async () => {
await categoriesPage.gotoCategoryListView();
- await categoriesPage.waitForDOMToFullyLoad();
+ await categoriesPage.waitForDatagridLoaderToDisappear();
await categoriesPage.clickCreateNewCategoryButton();
await categoriesPage.typeCategoryName("Utils");
await categoriesPage.typeCategoryDescription("Utils description");
@@ -20,7 +21,7 @@ test("TC: SALEOR_102 Create basic category @e2e @category", async () => {
await categoriesPage.clickSaveButton();
await categoriesPage.expectSuccessBanner();
});
-test("TC: SALEOR_103 Edit category @e2e @category", async () => {
+test("TC: SALEOR_103 Edit category #e2e #category", async () => {
await categoriesPage.gotoExistingCategoriesPage(CATEGORIES.categoryToBeUpdated.id);
await categoriesPage.typeCategoryName("Updated category");
await categoriesPage.typeCategoryDescription("Utils description updated");
@@ -29,7 +30,7 @@ test("TC: SALEOR_103 Edit category @e2e @category", async () => {
await categoriesPage.expectSuccessBanner();
await expect(categoriesPage.productsGridList).toContainText("beer to be updated");
});
-test("TC: SALEOR_104 Bulk delete categories @e2e @category", async () => {
+test("TC: SALEOR_104 Bulk delete categories #e2e #category", async () => {
await categoriesPage.gotoCategoryListView();
await categoriesPage.waitForDOMToFullyLoad();
await categoriesPage.checkListRowsBasedOnContainingText(
diff --git a/playwright/tests/channels.spec.ts b/playwright/tests/channels.spec.ts
index 727d68db732..17285ccc636 100644
--- a/playwright/tests/channels.spec.ts
+++ b/playwright/tests/channels.spec.ts
@@ -1,9 +1,10 @@
import { CHANNELS } from "@data/e2eTestData";
import { ChannelPage } from "@pages/channelsPage";
import { ConfigurationPage } from "@pages/configurationPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json", locale: "en" });
+test.use({ permissionName: "admin" });
let configurationPage: ConfigurationPage;
let channelPage: ChannelPage;
@@ -12,7 +13,7 @@ test.beforeEach(({ page }) => {
configurationPage = new ConfigurationPage(page);
channelPage = new ChannelPage(page);
});
-test("TC: SALEOR_97 Create basic channel @e2e @channels", async () => {
+test("TC: SALEOR_97 Create basic channel #e2e #channels", async () => {
const slugName = new Date().toISOString();
await configurationPage.goToConfigurationView();
@@ -26,7 +27,7 @@ test("TC: SALEOR_97 Create basic channel @e2e @channels", async () => {
await channelPage.expectSuccessBanner();
});
-test("TC: SALEOR_208 Create channel with all settings @e2e @channels", async () => {
+test("TC: SALEOR_208 Create channel with all settings #e2e #channels", async () => {
const slugName = new Date().toISOString();
await configurationPage.goToConfigurationView();
@@ -53,7 +54,7 @@ test("TC: SALEOR_208 Create channel with all settings @e2e @channels", async ()
await expect(channelPage.allowUnpaidOrdersCheckbox).toBeChecked();
});
-test("TC: SALEOR_98 Edit channel - transaction flow, allow unpaid, authorize, prio high stock @e2e @channels", async () => {
+test("TC: SALEOR_98 Edit channel - transaction flow, allow unpaid, authorize, prio high stock #e2e #channels", async () => {
await channelPage.gotoChannelDetails(CHANNELS.channelToBeEditedSettings.id);
await channelPage.clickTransactionFlowCheckbox();
await channelPage.clickAllowUnpaidOrdersCheckbox();
@@ -65,7 +66,7 @@ test("TC: SALEOR_98 Edit channel - transaction flow, allow unpaid, authorize, pr
await channelPage.clickSaveButton();
await channelPage.expectSuccessBanner();
});
-test("TC: SALEOR_99 Delete channel @e2e @channels", async () => {
+test("TC: SALEOR_99 Delete channel #e2e #channels", async () => {
await channelPage.gotoChannelList();
await channelPage.clickDeleteButtonOnRowContainingChannelName(CHANNELS.channelToBeDeleted.name);
await channelPage.deleteChannelDialog.clickDeleteButton();
diff --git a/playwright/tests/collections.spec.ts b/playwright/tests/collections.spec.ts
index dfc8b404284..6f643d8dea4 100644
--- a/playwright/tests/collections.spec.ts
+++ b/playwright/tests/collections.spec.ts
@@ -1,15 +1,16 @@
import { COLLECTIONS } from "@data/e2eTestData";
import { CollectionsPage } from "@pages/collectionsPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let collectionsPage: CollectionsPage;
test.beforeEach(({ page }) => {
collectionsPage = new CollectionsPage(page);
});
-test("TC: SALEOR_112 Create collection @collections @e2e", async () => {
+test("TC: SALEOR_112 Create collection #collections #e2e", async () => {
await collectionsPage.gotoCollectionsListView();
await collectionsPage.waitForDOMToFullyLoad();
await collectionsPage.clickCreateCollectionButton();
@@ -26,7 +27,7 @@ test("TC: SALEOR_112 Create collection @collections @e2e", async () => {
await collectionsPage.clickSaveButton();
await collectionsPage.expectSuccessBanner();
});
-test("TC: SALEOR_113 Edit collection: assign product @collections @e2e", async () => {
+test("TC: SALEOR_113 Edit collection: assign product #collections #e2e", async () => {
const productToBeAssigned = "Bean Juice";
await collectionsPage.gotoExistingCollectionView(COLLECTIONS.collectionToBeUpdated.id);
@@ -44,7 +45,7 @@ test("TC: SALEOR_113 Edit collection: assign product @collections @e2e", async (
`Only 1 category should be visible in table`,
).toEqual(1);
});
-test("TC: SALEOR_114 Bulk delete collections @collections @e2e", async () => {
+test("TC: SALEOR_114 Bulk delete collections #collections #e2e", async () => {
await collectionsPage.gotoCollectionsListView();
await collectionsPage.waitForDOMToFullyLoad();
await collectionsPage.checkListRowsBasedOnContainingText(
diff --git a/playwright/tests/customers.spec.ts b/playwright/tests/customers.spec.ts
index be1011512c1..2e27ebd5d55 100644
--- a/playwright/tests/customers.spec.ts
+++ b/playwright/tests/customers.spec.ts
@@ -6,10 +6,11 @@ import { AddAddressDialog } from "@pages/dialogs/addAddressDialog";
import { DeleteAddressDialog } from "@pages/dialogs/deleteAddressDialog";
import { AddressForm } from "@pages/forms/addressForm";
import { GiftCardsPage } from "@pages/giftCardsPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
import faker from "faker";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let customersPage: CustomersPage;
let giftCardsPage: GiftCardsPage;
@@ -27,7 +28,7 @@ test.beforeEach(({ page }) => {
deleteAddressDialog = new DeleteAddressDialog(page);
});
-test("TC: SALEOR_199 Create customer @e2e @customer", async () => {
+test("TC: SALEOR_199 Create customer #e2e #customer", async () => {
const firstName = faker.name.firstName();
const lastName = faker.name.lastName();
const note = faker.lorem.sentence();
@@ -55,7 +56,7 @@ test("TC: SALEOR_199 Create customer @e2e @customer", async () => {
await expect(customersPage.customerEmailInput).toHaveValue(email.toLowerCase());
});
-test("TC: SALEOR_200 As an admin I should not be able to create customer with duplicated email @e2e @customer", async () => {
+test("TC: SALEOR_200 As an admin I should not be able to create customer with duplicated email #e2e #customer", async () => {
const firstName = faker.name.firstName();
const lastName = faker.name.lastName();
const note = faker.lorem.sentence();
@@ -77,7 +78,7 @@ test("TC: SALEOR_200 As an admin I should not be able to create customer with du
await customersPage.expectErrorBannerMessage("User with this Email already exists.");
});
-test("TC: SALEOR_201 Update customer account info @e2e @customer", async () => {
+test("TC: SALEOR_201 Update customer account info #e2e #customer", async () => {
const firstName = faker.name.firstName();
const lastName = faker.name.lastName();
const email = faker.internet.email();
@@ -96,7 +97,7 @@ test("TC: SALEOR_201 Update customer account info @e2e @customer", async () => {
await expect(customersPage.customerEmailInput).toHaveValue(email.toLowerCase());
});
-test("TC: SALEOR_202 Deactivate a customer @e2e @customer", async () => {
+test("TC: SALEOR_202 Deactivate a customer #e2e #customer", async () => {
await customersPage.gotoCustomerDetailsPage(CUSTOMERS.customerToBeDeactivated.id);
await customersPage.customerActiveCheckbox.click();
await customersPage.saveCustomer();
@@ -104,7 +105,7 @@ test("TC: SALEOR_202 Deactivate a customer @e2e @customer", async () => {
await expect(customersPage.customerActiveCheckbox).not.toBeChecked();
});
-test("TC: SALEOR_203 Activate a customer @e2e @customer", async () => {
+test("TC: SALEOR_203 Activate a customer #e2e #customer", async () => {
await customersPage.gotoCustomerDetailsPage(CUSTOMERS.customerToBeActivated.id);
await customersPage.customerActiveCheckbox.click();
await customersPage.saveCustomer();
@@ -112,7 +113,7 @@ test("TC: SALEOR_203 Activate a customer @e2e @customer", async () => {
await expect(customersPage.customerActiveCheckbox).toBeChecked();
});
-test("TC: SALEOR_204 Delete customer from the details page @e2e @customer", async () => {
+test("TC: SALEOR_204 Delete customer from the details page #e2e #customer", async () => {
await customersPage.gotoCustomerDetailsPage(CUSTOMERS.deleteCustomer.id);
await customersPage.deleteCustomer();
await customersPage.deleteDialog.clickDeleteButton();
@@ -122,7 +123,7 @@ test("TC: SALEOR_204 Delete customer from the details page @e2e @customer", asyn
await expect(customersPage.emptyDataGridListView).toBeVisible();
});
-test("TC: SALEOR_205 Bulk delete customers @e2e @customer", async () => {
+test("TC: SALEOR_205 Bulk delete customers #e2e #customer", async () => {
const customersToBeBulkDeleted = CUSTOMERS.customersToBeBulkDeleted.names;
await customersPage.goToCustomersListView();
@@ -138,7 +139,7 @@ test("TC: SALEOR_205 Bulk delete customers @e2e @customer", async () => {
await expect(customersPage.emptyDataGridListView).toBeVisible();
});
-test("TC: SALEOR_206 As an admin I want to add address to the customer and set it as default shipping @e2e @customer", async () => {
+test("TC: SALEOR_206 As an admin I want to add address to the customer and set it as default shipping #e2e #customer", async () => {
await customersPage.gotoCustomerDetailsPage(CUSTOMERS.editCustomer.id);
await addressesListPage.clickManageAddresses();
await addressesListPage.clickAddAddressButton();
@@ -166,7 +167,7 @@ test("TC: SALEOR_206 As an admin I want to add address to the customer and set i
);
});
-test("TC: SALEOR_209 As an admin I want to update customer's address and set it as default billing @e2e @customer", async () => {
+test("TC: SALEOR_209 As an admin I want to update customer's address and set it as default billing #e2e #customer", async () => {
await customersPage.gotoCustomerDetailsPage(CUSTOMERS.editCustomer.id);
await addressesListPage.clickManageAddresses();
await addressesListPage.clickShowMoreMenu(CUSTOMERS.editCustomer.initialShippingAddress.lastName);
@@ -197,7 +198,7 @@ test("TC: SALEOR_209 As an admin I want to update customer's address and set it
);
});
-test("TC: SALEOR_210 Delete customer's address @e2e @customer", async () => {
+test("TC: SALEOR_210 Delete customer's address #e2e #customer", async () => {
await customersPage.gotoCustomerDetailsPage(CUSTOMERS.editCustomer.id);
await addressesListPage.clickManageAddresses();
await addressesListPage.clickShowMoreMenu(CUSTOMERS.editCustomer.initialBillingAddress.lastName);
@@ -210,11 +211,13 @@ test("TC: SALEOR_210 Delete customer's address @e2e @customer", async () => {
).not.toBeVisible();
});
-test("TC: SALEOR_207 Issue a new gift card for the customer @e2e @customer", async () => {
+test("TC: SALEOR_207 Issue a new gift card for the customer #e2e #customer", async () => {
const amount = faker.datatype.number(1000).toPrecision(2).toString();
await customersPage.gotoCustomerDetailsPage(CUSTOMERS.editCustomer.id);
await customersPage.clickIssueNewGiftCard();
+
+ await expect(customersPage.amountDropdown).toBeVisible();
await customersPage.issueGiftCardDialog.typeAmount(amount);
await customersPage.issueGiftCardDialog.typeCustomTag(faker.lorem.word());
await customersPage.issueGiftCardDialog.typeNote(faker.lorem.sentences(3));
@@ -228,8 +231,7 @@ test("TC: SALEOR_207 Issue a new gift card for the customer @e2e @customer", asy
await giftCardsPage.expectSuccessBanner();
await giftCardsPage.issueGiftCardDialog.clickOkButton();
await giftCardsPage.expectElementIsHidden(giftCardsPage.giftCardDialog);
- await giftCardsPage.expectSuccessBannerMessage("Successfully created gift card");
- await giftCardsPage.expectElementIsHidden(giftCardsPage.successBanner);
+ await giftCardsPage.expectSuccessBanner({ message: "Successfully created gift card" });
await giftCardsPage.gotoGiftCardsListView();
await giftCardsPage.waitForCanvasContainsText(`Code ending with ${code}`);
});
diff --git a/playwright/tests/discounts.spec.ts b/playwright/tests/discounts.spec.ts
index 252bedd9c9a..e445f7b2f6b 100644
--- a/playwright/tests/discounts.spec.ts
+++ b/playwright/tests/discounts.spec.ts
@@ -1,9 +1,10 @@
import { CATEGORIES, CHANNELS, COLLECTIONS, DISCOUNTS, PRODUCTS } from "@data/e2eTestData";
import { DiscountsPage } from "@pages/discountsPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
import faker from "faker";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let discounts: DiscountsPage;
@@ -14,7 +15,7 @@ test.beforeEach(({ page }) => {
const discountType = ["Order", "Catalog"];
for (const type of discountType) {
- test(`TC: SALEOR_149 Create promotion with ${type} predicate @discounts @e2e`, async () => {
+ test(`TC: SALEOR_149 Create promotion with ${type} predicate #discounts #e2e`, async () => {
const discountName = `${faker.lorem.word()}+${type}`;
await discounts.gotoListView();
@@ -28,19 +29,17 @@ for (const type of discountType) {
await discounts.typeEndDate();
await discounts.typeEndHour();
await discounts.clickSaveButton();
- await expect(discounts.successBanner).toBeVisible({ timeout: 10000 });
+ await discounts.expectSuccessBanner();
await expect(discounts.pageHeader).toHaveText(discountName);
await expect(discounts.discountTypeSelect).toHaveText(type);
await expect(discounts.ruleSection).toHaveText("Add your first rule to set up a promotion");
});
}
-test(`TC: SALEOR_151 Update existing promotion @discounts @e2e`, async () => {
+test(`TC: SALEOR_151 Update existing promotion #discounts #e2e`, async () => {
const newDiscountName = `${faker.lorem.word()}`;
- await discounts.waitForNetworkIdleAfterAction(() =>
- discounts.gotoExistingDiscount(DISCOUNTS.promotionToBeEdited.id),
- );
+ await discounts.gotoExistingDiscount(DISCOUNTS.promotionToBeEdited.id);
await discounts.ruleSection.waitFor({
state: "visible",
timeout: 10000,
@@ -57,7 +56,7 @@ test(`TC: SALEOR_151 Update existing promotion @discounts @e2e`, async () => {
await expect(discounts.endDateInput).not.toBeAttached();
await expect(discounts.endHourInput).not.toBeAttached();
await discounts.clickSaveButton();
- await expect(discounts.successBanner).toBeVisible({ timeout: 10000 });
+ await discounts.expectSuccessBanner();
await expect(discounts.pageHeader).toHaveText(newDiscountName);
await expect(discounts.discountTypeSelect).toHaveText(DISCOUNTS.promotionToBeEdited.type);
});
@@ -68,10 +67,8 @@ const promotions = [
];
for (const promotion of promotions) {
- test(`TC: SALEOR_153 Delete existing ${promotion.name} @discounts @e2e`, async () => {
- await discounts.waitForNetworkIdleAfterAction(() =>
- discounts.gotoExistingDiscount(promotion.id),
- );
+ test(`TC: SALEOR_153 Delete existing ${promotion.name} #discounts #e2e`, async () => {
+ await discounts.gotoExistingDiscount(promotion.id);
await discounts.ruleSection.waitFor({
state: "visible",
timeout: 10000,
@@ -81,10 +78,8 @@ for (const promotion of promotions) {
});
await discounts.clickDeleteButton();
await discounts.deleteDiscountDialog.waitForDOMToFullyLoad();
- await discounts.waitForNetworkIdleAfterAction(() =>
- discounts.deleteDiscountDialog.clickConfirmDeleteButton(),
- );
- await expect(discounts.successBanner).toBeVisible({ timeout: 10000 });
+ await discounts.deleteDiscountDialog.clickConfirmDeleteButton();
+ await discounts.expectSuccessBanner();
});
}
@@ -113,10 +108,8 @@ const rewardValue = "10";
const channelName = CHANNELS.channelPLN.name;
for (const { promotionRule, predicateValue } of predicateValues) {
- test(`TC: SALEOR_155 Create ${promotionRule} rule for ${predicateValue} in a catalogue promotion @discounts @e2e`, async () => {
- await discounts.waitForNetworkIdleAfterAction(() =>
- discounts.gotoExistingDiscount(promotion.id),
- );
+ test(`TC: SALEOR_155 Create ${promotionRule} rule for ${predicateValue} in a catalogue promotion #discounts #e2e`, async () => {
+ await discounts.gotoExistingDiscount(promotion.id);
await discounts.ruleSection.waitFor({
state: "visible",
timeout: 10000,
@@ -137,7 +130,7 @@ for (const { promotionRule, predicateValue } of predicateValues) {
await discounts.promotionRuleDialog.selectPercentageRewardValueType();
await discounts.promotionRuleDialog.typeRewardValue(rewardValue);
await discounts.promotionRuleDialog.clickSaveRuleButton();
- await expect(discounts.successBanner).toBeVisible({ timeout: 10000 });
+ await discounts.expectSuccessBanner();
await expect(
discounts.existingRule.filter({ hasText: `Catalog rule: ${name}` }).first(),
).toContainText(
@@ -162,10 +155,8 @@ const notEqConditions = [conditionLte, conditionGte];
const orderPromotion = DISCOUNTS.orderPromotion;
for (const { conditionType, value, conditionDesc } of notEqConditions) {
- test(`TC: SALEOR_157 Create subtotal type rule with multiple conditions with ${conditionDesc} in order promotion @discounts @e2e`, async () => {
- await discounts.waitForNetworkIdleAfterAction(() =>
- discounts.gotoExistingDiscount(orderPromotion.id),
- );
+ test(`TC: SALEOR_157 Create subtotal type rule with multiple conditions with ${conditionDesc} in order promotion #discounts #e2e`, async () => {
+ await discounts.gotoExistingDiscount(orderPromotion.id);
await discounts.ruleSection.waitFor({
state: "visible",
timeout: 10000,
@@ -191,7 +182,7 @@ for (const { conditionType, value, conditionDesc } of notEqConditions) {
await discounts.promotionRuleDialog.selectRuleConditionType(conditionType);
await discounts.promotionRuleDialog.typeRuleConditionValue(value, 1);
await discounts.promotionRuleDialog.clickSaveRuleButton();
- await expect(discounts.successBanner).toBeVisible({ timeout: 10000 });
+ await discounts.expectSuccessBanner();
await expect(
discounts.existingRule.filter({ hasText: `Order rule: ${name}` }).first(),
).toContainText(
@@ -205,10 +196,8 @@ const condition2 = { condition: "Total", gte: "20.00", lte: "50.00" };
const conditionsBetween = [condition1, condition2];
for (const { condition, lte, gte } of conditionsBetween) {
- test(`TC: SALEOR_160 Create gift reward rule with ${condition} between ${gte} and ${lte} in order promotion @discounts @e2e`, async () => {
- await discounts.waitForNetworkIdleAfterAction(() =>
- discounts.gotoExistingDiscount(orderPromotion.id),
- );
+ test(`TC: SALEOR_160 Create gift reward rule with ${condition} between ${gte} and ${lte} in order promotion #discounts #e2e`, async () => {
+ await discounts.gotoExistingDiscount(orderPromotion.id);
await discounts.ruleSection.waitFor({
state: "visible",
timeout: 10000,
@@ -227,10 +216,8 @@ for (const { condition, lte, gte } of conditionsBetween) {
await discounts.promotionRuleDialog.selectPredicate(`${condition} price`);
await discounts.promotionRuleDialog.selectRuleConditionType("between");
await discounts.promotionRuleDialog.typeRuleConditionBoundaryValues(gte, lte);
- await discounts.waitForNetworkIdleAfterAction(() =>
- discounts.promotionRuleDialog.clickSaveRuleButton(),
- );
- await expect(discounts.successBanner).toBeVisible({ timeout: 10000 });
+ await discounts.promotionRuleDialog.clickSaveRuleButton();
+ await discounts.expectSuccessBanner();
await discounts.ruleSection.waitFor({
state: "visible",
timeout: 10000,
@@ -249,10 +236,8 @@ const orderRules = [
];
for (const rule of orderRules) {
- test(`TC: SALEOR_163 Update promotion ${rule.name} from Order promotion @discounts @e2e`, async () => {
- await discounts.waitForNetworkIdleAfterAction(() =>
- discounts.gotoExistingDiscount(DISCOUNTS.orderPromotionWithRulesToBeUpdated.id),
- );
+ test(`TC: SALEOR_163 Update promotion ${rule.name} from Order promotion #discounts #e2e`, async () => {
+ await discounts.gotoExistingDiscount(DISCOUNTS.orderPromotionWithRulesToBeUpdated.id);
await discounts.ruleSection.waitFor({
state: "visible",
timeout: 10000,
@@ -264,11 +249,12 @@ for (const rule of orderRules) {
if (await discounts.promotionRuleDialog.ruleConditionRow.isVisible()) {
await discounts.promotionRuleDialog.clickAddRuleConditionButton();
+ await discounts.promotionRuleDialog.clickRuleConditionPredicateDropdown();
await discounts.promotionRuleDialog.selectPredicate("Total price", 1);
await discounts.promotionRuleDialog.typeRuleConditionValue("13.33", 1);
await discounts.promotionRuleDialog.typeRewardValue("1.00");
await discounts.promotionRuleDialog.clickSaveEditedRuleButton();
- await expect(discounts.successBanner).toBeVisible({ timeout: 10000 });
+ await discounts.expectSuccessBanner();
await expect(
discounts.existingRule.filter({ hasText: `Order rule: ${orderRules[0].name}` }).first(),
).toContainText(
@@ -286,7 +272,7 @@ for (const rule of orderRules) {
await discounts.promotionRuleDialog.removeExistingGiftReward(giftRewardToBeDeleted);
await discounts.promotionRuleDialog.selectGiftReward("Blue Hoodie");
await discounts.promotionRuleDialog.clickSaveEditedRuleButton();
- await expect(discounts.successBanner).toBeVisible({ timeout: 10000 });
+ await discounts.expectSuccessBanner();
await expect(
discounts.existingRule.filter({ hasText: `Order rule: ${orderRules[1].name}` }).first(),
).toContainText(
@@ -302,10 +288,8 @@ const catalogRules = [
];
for (const rule of catalogRules) {
- test(`TC: SALEOR_166 Update promotion ${rule.name} from Catalog promotion @discounts @e2e`, async () => {
- await discounts.waitForNetworkIdleAfterAction(() =>
- discounts.gotoExistingDiscount(DISCOUNTS.catalogPromotionWithRulesToBeUpdated.id),
- );
+ test(`TC: SALEOR_166 Update promotion ${rule.name} from Catalog promotion #discounts #e2e`, async () => {
+ await discounts.gotoExistingDiscount(DISCOUNTS.catalogPromotionWithRulesToBeUpdated.id);
await discounts.ruleSection.waitFor({
state: "visible",
timeout: 50000,
@@ -337,7 +321,7 @@ for (const rule of catalogRules) {
}
await discounts.promotionRuleDialog.clickSaveEditedRuleButton();
- await expect(discounts.successBanner).toBeVisible({ timeout: 10000 });
+ await discounts.expectSuccessBanner();
await discounts.ruleSection.waitFor({
state: "visible",
timeout: 10000,
@@ -357,20 +341,16 @@ const promotionsWithRules = [
for (const promotion of promotionsWithRules) {
for (const rule of promotion.rules) {
- test(`TC: SALEOR_167 Delete promotion ${rule.name} from ${promotion.type} promotion @discounts @e2e`, async () => {
- await discounts.waitForNetworkIdleAfterAction(() =>
- discounts.gotoExistingDiscount(promotion.id),
- );
+ test(`TC: SALEOR_167 Delete promotion ${rule.name} from ${promotion.type} promotion #discounts #e2e`, async () => {
+ await discounts.gotoExistingDiscount(promotion.id);
await discounts.ruleSection.waitFor({
state: "visible",
timeout: 50000,
});
await discounts.clickDeleteRuleButton(`${promotion.type} rule: ${rule.name}`);
await expect(discounts.deleteRuleModal).toBeVisible({ timeout: 10000 });
- await discounts.waitForNetworkIdleAfterAction(() =>
- discounts.deleteRuleDialog.clickConfirmDeleteButton(),
- );
- await expect(discounts.successBanner).toBeVisible({ timeout: 10000 });
+ await discounts.deleteRuleDialog.clickConfirmDeleteButton();
+ await discounts.expectSuccessBanner();
await expect(discounts.ruleSection).not.toHaveText(`${promotion.type}: ${rule.name}`);
});
}
diff --git a/playwright/tests/giftCards.spec.ts b/playwright/tests/giftCards.spec.ts
index 6f10be0322c..62a84edf86e 100644
--- a/playwright/tests/giftCards.spec.ts
+++ b/playwright/tests/giftCards.spec.ts
@@ -1,24 +1,24 @@
-import { MailpitService } from "@api/mailpit";
import { GIFT_CARDS } from "@data/e2eTestData";
import { GiftCardsPage } from "@pages/giftCardsPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let giftCardsPage: GiftCardsPage;
-let mailpitService: MailpitService;
-test.beforeEach(async ({ page, request }) => {
+test.beforeEach(async ({ page }) => {
test.slow();
giftCardsPage = new GiftCardsPage(page);
- mailpitService = new MailpitService(request);
await giftCardsPage.gotoGiftCardsListView();
await giftCardsPage.waitForDOMToFullyLoad();
});
-test("TC: SALEOR_105 Issue gift card @e2e @gift", async () => {
+test("TC: SALEOR_105 Issue gift card #e2e #gift", async () => {
await giftCardsPage.clickIssueCardButton();
+ await expect(giftCardsPage.issueGiftCardDialog.amountDropdown).toBeVisible();
await giftCardsPage.issueGiftCardDialog.typeAmount("50");
await giftCardsPage.issueGiftCardDialog.typeCustomTag("super ultra automation discount");
+ await giftCardsPage.issueGiftCardDialog.tagsInputBlur();
await giftCardsPage.issueGiftCardDialog.clickRequiresActivationCheckbox();
await giftCardsPage.issueGiftCardDialog.clickIssueButton();
await expect(giftCardsPage.issueGiftCardDialog.cardCode).toBeVisible();
@@ -29,17 +29,13 @@ test("TC: SALEOR_105 Issue gift card @e2e @gift", async () => {
await giftCardsPage.expectSuccessBanner();
await giftCardsPage.issueGiftCardDialog.clickOkButton();
await giftCardsPage.giftCardDialog.waitFor({ state: "hidden" });
- await giftCardsPage.expectSuccessBannerMessage("Successfully created gift card");
- await giftCardsPage.successBanner.first().waitFor({
- state: "hidden",
- timeout: 30000,
- });
+ await giftCardsPage.expectSuccessBanner({ message: "Successfully created gift card" });
await giftCardsPage.gotoGiftCardsListView();
await giftCardsPage.gridCanvas
.getByText(`Code ending with ${code}`)
.waitFor({ state: "attached", timeout: 30000 });
});
-test("TC: SALEOR_106 Issue gift card with specific customer and expiry date @e2e @gift", async () => {
+test("TC: SALEOR_106 Issue gift card with specific customer and expiry date #e2e #gift", async () => {
await giftCardsPage.clickIssueCardButton();
await giftCardsPage.issueGiftCardDialog.clickSendExpireDateCheckbox();
@@ -53,11 +49,7 @@ test("TC: SALEOR_106 Issue gift card with specific customer and expiry date @e2e
await giftCardsPage.issueGiftCardDialog.clickOkButton();
await giftCardsPage.giftCardDialog.waitFor({ state: "hidden" });
- await giftCardsPage.expectSuccessBannerMessage("Successfully created gift card");
- await giftCardsPage.successBanner.waitFor({
- state: "hidden",
- timeout: 30000,
- });
+ await giftCardsPage.expectSuccessBanner({ message: "Successfully created gift card" });
await giftCardsPage.gotoGiftCardsListView();
await giftCardsPage.searchAndFindRowIndexes(fullCode);
expect(
@@ -65,32 +57,39 @@ test("TC: SALEOR_106 Issue gift card with specific customer and expiry date @e2e
"There should be only one gift card visible on list",
).toEqual(1);
});
-test("TC: SALEOR_107 Resend code @e2e @gift", async () => {
+test("TC: SALEOR_107 Resend code #e2e #gift", async () => {
await giftCardsPage.clickListRowBasedOnContainingText(GIFT_CARDS.giftCardToResendCode.name);
await giftCardsPage.clickResendCodeButton();
+ // This is a workaround for the issue with the dropdown focusing on dialog open
+ // Dropdown can cover the resend button and cause test to fail
+ await giftCardsPage.resendGiftCardCodeDialog.blur();
await giftCardsPage.resendGiftCardCodeDialog.clickResendButton();
await giftCardsPage.expectSuccessBanner();
});
-test("TC: SALEOR_108 Deactivate gift card @e2e @gift", async () => {
+test("TC: SALEOR_108 Deactivate gift card #e2e #gift", async () => {
await giftCardsPage.gotoExistingGiftCardView(GIFT_CARDS.giftCardToBeDeactivated.id);
await giftCardsPage.clickDeactivateButton();
await giftCardsPage.expectSuccessBanner();
await expect(giftCardsPage.pageHeader).toContainText("Disabled");
});
-test("TC: SALEOR_109 Activate gift card @e2e @gift", async () => {
+test("TC: SALEOR_109 Activate gift card #e2e #gift", async () => {
await giftCardsPage.gotoExistingGiftCardView(GIFT_CARDS.giftCardToBeActivated.id);
await giftCardsPage.clickDeactivateButton();
await giftCardsPage.expectSuccessBanner();
await expect(giftCardsPage.pageHeader).not.toContainText("Disabled");
});
-test("TC: SALEOR_110 Edit gift card @e2e @gift", async () => {
+test("TC: SALEOR_110 Edit gift card #e2e #gift", async () => {
await giftCardsPage.gotoExistingGiftCardView(GIFT_CARDS.giftCardToBeEdited.id);
+ await giftCardsPage.openTagInput();
+ await giftCardsPage.selectFirstTag();
+ await giftCardsPage.selectFirstTag();
+ await giftCardsPage.closeTagInput();
await giftCardsPage.clickCardExpiresCheckbox();
await giftCardsPage.metadataSeoPage.expandAndAddAllMetadata();
await giftCardsPage.clickSaveButton();
await giftCardsPage.expectSuccessBanner();
});
-test("TC: SALEOR_111 Bulk delete gift cards @e2e @gift", async () => {
+test("TC: SALEOR_111 Bulk delete gift cards #e2e #gift", async () => {
await giftCardsPage.checkListRowsBasedOnContainingText(GIFT_CARDS.giftCardsToBeDeleted.names);
await giftCardsPage.clickBulkDeleteButton();
await giftCardsPage.deleteDialog.clickConfirmDeletionCheckbox();
@@ -101,13 +100,13 @@ test("TC: SALEOR_111 Bulk delete gift cards @e2e @gift", async () => {
await expect(giftCardsPage.gridCanvas).not.toContainText(`Code ending with ${last4Code}`);
}
});
-test("TC: SALEOR_181 Set gift card balance @e2e @gift", async () => {
+test("TC: SALEOR_181 Set gift card balance #e2e #gift", async () => {
await giftCardsPage.gotoExistingGiftCardView(GIFT_CARDS.giftCardToBeEdited.id);
await giftCardsPage.clickSetBalance();
await giftCardsPage.setGiftCardsBalanceDialog.setBalance("34");
await giftCardsPage.expectSuccessBanner();
});
-test("TC: SALEOR_182 Export gift card codes in XLSX file @e2e @gift", async () => {
+test("TC: SALEOR_182 Export gift card codes in XLSX file #e2e #gift", async () => {
await giftCardsPage.clickShowMoreMenu();
await giftCardsPage.clickExportGiftCards();
await giftCardsPage.exportGiftCardsDialog.exportGiftCardCodes("XLSX");
@@ -115,12 +114,8 @@ test("TC: SALEOR_182 Export gift card codes in XLSX file @e2e @gift", async () =
state: "hidden",
timeout: 30000,
});
- await mailpitService.checkDoesUserReceivedExportedData(
- process.env.E2E_USER_NAME!,
- "Your exported gift cards data is ready",
- );
});
-test("TC: SALEOR_183 Export gift card codes in CSV file @e2e @gift", async () => {
+test("TC: SALEOR_183 Export gift card codes in CSV file #e2e #gift", async () => {
await giftCardsPage.clickShowMoreMenu();
await giftCardsPage.clickExportGiftCards();
await giftCardsPage.exportGiftCardsDialog.exportGiftCardCodes("CSV");
@@ -128,8 +123,4 @@ test("TC: SALEOR_183 Export gift card codes in CSV file @e2e @gift", async () =>
state: "hidden",
timeout: 30000,
});
- await mailpitService.checkDoesUserReceivedExportedData(
- process.env.E2E_USER_NAME!,
- "Your exported gift cards data is ready",
- );
});
diff --git a/playwright/tests/home.spec.ts b/playwright/tests/home.spec.ts
index 2c8449045a5..2f3552a55fd 100644
--- a/playwright/tests/home.spec.ts
+++ b/playwright/tests/home.spec.ts
@@ -1,9 +1,11 @@
import { URL_LIST } from "@data/url";
import { HomePage } from "@pages/homePage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
-test("TC: SALEOR_29 Correct information on dashboard home page @e2e", async ({ page }) => {
+test.use({ permissionName: "admin" });
+
+test("TC: SALEOR_29 Correct information on dashboard home page #e2e", async ({ page }) => {
const homePage = new HomePage(page);
await page.goto(URL_LIST.homePage);
diff --git a/playwright/tests/navigation.spec.ts b/playwright/tests/navigation.spec.ts
index 075e169fabf..e8c84d4cc96 100644
--- a/playwright/tests/navigation.spec.ts
+++ b/playwright/tests/navigation.spec.ts
@@ -3,10 +3,11 @@ import { ConfigurationPage } from "@pages/configurationPage";
import { AddNavigationMenuItemDialog } from "@pages/dialogs/addNavigationMenuItemDialog";
import { NavigationDetailsPage } from "@pages/navigationDetailsPage";
import { NavigationPage } from "@pages/navigationPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
import faker from "faker";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let navigation: NavigationPage;
let navigationDetailsPage: NavigationDetailsPage;
@@ -19,13 +20,13 @@ test.beforeEach(({ page }) => {
navigationDetailsPage = new NavigationDetailsPage(page);
addNavigationMenuItemDialog = new AddNavigationMenuItemDialog(page);
});
-test("TC: SALEOR_193 Should go to Navigation page @navigation @e2e", async () => {
+test("TC: SALEOR_193 Should go to Navigation page #navigation #e2e", async () => {
await config.goToConfigurationView();
await navigation.clickNavigationButtonFromConfiguration();
await expect(navigation.navigationHeader).toBeVisible();
await expect(navigation.navigationList).toBeVisible();
});
-test("TC: SALEOR_194 Should create a new menu navigation with menu item @navigation @e2e", async () => {
+test("TC: SALEOR_194 Should create a new menu navigation with menu item #navigation #e2e", async () => {
test.slow();
await navigation.goToNavigationView();
await navigation.createMenuButton.click();
@@ -41,15 +42,16 @@ test("TC: SALEOR_194 Should create a new menu navigation with menu item @navigat
const menuItemName = faker.random.word();
await addNavigationMenuItemDialog.typeMenuItemName(menuItemName);
- await addNavigationMenuItemDialog.selectLinkOption("category", "Polo Shirts");
+ await addNavigationMenuItemDialog.selectLinkTypeOption("Categories");
+ await addNavigationMenuItemDialog.selectLinkTypeValue("Polo Shirts");
await addNavigationMenuItemDialog.clickSaveButton();
await expect(navigationDetailsPage.addMenuItemDialog).not.toBeVisible();
- await navigationDetailsPage.expectSuccessBanner();
+ await navigation.expectSuccessBanner();
await expect(navigationDetailsPage.menuNameInput).toHaveValue(menuName);
await expect(navigationDetailsPage.menuItemList).toContainText(menuItemName);
});
// TODO: To be updated after https://linear.app/saleor/issue/MERX-307 is fixed
-test("TC: SALEOR_198 Should update existing menu @navigation @e2e", async () => {
+test("TC: SALEOR_198 Should update existing menu #navigation #e2e", async () => {
await navigationDetailsPage.goToExistingMenuView(NAVIGATION_ITEMS.navigationMenuToBeUpdated.id);
const menuItemToBeUpdated = NAVIGATION_ITEMS.navigationMenuToBeUpdated.menuItems[0];
@@ -58,7 +60,8 @@ test("TC: SALEOR_198 Should update existing menu @navigation @e2e", async () =>
await navigationDetailsPage.clickEditMenuItemButton(menuItemToBeUpdated.name);
await addNavigationMenuItemDialog.typeMenuItemName(newItemName);
- await addNavigationMenuItemDialog.selectLinkOption("category", "Polo Shirts");
+ await addNavigationMenuItemDialog.selectLinkTypeOption("Categories");
+ await addNavigationMenuItemDialog.selectLinkTypeValue("Polo Shirts");
await addNavigationMenuItemDialog.clickSaveButton();
await expect(navigationDetailsPage.addMenuItemDialog).not.toBeVisible();
await navigationDetailsPage.clickDeleteMenuItemButton(menuItemToBeDeleted.name);
@@ -68,7 +71,8 @@ test("TC: SALEOR_198 Should update existing menu @navigation @e2e", async () =>
const menuItemName = faker.random.word();
await addNavigationMenuItemDialog.typeMenuItemName(menuItemName);
- await addNavigationMenuItemDialog.selectLinkOption("category", "Polo Shirts");
+ await addNavigationMenuItemDialog.selectLinkTypeOption("Categories");
+ await addNavigationMenuItemDialog.selectLinkTypeValue("Polo Shirts");
await addNavigationMenuItemDialog.clickSaveButton();
await expect(navigationDetailsPage.menuItemList).toContainText(menuItemName);
await navigationDetailsPage.clickDeleteMenuItemButton(menuItemName);
@@ -88,18 +92,18 @@ test("TC: SALEOR_198 Should update existing menu @navigation @e2e", async () =>
await expect(currentMenuName).not.toBe(NAVIGATION_ITEMS.navigationMenuToBeUpdated.name);
await expect(currentMenuName).toBe(newName);
});
-test("TC: SALEOR_197 Should remove existing menu from it's details page @navigation @e2e", async () => {
+test("TC: SALEOR_197 Should remove existing menu from it's details page #navigation #e2e", async () => {
await navigationDetailsPage.goToExistingMenuView(
NAVIGATION_ITEMS.navigationMenuToBeDeletedFromDetailsView.id,
);
await navigationDetailsPage.clickDeleteButton();
await navigationDetailsPage.deleteDialog.clickDeleteButton();
- await navigationDetailsPage.expectSuccessBanner();
+ await navigation.expectSuccessBanner();
await expect(navigation.navigationList).not.toHaveText(
NAVIGATION_ITEMS.navigationMenuToBeDeletedFromDetailsView.name,
);
});
-test("TC: SALEOR_195 Should remove a single menu from the list @navigation @e2e", async () => {
+test("TC: SALEOR_195 Should remove a single menu from the list #navigation #e2e", async () => {
await navigation.goToNavigationView();
await navigation.selectNavigationMenu(NAVIGATION_ITEMS.navigationMenuToBeDeletedFromList.name);
await navigation.deleteSingleMenu(NAVIGATION_ITEMS.navigationMenuToBeDeletedFromList.name);
@@ -109,7 +113,7 @@ test("TC: SALEOR_195 Should remove a single menu from the list @navigation @e2e"
NAVIGATION_ITEMS.navigationMenuToBeDeletedFromList.name,
);
});
-test("TC: SALEOR_196 Should bulk delete menus from the list @navigation @e2e", async () => {
+test("TC: SALEOR_196 Should bulk delete menus from the list #navigation #e2e", async () => {
await navigation.goToNavigationView();
await navigation.selectAll();
@@ -126,7 +130,7 @@ test("TC: SALEOR_196 Should bulk delete menus from the list @navigation @e2e", a
}
await navigation.clickBulkDeleteButton();
await navigation.deleteDialog.clickDeleteButton();
- await navigation.successBanner.waitFor({ state: "hidden" });
+ await navigation.expectSuccessBanner();
await expect(navigation.navigationList).not.toHaveText(menusToBeBulkDeleted[0]);
await expect(navigation.navigationList).not.toHaveText(menusToBeBulkDeleted[1]);
});
diff --git a/playwright/tests/orders.spec.ts b/playwright/tests/orders.spec.ts
index 41bc014e760..61f1a2ccf4d 100644
--- a/playwright/tests/orders.spec.ts
+++ b/playwright/tests/orders.spec.ts
@@ -7,9 +7,11 @@ import { AddressForm } from "@pages/forms/addressForm";
import { FulfillmentPage } from "@pages/fulfillmentPage";
import { OrdersPage } from "@pages/ordersPage";
import { RefundPage } from "@pages/refundPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import * as faker from "faker";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let ordersPage: OrdersPage;
let draftOrdersPage: DraftOrdersPage;
@@ -31,7 +33,7 @@ test.beforeEach(({ page }) => {
const variantSKU = PRODUCTS.productAvailableWithTransactionFlow.variant1sku;
-test("TC: SALEOR_28 Create basic order @e2e @order", async () => {
+test("TC: SALEOR_28 Create basic order #e2e #order", async () => {
await ordersPage.goToOrdersListView();
await ordersPage.clickCreateOrderButton();
await ordersPage.orderCreateDialog.completeOrderCreateDialogWithFirstChannel();
@@ -45,10 +47,10 @@ test("TC: SALEOR_28 Create basic order @e2e @order", async () => {
await ordersPage.clickAddShippingCarrierButton();
await ordersPage.shippingAddressDialog.pickAndConfirmFirstShippingMethod();
await ordersPage.clickFinalizeButton();
- await draftOrdersPage.expectSuccessBannerMessage("finalized");
+ await draftOrdersPage.expectSuccessBanner({ message: "finalized" });
});
-test("TC: SALEOR_76 Create order with transaction flow activated @e2e @order", async () => {
+test("TC: SALEOR_76 Create order with transaction flow activated #e2e #order", async () => {
await ordersPage.goToOrdersListView();
await ordersPage.clickCreateOrderButton();
await ordersPage.orderCreateDialog.completeOrderCreateDialogWithTransactionChannel();
@@ -63,16 +65,16 @@ test("TC: SALEOR_76 Create order with transaction flow activated @e2e @order", a
await ordersPage.clickAddShippingCarrierButton();
await ordersPage.shippingAddressDialog.pickAndConfirmFirstShippingMethod();
await ordersPage.clickFinalizeButton();
- await draftOrdersPage.expectSuccessBannerMessage("finalized");
+ await draftOrdersPage.expectSuccessBanner({ message: "finalized" });
});
-test("TC: SALEOR_77 Mark order as paid and fulfill it with transaction flow activated @e2e @order", async () => {
+test("TC: SALEOR_77 Mark order as paid and fulfill it with transaction flow activated #e2e #order", async () => {
await ordersPage.goToExistingOrderPage(
ORDERS.ordersWithinTransactionFlow.markAsPaidOrder.orderId,
);
await ordersPage.clickMarkAsPaidButton();
await ordersPage.markOrderAsPaidDialog.typeAndSaveOrderReference();
- await ordersPage.expectSuccessBannerMessage("paid");
+ await ordersPage.expectSuccessBanner({ message: "paid" });
const transactionsMadeRows = await ordersPage.orderTransactionsList.locator("tr");
@@ -80,11 +82,11 @@ test("TC: SALEOR_77 Mark order as paid and fulfill it with transaction flow acti
await expect(transactionsMadeRows).toContainText("Success");
await ordersPage.clickFulfillButton();
await fulfillmentPage.clickFulfillButton();
- await ordersPage.expectSuccessBannerMessage("fulfilled");
+ await ordersPage.expectSuccessBanner({ message: "fulfilled" });
expect(await ordersPage.pageHeaderStatusInfo).toContainText("Fulfilled");
});
-test("TC: SALEOR_78 Capture partial amounts by manual transactions and fulfill order with transaction flow activated @e2e @order", async () => {
+test("TC: SALEOR_78 Capture partial amounts by manual transactions and fulfill order with transaction flow activated #e2e #order", async () => {
const firstManualTransactionAmount = "100";
const secondManualTransactionAmount = "20";
@@ -138,17 +140,17 @@ test("TC: SALEOR_78 Capture partial amounts by manual transactions and fulfill o
);
await ordersPage.clickFulfillButton();
await fulfillmentPage.clickFulfillButton();
- await ordersPage.expectSuccessBannerMessage("fulfilled");
+ await ordersPage.expectSuccessBanner({ message: "fulfilled" });
expect(await ordersPage.pageHeaderStatusInfo, "Order should be yet fulfilled").toContainText(
"Fulfilled",
);
});
-test("TC: SALEOR_79 Mark order as paid and fulfill it with regular flow @e2e @order", async () => {
+test("TC: SALEOR_79 Mark order as paid and fulfill it with regular flow #e2e #order", async () => {
await ordersPage.goToExistingOrderPage(ORDERS.orderToMarkAsPaidAndFulfill.id);
await ordersPage.clickMarkAsPaidButton();
await ordersPage.markOrderAsPaidDialog.typeAndSaveOrderReference();
- await ordersPage.expectSuccessBannerMessage("paid");
+ await ordersPage.expectSuccessBanner({ message: "paid" });
await expect(ordersPage.balanceStatusInfo).toHaveText("Settled");
expect(await ordersPage.paymentStatusInfo, "Order should be fully paid").toContainText(
"Fully paid",
@@ -156,21 +158,21 @@ test("TC: SALEOR_79 Mark order as paid and fulfill it with regular flow @e2e @or
await ordersPage.clickFulfillButton();
await fulfillmentPage.clickFulfillButton();
- await ordersPage.expectSuccessBannerMessage("fulfilled");
+ await ordersPage.expectSuccessBanner({ message: "fulfilled" });
expect(await ordersPage.pageHeaderStatusInfo).toContainText("Fulfilled");
});
-test("TC: SALEOR_80 Add tracking to order @e2e @order", async () => {
+test("TC: SALEOR_80 Add tracking to order #e2e #order", async () => {
const trackingNumber = "123456789";
await ordersPage.goToExistingOrderPage(ORDERS.orderToAddTrackingNumberTo.id);
await ordersPage.clickAddTrackingButton();
await ordersPage.addTrackingDialog.typeTrackingNumberAndSave(trackingNumber);
- await ordersPage.expectSuccessBannerMessage("updated");
+ await ordersPage.expectSuccessBanner({ message: "updated" });
await expect(ordersPage.setTrackingNumber).toContainText(trackingNumber);
});
-test("TC: SALEOR_81 Change billing address in fulfilled order @e2e @order", async () => {
+test("TC: SALEOR_81 Change billing address in fulfilled order #e2e #order", async () => {
await ordersPage.goToExistingOrderPage(ORDERS.orderFulfilledToChangeBillingAddress.id);
await ordersPage.rightSideDetailsPage.clickEditBillingAddressButton();
await ordersPage.addressDialog.clickNewAddressRadioButton();
@@ -197,7 +199,7 @@ test("TC: SALEOR_81 Change billing address in fulfilled order @e2e @order", asyn
);
});
-test("TC: SALEOR_82 Change shipping address in not fulfilled order @e2e @order", async () => {
+test("TC: SALEOR_82 Change shipping address in not fulfilled order #e2e #order", async () => {
await ordersPage.goToExistingOrderPage(ORDERS.orderNotFulfilledToChangeShippingAddress.id);
await ordersPage.rightSideDetailsPage.clickEditShippingAddressButton();
await ordersPage.addressDialog.clickNewAddressRadioButton();
@@ -219,7 +221,7 @@ test("TC: SALEOR_82 Change shipping address in not fulfilled order @e2e @order",
);
});
-test("TC: SALEOR_83 Draft orders bulk delete @e2e @draft", async () => {
+test("TC: SALEOR_83 Draft orders bulk delete #e2e #draft", async () => {
await draftOrdersPage.goToDraftOrdersListView();
await draftOrdersPage.checkListRowsBasedOnContainingText(ORDERS.draftOrdersToBeDeleted.ids);
await draftOrdersPage.clickBulkDeleteButton();
@@ -232,7 +234,7 @@ test("TC: SALEOR_83 Draft orders bulk delete @e2e @draft", async () => {
).toEqual([]);
});
-test("TC: SALEOR_84 Create draft order @e2e @draft", async () => {
+test("TC: SALEOR_84 Create draft order #e2e #draft", async () => {
test.slow();
await draftOrdersPage.goToDraftOrdersListView();
await draftOrdersPage.clickCreateDraftOrderButton();
@@ -249,26 +251,36 @@ test("TC: SALEOR_84 Create draft order @e2e @draft", async () => {
await draftOrdersPage.expectSuccessBanner();
await draftOrdersPage.addressDialog.clickConfirmButton();
await draftOrdersPage.expectSuccessBanner();
+
+ await draftOrdersPage.addShippingCarrierLink.waitFor({ state: "visible" });
+ // Ensure the button is in viewport before clicking
+ await draftOrdersPage.addShippingCarrierLink.scrollIntoViewIfNeeded();
+
+ await expect(draftOrdersPage.addShippingCarrierLink).toBeVisible();
await draftOrdersPage.clickAddShippingCarrierButton();
+
await draftOrdersPage.shippingAddressDialog.pickAndConfirmFirstShippingMethod();
- await draftOrdersPage.expectSuccessBanner();
await draftOrdersPage.clickFinalizeButton();
- await draftOrdersPage.expectSuccessBannerMessage("finalized");
+ await draftOrdersPage.expectSuccessBanner({ message: "finalized" });
});
-test("TC: SALEOR_191 Refund products from the fully paid order @e2e @refunds", async () => {
- const order = ORDERS.fullyPaidOrdersWithSingleTransaction.first;
+test("TC: SALEOR_191 Refund products from the fully paid order #e2e #refunds", async () => {
+ // All steps of this test pass (including after hooks), but Playwright
+ // marks it as failed because of exceeding 30s timeout
+ test.slow();
+
+ const order = ORDERS.fullyPaidOrderWithSingleTransaction;
await ordersPage.goToExistingOrderPage(order.id);
await ordersPage.clickAddRefundButton();
await ordersPage.orderRefundDialog.pickLineItemsRefund();
await ordersPage.orderRefundModal.waitFor({ state: "hidden" });
- await refundPage.expectLineItemsRefundPageOpen(order.id);
+ await refundPage.expectAddLineItemsRefundPageOpen(order.id);
await refundPage.pickAllProductQuantityToRefund(order.lineItems[0].name);
const productRow = await refundPage.getProductRow(order.lineItems[0].name);
- expect(productRow.locator(refundPage.productQuantityInput)).toHaveValue(
+ await expect(productRow.locator(refundPage.productQuantityInput)).toHaveValue(
order.lineItems[0].quantity,
);
@@ -285,11 +297,12 @@ test("TC: SALEOR_191 Refund products from the fully paid order @e2e @refunds", a
await ordersPage.orderRefundSection.waitFor({ state: "visible" });
await ordersPage.assertRefundOnList(refundReason);
await ordersPage.clickEditRefundButton(refundReason);
+ await refundPage.waitForDOMToFullyLoad();
await refundPage.transferFunds();
- await refundPage.expectSuccessBannerMessage("Refund has been sent");
+ await refundPage.expectSuccessBanner({ message: "Refund has been sent" });
});
-test("TC: SALEOR_192 Should create a manual refund with a custom amount @e2e @refunds", async () => {
+test("TC: SALEOR_192 Should create a manual refund with a custom amount #e2e #refunds", async () => {
const order = ORDERS.fullyPaidOrderWithSeveralTransactions;
await ordersPage.goToExistingOrderPage(order.id);
@@ -306,8 +319,167 @@ test("TC: SALEOR_192 Should create a manual refund with a custom amount @e2e @re
);
await refundPage.provideRefundAmount("10");
await refundPage.transferFunds();
- await refundPage.expectSuccessBannerMessage("Transaction action requested successfully");
+ await refundPage.expectSuccessBanner({ message: "Transaction action requested successfully" });
await ordersPage.goToExistingOrderPage(order.id);
await ordersPage.orderRefundSection.waitFor({ state: "visible" });
await ordersPage.assertRefundOnList("Manual refund");
});
+
+const orderRefunds = ORDERS.orderWithRefundsInStatusOtherThanSuccess.refunds;
+
+for (const refund of orderRefunds) {
+ test(`TC: SALEOR_193 Update order with non-manual refund in ${refund.status} status #e2e #refunds`, async () => {
+ await ordersPage.goToExistingOrderPage(ORDERS.orderWithRefundsInStatusOtherThanSuccess.id);
+ await ordersPage.orderRefundList.scrollIntoViewIfNeeded();
+
+ const orderRefundListRow = await ordersPage.orderRefundList.locator("tr");
+ const pendingRefunds = await orderRefundListRow.filter({ hasText: "PENDING" }).all();
+
+ for (const pendingRefund of pendingRefunds) {
+ await expect(pendingRefund.locator(ordersPage.editRefundButton)).toBeDisabled();
+ }
+ await ordersPage.clickEditRefundButton(refund.status);
+ await refundPage.expectEditLineItemsRefundPageOpen(
+ ORDERS.orderWithRefundsInStatusOtherThanSuccess.id,
+ refund.id,
+ );
+ await refundPage.transferFunds();
+ await refundPage.expectSuccessBanner();
+ await expect(ordersPage.orderRefundList).not.toContainText(refund.status);
+ });
+}
+
+test(`TC: SALEOR_215 Inline discount is applied in a draft order #draft #discounts #e2e`, async () => {
+ test.slow();
+
+ const calculateDiscountedPrice = (
+ undiscountedPrice: number,
+ discountPercentage: number,
+ ): number => {
+ return undiscountedPrice - (undiscountedPrice * discountPercentage) / 100;
+ };
+
+ const formatPrice = (price: string): number => parseFloat(price.slice(3));
+
+ const discountedProduct = PRODUCTS.productWithDiscountChannelPLN;
+ const productAlreadyInBasket = ORDERS.draftOrderChannelPLN.productInBasket;
+ const totalPriceLocator = ordersPage.orderSummary.locator(ordersPage.totalPrice);
+
+ await ordersPage.goToExistingOrderPage(ORDERS.draftOrderChannelPLN.id);
+
+ const [initialTotal] = await Promise.all([
+ totalPriceLocator.innerText(),
+ draftOrdersPage.basketProductList.isVisible(),
+ ]);
+
+ expect(initialTotal).toContain(productAlreadyInBasket.price.toString());
+
+ await draftOrdersPage.clickAddProductsButton();
+ await draftOrdersPage.addProductsDialog.searchForProductInDialog(discountedProduct.name);
+ await draftOrdersPage.addProductsDialog.selectVariantBySKU(discountedProduct.variant.sku);
+ await draftOrdersPage.addProductsDialog.clickConfirmButton();
+
+ await draftOrdersPage.expectElementIsHidden(draftOrdersPage.dialog);
+ await draftOrdersPage.expectElementIsHidden(draftOrdersPage.successBanner);
+
+ const expectedDiscountedPrice = calculateDiscountedPrice(
+ discountedProduct.variant.undiscountedPrice,
+ discountedProduct.rewardPercentageDiscountValue,
+ );
+
+ expect(discountedProduct.variant.discountedPrice).toEqual(expectedDiscountedPrice);
+
+ await totalPriceLocator.waitFor({ state: "visible" });
+
+ const finalTotal = await totalPriceLocator.innerText();
+
+ const expectedTotal = (
+ productAlreadyInBasket.price + discountedProduct.variant.discountedPrice
+ ).toFixed(2);
+
+ expect(formatPrice(finalTotal).toFixed(2)).toEqual(expectedTotal);
+});
+
+test(`TC: SALEOR_216 Order type discount is applied to a draft order #draft #discounts #e2e`, async () => {
+ test.slow();
+ await draftOrdersPage.goToDraftOrdersListView();
+ await draftOrdersPage.clickCreateDraftOrderButton();
+ await draftOrdersPage.draftOrderCreateDialog.completeDraftOrderCreateDialogWithSpecificChannel(
+ "e2e-channel-do-not-delete",
+ );
+
+ await draftOrdersPage.clickAddProductsButton();
+ await draftOrdersPage.addProductsDialog.searchForProductInDialog(
+ PRODUCTS.productWithPriceLowerThan20.name,
+ );
+ await draftOrdersPage.addProductsDialog.selectVariantBySKU(
+ PRODUCTS.productWithPriceLowerThan20.variantSKU,
+ );
+ await draftOrdersPage.addProductsDialog.clickConfirmButton();
+ await draftOrdersPage.expectElementIsHidden(draftOrdersPage.dialog);
+ await ordersPage.totalPrice.waitFor({ state: "visible" });
+ await draftOrdersPage.expectElementIsHidden(draftOrdersPage.successBanner);
+
+ // TODO uncomment when MERX-727 is fixed
+ // const giftProduct = PRODUCTS.giftProduct.name;
+
+ // expect(draftOrdersPage.basketProductList).toContainText(giftProduct);
+
+ const initialTotalPrice = await ordersPage.orderSummary
+ .locator(ordersPage.totalPrice)
+ .innerText();
+ const initialSubTotalPrice = await ordersPage.subTotalPrice.innerText();
+
+ expect(parseFloat(initialSubTotalPrice.slice(3))).toBeLessThan(20);
+ expect(parseFloat(initialSubTotalPrice.slice(3))).toEqual(
+ PRODUCTS.productWithPriceLowerThan20.price,
+ );
+ expect(initialTotalPrice).toBe(initialSubTotalPrice);
+
+ await draftOrdersPage.clickAddProductsButton();
+
+ await draftOrdersPage.addProductsDialog.searchForProductInDialog(
+ PRODUCTS.productWithPriceHigherThan20.name,
+ );
+ await draftOrdersPage.addProductsDialog.selectVariantBySKU(
+ PRODUCTS.productWithPriceHigherThan20.variantSKU,
+ );
+ await draftOrdersPage.addProductsDialog.clickConfirmButton();
+ await draftOrdersPage.expectElementIsHidden(draftOrdersPage.dialog);
+ await ordersPage.totalPrice.waitFor({ state: "visible" });
+ await draftOrdersPage.expectElementIsHidden(draftOrdersPage.successBanner);
+
+ const finalSubTotalPrice = await ordersPage.subTotalPrice.innerText();
+
+ expect(parseFloat(finalSubTotalPrice.slice(3))).toBeGreaterThan(20);
+
+ const undiscountedOrderSubTotal =
+ PRODUCTS.productWithPriceLowerThan20.price + PRODUCTS.productWithPriceHigherThan20.price;
+ const finalTotalPrice = await ordersPage.orderSummary.locator(ordersPage.totalPrice).innerText();
+
+ expect(finalTotalPrice.slice(3)).not.toContain(initialSubTotalPrice);
+
+ const discountedOrderSubTotal = undiscountedOrderSubTotal - (undiscountedOrderSubTotal * 5) / 100;
+
+ expect(finalTotalPrice.slice(3)).toContain(discountedOrderSubTotal.toString());
+});
+
+test("TC: SALEOR_217 Complete basic order for non existing customer #e2e #order", async () => {
+ const nonExistingEmail = `customer-${faker.datatype.number()}@example.com`;
+ const newAddress = ADDRESS.addressPL;
+
+ await ordersPage.goToExistingOrderPage(ORDERS.orderWithoutAddedCustomer.id);
+ await ordersPage.rightSideDetailsPage.clickEditCustomerButton();
+ await ordersPage.rightSideDetailsPage.clickSearchCustomerInput();
+ await ordersPage.rightSideDetailsPage.typeAndSelectCustomerEmail(nonExistingEmail);
+ await addressForm.completeBasicInfoAddressForm(newAddress);
+ await addressForm.typeCompanyName(newAddress.companyName);
+ await addressForm.typePhone(newAddress.phone);
+ await addressForm.typeAddressLine2(newAddress.addressLine2);
+ await addressDialog.clickConfirmButton();
+ await ordersPage.expectSuccessBanner();
+ await ordersPage.clickAddShippingCarrierButton();
+ await ordersPage.shippingAddressDialog.pickAndConfirmFirstShippingMethod();
+ await ordersPage.clickFinalizeButton();
+ await ordersPage.expectSuccessBanner({ message: "finalized" });
+});
diff --git a/playwright/tests/pageTypes.spec.ts b/playwright/tests/pageTypes.spec.ts
index d7b8f4972b9..ebc566df943 100644
--- a/playwright/tests/pageTypes.spec.ts
+++ b/playwright/tests/pageTypes.spec.ts
@@ -1,13 +1,14 @@
import { ATTRIBUTES, PAGE_TYPES } from "@data/e2eTestData";
import { PageTypesPage } from "@pages/pageTypesPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
import * as faker from "faker";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
const pageTypeName = `e2e-page-type-${faker.datatype.number()}`;
-test("TC: SALEOR_187 As an admin user I can create page type @e2e @page-type", async ({ page }) => {
+test("TC: SALEOR_187 As an admin user I can create page type #e2e #page-type", async ({ page }) => {
const pageTypePage = new PageTypesPage(page);
await pageTypePage.gotoPageTypeListPage();
@@ -19,7 +20,7 @@ test("TC: SALEOR_187 As an admin user I can create page type @e2e @page-type", a
await pageTypePage.gotoPageTypeListPage();
await expect(pageTypePage.pageTypeList).toContainText(pageTypeName);
});
-test("TC: SALEOR_188 As an admin user I can update page type@e2e @page-type", async ({ page }) => {
+test("TC: SALEOR_188 As an admin user I can update page type#e2e #page-type", async ({ page }) => {
const pageTypePage = new PageTypesPage(page);
const updatedPageTypeName = `updated-e2e-page-type-${faker.datatype.number()}`;
const attributeName = ATTRIBUTES.attributeToBeAssignedToPageType.name;
@@ -33,7 +34,7 @@ test("TC: SALEOR_188 As an admin user I can update page type@e2e @page-type", as
await pageTypePage.expectSuccessBanner();
await expect(pageTypePage.pageAttributes).toContainText(attributeName);
});
-test("TC: SALEOR_189 As an admin user I can delete page type with assigned content@e2e @page-type", async ({
+test("TC: SALEOR_189 As an admin user I can delete page type with assigned content#e2e #page-type", async ({
page,
}) => {
const pageTypePage = new PageTypesPage(page);
@@ -48,7 +49,7 @@ test("TC: SALEOR_189 As an admin user I can delete page type with assigned conte
await pageTypePage.gotoPageTypeListPage();
await expect(pageTypePage.pageTypeList).not.toContainText(pageType.name);
});
-test("TC: SALEOR_190 As an admin user I can delete several page types@e2e @page-type", async ({
+test("TC: SALEOR_190 As an admin user I can delete several page types#e2e #page-type", async ({
page,
}) => {
const pageTypePage = new PageTypesPage(page);
diff --git a/playwright/tests/permissionGroup.spec.ts b/playwright/tests/permissionGroup.spec.ts
index 3a7a5a96b8f..50d1c665216 100644
--- a/playwright/tests/permissionGroup.spec.ts
+++ b/playwright/tests/permissionGroup.spec.ts
@@ -4,10 +4,11 @@ import { AssignPermissionGroupMembersDialog } from "@pages/dialogs/assignPermiss
import { UnassignPermissionGroupMembersDialog } from "@pages/dialogs/unassignPermissionGroupMembersDialog";
import { PermissionGroupDetailsPage } from "@pages/permissionGroupDetailsPage";
import { PermissionGroupsPage } from "@pages/permissionGroupsPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
import faker from "faker";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let permissions: PermissionGroupsPage;
let permissionDetails: PermissionGroupDetailsPage;
@@ -22,13 +23,13 @@ test.beforeEach(({ page }) => {
assignmentDialog = new AssignPermissionGroupMembersDialog(page);
unassignDialog = new UnassignPermissionGroupMembersDialog(page);
});
-test("TC: SALEOR_139 Should be able to navigate to permission groups page @permissions @e2e", async () => {
+test("TC: SALEOR_139 Should be able to navigate to permission groups page #permissions #e2e", async () => {
await config.goToConfigurationView();
await config.permissionGroupsButton.scrollIntoViewIfNeeded();
await config.openPermissionGroups();
await expect(permissions.permissionGroupsList).toBeVisible();
});
-test("TC: SALEOR_133 Should be able to create new permission group @permissions @e2e", async () => {
+test("TC: SALEOR_133 Should be able to create new permission group #permissions #e2e", async () => {
await permissions.gotoPermissionGroupsView();
await permissions.clickCreatePermissionGroupButton();
@@ -78,7 +79,7 @@ test("TC: SALEOR_133 Should be able to create new permission group @permissions
).toBeChecked();
}
});
-test("TC: SALEOR_134 Should be able to edit existing permission group @permissions @e2e", async () => {
+test("TC: SALEOR_134 Should be able to edit existing permission group #permissions #e2e", async () => {
await permissions.gotoPermissionGroupsView();
const permission = PERMISSION_GROUPS.permissionGroupToBeEdited;
@@ -161,7 +162,7 @@ test("TC: SALEOR_134 Should be able to edit existing permission group @permissio
timeout: 50000,
});
});
-test("TC: SALEOR_135 Should be able to delete single permission group @permissions @e2e", async () => {
+test("TC: SALEOR_135 Should be able to delete single permission group #permissions #e2e", async () => {
await permissions.gotoPermissionGroupsView();
const permission = PERMISSION_GROUPS.permissionGroupToBeDeleted;
diff --git a/playwright/tests/product.spec.ts b/playwright/tests/product.spec.ts
index 5de78790e31..8a6d9509432 100644
--- a/playwright/tests/product.spec.ts
+++ b/playwright/tests/product.spec.ts
@@ -1,25 +1,23 @@
-import { MailpitService } from "@api/mailpit";
import { AVAILABILITY } from "@data/copy";
import { PRODUCTS } from "@data/e2eTestData";
import { ProductCreateDialog } from "@pages/dialogs/productCreateDialog";
import { ProductPage } from "@pages/productPage";
import { VariantsPage } from "@pages/variantsPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let productPage: ProductPage;
let productCreateDialog: ProductCreateDialog;
let variantsPage: VariantsPage;
-let mailpitService: MailpitService;
-test.beforeEach(({ page, request }) => {
+test.beforeEach(({ page }) => {
productPage = new ProductPage(page);
productCreateDialog = new ProductCreateDialog(page);
variantsPage = new VariantsPage(page);
- mailpitService = new MailpitService(request);
});
-test("TC: SALEOR_3 Create basic product with variants @e2e @product", async () => {
+test("TC: SALEOR_3 Create basic product with variants #e2e #product", async () => {
await productPage.gotoProductListPage();
await productPage.clickCreateProductButton();
await productCreateDialog.selectProductTypeWithVariants();
@@ -32,7 +30,7 @@ test("TC: SALEOR_3 Create basic product with variants @e2e @product", async () =
await productPage.clickSaveButton();
await productPage.expectSuccessBanner();
});
-test("TC: SALEOR_5 Create basic - single product type - product without variants @e2e @product", async () => {
+test("TC: SALEOR_5 Create basic - single product type - product without variants #e2e #product", async () => {
await productPage.gotoCreateProductPage(PRODUCTS.singleProductType.id);
await productPage.rightSideDetailsPage.selectOneChannelAsAvailableWhenMoreSelected("Channel-PLN");
await productPage.typeNameDescAndRating();
@@ -45,7 +43,7 @@ test("TC: SALEOR_5 Create basic - single product type - product without variants
await productPage.clickSaveButton();
await productPage.expectSuccessBanner();
});
-test("TC: SALEOR_26 Create basic info variant - via edit variant page @e2e @product", async () => {
+test("TC: SALEOR_26 Create basic info variant - via edit variant page #e2e #product", async () => {
const variantName = `TC: SALEOR_26 - variant name - ${new Date().toISOString()}`;
await productPage.gotoExistingProductPage(PRODUCTS.productWithOneVariant.id);
@@ -67,7 +65,7 @@ test("TC: SALEOR_26 Create basic info variant - via edit variant page @e2e @prod
`New variant name: ${variantName} should be visible on the list`,
).toBeVisible();
});
-test("TC: SALEOR_27 Create full info variant - via edit variant page @e2e @product", async () => {
+test("TC: SALEOR_27 Create full info variant - via edit variant page #e2e #product", async () => {
const variantName = `TC: SALEOR_27 - variant name - ${new Date().toISOString()}`;
await productPage.gotoExistingProductPage(PRODUCTS.productWithOneVariant.id);
@@ -97,9 +95,13 @@ test("TC: SALEOR_27 Create full info variant - via edit variant page @e2e @produ
await variantsPage.clickSaveVariantButton();
await variantsPage.expectSuccessBanner();
});
-test("TC: SALEOR_44 As an admin I should be able to delete a several products @basic-regression @product @e2e", async () => {
+test("TC: SALEOR_44 As an admin I should be able to delete a several products @basic-regression #product #e2e", async () => {
await productPage.gotoProductListPage();
+
+ await productPage.searchAndFindRowIndexes("a product to be deleted via bulk");
await productPage.checkListRowsBasedOnContainingText(PRODUCTS.productsToBeBulkDeleted.names);
+
+ await productPage.clickBulkDeleteGridRowsButton();
await productPage.clickBulkDeleteButton();
await productPage.deleteProductDialog.clickDeleteButton();
await productPage.expectSuccessBanner();
@@ -110,13 +112,13 @@ test("TC: SALEOR_44 As an admin I should be able to delete a several products @b
`Given products: ${PRODUCTS.productsToBeBulkDeleted.names} should be deleted from the list`,
).toEqual([]);
});
-test("TC: SALEOR_45 As an admin I should be able to delete a single products @basic-regression @product @e2e", async () => {
+test("TC: SALEOR_45 As an admin I should be able to delete a single products @basic-regression #product #e2e", async () => {
await productPage.gotoExistingProductPage(
PRODUCTS.productWithOneVariantToBeDeletedFromDetails.id,
);
await productPage.clickDeleteProductButton();
await productPage.deleteProductDialog.clickDeleteButton();
- await productPage.expectSuccessBannerMessage("Product Removed");
+ await productPage.expectSuccessBanner({ message: "Product Removed" });
await productPage.waitForGrid();
await productPage.searchforProduct(PRODUCTS.productWithOneVariantToBeDeletedFromDetails.name);
await expect(
@@ -125,7 +127,7 @@ test("TC: SALEOR_45 As an admin I should be able to delete a single products @ba
}),
).not.toBeVisible();
});
-test("TC: SALEOR_46 As an admin, I should be able to update a product by uploading media, assigning channels, assigning tax, and adding a new variant @basic-regression @product @e2e", async () => {
+test("TC: SALEOR_46 As an admin, I should be able to update a product by uploading media, assigning channels, assigning tax, and adding a new variant @basic-regression #product #e2e", async () => {
const newVariantName = "variant 2";
await productPage.gotoExistingProductPage(PRODUCTS.singleProductTypeToBeUpdated.id);
@@ -162,7 +164,7 @@ test("TC: SALEOR_46 As an admin, I should be able to update a product by uploadi
"Newly added single image should be present",
).toEqual(1);
});
-test("TC: SALEOR_56 As an admin, I should be able to export products from single channel as CSV file @basic-regression @product @e2e", async () => {
+test("TC: SALEOR_56 As an admin, I should be able to export products from single channel as CSV file @basic-regression #product #e2e", async () => {
await productPage.gotoProductListPage();
await productPage.clickCogShowMoreButtonButton();
await productPage.clickExportButton();
@@ -172,12 +174,8 @@ test("TC: SALEOR_56 As an admin, I should be able to export products from single
await productPage.exportProductsDialog.clickExportAllProductsRadioButton();
await productPage.exportProductsDialog.clickSubmitButton();
await productPage.expectInfoBanner();
- await mailpitService.checkDoesUserReceivedExportedData(
- process.env.E2E_USER_NAME!,
- "Your exported products data is ready",
- );
});
-test("TC: SALEOR_57 As an admin, I should be able to search products on list view @basic-regression @product @e2e", async () => {
+test("TC: SALEOR_57 As an admin, I should be able to search products on list view @basic-regression #product #e2e", async () => {
await productPage.gotoProductListPage();
await productPage.searchAndFindRowIndexes(PRODUCTS.productToAddVariants.name);
await productPage.checkListRowsBasedOnContainingText([PRODUCTS.productToAddVariants.name]);
@@ -186,7 +184,7 @@ test("TC: SALEOR_57 As an admin, I should be able to search products on list vie
"There should be only one product visible on list",
).toEqual(1);
});
-test("TC: SALEOR_58 As an admin I should be able use pagination on product list view @basic-regression @product @e2e", async () => {
+test("TC: SALEOR_58 As an admin I should be able use pagination on product list view @basic-regression #product #e2e", async () => {
await productPage.gotoProductListPage();
const firstPageProductName = await productPage.getGridCellText(0, 0);
@@ -211,7 +209,7 @@ test("TC: SALEOR_58 As an admin I should be able use pagination on product list
`Product from first page: ${firstPageProductName} should be visible again`,
).toContainText(firstPageProductName);
});
-test("TC: SALEOR_59 As an admin I should be able to filter products by channel on product list view @basic-regression @product @e2e", async () => {
+test("TC: SALEOR_59 As an admin I should be able to filter products by channel on product list view @basic-regression #product #e2e", async () => {
await productPage.gotoProductListPage();
await productPage.searchAndFindRowIndexes(PRODUCTS.productAvailableOnlyInUsdChannel.name);
expect(
@@ -231,15 +229,13 @@ test("TC: SALEOR_59 As an admin I should be able to filter products by channel o
`Product: ${PRODUCTS.productAvailableOnlyInPlnChannel.name} should be visible on grid table`,
).toContainText(PRODUCTS.productAvailableOnlyInPlnChannel.name);
});
-test("TC: SALEOR_60 As an admin I should be able update existing variant @basic-regression @product @e2e", async () => {
+test("TC: SALEOR_60 As an admin I should be able update existing variant @basic-regression #product #e2e", async () => {
const variantName = `TC: SALEOR_60 - variant name - ${new Date().toISOString()}`;
const sku = `SALEOR_60-sku-${new Date().toISOString()}`;
- await productPage.waitForNetworkIdleAfterAction(() =>
- variantsPage.gotoExistingVariantPage(
- PRODUCTS.productWithVariantWhichWillBeUpdated.id,
- PRODUCTS.productWithVariantWhichWillBeUpdated.variantId,
- ),
+ await variantsPage.gotoExistingVariantPage(
+ PRODUCTS.productWithVariantWhichWillBeUpdated.id,
+ PRODUCTS.productWithVariantWhichWillBeUpdated.variantId,
);
await variantsPage.typeVariantName(variantName);
await variantsPage.clickMageChannelsButton();
@@ -264,12 +260,10 @@ test("TC: SALEOR_60 As an admin I should be able update existing variant @basic-
).toBeVisible();
await productPage.productImage.waitFor({ state: "visible" });
});
-test("TC: SALEOR_61 As an admin I should be able to delete existing variant @basic-regression @product @e2e", async () => {
- await productPage.waitForNetworkIdleAfterAction(() =>
- variantsPage.gotoExistingVariantPage(
- PRODUCTS.singleVariantDeleteProduct.productId,
- PRODUCTS.singleVariantDeleteProduct.variantId,
- ),
+test("TC: SALEOR_61 As an admin I should be able to delete existing variant @basic-regression #product #e2e", async () => {
+ await variantsPage.gotoExistingVariantPage(
+ PRODUCTS.singleVariantDeleteProduct.productId,
+ PRODUCTS.singleVariantDeleteProduct.variantId,
);
await variantsPage.clickDeleteVariantButton();
await variantsPage.deleteVariantDialog.clickDeleteVariantButton();
@@ -283,10 +277,8 @@ test("TC: SALEOR_61 As an admin I should be able to delete existing variant @bas
"Deleting last variant from variant details page should redirect to product page",
).toContain(PRODUCTS.singleVariantDeleteProduct.productId);
});
-test("TC: SALEOR_62 As an admin I should be able to bulk delete existing variants @basic-regression @product @e2e", async () => {
- await productPage.waitForNetworkIdleAfterAction(() =>
- productPage.gotoExistingProductPage(PRODUCTS.multipleVariantsBulkDeleteProduct.productId),
- );
+test("TC: SALEOR_62 As an admin I should be able to bulk delete existing variants @basic-regression #product #e2e", async () => {
+ await productPage.gotoExistingProductPage(PRODUCTS.multipleVariantsBulkDeleteProduct.productId);
await productPage.waitForGrid();
await productPage.gridCanvas.scrollIntoViewIfNeeded();
await productPage.clickGridCell(0, 0);
diff --git a/playwright/tests/productTypes.spec.ts b/playwright/tests/productTypes.spec.ts
index 261e3907dd6..595e9807612 100644
--- a/playwright/tests/productTypes.spec.ts
+++ b/playwright/tests/productTypes.spec.ts
@@ -1,13 +1,14 @@
import { PRODUCT_TYPES } from "@data/e2eTestData";
import { ProductTypePage } from "@pages/productTypePage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
import * as faker from "faker";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
const productTypeName = `e2e-product-type-${faker.datatype.number()}`;
-test("TC: SALEOR_1 Create basic product type @e2e @product-type", async ({ page }) => {
+test("TC: SALEOR_1 Create basic product type #e2e #product-type", async ({ page }) => {
const productTypePage = new ProductTypePage(page);
await productTypePage.gotoProductTypeListPage();
@@ -18,7 +19,7 @@ test("TC: SALEOR_1 Create basic product type @e2e @product-type", async ({ page
await productTypePage.expectSuccessBanner();
await expect(productTypePage.nameInput).toHaveValue(productTypeName);
});
-test("TC: SALEOR_2 Create gift card product type @e2e @product-type", async ({ page }) => {
+test("TC: SALEOR_2 Create gift card product type #e2e #product-type", async ({ page }) => {
const productTypePage = new ProductTypePage(page);
await productTypePage.gotoAddProductTypePage();
@@ -28,7 +29,7 @@ test("TC: SALEOR_2 Create gift card product type @e2e @product-type", async ({ p
await productTypePage.expectSuccessBanner();
await expect(productTypePage.nameInput).toHaveValue(productTypeName);
});
-test("TC: SALEOR_184 As a admin I can edit product type @e2e @product-type", async ({ page }) => {
+test("TC: SALEOR_184 As a admin I can edit product type #e2e #product-type", async ({ page }) => {
const productTypePage = new ProductTypePage(page);
const updatedProductTypeName = `updated-e2e-product-type-${faker.datatype.number()}`;
@@ -41,7 +42,7 @@ test("TC: SALEOR_184 As a admin I can edit product type @e2e @product-type", asy
await expect(productTypePage.shippingWeightInput).toHaveValue("10");
await expect(productTypePage.nameInput).toHaveValue(updatedProductTypeName);
});
-test("TC: SALEOR_185 As a admin user I can delete product type with assigned products @e2e @product-type", async ({
+test("TC: SALEOR_185 As a admin user I can delete product type with assigned products #e2e #product-type", async ({
page,
}) => {
const productTypePage = new ProductTypePage(page);
@@ -58,7 +59,7 @@ test("TC: SALEOR_185 As a admin user I can delete product type with assigned pro
});
await expect(productTypePage.productTypeList).not.toContainText(productTypeName);
});
-test("TC: SALEOR_186 As a admin user I can delete several product types @e2e @product-type", async ({
+test("TC: SALEOR_186 As a admin user I can delete several product types #e2e #product-type", async ({
page,
}) => {
const productTypePage = new ProductTypePage(page);
diff --git a/playwright/tests/shippingMethods.spec.ts b/playwright/tests/shippingMethods.spec.ts
index 19d2288aa73..df17d5f6807 100644
--- a/playwright/tests/shippingMethods.spec.ts
+++ b/playwright/tests/shippingMethods.spec.ts
@@ -1,9 +1,10 @@
import { CHANNELS, SHIPPING_METHODS, WAREHOUSES } from "@data/e2eTestData";
import { ShippingMethodsPage } from "@pages/shippingMethodsPage";
import { ShippingRatesPage } from "@pages/shippingRatesPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let shippingMethodsPage: ShippingMethodsPage;
let shippingRatesPage: ShippingRatesPage;
@@ -13,7 +14,7 @@ test.beforeEach(({ page }) => {
shippingMethodsPage = new ShippingMethodsPage(page);
shippingRatesPage = new ShippingRatesPage(page);
});
-test("TC: SALEOR_31 Create basic shipping method @shipping-method @e2e", async () => {
+test("TC: SALEOR_31 Create basic shipping method #shipping-method #e2e", async () => {
await shippingMethodsPage.gotoListView();
await shippingMethodsPage.clickCreateShippingZoneButton();
await shippingMethodsPage.typeShippingZoneName();
@@ -29,9 +30,10 @@ test("TC: SALEOR_31 Create basic shipping method @shipping-method @e2e", async (
await shippingMethodsPage.saveShippingZone();
await shippingMethodsPage.expectSuccessBanner();
});
-test("TC: SALEOR_32 Add price rate to shipping method - with excluded zip codes and excluded product @shipping-method @e2e", async () => {
+test("TC: SALEOR_32 Add price rate to shipping method - with excluded zip codes and excluded product #shipping-method #e2e", async () => {
await shippingMethodsPage.gotoExistingShippingMethod(
SHIPPING_METHODS.shippingMethodWithoutRates.id,
+ SHIPPING_METHODS.shippingMethodWithoutRates.name,
);
await shippingMethodsPage.clickAddPriceRateButton();
await shippingMethodsPage.rightSideDetailsPage.selectTaxIndex(1);
@@ -43,16 +45,17 @@ test("TC: SALEOR_32 Add price rate to shipping method - with excluded zip codes
await shippingRatesPage.typePrice();
await shippingRatesPage.addPostalCodeRange();
await shippingRatesPage.clickSaveButton();
- await shippingRatesPage.basePage.expectSuccessBanner();
+ await shippingRatesPage.expectSuccessBanner();
await shippingRatesPage.addExcludedProduct("Bean Juice");
- await shippingRatesPage.basePage.expectSuccessBanner();
+ await shippingRatesPage.expectSuccessBanner();
await shippingRatesPage.excludedProductsRows.waitFor({ state: "visible" });
await expect(shippingRatesPage.excludedProductsRows).toContainText("Bean Juice");
await expect(await shippingRatesPage.assignedPostalCodesRows.count()).toEqual(1);
});
-test("TC: SALEOR_33 Add weight rate to shipping method - with included zip codes and excluded product @shipping-method @e2e", async () => {
+test("TC: SALEOR_33 Add weight rate to shipping method - with included zip codes and excluded product #shipping-method #e2e", async () => {
await shippingMethodsPage.gotoExistingShippingMethod(
SHIPPING_METHODS.shippingMethodWithoutRates.id,
+ SHIPPING_METHODS.shippingMethodWithoutRates.name,
);
await shippingMethodsPage.clickAddWeightRateButton();
await shippingMethodsPage.rightSideDetailsPage.selectTaxIndex(1);
@@ -65,15 +68,16 @@ test("TC: SALEOR_33 Add weight rate to shipping method - with included zip codes
await shippingRatesPage.clickIncludePostalCodesRadioButton();
await shippingRatesPage.addPostalCodeRange();
await shippingRatesPage.clickSaveButton();
- await shippingRatesPage.basePage.expectSuccessBanner();
+ await shippingRatesPage.expectSuccessBanner();
await shippingRatesPage.addExcludedProduct("Bean Juice");
- await shippingRatesPage.basePage.expectSuccessBanner();
+ await shippingRatesPage.expectSuccessBanner();
await shippingRatesPage.excludedProductsRows.waitFor({ state: "visible" });
await expect(shippingRatesPage.excludedProductsRows).toContainText("Bean Juice");
});
-test("TC: SALEOR_34 Delete a single shipping rate from the shipping zone details page @shipping-method @e2e", async () => {
+test("TC: SALEOR_34 Delete a single shipping rate from the shipping zone details page #shipping-method #e2e", async () => {
await shippingMethodsPage.gotoExistingShippingMethod(
SHIPPING_METHODS.shippingMethodWithRatesToBeDeleted.id,
+ SHIPPING_METHODS.shippingMethodWithRatesToBeDeleted.name,
);
await expect(shippingMethodsPage.pageHeader).toBeVisible();
@@ -87,7 +91,7 @@ test("TC: SALEOR_34 Delete a single shipping rate from the shipping zone details
await expect(shippingMethodsPage.priceBasedRatesSection).toContainText("No shipping rates found");
await expect(shippingMethodsPage.priceBasedRatesSection).not.toContainText(priceBasedRate);
});
-test("TC: SALEOR_35 Delete a single shipping rate from its details page @shipping-method @e2e", async () => {
+test("TC: SALEOR_35 Delete a single shipping rate from its details page #shipping-method #e2e", async () => {
const shippingMethodId = SHIPPING_METHODS.shippingMethodWithRatesToBeDeleted.id;
const shippingRateId =
SHIPPING_METHODS.shippingMethodWithRatesToBeDeleted.rates.weightBasedRateToBeDeleted.id;
@@ -103,7 +107,7 @@ test("TC: SALEOR_35 Delete a single shipping rate from its details page @shippin
);
await expect(shippingMethodsPage.weightBasedRatesSection).not.toContainText(weightBasedRate);
});
-test("TC: SALEOR_36 Delete shipping zones in bulk @shipping-method @e2e", async () => {
+test("TC: SALEOR_36 Delete shipping zones in bulk #shipping-method #e2e", async () => {
const shippingZone1 = SHIPPING_METHODS.shippingMethodToBeBulkDeleted1.name;
const shippingZone2 = SHIPPING_METHODS.shippingMethodToBeBulkDeleted2.name;
const shippingZone3 = SHIPPING_METHODS.shippingMethodToBeBulkDeleted3.name;
@@ -118,11 +122,12 @@ test("TC: SALEOR_36 Delete shipping zones in bulk @shipping-method @e2e", async
await shippingMethodsPage.deleteShippingMethodDialog.clickDeleteButton();
await shippingMethodsPage.expectSuccessBanner();
});
-test("TC: SALEOR_37 Update a shipping method @shipping-method @e2e", async () => {
+test("TC: SALEOR_37 Update a shipping method #shipping-method #e2e", async () => {
const channelSection = shippingMethodsPage.rightSideDetailsPage.channelSection;
- const warehouseSection = shippingMethodsPage.rightSideDetailsPage.warehouseSection;
const alreadyAssignedChannels = [CHANNELS.channelUSD.name];
const channelsToBeAssigned = [CHANNELS.channelPLN.name];
+
+ const warehouseSection = shippingMethodsPage.rightSideDetailsPage.warehouseSection;
const alreadyAssignedWarehouses = [
WAREHOUSES.warehouseOceania.name,
WAREHOUSES.warehouseAfrica.name,
@@ -134,25 +139,35 @@ test("TC: SALEOR_37 Update a shipping method @shipping-method @e2e", async () =>
await shippingMethodsPage.gotoExistingShippingMethod(
SHIPPING_METHODS.shippingMethodToBeUpdated.id,
+ SHIPPING_METHODS.shippingMethodToBeUpdated.name,
+ );
+
+ await shippingMethodsPage.rightSideDetailsPage.expectOptionsSelected(
+ channelSection,
+ alreadyAssignedChannels,
);
await shippingMethodsPage.rightSideDetailsPage.clickChannelsSelectShippingPage();
await shippingMethodsPage.rightSideDetailsPage.selectSingleChannelShippingPage();
+
+ await shippingMethodsPage.rightSideDetailsPage.expectOptionsSelected(
+ warehouseSection,
+ alreadyAssignedWarehouses,
+ );
await shippingMethodsPage.rightSideDetailsPage.clickWarehouseSelectShippingPage();
await shippingMethodsPage.rightSideDetailsPage.typeAndSelectMultipleWarehousesShippingPage(
warehousesToBeAssigned,
);
+
await shippingMethodsPage.saveShippingZone();
await shippingMethodsPage.expectSuccessBanner();
- const updatedChannelsList = alreadyAssignedChannels.concat(channelsToBeAssigned);
+ const updatedChannelsList = [...alreadyAssignedChannels, ...channelsToBeAssigned];
+ const updatedWarehousesList = [...alreadyAssignedWarehouses, ...warehousesToBeAssigned];
await shippingMethodsPage.rightSideDetailsPage.expectOptionsSelected(
channelSection,
updatedChannelsList,
);
-
- const updatedWarehousesList = alreadyAssignedWarehouses.concat(warehousesToBeAssigned);
-
await shippingMethodsPage.rightSideDetailsPage.expectOptionsSelected(
warehouseSection,
updatedWarehousesList,
diff --git a/playwright/tests/singlePermissions/apps.spec.ts b/playwright/tests/singlePermissions/apps.spec.ts
index efa1ab1567e..a2eee154e10 100644
--- a/playwright/tests/singlePermissions/apps.spec.ts
+++ b/playwright/tests/singlePermissions/apps.spec.ts
@@ -1,9 +1,10 @@
import { AppsPage } from "@pages/appsPage";
import { HomePage } from "@pages/homePage";
import { MainMenuPage } from "@pages/mainMenuPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/app.json" });
+test.use({ permissionName: "app" });
let mainMenuPage: MainMenuPage;
let appsPage: AppsPage;
@@ -14,7 +15,7 @@ test.beforeEach(async ({ page }) => {
appsPage = new AppsPage(page);
home = new HomePage(page);
});
-test("TC: SALEOR_10 User should be able to navigate to apps list as a staff member using APP permission @e2e", async () => {
+test("TC: SALEOR_10 User should be able to navigate to apps list as a staff member using APP permission #e2e", async () => {
await home.goto();
await home.welcomeMessage.waitFor({ state: "visible", timeout: 30000 });
await mainMenuPage.openApps();
diff --git a/playwright/tests/singlePermissions/channelsWebhooks.spec.ts b/playwright/tests/singlePermissions/channelsWebhooks.spec.ts
index 888910af582..e70fc811aee 100644
--- a/playwright/tests/singlePermissions/channelsWebhooks.spec.ts
+++ b/playwright/tests/singlePermissions/channelsWebhooks.spec.ts
@@ -3,9 +3,10 @@ import { ConfigurationPage } from "@pages/configurationPage";
import { HomePage } from "@pages/homePage";
import { MainMenuPage } from "@pages/mainMenuPage";
import { WebhooksEventsPage } from "@pages/webhooksEventsPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/channel.json" });
+test.use({ permissionName: "channel" });
let channelPage: ChannelPage;
let mainMenuPage: MainMenuPage;
@@ -29,14 +30,14 @@ test.beforeEach(async ({ page }) => {
await home.goto();
await home.welcomeMessage.waitFor({ state: "visible", timeout: 30000 });
});
-test("TC: SALEOR_11 User should be able to navigate to channel list as a staff member using CHANNEL permission @e2e", async () => {
+test("TC: SALEOR_11 User should be able to navigate to channel list as a staff member using CHANNEL permission #e2e", async () => {
await mainMenuPage.openConfiguration();
await mainMenuPage.expectMenuItemsCount(3);
await configurationPage.openChannels();
await expect(channelPage.createChannelButton).toBeVisible();
await expect(channelPage.deleteChannelButton.first()).toBeVisible();
});
-test("TC: SALEOR_12 User should be able to navigate to webhooks and events as a staff member using CHANNEL permission @e2e", async () => {
+test("TC: SALEOR_12 User should be able to navigate to webhooks and events as a staff member using CHANNEL permission #e2e", async () => {
await configurationPage.goToConfigurationView();
await mainMenuPage.expectMenuItemsCount(3);
await configurationPage.openWebhooksAndEvents();
diff --git a/playwright/tests/singlePermissions/contentPage.spec.ts b/playwright/tests/singlePermissions/contentPage.spec.ts
index e0bd80af930..01c85db622d 100644
--- a/playwright/tests/singlePermissions/contentPage.spec.ts
+++ b/playwright/tests/singlePermissions/contentPage.spec.ts
@@ -4,9 +4,10 @@ import { ContentPage } from "@pages/contentPage";
import { HomePage } from "@pages/homePage";
import { MainMenuPage } from "@pages/mainMenuPage";
import { PageTypesPage } from "@pages/pageTypesPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/page.json" });
+test.use({ permissionName: "page" });
let basePage: BasePage;
let mainMenuPage: MainMenuPage;
@@ -33,13 +34,13 @@ test.beforeEach(async ({ page }) => {
await home.goto();
await home.welcomeMessage.waitFor({ state: "visible", timeout: 30000 });
});
-test("TC: SALEOR_14 User should be able to navigate to content list as a staff member using CONTENT aka PAGE permission @e2e", async () => {
+test("TC: SALEOR_14 User should be able to navigate to content list as a staff member using CONTENT aka PAGE permission #e2e", async () => {
await mainMenuPage.openContent();
await expect(contentPage.createContentButton).toBeVisible();
await mainMenuPage.expectMenuItemsCount(4);
await basePage.expectGridToBeAttached();
});
-test("TC: SALEOR_15 User should be able to navigate to page types list as a staff member using CONTENT aka PAGE permission @e2e", async () => {
+test("TC: SALEOR_15 User should be able to navigate to page types list as a staff member using CONTENT aka PAGE permission #e2e", async () => {
await configurationPage.goToConfigurationView();
await expect(configurationPage.taxesButton).toBeVisible();
await expect(configurationPage.pageTypesButton).toBeVisible();
diff --git a/playwright/tests/singlePermissions/customer.spec.ts b/playwright/tests/singlePermissions/customer.spec.ts
index 468645947aa..fb6eb4ebc48 100644
--- a/playwright/tests/singlePermissions/customer.spec.ts
+++ b/playwright/tests/singlePermissions/customer.spec.ts
@@ -2,10 +2,12 @@ import { URL_LIST } from "@data/url";
import { BasePage } from "@pages/basePage";
import { CustomersPage } from "@pages/customersPage";
import { MainMenuPage } from "@pages/mainMenuPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/customer.json" });
-test("TC: SALEOR_13 User should be able to navigate to customer list as a staff member using CUSTOMER permission @e2e", async ({
+test.use({ permissionName: "customer" });
+
+test("TC: SALEOR_13 User should be able to navigate to customer list as a staff member using CUSTOMER permission #e2e", async ({
page,
}) => {
const basePage = new BasePage(page);
diff --git a/playwright/tests/singlePermissions/discount.spec.ts b/playwright/tests/singlePermissions/discount.spec.ts
index 215981e3421..1cdd5b361e6 100644
--- a/playwright/tests/singlePermissions/discount.spec.ts
+++ b/playwright/tests/singlePermissions/discount.spec.ts
@@ -3,9 +3,10 @@ import { DiscountsPage } from "@pages/discountsPage";
import { HomePage } from "@pages/homePage";
import { MainMenuPage } from "@pages/mainMenuPage";
import { VouchersPage } from "@pages/vouchersPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/discount.json" });
+test.use({ permissionName: "discount" });
let mainMenuPage: MainMenuPage;
let home: HomePage;
@@ -29,13 +30,13 @@ test.beforeEach(async ({ page }) => {
await home.goto();
await home.welcomeMessage.waitFor({ state: "visible", timeout: 30000 });
});
-test("TC: SALEOR_6 User should be able to navigate to discount list as a staff member using DISCOUNTS permission @e2e", async () => {
+test("TC: SALEOR_6 User should be able to navigate to discount list as a staff member using DISCOUNTS permission #e2e", async () => {
await mainMenuPage.openDiscounts();
await basePage.waitForGrid();
await expect(discountsPage.createDiscountButton).toBeVisible();
await mainMenuPage.expectMenuItemsCount(4);
});
-test("TC: SALEOR_7 User should be able to navigate to voucher list as a staff member using DISCOUNTS permission @e2e", async () => {
+test("TC: SALEOR_7 User should be able to navigate to voucher list as a staff member using DISCOUNTS permission #e2e", async () => {
await mainMenuPage.openVouchers();
await basePage.waitForGrid();
await expect(vouchersPage.createVoucherButton).toBeVisible();
diff --git a/playwright/tests/singlePermissions/orders.spec.ts b/playwright/tests/singlePermissions/orders.spec.ts
index f878143fd50..f3d953653da 100644
--- a/playwright/tests/singlePermissions/orders.spec.ts
+++ b/playwright/tests/singlePermissions/orders.spec.ts
@@ -2,9 +2,10 @@ import { DraftOrdersPage } from "@pages/draftOrdersPage";
import { HomePage } from "@pages/homePage";
import { MainMenuPage } from "@pages/mainMenuPage";
import { OrdersPage } from "@pages/ordersPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/order.json" });
+test.use({ permissionName: "order" });
let home: HomePage;
let draftOrdersPage: DraftOrdersPage;
@@ -20,13 +21,13 @@ test.beforeEach(async ({ page }) => {
await home.goto();
await home.welcomeMessage.waitFor({ state: "visible", timeout: 30000 });
});
-test("TC: SALEOR_8 User should be able to navigate to order list as a staff member using ORDER permission @e2e", async () => {
+test("TC: SALEOR_8 User should be able to navigate to order list as a staff member using ORDER permission #e2e", async () => {
await mainMenuPage.openOrders();
await expect(ordersPage.createOrderButton).toBeVisible();
await ordersPage.expectGridToBeAttached();
await mainMenuPage.expectMenuItemsCount(4);
});
-test("TC: SALEOR_9 User should be able to navigate to draft list as a staff member using ORDER permission @e2e", async () => {
+test("TC: SALEOR_9 User should be able to navigate to draft list as a staff member using ORDER permission #e2e", async () => {
await mainMenuPage.openDrafts();
await expect(draftOrdersPage.createDraftOrderButton).toBeVisible();
await draftOrdersPage.expectGridToBeAttached();
diff --git a/playwright/tests/singlePermissions/plugins.spec.ts b/playwright/tests/singlePermissions/plugins.spec.ts
index aae0c39df10..80a27049840 100644
--- a/playwright/tests/singlePermissions/plugins.spec.ts
+++ b/playwright/tests/singlePermissions/plugins.spec.ts
@@ -1,9 +1,10 @@
import { ConfigurationPage } from "@pages/configurationPage";
import { MainMenuPage } from "@pages/mainMenuPage";
import { PluginsPage } from "@pages/pluginsPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/plugin.json" });
+test.use({ permissionName: "plugin" });
let configurationPage: ConfigurationPage;
let mainMenuPage: MainMenuPage;
@@ -14,7 +15,7 @@ test.beforeEach(({ page }) => {
mainMenuPage = new MainMenuPage(page);
pluginsPage = new PluginsPage(page);
});
-test("TC: SALEOR_16 User should be able to navigate to plugin list as a staff member using PLUGINS permission @e2e", async () => {
+test("TC: SALEOR_16 User should be able to navigate to plugin list as a staff member using PLUGINS permission #e2e", async () => {
await configurationPage.goToConfigurationView();
await configurationPage.openPlugins();
await expect(pluginsPage.pluginRow.first()).toBeVisible();
diff --git a/playwright/tests/singlePermissions/product.spec.ts b/playwright/tests/singlePermissions/product.spec.ts
index 09d1acba260..809ef4b7bf7 100644
--- a/playwright/tests/singlePermissions/product.spec.ts
+++ b/playwright/tests/singlePermissions/product.spec.ts
@@ -3,9 +3,10 @@ import { CollectionsPage } from "@pages/collectionsPage";
import { HomePage } from "@pages/homePage";
import { MainMenuPage } from "@pages/mainMenuPage";
import { ProductPage } from "@pages/productPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/product.json" });
+test.use({ permissionName: "product" });
let home: HomePage;
let mainMenuPage: MainMenuPage;
@@ -20,7 +21,7 @@ test.beforeEach(({ page }) => {
categoriesPage = new CategoriesPage(page);
collectionsPage = new CollectionsPage(page);
});
-test("TC: SALEOR_23 User should be able to navigate to product list as a staff member using PRODUCT permission @e2e", async () => {
+test("TC: SALEOR_23 User should be able to navigate to product list as a staff member using PRODUCT permission #e2e", async () => {
await home.goto();
await home.welcomeMessage.waitFor({ state: "visible", timeout: 30000 });
await mainMenuPage.openProducts();
@@ -28,7 +29,7 @@ test("TC: SALEOR_23 User should be able to navigate to product list as a staff m
await mainMenuPage.expectMenuItemsCount(6);
await productPage.expectGridToBeAttached();
});
-test("TC: SALEOR_24 User should be able to navigate to collections list as a staff member using PRODUCT permission @e2e", async () => {
+test("TC: SALEOR_24 User should be able to navigate to collections list as a staff member using PRODUCT permission #e2e", async () => {
await home.goto();
await home.welcomeMessage.waitFor({ state: "visible", timeout: 30000 });
await mainMenuPage.openCollections();
@@ -36,7 +37,7 @@ test("TC: SALEOR_24 User should be able to navigate to collections list as a sta
await mainMenuPage.expectMenuItemsCount(6);
await collectionsPage.expectGridToBeAttached();
});
-test("TC: SALEOR_25 User should be able to navigate to categories list as a staff member using PRODUCT permission @e2e", async () => {
+test("TC: SALEOR_25 User should be able to navigate to categories list as a staff member using PRODUCT permission #e2e", async () => {
await home.goto();
await home.welcomeMessage.waitFor({ state: "visible", timeout: 30000 });
await mainMenuPage.openCategories();
diff --git a/playwright/tests/singlePermissions/productType.spec.ts b/playwright/tests/singlePermissions/productType.spec.ts
index c08815159aa..493b55bf8a8 100644
--- a/playwright/tests/singlePermissions/productType.spec.ts
+++ b/playwright/tests/singlePermissions/productType.spec.ts
@@ -2,10 +2,12 @@ import { URL_LIST } from "@data/url";
import { ConfigurationPage } from "@pages/configurationPage";
import { MainMenuPage } from "@pages/mainMenuPage";
import { ProductTypePage } from "@pages/productTypePage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/productTypeAndAttribute.json" });
-test("TC: SALEOR_17 User should be able to navigate to product type list as a staff member using PRODUCT TYPE permission @e2e", async ({
+test.use({ permissionName: "productTypeAndAttribute" });
+
+test("TC: SALEOR_17 User should be able to navigate to product type list as a staff member using PRODUCT TYPE permission #e2e", async ({
page,
}) => {
const configurationPage = new ConfigurationPage(page);
diff --git a/playwright/tests/singlePermissions/readonlyAppAccess.spec.ts b/playwright/tests/singlePermissions/readonlyAppAccess.spec.ts
index c7a1778a096..c5f5e827be9 100644
--- a/playwright/tests/singlePermissions/readonlyAppAccess.spec.ts
+++ b/playwright/tests/singlePermissions/readonlyAppAccess.spec.ts
@@ -4,14 +4,16 @@ import { AppDetailsPage } from "@pages/appDetailsPage";
import { AppPage } from "@pages/appPageThirdparty";
import { AppsPage } from "@pages/appsPage";
import { MainMenuPage } from "@pages/mainMenuPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
const permissionToExclude = "app";
const permissionList = permissions.filter(item => item !== permissionToExclude);
for (const permission of permissionList) {
- test.use({ storageState: `playwright/.auth/${permission}.json` });
- test(`TC: SALEOR_131 User with ${permission} permissions should have readonly access to Apps @e2e @appp`, async ({
+ test.use({ permissionName: permission });
+
+ test(`TC: SALEOR_131 User with ${permission} permissions should have readonly access to Apps #e2e #apps`, async ({
page,
}) => {
const mainMenuPage = new MainMenuPage(page);
@@ -20,23 +22,21 @@ for (const permission of permissionList) {
const appDetailsPage = new AppDetailsPage(page);
await page.goto(URL_LIST.homePage);
- await mainMenuPage.waitForNetworkIdleAfterAction(() => mainMenuPage.openApps());
- await mainMenuPage.waitForDOMToFullyLoad();
+ await mainMenuPage.openApps();
+ await appsPage.waitForContentLoad();
+
await expect(appsPage.installExternalAppButton).not.toBeVisible();
- const appLists = [
- appsPage.installedAppsList,
- appsPage.availableAppsList,
- appsPage.upcomingAppsList,
- ];
+ const appLists = [appsPage.installedAppsList, appsPage.availableAppsList];
for (const appList of appLists) {
- await appsPage.waitForDOMToFullyLoad();
await expect(appList).toBeVisible();
}
- await appsPage.waitForNetworkIdleAfterAction(() => appsPage.installedAppRow.first().click());
+
+ await appsPage.installedAppRow.first().click();
await expect(appPage.appSettingsButton).toBeVisible();
- await appsPage.waitForNetworkIdleAfterAction(() => appPage.appSettingsButton.click());
+ await appPage.appSettingsButton.click();
+ await appPage.waitContentLoad();
await expect(appDetailsPage.appDetailsSection).toBeVisible();
const buttons = [
@@ -46,10 +46,6 @@ for (const permission of permissionList) {
];
for (const button of buttons) {
- await button.waitFor({
- state: "visible",
- timeout: 10000,
- });
await expect(button).toBeDisabled();
}
});
diff --git a/playwright/tests/singlePermissions/settingsConfiguration.spec.ts b/playwright/tests/singlePermissions/settingsConfiguration.spec.ts
index 6085397df4e..2a63892fe18 100644
--- a/playwright/tests/singlePermissions/settingsConfiguration.spec.ts
+++ b/playwright/tests/singlePermissions/settingsConfiguration.spec.ts
@@ -2,10 +2,12 @@ import { URL_LIST } from "@data/url";
import { ConfigurationPage } from "@pages/configurationPage";
import { MainMenuPage } from "@pages/mainMenuPage";
import { SiteSettingsPage } from "@pages/siteSettingsPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/settings.json" });
-test("TC: SALEOR_18 User should be able to navigate to configuration as a staff member using SETTINGS permission @e2e", async ({
+test.use({ permissionName: "settings" });
+
+test("TC: SALEOR_18 User should be able to navigate to configuration as a staff member using SETTINGS permission #e2e", async ({
page,
}) => {
const mainMenuPage = new MainMenuPage(page);
diff --git a/playwright/tests/singlePermissions/shipping.spec.ts b/playwright/tests/singlePermissions/shipping.spec.ts
index 1d493cf78fd..fe51f9bed44 100644
--- a/playwright/tests/singlePermissions/shipping.spec.ts
+++ b/playwright/tests/singlePermissions/shipping.spec.ts
@@ -2,10 +2,12 @@ import { URL_LIST } from "@data/url";
import { ConfigurationPage } from "@pages/configurationPage";
import { MainMenuPage } from "@pages/mainMenuPage";
import { ShippingMethodsPage } from "@pages/shippingMethodsPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/shipping.json" });
-test("TC: SALEOR_21 User should be able to navigate to shipping zones page as a staff member using SHIPPING permission @e2e", async ({
+test.use({ permissionName: "shipping" });
+
+test("TC: SALEOR_21 User should be able to navigate to shipping zones page as a staff member using SHIPPING permission #e2e", async ({
page,
}) => {
const mainMenuPage = new MainMenuPage(page);
diff --git a/playwright/tests/singlePermissions/staffMembers.spec.ts b/playwright/tests/singlePermissions/staffMembers.spec.ts
index 5f1df45fee8..3d363f5bbc9 100644
--- a/playwright/tests/singlePermissions/staffMembers.spec.ts
+++ b/playwright/tests/singlePermissions/staffMembers.spec.ts
@@ -2,9 +2,10 @@ import { ConfigurationPage } from "@pages/configurationPage";
import { MainMenuPage } from "@pages/mainMenuPage";
import { PermissionGroupsPage } from "@pages/permissionGroupsPage";
import { StaffMembersPage } from "@pages/staffMembersPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/staff.json" });
+test.use({ permissionName: "staff" });
let staffMembersPage: StaffMembersPage;
let mainMenuPage: MainMenuPage;
@@ -19,13 +20,13 @@ test.beforeEach(async ({ page, request }) => {
await configurationPage.goToConfigurationView();
await configurationPage.waitForDOMToFullyLoad();
});
-test("TC: SALEOR_19 User should be able to navigate to staff members list page as a staff member using STAFF permission @e2e", async () => {
+test("TC: SALEOR_19 User should be able to navigate to staff members list page as a staff member using STAFF permission #e2e", async () => {
await configurationPage.openStaffMembers();
await expect(staffMembersPage.inviteStaffMembersButton).toBeVisible();
await mainMenuPage.expectMenuItemsCount(3);
await staffMembersPage.expectGridToBeAttached();
});
-test("TC: SALEOR_20 User should be able to navigate to permission group list page as a staff member using STAFF permission @e2e", async () => {
+test("TC: SALEOR_20 User should be able to navigate to permission group list page as a staff member using STAFF permission #e2e", async () => {
await configurationPage.openPermissionGroups();
await expect(permissionGroupsPage.createPermissionGroupButton).toBeVisible();
await mainMenuPage.expectMenuItemsCount(3);
diff --git a/playwright/tests/singlePermissions/translations.spec.ts b/playwright/tests/singlePermissions/translations.spec.ts
index ba5d44cb6ce..77b5a9ec38c 100644
--- a/playwright/tests/singlePermissions/translations.spec.ts
+++ b/playwright/tests/singlePermissions/translations.spec.ts
@@ -1,10 +1,12 @@
import { URL_LIST } from "@data/url";
import { BasePage } from "@pages/basePage";
import { MainMenuPage } from "@pages/mainMenuPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/translations.json" });
-test("TC: SALEOR_22 User should be able to navigate to translations page as a staff member using TRANSLATION permission @e2e", async ({
+test.use({ permissionName: "translations" });
+
+test("TC: SALEOR_22 User should be able to navigate to translations page as a staff member using TRANSLATION permission #e2e", async ({
page,
}) => {
const mainMenuPage = new MainMenuPage(page);
diff --git a/playwright/tests/siteSettings.spec.ts b/playwright/tests/siteSettings.spec.ts
index 65902db8964..008b86b3ff5 100644
--- a/playwright/tests/siteSettings.spec.ts
+++ b/playwright/tests/siteSettings.spec.ts
@@ -1,15 +1,16 @@
import { SiteSettingsPage } from "@pages/siteSettingsPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
import faker from "faker";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let siteSettingsPage: SiteSettingsPage;
test.beforeEach(({ page }) => {
siteSettingsPage = new SiteSettingsPage(page);
});
-test("TC: SALEOR_132 Should be able to update site settings", async () => {
+test("TC: SALEOR_132 Should be able to update site settings #e2e", async () => {
const companyName = faker.company.companyName();
await siteSettingsPage.gotoSiteSettings();
diff --git a/playwright/tests/staffMemberActivation.spec.ts b/playwright/tests/staffMemberActivation.spec.ts
new file mode 100644
index 00000000000..5acbf62f65b
--- /dev/null
+++ b/playwright/tests/staffMemberActivation.spec.ts
@@ -0,0 +1,52 @@
+import { BasicApiService } from "@api/basics";
+import { USERS } from "@data/e2eTestData";
+import { ConfigurationPage } from "@pages/configurationPage";
+import { PermissionGroupsPage } from "@pages/permissionGroupsPage";
+import { StaffMembersPage } from "@pages/staffMembersPage";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
+
+test.use({ permissionName: "admin" });
+
+test.describe.configure({ mode: "serial" });
+
+let staffMembersPage: StaffMembersPage;
+let config: ConfigurationPage;
+let permissionGroupsPage: PermissionGroupsPage;
+let basicApiService: BasicApiService;
+
+test.beforeEach(async ({ page, request }) => {
+ staffMembersPage = new StaffMembersPage(page, request);
+ config = new ConfigurationPage(page);
+ permissionGroupsPage = new PermissionGroupsPage(page);
+ basicApiService = new BasicApiService(request);
+});
+test("TC: SALEOR_137 Admin User should be able to deactivate other user #e2e #staff-members", async () => {
+ await staffMembersPage.goToStaffDetailsPage(USERS.userToBeDeactivated.id);
+ await staffMembersPage.clickIsActiveCheckbox();
+ await staffMembersPage.clickSaveButton();
+ await staffMembersPage.basePage.expectSuccessBanner();
+ expect(await staffMembersPage.isActiveCheckbox.isChecked()).toEqual(false);
+
+ const loginViaApiDeactivatedUserResponse = await basicApiService.logInUserViaApi({
+ email: USERS.userToBeDeactivated.email,
+ password: process.env.E2E_PERMISSIONS_USERS_PASSWORD!,
+ });
+
+ expect(loginViaApiDeactivatedUserResponse.data.tokenCreate.errors[0].code).toEqual("INACTIVE");
+});
+test("TC: SALEOR_38 Admin User should be able to activate other user #e2e #staff-members", async () => {
+ await staffMembersPage.goToStaffDetailsPage(USERS.userToBeActivated.id);
+ await staffMembersPage.clickIsActiveCheckbox();
+ await staffMembersPage.clickSaveButton();
+ await staffMembersPage.basePage.expectSuccessBanner();
+ expect(await staffMembersPage.isActiveCheckbox.isChecked()).toEqual(true);
+
+ const loginViaApiDeactivatedUserResponse = await basicApiService.logInUserViaApi({
+ email: USERS.userToBeActivated.email,
+ password: process.env.E2E_PERMISSIONS_USERS_PASSWORD!,
+ });
+
+ expect(loginViaApiDeactivatedUserResponse.data.tokenCreate.errors).toEqual([]);
+ expect(loginViaApiDeactivatedUserResponse.data.tokenCreate.token).not.toEqual(null);
+});
diff --git a/playwright/tests/staffMembers.spec.ts b/playwright/tests/staffMembers.spec.ts
index 3f82142630a..113d2e56ad0 100644
--- a/playwright/tests/staffMembers.spec.ts
+++ b/playwright/tests/staffMembers.spec.ts
@@ -3,96 +3,97 @@ import { USERS } from "@data/e2eTestData";
import { ConfigurationPage } from "@pages/configurationPage";
import { PermissionGroupsPage } from "@pages/permissionGroupsPage";
import { StaffMembersPage } from "@pages/staffMembersPage";
-import { expect, test } from "@playwright/test";
-import faker from "faker";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let staffMembersPage: StaffMembersPage;
let config: ConfigurationPage;
let permissionGroupsPage: PermissionGroupsPage;
let basicApiService: BasicApiService;
+interface StaffMember {
+ id?: string;
+ name: string;
+ lastName: string;
+ email: string;
+}
+
test.beforeEach(async ({ page, request }) => {
staffMembersPage = new StaffMembersPage(page, request);
config = new ConfigurationPage(page);
permissionGroupsPage = new PermissionGroupsPage(page);
basicApiService = new BasicApiService(request);
-});
-test("TC: SALEOR_137 Admin User should be able to deactivate other user @e2e @staff-members", async () => {
- await staffMembersPage.goToStaffDetailsPage(USERS.userToBeDeactivated.id);
- await staffMembersPage.clickIsActiveCheckbox();
- await staffMembersPage.clickSaveButton();
- await staffMembersPage.basePage.expectSuccessBanner();
- await expect(await staffMembersPage.isActiveCheckbox.isChecked()).toEqual(false);
-
- const loginViaApiDeactivatedUserResponse = await basicApiService.logInUserViaApi({
- email: USERS.userToBeDeactivated.email,
- password: process.env.E2E_PERMISSIONS_USERS_PASSWORD!,
- });
- await expect(loginViaApiDeactivatedUserResponse.data.tokenCreate.errors[0].code).toEqual(
- "INACTIVE",
- );
+ await config.goToConfigurationView();
+ await config.openStaffMembers();
});
-test("TC: SALEOR_38 Admin User should be able to activate other user @e2e @staff-members", async () => {
- await staffMembersPage.goToStaffDetailsPage(USERS.userToBeActivated.id);
- await staffMembersPage.clickIsActiveCheckbox();
- await staffMembersPage.clickSaveButton();
- await staffMembersPage.basePage.expectSuccessBanner();
- await expect(await staffMembersPage.isActiveCheckbox.isChecked()).toEqual(true);
-
- const loginViaApiDeactivatedUserResponse = await basicApiService.logInUserViaApi({
- email: USERS.userToBeActivated.email,
- password: process.env.E2E_PERMISSIONS_USERS_PASSWORD!,
- });
- await expect(loginViaApiDeactivatedUserResponse.data.tokenCreate.errors).toEqual([]);
- await expect(loginViaApiDeactivatedUserResponse.data.tokenCreate.token).not.toEqual(null);
-});
-test("TC: SALEOR_211 Create a staff member @e2e @staff-members", async () => {
- const name = faker.name.firstName();
- const lastName = faker.name.lastName();
- const email = faker.internet.email().toLowerCase();
+test("TC: SALEOR_211 Create a staff member #e2e #staff-members", async () => {
+ const staffMember: StaffMember = {
+ name: "John",
+ lastName: "Create",
+ email: `test.staff.john.create@example.com`,
+ };
- await config.goToConfigurationView();
- await config.openStaffMembers();
await staffMembersPage.clickInviteStaffMemberButton();
- await staffMembersPage.inviteStaffMembersDialog.typeNameLastNameAndEmail(name, lastName, email);
+ await staffMembersPage.inviteStaffMembersDialog.typeNameLastNameAndEmail(
+ staffMember.name,
+ staffMember.lastName,
+ staffMember.email,
+ );
+ await staffMembersPage.inviteStaffMembersDialog.sendInviteButton.waitFor({ state: "visible" });
await staffMembersPage.inviteStaffMembersDialog.clickSendInviteButton();
await staffMembersPage.expectSuccessBanner();
- await expect(staffMembersPage.firstName).toHaveValue(name);
- await expect(staffMembersPage.lastName).toHaveValue(lastName);
- await expect(staffMembersPage.email).toHaveValue(email);
- await expect(await staffMembersPage.isActiveCheckbox.isChecked()).toEqual(true);
+
+ await expect(staffMembersPage.firstName).toHaveValue(staffMember.name);
+ await expect(staffMembersPage.lastName).toHaveValue(staffMember.lastName);
+ await expect(staffMembersPage.email).toHaveValue(staffMember.email);
+ await expect(await staffMembersPage.isActiveCheckbox.isChecked()).toBeTruthy();
+
await staffMembersPage.clickPermissionsGroupSelectButton();
+
await staffMembersPage.assignUserToPermissionGroup("Customer Support");
- await staffMembersPage.assignUserToPermissionGroup("Channels management");
+ await staffMembersPage.assignUserToPermissionGroup("Channels Management");
+
await staffMembersPage.clickSaveButton();
- await staffMembersPage.expectSuccessBanner();
+
await staffMembersPage.verifyAssignedPermission("Customer Support");
- await staffMembersPage.verifyAssignedPermission("Channels management");
+ await staffMembersPage.verifyAssignedPermission("Channels Management");
});
-test("TC: SALEOR_212 Edit a staff member @e2e @staff-members", async () => {
- const newName = faker.name.firstName();
- const newLastName = faker.name.lastName();
- const newEmail = faker.internet.email().toLowerCase();
+test("TC: SALEOR_212 Edit a staff member #e2e #staff-members", async () => {
+ const updatedStaffMember: StaffMember = {
+ name: "John",
+ lastName: "Edit",
+ email: `test.staff.john.edit@example.com`,
+ };
await staffMembersPage.gotToExistingStaffMemberPage(USERS.staffToBeEdited.id);
+ await staffMembersPage.updateStaffInfo(
+ updatedStaffMember.name,
+ updatedStaffMember.lastName,
+ updatedStaffMember.email,
+ );
+
await staffMembersPage.clickPermissionsGroupSelectButton();
await staffMembersPage.assignUserToPermissionGroup("Customer Support");
- await staffMembersPage.assignUserToPermissionGroup("Channels management");
+ await staffMembersPage.assignUserToPermissionGroup("Channels Management");
+
await staffMembersPage.clickSaveButton();
await staffMembersPage.expectSuccessBanner();
- await staffMembersPage.updateStaffInfo(newName, newLastName, newEmail);
- await expect(staffMembersPage.firstName).toHaveValue(newName);
- await expect(staffMembersPage.lastName).toHaveValue(newLastName);
- await expect(staffMembersPage.email).toHaveValue(newEmail);
+
+ await expect(staffMembersPage.firstName).toHaveValue(updatedStaffMember.name);
+ await expect(staffMembersPage.lastName).toHaveValue(updatedStaffMember.lastName);
+ await expect(staffMembersPage.email).toHaveValue(updatedStaffMember.email);
+
+ await staffMembersPage.clickPermissionsGroupSelectButton();
+
await staffMembersPage.verifyAssignedPermission("Customer Support");
- await staffMembersPage.verifyAssignedPermission("Channels management");
+ await staffMembersPage.verifyAssignedPermission("Channels Management");
await staffMembersPage.verifyAssignedPermission(USERS.staffToBeEdited.permission);
});
-test("TC: SALEOR_213 Delete a single staff member @e2e @staff-members", async () => {
+test("TC: SALEOR_213 Delete a single staff member #e2e #staff-members", async () => {
await staffMembersPage.gotToExistingStaffMemberPage(USERS.staffToBeDeleted.id);
await staffMembersPage.clickDeleteButton();
await staffMembersPage.clickSubmitButton();
diff --git a/playwright/tests/taxes.spec.ts b/playwright/tests/taxes.spec.ts
index 1244fa7de9f..f890ed11eb2 100644
--- a/playwright/tests/taxes.spec.ts
+++ b/playwright/tests/taxes.spec.ts
@@ -1,9 +1,10 @@
import { CHANNELS, COUNTRIES } from "@data/e2eTestData";
import { ConfigurationPage } from "@pages/configurationPage";
import { TaxesPage } from "@pages/taxesPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let configurationPage: ConfigurationPage;
let taxesPage: TaxesPage;
@@ -12,15 +13,15 @@ test.beforeEach(({ page }) => {
configurationPage = new ConfigurationPage(page);
taxesPage = new TaxesPage(page);
});
-test("TC: SALEOR_115 Change taxes in channel to use tax app @taxes @e2e", async () => {
+test("TC: SALEOR_115 Change taxes in channel to use tax app #taxes #e2e", async () => {
await configurationPage.goToConfigurationView();
await configurationPage.openTaxes();
await taxesPage.selectChannel(CHANNELS.channelForTaxEdition.name);
- await taxesPage.selectTaxCalculationMethod("saleor.app.dummy.tax");
+ await taxesPage.selectTaxCalculationMethod("Saleor Dummy tax app");
await taxesPage.clickSaveButton();
await taxesPage.expectSuccessBanner();
});
-test("TC: SALEOR_116 Change taxes in channel: enter prices without tax, do not show gross price, add country exception @taxes @e2e", async () => {
+test("TC: SALEOR_116 Change taxes in channel: enter prices without tax, do not show gross price, add country exception #taxes #e2e", async () => {
await taxesPage.gotoChannelsTabUrl();
await taxesPage.selectChannel(CHANNELS.channelForTaxEdition.name);
await taxesPage.selectPricesWithoutTaxes();
@@ -37,7 +38,7 @@ test("TC: SALEOR_116 Change taxes in channel: enter prices without tax, do not s
await taxesPage.clickSaveButton();
await taxesPage.expectSuccessBanner();
});
-test("TC: SALEOR_117 Add new country and tax rates to it @taxes @e2e", async () => {
+test("TC: SALEOR_117 Add new country and tax rates to it #taxes #e2e", async () => {
await taxesPage.gotoChannelsTabUrl();
await taxesPage.clickCountriesTab();
await taxesPage.clickAddCountryButton();
@@ -52,7 +53,7 @@ test("TC: SALEOR_117 Add new country and tax rates to it @taxes @e2e", async ()
await taxesPage.clickSaveButton();
await taxesPage.expectSuccessBanner();
});
-test("TC: SALEOR_118 Add new class with metadata and set tax rate for single country @taxes @e2e", async () => {
+test("TC: SALEOR_118 Add new class with metadata and set tax rate for single country #taxes #e2e", async () => {
await taxesPage.gotoChannelsTabUrl();
await taxesPage.clickTaxClassTab();
await taxesPage.clickCreateClassButton();
diff --git a/playwright/tests/translations.spec.ts b/playwright/tests/translations.spec.ts
index 8397fba68e8..83a9d69981b 100644
--- a/playwright/tests/translations.spec.ts
+++ b/playwright/tests/translations.spec.ts
@@ -1,15 +1,16 @@
import { TRANSLATIONS } from "@data/e2eTestData";
import { TranslationsPage } from "@pages/translationsPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let translationsPage: TranslationsPage;
test.beforeEach(({ page }) => {
translationsPage = new TranslationsPage(page);
});
-test("TC: SALEOR_121 Should be able to add translation @e2e @translations", async () => {
+test("TC: SALEOR_121 Should be able to add translation #e2e #translations", async () => {
await translationsPage.gotoTranslationsPage();
await translationsPage.translationPl_PL.click();
await translationsPage.page.getByText("CategoryToTranslate").click();
@@ -23,10 +24,10 @@ test("TC: SALEOR_121 Should be able to add translation @e2e @translations", asy
await translationsPage.editTranslationNameButton.click();
await translationsPage.translationInput.fill("Kategoria do Translacji");
await translationsPage.saveButton.click();
- await expect(translationsPage.successBanner).toBeVisible();
+ await translationsPage.expectSuccessBanner();
await expect(translationsPage.page.getByText("Kategoria do Translacji")).toBeVisible();
});
-test("TC: SALEOR_122 Should be able to edit translation @e2e @translations", async () => {
+test("TC: SALEOR_122 Should be able to edit translation #e2e #translations", async () => {
const newDescription =
"Brukselka, szpinak, groszek, jarmuż, sałata, kapusta, cukinia, więcej brukselki. Wszystkie warzywa, jakich będziesz potrzebować, w jednym pysznym soku.";
@@ -47,7 +48,7 @@ test("TC: SALEOR_122 Should be able to edit translation @e2e @translations", as
await translationsPage.translationRichText.clear();
await translationsPage.translationRichText.fill(newDescription);
await translationsPage.saveButton.click();
- await expect(translationsPage.successBanner).toBeVisible();
+ await translationsPage.expectSuccessBanner();
await translationsPage.goToDirectTranslationPage(
"PL_PL",
"products",
@@ -56,7 +57,7 @@ test("TC: SALEOR_122 Should be able to edit translation @e2e @translations", as
await translationsPage.waitForDOMToFullyLoad();
await expect(translationsPage.page.getByText(newDescription)).toBeVisible();
});
-test("TC: SALEOR_123 Should be able to clear translation @e2e @translations", async () => {
+test("TC: SALEOR_123 Should be able to clear translation #e2e #translations", async () => {
const description =
"Letnia kolekcja Saleor obejmuje gamę produktów, które cieszą się popularnością na rynku.Sklep demonstracyjny na każdą porę roku.Saleor uchwycił słońce open source, e-commerce.";
@@ -76,6 +77,6 @@ test("TC: SALEOR_123 Should be able to clear translation @e2e @translations", a
await translationsPage.editTranslationDescriptionButton.click();
await translationsPage.translationRichText.clear();
await translationsPage.saveButton.click();
- await expect(translationsPage.successBanner).toBeVisible();
+ await translationsPage.expectSuccessBanner();
await expect(translationsPage.page.getByText(description)).not.toBeVisible();
});
diff --git a/playwright/tests/vouchers.spec.ts b/playwright/tests/vouchers.spec.ts
index ee4ba0a2b71..e6fdad55522 100644
--- a/playwright/tests/vouchers.spec.ts
+++ b/playwright/tests/vouchers.spec.ts
@@ -1,16 +1,17 @@
import { AVAILABILITY } from "@data/copy";
import { VOUCHERS } from "@data/e2eTestData";
import { VouchersPage } from "@pages/vouchersPage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let vouchersPage: VouchersPage;
test.beforeEach(({ page }) => {
vouchersPage = new VouchersPage(page);
});
-test("TC: SALEOR_40 Create voucher with auto-generated codes and fixed amount discount @vouchers @e2e", async () => {
+test("TC: SALEOR_40 Create voucher with auto-generated codes and fixed amount discount #vouchers #e2e", async () => {
const codesQuantity = 5;
const codesPrefix = "auto";
@@ -31,7 +32,7 @@ test("TC: SALEOR_40 Create voucher with auto-generated codes and fixed amount di
`Auto-generated number of codes: ${codesQuantity} should be visible on grid`,
).toEqual(codesQuantity);
await vouchersPage.typeDiscountValueInChannel();
- await vouchersPage.waitForNetworkIdleAfterAction(() => vouchersPage.clickSaveButton());
+ await vouchersPage.clickSaveButton();
await vouchersPage.expectSuccessBanner();
await vouchersPage.waitForGrid();
@@ -42,7 +43,7 @@ test("TC: SALEOR_40 Create voucher with auto-generated codes and fixed amount di
`Given codes quantity: ${codesQuantity} should have status Active displayed on grid`,
).toEqual(codesQuantity);
});
-test("TC: SALEOR_85 Create voucher with manual code and percentage discount @vouchers @e2e", async () => {
+test("TC: SALEOR_85 Create voucher with manual code and percentage discount #vouchers #e2e", async () => {
const code = `code-TC: SALEOR_85 ${new Date().toISOString()}`;
await vouchersPage.gotoVoucherAddPage();
@@ -63,7 +64,7 @@ test("TC: SALEOR_85 Create voucher with manual code and percentage discount @vou
"Channel-PLN",
);
await vouchersPage.typeDiscountValueInChannel("Channel-PLN", "50");
- await vouchersPage.waitForNetworkIdleAfterAction(() => vouchersPage.clickSaveButton());
+ await vouchersPage.clickSaveButton();
await vouchersPage.expectSuccessBanner();
await vouchersPage.waitForGrid();
@@ -75,7 +76,7 @@ test("TC: SALEOR_85 Create voucher with manual code and percentage discount @vou
).toEqual(1);
await vouchersPage.page.getByText(AVAILABILITY.in1OutOf).waitFor({ state: "visible" });
});
-test("TC: SALEOR_86 Edit voucher to have free shipping discount @vouchers @e2e", async () => {
+test("TC: SALEOR_86 Edit voucher to have free shipping discount #vouchers #e2e", async () => {
await vouchersPage.gotoExistingVoucherPage(
VOUCHERS.vouchers.voucherToBeEditedWithFreeShipping.id,
);
@@ -88,8 +89,7 @@ test("TC: SALEOR_86 Edit voucher to have free shipping discount @vouchers @e2e",
vouchersPage.discountValueInput,
"No discount value input should be visible with free shipping type active ",
).not.toBeVisible();
- await vouchersPage.waitForNetworkIdleAfterAction(() => vouchersPage.clickSaveButton());
- await vouchersPage.waitForGrid();
+ await vouchersPage.clickSaveButton();
await vouchersPage.expectSuccessBanner();
const codesRowsAfterSave = await vouchersPage.getNumberOfGridRows();
@@ -99,7 +99,7 @@ test("TC: SALEOR_86 Edit voucher to have free shipping discount @vouchers @e2e",
`Same amount of codes should have status Active displayed on grid after switching to free shipping`,
).toEqual(codesRowsAfterSave);
});
-test("TC: SALEOR_87 Edit voucher Usage Limits: used in total, per customer, staff only, code used once @vouchers @e2e", async () => {
+test("TC: SALEOR_87 Edit voucher Usage Limits: used in total, per customer, staff only, code used once #vouchers #e2e", async () => {
await vouchersPage.gotoExistingVoucherPage(VOUCHERS.vouchers.voucherToBeEditedUsageLimits.id);
await vouchersPage.waitForGrid();
await vouchersPage.clickUsageTotalLimitCheckbox();
@@ -107,7 +107,7 @@ test("TC: SALEOR_87 Edit voucher Usage Limits: used in total, per customer, staf
await vouchersPage.clickOncePerCustomerLimitCheckbox();
await vouchersPage.clickOnlyForStaffLimitCheckbox();
await vouchersPage.clickSingleUseLimitCheckbox();
- await vouchersPage.waitForNetworkIdleAfterAction(() => vouchersPage.clickSaveButton());
+ await vouchersPage.clickSaveButton();
await vouchersPage.waitForGrid();
await vouchersPage.expectSuccessBanner();
expect(
@@ -115,7 +115,7 @@ test("TC: SALEOR_87 Edit voucher Usage Limits: used in total, per customer, staf
"All usage limit checkboxes should be checked",
).toEqual(4);
});
-test("TC: SALEOR_89 Create voucher with minimum value of order @vouchers @e2e", async () => {
+test("TC: SALEOR_89 Create voucher with minimum value of order #vouchers #e2e", async () => {
const code = `code-TC: SALEOR_89 ${new Date().toISOString()}`;
await vouchersPage.gotoVoucherAddPage();
@@ -133,7 +133,7 @@ test("TC: SALEOR_89 Create voucher with minimum value of order @vouchers @e2e",
);
await vouchersPage.clickMinimalOrderValueButton();
await vouchersPage.typeMinimumOrderValue("Channel-PLN", "50");
- await vouchersPage.waitForNetworkIdleAfterAction(() => vouchersPage.clickSaveButton());
+ await vouchersPage.clickSaveButton();
await vouchersPage.expectSuccessBanner();
await vouchersPage.waitForGrid();
@@ -144,20 +144,18 @@ test("TC: SALEOR_89 Create voucher with minimum value of order @vouchers @e2e",
`Given codes: ${code} should have status Active displayed on grid`,
).toEqual(1);
});
-test("TC: SALEOR_90 Edit voucher minimum quantity of items @vouchers @e2e", async () => {
+test("TC: SALEOR_90 Edit voucher minimum quantity of items #vouchers #e2e", async () => {
await vouchersPage.gotoExistingVoucherPage(VOUCHERS.vouchers.voucherToBeEditedMinimumQuantity.id);
await vouchersPage.clickMinimumQuantityOfItemsButton();
await vouchersPage.typeMinimumQuantityOfItems("4");
- await vouchersPage.waitForNetworkIdleAfterAction(() => vouchersPage.clickSaveButton());
+ await vouchersPage.clickSaveButton();
await vouchersPage.expectSuccessBanner();
await vouchersPage.waitForGrid();
});
-test("TC: SALEOR_92 Delete voucher @vouchers @e2e", async () => {
+test("TC: SALEOR_92 Delete voucher #vouchers #e2e", async () => {
await vouchersPage.gotoExistingVoucherPage(VOUCHERS.vouchers.voucherToBeDeleted.id);
await vouchersPage.clickDeleteSingleVoucherButton();
- await vouchersPage.waitForNetworkIdleAfterAction(() =>
- vouchersPage.deleteVoucherDialog.clickDeleteButton(),
- );
+ await vouchersPage.deleteVoucherDialog.clickDeleteButton();
await vouchersPage.expectSuccessBanner();
await vouchersPage.createVoucherButton.waitFor({ state: "visible" });
await vouchersPage.waitForGrid();
@@ -166,15 +164,13 @@ test("TC: SALEOR_92 Delete voucher @vouchers @e2e", async () => {
`Given vouchers: ${VOUCHERS.vouchers.voucherToBeBulkDeleted.names} should be deleted from the list`,
).toEqual([]);
});
-test("TC: SALEOR_93 Bulk delete voucher @vouchers @e2e", async () => {
+test("TC: SALEOR_93 Bulk delete voucher #vouchers #e2e", async () => {
await vouchersPage.gotoVouchersListPage();
await vouchersPage.checkListRowsBasedOnContainingText(
VOUCHERS.vouchers.voucherToBeBulkDeleted.names,
);
await vouchersPage.clickBulkDeleteButton();
- await vouchersPage.waitForNetworkIdleAfterAction(() =>
- vouchersPage.deleteVoucherDialog.clickDeleteButton(),
- );
+ await vouchersPage.deleteVoucherDialog.clickDeleteButton();
await vouchersPage.expectSuccessBanner();
await vouchersPage.gotoVouchersListPage();
await expect(
@@ -182,7 +178,7 @@ test("TC: SALEOR_93 Bulk delete voucher @vouchers @e2e", async () => {
`Given vouchers: ${VOUCHERS.vouchers.voucherToBeBulkDeleted.names} should be deleted from the list`,
).toEqual([]);
});
-test("TC: SALEOR_94 Edit voucher - assign voucher to specific category @vouchers @e2e", async () => {
+test("TC: SALEOR_94 Edit voucher - assign voucher to specific category #vouchers #e2e", async () => {
const categoryToBeAssigned = "Accessories";
await vouchersPage.gotoExistingVoucherPage(
@@ -190,10 +186,8 @@ test("TC: SALEOR_94 Edit voucher - assign voucher to specific category @vouchers
);
await vouchersPage.clickSpecificProductsButton();
await vouchersPage.clickAssignCategoryButton();
- await vouchersPage.waitForNetworkIdleAfterAction(() =>
- vouchersPage.assignSpecificProductsDialog.assignSpecificProductsByNameAndSave(
- categoryToBeAssigned,
- ),
+ await vouchersPage.assignSpecificProductsDialog.assignSpecificProductsByNameAndSave(
+ categoryToBeAssigned,
);
await vouchersPage.expectSuccessBanner();
await expect(
@@ -205,7 +199,7 @@ test("TC: SALEOR_94 Edit voucher - assign voucher to specific category @vouchers
`Only 1 category should be visible in table`,
).toEqual(1);
});
-test("TC:SALEOR_95 Edit voucher - assign voucher to specific collection @vouchers @e2e", async () => {
+test("TC:SALEOR_95 Edit voucher - assign voucher to specific collection #vouchers #e2e", async () => {
const collectionToBeAssigned = "Featured Products";
await vouchersPage.gotoExistingVoucherPage(
@@ -214,10 +208,8 @@ test("TC:SALEOR_95 Edit voucher - assign voucher to specific collection @vouche
await vouchersPage.clickSpecificProductsButton();
await vouchersPage.clickCollectionsTab();
await vouchersPage.clickAssignCollectionButton();
- await vouchersPage.waitForNetworkIdleAfterAction(() =>
- vouchersPage.assignSpecificProductsDialog.assignSpecificProductsByNameAndSave(
- collectionToBeAssigned,
- ),
+ await vouchersPage.assignSpecificProductsDialog.assignSpecificProductsByNameAndSave(
+ collectionToBeAssigned,
);
await vouchersPage.expectSuccessBanner();
await expect(
@@ -229,7 +221,7 @@ test("TC:SALEOR_95 Edit voucher - assign voucher to specific collection @vouche
`Only 1 collection should be visible in table`,
).toEqual(1);
});
-test("TC: SALEOR_96 Edit voucher - assign voucher to specific product @vouchers @e2e", async () => {
+test("TC: SALEOR_96 Edit voucher - assign voucher to specific product #vouchers #e2e", async () => {
const productToBeAssigned = "Bean Juice";
await vouchersPage.gotoExistingVoucherPage(
@@ -238,10 +230,8 @@ test("TC: SALEOR_96 Edit voucher - assign voucher to specific product @vouchers
await vouchersPage.clickSpecificProductsButton();
await vouchersPage.clickProductsTab();
await vouchersPage.clickAssignProductButton();
- await vouchersPage.waitForNetworkIdleAfterAction(() =>
- vouchersPage.assignSpecificProductsDialog.assignSpecificProductsByNameAndSave(
- productToBeAssigned,
- ),
+ await vouchersPage.assignSpecificProductsDialog.assignSpecificProductsByNameAndSave(
+ productToBeAssigned,
);
await vouchersPage.expectSuccessBanner();
await expect(
diff --git a/playwright/tests/warehouse.spec.ts b/playwright/tests/warehouse.spec.ts
index 1e295efea83..199588e1008 100644
--- a/playwright/tests/warehouse.spec.ts
+++ b/playwright/tests/warehouse.spec.ts
@@ -1,22 +1,23 @@
import { WAREHOUSES } from "@data/e2eTestData";
import { WarehousePage } from "@pages/warehousePage";
-import { expect, test } from "@playwright/test";
+import { expect } from "@playwright/test";
+import { test } from "utils/testWithPermission";
-test.use({ storageState: "./playwright/.auth/admin.json" });
+test.use({ permissionName: "admin" });
let warehousePage: WarehousePage;
test.beforeEach(({ page }) => {
warehousePage = new WarehousePage(page);
});
-test("TC: SALEOR_30 Create basic warehouse @e2e @warehouse", async () => {
+test("TC: SALEOR_30 Create basic warehouse #e2e #warehouse", async () => {
await warehousePage.gotoWarehouseListView();
await warehousePage.clickCreateNewWarehouseButton();
await warehousePage.completeWarehouseForm();
await warehousePage.clickSaveButton();
await warehousePage.basePage.expectSuccessBanner();
});
-test("TC: SALEOR_100 Edit warehouse @e2e @warehouse", async () => {
+test("TC: SALEOR_100 Edit warehouse #e2e #warehouse", async () => {
await warehousePage.gotoExistingWarehousePage(WAREHOUSES.warehouseToBeEdited.id);
await warehousePage.typeWarehouseName("edited warehouse");
await warehousePage.typeCompanyName("Umbrella");
@@ -28,7 +29,7 @@ test("TC: SALEOR_100 Edit warehouse @e2e @warehouse", async () => {
await warehousePage.clickSaveButton();
await warehousePage.basePage.expectSuccessBanner();
});
-test("TC: SALEOR_101 Delete warehouse @e2e @warehouse", async () => {
+test("TC: SALEOR_101 Delete warehouse #e2e #warehouse", async () => {
await warehousePage.gotoWarehouseListView();
await warehousePage.clickDeleteWarehouseButton(WAREHOUSES.warehouseToBeDeleted.name);
await warehousePage.deleteWarehouseDialog.clickDeleteButton();
diff --git a/playwright/utils/auth.ts b/playwright/utils/auth.ts
new file mode 100644
index 00000000000..a90975082e5
--- /dev/null
+++ b/playwright/utils/auth.ts
@@ -0,0 +1,76 @@
+import { BasicApiService } from "@api/basics";
+import { USER_PERMISSION, UserPermission } from "@data/userPermissions";
+import { request } from "@playwright/test";
+import fs from "fs";
+import path from "path";
+
+export const getStorageState = async (permission: UserPermission | "admin"): Promise => {
+ const tempDir = path.join(__dirname, "../.auth");
+ const storageStatePath = path.join(tempDir, `${permission}.json`);
+
+ if (!fs.existsSync(tempDir)) {
+ fs.mkdirSync(tempDir, { recursive: true });
+ }
+
+ if (!fs.existsSync(storageStatePath)) {
+ const apiRequestContext = await request.newContext({
+ baseURL: process.env.BASE_URL!,
+ });
+
+ const basicApiService = new BasicApiService(apiRequestContext);
+
+ const email = getEmailForPermission(permission);
+ const password = getPasswordForPermission(permission);
+
+ console.log("getStorageState login external api", permission);
+
+ try {
+ await basicApiService.logInUserViaApi({ email, password });
+ } catch (error: unknown) {
+ console.log("Err", error);
+
+ if (!(error instanceof Error)) {
+ throw new Error("An unknown error occurred while logging in the user via API");
+ }
+
+ const message = `logInUserViaApi failed for ${email}: ${error.message}`;
+
+ console.error(message);
+ throw new Error(message);
+ }
+
+ const loginJsonInfo = await apiRequestContext.storageState();
+
+ loginJsonInfo.origins.push({
+ origin: process.env.BASE_URL!,
+ localStorage: [
+ {
+ name: "_saleorRefreshToken",
+ value: loginJsonInfo.cookies[0].value,
+ },
+ ],
+ });
+
+ fs.writeFileSync(storageStatePath, JSON.stringify(loginJsonInfo, null, 2));
+
+ await apiRequestContext.dispose();
+ }
+
+ return storageStatePath;
+};
+
+const getEmailForPermission = (permission: UserPermission | "admin"): string => {
+ if (permission === "admin") {
+ return process.env.E2E_USER_NAME!;
+ } else {
+ return USER_PERMISSION[permission];
+ }
+};
+
+const getPasswordForPermission = (permission: UserPermission | "admin"): string => {
+ if (permission === "admin") {
+ return process.env.E2E_USER_PASSWORD!;
+ } else {
+ return process.env.E2E_PERMISSIONS_USERS_PASSWORD!;
+ }
+};
diff --git a/playwright/utils/testWithPermission.ts b/playwright/utils/testWithPermission.ts
new file mode 100644
index 00000000000..10eecbbb4de
--- /dev/null
+++ b/playwright/utils/testWithPermission.ts
@@ -0,0 +1,18 @@
+import { UserPermission } from "@data/userPermissions";
+import { test as base } from "@playwright/test";
+
+import { getStorageState } from "./auth";
+
+interface PermissionOptions {
+ permissionName: UserPermission | "admin";
+}
+
+export const test = base.extend({
+ permissionName: ["admin", { option: true }],
+
+ storageState: async ({ permissionName }, use) => {
+ const storageStatePath = await getStorageState(permissionName);
+
+ await use(storageStatePath);
+ },
+});
diff --git a/schema.graphql b/schema.graphql
index 1644d256c5f..2f96313284b 100644
--- a/schema.graphql
+++ b/schema.graphql
@@ -14,9 +14,9 @@ directive @webhookEventsInfo(
) on FIELD | FIELD_DEFINITION | INPUT_OBJECT | OBJECT
"""
-Create a new address for the customer.
+Create a new address for the customer.
-Requires one of the following permissions: AUTHENTICATED_USER.
+Requires one of following set of permissions: AUTHENTICATED_USER or AUTHENTICATED_APP + IMPERSONATE_USER.
Triggers the following webhook events:
- CUSTOMER_UPDATED (async): A customer account was updated.
@@ -326,6 +326,7 @@ enum AccountErrorCode {
JWT_MISSING_TOKEN
JWT_SIGNATURE_EXPIRED
LEFT_NOT_MANAGEABLE_PERMISSION
+ LOGIN_ATTEMPT_DELAYED
MISSING_CHANNEL_SLUG
NOT_FOUND
OUT_OF_SCOPE_GROUP
@@ -338,6 +339,7 @@ enum AccountErrorCode {
PASSWORD_TOO_SIMILAR
REQUIRED
UNIQUE
+ UNKNOWN_IP_ADDRESS
}
"""Fields required to update the user."""
@@ -478,9 +480,9 @@ type AccountSetPasswordRequested implements Event {
}
"""
-Updates the account of the logged-in user.
+Updates the account of the logged-in user.
-Requires one of the following permissions: AUTHENTICATED_USER.
+Requires one of following set of permissions: AUTHENTICATED_USER or AUTHENTICATED_APP + IMPERSONATE_USER.
Triggers the following webhook events:
- CUSTOMER_UPDATED (async): A customer account was updated.
@@ -700,6 +702,15 @@ input AddressInput {
"""Postal code."""
postalCode: String
+ """
+ Determine if the address should be validated. By default, Saleor accepts only address inputs matching ruleset from [Google Address Data]{https://chromium-i18n.appspot.com/ssl-address), using [i18naddress](https://github.com/mirumee/google-i18n-address) library. Some mutations may require additional permissions to use the the field. More info about permissions can be found in relevant mutation.
+
+ Added in Saleor 3.19.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ skipValidation: Boolean = false
+
"""Address."""
streetAddress1: String
@@ -4708,7 +4719,7 @@ type Checkout implements Node & ObjectWithMetadata {
totalBalance: Money!
"""
- The sum of the the checkout line prices, with all the taxes,shipping costs, and discounts included.
+ The sum of the checkout line prices, with all the taxes,shipping costs, and discounts included.
Triggers the following webhook events:
- CHECKOUT_CALCULATE_TAXES (sync): Optionally triggered when checkout prices are expired.
@@ -4894,6 +4905,8 @@ type CheckoutCountableEdge {
"""
Create a new checkout.
+`skipValidation` field requires HANDLE_CHECKOUTS and AUTHENTICATED_APP permissions.
+
Triggers the following webhook events:
- CHECKOUT_CREATED (async): A checkout was created.
"""
@@ -4971,7 +4984,9 @@ enum CheckoutCreateFromOrderUnavailableVariantErrorCode {
}
input CheckoutCreateInput {
- """Billing address of the customer."""
+ """
+ Billing address of the customer. `skipValidation` requires HANDLE_CHECKOUTS and AUTHENTICATED_APP permissions.
+ """
billingAddress: AddressInput
"""Slug of a channel in which to create a checkout."""
@@ -4989,7 +5004,7 @@ input CheckoutCreateInput {
lines: [CheckoutLineInput!]!
"""
- The mailing address to where the checkout will be shipped. Note: the address will be ignored if the checkout doesn't contain shippable items.
+ The mailing address to where the checkout will be shipped. Note: the address will be ignored if the checkout doesn't contain shippable items. `skipValidation` requires HANDLE_CHECKOUTS and AUTHENTICATED_APP permissions.
"""
shippingAddress: AddressInput
@@ -5179,7 +5194,7 @@ type CheckoutFilterShippingMethods implements Event {
}
"""
-Event sent when checkout is fully paid with transactions.
+Event sent when checkout is fully paid with transactions. The checkout is considered as fully paid when the checkout `charge_status` is `FULL` or `OVERCHARGED`. The event is not sent when the checkout authorization flow strategy is used.
Added in Saleor 3.13.
@@ -5544,6 +5559,13 @@ Added in Saleor 3.15.
Note: this API is currently in Feature Preview and can be subject to changes at later point.
"""
type CheckoutSettings {
+ """
+ Default `false`. Determines if the paid checkouts should be automatically completed. This setting applies only to checkouts where payment was processed through transactions.When enabled, the checkout will be automatically completed once the checkout `charge_status` reaches `FULL`. This occurs when the total sum of charged and authorized transaction amounts equals or exceeds the checkout's total amount.
+
+ Added in Saleor 3.20.
+ """
+ automaticallyCompleteFullyPaidCheckouts: Boolean!
+
"""
Default `true`. Determines if the checkout mutations should use legacy error flow. In legacy flow, all mutations can raise an exception unrelated to the requested action - (e.g. out-of-stock exception when updating checkoutShippingAddress.) If `false`, the errors will be aggregated in `checkout.problems` field. Some of the `problems` can block the finalizing checkout process. The legacy flow will be removed in Saleor 4.0. The flow with `checkout.problems` will be the default one.
@@ -5553,6 +5575,13 @@ type CheckoutSettings {
}
input CheckoutSettingsInput {
+ """
+ Default `false`. Determines if the paid checkouts should be automatically completed. This setting applies only to checkouts where payment was processed through transactions.When enabled, the checkout will be automatically completed once the checkout `charge_status` reaches `FULL`. This occurs when the total sum of charged and authorized transaction amounts equals or exceeds the checkout's total amount.
+
+ Added in Saleor 3.20.
+ """
+ automaticallyCompleteFullyPaidCheckouts: Boolean
+
"""
Default `true`. Determines if the checkout mutations should use legacy error flow. In legacy flow, all mutations can raise an exception unrelated to the requested action - (e.g. out-of-stock exception when updating checkoutShippingAddress.) If `false`, the errors will be aggregated in `checkout.problems` field. Some of the `problems` can block the finalizing checkout process. The legacy flow will be removed in Saleor 4.0. The flow with `checkout.problems` will be the default one.
@@ -6416,7 +6445,11 @@ type ConfirmEmailChange {
user: User
}
-"""An enumeration."""
+"""
+Represents country codes defined by the ISO 3166-1 alpha-2 standard.
+
+The `EU` value is DEPRECATED and will be removed in Saleor 3.21.
+"""
enum CountryCode {
AD
AE
@@ -11773,15 +11806,22 @@ input MoveProductInput {
type Mutation {
"""
- Create a new address for the customer.
+ Create a new address for the customer.
- Requires one of the following permissions: AUTHENTICATED_USER.
+ Requires one of following set of permissions: AUTHENTICATED_USER or AUTHENTICATED_APP + IMPERSONATE_USER.
Triggers the following webhook events:
- CUSTOMER_UPDATED (async): A customer account was updated.
- ADDRESS_CREATED (async): An address was created.
"""
accountAddressCreate(
+ """
+ ID of customer the application is impersonating. The field can be used and is required by apps only. Requires IMPERSONATE_USER and AUTHENTICATED_APP permission.
+
+ Added in Saleor 3.19.
+ """
+ customerId: ID
+
"""Fields required to create address."""
input: AddressInput!
@@ -11882,15 +11922,22 @@ type Mutation {
): AccountSetDefaultAddress
"""
- Updates the account of the logged-in user.
+ Updates the account of the logged-in user.
- Requires one of the following permissions: AUTHENTICATED_USER.
+ Requires one of following set of permissions: AUTHENTICATED_USER or AUTHENTICATED_APP + IMPERSONATE_USER.
Triggers the following webhook events:
- CUSTOMER_UPDATED (async): A customer account was updated.
- CUSTOMER_METADATA_UPDATED (async): Optionally called when customer's metadata was updated.
"""
accountUpdate(
+ """
+ ID of customer the application is impersonating. The field can be used and is required by apps only. Requires IMPERSONATE_USER and AUTHENTICATED_APP permission.
+
+ Added in Saleor 3.19.
+ """
+ customerId: ID
+
"""Fields required to update the account of the logged-in user."""
input: AccountInput!
): AccountUpdate
@@ -12673,6 +12720,8 @@ type Mutation {
"""
Create a new checkout.
+ `skipValidation` field requires HANDLE_CHECKOUTS and AUTHENTICATED_APP permissions.
+
Triggers the following webhook events:
- CHECKOUT_CREATED (async): A checkout was created.
"""
@@ -16342,10 +16391,19 @@ type Mutation {
Note: this API is currently in Feature Preview and can be subject to changes at later point.
Requires the following permissions: OWNER and HANDLE_PAYMENTS for apps, HANDLE_PAYMENTS for staff users. Staff user cannot update a transaction that is owned by the app.
+
+ Triggers the following webhook events:
+ - TRANSACTION_ITEM_METADATA_UPDATED (async): Optionally called when transaction's metadata was updated.
+ - CHECKOUT_FULLY_PAID (async): Optionally called when the checkout charge status changed to `FULL` or `OVERCHARGED`.
+ - ORDER_UPDATED (async): Optionally called when the transaction is related to the order and the order was updated.
"""
transactionEventReport(
- """The amount of the event to report."""
- amount: PositiveDecimal!
+ """
+ The amount of the event to report.
+
+ Required for all `REQUEST`, `SUCCESS`, `ACTION_REQUIRED`, and `ADJUSTMENT` events. For other events, the amount will be calculated based on the previous events with the same pspReference. If not possible to calculate, the mutation will return an error.
+ """
+ amount: PositiveDecimal
"""List of all possible actions for the transaction"""
availableActions: [TransactionActionEnum!]
@@ -16376,6 +16434,20 @@ type Mutation {
"""
token: UUID
+ """
+ Fields required to update the transaction metadata.
+
+ Added in Saleor 3.17.
+ """
+ transactionMetadata: [MetadataInput!]
+
+ """
+ Fields required to update the transaction private metadata.
+
+ Added in Saleor 3.17.
+ """
+ transactionPrivateMetadata: [MetadataInput!]
+
"""Current status of the event to report."""
type: TransactionEventTypeEnum!
): TransactionEventReport
@@ -17277,6 +17349,13 @@ type Order implements Node & ObjectWithMetadata {
"""Translated discount name."""
translatedDiscountName: String @deprecated(reason: "This field will be removed in Saleor 4.0. Use the `discounts` field instead. ")
+ """
+ Undiscounted total price of shipping.
+
+ Added in Saleor 3.19.
+ """
+ undiscountedShippingPrice: Money
+
"""Undiscounted total amount of the order."""
undiscountedTotal: TaxedMoney!
@@ -18298,6 +18377,7 @@ enum OrderEventsEnum {
PAYMENT_REFUNDED
PAYMENT_VOIDED
PLACED
+ PLACED_AUTOMATICALLY_FROM_PAID_CHECKOUT
PLACED_FROM_DRAFT
REMOVED_PRODUCTS
TRACKING_UPDATED
@@ -18338,6 +18418,7 @@ input OrderFilterInput {
channels: [ID!]
chargeStatus: [OrderChargeStatusEnum!]
checkoutIds: [ID!]
+ checkoutTokens: [UUID!]
created: DateRangeInput
customer: String
giftCardBought: Boolean
@@ -18895,6 +18976,13 @@ type OrderLine implements Node & ObjectWithMetadata {
"""
isGift: Boolean
+ """
+ Returns True, if the line unit price was overridden.
+
+ Added in Saleor 3.14.
+ """
+ isPriceOverridden: Boolean
+
"""Whether the product variant requires shipping."""
isShippingRequired: Boolean!
@@ -20903,6 +20991,7 @@ enum PaymentErrorCode {
BALANCE_CHECK_ERROR
BILLING_ADDRESS_NOT_SET
CHANNEL_INACTIVE
+ CHECKOUT_COMPLETION_IN_PROGRESS
CHECKOUT_EMAIL_NOT_SET
GRAPHQL_ERROR
INVALID
@@ -25382,13 +25471,9 @@ input PromotionCreateInput {
"""
Defines the promotion type. Implicate the required promotion rules predicate type and whether the promotion rules will give the catalogue or order discount.
- The default value is `Catalogue`.
-
- This field will be required from Saleor 3.20.
-
Added in Saleor 3.19.
"""
- type: PromotionTypeEnum
+ type: PromotionTypeEnum!
}
"""
@@ -26784,7 +26869,7 @@ type Query {
"""
Look up a checkout by id.
- Requires one of the following permissions to query checkouts that belong to other users: MANAGE_CHECKOUTS, IMPERSONATE_USER.
+ Requires one of the following permissions to query a checkout, if a checkout is in inactive channel: MANAGE_CHECKOUTS, IMPERSONATE_USER, HANDLE_PAYMENTS.
"""
checkout(
"""
@@ -26828,7 +26913,7 @@ type Query {
"""
List of checkouts.
- Requires one of the following permissions: MANAGE_CHECKOUTS.
+ Requires one of the following permissions: MANAGE_CHECKOUTS, HANDLE_PAYMENTS.
"""
checkouts(
"""Return the elements in the list that come after the specified cursor."""
@@ -26919,7 +27004,7 @@ type Query {
): CollectionCountableConnection
"""
- List of the shop's customers.
+ List of the shop's customers. This list includes all users who registered through the accountRegister mutation. Additionally, staff users who have placed an order using their account will also appear in this list.
Requires one of the following permissions: MANAGE_ORDERS, MANAGE_USERS.
"""
@@ -27263,7 +27348,9 @@ type Query {
"""
External ID of an order.
- Added in Saleor 3.10.
+ Added in Saleor 3.10..
+
+ Requires one of the following permissions: MANAGE_ORDERS.
"""
externalReference: String
@@ -27877,7 +27964,7 @@ type Query {
Requires one of the following permissions: MANAGE_PRODUCTS.
"""
stock(
- """ID of an warehouse"""
+ """ID of a stock"""
id: ID!
): Stock
@@ -29234,7 +29321,7 @@ type ShippingMethodTranslation implements Node {
language: LanguageDisplay!
"""Translated shipping method name."""
- name: String!
+ name: String
"""
Represents the shipping method fields to translate.
@@ -30104,7 +30191,7 @@ type Shop implements ObjectWithMetadata {
Requires one of the following permissions: AUTHENTICATED_STAFF_USER.
"""
- limits: LimitInfo!
+ limits: LimitInfo! @deprecated(reason: "This field will be removed in Saleor 4.0.")
"""List of public metadata items. Can be accessed without permissions."""
metadata: [MetadataItem!]!
@@ -31141,12 +31228,222 @@ input StringFilterInput {
}
type Subscription {
+ """
+ Event sent when new draft order is created.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ draftOrderCreated(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): DraftOrderCreated
+
+ """
+ Event sent when draft order is deleted.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ draftOrderDeleted(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): DraftOrderDeleted
+
+ """
+ Event sent when draft order is updated.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ draftOrderUpdated(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): DraftOrderUpdated
+
"""
Look up subscription event.
Added in Saleor 3.2.
"""
event: Event
+
+ """
+ Event sent when orders are imported.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ orderBulkCreated(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): OrderBulkCreated
+
+ """
+ Event sent when order is cancelled.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ orderCancelled(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): OrderCancelled
+
+ """
+ Event sent when order is confirmed.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ orderConfirmed(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): OrderConfirmed
+
+ """
+ Event sent when new order is created.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ orderCreated(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): OrderCreated
+
+ """
+ Event sent when order becomes expired.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ orderExpired(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): OrderExpired
+
+ """
+ Event sent when order is fulfilled.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ orderFulfilled(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): OrderFulfilled
+
+ """
+ Event sent when order is fully paid.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ orderFullyPaid(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): OrderFullyPaid
+
+ """
+ The order is fully refunded.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ orderFullyRefunded(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): OrderFullyRefunded
+
+ """
+ Event sent when order metadata is updated.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ orderMetadataUpdated(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): OrderMetadataUpdated
+
+ """
+ Payment has been made. The order may be partially or fully paid.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ orderPaid(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): OrderPaid
+
+ """
+ The order received a refund. The order may be partially or fully refunded.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ orderRefunded(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): OrderRefunded
+
+ """
+ Event sent when order is updated.
+
+ Added in Saleor 3.20.
+
+ Note: this API is currently in Feature Preview and can be subject to changes at later point.
+ """
+ orderUpdated(
+ """
+ List of channel slugs. The event will be sent only if the order belongs to one of the provided channels. If the channel slug list is empty, orders that belong to any channel will be sent. Maximally 500 items.
+ """
+ channels: [String!]
+ ): OrderUpdated
}
enum TaxCalculationStrategy {
@@ -31765,7 +32062,9 @@ type TaxableObject {
"""Determines if prices contain entered tax.."""
pricesEnteredWithTax: Boolean!
- """The price of shipping method."""
+ """
+ The price of shipping method, includes shipping voucher discount if applied.
+ """
shippingPrice: Money!
"""The source object related to this tax object."""
@@ -31779,6 +32078,19 @@ type TaxableObjectDiscount {
"""The name of the discount."""
name: String
+
+ """
+ Indicates which part of the order the discount should affect: SUBTOTAL or SHIPPING.
+ """
+ type: TaxableObjectDiscountTypeEnum!
+}
+
+"""
+Indicates which part of the order the discount should affect: SUBTOTAL or SHIPPING.
+"""
+enum TaxableObjectDiscountTypeEnum {
+ SHIPPING
+ SUBTOTAL
}
type TaxableObjectLine {
@@ -31797,10 +32109,14 @@ type TaxableObjectLine {
"""The source line related to this tax line."""
sourceLine: TaxSourceLine!
- """Price of the order line."""
+ """
+ Price of the order line. The price includes catalogue promotions, specific product and applied once per order voucher discounts. The price does not include the entire order discount.
+ """
totalPrice: Money!
- """Price of the single item in the order line."""
+ """
+ Price of the single item in the order line. The price includes catalogue promotions, specific product and applied once per order voucher discounts. The price does not include the entire order discount.
+ """
unitPrice: Money!
"""The variant name."""
@@ -32219,6 +32535,11 @@ Added in Saleor 3.13.
Note: this API is currently in Feature Preview and can be subject to changes at later point.
Requires the following permissions: OWNER and HANDLE_PAYMENTS for apps, HANDLE_PAYMENTS for staff users. Staff user cannot update a transaction that is owned by the app.
+
+Triggers the following webhook events:
+- TRANSACTION_ITEM_METADATA_UPDATED (async): Optionally called when transaction's metadata was updated.
+- CHECKOUT_FULLY_PAID (async): Optionally called when the checkout charge status changed to `FULL` or `OVERCHARGED`.
+- ORDER_UPDATED (async): Optionally called when the transaction is related to the order and the order was updated.
"""
type TransactionEventReport {
"""Defines if the reported event hasn't been processed earlier."""
@@ -32254,6 +32575,7 @@ enum TransactionEventReportErrorCode {
INCORRECT_DETAILS
INVALID
NOT_FOUND
+ REQUIRED
}
"""
@@ -32351,6 +32673,7 @@ type TransactionInitializeError {
"""An enumeration."""
enum TransactionInitializeErrorCode {
+ CHECKOUT_COMPLETION_IN_PROGRESS
GRAPHQL_ERROR
INVALID
NOT_FOUND
@@ -32651,6 +32974,7 @@ type TransactionProcessError {
"""An enumeration."""
enum TransactionProcessErrorCode {
+ CHECKOUT_COMPLETION_IN_PROGRESS
GRAPHQL_ERROR
INVALID
MISSING_PAYMENT_APP
@@ -34550,6 +34874,31 @@ type Warehouse implements Node & ObjectWithMetadata {
"""Warehouse slug."""
slug: String!
+
+ """
+ Stocks that belong to this warehouse.
+
+ Added in Saleor 3.20.
+
+ Requires one of the following permissions: MANAGE_PRODUCTS, MANAGE_ORDERS.
+ """
+ stocks(
+ """Return the elements in the list that come after the specified cursor."""
+ after: String
+
+ """Return the elements in the list that come before the specified cursor."""
+ before: String
+
+ """
+ Retrieve the first n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query.
+ """
+ first: Int
+
+ """
+ Retrieve the last n elements from the list. Note that the system only allows fetching a maximum of 100 objects in a single query.
+ """
+ last: Int
+ ): StockCountableConnection
}
"""An enumeration."""
@@ -34918,7 +35267,7 @@ input WebhookCreateInput {
asyncEvents: [WebhookEventTypeAsyncEnum!]
"""
- Custom headers, which will be added to HTTP request. There is a limitation of 5 headers per webhook and 998 characters per header.Only "X-*" and "Authorization*" keys are allowed.
+ Custom headers, which will be added to HTTP request. There is a limitation of 5 headers per webhook and 998 characters per header.Only `X-*`, `Authorization*`, and `BrokerProperties` keys are allowed.
Added in Saleor 3.12.
@@ -36529,7 +36878,7 @@ input WebhookUpdateInput {
asyncEvents: [WebhookEventTypeAsyncEnum!]
"""
- Custom headers, which will be added to HTTP request. There is a limitation of 5 headers per webhook and 998 characters per header.Only "X-*" and "Authorization*" keys are allowed.
+ Custom headers, which will be added to HTTP request. There is a limitation of 5 headers per webhook and 998 characters per header.Only `X-*`, `Authorization*`, and `BrokerProperties` keys are allowed.
Added in Saleor 3.12.
diff --git a/scripts/pika.js b/scripts/pika.js
deleted file mode 100644
index 8d3469dd0a7..00000000000
--- a/scripts/pika.js
+++ /dev/null
@@ -1,34 +0,0 @@
-
-const image = `
-
-████████╗███████╗░██████╗████████╗ ██████╗░░█████╗░░██████╗░██████╗███████╗██████╗░ ██╗
-╚══██╔══╝██╔════╝██╔════╝╚══██╔══╝ ██╔══██╗██╔══██╗██╔════╝██╔════╝██╔════╝██╔══██╗ ██║
-░░░██║░░░█████╗░░╚█████╗░░░░██║░░░ ██████╔╝███████║╚█████╗░╚█████╗░█████╗░░██║░░██║ ██║
-░░░██║░░░██╔══╝░░░╚═══██╗░░░██║░░░ ██╔═══╝░██╔══██║░╚═══██╗░╚═══██╗██╔══╝░░██║░░██║ ╚═╝
-░░░██║░░░███████╗██████╔╝░░░██║░░░ ██║░░░░░██║░░██║██████╔╝██████╔╝███████╗██████╔╝ ██╗
-░░░╚═╝░░░╚══════╝╚═════╝░░░░╚═╝░░░ ╚═╝░░░░░╚═╝░░╚═╝╚═════╝░╚═════╝░╚══════╝╚═════╝░ ╚═╝
-
-.//////:-.\`-[1;33mh[0m[1;33my[0mo/----.:////////////////////::o++++++++oooo++\`
-.//////-/+-.[1;33my[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33ms[0m/:.-////////////////////:-oo++oooooo+++++\`
-./////::ooo::[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33ms[0m/:////////////////////-/o+o++/+o[1;33ms[0m[1;33my[0m[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m.
-.////:-/++++/+[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0mo/://///////////////:-/++[1;33ms[0m[1;33my[0m[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m.
-.///:.-::--:/:/[1;33my[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33my[0m+///////////////++o[1;33my[0m[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33ms[0m\`
-.///-.----------+[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33mh[0m[1;33mh[0m[1;33mh[0m[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33my[0m[1;33ms[0m+\`
-.//:.------------:[1;33mo[1;33mh[0m[1;33mh[0m[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33ms[0m/:::\`
-.//-.---------..----[1;33mo[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33mh[0m[1;33my[0m+:::---\`
-./:......----..\`\`.-:[1;33my[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m+::::----\`
-.:..---..----.\`\`.-.[1;33mo[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33my[30mo+[1;33my[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33my[0m[1;30my[1;30m/[1;30m+[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m/-::::::\`
-.-\`--.......----:-:[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33ms[30m/:.+[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[1;30m+[1;30m/[1;30m.[1;30m.[1;33ms[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33my[0m-//////\`
-.\`...\`\`\`\`\`\`\`---::-[1;33mo[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33my[0m[1;33ms[33mo[1;33my[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33my[0m[1;33my[0m[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33my[0m[1;33ms[0m[1;33ms[0m[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m+/+////\`
-\`.--.\`\`\`\`\`\`.-:::-[1;31m.[1;31m/[1;31m0[1;33ms[0m[1;33my[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33ms[30mo[1;33ms[0m[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33my[0m[1;31my[0m[1;31my[0m[1;31my[0m[1;33mh[0m[1;33md[0m[1;33md[0m[1;33ms[0m/++++/\`
-\`------:::::::::.[1;31m-[1;31m+[1;31m+[1;31m+[1;31m+[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33mh[0m[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33ms[31m++++o[1;33mh[0m[1;33md[0m[1;33mh[0m//++//\`
-\`----------::::-.[1;31m:[1;31m/[1;31m+[1;31m+[1;31mo[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[1;33m+[35m/+ooo[1;33ms[0m[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[31mo+++++[1;33mh[0m[1;33md[0m[1;33md[0m[1;33my[0m:////\`
-.:-------------.-[1;33my[0m[1;33ms[0m[1;33ms[0m[1;33my[0m[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[35m/oyyyyo[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33ms[0m[1;33ms[0m[1;33ms[0m[1;33ms[0m[1;33my[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m+////\`
--:---------------o[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33my[35moossoo[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33my[0m:+//\`
-.--://///++++////:o[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m[1;33mh[0m[1;33mh[0m[1;33mh[0m[1;33mh[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33mh[0m/:::\`
-.------:://////:::/[1;33my[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0m[1;33md[0mo:::\`
-\`---------:///////:o[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33my[0m[1;33ms[0m---\`
-`;
-
-
-console.log(image)
\ No newline at end of file
diff --git a/src/apps/apps-routing.tsx b/src/apps/apps-routing.tsx
index 95dc9279bde..406b804893a 100644
--- a/src/apps/apps-routing.tsx
+++ b/src/apps/apps-routing.tsx
@@ -1,11 +1,12 @@
import { AppDetailsUrlQueryParams, AppInstallUrlQueryParams } from "@dashboard/apps/urls";
import SectionRoute from "@dashboard/auth/components/SectionRoute";
+import { Route } from "@dashboard/components/Router";
import { PermissionEnum } from "@dashboard/graphql";
import { sectionNames } from "@dashboard/intl";
import { parse as parseQs } from "qs";
import React from "react";
import { useIntl } from "react-intl";
-import { Route, RouteComponentProps, Switch } from "react-router-dom";
+import { RouteComponentProps, Switch } from "react-router-dom";
import {
AppInstallView,
AppListView,
diff --git a/src/apps/components/AllAppList/AllAppList.tsx b/src/apps/components/AllAppList/AllAppList.tsx
index c79a2ed7439..23f8c55c2b1 100644
--- a/src/apps/components/AllAppList/AllAppList.tsx
+++ b/src/apps/components/AllAppList/AllAppList.tsx
@@ -1,13 +1,12 @@
import { AppstoreApi } from "@dashboard/apps/appstore.types";
import { AppInstallationFragment } from "@dashboard/graphql";
-import { Skeleton } from "@material-ui/lab";
import { Box, useTheme } from "@saleor/macaw-ui-next";
import React from "react";
import AppListRow from "../AppListRow";
interface AllAppListProps {
- appList?: AppstoreApi.SaleorApp[];
+ appList: AppstoreApi.SaleorApp[];
appInstallationList?: AppInstallationFragment[];
navigateToAppInstallPage?: (manifestUrl: string) => void;
navigateToGithubForkPage?: (githubForkUrl: string) => void;
@@ -21,10 +20,6 @@ const AllAppList: React.FC = ({
}) => {
const { themeValues } = useTheme();
- if (!appList) {
- return ;
- }
-
return (
= ({
title={intl.formatMessage(msgs.activateAppTitle)}
variant="default"
>
- {getMainText()}
+ {getMainText()}
);
};
diff --git a/src/apps/components/AppAvatar/AppAvatar.tsx b/src/apps/components/AppAvatar/AppAvatar.tsx
index d8309c90198..d978321d9a9 100644
--- a/src/apps/components/AppAvatar/AppAvatar.tsx
+++ b/src/apps/components/AppAvatar/AppAvatar.tsx
@@ -3,7 +3,7 @@ import { Box, GenericAppIcon } from "@saleor/macaw-ui-next";
import React from "react";
type Logo = AppLogo | undefined;
-type Size = 8 | 12;
+type Size = 4 | 8 | 12;
export const AppAvatar: React.FC<{
logo?: Logo;
diff --git a/src/apps/components/AppDeactivateDialog/AppDeactivateDialog.tsx b/src/apps/components/AppDeactivateDialog/AppDeactivateDialog.tsx
index 169ed127ff9..9f2341ed1d4 100644
--- a/src/apps/components/AppDeactivateDialog/AppDeactivateDialog.tsx
+++ b/src/apps/components/AppDeactivateDialog/AppDeactivateDialog.tsx
@@ -2,7 +2,7 @@ import ActionDialog from "@dashboard/components/ActionDialog";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
import { buttonMessages } from "@dashboard/intl";
import { getStringOrPlaceholder } from "@dashboard/misc";
-import { DialogContentText } from "@material-ui/core";
+import { Box } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -47,7 +47,7 @@ const AppDeactivateDialog: React.FC = ({
title={intl.formatMessage(msgs.deactivateAppTitle)}
variant="delete"
>
-
+
{getMainText()}
{thirdParty && (
<>
@@ -55,7 +55,7 @@ const AppDeactivateDialog: React.FC = ({
>
)}
-
+
);
};
diff --git a/src/apps/components/AppDeleteDialog/AppDeleteDialog.tsx b/src/apps/components/AppDeleteDialog/AppDeleteDialog.tsx
index 822f1a46cf9..fb182137e27 100644
--- a/src/apps/components/AppDeleteDialog/AppDeleteDialog.tsx
+++ b/src/apps/components/AppDeleteDialog/AppDeleteDialog.tsx
@@ -1,7 +1,6 @@
import ActionDialog from "@dashboard/components/ActionDialog";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
import { getStringOrPlaceholder } from "@dashboard/misc";
-import { DialogContentText } from "@material-ui/core";
import { Box, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -57,7 +56,7 @@ const AppDeleteDialog: React.FC = ({
title={intl.formatMessage(msgs.deleteAppTitle)}
variant="delete"
>
-
+
= ({
borderColor="warning1"
borderStyle="solid"
>
- {intl.formatMessage(msgs.deleteAppWarning)}
+
+ {intl.formatMessage(msgs.deleteAppWarning)}
+
{getMainText()}
-
+
);
};
diff --git a/src/apps/components/AppDetailsPage/AboutCard.tsx b/src/apps/components/AppDetailsPage/AboutCard.tsx
index 2c6a515ef73..76a80580c57 100644
--- a/src/apps/components/AppDetailsPage/AboutCard.tsx
+++ b/src/apps/components/AppDetailsPage/AboutCard.tsx
@@ -1,5 +1,4 @@
-import Skeleton from "@dashboard/components/Skeleton";
-import { Box, BoxProps, Text } from "@saleor/macaw-ui-next";
+import { Box, BoxProps, Skeleton, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
@@ -14,7 +13,7 @@ export const AboutCard: React.FC = ({ aboutApp, loading, ...boxP
const intl = useIntl();
const renderContent = () => {
if (loading) {
- return ;
+ return ;
}
if (aboutApp) {
diff --git a/src/apps/components/AppDetailsPage/DataPrivacyCard.tsx b/src/apps/components/AppDetailsPage/DataPrivacyCard.tsx
index 4aec25f2639..bfc6505e3d5 100644
--- a/src/apps/components/AppDetailsPage/DataPrivacyCard.tsx
+++ b/src/apps/components/AppDetailsPage/DataPrivacyCard.tsx
@@ -1,6 +1,5 @@
import { ExternalLinkNext } from "@dashboard/components/ExternalLink";
-import Skeleton from "@dashboard/components/Skeleton";
-import { Box, BoxProps, Text } from "@saleor/macaw-ui-next";
+import { Box, BoxProps, Skeleton, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
diff --git a/src/apps/components/AppDetailsPage/PermissionsCard.tsx b/src/apps/components/AppDetailsPage/PermissionsCard.tsx
index 3e879ea96cf..b2428f5d260 100644
--- a/src/apps/components/AppDetailsPage/PermissionsCard.tsx
+++ b/src/apps/components/AppDetailsPage/PermissionsCard.tsx
@@ -1,10 +1,9 @@
import { AppPermissionsDialog } from "@dashboard/apps/components/AppPermissionsDialog";
import { ButtonWithTooltip } from "@dashboard/components/ButtonWithTooltip";
-import Skeleton from "@dashboard/components/Skeleton";
import { PermissionEnum } from "@dashboard/graphql";
import { useHasManagedAppsPermission } from "@dashboard/hooks/useHasManagedAppsPermission";
import { buttonMessages } from "@dashboard/intl";
-import { Box, BoxProps, Text } from "@saleor/macaw-ui-next";
+import { Box, BoxProps, Skeleton, Text } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
diff --git a/src/apps/components/AppDialog/AppDialog.tsx b/src/apps/components/AppDialog/AppDialog.tsx
index d2cddc4a733..f7991d6da8a 100644
--- a/src/apps/components/AppDialog/AppDialog.tsx
+++ b/src/apps/components/AppDialog/AppDialog.tsx
@@ -1,35 +1,23 @@
-import {
- Dialog,
- DialogContent,
- DialogProps,
- DialogTitle,
- IconButton,
- Typography,
-} from "@material-ui/core";
-import CloseIcon from "@material-ui/icons/Close";
+import { DashboardModal } from "@dashboard/components/Modal";
+import { Box } from "@saleor/macaw-ui-next";
import React from "react";
-import { useStyles } from "./styles";
-
-interface AppDialogProps extends DialogProps {
+interface AppDialogProps {
+ title?: string;
onClose: () => void;
+ open: boolean;
}
-export const AppDialog: React.FC = ({ children, ...props }) => {
- const classes = useStyles();
-
+export const AppDialog: React.FC = ({ children, title, onClose, ...props }) => {
return (
-
-
-
- {props.title}
-
-
-
-
-
- {children}
-
+
+
+ {title}
+
+ {children}
+
+
+
);
};
diff --git a/src/apps/components/AppDialog/styles.ts b/src/apps/components/AppDialog/styles.ts
deleted file mode 100644
index 2066b06c90e..00000000000
--- a/src/apps/components/AppDialog/styles.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { makeStyles } from "@saleor/macaw-ui";
-
-export const useStyles = makeStyles(
- () => ({
- header: {
- display: "flex",
- justifyContent: "space-between",
- alignItems: "center",
- },
- content: {
- margin: 0,
- padding: 0,
- overflow: "hidden",
- width: 600,
- height: 600,
- },
- }),
- { name: "AppDialog" },
-);
diff --git a/src/apps/components/AppFrame/appActionsHandler.test.ts b/src/apps/components/AppFrame/appActionsHandler.test.ts
index ec2996d3b87..551be12b661 100644
--- a/src/apps/components/AppFrame/appActionsHandler.test.ts
+++ b/src/apps/components/AppFrame/appActionsHandler.test.ts
@@ -56,7 +56,7 @@ describe("AppActionsHandler", function () {
jest.clearAllMocks();
});
/**
- * jsdom doesnt allow src code to write to window.location.href,
+ * jsdom doesn't allow src code to write to window.location.href,
* so totally replace this object so its writeable
*
* @see https://wildwolf.name/jest-how-to-mock-window-location-href/
@@ -75,12 +75,14 @@ describe("AppActionsHandler", function () {
});
describe("useHandleNotificationAction", () => {
it("Calls useNotifier with payload from action", () => {
+ // Arrange
const {
result: {
current: { handle },
},
} = renderHook(() => AppActionsHandler.useHandleNotificationAction());
+ // Act
handle({
type: "notification",
payload: {
@@ -90,6 +92,8 @@ describe("AppActionsHandler", function () {
title: "Test title",
},
});
+
+ // Assert
expect(mockNotify).toHaveBeenCalledTimes(1);
expect(mockNotify).toHaveBeenCalledWith({
status: "success",
@@ -100,6 +104,7 @@ describe("AppActionsHandler", function () {
});
describe("useUpdateRoutingAction", () => {
it("Updates dashboard url properly", () => {
+ // Arrange
const mockHistoryPushState = jest.fn();
jest.spyOn(window.history, "pushState").mockImplementation(mockHistoryPushState);
@@ -110,6 +115,7 @@ describe("AppActionsHandler", function () {
},
} = renderHook(() => AppActionsHandler.useHandleUpdateRoutingAction("XYZ"));
+ // Act
handle({
type: "updateRouting",
payload: {
@@ -117,6 +123,8 @@ describe("AppActionsHandler", function () {
newRoute: "/foo/bar",
},
});
+
+ // Assert
expect(mockHistoryPushState).toHaveBeenCalledTimes(1);
expect(mockHistoryPushState).toHaveBeenCalledWith(
null,
@@ -124,6 +132,32 @@ describe("AppActionsHandler", function () {
"/dashboard/apps/XYZ/app/foo/bar",
);
});
+
+ it("Does not update url if it's already updated", () => {
+ // Arrange
+ const mockHistoryPushState = jest.fn();
+
+ window.location.pathname = "/dashboard/apps/XYZ/app/foo/bar";
+ jest.spyOn(window.history, "pushState").mockImplementation(mockHistoryPushState);
+
+ const {
+ result: {
+ current: { handle },
+ },
+ } = renderHook(() => AppActionsHandler.useHandleUpdateRoutingAction("XYZ"));
+
+ // Act
+ handle({
+ type: "updateRouting",
+ payload: {
+ actionId: "123",
+ newRoute: "/foo/bar",
+ },
+ });
+
+ // Assert
+ expect(mockHistoryPushState).not.toHaveBeenCalled();
+ });
});
describe("useHandleRedirectAction", () => {
describe("Open in the new browser context", () => {
@@ -137,6 +171,7 @@ describe("AppActionsHandler", function () {
jest.spyOn(window, "open").mockImplementation(mockWindowOpen);
});
it("Opens external URL in new browser context", () => {
+ // Arrange & Act
hookRenderResult.result.current.handle({
type: "redirect",
payload: {
@@ -145,10 +180,13 @@ describe("AppActionsHandler", function () {
newContext: true,
},
});
+
+ // Assert
expect(mockWindowOpen).toHaveBeenCalledTimes(1);
expect(mockWindowOpen).toHaveBeenCalledWith("https://google.com");
});
it("Opens another dashboard url in new browser context", () => {
+ // Arrange & Act
hookRenderResult.result.current.handle({
type: "redirect",
payload: {
@@ -157,6 +195,8 @@ describe("AppActionsHandler", function () {
newContext: true,
},
});
+
+ // Assert
expect(mockWindowOpen).toHaveBeenCalledTimes(1);
expect(mockWindowOpen).toHaveBeenCalledWith("/dashboard/orders");
});
@@ -166,6 +206,7 @@ describe("AppActionsHandler", function () {
* TODO Drop this behavior, updateRouting action can do that explicitely
*/
it("Opens another app route in new browser context", () => {
+ // Arrange & Act
hookRenderResult.result.current.handle({
type: "redirect",
payload: {
@@ -174,6 +215,8 @@ describe("AppActionsHandler", function () {
newContext: true,
},
});
+
+ // Assert
expect(mockWindowOpen).toHaveBeenCalledTimes(1);
expect(mockWindowOpen).toHaveBeenCalledWith("/dashboard/apps/XYZ/app/config");
});
@@ -184,6 +227,7 @@ describe("AppActionsHandler", function () {
const hookRenderResult = renderHook(() => AppActionsHandler.useHandleRedirectAction("XYZ"));
it("Redirects to external URL after confirmation", () => {
+ // Arrange & Act
hookRenderResult.result.current.handle({
type: "redirect",
payload: {
@@ -192,9 +236,12 @@ describe("AppActionsHandler", function () {
newContext: false,
},
});
+
+ // Assert
expect(window.location.href).toBe("https://google.com");
});
it("Opens another dashboard url", () => {
+ // Arrange & Act
hookRenderResult.result.current.handle({
type: "redirect",
payload: {
@@ -203,14 +250,19 @@ describe("AppActionsHandler", function () {
newContext: false,
},
});
+
+ // Assert
expect(mockNavigate).toHaveBeenCalledTimes(1);
expect(mockNavigate).toHaveBeenCalledWith("/orders");
});
it("Update route within the same app", () => {
+ // Arrange
const mockHistoryPushState = jest.fn();
jest.spyOn(window.history, "pushState").mockImplementation(mockHistoryPushState);
window.location.pathname = "/apps/XYZ/app/foo";
+
+ // Act
hookRenderResult.result.current.handle({
type: "redirect",
payload: {
@@ -219,6 +271,8 @@ describe("AppActionsHandler", function () {
newContext: false,
},
});
+
+ // Assert
expect(mockHistoryPushState).toHaveBeenCalledTimes(1);
expect(mockHistoryPushState).toHaveBeenCalledWith(
null,
@@ -230,10 +284,12 @@ describe("AppActionsHandler", function () {
});
describe("useHandlePermissionRequest", () => {
it("Redirects to a dedicated page with params from action", () => {
+ // Arrange
const hookRenderResult = renderHook(() =>
AppActionsHandler.useHandlePermissionRequest("XYZ"),
);
+ // Act
hookRenderResult.result.current.handle({
type: "requestPermissions",
payload: {
@@ -242,6 +298,8 @@ describe("AppActionsHandler", function () {
redirectPath: "/permissions-result",
},
});
+
+ // Assert
expect(mockNavigate).toHaveBeenCalledTimes(1);
expect(mockNavigate).toHaveBeenCalledWith(
"/apps/XYZ/permissions?redirectPath=%2Fpermissions-result&requestedPermissions=MANAGE_ORDERS%2CMANAGE_CHANNELS",
diff --git a/src/apps/components/AppFrame/appActionsHandler.ts b/src/apps/components/AppFrame/appActionsHandler.ts
index 6453491f7d7..c127908d600 100644
--- a/src/apps/components/AppFrame/appActionsHandler.ts
+++ b/src/apps/components/AppFrame/appActionsHandler.ts
@@ -150,6 +150,12 @@ const useHandleUpdateRoutingAction = (appId: string) => ({
action.payload.newRoute,
);
+ if (window.location.pathname === exactLocation) {
+ debug("Current route is the same as requested change, skipping navigation.");
+
+ return createResponseStatus(actionId, true);
+ }
+
debug(`Update to new nested route: %s`, exactLocation);
window.history.pushState(null, "", exactLocation);
diff --git a/src/apps/components/AppInProgressDeleteDialog/AppInProgressDeleteDialog.tsx b/src/apps/components/AppInProgressDeleteDialog/AppInProgressDeleteDialog.tsx
index a672eb49240..c453708fbe2 100644
--- a/src/apps/components/AppInProgressDeleteDialog/AppInProgressDeleteDialog.tsx
+++ b/src/apps/components/AppInProgressDeleteDialog/AppInProgressDeleteDialog.tsx
@@ -1,7 +1,7 @@
import ActionDialog from "@dashboard/components/ActionDialog";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
import { getStringOrPlaceholder } from "@dashboard/misc";
-import { DialogContentText } from "@material-ui/core";
+import { Box } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
@@ -43,7 +43,7 @@ const AppInProgressDeleteDialog = ({
title={intl.formatMessage(msgs.header)}
variant="delete"
>
- {getMainText()}
+ {getMainText()}
);
};
diff --git a/src/apps/components/AppInstallErrorPage/AppInstallErrorPage.tsx b/src/apps/components/AppInstallErrorPage/AppInstallErrorPage.tsx
index 6a6942fa399..8b055ca3550 100644
--- a/src/apps/components/AppInstallErrorPage/AppInstallErrorPage.tsx
+++ b/src/apps/components/AppInstallErrorPage/AppInstallErrorPage.tsx
@@ -1,38 +1,65 @@
import errorImg from "@assets/images/app-install-error.svg";
-import { Button } from "@dashboard/components/Button";
-import Container from "@dashboard/components/Container";
-import { Grid, Typography } from "@material-ui/core";
+import { Box, Button, sprinkles, Text } from "@saleor/macaw-ui-next";
import React from "react";
+import SVG from "react-inlinesvg";
import { FormattedMessage } from "react-intl";
import messages from "./messages";
-import { useStyles } from "./styles";
interface AppInstallErrorPageProps {
onBack: () => void;
}
export const AppInstallErrorPage: React.FC = ({ onBack }) => {
- const classes = useStyles();
-
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
};
diff --git a/src/apps/components/AppInstallErrorPage/styles.ts b/src/apps/components/AppInstallErrorPage/styles.ts
deleted file mode 100644
index 270150971a3..00000000000
--- a/src/apps/components/AppInstallErrorPage/styles.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { makeStyles } from "@saleor/macaw-ui";
-
-export const useStyles = makeStyles(
- theme => ({
- button: {
- marginTop: theme.spacing(2),
- padding: theme.spacing(1.5, 2),
- },
- root: {
- "& > div": {
- minHeight: "80vh",
- },
- "& h3": {
- fontWeight: 600,
- marginBottom: theme.spacing(3),
- maxWidth: theme.spacing(60),
- },
- "& img": {
- maxWidth: "100%",
- },
- },
- }),
- {
- name: "AppInstallErrorPage",
- },
-);
diff --git a/src/apps/components/AppInstallPage/AppInstallPage.tsx b/src/apps/components/AppInstallPage/AppInstallPage.tsx
index b05f9e47db1..249bb8fe5a7 100644
--- a/src/apps/components/AppInstallPage/AppInstallPage.tsx
+++ b/src/apps/components/AppInstallPage/AppInstallPage.tsx
@@ -2,17 +2,15 @@ import plusIcon from "@assets/images/plus-icon.svg";
import saleorLogoDarkMode from "@assets/images/sidebar-deafult-logo-darkMode.png";
import saleorLogoLightMode from "@assets/images/sidebar-default-logo.png";
import { AppAvatar } from "@dashboard/apps/components/AppAvatar/AppAvatar";
+import { DashboardCard } from "@dashboard/components/Card";
import CardSpacer from "@dashboard/components/CardSpacer";
-import CardTitle from "@dashboard/components/CardTitle";
import Hr from "@dashboard/components/Hr";
import { DetailPageLayout } from "@dashboard/components/Layouts";
-import Skeleton from "@dashboard/components/Skeleton";
import { AppFetchMutation, AppInstallMutation } from "@dashboard/graphql";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import { buttonMessages } from "@dashboard/intl";
import { useTheme } from "@dashboard/theme";
-import { Card, CardContent, CircularProgress, Typography } from "@material-ui/core";
-import { Box, Button } from "@saleor/macaw-ui-next";
+import { Box, Button, Skeleton, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -51,28 +49,34 @@ export const AppInstallPage: React.FC = ({
-
-
- : intl.formatMessage(messages.title, { name })}
- data-test-id="app-installation-page-header"
- />
-
- {loading ? (
-
- ) : (
-
-
-
+
+
+
+ {loading ? (
+
+ ) : (
+ intl.formatMessage(messages.title, { name })
+ )}
+
+
+
+
+
+
+
+
+ {loading ? (
+
+
-
+ ) : (
= ({
: undefined
}
/>
-
- )}
-
-
+ )}
+
+
+
+
-
- {!loading && }
-
+
+
+
+
+ {intl.formatMessage(messages.permissionsTitle)}
+
+
+
{loading ? (
-
+ <>
+
+
+
+
+
+
+
+
+ >
) : (
<>
-
+
-
+
+
{!!data?.permissions?.length && (
{data?.permissions?.map(perm => {perm.name} )}
@@ -105,7 +125,7 @@ export const AppInstallPage: React.FC = ({
)}
-
+
= ({
)}
-
+
>
)}
-
-
+
+
+
+
diff --git a/src/apps/components/AppListPage/AppListPage.tsx b/src/apps/components/AppListPage/AppListPage.tsx
index 18fd62451f4..5b20a786662 100644
--- a/src/apps/components/AppListPage/AppListPage.tsx
+++ b/src/apps/components/AppListPage/AppListPage.tsx
@@ -4,7 +4,7 @@ import { useHasManagedAppsPermission } from "@dashboard/hooks/useHasManagedAppsP
import useNavigator from "@dashboard/hooks/useNavigator";
import { sectionNames } from "@dashboard/intl";
import { ListProps } from "@dashboard/types";
-import { Box, sprinkles, Text } from "@saleor/macaw-ui-next";
+import { Box, Skeleton, sprinkles, Text } from "@saleor/macaw-ui-next";
import React, { useCallback } from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -13,6 +13,7 @@ import InstalledAppList from "../InstalledAppList";
import { InstallWithManifestFormButton } from "../InstallWithManifestFormButton";
import MarketplaceAlert from "../MarketplaceAlert";
import { messages } from "./messages";
+import { MissingAppsFooter } from "./MissingAppsFooter";
import { useStyles } from "./styles";
import { AppListPageSections } from "./types";
import {
@@ -64,6 +65,9 @@ export const AppListPage: React.FC = props => {
window.open(githubForkUrl, "_blank");
}, []);
+ const showMissingAppsFooter =
+ !marketplaceError && verifiedInstallableMarketplaceApps && comingSoonMarketplaceApps;
+
return (
<>
@@ -98,12 +102,16 @@ export const AppListPage: React.FC = props => {
>
-
+ {verifiedInstallableMarketplaceApps ? (
+
+ ) : (
+
+ )}
)}
{sectionsAvailability.comingSoon && !marketplaceError && (
@@ -117,13 +125,18 @@ export const AppListPage: React.FC = props => {
>
{intl.formatMessage(messages.comingSoonApps)}
-
+ {comingSoonMarketplaceApps ? (
+
+ ) : (
+
+ )}
)}
+ {showMissingAppsFooter && }
>
);
diff --git a/src/apps/components/AppListPage/MissingAppsFooter.tsx b/src/apps/components/AppListPage/MissingAppsFooter.tsx
new file mode 100644
index 00000000000..c4d90237d7f
--- /dev/null
+++ b/src/apps/components/AppListPage/MissingAppsFooter.tsx
@@ -0,0 +1,36 @@
+import { MISSING_APPS_TYPEFORM_URL } from "@dashboard/links";
+import { Box, Button, Text } from "@saleor/macaw-ui-next";
+import React from "react";
+import { useIntl } from "react-intl";
+
+import { messages } from "./messages";
+
+const CONST_TYPEFORM_URL = `${MISSING_APPS_TYPEFORM_URL}?utm_button=${encodeURIComponent("Request integration")}`;
+
+export const MissingAppsFooter = () => {
+ const intl = useIntl();
+
+ return (
+
+
+
+ {intl.formatMessage(messages.missingAppsHeader)}
+
+
+ {intl.formatMessage(messages.missingAppsDescription)}
+
+
+ {intl.formatMessage(messages.missingAppsButton)}
+
+
+
+ );
+};
diff --git a/src/apps/components/AppListPage/messages.ts b/src/apps/components/AppListPage/messages.ts
index e5ba8b9f7a9..be199f68ae6 100644
--- a/src/apps/components/AppListPage/messages.ts
+++ b/src/apps/components/AppListPage/messages.ts
@@ -26,4 +26,19 @@ export const messages = defineMessages({
defaultMessage: "Upcoming Apps",
description: "section header",
},
+ missingAppsHeader: {
+ id: "Ntk3CQ",
+ defaultMessage: "Missing something?",
+ description: "footer title",
+ },
+ missingAppsDescription: {
+ id: "kyNv+Y",
+ defaultMessage: "Are we missing an integration your project requires? Let us know here",
+ description: "footer description",
+ },
+ missingAppsButton: {
+ id: "VlDG1B",
+ defaultMessage: "Request integration",
+ description: "Request integration",
+ },
});
diff --git a/src/apps/components/AppListRow/ErrorInstallAction.tsx b/src/apps/components/AppListRow/ErrorInstallAction.tsx
index 31b6e84b825..02e95f8c10c 100644
--- a/src/apps/components/AppListRow/ErrorInstallAction.tsx
+++ b/src/apps/components/AppListRow/ErrorInstallAction.tsx
@@ -1,14 +1,11 @@
import { appInstallationStatusMessages } from "@dashboard/apps/messages";
import { AppInstallationFragment } from "@dashboard/graphql";
import { buttonMessages } from "@dashboard/intl";
-import { Typography } from "@material-ui/core";
import { Button, Indicator, TooltipMountWrapper } from "@saleor/macaw-ui";
-import { Tooltip } from "@saleor/macaw-ui-next";
+import { sprinkles, Text, Tooltip } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage } from "react-intl";
-import { useActionsStyles } from "./styles";
-
interface InstallErrorActionProps {
appInstallation?: AppInstallationFragment;
retryInstall?: () => void;
@@ -20,15 +17,24 @@ const InstallErrorAction = ({
retryInstall,
removeInstall,
}: InstallErrorActionProps) => {
- const classes = useActionsStyles();
-
if (!retryInstall && !removeInstall) {
return null;
}
return (
<>
-
+
@@ -41,7 +47,7 @@ const InstallErrorAction = ({
{appInstallation?.message}
-
+
{retryInstall && (
diff --git a/src/apps/components/AppListRow/styles.ts b/src/apps/components/AppListRow/styles.ts
index 302f7f65ed7..e962ad1cc35 100644
--- a/src/apps/components/AppListRow/styles.ts
+++ b/src/apps/components/AppListRow/styles.ts
@@ -94,30 +94,3 @@ export const useIntegrationsStyles = makeStyles(
}),
{ name: "AppListCardIntegrations" },
);
-
-export const useActionsStyles = makeStyles(
- theme => ({
- cardActions: {
- display: "flex",
- justifyContent: "flex-end",
- padding: theme.spacing(2, 4),
- minHeight: theme.spacing(9),
- },
- cardActionsText: {
- width: "100%",
- },
- cardActionsIssueText: {
- width: "100%",
- color: theme.palette.error.main,
- whiteSpace: "nowrap",
- display: "flex",
- alignItems: "center",
- justifyContent: "flex-end",
- gap: theme.spacing(1),
- },
- releaseDate: {
- color: theme.palette.saleor.main[3],
- },
- }),
- { name: "AppListCardActions" },
-);
diff --git a/src/apps/components/AppManifestTableDisplay/AppManifestTableDisplay.tsx b/src/apps/components/AppManifestTableDisplay/AppManifestTableDisplay.tsx
index e89f8be3fb0..caa497361f0 100644
--- a/src/apps/components/AppManifestTableDisplay/AppManifestTableDisplay.tsx
+++ b/src/apps/components/AppManifestTableDisplay/AppManifestTableDisplay.tsx
@@ -1,7 +1,6 @@
import { appsMessages } from "@dashboard/apps/messages";
-import { Typography } from "@material-ui/core";
import { CopyIcon } from "@saleor/macaw-ui";
-import { Tooltip } from "@saleor/macaw-ui-next";
+import { Text, Tooltip } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React, { useState } from "react";
import { useIntl } from "react-intl";
@@ -22,7 +21,7 @@ export const AppManifestTableDisplay = ({ manifestUrl }: AppManifestTableDisplay
return (
- setCopied(false)}
className={styles.manifestText}
onClick={e => {
@@ -44,7 +43,7 @@ export const AppManifestTableDisplay = ({ manifestUrl }: AppManifestTableDisplay
})}
/>
)}
-
+
diff --git a/src/apps/components/AppPermissionsDialog/AppPermissionsDialog.tsx b/src/apps/components/AppPermissionsDialog/AppPermissionsDialog.tsx
index 823613eb14a..b645ef21db9 100644
--- a/src/apps/components/AppPermissionsDialog/AppPermissionsDialog.tsx
+++ b/src/apps/components/AppPermissionsDialog/AppPermissionsDialog.tsx
@@ -3,11 +3,10 @@ import { AppPermissionsDialogPermissionPicker } from "@dashboard/apps/components
import { useAppPermissionsDialogState } from "@dashboard/apps/components/AppPermissionsDialog/AppPermissionsDialogState";
import { AppPermissionsDialogMessages } from "@dashboard/apps/components/AppPermissionsDialog/messages";
import { useGetAvailableAppPermissions } from "@dashboard/apps/hooks/useGetAvailableAppPermissions";
+import { DashboardModal } from "@dashboard/components/Modal";
import { PermissionEnum, useAppQuery, useAppUpdatePermissionsMutation } from "@dashboard/graphql";
import useNotifier from "@dashboard/hooks/useNotifier";
-import { Dialog, DialogContent, DialogTitle } from "@material-ui/core";
-import { Skeleton } from "@material-ui/lab";
-import { Box, Text } from "@saleor/macaw-ui-next";
+import { Box, Skeleton, Text } from "@saleor/macaw-ui-next";
import React, { useEffect } from "react";
import { useIntl } from "react-intl";
@@ -110,9 +109,9 @@ export const AppPermissionsDialog = ({
};
return (
-
- {formatMessage(messages.heading)}
-
+
+
+ {formatMessage(messages.heading)}
{formatMessage(messages.info)}
{renderDialogContent()}
-
-
+
+
);
};
diff --git a/src/apps/components/AppPermissionsDialog/AppPermissionsDialogConfirmation.tsx b/src/apps/components/AppPermissionsDialog/AppPermissionsDialogConfirmation.tsx
index cc2bc5ea002..35647953c1d 100644
--- a/src/apps/components/AppPermissionsDialog/AppPermissionsDialogConfirmation.tsx
+++ b/src/apps/components/AppPermissionsDialog/AppPermissionsDialogConfirmation.tsx
@@ -1,7 +1,10 @@
import { AppPermissionsDialogMessages } from "@dashboard/apps/components/AppPermissionsDialog/messages";
import { useGetAvailableAppPermissions } from "@dashboard/apps/hooks/useGetAvailableAppPermissions";
+import BackButton from "@dashboard/components/BackButton";
+import { ConfirmButton } from "@dashboard/components/ConfirmButton";
+import { DashboardModal } from "@dashboard/components/Modal";
import { PermissionEnum } from "@dashboard/graphql";
-import { Box, Button, Text } from "@saleor/macaw-ui-next";
+import { Box, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
@@ -30,6 +33,7 @@ export const AppPermissionsDialogConfirmation = ({
{intl.formatMessage(messages.summaryText)}
+
{isPermissionsRemoved && (
@@ -42,6 +46,7 @@ export const AppPermissionsDialogConfirmation = ({
))}
)}
+
{isPermissionsAdded && (
@@ -54,23 +59,15 @@ export const AppPermissionsDialogConfirmation = ({
))}
)}
-
- {
- onBack();
- }}
- >
- {intl.formatMessage(messages.backButton)}
-
- {
- onApprove();
- }}
- >
+
+
+
+
+ {intl.formatMessage(messages.backButton)}
+
{intl.formatMessage(messages.confirmButton)}
-
-
+
+
);
};
diff --git a/src/apps/components/AppPermissionsDialog/AppPermissionsDialogPermissionPicker.tsx b/src/apps/components/AppPermissionsDialog/AppPermissionsDialogPermissionPicker.tsx
index 1fc132be2d2..a71daca1631 100644
--- a/src/apps/components/AppPermissionsDialog/AppPermissionsDialogPermissionPicker.tsx
+++ b/src/apps/components/AppPermissionsDialog/AppPermissionsDialogPermissionPicker.tsx
@@ -1,7 +1,10 @@
import { AppPermissionsDialogMessages } from "@dashboard/apps/components/AppPermissionsDialog/messages";
import { AppPermission } from "@dashboard/apps/components/AppPermissionsDialog/types";
+import BackButton from "@dashboard/components/BackButton";
+import { ConfirmButton } from "@dashboard/components/ConfirmButton";
+import { DashboardModal } from "@dashboard/components/Modal";
import { PermissionEnum } from "@dashboard/graphql";
-import { Box, Button, Checkbox, List, Text } from "@saleor/macaw-ui-next";
+import { Box, Checkbox, List, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
@@ -44,7 +47,7 @@ export const AppPermissionsDialogPermissionPicker = ({
onChange(values);
}}
>
-
+
{allPermissions.map(perm => {
const isAssigned = Boolean(selected.find(p => p === perm.code));
@@ -52,12 +55,11 @@ export const AppPermissionsDialogPermissionPicker = ({
return (
{perm.name}
@@ -66,12 +68,13 @@ export const AppPermissionsDialogPermissionPicker = ({
})}
-
-
- {intl.formatMessage(messages.closeButton)}
-
- {intl.formatMessage(messages.saveButton)}
-
+
+
+ {intl.formatMessage(messages.closeButton)}
+
+ {intl.formatMessage(messages.saveButton)}
+
+
);
};
diff --git a/src/apps/components/AppWebhooksDisplay/AppWebhooksAttemptDetails.tsx b/src/apps/components/AppWebhooksDisplay/AppWebhooksAttemptDetails.tsx
new file mode 100644
index 00000000000..6a29774b9e3
--- /dev/null
+++ b/src/apps/components/AppWebhooksDisplay/AppWebhooksAttemptDetails.tsx
@@ -0,0 +1,58 @@
+import { DateTime } from "@dashboard/components/Date";
+import { EventDeliveryAttemptFragment } from "@dashboard/graphql";
+import { Box, Text } from "@saleor/macaw-ui-next";
+import React from "react";
+
+interface AppWebhooksAttemptDetailsProps {
+ attempt: EventDeliveryAttemptFragment;
+}
+
+export const AppWebhooksAttemptDetails: React.FC = ({
+ attempt,
+}) => {
+ const { createdAt, status, responseStatusCode, response, id } = attempt;
+
+ return (
+
+
+
+
+
+
+
+ HTTP {" "}
+
+ {responseStatusCode}
+
+ Status :{" "}
+
+ {status}
+
+
+
+
+
+
+ {response}
+
+
+
+ );
+};
diff --git a/src/apps/components/AppWebhooksDisplay/AppWebhooksDisplay.tsx b/src/apps/components/AppWebhooksDisplay/AppWebhooksDisplay.tsx
index d66ec6513bb..b0b28807214 100644
--- a/src/apps/components/AppWebhooksDisplay/AppWebhooksDisplay.tsx
+++ b/src/apps/components/AppWebhooksDisplay/AppWebhooksDisplay.tsx
@@ -1,18 +1,11 @@
-import { DateTime } from "@dashboard/components/Date";
-import { EventDeliveryStatusEnum, useAppWebhookDeliveriesQuery } from "@dashboard/graphql";
+import { useAppWebhookDeliveriesQuery } from "@dashboard/graphql";
import { useHasManagedAppsPermission } from "@dashboard/hooks/useHasManagedAppsPermission";
-import {
- Accordion,
- Box,
- BoxProps,
- Chip,
- Skeleton,
- Text,
- ThemeTokensValues,
-} from "@saleor/macaw-ui-next";
+import { Accordion, Box, BoxProps, Chip, Skeleton, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
+import { EventDeliveriesList } from "./EventDeliveriesList";
+
interface AppWebhooksDisplayProps extends BoxProps {
appId: string;
}
@@ -39,53 +32,7 @@ const Wrapper = (boxProps: BoxProps) => {
);
};
-const mapDeliveryStatusToTextColor = (
- status: EventDeliveryStatusEnum,
-): keyof ThemeTokensValues["colors"]["text"] => {
- switch (status) {
- case EventDeliveryStatusEnum.FAILED:
- return "critical1";
- case EventDeliveryStatusEnum.PENDING:
- return "accent1";
- case EventDeliveryStatusEnum.SUCCESS:
- return "success1";
- }
-};
-const mapDeliveryStatusToBackgroundColor = (
- status: EventDeliveryStatusEnum,
-): keyof ThemeTokensValues["colors"]["background"] => {
- switch (status) {
- case EventDeliveryStatusEnum.FAILED:
- return "default2";
- case EventDeliveryStatusEnum.PENDING:
- return "default1";
- case EventDeliveryStatusEnum.SUCCESS:
- return "accent1";
- }
-};
-const DeliveryStatusDisplay = ({ status }: { status: EventDeliveryStatusEnum }) => {
- const { formatMessage } = useIntl();
- switch (status) {
- case EventDeliveryStatusEnum.FAILED:
- return <>{formatMessage({ defaultMessage: "Failed", id: "vXCeIi" })}>;
- case EventDeliveryStatusEnum.PENDING:
- return <>{formatMessage({ defaultMessage: "Pending", id: "eKEL/g" })}>;
- case EventDeliveryStatusEnum.SUCCESS:
- return <>{formatMessage({ defaultMessage: "Success", id: "xrKHS6" })} >;
- default:
- throw new Error("Invalid EventDeliveryStatusEnum value");
- }
-};
-const StatusChip = ({ status }: { status: EventDeliveryStatusEnum }) => {
- return (
-
-
-
-
-
- );
-};
const DisabledWebhookChip = () => {
const { formatMessage } = useIntl();
@@ -127,7 +74,7 @@ export const AppWebhooksDisplay = ({ appId, ...boxProps }: AppWebhooksDisplayPro
if (webhooksData?.app?.webhooks) {
return (
-
+
{webhooksData.app.webhooks.map((wh, index) => {
const isLastWebhook = index === (webhooksData?.app?.webhooks ?? []).length - 1;
const events = [...wh.asyncEvents, ...wh.syncEvents].flatMap(e => e.name).join(", ");
@@ -137,6 +84,7 @@ export const AppWebhooksDisplay = ({ appId, ...boxProps }: AppWebhooksDisplayPro
-
+
{formatMessage({
defaultMessage: "Pending & failed deliveries (last 10)",
@@ -169,45 +116,7 @@ export const AppWebhooksDisplay = ({ appId, ...boxProps }: AppWebhooksDisplayPro
- {eventDeliveries.map(ed => {
- const { createdAt } = ed.node;
- const attempts = ed.node.attempts?.edges ?? [];
- const attemptsCount = attempts.length;
- const lastAttemptDate = attempts[attemptsCount - 1]?.node.createdAt;
-
- return (
-
-
-
-
-
-
-
-
-
- {attempts.length > 0 && (
-
-
- {formatMessage({
- defaultMessage: "Attempts:",
- id: "OFTsI1",
- })}{" "}
-
- {attemptsCount} / 6
-
-
-
- {formatMessage({
- defaultMessage: "Last delivery attempt:",
- id: "EY/jqC",
- })}{" "}
-
-
-
- )}
-
- );
- })}
+
)}
diff --git a/src/apps/components/AppWebhooksDisplay/EventDeliveriesList.test.tsx b/src/apps/components/AppWebhooksDisplay/EventDeliveriesList.test.tsx
new file mode 100644
index 00000000000..e9a820a2e79
--- /dev/null
+++ b/src/apps/components/AppWebhooksDisplay/EventDeliveriesList.test.tsx
@@ -0,0 +1,143 @@
+import { EventDeliveryStatusEnum, WebhookEventTypeEnum } from "@dashboard/graphql";
+import { render } from "@testing-library/react";
+import React from "react";
+
+import { EventDeliveriesList, EventDelivery } from "./EventDeliveriesList";
+
+jest.mock("react-intl", () => ({
+ useIntl: jest.fn(() => ({
+ formatMessage: jest.fn(x => x.defaultMessage),
+ })),
+ defineMessages: jest.fn(x => x),
+ FormattedMessage: ({ defaultMessage }: { defaultMessage: any }) => <>{defaultMessage}>,
+}));
+
+describe("EventDeliveriesList", () => {
+ const mockEventDeliveries: EventDelivery[] = [
+ {
+ __typename: "EventDeliveryCountableEdge",
+ node: {
+ __typename: "EventDelivery",
+ id: "event-deliver-1",
+ eventType: WebhookEventTypeEnum.ORDER_CONFIRMED,
+ createdAt: "2023-01-02T00:00:00Z",
+ status: EventDeliveryStatusEnum.FAILED,
+ attempts: {
+ edges: [
+ {
+ __typename: "EventDeliveryAttemptCountableEdge",
+ node: {
+ createdAt: "2023-01-02T01:00:00Z",
+ id: "id-1",
+ response: '{"message":"Failed to send email"}',
+ responseStatusCode: 400,
+ status: EventDeliveryStatusEnum.FAILED,
+ __typename: "EventDeliveryAttempt",
+ },
+ },
+ ],
+ __typename: "EventDeliveryAttemptCountableConnection",
+ },
+ },
+ },
+ ];
+
+ const mockMultipleEventDeliveries: EventDelivery[] = [
+ {
+ __typename: "EventDeliveryCountableEdge",
+ node: {
+ __typename: "EventDelivery",
+ id: "event-deliver-1",
+ eventType: WebhookEventTypeEnum.ORDER_CONFIRMED,
+ createdAt: "2023-01-02T00:00:00Z",
+ status: EventDeliveryStatusEnum.FAILED,
+ attempts: {
+ edges: [
+ {
+ __typename: "EventDeliveryAttemptCountableEdge",
+ node: {
+ createdAt: "2024-01-02T01:00:00Z",
+ id: "id-1",
+ response: '{"message":"Failed to send email"}',
+ responseStatusCode: 400,
+ status: EventDeliveryStatusEnum.FAILED,
+ __typename: "EventDeliveryAttempt",
+ },
+ },
+ {
+ __typename: "EventDeliveryAttemptCountableEdge",
+ node: {
+ createdAt: "2024-01-02T01:10:00Z",
+ id: "id-2",
+ response: '{"message":"Failed to send email"}',
+ responseStatusCode: 400,
+ status: EventDeliveryStatusEnum.FAILED,
+ __typename: "EventDeliveryAttempt",
+ },
+ },
+ ],
+ __typename: "EventDeliveryAttemptCountableConnection",
+ },
+ },
+ },
+ {
+ __typename: "EventDeliveryCountableEdge",
+ node: {
+ __typename: "EventDelivery",
+ id: "event-deliver-2",
+ eventType: WebhookEventTypeEnum.ORDER_CONFIRMED,
+ createdAt: "2023-01-02T00:00:00Z",
+ status: EventDeliveryStatusEnum.SUCCESS,
+ attempts: {
+ edges: [
+ {
+ __typename: "EventDeliveryAttemptCountableEdge",
+ node: {
+ createdAt: "2024-01-03T01:00:00Z",
+ id: "id-2",
+ response: '{"message":"Failed to connect"}',
+ responseStatusCode: 400,
+ status: EventDeliveryStatusEnum.FAILED,
+ __typename: "EventDeliveryAttempt",
+ },
+ },
+ ],
+ __typename: "EventDeliveryAttemptCountableConnection",
+ },
+ },
+ },
+ ];
+
+ it("renders correctly with provided event delivery", () => {
+ // Arrange & Act
+ const { getByText } = render( );
+
+ // Assert
+ expect(getByText("FAILED")).toBeInTheDocument();
+ expect(getByText('{"message":"Failed to send email"}')).toBeInTheDocument();
+ expect(getByText("400")).toBeInTheDocument();
+ expect(getByText("1 / 6")).toBeInTheDocument();
+ });
+
+ it("render with multiple event deliveries", () => {
+ // Arrange & Act
+ const { getByTestId } = render(
+ ,
+ );
+
+ const firstContainer = getByTestId("event-deliver-1");
+ const secondContainer = getByTestId("event-deliver-2");
+
+ // Assert
+ expect(firstContainer).toBeInTheDocument();
+ expect(secondContainer).toBeInTheDocument();
+
+ expect(firstContainer.textContent).toContain("FAILED");
+ expect(firstContainer.textContent).toContain('{"message":"Failed to send email"}');
+ expect(firstContainer.textContent).toContain("2 / 6");
+
+ expect(secondContainer.textContent).toContain("FAILED");
+ expect(secondContainer.textContent).toContain('{"message":"Failed to connect"}');
+ expect(secondContainer.textContent).toContain("1 / 6");
+ });
+});
diff --git a/src/apps/components/AppWebhooksDisplay/EventDeliveriesList.tsx b/src/apps/components/AppWebhooksDisplay/EventDeliveriesList.tsx
new file mode 100644
index 00000000000..b03979a8e57
--- /dev/null
+++ b/src/apps/components/AppWebhooksDisplay/EventDeliveriesList.tsx
@@ -0,0 +1,39 @@
+import { AppWebhookDeliveriesQuery } from "@dashboard/graphql";
+import React from "react";
+
+import { EventDeliveryItem } from "./EventDeliveryItem";
+
+type App = NonNullable;
+type Webhook = NonNullable[0];
+type WebhookEventDelivery = NonNullable["edges"][0];
+
+export type EventDelivery = WebhookEventDelivery;
+
+interface EventDeliveriesListProps {
+ eventDeliveries: EventDelivery[];
+}
+
+export const EventDeliveriesList: React.FC = ({ eventDeliveries }) => (
+ <>
+ {eventDeliveries.map((ed, index) => {
+ const { createdAt, id } = ed.node;
+ const attempts = ed.node.attempts?.edges?.map(({ node }) => node) ?? [];
+ const attemptsCount = attempts.length;
+ const lastAttemptDate = attempts[attemptsCount - 1]?.createdAt;
+ const hasMore = index < eventDeliveries.length - 1;
+
+ return (
+
+ );
+ })}
+ >
+);
diff --git a/src/apps/components/AppWebhooksDisplay/EventDeliveriesStatus.tsx b/src/apps/components/AppWebhooksDisplay/EventDeliveriesStatus.tsx
new file mode 100644
index 00000000000..ff72bbbff49
--- /dev/null
+++ b/src/apps/components/AppWebhooksDisplay/EventDeliveriesStatus.tsx
@@ -0,0 +1,71 @@
+import { EventDeliveryStatusEnum } from "@dashboard/graphql";
+import { Chip, Text, ThemeTokensValues } from "@saleor/macaw-ui-next";
+import React from "react";
+import { useIntl } from "react-intl";
+
+const mapDeliveryStatusToTextColor = (
+ status: EventDeliveryStatusEnum,
+): keyof ThemeTokensValues["colors"]["text"] => {
+ switch (status) {
+ case EventDeliveryStatusEnum.FAILED:
+ return "critical1";
+ case EventDeliveryStatusEnum.PENDING:
+ return "accent1";
+ case EventDeliveryStatusEnum.SUCCESS:
+ return "success1";
+ }
+};
+
+const mapDeliveryStatusToBorderColor = (
+ status: EventDeliveryStatusEnum,
+): keyof ThemeTokensValues["colors"]["border"] => {
+ switch (status) {
+ case EventDeliveryStatusEnum.FAILED:
+ return "critical1";
+ case EventDeliveryStatusEnum.PENDING:
+ return "accent1";
+ case EventDeliveryStatusEnum.SUCCESS:
+ return "success1";
+ }
+};
+
+const mapDeliveryStatusToBackgroundColor = (
+ status: EventDeliveryStatusEnum,
+): keyof ThemeTokensValues["colors"]["background"] => {
+ switch (status) {
+ case EventDeliveryStatusEnum.FAILED:
+ return "critical1";
+ case EventDeliveryStatusEnum.PENDING:
+ return "default1";
+ case EventDeliveryStatusEnum.SUCCESS:
+ return "accent1";
+ }
+};
+
+const DeliveryStatusDisplay = ({ status }: { status: EventDeliveryStatusEnum }) => {
+ const { formatMessage } = useIntl();
+
+ switch (status) {
+ case EventDeliveryStatusEnum.FAILED:
+ return <>{formatMessage({ defaultMessage: "Failed", id: "vXCeIi" })}>;
+ case EventDeliveryStatusEnum.PENDING:
+ return <>{formatMessage({ defaultMessage: "Pending", id: "eKEL/g" })}>;
+ case EventDeliveryStatusEnum.SUCCESS:
+ return <>{formatMessage({ defaultMessage: "Success", id: "xrKHS6" })} >;
+ default:
+ throw new Error("Invalid EventDeliveryStatusEnum value");
+ }
+};
+
+export const EventDeliveryStatusChip = ({ status }: { status: EventDeliveryStatusEnum }) => {
+ return (
+
+
+
+
+
+ );
+};
diff --git a/src/apps/components/AppWebhooksDisplay/EventDeliveryItem.tsx b/src/apps/components/AppWebhooksDisplay/EventDeliveryItem.tsx
new file mode 100644
index 00000000000..22d0e3a46ea
--- /dev/null
+++ b/src/apps/components/AppWebhooksDisplay/EventDeliveryItem.tsx
@@ -0,0 +1,81 @@
+import { DateTime } from "@dashboard/components/Date";
+import { EventDeliveryAttemptFragment, EventDeliveryStatusEnum } from "@dashboard/graphql";
+import { Box, Text } from "@saleor/macaw-ui-next";
+import React from "react";
+import { useIntl } from "react-intl";
+
+import { AppWebhooksAttemptDetails } from "./AppWebhooksAttemptDetails";
+import { EventDeliveryStatusChip } from "./EventDeliveriesStatus";
+
+interface EventDeliveryItemProps {
+ createdAt: string;
+ attemptsCount: number;
+ status: EventDeliveryStatusEnum;
+ attempts: EventDeliveryAttemptFragment[];
+ lastAttemptDate: string;
+ hasMore: boolean;
+ dataTestId?: string;
+}
+
+const MAX_ATTEMPTS = 6;
+
+export const EventDeliveryItem: React.FC = ({
+ createdAt,
+ status,
+ attemptsCount,
+ attempts,
+ lastAttemptDate,
+ hasMore,
+ dataTestId,
+}) => {
+ const intl = useIntl();
+
+ return (
+
+
+
+
+
+
+
+
+
+ {attempts.length > 0 && (
+
+
+ {intl.formatMessage({
+ defaultMessage: "Attempts:",
+ id: "OFTsI1",
+ })}{" "}
+
+ {attemptsCount} / {MAX_ATTEMPTS}
+
+
+
+ {intl.formatMessage({
+ defaultMessage: "Last delivery attempt:",
+ id: "EY/jqC",
+ })}{" "}
+
+
+
+ )}
+
+
+ {attempts.map(attempt => (
+
+ ))}
+
+
+ );
+};
diff --git a/src/apps/components/DeactivatedText/DeactivatedText.tsx b/src/apps/components/DeactivatedText/DeactivatedText.tsx
index c1da4fd3a7b..0d2106b0669 100644
--- a/src/apps/components/DeactivatedText/DeactivatedText.tsx
+++ b/src/apps/components/DeactivatedText/DeactivatedText.tsx
@@ -1,5 +1,5 @@
import { commonStatusMessages } from "@dashboard/intl";
-import { Typography } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage } from "react-intl";
@@ -9,9 +9,9 @@ export const DeactivatedText: React.FC<{}> = () => {
const classes = useStyles({});
return (
-
+
-
+
);
};
diff --git a/src/apps/components/InstalledAppList/InstalledAppList.tsx b/src/apps/components/InstalledAppList/InstalledAppList.tsx
index 4767c5a2481..583fb70ff51 100644
--- a/src/apps/components/InstalledAppList/InstalledAppList.tsx
+++ b/src/apps/components/InstalledAppList/InstalledAppList.tsx
@@ -1,8 +1,7 @@
import { AppInstallation, InstalledApp } from "@dashboard/apps/types";
import { useHasManagedAppsPermission } from "@dashboard/hooks/useHasManagedAppsPermission";
import { ListProps } from "@dashboard/types";
-import { Skeleton } from "@material-ui/lab";
-import { Box, List, Text } from "@saleor/macaw-ui-next";
+import { Box, List, Skeleton, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
@@ -21,7 +20,7 @@ const InstalledAppList: React.FC = ({ appList, appInstall
const { hasManagedAppsPermission } = useHasManagedAppsPermission();
if (appsAreLoading({ appList, appInstallationList, hasManagedAppsPermission })) {
- return ;
+ return ;
}
if (hasEmptyAppList({ appList, appInstallationList, hasManagedAppsPermission })) {
diff --git a/src/apps/components/MarketplaceAlert/MarketplaceAlert.tsx b/src/apps/components/MarketplaceAlert/MarketplaceAlert.tsx
index a9b269f918f..19f432f4bc8 100644
--- a/src/apps/components/MarketplaceAlert/MarketplaceAlert.tsx
+++ b/src/apps/components/MarketplaceAlert/MarketplaceAlert.tsx
@@ -1,5 +1,5 @@
-import { Typography } from "@material-ui/core";
import { Alert } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -26,14 +26,14 @@ export const MarketplaceAlert: React.FC = ({ error }) =>
close={true}
title={intl.formatMessage(msgs.marketplaceError)}
>
-
+
{error.message},
}}
/>
-
+
);
};
diff --git a/src/apps/components/SectionHeader/SectionHeader.tsx b/src/apps/components/SectionHeader/SectionHeader.tsx
index df6acaa9925..9b964d2ecb3 100644
--- a/src/apps/components/SectionHeader/SectionHeader.tsx
+++ b/src/apps/components/SectionHeader/SectionHeader.tsx
@@ -1,4 +1,4 @@
-import { Typography } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React, { ReactNode } from "react";
import { useStyles } from "./styles";
@@ -11,9 +11,9 @@ export const SectionHeader: React.FC = ({ title }) => {
const classes = useStyles();
return (
-
+
{title}
-
+
);
};
SectionHeader.displayName = "SectionHeader";
diff --git a/src/apps/hooks/useActiveAppsInstallations.test.ts b/src/apps/hooks/useActiveAppsInstallations.test.ts
new file mode 100644
index 00000000000..1affd6aa48d
--- /dev/null
+++ b/src/apps/hooks/useActiveAppsInstallations.test.ts
@@ -0,0 +1,109 @@
+import { AppsInstallationsQuery } from "@dashboard/graphql";
+import useLocalStorage from "@dashboard/hooks/useLocalStorage";
+import { renderHook } from "@testing-library/react-hooks";
+
+import useActiveAppsInstallations from "./useActiveAppsInstallations";
+
+jest.mock("react-intl", () => ({
+ useIntl: jest.fn(() => ({
+ formatMessage: jest.fn(x => x.defaultMessage),
+ })),
+ defineMessages: jest.fn(x => x),
+}));
+
+jest.mock("@apollo/client", () => ({
+ gql: jest.fn(),
+ useApolloClient: jest.fn(),
+}));
+
+jest.mock("@dashboard/hooks/useLocalStorage");
+jest.mock("@dashboard/graphql", () => ({
+ useAppRetryInstallMutation: jest.fn(() => [jest.fn(), {}]),
+ useAppDeleteFailedInstallationMutation: jest.fn(() => [jest.fn(), {}]),
+}));
+
+jest.useFakeTimers();
+
+describe("useActiveAppsInstallations", () => {
+ it("install app notify should not be called when apps in progress data loading", () => {
+ // Arrange
+ const mockedActiveInstallations = [
+ {
+ id: "1",
+ name: "app1",
+ },
+ ];
+ const appInProgressLoading = true;
+ const appsInProgressData = {
+ appInstallations: [],
+ } as unknown as AppsInstallationsQuery;
+ const mockNotify = jest.fn();
+
+ (useLocalStorage as jest.Mock).mockReturnValue([mockedActiveInstallations, jest.fn()]);
+
+ renderHook(() =>
+ useActiveAppsInstallations({
+ appsInProgressData,
+ appsInProgressRefetch: jest.fn(),
+ appInProgressLoading,
+ appsRefetch: jest.fn(),
+ installedAppNotify: mockNotify,
+ removeInProgressAppNotify: jest.fn(),
+ onInstallSuccess: jest.fn(),
+ onInstallError: jest.fn(),
+ onRemoveInProgressAppSuccess: jest.fn(),
+ }),
+ );
+
+ expect(mockNotify).not.toHaveBeenCalled();
+ });
+
+ it("should call install app notify when apps in progress data loaded and no item found", () => {
+ // Arrange
+ const mockedActiveInstallations = [
+ {
+ id: "1",
+ name: "app1",
+ },
+ ];
+ const appsInProgressData = {
+ appsInstallations: [],
+ } as unknown as AppsInstallationsQuery;
+ const mockNotify = jest.fn();
+
+ jest.useFakeTimers();
+
+ (useLocalStorage as jest.Mock).mockReturnValue([mockedActiveInstallations, jest.fn()]);
+
+ const { rerender } = renderHook(
+ ({ appsInProgressData, appInProgressLoading }) =>
+ useActiveAppsInstallations({
+ appsInProgressData,
+ appsInProgressRefetch: jest.fn(),
+ appInProgressLoading,
+ appsRefetch: jest.fn(),
+ installedAppNotify: mockNotify,
+ removeInProgressAppNotify: jest.fn(),
+ onInstallSuccess: jest.fn(),
+ onInstallError: jest.fn(),
+ onRemoveInProgressAppSuccess: jest.fn(),
+ }),
+ {
+ initialProps: {
+ appsInProgressData: undefined,
+ appInProgressLoading: true,
+ } as {
+ appsInProgressData: AppsInstallationsQuery | undefined;
+ appInProgressLoading: boolean;
+ },
+ },
+ );
+
+ rerender({
+ appsInProgressData,
+ appInProgressLoading: false,
+ });
+
+ expect(mockNotify).toHaveBeenCalled();
+ });
+});
diff --git a/src/apps/hooks/useActiveAppsInstallations.ts b/src/apps/hooks/useActiveAppsInstallations.ts
index 07e488b0f1f..5ce6374875b 100644
--- a/src/apps/hooks/useActiveAppsInstallations.ts
+++ b/src/apps/hooks/useActiveAppsInstallations.ts
@@ -12,6 +12,7 @@ import { useEffect, useRef } from "react";
interface UseActiveAppsInstallations {
appsInProgressData: AppsInstallationsQuery | undefined;
+ appInProgressLoading: boolean;
appsInProgressRefetch: () => void;
appsRefetch: () => void;
removeInProgressAppNotify: () => void;
@@ -24,6 +25,7 @@ interface UseActiveAppsInstallations {
function useActiveAppsInstallations({
appsInProgressData,
appsInProgressRefetch,
+ appInProgressLoading,
appsRefetch,
installedAppNotify,
removeInProgressAppNotify,
@@ -130,7 +132,7 @@ function useActiveAppsInstallations({
useEffect(() => {
const appsInProgress = appsInProgressData?.appsInstallations || [];
- if (activeInstallations.length && !!appsInProgressData) {
+ if (activeInstallations.length && !appInProgressLoading) {
let newAppInstalled = false;
activeInstallations.forEach(installation => {
@@ -162,8 +164,14 @@ function useActiveAppsInstallations({
return {
handleAppInstallRetry,
handleRemoveInProgress,
- retryInstallAppOpts,
- deleteInProgressAppOpts,
+ retryInstallAppOpts: {
+ status: retryInstallAppOpts.status,
+ loading: retryInstallAppOpts.loading,
+ },
+ deleteInProgressAppOpts: {
+ status: deleteInProgressAppOpts.status,
+ loading: deleteInProgressAppOpts.loading,
+ },
};
}
export default useActiveAppsInstallations;
diff --git a/src/apps/queries.ts b/src/apps/queries.ts
index 4bbc4ebc18a..a3311fbfdac 100644
--- a/src/apps/queries.ts
+++ b/src/apps/queries.ts
@@ -104,14 +104,14 @@ export const appWebhookDeliveries = gql`
eventDeliveries(first: 10) {
edges {
node {
+ id
createdAt
status
eventType
attempts(first: 10) {
edges {
node {
- createdAt
- status
+ ...EventDeliveryAttempt
}
}
}
diff --git a/src/apps/views/AppListView/AppListView.tsx b/src/apps/views/AppListView/AppListView.tsx
index 8a6137a27d4..1f4dac9bf08 100644
--- a/src/apps/views/AppListView/AppListView.tsx
+++ b/src/apps/views/AppListView/AppListView.tsx
@@ -69,7 +69,11 @@ export const AppListView: React.FC = ({ params }) => {
installedAppsData?.apps?.pageInfo,
paginationState,
);
- const { data: appsInProgressData, refetch: appsInProgressRefetch } = useAppsInstallationsQuery({
+ const {
+ data: appsInProgressData,
+ refetch: appsInProgressRefetch,
+ loading: appInProgressLoading,
+ } = useAppsInstallationsQuery({
displayLoader: false,
skip: !hasManagedAppsPermission,
});
@@ -98,6 +102,7 @@ export const AppListView: React.FC = ({ params }) => {
const { handleAppInstallRetry, handleRemoveInProgress, deleteInProgressAppOpts } =
useActiveAppsInstallations({
appsInProgressData,
+ appInProgressLoading,
appsInProgressRefetch,
appsRefetch,
installedAppNotify,
diff --git a/src/attributes/components/AttributeBulkDeleteDialog/AttributeBulkDeleteDialog.tsx b/src/attributes/components/AttributeBulkDeleteDialog/AttributeBulkDeleteDialog.tsx
index 1d81dc1c3e5..fcf7079ae45 100644
--- a/src/attributes/components/AttributeBulkDeleteDialog/AttributeBulkDeleteDialog.tsx
+++ b/src/attributes/components/AttributeBulkDeleteDialog/AttributeBulkDeleteDialog.tsx
@@ -1,6 +1,5 @@
import ActionDialog from "@dashboard/components/ActionDialog";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
-import { DialogContentText } from "@material-ui/core";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -35,18 +34,16 @@ const AttributeBulkDeleteDialog: React.FC = ({
variant="delete"
data-test-id="attribute-bulk-delete-dialog"
>
-
- {quantity},
- }}
- />
-
+ {quantity},
+ }}
+ />
);
};
diff --git a/src/attributes/components/AttributeDeleteDialog/AttributeDeleteDialog.tsx b/src/attributes/components/AttributeDeleteDialog/AttributeDeleteDialog.tsx
index f56ac580fdb..9a6fa7792fc 100644
--- a/src/attributes/components/AttributeDeleteDialog/AttributeDeleteDialog.tsx
+++ b/src/attributes/components/AttributeDeleteDialog/AttributeDeleteDialog.tsx
@@ -1,6 +1,5 @@
import ActionDialog from "@dashboard/components/ActionDialog";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
-import { DialogContentText } from "@material-ui/core";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -34,17 +33,15 @@ const AttributeDeleteDialog: React.FC = ({
description: "dialog title",
})}
>
-
- {name},
- }}
- />
-
+ {name},
+ }}
+ />
);
};
diff --git a/src/attributes/components/AttributeDetails/AttributeDetails.tsx b/src/attributes/components/AttributeDetails/AttributeDetails.tsx
index b75702d82d8..f5dce4eaf5d 100644
--- a/src/attributes/components/AttributeDetails/AttributeDetails.tsx
+++ b/src/attributes/components/AttributeDetails/AttributeDetails.tsx
@@ -1,19 +1,19 @@
import { NumericUnits } from "@dashboard/attributes/components/AttributeDetails/NumericUnits";
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import ControlledCheckbox from "@dashboard/components/ControlledCheckbox";
import FormSpacer from "@dashboard/components/FormSpacer";
-import SingleSelectField from "@dashboard/components/SingleSelectField";
+import { Select } from "@dashboard/components/Select";
import {
AttributeEntityTypeEnum,
AttributeErrorFragment,
AttributeInputTypeEnum,
} from "@dashboard/graphql";
-import { UseFormResult } from "@dashboard/hooks/useForm";
+import { ChangeEvent, UseFormResult } from "@dashboard/hooks/useForm";
import { commonMessages } from "@dashboard/intl";
import { getFormErrors } from "@dashboard/utils/errors";
import getAttributeErrorMessage from "@dashboard/utils/errors/attribute";
-import { Card, CardContent, TextField } from "@material-ui/core";
-import { makeStyles } from "@saleor/macaw-ui";
+import { TextField } from "@material-ui/core";
+import { Box } from "@saleor/macaw-ui-next";
import React from "react";
import { defineMessages, useIntl } from "react-intl";
import slugify from "slugify";
@@ -39,19 +39,6 @@ const entityTypeMessages = defineMessages({
description: "product variant attribute entity type",
},
});
-const useStyles = makeStyles(
- theme => ({
- inputTypeSection: {
- columnGap: theme.spacing(2),
- display: "flex",
- [theme.breakpoints.down("md")]: {
- flexFlow: "wrap",
- rowGap: theme.spacing(3),
- },
- },
- }),
- { name: "AttributeDetails" },
-);
export interface AttributeDetailsProps
extends Pick<
@@ -61,13 +48,12 @@ export interface AttributeDetailsProps
canChangeType: boolean;
disabled: boolean;
apiErrors: AttributeErrorFragment[];
- onChange: (event: React.ChangeEvent) => void;
+ onChange: (event: ChangeEvent) => void;
}
const AttributeDetails: React.FC = props => {
const { canChangeType, errors, clearErrors, setError, data, disabled, apiErrors, onChange, set } =
props;
- const classes = useStyles(props);
const intl = useIntl();
const inputTypeChoices = [
{
@@ -135,9 +121,14 @@ const AttributeDetails: React.FC = props => {
);
return (
-
-
-
+
+
+
+ {intl.formatMessage(commonMessages.generalInformations)}
+
+
+
+
= props => {
onChange={onChange}
/>
-
-
- {data.inputType === AttributeInputTypeEnum.REFERENCE && (
-
+
+
+
+ {data.inputType === AttributeInputTypeEnum.REFERENCE && (
+
+
+
)}
-
+
= props => {
set={set}
/>
)}
-
-
+
+
);
};
diff --git a/src/attributes/components/AttributeDetails/NumericUnits.tsx b/src/attributes/components/AttributeDetails/NumericUnits.tsx
index 35029dce2a0..514d4b24db7 100644
--- a/src/attributes/components/AttributeDetails/NumericUnits.tsx
+++ b/src/attributes/components/AttributeDetails/NumericUnits.tsx
@@ -1,33 +1,19 @@
import { AttributePageFormData } from "@dashboard/attributes/components/AttributePage";
import ControlledCheckbox from "@dashboard/components/ControlledCheckbox";
-import SingleSelectField from "@dashboard/components/SingleSelectField";
+import { Select } from "@dashboard/components/Select";
import { MeasurementUnitsEnum } from "@dashboard/graphql";
import { UseFormResult } from "@dashboard/hooks/useForm";
import { commonMessages } from "@dashboard/intl";
import { makeStyles } from "@saleor/macaw-ui";
+import { Box, Option } from "@saleor/macaw-ui-next";
import React, { useEffect, useMemo, useState } from "react";
import { useIntl } from "react-intl";
import * as M from "./messages";
-import {
- getUnitChoices,
- unitMapping,
- UnitSystem,
- unitSystemChoices,
- UnitType,
- unitTypeChoices,
-} from "./utils";
+import { getUnitChoices, UnitSystem, unitSystemChoices, UnitType, unitTypeChoices } from "./utils";
const useStyles = makeStyles(
theme => ({
- unitsRow: {
- columnGap: theme.spacing(2),
- display: "flex",
- [theme.breakpoints.down("sm")]: {
- flexFlow: "wrap",
- rowGap: theme.spacing(3),
- },
- },
hr: {
border: "none",
borderTop: `1px solid ${theme.palette.divider}`,
@@ -73,11 +59,11 @@ export const NumericUnits: React.FC = ({
};
const [typeChoices, systemChoices, unitChoices] = useMemo(
() => [
- unitTypeChoices.map(choice => ({
+ unitTypeChoices.map(choice => ({
...choice,
label: formatMessage(choice.label),
})),
- unitSystemChoices.map(choice => ({
+ unitSystemChoices.map (choice => ({
...choice,
label: formatMessage(choice.label),
})),
@@ -138,52 +124,64 @@ export const NumericUnits: React.FC = ({
disabled={disabled}
/>
{data.unit !== null && (
-
- ) =>
- setUnitData(data => ({
- ...data,
- system: target.value as UnitSystem,
- }))
- }
- value={system}
- disabled={disabled}
- />
- ) =>
- setUnitData(data => ({
- ...data,
- type: target.value as UnitType,
- }))
- }
- disabled={!system || disabled}
- value={type}
- />
- ) =>
- setUnitData(data => ({
- ...data,
- unit: target.value as MeasurementUnitsEnum,
- }))
- }
- disabled={!type || disabled}
- value={
- type && system && unit && unitMapping[system][type].includes(unit) ? unit : undefined
- }
- />
-
+
+
+ {
+ setUnitData(data => ({
+ ...data,
+ system: target.value as UnitSystem,
+ }));
+ }}
+ value={system ?? null}
+ options={systemChoices}
+ />
+
+
+
+ {
+ setUnitData(data => ({
+ ...data,
+ type: target.value as UnitType,
+ }));
+ }}
+ value={type ?? null}
+ options={typeChoices}
+ />
+
+
+
+
+ setUnitData(data => ({
+ ...data,
+ unit: target.value as MeasurementUnitsEnum,
+ }))
+ }
+ value={unit as string}
+ options={(type && system ? unitChoices?.[system]?.[type] ?? [] : []) as Option[]}
+ />
+
+
)}
);
diff --git a/src/attributes/components/AttributeDetails/messages.tsx b/src/attributes/components/AttributeDetails/messages.tsx
index 9db9debca88..480b0791132 100644
--- a/src/attributes/components/AttributeDetails/messages.tsx
+++ b/src/attributes/components/AttributeDetails/messages.tsx
@@ -56,6 +56,11 @@ export const messages = defineMessages({
});
export const inputTypeMessages = defineMessages({
+ plainTextTruncated: {
+ id: "A02NDR",
+ defaultMessage: "Attribute value too long and truncated at {length} characters.",
+ description: "plain text attribute value was truncated",
+ },
dropdown: {
id: "bZksto",
defaultMessage: "Dropdown",
@@ -107,8 +112,13 @@ export const inputTypeMessages = defineMessages({
description: "date time attribute type",
},
swatch: {
- id: "gx4wCT",
+ id: "g8lXTL",
defaultMessage: "Swatch",
+ description: "swatch attribute",
+ },
+ swatchType: {
+ id: "ztvvcm",
+ defaultMessage: "Swatch type",
description: "swatch attribute type",
},
});
diff --git a/src/attributes/components/AttributeDetails/utils.ts b/src/attributes/components/AttributeDetails/utils.ts
index 75a25a0a8ee..bbb60945b51 100644
--- a/src/attributes/components/AttributeDetails/utils.ts
+++ b/src/attributes/components/AttributeDetails/utils.ts
@@ -1,5 +1,5 @@
-import { Choice } from "@dashboard/components/SingleSelectField";
import { MeasurementUnitsEnum } from "@dashboard/graphql";
+import { Option } from "@saleor/macaw-ui-next";
import React from "react";
import { IntlShape, MessageDescriptor } from "react-intl";
@@ -56,7 +56,7 @@ export const getMeasurementUnitMessage = (
: formatMessage(message as MessageDescriptor);
};
-export const unitSystemChoices: Array> = [
+export const unitSystemChoices = [
{
label: M.unitSystemMessages.metric,
value: "metric",
@@ -67,7 +67,7 @@ export const unitSystemChoices: Array> = [
},
];
-export const unitTypeChoices: Array> = [
+export const unitTypeChoices = [
{
label: M.unitTypeMessages.volume,
value: "volume",
@@ -149,7 +149,7 @@ export const getUnitChoices = (
formatMessage: IntlShape["formatMessage"],
): {
[key in UnitSystem]: {
- [key in UnitType]: Array>;
+ [key in UnitType]: Option[];
};
} =>
Object.entries(unitMapping).reduce(
@@ -160,6 +160,6 @@ export const getUnitChoices = (
{},
) as {
[key in UnitSystem]: {
- [key in UnitType]: Array>;
+ [key in UnitType]: Option[];
};
};
diff --git a/src/attributes/components/AttributeListDatagrid/AttributeListDatagrid.tsx b/src/attributes/components/AttributeListDatagrid/AttributeListDatagrid.tsx
index 826f16d8e2c..8b3e2486924 100644
--- a/src/attributes/components/AttributeListDatagrid/AttributeListDatagrid.tsx
+++ b/src/attributes/components/AttributeListDatagrid/AttributeListDatagrid.tsx
@@ -8,12 +8,14 @@ import {
} from "@dashboard/components/Datagrid/hooks/useDatagridChange";
import { TablePaginationWithContext } from "@dashboard/components/TablePagination";
import { AttributeFragment } from "@dashboard/graphql";
+import { getPrevLocationState } from "@dashboard/hooks/useBackLinkWithState";
import useNavigator from "@dashboard/hooks/useNavigator";
import { ListProps, SortPage } from "@dashboard/types";
import { Item } from "@glideapps/glide-data-grid";
import { Box } from "@saleor/macaw-ui-next";
import React, { useCallback, useMemo } from "react";
import { useIntl } from "react-intl";
+import { useLocation } from "react-router";
import { attributesListStaticColumnsAdapter, createGetCellContent } from "./datagrid";
import { messages } from "./messages";
@@ -33,6 +35,7 @@ export const AttributeListDatagrid = ({
onUpdateListSettings,
}: AttributeListDatagridProps) => {
const datagridState = useDatagridChangeState();
+ const location = useLocation();
const navigate = useNavigator();
const intl = useIntl();
const attributesListStaticColumns = useMemo(
@@ -66,7 +69,9 @@ export const AttributeListDatagrid = ({
const rowData: AttributeFragment = attributes[row];
if (rowData) {
- navigate(attributeUrl(rowData.id));
+ navigate(attributeUrl(rowData.id), {
+ state: getPrevLocationState(location),
+ });
}
},
[attributes],
@@ -114,6 +119,7 @@ export const AttributeListDatagrid = ({
onToggle={handlers.onToggle}
/>
)}
+ navigatorOpts={{ state: getPrevLocationState(location) }}
/>
diff --git a/src/attributes/components/AttributeListDatagrid/datagrid.ts b/src/attributes/components/AttributeListDatagrid/datagrid.ts
index 21c467c4c84..d0d66ca08dc 100644
--- a/src/attributes/components/AttributeListDatagrid/datagrid.ts
+++ b/src/attributes/components/AttributeListDatagrid/datagrid.ts
@@ -31,11 +31,6 @@ export const attributesListStaticColumnsAdapter = (
title: intl.formatMessage(columnsMessages.visible),
width: 200,
},
- {
- id: "searchable",
- title: intl.formatMessage(columnsMessages.searchable),
- width: 200,
- },
{
id: "use-in-faceted-search",
title: intl.formatMessage(columnsMessages.useInFacetedSearch),
@@ -71,8 +66,6 @@ export const createGetCellContent =
return readonlyTextCell(rowData?.name ?? PLACEHOLDER);
case "visible":
return readonlyTextCell(translateBoolean(rowData?.visibleInStorefront, intl));
- case "searchable":
- return readonlyTextCell(translateBoolean(rowData?.filterableInDashboard, intl));
case "use-in-faceted-search":
return readonlyTextCell(translateBoolean(rowData?.filterableInStorefront, intl));
default:
diff --git a/src/attributes/components/AttributeListDatagrid/messages.ts b/src/attributes/components/AttributeListDatagrid/messages.ts
index a57e274a6f0..f8366f11815 100644
--- a/src/attributes/components/AttributeListDatagrid/messages.ts
+++ b/src/attributes/components/AttributeListDatagrid/messages.ts
@@ -11,18 +11,13 @@ export const columnsMessages = defineMessages({
description: "attribute's label'",
},
visible: {
- id: "k6WDZl",
- defaultMessage: "Visible",
- description: "attribute is visible",
- },
- searchable: {
- id: "yKuba7",
- defaultMessage: "Searchable",
- description: "attribute can be searched in dashboard",
+ id: "W75xMz",
+ defaultMessage: "Visible in storefront",
+ description: "attribute is visible in storefront",
},
useInFacetedSearch: {
- defaultMessage: "Use as filter",
- id: "Y3pCRX",
+ defaultMessage: "Filterable in storefront",
+ id: "9IrVVZ",
description: "attribute can be searched in storefront",
},
});
diff --git a/src/attributes/components/AttributeListPage/AttributeListPage.tsx b/src/attributes/components/AttributeListPage/AttributeListPage.tsx
index 97b835d7169..4cf416e9a47 100644
--- a/src/attributes/components/AttributeListPage/AttributeListPage.tsx
+++ b/src/attributes/components/AttributeListPage/AttributeListPage.tsx
@@ -2,12 +2,13 @@ import { attributeAddUrl, AttributeListUrlSortField } from "@dashboard/attribute
import { ListFilters } from "@dashboard/components/AppLayout/ListFilters";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import { BulkDeleteButton } from "@dashboard/components/BulkDeleteButton";
+import { DashboardCard } from "@dashboard/components/Card";
import { FilterPresetsSelect } from "@dashboard/components/FilterPresetsSelect";
import { configurationMenuUrl } from "@dashboard/configuration";
+import { useFlag } from "@dashboard/featureFlags";
import { AttributeFragment } from "@dashboard/graphql";
import useNavigator from "@dashboard/hooks/useNavigator";
import { sectionNames } from "@dashboard/intl";
-import { Card } from "@material-ui/core";
import { Box, Button, ChevronRightIcon } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -48,6 +49,7 @@ const AttributeListPage: React.FC = ({
const navigate = useNavigator();
const structure = createFilterStructure(intl, filterOpts);
const [isFilterPresetOpen, setFilterPresetOpen] = useState(false);
+ const { enabled: isAttributesFilteringEnabled } = useFlag("new_filters");
return (
<>
@@ -96,30 +98,51 @@ const AttributeListPage: React.FC = ({
-
-
- currencySymbol={currencySymbol}
- initialSearch={initialSearch}
- onFilterChange={onFilterChange}
- onSearchChange={onSearchChange}
- filterStructure={structure}
- searchPlaceholder={intl.formatMessage({
- id: "9ScmSs",
- defaultMessage: "Search attributes...",
- })}
- actions={
-
- {selectedAttributesIds.length > 0 && (
-
-
-
- )}
-
- }
- />
+
+ {isAttributesFilteringEnabled ? (
+
+ type="expression-filter"
+ initialSearch={initialSearch}
+ onSearchChange={onSearchChange}
+ searchPlaceholder={intl.formatMessage({
+ id: "9ScmSs",
+ defaultMessage: "Search attributes...",
+ })}
+ actions={
+
+ {selectedAttributesIds.length > 0 && (
+
+
+
+ )}
+
+ }
+ />
+ ) : (
+
+ currencySymbol={currencySymbol}
+ initialSearch={initialSearch}
+ onFilterChange={onFilterChange}
+ onSearchChange={onSearchChange}
+ filterStructure={structure}
+ searchPlaceholder={intl.formatMessage({
+ id: "9ScmSs",
+ defaultMessage: "Search attributes...",
+ })}
+ actions={
+
+ {selectedAttributesIds.length > 0 && (
+
+
+
+ )}
+
+ }
+ />
+ )}
-
+
>
);
};
diff --git a/src/attributes/components/AttributeOrganization/AttributeOrganization.tsx b/src/attributes/components/AttributeOrganization/AttributeOrganization.tsx
index 9a542555ecf..2990334a8cf 100644
--- a/src/attributes/components/AttributeOrganization/AttributeOrganization.tsx
+++ b/src/attributes/components/AttributeOrganization/AttributeOrganization.tsx
@@ -1,8 +1,8 @@
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import RadioGroupField from "@dashboard/components/RadioGroupField";
import { AttributeTypeEnum } from "@dashboard/graphql";
-import { Card, CardContent, Typography } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { defineMessages, FormattedMessage, useIntl } from "react-intl";
@@ -48,15 +48,18 @@ const AttributeOrganization: React.FC = props => {
const intl = useIntl();
return (
-
-
-
+
+
+
+ {intl.formatMessage({
+ id: "nwvQPg",
+ defaultMessage: "Organization",
+ description: "section header",
+ })}
+
+
+
+
{canChangeType ? (
= props => {
label={
<>
-
+
-
+
>
}
name={"type" as keyof FormData}
@@ -87,18 +90,18 @@ const AttributeOrganization: React.FC = props => {
/>
) : (
<>
-
+
-
-
+
+
{data.type === AttributeTypeEnum.PRODUCT_TYPE
? intl.formatMessage(messages.productAttribute)
: intl.formatMessage(messages.contentAttribute)}
-
+
>
)}
-
-
+
+
);
};
diff --git a/src/attributes/components/AttributePage/AttributePage.tsx b/src/attributes/components/AttributePage/AttributePage.tsx
index e141fa7b149..e9fc36838ad 100644
--- a/src/attributes/components/AttributePage/AttributePage.tsx
+++ b/src/attributes/components/AttributePage/AttributePage.tsx
@@ -1,4 +1,4 @@
-import { attributeListUrl } from "@dashboard/attributes/urls";
+import { attributeListPath } from "@dashboard/attributes/urls";
import { ATTRIBUTE_TYPES_WITH_DEDICATED_VALUES } from "@dashboard/attributes/utils/data";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import CardSpacer from "@dashboard/components/CardSpacer";
@@ -18,6 +18,7 @@ import {
AttributeTypeEnum,
MeasurementUnitsEnum,
} from "@dashboard/graphql";
+import { useBackLinkWithState } from "@dashboard/hooks/useBackLinkWithState";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import useNavigator from "@dashboard/hooks/useNavigator";
import { ListSettings, ReorderAction } from "@dashboard/types";
@@ -135,6 +136,10 @@ const AttributePage: React.FC = ({
});
};
+ const attributePageBackLink = useBackLinkWithState({
+ path: attributeListPath,
+ });
+
return (
+
+
);
};
diff --git a/src/attributes/components/AttributeValues/AttributeValues.tsx b/src/attributes/components/AttributeValues/AttributeValues.tsx
index fa6df2f79f3..1cf890ea2f2 100644
--- a/src/attributes/components/AttributeValues/AttributeValues.tsx
+++ b/src/attributes/components/AttributeValues/AttributeValues.tsx
@@ -1,7 +1,6 @@
import { Button } from "@dashboard/components/Button";
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
-import Skeleton from "@dashboard/components/Skeleton";
import { SortableTableBody, SortableTableRow } from "@dashboard/components/SortableTable";
import TablePagination from "@dashboard/components/TablePagination";
import TableRowLink from "@dashboard/components/TableRowLink";
@@ -12,8 +11,9 @@ import {
} from "@dashboard/graphql";
import { renderCollection, stopPropagation } from "@dashboard/misc";
import { ListProps, PaginateListProps, RelayToFlat, ReorderAction } from "@dashboard/types";
-import { Card, TableCell, TableFooter, TableHead } from "@material-ui/core";
-import { DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui";
+import { TableCell, TableFooter, TableHead } from "@material-ui/core";
+import { IconButton, makeStyles } from "@saleor/macaw-ui";
+import { Box, Skeleton, TrashBinIcon } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -91,14 +91,16 @@ const AttributeValues: React.FC = ({
const numberOfColumns = isSwatch ? 5 : 4;
return (
-
-
+
+
+ {intl.formatMessage({
+ id: "J3uE0t",
+ defaultMessage: "Attribute Values",
+ description: "section header",
+ })}
+
+
= ({
description="assign attribute value button"
/>
- }
- />
+
+
+
@@ -170,11 +173,23 @@ const AttributeValues: React.FC = ({
>
{isSwatch && (
-
+ {value?.file ? (
+
+ ) : (
+
+ )}
)}
@@ -188,7 +203,7 @@ const AttributeValues: React.FC = ({
disabled={disabled}
onClick={stopPropagation(() => onValueDelete(value?.id ?? ""))}
>
-
+
@@ -207,7 +222,7 @@ const AttributeValues: React.FC = ({
)}
-
+
);
};
diff --git a/src/attributes/index.tsx b/src/attributes/index.tsx
index f636e2e788c..165e0396891 100644
--- a/src/attributes/index.tsx
+++ b/src/attributes/index.tsx
@@ -1,9 +1,11 @@
+import { ConditionalAttributesFilterProvider } from "@dashboard/components/ConditionalFilter";
+import { Route } from "@dashboard/components/Router";
import { sectionNames } from "@dashboard/intl";
import { asSortParams } from "@dashboard/utils/sort";
import { parse as parseQs } from "qs";
import React from "react";
import { useIntl } from "react-intl";
-import { Route, RouteComponentProps, Switch } from "react-router-dom";
+import { RouteComponentProps, Switch } from "react-router-dom";
import { WindowTitle } from "../components/WindowTitle";
import {
@@ -23,7 +25,11 @@ const AttributeList: React.FC> = ({ location }) => {
const qs = parseQs(location.search.substr(1)) as any;
const params: AttributeListUrlQueryParams = asSortParams(qs, AttributeListUrlSortField);
- return ;
+ return (
+
+
+
+ );
};
const AttributeCreate: React.FC> = ({ location }) => {
const qs = parseQs(location.search.substr(1));
diff --git a/src/attributes/urls.ts b/src/attributes/urls.ts
index d7ff0d978ef..85ee0d9aaf2 100644
--- a/src/attributes/urls.ts
+++ b/src/attributes/urls.ts
@@ -27,7 +27,6 @@ export enum AttributeListUrlSortField {
name = "name",
slug = "slug",
visible = "visible",
- searchable = "searchable",
useInFacetedSearch = "use-in-faceted-search",
}
export type AttributeListUrlSort = Sort;
diff --git a/src/attributes/utils/handlers.test.ts b/src/attributes/utils/handlers.test.ts
index 26791506ebc..d968270d779 100644
--- a/src/attributes/utils/handlers.test.ts
+++ b/src/attributes/utils/handlers.test.ts
@@ -1,9 +1,15 @@
import {
+ createAttributeChangeHandler,
createAttributeMultiChangeHandler,
+ handleDeleteMultipleAttributeValues,
prepareAttributesInput,
} from "@dashboard/attributes/utils/handlers";
import { AttributeInput, AttributeInputData } from "@dashboard/components/Attributes";
-import { AttributeInputTypeEnum, AttributeValueDetailsFragment } from "@dashboard/graphql";
+import {
+ AttributeInputTypeEnum,
+ AttributeValueDetailsFragment,
+ ProductFragment,
+} from "@dashboard/graphql";
import { FormsetData } from "@dashboard/hooks/useFormset";
const multipleValueAttributes: FormsetData = [
@@ -122,13 +128,18 @@ interface CreateAttribute {
initialValue?: AttributeValueDetailsFragment[];
availableValues?: AttributeValueDetailsFragment[];
value?: string;
+ isRequired?: boolean;
}
-const createAttribute = ({ inputType, value }: CreateAttribute): AttributeInput => ({
+const createAttribute = ({
+ inputType,
+ value,
+ isRequired = false,
+}: CreateAttribute): AttributeInput => ({
data: {
entityType: undefined,
inputType,
- isRequired: false,
+ isRequired,
// those values don't matter
selectedValues: [],
values: [],
@@ -138,35 +149,46 @@ const createAttribute = ({ inputType, value }: CreateAttribute): AttributeInput
label: "MyAttribute",
value: value !== null && value !== undefined ? [value] : [],
});
-const createSelectAttribute = (value: string) =>
+const createSelectAttribute = (value: string, isRequired?: boolean) =>
createAttribute({
inputType: AttributeInputTypeEnum.DROPDOWN,
value,
+ isRequired,
});
-const createReferenceAttribute = (value: string) =>
+const createReferenceAttribute = (value: string, isRequired?: boolean) =>
createAttribute({
inputType: AttributeInputTypeEnum.REFERENCE,
value,
+ isRequired,
});
-const createBooleanAttribute = (value: string) =>
- createAttribute({
+const createBooleanAttribute = (value: string, isRequired = false) => ({
+ data: {
+ entityType: undefined,
inputType: AttributeInputTypeEnum.BOOLEAN,
- value,
- });
-const createPlainTextAttribute = (value: string) =>
- createAttribute({ inputType: AttributeInputTypeEnum.PLAIN_TEXT, value });
-const createRichTextAttribute = (value: string) =>
- createAttribute({ inputType: AttributeInputTypeEnum.RICH_TEXT, value });
-const createDateAttribute = (value: string) =>
- createAttribute({ inputType: AttributeInputTypeEnum.DATE, value });
-const createDateTimeAttribute = (value: string) =>
- createAttribute({ inputType: AttributeInputTypeEnum.DATE_TIME, value });
-const createSwatchAttribute = (value: string) =>
- createAttribute({ inputType: AttributeInputTypeEnum.SWATCH, value });
-const createNumericAttribute = (value: string) =>
- createAttribute({ inputType: AttributeInputTypeEnum.NUMERIC, value });
-const createFileAttribute = (value: string) =>
- createAttribute({ inputType: AttributeInputTypeEnum.FILE, value });
+ isRequired,
+ // those values don't matter
+ selectedValues: [],
+ values: [],
+ unit: null,
+ },
+ id: ATTR_ID,
+ label: "MyAttribute",
+ value: [value],
+});
+const createPlainTextAttribute = (value: string, isRequired?: boolean) =>
+ createAttribute({ inputType: AttributeInputTypeEnum.PLAIN_TEXT, value, isRequired });
+const createRichTextAttribute = (value: string, isRequired?: boolean) =>
+ createAttribute({ inputType: AttributeInputTypeEnum.RICH_TEXT, value, isRequired });
+const createDateAttribute = (value: string, isRequired?: boolean) =>
+ createAttribute({ inputType: AttributeInputTypeEnum.DATE, value, isRequired });
+const createDateTimeAttribute = (value: string, isRequired?: boolean) =>
+ createAttribute({ inputType: AttributeInputTypeEnum.DATE_TIME, value, isRequired });
+const createSwatchAttribute = (value: string, isRequired?: boolean) =>
+ createAttribute({ inputType: AttributeInputTypeEnum.SWATCH, value, isRequired });
+const createNumericAttribute = (value: string, isRequired?: boolean) =>
+ createAttribute({ inputType: AttributeInputTypeEnum.NUMERIC, value, isRequired });
+const createFileAttribute = (value: string, isRequired?: boolean) =>
+ createAttribute({ inputType: AttributeInputTypeEnum.FILE, value, isRequired });
describe("Multiple select change handler", () => {
it("is able to select value", () => {
@@ -207,6 +229,7 @@ describe("Multiple select change handler", () => {
expect(trigger).toHaveBeenCalledTimes(1);
});
});
+
describe("Sending only changed attributes", () => {
// null in expected = attribute not present in output
describe("works with reference attributes", () => {
@@ -229,6 +252,28 @@ describe("Sending only changed attributes", () => {
expect(result).toEqual(expectedResult);
});
});
+
+ describe("works with required reference attributes", () => {
+ test.each`
+ newAttr | oldAttr | expected
+ ${null} | ${null} | ${[]}
+ ${"my value"} | ${"my value"} | ${["my value"]}
+ ${"my value"} | ${null} | ${["my value"]}
+ ${null} | ${"my value"} | ${[]}
+ `("$oldAttr -> $newAttr returns $expected", ({ newAttr, oldAttr, expected }) => {
+ const attribute = createReferenceAttribute(newAttr, true);
+ const prevAttribute = createReferenceAttribute(oldAttr, true);
+ const result = prepareAttributesInput({
+ attributes: [attribute],
+ prevAttributes: [prevAttribute],
+ updatedFileAttributes: [],
+ });
+ const expectedResult = expected !== null ? [{ id: ATTR_ID, references: expected }] : [];
+
+ expect(result).toEqual(expectedResult);
+ });
+ });
+
describe("works with select attributes", () => {
test.each`
newAttr | oldAttr | expected
@@ -249,29 +294,76 @@ describe("Sending only changed attributes", () => {
expect(result).toEqual(expectedResult);
});
});
+
+ describe("works with required select attributes", () => {
+ test.each`
+ newAttr | oldAttr | expected
+ ${null} | ${null} | ${[]}
+ ${"my value"} | ${"my value"} | ${["my value"]}
+ ${"my value"} | ${null} | ${["my value"]}
+ ${null} | ${"my value"} | ${[]}
+ `("$oldAttr -> $newAttr returns $expected", ({ newAttr, oldAttr, expected }) => {
+ const attribute = createSelectAttribute(newAttr, true);
+ const prevAttribute = createSelectAttribute(oldAttr, true);
+ const result = prepareAttributesInput({
+ attributes: [attribute],
+ prevAttributes: [prevAttribute],
+ updatedFileAttributes: [],
+ });
+ const expectedResult = expected !== null ? [{ id: ATTR_ID, values: expected }] : [];
+
+ expect(result).toEqual(expectedResult);
+ });
+ });
+
describe("works with boolean attributes", () => {
test.each`
- newAttr | oldAttr | expected
- ${null} | ${null} | ${null}
- ${"true"} | ${true} | ${null}
- ${"true"} | ${false} | ${true}
- ${"true"} | ${null} | ${true}
- ${"false"} | ${false} | ${null}
- ${"false"} | ${true} | ${false}
- ${"false"} | ${null} | ${false}
+ newAttr | oldAttr | expected
+ ${null} | ${null} | ${"empty"}
+ ${true} | ${true} | ${"empty"}
+ ${true} | ${false} | ${true}
+ ${true} | ${null} | ${true}
+ ${false} | ${false} | ${"empty"}
+ ${false} | ${true} | ${false}
+ ${false} | ${null} | ${false}
`("$oldAttr -> $newAttr returns $expected", ({ newAttr, oldAttr, expected }) => {
const attribute = createBooleanAttribute(newAttr);
const prevAttribute = createBooleanAttribute(oldAttr);
const result = prepareAttributesInput({
attributes: [attribute],
- prevAttributes: [prevAttribute],
+ prevAttributes: typeof prevAttribute === "undefined" ? [] : [prevAttribute],
updatedFileAttributes: [],
});
- const expectedResult = expected !== null ? [{ id: ATTR_ID, boolean: expected }] : [];
+
+ const expectedResult = expected !== "empty" ? [{ id: ATTR_ID, boolean: expected }] : [];
expect(result).toEqual(expectedResult);
});
});
+
+ describe("works with required boolean attributes", () => {
+ test.each`
+ newAttr | oldAttr | expected
+ ${null} | ${null} | ${null}
+ ${true} | ${true} | ${true}
+ ${true} | ${false} | ${true}
+ ${true} | ${null} | ${true}
+ ${false} | ${false} | ${false}
+ ${false} | ${true} | ${false}
+ ${false} | ${null} | ${false}
+ `("$oldAttr -> $newAttr returns $expected", ({ newAttr, oldAttr, expected }) => {
+ const attribute = createBooleanAttribute(newAttr, true);
+ const prevAttribute = createBooleanAttribute(oldAttr, true);
+ const result = prepareAttributesInput({
+ attributes: [attribute],
+ prevAttributes: [prevAttribute],
+ updatedFileAttributes: [],
+ });
+
+ expect(result).toEqual([{ id: ATTR_ID, boolean: expected }]);
+ });
+ });
+
describe("works with plain text attributes", () => {
test.each`
newAttr | oldAttr | expected
@@ -292,6 +384,27 @@ describe("Sending only changed attributes", () => {
expect(result).toEqual(expectedResult);
});
});
+
+ describe("works with required plain text attributes", () => {
+ test.each`
+ newAttr | oldAttr | expected
+ ${null} | ${null} | ${undefined}
+ ${"my value"} | ${"my value"} | ${"my value"}
+ ${"my value"} | ${null} | ${"my value"}
+ ${null} | ${"my value"} | ${undefined}
+ `("$oldAttr -> $newAttr returns $expected", ({ newAttr, oldAttr, expected }) => {
+ const attribute = createPlainTextAttribute(newAttr, true);
+ const prevAttribute = createPlainTextAttribute(oldAttr, true);
+ const result = prepareAttributesInput({
+ attributes: [attribute],
+ prevAttributes: [prevAttribute],
+ updatedFileAttributes: [],
+ });
+
+ expect(result).toEqual([{ id: ATTR_ID, plainText: expected }]);
+ });
+ });
+
describe("works with rich text attributes", () => {
test.each`
newAttr | oldAttr | expected
@@ -312,6 +425,27 @@ describe("Sending only changed attributes", () => {
expect(result).toEqual(expectedResult);
});
});
+
+ describe("works with required rich text attributes", () => {
+ test.each`
+ newAttr | oldAttr | expected
+ ${null} | ${null} | ${undefined}
+ ${"my value"} | ${"my value"} | ${"my value"}
+ ${"my value"} | ${null} | ${"my value"}
+ ${null} | ${"my value"} | ${undefined}
+ `("$oldAttr -> $newAttr returns $expected", ({ newAttr, oldAttr, expected }) => {
+ const attribute = createRichTextAttribute(newAttr, true);
+ const prevAttribute = createRichTextAttribute(oldAttr, true);
+ const result = prepareAttributesInput({
+ attributes: [attribute],
+ prevAttributes: [prevAttribute],
+ updatedFileAttributes: [],
+ });
+
+ expect(result).toEqual([{ id: ATTR_ID, richText: expected }]);
+ });
+ });
+
describe("works with date attributes", () => {
test.each`
newAttr | oldAttr | expected
@@ -332,6 +466,27 @@ describe("Sending only changed attributes", () => {
expect(result).toEqual(expectedResult);
});
});
+
+ describe("works with required date attributes", () => {
+ test.each`
+ newAttr | oldAttr | expected
+ ${null} | ${null} | ${undefined}
+ ${"2021-01-01"} | ${"2021-01-01"} | ${"2021-01-01"}
+ ${"2021-01-01"} | ${null} | ${"2021-01-01"}
+ ${null} | ${"2021-01-01"} | ${undefined}
+ `("$oldAttr -> $newAttr returns $expected", ({ newAttr, oldAttr, expected }) => {
+ const attribute = createDateAttribute(newAttr, true);
+ const prevAttribute = createDateAttribute(oldAttr, true);
+ const result = prepareAttributesInput({
+ attributes: [attribute],
+ prevAttributes: [prevAttribute],
+ updatedFileAttributes: [],
+ });
+
+ expect(result).toEqual([{ id: ATTR_ID, date: expected }]);
+ });
+ });
+
describe("works with date time attributes", () => {
const dateTime = "2021-01-01T11:00:00+01:00";
@@ -354,6 +509,29 @@ describe("Sending only changed attributes", () => {
expect(result).toEqual(expectedResult);
});
});
+
+ describe("works with required date time attributes", () => {
+ const dateTime = "2021-01-01T11:00:00+01:00";
+
+ test.each`
+ newAttr | oldAttr | expected
+ ${null} | ${null} | ${undefined}
+ ${dateTime} | ${dateTime} | ${dateTime}
+ ${dateTime} | ${null} | ${dateTime}
+ ${null} | ${dateTime} | ${undefined}
+ `("$oldAttr -> $newAttr returns $expected", ({ newAttr, oldAttr, expected }) => {
+ const attribute = createDateTimeAttribute(newAttr, true);
+ const prevAttribute = createDateTimeAttribute(oldAttr, true);
+ const result = prepareAttributesInput({
+ attributes: [attribute],
+ prevAttributes: [prevAttribute],
+ updatedFileAttributes: [],
+ });
+
+ expect(result).toEqual([{ id: ATTR_ID, dateTime: expected }]);
+ });
+ });
+
describe("works with swatch attributes", () => {
test.each`
newAttr | oldAttr | expected
@@ -375,6 +553,27 @@ describe("Sending only changed attributes", () => {
expect(result).toEqual(expectedResult);
});
});
+
+ describe("works with required swatch attributes", () => {
+ test.each`
+ newAttr | oldAttr | expected
+ ${null} | ${null} | ${""}
+ ${"my value"} | ${"my value"} | ${"my value"}
+ ${"my value"} | ${null} | ${"my value"}
+ ${null} | ${"my value"} | ${""}
+ `("$oldAttr -> $newAttr returns $expected", ({ newAttr, oldAttr, expected }) => {
+ const attribute = createSwatchAttribute(newAttr, true);
+ const prevAttribute = createSwatchAttribute(oldAttr, true);
+ const result = prepareAttributesInput({
+ attributes: [attribute],
+ prevAttributes: [prevAttribute],
+ updatedFileAttributes: [],
+ });
+
+ expect(result).toEqual([{ id: ATTR_ID, swatch: { value: expected } }]);
+ });
+ });
+
describe("works with numeric attributes", () => {
test.each`
newAttr | oldAttr | expected
@@ -395,6 +594,27 @@ describe("Sending only changed attributes", () => {
expect(result).toEqual(expectedResult);
});
});
+
+ describe("works with required numeric attributes", () => {
+ test.each`
+ newAttr | oldAttr | expected
+ ${null} | ${null} | ${[]}
+ ${"1"} | ${"1"} | ${["1"]}
+ ${"1"} | ${null} | ${["1"]}
+ ${null} | ${"1"} | ${[]}
+ `("$oldAttr -> $newAttr returns $expected", ({ newAttr, oldAttr, expected }) => {
+ const attribute = createNumericAttribute(newAttr, true);
+ const prevAttribute = createNumericAttribute(oldAttr, true);
+ const result = prepareAttributesInput({
+ attributes: [attribute],
+ prevAttributes: [prevAttribute],
+ updatedFileAttributes: [],
+ });
+
+ expect(result).toEqual([{ id: ATTR_ID, values: expected }]);
+ });
+ });
+
describe("works with file attributes", () => {
it("removes existing image (img -> null)", () => {
const attribute = createFileAttribute("");
@@ -461,4 +681,172 @@ describe("Sending only changed attributes", () => {
]);
});
});
+
+ describe("works with required file attributes", () => {
+ it("removes existing image (img -> null)", () => {
+ const attribute = createFileAttribute("", true);
+ const prevAttribute = createNumericAttribute("bob.jpg");
+ const result = prepareAttributesInput({
+ attributes: [attribute],
+ prevAttributes: [prevAttribute],
+ updatedFileAttributes: [
+ { file: undefined, id: ATTR_ID, contentType: undefined, values: [] },
+ ],
+ });
+
+ expect(result).toEqual([
+ {
+ id: ATTR_ID,
+ contentType: undefined,
+ file: undefined,
+ },
+ ]);
+ });
+ it("adds new image (null -> img)", () => {
+ const attribute = createFileAttribute("bob.jpg", true);
+ const prevAttribute = createNumericAttribute("");
+ const uploadUrl = "http://some-url.com/media/file_upload/bob.jpg";
+ const result = prepareAttributesInput({
+ attributes: [attribute],
+ prevAttributes: [prevAttribute],
+ updatedFileAttributes: [
+ {
+ file: uploadUrl,
+ id: ATTR_ID,
+ contentType: "image/jpeg",
+ values: [],
+ },
+ ],
+ });
+
+ expect(result).toEqual([
+ {
+ id: ATTR_ID,
+ file: uploadUrl,
+ contentType: "image/jpeg",
+ },
+ ]);
+ });
+ it("replaces existing image (bob.jpg -> juice.png)", () => {
+ const attribute = createFileAttribute("bob.jpg", true);
+ const prevAttribute = createNumericAttribute("juice.png");
+ const uploadUrl = "http://some-url.com/media/file_upload/juice.jpg";
+ const result = prepareAttributesInput({
+ attributes: [attribute],
+ prevAttributes: [prevAttribute],
+ updatedFileAttributes: [
+ {
+ file: uploadUrl,
+ id: ATTR_ID,
+ contentType: "image/png",
+ values: [],
+ },
+ ],
+ });
+
+ expect(result).toEqual([
+ {
+ id: ATTR_ID,
+ file: uploadUrl,
+ contentType: "image/png",
+ },
+ ]);
+ });
+ });
+});
+
+describe("createAttributeChangeHandler", () => {
+ it("should return empty array when value is empty string", () => {
+ // Arrange
+ const change = jest.fn();
+ const trigger = jest.fn();
+ const handler = createAttributeChangeHandler(change, trigger);
+
+ // Act
+ handler("attr-1", "");
+
+ // Assert
+ expect(change).toHaveBeenCalledTimes(1);
+ expect(change).toHaveBeenCalledWith("attr-1", []);
+ expect(trigger).toHaveBeenCalledTimes(1);
+ });
+
+ it("should return empty array when value is null", () => {
+ // Arrange
+ const change = jest.fn();
+ const trigger = jest.fn();
+ const handler = createAttributeChangeHandler(change, trigger);
+
+ // Act
+ handler("attr-1", null);
+
+ // Assert
+ expect(change).toHaveBeenCalledTimes(1);
+ expect(change).toHaveBeenCalledWith("attr-1", []);
+ expect(trigger).toHaveBeenCalledTimes(1);
+ });
+
+ it("should return array with value when value not null or undefined or empty string", () => {
+ // Arrange
+ const change = jest.fn();
+ const trigger = jest.fn();
+ const handler = createAttributeChangeHandler(change, trigger);
+
+ // Act
+ handler("attr-1", "val-1");
+
+ // Assert
+ expect(change).toHaveBeenCalledTimes(1);
+ expect(change).toHaveBeenCalledWith("attr-1", ["val-1"]);
+ expect(trigger).toHaveBeenCalledTimes(1);
+ });
+});
+
+describe("handleDeleteMultipleAttributeValues", () => {
+ it("should return empty array when no attributes", async () => {
+ // Arrange
+ const trigger = jest.fn();
+
+ // Act
+ const result = await handleDeleteMultipleAttributeValues([], undefined, trigger);
+
+ // Assert
+ expect(result).toEqual([]);
+ expect(trigger).toHaveBeenCalledTimes(0);
+ });
+
+ it("should call deleteAttributeValue when new attribute with file match existing one", async () => {
+ // Arrange
+ const deleteAttributeValue = jest.fn(() => Promise.resolve("val-1")) as any;
+ const attributesWithNewFileValue = [
+ {
+ id: "attr-1",
+ },
+ ] as FormsetData;
+
+ const attributes = [
+ {
+ attribute: {
+ id: "attr-1",
+ inputType: AttributeInputTypeEnum.FILE,
+ },
+ values: [
+ {
+ id: "val-1",
+ },
+ ],
+ },
+ ] as Array;
+
+ // Act
+ const result = await handleDeleteMultipleAttributeValues(
+ attributesWithNewFileValue,
+ attributes,
+ deleteAttributeValue,
+ );
+
+ // Assert
+ expect(result).toEqual(["val-1"]);
+ expect(deleteAttributeValue).toHaveBeenCalledTimes(1);
+ });
});
diff --git a/src/attributes/utils/handlers.ts b/src/attributes/utils/handlers.ts
index ce833376834..7f664cb1f66 100644
--- a/src/attributes/utils/handlers.ts
+++ b/src/attributes/utils/handlers.ts
@@ -29,10 +29,10 @@ import { getFileValuesToUploadFromAttributes, isFileValueUnused } from "./data";
export function createAttributeChangeHandler(
changeAttributeData: FormsetChange,
triggerChange: () => void,
-): FormsetChange {
- return (attributeId: string, value: string) => {
+): FormsetChange {
+ return (attributeId: string, value: string | null | undefined) => {
triggerChange();
- changeAttributeData(attributeId, value === "" ? [] : [value]);
+ changeAttributeData(attributeId, !value ? [] : [value]);
};
}
@@ -206,7 +206,7 @@ function getFileInput(attribute: AttributeInput, updatedFileAttributes: Attribut
function getBooleanInput(attribute: AttributeInput) {
return {
id: attribute.id,
- boolean: attribute.value[0] ? JSON.parse(attribute.value[0]) : null,
+ boolean: attribute.value[0] != null ? JSON.parse(attribute.value[0]) : null,
};
}
@@ -234,7 +234,7 @@ export const prepareAttributesInput = ({
return attributes.reduce((attrInput: AttributeValueInput[], attr) => {
const prevAttrValue = prevAttributesMap.get(attr.id);
- if (isEqual(attr.value, prevAttrValue)) {
+ if (isEqual(attr.value, prevAttrValue) && !attr.data.isRequired) {
return attrInput;
}
@@ -243,7 +243,7 @@ export const prepareAttributesInput = ({
if (inputType === AttributeInputTypeEnum.FILE) {
const fileInput = getFileInput(attr, updatedFileAttributes);
- if (fileInput.file) {
+ if (fileInput.file || attr.data.isRequired) {
attrInput.push(fileInput);
}
@@ -254,7 +254,7 @@ export const prepareAttributesInput = ({
const booleanInput = getBooleanInput(attr);
// previous comparison doesn't work because value was string
- if (isEqual([booleanInput.boolean], prevAttrValue)) {
+ if (isEqual([booleanInput.boolean], prevAttrValue) && !attr.data.isRequired) {
return attrInput;
}
@@ -319,6 +319,17 @@ export const prepareAttributesInput = ({
return attrInput;
}
+ if (inputType === AttributeInputTypeEnum.NUMERIC) {
+ const isEmpty = attr.value[0] === undefined || attr.value[0] === null;
+
+ attrInput.push({
+ id: attr.id,
+ values: isEmpty ? [] : attr.value,
+ });
+
+ return attrInput;
+ }
+
attrInput.push({
id: attr.id,
values: attr.value,
@@ -342,16 +353,22 @@ export const handleUploadMultipleFiles = async (
export const handleDeleteMultipleAttributeValues = async (
attributesWithNewFileValue: FormsetData,
- attributes: Array<
- | PageSelectedAttributeFragment
- | ProductFragment["attributes"][0]
- | NonNullable["nonSelectionAttributes"][0]
- >,
+ attributes:
+ | Array<
+ | PageSelectedAttributeFragment
+ | ProductFragment["attributes"][0]
+ | NonNullable["nonSelectionAttributes"][0]
+ >
+ | undefined,
deleteAttributeValue: (
variables: AttributeValueDeleteMutationVariables,
) => Promise>,
-) =>
- Promise.all(
+) => {
+ if (!attributes) {
+ return [];
+ }
+
+ return Promise.all(
attributes.map(existingAttribute => {
const fileValueUnused = isFileValueUnused(attributesWithNewFileValue, existingAttribute);
@@ -365,3 +382,4 @@ export const handleDeleteMultipleAttributeValues = async (
return undefined;
}),
);
+};
diff --git a/src/attributes/views/AttributeList/AttributeList.tsx b/src/attributes/views/AttributeList/AttributeList.tsx
index b8a67910608..e08ba13dc2c 100644
--- a/src/attributes/views/AttributeList/AttributeList.tsx
+++ b/src/attributes/views/AttributeList/AttributeList.tsx
@@ -3,8 +3,11 @@ import {
getFilterVariables,
storageUtils,
} from "@dashboard/attributes/views/AttributeList/filters";
+import { useConditionalFilterContext } from "@dashboard/components/ConditionalFilter";
+import { creatAttributesQueryVariables } from "@dashboard/components/ConditionalFilter/queryVariables";
import DeleteFilterTabDialog from "@dashboard/components/DeleteFilterTabDialog";
import SaveFilterTabDialog from "@dashboard/components/SaveFilterTabDialog";
+import { useFlag } from "@dashboard/featureFlags";
import { useAttributeBulkDeleteMutation, useAttributeListQuery } from "@dashboard/graphql";
import { useFilterPresets } from "@dashboard/hooks/useFilterPresets";
import useListSettings from "@dashboard/hooks/useListSettings";
@@ -41,6 +44,9 @@ const AttributeList: React.FC = ({ params }) => {
const notify = useNotifier();
const intl = useIntl();
const { updateListSettings, settings } = useListSettings(ListViews.ATTRIBUTE_LIST);
+ const { enabled: isAttributesFilteringEnabled } = useFlag("new_filters");
+ const { valueProvider } = useConditionalFilterContext();
+ const filters = creatAttributesQueryVariables(valueProvider.value);
usePaginationReset(attributeListUrl, params, settings.rowNumber);
@@ -53,8 +59,19 @@ const AttributeList: React.FC = ({ params }) => {
}),
[params, settings.rowNumber],
);
+ const newQueryVariables = React.useMemo(
+ () => ({
+ ...paginationState,
+ filter: {
+ ...filters,
+ search: params.query,
+ },
+ sort: getSortQueryVariables(params),
+ }),
+ [params, settings.rowNumber, valueProvider.value],
+ );
const { data, loading, refetch } = useAttributeListQuery({
- variables: queryVariables,
+ variables: isAttributesFilteringEnabled ? newQueryVariables : queryVariables,
});
const {
clearRowSelection,
diff --git a/src/attributes/views/AttributeList/sort.ts b/src/attributes/views/AttributeList/sort.ts
index 1249422a148..0f3197334af 100644
--- a/src/attributes/views/AttributeList/sort.ts
+++ b/src/attributes/views/AttributeList/sort.ts
@@ -8,8 +8,6 @@ export function getSortQueryField(sort: AttributeListUrlSortField): AttributeSor
return AttributeSortField.NAME;
case AttributeListUrlSortField.slug:
return AttributeSortField.SLUG;
- case AttributeListUrlSortField.searchable:
- return AttributeSortField.FILTERABLE_IN_DASHBOARD;
case AttributeListUrlSortField.useInFacetedSearch:
return AttributeSortField.FILTERABLE_IN_STOREFRONT;
case AttributeListUrlSortField.visible:
diff --git a/src/auth/AuthProvider.test.tsx b/src/auth/AuthProvider.test.tsx
index e723c6b6f5a..a756fc1fa4c 100644
--- a/src/auth/AuthProvider.test.tsx
+++ b/src/auth/AuthProvider.test.tsx
@@ -211,4 +211,49 @@ describe("AuthProvider", () => {
expect(hook.result.current.errors).toEqual(["noPermissionsError"]);
expect(hook.result.current.authenticated).toBe(false);
});
+
+ it("should handle concurrent login attempts correctly", async () => {
+ const intl = useIntl();
+ const notify = useNotifier();
+ const apolloClient = useApolloClient();
+
+ (useAuthState as jest.Mock).mockImplementation(() => ({
+ authenticated: false,
+ authenticating: false,
+ }));
+
+ const loginMock = jest.fn(
+ () =>
+ new Promise(resolve => {
+ return resolve({
+ data: {
+ tokenCreate: {
+ errors: [],
+ user: {
+ userPermissions: [
+ {
+ code: "MANAGE_USERS",
+ name: "Handle checkouts",
+ },
+ ],
+ },
+ },
+ },
+ });
+ }),
+ );
+
+ (useAuth as jest.Mock).mockImplementation(() => ({
+ login: loginMock,
+ logout: jest.fn(),
+ }));
+
+ const { result } = renderHook(() => useAuthProvider({ intl, notify, apolloClient }));
+
+ // Simulate two concurrent login attempts
+ result.current.login!("email", "password");
+ result.current.login!("email", "password");
+
+ expect(loginMock).toHaveBeenCalledTimes(1);
+ });
});
diff --git a/src/auth/components/LoginPage/LoginPage.tsx b/src/auth/components/LoginPage/LoginPage.tsx
index 5e002303dfb..6bcf525d15c 100644
--- a/src/auth/components/LoginPage/LoginPage.tsx
+++ b/src/auth/components/LoginPage/LoginPage.tsx
@@ -1,12 +1,12 @@
import { UserContextError } from "@dashboard/auth/types";
import { passwordResetUrl } from "@dashboard/auth/urls";
-import { Button } from "@dashboard/components/Button";
import { FormSpacer } from "@dashboard/components/FormSpacer";
import { AvailableExternalAuthenticationsQuery } from "@dashboard/graphql";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import { commonMessages } from "@dashboard/intl";
-import { CircularProgress, Divider, TextField, Typography } from "@material-ui/core";
+import { CircularProgress, Divider, TextField } from "@material-ui/core";
import { EyeIcon, IconButton } from "@saleor/macaw-ui";
+import { Box, Button, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { Link } from "react-router-dom";
@@ -48,14 +48,22 @@ const LoginPage: React.FC = props => {
return (
{({ change: handleChange, data, submit }) => (
- <>
-
+
+
-
+
{errors.map(error => (
-
- {getErrorMessage(error, intl)}
-
+
+ {getErrorMessage(error, intl)}
+
))}
= props => {
-
= props => {
defaultMessage="Forgot password?"
description="description"
/>
-
+
= props => {
-
+
-
+
>
)}
{externalAuthentications.map(externalAuthentication => (
onExternalAuthentication(externalAuthentication.id)}
data-test-id="external-authentication"
@@ -154,7 +163,7 @@ const LoginPage: React.FC = props => {
))}
- >
+
)}
);
diff --git a/src/auth/components/LoginPage/messages.ts b/src/auth/components/LoginPage/messages.ts
index 3d18f97cff0..369269d6479 100644
--- a/src/auth/components/LoginPage/messages.ts
+++ b/src/auth/components/LoginPage/messages.ts
@@ -22,6 +22,11 @@ export const errorMessages = defineMessages({
defaultMessage: "You don't have permission to login.",
description: "error message",
},
+ loginAttemptDelay: {
+ defaultMessage: "Please wait a moment before trying again.",
+ description: "error message",
+ id: "RyZd9J",
+ },
});
export function getErrorMessage(err: UserContextError, intl: IntlShape): string {
@@ -36,5 +41,7 @@ export function getErrorMessage(err: UserContextError, intl: IntlShape): string
return intl.formatMessage(errorMessages.serverError);
case "noPermissionsError":
return intl.formatMessage(errorMessages.noPermissionsError);
+ case "loginAttemptDelay":
+ return intl.formatMessage(errorMessages.loginAttemptDelay);
}
}
diff --git a/src/auth/components/NewPasswordPage/NewPasswordPage.tsx b/src/auth/components/NewPasswordPage/NewPasswordPage.tsx
index 179b8aea922..3b768a7f719 100644
--- a/src/auth/components/NewPasswordPage/NewPasswordPage.tsx
+++ b/src/auth/components/NewPasswordPage/NewPasswordPage.tsx
@@ -1,15 +1,13 @@
-import { Button } from "@dashboard/components/Button";
import Form from "@dashboard/components/Form";
import FormSpacer from "@dashboard/components/FormSpacer";
import { AccountErrorFragment } from "@dashboard/graphql";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import getAccountErrorMessage from "@dashboard/utils/errors/account";
-import { TextField, Typography } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
+import { Box, Button, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
-import useStyles from "../styles";
-
export interface NewPasswordPageFormData {
password: string;
confirmPassword: string;
@@ -26,7 +24,6 @@ const initialForm: NewPasswordPageFormData = {
};
const NewPasswordPage: React.FC = props => {
const { loading, errors, onSubmit } = props;
- const classes = useStyles(props);
const intl = useIntl();
return (
@@ -36,24 +33,31 @@ const NewPasswordPage: React.FC = props => {
return (
<>
-
+
-
+
{errors.map(error => (
-
+
{getAccountErrorMessage(error, intl)}
-
+
))}
-
+
-
+
= props => {
= props => {
const { disabled, error, onSubmit } = props;
- const classes = useStyles(props);
const intl = useIntl();
return (
{({ change: handleChange, data, submit: handleSubmit }) => (
- <>
-
-
-
-
+
+ }
+ href={getAppMountUri()}
+ variant="secondary"
+ marginBottom={4}
+ />
+
+
-
- {!!error && {error}
}
-
+
+ {!!error && (
+
+ {error}
+
+ )}
+
-
+
= props => {
= props => {
description="password reset, button"
/>
- >
+
)}
);
diff --git a/src/auth/components/ResetPasswordSuccessPage/ResetPasswordSuccessPage.tsx b/src/auth/components/ResetPasswordSuccessPage/ResetPasswordSuccessPage.tsx
index 8ea9ab58b2f..d8ce99cb801 100644
--- a/src/auth/components/ResetPasswordSuccessPage/ResetPasswordSuccessPage.tsx
+++ b/src/auth/components/ResetPasswordSuccessPage/ResetPasswordSuccessPage.tsx
@@ -1,11 +1,8 @@
-import { Button } from "@dashboard/components/Button";
import FormSpacer from "@dashboard/components/FormSpacer";
-import { Typography } from "@material-ui/core";
+import { Button, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage } from "react-intl";
-import useStyles from "../styles";
-
export interface ResetPasswordSuccessPageFormData {
email: string;
}
@@ -15,26 +12,25 @@ export interface ResetPasswordSuccessPageProps {
const ResetPasswordSuccessPage: React.FC = props => {
const { onBack } = props;
- const classes = useStyles(props);
return (
<>
-
+
-
-
+
+
-
+
diff --git a/src/auth/components/SectionRoute.tsx b/src/auth/components/SectionRoute.tsx
index 4624e756db8..83319872161 100644
--- a/src/auth/components/SectionRoute.tsx
+++ b/src/auth/components/SectionRoute.tsx
@@ -1,6 +1,7 @@
+import { Route } from "@dashboard/components/Router";
import { PermissionEnum } from "@dashboard/graphql";
import React from "react";
-import { Route, RouteProps } from "react-router-dom";
+import { RouteProps } from "react-router-dom";
import NotFound from "../../NotFound";
import { useUser } from "..";
diff --git a/src/auth/components/styles.ts b/src/auth/components/styles.ts
index 6e379e4a29f..0440c7ebe7c 100644
--- a/src/auth/components/styles.ts
+++ b/src/auth/components/styles.ts
@@ -5,16 +5,10 @@ const useStyles = makeStyles(
arrow: {
transform: "rotate(180deg)",
},
- backBtn: {
- marginBottom: theme.spacing(3),
- },
buttonContainer: {
display: "flex",
justifyContent: "flex-end",
- },
- header: {
- fontWeight: 700,
- marginBottom: theme.spacing(2),
+ width: "100%",
},
link: {
color: theme.palette.primary.main,
@@ -33,27 +27,15 @@ const useStyles = makeStyles(
loginButton: {
width: "100%",
},
- panel: {
- "& span": {
- color: theme.palette.error.contrastText,
- },
- ...theme.typography.body1,
- background: theme.palette.alert.paper.error,
- borderRadius: 8,
- marginBottom: theme.spacing(2),
- padding: theme.spacing(2.5),
- },
passwordWrapper: {
position: "relative",
+ width: "100%",
},
showPasswordBtn: {
position: "absolute",
top: 6,
right: 8,
},
- submit: {
- width: "100%",
- },
}),
{ name: "Login" },
);
diff --git a/src/auth/hooks/useAuthProvider.ts b/src/auth/hooks/useAuthProvider.ts
index 13cfd003974..ed115016727 100644
--- a/src/auth/hooks/useAuthProvider.ts
+++ b/src/auth/hooks/useAuthProvider.ts
@@ -1,7 +1,7 @@
import { ApolloClient, ApolloError } from "@apollo/client";
import { IMessageContext } from "@dashboard/components/messages";
import { DEMO_MODE } from "@dashboard/config";
-import { useUserDetailsQuery } from "@dashboard/graphql";
+import { AccountErrorCode, useUserDetailsQuery } from "@dashboard/graphql";
import useLocalStorage from "@dashboard/hooks/useLocalStorage";
import useNavigator from "@dashboard/hooks/useNavigator";
import { commonMessages } from "@dashboard/intl";
@@ -33,12 +33,14 @@ export interface UseAuthProviderOpts {
notify: IMessageContext;
apolloClient: ApolloClient;
}
+type AuthErrorCodes = `${AccountErrorCode}`;
export function useAuthProvider({ intl, notify, apolloClient }: UseAuthProviderOpts): UserContext {
const { login, getExternalAuthUrl, getExternalAccessToken, logout } = useAuth();
const navigate = useNavigator();
const { authenticated, authenticating, user } = useAuthState();
const [requestedExternalPluginId] = useLocalStorage("requestedExternalPluginId", null);
+ const [isAuthRequestRunning, setIsAuthRequestRunning] = useState(false);
const [errors, setErrors] = useState([]);
const permitCredentialsAPI = useRef(true);
@@ -112,27 +114,45 @@ export function useAuthProvider({ intl, notify, apolloClient }: UseAuthProviderO
}
}
};
+
const handleLogin = async (email: string, password: string) => {
+ if (isAuthRequestRunning) {
+ return;
+ }
+
try {
+ setIsAuthRequestRunning(true);
+
const result = await login({
email,
password,
includeDetails: false,
});
+ const errorList = result.data?.tokenCreate?.errors?.map(
+ ({ code }) => code,
+ // SDK is deprecated and has outdated types - we need to use ones from Dashboard
+ ) as AuthErrorCodes[];
+
if (isEmpty(result.data?.tokenCreate?.user?.userPermissions)) {
setErrors(["noPermissionsError"]);
await handleLogout();
}
- if (result && !result.data?.tokenCreate?.errors.length) {
+ if (result && !errorList?.length) {
if (DEMO_MODE) {
displayDemoMessage(intl, notify);
}
saveCredentials(result.data?.tokenCreate?.user!, password);
} else {
- setErrors(["loginError"]);
+ // While login page can show multiple errors, "loginError" doesn't match "attemptDelay"
+ // and should be shown when no other error is present
+ if (errorList?.includes(AccountErrorCode.LOGIN_ATTEMPT_DELAYED)) {
+ setErrors(["loginAttemptDelay"]);
+ } else {
+ setErrors(["loginError"]);
+ }
}
await logoutNonStaffUser(result.data?.tokenCreate!);
@@ -144,12 +164,24 @@ export function useAuthProvider({ intl, notify, apolloClient }: UseAuthProviderO
} else {
setErrors(["unknownLoginError"]);
}
+ } finally {
+ setIsAuthRequestRunning(false);
}
};
const handleRequestExternalLogin = async (pluginId: string, input: RequestExternalLoginInput) => {
+ let stringifyInput: string;
+
+ try {
+ stringifyInput = JSON.stringify(input);
+ } catch (error) {
+ setErrors(["externalLoginError"]);
+
+ return;
+ }
+
const result = await getExternalAuthUrl({
pluginId,
- input: JSON.stringify(input),
+ input: stringifyInput,
});
return result?.data?.externalAuthenticationUrl;
diff --git a/src/auth/index.tsx b/src/auth/index.tsx
index 9d774473ab5..d1f629bcfe2 100644
--- a/src/auth/index.tsx
+++ b/src/auth/index.tsx
@@ -1,6 +1,7 @@
+import { Route } from "@dashboard/components/Router";
import { parse as parseQs } from "qs";
import React, { useContext } from "react";
-import { Route, RouteComponentProps, Switch } from "react-router-dom";
+import { RouteComponentProps, Switch } from "react-router-dom";
import Layout from "./components/Layout";
import { UserContext as Context } from "./types";
diff --git a/src/auth/types.ts b/src/auth/types.ts
index 3dd781ffbe9..023f6b2a45b 100644
--- a/src/auth/types.ts
+++ b/src/auth/types.ts
@@ -20,6 +20,7 @@ export const UserContextError = {
serverError: "serverError",
noPermissionsError: "noPermissionsError",
externalLoginError: "externalLoginError",
+ loginAttemptDelay: "loginAttemptDelay",
unknownLoginError: "unknownLoginError",
} as const;
diff --git a/src/auth/views/Login.tsx b/src/auth/views/Login.tsx
index 16e5bb9f729..41fe9572a19 100644
--- a/src/auth/views/Login.tsx
+++ b/src/auth/views/Login.tsx
@@ -32,7 +32,11 @@ const LoginView: React.FC = ({ params }) => {
setRequestedExternalPluginId,
} = useAuthParameters();
const handleSubmit = async (data: LoginFormData) => {
- const result = await login!(data.email, data.password);
+ if (!login) {
+ return;
+ }
+
+ const result = await login(data.email, data.password);
const errors = result?.errors || [];
return errors;
diff --git a/src/categories/components/CategoryBackground/CategoryBackground.tsx b/src/categories/components/CategoryBackground/CategoryBackground.tsx
index daa0857aa47..63836003441 100644
--- a/src/categories/components/CategoryBackground/CategoryBackground.tsx
+++ b/src/categories/components/CategoryBackground/CategoryBackground.tsx
@@ -1,14 +1,13 @@
import { Button } from "@dashboard/components/Button";
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import Hr from "@dashboard/components/Hr";
import ImageUpload from "@dashboard/components/ImageUpload";
import MediaTile from "@dashboard/components/MediaTile";
-import Skeleton from "@dashboard/components/Skeleton";
import { CategoryDetailsFragment } from "@dashboard/graphql";
import { commonMessages } from "@dashboard/intl";
-import { Card, CardContent, TextField } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
-import { vars } from "@saleor/macaw-ui-next";
+import { Skeleton, vars } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -56,49 +55,50 @@ const CategoryBackground: React.FC = props => {
const handleImageUploadButtonClick = () => anchor.current?.click();
return (
-
-
-
-
-
- onImageUpload(files && files[0])}
- type="file"
- ref={anchor}
- accept="image/*"
- />
- >
- }
- />
+
+
+
+ {intl.formatMessage({
+ id: "DP6b8U",
+ defaultMessage: "Background Image (optional)",
+ description: "section header",
+ })}
+
+
+
+
+
+ onImageUpload(files && files[0])}
+ type="file"
+ ref={anchor}
+ accept="image/*"
+ />
+
+
+
{image === undefined ? (
-
+
-
+
) : image === null ? (
onImageUpload(files[0])} />
) : (
-
+
-
+
)}
{image && (
<>
-
+
= props => {
fullWidth
multiline
/>
-
+
>
)}
-
+
);
};
diff --git a/src/categories/components/CategoryDeleteDialog/CategoryDeleteDialog.tsx b/src/categories/components/CategoryDeleteDialog/CategoryDeleteDialog.tsx
deleted file mode 100644
index d7bc2be1da5..00000000000
--- a/src/categories/components/CategoryDeleteDialog/CategoryDeleteDialog.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import BackButton from "@dashboard/components/BackButton";
-import { Button } from "@dashboard/components/Button";
-import { buttonMessages } from "@dashboard/intl";
-import {
- Dialog,
- DialogActions,
- DialogContent,
- DialogContentText,
- DialogTitle,
-} from "@material-ui/core";
-import { makeStyles } from "@saleor/macaw-ui";
-import React from "react";
-import { FormattedMessage } from "react-intl";
-
-const useStyles = makeStyles(
- theme => ({
- deleteButton: {
- "&:hover": {
- backgroundColor: theme.palette.error.main,
- },
- backgroundColor: theme.palette.error.main,
- color: theme.palette.error.contrastText,
- },
- }),
- {
- name: "CategoryDeleteDialog",
- },
-);
-
-export interface CategoryDeleteDialogProps {
- open: boolean;
- name: string;
- onClose: () => any;
- onConfirm: () => any;
-}
-
-const CategoryDeleteDialog: React.FC = props => {
- const { name, open, onConfirm, onClose } = props;
- const classes = useStyles(props);
-
- return (
-
-
-
-
-
-
- {name},
- }}
- />
-
-
-
-
-
-
-
-
-
- );
-};
-
-CategoryDeleteDialog.displayName = "CategoryDeleteDialog";
-export default CategoryDeleteDialog;
diff --git a/src/categories/components/CategoryDeleteDialog/index.ts b/src/categories/components/CategoryDeleteDialog/index.ts
deleted file mode 100644
index 31957694a07..00000000000
--- a/src/categories/components/CategoryDeleteDialog/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from "./CategoryDeleteDialog";
-export * from "./CategoryDeleteDialog";
diff --git a/src/categories/components/CategoryDetailsForm/CategoryDetailsForm.tsx b/src/categories/components/CategoryDetailsForm/CategoryDetailsForm.tsx
index ba805fa32cc..95283b5ccb7 100644
--- a/src/categories/components/CategoryDetailsForm/CategoryDetailsForm.tsx
+++ b/src/categories/components/CategoryDetailsForm/CategoryDetailsForm.tsx
@@ -1,4 +1,4 @@
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import FormSpacer from "@dashboard/components/FormSpacer";
import RichTextEditor from "@dashboard/components/RichTextEditor";
import { RichTextEditorLoading } from "@dashboard/components/RichTextEditor/RichTextEditorLoading";
@@ -7,7 +7,7 @@ import { commonMessages } from "@dashboard/intl";
import { getFormErrors, getProductErrorMessage } from "@dashboard/utils/errors";
import { useRichTextContext } from "@dashboard/utils/richText/context";
import { OutputData } from "@editorjs/editorjs";
-import { Card, CardContent, TextField } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
import React from "react";
import { useIntl } from "react-intl";
@@ -32,9 +32,14 @@ export const CategoryDetailsForm: React.FC = ({
const formErrors = getFormErrors(["name", "description"], errors);
return (
-
-
-
+
+
+
+ {intl.formatMessage(commonMessages.generalInformations)}
+
+
+
+
= ({
name="description"
/>
)}
-
-
+
+
);
};
export default CategoryDetailsForm;
diff --git a/src/categories/components/CategoryListDatagrid/CategoryListDatagrid.tsx b/src/categories/components/CategoryListDatagrid/CategoryListDatagrid.tsx
index 7c1f076b8c4..db185f2ee0d 100644
--- a/src/categories/components/CategoryListDatagrid/CategoryListDatagrid.tsx
+++ b/src/categories/components/CategoryListDatagrid/CategoryListDatagrid.tsx
@@ -8,11 +8,13 @@ import {
} from "@dashboard/components/Datagrid/hooks/useDatagridChange";
import { TablePaginationWithContext } from "@dashboard/components/TablePagination";
import { CategoryFragment } from "@dashboard/graphql";
+import { getPrevLocationState } from "@dashboard/hooks/useBackLinkWithState";
import { PageListProps, SortPage } from "@dashboard/types";
import { Item } from "@glideapps/glide-data-grid";
import { Box } from "@saleor/macaw-ui-next";
import React, { ReactNode, useCallback, useMemo } from "react";
import { useIntl } from "react-intl";
+import { useLocation } from "react-router";
import { categoryListStaticColumnsAdapter, createGetCellContent } from "./datagrid";
import { messages } from "./messages";
@@ -37,6 +39,7 @@ export const CategoryListDatagrid = ({
selectionActionButton = null,
hasRowHover = true,
}: CategoryListDatagridProps) => {
+ const location = useLocation();
const datagridState = useDatagridChangeState();
const intl = useIntl();
const memoizedStaticColumns = useMemo(
@@ -103,6 +106,7 @@ export const CategoryListDatagrid = ({
staticColumns={staticColumns}
/>
)}
+ navigatorOpts={{ state: getPrevLocationState(location) }}
/>
diff --git a/src/categories/components/CategoryListPage/CategoryListPage.tsx b/src/categories/components/CategoryListPage/CategoryListPage.tsx
index 25026d0af72..b9dab8953a2 100644
--- a/src/categories/components/CategoryListPage/CategoryListPage.tsx
+++ b/src/categories/components/CategoryListPage/CategoryListPage.tsx
@@ -2,16 +2,16 @@ import { categoryAddUrl, CategoryListUrlSortField } from "@dashboard/categories/
import SearchInput from "@dashboard/components/AppLayout/ListFilters/components/SearchInput";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import { BulkDeleteButton } from "@dashboard/components/BulkDeleteButton";
-import { Button } from "@dashboard/components/Button";
+import { DashboardCard } from "@dashboard/components/Card";
import { FilterPresetsSelect } from "@dashboard/components/FilterPresetsSelect";
import { ListPageLayout } from "@dashboard/components/Layouts";
import { CategoryFragment } from "@dashboard/graphql";
import { sectionNames } from "@dashboard/intl";
import { PageListProps, SearchPageProps, SortPage, TabPageProps } from "@dashboard/types";
-import { Card } from "@material-ui/core";
-import { Box, ChevronRightIcon } from "@saleor/macaw-ui-next";
+import { Box, Button, ChevronRightIcon } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
+import { Link } from "react-router-dom";
import { CategoryListDatagrid } from "../CategoryListDatagrid";
import { messages } from "./messages";
@@ -78,12 +78,14 @@ export const CategoryListPage: React.FC = ({
/>
-
-
-
+
+
+
+
+
-
+
= ({
hasRowHover={!isFilterPresetOpen}
{...listProps}
/>
-
+
);
};
diff --git a/src/categories/components/CategoryProducts/CategoryProducts.tsx b/src/categories/components/CategoryProducts/CategoryProducts.tsx
index a608a9d653b..2188ec56afc 100644
--- a/src/categories/components/CategoryProducts/CategoryProducts.tsx
+++ b/src/categories/components/CategoryProducts/CategoryProducts.tsx
@@ -28,34 +28,33 @@ export const CategoryProducts = ({
onSelectProductsIds,
}: CategoryProductsProps) => (
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
{
return (
-
-
+
+
+
+
-
-
+
+
= ({
}: CategoryUpdatePageProps) => {
const intl = useIntl();
const navigate = useNavigator();
- const backHref = category?.parent?.id ? categoryUrl(category?.parent?.id) : categoryListUrl();
+
+ const categoryBackListUrl = useBackLinkWithState({
+ path: categoryListPath,
+ });
+
+ const backHref = category?.parent?.id ? categoryUrl(category?.parent?.id) : categoryBackListUrl;
return (
diff --git a/src/categories/index.tsx b/src/categories/index.tsx
index 4238b937781..8d3d4a95d76 100644
--- a/src/categories/index.tsx
+++ b/src/categories/index.tsx
@@ -1,9 +1,10 @@
+import { Route } from "@dashboard/components/Router";
import { sectionNames } from "@dashboard/intl";
import { asSortParams } from "@dashboard/utils/sort";
import { parse as parseQs } from "qs";
import React from "react";
import { useIntl } from "react-intl";
-import { Route, RouteComponentProps, Switch } from "react-router-dom";
+import { RouteComponentProps, Switch } from "react-router-dom";
import { WindowTitle } from "../components/WindowTitle";
import {
diff --git a/src/categories/views/CategoryDetails.tsx b/src/categories/views/CategoryDetails.tsx
index 21956251b85..55caae1c5c2 100644
--- a/src/categories/views/CategoryDetails.tsx
+++ b/src/categories/views/CategoryDetails.tsx
@@ -28,7 +28,7 @@ import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHa
import createMetadataUpdateHandler from "@dashboard/utils/handlers/metadataUpdateHandler";
import { mapEdgesToItems } from "@dashboard/utils/maps";
import { getParsedDataForJsonStringField } from "@dashboard/utils/richText/misc";
-import { DialogContentText } from "@material-ui/core";
+import { Box } from "@saleor/macaw-ui-next";
import isEqual from "lodash/isEqual";
import React, { useCallback, useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -305,21 +305,23 @@ export const CategoryDetails: React.FC = ({ id, params })
})}
variant="delete"
>
-
- {data?.category?.name || "..."},
- }}
- />
-
-
-
-
+
+
+ {data?.category?.name || "..."},
+ }}
+ />
+
+
+
+
+
= ({ id, params })
})}
variant="delete"
>
-
- selectedCategoryRowIds.length),
- displayQuantity: {maybe(() => selectedCategoryRowIds.length)} ,
- }}
- />
-
-
-
-
+
+
+ selectedCategoryRowIds.length),
+ displayQuantity: {maybe(() => selectedCategoryRowIds.length)} ,
+ }}
+ />
+
+
+
+
+
= ({ id, params })
})}
variant="delete"
>
-
+
= ({ id, params })
displayQuantity: {maybe(() => selectedProductRowIds.length)} ,
}}
/>
-
+
);
diff --git a/src/categories/views/CategoryList/CategoryList.tsx b/src/categories/views/CategoryList/CategoryList.tsx
index 068bb129397..91134717fb1 100644
--- a/src/categories/views/CategoryList/CategoryList.tsx
+++ b/src/categories/views/CategoryList/CategoryList.tsx
@@ -20,7 +20,7 @@ import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHa
import createSortHandler from "@dashboard/utils/handlers/sortHandler";
import { mapEdgesToItems } from "@dashboard/utils/maps";
import { getSortParams } from "@dashboard/utils/sort";
-import { DialogContentText } from "@material-ui/core";
+import { Box } from "@saleor/macaw-ui-next";
import isEqual from "lodash/isEqual";
import React, { useCallback } from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -188,22 +188,24 @@ export const CategoryList: React.FC = ({ params }) => {
})}
variant="delete"
>
-
- {params?.ids?.length},
- }}
- />
-
-
-
-
+
+
+ {params?.ids?.length},
+ }}
+ />
+
+
+
+
+
= props => {
{loading ? (
) : (
-
+
{`${items.length} ${itemsName.toLowerCase()}`}
-
+
)}
@@ -76,15 +74,11 @@ const AssignmentList: React.FC = props => {
{hasMoreItemsToBeSelected ? (
) : (
-
+
{intl.formatMessage(messages.allSelectedMessage, {
itemsName: itemsName.toLowerCase(),
})}
-
+
)}
>
)}
diff --git a/src/channels/components/CannotDefineChannelsAvailabilityCard/CannotDefineChannelsAvailabilityCard.tsx b/src/channels/components/CannotDefineChannelsAvailabilityCard/CannotDefineChannelsAvailabilityCard.tsx
index facb9b76541..f040c2c73b2 100644
--- a/src/channels/components/CannotDefineChannelsAvailabilityCard/CannotDefineChannelsAvailabilityCard.tsx
+++ b/src/channels/components/CannotDefineChannelsAvailabilityCard/CannotDefineChannelsAvailabilityCard.tsx
@@ -17,9 +17,11 @@ const messages = defineMessages({
});
const CannotDefineChannelsAvailabilityCard: React.FC = () => (
-
-
-
+
+
+
+
+
diff --git a/src/channels/components/ChannelAllocationStrategy/ChannelAllocationStrategy.tsx b/src/channels/components/ChannelAllocationStrategy/ChannelAllocationStrategy.tsx
index 50a2609e1cc..d2b4a5ecde5 100644
--- a/src/channels/components/ChannelAllocationStrategy/ChannelAllocationStrategy.tsx
+++ b/src/channels/components/ChannelAllocationStrategy/ChannelAllocationStrategy.tsx
@@ -1,10 +1,9 @@
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import PreviewPill from "@dashboard/components/PreviewPill";
import RadioGroupField from "@dashboard/components/RadioGroupField";
import { AllocationStrategyEnum, StockSettingsInput } from "@dashboard/graphql";
-import { Card, CardContent, Typography } from "@material-ui/core";
import HelpOutline from "@material-ui/icons/HelpOutline";
-import { Tooltip } from "@saleor/macaw-ui-next";
+import { Text, Tooltip } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage } from "react-intl";
@@ -38,19 +37,20 @@ const ChannelAllocationStrategy: React.FC = ({
const classes = useStyles();
return (
-
-
+
+
- }
- />
-
+
+
+
+
+
@@ -69,7 +69,7 @@ const ChannelAllocationStrategy: React.FC = ({
-
+
}
choices={strategyOptions.map(option => ({
label: (
@@ -77,13 +77,13 @@ const ChannelAllocationStrategy: React.FC = ({
className={classes.option}
data-test-id={`channel-allocation-strategy-option-${option.type}`}
>
-
+
-
+
{option.subtitle && (
-
+
-
+
)}
),
@@ -94,8 +94,8 @@ const ChannelAllocationStrategy: React.FC = ({
value={data?.allocationStrategy!}
onChange={onChange}
/>
-
-
+
+
);
};
diff --git a/src/channels/components/ChannelDeleteDialog/ChannelDeleteDialog.tsx b/src/channels/components/ChannelDeleteDialog/ChannelDeleteDialog.tsx
index b0dc914d576..c7b50d6eef1 100644
--- a/src/channels/components/ChannelDeleteDialog/ChannelDeleteDialog.tsx
+++ b/src/channels/components/ChannelDeleteDialog/ChannelDeleteDialog.tsx
@@ -1,9 +1,9 @@
import ActionDialog from "@dashboard/components/ActionDialog";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
-import { Choices, SingleSelectField } from "@dashboard/components/SingleSelectField";
+import { Select } from "@dashboard/components/Select";
import useStateFromProps from "@dashboard/hooks/useStateFromProps";
import { buttonMessages } from "@dashboard/intl";
-import { Typography } from "@material-ui/core";
+import { Option, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { defineMessages, useIntl } from "react-intl";
@@ -45,7 +45,7 @@ const messages = defineMessages({
});
export interface ChannelDeleteDialogProps {
- channelsChoices: Choices;
+ channelsChoices: Option[];
channelSlug: string;
currency: string;
hasOrders: boolean;
@@ -94,33 +94,33 @@ const ChannelDeleteDialog: React.FC = ({
{hasOrders ? (
hasChannels ? (
<>
- {intl.formatMessage(messages.deletingAllProductData)}
+ {intl.formatMessage(messages.deletingAllProductData)}
-
+
{intl.formatMessage(messages.needToBeMoved)}
{intl.formatMessage(messages.note)}
-
+
- setChoice(target.value)}
value={choice}
- onChange={e => setChoice(e.target.value)}
+ options={channelsChoices}
/>
>
) : (
-
+
{intl.formatMessage(messages.noAvailableChannel, {
channelSlug: {channelSlug} ,
currency: {currency} ,
})}
-
+
)
) : (
- {intl.formatMessage(messages.deletingAllProductData)}
+ {intl.formatMessage(messages.deletingAllProductData)}
)}
diff --git a/src/channels/components/ChannelForm/AutomaticallyCompleteCheckouts.tsx b/src/channels/components/ChannelForm/AutomaticallyCompleteCheckouts.tsx
new file mode 100644
index 00000000000..0744609926b
--- /dev/null
+++ b/src/channels/components/ChannelForm/AutomaticallyCompleteCheckouts.tsx
@@ -0,0 +1,58 @@
+import Link from "@dashboard/components/Link";
+import { FormChange } from "@dashboard/hooks/useForm";
+import { DOCS_ULRS } from "@dashboard/links";
+import { Box, Checkbox, Text } from "@saleor/macaw-ui-next";
+import React from "react";
+import { FormattedMessage } from "react-intl";
+
+import { messages } from "./messages";
+
+interface AutomaticallyCompleteCheckoutsProps {
+ onChange: FormChange;
+ isChecked: boolean;
+ hasError: boolean;
+ disabled?: boolean;
+}
+
+export const AutomaticallyCompleteCheckouts = ({
+ onChange,
+ isChecked,
+ hasError,
+ disabled,
+}: AutomaticallyCompleteCheckoutsProps) => (
+
+
+ onChange({ target: { name: "automaticallyCompleteCheckouts", value } })
+ }
+ disabled={disabled}
+ >
+
+
+ {" "}
+
+
+ {" "}
+
+
+
+
+ ),
+ }}
+ />
+
+
+
+);
diff --git a/src/channels/components/ChannelForm/ChannelForm.tsx b/src/channels/components/ChannelForm/ChannelForm.tsx
index 8e5cc8ecb56..48b38eaae86 100644
--- a/src/channels/components/ChannelForm/ChannelForm.tsx
+++ b/src/channels/components/ChannelForm/ChannelForm.tsx
@@ -1,3 +1,4 @@
+import { AutomaticallyCompleteCheckouts } from "@dashboard/channels/components/ChannelForm/AutomaticallyCompleteCheckouts";
import {
ChannelShippingZones,
ChannelWarehouses,
@@ -41,6 +42,7 @@ export interface FormData extends StockSettingsInput {
deleteExpiredOrdersAfter: number;
allowUnpaidOrders: boolean;
defaultTransactionFlowStrategy: TransactionFlowStrategyEnum;
+ automaticallyCompleteCheckouts: boolean;
}
export interface ChannelFormProps {
@@ -56,6 +58,7 @@ export interface ChannelFormProps {
onDefaultCountryChange: (event: ChangeEvent) => void;
onMarkAsPaidStrategyChange: () => void;
onTransactionFlowStrategyChange: () => void;
+ onAutomaticallyCompleteCheckoutsChange: () => void;
}
export const ChannelForm: React.FC = ({
@@ -71,6 +74,7 @@ export const ChannelForm: React.FC = ({
onDefaultCountryChange,
onMarkAsPaidStrategyChange,
onTransactionFlowStrategyChange,
+ onAutomaticallyCompleteCheckoutsChange,
}) => {
const intl = useIntl();
const [, copy] = useClipboard();
@@ -83,9 +87,11 @@ export const ChannelForm: React.FC = ({
return (
<>
-
- {intl.formatMessage(commonMessages.generalInformations)}
-
+
+
+ {intl.formatMessage(commonMessages.generalInformations)}
+
+
= ({
hasError={!!formErrors.defaultTransactionFlowStrategy}
disabled={disabled}
/>
+
+
>
);
diff --git a/src/channels/components/ChannelForm/messages.ts b/src/channels/components/ChannelForm/messages.ts
index 2a1c005fede..d9d2b947e80 100644
--- a/src/channels/components/ChannelForm/messages.ts
+++ b/src/channels/components/ChannelForm/messages.ts
@@ -67,4 +67,15 @@ export const messages = defineMessages({
"When enabled, all transactions would require an additional step to be charged. ({link})",
description: "When enabled, all transactions would require an additional step to be charged.",
},
+ automaticallyCompleteCheckoutsLabel: {
+ id: "GFkb2t",
+ defaultMessage: "Automatically complete checkouts when fully paid",
+ description: "automatically complete checkouts checkbox label",
+ },
+ automaticallyCompleteCheckoutsDescription: {
+ id: "hIh8bm",
+ defaultMessage:
+ "When enabled, checkouts detected as fully paid will be completed automatically, without checkoutComplete mutation. ({link})",
+ description: "automatically complete checkouts checkbox description",
+ },
});
diff --git a/src/channels/components/ChannelPickerDialog/ChannelPickerDialog.tsx b/src/channels/components/ChannelPickerDialog/ChannelPickerDialog.tsx
index 26636458d22..aea5f792a91 100644
--- a/src/channels/components/ChannelPickerDialog/ChannelPickerDialog.tsx
+++ b/src/channels/components/ChannelPickerDialog/ChannelPickerDialog.tsx
@@ -1,18 +1,16 @@
import ActionDialog from "@dashboard/components/ActionDialog";
+import { Combobox } from "@dashboard/components/Combobox";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
-import { Choice } from "@dashboard/components/SingleSelectField";
import useChoiceSearch from "@dashboard/hooks/useChoiceSearch";
import useModalDialogOpen from "@dashboard/hooks/useModalDialogOpen";
-import useStateFromProps from "@dashboard/hooks/useStateFromProps";
-import { MenuItem } from "@material-ui/core";
-import { Autocomplete } from "@saleor/macaw-ui";
-import React from "react";
+import { Option } from "@saleor/macaw-ui-next";
+import React, { useState } from "react";
import { useIntl } from "react-intl";
import { messages } from "./messages";
export interface ChannelPickerDialogProps {
- channelsChoices: Array>;
+ channelsChoices: Option[];
confirmButtonState: ConfirmButtonTransitionState;
defaultChoice: string;
open: boolean;
@@ -29,9 +27,7 @@ const ChannelPickerDialog: React.FC = ({
onConfirm,
}) => {
const intl = useIntl();
- const [choice, setChoice] = useStateFromProps(
- defaultChoice || (channelsChoices.length ? channelsChoices[0].value : ""),
- );
+ const [choice, setChoice] = useState("");
const { result, search } = useChoiceSearch(channelsChoices);
useModalDialogOpen(open, {
@@ -48,29 +44,20 @@ const ChannelPickerDialog: React.FC = ({
onClose={onClose}
onConfirm={() => onConfirm(choice)}
title={intl.formatMessage(messages.selectChannel)}
+ size="xs"
>
- res.value === choice)?.label ?? choice,
+ }}
onChange={e => setChoice(e.target.value)}
- onInputChange={search}
- >
- {({ getItemProps, highlightedIndex }) =>
- result.map((choice, choiceIndex) => (
-
- {choice.label}
-
- ))
- }
-
+ />
);
};
diff --git a/src/channels/components/ChannelStatus/ChannelStatus.tsx b/src/channels/components/ChannelStatus/ChannelStatus.tsx
index 2f2e8f8ff63..9cad5c95ecc 100644
--- a/src/channels/components/ChannelStatus/ChannelStatus.tsx
+++ b/src/channels/components/ChannelStatus/ChannelStatus.tsx
@@ -1,11 +1,8 @@
-import CardTitle from "@dashboard/components/CardTitle";
-import { Card, CardContent, Typography } from "@material-ui/core";
-import { Button } from "@saleor/macaw-ui-next";
+import { DashboardCard } from "@dashboard/components/Card";
+import { Button, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
-import { useStyles } from "../styles";
-
export interface ChannelStatusProps {
isActive: boolean;
disabled: boolean;
@@ -18,28 +15,30 @@ export const ChannelStatus: React.FC = ({
updateChannelStatus,
}) => {
const intl = useIntl();
- const classes = useStyles({});
return (
-
-
-
-
+
+
+
+ {intl.formatMessage({
+ id: "TSJRiZ",
+ defaultMessage: "Channel Status",
+ description: "channel status title",
+ })}
+
+
+
+
+
-
-
+
+
{isActive ? (
) : (
)}
-
+
= ({
)}
-
-
+
+
);
};
diff --git a/src/channels/components/ShippingZones/ShippingZones.tsx b/src/channels/components/ShippingZones/ShippingZones.tsx
index 6bc6fb2e3ba..5e5e4024c49 100644
--- a/src/channels/components/ShippingZones/ShippingZones.tsx
+++ b/src/channels/components/ShippingZones/ShippingZones.tsx
@@ -1,9 +1,9 @@
import { ChannelShippingZones } from "@dashboard/channels/pages/ChannelDetailsPage/types";
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import { SearchShippingZonesQuery } from "@dashboard/graphql";
import { sectionNames } from "@dashboard/intl";
import { FetchMoreProps, RelayToFlat } from "@dashboard/types";
-import { Card, CardContent, Typography } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
@@ -35,11 +35,13 @@ const ShippingZones: React.FC = props => {
const intl = useIntl();
return (
-
-
-
- {intl.formatMessage(messages.subtitle)}
-
+
+
+ {intl.formatMessage(sectionNames.shippingZones)}
+
+
+ {intl.formatMessage(messages.subtitle)}
+
= props => {
inputName="shippingZone"
itemsName={intl.formatMessage(sectionNames.shippingZones)}
/>
-
+
);
};
diff --git a/src/channels/components/Warehouses/Warehouses.tsx b/src/channels/components/Warehouses/Warehouses.tsx
index b7b4493eaf0..8b2ef5efc3c 100644
--- a/src/channels/components/Warehouses/Warehouses.tsx
+++ b/src/channels/components/Warehouses/Warehouses.tsx
@@ -1,9 +1,9 @@
import { ChannelWarehouses } from "@dashboard/channels/pages/ChannelDetailsPage/types";
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import { SearchWarehousesQuery } from "@dashboard/graphql";
import { sectionNames } from "@dashboard/intl";
import { FetchMoreProps, RelayToFlat, ReorderAction } from "@dashboard/types";
-import { Card, CardContent, Typography } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
@@ -37,11 +37,13 @@ const Warehouses: React.FC = props => {
const intl = useIntl();
return (
-
-
-
- {intl.formatMessage(messages.subtitle)}
-
+
+
+ {intl.formatMessage(sectionNames.warehouses)}
+
+
+ {intl.formatMessage(messages.subtitle)}
+
= props => {
inputName="warehouse"
itemsName={intl.formatMessage(sectionNames.warehouses)}
/>
-
+
);
};
diff --git a/src/channels/fixtures.ts b/src/channels/fixtures.ts
index 24859fc42cb..3e3b7abd951 100644
--- a/src/channels/fixtures.ts
+++ b/src/channels/fixtures.ts
@@ -58,6 +58,10 @@ export const channelsList: ChannelDetailsFragment[] = [
__typename: "PaymentSettings",
defaultTransactionFlowStrategy: TransactionFlowStrategyEnum.CHARGE,
},
+ checkoutSettings: {
+ automaticallyCompleteFullyPaidCheckouts: true,
+ __typename: "CheckoutSettings",
+ },
},
{
__typename: "Channel",
@@ -98,6 +102,10 @@ export const channelsList: ChannelDetailsFragment[] = [
__typename: "PaymentSettings",
defaultTransactionFlowStrategy: TransactionFlowStrategyEnum.CHARGE,
},
+ checkoutSettings: {
+ automaticallyCompleteFullyPaidCheckouts: true,
+ __typename: "CheckoutSettings",
+ },
},
{
__typename: "Channel",
@@ -138,6 +146,10 @@ export const channelsList: ChannelDetailsFragment[] = [
__typename: "PaymentSettings",
defaultTransactionFlowStrategy: TransactionFlowStrategyEnum.CHARGE,
},
+ checkoutSettings: {
+ automaticallyCompleteFullyPaidCheckouts: true,
+ __typename: "CheckoutSettings",
+ },
},
{
__typename: "Channel",
@@ -178,6 +190,10 @@ export const channelsList: ChannelDetailsFragment[] = [
__typename: "PaymentSettings",
defaultTransactionFlowStrategy: TransactionFlowStrategyEnum.CHARGE,
},
+ checkoutSettings: {
+ automaticallyCompleteFullyPaidCheckouts: true,
+ __typename: "CheckoutSettings",
+ },
},
{
__typename: "Channel",
@@ -218,6 +234,10 @@ export const channelsList: ChannelDetailsFragment[] = [
__typename: "PaymentSettings",
defaultTransactionFlowStrategy: TransactionFlowStrategyEnum.CHARGE,
},
+ checkoutSettings: {
+ automaticallyCompleteFullyPaidCheckouts: true,
+ __typename: "CheckoutSettings",
+ },
},
{
__typename: "Channel",
@@ -258,6 +278,10 @@ export const channelsList: ChannelDetailsFragment[] = [
__typename: "PaymentSettings",
defaultTransactionFlowStrategy: TransactionFlowStrategyEnum.CHARGE,
},
+ checkoutSettings: {
+ automaticallyCompleteFullyPaidCheckouts: true,
+ __typename: "CheckoutSettings",
+ },
},
{
__typename: "Channel",
@@ -298,6 +322,10 @@ export const channelsList: ChannelDetailsFragment[] = [
__typename: "PaymentSettings",
defaultTransactionFlowStrategy: TransactionFlowStrategyEnum.CHARGE,
},
+ checkoutSettings: {
+ automaticallyCompleteFullyPaidCheckouts: true,
+ __typename: "CheckoutSettings",
+ },
},
];
@@ -340,6 +368,10 @@ export const channel: ChannelDetailsFragment = {
__typename: "PaymentSettings",
defaultTransactionFlowStrategy: TransactionFlowStrategyEnum.CHARGE,
},
+ checkoutSettings: {
+ automaticallyCompleteFullyPaidCheckouts: true,
+ __typename: "CheckoutSettings",
+ },
};
type ProductChannelsWithPricing = NonNullable[0] & {
diff --git a/src/channels/index.tsx b/src/channels/index.tsx
index d6f1bf6edee..8101ae90bf6 100644
--- a/src/channels/index.tsx
+++ b/src/channels/index.tsx
@@ -1,9 +1,10 @@
+import { Route } from "@dashboard/components/Router";
import { sectionNames } from "@dashboard/intl";
import { asSortParams } from "@dashboard/utils/sort";
import { parse as parseQs } from "qs";
import React from "react";
import { useIntl } from "react-intl";
-import { Route, RouteComponentProps, Switch } from "react-router-dom";
+import { RouteComponentProps, Switch } from "react-router-dom";
import { WindowTitle } from "../components/WindowTitle";
import {
diff --git a/src/channels/pages/ChannelDetailsPage/ChannelDetailsPage.tsx b/src/channels/pages/ChannelDetailsPage/ChannelDetailsPage.tsx
index 6b6cf3caaca..94970a57c78 100644
--- a/src/channels/pages/ChannelDetailsPage/ChannelDetailsPage.tsx
+++ b/src/channels/pages/ChannelDetailsPage/ChannelDetailsPage.tsx
@@ -11,7 +11,6 @@ import Form from "@dashboard/components/Form";
import { DetailPageLayout } from "@dashboard/components/Layouts";
import RequirePermissions from "@dashboard/components/RequirePermissions";
import { Savebar } from "@dashboard/components/Savebar";
-import { SingleAutocompleteChoiceType } from "@dashboard/components/SingleAutocompleteSelectField";
import {
AllocationStrategyEnum,
ChannelDetailsFragment,
@@ -35,6 +34,7 @@ import useStateFromProps from "@dashboard/hooks/useStateFromProps";
import { FetchMoreProps, RelayToFlat } from "@dashboard/types";
import createSingleAutocompleteSelectHandler from "@dashboard/utils/handlers/singleAutocompleteSelectChangeHandler";
import { mapCountriesToChoices } from "@dashboard/utils/maps";
+import { Option } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import { useIntl } from "react-intl";
@@ -51,7 +51,7 @@ import { ChannelShippingZones, ChannelWarehouses } from "./types";
export interface ChannelDetailsPageProps {
channel?: ChannelDetailsFragment;
- currencyCodes?: SingleAutocompleteChoiceType[];
+ currencyCodes?: Option[];
disabled: boolean;
disabledStatus?: boolean;
errors: ChannelErrorFragment[];
@@ -102,8 +102,14 @@ const ChannelDetailsPage = function ({
channel?.defaultCountry.country || "",
);
const countryChoices = mapCountriesToChoices(countries || []);
- const { defaultCountry, stockSettings, orderSettings, paymentSettings, ...formData } =
- channel || ({} as ChannelDetailsFragment);
+ const {
+ defaultCountry,
+ stockSettings,
+ orderSettings,
+ paymentSettings,
+ checkoutSettings,
+ ...formData
+ } = channel || ({} as ChannelDetailsFragment);
const initialStockSettings: StockSettingsInput = {
allocationStrategy: AllocationStrategyEnum.PRIORITIZE_SORTING_ORDER,
...stockSettings,
@@ -125,6 +131,7 @@ const ChannelDetailsPage = function ({
deleteExpiredOrdersAfter: orderSettings?.deleteExpiredOrdersAfter,
allowUnpaidOrders: orderSettings?.allowUnpaidOrders,
defaultTransactionFlowStrategy: paymentSettings?.defaultTransactionFlowStrategy,
+ automaticallyCompleteCheckouts: checkoutSettings?.automaticallyCompleteFullyPaidCheckouts,
};
const getFilteredShippingZonesChoices = (
shippingZonesToDisplay: ChannelShippingZones,
@@ -211,6 +218,13 @@ const ChannelDetailsPage = function ({
: TransactionFlowStrategyEnum.CHARGE,
});
};
+
+ const handleAutomaticallyCompleteCheckoutsChange = () => {
+ set({
+ automaticallyCompleteCheckouts: !data.automaticallyCompleteCheckouts,
+ });
+ };
+
const allErrors = [...errors, ...validationErrors];
return (
@@ -239,6 +253,7 @@ const ChannelDetailsPage = function ({
onDefaultCountryChange={handleDefaultCountrySelect}
onMarkAsPaidStrategyChange={handleMarkAsPaidStrategyChange}
onTransactionFlowStrategyChange={handleTransactionFlowStrategyChange}
+ onAutomaticallyCompleteCheckoutsChange={handleAutomaticallyCompleteCheckoutsChange}
errors={allErrors}
/>
diff --git a/src/channels/pages/ChannelsListPage/ChannelsListPage.tsx b/src/channels/pages/ChannelsListPage/ChannelsListPage.tsx
index 371bb5f6f65..65ed642c367 100644
--- a/src/channels/pages/ChannelsListPage/ChannelsListPage.tsx
+++ b/src/channels/pages/ChannelsListPage/ChannelsListPage.tsx
@@ -3,10 +3,10 @@ import { channelAddUrl, channelUrl } from "@dashboard/channels/urls";
import { LimitsInfo } from "@dashboard/components/AppLayout/LimitsInfo";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import { Button } from "@dashboard/components/Button";
+import { DashboardCard } from "@dashboard/components/Card";
import { ListPageLayout } from "@dashboard/components/Layouts";
import LimitReachedAlert from "@dashboard/components/LimitReachedAlert";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
-import Skeleton from "@dashboard/components/Skeleton";
import { TableButtonWrapper } from "@dashboard/components/TableButtonWrapper/TableButtonWrapper";
import TableCellHeader from "@dashboard/components/TableCellHeader";
import TableRowLink from "@dashboard/components/TableRowLink";
@@ -15,8 +15,9 @@ import { ChannelDetailsFragment, RefreshLimitsQuery } from "@dashboard/graphql";
import { sectionNames } from "@dashboard/intl";
import { renderCollection, stopPropagation } from "@dashboard/misc";
import { hasLimits, isLimitReached } from "@dashboard/utils/limits";
-import { Card, TableBody, TableCell, TableHead } from "@material-ui/core";
+import { TableBody, TableCell, TableHead } from "@material-ui/core";
import { DeleteIcon, IconButton } from "@saleor/macaw-ui";
+import { Skeleton } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -80,7 +81,7 @@ export const ChannelsListPage: React.FC = ({
/>
)}
-
+
@@ -142,7 +143,7 @@ export const ChannelsListPage: React.FC = ({
)}
-
+
);
};
diff --git a/src/channels/views/ChannelCreate/ChannelCreate.tsx b/src/channels/views/ChannelCreate/ChannelCreate.tsx
index 077e0011f92..89509534f8e 100644
--- a/src/channels/views/ChannelCreate/ChannelCreate.tsx
+++ b/src/channels/views/ChannelCreate/ChannelCreate.tsx
@@ -74,6 +74,7 @@ export const ChannelCreateView = () => {
slug,
warehousesIdsToAdd,
warehousesToDisplay,
+ automaticallyCompleteCheckouts,
}: FormData) => {
const input: ChannelCreateInput = {
name,
@@ -93,6 +94,9 @@ export const ChannelCreateView = () => {
deleteExpiredOrdersAfter,
allowUnpaidOrders,
},
+ checkoutSettings: {
+ automaticallyCompleteFullyPaidCheckouts: automaticallyCompleteCheckouts,
+ },
};
return saveChannel(input, warehousesToDisplay);
diff --git a/src/channels/views/ChannelDetails/ChannelDetails.tsx b/src/channels/views/ChannelDetails/ChannelDetails.tsx
index 2c457ea787e..ef237b15746 100644
--- a/src/channels/views/ChannelDetails/ChannelDetails.tsx
+++ b/src/channels/views/ChannelDetails/ChannelDetails.tsx
@@ -104,12 +104,16 @@ export const ChannelDetails: React.FC = ({ id, params }) =>
warehousesIdsToAdd,
warehousesIdsToRemove,
warehousesToDisplay,
+ automaticallyCompleteCheckouts,
}: FormData) => {
const updateChannelMutation = updateChannel({
variables: {
id: data?.channel.id,
input: {
name,
+ checkoutSettings: {
+ automaticallyCompleteFullyPaidCheckouts: automaticallyCompleteCheckouts,
+ },
slug,
defaultCountry,
addShippingZones: shippingZonesIdsToAdd,
diff --git a/src/collections/components/CollectionDetails/CollectionDetails.tsx b/src/collections/components/CollectionDetails/CollectionDetails.tsx
index 2377950ca3a..cf9485767ed 100644
--- a/src/collections/components/CollectionDetails/CollectionDetails.tsx
+++ b/src/collections/components/CollectionDetails/CollectionDetails.tsx
@@ -1,5 +1,4 @@
-// @ts-strict-ignore
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import FormSpacer from "@dashboard/components/FormSpacer";
import RichTextEditor from "@dashboard/components/RichTextEditor";
import { RichTextEditorLoading } from "@dashboard/components/RichTextEditor/RichTextEditorLoading";
@@ -8,7 +7,7 @@ import { commonMessages } from "@dashboard/intl";
import { getFormErrors, getProductErrorMessage } from "@dashboard/utils/errors";
import { useRichTextContext } from "@dashboard/utils/richText/context";
import { OutputData } from "@editorjs/editorjs";
-import { Card, CardContent, TextField } from "@material-ui/core";
+import { Input } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
@@ -33,10 +32,14 @@ const CollectionDetails: React.FC = ({
const formErrors = getFormErrors(["name", "description"], errors);
return (
-
-
-
-
+
+
+ {intl.formatMessage(commonMessages.generalInformations)}
+
+
+
+ = ({
onChange={onChange}
error={!!formErrors.name}
helperText={getProductErrorMessage(formErrors.name, intl)}
- fullWidth
/>
{isReadyForMount ? (
@@ -69,8 +71,8 @@ const CollectionDetails: React.FC = ({
name="description"
/>
)}
-
-
+
+
);
};
diff --git a/src/collections/components/CollectionDetailsPage/CollectionDetailsPage.tsx b/src/collections/components/CollectionDetailsPage/CollectionDetailsPage.tsx
index b56067800da..99899edc695 100644
--- a/src/collections/components/CollectionDetailsPage/CollectionDetailsPage.tsx
+++ b/src/collections/components/CollectionDetailsPage/CollectionDetailsPage.tsx
@@ -1,8 +1,7 @@
// @ts-strict-ignore
import { ChannelCollectionData } from "@dashboard/channels/utils";
-import { collectionListUrl } from "@dashboard/collections/urls";
+import { collectionListPath, CollectionUrlQueryParams } from "@dashboard/collections/urls";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
-import { CardSpacer } from "@dashboard/components/CardSpacer";
import ChannelsAvailabilityCard from "@dashboard/components/ChannelsAvailabilityCard";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
import { DetailPageLayout } from "@dashboard/components/Layouts";
@@ -15,19 +14,19 @@ import {
CollectionErrorFragment,
PermissionEnum,
} from "@dashboard/graphql";
+import { useBackLinkWithState } from "@dashboard/hooks/useBackLinkWithState";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import useNavigator from "@dashboard/hooks/useNavigator";
import React from "react";
import { useIntl } from "react-intl";
-import { ChannelProps, ListActions, PageListProps } from "../../../types";
+import { ChannelProps, PageListProps } from "../../../types";
import CollectionDetails from "../CollectionDetails/CollectionDetails";
import { CollectionImage } from "../CollectionImage/CollectionImage";
import CollectionProducts from "../CollectionProducts/CollectionProducts";
import CollectionUpdateForm, { CollectionUpdateData } from "./form";
-export interface CollectionDetailsPageProps extends PageListProps, ListActions, ChannelProps {
- onAdd: () => void;
+export interface CollectionDetailsPageProps extends PageListProps, ChannelProps {
channelsCount: number;
channelsErrors: CollectionChannelListingErrorFragment[];
collection: CollectionDetailsQuery["collection"];
@@ -37,10 +36,10 @@ export interface CollectionDetailsPageProps extends PageListProps, ListActions,
onCollectionRemove: () => void;
onImageDelete: () => void;
onImageUpload: (file: File) => void;
- onProductUnassign: (id: string, event: React.MouseEvent) => void;
onSubmit: (data: CollectionUpdateData) => SubmitPromise;
onChannelsChange: (data: ChannelCollectionData[]) => void;
openChannelsModal: () => void;
+ params: CollectionUrlQueryParams;
}
const CollectionDetailsPage: React.FC = ({
@@ -62,6 +61,10 @@ const CollectionDetailsPage: React.FC = ({
const intl = useIntl();
const navigate = useNavigator();
+ const collectionListBackLink = useBackLinkWithState({
+ path: collectionListPath,
+ });
+
return (
= ({
>
{({ change, data, handlers, submit, isSaveDisabled }) => (
-
+
-
= ({
onImageUpload={onImageUpload}
onChange={change}
/>
-
-
-
= ({
- navigate(collectionListUrl())} />
+ navigate(collectionListBackLink)} />
= props => {
const { data, onImageUpload, image, onChange, onImageDelete } = props;
- const anchor = React.useRef();
+ const anchor = React.useRef(null);
const classes = useStyles(props);
const intl = useIntl();
- const handleImageUploadButtonClick = () => anchor.current.click();
+ const handleImageUploadButtonClick = () => anchor?.current?.click();
return (
-
-
+
+
+ {intl.formatMessage({
+ id: "DP6b8U",
+ defaultMessage: "Background Image (optional)",
+ description: "section header",
+ })}
+
+
<>
@@ -87,33 +86,34 @@ export const CollectionImage: React.FC = props => {
onImageUpload(event.target.files[0])}
+ onChange={event => event?.target?.files && onImageUpload(event.target.files[0])}
type="file"
ref={anchor}
accept="image/*"
/>
>
- }
- />
+
+
+
{image === undefined ? (
-
+
-
+
) : image === null ? (
onImageUpload(files[0])} />
) : (
-
+
-
+
)}
{image && (
<>
-
+
= props => {
fullWidth
multiline
/>
-
+
>
)}
-
+
);
};
diff --git a/src/collections/components/CollectionListDatagrid/CollectionListDatagrid.tsx b/src/collections/components/CollectionListDatagrid/CollectionListDatagrid.tsx
index 148d1a63cc0..3984b1e0042 100644
--- a/src/collections/components/CollectionListDatagrid/CollectionListDatagrid.tsx
+++ b/src/collections/components/CollectionListDatagrid/CollectionListDatagrid.tsx
@@ -10,6 +10,7 @@ import {
} from "@dashboard/components/Datagrid/hooks/useDatagridChange";
import { TablePaginationWithContext } from "@dashboard/components/TablePagination";
import { commonTooltipMessages } from "@dashboard/components/TooltipTableCellHeader/messages";
+import { getPrevLocationState } from "@dashboard/hooks/useBackLinkWithState";
import { ListProps, SortPage } from "@dashboard/types";
import { Item } from "@glideapps/glide-data-grid";
import { Box, useTheme } from "@saleor/macaw-ui-next";
@@ -157,6 +158,7 @@ export const CollectionListDatagrid = ({
onToggle={handlers.onToggle}
/>
)}
+ navigatorOpts={{ state: getPrevLocationState(location) }}
/>
diff --git a/src/collections/components/CollectionListPage/CollectionListPage.tsx b/src/collections/components/CollectionListPage/CollectionListPage.tsx
index fc6999429fa..c2c7f2e2d6d 100644
--- a/src/collections/components/CollectionListPage/CollectionListPage.tsx
+++ b/src/collections/components/CollectionListPage/CollectionListPage.tsx
@@ -8,16 +8,19 @@ import {
import { ListFilters } from "@dashboard/components/AppLayout/ListFilters";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import { BulkDeleteButton } from "@dashboard/components/BulkDeleteButton";
+import { DashboardCard } from "@dashboard/components/Card";
import { getByName } from "@dashboard/components/Filter/utils";
import { FilterPresetsSelect } from "@dashboard/components/FilterPresetsSelect";
import { ListPageLayout } from "@dashboard/components/Layouts";
+import { useFlag } from "@dashboard/featureFlags";
+import { getPrevLocationState } from "@dashboard/hooks/useBackLinkWithState";
import useNavigator from "@dashboard/hooks/useNavigator";
import { sectionNames } from "@dashboard/intl";
import { FilterPageProps, PageListProps, SortPage } from "@dashboard/types";
-import { Card } from "@material-ui/core";
import { Box, Button, ChevronRightIcon } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
+import { useLocation } from "react-router";
import { CollectionListDatagrid } from "../CollectionListDatagrid";
import { CollectionFilterKeys, CollectionListFilterOpts, createFilterStructure } from "./filters";
@@ -59,9 +62,11 @@ const CollectionListPage: React.FC = ({
...listProps
}) => {
const intl = useIntl();
+ const location = useLocation();
const navigate = useNavigator();
const filterStructure = createFilterStructure(intl, filterOpts);
const [isFilterPresetOpen, setFilterPresetOpen] = useState(false);
+ const { enabled: isNewCollectionListEnabled } = useFlag("new_filters");
const filterDependency = filterStructure.find(getByName("channel"));
return (
@@ -112,41 +117,63 @@ const CollectionListPage: React.FC = ({
-
-
- {selectedCollectionIds.length > 0 && (
-
-
-
- )}
-
- }
- />
+
+ {isNewCollectionListEnabled ? (
+
+ {selectedCollectionIds.length > 0 && (
+
+
+
+ )}
+
+ }
+ />
+ ) : (
+
+ {selectedCollectionIds.length > 0 && (
+
+
+
+ )}
+
+ }
+ onFilterChange={onFilterChange}
+ onFilterAttributeFocus={onFilterAttributeFocus}
+ filterStructure={filterStructure}
+ />
+ )}
{
- navigate(collectionUrl(id));
+ navigate(collectionUrl(id), {
+ state: getPrevLocationState(location),
+ });
}}
hasRowHover={!isFilterPresetOpen}
rowAnchor={collectionUrl}
{...listProps}
/>
-
+
);
};
diff --git a/src/collections/components/CollectionListPage/filters.ts b/src/collections/components/CollectionListPage/filters.ts
index e67eeaa74f9..5305f561ff0 100644
--- a/src/collections/components/CollectionListPage/filters.ts
+++ b/src/collections/components/CollectionListPage/filters.ts
@@ -1,14 +1,14 @@
import { IFilter } from "@dashboard/components/Filter";
-import { MultiAutocompleteChoiceType } from "@dashboard/components/MultiAutocompleteSelectField";
import { CollectionPublished } from "@dashboard/graphql";
import { commonMessages } from "@dashboard/intl";
import { FilterOpts } from "@dashboard/types";
import { createOptionsField } from "@dashboard/utils/filters/fields";
+import { Option } from "@saleor/macaw-ui-next";
import { defineMessages, IntlShape } from "react-intl";
export interface CollectionListFilterOpts {
status: FilterOpts;
- channel: FilterOpts & { choices: MultiAutocompleteChoiceType[] };
+ channel: FilterOpts & { choices: Option[] };
}
export enum CollectionFilterKeys {
diff --git a/src/collections/components/CollectionProducts/CollectionProducts.tsx b/src/collections/components/CollectionProducts/CollectionProducts.tsx
index 2a0185a08b1..12a716dcbff 100644
--- a/src/collections/components/CollectionProducts/CollectionProducts.tsx
+++ b/src/collections/components/CollectionProducts/CollectionProducts.tsx
@@ -1,202 +1,260 @@
-// @ts-strict-ignore
-import { Button } from "@dashboard/components/Button";
-import CardTitle from "@dashboard/components/CardTitle";
-import { ChannelsAvailabilityDropdown } from "@dashboard/components/ChannelsAvailabilityDropdown";
-import Checkbox from "@dashboard/components/Checkbox";
-import ResponsiveTable from "@dashboard/components/ResponsiveTable";
-import Skeleton from "@dashboard/components/Skeleton";
-import { TableButtonWrapper } from "@dashboard/components/TableButtonWrapper/TableButtonWrapper";
-import TableCellAvatar from "@dashboard/components/TableCellAvatar";
-import { AVATAR_MARGIN } from "@dashboard/components/TableCellAvatar/Avatar";
-import TableHead from "@dashboard/components/TableHead";
-import { TablePaginationWithContext } from "@dashboard/components/TablePagination";
-import TableRowLink from "@dashboard/components/TableRowLink";
-import { CollectionDetailsQuery } from "@dashboard/graphql";
-import { productUrl } from "@dashboard/products/urls";
+import { ChannelCollectionData } from "@dashboard/channels/utils";
+import {
+ collectionUrl,
+ CollectionUrlDialog,
+ CollectionUrlQueryParams,
+} from "@dashboard/collections/urls";
+import {
+ getAssignedProductIdsToCollection,
+ getProductsFromSearchResults,
+} from "@dashboard/collections/utils";
+import ActionDialog from "@dashboard/components/ActionDialog/ActionDialog";
+import { Container } from "@dashboard/components/AssignContainerDialog";
+import AssignProductDialog from "@dashboard/components/AssignProductDialog/AssignProductDialog";
+import { DashboardCard } from "@dashboard/components/Card";
+import { DEFAULT_INITIAL_SEARCH_DATA, PAGINATE_BY } from "@dashboard/config";
+import {
+ CollectionDetailsQuery,
+ useCollectionAssignProductMutation,
+ useCollectionProductsQuery,
+ useUnassignCollectionProductMutation,
+} from "@dashboard/graphql";
+import useBulkActions from "@dashboard/hooks/useBulkActions";
+import useListSettings from "@dashboard/hooks/useListSettings";
+import useLocalPaginator, { useLocalPaginationState } from "@dashboard/hooks/useLocalPaginator";
+import useNavigator from "@dashboard/hooks/useNavigator";
+import useNotifier from "@dashboard/hooks/useNotifier";
+import { PaginatorContext } from "@dashboard/hooks/usePaginator";
+import useProductSearch from "@dashboard/searches/useProductSearch";
+import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHandlers";
import { mapEdgesToItems } from "@dashboard/utils/maps";
-import { Card, TableBody, TableCell, TableFooter } from "@material-ui/core";
-import { DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui";
+import { Button, Skeleton } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
-import { maybe, renderCollection } from "../../../misc";
-import { ListActions, PageListProps } from "../../../types";
+import { ListViews } from "../../../types";
+import { Pagination } from "./Pagination";
+import { ProductsTable } from "./ProductsTable";
+import { ProductTableSkeleton } from "./ProductTableSkeleton";
+import { useCollectionId } from "./useCollectionId";
-const useStyles = makeStyles(
- theme => ({
- colActions: {
- width: `calc(76px + ${theme.spacing(1)})`,
- marginRight: theme.spacing(-2),
- },
- colName: {
- paddingLeft: 0,
- width: "auto",
- },
- colNameLabel: {
- marginLeft: AVATAR_MARGIN,
- },
- colPublished: {
- width: 200,
- },
- colType: {
- width: 200,
- },
- table: {
- tableLayout: "fixed",
- },
- tableRow: {
- cursor: "pointer",
- },
- }),
- { name: "CollectionProducts" },
-);
-
-export interface CollectionProductsProps extends PageListProps, ListActions {
+export interface CollectionProductsProps {
collection: CollectionDetailsQuery["collection"];
- onProductUnassign: (id: string, event: React.MouseEvent) => void;
- onAdd: () => void;
+ params: CollectionUrlQueryParams;
+ currentChannels: ChannelCollectionData[];
+ disabled: boolean;
}
-const CollectionProducts: React.FC = props => {
- const {
- collection,
- disabled,
- onAdd,
- onProductUnassign,
- isChecked,
- selected,
- toggle,
- toggleAll,
- toolbar,
- } = props;
- const classes = useStyles(props);
+const CollectionProducts: React.FC = ({
+ collection,
+ params,
+ currentChannels,
+ disabled,
+}) => {
+ const navigate = useNavigator();
+ const [openModal, closeModal] = createDialogActionHandlers<
+ CollectionUrlDialog,
+ CollectionUrlQueryParams
+ >(navigate, params => collectionUrl(id, params), params);
+ const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions(params.ids);
+
const intl = useIntl();
- const products = mapEdgesToItems(collection?.products);
+ const id = useCollectionId();
+ const { settings, updateListSettings } = useListSettings(ListViews.COLLECTION_PRODUCTS_LIST);
+ const numberOfRows = settings ? settings.rowNumber : PAGINATE_BY;
+ const [paginationState, setPaginationState] = useLocalPaginationState(numberOfRows);
+ const notify = useNotifier();
+
+ const [assignProduct, assignProductOpts] = useCollectionAssignProductMutation({
+ onCompleted: data => {
+ if (data.collectionAddProducts?.errors.length === 0) {
+ notify({
+ status: "success",
+ text: intl.formatMessage({
+ id: "56vUeQ",
+ defaultMessage: "Added product to collection",
+ }),
+ });
+ }
+ },
+ });
+ const [unassignProduct, unassignProductOpts] = useUnassignCollectionProductMutation({
+ onCompleted: data => {
+ if (data.collectionRemoveProducts?.errors.length === 0) {
+ notify({
+ status: "success",
+ text: intl.formatMessage({
+ id: "WW+Ruy",
+ defaultMessage: "Deleted product from collection",
+ }),
+ });
+ reset();
+ closeModal();
+ }
+ },
+ });
+
+ const { data } = useCollectionProductsQuery({
+ displayLoader: true,
+ variables: { id, ...paginationState },
+ });
+
+ const products = mapEdgesToItems(data?.collection?.products);
const numberOfColumns = products?.length === 0 ? 4 : 5;
+ const paginate = useLocalPaginator(setPaginationState);
+
+ const { pageInfo, ...paginationValues } = paginate(
+ data?.collection?.products?.pageInfo,
+ paginationState,
+ );
+
+ const { search, loadMore, result } = useProductSearch({
+ variables: DEFAULT_INITIAL_SEARCH_DATA,
+ });
+
+ const assignedProductDict = getAssignedProductIdsToCollection(collection, result.data?.search);
+
+ const handleProductUnassign = async (productId: string) => {
+ await unassignProduct({
+ variables: {
+ collectionId: id,
+ productIds: [productId],
+ ...paginationState,
+ },
+ });
+ await result.refetch(DEFAULT_INITIAL_SEARCH_DATA);
+ };
+
+ const handleAssignationChange = async (products: Container[]) => {
+ const productIds = products.map(product => product.id);
+ const toUnassignIds = Object.keys(assignedProductDict).filter(
+ s => assignedProductDict[s] && !productIds.includes(s),
+ );
+ const baseVariables = { ...paginationState, collectionId: id };
+
+ if (productIds.length > 0) {
+ await assignProduct({
+ variables: {
+ ...baseVariables,
+ productIds,
+ moves: productIds.map(id => ({ productId: id, sortOrder: 0 })),
+ },
+ });
+ }
+
+ if (toUnassignIds.length > 0) {
+ await unassignProduct({
+ variables: { ...baseVariables, productIds: toUnassignIds },
+ });
+ }
+
+ closeModal();
+
+ await result.refetch(DEFAULT_INITIAL_SEARCH_DATA);
+ };
return (
-
- collection.name, "..."),
- },
- )
- ) : (
-
- )
- }
- toolbar={
-
-
-
- }
+
+
+
+
+ {collection ? (
+ intl.formatMessage(
+ {
+ id: "/dnWE8",
+ defaultMessage: "Products in {name}",
+ description: "products in collection",
+ },
+ {
+ name: collection?.name ?? "...",
+ },
+ )
+ ) : (
+
+ )}
+
+
+ openModal("assign")}
+ >
+
+
+
+
+
+ {products ? (
+
+ openModal("unassign", {
+ ids: listElements,
+ })
+ }
+ updateListSettings={updateListSettings}
+ numberOfRows={numberOfRows}
+ />
+ ) : (
+
+ )}
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {renderCollection(
- products,
- product => {
- const isSelected = product ? isChecked(product.id) : false;
-
- return (
-
-
- toggle(product.id)}
- />
-
- product.thumbnail.url)}
- >
- {maybe(() => product.name, )}
-
-
- {maybe(() => product.productType.name, )}
-
-
- {product && !product?.channelListings?.length ? (
- "-"
- ) : product?.channelListings !== undefined ? (
-
- ) : (
-
- )}
-
-
-
- onProductUnassign(product.id, event)}
- >
-
-
-
-
-
- );
+
+ unassignProduct({
+ variables: {
+ ...paginationState,
+ collectionId: id,
+ productIds: params.ids ?? [],
},
- () => (
-
-
-
-
-
- ),
- )}
-
-
-
+ })
+ }
+ open={params.action === "unassign"}
+ title={intl.formatMessage({
+ id: "5OtU+V",
+ defaultMessage: "Unassign products from collection",
+ description: "dialog title",
+ })}
+ >
+ {params.ids?.length ?? 0},
+ }}
+ />
+
+
);
};
diff --git a/src/collections/components/CollectionProducts/EmptyImage.tsx b/src/collections/components/CollectionProducts/EmptyImage.tsx
new file mode 100644
index 00000000000..a4789456340
--- /dev/null
+++ b/src/collections/components/CollectionProducts/EmptyImage.tsx
@@ -0,0 +1,11 @@
+import { Box, useTheme } from "@saleor/macaw-ui-next";
+import React from "react";
+
+export const EmptyImage = () => {
+ const { theme } = useTheme();
+
+ // Using these colors to match other grid-based lists
+ const bgColor = theme === "defaultLight" ? "hsla(210, 15%, 87%, 1)" : "hsla(210, 32%, 25%, 1)";
+
+ return ;
+};
diff --git a/src/collections/components/CollectionProducts/Pagination.tsx b/src/collections/components/CollectionProducts/Pagination.tsx
new file mode 100644
index 00000000000..3ce72c45074
--- /dev/null
+++ b/src/collections/components/CollectionProducts/Pagination.tsx
@@ -0,0 +1,71 @@
+import { usePaginatorContext } from "@dashboard/hooks/usePaginator";
+import {
+ Box,
+ Button,
+ ChevronLeftIcon,
+ ChevronRightIcon,
+ Select,
+ Text,
+} from "@saleor/macaw-ui-next";
+import React from "react";
+import { FormattedMessage } from "react-intl";
+
+const ROW_NUMBER_OPTIONS = [
+ { label: "10", value: "10" },
+ { label: "20", value: "20" },
+ { label: "50", value: "50" },
+ { label: "100", value: "100" },
+];
+
+interface PaginationProps {
+ onUpdateListSettings: (key: "rowNumber", value: number) => void;
+ numberOfRows: number;
+}
+
+export const Pagination = ({ onUpdateListSettings, numberOfRows }: PaginationProps) => {
+ const { hasNextPage, hasPreviousPage, loadNextPage, loadPreviousPage } = usePaginatorContext();
+ const currentRowNumber = String(numberOfRows);
+ const currentRowNumberOption = ROW_NUMBER_OPTIONS.find(
+ option => option.value === currentRowNumber,
+ );
+
+ const handleRowNumberChange = ({ value }: { value: string; label: string }) => {
+ onUpdateListSettings("rowNumber", parseInt(value));
+ };
+
+ return (
+
+
+
+
+
+
+
+
+ }
+ />
+ }
+ />
+
+
+ );
+};
diff --git a/src/collections/components/CollectionProducts/ProductTableItem.tsx b/src/collections/components/CollectionProducts/ProductTableItem.tsx
new file mode 100644
index 00000000000..a7630658ea9
--- /dev/null
+++ b/src/collections/components/CollectionProducts/ProductTableItem.tsx
@@ -0,0 +1,129 @@
+import { ChannelsAvailabilityDropdown } from "@dashboard/components/ChannelsAvailabilityDropdown";
+import { GridTable } from "@dashboard/components/GridTable";
+import Link from "@dashboard/components/Link";
+import Drag from "@dashboard/icons/Drag";
+import { productUrl } from "@dashboard/products/urls";
+import { useSortable } from "@dnd-kit/sortable";
+import { CSS } from "@dnd-kit/utilities";
+import { Box, Button, Checkbox, Skeleton, Text, TrashBinIcon } from "@saleor/macaw-ui-next";
+import React from "react";
+
+import { EmptyImage } from "./EmptyImage";
+import { Product } from "./types";
+
+interface ItemProps {
+ product: Product;
+ isSelected: boolean;
+ draggable: boolean;
+ toggle: (id: string) => void;
+ onProductUnassign: (id: string, event: React.MouseEvent) => void;
+}
+
+export const ProductTableItem = ({
+ product,
+ isSelected,
+ draggable,
+ toggle,
+ onProductUnassign,
+}: ItemProps) => {
+ const { attributes, listeners, setNodeRef, transform, transition, isSorting } = useSortable({
+ id: product.id,
+ disabled: !draggable,
+ });
+ const style = {
+ transform: CSS.Transform.toString(transform),
+ transition,
+ };
+ const href = product ? productUrl(product.id) : "";
+ const isSaving = product.id.includes("moved_");
+
+ return (
+
+
+
+
+
+
+
+
+ product && toggle(product.id)} />
+
+
+
+
+
+ {product?.thumbnail ? (
+
+
+
+ ) : (
+
+ )}
+ {product?.name}
+
+
+
+
+
+
+ {product?.productType.name || }
+
+
+
+
+
+ {product && !product?.channelListings?.length ? (
+ "-"
+ ) : product?.channelListings !== undefined ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ product && onProductUnassign(product.id, event)}
+ icon={ }
+ />
+
+
+
+ );
+};
diff --git a/src/collections/components/CollectionProducts/ProductTableSkeleton.tsx b/src/collections/components/CollectionProducts/ProductTableSkeleton.tsx
new file mode 100644
index 00000000000..395d60095e3
--- /dev/null
+++ b/src/collections/components/CollectionProducts/ProductTableSkeleton.tsx
@@ -0,0 +1,66 @@
+import { GridTable } from "@dashboard/components/GridTable";
+import Drag from "@dashboard/icons/Drag";
+import { Box, Skeleton } from "@saleor/macaw-ui-next";
+import React from "react";
+
+export const ProductTableItemSkeleton = () => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+);
+
+export const ProductTableSkeleton = () => (
+
+
+
+
+
+
+
+
+
+
+ {Array.from({ length: 10 }, (_, index) => (
+
+ ))}
+
+
+);
diff --git a/src/collections/components/CollectionProducts/ProductsTable.tsx b/src/collections/components/CollectionProducts/ProductsTable.tsx
new file mode 100644
index 00000000000..ff46c1789fa
--- /dev/null
+++ b/src/collections/components/CollectionProducts/ProductsTable.tsx
@@ -0,0 +1,169 @@
+import { GridTable } from "@dashboard/components/GridTable";
+import { PaginationState } from "@dashboard/hooks/useLocalPaginator";
+import { renderCollection } from "@dashboard/misc";
+import { Node } from "@dashboard/types";
+import { closestCenter, DndContext } from "@dnd-kit/core";
+import { SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
+import { Box, Button, Checkbox, Text } from "@saleor/macaw-ui-next";
+import React from "react";
+import { FormattedMessage } from "react-intl";
+
+import { ProductTableItem } from "./ProductTableItem";
+import { Product } from "./types";
+import { useProductDrag } from "./useProductDrag";
+
+interface ProductsTableProps {
+ products: Product[];
+ isChecked: (id: string) => boolean | undefined;
+ toggle: (id: string) => void;
+ toggleAll: (items: Node[], selected: number) => void;
+ disabled: boolean;
+ onProductUnassign: (id: string, event: React.MouseEvent) => void;
+ numberOfColumns: number;
+ selected: number;
+ onUnassignClick: () => void;
+ paginationState: PaginationState;
+ updateListSettings: (key: "rowNumber", value: number) => void;
+ numberOfRows: number;
+}
+
+const areAllChecked = (products: Product[], selected: number) => {
+ if (products && products.length > selected && selected > 0) {
+ return "indeterminate";
+ }
+
+ return selected !== 0;
+};
+
+export const ProductsTable = ({
+ products,
+ isChecked,
+ toggle,
+ toggleAll,
+ disabled,
+ onProductUnassign,
+ selected,
+ onUnassignClick,
+ paginationState,
+}: ProductsTableProps) => {
+ const allChecked = areAllChecked(products, selected);
+ const { items, sensors, isSaving, handleDragEnd } = useProductDrag({ products, paginationState });
+
+ if (items.length === 0) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ toggleAll(products, selected)}
+ />
+
+
+
+ {selected ? (
+
+
+
+ ) : (
+
+
+
+ )}
+
+
+ {!selected && (
+
+
+
+ )}
+
+
+ {!selected && (
+
+
+
+ )}
+
+ {!!selected && (
+
+
+
+ )}
+
+
+
+
+ {renderCollection(items, product => {
+ if (!product) {
+ return null;
+ }
+
+ const isSelected = isChecked(product.id);
+
+ return (
+
+ );
+ })}
+
+
+
+
+ );
+};
diff --git a/src/collections/components/CollectionProducts/keepProductOrder.ts b/src/collections/components/CollectionProducts/keepProductOrder.ts
new file mode 100644
index 00000000000..5c671f69dce
--- /dev/null
+++ b/src/collections/components/CollectionProducts/keepProductOrder.ts
@@ -0,0 +1,35 @@
+import { CollectionProductsQuery } from "@dashboard/graphql";
+
+export type CollectionProducts = NonNullable<
+ NonNullable["products"]
+>;
+
+/*
+ The API needs to take items in the same order as they came, and the reversed one when we move items down (negative position).
+ This function is designed to keep that order.
+
+ Example:
+ list from the API: [1, 2, 3, 4, 5, 6]
+ we change (in order):
+ 5 to position 4
+ 2 to position 0
+
+ [1, 2, 3, 4, 5, 6]
+
+ The array we get for update is: [{ id: 5, sortOrder: 1 }, { id: 2, sortOrder: 1 }]
+ But instead we should send: [{ id: 2, sortOrder: 1 }, { id: 5, sortOrder: 1 }]
+ 2 is first because it came like this from the API
+*/
+export const keepProductOrder =
+ (listElements: string[], products: CollectionProducts) => (position: number) => {
+ const orderedProducts = products.edges
+ .map(edge => edge.node.id)
+ .map(nodeId => listElements.find(id => nodeId == id) || "")
+ .filter(Boolean);
+
+ if (position < 0) {
+ return orderedProducts.reverse();
+ }
+
+ return orderedProducts;
+ };
diff --git a/src/collections/components/CollectionProducts/types.ts b/src/collections/components/CollectionProducts/types.ts
new file mode 100644
index 00000000000..1866acbde8a
--- /dev/null
+++ b/src/collections/components/CollectionProducts/types.ts
@@ -0,0 +1,7 @@
+import { CollectionProductsQuery } from "@dashboard/graphql";
+
+export type Edges = NonNullable<
+ NonNullable["products"]>["edges"]
+>;
+
+export type Product = Edges[number]["node"];
diff --git a/src/collections/components/CollectionProducts/useCollectionId.ts b/src/collections/components/CollectionProducts/useCollectionId.ts
new file mode 100644
index 00000000000..61d36e62cbb
--- /dev/null
+++ b/src/collections/components/CollectionProducts/useCollectionId.ts
@@ -0,0 +1,11 @@
+import useRouter from "use-react-router";
+
+export const useCollectionId = () => {
+ const {
+ match: {
+ params: { id: collectionId },
+ },
+ } = useRouter<{ id: string }>();
+
+ return decodeURIComponent(collectionId);
+};
diff --git a/src/collections/components/CollectionProducts/useProductDrag.test.ts b/src/collections/components/CollectionProducts/useProductDrag.test.ts
new file mode 100644
index 00000000000..9d90127d719
--- /dev/null
+++ b/src/collections/components/CollectionProducts/useProductDrag.test.ts
@@ -0,0 +1,58 @@
+import type { DragEndEvent } from "@dnd-kit/core";
+import { act, renderHook } from "@testing-library/react-hooks";
+
+import { Product } from "./types";
+import { useProductDrag } from "./useProductDrag";
+import { useProductReorder } from "./useProductReorder";
+
+jest.mock("@dnd-kit/core");
+jest.mock("./useProductReorder");
+
+describe("CollectionProducts/useProductDrag", () => {
+ const initialProducts = [
+ { id: "1", name: "Product 1" },
+ { id: "2", name: "Product 2" },
+ { id: "3", name: "Product 3" },
+ ] as Product[];
+
+ it("should reorder items on drag end", () => {
+ // Arrange
+ const move = jest.fn();
+
+ (useProductReorder as jest.Mock).mockReturnValue({
+ move,
+ data: { loading: false },
+ });
+
+ const { result } = renderHook(() =>
+ useProductDrag({ products: initialProducts, paginationState: { first: 10, after: "1" } }),
+ );
+
+ const dragEndEvent = {
+ active: { id: "1" },
+ over: { id: "2" },
+ } as DragEndEvent;
+
+ // Act
+ act(() => {
+ result.current.handleDragEnd(dragEndEvent);
+ });
+
+ // Assert
+ expect(result.current.items).toEqual([
+ { id: "2", name: "Product 2" },
+ { id: "1", name: "Product 1" },
+ { id: "3", name: "Product 3" },
+ ]);
+
+ expect(move).toHaveBeenCalledWith(
+ [
+ { id: "2", name: "Product 2" },
+ { id: "1", name: "Product 1" },
+ { id: "3", name: "Product 3" },
+ ],
+ "1",
+ -1,
+ );
+ });
+});
diff --git a/src/collections/components/CollectionProducts/useProductDrag.ts b/src/collections/components/CollectionProducts/useProductDrag.ts
new file mode 100644
index 00000000000..ac8c1e1310d
--- /dev/null
+++ b/src/collections/components/CollectionProducts/useProductDrag.ts
@@ -0,0 +1,53 @@
+import { PaginationState } from "@dashboard/hooks/useLocalPaginator";
+import { DragEndEvent, KeyboardSensor, PointerSensor, useSensor, useSensors } from "@dnd-kit/core";
+import { arrayMove, sortableKeyboardCoordinates } from "@dnd-kit/sortable";
+import { useEffect, useState } from "react";
+
+import { Product } from "./types";
+import { useProductReorder } from "./useProductReorder";
+
+interface ProductDragProps {
+ products: Product[];
+ paginationState: PaginationState;
+}
+
+export const useProductDrag = ({ products, paginationState }: ProductDragProps) => {
+ const [items, setItems] = useState(products);
+ const { move, data } = useProductReorder({ paginationState });
+
+ const sensors = useSensors(
+ useSensor(PointerSensor),
+ useSensor(KeyboardSensor, {
+ coordinateGetter: sortableKeyboardCoordinates,
+ }),
+ );
+
+ useEffect(() => {
+ setItems(products);
+ }, [products]);
+
+ const handleDragEnd = (event: DragEndEvent) => {
+ const { active, over } = event;
+
+ if (active.id !== over?.id) {
+ setItems(items => {
+ const oldIndex = items.findIndex(item => item.id === active.id);
+ const newIndex = items.findIndex(item => item.id === over?.id);
+ const diff = oldIndex - newIndex;
+ const moved = arrayMove(items, oldIndex, newIndex);
+ const productId = active.id as string;
+
+ move(moved, productId, diff);
+
+ return moved;
+ });
+ }
+ };
+
+ return {
+ isSaving: data?.loading,
+ sensors,
+ items,
+ handleDragEnd,
+ };
+};
diff --git a/src/collections/components/CollectionProducts/useProductEdges.test.ts b/src/collections/components/CollectionProducts/useProductEdges.test.ts
new file mode 100644
index 00000000000..ce1bbeb5f0b
--- /dev/null
+++ b/src/collections/components/CollectionProducts/useProductEdges.test.ts
@@ -0,0 +1,116 @@
+import { useApolloClient } from "@apollo/client";
+import { PaginationState } from "@dashboard/hooks/usePaginator";
+import { renderHook } from "@testing-library/react-hooks";
+
+import { useCollectionId } from "./useCollectionId";
+import { useProductEdges } from "./useProductEdges";
+
+jest.mock("@apollo/client");
+jest.mock("@dashboard/graphql", () => ({
+ CollectionProductsDocument: "CollectionProductsDocument",
+}));
+jest.mock("./useCollectionId");
+
+describe("CollectionProducts/useProductEdges", () => {
+ const mockCollectionId = "collection-123";
+ const mockPaginationState = {
+ first: 10,
+ after: null,
+ } as unknown as PaginationState;
+
+ const mockProductEdges = [
+ { node: { id: "1", name: "Product 1" } },
+ { node: { id: "2", name: "Product 2" } },
+ ];
+
+ const mockQueryResponse = {
+ collection: {
+ products: {
+ edges: mockProductEdges,
+ },
+ },
+ };
+
+ const mockReadQuery = jest.fn();
+ const mockApolloClient = {
+ readQuery: mockReadQuery,
+ };
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ (useApolloClient as jest.Mock).mockReturnValue(mockApolloClient);
+ (useCollectionId as jest.Mock).mockReturnValue(mockCollectionId);
+ mockReadQuery.mockReturnValue(mockQueryResponse);
+ });
+
+ it("should return product edges when query cache exists", () => {
+ // Arrange & Act
+ const { result } = renderHook(() => useProductEdges({ paginationState: mockPaginationState }));
+
+ // Assert
+ expect(mockReadQuery).toHaveBeenCalledWith({
+ query: "CollectionProductsDocument",
+ variables: {
+ id: mockCollectionId,
+ ...mockPaginationState,
+ },
+ });
+
+ expect(result.current.edges).toEqual(mockProductEdges);
+ });
+
+ it("should return empty array when query cache is empty", () => {
+ // Arrange
+ mockReadQuery.mockReturnValue(null);
+
+ // Act
+ const { result } = renderHook(() => useProductEdges({ paginationState: mockPaginationState }));
+
+ // Assert
+ expect(result.current.edges).toEqual([]);
+ });
+
+ it("should return empty array when collection is empty", () => {
+ // Arrange
+ mockReadQuery.mockReturnValue({ collection: null });
+
+ // Act
+ const { result } = renderHook(() => useProductEdges({ paginationState: mockPaginationState }));
+
+ // Assert
+ expect(result.current.edges).toEqual([]);
+ });
+
+ it("should return empty array when there are no products", () => {
+ // Arrange
+ mockReadQuery.mockReturnValue({
+ collection: { products: null },
+ });
+
+ // Act
+ const { result } = renderHook(() => useProductEdges({ paginationState: mockPaginationState }));
+
+ // Assert
+ expect(result.current.edges).toEqual([]);
+ });
+
+ it("should pass pagination state to query", () => {
+ // Arrange
+ const customPaginationState = {
+ first: 20,
+ after: "cursor-123",
+ };
+
+ // Act
+ renderHook(() => useProductEdges({ paginationState: customPaginationState }));
+
+ // Assert
+ expect(mockReadQuery).toHaveBeenCalledWith({
+ query: expect.anything(),
+ variables: {
+ id: mockCollectionId,
+ ...customPaginationState,
+ },
+ });
+ });
+});
diff --git a/src/collections/components/CollectionProducts/useProductEdges.ts b/src/collections/components/CollectionProducts/useProductEdges.ts
new file mode 100644
index 00000000000..440e4569c95
--- /dev/null
+++ b/src/collections/components/CollectionProducts/useProductEdges.ts
@@ -0,0 +1,26 @@
+import { useApolloClient } from "@apollo/client";
+import { CollectionProductsDocument, CollectionProductsQuery } from "@dashboard/graphql";
+import { PaginationState } from "@dashboard/hooks/useLocalPaginator";
+
+import { useCollectionId } from "./useCollectionId";
+
+interface ProductEdgesProps {
+ paginationState: PaginationState;
+}
+
+export const useProductEdges = ({ paginationState }: ProductEdgesProps) => {
+ const client = useApolloClient();
+ const collectionId = useCollectionId();
+
+ const queryData = client.readQuery({
+ query: CollectionProductsDocument,
+ variables: {
+ id: collectionId,
+ ...paginationState,
+ },
+ });
+
+ const edges = queryData?.collection?.products?.edges || [];
+
+ return { edges };
+};
diff --git a/src/collections/components/CollectionProducts/useProductReorder.test.ts b/src/collections/components/CollectionProducts/useProductReorder.test.ts
new file mode 100644
index 00000000000..8d1ea9cc163
--- /dev/null
+++ b/src/collections/components/CollectionProducts/useProductReorder.test.ts
@@ -0,0 +1,97 @@
+import { useReorderProductsInCollectionMutation } from "@dashboard/graphql";
+import { useLocalPaginationState } from "@dashboard/hooks/useLocalPaginator";
+import useNotifier from "@dashboard/hooks/useNotifier";
+import { act, renderHook } from "@testing-library/react-hooks";
+
+import { Product } from "./types";
+import { useProductReorder } from "./useProductReorder";
+import { useProductReorderOptimistic } from "./useProductReorderOptimistic";
+
+jest.mock("react-intl", () => ({
+ useIntl: jest.fn(() => ({
+ formatMessage: jest.fn(x => x.defaultMessage),
+ })),
+ defineMessages: (x: unknown) => x,
+}));
+
+jest.mock("@dashboard/graphql", () => ({
+ useReorderProductsInCollectionMutation: jest.fn(),
+}));
+
+jest.mock("@dashboard/hooks/useLocalPaginator", () => ({
+ useLocalPaginationState: jest.fn(),
+}));
+
+jest.mock("./useProductReorderOptimistic", () => ({
+ useProductReorderOptimistic: jest.fn(),
+}));
+
+jest.mock("./useCollectionId", () => ({
+ useCollectionId: jest.fn(() => "collection-id-1"),
+}));
+
+jest.mock("@dashboard/hooks/useNotifier", () => jest.fn());
+
+describe("CollectionProducts/useProductReorder", () => {
+ const mockReorder = jest.fn();
+ const mockNotifier = jest.fn();
+ const createForDroppedItem = jest.fn(() => "optimistic-response");
+ const mockPaginationState = { page: 1, pageSize: 10 };
+
+ beforeEach(() => {
+ (useReorderProductsInCollectionMutation as jest.Mock).mockReturnValue([mockReorder, {}]);
+ (useLocalPaginationState as jest.Mock).mockReturnValue([mockPaginationState]);
+ (useProductReorderOptimistic as jest.Mock).mockReturnValue({
+ createForDroppedItem: createForDroppedItem,
+ });
+ (useNotifier as jest.Mock).mockReturnValue(mockNotifier);
+ });
+
+ afterEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it("should call reorder with correct variables when move is called", () => {
+ // Arrange
+ const { result } = renderHook(() =>
+ useProductReorder({ paginationState: { first: 10, after: "1" } }),
+ );
+ const productIds = [
+ { id: "1", name: "Product 1" },
+ { id: "2", name: "Product 2" },
+ { id: "3", name: "Product 3" },
+ ] as Product[];
+ const shift = 1;
+
+ // Act
+ act(() => {
+ result.current.move(productIds, "2", shift);
+ });
+
+ // Assert
+ expect(mockReorder).toHaveBeenCalledWith({
+ variables: {
+ after: "1",
+ collectionId: "collection-id-1",
+ first: 10,
+ moves: [
+ {
+ productId: "2",
+ sortOrder: -1,
+ },
+ ],
+ },
+ optimisticResponse: "optimistic-response",
+ });
+ });
+
+ it("should return data from the mutation", () => {
+ // Arrange & Act
+ const { result } = renderHook(() =>
+ useProductReorder({ paginationState: { first: 10, after: "1" } }),
+ );
+
+ // Assert
+ expect(result.current.data).toEqual({});
+ });
+});
diff --git a/src/collections/components/CollectionProducts/useProductReorder.ts b/src/collections/components/CollectionProducts/useProductReorder.ts
new file mode 100644
index 00000000000..133c2f80c5d
--- /dev/null
+++ b/src/collections/components/CollectionProducts/useProductReorder.ts
@@ -0,0 +1,50 @@
+import { useReorderProductsInCollectionMutation } from "@dashboard/graphql";
+import { PaginationState } from "@dashboard/hooks/useLocalPaginator";
+import useNotifier from "@dashboard/hooks/useNotifier";
+import { useIntl } from "react-intl";
+
+import { Product } from "./types";
+import { useCollectionId } from "./useCollectionId";
+import { useProductReorderOptimistic } from "./useProductReorderOptimistic";
+
+interface ProductReorderProps {
+ paginationState: PaginationState;
+}
+
+export const useProductReorder = ({ paginationState }: ProductReorderProps) => {
+ const collectionId = useCollectionId();
+ const notify = useNotifier();
+ const intl = useIntl();
+ const { createForDroppedItem } = useProductReorderOptimistic({ paginationState });
+
+ const [reorder, data] = useReorderProductsInCollectionMutation();
+
+ const move = async (products: Product[], productId: string, shift: number) => {
+ await reorder({
+ variables: {
+ collectionId,
+ moves: [
+ {
+ productId,
+ sortOrder: -shift,
+ },
+ ],
+ ...paginationState,
+ },
+ optimisticResponse: createForDroppedItem(products, productId),
+ });
+
+ notify({
+ text: intl.formatMessage({
+ id: "XAvER/",
+ defaultMessage: "Product reordered",
+ }),
+ status: "success",
+ });
+ };
+
+ return {
+ move,
+ data,
+ };
+};
diff --git a/src/collections/components/CollectionProducts/useProductReorderOptimistic.test.ts b/src/collections/components/CollectionProducts/useProductReorderOptimistic.test.ts
new file mode 100644
index 00000000000..8c3cabcfdbd
--- /dev/null
+++ b/src/collections/components/CollectionProducts/useProductReorderOptimistic.test.ts
@@ -0,0 +1,202 @@
+import { PaginationState } from "@dashboard/hooks/usePaginator";
+import { renderHook } from "@testing-library/react-hooks";
+
+import { Product } from "./types";
+import { useCollectionId } from "./useCollectionId";
+import { useProductEdges } from "./useProductEdges";
+import { useProductReorderOptimistic } from "./useProductReorderOptimistic";
+
+jest.mock("./useCollectionId");
+jest.mock("./useProductEdges");
+
+const mockCollectionId = "collection-123";
+const mockEdges = [
+ {
+ node: {
+ id: "product-1",
+ name: "Product 1",
+ },
+ },
+ {
+ node: {
+ id: "product-2",
+ name: "Product 2",
+ },
+ },
+ {
+ node: {
+ id: "product-3",
+ name: "Product 3",
+ },
+ },
+];
+
+(useCollectionId as jest.Mock).mockReturnValue(mockCollectionId);
+(useProductEdges as jest.Mock).mockReturnValue({ edges: mockEdges });
+
+describe("CollectionProducts/useProductReorderOptimistic", () => {
+ // Arrange
+ const defaultPaginationState = {
+ first: 10,
+ after: null,
+ last: null,
+ before: null,
+ } as unknown as PaginationState;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ (useCollectionId as jest.Mock).mockReturnValue(mockCollectionId);
+ (useProductEdges as jest.Mock).mockReturnValue({ edges: mockEdges });
+ });
+
+ it("should create proper optimistic response for reordered products", () => {
+ // Arrange & Act
+ const { result } = renderHook(() =>
+ useProductReorderOptimistic({ paginationState: defaultPaginationState }),
+ );
+
+ const products = [
+ { id: "product-2", name: "Product 2" },
+ { id: "product-1", name: "Product 1" },
+ { id: "product-3", name: "Product 3" },
+ ] as Product[];
+
+ const activeNodeId = "product-1";
+ const response = result.current.createForDroppedItem(products, activeNodeId);
+
+ // Assert
+ expect(response).toEqual({
+ collectionReorderProducts: {
+ __typename: "CollectionReorderProducts",
+ collection: {
+ __typename: "Collection",
+ id: mockCollectionId,
+ products: {
+ __typename: "ProductCountableConnection",
+ edges: [
+ {
+ node: {
+ id: "product-2",
+ name: "Product 2",
+ },
+ },
+ {
+ node: {
+ id: "moved_product-1",
+ name: "Product 1",
+ },
+ },
+ {
+ node: {
+ id: "product-3",
+ name: "Product 3",
+ },
+ },
+ ],
+ pageInfo: {
+ __typename: "PageInfo",
+ endCursor: null,
+ hasNextPage: false,
+ hasPreviousPage: false,
+ startCursor: null,
+ },
+ },
+ },
+ errors: [],
+ },
+ __typename: "Mutation",
+ });
+ });
+
+ it("should handle empty product list", () => {
+ // Arrange & Act
+ const { result } = renderHook(() =>
+ useProductReorderOptimistic({ paginationState: defaultPaginationState }),
+ );
+
+ const products: Product[] = [];
+ const activeNodeId = "product-1";
+ const response = result.current.createForDroppedItem(products, activeNodeId);
+
+ // Assert
+ expect(response.collectionReorderProducts.collection.products.edges).toEqual([]);
+ });
+
+ it("should handle product not found in edges", () => {
+ // Arrange & Act
+ const { result } = renderHook(() =>
+ useProductReorderOptimistic({ paginationState: defaultPaginationState }),
+ );
+
+ const products = [
+ { id: "non-existent", name: "Non Existent Product" },
+ { id: "product-1", name: "Product 1" },
+ ] as Product[];
+
+ const activeNodeId = "product-1";
+ const response = result.current.createForDroppedItem(products, activeNodeId);
+
+ // Assert
+ expect(response.collectionReorderProducts.collection.products.edges).toEqual([
+ {
+ node: {
+ id: "moved_product-1",
+ name: "Product 1",
+ },
+ },
+ ]);
+ });
+
+ it("should use correct collection ID from hook", () => {
+ // Arrange
+ const customCollectionId = "custom-collection-123";
+
+ (useCollectionId as jest.Mock).mockReturnValue(customCollectionId);
+
+ const { result } = renderHook(() =>
+ useProductReorderOptimistic({ paginationState: defaultPaginationState }),
+ );
+
+ const products = [{ id: "product-1", name: "Product 1" }] as Product[];
+ const activeNodeId = "product-1";
+ const response = result.current.createForDroppedItem(products, activeNodeId);
+
+ // Assert
+ expect(response.collectionReorderProducts.collection.id).toBe(customCollectionId);
+ });
+
+ it("should preserve edge properties when creating optimistic response", () => {
+ // Arrange
+ const edgesWithExtraProps = [
+ {
+ node: {
+ id: "product-1",
+ name: "Product 1",
+ extraProp: "extra value",
+ },
+ cursor: "cursor-1",
+ },
+ ];
+
+ // Act
+ (useProductEdges as jest.Mock).mockReturnValue({ edges: edgesWithExtraProps });
+
+ const { result } = renderHook(() =>
+ useProductReorderOptimistic({ paginationState: defaultPaginationState }),
+ );
+
+ const products = [{ id: "product-1", name: "Product 1" }] as Product[];
+ const activeNodeId = "product-1";
+ const response = result.current.createForDroppedItem(products, activeNodeId);
+
+ // Assert
+ expect(response.collectionReorderProducts.collection.products.edges[0]).toMatchObject({
+ node: {
+ id: "moved_product-1",
+ name: "Product 1",
+ extraProp: "extra value",
+ },
+ cursor: "cursor-1",
+ });
+ });
+});
diff --git a/src/collections/components/CollectionProducts/useProductReorderOptimistic.ts b/src/collections/components/CollectionProducts/useProductReorderOptimistic.ts
new file mode 100644
index 00000000000..0bed5bf6b2c
--- /dev/null
+++ b/src/collections/components/CollectionProducts/useProductReorderOptimistic.ts
@@ -0,0 +1,62 @@
+import { PaginationState } from "@dashboard/hooks/useLocalPaginator";
+
+import { Edges, Product } from "./types";
+import { useCollectionId } from "./useCollectionId";
+import { useProductEdges } from "./useProductEdges";
+
+const createOptimisticResponseForEdges = (collectionId: string, edges: Edges) => ({
+ collectionReorderProducts: {
+ __typename: "CollectionReorderProducts" as const,
+ collection: {
+ __typename: "Collection" as const,
+ id: collectionId,
+ products: {
+ __typename: "ProductCountableConnection" as const,
+ edges: edges,
+ pageInfo: {
+ __typename: "PageInfo" as const,
+ endCursor: null,
+ hasNextPage: false,
+ hasPreviousPage: false,
+ startCursor: null,
+ },
+ },
+ },
+ errors: [],
+ },
+ __typename: "Mutation" as const,
+});
+
+interface ProductReorderOptimisticProps {
+ paginationState: PaginationState;
+}
+
+export const useProductReorderOptimistic = ({ paginationState }: ProductReorderOptimisticProps) => {
+ const collectionId = useCollectionId();
+ const { edges } = useProductEdges({ paginationState });
+
+ const createForDroppedItem = (listAfterSort: Product[], activeNodeId: string) => {
+ const exceededEdges = listAfterSort
+ .map(product => edges.find(edge => edge?.node?.id === product.id))
+ .filter(Boolean)
+ .map(edge => {
+ const nodeId = edge?.node?.id || "";
+ const isMoved = activeNodeId == nodeId;
+ const newId = isMoved ? "moved_" + nodeId : nodeId;
+
+ return {
+ ...edge,
+ node: {
+ ...edge?.node,
+ id: newId,
+ },
+ };
+ });
+
+ return createOptimisticResponseForEdges(collectionId, exceededEdges as Edges);
+ };
+
+ return {
+ createForDroppedItem,
+ };
+};
diff --git a/src/collections/index.tsx b/src/collections/index.tsx
index 9ab68615f9a..e2b141e551c 100644
--- a/src/collections/index.tsx
+++ b/src/collections/index.tsx
@@ -1,9 +1,11 @@
+import { ConditionalCollectionFilterProvider } from "@dashboard/components/ConditionalFilter";
+import { Route } from "@dashboard/components/Router";
import { sectionNames } from "@dashboard/intl";
import { asSortParams } from "@dashboard/utils/sort";
import { parse as parseQs } from "qs";
import React from "react";
import { useIntl } from "react-intl";
-import { Route, RouteComponentProps, Switch } from "react-router-dom";
+import { RouteComponentProps, Switch } from "react-router-dom";
import { WindowTitle } from "../components/WindowTitle";
import {
@@ -23,7 +25,11 @@ const CollectionList: React.FC> = ({ location }) => {
const qs = parseQs(location.search.substr(1)) as any;
const params: CollectionListUrlQueryParams = asSortParams(qs, CollectionListUrlSortField);
- return ;
+ return (
+
+
+
+ );
};
interface CollectionDetailsRouteProps {
diff --git a/src/collections/mutations.ts b/src/collections/mutations.ts
index 0edb43a8f1a..ba828c98b0b 100644
--- a/src/collections/mutations.ts
+++ b/src/collections/mutations.ts
@@ -13,19 +13,44 @@ export const collectionUpdate = gql`
}
`;
+/*
+ The mutation below has two simultaneous mutations:
+ - collectionAddProducts, for adding products to the collection
+ - collectionReorderProducts, for resetting its reorder position
+
+ The collectionReorderProducts is used here as a workaround due to issues on the API.
+ It does the reorder by moving product by 0, which sets the initial reorder position.
+
+ Additionally, collectionAddProducts gets only the errors as requested field,
+ while collectionReorderProducts takes the desired response (products and collection id) - this is
+ intentional as we are interested only in the response from reorder mutation, and
+ only that will invalidate the apollo cache (because of request collection id presence, required for cache key)
+*/
export const assignCollectionProduct = gql`
mutation CollectionAssignProduct(
$collectionId: ID!
$productIds: [ID!]!
+ $moves: [MoveProductInput!]!
$first: Int
$after: String
$last: Int
$before: String
) {
collectionAddProducts(collectionId: $collectionId, products: $productIds) {
+ errors {
+ ...CollectionError
+ }
+ }
+ collectionReorderProducts(collectionId: $collectionId, moves: $moves) {
collection {
id
- products(first: $first, after: $after, before: $before, last: $last) {
+ products(
+ first: $first
+ after: $after
+ before: $before
+ last: $last
+ sortBy: { field: COLLECTION, direction: ASC }
+ ) {
edges {
node {
...CollectionProduct
@@ -40,7 +65,7 @@ export const assignCollectionProduct = gql`
}
}
errors {
- ...CollectionError
+ message
}
}
}
@@ -81,18 +106,16 @@ export const unassignCollectionProduct = gql`
collectionRemoveProducts(collectionId: $collectionId, products: $productIds) {
collection {
id
- products(first: $first, after: $after, before: $before, last: $last) {
+ products(
+ first: $first
+ after: $after
+ before: $before
+ last: $last
+ sortBy: { field: COLLECTION, direction: ASC }
+ ) {
edges {
node {
- id
- name
- productType {
- id
- name
- }
- thumbnail {
- url
- }
+ ...CollectionProduct
}
}
pageInfo {
@@ -129,3 +152,42 @@ export const collectionChannelListingUpdate = gql`
}
}
`;
+
+export const reorderProductsInCollection = gql`
+ mutation ReorderProductsInCollection(
+ $collectionId: ID!
+ $moves: [MoveProductInput!]!
+ $first: Int
+ $after: String
+ $last: Int
+ $before: String
+ ) {
+ collectionReorderProducts(collectionId: $collectionId, moves: $moves) {
+ collection {
+ id
+ products(
+ first: $first
+ after: $after
+ before: $before
+ last: $last
+ sortBy: { field: COLLECTION, direction: ASC }
+ ) {
+ edges {
+ node {
+ ...CollectionProduct
+ }
+ }
+ pageInfo {
+ endCursor
+ hasNextPage
+ hasPreviousPage
+ startCursor
+ }
+ }
+ }
+ errors {
+ message
+ }
+ }
+ }
+`;
diff --git a/src/collections/queries.ts b/src/collections/queries.ts
index 4fccd237139..90e3f427ade 100644
--- a/src/collections/queries.ts
+++ b/src/collections/queries.ts
@@ -38,10 +38,24 @@ export const collectionList = gql`
`;
export const collectionDetails = gql`
- query CollectionDetails($id: ID!, $first: Int, $after: String, $last: Int, $before: String) {
+ query CollectionDetails($id: ID) {
collection(id: $id) {
...CollectionDetails
- products(first: $first, after: $after, before: $before, last: $last) {
+ }
+ }
+`;
+
+export const collectionProducts = gql`
+ query CollectionProducts($id: ID!, $first: Int, $after: String, $last: Int, $before: String) {
+ collection(id: $id) {
+ id
+ products(
+ first: $first
+ after: $after
+ before: $before
+ last: $last
+ sortBy: { field: COLLECTION, direction: ASC }
+ ) {
edges {
node {
...CollectionProduct
diff --git a/src/collections/utils.test.ts b/src/collections/utils.test.ts
new file mode 100644
index 00000000000..529967b6193
--- /dev/null
+++ b/src/collections/utils.test.ts
@@ -0,0 +1,38 @@
+import { SearchProductsQuery } from "@dashboard/graphql";
+
+import { getProductsFromSearchResults } from "./utils";
+
+describe("getProductsFromSearchResults", () => {
+ it("should return empty array when searchResults is undefined", () => {
+ // Arrange
+ const searchResults = undefined;
+
+ // Act
+ const result = getProductsFromSearchResults(searchResults);
+
+ // Assert
+ expect(result).toEqual([]);
+ });
+
+ it("should return products from search results", () => {
+ // Arrange
+ const searchResults = {
+ search: {
+ edges: [
+ {
+ node: { id: 1 },
+ },
+ {
+ node: { id: 2 },
+ },
+ ],
+ },
+ } as unknown as SearchProductsQuery;
+
+ // Act
+ const result = getProductsFromSearchResults(searchResults);
+
+ // Assert
+ expect(result).toEqual([{ id: 1 }, { id: 2 }]);
+ });
+});
diff --git a/src/collections/utils.ts b/src/collections/utils.ts
index 3e57b72a24a..9b4af6ce15b 100644
--- a/src/collections/utils.ts
+++ b/src/collections/utils.ts
@@ -1,5 +1,6 @@
import { ChannelCollectionData } from "@dashboard/channels/utils";
import { CollectionDetailsQuery, SearchProductsQuery } from "@dashboard/graphql";
+import { mapEdgesToItems } from "@dashboard/utils/maps";
export const createChannelsChangeHandler =
(
@@ -25,7 +26,7 @@ export const createChannelsChangeHandler =
export const getAssignedProductIdsToCollection = (
collection: CollectionDetailsQuery["collection"],
- queryData: SearchProductsQuery["search"],
+ queryData?: SearchProductsQuery["search"],
) => {
if (!queryData || !collection) {
return {};
@@ -36,3 +37,11 @@ export const getAssignedProductIdsToCollection = (
.map(e => ({ [e.node.id]: true }))
.reduce((p, c) => ({ ...p, ...c }), {});
};
+
+export const getProductsFromSearchResults = (searchResults: SearchProductsQuery | undefined) => {
+ if (!searchResults?.search) {
+ return [];
+ }
+
+ return mapEdgesToItems(searchResults.search)?.filter(suggestedProduct => suggestedProduct.id);
+};
diff --git a/src/collections/views/CollectionCreate.tsx b/src/collections/views/CollectionCreate.tsx
index 4cc8fc4dfe3..a79db066b10 100644
--- a/src/collections/views/CollectionCreate.tsx
+++ b/src/collections/views/CollectionCreate.tsx
@@ -63,28 +63,7 @@ export const CollectionCreate: React.FC = ({ params }) =>
{ closeModal, openModal },
{ formId: COLLECTION_CREATE_FORM_ID },
);
- const [createCollection, createCollectionOpts] = useCreateCollectionMutation({
- onCompleted: data => {
- if (data.collectionCreate.errors.length === 0) {
- notify({
- status: "success",
- text: intl.formatMessage(commonMessages.savedChanges),
- });
- navigate(collectionUrl(data.collectionCreate.collection.id));
- } else {
- const backgroundImageError = data.collectionCreate.errors.find(
- error => error.field === ("backgroundImage" as keyof CollectionCreateInput),
- );
-
- if (backgroundImageError) {
- notify({
- status: "error",
- text: intl.formatMessage(commonMessages.somethingWentWrong),
- });
- }
- }
- },
- });
+ const [createCollection, createCollectionOpts] = useCreateCollectionMutation({});
const handleCreate = async (formData: CollectionCreateData) => {
const result = await createCollection({
variables: {
@@ -103,7 +82,7 @@ export const CollectionCreate: React.FC = ({ params }) =>
const id = result.data?.collectionCreate.collection?.id || null;
if (id) {
- updateChannels({
+ await updateChannels({
variables: {
id,
input: {
@@ -118,6 +97,25 @@ export const CollectionCreate: React.FC = ({ params }) =>
});
}
+ if (result.data.collectionCreate.errors.length === 0) {
+ notify({
+ status: "success",
+ text: intl.formatMessage(commonMessages.savedChanges),
+ });
+ navigate(collectionUrl(id));
+ } else {
+ const backgroundImageError = result.data.collectionCreate.errors.find(
+ error => error.field === ("backgroundImage" as keyof CollectionCreateInput),
+ );
+
+ if (backgroundImageError) {
+ notify({
+ status: "error",
+ text: intl.formatMessage(commonMessages.somethingWentWrong),
+ });
+ }
+ }
+
return { id, errors: getMutationErrors(result) };
};
const handleSubmit = createMetadataCreateHandler(
diff --git a/src/collections/views/CollectionDetails.tsx b/src/collections/views/CollectionDetails.tsx
index 03cabe967e3..bef48e65cf4 100644
--- a/src/collections/views/CollectionDetails.tsx
+++ b/src/collections/views/CollectionDetails.tsx
@@ -2,40 +2,28 @@
import { createCollectionChannels, createCollectionChannelsData } from "@dashboard/channels/utils";
import ActionDialog from "@dashboard/components/ActionDialog";
import useAppChannel from "@dashboard/components/AppLayout/AppChannelContext";
-import { Container } from "@dashboard/components/AssignContainerDialog";
-import AssignProductDialog from "@dashboard/components/AssignProductDialog";
-import { Button } from "@dashboard/components/Button";
import ChannelsAvailabilityDialog from "@dashboard/components/ChannelsAvailabilityDialog";
import NotFoundPage from "@dashboard/components/NotFoundPage";
import { WindowTitle } from "@dashboard/components/WindowTitle";
-import { DEFAULT_INITIAL_SEARCH_DATA, PAGINATE_BY } from "@dashboard/config";
import {
CollectionInput,
CollectionUpdateMutation,
- useCollectionAssignProductMutation,
useCollectionChannelListingUpdateMutation,
useCollectionDetailsQuery,
useCollectionUpdateMutation,
useRemoveCollectionMutation,
- useUnassignCollectionProductMutation,
useUpdateMetadataMutation,
useUpdatePrivateMetadataMutation,
} from "@dashboard/graphql";
-import useBulkActions from "@dashboard/hooks/useBulkActions";
import useChannels from "@dashboard/hooks/useChannels";
-import useLocalPaginator, { useLocalPaginationState } from "@dashboard/hooks/useLocalPaginator";
import useLocalStorage from "@dashboard/hooks/useLocalStorage";
import useNavigator from "@dashboard/hooks/useNavigator";
import useNotifier from "@dashboard/hooks/useNotifier";
-import { PaginatorContext } from "@dashboard/hooks/usePaginator";
import { commonMessages, errorMessages } from "@dashboard/intl";
-import useProductSearch from "@dashboard/searches/useProductSearch";
import { arrayDiff } from "@dashboard/utils/arrays";
import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHandlers";
import createMetadataUpdateHandler from "@dashboard/utils/handlers/metadataUpdateHandler";
-import { mapEdgesToItems } from "@dashboard/utils/maps";
import { getParsedDataForJsonStringField } from "@dashboard/utils/richText/misc";
-import { DialogContentText } from "@material-ui/core";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -48,7 +36,6 @@ import {
CollectionUrlDialog,
CollectionUrlQueryParams,
} from "../urls";
-import { getAssignedProductIdsToCollection } from "../utils";
import { COLLECTION_DETAILS_FORM_ID } from "./consts";
interface CollectionDetailsProps {
@@ -59,11 +46,7 @@ interface CollectionDetailsProps {
export const CollectionDetails: React.FC = ({ id, params }) => {
const navigate = useNavigator();
const notify = useNotifier();
- const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions(params.ids);
const intl = useIntl();
- const { search, loadMore, result } = useProductSearch({
- variables: DEFAULT_INITIAL_SEARCH_DATA,
- });
const [openModal, closeModal] = createDialogActionHandlers<
CollectionUrlDialog,
CollectionUrlQueryParams
@@ -96,35 +79,7 @@ export const CollectionDetails: React.FC = ({ id, params
const [updateCollection, updateCollectionOpts] = useCollectionUpdateMutation({
onCompleted: handleCollectionUpdate,
});
- const [assignProduct, assignProductOpts] = useCollectionAssignProductMutation({
- onCompleted: data => {
- if (data.collectionAddProducts.errors.length === 0) {
- notify({
- status: "success",
- text: intl.formatMessage({
- id: "56vUeQ",
- defaultMessage: "Added product to collection",
- }),
- });
- navigate(collectionUrl(id), { replace: true });
- }
- },
- });
- const [unassignProduct, unassignProductOpts] = useUnassignCollectionProductMutation({
- onCompleted: data => {
- if (data.collectionRemoveProducts.errors.length === 0) {
- notify({
- status: "success",
- text: intl.formatMessage({
- id: "WW+Ruy",
- defaultMessage: "Deleted product from collection",
- }),
- });
- reset();
- closeModal();
- }
- },
- });
+
const [removeCollection, removeCollectionOpts] = useRemoveCollectionMutation({
onCompleted: data => {
if (data.collectionDelete.errors.length === 0) {
@@ -139,13 +94,13 @@ export const CollectionDetails: React.FC = ({ id, params
}
},
});
- const [paginationState, setPaginationState] = useLocalPaginationState(PAGINATE_BY);
- const paginate = useLocalPaginator(setPaginationState);
+
const [selectedChannel] = useLocalStorage("collectionListChannel", "");
const { data, loading } = useCollectionDetailsQuery({
displayLoader: true,
- variables: { id, ...paginationState },
+ variables: { id },
});
+
const collection = data?.collection;
const allChannels = createCollectionChannels(availableChannels)?.sort((channel, nextChannel) =>
channel.name.localeCompare(nextChannel.name),
@@ -214,45 +169,19 @@ export const CollectionDetails: React.FC = ({ id, params
variables => updateMetadata({ variables }),
variables => updatePrivateMetadata({ variables }),
);
- const handleAssignationChange = async (products: Container[]) => {
- const productIds = products.map(product => product.id);
- const toUnassignIds = Object.keys(assignedProductDict).filter(
- s => assignedProductDict[s] && !productIds.includes(s),
- );
- const baseVariables = { ...paginationState, collectionId: id };
-
- if (productIds.length > 0) {
- await assignProduct({
- variables: { ...baseVariables, productIds },
- });
- }
-
- if (toUnassignIds.length > 0) {
- await unassignProduct({
- variables: { ...baseVariables, productIds: toUnassignIds },
- });
- }
- await result.refetch(DEFAULT_INITIAL_SEARCH_DATA);
- };
const formTransitionState = getMutationState(
updateCollectionOpts.called,
updateCollectionOpts.loading,
updateCollectionOpts.data?.collectionUpdate.errors,
);
- const { pageInfo, ...paginationValues } = paginate(
- data?.collection?.products?.pageInfo,
- paginationState,
- );
if (collection === null) {
return ;
}
- const assignedProductDict = getAssignedProductIdsToCollection(collection, result.data?.search);
-
return (
-
+ <>
{!!allChannels?.length && (
= ({ id, params
/>
)}
openModal("assign")}
disabled={loading || updateChannelsOpts.loading}
collection={data?.collection}
channelsErrors={updateChannelsOpts?.data?.collectionChannelListingUpdate.errors || []}
@@ -291,61 +219,13 @@ export const CollectionDetails: React.FC = ({ id, params
})
}
onSubmit={handleSubmit}
- onProductUnassign={async (productId, event) => {
- event.stopPropagation();
- await unassignProduct({
- variables: {
- collectionId: id,
- productIds: [productId],
- ...paginationState,
- },
- });
- await result.refetch(DEFAULT_INITIAL_SEARCH_DATA);
- }}
saveButtonBarState={formTransitionState}
- toolbar={
-
- openModal("unassign", {
- ids: listElements,
- })
- }
- >
-
-
- }
- isChecked={isSelected}
- selected={listElements.length}
- toggle={toggle}
- toggleAll={toggleAll}
currentChannels={currentChannels}
channelsCount={availableChannels.length}
selectedChannelId={selectedChannel}
openChannelsModal={handleChannelsModalOpen}
onChannelsChange={setCurrentChannels}
- />
- suggestedProduct.id,
- )}
+ params={params}
/>
= ({ id, params
})}
variant="delete"
>
-
- {maybe(() => data.collection.name, "...")},
- }}
- />
-
-
-
- unassignProduct({
- variables: {
- ...paginationState,
- collectionId: id,
- productIds: params.ids,
- },
- })
- }
- open={params.action === "unassign"}
- title={intl.formatMessage({
- id: "5OtU+V",
- defaultMessage: "Unassign products from collection",
- description: "dialog title",
- })}
- >
-
- params.ids.length),
- displayQuantity: {maybe(() => params.ids.length)} ,
- }}
- />
-
+ {maybe(() => data.collection.name, "...")},
+ }}
+ />
+
= ({ id, params
})}
variant="delete"
>
-
-
-
+
-
+ >
);
};
export default CollectionDetails;
diff --git a/src/collections/views/CollectionList/CollectionList.tsx b/src/collections/views/CollectionList/CollectionList.tsx
index d6b611f5e30..8a2a5f25654 100644
--- a/src/collections/views/CollectionList/CollectionList.tsx
+++ b/src/collections/views/CollectionList/CollectionList.tsx
@@ -1,8 +1,11 @@
// @ts-strict-ignore
import ActionDialog from "@dashboard/components/ActionDialog";
import useAppChannel from "@dashboard/components/AppLayout/AppChannelContext";
+import { useConditionalFilterContext } from "@dashboard/components/ConditionalFilter";
+import { createCollectionsQueryVariables } from "@dashboard/components/ConditionalFilter/queryVariables";
import DeleteFilterTabDialog from "@dashboard/components/DeleteFilterTabDialog";
import SaveFilterTabDialog from "@dashboard/components/SaveFilterTabDialog";
+import { useFlag } from "@dashboard/featureFlags";
import { useCollectionBulkDeleteMutation, useCollectionListQuery } from "@dashboard/graphql";
import { useFilterPresets } from "@dashboard/hooks/useFilterPresets";
import useListSettings from "@dashboard/hooks/useListSettings";
@@ -22,7 +25,6 @@ import createFilterHandlers from "@dashboard/utils/handlers/filterHandlers";
import createSortHandler from "@dashboard/utils/handlers/sortHandler";
import { mapEdgesToItems, mapNodeToChoice } from "@dashboard/utils/maps";
import { getSortParams } from "@dashboard/utils/sort";
-import { DialogContentText } from "@material-ui/core";
import isEqual from "lodash/isEqual";
import React, { useCallback, useEffect } from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -45,10 +47,11 @@ export const CollectionList: React.FC = ({ params }) => {
const intl = useIntl();
const notify = useNotifier();
const { updateListSettings, settings } = useListSettings(ListViews.COLLECTION_LIST);
+ const { enabled: isNewCollectionFilterEnabled } = useFlag("new_filters");
+ const { valueProvider } = useConditionalFilterContext();
usePaginationReset(collectionListUrl, params, settings.rowNumber);
- const { channel } = useAppChannel(false);
const {
clearRowSelection,
selectedRowIds,
@@ -63,11 +66,10 @@ export const CollectionList: React.FC = ({ params }) => {
params,
keepActiveTab: true,
});
- const { availableChannels } = useAppChannel(false);
+ const { availableChannels, channel } = useAppChannel(false);
const channelOpts = availableChannels
? mapNodeToChoice(availableChannels, channel => channel.slug)
: null;
- const selectedChannel = availableChannels.find(channel => channel.slug === params.channel);
const {
selectedPreset,
presets,
@@ -85,14 +87,31 @@ export const CollectionList: React.FC = ({ params }) => {
storageUtils,
});
const paginationState = createPaginationState(settings.rowNumber, params);
- const queryVariables = React.useMemo(
- () => ({
+ const selectedChannel_legacy = availableChannels.find(channel => channel.slug === params.channel);
+ const queryVariables = React.useMemo(() => {
+ if (!isNewCollectionFilterEnabled) {
+ return {
+ ...paginationState,
+ filter: getFilterVariables(params),
+ sort: getSortQueryVariables(params),
+ channel: selectedChannel_legacy?.slug,
+ };
+ }
+
+ const { channel, ...variables } = createCollectionsQueryVariables(valueProvider.value);
+
+ return {
...paginationState,
- filter: getFilterVariables(params),
+ filter: {
+ ...variables,
+ search: params.query,
+ },
sort: getSortQueryVariables(params),
- channel: selectedChannel?.slug,
- }),
- [params, settings.rowNumber],
+ channel, // Saleor docs say 'channel' in filter is deprecated and should be moved to root
+ };
+ }, [params, settings.rowNumber, valueProvider.value, isNewCollectionFilterEnabled]);
+ const selectedChannel = availableChannels.find(
+ channel => channel.slug === queryVariables.channel,
);
const { data, refetch } = useCollectionListQuery({
displayLoader: true,
@@ -112,10 +131,9 @@ export const CollectionList: React.FC = ({ params }) => {
}
},
});
- const filterOpts = getFilterOpts(params, channelOpts);
useEffect(() => {
- if (!canBeSorted(params.sort, !!selectedChannel)) {
+ if (!canBeSorted(params.sort, !!queryVariables.channel)) {
navigate(
collectionListUrl({
...params,
@@ -161,6 +179,11 @@ export const CollectionList: React.FC = ({ params }) => {
clearRowSelection();
}, [selectedRowIds]);
+ const filterOpts = getFilterOpts(params, channelOpts);
+ const selectedChannelId = isNewCollectionFilterEnabled
+ ? selectedChannel?.id
+ : selectedChannel_legacy?.id;
+
return (
= ({ params }) => {
onSort={handleSort}
onUpdateListSettings={updateListSettings}
sort={getSortParams(params)}
- selectedChannelId={selectedChannel?.id}
+ selectedChannelId={selectedChannelId}
filterOpts={filterOpts}
onFilterChange={changeFilters}
selectedCollectionIds={selectedRowIds}
@@ -208,16 +231,14 @@ export const CollectionList: React.FC = ({ params }) => {
description: "dialog title",
})}
>
-
- selectedRowIds.length),
- displayQuantity: {maybe(() => selectedRowIds.length)} ,
- }}
- />
-
+ selectedRowIds.length),
+ displayQuantity: {maybe(() => selectedRowIds.length)} ,
+ }}
+ />
{
value: CollectionPublished.PUBLISHED,
},
channel: undefined as unknown as FilterOpts & {
- choices: MultiAutocompleteChoiceType[];
+ choices: Option[];
},
});
@@ -51,7 +51,7 @@ describe("Filtering URL params", () => {
value: CollectionPublished.PUBLISHED,
},
channel: undefined as unknown as FilterOpts & {
- choices: MultiAutocompleteChoiceType[];
+ choices: Option[];
},
});
const filterQueryParams = getFilterQueryParams(
diff --git a/src/collections/views/CollectionList/filters.ts b/src/collections/views/CollectionList/filters.ts
index 7890ae6608c..467d39ed91a 100644
--- a/src/collections/views/CollectionList/filters.ts
+++ b/src/collections/views/CollectionList/filters.ts
@@ -4,9 +4,9 @@ import {
CollectionListFilterOpts,
} from "@dashboard/collections/components/CollectionListPage";
import { FilterElement, FilterElementRegular } from "@dashboard/components/Filter";
-import { SingleAutocompleteChoiceType } from "@dashboard/components/SingleAutocompleteSelectField";
import { CollectionFilterInput, CollectionPublished } from "@dashboard/graphql";
import { findValueInEnum, maybe } from "@dashboard/misc";
+import { Option } from "@saleor/macaw-ui-next";
import {
createFilterTabUtils,
@@ -24,7 +24,7 @@ export const COLLECTION_FILTERS_KEY = "collectionFilters";
export function getFilterOpts(
params: CollectionListUrlFilters,
- channels: SingleAutocompleteChoiceType[],
+ channels: Option[],
): CollectionListFilterOpts {
return {
channel: {
diff --git a/src/components/AccountPermissionGroups/AccountPermissionGroups.tsx b/src/components/AccountPermissionGroups/AccountPermissionGroups.tsx
index 66ffac1172c..91ff2f08f3b 100644
--- a/src/components/AccountPermissionGroups/AccountPermissionGroups.tsx
+++ b/src/components/AccountPermissionGroups/AccountPermissionGroups.tsx
@@ -4,8 +4,7 @@ import { FormChange } from "@dashboard/hooks/useForm";
import { FetchMoreProps, RelayToFlat, SearchPageProps } from "@dashboard/types";
import { getFormErrors } from "@dashboard/utils/errors";
import getStaffErrorMessage from "@dashboard/utils/errors/staff";
-import { Typography } from "@material-ui/core";
-import { Option } from "@saleor/macaw-ui-next";
+import { Option, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
@@ -63,10 +62,10 @@ const AccountPermissionGroups: React.FC = props =>
helperText={getStaffErrorMessage(formErrors.addGroups, intl)}
/>
{!!formErrors.addGroups && (
- {getStaffErrorMessage(formErrors.addGroups, intl)}
+ {getStaffErrorMessage(formErrors.addGroups, intl)}
)}
{!!formErrors.removeGroups && (
- {getStaffErrorMessage(formErrors.removeGroups, intl)}
+ {getStaffErrorMessage(formErrors.removeGroups, intl)}
)}
>
);
diff --git a/src/components/AccountPermissions/components/PermissionList/PermissionList.tsx b/src/components/AccountPermissions/components/PermissionList/PermissionList.tsx
index 5b482d6c5f6..f616671338e 100644
--- a/src/components/AccountPermissions/components/PermissionList/PermissionList.tsx
+++ b/src/components/AccountPermissions/components/PermissionList/PermissionList.tsx
@@ -1,7 +1,6 @@
-import Skeleton from "@dashboard/components/Skeleton";
import { PermissionData } from "@dashboard/permissionGroups/components/PermissionGroupDetailsPage";
import { Checkbox, ListItem, ListItemIcon, ListItemText } from "@material-ui/core";
-import { Box } from "@saleor/macaw-ui-next";
+import { Box, Skeleton } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
diff --git a/src/components/ActionDialog/ActionDialog.tsx b/src/components/ActionDialog/ActionDialog.tsx
index 0e60c63758c..67e1791976b 100644
--- a/src/components/ActionDialog/ActionDialog.tsx
+++ b/src/components/ActionDialog/ActionDialog.tsx
@@ -1,37 +1,67 @@
-import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
+import { ConfirmButton, ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
+import { buttonMessages } from "@dashboard/intl";
import { DialogProps } from "@dashboard/types";
-import { Dialog, DialogContent, DialogTitle } from "@material-ui/core";
+import { Box } from "@saleor/macaw-ui-next";
import React from "react";
+import { useIntl } from "react-intl";
-import DialogButtons from "./DialogButtons";
-import { ActionDialogVariant, Size } from "./types";
+import BackButton from "../BackButton";
+import { DashboardModal, DashboardModalContentSize } from "../Modal";
+import { ActionDialogVariant } from "./types";
export interface ActionDialogProps extends DialogProps {
children?: React.ReactNode;
confirmButtonLabel?: string;
confirmButtonState: ConfirmButtonTransitionState;
disabled?: boolean;
- maxWidth?: Size | false;
title: string;
variant?: ActionDialogVariant;
backButtonText?: string;
onConfirm: () => any;
+ size?: DashboardModalContentSize;
}
-const ActionDialog: React.FC = props => {
- const { children, open, title, onClose, variant, maxWidth, ...rest } = props;
+const ActionDialog = ({
+ children,
+ open,
+ title,
+ onClose,
+ variant,
+ confirmButtonState,
+ backButtonText,
+ disabled,
+ onConfirm,
+ confirmButtonLabel,
+ size = "sm",
+}: ActionDialogProps) => {
+ const intl = useIntl();
return (
-
- {title}
- {children}
-
-
+
+
+ {title}
+ {children}
+
+ {backButtonText}
+ {variant !== "info" && (
+
+ {confirmButtonLabel ||
+ (variant === "delete"
+ ? intl.formatMessage(buttonMessages.delete)
+ : intl.formatMessage(buttonMessages.confirm))}
+
+ )}
+
+
+
);
};
-ActionDialog.defaultProps = {
- maxWidth: "xs",
-};
ActionDialog.displayName = "ActionDialog";
export default ActionDialog;
diff --git a/src/components/ActionDialog/DialogButtons.tsx b/src/components/ActionDialog/DialogButtons.tsx
deleted file mode 100644
index b06fc40341a..00000000000
--- a/src/components/ActionDialog/DialogButtons.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-// @ts-strict-ignore
-import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
-import { buttonMessages } from "@dashboard/intl";
-import { DialogActions } from "@material-ui/core";
-import React from "react";
-import { useIntl } from "react-intl";
-
-import BackButton from "../BackButton";
-import { ConfirmButton } from "../ConfirmButton/ConfirmButton";
-import { ActionDialogVariant } from "./types";
-
-interface DialogButtonsProps {
- onClose: () => void;
- confirmButtonLabel?: string;
- confirmButtonState?: ConfirmButtonTransitionState;
- disabled?: boolean;
- variant?: ActionDialogVariant;
- children?: React.ReactNode;
- showBackButton?: boolean;
- backButtonText?: string;
- onConfirm: () => any;
-}
-
-const DialogButtons: React.FC = props => {
- const {
- confirmButtonLabel,
- confirmButtonState,
- disabled,
- variant,
- onConfirm,
- onClose,
- children,
- showBackButton = true,
- backButtonText,
- } = props;
- const intl = useIntl();
-
- return (
-
- {children}
- {showBackButton && {backButtonText} }
- {variant !== "info" && (
-
- {confirmButtonLabel ||
- (variant === "delete"
- ? intl.formatMessage(buttonMessages.delete)
- : intl.formatMessage(buttonMessages.confirm))}
-
- )}
-
- );
-};
-
-DialogButtons.defaultProps = {
- confirmButtonState: "default",
- variant: "default",
-};
-
-export default DialogButtons;
diff --git a/src/components/ActionDialog/NewActionDialog.tsx b/src/components/ActionDialog/NewActionDialog.tsx
index d97a2ec6c56..e69de29bb2d 100644
--- a/src/components/ActionDialog/NewActionDialog.tsx
+++ b/src/components/ActionDialog/NewActionDialog.tsx
@@ -1,53 +0,0 @@
-import { ConfirmButton, ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
-import { DialogProps } from "@dashboard/types";
-import React from "react";
-
-import BackButton from "../BackButton";
-import { DASHBOARD_MODAL_WIDTH, DashboardModal } from "../Modal";
-import { ActionDialogVariant, Size } from "./types";
-
-export interface NewActionDialogProps extends DialogProps {
- children?: React.ReactNode;
- confirmButtonLabel?: string;
- confirmButtonState: ConfirmButtonTransitionState;
- disabled?: boolean;
- maxWidth?: Size | false;
- title: string;
- variant?: ActionDialogVariant;
- backButtonText?: string;
- onConfirm: () => any;
-}
-
-// TODO: migrate alle old components to new dialog MERX-649
-const NewActionDialog: React.FC = props => {
- const { children, open, title, onClose, variant, maxWidth, ...rest } = props;
-
- return (
-
-
- {title}
-
- {children}
-
-
- {rest?.backButtonText}
-
- {rest?.confirmButtonLabel}
-
-
-
-
- );
-};
-
-NewActionDialog.defaultProps = {
- maxWidth: "xs",
-};
-NewActionDialog.displayName = "ActionDialog";
-export default NewActionDialog;
diff --git a/src/components/ActionDialog/index.ts b/src/components/ActionDialog/index.ts
index b98866d7be2..1b7746fa07b 100644
--- a/src/components/ActionDialog/index.ts
+++ b/src/components/ActionDialog/index.ts
@@ -1,3 +1,2 @@
export { default } from "./ActionDialog";
export * from "./ActionDialog";
-export * from "./NewActionDialog";
diff --git a/src/components/ActionDialog/types.ts b/src/components/ActionDialog/types.ts
index ad9440fb5a1..2fcce1ea665 100644
--- a/src/components/ActionDialog/types.ts
+++ b/src/components/ActionDialog/types.ts
@@ -1,3 +1 @@
export type ActionDialogVariant = "default" | "delete" | "info";
-
-export type Size = "xs" | "sm" | "md" | "lg" | "xl";
diff --git a/src/components/AddressEdit/useAddressValidation.test.ts b/src/components/AddressEdit/useAddressValidation.test.ts
index 4c436dd2c57..96b0e729cc0 100644
--- a/src/components/AddressEdit/useAddressValidation.test.ts
+++ b/src/components/AddressEdit/useAddressValidation.test.ts
@@ -1,12 +1,13 @@
-import { useAddressValidationRulesQuery } from "@dashboard/graphql";
+import { AddressValidationRulesQuery, useAddressValidationRulesQuery } from "@dashboard/graphql";
import { renderHook } from "@testing-library/react-hooks";
-import { useAddressValidation } from "./useAddressValidation";
+import { selectRules, useAddressValidation } from "./useAddressValidation";
jest.mock("@dashboard/graphql", () => ({
CountryCode: jest.requireActual("@dashboard/graphql").CountryCode,
useAddressValidationRulesQuery: jest.fn(),
}));
+
describe("useAddressValidation", () => {
it("skips loading validation rules when country is not provided", () => {
// Arrange
@@ -29,6 +30,7 @@ describe("useAddressValidation", () => {
});
expect(current.isFieldAllowed("country")).toBeFalsy();
});
+
it("loads validation rules when country is provided", () => {
// Arrange
(useAddressValidationRulesQuery as jest.Mock).mockReturnValue({
@@ -62,4 +64,130 @@ describe("useAddressValidation", () => {
expect(current.isFieldAllowed("country")).toBeTruthy();
expect(current.isFieldAllowed("countryArea")).toBeFalsy();
});
+
+ it("getDisplayValue should return display value for area code when valid", () => {
+ // Arrange
+ (useAddressValidationRulesQuery as jest.Mock).mockReturnValue({
+ data: {
+ addressValidationRules: {
+ countryAreaChoices: [
+ { raw: "AL", verbose: "Alabama" },
+ { raw: "AN", verbose: "Ancona" },
+ ],
+ allowedFields: ["country"],
+ },
+ },
+ loading: false,
+ });
+
+ const {
+ result: { current },
+ } = renderHook(() => useAddressValidation("US"));
+
+ const displayValue = current.getDisplayValue("AL");
+
+ // Assert
+ expect(displayValue).toEqual("Alabama");
+ });
+
+ it("getDisplayValue should return value when area code invalid", () => {
+ // Arrange
+ (useAddressValidationRulesQuery as jest.Mock).mockReturnValue({
+ data: {
+ addressValidationRules: {
+ countryAreaChoices: [
+ { raw: "AL", verbose: "Alabama" },
+ { raw: "AN", verbose: "Ancona" },
+ ],
+ allowedFields: ["country"],
+ },
+ },
+ loading: false,
+ });
+
+ const {
+ result: { current },
+ } = renderHook(() => useAddressValidation("US"));
+
+ const displayValue = current.getDisplayValue("XX");
+
+ // Assert
+ expect(displayValue).toEqual("XX");
+ });
+
+ it("getDisplayValue should return empty string when value is null", () => {
+ // Arrange
+ (useAddressValidationRulesQuery as jest.Mock).mockReturnValue({
+ data: {
+ addressValidationRules: {
+ countryAreaChoices: [
+ { raw: "AL", verbose: "Alabama" },
+ { raw: "AN", verbose: "Ancona" },
+ ],
+ allowedFields: ["country"],
+ },
+ },
+ loading: false,
+ });
+
+ const {
+ result: { current },
+ } = renderHook(() => useAddressValidation("US"));
+
+ const displayValue = current.getDisplayValue(null);
+
+ // Assert
+ expect(displayValue).toEqual("");
+ });
+});
+
+describe("selectRules", () => {
+ it("should return select rules when available", () => {
+ // Arrange
+ const data = {
+ addressValidationRules: {
+ countryAreaChoices: [
+ { raw: "AL", verbose: "Alabama" },
+ { raw: "AN", verbose: "Ancona" },
+ ],
+ allowedFields: ["country"],
+ },
+ } as AddressValidationRulesQuery;
+
+ // Act
+ const rules = selectRules(data);
+
+ // Assert
+ expect(rules).toEqual({
+ countryAreaChoices: [
+ { raw: "AL", verbose: "Alabama" },
+ { raw: "AN", verbose: "Ancona" },
+ ],
+ allowedFields: ["country"],
+ });
+ });
+
+ it("should return empty array when addressValidationRules is not provided", () => {
+ // Arrange
+ const data = {
+ addressValidationRules: null,
+ } as AddressValidationRulesQuery;
+
+ // Act
+ const rules = selectRules(data);
+
+ // Assert
+ expect(rules).toEqual({ countryAreaChoices: [], allowedFields: [] });
+ });
+
+ it("should return empty array when data is not provided", () => {
+ // Arrange
+ const data = undefined;
+
+ // Act
+ const rules = selectRules(data);
+
+ // Assert
+ expect(rules).toEqual({ countryAreaChoices: [], allowedFields: [] });
+ });
});
diff --git a/src/components/AddressEdit/useAddressValidation.ts b/src/components/AddressEdit/useAddressValidation.ts
index 50b19ab4c4e..b7cec8fa771 100644
--- a/src/components/AddressEdit/useAddressValidation.ts
+++ b/src/components/AddressEdit/useAddressValidation.ts
@@ -18,8 +18,15 @@ const prepareChoices = (values: ChoiceValue[]): AreaChoices[] =>
value: v.verbose,
raw: v.raw,
}));
-const selectRules = (data: AddressValidationRulesQuery) =>
- data ? data.addressValidationRules : { countryAreaChoices: [], allowedFields: [] };
+
+export const selectRules = (data: AddressValidationRulesQuery | null | undefined) => {
+ if (!data || !data.addressValidationRules) {
+ return { countryAreaChoices: [], allowedFields: [] };
+ }
+
+ return data.addressValidationRules;
+};
+
const useValidationRules = (country?: string) => {
const countryCode = CountryCode[country];
const { data, loading } = useAddressValidationRulesQuery({
@@ -30,7 +37,7 @@ const useValidationRules = (country?: string) => {
return { data, loading };
};
const useAreas = (data: AddressValidationRulesQuery) => {
- const rawChoices = selectRules(data).countryAreaChoices;
+ const rawChoices = selectRules(data)?.countryAreaChoices ?? [];
const choices = prepareChoices(rawChoices);
return choices;
@@ -48,11 +55,19 @@ const useAllowedFields = (data: AddressValidationRulesQuery) => {
};
const useDisplayValues = (areas: AreaChoices[]) => {
const isProvinceCode = (code: string) => code.length === 2 && code.toLocaleUpperCase() === code;
- const getDisplayValue = (value: string) => {
+ const getDisplayValue = (value: string | null | undefined) => {
+ if (!value) {
+ return "";
+ }
+
if (isProvinceCode(value)) {
const area = areas.find(area => area.raw === value);
- return area.value;
+ if (area) {
+ return area.value;
+ }
+
+ return value;
}
return value;
diff --git a/src/components/AddressFormatter/AddressFormatter.tsx b/src/components/AddressFormatter/AddressFormatter.tsx
index 665c7679716..d20d318a48a 100644
--- a/src/components/AddressFormatter/AddressFormatter.tsx
+++ b/src/components/AddressFormatter/AddressFormatter.tsx
@@ -1,8 +1,7 @@
-import { Typography } from "@material-ui/core";
+import { Skeleton, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { AddressType } from "../../customers/types";
-import Skeleton from "../Skeleton";
interface AddressFormatterProps {
address?: AddressType;
@@ -20,32 +19,32 @@ const AddressFormatter: React.FC = ({ address }) => {
fontStyle: "inherit",
}}
>
-
+
{address.firstName} {address.lastName}
-
-
+
+
{address.phone}
-
+
{address.companyName && (
-
+
{address.companyName}
-
+
)}
-
+
{address.streetAddress1}
{address.streetAddress2}
-
-
+
+
{" "}
{address.postalCode} {address.city}
{address.cityArea ? ", " + address.cityArea : ""}
-
-
+
+
{address.countryArea
? address.countryArea + ", " + address.country.country
: address.country.country}
-
+
);
};
diff --git a/src/components/Alert/InlineAlert.tsx b/src/components/Alert/InlineAlert.tsx
index d23c15a186e..cf1ec3e7bc2 100644
--- a/src/components/Alert/InlineAlert.tsx
+++ b/src/components/Alert/InlineAlert.tsx
@@ -1,25 +1,15 @@
-import { Card } from "@material-ui/core";
-import { makeStyles } from "@saleor/macaw-ui";
import React from "react";
-const useStyles = makeStyles(
- theme => ({
- container: {
- backgroundColor: theme.palette.error.main,
- padding: theme.spacing(1.5, 2),
- },
- }),
- { name: "InlineAlert" },
-);
+import { DashboardCard } from "../Card";
interface AlertCardProps {
children?: React.ReactNode | React.ReactNode[];
}
-const AlertCard: React.FC = ({ children }) => {
- const classes = useStyles({});
-
- return {children} ;
-};
+const AlertCard: React.FC = ({ children }) => (
+
+ {children}
+
+);
export default AlertCard;
diff --git a/src/components/AppLayout/AppChannelSelect.tsx b/src/components/AppLayout/AppChannelSelect.tsx
index e40386172da..4551d84f2c8 100644
--- a/src/components/AppLayout/AppChannelSelect.tsx
+++ b/src/components/AppLayout/AppChannelSelect.tsx
@@ -1,30 +1,10 @@
+import { Select } from "@dashboard/components/Select";
import { ChannelFragment } from "@dashboard/graphql";
import { ChannelProps } from "@dashboard/types";
import { mapNodeToChoice } from "@dashboard/utils/maps";
-import { makeStyles } from "@saleor/macaw-ui";
-import { vars } from "@saleor/macaw-ui-next";
+import { Box } from "@saleor/macaw-ui-next";
import React from "react";
-import SingleSelectField from "../SingleSelectField";
-
-const useStyles = makeStyles(
- {
- input: {
- height: 40,
- },
- root: {
- "&& fieldset": {
- borderColor: vars.colors.border.default1,
- },
- width: 192,
- padding: 10,
- },
- },
- {
- name: "AppChannelSelect",
- },
-);
-
export interface AppChannelSelectProps extends ChannelProps {
channels: ChannelFragment[];
onChannelSelect: (id: string) => void;
@@ -35,20 +15,17 @@ const AppChannelSelect: React.FC = ({
onChannelSelect,
selectedChannelId,
}) => {
- const classes = useStyles({});
-
return (
-
-
+ onChannelSelect(target.value)}
value={selectedChannelId}
- onChange={event => onChannelSelect(event.target.value)}
+ options={mapNodeToChoice(channels)}
/>
-
+
);
};
diff --git a/src/components/AppLayout/ContextualLinks/ContextualLine.tsx b/src/components/AppLayout/ContextualLinks/ContextualLine.tsx
new file mode 100644
index 00000000000..eeba25c78eb
--- /dev/null
+++ b/src/components/AppLayout/ContextualLinks/ContextualLine.tsx
@@ -0,0 +1,41 @@
+import { Box, Paragraph, TextProps } from "@saleor/macaw-ui-next";
+import React from "react";
+
+const Root = ({ children, ...rest }: TextProps) => (
+
+ {children}
+
+);
+
+const ContextualLineLink = ({
+ href,
+ children,
+ onClick,
+}: {
+ href: string;
+ children: React.ReactNode;
+ onClick?: () => void;
+}) => (
+
+ {children}
+
+);
+
+export const ContextualLine = Object.assign(Root, {
+ Link: ContextualLineLink,
+});
diff --git a/src/components/AppLayout/ContextualLinks/messages.ts b/src/components/AppLayout/ContextualLinks/messages.ts
new file mode 100644
index 00000000000..0dc4743b6fb
--- /dev/null
+++ b/src/components/AppLayout/ContextualLinks/messages.ts
@@ -0,0 +1,48 @@
+import { defineMessages } from "react-intl";
+
+export const contextualLinks = defineMessages({
+ devModePanel: {
+ defaultMessage: "Learn more about {apiReference} and view {apiGuide}",
+ id: "zRIsjN",
+ },
+ apiReference: {
+ defaultMessage: "API reference",
+ id: "Zvo5iu",
+ },
+ apiGuide: {
+ defaultMessage: "API guide",
+ id: "BA4leV",
+ },
+ webhooks: {
+ defaultMessage: "Learn more about {extendingSaleor}",
+ id: "zT1CvH",
+ },
+ extendingSaleor: {
+ defaultMessage: "extending Saleor with Webhooks",
+ id: "B8PvdI",
+ },
+ staffMembers: {
+ defaultMessage: "Learn more about {userPermissions}",
+ id: "19o9WS",
+ },
+ userPermissions: {
+ defaultMessage: "User permissions",
+ id: "5M+hLZ",
+ },
+ orders: {
+ defaultMessage: "Learn more about {orderManagement}",
+ id: "tl1/1E",
+ },
+ orderManagement: {
+ defaultMessage: "order management",
+ id: "91vQMc",
+ },
+ products: {
+ defaultMessage: "Learn more about {productConfigurations}",
+ id: "C9cgck",
+ },
+ productConfigurations: {
+ defaultMessage: "product configurations",
+ id: "dVk241",
+ },
+});
diff --git a/src/components/AppLayout/ContextualLinks/useContextualLink.tsx b/src/components/AppLayout/ContextualLinks/useContextualLink.tsx
new file mode 100644
index 00000000000..97c04fee263
--- /dev/null
+++ b/src/components/AppLayout/ContextualLinks/useContextualLink.tsx
@@ -0,0 +1,95 @@
+import { useAnalytics } from "@dashboard/components/ProductAnalytics/useAnalytics";
+import {
+ API_GUIDE_DOCS,
+ API_REFERENCE_DOCS,
+ EXTENDING_WITH_WEBHOOKS_DOCS_URL,
+ ORDER_MANAGEMENT_DOCS_URL,
+ PRODUCT_CONFIGURATION_DOCS_URL,
+ USER_PERMISSIONS_DOCS_URL,
+} from "@dashboard/links";
+import * as React from "react";
+import { useIntl } from "react-intl";
+
+import { ContextualLine } from "./ContextualLine";
+import { contextualLinks } from "./messages";
+
+type SubtitleType =
+ | "extending_saleor"
+ | "product_list"
+ | "order_list"
+ | "dev_panel"
+ | "webhooks_events"
+ | "staff_members";
+
+const EVENT = "contextual_link_clicked";
+
+export const useContextualLink = (type: SubtitleType) => {
+ const { trackEvent: track } = useAnalytics();
+ const intl = useIntl();
+ const trackEvent = (type: string) => track(EVENT, { type });
+
+ switch (type) {
+ case "staff_members":
+ return intl.formatMessage(contextualLinks.staffMembers, {
+ userPermissions: (
+ trackEvent("user_permissions_docs")}
+ >
+ {intl.formatMessage(contextualLinks.userPermissions)}
+
+ ),
+ });
+ case "extending_saleor":
+ return intl.formatMessage(contextualLinks.webhooks, {
+ extendingSaleor: (
+ trackEvent("extending_saleor_docs")}
+ >
+ {intl.formatMessage(contextualLinks.extendingSaleor)}
+
+ ),
+ });
+ case "dev_panel":
+ return intl.formatMessage(contextualLinks.devModePanel, {
+ apiReference: (
+ trackEvent("api_reference_docs")}
+ >
+ {intl.formatMessage(contextualLinks.apiReference)}
+
+ ),
+ apiGuide: (
+ trackEvent("api_guide_docs")}>
+ {intl.formatMessage(contextualLinks.apiGuide)}
+
+ ),
+ });
+ case "order_list":
+ return intl.formatMessage(contextualLinks.orders, {
+ orderManagement: (
+ trackEvent("order_management_docs")}
+ >
+ {intl.formatMessage(contextualLinks.orderManagement)}
+
+ ),
+ });
+ case "product_list":
+ return intl.formatMessage(contextualLinks.products, {
+ productConfigurations: (
+ trackEvent("product_configuration_docs")}
+ >
+ {intl.formatMessage(contextualLinks.productConfigurations)}
+
+ ),
+ });
+ default:
+ return null;
+ }
+};
diff --git a/src/components/AppLayout/ListFilters/ListFilters.tsx b/src/components/AppLayout/ListFilters/ListFilters.tsx
index b1e86707f5d..89ed38b545b 100644
--- a/src/components/AppLayout/ListFilters/ListFilters.tsx
+++ b/src/components/AppLayout/ListFilters/ListFilters.tsx
@@ -8,56 +8,65 @@ import { FiltersSelect } from "./components/FiltersSelect";
import { LegacyFiltersPresetsAlert } from "./components/LegacyFiltersPresetsAlert";
import SearchInput from "./components/SearchInput";
-export interface ListFiltersProps
+export interface NewFilterProps extends SearchPageProps {
+ type: "expression-filter";
+ searchPlaceholder: string;
+ actions?: ReactNode;
+}
+
+interface OldFiltersProps
extends FilterProps,
SearchPageProps {
+ type?: "old-filter-select";
searchPlaceholder: string;
- errorMessages?: FilterErrorMessages;
- filterStructure: IFilter;
actions?: ReactNode;
- filtersEnabled?: boolean;
+ filterStructure?: IFilter;
+ errorMessages?: FilterErrorMessages;
}
+export type ListFiltersProps =
+ | NewFilterProps
+ | OldFiltersProps;
+
export const ListFilters = ({
- currencySymbol,
- filterStructure,
initialSearch,
searchPlaceholder,
onSearchChange,
- onFilterChange,
- onFilterAttributeFocus,
- errorMessages,
actions,
- filtersEnabled,
-}: ListFiltersProps) => (
- <>
- {filtersEnabled && }
-
-
- {filtersEnabled ? (
-
- ) : (
-
- errorMessages={errorMessages}
- menu={filterStructure}
- currencySymbol={currencySymbol}
- onFilterAdd={onFilterChange}
- onFilterAttributeFocus={onFilterAttributeFocus}
- />
- )}
-
-
+ ...props
+}: ListFiltersProps) => {
+ const isExpressionFilter = props.type === "expression-filter";
+
+ return (
+ <>
+ {isExpressionFilter && }
+
+
+ {isExpressionFilter ? (
+
+ ) : (
+
+ errorMessages={props.errorMessages}
+ menu={props.filterStructure!}
+ currencySymbol={props.currencySymbol}
+ onFilterAdd={props.onFilterChange!}
+ onFilterAttributeFocus={props.onFilterAttributeFocus}
+ />
+ )}
+
+
+
+
+
+ {actions}
-
- {actions}
-
-
- >
-);
+ >
+ );
+};
ListFilters.displayName = "FilterBar";
diff --git a/src/components/AppLayout/ListFilters/components/ExpressionFilters.tsx b/src/components/AppLayout/ListFilters/components/ExpressionFilters.tsx
index fe956223c19..59bcca6f8c0 100644
--- a/src/components/AppLayout/ListFilters/components/ExpressionFilters.tsx
+++ b/src/components/AppLayout/ListFilters/components/ExpressionFilters.tsx
@@ -10,7 +10,7 @@ import { useIntl } from "react-intl";
export const ExpressionFilters = () => {
const { formatMessage } = useIntl();
const { valueProvider, containerState, filterWindow } = useConditionalFilterContext();
- const clickOutside = () => {
+ const clearEmpty = () => {
containerState.clearEmpty();
};
@@ -23,7 +23,7 @@ export const ExpressionFilters = () => {
})}
-
+
{
{formatMessage(conditionalFilterMessages.popoverTitle)}
- } />
+ } onClick={clearEmpty} />
diff --git a/src/components/AppLayout/TopNav/Root.tsx b/src/components/AppLayout/TopNav/Root.tsx
index 93e0ac5ce2b..4108f0962b9 100644
--- a/src/components/AppLayout/TopNav/Root.tsx
+++ b/src/components/AppLayout/TopNav/Root.tsx
@@ -4,11 +4,13 @@ import React, { PropsWithChildren } from "react";
import useAppChannel from "../AppChannelContext";
import AppChannelSelect from "../AppChannelSelect";
+import { ContextualLine } from "../ContextualLinks/ContextualLine";
import { TopNavLink } from "./TopNavLink";
import { TopNavWrapper } from "./TopNavWrapper";
interface TopNavProps {
title: string | React.ReactNode;
+ subtitle?: React.ReactNode;
href?: string;
withoutBorder?: boolean;
isAlignToRight?: boolean;
@@ -16,6 +18,7 @@ interface TopNavProps {
export const Root: React.FC> = ({
title,
+ subtitle,
href,
withoutBorder = false,
isAlignToRight = true,
@@ -26,21 +29,33 @@ export const Root: React.FC> = ({
const channels = user?.user?.accessibleChannels ?? [];
return (
-
- {href && }
-
- {title}
-
-
- {isPickerActive && channels.length > 0 && (
-
- )}
- {children}
+
+
+ {href && }
+
+ {title}
+
+
+ {isPickerActive && channels.length > 0 && (
+
+ )}
+ {children}
+
+ {subtitle ? (
+
+ {subtitle}
+
+ ) : null}
);
};
diff --git a/src/components/AppLayout/TopNav/TopNavWrapper.tsx b/src/components/AppLayout/TopNav/TopNavWrapper.tsx
index fe9be9840ee..b53be6702c4 100644
--- a/src/components/AppLayout/TopNav/TopNavWrapper.tsx
+++ b/src/components/AppLayout/TopNav/TopNavWrapper.tsx
@@ -1,14 +1,14 @@
import { Box } from "@saleor/macaw-ui-next";
import React from "react";
-import { topBarHeight } from "../consts";
+import { topBarHeight, topBarHeightSubtitle } from "../consts";
-export const TopNavWrapper: React.FC<{ withoutBorder?: boolean }> = ({
- children,
- withoutBorder,
-}) => (
+export const TopNavWrapper: React.FC<{
+ withoutBorder?: boolean;
+ hasSubtitle?: boolean;
+}> = ({ children, withoutBorder, hasSubtitle }) => (
= ({
borderColor="default1"
position="relative"
data-test-id="page-header"
- __height={topBarHeight}
+ __height={hasSubtitle ? topBarHeightSubtitle : topBarHeight}
gridColumn="8"
gridRowStart="1"
backgroundColor="default1"
diff --git a/src/components/AppLayout/consts.ts b/src/components/AppLayout/consts.ts
index bcc8ade0419..0b8c59648d4 100644
--- a/src/components/AppLayout/consts.ts
+++ b/src/components/AppLayout/consts.ts
@@ -1,4 +1,5 @@
export const topBarHeight = "77px";
+export const topBarHeightSubtitle = "120px";
export const appLoaderHeight = 2;
export const savebarHeight = "64px";
export const borderHeight = "1px";
diff --git a/src/components/AssignAttributeDialog/AssignAttributeDialog.tsx b/src/components/AssignAttributeDialog/AssignAttributeDialog.tsx
index 94f2a8224c9..d9452b787bb 100644
--- a/src/components/AssignAttributeDialog/AssignAttributeDialog.tsx
+++ b/src/components/AssignAttributeDialog/AssignAttributeDialog.tsx
@@ -1,31 +1,20 @@
// @ts-strict-ignore
import Checkbox from "@dashboard/components/Checkbox";
import { ConfirmButton, ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
+import { InfiniteScroll } from "@dashboard/components/InfiniteScroll";
+import { DashboardModal } from "@dashboard/components/Modal";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
import TableRowLink from "@dashboard/components/TableRowLink";
import { AvailableAttributeFragment } from "@dashboard/graphql";
-import useElementScroll, { isScrolledToBottom } from "@dashboard/hooks/useElementScroll";
import useModalDialogErrors from "@dashboard/hooks/useModalDialogErrors";
import useModalDialogOpen from "@dashboard/hooks/useModalDialogOpen";
import useSearchQuery from "@dashboard/hooks/useSearchQuery";
import { maybe, renderCollection } from "@dashboard/misc";
import { FetchMoreProps } from "@dashboard/types";
-import {
- CircularProgress,
- Dialog,
- DialogActions,
- DialogContent,
- DialogContentText,
- DialogTitle,
- TableBody,
- TableCell,
- TextField,
- Typography,
-} from "@material-ui/core";
+import { CircularProgress, TableBody, TableCell, TextField } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
-import clsx from "clsx";
+import { Box, Text } from "@saleor/macaw-ui-next";
import React from "react";
-import InfiniteScroll from "react-infinite-scroll-component";
import { FormattedMessage, useIntl } from "react-intl";
import BackButton from "../BackButton";
@@ -33,18 +22,9 @@ import { messages } from "./messages";
const useStyles = makeStyles(
theme => ({
- actions: {
- boxShadow: "0px 4px 4px rgba(0, 0, 0, 0.25)",
- },
checkboxCell: {
paddingLeft: 0,
},
- dialogPaper: {
- overflow: "hidden",
- },
- dropShadow: {
- boxShadow: `0px -5px 10px 0px ${theme.palette.divider}`,
- },
loadMoreLoaderContainer: {
alignItems: "center",
display: "flex",
@@ -52,17 +32,6 @@ const useStyles = makeStyles(
height: theme.spacing(3),
justifyContent: "center",
},
- searchArea: {
- marginBottom: theme.spacing(3),
- overflowY: "hidden",
- paddingBottom: theme.spacing(6),
- },
- scrollArea: {
- maxHeight: 700,
- overflowY: "scroll",
- paddingTop: 0,
- marginBottom: theme.spacing(3),
- },
wideCell: {
width: "100%",
},
@@ -103,8 +72,6 @@ const AssignAttributeDialog: React.FC = ({
const classes = useStyles({});
const [query, onQueryChange, resetQuery] = useSearchQuery(onFetch);
const errors = useModalDialogErrors(apiErrors, open);
- const anchor = React.useRef(null);
- const position = useElementScroll(anchor);
useModalDialogOpen(open, {
onClose: resetQuery,
@@ -112,19 +79,12 @@ const AssignAttributeDialog: React.FC = ({
});
return (
-
-
-
-
-
+
+
+
+
+
+
= ({
endAdornment: loading && ,
}}
/>
-
-
+
-
-
- }
scrollableTarget={scrollableTargetId}
>
@@ -172,7 +127,9 @@ const AssignAttributeDialog: React.FC = ({
{attribute.name}
- {attribute.slug}
+
+ {attribute.slug}
+
);
@@ -189,32 +146,29 @@ const AssignAttributeDialog: React.FC = ({
-
- {errors.length > 0 && (
-
- {errors.map((error, errorIndex) => (
-
- {error}
-
- ))}
-
- )}
-
-
-
-
-
-
-
+
+
+ {errors.length > 0 &&
+ errors.map((error, errorIndex) => (
+
+ {error}
+
+ ))}
+
+
+
+
+
+
+
+
+
+
);
};
diff --git a/src/components/AssignContainerDialog/AssignContainerDialog.tsx b/src/components/AssignContainerDialog/AssignContainerDialog.tsx
index 63065afbd32..e3a3447be80 100644
--- a/src/components/AssignContainerDialog/AssignContainerDialog.tsx
+++ b/src/components/AssignContainerDialog/AssignContainerDialog.tsx
@@ -1,21 +1,12 @@
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
+import { InfiniteScroll } from "@dashboard/components/InfiniteScroll";
+import { DashboardModal } from "@dashboard/components/Modal";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
import TableRowLink from "@dashboard/components/TableRowLink";
import useSearchQuery from "@dashboard/hooks/useSearchQuery";
-import useScrollableDialogStyle from "@dashboard/styles/useScrollableDialogStyle";
import { DialogProps, FetchMoreProps, Node } from "@dashboard/types";
-import {
- CircularProgress,
- Dialog,
- DialogActions,
- DialogContent,
- DialogTitle,
- TableBody,
- TableCell,
- TextField,
-} from "@material-ui/core";
+import { CircularProgress, TableBody, TableCell, TextField } from "@material-ui/core";
import React from "react";
-import InfiniteScroll from "react-infinite-scroll-component";
import BackButton from "../BackButton";
import Checkbox from "../Checkbox";
@@ -70,7 +61,6 @@ const AssignContainerDialog: React.FC = props => {
onSubmit,
} = props;
const classes = useStyles(props);
- const scrollableDialogClasses = useScrollableDialogStyle({});
const [query, onQueryChange, queryReset] = useSearchQuery(onFetch);
const [selectedContainers, setSelectedContainers] = React.useState([]);
const handleSubmit = () => onSubmit(selectedContainers);
@@ -80,15 +70,10 @@ const AssignContainerDialog: React.FC = props => {
};
return (
-
- {labels.title}
-
+
+
+ {labels.title}
+
= props => {
endAdornment: loading && ,
}}
/>
-
-
+
-
-
- }
scrollableTarget={scrollableTargetId}
>
@@ -146,19 +126,20 @@ const AssignContainerDialog: React.FC = props => {
-
-
-
-
- {labels.confirmBtn}
-
-
-
+
+
+
+
+ {labels.confirmBtn}
+
+
+
+
);
};
diff --git a/src/components/AssignProductDialog/AssignProductDialog.tsx b/src/components/AssignProductDialog/AssignProductDialog.tsx
index 35cf33ea3dc..e7fbec90e70 100644
--- a/src/components/AssignProductDialog/AssignProductDialog.tsx
+++ b/src/components/AssignProductDialog/AssignProductDialog.tsx
@@ -1,26 +1,17 @@
// @ts-strict-ignore
import { ConfirmButton, ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
+import { InfiniteScroll } from "@dashboard/components/InfiniteScroll";
+import { DashboardModal } from "@dashboard/components/Modal";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
import TableCellAvatar from "@dashboard/components/TableCellAvatar";
import TableRowLink from "@dashboard/components/TableRowLink";
import useModalDialogOpen from "@dashboard/hooks/useModalDialogOpen";
import useSearchQuery from "@dashboard/hooks/useSearchQuery";
import { maybe } from "@dashboard/misc";
-import useScrollableDialogStyle from "@dashboard/styles/useScrollableDialogStyle";
import { DialogProps, FetchMoreProps } from "@dashboard/types";
-import {
- CircularProgress,
- Dialog,
- DialogActions,
- DialogContent,
- DialogTitle,
- TableBody,
- TableCell,
- TextField,
-} from "@material-ui/core";
+import { CircularProgress, TableBody, TableCell, TextField } from "@material-ui/core";
import { Text } from "@saleor/macaw-ui-next";
import React, { useEffect } from "react";
-import InfiniteScroll from "react-infinite-scroll-component";
import { FormattedMessage, useIntl } from "react-intl";
import { Container } from "../AssignContainerDialog";
@@ -64,7 +55,6 @@ const AssignProductDialog: React.FC = props => {
selectedIds,
} = props;
const classes = useStyles(props);
- const scrollableDialogClasses = useScrollableDialogStyle({});
const intl = useIntl();
const [query, onQueryChange, queryReset] = useSearchQuery(onFetch);
const [productsDict, setProductsDict] = React.useState(selectedIds || {});
@@ -113,17 +103,12 @@ const AssignProductDialog: React.FC = props => {
};
return (
-
-
-
-
-
+
+
+
+
+
+
= props => {
endAdornment: loading && ,
}}
/>
-
-
+
-
-
- }
scrollableTarget={scrollableTargetId}
>
@@ -190,19 +170,20 @@ const AssignProductDialog: React.FC = props => {
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
);
};
diff --git a/src/components/AssignProductDialog/utils.test.ts b/src/components/AssignProductDialog/utils.test.ts
index 03c96b45f27..a5831b5c161 100644
--- a/src/components/AssignProductDialog/utils.test.ts
+++ b/src/components/AssignProductDialog/utils.test.ts
@@ -2,7 +2,7 @@ import { ProductChannels, SelectedChannel } from "./types";
import { isProductAvailableInVoucherChannels } from "./utils";
describe("isProductAvailableInVoucherChannels", () => {
- it("should return trun when product has at least one channel common with voucher", () => {
+ it("should return true when product has at least one channel common with voucher", () => {
// Arrange
const mockProductChannels = [
{ channel: { id: "1" } },
@@ -83,4 +83,16 @@ describe("isProductAvailableInVoucherChannels", () => {
// Assert
expect(result).toBe(true);
});
+
+ it("should return false when no products channels", () => {
+ // Arrange
+ const mockProductChannels = undefined;
+ const mockVariantChannels = [] as SelectedChannel[];
+
+ // Act
+ const result = isProductAvailableInVoucherChannels(mockProductChannels, mockVariantChannels);
+
+ // Assert
+ expect(result).toBe(false);
+ });
});
diff --git a/src/components/AssignProductDialog/utils.ts b/src/components/AssignProductDialog/utils.ts
index 9b5da570fa0..b7ef4807af8 100644
--- a/src/components/AssignProductDialog/utils.ts
+++ b/src/components/AssignProductDialog/utils.ts
@@ -1,13 +1,19 @@
import { ProductChannels, SelectedChannel } from "./types";
export const isProductAvailableInVoucherChannels = (
- productChannels: ProductChannels,
+ productChannels?: ProductChannels,
selectedChannels?: SelectedChannel[],
) => {
+ // If there are no selected channels, the product is available in all channels
if (!selectedChannels) {
return true;
}
+ // If there are no product channels, the product is not available in any channel
+ if (!productChannels) {
+ return false;
+ }
+
const selectedChannelsIds = selectedChannels.map(chan => chan.id);
const productChannelsIds = productChannels.map(chan => chan.channel.id);
diff --git a/src/components/AssignVariantDialog/AssignVariantDialog.tsx b/src/components/AssignVariantDialog/AssignVariantDialog.tsx
index 7e6d299e6aa..e36c2466526 100644
--- a/src/components/AssignVariantDialog/AssignVariantDialog.tsx
+++ b/src/components/AssignVariantDialog/AssignVariantDialog.tsx
@@ -1,5 +1,7 @@
// @ts-strict-ignore
import { ConfirmButton, ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
+import { InfiniteScroll } from "@dashboard/components/InfiniteScroll";
+import { DashboardModal } from "@dashboard/components/Modal";
import Money from "@dashboard/components/Money";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
import TableCellAvatar from "@dashboard/components/TableCellAvatar";
@@ -7,21 +9,10 @@ import TableRowLink from "@dashboard/components/TableRowLink";
import { SearchProductsQuery } from "@dashboard/graphql";
import useSearchQuery from "@dashboard/hooks/useSearchQuery";
import { maybe, renderCollection } from "@dashboard/misc";
-import useScrollableDialogStyle from "@dashboard/styles/useScrollableDialogStyle";
import { DialogProps, FetchMoreProps, RelayToFlat } from "@dashboard/types";
-import {
- CircularProgress,
- Dialog,
- DialogActions,
- DialogContent,
- DialogTitle,
- TableBody,
- TableCell,
- TextField,
- Typography,
-} from "@material-ui/core";
+import { CircularProgress, TableBody, TableCell, TextField } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
-import InfiniteScroll from "react-infinite-scroll-component";
import { FormattedMessage, useIntl } from "react-intl";
import { Container } from "../AssignContainerDialog";
@@ -64,7 +55,6 @@ const AssignVariantDialog: React.FC = props => {
onSubmit,
} = props;
const classes = useStyles(props);
- const scrollableDialogClasses = useScrollableDialogStyle({});
const intl = useIntl();
const [query, onQueryChange, queryReset] = useSearchQuery(onFetch);
const [variants, setVariants] = React.useState([]);
@@ -90,17 +80,12 @@ const AssignVariantDialog: React.FC = props => {
};
return (
-
-
-
-
-
+
+
+
+
+
+
= props => {
endAdornment: loading && ,
}}
/>
-
-
+
-
-
- }
scrollableTarget={scrollableTargetId}
>
@@ -199,29 +179,30 @@ const AssignVariantDialog: React.FC = props => {
),
() => (
-
+
{query
? intl.formatMessage(messages.noProductsInQuery)
: intl.formatMessage(messages.noProductsInChannel)}
-
+
),
)}
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
);
};
diff --git a/src/components/AttributeUnassignDialog/AttributeUnassignDialog.tsx b/src/components/AttributeUnassignDialog/AttributeUnassignDialog.tsx
index 8a5b552a9e7..1c58edb78af 100644
--- a/src/components/AttributeUnassignDialog/AttributeUnassignDialog.tsx
+++ b/src/components/AttributeUnassignDialog/AttributeUnassignDialog.tsx
@@ -1,6 +1,5 @@
import ActionDialog from "@dashboard/components/ActionDialog";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
-import { DialogContentText } from "@material-ui/core";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -36,15 +35,13 @@ const AttributeUnassignDialog: React.FC = ({
title={title}
confirmButtonLabel={intl.formatMessage(messages.confirmBtn)}
>
-
- {attributeName},
- itemTypeName: {itemTypeName} ,
- }}
- />
-
+ {attributeName},
+ itemTypeName: {itemTypeName} ,
+ }}
+ />
);
};
diff --git a/src/components/Attributes/AttributeRow.tsx b/src/components/Attributes/AttributeRow.tsx
index 019137bb97e..a211d5327fa 100644
--- a/src/components/Attributes/AttributeRow.tsx
+++ b/src/components/Attributes/AttributeRow.tsx
@@ -14,6 +14,7 @@ import {
getReferenceDisplayValue,
getSingleChoices,
getSingleDisplayValue,
+ getTruncatedTextValue,
} from "@dashboard/components/Attributes/utils";
import FileUploadField from "@dashboard/components/FileUploadField";
import RichTextEditor from "@dashboard/components/RichTextEditor";
@@ -130,26 +131,40 @@ const AttributeRow: React.FC = ({
fetchMoreAttributeValues={fetchMoreAttributeValues}
/>
);
- case AttributeInputTypeEnum.PLAIN_TEXT:
+ case AttributeInputTypeEnum.PLAIN_TEXT: {
+ // Since the API doesn't enforce a limit for plain text attribute length, we need to set one here. If we don't, the dashboard will freeze when the user tries to display a product with a long attribute value.
+ const MAX_LENGTH = 10000; // This is an arbitrary number. Dashboard will still work with a higher number, but it gets significantly slower.
+ const attributeValue = attribute.value[0];
+ const isTooLong = attributeValue?.length > MAX_LENGTH;
+
+ const value = isTooLong ? getTruncatedTextValue(attributeValue, MAX_LENGTH) : attributeValue;
+
return (
onChange(attribute.id, event.target.value)}
type="text"
- value={attribute.value[0]}
+ value={value}
size="small"
id={`attribute:${attribute.label}`}
- helperText={getErrorMessage(error, intl)}
+ helperText={
+ isTooLong
+ ? intl.formatMessage(inputTypeMessages.plainTextTruncated, {
+ length: MAX_LENGTH,
+ })
+ : getErrorMessage(error, intl)
+ }
/>
);
+ }
case AttributeInputTypeEnum.RICH_TEXT: {
const { getShouldMount, getDefaultValue, getMountEditor, getHandleChange } = richTextGetters;
const defaultValue = getDefaultValue(attribute.id);
diff --git a/src/components/Attributes/utils.test.ts b/src/components/Attributes/utils.test.ts
new file mode 100644
index 00000000000..376b8fe2676
--- /dev/null
+++ b/src/components/Attributes/utils.test.ts
@@ -0,0 +1,23 @@
+import { getTruncatedTextValue } from "./utils";
+
+describe("getTruncatedTextValue", () => {
+ it("should truncate the value if it is longer than the specified length", () => {
+ expect(getTruncatedTextValue("Hello, world!", 5)).toBe("Hello...");
+ });
+
+ it("should return the value if it is shorter than the specified length", () => {
+ expect(getTruncatedTextValue("Hello", 10)).toBe("Hello");
+ });
+
+ it("should return the value if it is exactly the specified length", () => {
+ expect(getTruncatedTextValue("Hello", 5)).toBe("Hello");
+ });
+
+ it("should return the value if it is empty", () => {
+ expect(getTruncatedTextValue("", 5)).toBe("");
+ });
+
+ it("should return the value if it is undefined", () => {
+ expect(getTruncatedTextValue(undefined, 5)).toBe(undefined);
+ });
+});
diff --git a/src/components/Attributes/utils.ts b/src/components/Attributes/utils.ts
index 748421d33d2..6b01683cee2 100644
--- a/src/components/Attributes/utils.ts
+++ b/src/components/Attributes/utils.ts
@@ -1,8 +1,6 @@
// @ts-strict-ignore
import { AttributeInput } from "@dashboard/components/Attributes/Attributes";
import { FileChoiceType } from "@dashboard/components/FileUploadField";
-import { MultiAutocompleteChoiceType } from "@dashboard/components/MultiAutocompleteSelectField";
-import { SingleAutocompleteChoiceType } from "@dashboard/components/SingleAutocompleteSelectField";
import { SortableChipsFieldValueType } from "@dashboard/components/SortableChipsField";
import {
AttributeValueFragment,
@@ -12,9 +10,10 @@ import {
import { getProductErrorMessage } from "@dashboard/utils/errors";
import getPageErrorMessage from "@dashboard/utils/errors/page";
import { OutputData } from "@editorjs/editorjs";
+import { Option } from "@saleor/macaw-ui-next";
import { IntlShape } from "react-intl";
-export function getSingleChoices(values: AttributeValueFragment[]): SingleAutocompleteChoiceType[] {
+export function getSingleChoices(values: AttributeValueFragment[]): Option[] {
return values.map(value => ({
label: value.name,
value: value.slug,
@@ -90,7 +89,7 @@ export function getReferenceDisplayValue(attribute: AttributeInput): SortableChi
});
}
-export function getMultiChoices(values: AttributeValueFragment[]): MultiAutocompleteChoiceType[] {
+export function getMultiChoices(values: AttributeValueFragment[]): Option[] {
return values.map(value => ({
label: value.name,
value: value.slug,
@@ -112,7 +111,7 @@ export function getSingleDisplayValue(
export function getMultiDisplayValue(
attribute: AttributeInput,
attributeValues: AttributeValueFragment[],
-): MultiAutocompleteChoiceType[] {
+): Option[] {
if (!attribute.value) {
return [];
}
@@ -184,3 +183,11 @@ export function getBooleanDropdownOptions(intl: IntlShape) {
},
];
}
+
+export function getTruncatedTextValue(value: string | undefined, length: number) {
+ if (!value) {
+ return value;
+ }
+
+ return value.length > length ? value.slice(0, length) + "..." : value;
+}
diff --git a/src/components/AutocompleteSelectMenu/AutocompleteSelectMenu.test.tsx b/src/components/AutocompleteSelectMenu/AutocompleteSelectMenu.test.tsx
deleted file mode 100644
index 3b969d20b78..00000000000
--- a/src/components/AutocompleteSelectMenu/AutocompleteSelectMenu.test.tsx
+++ /dev/null
@@ -1,119 +0,0 @@
-import { IMenu } from "@dashboard/utils/menu";
-import { fireEvent, render, waitFor } from "@testing-library/react";
-import React from "react";
-import { IntlProvider } from "react-intl";
-
-import AutocompleteSelectMenu from "./AutocompleteSelectMenu";
-
-describe("AutocompleteSelectMenu", () => {
- const mockOnChange = jest.fn();
- const mockOnInputChange = jest.fn();
-
- const defaultProps = {
- disabled: false,
- displayValue: "Test",
- error: false,
- helperText: "Helper text",
- label: "Link",
- loading: false,
- name: "id",
- options: [
- {
- label: "Option 1",
- children: [
- {
- label: "Option 1 Child",
- data: {},
- children: [],
- },
- ],
- data: {},
- },
- {
- label: "Option 2",
- children: [
- {
- label: "Option 2 Child",
- data: {},
- children: [],
- },
- ],
-
- data: {},
- },
- {
- label: "Option 3",
- data: {},
- children: [
- {
- label: "Option 3 Child",
- data: {},
- children: [],
- },
- {
- label: "Option 3 Child 2",
- data: {},
- children: [],
- },
- ],
- },
- ] as IMenu,
- placeholder: "Start typing to begin search...",
- onChange: mockOnChange,
- onInputChange: mockOnInputChange,
- testIds: ["1", "2", "3", "4"],
- };
-
- it("renders without crashing", () => {
- // Arrange & Act
- const { container } = render( );
-
- // Assert
- expect(container).toBeInTheDocument();
- });
-
- it("renders the input field", () => {
- // Arrange & Act
- const { getByPlaceholderText } = render( );
- const input = getByPlaceholderText(defaultProps.placeholder);
-
- // Assert
- expect(input).toBeInTheDocument();
- });
-
- it("calls onInputChange when typing in the input field", async () => {
- // Arrange
- const { getByPlaceholderText } = render( );
- const input = getByPlaceholderText(defaultProps.placeholder);
-
- // Act
- fireEvent.change(input, { target: { value: "Option 2" } });
-
- // Assert
- await waitFor(() => {
- expect(mockOnInputChange).toHaveBeenCalledWith("Option 2");
- });
- });
-
- it("shows inner list when option is selected", async () => {
- // Arrange
- const { getByPlaceholderText, getByText } = render(
-
-
- ,
- );
- const input = getByPlaceholderText(defaultProps.placeholder);
-
- // Act
- fireEvent.focus(input);
-
- const option = getByText("Option 1");
-
- fireEvent.click(option);
-
- // Assert
- await waitFor(() => {
- expect(getByText("Option 1 Child")).toBeInTheDocument();
- });
- });
-});
diff --git a/src/components/AutocompleteSelectMenu/AutocompleteSelectMenu.tsx b/src/components/AutocompleteSelectMenu/AutocompleteSelectMenu.tsx
deleted file mode 100644
index b18c07a893a..00000000000
--- a/src/components/AutocompleteSelectMenu/AutocompleteSelectMenu.tsx
+++ /dev/null
@@ -1,176 +0,0 @@
-// @ts-strict-ignore
-import { buttonMessages } from "@dashboard/intl";
-import { CircularProgress, MenuItem, Paper, TextField } from "@material-ui/core";
-import ArrowBack from "@material-ui/icons/ArrowBack";
-import { makeStyles } from "@saleor/macaw-ui";
-import Downshift from "downshift";
-import React from "react";
-import { FormattedMessage } from "react-intl";
-
-import { getMenuItemByPath, IMenu, validateMenuOptions } from "../../utils/menu";
-import Debounce, { DebounceProps } from "../Debounce";
-
-export interface AutocompleteSelectMenuProps {
- disabled: boolean;
- displayValue: string;
- error: boolean;
- helperText: string;
- label: string;
- loading: boolean;
- name: string;
- options: IMenu;
- testIds?: string[];
- placeholder: string;
- onChange: (event: React.ChangeEvent) => void;
- onInputChange?: (value: string) => void;
-}
-
-const validationError: Error = new Error(
- "Values supplied to AutocompleteSelectMenu should be unique",
-);
-const DebounceAutocomplete: React.ComponentType> = Debounce;
-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: {},
- }),
- { name: "AutocompleteSelectMenu" },
-);
-const AutocompleteSelectMenu: React.FC = props => {
- const {
- disabled,
- displayValue,
- error,
- helperText,
- label,
- loading,
- name,
- options,
- testIds,
- placeholder,
- onChange,
- onInputChange,
- } = props;
- const classes = useStyles(props);
- const [isFocused, setIsFocused] = React.useState(false);
- const [inputValue, setInputValue] = React.useState(displayValue || "");
- const [menuPath, setMenuPath] = React.useState([]);
- const handleChange = (value: string) =>
- onChange({
- target: {
- name,
- value,
- },
- } as any);
-
- // Validate if option values are duplicated
- React.useEffect(() => {
- if (!validateMenuOptions(options)) {
- throw validationError;
- }
- }, []);
- // Navigate back to main menu after input field change
- React.useEffect(() => setMenuPath([]), [options]);
- // Reset input value after displayValue change
- React.useEffect(() => setInputValue(displayValue), [displayValue]);
-
- const menuOptions = getMenuItemByPath(options, menuPath);
-
- return (
-
- {debounceFn => (
-
- {({ getItemProps, isOpen, openMenu, closeMenu, selectItem }) => (
-
-
,
- id: undefined,
- onBlur() {
- setIsFocused(false);
- closeMenu();
- setMenuPath([]);
- setInputValue(displayValue || "");
- debounceFn("");
- },
- onChange: event => {
- debounceFn(event.target.value);
- setInputValue(event.target.value);
- },
- onFocus: () => {
- openMenu();
- setIsFocused(true);
- },
- placeholder,
- }}
- disabled={disabled}
- error={error}
- helperText={helperText}
- label={label}
- fullWidth={true}
- value={inputValue}
- />
- {isOpen && (
-
- {options.length ? (
- <>
- {menuPath.length > 0 && (
- setMenuPath(menuPath.slice(0, menuPath.length - 2))}
- >
-
-
-
- )}
- {(menuOptions ? menuOptions.children : options).map((suggestion, index) => (
-
- suggestion.value
- ? selectItem(suggestion.value)
- : setMenuPath([...menuPath, index])
- }
- >
- {suggestion.label}
-
- ))}
- >
- ) : (
-
-
-
- )}
-
- )}
-
- )}
-
- )}
-
- );
-};
-
-AutocompleteSelectMenu.displayName = "AutocompleteSelectMenu";
-export default AutocompleteSelectMenu;
diff --git a/src/components/AutocompleteSelectMenu/index.ts b/src/components/AutocompleteSelectMenu/index.ts
deleted file mode 100644
index a49ff0536f4..00000000000
--- a/src/components/AutocompleteSelectMenu/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from "./AutocompleteSelectMenu";
-export * from "./AutocompleteSelectMenu";
diff --git a/src/components/BulkAttributeUnassignDialog/BulkAttributeUnassignDialog.tsx b/src/components/BulkAttributeUnassignDialog/BulkAttributeUnassignDialog.tsx
index e1656e56747..e472d9cae05 100644
--- a/src/components/BulkAttributeUnassignDialog/BulkAttributeUnassignDialog.tsx
+++ b/src/components/BulkAttributeUnassignDialog/BulkAttributeUnassignDialog.tsx
@@ -1,6 +1,5 @@
import ActionDialog from "@dashboard/components/ActionDialog";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
-import { DialogContentText } from "@material-ui/core";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -36,16 +35,14 @@ const BulkAttributeUnassignDialog: React.FC =
title={title}
confirmButtonLabel={intl.formatMessage(messages.confirmBtn)}
>
-
- {attributeQuantity},
- counter: attributeQuantity,
- itemTypeName: {itemTypeName} ,
- }}
- />
-
+ {attributeQuantity},
+ counter: attributeQuantity,
+ itemTypeName: {itemTypeName} ,
+ }}
+ />
);
};
diff --git a/src/components/ButtonWithLoader/ButtonWithLoader.test.tsx b/src/components/ButtonWithLoader/ButtonWithLoader.test.tsx
new file mode 100644
index 00000000000..7f243e478a9
--- /dev/null
+++ b/src/components/ButtonWithLoader/ButtonWithLoader.test.tsx
@@ -0,0 +1,58 @@
+import { fireEvent, render, screen } from "@testing-library/react";
+import React from "react";
+
+import { ButtonWithLoader } from "./ButtonWithLoader";
+
+jest.mock("react-intl", () => ({
+ useIntl: jest.fn(() => ({
+ formatMessage: jest.fn(x => x.defaultMessage),
+ })),
+ defineMessages: jest.fn(x => x),
+ FormattedMessage: ({ defaultMessage }: { defaultMessage: string }) => <>{defaultMessage}>,
+}));
+
+describe("ButtonWithLoader", () => {
+ it("should render a button with confirm label", () => {
+ // Arrange & Act
+ render(Confirm );
+ // Assert
+ expect(screen.getByRole("button")).toBeInTheDocument();
+ expect(screen.getByRole("button")).toHaveTextContent("Confirm");
+ });
+
+ it("should render a button with loading spinner", () => {
+ // Arrange & Act
+ render( );
+ // Assert
+ expect(screen.getByRole("button")).toBeInTheDocument();
+ expect(screen.getByTestId("button-progress")).toBeInTheDocument();
+ });
+
+ it("should call onClick when clicked", () => {
+ // Arrange
+ const onClick = jest.fn();
+
+ // Act
+ render( );
+ fireEvent.click(screen.getByRole("button"));
+
+ // Assert
+ expect(onClick).toHaveBeenCalled();
+ });
+
+ it("should render original label after loading state", async () => {
+ // Arrange & Act
+ const { rerender } = render(
+ Confirm ,
+ );
+
+ // Assert
+ expect(screen.getByTestId("button-progress")).toBeInTheDocument();
+
+ // Act
+ rerender(Confirm );
+
+ // Assert
+ expect(screen.queryByTestId("button-progress")).not.toBeInTheDocument();
+ });
+});
diff --git a/src/components/ButtonWithLoader/ButtonWithLoader.tsx b/src/components/ButtonWithLoader/ButtonWithLoader.tsx
new file mode 100644
index 00000000000..5d217bce58a
--- /dev/null
+++ b/src/components/ButtonWithLoader/ButtonWithLoader.tsx
@@ -0,0 +1,56 @@
+import { buttonMessages } from "@dashboard/intl";
+import { Box, Button, ButtonProps, Spinner, sprinkles } from "@saleor/macaw-ui-next";
+import React from "react";
+import { useIntl } from "react-intl";
+
+import { ConfirmButtonTransitionState } from "../ConfirmButton";
+
+interface ButtonWithLoaderProps extends ButtonProps {
+ transitionState: ConfirmButtonTransitionState;
+}
+
+export const ButtonWithLoader = ({
+ transitionState,
+ onClick,
+ disabled,
+ children,
+ ...props
+}: ButtonWithLoaderProps) => {
+ const intl = useIntl();
+ const isLoading = transitionState === "loading";
+
+ const renderSpinner = () => {
+ if (isLoading) {
+ return (
+
+
+
+ );
+ }
+
+ return null;
+ };
+
+ const getByLabelText = () => {
+ return children || intl.formatMessage(buttonMessages.save);
+ };
+
+ return (
+
+ {renderSpinner()}
+
+ {getByLabelText()}
+
+
+ );
+};
diff --git a/src/components/Card/Actions.tsx b/src/components/Card/Actions.tsx
new file mode 100644
index 00000000000..849f3735e2b
--- /dev/null
+++ b/src/components/Card/Actions.tsx
@@ -0,0 +1,24 @@
+import { Box, PropsWithBox } from "@saleor/macaw-ui-next";
+import React from "react";
+
+export const Actions: React.FC> = ({
+ children,
+ className,
+ style,
+ ...rest
+}) => (
+
+ {children}
+
+);
diff --git a/src/components/Card/Content.tsx b/src/components/Card/Content.tsx
index 570b373103e..7b173143841 100644
--- a/src/components/Card/Content.tsx
+++ b/src/components/Card/Content.tsx
@@ -1,7 +1,10 @@
-import { Box, Sprinkles } from "@saleor/macaw-ui-next";
+import { Box, PropsWithBox } from "@saleor/macaw-ui-next";
import React from "react";
-export const Content: React.FC = ({ children, ...rest }) => (
+export const Content: React.FC> = ({
+ children,
+ ...rest
+}) => (
{children}
diff --git a/src/components/Card/Header.tsx b/src/components/Card/Header.tsx
new file mode 100644
index 00000000000..991734ad845
--- /dev/null
+++ b/src/components/Card/Header.tsx
@@ -0,0 +1,21 @@
+import { Box, PropsWithBox } from "@saleor/macaw-ui-next";
+import React from "react";
+
+export const Header: React.FC> = ({
+ children,
+ className,
+ ...rest
+}) => (
+
+ {children}
+
+);
diff --git a/src/components/Card/Root.tsx b/src/components/Card/Root.tsx
index 6b06fb44315..09c283e897b 100644
--- a/src/components/Card/Root.tsx
+++ b/src/components/Card/Root.tsx
@@ -1,8 +1,11 @@
-import { Box, Sprinkles } from "@saleor/macaw-ui-next";
+import { Box, PropsWithBox } from "@saleor/macaw-ui-next";
import React from "react";
-export const Root: React.FC = ({ children, ...rest }) => (
-
+export const Root: React.FC> = ({
+ children,
+ ...rest
+}) => (
+
{children}
);
diff --git a/src/components/Card/Subtitle.tsx b/src/components/Card/Subtitle.tsx
new file mode 100644
index 00000000000..29bee2cb42c
--- /dev/null
+++ b/src/components/Card/Subtitle.tsx
@@ -0,0 +1,13 @@
+import { Sprinkles, Text } from "@saleor/macaw-ui-next";
+import React, { PropsWithChildren } from "react";
+
+type CardSubtitleProps = Sprinkles;
+
+export const CardSubtitle: React.FC> = ({
+ children,
+ ...rest
+}) => (
+
+ {children}
+
+);
diff --git a/src/components/Card/Title.tsx b/src/components/Card/Title.tsx
index ea441b111d6..0fee1acb911 100644
--- a/src/components/Card/Title.tsx
+++ b/src/components/Card/Title.tsx
@@ -1,14 +1,8 @@
-import { Box, Sprinkles, Text } from "@saleor/macaw-ui-next";
-import React from "react";
+import { Text, TextProps } from "@saleor/macaw-ui-next";
+import React, { PropsWithChildren } from "react";
-interface TitleProps {
- paddingX?: Sprinkles["paddingX"];
-}
-
-export const Title: React.FC = ({ children, paddingX }) => (
-
-
- {children}
-
-
+export const Title: React.FC> = ({ children, ...rest }) => (
+
+ {children}
+
);
diff --git a/src/components/Card/Toolbar.tsx b/src/components/Card/Toolbar.tsx
new file mode 100644
index 00000000000..50e06b669d6
--- /dev/null
+++ b/src/components/Card/Toolbar.tsx
@@ -0,0 +1,11 @@
+import { Box, PropsWithBox } from "@saleor/macaw-ui-next";
+import React from "react";
+
+export const Toolbar: React.FC> = ({
+ children,
+ ...rest
+}) => (
+
+ {children}
+
+);
diff --git a/src/components/Card/index.ts b/src/components/Card/index.ts
index bf4f342a9f8..76824fd7b6b 100644
--- a/src/components/Card/index.ts
+++ b/src/components/Card/index.ts
@@ -1,5 +1,16 @@
+import { Actions as BottomActions } from "./Actions";
import { Content } from "./Content";
+import { Header } from "./Header";
import { Root } from "./Root";
+import { CardSubtitle as Subtitle } from "./Subtitle";
import { Title } from "./Title";
+import { Toolbar } from "./Toolbar";
-export const DashboardCard = Object.assign(Root, { Title, Content });
+export const DashboardCard = Object.assign(Root, {
+ Title,
+ Content,
+ BottomActions,
+ Subtitle,
+ Header,
+ Toolbar,
+});
diff --git a/src/components/CardMenu/CardMenu.tsx b/src/components/CardMenu/CardMenu.tsx
index bf1c296309b..6d3b73c660d 100644
--- a/src/components/CardMenu/CardMenu.tsx
+++ b/src/components/CardMenu/CardMenu.tsx
@@ -7,9 +7,9 @@ import {
MenuList,
Paper,
Popper,
- Typography,
} from "@material-ui/core";
import { IconButtonProps, makeStyles, SettingsIcon } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React, { useEffect, useRef, useState } from "react";
import { FormattedMessage } from "react-intl";
@@ -185,15 +185,15 @@ const CardMenu: React.FC = props => {
>
{menuItem.loading ? (
<>
-
+
-
+
>
) : (
-
+
{showMenuIcon && menuItem.Icon} {menuItem.label}
-
+
)}
diff --git a/src/components/ChannelsAvailabilityCard/Channel/ChannelAvailabilityItemContent.tsx b/src/components/ChannelsAvailabilityCard/Channel/ChannelAvailabilityItemContent.tsx
index c2461f78fd5..1931f97417f 100644
--- a/src/components/ChannelsAvailabilityCard/Channel/ChannelAvailabilityItemContent.tsx
+++ b/src/components/ChannelsAvailabilityCard/Channel/ChannelAvailabilityItemContent.tsx
@@ -1,11 +1,11 @@
// @ts-strict-ignore
import { ChannelData } from "@dashboard/channels/utils";
import { DateTimeTimezoneField } from "@dashboard/components/DateTimeTimezoneField";
-import { RadioGroup } from "@dashboard/components/RadioGroup";
+import { StopPropagation } from "@dashboard/components/StopPropagation";
import useCurrentDate from "@dashboard/hooks/useCurrentDate";
import useDateLocalize from "@dashboard/hooks/useDateLocalize";
import { getFormErrors, getProductErrorMessage } from "@dashboard/utils/errors";
-import { Box, Checkbox, Divider, Text } from "@saleor/macaw-ui-next";
+import { Box, Checkbox, Divider, RadioGroup, Text } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import { useIntl } from "react-intl";
@@ -56,41 +56,48 @@ export const ChannelAvailabilityItemContent: React.FC = ({
return (
- {
- onChange(id, {
- ...formData,
- isPublished: value === "true",
- publishedAt: value === "false" ? null : publishedAt,
- });
- }}
- disabled={disabled}
- display="flex"
- flexDirection="column"
- gap={3}
- >
-
-
- {messages.visibleLabel}
- {isPublished && publishedAt && Date.parse(publishedAt) < dateNow && (
-
- {messages.visibleSecondLabel || visibleMessage(publishedAt)}
-
- )}
-
-
-
-
- {messages.hiddenLabel}
- {publishedAt && !isPublished && Date.parse(publishedAt) >= dateNow && (
-
- {messages.hiddenSecondLabel}
-
- )}
-
-
-
+ {/**
+ * StopPropagation is used here to block onClick events from RadioGroup that cause throw error in datagrid
+ * Datagrid listing for all on click event but RadioGroup emitted couple of events at once
+ * Radix issue: https://github.com/radix-ui/primitives/issues/1982
+ */}
+
+ {
+ onChange(id, {
+ ...formData,
+ isPublished: value === "true",
+ publishedAt: value === "false" ? null : publishedAt,
+ });
+ }}
+ disabled={disabled}
+ display="flex"
+ flexDirection="column"
+ gap={3}
+ >
+
+
+ {messages.visibleLabel}
+ {isPublished && publishedAt && Date.parse(publishedAt) < dateNow && (
+
+ {messages.visibleSecondLabel || visibleMessage(publishedAt)}
+
+ )}
+
+
+
+
+ {messages.hiddenLabel}
+ {publishedAt && !isPublished && Date.parse(publishedAt) >= dateNow && (
+
+ {messages.hiddenSecondLabel}
+
+ )}
+
+
+
+
{!isPublished && (
= props => {
>
{channels
? channels.map(data => {
- const channelErrors = errors?.filter(error => error.channels.includes(data.id)) || [];
+ const channelErrors = errors?.filter(error => error.channels?.includes(data.id)) || [];
return (
diff --git a/src/components/ChannelsAvailabilityCard/ChannelsAvailabilityCardWrapper.tsx b/src/components/ChannelsAvailabilityCard/ChannelsAvailabilityCardWrapper.tsx
index baa16ea3fbd..c00703c8544 100644
--- a/src/components/ChannelsAvailabilityCard/ChannelsAvailabilityCardWrapper.tsx
+++ b/src/components/ChannelsAvailabilityCard/ChannelsAvailabilityCardWrapper.tsx
@@ -34,22 +34,23 @@ export const ChannelsAvailabilityCardWrapper: React.FC<
return (
-
-
-
-
- {intl.formatMessage({
- id: "5A6/2C",
- defaultMessage: "Availability",
- description: "section header",
- })}
-
+
+
+ {intl.formatMessage({
+ id: "5A6/2C",
+ defaultMessage: "Availability",
+ description: "section header",
+ })}
+
+
{!!channelsAvailabilityText && (
{channelsAvailabilityText}
)}
-
+
+
+
-
-
+
+
{children}
diff --git a/src/components/ChannelsAvailabilityContent/ChannelsAvailabilityContent.tsx b/src/components/ChannelsAvailabilityContent/ChannelsAvailabilityContent.tsx
index f0c5878479b..949411ffe91 100644
--- a/src/components/ChannelsAvailabilityContent/ChannelsAvailabilityContent.tsx
+++ b/src/components/ChannelsAvailabilityContent/ChannelsAvailabilityContent.tsx
@@ -2,7 +2,8 @@ import { Channel } from "@dashboard/channels/utils";
import { ControlledCheckbox } from "@dashboard/components/ControlledCheckbox";
import Hr from "@dashboard/components/Hr";
import { fuzzySearch } from "@dashboard/misc";
-import { TextField, Typography } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -40,13 +41,13 @@ export const ChannelsAvailabilityContent: React.FC
{!!contentType && (
-
+
-
+
)}
+
-
+
)
}
onChange={() => toggleAll(channels, selected)}
@@ -75,9 +76,9 @@ export const ChannelsAvailabilityContent: React.FC
>
)}
-
+
-
+
{option.name}}
+ label={
{option.name} }
onChange={() => onChange(option)}
/>
diff --git a/src/components/ChannelsAvailabilityDialog/NoChannels.tsx b/src/components/ChannelsAvailabilityDialog/NoChannels.tsx
index 4548bf71aa0..990ec95ad03 100644
--- a/src/components/ChannelsAvailabilityDialog/NoChannels.tsx
+++ b/src/components/ChannelsAvailabilityDialog/NoChannels.tsx
@@ -1,11 +1,11 @@
-import { Typography } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage } from "react-intl";
import { channelsAvailabilityDialogMessages as messages } from "./messages";
export const NoChannels = () => (
-
+
-
+
);
diff --git a/src/components/ChannelsAvailabilityDialogChannelsList/ChannelsAvailabilityDialogChannelsList.tsx b/src/components/ChannelsAvailabilityDialogChannelsList/ChannelsAvailabilityDialogChannelsList.tsx
index c11449b5209..a9b90acbf1c 100644
--- a/src/components/ChannelsAvailabilityDialogChannelsList/ChannelsAvailabilityDialogChannelsList.tsx
+++ b/src/components/ChannelsAvailabilityDialogChannelsList/ChannelsAvailabilityDialogChannelsList.tsx
@@ -1,8 +1,8 @@
import { Channel } from "@dashboard/channels/utils";
import { ControlledCheckbox } from "@dashboard/components/ControlledCheckbox";
import Hr from "@dashboard/components/Hr";
-import { Typography } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
export const useStyles = makeStyles(
@@ -42,7 +42,7 @@ const ChannelsAvailabilityContent: React.FC
=
{option.name}}
+ label={{option.name} }
onChange={() => onChange(option)}
/>
diff --git a/src/components/ChannelsAvailabilityDialogWrapper/ChannelsAvailabilityDialogWrapper.tsx b/src/components/ChannelsAvailabilityDialogWrapper/ChannelsAvailabilityDialogWrapper.tsx
index b6d56d78e54..4db1c06d31a 100644
--- a/src/components/ChannelsAvailabilityDialogWrapper/ChannelsAvailabilityDialogWrapper.tsx
+++ b/src/components/ChannelsAvailabilityDialogWrapper/ChannelsAvailabilityDialogWrapper.tsx
@@ -1,8 +1,10 @@
import { ControlledCheckbox } from "@dashboard/components/ControlledCheckbox";
import Hr from "@dashboard/components/Hr";
import Label from "@dashboard/orders/components/OrderHistory/Label";
-import { TextField, Typography } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
+import clsx from "clsx";
import React from "react";
import { defineMessages, FormattedMessage, useIntl } from "react-intl";
@@ -31,10 +33,6 @@ export const useStyles = makeStyles(
paddingBottom: theme.spacing(2),
},
scrollArea: {
- maxHeight: "calc(100vh - 400px)",
- "@media (min-height: 800px)": {
- maxHeight: 400,
- },
overflowY: "scroll",
overflowX: "hidden",
// overflowX can't be "visible" when overflowY is "scroll"
@@ -105,9 +103,9 @@ export const ChannelsAvailabilityContentWrapper: React.FC
{!!contentType && (
-
+
-
+
)}
>
)}
-
+
-
+
{hasAnyChannelsToDisplay ? (
diff --git a/src/components/ChannelsAvailabilityDropdown/ChannelsAvailabilityDropdown.tsx b/src/components/ChannelsAvailabilityDropdown/ChannelsAvailabilityDropdown.tsx
index 32a8363bcf0..95f04898f01 100644
--- a/src/components/ChannelsAvailabilityDropdown/ChannelsAvailabilityDropdown.tsx
+++ b/src/components/ChannelsAvailabilityDropdown/ChannelsAvailabilityDropdown.tsx
@@ -1,8 +1,9 @@
// @ts-strict-ignore
-import { Card, Popper } from "@material-ui/core";
+import { Popper } from "@material-ui/core";
import React from "react";
import { useIntl } from "react-intl";
+import { DashboardCard } from "../Card";
import ChannelsAvailabilityMenuContent from "../ChannelsAvailabilityMenuContent";
import { Pill } from "../Pill";
import { messages } from "./messages";
@@ -44,9 +45,9 @@ export const ChannelsAvailabilityDropdown: React.FC
-
+
-
+
);
diff --git a/src/components/ChannelsAvailabilityMenuContent/ChannelsAvailabilityMenuContent.tsx b/src/components/ChannelsAvailabilityMenuContent/ChannelsAvailabilityMenuContent.tsx
index 421c0507246..f3506f4c1f8 100644
--- a/src/components/ChannelsAvailabilityMenuContent/ChannelsAvailabilityMenuContent.tsx
+++ b/src/components/ChannelsAvailabilityMenuContent/ChannelsAvailabilityMenuContent.tsx
@@ -2,8 +2,8 @@
import HorizontalSpacer from "@dashboard/components/HorizontalSpacer";
import { CollectionFragment } from "@dashboard/graphql";
import ScrollableContent from "@dashboard/plugins/components/PluginsList/PluginAvailabilityStatusPopup/ScrollableContent";
-import { Typography } from "@material-ui/core";
import { PillColor } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { MessageDescriptor, useIntl } from "react-intl";
@@ -29,17 +29,17 @@ export const ChannelsAvailabilityMenuContent: React.FC
-
+
{intl.formatMessage(messages.channel)}
-
-
+
+
{intl.formatMessage(messages.status)}
-
+
{pills.map(pill => (
-
{pill.channel.name}
+
{pill.channel.name}
diff --git a/src/components/Chip/Chip.tsx b/src/components/Chip/Chip.tsx
index 5559aadde5b..d2a3105f147 100644
--- a/src/components/Chip/Chip.tsx
+++ b/src/components/Chip/Chip.tsx
@@ -1,7 +1,7 @@
-import { Typography } from "@material-ui/core";
import { alpha } from "@material-ui/core/styles";
import CloseIcon from "@material-ui/icons/Close";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
@@ -38,10 +38,10 @@ const Chip: React.FC = props => {
return (
-
+
{label}
{onClose && }
-
+
);
};
diff --git a/src/components/CompanyAddressInput/CompanyAddressForm.tsx b/src/components/CompanyAddressInput/CompanyAddressForm.tsx
index 0e4cab46c17..9786d06cd2b 100644
--- a/src/components/CompanyAddressInput/CompanyAddressForm.tsx
+++ b/src/components/CompanyAddressInput/CompanyAddressForm.tsx
@@ -170,6 +170,7 @@ const CompanyAddressForm: React.FC = props => {
= props => {
{isFieldAllowed("countryArea") && (
= props => {
return (
- {header}
+
+ {header}
+
diff --git a/src/components/ConditionalFilter/API/Handler.ts b/src/components/ConditionalFilter/API/Handler.ts
index 9566a68e960..f4cd517120b 100644
--- a/src/components/ConditionalFilter/API/Handler.ts
+++ b/src/components/ConditionalFilter/API/Handler.ts
@@ -12,19 +12,34 @@ import {
_GetCollectionsChoicesDocument,
_GetCollectionsChoicesQuery,
_GetCollectionsChoicesQueryVariables,
+ _GetCustomersChoicesDocument,
+ _GetCustomersChoicesQuery,
+ _GetCustomersChoicesQueryVariables,
_GetDynamicLeftOperandsDocument,
_GetDynamicLeftOperandsQuery,
_GetDynamicLeftOperandsQueryVariables,
+ _GetGiftCardTagsChoicesDocument,
+ _GetGiftCardTagsChoicesQuery,
+ _GetGiftCardTagsChoicesQueryVariables,
_GetLegacyChannelOperandsDocument,
+ _GetPageTypesChoicesDocument,
+ _GetPageTypesChoicesQuery,
+ _GetPageTypesChoicesQueryVariables,
+ _GetProductChoicesDocument,
+ _GetProductChoicesQuery,
+ _GetProductChoicesQueryVariables,
_GetProductTypesChoicesDocument,
_GetProductTypesChoicesQuery,
_GetProductTypesChoicesQueryVariables,
+ ChannelCurrenciesDocument,
+ ChannelCurrenciesQuery,
+ ChannelCurrenciesQueryVariables,
} from "@dashboard/graphql";
import { IntlShape } from "react-intl";
import { ItemOption } from "../FilterElement/ConditionValue";
import { LeftOperand } from "../LeftOperandsProvider";
-import { getLocalizedLabel } from "./initialState/orders/intl";
+import { getLocalizedLabel } from "./intl";
export interface Handler {
fetch: () => Promise;
@@ -47,6 +62,25 @@ export const createOptionsFromAPI = (
originalSlug: node.originalSlug,
}));
+export const createCustomerOptionsFromAPI = (
+ data: Array<{
+ node: {
+ id: string;
+ email: string;
+ firstName: string;
+ lastName: string;
+ };
+ }>,
+) => {
+ return (
+ data.map(({ node }) => ({
+ label: node?.firstName && node?.lastName ? `${node.firstName} ${node.lastName}` : node.email,
+ value: node.id,
+ slug: node.id,
+ })) ?? []
+ );
+};
+
export class AttributeChoicesHandler implements Handler {
constructor(
public client: ApolloClient,
@@ -94,6 +128,33 @@ export class CollectionHandler implements Handler {
};
}
+export class CurrencyHandler implements Handler {
+ constructor(
+ public client: ApolloClient,
+ public query: string,
+ ) {}
+
+ fetch = async () => {
+ const { data } = await this.client.query<
+ ChannelCurrenciesQuery,
+ ChannelCurrenciesQueryVariables
+ >({
+ query: ChannelCurrenciesDocument,
+ variables: {},
+ });
+
+ return data.shop.channelCurrencies
+ .map(currency => ({
+ label: currency,
+ value: currency,
+ slug: currency,
+ }))
+ .filter(({ label }) => {
+ return label.toLowerCase().includes(this.query.toLowerCase());
+ });
+ };
+}
+
export class CategoryHandler implements Handler {
constructor(
public client: ApolloClient,
@@ -138,6 +199,56 @@ export class ProductTypeHandler implements Handler {
};
}
+export class ProductsHandler implements Handler {
+ constructor(
+ public client: ApolloClient,
+ public query: string,
+ ) {}
+
+ fetch = async () => {
+ const { data } = await this.client.query<
+ _GetProductChoicesQuery,
+ _GetProductChoicesQueryVariables
+ >({
+ query: _GetProductChoicesDocument,
+ variables: {
+ first: 5,
+ query: this.query,
+ },
+ });
+
+ return createOptionsFromAPI(data.products?.edges ?? []);
+ };
+}
+
+export class GiftCardTagsHandler implements Handler {
+ constructor(
+ public client: ApolloClient,
+ public query: string,
+ ) {}
+
+ fetch = async () => {
+ const { data } = await this.client.query<
+ _GetGiftCardTagsChoicesQuery,
+ _GetGiftCardTagsChoicesQueryVariables
+ >({
+ query: _GetGiftCardTagsChoicesDocument,
+ variables: {
+ first: 5,
+ query: this.query,
+ },
+ });
+
+ return (
+ data?.giftCardTags?.edges.map(({ node }) => ({
+ label: node.name,
+ value: node.name,
+ slug: node.name,
+ })) ?? []
+ );
+ };
+}
+
export class ChannelHandler implements Handler {
constructor(
public client: ApolloClient,
@@ -163,6 +274,28 @@ export class ChannelHandler implements Handler {
};
}
+export class CustomerHandler implements Handler {
+ constructor(
+ public client: ApolloClient,
+ public query: string,
+ ) {}
+
+ fetch = async () => {
+ const { data } = await this.client.query<
+ _GetCustomersChoicesQuery,
+ _GetCustomersChoicesQueryVariables
+ >({
+ query: _GetCustomersChoicesDocument,
+ variables: {
+ first: 5,
+ query: this.query,
+ },
+ });
+
+ return createCustomerOptionsFromAPI(data.customers?.edges ?? []);
+ };
+}
+
// 'Orders' filter required channel ID, not slug
export class LegacyChannelHandler implements Handler {
constructor(
@@ -269,4 +402,26 @@ export class TextInputValuesHandler implements Handler {
};
}
+export class PageTypesHandler implements Handler {
+ constructor(
+ public client: ApolloClient,
+ public query: string,
+ ) {}
+
+ fetch = async () => {
+ const { data } = await this.client.query<
+ _GetPageTypesChoicesQuery,
+ _GetPageTypesChoicesQueryVariables
+ >({
+ query: _GetPageTypesChoicesDocument,
+ variables: {
+ first: 5,
+ query: this.query,
+ },
+ });
+
+ return createOptionsFromAPI(data.pageTypes?.edges ?? []);
+ };
+}
+
export const NoopValuesHandler = TextInputValuesHandler;
diff --git a/src/components/ConditionalFilter/API/index.ts b/src/components/ConditionalFilter/API/index.ts
deleted file mode 100644
index ff44d0671a5..00000000000
--- a/src/components/ConditionalFilter/API/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./initialState";
diff --git a/src/components/ConditionalFilter/API/initialState/attributes/InitialAttributesState.test.ts b/src/components/ConditionalFilter/API/initialState/attributes/InitialAttributesState.test.ts
new file mode 100644
index 00000000000..ce8b17fc227
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/attributes/InitialAttributesState.test.ts
@@ -0,0 +1,202 @@
+import { UrlEntry, UrlToken } from "../../../ValueProvider/UrlToken";
+import { InitialAttributesStateResponse } from "./InitialAttributesState";
+
+describe("ConditionalFilter / API / Page / InitialAttributesState", () => {
+ it("should filter by channel", () => {
+ // Arrange
+ const initialAttributesState = InitialAttributesStateResponse.empty();
+
+ initialAttributesState.channels = [
+ {
+ label: "Channel 1",
+ value: "channel-1",
+ slug: "channel-1",
+ },
+ {
+ label: "Channel 2",
+ value: "channel-2",
+ slug: "channel-2",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.channel", "channel-1"));
+ const expectedOutput = [
+ {
+ label: "Channel 1",
+ value: "channel-1",
+ slug: "channel-1",
+ },
+ ];
+
+ // Act
+ const result = initialAttributesState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by attributeType", () => {
+ // Arrange
+ const initialAttributesState = InitialAttributesStateResponse.empty();
+
+ initialAttributesState.attributeTypes = [
+ {
+ label: "Attribute Type 1",
+ value: "attr-1",
+ slug: "attr-1",
+ },
+ {
+ label: "Attribute Type 2",
+ value: "attr-2",
+ slug: "attr-2",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.attributeType", "attr-2"));
+ const expectedOutput = [
+ {
+ label: "Attribute Type 2",
+ value: "attr-2",
+ slug: "attr-2",
+ },
+ ];
+
+ // Act
+ const result = initialAttributesState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by filterableInStorefront", () => {
+ // Arrange
+ const initialAttributesState = InitialAttributesStateResponse.empty();
+
+ initialAttributesState.filterableInStorefront = [
+ {
+ label: "Yes",
+ value: "true",
+ slug: "true",
+ },
+ {
+ label: "No",
+ value: "false",
+ slug: "false",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.filterableInStorefront", "false"));
+ const expectedOutput = [
+ {
+ label: "No",
+ value: "false",
+ slug: "false",
+ },
+ ];
+
+ // Act
+ const result = initialAttributesState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by isVariantOnly", () => {
+ // Arrange
+ const initialAttributesState = InitialAttributesStateResponse.empty();
+
+ initialAttributesState.isVariantOnly = [
+ {
+ label: "Yes",
+ value: "true",
+ slug: "true",
+ },
+ {
+ label: "No",
+ value: "false",
+ slug: "false",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.isVariantOnly", "false"));
+ const expectedOutput = [
+ {
+ label: "No",
+ value: "false",
+ slug: "false",
+ },
+ ];
+
+ // Act
+ const result = initialAttributesState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by valueRequired", () => {
+ // Arrange
+ const initialAttributesState = InitialAttributesStateResponse.empty();
+
+ initialAttributesState.valueRequired = [
+ {
+ label: "Yes",
+ value: "true",
+ slug: "true",
+ },
+ {
+ label: "No",
+ value: "false",
+ slug: "false",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.valueRequired", "false"));
+ const expectedOutput = [
+ {
+ label: "No",
+ value: "false",
+ slug: "false",
+ },
+ ];
+
+ // Act
+ const result = initialAttributesState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by visibleInStorefront", () => {
+ // Arrange
+ const initialAttributesState = InitialAttributesStateResponse.empty();
+
+ initialAttributesState.visibleInStorefront = [
+ {
+ label: "Yes",
+ value: "true",
+ slug: "true",
+ },
+ {
+ label: "No",
+ value: "false",
+ slug: "false",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.visibleInStorefront", "false"));
+ const expectedOutput = [
+ {
+ label: "No",
+ value: "false",
+ slug: "false",
+ },
+ ];
+
+ // Act
+ const result = initialAttributesState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
diff --git a/src/components/ConditionalFilter/API/initialState/attributes/InitialAttributesState.ts b/src/components/ConditionalFilter/API/initialState/attributes/InitialAttributesState.ts
new file mode 100644
index 00000000000..71d4a203804
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/attributes/InitialAttributesState.ts
@@ -0,0 +1,55 @@
+import { ItemOption } from "../../../FilterElement/ConditionValue";
+import { UrlToken } from "../../../ValueProvider/UrlToken";
+
+export interface InitialAttributesState {
+ channels: ItemOption[];
+ attributeTypes: ItemOption[];
+ filterableInStorefront: ItemOption[];
+ isVariantOnly: ItemOption[];
+ valueRequired: ItemOption[];
+ visibleInStorefront: ItemOption[];
+}
+
+export class InitialAttributesStateResponse implements InitialAttributesState {
+ constructor(
+ public channels: ItemOption[] = [],
+ public attributeTypes: ItemOption[] = [],
+ public filterableInStorefront: ItemOption[] = [],
+ public isVariantOnly: ItemOption[] = [],
+ public valueRequired: ItemOption[] = [],
+ public visibleInStorefront: ItemOption[] = [],
+ ) {}
+
+ public static empty() {
+ return new InitialAttributesStateResponse();
+ }
+
+ public filterByUrlToken(token: UrlToken) {
+ const entry = this.getEntryByName(token.name);
+
+ if (!token.isLoadable()) {
+ return [token.value] as string[];
+ }
+
+ return (entry as ItemOption[]).filter(({ slug }) => slug && token.value.includes(slug));
+ }
+
+ private getEntryByName(name: string): ItemOption[] {
+ switch (name) {
+ case "channel":
+ return this.channels;
+ case "attributeType":
+ return this.attributeTypes;
+ case "filterableInStorefront":
+ return this.filterableInStorefront;
+ case "isVariantOnly":
+ return this.isVariantOnly;
+ case "valueRequired":
+ return this.valueRequired;
+ case "visibleInStorefront":
+ return this.visibleInStorefront;
+ default:
+ return [];
+ }
+ }
+}
diff --git a/src/components/ConditionalFilter/API/initialState/attributes/useInitialAttributesState.ts b/src/components/ConditionalFilter/API/initialState/attributes/useInitialAttributesState.ts
new file mode 100644
index 00000000000..eb7ce6a671d
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/attributes/useInitialAttributesState.ts
@@ -0,0 +1,74 @@
+import { useApolloClient } from "@apollo/client";
+import {
+ _GetChannelOperandsDocument,
+ _GetChannelOperandsQuery,
+ _GetChannelOperandsQueryVariables,
+ AttributeTypeEnum,
+} from "@dashboard/graphql";
+import { useState } from "react";
+import { useIntl } from "react-intl";
+
+import { AttributesFetchingParams } from "../../../ValueProvider/TokenArray/fetchingParams";
+import { EnumValuesHandler } from "../../Handler";
+import { createInitialAttributeState } from "../helpers";
+import { InitialAttributesAPIResponse } from "../types";
+import { InitialAttributesStateResponse } from "./InitialAttributesState";
+
+export interface InitialAttributesAPIState {
+ data: InitialAttributesStateResponse;
+ loading: boolean;
+ fetchQueries: (params: AttributesFetchingParams) => Promise;
+}
+
+export const useInitialAttributesState = (): InitialAttributesAPIState => {
+ const client = useApolloClient();
+ const intl = useIntl();
+ const [data, setData] = useState(
+ InitialAttributesStateResponse.empty(),
+ );
+ const [loading, setLoading] = useState(true);
+
+ const queriesToRun: Array> = [];
+
+ const fetchQueries = async ({ channel, attributeType }: AttributesFetchingParams) => {
+ if (channel.length > 0) {
+ queriesToRun.push(
+ client.query<_GetChannelOperandsQuery, _GetChannelOperandsQueryVariables>({
+ query: _GetChannelOperandsDocument,
+ }),
+ );
+ }
+
+ const attributeTypeInit = new EnumValuesHandler(
+ AttributeTypeEnum,
+ "attributeType",
+ intl,
+ attributeType,
+ );
+
+ const data = await Promise.all(queriesToRun);
+
+ const initialState = {
+ ...createInitialAttributeState(data),
+ attributeType: await attributeTypeInit.fetch(),
+ };
+
+ setData(
+ new InitialAttributesStateResponse(
+ initialState.channels,
+ initialState.attributeType,
+ initialState.filterableInStorefront,
+ initialState.isVariantOnly,
+ initialState.valueRequired,
+ initialState.visibleInStorefront,
+ ),
+ );
+ setLoading(false);
+ };
+
+ return {
+ data,
+ loading,
+ fetchQueries,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/initialState/collections/InitialCollectionState.test.ts b/src/components/ConditionalFilter/API/initialState/collections/InitialCollectionState.test.ts
new file mode 100644
index 00000000000..a960a0bd633
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/collections/InitialCollectionState.test.ts
@@ -0,0 +1,72 @@
+import { CollectionPublished } from "@dashboard/graphql";
+
+import { UrlEntry, UrlToken } from "../../../ValueProvider/UrlToken";
+import { InitialCollectionStateResponse } from "./InitialCollectionState";
+
+describe("ConditionalFilter / API / Page / InitialCollectionStateResponse", () => {
+ it("should filter by channel", () => {
+ // Arrange
+ const initialCollectionState = InitialCollectionStateResponse.empty();
+
+ initialCollectionState.channel = [
+ {
+ label: "Channel 1",
+ value: "chan-1",
+ slug: "chan-1",
+ },
+ {
+ label: "Channel 2",
+ value: "chan-2",
+ slug: "chan-2",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.channel", "chan-1"));
+ const expectedOutput = [
+ {
+ label: "Channel 1",
+ value: "chan-1",
+ slug: "chan-1",
+ },
+ ];
+
+ // Act
+ const result = initialCollectionState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by published", () => {
+ // Arrange
+ const initialCollectionState = InitialCollectionStateResponse.empty();
+
+ initialCollectionState.published = [
+ {
+ label: CollectionPublished.PUBLISHED,
+ value: CollectionPublished.PUBLISHED,
+ slug: CollectionPublished.PUBLISHED,
+ },
+ {
+ label: CollectionPublished.HIDDEN,
+ value: CollectionPublished.HIDDEN,
+ slug: CollectionPublished.HIDDEN,
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.published", "HIDDEN"));
+ const expectedOutput = [
+ {
+ label: CollectionPublished.HIDDEN,
+ value: CollectionPublished.HIDDEN,
+ slug: CollectionPublished.HIDDEN,
+ },
+ ];
+
+ // Act
+ const result = initialCollectionState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
diff --git a/src/components/ConditionalFilter/API/initialState/collections/InitialCollectionState.ts b/src/components/ConditionalFilter/API/initialState/collections/InitialCollectionState.ts
new file mode 100644
index 00000000000..bd063dd54aa
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/collections/InitialCollectionState.ts
@@ -0,0 +1,49 @@
+import { ItemOption } from "@dashboard/components/ConditionalFilter/FilterElement/ConditionValue";
+import { UrlToken } from "@dashboard/components/ConditionalFilter/ValueProvider/UrlToken";
+
+export interface InitialCollectionState {
+ channel: ItemOption[];
+ published: ItemOption[];
+ metadata: ItemOption[];
+}
+
+export class InitialCollectionStateResponse implements InitialCollectionState {
+ constructor(
+ public channel: ItemOption[] = [],
+ public published: ItemOption[] = [],
+ public metadata: ItemOption[] = [],
+ ) {}
+
+ static empty() {
+ return new InitialCollectionStateResponse();
+ }
+
+ public filterByUrlToken(token: UrlToken) {
+ const entry = this.getEntryByName(token.name);
+
+ if (!token.isLoadable()) {
+ return [token.value] as string[];
+ }
+
+ return entry.filter(({ slug }) => {
+ if (Array.isArray(token.value)) {
+ return token.value.includes(slug);
+ }
+
+ return slug === token.value;
+ });
+ }
+
+ private getEntryByName(name: string): ItemOption[] {
+ switch (name) {
+ case "channel":
+ return this.channel;
+ case "published":
+ return this.published;
+ case "metadata":
+ return this.metadata;
+ default:
+ return [];
+ }
+ }
+}
diff --git a/src/components/ConditionalFilter/API/initialState/collections/useInitialCollectionsState.ts b/src/components/ConditionalFilter/API/initialState/collections/useInitialCollectionsState.ts
new file mode 100644
index 00000000000..1b3bdceac5e
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/collections/useInitialCollectionsState.ts
@@ -0,0 +1,59 @@
+import { useApolloClient } from "@apollo/client";
+import { CollectionFetchingParams } from "@dashboard/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams";
+import {
+ _GetChannelOperandsDocument,
+ _GetChannelOperandsQuery,
+ _GetChannelOperandsQueryVariables,
+} from "@dashboard/graphql";
+import { useState } from "react";
+
+import { createInitialCollectionState } from "../helpers";
+import { InitialCollectionAPIResponse } from "../types";
+import { InitialCollectionStateResponse } from "./InitialCollectionState";
+
+export interface InitialCollectionAPIState {
+ data: InitialCollectionStateResponse;
+ loading: boolean;
+ fetchQueries: (params: CollectionFetchingParams) => Promise;
+}
+
+export const useInitialCollectionState = (): InitialCollectionAPIState => {
+ const client = useApolloClient();
+
+ const [data, setData] = useState(
+ InitialCollectionStateResponse.empty(),
+ );
+ const [loading, setLoading] = useState(true);
+
+ const queriesToRun: Array> = [];
+
+ const fetchQueries = async ({ channel }: CollectionFetchingParams) => {
+ if (channel?.length > 0) {
+ queriesToRun.push(
+ client.query<_GetChannelOperandsQuery, _GetChannelOperandsQueryVariables>({
+ query: _GetChannelOperandsDocument,
+ }),
+ );
+ }
+
+ const data = await Promise.all(queriesToRun);
+ const initialState = {
+ ...createInitialCollectionState(data, channel),
+ };
+
+ setData(
+ new InitialCollectionStateResponse(
+ initialState.channel,
+ initialState.published,
+ initialState.metadata,
+ ),
+ );
+ setLoading(false);
+ };
+
+ return {
+ data,
+ loading,
+ fetchQueries,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/initialState/giftCards/InitialGiftCardsState.test.ts b/src/components/ConditionalFilter/API/initialState/giftCards/InitialGiftCardsState.test.ts
new file mode 100644
index 00000000000..6f16ac21f99
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/giftCards/InitialGiftCardsState.test.ts
@@ -0,0 +1,194 @@
+import { UrlEntry, UrlToken } from "../../../ValueProvider/UrlToken";
+import { InitialGiftCardsStateResponse } from "./InitialGiftCardsState";
+
+describe("ConditionalFilter / API / Page / InitialGiftCardsState", () => {
+ it("should filter by currency", () => {
+ // Arrange
+ const initialPageState = InitialGiftCardsStateResponse.empty();
+
+ initialPageState.currency = [
+ {
+ label: "USD",
+ value: "usd",
+ slug: "usd",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.currency", "usd"));
+ const expectedOutput = [
+ {
+ label: "USD",
+ value: "usd",
+ slug: "usd",
+ },
+ ];
+
+ // Act
+ const result = initialPageState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by tags", () => {
+ // Arrange
+ const initialPageState = InitialGiftCardsStateResponse.empty();
+
+ initialPageState.tags = [
+ {
+ label: "Tag 1",
+ value: "tag-1",
+ slug: "tag-1",
+ },
+ {
+ label: "Tag 2",
+ value: "tag-2",
+ slug: "tag-2",
+ },
+ {
+ label: "Tag 3",
+ value: "tag-3",
+ slug: "tag-3",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s2.tags", ["tag-1", "tag-3"]));
+ const expectedOutput = [
+ {
+ label: "Tag 1",
+ value: "tag-1",
+ slug: "tag-1",
+ },
+ {
+ label: "Tag 3",
+ value: "tag-3",
+ slug: "tag-3",
+ },
+ ];
+
+ // Act
+ const result = initialPageState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by products", () => {
+ // Arrange
+ const initialPageState = InitialGiftCardsStateResponse.empty();
+
+ initialPageState.products = [
+ {
+ label: "Product 1",
+ value: "product-1",
+ slug: "product-1",
+ },
+ {
+ label: "Product 2",
+ value: "product-2",
+ slug: "product-2",
+ },
+ {
+ label: "Product 3",
+ value: "product-3",
+ slug: "product-3",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s2.products", ["product-1", "product-3"]));
+ const expectedOutput = [
+ {
+ label: "Product 1",
+ value: "product-1",
+ slug: "product-1",
+ },
+ {
+ label: "Product 3",
+ value: "product-3",
+ slug: "product-3",
+ },
+ ];
+
+ // Act
+ const result = initialPageState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by used by", () => {
+ // Arrange
+ const initialPageState = InitialGiftCardsStateResponse.empty();
+
+ initialPageState.usedBy = [
+ {
+ label: "Customer 1",
+ value: "customer-1",
+ slug: "customer-1",
+ },
+ {
+ label: "Customer 2",
+ value: "customer-2",
+ slug: "customer-2",
+ },
+ {
+ label: "Customer 3",
+ value: "customer-3",
+ slug: "customer-3",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s2.usedBy", ["customer-1", "customer-3"]));
+ const expectedOutput = [
+ {
+ label: "Customer 1",
+ value: "customer-1",
+ slug: "customer-1",
+ },
+ {
+ label: "Customer 3",
+ value: "customer-3",
+ slug: "customer-3",
+ },
+ ];
+
+ // Act
+ const result = initialPageState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by is active", () => {
+ // Arrange
+ const initialPageState = InitialGiftCardsStateResponse.empty();
+
+ initialPageState.isActive = [
+ {
+ label: "Yes",
+ value: "yes",
+ slug: "yes",
+ },
+ {
+ label: "No",
+ value: "no",
+ slug: "no",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s2.isActive", "yes"));
+ const expectedOutput = [
+ {
+ label: "Yes",
+ value: "yes",
+ slug: "yes",
+ },
+ ];
+
+ // Act
+ const result = initialPageState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
diff --git a/src/components/ConditionalFilter/API/initialState/giftCards/InitialGiftCardsState.ts b/src/components/ConditionalFilter/API/initialState/giftCards/InitialGiftCardsState.ts
new file mode 100644
index 00000000000..90c8b94ab51
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/giftCards/InitialGiftCardsState.ts
@@ -0,0 +1,51 @@
+import { ItemOption } from "@dashboard/components/ConditionalFilter/FilterElement/ConditionValue";
+import { UrlToken } from "@dashboard/components/ConditionalFilter/ValueProvider/UrlToken";
+
+export interface InitialGiftCardsState {
+ currency: ItemOption[];
+ products: ItemOption[];
+ isActive: ItemOption[];
+ tags: ItemOption[];
+ usedBy: ItemOption[];
+}
+
+export class InitialGiftCardsStateResponse implements InitialGiftCardsState {
+ constructor(
+ public currency: ItemOption[] = [],
+ public products: ItemOption[] = [],
+ public isActive: ItemOption[] = [],
+ public tags: ItemOption[] = [],
+ public usedBy: ItemOption[] = [],
+ ) {}
+
+ public static empty() {
+ return new InitialGiftCardsStateResponse();
+ }
+
+ public filterByUrlToken(token: UrlToken) {
+ const entry = this.getEntryByName(token.name);
+
+ if (!token.isLoadable()) {
+ return [token.value] as string[];
+ }
+
+ return (entry as ItemOption[]).filter(({ slug }) => slug && token.value.includes(slug));
+ }
+
+ private getEntryByName(name: string): ItemOption[] {
+ switch (name) {
+ case "currency":
+ return this.currency;
+ case "products":
+ return this.products;
+ case "isActive":
+ return this.isActive;
+ case "tags":
+ return this.tags;
+ case "usedBy":
+ return this.usedBy;
+ default:
+ return [];
+ }
+ }
+}
diff --git a/src/components/ConditionalFilter/API/initialState/giftCards/useInitialGiftCardsState.ts b/src/components/ConditionalFilter/API/initialState/giftCards/useInitialGiftCardsState.ts
new file mode 100644
index 00000000000..191128343b0
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/giftCards/useInitialGiftCardsState.ts
@@ -0,0 +1,88 @@
+import { useApolloClient } from "@apollo/client";
+import { createInitialGiftCardsState } from "@dashboard/components/ConditionalFilter/API/initialState/helpers";
+import { InitialGiftCardsAPIResponse } from "@dashboard/components/ConditionalFilter/API/initialState/types";
+import { GiftCardsFetchingParams } from "@dashboard/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams";
+import {
+ _SearchCustomersOperandsDocument,
+ _SearchCustomersOperandsQuery,
+ _SearchCustomersOperandsQueryVariables,
+ _SearchProductOperandsDocument,
+ _SearchProductOperandsQuery,
+ _SearchProductOperandsQueryVariables,
+ ChannelCurrenciesDocument,
+ ChannelCurrenciesQuery,
+ ChannelCurrenciesQueryVariables,
+} from "@dashboard/graphql";
+import { useState } from "react";
+
+import { InitialGiftCardsStateResponse } from "./InitialGiftCardsState";
+
+export interface InitialGiftCardsAPIState {
+ data: InitialGiftCardsStateResponse;
+ loading: boolean;
+ fetchQueries: (params: GiftCardsFetchingParams) => Promise;
+}
+
+export const useInitialGiftCardsState = () => {
+ const client = useApolloClient();
+ const [data, setData] = useState(
+ InitialGiftCardsStateResponse.empty(),
+ );
+ const [loading, setLoading] = useState(true);
+ const queriesToRun: Array> = [];
+
+ const fetchQueries = async ({ usedBy, products, currency, tags }: GiftCardsFetchingParams) => {
+ if (products.length > 0) {
+ queriesToRun.push(
+ client.query<_SearchProductOperandsQuery, _SearchProductOperandsQueryVariables>({
+ query: _SearchProductOperandsDocument,
+ variables: {
+ first: products.length,
+ productsIds: products,
+ },
+ }),
+ );
+ }
+
+ if (usedBy.length > 0) {
+ queriesToRun.push(
+ client.query<_SearchCustomersOperandsQuery, _SearchCustomersOperandsQueryVariables>({
+ query: _SearchCustomersOperandsDocument,
+ variables: {
+ first: usedBy.length,
+ customersIds: usedBy,
+ },
+ }),
+ );
+ }
+
+ if (currency.length > 0) {
+ queriesToRun.push(
+ client.query({
+ query: ChannelCurrenciesDocument,
+ variables: {},
+ }),
+ );
+ }
+
+ const data = await Promise.all(queriesToRun);
+ const initialState = createInitialGiftCardsState(data, tags);
+
+ setData(
+ new InitialGiftCardsStateResponse(
+ initialState.currency,
+ initialState.products,
+ initialState.isActive,
+ initialState.tags,
+ initialState.usedBy,
+ ),
+ );
+ setLoading(false);
+ };
+
+ return {
+ data,
+ loading,
+ fetchQueries,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/initialState/helpers.test.ts b/src/components/ConditionalFilter/API/initialState/helpers.test.ts
index 59b5498d8ad..0499641e48c 100644
--- a/src/components/ConditionalFilter/API/initialState/helpers.test.ts
+++ b/src/components/ConditionalFilter/API/initialState/helpers.test.ts
@@ -7,7 +7,7 @@ import {
_SearchProductTypesOperandsQuery,
} from "@dashboard/graphql";
-import { createInitialStateFromData } from "./helpers";
+import { createInitialProductStateFromData } from "./helpers";
describe("ConditionalFilter / API / createInitialStateFromData", () => {
it("should create initial state from queries", () => {
@@ -99,7 +99,7 @@ describe("ConditionalFilter / API / createInitialStateFromData", () => {
const data = [channelQuery, collectionQuery, categoryQuery, productTypeQuery, attributeQuery];
const channel = ["channel-1"];
// Act
- const result = createInitialStateFromData(data, channel);
+ const result = createInitialProductStateFromData(data, channel);
// Assert
expect(result).toMatchSnapshot();
diff --git a/src/components/ConditionalFilter/API/initialState/helpers.ts b/src/components/ConditionalFilter/API/initialState/helpers.ts
index 258126f9945..d82bd45989b 100644
--- a/src/components/ConditionalFilter/API/initialState/helpers.ts
+++ b/src/components/ConditionalFilter/API/initialState/helpers.ts
@@ -5,36 +5,68 @@ import {
_SearchAttributeOperandsQuery,
_SearchCategoriesOperandsQuery,
_SearchCollectionsOperandsQuery,
+ _SearchCustomersOperandsQuery,
+ _SearchPageTypesOperandsQuery,
+ _SearchProductOperandsQuery,
_SearchProductTypesOperandsQuery,
+ ChannelCurrenciesQuery,
} from "@dashboard/graphql";
import { createBooleanOptions } from "../../constants";
-import { createOptionsFromAPI } from "../Handler";
-import { InitialState } from "../InitialStateResponse";
+import { createCustomerOptionsFromAPI, createOptionsFromAPI } from "../Handler";
+import { InitialAttributesState } from "./attributes/InitialAttributesState";
+import { InitialCollectionState } from "./collections/InitialCollectionState";
+import { InitialGiftCardsState } from "./giftCards/InitialGiftCardsState";
import { InitialOrderState } from "./orders/InitialOrderState";
-import { InitialAPIResponse, InitialOrderAPIResponse } from "./types";
+import { InitialPageState } from "./page/InitialPageState";
+import { InitialProductState } from "./product/InitialProductStateResponse";
+import {
+ InitialAttributesAPIResponse,
+ InitialCollectionAPIResponse,
+ InitialGiftCardsAPIResponse,
+ InitialOrderAPIResponse,
+ InitialPageAPIResponse,
+ InitialProductAPIResponse,
+ InitialVoucherAPIResponse,
+} from "./types";
+import { InitialVouchersState } from "./vouchers/InitialVouchersState";
const isChannelQuery = (
- query: InitialAPIResponse,
+ query: InitialProductAPIResponse,
): query is ApolloQueryResult<_GetChannelOperandsQuery> => "channels" in query.data;
const isChannelsQuery = (
query: InitialOrderAPIResponse,
): query is ApolloQueryResult<_GetLegacyChannelOperandsQuery> => "channels" in query.data;
const isCollectionQuery = (
- query: InitialAPIResponse,
+ query: InitialProductAPIResponse,
): query is ApolloQueryResult<_SearchCollectionsOperandsQuery> => "collections" in query.data;
const isCategoryQuery = (
- query: InitialAPIResponse,
+ query: InitialProductAPIResponse,
): query is ApolloQueryResult<_SearchCategoriesOperandsQuery> => "categories" in query.data;
const isProductTypeQuery = (
- query: InitialAPIResponse,
+ query: InitialProductAPIResponse,
): query is ApolloQueryResult<_SearchProductTypesOperandsQuery> => "productTypes" in query.data;
const isAttributeQuery = (
- query: InitialAPIResponse,
+ query: InitialProductAPIResponse,
): query is ApolloQueryResult<_SearchAttributeOperandsQuery> => "attributes" in query.data;
+const isPageTypesQuery = (
+ query: InitialPageAPIResponse,
+): query is ApolloQueryResult<_SearchPageTypesOperandsQuery> => "pageTypes" in query.data;
+const isCustomerQuery = (
+ query: InitialGiftCardsAPIResponse,
+): query is ApolloQueryResult<_SearchCustomersOperandsQuery> => "customers" in query.data;
+const isProductQuery = (
+ query: InitialGiftCardsAPIResponse,
+): query is ApolloQueryResult<_SearchProductOperandsQuery> => "products" in query.data;
+const isCurrencyQuery = (
+ query: InitialGiftCardsAPIResponse,
+): query is ApolloQueryResult => "shop" in query.data;
-export const createInitialStateFromData = (data: InitialAPIResponse[], channel: string[]) =>
- data.reduce(
+export const createInitialProductStateFromData = (
+ data: InitialProductAPIResponse[],
+ channel: string[],
+) =>
+ data.reduce(
(acc, query) => {
if (isChannelQuery(query)) {
return {
@@ -131,9 +163,141 @@ export const createInitialOrderState = (data: InitialOrderAPIResponse[]) =>
isPreorder: createBooleanOptions(),
giftCardBought: createBooleanOptions(),
giftCardUsed: createBooleanOptions(),
- customer: [],
ids: [],
created: "",
updatedAt: "",
},
);
+
+export const createInitialVoucherState = (data: InitialVoucherAPIResponse[]) =>
+ data.reduce(
+ (acc, query) => {
+ if (isChannelsQuery(query)) {
+ return {
+ ...acc,
+ channels: (query.data?.channels ?? []).map(({ id, name, slug }) => ({
+ label: name,
+ value: id,
+ slug,
+ })),
+ };
+ }
+
+ return acc;
+ },
+ {
+ channels: [],
+ discountType: [],
+ voucherStatus: [],
+ },
+ );
+
+export const createInitialPageState = (data: InitialPageAPIResponse[]) =>
+ data.reduce(
+ (acc, query) => {
+ if (isPageTypesQuery(query)) {
+ return {
+ ...acc,
+ pageTypes: createOptionsFromAPI(query.data?.pageTypes?.edges ?? []),
+ };
+ }
+
+ return acc;
+ },
+ {
+ pageTypes: [],
+ },
+ );
+
+export const createInitialGiftCardsState = (
+ data: InitialGiftCardsAPIResponse[],
+ tags: string[],
+): InitialGiftCardsState => {
+ return data.reduce(
+ (acc, query) => {
+ if (isCustomerQuery(query)) {
+ return {
+ ...acc,
+ usedBy: createCustomerOptionsFromAPI(query.data?.customers?.edges ?? []),
+ };
+ }
+
+ if (isProductQuery(query)) {
+ return {
+ ...acc,
+ products: createOptionsFromAPI(query.data?.products?.edges ?? []),
+ };
+ }
+
+ if (isCurrencyQuery(query)) {
+ return {
+ ...acc,
+ currency: query.data.shop.channelCurrencies.map(currency => ({
+ label: currency,
+ value: currency,
+ slug: currency,
+ })),
+ };
+ }
+
+ return acc;
+ },
+ {
+ currency: [],
+ isActive: createBooleanOptions(),
+ products: [],
+ tags: tags?.map(tag => ({ label: tag, value: tag, slug: tag })) ?? [],
+ usedBy: [],
+ } as InitialGiftCardsState,
+ );
+};
+
+export const createInitialCollectionState = (
+ data: InitialCollectionAPIResponse[],
+ channel: string[],
+) =>
+ data.reduce(
+ (acc, query) => {
+ if (isChannelQuery(query)) {
+ return {
+ ...acc,
+ channel: (query.data?.channels ?? [])
+ .filter(({ slug }) => channel.includes(slug))
+ .map(({ id, name, slug }) => ({ label: name, value: id, slug })),
+ };
+ }
+
+ return acc;
+ },
+ {
+ channel: [],
+ published: createBooleanOptions(),
+ metadata: [],
+ },
+ );
+
+export const createInitialAttributeState = (data: InitialAttributesAPIResponse[]) =>
+ data.reduce(
+ (acc, query) => {
+ if (isChannelsQuery(query)) {
+ return {
+ ...acc,
+ channels: (query.data?.channels ?? []).map(({ id, name, slug }) => ({
+ label: name,
+ value: id,
+ slug,
+ })),
+ };
+ }
+
+ return acc;
+ },
+ {
+ channels: [],
+ attributeTypes: [],
+ filterableInStorefront: createBooleanOptions(),
+ isVariantOnly: createBooleanOptions(),
+ valueRequired: createBooleanOptions(),
+ visibleInStorefront: createBooleanOptions(),
+ },
+ );
diff --git a/src/components/ConditionalFilter/API/initialState/index.ts b/src/components/ConditionalFilter/API/initialState/index.ts
deleted file mode 100644
index 174987ad9f9..00000000000
--- a/src/components/ConditionalFilter/API/initialState/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./useInitialAPIState";
diff --git a/src/components/ConditionalFilter/API/initialState/orders/InitialOrderState.test.ts b/src/components/ConditionalFilter/API/initialState/orders/InitialOrderState.test.ts
index 57da8c0e931..5917383a9ae 100644
--- a/src/components/ConditionalFilter/API/initialState/orders/InitialOrderState.test.ts
+++ b/src/components/ConditionalFilter/API/initialState/orders/InitialOrderState.test.ts
@@ -31,34 +31,6 @@ describe("ConditionalFilter / API / Orders / InitialOrderState", () => {
expect(result).toEqual(expectedOutput);
});
- it("should filter by customer", () => {
- // Arrange
- const initialOrderState = InitialOrderStateResponse.empty();
-
- initialOrderState.customer = [
- {
- label: "Customer",
- slug: "customer",
- value: "test",
- },
- ];
-
- const token = UrlToken.fromUrlEntry(new UrlEntry("s0.customer", "test"));
- const expectedOutput = [
- {
- label: "Customer",
- slug: "customer",
- value: "test",
- },
- ];
-
- // Act
- const result = initialOrderState.filterByUrlToken(token);
-
- // Assert
- expect(result).toEqual(expectedOutput);
- });
-
it("should filter by click and collect", () => {
// Arrange
const initialOrderState = InitialOrderStateResponse.empty();
diff --git a/src/components/ConditionalFilter/API/initialState/orders/InitialOrderState.ts b/src/components/ConditionalFilter/API/initialState/orders/InitialOrderState.ts
index 2f1064274c7..082e2650a03 100644
--- a/src/components/ConditionalFilter/API/initialState/orders/InitialOrderState.ts
+++ b/src/components/ConditionalFilter/API/initialState/orders/InitialOrderState.ts
@@ -11,13 +11,11 @@ export interface InitialOrderState {
isPreorder: ItemOption[];
giftCardBought: ItemOption[];
giftCardUsed: ItemOption[];
- customer: ItemOption[];
created: string | string[];
updatedAt: string | string[];
ids: ItemOption[];
}
-const isTextInput = (name: string) => ["customer"].includes(name);
const isDateField = (name: string) => ["created", "updatedAt"].includes(name);
export class InitialOrderStateResponse implements InitialOrderState {
@@ -31,7 +29,6 @@ export class InitialOrderStateResponse implements InitialOrderState {
public isPreorder: ItemOption[] = [],
public giftCardBought: ItemOption[] = [],
public giftCardUsed: ItemOption[] = [],
- public customer: ItemOption[] = [],
public created: string | string[] = [],
public updatedAt: string | string[] = [],
public ids: ItemOption[] = [],
@@ -48,8 +45,8 @@ export class InitialOrderStateResponse implements InitialOrderState {
const entry = this.getEntryByName(token.name);
- if (isTextInput(token.name)) {
- return entry;
+ if (!token.isLoadable()) {
+ return [token.value] as string[];
}
return (entry as ItemOption[]).filter(({ slug }) => slug && token.value.includes(slug));
@@ -75,8 +72,6 @@ export class InitialOrderStateResponse implements InitialOrderState {
return this.giftCardBought;
case "giftCardUsed":
return this.giftCardUsed;
- case "customer":
- return this.customer;
case "ids":
return this.ids;
default:
diff --git a/src/components/ConditionalFilter/API/initialState/orders/intl.ts b/src/components/ConditionalFilter/API/initialState/orders/intl.ts
deleted file mode 100644
index 7e3d1e2ac82..00000000000
--- a/src/components/ConditionalFilter/API/initialState/orders/intl.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import { LeftOperand } from "@dashboard/components/ConditionalFilter/LeftOperandsProvider";
-import {
- OrderAuthorizeStatusEnum,
- OrderChargeStatusEnum,
- OrderStatusFilter,
- PaymentChargeStatusEnum,
-} from "@dashboard/graphql";
-import { transformOrderStatus, transformPaymentStatus } from "@dashboard/misc";
-import { IntlShape } from "react-intl";
-
-import { authorizeStatusMessages, chargeStatusMessages } from "./messages";
-
-const getPaymentStatusLabel = (status: PaymentChargeStatusEnum, intl: IntlShape) => {
- const { localized } = transformPaymentStatus(status, intl);
-
- return localized;
-};
-
-const getOrderStatusLabel = (status: OrderStatusFilter, intl: IntlShape) => {
- const { localized } = transformOrderStatus(status, intl);
-
- return localized;
-};
-
-const getAuthorizeStatusLabel = (status: OrderAuthorizeStatusEnum, intl: IntlShape) => {
- switch (status) {
- case OrderAuthorizeStatusEnum.FULL:
- return intl.formatMessage(authorizeStatusMessages.full);
- case OrderAuthorizeStatusEnum.PARTIAL:
- return intl.formatMessage(authorizeStatusMessages.partial);
- case OrderAuthorizeStatusEnum.NONE:
- return intl.formatMessage(authorizeStatusMessages.none);
- default:
- return status;
- }
-};
-
-const getChargeStatusLabel = (status: OrderChargeStatusEnum, intl: IntlShape) => {
- switch (status) {
- case OrderChargeStatusEnum.FULL:
- return intl.formatMessage(chargeStatusMessages.full);
- case OrderChargeStatusEnum.PARTIAL:
- return intl.formatMessage(chargeStatusMessages.partial);
- case OrderChargeStatusEnum.OVERCHARGED:
- return intl.formatMessage(chargeStatusMessages.overcharged);
- case OrderChargeStatusEnum.NONE:
- return intl.formatMessage(chargeStatusMessages.none);
- default:
- return status;
- }
-};
-
-export const getLocalizedLabel = (rowType: LeftOperand["type"], value: string, intl: IntlShape) => {
- switch (rowType) {
- case "paymentStatus":
- return getPaymentStatusLabel(value as PaymentChargeStatusEnum, intl);
- case "status":
- return getOrderStatusLabel(value as OrderStatusFilter, intl);
- case "authorizeStatus":
- return getAuthorizeStatusLabel(value as OrderAuthorizeStatusEnum, intl);
- case "chargeStatus":
- return getChargeStatusLabel(value as OrderChargeStatusEnum, intl);
- default:
- return value;
- }
-};
diff --git a/src/components/ConditionalFilter/API/initialState/orders/messages.ts b/src/components/ConditionalFilter/API/initialState/orders/messages.ts
deleted file mode 100644
index 64c9cc632b7..00000000000
--- a/src/components/ConditionalFilter/API/initialState/orders/messages.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { defineMessages } from "react-intl";
-
-export const authorizeStatusMessages = defineMessages({
- full: {
- defaultMessage: "Full",
- id: "F/JMp6",
- description: "authorize status full",
- },
- partial: {
- defaultMessage: "Partial",
- id: "EojeG7",
- description: "authorize status partial",
- },
- none: {
- defaultMessage: "None",
- id: "EoTI4r",
- description: "authorize status none",
- },
-});
-
-export const chargeStatusMessages = defineMessages({
- full: {
- defaultMessage: "Full",
- id: "UIM5bq",
- description: "charge status full",
- },
- partial: {
- defaultMessage: "Partial",
- id: "KPmk40",
- description: "charge status partial",
- },
- overcharged: {
- defaultMessage: "Overcharged",
- id: "ZOamBQ",
- description: "charge status overcharged",
- },
- none: {
- defaultMessage: "None",
- id: "dLIeRH",
- description: "charge status none",
- },
-});
diff --git a/src/components/ConditionalFilter/API/initialState/orders/useInitialOrderState.ts b/src/components/ConditionalFilter/API/initialState/orders/useInitialOrderState.ts
index f24e44349c2..df134647877 100644
--- a/src/components/ConditionalFilter/API/initialState/orders/useInitialOrderState.ts
+++ b/src/components/ConditionalFilter/API/initialState/orders/useInitialOrderState.ts
@@ -17,14 +17,6 @@ import { createInitialOrderState } from "../helpers";
import { InitialOrderAPIResponse } from "../types";
import { InitialOrderStateResponse } from "./InitialOrderState";
-const getCustomer = (customer: string[]) => {
- if (Array.isArray(customer) && customer.length > 0) {
- return customer.at(-1) ?? "";
- }
-
- return "";
-};
-
const mapIDsToOptions = (ids: string[]) =>
ids.map(id => ({
type: "ids",
@@ -53,7 +45,6 @@ export const useInitialOrderState = (): InitialOrderAPIState => {
paymentStatus,
status,
authorizeStatus,
- customer,
ids,
}: OrderFetchingParams) => {
if (channels.length > 0) {
@@ -93,14 +84,6 @@ export const useInitialOrderState = (): InitialOrderAPIState => {
status: await statusInit.fetch(),
authorizeStatus: await authorizeStatusInit.fetch(),
chargeStatus: await chargeStatusInit.fetch(),
- customer: [
- {
- type: "customer",
- label: "Customer",
- value: getCustomer(customer),
- slug: "customer",
- },
- ],
ids: mapIDsToOptions(ids),
};
@@ -115,7 +98,6 @@ export const useInitialOrderState = (): InitialOrderAPIState => {
initialState.isClickAndCollect,
initialState.giftCardBought,
initialState.giftCardUsed,
- initialState.customer,
initialState.created,
initialState.updatedAt,
initialState.ids,
diff --git a/src/components/ConditionalFilter/API/initialState/page/InitialPageState.test.ts b/src/components/ConditionalFilter/API/initialState/page/InitialPageState.test.ts
new file mode 100644
index 00000000000..bcfdd47fc0b
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/page/InitialPageState.test.ts
@@ -0,0 +1,32 @@
+import { UrlEntry, UrlToken } from "../../../ValueProvider/UrlToken";
+import { InitialPageStateResponse } from "./InitialPageState";
+
+describe("ConditionalFilter / API / Page / InitialPageState", () => {
+ it("should filter by page type", () => {
+ // Arrange
+ const initialPageState = InitialPageStateResponse.empty();
+
+ initialPageState.pageTypes = [
+ {
+ label: "Home",
+ value: "home",
+ slug: "home",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.pageTypes", "home"));
+ const expectedOutput = [
+ {
+ label: "Home",
+ value: "home",
+ slug: "home",
+ },
+ ];
+
+ // Act
+ const result = initialPageState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
diff --git a/src/components/ConditionalFilter/API/initialState/page/InitialPageState.ts b/src/components/ConditionalFilter/API/initialState/page/InitialPageState.ts
new file mode 100644
index 00000000000..7247576aa4c
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/page/InitialPageState.ts
@@ -0,0 +1,33 @@
+import { ItemOption } from "@dashboard/components/ConditionalFilter/FilterElement/ConditionValue";
+import { UrlToken } from "@dashboard/components/ConditionalFilter/ValueProvider/UrlToken";
+
+export interface InitialPageState {
+ pageTypes: ItemOption[];
+}
+
+export class InitialPageStateResponse implements InitialPageState {
+ constructor(public pageTypes: ItemOption[] = []) {}
+
+ public static empty() {
+ return new InitialPageStateResponse();
+ }
+
+ public filterByUrlToken(token: UrlToken) {
+ const entry = this.getEntryByName(token.name);
+
+ if (!token.isLoadable()) {
+ return [token.value] as string[];
+ }
+
+ return (entry as ItemOption[]).filter(({ slug }) => slug && token.value.includes(slug));
+ }
+
+ private getEntryByName(name: string): ItemOption[] {
+ switch (name) {
+ case "pageTypes":
+ return this.pageTypes;
+ default:
+ return [];
+ }
+ }
+}
diff --git a/src/components/ConditionalFilter/API/initialState/page/useInitialPageState.ts b/src/components/ConditionalFilter/API/initialState/page/useInitialPageState.ts
new file mode 100644
index 00000000000..1ac2bbe5698
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/page/useInitialPageState.ts
@@ -0,0 +1,51 @@
+import { useApolloClient } from "@apollo/client";
+import { createInitialPageState } from "@dashboard/components/ConditionalFilter/API/initialState/helpers";
+import { InitialPageAPIResponse } from "@dashboard/components/ConditionalFilter/API/initialState/types";
+import { PageFetchingParams } from "@dashboard/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams";
+import {
+ _SearchPageTypesOperandsDocument,
+ _SearchPageTypesOperandsQuery,
+ _SearchPageTypesOperandsQueryVariables,
+} from "@dashboard/graphql";
+import { useState } from "react";
+
+import { InitialPageStateResponse } from "./InitialPageState";
+
+export interface InitialPageAPIState {
+ data: InitialPageStateResponse;
+ loading: boolean;
+ fetchQueries: (params: PageFetchingParams) => Promise;
+}
+
+export const useInitialPageState = () => {
+ const client = useApolloClient();
+ const [data, setData] = useState(InitialPageStateResponse.empty());
+ const [loading, setLoading] = useState(true);
+ const queriesToRun: Array> = [];
+
+ const fetchQueries = async ({ pageTypes }: PageFetchingParams) => {
+ if (pageTypes.length > 0) {
+ queriesToRun.push(
+ client.query<_SearchPageTypesOperandsQuery, _SearchPageTypesOperandsQueryVariables>({
+ query: _SearchPageTypesOperandsDocument,
+ variables: {
+ first: 5,
+ pageTypesSlugs: pageTypes,
+ },
+ }),
+ );
+ }
+
+ const data = await Promise.all(queriesToRun);
+ const initialState = createInitialPageState(data);
+
+ setData(new InitialPageStateResponse(initialState.pageTypes));
+ setLoading(false);
+ };
+
+ return {
+ data,
+ loading,
+ fetchQueries,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/InitalStateResponse.test.ts b/src/components/ConditionalFilter/API/initialState/product/InitalProductStateResponse.test.ts
similarity index 83%
rename from src/components/ConditionalFilter/API/InitalStateResponse.test.ts
rename to src/components/ConditionalFilter/API/initialState/product/InitalProductStateResponse.test.ts
index be2439ff2a3..018b762ffbe 100644
--- a/src/components/ConditionalFilter/API/InitalStateResponse.test.ts
+++ b/src/components/ConditionalFilter/API/initialState/product/InitalProductStateResponse.test.ts
@@ -1,10 +1,10 @@
-import { UrlEntry, UrlToken } from "../ValueProvider/UrlToken";
-import { InitialStateResponse } from "./InitialStateResponse";
+import { UrlEntry, UrlToken } from "../../../ValueProvider/UrlToken";
+import { InitialProductStateResponse } from "./InitialProductStateResponse";
-describe("ConditionalFilter / API / InitialStateResponse", () => {
+describe("ConditionalFilter / API / InitialProductStateResponse", () => {
it("should filter by dynamic attribute token", () => {
// Arrange
- const initialState = InitialStateResponse.empty();
+ const initialState = InitialProductStateResponse.empty();
initialState.attribute = {
"attribute-1": {
@@ -29,7 +29,7 @@ describe("ConditionalFilter / API / InitialStateResponse", () => {
});
it("should filter by static token type", () => {
// Arrange
- const initialState = InitialStateResponse.empty();
+ const initialState = InitialProductStateResponse.empty();
initialState.category = [{ label: "Category 1", value: "1", slug: "category-1" }];
@@ -43,7 +43,7 @@ describe("ConditionalFilter / API / InitialStateResponse", () => {
});
it("should filter by boolean attribute token", () => {
// Arrange
- const initialState = InitialStateResponse.empty();
+ const initialState = InitialProductStateResponse.empty();
initialState.attribute = {
"attribute-2": {
@@ -73,7 +73,7 @@ describe("ConditionalFilter / API / InitialStateResponse", () => {
});
it("should filter by static attribute token", () => {
// Arrange
- const initialState = InitialStateResponse.empty();
+ const initialState = InitialProductStateResponse.empty();
initialState.attribute = {
size: {
diff --git a/src/components/ConditionalFilter/API/InitialStateResponse.ts b/src/components/ConditionalFilter/API/initialState/product/InitialProductStateResponse.ts
similarity index 80%
rename from src/components/ConditionalFilter/API/InitialStateResponse.ts
rename to src/components/ConditionalFilter/API/initialState/product/InitialProductStateResponse.ts
index 6597c779e89..758c7845430 100644
--- a/src/components/ConditionalFilter/API/InitialStateResponse.ts
+++ b/src/components/ConditionalFilter/API/initialState/product/InitialProductStateResponse.ts
@@ -1,9 +1,9 @@
import { AttributeInputTypeEnum } from "@dashboard/graphql";
-import { createBooleanOption } from "../constants";
-import { AttributeInputType } from "../FilterElement/ConditionOptions";
-import { ItemOption } from "../FilterElement/ConditionValue";
-import { UrlToken } from "../ValueProvider/UrlToken";
+import { createBooleanOption } from "../../../constants";
+import { AttributeInputType } from "../../../FilterElement/ConditionOptions";
+import { ItemOption } from "../../../FilterElement/ConditionValue";
+import { UrlToken } from "../../../ValueProvider/UrlToken";
export interface AttributeDTO {
choices: Array<{
@@ -18,7 +18,7 @@ export interface AttributeDTO {
value: string;
}
-export interface InitialState {
+export interface InitialProductState {
category: ItemOption[];
attribute: Record;
channel: ItemOption[];
@@ -31,7 +31,10 @@ export interface InitialState {
giftCard: ItemOption[];
}
-export class InitialStateResponse implements InitialState {
+const isDateField = (name: string) =>
+ ["created", "updatedAt", "startDate", "endDate"].includes(name);
+
+export class InitialProductStateResponse implements InitialProductState {
constructor(
public category: ItemOption[] = [],
public attribute: Record = {},
@@ -50,7 +53,7 @@ export class InitialStateResponse implements InitialState {
}
public static empty() {
- return new InitialStateResponse();
+ return new InitialProductStateResponse();
}
public filterByUrlToken(token: UrlToken) {
@@ -58,6 +61,10 @@ export class InitialStateResponse implements InitialState {
return this.attribute[token.name].choices.filter(({ value }) => token.value.includes(value));
}
+ if (isDateField(token.name)) {
+ return token.value;
+ }
+
if (token.isAttribute()) {
const attr = this.attribute[token.name];
diff --git a/src/components/ConditionalFilter/API/initialState/useInitialAPIState.tsx b/src/components/ConditionalFilter/API/initialState/product/useProductInitialAPIState.tsx
similarity index 81%
rename from src/components/ConditionalFilter/API/initialState/useInitialAPIState.tsx
rename to src/components/ConditionalFilter/API/initialState/product/useProductInitialAPIState.tsx
index 44d3c398d34..cc4b4753cb8 100644
--- a/src/components/ConditionalFilter/API/initialState/useInitialAPIState.tsx
+++ b/src/components/ConditionalFilter/API/initialState/product/useProductInitialAPIState.tsx
@@ -18,22 +18,24 @@ import {
} from "@dashboard/graphql";
import { useState } from "react";
-import { FetchingParams } from "../../ValueProvider/TokenArray/fetchingParams";
-import { InitialStateResponse } from "../InitialStateResponse";
-import { createInitialStateFromData } from "./helpers";
-import { InitialAPIResponse } from "./types";
+import { FetchingParams } from "../../../ValueProvider/TokenArray/fetchingParams";
+import { createInitialProductStateFromData } from "../helpers";
+import { InitialProductAPIResponse } from "../types";
+import { InitialProductStateResponse } from "./InitialProductStateResponse";
-export interface InitialAPIState {
- data: InitialStateResponse;
+export interface InitialProductAPIState {
+ data: InitialProductStateResponse;
loading: boolean;
fetchQueries: (params: FetchingParams) => Promise;
}
-export const useProductInitialAPIState = (): InitialAPIState => {
+export const useProductInitialAPIState = (): InitialProductAPIState => {
const client = useApolloClient();
- const [data, setData] = useState(InitialStateResponse.empty());
+ const [data, setData] = useState(
+ InitialProductStateResponse.empty(),
+ );
const [loading, setLoading] = useState(true);
- const queriesToRun: Array> = [];
+ const queriesToRun: Array> = [];
const fetchQueries = async ({
category,
collection,
@@ -99,10 +101,10 @@ export const useProductInitialAPIState = (): InitialAPIState => {
}
const data = await Promise.all(queriesToRun);
- const initialState = createInitialStateFromData(data, channel);
+ const initialState = createInitialProductStateFromData(data, channel);
setData(
- new InitialStateResponse(
+ new InitialProductStateResponse(
initialState.category,
initialState.attribute,
initialState.channel,
diff --git a/src/components/ConditionalFilter/API/initialState/productTypes/InitialProductTypesState.test.ts b/src/components/ConditionalFilter/API/initialState/productTypes/InitialProductTypesState.test.ts
new file mode 100644
index 00000000000..275628e414e
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/productTypes/InitialProductTypesState.test.ts
@@ -0,0 +1,70 @@
+import { UrlEntry, UrlToken } from "../../../ValueProvider/UrlToken";
+import { InitialProductTypesStateResponse } from "./InitialProductTypesState";
+
+describe("ConditionalFilter / API / Page / InitialProductTypesState", () => {
+ it("should filter by product type", () => {
+ // Arrange
+ const initialPageState = InitialProductTypesStateResponse.empty();
+
+ initialPageState.typeOfProduct = [
+ {
+ label: "Type 1",
+ value: "type-1",
+ slug: "type-1",
+ },
+ {
+ label: "Type 2",
+ value: "type-2",
+ slug: "type-2",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.typeOfProduct", "type-2"));
+ const expectedOutput = [
+ {
+ label: "Type 2",
+ value: "type-2",
+ slug: "type-2",
+ },
+ ];
+
+ // Act
+ const result = initialPageState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by configurable", () => {
+ // Arrange
+ const initialPageState = InitialProductTypesStateResponse.empty();
+
+ initialPageState.configurable = [
+ {
+ label: "Yes",
+ value: "CONFIGURABLE",
+ slug: "yes",
+ },
+ {
+ label: "No",
+ value: "SIMPLE",
+ slug: "no",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.configurable", "no"));
+ const expectedOutput = [
+ {
+ label: "No",
+ value: "SIMPLE",
+ slug: "no",
+ },
+ ];
+
+ // Act
+ const result = initialPageState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
diff --git a/src/components/ConditionalFilter/API/initialState/productTypes/InitialProductTypesState.ts b/src/components/ConditionalFilter/API/initialState/productTypes/InitialProductTypesState.ts
new file mode 100644
index 00000000000..9ee7ee05eef
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/productTypes/InitialProductTypesState.ts
@@ -0,0 +1,39 @@
+import { ItemOption } from "@dashboard/components/ConditionalFilter/FilterElement/ConditionValue";
+import { UrlToken } from "@dashboard/components/ConditionalFilter/ValueProvider/UrlToken";
+
+export interface InitialProductTypesState {
+ typeOfProduct: ItemOption[];
+ configurable: ItemOption[];
+}
+
+export class InitialProductTypesStateResponse implements InitialProductTypesState {
+ constructor(
+ public typeOfProduct: ItemOption[] = [],
+ public configurable: ItemOption[] = [],
+ ) {}
+
+ public static empty() {
+ return new InitialProductTypesStateResponse();
+ }
+
+ public filterByUrlToken(token: UrlToken) {
+ const entry = this.getEntryByName(token.name);
+
+ if (!token.isLoadable()) {
+ return [token.value] as string[];
+ }
+
+ return (entry as ItemOption[]).filter(({ slug }) => slug && token.value.includes(slug));
+ }
+
+ private getEntryByName(name: string): ItemOption[] {
+ switch (name) {
+ case "typeOfProduct":
+ return this.typeOfProduct;
+ case "configurable":
+ return this.configurable;
+ default:
+ return [];
+ }
+ }
+}
diff --git a/src/components/ConditionalFilter/API/initialState/productTypes/useInitialProdutTypesState.ts b/src/components/ConditionalFilter/API/initialState/productTypes/useInitialProdutTypesState.ts
new file mode 100644
index 00000000000..30cc3545002
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/productTypes/useInitialProdutTypesState.ts
@@ -0,0 +1,47 @@
+import { InitialProductTypesStateResponse } from "@dashboard/components/ConditionalFilter/API/initialState/productTypes/InitialProductTypesState";
+import { createBooleanOptions } from "@dashboard/components/ConditionalFilter/constants";
+import { ProductTypeEnum } from "@dashboard/graphql";
+import { useState } from "react";
+import { useIntl } from "react-intl";
+
+import { ProductTypesFetchingParams } from "../../../ValueProvider/TokenArray/fetchingParams";
+import { EnumValuesHandler } from "../../Handler";
+
+export interface InitialProductTypesAPIState {
+ data: InitialProductTypesStateResponse;
+ loading: boolean;
+ fetchQueries: (params: ProductTypesFetchingParams) => Promise;
+}
+
+export const useInitialProductTypesState = (): InitialProductTypesAPIState => {
+ const intl = useIntl();
+ const [data, setData] = useState(
+ InitialProductTypesStateResponse.empty(),
+ );
+ const [loading, setLoading] = useState(true);
+
+ const fetchQueries = async ({ typeOfProduct }: ProductTypesFetchingParams) => {
+ const typeOfProductInit = new EnumValuesHandler(
+ ProductTypeEnum,
+ "typeOfProduct",
+ intl,
+ typeOfProduct,
+ );
+
+ const initialState = {
+ typeOfProduct: await typeOfProductInit.fetch(),
+ configurable: createBooleanOptions(),
+ };
+
+ setData(
+ new InitialProductTypesStateResponse(initialState.typeOfProduct, initialState.configurable),
+ );
+ setLoading(false);
+ };
+
+ return {
+ data,
+ loading,
+ fetchQueries,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/initialState/staffMembers/InitialStaffMembersState.test.ts b/src/components/ConditionalFilter/API/initialState/staffMembers/InitialStaffMembersState.test.ts
new file mode 100644
index 00000000000..b1bdc1eb87c
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/staffMembers/InitialStaffMembersState.test.ts
@@ -0,0 +1,37 @@
+import { UrlEntry, UrlToken } from "../../../ValueProvider/UrlToken";
+import { InitialStaffMembersStateResponse } from "./InitialStaffMembersState";
+
+describe("ConditionalFilter / API / Page / InitialStaffMembersState", () => {
+ it("should filter by status", () => {
+ // Arrange
+ const initialStaffMembersState = InitialStaffMembersStateResponse.empty();
+
+ initialStaffMembersState.staffMemberStatus = [
+ {
+ label: "Active",
+ value: "active",
+ slug: "active",
+ },
+ {
+ label: "Inactive",
+ value: "deactivated",
+ slug: "deactivated",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.staffMemberStatus", "active"));
+ const expectedOutput = [
+ {
+ label: "Active",
+ value: "active",
+ slug: "active",
+ },
+ ];
+
+ // Act
+ const result = initialStaffMembersState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
diff --git a/src/components/ConditionalFilter/API/initialState/staffMembers/InitialStaffMembersState.ts b/src/components/ConditionalFilter/API/initialState/staffMembers/InitialStaffMembersState.ts
new file mode 100644
index 00000000000..38d2aaf0e26
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/staffMembers/InitialStaffMembersState.ts
@@ -0,0 +1,33 @@
+import { ItemOption } from "@dashboard/components/ConditionalFilter/FilterElement/ConditionValue";
+import { UrlToken } from "@dashboard/components/ConditionalFilter/ValueProvider/UrlToken";
+
+export interface InitialStaffMembersState {
+ staffMemberStatus: ItemOption[];
+}
+
+export class InitialStaffMembersStateResponse implements InitialStaffMembersState {
+ constructor(public staffMemberStatus: ItemOption[] = []) {}
+
+ public static empty() {
+ return new InitialStaffMembersStateResponse();
+ }
+
+ public filterByUrlToken(token: UrlToken) {
+ const entry = this.getEntryByName(token.name);
+
+ if (!token.isLoadable()) {
+ return [token.value] as string[];
+ }
+
+ return (entry as ItemOption[]).filter(({ slug }) => slug && token.value.includes(slug));
+ }
+
+ private getEntryByName(name: string): ItemOption[] {
+ switch (name) {
+ case "staffMemberStatus":
+ return this.staffMemberStatus;
+ default:
+ return [];
+ }
+ }
+}
diff --git a/src/components/ConditionalFilter/API/initialState/staffMembers/useInitialStaffMemebersState.ts b/src/components/ConditionalFilter/API/initialState/staffMembers/useInitialStaffMemebersState.ts
new file mode 100644
index 00000000000..33b1ce70d3b
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/staffMembers/useInitialStaffMemebersState.ts
@@ -0,0 +1,43 @@
+import { StaffMemberStatus } from "@dashboard/graphql";
+import { useState } from "react";
+import { useIntl } from "react-intl";
+
+import { StaffMembersFetchingParams } from "../../../ValueProvider/TokenArray/fetchingParams";
+import { EnumValuesHandler } from "../../Handler";
+import { InitialStaffMembersStateResponse } from "./InitialStaffMembersState";
+
+export interface InitialStaffMembersAPIState {
+ data: InitialStaffMembersStateResponse;
+ loading: boolean;
+ fetchQueries: (params: StaffMembersFetchingParams) => Promise;
+}
+
+export const useInitialStaffMembersState = (): InitialStaffMembersAPIState => {
+ const intl = useIntl();
+ const [data, setData] = useState(
+ InitialStaffMembersStateResponse.empty(),
+ );
+ const [loading, setLoading] = useState(true);
+
+ const fetchQueries = async ({ staffMemberStatus }: StaffMembersFetchingParams) => {
+ const staffMemberStatusInit = new EnumValuesHandler(
+ StaffMemberStatus,
+ "staffMemberStatus",
+ intl,
+ staffMemberStatus,
+ );
+
+ const initialState = {
+ staffMemberStatus: await staffMemberStatusInit.fetch(),
+ };
+
+ setData(new InitialStaffMembersStateResponse(initialState.staffMemberStatus));
+ setLoading(false);
+ };
+
+ return {
+ data,
+ loading,
+ fetchQueries,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/initialState/types.ts b/src/components/ConditionalFilter/API/initialState/types.ts
index faa13239959..137d0744350 100644
--- a/src/components/ConditionalFilter/API/initialState/types.ts
+++ b/src/components/ConditionalFilter/API/initialState/types.ts
@@ -4,10 +4,14 @@ import {
_SearchAttributeOperandsQuery,
_SearchCategoriesOperandsQuery,
_SearchCollectionsOperandsQuery,
+ _SearchCustomersOperandsQuery,
+ _SearchPageTypesOperandsQuery,
+ _SearchProductOperandsQuery,
_SearchProductTypesOperandsQuery,
+ ChannelCurrenciesQuery,
} from "@dashboard/graphql";
-export type InitialAPIResponse = ApolloQueryResult<
+export type InitialProductAPIResponse = ApolloQueryResult<
| _GetChannelOperandsQuery
| _SearchCollectionsOperandsQuery
| _SearchCategoriesOperandsQuery
@@ -15,3 +19,15 @@ export type InitialAPIResponse = ApolloQueryResult<
| _SearchAttributeOperandsQuery
>;
export type InitialOrderAPIResponse = ApolloQueryResult<_GetChannelOperandsQuery>;
+
+export type InitialVoucherAPIResponse = ApolloQueryResult<_GetChannelOperandsQuery>;
+
+export type InitialPageAPIResponse = ApolloQueryResult<_SearchPageTypesOperandsQuery>;
+
+export type InitialGiftCardsAPIResponse = ApolloQueryResult<
+ _SearchProductOperandsQuery | _SearchCustomersOperandsQuery | ChannelCurrenciesQuery
+>;
+
+export type InitialCollectionAPIResponse = ApolloQueryResult<_GetChannelOperandsQuery>;
+
+export type InitialAttributesAPIResponse = ApolloQueryResult<_GetChannelOperandsQuery>;
diff --git a/src/components/ConditionalFilter/API/initialState/vouchers/InitialVouchersState.test.ts b/src/components/ConditionalFilter/API/initialState/vouchers/InitialVouchersState.test.ts
new file mode 100644
index 00000000000..7115eaa1787
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/vouchers/InitialVouchersState.test.ts
@@ -0,0 +1,123 @@
+import { UrlEntry, UrlToken } from "../../../ValueProvider/UrlToken";
+import { InitialVouchersStateResponse } from "./InitialVouchersState";
+
+describe("ConditionalFilter / API / Page / InitialVouchersState", () => {
+ it("should filter by channel", () => {
+ // Arrange
+ const initialPageState = InitialVouchersStateResponse.empty();
+
+ initialPageState.channels = [
+ {
+ label: "Channel 1",
+ value: "chan-1",
+ slug: "chan-1",
+ },
+ {
+ label: "Channel 2",
+ value: "chan-2",
+ slug: "chan-2",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s0.channel", "chan-2"));
+ const expectedOutput = [
+ {
+ label: "Channel 2",
+ value: "chan-2",
+ slug: "chan-2",
+ },
+ ];
+
+ // Act
+ const result = initialPageState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by discount types", () => {
+ // Arrange
+ const initialPageState = InitialVouchersStateResponse.empty();
+
+ initialPageState.discountType = [
+ {
+ label: "FIXED",
+ value: "FIXED",
+ slug: "FIXED",
+ },
+ {
+ label: "PERCENTAGE",
+ value: "PERCENTAGE",
+ slug: "PERCENTAGE",
+ },
+ {
+ label: "SHIPPING",
+ value: "SHIPPING",
+ slug: "SHIPPING",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s2.discountType", ["FIXED", "SHIPPING"]));
+ const expectedOutput = [
+ {
+ label: "FIXED",
+ value: "FIXED",
+ slug: "FIXED",
+ },
+ {
+ label: "SHIPPING",
+ value: "SHIPPING",
+ slug: "SHIPPING",
+ },
+ ];
+
+ // Act
+ const result = initialPageState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should filter by voucher status", () => {
+ // Arrange
+ const initialPageState = InitialVouchersStateResponse.empty();
+
+ initialPageState.voucherStatus = [
+ {
+ label: "ACTIVE",
+ value: "ACTIVE",
+ slug: "ACTIVE",
+ },
+ {
+ label: "EXPIRED",
+ value: "EXPIRED",
+ slug: "EXPIRED",
+ },
+ {
+ label: "SCHEDULED",
+ value: "SCHEDULED",
+ slug: "SCHEDULED",
+ },
+ ];
+
+ const token = UrlToken.fromUrlEntry(new UrlEntry("s2.voucherStatus", ["ACTIVE", "SCHEDULED"]));
+ const expectedOutput = [
+ {
+ label: "ACTIVE",
+ value: "ACTIVE",
+ slug: "ACTIVE",
+ },
+ {
+ label: "SCHEDULED",
+ value: "SCHEDULED",
+ slug: "SCHEDULED",
+ },
+ ];
+
+ // Act
+ const result = initialPageState.filterByUrlToken(token);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
diff --git a/src/components/ConditionalFilter/API/initialState/vouchers/InitialVouchersState.ts b/src/components/ConditionalFilter/API/initialState/vouchers/InitialVouchersState.ts
new file mode 100644
index 00000000000..854ce5c9152
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/vouchers/InitialVouchersState.ts
@@ -0,0 +1,49 @@
+import { ItemOption } from "@dashboard/components/ConditionalFilter/FilterElement/ConditionValue";
+import { UrlToken } from "@dashboard/components/ConditionalFilter/ValueProvider/UrlToken";
+
+export interface InitialVouchersState {
+ channels: ItemOption[];
+ discountType: ItemOption[];
+ voucherStatus: ItemOption[];
+}
+
+const isDateField = (name: string) => ["started"].includes(name);
+
+export class InitialVouchersStateResponse implements InitialVouchersState {
+ constructor(
+ public channels: ItemOption[] = [],
+ public discountType: ItemOption[] = [],
+ public voucherStatus: ItemOption[] = [],
+ ) {}
+
+ public static empty() {
+ return new InitialVouchersStateResponse();
+ }
+
+ public filterByUrlToken(token: UrlToken) {
+ const entry = this.getEntryByName(token.name);
+
+ if (isDateField(token.name)) {
+ return token.value;
+ }
+
+ if (!token.isLoadable()) {
+ return [token.value] as string[];
+ }
+
+ return (entry as ItemOption[]).filter(({ slug }) => slug && token.value.includes(slug));
+ }
+
+ private getEntryByName(name: string): ItemOption[] {
+ switch (name) {
+ case "channel":
+ return this.channels;
+ case "discountType":
+ return this.discountType;
+ case "voucherStatus":
+ return this.voucherStatus;
+ default:
+ return [];
+ }
+ }
+}
diff --git a/src/components/ConditionalFilter/API/initialState/vouchers/useInitialVouchersState.ts b/src/components/ConditionalFilter/API/initialState/vouchers/useInitialVouchersState.ts
new file mode 100644
index 00000000000..1128d102575
--- /dev/null
+++ b/src/components/ConditionalFilter/API/initialState/vouchers/useInitialVouchersState.ts
@@ -0,0 +1,78 @@
+import { useApolloClient } from "@apollo/client";
+import {
+ _GetLegacyChannelOperandsDocument,
+ _GetLegacyChannelOperandsQuery,
+ _GetLegacyChannelOperandsQueryVariables,
+ DiscountStatusEnum,
+ VoucherDiscountType,
+} from "@dashboard/graphql";
+import { useState } from "react";
+import { useIntl } from "react-intl";
+
+import { VoucherFetchingParams } from "../../../ValueProvider/TokenArray/fetchingParams";
+import { EnumValuesHandler } from "../../Handler";
+import { createInitialVoucherState } from "../helpers";
+import { InitialVoucherAPIResponse } from "../types";
+import { InitialVouchersStateResponse } from "./InitialVouchersState";
+
+export interface InitialVoucherAPIState {
+ data: InitialVouchersStateResponse;
+ loading: boolean;
+ fetchQueries: (params: VoucherFetchingParams) => Promise;
+}
+
+export const useInitialVouchersState = (): InitialVoucherAPIState => {
+ const client = useApolloClient();
+ const intl = useIntl();
+ const [data, setData] = useState(
+ InitialVouchersStateResponse.empty(),
+ );
+ const [loading, setLoading] = useState(true);
+ const queriesToRun: Array> = [];
+
+ const fetchQueries = async ({ discountType, voucherStatus, channel }: VoucherFetchingParams) => {
+ if (channel) {
+ queriesToRun.push(
+ client.query<_GetLegacyChannelOperandsQuery, _GetLegacyChannelOperandsQueryVariables>({
+ query: _GetLegacyChannelOperandsDocument,
+ }),
+ );
+ }
+
+ const discountTypeInit = new EnumValuesHandler(
+ VoucherDiscountType,
+ "discountType",
+ intl,
+ discountType,
+ );
+
+ const voucherStatusInit = new EnumValuesHandler(
+ DiscountStatusEnum,
+ "voucherStatus",
+ intl,
+ voucherStatus,
+ );
+
+ const data = await Promise.all(queriesToRun);
+ const initialState = {
+ ...createInitialVoucherState(data),
+ discountType: await discountTypeInit.fetch(),
+ voucherStatus: await voucherStatusInit.fetch(),
+ };
+
+ setData(
+ new InitialVouchersStateResponse(
+ initialState.channels,
+ initialState.discountType,
+ initialState.voucherStatus,
+ ),
+ );
+ setLoading(false);
+ };
+
+ return {
+ data,
+ loading,
+ fetchQueries,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/intl.ts b/src/components/ConditionalFilter/API/intl.ts
new file mode 100644
index 00000000000..c70519d86cd
--- /dev/null
+++ b/src/components/ConditionalFilter/API/intl.ts
@@ -0,0 +1,161 @@
+import { LeftOperand } from "@dashboard/components/ConditionalFilter/LeftOperandsProvider";
+import {
+ AttributeTypeEnum,
+ CollectionPublished,
+ DiscountStatusEnum,
+ OrderAuthorizeStatusEnum,
+ OrderChargeStatusEnum,
+ OrderStatusFilter,
+ PaymentChargeStatusEnum,
+ ProductTypeEnum,
+ StaffMemberStatus,
+ VoucherDiscountType,
+} from "@dashboard/graphql";
+import { transformOrderStatus, transformPaymentStatus } from "@dashboard/misc";
+import { IntlShape } from "react-intl";
+
+import {
+ attributeTypesMessages,
+ authorizeStatusMessages,
+ chargeStatusMessages,
+ collectionFilterMessages,
+ discountTypeMessages,
+ productTypeMessages,
+ staffMembersStatusMessages,
+ voucherStatusMessages,
+} from "./messages";
+
+const getPaymentStatusLabel = (status: PaymentChargeStatusEnum, intl: IntlShape) => {
+ const { localized } = transformPaymentStatus(status, intl);
+
+ return localized;
+};
+
+const getOrderStatusLabel = (status: OrderStatusFilter, intl: IntlShape) => {
+ const { localized } = transformOrderStatus(status, intl);
+
+ return localized;
+};
+
+const getAuthorizeStatusLabel = (status: OrderAuthorizeStatusEnum, intl: IntlShape) => {
+ switch (status) {
+ case OrderAuthorizeStatusEnum.FULL:
+ return intl.formatMessage(authorizeStatusMessages.full);
+ case OrderAuthorizeStatusEnum.PARTIAL:
+ return intl.formatMessage(authorizeStatusMessages.partial);
+ case OrderAuthorizeStatusEnum.NONE:
+ return intl.formatMessage(authorizeStatusMessages.none);
+ default:
+ return status;
+ }
+};
+
+const getChargeStatusLabel = (status: OrderChargeStatusEnum, intl: IntlShape) => {
+ switch (status) {
+ case OrderChargeStatusEnum.FULL:
+ return intl.formatMessage(chargeStatusMessages.full);
+ case OrderChargeStatusEnum.PARTIAL:
+ return intl.formatMessage(chargeStatusMessages.partial);
+ case OrderChargeStatusEnum.OVERCHARGED:
+ return intl.formatMessage(chargeStatusMessages.overcharged);
+ case OrderChargeStatusEnum.NONE:
+ return intl.formatMessage(chargeStatusMessages.none);
+ default:
+ return status;
+ }
+};
+
+const getDiscountTypeLabel = (type: VoucherDiscountType, intl: IntlShape) => {
+ switch (type) {
+ case VoucherDiscountType.FIXED:
+ return intl.formatMessage(discountTypeMessages.fixed);
+ case VoucherDiscountType.PERCENTAGE:
+ return intl.formatMessage(discountTypeMessages.percentage);
+ case VoucherDiscountType.SHIPPING:
+ return intl.formatMessage(discountTypeMessages.shipping);
+ }
+};
+
+const getVoucherStatusLabel = (status: DiscountStatusEnum, intl: IntlShape) => {
+ switch (status) {
+ case DiscountStatusEnum.ACTIVE:
+ return intl.formatMessage(voucherStatusMessages.active);
+ case DiscountStatusEnum.EXPIRED:
+ return intl.formatMessage(voucherStatusMessages.expired);
+ case DiscountStatusEnum.SCHEDULED:
+ return intl.formatMessage(voucherStatusMessages.scheduled);
+ default:
+ return status;
+ }
+};
+
+const getPublishedLabel = (status: CollectionPublished, intl: IntlShape) => {
+ switch (status) {
+ case CollectionPublished.PUBLISHED:
+ return intl.formatMessage(collectionFilterMessages.published);
+ case CollectionPublished.HIDDEN:
+ return intl.formatMessage(collectionFilterMessages.hidden);
+ default:
+ return status;
+ }
+};
+
+export const getProductTypeLabel = (type: ProductTypeEnum, intl: IntlShape) => {
+ switch (type) {
+ case ProductTypeEnum.DIGITAL:
+ return intl.formatMessage(productTypeMessages.digital);
+ case ProductTypeEnum.SHIPPABLE:
+ return intl.formatMessage(productTypeMessages.shippable);
+ default:
+ return type;
+ }
+};
+
+const getStaffMemberStatusLabel = (status: StaffMemberStatus, intl: IntlShape) => {
+ switch (status) {
+ case StaffMemberStatus.ACTIVE:
+ return intl.formatMessage(staffMembersStatusMessages.active);
+ case StaffMemberStatus.DEACTIVATED:
+ return intl.formatMessage(staffMembersStatusMessages.deactivated);
+ default:
+ return status;
+ }
+};
+
+const getAttributeTypeLabel = (type: AttributeTypeEnum, intl: IntlShape) => {
+ switch (type) {
+ case AttributeTypeEnum.PAGE_TYPE:
+ return intl.formatMessage(attributeTypesMessages.pageType);
+ case AttributeTypeEnum.PRODUCT_TYPE:
+ return intl.formatMessage(attributeTypesMessages.productType);
+ default:
+ return type;
+ }
+};
+
+export const getLocalizedLabel = (rowType: LeftOperand["type"], value: string, intl: IntlShape) => {
+ switch (rowType) {
+ case "paymentStatus":
+ return getPaymentStatusLabel(value as PaymentChargeStatusEnum, intl);
+ case "status":
+ return getOrderStatusLabel(value as OrderStatusFilter, intl);
+ case "authorizeStatus":
+ return getAuthorizeStatusLabel(value as OrderAuthorizeStatusEnum, intl);
+ case "chargeStatus":
+ return getChargeStatusLabel(value as OrderChargeStatusEnum, intl);
+ case "published":
+ return getPublishedLabel(value as CollectionPublished, intl);
+ case "discountType":
+ return getDiscountTypeLabel(value as VoucherDiscountType, intl);
+ case "voucherStatus":
+ return getVoucherStatusLabel(value as DiscountStatusEnum, intl);
+ case "typeOfProduct":
+ return getProductTypeLabel(value as ProductTypeEnum, intl);
+ case "staffMemberStatus":
+ return getStaffMemberStatusLabel(value as StaffMemberStatus, intl);
+ case "attributeType":
+ return getAttributeTypeLabel(value as AttributeTypeEnum, intl);
+ default:
+ return value;
+ }
+};
diff --git a/src/components/ConditionalFilter/API/messages.ts b/src/components/ConditionalFilter/API/messages.ts
new file mode 100644
index 00000000000..3bef8133de6
--- /dev/null
+++ b/src/components/ConditionalFilter/API/messages.ts
@@ -0,0 +1,130 @@
+import { defineMessages } from "react-intl";
+
+export const authorizeStatusMessages = defineMessages({
+ full: {
+ defaultMessage: "Full",
+ id: "F/JMp6",
+ description: "authorize status full",
+ },
+ partial: {
+ defaultMessage: "Partial",
+ id: "EojeG7",
+ description: "authorize status partial",
+ },
+ none: {
+ defaultMessage: "None",
+ id: "EoTI4r",
+ description: "authorize status none",
+ },
+});
+
+export const chargeStatusMessages = defineMessages({
+ full: {
+ defaultMessage: "Full",
+ id: "UIM5bq",
+ description: "charge status full",
+ },
+ partial: {
+ defaultMessage: "Partial",
+ id: "KPmk40",
+ description: "charge status partial",
+ },
+ overcharged: {
+ defaultMessage: "Overcharged",
+ id: "ZOamBQ",
+ description: "charge status overcharged",
+ },
+ none: {
+ defaultMessage: "None",
+ id: "dLIeRH",
+ description: "charge status none",
+ },
+});
+
+export const discountTypeMessages = defineMessages({
+ fixed: {
+ defaultMessage: "Fixed",
+ id: "1/bAgt",
+ description: "discount type fixed",
+ },
+ percentage: {
+ defaultMessage: "Percentage",
+ id: "+Wm2vY",
+ description: "discount type percentage",
+ },
+ shipping: {
+ defaultMessage: "Shipping",
+ id: "UVDfTs",
+ description: "discount type shipping",
+ },
+});
+
+export const voucherStatusMessages = defineMessages({
+ active: {
+ defaultMessage: "Active",
+ id: "EGycu/",
+ description: "voucher status active",
+ },
+ expired: {
+ defaultMessage: "Expired",
+ id: "+470FM",
+ description: "voucher status expired",
+ },
+ scheduled: {
+ defaultMessage: "Scheduled",
+ id: "qQih8j",
+ description: "voucher status scheduled",
+ },
+});
+
+export const collectionFilterMessages = defineMessages({
+ published: {
+ defaultMessage: "Published",
+ description: "collection filter published",
+ id: "UYKEsx",
+ },
+ hidden: {
+ defaultMessage: "Hidden",
+ description: "collection filter hidden",
+ id: "ufahVh",
+ },
+});
+
+export const staffMembersStatusMessages = defineMessages({
+ active: {
+ defaultMessage: "Active",
+ description: "staff members status active",
+ id: "nG1+Cz",
+ },
+ deactivated: {
+ defaultMessage: "Inactive",
+ description: "staff members status deactivated",
+ id: "oYV+Ru",
+ },
+});
+
+export const productTypeMessages = defineMessages({
+ digital: {
+ defaultMessage: "Digital",
+ description: "product type digital",
+ id: "SgFE10",
+ },
+ shippable: {
+ defaultMessage: "Shippable",
+ description: "product type shippable",
+ id: "M61TN/",
+ },
+});
+
+export const attributeTypesMessages = defineMessages({
+ productType: {
+ defaultMessage: "Product type",
+ id: "jzu97k",
+ description: "attribute product type",
+ },
+ pageType: {
+ defaultMessage: "Page type",
+ id: "qT0qr/",
+ description: "attribute page type",
+ },
+});
diff --git a/src/components/ConditionalFilter/API/providers/AttributesFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/AttributesFilterAPIProvider.tsx
new file mode 100644
index 00000000000..8cbcdce464d
--- /dev/null
+++ b/src/components/ConditionalFilter/API/providers/AttributesFilterAPIProvider.tsx
@@ -0,0 +1,87 @@
+import { ApolloClient, useApolloClient } from "@apollo/client";
+import { AttributeTypeEnum } from "@dashboard/graphql";
+import { IntlShape, useIntl } from "react-intl";
+
+import { FilterContainer, FilterElement } from "../../FilterElement";
+import { FilterAPIProvider } from "../FilterAPIProvider";
+import { BooleanValuesHandler, ChannelHandler, EnumValuesHandler, Handler } from "../Handler";
+
+const getFilterElement = (value: FilterContainer, index: number): FilterElement => {
+ const possibleFilterElement = value[index];
+
+ if (typeof possibleFilterElement !== "string" && !Array.isArray(possibleFilterElement)) {
+ return possibleFilterElement;
+ }
+
+ throw new Error("Unknown filter element used to create API handler");
+};
+
+const booleanTypes = [
+ "isVariantOnly",
+ "valueRequired",
+ "visibleInStorefront",
+ "filterableInStorefront",
+];
+
+const createAPIHandler = (
+ selectedRow: FilterElement,
+ client: ApolloClient,
+ inputValue: string,
+ intl: IntlShape,
+): Handler => {
+ const rowType = selectedRow.rowType();
+
+ if (rowType === "channel") {
+ return new ChannelHandler(client, inputValue);
+ }
+
+ if (rowType === "attributeType") {
+ return new EnumValuesHandler(AttributeTypeEnum, "attributeType", intl);
+ }
+
+ if (rowType && booleanTypes.includes(rowType) && rowType !== "attribute") {
+ return new BooleanValuesHandler([
+ {
+ label: "Yes",
+ value: "true",
+ type: rowType,
+ slug: "true",
+ },
+ {
+ label: "No",
+ value: "false",
+ type: rowType,
+ slug: "false",
+ },
+ ]);
+ }
+
+ throw new Error(`Unknown filter element: "${rowType}"`);
+};
+
+export const useAttributesFilterAPIProvider = (): FilterAPIProvider => {
+ const intl = useIntl();
+ const client = useApolloClient();
+
+ const fetchRightOptions = async (
+ position: string,
+ value: FilterContainer,
+ inputValue: string,
+ ) => {
+ const index = parseInt(position, 10);
+ const filterElement = getFilterElement(value, index);
+
+ const handler = createAPIHandler(filterElement, client, inputValue, intl);
+
+ return handler.fetch();
+ };
+
+ const fetchLeftOptions = async () => {
+ return [];
+ };
+
+ return {
+ fetchRightOptions,
+ fetchLeftOptions,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/providers/CollectionFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/CollectionFilterAPIProvider.tsx
new file mode 100644
index 00000000000..57215712857
--- /dev/null
+++ b/src/components/ConditionalFilter/API/providers/CollectionFilterAPIProvider.tsx
@@ -0,0 +1,66 @@
+import { ApolloClient, useApolloClient } from "@apollo/client";
+
+import { FilterContainer, FilterElement } from "../../FilterElement";
+import { FilterAPIProvider } from "../FilterAPIProvider";
+import { BooleanValuesHandler, ChannelHandler, Handler, NoopValuesHandler } from "../Handler";
+import { getFilterElement } from "../utils";
+
+const createAPIHandler = (
+ selectedRow: FilterElement,
+ client: ApolloClient,
+ inputValue: string,
+): Handler => {
+ const rowType = selectedRow.rowType();
+
+ if (rowType === "published") {
+ return new BooleanValuesHandler([
+ {
+ label: "Yes",
+ value: "true",
+ type: rowType,
+ slug: "true",
+ },
+ {
+ label: "No",
+ value: "false",
+ type: rowType,
+ slug: "false",
+ },
+ ]);
+ }
+
+ if (rowType === "metadata") {
+ return new NoopValuesHandler([]);
+ }
+
+ if (rowType === "channel") {
+ return new ChannelHandler(client, inputValue);
+ }
+
+ throw new Error(`Unknown filter element: "${rowType}"`);
+};
+
+export const useCollectionFilterAPIProvider = (): FilterAPIProvider => {
+ const client = useApolloClient();
+
+ const fetchRightOptions = async (
+ position: string,
+ value: FilterContainer,
+ inputValue: string,
+ ) => {
+ const index = parseInt(position, 10);
+ const filterElement = getFilterElement(value, index);
+
+ const handler = createAPIHandler(filterElement, client, inputValue);
+
+ return handler.fetch();
+ };
+ const fetchLeftOptions = async () => {
+ return [];
+ };
+
+ return {
+ fetchRightOptions,
+ fetchLeftOptions,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/providers/CustomerFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/CustomerFilterAPIProvider.tsx
new file mode 100644
index 00000000000..db66287a4c8
--- /dev/null
+++ b/src/components/ConditionalFilter/API/providers/CustomerFilterAPIProvider.tsx
@@ -0,0 +1,16 @@
+import { FilterAPIProvider } from "../FilterAPIProvider";
+
+export const useCustomerAPIProvider = (): FilterAPIProvider => {
+ const fetchRightOptions = async () => {
+ return [];
+ };
+
+ const fetchLeftOptions = async () => {
+ return [];
+ };
+
+ return {
+ fetchRightOptions,
+ fetchLeftOptions,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/DiscountFiltersAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/DiscountFiltersAPIProvider.tsx
similarity index 72%
rename from src/components/ConditionalFilter/API/DiscountFiltersAPIProvider.tsx
rename to src/components/ConditionalFilter/API/providers/DiscountFiltersAPIProvider.tsx
index 8a3975dd0e1..5e4db129890 100644
--- a/src/components/ConditionalFilter/API/DiscountFiltersAPIProvider.tsx
+++ b/src/components/ConditionalFilter/API/providers/DiscountFiltersAPIProvider.tsx
@@ -1,4 +1,4 @@
-import { FilterAPIProvider } from "@dashboard/components/ConditionalFilter/API/FilterAPIProvider";
+import { FilterAPIProvider } from "../FilterAPIProvider";
export const useDiscountFilterAPIProvider = (): FilterAPIProvider => {
const fetchRightOptions = async () => {
diff --git a/src/components/ConditionalFilter/API/providers/DraftOrderFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/DraftOrderFilterAPIProvider.tsx
new file mode 100644
index 00000000000..0d474e290dd
--- /dev/null
+++ b/src/components/ConditionalFilter/API/providers/DraftOrderFilterAPIProvider.tsx
@@ -0,0 +1,15 @@
+import { FilterAPIProvider } from "../FilterAPIProvider";
+
+export const useDraftOrderFilterAPIProvider = (): FilterAPIProvider => {
+ const fetchRightOptions = async () => {
+ return [];
+ };
+ const fetchLeftOptions = async () => {
+ return [];
+ };
+
+ return {
+ fetchRightOptions,
+ fetchLeftOptions,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/providers/GiftCardsFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/GiftCardsFilterAPIProvider.tsx
new file mode 100644
index 00000000000..aa2cc096d4f
--- /dev/null
+++ b/src/components/ConditionalFilter/API/providers/GiftCardsFilterAPIProvider.tsx
@@ -0,0 +1,81 @@
+import { ApolloClient, useApolloClient } from "@apollo/client";
+
+import { FilterContainer, FilterElement } from "../../FilterElement";
+import { FilterAPIProvider } from "../FilterAPIProvider";
+import {
+ BooleanValuesHandler,
+ CurrencyHandler,
+ CustomerHandler,
+ GiftCardTagsHandler,
+ Handler,
+ ProductsHandler,
+} from "../Handler";
+import { getFilterElement } from "../utils";
+
+const createAPIHandler = (
+ selectedRow: FilterElement,
+ client: ApolloClient,
+ inputValue: string,
+): Handler => {
+ const rowType = selectedRow.rowType();
+
+ if (rowType === "currency") {
+ return new CurrencyHandler(client, inputValue);
+ }
+
+ if (rowType === "products") {
+ return new ProductsHandler(client, inputValue);
+ }
+
+ if (rowType === "tags") {
+ return new GiftCardTagsHandler(client, inputValue);
+ }
+
+ if (rowType === "usedBy") {
+ return new CustomerHandler(client, inputValue);
+ }
+
+ if (rowType === "isActive") {
+ return new BooleanValuesHandler([
+ {
+ label: "Yes",
+ value: "true",
+ type: rowType,
+ slug: "true",
+ },
+ {
+ label: "No",
+ value: "false",
+ type: rowType,
+ slug: "false",
+ },
+ ]);
+ }
+
+ throw new Error(`Unknown filter element: "${rowType}"`);
+};
+
+export const useGiftCardsFiltersAPIProvider = (): FilterAPIProvider => {
+ const client = useApolloClient();
+
+ const fetchRightOptions = async (
+ position: string,
+ value: FilterContainer,
+ inputValue: string,
+ ) => {
+ const index = parseInt(position, 10);
+ const filterElement = getFilterElement(value, index);
+
+ const handler = createAPIHandler(filterElement, client, inputValue);
+
+ return handler.fetch();
+ };
+ const fetchLeftOptions = async () => {
+ return [];
+ };
+
+ return {
+ fetchRightOptions,
+ fetchLeftOptions,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/OrderFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/OrderFilterAPIProvider.tsx
similarity index 82%
rename from src/components/ConditionalFilter/API/OrderFilterAPIProvider.tsx
rename to src/components/ConditionalFilter/API/providers/OrderFilterAPIProvider.tsx
index f804c8de32a..e77a3fbf0c3 100644
--- a/src/components/ConditionalFilter/API/OrderFilterAPIProvider.tsx
+++ b/src/components/ConditionalFilter/API/providers/OrderFilterAPIProvider.tsx
@@ -1,5 +1,4 @@
import { ApolloClient, useApolloClient } from "@apollo/client";
-import { FilterAPIProvider } from "@dashboard/components/ConditionalFilter/API/FilterAPIProvider";
import {
OrderAuthorizeStatusEnum,
OrderChargeStatusEnum,
@@ -8,8 +7,9 @@ import {
} from "@dashboard/graphql";
import { IntlShape, useIntl } from "react-intl";
-import { RowType } from "../constants";
-import { FilterContainer, FilterElement } from "../FilterElement";
+import { RowType } from "../../constants";
+import { FilterContainer, FilterElement } from "../../FilterElement";
+import { FilterAPIProvider } from "../FilterAPIProvider";
import {
BooleanValuesHandler,
EnumValuesHandler,
@@ -17,17 +17,8 @@ import {
LegacyChannelHandler,
NoopValuesHandler,
TextInputValuesHandler,
-} from "./Handler";
-
-const getFilterElement = (value: FilterContainer, index: number): FilterElement => {
- const possibleFilterElement = value[index];
-
- if (typeof possibleFilterElement !== "string" && !Array.isArray(possibleFilterElement)) {
- return possibleFilterElement;
- }
-
- throw new Error("Unknown filter element used to create API handler");
-};
+} from "../Handler";
+import { getFilterElement } from "../utils";
const isStaticBoolean = (rowType: RowType) => {
return ["isClickAndCollect", "isPreorder", "giftCardUsed", "giftCardBought"].includes(rowType);
@@ -93,6 +84,10 @@ const createAPIHandler = (
return new NoopValuesHandler([]);
}
+ if (rowType === "metadata") {
+ return new NoopValuesHandler([]);
+ }
+
throw new Error(`Unknown filter element: "${rowType}"`);
};
diff --git a/src/components/ConditionalFilter/API/providers/PageFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/PageFilterAPIProvider.tsx
new file mode 100644
index 00000000000..e884bdca729
--- /dev/null
+++ b/src/components/ConditionalFilter/API/providers/PageFilterAPIProvider.tsx
@@ -0,0 +1,36 @@
+import { useApolloClient } from "@apollo/client";
+
+import { FilterContainer } from "../../FilterElement";
+import { FilterAPIProvider } from "../FilterAPIProvider";
+import { PageTypesHandler } from "../Handler";
+import { getFilterElement } from "../utils";
+
+export const usePageAPIProvider = (): FilterAPIProvider => {
+ const client = useApolloClient();
+
+ const fetchRightOptions = async (
+ position: string,
+ value: FilterContainer,
+ inputValue: string,
+ ) => {
+ const index = parseInt(position, 10);
+ const filterElement = getFilterElement(value, index);
+
+ const rowType = filterElement.rowType();
+
+ if (rowType === "pageTypes") {
+ return new PageTypesHandler(client, inputValue).fetch();
+ }
+
+ throw new Error(`Unknown filter element: "${rowType}"`);
+ };
+
+ const fetchLeftOptions = async () => {
+ return [];
+ };
+
+ return {
+ fetchRightOptions,
+ fetchLeftOptions,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/ProductFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/ProductFilterAPIProvider.tsx
similarity index 83%
rename from src/components/ConditionalFilter/API/ProductFilterAPIProvider.tsx
rename to src/components/ConditionalFilter/API/providers/ProductFilterAPIProvider.tsx
index d55946486f4..22467c4bdf8 100644
--- a/src/components/ConditionalFilter/API/ProductFilterAPIProvider.tsx
+++ b/src/components/ConditionalFilter/API/providers/ProductFilterAPIProvider.tsx
@@ -1,9 +1,9 @@
import { ApolloClient, useApolloClient } from "@apollo/client";
import { AttributeInputTypeEnum } from "@dashboard/graphql";
-import { RowType } from "../constants";
-import { FilterContainer, FilterElement } from "../FilterElement";
-import { FilterAPIProvider } from "./FilterAPIProvider";
+import { RowType } from "../../constants";
+import { FilterContainer, FilterElement } from "../../FilterElement";
+import { FilterAPIProvider } from "../FilterAPIProvider";
import {
AttributeChoicesHandler,
AttributesHandler,
@@ -13,17 +13,9 @@ import {
CollectionHandler,
Handler,
ProductTypeHandler,
-} from "./Handler";
+} from "../Handler";
+import { getFilterElement } from "../utils";
-const getFilterElement = (value: FilterContainer, index: number): FilterElement => {
- const possibleFilterElement = value[index];
-
- if (typeof possibleFilterElement !== "string" && !Array.isArray(possibleFilterElement)) {
- return possibleFilterElement;
- }
-
- throw new Error("Unknown filter element used to create API handler");
-};
const isStaticBoolean = (rowType: RowType) => {
return [
"isAvailable",
diff --git a/src/components/ConditionalFilter/API/providers/ProductTypesFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/ProductTypesFilterAPIProvider.tsx
new file mode 100644
index 00000000000..7267a4a9f39
--- /dev/null
+++ b/src/components/ConditionalFilter/API/providers/ProductTypesFilterAPIProvider.tsx
@@ -0,0 +1,51 @@
+import {
+ BooleanValuesHandler,
+ EnumValuesHandler,
+} from "@dashboard/components/ConditionalFilter/API/Handler";
+import { ProductTypeEnum } from "@dashboard/graphql";
+import { useIntl } from "react-intl";
+
+import { FilterContainer } from "../../FilterElement";
+import { FilterAPIProvider } from "../FilterAPIProvider";
+import { getFilterElement } from "../utils";
+
+export const useProductTypesFilterAPIProvider = (): FilterAPIProvider => {
+ const intl = useIntl();
+
+ const fetchRightOptions = async (position: string, value: FilterContainer) => {
+ const index = parseInt(position, 10);
+ const filterElement = getFilterElement(value, index);
+ const rowType = filterElement.rowType();
+
+ if (rowType === "configurable") {
+ return await new BooleanValuesHandler([
+ {
+ label: "Yes",
+ value: "true",
+ type: rowType,
+ slug: "true",
+ },
+ {
+ label: "No",
+ value: "false",
+ type: rowType,
+ slug: "false",
+ },
+ ]).fetch();
+ }
+
+ if (rowType === "typeOfProduct") {
+ return await new EnumValuesHandler(ProductTypeEnum, "typeOfProduct", intl).fetch();
+ }
+
+ return [];
+ };
+ const fetchLeftOptions = async () => {
+ return [];
+ };
+
+ return {
+ fetchRightOptions,
+ fetchLeftOptions,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/providers/StaffMembersFilterAPIProvider.tsx b/src/components/ConditionalFilter/API/providers/StaffMembersFilterAPIProvider.tsx
new file mode 100644
index 00000000000..9a78b1b40a3
--- /dev/null
+++ b/src/components/ConditionalFilter/API/providers/StaffMembersFilterAPIProvider.tsx
@@ -0,0 +1,45 @@
+import { StaffMemberStatus } from "@dashboard/graphql";
+import { useIntl } from "react-intl";
+
+import { FilterAPIProvider } from "../../API/FilterAPIProvider";
+import { EnumValuesHandler } from "../../API/Handler";
+import { FilterContainer, FilterElement } from "../../FilterElement";
+
+const getFilterElement = (value: FilterContainer, index: number): FilterElement => {
+ const possibleFilterElement = value[index];
+
+ if (typeof possibleFilterElement !== "string" && !Array.isArray(possibleFilterElement)) {
+ return possibleFilterElement;
+ }
+
+ throw new Error("Unknown filter element used to create API handler");
+};
+
+export const useStaffMembersFilterAPIProvider = (): FilterAPIProvider => {
+ const intl = useIntl();
+
+ const fetchRightOptions = async (position: string, value: FilterContainer) => {
+ const index = parseInt(position, 10);
+ const filterElement = getFilterElement(value, index);
+
+ const rowType = filterElement.rowType();
+
+ if (!rowType) {
+ return [];
+ }
+
+ if (rowType === "staffMemberStatus") {
+ return new EnumValuesHandler(StaffMemberStatus, "staffMemberStatus", intl).fetch();
+ }
+
+ return [];
+ };
+ const fetchLeftOptions = async () => {
+ return [];
+ };
+
+ return {
+ fetchRightOptions,
+ fetchLeftOptions,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/providers/VoucherFilterAPIProvider.ts b/src/components/ConditionalFilter/API/providers/VoucherFilterAPIProvider.ts
new file mode 100644
index 00000000000..a2fd37c5704
--- /dev/null
+++ b/src/components/ConditionalFilter/API/providers/VoucherFilterAPIProvider.ts
@@ -0,0 +1,58 @@
+import { ApolloClient, useApolloClient } from "@apollo/client";
+import { DiscountStatusEnum, VoucherDiscountType } from "@dashboard/graphql";
+import { IntlShape, useIntl } from "react-intl";
+
+import { FilterContainer, FilterElement } from "../../FilterElement";
+import { FilterAPIProvider } from "../FilterAPIProvider";
+import { ChannelHandler, EnumValuesHandler, Handler } from "../Handler";
+import { getFilterElement } from "../utils";
+
+const createAPIHandler = (
+ selectedRow: FilterElement,
+ client: ApolloClient,
+ inputValue: string,
+ intl: IntlShape,
+): Handler => {
+ const rowType = selectedRow.rowType();
+
+ if (rowType === "channel") {
+ return new ChannelHandler(client, inputValue);
+ }
+
+ if (rowType === "discountType") {
+ return new EnumValuesHandler(VoucherDiscountType, "discountType", intl);
+ }
+
+ if (rowType === "voucherStatus") {
+ return new EnumValuesHandler(DiscountStatusEnum, "voucherStatus", intl);
+ }
+
+ throw new Error(`Unknown filter element: "${rowType}"`);
+};
+
+export const useVoucherAPIProvider = (): FilterAPIProvider => {
+ const intl = useIntl();
+ const client = useApolloClient();
+
+ const fetchRightOptions = async (
+ position: string,
+ value: FilterContainer,
+ inputValue: string,
+ ) => {
+ const index = parseInt(position, 10);
+ const filterElement = getFilterElement(value, index);
+
+ const handler = createAPIHandler(filterElement, client, inputValue, intl);
+
+ return handler.fetch();
+ };
+
+ const fetchLeftOptions = async () => {
+ return [];
+ };
+
+ return {
+ fetchRightOptions,
+ fetchLeftOptions,
+ };
+};
diff --git a/src/components/ConditionalFilter/API/queries.ts b/src/components/ConditionalFilter/API/queries.ts
index d50027be2f1..199a075d0d2 100644
--- a/src/components/ConditionalFilter/API/queries.ts
+++ b/src/components/ConditionalFilter/API/queries.ts
@@ -78,6 +78,18 @@ export const initialDynamicOperands = gql`
}
}
+ query _SearchPageTypesOperands($first: Int!, $pageTypesSlugs: [String!]) {
+ pageTypes(first: $first, filter: { slugs: $pageTypesSlugs }) {
+ edges {
+ node {
+ id
+ name
+ slug
+ }
+ }
+ }
+ }
+
query _SearchAttributeOperands($attributesSlugs: [String!], $choicesIds: [ID!], $first: Int!) {
attributes(first: $first, filter: { slugs: $attributesSlugs }) {
edges {
@@ -153,4 +165,76 @@ export const dynamicOperandsQueries = gql`
}
}
}
+
+ query _GetPageTypesChoices($first: Int!, $query: String!) {
+ pageTypes(first: $first, filter: { search: $query }) {
+ edges {
+ node {
+ id
+ name
+ slug
+ }
+ }
+ }
+ }
+
+ query _GetProductChoices($first: Int!, $query: String!) {
+ products(first: $first, filter: { search: $query }) {
+ edges {
+ node {
+ id
+ name
+ slug
+ }
+ }
+ }
+ }
+
+ query _GetGiftCardTagsChoices($first: Int!, $query: String!) {
+ giftCardTags(first: $first, filter: { search: $query }) {
+ edges {
+ node {
+ id
+ name
+ }
+ }
+ }
+ }
+
+ query _GetCustomersChoices($first: Int!, $query: String!) {
+ customers(first: $first, filter: { search: $query }) {
+ edges {
+ node {
+ id
+ email
+ firstName
+ lastName
+ }
+ }
+ }
+ }
+
+ query _SearchCustomersOperands($first: Int!, $customersIds: [ID!]) {
+ customers(first: $first, filter: { ids: $customersIds }) {
+ edges {
+ node {
+ id
+ email
+ firstName
+ lastName
+ }
+ }
+ }
+ }
+ query _SearchProductOperands($first: Int!, $productsIds: [ID!]) {
+ products(first: $first, filter: { ids: $productsIds }) {
+ edges {
+ node {
+ id
+ name
+ slug
+ }
+ }
+ }
+ }
`;
diff --git a/src/components/ConditionalFilter/API/utils.test.ts b/src/components/ConditionalFilter/API/utils.test.ts
new file mode 100644
index 00000000000..f21f0b02aad
--- /dev/null
+++ b/src/components/ConditionalFilter/API/utils.test.ts
@@ -0,0 +1,43 @@
+import { ConditionOptions } from "@dashboard/components/ConditionalFilter/FilterElement/ConditionOptions";
+import { ConditionSelected } from "@dashboard/components/ConditionalFilter/FilterElement/ConditionSelected";
+import { ExpressionValue } from "@dashboard/components/ConditionalFilter/FilterElement/FilterElement";
+
+import { Condition, FilterContainer, FilterElement } from "../FilterElement";
+import { getFilterElement } from "./utils";
+
+describe("ConditionalFilter / API / utils / getFilterElement", () => {
+ it("should return filter element at index", () => {
+ // Arrange
+ const firstFilterElement: FilterElement = new FilterElement(
+ new ExpressionValue("price", "Price", "price"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("price"),
+ new ConditionSelected(
+ { label: "price", slug: "price", value: "123" },
+ { type: "price", value: "123", label: "Price" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+ const filterContainer: FilterContainer = [firstFilterElement];
+
+ // Act
+ const result = getFilterElement(filterContainer, 0);
+
+ // Assert
+ expect(result).toEqual(firstFilterElement);
+ });
+
+ it("throws error when unknown filter element is used", () => {
+ // Arrange
+ const filterContainer: FilterContainer = [];
+
+ // Act & Assert
+ expect(() => getFilterElement(filterContainer, 2)).toThrowError(
+ "Unknown filter element used to create API handler",
+ );
+ });
+});
diff --git a/src/components/ConditionalFilter/API/utils.ts b/src/components/ConditionalFilter/API/utils.ts
new file mode 100644
index 00000000000..6e3f64e0af0
--- /dev/null
+++ b/src/components/ConditionalFilter/API/utils.ts
@@ -0,0 +1,15 @@
+import { FilterContainer, FilterElement } from "../FilterElement";
+
+export const getFilterElement = (value: FilterContainer, index: number): FilterElement => {
+ const possibleFilterElement = value[index];
+
+ if (
+ !possibleFilterElement ||
+ typeof possibleFilterElement === "string" ||
+ Array.isArray(possibleFilterElement)
+ ) {
+ throw new Error("Unknown filter element used to create API handler");
+ }
+
+ return possibleFilterElement;
+};
diff --git a/src/components/ConditionalFilter/FilterElement/Condition.test.ts b/src/components/ConditionalFilter/FilterElement/Condition.test.ts
index c282ccaf3a8..2648080bb1e 100644
--- a/src/components/ConditionalFilter/FilterElement/Condition.test.ts
+++ b/src/components/ConditionalFilter/FilterElement/Condition.test.ts
@@ -1,4 +1,4 @@
-import { InitialStateResponse } from "../API/InitialStateResponse";
+import { InitialProductStateResponse } from "../API/initialState/product/InitialProductStateResponse";
import { STATIC_CONDITIONS } from "../constants";
import { UrlToken } from "../ValueProvider/UrlToken";
import { Condition } from "./Condition";
@@ -24,7 +24,7 @@ describe("ConditionalFilter / FilterElement / Condition", () => {
it.each([
{
token: new UrlToken("category", ["cat1"], "s", "is"),
- response: new InitialStateResponse([
+ response: new InitialProductStateResponse([
{
label: "Cat1",
value: "cat-1-id",
@@ -47,7 +47,7 @@ describe("ConditionalFilter / FilterElement / Condition", () => {
},
{
token: new UrlToken("some-attr1", ["some-attr-1z"], "m", "in"),
- response: new InitialStateResponse([], {
+ response: new InitialProductStateResponse([], {
"some-attr1": {
choices: [
{
diff --git a/src/components/ConditionalFilter/FilterElement/Condition.ts b/src/components/ConditionalFilter/FilterElement/Condition.ts
index 35655331368..27e7262d4bf 100644
--- a/src/components/ConditionalFilter/FilterElement/Condition.ts
+++ b/src/components/ConditionalFilter/FilterElement/Condition.ts
@@ -1,6 +1,6 @@
-import { InitialOrderStateResponse } from "../API/initialState/orders/InitialOrderState";
-import { InitialStateResponse } from "../API/InitialStateResponse";
+import { InitialProductStateResponse } from "../API/initialState/product/InitialProductStateResponse";
import { LeftOperand } from "../LeftOperandsProvider";
+import { InitialResponseType } from "../types";
import { UrlToken } from "./../ValueProvider/UrlToken";
import { ConditionOptions, StaticElementName } from "./ConditionOptions";
import { ConditionSelected } from "./ConditionSelected";
@@ -45,10 +45,7 @@ export class Condition {
return new Condition(options, ConditionSelected.fromConditionItem(options.first()), false);
}
- public static fromUrlToken(
- token: UrlToken,
- response: InitialStateResponse | InitialOrderStateResponse,
- ) {
+ public static fromUrlToken(token: UrlToken, response: InitialResponseType) {
if (ConditionOptions.isStaticName(token.name)) {
const staticOptions = ConditionOptions.fromStaticElementName(token.name);
const selectedOption = staticOptions.findByLabel(token.conditionKind);
@@ -56,8 +53,9 @@ export class Condition {
const isMultiSelect = selectedOption?.type === "multiselect" && valueItems.length > 0;
const isBulkSelect = selectedOption?.type === "bulkselect" && valueItems.length > 0;
- const isDate = ["created", "updatedAt", "startDate", "endDate"].includes(token.name);
-
+ const isDate = ["created", "updatedAt", "startDate", "endDate", "started"].includes(
+ token.name,
+ );
const value = isMultiSelect || isDate || isBulkSelect ? valueItems : valueItems[0];
if (!selectedOption) {
@@ -72,7 +70,7 @@ export class Condition {
}
if (token.isAttribute()) {
- const attribute = (response as InitialStateResponse).attributeByName(token.name);
+ const attribute = (response as InitialProductStateResponse).attributeByName(token.name);
const options = ConditionOptions.fromAttributeType(attribute.inputType);
const option = options.find(item => item.label === token.conditionKind)!;
const value = response.filterByUrlToken(token);
diff --git a/src/components/ConditionalFilter/FilterElement/ConditionSelected.ts b/src/components/ConditionalFilter/FilterElement/ConditionSelected.ts
index cb0df633794..694d5dca2f7 100644
--- a/src/components/ConditionalFilter/FilterElement/ConditionSelected.ts
+++ b/src/components/ConditionalFilter/FilterElement/ConditionSelected.ts
@@ -14,7 +14,7 @@ export class ConditionSelected {
return (
this.value === "" ||
(isItemOptionArray(this.value) && this.value.length === 0) ||
- (isTuple(this.value) && this.value.includes(""))
+ (isTuple(this.value) && this.value.every(el => el === ""))
);
}
diff --git a/src/components/ConditionalFilter/FilterElement/ConditionValue.test.ts b/src/components/ConditionalFilter/FilterElement/ConditionValue.test.ts
new file mode 100644
index 00000000000..7fb2f89f3d7
--- /dev/null
+++ b/src/components/ConditionalFilter/FilterElement/ConditionValue.test.ts
@@ -0,0 +1,33 @@
+import { slugFromConditionValue } from "./ConditionValue";
+
+describe("slugFromConditionValue", () => {
+ it("should return string when input is string", () => {
+ const result = slugFromConditionValue("test");
+
+ expect(result).toBe("test");
+ });
+
+ it("should return slug when input is ItemOption", () => {
+ const result = slugFromConditionValue({ label: "test", value: "test", slug: "test" });
+
+ expect(result).toBe("test");
+ });
+
+ it("should return slug when input is ItemOption array", () => {
+ const result = slugFromConditionValue([{ label: "test", value: "test", slug: "test" }]);
+
+ expect(result).toEqual(["test"]);
+ });
+
+ it("should return slug when input is tuple", () => {
+ const result = slugFromConditionValue(["test", "test"]);
+
+ expect(result).toEqual(["test", "test"]);
+ });
+
+ it("should return empty string when input is undefined", () => {
+ const result = slugFromConditionValue(undefined);
+
+ expect(result).toBe("");
+ });
+});
diff --git a/src/components/ConditionalFilter/FilterElement/ConditionValue.ts b/src/components/ConditionalFilter/FilterElement/ConditionValue.ts
index bc963d34e62..918f15529c7 100644
--- a/src/components/ConditionalFilter/FilterElement/ConditionValue.ts
+++ b/src/components/ConditionalFilter/FilterElement/ConditionValue.ts
@@ -17,7 +17,7 @@ export const isItemOptionArray = (x: ConditionValue): x is ItemOption[] =>
export const isTuple = (x: ConditionValue): x is [string, string] =>
Array.isArray(x) && x.length === 2 && (x as string[]).every(y => typeof y === "string");
-export const slugFromConditionValue = (rawEntry: ConditionValue): string | string[] => {
+export const slugFromConditionValue = (rawEntry?: ConditionValue): string | string[] => {
if (typeof rawEntry === "string") {
return rawEntry;
}
@@ -26,5 +26,5 @@ export const slugFromConditionValue = (rawEntry: ConditionValue): string | strin
return rawEntry.map(el => (typeof el === "string" ? el : el.slug));
}
- return rawEntry.slug;
+ return rawEntry?.slug ?? "";
};
diff --git a/src/components/ConditionalFilter/FilterElement/Constraint.test.ts b/src/components/ConditionalFilter/FilterElement/Constraint.test.ts
index a44ab24ced4..228a0eb2bcc 100644
--- a/src/components/ConditionalFilter/FilterElement/Constraint.test.ts
+++ b/src/components/ConditionalFilter/FilterElement/Constraint.test.ts
@@ -21,7 +21,7 @@ describe("ConditionalFilter / FilterElement / Constraint", () => {
// Assert
expect(constraint).toEqual({
- dependsOn: ["price", "isVisibleInListing", "isAvailable", "isPublished"],
+ dependsOn: ["price", "isVisibleInListing", "isAvailable", "isPublished", "published"],
disabled: ["left", "condition"],
removable: false,
});
diff --git a/src/components/ConditionalFilter/FilterElement/FilterElement.ts b/src/components/ConditionalFilter/FilterElement/FilterElement.ts
index daa23766fcf..ea79aa31840 100644
--- a/src/components/ConditionalFilter/FilterElement/FilterElement.ts
+++ b/src/components/ConditionalFilter/FilterElement/FilterElement.ts
@@ -1,7 +1,7 @@
-import { InitialOrderStateResponse } from "../API/initialState/orders/InitialOrderState";
-import { InitialStateResponse } from "../API/InitialStateResponse";
+import { InitialProductStateResponse } from "../API/initialState/product/InitialProductStateResponse";
import { RowType, STATIC_OPTIONS } from "../constants";
import { LeftOperand } from "../LeftOperandsProvider";
+import { InitialResponseType } from "../types";
import { TokenType, UrlEntry, UrlToken } from "./../ValueProvider/UrlToken";
import { Condition } from "./Condition";
import { ConditionItem, ConditionOptions, StaticElementName } from "./ConditionOptions";
@@ -46,7 +46,7 @@ export class ExpressionValue {
return new ExpressionValue(token.name, option.label, token.name);
}
- public static forAttribute(attributeName: string, response: InitialStateResponse) {
+ public static forAttribute(attributeName: string, response: InitialProductStateResponse) {
const attribute = response.attributeByName(attributeName);
return new ExpressionValue(attributeName, attribute.label, attribute.inputType);
@@ -175,10 +175,7 @@ export class FilterElement {
return new FilterElement(ExpressionValue.fromSlug(slug), Condition.emptyFromSlug(slug), false);
}
- public static fromUrlToken(
- token: UrlToken,
- response: InitialStateResponse | InitialOrderStateResponse,
- ) {
+ public static fromUrlToken(token: UrlToken, response: InitialResponseType) {
if (token.isStatic()) {
return new FilterElement(
ExpressionValue.fromUrlToken(token),
@@ -189,7 +186,7 @@ export class FilterElement {
if (token.isAttribute()) {
return new FilterElement(
- ExpressionValue.forAttribute(token.name, response as InitialStateResponse),
+ ExpressionValue.forAttribute(token.name, response as InitialProductStateResponse),
Condition.fromUrlToken(token, response),
false,
);
diff --git a/src/components/ConditionalFilter/UI/MetadataInput.tsx b/src/components/ConditionalFilter/UI/MetadataInput.tsx
new file mode 100644
index 00000000000..76fc18fc193
--- /dev/null
+++ b/src/components/ConditionalFilter/UI/MetadataInput.tsx
@@ -0,0 +1,73 @@
+import { Box, Input } from "@saleor/macaw-ui-next";
+import React from "react";
+import { useIntl } from "react-intl";
+
+import { metadataInputMessages } from "../intl";
+import { FilterEventEmitter } from "./EventEmitter";
+import { DoubleTextOperator } from "./types";
+
+interface MetadataInputProps {
+ index: number;
+ selected: DoubleTextOperator;
+ emitter: FilterEventEmitter;
+ error: boolean;
+ disabled: boolean;
+}
+
+export const MetadataInput = ({
+ index,
+ selected,
+ emitter,
+ error,
+ disabled,
+}: MetadataInputProps) => {
+ const intl = useIntl();
+
+ return (
+
+ {
+ emitter.changeRightOperator(index, [e.target.value, selected.value[1]]);
+ }}
+ onFocus={() => {
+ emitter.focusRightOperator(index);
+ }}
+ onBlur={() => {
+ emitter.blurRightOperator(index);
+ }}
+ error={error}
+ placeholder={intl.formatMessage(metadataInputMessages.keyPlaceholder)}
+ disabled={disabled}
+ />
+
+ {
+ emitter.changeRightOperator(index, [selected.value[0], e.target.value]);
+ }}
+ onFocus={() => {
+ emitter.focusRightOperator(index);
+ }}
+ onBlur={() => {
+ emitter.blurRightOperator(index);
+ }}
+ error={error}
+ placeholder={intl.formatMessage(metadataInputMessages.valuePlaceholder)}
+ disabled={disabled}
+ />
+
+ );
+};
diff --git a/src/components/ConditionalFilter/UI/RightOperator.tsx b/src/components/ConditionalFilter/UI/RightOperator.tsx
index d108a371f49..c1dd5aca754 100644
--- a/src/components/ConditionalFilter/UI/RightOperator.tsx
+++ b/src/components/ConditionalFilter/UI/RightOperator.tsx
@@ -9,6 +9,7 @@ import React from "react";
import BulkSelect from "./BulkSelect";
import { FilterEventEmitter } from "./EventEmitter";
+import { MetadataInput } from "./MetadataInput";
import {
isBulkSelect,
isCombobox,
@@ -16,6 +17,7 @@ import {
isDateRange,
isDateTime,
isDateTimeRange,
+ isDoubleText,
isMultiselect,
isNumberInput,
isNumberRange,
@@ -261,5 +263,17 @@ export const RightOperator = ({
);
}
+ if (isDoubleText(selected)) {
+ return (
+
+ );
+ }
+
return ;
};
diff --git a/src/components/ConditionalFilter/UI/operators.ts b/src/components/ConditionalFilter/UI/operators.ts
index 2c3412c458e..50498686919 100644
--- a/src/components/ConditionalFilter/UI/operators.ts
+++ b/src/components/ConditionalFilter/UI/operators.ts
@@ -3,6 +3,7 @@ import {
ComboboxOperator,
DateOperator,
DateTimeOperator,
+ DoubleTextOperator,
InputOperator,
MultiselectOperator,
NumberRangeOperator,
@@ -42,3 +43,6 @@ export const isDateRange = (value: SelectedOperator): value is DateOperator =>
export const isDateTimeRange = (value: SelectedOperator): value is DateTimeOperator =>
value.conditionValue?.type === "datetime.range";
+
+export const isDoubleText = (value: SelectedOperator): value is DoubleTextOperator =>
+ value.conditionValue?.type === "text.double";
diff --git a/src/components/ConditionalFilter/UI/types.ts b/src/components/ConditionalFilter/UI/types.ts
index 9afcf2aa848..39df8a68355 100644
--- a/src/components/ConditionalFilter/UI/types.ts
+++ b/src/components/ConditionalFilter/UI/types.ts
@@ -33,6 +33,7 @@ type ConditionOptionTypes = ConditionOption<
| "datetime"
| "date.range"
| "datetime.range"
+ | "text.double"
>;
export interface Row {
@@ -60,7 +61,8 @@ export type SelectedOperator =
| DateOperator
| DateTimeOperator
| DateRangeOperator
- | DateTimeRangeOperator;
+ | DateTimeRangeOperator
+ | DoubleTextOperator;
export interface InputOperator {
value: string | RightOperatorOption;
@@ -119,6 +121,11 @@ export interface DateTimeRangeOperator {
conditionValue: ConditionOption<"datetime.range"> | null;
}
+export interface DoubleTextOperator {
+ value: [string, string];
+ conditionValue: ConditionOption<"text.double"> | null;
+}
+
export interface FilterEvent extends Event {
detail?:
| RowAddData
diff --git a/src/components/ConditionalFilter/ValueProvider/TokenArray/TokenArray.test.ts b/src/components/ConditionalFilter/ValueProvider/TokenArray/TokenArray.test.ts
index b29af42321f..63375e4af24 100644
--- a/src/components/ConditionalFilter/ValueProvider/TokenArray/TokenArray.test.ts
+++ b/src/components/ConditionalFilter/ValueProvider/TokenArray/TokenArray.test.ts
@@ -1,4 +1,4 @@
-import { InitialStateResponse } from "../../API/InitialStateResponse";
+import { InitialProductStateResponse } from "../../API/initialState/product/InitialProductStateResponse";
import { TokenArray } from ".";
import { FetchingParams } from "./fetchingParams";
@@ -15,7 +15,7 @@ describe("ConditionalFilter / ValueProvider / TokenArray", () => {
// Arrange
const url = new TokenArray("");
// Act
- const fetchingParams = url.getFetchingParams(productParams);
+ const fetchingParams = url.getFetchingParams(productParams, "product");
// Assert
expect(fetchingParams).toEqual({
@@ -44,7 +44,7 @@ describe("ConditionalFilter / ValueProvider / TokenArray", () => {
});
// Act
const url = new TokenArray(params.toString());
- const fetchingParams = url.getFetchingParams(productParams);
+ const fetchingParams = url.getFetchingParams(productParams, "product");
// Assert
expect(fetchingParams).toEqual({
@@ -64,7 +64,7 @@ describe("ConditionalFilter / ValueProvider / TokenArray", () => {
"1": "AND",
"2[s0.channel]": "channel-pln",
});
- const response = new InitialStateResponse(
+ const response = new InitialProductStateResponse(
[
{
label: "Cat1",
@@ -93,7 +93,7 @@ describe("ConditionalFilter / ValueProvider / TokenArray", () => {
const params = new URLSearchParams({
"0[s0.channel]": "channel-pln",
});
- const response = new InitialStateResponse(
+ const response = new InitialProductStateResponse(
[
{
label: "Cat1",
diff --git a/src/components/ConditionalFilter/ValueProvider/TokenArray/__snapshots__/TokenArray.test.ts.snap b/src/components/ConditionalFilter/ValueProvider/TokenArray/__snapshots__/TokenArray.test.ts.snap
index 75a346f834c..3e1e62796b8 100644
--- a/src/components/ConditionalFilter/ValueProvider/TokenArray/__snapshots__/TokenArray.test.ts.snap
+++ b/src/components/ConditionalFilter/ValueProvider/TokenArray/__snapshots__/TokenArray.test.ts.snap
@@ -116,6 +116,7 @@ TokenArray [
"isVisibleInListing",
"isAvailable",
"isPublished",
+ "published",
],
"disabled": Array [
"left",
diff --git a/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.test.ts b/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.test.ts
new file mode 100644
index 00000000000..fa24835581a
--- /dev/null
+++ b/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.test.ts
@@ -0,0 +1,293 @@
+import { UrlToken } from "../UrlToken";
+import {
+ getEmptyFetchingPrams,
+ toAttributesFetchingParams,
+ toCollectionFetchingParams,
+ toGiftCardsFetchingParams,
+ toPageFetchingParams,
+ toProductTypesFetchingParams,
+ toStaffMembersFetchingParams,
+ toVouchersFetchingParams,
+} from "./fetchingParams";
+
+describe("TokenArray / fetchingParams / getEmptyFetchingPrams", () => {
+ it("should return product fetching params", () => {
+ // Arrange
+ const type = "product";
+
+ // Act
+ const fetchingParams = getEmptyFetchingPrams(type);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ category: [],
+ collection: [],
+ channel: [],
+ productType: [],
+ attribute: {},
+ });
+ });
+
+ it("should return order fetching params", () => {
+ // Arrange
+ const type = "order";
+
+ // Act
+ const fetchingParams = getEmptyFetchingPrams(type);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ paymentStatus: [],
+ status: [],
+ authorizeStatus: [],
+ chargeStatus: [],
+ channels: [],
+ customer: [],
+ ids: [],
+ });
+ });
+
+ it("should return voucher fetching params", () => {
+ // Arrange
+ const type = "voucher";
+
+ // Act
+ const fetchingParams = getEmptyFetchingPrams(type);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ channel: [],
+ discountType: [],
+ voucherStatus: [],
+ });
+ });
+
+ it("should return page fetching params", () => {
+ // Arrange
+ const type = "page";
+
+ // Act
+ const fetchingParams = getEmptyFetchingPrams(type);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ pageTypes: [],
+ });
+ });
+
+ it("should return gift cards fetching params", () => {
+ // Arrange
+ const type = "gift-cards";
+
+ // Act
+ const fetchingParams = getEmptyFetchingPrams(type);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ currency: [],
+ products: [],
+ tags: [],
+ usedBy: [],
+ });
+ });
+
+ it("should return gift product tyes fetching params", () => {
+ // Arrange
+ const type = "product-types";
+
+ // Act
+ const fetchingParams = getEmptyFetchingPrams(type);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ typeOfProduct: [],
+ configurable: [],
+ });
+ });
+});
+
+describe("TokenArray / fetchingParams / toVouchersFetchingParams", () => {
+ it("should return fetching params", () => {
+ // Arrange
+ const params = {
+ channel: [],
+ discountType: [],
+ voucherStatus: [],
+ };
+
+ const token = {
+ conditionKind: "is",
+ name: "channel",
+ type: "s",
+ value: "channel-1",
+ } as UrlToken;
+
+ // Act
+ const fetchingParams = toVouchersFetchingParams(params, token);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ channel: ["channel-1"],
+ discountType: [],
+ voucherStatus: [],
+ });
+ });
+});
+
+describe("TokenArray / fetchingParams / toPageFetchingParams", () => {
+ it("should return fetching params", () => {
+ // Arrange
+ const params = {
+ pageTypes: ["page-type-1", "page-type-2"],
+ };
+
+ const token = {
+ conditionKind: "in",
+ name: "pageTypes",
+ type: "s",
+ value: ["page-type-1", "page-type-2"],
+ } as UrlToken;
+
+ // Act
+ const fetchingParams = toPageFetchingParams(params, token);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ pageTypes: ["page-type-1", "page-type-2"],
+ });
+ });
+});
+
+describe("TokenArray / fetchingParams / toGiftCardsFetchingParams", () => {
+ it("should return fetching params", () => {
+ // Arrange
+ const params = {
+ currency: [],
+ products: [],
+ tags: [],
+ usedBy: [],
+ };
+
+ const token = {
+ conditionKind: "in",
+ name: "products",
+ type: "s",
+ value: ["product-1", "product-2", "product-3"],
+ } as UrlToken;
+
+ // Act
+ const fetchingParams = toGiftCardsFetchingParams(params, token);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ currency: [],
+ products: ["product-1", "product-2", "product-3"],
+ tags: [],
+ usedBy: [],
+ });
+ });
+});
+
+describe("TokenArray / fetchingParams / toCollectionFetchingParams", () => {
+ it("should return fetching params", () => {
+ // Arrange
+ const params = {
+ channel: [],
+ metadata: [],
+ published: [],
+ };
+
+ const token = {
+ conditionKind: "in",
+ name: "channel",
+ type: "s",
+ value: "chan-1",
+ } as UrlToken;
+
+ // Act
+ const fetchingParams = toCollectionFetchingParams(params, token);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ channel: ["chan-1"],
+ metadata: [],
+ published: [],
+ });
+ });
+});
+
+describe("TokenArray / fetchingParams / toProductTypesFetchingParams", () => {
+ it("should return fetching params", () => {
+ // Arrange
+ const params = {
+ typeOfProduct: [],
+ configurable: [],
+ };
+
+ const token = {
+ conditionKind: "is",
+ name: "typeOfProduct",
+ type: "s",
+ value: "SHIPPABLE",
+ } as UrlToken;
+
+ // Act
+ const fetchingParams = toProductTypesFetchingParams(params, token);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ typeOfProduct: ["SHIPPABLE"],
+ configurable: [],
+ });
+ });
+});
+
+describe("TokenArray / fetchingParams / toStaffMembersFetchingParams", () => {
+ it("should return fetching params", () => {
+ // Arrange
+ const params = {
+ staffMemberStatus: [],
+ };
+
+ const token = {
+ conditionKind: "in",
+ name: "staffMemberStatus",
+ type: "s",
+ value: "active",
+ } as UrlToken;
+
+ // Act
+ const fetchingParams = toStaffMembersFetchingParams(params, token);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ staffMemberStatus: ["active"],
+ });
+ });
+});
+
+describe("TokenArray / fetchingParams / toAttributesFetchingParams", () => {
+ it("should return fetching params", () => {
+ // Arrange
+ const params = {
+ channel: [],
+ attributeType: [],
+ };
+
+ const token = {
+ conditionKind: "in",
+ name: "channel",
+ type: "s",
+ value: "chan-1",
+ } as UrlToken;
+
+ // Act
+ const fetchingParams = toAttributesFetchingParams(params, token);
+
+ // Assert
+ expect(fetchingParams).toEqual({
+ channel: ["chan-1"],
+ attributeType: [],
+ });
+ });
+});
diff --git a/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.ts b/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.ts
index aa19ebdfd77..7c5532abdeb 100644
--- a/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.ts
+++ b/src/components/ConditionalFilter/ValueProvider/TokenArray/fetchingParams.ts
@@ -1,3 +1,4 @@
+import { FilterProviderType } from "../../types";
import { TokenType, UrlToken } from "../UrlToken";
export interface FetchingParams {
@@ -18,8 +19,51 @@ export interface OrderFetchingParams {
ids: string[];
}
+export interface VoucherFetchingParams {
+ channel: string[];
+ discountType: string[];
+ voucherStatus: string[];
+}
+
+export interface PageFetchingParams {
+ pageTypes: string[];
+}
+
+export interface GiftCardsFetchingParams {
+ currency: string[];
+ products: string[];
+ tags: string[];
+ usedBy: string[];
+}
+
+export interface CollectionFetchingParams {
+ channel: string[];
+ metadata: string[];
+ published: string[];
+}
+
+export interface ProductTypesFetchingParams {
+ typeOfProduct: string[];
+ configurable: string[];
+}
+
+export interface StaffMembersFetchingParams {
+ staffMemberStatus: string[];
+}
+
+export interface AttributesFetchingParams {
+ channel: string[];
+ attributeType: string[];
+}
+
type FetchingParamsKeys = keyof Omit;
type OrderParamsKeys = keyof OrderFetchingParams;
+type VoucherParamsKeys = keyof VoucherFetchingParams;
+type PageParamsKeys = keyof PageFetchingParams;
+type GiftCardsParamKeys = keyof GiftCardsFetchingParams;
+type ProductTypesParamsKeys = keyof ProductTypesFetchingParams;
+type StaffMembersParamsKeys = keyof StaffMembersFetchingParams;
+type AttributesParamsKeys = keyof AttributesFetchingParams;
export const emptyFetchingParams: FetchingParams = {
category: [],
@@ -39,6 +83,43 @@ export const emptyOrderFetchingParams: OrderFetchingParams = {
ids: [],
};
+export const emptyVoucherFetchingParams: VoucherFetchingParams = {
+ channel: [],
+ discountType: [],
+ voucherStatus: [],
+};
+
+export const emptyPageFetchingParams: PageFetchingParams = {
+ pageTypes: [],
+};
+
+export const emptyGiftCardsFetchingParams: GiftCardsFetchingParams = {
+ currency: [],
+ products: [],
+ tags: [],
+ usedBy: [],
+};
+
+export const emptyCollectionFetchingParams: CollectionFetchingParams = {
+ channel: [],
+ metadata: [],
+ published: [],
+};
+
+export const emptyProductTypesFetchingParams: ProductTypesFetchingParams = {
+ typeOfProduct: [],
+ configurable: [],
+};
+
+export const emptyStaffMembersFetchingParams: StaffMembersFetchingParams = {
+ staffMemberStatus: [],
+};
+
+export const emptyAttributesFetchingParams: AttributesFetchingParams = {
+ channel: [],
+ attributeType: [],
+};
+
const unique = (array: Iterable) => Array.from(new Set(array));
const includedInParams = (c: UrlToken) =>
TokenType.ATTRIBUTE_DROPDOWN === c.type || TokenType.ATTRIBUTE_MULTISELECT === c.type;
@@ -88,3 +169,121 @@ export const toOrderFetchingParams = (p: OrderFetchingParams, c: UrlToken) => {
return p;
};
+
+export const toVouchersFetchingParams = (p: VoucherFetchingParams, c: UrlToken) => {
+ const key = c.name as VoucherParamsKeys;
+
+ if (!p[key]) {
+ p[key] = [];
+ }
+
+ p[key] = unique(p[key].concat(c.value));
+
+ return p;
+};
+
+export const toPageFetchingParams = (p: PageFetchingParams, c: UrlToken) => {
+ const key = c.name as PageParamsKeys;
+
+ if (!p[key]) {
+ p[key] = [];
+ }
+
+ p[key] = unique(p[key].concat(c.value));
+
+ return p;
+};
+
+export const toGiftCardsFetchingParams = (p: GiftCardsFetchingParams, c: UrlToken) => {
+ const key = c.name as GiftCardsParamKeys;
+
+ if (!p[key]) {
+ p[key] = [];
+ }
+
+ p[key] = unique(p[key].concat(c.value));
+
+ return p;
+};
+
+export const toCollectionFetchingParams = (p: CollectionFetchingParams, c: UrlToken) => {
+ const key = c.name as keyof CollectionFetchingParams;
+
+ if (!p[key]) {
+ p[key] = [];
+ }
+
+ p[key] = unique(p[key].concat(c.value));
+
+ return p;
+};
+
+export const toProductTypesFetchingParams = (p: ProductTypesFetchingParams, c: UrlToken) => {
+ const key = c.name as ProductTypesParamsKeys;
+
+ if (!p[key]) {
+ p[key] = [];
+ }
+
+ p[key] = unique(p[key].concat(c.value));
+
+ return p;
+};
+
+export const toStaffMembersFetchingParams = (p: StaffMembersFetchingParams, c: UrlToken) => {
+ const key = c.name as StaffMembersParamsKeys;
+
+ if (!p[key]) {
+ p[key] = [];
+ }
+
+ p[key] = unique(p[key].concat(c.value));
+
+ return p;
+};
+
+export const toAttributesFetchingParams = (p: AttributesFetchingParams, c: UrlToken) => {
+ const key = c.name as AttributesParamsKeys;
+
+ if (!p[key]) {
+ p[key] = [];
+ }
+
+ p[key] = unique(p[key].concat(c.value));
+
+ return p;
+};
+
+export type FetchingParamsType =
+ | OrderFetchingParams
+ | FetchingParams
+ | CollectionFetchingParams
+ | GiftCardsFetchingParams
+ | PageFetchingParams
+ | VoucherFetchingParams
+ | ProductTypesFetchingParams
+ | StaffMembersFetchingParams
+ | AttributesFetchingParams;
+
+export const getEmptyFetchingPrams = (type: FilterProviderType) => {
+ switch (type) {
+ case "product":
+ return emptyFetchingParams;
+ case "order":
+ return emptyOrderFetchingParams;
+ case "voucher":
+ return emptyVoucherFetchingParams;
+ case "page":
+ return emptyPageFetchingParams;
+ case "gift-cards":
+ return emptyGiftCardsFetchingParams;
+ case "collection":
+ return emptyCollectionFetchingParams;
+ case "product-types":
+ return emptyProductTypesFetchingParams;
+ case "staff-members":
+ return emptyStaffMembersFetchingParams;
+ case "attributes":
+ return emptyAttributesFetchingParams;
+ }
+};
diff --git a/src/components/ConditionalFilter/ValueProvider/TokenArray/index.ts b/src/components/ConditionalFilter/ValueProvider/TokenArray/index.ts
index c55a42bc3a5..86d20aadb26 100644
--- a/src/components/ConditionalFilter/ValueProvider/TokenArray/index.ts
+++ b/src/components/ConditionalFilter/ValueProvider/TokenArray/index.ts
@@ -1,14 +1,29 @@
import { parse, ParsedQs } from "qs";
-import { InitialOrderStateResponse } from "../../API/initialState/orders/InitialOrderState";
-import { InitialStateResponse } from "../../API/InitialStateResponse";
+import { InitialProductStateResponse } from "../../API/initialState/product/InitialProductStateResponse";
import { FilterContainer, FilterElement } from "../../FilterElement";
+import { FilterProviderType, InitialResponseType } from "../../types";
import { UrlEntry, UrlToken } from "../UrlToken";
import {
+ AttributesFetchingParams,
+ CollectionFetchingParams,
FetchingParams,
+ FetchingParamsType,
+ GiftCardsFetchingParams,
OrderFetchingParams,
+ PageFetchingParams,
+ ProductTypesFetchingParams,
+ StaffMembersFetchingParams,
+ toAttributesFetchingParams,
+ toCollectionFetchingParams,
toFetchingParams,
+ toGiftCardsFetchingParams,
toOrderFetchingParams,
+ toPageFetchingParams,
+ toProductTypesFetchingParams,
+ toStaffMembersFetchingParams,
+ toVouchersFetchingParams,
+ VoucherFetchingParams,
} from "./fetchingParams";
const toFlatUrlTokens = (p: UrlToken[], c: TokenArray[number]) => {
@@ -43,7 +58,7 @@ const tokenizeUrl = (urlParams: string) => {
};
const mapUrlTokensToFilterValues = (
urlTokens: TokenArray,
- response: InitialStateResponse | InitialOrderStateResponse,
+ response: InitialResponseType,
): FilterContainer =>
urlTokens.map(el => {
if (typeof el === "string") {
@@ -62,25 +77,67 @@ export class TokenArray extends Array {
super(...tokenizeUrl(url));
}
- public getFetchingParams(params: OrderFetchingParams | FetchingParams) {
- if ("paymentStatus" in params) {
- return this.asFlatArray()
- .filter(token => token.isLoadable())
- .reduce(toOrderFetchingParams, params);
+ public getFetchingParams(params: FetchingParamsType, type: FilterProviderType) {
+ switch (type) {
+ case "order":
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(toOrderFetchingParams, params as OrderFetchingParams);
+ case "collection":
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(
+ toCollectionFetchingParams,
+ params as CollectionFetchingParams,
+ );
+ case "voucher":
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(toVouchersFetchingParams, params as VoucherFetchingParams);
+ case "page":
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(toPageFetchingParams, params as PageFetchingParams);
+ case "gift-cards":
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(
+ toGiftCardsFetchingParams,
+ params as GiftCardsFetchingParams,
+ );
+ case "product-types":
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(
+ toProductTypesFetchingParams,
+ params as ProductTypesFetchingParams,
+ );
+ case "staff-members":
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(
+ toStaffMembersFetchingParams,
+ params as StaffMembersFetchingParams,
+ );
+ case "attributes":
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(
+ toAttributesFetchingParams,
+ params as AttributesFetchingParams,
+ );
+ default:
+ return this.asFlatArray()
+ .filter(token => token.isLoadable())
+ .reduce(toFetchingParams, params as FetchingParams);
}
-
- return this.asFlatArray()
- .filter(token => token.isLoadable())
- .reduce(toFetchingParams, params);
}
public asFlatArray() {
return flatenate(this);
}
- public asFilterValuesFromResponse(
- response: InitialStateResponse | InitialOrderStateResponse,
- ): FilterContainer {
+ public asFilterValuesFromResponse(response: InitialResponseType): FilterContainer {
return this.map(el => {
if (typeof el === "string") {
return el;
@@ -101,6 +158,6 @@ export class TokenArray extends Array {
}
public asFilterValueFromEmpty(): FilterContainer {
- return this.asFilterValuesFromResponse(InitialStateResponse.empty());
+ return this.asFilterValuesFromResponse(InitialProductStateResponse.empty());
}
}
diff --git a/src/components/ConditionalFilter/ValueProvider/TokenArray/ordersFetchingParams.ts b/src/components/ConditionalFilter/ValueProvider/TokenArray/ordersFetchingParams.ts
deleted file mode 100644
index e3425d48408..00000000000
--- a/src/components/ConditionalFilter/ValueProvider/TokenArray/ordersFetchingParams.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { UrlToken } from "../UrlToken";
-
-export interface OrdersFetchingParams {
- paymentStatus: string[];
-}
-
-type FetchingParamsKeys = keyof Omit;
-
-export const emptyFetchingParams: OrdersFetchingParams = {
- paymentStatus: [],
-};
-
-const unique = (array: Iterable) => Array.from(new Set(array));
-
-export const toFetchingParams = (p: OrdersFetchingParams, c: UrlToken) => {
- const key = c.name as FetchingParamsKeys;
-
- if (!c.isAttribute() && !p[key]) {
- p[key] = [];
- }
-
- p[key] = unique(p[key].concat(c.value));
-
- return p;
-};
diff --git a/src/components/ConditionalFilter/ValueProvider/UrlToken.ts b/src/components/ConditionalFilter/ValueProvider/UrlToken.ts
index 564474c5c63..26cc0347c77 100644
--- a/src/components/ConditionalFilter/ValueProvider/UrlToken.ts
+++ b/src/components/ConditionalFilter/ValueProvider/UrlToken.ts
@@ -6,6 +6,18 @@ import { slugFromConditionValue } from "../FilterElement/ConditionValue";
export const CONDITIONS = ["is", "equals", "in", "between", "lower", "greater"];
+const PRODUCT_STATICS = [
+ "category",
+ "collection",
+ "channel",
+ "productType",
+ "isAvailable",
+ "isPublished",
+ "isVisibleInListing",
+ "hasCategory",
+ "giftCard",
+];
+
const ORDER_STATICS = [
"paymentStatus",
"status",
@@ -16,21 +28,40 @@ const ORDER_STATICS = [
"isPreorder",
"isClickAndCollect",
"channels",
- "customer",
"ids",
];
-const STATIC_TO_LOAD = [
- "category",
- "collection",
+const VOUCHER_STATICS = ["channel", "discountType", "voucherStatus"];
+
+const PAGE_STATIC = ["pageTypes"];
+
+const GIFT_CARDS_STATICS = ["currency", "products", "isActive", "tags", "usedBy"];
+
+const COLLECTION_STATICS = ["channel", "published"];
+
+const PRODUCT_TYPES_STATICS = ["typeOfProduct", "configurable"];
+
+const STAFF_MEMBERS_STATICS = ["staffMemberStatus"];
+
+const ATTRIBUTES_STATICS = [
"channel",
- "productType",
- "isAvailable",
- "isPublished",
- "isVisibleInListing",
- "hasCategory",
- "giftCard",
+ "attributeType",
+ "filterableInStorefront",
+ "isVariantOnly",
+ "valueRequired",
+ "visibleInStorefront",
+];
+
+const STATIC_TO_LOAD = [
+ ...PRODUCT_STATICS,
...ORDER_STATICS,
+ ...VOUCHER_STATICS,
+ ...PAGE_STATIC,
+ ...GIFT_CARDS_STATICS,
+ ...COLLECTION_STATICS,
+ ...PRODUCT_TYPES_STATICS,
+ ...STAFF_MEMBERS_STATICS,
+ ...ATTRIBUTES_STATICS,
];
export const TokenType = {
diff --git a/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts b/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts
index 525b6fd6394..6e0898e817f 100644
--- a/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts
+++ b/src/components/ConditionalFilter/ValueProvider/useUrlValueProvider.ts
@@ -3,38 +3,37 @@ import { stringify } from "qs";
import { useEffect, useState } from "react";
import useRouter from "use-react-router";
-import { InitialAPIState } from "../API";
+import { InitialAttributesAPIState } from "../API/initialState/attributes/useInitialAttributesState";
+import { InitialCollectionAPIState } from "../API/initialState/collections/useInitialCollectionsState";
+import { InitialGiftCardsAPIState } from "../API/initialState/giftCards/useInitialGiftCardsState";
import { InitialOrderAPIState } from "../API/initialState/orders/useInitialOrderState";
+import { InitialPageAPIState } from "../API/initialState/page/useInitialPageState";
+import { InitialProductAPIState } from "../API/initialState/product/useProductInitialAPIState";
+import { InitialProductTypesAPIState } from "../API/initialState/productTypes/useInitialProdutTypesState";
+import { InitialStaffMembersAPIState } from "../API/initialState/staffMembers/useInitialStaffMemebersState";
+import { InitialVoucherAPIState } from "../API/initialState/vouchers/useInitialVouchersState";
import { FilterContainer, FilterElement } from "../FilterElement";
import { FilterValueProvider } from "../FilterValueProvider";
+import { FilterProviderType, InitialAPIState } from "../types";
import { TokenArray } from "./TokenArray";
import {
- emptyFetchingParams,
- emptyOrderFetchingParams,
+ AttributesFetchingParams,
+ CollectionFetchingParams,
FetchingParams,
+ getEmptyFetchingPrams,
+ GiftCardsFetchingParams,
OrderFetchingParams,
+ PageFetchingParams,
+ ProductTypesFetchingParams,
+ StaffMembersFetchingParams,
+ VoucherFetchingParams,
} from "./TokenArray/fetchingParams";
-import { UrlEntry } from "./UrlToken";
-
-type Structure = Array;
-
-const prepareStructure = (filterValue: FilterContainer): Structure =>
- filterValue.map(f => {
- if (typeof f === "string") {
- return f;
- }
-
- if (Array.isArray(f)) {
- return prepareStructure(f);
- }
-
- return f.asUrlEntry();
- });
+import { prepareStructure } from "./utils";
export const useUrlValueProvider = (
locationSearch: string,
- type: "product" | "order" | "discount",
- initialState?: InitialAPIState | InitialOrderAPIState,
+ type: FilterProviderType,
+ initialState?: InitialAPIState,
): FilterValueProvider => {
const router = useRouter();
const params = new URLSearchParams(locationSearch);
@@ -52,20 +51,55 @@ export const useUrlValueProvider = (
params.delete("after");
const tokenizedUrl = new TokenArray(params.toString());
- const paramsFromType = type === "product" ? emptyFetchingParams : emptyOrderFetchingParams;
- const fetchingParams = tokenizedUrl.getFetchingParams(paramsFromType);
+ const paramsFromType = getEmptyFetchingPrams(type);
+ const fetchingParams = paramsFromType
+ ? tokenizedUrl.getFetchingParams(paramsFromType, type)
+ : null;
useEffect(() => {
if (initialState) {
switch (type) {
case "product":
- (initialState as InitialAPIState).fetchQueries(fetchingParams as FetchingParams);
+ (initialState as InitialProductAPIState).fetchQueries(fetchingParams as FetchingParams);
break;
case "order":
(initialState as InitialOrderAPIState).fetchQueries(
fetchingParams as OrderFetchingParams,
);
break;
+ case "voucher":
+ (initialState as InitialVoucherAPIState).fetchQueries(
+ fetchingParams as VoucherFetchingParams,
+ );
+ break;
+ case "page":
+ (initialState as InitialPageAPIState).fetchQueries(fetchingParams as PageFetchingParams);
+ break;
+ case "gift-cards":
+ (initialState as InitialGiftCardsAPIState).fetchQueries(
+ fetchingParams as GiftCardsFetchingParams,
+ );
+ break;
+ case "collection":
+ (initialState as InitialCollectionAPIState).fetchQueries(
+ fetchingParams as CollectionFetchingParams,
+ );
+ break;
+ case "product-types":
+ (initialState as InitialProductTypesAPIState).fetchQueries(
+ fetchingParams as ProductTypesFetchingParams,
+ );
+ break;
+ case "staff-members":
+ (initialState as InitialStaffMembersAPIState).fetchQueries(
+ fetchingParams as StaffMembersFetchingParams,
+ );
+ break;
+ case "attributes":
+ (initialState as InitialAttributesAPIState).fetchQueries(
+ fetchingParams as AttributesFetchingParams,
+ );
+ break;
}
}
}, [locationSearch]);
diff --git a/src/components/ConditionalFilter/ValueProvider/utils.ts b/src/components/ConditionalFilter/ValueProvider/utils.ts
new file mode 100644
index 00000000000..ed504bef8c7
--- /dev/null
+++ b/src/components/ConditionalFilter/ValueProvider/utils.ts
@@ -0,0 +1,17 @@
+import { FilterContainer } from "../FilterElement";
+import { UrlEntry } from "./UrlToken";
+
+type Structure = Array;
+
+export const prepareStructure = (filterValue: FilterContainer): Structure =>
+ filterValue.map(f => {
+ if (typeof f === "string") {
+ return f;
+ }
+
+ if (Array.isArray(f)) {
+ return prepareStructure(f);
+ }
+
+ return f.asUrlEntry();
+ });
diff --git a/src/components/ConditionalFilter/constants.ts b/src/components/ConditionalFilter/constants.ts
index b9dab9eba80..81490e376e7 100644
--- a/src/components/ConditionalFilter/constants.ts
+++ b/src/components/ConditionalFilter/constants.ts
@@ -13,6 +13,20 @@ export const STATIC_CONDITIONS = {
{ type: "number", label: "greater", value: "input-3" },
{ type: "number.range", label: "between", value: "input-4" },
],
+ timesUsed: [
+ { type: "number", label: "is", value: "input-1" },
+ { type: "number.range", label: "between", value: "input-2" },
+ ],
+ currentBalance: [
+ { type: "number", label: "lower", value: "input-1" },
+ { type: "number", label: "greater", value: "input-2" },
+ { type: "number.range", label: "between", value: "input-3" },
+ ],
+ initialBalance: [
+ { type: "number", label: "lower", value: "input-1" },
+ { type: "number", label: "greater", value: "input-2" },
+ { type: "number.range", label: "between", value: "input-3" },
+ ],
collection: [{ type: "multiselect", label: "in", value: "input-4" }],
channel: [{ type: "select", label: "is", value: "input-5" }],
channels: [{ type: "multiselect", label: "in", value: "input-1" }],
@@ -20,9 +34,19 @@ export const STATIC_CONDITIONS = {
{ type: "combobox", label: "is", value: "input-1" },
{ type: "multiselect", label: "in", value: "input-2" },
],
+ discountType: [
+ { type: "select", label: "is", value: "input-1" },
+ { type: "multiselect", label: "in", value: "input-2" },
+ ],
+ isActive: [{ type: "select", label: "is", value: "input-1" }],
isAvailable: [{ type: "select", label: "is", value: "input-1" }],
isPublished: [{ type: "select", label: "is", value: "input-1" }],
isVisibleInListing: [{ type: "select", label: "is", value: "input-1" }],
+ isVariantOnly: [{ type: "select", label: "is", value: "input-1" }],
+ valueRequired: [{ type: "select", label: "is", value: "input-1" }],
+ visibleInStorefront: [{ type: "select", label: "is", value: "input-1" }],
+ filterableInStorefront: [{ type: "select", label: "is", value: "input-1" }],
+ attributeType: [{ type: "select", label: "is", value: "input-1" }],
hasCategory: [{ type: "select", label: "is", value: "input-1" }],
giftCard: [{ type: "select", label: "is", value: "input-1" }],
startDate: [
@@ -63,11 +87,39 @@ export const STATIC_CONDITIONS = {
value: "input-2",
},
],
+ voucherStatus: [
+ {
+ type: "combobox",
+ label: "is",
+ value: "input-1",
+ },
+ {
+ type: "multiselect",
+ label: "in",
+ value: "input-2",
+ },
+ ],
created: [
{ type: "date", label: "lower", value: "input-1" },
{ type: "date", label: "greater", value: "input-2" },
{ type: "date.range", label: "between", value: "input-3" },
],
+ dateJoined: [
+ { type: "date", label: "lower", value: "input-1" },
+ { type: "date", label: "greater", value: "input-2" },
+ { type: "date.range", label: "between", value: "input-3" },
+ ],
+ numberOfOrders: [
+ { type: "number", label: "is", value: "input-1" },
+ { type: "number", label: "lower", value: "input-1" },
+ { type: "number", label: "greater", value: "input-2" },
+ { type: "number.range", label: "between", value: "input-2" },
+ ],
+ started: [
+ { type: "datetime", label: "lower", value: "input-1" },
+ { type: "datetime", label: "greater", value: "input-2" },
+ { type: "datetime.range", label: "between", value: "input-3" },
+ ],
authorizeStatus: [
{
type: "combobox",
@@ -111,11 +163,69 @@ export const STATIC_CONDITIONS = {
value: "input-1",
},
],
+ metadata: [
+ {
+ type: "text.double",
+ label: "is",
+ value: "input-1",
+ },
+ ],
+ pageTypes: [
+ {
+ type: "multiselect",
+ label: "in",
+ value: "input-1",
+ },
+ ],
+ currency: [
+ {
+ type: "select",
+ label: "is",
+ value: "input-1",
+ },
+ ],
+ products: [{ type: "multiselect", label: "in", value: "input-1" }],
+ tags: [{ type: "multiselect", label: "in", value: "input-1" }],
+ usedBy: [{ type: "multiselect", label: "in", value: "input-1" }],
+ published: [
+ {
+ type: "select",
+ label: "is",
+ value: "input-1",
+ },
+ ],
+ slugs: [
+ {
+ type: "bulkselect",
+ label: "in",
+ value: "input-1",
+ },
+ ],
+ typeOfProduct: [
+ {
+ type: "select",
+ label: "is",
+ value: "input-1",
+ },
+ ],
+ configurable: [
+ {
+ type: "select",
+ label: "is",
+ value: "input-1",
+ },
+ ],
+ staffMemberStatus: [{ type: "select", label: "is", value: "input-1" }],
};
export const CONSTRAINTS = {
channel: {
- dependsOn: ["price", "isVisibleInListing", "isAvailable", "isPublished"],
+ dependsOn: ["price", "isVisibleInListing", "isAvailable", "isPublished", "published"],
+ removable: false,
+ disabled: ["left", "condition"],
+ },
+ currency: {
+ dependsOn: ["currentBalance", "initialBalance"],
removable: false,
disabled: ["left", "condition"],
},
@@ -206,7 +316,7 @@ export const STATIC_ORDER_OPTIONS: LeftOperand[] = [
},
{
value: "created",
- label: "Created",
+ label: "Creation date",
type: "created",
slug: "created",
},
@@ -258,12 +368,228 @@ export const STATIC_ORDER_OPTIONS: LeftOperand[] = [
type: "customer",
slug: "customer",
},
+ {
+ value: "metadata",
+ label: "Metadata",
+ type: "metadata",
+ slug: "metadata",
+ },
+];
+
+export const STATIC_VOUCHER_OPTIONS: LeftOperand[] = [
+ {
+ value: "channel",
+ label: "Channel",
+ type: "channel",
+ slug: "channel",
+ },
+ {
+ value: "discountType",
+ label: "Discount type",
+ type: "discountType",
+ slug: "discountType",
+ },
+ {
+ value: "started",
+ label: "Started",
+ type: "startDate",
+ slug: "started",
+ },
+ {
+ value: "voucherStatus",
+ label: "Status",
+ type: "voucherStatus",
+ slug: "voucherStatus",
+ },
+ {
+ value: "timesUsed",
+ label: "Times used",
+ type: "timesUsed",
+ slug: "timesUsed",
+ },
+];
+
+export const STATIC_COLLECTION_OPTIONS: LeftOperand[] = [
+ {
+ value: "published",
+ label: "Is published",
+ type: "published",
+ slug: "published",
+ },
+ {
+ value: "metadata",
+ label: "Metadata",
+ type: "metadata",
+ slug: "metadata",
+ },
+ {
+ value: "channel",
+ label: "Channel",
+ type: "channel",
+ slug: "channel",
+ },
+];
+
+export const STATIC_PAGE_OPTIONS: LeftOperand[] = [
+ {
+ value: "pageTypes",
+ label: "Page types",
+ type: "pageTypes",
+ slug: "pageTypes",
+ },
+];
+
+export const STATIC_DRAFT_ORDER_OPTIONS: LeftOperand[] = [
+ {
+ value: "customer",
+ label: "Customer",
+ type: "customer",
+ slug: "customer",
+ },
+ {
+ value: "created",
+ label: "Creation date",
+ type: "created",
+ slug: "created",
+ },
+];
+
+export const STATIC_GIFT_CARDS_OPTIONS: LeftOperand[] = [
+ {
+ value: "currency",
+ label: "Currency",
+ type: "currency",
+ slug: "currency",
+ },
+ {
+ value: "currentBalance",
+ label: "Current balance",
+ type: "currentBalance",
+ slug: "currentBalance",
+ },
+ {
+ value: "initialBalance",
+ label: "Initial balance",
+ type: "initialBalance",
+ slug: "initialBalance",
+ },
+ {
+ value: "products",
+ label: "Products",
+ type: "products",
+ slug: "products",
+ },
+ {
+ value: "isActive",
+ label: "Is active",
+ type: "isActive",
+ slug: "isActive",
+ },
+ {
+ value: "tags",
+ label: "Tags",
+ type: "tags",
+ slug: "tags",
+ },
+ {
+ value: "usedBy",
+ label: "Used by",
+ type: "usedBy",
+ slug: "usedBy",
+ },
+];
+
+export const STATIC_CUSTOMER_OPTIONS: LeftOperand[] = [
+ {
+ value: "dateJoined",
+ label: "Join date",
+ type: "dateJoined",
+ slug: "dateJoined",
+ },
+ {
+ value: "numberOfOrders",
+ label: "Number of orders",
+ type: "numberOfOrders",
+ slug: "numberOfOrders",
+ },
+];
+
+export const STATIC_PRODUCT_TYPES_OPTIONS: LeftOperand[] = [
+ {
+ value: "configurable",
+ label: "Has variant attributes",
+ type: "configurable",
+ slug: "configurable",
+ },
+ {
+ value: "typeOfProduct",
+ label: "Type",
+ type: "typeOfProduct",
+ slug: "typeOfProduct",
+ },
+];
+
+export const STAFF_MEMBER_OPTIONS: LeftOperand[] = [
+ {
+ value: "staffMemberStatus",
+ label: "Status",
+ type: "staffMemberStatus",
+ slug: "staffMemberStatus",
+ },
+];
+
+export const STATIC_ATTRIBUTES_OPTIONS: LeftOperand[] = [
+ {
+ value: "filterableInStorefront",
+ label: "Filterable in Storefront",
+ type: "filterableInStorefront",
+ slug: "filterableInStorefront",
+ },
+ {
+ value: "isVariantOnly",
+ label: "Variant only",
+ type: "isVariantOnly",
+ slug: "isVariantOnly",
+ },
+ {
+ value: "valueRequired",
+ label: "Is required",
+ type: "valueRequired",
+ slug: "valueRequired",
+ },
+ {
+ value: "visibleInStorefront",
+ label: "Visible in Storefront",
+ type: "visibleInStorefront",
+ slug: "visibleInStorefront",
+ },
+ {
+ value: "attributeType",
+ label: "Type",
+ type: "attributeType",
+ slug: "attributeType",
+ },
+ {
+ value: "channel",
+ label: "Channel",
+ type: "channel",
+ slug: "channel",
+ },
];
export const STATIC_OPTIONS = [
...STATIC_PRODUCT_OPTIONS,
...STATIC_DISCOUNT_OPTIONS,
...STATIC_ORDER_OPTIONS,
+ ...STATIC_VOUCHER_OPTIONS,
+ ...STATIC_PAGE_OPTIONS,
+ ...STATIC_DRAFT_ORDER_OPTIONS,
+ ...STATIC_GIFT_CARDS_OPTIONS,
+ ...STATIC_CUSTOMER_OPTIONS,
+ ...STATIC_COLLECTION_OPTIONS,
+ ...STATIC_PRODUCT_TYPES_OPTIONS,
+ ...STAFF_MEMBER_OPTIONS,
+ ...STATIC_ATTRIBUTES_OPTIONS,
];
export const ATTRIBUTE_INPUT_TYPE_CONDITIONS = {
diff --git a/src/components/ConditionalFilter/context/provider.tsx b/src/components/ConditionalFilter/context/provider.tsx
index eaccbcd0001..745e02e5418 100644
--- a/src/components/ConditionalFilter/context/provider.tsx
+++ b/src/components/ConditionalFilter/context/provider.tsx
@@ -1,14 +1,39 @@
import React, { FC } from "react";
-import { useDiscountFilterAPIProvider } from "../API/DiscountFiltersAPIProvider";
+import { useInitialAttributesState } from "../API/initialState/attributes/useInitialAttributesState";
+import { useInitialCollectionState } from "../API/initialState/collections/useInitialCollectionsState";
+import { useInitialGiftCardsState } from "../API/initialState/giftCards/useInitialGiftCardsState";
import { useInitialOrderState } from "../API/initialState/orders/useInitialOrderState";
-import { useProductInitialAPIState } from "../API/initialState/useInitialAPIState";
-import { useOrderFilterAPIProvider } from "../API/OrderFilterAPIProvider";
-import { useProductFilterAPIProvider } from "../API/ProductFilterAPIProvider";
+import { useInitialPageState } from "../API/initialState/page/useInitialPageState";
+import { useProductInitialAPIState } from "../API/initialState/product/useProductInitialAPIState";
+import { useInitialProductTypesState } from "../API/initialState/productTypes/useInitialProdutTypesState";
+import { useInitialStaffMembersState } from "../API/initialState/staffMembers/useInitialStaffMemebersState";
+import { useInitialVouchersState } from "../API/initialState/vouchers/useInitialVouchersState";
+import { useAttributesFilterAPIProvider } from "../API/providers/AttributesFilterAPIProvider";
+import { useCollectionFilterAPIProvider } from "../API/providers/CollectionFilterAPIProvider";
+import { useCustomerAPIProvider } from "../API/providers/CustomerFilterAPIProvider";
+import { useDiscountFilterAPIProvider } from "../API/providers/DiscountFiltersAPIProvider";
+import { useDraftOrderFilterAPIProvider } from "../API/providers/DraftOrderFilterAPIProvider";
+import { useGiftCardsFiltersAPIProvider } from "../API/providers/GiftCardsFilterAPIProvider";
+import { useOrderFilterAPIProvider } from "../API/providers/OrderFilterAPIProvider";
+import { usePageAPIProvider } from "../API/providers/PageFilterAPIProvider";
+import { useProductFilterAPIProvider } from "../API/providers/ProductFilterAPIProvider";
+import { useProductTypesFilterAPIProvider } from "../API/providers/ProductTypesFilterAPIProvider";
+import { useStaffMembersFilterAPIProvider } from "../API/providers/StaffMembersFilterAPIProvider";
+import { useVoucherAPIProvider } from "../API/providers/VoucherFilterAPIProvider";
import {
+ STAFF_MEMBER_OPTIONS,
+ STATIC_ATTRIBUTES_OPTIONS,
+ STATIC_COLLECTION_OPTIONS,
+ STATIC_CUSTOMER_OPTIONS,
STATIC_DISCOUNT_OPTIONS,
+ STATIC_DRAFT_ORDER_OPTIONS,
+ STATIC_GIFT_CARDS_OPTIONS,
STATIC_ORDER_OPTIONS,
+ STATIC_PAGE_OPTIONS,
STATIC_PRODUCT_OPTIONS,
+ STATIC_PRODUCT_TYPES_OPTIONS,
+ STATIC_VOUCHER_OPTIONS,
} from "../constants";
import { useContainerState } from "../useContainerState";
import { useFilterLeftOperandsProvider } from "../useFilterLeftOperands";
@@ -90,3 +115,237 @@ export const ConditionalOrderFilterProvider: FC<{
);
};
+
+export const ConditionalVoucherFilterProvider: FC<{ locationSearch: string }> = ({
+ children,
+ locationSearch,
+}) => {
+ const apiProvider = useVoucherAPIProvider();
+
+ const initialState = useInitialVouchersState();
+ const valueProvider = useUrlValueProvider(locationSearch, "voucher", initialState);
+ const leftOperandsProvider = useFilterLeftOperandsProvider(STATIC_VOUCHER_OPTIONS);
+ const containerState = useContainerState(valueProvider);
+ const filterWindow = useFilterWindow();
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const ConditionalPageFilterProvider: FC<{
+ locationSearch: string;
+}> = ({ children, locationSearch }) => {
+ const apiProvider = usePageAPIProvider();
+
+ const initialState = useInitialPageState();
+ const valueProvider = useUrlValueProvider(locationSearch, "page", initialState);
+ const leftOperandsProvider = useFilterLeftOperandsProvider(STATIC_PAGE_OPTIONS);
+ const containerState = useContainerState(valueProvider);
+ const filterWindow = useFilterWindow();
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const ConditionalDraftOrderFilterProvider: FC<{
+ locationSearch: string;
+}> = ({ children, locationSearch }) => {
+ const apiProvider = useDraftOrderFilterAPIProvider();
+
+ const valueProvider = useUrlValueProvider(locationSearch, "draft-order");
+ const leftOperandsProvider = useFilterLeftOperandsProvider(STATIC_DRAFT_ORDER_OPTIONS);
+ const containerState = useContainerState(valueProvider);
+ const filterWindow = useFilterWindow();
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const ConditionalGiftCardsFilterProver: FC<{ locationSearch: string }> = ({
+ children,
+ locationSearch,
+}) => {
+ const initialState = useInitialGiftCardsState();
+ const apiProvider = useGiftCardsFiltersAPIProvider();
+ const valueProvider = useUrlValueProvider(locationSearch, "gift-cards", initialState);
+ const leftOperandsProvider = useFilterLeftOperandsProvider(STATIC_GIFT_CARDS_OPTIONS);
+ const containerState = useContainerState(valueProvider);
+ const filterWindow = useFilterWindow();
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const ConditionalCustomerFilterProvider: FC<{
+ locationSearch: string;
+}> = ({ children, locationSearch }) => {
+ const apiProvider = useCustomerAPIProvider();
+
+ const valueProvider = useUrlValueProvider(locationSearch, "customer");
+ const leftOperandsProvider = useFilterLeftOperandsProvider(STATIC_CUSTOMER_OPTIONS);
+ const containerState = useContainerState(valueProvider);
+ const filterWindow = useFilterWindow();
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const ConditionalCollectionFilterProvider: FC<{
+ locationSearch: string;
+}> = ({ children, locationSearch }) => {
+ const apiProvider = useCollectionFilterAPIProvider();
+
+ const initialState = useInitialCollectionState();
+
+ const valueProvider = useUrlValueProvider(locationSearch, "collection", initialState);
+ const leftOperandsProvider = useFilterLeftOperandsProvider(STATIC_COLLECTION_OPTIONS);
+ const containerState = useContainerState(valueProvider);
+ const filterWindow = useFilterWindow();
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const ConditionalProductTypesFilterProvider: FC<{
+ locationSearch: string;
+}> = ({ children, locationSearch }) => {
+ const apiProvider = useProductTypesFilterAPIProvider();
+
+ const initialState = useInitialProductTypesState();
+ const valueProvider = useUrlValueProvider(locationSearch, "product-types", initialState);
+ const leftOperandsProvider = useFilterLeftOperandsProvider(STATIC_PRODUCT_TYPES_OPTIONS);
+ const containerState = useContainerState(valueProvider);
+ const filterWindow = useFilterWindow();
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const ConditionalStaffMembersFilterProvider: FC<{
+ locationSearch: string;
+}> = ({ children, locationSearch }) => {
+ const apiProvider = useStaffMembersFilterAPIProvider();
+
+ const initialState = useInitialStaffMembersState();
+ const valueProvider = useUrlValueProvider(locationSearch, "staff-members", initialState);
+ const leftOperandsProvider = useFilterLeftOperandsProvider(STAFF_MEMBER_OPTIONS);
+ const containerState = useContainerState(valueProvider);
+ const filterWindow = useFilterWindow();
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const ConditionalAttributesFilterProvider: FC<{
+ locationSearch: string;
+}> = ({ children, locationSearch }) => {
+ const apiProvider = useAttributesFilterAPIProvider();
+
+ const initialState = useInitialAttributesState();
+ const valueProvider = useUrlValueProvider(locationSearch, "attributes", initialState);
+ const leftOperandsProvider = useFilterLeftOperandsProvider(STATIC_ATTRIBUTES_OPTIONS);
+ const containerState = useContainerState(valueProvider);
+ const filterWindow = useFilterWindow();
+
+ return (
+
+ {children}
+
+ );
+};
diff --git a/src/components/ConditionalFilter/controlsType.ts b/src/components/ConditionalFilter/controlsType.ts
index 565ffcc0605..1f769677468 100644
--- a/src/components/ConditionalFilter/controlsType.ts
+++ b/src/components/ConditionalFilter/controlsType.ts
@@ -11,6 +11,7 @@ export const CONTROL_DEFAULTS = {
datetime: "",
"date.range": ["", ""] as [string, string],
"datetime.range": ["", ""] as [string, string],
+ "text.double": ["", ""] as [string, string],
};
export const getDefaultByControlName = (name: string): ConditionValue =>
diff --git a/src/components/ConditionalFilter/intl.ts b/src/components/ConditionalFilter/intl.ts
index 99e98ee9858..64f4b20389f 100644
--- a/src/components/ConditionalFilter/intl.ts
+++ b/src/components/ConditionalFilter/intl.ts
@@ -42,3 +42,14 @@ export const leftOperatorsMessages = defineMessages({
defaultMessage: "Is giftcard",
},
});
+
+export const metadataInputMessages = defineMessages({
+ keyPlaceholder: {
+ id: "EcglP9",
+ defaultMessage: "Key",
+ },
+ valuePlaceholder: {
+ id: "GufXy5",
+ defaultMessage: "Value",
+ },
+});
diff --git a/src/components/ConditionalFilter/queryVariables.test.ts b/src/components/ConditionalFilter/queryVariables.test.ts
index 853c298b586..19e627dfe0a 100644
--- a/src/components/ConditionalFilter/queryVariables.test.ts
+++ b/src/components/ConditionalFilter/queryVariables.test.ts
@@ -1,8 +1,21 @@
+import { ProductTypeConfigurable, ProductTypeEnum } from "@dashboard/graphql";
+
import { Condition, FilterContainer, FilterElement } from "./FilterElement";
import { ConditionOptions } from "./FilterElement/ConditionOptions";
import { ConditionSelected } from "./FilterElement/ConditionSelected";
import { ExpressionValue } from "./FilterElement/FilterElement";
-import { createProductQueryVariables } from "./queryVariables";
+import {
+ creatAttributesQueryVariables,
+ creatDraftOrderQueryVariables,
+ createCustomerQueryVariables,
+ createGiftCardQueryVariables,
+ createPageQueryVariables,
+ createProductQueryVariables,
+ createProductTypesQueryVariables,
+ createStaffMembersQueryVariables,
+ creatVoucherQueryVariables,
+ mapStaticQueryPartToLegacyVariables,
+} from "./queryVariables";
describe("ConditionalFilter / queryVariables / createProductQueryVariables", () => {
it("should return empty variables for empty filters", () => {
@@ -75,3 +88,648 @@ describe("ConditionalFilter / queryVariables / createProductQueryVariables", ()
expect(result).toEqual(expectedOutput);
});
});
+
+describe("ConditionalFilter / queryVariables / creatVoucherQueryVariables", () => {
+ it("should return empty variables for empty filters", () => {
+ // Arrange
+ const filters: FilterContainer = [];
+ const expectedOutput = {};
+ // Act
+ const result = creatVoucherQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual({
+ filters: expectedOutput,
+ channel: undefined,
+ });
+ });
+
+ it("should create variables with selected filters", () => {
+ // Arrange
+ const channelFilterElement = new FilterElement(
+ new ExpressionValue("channel", "Channel", "channel"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("channel"),
+ new ConditionSelected(
+ { label: "Channel 1", slug: "channel-1", value: "channel-1" },
+ { type: "select", label: "is", value: "input-5" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+
+ const discuntTypeFilterElement = new FilterElement(
+ new ExpressionValue("discountType", "Discount Type", "discountType"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("discountType"),
+ new ConditionSelected(
+ [
+ { value: "discount-1", slug: "discount-1", label: "Discount 1" },
+ { value: "discount-2", slug: "discount-2", label: "Discount 2" },
+ ],
+ { type: "multiselect", label: "in", value: "input-2" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+
+ const startedFilterElement = new FilterElement(
+ new ExpressionValue("started", "Started", "started"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("started"),
+ new ConditionSelected(
+ ["2025-01-31T16:24", "2025-02-15T16:24"],
+ { type: "datetime.range", label: "between", value: "input-3" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+
+ const voucherStatusFilterElement = new FilterElement(
+ new ExpressionValue("voucherStatus", "Voucher status", "voucherStatus"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("voucherStatus"),
+ new ConditionSelected(
+ { value: "status-1", slug: "status-1", label: "Status 1" },
+ { type: "combobox", label: "is", value: "input-1" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+
+ const timeUSedFilterElement = new FilterElement(
+ new ExpressionValue("timesUsed", "Time used", "timesUsed"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("timesUsed"),
+ new ConditionSelected("10", { type: "number", label: "is", value: "input-2" }, [], false),
+ false,
+ ),
+ false,
+ );
+
+ const filters: FilterContainer = [
+ channelFilterElement,
+ "AND",
+ discuntTypeFilterElement,
+ "AND",
+ timeUSedFilterElement,
+ "AND",
+ voucherStatusFilterElement,
+ "AND",
+ startedFilterElement,
+ ];
+ const expectedChannel = "channel-1";
+ const expectedOutput = {
+ discountType: ["discount-1", "discount-2"],
+ started: { lte: "2025-02-15T16:24", gte: "2025-01-31T16:24" },
+ timesUsed: { gte: 10, lte: 10 },
+ status: "status-1",
+ };
+ // Act
+ const result = creatVoucherQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual({
+ filters: expectedOutput,
+ channel: expectedChannel,
+ });
+ });
+});
+
+describe("ConditionalFilter / queryVariables / createPageQueryVariables", () => {
+ it("should return empty variables for empty filters", () => {
+ // Arrange
+ const filters: FilterContainer = [];
+ const expectedOutput = {};
+ // Act
+ const result = createPageQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+ it("should create variables with selected filters", () => {
+ // Arrange
+ const filters: FilterContainer = [
+ new FilterElement(
+ new ExpressionValue("pageTypes", "Product types", "pageTypes"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("pageTypes"),
+ new ConditionSelected(
+ [
+ { label: "pageTypes1", slug: "pageTypes1", value: "value1" },
+ { label: "pageTypes2", slug: "pageTypes2", value: "value2" },
+ ],
+ { type: "multiselect", label: "in", value: "input-1" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ ),
+ ];
+ const expectedOutput = {
+ pageTypes: ["value1", "value2"],
+ };
+ // Act
+ const result = createPageQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
+
+describe("ConditionalFilter / queryVariables / creatDraftOrderQueryVariables", () => {
+ it("should return empty variables for empty filters", () => {
+ // Arrange
+ const filters: FilterContainer = [];
+ const expectedOutput = {};
+ // Act
+ const result = creatDraftOrderQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should create variables with selected filters", () => {
+ // Arrange
+ const filters: FilterContainer = [
+ new FilterElement(
+ new ExpressionValue("customer", "Customer", "customer"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("customer"),
+ new ConditionSelected(
+ { label: "customer1", slug: "customer1", value: "value1" },
+ { type: "text", label: "is", value: "input-1" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ ),
+ "AND",
+ new FilterElement(
+ new ExpressionValue("created", "Created", "created"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("customer"),
+ new ConditionSelected(
+ ["2025-02-01", "2025-02-05"],
+ { type: "date.range", label: "between", value: "input-3" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ ),
+ ];
+ const expectedOutput = {
+ created: { gte: "2025-02-01", lte: "2025-02-05" },
+ customer: "value1",
+ };
+ // Act
+ const result = creatDraftOrderQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
+
+describe("ConditionalFilter / queryVariables / createGiftCardQueryVariables", () => {
+ it("should return empty variables for empty filters", () => {
+ // Arrange
+ const filters: FilterContainer = [];
+ const expectedOutput = {};
+ // Act
+ const result = createGiftCardQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should create variables with selected filters", () => {
+ // Arrange
+ const productsFilterElement = new FilterElement(
+ new ExpressionValue("products", "Products", "products"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("products"),
+ new ConditionSelected(
+ [
+ { label: "product1", slug: "product1", value: "value1" },
+ { label: "product2", slug: "product2", value: "value2" },
+ ],
+ { type: "multiselect", label: "in", value: "input-1" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+
+ const currencyFilterElement = new FilterElement(
+ new ExpressionValue("currency", "Currency", "currency"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("currency"),
+ new ConditionSelected(
+ { label: "USD", slug: "usd", value: "usd" },
+ { type: "select", label: "is", value: "input-1" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+
+ const currentBalanceFilterElement = new FilterElement(
+ new ExpressionValue("currentBalance", "Current balance", "currentBalance"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("currentBalance"),
+ new ConditionSelected(
+ ["1", "22"],
+ { type: "number.range", label: "between", value: "input-3" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+
+ const initialBalanceFilterElement = new FilterElement(
+ new ExpressionValue("initialBalance", "Initial balance", "initialBalance"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("initialBalance"),
+ new ConditionSelected(
+ "10",
+ { type: "number", label: "greater", value: "input-2" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+
+ const isActiveFilterElement = new FilterElement(
+ new ExpressionValue("isActive", "Is active", "isActive"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("isActive"),
+ new ConditionSelected(
+ { label: "Yes", value: "true", slug: "true" },
+ { type: "select", label: "is", value: "input-1" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+
+ const tagsFilterElement = new FilterElement(
+ new ExpressionValue("tags", "Tags", "tags"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("tags"),
+ new ConditionSelected(
+ [
+ { label: "Tag 1", value: "tag-1", slug: "tag-1" },
+ { label: "Tag 2", value: "tag-2", slug: "tag-2" },
+ ],
+ { type: "multiselect", label: "in", value: "input-1" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+
+ const usedByFilterElement = new FilterElement(
+ new ExpressionValue("usedBy", "Used by", "usedBy"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("usedBy"),
+ new ConditionSelected(
+ [
+ { label: "Customer 1", value: "customer-1", slug: "customer-1" },
+ { label: "Customer 2", value: "customer-2", slug: "customer-2" },
+ ],
+ { type: "multiselect", label: "in", value: "input-1" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+
+ const filters: FilterContainer = [
+ currencyFilterElement,
+ "AND",
+ productsFilterElement,
+ "AND",
+ currentBalanceFilterElement,
+ "AND",
+ initialBalanceFilterElement,
+ "AND",
+ isActiveFilterElement,
+ "AND",
+ tagsFilterElement,
+ "AND",
+ usedByFilterElement,
+ ];
+ const expectedOutput = {
+ currency: "usd",
+ currentBalance: {
+ gte: "1",
+ lte: "22",
+ },
+ initialBalance: {
+ gte: "10",
+ },
+ isActive: true,
+ products: ["value1", "value2"],
+ tags: ["tag-1", "tag-2"],
+ usedBy: ["customer-1", "customer-2"],
+ };
+
+ // Act
+ const result = createGiftCardQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
+
+describe("ConditionalFilter / queryVariables / createCustomerQueryVariables", () => {
+ it("should return empty variables for empty filters", () => {
+ // Arrange
+ const filters: FilterContainer = [];
+ const expectedOutput = {};
+ // Act
+ const result = createCustomerQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should create variables with selected filters", () => {
+ // Arrange
+ const filters: FilterContainer = [
+ new FilterElement(
+ new ExpressionValue("dateJoined", "Date joined", "dateJoined"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("dateJoined"),
+ new ConditionSelected(
+ ["2025-02-01", "2025-02-08"],
+ { type: "number.range", label: "between", value: "input-2" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ ),
+ "AND",
+ new FilterElement(
+ new ExpressionValue("numberOfOrders", "Number of orders", "numberOfOrders"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("numberOfOrders"),
+ new ConditionSelected(
+ ["1", "100"],
+ { type: "number.range", label: "between", value: "input-2" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ ),
+ ];
+ const expectedOutput = {
+ dateJoined: { gte: "2025-02-01", lte: "2025-02-08" },
+ numberOfOrders: { gte: "1", lte: "100" },
+ };
+ // Act
+ const result = createCustomerQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
+
+describe("ConditionalFilter / queryVariables / createProductTypesQueryVariables", () => {
+ it("should return empty variables for empty filters", () => {
+ // Arrange
+ const filters: FilterContainer = [];
+ const expectedOutput = {};
+ // Act
+ const result = createProductTypesQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should create variables with selected filters", () => {
+ // Arrange
+ const filters: FilterContainer = [
+ new FilterElement(
+ new ExpressionValue("typeOfProduct", "Product type", "typeOfProduct"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("typeOfProduct"),
+ new ConditionSelected(
+ ProductTypeEnum.DIGITAL,
+ { type: "select", label: "is", value: "input-1" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ ),
+ "AND",
+ new FilterElement(
+ new ExpressionValue("configurable", "Configurable", "configurable"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("configurable"),
+ new ConditionSelected(
+ ProductTypeConfigurable.SIMPLE,
+ { type: "select", label: "is", value: "input-1" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ ),
+ ];
+ const expectedOutput = {
+ productType: "DIGITAL",
+ configurable: "SIMPLE",
+ };
+ // Act
+ const result = createProductTypesQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
+
+describe("ConditionalFilter / queryVariables / createStaffMembersQueryVariables", () => {
+ it("should return empty variables for empty filters", () => {
+ // Arrange
+ const filters: FilterContainer = [];
+ const expectedOutput = {};
+ // Act
+ const result = createStaffMembersQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should create variables with selected filters", () => {
+ // Arrange
+ const filters: FilterContainer = [
+ new FilterElement(
+ new ExpressionValue("staffMemberStatus", "Status", "staffMemberStatus"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("staffMemberStatus"),
+ new ConditionSelected(
+ "active",
+ { type: "select", label: "is", value: "input-1" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ ),
+ ];
+ const expectedOutput = {
+ status: "active",
+ };
+ // Act
+ const result = createStaffMembersQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
+
+describe("ConditionalFilter / queryVariables / creatAttributesQueryVariables", () => {
+ it("should return empty variables for empty filters", () => {
+ // Arrange
+ const filters: FilterContainer = [];
+ const expectedOutput = {};
+ // Act
+ const result = creatAttributesQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should create variables with selected filters", () => {
+ // Arrange
+ const channelFilterElemen = new FilterElement(
+ new ExpressionValue("channel", "Channel", "channel"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("channel"),
+ new ConditionSelected(
+ "default-channel",
+ { type: "select", label: "is", value: "input-5" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+
+ const typeFilterElement = new FilterElement(
+ new ExpressionValue("attributeType", "Attribute type", "attributeType"),
+ new Condition(
+ ConditionOptions.fromStaticElementName("attributeType"),
+ new ConditionSelected(
+ "PRODUCT_TYPE",
+ { type: "select", label: "is", value: "input-1" },
+ [],
+ false,
+ ),
+ false,
+ ),
+ false,
+ );
+
+ const filters: FilterContainer = [channelFilterElemen, "AND", typeFilterElement];
+ const expectedOutput = {
+ channel: "default-channel",
+ type: "PRODUCT_TYPE",
+ };
+ // Act
+ const result = creatAttributesQueryVariables(filters);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
+
+describe("ConditionalFilter / queryVariables / mapStaticQueryPartToLegacyVariables", () => {
+ it("should return queryPart if it is not an object", () => {
+ // Arrange
+ const queryPart = "queryPart";
+ const expectedOutput = "queryPart";
+
+ // Act
+ const result = mapStaticQueryPartToLegacyVariables(queryPart);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should transform range input to legacy format", () => {
+ // Arrange
+ const queryPart = { range: { lte: "value" } };
+ const expectedOutput = { lte: "value" };
+
+ // Act
+ const result = mapStaticQueryPartToLegacyVariables(queryPart);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should transform eq input to legacy format", () => {
+ // Arrange
+ const queryPart = { eq: "value" };
+ const expectedOutput = "value";
+ // Act
+ const result = mapStaticQueryPartToLegacyVariables(queryPart);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+
+ it("should transform oneOf input to legacy format", () => {
+ // Arrange
+ const queryPart = { oneOf: ["value1", "value2"] };
+ const expectedOutput = ["value1", "value2"];
+ // Act
+ const result = mapStaticQueryPartToLegacyVariables(queryPart);
+
+ // Assert
+ expect(result).toEqual(expectedOutput);
+ });
+});
diff --git a/src/components/ConditionalFilter/queryVariables.ts b/src/components/ConditionalFilter/queryVariables.ts
index 412006d39c6..a809c7ee534 100644
--- a/src/components/ConditionalFilter/queryVariables.ts
+++ b/src/components/ConditionalFilter/queryVariables.ts
@@ -1,13 +1,23 @@
import {
+ AttributeFilterInput,
AttributeInput,
+ CollectionFilterInput,
+ CollectionPublished,
+ CustomerFilterInput,
DateRangeInput,
DateTimeFilterInput,
DateTimeRangeInput,
DecimalFilterInput,
+ GiftCardFilterInput,
GlobalIdFilterInput,
- OrderFilterInput,
+ OrderDraftFilterInput,
+ PageFilterInput,
+ ProductTypeConfigurable,
+ ProductTypeFilterInput,
ProductWhereInput,
PromotionWhereInput,
+ StaffUserInput,
+ VoucherFilterInput,
} from "@dashboard/graphql";
import { FilterContainer } from "./FilterElement";
@@ -49,6 +59,10 @@ const createStaticQueryPart = (selected: ConditionSelected): StaticQueryPart =>
}
if (typeof value === "string") {
+ if (["true", "false"].includes(value)) {
+ return value === "true";
+ }
+
return { eq: value };
}
@@ -58,6 +72,27 @@ const createStaticQueryPart = (selected: ConditionSelected): StaticQueryPart =>
return value;
};
+
+export const mapStaticQueryPartToLegacyVariables = (queryPart: StaticQueryPart) => {
+ if (typeof queryPart !== "object") {
+ return queryPart;
+ }
+
+ if ("range" in queryPart) {
+ return queryPart.range;
+ }
+
+ if ("eq" in queryPart) {
+ return queryPart.eq;
+ }
+
+ if ("oneOf" in queryPart) {
+ return queryPart.oneOf;
+ }
+
+ return queryPart;
+};
+
const getRangeQueryPartByType = (value: [string, string], type: string) => {
const [gte, lte] = value;
@@ -71,6 +106,7 @@ const getRangeQueryPartByType = (value: [string, string], type: string) => {
return { valuesRange: { lte: parseFloat(lte), gte: parseFloat(gte) } };
}
};
+
const getQueryPartByType = (value: string, type: string, what: "lte" | "gte") => {
switch (type) {
case "datetime":
@@ -81,6 +117,7 @@ const getQueryPartByType = (value: string, type: string, what: "lte" | "gte") =>
return { valuesRange: { [what]: parseFloat(value) } };
}
};
+
const createAttributeQueryPart = (
attributeSlug: string,
selected: ConditionSelected,
@@ -133,6 +170,11 @@ const createAttributeQueryPart = (
type ProductQueryVars = ProductWhereInput & { channel?: { eq: string } };
+/*
+ Map to ProductQueryVars as long as it does not have "where" filter - it would use mostly same keys.
+*/
+export type OrderQueryVars = ProductQueryVars & { created?: DateTimeRangeInput | DateRangeInput };
+
export const createProductQueryVariables = (value: FilterContainer): ProductQueryVars => {
return value.reduce((p, c) => {
if (typeof c === "string" || Array.isArray(c)) return p;
@@ -163,23 +205,239 @@ export const createDiscountsQueryVariables = (value: FilterContainer): Promotion
};
export const createOrderQueryVariables = (value: FilterContainer) => {
- return value.reduce((p, c) => {
+ return value.reduce((p: OrderQueryVars, c) => {
if (typeof c === "string" || Array.isArray(c)) {
return p;
}
+ if (c.value.type === "metadata") {
+ p.metadata = p.metadata || [];
+
+ const [key, value] = c.condition.selected.value as [string, string];
+
+ p.metadata.push({ key, value });
+
+ return p;
+ }
+
if (c.value.type === "updatedAt" || c.value.type === "created") {
p[c.value.value as "updatedAt" | "created"] = createStaticQueryPart(c.condition.selected) as
| DateTimeRangeInput
| DateRangeInput;
+
+ return p;
+ }
+
+ if (c.isStatic()) {
+ p[c.value.value as keyof OrderQueryVars] = createStaticQueryPart(c.condition.selected);
+
+ return p;
+ }
+
+ return p;
+ }, {} as OrderQueryVars);
+};
+
+export const creatVoucherQueryVariables = (
+ value: FilterContainer,
+): { filters: VoucherFilterInput; channel: string | undefined } => {
+ let channel: string | undefined;
+
+ const filters = value.reduce((p, c) => {
+ if (typeof c === "string" || Array.isArray(c)) return p;
+
+ if (c.value.type === "channel") {
+ if (isItemOption(c.condition.selected.value)) {
+ channel = c.condition.selected.value.slug;
+ } else {
+ channel = c.condition.selected.value as string;
+ }
+
+ return p;
+ }
+
+ if (c.value.type === "timesUsed") {
+ if (typeof c.condition.selected.value === "string") {
+ p["timesUsed"] = {
+ gte: Number(c.condition.selected.value),
+ lte: Number(c.condition.selected.value),
+ };
+
+ return p;
+ }
}
+ if (c.value.type === "voucherStatus") {
+ p["status"] = mapStaticQueryPartToLegacyVariables(
+ createStaticQueryPart(c.condition.selected),
+ );
+
+ return p;
+ }
+
+ p[c.value.value as keyof VoucherFilterInput] = mapStaticQueryPartToLegacyVariables(
+ createStaticQueryPart(c.condition.selected),
+ );
+
+ return p;
+ }, {} as VoucherFilterInput);
+
+ return {
+ channel,
+ filters,
+ };
+};
+
+export const createPageQueryVariables = (value: FilterContainer): PageFilterInput => {
+ return value.reduce((p, c) => {
+ if (typeof c === "string" || Array.isArray(c)) return p;
+
+ p[c.value.value as keyof PageFilterInput] = mapStaticQueryPartToLegacyVariables(
+ createStaticQueryPart(c.condition.selected),
+ );
+
+ return p;
+ }, {} as PageFilterInput);
+};
+
+export const creatDraftOrderQueryVariables = (value: FilterContainer): OrderDraftFilterInput => {
+ return value.reduce((p, c) => {
+ if (typeof c === "string" || Array.isArray(c)) return p;
+
+ p[c.value.value as keyof OrderDraftFilterInput] = mapStaticQueryPartToLegacyVariables(
+ createStaticQueryPart(c.condition.selected),
+ );
+
+ return p;
+ }, {} as OrderDraftFilterInput);
+};
+
+export const createGiftCardQueryVariables = (value: FilterContainer) => {
+ return value.reduce((p, c) => {
+ if (typeof c === "string" || Array.isArray(c)) return p;
+
if (c.isStatic()) {
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore - seems to be a bug in TS, works fine in 5.4.5
- p[c.value.value] = createStaticQueryPart(c.condition.selected);
+ (p[c.value.value as keyof GiftCardFilterInput] as any) = mapStaticQueryPartToLegacyVariables(
+ createStaticQueryPart(c.condition.selected),
+ );
}
return p;
- }, {} as OrderFilterInput);
+ }, {} as GiftCardFilterInput);
+};
+
+export const createCustomerQueryVariables = (value: FilterContainer): CustomerFilterInput => {
+ return value.reduce((p, c) => {
+ if (typeof c === "string" || Array.isArray(c)) return p;
+
+ if (c.value.type === "numberOfOrders" && c.condition.selected.conditionValue?.label === "is") {
+ p["numberOfOrders"] = {
+ gte: Number(c.condition.selected.value),
+ lte: Number(c.condition.selected.value),
+ };
+
+ return p;
+ }
+
+ p[c.value.value as keyof CustomerFilterInput] = mapStaticQueryPartToLegacyVariables(
+ createStaticQueryPart(c.condition.selected),
+ );
+
+ return p;
+ }, {} as CustomerFilterInput);
+};
+
+type CollectionQueryVars = CollectionFilterInput & { channel?: { eq: string } };
+
+export const createCollectionsQueryVariables = (value: FilterContainer): CollectionQueryVars => {
+ return value.reduce((p, c) => {
+ if (typeof c === "string" || Array.isArray(c)) return p;
+
+ const value = mapStaticQueryPartToLegacyVariables(createStaticQueryPart(c.condition.selected));
+
+ if (c.value.type === "metadata") {
+ p.metadata = p.metadata || [];
+
+ const [key, value] = c.condition.selected.value as [string, string];
+
+ p.metadata.push({ key, value });
+
+ return p;
+ }
+
+ if (c.value.type === "published") {
+ p["published"] = value === true ? CollectionPublished.PUBLISHED : CollectionPublished.HIDDEN;
+
+ return p;
+ }
+
+ p[c.value.value as keyof CollectionFilterInput] = value;
+
+ return p;
+ }, {} as CollectionQueryVars);
+};
+
+export const createProductTypesQueryVariables = (
+ value: FilterContainer,
+): ProductTypeFilterInput => {
+ return value.reduce((p, c) => {
+ if (typeof c === "string" || Array.isArray(c)) return p;
+
+ const value = mapStaticQueryPartToLegacyVariables(createStaticQueryPart(c.condition.selected));
+
+ if (c.value.type === "typeOfProduct") {
+ p["productType"] = value;
+
+ return p;
+ }
+
+ if (c.value.type === "configurable") {
+ p["configurable"] =
+ value === true ? ProductTypeConfigurable.CONFIGURABLE : ProductTypeConfigurable.SIMPLE;
+
+ return p;
+ }
+
+ (p[c.value.value as keyof ProductTypeFilterInput] as ProductTypeFilterInput) = value;
+
+ return p;
+ }, {} as ProductTypeFilterInput);
+};
+
+export const createStaffMembersQueryVariables = (value: FilterContainer): StaffUserInput => {
+ return value.reduce((p, c) => {
+ if (typeof c === "string" || Array.isArray(c)) return p;
+
+ if (c.value.type === "staffMemberStatus") {
+ p["status"] = mapStaticQueryPartToLegacyVariables(
+ createStaticQueryPart(c.condition.selected),
+ );
+
+ return p;
+ }
+
+ p[c.value.value as keyof StaffUserInput] = mapStaticQueryPartToLegacyVariables(
+ createStaticQueryPart(c.condition.selected),
+ );
+
+ return p;
+ }, {} as StaffUserInput);
+};
+
+export const creatAttributesQueryVariables = (value: FilterContainer): AttributeFilterInput => {
+ return value.reduce((p, c) => {
+ if (typeof c === "string" || Array.isArray(c)) return p;
+
+ if (c.value.type === "attributeType") {
+ p["type"] = mapStaticQueryPartToLegacyVariables(createStaticQueryPart(c.condition.selected));
+
+ return p;
+ }
+
+ (p[c.value.value as keyof AttributeFilterInput] as any) = mapStaticQueryPartToLegacyVariables(
+ createStaticQueryPart(c.condition.selected),
+ );
+
+ return p;
+ }, {} as AttributeFilterInput);
};
diff --git a/src/components/ConditionalFilter/types.ts b/src/components/ConditionalFilter/types.ts
new file mode 100644
index 00000000000..0b9cde1ad1f
--- /dev/null
+++ b/src/components/ConditionalFilter/types.ts
@@ -0,0 +1,54 @@
+import { InitialAttributesStateResponse } from "./API/initialState/attributes/InitialAttributesState";
+import { InitialAttributesAPIState } from "./API/initialState/attributes/useInitialAttributesState";
+import { InitialCollectionStateResponse } from "./API/initialState/collections/InitialCollectionState";
+import { InitialCollectionAPIState } from "./API/initialState/collections/useInitialCollectionsState";
+import { InitialGiftCardsStateResponse } from "./API/initialState/giftCards/InitialGiftCardsState";
+import { InitialGiftCardsAPIState } from "./API/initialState/giftCards/useInitialGiftCardsState";
+import { InitialOrderStateResponse } from "./API/initialState/orders/InitialOrderState";
+import { InitialOrderAPIState } from "./API/initialState/orders/useInitialOrderState";
+import { InitialPageStateResponse } from "./API/initialState/page/InitialPageState";
+import { InitialPageAPIState } from "./API/initialState/page/useInitialPageState";
+import { InitialProductStateResponse } from "./API/initialState/product/InitialProductStateResponse";
+import { InitialProductAPIState } from "./API/initialState/product/useProductInitialAPIState";
+import { InitialProductTypesStateResponse } from "./API/initialState/productTypes/InitialProductTypesState";
+import { InitialProductTypesAPIState } from "./API/initialState/productTypes/useInitialProdutTypesState";
+import { InitialStaffMembersStateResponse } from "./API/initialState/staffMembers/InitialStaffMembersState";
+import { InitialStaffMembersAPIState } from "./API/initialState/staffMembers/useInitialStaffMemebersState";
+import { InitialVouchersStateResponse } from "./API/initialState/vouchers/InitialVouchersState";
+import { InitialVoucherAPIState } from "./API/initialState/vouchers/useInitialVouchersState";
+
+export type InitialResponseType =
+ | InitialProductStateResponse
+ | InitialOrderStateResponse
+ | InitialCollectionStateResponse
+ | InitialVouchersStateResponse
+ | InitialPageStateResponse
+ | InitialProductTypesStateResponse
+ | InitialGiftCardsStateResponse
+ | InitialStaffMembersStateResponse
+ | InitialAttributesStateResponse;
+
+export type InitialAPIState =
+ | InitialProductAPIState
+ | InitialOrderAPIState
+ | InitialVoucherAPIState
+ | InitialPageAPIState
+ | InitialGiftCardsAPIState
+ | InitialCollectionAPIState
+ | InitialProductTypesAPIState
+ | InitialStaffMembersAPIState
+ | InitialAttributesAPIState;
+
+export type FilterProviderType =
+ | "product"
+ | "order"
+ | "discount"
+ | "customer"
+ | "voucher"
+ | "page"
+ | "draft-order"
+ | "gift-cards"
+ | "collection"
+ | "product-types"
+ | "staff-members"
+ | "attributes";
diff --git a/src/components/ConditionalFilter/useContainerState.ts b/src/components/ConditionalFilter/useContainerState.ts
index 3b6e7fa9cd7..76d8072b68f 100644
--- a/src/components/ConditionalFilter/useContainerState.ts
+++ b/src/components/ConditionalFilter/useContainerState.ts
@@ -103,7 +103,8 @@ export const useContainerState = (valueProvider: FilterValueProvider) => {
setValue(v => removeElement(v, index));
};
- const create = (element: FilterElement) => {
+
+ const createNewValue = (value: FilterContainer, element: FilterElement) => {
const newValue: FilterContainer = [];
if (value.length > 0) {
@@ -111,8 +112,26 @@ export const useContainerState = (valueProvider: FilterValueProvider) => {
}
newValue.push(element);
+
+ return newValue;
+ };
+
+ const create = (element: FilterElement) => {
+ const newValue = createNewValue(value, element);
+
setValue(v => v.concat(newValue));
};
+
+ // This function was created to cover a case when on click outside filter handler
+ // fire state update, but applied of those state change happened after create function call,
+ // so we have not removed empty values in container
+ const createAndRemoveEmpty = (element: FilterElement) => {
+ const filteredValue = removeEmptyElements(value, valueProvider);
+ const newValue = createNewValue(filteredValue, element);
+
+ setValue(() => filteredValue.concat(newValue));
+ };
+
const exist = (slug: string) => {
return value.some(entry => FilterElement.isCompatible(entry) && entry.value.value === slug);
};
@@ -128,6 +147,7 @@ export const useContainerState = (valueProvider: FilterValueProvider) => {
return {
create,
+ createAndRemoveEmpty,
exist,
updateBySlug,
createEmpty,
diff --git a/src/components/ControlledSwitch.tsx b/src/components/ControlledSwitch.tsx
index ff66a5374b6..1469525edb5 100644
--- a/src/components/ControlledSwitch.tsx
+++ b/src/components/ControlledSwitch.tsx
@@ -1,17 +1,8 @@
// @ts-strict-ignore
import { FormControlLabel, Switch } from "@material-ui/core";
-import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
-const useStyles = makeStyles(
- () => ({
- labelText: {
- fontSize: 14,
- },
- }),
- { name: "ControlledSwitch" },
-);
-
interface ControlledSwitchProps {
className?: string;
checked: boolean;
@@ -26,7 +17,6 @@ interface ControlledSwitchProps {
export const ControlledSwitch: React.FC = props => {
const { checked, disabled, onChange, label, name, secondLabel, uncheckedLabel, className } =
props;
- const classes = useStyles(props);
return (
= props => {
uncheckedLabel
)
) : typeof label === "string" ? (
- {label}
+ {label}
) : (
label
)}
diff --git a/src/components/CountryList/CountryList.tsx b/src/components/CountryList/CountryList.tsx
index 7b5cc02ebe0..3b9bc4914e3 100644
--- a/src/components/CountryList/CountryList.tsx
+++ b/src/components/CountryList/CountryList.tsx
@@ -1,18 +1,18 @@
// @ts-strict-ignore
import { Button } from "@dashboard/components/Button";
-import CardTitle from "@dashboard/components/CardTitle";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
-import Skeleton from "@dashboard/components/Skeleton";
import TableRowLink from "@dashboard/components/TableRowLink";
import { CountryFragment } from "@dashboard/graphql";
-import { Card, TableBody, TableCell } from "@material-ui/core";
+import { TableBody, TableCell } from "@material-ui/core";
import ArrowDropDownIcon from "@material-ui/icons/ArrowDropDown";
import { DeleteIcon, IconButton, makeStyles } from "@saleor/macaw-ui";
+import { Skeleton } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
import { FormattedMessage } from "react-intl";
import { getStringOrPlaceholder, maybe, renderCollection } from "../../misc";
+import { DashboardCard } from "../Card";
export interface CountryListProps {
countries: CountryFragment[];
@@ -82,15 +82,15 @@ const CountryList: React.FC = props => {
}
return (
-
-
+
+ {title}
+
- }
- />
+
+
@@ -157,7 +157,7 @@ const CountryList: React.FC = props => {
)}
-
+
);
};
diff --git a/src/components/CreatorSteps/CreatorSteps.tsx b/src/components/CreatorSteps/CreatorSteps.tsx
index 397a73d2669..06973c7432f 100644
--- a/src/components/CreatorSteps/CreatorSteps.tsx
+++ b/src/components/CreatorSteps/CreatorSteps.tsx
@@ -1,5 +1,5 @@
-import { Typography } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
@@ -62,9 +62,9 @@ function makeCreatorSteps() {
onClick={visitedStep ? () => onStepClick(step.value) : undefined}
key={step.value}
>
-
+
{step.label}
-
+
);
})}
diff --git a/src/components/Datagrid/Datagrid.tsx b/src/components/Datagrid/Datagrid.tsx
index 04291b6999b..b7153c96794 100644
--- a/src/components/Datagrid/Datagrid.tsx
+++ b/src/components/Datagrid/Datagrid.tsx
@@ -1,6 +1,7 @@
import "@glideapps/glide-data-grid/dist/index.css";
-import useNavigator from "@dashboard/hooks/useNavigator";
+import { useRowAnchorHandler } from "@dashboard/components/Datagrid/hooks/useRowAnchorHandler";
+import { NavigatorOpts } from "@dashboard/hooks/useNavigator";
import { usePreventHistoryBack } from "@dashboard/hooks/usePreventHistoryBack";
import { getCellAction } from "@dashboard/products/components/ProductListDatagrid/datagrid";
import DataEditor, {
@@ -16,7 +17,7 @@ import DataEditor, {
Theme,
} from "@glideapps/glide-data-grid";
import { GetRowThemeCallback } from "@glideapps/glide-data-grid/dist/ts/data-grid/data-grid-render";
-import { Card, CardContent, CircularProgress } from "@material-ui/core";
+import { CircularProgress } from "@material-ui/core";
import { Box, Text, useTheme } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import range from "lodash/range";
@@ -31,6 +32,7 @@ import React, {
useState,
} from "react";
+import { DashboardCard } from "../Card";
import { CardMenuItem } from "../CardMenu";
import { FullScreenContainer } from "./components/FullScreenContainer";
import { RowActions } from "./components/RowActions";
@@ -97,6 +99,7 @@ export interface DatagridProps {
recentlyAddedColumn?: string | null; // Enables scroll to recently added column
onClearRecentlyAddedColumn?: () => void;
renderHeader?: (props: DatagridRenderHeaderProps) => ReactNode;
+ navigatorOpts?: NavigatorOpts;
}
export const Datagrid: React.FC = ({
@@ -129,6 +132,7 @@ export const Datagrid: React.FC = ({
onClearRecentlyAddedColumn,
rowHeight = cellHeight,
renderHeader,
+ navigatorOpts,
...datagridProps
}): ReactElement => {
const classes = useStyles({ actionButtonPosition });
@@ -136,7 +140,6 @@ export const Datagrid: React.FC = ({
const datagridTheme = useDatagridTheme(readonly, readonly);
const editor = useRef(null);
const customRenderers = useCustomCellRenderers();
- const navigate = useNavigator();
const { scrolledToRight, scroller } = useScrollRight();
const fullScreenClasses = useFullScreenStyles(classes);
const { isOpen, isAnimationOpenFinished, toggle } = useFullScreenMode();
@@ -149,6 +152,7 @@ export const Datagrid: React.FC = ({
rowMarkers,
availableColumns,
});
+ const rowAnchorHandler = useRowAnchorHandler(navigatorOpts);
const { handleRowHover, hoverRow } = useRowHover({
hasRowHover,
@@ -393,7 +397,7 @@ export const Datagrid: React.FC = ({
if (loading) {
return (
-
+
);
@@ -401,14 +405,20 @@ export const Datagrid: React.FC = ({
return (
-
+
{renderHeader?.({
toggleFullscreen: toggle,
addRowOnDatagrid: onRowAdded,
isFullscreenOpen: isOpen,
isAnimationOpenFinished,
})}
-
+
{rowsTotal > 0 || showEmptyDatagrid ? (
<>
{selection?.rows && selection?.rows.length > 0 && selectionActionsComponent && (
@@ -506,8 +516,8 @@ export const Datagrid: React.FC = ({
)}
-
-
+
+
= ({
{rowAnchor && (
{
- e.preventDefault();
-
- if (e.currentTarget.dataset.reactRouterPath) {
- navigate(e.currentTarget.dataset.reactRouterPath);
- }
- }}
+ onClick={rowAnchorHandler}
/>
)}
diff --git a/src/components/Datagrid/customCells/PillCell.tsx b/src/components/Datagrid/customCells/PillCell.tsx
index e3f39bc4f5c..9e5d97c6a75 100644
--- a/src/components/Datagrid/customCells/PillCell.tsx
+++ b/src/components/Datagrid/customCells/PillCell.tsx
@@ -81,12 +81,15 @@ export const pillCellRenderer = (): CustomRenderer => ({
const tileHeight = textHeight * 1.2;
// Draw the tile
- ctx.fillStyle = base;
- ctx.strokeStyle = border;
- ctx.beginPath();
- ctx.roundRect(x + 10, y + height / 2 - tileHeight / 2, tileWidth, tileHeight, 5);
- ctx.stroke();
- ctx.fill();
+ if ("roundRect" in ctx) {
+ ctx.fillStyle = base;
+ ctx.strokeStyle = border;
+ ctx.beginPath();
+ ctx.roundRect(x + 10, y + height / 2 - tileHeight / 2, tileWidth, tileHeight, 5);
+ ctx.stroke();
+ ctx.fill();
+ }
+
// Draw the text
ctx.fillStyle = text;
ctx.fillText(label, x + 15, y + height / 2 + getMiddleCenterBias(ctx, theme));
diff --git a/src/components/Datagrid/hooks/useRowAnchorHandler.test.ts b/src/components/Datagrid/hooks/useRowAnchorHandler.test.ts
new file mode 100644
index 00000000000..0fa8a6c99ab
--- /dev/null
+++ b/src/components/Datagrid/hooks/useRowAnchorHandler.test.ts
@@ -0,0 +1,80 @@
+import useNavigator from "@dashboard/hooks/useNavigator";
+import { renderHook } from "@testing-library/react-hooks";
+
+import { useRowAnchorHandler } from "./useRowAnchorHandler";
+
+jest.mock("@dashboard/hooks/useNavigator", () => jest.fn());
+
+jest.mock("@dashboard/hooks/useNavigator", () => ({
+ __esModule: true,
+ default: jest.fn(() => jest.fn()),
+}));
+
+describe("useRowAnchorHandler", () => {
+ it("should navigate to the given path", () => {
+ // Arrange
+ const navigate = jest.fn();
+
+ (useNavigator as jest.Mock).mockReturnValue(navigate);
+
+ const navigatorOpts = { replace: true };
+ const handler = renderHook(() => useRowAnchorHandler(navigatorOpts)).result.current;
+ const event = {
+ preventDefault: jest.fn(),
+ currentTarget: {
+ dataset: {
+ reactRouterPath: "/some-path",
+ },
+ },
+ };
+
+ // Act
+ handler(event as any);
+
+ // Assert
+ expect(event.preventDefault).toHaveBeenCalled();
+ expect(navigate).toHaveBeenCalledWith("/some-path", navigatorOpts);
+ });
+
+ it("should not prevent default when CMD key is pressed", () => {
+ // Arrange
+ const navigate = jest.fn();
+
+ (useNavigator as jest.Mock).mockReturnValue(navigate);
+
+ const handler = renderHook(() => useRowAnchorHandler()).result.current;
+ const event = {
+ preventDefault: jest.fn(),
+ metaKey: true,
+ ctrlKey: false,
+ };
+
+ // Act
+ handler(event as any);
+
+ // Assert
+ expect(event.preventDefault).not.toHaveBeenCalled();
+ expect(navigate).not.toHaveBeenCalled();
+ });
+
+ it("should not prevent default when CTRL key is pressed", () => {
+ // Arrange
+ const navigate = jest.fn();
+
+ (useNavigator as jest.Mock).mockReturnValue(navigate);
+
+ const handler = renderHook(() => useRowAnchorHandler()).result.current;
+ const event = {
+ preventDefault: jest.fn(),
+ metaKey: false,
+ ctrlKey: true,
+ };
+
+ // Act
+ handler(event as any);
+
+ // Assert
+ expect(event.preventDefault).not.toHaveBeenCalled();
+ expect(navigate).not.toHaveBeenCalled();
+ });
+});
diff --git a/src/components/Datagrid/hooks/useRowAnchorHandler.ts b/src/components/Datagrid/hooks/useRowAnchorHandler.ts
new file mode 100644
index 00000000000..a85acf35a04
--- /dev/null
+++ b/src/components/Datagrid/hooks/useRowAnchorHandler.ts
@@ -0,0 +1,22 @@
+import useNavigator, { NavigatorOpts } from "@dashboard/hooks/useNavigator";
+import { MouseEvent } from "react";
+
+export const useRowAnchorHandler = (navigatorOpts?: NavigatorOpts) => {
+ const navigate = useNavigator();
+
+ return (e: MouseEvent) => {
+ // When someone clicks with CMD key to open in new tab, we should not prevent default
+ if (e.metaKey || e.ctrlKey) {
+ return;
+ }
+
+ // Prevent default when navigate with browser router
+ e.preventDefault();
+
+ if (e.currentTarget.dataset.reactRouterPath) {
+ // Navigate gets only a path to navigate, for example, /products/1
+ // Navigate use browser router and cover case when url is with /dashboard or not
+ navigate(e.currentTarget.dataset.reactRouterPath, navigatorOpts);
+ }
+ };
+};
diff --git a/src/components/Datagrid/styles.ts b/src/components/Datagrid/styles.ts
index 67427f0a2c7..69d8c7aa23b 100644
--- a/src/components/Datagrid/styles.ts
+++ b/src/components/Datagrid/styles.ts
@@ -97,9 +97,6 @@ const useStyles = makeStyles<{ actionButtonPosition?: "left" | "right" }>(
width: "100%",
paddingBottom: "1px",
},
- root: {
- position: "relative",
- },
rowActionBar: {
height: "100%",
width: 36,
@@ -159,14 +156,6 @@ const useStyles = makeStyles<{ actionButtonPosition?: "left" | "right" }>(
boxShadow: "-1px 0px 12px rgba(0, 0, 0, 0.80)",
},
rowActionSelected,
- cardContentRoot: {
- padding: "0",
- flex: 1,
-
- "&:last-child": {
- padding: "0",
- },
- },
};
},
{ name: "Datagrid" },
diff --git a/src/components/Datagrid/types.ts b/src/components/Datagrid/types.ts
index f7bd78682e4..28c2d882a20 100644
--- a/src/components/Datagrid/types.ts
+++ b/src/components/Datagrid/types.ts
@@ -10,5 +10,5 @@ export interface AvailableColumn {
hasMenu?: boolean;
icon?: string;
themeOverride?: Partial;
- action?: (id: string) => void;
+ action?: (id: string) => boolean;
}
diff --git a/src/components/DeleteButton/DeleteButton.tsx b/src/components/DeleteButton/DeleteButton.tsx
index c9c46053599..b0056bbf287 100644
--- a/src/components/DeleteButton/DeleteButton.tsx
+++ b/src/components/DeleteButton/DeleteButton.tsx
@@ -1,5 +1,5 @@
-import { Button } from "@dashboard/components/Button";
import { buttonMessages } from "@dashboard/intl";
+import { Button } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
@@ -20,8 +20,7 @@ const DeleteButton: React.FC = ({
return (
= ({
})}
variant="delete"
>
-
- {tabName},
- }}
- />
-
+ {tabName},
+ }}
+ />
);
};
diff --git a/src/components/DevModePanel/DevModePanel.tsx b/src/components/DevModePanel/DevModePanel.tsx
index 67f7e1c0a52..6f854418d29 100644
--- a/src/components/DevModePanel/DevModePanel.tsx
+++ b/src/components/DevModePanel/DevModePanel.tsx
@@ -1,26 +1,35 @@
// @ts-strict-ignore
import { useDashboardTheme } from "@dashboard/components/GraphiQL/styles";
-import { createGraphiQLFetcher } from "@graphiql/toolkit";
-import { Dialog, DialogContent } from "@material-ui/core";
-import { DialogHeader } from "@saleor/macaw-ui";
-import { createFetch } from "@saleor/sdk";
+import { DashboardModal } from "@dashboard/components/Modal";
+import { useOnboarding } from "@dashboard/welcomePage/WelcomePageOnboarding/onboardingContext";
+import { FetcherOpts, FetcherParams } from "@graphiql/toolkit";
import React from "react";
import { useIntl } from "react-intl";
+import { ContextualLine } from "../AppLayout/ContextualLinks/ContextualLine";
+import { useContextualLink } from "../AppLayout/ContextualLinks/useContextualLink";
import PlainGraphiQL from "../GraphiQLPlain";
import { useDevModeContext } from "./hooks";
import { messages } from "./messages";
-
-const authorizedFetch = createFetch();
+import { getFetcher } from "./utils";
export const DevModePanel: React.FC = () => {
const intl = useIntl();
+ const subtitle = useContextualLink("dev_panel");
const { rootStyle } = useDashboardTheme();
+ const { markOnboardingStepAsCompleted } = useOnboarding();
const { isDevModeVisible, variables, devModeContent, setDevModeVisibility } = useDevModeContext();
- const fetcher = createGraphiQLFetcher({
- url: process.env.API_URL,
- fetch: authorizedFetch,
- });
+ const fetcher = async (graphQLParams: FetcherParams, opts: FetcherOpts) => {
+ if (graphQLParams.operationName !== "IntrospectionQuery") {
+ markOnboardingStepAsCompleted("graphql-playground");
+ }
+
+ const baseFetcher = getFetcher(opts);
+
+ const result = await baseFetcher(graphQLParams, opts); // Call the base fetcher
+
+ return result;
+ };
const overwriteCodeMirrorCSSVariables = {
__html: `
.graphiql-container, .CodeMirror-info, .CodeMirror-lint-tooltip, reach-portal{
@@ -34,20 +43,17 @@ export const DevModePanel: React.FC = () => {
};
return (
-
-
- setDevModeVisibility(false)}>
- {intl.formatMessage(messages.title)}
-
-
+ setDevModeVisibility(false)}>
+
+
+
+ {intl.formatMessage(messages.title)}
+
+ {subtitle}
+
+
-
-
+
+
);
};
diff --git a/src/components/DevModePanel/utils.test.ts b/src/components/DevModePanel/utils.test.ts
new file mode 100644
index 00000000000..773aeb09191
--- /dev/null
+++ b/src/components/DevModePanel/utils.test.ts
@@ -0,0 +1,112 @@
+import { createGraphiQLFetcher, FetcherOpts } from "@graphiql/toolkit";
+import { createFetch } from "@saleor/sdk";
+
+import { getFetcher } from "./utils";
+
+jest.mock("@graphiql/toolkit", () => ({
+ createGraphiQLFetcher: jest.fn(),
+}));
+
+jest.mock("@saleor/sdk", () => ({
+ createFetch: jest.fn().mockReturnValue(jest.fn()),
+}));
+
+jest.mock("@dashboard/config", () => ({
+ ENABLED_SERVICE_NAME_HEADER: true,
+}));
+
+const mockCreateGraphiQLFetcher = createGraphiQLFetcher as jest.Mock;
+const authorizedFetch = createFetch as jest.Mock;
+
+describe("getFetcher", () => {
+ const mockApiUrl = "http://test-api.com";
+ let originalFetch: typeof fetch;
+
+ beforeEach(() => {
+ process.env.API_URL = mockApiUrl;
+ originalFetch = global.fetch;
+ });
+
+ afterEach(() => {
+ jest.resetAllMocks();
+ global.fetch = originalFetch;
+ });
+
+ it("should return fetcher with authorizedFetch when no auth headers", () => {
+ // Arrange
+ const opts: FetcherOpts = { headers: {} };
+
+ // Act
+ getFetcher(opts);
+
+ // Assert
+ expect(authorizedFetch).toHaveBeenCalled();
+ // 'toHaveBeenCalledWith' can't properly compare mock functions
+ expect(mockCreateGraphiQLFetcher).toHaveBeenCalledWith(
+ expect.objectContaining({
+ url: mockApiUrl,
+ }),
+ );
+ });
+
+ it("should return fetcher with fetch when Authorization header present", () => {
+ // Arrange
+ const opts: FetcherOpts = {
+ headers: { Authorization: "Bearer token" },
+ };
+
+ // Act
+ getFetcher(opts);
+
+ // Assert
+ expect(mockCreateGraphiQLFetcher).toHaveBeenCalledWith({
+ url: mockApiUrl,
+ fetch: fetch,
+ headers: {
+ "source-service-name": "saleor.dashboard.playground",
+ },
+ });
+ });
+
+ it("should return fetcher with fetch when Authorization-Bearer header present", () => {
+ // Arrange
+ const opts: FetcherOpts = {
+ headers: {
+ "Authorization-Bearer": "token",
+ },
+ };
+
+ // Act
+ getFetcher(opts);
+
+ // Assert
+ expect(mockCreateGraphiQLFetcher).toHaveBeenCalledWith({
+ url: mockApiUrl,
+ fetch: fetch,
+ headers: {
+ "source-service-name": "saleor.dashboard.playground",
+ },
+ });
+ });
+
+ it("should return fetcher with fetch when lowercase header present", () => {
+ // Arrange
+ const opts: FetcherOpts = {
+ headers: {
+ "authorization-bearer": "token",
+ },
+ };
+
+ // Act
+ getFetcher(opts);
+
+ // Assert
+ expect(mockCreateGraphiQLFetcher).toHaveBeenCalledWith({
+ url: mockApiUrl,
+ fetch: fetch,
+ headers: {
+ "source-service-name": "saleor.dashboard.playground",
+ },
+ });
+ });
+});
diff --git a/src/components/DevModePanel/utils.ts b/src/components/DevModePanel/utils.ts
new file mode 100644
index 00000000000..98557193155
--- /dev/null
+++ b/src/components/DevModePanel/utils.ts
@@ -0,0 +1,31 @@
+import { ENABLED_SERVICE_NAME_HEADER } from "@dashboard/config";
+import { createGraphiQLFetcher, FetcherOpts } from "@graphiql/toolkit";
+import { createFetch } from "@saleor/sdk";
+
+const authHeaders = ["Authorization", "Authorization-Bearer"];
+
+const authorizedFetch = createFetch();
+
+export const getFetcher = (opts: FetcherOpts) => {
+ let httpFetch = authorizedFetch;
+
+ const hasAuthorizationHeaders =
+ opts.headers &&
+ authHeaders.some(header => opts.headers![header] || opts.headers![header.toLowerCase()]);
+
+ if (hasAuthorizationHeaders) {
+ httpFetch = fetch;
+ }
+
+ const headers: Record = {};
+
+ if (ENABLED_SERVICE_NAME_HEADER) {
+ headers["source-service-name"] = "saleor.dashboard.playground";
+ }
+
+ return createGraphiQLFetcher({
+ url: process.env.API_URL as string,
+ fetch: httpFetch as typeof fetch,
+ headers,
+ });
+};
diff --git a/src/components/DiscountedPrice/DiscountedPrice.tsx b/src/components/DiscountedPrice/DiscountedPrice.tsx
index eace1c7e6be..a8acaf1fa51 100644
--- a/src/components/DiscountedPrice/DiscountedPrice.tsx
+++ b/src/components/DiscountedPrice/DiscountedPrice.tsx
@@ -1,5 +1,5 @@
import { IMoney } from "@dashboard/utils/intl";
-import { Typography } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import Money from "../Money";
@@ -15,9 +15,9 @@ const DiscountedPrice: React.FC = ({ regularPrice, discoun
return (
<>
-
+
-
+
>
);
diff --git a/src/components/DryRun/DryRun.tsx b/src/components/DryRun/DryRun.tsx
index d14b30c50b9..56346ff84e1 100644
--- a/src/components/DryRun/DryRun.tsx
+++ b/src/components/DryRun/DryRun.tsx
@@ -1,25 +1,19 @@
// @ts-strict-ignore
import Grid from "@dashboard/components/Grid";
+import { DashboardModal } from "@dashboard/components/Modal";
import { useStyles } from "@dashboard/custom-apps/components/WebhookEvents/styles";
import { useTriggerWebhookDryRunMutation, WebhookEventTypeSyncEnum } from "@dashboard/graphql";
-import {
- capitalize,
- Dialog,
- DialogActions,
- DialogContent,
- DialogContentText,
- Typography,
-} from "@material-ui/core";
+import { capitalize } from "@material-ui/core";
import {
Alert,
Button,
- DialogHeader,
List,
ListBody,
ListHeader,
ListItem,
ListItemCell,
} from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import React, { Dispatch, SetStateAction, useState } from "react";
import { useIntl } from "react-intl";
@@ -73,30 +67,32 @@ const DryRun: React.FC = ({
if (syncEvents.length > 0) {
return (
-
- {intl.formatMessage(messages.header)}
-
+
+
+ {intl.formatMessage(messages.header)}
+
- {intl.formatMessage(messages.unavailableSyncEvents)}
+ {intl.formatMessage(messages.unavailableSyncEvents)}
-
-
+
+
);
}
return (
-
- {intl.formatMessage(messages.header)}
-
- {intl.formatMessage(messages.selectObject)}
+
+
+ {intl.formatMessage(messages.header)}
+
+ {intl.formatMessage(messages.selectObject)}
{!!unavailableObjects.length && (
-
+
{intl.formatMessage(messages.unavailableEvents)}
{unavailableObjects.join(", ")}
-
+
)}
@@ -112,9 +108,7 @@ const DryRun: React.FC = ({
- {!availableObjects.length && (
- {intl.formatMessage(messages.noObjects)}
- )}
+ {!availableObjects.length && {intl.formatMessage(messages.noObjects)} }
{availableObjects.map((object, idx) => (
= ({
- {intl.formatMessage(messages.itemsDefaultMessage)}
+ {intl.formatMessage(messages.itemsDefaultMessage)}
>
)}
-
-
-
- {intl.formatMessage(messages.run)}
-
-
-
+
+
+
+ {intl.formatMessage(messages.run)}
+
+
+
+
);
};
diff --git a/src/components/DryRun/utils.ts b/src/components/DryRun/utils.ts
index 437fd818955..4532fed6309 100644
--- a/src/components/DryRun/utils.ts
+++ b/src/components/DryRun/utils.ts
@@ -3,7 +3,7 @@ import { getWebhookTypes } from "@dashboard/custom-apps/components/WebhookEvents
import { WebhookEventTypeAsyncEnum } from "@dashboard/graphql";
import { InlineFragmentNode, ObjectFieldNode, parse, visit } from "graphql";
-import { DocumentMap, ExcludedDocumentMap } from "../DryRunItemsList/utils";
+import { DocumentMap, ExcludedDocumentKeys } from "../DryRunItemsList/utils";
const getEventsFromQuery = (query: string) => {
if (query.length === 0) {
@@ -56,7 +56,7 @@ const checkEventPresence = (event: string) => {
object => !availableObjects.includes(object),
);
- Object.keys(ExcludedDocumentMap).forEach(
+ ExcludedDocumentKeys.forEach(
object => !excludedObjects.includes(object) && excludedObjects.push(object),
);
diff --git a/src/components/DryRunItemsList/DryRunItemsList.tsx b/src/components/DryRunItemsList/DryRunItemsList.tsx
index 8d915f19141..0cd0f3850e9 100644
--- a/src/components/DryRunItemsList/DryRunItemsList.tsx
+++ b/src/components/DryRunItemsList/DryRunItemsList.tsx
@@ -1,5 +1,5 @@
// @ts-strict-ignore
-import Skeleton from "@dashboard/components/Skeleton";
+
import { useStyles } from "@dashboard/custom-apps/components/WebhookEvents/styles";
import { useQuery } from "@dashboard/hooks/graphql";
import { mapEdgesToItems } from "@dashboard/utils/maps";
@@ -12,6 +12,7 @@ import {
ListItemCell,
useListWidths,
} from "@saleor/macaw-ui";
+import { Skeleton } from "@saleor/macaw-ui-next";
import camelCase from "lodash/camelCase";
import React from "react";
import { useIntl } from "react-intl";
@@ -71,7 +72,7 @@ const DryRunItemsList: React.FC = ({
) : (
- (mapEdgesToItems(data[objectCollection]) || []).map((item, idx) => (
+ (mapEdgesToItems(data?.[objectCollection]) || []).map((item, idx) => (
setObjectId(item.id)}>
{item.name || item[objectDocument.displayedAttribute] || item.id || item.__typename}
diff --git a/src/components/DryRunItemsList/utils.ts b/src/components/DryRunItemsList/utils.ts
index f279c6b68e4..8889c594bbd 100644
--- a/src/components/DryRunItemsList/utils.ts
+++ b/src/components/DryRunItemsList/utils.ts
@@ -8,14 +8,12 @@ import {
AttributeListQueryVariables,
CategoryDetailsQuery,
CategoryDetailsQueryVariables,
- ChannelListDocument,
CheckoutListDocument,
CheckoutListQuery,
CheckoutListQueryVariables,
CollectionListDocument,
CollectionListQuery,
CollectionListQueryVariables,
- CustomerAddressesDocument,
CustomerAddressesQuery,
CustomerAddressesQueryVariables,
CustomerDetailsQuery,
@@ -29,7 +27,6 @@ import {
MenuListDocument,
MenuListQuery,
MenuListQueryVariables,
- OrderFulfillDataDocument,
OrderFulfillDataQuery,
OrderFulfillDataQueryVariables,
OrderListDocument,
@@ -41,7 +38,6 @@ import {
ProductListDocument,
ProductListQuery,
ProductListQueryVariables,
- ProductVariantListDocument,
ProductVariantListQuery,
ProductVariantListQueryVariables,
RootCategoriesDocument,
@@ -162,13 +158,6 @@ export const DocumentMap: Record = {
displayedAttribute: "email",
// TODO inverted name
},
-
- INVOICE: {
- document: OrderListDocument,
- variables: DefaultVariables,
- collection: "orders",
- displayedAttribute: "number",
- },
MENU: {
document: MenuListDocument,
variables: DefaultVariables,
@@ -189,6 +178,8 @@ export const DocumentMap: Record = {
variables: {
first: 100,
hasChannel: true,
+ includeCategories: false,
+ includeCollections: false,
},
displayedAttribute: "name",
},
@@ -228,35 +219,29 @@ export const DocumentMap: Record = {
// Documents which require parent object or can't be handled ATM
//
-export const ExcludedDocumentMap: Record = {
- ADDRESS: {
- document: CustomerAddressesDocument,
- variables: {
- // USER ID REQUIRED
- first: 100,
- },
- },
+export const ExcludedDocumentKeys = [
+ // USER ID REQUIRED
+ "ADDRESS",
// it's not a countable collection
- CHANNEL: {
- document: ChannelListDocument,
- variables: {},
- },
- FULFILLMENT: {
- document: OrderFulfillDataDocument,
- variables: {
- // ORDER ID REQUIRED
- first: 100,
- },
- },
- PRODUCT_VARIANT: {
- document: ProductVariantListDocument,
- variables: {
- // PRODUCT ID REQUIRED
- first: 100,
- },
- },
- TRANSLATION: {
- document: null,
- variables: {},
- },
-};
+ "CHANNEL",
+ // ORDER ID REQUIRED
+ "FULFILLMENT",
+ // PRODUCT ID REQUIRED
+ "PRODUCT_VARIANT",
+ "PRODUCT_EXPORT_COMPLETED",
+ "PRODUCT_MEDIA_CREATED",
+ "PRODUCT_MEDIA_DELETED",
+ "PRODUCT_MEDIA_UPDATED",
+ "PRODUCT_VARIANT_BACK_IN_STOCK",
+ "PRODUCT_VARIANT_CREATED",
+ "PRODUCT_VARIANT_DELETED",
+ "PRODUCT_VARIANT_METADATA_UPDATED",
+ "PRODUCT_VARIANT_OUT_OF_STOCK",
+ "PRODUCT_VARIANT_STOCK_UPDATED",
+ "PRODUCT_VARIANT_UPDATED",
+ "VOUCHER_CODES_CREATED",
+ "VOUCHER_CODES_DELETED",
+ "VOUCHER_CODE_EXPORT_COMPLETED",
+ "ORDER_BULK_CREATED",
+ "TRANSLATION",
+];
diff --git a/src/components/EditableTableCell/EditableTableCell.tsx b/src/components/EditableTableCell/EditableTableCell.tsx
index be9f4690c84..bde74b242e2 100644
--- a/src/components/EditableTableCell/EditableTableCell.tsx
+++ b/src/components/EditableTableCell/EditableTableCell.tsx
@@ -1,15 +1,15 @@
import useForm from "@dashboard/hooks/useForm";
-import { Card, CardContent, TableCell, TextField, Typography } from "@material-ui/core";
+import { TableCell, TextField } from "@material-ui/core";
import { TextFieldProps } from "@material-ui/core/TextField";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
+import { DashboardCard } from "../Card";
+
const useStyles = makeStyles(
theme => ({
- card: {
- border: `1px solid ${theme.palette.divider}`,
- },
container: {
position: "relative",
},
@@ -71,13 +71,13 @@ export const EditableTableCell: React.FC = props => {
return (
{opened &&
}
-
+
{value || defaultValue}
-
+
{opened && (
-
-
+
+
= props => {
variant="standard"
{...InputProps}
/>
-
-
+
+
)}
diff --git a/src/components/ErrorMessageCard/ErrorMessageCard.tsx b/src/components/ErrorMessageCard/ErrorMessageCard.tsx
index b709bd935e3..3cc01ef4c32 100644
--- a/src/components/ErrorMessageCard/ErrorMessageCard.tsx
+++ b/src/components/ErrorMessageCard/ErrorMessageCard.tsx
@@ -1,20 +1,24 @@
-import { Card, CardContent, Typography } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage } from "react-intl";
+import { DashboardCard } from "../Card";
+
interface ErrorMessageCardProps {
message: string;
}
const ErrorMessageCard: React.FC = ({ message }) => (
-
-
-
+
+
+
-
- {message}
-
-
+
+
+ {message}
+
+
+
);
ErrorMessageCard.displayName = "ErrorMessageCard";
diff --git a/src/components/ErrorPage/ErrorPage.tsx b/src/components/ErrorPage/ErrorPage.tsx
index ff09347debe..f6210a9b88a 100644
--- a/src/components/ErrorPage/ErrorPage.tsx
+++ b/src/components/ErrorPage/ErrorPage.tsx
@@ -2,14 +2,12 @@
import notFoundImage from "@assets/images/what.svg";
import useAppState from "@dashboard/hooks/useAppState";
import useNavigator from "@dashboard/hooks/useNavigator";
-import { Typography } from "@material-ui/core";
-import { Button } from "@saleor/macaw-ui";
+import { Box, Button, sprinkles, Text } from "@saleor/macaw-ui-next";
import React from "react";
import SVG from "react-inlinesvg";
import { FormattedMessage } from "react-intl";
import messages from "./messages";
-import useStyles from "./styles";
export interface ErrorPageProps {
onBack: () => void;
@@ -17,7 +15,6 @@ export interface ErrorPageProps {
}
const ErrorPage: React.FC = ({ onBack, onRefresh }) => {
- const classes = useStyles();
const navigate = useNavigator();
const [appState, dispatchAppState] = useAppState();
const handleOnBack = () => {
@@ -33,40 +30,67 @@ const ErrorPage: React.FC = ({ onBack, onRefresh }) => {
const errorTrackingId = appState.error?.type === "unhandled" ? appState.error.id : null;
return (
-
-
-
-
+
+
+
+
-
+
-
-
+
+
-
+
{!!errorTrackingId && (
-
-
+
+
Error ID
-
- {errorTrackingId}
-
+
+
+ {errorTrackingId}
+
+
)}
-
-
-
-
+
+
+
+
);
};
diff --git a/src/components/ErrorPage/styles.ts b/src/components/ErrorPage/styles.ts
deleted file mode 100644
index 302910f43bf..00000000000
--- a/src/components/ErrorPage/styles.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { makeStyles } from "@saleor/macaw-ui";
-
-const useStyles = makeStyles(
- theme => ({
- buttonContainer: {
- marginTop: theme.spacing(2),
- },
- container: {
- [theme.breakpoints.down("sm")]: {
- gridTemplateColumns: "1fr",
- padding: theme.spacing(3),
- width: "100%",
- },
- display: "grid",
- gridTemplateColumns: "1fr 487px",
- margin: "0 auto",
- gap: theme.spacing(5),
- width: `calc(480px * 2 + ${theme.spacing(5)})`,
- },
- conjunction: {
- display: "inline-block",
- margin: theme.spacing(0, 1),
- },
- errorId: {
- marginTop: theme.spacing(3),
- letterSpacing: "0.1rem",
- textTransform: "uppercase",
- fontWeight: 500,
- },
- innerContainer: {
- [theme.breakpoints.down("sm")]: {
- order: 1,
- textAlign: "center",
- },
- display: "flex",
- flexDirection: "column",
- justifyContent: "center",
- },
- notFoundImage: {
- width: "100%",
- },
- root: {
- alignItems: "center",
- display: "flex",
- height: "100vh",
- },
- header: {
- marginBottom: theme.spacing(2),
- },
- }),
- { name: "ErrorPage" },
-);
-
-export default useStyles;
diff --git a/src/components/ExternalLink/ExternalLink.tsx b/src/components/ExternalLink/ExternalLink.tsx
index b343a29ea79..b25ec5ea3e4 100644
--- a/src/components/ExternalLink/ExternalLink.tsx
+++ b/src/components/ExternalLink/ExternalLink.tsx
@@ -1,5 +1,3 @@
-import { Typography } from "@material-ui/core";
-import { TypographyProps } from "@material-ui/core/Typography";
import { makeStyles } from "@saleor/macaw-ui";
import { Text, TextProps } from "@saleor/macaw-ui-next";
import React, { HTMLAttributes } from "react";
@@ -16,14 +14,13 @@ const useStyles = makeStyles(
interface ExternalLinkProps extends React.HTMLProps {
href: string;
className?: string;
- typographyProps?: TypographyProps;
}
/**
* @deprecated use ExternalLinkNext
*/
const ExternalLink: React.FC = props => {
- const { className, children, href, typographyProps, target, rel, ...rest } = props;
+ const { className, children, href, target, rel, ...rest } = props;
const classes = useStyles(props);
const opensNewTab = target === "_blank";
@@ -35,9 +32,9 @@ const ExternalLink: React.FC = props => {
rel={rel ?? opensNewTab ? "noopener noreferer" : ""}
{...rest}
>
-
+
{children}
-
+
);
};
diff --git a/src/components/FileUploadField/FileUploadField.tsx b/src/components/FileUploadField/FileUploadField.tsx
index 35ba65070cd..f80f76ed01d 100644
--- a/src/components/FileUploadField/FileUploadField.tsx
+++ b/src/components/FileUploadField/FileUploadField.tsx
@@ -1,12 +1,10 @@
// @ts-strict-ignore
import { FileFragment } from "@dashboard/graphql";
import { commonMessages } from "@dashboard/intl";
-import { Box, Button, Text, TrashBinIcon } from "@saleor/macaw-ui-next";
+import { Box, Button, Skeleton, Text, TrashBinIcon } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
-import Skeleton from "../Skeleton";
-
export interface FileChoiceType {
label: string;
value: string;
diff --git a/src/components/Filter/Filter.tsx b/src/components/Filter/Filter.tsx
index 7ae0e12f29e..913f0c9d3a9 100644
--- a/src/components/Filter/Filter.tsx
+++ b/src/components/Filter/Filter.tsx
@@ -1,8 +1,8 @@
// @ts-strict-ignore
-import { ClickAwayListener, Grow, Popper, Typography } from "@material-ui/core";
+import { ClickAwayListener, Grow, Popper } from "@material-ui/core";
import { alpha } from "@material-ui/core/styles";
import { Button, makeStyles } from "@saleor/macaw-ui";
-import { vars } from "@saleor/macaw-ui-next";
+import { Text, vars } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React, { useMemo, useState } from "react";
import { FormattedMessage } from "react-intl";
@@ -127,9 +127,9 @@ const Filter: React.FC = props => {
data-test-id="show-filters-button"
variant="secondary"
>
-
+
-
+
{isFilterActive && selectedFilterAmount > 0 && <>({selectedFilterAmount})>}
;
+export type FilterAutocompleteDisplayValues = Record;
const useStyles = makeStyles(
theme => ({
@@ -62,14 +62,14 @@ const FilterAutocompleteField: React.FC = ({
fieldDisplayValues.every(displayValue => displayValue.value !== option.value),
);
const displayNoResults = availableOptions.length === 0 && fieldDisplayValues.length === 0;
- const getUpdatedFilterValue = (option: MultiAutocompleteChoiceType) => {
+ const getUpdatedFilterValue = (option: Option) => {
if (filter.multiple) {
return toggle(option.value, filter.value, (a, b) => a === b);
}
return [option.value];
};
- const handleChange = (option: MultiAutocompleteChoiceType) => {
+ const handleChange = (option: Option) => {
onFilterPropertyChange({
payload: {
name: filter.name,
@@ -88,8 +88,7 @@ const FilterAutocompleteField: React.FC = ({
});
}
};
- const isValueChecked = (displayValue: MultiAutocompleteChoiceType) =>
- filter.value.includes(displayValue.value);
+ const isValueChecked = (displayValue: Option) => filter.value.includes(displayValue.value);
const filteredValuesChecked = initialFieldDisplayValues.filter(isValueChecked);
const filteredValuesUnchecked = fieldDisplayValues.filter(
displayValue => !isValueChecked(displayValue),
@@ -129,13 +128,13 @@ const FilterAutocompleteField: React.FC = ({
))}
{displayHr && }
{displayNoResults && (
-
-
+
)}
{filteredValuesUnchecked.map(option => (
diff --git a/src/components/Filter/FilterContent/FilterContent.tsx b/src/components/Filter/FilterContent/FilterContent.tsx
index 0e4762e4b78..deec7a6a744 100644
--- a/src/components/Filter/FilterContent/FilterContent.tsx
+++ b/src/components/Filter/FilterContent/FilterContent.tsx
@@ -1,8 +1,9 @@
// @ts-strict-ignore
import CollectionWithDividers from "@dashboard/components/CollectionWithDividers";
import useStateFromProps from "@dashboard/hooks/useStateFromProps";
-import { makeStyles, Paper, Typography } from "@material-ui/core";
+import { makeStyles, Paper } from "@material-ui/core";
import { Accordion, AccordionSummary } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import { FilterAutocompleteDisplayValues } from "../FilterAutocompleteField";
@@ -219,7 +220,7 @@ const FilterContent: React.FC
= ({
active: currentFilter?.active,
}}
>
- {filterField.label}
+ {filterField.label}
)}
/>
diff --git a/src/components/Filter/FilterContent/FilterContentBody.tsx b/src/components/Filter/FilterContent/FilterContentBody.tsx
index 78eb4fc215f..630d5a2c44b 100644
--- a/src/components/Filter/FilterContent/FilterContentBody.tsx
+++ b/src/components/Filter/FilterContent/FilterContentBody.tsx
@@ -3,10 +3,9 @@ import { FilterDateTimeField } from "@dashboard/components/Filter/FilterContent/
import { FilterNumericField } from "@dashboard/components/Filter/FilterContent/FilterNumericField";
import { FilterSingleSelectField } from "@dashboard/components/Filter/FilterContent/FilterSingleSelectField";
import { useCommonStyles } from "@dashboard/components/Filter/FilterContent/utils";
-import { MultiAutocompleteChoiceType } from "@dashboard/components/MultiAutocompleteSelectField";
-import Skeleton from "@dashboard/components/Skeleton";
import { FormControlLabel, Radio, TextField } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
+import { Option, Skeleton } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
@@ -49,9 +48,7 @@ export interface FilterContentBodyProps {
initialAutocompleteDisplayValues: FilterAutocompleteDisplayValues;
onFilterPropertyChange: (value: FilterReducerAction) => void;
autocompleteDisplayValues: FilterAutocompleteDisplayValues;
- setAutocompleteDisplayValues: React.Dispatch<
- React.SetStateAction>
- >;
+ setAutocompleteDisplayValues: React.Dispatch>>;
}
const FilterContentBody = ({
diff --git a/src/components/Filter/FilterContent/FilterContentHeader.tsx b/src/components/Filter/FilterContent/FilterContentHeader.tsx
index 2e06bb1c99c..a01fa469809 100644
--- a/src/components/Filter/FilterContent/FilterContentHeader.tsx
+++ b/src/components/Filter/FilterContent/FilterContentHeader.tsx
@@ -1,8 +1,7 @@
import { Button } from "@dashboard/components/Button";
import { buttonMessages } from "@dashboard/intl";
-import { Typography } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
-import { vars } from "@saleor/macaw-ui-next";
+import { Text, vars } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage } from "react-intl";
@@ -38,9 +37,9 @@ const FilterContentHeader: React.FC = ({ onClear }) =>
return (
-
+
-
+
= ({
{errors.map(code => (
-
{getErrorMessage(code)}
+
{getErrorMessage(code)}
))}
diff --git a/src/components/Filter/FilterContent/FilterSingleSelectField.tsx b/src/components/Filter/FilterContent/FilterSingleSelectField.tsx
index 601bb40fafb..902fee88e91 100644
--- a/src/components/Filter/FilterContent/FilterSingleSelectField.tsx
+++ b/src/components/Filter/FilterContent/FilterSingleSelectField.tsx
@@ -1,42 +1,32 @@
// @ts-strict-ignore
import { FilterFieldBaseProps, FilterType } from "@dashboard/components/Filter";
-import {
- getIsFilterMultipleChoices,
- useCommonStyles,
-} from "@dashboard/components/Filter/FilterContent/utils";
+import { getIsFilterMultipleChoices } from "@dashboard/components/Filter/FilterContent/utils";
import FormSpacer from "@dashboard/components/FormSpacer";
+import { Select } from "@dashboard/components/Select";
import React from "react";
import { useIntl } from "react-intl";
-import SingleSelectField from "../../SingleSelectField/SingleSelectField";
-
type FilterSingleSelectFieldProps = FilterFieldBaseProps;
export const FilterSingleSelectField: React.FC = ({
filter,
onFilterPropertyChange,
}) => {
- const classes = useCommonStyles({});
const intl = useIntl();
return (
<>
-
+ onChange={({ target }) =>
onFilterPropertyChange({
payload: {
name: filter.name,
update: {
- multiple: event.target.value === FilterType.MULTIPLE,
- ...(event.target.value !== FilterType.MULTIPLE && {
+ multiple: target.value === FilterType.MULTIPLE,
+ ...(target.value !== FilterType.MULTIPLE && {
value: filter.value.slice(0, 1) as string[],
}),
},
diff --git a/src/components/Filter/FilterContent/utils.ts b/src/components/Filter/FilterContent/utils.ts
index f65205c42db..c1267d0f546 100644
--- a/src/components/Filter/FilterContent/utils.ts
+++ b/src/components/Filter/FilterContent/utils.ts
@@ -1,7 +1,7 @@
// @ts-strict-ignore
-import { SingleAutocompleteChoiceType } from "@dashboard/components/SingleAutocompleteSelectField";
import { joinDateTime, splitDateTime } from "@dashboard/misc";
import { makeStyles } from "@saleor/macaw-ui";
+import { Option } from "@saleor/macaw-ui-next";
import { IntlShape } from "react-intl";
import { FilterType } from "../types";
@@ -34,7 +34,7 @@ export const useCommonStyles = makeStyles(
{ name: "FilterContentBodyCommon" },
);
-export function getIsFilterMultipleChoices(intl: IntlShape): SingleAutocompleteChoiceType[] {
+export function getIsFilterMultipleChoices(intl: IntlShape): Option[] {
return [
{
label: intl.formatMessage({
diff --git a/src/components/Filter/types.ts b/src/components/Filter/types.ts
index 910e948b0fc..e5995bbebab 100644
--- a/src/components/Filter/types.ts
+++ b/src/components/Filter/types.ts
@@ -1,8 +1,8 @@
import { PermissionEnum } from "@dashboard/graphql";
import { FetchMoreProps, KeyValue, SearchPageProps } from "@dashboard/types";
+import { Option } from "@saleor/macaw-ui-next";
import { MessageDescriptor } from "react-intl";
-import { MultiAutocompleteChoiceType } from "../MultiAutocompleteSelectField";
import { FilterDispatchFunction } from "./useFilter";
export enum FieldType {
@@ -20,7 +20,7 @@ export enum FieldType {
interface FilterElementCommonData {
active: boolean;
multiple: boolean;
- options?: MultiAutocompleteChoiceType[];
+ options?: Option[];
}
export interface KeyValueFilterElementData {
@@ -48,7 +48,7 @@ export type IFilterElementMutableDataGeneric = T extends Fi
type FilterElementCommon = {
autocomplete?: boolean;
- displayValues?: MultiAutocompleteChoiceType[];
+ displayValues?: Option[];
group?: K;
label: string;
name: K;
diff --git a/src/components/FilterCard/FilterCard.tsx b/src/components/FilterCard/FilterCard.tsx
index 86bf4289b0a..e57a80fe176 100644
--- a/src/components/FilterCard/FilterCard.tsx
+++ b/src/components/FilterCard/FilterCard.tsx
@@ -1,10 +1,12 @@
// @ts-strict-ignore
-import { Card, CardContent, CardHeader } from "@material-ui/core";
+import { CardHeader } from "@material-ui/core";
import RefreshIcon from "@material-ui/icons/Refresh";
import { IconButton } from "@saleor/macaw-ui";
import React from "react";
import { useIntl } from "react-intl";
+import { DashboardCard } from "../Card";
+
export interface FilterCardProps {
handleClear: () => any;
}
@@ -13,7 +15,7 @@ const FilterCard: React.FC = ({ children, handleClear }) => {
const intl = useIntl();
return (
-
+
= ({ children, handleClear }) => {
defaultMessage: "Filters",
})}
/>
- {children}
+ {children}
-
+
);
};
diff --git a/src/components/Form/ExitFormDialog.test.tsx b/src/components/Form/ExitFormDialog.test.tsx
index 8a2b8a80a25..0cf12f1846f 100644
--- a/src/components/Form/ExitFormDialog.test.tsx
+++ b/src/components/Form/ExitFormDialog.test.tsx
@@ -43,7 +43,7 @@ describe("ExitFormDialog", () => {
// Act
const { getByTestId } = render( );
- await user.click(getByTestId("keep-editing"));
+ await user.click(getByTestId("back"));
// Assert
expect(props.onClose).toHaveBeenCalled();
});
diff --git a/src/components/Form/ExitFormDialog.tsx b/src/components/Form/ExitFormDialog.tsx
index b9589edc42f..f31590aad3c 100644
--- a/src/components/Form/ExitFormDialog.tsx
+++ b/src/components/Form/ExitFormDialog.tsx
@@ -1,34 +1,11 @@
-import HorizontalSpacer from "@dashboard/components/HorizontalSpacer";
-import { Button, Dialog, DialogContent, makeStyles } from "@material-ui/core";
-import { DialogHeader } from "@saleor/macaw-ui";
+import BackButton from "@dashboard/components/BackButton";
+import { DashboardModal } from "@dashboard/components/Modal";
+import { Button } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
import { exitFormPromptMessages as messages } from "./messages";
-const useStyles = makeStyles(
- () => ({
- container: {
- width: "100vw",
- height: "100vh",
- display: "flex",
- justifyContent: "center",
- alignItems: "center",
- },
- buttonsContainer: {
- display: "flex",
- justifyContent: "flex-end",
- },
- dialogContent: {
- "@media (min-width: 800px)": {
- minWidth: 500,
- },
- paddingTop: 0,
- },
- }),
- { name: "ExitFormPrompt" },
-);
-
interface ExitFormDialogProps {
onClose: () => void;
onLeave: () => void;
@@ -36,31 +13,23 @@ interface ExitFormDialogProps {
}
const ExitFormDialog: React.FC = ({ onLeave, onClose, isOpen }) => {
- const classes = useStyles();
const intl = useIntl();
return (
-
-
- {intl.formatMessage(messages.unableToSaveTitle)}
-
-
-
-
- {intl.formatMessage(messages.keepEditing)}
-
-
-
+
+
+
+ {intl.formatMessage(messages.unableToSaveTitle)}
+
+
+
+ {intl.formatMessage(messages.keepEditing)}
+
{intl.formatMessage(messages.ignoreChanges)}
-
-
-
+
+
+
);
};
diff --git a/src/components/ImageUpload/ImageUpload.tsx b/src/components/ImageUpload/ImageUpload.tsx
index 5e2528d5d35..6a203e6f6c4 100644
--- a/src/components/ImageUpload/ImageUpload.tsx
+++ b/src/components/ImageUpload/ImageUpload.tsx
@@ -1,8 +1,7 @@
// @ts-strict-ignore
-import { Typography } from "@material-ui/core";
import { alpha } from "@material-ui/core/styles";
import { ImageIcon, makeStyles } from "@saleor/macaw-ui";
-import { vars } from "@saleor/macaw-ui-next";
+import { Text, vars } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
import { FormattedMessage } from "react-intl";
@@ -50,12 +49,6 @@ const useStyles = makeStyles(
padding: theme.spacing(5, 0),
textAlign: "center",
},
- uploadText: {
- color: theme.typography.body1.color,
- fontSize: 12,
- fontWeight: 600,
- textTransform: "uppercase",
- },
}),
{ name: "ImageUpload" },
);
@@ -92,13 +85,13 @@ export const ImageUpload: React.FC = props => {
>
-
+
-
+
)}
diff --git a/src/components/InfiniteScroll/InfiniteScroll.tsx b/src/components/InfiniteScroll/InfiniteScroll.tsx
new file mode 100644
index 00000000000..3f207d11087
--- /dev/null
+++ b/src/components/InfiniteScroll/InfiniteScroll.tsx
@@ -0,0 +1,34 @@
+import { Box, Spinner } from "@saleor/macaw-ui-next";
+import React from "react";
+import InfiniteScrollComponent, { Props } from "react-infinite-scroll-component";
+
+interface InfiniteScrollProps extends Omit {
+ id: string;
+ loader?: React.ReactNode;
+ children: React.ReactNode;
+}
+
+const InfiniteScrollLoader = () => (
+
+
+
+);
+
+export const InfiniteScroll = ({ children, id, loader, ...props }: InfiniteScrollProps) => {
+ const loaderComponent = loader ?? ;
+
+ return (
+
+
+ {children}
+
+
+ );
+};
diff --git a/src/components/InfiniteScroll/index.ts b/src/components/InfiniteScroll/index.ts
new file mode 100644
index 00000000000..9a6d746fa8d
--- /dev/null
+++ b/src/components/InfiniteScroll/index.ts
@@ -0,0 +1 @@
+export * from "./InfiniteScroll";
diff --git a/src/components/LanguageSwitch/LanguageSwitch.tsx b/src/components/LanguageSwitch/LanguageSwitch.tsx
index 5d4707a356c..1ec0045eab2 100644
--- a/src/components/LanguageSwitch/LanguageSwitch.tsx
+++ b/src/components/LanguageSwitch/LanguageSwitch.tsx
@@ -1,22 +1,23 @@
// @ts-strict-ignore
import { LanguageCodeEnum, LanguageFragment } from "@dashboard/graphql";
import {
- Card,
ClickAwayListener,
Grow,
MenuItem,
MenuList as Menu,
Paper,
Popper,
- Typography,
} from "@material-ui/core";
import ArrowDropDown from "@material-ui/icons/ArrowDropDown";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom";
+import { DashboardCard } from "../Card";
+
export interface LanguageSwitchProps {
currentLanguage: LanguageCodeEnum;
languages: LanguageFragment[];
@@ -64,14 +65,17 @@ const LanguageSwitch: React.FC = props => {
return (
-
setExpandedState(!isExpanded)}>
- {currentLanguage}
+ setExpandedState(!isExpanded)}
+ >
+ {currentLanguage}
-
+
= ({ children }) => (
+export const RightSidebar: React.FC = ({
+ children,
+ ...props
+}) => (
= ({ chil
gridColumn={"8"}
gridRow={{ mobile: "6", tablet: "full", desktop: "full" }}
paddingBottom={6}
+ {...props}
>
{children}
diff --git a/src/components/Layouts/Detail/Root.tsx b/src/components/Layouts/Detail/Root.tsx
index 7588b12bbae..58a04ab2617 100644
--- a/src/components/Layouts/Detail/Root.tsx
+++ b/src/components/Layouts/Detail/Root.tsx
@@ -20,12 +20,14 @@ export const RootLayout: React.FC = ({
if (gridTemplateColumns instanceof Object) {
return {
mobile: gridTemplateColumns.mobile ?? 1,
+ tablet: gridTemplateColumns.tablet,
...gridTemplateColumns,
};
}
return {
mobile: 1,
+ tablet: gridTemplateColumns,
desktop: gridTemplateColumns,
};
}, [gridTemplateColumns]);
diff --git a/src/components/Link.tsx b/src/components/Link.tsx
index 3cf727e8d25..5ed8d4dfaed 100644
--- a/src/components/Link.tsx
+++ b/src/components/Link.tsx
@@ -1,8 +1,8 @@
// @ts-strict-ignore
import { isExternalURL } from "@dashboard/utils/urls";
-import { Typography } from "@material-ui/core";
import { TypographyProps } from "@material-ui/core/Typography";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
import { Link as RouterLink } from "react-router-dom";
@@ -109,9 +109,9 @@ const Link: React.FC = props => {
{children}
) : (
-
+
{children}
-
+
)}
>
);
diff --git a/src/components/LinkChoice/LinkChoice.tsx b/src/components/LinkChoice/LinkChoice.tsx
index 4c9c2a803cc..6945d97bdb2 100644
--- a/src/components/LinkChoice/LinkChoice.tsx
+++ b/src/components/LinkChoice/LinkChoice.tsx
@@ -2,17 +2,17 @@
import { FormChange } from "@dashboard/hooks/useForm";
import ArrowDropdown from "@dashboard/icons/ArrowDropdown";
import { ClickAwayListener, MenuItem, Paper, Popper } from "@material-ui/core";
+import { Option } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import { codes } from "keycode";
import React from "react";
import Link from "../Link";
-import { SingleAutocompleteChoiceType } from "../SingleAutocompleteSelectField";
import { useStyles } from "./styles";
export interface LinkChoiceProps {
className?: string;
- choices: SingleAutocompleteChoiceType[];
+ choices: Option[];
name?: string;
value: string;
onChange: FormChange;
diff --git a/src/components/Metadata/Metadata.tsx b/src/components/Metadata/Metadata.tsx
index da11d9b2269..677f3509848 100644
--- a/src/components/Metadata/Metadata.tsx
+++ b/src/components/Metadata/Metadata.tsx
@@ -6,13 +6,19 @@ import { Box } from "@saleor/macaw-ui-next";
import React, { memo } from "react";
import { MetadataCard, MetadataCardProps } from "./MetadataCard";
+import { MetadataLoadingCard } from "./MetadataLoadingCard";
import { EventDataAction, EventDataField } from "./types";
import { getDataKey, parseEventData } from "./utils";
export interface MetadataProps extends Omit {
- data: Record<"metadata" | "privateMetadata", MetadataInput[]>;
+ data: {
+ metadata: MetadataInput[];
+ privateMetadata: MetadataInput[] | undefined;
+ };
isLoading?: boolean;
readonly?: boolean;
+ // This props is used to hide the private metadata section when user doesn't have enough permissions.
+ hidePrivateMetadata?: boolean;
}
const propsCompare = (_, newProps: MetadataProps) => {
@@ -29,55 +35,71 @@ const propsCompare = (_, newProps: MetadataProps) => {
return false;
};
-export const Metadata: React.FC = memo(({ data, onChange, readonly = false }) => {
- const change = (event: ChangeEvent, isPrivate: boolean) => {
- const { action, field, fieldIndex, value } = parseEventData(event);
- const key = getDataKey(isPrivate);
- const dataToUpdate = data[key];
+// TODO: Refactor loading state logic
+// TODO: Split "Metadata" component into "Metadata" and "PrivateMetadata" components
+export const Metadata: React.FC = memo(
+ ({ data, onChange, isLoading, readonly = false, hidePrivateMetadata = false }) => {
+ const change = (event: ChangeEvent, isPrivate: boolean) => {
+ const { action, field, fieldIndex, value } = parseEventData(event);
+ const key = getDataKey(isPrivate);
+ const dataToUpdate = data[key];
- onChange({
- target: {
- name: key,
- value:
- action === EventDataAction.update
- ? updateAtIndex(
- {
- ...dataToUpdate[fieldIndex],
- key: field === EventDataField.name ? value : dataToUpdate[fieldIndex].key,
- value: field === EventDataField.value ? value : dataToUpdate[fieldIndex].value,
- },
- dataToUpdate,
- fieldIndex,
- )
- : action === EventDataAction.add
- ? [
- ...dataToUpdate,
+ onChange({
+ target: {
+ name: key,
+ value:
+ action === EventDataAction.update
+ ? updateAtIndex(
{
- key: "",
- value: "",
+ ...dataToUpdate[fieldIndex],
+ key: field === EventDataField.name ? value : dataToUpdate[fieldIndex].key,
+ value: field === EventDataField.value ? value : dataToUpdate[fieldIndex].value,
},
- ]
- : removeAtIndex(dataToUpdate, fieldIndex),
- },
- });
- };
+ dataToUpdate,
+ fieldIndex,
+ )
+ : action === EventDataAction.add
+ ? [
+ ...dataToUpdate,
+ {
+ key: "",
+ value: "",
+ },
+ ]
+ : removeAtIndex(dataToUpdate, fieldIndex),
+ },
+ });
+ };
- return (
-
- change(event, false)}
- />
- change(event, true)}
- />
-
- );
-}, propsCompare);
+ return (
+
+ {isLoading ? (
+ <>
+
+ {!hidePrivateMetadata && }
+ >
+ ) : (
+ <>
+ change(event, false)}
+ />
+ {(data?.privateMetadata || !hidePrivateMetadata) && (
+ change(event, true)}
+ />
+ )}
+ >
+ )}
+
+ );
+ },
+ propsCompare,
+);
Metadata.displayName = "Metadata";
diff --git a/src/components/Metadata/MetadataCard.tsx b/src/components/Metadata/MetadataCard.tsx
index 8c9d0bffb14..01a7577ca6a 100644
--- a/src/components/Metadata/MetadataCard.tsx
+++ b/src/components/Metadata/MetadataCard.tsx
@@ -7,6 +7,7 @@ import { FormattedMessage, useIntl } from "react-intl";
import { DashboardCard } from "../Card";
import { MetadataCardTable } from "./MetadataCardTable";
import { EventDataAction } from "./types";
+import { getMetadataTitle } from "./utils";
export interface MetadataCardProps {
data: MetadataInput[];
@@ -23,17 +24,6 @@ export const MetadataCard: React.FC = ({
}) => {
const intl = useIntl();
const [expanded, setExpanded] = useState(readonly ? "metadata-accordion" : undefined);
- const title = isPrivate
- ? {
- id: "ETHnjq",
- defaultMessage: "Private Metadata",
- description: "header",
- }
- : {
- id: "VcI+Zh",
- defaultMessage: "Metadata",
- description: "header",
- };
return (
@@ -43,7 +33,7 @@ export const MetadataCard: React.FC = ({
- {intl.formatMessage(title)}
+ {intl.formatMessage(getMetadataTitle(isPrivate))}
{data?.length > 0 && (
diff --git a/src/components/Metadata/MetadataLoadingCard.tsx b/src/components/Metadata/MetadataLoadingCard.tsx
new file mode 100644
index 00000000000..7e04b20f383
--- /dev/null
+++ b/src/components/Metadata/MetadataLoadingCard.tsx
@@ -0,0 +1,25 @@
+import { Box, Skeleton, Text } from "@saleor/macaw-ui-next";
+import React from "react";
+import { useIntl } from "react-intl";
+
+import { DashboardCard } from "../Card";
+import { getMetadataTitle } from "./utils";
+
+export const MetadataLoadingCard: React.FC<{ isPrivate?: boolean }> = ({ isPrivate = false }) => {
+ const intl = useIntl();
+
+ return (
+
+
+
+ {intl.formatMessage(getMetadataTitle(isPrivate))}
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/components/Metadata/utils.ts b/src/components/Metadata/utils.ts
index 0e01a37a680..21413735409 100644
--- a/src/components/Metadata/utils.ts
+++ b/src/components/Metadata/utils.ts
@@ -47,3 +47,16 @@ export function parseEventData(event: ChangeEvent): EventData {
export function getDataKey(isPrivate: boolean) {
return isPrivate ? "privateMetadata" : "metadata";
}
+
+export const getMetadataTitle = (isPrivate: boolean) =>
+ isPrivate
+ ? {
+ id: "ETHnjq",
+ defaultMessage: "Private Metadata",
+ description: "header",
+ }
+ : {
+ id: "VcI+Zh",
+ defaultMessage: "Metadata",
+ description: "header",
+ };
diff --git a/src/components/Modal/Close.tsx b/src/components/Modal/Close.tsx
index 26218adc857..0839f46ef35 100644
--- a/src/components/Modal/Close.tsx
+++ b/src/components/Modal/Close.tsx
@@ -4,7 +4,13 @@ import React from "react";
export const Close = ({ onClose, ...rest }: PropsWithBox<{ onClose: () => void }>) => {
return (
- } size="small" variant="tertiary" onClick={onClose} />
+ }
+ size="small"
+ variant="tertiary"
+ onClick={onClose}
+ />
);
};
diff --git a/src/components/Modal/Content.tsx b/src/components/Modal/Content.tsx
index cbc455b4a18..964b682dda5 100644
--- a/src/components/Modal/Content.tsx
+++ b/src/components/Modal/Content.tsx
@@ -1,12 +1,23 @@
import { Box, Modal, PropsWithBox } from "@saleor/macaw-ui-next";
import React, { ReactNode } from "react";
+export type ContentSize = "xs" | "sm" | "md" | "lg" | "xl";
+
type ContentProps = PropsWithBox<{
children: ReactNode;
disableAutofocus?: boolean;
+ size: ContentSize;
}>;
-export const Content = ({ children, disableAutofocus, ...rest }: ContentProps) => {
+const sizes: Record = {
+ xs: 444,
+ sm: 600,
+ md: 960,
+ lg: 1280,
+ xl: 1920,
+};
+
+export const Content = ({ children, disableAutofocus, size, ...rest }: ContentProps) => {
return (
diff --git a/src/components/Modal/Grid.tsx b/src/components/Modal/Grid.tsx
new file mode 100644
index 00000000000..c44999468e8
--- /dev/null
+++ b/src/components/Modal/Grid.tsx
@@ -0,0 +1,10 @@
+import { Box, PropsWithBox } from "@saleor/macaw-ui-next";
+import React from "react";
+
+export const Grid = ({ children, ...rest }: PropsWithBox<{ children: React.ReactNode }>) => {
+ return (
+
+ {children}
+
+ );
+};
diff --git a/src/components/Modal/Header.tsx b/src/components/Modal/Header.tsx
new file mode 100644
index 00000000000..f9c54336d48
--- /dev/null
+++ b/src/components/Modal/Header.tsx
@@ -0,0 +1,21 @@
+import { useModalContext } from "@dashboard/components/Modal/context";
+import { Box } from "@saleor/macaw-ui-next";
+import React, { ReactNode } from "react";
+
+import { Close } from "./Close";
+import { Title, TitleProps } from "./Title";
+
+interface HeaderProps extends TitleProps {
+ children: ReactNode;
+}
+
+export const Header = ({ children, ...rest }: HeaderProps) => {
+ const { onChange } = useModalContext();
+
+ return (
+
+ {children}
+ onChange?.(false)} />
+
+ );
+};
diff --git a/src/components/Modal/Root.tsx b/src/components/Modal/Root.tsx
index 3b423af088b..cd05e5b0cba 100644
--- a/src/components/Modal/Root.tsx
+++ b/src/components/Modal/Root.tsx
@@ -1,6 +1,15 @@
+import { ModalContextProvider } from "@dashboard/components/Modal/context";
import { Modal, ModalRootProps } from "@saleor/macaw-ui-next";
import React from "react";
-export const Root = ({ children, ...rest }: ModalRootProps) => {
- return {children} ;
+type RootProps = ModalRootProps;
+
+export const Root = ({ children, onChange, open, ...rest }: RootProps) => {
+ return (
+
+
+ {children}
+
+
+ );
};
diff --git a/src/components/Modal/Title.tsx b/src/components/Modal/Title.tsx
index 6d335727c6c..c3f34418ca0 100644
--- a/src/components/Modal/Title.tsx
+++ b/src/components/Modal/Title.tsx
@@ -1,7 +1,7 @@
import { Text, TextProps } from "@saleor/macaw-ui-next";
import React, { ReactNode } from "react";
-interface TitleProps extends TextProps {
+export interface TitleProps extends TextProps {
children: ReactNode;
}
diff --git a/src/components/Modal/context.tsx b/src/components/Modal/context.tsx
new file mode 100644
index 00000000000..60bc8692c7b
--- /dev/null
+++ b/src/components/Modal/context.tsx
@@ -0,0 +1,30 @@
+import React, { createContext } from "react";
+
+interface ModalContextValues {
+ open?: boolean;
+ onChange?: (open: boolean) => void;
+}
+
+const ModalContext = createContext(null);
+
+export const ModalContextProvider = ({
+ children,
+ onChange,
+ open,
+}: {
+ children: React.ReactNode;
+ onChange?: (open: boolean) => void;
+ open?: boolean;
+}) => {
+ return {children} ;
+};
+
+export const useModalContext = () => {
+ const context = React.useContext(ModalContext);
+
+ if (!context) {
+ throw new Error("useModalContext must be used within a ModalContextProvider");
+ }
+
+ return context;
+};
diff --git a/src/components/Modal/index.ts b/src/components/Modal/index.ts
index 5f03e1dcfaf..0a2cf217007 100644
--- a/src/components/Modal/index.ts
+++ b/src/components/Modal/index.ts
@@ -1,14 +1,18 @@
import { Actions } from "./Actions";
import { Close } from "./Close";
-import { Content } from "./Content";
+import { Content, ContentSize } from "./Content";
+import { Grid } from "./Grid";
+import { Header } from "./Header";
import { Root } from "./Root";
import { Title } from "./Title";
-export const DASHBOARD_MODAL_WIDTH = 600;
+export type DashboardModalContentSize = ContentSize;
export const DashboardModal = Object.assign(Root, {
Title,
Content,
Actions,
Close,
+ Grid,
+ Header,
});
diff --git a/src/components/Money/Money.tsx b/src/components/Money/Money.tsx
index 62fcf6f3130..e27fd9ea5c1 100644
--- a/src/components/Money/Money.tsx
+++ b/src/components/Money/Money.tsx
@@ -32,7 +32,7 @@ export const Money: React.FC = props => {
}
return (
-
+
{money.currency}
{formatMoneyAmount(money, locale)}
diff --git a/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectField.tsx b/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectField.tsx
index fb10736f409..e69de29bb2d 100644
--- a/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectField.tsx
+++ b/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectField.tsx
@@ -1,274 +0,0 @@
-// @ts-strict-ignore
-import Debounce, { DebounceProps } from "@dashboard/components/Debounce";
-import { fuzzySearch } from "@dashboard/misc";
-import { FetchMoreProps } from "@dashboard/types";
-import { Popper, PopperPlacementType, TextField, Typography } from "@material-ui/core";
-import CloseIcon from "@material-ui/icons/Close";
-import { ChevronIcon, IconButton } from "@saleor/macaw-ui";
-import clsx from "clsx";
-import Downshift, { ControllerStateAndHelpers } from "downshift";
-import React from "react";
-
-import MultiAutocompleteSelectFieldContent, {
- MultiAutocompleteActionType,
- MultiAutocompleteChoiceType,
-} from "./MultiAutocompleteSelectFieldContent";
-import { useStyles } from "./styles";
-
-export interface MultiAutocompleteSelectFieldProps extends Partial {
- add?: MultiAutocompleteActionType;
- allowCustomValues?: boolean;
- displayValues: MultiAutocompleteChoiceType[];
- error?: boolean;
- name: string;
- choices: MultiAutocompleteChoiceType[];
- value: string[];
- loading?: boolean;
- placeholder?: string;
- helperText?: string;
- label?: string;
- disabled?: boolean;
- testId?: string;
- fetchChoices?: (value: string) => void;
- onChange: (event: React.ChangeEvent) => void;
- onBlur?: () => void;
- fetchOnFocus?: boolean;
- endAdornment?: React.ReactNode;
- popperPlacement?: PopperPlacementType;
-}
-
-const DebounceAutocomplete: React.ComponentType> = Debounce;
-const MultiAutocompleteSelectFieldComponent: React.FC<
- MultiAutocompleteSelectFieldProps
-> = props => {
- const {
- add,
- allowCustomValues,
- choices,
- displayValues,
- error,
- hasMore,
- helperText,
- label,
- loading,
- name,
- placeholder,
- value,
- disabled,
- testId,
- fetchChoices,
- onChange,
- onBlur,
- onFetchMore,
- fetchOnFocus,
- endAdornment,
- popperPlacement = "bottom-end",
- ...rest
- } = props;
- const classes = useStyles(props);
- const anchor = React.useRef(null);
- const input = React.useRef(null);
- const [inputValue, setInputValue] = React.useState("");
- const handleSelect = (item: string, downshiftOpts?: ControllerStateAndHelpers) => {
- if (downshiftOpts) {
- downshiftOpts.reset({
- inputValue: downshiftOpts.inputValue,
- isOpen: true,
- });
- }
-
- onChange({
- target: { name, value: item },
- } as any);
- };
-
- return (
- <>
- {
- setInputValue(value);
- fetchChoices(value);
- }}
- >
- {debounceFn => (
- debounceFn(value)}
- onSelect={handleSelect}
- itemToString={() => inputValue}
- // this is to prevent unwanted state updates when the dropdown is closed with an empty value,
- // which downshift interprets as the value being updated with an empty string, causing side-effects
- stateReducer={(state, changes) => {
- if (!changes.isOpen && state.inputValue === "") {
- delete changes.inputValue;
- }
-
- return changes;
- }}
- >
- {({
- closeMenu,
- getInputProps,
- getItemProps,
- isOpen,
- toggleMenu,
- getMenuProps,
- highlightedIndex,
- inputValue,
- }) => {
- const displayCustomValue =
- inputValue &&
- inputValue.length > 0 &&
- allowCustomValues &&
- !choices.find(choice => choice.label.toLowerCase() === inputValue.toLowerCase());
- const handleFocus = () => {
- if (fetchOnFocus) {
- fetchChoices(inputValue);
- }
-
- if (input.current) {
- input.current.select();
- }
- };
- const handleToggleMenu = () => {
- if (disabled) {
- return;
- }
-
- toggleMenu();
- };
-
- return (
-
- {
- handleToggleMenu();
- handleFocus();
- }}
- className={clsx(classes.adornment, {
- [classes.adornmentRotate]: isOpen,
- })}
- >
- {endAdornment}
-
-
- ),
- id: undefined,
- onFocus: handleFocus,
- ref: anchor,
- }}
- inputProps={{
- ...getInputProps({
- placeholder,
- testId,
- onClick: handleToggleMenu,
- }),
- ...getMenuProps(),
- }}
- error={error}
- helperText={helperText}
- label={label}
- fullWidth={true}
- disabled={disabled}
- autoFocus={true}
- onBlur={onBlur}
- inputRef={input}
- />
- {isOpen && (
-
- {
- add.onClick();
- closeMenu();
- },
- }
- }
- choices={choices?.filter(choice => !value.includes(choice.value))}
- displayCustomValue={displayCustomValue}
- displayValues={displayValues}
- getItemProps={getItemProps}
- hasMore={hasMore}
- highlightedIndex={highlightedIndex}
- loading={loading}
- inputValue={inputValue}
- onFetchMore={onFetchMore}
- />
-
- )}
-
- );
- }}
-
- )}
-
-
- {displayValues.map(value => (
-
-
- {value.label}
-
- handleSelect(value.value)}
- >
-
-
-
-
- ))}
-
- >
- );
-};
-const MultiAutocompleteSelectField: React.FC = ({
- choices,
- fetchChoices,
- testId,
- ...props
-}) => {
- const [query, setQuery] = React.useState("");
-
- if (fetchChoices) {
- return (
-
- );
- }
-
- return (
- setQuery(q || "")}
- choices={fuzzySearch(choices, query, ["label"])}
- {...props}
- />
- );
-};
-
-MultiAutocompleteSelectField.displayName = "MultiAutocompleteSelectField";
-export default MultiAutocompleteSelectField;
diff --git a/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectFieldContent.tsx b/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectFieldContent.tsx
index fbe36bfc89d..e69de29bb2d 100644
--- a/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectFieldContent.tsx
+++ b/src/components/MultiAutocompleteSelectField/MultiAutocompleteSelectFieldContent.tsx
@@ -1,334 +0,0 @@
-// @ts-strict-ignore
-import chevronDown from "@assets/images/ChevronDown.svg";
-import Checkbox from "@dashboard/components/Checkbox";
-import HorizontalSpacer from "@dashboard/components/HorizontalSpacer";
-import useElementScroll, { isScrolledToBottom } from "@dashboard/hooks/useElementScroll";
-import { FetchMoreProps } from "@dashboard/types";
-import { CircularProgress, MenuItem, Paper, Typography } from "@material-ui/core";
-import AddIcon from "@material-ui/icons/Add";
-import { makeStyles } from "@saleor/macaw-ui";
-import clsx from "clsx";
-import { GetItemPropsOptions } from "downshift";
-import React, { ReactNode } from "react";
-import SVG from "react-inlinesvg";
-import { FormattedMessage } from "react-intl";
-
-import Hr from "../Hr";
-
-const menuItemHeight = 46;
-const maxMenuItems = 5;
-const offset = 24;
-
-export interface MultiAutocompleteActionType {
- label: string;
- onClick: () => void;
-}
-export interface MultiAutocompleteChoiceType {
- label: string;
- value: any;
- disabled?: boolean;
- badge?: ReactNode;
-}
-export interface MultiAutocompleteSelectFieldContentProps extends Partial {
- add?: MultiAutocompleteActionType;
- choices: MultiAutocompleteChoiceType[];
- displayCustomValue: boolean;
- displayValues: MultiAutocompleteChoiceType[];
- getItemProps: (options: GetItemPropsOptions) => any;
- highlightedIndex: number;
- inputValue: string;
-}
-
-const useStyles = makeStyles(
- theme => ({
- add: {
- background: theme.palette.background.default,
- border: `1px solid ${theme.palette.divider}`,
- borderRadius: "100%",
- height: 24,
- margin: theme.spacing(),
- width: 24,
- },
- addIcon: {
- height: 24,
- margin: 9,
- width: 20,
- },
- arrowContainer: {
- position: "relative",
- },
- arrowInnerContainer: {
- alignItems: "center",
- background: theme.palette.type === "light" ? theme.palette.grey[50] : theme.palette.grey[900],
- bottom: 0,
- color: theme.palette.grey[500],
- display: "flex",
- height: 30,
- justifyContent: "center",
- opacity: 1,
- position: "absolute",
- transition: theme.transitions.duration.short + "ms",
- width: "100%",
- },
- checkbox: {
- height: 24,
- width: 20,
- },
- content: {
- maxHeight: `calc(${menuItemHeight * maxMenuItems}px + ${theme.spacing(2)})`,
- overflowY: "scroll",
- padding: 8,
- },
- hide: {
- opacity: 0,
- zIndex: -1,
- },
- hr: {
- margin: theme.spacing(1, 0),
- },
- menuItem: {
- "&:focus": {
- backgroundColor: [theme.palette.background.default, "!important"] as any,
- color: theme.palette.primary.main,
- fontWeight: 400,
- },
- "&:hover": {
- backgroundColor: [theme.palette.background.default, "!important"] as any,
- color: theme.palette.primary.main,
- fontWeight: 700,
- },
- paddingLeft: theme.spacing(1.5),
- borderRadius: 4,
- display: "grid",
- gridColumnGap: theme.spacing(1),
- gridTemplateColumns: "30px 1fr",
- height: "auto",
- marginBottom: theme.spacing(0.5),
- padding: 0,
- whiteSpace: "normal",
- },
- menuItemLabel: {
- display: "flex",
- overflowWrap: "break-word",
- },
- progress: {},
- progressContainer: {
- display: "flex",
- justifyContent: "center",
- padding: theme.spacing(1, 0),
- },
- root: {
- borderBottomLeftRadius: 8,
- borderBottomRightRadius: 8,
- margin: theme.spacing(1, 0),
- overflow: "hidden",
- zIndex: 22,
- },
- }),
- {
- name: "MultiAutocompleteSelectFieldContent",
- },
-);
-
-function getChoiceIndex(
- index: number,
- displayValues: MultiAutocompleteChoiceType[],
- displayCustomValue: boolean,
- add: boolean,
-) {
- let choiceIndex = index;
-
- if (add || displayCustomValue) {
- choiceIndex += 2;
- }
-
- if (displayValues.length > 0) {
- choiceIndex += 1 + displayValues.length;
- }
-
- return choiceIndex;
-}
-
-const MultiAutocompleteSelectFieldContent: React.FC<
- MultiAutocompleteSelectFieldContentProps
-> = props => {
- const {
- add,
- choices = [],
- displayCustomValue,
- displayValues,
- getItemProps,
- hasMore,
- highlightedIndex,
- loading,
- inputValue,
- onFetchMore,
- } = props;
-
- if (!!add && !!displayCustomValue) {
- throw new Error("Add and custom value cannot be displayed simultaneously");
- }
-
- const classes = useStyles(props);
- const anchor = React.useRef();
- const scrollPosition = useElementScroll(anchor);
- const [calledForMore, setCalledForMore] = React.useState(false);
- const scrolledToBottom = isScrolledToBottom(anchor, scrollPosition, offset);
-
- React.useEffect(() => {
- if (!calledForMore && onFetchMore && scrolledToBottom) {
- onFetchMore();
- setCalledForMore(true);
- }
- }, [scrolledToBottom]);
- React.useEffect(() => {
- if (calledForMore && !loading) {
- setCalledForMore(false);
- }
- }, [loading]);
-
- const hasValuesToDisplay = displayValues?.length > 0 || displayCustomValue || choices.length > 0;
-
- return (
-
- {hasValuesToDisplay && (
-
- <>
- {add && (
-
-
- {add.label}
-
- )}
- {displayCustomValue && (
-
-
-
-
- )}
- {(choices.length > 0 || displayValues?.length > 0) && displayCustomValue && (
-
- )}
- {displayValues?.map(value => (
-
-
-
- {value.badge}
- {value.badge && }
- {value.label}
-
-
- ))}
- {displayValues?.length > 0 && choices.length > 0 &&
}
- {choices.map((suggestion, index) => {
- const choiceIndex = getChoiceIndex(index, displayValues, displayCustomValue, !!add);
-
- return (
-
-
-
-
- {suggestion.badge}
- {suggestion.badge && }
- {suggestion.label}
-
-
- );
- })}
- >
-
- )}
- {!loading && !hasValuesToDisplay && (
-
-
-
- )}
- {(hasMore || loading) && (
- <>
- {hasMore && }
-
-
-
- >
- )}
- {choices.length > maxMenuItems && (
-
- )}
-
- );
-};
-
-MultiAutocompleteSelectFieldContent.displayName = "MultiAutocompleteSelectFieldContent";
-export default MultiAutocompleteSelectFieldContent;
diff --git a/src/components/MultiAutocompleteSelectField/index.ts b/src/components/MultiAutocompleteSelectField/index.ts
deleted file mode 100644
index 8a33bf4b47c..00000000000
--- a/src/components/MultiAutocompleteSelectField/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { default } from "./MultiAutocompleteSelectField";
-export * from "./MultiAutocompleteSelectField";
-export * from "./MultiAutocompleteSelectFieldContent";
diff --git a/src/components/MultiAutocompleteSelectField/styles.ts b/src/components/MultiAutocompleteSelectField/styles.ts
deleted file mode 100644
index 4d3cca04004..00000000000
--- a/src/components/MultiAutocompleteSelectField/styles.ts
+++ /dev/null
@@ -1,75 +0,0 @@
-import { alpha } from "@material-ui/core/styles";
-import { makeStyles } from "@saleor/macaw-ui";
-
-export const useStyles = makeStyles(
- theme => ({
- chip: {
- width: "100%",
- },
- chipClose: {
- height: 32,
- padding: 0,
- width: 32,
- border: 0,
- },
- chipContainer: {
- display: "flex",
- flexDirection: "column",
- marginTop: theme.spacing(1),
- },
- chipInner: {
- "& svg": {
- color: theme.palette.primary.contrastText,
- },
- alignItems: "center",
- background:
- theme.palette.type === "dark"
- ? theme.palette.secondary.main
- : alpha(theme.palette.primary.main, 0.8),
- borderRadius: 18,
- color: theme.palette.primary.contrastText,
- display: "flex",
- justifyContent: "space-between",
- margin: theme.spacing(1, 0),
- paddingLeft: theme.spacing(2),
- paddingRight: theme.spacing(1),
- },
- chipLabel: {
- color: theme.palette.primary.contrastText,
- },
- container: {
- flexGrow: 1,
- position: "relative",
- },
- disabledChipInner: {
- "& svg": {
- color: theme.palette.grey[200],
- },
- alignItems: "center",
- background: alpha(theme.palette.grey[400], 0.8),
- borderRadius: 18,
- color: theme.palette.primary.contrastText,
- display: "flex",
- justifyContent: "space-between",
- margin: theme.spacing(1, 0),
- paddingLeft: theme.spacing(2),
- paddingRight: theme.spacing(1),
- },
- adornment: {
- color: theme.palette.saleor.main[3],
- cursor: "pointer",
- userSelect: "none",
- display: "flex",
- alignItems: "center",
- "& svg": {
- transition: theme.transitions.duration.shorter + "ms",
- },
- },
- adornmentRotate: {
- "& svg": {
- transform: "rotate(180deg)",
- },
- },
- }),
- { name: "MultiAutocompleteSelectField" },
-);
diff --git a/src/components/MultiSelectField/MultiSelectField.tsx b/src/components/MultiSelectField/MultiSelectField.tsx
deleted file mode 100644
index b4d0a5ebab6..00000000000
--- a/src/components/MultiSelectField/MultiSelectField.tsx
+++ /dev/null
@@ -1,108 +0,0 @@
-// @ts-strict-ignore
-import {
- FilledInput,
- FormControl,
- FormHelperText,
- InputLabel,
- MenuItem,
- Select,
-} from "@material-ui/core";
-import { SelectProps } from "@material-ui/core/Select";
-import { makeStyles } from "@saleor/macaw-ui";
-import React from "react";
-import { FormattedMessage } from "react-intl";
-
-import Checkbox from "../Checkbox";
-
-const useStyles = makeStyles(
- theme => ({
- checkbox: {
- marginRight: theme.spacing(-2),
- },
- formControl: {
- width: "100%",
- },
- menuItem: {
- alignItems: "center",
- display: "flex",
- justifyContent: "space-between",
- width: "100%",
- },
- }),
- { name: "MultiSelectField" },
-);
-
-interface MultiSelectFieldProps {
- choices: Array<{
- value: string;
- label: string;
- }>;
- disabled?: boolean;
- error?: boolean;
- hint?: string;
- label?: string;
- name?: string;
- selectProps?: SelectProps;
- value?: string[];
- onChange: (event: any) => any;
-}
-
-export const MultiSelectField: React.FC = props => {
- const { disabled, error, label, choices, value, onChange, name, hint, selectProps } = props;
- const classes = useStyles(props);
- const choicesByKey = disabled
- ? {}
- : choices.reduce((prev, curr) => {
- prev[curr.value] = curr.label;
-
- return prev;
- }, {});
-
- return (
-
- {label && {label} }
-
- (choiceValues as string[]).map(choiceValue => choicesByKey[choiceValue]).join(", ")
- }
- value={value}
- name={name}
- onChange={onChange}
- input={ }
- {...selectProps}
- >
- {choices.length > 0 ? (
- choices.map(choice => {
- const isSelected = !!value.find(selectedChoice => selectedChoice === choice.value);
-
- return (
-
-
- {choice.label}
-
-
-
- );
- })
- ) : (
-
-
-
- )}
-
- {hint && {hint} }
-
- );
-};
-MultiSelectField.defaultProps = {
- value: [],
-};
-MultiSelectField.displayName = "MultiSelectField";
-export default MultiSelectField;
diff --git a/src/components/MultiSelectField/index.ts b/src/components/MultiSelectField/index.ts
deleted file mode 100644
index 16d0759519d..00000000000
--- a/src/components/MultiSelectField/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from "./MultiSelectField";
-export * from "./MultiSelectField";
diff --git a/src/components/NavigatorSearch/NavigatorSearch.tsx b/src/components/NavigatorSearch/NavigatorSearch.tsx
index 3d21b627a77..d68594e456d 100644
--- a/src/components/NavigatorSearch/NavigatorSearch.tsx
+++ b/src/components/NavigatorSearch/NavigatorSearch.tsx
@@ -140,8 +140,8 @@ const NavigatorSearch: React.FC = () => {
return (
-
-
+
+
(item ? item.label : "")}
onSelect={(item: QuickSearchAction) => {
diff --git a/src/components/NavigatorSearch/NavigatorSearchSection.tsx b/src/components/NavigatorSearch/NavigatorSearchSection.tsx
index 99c151809a0..43ed8196958 100644
--- a/src/components/NavigatorSearch/NavigatorSearchSection.tsx
+++ b/src/components/NavigatorSearch/NavigatorSearchSection.tsx
@@ -56,7 +56,7 @@ const NavigatorSearchSection: React.FC = props => {
{item.label}
{item.caption && (
-
+
{item.caption}
)}
diff --git a/src/components/NavigatorSearch/modes/index.ts b/src/components/NavigatorSearch/modes/index.ts
index 666e4ad551f..105e377216e 100644
--- a/src/components/NavigatorSearch/modes/index.ts
+++ b/src/components/NavigatorSearch/modes/index.ts
@@ -33,7 +33,7 @@ function getModeActions(
case "help":
return getHelpModeActions(query, intl, cbs.setMode);
case "orders":
- return getOrdersModeActions(query, intl, cbs.navigate, queries.order);
+ return getOrdersModeActions(intl, cbs.navigate, queries.orders);
default:
return getDefaultModeActions(query, intl, cbs.navigate, cbs.createOrder, cbs.setMode);
}
diff --git a/src/components/NavigatorSearch/modes/orders.ts b/src/components/NavigatorSearch/modes/orders.ts
index c6157b8e654..31e83b8e7d3 100644
--- a/src/components/NavigatorSearch/modes/orders.ts
+++ b/src/components/NavigatorSearch/modes/orders.ts
@@ -1,10 +1,10 @@
// @ts-strict-ignore
-import { CheckIfOrderExistsQuery } from "@dashboard/graphql";
import { UseNavigatorResult } from "@dashboard/hooks/useNavigator";
-import { maybe, transformOrderStatus } from "@dashboard/misc";
+import { transformOrderStatus } from "@dashboard/misc";
import { orderUrl } from "@dashboard/orders/urls";
import { IntlShape } from "react-intl";
+import { QuickOrderSearchResult } from "../queries/useQuickOrderSearch";
import { QuickSearchAction } from "../types";
import messages from "./messages";
@@ -17,31 +17,30 @@ export function getGqlOrderId(orderNumber: string): string {
}
function getOrdersModeActions(
- query: string,
intl: IntlShape,
navigate: UseNavigatorResult,
- order: CheckIfOrderExistsQuery["order"],
+ orders: QuickOrderSearchResult,
): QuickSearchAction[] {
- const gqlId = getGqlOrderId(query);
-
- if (isQueryValidOrderNumber(query) && maybe(() => order.id === gqlId)) {
- return [
- {
- extraInfo: transformOrderStatus(order.status, intl).localized,
- label: intl.formatMessage(messages.goToOrder, {
- orderNumber: query,
- }),
- onClick: () => {
- navigate(orderUrl(gqlId));
-
- return false;
- },
- type: "action",
- },
- ];
+ if (!orders) {
+ return [];
}
- return [];
+ return orders.map(order => {
+ const orderNumber = order?.number ?? "";
+
+ return {
+ extraInfo: transformOrderStatus(order.status, intl).localized,
+ label: intl.formatMessage(messages.goToOrder, {
+ orderNumber,
+ }),
+ onClick: () => {
+ navigate(orderUrl(order.id));
+
+ return false;
+ },
+ type: "action",
+ };
+ });
}
export default getOrdersModeActions;
diff --git a/src/components/NavigatorSearch/modes/types.ts b/src/components/NavigatorSearch/modes/types.ts
index baec023150e..1e3d757a478 100644
--- a/src/components/NavigatorSearch/modes/types.ts
+++ b/src/components/NavigatorSearch/modes/types.ts
@@ -1,13 +1,11 @@
// @ts-strict-ignore
-import {
- CheckIfOrderExistsQuery,
- SearchCatalogQuery,
- SearchCustomersQuery,
-} from "@dashboard/graphql";
+import { SearchCatalogQuery, SearchCustomersQuery } from "@dashboard/graphql";
import { RelayToFlat } from "@dashboard/types";
+import { QuickOrderSearchResult } from "../queries/useQuickOrderSearch";
+
export interface ActionQueries {
catalog: SearchCatalogQuery;
customers: RelayToFlat;
- order: CheckIfOrderExistsQuery["order"];
+ orders: QuickOrderSearchResult;
}
diff --git a/src/components/NavigatorSearch/queries/queries.ts b/src/components/NavigatorSearch/queries/queries.ts
index 0b6694ee02b..b9fb6d1f85a 100644
--- a/src/components/NavigatorSearch/queries/queries.ts
+++ b/src/components/NavigatorSearch/queries/queries.ts
@@ -1,10 +1,15 @@
import { gql } from "@apollo/client";
-export const checkIfOrderExists = gql`
- query CheckIfOrderExists($id: ID!) {
- order(id: $id) {
- id
- status
+export const searchOrdersByNumber = gql`
+ query SearchOrdersByNumber($first: Int!, $query: [String!]) {
+ orders(first: $first, filter: { numbers: $query }) {
+ edges {
+ node {
+ id
+ number
+ status
+ }
+ }
}
}
`;
diff --git a/src/components/NavigatorSearch/queries/useCheckIfOrderExists.ts b/src/components/NavigatorSearch/queries/useCheckIfOrderExists.ts
deleted file mode 100644
index a90c0cbd568..00000000000
--- a/src/components/NavigatorSearch/queries/useCheckIfOrderExists.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { CheckIfOrderExistsQueryHookResult, useCheckIfOrderExistsQuery } from "@dashboard/graphql";
-import useDebounce from "@dashboard/hooks/useDebounce";
-import { useState } from "react";
-
-function useCheckIfOrderExists(): [CheckIfOrderExistsQueryHookResult, (query: string) => void] {
- const [id, setId] = useState("");
- const setIdDebounced = useDebounce(setId);
- const result = useCheckIfOrderExistsQuery({
- skip: id === "",
- variables: {
- id,
- },
- });
-
- return [result, setIdDebounced];
-}
-export default useCheckIfOrderExists;
diff --git a/src/components/NavigatorSearch/queries/useQuickOrderSearch.test.ts b/src/components/NavigatorSearch/queries/useQuickOrderSearch.test.ts
new file mode 100644
index 00000000000..2cdb2df50fd
--- /dev/null
+++ b/src/components/NavigatorSearch/queries/useQuickOrderSearch.test.ts
@@ -0,0 +1,31 @@
+import { act, renderHook } from "@testing-library/react-hooks";
+
+import { useQuickOrderSearch } from "./useQuickOrderSearch";
+
+const useSearchOrdersByNumberQuery = jest.fn();
+
+jest.mock("@dashboard/graphql", () => ({
+ SearchOrdersByNumberQuery: {},
+ useSearchOrdersByNumberQuery: (props: any) => useSearchOrdersByNumberQuery(props),
+}));
+jest.mock("@dashboard/hooks/useDebounce", () => (fn: any) => fn);
+
+describe("useQuickOrderSearch", () => {
+ it("invokes search query", () => {
+ // Arrange
+ const { result } = renderHook(() => useQuickOrderSearch());
+ const [, setQueryDebounced] = result.current;
+
+ // Act
+ act(() => setQueryDebounced("1234"));
+
+ // Assert
+ expect(useSearchOrdersByNumberQuery).toHaveBeenCalledWith({
+ skip: false,
+ variables: {
+ first: 1,
+ query: "1234",
+ },
+ });
+ });
+});
diff --git a/src/components/NavigatorSearch/queries/useQuickOrderSearch.ts b/src/components/NavigatorSearch/queries/useQuickOrderSearch.ts
new file mode 100644
index 00000000000..c806c1b3f69
--- /dev/null
+++ b/src/components/NavigatorSearch/queries/useQuickOrderSearch.ts
@@ -0,0 +1,28 @@
+import {
+ SearchOrdersByNumberQuery,
+ SearchOrdersByNumberQueryHookResult,
+ useSearchOrdersByNumberQuery,
+} from "@dashboard/graphql";
+import useDebounce from "@dashboard/hooks/useDebounce";
+import { useState } from "react";
+
+type OrderNode = NonNullable["edges"][0]["node"];
+export type QuickOrderSearchResult = OrderNode[];
+
+export function useQuickOrderSearch(): [
+ SearchOrdersByNumberQueryHookResult,
+ (query: string) => void,
+] {
+ const [query, setQuery] = useState("");
+ const setQueryDebounced = useDebounce(setQuery);
+
+ const result = useSearchOrdersByNumberQuery({
+ skip: query === "",
+ variables: {
+ first: 1,
+ query,
+ },
+ });
+
+ return [result, setQueryDebounced];
+}
diff --git a/src/components/NavigatorSearch/useQuickSearch.ts b/src/components/NavigatorSearch/useQuickSearch.ts
index fc207d9deda..a9b58bca452 100644
--- a/src/components/NavigatorSearch/useQuickSearch.ts
+++ b/src/components/NavigatorSearch/useQuickSearch.ts
@@ -4,7 +4,6 @@ import { useOrderDraftCreateMutation } from "@dashboard/graphql";
import { ChangeEvent, FormChange } from "@dashboard/hooks/useForm";
import useModalDialogOpen from "@dashboard/hooks/useModalDialogOpen";
import useNavigator from "@dashboard/hooks/useNavigator";
-import { maybe } from "@dashboard/misc";
import { orderUrl } from "@dashboard/orders/urls";
import useCustomerSearch from "@dashboard/searches/useCustomerSearch";
import { mapEdgesToItems } from "@dashboard/utils/maps";
@@ -12,10 +11,10 @@ import { RefObject, useEffect, useState } from "react";
import { useIntl } from "react-intl";
import getModeActions from "./modes";
-import { getGqlOrderId, isQueryValidOrderNumber } from "./modes/orders";
+import { isQueryValidOrderNumber } from "./modes/orders";
import { getMode } from "./modes/utils";
import useSearchCatalog from "./queries/useCatalogSearch";
-import useCheckIfOrderExists from "./queries/useCheckIfOrderExists";
+import { useQuickOrderSearch } from "./queries/useQuickOrderSearch";
import { QuickSearchAction, QuickSearchMode } from "./types";
type UseQuickSearch = [string, QuickSearchMode, FormChange, QuickSearchAction[]];
@@ -24,7 +23,8 @@ function useQuickSearch(open: boolean, input: RefObject): UseQ
const [mode, setMode] = useState("default");
const intl = useIntl();
const navigate = useNavigator();
- const [{ data: orderData }, getOrderData] = useCheckIfOrderExists();
+ const [{ data: orderData }, getOrderData] = useQuickOrderSearch();
+
const { result: customers, search: searchCustomers } = useCustomerSearch({
variables: {
...DEFAULT_INITIAL_SEARCH_DATA,
@@ -85,7 +85,7 @@ function useQuickSearch(open: boolean, input: RefObject): UseQ
}
if (mode === "orders" && isQueryValidOrderNumber(value)) {
- getOrderData(getGqlOrderId(value));
+ getOrderData(value);
}
if (mode === "catalog") {
@@ -110,7 +110,7 @@ function useQuickSearch(open: boolean, input: RefObject): UseQ
{
catalog,
customers: mapEdgesToItems(customers?.data?.search) || [],
- order: maybe(() => orderData.order),
+ orders: mapEdgesToItems(orderData?.orders) || [],
},
{
createOrder,
diff --git a/src/components/NotFoundPage/NotFoundPage.tsx b/src/components/NotFoundPage/NotFoundPage.tsx
index bb77aac2967..7a798ad701b 100644
--- a/src/components/NotFoundPage/NotFoundPage.tsx
+++ b/src/components/NotFoundPage/NotFoundPage.tsx
@@ -1,7 +1,7 @@
import notFoundImage from "@assets/images/not-found-404.svg";
import { Button } from "@dashboard/components/Button";
-import { Typography } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import SVG from "react-inlinesvg";
import { FormattedMessage } from "react-intl";
@@ -68,15 +68,21 @@ const NotFoundPage: React.FC = props => {
-
+
-
-
+
+
-
-
+
+
-
+
diff --git a/src/components/PageHeader/PageHeader.tsx b/src/components/PageHeader/PageHeader.tsx
index 2c9596219b3..cb841e742a1 100644
--- a/src/components/PageHeader/PageHeader.tsx
+++ b/src/components/PageHeader/PageHeader.tsx
@@ -1,10 +1,9 @@
-import { Typography } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
+import { Skeleton, Text } from "@saleor/macaw-ui-next";
import React from "react";
import ExtendedPageHeader from "../ExtendedPageHeader";
import PreviewPill from "../PreviewPill";
-import Skeleton from "../Skeleton";
const useStyles = makeStyles(
theme => ({
@@ -69,18 +68,18 @@ const PageHeader: React.FC = props => {
underline={underline}
title={
<>
-
+
{title !== undefined ? title : }
-
+
{cardMenu}
>
}
>
{limitText && (
-
+
{limitText}
-
+
)}
{children}
diff --git a/src/components/PageSectionHeader/PageSectionHeader.tsx b/src/components/PageSectionHeader/PageSectionHeader.tsx
index ad4afe6c621..a01affa7cc4 100644
--- a/src/components/PageSectionHeader/PageSectionHeader.tsx
+++ b/src/components/PageSectionHeader/PageSectionHeader.tsx
@@ -1,6 +1,5 @@
import VerticalSpacer from "@dashboard/components/VerticalSpacer";
-import { Typography } from "@material-ui/core";
-import { Box } from "@saleor/macaw-ui-next";
+import { Box, Text } from "@saleor/macaw-ui-next";
import React from "react";
interface PageSectionHeaderProps {
@@ -13,9 +12,17 @@ const PageSectionHeader: React.FC = props => {
return (
- {title && {title} }
+ {title && (
+
+ {title}
+
+ )}
{title && description && }
- {description && {description} }
+ {description && (
+
+ {description}
+
+ )}
);
};
diff --git a/src/components/PhoneField/PhoneField.tsx b/src/components/PhoneField/PhoneField.tsx
index af641879471..07f34859913 100644
--- a/src/components/PhoneField/PhoneField.tsx
+++ b/src/components/PhoneField/PhoneField.tsx
@@ -1,5 +1,6 @@
// @ts-strict-ignore
-import SingleSelectField from "@dashboard/components/SingleSelectField";
+import { Select } from "@dashboard/components/Select";
+import { ChangeEvent } from "@dashboard/hooks/useForm";
import { TextField } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
import React from "react";
@@ -21,18 +22,19 @@ interface PhoneFieldProps {
number: string;
prefixes: string[];
label?: string;
- onChange: (event: React.ChangeEvent) => any;
+ onChange: (event: ChangeEvent) => any;
}
const PhoneField: React.FC = props => {
const { name, number: phoneNumber, prefix, prefixes, label, onChange } = props;
const classes = useStyles(props);
+ const nameWithPrefix = name + "_prefix";
return (
-
({ label: "+" + p, value: p }))}
+ ({ label: "+" + p, value: p }))}
onChange={onChange}
value={prefix}
label={label}
diff --git a/src/components/PreviewPill/PreviewPill.tsx b/src/components/PreviewPill/PreviewPill.tsx
index 36ea5978900..44612251ed3 100644
--- a/src/components/PreviewPill/PreviewPill.tsx
+++ b/src/components/PreviewPill/PreviewPill.tsx
@@ -1,4 +1,5 @@
-import { Grow, Paper, Popper, Typography } from "@material-ui/core";
+import { Grow, Paper, Popper } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
@@ -38,9 +39,7 @@ export const PreviewPill: React.FC = ({ className }) => {
{({ TransitionProps }) => (
-
- {intl.formatMessage(messages.tooltip)}
-
+ {intl.formatMessage(messages.tooltip)}
)}
diff --git a/src/components/ProductAnalytics/index.tsx b/src/components/ProductAnalytics/index.tsx
index 5729339a672..bcc4a047dbf 100644
--- a/src/components/ProductAnalytics/index.tsx
+++ b/src/components/ProductAnalytics/index.tsx
@@ -1,20 +1,42 @@
+import { PostHogConfig } from "posthog-js";
import { PostHogProvider } from "posthog-js/react";
import React from "react";
+const isDomainExcluded = () => {
+ const domainsString = process.env.POSTHOG_EXCLUDED_DOMAINS;
+
+ if (!domainsString) {
+ return false;
+ }
+
+ const excludedDomains = domainsString.split(",");
+
+ return excludedDomains.some(domain => window.location.hostname.includes(domain));
+};
+
const useConfig = () => {
const options = {
api_host: process.env.POSTHOG_HOST,
capture_pageview: false,
autocapture: false,
advanced_disable_decide: true,
- };
+ cookie_expiration: 30, // 30 days,
+ loaded: posthog => {
+ if (process.env.NODE_ENV === "development") posthog.debug();
+ },
+ } satisfies Partial;
const apiKey = process.env.POSTHOG_KEY;
const isCloudInstance = process.env.IS_CLOUD_INSTANCE;
+
const canRenderAnalytics = () => {
if (!isCloudInstance) {
return false;
}
+ if (isDomainExcluded()) {
+ return false;
+ }
+
if (!options.api_host || !apiKey) {
return false;
}
diff --git a/src/components/ProductAnalytics/useAnalytics.ts b/src/components/ProductAnalytics/useAnalytics.ts
new file mode 100644
index 00000000000..6022721d1c5
--- /dev/null
+++ b/src/components/ProductAnalytics/useAnalytics.ts
@@ -0,0 +1,41 @@
+import { usePostHog } from "posthog-js/react";
+
+import { useRouteChange } from "../Router/useRouteChange";
+
+interface UserProperties {
+ domain: string;
+ email_domain: string;
+}
+
+interface Analytics {
+ initialize: (userProperties: UserProperties) => void;
+ trackEvent: (event: string, properties?: Record) => void;
+}
+
+export function useAnalytics(): Analytics {
+ const posthog = usePostHog();
+
+ const { register } = useRouteChange(location => {
+ trackEvent("$pageview", {
+ normalized_path: location.pathname,
+ });
+ });
+
+ function initialize(userProperties: UserProperties) {
+ if (!posthog) return;
+
+ register();
+
+ const id = posthog.get_distinct_id();
+
+ posthog.identify(id, userProperties);
+ }
+
+ function trackEvent(event: string, properties?: Record) {
+ if (!posthog) return;
+
+ posthog.capture(event, properties);
+ }
+
+ return { trackEvent, initialize };
+}
diff --git a/src/components/ProductAnalytics/utils.ts b/src/components/ProductAnalytics/utils.ts
new file mode 100644
index 00000000000..9ce6f3e08df
--- /dev/null
+++ b/src/components/ProductAnalytics/utils.ts
@@ -0,0 +1,2 @@
+export const extractEmailDomain = (email: string | undefined) =>
+ email?.split("@")[1] ?? "internal-no-domain";
diff --git a/src/components/RadioGroup/RadioGroup.tsx b/src/components/RadioGroup/RadioGroup.tsx
deleted file mode 100644
index fa841abed7d..00000000000
--- a/src/components/RadioGroup/RadioGroup.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import { RadioGroup as RadioGroupBase, RadioGroupRootProps } from "@saleor/macaw-ui-next";
-import React from "react";
-
-import { StopPropagation } from "../StopPropagation";
-
-const RadioGroupRoot = (props: RadioGroupRootProps) => {
- // StopProgation is used here to block onClick events from RadioGroup that cause throw error in datagrid
- // Datagrid listing for all on click event but RadioGroup emitated couple events at onced
- // Radix issue: https://github.com/radix-ui/primitives/issues/1982
- return (
-
-
-
- );
-};
-
-export const RadioGroup = Object.assign(RadioGroupRoot, {
- Item: RadioGroupBase.Item,
-});
diff --git a/src/components/RadioGroup/index.ts b/src/components/RadioGroup/index.ts
deleted file mode 100644
index da254de2986..00000000000
--- a/src/components/RadioGroup/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./RadioGroup";
diff --git a/src/components/RadioGroupField/RadioGroupField.tsx b/src/components/RadioGroupField/RadioGroupField.tsx
index 3c90b1f2c1e..67dd22dc930 100644
--- a/src/components/RadioGroupField/RadioGroupField.tsx
+++ b/src/components/RadioGroupField/RadioGroupField.tsx
@@ -11,6 +11,7 @@ import clsx from "clsx";
import React from "react";
import { FormattedMessage } from "react-intl";
+import { SimpleRadioGroupField } from "../SimpleRadioGroupField";
import { useStyles } from "./styles";
export interface RadioGroupFieldChoice {
@@ -34,6 +35,8 @@ interface RadioGroupFieldProps {
onChange: (event: React.ChangeEvent) => void;
}
+export const NewRadioGroupField = SimpleRadioGroupField;
+
export const RadioGroupField: React.FC = props => {
const {
alignTop,
diff --git a/src/components/RadioGroupField/styles.ts b/src/components/RadioGroupField/styles.ts
index 06a1a97c8b2..ab8adfb5919 100644
--- a/src/components/RadioGroupField/styles.ts
+++ b/src/components/RadioGroupField/styles.ts
@@ -25,6 +25,8 @@ export const useStyles = makeStyles(
},
label: {
marginTop: theme.spacing(0.2),
+ display: "flex",
+ flexDirection: "column",
},
root: {
"& $radioLabel": {
diff --git a/src/components/RichTextEditor/ReactEditorJS.tsx b/src/components/RichTextEditor/ReactEditorJS.tsx
index 9e35a63834a..0ae96d99807 100644
--- a/src/components/RichTextEditor/ReactEditorJS.tsx
+++ b/src/components/RichTextEditor/ReactEditorJS.tsx
@@ -32,6 +32,8 @@ class ClientEditorCore implements EditorCore {
}
public async save() {
+ await this._editorJS.isReady;
+
return this._editorJS.save();
}
diff --git a/src/components/RichTextEditor/RichTextEditor.tsx b/src/components/RichTextEditor/RichTextEditor.tsx
index d66d6154ea4..0f196a59268 100644
--- a/src/components/RichTextEditor/RichTextEditor.tsx
+++ b/src/components/RichTextEditor/RichTextEditor.tsx
@@ -7,7 +7,7 @@ import clsx from "clsx";
import React from "react";
import { tools } from "./consts";
-import { useHasRendered } from "./hooks";
+import { useHasRendered, useUpdateOnRerender } from "./hooks";
import { ReactEditorJS } from "./ReactEditorJS";
import useStyles from "./styles";
@@ -41,6 +41,7 @@ const RichTextEditor: React.FC = ({
}) => {
const classes = useStyles({});
const id = useId(defaultId);
+ const ref = React.useRef(null);
const [isFocused, setIsFocused] = React.useState(false);
const [hasValue, setHasValue] = React.useState(false);
const isTyped = Boolean(hasValue || isFocused);
@@ -54,12 +55,22 @@ const RichTextEditor: React.FC = ({
}
if (editorRef) {
+ ref.current = editor;
+
return (editorRef.current = editor);
}
}, []);
// We need to render FormControl first to get id from @reach/auto-id
const hasRendered = useHasRendered();
+ // EditorJS does not rerender when default value changes,
+ // so we need to manually update it
+ useUpdateOnRerender({
+ render: ref.current?.render.bind(ref.current),
+ defaultValue: props.defaultValue,
+ hasRendered,
+ });
+
return (
{
+ it("should call render when defaultValue changes after initial render", () => {
+ // Arrange
+ const mockRender = jest.fn();
+
+ const { rerender } = renderHook(
+ ({ render, defaultValue, hasRendered }) =>
+ useUpdateOnRerender({ render, defaultValue, hasRendered }),
+ {
+ initialProps: {
+ render: mockRender,
+ defaultValue: { blocks: [{ type: "paragraph", data: { text: "Initial" } }] },
+ hasRendered: true,
+ },
+ },
+ );
+
+ // Act
+ rerender({
+ render: mockRender,
+ defaultValue: { blocks: [{ type: "paragraph", data: { text: "Updated" } }] },
+ hasRendered: true,
+ });
+
+ // Assert
+ expect(mockRender).toHaveBeenCalledWith({
+ blocks: [{ type: "paragraph", data: { text: "Updated" } }],
+ });
+ });
+
+ it("should call render once when defaultValue change", () => {
+ // Arrange
+ const mockRender = jest.fn();
+
+ const { rerender } = renderHook(
+ ({ render, defaultValue, hasRendered }) =>
+ useUpdateOnRerender({ render, defaultValue, hasRendered }),
+ {
+ initialProps: {
+ render: mockRender,
+ defaultValue: { blocks: [{ type: "paragraph", data: { text: "Initial" } }] },
+ hasRendered: false,
+ },
+ },
+ );
+
+ // Act
+ rerender({
+ render: mockRender,
+ defaultValue: { blocks: [{ type: "paragraph", data: { text: "Initial" } }] },
+ hasRendered: true,
+ });
+ rerender({
+ render: mockRender,
+ defaultValue: { blocks: [{ type: "paragraph", data: { text: "Initial" } }] },
+ hasRendered: true,
+ });
+
+ // Assert
+ expect(mockRender).toHaveBeenCalledTimes(1);
+ });
+
+ it("should not call render if hasRendered is false", () => {
+ // Arrange
+ const mockRender = jest.fn();
+
+ const { rerender } = renderHook(
+ ({ render, defaultValue, hasRendered }) =>
+ useUpdateOnRerender({ render, defaultValue, hasRendered }),
+ {
+ initialProps: {
+ render: mockRender,
+ defaultValue: { blocks: [{ type: "paragraph", data: { text: "Initial" } }] },
+ hasRendered: false,
+ },
+ },
+ );
+
+ // Act
+ rerender({
+ render: mockRender,
+ defaultValue: { blocks: [{ type: "paragraph", data: { text: "Updated" } }] },
+ hasRendered: false,
+ });
+
+ // Assert
+ expect(mockRender).not.toHaveBeenCalled();
+ });
+});
diff --git a/src/components/RichTextEditor/hooks.ts b/src/components/RichTextEditor/hooks.ts
index f514771bac0..b044c5763fb 100644
--- a/src/components/RichTextEditor/hooks.ts
+++ b/src/components/RichTextEditor/hooks.ts
@@ -1,4 +1,6 @@
-import { useLayoutEffect, useState } from "react";
+import { EditorConfig } from "@editorjs/editorjs";
+import { EditorCore } from "@react-editor-js/core";
+import { useEffect, useLayoutEffect, useRef, useState } from "react";
export const useHasRendered = () => {
const [hasRendered, setHasRendereed] = useState(false);
@@ -9,3 +11,32 @@ export const useHasRendered = () => {
return hasRendered;
};
+
+export const useUpdateOnRerender = ({
+ render,
+ defaultValue,
+ hasRendered,
+}: {
+ render: EditorCore["render"] | undefined;
+ defaultValue: EditorConfig["data"];
+ hasRendered: boolean;
+}) => {
+ const prevDefaultValue = useRef(undefined);
+
+ useEffect(() => {
+ if (!hasRendered) {
+ return;
+ }
+
+ // Prevent call render when defaultValue doesn't change
+ if (JSON.stringify(defaultValue) === JSON.stringify(prevDefaultValue.current)) {
+ return;
+ }
+
+ prevDefaultValue.current = defaultValue;
+
+ render?.({
+ blocks: defaultValue?.blocks ?? [],
+ });
+ }, [defaultValue, hasRendered, render]);
+};
diff --git a/src/components/Router/index.tsx b/src/components/Router/index.tsx
new file mode 100644
index 00000000000..4299ec429da
--- /dev/null
+++ b/src/components/Router/index.tsx
@@ -0,0 +1,18 @@
+import { getAppMountUri } from "@dashboard/config";
+import * as Sentry from "@sentry/react";
+import { createBrowserHistory } from "history";
+import React from "react";
+import { RouterProps as BaseRouterProps } from "react-router";
+import { Route as BaseRoute, Router as BaseRouter } from "react-router-dom";
+
+type RouterProps = Omit & { children: React.ReactNode };
+
+export const history = createBrowserHistory({
+ basename: getAppMountUri(),
+});
+
+export const Route = Sentry.withSentryRouting(BaseRoute);
+
+export const Router = (props: RouterProps) => {
+ return {props.children} ;
+};
diff --git a/src/components/Router/useRouteChange.ts b/src/components/Router/useRouteChange.ts
new file mode 100644
index 00000000000..ccf8d17c36d
--- /dev/null
+++ b/src/components/Router/useRouteChange.ts
@@ -0,0 +1,28 @@
+import { Location, UnregisterCallback } from "history";
+import { useRef } from "react";
+import useRouter from "use-react-router";
+
+const compareLocations = (a: Location, b: Location) => {
+ return a.pathname === b.pathname && a.search === b.search;
+};
+
+export const useRouteChange = (onChange: (location: Location) => void) => {
+ const router = useRouter();
+ const location = useRef(router.history.location);
+ const listener = useRef(null);
+
+ const register = () => {
+ if (listener.current) return;
+
+ onChange(router.history.location);
+
+ listener.current = router.history.listen(incomingLocation => {
+ if (location.current && compareLocations(location.current, incomingLocation)) return;
+
+ onChange(incomingLocation);
+ location.current = incomingLocation;
+ });
+ };
+
+ return { register };
+};
diff --git a/src/components/SaveFilterTabDialog/SaveFilterTabDialog.tsx b/src/components/SaveFilterTabDialog/SaveFilterTabDialog.tsx
index 017be3867c6..4fa000981f1 100644
--- a/src/components/SaveFilterTabDialog/SaveFilterTabDialog.tsx
+++ b/src/components/SaveFilterTabDialog/SaveFilterTabDialog.tsx
@@ -1,7 +1,7 @@
-// @ts-strict-ignore
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
+import { DashboardModal } from "@dashboard/components/Modal";
import { buttonMessages } from "@dashboard/intl";
-import { Dialog, DialogActions, DialogContent, DialogTitle, TextField } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -32,7 +32,7 @@ const SaveFilterTabDialog: React.FC = ({
}) => {
const intl = useIntl();
const [errors, setErrors] = React.useState(false);
- const handleErrors = data => {
+ const handleErrors = (data: SaveFilterTabDialogFormData) => {
if (data.name.trim().length) {
onSubmit(data);
setErrors(false);
@@ -42,18 +42,19 @@ const SaveFilterTabDialog: React.FC = ({
};
return (
-
-
-
-
-
- {({ change, data, submit }) => (
- <>
-
+
+
+
+ {({ change, data, submit }) => (
+
+
+
+
+
= ({
data-test-id="preset-name-text-field"
helperText={errors ? "This field is required" : null}
/>
-
-
-
-
-
-
-
-
-
- >
- )}
-
-
+
+
+
+
+
+
+
+
+
+
+ )}
+
+
+
);
};
diff --git a/src/components/Select/Select.tsx b/src/components/Select/Select.tsx
new file mode 100644
index 00000000000..304aaa5e410
--- /dev/null
+++ b/src/components/Select/Select.tsx
@@ -0,0 +1,27 @@
+import { ChangeEvent } from "@dashboard/hooks/useForm";
+import {
+ Option,
+ Select as SelectComponent,
+ SelectProps as SelectComponentProps,
+} from "@saleor/macaw-ui-next";
+import React from "react";
+
+export interface SelectProps extends Omit, "onChange"> {
+ onChange: (event: ChangeEvent) => void;
+}
+
+export const Select = ({
+ onChange,
+ ...props
+}: SelectProps) => {
+ const handleOnChange = (value: V) => {
+ onChange({
+ target: {
+ value: typeof value === "string" ? value : (value as Option)?.value,
+ name: props.name ?? "",
+ },
+ });
+ };
+
+ return ;
+};
diff --git a/src/components/Select/index.ts b/src/components/Select/index.ts
new file mode 100644
index 00000000000..b6e8a07c267
--- /dev/null
+++ b/src/components/Select/index.ts
@@ -0,0 +1 @@
+export * from "./Select";
diff --git a/src/components/Shop/index.tsx b/src/components/Shop/index.tsx
index 712727f0bcd..56d3f7c07d5 100644
--- a/src/components/Shop/index.tsx
+++ b/src/components/Shop/index.tsx
@@ -5,19 +5,35 @@ import favicon32 from "@assets/favicons/favicon-32x32.png";
import safariPinnedTab from "@assets/favicons/safari-pinned-tab.svg";
import { useUser } from "@dashboard/auth";
import { ShopInfoQuery, useShopInfoQuery } from "@dashboard/graphql";
-import React from "react";
+import React, { useEffect } from "react";
import Helmet from "react-helmet";
+import { useAnalytics } from "../ProductAnalytics/useAnalytics";
+import { extractEmailDomain } from "../ProductAnalytics/utils";
+
type ShopContext = ShopInfoQuery["shop"];
export const ShopContext = React.createContext(undefined);
export const ShopProvider: React.FC = ({ children }) => {
const { authenticated, user } = useUser();
+ const analytics = useAnalytics();
const { data } = useShopInfoQuery({
skip: !authenticated || !user,
});
+ useEffect(() => {
+ if (data) {
+ const { shop } = data;
+
+ analytics.initialize({
+ domain: shop.domain.host,
+ email_domain: extractEmailDomain(user.email),
+ });
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [data]);
+
return (
<>
diff --git a/src/components/Sidebar/Sidebar.tsx b/src/components/Sidebar/Sidebar.tsx
index b91af9d19fc..ae19d8920ea 100644
--- a/src/components/Sidebar/Sidebar.tsx
+++ b/src/components/Sidebar/Sidebar.tsx
@@ -5,7 +5,11 @@ import { SidebarContent } from "./Content";
export const Sidebar = () => (
<>
-
+
@@ -25,6 +29,7 @@ export const Sidebar = () => (
backgroundColor="default2"
data-test-id="sidebar-drawer-content"
paddingTop={0}
+ __width="260px"
>
diff --git a/src/components/Sidebar/menu/hooks/useEnvLink.test.ts b/src/components/Sidebar/menu/hooks/useEnvLink.test.ts
index d17f085da8b..69da735e9a0 100644
--- a/src/components/Sidebar/menu/hooks/useEnvLink.test.ts
+++ b/src/components/Sidebar/menu/hooks/useEnvLink.test.ts
@@ -21,7 +21,7 @@ describe("useEnvLink", () => {
it("should return link to the cloud environment on staging", () => {
// Arrange
const stagingHref =
- "https://staging-cloud.saleor.io/env/test.staging.com?utm_source=dashboard&utm_content=sidebar_button";
+ "https://cloud.staging.saleor.io/env/test.staging.com?utm_source=dashboard&utm_content=sidebar_button";
delete (window as { location?: unknown }).location;
// @ts-expect-error error
diff --git a/src/components/Sidebar/menu/hooks/useEnvLink.ts b/src/components/Sidebar/menu/hooks/useEnvLink.ts
index 81e8bebfe0e..dcd0c816150 100644
--- a/src/components/Sidebar/menu/hooks/useEnvLink.ts
+++ b/src/components/Sidebar/menu/hooks/useEnvLink.ts
@@ -1,6 +1,9 @@
const UTM_PARAMS = "?utm_source=dashboard&utm_content=sidebar_button";
+
+// TODO: Refactor it, get rid of hardcoded links
const stagingLink = (hostname: string) =>
- `https://staging-cloud.saleor.io/env/${hostname}${UTM_PARAMS}`;
+ `https://cloud.staging.saleor.io/env/${hostname}${UTM_PARAMS}`;
+
const prodLink = (hostname: string) => `https://cloud.saleor.io/env/${hostname}${UTM_PARAMS}`;
export const useEnvLink = () => {
diff --git a/src/components/SimpleRadioGroupField.test.tsx b/src/components/SimpleRadioGroupField.test.tsx
new file mode 100644
index 00000000000..51081ff4a00
--- /dev/null
+++ b/src/components/SimpleRadioGroupField.test.tsx
@@ -0,0 +1,98 @@
+import "@testing-library/jest-dom/extend-expect";
+
+import { fireEvent, render, screen } from "@testing-library/react";
+import React from "react";
+
+import { SimpleRadioGroupField } from "./SimpleRadioGroupField";
+
+const choices = [
+ { label: "Choice 1", value: "choice1" },
+ { label: "Choice 2", value: "choice2", disabled: true },
+ { label: "Choice 3", value: "choice3" },
+];
+
+describe("SimpleRadioGroupField", () => {
+ it("renders radio fields correctly", () => {
+ // Arrange & Act
+ render(
+ ,
+ );
+
+ // Assert
+ expect(screen.getByText("Choice 1")).toBeInTheDocument();
+ expect(screen.getByText("Choice 2")).toBeInTheDocument();
+ expect(screen.getByText("Choice 3")).toBeInTheDocument();
+ });
+
+ it("calls onChange when a radio button is clicked", () => {
+ // Arrange
+ const handleChange = jest.fn();
+
+ render(
+ ,
+ );
+
+ // Act
+ const radioButton = screen.getByLabelText("Choice 3");
+
+ fireEvent.click(radioButton);
+
+ // Assert
+ expect(handleChange).toHaveBeenCalledWith({
+ target: { value: "choice3", name: "testRadioGroup" },
+ });
+ });
+
+ it("doesn't call onChange when `disabled` item is clicked", () => {
+ // Arrange
+ const handleChange = jest.fn();
+
+ render(
+ ,
+ );
+
+ // Act
+ const radioButton = screen.getByLabelText("Choice 2");
+
+ fireEvent.click(radioButton);
+
+ // Assert
+ expect(handleChange).not.toHaveBeenCalledWith({
+ target: { value: "choice2", name: "testRadioGroup" },
+ });
+ });
+
+ it("displays the error message when provided", () => {
+ // Arrange & Act
+ const errorMessage = "Error message";
+
+ render(
+ ,
+ );
+
+ // Assert
+ expect(screen.getByText(errorMessage)).toBeInTheDocument();
+ });
+});
diff --git a/src/components/SimpleRadioGroupField.tsx b/src/components/SimpleRadioGroupField.tsx
new file mode 100644
index 00000000000..70c9eaa7a2c
--- /dev/null
+++ b/src/components/SimpleRadioGroupField.tsx
@@ -0,0 +1,64 @@
+import { ChangeEvent } from "@dashboard/hooks/useForm";
+import { RadioGroup, RadioGroupRootProps, Text } from "@saleor/macaw-ui-next";
+import React from "react";
+
+type RadioGroupFieldChoice = {
+ label: string | React.ReactNode;
+ value: string;
+ disabled?: boolean;
+};
+
+interface SimpleRadioGroupFieldProps
+ extends Omit {
+ name: string;
+ onChange: (event: ChangeEvent) => void;
+ choices: RadioGroupFieldChoice[];
+ size?: RadioGroupRootProps["size"];
+ errorMessage?: string;
+}
+
+// SimpleRadioGroupField is a migration of RadioGroupField "@dashboard/components/RadioGroupField" using Macaw UI
+// While migrating to this component note that it doesn't have a label, hint or 'no choices' message.
+export const SimpleRadioGroupField: React.FC = ({
+ name,
+ value,
+ error,
+ onChange,
+ choices,
+ size = "large",
+ errorMessage,
+ ...props
+}) => {
+ return (
+ <>
+ onChange({ target: { value, name } })}
+ {...props}
+ >
+ {choices.map(({ label, value, disabled }) => (
+
+
+ {label}
+
+
+ ))}
+
+
+ {errorMessage && {errorMessage} }
+ >
+ );
+};
diff --git a/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectField.tsx b/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectField.tsx
deleted file mode 100644
index 06512d8f6e6..00000000000
--- a/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectField.tsx
+++ /dev/null
@@ -1,303 +0,0 @@
-// @ts-strict-ignore
-import { FetchMoreProps } from "@dashboard/types";
-import {
- FormHelperTextProps,
- InputBase,
- OutlinedInputProps,
- Popper,
- PopperPlacementType,
- TextField,
-} from "@material-ui/core";
-import { InputProps } from "@material-ui/core/Input";
-import { ChevronIcon } from "@saleor/macaw-ui";
-import clsx from "clsx";
-import Downshift from "downshift";
-import Fuse from "fuse.js";
-import React from "react";
-
-import Debounce, { DebounceProps } from "../Debounce";
-import SingleAutocompleteSelectFieldContent, {
- SingleAutocompleteActionType,
- SingleAutocompleteChoiceType,
-} from "./SingleAutocompleteSelectFieldContent";
-import { useStyles } from "./styles";
-
-export interface SingleAutocompleteSelectFieldProps extends Partial {
- add?: SingleAutocompleteActionType;
- className?: string;
- error?: boolean;
- name: string;
- displayValue: string;
- emptyOption?: boolean;
- choices: Array>;
- value: string;
- disabled?: boolean;
- placeholder?: string;
- allowCustomValues?: boolean;
- helperText?: string;
- label?: string;
- InputProps?: InputProps;
- autocomplete?: string;
- fetchChoices?: (value: string) => void;
- onChange: (event: React.ChangeEvent) => void;
- fetchOnFocus?: boolean;
- FormHelperTextProps?: FormHelperTextProps & {
- "data-test-id": string;
- };
- nakedInput?: boolean;
- onBlur?: () => void;
- popperPlacement?: PopperPlacementType;
- id?: string;
-}
-
-const DebounceAutocomplete: React.ComponentType> = Debounce;
-const SingleAutocompleteSelectFieldComponent: React.FC<
- SingleAutocompleteSelectFieldProps
-> = props => {
- const {
- add,
- allowCustomValues,
- className,
- choices,
- disabled,
- displayValue,
- emptyOption,
- error,
- hasMore,
- helperText,
- label,
- loading,
- name,
- autocomplete,
- placeholder,
- value,
- InputProps,
- fetchChoices,
- onChange,
- onFetchMore,
- fetchOnFocus,
- FormHelperTextProps,
- nakedInput = false,
- onBlur,
- popperPlacement = "bottom-end",
- id,
- ...rest
- } = props;
- const classes = useStyles(props);
- const anchor = React.useRef(null);
- const input = React.useRef(null);
- const handleChange = (item: string) => {
- onChange({
- target: {
- name,
- value: item,
- },
- } as any);
- };
-
- return (
-
- {fetchChoicesDebounced => (
- displayValue || ""}
- onInputValueChange={value => fetchChoicesDebounced(value)}
- onSelect={handleChange}
- selectedItem={value || ""}
- // this is to prevent unwanted state updates when the dropdown is closed with an empty value,
- // which downshift interprets as the value being updated with an empty string, causing side-effects
- stateReducer={(_, changes) => {
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-boolean-literal-compare
- if (changes.isOpen === false) {
- delete changes.inputValue;
- }
-
- return changes;
- }}
- >
- {({
- getInputProps,
- getItemProps,
- isOpen,
- inputValue,
- selectedItem,
- toggleMenu,
- closeMenu,
- highlightedIndex,
- reset,
- }) => {
- const isCustomValueSelected =
- choices && selectedItem
- ? choices.filter(c => c.value === selectedItem).length === 0
- : false;
- const choiceFromInputValue = choices.find(
- ({ value: choiceId }) => choiceId === inputValue,
- );
- const isValueInValues = !!choiceFromInputValue;
- const isValueInLabels = !!choices.find(choice => choice.label === inputValue);
- const ensureProperValues = (alwaysCheck = false) => {
- if ((allowCustomValues || isValueInLabels) && !alwaysCheck) {
- return;
- }
-
- if (isValueInValues && !isValueInLabels) {
- reset({ inputValue: choiceFromInputValue.value });
-
- return;
- }
-
- reset({ inputValue: displayValue });
- };
- const displayCustomValue = !!(
- inputValue &&
- inputValue.length > 0 &&
- allowCustomValues &&
- !isValueInLabels
- );
- const handleBlur = () => {
- ensureProperValues(true);
-
- if (onBlur) {
- onBlur();
- }
-
- closeMenu();
- };
- const handleFocus = () => {
- if (fetchOnFocus) {
- fetchChoices(inputValue);
- }
-
- if (input.current) {
- input.current.select();
- }
- };
- const handleToggleMenu = () => {
- if (disabled) {
- return;
- }
-
- toggleMenu();
- };
- const TextFieldComponent = nakedInput ? InputBase : TextField;
- const commonInputProps = {
- ...InputProps,
- endAdornment: (
- {
- handleToggleMenu();
- handleFocus();
- }}
- className={clsx(classes.adornment, {
- [classes.adornmentRotate]: isOpen,
- })}
- >
-
-
- ),
- error,
- id: undefined,
- onFocus: handleFocus,
- ref: anchor,
- };
- const nakedInputProps = nakedInput
- ? {
- "aria-label": "naked",
- ...commonInputProps,
- autoFocus: true,
- className: classes.nakedInput,
- onBlur: handleBlur,
- }
- : {};
-
- return (
-
-
- {isOpen && (!!inputValue || !!choices.length) && (
-
- {
- add.onClick();
- closeMenu();
- },
- }
- }
- choices={choices}
- displayCustomValue={displayCustomValue}
- emptyOption={emptyOption}
- getItemProps={getItemProps}
- hasMore={hasMore}
- highlightedIndex={highlightedIndex}
- loading={loading}
- inputValue={inputValue}
- isCustomValueSelected={isCustomValueSelected}
- selectedItem={selectedItem}
- onFetchMore={onFetchMore}
- />
-
- )}
-
- );
- }}
-
- )}
-
- );
-};
-const SingleAutocompleteSelectField: React.FC = ({
- choices,
- fetchChoices,
- ...rest
-}) => {
- const [query, setQuery] = React.useState("");
-
- if (fetchChoices) {
- return (
-
- );
- }
-
- const fuse = new Fuse(choices, { keys: ["label"] });
-
- return (
- setQuery(q || "")}
- choices={query !== "" ? fuse.search(query).map(v => v.item) : choices}
- {...rest}
- />
- );
-};
-
-export default SingleAutocompleteSelectField;
diff --git a/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectFieldContent.tsx b/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectFieldContent.tsx
index eca56a8ad17..e69de29bb2d 100644
--- a/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectFieldContent.tsx
+++ b/src/components/SingleAutocompleteSelectField/SingleAutocompleteSelectFieldContent.tsx
@@ -1,313 +0,0 @@
-// @ts-strict-ignore
-import chevronDown from "@assets/images/ChevronDown.svg";
-import useElementScroll, { isScrolledToBottom } from "@dashboard/hooks/useElementScroll";
-import { FetchMoreProps } from "@dashboard/types";
-import { CircularProgress, MenuItem, Paper, Typography } from "@material-ui/core";
-import Add from "@material-ui/icons/Add";
-import { makeStyles } from "@saleor/macaw-ui";
-import clsx from "clsx";
-import { GetItemPropsOptions } from "downshift";
-import React, { ReactElement } from "react";
-import SVG from "react-inlinesvg";
-import { FormattedMessage } from "react-intl";
-
-import Hr from "../Hr";
-
-const menuItemHeight = 46;
-const maxMenuItems = 5;
-const offset = 24;
-
-export type ChoiceValue = string;
-export interface SingleAutocompleteChoiceType {
- label: L;
- value: V;
-}
-export interface SingleAutocompleteActionType {
- label: string;
- onClick: () => void;
-}
-export interface SingleAutocompleteSelectFieldContentProps extends Partial {
- add?: SingleAutocompleteActionType;
- choices: Array>;
- displayCustomValue: boolean;
- emptyOption: boolean;
- getItemProps: (options: GetItemPropsOptions) => any;
- highlightedIndex: number;
- inputValue: string;
- isCustomValueSelected: boolean;
- selectedItem: any;
- style?: React.CSSProperties;
-}
-
-const useStyles = makeStyles(
- theme => ({
- add: {
- background: theme.palette.background.default,
- border: `1px solid ${theme.palette.divider}`,
- borderRadius: "100%",
- height: 24,
- marginRight: theme.spacing(),
- width: 24,
- },
- arrowContainer: {
- position: "relative",
- },
- arrowInnerContainer: {
- alignItems: "center",
- background: theme.palette.type === "light" ? theme.palette.grey[50] : theme.palette.grey[900],
- bottom: 0,
- color: theme.palette.grey[500],
- display: "flex",
- height: 30,
- justifyContent: "center",
- opacity: 1,
- position: "absolute",
- transition: theme.transitions.duration.short + "ms",
- width: "100%",
- },
- content: {
- maxHeight: `calc(${menuItemHeight * maxMenuItems}px + ${theme.spacing(2)})`,
- overflow: "scroll",
- padding: 8,
- },
- hide: {
- opacity: 0,
- zIndex: -1,
- },
- hr: {
- margin: theme.spacing(1, 0),
- },
- menuItem: {
- height: "auto",
- whiteSpace: "normal",
- '&[aria-selected="true"]': {
- backgroundColor: theme.palette.background.default,
- },
- },
- progress: {},
- progressContainer: {
- display: "flex",
- justifyContent: "center",
- padding: theme.spacing(1, 0),
- },
- root: {
- borderBottomLeftRadius: 8,
- borderBottomRightRadius: 8,
- margin: theme.spacing(1, 0),
- overflow: "hidden",
- zIndex: 22,
- },
- }),
- {
- name: "SingleAutocompleteSelectFieldContent",
- },
-);
-
-function getChoiceIndex(index: number, emptyValue: boolean, customValue: boolean, add: boolean) {
- let choiceIndex = index;
-
- if (emptyValue) {
- choiceIndex += 1;
- }
-
- if (customValue || add) {
- choiceIndex += 2;
- }
-
- return choiceIndex;
-}
-
-const sliceSize = 20;
-const SingleAutocompleteSelectFieldContent: React.FC<
- SingleAutocompleteSelectFieldContentProps
-> = props => {
- const {
- add,
- choices,
- displayCustomValue,
- emptyOption,
- getItemProps,
- hasMore,
- loading,
- inputValue,
- isCustomValueSelected,
- selectedItem,
- onFetchMore,
- style,
- } = props;
-
- if (!!add && !!displayCustomValue) {
- throw new Error("Add and custom value cannot be displayed simultaneously");
- }
-
- const classes = useStyles(props);
- const anchor = React.useRef();
- const scrollPosition = useElementScroll(anchor);
- const [calledForMore, setCalledForMore] = React.useState(false);
- const [slice, setSlice] = React.useState(onFetchMore ? 10000 : sliceSize);
- const [initialized, setInitialized] = React.useState(false);
- const scrolledToBottom = isScrolledToBottom(anchor, scrollPosition, offset);
-
- React.useEffect(() => {
- if (!calledForMore && onFetchMore && scrolledToBottom && hasMore) {
- onFetchMore();
- setCalledForMore(true);
- } else if (scrolledToBottom && !onFetchMore) {
- setSlice(slice => slice + sliceSize);
- }
- }, [scrolledToBottom]);
- React.useEffect(() => {
- if (!onFetchMore) {
- setSlice(sliceSize);
- }
- }, [choices?.length]);
- React.useEffect(() => {
- if (anchor.current?.scrollTo && !initialized) {
- anchor.current.scrollTo({
- top: 0,
- });
- setInitialized(true);
- }
- }, [initialized]);
- React.useEffect(() => {
- setInitialized(false);
- }, [inputValue]);
- React.useEffect(() => {
- if (calledForMore && !loading) {
- setCalledForMore(false);
- }
- }, [loading]);
-
- const emptyOptionProps = getItemProps({
- item: "",
- });
- const choicesToDisplay = choices.slice(0, slice);
-
- return (
-
-
- {choices.length > 0 || displayCustomValue ? (
- <>
- {emptyOption && (
-
-
-
-
-
- )}
- {add && (
-
-
- {add.label}
-
- )}
- {displayCustomValue && (
-
-
-
- )}
- {choices.length > 0 && (!!add || displayCustomValue) &&
}
- {choicesToDisplay.map((suggestion, index) => {
- const choiceIndex = getChoiceIndex(index, emptyOption, displayCustomValue, !!add);
- const key = React.isValidElement(suggestion.label)
- ? `${index}${suggestion.value}${(suggestion as unknown as ReactElement).props}`
- : JSON.stringify(suggestion);
-
- return (
-
- {suggestion.label}
-
- );
- })}
- {hasMore && (
- <>
-
-
-
-
- >
- )}
- >
- ) : (
-
-
-
- )}
-
- {choices.length > maxMenuItems && (
-
- )}
-
- );
-};
-
-SingleAutocompleteSelectFieldContent.displayName = "SingleAutocompleteSelectFieldContent";
-export default SingleAutocompleteSelectFieldContent;
diff --git a/src/components/SingleAutocompleteSelectField/index.ts b/src/components/SingleAutocompleteSelectField/index.ts
deleted file mode 100644
index 56328d1d5c1..00000000000
--- a/src/components/SingleAutocompleteSelectField/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export { default } from "./SingleAutocompleteSelectField";
-export * from "./SingleAutocompleteSelectField";
-export * from "./SingleAutocompleteSelectFieldContent";
diff --git a/src/components/SingleAutocompleteSelectField/styles.ts b/src/components/SingleAutocompleteSelectField/styles.ts
deleted file mode 100644
index 20c7866c186..00000000000
--- a/src/components/SingleAutocompleteSelectField/styles.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { makeStyles } from "@saleor/macaw-ui";
-
-export const useStyles = makeStyles(
- theme => ({
- container: {
- flexGrow: 1,
- position: "relative",
- },
- nakedInput: {
- padding: theme.spacing(2, 0),
- },
- adornment: {
- color: theme.palette.saleor.main[3],
- cursor: "pointer",
- userSelect: "none",
- "& svg": {
- transition: theme.transitions.duration.shorter + "ms",
- },
- },
- adornmentRotate: {
- "& svg": {
- transform: "rotate(180deg)",
- },
- },
- }),
- { name: "SingleAutocompleteSelectField" },
-);
diff --git a/src/components/SingleSelectField/SingleSelectField.tsx b/src/components/SingleSelectField/SingleSelectField.tsx
deleted file mode 100644
index 600081b3919..00000000000
--- a/src/components/SingleSelectField/SingleSelectField.tsx
+++ /dev/null
@@ -1,149 +0,0 @@
-// @ts-strict-ignore
-import {
- FormControl,
- FormHelperText,
- InputLabel,
- MenuItem,
- OutlinedInput,
- OutlinedInputProps,
- Select,
-} from "@material-ui/core";
-import { SelectProps } from "@material-ui/core/Select";
-import { makeStyles } from "@saleor/macaw-ui";
-import clsx from "clsx";
-import React from "react";
-import { FormattedMessage } from "react-intl";
-
-import { singleSelectFieldItemHeight } from "./consts";
-
-const useStyles = makeStyles(
- theme => ({
- formControl: {
- "& label": {
- top: "-3px",
- },
- width: "100%",
- },
- label: {
- zIndex: 3,
- },
- noLabel: {
- padding: theme.spacing(2, 1.5),
- },
- paper: {
- maxHeight: `calc(${singleSelectFieldItemHeight}px * 10 + ${singleSelectFieldItemHeight}px * 0.5)`,
- },
- disabledMenuItem: {
- pointerEvents: "none",
- },
- }),
- { name: "SingleSelectField" },
-);
-
-export interface Choice {
- value: T;
- label: L;
- disabled?: boolean;
-}
-
-export type Choices = Choice[];
-interface SingleSelectFieldProps {
- testId?: string;
- choices: Choices;
- className?: string;
- disabled?: boolean;
- error?: boolean;
- hint?: string | React.ReactNode;
- label?: string | React.ReactNode;
- name?: string;
- selectProps?: SelectProps;
- placeholder?: string;
- value?: string;
- InputProps?: OutlinedInputProps;
- onChange: (event: any) => any;
-}
-
-export const SingleSelectField: React.FC = props => {
- const {
- className,
- disabled,
- error,
- label,
- choices,
- value,
- onChange,
- name,
- hint,
- selectProps,
- placeholder,
- InputProps,
- testId,
- } = props;
- const classes = useStyles(props);
- const choicesByKey: Record =
- choices === undefined
- ? {}
- : choices.reduce((prev, curr) => {
- prev[curr.value] = curr.label;
-
- return prev;
- }, {});
-
- return (
-
-
- {label}
-
-
- choiceValue ? choicesByKey[choiceValue.toString()] : placeholder
- }
- value={value || ""}
- onChange={onChange}
- input={
-
- }
- {...selectProps}
- MenuProps={{
- classes: {
- paper: classes.paper,
- },
- }}
- >
- {choices.length > 0 ? (
- choices.map(choice => (
-
- {choice.label}
-
- ))
- ) : (
-
-
-
- )}
-
- {hint && {hint} }
-
- );
-};
-SingleSelectField.displayName = "SingleSelectField";
-export default SingleSelectField;
diff --git a/src/components/SingleSelectField/consts.ts b/src/components/SingleSelectField/consts.ts
deleted file mode 100644
index 971a8267ddc..00000000000
--- a/src/components/SingleSelectField/consts.ts
+++ /dev/null
@@ -1 +0,0 @@
-export const singleSelectFieldItemHeight = "36";
diff --git a/src/components/SingleSelectField/index.ts b/src/components/SingleSelectField/index.ts
deleted file mode 100644
index c8af8bf3f43..00000000000
--- a/src/components/SingleSelectField/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from "./SingleSelectField";
-export * from "./SingleSelectField";
diff --git a/src/components/Skeleton.tsx b/src/components/Skeleton.tsx
deleted file mode 100644
index 56d1b5e6bf8..00000000000
--- a/src/components/Skeleton.tsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { makeStyles } from "@saleor/macaw-ui";
-import clsx from "clsx";
-import React from "react";
-
-const useStyles = makeStyles(
- theme => ({
- "@keyframes skeleton-animation": {
- "0%": {
- opacity: 0.6,
- },
- "100%": {
- opacity: 1,
- },
- },
- primary: {
- "&$skeleton": {
- background: theme.palette.primary.main,
- },
- },
- skeleton: {
- animation: "skeleton-animation .75s linear infinite forwards alternate",
- background: theme.palette.background.default,
- borderRadius: 4,
- display: "block",
- height: "0.8em",
- margin: "0.2em 0",
- },
- }),
- { name: "Skeleton" },
-);
-
-interface SkeletonProps {
- className?: string;
- primary?: boolean;
- style?: React.CSSProperties;
-}
-
-const Skeleton: React.FC = props => {
- const { className, primary, style } = props;
- const classes = useStyles(props);
-
- return (
-
-
-
- );
-};
-
-Skeleton.displayName = "Skeleton";
-export default Skeleton;
diff --git a/src/components/SortableChip/SortableChip.tsx b/src/components/SortableChip/SortableChip.tsx
index b62318c06d4..8d74f30e12d 100644
--- a/src/components/SortableChip/SortableChip.tsx
+++ b/src/components/SortableChip/SortableChip.tsx
@@ -1,6 +1,6 @@
-import { Typography } from "@material-ui/core";
import CloseIcon from "@material-ui/icons/Close";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
import { SortableElement, SortableElementProps } from "react-sortable-hoc";
@@ -70,7 +70,7 @@ const SortableChip = SortableElement((props: SortableChipProps) => {
})}
data-test-id="button-drag-handle"
/>
- {label}
+ {label}
{onClose && (
({
const activeIndex = clonedItems.findIndex(({ id }) => id === activeId);
const sortedItems = arrayMove(clonedItems, activeIndex, overIndex);
const previousItem = sortedItems[overIndex - 1];
+ const nextItem = sortedItems[overIndex + 1];
let announcement;
const movedVerb = eventName === "onDragEnd" ? "dropped" : "moved";
const nestedVerb = eventName === "onDragEnd" ? "dropped" : "nested";
- if (!previousItem) {
- const nextItem = sortedItems[overIndex + 1];
-
+ if (!previousItem && nextItem) {
announcement = `${activeId} was ${movedVerb} before ${nextItem.id}.`;
- } else if (projected.depth > previousItem.depth) {
+ } else if (projected?.depth > previousItem?.depth) {
announcement = `${activeId} was ${nestedVerb} under ${previousItem.id}.`;
} else {
const previousSibling = findPreviousSibling(projected, previousItem, sortedItems);
diff --git a/src/components/Tab/Tab.tsx b/src/components/Tab/Tab.tsx
index 5440b11235c..f3e70c04a8e 100644
--- a/src/components/Tab/Tab.tsx
+++ b/src/components/Tab/Tab.tsx
@@ -1,6 +1,6 @@
-import { Typography } from "@material-ui/core";
import { alpha } from "@material-ui/core/styles";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
@@ -47,8 +47,8 @@ export function Tab(value: T) {
const classes = useStyles(props);
return (
- (value: T) {
onClick={() => changeTab(value)}
>
{children}
-
+
);
};
diff --git a/src/components/TableCellAvatar/AvatarImage.tsx b/src/components/TableCellAvatar/AvatarImage.tsx
index 21e6039e03d..94b27701597 100644
--- a/src/components/TableCellAvatar/AvatarImage.tsx
+++ b/src/components/TableCellAvatar/AvatarImage.tsx
@@ -1,5 +1,6 @@
-import { Avatar as MuiAvatar, Typography } from "@material-ui/core";
+import { Avatar as MuiAvatar } from "@material-ui/core";
import { ImageIcon } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
@@ -17,7 +18,9 @@ const AvatarImage: React.FC = ({ initials, thumbnail, avatarPr
if (!thumbnail && initials) {
return (
- {initials}
+
+ {initials}
+
);
}
diff --git a/src/components/TableHead/TableHead.tsx b/src/components/TableHead/TableHead.tsx
index 9d65eca00c0..081285e653c 100644
--- a/src/components/TableHead/TableHead.tsx
+++ b/src/components/TableHead/TableHead.tsx
@@ -1,8 +1,9 @@
// @ts-strict-ignore
import TableRowLink from "@dashboard/components/TableRowLink";
-import { TableCell, TableHead as MuiTableHead, Typography } from "@material-ui/core";
+import { TableCell, TableHead as MuiTableHead } from "@material-ui/core";
import { TableHeadProps as MuiTableHeadProps } from "@material-ui/core/TableHead";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
import { FormattedMessage } from "react-intl";
@@ -107,7 +108,7 @@ const TableHead: React.FC = props => {
>
{selected && (
-
+
= props => {
number: selected,
}}
/>
-
+
)}
{toolbar && (
diff --git a/src/components/TableRowLink/TableRowLink.tsx b/src/components/TableRowLink/TableRowLink.tsx
index ce7cf799009..3eed8ca40a7 100644
--- a/src/components/TableRowLink/TableRowLink.tsx
+++ b/src/components/TableRowLink/TableRowLink.tsx
@@ -3,13 +3,15 @@ import { TableRow, TableRowTypeMap } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
import clsx from "clsx";
import React, { forwardRef } from "react";
-import { Link } from "react-router-dom";
+import { Link, LinkProps } from "react-router-dom";
type MaterialTableRowPropsType = TableRowTypeMap["props"];
+type LocationDescriptor = LinkProps["to"];
+
export interface TableRowLinkProps extends MaterialTableRowPropsType {
children: React.ReactNode;
- href?: string;
+ href?: string | LocationDescriptor;
className?: string;
linkClassName?: string;
onClick?: () => void;
@@ -28,7 +30,7 @@ const TableRowLink = forwardRef
((props,
const { href, children, linkClassName, onClick, ...restProps } = props;
const classes = useStyles();
- if (!href || isExternalURL(href)) {
+ if (!href || (typeof href === "string" && isExternalURL(href))) {
return (
{children}
diff --git a/src/components/TextFieldWithChoice/TextFieldWithChoice.tsx b/src/components/TextFieldWithChoice/TextFieldWithChoice.tsx
index df1d9a87b7e..8f81426289b 100644
--- a/src/components/TextFieldWithChoice/TextFieldWithChoice.tsx
+++ b/src/components/TextFieldWithChoice/TextFieldWithChoice.tsx
@@ -7,11 +7,11 @@ import {
Paper,
Popper,
TextField,
- Typography,
} from "@material-ui/core";
import { TextFieldProps } from "@material-ui/core/TextField";
import DropdownIcon from "@material-ui/icons/ArrowDropDown";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import MenuToggle from "../MenuToggle";
@@ -71,9 +71,9 @@ const TextFieldWithChoice: React.FC = props => {
ref={anchor}
onClick={!menuOpen ? openMenu : undefined}
>
-
+
{ChoiceProps.label}
-
+
{ChoiceProps.values ? : null}
= ({
change,
choices,
loading,
- containerClassName,
textFieldProps,
selectFieldProps,
helperText,
isError,
}) => {
- const classes = useStyles();
const {
name: textFieldName,
value: textFieldValue,
@@ -45,11 +37,7 @@ const TextWithSelectField: React.FC = ({
type: textFieldType,
minValue: textFieldMinValue,
} = textFieldProps;
- const {
- name: selectFieldName,
- value: selectFieldValue,
- className: selectFieldClassName,
- } = selectFieldProps;
+ const { name: selectFieldName, value: selectFieldValue } = selectFieldProps;
const handleTextChange = (event: ChangeEvent) => {
const { value } = event.target;
const otherTarget = {
@@ -68,22 +56,18 @@ const TextWithSelectField: React.FC = ({
};
return (
-
-
+
@@ -92,15 +76,14 @@ const TextWithSelectField: React.FC = ({
name={selectFieldName}
onChange={value => change({ target: { name: selectFieldName, value } })}
value={selectFieldValue}
- className={clsx("noBorder", selectFieldClassName)}
+ className="noBorder"
+ __width="50px"
options={choices}
/>
- ),
- }}
- onChange={handleTextChange}
- value={textFieldValue}
+ )
+ }
/>
-
+
);
};
diff --git a/src/components/TextWithSelectField/styles.ts b/src/components/TextWithSelectField/styles.ts
deleted file mode 100644
index 5109af709f3..00000000000
--- a/src/components/TextWithSelectField/styles.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import { makeStyles } from "@saleor/macaw-ui";
-
-export const useStyles = makeStyles(
- () => ({
- container: {
- width: 400,
- },
- innerContainer: {
- width: "100%",
- },
- textField: {
- width: "100%",
- paddingRight: 0,
- "& input": {
- maxWidth: "100%",
- },
- },
- textFieldCentered: {
- "& input": {
- paddingTop: 17,
- paddingBottom: 16,
- },
- },
-
- // It may seem lazy to set these CSS properties with !important tags, but
- // specificity of overriden styles is really high and refer to mutliple
- // internal classes. Instead of dealing with it and trying to create
- // complex selectors with volatile class names, it's both easier and safer
- // to enforce these styles with !important.
- input: {
- boxShadow: "none !important",
- border: "none",
- },
- noBorder: {
- borderColor: "transparent !important",
- },
- noBackground: {
- backgroundColor: "transparent !important",
- },
- }),
- { name: "TextWithSelectField" },
-);
diff --git a/src/components/Timeline/Timeline.tsx b/src/components/Timeline/Timeline.tsx
index be21ecfbe07..0928559f91b 100644
--- a/src/components/Timeline/Timeline.tsx
+++ b/src/components/Timeline/Timeline.tsx
@@ -2,29 +2,22 @@
import { useUser } from "@dashboard/auth";
import { Button } from "@dashboard/components/Button";
import { getUserInitials } from "@dashboard/misc";
-import { CardContent, TextField } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
-import { vars } from "@saleor/macaw-ui-next";
+import { sprinkles, vars } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
+import { DashboardCard } from "../Card";
import { UserAvatar } from "../UserAvatar";
const useStyles = makeStyles(
theme => ({
- avatar: {
- left: -19,
- position: "absolute",
- top: 20,
- },
button: {
padding: `7px`,
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
},
- cardActionsExpanded: {
- maxHeight: theme.spacing(6),
- },
input: {
"& > div": {
padding: "0 0 0 14px",
@@ -38,7 +31,6 @@ const useStyles = makeStyles(
},
noteRoot: {
marginBottom: theme.spacing(3),
- // position: "absolute",
top: 0,
left: -19,
right: 0,
@@ -90,11 +82,15 @@ export const TimelineAddNote: React.FC = props => {
return (
-
+
= props => {
}}
variant="outlined"
/>
-
+
);
};
diff --git a/src/components/Timeline/TimelineNote.test.tsx b/src/components/Timeline/TimelineNote.test.tsx
index 7c712bb56f9..8c088a55b85 100644
--- a/src/components/Timeline/TimelineNote.test.tsx
+++ b/src/components/Timeline/TimelineNote.test.tsx
@@ -1,6 +1,7 @@
import { OrderEventFragment } from "@dashboard/graphql/types.generated";
import Wrapper from "@test/wrapper";
-import { render, screen } from "@testing-library/react";
+import { act, render, screen } from "@testing-library/react";
+import userEvent from "@testing-library/user-event";
import React from "react";
import TimelineNote from "./TimelineNote";
@@ -142,4 +143,85 @@ describe("TimelineNote", () => {
expect(initials).toBeNull();
expect(avatar).toBeInTheDocument();
});
+
+ it("renders note id and refer id", () => {
+ // Arrange
+ const noteId = "T3JkZXJFdmVudDozNDM3";
+ const noteRelatedId = "T3JkZXJFdmVudDozNDQx";
+ const mockedUser = {
+ avatar: null,
+ id: "1",
+ email: "test@test.com",
+ firstName: "Test",
+ lastName: "User",
+ __typename: "User",
+ } satisfies OrderEventFragment["user"];
+
+ // Act
+ render(
+ ,
+ { wrapper: Wrapper },
+ );
+
+ // Assert
+ expect(screen.getByText("Test User")).toBeInTheDocument();
+ expect(screen.getByText("Note")).toBeInTheDocument();
+ expect(screen.getByText("TU")).toBeInTheDocument();
+ expect(screen.getByText("a few seconds ago")).toBeInTheDocument();
+ expect(screen.getByText(`Note id: ${noteId}`)).toBeInTheDocument();
+ expect(screen.getByText(new RegExp(noteRelatedId))).toBeInTheDocument();
+ });
+
+ it("should edit note", async () => {
+ // Arrange
+ const noteId = "T3JkZXJFdmVudDozNDM3";
+ const noteRelatedId = "T3JkZXJFdmVudDozNDQx";
+ const onNoteUpdate = jest.fn();
+ const onNoteUpdateLoading = false;
+ const mockedUser = {
+ avatar: null,
+ id: "1",
+ email: "test@test.com",
+ firstName: "Test",
+ lastName: "User",
+ __typename: "User",
+ } satisfies OrderEventFragment["user"];
+
+ render(
+ ,
+ { wrapper: Wrapper },
+ );
+
+ // Act
+ await act(async () => {
+ await userEvent.click(screen.getByTestId("edit-note"));
+ });
+
+ await act(async () => {
+ await userEvent.clear(screen.getByRole("textbox"));
+ await userEvent.type(screen.getByRole("textbox"), "New note");
+ await userEvent.click(screen.getByRole("button", { name: /save/i }));
+ });
+
+ // Assert
+ expect(onNoteUpdate).toHaveBeenCalledWith(noteId, "New note");
+ });
});
diff --git a/src/components/Timeline/TimelineNote.tsx b/src/components/Timeline/TimelineNote.tsx
index 41f3d968ae6..7beac14dc77 100644
--- a/src/components/Timeline/TimelineNote.tsx
+++ b/src/components/Timeline/TimelineNote.tsx
@@ -1,56 +1,28 @@
-import { GiftCardEventFragment, OrderEventFragment } from "@dashboard/graphql";
+import { GiftCardEventsQuery, OrderEventFragment } from "@dashboard/graphql";
import { getUserInitials, getUserName } from "@dashboard/misc";
-import { Card, CardContent } from "@material-ui/core";
-import { makeStyles } from "@saleor/macaw-ui";
-import { Text, vars } from "@saleor/macaw-ui-next";
-import React from "react";
+import { Box, Button, EditIcon, Text } from "@saleor/macaw-ui-next";
+import React, { useState } from "react";
+import { FormattedMessage } from "react-intl";
+import { DashboardCard } from "../Card";
import { DateTime } from "../Date";
import { UserAvatar } from "../UserAvatar";
+import { TimelineNoteEdit } from "./TimelineNoteEdit";
-const useStyles = makeStyles(
- theme => ({
- avatar: {
- left: -40,
- position: "absolute",
- top: 0,
- },
- card: {
- marginBottom: theme.spacing(3),
- position: "relative",
- boxShadow: "none",
- background: vars.colors.background.default1,
- },
- cardContent: {
- wordBreak: "break-all",
- borderRadius: "4px",
- border: `1px solid ${vars.colors.border.default1}`,
- "&:last-child": {
- padding: 16,
- },
- },
- root: {
- position: "relative",
- },
- title: {
- "& p": {
- fontSize: "14px",
- },
- alignItems: "center",
- display: "flex",
- justifyContent: "space-between",
- marginBottom: theme.spacing(),
- },
- }),
- { name: "TimelineNote" },
-);
+type TimelineAppType =
+ | NonNullable["events"][0]["app"]
+ | OrderEventFragment["app"];
interface TimelineNoteProps {
date: string;
message: string | null;
user: OrderEventFragment["user"];
- app: OrderEventFragment["app"] | GiftCardEventFragment["app"];
+ app: TimelineAppType;
hasPlainDate?: boolean;
+ id?: string;
+ relatedId?: string;
+ onNoteUpdate?: (id: string, message: string) => Promise;
+ onNoteUpdateLoading?: boolean;
}
interface NoteMessageProps {
@@ -75,8 +47,8 @@ const TimelineAvatar = ({
className,
}: {
user: OrderEventFragment["user"];
- app: OrderEventFragment["app"] | GiftCardEventFragment["app"];
- className: string;
+ app: TimelineAppType;
+ className?: string;
}) => {
if (user) {
return (
@@ -103,26 +75,84 @@ export const TimelineNote: React.FC = ({
message,
hasPlainDate,
app,
+ id,
+ relatedId,
+ onNoteUpdate,
+ onNoteUpdateLoading,
}) => {
- const classes = useStyles();
-
const userDisplayName = getUserName(user, true) ?? app?.name;
+ const [showEdit, setShowEdit] = useState(false);
return (
-
-
-
+
+
+
+
+
{userDisplayName}
-
+
+ {relatedId ? (
+
+ ) : (
+
+ )}
-
-
-
-
-
-
-
+
+
+ {showEdit && id ? (
+ setShowEdit(false)}
+ />
+ ) : (
+ <>
+
+
+
+ {onNoteUpdate && (
+ {
+ setShowEdit(true);
+ }}
+ icon={ }
+ />
+ )}
+
+
+
+
+ {id && (
+
+ : {id}
+
+ )}
+ {relatedId && (
+
+ : {relatedId}
+
+ )}
+
+ >
+ )}
+
);
};
TimelineNote.displayName = "TimelineNote";
diff --git a/src/components/Timeline/TimelineNoteEdit.tsx b/src/components/Timeline/TimelineNoteEdit.tsx
new file mode 100644
index 00000000000..7adf1c13374
--- /dev/null
+++ b/src/components/Timeline/TimelineNoteEdit.tsx
@@ -0,0 +1,58 @@
+import { ConfirmButton } from "@dashboard/components/ConfirmButton";
+import { buttonMessages } from "@dashboard/intl";
+import { Box, Button, Textarea } from "@saleor/macaw-ui-next";
+import React from "react";
+import { useForm } from "react-hook-form";
+import { FormattedMessage } from "react-intl";
+
+interface TimelineNoteEditProps {
+ id: string;
+ note: string;
+ loading: boolean;
+ onSubmit: (id: string, message: string) => Promise;
+ onCancel: () => void;
+}
+
+interface TimelineNoteEditData {
+ note: string;
+}
+
+export const TimelineNoteEdit = ({
+ onCancel,
+ note,
+ onSubmit,
+ id,
+ loading,
+}: TimelineNoteEditProps) => {
+ const { handleSubmit, register } = useForm({
+ defaultValues: {
+ note,
+ },
+ });
+
+ const submitHandler = async (data: TimelineNoteEditData) => {
+ await onSubmit(id, data.note);
+ onCancel();
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/src/components/TypeDeleteWarningDialog/DeleteWarningDialogConsentContent.tsx b/src/components/TypeDeleteWarningDialog/DeleteWarningDialogConsentContent.tsx
index 8fdfbe91d1a..b930c905581 100644
--- a/src/components/TypeDeleteWarningDialog/DeleteWarningDialogConsentContent.tsx
+++ b/src/components/TypeDeleteWarningDialog/DeleteWarningDialogConsentContent.tsx
@@ -1,9 +1,5 @@
-import { Typography } from "@material-ui/core";
-import React, { ChangeEvent } from "react";
-
-import CardSpacer from "../CardSpacer";
-import ControlledCheckbox from "../ControlledCheckbox";
-import { useTypeDeleteWarningDialogStyles as useStyles } from "./styles";
+import { Checkbox, Text } from "@saleor/macaw-ui-next";
+import React from "react";
interface DeleteWarningDialogConsentContentProps {
description: string | React.ReactNode[] | readonly React.ReactNode[];
@@ -17,24 +13,21 @@ const DeleteWarningDialogConsentContent: React.FC {
- const classes = useStyles();
- const handleConsentChange = ({ target }: ChangeEvent) => onConsentChange(target.value);
+}) => (
+ <>
+ {description}
- return (
- <>
- {description}
-
- {consentLabel && (
- {consentLabel}}
- />
- )}
- >
- );
-};
+ {consentLabel && (
+ onConsentChange(!!value)}
+ >
+ {consentLabel}
+
+ )}
+ >
+);
export default DeleteWarningDialogConsentContent;
diff --git a/src/components/TypeDeleteWarningDialog/TypeDeleteWarningDialog.tsx b/src/components/TypeDeleteWarningDialog/TypeDeleteWarningDialog.tsx
index 48e17fdc622..adff4c17350 100644
--- a/src/components/TypeDeleteWarningDialog/TypeDeleteWarningDialog.tsx
+++ b/src/components/TypeDeleteWarningDialog/TypeDeleteWarningDialog.tsx
@@ -1,19 +1,16 @@
// @ts-strict-ignore
-import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
+import { ConfirmButton, ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
+import { buttonMessages } from "@dashboard/intl";
import { getById } from "@dashboard/misc";
-import ModalTitle from "@dashboard/orders/components/OrderDiscountCommonModal/ModalTitle";
-import { Card, CardContent, CircularProgress, Modal } from "@material-ui/core";
-import React from "react";
+import { Box, Spinner } from "@saleor/macaw-ui-next";
+import React, { useState } from "react";
import { useIntl } from "react-intl";
+import { Link } from "react-router-dom";
-import { useTypeDeleteWarningDialogStyles as useStyles } from "./styles";
-import ProductTypeDeleteWarningDialogContent from "./TypeDeleteWarningDialogContent";
-import { CommonTypeDeleteWarningMessages, TypeDeleteWarningMessages } from "./types";
-
-export interface TypeBaseData {
- id: string;
- name: string;
-}
+import DeleteButton from "../DeleteButton";
+import { DashboardModal } from "../Modal";
+import DeleteWarningDialogConsentContent from "./DeleteWarningDialogConsentContent";
+import { CommonTypeDeleteWarningMessages, TypeBaseData, TypeDeleteWarningMessages } from "./types";
export interface TypeDeleteMessages {
baseMessages: CommonTypeDeleteWarningMessages;
@@ -28,13 +25,11 @@ export interface TypeDeleteWarningDialogProps extends Ty
deleteButtonState: ConfirmButtonTransitionState;
onClose: () => void;
onDelete: () => void;
- viewAssignedItemsUrl: string;
+ viewAssignedItemsUrl: string | null;
typesToDelete: string[];
assignedItemsCount: number | undefined;
- isLoading?: boolean;
typesData: T[];
- // temporary, until we add filters to pages list - SALEOR-3279
- showViewAssignedItemsButton?: boolean;
+ isLoading?: boolean;
}
function TypeDeleteWarningDialog({
@@ -51,10 +46,10 @@ function TypeDeleteWarningDialog({
viewAssignedItemsUrl,
typesToDelete,
typesData,
- showViewAssignedItemsButton = true,
}: TypeDeleteWarningDialogProps) {
const intl = useIntl();
- const classes = useStyles({});
+ const [isConsentChecked, setIsConsentChecked] = useState(false);
+
const showMultiple = typesToDelete.length > 1;
const hasAssignedItems = !!assignedItemsCount;
const selectMessages = () => {
@@ -75,40 +70,60 @@ function TypeDeleteWarningDialog({
};
};
const { description, consentLabel } = selectMessages();
+
const singleItemSelectedId = typesToDelete[0];
const singleItemSelectedName = typesData.find(getById(singleItemSelectedId))?.name;
+ const shouldShowViewAssignedItemsButton = hasAssignedItems;
return (
-
-
-
-
- {isLoading ? (
-
-
-
- ) : (
-
+
+
+ {intl.formatMessage(baseMessages.title, {
+ selectedTypesCount: typesToDelete.length,
+ })}
+
+
+ {isLoading ? (
+
+
+
+ ) : (
+ <>
+ {chunks} ,
+ })}
+ consentLabel={consentLabel && intl.formatMessage(consentLabel)}
+ isConsentChecked={isConsentChecked}
+ onConsentChange={setIsConsentChecked}
/>
- )}
-
-
-
+
+
+ {shouldShowViewAssignedItemsButton && (
+
+
+ {intl.formatMessage(baseMessages.viewAssignedItemsButtonLabel)}
+
+
+ )}
+
+ {intl.formatMessage(buttonMessages.delete)}
+
+
+ >
+ )}
+
+
);
}
diff --git a/src/components/TypeDeleteWarningDialog/TypeDeleteWarningDialogContent.tsx b/src/components/TypeDeleteWarningDialog/TypeDeleteWarningDialogContent.tsx
deleted file mode 100644
index 208536ccaf7..00000000000
--- a/src/components/TypeDeleteWarningDialog/TypeDeleteWarningDialogContent.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import CardSpacer from "@dashboard/components/CardSpacer";
-import { ConfirmButton } from "@dashboard/components/ConfirmButton";
-import HorizontalSpacer from "@dashboard/components/HorizontalSpacer";
-import useNavigator from "@dashboard/hooks/useNavigator";
-import { CardContent } from "@material-ui/core";
-import React, { useState } from "react";
-import { MessageDescriptor, useIntl } from "react-intl";
-
-import DeleteButton from "../DeleteButton";
-import DeleteWarningDialogConsentContent from "./DeleteWarningDialogConsentContent";
-import { useTypeDeleteWarningDialogStyles as useStyles } from "./styles";
-
-interface TypeDeleteWarningDialogContentProps {
- singleItemSelectedName?: string;
- viewAssignedItemsButtonLabel: MessageDescriptor;
- description: MessageDescriptor;
- consentLabel: MessageDescriptor;
- viewAssignedItemsUrl: string;
- hasAssignedItems: boolean;
- assignedItemsCount: number | undefined;
- onDelete: () => void;
- // temporary, until we add filters to pages list - SALEOR-3279
- showViewAssignedItemsButton?: boolean;
-}
-
-const TypeDeleteWarningDialogContent: React.FC = ({
- description,
- consentLabel,
- viewAssignedItemsUrl,
- viewAssignedItemsButtonLabel,
- singleItemSelectedName,
- hasAssignedItems,
- assignedItemsCount,
- onDelete,
- showViewAssignedItemsButton,
-}) => {
- const classes = useStyles({});
- const intl = useIntl();
- const navigate = useNavigator();
- const [isConsentChecked, setIsConsentChecked] = useState(false);
- const handleViewAssignedItems = () => navigate(viewAssignedItemsUrl);
- const isDisbled = hasAssignedItems ? !isConsentChecked : false;
- const shouldShowViewAssignedItemsButton = showViewAssignedItemsButton && hasAssignedItems;
-
- return (
-
- {chunks} ,
- })}
- consentLabel={consentLabel && intl.formatMessage(consentLabel)}
- isConsentChecked={isConsentChecked}
- onConsentChange={setIsConsentChecked}
- />
-
-
- {shouldShowViewAssignedItemsButton && (
- <>
-
- {intl.formatMessage(viewAssignedItemsButtonLabel)}
-
-
- >
- )}
-
-
-
- );
-};
-
-export default TypeDeleteWarningDialogContent;
diff --git a/src/components/TypeDeleteWarningDialog/styles.ts b/src/components/TypeDeleteWarningDialog/styles.ts
deleted file mode 100644
index ea40ac068ee..00000000000
--- a/src/components/TypeDeleteWarningDialog/styles.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { makeStyles } from "@saleor/macaw-ui";
-
-export const useTypeDeleteWarningDialogStyles = makeStyles(
- theme => ({
- centerContainer: {
- display: "flex",
- alignItems: "center",
- justifyContent: "center",
- height: "100%",
- },
- content: {
- width: 600,
- },
- consentLabel: {
- color: theme.palette.primary.main,
- },
- buttonsSection: {
- display: "flex",
- justifyContent: "flex-end",
- },
- }),
- { name: "ProductTypeDeleteWarningDialog" },
-);
diff --git a/src/components/TypeDeleteWarningDialog/types.ts b/src/components/TypeDeleteWarningDialog/types.ts
index d5c8cce8b59..cd2f5953ab8 100644
--- a/src/components/TypeDeleteWarningDialog/types.ts
+++ b/src/components/TypeDeleteWarningDialog/types.ts
@@ -8,3 +8,9 @@ export type CommonTypeDeleteWarningMessages = Record<
export type TypeDeleteWarningMessages = Partial<
Record<"description" | "consentLabel", MessageDescriptor>
>;
+
+export interface TypeBaseData {
+ id: string;
+ name: string;
+ slug?: string;
+}
diff --git a/src/components/TypeDeleteWarningDialog/useViewProducts.test.ts b/src/components/TypeDeleteWarningDialog/useViewProducts.test.ts
new file mode 100644
index 00000000000..34882d82875
--- /dev/null
+++ b/src/components/TypeDeleteWarningDialog/useViewProducts.test.ts
@@ -0,0 +1,52 @@
+import { renderHook } from "@testing-library/react-hooks";
+
+import { useViewProducts } from "./useViewProducts";
+
+describe("useViewProducts", () => {
+ const productTypeBaseData = [
+ {
+ id: "123",
+ name: "Audiobooks",
+ slug: "audiobooks",
+ },
+ ];
+
+ it("should return URL with product type filtered", () => {
+ // Arrange & Act
+ const { result } = renderHook(() => useViewProducts({ productTypeBaseData }));
+
+ // Assert
+ expect(result.current).not.toBeNull();
+
+ const expectedQuery = "0[s0.productType][0]=audiobooks";
+ const receivedQuery = decodeURIComponent(result.current!.split("?")[1]);
+
+ expect(receivedQuery).toBe(expectedQuery);
+ });
+
+ it("should return URL with product type filtered when multiple product types are selected", () => {
+ // Arrange
+ const multipleProductTypeBaseData = [
+ ...productTypeBaseData,
+ {
+ id: "456",
+ name: "Shirts",
+ slug: "shirts",
+ },
+ ];
+
+ // Act
+ const { result } = renderHook(() =>
+ useViewProducts({ productTypeBaseData: multipleProductTypeBaseData }),
+ );
+
+ // Assert
+ expect(result.current).not.toBeNull();
+
+ const expectedQuery = "0[s2.productType][0]=audiobooks&0[s2.productType][1]=shirts";
+
+ const receivedQuery = decodeURIComponent(result.current!.split("?")[1]);
+
+ expect(receivedQuery).toBe(expectedQuery);
+ });
+});
diff --git a/src/components/TypeDeleteWarningDialog/useViewProducts.ts b/src/components/TypeDeleteWarningDialog/useViewProducts.ts
new file mode 100644
index 00000000000..420636ecf3a
--- /dev/null
+++ b/src/components/TypeDeleteWarningDialog/useViewProducts.ts
@@ -0,0 +1,49 @@
+import { productListPath } from "@dashboard/products/urls";
+import { stringify } from "qs";
+import { useMemo } from "react";
+import urljoin from "url-join";
+
+import { FilterElement } from "../ConditionalFilter/FilterElement";
+import { prepareStructure } from "../ConditionalFilter/ValueProvider/utils";
+import { TypeBaseData } from "./types";
+
+export interface ProductTypeBaseData extends TypeBaseData {
+ slug: string;
+}
+
+interface ViewProductsProps {
+ productTypeBaseData: ProductTypeBaseData[] | undefined;
+}
+
+const baseDataToCondition = (baseData: ProductTypeBaseData) => ({
+ label: baseData.name,
+ slug: baseData.slug,
+ value: baseData.id,
+});
+
+export const useViewProducts = ({ productTypeBaseData }: ViewProductsProps) => {
+ const viewProductsUrl = useMemo(() => {
+ if (!productTypeBaseData) {
+ return null;
+ }
+
+ const productFilterElement = FilterElement.createStaticBySlug("productType");
+
+ const condition =
+ productTypeBaseData.length > 1
+ ? productFilterElement.condition.options[1]
+ : productFilterElement.condition.options[0]; // "in" or "is"
+
+ productFilterElement.updateCondition(condition);
+
+ productFilterElement.updateRightOperator(productTypeBaseData.map(baseDataToCondition));
+
+ const url = stringify({
+ ...prepareStructure([productFilterElement]),
+ });
+
+ return urljoin(productListPath, `?${url}`);
+ }, [productTypeBaseData]);
+
+ return viewProductsUrl;
+};
diff --git a/src/components/UserAvatar/UserAvatar.tsx b/src/components/UserAvatar/UserAvatar.tsx
index 39b78eed1e9..3796c7ec977 100644
--- a/src/components/UserAvatar/UserAvatar.tsx
+++ b/src/components/UserAvatar/UserAvatar.tsx
@@ -5,6 +5,7 @@ interface UserAvatarProps {
url?: string;
initials?: string;
className?: string;
+ style?: React.CSSProperties;
}
export const UserAvatar: React.FC = ({ url, initials, ...rest }) =>
diff --git a/src/components/VersionInfo/VersionInfo.tsx b/src/components/VersionInfo/VersionInfo.tsx
index 5b3c4b54b1c..2b52962186b 100644
--- a/src/components/VersionInfo/VersionInfo.tsx
+++ b/src/components/VersionInfo/VersionInfo.tsx
@@ -1,4 +1,4 @@
-import { Typography } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { useStyles } from "./styles";
@@ -16,10 +16,10 @@ const VersionInfo: React.FC = ({ dashboardVersion, coreVersion
}
return (
-
+
{`dashboard ${dashboardVersion}`}
{`core v${coreVersion}`}
-
+
);
};
diff --git a/src/components/VisibilityCard/DateVisibilitySelector.tsx b/src/components/VisibilityCard/DateVisibilitySelector.tsx
index 4e48a0ce435..2e5cc2ebb9a 100644
--- a/src/components/VisibilityCard/DateVisibilitySelector.tsx
+++ b/src/components/VisibilityCard/DateVisibilitySelector.tsx
@@ -1,6 +1,6 @@
import closeIcon from "@assets/images/close-thin.svg";
-import { Typography } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import FormSpacer from "../FormSpacer";
@@ -46,9 +46,9 @@ const DateVisibilitySelector = ({ buttonText, children, onInputClose }: Props) =
if (!showInput) {
return (
- setShowInput(true)}>
+ setShowInput(true)}>
{buttonText}
-
+
);
}
diff --git a/src/components/VisibilityCard/VisibilityCard.tsx b/src/components/VisibilityCard/VisibilityCard.tsx
index 8181e71f6ce..a59e50a7c31 100644
--- a/src/components/VisibilityCard/VisibilityCard.tsx
+++ b/src/components/VisibilityCard/VisibilityCard.tsx
@@ -1,5 +1,4 @@
// @ts-strict-ignore
-import CardTitle from "@dashboard/components/CardTitle";
import ControlledCheckbox from "@dashboard/components/ControlledCheckbox";
import Hr from "@dashboard/components/Hr";
import RadioSwitchField from "@dashboard/components/RadioSwitchField";
@@ -8,13 +7,13 @@ import useDateLocalize from "@dashboard/hooks/useDateLocalize";
import { ChangeEvent } from "@dashboard/hooks/useForm";
import { UserError } from "@dashboard/types";
import { getFieldError } from "@dashboard/utils/errors";
-import { Card, CardContent, Typography } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
import { Box, Checkbox, RadioGroup, Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React, { useState } from "react";
import { useIntl } from "react-intl";
+import { DashboardCard } from "../Card";
import { DateTimeTimezoneField } from "../DateTimeTimezoneField";
import FormSpacer from "../FormSpacer";
import DateVisibilitySelector from "./DateVisibilitySelector";
@@ -135,9 +134,13 @@ export const VisibilityCard: React.FC = props => {
};
return (
-
-
-
+
+
+
+ {intl.formatMessage(visibilityCardMessages.title)}
+
+
+
= props => {
{getFieldError(errors, "isPublished") && (
<>
- {getFieldError(errors, "isPublished")?.message}
+ {getFieldError(errors, "isPublished")?.message}
>
)}
{hasAvailableProps && (
@@ -286,9 +289,9 @@ export const VisibilityCard: React.FC = props => {
{getFieldError(errors, "isAvailableForPurchase") && (
<>
-
+
{getFieldError(errors, "isAvailableForPurchase")?.message}
-
+
>
)}
>
@@ -325,8 +328,8 @@ export const VisibilityCard: React.FC = props => {
>
)}
{children}
-
-
+
+
);
};
VisibilityCard.displayName = "VisibilityCard";
diff --git a/src/config.ts b/src/config.ts
index 571ee2bc390..e53640cba6b 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -199,3 +199,5 @@ export const DEMO_MODE = process.env.DEMO_MODE === "true";
export const GTM_ID = process.env.GTM_ID;
export const DEFAULT_NOTIFICATION_SHOW_TIME = 3000;
+export const ENABLED_SERVICE_NAME_HEADER =
+ (process.env.ENABLED_SERVICE_NAME_HEADER as string) === "true";
diff --git a/src/configuration/ConfigurationPage.tsx b/src/configuration/ConfigurationPage.tsx
index 3210d65deae..6e27c766c43 100644
--- a/src/configuration/ConfigurationPage.tsx
+++ b/src/configuration/ConfigurationPage.tsx
@@ -3,11 +3,10 @@ import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import { DetailPageLayout } from "@dashboard/components/Layouts";
import { UserFragment } from "@dashboard/graphql";
import { sectionNames } from "@dashboard/intl";
-import { Typography } from "@material-ui/core";
import { useTheme } from "@material-ui/core/styles";
import useMediaQuery from "@material-ui/core/useMediaQuery";
import { makeStyles, NavigationCard } from "@saleor/macaw-ui";
-import { Box, vars } from "@saleor/macaw-ui-next";
+import { Box, Text, vars } from "@saleor/macaw-ui-next";
import React from "react";
import { useIntl } from "react-intl";
import { Link } from "react-router-dom";
@@ -103,7 +102,7 @@ export const ConfigurationPage: React.FC = props => {
.map((menu, menuIndex) => (
- {menu.label}
+ {menu.label}
{menu.menuItems
diff --git a/src/custom-apps/components/CustomAppDefaultToken/CustomAppDefaultToken.tsx b/src/custom-apps/components/CustomAppDefaultToken/CustomAppDefaultToken.tsx
index 2f8951e9b75..357209963e7 100644
--- a/src/custom-apps/components/CustomAppDefaultToken/CustomAppDefaultToken.tsx
+++ b/src/custom-apps/components/CustomAppDefaultToken/CustomAppDefaultToken.tsx
@@ -1,13 +1,12 @@
-import { Button } from "@dashboard/components/Button";
+import { DashboardCard } from "@dashboard/components/Card";
import Link from "@dashboard/components/Link";
import useClipboard from "@dashboard/hooks/useClipboard";
-import { Card, CardContent, Paper, Typography } from "@material-ui/core";
import CloseIcon from "@material-ui/icons/Close";
-import { IconButton } from "@saleor/macaw-ui";
+import { Box, Button, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage } from "react-intl";
-import { useStyles } from "./styles";
+import { Mono } from "../TokenCreateDialog/Mono";
export interface CustomAppDefaultTokenProps {
apiUrl: string;
@@ -18,21 +17,20 @@ export interface CustomAppDefaultTokenProps {
const CustomAppDefaultToken: React.FC
= props => {
const { apiUrl, token, onApiUrlClick, onTokenClose } = props;
- const classes = useStyles(props);
const [copied, copy] = useClipboard();
return (
-
-
-
+
+
+
-
+
-
-
+
+
= props => {
),
}}
/>
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
- {token}
- copy(token)}>
+
+
+ {token}
+
+ copy(token)}>
{copied ? (
) : (
)}
-
-
-
+
+
+
);
};
diff --git a/src/custom-apps/components/CustomAppDefaultToken/styles.ts b/src/custom-apps/components/CustomAppDefaultToken/styles.ts
deleted file mode 100644
index 32b24c29718..00000000000
--- a/src/custom-apps/components/CustomAppDefaultToken/styles.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { alpha } from "@material-ui/core/styles";
-import { makeStyles } from "@saleor/macaw-ui";
-
-export const useStyles = makeStyles(
- theme => ({
- cancel: {
- marginRight: theme.spacing(1),
- },
- closeContainer: {
- display: "flex",
- justifyContent: "flex-end",
- position: "relative",
- right: theme.spacing(-1),
- top: theme.spacing(-1),
- },
- content: {
- display: "grid",
- gridColumnGap: theme.spacing(3),
- gridTemplateColumns: "1fr 60px",
- marginBottom: theme.spacing(3),
- },
- copy: {
- marginTop: theme.spacing(),
- position: "relative",
- right: theme.spacing(1),
- },
- paper: {
- background: alpha(theme.palette.primary.main, 0.05),
- padding: theme.spacing(2, 3),
- },
- root: {
- boxShadow: "0px 5px 10px rgba(0, 0, 0, 0.05)",
- },
- }),
- {
- name: "CustomAppTokenCreateDialog",
- },
-);
diff --git a/src/custom-apps/components/CustomAppInformation/CustomAppInformation.tsx b/src/custom-apps/components/CustomAppInformation/CustomAppInformation.tsx
index 54a8e8145c8..89d453b55c3 100644
--- a/src/custom-apps/components/CustomAppInformation/CustomAppInformation.tsx
+++ b/src/custom-apps/components/CustomAppInformation/CustomAppInformation.tsx
@@ -1,10 +1,10 @@
// @ts-strict-ignore
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import { AppErrorFragment } from "@dashboard/graphql";
import { FormChange } from "@dashboard/hooks/useForm";
import { getFormErrors } from "@dashboard/utils/errors";
import getAppErrorMessage from "@dashboard/utils/errors/app";
-import { Card, CardContent, TextField } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
import React from "react";
import { useIntl } from "react-intl";
@@ -38,16 +38,17 @@ const CustomAppInformation: React.FC = ({
const formErrors = getFormErrors(["name"], errors);
return (
-
-
-
+
+
+
+ {intl.formatMessage({
+ id: "imYxM9",
+ defaultMessage: "App Information",
+ description: "header",
+ })}
+
+
+
= ({
value={data.name}
onChange={onChange}
/>
-
-
+
+
);
};
diff --git a/src/custom-apps/components/CustomAppListPage/CustomAppListPage.tsx b/src/custom-apps/components/CustomAppListPage/CustomAppListPage.tsx
index bd4c2a5099f..507e9a6daa7 100644
--- a/src/custom-apps/components/CustomAppListPage/CustomAppListPage.tsx
+++ b/src/custom-apps/components/CustomAppListPage/CustomAppListPage.tsx
@@ -1,4 +1,5 @@
import DeactivatedText from "@dashboard/apps/components/DeactivatedText";
+import { useContextualLink } from "@dashboard/components/AppLayout/ContextualLinks/useContextualLink";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import { ListPageLayout } from "@dashboard/components/Layouts";
import { TableButtonWrapper } from "@dashboard/components/TableButtonWrapper/TableButtonWrapper";
@@ -9,7 +10,7 @@ import { AppListItemFragment } from "@dashboard/graphql";
import useNavigator from "@dashboard/hooks/useNavigator";
import { sectionNames } from "@dashboard/intl";
import { renderCollection } from "@dashboard/misc";
-import { TableBody, TableCell, Typography } from "@material-ui/core";
+import { TableBody, TableCell } from "@material-ui/core";
import { DeleteIcon, IconButton, ResponsiveTable } from "@saleor/macaw-ui";
import { Box, Button, Text } from "@saleor/macaw-ui-next";
import React from "react";
@@ -32,11 +33,13 @@ const CustomAppListPage: React.FC = ({
const intl = useIntl();
const classes = useStyles();
const navigate = useNavigator();
+ const subtitle = useContextualLink("extending_saleor");
return (
= ({
() => (
-
+
-
+
),
diff --git a/src/custom-apps/components/CustomAppTokens/CustomAppTokens.tsx b/src/custom-apps/components/CustomAppTokens/CustomAppTokens.tsx
index b8550d56fdb..8a807f52a51 100644
--- a/src/custom-apps/components/CustomAppTokens/CustomAppTokens.tsx
+++ b/src/custom-apps/components/CustomAppTokens/CustomAppTokens.tsx
@@ -1,13 +1,13 @@
// @ts-strict-ignore
import { Button } from "@dashboard/components/Button";
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
-import Skeleton from "@dashboard/components/Skeleton";
import TableRowLink from "@dashboard/components/TableRowLink";
import { AppUpdateMutation } from "@dashboard/graphql";
import { renderCollection } from "@dashboard/misc";
-import { Card, CardContent, TableBody, TableCell, TableHead } from "@material-ui/core";
+import { TableBody, TableCell, TableHead } from "@material-ui/core";
import { DeleteIcon, IconButton } from "@saleor/macaw-ui";
+import { Skeleton } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -26,21 +26,23 @@ const CustomAppTokens: React.FC = props => {
const intl = useIntl();
return (
-
-
+
+
+ {intl.formatMessage({
+ id: "0Mg8o5",
+ defaultMessage: "Tokens",
+ description: "header",
+ })}
+
+
- }
- />
-
+
+
+
+
@@ -93,8 +95,8 @@ const CustomAppTokens: React.FC = props => {
)}
-
-
+
+
);
};
diff --git a/src/custom-apps/components/CustomAppsSkeleton/CustomAppsSkeleton.tsx b/src/custom-apps/components/CustomAppsSkeleton/CustomAppsSkeleton.tsx
index f6b102d60e2..129022e571b 100644
--- a/src/custom-apps/components/CustomAppsSkeleton/CustomAppsSkeleton.tsx
+++ b/src/custom-apps/components/CustomAppsSkeleton/CustomAppsSkeleton.tsx
@@ -1,6 +1,6 @@
-import Skeleton from "@dashboard/components/Skeleton";
import TableRowLink from "@dashboard/components/TableRowLink";
import { TableCell } from "@material-ui/core";
+import { Skeleton } from "@saleor/macaw-ui-next";
import React from "react";
import { useStyles } from "./styles";
diff --git a/src/custom-apps/components/PermissionAlert/PermissionAlert.tsx b/src/custom-apps/components/PermissionAlert/PermissionAlert.tsx
index dd69ec9a042..7b6fa75ecaa 100644
--- a/src/custom-apps/components/PermissionAlert/PermissionAlert.tsx
+++ b/src/custom-apps/components/PermissionAlert/PermissionAlert.tsx
@@ -1,10 +1,11 @@
-import { useQuery } from "@apollo/client";
+import { gql, useQuery } from "@apollo/client";
import { Alert } from "@saleor/macaw-ui";
import { Box, Chip, Text } from "@saleor/macaw-ui-next";
+import { getIntrospectionQuery } from "graphql";
import React from "react";
import { useIntl } from "react-intl";
-import { buildPermissionMap, getPermissions, IntrospectionQuery } from "./utils";
+import { getPermissions } from "./utils";
export interface PermissionAlertProps {
query: string;
@@ -12,16 +13,16 @@ export interface PermissionAlertProps {
const PermissionAlert: React.FC = ({ query }) => {
const intl = useIntl();
- const { data } = useQuery(IntrospectionQuery, {
+ const introQuery = getIntrospectionQuery();
+ const { data } = useQuery(gql(introQuery), {
fetchPolicy: "network-only",
});
- const elements = data?.__schema?.types || [];
- const permissionMapping = buildPermissionMap(elements);
- const permissions = getPermissions(query, permissionMapping);
+ const permissionInfo = getPermissions(query, data);
+ const hasPermissions = permissionInfo && Object.entries(permissionInfo).length > 0;
return (
- {permissions.length > 0 && (
+ {hasPermissions && (
= ({ query }) => {
close={false}
className="remove-icon-background"
>
-
- {permissions.map(permission => (
-
- {permission}
-
- ))}
+
+ {Object.entries(permissionInfo).map(
+ ([subscription, { isOneOfRequired, permissions }]) => (
+
+
+ {intl.formatMessage({
+ id: "0YjGFG",
+ defaultMessage: "For subscription",
+ description: "alert message",
+ })}
+
+
+ {subscription}
+
+
+ {isOneOfRequired
+ ? intl.formatMessage({
+ id: "I/y4IU",
+ defaultMessage: "one of",
+ description: "alert message",
+ })
+ : intl.formatMessage({
+ defaultMessage: "all of",
+ id: "C+WD8j",
+ description: "alert message",
+ })}
+
+ {permissions.map(permission => (
+
+ {permission}
+
+ ))}
+
+ ),
+ )}
)}
diff --git a/src/custom-apps/components/PermissionAlert/utils.test.ts b/src/custom-apps/components/PermissionAlert/utils.test.ts
index 325b2aeb20a..0d9321779b4 100644
--- a/src/custom-apps/components/PermissionAlert/utils.test.ts
+++ b/src/custom-apps/components/PermissionAlert/utils.test.ts
@@ -4,10 +4,10 @@ describe("Permission Parsing", () => {
it("should extract permissions from the meta `description` if available", () => {
// Arrange
// -> Order.invoices
- // https://docs.saleor.io/docs/3.x/api-reference/objects/order
+ // https://docs.saleor.io/api-reference/orders/objects/order
const description = `List of order invoices. Can be fetched for orders created in Saleor 3.2 and later, for other orders requires one of the following permissions: MANAGE_ORDERS, OWNER.`;
// Act
- const permissions = extractPermissions(description);
+ const { permissions } = extractPermissions(description);
// Assert
expect(permissions).toHaveLength(2);
@@ -16,12 +16,25 @@ describe("Permission Parsing", () => {
it("should return empty list if the `description` doesn't mention permissions", () => {
// Arrange
// -> Order.number
- // https://docs.saleor.io/docs/3.x/api-reference/objects/order
+ // https://docs.saleor.io/api-reference/orders/objects/order
const description = `User-friendly number of an order.`;
// Act
- const permissions = extractPermissions(description);
+ const { permissions } = extractPermissions(description);
// Assert
expect(permissions).toHaveLength(0);
});
+ it("should correctly asses if the permissions are optional", () => {
+ // Arrange
+ // -> Order.invoices
+ // https://docs.saleor.io/api-reference/orders/objects/order
+ const description = `List of order invoices. Can be fetched for orders created in Saleor 3.2 and later, for other orders requires one of the following permissions: MANAGE_ORDERS, OWNER.`;
+ // Act
+ const { permissions, isOneOfRequired } = extractPermissions(description);
+
+ // Assert
+ expect(isOneOfRequired).toBe(true);
+ expect(permissions).toHaveLength(2);
+ expect(permissions[1]).toEqual("OWNER");
+ });
});
diff --git a/src/custom-apps/components/PermissionAlert/utils.ts b/src/custom-apps/components/PermissionAlert/utils.ts
index 5480e77f570..b2cd862d70e 100644
--- a/src/custom-apps/components/PermissionAlert/utils.ts
+++ b/src/custom-apps/components/PermissionAlert/utils.ts
@@ -1,47 +1,62 @@
-// @ts-strict-ignore
-import { gql } from "@apollo/client";
-import { FieldNode, parse, SelectionNode, visit } from "graphql";
-
-interface IntrospectionNode {
- kind: string;
- name: string;
- description: string;
- fields: Array<{
- name: string;
- description: string;
- }>;
-}
+import {
+ buildClientSchema,
+ DocumentNode,
+ GraphQLField,
+ GraphQLList,
+ GraphQLNonNull,
+ GraphQLObjectType,
+ GraphQLSchema,
+ GraphQLType,
+ IntrospectionQuery,
+ Location,
+ parse,
+ Token,
+ visit,
+} from "graphql";
+import { TypeMap } from "graphql/type/schema";
+
+type SubscriptionQueryPermission = Record<
+ string,
+ {
+ isOneOfRequired: boolean;
+ permissions: string[];
+ }
+>;
-interface PermissionChildNode {
- permissions: string[];
- children: string[];
-}
+const getStartToken = (documentNode: DocumentNode) => {
+ const loc = documentNode.loc as Location | undefined;
-interface PermissionNode {
- permissions: string[];
- children: Record
;
-}
+ return loc?.startToken;
+};
-type PermissionMap = Record;
-
-// cannot be in `queries.ts` as codegen cannot handle `__schema`
-export const IntrospectionQuery = gql`
- query PermissionIntrospection {
- __schema {
- types {
- kind
- name
- description
- fields(includeDeprecated: false) {
- name
- description
- }
- }
- }
+type FlattenedTokenArray = (string | undefined)[];
+
+const toFlattenedTokenArray = (
+ token: Token | undefined,
+ tokens: FlattenedTokenArray = [],
+): FlattenedTokenArray => {
+ if (token && token.next) {
+ tokens.push(token.value);
+
+ return toFlattenedTokenArray(token.next, tokens);
}
-`;
-const uniq = (value: T, index: number, self: T[]) => self.indexOf(value) === index;
+ return tokens;
+};
+
+const flattenedTokenArray = (token: Token | undefined, tokens: string[] = []): string[] => {
+ const flattened = toFlattenedTokenArray(token, tokens);
+
+ return flattened.filter(Boolean) as string[];
+};
+
+const unwrapType = (type: GraphQLType): GraphQLType => {
+ if (type instanceof GraphQLNonNull || type instanceof GraphQLList) {
+ return unwrapType(type.ofType);
+ }
+
+ return type;
+};
// Right now, permissions are appended at the end of `description`
// for each field in the result of the introspection query. The format
@@ -50,92 +65,121 @@ const uniq = (value: T, index: number, self: T[]) => self.indexOf(value) ===
// separated and independant, yet easily accessible
export const extractPermissions = (description?: string) => {
const match = (description || "").match(/following permissions(.*): (.*?)\./);
+ // We're assuming that if there is no "one of" then all permissions are required
+ const isOneOfRequired = (description || "").includes("one of");
const permissions = match ? match[2].split(",") : [];
- return permissions;
+ return {
+ isOneOfRequired,
+ permissions: permissions.map(permission => permission.trim()),
+ };
};
-export const getPermissions = (query: string, permissionMapping: PermissionMap) => {
- const cursors = extractCursorsFromQuery(query);
-
- return cursors.map(findPermission(permissionMapping)).flat().filter(uniq);
+export const getPermissions = (
+ query: string,
+ introspectionQuery: IntrospectionQuery,
+): SubscriptionQueryPermission => {
+ return extractPermissionsFromQuery(query, introspectionQuery);
};
-export const buildPermissionMap = (elements: IntrospectionNode[]): PermissionMap =>
- elements
- .filter(({ kind }) => kind === "OBJECT")
- .filter(({ name }) => !/(Created|Create|Delete|Deleted|Update|Updated)$/.test(name))
- .reduce((saved, { name, description, fields }) => {
- const permissions = extractPermissions(description);
- const children = fields.reduce((prev, { name, description }) => {
- const permissions = extractPermissions(description);
-
- return {
- ...prev,
- [name.toLowerCase()]: { permissions },
- };
- }, {});
-
- return {
- ...saved,
- [name.toLowerCase()]: {
- permissions,
- children,
- },
- };
- }, {});
-
-const byKind = (name: string) => (element: SelectionNode) => element.kind === name;
-const extractValue = (element: FieldNode) => element.name.value;
-const isNotEvent = (value: string) => value !== "event";
-
-export const extractCursorsFromQuery = (query: string) => {
- const cursors: string[][] = [];
+const extractSubscriptions = (
+ subscriptions: GraphQLObjectType[],
+ tokens: string[],
+): GraphQLObjectType[] =>
+ tokens.reduce((acc, token) => {
+ const subscription = subscriptions.find(({ name }) => name === token);
- try {
- const ast = parse(query);
+ if (subscription) {
+ return [...acc, subscription];
+ }
+
+ return acc as GraphQLObjectType[];
+ }, [] as GraphQLObjectType[]);
- visit(ast, {
- Field(node, _key, _parent, _path, ancestors) {
- if (node.name.value !== "__typename") {
- const cursor = ancestors.filter(byKind("Field")).map(extractValue).filter(isNotEvent);
+const getSubscriptions = (typeMap: TypeMap): GraphQLObjectType[] =>
+ Object.keys(typeMap).reduce((acc, key) => {
+ const type = typeMap[key] as GraphQLObjectType;
- if (cursor.length > 0) {
- cursors.push([...cursor, node.name.value]);
+ if (type instanceof GraphQLObjectType) {
+ const interfaces = type.getInterfaces();
+ const hasEvent = interfaces.some(({ name }) => name === "Event");
+
+ if (hasEvent) {
+ return [...acc, type];
+ }
+ }
+
+ return acc;
+ }, [] as GraphQLObjectType[]);
+
+function getDescriptionsFromQuery(query: string, schema: GraphQLSchema): { [key: string]: string } {
+ const descriptions: { [key: string]: string } = {};
+ const ast = parse(query);
+ const startToken = getStartToken(ast);
+ const tree = flattenedTokenArray(startToken, []);
+ const subscriptions = getSubscriptions(schema.getTypeMap());
+ const subscriptionsFromQuery = extractSubscriptions(subscriptions, tree);
+
+ visit(ast, {
+ Field(node, _key, _parent, _path, ancestors) {
+ for (const _type in subscriptionsFromQuery) {
+ const fieldPath = ancestors
+ .filter((ancestor: any) => ancestor.kind === "Field")
+ .map((ancestor: any) => ancestor.name.value)
+ .concat(node.name.value);
+ let type: GraphQLObjectType | undefined = subscriptionsFromQuery[_type];
+
+ for (const fieldName of fieldPath.slice(1, -1)) {
+ if (type) {
+ const field: GraphQLField = (
+ unwrapType(type) as GraphQLObjectType
+ ).getFields()[fieldName];
+
+ // Some types can have multiple nested fields eg. lists
+ type = field && field.type ? (unwrapType(field.type) as GraphQLObjectType) : undefined;
+ }
+ }
+
+ if (type) {
+ const field = type.getFields()[node.name.value];
+
+ if (field) {
+ descriptions[fieldPath.join(".")] = field.description || "No description available";
}
}
- },
- });
+ }
+ },
+ });
+
+ return descriptions;
+}
+
+const extractSubscriptionQueryPermissions = (descriptions: { [key: string]: string }) => {
+ return Object.keys(descriptions).reduce((acc, key) => {
+ const { isOneOfRequired, permissions } = extractPermissions(descriptions[key]);
+
+ if (permissions.length > 0) {
+ acc[key] = { isOneOfRequired, permissions };
+ }
+
+ return acc;
+ }, {} as SubscriptionQueryPermission);
+};
+
+const extractPermissionsFromQuery = (
+ query: string,
+ introspectionQuery: IntrospectionQuery,
+): SubscriptionQueryPermission => {
+ let permissions: SubscriptionQueryPermission = {};
+
+ try {
+ const schema = buildClientSchema(introspectionQuery);
+ const descriptions = getDescriptionsFromQuery(query, schema);
+
+ permissions = extractSubscriptionQueryPermissions(descriptions);
} catch (error) {
// explicit silent
}
- return cursors;
-};
-
-const groupBy = (list: T[], groupSize = 2) =>
- list.slice(groupSize - 1).map((_, index) => list.slice(index, index + groupSize));
-
-// Permission Map is a tree like nested structure. As we want to
-// visit each level, we split the cursor provided by the user
-// into chunks (groups) to check if there are permissions for
-// each element between root and leafs
-// e.g.
-// ['query', 'order', 'invoices', 'name']
-// becomes
-// [['query', 'order'], ['order', 'invoices'], ['invoices', 'name']]
-// so we can check first ir `order` contains permission, then `invoices`
-// and then `name`
-export const findPermission = (permissions: PermissionMap) => (cursor: string[]) => {
- const groups = groupBy(["query", ...cursor]);
-
- return groups.reduce(
- (saved, [parent, child]) => [
- ...saved,
- ...(permissions[parent] && permissions[parent].children[child]
- ? permissions[parent].children[child].permissions
- : []),
- ],
- [],
- );
+ return permissions;
};
diff --git a/src/custom-apps/components/TokenCreateDialog/Mono.tsx b/src/custom-apps/components/TokenCreateDialog/Mono.tsx
new file mode 100644
index 00000000000..0f83f6cbbc6
--- /dev/null
+++ b/src/custom-apps/components/TokenCreateDialog/Mono.tsx
@@ -0,0 +1,15 @@
+import { Text } from "@saleor/macaw-ui-next";
+import React, { PropsWithChildren } from "react";
+
+export const Mono: React.FC> = ({ children }) => (
+
+ {children}
+
+);
diff --git a/src/custom-apps/components/TokenCreateDialog/TokenCreateDialog.tsx b/src/custom-apps/components/TokenCreateDialog/TokenCreateDialog.tsx
index 919159d50ca..80a1838af7a 100644
--- a/src/custom-apps/components/TokenCreateDialog/TokenCreateDialog.tsx
+++ b/src/custom-apps/components/TokenCreateDialog/TokenCreateDialog.tsx
@@ -1,27 +1,17 @@
-// @ts-strict-ignore
import BackButton from "@dashboard/components/BackButton";
-import { Button } from "@dashboard/components/Button";
-import CardSpacer from "@dashboard/components/CardSpacer";
import { ConfirmButton, ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
import Form from "@dashboard/components/Form";
-import FormSpacer from "@dashboard/components/FormSpacer";
+import { DashboardModal } from "@dashboard/components/Modal";
import { getApiUrl } from "@dashboard/config";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import useModalDialogOpen from "@dashboard/hooks/useModalDialogOpen";
import { buttonMessages } from "@dashboard/intl";
-import {
- Dialog,
- DialogActions,
- DialogContent,
- DialogTitle,
- Paper,
- TextField,
- Typography,
-} from "@material-ui/core";
+import { TextField } from "@material-ui/core";
+import { Box, Button, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
-import { useStyles } from "./styles";
+import { Mono } from "./Mono";
export interface TokenCreateDialogProps {
confirmButtonState: ConfirmButtonTransitionState;
@@ -37,14 +27,20 @@ function handleCopy(token: string) {
navigator.clipboard.writeText(token);
}
-const Mono = ({ children, className }) => {children} ;
+const tokenPaperStyles = {
+ padding: 4,
+ backgroundColor: "default2",
+ borderRadius: 4,
+ __whiteSpace: "pre-wrap",
+} as const;
+
const createHeadersString = (token: string) => `{\n "authorization": "Bearer ${token}"\n}`;
+
const TokenCreateDialog: React.FC = props => {
const { confirmButtonState, open, token, onClose, onCreate } = props;
const [step, setStep] = React.useState("form");
const intl = useIntl();
- const classes = useStyles(props);
- const headers = createHeadersString(token);
+ const headers = createHeadersString(token ?? "");
React.useEffect(() => {
if (token !== undefined) {
@@ -60,23 +56,24 @@ const TokenCreateDialog: React.FC = props => {
};
return (
-
- onCreate(data.name)}>
- {({ change, data, submit }) => (
- <>
-
-
-
-
+
+
+ onCreate(data.name)}>
+ {({ change, data, submit }) => (
+
+
+
+
+
{step === "form" ? (
<>
-
+
-
-
+
+
= props => {
>
) : (
<>
-
+
-
-
-
-
+
+
+
+
-
-
- {token}
-
- handleCopy(token)}>
+
+
+
+ {token}
+
+
+ handleCopy(token ?? "")}
+ >
-
-
-
-
+
+
+
+
-
-
- {headers}
-
- handleCopy(headers)}>
-
-
-
-
-
-
-
- >
- )}
-
-
- {step === "form" ? (
- <>
-
-
-
-
+
+
+
+ {headers}
+
+
+
+ handleCopy(headers)}>
+
+
+
+
+
+
+
>
- ) : (
-
-
-
)}
-
- >
- )}
-
-
+
+
+ {step === "form" ? (
+ <>
+
+
+
+
+ >
+ ) : (
+
+
+
+ )}
+
+
+ )}
+
+
+
);
};
diff --git a/src/custom-apps/components/TokenCreateDialog/styles.ts b/src/custom-apps/components/TokenCreateDialog/styles.ts
deleted file mode 100644
index a55470578ed..00000000000
--- a/src/custom-apps/components/TokenCreateDialog/styles.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { alpha } from "@material-ui/core/styles";
-import { makeStyles } from "@saleor/macaw-ui";
-
-export const useStyles = makeStyles(
- theme => ({
- cancel: {
- marginRight: theme.spacing(1),
- },
- copy: {
- marginTop: theme.spacing(),
- marginRight: theme.spacing(),
- position: "relative",
- right: theme.spacing(1),
- },
- mono: {
- fontFamily:
- "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace",
- fontSize: theme.typography.caption.fontSize,
- },
- paper: {
- background: alpha(theme.palette.primary.main, 0.05),
- padding: theme.spacing(2, 3),
- whiteSpace: "pre-wrap",
- },
- }),
- {
- name: "TokenCreateDialog",
- },
-);
diff --git a/src/custom-apps/components/TokenDeleteDialog/TokenDeleteDialog.tsx b/src/custom-apps/components/TokenDeleteDialog/TokenDeleteDialog.tsx
index 65b0097b752..419ea8e4e57 100644
--- a/src/custom-apps/components/TokenDeleteDialog/TokenDeleteDialog.tsx
+++ b/src/custom-apps/components/TokenDeleteDialog/TokenDeleteDialog.tsx
@@ -1,6 +1,5 @@
import ActionDialog from "@dashboard/components/ActionDialog";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
-import { DialogContentText } from "@material-ui/core";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -34,16 +33,14 @@ const TokenDeleteDialog: React.FC = ({
description: "dialog title",
})}
>
-
- {name},
- }}
- />
-
+ {name},
+ }}
+ />
);
};
diff --git a/src/custom-apps/components/WebhookDeleteDialog/WebhookDeleteDialog.tsx b/src/custom-apps/components/WebhookDeleteDialog/WebhookDeleteDialog.tsx
index 15ce91a44f2..97c849f7057 100644
--- a/src/custom-apps/components/WebhookDeleteDialog/WebhookDeleteDialog.tsx
+++ b/src/custom-apps/components/WebhookDeleteDialog/WebhookDeleteDialog.tsx
@@ -1,6 +1,5 @@
import ActionDialog from "@dashboard/components/ActionDialog";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
-import { DialogContentText } from "@material-ui/core";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -34,24 +33,22 @@ const WebhookDeleteDialog: React.FC = ({
})}
variant="delete"
>
-
- {!name ? (
-
- ) : (
- {name},
- }}
- />
- )}
-
+ {!name ? (
+
+ ) : (
+ {name},
+ }}
+ />
+ )}
);
};
diff --git a/src/custom-apps/components/WebhookEvents/WebhookEvents.tsx b/src/custom-apps/components/WebhookEvents/WebhookEvents.tsx
index bf29577158e..c6bdb10883c 100644
--- a/src/custom-apps/components/WebhookEvents/WebhookEvents.tsx
+++ b/src/custom-apps/components/WebhookEvents/WebhookEvents.tsx
@@ -1,12 +1,12 @@
// @ts-strict-ignore
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import Grid from "@dashboard/components/Grid";
import Hr from "@dashboard/components/Hr";
import { Pill } from "@dashboard/components/Pill";
import { WebhookEventTypeAsyncEnum, WebhookEventTypeSyncEnum } from "@dashboard/graphql";
import { ChangeEvent } from "@dashboard/hooks/useForm";
import { capitalize } from "@dashboard/misc";
-import { Card, CardContent, Checkbox, Typography } from "@material-ui/core";
+import { Checkbox } from "@material-ui/core";
import {
List,
ListBody,
@@ -18,6 +18,7 @@ import {
PageTabs,
useListWidths,
} from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import React, { Dispatch, SetStateAction, useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -73,23 +74,25 @@ const WebhookEvents: React.FC = ({
return (
<>
-
-
-
+
+
+ {intl.formatMessage(messages.webhookEvents)}
+
+
-
+
-
-
+
+
@@ -160,7 +163,7 @@ const WebhookEvents: React.FC = ({
-
+
>
);
};
diff --git a/src/custom-apps/components/WebhookHeaders/WebhookHeaders.tsx b/src/custom-apps/components/WebhookHeaders/WebhookHeaders.tsx
index 27a4909bb04..ab5c81b9c48 100644
--- a/src/custom-apps/components/WebhookHeaders/WebhookHeaders.tsx
+++ b/src/custom-apps/components/WebhookHeaders/WebhookHeaders.tsx
@@ -1,18 +1,8 @@
-import { Button } from "@dashboard/components/Button";
-import CardTitle from "@dashboard/components/CardTitle";
-import Skeleton from "@dashboard/components/Skeleton";
+import { DashboardCard } from "@dashboard/components/Card";
import TableRowLink from "@dashboard/components/TableRowLink";
import { FormChange } from "@dashboard/hooks/useForm";
-import {
- Card,
- CardActions,
- CardContent,
- Table,
- TableCell,
- TableHead,
- Typography,
-} from "@material-ui/core";
-import { ExpandIcon, IconButton } from "@saleor/macaw-ui";
+import { Table, TableCell, TableHead } from "@material-ui/core";
+import { Button, ChervonDownIcon, Skeleton, Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React, { useEffect, useMemo, useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -53,64 +43,66 @@ const WebhookHeaders: React.FC = ({ data: { customHeaders }
};
return (
-
-
- {intl.formatMessage(messages.header)}
- setExpanded(!expanded)}
- >
-
-
- >
- }
- />
+
+
+
+ {intl.formatMessage(messages.header)}
+ setExpanded(!expanded)}
+ >
+
+
+
+
+
{headers === undefined ? (
-
+
-
+
) : (
<>
-
+
{headers.length > 0 && (
-
+
-
+
)}
-
+
{expanded && (
<>
{headers.length === 0 ? (
-
-
+
+
-
-
+
+
) : (
<>
-
-
+
+
{chunks}
,
}}
/>
-
-
+
+
@@ -130,7 +122,7 @@ const WebhookHeaders: React.FC = ({ data: { customHeaders }
>
)}
-
+
= ({ data: { customHeaders }
>
-
+
>
)}
>
)}
-
+
);
};
diff --git a/src/custom-apps/components/WebhookHeaders/styles.ts b/src/custom-apps/components/WebhookHeaders/styles.ts
index f9e24e89fde..cbde74d13a1 100644
--- a/src/custom-apps/components/WebhookHeaders/styles.ts
+++ b/src/custom-apps/components/WebhookHeaders/styles.ts
@@ -42,13 +42,6 @@ const useStyles = makeStyles(
...colName,
},
colValue: {},
- actions: {
- "&&": {
- paddingBottom: theme.spacing(2),
- paddingTop: theme.spacing(2),
- paddingLeft: theme.spacing(4),
- },
- },
content: {
paddingBottom: 0,
paddingTop: theme.spacing(),
@@ -57,20 +50,6 @@ const useStyles = makeStyles(
paddingBottom: 0,
paddingTop: 0,
},
- expandBtn: {
- position: "relative",
- left: theme.spacing(1),
- top: -2,
- transition: theme.transitions.create("transform", {
- duration: theme.transitions.duration.shorter,
- }),
- border: 0,
- },
- header: {
- "&&": {
- paddingBottom: theme.spacing(1),
- },
- },
input: {
padding: theme.spacing(1.5, 2),
},
@@ -82,9 +61,6 @@ const useStyles = makeStyles(
padding: 0,
},
},
- rotate: {
- transform: "rotate(-180deg)",
- },
};
},
{
diff --git a/src/custom-apps/components/WebhookInfo/WebhookInfo.tsx b/src/custom-apps/components/WebhookInfo/WebhookInfo.tsx
index 7c68ba2b069..c51b43e759f 100644
--- a/src/custom-apps/components/WebhookInfo/WebhookInfo.tsx
+++ b/src/custom-apps/components/WebhookInfo/WebhookInfo.tsx
@@ -1,4 +1,4 @@
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import FormSpacer from "@dashboard/components/FormSpacer";
import Hr from "@dashboard/components/Hr";
import Link from "@dashboard/components/Link";
@@ -7,7 +7,8 @@ import { WebhookErrorFragment } from "@dashboard/graphql";
import { commonMessages } from "@dashboard/intl";
import { getFormErrors } from "@dashboard/utils/errors";
import getWebhookErrorMessage from "@dashboard/utils/errors/webhooks";
-import { Card, CardContent, Popper, TextField, Typography } from "@material-ui/core";
+import { Popper, TextField } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -30,15 +31,15 @@ const WebhookInfo: React.FC = ({ data, disabled, errors, onCha
const anchor = React.useRef(null);
return (
-
-
-
-
+
+
+ {intl.formatMessage(messages.webhookInformation)}
+
+
+
+
{intl.formatMessage(commonMessages.generalInformations)}
-
+
= ({ data, disabled, errors, onCha
size="small"
/>
-
-
+
+
-
+
= ({ data, disabled, errors, onCha
>
-
+
),
}}
/>
-
-
+
+
);
};
diff --git a/src/custom-apps/components/WebhookInfo/styles.ts b/src/custom-apps/components/WebhookInfo/styles.ts
index ac56d28b8b3..7b32fa0748c 100644
--- a/src/custom-apps/components/WebhookInfo/styles.ts
+++ b/src/custom-apps/components/WebhookInfo/styles.ts
@@ -8,9 +8,6 @@ export const useStyles = makeStyles(
color: theme.palette.common.black,
marginBottom: theme.spacing(2),
},
- cardTitle: {
- paddingLeft: 0,
- },
card: {
paddingLeft: 0,
},
diff --git a/src/custom-apps/components/WebhookSubscriptionQuery/WebhookSubscriptionQuery.tsx b/src/custom-apps/components/WebhookSubscriptionQuery/WebhookSubscriptionQuery.tsx
index 99779cd6720..d89957e7a4d 100644
--- a/src/custom-apps/components/WebhookSubscriptionQuery/WebhookSubscriptionQuery.tsx
+++ b/src/custom-apps/components/WebhookSubscriptionQuery/WebhookSubscriptionQuery.tsx
@@ -1,13 +1,11 @@
// @ts-strict-ignore
import "graphiql/graphiql.min.css";
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import { WebhookErrorFragment } from "@dashboard/graphql";
import { getFormErrors } from "@dashboard/utils/errors";
import { useExplorerPlugin } from "@graphiql/plugin-explorer";
import { createGraphiQLFetcher } from "@graphiql/toolkit";
-import { Card, CardContent } from "@material-ui/core";
-import clsx from "clsx";
import React from "react";
import { defineMessages, useIntl } from "react-intl";
@@ -49,13 +47,15 @@ const WebhookSubscriptionQuery: React.FC = ({
const formErrors = getFormErrors(["subscriptionQuery"], errors);
return (
-
-
-
+
+
+
+ {intl.formatMessage(messages.title)}
+
+ {formErrors.subscriptionQuery?.message}
+
+
+
= ({
isHeadersEditorEnabled={false}
data={data}
/>
-
-
+
+
);
};
diff --git a/src/custom-apps/components/WebhookSubscriptionQuery/styles.ts b/src/custom-apps/components/WebhookSubscriptionQuery/styles.ts
index 58fb2872467..a6e3fe1e244 100644
--- a/src/custom-apps/components/WebhookSubscriptionQuery/styles.ts
+++ b/src/custom-apps/components/WebhookSubscriptionQuery/styles.ts
@@ -1,5 +1,4 @@
import { makeStyles } from "@saleor/macaw-ui";
-import { vars } from "@saleor/macaw-ui-next";
export const useStyles = makeStyles(
theme => ({
@@ -17,12 +16,6 @@ export const useStyles = makeStyles(
cardTitle: {
paddingLeft: 0,
},
- error: {
- color: vars.colors.text.critical1,
- "& .MuiTypography-colorTextSecondary": {
- color: vars.colors.text.critical1,
- },
- },
}),
{ name: "WebhookSubscriptionQuery" },
);
diff --git a/src/custom-apps/components/WebhooksList/WebhooksList.tsx b/src/custom-apps/components/WebhooksList/WebhooksList.tsx
index ccf03f62d76..2e372fe30ec 100644
--- a/src/custom-apps/components/WebhooksList/WebhooksList.tsx
+++ b/src/custom-apps/components/WebhooksList/WebhooksList.tsx
@@ -1,8 +1,7 @@
import { Button } from "@dashboard/components/Button";
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import { Pill } from "@dashboard/components/Pill";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
-import Skeleton from "@dashboard/components/Skeleton";
import { TableButtonWrapper } from "@dashboard/components/TableButtonWrapper/TableButtonWrapper";
import TableCellHeader from "@dashboard/components/TableCellHeader";
import TableRowLink from "@dashboard/components/TableRowLink";
@@ -11,8 +10,9 @@ import { isUnnamed } from "@dashboard/custom-apps/utils";
import { WebhookFragment } from "@dashboard/graphql";
import { commonMessages, commonStatusMessages, sectionNames } from "@dashboard/intl";
import { renderCollection, stopPropagation } from "@dashboard/misc";
-import { Card, CardContent, TableBody, TableCell, TableHead } from "@material-ui/core";
+import { TableBody, TableCell, TableHead } from "@material-ui/core";
import { DeleteIcon, IconButton } from "@saleor/macaw-ui";
+import { Skeleton } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -32,19 +32,20 @@ const WebhooksList: React.FC = ({ webhooks, createHref, onRem
const numberOfColumns = webhooks?.length === 0 ? 2 : 3;
return (
-
-
+
+
+ {intl.formatMessage(sectionNames.webhooksAndEvents)}
+
+
+ {!!createHref && (
- )
- }
- />
-
+ )}
+
+
+
@@ -113,8 +114,8 @@ const WebhooksList: React.FC = ({ webhooks, createHref, onRem
)}
-
-
+
+
);
};
diff --git a/src/custom-apps/index.tsx b/src/custom-apps/index.tsx
index 20811d8603b..021aae61d6f 100644
--- a/src/custom-apps/index.tsx
+++ b/src/custom-apps/index.tsx
@@ -1,10 +1,11 @@
// @ts-strict-ignore
+import { Route } from "@dashboard/components/Router";
import { WindowTitle } from "@dashboard/components/WindowTitle";
import { sectionNames } from "@dashboard/intl";
import { parse as parseQs } from "qs";
import React from "react";
import { useIntl } from "react-intl";
-import { Route, RouteComponentProps, Switch } from "react-router-dom";
+import { RouteComponentProps, Switch } from "react-router-dom";
import {
CustomAppDetailsUrlQueryParams,
diff --git a/src/custom-apps/views/CustomAppList.tsx b/src/custom-apps/views/CustomAppList.tsx
index dca409a1487..ad58621fa3f 100644
--- a/src/custom-apps/views/CustomAppList.tsx
+++ b/src/custom-apps/views/CustomAppList.tsx
@@ -16,7 +16,8 @@ import { sectionNames } from "@dashboard/intl";
import { findById } from "@dashboard/misc";
import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHandlers";
import { mapEdgesToItems } from "@dashboard/utils/maps";
-import React from "react";
+import { useOnboarding } from "@dashboard/welcomePage/WelcomePageOnboarding/onboardingContext";
+import React, { useEffect } from "react";
import { useIntl } from "react-intl";
import CustomAppListPage from "../components/CustomAppListPage";
@@ -32,6 +33,12 @@ export const CustomAppList: React.FC = ({ params }) => {
const notify = useNotifier();
const intl = useIntl();
const client = useApolloClient();
+ const { markOnboardingStepAsCompleted } = useOnboarding();
+
+ useEffect(() => {
+ markOnboardingStepAsCompleted("view-webhooks");
+ }, []);
+
const [openModal, closeModal] = createDialogActionHandlers<
CustomAppListUrlDialog,
CustomAppListUrlQueryParams
diff --git a/src/customers/components/CustomerAddress/CustomerAddress.tsx b/src/customers/components/CustomerAddress/CustomerAddress.tsx
index 0cc8cc82807..bea3776ec43 100644
--- a/src/customers/components/CustomerAddress/CustomerAddress.tsx
+++ b/src/customers/components/CustomerAddress/CustomerAddress.tsx
@@ -1,11 +1,10 @@
// @ts-strict-ignore
import AddressFormatter from "@dashboard/components/AddressFormatter";
+import { DashboardCard } from "@dashboard/components/Card";
import CardMenu from "@dashboard/components/CardMenu";
-import CardTitle from "@dashboard/components/CardTitle";
-import Skeleton from "@dashboard/components/Skeleton";
import { AddressFragment, AddressTypeEnum } from "@dashboard/graphql";
-import { Card, CardContent } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
+import { Skeleton } from "@saleor/macaw-ui-next";
import React from "react";
import { defineMessages, useIntl } from "react-intl";
@@ -88,11 +87,10 @@ const CustomerAddress: React.FC = props => {
const intl = useIntl();
return (
-
-
+
+
+ {address ? (
<>
{isDefaultBillingAddress && isDefaultShippingAddress
? intl.formatMessage(messages.defaultAddress)
@@ -104,9 +102,9 @@ const CustomerAddress: React.FC = props => {
>
) : (
- )
- }
- toolbar={
+ )}
+
+
= props => {
},
]}
/>
- }
- />
-
+
+
+
-
-
+
+
);
};
diff --git a/src/customers/components/CustomerAddressChoiceCard/CustomerAddressChoiceCard.tsx b/src/customers/components/CustomerAddressChoiceCard/CustomerAddressChoiceCard.tsx
index 5efd4fef59c..06a83901262 100644
--- a/src/customers/components/CustomerAddressChoiceCard/CustomerAddressChoiceCard.tsx
+++ b/src/customers/components/CustomerAddressChoiceCard/CustomerAddressChoiceCard.tsx
@@ -1,9 +1,10 @@
// @ts-strict-ignore
import AddressFormatter from "@dashboard/components/AddressFormatter";
+import { DashboardCard } from "@dashboard/components/Card";
import { AddressFragment } from "@dashboard/graphql";
import { commonMessages } from "@dashboard/intl";
-import { Card, CardContent, Typography } from "@material-ui/core";
import { EditIcon } from "@saleor/macaw-ui";
+import { Text } from "@saleor/macaw-ui-next";
import clsx from "clsx";
import React from "react";
import { useIntl } from "react-intl";
@@ -24,14 +25,14 @@ const CustomerAddressChoiceCard: React.FC = prop
const intl = useIntl();
return (
-
-
+
{editable && (
@@ -39,12 +40,12 @@ const CustomerAddressChoiceCard: React.FC = prop
)}
{selected && (
-
+
{intl.formatMessage(commonMessages.selected)}
-
+
)}
-
-
+
+
);
};
diff --git a/src/customers/components/CustomerAddressDialog/CustomerAddressDialog.tsx b/src/customers/components/CustomerAddressDialog/CustomerAddressDialog.tsx
index 354951bdf72..d7152c5b9fb 100644
--- a/src/customers/components/CustomerAddressDialog/CustomerAddressDialog.tsx
+++ b/src/customers/components/CustomerAddressDialog/CustomerAddressDialog.tsx
@@ -3,7 +3,7 @@ import { createCountryHandler } from "@dashboard/components/AddressEdit/createCo
import BackButton from "@dashboard/components/BackButton";
import { ConfirmButton, ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
import Form from "@dashboard/components/Form";
-import { DASHBOARD_MODAL_WIDTH, DashboardModal } from "@dashboard/components/Modal";
+import { DashboardModal } from "@dashboard/components/Modal";
import {
AccountErrorFragment,
AddressFragment,
@@ -64,62 +64,64 @@ const CustomerAddressDialog: React.FC = ({
return (
- {
- setCountryDisplayName("");
- handleSubmit(data);
- }}
- >
- {({ change, set, data, submit }) => {
- const countrySelect = createSingleAutocompleteSelectHandler(
- change,
- setCountryDisplayName,
- countryChoices,
- );
- const handleCountrySelect = createCountryHandler(countrySelect, set);
+
+ {
+ setCountryDisplayName("");
+ handleSubmit(data);
+ }}
+ >
+ {({ change, set, data, submit }) => {
+ const countrySelect = createSingleAutocompleteSelectHandler(
+ change,
+ setCountryDisplayName,
+ countryChoices,
+ );
+ const handleCountrySelect = createCountryHandler(countrySelect, set);
- return (
-
-
- {variant === "create" ? (
-
- ) : (
-
- )}
-
+ return (
+
+
+ {variant === "create" ? (
+
+ ) : (
+
+ )}
+
-
+
-
-
-
-
-
-
-
- );
- }}
-
+
+
+
+
+
+
+
+ );
+ }}
+
+
);
};
diff --git a/src/customers/components/CustomerAddressListPage/CustomerAddressListPage.tsx b/src/customers/components/CustomerAddressListPage/CustomerAddressListPage.tsx
index 1a02f263318..649748f5bb7 100644
--- a/src/customers/components/CustomerAddressListPage/CustomerAddressListPage.tsx
+++ b/src/customers/components/CustomerAddressListPage/CustomerAddressListPage.tsx
@@ -1,13 +1,11 @@
// @ts-strict-ignore
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
-import { Button } from "@dashboard/components/Button";
import { ListPageLayout } from "@dashboard/components/Layouts";
import { customerUrl } from "@dashboard/customers/urls";
import { AddressTypeEnum, CustomerAddressesFragment } from "@dashboard/graphql";
import { getStringOrPlaceholder, renderCollection } from "@dashboard/misc";
-import { Typography } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
-import { Box } from "@saleor/macaw-ui-next";
+import { Box, Button, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { defineMessages, useIntl } from "react-intl";
@@ -117,10 +115,12 @@ const CustomerAddressListPage: React.FC = props =>
padding={6}
flexDirection="column"
>
- {intl.formatMessage(messages.noAddressToShow)}
-
+
+ {intl.formatMessage(messages.noAddressToShow)}
+
+
{intl.formatMessage(messages.doesntHaveAddresses)}
-
+
{intl.formatMessage(messages.addAddress)}
diff --git a/src/customers/components/CustomerAddresses/CustomerAddresses.tsx b/src/customers/components/CustomerAddresses/CustomerAddresses.tsx
index 3e6dda27c80..873bcf22539 100644
--- a/src/customers/components/CustomerAddresses/CustomerAddresses.tsx
+++ b/src/customers/components/CustomerAddresses/CustomerAddresses.tsx
@@ -1,14 +1,14 @@
// @ts-strict-ignore
import AddressFormatter from "@dashboard/components/AddressFormatter";
-import { Button } from "@dashboard/components/Button";
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import { Hr } from "@dashboard/components/Hr";
import { CustomerDetailsFragment } from "@dashboard/graphql";
import { buttonMessages } from "@dashboard/intl";
-import { Card, CardContent, Typography } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
+import { Button, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
+import { Link } from "react-router-dom";
import { maybe } from "../../../misc";
@@ -34,73 +34,72 @@ const CustomerAddresses: React.FC = props => {
const intl = useIntl();
return (
-
-
-
-
- }
- />
+
+
+
+ {intl.formatMessage({
+ id: "BfJGij",
+ defaultMessage: "Address Information",
+ description: "header",
+ })}
+
+
+
+
+
+
+
+
+
{maybe(() => customer.defaultBillingAddress.id) !==
maybe(() => customer.defaultShippingAddress.id) ? (
<>
{maybe(() => customer.defaultBillingAddress) !== null && (
-
-
+
+
-
+
customer.defaultBillingAddress)} />
-
+
)}
{maybe(() => customer.defaultBillingAddress && customer.defaultShippingAddress) && }
{maybe(() => customer.defaultShippingAddress) && (
-
-
+
+
-
+
customer.defaultShippingAddress)} />
-
+
)}
>
) : maybe(() => customer.defaultBillingAddress) === null &&
maybe(() => customer.defaultShippingAddress) === null ? (
-
-
+
+
-
-
+
+
) : (
-
-
+
+
-
+
customer.defaultBillingAddress)} />
-
+
)}
-
+
);
};
diff --git a/src/customers/components/CustomerCreateAddress/CustomerCreateAddress.tsx b/src/customers/components/CustomerCreateAddress/CustomerCreateAddress.tsx
index 1435b019043..1311e0271b7 100644
--- a/src/customers/components/CustomerCreateAddress/CustomerCreateAddress.tsx
+++ b/src/customers/components/CustomerCreateAddress/CustomerCreateAddress.tsx
@@ -1,12 +1,10 @@
// @ts-strict-ignore
import AddressEdit from "@dashboard/components/AddressEdit";
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import { FormSpacer } from "@dashboard/components/FormSpacer";
-import { SingleAutocompleteChoiceType } from "@dashboard/components/SingleAutocompleteSelectField";
import { AccountErrorFragment } from "@dashboard/graphql";
-import { Card, CardContent, Typography } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
-import { Box } from "@saleor/macaw-ui-next";
+import { Box, Option, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -22,7 +20,7 @@ const useStyles = makeStyles(
);
export interface CustomerCreateAddressProps {
- countries: SingleAutocompleteChoiceType[];
+ countries: Option[];
countryDisplayName: string;
data: AddressTypeInput;
disabled: boolean;
@@ -38,18 +36,20 @@ const CustomerCreateAddress: React.FC = props => {
const intl = useIntl();
return (
-
-
-
-
+
+
+
+ {intl.formatMessage({
+ id: "jGGnSZ",
+ defaultMessage: "Primary Address",
+ description: "page header",
+ })}
+
+
+
+
-
+
= props => {
onCountryChange={onCountryChange}
/>
-
-
+
+
);
};
diff --git a/src/customers/components/CustomerCreateDetails/CustomerCreateDetails.tsx b/src/customers/components/CustomerCreateDetails/CustomerCreateDetails.tsx
index 913654c20c1..01f8a53fe80 100644
--- a/src/customers/components/CustomerCreateDetails/CustomerCreateDetails.tsx
+++ b/src/customers/components/CustomerCreateDetails/CustomerCreateDetails.tsx
@@ -1,10 +1,10 @@
// @ts-strict-ignore
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import { AccountErrorFragment } from "@dashboard/graphql";
import { commonMessages } from "@dashboard/intl";
import { getFormErrors } from "@dashboard/utils/errors";
import getAccountErrorMessage from "@dashboard/utils/errors/account";
-import { Card, CardContent, TextField } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
import React from "react";
import { useIntl } from "react-intl";
@@ -39,15 +39,17 @@ const CustomerCreateDetails: React.FC = props => {
const formErrors = getFormErrors(["customerFirstName", "customerLastName", "email"], errors);
return (
-
-
-
+
+
+
+ {intl.formatMessage({
+ id: "fjPWOA",
+ defaultMessage: "Customer Overview",
+ description: "header",
+ })}
+
+
+
= props => {
}}
/>
-
-
+
+
);
};
diff --git a/src/customers/components/CustomerCreateNote/CustomerCreateNote.tsx b/src/customers/components/CustomerCreateNote/CustomerCreateNote.tsx
index d98c853fbad..031164c5d50 100644
--- a/src/customers/components/CustomerCreateNote/CustomerCreateNote.tsx
+++ b/src/customers/components/CustomerCreateNote/CustomerCreateNote.tsx
@@ -1,10 +1,11 @@
// @ts-strict-ignore
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import { FormSpacer } from "@dashboard/components/FormSpacer";
import { AccountErrorFragment } from "@dashboard/graphql";
import { getFormErrors } from "@dashboard/utils/errors";
import getAccountErrorMessage from "@dashboard/utils/errors/account";
-import { Card, CardContent, TextField, Typography } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -28,21 +29,23 @@ const CustomerCreateNote: React.FC = ({
const formErrors = getFormErrors(["note"], errors);
return (
-
-
-
-
+
+
+
+ {intl.formatMessage({
+ id: "qNcoRY",
+ defaultMessage: "Notes",
+ description: "notes about customer header",
+ })}
+
+
+
+
-
+
= ({
value={data.note}
onChange={onChange}
/>
-
-
+
+
);
};
diff --git a/src/customers/components/CustomerDetails/CustomerDetails.tsx b/src/customers/components/CustomerDetails/CustomerDetails.tsx
index 26366dcc958..8fd18b46f88 100644
--- a/src/customers/components/CustomerDetails/CustomerDetails.tsx
+++ b/src/customers/components/CustomerDetails/CustomerDetails.tsx
@@ -1,13 +1,12 @@
// @ts-strict-ignore
-import CardTitle from "@dashboard/components/CardTitle";
-import { ControlledCheckbox } from "@dashboard/components/ControlledCheckbox";
-import Skeleton from "@dashboard/components/Skeleton";
+import { DashboardCard } from "@dashboard/components/Card";
import { AccountErrorFragment, CustomerDetailsQuery } from "@dashboard/graphql";
import { maybe } from "@dashboard/misc";
import { getFormErrors } from "@dashboard/utils/errors";
import getAccountErrorMessage from "@dashboard/utils/errors/account";
-import { Card, CardContent, TextField, Typography } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
+import { Checkbox, Skeleton, Text } from "@saleor/macaw-ui-next";
import moment from "moment-timezone";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -50,14 +49,18 @@ const CustomerDetails: React.FC = props => {
const formErrors = getFormErrors(["note"], errors);
return (
-
-
+
+
<>
{maybe(() => customer.email, )}
{customer && customer.dateJoined ? (
-
+
= props => {
date: moment(customer.dateJoined).format("MMM YYYY"),
}}
/>
-
+
) : (
)}
>
- }
- />
-
-
+
+
+
+ onCheckedChange={value => {
+ onChange({
+ target: {
+ name: "isActive",
+ value,
+ },
+ } as React.ChangeEvent);
+ }}
+ >
+
+ {intl.formatMessage({
+ id: "+NUzaQ",
+ defaultMessage: "User account active",
+ description: "check to mark this account as active",
+ })}
+
+
= props => {
value={data.note}
onChange={onChange}
/>
-
-
+
+
);
};
diff --git a/src/customers/components/CustomerDetailsPage/CustomerDetailsPage.tsx b/src/customers/components/CustomerDetailsPage/CustomerDetailsPage.tsx
index 0eb79f48c20..8115a2c38fb 100644
--- a/src/customers/components/CustomerDetailsPage/CustomerDetailsPage.tsx
+++ b/src/customers/components/CustomerDetailsPage/CustomerDetailsPage.tsx
@@ -15,9 +15,10 @@ import { Metadata } from "@dashboard/components/Metadata/Metadata";
import { MetadataFormData } from "@dashboard/components/Metadata/types";
import RequirePermissions from "@dashboard/components/RequirePermissions";
import { Savebar } from "@dashboard/components/Savebar";
-import { customerAddressesUrl, customerListUrl } from "@dashboard/customers/urls";
+import { customerAddressesUrl, customerListPath } from "@dashboard/customers/urls";
import CustomerGiftCardsCard from "@dashboard/giftCards/components/GiftCardCustomerCard/CustomerGiftCardsCard";
import { AccountErrorFragment, CustomerDetailsQuery, PermissionEnum } from "@dashboard/graphql";
+import { useBackLinkWithState } from "@dashboard/hooks/useBackLinkWithState";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import useNavigator from "@dashboard/hooks/useNavigator";
import { sectionNames } from "@dashboard/intl";
@@ -70,7 +71,9 @@ const CustomerDetailsPage: React.FC = ({
lastName: customer?.lastName || "",
metadata: customer?.metadata.map(mapMetadataItemToInput),
note: customer?.note || "",
- privateMetadata: customer?.privateMetadata.map(mapMetadataItemToInput),
+ privateMetadata: customer?.privateMetadata
+ ? customer?.privateMetadata.map(mapMetadataItemToInput)
+ : [],
};
const { makeChangeHandler: makeMetadataChangeHandler } = useMetadataChangeTrigger();
const { CUSTOMER_DETAILS_MORE_ACTIONS } = useExtensions(extensionMountPoints.CUSTOMER_DETAILS);
@@ -79,6 +82,10 @@ const CustomerDetailsPage: React.FC = ({
customerId,
);
+ const customerBackLink = useBackLinkWithState({
+ path: customerListPath,
+ });
+
return (
{({ change, data, isSaveDisabled, submit }) => {
@@ -86,11 +93,11 @@ const CustomerDetailsPage: React.FC = ({
return (
-
+
{extensionMenuItems.length > 0 && }
-
+
{intl.formatMessage(sectionNames.customers)}
= ({
- navigate(customerListUrl())} />
+ navigate(customerBackLink)} />
= props => {
const formErrors = getFormErrors(["firstName", "lastName", "email"], errors);
return (
-
-
+
+
- }
- />
-
-
+
+
+
+
-
+
= props => {
/>
-
+
-
+
= props => {
spellCheck: false,
}}
/>
-
-
+
+
);
};
diff --git a/src/customers/components/CustomerListDatagrid/CustomerListDatagrid.tsx b/src/customers/components/CustomerListDatagrid/CustomerListDatagrid.tsx
index 11acbf11110..90c1bbf0278 100644
--- a/src/customers/components/CustomerListDatagrid/CustomerListDatagrid.tsx
+++ b/src/customers/components/CustomerListDatagrid/CustomerListDatagrid.tsx
@@ -10,11 +10,13 @@ import { TablePaginationWithContext } from "@dashboard/components/TablePaginatio
import { Customer, Customers } from "@dashboard/customers/types";
import { CustomerListUrlSortField } from "@dashboard/customers/urls";
import { PermissionEnum } from "@dashboard/graphql";
+import { getPrevLocationState } from "@dashboard/hooks/useBackLinkWithState";
import { ListProps, SortPage } from "@dashboard/types";
import { Item } from "@glideapps/glide-data-grid";
import { Box } from "@saleor/macaw-ui-next";
import React, { useCallback, useMemo } from "react";
import { useIntl } from "react-intl";
+import { useLocation } from "react-router";
import { createGetCellContent, customerListStaticColumnsAdapter } from "./datagrid";
import { messages } from "./messages";
@@ -42,6 +44,7 @@ export const CustomerListDatagrid = ({
onSort,
}: CustomerListDatagridProps) => {
const intl = useIntl();
+ const location = useLocation();
const datagrid = useDatagridChangeState();
const userPermissions = useUserPermissions();
const hasManageOrdersPermission =
@@ -135,6 +138,7 @@ export const CustomerListDatagrid = ({
onToggle={handlers.onToggle}
/>
)}
+ navigatorOpts={{ state: getPrevLocationState(location) }}
/>
diff --git a/src/customers/components/CustomerListPage/CustomerListPage.tsx b/src/customers/components/CustomerListPage/CustomerListPage.tsx
index dca7d85656e..39fba77f8ed 100644
--- a/src/customers/components/CustomerListPage/CustomerListPage.tsx
+++ b/src/customers/components/CustomerListPage/CustomerListPage.tsx
@@ -13,6 +13,7 @@ import { ButtonWithDropdown } from "@dashboard/components/ButtonWithDropdown";
import { FilterPresetsSelect } from "@dashboard/components/FilterPresetsSelect";
import { Customers } from "@dashboard/customers/types";
import { customerAddUrl, CustomerListUrlSortField, customerUrl } from "@dashboard/customers/urls";
+import { useFlag } from "@dashboard/featureFlags";
import useNavigator from "@dashboard/hooks/useNavigator";
import { sectionNames } from "@dashboard/intl";
import { FilterPagePropsWithPresets, PageListProps, SortPage } from "@dashboard/types";
@@ -56,6 +57,7 @@ const CustomerListPage: React.FC = ({
const userPermissions = useUserPermissions();
const structure = createFilterStructure(intl, filterOpts, userPermissions);
const [isFilterPresetOpen, setFilterPresetOpen] = useState(false);
+ const { enabled: isCustomersFiltersEnabled } = useFlag("new_filters");
const { CUSTOMER_OVERVIEW_CREATE, CUSTOMER_OVERVIEW_MORE_ACTIONS } = useExtensions(
extensionMountPoints.CUSTOMER_LIST,
);
@@ -122,25 +124,46 @@ const CustomerListPage: React.FC = ({
-
- {selectedCustomerIds.length > 0 && (
-
-
-
- )}
-
- }
- />
+ {isCustomersFiltersEnabled ? (
+
+ {selectedCustomerIds.length > 0 && (
+
+
+
+ )}
+
+ }
+ />
+ ) : (
+
+ {selectedCustomerIds.length > 0 && (
+
+
+
+ )}
+
+ }
+ />
+ )}
= props => {
: undefined;
return (
-
-
-
-
- }
- />
+
+
+
+ {intl.formatMessage({
+ id: "1LiVhv",
+ defaultMessage: "Recent Orders",
+ description: "section header",
+ })}
+
+
+
+
+
+
+
+
+
@@ -139,7 +143,7 @@ const CustomerOrders: React.FC = props => {
)}
-
+
);
};
diff --git a/src/customers/components/CustomerStats/CustomerStats.tsx b/src/customers/components/CustomerStats/CustomerStats.tsx
index 1e740587b41..2ed77e95f51 100644
--- a/src/customers/components/CustomerStats/CustomerStats.tsx
+++ b/src/customers/components/CustomerStats/CustomerStats.tsx
@@ -1,9 +1,8 @@
import { DashboardCard } from "@dashboard/components/Card";
import { DateTime } from "@dashboard/components/Date";
import RequirePermissions from "@dashboard/components/RequirePermissions";
-import Skeleton from "@dashboard/components/Skeleton";
import { CustomerDetailsQuery, PermissionEnum } from "@dashboard/graphql";
-import { Divider, Text } from "@saleor/macaw-ui-next";
+import { Divider, Skeleton, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -17,13 +16,15 @@ const CustomerStats: React.FC = props => {
return (
-
- {intl.formatMessage({
- id: "e7Nyu7",
- defaultMessage: "Customer History",
- description: "section header",
- })}
-
+
+
+ {intl.formatMessage({
+ id: "e7Nyu7",
+ defaultMessage: "Customer History",
+ description: "section header",
+ })}
+
+
diff --git a/src/customers/index.tsx b/src/customers/index.tsx
index 88135030594..fe92863f418 100644
--- a/src/customers/index.tsx
+++ b/src/customers/index.tsx
@@ -1,9 +1,11 @@
+import { ConditionalCustomerFilterProvider } from "@dashboard/components/ConditionalFilter";
+import { Route } from "@dashboard/components/Router";
import { sectionNames } from "@dashboard/intl";
import { asSortParams } from "@dashboard/utils/sort";
import { parse as parseQs } from "qs";
import React from "react";
import { useIntl } from "react-intl";
-import { Route, RouteComponentProps, Switch } from "react-router-dom";
+import { RouteComponentProps, Switch } from "react-router-dom";
import { WindowTitle } from "../components/WindowTitle";
import {
@@ -25,7 +27,11 @@ const CustomerListView: React.FC> = ({ location }) => {
const qs = parseQs(location.search.substr(1)) as any;
const params: CustomerListUrlQueryParams = asSortParams(qs, CustomerListUrlSortField);
- return ;
+ return (
+
+
+
+ );
};
interface CustomerDetailsRouteParams {
diff --git a/src/customers/queries.ts b/src/customers/queries.ts
index 92eb6134eb6..62f9ef14d00 100644
--- a/src/customers/queries.ts
+++ b/src/customers/queries.ts
@@ -37,9 +37,19 @@ export const customerList = gql`
`;
export const customerDetails = gql`
- query CustomerDetails($id: ID!, $PERMISSION_MANAGE_ORDERS: Boolean!) {
+ query CustomerDetails(
+ $id: ID!
+ $PERMISSION_MANAGE_ORDERS: Boolean!
+ $PERMISSION_MANAGE_STAFF: Boolean!
+ ) {
user(id: $id) {
...CustomerDetails
+ metadata {
+ ...MetadataItem
+ }
+ privateMetadata @include(if: $PERMISSION_MANAGE_STAFF) {
+ ...MetadataItem
+ }
orders(last: 5) @include(if: $PERMISSION_MANAGE_ORDERS) {
edges {
node {
diff --git a/src/customers/views/CustomerAddresses.tsx b/src/customers/views/CustomerAddresses.tsx
index 6a0e1aa91b7..b2b83fdb182 100644
--- a/src/customers/views/CustomerAddresses.tsx
+++ b/src/customers/views/CustomerAddresses.tsx
@@ -13,7 +13,7 @@ import useNotifier from "@dashboard/hooks/useNotifier";
import useShop from "@dashboard/hooks/useShop";
import { commonMessages } from "@dashboard/intl";
import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHandlers";
-import { DialogContentText } from "@material-ui/core";
+import { Box } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -169,12 +169,12 @@ const CustomerAddresses: React.FC = ({ id, params }) =>
})
}
>
-
+
-
+
>
);
diff --git a/src/customers/views/CustomerDetails.tsx b/src/customers/views/CustomerDetails.tsx
index 95019a932d9..3969e41c216 100644
--- a/src/customers/views/CustomerDetails.tsx
+++ b/src/customers/views/CustomerDetails.tsx
@@ -13,7 +13,6 @@ import useNotifier from "@dashboard/hooks/useNotifier";
import { commonMessages } from "@dashboard/intl";
import { extractMutationErrors, getStringOrPlaceholder } from "@dashboard/misc";
import createMetadataUpdateHandler from "@dashboard/utils/handlers/metadataUpdateHandler";
-import { DialogContentText } from "@material-ui/core";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -88,7 +87,10 @@ const CustomerDetailsViewInner: React.FC = ({ id, para
);
const handleSubmit = createMetadataUpdateHandler(
- user,
+ {
+ ...user,
+ privateMetadata: user?.privateMetadata || [],
+ },
updateData,
variables => updateMetadata({ variables }),
variables => updatePrivateMetadata({ variables }),
@@ -132,16 +134,14 @@ const CustomerDetailsViewInner: React.FC = ({ id, para
variant="delete"
open={params.action === "remove"}
>
-
- {getStringOrPlaceholder(user?.email)},
- }}
- />
-
+ {getStringOrPlaceholder(user?.email)},
+ }}
+ />
>
);
diff --git a/src/customers/views/CustomerList/CustomerList.tsx b/src/customers/views/CustomerList/CustomerList.tsx
index 07de69c99e8..133eb0cbea4 100644
--- a/src/customers/views/CustomerList/CustomerList.tsx
+++ b/src/customers/views/CustomerList/CustomerList.tsx
@@ -1,7 +1,10 @@
import ActionDialog from "@dashboard/components/ActionDialog";
+import { useConditionalFilterContext } from "@dashboard/components/ConditionalFilter";
+import { createCustomerQueryVariables } from "@dashboard/components/ConditionalFilter/queryVariables";
import DeleteFilterTabDialog from "@dashboard/components/DeleteFilterTabDialog";
import SaveFilterTabDialog from "@dashboard/components/SaveFilterTabDialog";
import { WindowTitle } from "@dashboard/components/WindowTitle";
+import { useFlag } from "@dashboard/featureFlags";
import { useBulkRemoveCustomersMutation, useListCustomersQuery } from "@dashboard/graphql";
import { useFilterPresets } from "@dashboard/hooks/useFilterPresets";
import useListSettings from "@dashboard/hooks/useListSettings";
@@ -20,7 +23,6 @@ import createFilterHandlers from "@dashboard/utils/handlers/filterHandlers";
import createSortHandler from "@dashboard/utils/handlers/sortHandler";
import { mapEdgesToItems } from "@dashboard/utils/maps";
import { getSortParams } from "@dashboard/utils/sort";
-import { DialogContentText } from "@material-ui/core";
import isEqual from "lodash/isEqual";
import React, { useCallback } from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -39,6 +41,9 @@ export const CustomerList: React.FC = ({ params }) => {
const notify = useNotifier();
const intl = useIntl();
const { updateListSettings, settings } = useListSettings(ListViews.CUSTOMER_LIST);
+ const { enabled: isCustomersFiltersEnabled } = useFlag("new_filters");
+ const { valueProvider } = useConditionalFilterContext();
+ const filter = createCustomerQueryVariables(valueProvider.value);
usePaginationReset(customerListUrl, params, settings.rowNumber);
@@ -73,9 +78,21 @@ export const CustomerList: React.FC = ({ params }) => {
}),
[params, settings.rowNumber],
);
+ const newQueryVariables = React.useMemo(
+ () => ({
+ ...paginationState,
+ filter: {
+ ...filter,
+ search: params.query,
+ },
+ sort: getSortQueryVariables(params),
+ }),
+ [params, settings.rowNumber, valueProvider.value],
+ );
+
const { data, refetch } = useListCustomersQuery({
displayLoader: true,
- variables: queryVariables,
+ variables: isCustomersFiltersEnabled ? newQueryVariables : queryVariables,
});
const customers = mapEdgesToItems(data?.customers);
const [changeFilters, resetFilters, handleSearchChange] = createFilterHandlers({
@@ -115,7 +132,7 @@ export const CustomerList: React.FC = ({ params }) => {
return;
}
- const rowsIds = rows.map(row => customers[row].id);
+ const rowsIds = rows.map(row => customers[row]?.id).filter(id => id !== undefined);
const haveSaveValues = isEqual(rowsIds, selectedRowIds);
if (!haveSaveValues) {
@@ -175,16 +192,14 @@ export const CustomerList: React.FC = ({ params }) => {
description: "dialog header",
})}
>
-
- {selectedRowIds?.length},
- }}
- />
-
+ {selectedRowIds?.length},
+ }}
+ />
= props => {
const intl = useIntl();
return (
-
-
+
+
+ {intl.formatMessage(messages.discountCategoriesHeader)}
+
+
- }
- />
+
+
@@ -85,7 +87,7 @@ const DiscountCategories: React.FC = props => {
{renderCollection(
- mapEdgesToItems(discount?.categories),
+ getLoadableList(discount?.categories),
category => {
const isSelected = category ? isChecked(category.id) : false;
@@ -106,10 +108,8 @@ const DiscountCategories: React.FC = props => {
onChange={() => toggle(category.id)}
/>
- {maybe(() => category.name, )}
-
- {maybe(() => category.products.totalCount, )}
-
+ {category ? category.name : }
+ {category ? category.products.totalCount : }
= props => {
)}
-
+
);
};
diff --git a/src/discounts/components/DiscountCollections/DiscountCollections.tsx b/src/discounts/components/DiscountCollections/DiscountCollections.tsx
index 7e75d194bb4..bfcf47a8d50 100644
--- a/src/discounts/components/DiscountCollections/DiscountCollections.tsx
+++ b/src/discounts/components/DiscountCollections/DiscountCollections.tsx
@@ -1,22 +1,22 @@
// @ts-strict-ignore
import { collectionUrl } from "@dashboard/collections/urls";
import { Button } from "@dashboard/components/Button";
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import Checkbox from "@dashboard/components/Checkbox";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
-import Skeleton from "@dashboard/components/Skeleton";
import { TableButtonWrapper } from "@dashboard/components/TableButtonWrapper/TableButtonWrapper";
import TableHead from "@dashboard/components/TableHead";
import { TablePaginationWithContext } from "@dashboard/components/TablePagination";
import TableRowLink from "@dashboard/components/TableRowLink";
import { SaleDetailsFragment, VoucherDetailsFragment } from "@dashboard/graphql";
-import { mapEdgesToItems } from "@dashboard/utils/maps";
-import { Card, TableBody, TableCell, TableFooter } from "@material-ui/core";
+import { getLoadableList, mapEdgesToItems } from "@dashboard/utils/maps";
+import { TableBody, TableCell, TableFooter } from "@material-ui/core";
import { DeleteIcon, IconButton } from "@saleor/macaw-ui";
+import { Skeleton } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
-import { maybe, renderCollection } from "../../../misc";
+import { renderCollection } from "../../../misc";
import { ListActions, ListProps } from "../../../types";
import { messages } from "./messages";
import { useStyles } from "./styles";
@@ -44,15 +44,17 @@ const DiscountCollections: React.FC = props => {
const intl = useIntl();
return (
-
-
+
+
+ {intl.formatMessage(messages.discountCollectionsHeader)}
+
+
- }
- />
+
+
@@ -83,7 +85,7 @@ const DiscountCollections: React.FC = props => {
{renderCollection(
- mapEdgesToItems(sale?.collections),
+ getLoadableList(sale?.collections),
collection => {
const isSelected = collection ? isChecked(collection.id) : false;
@@ -105,10 +107,10 @@ const DiscountCollections: React.FC = props => {
/>
- {maybe(() => collection.name, )}
+ {collection ? collection.name : }
- {maybe(() => collection.products.totalCount, )}
+ {collection ? collection.products.totalCount : }
@@ -137,7 +139,7 @@ const DiscountCollections: React.FC = props => {
)}
-
+
);
};
diff --git a/src/discounts/components/DiscountCountrySelectDialog/DiscountCountrySelectDialog.tsx b/src/discounts/components/DiscountCountrySelectDialog/DiscountCountrySelectDialog.tsx
index fd9c3d5f050..4e74ecd2258 100644
--- a/src/discounts/components/DiscountCountrySelectDialog/DiscountCountrySelectDialog.tsx
+++ b/src/discounts/components/DiscountCountrySelectDialog/DiscountCountrySelectDialog.tsx
@@ -1,26 +1,16 @@
-// @ts-strict-ignore
import BackButton from "@dashboard/components/BackButton";
import Checkbox from "@dashboard/components/Checkbox";
import { ConfirmButton, ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
import Form from "@dashboard/components/Form";
-import FormSpacer from "@dashboard/components/FormSpacer";
import Hr from "@dashboard/components/Hr";
+import { DashboardModal } from "@dashboard/components/Modal";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
import TableRowLink from "@dashboard/components/TableRowLink";
import { CountryWithCodeFragment } from "@dashboard/graphql";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import { fuzzySearch } from "@dashboard/misc";
-import useScrollableDialogStyle from "@dashboard/styles/useScrollableDialogStyle";
-import {
- Dialog,
- DialogActions,
- DialogContent,
- DialogTitle,
- TableBody,
- TableCell,
- TextField,
- Typography,
-} from "@material-ui/core";
+import { TableBody, TableCell, TextField } from "@material-ui/core";
+import { Box, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -44,7 +34,6 @@ export interface DiscountCountrySelectDialogProps {
const DiscountCountrySelectDialog: React.FC = props => {
const { confirmButtonState, onClose, countries, open, initial, onConfirm } = props;
const classes = useStyles(props);
- const scrollableDialogClasses = useScrollableDialogStyle();
const intl = useIntl();
const initialForm: FormData = {
allCountries: true,
@@ -53,34 +42,41 @@ const DiscountCountrySelectDialog: React.FC =
};
return (
-
-
- {({ data, change }) => {
- const countrySelectionMap = countries.reduce((acc, country) => {
- acc[country.code] = !!data.countries.find(
- selectedCountries => selectedCountries === country.code,
+
+
+
+ {({ data, change }) => {
+ const countrySelectionMap = countries.reduce(
+ (acc, country) => {
+ acc[country.code] = !!data.countries.find(
+ selectedCountries => selectedCountries === country.code,
+ );
+
+ return acc;
+ },
+ {} as Record,
);
- return acc;
- }, {});
+ return (
+
+
+
+
- return (
- <>
-
-
-
-
-
+
-
-
+
+
=
})}
fullWidth
/>
-
+
-
-
+
+
-
-
-
-
-
- {fuzzySearch(countries, data.query, ["country"]).map(country => {
- const isChecked = countrySelectionMap[country.code];
+
- return (
-
- {country.country}
-
-
- isChecked
- ? change({
- target: {
- name: "countries" as keyof FormData,
- value: data.countries.filter(
- selectedCountries => selectedCountries !== country.code,
- ),
- },
- } as any)
- : change({
- target: {
- name: "countries" as keyof FormData,
- value: [...data.countries, country.code],
- },
- } as any)
- }
- />
-
-
- );
- })}
-
-
-
-
-
-
-
-
-
- >
- );
- }}
-
-
+
+
+
+ {fuzzySearch(countries, data.query, ["country"]).map(country => {
+ const isChecked = countrySelectionMap[country.code];
+
+ return (
+
+ {country.country}
+
+
+ isChecked
+ ? change({
+ target: {
+ name: "countries" as keyof FormData,
+ value: data.countries.filter(
+ selectedCountries => selectedCountries !== country.code,
+ ),
+ },
+ } as any)
+ : change({
+ target: {
+ name: "countries" as keyof FormData,
+ value: [...data.countries, country.code],
+ },
+ } as any)
+ }
+ />
+
+
+ );
+ })}
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }}
+
+
+
);
};
diff --git a/src/discounts/components/DiscountDates/DiscountDates.tsx b/src/discounts/components/DiscountDates/DiscountDates.tsx
index 49c81dd1bcf..4e6ef49df12 100644
--- a/src/discounts/components/DiscountDates/DiscountDates.tsx
+++ b/src/discounts/components/DiscountDates/DiscountDates.tsx
@@ -37,13 +37,15 @@ const DiscountDates = ({
return (
-
-
-
+
+
+
+
+
diff --git a/src/discounts/components/DiscountDeleteModal/DiscountDeleteModal.tsx b/src/discounts/components/DiscountDeleteModal/DiscountDeleteModal.tsx
index 9767b9d69d7..ef1ced399ce 100644
--- a/src/discounts/components/DiscountDeleteModal/DiscountDeleteModal.tsx
+++ b/src/discounts/components/DiscountDeleteModal/DiscountDeleteModal.tsx
@@ -20,10 +20,10 @@ export const DiscountDeleteModal = ({
}: DiscountDeleteModalProps) => {
return (
-
-
+
+
-
+
-
-
-
+
+
+
+
+
{isReadyForMount ? (
void;
ruleDeleteButtonState: ConfirmButtonTransitionState;
onBack: () => void;
+ backLinkHref: string;
}
export const DiscountDetailsPage = ({
@@ -55,13 +55,14 @@ export const DiscountDetailsPage = ({
ruleCreateButtonState,
ruleUpdateButtonState,
ruleDeleteButtonState,
+ backLinkHref,
}: DiscountDetailsPageProps) => {
const intl = useIntl();
const formErrors = getFormErrors(["name"], errors);
return (
-
+
-
-
-
+
+
+
+
+
)}
+ navigatorOpts={{ state: getPrevLocationState(location) }}
/>
diff --git a/src/discounts/components/DiscountListPage/DiscountListPage.tsx b/src/discounts/components/DiscountListPage/DiscountListPage.tsx
index c24c8ff3ae5..14fbe662fda 100644
--- a/src/discounts/components/DiscountListPage/DiscountListPage.tsx
+++ b/src/discounts/components/DiscountListPage/DiscountListPage.tsx
@@ -11,12 +11,14 @@ import {
discountUrl,
} from "@dashboard/discounts/discountsUrls";
import { PromotionFragment } from "@dashboard/graphql";
+import { getPrevLocationState } from "@dashboard/hooks/useBackLinkWithState";
import useNavigator from "@dashboard/hooks/useNavigator";
import { commonMessages } from "@dashboard/intl";
import { FilterPresetsProps, PageListProps, SortPage } from "@dashboard/types";
import { Box, Button, ChevronRightIcon } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
+import { useLocation } from "react-router";
import { DiscountListDatagrid } from "../DiscountListDatagrid";
@@ -45,9 +47,12 @@ const DiscountListPage: React.FC = ({
}) => {
const intl = useIntl();
const navigation = useNavigator();
+ const location = useLocation();
const [isFilterPresetOpen, setFilterPresetOpen] = useState(false);
const handleRowClick = (id: string) => {
- navigation(discountUrl(id));
+ navigation(discountUrl(id), {
+ state: getPrevLocationState(location),
+ });
};
return (
diff --git a/src/discounts/components/DiscountProducts/DiscountProducts.tsx b/src/discounts/components/DiscountProducts/DiscountProducts.tsx
index a1f5466e2f6..a386ff94565 100644
--- a/src/discounts/components/DiscountProducts/DiscountProducts.tsx
+++ b/src/discounts/components/DiscountProducts/DiscountProducts.tsx
@@ -1,10 +1,9 @@
// @ts-strict-ignore
import { Button } from "@dashboard/components/Button";
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import { ChannelsAvailabilityDropdown } from "@dashboard/components/ChannelsAvailabilityDropdown";
import Checkbox from "@dashboard/components/Checkbox";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
-import Skeleton from "@dashboard/components/Skeleton";
import { TableButtonWrapper } from "@dashboard/components/TableButtonWrapper/TableButtonWrapper";
import TableCellAvatar from "@dashboard/components/TableCellAvatar";
import TableHead from "@dashboard/components/TableHead";
@@ -12,20 +11,20 @@ import { TablePaginationWithContext } from "@dashboard/components/TablePaginatio
import TableRowLink from "@dashboard/components/TableRowLink";
import { SaleDetailsFragment, VoucherDetailsFragment } from "@dashboard/graphql";
import { productUrl } from "@dashboard/products/urls";
-import { Card, TableBody, TableCell, TableFooter } from "@material-ui/core";
+import { getLoadableList, mapEdgesToItems } from "@dashboard/utils/maps";
+import { TableBody, TableCell, TableFooter } from "@material-ui/core";
import { DeleteIcon, IconButton } from "@saleor/macaw-ui";
+import { Skeleton } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { maybe, renderCollection } from "../../../misc";
-import { ListActions, ListProps, RelayToFlat } from "../../../types";
+import { ListActions, ListProps } from "../../../types";
import { messages } from "./messages";
import { useStyles } from "./styles";
export interface SaleProductsProps extends ListProps, ListActions {
- products:
- | RelayToFlat
- | RelayToFlat;
+ discount: SaleDetailsFragment | VoucherDetailsFragment;
onProductAssign: () => void;
onProductUnassign: (id: string) => void;
}
@@ -33,7 +32,7 @@ export interface SaleProductsProps extends ListProps, ListActions {
const numberOfColumns = 5;
const DiscountProducts: React.FC = props => {
const {
- products,
+ discount,
disabled,
onProductAssign,
onProductUnassign,
@@ -46,16 +45,21 @@ const DiscountProducts: React.FC = props => {
const classes = useStyles(props);
const intl = useIntl();
+ const productsList = mapEdgesToItems(discount?.products);
+
return (
-
-
+
+
+ {intl.formatMessage(messages.discountProductsHeader)}
+
+
- }
- />
+
+
+
@@ -68,12 +72,12 @@ const DiscountProducts: React.FC = props => {
colSpan={numberOfColumns}
selected={selected}
disabled={disabled}
- items={products}
+ items={productsList}
toggleAll={toggleAll}
toolbar={toolbar}
>
- 0 && classes.colNameLabel}>
+ 0 && classes.colNameLabel}>
@@ -92,7 +96,7 @@ const DiscountProducts: React.FC = props => {
{renderCollection(
- products,
+ getLoadableList(discount?.products),
product => {
const isSelected = product ? isChecked(product.id) : false;
@@ -158,7 +162,7 @@ const DiscountProducts: React.FC = props => {
)}
-
+
);
};
diff --git a/src/discounts/components/DiscountRules/DiscountRules.tsx b/src/discounts/components/DiscountRules/DiscountRules.tsx
index ee5ca32feae..6a727c1e8f5 100644
--- a/src/discounts/components/DiscountRules/DiscountRules.tsx
+++ b/src/discounts/components/DiscountRules/DiscountRules.tsx
@@ -4,7 +4,6 @@ import { Rule } from "@dashboard/discounts/models";
import { useLabelMapsContext } from "@dashboard/discounts/views/DiscountDetails/context/context";
import { ChannelFragment, PromotionTypeEnum } from "@dashboard/graphql";
import { CommonError } from "@dashboard/utils/errors/common";
-import { Box } from "@saleor/macaw-ui-next";
import React, { useEffect, useMemo, useState } from "react";
import { useIntl } from "react-intl";
@@ -92,12 +91,12 @@ export const DiscountRules = ({
disabled={disabled}
>
-
-
- {intl.formatMessage(messages.title)}
+
+ {intl.formatMessage(messages.title)}
+
setIsModalOpen(true)} />
-
-
+
+
-
-
- {intl.formatMessage(messages.deleteRule)}
-
-
+
+ {intl.formatMessage(messages.deleteRule)}
-
-
-
-
-
+
+
+
diff --git a/src/discounts/components/DiscountRules/componenets/RuleForm/RuleForm.tsx b/src/discounts/components/DiscountRules/componenets/RuleForm/RuleForm.tsx
index 3e774c16e68..fe4ae11ad2d 100644
--- a/src/discounts/components/DiscountRules/componenets/RuleForm/RuleForm.tsx
+++ b/src/discounts/components/DiscountRules/componenets/RuleForm/RuleForm.tsx
@@ -81,7 +81,7 @@ export const RuleForm = ({ errors, openPlayground }: RuleFormProps
-
+
diff --git a/src/discounts/components/DiscountRules/componenets/RuleFormModal/RuleFormModal.tsx b/src/discounts/components/DiscountRules/componenets/RuleFormModal/RuleFormModal.tsx
index cd8ec62222c..e53a0f2cce9 100644
--- a/src/discounts/components/DiscountRules/componenets/RuleFormModal/RuleFormModal.tsx
+++ b/src/discounts/components/DiscountRules/componenets/RuleFormModal/RuleFormModal.tsx
@@ -38,11 +38,10 @@ export const RuleFormModal = ({
return (
-
-
+
+
-
-
+
{children}
diff --git a/src/discounts/components/DiscountVariants/DiscountVariants.tsx b/src/discounts/components/DiscountVariants/DiscountVariants.tsx
index 4e511862913..e5c607f6279 100644
--- a/src/discounts/components/DiscountVariants/DiscountVariants.tsx
+++ b/src/discounts/components/DiscountVariants/DiscountVariants.tsx
@@ -1,9 +1,8 @@
// @ts-strict-ignore
import { Button } from "@dashboard/components/Button";
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import Checkbox from "@dashboard/components/Checkbox";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
-import Skeleton from "@dashboard/components/Skeleton";
import { TableButtonWrapper } from "@dashboard/components/TableButtonWrapper/TableButtonWrapper";
import TableCellAvatar from "@dashboard/components/TableCellAvatar";
import TableHead from "@dashboard/components/TableHead";
@@ -11,18 +10,20 @@ import { TablePaginationWithContext } from "@dashboard/components/TablePaginatio
import TableRowLink from "@dashboard/components/TableRowLink";
import { SaleDetailsFragment } from "@dashboard/graphql";
import { productVariantEditPath } from "@dashboard/products/urls";
-import { Card, TableBody, TableCell, TableFooter } from "@material-ui/core";
+import { getLoadableList, mapEdgesToItems } from "@dashboard/utils/maps";
+import { TableBody, TableCell, TableFooter } from "@material-ui/core";
import { DeleteIcon, IconButton } from "@saleor/macaw-ui";
+import { Skeleton } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { maybe, renderCollection } from "../../../misc";
-import { ListActions, ListProps, RelayToFlat } from "../../../types";
+import { ListActions, ListProps } from "../../../types";
import { messages } from "./messages";
import { useStyles } from "./styles";
export interface SaleVariantsProps extends ListProps, ListActions {
- variants: RelayToFlat | null;
+ discount: SaleDetailsFragment;
onVariantAssign: () => void;
onVariantUnassign: (id: string) => void;
}
@@ -30,7 +31,7 @@ export interface SaleVariantsProps extends ListProps, ListActions {
const numberOfColumns = 5;
const DiscountVariants: React.FC = props => {
const {
- variants,
+ discount,
disabled,
onVariantAssign,
onVariantUnassign,
@@ -43,16 +44,20 @@ const DiscountVariants: React.FC = props => {
const classes = useStyles(props);
const intl = useIntl();
+ const variants = mapEdgesToItems(discount?.variants);
+
return (
-
-
+
+
+ {intl.formatMessage(messages.discountVariantsHeader)}
+
+
- }
- />
+
+
@@ -89,7 +94,7 @@ const DiscountVariants: React.FC = props => {
{renderCollection(
- variants,
+ getLoadableList(discount?.variants),
variant => {
const isSelected = variant ? isChecked(variant.id) : false;
@@ -148,7 +153,7 @@ const DiscountVariants: React.FC = props => {
)}
-
+
);
};
diff --git a/src/discounts/components/SaleDetailsPage/SaleDetailsPage.tsx b/src/discounts/components/SaleDetailsPage/SaleDetailsPage.tsx
index a9169f63e04..b5c92b6c650 100644
--- a/src/discounts/components/SaleDetailsPage/SaleDetailsPage.tsx
+++ b/src/discounts/components/SaleDetailsPage/SaleDetailsPage.tsx
@@ -14,7 +14,7 @@ import {
createSaleUpdateHandler,
} from "@dashboard/discounts/handlers";
import { itemsQuantityMessages } from "@dashboard/discounts/translations";
-import { saleListUrl } from "@dashboard/discounts/urls";
+import { saleListPath, saleListUrl } from "@dashboard/discounts/urls";
import { SALE_UPDATE_FORM_ID } from "@dashboard/discounts/views/SaleDetails/types";
import {
DiscountErrorFragment,
@@ -22,9 +22,10 @@ import {
SaleDetailsFragment,
SaleType as SaleTypeEnum,
} from "@dashboard/graphql";
+import { useBackLinkWithState } from "@dashboard/hooks/useBackLinkWithState";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import useNavigator from "@dashboard/hooks/useNavigator";
-import { mapEdgesToItems, mapMetadataItemToInput } from "@dashboard/utils/maps";
+import { mapMetadataItemToInput } from "@dashboard/utils/maps";
import useMetadataChangeTrigger from "@dashboard/utils/metadata/useMetadataChangeTrigger";
import { sprinkles } from "@saleor/macaw-ui-next";
import React from "react";
@@ -149,6 +150,10 @@ const SaleDetailsPage: React.FC = ({
const checkIfSaveIsDisabled = (data: SaleDetailsPageFormData) =>
data.channelListings?.some(channel => validateSalePrice(data, channel)) || disabled;
+ const saleListBackLink = useBackLinkWithState({
+ path: saleListPath,
+ });
+
return (
= ({
return (
-
+
@@ -249,7 +254,7 @@ const SaleDetailsPage: React.FC = ({
disabled={disabled}
onProductAssign={onProductAssign}
onProductUnassign={onProductUnassign}
- products={mapEdgesToItems(sale?.products)}
+ discount={sale}
isChecked={isChecked}
selected={selected}
toggle={toggle}
@@ -261,7 +266,7 @@ const SaleDetailsPage: React.FC = ({
disabled={disabled}
onVariantAssign={onVariantAssign}
onVariantUnassign={onVariantUnassign}
- variants={mapEdgesToItems(sale?.variants)}
+ discount={sale}
isChecked={isChecked}
selected={selected}
toggle={toggle}
diff --git a/src/discounts/components/SaleInfo/SaleInfo.tsx b/src/discounts/components/SaleInfo/SaleInfo.tsx
index da62334bd30..9fde3b923f9 100644
--- a/src/discounts/components/SaleInfo/SaleInfo.tsx
+++ b/src/discounts/components/SaleInfo/SaleInfo.tsx
@@ -1,9 +1,9 @@
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import { DiscountErrorFragment } from "@dashboard/graphql";
import { commonMessages } from "@dashboard/intl";
import { getFormErrors } from "@dashboard/utils/errors";
import getDiscountErrorMessage from "@dashboard/utils/errors/discounts";
-import { Card, CardContent, TextField } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
import React from "react";
import { useIntl } from "react-intl";
@@ -21,9 +21,13 @@ const SaleInfo: React.FC = ({ data, disabled, errors, onChange })
const formErrors = getFormErrors(["name"], errors);
return (
-
-
-
+
+
+
+ {intl.formatMessage(commonMessages.generalInformations)}
+
+
+
= ({ data, disabled, errors, onChange })
value={data.name}
fullWidth
/>
-
-
+
+
);
};
diff --git a/src/discounts/components/SaleListDatagrid/SaleListDatagrid.tsx b/src/discounts/components/SaleListDatagrid/SaleListDatagrid.tsx
index 6f376e19e43..c62de39c976 100644
--- a/src/discounts/components/SaleListDatagrid/SaleListDatagrid.tsx
+++ b/src/discounts/components/SaleListDatagrid/SaleListDatagrid.tsx
@@ -9,6 +9,7 @@ import { TablePaginationWithContext } from "@dashboard/components/TablePaginatio
import { commonTooltipMessages } from "@dashboard/components/TooltipTableCellHeader/messages";
import { SaleListUrlSortField, saleUrl } from "@dashboard/discounts/urls";
import { SaleFragment } from "@dashboard/graphql";
+import { getPrevLocationState } from "@dashboard/hooks/useBackLinkWithState";
import useLocale from "@dashboard/hooks/useLocale";
import { ChannelProps, ListProps, SortPage } from "@dashboard/types";
import { Item } from "@glideapps/glide-data-grid";
@@ -141,6 +142,7 @@ export const SaleListDatagrid = ({
onToggle={handlers.onToggle}
/>
)}
+ navigatorOpts={{ state: getPrevLocationState(location) }}
/>
diff --git a/src/discounts/components/SaleListPage/SaleListPage.tsx b/src/discounts/components/SaleListPage/SaleListPage.tsx
index 69c0c67db4f..c65b730a3b3 100644
--- a/src/discounts/components/SaleListPage/SaleListPage.tsx
+++ b/src/discounts/components/SaleListPage/SaleListPage.tsx
@@ -1,11 +1,13 @@
import { ListFilters } from "@dashboard/components/AppLayout/ListFilters";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import { BulkDeleteButton } from "@dashboard/components/BulkDeleteButton";
+import { DashboardCard } from "@dashboard/components/Card";
import { getByName } from "@dashboard/components/Filter/utils";
import { FilterPresetsSelect } from "@dashboard/components/FilterPresetsSelect";
import { ListPageLayout } from "@dashboard/components/Layouts";
import { saleAddUrl, SaleListUrlSortField, saleUrl } from "@dashboard/discounts/urls";
import { SaleFragment } from "@dashboard/graphql";
+import { getPrevLocationState } from "@dashboard/hooks/useBackLinkWithState";
import useNavigator from "@dashboard/hooks/useNavigator";
import { commonMessages } from "@dashboard/intl";
import {
@@ -14,10 +16,10 @@ import {
PageListProps,
SortPage,
} from "@dashboard/types";
-import { Card } from "@material-ui/core";
import { Box, Button, ChevronRightIcon } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
+import { useLocation } from "react-router";
import { SaleListDatagrid } from "../SaleListDatagrid";
import { createFilterStructure, SaleFilterKeys, SaleListFilterOpts } from "./filters";
@@ -52,12 +54,15 @@ const SaleListPage: React.FC = ({
...listProps
}) => {
const intl = useIntl();
+ const location = useLocation();
const navigation = useNavigator();
const structure = createFilterStructure(intl, filterOpts);
const [isFilterPresetOpen, setFilterPresetOpen] = useState(false);
const filterDependency = structure.find(getByName("channel"));
const handleRowClick = (id: string) => {
- navigation(saleUrl(id));
+ navigation(saleUrl(id), {
+ state: getPrevLocationState(location),
+ });
};
return (
@@ -103,7 +108,7 @@ const SaleListPage: React.FC = ({
-
+
currencySymbol={currencySymbol}
initialSearch={initialSearch}
@@ -131,7 +136,7 @@ const SaleListPage: React.FC = ({
filterDependency={filterDependency}
onRowClick={handleRowClick}
/>
-
+
);
};
diff --git a/src/discounts/components/SaleListPage/filters.ts b/src/discounts/components/SaleListPage/filters.ts
index 02b222da95a..e7c37d7234d 100644
--- a/src/discounts/components/SaleListPage/filters.ts
+++ b/src/discounts/components/SaleListPage/filters.ts
@@ -1,8 +1,8 @@
import { IFilter } from "@dashboard/components/Filter";
-import { MultiAutocompleteChoiceType } from "@dashboard/components/MultiAutocompleteSelectField";
import { DiscountStatusEnum, DiscountValueTypeEnum } from "@dashboard/graphql";
import { FilterOpts, MinMax } from "@dashboard/types";
import { createDateField, createOptionsField } from "@dashboard/utils/filters/fields";
+import { Option } from "@saleor/macaw-ui-next";
import { defineMessages, IntlShape } from "react-intl";
export enum SaleFilterKeys {
@@ -16,7 +16,7 @@ export interface SaleListFilterOpts {
saleType: FilterOpts;
started: FilterOpts;
status: FilterOpts;
- channel: FilterOpts & { choices: MultiAutocompleteChoiceType[] };
+ channel: FilterOpts & { choices: Option[] };
}
const messages = defineMessages({
diff --git a/src/discounts/components/SaleSummary/SaleSummary.tsx b/src/discounts/components/SaleSummary/SaleSummary.tsx
index 75e23e1d25d..07c7d79fce8 100644
--- a/src/discounts/components/SaleSummary/SaleSummary.tsx
+++ b/src/discounts/components/SaleSummary/SaleSummary.tsx
@@ -1,15 +1,14 @@
+import { DashboardCard } from "@dashboard/components/Card";
import CardSpacer from "@dashboard/components/CardSpacer";
-import CardTitle from "@dashboard/components/CardTitle";
import Date from "@dashboard/components/Date";
import FormSpacer from "@dashboard/components/FormSpacer";
import Hr from "@dashboard/components/Hr";
import Money from "@dashboard/components/Money";
import Percent from "@dashboard/components/Percent";
-import Skeleton from "@dashboard/components/Skeleton";
import { SaleDetailsFragment, SaleType } from "@dashboard/graphql";
import { commonMessages } from "@dashboard/intl";
import { ChannelProps } from "@dashboard/types";
-import { Card, CardContent, Typography } from "@material-ui/core";
+import { Skeleton, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -26,21 +25,23 @@ const SaleSummary: React.FC = ({ selectedChannelId, sale }) =>
const channel = sale?.channelListings?.find(listing => listing.channel.id === selectedChannelId);
return (
-
-
-
-
+
+
+ {intl.formatMessage(commonMessages.summary)}
+
+
+
-
-
+
+
{maybe(() => sale.name, )}
-
+
-
+
-
-
+
+
{sale ? (
sale.type === SaleType.FIXED && channel?.discountValue ? (
= ({ selectedChannelId, sale }) =>
) : (
)}
-
+
-
+
-
-
+
+
{maybe(
() => (
),
,
)}
-
+
-
+
-
-
+
+
{maybe(
() => (sale.endDate === null ? "-" : ),
,
)}
-
-
-
+
+
+
);
};
diff --git a/src/discounts/components/SaleType/SaleType.tsx b/src/discounts/components/SaleType/SaleType.tsx
index 910474469e3..af845276a2f 100644
--- a/src/discounts/components/SaleType/SaleType.tsx
+++ b/src/discounts/components/SaleType/SaleType.tsx
@@ -1,8 +1,7 @@
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import RadioGroupField, { RadioGroupFieldChoice } from "@dashboard/components/RadioGroupField";
import { SaleType as SaleTypeEnum } from "@dashboard/graphql";
import { FormChange } from "@dashboard/hooks/useForm";
-import { Card, CardContent } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
import React from "react";
import { IntlShape, useIntl } from "react-intl";
@@ -56,15 +55,17 @@ const SaleType: React.FC = props => {
const choices = createChoices(intl);
return (
-
-
-
+
+
+
+ {intl.formatMessage({
+ id: "WkxE8/",
+ defaultMessage: "Discount Type",
+ description: "percentage or fixed, header",
+ })}
+
+
+
= props => {
value={data.type}
onChange={onChange}
/>
-
-
+
+
);
};
diff --git a/src/discounts/components/SaleValue/SaleValue.tsx b/src/discounts/components/SaleValue/SaleValue.tsx
index 6e8b5ea9154..c117a047c67 100644
--- a/src/discounts/components/SaleValue/SaleValue.tsx
+++ b/src/discounts/components/SaleValue/SaleValue.tsx
@@ -1,13 +1,13 @@
// @ts-strict-ignore
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
-import Skeleton from "@dashboard/components/Skeleton";
import TableRowLink from "@dashboard/components/TableRowLink";
import { DiscountErrorFragment } from "@dashboard/graphql";
import { renderCollection } from "@dashboard/misc";
import { getFormErrors } from "@dashboard/utils/errors";
import getDiscountErrorMessage from "@dashboard/utils/errors/discounts";
-import { Card, TableBody, TableCell, TableHead, Typography } from "@material-ui/core";
+import { TableBody, TableCell, TableHead } from "@material-ui/core";
+import { Skeleton, Text } from "@saleor/macaw-ui-next";
import * as React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -31,14 +31,16 @@ const SaleValue: React.FC = ({ data, disabled, errors, onChange
const formErrors = getFormErrors(["value"], errors);
return (
-
-
+
+
+
+ {intl.formatMessage({
+ id: "wHdMAX",
+ defaultMessage: "Value",
+ description: "sale value, header",
+ })}
+
+
@@ -73,7 +75,7 @@ const SaleValue: React.FC = ({ data, disabled, errors, onChange
return (
- {listing?.name || }
+ {listing?.name || }
{listing ? (
@@ -102,7 +104,7 @@ const SaleValue: React.FC = ({ data, disabled, errors, onChange
)}
-
+
);
};
diff --git a/src/discounts/components/VoucherCodes/utils.test.ts b/src/discounts/components/VoucherCodes/utils.test.ts
index b1e85c998a6..3a9e1e6e9b7 100644
--- a/src/discounts/components/VoucherCodes/utils.test.ts
+++ b/src/discounts/components/VoucherCodes/utils.test.ts
@@ -2,6 +2,7 @@ import { hasSavedVoucherCodesToDelete } from "./utils";
describe("hasSavedVoucherCodesToDelete", () => {
it("should return true if there are saved voucher codes to delete", () => {
+ // Arrange
const voucherCodesIdsToDelete = ["voucherCode1", "voucherCode2"];
const voucherCodes = [
{
@@ -18,9 +19,14 @@ describe("hasSavedVoucherCodesToDelete", () => {
},
];
- expect(hasSavedVoucherCodesToDelete(voucherCodesIdsToDelete, voucherCodes)).toBe(true);
+ // Act
+ const result = hasSavedVoucherCodesToDelete(voucherCodesIdsToDelete, voucherCodes);
+
+ // Assert
+ expect(result).toBe(true);
});
it("should return false if there are no saved voucher codes to delete", () => {
+ // Arrange
const voucherCodesIdsToDelete = ["voucherCode1", "voucherCode2"];
const voucherCodes = [
{
@@ -33,6 +39,10 @@ describe("hasSavedVoucherCodesToDelete", () => {
},
];
- expect(hasSavedVoucherCodesToDelete(voucherCodesIdsToDelete, voucherCodes)).toBe(false);
+ // Act
+ const result = hasSavedVoucherCodesToDelete(voucherCodesIdsToDelete, voucherCodes);
+
+ // Assert
+ expect(result).toBe(false);
});
});
diff --git a/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx b/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx
index d2579c895e7..477a2f52865 100644
--- a/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx
+++ b/src/discounts/components/VoucherCodesDeleteDialog/VoucherCodesDeleteDialog.tsx
@@ -23,10 +23,10 @@ export const VoucherCodesDeleteDialog = ({
return (
-
-
+
+
-
+
-
- {intl.formatMessage(messages.title)}
+
+ {intl.formatMessage(messages.title)}
-
-
+
+
-
+
= ({
clearRowSelection();
triggerChange(true);
set({
- codes: [...generateMultipleIds(quantity, prefix), ...data.codes],
+ codes: [...generateMultipleVoucherCodes(quantity, prefix), ...data.codes],
});
};
const handleDeleteVoucherCodes = () => {
@@ -111,7 +111,7 @@ const VoucherCreatePage: React.FC = ({
triggerChange(true);
set({
- codes: [{ code }, ...data.codes],
+ codes: [generateDraftVoucherCode(code), ...data.codes],
});
};
const { pagination, paginatedCodes, settings, onSettingsChange } = useVoucherCodesPagination(
diff --git a/src/discounts/components/VoucherCreatePage/utils.test.ts b/src/discounts/components/VoucherCreatePage/utils.test.ts
new file mode 100644
index 00000000000..dfdd2401e0d
--- /dev/null
+++ b/src/discounts/components/VoucherCreatePage/utils.test.ts
@@ -0,0 +1,36 @@
+import {
+ generateDraftVoucherCode,
+ generateMultipleVoucherCodes,
+} from "@dashboard/discounts/components/VoucherCreatePage/utils";
+import { v4 as uuidv4 } from "uuid";
+
+jest.mock("uuid");
+
+describe("generateDraftVoucherCode", () => {
+ it("should return draft voucher code", () => {
+ // Act
+ const draftVoucherCode = generateDraftVoucherCode("test1");
+
+ // Assert
+ expect(draftVoucherCode).toEqual({
+ code: "test1",
+ status: "Draft",
+ });
+ });
+});
+
+describe("generateMultipleVoucherCodes", () => {
+ it("should return multiple voucher codes", () => {
+ // Arrange
+ (uuidv4 as jest.Mock).mockImplementation(() => "uuid");
+
+ // Act
+ const draftVoucherCodes = generateMultipleVoucherCodes("2", "test");
+
+ // Assert
+ expect(draftVoucherCodes).toEqual([
+ { code: "test-uuid", status: "Draft" },
+ { code: "test-uuid", status: "Draft" },
+ ]);
+ });
+});
diff --git a/src/discounts/components/VoucherCreatePage/utils.ts b/src/discounts/components/VoucherCreatePage/utils.ts
index f13b2258d74..fb87dd7372f 100644
--- a/src/discounts/components/VoucherCreatePage/utils.ts
+++ b/src/discounts/components/VoucherCreatePage/utils.ts
@@ -2,11 +2,17 @@ import { v4 as uuidv4 } from "uuid";
import { VoucherCode } from "../VoucherCodesDatagrid/types";
-export const generateMultipleIds = (quantity: string, prefix?: string) => {
- return Array.from({ length: Number(quantity) }).map(() => ({
- code: prefix ? `${prefix}-${uuidv4()}` : uuidv4(),
+export const generateDraftVoucherCode = (code: string) => {
+ return {
+ code,
status: "Draft",
- }));
+ };
+};
+
+export const generateMultipleVoucherCodes = (quantity: string, prefix?: string) => {
+ return Array.from({ length: Number(quantity) }).map(() =>
+ generateDraftVoucherCode(prefix ? `${prefix}-${uuidv4()}` : uuidv4()),
+ );
};
export const voucherCodeExists = (code: string, voucherCodes: VoucherCode[]) => {
diff --git a/src/discounts/components/VoucherDates/VoucherDates.tsx b/src/discounts/components/VoucherDates/VoucherDates.tsx
index 9d5c72fd340..5e7eead01f9 100644
--- a/src/discounts/components/VoucherDates/VoucherDates.tsx
+++ b/src/discounts/components/VoucherDates/VoucherDates.tsx
@@ -1,11 +1,11 @@
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import { ControlledCheckbox } from "@dashboard/components/ControlledCheckbox";
import Grid from "@dashboard/components/Grid";
import { DiscountErrorFragment } from "@dashboard/graphql";
import { commonMessages } from "@dashboard/intl";
import { getFormErrors } from "@dashboard/utils/errors";
import getDiscountErrorMessage from "@dashboard/utils/errors/discounts";
-import { Card, CardContent, TextField } from "@material-ui/core";
+import { TextField } from "@material-ui/core";
import React from "react";
import { useIntl } from "react-intl";
@@ -23,15 +23,17 @@ const VoucherDates = ({ data, disabled, errors, onChange }: VoucherDatesProps) =
const formErrors = getFormErrors(["startDate", "endDate"], errors);
return (
-
-
-
+
+
+
+ {intl.formatMessage({
+ id: "YjcN9w",
+ defaultMessage: "Active Dates",
+ description: "time during voucher is active, header",
+ })}
+
+
+
)}
-
-
+
+
);
};
diff --git a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx
index c34e93eab24..3c5790fcd43 100644
--- a/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx
+++ b/src/discounts/components/VoucherDetailsPage/VoucherDetailsPage.tsx
@@ -17,7 +17,7 @@ import {
} from "@dashboard/discounts/handlers";
import { itemsQuantityMessages } from "@dashboard/discounts/translations";
import { DiscountTypeEnum, RequirementsPicker } from "@dashboard/discounts/types";
-import { voucherListUrl } from "@dashboard/discounts/urls";
+import { voucherListPath } from "@dashboard/discounts/urls";
import {
DiscountErrorFragment,
DiscountValueTypeEnum,
@@ -25,12 +25,13 @@ import {
VoucherDetailsFragment,
VoucherTypeEnum,
} from "@dashboard/graphql";
+import { useBackLinkWithState } from "@dashboard/hooks/useBackLinkWithState";
import { UseListSettings } from "@dashboard/hooks/useListSettings";
import { LocalPagination } from "@dashboard/hooks/useLocalPaginator";
import useNavigator from "@dashboard/hooks/useNavigator";
-import { mapEdgesToItems, mapMetadataItemToInput } from "@dashboard/utils/maps";
+import { mapMetadataItemToInput } from "@dashboard/utils/maps";
import useMetadataChangeTrigger from "@dashboard/utils/metadata/useMetadataChangeTrigger";
-import { Typography } from "@material-ui/core";
+import { Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -209,6 +210,10 @@ const VoucherDetailsPage: React.FC = ({
privateMetadata: voucher?.privateMetadata.map(mapMetadataItemToInput),
};
+ const voucherListBackLink = useBackLinkWithState({
+ path: voucherListPath,
+ });
+
return (
{({ change, data, submit, triggerChange, set }) => {
@@ -224,7 +229,7 @@ const VoucherDetailsPage: React.FC = ({
return (
-
+
= ({
disabled={disabled}
onProductAssign={onProductAssign}
onProductUnassign={onProductUnassign}
- products={mapEdgesToItems(voucher?.products)}
+ discount={voucher}
isChecked={isChecked}
selected={selected}
toggle={toggle}
@@ -349,12 +354,12 @@ const VoucherDetailsPage: React.FC = ({
defaultMessage: "Countries",
description: "voucher country range",
})}
-
+
-
+
>
}
onCountryAssign={onCountryAssign}
@@ -396,7 +401,7 @@ const VoucherDetailsPage: React.FC = ({
- navigate(voucherListUrl())} />
+ navigate(voucherListBackLink)} />
handleSubmit(data)}
diff --git a/src/discounts/components/VoucherInfo/VoucherInfo.tsx b/src/discounts/components/VoucherInfo/VoucherInfo.tsx
index a8e23c8061c..399a61851f7 100644
--- a/src/discounts/components/VoucherInfo/VoucherInfo.tsx
+++ b/src/discounts/components/VoucherInfo/VoucherInfo.tsx
@@ -22,9 +22,11 @@ const VoucherInfo = ({ data, disabled, errors, onChange }: VoucherInfoProps) =>
return (
-
- {intl.formatMessage(commonMessages.generalInformations)}
-
+
+
+ {intl.formatMessage(commonMessages.generalInformations)}
+
+
-
-
+
+
+ {intl.formatMessage(messages.usageLimitsTitle)}
+
+
-
+
{intl.formatMessage(messages.usesLeftCaption)}
-
- {usesLeft >= 0 ? usesLeft : 0}
+
+ {usesLeft >= 0 ? usesLeft : 0}
))}
@@ -113,8 +116,8 @@ const VoucherLimits = ({
name={"singleUse" satisfies keyof VoucherDetailsPageFormData}
onChange={onChange}
/>
-
-
+
+
);
};
diff --git a/src/discounts/components/VoucherListDatagrid/VoucherListDatagrid.tsx b/src/discounts/components/VoucherListDatagrid/VoucherListDatagrid.tsx
index 17faa536b3c..1bbd5163789 100644
--- a/src/discounts/components/VoucherListDatagrid/VoucherListDatagrid.tsx
+++ b/src/discounts/components/VoucherListDatagrid/VoucherListDatagrid.tsx
@@ -10,6 +10,7 @@ import { commonTooltipMessages } from "@dashboard/components/TooltipTableCellHea
import { VoucherListUrlSortField, voucherUrl } from "@dashboard/discounts/urls";
import { canBeSorted } from "@dashboard/discounts/views/VoucherList/sort";
import { VoucherFragment } from "@dashboard/graphql";
+import { getPrevLocationState } from "@dashboard/hooks/useBackLinkWithState";
import useLocale from "@dashboard/hooks/useLocale";
import useNavigator from "@dashboard/hooks/useNavigator";
import { ChannelProps, ListProps, SortPage } from "@dashboard/types";
@@ -17,6 +18,7 @@ import { Item } from "@glideapps/glide-data-grid";
import { Box } from "@saleor/macaw-ui-next";
import React, { useCallback, useMemo } from "react";
import { useIntl } from "react-intl";
+import { useLocation } from "react-router";
import { createGetCellContent, vouchersListStaticColumnsAdapter } from "./datagrid";
import { messages } from "./messages";
@@ -41,6 +43,7 @@ export const VoucherListDatagrid = ({
onUpdateListSettings,
}: VoucherListDatagridProps) => {
const datagridState = useDatagridChangeState();
+ const location = useLocation();
const navigate = useNavigator();
const { locale } = useLocale();
const intl = useIntl();
@@ -77,7 +80,9 @@ export const VoucherListDatagrid = ({
const rowData: VoucherFragment = vouchers[row];
if (rowData) {
- navigate(voucherUrl(rowData.id));
+ navigate(voucherUrl(rowData.id), {
+ state: getPrevLocationState(location),
+ });
}
},
[vouchers],
diff --git a/src/discounts/components/VoucherListPage/VoucherListPage.tsx b/src/discounts/components/VoucherListPage/VoucherListPage.tsx
index 75623927f4f..1bac8558e35 100644
--- a/src/discounts/components/VoucherListPage/VoucherListPage.tsx
+++ b/src/discounts/components/VoucherListPage/VoucherListPage.tsx
@@ -2,10 +2,12 @@
import { ListFilters } from "@dashboard/components/AppLayout/ListFilters";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import { BulkDeleteButton } from "@dashboard/components/BulkDeleteButton";
+import { DashboardCard } from "@dashboard/components/Card";
import { getByName } from "@dashboard/components/Filter/utils";
import { FilterPresetsSelect } from "@dashboard/components/FilterPresetsSelect";
import { ListPageLayout } from "@dashboard/components/Layouts";
import { voucherAddUrl, VoucherListUrlSortField } from "@dashboard/discounts/urls";
+import { useFlag } from "@dashboard/featureFlags";
import { VoucherFragment } from "@dashboard/graphql";
import useNavigator from "@dashboard/hooks/useNavigator";
import { sectionNames } from "@dashboard/intl";
@@ -15,7 +17,6 @@ import {
PageListProps,
SortPage,
} from "@dashboard/types";
-import { Card } from "@material-ui/core";
import { Box, Button, ChevronRightIcon } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -54,6 +55,7 @@ const VoucherListPage: React.FC = ({
}) => {
const intl = useIntl();
const navigate = useNavigator();
+ const { enabled: isVoucherFiltersEnabled } = useFlag("new_filters");
const structure = createFilterStructure(intl, filterOpts);
const [isFilterPresetOpen, setFilterPresetOpen] = useState(false);
const filterDependency = structure.find(getByName("channel"));
@@ -100,30 +102,51 @@ const VoucherListPage: React.FC = ({
-
-
- currencySymbol={currencySymbol}
- initialSearch={initialSearch}
- onFilterChange={onFilterChange}
- onSearchChange={onSearchChange}
- filterStructure={structure}
- searchPlaceholder={intl.formatMessage({
- id: "bPshhv",
- defaultMessage: "Search vouchers...",
- })}
- actions={
-
- {selectedVouchersIds.length > 0 && (
-
-
-
- )}
-
- }
- />
+
+ {isVoucherFiltersEnabled ? (
+
+ {selectedVouchersIds.length > 0 && (
+
+
+
+ )}
+
+ }
+ />
+ ) : (
+
+ currencySymbol={currencySymbol}
+ initialSearch={initialSearch}
+ onFilterChange={onFilterChange}
+ onSearchChange={onSearchChange}
+ filterStructure={structure}
+ searchPlaceholder={intl.formatMessage({
+ id: "bPshhv",
+ defaultMessage: "Search vouchers...",
+ })}
+ actions={
+
+ {selectedVouchersIds.length > 0 && (
+
+
+
+ )}
+
+ }
+ />
+ )}
-
+
);
};
diff --git a/src/discounts/components/VoucherListPage/filters.ts b/src/discounts/components/VoucherListPage/filters.ts
index 54a5fac6d3b..137c1291af5 100644
--- a/src/discounts/components/VoucherListPage/filters.ts
+++ b/src/discounts/components/VoucherListPage/filters.ts
@@ -1,5 +1,4 @@
import { IFilter } from "@dashboard/components/Filter";
-import { MultiAutocompleteChoiceType } from "@dashboard/components/MultiAutocompleteSelectField";
import { DiscountStatusEnum, VoucherDiscountType } from "@dashboard/graphql";
import { FilterOpts, MinMax } from "@dashboard/types";
import {
@@ -7,6 +6,7 @@ import {
createNumberField,
createOptionsField,
} from "@dashboard/utils/filters/fields";
+import { Option } from "@saleor/macaw-ui-next";
import { defineMessages, IntlShape } from "react-intl";
export enum VoucherFilterKeys {
@@ -22,7 +22,7 @@ export interface VoucherListFilterOpts {
started: FilterOpts;
status: FilterOpts;
timesUsed: FilterOpts;
- channel: FilterOpts & { choices: MultiAutocompleteChoiceType[] };
+ channel: FilterOpts & { choices: Option[] };
}
const messages = defineMessages({
diff --git a/src/discounts/components/VoucherRequirements/VoucherRequirements.tsx b/src/discounts/components/VoucherRequirements/VoucherRequirements.tsx
index be7b0b47286..0b6ac976a93 100644
--- a/src/discounts/components/VoucherRequirements/VoucherRequirements.tsx
+++ b/src/discounts/components/VoucherRequirements/VoucherRequirements.tsx
@@ -1,10 +1,9 @@
// @ts-strict-ignore
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import { FormSpacer } from "@dashboard/components/FormSpacer";
import PriceField from "@dashboard/components/PriceField";
import RadioGroupField from "@dashboard/components/RadioGroupField";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
-import Skeleton from "@dashboard/components/Skeleton";
import TableHead from "@dashboard/components/TableHead";
import TableRowLink from "@dashboard/components/TableRowLink";
import { ChannelInput } from "@dashboard/discounts/handlers";
@@ -13,7 +12,8 @@ import { DiscountErrorFragment } from "@dashboard/graphql";
import { renderCollection } from "@dashboard/misc";
import { getFormErrors } from "@dashboard/utils/errors";
import getDiscountErrorMessage from "@dashboard/utils/errors/discounts";
-import { Card, CardContent, TableBody, TableCell, TextField, Typography } from "@material-ui/core";
+import { TableBody, TableCell, TextField } from "@material-ui/core";
+import { Skeleton, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -69,15 +69,17 @@ const VoucherRequirements = ({
];
return (
-
-
-
+
+
+
+ {intl.formatMessage({
+ id: "yhv3HX",
+ defaultMessage: "Minimum Requirements",
+ description: "voucher requirements, header",
+ })}
+
+
+
- {listing?.name || }
+ {listing?.name || }
{listing ? (
@@ -175,8 +177,8 @@ const VoucherRequirements = ({
fullWidth
/>
) : null}
-
-
+
+
);
};
diff --git a/src/discounts/components/VoucherSummary/VoucherSummary.tsx b/src/discounts/components/VoucherSummary/VoucherSummary.tsx
index bba4a6294c7..b0ea729b5df 100644
--- a/src/discounts/components/VoucherSummary/VoucherSummary.tsx
+++ b/src/discounts/components/VoucherSummary/VoucherSummary.tsx
@@ -1,19 +1,17 @@
+import { DashboardCard } from "@dashboard/components/Card";
import CardSpacer from "@dashboard/components/CardSpacer";
-import CardTitle from "@dashboard/components/CardTitle";
import Date from "@dashboard/components/Date";
import FormSpacer from "@dashboard/components/FormSpacer";
import Hr from "@dashboard/components/Hr";
import Money from "@dashboard/components/Money";
import Percent from "@dashboard/components/Percent";
-import Skeleton from "@dashboard/components/Skeleton";
import { DiscountValueTypeEnum, VoucherDetailsFragment } from "@dashboard/graphql";
import { commonMessages } from "@dashboard/intl";
import { ChannelProps } from "@dashboard/types";
-import { Card, CardContent, Typography } from "@material-ui/core";
+import { Skeleton, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
-import { maybe } from "../../../misc";
import { translateVoucherTypes } from "../../translations";
export interface VoucherSummaryProps extends ChannelProps {
@@ -28,21 +26,23 @@ const VoucherSummary: React.FC = ({ selectedChannelId, vouc
);
return (
-
-
-
-
+
+
+ {intl.formatMessage(commonMessages.summary)}
+
+
+
-
-
- {maybe(() => translatedVoucherTypes[voucher.type], )}
-
+
+
+ {voucher?.type ? translatedVoucherTypes[voucher.type] : }
+
-
+
-
-
+
+
{voucher ? (
voucher.discountValueType === DiscountValueTypeEnum.FIXED && channel?.discountValue ? (
= ({ selectedChannelId, vouc
) : (
)}
-
+
- {intl.formatMessage(commonMessages.startDate)}
-
- {maybe(
- () => (
-
- ),
- ,
- )}
-
+
+ {intl.formatMessage(commonMessages.startDate)}
+
+
+ {voucher?.startDate ? : }
+
- {intl.formatMessage(commonMessages.endDate)}
-
- {maybe(
- () => (voucher.endDate === null ? "-" : ),
- ,
- )}
-
+
+ {intl.formatMessage(commonMessages.endDate)}
+
+
+ {voucher?.endDate ? : "-"}
+
-
+
-
-
+
+
{voucher ? channel?.minSpent ? : "-" : }
-
+
-
+
-
-
- {maybe(
- () => (voucher.usageLimit === null ? "-" : voucher.usageLimit),
- ,
- )}
-
+
+ {voucher?.usageLimit ? voucher.usageLimit : "-"}
-
+
-
- {voucher?.used ?? }
-
-
+
+ {voucher?.used ?? }
+
+
);
};
diff --git a/src/discounts/components/VoucherTypes/VoucherTypes.tsx b/src/discounts/components/VoucherTypes/VoucherTypes.tsx
index 74afdd33d4f..b70fa86d9a5 100644
--- a/src/discounts/components/VoucherTypes/VoucherTypes.tsx
+++ b/src/discounts/components/VoucherTypes/VoucherTypes.tsx
@@ -1,11 +1,10 @@
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import Grid from "@dashboard/components/Grid";
import RadioGroupField from "@dashboard/components/RadioGroupField";
import { DiscountTypeEnum } from "@dashboard/discounts/types";
import { DiscountErrorFragment } from "@dashboard/graphql";
import { getFormErrors } from "@dashboard/utils/errors";
import getDiscountErrorMessage from "@dashboard/utils/errors/discounts";
-import { Card, CardContent } from "@material-ui/core";
import React from "react";
import { useIntl } from "react-intl";
@@ -49,15 +48,17 @@ const VoucherTypes = ({ data, disabled, errors, onChange }: VoucherTypesProps) =
];
return (
-
-
-
+
+
+
+ {intl.formatMessage({
+ id: "6cq+c+",
+ defaultMessage: "Discount Type",
+ description: "header",
+ })}
+
+
+
-
-
+
+
);
};
diff --git a/src/discounts/components/VoucherValue/VoucherValue.tsx b/src/discounts/components/VoucherValue/VoucherValue.tsx
index 38190cc3c78..6ebffb06d34 100644
--- a/src/discounts/components/VoucherValue/VoucherValue.tsx
+++ b/src/discounts/components/VoucherValue/VoucherValue.tsx
@@ -1,10 +1,9 @@
// @ts-strict-ignore
-import CardTitle from "@dashboard/components/CardTitle";
+import { DashboardCard } from "@dashboard/components/Card";
import ControlledCheckbox from "@dashboard/components/ControlledCheckbox";
import { FormSpacer } from "@dashboard/components/FormSpacer";
import RadioGroupField from "@dashboard/components/RadioGroupField";
import ResponsiveTable from "@dashboard/components/ResponsiveTable";
-import Skeleton from "@dashboard/components/Skeleton";
import TableHead from "@dashboard/components/TableHead";
import TableRowLink from "@dashboard/components/TableRowLink";
import { ChannelInput } from "@dashboard/discounts/handlers";
@@ -13,8 +12,8 @@ import { DiscountErrorFragment } from "@dashboard/graphql";
import { renderCollection } from "@dashboard/misc";
import { getFormErrors } from "@dashboard/utils/errors";
import getDiscountErrorMessage from "@dashboard/utils/errors/discounts";
-import { Card, CardContent, TableBody, TableCell, Typography } from "@material-ui/core";
-import { Input, Text } from "@saleor/macaw-ui-next";
+import { TableBody, TableCell } from "@material-ui/core";
+import { Input, Skeleton, Text } from "@saleor/macaw-ui-next";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -49,15 +48,17 @@ const VoucherValue: React.FC = props => {
}));
return (
-
-
-
+
+
+
+ {intl.formatMessage({
+ id: "/oaqFS",
+ defaultMessage: "Value",
+ description: "section header",
+ })}
+
+
+
@@ -166,20 +167,20 @@ const VoucherValue: React.FC = props => {
defaultMessage="Apply only to a single cheapest eligible product"
description="voucher application, switch button"
/>
-
+
-
+
>
}
checked={data.applyOncePerOrder}
onChange={onChange}
disabled={disabled}
/>
-
-
+
+
);
};
diff --git a/src/discounts/discountsUrls.ts b/src/discounts/discountsUrls.ts
index 2ee8175cdc3..2f4992ebc27 100644
--- a/src/discounts/discountsUrls.ts
+++ b/src/discounts/discountsUrls.ts
@@ -10,6 +10,8 @@ export enum DiscountListUrlSortField {
const discountSection = "/discounts/sales";
+export const discountSalesListPath = discountSection;
+
export type DiscountListUrlDialog = TabActionDialog;
export type DiscountListUrlSort = Sort;
diff --git a/src/discounts/index.tsx b/src/discounts/index.tsx
index 58291ee3c28..5ef0ffa245a 100644
--- a/src/discounts/index.tsx
+++ b/src/discounts/index.tsx
@@ -1,11 +1,15 @@
-import { ConditionalDiscountFilterProvider } from "@dashboard/components/ConditionalFilter";
+import {
+ ConditionalDiscountFilterProvider,
+ ConditionalVoucherFilterProvider,
+} from "@dashboard/components/ConditionalFilter";
+import { Route } from "@dashboard/components/Router";
import { useFlag } from "@dashboard/featureFlags";
import { sectionNames } from "@dashboard/intl";
import { asSortParams } from "@dashboard/utils/sort";
import { parse as parseQs } from "qs";
import React from "react";
import { useIntl } from "react-intl";
-import { Route, RouteComponentProps, Switch } from "react-router-dom";
+import { RouteComponentProps, Switch } from "react-router-dom";
import { WindowTitle } from "../components/WindowTitle";
import { DiscountListUrlQueryParams, DiscountListUrlSortField } from "./discountsUrls";
@@ -80,7 +84,11 @@ const VoucherListView: React.FC> = ({ location }) => {
VoucherListUrlSortField.code,
);
- return ;
+ return (
+
+
+
+ );
};
const VoucherDetailsView: React.FC> = ({ match, location }) => {
const qs = parseQs(location.search.substr(1));
diff --git a/src/discounts/queries.ts b/src/discounts/queries.ts
index 04f3668a0a2..ed149554145 100644
--- a/src/discounts/queries.ts
+++ b/src/discounts/queries.ts
@@ -229,27 +229,7 @@ export const PromotionDetailsQuery = /* GraphQL */ `
name
description
channels {
- id
- isActive
- name
- slug
- currencyCode
- defaultCountry {
- code
- country
- }
- stockSettings {
- allocationStrategy
- }
- hasOrders
- orderSettings {
- markAsPaidStrategy
- deleteExpiredOrdersAfter
- allowUnpaidOrders
- }
- paymentSettings {
- defaultTransactionFlowStrategy
- }
+ ...PromotionRuleChannel
}
giftIds
rewardType
diff --git a/src/discounts/views/DiscountDetails/DiscountDetails.tsx b/src/discounts/views/DiscountDetails/DiscountDetails.tsx
index 6042f9c4411..fb99bf7999d 100644
--- a/src/discounts/views/DiscountDetails/DiscountDetails.tsx
+++ b/src/discounts/views/DiscountDetails/DiscountDetails.tsx
@@ -2,7 +2,8 @@ import useAppChannel from "@dashboard/components/AppLayout/AppChannelContext";
import { WindowTitle } from "@dashboard/components/WindowTitle";
import { DiscountDeleteModal } from "@dashboard/discounts/components/DiscountDeleteModal";
import { DiscountDetailsPage } from "@dashboard/discounts/components/DiscountDetailsPage";
-import { discountListUrl, DiscountUrlQueryParams } from "@dashboard/discounts/discountsUrls";
+import { discountSalesListPath, DiscountUrlQueryParams } from "@dashboard/discounts/discountsUrls";
+import { useBackLinkWithState } from "@dashboard/hooks/useBackLinkWithState";
import useNavigator from "@dashboard/hooks/useNavigator";
import { commonMessages } from "@dashboard/intl";
import { getMutationErrors } from "@dashboard/misc";
@@ -34,6 +35,9 @@ export const DiscountDetails = ({ id }: DiscountDetailsProps) => {
const { promotionRuleUpdate, promotionRuleUpdateOpts } = usePromotionRuleUpdate(id);
const { promotionRuleCreate, promotionRuleCreateOpts } = usePromotionRuleCreate(id);
const { promotionRuleDelete, promotionRuleDeleteOpts } = usePromotionRuleDelete(id);
+ const discountListBackLink = useBackLinkWithState({
+ path: discountSalesListPath,
+ });
const onSubmit = createUpdateHandler(promotionData?.promotion, variables =>
promotionUpdate({ variables }),
);
@@ -74,7 +78,7 @@ export const DiscountDetails = ({ id }: DiscountDetailsProps) => {
promotionRuleDeleteOpts.loading
}
onBack={() => {
- navigate(discountListUrl());
+ navigate(discountListBackLink);
}}
channels={availableChannels}
onSubmit={onSubmit}
@@ -86,6 +90,7 @@ export const DiscountDetails = ({ id }: DiscountDetailsProps) => {
ruleCreateButtonState={promotionRuleCreateOpts.status}
onRuleDeleteSubmit={onRuleDeleteSubmit}
ruleDeleteButtonState={promotionRuleDeleteOpts.status}
+ backLinkHref={discountListBackLink}
/>
= ({ id, params }) => {
confirmButtonLabel={intl.formatMessage(messages.saleDetailsUnassignCategory)}
>
{canOpenBulkActionDialog && (
-
- {params.ids.length},
- }}
- />
-
+ {params.ids.length},
+ }}
+ />
)}
= ({ id, params }) => {
confirmButtonLabel={intl.formatMessage(messages.saleDetailsUnassignCollection)}
>
{canOpenBulkActionDialog && (
-
- {params.ids.length},
- }}
- />
-
+ {params.ids.length},
+ }}
+ />
)}
= ({ id, params }) => {
confirmButtonLabel={intl.formatMessage(messages.saleDetailsUnassignProduct)}
>
{canOpenBulkActionDialog && (
-
- {params.ids.length},
- }}
- />
-
+ {params.ids.length},
+ }}
+ />
)}
= ({ id, params }) => {
confirmButtonLabel={intl.formatMessage(messages.saleDetailsUnassignVariant)}
>
{canOpenBulkActionDialog && (
-
- {params.ids.length},
- }}
- />
-
+ {params.ids.length},
+ }}
+ />
)}
= ({ id, params }) => {
})
}
>
-
- {maybe(() => data.sale.name, "...")},
- }}
- />
-
+ {maybe(() => data.sale.name, "...")},
+ }}
+ />
);
diff --git a/src/discounts/views/SaleList/SaleList.tsx b/src/discounts/views/SaleList/SaleList.tsx
index b9c0ada65f3..fb006288573 100644
--- a/src/discounts/views/SaleList/SaleList.tsx
+++ b/src/discounts/views/SaleList/SaleList.tsx
@@ -21,7 +21,6 @@ import createFilterHandlers from "@dashboard/utils/handlers/filterHandlers";
import createSortHandler from "@dashboard/utils/handlers/sortHandler";
import { mapEdgesToItems, mapNodeToChoice } from "@dashboard/utils/maps";
import { getSortParams } from "@dashboard/utils/sort";
-import { DialogContentText } from "@material-ui/core";
import isEqual from "lodash/isEqual";
import React, { useCallback, useEffect } from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -134,7 +133,10 @@ export const SaleList: React.FC = ({ params }) => {
return;
}
- const rowsIds = rows.map(row => sales[row].id);
+ const rowsIds = rows
+ .filter(row => typeof sales[row] !== "undefined")
+ .map(row => sales[row].id);
+
const haveSaveValues = isEqual(rowsIds, selectedRowIds);
if (!haveSaveValues) {
@@ -197,17 +199,15 @@ export const SaleList: React.FC = ({ params }) => {
})}
variant="delete"
>
-
- {selectedRowIds.length},
- }}
- />
-
+ {selectedRowIds.length},
+ }}
+ />
{
+ it("should not call channel update when voucherCreate return error", async () => {
+ // Arrange
+ const voucherCreate = jest.fn().mockResolvedValue({ errors: ["error"] });
+ const updateChannels = jest.fn();
+ const validateFn = jest.fn().mockReturnValue(true);
+ const handler = createHandler(voucherCreate, updateChannels, validateFn);
+
+ // Act
+ const result = await handler(formData);
+
+ // Assert
+ expect(result).toEqual({ errors: ["Could not update channels"] });
+ expect(voucherCreate).toHaveBeenCalled();
+ expect(updateChannels).not.toHaveBeenCalled();
+ });
+
+ it("should call channel update when voucherCreate successes", async () => {
+ // Arrange
+ const voucherCreate = jest
+ .fn()
+ .mockResolvedValue({ data: { voucherCreate: { voucher: { id: "id" } } } });
+ const updateChannels = jest.fn();
+ const validateFn = jest.fn().mockReturnValue(true);
+ const handler = createHandler(voucherCreate, updateChannels, validateFn);
+
+ // Act
+ await handler(formData);
+
+ // Assert
+ expect(voucherCreate).toHaveBeenCalled();
+ expect(updateChannels).toHaveBeenCalled();
+ });
+});
diff --git a/src/discounts/views/VoucherCreate/handlers.ts b/src/discounts/views/VoucherCreate/handlers.ts
index 20d3b6c3dfb..2e24357810e 100644
--- a/src/discounts/views/VoucherCreate/handlers.ts
+++ b/src/discounts/views/VoucherCreate/handlers.ts
@@ -1,4 +1,3 @@
-// @ts-strict-ignore
import { FetchResult } from "@apollo/client";
import { VoucherDetailsPageFormData } from "@dashboard/discounts/components/VoucherDetailsPage";
import { getChannelsVariables } from "@dashboard/discounts/handlers";
@@ -60,6 +59,12 @@ export function createHandler(
return { errors };
}
+ if (!response?.data?.voucherCreate?.voucher) {
+ return {
+ errors: ["Could not update channels"],
+ };
+ }
+
const channelsUpdateErrors = await extractMutationErrors(
updateChannels({
variables: getChannelsVariables(
diff --git a/src/discounts/views/VoucherDetails/VoucherDetails.tsx b/src/discounts/views/VoucherDetails/VoucherDetails.tsx
index fb7ee00833c..b7de651d009 100644
--- a/src/discounts/views/VoucherDetails/VoucherDetails.tsx
+++ b/src/discounts/views/VoucherDetails/VoucherDetails.tsx
@@ -55,7 +55,6 @@ import useCollectionSearch from "@dashboard/searches/useCollectionSearch";
import useProductSearch from "@dashboard/searches/useProductSearch";
import createDialogActionHandlers from "@dashboard/utils/handlers/dialogActionHandlers";
import createMetadataUpdateHandler from "@dashboard/utils/handlers/metadataUpdateHandler";
-import { DialogContentText } from "@material-ui/core";
import React, { useMemo, useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -504,17 +503,15 @@ export const VoucherDetails: React.FC = ({ id, params }) =>
})}
>
{canOpenBulkActionDialog && (
-
- {params.ids.length},
- }}
- />
-
+ {params.ids.length},
+ }}
+ />
)}
= ({ id, params }) =>
})}
>
{canOpenBulkActionDialog && (
-
- {params.ids.length},
- }}
- />
-
+ {params.ids.length},
+ }}
+ />
)}
= ({ id, params }) =>
})}
>
{canOpenBulkActionDialog && (
-
- {params.ids.length},
- }}
- />
-
+ {params.ids.length},
+ }}
+ />
)}
= ({ id, params }) =>
})
}
>
-
- {maybe(() => data.voucher.name, "...")},
- }}
- />
-
+ {maybe(() => data.voucher.name, "...")},
+ }}
+ />
);
diff --git a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts
index 23fe1456f69..a328c94b3e3 100644
--- a/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts
+++ b/src/discounts/views/VoucherDetails/hooks/useVoucherCodesClient.ts
@@ -2,7 +2,7 @@ import { VoucherCode } from "@dashboard/discounts/components/VoucherCodesDatagri
import { GenerateMultipleVoucherCodeFormData } from "@dashboard/discounts/components/VoucherCodesGenerateDialog";
import { useVoucherCodesPagination } from "@dashboard/discounts/components/VoucherCreatePage/hooks/useVoucherCodesPagination";
import {
- generateMultipleIds,
+ generateMultipleVoucherCodes,
voucherCodeExists,
} from "@dashboard/discounts/components/VoucherCreatePage/utils";
import { UseListSettings } from "@dashboard/hooks/useListSettings";
@@ -52,7 +52,7 @@ export const useVoucherCodesClient = (
quantity,
prefix,
}: GenerateMultipleVoucherCodeFormData) => {
- setAddedVoucherCodes(codes => [...generateMultipleIds(quantity, prefix), ...codes]);
+ setAddedVoucherCodes(codes => [...generateMultipleVoucherCodes(quantity, prefix), ...codes]);
switchToClientPagination();
resetPage();
};
diff --git a/src/discounts/views/VoucherList/VoucherList.tsx b/src/discounts/views/VoucherList/VoucherList.tsx
index bb62a7b17a5..9d246b3dd40 100644
--- a/src/discounts/views/VoucherList/VoucherList.tsx
+++ b/src/discounts/views/VoucherList/VoucherList.tsx
@@ -1,9 +1,12 @@
// @ts-strict-ignore
import ActionDialog from "@dashboard/components/ActionDialog";
import useAppChannel from "@dashboard/components/AppLayout/AppChannelContext";
+import { useConditionalFilterContext } from "@dashboard/components/ConditionalFilter";
+import { creatVoucherQueryVariables } from "@dashboard/components/ConditionalFilter/queryVariables";
import DeleteFilterTabDialog from "@dashboard/components/DeleteFilterTabDialog";
import SaveFilterTabDialog from "@dashboard/components/SaveFilterTabDialog";
import { WindowTitle } from "@dashboard/components/WindowTitle";
+import { useFlag } from "@dashboard/featureFlags";
import { useVoucherBulkDeleteMutation, useVoucherListQuery } from "@dashboard/graphql";
import { useFilterPresets } from "@dashboard/hooks/useFilterPresets";
import useListSettings from "@dashboard/hooks/useListSettings";
@@ -22,7 +25,6 @@ import createFilterHandlers from "@dashboard/utils/handlers/filterHandlers";
import createSortHandler from "@dashboard/utils/handlers/sortHandler";
import { mapEdgesToItems, mapNodeToChoice } from "@dashboard/utils/maps";
import { getSortParams } from "@dashboard/utils/sort";
-import { DialogContentText } from "@material-ui/core";
import isEqual from "lodash/isEqual";
import React, { useCallback, useEffect } from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -40,6 +42,9 @@ export const VoucherList: React.FC = ({ params }) => {
const navigate = useNavigator();
const notify = useNotifier();
const { updateListSettings, settings } = useListSettings(ListViews.VOUCHER_LIST);
+ const { enabled: isNewGiftCardsFilterEnabled } = useFlag("new_filters");
+ const { valueProvider } = useConditionalFilterContext();
+ const { filters, channel } = creatVoucherQueryVariables(valueProvider.value);
usePaginationReset(voucherListUrl, params, settings.rowNumber);
@@ -63,9 +68,22 @@ export const VoucherList: React.FC = ({ params }) => {
}),
[params, settings.rowNumber],
);
+ const newFiltersQueryVariables = React.useMemo(
+ () => ({
+ ...paginationState,
+ filter: {
+ ...filters,
+ search: params.query,
+ },
+ sort: getSortQueryVariables(params),
+ channel,
+ }),
+ [params, settings.rowNumber, valueProvider.value],
+ );
+
const { data, refetch } = useVoucherListQuery({
displayLoader: true,
- variables: queryVariables,
+ variables: isNewGiftCardsFilterEnabled ? newFiltersQueryVariables : queryVariables,
});
const {
clearRowSelection,
@@ -198,17 +216,15 @@ export const VoucherList: React.FC = ({ params }) => {
})}
variant="delete"
>
-
- {selectedRowIds.length},
- }}
- />
-
+ {selectedRowIds.length},
+ }}
+ />
= ({ onClose, open }) => {
return (
<>
-
- {intl.formatMessage(messages.title)}
+
+ {intl.formatMessage(messages.title)}
{!loadingChannelCurrencies && (
formErrors = {},
}) => {
const intl = useIntl();
- const classes = useStyles({});
const { data: settingsData, loading: loadingSettings } = useGiftCardSettingsQuery();
const getInitialExpirySettingsData = (): Partial => {
if (loadingSettings) {
@@ -93,7 +92,7 @@ const GiftCardBulkCreateDialogForm: React.FC
error={!!formErrors?.count}
name="cardsAmount"
onChange={change}
- className={classes.fullWidthContainer}
+ fullWidth
label={intl.formatMessage(messages.giftCardsAmountLabel)}
value={cardsAmount}
helperText={getGiftCardErrorMessage(formErrors?.count, intl)}
@@ -106,7 +105,7 @@ const GiftCardBulkCreateDialogForm: React.FC
error={formErrors?.tags}
name="tags"
values={tags}
- toggleChange={change}
+ onChange={change}
/>
@@ -117,7 +116,7 @@ const GiftCardBulkCreateDialogForm: React.FC
- {intl.formatMessage(messages.bulkCreateExplanation)}
+ {intl.formatMessage(messages.bulkCreateExplanation)}
diff --git a/src/giftCards/GiftCardCreateDialog/GiftCardBulkCreateSuccessDialog.tsx b/src/giftCards/GiftCardCreateDialog/GiftCardBulkCreateSuccessDialog.tsx
index 2976b5ecb91..c5a8d6de876 100644
--- a/src/giftCards/GiftCardCreateDialog/GiftCardBulkCreateSuccessDialog.tsx
+++ b/src/giftCards/GiftCardCreateDialog/GiftCardBulkCreateSuccessDialog.tsx
@@ -1,6 +1,6 @@
-import { Button } from "@dashboard/components/Button";
+import { DashboardModal } from "@dashboard/components/Modal";
import { DialogProps } from "@dashboard/types";
-import { Dialog, DialogActions, DialogContent, DialogTitle, Typography } from "@material-ui/core";
+import { Button, Text } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
@@ -25,25 +25,28 @@ const GiftCardBulkCreateSuccessDialog: React.FC
-
-
- {intl.formatMessage(messages.bulkCreateIssuedTitle)}
-
-
-