Browse Source

Merge branch 'master' into next

Michael Bromley 5 years ago
parent
commit
000525db70
52 changed files with 698 additions and 122 deletions
  1. 19 0
      CHANGELOG.md
  2. 1 1
      lerna.json
  3. 3 3
      packages/admin-ui-plugin/package.json
  4. 18 18
      packages/admin-ui/i18n-coverage.json
  5. 2 2
      packages/admin-ui/package.json
  6. 45 7
      packages/admin-ui/src/lib/catalog/src/components/product-variants-list/product-variants-list.component.html
  7. 7 0
      packages/admin-ui/src/lib/catalog/src/components/product-variants-list/product-variants-list.component.ts
  8. 21 12
      packages/admin-ui/src/lib/core/src/common/base-list.component.ts
  9. 44 0
      packages/admin-ui/src/lib/core/src/common/generated-types.ts
  10. 1 1
      packages/admin-ui/src/lib/core/src/common/version.ts
  11. 3 0
      packages/admin-ui/src/lib/core/src/components/user-menu/user-menu.component.html
  12. 18 0
      packages/admin-ui/src/lib/core/src/data/definitions/administrator-definitions.ts
  13. 10 0
      packages/admin-ui/src/lib/core/src/data/providers/administrator-data.service.ts
  14. 5 1
      packages/admin-ui/src/lib/core/src/providers/local-storage/local-storage.service.ts
  15. 7 7
      packages/admin-ui/src/lib/login/src/components/login/login.component.html
  16. 38 1
      packages/admin-ui/src/lib/login/src/components/login/login.component.scss
  17. 3 1
      packages/admin-ui/src/lib/order/src/components/order-detail/order-detail.component.ts
  18. 49 20
      packages/admin-ui/src/lib/order/src/components/order-list/order-list.component.ts
  19. 33 0
      packages/admin-ui/src/lib/settings/src/components/profile/profile.component.html
  20. 0 0
      packages/admin-ui/src/lib/settings/src/components/profile/profile.component.scss
  21. 92 0
      packages/admin-ui/src/lib/settings/src/components/profile/profile.component.ts
  22. 30 0
      packages/admin-ui/src/lib/settings/src/providers/routing/profile-resolver.ts
  23. 2 0
      packages/admin-ui/src/lib/settings/src/public_api.ts
  24. 2 0
      packages/admin-ui/src/lib/settings/src/settings.module.ts
  25. 11 0
      packages/admin-ui/src/lib/settings/src/settings.routes.ts
  26. 7 0
      packages/admin-ui/src/lib/static/i18n-messages/cs.json
  27. 7 0
      packages/admin-ui/src/lib/static/i18n-messages/de.json
  28. 7 0
      packages/admin-ui/src/lib/static/i18n-messages/en.json
  29. 7 0
      packages/admin-ui/src/lib/static/i18n-messages/es.json
  30. 7 0
      packages/admin-ui/src/lib/static/i18n-messages/pl.json
  31. 7 0
      packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json
  32. 7 0
      packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json
  33. 7 0
      packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json
  34. 13 0
      packages/asset-server-plugin/e2e/graphql/generated-e2e-asset-server-plugin-types.ts
  35. 3 3
      packages/asset-server-plugin/package.json
  36. 1 1
      packages/common/package.json
  37. 14 0
      packages/common/src/generated-types.ts
  38. 1 1
      packages/core/e2e/__snapshots__/administrator.e2e-spec.ts.snap
  39. 49 16
      packages/core/e2e/administrator.e2e-spec.ts
  40. 27 0
      packages/core/e2e/graphql/generated-e2e-admin-types.ts
  41. 2 2
      packages/core/package.json
  42. 17 0
      packages/core/src/api/resolvers/admin/administrator.resolver.ts
  43. 9 0
      packages/core/src/api/schema/admin-api/administrator.api.graphql
  44. 4 0
      packages/core/src/service/services/administrator.service.ts
  45. 3 3
      packages/create/package.json
  46. 9 9
      packages/dev-server/package.json
  47. 13 0
      packages/elasticsearch-plugin/e2e/graphql/generated-e2e-elasticsearch-plugin-types.ts
  48. 3 3
      packages/elasticsearch-plugin/package.json
  49. 3 3
      packages/email-plugin/package.json
  50. 3 3
      packages/testing/package.json
  51. 4 4
      packages/ui-devkit/package.json
  52. 0 0
      schema-admin.json

+ 19 - 0
CHANGELOG.md

@@ -1,3 +1,22 @@
+## <small>0.17.1 (2020-11-20)</small>
+
+
+#### Features
+
+* **admin-ui** Add "allocated" and "saleable" values to Variant form ([0df7c71](https://github.com/vendure-ecommerce/vendure/commit/0df7c71)), closes [#554](https://github.com/vendure-ecommerce/vendure/issues/554)
+* **admin-ui** Add profile page to edit current admin details ([e183041](https://github.com/vendure-ecommerce/vendure/commit/e183041))
+* **admin-ui** Allow fulfillment when in PartiallyDelivered state ([b36ce38](https://github.com/vendure-ecommerce/vendure/commit/b36ce38)), closes [#565](https://github.com/vendure-ecommerce/vendure/issues/565)
+* **admin-ui** Improved login error message ([2b952aa](https://github.com/vendure-ecommerce/vendure/commit/2b952aa))
+* **admin-ui** Persist custom order filter params in url ([8eb6246](https://github.com/vendure-ecommerce/vendure/commit/8eb6246)), closes [#561](https://github.com/vendure-ecommerce/vendure/issues/561)
+* **admin-ui** Store last used order list filters in localStorage ([7a9ba23](https://github.com/vendure-ecommerce/vendure/commit/7a9ba23)), closes [#561](https://github.com/vendure-ecommerce/vendure/issues/561)
+* **core** Add `activeAdministrator` query to Admin API ([70e14f2](https://github.com/vendure-ecommerce/vendure/commit/70e14f2))
+* **core** Add `updateActiveAdministrator` mutation ([73ab736](https://github.com/vendure-ecommerce/vendure/commit/73ab736))
+
+#### Fixes
+
+* **admin-ui** Add missing Czech translations for new translation tokens ([f2b541f](https://github.com/vendure-ecommerce/vendure/commit/f2b541f))
+* **admin-ui** Refetch customer list on channel change ([078de40](https://github.com/vendure-ecommerce/vendure/commit/078de40))
+
 ## 0.17.0 (2020-11-13)
 
 

+ 1 - 1
lerna.json

@@ -2,7 +2,7 @@
   "packages": [
     "packages/*"
   ],
-  "version": "0.17.0",
+  "version": "0.17.1",
   "npmClient": "yarn",
   "useWorkspaces": true,
   "command": {

+ 3 - 3
packages/admin-ui-plugin/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/admin-ui-plugin",
-  "version": "0.17.0",
+  "version": "0.17.1",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
   "files": [
@@ -19,8 +19,8 @@
   "devDependencies": {
     "@types/express": "^4.17.8",
     "@types/fs-extra": "^9.0.1",
-    "@vendure/common": "^0.17.0",
-    "@vendure/core": "^0.17.0",
+    "@vendure/common": "^0.17.1",
+    "@vendure/core": "^0.17.1",
     "express": "^4.17.1",
     "rimraf": "^3.0.2",
     "typescript": "4.0.3"

+ 18 - 18
packages/admin-ui/i18n-coverage.json

@@ -1,46 +1,46 @@
 {
-  "generatedOn": "2020-11-18T10:02:11.129Z",
-  "lastCommit": "078de4094b9eaa486e8337fc90c575302a91b590",
+  "generatedOn": "2020-11-20T08:36:18.659Z",
+  "lastCommit": "73ab736f93c07f8e4580587ddc7aacd97a5769b2",
   "translationStatus": {
     "cs": {
-      "tokenCount": 688,
-      "translatedCount": 687,
-      "percentage": 100
+      "tokenCount": 695,
+      "translatedCount": 688,
+      "percentage": 99
     },
     "de": {
-      "tokenCount": 688,
+      "tokenCount": 695,
       "translatedCount": 597,
-      "percentage": 87
+      "percentage": 86
     },
     "en": {
-      "tokenCount": 688,
-      "translatedCount": 687,
+      "tokenCount": 695,
+      "translatedCount": 693,
       "percentage": 100
     },
     "es": {
-      "tokenCount": 688,
+      "tokenCount": 695,
       "translatedCount": 455,
-      "percentage": 66
+      "percentage": 65
     },
     "pl": {
-      "tokenCount": 688,
+      "tokenCount": 695,
       "translatedCount": 552,
-      "percentage": 80
+      "percentage": 79
     },
     "pt_BR": {
-      "tokenCount": 688,
+      "tokenCount": 695,
       "translatedCount": 643,
       "percentage": 93
     },
     "zh_Hans": {
-      "tokenCount": 688,
+      "tokenCount": 695,
       "translatedCount": 536,
-      "percentage": 78
+      "percentage": 77
     },
     "zh_Hant": {
-      "tokenCount": 688,
+      "tokenCount": 695,
       "translatedCount": 536,
-      "percentage": 78
+      "percentage": 77
     }
   }
 }

+ 2 - 2
packages/admin-ui/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/admin-ui",
-  "version": "0.17.0",
+  "version": "0.17.1",
   "license": "MIT",
   "scripts": {
     "ng": "ng",
@@ -36,7 +36,7 @@
     "@ng-select/ng-select": "^5.0.3",
     "@ngx-translate/core": "^13.0.0",
     "@ngx-translate/http-loader": "^6.0.0",
-    "@vendure/common": "^0.17.0",
+    "@vendure/common": "^0.17.1",
     "@webcomponents/custom-elements": "^1.2.4",
     "apollo-angular": "^2.0.4",
     "apollo-upload-client": "^12.1.0",

+ 45 - 7
packages/admin-ui/src/lib/catalog/src/components/product-variants-list/product-variants-list.component.html

@@ -67,7 +67,7 @@
                                     <ng-template #taxCategoryLabel>
                                         <label class="clr-control-label">{{
                                             'catalog.tax-category' | translate
-                                            }}</label>
+                                        }}</label>
                                         <div class="tax-category-label">
                                             {{ getTaxCategoryName(formGroup) }}
                                         </div>
@@ -94,7 +94,7 @@
                             <div class="variant-form-input-row">
                                 <clr-select-container *vdrIfPermissions="'UpdateCatalog'">
                                     <label
-                                    >{{ 'catalog.track-inventory' | translate }}
+                                        >{{ 'catalog.track-inventory' | translate }}
                                         <vdr-help-tooltip
                                             [content]="'catalog.track-inventory-tooltip' | translate"
                                         ></vdr-help-tooltip>
@@ -112,7 +112,12 @@
                                     </select>
                                 </clr-select-container>
                                 <clr-input-container>
-                                    <label>{{ 'catalog.stock-on-hand' | translate }}</label>
+                                    <label
+                                        >{{ 'catalog.stock-on-hand' | translate }}
+                                        <vdr-help-tooltip
+                                            [content]="'catalog.stock-on-hand-tooltip' | translate"
+                                        ></vdr-help-tooltip
+                                    ></label>
                                     <input
                                         [class.inventory-untracked]="inventoryIsNotTracked(formGroup)"
                                         clrInput
@@ -124,9 +129,35 @@
                                         [vdrDisabled]="inventoryIsNotTracked(formGroup)"
                                     />
                                 </clr-input-container>
+                                <div [class.inventory-untracked]="inventoryIsNotTracked(formGroup)">
+                                    <label class="clr-control-label"
+                                        >{{ 'catalog.stock-allocated' | translate }}
+                                        <vdr-help-tooltip
+                                            [content]="'catalog.stock-allocated-tooltip' | translate"
+                                        ></vdr-help-tooltip
+                                    ></label>
+                                    <div class="value">
+                                        {{ variant.stockAllocated }}
+                                    </div>
+                                </div>
+                                <div [class.inventory-untracked]="inventoryIsNotTracked(formGroup)">
+                                    <label class="clr-control-label"
+                                        >{{ 'catalog.stock-saleable' | translate }}
+                                        <vdr-help-tooltip
+                                            [content]="'catalog.stock-saleable-tooltip' | translate"
+                                        ></vdr-help-tooltip
+                                    ></label>
+                                    <div class="value">
+                                        {{ getSaleableStockLevel(variant) }}
+                                    </div>
+                                </div>
                             </div>
+
                             <div class="variant-form-input-row">
-                                <div class="out-of-stock-threshold-wrapper" [class.inventory-untracked]="inventoryIsNotTracked(formGroup)">
+                                <div
+                                    class="out-of-stock-threshold-wrapper"
+                                    [class.inventory-untracked]="inventoryIsNotTracked(formGroup)"
+                                >
                                     <label class="clr-control-label"
                                         >{{ 'catalog.out-of-stock-threshold' | translate
                                         }}<vdr-help-tooltip
@@ -142,7 +173,7 @@
                                                 [readonly]="!('UpdateCatalog' | hasPermission)"
                                                 [vdrDisabled]="
                                                     formGroup.get('useGlobalOutOfStockThreshold')?.value !==
-                                                    false || inventoryIsNotTracked(formGroup)
+                                                        false || inventoryIsNotTracked(formGroup)
                                                 "
                                             />
                                         </clr-input-container>
@@ -152,9 +183,16 @@
                                                 clrToggle
                                                 name="useGlobalOutOfStockThreshold"
                                                 formControlName="useGlobalOutOfStockThreshold"
-                                                [vdrDisabled]="!('UpdateCatalog' | hasPermission) || inventoryIsNotTracked(formGroup)"
+                                                [vdrDisabled]="
+                                                    !('UpdateCatalog' | hasPermission) ||
+                                                    inventoryIsNotTracked(formGroup)
+                                                "
                                             />
-                                            <label>{{ 'catalog.use-global-value' | translate }} ({{ globalOutOfStockThreshold }})</label>
+                                            <label
+                                                >{{ 'catalog.use-global-value' | translate }} ({{
+                                                    globalOutOfStockThreshold
+                                                }})</label
+                                            >
                                         </clr-toggle-wrapper>
                                     </div>
                                 </div>

+ 7 - 0
packages/admin-ui/src/lib/catalog/src/components/product-variants-list/product-variants-list.component.ts

@@ -137,6 +137,13 @@ export class ProductVariantsListComponent implements OnChanges, OnInit, OnDestro
         return '';
     }
 
+    getSaleableStockLevel(variant: ProductWithVariants.Variants) {
+        const effectiveOutOfStockThreshold = variant.useGlobalOutOfStockThreshold
+            ? this.globalOutOfStockThreshold
+            : variant.outOfStockThreshold;
+        return variant.stockOnHand - variant.stockAllocated - effectiveOutOfStockThreshold;
+    }
+
     areAllSelected(): boolean {
         return !!this.variants && this.selectedVariantIds.length === this.variants.length;
     }

+ 21 - 12
packages/admin-ui/src/lib/core/src/common/base-list.component.ts

@@ -1,7 +1,7 @@
 import { Directive, OnDestroy, OnInit } from '@angular/core';
-import { ActivatedRoute, Router } from '@angular/router';
+import { ActivatedRoute, QueryParamsHandling, Router } from '@angular/router';
 import { BehaviorSubject, combineLatest, Observable, Subject } from 'rxjs';
-import { map, shareReplay, takeUntil } from 'rxjs/operators';
+import { distinctUntilChanged, map, shareReplay, takeUntil } from 'rxjs/operators';
 
 import { QueryResult } from '../data/query-result';
 
@@ -66,10 +66,12 @@ export class BaseListComponent<ResultType, ItemType, VariableType = any> impleme
         this.currentPage$ = this.route.queryParamMap.pipe(
             map(qpm => qpm.get('page')),
             map(page => (!page ? 1 : +page)),
+            distinctUntilChanged(),
         );
         this.itemsPerPage$ = this.route.queryParamMap.pipe(
             map(qpm => qpm.get('perPage')),
             map(perPage => (!perPage ? 10 : +perPage)),
+            distinctUntilChanged(),
         );
 
         combineLatest(this.currentPage$, this.itemsPerPage$, this.refresh$)
@@ -83,11 +85,11 @@ export class BaseListComponent<ResultType, ItemType, VariableType = any> impleme
     }
 
     setPageNumber(page: number) {
-        this.setQueryParam('page', page, true);
+        this.setQueryParam('page', page, { replaceUrl: true });
     }
 
     setItemsPerPage(perPage: number) {
-        this.setQueryParam('perPage', perPage, true);
+        this.setQueryParam('perPage', perPage, { replaceUrl: true });
     }
 
     /**
@@ -97,20 +99,27 @@ export class BaseListComponent<ResultType, ItemType, VariableType = any> impleme
         this.refresh$.next(undefined);
     }
 
-    protected setQueryParam(hash: { [key: string]: any }, replaceUrl?: boolean);
-    protected setQueryParam(key: string, value: any, replaceUrl?: boolean);
+    protected setQueryParam(
+        hash: { [key: string]: any },
+        options?: { replaceUrl?: boolean; queryParamsHandling?: QueryParamsHandling },
+    );
+    protected setQueryParam(
+        key: string,
+        value: any,
+        options?: { replaceUrl?: boolean; queryParamsHandling?: QueryParamsHandling },
+    );
     protected setQueryParam(
         keyOrHash: string | { [key: string]: any },
-        valueOrReplaceUrl?: any,
-        maybeReplaceUrl?: boolean,
+        valueOrOptions?: any,
+        maybeOptions?: { replaceUrl?: boolean; queryParamsHandling?: QueryParamsHandling },
     ) {
-        const paramsObject = typeof keyOrHash === 'string' ? { [keyOrHash]: valueOrReplaceUrl } : keyOrHash;
-        const replaceUrl = (typeof keyOrHash === 'string' ? maybeReplaceUrl : valueOrReplaceUrl) ?? false;
+        const paramsObject = typeof keyOrHash === 'string' ? { [keyOrHash]: valueOrOptions } : keyOrHash;
+        const options = (typeof keyOrHash === 'string' ? maybeOptions : valueOrOptions) ?? {};
         this.router.navigate(['./'], {
-            queryParams: typeof keyOrHash === 'string' ? { [keyOrHash]: valueOrReplaceUrl } : keyOrHash,
+            queryParams: typeof keyOrHash === 'string' ? { [keyOrHash]: valueOrOptions } : keyOrHash,
             relativeTo: this.route,
             queryParamsHandling: 'merge',
-            replaceUrl,
+            ...options,
         });
     }
 }

+ 44 - 0
packages/admin-ui/src/lib/core/src/common/generated-types.ts

@@ -409,6 +409,8 @@ export type Mutation = {
   settleRefund: SettleRefundResult;
   transitionFulfillmentToState: TransitionFulfillmentToStateResult;
   transitionOrderToState?: Maybe<TransitionOrderToStateResult>;
+  /** Update the active (currently logged-in) Administrator */
+  updateActiveAdministrator: Administrator;
   /** Update an existing Administrator */
   updateAdministrator: Administrator;
   /** Update an existing Asset */
@@ -816,6 +818,11 @@ export type MutationTransitionOrderToStateArgs = {
 };
 
 
+export type MutationUpdateActiveAdministratorArgs = {
+  input: UpdateActiveAdministratorInput;
+};
+
+
 export type MutationUpdateAdministratorArgs = {
   input: UpdateAdministratorInput;
 };
@@ -957,6 +964,13 @@ export type UpdateAdministratorInput = {
   roleIds?: Maybe<Array<Scalars['ID']>>;
 };
 
+export type UpdateActiveAdministratorInput = {
+  firstName?: Maybe<Scalars['String']>;
+  lastName?: Maybe<Scalars['String']>;
+  emailAddress?: Maybe<Scalars['String']>;
+  password?: Maybe<Scalars['String']>;
+};
+
 export type MimeTypeError = ErrorResult & {
   __typename?: 'MimeTypeError';
   errorCode: ErrorCode;
@@ -4336,6 +4350,14 @@ export type GetAdministratorsQuery = { administrators: (
     )> }
   ) };
 
+export type GetActiveAdministratorQueryVariables = Exact<{ [key: string]: never; }>;
+
+
+export type GetActiveAdministratorQuery = { activeAdministrator?: Maybe<(
+    { __typename?: 'Administrator' }
+    & AdministratorFragment
+  )> };
+
 export type GetAdministratorQueryVariables = Exact<{
   id: Scalars['ID'];
 }>;
@@ -4366,6 +4388,16 @@ export type UpdateAdministratorMutation = { updateAdministrator: (
     & AdministratorFragment
   ) };
 
+export type UpdateActiveAdministratorMutationVariables = Exact<{
+  input: UpdateActiveAdministratorInput;
+}>;
+
+
+export type UpdateActiveAdministratorMutation = { updateActiveAdministrator: (
+    { __typename?: 'Administrator' }
+    & AdministratorFragment
+  ) };
+
 export type DeleteAdministratorMutationVariables = Exact<{
   id: Scalars['ID'];
 }>;
@@ -7177,6 +7209,12 @@ export namespace GetAdministrators {
   export type Items = NonNullable<(NonNullable<(NonNullable<GetAdministratorsQuery['administrators']>)['items']>)[number]>;
 }
 
+export namespace GetActiveAdministrator {
+  export type Variables = GetActiveAdministratorQueryVariables;
+  export type Query = GetActiveAdministratorQuery;
+  export type ActiveAdministrator = (NonNullable<GetActiveAdministratorQuery['activeAdministrator']>);
+}
+
 export namespace GetAdministrator {
   export type Variables = GetAdministratorQueryVariables;
   export type Query = GetAdministratorQuery;
@@ -7195,6 +7233,12 @@ export namespace UpdateAdministrator {
   export type UpdateAdministrator = (NonNullable<UpdateAdministratorMutation['updateAdministrator']>);
 }
 
+export namespace UpdateActiveAdministrator {
+  export type Variables = UpdateActiveAdministratorMutationVariables;
+  export type Mutation = UpdateActiveAdministratorMutation;
+  export type UpdateActiveAdministrator = (NonNullable<UpdateActiveAdministratorMutation['updateActiveAdministrator']>);
+}
+
 export namespace DeleteAdministrator {
   export type Variables = DeleteAdministratorMutationVariables;
   export type Mutation = DeleteAdministratorMutation;

+ 1 - 1
packages/admin-ui/src/lib/core/src/common/version.ts

@@ -1,2 +1,2 @@
 // Auto-generated by the set-version.js script.
-export const ADMIN_UI_VERSION = '0.17.0';
+export const ADMIN_UI_VERSION = '0.17.1';

+ 3 - 0
packages/admin-ui/src/lib/core/src/components/user-menu/user-menu.component.html

@@ -5,6 +5,9 @@
         <clr-icon shape="caret down"></clr-icon>
     </button>
     <vdr-dropdown-menu vdrPosition="bottom-right">
+        <a [routerLink]="['/settings', 'profile']" vdrDropdownItem>
+            <clr-icon shape="user" class="is-solid"></clr-icon> {{ 'settings.profile' | translate }}
+        </a>
         <ng-container *ngIf="1 < availableLanguages.length">
             <button
                 type="button"

+ 18 - 0
packages/admin-ui/src/lib/core/src/data/definitions/administrator-definitions.ts

@@ -57,6 +57,15 @@ export const GET_ADMINISTRATORS = gql`
     ${ADMINISTRATOR_FRAGMENT}
 `;
 
+export const GET_ACTIVE_ADMINISTRATOR = gql`
+    query GetActiveAdministrator {
+        activeAdministrator {
+            ...Administrator
+        }
+    }
+    ${ADMINISTRATOR_FRAGMENT}
+`;
+
 export const GET_ADMINISTRATOR = gql`
     query GetAdministrator($id: ID!) {
         administrator(id: $id) {
@@ -84,6 +93,15 @@ export const UPDATE_ADMINISTRATOR = gql`
     ${ADMINISTRATOR_FRAGMENT}
 `;
 
+export const UPDATE_ACTIVE_ADMINISTRATOR = gql`
+    mutation UpdateActiveAdministrator($input: UpdateActiveAdministratorInput!) {
+        updateActiveAdministrator(input: $input) {
+            ...Administrator
+        }
+    }
+    ${ADMINISTRATOR_FRAGMENT}
+`;
+
 export const DELETE_ADMINISTRATOR = gql`
     mutation DeleteAdministrator($id: ID!) {
         deleteAdministrator(id: $id) {

+ 10 - 0
packages/admin-ui/src/lib/core/src/data/providers/administrator-data.service.ts

@@ -12,6 +12,8 @@ import {
     GetAdministrators,
     GetRole,
     GetRoles,
+    UpdateActiveAdministrator,
+    UpdateActiveAdministratorInput,
     UpdateAdministrator,
     UpdateAdministratorInput,
     UpdateRole,
@@ -27,6 +29,7 @@ import {
     GET_ADMINISTRATORS,
     GET_ROLE,
     GET_ROLES,
+    UPDATE_ACTIVE_ADMINISTRATOR,
     UPDATE_ADMINISTRATOR,
     UPDATE_ROLE,
 } from '../definitions/administrator-definitions';
@@ -79,6 +82,13 @@ export class AdministratorDataService {
         );
     }
 
+    updateActiveAdministrator(input: UpdateActiveAdministratorInput) {
+        return this.baseDataService.mutate<
+            UpdateActiveAdministrator.Mutation,
+            UpdateActiveAdministrator.Variables
+        >(UPDATE_ACTIVE_ADMINISTRATOR, { input });
+    }
+
     deleteAdministrator(id: string) {
         return this.baseDataService.mutate<DeleteAdministrator.Mutation, DeleteAdministrator.Variables>(
             DELETE_ADMINISTRATOR,

+ 5 - 1
packages/admin-ui/src/lib/core/src/providers/local-storage/local-storage.service.ts

@@ -1,7 +1,11 @@
 import { Location } from '@angular/common';
 import { Injectable } from '@angular/core';
 
-export type LocalStorageKey = 'activeChannelToken' | 'authToken' | 'uiLanguageCode';
+export type LocalStorageKey =
+    | 'activeChannelToken'
+    | 'authToken'
+    | 'uiLanguageCode'
+    | 'orderListLastCustomFilters';
 export type LocalStorageLocationBasedKey = 'shippingTestOrder' | 'shippingTestAddress';
 const PREFIX = 'vnd_';
 

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

@@ -18,6 +18,13 @@
                 [(ngModel)]="password"
                 [placeholder]="'common.password' | translate"
             />
+            <clr-alert [clrAlertType]="'danger'"  [clrAlertClosable]="false" [class.visible]="errorMessage" class="login-error">
+                <clr-alert-item>
+                    <span class="alert-text">
+                        {{ errorMessage }}
+                    </span>
+                </clr-alert-item>
+            </clr-alert>
             <clr-checkbox-wrapper>
                 <input
                     type="checkbox"
@@ -36,13 +43,6 @@
             >
                 {{ 'common.login' | translate }}
             </button>
-            <clr-alert [clrAlertType]="'danger'" *ngIf="errorMessage">
-                <clr-alert-item>
-                    <span class="alert-text">
-                        {{ errorMessage }}
-                    </span>
-                </clr-alert-item>
-            </clr-alert>
         </div>
         <div class="version">vendure {{ version }}</div>
     </form>

+ 38 - 1
packages/admin-ui/src/lib/login/src/components/login/login.component.scss

@@ -1,4 +1,4 @@
-@import "variables";
+@import 'variables';
 
 .login-wrapper {
     background-image: url(data:image/gif;base64,R0lGODlhFAAhAKIAABwcHBsbGxcXFx0dHRUVFRkZGR4eHhQUFCH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4zLWMwMTEgNjYuMTQ2NzI5LCAyMDEyLzA1LzAzLTEzOjQwOjAzICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgRWxlbWVudHMgMTIuMCBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjhBOTg1NDlCNjMwNDExRUFBNEUwQ0M2RDdENUQ3RTBFIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjhBOTg1NDlDNjMwNDExRUFBNEUwQ0M2RDdENUQ3RTBFIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OEE5ODU0OTk2MzA0MTFFQUE0RTBDQzZEN0Q1RDdFMEUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OEE5ODU0OUE2MzA0MTFFQUE0RTBDQzZEN0Q1RDdFMEUiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4B//79/Pv6+fj39vX08/Lx8O/u7ezr6uno5+bl5OPi4eDf3t3c29rZ2NfW1dTT0tHQz87NzMvKycjHxsXEw8LBwL++vby7urm4t7a1tLOysbCvrq2sq6qpqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+OjYyLiomIh4aFhIOCgYB/fn18e3p5eHd2dXRzcnFwb25tbGtqaWhnZmVkY2JhYF9eXVxbWllYV1ZVVFNSUVBPTk1MS0pJSEdGRURDQkFAPz49PDs6OTg3NjU0MzIxMC8uLSwrKikoJyYlJCMiISAfHh0cGxoZGBcWFRQTEhEQDw4NDAsKCQgHBgUEAwIBAAAh+QQAAAAAACwAAAAAFAAhAAADfSi23M7igEcZOIfUSvApm1N42RAuQ0cqZ0Ri0xa8nlaltAdSY44RJsfAt3q4iLDGDFlj4Ji6RQ/6GwypqyOtwO12BQKv+EawnRq93dlwLa0NWtZpSYptniRzZfpSP9o0QBVaNHJKUHYoKkh6BnxIaoBMgnBYGAp0lgCLlgQJADs=);
@@ -18,3 +18,40 @@
     justify-content: center;
     color: $color-grey-300;
 }
+
+.login-error {
+    max-height: 0;
+    overflow: hidden;
+    &.visible {
+        max-height: 46px;
+        transition: max-height 0.2s;
+        animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
+        animation-delay: 0.2s;
+        transform: translate3d(0, 0, 0);
+        backface-visibility: hidden;
+        perspective: 1000px;
+    }
+}
+
+@keyframes shake {
+    10%,
+    90% {
+        transform: translate3d(-1px, 0, 0);
+    }
+
+    20%,
+    80% {
+        transform: translate3d(2px, 0, 0);
+    }
+
+    30%,
+    50%,
+    70% {
+        transform: translate3d(-4px, 0, 0);
+    }
+
+    40%,
+    60% {
+        transform: translate3d(4px, 0, 0);
+    }
+}

+ 3 - 1
packages/admin-ui/src/lib/order/src/components/order-detail/order-detail.component.ts

@@ -204,7 +204,9 @@ export class OrderDetailComponent
             .every(item => !!item.fulfillment);
         return (
             !allItemsFulfilled &&
-            (order.nextStates.includes('Shipped') || order.nextStates.includes('PartiallyShipped'))
+            (order.nextStates.includes('Shipped') ||
+                order.nextStates.includes('PartiallyShipped') ||
+                order.nextStates.includes('Delivered'))
         );
     }
 

+ 49 - 20
packages/admin-ui/src/lib/order/src/components/order-list/order-list.component.ts

@@ -6,11 +6,12 @@ import {
     BaseListComponent,
     DataService,
     GetOrderList,
+    LocalStorageService,
     ServerConfigService,
     SortOrder,
 } from '@vendure/admin-ui/core';
 import { merge, Observable } from 'rxjs';
-import { debounceTime, distinctUntilChanged, map, skip, takeUntil } from 'rxjs/operators';
+import { debounceTime, distinctUntilChanged, map, skip, takeUntil, tap } from 'rxjs/operators';
 
 interface OrderFilterConfig {
     active?: boolean;
@@ -41,7 +42,9 @@ export class OrderListComponent
             label: _('order.filter-preset-open'),
             config: {
                 active: false,
-                states: this.orderStates.filter(s => s !== 'Delivered' && s !== 'Cancelled' && s !== 'Shipped'),
+                states: this.orderStates.filter(
+                    s => s !== 'Delivered' && s !== 'Cancelled' && s !== 'Shipped',
+                ),
             },
         },
         {
@@ -73,6 +76,7 @@ export class OrderListComponent
     constructor(
         private serverConfigService: ServerConfigService,
         private dataService: DataService,
+        private localStorageService: LocalStorageService,
         router: Router,
         route: ActivatedRoute,
     ) {
@@ -90,6 +94,10 @@ export class OrderListComponent
                     this.route.snapshot.queryParamMap.get('filter') || 'open',
                 ),
         );
+        const lastFilters = this.localStorageService.get('orderListLastCustomFilters');
+        if (lastFilters) {
+            this.setQueryParam(lastFilters, { replaceUrl: true });
+        }
     }
 
     ngOnInit() {
@@ -98,29 +106,47 @@ export class OrderListComponent
             map(qpm => qpm.get('filter') || 'open'),
             distinctUntilChanged(),
         );
-        merge(this.searchTerm.valueChanges, this.activePreset$.pipe(skip(1)))
-            .pipe(debounceTime(250), takeUntil(this.destroy$))
-            .subscribe(() => this.refresh());
+        merge(this.searchTerm.valueChanges.pipe(debounceTime(250)), this.route.queryParamMap)
+            .pipe(takeUntil(this.destroy$))
+            .subscribe(val => {
+                this.refresh();
+            });
+
+        const queryParamMap = this.route.snapshot.queryParamMap;
         this.customFilterForm = new FormGroup({
-            states: new FormControl([]),
-            placedAtStart: new FormControl(),
-            placedAtEnd: new FormControl(),
+            states: new FormControl(queryParamMap.getAll('states') ?? []),
+            placedAtStart: new FormControl(queryParamMap.get('placedAtStart')),
+            placedAtEnd: new FormControl(queryParamMap.get('placedAtEnd')),
         });
     }
 
     selectFilterPreset(presetName: string) {
+        const lastCustomFilters = this.localStorageService.get('orderListLastCustomFilters') ?? {};
+        const emptyCustomFilters = { states: undefined, placedAtStart: undefined, placedAtEnd: undefined };
+        const filters = presetName === 'custom' ? lastCustomFilters : emptyCustomFilters;
         this.setQueryParam(
             {
                 filter: presetName,
                 page: 1,
+                ...filters,
             },
-            true,
+            { replaceUrl: true },
         );
     }
 
     applyCustomFilters() {
+        const formValue = this.customFilterForm.value;
+        const customFilters = {
+            states: formValue.states,
+            placedAtStart: formValue.placedAtStart,
+            placedAtEnd: formValue.placedAtEnd,
+        };
+        this.setQueryParam({
+            filter: 'custom',
+            ...customFilters,
+        });
         this.customFilterForm.markAsPristine();
-        this.refresh();
+        this.localStorageService.set('orderListLastCustomFilters', customFilters);
     }
 
     // tslint:disable-next-line:no-shadowed-variable
@@ -139,26 +165,29 @@ export class OrderListComponent
                 };
             }
         } else if (activeFilterPreset === 'custom') {
-            const formValue = this.customFilterForm?.value ?? {};
-            if (formValue.states?.length) {
+            const queryParams = this.route.snapshot.queryParamMap;
+            const states = queryParams.getAll('states') ?? [];
+            const placedAtStart = queryParams.get('placedAtStart');
+            const placedAtEnd = queryParams.get('placedAtEnd');
+            if (states.length) {
                 filter.state = {
-                    in: formValue.states,
+                    in: states,
                 };
             }
-            if (formValue.placedAtStart && formValue.placedAtEnd) {
+            if (placedAtStart && placedAtEnd) {
                 filter.orderPlacedAt = {
                     between: {
-                        start: formValue.placedAtStart,
-                        end: formValue.placedAtEnd,
+                        start: placedAtStart,
+                        end: placedAtEnd,
                     },
                 };
-            } else if (formValue.placedAtStart) {
+            } else if (placedAtStart) {
                 filter.orderPlacedAt = {
-                    after: formValue.placedAtStart,
+                    after: placedAtStart,
                 };
-            } else if (formValue.placedAtEnd) {
+            } else if (placedAtEnd) {
                 filter.orderPlacedAt = {
-                    before: formValue.placedAtEnd,
+                    before: placedAtEnd,
                 };
             }
         }

+ 33 - 0
packages/admin-ui/src/lib/settings/src/components/profile/profile.component.html

@@ -0,0 +1,33 @@
+<vdr-action-bar>
+    <vdr-ab-left>
+        <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
+    </vdr-ab-left>
+    <vdr-ab-right>
+        <vdr-action-bar-items locationId="administrator-detail"></vdr-action-bar-items>
+        <button
+            class="btn btn-primary"
+            (click)="save()"
+            [disabled]="detailForm.invalid || detailForm.pristine"
+        >
+            {{ 'common.update' | translate }}
+        </button>
+    </vdr-ab-right>
+</vdr-action-bar>
+
+<form class="form" [formGroup]="detailForm">
+    <vdr-form-field [label]="'settings.email-address' | translate" for="emailAddress">
+        <input id="emailAddress" type="text" formControlName="emailAddress" />
+    </vdr-form-field>
+    <vdr-form-field [label]="'settings.first-name' | translate" for="firstName">
+        <input id="firstName" type="text" formControlName="firstName" />
+    </vdr-form-field>
+    <vdr-form-field [label]="'settings.last-name' | translate" for="lastName">
+        <input id="lastName" type="text" formControlName="lastName" />
+    </vdr-form-field>
+    <vdr-form-field *ngIf="isNew$ | async" [label]="'settings.password' | translate" for="password">
+        <input id="password" type="password" formControlName="password" />
+    </vdr-form-field>
+    <vdr-form-field [label]="'settings.password' | translate" for="password" [readOnlyToggle]="true">
+        <input id="password" type="password" formControlName="password" />
+    </vdr-form-field>
+</form>

+ 0 - 0
packages/admin-ui/src/lib/settings/src/components/profile/profile.component.scss


+ 92 - 0
packages/admin-ui/src/lib/settings/src/components/profile/profile.component.ts

@@ -0,0 +1,92 @@
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { ActivatedRoute, Router } from '@angular/router';
+import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
+import {
+    Administrator,
+    BaseDetailComponent,
+    DataService,
+    GetActiveAdministrator,
+    LanguageCode,
+    NotificationService,
+    ServerConfigService,
+    UpdateActiveAdministratorInput,
+} from '@vendure/admin-ui/core';
+import { mergeMap, take } from 'rxjs/operators';
+
+@Component({
+    selector: 'vdr-profile',
+    templateUrl: './profile.component.html',
+    styleUrls: ['./profile.component.scss'],
+    changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class ProfileComponent
+    extends BaseDetailComponent<GetActiveAdministrator.ActiveAdministrator>
+    implements OnInit, OnDestroy {
+    detailForm: FormGroup;
+
+    constructor(
+        router: Router,
+        route: ActivatedRoute,
+        serverConfigService: ServerConfigService,
+        private changeDetector: ChangeDetectorRef,
+        protected dataService: DataService,
+        private formBuilder: FormBuilder,
+        private notificationService: NotificationService,
+    ) {
+        super(route, router, serverConfigService, dataService);
+        this.detailForm = this.formBuilder.group({
+            emailAddress: ['', Validators.required],
+            firstName: ['', Validators.required],
+            lastName: ['', Validators.required],
+            password: [''],
+        });
+    }
+
+    ngOnInit() {
+        this.init();
+    }
+
+    ngOnDestroy(): void {
+        this.destroy();
+    }
+
+    save() {
+        this.entity$
+            .pipe(
+                take(1),
+                mergeMap(({ id }) => {
+                    const formValue = this.detailForm.value;
+                    const administrator: UpdateActiveAdministratorInput = {
+                        emailAddress: formValue.emailAddress,
+                        firstName: formValue.firstName,
+                        lastName: formValue.lastName,
+                        password: formValue.password,
+                    };
+                    return this.dataService.administrator.updateActiveAdministrator(administrator);
+                }),
+            )
+            .subscribe(
+                data => {
+                    this.notificationService.success(_('common.notify-update-success'), {
+                        entity: 'Administrator',
+                    });
+                    this.detailForm.markAsPristine();
+                    this.changeDetector.markForCheck();
+                },
+                err => {
+                    this.notificationService.error(_('common.notify-update-error'), {
+                        entity: 'Administrator',
+                    });
+                },
+            );
+    }
+
+    protected setFormValues(administrator: Administrator, languageCode: LanguageCode): void {
+        this.detailForm.patchValue({
+            emailAddress: administrator.emailAddress,
+            firstName: administrator.firstName,
+            lastName: administrator.lastName,
+        });
+    }
+}

+ 30 - 0
packages/admin-ui/src/lib/settings/src/providers/routing/profile-resolver.ts

@@ -0,0 +1,30 @@
+import { Injectable } from '@angular/core';
+import { Router } from '@angular/router';
+import { BaseEntityResolver } from '@vendure/admin-ui/core';
+import { Administrator, Role } from '@vendure/admin-ui/core';
+import { DataService } from '@vendure/admin-ui/core';
+
+@Injectable({
+    providedIn: 'root',
+})
+export class ProfileResolver extends BaseEntityResolver<Administrator.Fragment> {
+    constructor(router: Router, dataService: DataService) {
+        super(
+            router,
+            {
+                __typename: 'Administrator' as 'Administrator',
+                id: '',
+                createdAt: '',
+                updatedAt: '',
+                emailAddress: '',
+                firstName: '',
+                lastName: '',
+                user: { roles: [] } as any,
+            },
+            id =>
+                dataService.administrator
+                    .getActiveAdministrator()
+                    .mapStream(data => data.activeAdministrator),
+        );
+    }
+}

+ 2 - 0
packages/admin-ui/src/lib/settings/src/public_api.ts

@@ -10,6 +10,7 @@ export * from './components/global-settings/global-settings.component';
 export * from './components/payment-method-detail/payment-method-detail.component';
 export * from './components/payment-method-list/payment-method-list.component';
 export * from './components/permission-grid/permission-grid.component';
+export * from './components/profile/profile.component';
 export * from './components/role-detail/role-detail.component';
 export * from './components/role-list/role-list.component';
 export * from './components/shipping-eligibility-test-result/shipping-eligibility-test-result.component';
@@ -32,6 +33,7 @@ export * from './providers/routing/channel-resolver';
 export * from './providers/routing/country-resolver';
 export * from './providers/routing/global-settings-resolver';
 export * from './providers/routing/payment-method-resolver';
+export * from './providers/routing/profile-resolver';
 export * from './providers/routing/role-resolver';
 export * from './providers/routing/shipping-method-resolver';
 export * from './providers/routing/tax-category-resolver';

+ 2 - 0
packages/admin-ui/src/lib/settings/src/settings.module.ts

@@ -13,6 +13,7 @@ import { GlobalSettingsComponent } from './components/global-settings/global-set
 import { PaymentMethodDetailComponent } from './components/payment-method-detail/payment-method-detail.component';
 import { PaymentMethodListComponent } from './components/payment-method-list/payment-method-list.component';
 import { PermissionGridComponent } from './components/permission-grid/permission-grid.component';
+import { ProfileComponent } from './components/profile/profile.component';
 import { RoleDetailComponent } from './components/role-detail/role-detail.component';
 import { RoleListComponent } from './components/role-list/role-list.component';
 import { ShippingEligibilityTestResultComponent } from './components/shipping-eligibility-test-result/shipping-eligibility-test-result.component';
@@ -63,6 +64,7 @@ import { settingsRoutes } from './settings.routes';
         ZoneMemberListHeaderDirective,
         ZoneMemberControlsDirective,
         ZoneDetailDialogComponent,
+        ProfileComponent,
     ],
 })
 export class SettingsModule {}

+ 11 - 0
packages/admin-ui/src/lib/settings/src/settings.routes.ts

@@ -22,6 +22,7 @@ import { CountryListComponent } from './components/country-list/country-list.com
 import { GlobalSettingsComponent } from './components/global-settings/global-settings.component';
 import { PaymentMethodDetailComponent } from './components/payment-method-detail/payment-method-detail.component';
 import { PaymentMethodListComponent } from './components/payment-method-list/payment-method-list.component';
+import { ProfileComponent } from './components/profile/profile.component';
 import { RoleDetailComponent } from './components/role-detail/role-detail.component';
 import { RoleListComponent } from './components/role-list/role-list.component';
 import { ShippingMethodDetailComponent } from './components/shipping-method-detail/shipping-method-detail.component';
@@ -36,12 +37,22 @@ import { ChannelResolver } from './providers/routing/channel-resolver';
 import { CountryResolver } from './providers/routing/country-resolver';
 import { GlobalSettingsResolver } from './providers/routing/global-settings-resolver';
 import { PaymentMethodResolver } from './providers/routing/payment-method-resolver';
+import { ProfileResolver } from './providers/routing/profile-resolver';
 import { RoleResolver } from './providers/routing/role-resolver';
 import { ShippingMethodResolver } from './providers/routing/shipping-method-resolver';
 import { TaxCategoryResolver } from './providers/routing/tax-category-resolver';
 import { TaxRateResolver } from './providers/routing/tax-rate-resolver';
 
 export const settingsRoutes: Route[] = [
+    {
+        path: 'profile',
+        component: ProfileComponent,
+        resolve: createResolveData(ProfileResolver),
+        canDeactivate: [CanDeactivateDetailGuard],
+        data: {
+            breadcrumb: _('breadcrumb.profile'),
+        },
+    },
     {
         path: 'administrators',
         component: AdministratorListComponent,

+ 7 - 0
packages/admin-ui/src/lib/static/i18n-messages/cs.json

@@ -40,6 +40,7 @@
     "orders": "Objednávky",
     "payment-methods": "Platební metody",
     "products": "Produkty",
+    "profile": "",
     "promotions": "Propagace",
     "roles": "Role",
     "shipping-methods": "Dopravní metody",
@@ -125,7 +126,12 @@
     "sku": "SKU",
     "slug": "Odkaz",
     "slug-pattern-error": "Špatný formát odkazu",
+    "stock-allocated": "",
+    "stock-allocated-tooltip": "",
     "stock-on-hand": "Sklad",
+    "stock-on-hand-tooltip": "",
+    "stock-saleable": "",
+    "stock-saleable-tooltip": "",
     "tax-category": "Skupina daní",
     "taxes": "Daně",
     "track-inventory": "Dopočítávat sklad",
@@ -667,6 +673,7 @@
     "payment-method-config-options": "Konfigurace platební metody",
     "permissions": "Oprávnění",
     "prices-include-tax": "Zadávané ceny jsou včetně daně pro výchozí zónu",
+    "profile": "",
     "rate": "Sazba",
     "remove-countries-from-zone-success": "Odebráno: { countryCount } {countryCount, plural, one {země} other {země}} ze zóny \"{ zoneName }\"",
     "remove-from-zone": "Odebrat ze zóny",

+ 7 - 0
packages/admin-ui/src/lib/static/i18n-messages/de.json

@@ -40,6 +40,7 @@
     "orders": "Bestellungen",
     "payment-methods": "Zahlungsarten",
     "products": "Produkte",
+    "profile": "",
     "promotions": "Promotionen",
     "roles": "Rollen",
     "shipping-methods": "Versandarten",
@@ -125,7 +126,12 @@
     "sku": "Artikelnummer",
     "slug": "Slug",
     "slug-pattern-error": "",
+    "stock-allocated": "",
+    "stock-allocated-tooltip": "",
     "stock-on-hand": "Bestand",
+    "stock-on-hand-tooltip": "",
+    "stock-saleable": "",
+    "stock-saleable-tooltip": "",
     "tax-category": "Steuerkategorie",
     "taxes": "Steuern",
     "track-inventory": "Bestand verfolgen",
@@ -667,6 +673,7 @@
     "payment-method-config-options": "Konfiguration der Zahlungsart",
     "permissions": "Berechtigungen",
     "prices-include-tax": "Preise enthalten die Steuer für die Standardzone",
+    "profile": "",
     "rate": "Steuersatz",
     "remove-countries-from-zone-success": "{ countryCount } {countryCount, plural, one {Land} other {Länder}} entfernt aus \"{ zoneName }\"",
     "remove-from-zone": "Aus Zone entfernen",

+ 7 - 0
packages/admin-ui/src/lib/static/i18n-messages/en.json

@@ -40,6 +40,7 @@
     "orders": "Orders",
     "payment-methods": "Payment methods",
     "products": "Products",
+    "profile": "Profile",
     "promotions": "Promotions",
     "roles": "Roles",
     "shipping-methods": "Shipping methods",
@@ -125,7 +126,12 @@
     "sku": "SKU",
     "slug": "Slug",
     "slug-pattern-error": "Slug is invalid",
+    "stock-allocated": "Allocated",
+    "stock-allocated-tooltip": "The number of units allocated to Orders which have checked out but not yet been fulfilled",
     "stock-on-hand": "Stock",
+    "stock-on-hand-tooltip": "Stock on hand - the number of physical units available in stock",
+    "stock-saleable": "Saleable",
+    "stock-saleable-tooltip": "The number of saleable units, comprising the stock on hand - allocated, taking into account the out-of-stock threshold",
     "tax-category": "Tax category",
     "taxes": "Taxes",
     "track-inventory": "Track inventory",
@@ -667,6 +673,7 @@
     "payment-method-config-options": "Payment method configuration",
     "permissions": "Permissions",
     "prices-include-tax": "Prices include tax for the default Zone",
+    "profile": "Profile",
     "rate": "Rate",
     "remove-countries-from-zone-success": "Removed { countryCount } {countryCount, plural, one {country} other {countries}} from zone \"{ zoneName }\"",
     "remove-from-zone": "Remove from zone",

+ 7 - 0
packages/admin-ui/src/lib/static/i18n-messages/es.json

@@ -40,6 +40,7 @@
     "orders": "Pedidos",
     "payment-methods": "Métodos de pago",
     "products": "Productos",
+    "profile": "",
     "promotions": "Promociones",
     "roles": "Roles",
     "shipping-methods": "Métodos de envío",
@@ -125,7 +126,12 @@
     "sku": "SKU",
     "slug": "Slug",
     "slug-pattern-error": "",
+    "stock-allocated": "",
+    "stock-allocated-tooltip": "",
     "stock-on-hand": "Inventario disponible",
+    "stock-on-hand-tooltip": "",
+    "stock-saleable": "",
+    "stock-saleable-tooltip": "",
     "tax-category": "Categoría de impuestos",
     "taxes": "Impuestos",
     "track-inventory": "",
@@ -667,6 +673,7 @@
     "payment-method-config-options": "Configuración método de pago",
     "permissions": "Permisos",
     "prices-include-tax": "Los precios incluyen impuestos para la zona por defecto.",
+    "profile": "",
     "rate": "Tasa",
     "remove-countries-from-zone-success": "Eliminados { countryCount } {countryCount, plural, one {país} other {países}} de la zona \"{ zoneName }\"",
     "remove-from-zone": "Eliminar de la zona",

+ 7 - 0
packages/admin-ui/src/lib/static/i18n-messages/pl.json

@@ -40,6 +40,7 @@
     "orders": "Zamówienia",
     "payment-methods": "Metody płatności",
     "products": "Produkty",
+    "profile": "",
     "promotions": "Promocje",
     "roles": "Role",
     "shipping-methods": "Metody wysyłki",
@@ -125,7 +126,12 @@
     "sku": "SKU",
     "slug": "Slug",
     "slug-pattern-error": "",
+    "stock-allocated": "",
+    "stock-allocated-tooltip": "",
     "stock-on-hand": "Stan magazynowy",
+    "stock-on-hand-tooltip": "",
+    "stock-saleable": "",
+    "stock-saleable-tooltip": "",
     "tax-category": "Kategoria podatkowa",
     "taxes": "Podatki",
     "track-inventory": "Śledź magazyn",
@@ -667,6 +673,7 @@
     "payment-method-config-options": "Konfiguracja metody płatności",
     "permissions": "Uprawnienia",
     "prices-include-tax": "Ceny zawierają podatek dla domyślnej strefy",
+    "profile": "",
     "rate": "Stawka",
     "remove-countries-from-zone-success": "Usunięto { countryCount } {countryCount, plural, one {kraj} other {kraje}} ze strefy \"{ zoneName }\"",
     "remove-from-zone": "",

+ 7 - 0
packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json

@@ -40,6 +40,7 @@
     "orders": "Pedidos",
     "payment-methods": "Métodos de pagamentos",
     "products": "Produtos",
+    "profile": "",
     "promotions": "Promoções",
     "roles": "Regras",
     "shipping-methods": "Métodos de envio",
@@ -125,7 +126,12 @@
     "sku": "SKU",
     "slug": "Slug",
     "slug-pattern-error": "",
+    "stock-allocated": "",
+    "stock-allocated-tooltip": "",
     "stock-on-hand": "Estoque",
+    "stock-on-hand-tooltip": "",
+    "stock-saleable": "",
+    "stock-saleable-tooltip": "",
     "tax-category": "Categoria de impostos",
     "taxes": "Impostos",
     "track-inventory": "Rastrear inventário",
@@ -667,6 +673,7 @@
     "payment-method-config-options": "Configuração do método de pagamento",
     "permissions": "Permissões",
     "prices-include-tax": "Os preços incluem impostos para a Zona padrão",
+    "profile": "",
     "rate": "Taxa",
     "remove-countries-from-zone-success": "Excluído { countryCount } {countryCount, plural, one {country} other {countries}} da zona \"{ zoneName }\"",
     "remove-from-zone": "Excluir da zona",

+ 7 - 0
packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json

@@ -40,6 +40,7 @@
     "orders": "订单管理",
     "payment-methods": "支付管理",
     "products": "商品列表",
+    "profile": "",
     "promotions": "优惠券管理",
     "roles": "角色管理",
     "shipping-methods": "配送方式管理",
@@ -125,7 +126,12 @@
     "sku": "商品库存编码",
     "slug": "名称缩写",
     "slug-pattern-error": "",
+    "stock-allocated": "",
+    "stock-allocated-tooltip": "",
     "stock-on-hand": "库存",
+    "stock-on-hand-tooltip": "",
+    "stock-saleable": "",
+    "stock-saleable-tooltip": "",
     "tax-category": "税表分类",
     "taxes": "价格(含税)",
     "track-inventory": "跟踪库存",
@@ -667,6 +673,7 @@
     "payment-method-config-options": "支付方式选项配置",
     "permissions": "权限",
     "prices-include-tax": "设置默认销售区域价格含税",
+    "profile": "",
     "rate": "税率",
     "remove-countries-from-zone-success": "{ countryCount }个国际已从\"{ zoneName }\"中移除",
     "remove-from-zone": "",

+ 7 - 0
packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json

@@ -40,6 +40,7 @@
     "orders": "訂單管理",
     "payment-methods": "支付方式",
     "products": "商品",
+    "profile": "",
     "promotions": "優惠",
     "roles": "角色管理",
     "shipping-methods": "配送方式管理",
@@ -125,7 +126,12 @@
     "sku": "商品庫存編碼",
     "slug": "名稱缩写",
     "slug-pattern-error": "",
+    "stock-allocated": "",
+    "stock-allocated-tooltip": "",
     "stock-on-hand": "庫存",
+    "stock-on-hand-tooltip": "",
+    "stock-saleable": "",
+    "stock-saleable-tooltip": "",
     "tax-category": "税表分類",
     "taxes": "價格(連税)",
     "track-inventory": "跟踪庫存",
@@ -667,6 +673,7 @@
     "payment-method-config-options": "支付方式選項配置",
     "permissions": "權限",
     "prices-include-tax": "設定默認銷售區域價格連税",
+    "profile": "",
     "rate": "税率",
     "remove-countries-from-zone-success": "{ countryCount }個國際已從\"{ zoneName }\"中移除",
     "remove-from-zone": "",

+ 13 - 0
packages/asset-server-plugin/e2e/graphql/generated-e2e-asset-server-plugin-types.ts

@@ -244,6 +244,8 @@ export type Mutation = {
     createAdministrator: Administrator;
     /** Update an existing Administrator */
     updateAdministrator: Administrator;
+    /** Update the active (currently logged-in) Administrator */
+    updateActiveAdministrator: Administrator;
     /** Delete an Administrator */
     deleteAdministrator: DeletionResponse;
     /** Assign a Role to an Administrator */
@@ -411,6 +413,10 @@ export type MutationUpdateAdministratorArgs = {
     input: UpdateAdministratorInput;
 };
 
+export type MutationUpdateActiveAdministratorArgs = {
+    input: UpdateActiveAdministratorInput;
+};
+
 export type MutationDeleteAdministratorArgs = {
     id: Scalars['ID'];
 };
@@ -795,6 +801,13 @@ export type UpdateAdministratorInput = {
     roleIds?: Maybe<Array<Scalars['ID']>>;
 };
 
+export type UpdateActiveAdministratorInput = {
+    firstName?: Maybe<Scalars['String']>;
+    lastName?: Maybe<Scalars['String']>;
+    emailAddress?: Maybe<Scalars['String']>;
+    password?: Maybe<Scalars['String']>;
+};
+
 export type MimeTypeError = ErrorResult & {
     errorCode: ErrorCode;
     message: Scalars['String'];

+ 3 - 3
packages/asset-server-plugin/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/asset-server-plugin",
-  "version": "0.17.0",
+  "version": "0.17.1",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
   "files": [
@@ -22,8 +22,8 @@
     "@types/fs-extra": "^9.0.1",
     "@types/node-fetch": "^2.5.7",
     "@types/sharp": "^0.26.0",
-    "@vendure/common": "^0.17.0",
-    "@vendure/core": "^0.17.0",
+    "@vendure/common": "^0.17.1",
+    "@vendure/core": "^0.17.1",
     "aws-sdk": "^2.766.0",
     "express": "^4.17.1",
     "node-fetch": "^2.6.1",

+ 1 - 1
packages/common/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/common",
-  "version": "0.17.0",
+  "version": "0.17.1",
   "main": "index.js",
   "license": "MIT",
   "scripts": {

+ 14 - 0
packages/common/src/generated-types.ts

@@ -286,6 +286,8 @@ export type Mutation = {
   createAdministrator: Administrator;
   /** Update an existing Administrator */
   updateAdministrator: Administrator;
+  /** Update the active (currently logged-in) Administrator */
+  updateActiveAdministrator: Administrator;
   /** Delete an Administrator */
   deleteAdministrator: DeletionResponse;
   /** Assign a Role to an Administrator */
@@ -456,6 +458,11 @@ export type MutationUpdateAdministratorArgs = {
 };
 
 
+export type MutationUpdateActiveAdministratorArgs = {
+  input: UpdateActiveAdministratorInput;
+};
+
+
 export type MutationDeleteAdministratorArgs = {
   id: Scalars['ID'];
 };
@@ -926,6 +933,13 @@ export type UpdateAdministratorInput = {
   roleIds?: Maybe<Array<Scalars['ID']>>;
 };
 
+export type UpdateActiveAdministratorInput = {
+  firstName?: Maybe<Scalars['String']>;
+  lastName?: Maybe<Scalars['String']>;
+  emailAddress?: Maybe<Scalars['String']>;
+  password?: Maybe<Scalars['String']>;
+};
+
 export type MimeTypeError = ErrorResult & {
   __typename?: 'MimeTypeError';
   errorCode: ErrorCode;

+ 1 - 1
packages/core/e2e/__snapshots__/administrator.e2e-spec.ts.snap

@@ -57,7 +57,7 @@ Object {
   "lastName": "new last",
   "user": Object {
     "id": "T_3",
-    "identifier": "test@test.com",
+    "identifier": "new-email",
     "lastLogin": null,
     "roles": Array [
       Object {

+ 49 - 16
packages/core/e2e/administrator.e2e-spec.ts

@@ -15,6 +15,7 @@ import {
     DeletionResult,
     GetAdministrator,
     GetAdministrators,
+    UpdateActiveAdministrator,
     UpdateAdministrator,
 } from './graphql/generated-e2e-admin-types';
 import { CREATE_ADMINISTRATOR } from './graphql/shared-definitions';
@@ -73,22 +74,6 @@ describe('Administrator resolver', () => {
         expect(result.administrator).toEqual(createdAdmin);
     });
 
-    it('activeAdministrator', async () => {
-        await adminClient.asAnonymousUser();
-
-        const { activeAdministrator: result1 } = await adminClient.query<ActiveAdministrator.Query>(
-            GET_ACTIVE_ADMINISTRATOR,
-        );
-        expect(result1).toBeNull();
-
-        await adminClient.asSuperAdmin();
-
-        const { activeAdministrator: result2 } = await adminClient.query<ActiveAdministrator.Query>(
-            GET_ACTIVE_ADMINISTRATOR,
-        );
-        expect(result2?.emailAddress).toBe(SUPER_ADMIN_USER_IDENTIFIER);
-    });
-
     it('updateAdministrator', async () => {
         const result = await adminClient.query<UpdateAdministrator.Mutation, UpdateAdministrator.Variables>(
             UPDATE_ADMINISTRATOR,
@@ -175,6 +160,45 @@ describe('Administrator resolver', () => {
 
         expect(administrator).toBeNull();
     });
+
+    it('activeAdministrator', async () => {
+        await adminClient.asAnonymousUser();
+
+        const { activeAdministrator: result1 } = await adminClient.query<ActiveAdministrator.Query>(
+            GET_ACTIVE_ADMINISTRATOR,
+        );
+        expect(result1).toBeNull();
+
+        await adminClient.asSuperAdmin();
+
+        const { activeAdministrator: result2 } = await adminClient.query<ActiveAdministrator.Query>(
+            GET_ACTIVE_ADMINISTRATOR,
+        );
+        expect(result2?.emailAddress).toBe(SUPER_ADMIN_USER_IDENTIFIER);
+    });
+
+    it('updateActiveAdministrator', async () => {
+        const { updateActiveAdministrator } = await adminClient.query<
+            UpdateActiveAdministrator.Mutation,
+            UpdateActiveAdministrator.Variables
+        >(UPDATE_ACTIVE_ADMINISTRATOR, {
+            input: {
+                firstName: 'Thomas',
+                lastName: 'Anderson',
+                emailAddress: 'neo@metacortex.com',
+            },
+        });
+
+        expect(updateActiveAdministrator.firstName).toBe('Thomas');
+        expect(updateActiveAdministrator.lastName).toBe('Anderson');
+
+        const { activeAdministrator } = await adminClient.query<ActiveAdministrator.Query>(
+            GET_ACTIVE_ADMINISTRATOR,
+        );
+
+        expect(activeAdministrator?.firstName).toBe('Thomas');
+        expect(activeAdministrator?.user.identifier).toBe('neo@metacortex.com');
+    });
 });
 
 export const GET_ADMINISTRATORS = gql`
@@ -207,6 +231,15 @@ export const GET_ACTIVE_ADMINISTRATOR = gql`
     ${ADMINISTRATOR_FRAGMENT}
 `;
 
+export const UPDATE_ACTIVE_ADMINISTRATOR = gql`
+    mutation UpdateActiveAdministrator($input: UpdateActiveAdministratorInput!) {
+        updateActiveAdministrator(input: $input) {
+            ...Administrator
+        }
+    }
+    ${ADMINISTRATOR_FRAGMENT}
+`;
+
 export const UPDATE_ADMINISTRATOR = gql`
     mutation UpdateAdministrator($input: UpdateAdministratorInput!) {
         updateAdministrator(input: $input) {

+ 27 - 0
packages/core/e2e/graphql/generated-e2e-admin-types.ts

@@ -244,6 +244,8 @@ export type Mutation = {
     createAdministrator: Administrator;
     /** Update an existing Administrator */
     updateAdministrator: Administrator;
+    /** Update the active (currently logged-in) Administrator */
+    updateActiveAdministrator: Administrator;
     /** Delete an Administrator */
     deleteAdministrator: DeletionResponse;
     /** Assign a Role to an Administrator */
@@ -411,6 +413,10 @@ export type MutationUpdateAdministratorArgs = {
     input: UpdateAdministratorInput;
 };
 
+export type MutationUpdateActiveAdministratorArgs = {
+    input: UpdateActiveAdministratorInput;
+};
+
 export type MutationDeleteAdministratorArgs = {
     id: Scalars['ID'];
 };
@@ -795,6 +801,13 @@ export type UpdateAdministratorInput = {
     roleIds?: Maybe<Array<Scalars['ID']>>;
 };
 
+export type UpdateActiveAdministratorInput = {
+    firstName?: Maybe<Scalars['String']>;
+    lastName?: Maybe<Scalars['String']>;
+    emailAddress?: Maybe<Scalars['String']>;
+    password?: Maybe<Scalars['String']>;
+};
+
 export type MimeTypeError = ErrorResult & {
     errorCode: ErrorCode;
     message: Scalars['String'];
@@ -4014,6 +4027,12 @@ export type ActiveAdministratorQueryVariables = Exact<{ [key: string]: never }>;
 
 export type ActiveAdministratorQuery = { activeAdministrator?: Maybe<AdministratorFragment> };
 
+export type UpdateActiveAdministratorMutationVariables = Exact<{
+    input: UpdateActiveAdministratorInput;
+}>;
+
+export type UpdateActiveAdministratorMutation = { updateActiveAdministrator: AdministratorFragment };
+
 export type UpdateAdministratorMutationVariables = Exact<{
     input: UpdateAdministratorInput;
 }>;
@@ -5753,6 +5772,14 @@ export namespace ActiveAdministrator {
     export type ActiveAdministrator = NonNullable<ActiveAdministratorQuery['activeAdministrator']>;
 }
 
+export namespace UpdateActiveAdministrator {
+    export type Variables = UpdateActiveAdministratorMutationVariables;
+    export type Mutation = UpdateActiveAdministratorMutation;
+    export type UpdateActiveAdministrator = NonNullable<
+        UpdateActiveAdministratorMutation['updateActiveAdministrator']
+    >;
+}
+
 export namespace UpdateAdministrator {
     export type Variables = UpdateAdministratorMutationVariables;
     export type Mutation = UpdateAdministratorMutation;

+ 2 - 2
packages/core/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/core",
-  "version": "0.17.0",
+  "version": "0.17.1",
   "description": "A modern, headless ecommerce framework",
   "repository": {
     "type": "git",
@@ -48,7 +48,7 @@
     "@nestjs/testing": "7.4.4",
     "@nestjs/typeorm": "7.1.3",
     "@types/fs-extra": "^9.0.1",
-    "@vendure/common": "^0.17.0",
+    "@vendure/common": "^0.17.1",
     "apollo-server-express": "2.18.1",
     "bcrypt": "^5.0.0",
     "body-parser": "^1.19.0",

+ 17 - 0
packages/core/src/api/resolvers/admin/administrator.resolver.ts

@@ -4,6 +4,7 @@ import {
     MutationAssignRoleToAdministratorArgs,
     MutationCreateAdministratorArgs,
     MutationDeleteAdministratorArgs,
+    MutationUpdateActiveAdministratorArgs,
     MutationUpdateAdministratorArgs,
     Permission,
     QueryAdministratorArgs,
@@ -70,6 +71,22 @@ export class AdministratorResolver {
         return this.administratorService.update(ctx, input);
     }
 
+    @Transaction()
+    @Mutation()
+    @Allow(Permission.Owner)
+    async updateActiveAdministrator(
+        @Ctx() ctx: RequestContext,
+        @Args() args: MutationUpdateActiveAdministratorArgs,
+    ): Promise<Administrator | undefined> {
+        if (ctx.activeUserId) {
+            const { input } = args;
+            const administrator = await this.administratorService.findOneByUserId(ctx, ctx.activeUserId);
+            if (administrator) {
+                return this.administratorService.update(ctx, { ...input, id: administrator.id });
+            }
+        }
+    }
+
     @Transaction()
     @Mutation()
     @Allow(Permission.UpdateAdministrator)

+ 9 - 0
packages/core/src/api/schema/admin-api/administrator.api.graphql

@@ -9,6 +9,8 @@ type Mutation {
     createAdministrator(input: CreateAdministratorInput!): Administrator!
     "Update an existing Administrator"
     updateAdministrator(input: UpdateAdministratorInput!): Administrator!
+    "Update the active (currently logged-in) Administrator"
+    updateActiveAdministrator(input: UpdateActiveAdministratorInput!): Administrator!
     "Delete an Administrator"
     deleteAdministrator(id: ID!): DeletionResponse!
     "Assign a Role to an Administrator"
@@ -34,3 +36,10 @@ input UpdateAdministratorInput {
     password: String
     roleIds: [ID!]
 }
+
+input UpdateActiveAdministratorInput {
+    firstName: String
+    lastName: String
+    emailAddress: String
+    password: String
+}

+ 4 - 0
packages/core/src/service/services/administrator.service.ts

@@ -91,6 +91,10 @@ export class AdministratorService {
         let updatedAdministrator = patchEntity(administrator, input);
         await this.connection.getRepository(ctx, Administrator).save(administrator, { reload: false });
 
+        if (input.emailAddress) {
+            updatedAdministrator.user.identifier = input.emailAddress;
+            await this.connection.getRepository(ctx, User).save(updatedAdministrator.user);
+        }
         if (input.password) {
             const user = await this.userService.getUserById(ctx, administrator.user.id);
             if (user) {

+ 3 - 3
packages/create/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/create",
-  "version": "0.17.0",
+  "version": "0.17.1",
   "license": "MIT",
   "bin": {
     "create": "./index.js"
@@ -26,13 +26,13 @@
     "@types/handlebars": "^4.1.0",
     "@types/listr": "^0.14.2",
     "@types/semver": "^6.2.2",
-    "@vendure/core": "^0.17.0",
+    "@vendure/core": "^0.17.1",
     "rimraf": "^3.0.2",
     "ts-node": "^9.0.0",
     "typescript": "4.0.3"
   },
   "dependencies": {
-    "@vendure/common": "^0.17.0",
+    "@vendure/common": "^0.17.1",
     "chalk": "^4.1.0",
     "commander": "^6.1.0",
     "cross-spawn": "^7.0.3",

+ 9 - 9
packages/dev-server/package.json

@@ -1,6 +1,6 @@
 {
   "name": "dev-server",
-  "version": "0.17.0",
+  "version": "0.17.1",
   "main": "index.js",
   "license": "MIT",
   "private": true,
@@ -14,18 +14,18 @@
     "load-test:100k": "node -r ts-node/register load-testing/run-load-test.ts 100000"
   },
   "dependencies": {
-    "@vendure/admin-ui-plugin": "^0.17.0",
-    "@vendure/asset-server-plugin": "^0.17.0",
-    "@vendure/common": "^0.17.0",
-    "@vendure/core": "^0.17.0",
-    "@vendure/elasticsearch-plugin": "^0.17.0",
-    "@vendure/email-plugin": "^0.17.0",
+    "@vendure/admin-ui-plugin": "^0.17.1",
+    "@vendure/asset-server-plugin": "^0.17.1",
+    "@vendure/common": "^0.17.1",
+    "@vendure/core": "^0.17.1",
+    "@vendure/elasticsearch-plugin": "^0.17.1",
+    "@vendure/email-plugin": "^0.17.1",
     "typescript": "4.0.3"
   },
   "devDependencies": {
     "@types/csv-stringify": "^3.1.0",
-    "@vendure/testing": "^0.17.0",
-    "@vendure/ui-devkit": "^0.17.0",
+    "@vendure/testing": "^0.17.1",
+    "@vendure/ui-devkit": "^0.17.1",
     "concurrently": "^5.0.0",
     "csv-stringify": "^5.3.3"
   }

+ 13 - 0
packages/elasticsearch-plugin/e2e/graphql/generated-e2e-elasticsearch-plugin-types.ts

@@ -244,6 +244,8 @@ export type Mutation = {
     createAdministrator: Administrator;
     /** Update an existing Administrator */
     updateAdministrator: Administrator;
+    /** Update the active (currently logged-in) Administrator */
+    updateActiveAdministrator: Administrator;
     /** Delete an Administrator */
     deleteAdministrator: DeletionResponse;
     /** Assign a Role to an Administrator */
@@ -411,6 +413,10 @@ export type MutationUpdateAdministratorArgs = {
     input: UpdateAdministratorInput;
 };
 
+export type MutationUpdateActiveAdministratorArgs = {
+    input: UpdateActiveAdministratorInput;
+};
+
 export type MutationDeleteAdministratorArgs = {
     id: Scalars['ID'];
 };
@@ -795,6 +801,13 @@ export type UpdateAdministratorInput = {
     roleIds?: Maybe<Array<Scalars['ID']>>;
 };
 
+export type UpdateActiveAdministratorInput = {
+    firstName?: Maybe<Scalars['String']>;
+    lastName?: Maybe<Scalars['String']>;
+    emailAddress?: Maybe<Scalars['String']>;
+    password?: Maybe<Scalars['String']>;
+};
+
 export type MimeTypeError = ErrorResult & {
     errorCode: ErrorCode;
     message: Scalars['String'];

+ 3 - 3
packages/elasticsearch-plugin/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/elasticsearch-plugin",
-  "version": "0.17.0",
+  "version": "0.17.1",
   "license": "MIT",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
@@ -22,8 +22,8 @@
     "deepmerge": "^4.2.2"
   },
   "devDependencies": {
-    "@vendure/common": "^0.17.0",
-    "@vendure/core": "^0.17.0",
+    "@vendure/common": "^0.17.1",
+    "@vendure/core": "^0.17.1",
     "rimraf": "^3.0.2",
     "typescript": "4.0.3"
   }

+ 3 - 3
packages/email-plugin/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/email-plugin",
-  "version": "0.17.0",
+  "version": "0.17.1",
   "license": "MIT",
   "main": "lib/index.js",
   "types": "lib/index.d.ts",
@@ -33,8 +33,8 @@
     "@types/handlebars": "^4.1.0",
     "@types/mjml": "^4.0.4",
     "@types/nodemailer": "^6.4.0",
-    "@vendure/common": "^0.17.0",
-    "@vendure/core": "^0.17.0",
+    "@vendure/common": "^0.17.1",
+    "@vendure/core": "^0.17.1",
     "rimraf": "^3.0.2",
     "typescript": "4.0.3"
   }

+ 3 - 3
packages/testing/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/testing",
-  "version": "0.17.0",
+  "version": "0.17.1",
   "description": "End-to-end testing tools for Vendure projects",
   "keywords": [
     "vendure",
@@ -33,7 +33,7 @@
   },
   "dependencies": {
     "@types/node-fetch": "^2.5.4",
-    "@vendure/common": "^0.17.0",
+    "@vendure/common": "^0.17.1",
     "faker": "^4.1.0",
     "form-data": "^3.0.0",
     "graphql": "15.3.0",
@@ -44,7 +44,7 @@
   "devDependencies": {
     "@types/mysql": "^2.15.15",
     "@types/pg": "^7.14.5",
-    "@vendure/core": "^0.17.0",
+    "@vendure/core": "^0.17.1",
     "mysql": "^2.18.1",
     "pg": "^8.4.0",
     "rimraf": "^3.0.0",

+ 4 - 4
packages/ui-devkit/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@vendure/ui-devkit",
-  "version": "0.17.0",
+  "version": "0.17.1",
   "description": "A library for authoring Vendure Admin UI extensions",
   "keywords": [
     "vendure",
@@ -39,8 +39,8 @@
     "@angular/cli": "^10.1.4",
     "@angular/compiler": "^10.1.4",
     "@angular/compiler-cli": "^10.1.4",
-    "@vendure/admin-ui": "^0.17.0",
-    "@vendure/common": "^0.17.0",
+    "@vendure/admin-ui": "^0.17.1",
+    "@vendure/common": "^0.17.1",
     "chalk": "^4.1.0",
     "chokidar": "^3.4.2",
     "fs-extra": "^9.0.1",
@@ -51,7 +51,7 @@
     "@rollup/plugin-node-resolve": "^9.0.0",
     "@types/fs-extra": "^9.0.1",
     "@types/glob": "^7.1.3",
-    "@vendure/core": "^0.17.0",
+    "@vendure/core": "^0.17.1",
     "rimraf": "^3.0.2",
     "rollup": "^2.28.2",
     "rollup-plugin-terser": "^7.0.2",

File diff suppressed because it is too large
+ 0 - 0
schema-admin.json


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