Browse Source

refactor(admin-ui): Update to use new error handling APIs

Relates to #437
Michael Bromley 5 years ago
parent
commit
cfa511bec5
17 changed files with 964 additions and 341 deletions
  1. 328 189
      packages/admin-ui/src/lib/core/src/common/generated-types.ts
  2. 315 3
      packages/admin-ui/src/lib/core/src/common/introspection-result.ts
  3. 8 4
      packages/admin-ui/src/lib/core/src/data/definitions/auth-definitions.ts
  4. 6 0
      packages/admin-ui/src/lib/core/src/data/definitions/customer-definitions.ts
  5. 40 7
      packages/admin-ui/src/lib/core/src/data/definitions/order-definitions.ts
  6. 12 6
      packages/admin-ui/src/lib/core/src/data/definitions/product-definitions.ts
  7. 7 1
      packages/admin-ui/src/lib/core/src/data/definitions/promotion-definitions.ts
  8. 7 1
      packages/admin-ui/src/lib/core/src/data/definitions/settings-definitions.ts
  9. 7 0
      packages/admin-ui/src/lib/core/src/data/definitions/shared-definitions.ts
  10. 20 8
      packages/admin-ui/src/lib/core/src/providers/auth/auth.service.ts
  11. 66 37
      packages/admin-ui/src/lib/customer/src/components/customer-detail/customer-detail.component.ts
  12. 7 0
      packages/admin-ui/src/lib/login/src/components/login/login.component.html
  13. 15 10
      packages/admin-ui/src/lib/login/src/components/login/login.component.ts
  14. 14 5
      packages/admin-ui/src/lib/marketing/src/components/promotion-detail/promotion-detail.component.ts
  15. 64 23
      packages/admin-ui/src/lib/order/src/components/order-detail/order-detail.component.ts
  16. 30 31
      packages/admin-ui/src/lib/settings/src/components/channel-detail/channel-detail.component.ts
  17. 18 16
      packages/admin-ui/src/lib/settings/src/components/global-settings/global-settings.component.ts

File diff suppressed because it is too large
+ 328 - 189
packages/admin-ui/src/lib/core/src/common/generated-types.ts


+ 315 - 3
packages/admin-ui/src/lib/core/src/common/introspection-result.ts

@@ -280,13 +280,16 @@ const result: IntrospectionResultData = {
             },
             },
             {
             {
                 kind: 'UNION',
                 kind: 'UNION',
-                name: 'CreateAssetResult',
+                name: 'AddFulfillmentToOrderResult',
                 possibleTypes: [
                 possibleTypes: [
                     {
                     {
-                        name: 'Asset',
+                        name: 'Fulfillment',
                     },
                     },
                     {
                     {
-                        name: 'MimeTypeError',
+                        name: 'EmptyOrderLineSelectionError',
+                    },
+                    {
+                        name: 'ItemsAlreadyFulfilledError',
                     },
                     },
                 ],
                 ],
             },
             },
@@ -294,9 +297,318 @@ const result: IntrospectionResultData = {
                 kind: 'INTERFACE',
                 kind: 'INTERFACE',
                 name: 'ErrorResult',
                 name: 'ErrorResult',
                 possibleTypes: [
                 possibleTypes: [
+                    {
+                        name: 'EmptyOrderLineSelectionError',
+                    },
+                    {
+                        name: 'ItemsAlreadyFulfilledError',
+                    },
+                    {
+                        name: 'InvalidCredentialsError',
+                    },
+                    {
+                        name: 'QuantityTooGreatError',
+                    },
+                    {
+                        name: 'MultipleOrderError',
+                    },
+                    {
+                        name: 'CancelActiveOrderError',
+                    },
+                    {
+                        name: 'OrderStateTransitionError',
+                    },
                     {
                     {
                         name: 'MimeTypeError',
                         name: 'MimeTypeError',
                     },
                     },
+                    {
+                        name: 'LanguageNotAvailableError',
+                    },
+                    {
+                        name: 'EmailAddressConflictError',
+                    },
+                    {
+                        name: 'MissingConditionsError',
+                    },
+                    {
+                        name: 'NativeAuthStrategyError',
+                    },
+                    {
+                        name: 'NothingToRefundError',
+                    },
+                    {
+                        name: 'PaymentOrderMismatchError',
+                    },
+                    {
+                        name: 'RefundOrderStateError',
+                    },
+                    {
+                        name: 'AlreadyRefundedError',
+                    },
+                    {
+                        name: 'RefundStateTransitionError',
+                    },
+                    {
+                        name: 'ProductOptionInUseError',
+                    },
+                    {
+                        name: 'SettlePaymentError',
+                    },
+                    {
+                        name: 'PaymentStateTransitionError',
+                    },
+                    {
+                        name: 'FulfillmentStateTransitionError',
+                    },
+                    {
+                        name: 'ChannelDefaultLanguageError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'AuthenticationResult',
+                possibleTypes: [
+                    {
+                        name: 'CurrentUser',
+                    },
+                    {
+                        name: 'InvalidCredentialsError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'CancelOrderResult',
+                possibleTypes: [
+                    {
+                        name: 'Order',
+                    },
+                    {
+                        name: 'EmptyOrderLineSelectionError',
+                    },
+                    {
+                        name: 'QuantityTooGreatError',
+                    },
+                    {
+                        name: 'MultipleOrderError',
+                    },
+                    {
+                        name: 'CancelActiveOrderError',
+                    },
+                    {
+                        name: 'OrderStateTransitionError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'CreateAssetResult',
+                possibleTypes: [
+                    {
+                        name: 'Asset',
+                    },
+                    {
+                        name: 'MimeTypeError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'CreateChannelResult',
+                possibleTypes: [
+                    {
+                        name: 'Channel',
+                    },
+                    {
+                        name: 'LanguageNotAvailableError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'CreateCustomerResult',
+                possibleTypes: [
+                    {
+                        name: 'Customer',
+                    },
+                    {
+                        name: 'EmailAddressConflictError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'CreatePromotionResult',
+                possibleTypes: [
+                    {
+                        name: 'Promotion',
+                    },
+                    {
+                        name: 'MissingConditionsError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'NativeAuthenticationResult',
+                possibleTypes: [
+                    {
+                        name: 'CurrentUser',
+                    },
+                    {
+                        name: 'InvalidCredentialsError',
+                    },
+                    {
+                        name: 'NativeAuthStrategyError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'RefundOrderResult',
+                possibleTypes: [
+                    {
+                        name: 'Refund',
+                    },
+                    {
+                        name: 'QuantityTooGreatError',
+                    },
+                    {
+                        name: 'NothingToRefundError',
+                    },
+                    {
+                        name: 'OrderStateTransitionError',
+                    },
+                    {
+                        name: 'MultipleOrderError',
+                    },
+                    {
+                        name: 'PaymentOrderMismatchError',
+                    },
+                    {
+                        name: 'RefundOrderStateError',
+                    },
+                    {
+                        name: 'AlreadyRefundedError',
+                    },
+                    {
+                        name: 'RefundStateTransitionError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'RemoveOptionGroupFromProductResult',
+                possibleTypes: [
+                    {
+                        name: 'Product',
+                    },
+                    {
+                        name: 'ProductOptionInUseError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'SettlePaymentResult',
+                possibleTypes: [
+                    {
+                        name: 'Payment',
+                    },
+                    {
+                        name: 'SettlePaymentError',
+                    },
+                    {
+                        name: 'PaymentStateTransitionError',
+                    },
+                    {
+                        name: 'OrderStateTransitionError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'SettleRefundResult',
+                possibleTypes: [
+                    {
+                        name: 'Refund',
+                    },
+                    {
+                        name: 'RefundStateTransitionError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'TransitionFulfillmentToStateResult',
+                possibleTypes: [
+                    {
+                        name: 'Fulfillment',
+                    },
+                    {
+                        name: 'FulfillmentStateTransitionError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'TransitionOrderToStateResult',
+                possibleTypes: [
+                    {
+                        name: 'Order',
+                    },
+                    {
+                        name: 'OrderStateTransitionError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'UpdateChannelResult',
+                possibleTypes: [
+                    {
+                        name: 'Channel',
+                    },
+                    {
+                        name: 'LanguageNotAvailableError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'UpdateCustomerResult',
+                possibleTypes: [
+                    {
+                        name: 'Customer',
+                    },
+                    {
+                        name: 'EmailAddressConflictError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'UpdateGlobalSettingsResult',
+                possibleTypes: [
+                    {
+                        name: 'GlobalSettings',
+                    },
+                    {
+                        name: 'ChannelDefaultLanguageError',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'UpdatePromotionResult',
+                possibleTypes: [
+                    {
+                        name: 'Promotion',
+                    },
+                    {
+                        name: 'MissingConditionsError',
+                    },
                 ],
                 ],
             },
             },
         ],
         ],

+ 8 - 4
packages/admin-ui/src/lib/core/src/data/definitions/auth-definitions.ts

@@ -1,5 +1,7 @@
 import gql from 'graphql-tag';
 import gql from 'graphql-tag';
 
 
+import { ERROR_RESULT_FRAGMENT } from './shared-definitions';
+
 export const CURRENT_USER_FRAGMENT = gql`
 export const CURRENT_USER_FRAGMENT = gql`
     fragment CurrentUser on CurrentUser {
     fragment CurrentUser on CurrentUser {
         id
         id
@@ -16,17 +18,19 @@ export const CURRENT_USER_FRAGMENT = gql`
 export const ATTEMPT_LOGIN = gql`
 export const ATTEMPT_LOGIN = gql`
     mutation AttemptLogin($username: String!, $password: String!, $rememberMe: Boolean!) {
     mutation AttemptLogin($username: String!, $password: String!, $rememberMe: Boolean!) {
         login(username: $username, password: $password, rememberMe: $rememberMe) {
         login(username: $username, password: $password, rememberMe: $rememberMe) {
-            user {
-                ...CurrentUser
-            }
+            ...CurrentUser
+            ...ErrorResult
         }
         }
     }
     }
     ${CURRENT_USER_FRAGMENT}
     ${CURRENT_USER_FRAGMENT}
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const LOG_OUT = gql`
 export const LOG_OUT = gql`
     mutation LogOut {
     mutation LogOut {
-        logout
+        logout {
+            success
+        }
     }
     }
 `;
 `;
 
 

+ 6 - 0
packages/admin-ui/src/lib/core/src/data/definitions/customer-definitions.ts

@@ -1,5 +1,7 @@
 import gql from 'graphql-tag';
 import gql from 'graphql-tag';
 
 
+import { ERROR_RESULT_FRAGMENT } from './shared-definitions';
+
 export const ADDRESS_FRAGMENT = gql`
 export const ADDRESS_FRAGMENT = gql`
     fragment Address on Address {
     fragment Address on Address {
         id
         id
@@ -95,18 +97,22 @@ export const CREATE_CUSTOMER = gql`
     mutation CreateCustomer($input: CreateCustomerInput!, $password: String) {
     mutation CreateCustomer($input: CreateCustomerInput!, $password: String) {
         createCustomer(input: $input, password: $password) {
         createCustomer(input: $input, password: $password) {
             ...Customer
             ...Customer
+            ...ErrorResult
         }
         }
     }
     }
     ${CUSTOMER_FRAGMENT}
     ${CUSTOMER_FRAGMENT}
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const UPDATE_CUSTOMER = gql`
 export const UPDATE_CUSTOMER = gql`
     mutation UpdateCustomer($input: UpdateCustomerInput!) {
     mutation UpdateCustomer($input: UpdateCustomerInput!) {
         updateCustomer(input: $input) {
         updateCustomer(input: $input) {
             ...Customer
             ...Customer
+            ...ErrorResult
         }
         }
     }
     }
     ${CUSTOMER_FRAGMENT}
     ${CUSTOMER_FRAGMENT}
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const DELETE_CUSTOMER = gql`
 export const DELETE_CUSTOMER = gql`

+ 40 - 7
packages/admin-ui/src/lib/core/src/data/definitions/order-definitions.ts

@@ -1,5 +1,7 @@
 import gql from 'graphql-tag';
 import gql from 'graphql-tag';
 
 
+import { ERROR_RESULT_FRAGMENT } from './shared-definitions';
+
 export const ADJUSTMENT_FRAGMENT = gql`
 export const ADJUSTMENT_FRAGMENT = gql`
     fragment Adjustment on Adjustment {
     fragment Adjustment on Adjustment {
         adjustmentSource
         adjustmentSource
@@ -199,50 +201,71 @@ export const GET_ORDER = gql`
 export const SETTLE_PAYMENT = gql`
 export const SETTLE_PAYMENT = gql`
     mutation SettlePayment($id: ID!) {
     mutation SettlePayment($id: ID!) {
         settlePayment(id: $id) {
         settlePayment(id: $id) {
-            id
-            transactionId
-            amount
-            method
-            state
-            metadata
+            ... on Payment {
+                id
+                transactionId
+                amount
+                method
+                state
+                metadata
+            }
+            ...ErrorResult
+            ... on SettlePaymentError {
+                paymentErrorMessage
+            }
+            ... on PaymentStateTransitionError {
+                transitionError
+            }
+            ... on OrderStateTransitionError {
+                transitionError
+            }
         }
         }
     }
     }
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const CREATE_FULFILLMENT = gql`
 export const CREATE_FULFILLMENT = gql`
     mutation CreateFulfillment($input: FulfillOrderInput!) {
     mutation CreateFulfillment($input: FulfillOrderInput!) {
-        fulfillOrder(input: $input) {
+        addFulfillmentToOrder(input: $input) {
             ...Fulfillment
             ...Fulfillment
+            ...ErrorResult
         }
         }
     }
     }
     ${FULFILLMENT_FRAGMENT}
     ${FULFILLMENT_FRAGMENT}
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const CANCEL_ORDER = gql`
 export const CANCEL_ORDER = gql`
     mutation CancelOrder($input: CancelOrderInput!) {
     mutation CancelOrder($input: CancelOrderInput!) {
         cancelOrder(input: $input) {
         cancelOrder(input: $input) {
             ...OrderDetail
             ...OrderDetail
+            ...ErrorResult
         }
         }
     }
     }
     ${ORDER_DETAIL_FRAGMENT}
     ${ORDER_DETAIL_FRAGMENT}
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const REFUND_ORDER = gql`
 export const REFUND_ORDER = gql`
     mutation RefundOrder($input: RefundOrderInput!) {
     mutation RefundOrder($input: RefundOrderInput!) {
         refundOrder(input: $input) {
         refundOrder(input: $input) {
             ...Refund
             ...Refund
+            ...ErrorResult
         }
         }
     }
     }
     ${REFUND_FRAGMENT}
     ${REFUND_FRAGMENT}
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const SETTLE_REFUND = gql`
 export const SETTLE_REFUND = gql`
     mutation SettleRefund($input: SettleRefundInput!) {
     mutation SettleRefund($input: SettleRefundInput!) {
         settleRefund(input: $input) {
         settleRefund(input: $input) {
             ...Refund
             ...Refund
+            ...ErrorResult
         }
         }
     }
     }
     ${REFUND_FRAGMENT}
     ${REFUND_FRAGMENT}
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const GET_ORDER_HISTORY = gql`
 export const GET_ORDER_HISTORY = gql`
@@ -299,9 +322,14 @@ export const TRANSITION_ORDER_TO_STATE = gql`
     mutation TransitionOrderToState($id: ID!, $state: String!) {
     mutation TransitionOrderToState($id: ID!, $state: String!) {
         transitionOrderToState(id: $id, state: $state) {
         transitionOrderToState(id: $id, state: $state) {
             ...Order
             ...Order
+            ...ErrorResult
+            ... on OrderStateTransitionError {
+                transitionError
+            }
         }
         }
     }
     }
     ${ORDER_FRAGMENT}
     ${ORDER_FRAGMENT}
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const UPDATE_ORDER_CUSTOM_FIELDS = gql`
 export const UPDATE_ORDER_CUSTOM_FIELDS = gql`
@@ -317,7 +345,12 @@ export const TRANSITION_FULFILLMENT_TO_STATE = gql`
     mutation TransitionFulfillmentToState($id: ID!, $state: String!) {
     mutation TransitionFulfillmentToState($id: ID!, $state: String!) {
         transitionFulfillmentToState(id: $id, state: $state) {
         transitionFulfillmentToState(id: $id, state: $state) {
             ...Fulfillment
             ...Fulfillment
+            ...ErrorResult
+            ... on FulfillmentStateTransitionError {
+                transitionError
+            }
         }
         }
     }
     }
     ${FULFILLMENT_FRAGMENT}
     ${FULFILLMENT_FRAGMENT}
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;

+ 12 - 6
packages/admin-ui/src/lib/core/src/data/definitions/product-definitions.ts

@@ -1,5 +1,7 @@
 import gql from 'graphql-tag';
 import gql from 'graphql-tag';
 
 
+import { ERROR_RESULT_FRAGMENT } from './shared-definitions';
+
 export const ASSET_FRAGMENT = gql`
 export const ASSET_FRAGMENT = gql`
     fragment Asset on Asset {
     fragment Asset on Asset {
         id
         id
@@ -274,23 +276,27 @@ export const ADD_OPTION_GROUP_TO_PRODUCT = gql`
 export const REMOVE_OPTION_GROUP_FROM_PRODUCT = gql`
 export const REMOVE_OPTION_GROUP_FROM_PRODUCT = gql`
     mutation RemoveOptionGroupFromProduct($productId: ID!, $optionGroupId: ID!) {
     mutation RemoveOptionGroupFromProduct($productId: ID!, $optionGroupId: ID!) {
         removeOptionGroupFromProduct(productId: $productId, optionGroupId: $optionGroupId) {
         removeOptionGroupFromProduct(productId: $productId, optionGroupId: $optionGroupId) {
-            id
-            createdAt
-            updatedAt
-            optionGroups {
+            ... on Product {
                 id
                 id
                 createdAt
                 createdAt
                 updatedAt
                 updatedAt
-                code
-                options {
+                optionGroups {
                     id
                     id
                     createdAt
                     createdAt
                     updatedAt
                     updatedAt
                     code
                     code
+                    options {
+                        id
+                        createdAt
+                        updatedAt
+                        code
+                    }
                 }
                 }
             }
             }
+            ...ErrorResult
         }
         }
     }
     }
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const GET_PRODUCT_WITH_VARIANTS = gql`
 export const GET_PRODUCT_WITH_VARIANTS = gql`

+ 7 - 1
packages/admin-ui/src/lib/core/src/data/definitions/promotion-definitions.ts

@@ -1,6 +1,10 @@
 import gql from 'graphql-tag';
 import gql from 'graphql-tag';
 
 
-import { CONFIGURABLE_OPERATION_DEF_FRAGMENT, CONFIGURABLE_OPERATION_FRAGMENT } from './shared-definitions';
+import {
+    CONFIGURABLE_OPERATION_DEF_FRAGMENT,
+    CONFIGURABLE_OPERATION_FRAGMENT,
+    ERROR_RESULT_FRAGMENT,
+} from './shared-definitions';
 
 
 export const PROMOTION_FRAGMENT = gql`
 export const PROMOTION_FRAGMENT = gql`
     fragment Promotion on Promotion {
     fragment Promotion on Promotion {
@@ -60,9 +64,11 @@ export const CREATE_PROMOTION = gql`
     mutation CreatePromotion($input: CreatePromotionInput!) {
     mutation CreatePromotion($input: CreatePromotionInput!) {
         createPromotion(input: $input) {
         createPromotion(input: $input) {
             ...Promotion
             ...Promotion
+            ...ErrorResult
         }
         }
     }
     }
     ${PROMOTION_FRAGMENT}
     ${PROMOTION_FRAGMENT}
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const UPDATE_PROMOTION = gql`
 export const UPDATE_PROMOTION = gql`

+ 7 - 1
packages/admin-ui/src/lib/core/src/data/definitions/settings-definitions.ts

@@ -1,6 +1,6 @@
 import gql from 'graphql-tag';
 import gql from 'graphql-tag';
 
 
-import { CONFIGURABLE_OPERATION_DEF_FRAGMENT } from './shared-definitions';
+import { CONFIGURABLE_OPERATION_DEF_FRAGMENT, ERROR_RESULT_FRAGMENT } from './shared-definitions';
 
 
 export const COUNTRY_FRAGMENT = gql`
 export const COUNTRY_FRAGMENT = gql`
     fragment Country on Country {
     fragment Country on Country {
@@ -342,18 +342,22 @@ export const CREATE_CHANNEL = gql`
     mutation CreateChannel($input: CreateChannelInput!) {
     mutation CreateChannel($input: CreateChannelInput!) {
         createChannel(input: $input) {
         createChannel(input: $input) {
             ...Channel
             ...Channel
+            ...ErrorResult
         }
         }
     }
     }
     ${CHANNEL_FRAGMENT}
     ${CHANNEL_FRAGMENT}
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const UPDATE_CHANNEL = gql`
 export const UPDATE_CHANNEL = gql`
     mutation UpdateChannel($input: UpdateChannelInput!) {
     mutation UpdateChannel($input: UpdateChannelInput!) {
         updateChannel(input: $input) {
         updateChannel(input: $input) {
             ...Channel
             ...Channel
+            ...ErrorResult
         }
         }
     }
     }
     ${CHANNEL_FRAGMENT}
     ${CHANNEL_FRAGMENT}
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const DELETE_CHANNEL = gql`
 export const DELETE_CHANNEL = gql`
@@ -433,9 +437,11 @@ export const UPDATE_GLOBAL_SETTINGS = gql`
     mutation UpdateGlobalSettings($input: UpdateGlobalSettingsInput!) {
     mutation UpdateGlobalSettings($input: UpdateGlobalSettingsInput!) {
         updateGlobalSettings(input: $input) {
         updateGlobalSettings(input: $input) {
             ...GlobalSettings
             ...GlobalSettings
+            ...ErrorResult
         }
         }
     }
     }
     ${GLOBAL_SETTINGS_FRAGMENT}
     ${GLOBAL_SETTINGS_FRAGMENT}
+    ${ERROR_RESULT_FRAGMENT}
 `;
 `;
 
 
 export const CUSTOM_FIELD_CONFIG_FRAGMENT = gql`
 export const CUSTOM_FIELD_CONFIG_FRAGMENT = gql`

+ 7 - 0
packages/admin-ui/src/lib/core/src/data/definitions/shared-definitions.ts

@@ -23,3 +23,10 @@ export const CONFIGURABLE_OPERATION_DEF_FRAGMENT = gql`
         description
         description
     }
     }
 `;
 `;
+
+export const ERROR_RESULT_FRAGMENT = gql`
+    fragment ErrorResult on ErrorResult {
+        errorCode
+        message
+    }
+`;

+ 20 - 8
packages/admin-ui/src/lib/core/src/providers/auth/auth.service.ts

@@ -1,9 +1,14 @@
 import { Injectable } from '@angular/core';
 import { Injectable } from '@angular/core';
 import { DEFAULT_CHANNEL_CODE } from '@vendure/common/lib/shared-constants';
 import { DEFAULT_CHANNEL_CODE } from '@vendure/common/lib/shared-constants';
 import { Observable, of } from 'rxjs';
 import { Observable, of } from 'rxjs';
-import { catchError, mapTo, mergeMap, switchMap } from 'rxjs/operators';
+import { catchError, map, mapTo, mergeMap, switchMap } from 'rxjs/operators';
 
 
-import { CurrentUserChannel, CurrentUserFragment, SetAsLoggedIn } from '../../common/generated-types';
+import {
+    AttemptLogin,
+    CurrentUserChannel,
+    CurrentUserFragment,
+    SetAsLoggedIn,
+} from '../../common/generated-types';
 import { DataService } from '../../data/providers/data.service';
 import { DataService } from '../../data/providers/data.service';
 import { ServerConfigService } from '../../data/server-config';
 import { ServerConfigService } from '../../data/server-config';
 import { LocalStorageService } from '../local-storage/local-storage.service';
 import { LocalStorageService } from '../local-storage/local-storage.service';
@@ -25,15 +30,22 @@ export class AuthService {
      * Attempts to log in via the REST login endpoint and updates the app
      * Attempts to log in via the REST login endpoint and updates the app
      * state on success.
      * state on success.
      */
      */
-    logIn(username: string, password: string, rememberMe: boolean): Observable<SetAsLoggedIn.Mutation> {
+    logIn(username: string, password: string, rememberMe: boolean): Observable<AttemptLogin.Login> {
         return this.dataService.auth.attemptLogin(username, password, rememberMe).pipe(
         return this.dataService.auth.attemptLogin(username, password, rememberMe).pipe(
             switchMap(response => {
             switchMap(response => {
-                this.setChannelToken(response.login.user.channels);
-                return this.serverConfigService.getServerConfig().then(() => response.login.user);
+                if (response.login.__typename === 'CurrentUser') {
+                    this.setChannelToken(response.login.channels);
+                }
+                return this.serverConfigService.getServerConfig().then(() => response.login);
             }),
             }),
-            switchMap(user => {
-                const { id } = this.getActiveChannel(user.channels);
-                return this.dataService.client.loginSuccess(username, id, user.channels);
+            switchMap(login => {
+                if (login.__typename === 'CurrentUser') {
+                    const { id } = this.getActiveChannel(login.channels);
+                    return this.dataService.client
+                        .loginSuccess(username, id, login.channels)
+                        .pipe(map(() => login));
+                }
+                return of(login);
             }),
             }),
         );
         );
     }
     }

+ 66 - 37
packages/admin-ui/src/lib/customer/src/components/customer-detail/customer-detail.component.ts

@@ -5,6 +5,8 @@ import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
 import {
 import {
     BaseDetailComponent,
     BaseDetailComponent,
     CreateAddressInput,
     CreateAddressInput,
+    CreateCustomerAddress,
+    CreateCustomerAddressMutation,
     CreateCustomerInput,
     CreateCustomerInput,
     Customer,
     Customer,
     CustomFieldConfig,
     CustomFieldConfig,
@@ -19,7 +21,11 @@ import {
     NotificationService,
     NotificationService,
     ServerConfigService,
     ServerConfigService,
     SortOrder,
     SortOrder,
+    UpdateCustomer,
+    UpdateCustomerAddress,
+    UpdateCustomerAddressMutation,
     UpdateCustomerInput,
     UpdateCustomerInput,
+    UpdateCustomerMutation,
 } from '@vendure/admin-ui/core';
 } from '@vendure/admin-ui/core';
 import { notNullOrUndefined } from '@vendure/common/lib/shared-utils';
 import { notNullOrUndefined } from '@vendure/common/lib/shared-utils';
 import { EMPTY, forkJoin, from, Observable, Subject } from 'rxjs';
 import { EMPTY, forkJoin, from, Observable, Subject } from 'rxjs';
@@ -183,30 +189,31 @@ export class CustomerDetailComponent extends BaseDetailComponent<CustomerWithOrd
             phoneNumber: formValue.phoneNumber,
             phoneNumber: formValue.phoneNumber,
             customFields,
             customFields,
         };
         };
-        this.dataService.customer.createCustomer(customer, formValue.password).subscribe(
-            data => {
-                this.notificationService.success(_('common.notify-create-success'), {
-                    entity: 'Customer',
-                });
-                if (data.createCustomer.emailAddress && !formValue.password) {
-                    this.notificationService.notify({
-                        message: _('customer.email-verification-sent'),
-                        translationVars: { emailAddress: formValue.emailAddress },
-                        type: 'info',
-                        duration: 10000,
-                    });
+        this.dataService.customer
+            .createCustomer(customer, formValue.password)
+            .subscribe(({ createCustomer }) => {
+                switch (createCustomer.__typename) {
+                    case 'Customer':
+                        this.notificationService.success(_('common.notify-create-success'), {
+                            entity: 'Customer',
+                        });
+                        if (createCustomer.emailAddress && !formValue.password) {
+                            this.notificationService.notify({
+                                message: _('customer.email-verification-sent'),
+                                translationVars: { emailAddress: formValue.emailAddress },
+                                type: 'info',
+                                duration: 10000,
+                            });
+                        }
+                        this.detailForm.markAsPristine();
+                        this.addressDefaultsUpdated = false;
+                        this.changeDetector.markForCheck();
+                        this.router.navigate(['../', createCustomer.id], { relativeTo: this.route });
+                        break;
+                    case 'EmailAddressConflictError':
+                        this.notificationService.error(createCustomer.message);
                 }
                 }
-                this.detailForm.markAsPristine();
-                this.addressDefaultsUpdated = false;
-                this.changeDetector.markForCheck();
-                this.router.navigate(['../', data.createCustomer.id], { relativeTo: this.route });
-            },
-            err => {
-                this.notificationService.error(_('common.notify-create-error'), {
-                    entity: 'Customer',
-                });
-            },
-        );
+            });
     }
     }
 
 
     save() {
     save() {
@@ -214,7 +221,11 @@ export class CustomerDetailComponent extends BaseDetailComponent<CustomerWithOrd
             .pipe(
             .pipe(
                 take(1),
                 take(1),
                 mergeMap(({ id }) => {
                 mergeMap(({ id }) => {
-                    const saveOperations: Array<Observable<any>> = [];
+                    const saveOperations: Array<Observable<
+                        | UpdateCustomer.UpdateCustomer
+                        | CreateCustomerAddress.CreateCustomerAddress
+                        | UpdateCustomerAddress.UpdateCustomerAddress
+                    >> = [];
                     const customerForm = this.detailForm.get('customer');
                     const customerForm = this.detailForm.get('customer');
                     if (customerForm && customerForm.dirty) {
                     if (customerForm && customerForm.dirty) {
                         const formValue = customerForm.value;
                         const formValue = customerForm.value;
@@ -228,7 +239,11 @@ export class CustomerDetailComponent extends BaseDetailComponent<CustomerWithOrd
                             phoneNumber: formValue.phoneNumber,
                             phoneNumber: formValue.phoneNumber,
                             customFields,
                             customFields,
                         };
                         };
-                        saveOperations.push(this.dataService.customer.updateCustomer(customer));
+                        saveOperations.push(
+                            this.dataService.customer
+                                .updateCustomer(customer)
+                                .pipe(map(res => res.updateCustomer)),
+                        );
                     }
                     }
                     const addressFormArray = this.detailForm.get('addresses') as FormArray;
                     const addressFormArray = this.detailForm.get('addresses') as FormArray;
                     if ((addressFormArray && addressFormArray.dirty) || this.addressDefaultsUpdated) {
                     if ((addressFormArray && addressFormArray.dirty) || this.addressDefaultsUpdated) {
@@ -251,14 +266,18 @@ export class CustomerDetailComponent extends BaseDetailComponent<CustomerWithOrd
                                 };
                                 };
                                 if (!address.id) {
                                 if (!address.id) {
                                     saveOperations.push(
                                     saveOperations.push(
-                                        this.dataService.customer.createCustomerAddress(id, input),
+                                        this.dataService.customer
+                                            .createCustomerAddress(id, input)
+                                            .pipe(map(res => res.createCustomerAddress)),
                                     );
                                     );
                                 } else {
                                 } else {
                                     saveOperations.push(
                                     saveOperations.push(
-                                        this.dataService.customer.updateCustomerAddress({
-                                            ...input,
-                                            id: address.id,
-                                        }),
+                                        this.dataService.customer
+                                            .updateCustomerAddress({
+                                                ...input,
+                                                id: address.id,
+                                            })
+                                            .pipe(map(res => res.updateCustomerAddress)),
                                     );
                                     );
                                 }
                                 }
                             }
                             }
@@ -269,13 +288,23 @@ export class CustomerDetailComponent extends BaseDetailComponent<CustomerWithOrd
             )
             )
             .subscribe(
             .subscribe(
                 data => {
                 data => {
-                    this.notificationService.success(_('common.notify-update-success'), {
-                        entity: 'Customer',
-                    });
-                    this.detailForm.markAsPristine();
-                    this.addressDefaultsUpdated = false;
-                    this.changeDetector.markForCheck();
-                    this.fetchHistory.next();
+                    for (const result of data) {
+                        switch (result.__typename) {
+                            case 'Customer':
+                            case 'Address':
+                                this.notificationService.success(_('common.notify-update-success'), {
+                                    entity: 'Customer',
+                                });
+                                this.detailForm.markAsPristine();
+                                this.addressDefaultsUpdated = false;
+                                this.changeDetector.markForCheck();
+                                this.fetchHistory.next();
+                                break;
+                            case 'EmailAddressConflictError':
+                                this.notificationService.error(result.message);
+                                break;
+                        }
+                    }
                 },
                 },
                 err => {
                 err => {
                     this.notificationService.error(_('common.notify-update-error'), {
                     this.notificationService.error(_('common.notify-update-error'), {

+ 7 - 0
packages/admin-ui/src/lib/login/src/components/login/login.component.html

@@ -36,6 +36,13 @@
             >
             >
                 {{ 'common.login' | translate }}
                 {{ 'common.login' | translate }}
             </button>
             </button>
+            <clr-alert [clrAlertType]="'danger'" *ngIf="errorMessage">
+                <clr-alert-item>
+                    <span class="alert-text">
+                        {{ errorMessage }}
+                    </span>
+                </clr-alert-item>
+            </clr-alert>
         </div>
         </div>
         <div class="version">vendure {{ version }}</div>
         <div class="version">vendure {{ version }}</div>
     </form>
     </form>

+ 15 - 10
packages/admin-ui/src/lib/login/src/components/login/login.component.ts

@@ -12,23 +12,28 @@ export class LoginComponent {
     password = '';
     password = '';
     rememberMe = false;
     rememberMe = false;
     version = ADMIN_UI_VERSION;
     version = ADMIN_UI_VERSION;
+    errorMessage: string | undefined;
 
 
     constructor(private authService: AuthService, private router: Router) {}
     constructor(private authService: AuthService, private router: Router) {}
 
 
     logIn(): void {
     logIn(): void {
-        this.authService.logIn(this.username, this.password, this.rememberMe).subscribe(
-            () => {
-                const redirect = this.getRedirectRoute();
-                this.router.navigateByUrl(redirect ? redirect : '/');
-            },
-            err => {
-                /* error handled by http interceptor */
-            },
-        );
+        this.errorMessage = undefined;
+        this.authService.logIn(this.username, this.password, this.rememberMe).subscribe(result => {
+            switch (result.__typename) {
+                case 'CurrentUser':
+                    const redirect = this.getRedirectRoute();
+                    this.router.navigateByUrl(redirect ? redirect : '/');
+                    break;
+                case 'InvalidCredentialsError':
+                case 'NativeAuthStrategyError':
+                    this.errorMessage = result.message;
+                    break;
+            }
+        });
     }
     }
 
 
     /**
     /**
-     * Attemps to read a redirect param from the current url and parse it into a
+     * Attempts to read a redirect param from the current url and parse it into a
      * route from which the user was redirected after a 401 error.
      * route from which the user was redirected after a 401 error.
      */
      */
     private getRedirectRoute(): string | undefined {
     private getRedirectRoute(): string | undefined {

+ 14 - 5
packages/admin-ui/src/lib/marketing/src/components/promotion-detail/promotion-detail.component.ts

@@ -138,11 +138,20 @@ export class PromotionDetailComponent extends BaseDetailComponent<Promotion.Frag
             actions: this.mapOperationsToInputs(this.actions, formValue.actions),
             actions: this.mapOperationsToInputs(this.actions, formValue.actions),
         };
         };
         this.dataService.promotion.createPromotion(input).subscribe(
         this.dataService.promotion.createPromotion(input).subscribe(
-            data => {
-                this.notificationService.success(_('common.notify-create-success'), { entity: 'Promotion' });
-                this.detailForm.markAsPristine();
-                this.changeDetector.markForCheck();
-                this.router.navigate(['../', data.createPromotion.id], { relativeTo: this.route });
+            ({ createPromotion }) => {
+                switch (createPromotion.__typename) {
+                    case 'Promotion':
+                        this.notificationService.success(_('common.notify-create-success'), {
+                            entity: 'Promotion',
+                        });
+                        this.detailForm.markAsPristine();
+                        this.changeDetector.markForCheck();
+                        this.router.navigate(['../', createPromotion.id], { relativeTo: this.route });
+                        break;
+                    case 'MissingConditionsError':
+                        this.notificationService.error(createPromotion.message);
+                        break;
+                }
             },
             },
             err => {
             err => {
                 this.notificationService.error(_('common.notify-create-error'), {
                 this.notificationService.error(_('common.notify-create-error'), {

+ 64 - 23
packages/admin-ui/src/lib/order/src/components/order-detail/order-detail.component.ts

@@ -9,6 +9,7 @@ import {
     DataService,
     DataService,
     EditNoteDialogComponent,
     EditNoteDialogComponent,
     GetOrderHistory,
     GetOrderHistory,
+    GetOrderQuery,
     HistoryEntry,
     HistoryEntry,
     ModalService,
     ModalService,
     NotificationService,
     NotificationService,
@@ -132,9 +133,15 @@ export class OrderDetailComponent extends BaseDetailComponent<OrderDetail.Fragme
     }
     }
 
 
     transitionToState(state: string) {
     transitionToState(state: string) {
-        this.dataService.order.transitionToState(this.id, state).subscribe(val => {
-            this.notificationService.success(_('order.transitioned-to-state-success'), { state });
-            this.fetchHistory.next();
+        this.dataService.order.transitionToState(this.id, state).subscribe(({ transitionOrderToState }) => {
+            switch (transitionOrderToState?.__typename) {
+                case 'Order':
+                    this.notificationService.success(_('order.transitioned-to-state-success'), { state });
+                    this.fetchHistory.next();
+                    break;
+                case 'OrderStateTransitionError':
+                    this.notificationService.error(transitionOrderToState.transitionError);
+            }
         });
         });
     }
     }
 
 
@@ -171,14 +178,20 @@ export class OrderDetailComponent extends BaseDetailComponent<OrderDetail.Fragme
 
 
     settlePayment(payment: OrderDetail.Payments) {
     settlePayment(payment: OrderDetail.Payments) {
         this.dataService.order.settlePayment(payment.id).subscribe(({ settlePayment }) => {
         this.dataService.order.settlePayment(payment.id).subscribe(({ settlePayment }) => {
-            if (settlePayment) {
-                if (settlePayment.state === 'Settled') {
-                    this.notificationService.success(_('order.settle-payment-success'));
-                } else {
-                    this.notificationService.error(_('order.settle-payment-error'));
-                }
-                this.dataService.order.getOrder(this.id).single$.subscribe();
-                this.fetchHistory.next();
+            switch (settlePayment.__typename) {
+                case 'Payment':
+                    if (settlePayment.state === 'Settled') {
+                        this.notificationService.success(_('order.settle-payment-success'));
+                    } else {
+                        this.notificationService.error(_('order.settle-payment-error'));
+                    }
+                    this.dataService.order.getOrder(this.id).single$.subscribe();
+                    this.fetchHistory.next();
+                    break;
+                case 'OrderStateTransitionError':
+                case 'PaymentStateTransitionError':
+                case 'SettlePaymentError':
+                    this.notificationService.error(settlePayment.message);
             }
             }
         });
         });
     }
     }
@@ -362,15 +375,32 @@ export class OrderDetailComponent extends BaseDetailComponent<OrderDetail.Fragme
                 switchMap(input => {
                 switchMap(input => {
                     if (input) {
                     if (input) {
                         return this.dataService.order.refundOrder(omit(input, ['cancel'])).pipe(
                         return this.dataService.order.refundOrder(omit(input, ['cancel'])).pipe(
-                            switchMap(result => {
-                                if (input.cancel.length) {
-                                    return this.dataService.order.cancelOrder({
-                                        orderId: this.id,
-                                        lines: input.cancel,
-                                        reason: input.reason,
-                                    });
-                                } else {
-                                    return of(result);
+                            switchMap(({ refundOrder }) => {
+                                switch (refundOrder.__typename) {
+                                    case 'Refund':
+                                        if (input.cancel.length) {
+                                            return this.dataService.order
+                                                .cancelOrder({
+                                                    orderId: this.id,
+                                                    lines: input.cancel,
+                                                    reason: input.reason,
+                                                })
+                                                .pipe(map(({ cancelOrder }) => cancelOrder));
+                                        } else {
+                                            return of(refundOrder);
+                                        }
+                                    case 'AlreadyRefundedError':
+                                    case 'OrderStateTransitionError':
+                                    case 'MultipleOrderError':
+                                    case 'NothingToRefundError':
+                                    case 'PaymentOrderMismatchError':
+                                    case 'QuantityTooGreatError':
+                                    case 'RefundOrderStateError':
+                                    case 'RefundStateTransitionError':
+                                        this.notificationService.error(refundOrder.message);
+                                    // tslint:disable-next-line:no-switch-case-fall-through
+                                    default:
+                                        return of(undefined);
                                 }
                                 }
                             }),
                             }),
                         );
                         );
@@ -378,16 +408,27 @@ export class OrderDetailComponent extends BaseDetailComponent<OrderDetail.Fragme
                         return of(undefined);
                         return of(undefined);
                     }
                     }
                 }),
                 }),
-                switchMap(result => this.refetchOrder(result)),
             )
             )
             .subscribe(result => {
             .subscribe(result => {
                 if (result) {
                 if (result) {
-                    this.notificationService.success(_('order.refund-order-success'));
+                    switch (result.__typename) {
+                        case 'Order':
+                        case 'Refund':
+                            this.refetchOrder(result).subscribe();
+                            this.notificationService.success(_('order.refund-order-success'));
+                            break;
+                        case 'QuantityTooGreatError':
+                        case 'MultipleOrderError':
+                        case 'OrderStateTransitionError':
+                        case 'CancelActiveOrderError':
+                        case 'EmptyOrderLineSelectionError':
+                            this.notificationService.error(result.message);
+                    }
                 }
                 }
             });
             });
     }
     }
 
 
-    private refetchOrder(result: object | undefined) {
+    private refetchOrder(result: object | undefined): Observable<GetOrderQuery | undefined> {
         this.fetchHistory.next();
         this.fetchHistory.next();
         if (result) {
         if (result) {
             return this.dataService.order.getOrder(this.id).single$;
             return this.dataService.order.getOrder(this.id).single$;

+ 30 - 31
packages/admin-ui/src/lib/settings/src/components/channel-detail/channel-detail.component.ts

@@ -54,7 +54,7 @@ export class ChannelDetailComponent extends BaseDetailComponent<Channel.Fragment
 
 
     ngOnInit() {
     ngOnInit() {
         this.init();
         this.init();
-        this.zones$ = this.dataService.settings.getZones().mapSingle((data) => data.zones);
+        this.zones$ = this.dataService.settings.getZones().mapSingle(data => data.zones);
         this.availableLanguageCodes$ = this.serverConfigService.getAvailableLanguages();
         this.availableLanguageCodes$ = this.serverConfigService.getAvailableLanguages();
     }
     }
 
 
@@ -96,21 +96,21 @@ export class ChannelDetailComponent extends BaseDetailComponent<Channel.Fragment
                     this.dataService.client.updateUserChannels(me!.channels).pipe(map(() => createChannel)),
                     this.dataService.client.updateUserChannels(me!.channels).pipe(map(() => createChannel)),
                 ),
                 ),
             )
             )
-            .subscribe(
-                (data) => {
-                    this.notificationService.success(_('common.notify-create-success'), {
-                        entity: 'Channel',
-                    });
-                    this.detailForm.markAsPristine();
-                    this.changeDetector.markForCheck();
-                    this.router.navigate(['../', data.id], { relativeTo: this.route });
-                },
-                (err) => {
-                    this.notificationService.error(_('common.notify-create-error'), {
-                        entity: 'Channel',
-                    });
-                },
-            );
+            .subscribe(data => {
+                switch (data.__typename) {
+                    case 'Channel':
+                        this.notificationService.success(_('common.notify-create-success'), {
+                            entity: 'Channel',
+                        });
+                        this.detailForm.markAsPristine();
+                        this.changeDetector.markForCheck();
+                        this.router.navigate(['../', data.id], { relativeTo: this.route });
+                        break;
+                    case 'LanguageNotAvailableError':
+                        this.notificationService.error(data.message);
+                        break;
+                }
+            });
     }
     }
 
 
     save() {
     save() {
@@ -121,7 +121,7 @@ export class ChannelDetailComponent extends BaseDetailComponent<Channel.Fragment
         this.entity$
         this.entity$
             .pipe(
             .pipe(
                 take(1),
                 take(1),
-                mergeMap((channel) => {
+                mergeMap(channel => {
                     const input = {
                     const input = {
                         id: channel.id,
                         id: channel.id,
                         code: formValue.code,
                         code: formValue.code,
@@ -134,20 +134,19 @@ export class ChannelDetailComponent extends BaseDetailComponent<Channel.Fragment
                     return this.dataService.settings.updateChannel(input);
                     return this.dataService.settings.updateChannel(input);
                 }),
                 }),
             )
             )
-            .subscribe(
-                () => {
-                    this.notificationService.success(_('common.notify-update-success'), {
-                        entity: 'Channel',
-                    });
-                    this.detailForm.markAsPristine();
-                    this.changeDetector.markForCheck();
-                },
-                (err) => {
-                    this.notificationService.error(_('common.notify-update-error'), {
-                        entity: 'Channel',
-                    });
-                },
-            );
+            .subscribe(({ updateChannel }) => {
+                switch (updateChannel.__typename) {
+                    case 'Channel':
+                        this.notificationService.success(_('common.notify-update-success'), {
+                            entity: 'Channel',
+                        });
+                        this.detailForm.markAsPristine();
+                        this.changeDetector.markForCheck();
+                        break;
+                    case 'LanguageNotAvailableError':
+                        this.notificationService.error(updateChannel.message);
+                }
+            });
     }
     }
 
 
     /**
     /**

+ 18 - 16
packages/admin-ui/src/lib/settings/src/components/global-settings/global-settings.component.ts

@@ -7,7 +7,7 @@ import { CustomFieldConfig, GlobalSettings, LanguageCode, Permission } from '@ve
 import { NotificationService } from '@vendure/admin-ui/core';
 import { NotificationService } from '@vendure/admin-ui/core';
 import { DataService } from '@vendure/admin-ui/core';
 import { DataService } from '@vendure/admin-ui/core';
 import { ServerConfigService } from '@vendure/admin-ui/core';
 import { ServerConfigService } from '@vendure/admin-ui/core';
-import { switchMap } from 'rxjs/operators';
+import { switchMap, tap } from 'rxjs/operators';
 
 
 @Component({
 @Component({
     selector: 'vdr-global-settings',
     selector: 'vdr-global-settings',
@@ -63,21 +63,23 @@ export class GlobalSettingsComponent extends BaseDetailComponent<GlobalSettings>
 
 
         this.dataService.settings
         this.dataService.settings
             .updateGlobalSettings(this.detailForm.value)
             .updateGlobalSettings(this.detailForm.value)
-            .pipe(switchMap(() => this.serverConfigService.refreshGlobalSettings()))
-            .subscribe(
-                () => {
-                    this.detailForm.markAsPristine();
-                    this.changeDetector.markForCheck();
-                    this.notificationService.success(_('common.notify-update-success'), {
-                        entity: 'Settings',
-                    });
-                },
-                (err) => {
-                    this.notificationService.error(_('common.notify-update-error'), {
-                        entity: 'Settings',
-                    });
-                },
-            );
+            .pipe(
+                tap(({ updateGlobalSettings }) => {
+                    switch (updateGlobalSettings.__typename) {
+                        case 'GlobalSettings':
+                            this.detailForm.markAsPristine();
+                            this.changeDetector.markForCheck();
+                            this.notificationService.success(_('common.notify-update-success'), {
+                                entity: 'Settings',
+                            });
+                            break;
+                        case 'ChannelDefaultLanguageError':
+                            this.notificationService.error(updateGlobalSettings.message);
+                    }
+                }),
+                switchMap(() => this.serverConfigService.refreshGlobalSettings()),
+            )
+            .subscribe();
     }
     }
 
 
     protected setFormValues(entity: GlobalSettings, languageCode: LanguageCode): void {
     protected setFormValues(entity: GlobalSettings, languageCode: LanguageCode): void {

Some files were not shown because too many files changed in this diff