From 554c694b5ed7c8292548c366550b14ecdd17ad25 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Sat, 16 Sep 2023 17:29:40 +0200 Subject: [PATCH] Fix unset. (#1025) --- backend/i18n/frontend_en.json | 2 + backend/i18n/frontend_fr.json | 2 + backend/i18n/frontend_it.json | 2 + backend/i18n/frontend_nl.json | 2 + backend/i18n/frontend_pt.json | 2 + backend/i18n/frontend_zh.json | 2 + backend/i18n/source/frontend_en.json | 2 + .../Schemas/ReferencesFieldProperties.cs | 2 + .../Fields/ReferencesFieldPropertiesDto.cs | 5 ++ .../Squidex/wwwroot/scripts/editor-sdk.d.ts | 23 ++--- .../src/Squidex/wwwroot/scripts/editor-sdk.js | 27 +++--- .../shared/forms/field-editor.component.html | 4 +- .../shared/forms/iframe-editor.component.html | 1 + .../shared/forms/iframe-editor.component.ts | 4 +- .../references/content-creator.component.html | 8 +- .../references-editor.component.html | 1 + .../references/references-editor.component.ts | 3 + .../fields/types/references-ui.component.html | 12 +++ .../angular/forms/templated-form-array.ts | 2 +- .../forms/templated-form-group.spec.ts | 1 + .../angular/forms/templated-form-group.ts | 2 +- .../content-selector.component.html | 6 +- .../references/content-selector.component.ts | 10 ++- .../references/reference-input.component.html | 1 + .../references/reference-input.component.ts | 3 + .../queries/filter-comparison.component.html | 3 +- .../src/app/shared/services/schemas.types.ts | 1 + .../app/shared/state/contents.forms.spec.ts | 89 ++++++++++--------- .../src/app/shared/state/contents.forms.ts | 2 + .../state/contents.forms.visitors.spec.ts | 8 +- .../shared/state/contents.forms.visitors.ts | 4 +- .../src/app/shared/state/schemas.forms.ts | 1 + 32 files changed, 158 insertions(+), 79 deletions(-) diff --git a/backend/i18n/frontend_en.json b/backend/i18n/frontend_en.json index 1eea7677e..4aac7c528 100644 --- a/backend/i18n/frontend_en.json +++ b/backend/i18n/frontend_en.json @@ -913,6 +913,8 @@ "schemas.fieldTypes.references.countMin": "Min Items", "schemas.fieldTypes.references.description": "Links to other content items.", "schemas.fieldTypes.references.mustBePublished": "Only take published references into account when validating.", + "schemas.fieldTypes.references.query": "Initial Query", + "schemas.fieldTypes.references.queryHint": "The initial query that is used in the UI to narrow down the results for the user. In Odata notation.", "schemas.fieldTypes.references.resolve": "Resolve references", "schemas.fieldTypes.references.resolveHint": "Show the name of the referenced item in content list when MaxItems is set to 1.", "schemas.fieldTypes.string.characters": "Characters", diff --git a/backend/i18n/frontend_fr.json b/backend/i18n/frontend_fr.json index 94066370e..e3157ea0b 100644 --- a/backend/i18n/frontend_fr.json +++ b/backend/i18n/frontend_fr.json @@ -913,6 +913,8 @@ "schemas.fieldTypes.references.countMin": "Articles minimum", "schemas.fieldTypes.references.description": "Liens vers d'autres éléments de contenu.", "schemas.fieldTypes.references.mustBePublished": "Ne tenez compte que des références publiées lors de la validation.", + "schemas.fieldTypes.references.query": "Initial Query", + "schemas.fieldTypes.references.queryHint": "The initial query that is used in the UI to narrow down the results for the user. In Odata notation.", "schemas.fieldTypes.references.resolve": "Résoudre les références", "schemas.fieldTypes.references.resolveHint": "Afficher le nom de l'élément référencé dans la liste de contenu lorsque MaxItems est défini sur 1.", "schemas.fieldTypes.string.characters": "Personnages", diff --git a/backend/i18n/frontend_it.json b/backend/i18n/frontend_it.json index fc054cebb..85bc51a75 100644 --- a/backend/i18n/frontend_it.json +++ b/backend/i18n/frontend_it.json @@ -913,6 +913,8 @@ "schemas.fieldTypes.references.countMin": "Numero Min Elementi", "schemas.fieldTypes.references.description": "Link ad altri elementi del contenuto.", "schemas.fieldTypes.references.mustBePublished": "I contenuti collegati devono essere pubblicati", + "schemas.fieldTypes.references.query": "Initial Query", + "schemas.fieldTypes.references.queryHint": "The initial query that is used in the UI to narrow down the results for the user. In Odata notation.", "schemas.fieldTypes.references.resolve": "Resolve references", "schemas.fieldTypes.references.resolveHint": "Mostra il nome dell'elemento collegato (riferimento) nella lista dei contenuti quando il numero massimo di elementi è impostato a 1.", "schemas.fieldTypes.string.characters": "Caratteri", diff --git a/backend/i18n/frontend_nl.json b/backend/i18n/frontend_nl.json index 14a8d8749..cc0de5df4 100644 --- a/backend/i18n/frontend_nl.json +++ b/backend/i18n/frontend_nl.json @@ -913,6 +913,8 @@ "schemas.fieldTypes.references.countMin": "Min. items", "schemas.fieldTypes.references.description": "Links naar andere inhoudsitems.", "schemas.fieldTypes.references.mustBePublished": "Referenties moeten worden gepubliceerd", + "schemas.fieldTypes.references.query": "Initial Query", + "schemas.fieldTypes.references.queryHint": "The initial query that is used in the UI to narrow down the results for the user. In Odata notation.", "schemas.fieldTypes.references.resolve": "Referenties tonen", "schemas.fieldTypes.references.resolveHint": "Toon de naam van het item waarnaar wordt verwezen in de inhoudslijst wanneer MaxItems is ingesteld op 1.", "schemas.fieldTypes.string.characters": "Karakters", diff --git a/backend/i18n/frontend_pt.json b/backend/i18n/frontend_pt.json index 288d6efb1..a64267211 100644 --- a/backend/i18n/frontend_pt.json +++ b/backend/i18n/frontend_pt.json @@ -913,6 +913,8 @@ "schemas.fieldTypes.references.countMin": "Min Itens", "schemas.fieldTypes.references.description": "Links para outros itens de conteúdo.", "schemas.fieldTypes.references.mustBePublished": "Só ter em conta as referências publicadas ao validar.", + "schemas.fieldTypes.references.query": "Initial Query", + "schemas.fieldTypes.references.queryHint": "The initial query that is used in the UI to narrow down the results for the user. In Odata notation.", "schemas.fieldTypes.references.resolve": "Resolver referências", "schemas.fieldTypes.references.resolveHint": "Mostre o nome do item referenciado na lista de conteúdos quando maxItems estiver definido para 1.", "schemas.fieldTypes.string.characters": "Personagens", diff --git a/backend/i18n/frontend_zh.json b/backend/i18n/frontend_zh.json index 1949dfa56..46f2e076a 100644 --- a/backend/i18n/frontend_zh.json +++ b/backend/i18n/frontend_zh.json @@ -913,6 +913,8 @@ "schemas.fieldTypes.references.countMin": "最小项目", "schemas.fieldTypes.references.description": "链接到其他内容项。", "schemas.fieldTypes.references.mustBePublished": "必须发布参考文献", + "schemas.fieldTypes.references.query": "Initial Query", + "schemas.fieldTypes.references.queryHint": "The initial query that is used in the UI to narrow down the results for the user. In Odata notation.", "schemas.fieldTypes.references.resolve": "Resolve references", "schemas.fieldTypes.references.resolveHint": "当 MaxItems 设置为 1 时,在内容列表中显示引用项的名称。", "schemas.fieldTypes.string.characters": "字符", diff --git a/backend/i18n/source/frontend_en.json b/backend/i18n/source/frontend_en.json index 1eea7677e..4aac7c528 100644 --- a/backend/i18n/source/frontend_en.json +++ b/backend/i18n/source/frontend_en.json @@ -913,6 +913,8 @@ "schemas.fieldTypes.references.countMin": "Min Items", "schemas.fieldTypes.references.description": "Links to other content items.", "schemas.fieldTypes.references.mustBePublished": "Only take published references into account when validating.", + "schemas.fieldTypes.references.query": "Initial Query", + "schemas.fieldTypes.references.queryHint": "The initial query that is used in the UI to narrow down the results for the user. In Odata notation.", "schemas.fieldTypes.references.resolve": "Resolve references", "schemas.fieldTypes.references.resolveHint": "Show the name of the referenced item in content list when MaxItems is set to 1.", "schemas.fieldTypes.string.characters": "Characters", diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs index d0f72af6a..c38fbf9db 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldProperties.cs @@ -26,6 +26,8 @@ public sealed record ReferencesFieldProperties : FieldProperties public bool MustBePublished { get; init; } + public string? Query { get; init;} + public ReferencesFieldEditor Editor { get; init; } public DomainId SchemaId diff --git a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs index 8e54fe870..1fc6d02a7 100644 --- a/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs +++ b/backend/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs @@ -51,6 +51,11 @@ public sealed class ReferencesFieldPropertiesDto : FieldPropertiesDto /// public bool MustBePublished { get; set; } + /// + /// The initial query that is applied in the UI. + /// + public string? Query { get; init; } + /// /// The editor that is used to manage this field. /// diff --git a/backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts b/backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts index 51e76a843..0fdf0c11c 100644 --- a/backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts +++ b/backend/src/Squidex/wwwroot/scripts/editor-sdk.d.ts @@ -12,14 +12,14 @@ declare class EditorPlugin { /** * Register an function that is called when the sidebar is initialized. * - * @param {Function} callback: The callback to invoke. + * @param {function} callback: The callback to invoke. */ onInit(callback: () => void): void; /** * Register an function that is called whenever the value of the content has changed. * - * @param {Function} callback: The callback to invoke. Argument 1: Content value (any). + * @param {function} callback: The callback to invoke. Argument 1: Content value (any). */ onContentChanged(callback: (content: any) => void): void; @@ -133,62 +133,63 @@ declare class SquidexFormField { * * @param {string} schemas: The list of schema names. * @param {function} callback The callback to invoke when the dialog is completed or closed. + * @param {string} query: The initial query that is used in the UI. */ - pickContents(schemas: string[], callback: (assets: any[]) => void): void; + pickContents(schemas: string[], callback: (assets: any[]) => void, query?: string): void; /** * Register an function that is called when the field is initialized. * - * @param {Function} callback: The callback to invoke. + * @param {function} callback: The callback to invoke. */ onInit(callback: () => void): void; /** * Register an function that is called when the field is moved. * - * @param {Function} callback: The callback to invoke. Argument 1: New position (number). + * @param {function} callback: The callback to invoke. Argument 1: New position (number). */ onMoved(callback: (index: number) => void): void; /** * Register an function that is called whenever the field is disabled or enabled. * - * @param {Function} callback: The callback to invoke. Argument 1: New disabled state (boolean, disabled = true, enabled = false). + * @param {function} callback: The callback to invoke. Argument 1: New disabled state (boolean, disabled = true, enabled = false). */ onDisabled(callback: (isDisabled: boolean) => void): void; /** * Register an function that is called whenever the field language is changed. * - * @param {Function} callback: The callback to invoke. Argument 1: Language code (string). + * @param {function} callback: The callback to invoke. Argument 1: Language code (string). */ onLanguageChanged(callback: (language: string) => void): void; /** * Register an function that is called whenever the value of the field has changed. * - * @param {Function} callback: The callback to invoke. Argument 1: Field value (any). + * @param {function} callback: The callback to invoke. Argument 1: Field value (any). */ onValueChanged(callback: (value: any) => void): void; /** * Register an function that is called whenever the value of the content has changed. * - * @param {Function} callback: The callback to invoke. Argument 1: Content value (any). + * @param {function} callback: The callback to invoke. Argument 1: Content value (any). */ onFormValueChanged(callback: (value: any) => void): void; /** * Register an function that is called whenever the fullscreen mode has changed. * - * @param {Function} callback: The callback to invoke. Argument 1: Fullscreen state (boolean, fullscreen on = true, fullscreen off = false). + * @param {function} callback: The callback to invoke. Argument 1: Fullscreen state (boolean, fullscreen on = true, fullscreen off = false). */ onFullscreen(callback: (isFullscreen: boolean) => void): void; /** * Register an function that is called whenever the expanded mode has changed. * - * @param {Function} callback: The callback to invoke. Argument 1: Expanded state (boolean, expanded on = true, expanded off = false). + * @param {function} callback: The callback to invoke. Argument 1: Expanded state (boolean, expanded on = true, expanded off = false). */ onExpanded(callback: (isExpanded: boolean) => void): void; diff --git a/backend/src/Squidex/wwwroot/scripts/editor-sdk.js b/backend/src/Squidex/wwwroot/scripts/editor-sdk.js index e0d131830..4c45b22e5 100644 --- a/backend/src/Squidex/wwwroot/scripts/editor-sdk.js +++ b/backend/src/Squidex/wwwroot/scripts/editor-sdk.js @@ -114,7 +114,7 @@ function SquidexPlugin() { /** * Register an function that is called when the sidebar is initialized. * - * @param {Function} callback: The callback to invoke. + * @param {function} callback: The callback to invoke. */ onInit: function (callback) { if (!isFunction(callback)) { @@ -129,7 +129,7 @@ function SquidexPlugin() { /** * Register an function that is called whenever the value of the content has changed. * - * @param {Function} callback: The callback to invoke. Argument 1: Content value (any). + * @param {function} callback: The callback to invoke. Argument 1: Content value (any). */ onContentChanged: function (callback) { if (!isFunction(callback)) { @@ -491,8 +491,9 @@ function SquidexFormField() { * * @param {string} schemas: The list of schema names. * @param {function} callback The callback to invoke when the dialog is completed or closed. + * @param {string} query: The initial filter that is used in the UI. */ - pickContents: function (schemas, callback) { + pickContents: function (schemas, callback, query) { if (!isFunction(callback) || !isArrayOfStrings(schemas)) { return; } @@ -501,18 +502,18 @@ function SquidexFormField() { currentPickContents = { correlationId: correlationId, - callback: callback + callback: callback, }; if (window.parent) { - window.parent.postMessage({ type: 'pickContents', correlationId: correlationId, schemas: schemas }, '*'); + window.parent.postMessage({ type: 'pickContents', correlationId: correlationId, schemas: schemas, query: query }, '*'); } }, /** * Register an function that is called when the field is initialized. * - * @param {Function} callback: The callback to invoke. + * @param {function} callback: The callback to invoke. */ onInit: function (callback) { if (!isFunction(callback)) { @@ -527,7 +528,7 @@ function SquidexFormField() { /** * Register an function that is called when the field is moved. * - * @param {Function} callback: The callback to invoke. Argument 1: New position (number). + * @param {function} callback: The callback to invoke. Argument 1: New position (number). */ onMoved: function (callback) { if (!isFunction(callback)) { @@ -542,7 +543,7 @@ function SquidexFormField() { /** * Register an function that is called whenever the field is disabled or enabled. * - * @param {Function} callback: The callback to invoke. Argument 1: New disabled state (boolean, disabled = true, enabled = false). + * @param {function} callback: The callback to invoke. Argument 1: New disabled state (boolean, disabled = true, enabled = false). */ onDisabled: function (callback) { if (!isFunction(callback)) { @@ -557,7 +558,7 @@ function SquidexFormField() { /** * Register an function that is called whenever the field language is changed. * - * @param {Function} callback: The callback to invoke. Argument 1: Language code (string). + * @param {function} callback: The callback to invoke. Argument 1: Language code (string). */ onLanguageChanged: function (callback) { if (!isFunction(callback)) { @@ -572,7 +573,7 @@ function SquidexFormField() { /** * Register an function that is called whenever the value of the field has changed. * - * @param {Function} callback: The callback to invoke. Argument 1: Field value (any). + * @param {function} callback: The callback to invoke. Argument 1: Field value (any). */ onValueChanged: function (callback) { if (!isFunction(callback)) { @@ -587,7 +588,7 @@ function SquidexFormField() { /** * Register an function that is called whenever the value of the content has changed. * - * @param {Function} callback: The callback to invoke. Argument 1: Content value (any). + * @param {function} callback: The callback to invoke. Argument 1: Content value (any). */ onFormValueChanged: function (callback) { if (!isFunction(callback)) { @@ -602,7 +603,7 @@ function SquidexFormField() { /** * Register an function that is called whenever the fullscreen mode has changed. * - * @param {Function} callback: The callback to invoke. Argument 1: Fullscreen state (boolean, fullscreen on = true, fullscreen off = false). + * @param {function} callback: The callback to invoke. Argument 1: Fullscreen state (boolean, fullscreen on = true, fullscreen off = false). */ onFullscreen: function (callback) { if (!isFunction(callback)) { @@ -617,7 +618,7 @@ function SquidexFormField() { /** * Register an function that is called whenever the expanded mode has changed. * - * @param {Function} callback: The callback to invoke. Argument 1: Expanded state (boolean, expanded on = true, expanded off = false). + * @param {function} callback: The callback to invoke. Argument 1: Expanded state (boolean, expanded on = true, expanded off = false). */ onExpanded: function (callback) { if (!isFunction(callback)) { diff --git a/frontend/src/app/features/content/shared/forms/field-editor.component.html b/frontend/src/app/features/content/shared/forms/field-editor.component.html index 2dde0a018..c6031418d 100644 --- a/frontend/src/app/features/content/shared/forms/field-editor.component.html +++ b/frontend/src/app/features/content/shared/forms/field-editor.component.html @@ -137,6 +137,7 @@ [isExpanded]="isExpanded" [language]="language" [languages]="languages" + [query]="field.rawProperties.query" [schemaIds]="field.rawProperties.schemaIds"> @@ -152,9 +153,10 @@ diff --git a/frontend/src/app/features/content/shared/forms/iframe-editor.component.html b/frontend/src/app/features/content/shared/forms/iframe-editor.component.html index c40501411..5b04e60cb 100644 --- a/frontend/src/app/features/content/shared/forms/iframe-editor.component.html +++ b/frontend/src/app/features/content/shared/forms/iframe-editor.component.html @@ -10,6 +10,7 @@ diff --git a/frontend/src/app/features/content/shared/forms/iframe-editor.component.ts b/frontend/src/app/features/content/shared/forms/iframe-editor.component.ts index e800ddf0d..3ad605c3d 100644 --- a/frontend/src/app/features/content/shared/forms/iframe-editor.component.ts +++ b/frontend/src/app/features/content/shared/forms/iframe-editor.component.ts @@ -78,6 +78,7 @@ export class IFrameEditorComponent extends StatefulComponent implements public assetsCorrelationId: any; public assetsDialog = new DialogModel(); + public contentsQuery?: string = undefined; public contentsCorrelationId: any; public contentsSchemas?: string[]; public contentsDialog = new DialogModel(); @@ -207,9 +208,10 @@ export class IFrameEditorComponent extends StatefulComponent implements this.assetsDialog.show(); } } else if (type === 'pickContents') { - const { correlationId, schemas } = event.data; + const { correlationId, schemas, query } = event.data; if (correlationId) { + this.contentsQuery = query; this.contentsCorrelationId = correlationId; this.contentsSchemas = schemas; this.contentsDialog.show(); diff --git a/frontend/src/app/features/content/shared/references/content-creator.component.html b/frontend/src/app/features/content/shared/references/content-creator.component.html index 29ef52ece..978366d2b 100644 --- a/frontend/src/app/features/content/shared/references/content-creator.component.html +++ b/frontend/src/app/features/content/shared/references/content-creator.component.html @@ -1,10 +1,14 @@ - +- - + +
+ {{ 'contents.referencesSelectSchema' | sqxTranslate: { schema: schemas[0].displayName } }} +
diff --git a/frontend/src/app/features/content/shared/references/references-editor.component.html b/frontend/src/app/features/content/shared/references/references-editor.component.html index 559b73ef8..945667dda 100644 --- a/frontend/src/app/features/content/shared/references/references-editor.component.html +++ b/frontend/src/app/features/content/shared/references/references-editor.component.html @@ -52,5 +52,6 @@ [alreadySelected]="snapshot.contentItems" [language]="language" [languages]="languages" + [query]="query" [schemaIds]="schemaIds">
\ No newline at end of file diff --git a/frontend/src/app/features/content/shared/references/references-editor.component.ts b/frontend/src/app/features/content/shared/references/references-editor.component.ts index 590ae40bf..31a1b902d 100644 --- a/frontend/src/app/features/content/shared/references/references-editor.component.ts +++ b/frontend/src/app/features/content/shared/references/references-editor.component.ts @@ -35,6 +35,9 @@ export class ReferencesEditorComponent extends StatefulControlComponent; + @Input({ required: true }) + public query?: string; + @Input({ required: true }) public language!: AppLanguageDto; diff --git a/frontend/src/app/features/schemas/pages/schema/fields/types/references-ui.component.html b/frontend/src/app/features/schemas/pages/schema/fields/types/references-ui.component.html index 3361b2c2d..a69fad61c 100644 --- a/frontend/src/app/features/schemas/pages/schema/fields/types/references-ui.component.html +++ b/frontend/src/app/features/schemas/pages/schema/fields/types/references-ui.component.html @@ -27,4 +27,16 @@ + +
+ + +
+ + + + {{ 'schemas.field.references.queryHint' | sqxTranslate }} + +
+
\ No newline at end of file diff --git a/frontend/src/app/framework/angular/forms/templated-form-array.ts b/frontend/src/app/framework/angular/forms/templated-form-array.ts index 079309965..ebd70a7ee 100644 --- a/frontend/src/app/framework/angular/forms/templated-form-array.ts +++ b/frontend/src/app/framework/angular/forms/templated-form-array.ts @@ -21,7 +21,7 @@ export class TemplatedFormArray extends UndefinableFormArray { constructor(public readonly template: FormArrayTemplate, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null, ) { - super(undefined, validatorOrOpts, asyncValidator); + super([], validatorOrOpts, asyncValidator); } public setValue(value?: any[], options?: { onlySelf?: boolean; emitEvent?: boolean }) { diff --git a/frontend/src/app/framework/angular/forms/templated-form-group.spec.ts b/frontend/src/app/framework/angular/forms/templated-form-group.spec.ts index 13f2c1433..f29a8b3ef 100644 --- a/frontend/src/app/framework/angular/forms/templated-form-group.spec.ts +++ b/frontend/src/app/framework/angular/forms/templated-form-group.spec.ts @@ -48,6 +48,7 @@ describe('TemplatedFormGroup', () => { expect(formArray.value).toEqual(value1); }); + it(`Should call template to clear items with for ${name}`, () => { const value1 = { value: 1, diff --git a/frontend/src/app/framework/angular/forms/templated-form-group.ts b/frontend/src/app/framework/angular/forms/templated-form-group.ts index a3fdaf7a5..f2704bcea 100644 --- a/frontend/src/app/framework/angular/forms/templated-form-group.ts +++ b/frontend/src/app/framework/angular/forms/templated-form-group.ts @@ -19,7 +19,7 @@ export class TemplatedFormGroup extends UndefinableFormGroup { constructor(public readonly template: FormGroupTemplate, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null, ) { - super(undefined, validatorOrOpts, asyncValidator); + super({}, validatorOrOpts, asyncValidator); } public setValue(value?: {}, options?: { onlySelf?: boolean; emitEvent?: boolean }) { diff --git a/frontend/src/app/shared/components/references/content-selector.component.html b/frontend/src/app/shared/components/references/content-selector.component.html index e5ec35bca..c4023ea9f 100644 --- a/frontend/src/app/shared/components/references/content-selector.component.html +++ b/frontend/src/app/shared/components/references/content-selector.component.html @@ -2,13 +2,17 @@
-
+ +
+ {{ 'contents.referencesSelectSchema' | sqxTranslate: { schema: schemas[0].displayName } }} +
diff --git a/frontend/src/app/shared/components/references/content-selector.component.ts b/frontend/src/app/shared/components/references/content-selector.component.ts index a53ce9140..494972dc2 100644 --- a/frontend/src/app/shared/components/references/content-selector.component.ts +++ b/frontend/src/app/shared/components/references/content-selector.component.ts @@ -19,6 +19,8 @@ import { ApiUrlConfig, AppsState, ComponentContentsState, ContentDto, LanguageDt ], }) export class ContentSelectorComponent extends ResourceOwner implements OnInit { + private initialQuery?: string = undefined; + public readonly metaFields = META_FIELDS; @Output() @@ -36,6 +38,9 @@ export class ContentSelectorComponent extends ResourceOwner implements OnInit { @Input() public schemaNames?: ReadonlyArray; + @Input() + public query?: string; + @Input({ required: true }) public language!: LanguageDto; @@ -77,6 +82,8 @@ export class ContentSelectorComponent extends ResourceOwner implements OnInit { } public ngOnInit() { + this.initialQuery = this.query; + this.own( this.contentsState.statuses .subscribe(() => { @@ -101,7 +108,8 @@ export class ContentSelectorComponent extends ResourceOwner implements OnInit { if (schema) { this.contentsState.schema = schema; - this.contentsState.load(); + this.contentsState.search({ fullText: this.initialQuery || undefined }); + this.initialQuery = undefined; this.updateModel(); } diff --git a/frontend/src/app/shared/components/references/reference-input.component.html b/frontend/src/app/shared/components/references/reference-input.component.html index 258076a62..a5729262d 100644 --- a/frontend/src/app/shared/components/references/reference-input.component.html +++ b/frontend/src/app/shared/components/references/reference-input.component.html @@ -10,6 +10,7 @@ (select)="select($event)" [language]="language" [languages]="languages" + [query]="query" maxItems="1" [schemaIds]="schemaIds"> \ No newline at end of file diff --git a/frontend/src/app/shared/components/references/reference-input.component.ts b/frontend/src/app/shared/components/references/reference-input.component.ts index 1c4f6baa4..7a7a0b1fc 100644 --- a/frontend/src/app/shared/components/references/reference-input.component.ts +++ b/frontend/src/app/shared/components/references/reference-input.component.ts @@ -34,6 +34,9 @@ export class ReferenceInputComponent extends StatefulControlComponent; + @Input({ required: true }) + public query?: string; + @Input({ required: true }) public language!: LanguageDto; diff --git a/frontend/src/app/shared/components/search/queries/filter-comparison.component.html b/frontend/src/app/shared/components/search/queries/filter-comparison.component.html index 7f83efbc1..6c3ea4e37 100644 --- a/frontend/src/app/shared/components/search/queries/filter-comparison.component.html +++ b/frontend/src/app/shared/components/search/queries/filter-comparison.component.html @@ -45,7 +45,8 @@ [ngModel]="filter.value" (ngModelChange)="changeValue($event)" [language]="language" - [languages]="languages"> + [languages]="languages" + [query]="undefined"> diff --git a/frontend/src/app/shared/services/schemas.types.ts b/frontend/src/app/shared/services/schemas.types.ts index aa2722b0f..6f0c348ff 100644 --- a/frontend/src/app/shared/services/schemas.types.ts +++ b/frontend/src/app/shared/services/schemas.types.ts @@ -390,6 +390,7 @@ export class ReferencesFieldPropertiesDto extends FieldPropertiesDto { public readonly maxItems?: number; public readonly minItems?: number; public readonly mustBePublished?: boolean; + public readonly query?: string; public readonly resolveReference?: boolean; public readonly schemaIds?: ReadonlyArray; diff --git a/frontend/src/app/shared/state/contents.forms.spec.ts b/frontend/src/app/shared/state/contents.forms.spec.ts index be39f7a1d..24b5877bc 100644 --- a/frontend/src/app/shared/state/contents.forms.spec.ts +++ b/frontend/src/app/shared/state/contents.forms.spec.ts @@ -410,11 +410,11 @@ describe('ContentForm', () => { createField({ id: 4, properties: createProperties('Array'), - partitioning: 'invariant', nested: [ createNestedField({ id: 41, properties: createProperties('String') }), createNestedField({ id: 42, properties: createProperties('String', { defaultValue: 'Default' }), isDisabled: true }), ], + partitioning: 'invariant', }), ] }); @@ -452,6 +452,18 @@ describe('ContentForm', () => { }); describe('with complex form', () => { + const arraySetup = [ + { + value: [], + defaultValue: 'EmptyArray', + + }, + { + value: undefined, + defaultValue: 'Null', + }, + ]; + it('should not enabled disabled fields', () => { const contentForm = createForm([ createField({ id: 1, properties: createProperties('String') }), @@ -471,6 +483,32 @@ describe('ContentForm', () => { expectForm(contentForm.form, 'field3.de', { invalid: false }); }); + arraySetup.forEach(test => { + it(`should create array with ${test.defaultValue} default value`, () => { + const contentForm = createForm([ + createField({ + id: 4, + properties: createProperties('Array', { calculatedDefaultValue: test.defaultValue }), + }), + ]); + + expect(contentForm.value.field4.en).toEqual(test.value); + }); + }); + + arraySetup.forEach(test => { + it(`should create components with ${test.defaultValue} default value`, () => { + const contentForm = createForm([ + createField({ + id: 4, + properties: createProperties('Components', { calculatedDefaultValue: test.defaultValue }), + }), + ]); + + expect(contentForm.value.field4.en).toEqual(test.value); + }); + }); + it('should require field based on context condition', () => { const contentForm = createForm([ createField({ id: 1, properties: createProperties('Number'), partitioning: 'invariant' }), @@ -587,11 +625,11 @@ describe('ContentForm', () => { createField({ id: 4, properties: createProperties('Array'), - partitioning: 'invariant', nested: [ createNestedField({ id: 41, properties: createProperties('Number') }), createNestedField({ id: 42, properties: createProperties('Number') }), ], + partitioning: 'invariant', }), ], [{ field: 'field4.nested42', action: 'Disable', condition: 'itemData.nested41 > 100', @@ -620,11 +658,11 @@ describe('ContentForm', () => { createField({ id: 4, properties: createProperties('Array'), - partitioning: 'invariant', nested: [ createNestedField({ id: 41, properties: createProperties('Number') }), createNestedField({ id: 42, properties: createProperties('Number') }), ], + partitioning: 'invariant', }), ], [{ field: 'field4.nested42', action: 'Hide', condition: 'itemData.nested41 > 100', @@ -653,11 +691,11 @@ describe('ContentForm', () => { createField({ id: 4, properties: createProperties('Array'), - partitioning: 'language', nested: [ createNestedField({ id: 41, properties: createProperties('Number') }), createNestedField({ id: 42, properties: createProperties('Number') }), ], + partitioning: 'language', }), ], [{ field: 'field4.nested42', action: 'Hide', condition: 'itemData.nested41 > 100', @@ -686,11 +724,7 @@ describe('ContentForm', () => { const component = createSchema({ id: 2, fields: [ - createField({ - id: 1, - properties: createProperties('String'), - partitioning: 'invariant', - }), + createField({ id: 1, properties: createProperties('String'), partitioning: 'invariant' }), ], fieldRules: [{ field: 'field1', action: 'Hide', condition: 'data.field1 > 100', @@ -804,11 +838,7 @@ describe('ContentForm', () => { }); const contentForm = createForm([ - createField({ - id: 4, - properties: createProperties('Components'), - partitioning: 'invariant', - }), + createField({ id: 4, properties: createProperties('Components'), partitioning: 'invariant' }), ], [], { [componentId]: component, }); @@ -841,11 +871,7 @@ describe('ContentForm', () => { const component1 = createSchema({ id: 1, fields: [ - createField({ - id: 11, - properties: createProperties('String'), - partitioning: 'invariant', - }), + createField({ id: 11, properties: createProperties('String'), partitioning: 'invariant' }), ], }); @@ -853,20 +879,12 @@ describe('ContentForm', () => { const component2 = createSchema({ id: 2, fields: [ - createField({ - id: 21, - properties: createProperties('String'), - partitioning: 'invariant', - }), + createField({ id: 21, properties: createProperties('String'), partitioning: 'invariant' }), ], }); const contentForm = createForm([ - createField({ - id: 4, - properties: createProperties('Component'), - partitioning: 'invariant', - }), + createField({ id: 4, properties: createProperties('Component'), partitioning: 'invariant' }), ], [], { [component1Id]: component1, [component2Id]: component2, @@ -923,20 +941,11 @@ describe('ContentForm', () => { const component = createSchema({ id: 1, fields: [ - createField({ - id: 11, - properties: createProperties('String'), - partitioning: 'invariant', - }), - ], + createField({ id: 11, properties: createProperties('String'), partitioning: 'invariant' })], }); const contentForm = createForm([ - createField({ - id: 4, - properties: createProperties('Component'), - partitioning: 'invariant', - }), + createField({ id: 4, properties: createProperties('Component'), partitioning: 'invariant' }), ], [], { [componentId]: component, }); diff --git a/frontend/src/app/shared/state/contents.forms.ts b/frontend/src/app/shared/state/contents.forms.ts index 813abb2e9..a53392f18 100644 --- a/frontend/src/app/shared/state/contents.forms.ts +++ b/frontend/src/app/shared/state/contents.forms.ts @@ -345,6 +345,8 @@ export class FieldArrayForm extends AbstractContentForm this), FieldsValidators.create(field, isOptional)), isOptional, rules); + this.form.setValue(FieldDefaultValue.get(field, this.partition), { emitEvent: false }); + (this.form.template as any)['form'] = this; } diff --git a/frontend/src/app/shared/state/contents.forms.visitors.spec.ts b/frontend/src/app/shared/state/contents.forms.visitors.spec.ts index a74b64e76..2ec0ce978 100644 --- a/frontend/src/app/shared/state/contents.forms.visitors.spec.ts +++ b/frontend/src/app/shared/state/contents.forms.visitors.spec.ts @@ -42,10 +42,10 @@ describe('ArrayField', () => { expect(FieldDefaultValue.get(field, 'iv')).toEqual([]); }); - it('should return default value as null when configured', () => { + it('should return default value as undefined when configured', () => { const field2 = createField({ properties: createProperties('Array', { calculatedDefaultValue: 'Null' }) }); - expect(FieldDefaultValue.get(field2, 'iv')).toBeNull(); + expect(FieldDefaultValue.get(field2, 'iv')).toBeUndefined(); }); }); @@ -140,10 +140,10 @@ describe('ComponentsField', () => { expect(FieldDefaultValue.get(field, 'iv')).toEqual([]); }); - it('should return default value as null when configured', () => { + it('should return default value as undefined when configured', () => { const field2 = createField({ properties: createProperties('Components', { calculatedDefaultValue: 'Null' }) }); - expect(FieldDefaultValue.get(field2, 'iv')).toBeNull(); + expect(FieldDefaultValue.get(field2, 'iv')).toBeUndefined(); }); }); diff --git a/frontend/src/app/shared/state/contents.forms.visitors.ts b/frontend/src/app/shared/state/contents.forms.visitors.ts index 884bb3caa..d3d2ae047 100644 --- a/frontend/src/app/shared/state/contents.forms.visitors.ts +++ b/frontend/src/app/shared/state/contents.forms.visitors.ts @@ -419,7 +419,7 @@ export class FieldDefaultValue implements FieldPropertiesVisitor { public visitArray(properties: ArrayFieldPropertiesDto): any { if (properties.calculatedDefaultValue === 'Null') { - return null; + return undefined; } return []; @@ -427,7 +427,7 @@ export class FieldDefaultValue implements FieldPropertiesVisitor { public visitComponents(properties: ComponentsFieldPropertiesDto): any { if (properties.calculatedDefaultValue === 'Null') { - return null; + return undefined; } return []; diff --git a/frontend/src/app/shared/state/schemas.forms.ts b/frontend/src/app/shared/state/schemas.forms.ts index 2ff127472..83227059a 100644 --- a/frontend/src/app/shared/state/schemas.forms.ts +++ b/frontend/src/app/shared/state/schemas.forms.ts @@ -326,6 +326,7 @@ export class EditFieldFormVisitor implements FieldPropertiesVisitor { this.config['maxItems'] = new UntypedFormControl(undefined); this.config['minItems'] = new UntypedFormControl(undefined); this.config['mustBePublished'] = new UntypedFormControl(false); + this.config['query'] = new UntypedFormControl(undefined); this.config['resolveReference'] = new UntypedFormControl(false); this.config['schemaIds'] = new UntypedFormControl(undefined); }