From 8d072caa739a0ff86fdd81eb37a3215aae786c15 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 13 May 2020 17:21:35 +0200 Subject: [PATCH] References checkboxes --- .../Schemas/ReferencesFieldEditor.cs | 3 +- .../shared/forms/field-editor.component.html | 7 + .../fields/types/date-time-ui.component.ts | 4 +- .../fields/types/number-ui.component.ts | 4 +- .../fields/types/references-ui.component.html | 7 + .../references-validation.component.html | 2 +- .../pages/workflows/workflow.component.html | 2 +- .../editors/checkbox-group.component.html | 2 +- .../forms/editors/checkbox-group.component.ts | 40 ++++-- .../forms/editors/tag-editor.component.ts | 119 +-------------- frontend/app/framework/internal.ts | 1 + frontend/app/framework/utils/tag-values.ts | 136 ++++++++++++++++++ .../references-checkboxes.component.html | 3 + .../references-checkboxes.component.scss | 0 .../forms/references-checkboxes.component.ts | 124 ++++++++++++++++ .../forms/references-tag-converter.ts | 47 ++++++ .../forms/references-tags.component.html | 2 +- .../forms/references-tags.component.ts | 54 ++----- frontend/app/shared/declarations.ts | 1 + frontend/app/shared/module.ts | 4 +- .../app/shared/state/schema-tag-source.ts | 4 +- 21 files changed, 382 insertions(+), 184 deletions(-) create mode 100644 frontend/app/framework/utils/tag-values.ts create mode 100644 frontend/app/shared/components/forms/references-checkboxes.component.html create mode 100644 frontend/app/shared/components/forms/references-checkboxes.component.scss create mode 100644 frontend/app/shared/components/forms/references-checkboxes.component.ts create mode 100644 frontend/app/shared/components/forms/references-tag-converter.ts diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldEditor.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldEditor.cs index 07400c19a..c66725fe7 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldEditor.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldEditor.cs @@ -11,6 +11,7 @@ namespace Squidex.Domain.Apps.Core.Schemas { List, Dropdown, - Tags + Tags, + Checkboxes } } diff --git a/frontend/app/features/content/shared/forms/field-editor.component.html b/frontend/app/features/content/shared/forms/field-editor.component.html index 51586fb07..e12d96e33 100644 --- a/frontend/app/features/content/shared/forms/field-editor.component.html +++ b/frontend/app/features/content/shared/forms/field-editor.component.html @@ -101,6 +101,13 @@ [schemaId]="field.rawProperties.singleId"> + + + + diff --git a/frontend/app/features/schemas/pages/schema/fields/types/date-time-ui.component.ts b/frontend/app/features/schemas/pages/schema/fields/types/date-time-ui.component.ts index 9931a5a52..6827a0906 100644 --- a/frontend/app/features/schemas/pages/schema/fields/types/date-time-ui.component.ts +++ b/frontend/app/features/schemas/pages/schema/fields/types/date-time-ui.component.ts @@ -16,6 +16,8 @@ import { Observable } from 'rxjs'; templateUrl: 'date-time-ui.component.html' }) export class DateTimeUIComponent implements OnInit { + public readonly converter = FloatConverter.INSTANCE; + @Input() public editForm: FormGroup; @@ -25,8 +27,6 @@ export class DateTimeUIComponent implements OnInit { @Input() public properties: NumberFieldPropertiesDto; - public converter = new FloatConverter(); - public hideAllowedValues: Observable; public ngOnInit() { diff --git a/frontend/app/features/schemas/pages/schema/fields/types/number-ui.component.ts b/frontend/app/features/schemas/pages/schema/fields/types/number-ui.component.ts index e3844d814..e1ce00dae 100644 --- a/frontend/app/features/schemas/pages/schema/fields/types/number-ui.component.ts +++ b/frontend/app/features/schemas/pages/schema/fields/types/number-ui.component.ts @@ -17,6 +17,8 @@ import { map } from 'rxjs/operators'; templateUrl: 'number-ui.component.html' }) export class NumberUIComponent extends ResourceOwner implements OnInit { + public readonly converter = FloatConverter.INSTANCE; + @Input() public editForm: FormGroup; @@ -26,8 +28,6 @@ export class NumberUIComponent extends ResourceOwner implements OnInit { @Input() public properties: NumberFieldPropertiesDto; - public converter = new FloatConverter(); - public hideAllowedValues: Observable; public hideInlineEditable: Observable; diff --git a/frontend/app/features/schemas/pages/schema/fields/types/references-ui.component.html b/frontend/app/features/schemas/pages/schema/fields/types/references-ui.component.html index e282432dd..ee9f17c8c 100644 --- a/frontend/app/features/schemas/pages/schema/fields/types/references-ui.component.html +++ b/frontend/app/features/schemas/pages/schema/fields/types/references-ui.component.html @@ -24,6 +24,13 @@ Tags + diff --git a/frontend/app/features/schemas/pages/schema/fields/types/references-validation.component.html b/frontend/app/features/schemas/pages/schema/fields/types/references-validation.component.html index 0068ae4b6..d8b998dd7 100644 --- a/frontend/app/features/schemas/pages/schema/fields/types/references-validation.component.html +++ b/frontend/app/features/schemas/pages/schema/fields/types/references-validation.component.html @@ -4,7 +4,7 @@
+ [converter]="schemasSource.converter | async" [suggestions]="(schemasSource.converter | async)?.suggestions">
diff --git a/frontend/app/features/settings/pages/workflows/workflow.component.html b/frontend/app/features/settings/pages/workflows/workflow.component.html index 6b03e1eb3..6c2a71048 100644 --- a/frontend/app/features/settings/pages/workflows/workflow.component.html +++ b/frontend/app/features/settings/pages/workflows/workflow.component.html @@ -64,7 +64,7 @@ [converter]="schemasSource.converter | async" [ngModel]="workflow.schemaIds" (ngModelChange)="changeSchemaIds($event)" - [suggestedValues]="(schemasSource.converter | async)?.suggestions"> + [suggestions]="(schemasSource.converter | async)?.suggestions"> diff --git a/frontend/app/framework/angular/forms/editors/checkbox-group.component.html b/frontend/app/framework/angular/forms/editors/checkbox-group.component.html index 0825af933..a6d6fca0b 100644 --- a/frontend/app/framework/angular/forms/editors/checkbox-group.component.html +++ b/frontend/app/framework/angular/forms/editors/checkbox-group.component.html @@ -1,5 +1,5 @@
-
+
CheckboxGroupComponent), multi: true @@ -19,7 +19,10 @@ let CACHED_FONT: string; interface State { // The checked values. - checkedValues: ReadonlyArray; + checkedValues: ReadonlyArray; + + // True when all checkboxes can be shown as single line. + isSingleLine?: boolean; } @Component({ @@ -33,18 +36,23 @@ interface State { }) export class CheckboxGroupComponent extends StatefulControlComponent implements AfterViewInit, AfterViewChecked, OnChanges { private childrenWidth = 0; + private checkedValuesRaw: any; private containerWidth = 0; private labelsMeasured = false; public readonly controlId = MathHelper.guid(); - public isSingleLine = false; - @ViewChild('container', { static: false }) public containerElement: ElementRef; @Input() - public values: ReadonlyArray = []; + public set values(value: ReadonlyArray) { + this.valuesSorted = getTagValues(value); + + this.writeValue(this.checkedValuesRaw); + } + + public valuesSorted: ReadonlyArray = []; constructor(changeDetector: ChangeDetectorRef) { super(changeDetector, { @@ -97,9 +105,9 @@ export class CheckboxGroupComponent extends StatefulControlComponent this.values.indexOf(x) >= 0) : []; + this.checkedValuesRaw = obj; + + let checkedValues: TagValue[] = []; + + if (Types.isArray(obj) && obj.length > 0) { + checkedValues = this.valuesSorted.filter(x => obj.indexOf(x.value) >= 0); + } this.next(s => ({ ...s, checkedValues })); } - public check(isChecked: boolean, value: string) { + public check(isChecked: boolean, value: TagValue) { let checkedValues = this.snapshot.checkedValues; if (isChecked) { @@ -151,10 +167,10 @@ export class CheckboxGroupComponent extends StatefulControlComponent ({ ...s, checkedValues })); - this.callChange([...checkedValues]); + this.callChange(checkedValues.map(x => x.id)); } - public isChecked(value: string) { + public isChecked(value: TagValue) { return this.snapshot.checkedValues.indexOf(value) >= 0; } } diff --git a/frontend/app/framework/angular/forms/editors/tag-editor.component.ts b/frontend/app/framework/angular/forms/editors/tag-editor.component.ts index 0fbfc6296..cb990a2d6 100644 --- a/frontend/app/framework/angular/forms/editors/tag-editor.component.ts +++ b/frontend/app/framework/angular/forms/editors/tag-editor.component.ts @@ -9,109 +9,11 @@ import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, forwardRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild } from '@angular/core'; import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { fadeAnimation, Keys, ModalModel, StatefulControlComponent, Types } from '@app/framework/internal'; +import { fadeAnimation, getTagValues, Keys, ModalModel, StatefulControlComponent, StringConverter, TagValue, Types } from '@app/framework/internal'; import { distinctUntilChanged, map, tap } from 'rxjs/operators'; export const CONVERSION_FAILED = {}; -export class TagValue { - public readonly lowerCaseName: string; - - constructor( - public readonly id: any, - public readonly name: string, - public readonly value: T - ) { - this.lowerCaseName = name.toLowerCase(); - } - - public toString() { - return this.name; - } -} - -export interface Converter { - convertInput(input: string): TagValue | null; - - convertValue(value: any): TagValue | null; -} - -export class IntConverter implements Converter { - private static ZERO = new TagValue(0, '0', 0); - - public convertInput(input: string) { - if (input === '0') { - return IntConverter.ZERO; - } - - const parsed = parseInt(input, 10); - - if (parsed) { - return new TagValue(parsed, input, parsed); - } - - return null; - } - - public convertValue(value: any) { - if (Types.isNumber(value)) { - return new TagValue(value, `${value}`, value); - } - - return null; - } -} - -export class FloatConverter implements Converter { - private static ZERO = new TagValue(0, '0', 0); - - public convertInput(input: string) { - if (input === '0') { - return FloatConverter.ZERO; - } - - const parsed = parseFloat(input); - - if (parsed) { - return new TagValue(parsed, input, parsed); - } - - return null; - } - - public convertValue(value: any) { - if (Types.isNumber(value)) { - return new TagValue(value, `${value}`, value); - } - - return null; - } -} - -export class StringConverter implements Converter { - public convertInput(input: string) { - if (input) { - const trimmed = input.trim(); - - if (trimmed.length > 0) { - return new TagValue(trimmed, trimmed, trimmed); - } - } - - return null; - } - - public convertValue(value: any) { - if (Types.isString(value)) { - const trimmed = value.trim(); - - return new TagValue(trimmed, trimmed, trimmed); - } - - return null; - } -} - export const SQX_TAG_EDITOR_CONTROL_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TagEditorComponent), multi: true }; @@ -156,7 +58,7 @@ export class TagEditorComponent extends StatefulControlComponent; @Input() - public converter: Converter = new StringConverter(); + public converter = StringConverter.INSTANCE; @Input() public undefinedWhenEmpty = true; @@ -192,21 +94,8 @@ export class TagEditorComponent extends StatefulControlComponent) { - if (value) { - this.suggestionsSorted = value.sortedByString(x => x.lowerCaseName); - } else { - this.suggestionsSorted = []; - } - } - - @Input() - public set suggestions(value: ReadonlyArray) { - if (value) { - this.suggestionsSorted = value.map(x => new TagValue(x, x, x)).sortedByString(x => x.lowerCaseName); - } else { - this.suggestionsSorted = []; - } + public set suggestions(value: ReadonlyArray) { + this.suggestionsSorted = getTagValues(value); } @Input() diff --git a/frontend/app/framework/internal.ts b/frontend/app/framework/internal.ts index 8632c37fe..9f369fe02 100644 --- a/frontend/app/framework/internal.ts +++ b/frontend/app/framework/internal.ts @@ -37,5 +37,6 @@ export * from './utils/pager'; export * from './utils/picasso'; export * from './utils/rxjs-extensions'; export * from './utils/string-helper'; +export * from './utils/tag-values'; export * from './utils/types'; export * from './utils/version'; \ No newline at end of file diff --git a/frontend/app/framework/utils/tag-values.ts b/frontend/app/framework/utils/tag-values.ts new file mode 100644 index 000000000..ff67333c2 --- /dev/null +++ b/frontend/app/framework/utils/tag-values.ts @@ -0,0 +1,136 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { Types } from './types'; + +export class TagValue { + public readonly lowerCaseName: string; + + constructor( + public readonly id: any, + public readonly name: string, + public readonly value: T + ) { + this.lowerCaseName = name.toLowerCase(); + } + + public toString() { + return this.name; + } +} + +export interface TagConverter { + convertInput(input: string): TagValue | null; + + convertValue(value: any): TagValue | null; +} + +export class IntConverter implements TagConverter { + private static ZERO = new TagValue(0, '0', 0); + + public static readonly INSTANCE: TagConverter = new IntConverter(); + + private constructor() {} + + public convertInput(input: string) { + if (input === '0') { + return IntConverter.ZERO; + } + + const parsed = parseInt(input, 10); + + if (parsed) { + return new TagValue(parsed, input, parsed); + } + + return null; + } + + public convertValue(value: any) { + if (Types.isNumber(value)) { + return new TagValue(value, `${value}`, value); + } + + return null; + } +} + +export class FloatConverter implements TagConverter { + private static ZERO = new TagValue(0, '0', 0); + + public static readonly INSTANCE: TagConverter = new FloatConverter(); + + private constructor() {} + + public convertInput(input: string) { + if (input === '0') { + return FloatConverter.ZERO; + } + + const parsed = parseFloat(input); + + if (parsed) { + return new TagValue(parsed, input, parsed); + } + + return null; + } + + public convertValue(value: any) { + if (Types.isNumber(value)) { + return new TagValue(value, `${value}`, value); + } + + return null; + } +} + +export class StringConverter implements TagConverter { + public static readonly INSTANCE: TagConverter = new StringConverter(); + + private constructor() {} + + public convertInput(input: string) { + if (input) { + const trimmed = input.trim(); + + if (trimmed.length > 0) { + return new TagValue(trimmed, trimmed, trimmed); + } + } + + return null; + } + + public convertValue(value: any) { + if (Types.isString(value)) { + const trimmed = value.trim(); + + return new TagValue(trimmed, trimmed, trimmed); + } + + return null; + } +} + +export function getTagValues(values: ReadonlyArray) { + + if (!Types.isArray(values)) { + return []; + } + const result: TagValue[] = []; + + for (let value of values) { + if (Types.isString(value)) { + result.push(new TagValue(value, value, value)); + } else { + result.push(value); + } + } + + return result.sortedByString(x => x.lowerCaseName); +} \ No newline at end of file diff --git a/frontend/app/shared/components/forms/references-checkboxes.component.html b/frontend/app/shared/components/forms/references-checkboxes.component.html new file mode 100644 index 000000000..10b4bcd32 --- /dev/null +++ b/frontend/app/shared/components/forms/references-checkboxes.component.html @@ -0,0 +1,3 @@ + + \ No newline at end of file diff --git a/frontend/app/shared/components/forms/references-checkboxes.component.scss b/frontend/app/shared/components/forms/references-checkboxes.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/app/shared/components/forms/references-checkboxes.component.ts b/frontend/app/shared/components/forms/references-checkboxes.component.ts new file mode 100644 index 000000000..436dd5448 --- /dev/null +++ b/frontend/app/shared/components/forms/references-checkboxes.component.ts @@ -0,0 +1,124 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input, OnChanges, SimpleChanges } from '@angular/core'; +import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { AppsState, ContentDto, ContentsService, LanguageDto, StatefulControlComponent, UIOptions } from '@app/shared/internal'; +import { ReferencesTagsConverter } from './references-tag-converter'; + +export const SQX_REFERENCES_CHECKBOXES_CONTROL_VALUE_ACCESSOR: any = { + provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ReferencesCheckboxesComponent), multi: true +}; + +interface State { + // The tags converter. + converter: ReferencesTagsConverter; +} + +const NO_EMIT = { emitEvent: false }; + +@Component({ + selector: 'sqx-references-checkboxes', + styleUrls: ['./references-checkboxes.component.scss'], + templateUrl: './references-checkboxes.component.html', + providers: [ + SQX_REFERENCES_CHECKBOXES_CONTROL_VALUE_ACCESSOR + ], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class ReferencesCheckboxesComponent extends StatefulControlComponent> implements OnChanges { + private itemCount: number; + private contentItems: ReadonlyArray | null = null; + + @Input() + public schemaId: string; + + @Input() + public language: LanguageDto; + + public get isValid() { + return !!this.schemaId && !!this.language; + } + + public selectionControl = new FormControl([]); + + constructor(changeDetector: ChangeDetectorRef, uiOptions: UIOptions, + private readonly appsState: AppsState, + private readonly contentsService: ContentsService + ) { + super(changeDetector, { converter: new ReferencesTagsConverter(null!, []) }); + + this.itemCount = uiOptions.get('referencesDropdownItemCount'); + + this.own( + this.selectionControl.valueChanges + .subscribe((value: string[]) => { + if (value && value.length > 0) { + this.callTouched(); + this.callChange(value); + } else { + this.callTouched(); + this.callChange(null); + } + })); + } + + public ngOnChanges(changes: SimpleChanges) { + if (changes['schemaId']) { + this.resetState(); + + if (this.isValid) { + this.contentsService.getContents(this.appsState.appName, this.schemaId, { take: this.itemCount }) + .subscribe(contents => { + this.contentItems = contents.items; + + this.resetConverterState(); + }, () => { + this.contentItems = null; + + this.resetConverterState(); + }); + } else { + this.contentItems = null; + + this.resetConverterState(); + } + } else { + this.resetConverterState(); + } + } + + public setDisabledState(isDisabled: boolean) { + if (isDisabled) { + this.selectionControl.disable(NO_EMIT); + } else if (this.isValid) { + this.selectionControl.enable(NO_EMIT); + } + + super.setDisabledState(isDisabled); + } + + public writeValue(obj: ReadonlyArray) { + this.selectionControl.setValue(obj, NO_EMIT); + } + + private resetConverterState() { + let converter: ReferencesTagsConverter; + + if (this.isValid && this.contentItems && this.contentItems.length > 0) { + converter = new ReferencesTagsConverter(this.language, this.contentItems); + + this.selectionControl.enable(NO_EMIT); + } else { + converter = new ReferencesTagsConverter(null!, []); + + this.selectionControl.disable(NO_EMIT); + } + + this.next({ converter }); + } +} diff --git a/frontend/app/shared/components/forms/references-tag-converter.ts b/frontend/app/shared/components/forms/references-tag-converter.ts new file mode 100644 index 000000000..744dd9f59 --- /dev/null +++ b/frontend/app/shared/components/forms/references-tag-converter.ts @@ -0,0 +1,47 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { ContentDto, getContentValue, LanguageDto, TagConverter, TagValue } from '@app/shared/internal'; + +export class ReferencesTagsConverter implements TagConverter { + public suggestions: ReadonlyArray = []; + + constructor(language: LanguageDto, contents: ReadonlyArray) { + this.suggestions = this.createTags(language, contents); + } + + public convertInput(input: string) { + const result = this.suggestions.find(x => x.name === input); + + return result || null; + } + + public convertValue(value: any) { + const result = this.suggestions.find(x => x.id === value); + + return result || null; + } + + private createTags(language: LanguageDto, contents: ReadonlyArray): ReadonlyArray { + if (contents.length === 0) { + return []; + } + + const values = contents.map(content => { + const name = + content.referenceFields + .map(f => getContentValue(content, language, f, false)) + .map(v => v.formatted || 'No value') + .filter(v => !!v) + .join(', '); + + return new TagValue(content.id, name, content.id); + }); + + return values; + } +} \ No newline at end of file diff --git a/frontend/app/shared/components/forms/references-tags.component.html b/frontend/app/shared/components/forms/references-tags.component.html index d501ef9a4..9ca5b35d9 100644 --- a/frontend/app/shared/components/forms/references-tags.component.html +++ b/frontend/app/shared/components/forms/references-tags.component.html @@ -1,3 +1,3 @@ + [suggestions]="snapshot.converter.suggestions"> \ No newline at end of file diff --git a/frontend/app/shared/components/forms/references-tags.component.ts b/frontend/app/shared/components/forms/references-tags.component.ts index a6fccc18f..0e548e1e6 100644 --- a/frontend/app/shared/components/forms/references-tags.component.ts +++ b/frontend/app/shared/components/forms/references-tags.component.ts @@ -7,54 +7,16 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input, OnChanges, SimpleChanges } from '@angular/core'; import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms'; -import { AppsState, ContentDto, ContentsService, Converter, getContentValue, LanguageDto, StatefulControlComponent, TagValue, UIOptions } from '@app/shared/internal'; +import { AppsState, ContentDto, ContentsService, LanguageDto, StatefulControlComponent, UIOptions } from '@app/shared/internal'; +import { ReferencesTagsConverter } from './references-tag-converter'; export const SQX_REFERENCES_TAGS_CONTROL_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ReferencesTagsComponent), multi: true }; -class TagsConverter implements Converter { - public suggestions: ReadonlyArray = []; - - constructor(language: LanguageDto, contents: ReadonlyArray) { - this.suggestions = this.createTags(language, contents); - } - - public convertInput(input: string) { - const result = this.suggestions.find(x => x.name === input); - - return result || null; - } - - public convertValue(value: any) { - const result = this.suggestions.find(x => x.id === value); - - return result || null; - } - - private createTags(language: LanguageDto, contents: ReadonlyArray): ReadonlyArray { - if (contents.length === 0) { - return []; - } - - const values = contents.map(content => { - const name = - content.referenceFields - .map(f => getContentValue(content, language, f, false)) - .map(v => v.formatted || 'No value') - .filter(v => !!v) - .join(', '); - - return new TagValue(content.id, name, content.id); - }); - - return values; - } -} - interface State { // The tags converter. - converter: TagsConverter; + converter: ReferencesTagsConverter; } const NO_EMIT = { emitEvent: false }; @@ -88,7 +50,7 @@ export class ReferencesTagsComponent extends StatefulControlComponent 0) { - converter = new TagsConverter(this.language, this.contentItems); + converter = new ReferencesTagsConverter(this.language, this.contentItems); this.selectionControl.enable(NO_EMIT); } else { - converter = new TagsConverter(null!, []); + converter = new ReferencesTagsConverter(null!, []); this.selectionControl.disable(NO_EMIT); } diff --git a/frontend/app/shared/declarations.ts b/frontend/app/shared/declarations.ts index f0b61ff1e..55d10fd3b 100644 --- a/frontend/app/shared/declarations.ts +++ b/frontend/app/shared/declarations.ts @@ -23,6 +23,7 @@ export * from './components/comments/comments.component'; export * from './components/forms/geolocation-editor.component'; export * from './components/forms/language-selector.component'; export * from './components/forms/markdown-editor.component'; +export * from './components/forms/references-checkboxes.component'; export * from './components/forms/references-dropdown.component'; export * from './components/forms/references-tags.component'; export * from './components/forms/rich-editor.component'; diff --git a/frontend/app/shared/module.ts b/frontend/app/shared/module.ts index 472b65294..1c5588126 100644 --- a/frontend/app/shared/module.ts +++ b/frontend/app/shared/module.ts @@ -13,7 +13,7 @@ import { ModuleWithProviders, NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { SqxFrameworkModule } from '@app/framework'; import { MentionModule } from 'angular-mentions'; -import { AppFormComponent, AppLanguagesService, AppMustExistGuard, AppsService, AppsState, AssetComponent, AssetDialogComponent, AssetFolderComponent, AssetFolderDialogComponent, AssetHistoryComponent, AssetPathComponent, AssetPreviewUrlPipe, AssetsDialogState, AssetsListComponent, AssetsSelectorComponent, AssetsService, AssetsState, AssetUploaderComponent, AssetUploaderState, AssetUrlPipe, AuthInterceptor, AuthService, AutoSaveService, BackupsService, BackupsState, ClientsService, ClientsState, CommentComponent, CommentsComponent, CommentsService, ContentMustExistGuard, ContentsService, ContentsState, ContributorsService, ContributorsState, FileIconPipe, FilterComparisonComponent, FilterLogicalComponent, FilterNodeComponent, GeolocationEditorComponent, GraphQlService, HelpComponent, HelpMarkdownPipe, HelpService, HistoryComponent, HistoryListComponent, HistoryMessagePipe, HistoryService, ImageCropperComponent, ImageFocusPointComponent, LanguageSelectorComponent, LanguagesService, LanguagesState, LoadAppsGuard, LoadLanguagesGuard, MarkdownEditorComponent, MustBeAuthenticatedGuard, MustBeNotAuthenticatedGuard, NewsService, PatternsService, PatternsState, PlansService, PlansState, QueryComponent, QueryListComponent, QueryPathComponent, ReferencesDropdownComponent, ReferencesTagsComponent, RichEditorComponent, RolesService, RolesState, RuleEventsState, RulesService, RulesState, SavedQueriesComponent, SchemaCategoryComponent, SchemaMustExistGuard, SchemaMustExistPublishedGuard, SchemaMustNotBeSingletonGuard, SchemasService, SchemasState, SchemaTagSource, SearchFormComponent, SortingComponent, StockPhotoService, TableHeaderComponent, TranslationsService, UIService, UIState, UnsetAppGuard, UnsetContentGuard, UsagesService, UserDtoPicture, UserIdPicturePipe, UserNamePipe, UserNameRefPipe, UserPicturePipe, UserPictureRefPipe, UsersProviderService, UsersService, WorkflowsService, WorkflowsState } from './declarations'; +import { AppFormComponent, AppLanguagesService, AppMustExistGuard, AppsService, AppsState, AssetComponent, AssetDialogComponent, AssetFolderComponent, AssetFolderDialogComponent, AssetHistoryComponent, AssetPathComponent, AssetPreviewUrlPipe, AssetsDialogState, AssetsListComponent, AssetsSelectorComponent, AssetsService, AssetsState, AssetUploaderComponent, AssetUploaderState, AssetUrlPipe, AuthInterceptor, AuthService, AutoSaveService, BackupsService, BackupsState, ClientsService, ClientsState, CommentComponent, CommentsComponent, CommentsService, ContentMustExistGuard, ContentsService, ContentsState, ContributorsService, ContributorsState, FileIconPipe, FilterComparisonComponent, FilterLogicalComponent, FilterNodeComponent, GeolocationEditorComponent, GraphQlService, HelpComponent, HelpMarkdownPipe, HelpService, HistoryComponent, HistoryListComponent, HistoryMessagePipe, HistoryService, ImageCropperComponent, ImageFocusPointComponent, LanguageSelectorComponent, LanguagesService, LanguagesState, LoadAppsGuard, LoadLanguagesGuard, MarkdownEditorComponent, MustBeAuthenticatedGuard, MustBeNotAuthenticatedGuard, NewsService, PatternsService, PatternsState, PlansService, PlansState, QueryComponent, QueryListComponent, QueryPathComponent, ReferencesCheckboxesComponent, ReferencesDropdownComponent, ReferencesTagsComponent, RichEditorComponent, RolesService, RolesState, RuleEventsState, RulesService, RulesState, SavedQueriesComponent, SchemaCategoryComponent, SchemaMustExistGuard, SchemaMustExistPublishedGuard, SchemaMustNotBeSingletonGuard, SchemasService, SchemasState, SchemaTagSource, SearchFormComponent, SortingComponent, StockPhotoService, TableHeaderComponent, TranslationsService, UIService, UIState, UnsetAppGuard, UnsetContentGuard, UsagesService, UserDtoPicture, UserIdPicturePipe, UserNamePipe, UserNameRefPipe, UserPicturePipe, UserPictureRefPipe, UsersProviderService, UsersService, WorkflowsService, WorkflowsState } from './declarations'; import { SearchService } from './services/search.service'; @NgModule({ @@ -55,6 +55,7 @@ import { SearchService } from './services/search.service'; QueryComponent, QueryListComponent, QueryPathComponent, + ReferencesCheckboxesComponent, ReferencesDropdownComponent, ReferencesTagsComponent, RichEditorComponent, @@ -95,6 +96,7 @@ import { SearchService } from './services/search.service'; LanguageSelectorComponent, MarkdownEditorComponent, QueryListComponent, + ReferencesCheckboxesComponent, ReferencesDropdownComponent, ReferencesTagsComponent, RichEditorComponent, diff --git a/frontend/app/shared/state/schema-tag-source.ts b/frontend/app/shared/state/schema-tag-source.ts index 543cbe144..360dc1b68 100644 --- a/frontend/app/shared/state/schema-tag-source.ts +++ b/frontend/app/shared/state/schema-tag-source.ts @@ -6,12 +6,12 @@ */ import { Injectable } from '@angular/core'; -import { Converter, TagValue } from '@app/framework'; +import { TagConverter, TagValue } from '@app/framework'; import { map, shareReplay } from 'rxjs/operators'; import { SchemaDto } from './../services/schemas.service'; import { SchemasState } from './schemas.state'; -class SchemaConverter implements Converter { +class SchemaConverter implements TagConverter { public suggestions: ReadonlyArray; constructor(