Browse Source

Merge branch 'master' into feature/plugins

# Conflicts:
#	src/Squidex/app/framework/angular/forms/control-errors.component.ts
pull/349/head
Sebastian Stehle 7 years ago
parent
commit
25e74b8659
  1. 2
      src/Squidex.Domain.Apps.Entities/Schemas/State/SchemaState.cs
  2. 3
      src/Squidex.Infrastructure.GoogleCloud/Assets/GoogleCloudAssetStore.cs
  3. 2
      src/Squidex.Infrastructure.MongoDb/Assets/MongoGridFsAssetStore.cs
  4. 3
      src/Squidex.Infrastructure/Assets/FolderAssetStore.cs
  5. 33
      src/Squidex.Infrastructure/StringExtensions.cs
  6. 2
      src/Squidex/Config/Domain/InfrastructureServices.cs
  7. 6
      src/Squidex/app/framework/angular/forms/control-errors.component.ts
  8. 2
      src/Squidex/app/framework/angular/forms/iframe-editor.component.html
  9. 41
      src/Squidex/app/framework/angular/forms/iframe-editor.component.ts
  10. 2
      src/Squidex/app/framework/angular/modals/modal-target.directive.ts
  11. 4
      src/Squidex/app/framework/angular/modals/onboarding-tooltip.component.ts
  12. 12
      src/Squidex/app/framework/angular/sorted.directive.ts
  13. 19
      src/Squidex/app/framework/angular/stateful.component.ts
  14. 5
      tests/Squidex.Infrastructure.Tests/Assets/AssetStoreTests.cs

2
src/Squidex.Domain.Apps.Entities/Schemas/State/SchemaState.cs

@ -59,7 +59,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.State
SchemaDef = SchemaDef.AddField(field);
}
SchemaFieldsTotal++;
SchemaFieldsTotal = Math.Max(SchemaFieldsTotal, @event.FieldId.Id);
}
protected void On(SchemaCategoryChanged @event)

3
src/Squidex.Infrastructure.GoogleCloud/Assets/GoogleCloudAssetStore.cs

@ -7,7 +7,6 @@
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
@ -141,7 +140,7 @@ namespace Squidex.Infrastructure.Assets
private static string GetFileName(string id, long version, string suffix)
{
return string.Join("_", new[] { id, version.ToString(), suffix }.Where(x => !string.IsNullOrWhiteSpace(x)));
return StringExtensions.JoinNonEmpty("_", id, version.ToString(), suffix);
}
}
}

2
src/Squidex.Infrastructure.MongoDb/Assets/MongoGridFsAssetStore.cs

@ -128,7 +128,7 @@ namespace Squidex.Infrastructure.Assets
private static string GetFileName(string id, long version, string suffix)
{
return string.Join("_", new[] { id, version.ToString(), suffix }.Where(x => !string.IsNullOrWhiteSpace(x)));
return StringExtensions.JoinNonEmpty("_", id, version.ToString(), suffix);
}
}
}

3
src/Squidex.Infrastructure/Assets/FolderAssetStore.cs

@ -7,7 +7,6 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Squidex.Infrastructure.Log;
@ -159,7 +158,7 @@ namespace Squidex.Infrastructure.Assets
private string GetPath(string id, long version, string suffix)
{
return Path.Combine(directory.FullName, string.Join("_", new[] { id, version.ToString(), suffix }.Where(x => !string.IsNullOrWhiteSpace(x))));
return Path.Combine(directory.FullName, StringExtensions.JoinNonEmpty("_", id, version.ToString(), suffix));
}
}
}

33
src/Squidex.Infrastructure/StringExtensions.cs

@ -16,9 +16,11 @@ namespace Squidex.Infrastructure
public static class StringExtensions
{
private const char NullChar = (char)0;
private static readonly Regex SlugRegex = new Regex("^[a-z0-9]+(\\-[a-z0-9]+)*$", RegexOptions.Compiled);
private static readonly Regex EmailRegex = new Regex("^[a-zA-Z0-9.!#$%&’*+\\/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:.[a-zA-Z0-9-]+)*$", RegexOptions.Compiled);
private static readonly Regex PropertyNameRegex = new Regex("^[a-zA-Z0-9]+(\\-[a-zA-Z0-9]+)*$", RegexOptions.Compiled);
private static readonly Dictionary<char, string> LowerCaseDiacritics;
private static readonly Dictionary<char, string> Diacritics = new Dictionary<char, string>
{
@ -555,6 +557,8 @@ namespace Squidex.Infrastructure
public static string BuildFullUrl(this string baseUrl, string path, bool trailingSlash = false)
{
Guard.NotNull(path, nameof(path));
var url = $"{baseUrl.TrimEnd('/')}/{path.Trim('/')}";
if (trailingSlash &&
@ -567,5 +571,34 @@ namespace Squidex.Infrastructure
return url;
}
public static string JoinNonEmpty(string separator, params string[] parts)
{
Guard.NotNull(separator, nameof(separator));
if (parts == null || parts.Length == 0)
{
return string.Empty;
}
var sb = new StringBuilder();
for (var i = 0; i < parts.Length; i++)
{
var part = parts[i];
if (!string.IsNullOrWhiteSpace(part))
{
sb.Append(part);
if (i < parts.Length - 1)
{
sb.Append(separator);
}
}
}
return sb.ToString();
}
}
}

2
src/Squidex/Config/Domain/InfrastructureServices.cs

@ -5,7 +5,6 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using Microsoft.AspNetCore.DataProtection.Repositories;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Infrastructure;
@ -16,7 +15,6 @@ using NodaTime;
using Squidex.Areas.Api.Controllers.News.Service;
using Squidex.Domain.Apps.Entities.Apps.Diagnostics;
using Squidex.Domain.Users;
using Squidex.Infrastructure;
using Squidex.Infrastructure.Caching;
using Squidex.Infrastructure.Diagnostics;
using Squidex.Infrastructure.Translations;

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

@ -61,10 +61,6 @@ export class ControlErrorsComponent extends StatefulComponent<State> implements
public ngOnDestroy() {
super.ngOnDestroy();
this.unsubscribe();
}
private unsubscribe() {
if (this.control && this.originalMarkAsTouched) {
this.control['markAsTouched'] = this.originalMarkAsTouched;
}
@ -90,7 +86,7 @@ export class ControlErrorsComponent extends StatefulComponent<State> implements
}
if (this.control !== control) {
this.unsubscribe();
this.unsubscribeAll();
this.control = control;

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

@ -1 +1 @@
<iframe #iframe scrolling="no" [attr.src]="sanitizedUrl" width="100%"></iframe>
<iframe #iframe scrolling="no" width="100%"></iframe>

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

@ -5,9 +5,8 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
import { AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, forwardRef, Input, OnInit, Renderer2, ViewChild } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, forwardRef, Input, OnChanges, OnInit, Renderer2, ViewChild } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { ExternalControlComponent, Types } from '@app/framework/internal';
@ -22,50 +21,42 @@ export const SQX_IFRAME_EDITOR_CONTROL_VALUE_ACCESSOR: any = {
providers: [SQX_IFRAME_EDITOR_CONTROL_VALUE_ACCESSOR],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class IFrameEditorComponent extends ExternalControlComponent<any> implements AfterViewInit, OnInit {
export class IFrameEditorComponent extends ExternalControlComponent<any> implements OnChanges, OnInit {
private value: any;
private isDisabled = false;
private isInitialized = false;
private plugin: HTMLIFrameElement;
@ViewChild('iframe')
public iframe: ElementRef<HTMLIFrameElement>;
@Input()
public set url(value: string) {
this.sanitizedUrl = this.sanitizer.bypassSecurityTrustResourceUrl(value);
}
public sanitizedUrl: SafeResourceUrl;
public url: string;
constructor(changeDetector: ChangeDetectorRef,
private readonly sanitizer: DomSanitizer,
private readonly renderer: Renderer2
) {
super(changeDetector);
}
public ngAfterViewInit() {
this.plugin = this.iframe.nativeElement;
public ngOnChanges() {
this.iframe.nativeElement.src = this.url;
}
public ngOnInit(): void {
this.own(
this.renderer.listen('window', 'message', (event: MessageEvent) => {
if (event.source === this.plugin.contentWindow) {
if (event.source === this.iframe.nativeElement.contentWindow) {
const { type } = event.data;
if (type === 'started') {
this.isInitialized = true;
if (this.plugin.contentWindow && Types.isFunction(this.plugin.contentWindow.postMessage)) {
this.plugin.contentWindow.postMessage({ type: 'disabled', isDisabled: this.isDisabled }, '*');
this.plugin.contentWindow.postMessage({ type: 'valueChanged', value: this.value }, '*');
}
this.sendMessage({ type: 'disabled', isDisabled: this.isDisabled });
this.sendMessage({ type: 'valueChanged', value: this.value });
} else if (type === 'resize') {
const { height } = event.data;
this.plugin.height = height + 'px';
this.iframe.nativeElement.height = height + 'px';
} else if (type === 'valueChanged') {
const { value } = event.data;
@ -84,16 +75,20 @@ export class IFrameEditorComponent extends ExternalControlComponent<any> impleme
public writeValue(obj: any) {
this.value = obj;
if (this.isInitialized && this.plugin.contentWindow && Types.isFunction(this.plugin.contentWindow.postMessage)) {
this.plugin.contentWindow.postMessage({ type: 'valueChanged', value: this.value }, '*');
}
this.sendMessage({ type: 'valueChanged', value: this.value });
}
public setDisabledState(isDisabled: boolean): void {
this.isDisabled = isDisabled;
if (this.isInitialized && this.plugin.contentWindow && Types.isFunction(this.plugin.contentWindow.postMessage)) {
this.plugin.contentWindow.postMessage({ type: 'disabled', isDisabled: this.isDisabled }, '*');
this.sendMessage({ type: 'disabled', isDisabled: this.isDisabled });
}
private sendMessage(message: any) {
const iframe = this.iframe.nativeElement;
if (this.isInitialized && iframe.contentWindow && Types.isFunction(iframe.contentWindow.postMessage)) {
iframe.contentWindow.postMessage(message, '*');
}
}
}

2
src/Squidex/app/framework/angular/modals/modal-target.directive.ts

@ -20,7 +20,7 @@ export class ModalTargetDirective extends ResourceOwner implements AfterViewInit
@Input('sqxModalTarget')
public set target(element: any) {
if (element !== this.targetElement) {
this.ngOnDestroy();
this.unsubscribeAll();
this.targetElement = element;

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

@ -100,12 +100,12 @@ export class OnboardingTooltipComponent extends StatefulComponent implements OnD
public hideThis() {
this.onboardingService.disable(this.helpId);
this.ngOnDestroy();
this.unsubscribeAll();
}
public hideAll() {
this.onboardingService.disableAll();
this.ngOnDestroy();
this.unsubscribeAll();
}
}

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, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
import { Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import * as Sortable from 'sortablejs';
@Directive({
selector: '[sqxSortModel]'
})
export class SortedDirective implements OnDestroy, OnInit, OnChanges {
export class SortedDirective implements OnDestroy, OnInit {
private sortable: Sortable.Ref;
@Input()
@ -29,13 +29,6 @@ export class SortedDirective implements OnDestroy, OnInit, OnChanges {
) {
}
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();
@ -48,7 +41,6 @@ export class SortedDirective implements OnDestroy, OnInit, OnChanges {
animation: 150,
onSort: (event: { oldIndex: number, newIndex: number }) => {
console.log('FOO');
if (this.sortModel && event.newIndex !== event.oldIndex) {
const newModel = [...this.sortModel];

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

@ -32,6 +32,10 @@ export class ResourceOwner implements OnDestroy {
}
public ngOnDestroy() {
this.unsubscribeAll();
}
public unsubscribeAll() {
try {
for (let subscription of this.subscriptions) {
if (Types.isFunction(subscription)) {
@ -48,6 +52,7 @@ export class ResourceOwner implements OnDestroy {
export abstract class StatefulComponent<T = any> extends State<T> implements OnDestroy {
private readonly subscriptions = new ResourceOwner();
private subscription: Subscription;
constructor(
private readonly changeDetector: ChangeDetectorRef,
@ -55,17 +60,23 @@ export abstract class StatefulComponent<T = any> extends State<T> implements OnD
) {
super(state);
this.own(
this.subscription =
this.changes.pipe(skip(1)).subscribe(() => {
this.changeDetector.detectChanges();
}));
});
}
public ngOnDestroy() {
this.subscriptions.ngOnDestroy();
this.subscription.unsubscribe();
this.unsubscribeAll();
}
protected unsubscribeAll() {
this.subscriptions.unsubscribeAll();
}
public detectChanges() {
protected detectChanges() {
this.changeDetector.detectChanges();
}

5
tests/Squidex.Infrastructure.Tests/Assets/AssetStoreTests.cs

@ -23,7 +23,10 @@ namespace Squidex.Infrastructure.Assets
{
sut = new Lazy<T>(CreateStore);
((IInitializable)Sut).InitializeAsync().Wait();
if (Sut is IInitializable initializable)
{
initializable.InitializeAsync().Wait();
}
}
protected T Sut

Loading…
Cancel
Save