From b40843a2987222bafc8c90d47d7bb613521feb8f Mon Sep 17 00:00:00 2001 From: Lukas Chladek Date: Fri, 6 Nov 2020 14:35:13 +0100 Subject: [PATCH 01/21] fix(admin-ui): Add missing "state.error" token --- packages/admin-ui/i18n-coverage.json | 46 +++++++++---------- .../src/shared/pipes/state-i18n-token.pipe.ts | 1 + .../src/lib/static/i18n-messages/cs.json | 1 + .../src/lib/static/i18n-messages/de.json | 3 +- .../src/lib/static/i18n-messages/en.json | 1 + .../src/lib/static/i18n-messages/es.json | 1 + .../src/lib/static/i18n-messages/pl.json | 3 +- .../src/lib/static/i18n-messages/pt_BR.json | 3 +- .../src/lib/static/i18n-messages/zh_Hans.json | 3 +- .../src/lib/static/i18n-messages/zh_Hant.json | 3 +- 10 files changed, 37 insertions(+), 28 deletions(-) diff --git a/packages/admin-ui/i18n-coverage.json b/packages/admin-ui/i18n-coverage.json index 944e7b29d2..9382197663 100644 --- a/packages/admin-ui/i18n-coverage.json +++ b/packages/admin-ui/i18n-coverage.json @@ -1,46 +1,46 @@ { - "generatedOn": "2020-11-02T18:52:26.628Z", - "lastCommit": "345bcbf915abe30eb390ceaa02ce5fdedd1a0ff6", + "generatedOn": "2020-11-06T11:26:32.981Z", + "lastCommit": "1662885683cf5844daee8737d68023eb67e60714", "translationStatus": { "cs": { - "tokenCount": 676, - "translatedCount": 674, + "tokenCount": 677, + "translatedCount": 676, "percentage": 100 }, "de": { - "tokenCount": 676, - "translatedCount": 601, - "percentage": 89 + "tokenCount": 677, + "translatedCount": 609, + "percentage": 90 }, "en": { - "tokenCount": 676, - "translatedCount": 672, - "percentage": 99 + "tokenCount": 677, + "translatedCount": 675, + "percentage": 100 }, "es": { - "tokenCount": 676, + "tokenCount": 677, "translatedCount": 466, "percentage": 69 }, "pl": { - "tokenCount": 676, - "translatedCount": 556, - "percentage": 82 + "tokenCount": 677, + "translatedCount": 564, + "percentage": 83 }, "pt_BR": { - "tokenCount": 676, - "translatedCount": 647, - "percentage": 96 + "tokenCount": 677, + "translatedCount": 655, + "percentage": 97 }, "zh_Hans": { - "tokenCount": 676, - "translatedCount": 540, - "percentage": 80 + "tokenCount": 677, + "translatedCount": 548, + "percentage": 81 }, "zh_Hant": { - "tokenCount": 676, - "translatedCount": 540, - "percentage": 80 + "tokenCount": 677, + "translatedCount": 548, + "percentage": 81 } } } \ No newline at end of file diff --git a/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts b/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts index dfe23689e2..69dcc0ebd5 100644 --- a/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts +++ b/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts @@ -18,6 +18,7 @@ export class StateI18nTokenPipe implements PipeTransform { Pending: _('state.pending'), Settled: _('state.settled'), Failed: _('state.failed'), + Error: _('state.error'), }; transform(value: T): T { if (typeof value === 'string') { diff --git a/packages/admin-ui/src/lib/static/i18n-messages/cs.json b/packages/admin-ui/src/lib/static/i18n-messages/cs.json index 7179cca727..adaabe7e7b 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/cs.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/cs.json @@ -680,6 +680,7 @@ "arranging-payment": "Zřizování platby", "cancelled": "Zrušeno", "delivered": "Doručeno", + "error": "Chyba", "failed": "Selhalo", "partially-delivered": "Částečně doručeno", "partially-shipped": "Částečně expedováno", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/de.json b/packages/admin-ui/src/lib/static/i18n-messages/de.json index 6d45760adb..9cf87002cf 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/de.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/de.json @@ -680,6 +680,7 @@ "arranging-payment": "Zahlung einrichten", "cancelled": "Storniert", "delivered": "Ausgeführt", + "error": "", "failed": "", "partially-delivered": "Teilweise ausgeführt", "partially-shipped": "", @@ -707,4 +708,4 @@ "job-result": "Job-Ergebnis", "job-state": "Job-Status" } -} +} \ No newline at end of file diff --git a/packages/admin-ui/src/lib/static/i18n-messages/en.json b/packages/admin-ui/src/lib/static/i18n-messages/en.json index 916de60bdd..8860e8b9c9 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/en.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/en.json @@ -680,6 +680,7 @@ "arranging-payment": "Arranging payment", "cancelled": "Cancelled", "delivered": "Delivered", + "error": "Error", "failed": "Failed", "partially-delivered": "Partially delivered", "partially-shipped": "Partially shipped", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/es.json b/packages/admin-ui/src/lib/static/i18n-messages/es.json index 68074e8c3a..3292fd7e5e 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/es.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/es.json @@ -680,6 +680,7 @@ "arranging-payment": "", "cancelled": "", "delivered": "", + "error": "", "failed": "", "partially-delivered": "", "partially-shipped": "", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/pl.json b/packages/admin-ui/src/lib/static/i18n-messages/pl.json index bbf8aeb2c6..aff4bf01b7 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/pl.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/pl.json @@ -680,6 +680,7 @@ "arranging-payment": "Oczekiwanie na płatność", "cancelled": "Anulowano", "delivered": "Zrealizowano", + "error": "", "failed": "", "partially-delivered": "Częściowo zrealizowano", "partially-shipped": "", @@ -707,4 +708,4 @@ "job-result": "Rezultat zlecenia", "job-state": "Status zlecenia" } -} +} \ No newline at end of file diff --git a/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json b/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json index 12de4809e3..33bf95cdd5 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json @@ -680,6 +680,7 @@ "arranging-payment": "Organização de pagamento", "cancelled": "Cancelado", "delivered": "Realizado", + "error": "", "failed": "", "partially-delivered": "Parcialmente realizado", "partially-shipped": "", @@ -707,4 +708,4 @@ "job-result": "Resultado do trabalho", "job-state": "Estado do trabalho" } -} +} \ No newline at end of file diff --git a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json index 7f3ad9dce1..bee7be4db5 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json @@ -680,6 +680,7 @@ "arranging-payment": "正在付款", "cancelled": "已取消", "delivered": "已完成", + "error": "", "failed": "", "partially-delivered": "部分配货", "partially-shipped": "", @@ -707,4 +708,4 @@ "job-result": "", "job-state": "" } -} +} \ No newline at end of file diff --git a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json index 8176a823c9..485a8061e1 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json @@ -680,6 +680,7 @@ "arranging-payment": "正在付款", "cancelled": "已取消", "delivered": "已完成", + "error": "", "failed": "", "partially-delivered": "部分配貨", "partially-shipped": "", @@ -707,4 +708,4 @@ "job-result": "", "job-state": "" } -} +} \ No newline at end of file From 788ba873123a2fe43a4dfd0a9c260c3c5173058d Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Fri, 6 Nov 2020 14:59:25 +0100 Subject: [PATCH 02/21] fix(admin-ui): Add missing "authorized" state translation --- packages/admin-ui/i18n-coverage.json | 24 +++++++++---------- .../src/shared/pipes/state-i18n-token.pipe.ts | 1 + .../src/lib/static/i18n-messages/cs.json | 1 + .../src/lib/static/i18n-messages/de.json | 3 ++- .../src/lib/static/i18n-messages/en.json | 1 + .../src/lib/static/i18n-messages/es.json | 1 + .../src/lib/static/i18n-messages/pl.json | 1 + .../src/lib/static/i18n-messages/pt_BR.json | 3 ++- .../src/lib/static/i18n-messages/zh_Hans.json | 1 + .../src/lib/static/i18n-messages/zh_Hant.json | 1 + 10 files changed, 23 insertions(+), 14 deletions(-) diff --git a/packages/admin-ui/i18n-coverage.json b/packages/admin-ui/i18n-coverage.json index 9382197663..d9633faf03 100644 --- a/packages/admin-ui/i18n-coverage.json +++ b/packages/admin-ui/i18n-coverage.json @@ -1,44 +1,44 @@ { - "generatedOn": "2020-11-06T11:26:32.981Z", - "lastCommit": "1662885683cf5844daee8737d68023eb67e60714", + "generatedOn": "2020-11-06T13:55:36.076Z", + "lastCommit": "b40843a2987222bafc8c90d47d7bb613521feb8f", "translationStatus": { "cs": { - "tokenCount": 677, - "translatedCount": 676, + "tokenCount": 678, + "translatedCount": 677, "percentage": 100 }, "de": { - "tokenCount": 677, + "tokenCount": 678, "translatedCount": 609, "percentage": 90 }, "en": { - "tokenCount": 677, - "translatedCount": 675, + "tokenCount": 678, + "translatedCount": 676, "percentage": 100 }, "es": { - "tokenCount": 677, + "tokenCount": 678, "translatedCount": 466, "percentage": 69 }, "pl": { - "tokenCount": 677, + "tokenCount": 678, "translatedCount": 564, "percentage": 83 }, "pt_BR": { - "tokenCount": 677, + "tokenCount": 678, "translatedCount": 655, "percentage": 97 }, "zh_Hans": { - "tokenCount": 677, + "tokenCount": 678, "translatedCount": 548, "percentage": 81 }, "zh_Hant": { - "tokenCount": 677, + "tokenCount": 678, "translatedCount": 548, "percentage": 81 } diff --git a/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts b/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts index 69dcc0ebd5..20a16a333a 100644 --- a/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts +++ b/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts @@ -13,6 +13,7 @@ export class StateI18nTokenPipe implements PipeTransform { PartiallyShipped: _('state.partially-shipped'), Shipped: _('state.shipped'), PartiallyDelivered: _('state.partially-delivered'), + Authorized: _('state.authorized'), Delivered: _('state.delivered'), Cancelled: _('state.cancelled'), Pending: _('state.pending'), diff --git a/packages/admin-ui/src/lib/static/i18n-messages/cs.json b/packages/admin-ui/src/lib/static/i18n-messages/cs.json index adaabe7e7b..eb220ff8d7 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/cs.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/cs.json @@ -678,6 +678,7 @@ "adding-items": "Košík", "all-orders": "Všechny objednávky", "arranging-payment": "Zřizování platby", + "authorized": "Autorizovaná", "cancelled": "Zrušeno", "delivered": "Doručeno", "error": "Chyba", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/de.json b/packages/admin-ui/src/lib/static/i18n-messages/de.json index 9cf87002cf..2796eac6d1 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/de.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/de.json @@ -678,6 +678,7 @@ "adding-items": "Artikel hinzufügen", "all-orders": "Alle Bestellungen", "arranging-payment": "Zahlung einrichten", + "authorized": "Autorisiert", "cancelled": "Storniert", "delivered": "Ausgeführt", "error": "", @@ -708,4 +709,4 @@ "job-result": "Job-Ergebnis", "job-state": "Job-Status" } -} \ No newline at end of file +} diff --git a/packages/admin-ui/src/lib/static/i18n-messages/en.json b/packages/admin-ui/src/lib/static/i18n-messages/en.json index 8860e8b9c9..400e74ae52 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/en.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/en.json @@ -678,6 +678,7 @@ "adding-items": "Adding items", "all-orders": "All orders", "arranging-payment": "Arranging payment", + "authorized": "Authorized", "cancelled": "Cancelled", "delivered": "Delivered", "error": "Error", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/es.json b/packages/admin-ui/src/lib/static/i18n-messages/es.json index 3292fd7e5e..71f24d8e8b 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/es.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/es.json @@ -678,6 +678,7 @@ "adding-items": "", "all-orders": "", "arranging-payment": "", + "authorized": "", "cancelled": "", "delivered": "", "error": "", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/pl.json b/packages/admin-ui/src/lib/static/i18n-messages/pl.json index aff4bf01b7..9fa74a7288 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/pl.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/pl.json @@ -678,6 +678,7 @@ "adding-items": "Dodawanie", "all-orders": "Wszystkie zamówienia", "arranging-payment": "Oczekiwanie na płatność", + "authorized": "", "cancelled": "Anulowano", "delivered": "Zrealizowano", "error": "", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json b/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json index 33bf95cdd5..fb1691bd3a 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json @@ -678,6 +678,7 @@ "adding-items": "Criando itens", "all-orders": "Todos os pedidos", "arranging-payment": "Organização de pagamento", + "authorized": "Autorizado", "cancelled": "Cancelado", "delivered": "Realizado", "error": "", @@ -708,4 +709,4 @@ "job-result": "Resultado do trabalho", "job-state": "Estado do trabalho" } -} \ No newline at end of file +} diff --git a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json index bee7be4db5..d53e33e246 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json @@ -678,6 +678,7 @@ "adding-items": "正在选择商品", "all-orders": "所有订单", "arranging-payment": "正在付款", + "authorized": "", "cancelled": "已取消", "delivered": "已完成", "error": "", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json index 485a8061e1..2e69ed42f3 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json @@ -678,6 +678,7 @@ "adding-items": "正在選擇商品", "all-orders": "所有訂單", "arranging-payment": "正在付款", + "authorized": "", "cancelled": "已取消", "delivered": "已完成", "error": "", From df32ba12b4dd9b53d837502da52858029646c437 Mon Sep 17 00:00:00 2001 From: Lukas Chladek Date: Fri, 6 Nov 2020 16:01:51 +0100 Subject: [PATCH 03/21] fix(admin-ui): Fix payment states --- packages/admin-ui/i18n-coverage.json | 30 +++++++++---------- .../src/shared/pipes/state-i18n-token.pipe.ts | 2 ++ .../src/lib/static/i18n-messages/cs.json | 4 ++- .../src/lib/static/i18n-messages/de.json | 4 ++- .../src/lib/static/i18n-messages/en.json | 4 ++- .../src/lib/static/i18n-messages/es.json | 2 ++ .../src/lib/static/i18n-messages/pl.json | 2 ++ .../src/lib/static/i18n-messages/pt_BR.json | 4 ++- .../src/lib/static/i18n-messages/zh_Hans.json | 2 ++ .../src/lib/static/i18n-messages/zh_Hant.json | 2 ++ 10 files changed, 37 insertions(+), 19 deletions(-) diff --git a/packages/admin-ui/i18n-coverage.json b/packages/admin-ui/i18n-coverage.json index d9633faf03..79679dc72c 100644 --- a/packages/admin-ui/i18n-coverage.json +++ b/packages/admin-ui/i18n-coverage.json @@ -1,44 +1,44 @@ { - "generatedOn": "2020-11-06T13:55:36.076Z", - "lastCommit": "b40843a2987222bafc8c90d47d7bb613521feb8f", + "generatedOn": "2020-11-06T14:43:15.173Z", + "lastCommit": "d41471b9a7958847813e314d016ff0d5807d1189", "translationStatus": { "cs": { - "tokenCount": 678, - "translatedCount": 677, + "tokenCount": 680, + "translatedCount": 680, "percentage": 100 }, "de": { - "tokenCount": 678, - "translatedCount": 609, + "tokenCount": 680, + "translatedCount": 610, "percentage": 90 }, "en": { - "tokenCount": 678, - "translatedCount": 676, + "tokenCount": 680, + "translatedCount": 679, "percentage": 100 }, "es": { - "tokenCount": 678, + "tokenCount": 680, "translatedCount": 466, "percentage": 69 }, "pl": { - "tokenCount": 678, + "tokenCount": 680, "translatedCount": 564, "percentage": 83 }, "pt_BR": { - "tokenCount": 678, - "translatedCount": 655, - "percentage": 97 + "tokenCount": 680, + "translatedCount": 656, + "percentage": 96 }, "zh_Hans": { - "tokenCount": 678, + "tokenCount": 680, "translatedCount": 548, "percentage": 81 }, "zh_Hant": { - "tokenCount": 678, + "tokenCount": 680, "translatedCount": 548, "percentage": 81 } diff --git a/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts b/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts index 20a16a333a..cae4526a0e 100644 --- a/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts +++ b/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts @@ -20,6 +20,8 @@ export class StateI18nTokenPipe implements PipeTransform { Settled: _('state.settled'), Failed: _('state.failed'), Error: _('state.error'), + Created: _('state.created'), + Declined: _('state.declined') }; transform(value: T): T { if (typeof value === 'string') { diff --git a/packages/admin-ui/src/lib/static/i18n-messages/cs.json b/packages/admin-ui/src/lib/static/i18n-messages/cs.json index eb220ff8d7..f47f874c80 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/cs.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/cs.json @@ -678,8 +678,10 @@ "adding-items": "Košík", "all-orders": "Všechny objednávky", "arranging-payment": "Zřizování platby", - "authorized": "Autorizovaná", + "authorized": "Autorizováno", "cancelled": "Zrušeno", + "created": "Vytvořeno", + "declined": "Odmítnuto", "delivered": "Doručeno", "error": "Chyba", "failed": "Selhalo", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/de.json b/packages/admin-ui/src/lib/static/i18n-messages/de.json index 2796eac6d1..83f848e2c2 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/de.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/de.json @@ -680,6 +680,8 @@ "arranging-payment": "Zahlung einrichten", "authorized": "Autorisiert", "cancelled": "Storniert", + "created": "", + "declined": "", "delivered": "Ausgeführt", "error": "", "failed": "", @@ -709,4 +711,4 @@ "job-result": "Job-Ergebnis", "job-state": "Job-Status" } -} +} \ No newline at end of file diff --git a/packages/admin-ui/src/lib/static/i18n-messages/en.json b/packages/admin-ui/src/lib/static/i18n-messages/en.json index 400e74ae52..ae7b025171 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/en.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/en.json @@ -680,6 +680,8 @@ "arranging-payment": "Arranging payment", "authorized": "Authorized", "cancelled": "Cancelled", + "created": "Created", + "declined": "Declined", "delivered": "Delivered", "error": "Error", "failed": "Failed", @@ -709,4 +711,4 @@ "job-result": "Job result", "job-state": "Job state" } -} +} \ No newline at end of file diff --git a/packages/admin-ui/src/lib/static/i18n-messages/es.json b/packages/admin-ui/src/lib/static/i18n-messages/es.json index 71f24d8e8b..1c1d6108af 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/es.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/es.json @@ -680,6 +680,8 @@ "arranging-payment": "", "authorized": "", "cancelled": "", + "created": "", + "declined": "", "delivered": "", "error": "", "failed": "", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/pl.json b/packages/admin-ui/src/lib/static/i18n-messages/pl.json index 9fa74a7288..9115b63997 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/pl.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/pl.json @@ -680,6 +680,8 @@ "arranging-payment": "Oczekiwanie na płatność", "authorized": "", "cancelled": "Anulowano", + "created": "", + "declined": "", "delivered": "Zrealizowano", "error": "", "failed": "", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json b/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json index fb1691bd3a..74470f5f1c 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json @@ -680,6 +680,8 @@ "arranging-payment": "Organização de pagamento", "authorized": "Autorizado", "cancelled": "Cancelado", + "created": "", + "declined": "", "delivered": "Realizado", "error": "", "failed": "", @@ -709,4 +711,4 @@ "job-result": "Resultado do trabalho", "job-state": "Estado do trabalho" } -} +} \ No newline at end of file diff --git a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json index d53e33e246..204f0be0b8 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json @@ -680,6 +680,8 @@ "arranging-payment": "正在付款", "authorized": "", "cancelled": "已取消", + "created": "", + "declined": "", "delivered": "已完成", "error": "", "failed": "", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json index 2e69ed42f3..e278b0f4cc 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json @@ -680,6 +680,8 @@ "arranging-payment": "正在付款", "authorized": "", "cancelled": "已取消", + "created": "", + "declined": "", "delivered": "已完成", "error": "", "failed": "", From 8688c35b84aeb0f2355f00fc4adadf94b50eb8b7 Mon Sep 17 00:00:00 2001 From: Lukas Chladek Date: Tue, 10 Nov 2020 17:13:24 +0700 Subject: [PATCH 04/21] feat(core): Export HistoryService --- packages/core/src/service/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/src/service/index.ts b/packages/core/src/service/index.ts index 6defc12f03..22f5539bfb 100644 --- a/packages/core/src/service/index.ts +++ b/packages/core/src/service/index.ts @@ -35,4 +35,5 @@ export * from './services/tax-category.service'; export * from './services/tax-rate.service'; export * from './services/user.service'; export * from './services/zone.service'; +export * from './services/history.service'; export * from './transaction/transactional-connection'; From 3ff011f532b786955cec7d4c4039557d3bce8e95 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Wed, 11 Nov 2020 09:43:41 +0100 Subject: [PATCH 05/21] chore: Add mysql 5.7 to dev docker-compose --- packages/dev-server/docker-compose.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/dev-server/docker-compose.yml b/packages/dev-server/docker-compose.yml index 0ba60d43bf..b4780ce22a 100644 --- a/packages/dev-server/docker-compose.yml +++ b/packages/dev-server/docker-compose.yml @@ -2,6 +2,7 @@ version: '3.7' services: mariadb: image: 'bitnami/mariadb:latest' + container_name: mariadb environment: - ALLOW_EMPTY_PASSWORD=yes volumes: @@ -20,6 +21,7 @@ services: - /sessions mysql: image: bitnami/mysql:8.0 + container_name: mysql-8 environment: ALLOW_EMPTY_PASSWORD: 'yes' MYSQL_AUTHENTICATION_PLUGIN: mysql_native_password @@ -27,6 +29,25 @@ services: - 'mysql_data:/bitnami' ports: - '3306:3306' + mysql5: + image: bitnami/mysql:5.7 + container_name: mysql-5.7 + environment: + ALLOW_EMPTY_PASSWORD: 'yes' + volumes: + - 'mysql_data:/bitnami' + ports: + - '3306:3306' + phpmyadmin-mysql5: + image: 'phpmyadmin/phpmyadmin:latest' + container_name: phpmyadmin-mysql5 + environment: + - PMA_HOST=mysql-5.7 + - PMA_USER=root + ports: + - 8082:80 + volumes: + - /sessions phpmyadmin-mysql: image: 'phpmyadmin/phpmyadmin:latest' container_name: phpmyadmin-mysql @@ -39,6 +60,7 @@ services: - /sessions postgres: image: postgres:12.3 + container_name: postgres environment: POSTGRES_DB: postgres POSTGRES_USER: admin @@ -49,6 +71,7 @@ services: ports: - "5432:5432" pgadmin: + container_name: pgadmin image: dpage/pgadmin4:4.18 environment: PGADMIN_DEFAULT_EMAIL: admin@localhost.dev From 185c7809ae7fadc844a76f5b4765ea1a8e1d00a6 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Wed, 11 Nov 2020 09:58:10 +0100 Subject: [PATCH 06/21] chore(docs): Update FAQ & roadmap --- docs/content/article/faq.md | 6 +----- docs/content/article/roadmap.md | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/content/article/faq.md b/docs/content/article/faq.md index ff98868586..6162017f9a 100644 --- a/docs/content/article/faq.md +++ b/docs/content/article/faq.md @@ -24,11 +24,7 @@ For example, there are already Vendure storefront projects built with Vue, React ## Who is using Vendure? -There are a number of Vendure projects under development at the moment. Based on community interactions, we know that Vendure is being used in both public B2C settings and enterprise B2B. Here are some live Vendure sites that we know of. Please get in touch if you'd like yours to be added! - -* [CB Made In Italy](https://cbmadeinitaly.com/): Vendure + [Vue Storefront](https://www.vuestorefront.io/) -* [Racketworld.ch](https://racketworld.ch/): Vendure + [Svelte](https://svelte.dev/) + [Sapper](https://sapper.svelte.dev/) -* [GoMo](https://gomo.in.th/): Vendure + [React](https://reactjs.org/) +There are a number of Vendure projects under development at the moment. Based on community interactions, we know that Vendure is being used in both public B2C settings and enterprise B2B. We're collecting a list of production Vendure-powered sites in the [Built With Vendure](https://github.com/vendure-ecommerce/vendure/discussions/485) thread in our discussion forum. ## Is enterprise support available? diff --git a/docs/content/article/roadmap.md b/docs/content/article/roadmap.md index ddf3abf7c8..81a79899a8 100644 --- a/docs/content/article/roadmap.md +++ b/docs/content/article/roadmap.md @@ -9,7 +9,7 @@ showtoc: false Here is a list of some of the main outstanding tasks that are planned for the v1.0 release, at which point Vendure will come out of beta: * Complete the Channels implementation -* Back order handling +* ~~Back order handling~~ ✅ * Administrator creation & editing of orders * ~~Custom authentication support~~ ✅ * Improved promotions support @@ -25,4 +25,4 @@ Once we hit v1.0, Vendure will continue to follow [Semantic Versioning](https:// ## Long-term -Vendure is in this for the long-term. This is not a venture-backed start-up looking for an exit. We plan to grow Vendure into the go-to solution for Node.js e-commerce with a solid, stable core and vibrant community. Post v1.0 we will be introducing a set of commercial plugins covering some more advanced use-cases. +Vendure is in this for the long-term. The project is backed by a successful UK-based retailer who have been in e-commerce for over 15 years. We plan to grow Vendure into the go-to solution for Node.js e-commerce with a solid, stable core and vibrant community. Post v1.0 we will be introducing a set of commercial plugins covering some more advanced use-cases. From a6f754e270dff5363a2fc7a982bee8ea02b8f84d Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Wed, 11 Nov 2020 10:18:23 +0100 Subject: [PATCH 07/21] chore(core): Fix docs tag --- .../core/src/config/order/default-stock-allocation-strategy.ts | 2 +- packages/core/src/config/order/stock-allocation-strategy.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/src/config/order/default-stock-allocation-strategy.ts b/packages/core/src/config/order/default-stock-allocation-strategy.ts index 8f69fb3921..9cccc536d6 100644 --- a/packages/core/src/config/order/default-stock-allocation-strategy.ts +++ b/packages/core/src/config/order/default-stock-allocation-strategy.ts @@ -9,7 +9,7 @@ import { StockAllocationStrategy } from './stock-allocation-strategy'; * Allocates stock when the Order transitions from `ArrangingPayment` to either * `PaymentAuthorized` or `PaymentSettled`. * - * @docsCategory order + * @docsCategory orders */ export class DefaultStockAllocationStrategy implements StockAllocationStrategy { shouldAllocateStock( diff --git a/packages/core/src/config/order/stock-allocation-strategy.ts b/packages/core/src/config/order/stock-allocation-strategy.ts index e01f49e2d5..3b2435d50b 100644 --- a/packages/core/src/config/order/stock-allocation-strategy.ts +++ b/packages/core/src/config/order/stock-allocation-strategy.ts @@ -8,7 +8,7 @@ import { OrderState } from '../../service/helpers/order-state-machine/order-stat * This strategy is responsible for deciding at which stage in the order process * stock will be allocated. * - * @docsCategory order + * @docsCategory orders */ export interface StockAllocationStrategy extends InjectableStrategy { /** From 405b754d513dd8a2174fdc7933abe3a53460c7ae Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Wed, 11 Nov 2020 10:19:13 +0100 Subject: [PATCH 08/21] feat(docs): Add note on DI for ConfigurableOperationDefs --- .../docs/developer-guide/payment-integrations/index.md | 6 ++++++ docs/content/docs/developer-guide/promotions.md | 6 ++++++ docs/content/docs/developer-guide/shipping.md | 6 ++++++ packages/core/src/common/configurable-operation.ts | 2 +- packages/core/src/common/injector.ts | 2 +- 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/docs/content/docs/developer-guide/payment-integrations/index.md b/docs/content/docs/developer-guide/payment-integrations/index.md index 14a49e65a3..f5e6d912d4 100644 --- a/docs/content/docs/developer-guide/payment-integrations/index.md +++ b/docs/content/docs/developer-guide/payment-integrations/index.md @@ -107,6 +107,12 @@ export const config: VendureConfig = { }; ``` +{{% alert %}} +**Dependency Injection** + +If your PaymentMethodHandler needs access to the database or other providers, see the [ConfigurableOperationDef Dependency Injection guide]({{< relref "configurable-operation-def" >}}#dependency-injection). +{{< /alert >}} + ## Payment flow 1. Once the active Order has been transitioned to the ArrangingPayment state (see the [Order Workflow guide]({{< relref "order-workflow" >}})), one or more Payments are created by executing the [`addPaymentToOrder` mutation]({{< relref "/docs/graphql-api/shop/mutations#addpaymenttoorder" >}}). This mutation has a required `method` input field, which _must_ match the `code` of one of the configured PaymentMethodHandlers. In the case above, this would be set to `"my-payment-method"`. diff --git a/docs/content/docs/developer-guide/promotions.md b/docs/content/docs/developer-guide/promotions.md index 3e2e5f61c8..87364ccf3d 100644 --- a/docs/content/docs/developer-guide/promotions.md +++ b/docs/content/docs/developer-guide/promotions.md @@ -155,3 +155,9 @@ export const config: VendureConfig = { } } ``` + +{{% alert %}} +**Dependency Injection** + +If your PromotionCondition or PromotionAction needs access to the database or other providers, see the [ConfigurableOperationDef Dependency Injection guide]({{< relref "configurable-operation-def" >}}#dependency-injection). +{{< /alert >}} diff --git a/docs/content/docs/developer-guide/shipping.md b/docs/content/docs/developer-guide/shipping.md index 98b34b5bb0..d281919db9 100644 --- a/docs/content/docs/developer-guide/shipping.md +++ b/docs/content/docs/developer-guide/shipping.md @@ -125,6 +125,12 @@ export const config: VendureConfig = { } ``` +{{% alert %}} +**Dependency Injection** + +If your ShippingEligibilityChecker or ShippingCalculator needs access to the database or other providers, see the [ConfigurableOperationDef Dependency Injection guide]({{< relref "configurable-operation-def" >}}#dependency-injection). +{{< /alert >}} + ## Fulfillments Fulfillments represent the actual shipping status of items in an order. Like Orders, Fulfillments are governed by a [finite state machine]({{< relref "fsm" >}}) and by default, a Fulfillment can be in one of the [following states]({{< relref "fulfillment-state" >}}): diff --git a/packages/core/src/common/configurable-operation.ts b/packages/core/src/common/configurable-operation.ts index fc4e5a9436..6ad44bdb99 100644 --- a/packages/core/src/common/configurable-operation.ts +++ b/packages/core/src/common/configurable-operation.ts @@ -243,7 +243,7 @@ export interface ConfigurableOperationDefOptions extends I * the docs of {@link ConfigArgs}. * * ## Dependency Injection - * If your business logic relies on injectable providers, such as the TypeORM `Connection` object, or any of the + * If your business logic relies on injectable providers, such as the `TransactionalConnection` object, or any of the * internal Vendure services or those defined in a plugin, you can inject them by using the config object's * `init()` method, which exposes the {@link Injector}. * diff --git a/packages/core/src/common/injector.ts b/packages/core/src/common/injector.ts index 8db2238100..f063992ee6 100644 --- a/packages/core/src/common/injector.ts +++ b/packages/core/src/common/injector.ts @@ -26,7 +26,7 @@ export class Injector { /** * @description - * Retrieve the TypeORM `Connection` instance. + * (deprecated) Retrieve the TypeORM `Connection` instance. * * @deprecated Use `.get(TransactionalConnection)` instead. */ From a117a95a9f4d3f035c9fb81f672c13356b614620 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Wed, 11 Nov 2020 10:35:12 +0100 Subject: [PATCH 09/21] chore(docs): Update some examples to latest APIs --- docs/content/docs/developer-guide/job-queue/index.md | 2 +- docs/content/docs/developer-guide/promotions.md | 4 ++-- docs/content/docs/developer-guide/shipping.md | 4 ++-- packages/core/src/config/promotion/promotion-action.ts | 5 +++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/content/docs/developer-guide/job-queue/index.md b/docs/content/docs/developer-guide/job-queue/index.md index 27c1647c44..26b3677123 100644 --- a/docs/content/docs/developer-guide/job-queue/index.md +++ b/docs/content/docs/developer-guide/job-queue/index.md @@ -36,7 +36,7 @@ It is also possible to implement your own JobQueueStrategy to enable other persi ## Using Job Queues in a plugin -If you create a [Vendure plugin]({{< relref "/docs/plugins" >}}) which involves some long-running tasks, you can also make use of the job queue. See the [JobQueue plugin example]({{< relref "plugin-examples" >}}#using-the-jobqueueservice) for a detailed annotated example. +If you create a [Vendure plugin]({{< relref "/docs/plugins" >}}) which involves some long-running tasks, you can also make use of the job queue. See the [JobQueue plugin example]({{< relref "using-job-queue-service" >}}) for a detailed annotated example. {{< alert "primary" >}} Note: The [JobQueueService]({{< relref "job-queue-service" >}}) combines well with the [WorkerService]({{< relref "worker-service" >}}). diff --git a/docs/content/docs/developer-guide/promotions.md b/docs/content/docs/developer-guide/promotions.md index 87364ccf3d..6e5dd708a3 100644 --- a/docs/content/docs/developer-guide/promotions.md +++ b/docs/content/docs/developer-guide/promotions.md @@ -71,7 +71,7 @@ export const minimumOrderAmount = new PromotionCondition({ * must resolve to a boolean value indicating whether the condition has * been satisfied. */ - check(order, args) { + check(ctx, order, args) { if (args.taxInclusive) { return order.subTotal >= args.amount; } else { @@ -132,7 +132,7 @@ export const orderPercentageDiscount = new PromotionOrderAction({ * It should return a negative number representing the discount in * pennies/cents etc. Rounding to an integer is handled automatically. */ - execute(order, args) { + execute(ctx, order, args) { return -order.subTotal * (args.discount / 100); }, }); diff --git a/docs/content/docs/developer-guide/shipping.md b/docs/content/docs/developer-guide/shipping.md index d281919db9..f9f07836d3 100644 --- a/docs/content/docs/developer-guide/shipping.md +++ b/docs/content/docs/developer-guide/shipping.md @@ -43,7 +43,7 @@ export const maxWeightChecker = new ShippingEligibilityChecker({ * (This example assumes a custom field "weight" is defined on the * ProductVariant entity) */ - check: (order, args) => { + check: (ctx, order, args) => { const totalWeight = order.lines .map((l) => (l.productVariant.customFields as any).weight * l.quantity) .reduce((total, lineWeight) => total + lineWeight, 0); @@ -89,7 +89,7 @@ export const externalShippingCalculator = new ShippingCalculator({ label: [{ languageCode: LanguageCode.en, value: 'Tax rate' }], }, }, - calculate: async (order, args) => { + calculate: async (ctx, order, args) => { // `shippingDataSource` is assumed to fetch the data from some // external data source. const { rate, deliveryDate, courier } = await shippingDataSource.getRate({ diff --git a/packages/core/src/config/promotion/promotion-action.ts b/packages/core/src/config/promotion/promotion-action.ts index 046bcb0120..53c52e35bc 100644 --- a/packages/core/src/config/promotion/promotion-action.ts +++ b/packages/core/src/config/promotion/promotion-action.ts @@ -46,6 +46,7 @@ export interface PromotionActionConfig extends Configurabl /** * @description + * Configuration for a {@link PromotionItemAction} * * @docsCategory promotions * @docsPage promotion-action @@ -107,7 +108,7 @@ export abstract class PromotionAction extends Configu * const itemPercentageDiscount = new PromotionItemAction({ * code: 'item_percentage_discount', * args: { discount: 'percentage' }, - * execute(orderItem, orderLine, args) { + * execute(ctx, orderItem, orderLine, args) { * return -orderLine.unitPrice * (args.discount / 100); * }, * description: 'Discount every item by { discount }%', @@ -141,7 +142,7 @@ export class PromotionItemAction extends Prom * const orderPercentageDiscount = new PromotionOrderAction({ * code: 'order_percentage_discount', * args: { discount: 'percentage' }, - * execute(order, args) { + * execute(ctx, order, args) { * return -order.subTotal * (args.discount / 100); * }, * description: 'Discount order by { discount }%', From d1dee7d4735571f2b688c85de9fc59d38cc29911 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Wed, 11 Nov 2020 11:43:13 +0100 Subject: [PATCH 10/21] chore: Clean up after merge --- packages/admin-ui/i18n-coverage.json | 30 +++++++++---------- .../src/shared/pipes/state-i18n-token.pipe.ts | 1 - .../src/lib/static/i18n-messages/cs.json | 2 +- .../src/lib/static/i18n-messages/de.json | 3 ++ .../src/lib/static/i18n-messages/en.json | 2 +- .../src/lib/static/i18n-messages/es.json | 3 ++ .../src/lib/static/i18n-messages/pl.json | 3 ++ .../src/lib/static/i18n-messages/pt_BR.json | 3 ++ .../src/lib/static/i18n-messages/zh_Hans.json | 3 ++ .../src/lib/static/i18n-messages/zh_Hant.json | 3 ++ 10 files changed, 35 insertions(+), 18 deletions(-) diff --git a/packages/admin-ui/i18n-coverage.json b/packages/admin-ui/i18n-coverage.json index 1d185a9ff1..dc565d3b93 100644 --- a/packages/admin-ui/i18n-coverage.json +++ b/packages/admin-ui/i18n-coverage.json @@ -1,44 +1,44 @@ { - "generatedOn": "2020-11-09T10:05:17.690Z", - "lastCommit": "e57386b02d02e678651ac4d0c91caecee4bc3f45", + "generatedOn": "2020-11-11T10:27:35.876Z", + "lastCommit": "f0cd67c00bd38cf16bab72b68c5d4d3887aff61b", "translationStatus": { "cs": { - "tokenCount": 684, - "translatedCount": 664, + "tokenCount": 687, + "translatedCount": 669, "percentage": 97 }, "de": { - "tokenCount": 684, + "tokenCount": 687, "translatedCount": 597, "percentage": 87 }, "en": { - "tokenCount": 684, - "translatedCount": 680, - "percentage": 99 + "tokenCount": 687, + "translatedCount": 687, + "percentage": 100 }, "es": { - "tokenCount": 684, + "tokenCount": 687, "translatedCount": 455, - "percentage": 67 + "percentage": 66 }, "pl": { - "tokenCount": 684, + "tokenCount": 687, "translatedCount": 552, - "percentage": 81 + "percentage": 80 }, "pt_BR": { - "tokenCount": 684, + "tokenCount": 687, "translatedCount": 643, "percentage": 94 }, "zh_Hans": { - "tokenCount": 684, + "tokenCount": 687, "translatedCount": 536, "percentage": 78 }, "zh_Hant": { - "tokenCount": 684, + "tokenCount": 687, "translatedCount": 536, "percentage": 78 } diff --git a/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts b/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts index 4e72804015..5c16834727 100644 --- a/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts +++ b/packages/admin-ui/src/lib/core/src/shared/pipes/state-i18n-token.pipe.ts @@ -21,7 +21,6 @@ export class StateI18nTokenPipe implements PipeTransform { Settled: _('state.settled'), Failed: _('state.failed'), Error: _('state.error'), - Created: _('state.created'), Declined: _('state.declined'), }; transform(value: T): T { diff --git a/packages/admin-ui/src/lib/static/i18n-messages/cs.json b/packages/admin-ui/src/lib/static/i18n-messages/cs.json index 2fe4b04a6d..6e79d95f94 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/cs.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/cs.json @@ -718,4 +718,4 @@ "job-result": "Výsledek úlohy", "job-state": "Stav úlohy" } -} +} \ No newline at end of file diff --git a/packages/admin-ui/src/lib/static/i18n-messages/de.json b/packages/admin-ui/src/lib/static/i18n-messages/de.json index 427361b0d2..7172b054a1 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/de.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/de.json @@ -685,9 +685,12 @@ "adding-items": "Artikel hinzufügen", "all-orders": "", "arranging-payment": "Zahlung einrichten", + "authorized": "", "cancelled": "Storniert", "created": "", + "declined": "", "delivered": "Ausgeführt", + "error": "", "failed": "", "partially-delivered": "Teilweise ausgeführt", "partially-shipped": "", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/en.json b/packages/admin-ui/src/lib/static/i18n-messages/en.json index fd3132b240..59656f066a 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/en.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/en.json @@ -718,4 +718,4 @@ "job-result": "Job result", "job-state": "Job state" } -} +} \ No newline at end of file diff --git a/packages/admin-ui/src/lib/static/i18n-messages/es.json b/packages/admin-ui/src/lib/static/i18n-messages/es.json index 05fde136b7..2920a4702e 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/es.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/es.json @@ -685,9 +685,12 @@ "adding-items": "", "all-orders": "", "arranging-payment": "", + "authorized": "", "cancelled": "", "created": "", + "declined": "", "delivered": "", + "error": "", "failed": "", "partially-delivered": "", "partially-shipped": "", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/pl.json b/packages/admin-ui/src/lib/static/i18n-messages/pl.json index 4294402f5d..a13ba2df49 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/pl.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/pl.json @@ -685,9 +685,12 @@ "adding-items": "Dodawanie", "all-orders": "", "arranging-payment": "Oczekiwanie na płatność", + "authorized": "", "cancelled": "Anulowano", "created": "", + "declined": "", "delivered": "Zrealizowano", + "error": "", "failed": "", "partially-delivered": "Częściowo zrealizowano", "partially-shipped": "", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json b/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json index 9eda5ab659..920370f115 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json @@ -685,9 +685,12 @@ "adding-items": "Criando itens", "all-orders": "", "arranging-payment": "Organização de pagamento", + "authorized": "", "cancelled": "Cancelado", "created": "", + "declined": "", "delivered": "Realizado", + "error": "", "failed": "", "partially-delivered": "Parcialmente realizado", "partially-shipped": "", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json index 1eaa985c2b..f287e306b2 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json @@ -685,9 +685,12 @@ "adding-items": "正在选择商品", "all-orders": "", "arranging-payment": "正在付款", + "authorized": "", "cancelled": "已取消", "created": "", + "declined": "", "delivered": "已完成", + "error": "", "failed": "", "partially-delivered": "部分配货", "partially-shipped": "", diff --git a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json index 8cf421fc5f..1d347281a1 100644 --- a/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json +++ b/packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json @@ -685,9 +685,12 @@ "adding-items": "正在選擇商品", "all-orders": "", "arranging-payment": "正在付款", + "authorized": "", "cancelled": "已取消", "created": "", + "declined": "", "delivered": "已完成", + "error": "", "failed": "", "partially-delivered": "部分配貨", "partially-shipped": "", From 7a1773c52205c6dfd98ade07b1c9d9da7fb39670 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Wed, 11 Nov 2020 17:32:34 +0100 Subject: [PATCH 11/21] feat(core): Improve feedback & error handling in migration functions --- packages/core/src/migrate.ts | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/packages/core/src/migrate.ts b/packages/core/src/migrate.ts index f2e2ea070c..f92c12a0b1 100644 --- a/packages/core/src/migrate.ts +++ b/packages/core/src/migrate.ts @@ -39,8 +39,20 @@ export interface MigrationOptions { export async function runMigrations(userConfig: Partial) { const config = await preBootstrapConfig(userConfig); const connection = await createConnection(createConnectionOptions(config)); - await disableForeignKeysForSqLite(connection, () => connection.runMigrations({ transaction: 'each' })); - await connection.close(); + try { + const migrations = await disableForeignKeysForSqLite(connection, () => + connection.runMigrations({ transaction: 'each' }), + ); + for (const migration of migrations) { + console.log(chalk.green(`Successfully ran migration: ${migration.name}`)); + } + } catch (e) { + console.log(chalk.red(`An error occurred when running migrations:`)); + console.log(e.message); + process.exitCode = 1; + } finally { + await connection.close(); + } } /** @@ -53,10 +65,17 @@ export async function runMigrations(userConfig: Partial) { export async function revertLastMigration(userConfig: Partial) { const config = await preBootstrapConfig(userConfig); const connection = await createConnection(createConnectionOptions(config)); - await disableForeignKeysForSqLite(connection, () => - connection.undoLastMigration({ transaction: 'each' }), - ); - await connection.close(); + try { + await disableForeignKeysForSqLite(connection, () => + connection.undoLastMigration({ transaction: 'each' }), + ); + } catch (e) { + console.log(chalk.red(`An error occurred when reverting migration:`)); + console.log(e.message); + process.exitCode = 1; + } finally { + await connection.close(); + } } /** @@ -154,15 +173,16 @@ function createConnectionOptions(userConfig: Partial): Connection * is a work-around for the issue. * See https://github.com/typeorm/typeorm/issues/2576#issuecomment-499506647 */ -async function disableForeignKeysForSqLite(connection: Connection, work: () => Promise) { +async function disableForeignKeysForSqLite(connection: Connection, work: () => Promise): Promise { const isSqLite = connection.options.type === 'sqlite'; if (isSqLite) { await connection.query('PRAGMA foreign_keys=OFF'); } - await work(); + const result = await work(); if (isSqLite) { await connection.query('PRAGMA foreign_keys=ON'); } + return result; } /** From 2bc37f8ee0b4f77b15dc8c2e3ed31e586d41c6c5 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Wed, 11 Nov 2020 17:33:45 +0100 Subject: [PATCH 12/21] feat(docs): Improve docs on migrations --- docs/content/docs/developer-guide/migrations.md | 10 ++++++++-- docs/content/docs/developer-guide/updating-vendure.md | 9 +++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/content/docs/developer-guide/migrations.md b/docs/content/docs/developer-guide/migrations.md index 117ae7e7b1..da79562147 100644 --- a/docs/content/docs/developer-guide/migrations.md +++ b/docs/content/docs/developer-guide/migrations.md @@ -12,7 +12,7 @@ Database migrations are needed whenever the database schema changes. This can be ## Synchronize vs migrate -TypeORM (which Vendure uses to interact with the database layer) has a `synchronize` option which, when set to `true`, will automatically update your database schema to reflect the current Vendure configuration. +TypeORM (which Vendure uses to interact with the database) has a `synchronize` option which, when set to `true`, will automatically update your database schema to reflect the current Vendure configuration. This is convenient while developing, but should not be used in production, since a misconfiguration could potentially delete production data. In this case, migrations should be used. @@ -34,12 +34,18 @@ export const config: VendureConfig = { ### Generate a migration -The [`generateMigration` function]({{< relref "generate-migration" >}}) will compare the provided VendureCofig against the current database schema and generate a new migration file containing SQL statements which, when applied to the current database, will modify the schema to fit with the configuration. It will also contain statements to revert these changes. +The [`generateMigration` function]({{< relref "generate-migration" >}}) will compare the provided VendureConfig against the current database schema and generate a new migration file containing SQL statements which, when applied to the current database, will modify the schema to fit with the configuration. It will also contain statements to revert these changes. ### Run migrations The [`runMigrations` function]({{< relref "run-migrations" >}}) will apply any migrations files found according to the pattern provided to `dbConnectionOptions.migrations` to the database. TypeORM keeps a track of which migrations have already been applied, so running this function multiple times will not apply the same migration more than once. +{{% alert "warning" %}} +⚠ TypeORM will attempt to run each migration inside a transaction. This means that if one of the migration commands fails, then the entire transaction will be rolled back to its original state. + +_However_ this is **not supported by MySQL / MariaDB**. This means that when using MySQL or MariaDB, errors in your migration script could leave your database in a broken or inconsistent state. Therefore it is **critical** that you first create a backup of your database before running a migration. +{{< /alert >}} + ### Revert a migration The [`runMigrations` function]({{< relref "run-migrations" >}}) will revert the last applied migration. If run again it will then revert the one before that, and so on. diff --git a/docs/content/docs/developer-guide/updating-vendure.md b/docs/content/docs/developer-guide/updating-vendure.md index af5eb90e9d..52027d13b0 100644 --- a/docs/content/docs/developer-guide/updating-vendure.md +++ b/docs/content/docs/developer-guide/updating-vendure.md @@ -58,10 +58,11 @@ The key rule is **never run your production instance with the `synchronize` opti For any database schema changes, it is advised to: 1. Read the changelog breaking changes entries to see what changes to expect -2. Create a new database migration as described in the [Migrations guide](https://www.vendure.io/docs/developer-guide/migrations/) -3. Manually check the migration script. In some cases manual action is needed to customize the script in order to correctly migrate your existing data. -4. Test the migration script against non-production data. -5. Only when you have verified that the migration works as expected, run it against your production database. +2. **Important:** Make a backup of your database! +3. Create a new database migration as described in the [Migrations guide]({{< relref "migrations" >}}) +4. Manually check the migration script. In some cases manual action is needed to customize the script in order to correctly migrate your existing data. +5. Test the migration script against non-production data. +6. Only when you have verified that the migration works as expected, run it against your production database. ### GraphQL schema changes From 4713425d14f78fc445b9c44423d40a09980fbcf1 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Thu, 12 Nov 2020 17:45:13 +0100 Subject: [PATCH 13/21] chore(docs): Update storefront examples --- .../building-a-storefront/_index.md | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/docs/content/docs/storefront/building-a-storefront/_index.md b/docs/content/docs/storefront/building-a-storefront/_index.md index 815917ca1f..9fedf50de0 100644 --- a/docs/content/docs/storefront/building-a-storefront/_index.md +++ b/docs/content/docs/storefront/building-a-storefront/_index.md @@ -8,11 +8,11 @@ showtoc: true The storefront is the application which customers use to buy things from your store. -As a headless server, Vendure provides a GraphQL API and admin UI app, but no storefront. The key advantage of the headless model is that the storefront (or indeed, any number of client applications) can be developed completely independently of the server. This flexibility comes at the cost of having to build and maintain your own storefront. +As a headless server, Vendure provides a GraphQL API and Admin UI app, but no storefront. The key advantage of the headless model is that the storefront (or indeed, any number of client applications) can be developed completely independently of the server. This flexibility comes at the cost of having to build and maintain your own storefront. -However, we'd like to lower the barrier to getting started in the regard, so here are some options you may wish to investigate: +Essentially, you can use **any technology** to build your storefront. Here are some suggestions you may wish to investigate: -## Vendure Angular Storefront +## Angular / Vendure Storefront {{< figure src="./vendure-storefront-screenshot-01.jpg" >}} @@ -22,18 +22,23 @@ A live demo can be found here: [demo.vendure.io/storefront/](https://demo.vendur Keep up with development here: [github.com/vendure-ecommerce/storefront](https://github.com/vendure-ecommerce/storefront) -## DEITY Falcon +## Next.js -[DEITY Falcon](https://falcon.deity.io/docs/getting-started/intro) is a React-based PWA storefront solution. It uses a modular architecture which allows it to connect to any e-commerce backend. We are developing the [Vendure Falcon API](https://www.npmjs.com/package/@vendure/falcon-vendure-api) which allows Falcon to be used with Vendure. +[Next.js](https://nextjs.org/) is a popular React-based framework which many Vendure developers have chosen as the basis of their storefront application. The team behind Next.js are also working on an e-commerce-specific solution, [Next.js Commerce](https://nextjs.org/commerce), which is currently under development but is worth keeping an eye on. -Here's a video showing how to quickly get started with Vendure + DEITY Falcon: +## Vue / Nuxt + +[Nuxt](https://nuxtjs.org/) is a framework based on [Vue](https://vuejs.org/) with a focus on developer experience and has support for PWA, server-side rendering and static content generation. -{{< vimeo 322812102 >}} ## Vue Storefront -[Vue Storefront](https://www.vuestorefront.io/) is one of the most popular backend-agnostic storefront PWA solutions. They offer extensive documentation on connecting their frontend application with a custom backend such as Vendure: https://github.com/DivanteLtd/vue-storefront-integration-sdk +[Vue Storefront](https://www.vuestorefront.io/) is a popular backend-agnostic storefront PWA solution. They offer documentation on connecting their frontend application with a custom backend such as Vendure: https://github.com/DivanteLtd/vue-storefront-integration-sdk ## Gatsby -We have developed a [Gatsby](https://www.gatsbyjs.org/)-based storefront app: [vendure-ecommerce/gatsby-storefront](https://github.com/vendure-ecommerce/gatsby-storefront). This is a proof-of-concept which can be used as the starting point for your own Gatsby-based storefront. +[Gatsby](https://www.gatsbyjs.org/) is a popular React-based static site generator. We have developed a Gatsby-based storefront app: [vendure-ecommerce/gatsby-storefront](https://github.com/vendure-ecommerce/gatsby-storefront). This is a minimal proof-of-concept which can be used as the starting point for your own Gatsby-based storefront. + +## Svelte / Sapper + +[Sapper](https://sapper.svelte.dev/) is a framework based on [Svelte](https://svelte.dev/), and focuses on high-performance and supports server-rendering. From 31bb06a360d5294fb48dc45c93303b15a7208350 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Fri, 13 Nov 2020 11:42:47 +0100 Subject: [PATCH 14/21] feat(core): Enable inventory tracking by default in GlobalSettings --- .../core/src/entity/global-settings/global-settings.entity.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/entity/global-settings/global-settings.entity.ts b/packages/core/src/entity/global-settings/global-settings.entity.ts index f1116431e3..68e6dde296 100644 --- a/packages/core/src/entity/global-settings/global-settings.entity.ts +++ b/packages/core/src/entity/global-settings/global-settings.entity.ts @@ -21,7 +21,7 @@ export class GlobalSettings extends VendureEntity implements HasCustomFields { * Can be overridden per ProductVariant, but this value determines the default * if not otherwise specified. */ - @Column({ default: false }) + @Column({ default: true }) trackInventory: boolean; /** From af4589fd99a9350dbc0ff2a4003e42d4b950a990 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Fri, 13 Nov 2020 12:51:18 +0100 Subject: [PATCH 15/21] feat(docs): Add stock control guide --- .../stock-control/global-stock-control.jpg | Bin 0 -> 23734 bytes .../developer-guide/stock-control/index.md | 63 ++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 docs/content/docs/developer-guide/stock-control/global-stock-control.jpg create mode 100644 docs/content/docs/developer-guide/stock-control/index.md diff --git a/docs/content/docs/developer-guide/stock-control/global-stock-control.jpg b/docs/content/docs/developer-guide/stock-control/global-stock-control.jpg new file mode 100644 index 0000000000000000000000000000000000000000..981614c9b5906683f29cc061c65b66cff58255c0 GIT binary patch literal 23734 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 literal 0 HcmV?d00001 diff --git a/docs/content/docs/developer-guide/stock-control/index.md b/docs/content/docs/developer-guide/stock-control/index.md new file mode 100644 index 0000000000..d36c4a5cd1 --- /dev/null +++ b/docs/content/docs/developer-guide/stock-control/index.md @@ -0,0 +1,63 @@ +--- +title: "Stock Control" +showtoc: true +--- + +# Stock Control + +Vendure includes features to help manage your stock levels, stock allocations and back orders. The basic purpose is to help you keep track of how many of a given ProductVariant you have available to sell. + +Stock control is enabled globally via the Global Settings: + +{{< figure src="./global-stock-control.jpg" >}} + +It can be disabled if, for example, you manage your stock with a separate inventory management system and synchronize stock levels into Vendure automatically. The setting can also be overridden at the individual ProductVariant level. + +## Stock Control Concepts + +* **Stock on hand:** This refers to the number of physical units of a particular variant which you have in stock right now. This can be zero or more, but not negative. +* **Allocated:** This refers to the number of units which have been assigned to Orders, but which have not yet been fulfilled. +* **Out-of-stock threshold:** This value determines the stock level at which the variant is considered "out of stock". This value is set globally, but can be overridden for specific variants. It defaults to `0`. +* **Saleable:** This means the number of units that can be sold right now. The formula is: + `saleable = stockOnHand - allocated - outOfStockThreshold` + +Here's a table to better illustrate the relationship between these concepts: + +Stock on hand | Allocated | Out-of-stock threshold | Saleable +--------------|-----------|------------------------|---------- +10 | 0 | 0 | 10 +10 | 0 | 3 | 7 +10 | 5 | 0 | 5 +10 | 5 | 3 | 2 +10 | 10 | 0 | 0 +10 | 10 | -5 | 5 + +The saleable value is what determines whether the customer is able to add a variant to an order. If there is 0 saleable stock, then any attempt to add to the order will result in an [`InsufficientStockError`]({{< relref "/docs/graphql-api/shop/object-types" >}}#insufficientstockerror). + +```JSON +{ + "data": { + "addItemToOrder": { + "errorCode": "INSUFFICIENT_STOCK_ERROR", + "message": "Only 105 items were added to the order due to insufficient stock", + "quantityAvailable": 105, + "order": { + "id": "2", + "totalQuantity": 106 + } + } + } +} +``` + +### Back orders + +You may have noticed that the `outOfStockThreshold` value can be set to a negative number. This allows you to sell variants even when you don't physically have them in stock. This is known as a "back order". + +Back orders can be really useful to allow orders to keep flowing even when stockOnHand temporarily drops to zero. For many businesses with predictable re-supply schedules they make a lot of sense. + +Once a customer completes checkout, those variants in the order are marked as `allocated`. When a Fulfillment is created, those allocations are converted to Sales and the `stockOnHand` of each variant is adjusted. Fulfillments may only be created if there is sufficient stock on hand. + +### Configurable stock allocation + +By default, stock is allocated when checkout completes, which means when the Order transitions to the `'PaymentAuthorized'` or `'PaymentSettled'` state. However, you may have special requirements which mean you wish to allocate stock earlier or later in the order process. With the new [StockAllocationStrategy]({{< relref "stock-allocation-strategy" >}}) you can tailor allocation to your exact needs. From 5f6f9ff14403ae457252f67e65ba64d569b1fde0 Mon Sep 17 00:00:00 2001 From: Michael Bromley Date: Fri, 13 Nov 2020 13:04:33 +0100 Subject: [PATCH 16/21] fix(admin-ui): Use translated state labels in custom filter select --- .../src/components/order-list/order-list.component.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/admin-ui/src/lib/order/src/components/order-list/order-list.component.html b/packages/admin-ui/src/lib/order/src/components/order-list/order-list.component.html index c825efa470..87364e74ad 100644 --- a/packages/admin-ui/src/lib/order/src/components/order-list/order-list.component.html +++ b/packages/admin-ui/src/lib/order/src/components/order-list/order-list.component.html @@ -41,6 +41,11 @@ [clearable]="true" [searchable]="false" > + {{ item | stateI18nToken | translate }} + + {{ item | stateI18nToken | translate }} + +