Explorar o código

feat(admin-ui): Extend custom field controls to support new options

Relates to #85
Michael Bromley %!s(int64=6) %!d(string=hai) anos
pai
achega
019cd029ca

+ 182 - 59
admin-ui/src/app/common/generated-types.ts

@@ -162,6 +162,14 @@ export enum AssetType {
   BINARY = 'BINARY'
 }
 
+export type BooleanCustomFieldConfig = CustomField & {
+  __typename?: 'BooleanCustomFieldConfig',
+  name: Scalars['String'],
+  type: Scalars['String'],
+  label?: Maybe<Array<LocalizedString>>,
+  description?: Maybe<Array<LocalizedString>>,
+};
+
 export type BooleanOperators = {
   eq?: Maybe<Scalars['Boolean']>,
 };
@@ -933,14 +941,16 @@ export type CustomerSortParameter = {
   emailAddress?: Maybe<SortOrder>,
 };
 
-export type CustomFieldConfig = {
-  __typename?: 'CustomFieldConfig',
+export type CustomField = {
+  __typename?: 'CustomField',
   name: Scalars['String'],
   type: Scalars['String'],
   label?: Maybe<Array<LocalizedString>>,
   description?: Maybe<Array<LocalizedString>>,
 };
 
+export type CustomFieldConfig = StringCustomFieldConfig | LocaleStringCustomFieldConfig | IntCustomFieldConfig | FloatCustomFieldConfig | BooleanCustomFieldConfig | DateTimeCustomFieldConfig;
+
 export type CustomFields = {
   __typename?: 'CustomFields',
   Address: Array<CustomFieldConfig>,
@@ -970,6 +980,20 @@ export type DateRange = {
 };
 
 
+/** Expects the same validation formats as the <input type="datetime-local"> HTML element.
+ * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local#Additional_attributes
+ */
+export type DateTimeCustomFieldConfig = CustomField & {
+  __typename?: 'DateTimeCustomFieldConfig',
+  name: Scalars['String'],
+  type: Scalars['String'],
+  label?: Maybe<Array<LocalizedString>>,
+  description?: Maybe<Array<LocalizedString>>,
+  min?: Maybe<Scalars['String']>,
+  max?: Maybe<Scalars['String']>,
+  step?: Maybe<Scalars['Int']>,
+};
+
 export type DeletionResponse = {
   __typename?: 'DeletionResponse',
   result: DeletionResult,
@@ -1081,6 +1105,17 @@ export type FacetValueTranslationInput = {
   customFields?: Maybe<Scalars['JSON']>,
 };
 
+export type FloatCustomFieldConfig = CustomField & {
+  __typename?: 'FloatCustomFieldConfig',
+  name: Scalars['String'],
+  type: Scalars['String'],
+  label?: Maybe<Array<LocalizedString>>,
+  description?: Maybe<Array<LocalizedString>>,
+  min?: Maybe<Scalars['Float']>,
+  max?: Maybe<Scalars['Float']>,
+  step?: Maybe<Scalars['Float']>,
+};
+
 export type Fulfillment = Node & {
   __typename?: 'Fulfillment',
   id: Scalars['ID'],
@@ -1159,6 +1194,17 @@ export type ImportInfo = {
   imported: Scalars['Int'],
 };
 
+export type IntCustomFieldConfig = CustomField & {
+  __typename?: 'IntCustomFieldConfig',
+  name: Scalars['String'],
+  type: Scalars['String'],
+  label?: Maybe<Array<LocalizedString>>,
+  description?: Maybe<Array<LocalizedString>>,
+  min?: Maybe<Scalars['Int']>,
+  max?: Maybe<Scalars['Int']>,
+  step?: Maybe<Scalars['Int']>,
+};
+
 export type JobInfo = {
   __typename?: 'JobInfo',
   id: Scalars['String'],
@@ -1556,6 +1602,15 @@ export enum LanguageCode {
   zu = 'zu'
 }
 
+export type LocaleStringCustomFieldConfig = CustomField & {
+  __typename?: 'LocaleStringCustomFieldConfig',
+  name: Scalars['String'],
+  type: Scalars['String'],
+  label?: Maybe<Array<LocalizedString>>,
+  description?: Maybe<Array<LocalizedString>>,
+  pattern?: Maybe<Scalars['String']>,
+};
+
 export type LocalizedString = {
   __typename?: 'LocalizedString',
   languageCode: LanguageCode,
@@ -1575,14 +1630,14 @@ export type MoveCollectionInput = {
 
 export type Mutation = {
   __typename?: 'Mutation',
-  /** Create a new Asset */
-  createAssets: Array<Asset>,
   /** Create a new Administrator */
   createAdministrator: Administrator,
   /** Update an existing Administrator */
   updateAdministrator: Administrator,
   /** Assign a Role to an Administrator */
   assignRoleToAdministrator: Administrator,
+  /** Create a new Asset */
+  createAssets: Array<Asset>,
   login: LoginResult,
   logout: Scalars['Boolean'],
   /** Create a new Channel */
@@ -1645,6 +1700,7 @@ export type Mutation = {
   addNoteToOrder: Order,
   /** Update an existing PaymentMethod */
   updatePaymentMethod: PaymentMethod,
+  reindex: JobInfo,
   /** Create a new ProductOptionGroup */
   createProductOptionGroup: ProductOptionGroup,
   /** Update an existing ProductOptionGroup */
@@ -1653,7 +1709,6 @@ export type Mutation = {
   createProductOption: ProductOption,
   /** Create a new ProductOption within a ProductOptionGroup */
   updateProductOption: ProductOption,
-  reindex: JobInfo,
   /** Create a new Product */
   createProduct: Product,
   /** Update an existing Product */
@@ -1685,6 +1740,10 @@ export type Mutation = {
   createTaxCategory: TaxCategory,
   /** Update an existing TaxCategory */
   updateTaxCategory: TaxCategory,
+  /** Create a new TaxRate */
+  createTaxRate: TaxRate,
+  /** Update an existing TaxRate */
+  updateTaxRate: TaxRate,
   /** Create a new Zone */
   createZone: Zone,
   /** Update an existing Zone */
@@ -1695,10 +1754,6 @@ export type Mutation = {
   addMembersToZone: Zone,
   /** Remove members from a Zone */
   removeMembersFromZone: Zone,
-  /** Create a new TaxRate */
-  createTaxRate: TaxRate,
-  /** Update an existing TaxRate */
-  updateTaxRate: TaxRate,
   requestStarted: Scalars['Int'],
   requestCompleted: Scalars['Int'],
   setAsLoggedIn: UserStatus,
@@ -1707,11 +1762,6 @@ export type Mutation = {
 };
 
 
-export type MutationCreateAssetsArgs = {
-  input: Array<CreateAssetInput>
-};
-
-
 export type MutationCreateAdministratorArgs = {
   input: CreateAdministratorInput
 };
@@ -1728,6 +1778,11 @@ export type MutationAssignRoleToAdministratorArgs = {
 };
 
 
+export type MutationCreateAssetsArgs = {
+  input: Array<CreateAssetInput>
+};
+
+
 export type MutationLoginArgs = {
   username: Scalars['String'],
   password: Scalars['String'],
@@ -2018,6 +2073,16 @@ export type MutationUpdateTaxCategoryArgs = {
 };
 
 
+export type MutationCreateTaxRateArgs = {
+  input: CreateTaxRateInput
+};
+
+
+export type MutationUpdateTaxRateArgs = {
+  input: UpdateTaxRateInput
+};
+
+
 export type MutationCreateZoneArgs = {
   input: CreateZoneInput
 };
@@ -2045,16 +2110,6 @@ export type MutationRemoveMembersFromZoneArgs = {
 };
 
 
-export type MutationCreateTaxRateArgs = {
-  input: CreateTaxRateInput
-};
-
-
-export type MutationUpdateTaxRateArgs = {
-  input: UpdateTaxRateInput
-};
-
-
 export type MutationSetAsLoggedInArgs = {
   username: Scalars['String'],
   loginTime: Scalars['String']
@@ -2566,10 +2621,10 @@ export type PromotionSortParameter = {
 
 export type Query = {
   __typename?: 'Query',
-  assets: AssetList,
-  asset?: Maybe<Asset>,
   administrators: AdministratorList,
   administrator?: Maybe<Administrator>,
+  assets: AssetList,
+  asset?: Maybe<Asset>,
   me?: Maybe<CurrentUser>,
   channels: Array<Channel>,
   channel?: Maybe<Channel>,
@@ -2592,9 +2647,9 @@ export type Query = {
   orders: OrderList,
   paymentMethods: PaymentMethodList,
   paymentMethod?: Maybe<PaymentMethod>,
+  search: SearchResponse,
   productOptionGroups: Array<ProductOptionGroup>,
   productOptionGroup?: Maybe<ProductOptionGroup>,
-  search: SearchResponse,
   products: ProductList,
   /** Get a Product either by id or slug. If neither id nor slug is speicified, an error will result. */
   product?: Maybe<Product>,
@@ -2609,32 +2664,32 @@ export type Query = {
   shippingCalculators: Array<ConfigurableOperation>,
   taxCategories: Array<TaxCategory>,
   taxCategory?: Maybe<TaxCategory>,
-  zones: Array<Zone>,
-  zone?: Maybe<Zone>,
   taxRates: TaxRateList,
   taxRate?: Maybe<TaxRate>,
+  zones: Array<Zone>,
+  zone?: Maybe<Zone>,
   networkStatus: NetworkStatus,
   userStatus: UserStatus,
   uiState: UiState,
 };
 
 
-export type QueryAssetsArgs = {
-  options?: Maybe<AssetListOptions>
+export type QueryAdministratorsArgs = {
+  options?: Maybe<AdministratorListOptions>
 };
 
 
-export type QueryAssetArgs = {
+export type QueryAdministratorArgs = {
   id: Scalars['ID']
 };
 
 
-export type QueryAdministratorsArgs = {
-  options?: Maybe<AdministratorListOptions>
+export type QueryAssetsArgs = {
+  options?: Maybe<AssetListOptions>
 };
 
 
-export type QueryAdministratorArgs = {
+export type QueryAssetArgs = {
   id: Scalars['ID']
 };
 
@@ -2723,6 +2778,11 @@ export type QueryPaymentMethodArgs = {
 };
 
 
+export type QuerySearchArgs = {
+  input: SearchInput
+};
+
+
 export type QueryProductOptionGroupsArgs = {
   languageCode?: Maybe<LanguageCode>,
   filterTerm?: Maybe<Scalars['String']>
@@ -2735,11 +2795,6 @@ export type QueryProductOptionGroupArgs = {
 };
 
 
-export type QuerySearchArgs = {
-  input: SearchInput
-};
-
-
 export type QueryProductsArgs = {
   languageCode?: Maybe<LanguageCode>,
   options?: Maybe<ProductListOptions>
@@ -2788,11 +2843,6 @@ export type QueryTaxCategoryArgs = {
 };
 
 
-export type QueryZoneArgs = {
-  id: Scalars['ID']
-};
-
-
 export type QueryTaxRatesArgs = {
   options?: Maybe<TaxRateListOptions>
 };
@@ -2802,6 +2852,11 @@ export type QueryTaxRateArgs = {
   id: Scalars['ID']
 };
 
+
+export type QueryZoneArgs = {
+  id: Scalars['ID']
+};
+
 export type Refund = Node & {
   __typename?: 'Refund',
   id: Scalars['ID'],
@@ -3053,6 +3108,22 @@ export enum StockMovementType {
   RETURN = 'RETURN'
 }
 
+export type StringCustomFieldConfig = CustomField & {
+  __typename?: 'StringCustomFieldConfig',
+  name: Scalars['String'],
+  type: Scalars['String'],
+  label?: Maybe<Array<LocalizedString>>,
+  description?: Maybe<Array<LocalizedString>>,
+  pattern?: Maybe<Scalars['String']>,
+  options?: Maybe<Array<StringFieldOption>>,
+};
+
+export type StringFieldOption = {
+  __typename?: 'StringFieldOption',
+  value: Scalars['String'],
+  label?: Maybe<Array<LocalizedString>>,
+};
+
 export type StringOperators = {
   eq?: Maybe<Scalars['String']>,
   contains?: Maybe<Scalars['String']>,
@@ -4078,12 +4149,26 @@ export type UpdateGlobalSettingsMutationVariables = {
 
 export type UpdateGlobalSettingsMutation = ({ __typename?: 'Mutation' } & { updateGlobalSettings: ({ __typename?: 'GlobalSettings' } & GlobalSettingsFragment) });
 
-export type CustomFieldConfigFragment = ({ __typename?: 'CustomFieldConfig' } & Pick<CustomFieldConfig, 'name' | 'type'>);
+export type CustomFieldConfigFragment = ({ __typename?: 'StringCustomFieldConfig' | 'LocaleStringCustomFieldConfig' | 'IntCustomFieldConfig' | 'FloatCustomFieldConfig' | 'BooleanCustomFieldConfig' | 'DateTimeCustomFieldConfig' } & Pick<CustomField, 'name' | 'type'> & { description: Maybe<Array<({ __typename?: 'LocalizedString' } & Pick<LocalizedString, 'languageCode' | 'value'>)>>, label: Maybe<Array<({ __typename?: 'LocalizedString' } & Pick<LocalizedString, 'languageCode' | 'value'>)>> });
+
+export type StringCustomFieldFragment = ({ __typename?: 'StringCustomFieldConfig' } & Pick<StringCustomFieldConfig, 'pattern'> & { options: Maybe<Array<({ __typename?: 'StringFieldOption' } & Pick<StringFieldOption, 'value'> & { label: Maybe<Array<({ __typename?: 'LocalizedString' } & Pick<LocalizedString, 'languageCode' | 'value'>)>> })>> } & CustomFieldConfigFragment);
+
+export type LocaleStringCustomFieldFragment = ({ __typename?: 'LocaleStringCustomFieldConfig' } & Pick<LocaleStringCustomFieldConfig, 'pattern'> & CustomFieldConfigFragment);
+
+export type BooleanCustomFieldFragment = ({ __typename?: 'BooleanCustomFieldConfig' } & CustomFieldConfigFragment);
+
+export type IntCustomFieldFragment = ({ __typename?: 'IntCustomFieldConfig' } & { intMin: IntCustomFieldConfig['min'], intMax: IntCustomFieldConfig['max'], intStep: IntCustomFieldConfig['step'] } & CustomFieldConfigFragment);
+
+export type FloatCustomFieldFragment = ({ __typename?: 'FloatCustomFieldConfig' } & { floatMin: FloatCustomFieldConfig['min'], floatMax: FloatCustomFieldConfig['max'], floatStep: FloatCustomFieldConfig['step'] } & CustomFieldConfigFragment);
+
+export type DateTimeCustomFieldFragment = ({ __typename?: 'DateTimeCustomFieldConfig' } & { datetimeMin: DateTimeCustomFieldConfig['min'], datetimeMax: DateTimeCustomFieldConfig['max'], datetimeStep: DateTimeCustomFieldConfig['step'] } & CustomFieldConfigFragment);
+
+export type CustomFieldsFragment = ({ __typename?: 'StringCustomFieldConfig' | 'LocaleStringCustomFieldConfig' | 'IntCustomFieldConfig' | 'FloatCustomFieldConfig' | 'BooleanCustomFieldConfig' | 'DateTimeCustomFieldConfig' } & (({ __typename?: 'StringCustomFieldConfig' } & StringCustomFieldFragment) | ({ __typename?: 'LocaleStringCustomFieldConfig' } & LocaleStringCustomFieldFragment) | ({ __typename?: 'BooleanCustomFieldConfig' } & BooleanCustomFieldFragment) | ({ __typename?: 'IntCustomFieldConfig' } & IntCustomFieldFragment) | ({ __typename?: 'FloatCustomFieldConfig' } & FloatCustomFieldFragment) | ({ __typename?: 'DateTimeCustomFieldConfig' } & DateTimeCustomFieldFragment)));
 
 export type GetServerConfigQueryVariables = {};
 
 
-export type GetServerConfigQuery = ({ __typename?: 'Query' } & { globalSettings: ({ __typename?: 'GlobalSettings' } & { serverConfig: ({ __typename?: 'ServerConfig' } & { customFieldConfig: ({ __typename?: 'CustomFields' } & { Address: Array<({ __typename?: 'CustomFieldConfig' } & CustomFieldConfigFragment)>, Collection: Array<({ __typename?: 'CustomFieldConfig' } & CustomFieldConfigFragment)>, Customer: Array<({ __typename?: 'CustomFieldConfig' } & CustomFieldConfigFragment)>, Facet: Array<({ __typename?: 'CustomFieldConfig' } & CustomFieldConfigFragment)>, FacetValue: Array<({ __typename?: 'CustomFieldConfig' } & CustomFieldConfigFragment)>, GlobalSettings: Array<({ __typename?: 'CustomFieldConfig' } & CustomFieldConfigFragment)>, OrderLine: Array<({ __typename?: 'CustomFieldConfig' } & CustomFieldConfigFragment)>, Product: Array<({ __typename?: 'CustomFieldConfig' } & CustomFieldConfigFragment)>, ProductOption: Array<({ __typename?: 'CustomFieldConfig' } & CustomFieldConfigFragment)>, ProductOptionGroup: Array<({ __typename?: 'CustomFieldConfig' } & CustomFieldConfigFragment)>, ProductVariant: Array<({ __typename?: 'CustomFieldConfig' } & CustomFieldConfigFragment)>, User: Array<({ __typename?: 'CustomFieldConfig' } & CustomFieldConfigFragment)> }) }) }) });
+export type GetServerConfigQuery = ({ __typename?: 'Query' } & { globalSettings: ({ __typename?: 'GlobalSettings' } & { serverConfig: ({ __typename?: 'ServerConfig' } & { customFieldConfig: ({ __typename?: 'CustomFields' } & { Address: Array<CustomFieldsFragment>, Collection: Array<CustomFieldsFragment>, Customer: Array<CustomFieldsFragment>, Facet: Array<CustomFieldsFragment>, FacetValue: Array<CustomFieldsFragment>, GlobalSettings: Array<CustomFieldsFragment>, OrderLine: Array<CustomFieldsFragment>, Product: Array<CustomFieldsFragment>, ProductOption: Array<CustomFieldsFragment>, ProductOptionGroup: Array<CustomFieldsFragment>, ProductVariant: Array<CustomFieldsFragment>, User: Array<CustomFieldsFragment> }) }) }) });
 
 export type JobInfoFragment = ({ __typename?: 'JobInfo' } & Pick<JobInfo, 'id' | 'name' | 'state' | 'progress' | 'duration' | 'result'>);
 
@@ -4955,6 +5040,44 @@ export namespace UpdateGlobalSettings {
 
 export namespace CustomFieldConfig {
   export type Fragment = CustomFieldConfigFragment;
+  export type Description = (NonNullable<(NonNullable<CustomFieldConfigFragment['description']>)[0]>);
+  export type Label = (NonNullable<(NonNullable<CustomFieldConfigFragment['label']>)[0]>);
+}
+
+export namespace StringCustomField {
+  export type Fragment = CustomFieldConfigFragment;
+  export type Options = (NonNullable<(NonNullable<StringCustomFieldFragment['options']>)[0]>);
+  export type Label = (NonNullable<(NonNullable<(NonNullable<(NonNullable<StringCustomFieldFragment['options']>)[0]>)['label']>)[0]>);
+}
+
+export namespace LocaleStringCustomField {
+  export type Fragment = CustomFieldConfigFragment;
+}
+
+export namespace BooleanCustomField {
+  export type Fragment = CustomFieldConfigFragment;
+}
+
+export namespace IntCustomField {
+  export type Fragment = CustomFieldConfigFragment;
+}
+
+export namespace FloatCustomField {
+  export type Fragment = CustomFieldConfigFragment;
+}
+
+export namespace DateTimeCustomField {
+  export type Fragment = CustomFieldConfigFragment;
+}
+
+export namespace CustomFields {
+  export type Fragment = CustomFieldsFragment;
+  export type StringCustomFieldConfigInlineFragment = StringCustomFieldFragment;
+  export type LocaleStringCustomFieldConfigInlineFragment = LocaleStringCustomFieldFragment;
+  export type BooleanCustomFieldConfigInlineFragment = BooleanCustomFieldFragment;
+  export type IntCustomFieldConfigInlineFragment = IntCustomFieldFragment;
+  export type FloatCustomFieldConfigInlineFragment = FloatCustomFieldFragment;
+  export type DateTimeCustomFieldConfigInlineFragment = DateTimeCustomFieldFragment;
 }
 
 export namespace GetServerConfig {
@@ -4963,18 +5086,18 @@ export namespace GetServerConfig {
   export type GlobalSettings = GetServerConfigQuery['globalSettings'];
   export type ServerConfig = GetServerConfigQuery['globalSettings']['serverConfig'];
   export type CustomFieldConfig = GetServerConfigQuery['globalSettings']['serverConfig']['customFieldConfig'];
-  export type Address = CustomFieldConfigFragment;
-  export type Collection = CustomFieldConfigFragment;
-  export type Customer = CustomFieldConfigFragment;
-  export type Facet = CustomFieldConfigFragment;
-  export type FacetValue = CustomFieldConfigFragment;
-  export type _GlobalSettings = CustomFieldConfigFragment;
-  export type OrderLine = CustomFieldConfigFragment;
-  export type Product = CustomFieldConfigFragment;
-  export type ProductOption = CustomFieldConfigFragment;
-  export type ProductOptionGroup = CustomFieldConfigFragment;
-  export type ProductVariant = CustomFieldConfigFragment;
-  export type User = CustomFieldConfigFragment;
+  export type Address = CustomFieldsFragment;
+  export type Collection = CustomFieldsFragment;
+  export type Customer = CustomFieldsFragment;
+  export type Facet = CustomFieldsFragment;
+  export type FacetValue = CustomFieldsFragment;
+  export type _GlobalSettings = CustomFieldsFragment;
+  export type OrderLine = CustomFieldsFragment;
+  export type Product = CustomFieldsFragment;
+  export type ProductOption = CustomFieldsFragment;
+  export type ProductOptionGroup = CustomFieldsFragment;
+  export type ProductVariant = CustomFieldsFragment;
+  export type User = CustomFieldsFragment;
 }
 
 export namespace JobInfo {

+ 272 - 0
admin-ui/src/app/common/introspection-result.ts

@@ -0,0 +1,272 @@
+export interface IntrospectionResultData {
+    __schema: {
+        types: Array<{
+            kind: string;
+            name: string;
+            possibleTypes: Array<{
+                name: string;
+            }>;
+        }>;
+    };
+}
+
+const result: IntrospectionResultData = {
+    __schema: {
+        types: [
+            {
+                kind: 'INTERFACE',
+                name: 'PaginatedList',
+                possibleTypes: [
+                    {
+                        name: 'AdministratorList',
+                    },
+                    {
+                        name: 'AssetList',
+                    },
+                    {
+                        name: 'CollectionList',
+                    },
+                    {
+                        name: 'ProductVariantList',
+                    },
+                    {
+                        name: 'OrderList',
+                    },
+                    {
+                        name: 'HistoryEntryList',
+                    },
+                    {
+                        name: 'CountryList',
+                    },
+                    {
+                        name: 'CustomerList',
+                    },
+                    {
+                        name: 'FacetList',
+                    },
+                    {
+                        name: 'PaymentMethodList',
+                    },
+                    {
+                        name: 'ProductList',
+                    },
+                    {
+                        name: 'PromotionList',
+                    },
+                    {
+                        name: 'RoleList',
+                    },
+                    {
+                        name: 'ShippingMethodList',
+                    },
+                    {
+                        name: 'TaxRateList',
+                    },
+                ],
+            },
+            {
+                kind: 'INTERFACE',
+                name: 'Node',
+                possibleTypes: [
+                    {
+                        name: 'Administrator',
+                    },
+                    {
+                        name: 'User',
+                    },
+                    {
+                        name: 'Role',
+                    },
+                    {
+                        name: 'Channel',
+                    },
+                    {
+                        name: 'Zone',
+                    },
+                    {
+                        name: 'Country',
+                    },
+                    {
+                        name: 'Asset',
+                    },
+                    {
+                        name: 'Collection',
+                    },
+                    {
+                        name: 'ProductVariant',
+                    },
+                    {
+                        name: 'TaxRate',
+                    },
+                    {
+                        name: 'TaxCategory',
+                    },
+                    {
+                        name: 'CustomerGroup',
+                    },
+                    {
+                        name: 'ProductOption',
+                    },
+                    {
+                        name: 'FacetValue',
+                    },
+                    {
+                        name: 'Facet',
+                    },
+                    {
+                        name: 'StockAdjustment',
+                    },
+                    {
+                        name: 'Sale',
+                    },
+                    {
+                        name: 'OrderLine',
+                    },
+                    {
+                        name: 'OrderItem',
+                    },
+                    {
+                        name: 'Fulfillment',
+                    },
+                    {
+                        name: 'Order',
+                    },
+                    {
+                        name: 'Customer',
+                    },
+                    {
+                        name: 'Address',
+                    },
+                    {
+                        name: 'Payment',
+                    },
+                    {
+                        name: 'Refund',
+                    },
+                    {
+                        name: 'ShippingMethod',
+                    },
+                    {
+                        name: 'HistoryEntry',
+                    },
+                    {
+                        name: 'Cancellation',
+                    },
+                    {
+                        name: 'Return',
+                    },
+                    {
+                        name: 'PaymentMethod',
+                    },
+                    {
+                        name: 'ProductOptionGroup',
+                    },
+                    {
+                        name: 'Product',
+                    },
+                    {
+                        name: 'Promotion',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'StockMovementItem',
+                possibleTypes: [
+                    {
+                        name: 'StockAdjustment',
+                    },
+                    {
+                        name: 'Sale',
+                    },
+                    {
+                        name: 'Cancellation',
+                    },
+                    {
+                        name: 'Return',
+                    },
+                ],
+            },
+            {
+                kind: 'INTERFACE',
+                name: 'StockMovement',
+                possibleTypes: [
+                    {
+                        name: 'StockAdjustment',
+                    },
+                    {
+                        name: 'Sale',
+                    },
+                    {
+                        name: 'Cancellation',
+                    },
+                    {
+                        name: 'Return',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'CustomFieldConfig',
+                possibleTypes: [
+                    {
+                        name: 'StringCustomFieldConfig',
+                    },
+                    {
+                        name: 'LocaleStringCustomFieldConfig',
+                    },
+                    {
+                        name: 'IntCustomFieldConfig',
+                    },
+                    {
+                        name: 'FloatCustomFieldConfig',
+                    },
+                    {
+                        name: 'BooleanCustomFieldConfig',
+                    },
+                    {
+                        name: 'DateTimeCustomFieldConfig',
+                    },
+                ],
+            },
+            {
+                kind: 'INTERFACE',
+                name: 'CustomField',
+                possibleTypes: [
+                    {
+                        name: 'StringCustomFieldConfig',
+                    },
+                    {
+                        name: 'LocaleStringCustomFieldConfig',
+                    },
+                    {
+                        name: 'IntCustomFieldConfig',
+                    },
+                    {
+                        name: 'FloatCustomFieldConfig',
+                    },
+                    {
+                        name: 'BooleanCustomFieldConfig',
+                    },
+                    {
+                        name: 'DateTimeCustomFieldConfig',
+                    },
+                ],
+            },
+            {
+                kind: 'UNION',
+                name: 'SearchResultPrice',
+                possibleTypes: [
+                    {
+                        name: 'PriceRange',
+                    },
+                    {
+                        name: 'SinglePrice',
+                    },
+                ],
+            },
+        ],
+    },
+};
+
+export default result;

+ 7 - 2
admin-ui/src/app/data/data.module.ts

@@ -1,7 +1,7 @@
 import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
 import { APP_INITIALIZER, NgModule } from '@angular/core';
 import { APOLLO_OPTIONS, ApolloModule } from 'apollo-angular';
-import { InMemoryCache } from 'apollo-cache-inmemory';
+import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
 import { ApolloClientOptions } from 'apollo-client';
 import { ApolloLink } from 'apollo-link';
 import { setContext } from 'apollo-link-context';
@@ -9,6 +9,7 @@ import { createUploadLink } from 'apollo-upload-client';
 
 import { environment } from '../../environments/environment';
 import { getAppConfig } from '../app.config';
+import introspectionResult from '../common/introspection-result';
 import { LocalStorageService } from '../core/providers/local-storage/local-storage.service';
 
 import { clientDefaults } from './client-state/client-defaults';
@@ -27,7 +28,11 @@ export function createApollo(
     const { apiHost, apiPort, adminApiPath } = getAppConfig();
     const host = apiHost === 'auto' ? `${location.protocol}//${location.hostname}` : apiHost;
     const port = apiPort === 'auto' ? (location.port === '' ? '' : `:${location.port}`) : `:${apiPort}`;
-    const apolloCache = new InMemoryCache();
+    const apolloCache = new InMemoryCache({
+        fragmentMatcher: new IntrospectionFragmentMatcher({
+            introspectionQueryResultData: introspectionResult,
+        }),
+    });
     apolloCache.writeData({
         data: clientDefaults,
     });

+ 106 - 14
admin-ui/src/app/data/definitions/settings-definitions.ts

@@ -383,10 +383,102 @@ export const UPDATE_GLOBAL_SETTINGS = gql`
 `;
 
 export const CUSTOM_FIELD_CONFIG_FRAGMENT = gql`
-    fragment CustomFieldConfig on CustomFieldConfig {
+    fragment CustomFieldConfig on CustomField {
         name
         type
+        description {
+            languageCode
+            value
+        }
+        label {
+            languageCode
+            value
+        }
+    }
+`;
+
+export const STRING_CUSTOM_FIELD_FRAGMENT = gql`
+    fragment StringCustomField on StringCustomFieldConfig {
+        ...CustomFieldConfig
+        pattern
+        options {
+            label {
+                languageCode
+                value
+            }
+            value
+        }
+    }
+    ${CUSTOM_FIELD_CONFIG_FRAGMENT}
+`;
+export const LOCALE_STRING_CUSTOM_FIELD_FRAGMENT = gql`
+    fragment LocaleStringCustomField on LocaleStringCustomFieldConfig {
+        ...CustomFieldConfig
+        pattern
+    }
+    ${CUSTOM_FIELD_CONFIG_FRAGMENT}
+`;
+export const BOOLEAN_CUSTOM_FIELD_FRAGMENT = gql`
+    fragment BooleanCustomField on BooleanCustomFieldConfig {
+        ...CustomFieldConfig
+    }
+    ${CUSTOM_FIELD_CONFIG_FRAGMENT}
+`;
+export const INT_CUSTOM_FIELD_FRAGMENT = gql`
+    fragment IntCustomField on IntCustomFieldConfig {
+        ...CustomFieldConfig
+        intMin: min
+        intMax: max
+        intStep: step
+    }
+    ${CUSTOM_FIELD_CONFIG_FRAGMENT}
+`;
+export const FLOAT_CUSTOM_FIELD_FRAGMENT = gql`
+    fragment FloatCustomField on FloatCustomFieldConfig {
+        ...CustomFieldConfig
+        floatMin: min
+        floatMax: max
+        floatStep: step
     }
+    ${CUSTOM_FIELD_CONFIG_FRAGMENT}
+`;
+export const DATE_TIME_CUSTOM_FIELD_FRAGMENT = gql`
+    fragment DateTimeCustomField on DateTimeCustomFieldConfig {
+        ...CustomFieldConfig
+        datetimeMin: min
+        datetimeMax: max
+        datetimeStep: step
+    }
+    ${CUSTOM_FIELD_CONFIG_FRAGMENT}
+`;
+
+export const ALL_CUSTOM_FIELDS_FRAGMENT = gql`
+    fragment CustomFields on CustomField {
+        ... on StringCustomFieldConfig {
+            ...StringCustomField
+        }
+        ... on LocaleStringCustomFieldConfig {
+            ...LocaleStringCustomField
+        }
+        ... on BooleanCustomFieldConfig {
+            ...BooleanCustomField
+        }
+        ... on IntCustomFieldConfig {
+            ...IntCustomField
+        }
+        ... on FloatCustomFieldConfig {
+            ...FloatCustomField
+        }
+        ... on DateTimeCustomFieldConfig {
+            ...DateTimeCustomField
+        }
+    }
+    ${STRING_CUSTOM_FIELD_FRAGMENT}
+    ${LOCALE_STRING_CUSTOM_FIELD_FRAGMENT}
+    ${BOOLEAN_CUSTOM_FIELD_FRAGMENT}
+    ${INT_CUSTOM_FIELD_FRAGMENT}
+    ${FLOAT_CUSTOM_FIELD_FRAGMENT}
+    ${DATE_TIME_CUSTOM_FIELD_FRAGMENT}
 `;
 
 export const GET_SERVER_CONFIG = gql`
@@ -395,46 +487,46 @@ export const GET_SERVER_CONFIG = gql`
             serverConfig {
                 customFieldConfig {
                     Address {
-                        ...CustomFieldConfig
+                        ...CustomFields
                     }
                     Collection {
-                        ...CustomFieldConfig
+                        ...CustomFields
                     }
                     Customer {
-                        ...CustomFieldConfig
+                        ...CustomFields
                     }
                     Facet {
-                        ...CustomFieldConfig
+                        ...CustomFields
                     }
                     FacetValue {
-                        ...CustomFieldConfig
+                        ...CustomFields
                     }
                     GlobalSettings {
-                        ...CustomFieldConfig
+                        ...CustomFields
                     }
                     OrderLine {
-                        ...CustomFieldConfig
+                        ...CustomFields
                     }
                     Product {
-                        ...CustomFieldConfig
+                        ...CustomFields
                     }
                     ProductOption {
-                        ...CustomFieldConfig
+                        ...CustomFields
                     }
                     ProductOptionGroup {
-                        ...CustomFieldConfig
+                        ...CustomFields
                     }
                     ProductVariant {
-                        ...CustomFieldConfig
+                        ...CustomFields
                     }
                     User {
-                        ...CustomFieldConfig
+                        ...CustomFields
                     }
                 }
             }
         }
     }
-    ${CUSTOM_FIELD_CONFIG_FRAGMENT}
+    ${ALL_CUSTOM_FIELDS_FRAGMENT}
 `;
 
 export const JOB_INFO_FRAGMENT = gql`

+ 16 - 4
admin-ui/src/app/shared/components/custom-field-control/custom-field-control.component.html

@@ -1,14 +1,23 @@
 <vdr-form-field [label]="label" [for]="customField.name">
     <input
-        *ngIf="customField.type === 'string' || customField.type === 'localeString'"
+        *ngIf="isTextInput"
         type="text"
         [id]="customField.name"
+        [pattern]="customField.pattern"
         [formControl]="formGroup.get(customField.name)"
     />
+    <select *ngIf="isSelectInput" clrSelect [formControl]="formGroup.get(customField.name)">
+        <option *ngFor="let option of stringOptions" [value]="option.value">
+            {{ getLabel(option.value, option.label) }}
+        </option>
+    </select>
     <input
         *ngIf="customField.type === 'int' || customField.type === 'float'"
         type="number"
         [id]="customField.name"
+        [min]="min"
+        [max]="max"
+        [step]="step"
         [formControl]="formGroup.get(customField.name)"
     />
     <clr-toggle-wrapper *ngIf="customField.type === 'boolean'">
@@ -21,9 +30,12 @@
     </clr-toggle-wrapper>
     <input
         *ngIf="customField.type === 'datetime'"
-        type="date"
+        type="datetime-local"
+        [min]="min"
+        [max]="max"
+        [step]="step"
         [id]="customField.name"
-        [formControl]="formGroup.get(customField.name)"
-        clrDate
+        [value]="formGroup.get(customField.name).value | date: 'yyyy-MM-ddTHH:mm:ss'"
+        (change)="updateDateTime(formGroup.get(customField.name), $event)"
     />
 </vdr-form-field>

+ 104 - 8
admin-ui/src/app/shared/components/custom-field-control/custom-field-control.component.ts

@@ -1,7 +1,15 @@
-import { Component, Input, OnInit } from '@angular/core';
-import { FormGroup } from '@angular/forms';
+import { Component, Input, OnDestroy, OnInit } from '@angular/core';
+import { FormControl, FormGroup } from '@angular/forms';
+import { Subscription } from 'rxjs';
 
-import { CustomFieldConfig } from '../../../common/generated-types';
+import {
+    CustomFieldConfig,
+    CustomFieldsFragment,
+    GetServerConfig,
+    LanguageCode,
+    LocalizedString,
+} from '../../../common/generated-types';
+import { DataService } from '../../../data/providers/data.service';
 
 /**
  * This component renders the appropriate type of form input control based
@@ -12,15 +20,103 @@ import { CustomFieldConfig } from '../../../common/generated-types';
     templateUrl: './custom-field-control.component.html',
     styleUrls: ['./custom-field-control.component.scss'],
 })
-export class CustomFieldControlComponent implements OnInit {
+export class CustomFieldControlComponent implements OnInit, OnDestroy {
     @Input('customFieldsFormGroup') formGroup: FormGroup;
-    @Input() customField: CustomFieldConfig;
+    @Input() customField: CustomFieldsFragment;
     @Input() showLabel = true;
-    label: string;
+    private uiLanguageCode: LanguageCode;
+    private sub: Subscription;
 
-    ngOnInit() {
+    constructor(private dataService: DataService) {}
+
+    ngOnInit(): void {
+        this.sub = this.dataService.client
+            .uiState()
+            .mapStream(data => data.uiState.language)
+            .subscribe(language => {
+                this.uiLanguageCode = language;
+            });
+    }
+
+    ngOnDestroy(): void {
+        if (this.sub) {
+            this.sub.unsubscribe();
+        }
+    }
+
+    get isTextInput(): boolean {
+        if (this.customField.__typename === 'StringCustomFieldConfig') {
+            return !this.customField.options;
+        } else {
+            return this.customField.__typename === 'LocaleStringCustomFieldConfig';
+        }
+    }
+
+    get isSelectInput(): boolean {
+        if (this.customField.__typename === 'StringCustomFieldConfig') {
+            return !!this.customField.options;
+        }
+        return false;
+    }
+
+    get stringOptions() {
+        if (this.customField.__typename === 'StringCustomFieldConfig') {
+            return this.customField.options || [];
+        }
+        return [];
+    }
+
+    get label(): string | undefined {
         if (this.showLabel) {
-            this.label = this.customField.name;
+            return this.getLabel(this.customField.name, this.customField.label);
+        }
+    }
+
+    get min(): string | number | undefined | null {
+        switch (this.customField.__typename) {
+            case 'IntCustomFieldConfig':
+                return this.customField.intMin;
+            case 'FloatCustomFieldConfig':
+                return this.customField.floatMin;
+            case 'DateTimeCustomFieldConfig':
+                return this.customField.datetimeMin;
+        }
+    }
+
+    get max(): string | number | undefined | null {
+        switch (this.customField.__typename) {
+            case 'IntCustomFieldConfig':
+                return this.customField.intMax;
+            case 'FloatCustomFieldConfig':
+                return this.customField.floatMax;
+            case 'DateTimeCustomFieldConfig':
+                return this.customField.datetimeMax;
+        }
+    }
+
+    get step(): string | number | undefined | null {
+        switch (this.customField.__typename) {
+            case 'IntCustomFieldConfig':
+                return this.customField.intStep;
+            case 'FloatCustomFieldConfig':
+                return this.customField.floatStep;
+            case 'DateTimeCustomFieldConfig':
+                return this.customField.datetimeStep;
+        }
+    }
+
+    updateDateTime(formControl: FormControl, event: Event) {
+        const value = (event.target as HTMLInputElement).value;
+        formControl.setValue(value ? new Date(value).toISOString() : null, { emitEvent: true });
+        formControl.parent.markAsDirty();
+    }
+
+    getLabel(defaultLabel: string, label?: LocalizedString[] | null): string {
+        if (label) {
+            const match = label.find(l => l.languageCode === this.uiLanguageCode);
+            return match ? match.value : label[0].value;
+        } else {
+            return defaultLabel;
         }
     }
 }

+ 1 - 0
package.json

@@ -37,6 +37,7 @@
     "@commitlint/config-conventional": "^7.6.0",
     "@graphql-codegen/add": "^1.1.3",
     "@graphql-codegen/cli": "^1.1.3",
+    "@graphql-codegen/fragment-matcher": "^1.4.0",
     "@graphql-codegen/typescript": "^1.1.3",
     "@graphql-codegen/typescript-compatibility": "^1.1.3",
     "@graphql-codegen/typescript-operations": "^1.1.3",

+ 1 - 20
packages/common/src/generated-shop-types.ts

@@ -1651,14 +1651,7 @@ export type Product = Node & {
     facetValues: Array<FacetValue>;
     translations: Array<ProductTranslation>;
     collections: Array<Collection>;
-    customFields?: Maybe<ProductCustomFields>;
-};
-
-export type ProductCustomFields = {
-    __typename?: 'ProductCustomFields';
-    nickname?: Maybe<Scalars['String']>;
-    localNickname?: Maybe<Scalars['String']>;
-    expires?: Maybe<Scalars['DateTime']>;
+    customFields?: Maybe<Scalars['JSON']>;
 };
 
 export type ProductFilterParameter = {
@@ -1668,9 +1661,6 @@ export type ProductFilterParameter = {
     name?: Maybe<StringOperators>;
     slug?: Maybe<StringOperators>;
     description?: Maybe<StringOperators>;
-    nickname?: Maybe<StringOperators>;
-    localNickname?: Maybe<StringOperators>;
-    expires?: Maybe<DateOperators>;
 };
 
 export type ProductList = PaginatedList & {
@@ -1737,9 +1727,6 @@ export type ProductSortParameter = {
     name?: Maybe<SortOrder>;
     slug?: Maybe<SortOrder>;
     description?: Maybe<SortOrder>;
-    nickname?: Maybe<SortOrder>;
-    localNickname?: Maybe<SortOrder>;
-    expires?: Maybe<SortOrder>;
 };
 
 export type ProductTranslation = {
@@ -1751,12 +1738,6 @@ export type ProductTranslation = {
     name: Scalars['String'];
     slug: Scalars['String'];
     description: Scalars['String'];
-    customFields?: Maybe<ProductTranslationCustomFields>;
-};
-
-export type ProductTranslationCustomFields = {
-    __typename?: 'ProductTranslationCustomFields';
-    localNickname?: Maybe<Scalars['String']>;
 };
 
 export type ProductVariant = Node & {

+ 11 - 44
packages/common/src/generated-types.ts

@@ -471,17 +471,12 @@ export type CreateGroupOptionInput = {
   translations: Array<ProductOptionGroupTranslationInput>,
 };
 
-export type CreateProductCustomFieldsInput = {
-  nickname?: Maybe<Scalars['String']>,
-  expires?: Maybe<Scalars['DateTime']>,
-};
-
 export type CreateProductInput = {
   featuredAssetId?: Maybe<Scalars['ID']>,
   assetIds?: Maybe<Array<Scalars['ID']>>,
   facetValueIds?: Maybe<Array<Scalars['ID']>>,
   translations: Array<ProductTranslationInput>,
-  customFields?: Maybe<CreateProductCustomFieldsInput>,
+  customFields?: Maybe<Scalars['JSON']>,
 };
 
 export type CreateProductOptionGroupInput = {
@@ -1704,6 +1699,7 @@ export type Mutation = {
   addNoteToOrder: Order,
   /** Update an existing PaymentMethod */
   updatePaymentMethod: PaymentMethod,
+  reindex: JobInfo,
   /** Create a new ProductOptionGroup */
   createProductOptionGroup: ProductOptionGroup,
   /** Update an existing ProductOptionGroup */
@@ -1712,7 +1708,6 @@ export type Mutation = {
   createProductOption: ProductOption,
   /** Create a new ProductOption within a ProductOptionGroup */
   updateProductOption: ProductOption,
-  reindex: JobInfo,
   /** Create a new Product */
   createProduct: Product,
   /** Update an existing Product */
@@ -2363,14 +2358,7 @@ export type Product = Node & {
   translations: Array<ProductTranslation>,
   collections: Array<Collection>,
   enabled: Scalars['Boolean'],
-  customFields?: Maybe<ProductCustomFields>,
-};
-
-export type ProductCustomFields = {
-  __typename?: 'ProductCustomFields',
-  nickname?: Maybe<Scalars['String']>,
-  localNickname?: Maybe<Scalars['String']>,
-  expires?: Maybe<Scalars['DateTime']>,
+  customFields?: Maybe<Scalars['JSON']>,
 };
 
 export type ProductFilterParameter = {
@@ -2381,9 +2369,6 @@ export type ProductFilterParameter = {
   slug?: Maybe<StringOperators>,
   description?: Maybe<StringOperators>,
   enabled?: Maybe<BooleanOperators>,
-  nickname?: Maybe<StringOperators>,
-  localNickname?: Maybe<StringOperators>,
-  expires?: Maybe<DateOperators>,
 };
 
 export type ProductList = PaginatedList & {
@@ -2464,9 +2449,6 @@ export type ProductSortParameter = {
   name?: Maybe<SortOrder>,
   slug?: Maybe<SortOrder>,
   description?: Maybe<SortOrder>,
-  nickname?: Maybe<SortOrder>,
-  localNickname?: Maybe<SortOrder>,
-  expires?: Maybe<SortOrder>,
 };
 
 export type ProductTranslation = {
@@ -2478,16 +2460,6 @@ export type ProductTranslation = {
   name: Scalars['String'],
   slug: Scalars['String'],
   description: Scalars['String'],
-  customFields?: Maybe<ProductTranslationCustomFields>,
-};
-
-export type ProductTranslationCustomFields = {
-  __typename?: 'ProductTranslationCustomFields',
-  localNickname?: Maybe<Scalars['String']>,
-};
-
-export type ProductTranslationCustomFieldsInput = {
-  localNickname?: Maybe<Scalars['String']>,
 };
 
 export type ProductTranslationInput = {
@@ -2496,7 +2468,7 @@ export type ProductTranslationInput = {
   name?: Maybe<Scalars['String']>,
   slug?: Maybe<Scalars['String']>,
   description?: Maybe<Scalars['String']>,
-  customFields?: Maybe<ProductTranslationCustomFieldsInput>,
+  customFields?: Maybe<Scalars['JSON']>,
 };
 
 export type ProductVariant = Node & {
@@ -2653,9 +2625,9 @@ export type Query = {
   orders: OrderList,
   paymentMethods: PaymentMethodList,
   paymentMethod?: Maybe<PaymentMethod>,
+  search: SearchResponse,
   productOptionGroups: Array<ProductOptionGroup>,
   productOptionGroup?: Maybe<ProductOptionGroup>,
-  search: SearchResponse,
   products: ProductList,
   /** Get a Product either by id or slug. If neither id nor slug is speicified, an error will result. */
   product?: Maybe<Product>,
@@ -2781,6 +2753,11 @@ export type QueryPaymentMethodArgs = {
 };
 
 
+export type QuerySearchArgs = {
+  input: SearchInput
+};
+
+
 export type QueryProductOptionGroupsArgs = {
   languageCode?: Maybe<LanguageCode>,
   filterTerm?: Maybe<Scalars['String']>
@@ -2793,11 +2770,6 @@ export type QueryProductOptionGroupArgs = {
 };
 
 
-export type QuerySearchArgs = {
-  input: SearchInput
-};
-
-
 export type QueryProductsArgs = {
   languageCode?: Maybe<LanguageCode>,
   options?: Maybe<ProductListOptions>
@@ -3279,11 +3251,6 @@ export type UpdatePaymentMethodInput = {
   configArgs?: Maybe<Array<ConfigArgInput>>,
 };
 
-export type UpdateProductCustomFieldsInput = {
-  nickname?: Maybe<Scalars['String']>,
-  expires?: Maybe<Scalars['DateTime']>,
-};
-
 export type UpdateProductInput = {
   id: Scalars['ID'],
   enabled?: Maybe<Scalars['Boolean']>,
@@ -3291,7 +3258,7 @@ export type UpdateProductInput = {
   assetIds?: Maybe<Array<Scalars['ID']>>,
   facetValueIds?: Maybe<Array<Scalars['ID']>>,
   translations?: Maybe<Array<ProductTranslationInput>>,
-  customFields?: Maybe<UpdateProductCustomFieldsInput>,
+  customFields?: Maybe<Scalars['JSON']>,
 };
 
 export type UpdateProductOptionGroupInput = {

+ 10 - 43
packages/core/e2e/graphql/generated-e2e-admin-types.ts

@@ -471,17 +471,12 @@ export type CreateGroupOptionInput = {
     translations: Array<ProductOptionGroupTranslationInput>;
 };
 
-export type CreateProductCustomFieldsInput = {
-    nickname?: Maybe<Scalars['String']>;
-    expires?: Maybe<Scalars['DateTime']>;
-};
-
 export type CreateProductInput = {
     featuredAssetId?: Maybe<Scalars['ID']>;
     assetIds?: Maybe<Array<Scalars['ID']>>;
     facetValueIds?: Maybe<Array<Scalars['ID']>>;
     translations: Array<ProductTranslationInput>;
-    customFields?: Maybe<CreateProductCustomFieldsInput>;
+    customFields?: Maybe<Scalars['JSON']>;
 };
 
 export type CreateProductOptionGroupInput = {
@@ -1707,6 +1702,7 @@ export type Mutation = {
     addNoteToOrder: Order;
     /** Update an existing PaymentMethod */
     updatePaymentMethod: PaymentMethod;
+    reindex: JobInfo;
     /** Create a new ProductOptionGroup */
     createProductOptionGroup: ProductOptionGroup;
     /** Update an existing ProductOptionGroup */
@@ -1715,7 +1711,6 @@ export type Mutation = {
     createProductOption: ProductOption;
     /** Create a new ProductOption within a ProductOptionGroup */
     updateProductOption: ProductOption;
-    reindex: JobInfo;
     /** Create a new Product */
     createProduct: Product;
     /** Update an existing Product */
@@ -2298,14 +2293,7 @@ export type Product = Node & {
     translations: Array<ProductTranslation>;
     collections: Array<Collection>;
     enabled: Scalars['Boolean'];
-    customFields?: Maybe<ProductCustomFields>;
-};
-
-export type ProductCustomFields = {
-    __typename?: 'ProductCustomFields';
-    nickname?: Maybe<Scalars['String']>;
-    localNickname?: Maybe<Scalars['String']>;
-    expires?: Maybe<Scalars['DateTime']>;
+    customFields?: Maybe<Scalars['JSON']>;
 };
 
 export type ProductFilterParameter = {
@@ -2316,9 +2304,6 @@ export type ProductFilterParameter = {
     slug?: Maybe<StringOperators>;
     description?: Maybe<StringOperators>;
     enabled?: Maybe<BooleanOperators>;
-    nickname?: Maybe<StringOperators>;
-    localNickname?: Maybe<StringOperators>;
-    expires?: Maybe<DateOperators>;
 };
 
 export type ProductList = PaginatedList & {
@@ -2399,9 +2384,6 @@ export type ProductSortParameter = {
     name?: Maybe<SortOrder>;
     slug?: Maybe<SortOrder>;
     description?: Maybe<SortOrder>;
-    nickname?: Maybe<SortOrder>;
-    localNickname?: Maybe<SortOrder>;
-    expires?: Maybe<SortOrder>;
 };
 
 export type ProductTranslation = {
@@ -2413,16 +2395,6 @@ export type ProductTranslation = {
     name: Scalars['String'];
     slug: Scalars['String'];
     description: Scalars['String'];
-    customFields?: Maybe<ProductTranslationCustomFields>;
-};
-
-export type ProductTranslationCustomFields = {
-    __typename?: 'ProductTranslationCustomFields';
-    localNickname?: Maybe<Scalars['String']>;
-};
-
-export type ProductTranslationCustomFieldsInput = {
-    localNickname?: Maybe<Scalars['String']>;
 };
 
 export type ProductTranslationInput = {
@@ -2431,7 +2403,7 @@ export type ProductTranslationInput = {
     name?: Maybe<Scalars['String']>;
     slug?: Maybe<Scalars['String']>;
     description?: Maybe<Scalars['String']>;
-    customFields?: Maybe<ProductTranslationCustomFieldsInput>;
+    customFields?: Maybe<Scalars['JSON']>;
 };
 
 export type ProductVariant = Node & {
@@ -2587,9 +2559,9 @@ export type Query = {
     orders: OrderList;
     paymentMethods: PaymentMethodList;
     paymentMethod?: Maybe<PaymentMethod>;
+    search: SearchResponse;
     productOptionGroups: Array<ProductOptionGroup>;
     productOptionGroup?: Maybe<ProductOptionGroup>;
-    search: SearchResponse;
     products: ProductList;
     /** Get a Product either by id or slug. If neither id nor slug is speicified, an error will result. */
     product?: Maybe<Product>;
@@ -2694,6 +2666,10 @@ export type QueryPaymentMethodArgs = {
     id: Scalars['ID'];
 };
 
+export type QuerySearchArgs = {
+    input: SearchInput;
+};
+
 export type QueryProductOptionGroupsArgs = {
     languageCode?: Maybe<LanguageCode>;
     filterTerm?: Maybe<Scalars['String']>;
@@ -2704,10 +2680,6 @@ export type QueryProductOptionGroupArgs = {
     languageCode?: Maybe<LanguageCode>;
 };
 
-export type QuerySearchArgs = {
-    input: SearchInput;
-};
-
 export type QueryProductsArgs = {
     languageCode?: Maybe<LanguageCode>;
     options?: Maybe<ProductListOptions>;
@@ -3181,11 +3153,6 @@ export type UpdatePaymentMethodInput = {
     configArgs?: Maybe<Array<ConfigArgInput>>;
 };
 
-export type UpdateProductCustomFieldsInput = {
-    nickname?: Maybe<Scalars['String']>;
-    expires?: Maybe<Scalars['DateTime']>;
-};
-
 export type UpdateProductInput = {
     id: Scalars['ID'];
     enabled?: Maybe<Scalars['Boolean']>;
@@ -3193,7 +3160,7 @@ export type UpdateProductInput = {
     assetIds?: Maybe<Array<Scalars['ID']>>;
     facetValueIds?: Maybe<Array<Scalars['ID']>>;
     translations?: Maybe<Array<ProductTranslationInput>>;
-    customFields?: Maybe<UpdateProductCustomFieldsInput>;
+    customFields?: Maybe<Scalars['JSON']>;
 };
 
 export type UpdateProductOptionGroupInput = {

+ 1 - 20
packages/core/e2e/graphql/generated-e2e-shop-types.ts

@@ -1651,14 +1651,7 @@ export type Product = Node & {
     facetValues: Array<FacetValue>;
     translations: Array<ProductTranslation>;
     collections: Array<Collection>;
-    customFields?: Maybe<ProductCustomFields>;
-};
-
-export type ProductCustomFields = {
-    __typename?: 'ProductCustomFields';
-    nickname?: Maybe<Scalars['String']>;
-    localNickname?: Maybe<Scalars['String']>;
-    expires?: Maybe<Scalars['DateTime']>;
+    customFields?: Maybe<Scalars['JSON']>;
 };
 
 export type ProductFilterParameter = {
@@ -1668,9 +1661,6 @@ export type ProductFilterParameter = {
     name?: Maybe<StringOperators>;
     slug?: Maybe<StringOperators>;
     description?: Maybe<StringOperators>;
-    nickname?: Maybe<StringOperators>;
-    localNickname?: Maybe<StringOperators>;
-    expires?: Maybe<DateOperators>;
 };
 
 export type ProductList = PaginatedList & {
@@ -1737,9 +1727,6 @@ export type ProductSortParameter = {
     name?: Maybe<SortOrder>;
     slug?: Maybe<SortOrder>;
     description?: Maybe<SortOrder>;
-    nickname?: Maybe<SortOrder>;
-    localNickname?: Maybe<SortOrder>;
-    expires?: Maybe<SortOrder>;
 };
 
 export type ProductTranslation = {
@@ -1751,12 +1738,6 @@ export type ProductTranslation = {
     name: Scalars['String'];
     slug: Scalars['String'];
     description: Scalars['String'];
-    customFields?: Maybe<ProductTranslationCustomFields>;
-};
-
-export type ProductTranslationCustomFields = {
-    __typename?: 'ProductTranslationCustomFields';
-    localNickname?: Maybe<Scalars['String']>;
 };
 
 export type ProductVariant = Node & {

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
schema-admin.json


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
schema-shop.json


+ 6 - 0
scripts/codegen/generate-graphql-types.ts

@@ -69,6 +69,12 @@ Promise.all([
                     plugins: clientPlugins,
                     config,
                 },
+                [path.join(__dirname, '../../admin-ui/src/app/common/introspection-result.ts')]: {
+                    schema: [ADMIN_SCHEMA_OUTPUT_FILE, path.join(__dirname, 'client-schema.ts')],
+                    documents: CLIENT_QUERY_FILES,
+                    plugins: ['fragment-matcher'],
+                    config,
+                },
                 [path.join(__dirname, '../../packages/common/src/generated-types.ts')]: {
                     schema: [ADMIN_SCHEMA_OUTPUT_FILE],
                     plugins: commonPlugins,

+ 22 - 0
yarn.lock

@@ -369,6 +369,13 @@
     graphql-toolkit "0.2.12"
     tslib "1.9.3"
 
+"@graphql-codegen/fragment-matcher@^1.4.0":
+  version "1.4.0"
+  resolved "https://registry.npmjs.org/@graphql-codegen/fragment-matcher/-/fragment-matcher-1.4.0.tgz#5c09972e07cbd0c53a1664c717be882fbceefe60"
+  integrity sha512-vXQfevAaOOx4r0Fi34a0tIenkkJWy/TcnAV1p53PSKk8OCYst9v5wT6/WMU1l57D8b+UgpNy49Uuxva1ox5HSw==
+  dependencies:
+    "@graphql-codegen/plugin-helpers" "1.4.0"
+
 "@graphql-codegen/plugin-helpers@1.2.0":
   version "1.2.0"
   resolved "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-1.2.0.tgz#a5011f9d90767cbbe20ad9b4f6c8080bf79ba2fa"
@@ -379,6 +386,16 @@
     import-from "3.0.0"
     tslib "1.9.3"
 
+"@graphql-codegen/plugin-helpers@1.4.0":
+  version "1.4.0"
+  resolved "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-1.4.0.tgz#46e04fa1477172930ef5b1cd8461ee65fe9a4aa3"
+  integrity sha512-J1I6i2+SawA4Se8yeZ/GwjoLmb5M5F2rpx3UWoIgKwa+trL+yM5NECJ1Gf7R/d6suNdO2kapGkrEXuw52GT1Jw==
+  dependencies:
+    change-case "3.1.0"
+    common-tags "1.8.0"
+    import-from "3.0.0"
+    tslib "1.10.0"
+
 "@graphql-codegen/typescript-compatibility@^1.1.3":
   version "1.2.0"
   resolved "https://registry.npmjs.org/@graphql-codegen/typescript-compatibility/-/typescript-compatibility-1.2.0.tgz#1c2b785936e1ed6bcf4aaa7883aca6f91cf89691"
@@ -10981,6 +10998,11 @@ ts-node@^8.0.3:
     source-map-support "^0.5.6"
     yn "^3.0.0"
 
+tslib@1.10.0:
+  version "1.10.0"
+  resolved "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
+  integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
+
 tslib@1.9.3, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
   version "1.9.3"
   resolved "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio