Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add i18n support #848

Merged
merged 46 commits into from
Jan 10, 2025
Merged
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
15d836f
feat: add i18n helper and provider
pfferrari Dec 11, 2024
e6c851e
feat: add i18n-locales package
pfferrari Dec 11, 2024
e8711c7
chore: export useTranslation
marcomontalbano Dec 11, 2024
503e3f4
perf: import useTranslation from app-elements in docs
pfferrari Dec 11, 2024
042e7c4
chore: rename localeUrl prop
pfferrari Dec 11, 2024
0d32536
feat: add translations for dictionaries
pfferrari Dec 12, 2024
ae8a0e3
fix: remove i18n package to ship locales with app-elements using `i18…
gciotola Dec 13, 2024
55529de
fix: remove `useTranslation` in functions (non-react components)
gciotola Dec 13, 2024
ecfdc63
feat: add translations for hooks
pfferrari Dec 16, 2024
5dbf39e
fix: use `ts` file to improve type definitions in consumer apps
gciotola Dec 16, 2024
ac2fa45
fix: update vite plugin hook
gciotola Dec 16, 2024
8a0ff85
fix: apply new structure to locales
gciotola Dec 16, 2024
dea3c4e
fix: add static type defs for locales
gciotola Dec 16, 2024
1fbcbd9
fix: add more keys for app-orders
gciotola Dec 17, 2024
fdb2699
fix: add new locale keys
gciotola Dec 17, 2024
36abcd7
fix: update locales import path
gciotola Dec 17, 2024
708802c
feat: add locales for composite components
pfferrari Dec 18, 2024
1f9020f
fix: reorganize empty states locale keys
gciotola Dec 18, 2024
a8ce6e3
chore: add new locales for forms components
pfferrari Dec 18, 2024
f89e320
fix: add new keys for app orders and links
gciotola Dec 18, 2024
5317ad2
fix: update translations for app orders
gciotola Dec 18, 2024
fcda3c7
chore: add locales for forms components
pfferrari Dec 18, 2024
34373f8
feat: add locales for resources components
pfferrari Dec 19, 2024
ba5dc1b
fix: add new translations keys for app customers
gciotola Dec 19, 2024
aef78bb
fix: add more keys of app-customers
gciotola Dec 19, 2024
c910794
fix: improve loading state in i18n provider
gciotola Dec 19, 2024
5fcf5ea
fix: add missing translations for app shipments
gciotola Dec 20, 2024
60551bc
chore: add locales for resources components
pfferrari Dec 20, 2024
bcb83cc
fix: export Trans component
gciotola Dec 20, 2024
ac82b7a
fix: update locales for orders and returns
gciotola Dec 20, 2024
d5862c8
fix: add missing locale keys
gciotola Dec 20, 2024
34a70e2
fix: update locale keys
gciotola Dec 20, 2024
e7324cf
fix: typos
gciotola Dec 20, 2024
da77d6a
fix: add locale in user object
gciotola Jan 2, 2025
46d7125
fix: update locale keys
gciotola Jan 3, 2025
5e67971
fix: add withLocale decorator in storybook
gciotola Jan 3, 2025
e22c77b
fix: add missing translations
gciotola Jan 3, 2025
1b73032
fix: add localization for date helpers
gciotola Jan 7, 2025
64ca6ef
docs: update date story with i18n s
gciotola Jan 7, 2025
99a117c
fix: update language code rules
gciotola Jan 7, 2025
7668b2a
fix: set locale as optional in date helpers
gciotola Jan 7, 2025
3dd6a5d
fix: pass correct locale to ResourceListItem date helpers
gciotola Jan 7, 2025
3eb3248
fix: remove unused `i18next-browser-languagedetecto` package
gciotola Jan 7, 2025
9ae2f39
fix: add missing locale keys
gciotola Jan 7, 2025
9a8d373
fix: add missing locale keys
gciotola Jan 7, 2025
acd34d0
docs: add basic documentation for `I18NProvider`
gciotola Jan 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: update locale keys
  • Loading branch information
gciotola committed Jan 7, 2025
commit 46d7125cc6a5b3723a1a59651374178a4ad5d058
21 changes: 6 additions & 15 deletions packages/app-elements/src/locales/en.ts
Original file line number Diff line number Diff line change
@@ -228,6 +228,7 @@ const en = {
missing_resource: 'Missing {{resource}}',
update_resource: 'Update {{resource}}',
add_up_to: 'You can add up to {{limit}} {{resource}}.',
all: 'All',
all_items: 'All items',
amount: 'Amount',
apply: 'Apply',
@@ -394,19 +395,6 @@ const en = {
share_whatsapp_text:
'Please follow this link to checkout your order *#{{number}}*: {{url}}'
},
filters_instructions: {
order_status: 'Order status',
payment_status: 'Payment status',
fulfillment_status: 'Fulfillment status',
archived: 'Archived',
only_archived: 'Only archived',
hide_archived: 'Hide archived',
show_all: 'Show all, both archived and not',
time_range: 'Time range',
search: 'Search',
name: 'Name',
amount: 'Amount'
},
tracking_details: {
contents_type: 'Contents type',
courier: 'Courier',
@@ -604,7 +592,9 @@ const en = {
ship_from: 'Ship from',
ship_to: 'Ship to',
origin: 'Origin',
weight: 'Weight'
weight: 'Weight',
parcel_item: '{{count}} item',
parcel_item_other: '{{count}} items'
},
tasks: {
pending: 'Pending',
@@ -668,7 +658,8 @@ const en = {
no_packages_found: 'No packages found for current stock location',
select_package: 'Select a package',
packing_items: 'items',
pack_items: 'Pack · {{items}}'
pack_items: 'Pack · {{items}}',
more_options: 'More options'
}
},
promotions: {
55 changes: 23 additions & 32 deletions packages/app-elements/src/locales/it.ts
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ const it: typeof en = {
new_resource: 'Crea {{resource}}',
missing_resource: '{{resource}} mancante',
add_up_to: 'Puoi aggiungere fino a {{limit}} {{resource}}.',
all: 'Tutti',
all_items: 'Tutti gli elementi',
amount: 'Importo',
apply: 'Applica',
@@ -37,7 +38,7 @@ const it: typeof en = {
filters: 'Filtri',
from: 'Dal',
to: 'Al',
info: 'Informazioni',
info: 'Info',
limit_reached: 'Limite raggiunto',
loading: 'Caricamento...',
manage_resource: 'Gestisci {{resource}}',
@@ -58,7 +59,7 @@ const it: typeof en = {
reference: 'Referenza',
reference_origin: 'Origine referenza',
remove: 'Rimuovi',
restocked: 'Rifornito',
restocked: 'Riassortito',
retry: 'Riprova',
saving: 'Salvataggio...',
search: 'Cerca...',
@@ -139,7 +140,7 @@ const it: typeof en = {
left_a_refund_note: 'ha lasciato una nota di rimborso',
resources: {
order_is: "L'ordine è",
order_was: "L'Ordine è stato",
order_was: "L'ordine è stato",
order_created: 'creato',
order_placed: 'piazzato',
order_cancelled: 'annullato',
@@ -150,17 +151,17 @@ const it: typeof en = {
order_fulfillment_is: "L'evasione dell'ordine è",
order_fulfillment_in_progress: 'in corso',
order_fulfillment_not_required: 'non richiesto',
return_number_was: 'Reso #{{number}} era stato',
return_number_was: 'Reso #{{number}} è stato',
return_approved: 'approvato',
return_cancelled: 'annullato',
return_received: 'ricevuto',
return_rejected: 'rifiutato',
return_shipped: 'spedito',
payment_of_was: 'Il pagamento di {{amount}} era stato',
payment_of_was: 'Il pagamento di {{amount}} è stato',
stock_transfer_completed: 'completato',
shipment_number_is: 'La spedizione #{{number}} è',
shipment_number_isbeing: 'La spedizione #{{number}} sta per essere',
shipment_number_was: 'La spedizione #{{number}} era',
shipment_number_was: 'La spedizione #{{number}} è',
shipment_on_hold: 'in attesa',
shipment_picked: 'presa',
shipment_packed: 'imballata',
@@ -179,19 +180,6 @@ const it: typeof en = {
share_whatsapp_text:
'Apri questo link per completare il tuo ordine *#{{number}}*: {{url}}'
},
filters_instructions: {
order_status: 'Stato ordine',
payment_status: 'Stato pagamento',
fulfillment_status: 'Stato spedizione',
archived: 'Archiviati',
only_archived: 'Solo archiviati',
hide_archived: 'Nascondi archiviati',
show_all: 'Mostra tutti, sia archiviati che non',
time_range: 'Intervallo di tempo',
search: 'Cerca',
name: 'Nome',
amount: 'Importo'
},
tracking_details: {
contents_type: 'Tipo di contenuto',
courier: 'Corriere',
@@ -529,18 +517,18 @@ const it: typeof en = {
confirm_return_cancellation:
'Sei sicuro di voler cancellare il reso #{{number}}',
delete_error: "Errore durante l'eliminazione del reso",
info: 'Informazioni',
info: 'Info',
timeline_requested_return:
'{{email}} ha richiesto un reso di {{count}} prodotto',
timeline_requested_return_other:
'{{email}} ha richiesto un reso di {{count}} prodotti',
timeline_shipped: 'Il resto è stato <strong>spedito</strong>',
timeline_received: 'Il resto è stato <strong>ricevuto</strong>',
timeline_cancelled: 'Il resto è stato <strong>cancellato</strong>',
timeline_archived: 'Il resto è stato <strong>archiviato</strong>',
timeline_approved: 'Il resto è stato <strong>approvato</strong>',
timeline_shipped: 'Il reso è stato <strong>spedito</strong>',
timeline_received: 'Il reso è stato <strong>ricevuto</strong>',
timeline_cancelled: 'Il reso è stato <strong>cancellato</strong>',
timeline_archived: 'Il reso è stato <strong>archiviato</strong>',
timeline_approved: 'Il reso è stato <strong>approvato</strong>',
timeline_item_code_restocked:
'Il prodotto {{code}} è stato <strong>rifornito</strong>',
'Il prodotto {{code}} è stato <strong>riassortito</strong>',
timeline_payment_of_amount_was_action:
'Il pagamento di {{amount}} è stato <strong>{{action}}</strong>',
timeline_action_of_amount_failed:
@@ -549,9 +537,9 @@ const it: typeof en = {
tasks: {
open: 'Aperti',
browse: 'Altro',
requested: 'Richiesti',
approved: 'Approvati',
shipped: 'Inviati',
requested: 'Da approvare',
approved: 'Da spedire',
shipped: 'Da ricevere',
all_returns: 'Tutti i resi',
archived: 'Archiviati'
},
@@ -565,7 +553,7 @@ const it: typeof en = {
cancel: 'Annulla reso',
ship: 'Segna come spedito',
receive: 'Ricevuto',
restock: 'Rifornisci',
restock: 'Restock',
archive: 'Archivia',
unarchive: 'Ripristina',
refund: 'Emetti un rimborso'
@@ -590,7 +578,9 @@ const it: typeof en = {
origin: 'Magazzino di partenza',
ship_from: 'Partenza da',
ship_to: 'Destinazione',
weight: 'Peso'
weight: 'Peso',
parcel_item: '{{count}} prodotto',
parcel_item_other: '{{count}} prodotti'
},
tasks: {
pending: 'Aperte',
@@ -654,7 +644,8 @@ const it: typeof en = {
no_packages_found: 'Nessun imballo trovato in questo magazzino',
select_package: 'Seleziona un imballo',
packing_items: 'Prodotti',
pack_items: 'Imballa elementi · {{items}}'
pack_items: 'Imballa elementi · {{items}}',
more_options: 'Altre opzioni'
}
},
promotions: {
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ import { Icon } from '#ui/atoms/Icon'
import cn from 'classnames'
import debounce from 'lodash/debounce'
import { forwardRef, useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'

export interface DropdownSearchProps {
/**
@@ -29,16 +30,11 @@ export interface DropdownSearchProps {
*/
export const DropdownSearch = forwardRef<HTMLInputElement, DropdownSearchProps>(
(
{
onSearch,
debounceMs = 500,
placeholder = 'Search...',
autoFocus,
...rest
},
{ onSearch, debounceMs = 500, placeholder, autoFocus, ...rest },
ref
): JSX.Element => {
const [searchValue, setSearchValue] = useState('')
const { t } = useTranslation()

const debouncedOnSearch = useCallback(debounce(onSearch, debounceMs), [
onSearch
@@ -64,7 +60,7 @@ export const DropdownSearch = forwardRef<HTMLInputElement, DropdownSearchProps>(
className={cn(
'pl-10 pr-8 py-2 bg-transparent min-w-max font-semibold text-sm placeholder:text-gray-400 !ring-0'
)}
placeholder={placeholder}
placeholder={placeholder ?? t('common.search')}
value={searchValue}
onChange={({ currentTarget: { value } }) => {
setSearchValue(value)
Original file line number Diff line number Diff line change
@@ -531,7 +531,8 @@ const useTimelineReducer = (order: Order) => {
message: (
<>
{t('common.timeline.resources.shipment_number_isbeing', {
number: shipment.number
number: shipment.number,
interpolation: { escapeValue: false }
})}{' '}
<Text weight='bold'>
{t('common.timeline.resources.shipment_packed')}
@@ -550,7 +551,8 @@ const useTimelineReducer = (order: Order) => {
message: (
<>
{t('common.timeline.resources.shipment_number_is', {
number: shipment.number
number: shipment.number,
interpolation: { escapeValue: false }
})}{' '}
<Text weight='bold'>
{t('common.timeline.resources.shipment_ready_to_ship')}
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ import {
type TrackingDetail
} from '#helpers/tracking'
import { useOverlay } from '#hooks/useOverlay'
import { t } from '#providers/I18NProvider'
import { t, useTranslation } from '#providers/I18NProvider'
import { useTokenProvider } from '#providers/TokenProvider'
import { A } from '#ui/atoms/A'
import { Avatar } from '#ui/atoms/Avatar'
@@ -116,6 +116,7 @@ const Parcel = withSkeletonTemplate<{
showEstimatedDelivery?: boolean
onRemove?: () => void
}>(({ parcel, rate, showEstimatedDelivery = false, onRemove }) => {
const { t } = useTranslation()
const itemsLength =
parcel.parcel_line_items?.reduce((sum, item) => sum + item.quantity, 0) ?? 0

@@ -139,7 +140,9 @@ const Parcel = withSkeletonTemplate<{
<FlexRow>
<Text variant='info'>{t('common.parcel_total')}</Text>
<Text weight='semibold'>
{itemsLength} {itemsLength > 1 ? 'items' : 'item'}
{t('apps.shipments.details.parcel_item', {
count: itemsLength
})}
</Text>
</FlexRow>
<Spacer top='4'>
Original file line number Diff line number Diff line change
@@ -22,15 +22,11 @@ describe('FiltersNav', () => {
expect(container).toBeVisible()

// grouped by status_in
expect(
getByText('common.filters_instructions.order_status · 2')
).toBeVisible()
expect(getByText('Status · 2')).toBeVisible()
// payment_status_eq is only one, so it should not be grouped
expect(
getByText('resources.orders.attributes.payment_status.authorized')
).toBeVisible()
expect(getByText('Authorized')).toBeVisible()
// grouped by market_in, we have 3 markets
expect(getByText('resources.markets.name_other · 3')).toBeVisible()
expect(getByText('Markets · 3')).toBeVisible()
})

test('should render single resource name (relationship) when there is only 1 filter for relationship selected (InputResourceGroup component)', async () => {
@@ -68,9 +64,7 @@ describe('FiltersNav', () => {
/>
)

fireEvent.click(
getByText('resources.orders.attributes.payment_status.authorized')
)
fireEvent.click(getByText('Authorized'))
expect(onFilterClick).toHaveBeenCalledWith(
'payment_status_eq=authorized&status_in=placed&status_in=approved',
'payment_status_eq'
Loading