Browse Source

Progress with comparison

pull/345/head
Sebastian Stehle 7 years ago
parent
commit
72895f897a
  1. 2
      src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts
  2. 4
      src/Squidex/app/features/content/pages/content/content-field.component.html
  3. 41
      src/Squidex/app/features/content/pages/content/content-field.component.ts
  4. 2
      src/Squidex/app/features/content/pages/content/content-history-page.component.html
  5. 6
      src/Squidex/app/features/content/pages/content/content-history-page.component.ts
  6. 4
      src/Squidex/app/features/content/pages/content/content-page.component.html
  7. 25
      src/Squidex/app/features/content/pages/content/content-page.component.ts
  8. 10
      src/Squidex/app/features/content/pages/content/field-languages.component.ts
  9. 2
      src/Squidex/app/features/content/pages/contents/contents-page.component.html
  10. 2
      src/Squidex/app/features/content/pages/contents/contents-page.component.ts
  11. 3
      src/Squidex/app/features/content/pages/messages.ts
  12. 3
      src/Squidex/app/features/content/shared/array-editor.component.ts
  13. 3
      src/Squidex/app/features/content/shared/array-item.component.ts
  14. 10
      src/Squidex/app/features/content/shared/assets-editor.component.html
  15. 3
      src/Squidex/app/features/content/shared/assets-editor.component.scss
  16. 9
      src/Squidex/app/features/content/shared/assets-editor.component.ts
  17. 10
      src/Squidex/app/features/content/shared/content-item.component.html
  18. 3
      src/Squidex/app/features/content/shared/content-item.component.ts
  19. 2
      src/Squidex/app/features/content/shared/contents-selector.component.html
  20. 2
      src/Squidex/app/features/content/shared/contents-selector.component.ts
  21. 7
      src/Squidex/app/features/content/shared/field-editor.component.html
  22. 8
      src/Squidex/app/features/content/shared/field-editor.component.ts
  23. 3
      src/Squidex/app/features/content/shared/references-editor.component.html
  24. 5
      src/Squidex/app/features/content/shared/references-editor.component.ts
  25. 2
      src/Squidex/app/features/settings/pages/backups/backups-page.component.ts
  26. 2
      src/Squidex/app/framework/angular/forms/autocomplete.component.ts
  27. 10
      src/Squidex/app/framework/angular/forms/control-errors.component.ts
  28. 4
      src/Squidex/app/framework/angular/forms/date-time-editor.component.ts
  29. 2
      src/Squidex/app/framework/angular/forms/iframe-editor.component.ts
  30. 2
      src/Squidex/app/framework/angular/forms/tag-editor.component.ts
  31. 10
      src/Squidex/app/framework/angular/modals/dialog-renderer.component.ts
  32. 6
      src/Squidex/app/framework/angular/modals/onboarding-tooltip.component.ts
  33. 4
      src/Squidex/app/framework/angular/modals/tooltip.component.ts
  34. 12
      src/Squidex/app/framework/angular/sorted.directive.ts
  35. 4
      src/Squidex/app/framework/angular/stateful.component.ts
  36. 66
      src/Squidex/app/shared/components/asset.component.html
  37. 36
      src/Squidex/app/shared/components/asset.component.scss
  38. 5
      src/Squidex/app/shared/components/asset.component.ts
  39. 2
      src/Squidex/app/shared/components/comments.component.ts
  40. 2
      src/Squidex/app/shell/pages/internal/profile-menu.component.ts

2
src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts

@ -51,7 +51,7 @@ export class EventConsumersPageComponent extends ResourceOwner implements OnInit
this.eventConsumersState.reset(es).pipe(onErrorResumeNext()).subscribe();
}
public trackByEventConsumer(es: EventConsumerDto) {
public trackByEventConsumer(index: number, es: EventConsumerDto) {
return es.name;
}

4
src/Squidex/app/features/content/pages/content/content-field.component.html

@ -20,6 +20,7 @@
[field]="field"
[language]="language"
[languages]="languages"
[isCompact]="!!fieldFormCompare"
[control]="fieldForm.controls[language.iso2Code]">
</sqx-field-editor>
</div>
@ -31,6 +32,7 @@
[field]="field"
[language]="language"
[languages]="languages"
[isCompact]="!!fieldFormCompare"
[control]="selectedFormControl">
</sqx-field-editor>
</ng-template>
@ -61,6 +63,7 @@
[field]="field"
[language]="language"
[languages]="languages"
[isCompact]="true"
[control]="fieldFormCompare?.controls[language.iso2Code]">
</sqx-field-editor>
</div>
@ -71,6 +74,7 @@
[field]="field"
[language]="language"
[languages]="languages"
[isCompact]="true"
[control]="selectedFormControlCompare">
</sqx-field-editor>
</ng-template>

41
src/Squidex/app/features/content/pages/content/content-field.component.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
import { Component, DoCheck, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { AbstractControl, FormGroup } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
@ -14,7 +14,6 @@ import {
AppLanguageDto,
EditContentForm,
fieldInvariant,
ImmutableArray,
LocalStoreService,
RootFieldDto,
SchemaDto,
@ -26,7 +25,7 @@ import {
styleUrls: ['./content-field.component.scss'],
templateUrl: './content-field.component.html'
})
export class ContentFieldComponent implements DoCheck, OnChanges {
export class ContentFieldComponent implements OnChanges {
@Input()
public form: EditContentForm;
@ -46,7 +45,7 @@ export class ContentFieldComponent implements DoCheck, OnChanges {
public language: AppLanguageDto;
@Input()
public languages: ImmutableArray<AppLanguageDto>;
public languages: AppLanguageDto[];
@Output()
public languageChange = new EventEmitter<AppLanguageDto>();
@ -71,25 +70,7 @@ export class ContentFieldComponent implements DoCheck, OnChanges {
if (changes['field']) {
this.showAllControls = this.localStore.getBoolean(this.configKey());
}
}
public changeShowAllControls(value: boolean) {
this.showAllControls = value;
this.localStore.setBoolean(this.configKey(), this.showAllControls);
}
public copy() {
if (this.selectedFormControlCompare && this.fieldFormCompare) {
if (this.showAllControls) {
this.fieldForm.setValue(this.fieldFormCompare.value);
} else {
this.selectedFormControl.setValue(this.selectedFormControlCompare.value);
}
}
}
public ngDoCheck() {
const control = this.findControl(this.fieldForm);
if (this.selectedFormControl !== control) {
@ -113,6 +94,22 @@ export class ContentFieldComponent implements DoCheck, OnChanges {
}
}
public changeShowAllControls(value: boolean) {
this.showAllControls = value;
this.localStore.setBoolean(this.configKey(), this.showAllControls);
}
public copy() {
if (this.selectedFormControlCompare && this.fieldFormCompare) {
if (this.showAllControls) {
this.fieldForm.setValue(this.fieldFormCompare.value);
} else {
this.selectedFormControl.setValue(this.selectedFormControlCompare.value);
}
}
}
private findControl(form: FormGroup) {
if (this.field.isLocalizable) {
return form.controls[this.language.iso2Code];

2
src/Squidex/app/features/content/pages/content/content-history-page.component.html

@ -15,7 +15,7 @@
</div>
<div class="event-created">{{event.created | sqxFromNow}}</div>
<a class="event-load force" (click)="loadVersion(event.version)">Load this Version</a>
<a class="event-load force" (click)="loadVersion(event.version)">Load</a> &middot; <a class="event-load force" (click)="compareVersion(event.version)">Compare</a>
</div>
</div>
</ng-container>

6
src/Squidex/app/features/content/pages/content/content-history-page.component.ts

@ -62,7 +62,11 @@ export class ContentHistoryPageComponent {
}
public loadVersion(version: number) {
this.messageBus.emit(new ContentVersionSelected(new Version(version.toString())));
this.messageBus.emit(new ContentVersionSelected(new Version(version.toString()), false));
}
public compareVersion(version: number) {
this.messageBus.emit(new ContentVersionSelected(new Version(version.toString()), true));
}
public trackByEvent(index: number, event: HistoryEventDto) {

4
src/Squidex/app/features/content/pages/content/content-page.component.html

@ -1,7 +1,7 @@
<sqx-title message="{app} | {schema} | Content" parameter1="app" parameter2="schema" [value1]="appsState.appName" [value2]="schema.displayName"></sqx-title>
<form [formGroup]="contentForm.form" (ngSubmit)="saveAndPublish()">
<sqx-panel desiredWidth="*" minWidth="40rem" [showSidebar]="content">
<sqx-panel desiredWidth="*" minWidth="60rem" [showSidebar]="content">
<ng-container title>
<a class="btn btn-text" (click)="back()" *ngIf="!schema.isSingleton">
<i class="icon-angle-left"></i>
@ -118,7 +118,7 @@
[fieldForm]="contentForm.form.get(field.name)"
[fieldFormCompare]="contentFormCompare?.form.get(field.name)"
[schema]="schema"
[languages]="languages"
[languages]="languages.mutableValues"
[(language)]="language">
</sqx-content-field>
</div>

25
src/Squidex/app/features/content/pages/content/content-page.component.ts

@ -101,7 +101,7 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD
this.own(
this.messageBus.of(ContentVersionSelected)
.subscribe(message => {
this.loadVersion(message.version);
this.loadVersion(message.version, message.compare);
}));
}
@ -209,25 +209,36 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD
.subscribe();
}
private loadVersion(version: Version | null) {
private loadVersion(version: Version | null, compare: boolean) {
if (!this.content || version === null || version.eq(this.content.version)) {
this.contentFormCompare = null;
this.contentVersion = null;
this.contentForm.load(this.content.dataDraft);
} else {
this.contentsState.loadVersion(this.content, version)
.subscribe(dto => {
if (this.contentFormCompare === null) {
this.contentFormCompare = new EditContentForm(this.schema, this.languages);
this.contentFormCompare.form.disable();
if (compare) {
if (this.contentFormCompare === null) {
this.contentFormCompare = new EditContentForm(this.schema, this.languages);
this.contentFormCompare.form.disable();
}
this.contentFormCompare.load(dto.payload);
this.contentForm.load(this.content.dataDraft);
} else {
if (this.contentFormCompare) {
this.contentFormCompare = null;
}
this.contentForm.load(dto.payload);
}
this.contentFormCompare.load(dto.payload);
this.contentVersion = version;
});
}
}
public showLatest() {
this.loadVersion(null);
this.loadVersion(null, false);
}
}

10
src/Squidex/app/features/content/pages/content/field-languages.component.ts

@ -7,11 +7,7 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import {
AppLanguageDto,
ImmutableArray,
RootFieldDto
} from '@app/shared';
import { AppLanguageDto, RootFieldDto } from '@app/shared';
@Component({
selector: 'sqx-field-languages',
@ -25,7 +21,7 @@ import {
<sqx-language-selector size="sm" #buttonLanguages
[selectedLanguage]="language"
(selectedLanguageChange)="languageChange.emit($event)"
[languages]="languages.values">
[languages]="languages">
</sqx-language-selector>
<sqx-onboarding-tooltip helpId="languages" [for]="buttonLanguages" position="topRight" after="120000">
@ -45,7 +41,7 @@ export class FieldLanguagesComponent {
public language: AppLanguageDto;
@Input()
public languages: ImmutableArray<AppLanguageDto>;
public languages: AppLanguageDto[];
@Output()
public languageChange = new EventEmitter<AppLanguageDto>();

2
src/Squidex/app/features/content/pages/contents/contents-page.component.html

@ -33,7 +33,7 @@
</sqx-search-form>
</div>
<div class="col-auto pl-1" *ngIf="languages.length > 1">
<sqx-language-selector class="languages-buttons" (selectedLanguageChange)="selectLanguage($event)" [languages]="languages.values"></sqx-language-selector>
<sqx-language-selector class="languages-buttons" (selectedLanguageChange)="selectLanguage($event)" [languages]="languages.mutableValues"></sqx-language-selector>
</div>
<div class="col-auto pl-1">
<button class="btn btn-success" #newButton routerLink="new" title="New Content (CTRL + SHIFT + G)">

2
src/Squidex/app/features/content/pages/contents/contents-page.component.ts

@ -200,7 +200,7 @@ export class ContentsPageComponent extends ResourceOwner implements OnInit {
this.updateSelectionSummary();
}
public trackByContent(content: ContentDto): string {
public trackByContent(index: number, content: ContentDto): string {
return content.id;
}

3
src/Squidex/app/features/content/pages/messages.ts

@ -9,7 +9,8 @@ import { Version } from '@app/shared';
export class ContentVersionSelected {
constructor(
public readonly version: Version
public readonly version: Version,
public readonly compare: boolean
) {
}
}

3
src/Squidex/app/features/content/shared/array-editor.component.ts

@ -11,7 +11,6 @@ import { AbstractControl, FormArray, FormGroup } from '@angular/forms';
import {
AppLanguageDto,
EditContentForm,
ImmutableArray,
RootFieldDto,
StatefulComponent
} from '@app/shared';
@ -37,7 +36,7 @@ export class ArrayEditorComponent extends StatefulComponent<State> {
public language: AppLanguageDto;
@Input()
public languages: ImmutableArray<AppLanguageDto>;
public languages: AppLanguageDto[];
@Input()
public arrayControl: FormArray;

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

@ -14,7 +14,6 @@ import {
AppLanguageDto,
EditContentForm,
FieldDto,
ImmutableArray,
RootFieldDto
} from '@app/shared';
@ -62,7 +61,7 @@ export class ArrayItemComponent implements OnChanges {
public language: AppLanguageDto;
@Input()
public languages: ImmutableArray<AppLanguageDto>;
public languages: AppLanguageDto[];
public isInvalid: Observable<boolean>;

10
src/Squidex/app/features/content/shared/assets-editor.component.html

@ -4,7 +4,7 @@
<div class="row no-gutters">
<div class="col">
<div class="drop-area align-items-center" (click)="assetsDialog.show()" (sqxFileDrop)="addFiles($event)">
Drop files or click here to add assets.
Drop files or click
</div>
</div>
<div class="col-auto pl-1">
@ -26,7 +26,7 @@
<sqx-asset *ngFor="let file of snapshot.assetFiles" [initFile]="file"
(failed)="removeLoadingAsset(file)" (loaded)="addAsset(file, $event)">
</sqx-asset>
<sqx-asset *ngFor="let asset of snapshot.assets; trackBy: trackByAsset" [asset]="asset" removeMode="true"
<sqx-asset *ngFor="let asset of snapshot.assets; trackBy: trackByAsset" [asset]="asset" [isCompact]="isCompact" removeMode="true"
(updated)="notifyOthers($event)" (removing)="removeLoadedAsset($event)">
</sqx-asset>
</div>
@ -39,10 +39,12 @@
</sqx-asset>
<div
[sqxSortModel]="snapshot.assets.values"
[sqxSortModel]="snapshot.assets.mutableValues"
(sqxSorted)="sortAssets($event)">
<div *ngFor="let asset of snapshot.assets; trackBy: trackByAsset">
<sqx-asset [asset]="asset" removeMode="true" [isListView]="true"
<sqx-asset [asset]="asset" removeMode="true"
[isListView]="true"
[isCompact]="isCompact"
(updated)="notifyOthers($event)" (removing)="removeLoadedAsset($event)">
</sqx-asset>
</div>

3
src/Squidex/app/features/content/shared/assets-editor.component.scss

@ -46,9 +46,10 @@
@include border-radius;
@include truncate-nowidth;
border: 2px dashed darken($color-border, 10%);
padding: 5px .5rem;
font-weight: normal;
font-size: 1rem;
text-align: center;
padding: 5px 2rem;
color: darken($color-border, 30%);
cursor: pointer;
}

9
src/Squidex/app/features/content/shared/assets-editor.component.ts

@ -5,7 +5,7 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, OnInit } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input, OnInit } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import {
@ -50,6 +50,9 @@ interface State {
export class AssetsEditorComponent extends StatefulControlComponent<State, string[]> implements OnInit {
public assetsDialog = new DialogModel();
@Input()
public isCompact = false;
constructor(changeDetector: ChangeDetectorRef,
private readonly appsState: AppsState,
private readonly assetsService: AssetsService,
@ -89,7 +92,7 @@ export class AssetsEditorComponent extends StatefulControlComponent<State, strin
}
public ngOnInit() {
this.takeOver(
this.own(
this.messageBus.of(AssetUpdated)
.subscribe(event => {
if (event.source !== this) {
@ -167,7 +170,7 @@ export class AssetsEditorComponent extends StatefulControlComponent<State, strin
this.callChange(ids);
}
public trackByAsset(asset: AssetDto) {
public trackByAsset(index: number, asset: AssetDto) {
return asset.id;
}
}

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

@ -59,7 +59,7 @@
{{values[i]}}
</div>
</td>
<td class="cell-time" (click)="shouldStop($event)">
<td class="cell-time" *ngIf="!isCompact" (click)="shouldStop($event)">
<sqx-content-status
[status]="content.status"
[scheduledTo]="content.scheduleJob?.status"
@ -70,6 +70,10 @@
<small class="item-modified">{{content.lastModified | sqxFromNow}}</small>
</td>
<td class="cell-user" *ngIf="!isCompact && patchForm.form.pristine" (click)="shouldStop($event)">
<img class="user-picture" [attr.title]="content.lastModifiedBy | sqxUserNameRef" [attr.src]="content.lastModifiedBy | sqxUserPictureRef" />
</td>
<td class="cell-user" *ngIf="patchForm.form.dirty" (click)="shouldStop($event)">
<button type="button" class="btn btn-success" (click)="save(); $event.stopPropagation()">
<i class="icon-checkmark"></i>
@ -81,10 +85,6 @@
</button>
</td>
<td class="cell-user" *ngIf="patchForm.form.pristine" (click)="shouldStop($event)">
<img class="user-picture" [attr.title]="content.lastModifiedBy | sqxUserNameRef" [attr.src]="content.lastModifiedBy | sqxUserPictureRef" />
</td>
<td class="cell-actions" *ngIf="!isReadOnly && patchForm.form.pristine" (click)="shouldStop($event)">
<div class="dropdown dropdown-options" *ngIf="content">
<button type="button" class="btn btn-text-secondary" (click)="dropdown.toggle(); $event.stopPropagation()" [class.active]="dropdown.isOpen | async" #optionsButton>

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

@ -69,6 +69,9 @@ export class ContentItemComponent implements OnChanges {
@Input()
public isReference = false;
@Input()
public isCompact = false;
@Input('sqxContent')
public content: ContentDto;

2
src/Squidex/app/features/content/shared/contents-selector.component.html

@ -19,7 +19,7 @@
</div>
<div class="col pl-1" *ngIf="languages.length > 1">
<sqx-language-selector class="languages-buttons" (selectedLanguageChange)="selectLanguage($event)" [languages]="languages.values"></sqx-language-selector>
<sqx-language-selector class="languages-buttons" (selectedLanguageChange)="selectLanguage($event)" [languages]="languages"></sqx-language-selector>
</div>
</div>
</ng-container>

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

@ -115,7 +115,7 @@ export class ContentsSelectorComponent implements OnInit {
this.isAllSelected = this.selectionCount === this.contentsState.snapshot.contents.length;
}
public trackByContent(content: ContentDto): string {
public trackByContent(index: number, content: ContentDto): string {
return content.id;
}
}

7
src/Squidex/app/features/content/shared/field-editor.component.html

@ -101,7 +101,7 @@
<sqx-json-editor [formControl]="control"></sqx-json-editor>
</ng-container>
<ng-container *ngSwitchCase="'Assets'">
<sqx-assets-editor [formControl]="control"></sqx-assets-editor>
<sqx-assets-editor [formControl]="control" [isCompact]="isCompact"></sqx-assets-editor>
</ng-container>
<ng-container *ngSwitchCase="'Tags'">
<ng-container [ngSwitch]="field.properties['editor']">
@ -122,7 +122,7 @@
<sqx-array-editor
[arrayControl]="control"
[form]="form"
[field]="field"
[field]="field"
[language]="language"
[languages]="languages">
</sqx-array-editor>
@ -132,7 +132,8 @@
[formControl]="control"
[language]="language"
[languages]="languages"
[schemaId]="field.properties['schemaId']">
[schemaId]="field.properties['schemaId']"
[isCompact]="isCompact">
</sqx-references-editor>
</ng-container>
</ng-container>

8
src/Squidex/app/features/content/shared/field-editor.component.ts

@ -11,8 +11,7 @@ import { FormControl } from '@angular/forms';
import {
AppLanguageDto,
EditContentForm,
FieldDto,
ImmutableArray
FieldDto
} from '@app/shared';
@Component({
@ -34,7 +33,10 @@ export class FieldEditorComponent {
public language: AppLanguageDto;
@Input()
public languages: ImmutableArray<AppLanguageDto>;
public languages: AppLanguageDto[];
@Input()
public isCompact = false;
@Input()
public displaySuffix: string;

3
src/Squidex/app/features/content/shared/references-editor.component.html

@ -7,13 +7,14 @@
</div>
<table class="table table-items table-fixed" [class.disabled]="snapshot.isDisabled" *ngIf="snapshot.schema && snapshot.contentItems && snapshot.contentItems.length > 0"
[sqxSortModel]="snapshot.contentItems.values"
[sqxSortModel]="snapshot.contentItems.mutableValues"
(sqxSorted)="sort($event)">
<tbody *ngFor="let content of snapshot.contentItems">
<tr [sqxContent]="content"
[language]="language"
[isReadOnly]="true"
[isReference]="true"
[isCompact]="isCompact"
[schema]="snapshot.schema"
(deleting)="remove(content)"></tr>
<tr class="spacer"></tr>

5
src/Squidex/app/features/content/shared/references-editor.component.ts

@ -48,7 +48,10 @@ export class ReferencesEditorComponent extends StatefulControlComponent<State, s
public language: AppLanguageDto;
@Input()
public languages: ImmutableArray<AppLanguageDto>;
public languages: AppLanguageDto[];
@Input()
public isCompact = false;
public selectorDialog = new DialogModel();

2
src/Squidex/app/features/settings/pages/backups/backups-page.component.ts

@ -49,7 +49,7 @@ export class BackupsPageComponent extends ResourceOwner implements OnInit {
this.backupsState.delete(backup).pipe(onErrorResumeNext()).subscribe();
}
public trackByBackup(item: BackupDto) {
public trackByBackup(index: number, item: BackupDto) {
return item.id;
}
}

2
src/Squidex/app/framework/angular/forms/autocomplete.component.ts

@ -66,7 +66,7 @@ export class AutocompleteComponent extends StatefulControlComponent<State, any[]
}
public ngOnInit() {
this.takeOver(
this.own(
this.queryInput.valueChanges.pipe(
tap(query => {
this.callChange(query);

10
src/Squidex/app/framework/angular/forms/control-errors.component.ts

@ -91,7 +91,7 @@ export class ControlErrorsComponent extends StatefulComponent<State> implements
this.control = control;
if (control) {
this.takeOver(
this.own(
merge(control.valueChanges, control.statusChanges)
.subscribe(() => {
this.createMessages();
@ -113,7 +113,7 @@ export class ControlErrorsComponent extends StatefulComponent<State> implements
}
private createMessages() {
const errorMessages: string[] = [];
const errors: string[] = [];
if (this.control && this.control.invalid && ((this.control.touched && !this.submitOnly) || this.submitted) && this.control.errors) {
for (let key in <any>this.control.errors) {
@ -121,12 +121,14 @@ export class ControlErrorsComponent extends StatefulComponent<State> implements
const message = formatError(this.displayFieldName, key, this.control.errors[key], this.control.value, this.errors);
if (message) {
errorMessages.push(message);
errors.push(message);
}
}
}
}
this.next(s => ({ ...s, errorMessages }));
if (errors.length !== this.snapshot.errorMessages.length || errors.length > 0) {
this.next(s => ({ ...s, errorMessages: errors }));
}
}
}

4
src/Squidex/app/framework/angular/forms/date-time-editor.component.ts

@ -60,7 +60,7 @@ export class DateTimeEditorComponent extends StatefulControlComponent<{}, string
}
public ngOnInit() {
this.takeOver(
this.own(
this.timeControl.valueChanges.subscribe(value => {
if (!value || value.length === 0) {
this.timeValue = null;
@ -71,7 +71,7 @@ export class DateTimeEditorComponent extends StatefulControlComponent<{}, string
this.updateValue();
}));
this.takeOver(
this.own(
this.dateControl.valueChanges.subscribe(value => {
if (!value || value.length === 0) {
this.dateValue = null;

2
src/Squidex/app/framework/angular/forms/iframe-editor.component.ts

@ -50,7 +50,7 @@ export class IFrameEditorComponent extends ExternalControlComponent<any> impleme
}
public ngOnInit(): void {
this.takeOver(
this.own(
this.renderer.listen('window', 'message', (event: MessageEvent) => {
if (event.source === this.plugin.contentWindow) {
const { type } = event.data;

2
src/Squidex/app/framework/angular/forms/tag-editor.component.ts

@ -146,7 +146,7 @@ export class TagEditorComponent extends StatefulControlComponent<State, any[]> i
}
public ngOnInit() {
this.takeOver(
this.own(
this.addInput.valueChanges.pipe(
tap(() => {
this.resetSize();

10
src/Squidex/app/framework/angular/modals/dialog-renderer.component.ts

@ -45,14 +45,14 @@ export class DialogRendererComponent extends StatefulComponent<State> implements
}
public ngOnInit() {
this.takeOver(
this.own(
this.dialogView.isOpen.subscribe(isOpen => {
if (!isOpen) {
this.finishRequest(false);
}
}));
this.takeOver(
this.own(
this.dialogs.notifications.subscribe(notification => {
this.next(s => ({
...s,
@ -60,17 +60,19 @@ export class DialogRendererComponent extends StatefulComponent<State> implements
}));
if (notification.displayTime > 0) {
this.takeOver(timer(notification.displayTime).subscribe(() => {
this.own(timer(notification.displayTime).subscribe(() => {
this.close(notification);
}));
}
}));
this.takeOver(
this.own(
this.dialogs.dialogs
.subscribe(dialogRequest => {
this.cancel();
this.dialogView.show();
this.next(s => ({ ...s, dialogRequest }));
}));
}

6
src/Squidex/app/framework/angular/modals/onboarding-tooltip.component.ts

@ -55,7 +55,7 @@ export class OnboardingTooltipComponent extends StatefulComponent implements OnD
public ngOnInit() {
if (this.for && this.helpId && Types.isFunction(this.for.addEventListener)) {
this.takeOver(
this.own(
timer(this.after).subscribe(() => {
if (this.onboardingService.shouldShow(this.helpId)) {
const forRect = this.for.getBoundingClientRect();
@ -68,7 +68,7 @@ export class OnboardingTooltipComponent extends StatefulComponent implements OnD
if (this.isSameOrParent(fromPoint)) {
this.tooltipModal.show();
this.takeOver(
this.own(
timer(10000).subscribe(() => {
this.hideThis();
}));
@ -78,7 +78,7 @@ export class OnboardingTooltipComponent extends StatefulComponent implements OnD
}
}));
this.takeOver(
this.own(
this.renderer.listen(this.for, 'mousedown', () => {
this.onboardingService.disable(this.helpId);

4
src/Squidex/app/framework/angular/modals/tooltip.component.ts

@ -39,12 +39,12 @@ export class TooltipComponent extends StatefulComponent implements OnDestroy, On
public ngOnInit() {
if (this.target) {
this.takeOver(
this.own(
this.renderer.listen(this.target, 'mouseenter', () => {
this.modal.show();
}));
this.takeOver(
this.own(
this.renderer.listen(this.target, 'mouseleave', () => {
this.modal.hide();
}));

12
src/Squidex/app/framework/angular/sorted.directive.ts

@ -5,14 +5,14 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
import { Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { Directive, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
import * as Sortable from 'sortablejs';
@Directive({
selector: '[sqxSortModel]'
})
export class SortedDirective implements OnDestroy, OnInit {
export class SortedDirective implements OnDestroy, OnInit, OnChanges {
private sortable: Sortable.Ref;
@Input()
@ -29,6 +29,13 @@ export class SortedDirective implements OnDestroy, OnInit {
) {
}
public ngOnChanges(changes: SimpleChanges) {
const sortModel = changes['sortModel'].currentValue;
if (sortModel) {
console.log(JSON.stringify(sortModel.map((x: any) => x.fileName)));
}
}
public ngOnDestroy() {
if (this.sortable) {
this.sortable.destroy();
@ -41,6 +48,7 @@ export class SortedDirective implements OnDestroy, OnInit {
animation: 150,
onSort: (event: { oldIndex: number, newIndex: number }) => {
console.log('FOO');
if (this.sortModel && event.newIndex !== event.oldIndex) {
const newModel = [...this.sortModel];

4
src/Squidex/app/framework/angular/stateful.component.ts

@ -55,7 +55,7 @@ export abstract class StatefulComponent<T = any> extends State<T> implements OnD
) {
super(state);
this.takeOver(
this.own(
this.changes.pipe(skip(1)).subscribe(() => {
this.changeDetector.detectChanges();
}));
@ -65,7 +65,7 @@ export abstract class StatefulComponent<T = any> extends State<T> implements OnD
this.subscriptions.ngOnDestroy();
}
public takeOver<R>(subscription: Subscription | UnsubscribeFunction | Observable<R>) {
public own<R>(subscription: Subscription | UnsubscribeFunction | Observable<R>) {
this.subscriptions.own(subscription);
}
}

66
src/Squidex/app/shared/components/asset.component.html

@ -95,39 +95,41 @@
<img class="icon" [attr.src]="asset | sqxFileIcon">
</div>
<div class="row no-gutters" *ngIf="asset && snapshot.progress === 0" @fade>
<div class="col col-name">
<div *ngIf="!snapshot.isRenaming" class="file-name editable" (dblclick)="renameStart()">
{{asset.fileName}}
</div>
<div *ngIf="snapshot.isRenaming">
<form [formGroup]="renameForm.form" (ngSubmit)="renameAsset()">
<sqx-control-errors for="name" [submitted]="renameForm.submitted | async"></sqx-control-errors>
<table class="table-fixed" *ngIf="asset && snapshot.progress === 0" @fade>
<tr>
<td class="col-name">
<div *ngIf="!snapshot.isRenaming" class="file-name editable" (dblclick)="renameStart()">
{{asset.fileName}}
</div>
<div *ngIf="snapshot.isRenaming">
<form [formGroup]="renameForm.form" (ngSubmit)="renameAsset()">
<sqx-control-errors for="name" [submitted]="renameForm.submitted | async"></sqx-control-errors>
<input type="text" class="form-control editable form-underlined" id="assetName" formControlName="name" autocomplete="off" spellcheck="false" sqxFocusOnInit (blur)="renameCancel()" />
</form>
</div>
</div>
<div class="col col-info">
<ng-container *ngIf="asset.pixelWidth">{{asset.pixelWidth}}x{{asset.pixelHeight}}px, </ng-container> {{asset.fileSize | sqxFileSize}}
</div>
<div class="col col-user">
<img class="user-picture" [attr.title]="asset.lastModifiedBy | sqxUserNameRef" [attr.src]="asset.lastModifiedBy | sqxUserPictureRef" />
</div>
<div class="col col-actions text-right">
<a class="btn btn-text-secondary" [href]="asset | sqxAssetUrl" sqxExternalLink="noicon" (click)="$event.stopPropagation()">
<i class="icon-download"></i>
</a>
</div>
<div class="col col-actions text-right" *ngIf="!isDisabled || removeMode">
<button class="btn btn-text-danger" (click)="deleting.emit(asset); $event.stopPropagation()" *ngIf="!isDisabled && !removeMode">
<i class="icon-bin2"></i>
</button>
<button class="btn btn-text-secondary" (click)="removing.emit(asset); $event.stopPropagation()" *ngIf="removeMode">
<i class="icon-close"></i>
</button>
</div>
</div>
<input type="text" class="form-control editable form-underlined" id="assetName" formControlName="name" autocomplete="off" spellcheck="false" sqxFocusOnInit (blur)="renameCancel()" />
</form>
</div>
</td>
<td class="col-info" *ngIf="!isCompact">
<ng-container *ngIf="asset.pixelWidth">{{asset.pixelWidth}}x{{asset.pixelHeight}}px, </ng-container> {{asset.fileSize | sqxFileSize}}
</td>
<td class="col-user" *ngIf="!isCompact">
<img class="user-picture" [attr.title]="asset.lastModifiedBy | sqxUserNameRef" [attr.src]="asset.lastModifiedBy | sqxUserPictureRef" />
</td>
<td class="col-actions text-right" *ngIf="!isCompact">
<a class="btn btn-text-secondary" [href]="asset | sqxAssetUrl" sqxExternalLink="noicon" (click)="$event.stopPropagation()">
<i class="icon-download"></i>
</a>
</td>
<td class="col-actions text-right" *ngIf="!isDisabled || removeMode">
<button class="btn btn-text-danger" (click)="deleting.emit(asset); $event.stopPropagation()" *ngIf="!isDisabled && !removeMode">
<i class="icon-bin2"></i>
</button>
<button class="btn btn-text-secondary" (click)="removing.emit(asset); $event.stopPropagation()" *ngIf="removeMode">
<i class="icon-close"></i>
</button>
</td>
</tr>
</table>
<div class="upload-progress" *ngIf="snapshot.progress > 0">
<sqx-progress-bar [value]="snapshot.progress" [trailWidth]="0.8" [strokeWidth]="0.8" [showText]="false"></sqx-progress-bar>

36
src/Squidex/app/shared/components/asset.component.scss

@ -107,8 +107,7 @@ $list-height: 2.375rem;
background: $color-dark-black;
}
&-name,
&-info {
&-name, &-info {
@include truncate;
}
@ -187,7 +186,7 @@ $list-height: 2.375rem;
.table-items-row {
& {
position: relative;
padding-left: $list-height + 2rem;
padding-left: $list-height + 3rem;
height: $list-height + 2rem;
}
@ -229,36 +228,31 @@ $list-height: 2.375rem;
height: $list-height;
}
&-user {
padding-top: .2rem;
}
&-actions {
line-height: $list-height;
&-name {
width: 100%;
padding-right: .5rem;
}
&-name,
&-info {
@include truncate;
padding-right: 1rem;
padding-left: 1rem;
line-height: $list-height;
&-user {
width: 3rem;
}
&-actions,
&-user {
max-width: 3rem;
min-width: 3rem;
&-actions {
width: 3rem;
}
&-info {
color: $color-text-decent;
font-size: .9rem;
max-width: 12rem;
min-width: 12rem;
font-weight: normal;
width: 12rem;
}
}
table {
width: 100%;
}
.upload-progress {
padding: .25rem 0;
}

5
src/Squidex/app/shared/components/asset.component.ts

@ -51,6 +51,9 @@ export class AssetComponent extends StatefulComponent<State> implements OnChange
@Input()
public removeMode = false;
@Input()
public isCompact = false;
@Input()
public isDisabled = false;
@ -122,7 +125,7 @@ export class AssetComponent extends StatefulComponent<State> implements OnChange
});
}
this.takeOver(
this.own(
this.tagInput.valueChanges.pipe(
distinctUntilChanged(),
debounceTime(2000)

2
src/Squidex/app/shared/components/comments.component.ts

@ -73,7 +73,7 @@ export class CommentsComponent extends ResourceOwner implements OnDestroy, OnIni
}
}
public trackByComment(comment: CommentDto) {
public trackByComment(index: number, comment: CommentDto) {
return comment.id;
}
}

2
src/Squidex/app/shell/pages/internal/profile-menu.component.ts

@ -44,7 +44,7 @@ export class ProfileMenuComponent extends StatefulComponent<State> implements On
});
}
public ngOnInit() {
this.takeOver(
this.own(
this.authService.userChanges.pipe(filter(user => !!user))
.subscribe(user => {
const profileId = user!.id;

Loading…
Cancel
Save