Browse Source

References checkboxes

pull/523/head
Sebastian 6 years ago
parent
commit
8d072caa73
  1. 3
      backend/src/Squidex.Domain.Apps.Core.Model/Schemas/ReferencesFieldEditor.cs
  2. 7
      frontend/app/features/content/shared/forms/field-editor.component.html
  3. 4
      frontend/app/features/schemas/pages/schema/fields/types/date-time-ui.component.ts
  4. 4
      frontend/app/features/schemas/pages/schema/fields/types/number-ui.component.ts
  5. 7
      frontend/app/features/schemas/pages/schema/fields/types/references-ui.component.html
  6. 2
      frontend/app/features/schemas/pages/schema/fields/types/references-validation.component.html
  7. 2
      frontend/app/features/settings/pages/workflows/workflow.component.html
  8. 2
      frontend/app/framework/angular/forms/editors/checkbox-group.component.html
  9. 40
      frontend/app/framework/angular/forms/editors/checkbox-group.component.ts
  10. 119
      frontend/app/framework/angular/forms/editors/tag-editor.component.ts
  11. 1
      frontend/app/framework/internal.ts
  12. 136
      frontend/app/framework/utils/tag-values.ts
  13. 3
      frontend/app/shared/components/forms/references-checkboxes.component.html
  14. 0
      frontend/app/shared/components/forms/references-checkboxes.component.scss
  15. 124
      frontend/app/shared/components/forms/references-checkboxes.component.ts
  16. 47
      frontend/app/shared/components/forms/references-tag-converter.ts
  17. 2
      frontend/app/shared/components/forms/references-tags.component.html
  18. 54
      frontend/app/shared/components/forms/references-tags.component.ts
  19. 1
      frontend/app/shared/declarations.ts
  20. 4
      frontend/app/shared/module.ts
  21. 4
      frontend/app/shared/state/schema-tag-source.ts

3
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
}
}

7
frontend/app/features/content/shared/forms/field-editor.component.html

@ -101,6 +101,13 @@
[schemaId]="field.rawProperties.singleId">
</sqx-references-tags>
</ng-container>
<ng-container *ngSwitchCase="'Checkboxes'">
<sqx-references-checkboxes
[formControl]="editorControl"
[language]="language"
[schemaId]="field.rawProperties.singleId">
</sqx-references-checkboxes>
</ng-container>
</ng-container>
</ng-container>
<ng-container *ngSwitchCase="'String'">

4
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<boolean>;
public ngOnInit() {

4
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<boolean>;
public hideInlineEditable: Observable<boolean>;

7
frontend/app/features/schemas/pages/schema/fields/types/references-ui.component.html

@ -24,6 +24,13 @@
<span class="radio-label">Tags</span>
</label>
<label class="btn btn-radio" [class.active]="editForm.controls['editor'].value === 'Checkboxes'">
<input type="radio" class="radio-input" name="editor" formControlName="editor" value="Checkboxes" />
<i class="icon-control-Checkboxes"></i>
<span class="radio-label">Checkboxes</span>
</label>
</div>
</div>

2
frontend/app/features/schemas/pages/schema/fields/types/references-validation.component.html

@ -4,7 +4,7 @@
<div class="col-6">
<sqx-tag-editor placeholder=", to add schema" formControlName="schemaIds"
[converter]="schemasSource.converter | async" [suggestedValues]="(schemasSource.converter | async)?.suggestions">
[converter]="schemasSource.converter | async" [suggestions]="(schemasSource.converter | async)?.suggestions">
</sqx-tag-editor>
</div>
</div>

2
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">
</sqx-tag-editor>
<sqx-form-hint>

2
frontend/app/framework/angular/forms/editors/checkbox-group.component.html

@ -1,5 +1,5 @@
<div #container (sqxResized)="updateContainerWidth($event.width)">
<div class="form-check" [class.form-check-block]="!isSingleLine" [class.form-check-inline]="isSingleLine" *ngFor="let value of values">
<div class="form-check" [class.form-check-block]="!snapshot.isSingleLine" [class.form-check-inline]="snapshot.isSingleLine" *ngFor="let value of valuesSorted">
<input type="checkbox" class="form-check-input" id="{{controlId}}{{value}}"
(blur)="callTouched()"
(change)="check($event.target.checked, value)"

40
frontend/app/framework/angular/forms/editors/checkbox-group.component.ts

@ -9,7 +9,7 @@
import { AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, forwardRef, Input, OnChanges, ViewChild } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { MathHelper, StatefulControlComponent, Types } from '@app/framework/internal';
import { getTagValues, MathHelper, StatefulControlComponent, TagValue, Types } from '@app/framework/internal';
export const SQX_CHECKBOX_GROUP_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CheckboxGroupComponent), multi: true
@ -19,7 +19,10 @@ let CACHED_FONT: string;
interface State {
// The checked values.
checkedValues: ReadonlyArray<string>;
checkedValues: ReadonlyArray<TagValue>;
// True when all checkboxes can be shown as single line.
isSingleLine?: boolean;
}
@Component({
@ -33,18 +36,23 @@ interface State {
})
export class CheckboxGroupComponent extends StatefulControlComponent<State, string[]> 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<HTMLDivElement>;
@Input()
public values: ReadonlyArray<string> = [];
public set values(value: ReadonlyArray<string | TagValue>) {
this.valuesSorted = getTagValues(value);
this.writeValue(this.checkedValuesRaw);
}
public valuesSorted: ReadonlyArray<TagValue> = [];
constructor(changeDetector: ChangeDetectorRef) {
super(changeDetector, {
@ -97,9 +105,9 @@ export class CheckboxGroupComponent extends StatefulControlComponent<State, stri
let width = 0;
for (let text of this.values) {
for (let value of this.valuesSorted) {
width += 30;
width += ctx.measureText(text).width;
width += ctx.measureText(value.name).width;
}
this.childrenWidth = width;
@ -112,7 +120,9 @@ export class CheckboxGroupComponent extends StatefulControlComponent<State, stri
}
private calculateSingleLine() {
this.isSingleLine = this.childrenWidth < this.containerWidth;
const isSingleLine = this.childrenWidth < this.containerWidth;
this.next({ isSingleLine });
}
private calculateStyle() {
@ -135,12 +145,18 @@ export class CheckboxGroupComponent extends StatefulControlComponent<State, stri
}
public writeValue(obj: any) {
const checkedValues = Types.isArrayOfString(obj) ? obj.filter(x => 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<State, stri
this.next(s => ({ ...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;
}
}

119
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<T = any> {
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<State, Readonly
public inputElement: ElementRef<HTMLInputElement>;
@Input()
public converter: Converter = new StringConverter();
public converter = StringConverter.INSTANCE;
@Input()
public undefinedWhenEmpty = true;
@ -192,21 +94,8 @@ export class TagEditorComponent extends StatefulControlComponent<State, Readonly
public inputName = 'tag-editor';
@Input()
public set suggestedValues(value: ReadonlyArray<TagValue>) {
if (value) {
this.suggestionsSorted = value.sortedByString(x => x.lowerCaseName);
} else {
this.suggestionsSorted = [];
}
}
@Input()
public set suggestions(value: ReadonlyArray<string>) {
if (value) {
this.suggestionsSorted = value.map(x => new TagValue(x, x, x)).sortedByString(x => x.lowerCaseName);
} else {
this.suggestionsSorted = [];
}
public set suggestions(value: ReadonlyArray<string | TagValue>) {
this.suggestionsSorted = getTagValues(value);
}
@Input()

1
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';

136
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<T = any> {
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<string | TagValue>) {
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);
}

3
frontend/app/shared/components/forms/references-checkboxes.component.html

@ -0,0 +1,3 @@
<sqx-checkbox-group [formControl]="selectionControl"
[values]="snapshot.converter.suggestions">
</sqx-checkbox-group>

0
frontend/app/shared/components/forms/references-checkboxes.component.scss

124
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<State, ReadonlyArray<string>> implements OnChanges {
private itemCount: number;
private contentItems: ReadonlyArray<ContentDto> | 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<string>) {
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 });
}
}

47
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<TagValue> = [];
constructor(language: LanguageDto, contents: ReadonlyArray<ContentDto>) {
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<ContentDto>): ReadonlyArray<TagValue> {
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;
}
}

2
frontend/app/shared/components/forms/references-tags.component.html

@ -1,3 +1,3 @@
<sqx-tag-editor placeholder=", to add reference" [converter]="snapshot.converter" [formControl]="selectionControl"
[suggestedValues]="snapshot.converter.suggestions">
[suggestions]="snapshot.converter.suggestions">
</sqx-tag-editor>

54
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<TagValue> = [];
constructor(language: LanguageDto, contents: ReadonlyArray<ContentDto>) {
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<ContentDto>): ReadonlyArray<TagValue> {
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<State, Rea
private readonly appsState: AppsState,
private readonly contentsService: ContentsService
) {
super(changeDetector, { converter: new TagsConverter(null!, []) });
super(changeDetector, { converter: new ReferencesTagsConverter(null!, []) });
this.itemCount = uiOptions.get('referencesDropdownItemCount');
@ -125,6 +87,8 @@ export class ReferencesTagsComponent extends StatefulControlComponent<State, Rea
this.resetConverterState();
}
} else {
this.resetConverterState();
}
}
@ -143,14 +107,14 @@ export class ReferencesTagsComponent extends StatefulControlComponent<State, Rea
}
private resetConverterState() {
let converter: TagsConverter;
let converter: ReferencesTagsConverter;
if (this.isValid && this.contentItems && this.contentItems.length > 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);
}

1
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';

4
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,

4
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<TagValue>;
constructor(

Loading…
Cancel
Save