diff --git a/src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.scss b/src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.scss
index bee27d9b5..446243a46 100644
--- a/src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.scss
+++ b/src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.scss
@@ -1,10 +1,6 @@
@import '_vars';
@import '_mixins';
-.truncate {
- @include truncate;
-}
-
.faulted {
& {
color: $color-theme-error;
diff --git a/src/Squidex/app/features/content/declarations.ts b/src/Squidex/app/features/content/declarations.ts
index 853a1a061..a8d2ba651 100644
--- a/src/Squidex/app/features/content/declarations.ts
+++ b/src/Squidex/app/features/content/declarations.ts
@@ -15,11 +15,12 @@ export * from './pages/contents/contents-page.component';
export * from './pages/schemas/schemas-page.component';
export * from './shared/array-editor.component';
-export * from './shared/assets-editor.component';
export * from './shared/array-item.component';
+export * from './shared/assets-editor.component';
export * from './shared/content-item.component';
-export * from './shared/content-item-editor.component';
export * from './shared/content-status.component';
+export * from './shared/content-value.component';
+export * from './shared/content-value-editor.component';
export * from './shared/contents-selector.component';
export * from './shared/due-time-selector.component';
export * from './shared/field-editor.component';
diff --git a/src/Squidex/app/features/content/module.ts b/src/Squidex/app/features/content/module.ts
index 488f2a6c5..2592ae979 100644
--- a/src/Squidex/app/features/content/module.ts
+++ b/src/Squidex/app/features/content/module.ts
@@ -28,12 +28,13 @@ import {
ContentFieldComponent,
ContentHistoryPageComponent,
ContentItemComponent,
- ContentItemEditorComponent,
ContentPageComponent,
ContentsFiltersPageComponent,
ContentsPageComponent,
ContentsSelectorComponent,
ContentStatusComponent,
+ ContentValueComponent,
+ ContentValueEditorComponent,
DueTimeSelectorComponent,
FieldEditorComponent,
FieldLanguagesComponent,
@@ -113,12 +114,13 @@ const routes: Routes = [
ContentFieldComponent,
ContentHistoryPageComponent,
ContentItemComponent,
- ContentItemEditorComponent,
ContentPageComponent,
ContentsFiltersPageComponent,
- ContentStatusComponent,
ContentsPageComponent,
ContentsSelectorComponent,
+ ContentStatusComponent,
+ ContentValueComponent,
+ ContentValueEditorComponent,
DueTimeSelectorComponent,
FieldEditorComponent,
FieldLanguagesComponent,
diff --git a/src/Squidex/app/features/content/shared/content-item.component.html b/src/Squidex/app/features/content/shared/content-item.component.html
index 87fde104e..b145733d8 100644
--- a/src/Squidex/app/features/content/shared/content-item.component.html
+++ b/src/Squidex/app/features/content/shared/content-item.component.html
@@ -13,11 +13,11 @@
-
+
- {{values[i]}}
+
|
diff --git a/src/Squidex/app/features/content/shared/content-item.component.scss b/src/Squidex/app/features/content/shared/content-item.component.scss
index 12788118e..d56691f00 100644
--- a/src/Squidex/app/features/content/shared/content-item.component.scss
+++ b/src/Squidex/app/features/content/shared/content-item.component.scss
@@ -1,10 +1,6 @@
@import '_vars';
@import '_mixins';
-.truncate {
- @include truncate;
-}
-
.reference-edit {
& {
position: relative;
diff --git a/src/Squidex/app/features/content/shared/content-item.component.ts b/src/Squidex/app/features/content/shared/content-item.component.ts
index 5f27a6cf9..8e038d7b2 100644
--- a/src/Squidex/app/features/content/shared/content-item.component.ts
+++ b/src/Squidex/app/features/content/shared/content-item.component.ts
@@ -154,7 +154,7 @@ export class ContentItemComponent implements OnChanges {
if (Types.isUndefined(value)) {
this.values.push('');
} else {
- this.values.push(FieldFormatter.format(field, value));
+ this.values.push(FieldFormatter.format(field, value, true));
}
if (this.patchForm) {
diff --git a/src/Squidex/app/features/content/shared/content-item-editor.component.ts b/src/Squidex/app/features/content/shared/content-value-editor.component.ts
similarity index 97%
rename from src/Squidex/app/features/content/shared/content-item-editor.component.ts
rename to src/Squidex/app/features/content/shared/content-value-editor.component.ts
index cdfca6e8c..bdd6cd7b8 100644
--- a/src/Squidex/app/features/content/shared/content-item-editor.component.ts
+++ b/src/Squidex/app/features/content/shared/content-value-editor.component.ts
@@ -11,7 +11,7 @@ import { FormGroup } from '@angular/forms';
import { FieldDto } from '@app/shared';
@Component({
- selector: 'sqx-content-item-editor',
+ selector: 'sqx-content-value-editor',
template: `
@@ -60,7 +60,7 @@ import { FieldDto } from '@app/shared';
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
-export class ContentItemEditorComponent {
+export class ContentValueEditorComponent {
@Input()
public field: FieldDto;
diff --git a/src/Squidex/app/features/content/shared/content-value.component.ts b/src/Squidex/app/features/content/shared/content-value.component.ts
new file mode 100644
index 000000000..d7870c8c7
--- /dev/null
+++ b/src/Squidex/app/features/content/shared/content-value.component.ts
@@ -0,0 +1,31 @@
+/*
+ * Squidex Headless CMS
+ *
+ * @license
+ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
+ */
+
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
+
+import { HtmlValue, Types } from '@app/shared';
+
+@Component({
+ selector: 'sqx-content-value',
+ template: `
+
+ {{value}}
+
+
+
+
+ `,
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class ContentValueComponent {
+ public get isPlain() {
+ return !Types.is(this.value, HtmlValue);
+ }
+
+ @Input()
+ public value: any;
+}
\ No newline at end of file
diff --git a/src/Squidex/app/features/content/shared/references-dropdown.component.ts b/src/Squidex/app/features/content/shared/references-dropdown.component.ts
index ac9025e7e..e5ca9f971 100644
--- a/src/Squidex/app/features/content/shared/references-dropdown.component.ts
+++ b/src/Squidex/app/features/content/shared/references-dropdown.component.ts
@@ -140,13 +140,13 @@ export class ReferencesDropdownComponent extends StatefulControlComponent {
- const values: string[] = [];
+ const values: any[] = [];
for (let field of schema.listFields) {
const value = getRawValue(field, content.data, this.languageField);
if (!Types.isUndefined(value)) {
- values.push(FieldFormatter.format(field, value));
+ values.push(FieldFormatter.format(field, value, false));
}
}
diff --git a/src/Squidex/app/features/rules/pages/events/rule-events-page.component.scss b/src/Squidex/app/features/rules/pages/events/rule-events-page.component.scss
index 73d4911d2..0828441b3 100644
--- a/src/Squidex/app/features/rules/pages/events/rule-events-page.component.scss
+++ b/src/Squidex/app/features/rules/pages/events/rule-events-page.component.scss
@@ -5,10 +5,6 @@ h3 {
margin-bottom: 1rem;
}
-.truncate {
- @include truncate;
-}
-
.event {
&-stats {
font-size: .8rem;
diff --git a/src/Squidex/app/shared/state/contents.forms.spec.ts b/src/Squidex/app/shared/state/contents.forms.spec.ts
index 935b47266..05aa3a27a 100644
--- a/src/Squidex/app/shared/state/contents.forms.spec.ts
+++ b/src/Squidex/app/shared/state/contents.forms.spec.ts
@@ -25,6 +25,7 @@ import {
StringFieldPropertiesDto,
TagsFieldPropertiesDto
} from '@app/shared/internal';
+import { HtmlValue } from './contents.forms';
describe('SchemaDetailsDto', () => {
it('should return label as display name', () => {
@@ -227,7 +228,7 @@ describe('DateTimeField', () => {
});
it('should format to input if parsing failed', () => {
- expect(FieldFormatter.format(field, true)).toBe(true);
+ expect(FieldFormatter.format(field, true)).toBe(true);
});
it('should format to date', () => {
@@ -313,7 +314,37 @@ describe('NumberField', () => {
});
it('should format to number', () => {
- expect(FieldFormatter.format(field, 42)).toEqual(42);
+ expect(FieldFormatter.format(field, 42)).toEqual(42);
+ });
+
+ it('should format to stars if html allowed', () => {
+ const field2 = createField(new NumberFieldPropertiesDto('Stars'));
+
+ expect(FieldFormatter.format(field2, 3)).toEqual(new HtmlValue('★ ★ ★ '));
+ });
+
+ it('should format to short star view for many stars', () => {
+ const field2 = createField(new NumberFieldPropertiesDto('Stars'));
+
+ expect(FieldFormatter.format(field2, 42)).toEqual(new HtmlValue('★ 42'));
+ });
+
+ it('should format to short star view for no stars', () => {
+ const field2 = createField(new NumberFieldPropertiesDto('Stars'));
+
+ expect(FieldFormatter.format(field2, 0)).toEqual(new HtmlValue('★ 0'));
+ });
+
+ it('should format to short star view for negative stars', () => {
+ const field2 = createField(new NumberFieldPropertiesDto('Stars'));
+
+ expect(FieldFormatter.format(field2, -13)).toEqual(new HtmlValue('★ -13'));
+ });
+
+ it('should not format to stars if html not allowed', () => {
+ const field2 = createField(new NumberFieldPropertiesDto('Stars'));
+
+ expect(FieldFormatter.format(field2, 3, false)).toEqual(3);
});
it('should return default value for default properties', () => {
diff --git a/src/Squidex/app/shared/state/contents.forms.ts b/src/Squidex/app/shared/state/contents.forms.ts
index f74cc0d4d..da3a2084c 100644
--- a/src/Squidex/app/shared/state/contents.forms.ts
+++ b/src/Squidex/app/shared/state/contents.forms.ts
@@ -37,6 +37,13 @@ import {
UIFieldPropertiesDto
} from './../services/schemas.types';
+export class HtmlValue {
+ constructor(
+ public readonly html: string
+ ) {
+ }
+}
+
export class SaveQueryForm extends Form {
constructor(formBuilder: FormBuilder) {
super(formBuilder.group({
@@ -49,21 +56,22 @@ export class SaveQueryForm extends Form {
}
}
-export class FieldFormatter implements FieldPropertiesVisitor {
+export class FieldFormatter implements FieldPropertiesVisitor {
constructor(
- private readonly value: any
+ private readonly value: any,
+ private readonly allowHtml: boolean
) {
}
- public static format(field: FieldDto, value: any) {
+ public static format(field: FieldDto, value: any, allowHtml = true) {
if (value === null || value === undefined) {
return '';
}
- return field.properties.accept(new FieldFormatter(value));
+ return field.properties.accept(new FieldFormatter(value, allowHtml));
}
- public visitDateTime(properties: DateTimeFieldPropertiesDto): string {
+ public visitDateTime(properties: DateTimeFieldPropertiesDto): string | any {
try {
const parsed = DateTime.parseISO_UTC(this.value);
@@ -121,15 +129,28 @@ export class FieldFormatter implements FieldPropertiesVisitor {
return '';
}
- public visitNumber(properties: NumberFieldPropertiesDto): string {
+ public visitNumber(properties: NumberFieldPropertiesDto): string | HtmlValue | number {
+ if (Types.isNumber(this.value) && properties.editor === 'Stars' && this.allowHtml) {
+ if (this.value <= 0 || this.value > 6) {
+ return new HtmlValue(`★ ${this.value}`);
+ } else {
+ let html = '';
+
+ for (let i = 0; i < this.value; i++) {
+ html += '★ ';
+ }
+
+ return new HtmlValue(html);
+ }
+ }
return this.value;
}
- public visitString(properties: StringFieldPropertiesDto): string {
+ public visitString(properties: StringFieldPropertiesDto): any {
return this.value;
}
- public visitUI(properties: UIFieldPropertiesDto): string {
+ public visitUI(properties: UIFieldPropertiesDto): any {
return this.value;
}
}