Browse Source

feat(admin-ui): Add entity info to detail views

Closes #179
Michael Bromley 6 years ago
parent
commit
cf604aae26
47 changed files with 266 additions and 70 deletions
  1. 1 0
      packages/admin-ui/src/app/catalog/components/collection-detail/collection-detail.component.html
  2. 10 5
      packages/admin-ui/src/app/catalog/components/facet-detail/facet-detail.component.html
  3. 12 9
      packages/admin-ui/src/app/catalog/components/product-detail/product-detail.component.html
  4. 1 1
      packages/admin-ui/src/app/catalog/components/product-detail/product-detail.component.scss
  5. 1 0
      packages/admin-ui/src/app/catalog/components/product-variants-list/product-variants-list.component.html
  6. 2 0
      packages/admin-ui/src/app/catalog/providers/routing/collection-resolver.ts
  7. 2 1
      packages/admin-ui/src/app/catalog/providers/routing/facet-resolver.ts
  8. 2 0
      packages/admin-ui/src/app/catalog/providers/routing/product-resolver.ts
  9. 2 0
      packages/admin-ui/src/app/catalog/providers/routing/product-variants-resolver.ts
  10. 30 24
      packages/admin-ui/src/app/common/generated-types.ts
  11. 14 2
      packages/admin-ui/src/app/common/utilities/flatten-facet-values.spec.ts
  12. 1 0
      packages/admin-ui/src/app/customer/components/address-card/address-card.component.html
  13. 4 1
      packages/admin-ui/src/app/customer/components/customer-detail/customer-detail.component.html
  14. 2 0
      packages/admin-ui/src/app/customer/providers/routing/customer-resolver.ts
  15. 4 0
      packages/admin-ui/src/app/data/definitions/administrator-definitions.ts
  16. 2 0
      packages/admin-ui/src/app/data/definitions/collection-definitions.ts
  17. 4 0
      packages/admin-ui/src/app/data/definitions/customer-definitions.ts
  18. 5 0
      packages/admin-ui/src/app/data/definitions/facet-definitions.ts
  19. 45 0
      packages/admin-ui/src/app/data/definitions/product-definitions.ts
  20. 10 0
      packages/admin-ui/src/app/data/definitions/settings-definitions.ts
  21. 12 9
      packages/admin-ui/src/app/marketing/components/promotion-detail/promotion-detail.component.html
  22. 2 5
      packages/admin-ui/src/app/order/components/order-detail/order-detail.component.html
  23. 0 5
      packages/admin-ui/src/app/order/components/order-detail/order-detail.component.scss
  24. 3 1
      packages/admin-ui/src/app/settings/components/admin-detail/admin-detail.component.html
  25. 3 1
      packages/admin-ui/src/app/settings/components/channel-detail/channel-detail.component.html
  26. 1 0
      packages/admin-ui/src/app/settings/components/country-detail/country-detail.component.html
  27. 3 1
      packages/admin-ui/src/app/settings/components/payment-method-detail/payment-method-detail.component.html
  28. 3 1
      packages/admin-ui/src/app/settings/components/role-detail/role-detail.component.html
  29. 3 1
      packages/admin-ui/src/app/settings/components/shipping-method-detail/shipping-method-detail.component.html
  30. 3 1
      packages/admin-ui/src/app/settings/components/tax-category-detail/tax-category-detail.component.html
  31. 3 1
      packages/admin-ui/src/app/settings/components/tax-rate-detail/tax-rate-detail.component.html
  32. 2 0
      packages/admin-ui/src/app/settings/providers/routing/administrator-resolver.ts
  33. 2 0
      packages/admin-ui/src/app/settings/providers/routing/channel-resolver.ts
  34. 2 0
      packages/admin-ui/src/app/settings/providers/routing/country-resolver.ts
  35. 2 0
      packages/admin-ui/src/app/settings/providers/routing/payment-method-resolver.ts
  36. 2 0
      packages/admin-ui/src/app/settings/providers/routing/role-resolver.ts
  37. 2 0
      packages/admin-ui/src/app/settings/providers/routing/tax-category-resolver.ts
  38. 2 0
      packages/admin-ui/src/app/settings/providers/routing/tax-rate-resolver.ts
  39. 8 1
      packages/admin-ui/src/app/shared/components/asset-gallery/asset-gallery.component.html
  40. 4 0
      packages/admin-ui/src/app/shared/components/asset-gallery/asset-gallery.component.scss
  41. 5 0
      packages/admin-ui/src/app/shared/components/asset-gallery/asset-gallery.component.ts
  42. 18 0
      packages/admin-ui/src/app/shared/components/entity-info/entity-info.component.html
  43. 8 0
      packages/admin-ui/src/app/shared/components/entity-info/entity-info.component.scss
  44. 12 0
      packages/admin-ui/src/app/shared/components/entity-info/entity-info.component.ts
  45. 1 0
      packages/admin-ui/src/app/shared/shared-declarations.ts
  46. 2 0
      packages/admin-ui/src/app/shared/shared.module.ts
  47. 4 0
      packages/admin-ui/src/styles/theme/_theme.scss

+ 1 - 0
packages/admin-ui/src/app/catalog/components/collection-detail/collection-detail.component.html

@@ -1,5 +1,6 @@
 <vdr-action-bar>
     <vdr-ab-left>
+        <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
         <vdr-language-selector
             [disabled]="isNew$ | async"
             [availableLanguageCodes]="availableLanguages$ | async"

+ 10 - 5
packages/admin-ui/src/app/catalog/components/facet-detail/facet-detail.component.html

@@ -1,5 +1,6 @@
 <vdr-action-bar>
     <vdr-ab-left>
+        <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
         <vdr-language-selector
             [disabled]="isNew$ | async"
             [availableLanguageCodes]="availableLanguages$ | async"
@@ -92,6 +93,7 @@
         <table class="facet-values-list table" formArrayName="values" *ngIf="0 < getValuesFormArray().length">
             <thead>
                 <tr>
+                    <th></th>
                     <th>{{ 'common.name' | translate }}</th>
                     <th>{{ 'common.code' | translate }}</th>
                     <ng-container *ngFor="let customField of customValueFields">
@@ -103,10 +105,13 @@
             <tbody>
                 <tr
                     class="facet-value"
-                    *ngFor="let value of getValuesFormArray().controls; let i = index"
+                    *ngFor="let value of values$ | async; let i = index"
                     [formGroupName]="i"
                 >
-                    <td>
+                    <td class="align-middle">
+                        <vdr-entity-info [entity]="value"></vdr-entity-info>
+                    </td>
+                    <td class="align-middle">
                         <input
                             type="text"
                             formControlName="name"
@@ -114,9 +119,9 @@
                             (input)="updateValueCode(facet.values[i]?.code, $event.target.value, i)"
                         />
                     </td>
-                    <td><input type="text" formControlName="code" readonly /></td>
+                    <td class="align-middle"><input type="text" formControlName="code" readonly /></td>
                     <ng-container *ngFor="let customField of customValueFields">
-                        <td>
+                        <td class="align-middle">
                             <vdr-custom-field-control
                                 *ngIf="customValueFieldIsSet(i, customField.name)"
                                 entityName="FacetValue"
@@ -126,7 +131,7 @@
                             ></vdr-custom-field-control>
                         </td>
                     </ng-container>
-                    <td>
+                    <td class="align-middle">
                         <vdr-dropdown>
                             <button type="button" class="btn btn-link btn-sm" vdrDropdownTrigger>
                                 {{ 'common.actions' | translate }}

+ 12 - 9
packages/admin-ui/src/app/catalog/components/product-detail/product-detail.component.html

@@ -1,14 +1,17 @@
 <vdr-action-bar>
     <vdr-ab-left>
-        <clr-toggle-wrapper *vdrIfPermissions="'UpdateCatalog'">
-            <input
-                type="checkbox"
-                clrToggle
-                name="enabled"
-                [formControl]="detailForm.get(['product', 'enabled'])"
-            />
-            <label>{{ 'common.enabled' | translate }}</label>
-        </clr-toggle-wrapper>
+        <div class="flex clr-flex-row">
+            <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
+            <clr-toggle-wrapper *vdrIfPermissions="'UpdateCatalog'">
+                <input
+                    type="checkbox"
+                    clrToggle
+                    name="enabled"
+                    [formControl]="detailForm.get(['product', 'enabled'])"
+                />
+                <label>{{ 'common.enabled' | translate }}</label>
+            </clr-toggle-wrapper>
+        </div>
         <vdr-language-selector
             [disabled]="isNew$ | async"
             [availableLanguageCodes]="availableLanguages$ | async"

+ 1 - 1
packages/admin-ui/src/app/catalog/components/product-detail/product-detail.component.scss

@@ -9,7 +9,7 @@
 }
 
 vdr-action-bar clr-toggle-wrapper {
-    margin-top: 10px;
+    margin-top: 12px;
 }
 
 .group-name {

+ 1 - 0
packages/admin-ui/src/app/catalog/components/product-variants-list/product-variants-list.component.html

@@ -134,6 +134,7 @@
             </div>
             <div class="card-block">
                 <div class="options-facets">
+                    <vdr-entity-info [entity]="variant"></vdr-entity-info>
                     <div *ngIf="variant.options.length">
                         <div class="options">
                             <vdr-chip

+ 2 - 0
packages/admin-ui/src/app/catalog/providers/routing/collection-resolver.ts

@@ -12,6 +12,8 @@ export class CollectionResolver extends BaseEntityResolver<Collection.Fragment>
             {
                 __typename: 'Collection' as 'Collection',
                 id: '',
+                createdAt: '',
+                updatedAt: '',
                 languageCode: getDefaultLanguage(),
                 name: '',
                 isPrivate: false,

+ 2 - 1
packages/admin-ui/src/app/catalog/providers/routing/facet-resolver.ts

@@ -12,11 +12,12 @@ export class FacetResolver extends BaseEntityResolver<FacetWithValues.Fragment>
             {
                 __typename: 'Facet' as 'Facet',
                 id: '',
+                createdAt: '',
+                updatedAt: '',
                 isPrivate: false,
                 languageCode: getDefaultLanguage(),
                 name: '',
                 code: '',
-                updatedAt: '',
                 translations: [],
                 values: [],
             },

+ 2 - 0
packages/admin-ui/src/app/catalog/providers/routing/product-resolver.ts

@@ -12,6 +12,8 @@ export class ProductResolver extends BaseEntityResolver<ProductWithVariants.Frag
             {
                 __typename: 'Product' as 'Product',
                 id: '',
+                createdAt: '',
+                updatedAt: '',
                 enabled: true,
                 languageCode: getDefaultLanguage(),
                 name: '',

+ 2 - 0
packages/admin-ui/src/app/catalog/providers/routing/product-variants-resolver.ts

@@ -11,6 +11,8 @@ export class ProductVariantsResolver extends BaseEntityResolver<GetProductVarian
             {
                 __typename: 'Product' as 'Product',
                 id: '',
+                createdAt: '',
+                updatedAt: '',
                 name: '',
                 optionGroups: [],
                 variants: [],

+ 30 - 24
packages/admin-ui/src/app/common/generated-types.ts

@@ -332,6 +332,8 @@ export type ConfigurableOperationInput = {
 export type Country = Node & {
   __typename?: 'Country',
   id: Scalars['ID'],
+  createdAt: Scalars['DateTime'],
+  updatedAt: Scalars['DateTime'],
   languageCode: LanguageCode,
   code: Scalars['String'],
   name: Scalars['String'],
@@ -340,6 +342,8 @@ export type Country = Node & {
 };
 
 export type CountryFilterParameter = {
+  createdAt?: Maybe<DateOperators>,
+  updatedAt?: Maybe<DateOperators>,
   languageCode?: Maybe<StringOperators>,
   code?: Maybe<StringOperators>,
   name?: Maybe<StringOperators>,
@@ -361,6 +365,8 @@ export type CountryListOptions = {
 
 export type CountrySortParameter = {
   id?: Maybe<SortOrder>,
+  createdAt?: Maybe<SortOrder>,
+  updatedAt?: Maybe<SortOrder>,
   code?: Maybe<SortOrder>,
   name?: Maybe<SortOrder>,
 };
@@ -3465,9 +3471,9 @@ export type Zone = Node & {
   name: Scalars['String'],
   members: Array<Country>,
 };
-export type AdministratorFragment = ({ __typename?: 'Administrator' } & Pick<Administrator, 'id' | 'firstName' | 'lastName' | 'emailAddress'> & { user: ({ __typename?: 'User' } & Pick<User, 'id' | 'identifier' | 'lastLogin'> & { roles: Array<({ __typename?: 'Role' } & Pick<Role, 'id' | 'code' | 'description' | 'permissions'>)> }) });
+export type AdministratorFragment = ({ __typename?: 'Administrator' } & Pick<Administrator, 'id' | 'createdAt' | 'updatedAt' | 'firstName' | 'lastName' | 'emailAddress'> & { user: ({ __typename?: 'User' } & Pick<User, 'id' | 'identifier' | 'lastLogin'> & { roles: Array<({ __typename?: 'Role' } & Pick<Role, 'id' | 'code' | 'description' | 'permissions'>)> }) });
 
-export type RoleFragment = ({ __typename?: 'Role' } & Pick<Role, 'id' | 'code' | 'description' | 'permissions'> & { channels: Array<({ __typename?: 'Channel' } & Pick<Channel, 'id' | 'code' | 'token'>)> });
+export type RoleFragment = ({ __typename?: 'Role' } & Pick<Role, 'id' | 'createdAt' | 'updatedAt' | 'code' | 'description' | 'permissions'> & { channels: Array<({ __typename?: 'Channel' } & Pick<Channel, 'id' | 'code' | 'token'>)> });
 
 export type GetAdministratorsQueryVariables = {
   options?: Maybe<AdministratorListOptions>
@@ -3605,7 +3611,7 @@ export type GetCollectionFiltersQueryVariables = {};
 
 export type GetCollectionFiltersQuery = ({ __typename?: 'Query' } & { collectionFilters: Array<({ __typename?: 'ConfigurableOperationDefinition' } & ConfigurableOperationDefFragment)> });
 
-export type CollectionFragment = ({ __typename?: 'Collection' } & Pick<Collection, 'id' | 'name' | 'description' | 'isPrivate' | 'languageCode'> & { featuredAsset: Maybe<({ __typename?: 'Asset' } & AssetFragment)>, assets: Array<({ __typename?: 'Asset' } & AssetFragment)>, filters: Array<({ __typename?: 'ConfigurableOperation' } & ConfigurableOperationFragment)>, translations: Array<({ __typename?: 'CollectionTranslation' } & Pick<CollectionTranslation, 'id' | 'languageCode' | 'name' | 'description'>)>, parent: Maybe<({ __typename?: 'Collection' } & Pick<Collection, 'id' | 'name'>)>, children: Maybe<Array<({ __typename?: 'Collection' } & Pick<Collection, 'id' | 'name'>)>> });
+export type CollectionFragment = ({ __typename?: 'Collection' } & Pick<Collection, 'id' | 'createdAt' | 'updatedAt' | 'name' | 'description' | 'isPrivate' | 'languageCode'> & { featuredAsset: Maybe<({ __typename?: 'Asset' } & AssetFragment)>, assets: Array<({ __typename?: 'Asset' } & AssetFragment)>, filters: Array<({ __typename?: 'ConfigurableOperation' } & ConfigurableOperationFragment)>, translations: Array<({ __typename?: 'CollectionTranslation' } & Pick<CollectionTranslation, 'id' | 'languageCode' | 'name' | 'description'>)>, parent: Maybe<({ __typename?: 'Collection' } & Pick<Collection, 'id' | 'name'>)>, children: Maybe<Array<({ __typename?: 'Collection' } & Pick<Collection, 'id' | 'name'>)>> });
 
 export type GetCollectionListQueryVariables = {
   options?: Maybe<CollectionListOptions>
@@ -3657,9 +3663,9 @@ export type GetCollectionContentsQueryVariables = {
 
 export type GetCollectionContentsQuery = ({ __typename?: 'Query' } & { collection: Maybe<({ __typename?: 'Collection' } & Pick<Collection, 'id' | 'name'> & { productVariants: ({ __typename?: 'ProductVariantList' } & Pick<ProductVariantList, 'totalItems'> & { items: Array<({ __typename?: 'ProductVariant' } & Pick<ProductVariant, 'id' | 'productId' | 'name'>)> }) })> });
 
-export type AddressFragment = ({ __typename?: 'Address' } & Pick<Address, 'id' | 'fullName' | 'company' | 'streetLine1' | 'streetLine2' | 'city' | 'province' | 'postalCode' | 'phoneNumber' | 'defaultShippingAddress' | 'defaultBillingAddress'> & { country: ({ __typename?: 'Country' } & Pick<Country, 'id' | 'code' | 'name'>) });
+export type AddressFragment = ({ __typename?: 'Address' } & Pick<Address, 'id' | 'createdAt' | 'updatedAt' | 'fullName' | 'company' | 'streetLine1' | 'streetLine2' | 'city' | 'province' | 'postalCode' | 'phoneNumber' | 'defaultShippingAddress' | 'defaultBillingAddress'> & { country: ({ __typename?: 'Country' } & Pick<Country, 'id' | 'code' | 'name'>) });
 
-export type CustomerFragment = ({ __typename?: 'Customer' } & Pick<Customer, 'id' | 'title' | 'firstName' | 'lastName' | 'phoneNumber' | 'emailAddress'> & { user: Maybe<({ __typename?: 'User' } & Pick<User, 'id' | 'identifier' | 'verified' | 'lastLogin'>)>, addresses: Maybe<Array<({ __typename?: 'Address' } & AddressFragment)>> });
+export type CustomerFragment = ({ __typename?: 'Customer' } & Pick<Customer, 'id' | 'createdAt' | 'updatedAt' | 'title' | 'firstName' | 'lastName' | 'phoneNumber' | 'emailAddress'> & { user: Maybe<({ __typename?: 'User' } & Pick<User, 'id' | 'identifier' | 'verified' | 'lastLogin'>)>, addresses: Maybe<Array<({ __typename?: 'Address' } & AddressFragment)>> });
 
 export type GetCustomerListQueryVariables = {
   options?: Maybe<CustomerListOptions>
@@ -3706,9 +3712,9 @@ export type UpdateCustomerAddressMutationVariables = {
 
 export type UpdateCustomerAddressMutation = ({ __typename?: 'Mutation' } & { updateCustomerAddress: ({ __typename?: 'Address' } & AddressFragment) });
 
-export type FacetValueFragment = ({ __typename?: 'FacetValue' } & Pick<FacetValue, 'id' | 'languageCode' | 'code' | 'name'> & { translations: Array<({ __typename?: 'FacetValueTranslation' } & Pick<FacetValueTranslation, 'id' | 'languageCode' | 'name'>)>, facet: ({ __typename?: 'Facet' } & Pick<Facet, 'id' | 'name'>) });
+export type FacetValueFragment = ({ __typename?: 'FacetValue' } & Pick<FacetValue, 'id' | 'createdAt' | 'updatedAt' | 'languageCode' | 'code' | 'name'> & { translations: Array<({ __typename?: 'FacetValueTranslation' } & Pick<FacetValueTranslation, 'id' | 'languageCode' | 'name'>)>, facet: ({ __typename?: 'Facet' } & Pick<Facet, 'id' | 'createdAt' | 'updatedAt' | 'name'>) });
 
-export type FacetWithValuesFragment = ({ __typename?: 'Facet' } & Pick<Facet, 'id' | 'updatedAt' | 'languageCode' | 'isPrivate' | 'code' | 'name'> & { translations: Array<({ __typename?: 'FacetTranslation' } & Pick<FacetTranslation, 'id' | 'languageCode' | 'name'>)>, values: Array<({ __typename?: 'FacetValue' } & FacetValueFragment)> });
+export type FacetWithValuesFragment = ({ __typename?: 'Facet' } & Pick<Facet, 'id' | 'createdAt' | 'updatedAt' | 'languageCode' | 'isPrivate' | 'code' | 'name'> & { translations: Array<({ __typename?: 'FacetTranslation' } & Pick<FacetTranslation, 'id' | 'languageCode' | 'name'>)>, values: Array<({ __typename?: 'FacetValue' } & FacetValueFragment)> });
 
 export type CreateFacetMutationVariables = {
   input: CreateFacetInput
@@ -3844,13 +3850,13 @@ export type AddNoteToOrderMutationVariables = {
 
 export type AddNoteToOrderMutation = ({ __typename?: 'Mutation' } & { addNoteToOrder: ({ __typename?: 'Order' } & Pick<Order, 'id'>) });
 
-export type AssetFragment = ({ __typename?: 'Asset' } & Pick<Asset, 'id' | 'createdAt' | 'name' | 'fileSize' | 'mimeType' | 'type' | 'preview' | 'source'>);
+export type AssetFragment = ({ __typename?: 'Asset' } & Pick<Asset, 'id' | 'createdAt' | 'updatedAt' | 'name' | 'fileSize' | 'mimeType' | 'type' | 'preview' | 'source'>);
 
-export type ProductVariantFragment = ({ __typename?: 'ProductVariant' } & Pick<ProductVariant, 'id' | 'enabled' | 'languageCode' | 'name' | 'price' | 'currencyCode' | 'priceIncludesTax' | 'priceWithTax' | 'stockOnHand' | 'trackInventory' | 'sku'> & { taxRateApplied: ({ __typename?: 'TaxRate' } & Pick<TaxRate, 'id' | 'name' | 'value'>), taxCategory: ({ __typename?: 'TaxCategory' } & Pick<TaxCategory, 'id' | 'name'>), options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'code' | 'languageCode' | 'name' | 'groupId'> & { translations: Array<({ __typename?: 'ProductOptionTranslation' } & Pick<ProductOptionTranslation, 'id' | 'languageCode' | 'name'>)> })>, facetValues: Array<({ __typename?: 'FacetValue' } & Pick<FacetValue, 'id' | 'code' | 'name'> & { facet: ({ __typename?: 'Facet' } & Pick<Facet, 'id' | 'name'>) })>, featuredAsset: Maybe<({ __typename?: 'Asset' } & AssetFragment)>, assets: Array<({ __typename?: 'Asset' } & AssetFragment)>, translations: Array<({ __typename?: 'ProductVariantTranslation' } & Pick<ProductVariantTranslation, 'id' | 'languageCode' | 'name'>)> });
+export type ProductVariantFragment = ({ __typename?: 'ProductVariant' } & Pick<ProductVariant, 'id' | 'createdAt' | 'updatedAt' | 'enabled' | 'languageCode' | 'name' | 'price' | 'currencyCode' | 'priceIncludesTax' | 'priceWithTax' | 'stockOnHand' | 'trackInventory' | 'sku'> & { taxRateApplied: ({ __typename?: 'TaxRate' } & Pick<TaxRate, 'id' | 'name' | 'value'>), taxCategory: ({ __typename?: 'TaxCategory' } & Pick<TaxCategory, 'id' | 'name'>), options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'code' | 'languageCode' | 'name' | 'groupId'> & { translations: Array<({ __typename?: 'ProductOptionTranslation' } & Pick<ProductOptionTranslation, 'id' | 'languageCode' | 'name'>)> })>, facetValues: Array<({ __typename?: 'FacetValue' } & Pick<FacetValue, 'id' | 'code' | 'name'> & { facet: ({ __typename?: 'Facet' } & Pick<Facet, 'id' | 'name'>) })>, featuredAsset: Maybe<({ __typename?: 'Asset' } & AssetFragment)>, assets: Array<({ __typename?: 'Asset' } & AssetFragment)>, translations: Array<({ __typename?: 'ProductVariantTranslation' } & Pick<ProductVariantTranslation, 'id' | 'languageCode' | 'name'>)> });
 
-export type ProductWithVariantsFragment = ({ __typename?: 'Product' } & Pick<Product, 'id' | 'enabled' | 'languageCode' | 'name' | 'slug' | 'description'> & { featuredAsset: Maybe<({ __typename?: 'Asset' } & AssetFragment)>, assets: Array<({ __typename?: 'Asset' } & AssetFragment)>, translations: Array<({ __typename?: 'ProductTranslation' } & Pick<ProductTranslation, 'languageCode' | 'name' | 'slug' | 'description'>)>, optionGroups: Array<({ __typename?: 'ProductOptionGroup' } & Pick<ProductOptionGroup, 'id' | 'languageCode' | 'code' | 'name'>)>, variants: Array<({ __typename?: 'ProductVariant' } & ProductVariantFragment)>, facetValues: Array<({ __typename?: 'FacetValue' } & Pick<FacetValue, 'id' | 'code' | 'name'> & { facet: ({ __typename?: 'Facet' } & Pick<Facet, 'id' | 'name'>) })> });
+export type ProductWithVariantsFragment = ({ __typename?: 'Product' } & Pick<Product, 'id' | 'createdAt' | 'updatedAt' | 'enabled' | 'languageCode' | 'name' | 'slug' | 'description'> & { featuredAsset: Maybe<({ __typename?: 'Asset' } & AssetFragment)>, assets: Array<({ __typename?: 'Asset' } & AssetFragment)>, translations: Array<({ __typename?: 'ProductTranslation' } & Pick<ProductTranslation, 'id' | 'languageCode' | 'name' | 'slug' | 'description'>)>, optionGroups: Array<({ __typename?: 'ProductOptionGroup' } & Pick<ProductOptionGroup, 'id' | 'languageCode' | 'code' | 'name'>)>, variants: Array<({ __typename?: 'ProductVariant' } & ProductVariantFragment)>, facetValues: Array<({ __typename?: 'FacetValue' } & Pick<FacetValue, 'id' | 'code' | 'name'> & { facet: ({ __typename?: 'Facet' } & Pick<Facet, 'id' | 'name'>) })> });
 
-export type ProductOptionGroupFragment = ({ __typename?: 'ProductOptionGroup' } & Pick<ProductOptionGroup, 'id' | 'languageCode' | 'code' | 'name'> & { translations: Array<({ __typename?: 'ProductOptionGroupTranslation' } & Pick<ProductOptionGroupTranslation, 'name'>)>, options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'languageCode' | 'name' | 'code'> & { translations: Array<({ __typename?: 'ProductOptionTranslation' } & Pick<ProductOptionTranslation, 'name'>)> })> });
+export type ProductOptionGroupFragment = ({ __typename?: 'ProductOptionGroup' } & Pick<ProductOptionGroup, 'id' | 'createdAt' | 'updatedAt' | 'languageCode' | 'code' | 'name'> & { translations: Array<({ __typename?: 'ProductOptionGroupTranslation' } & Pick<ProductOptionGroupTranslation, 'id' | 'name'>)>, options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'languageCode' | 'name' | 'code'> & { translations: Array<({ __typename?: 'ProductOptionTranslation' } & Pick<ProductOptionTranslation, 'name'>)> })> });
 
 export type UpdateProductMutationVariables = {
   input: UpdateProductInput
@@ -3906,7 +3912,7 @@ export type AddOptionToGroupMutationVariables = {
 };
 
 
-export type AddOptionToGroupMutation = ({ __typename?: 'Mutation' } & { createProductOption: ({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'name' | 'code' | 'groupId'>) });
+export type AddOptionToGroupMutation = ({ __typename?: 'Mutation' } & { createProductOption: ({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'createdAt' | 'updatedAt' | 'name' | 'code' | 'groupId'>) });
 
 export type AddOptionGroupToProductMutationVariables = {
   productId: Scalars['ID'],
@@ -3914,7 +3920,7 @@ export type AddOptionGroupToProductMutationVariables = {
 };
 
 
-export type AddOptionGroupToProductMutation = ({ __typename?: 'Mutation' } & { addOptionGroupToProduct: ({ __typename?: 'Product' } & Pick<Product, 'id'> & { optionGroups: Array<({ __typename?: 'ProductOptionGroup' } & Pick<ProductOptionGroup, 'id' | 'code'> & { options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'code'>)> })> }) });
+export type AddOptionGroupToProductMutation = ({ __typename?: 'Mutation' } & { addOptionGroupToProduct: ({ __typename?: 'Product' } & Pick<Product, 'id' | 'createdAt' | 'updatedAt'> & { optionGroups: Array<({ __typename?: 'ProductOptionGroup' } & Pick<ProductOptionGroup, 'id' | 'createdAt' | 'updatedAt' | 'code'> & { options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'createdAt' | 'updatedAt' | 'code'>)> })> }) });
 
 export type RemoveOptionGroupFromProductMutationVariables = {
   productId: Scalars['ID'],
@@ -3922,7 +3928,7 @@ export type RemoveOptionGroupFromProductMutationVariables = {
 };
 
 
-export type RemoveOptionGroupFromProductMutation = ({ __typename?: 'Mutation' } & { removeOptionGroupFromProduct: ({ __typename?: 'Product' } & Pick<Product, 'id'> & { optionGroups: Array<({ __typename?: 'ProductOptionGroup' } & Pick<ProductOptionGroup, 'id' | 'code'> & { options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'code'>)> })> }) });
+export type RemoveOptionGroupFromProductMutation = ({ __typename?: 'Mutation' } & { removeOptionGroupFromProduct: ({ __typename?: 'Product' } & Pick<Product, 'id' | 'createdAt' | 'updatedAt'> & { optionGroups: Array<({ __typename?: 'ProductOptionGroup' } & Pick<ProductOptionGroup, 'id' | 'createdAt' | 'updatedAt' | 'code'> & { options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'createdAt' | 'updatedAt' | 'code'>)> })> }) });
 
 export type GetProductWithVariantsQueryVariables = {
   id: Scalars['ID']
@@ -3936,14 +3942,14 @@ export type GetProductListQueryVariables = {
 };
 
 
-export type GetProductListQuery = ({ __typename?: 'Query' } & { products: ({ __typename?: 'ProductList' } & Pick<ProductList, 'totalItems'> & { items: Array<({ __typename?: 'Product' } & Pick<Product, 'id' | 'enabled' | 'languageCode' | 'name' | 'slug'> & { featuredAsset: Maybe<({ __typename?: 'Asset' } & Pick<Asset, 'id' | 'preview'>)> })> }) });
+export type GetProductListQuery = ({ __typename?: 'Query' } & { products: ({ __typename?: 'ProductList' } & Pick<ProductList, 'totalItems'> & { items: Array<({ __typename?: 'Product' } & Pick<Product, 'id' | 'createdAt' | 'updatedAt' | 'enabled' | 'languageCode' | 'name' | 'slug'> & { featuredAsset: Maybe<({ __typename?: 'Asset' } & Pick<Asset, 'id' | 'createdAt' | 'updatedAt' | 'preview'>)> })> }) });
 
 export type GetProductOptionGroupsQueryVariables = {
   filterTerm?: Maybe<Scalars['String']>
 };
 
 
-export type GetProductOptionGroupsQuery = ({ __typename?: 'Query' } & { productOptionGroups: Array<({ __typename?: 'ProductOptionGroup' } & Pick<ProductOptionGroup, 'id' | 'languageCode' | 'code' | 'name'> & { options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'languageCode' | 'code' | 'name'>)> })> });
+export type GetProductOptionGroupsQuery = ({ __typename?: 'Query' } & { productOptionGroups: Array<({ __typename?: 'ProductOptionGroup' } & Pick<ProductOptionGroup, 'id' | 'createdAt' | 'updatedAt' | 'languageCode' | 'code' | 'name'> & { options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'createdAt' | 'updatedAt' | 'languageCode' | 'code' | 'name'>)> })> });
 
 export type GetAssetListQueryVariables = {
   options?: Maybe<AssetListOptions>
@@ -3964,14 +3970,14 @@ export type SearchProductsQueryVariables = {
 };
 
 
-export type SearchProductsQuery = ({ __typename?: 'Query' } & { search: ({ __typename?: 'SearchResponse' } & Pick<SearchResponse, 'totalItems'> & { items: Array<({ __typename?: 'SearchResult' } & Pick<SearchResult, 'enabled' | 'productId' | 'productName' | 'productPreview' | 'productVariantId' | 'productVariantName' | 'productVariantPreview' | 'sku'>)>, facetValues: Array<({ __typename?: 'FacetValueResult' } & Pick<FacetValueResult, 'count'> & { facetValue: ({ __typename?: 'FacetValue' } & Pick<FacetValue, 'id' | 'name'> & { facet: ({ __typename?: 'Facet' } & Pick<Facet, 'id' | 'name'>) }) })> }) });
+export type SearchProductsQuery = ({ __typename?: 'Query' } & { search: ({ __typename?: 'SearchResponse' } & Pick<SearchResponse, 'totalItems'> & { items: Array<({ __typename?: 'SearchResult' } & Pick<SearchResult, 'enabled' | 'productId' | 'productName' | 'productPreview' | 'productVariantId' | 'productVariantName' | 'productVariantPreview' | 'sku'>)>, facetValues: Array<({ __typename?: 'FacetValueResult' } & Pick<FacetValueResult, 'count'> & { facetValue: ({ __typename?: 'FacetValue' } & Pick<FacetValue, 'id' | 'createdAt' | 'updatedAt' | 'name'> & { facet: ({ __typename?: 'Facet' } & Pick<Facet, 'id' | 'createdAt' | 'updatedAt' | 'name'>) }) })> }) });
 
 export type UpdateProductOptionMutationVariables = {
   input: UpdateProductOptionInput
 };
 
 
-export type UpdateProductOptionMutation = ({ __typename?: 'Mutation' } & { updateProductOption: ({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'code' | 'name'>) });
+export type UpdateProductOptionMutation = ({ __typename?: 'Mutation' } & { updateProductOption: ({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'createdAt' | 'updatedAt' | 'code' | 'name'>) });
 
 export type DeleteProductVariantMutationVariables = {
   id: Scalars['ID']
@@ -3985,7 +3991,7 @@ export type GetProductVariantOptionsQueryVariables = {
 };
 
 
-export type GetProductVariantOptionsQuery = ({ __typename?: 'Query' } & { product: Maybe<({ __typename?: 'Product' } & Pick<Product, 'id' | 'name'> & { optionGroups: Array<({ __typename?: 'ProductOptionGroup' } & Pick<ProductOptionGroup, 'id' | 'name' | 'code'> & { options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'name' | 'code'>)> })>, variants: Array<({ __typename?: 'ProductVariant' } & Pick<ProductVariant, 'id' | 'enabled' | 'name' | 'sku' | 'price' | 'stockOnHand' | 'enabled'> & { options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'name' | 'code' | 'groupId'>)> })> })> });
+export type GetProductVariantOptionsQuery = ({ __typename?: 'Query' } & { product: Maybe<({ __typename?: 'Product' } & Pick<Product, 'id' | 'createdAt' | 'updatedAt' | 'name'> & { optionGroups: Array<({ __typename?: 'ProductOptionGroup' } & Pick<ProductOptionGroup, 'id' | 'name' | 'code'> & { options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'createdAt' | 'updatedAt' | 'name' | 'code'>)> })>, variants: Array<({ __typename?: 'ProductVariant' } & Pick<ProductVariant, 'id' | 'createdAt' | 'updatedAt' | 'enabled' | 'name' | 'sku' | 'price' | 'stockOnHand' | 'enabled'> & { options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'createdAt' | 'updatedAt' | 'name' | 'code' | 'groupId'>)> })> })> });
 
 export type PromotionFragment = ({ __typename?: 'Promotion' } & Pick<Promotion, 'id' | 'createdAt' | 'updatedAt' | 'name' | 'enabled'> & { conditions: Array<({ __typename?: 'ConfigurableOperation' } & ConfigurableOperationFragment)>, actions: Array<({ __typename?: 'ConfigurableOperation' } & ConfigurableOperationFragment)> });
 
@@ -4029,7 +4035,7 @@ export type DeletePromotionMutationVariables = {
 
 export type DeletePromotionMutation = ({ __typename?: 'Mutation' } & { deletePromotion: ({ __typename?: 'DeletionResponse' } & Pick<DeletionResponse, 'result' | 'message'>) });
 
-export type CountryFragment = ({ __typename?: 'Country' } & Pick<Country, 'id' | 'code' | 'name' | 'enabled'> & { translations: Array<({ __typename?: 'CountryTranslation' } & Pick<CountryTranslation, 'id' | 'languageCode' | 'name'>)> });
+export type CountryFragment = ({ __typename?: 'Country' } & Pick<Country, 'id' | 'createdAt' | 'updatedAt' | 'code' | 'name' | 'enabled'> & { translations: Array<({ __typename?: 'CountryTranslation' } & Pick<CountryTranslation, 'id' | 'languageCode' | 'name'>)> });
 
 export type GetCountryListQueryVariables = {
   options?: Maybe<CountryListOptions>
@@ -4115,7 +4121,7 @@ export type RemoveMembersFromZoneMutationVariables = {
 
 export type RemoveMembersFromZoneMutation = ({ __typename?: 'Mutation' } & { removeMembersFromZone: ({ __typename?: 'Zone' } & ZoneFragment) });
 
-export type TaxCategoryFragment = ({ __typename?: 'TaxCategory' } & Pick<TaxCategory, 'id' | 'name'>);
+export type TaxCategoryFragment = ({ __typename?: 'TaxCategory' } & Pick<TaxCategory, 'id' | 'createdAt' | 'updatedAt' | 'name'>);
 
 export type GetTaxCategoriesQueryVariables = {};
 
@@ -4143,7 +4149,7 @@ export type UpdateTaxCategoryMutationVariables = {
 
 export type UpdateTaxCategoryMutation = ({ __typename?: 'Mutation' } & { updateTaxCategory: ({ __typename?: 'TaxCategory' } & TaxCategoryFragment) });
 
-export type TaxRateFragment = ({ __typename?: 'TaxRate' } & Pick<TaxRate, 'id' | 'name' | 'enabled' | 'value'> & { category: ({ __typename?: 'TaxCategory' } & Pick<TaxCategory, 'id' | 'name'>), zone: ({ __typename?: 'Zone' } & Pick<Zone, 'id' | 'name'>), customerGroup: Maybe<({ __typename?: 'CustomerGroup' } & Pick<CustomerGroup, 'id' | 'name'>)> });
+export type TaxRateFragment = ({ __typename?: 'TaxRate' } & Pick<TaxRate, 'id' | 'createdAt' | 'updatedAt' | 'name' | 'enabled' | 'value'> & { category: ({ __typename?: 'TaxCategory' } & Pick<TaxCategory, 'id' | 'name'>), zone: ({ __typename?: 'Zone' } & Pick<Zone, 'id' | 'name'>), customerGroup: Maybe<({ __typename?: 'CustomerGroup' } & Pick<CustomerGroup, 'id' | 'name'>)> });
 
 export type GetTaxRateListQueryVariables = {
   options?: Maybe<TaxRateListOptions>
@@ -4173,7 +4179,7 @@ export type UpdateTaxRateMutationVariables = {
 
 export type UpdateTaxRateMutation = ({ __typename?: 'Mutation' } & { updateTaxRate: ({ __typename?: 'TaxRate' } & TaxRateFragment) });
 
-export type ChannelFragment = ({ __typename?: 'Channel' } & Pick<Channel, 'id' | 'code' | 'token' | 'pricesIncludeTax' | 'currencyCode' | 'defaultLanguageCode'> & { defaultShippingZone: Maybe<({ __typename?: 'Zone' } & Pick<Zone, 'id' | 'name'>)>, defaultTaxZone: Maybe<({ __typename?: 'Zone' } & Pick<Zone, 'id' | 'name'>)> });
+export type ChannelFragment = ({ __typename?: 'Channel' } & Pick<Channel, 'id' | 'createdAt' | 'updatedAt' | 'code' | 'token' | 'pricesIncludeTax' | 'currencyCode' | 'defaultLanguageCode'> & { defaultShippingZone: Maybe<({ __typename?: 'Zone' } & Pick<Zone, 'id' | 'name'>)>, defaultTaxZone: Maybe<({ __typename?: 'Zone' } & Pick<Zone, 'id' | 'name'>)> });
 
 export type GetChannelsQueryVariables = {};
 
@@ -4206,7 +4212,7 @@ export type UpdateChannelMutationVariables = {
 
 export type UpdateChannelMutation = ({ __typename?: 'Mutation' } & { updateChannel: ({ __typename?: 'Channel' } & ChannelFragment) });
 
-export type PaymentMethodFragment = ({ __typename?: 'PaymentMethod' } & Pick<PaymentMethod, 'id' | 'code' | 'enabled'> & { configArgs: Array<({ __typename?: 'ConfigArg' } & Pick<ConfigArg, 'name' | 'type' | 'value'>)> });
+export type PaymentMethodFragment = ({ __typename?: 'PaymentMethod' } & Pick<PaymentMethod, 'id' | 'createdAt' | 'updatedAt' | 'code' | 'enabled'> & { configArgs: Array<({ __typename?: 'ConfigArg' } & Pick<ConfigArg, 'name' | 'type' | 'value'>)> });
 
 export type GetPaymentMethodListQueryVariables = {
   options: PaymentMethodListOptions

+ 14 - 2
packages/admin-ui/src/app/common/utilities/flatten-facet-values.spec.ts

@@ -8,6 +8,8 @@ describe('flattenFacetValues()', () => {
     it('works', () => {
         const facetValue1 = {
             id: '1',
+            createdAt: '',
+            updatedAt: '',
             languageCode: LanguageCode.en,
             code: 'Balistreri,_Lesch_and_Crooks',
             name: 'Balistreri, Lesch and Crooks',
@@ -16,6 +18,8 @@ describe('flattenFacetValues()', () => {
         };
         const facetValue2 = {
             id: '2',
+            createdAt: '',
+            updatedAt: '',
             languageCode: LanguageCode.en,
             code: 'Rodriguez_-_Von',
             name: 'Rodriguez - Von',
@@ -24,6 +28,8 @@ describe('flattenFacetValues()', () => {
         };
         const facetValue3 = {
             id: '3',
+            createdAt: '',
+            updatedAt: '',
             languageCode: LanguageCode.en,
             code: 'Hahn_and_Sons',
             name: 'Hahn and Sons',
@@ -32,6 +38,8 @@ describe('flattenFacetValues()', () => {
         };
         const facetValue4 = {
             id: '4',
+            createdAt: '',
+            updatedAt: '',
             languageCode: LanguageCode.en,
             code: 'Balistreri,_Lesch_and_Crooks',
             name: 'Balistreri, Lesch and Crooks',
@@ -40,6 +48,8 @@ describe('flattenFacetValues()', () => {
         };
         const facetValue5 = {
             id: '5',
+            createdAt: '',
+            updatedAt: '',
             languageCode: LanguageCode.en,
             code: 'Rodriguez_-_Von',
             name: 'Rodriguez - Von',
@@ -50,23 +60,25 @@ describe('flattenFacetValues()', () => {
         const input: FacetWithValues.Fragment[] = [
             {
                 id: '1',
+                createdAt: '',
+                updatedAt: '',
                 isPrivate: false,
                 languageCode: LanguageCode.en,
                 code: 'brand',
                 name: 'Brand',
                 translations: [],
                 values: [facetValue1, facetValue2, facetValue3],
-                updatedAt: '',
             },
             {
                 id: '2',
+                createdAt: '',
+                updatedAt: '',
                 isPrivate: false,
                 languageCode: LanguageCode.en,
                 code: 'type',
                 name: 'Type',
                 translations: [],
                 values: [facetValue4, facetValue5],
-                updatedAt: '',
             },
         ];
 

+ 1 - 0
packages/admin-ui/src/app/customer/components/address-card/address-card.component.html

@@ -59,6 +59,7 @@
         </div>
     </div>
     <div class="card-footer">
+        <vdr-entity-info [entity]="address"></vdr-entity-info>
         <button class="btn btn-sm btn-link" *ngIf="editing" (click)="editing = false">
             {{ 'common.done' | translate }}
         </button>

+ 4 - 1
packages/admin-ui/src/app/customer/components/customer-detail/customer-detail.component.html

@@ -1,6 +1,9 @@
 <vdr-action-bar>
     <vdr-ab-left>
-        <vdr-customer-status-label [customer]="entity$ | async"></vdr-customer-status-label>
+        <div class="flex clr-align-items-center">
+            <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
+            <vdr-customer-status-label [customer]="entity$ | async"></vdr-customer-status-label>
+        </div>
     </vdr-ab-left>
 
     <vdr-ab-right>

+ 2 - 0
packages/admin-ui/src/app/customer/providers/routing/customer-resolver.ts

@@ -11,6 +11,8 @@ export class CustomerResolver extends BaseEntityResolver<Customer.Fragment> {
             {
                 __typename: 'Customer',
                 id: '',
+                createdAt: '',
+                updatedAt: '',
                 title: '',
                 firstName: '',
                 lastName: '',

+ 4 - 0
packages/admin-ui/src/app/data/definitions/administrator-definitions.ts

@@ -3,6 +3,8 @@ import gql from 'graphql-tag';
 export const ADMINISTRATOR_FRAGMENT = gql`
     fragment Administrator on Administrator {
         id
+        createdAt
+        updatedAt
         firstName
         lastName
         emailAddress
@@ -23,6 +25,8 @@ export const ADMINISTRATOR_FRAGMENT = gql`
 export const ROLE_FRAGMENT = gql`
     fragment Role on Role {
         id
+        createdAt
+        updatedAt
         code
         description
         permissions

+ 2 - 0
packages/admin-ui/src/app/data/definitions/collection-definitions.ts

@@ -15,6 +15,8 @@ export const GET_COLLECTION_FILTERS = gql`
 export const COLLECTION_FRAGMENT = gql`
     fragment Collection on Collection {
         id
+        createdAt
+        updatedAt
         name
         description
         isPrivate

+ 4 - 0
packages/admin-ui/src/app/data/definitions/customer-definitions.ts

@@ -3,6 +3,8 @@ import gql from 'graphql-tag';
 export const ADDRESS_FRAGMENT = gql`
     fragment Address on Address {
         id
+        createdAt
+        updatedAt
         fullName
         company
         streetLine1
@@ -24,6 +26,8 @@ export const ADDRESS_FRAGMENT = gql`
 export const CUSTOMER_FRAGMENT = gql`
     fragment Customer on Customer {
         id
+        createdAt
+        updatedAt
         title
         firstName
         lastName

+ 5 - 0
packages/admin-ui/src/app/data/definitions/facet-definitions.ts

@@ -3,6 +3,8 @@ import gql from 'graphql-tag';
 export const FACET_VALUE_FRAGMENT = gql`
     fragment FacetValue on FacetValue {
         id
+        createdAt
+        updatedAt
         languageCode
         code
         name
@@ -13,6 +15,8 @@ export const FACET_VALUE_FRAGMENT = gql`
         }
         facet {
             id
+            createdAt
+            updatedAt
             name
         }
     }
@@ -21,6 +25,7 @@ export const FACET_VALUE_FRAGMENT = gql`
 export const FACET_WITH_VALUES_FRAGMENT = gql`
     fragment FacetWithValues on Facet {
         id
+        createdAt
         updatedAt
         languageCode
         isPrivate

+ 45 - 0
packages/admin-ui/src/app/data/definitions/product-definitions.ts

@@ -4,6 +4,7 @@ export const ASSET_FRAGMENT = gql`
     fragment Asset on Asset {
         id
         createdAt
+        updatedAt
         name
         fileSize
         mimeType
@@ -16,6 +17,8 @@ export const ASSET_FRAGMENT = gql`
 export const PRODUCT_VARIANT_FRAGMENT = gql`
     fragment ProductVariant on ProductVariant {
         id
+        createdAt
+        updatedAt
         enabled
         languageCode
         name
@@ -74,6 +77,8 @@ export const PRODUCT_VARIANT_FRAGMENT = gql`
 export const PRODUCT_WITH_VARIANTS_FRAGMENT = gql`
     fragment ProductWithVariants on Product {
         id
+        createdAt
+        updatedAt
         enabled
         languageCode
         name
@@ -86,6 +91,7 @@ export const PRODUCT_WITH_VARIANTS_FRAGMENT = gql`
             ...Asset
         }
         translations {
+            id
             languageCode
             name
             slug
@@ -117,10 +123,13 @@ export const PRODUCT_WITH_VARIANTS_FRAGMENT = gql`
 export const PRODUCT_OPTION_GROUP_FRAGMENT = gql`
     fragment ProductOptionGroup on ProductOptionGroup {
         id
+        createdAt
+        updatedAt
         languageCode
         code
         name
         translations {
+            id
             name
         }
         options {
@@ -202,6 +211,8 @@ export const ADD_OPTION_TO_GROUP = gql`
     mutation AddOptionToGroup($input: CreateProductOptionInput!) {
         createProductOption(input: $input) {
             id
+            createdAt
+            updatedAt
             name
             code
             groupId
@@ -213,11 +224,17 @@ export const ADD_OPTION_GROUP_TO_PRODUCT = gql`
     mutation AddOptionGroupToProduct($productId: ID!, $optionGroupId: ID!) {
         addOptionGroupToProduct(productId: $productId, optionGroupId: $optionGroupId) {
             id
+            createdAt
+            updatedAt
             optionGroups {
                 id
+                createdAt
+                updatedAt
                 code
                 options {
                     id
+                    createdAt
+                    updatedAt
                     code
                 }
             }
@@ -229,11 +246,17 @@ export const REMOVE_OPTION_GROUP_FROM_PRODUCT = gql`
     mutation RemoveOptionGroupFromProduct($productId: ID!, $optionGroupId: ID!) {
         removeOptionGroupFromProduct(productId: $productId, optionGroupId: $optionGroupId) {
             id
+            createdAt
+            updatedAt
             optionGroups {
                 id
+                createdAt
+                updatedAt
                 code
                 options {
                     id
+                    createdAt
+                    updatedAt
                     code
                 }
             }
@@ -255,12 +278,16 @@ export const GET_PRODUCT_LIST = gql`
         products(options: $options) {
             items {
                 id
+                createdAt
+                updatedAt
                 enabled
                 languageCode
                 name
                 slug
                 featuredAsset {
                     id
+                    createdAt
+                    updatedAt
                     preview
                 }
             }
@@ -273,11 +300,15 @@ export const GET_PRODUCT_OPTION_GROUPS = gql`
     query GetProductOptionGroups($filterTerm: String) {
         productOptionGroups(filterTerm: $filterTerm) {
             id
+            createdAt
+            updatedAt
             languageCode
             code
             name
             options {
                 id
+                createdAt
+                updatedAt
                 languageCode
                 code
                 name
@@ -325,9 +356,13 @@ export const SEARCH_PRODUCTS = gql`
                 count
                 facetValue {
                     id
+                    createdAt
+                    updatedAt
                     name
                     facet {
                         id
+                        createdAt
+                        updatedAt
                         name
                     }
                 }
@@ -340,6 +375,8 @@ export const UPDATE_PRODUCT_OPTION = gql`
     mutation UpdateProductOption($input: UpdateProductOptionInput!) {
         updateProductOption(input: $input) {
             id
+            createdAt
+            updatedAt
             code
             name
         }
@@ -359,6 +396,8 @@ export const GET_PRODUCT_VARIANT_OPTIONS = gql`
     query GetProductVariantOptions($id: ID!) {
         product(id: $id) {
             id
+            createdAt
+            updatedAt
             name
             optionGroups {
                 id
@@ -366,12 +405,16 @@ export const GET_PRODUCT_VARIANT_OPTIONS = gql`
                 code
                 options {
                     id
+                    createdAt
+                    updatedAt
                     name
                     code
                 }
             }
             variants {
                 id
+                createdAt
+                updatedAt
                 enabled
                 name
                 sku
@@ -380,6 +423,8 @@ export const GET_PRODUCT_VARIANT_OPTIONS = gql`
                 enabled
                 options {
                     id
+                    createdAt
+                    updatedAt
                     name
                     code
                     groupId

+ 10 - 0
packages/admin-ui/src/app/data/definitions/settings-definitions.ts

@@ -3,6 +3,8 @@ import gql from 'graphql-tag';
 export const COUNTRY_FRAGMENT = gql`
     fragment Country on Country {
         id
+        createdAt
+        updatedAt
         code
         name
         enabled
@@ -150,6 +152,8 @@ export const REMOVE_MEMBERS_FROM_ZONE = gql`
 export const TAX_CATEGORY_FRAGMENT = gql`
     fragment TaxCategory on TaxCategory {
         id
+        createdAt
+        updatedAt
         name
     }
 `;
@@ -193,6 +197,8 @@ export const UPDATE_TAX_CATEGORY = gql`
 export const TAX_RATE_FRAGMENT = gql`
     fragment TaxRate on TaxRate {
         id
+        createdAt
+        updatedAt
         name
         enabled
         value
@@ -253,6 +259,8 @@ export const UPDATE_TAX_RATE = gql`
 export const CHANNEL_FRAGMENT = gql`
     fragment Channel on Channel {
         id
+        createdAt
+        updatedAt
         code
         token
         pricesIncludeTax
@@ -317,6 +325,8 @@ export const UPDATE_CHANNEL = gql`
 export const PAYMENT_METHOD_FRAGMENT = gql`
     fragment PaymentMethod on PaymentMethod {
         id
+        createdAt
+        updatedAt
         code
         enabled
         configArgs {

+ 12 - 9
packages/admin-ui/src/app/marketing/components/promotion-detail/promotion-detail.component.html

@@ -1,14 +1,17 @@
 <vdr-action-bar>
     <vdr-ab-left>
-        <clr-toggle-wrapper *vdrIfPermissions="'UpdatePromotion'">
-            <input
-                type="checkbox"
-                clrToggle
-                name="enabled"
-                [formControl]="detailForm.get(['enabled'])"
-            />
-            <label>{{ 'common.enabled' | translate }}</label>
-        </clr-toggle-wrapper>
+        <div class="flex clr-align-items-center">
+            <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
+            <clr-toggle-wrapper *vdrIfPermissions="'UpdatePromotion'">
+                <input
+                    type="checkbox"
+                    clrToggle
+                    name="enabled"
+                    [formControl]="detailForm.get(['enabled'])"
+                />
+                <label>{{ 'common.enabled' | translate }}</label>
+            </clr-toggle-wrapper>
+        </div>
     </vdr-ab-left>
 
     <vdr-ab-right>

+ 2 - 5
packages/admin-ui/src/app/order/components/order-detail/order-detail.component.html

@@ -1,11 +1,8 @@
 <vdr-action-bar *ngIf="entity$ | async as order">
     <vdr-ab-left>
-        <div class="clr-row clr-flex-column">
+        <div class="flex clr-align-items-center">
+            <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
             <vdr-order-state-label [state]="order.state"></vdr-order-state-label>
-            <div class="date-detail">
-                {{ 'common.updated' | translate }}:
-                <strong>{{ order.updatedAt | date: 'medium' }}</strong>
-            </div>
         </div>
     </vdr-ab-left>
 

+ 0 - 5
packages/admin-ui/src/app/order/components/order-detail/order-detail.component.scss

@@ -1,11 +1,6 @@
 @import "variables";
 @import "mixins";
 
-.date-detail {
-    color: $color-grey-500;
-    padding-left: 6px;
-}
-
 .shipping-address {
     list-style-type: none;
     line-height: 1.3em;

+ 3 - 1
packages/admin-ui/src/app/settings/components/admin-detail/admin-detail.component.html

@@ -1,5 +1,7 @@
 <vdr-action-bar>
-    <vdr-ab-left></vdr-ab-left>
+    <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

+ 3 - 1
packages/admin-ui/src/app/settings/components/channel-detail/channel-detail.component.html

@@ -1,5 +1,7 @@
 <vdr-action-bar>
-    <vdr-ab-left></vdr-ab-left>
+    <vdr-ab-left>
+        <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
+    </vdr-ab-left>
 
     <vdr-ab-right>
         <vdr-action-bar-items locationId="channel-detail"></vdr-action-bar-items>

+ 1 - 0
packages/admin-ui/src/app/settings/components/country-detail/country-detail.component.html

@@ -1,5 +1,6 @@
 <vdr-action-bar>
     <vdr-ab-left>
+        <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
         <vdr-language-selector
             [disabled]="isNew$ | async"
             [availableLanguageCodes]="availableLanguages$ | async"

+ 3 - 1
packages/admin-ui/src/app/settings/components/payment-method-detail/payment-method-detail.component.html

@@ -1,5 +1,7 @@
 <vdr-action-bar>
-    <vdr-ab-left></vdr-ab-left>
+    <vdr-ab-left>
+        <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
+    </vdr-ab-left>
 
     <vdr-ab-right>
         <vdr-action-bar-items locationId="payment-method-detail"></vdr-action-bar-items>

+ 3 - 1
packages/admin-ui/src/app/settings/components/role-detail/role-detail.component.html

@@ -1,5 +1,7 @@
 <vdr-action-bar>
-    <vdr-ab-left></vdr-ab-left>
+    <vdr-ab-left>
+        <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
+    </vdr-ab-left>
     <vdr-ab-right>
         <vdr-action-bar-items locationId="role-detail"></vdr-action-bar-items>
         <button

+ 3 - 1
packages/admin-ui/src/app/settings/components/shipping-method-detail/shipping-method-detail.component.html

@@ -1,5 +1,7 @@
 <vdr-action-bar>
-    <vdr-ab-left></vdr-ab-left>
+    <vdr-ab-left>
+        <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
+    </vdr-ab-left>
 
     <vdr-ab-right>
         <vdr-action-bar-items locationId="shipping-method-detail"></vdr-action-bar-items>

+ 3 - 1
packages/admin-ui/src/app/settings/components/tax-category-detail/tax-category-detail.component.html

@@ -1,5 +1,7 @@
 <vdr-action-bar>
-    <vdr-ab-left></vdr-ab-left>
+    <vdr-ab-left>
+        <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
+    </vdr-ab-left>
 
     <vdr-ab-right>
         <vdr-action-bar-items locationId="tax-category-detail"></vdr-action-bar-items>

+ 3 - 1
packages/admin-ui/src/app/settings/components/tax-rate-detail/tax-rate-detail.component.html

@@ -1,5 +1,7 @@
 <vdr-action-bar>
-    <vdr-ab-left></vdr-ab-left>
+    <vdr-ab-left>
+        <vdr-entity-info [entity]="entity$ | async"></vdr-entity-info>
+    </vdr-ab-left>
 
     <vdr-ab-right>
         <vdr-action-bar-items locationId="tax-rate-detail"></vdr-action-bar-items>

+ 2 - 0
packages/admin-ui/src/app/settings/providers/routing/administrator-resolver.ts

@@ -11,6 +11,8 @@ export class AdministratorResolver extends BaseEntityResolver<Administrator.Frag
             {
                 __typename: 'Administrator' as 'Administrator',
                 id: '',
+                createdAt: '',
+                updatedAt: '',
                 emailAddress: '',
                 firstName: '',
                 lastName: '',

+ 2 - 0
packages/admin-ui/src/app/settings/providers/routing/channel-resolver.ts

@@ -15,6 +15,8 @@ export class ChannelResolver extends BaseEntityResolver<Channel.Fragment> {
             {
                 __typename: 'Channel',
                 id: '',
+                createdAt: '',
+                updatedAt: '',
                 code: '',
                 token: '',
                 pricesIncludeTax: false,

+ 2 - 0
packages/admin-ui/src/app/settings/providers/routing/country-resolver.ts

@@ -14,6 +14,8 @@ export class CountryResolver extends BaseEntityResolver<Country.Fragment> {
             {
                 __typename: 'Country',
                 id: '',
+                createdAt: '',
+                updatedAt: '',
                 code: '',
                 name: '',
                 enabled: false,

+ 2 - 0
packages/admin-ui/src/app/settings/providers/routing/payment-method-resolver.ts

@@ -14,6 +14,8 @@ export class PaymentMethodResolver extends BaseEntityResolver<PaymentMethod.Frag
             {
                 __typename: 'PaymentMethod',
                 id: '',
+                createdAt: '',
+                updatedAt: '',
                 code: '',
                 enabled: true,
                 configArgs: [],

+ 2 - 0
packages/admin-ui/src/app/settings/providers/routing/role-resolver.ts

@@ -11,6 +11,8 @@ export class RoleResolver extends BaseEntityResolver<Role.Fragment> {
             {
                 __typename: 'Role' as 'Role',
                 id: '',
+                createdAt: '',
+                updatedAt: '',
                 code: '',
                 description: '',
                 permissions: [],

+ 2 - 0
packages/admin-ui/src/app/settings/providers/routing/tax-category-resolver.ts

@@ -14,6 +14,8 @@ export class TaxCategoryResolver extends BaseEntityResolver<TaxCategory.Fragment
             {
                 __typename: 'TaxCategory',
                 id: '',
+                createdAt: '',
+                updatedAt: '',
                 name: '',
             },
             id => this.dataService.settings.getTaxCategory(id).mapStream(data => data.taxCategory),

+ 2 - 0
packages/admin-ui/src/app/settings/providers/routing/tax-rate-resolver.ts

@@ -14,6 +14,8 @@ export class TaxRateResolver extends BaseEntityResolver<TaxRate.Fragment> {
             {
                 __typename: 'TaxRate',
                 id: '',
+                createdAt: '',
+                updatedAt: '',
                 name: '',
                 value: 0,
                 enabled: true,

+ 8 - 1
packages/admin-ui/src/app/shared/components/asset-gallery/asset-gallery.component.html

@@ -9,7 +9,14 @@
             <div class="selected-checkbox"><clr-icon shape="check-circle" size="32"></clr-icon></div>
             <img [src]="asset.preview + '?preset=thumb'" />
         </div>
-        <div class="detail">{{ asset.name }}</div>
+        <div class="detail">
+            <vdr-entity-info
+                [entity]="asset"
+                [small]="true"
+                (click)="entityInfoClick($event)"
+            ></vdr-entity-info>
+            <span [title]="asset.name">{{ asset.name }}</span>
+        </div>
     </div>
 </div>
 <div class="info-bar">

+ 4 - 0
packages/admin-ui/src/app/shared/components/asset-gallery/asset-gallery.component.scss

@@ -25,6 +25,7 @@
 
 .card {
     margin-top: 0;
+    position: relative;
 }
 
 .selected-checkbox {
@@ -54,6 +55,9 @@
     overflow: hidden;
     white-space: nowrap;
     text-overflow: ellipsis;
+    vdr-entity-info {
+        height: 16px;
+    }
 }
 
 .info-bar {

+ 5 - 0
packages/admin-ui/src/app/shared/components/asset-gallery/asset-gallery.component.ts

@@ -59,4 +59,9 @@ export class AssetGalleryComponent {
             })
             .subscribe();
     }
+
+    entityInfoClick(event: MouseEvent) {
+        event.preventDefault();
+        event.stopPropagation();
+    }
 }

+ 18 - 0
packages/admin-ui/src/app/shared/components/entity-info/entity-info.component.html

@@ -0,0 +1,18 @@
+<vdr-dropdown *ngIf="entity.id">
+    <button class="btn btn-icon btn-link info-button" [class.btn-sm]="small" vdrDropdownTrigger>
+        <clr-icon shape="info-standard"></clr-icon>
+    </button>
+    <vdr-dropdown-menu>
+        <div class="entity-info">
+            <vdr-labeled-data [label]="'common.ID' | translate">
+                {{ entity.id }}
+            </vdr-labeled-data>
+            <vdr-labeled-data *ngIf="entity.createdAt" [label]="'common.created-at' | translate">
+                {{ entity.createdAt | date: 'medium' }}
+            </vdr-labeled-data>
+            <vdr-labeled-data *ngIf="entity.updatedAt" [label]="'common.updated-at' | translate">
+                {{ entity.updatedAt | date: 'medium' }}
+            </vdr-labeled-data>
+        </div>
+    </vdr-dropdown-menu>
+</vdr-dropdown>

+ 8 - 0
packages/admin-ui/src/app/shared/components/entity-info/entity-info.component.scss

@@ -0,0 +1,8 @@
+@import "variables";
+
+.info-button {
+    color: $color-grey-500;
+}
+.entity-info {
+    margin: 0 12px;
+}

+ 12 - 0
packages/admin-ui/src/app/shared/components/entity-info/entity-info.component.ts

@@ -0,0 +1,12 @@
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
+
+@Component({
+    selector: 'vdr-entity-info',
+    templateUrl: './entity-info.component.html',
+    styleUrls: ['./entity-info.component.scss'],
+    changeDetection: ChangeDetectionStrategy.OnPush,
+})
+export class EntityInfoComponent {
+    @Input() small = false;
+    @Input() entity: { id: string; createdAt?: string; updatedAt?: string };
+}

+ 1 - 0
packages/admin-ui/src/app/shared/shared-declarations.ts

@@ -46,6 +46,7 @@ export { SelectToggleComponent } from './components/select-toggle/select-toggle.
 export { SimpleDialogComponent } from './components/simple-dialog/simple-dialog.component';
 export { TableRowActionComponent } from './components/table-row-action/table-row-action.component';
 export { TitleInputComponent } from './components/title-input/title-input.component';
+export { EntityInfoComponent } from './components/entity-info/entity-info.component';
 export { CurrencyNamePipe } from './pipes/currency-name.pipe';
 export { FileSizePipe } from './pipes/file-size.pipe';
 export { SentenceCasePipe } from './pipes/sentence-case.pipe';

+ 2 - 0
packages/admin-ui/src/app/shared/shared.module.ts

@@ -39,6 +39,7 @@ import {
     DropdownItemDirective,
     DropdownMenuComponent,
     DropdownTriggerDirective,
+    EntityInfoComponent,
     FacetValueChipComponent,
     FacetValueSelectorComponent,
     FileSizePipe,
@@ -126,6 +127,7 @@ const DECLARATIONS = [
     AssetFileInputComponent,
     AssetGalleryComponent,
     AssetPickerDialogComponent,
+    EntityInfoComponent,
 ];
 
 @NgModule({

+ 4 - 0
packages/admin-ui/src/styles/theme/_theme.scss

@@ -13,6 +13,10 @@ a:focus, button:focus {
     outline-color: $color-primary-400;
 }
 
+.flex {
+    display: flex;
+}
+
 .flex-spacer {
     flex: 1;
 }