Browse Source

Stars view in content list.

pull/387/head
Sebastian Stehle 7 years ago
parent
commit
fefa204161
  1. 4
      src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.scss
  2. 5
      src/Squidex/app/features/content/declarations.ts
  3. 8
      src/Squidex/app/features/content/module.ts
  4. 4
      src/Squidex/app/features/content/shared/content-item.component.html
  5. 4
      src/Squidex/app/features/content/shared/content-item.component.scss
  6. 2
      src/Squidex/app/features/content/shared/content-item.component.ts
  7. 4
      src/Squidex/app/features/content/shared/content-value-editor.component.ts
  8. 31
      src/Squidex/app/features/content/shared/content-value.component.ts
  9. 4
      src/Squidex/app/features/content/shared/references-dropdown.component.ts
  10. 4
      src/Squidex/app/features/rules/pages/events/rule-events-page.component.scss
  11. 35
      src/Squidex/app/shared/state/contents.forms.spec.ts
  12. 37
      src/Squidex/app/shared/state/contents.forms.ts

4
src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.scss

@ -1,10 +1,6 @@
@import '_vars'; @import '_vars';
@import '_mixins'; @import '_mixins';
.truncate {
@include truncate;
}
.faulted { .faulted {
& { & {
color: $color-theme-error; color: $color-theme-error;

5
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 './pages/schemas/schemas-page.component';
export * from './shared/array-editor.component'; export * from './shared/array-editor.component';
export * from './shared/assets-editor.component';
export * from './shared/array-item.component'; export * from './shared/array-item.component';
export * from './shared/assets-editor.component';
export * from './shared/content-item.component'; export * from './shared/content-item.component';
export * from './shared/content-item-editor.component';
export * from './shared/content-status.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/contents-selector.component';
export * from './shared/due-time-selector.component'; export * from './shared/due-time-selector.component';
export * from './shared/field-editor.component'; export * from './shared/field-editor.component';

8
src/Squidex/app/features/content/module.ts

@ -28,12 +28,13 @@ import {
ContentFieldComponent, ContentFieldComponent,
ContentHistoryPageComponent, ContentHistoryPageComponent,
ContentItemComponent, ContentItemComponent,
ContentItemEditorComponent,
ContentPageComponent, ContentPageComponent,
ContentsFiltersPageComponent, ContentsFiltersPageComponent,
ContentsPageComponent, ContentsPageComponent,
ContentsSelectorComponent, ContentsSelectorComponent,
ContentStatusComponent, ContentStatusComponent,
ContentValueComponent,
ContentValueEditorComponent,
DueTimeSelectorComponent, DueTimeSelectorComponent,
FieldEditorComponent, FieldEditorComponent,
FieldLanguagesComponent, FieldLanguagesComponent,
@ -113,12 +114,13 @@ const routes: Routes = [
ContentFieldComponent, ContentFieldComponent,
ContentHistoryPageComponent, ContentHistoryPageComponent,
ContentItemComponent, ContentItemComponent,
ContentItemEditorComponent,
ContentPageComponent, ContentPageComponent,
ContentsFiltersPageComponent, ContentsFiltersPageComponent,
ContentStatusComponent,
ContentsPageComponent, ContentsPageComponent,
ContentsSelectorComponent, ContentsSelectorComponent,
ContentStatusComponent,
ContentValueComponent,
ContentValueEditorComponent,
DueTimeSelectorComponent, DueTimeSelectorComponent,
FieldEditorComponent, FieldEditorComponent,
FieldLanguagesComponent, FieldLanguagesComponent,

4
src/Squidex/app/features/content/shared/content-item.component.html

@ -13,11 +13,11 @@
<td class="cell-auto" *ngFor="let field of schema.listFields; let i = index; trackBy: trackByField.bind(this)" [sqxStopClick]="isDirty || (field.isInlineEditable && patchAllowed)"> <td class="cell-auto" *ngFor="let field of schema.listFields; let i = index; trackBy: trackByField.bind(this)" [sqxStopClick]="isDirty || (field.isInlineEditable && patchAllowed)">
<ng-container *ngIf="field.isInlineEditable && patchAllowed; else displayTemplate"> <ng-container *ngIf="field.isInlineEditable && patchAllowed; else displayTemplate">
<sqx-content-item-editor [form]="patchForm.form" [field]="field"></sqx-content-item-editor> <sqx-content-value-editor [form]="patchForm.form" [field]="field"></sqx-content-value-editor>
</ng-container> </ng-container>
<ng-template #displayTemplate> <ng-template #displayTemplate>
<span class="truncate">{{values[i]}}</span> <sqx-content-value [value]="values[i]"></sqx-content-value>
</ng-template> </ng-template>
</td> </td>

4
src/Squidex/app/features/content/shared/content-item.component.scss

@ -1,10 +1,6 @@
@import '_vars'; @import '_vars';
@import '_mixins'; @import '_mixins';
.truncate {
@include truncate;
}
.reference-edit { .reference-edit {
& { & {
position: relative; position: relative;

2
src/Squidex/app/features/content/shared/content-item.component.ts

@ -154,7 +154,7 @@ export class ContentItemComponent implements OnChanges {
if (Types.isUndefined(value)) { if (Types.isUndefined(value)) {
this.values.push(''); this.values.push('');
} else { } else {
this.values.push(FieldFormatter.format(field, value)); this.values.push(FieldFormatter.format(field, value, true));
} }
if (this.patchForm) { if (this.patchForm) {

4
src/Squidex/app/features/content/shared/content-item-editor.component.ts → 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'; import { FieldDto } from '@app/shared';
@Component({ @Component({
selector: 'sqx-content-item-editor', selector: 'sqx-content-value-editor',
template: ` template: `
<div [formGroup]="form"> <div [formGroup]="form">
<ng-container [ngSwitch]="field.properties.fieldType"> <ng-container [ngSwitch]="field.properties.fieldType">
@ -60,7 +60,7 @@ import { FieldDto } from '@app/shared';
</div>`, </div>`,
changeDetection: ChangeDetectionStrategy.OnPush changeDetection: ChangeDetectionStrategy.OnPush
}) })
export class ContentItemEditorComponent { export class ContentValueEditorComponent {
@Input() @Input()
public field: FieldDto; public field: FieldDto;

31
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: `
<ng-container *ngIf="isPlain; else html">
<span class="truncate">{{value}}</span>
</ng-container>
<ng-template #html>
<span class="truncate" [innerHTML]="value.html"></span>
</ng-template>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ContentValueComponent {
public get isPlain() {
return !Types.is(this.value, HtmlValue);
}
@Input()
public value: any;
}

4
src/Squidex/app/features/content/shared/references-dropdown.component.ts

@ -140,13 +140,13 @@ export class ReferencesDropdownComponent extends StatefulControlComponent<State,
} }
return contents.map(content => { return contents.map(content => {
const values: string[] = []; const values: any[] = [];
for (let field of schema.listFields) { for (let field of schema.listFields) {
const value = getRawValue(field, content.data, this.languageField); const value = getRawValue(field, content.data, this.languageField);
if (!Types.isUndefined(value)) { if (!Types.isUndefined(value)) {
values.push(FieldFormatter.format(field, value)); values.push(FieldFormatter.format(field, value, false));
} }
} }

4
src/Squidex/app/features/rules/pages/events/rule-events-page.component.scss

@ -5,10 +5,6 @@ h3 {
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.truncate {
@include truncate;
}
.event { .event {
&-stats { &-stats {
font-size: .8rem; font-size: .8rem;

35
src/Squidex/app/shared/state/contents.forms.spec.ts

@ -25,6 +25,7 @@ import {
StringFieldPropertiesDto, StringFieldPropertiesDto,
TagsFieldPropertiesDto TagsFieldPropertiesDto
} from '@app/shared/internal'; } from '@app/shared/internal';
import { HtmlValue } from './contents.forms';
describe('SchemaDetailsDto', () => { describe('SchemaDetailsDto', () => {
it('should return label as display name', () => { it('should return label as display name', () => {
@ -227,7 +228,7 @@ describe('DateTimeField', () => {
}); });
it('should format to input if parsing failed', () => { it('should format to input if parsing failed', () => {
expect(FieldFormatter.format(field, true)).toBe(<any>true); expect(FieldFormatter.format(field, true)).toBe(true);
}); });
it('should format to date', () => { it('should format to date', () => {
@ -313,7 +314,37 @@ describe('NumberField', () => {
}); });
it('should format to number', () => { it('should format to number', () => {
expect(FieldFormatter.format(field, 42)).toEqual(<any>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('&#9733; &#9733; &#9733; '));
});
it('should format to short star view for many stars', () => {
const field2 = createField(new NumberFieldPropertiesDto('Stars'));
expect(FieldFormatter.format(field2, 42)).toEqual(new HtmlValue('&#9733; 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('&#9733; 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('&#9733; -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', () => { it('should return default value for default properties', () => {

37
src/Squidex/app/shared/state/contents.forms.ts

@ -37,6 +37,13 @@ import {
UIFieldPropertiesDto UIFieldPropertiesDto
} from './../services/schemas.types'; } from './../services/schemas.types';
export class HtmlValue {
constructor(
public readonly html: string
) {
}
}
export class SaveQueryForm extends Form<FormGroup, any> { export class SaveQueryForm extends Form<FormGroup, any> {
constructor(formBuilder: FormBuilder) { constructor(formBuilder: FormBuilder) {
super(formBuilder.group({ super(formBuilder.group({
@ -49,21 +56,22 @@ export class SaveQueryForm extends Form<FormGroup, any> {
} }
} }
export class FieldFormatter implements FieldPropertiesVisitor<string> { export class FieldFormatter implements FieldPropertiesVisitor<any> {
constructor( 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) { if (value === null || value === undefined) {
return ''; 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 { try {
const parsed = DateTime.parseISO_UTC(this.value); const parsed = DateTime.parseISO_UTC(this.value);
@ -121,15 +129,28 @@ export class FieldFormatter implements FieldPropertiesVisitor<string> {
return '<Json />'; return '<Json />';
} }
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(`&#9733; ${this.value}`);
} else {
let html = '';
for (let i = 0; i < this.value; i++) {
html += '&#9733; ';
}
return new HtmlValue(html);
}
}
return this.value; return this.value;
} }
public visitString(properties: StringFieldPropertiesDto): string { public visitString(properties: StringFieldPropertiesDto): any {
return this.value; return this.value;
} }
public visitUI(properties: UIFieldPropertiesDto): string { public visitUI(properties: UIFieldPropertiesDto): any {
return this.value; return this.value;
} }
} }

Loading…
Cancel
Save