## Summary
**What** — What changes are introduced in this PR?
*Adds a new pt-PT translation file for the Medusa Admin Dashboard and registers the Portuguese (Portugal) locale in the i18n configuration.*
**Why** — Why are these changes relevant or necessary?
*To provide full localization support for users in Portugal. The Admin currently includes a pt-BR translation, and this PR adds proper European Portuguese equivalents with consistent terminology and grammar.*
**How** — How have these changes been implemented?
*Created a new file ptPT.json following the same structure as en.json and ptBR.json.*
*Registered the "pt-PT" locale in the i18n resources and language selector.*
*Verified placeholder consistency ({{ }}, <0></0>, etc.) and kept all keys identical to the English source.*
**Testing** — How have these changes been tested, or how can the reviewer test the feature?
*Please provide answer here*
---
## Examples
Provide examples or code snippets that demonstrate how this feature works, or how it can be used in practice.
This helps with documentation and ensures maintainers can quickly understand and verify the change.
```ts
// Example usage
```
---
## Checklist
Please ensure the following before requesting a review:
- [ ] I have added a **changeset** for this PR
- Every non-breaking change should be marked as a **patch**
- To add a changeset, run `yarn changeset` and follow the prompts
- [ x] The changes are covered by relevant **tests**
- [x ] I have verified the code works as intended locally
- [x ] I have linked the related issue(s) if applicable
---
## Additional Context
Add any additional context, related issues, or references that might help the reviewer understand this PR.
---
> [!NOTE]
> Adds European Portuguese (`ptPT`) translations and registers the locale in i18n resources and the language selector.
>
> - **i18n**:
> - Add `ptPT` translation file `packages/admin/dashboard/src/i18n/translations/ptPT.json`.
> - Register `ptPT` in `packages/admin/dashboard/src/i18n/translations/index.ts` resources.
> - Register `ptPT` in `packages/admin/dashboard/src/i18n/languages.ts` with `date-fns` locale and display name "Português (Portugal)".
> - **Changeset**:
> - Add patch changeset for `@medusajs/dashboard`.
>
> <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 4cf30255609fa33d0c0362858c35e094b97d68e1. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup>
Co-authored-by: William Bouchard <46496014+willbouch@users.noreply.github.com>
## Summary
**What** — What changes are introduced in this PR?
Fix to prevent InfiniteList component from falling into an infinite loop of requests.
Before:
Uploading Grabación de pantalla 2025-11-03 a la(s) 11.34.55 p. m..mov…
**Why** — Why are these changes relevant or necessary?
The current dependency array of the useEffect in charge of issuing the next/previous fetch calls for pagination, include the functions from `useInfiniteQuery` in its dependency array as well as its body. This causes the component to render infinitely, as the functions reference change on every render.
**How** — How have these changes been implemented?
- Updated the problematic dependency array to not include these functions.
- Included a useEffect and refs for both functions to always have the latest value.
**Testing** — How have these changes been tested, or how can the reviewer test the feature?
Tested locally that the bug that was happening before the fix was mitigated and i was able to paginate correctly.
After fix:
https://github.com/user-attachments/assets/17d41bf9-6b3f-437b-b2ce-10e4dcbe248a
---
## Examples
Provide examples or code snippets that demonstrate how this feature works, or how it can be used in practice.
This helps with documentation and ensures maintainers can quickly understand and verify the change.
```ts
// Example usage
```
---
## Checklist
Please ensure the following before requesting a review:
- [x] I have added a **changeset** for this PR
- Every non-breaking change should be marked as a **patch**
- To add a changeset, run `yarn changeset` and follow the prompts
- [ ] The changes are covered by relevant **tests**
- [x] I have verified the code works as intended locally
- [x] I have linked the related issue(s) if applicable
---
## Additional Context
Add any additional context, related issues, or references that might help the reviewer understand this PR.
closes SUP-2620
---
> [!NOTE]
> Prevents InfiniteList from entering an infinite fetch loop by storing pagination functions in refs and removing them from the effect dependency array.
>
> - **Dashboard**:
> - **`packages/admin/dashboard/src/components/common/infinite-list/infinite-list.tsx`**:
> - Store pagination callbacks in refs: `fetchNextPageRef`, `fetchPreviousPageRef`, synced via `useEffect`.
> - Update `IntersectionObserver` callbacks to call `ref.current()` instead of the functions directly.
> - Remove `fetchNextPage`/`fetchPreviousPage` from the `useEffect` dependency array to stabilize observer setup.
> - **Changeset**:
> - Patch release for `@medusajs/dashboard` describing the fix.
>
> <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e21d9998ac01ae048fa7e72713a2027d3fc8cfb6. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup>
* chore(): Cleanup and organize deps
* chore(): Cleanup and organize deps
* chore(): Cleanup and organize deps
* chore(): Cleanup and organize deps
* chore(): Cleanup and organize deps
* chore(): Cleanup and organize deps
* Create lucky-poets-scream.md
* chore(): Cleanup and organize deps
* chore(): Cleanup and organize deps
* chore(): Cleanup and organize deps
* chore(): Cleanup and organize deps
* dedupe snapshot this build
* split into 4 shard
* re configure packages integration tests
* re configure packages integration tests
* re configure packages integration tests
* re configure packages integration tests
* update scripts
* update scripts
* update scripts
* update scripts
* update scripts
* update scripts
* update scripts
* update scripts
* reduce shard for packages
## Summary
**What** — What changes are introduced in this PR?
- show thumbnail on the product variant list
- refactor variant image editor state management
- await revalidation before rendering form
**Testing** — How have these changes been tested, or how can the reviewer test the feature?
Manual testing
---
## Checklist
Please ensure the following before requesting a review:
- [x] I have added a **changeset** for this PR
- Every non-breaking change should be marked as a **patch**
- To add a changeset, run `yarn changeset` and follow the prompts
- [ ] The changes are covered by relevant **tests**
- [x] I have verified the code works as intended locally
- [ ] I have linked the related issue(s) if applicable
## Summary
**What**
Exports the type of medusa's i18n keys from the dashboard package, for autocomplete support.
**Why**
Currently i18next is not able to provide proper ts autocomplete support when adding translations to projects or plugins.
For example when adding a data table or form, I have to go back multiple times to the source i18n files in the medusa repo and search for the exact key name(is it "actions.confirm" or "general.confirm"? etc) and I forget it right after every single time.
Even if all medusa components were provided already translated, it's still very convinient to use keys from medusa(if context appropriate) for some custom components, since they are already translated into many languages(eg "yes", "no" and other very basic strings). Hence why ts support for the base keys would be very helpful
**How**
Modified the generateTypes script to also copy the `en.json` file to the dist folder, and export a `Resources` type with the inferred keys in index.d.ts.
This allows users to define their own i18next type definitions including the base "translation" namespace, example below.
**Testing**
Manual testing
---
## Examples
```ts
// In src/admin/i18next.d.ts
import type enTranslation from "./i18n/en.json" // custom keys
import type { Resources } from "@medusajs/dashboard" // medusa keys
declare module "i18next" {
interface CustomTypeOptions {
fallbackNS: "translation"
resources: {
translation: Resources["translation"]
// all custom namespaces need to merge Resources["translation"] as well
// otherwise when falling back to "translation", strings will have type "never"
myCustomNs: typeof enTranslation & Resources["translation"]
}
}
}
```
Then, both `useTranslation()` and `useTranslation("myCustomNs")` will have proper autocomplete support
---
## Checklist
Please ensure the following before requesting a review:
- [x] I have added a **changeset** for this PR
- Every non-breaking change should be marked as a **patch**
- To add a changeset, run `yarn changeset` and follow the prompts
- [x] The changes are covered by relevant **tests**
- [x] I have verified the code works as intended locally
- [x] I have linked the related issue(s) if applicable
## Summary
**What** — What changes are introduced in this PR?
This PR standardizes heading levels across dashboard components to maintain proper semantic HTML hierarchy.
**Why** — Why are these changes relevant or necessary?
*Please provide answer here*
**How** — How have these changes been implemented?
- Added optional `headingLevel` prop `"h1" | "h2" | "h3"` to `DataTable` component with default value of `"h1"`
- Modified `Heading` component usage to explicitly specify the appropriate level based on context
**Testing** — How have these changes been tested, or how can the reviewer test the feature?
*Please provide answer here*
---
## Checklist
Please ensure the following before requesting a review:
- [x] I have added a **changeset** for this PR
- Every non-breaking change should be marked as a **patch**
- To add a changeset, run `yarn changeset` and follow the prompts
- [ ] The changes are covered by relevant **tests**
- [x] I have verified the code works as intended locally
- [ ] I have linked the related issue(s) if applicable
* Limit the number of ids passed to the different queries to render the tooltip details to 10, for products, product types and shipping options
* Add changeset
* Extract common additional field computation into variable
* virtual i18n module
* changeset
* fallback ns
fallback to the default "translation" ns if the key isnt found. Allows to use a single "useTranslation("customNs")" hook for both custom and medusa-provided keys
* simplify merges
* optional for backward compat
* fix HMR
* fix generated deepMerge
* test
* feat(): version order credit lines
* undo last change
* adjust where
* remove date on ui
* Create five-donuts-obey.md
* add test
* nit comment
* woops
This pull request enhances the entity column generation logic in the admin views by adding support for including fields from additional GraphQL types, specifically for the `orders` entity. The changes allow more flexible and comprehensive column definitions by pulling in fields from related types (like `OrderDetail`) and updating the filtering and type resolution logic accordingly.
**This adding payment_status & fulfillment_status from OrderDetail in view configuration feature**
**Entity column generation enhancements:**
* Added the `ADDITIONAL_ENTITY_TYPES` mapping to specify extra GraphQL types whose fields should be included for certain entities (currently, `OrderDetail` for `orders`). ([packages/medusa/src/api/admin/views/[entity]/columns/helpers.tsR260-R263](diffhunk://#diff-ce197feb4e4d1273d9ee19126e284b65fdb4367f0871774a75add5c8cd749d02R260-R263))
* Updated the column generation process to collect fields from both the main entity type and any additional types, while properly filtering out arrays and excluded fields. ([packages/medusa/src/api/admin/views/[entity]/columns/helpers.tsR340-R345](diffhunk://#diff-ce197feb4e4d1273d9ee19126e284b65fdb4367f0871774a75add5c8cd749d02R340-R345), [packages/medusa/src/api/admin/views/[entity]/columns/helpers.tsR373-R414](diffhunk://#diff-ce197feb4e4d1273d9ee19126e284b65fdb4367f0871774a75add5c8cd749d02R373-R414))
* Changed field lookup logic to use a unified `entityFields` object and a new `additionalFieldDefinitions` map for extra fields, ensuring correct type info resolution for all columns. ([packages/medusa/src/api/admin/views/[entity]/columns/helpers.tsL344-R354](diffhunk://#diff-ce197feb4e4d1273d9ee19126e284b65fdb4367f0871774a75add5c8cd749d02L344-R354), [packages/medusa/src/api/admin/views/[entity]/columns/helpers.tsL411-R463](diffhunk://#diff-ce197feb4e4d1273d9ee19126e284b65fdb4367f0871774a75add5c8cd749d02L411-R463))
### What
Add a new `once` allocation strategy to promotions that limits application to a maximum number of items across the entire cart, rather than per line item.
### Why
Merchants want to create promotions that apply to a limited number of items across the entire cart. For example:
- "Get $10 off, applied to one item only"
- "20% off up to 2 items in your cart"
Current allocation strategies:
- `each`: Applies to each line item independently (respects `max_quantity` per item)
- `across`: Distributes proportionally across all items
Neither supports limiting total applications across the entire cart.
### How
Add `once` to the `ApplicationMethodAllocation` enum.
Behavior:
- Applies promotion to maximum `max_quantity` items across entire cart
- Always prioritizes lowest-priced eligible items first
- Distributes sequentially across items until quota exhausted
- Requires `max_quantity` field to be set
### Example Usage
**Scenario 1: Fixed discount**
```javascript
{
type: "fixed",
allocation: "once",
value: 10, // $10 off
max_quantity: 2 // Apply to 2 items max across cart
}
Cart:
- Item A: 3 units @ $100/unit
- Item B: 5 units @ $50/unit (lowest price)
Result: $20 discount on Item B (2 units × $10)
```
**Scenario 2: Distribution across items**
```javascript
{
type: "fixed",
allocation: "once",
value: 5,
max_quantity: 4
}
Cart:
- Item A: 2 units @ $50/unit
- Item B: 3 units @ $60/unit
Result:
- Item A: $10 discount (2 units × $5)
- Item B: $10 discount (2 units × $5, remaining quota)
```
**Scenario 3: Percentage discount - single item**
```javascript
{
type: "percentage",
allocation: "once",
value: 20, // 20% off
max_quantity: 3 // Apply to 3 items max
}
Cart:
- Item A: 5 units @ $100/unit
- Item B: 4 units @ $50/unit (lowest price)
Result: $30 discount on Item B (3 units × $50 × 20% = $30)
```
**Scenario 4: Percentage discount - distributed across items**
```javascript
{
type: "percentage",
allocation: "once",
value: 15, // 15% off
max_quantity: 5
}
Cart:
- Item A: 2 units @ $40/unit (lowest price)
- Item B: 4 units @ $80/unit
Result:
- Item A: $12 discount (2 units × $40 × 15% = $12)
- Item B: $36 discount (3 units × $80 × 15% = $36, remaining quota)
Total: $48 discount
```
**Scenario 5: Percentage with max_quantity = 1**
```javascript
{
type: "percentage",
allocation: "once",
value: 25, // 25% off
max_quantity: 1 // Only one item
}
Cart:
- Item A: 3 units @ $60/unit
- Item B: 2 units @ $30/unit (lowest price)
Result: $7.50 discount on Item B (1 unit × $30 × 25%)
```
* fix: replace CountrySelect fallback with Medusa Select
* Country Select Component Fix to use Medusa UI Select Component
* added Change set
* using the props supported by the Select
* value should be lowercased if passed from the pareant component
* fix province Select with medusa UI select and added change set
* bug fix the province with providing
---------
Co-authored-by: Aryan Patel <21cs038@charusat.edu.in>
Co-authored-by: William Bouchard <46496014+willbouch@users.noreply.github.com>
**What**
- implement promotion usage limits per customer/email
- fix registering spend usage over the limit
- fix type errors in promotion module tests
**How**
- introduce a new type of campaign budget that can be defined by an attribute such as customer id or email
- add `CampaignBudgetUsage` entity to keep track of the number of uses per attribute value
- update `registerUsage` and `computeActions` in the promotion module to work with the new type
- update `core-flows` to pass context needed for usage calculation to the promotion module
**Breaking**
- registering promotion usage now throws (and cart complete fails) if the budget limit is exceeded or if the cart completion would result in a breached limit
---
CLOSES CORE-1172
CLOSES CORE-1173
CLOSES CORE-1174
CLOSES CORE-1175
Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
In the order details page, clicking the copy button for customer phone number was incorrectly copying the email address instead of the phone number.
Co-authored-by: William Bouchard <46496014+willbouch@users.noreply.github.com>
**What**
- add InfiniteList on location selection for inventory level -> fixes issue with location pagination
- fix removal of location level for an inventory item
- refresh the levels table when locations are updated
- add search input for filtering locations
---
CLOSES CORE-1208
**What**
- a promotion couldn't be added to a campaign without a currency budget (on promotion details screen)
- fix fetching campaigns pagination issue
- move select to Combobox
- fix currency restriction and move warning description to the label hint
CLOSES CORE-1209
This PR just adds the stuff necessary to support refund reasons in the dashboard. It adds the option in the settings tab and allows viewing, creating, editing and deleting refund reasons. I hate to open such a big PR but most of it is copy pasted from the return reasons. Major difference is only the fact that refund reasons don't have a `value` field
* fix: add direction attribute to components and adjust styles for RTL support
* fix(data-grid): comment it out
* Added useDocumentDirection hook
* refactor: Integrate useDocumentDirection hook
* refactor: Standardize direction prop usage across components
* resolve
* fix: resolve build errors
* fix : remove unused useDocument
* Apply RTL styles for some components
* Create smooth-gorillas-hide.md
* refactor: update some styles for RTL support
---------
Co-authored-by: William Bouchard <46496014+willbouch@users.noreply.github.com>
This pull request introduces a minor update to the table configuration functionality in the dashboard package. The main change is the addition of pagination support through `offset` and `limit` query parameters.
This fix pagination with `view_configurations:true`
Pagination improvements:
* [`packages/admin/dashboard/src/hooks/table/use-table-configuration.tsx`](diffhunk://#diff-2cf338f1bf284cf3568eabc51107b9a3d51a4b830a81baae2362f608f7c8a55aL71-R71): Updated the `useTableConfiguration` hook to include `offset` and `limit` in the query parameters, enabling pagination for table data.
* [`.changeset/spicy-swans-grab.md`](diffhunk://#diff-1bada2c80b4c3b4ee3c8782ee24ca0183b1bee09aafd7fe130c481152458f1a4R1-R5): Documented the change as a minor update to `@medusajs/dashboard`, specifying the addition of `offset` and `limit` to query parameters in `useTableConfiguration`.
Related to #13086, #12440 and #12668
Currencies were added in the migrations, but not in the admin dashboard list, causing admin display errors.
This mod should fix that
Co-authored-by: William Bouchard <46496014+willbouch@users.noreply.github.com>
### Overview
This PR updates the fulfillment label rendering by replacing the deprecated .url field with the new tracking_url and label_url fields, following the MedusaJS FulfillmentLabel model.
### Changes
- Implemented conditional rendering for both tracking_url and label_url.
- If a tracking_url exists, it is displayed as a clickable link.
- Similarly, if a label_url exists, it is displayed as a clickable link.
- If neither link is provided, only the tracking number is shown.
- Maintained existing styling for interactive elements.

### Reference
This update is based on the MedusaJS FulfillmentLabel model:
https://docs.medusajs.com/resources/references/fulfillment/models/FulfillmentLabel
Please review the changes and provide feedback for further improvements.
Co-authored-by: William Bouchard <46496014+willbouch@users.noreply.github.com>