Skip to content

Commit 3e3e6c3

Browse files
authored
fix(dashboard): show correct color indicators for payment and fulfillment status columns for view_configuration feature flag (medusajs#14215)
## Summary **What** — What changes are introduced in this PR? Show correct color indicator for payment and fulfillment status columns when `view_configuration` feature flag is enabled on order data table. **Why** — Why are these changes relevant or necessary? For non canceled status, grey default indicator was shown, as these columns weren't handled with their dedicated helper functions. **How** — How have these changes been implemented? Updated `StatusRenderer` to resolve the label and color for these columns with their helper functions, just like we do for the normal order table. **Testing** — How have these changes been tested, or how can the reviewer test the feature? Validated Admin UI shows correct color indicators when `view_configuration` is enabled. --- ## 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 CORE-1309
1 parent 24c469d commit 3e3e6c3

File tree

2 files changed

+107
-83
lines changed

2 files changed

+107
-83
lines changed

.changeset/tough-jeans-shop.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@medusajs/dashboard": patch
3+
---
4+
5+
fix(dashboard): show correct color indicators for payment and fulfillment status columns for `view_configuration` feature flag

packages/admin/dashboard/src/lib/table/cell-renderers.tsx

Lines changed: 102 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ import { DisplayIdCell } from "../../components/table/table-cells/order/display-
1313
import { TotalCell } from "../../components/table/table-cells/order/total-cell"
1414
import { MoneyAmountCell } from "../../components/table/table-cells/common/money-amount-cell"
1515
import { TFunction } from "i18next"
16-
import { toCamelCase } from "../common"
16+
import {
17+
getOrderPaymentStatus,
18+
getOrderFulfillmentStatus,
19+
} from "../order-helpers"
1720

1821
export type CellRenderer<TData = any> = (
1922
value: any,
@@ -27,96 +30,104 @@ export type RendererRegistry = Map<string, CellRenderer>
2730
const cellRenderers: RendererRegistry = new Map()
2831

2932
const getNestedValue = (obj: any, path: string) => {
30-
return path.split('.').reduce((current, key) => current?.[key], obj)
33+
return path.split(".").reduce((current, key) => current?.[key], obj)
3134
}
3235

3336
const TextRenderer: CellRenderer = (value, _row, _column, _t) => {
34-
if (value === null || value === undefined) return '-'
37+
if (value === null || value === undefined) return "-"
3538
return String(value)
3639
}
3740

3841
const CountRenderer: CellRenderer = (value, _row, _column, t) => {
3942
const items = value || []
4043
const count = Array.isArray(items) ? items.length : 0
41-
return t('general.items', { count })
44+
return t("general.items", { count })
4245
}
4346

4447
const StatusRenderer: CellRenderer = (value, row, column, t) => {
45-
if (!value) return '-'
48+
if (!value) return "-"
4649

47-
if (column.field === 'status' && row.status && (row.handle || row.is_giftcard !== undefined)) {
50+
if (
51+
column.field === "status" &&
52+
row.status &&
53+
(row.handle || row.is_giftcard !== undefined)
54+
) {
4855
return <ProductStatusCell status={row.status} />
4956
}
5057

51-
// Generic status badge
58+
if (column.context === "payment" && t) {
59+
const { label, color } = getOrderPaymentStatus(t, value)
60+
return <StatusBadge color={color}>{label}</StatusBadge>
61+
}
62+
63+
if (column.context === "fulfillment" && t) {
64+
const { label, color } = getOrderFulfillmentStatus(t, value)
65+
return <StatusBadge color={color}>{label}</StatusBadge>
66+
}
67+
68+
// Generic status badge for other status types
5269
const getStatusColor = (status: string) => {
5370
switch (status?.toLowerCase()) {
54-
case 'active':
55-
case 'published':
56-
case 'fulfilled':
57-
case 'paid':
58-
return 'green'
59-
case 'pending':
60-
case 'proposed':
61-
case 'processing':
62-
return 'orange'
63-
case 'draft':
64-
return 'grey'
65-
case 'rejected':
66-
case 'failed':
67-
case 'canceled':
68-
return 'red'
71+
case "active":
72+
case "published":
73+
case "fulfilled":
74+
case "paid":
75+
return "green"
76+
case "pending":
77+
case "proposed":
78+
case "processing":
79+
return "orange"
80+
case "draft":
81+
return "grey"
82+
case "rejected":
83+
case "failed":
84+
case "canceled":
85+
return "red"
6986
default:
70-
return 'grey'
87+
return "grey"
7188
}
7289
}
7390

7491
// Use existing translation keys where available
75-
const getTranslatedStatus = (status: string, column: HttpTypes.AdminColumn): string => {
92+
const getTranslatedStatus = (status: string): string => {
7693
if (!t) return status
7794

7895
const lowerStatus = status.toLowerCase()
79-
const camelCaseStatus = toCamelCase(lowerStatus)
8096
switch (lowerStatus) {
81-
case 'active':
82-
return t('general.active', 'Active') as string
83-
case 'published':
84-
return t('products.productStatus.published', 'Published') as string
85-
case 'draft':
86-
return t('orders.status.draft', 'Draft') as string
87-
case 'pending':
88-
return t('orders.status.pending', 'Pending') as string
89-
case 'canceled':
90-
return t('orders.status.canceled', 'Canceled') as string
97+
case "active":
98+
return t("general.active", "Active") as string
99+
case "published":
100+
return t("products.productStatus.published", "Published") as string
101+
case "draft":
102+
return t("orders.status.draft", "Draft") as string
103+
case "pending":
104+
return t("orders.status.pending", "Pending") as string
105+
case "canceled":
106+
return t("orders.status.canceled", "Canceled") as string
91107
default:
92-
if (column.context === 'payment') {
93-
return t(`orders.payment.status.${camelCaseStatus}`, status) as string
94-
}
95-
if (column.context === 'fulfillment') {
96-
return t(`orders.fulfillment.status.${camelCaseStatus}`, status) as string
97-
}
98108
// Try generic status translation with fallback
99109
return t(`status.${lowerStatus}`, status) as string
100110
}
101111
}
102112

103-
const translatedValue = getTranslatedStatus(value, column)
113+
const translatedValue = getTranslatedStatus(value)
104114

105115
return (
106-
<StatusBadge color={getStatusColor(value)}>
107-
{translatedValue}
108-
</StatusBadge>
116+
<StatusBadge color={getStatusColor(value)}>{translatedValue}</StatusBadge>
109117
)
110118
}
111119

112120
const BadgeListRenderer: CellRenderer = (value, row, column, t) => {
113121
// For sales channels
114-
if (column.field === 'sales_channels_display' || column.field === 'sales_channels') {
122+
if (
123+
column.field === "sales_channels_display" ||
124+
column.field === "sales_channels"
125+
) {
115126
return <SalesChannelsCell salesChannels={row.sales_channels} />
116127
}
117128

118129
// Generic badge list
119-
if (!Array.isArray(value)) return '-'
130+
if (!Array.isArray(value)) return "-"
120131

121132
const items = value.slice(0, 2)
122133
const remaining = value.length - 2
@@ -125,12 +136,16 @@ const BadgeListRenderer: CellRenderer = (value, row, column, t) => {
125136
<div className="flex gap-1">
126137
{items.map((item, index) => (
127138
<Badge key={index} size="xsmall">
128-
{typeof item === 'string' ? item : item.name || item.title || '-'}
139+
{typeof item === "string" ? item : item.name || item.title || "-"}
129140
</Badge>
130141
))}
131142
{remaining > 0 && (
132143
<Badge size="xsmall" color="grey">
133-
{t ? t('general.plusCountMore', '+ {{count}} more', { count: remaining }) : `+${remaining}`}
144+
{t
145+
? t("general.plusCountMore", "+ {{count}} more", {
146+
count: remaining,
147+
})
148+
: `+${remaining}`}
134149
</Badge>
135150
)}
136151
</div>
@@ -152,7 +167,9 @@ const VariantsRenderer: CellRenderer = (_, row, _column, _t) => {
152167
// Order-specific renderers
153168
const CustomerNameRenderer: CellRenderer = (_, row, _column, t) => {
154169
if (row.customer?.first_name || row.customer?.last_name) {
155-
const fullName = `${row.customer.first_name || ''} ${row.customer.last_name || ''}`.trim()
170+
const fullName = `${row.customer.first_name || ""} ${
171+
row.customer.last_name || ""
172+
}`.trim()
156173
if (fullName) return fullName
157174
}
158175

@@ -166,20 +183,20 @@ const CustomerNameRenderer: CellRenderer = (_, row, _column, t) => {
166183
return row.customer.phone
167184
}
168185

169-
return t ? t('customers.guest', 'Guest') : 'Guest'
186+
return t ? t("customers.guest", "Guest") : "Guest"
170187
}
171188

172189
const AddressSummaryRenderer: CellRenderer = (_, row, column, _t) => {
173190
let address = null
174-
if (column.field === 'shipping_address_display') {
191+
if (column.field === "shipping_address_display") {
175192
address = row.shipping_address
176-
} else if (column.field === 'billing_address_display') {
193+
} else if (column.field === "billing_address_display") {
177194
address = row.billing_address
178195
} else {
179196
address = row.shipping_address || row.billing_address
180197
}
181198

182-
if (!address) return '-'
199+
if (!address) return "-"
183200

184201
const parts = []
185202

@@ -193,14 +210,14 @@ const AddressSummaryRenderer: CellRenderer = (_, row, column, _t) => {
193210
if (address.postal_code) locationParts.push(address.postal_code)
194211

195212
if (locationParts.length > 0) {
196-
parts.push(locationParts.join(', '))
213+
parts.push(locationParts.join(", "))
197214
}
198215

199216
if (address.country_code) {
200217
parts.push(address.country_code.toUpperCase())
201218
}
202219

203-
return parts.join('') || '-'
220+
return parts.join("") || "-"
204221
}
205222

206223
const CountryCodeRenderer: CellRenderer = (_, row, _column, _t) => {
@@ -239,36 +256,38 @@ const DisplayIdRenderer: CellRenderer = (value, _row, _column, _t) => {
239256
}
240257

241258
const CurrencyRenderer: CellRenderer = (value, row, _column, _t) => {
242-
const currencyCode = row.currency_code || 'USD'
243-
return <MoneyAmountCell currencyCode={currencyCode} amount={value} align="right" />
259+
const currencyCode = row.currency_code || "USD"
260+
return (
261+
<MoneyAmountCell currencyCode={currencyCode} amount={value} align="right" />
262+
)
244263
}
245264

246265
const TotalRenderer: CellRenderer = (value, row, _column, _t) => {
247-
const currencyCode = row.currency_code || 'USD'
266+
const currencyCode = row.currency_code || "USD"
248267
return <TotalCell currencyCode={currencyCode} total={value} />
249268
}
250269

251270
// Register built-in renderers
252-
cellRenderers.set('text', TextRenderer)
253-
cellRenderers.set('count', CountRenderer)
254-
cellRenderers.set('status', StatusRenderer)
255-
cellRenderers.set('badge_list', BadgeListRenderer)
256-
cellRenderers.set('date', DateRenderer)
257-
cellRenderers.set('timestamp', DateRenderer)
258-
cellRenderers.set('currency', CurrencyRenderer)
259-
cellRenderers.set('total', TotalRenderer)
271+
cellRenderers.set("text", TextRenderer)
272+
cellRenderers.set("count", CountRenderer)
273+
cellRenderers.set("status", StatusRenderer)
274+
cellRenderers.set("badge_list", BadgeListRenderer)
275+
cellRenderers.set("date", DateRenderer)
276+
cellRenderers.set("timestamp", DateRenderer)
277+
cellRenderers.set("currency", CurrencyRenderer)
278+
cellRenderers.set("total", TotalRenderer)
260279

261280
// Register product-specific renderers
262-
cellRenderers.set('product_info', ProductInfoRenderer)
263-
cellRenderers.set('collection', CollectionRenderer)
264-
cellRenderers.set('variants', VariantsRenderer)
265-
cellRenderers.set('sales_channels_list', BadgeListRenderer)
281+
cellRenderers.set("product_info", ProductInfoRenderer)
282+
cellRenderers.set("collection", CollectionRenderer)
283+
cellRenderers.set("variants", VariantsRenderer)
284+
cellRenderers.set("sales_channels_list", BadgeListRenderer)
266285

267286
// Register order-specific renderers
268-
cellRenderers.set('customer_name', CustomerNameRenderer)
269-
cellRenderers.set('address_summary', AddressSummaryRenderer)
270-
cellRenderers.set('country_code', CountryCodeRenderer)
271-
cellRenderers.set('display_id', DisplayIdRenderer)
287+
cellRenderers.set("customer_name", CustomerNameRenderer)
288+
cellRenderers.set("address_summary", AddressSummaryRenderer)
289+
cellRenderers.set("country_code", CountryCodeRenderer)
290+
cellRenderers.set("display_id", DisplayIdRenderer)
272291

273292
export function getCellRenderer(
274293
renderType?: string,
@@ -279,21 +298,21 @@ export function getCellRenderer(
279298
}
280299

281300
switch (dataType) {
282-
case 'number':
283-
case 'string':
301+
case "number":
302+
case "string":
284303
return TextRenderer
285-
case 'date':
304+
case "date":
286305
return DateRenderer
287-
case 'boolean':
306+
case "boolean":
288307
return (value, _row, _column, t) => {
289308
if (t) {
290-
return value ? t('fields.yes', 'Yes') : t('fields.no', 'No')
309+
return value ? t("fields.yes", "Yes") : t("fields.no", "No")
291310
}
292-
return value ? 'Yes' : 'No'
311+
return value ? "Yes" : "No"
293312
}
294-
case 'enum':
313+
case "enum":
295314
return StatusRenderer
296-
case 'currency':
315+
case "currency":
297316
return CurrencyRenderer
298317
default:
299318
return TextRenderer

0 commit comments

Comments
 (0)