فهرست منبع

refactor(admin-ui): Extract common code into shared utils

Michael Bromley 3 سال پیش
والد
کامیت
6e320cc8b4

+ 8 - 26
packages/admin-ui/src/lib/catalog/src/components/collection-list/collection-list-bulk-actions.ts

@@ -1,5 +1,5 @@
 import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
-import { CollectionListComponent, CollectionPartial, ProductListComponent } from '@vendure/admin-ui/catalog';
+import { CollectionListComponent, CollectionPartial } from '@vendure/admin-ui/catalog';
 import {
     BulkAction,
     DataService,
@@ -7,14 +7,16 @@ import {
     ModalService,
     NotificationService,
     Permission,
-    SearchProducts,
 } from '@vendure/admin-ui/core';
-import { DEFAULT_CHANNEL_CODE } from '@vendure/common/lib/shared-constants';
 import { unique } from '@vendure/common/lib/unique';
 import { EMPTY, from, of } from 'rxjs';
 import { mapTo, switchMap } from 'rxjs/operators';
 
-import { getChannelCodeFromUserStatus } from '../../../../core/src/common/utilities/get-channel-code-from-user-status';
+import {
+    currentChannelIsNotDefault,
+    getChannelCodeFromUserStatus,
+    isMultiChannel,
+} from '../../../../core/src/common/utilities/bulk-action-utils';
 import { AssignToChannelDialogComponent } from '../assign-to-channel-dialog/assign-to-channel-dialog.component';
 
 export const deleteCollectionsBulkAction: BulkAction<CollectionPartial, CollectionListComponent> = {
@@ -79,13 +81,7 @@ export const assignCollectionsToChannelBulkAction: BulkAction<CollectionPartial,
     requiresPermission: userPermissions =>
         userPermissions.includes(Permission.UpdateCatalog) ||
         userPermissions.includes(Permission.UpdateProduct),
-    isVisible: ({ injector }) => {
-        return injector
-            .get(DataService)
-            .client.userStatus()
-            .mapSingle(({ userStatus }) => 1 < userStatus.channels.length)
-            .toPromise();
-    },
+    isVisible: ({ injector }) => isMultiChannel(injector.get(DataService)),
     onClick: ({ injector, selection, hostComponent, clearSelection }) => {
         const modalService = injector.get(ModalService);
         const dataService = injector.get(DataService);
@@ -129,21 +125,7 @@ export const removeCollectionsFromChannelBulkAction: BulkAction<CollectionPartia
         getTranslationVars: ({ injector }) => getChannelCodeFromUserStatus(injector.get(DataService)),
         icon: 'layers',
         iconClass: 'is-warning',
-        isVisible: ({ injector }) => {
-            return injector
-                .get(DataService)
-                .client.userStatus()
-                .mapSingle(({ userStatus }) => {
-                    if (userStatus.channels.length === 1) {
-                        return false;
-                    }
-                    const defaultChannelId = userStatus.channels.find(
-                        c => c.code === DEFAULT_CHANNEL_CODE,
-                    )?.id;
-                    return userStatus.activeChannelId !== defaultChannelId;
-                })
-                .toPromise();
-        },
+        isVisible: ({ injector }) => currentChannelIsNotDefault(injector.get(DataService)),
         onClick: ({ injector, selection, hostComponent, clearSelection }) => {
             const modalService = injector.get(ModalService);
             const dataService = injector.get(DataService);

+ 7 - 22
packages/admin-ui/src/lib/catalog/src/components/facet-list/facet-list-bulk-actions.ts

@@ -9,12 +9,15 @@ import {
     NotificationService,
     Permission,
 } from '@vendure/admin-ui/core';
-import { DEFAULT_CHANNEL_CODE } from '@vendure/common/lib/shared-constants';
 import { unique } from '@vendure/common/lib/unique';
 import { EMPTY, of } from 'rxjs';
 import { map, mapTo, switchMap } from 'rxjs/operators';
 
-import { getChannelCodeFromUserStatus } from '../../../../core/src/common/utilities/get-channel-code-from-user-status';
+import {
+    currentChannelIsNotDefault,
+    getChannelCodeFromUserStatus,
+    isMultiChannel,
+} from '../../../../core/src/common/utilities/bulk-action-utils';
 import { AssignToChannelDialogComponent } from '../assign-to-channel-dialog/assign-to-channel-dialog.component';
 
 export const deleteFacetsBulkAction: BulkAction<GetFacetList.Items, FacetListComponent> = {
@@ -108,13 +111,7 @@ export const assignFacetsToChannelBulkAction: BulkAction<GetFacetList.Items, Fac
     requiresPermission: userPermissions =>
         userPermissions.includes(Permission.UpdateFacet) ||
         userPermissions.includes(Permission.UpdateCatalog),
-    isVisible: ({ injector }) => {
-        return injector
-            .get(DataService)
-            .client.userStatus()
-            .mapSingle(({ userStatus }) => 1 < userStatus.channels.length)
-            .toPromise();
-    },
+    isVisible: ({ injector }) => isMultiChannel(injector.get(DataService)),
     onClick: ({ injector, selection, hostComponent, clearSelection }) => {
         const modalService = injector.get(ModalService);
         const dataService = injector.get(DataService);
@@ -157,19 +154,7 @@ export const removeFacetsFromChannelBulkAction: BulkAction<GetFacetList.Items, F
     requiresPermission: userPermissions =>
         userPermissions.includes(Permission.UpdateFacet) ||
         userPermissions.includes(Permission.UpdateCatalog),
-    isVisible: ({ injector }) => {
-        return injector
-            .get(DataService)
-            .client.userStatus()
-            .mapSingle(({ userStatus }) => {
-                if (userStatus.channels.length === 1) {
-                    return false;
-                }
-                const defaultChannelId = userStatus.channels.find(c => c.code === DEFAULT_CHANNEL_CODE)?.id;
-                return userStatus.activeChannelId !== defaultChannelId;
-            })
-            .toPromise();
-    },
+    isVisible: ({ injector }) => currentChannelIsNotDefault(injector.get(DataService)),
     onClick: ({ injector, selection, hostComponent, clearSelection }) => {
         const modalService = injector.get(ModalService);
         const dataService = injector.get(DataService);

+ 1 - 1
packages/admin-ui/src/lib/catalog/src/components/product-detail/product-detail.component.ts

@@ -51,7 +51,7 @@ import {
     tap,
     withLatestFrom,
 } from 'rxjs/operators';
-import { getChannelCodeFromUserStatus } from '../../../../core/src/common/utilities/get-channel-code-from-user-status';
+import { getChannelCodeFromUserStatus } from '../../../../core/src/common/utilities/bulk-action-utils';
 
 import { ProductDetailService } from '../../providers/product-detail/product-detail.service';
 import { ApplyFacetDialogComponent } from '../apply-facet-dialog/apply-facet-dialog.component';

+ 5 - 34
packages/admin-ui/src/lib/catalog/src/components/product-list/product-list-bulk-actions.ts

@@ -1,23 +1,12 @@
 import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
-import {
-    BulkAction,
-    DataService,
-    DeletionResult,
-    GetFacetList,
-    ModalService,
-    NotificationService,
-    Permission,
-    SearchProducts,
-} from '@vendure/admin-ui/core';
-import { DEFAULT_CHANNEL_CODE } from '@vendure/common/lib/shared-constants';
+import { BulkAction, DataService, DeletionResult, ModalService, NotificationService, Permission, SearchProducts, } from '@vendure/admin-ui/core';
 import { unique } from '@vendure/common/lib/unique';
 import { EMPTY, from, of } from 'rxjs';
-import { map, mapTo, switchMap } from 'rxjs/operators';
-import { getChannelCodeFromUserStatus } from '../../../../core/src/common/utilities/get-channel-code-from-user-status';
+import { mapTo, switchMap } from 'rxjs/operators';
 
+import { currentChannelIsNotDefault, getChannelCodeFromUserStatus, isMultiChannel, } from '../../../../core/src/common/utilities/bulk-action-utils';
 import { AssignProductsToChannelDialogComponent } from '../assign-products-to-channel-dialog/assign-products-to-channel-dialog.component';
 import { BulkAddFacetValuesDialogComponent } from '../bulk-add-facet-values-dialog/bulk-add-facet-values-dialog.component';
-import { FacetListComponent } from '../facet-list/facet-list.component';
 
 import { ProductListComponent } from './product-list.component';
 
@@ -82,13 +71,7 @@ export const assignProductsToChannelBulkAction: BulkAction<SearchProducts.Items,
     requiresPermission: userPermissions =>
         userPermissions.includes(Permission.UpdateCatalog) ||
         userPermissions.includes(Permission.UpdateProduct),
-    isVisible: ({ injector }) => {
-        return injector
-            .get(DataService)
-            .client.userStatus()
-            .mapSingle(({ userStatus }) => 1 < userStatus.channels.length)
-            .toPromise();
-    },
+    isVisible: ({ injector }) => isMultiChannel(injector.get(DataService)),
     onClick: ({ injector, selection, hostComponent, clearSelection }) => {
         const modalService = injector.get(ModalService);
         const dataService = injector.get(DataService);
@@ -118,19 +101,7 @@ export const removeProductsFromChannelBulkAction: BulkAction<SearchProducts.Item
     getTranslationVars: ({ injector }) => getChannelCodeFromUserStatus(injector.get(DataService)),
     icon: 'layers',
     iconClass: 'is-warning',
-    isVisible: ({ injector }) => {
-        return injector
-            .get(DataService)
-            .client.userStatus()
-            .mapSingle(({ userStatus }) => {
-                if (userStatus.channels.length === 1) {
-                    return false;
-                }
-                const defaultChannelId = userStatus.channels.find(c => c.code === DEFAULT_CHANNEL_CODE)?.id;
-                return userStatus.activeChannelId !== defaultChannelId;
-            })
-            .toPromise();
-    },
+    isVisible: ({ injector }) => currentChannelIsNotDefault(injector.get(DataService)),
     onClick: ({ injector, selection, hostComponent, clearSelection }) => {
         const modalService = injector.get(ModalService);
         const dataService = injector.get(DataService);

+ 48 - 0
packages/admin-ui/src/lib/core/src/common/utilities/bulk-action-utils.ts

@@ -0,0 +1,48 @@
+import { DEFAULT_CHANNEL_CODE } from '@vendure/common/lib/shared-constants';
+
+import { DataService } from '../../data/providers/data.service';
+
+/**
+ * @description
+ * Resolves to an object containing the Channel code of the given channelId, or if no channelId
+ * is supplied, the code of the activeChannel.
+ */
+export function getChannelCodeFromUserStatus(dataService: DataService, channelId?: string) {
+    return dataService.client
+        .userStatus()
+        .mapSingle(({ userStatus }) => {
+            const channelCode =
+                userStatus.channels.find(c => c.id === (channelId ?? userStatus.activeChannelId))?.code ??
+                'undefined';
+            return { channelCode };
+        })
+        .toPromise();
+}
+
+/**
+ * @description
+ * Resolves to `true` if multiple Channels are set up.
+ */
+export function isMultiChannel(dataService: DataService) {
+    return dataService.client
+        .userStatus()
+        .mapSingle(({ userStatus }) => 1 < userStatus.channels.length)
+        .toPromise();
+}
+
+/**
+ * @description
+ * Resolves to `true` if the current active Channel is not the default Channel.
+ */
+export function currentChannelIsNotDefault(dataService: DataService) {
+    return dataService.client
+        .userStatus()
+        .mapSingle(({ userStatus }) => {
+            if (userStatus.channels.length === 1) {
+                return false;
+            }
+            const defaultChannelId = userStatus.channels.find(c => c.code === DEFAULT_CHANNEL_CODE)?.id;
+            return userStatus.activeChannelId !== defaultChannelId;
+        })
+        .toPromise();
+}

+ 0 - 13
packages/admin-ui/src/lib/core/src/common/utilities/get-channel-code-from-user-status.ts

@@ -1,13 +0,0 @@
-import { DataService } from '../../data/providers/data.service';
-
-export function getChannelCodeFromUserStatus(dataService: DataService, channelId?: string) {
-    return dataService.client
-        .userStatus()
-        .mapSingle(({ userStatus }) => {
-            const channelCode =
-                userStatus.channels.find(c => c.id === (channelId ?? userStatus.activeChannelId))?.code ??
-                'undefined';
-            return { channelCode };
-        })
-        .toPromise();
-}

BIN
packages/admin-ui/vendure-admin-ui-2.0.0-next.14.tgz


+ 1 - 0
packages/core/vendure-import-error.log

@@ -0,0 +1 @@
+Invalid Record Length: header length is 19, got 1 on line 8

+ 32 - 0
packages/dev-server/test-plugins/custom-scalar-plugin.ts

@@ -0,0 +1,32 @@
+import { CustomScalar, Resolver, Scalar } from '@nestjs/graphql';
+import { VendurePlugin } from '@vendure/core';
+import { Kind, ValueNode } from 'graphql';
+import gql from 'graphql-tag';
+
+@Resolver('MyDate')
+export class DateScalar implements CustomScalar<number, Date> {
+    description = 'Date custom scalar type';
+
+    parseValue(value: number): Date {
+        return new Date(value); // value from the client
+    }
+
+    serialize(value: Date): number {
+        return value.getTime(); // value sent to the client
+    }
+
+    parseLiteral(ast: ValueNode): Date | null {
+        if (ast.kind === Kind.INT) {
+            return new Date(ast.value);
+        }
+        return null;
+    }
+}
+
+@VendurePlugin({
+    providers: [DateScalar],
+    shopApiExtensions: {
+        resolvers: [DateScalar],
+    },
+})
+export class CustomScalarPlugin {}

+ 25 - 0
packages/dev-server/test-plugins/custom-scalars.plugin.ts

@@ -0,0 +1,25 @@
+import { PluginCommonModule, VendurePlugin } from '@vendure/core';
+import { GraphQLScalarType, Kind } from 'graphql';
+import gql from 'graphql-tag';
+
+const FooScalar = new GraphQLScalarType({
+    name: 'FooScalar',
+    description: 'A test scalar',
+    serialize(value) {
+        return value.toString() + '-foo';
+    },
+    parseValue(value) {
+        return value.toString().split('-foo')[0];
+    },
+});
+
+@VendurePlugin({
+    imports: [PluginCommonModule],
+    shopApiExtensions: {
+        schema: gql`
+            scalar FooScalar
+        `,
+        scalars: { FooScalar },
+    },
+})
+export class CustomScalarsPlugin {}

+ 9 - 0
packages/payments-plugin/src/stripe/stripe-order-process.ts

@@ -0,0 +1,9 @@
+import { CustomOrderProcess, OrderState } from '@vendure/core';
+
+const stripeOrderProcess: CustomOrderProcess<never> = {
+    async onTransitionEnd(fromState, toState, data) {
+        if (fromState === 'ArrangingPayment' && toState === 'AddingItems') {
+            data.order;
+        }
+    },
+};