From 393b9cf4ab17006cefe1259d8a5c641d89fb1f22 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sun, 25 Oct 2020 11:27:42 +0100 Subject: [PATCH 1/4] Drag and drop of folders. --- .../angular/forms/file-drop.directive.ts | 109 +++++++++++++----- 1 file changed, 79 insertions(+), 30 deletions(-) diff --git a/frontend/app/framework/angular/forms/file-drop.directive.ts b/frontend/app/framework/angular/forms/file-drop.directive.ts index ad112f5ff..bcae3172e 100644 --- a/frontend/app/framework/angular/forms/file-drop.directive.ts +++ b/frontend/app/framework/angular/forms/file-drop.directive.ts @@ -6,6 +6,7 @@ */ // tslint:disable: prefer-for-of +// tslint:disable: readonly-array import { Directive, ElementRef, EventEmitter, HostListener, Input, Output, Renderer2 } from '@angular/core'; import { Types } from '@app/framework/internal'; @@ -45,18 +46,16 @@ export class FileDropDirective { } @HostListener('paste', ['$event']) - public onPaste(event: ClipboardEvent) { - if (this.noPaste) { - return; - } + public async onPaste(event: ClipboardEvent) { + if (!this.noPaste) { + this.stopEvent(event); - const files = this.getAllowedFiles(event.clipboardData); + const files = await this.getAllowedFiles(event.clipboardData); - if (files && !this.disabled) { - this.drop.emit(files); + if (files && !this.disabled) { + this.drop.emit(files); + } } - - this.stopEvent(event); } @HostListener('dragend', ['$event']) @@ -88,16 +87,15 @@ export class FileDropDirective { } @HostListener('drop', ['$event']) - public onDrop(event: DragDropEvent) { + public async onDrop(event: DragDropEvent) { if (hasFiles(event.dataTransfer)) { - const files = this.getAllowedFiles(event.dataTransfer); + this.stopDrag(event); + + const files = await this.getAllowedFiles(event.dataTransfer); if (files && !this.disabled) { this.drop.emit(files); } - - this.dragEnd(0); - this.stopEvent(event); } } @@ -106,6 +104,11 @@ export class FileDropDirective { event.stopPropagation(); } + private stopDrag(event: DragDropEvent) { + this.dragEnd(0); + this.stopEvent(event); + } + private dragStart() { this.dragCounter++; @@ -122,30 +125,20 @@ export class FileDropDirective { } } - private getAllowedFiles(dataTransfer: DataTransfer | null) { + private async getAllowedFiles(dataTransfer: DataTransfer | null) { if (!dataTransfer || !hasFiles(dataTransfer)) { return null; } - const files: File[] = []; + let files: File[] = []; - for (let i = 0; i < dataTransfer.files.length; i++) { - const file = dataTransfer.files.item(i); + for (let i = 0; i < dataTransfer.items.length; i++) { + const item = dataTransfer.items[i]; - if (file && this.isAllowedFile(file)) { - files.push(file); - } + await transferFileTree(item, files); } - if (files.length === 0) { - for (let i = 0; i < dataTransfer.items.length; i++) { - const file = dataTransfer.items[i].getAsFile(); - - if (file && this.isAllowedFile(file)) { - files.push(file); - } - } - } + files = files.filter(f => this.isAllowedFile(f)); return files.length > 0 ? files : null; } @@ -203,6 +196,62 @@ function hasFiles(dataTransfer: DataTransfer): boolean { } } +async function transferWebkitTree(item: any, files: File[]) { + if (item.isFile) { + const file = await getFilePromise(item); + + files.push(file); + } else if (item.isDirectory) { + const entries = await getFilesPromise(item); + + for (const entry of entries) { + await transferWebkitTree(entry, files); + } + } +} + +async function transferFileTree(item: DataTransferItem, files: File[]) { + if (Types.isFunction(item['webkitGetAsEntry'])) { + const webkitEntry = item.webkitGetAsEntry(); + + if (webkitEntry) { + await transferWebkitTree(webkitEntry, files); + + return; + } + } + + if (Types.isFunction(item['getAsFile'])) { + const fileItem = item.getAsFile(); + + if (fileItem) { + files.push(fileItem); + } + } +} + +function getFilesPromise(item: any): Promise> { + return new Promise((resolve, reject) => { + try { + const reader = item.createReader(); + + reader.readEntries(resolve); + } catch (ex) { + reject(ex); + } + }); +} + +function getFilePromise(item: any): Promise { + return new Promise((resolve, reject) => { + try { + item.file(resolve); + } catch (ex) { + reject(ex); + } + }); +} + interface DragDropEvent extends MouseEvent { readonly dataTransfer: DataTransfer; } \ No newline at end of file From 88a37910e41efaaed884c69e154d8e5124c6052f Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 26 Oct 2020 11:16:12 +0100 Subject: [PATCH 2/4] Small UI improvement. --- .../features/content/shared/forms/array-editor.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/app/features/content/shared/forms/array-editor.component.html b/frontend/app/features/content/shared/forms/array-editor.component.html index 9c760a428..b2ef3fddb 100644 --- a/frontend/app/features/content/shared/forms/array-editor.component.html +++ b/frontend/app/features/content/shared/forms/array-editor.component.html @@ -24,7 +24,7 @@
-
From f42d16422db3273f0b3bcaf917ce43e19b41c56a Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 26 Oct 2020 14:11:23 +0100 Subject: [PATCH 3/4] Converter simplified. --- .../Apps/Json/AppPatternsConverter.cs | 10 ++--- .../Apps/Json/JsonAppPattern.cs | 38 ------------------- 2 files changed, 5 insertions(+), 43 deletions(-) delete mode 100644 backend/src/Squidex.Domain.Apps.Core.Model/Apps/Json/JsonAppPattern.cs diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs index adcafa6f4..6538f521d 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Model/Apps/Json/AppPatternsConverter.cs @@ -17,11 +17,11 @@ namespace Squidex.Domain.Apps.Core.Apps.Json { protected override void WriteValue(JsonWriter writer, AppPatterns value, JsonSerializer serializer) { - var json = new Dictionary(value.Count); + var json = new Dictionary(value.Count); - foreach (var (key, appPattern) in value) + foreach (var (key, pattern) in value) { - json.Add(key, new JsonAppPattern(appPattern)); + json.Add(key, pattern); } serializer.Serialize(writer, json); @@ -29,9 +29,9 @@ namespace Squidex.Domain.Apps.Core.Apps.Json protected override AppPatterns ReadValue(JsonReader reader, Type objectType, JsonSerializer serializer) { - var json = serializer.Deserialize>(reader)!; + var json = serializer.Deserialize>(reader)!; - return new AppPatterns(json.ToDictionary(x => x.Key, x => x.Value.ToPattern())); + return new AppPatterns(json); } } } diff --git a/backend/src/Squidex.Domain.Apps.Core.Model/Apps/Json/JsonAppPattern.cs b/backend/src/Squidex.Domain.Apps.Core.Model/Apps/Json/JsonAppPattern.cs deleted file mode 100644 index dfca9aa3b..000000000 --- a/backend/src/Squidex.Domain.Apps.Core.Model/Apps/Json/JsonAppPattern.cs +++ /dev/null @@ -1,38 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschränkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using Newtonsoft.Json; -using Squidex.Infrastructure.Reflection; - -namespace Squidex.Domain.Apps.Core.Apps.Json -{ - public class JsonAppPattern - { - [JsonProperty] - public string Name { get; set; } - - [JsonProperty] - public string Pattern { get; set; } - - [JsonProperty] - public string? Message { get; set; } - - public JsonAppPattern() - { - } - - public JsonAppPattern(AppPattern pattern) - { - SimpleMapper.Map(pattern, this); - } - - public AppPattern ToPattern() - { - return new AppPattern(Name, Pattern, Message); - } - } -} From 856b447b749a1088bc3efc080f92a59161bc6776 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 29 Oct 2020 11:30:12 +0100 Subject: [PATCH 4/4] UI fixes. --- .../custom-view-editor.component.html | 4 +- .../custom-view-editor.component.scss | 2 +- .../workflows/workflow-step.component.html | 39 +++++++++++++++---- .../workflows/workflow-step.component.scss | 2 +- .../workflow-transition.component.html | 16 +++++++- .../pages/workflows/workflow.component.html | 5 ++- .../workflows/workflows-page.component.html | 3 +- 7 files changed, 56 insertions(+), 15 deletions(-) diff --git a/frontend/app/features/content/pages/contents/custom-view-editor.component.html b/frontend/app/features/content/pages/contents/custom-view-editor.component.html index 71d55aa29..fb4100ef9 100644 --- a/frontend/app/features/content/pages/contents/custom-view-editor.component.html +++ b/frontend/app/features/content/pages/contents/custom-view-editor.component.html @@ -15,9 +15,9 @@
- +
diff --git a/frontend/app/features/content/pages/contents/custom-view-editor.component.scss b/frontend/app/features/content/pages/contents/custom-view-editor.component.scss index 9f16730f8..cacab06be 100644 --- a/frontend/app/features/content/pages/contents/custom-view-editor.component.scss +++ b/frontend/app/features/content/pages/contents/custom-view-editor.component.scss @@ -13,7 +13,7 @@ visibility: hidden; } -.form-check { +.custom-checkbox { display: inline-block; padding-left: 2rem; padding-right: .5rem; diff --git a/frontend/app/features/settings/pages/workflows/workflow-step.component.html b/frontend/app/features/settings/pages/workflows/workflow-step.component.html index 779272ef4..294a146f4 100644 --- a/frontend/app/features/settings/pages/workflows/workflow-step.component.html +++ b/frontend/app/features/settings/pages/workflows/workflow-step.component.html @@ -1,12 +1,19 @@
-
- +
@@ -26,7 +33,11 @@
- +
@@ -47,11 +58,14 @@
-
+
- +
- +
{{ 'workflows.syntax.for' | sqxTranslate }}
- +
diff --git a/frontend/app/features/settings/pages/workflows/workflow-step.component.scss b/frontend/app/features/settings/pages/workflows/workflow-step.component.scss index 57bdbb4e9..5a84b2c16 100644 --- a/frontend/app/features/settings/pages/workflows/workflow-step.component.scss +++ b/frontend/app/features/settings/pages/workflows/workflow-step.component.scss @@ -84,9 +84,9 @@ .transition-prevent-updates { & { - line-height: 2.5rem; margin-bottom: 1rem; margin-top: .25rem; + min-height: 2.5rem; } &-to { diff --git a/frontend/app/features/settings/pages/workflows/workflow-transition.component.html b/frontend/app/features/settings/pages/workflows/workflow-transition.component.html index 48546bbb8..23040dd60 100644 --- a/frontend/app/features/settings/pages/workflows/workflow-transition.component.html +++ b/frontend/app/features/settings/pages/workflows/workflow-transition.component.html @@ -11,13 +11,25 @@ {{ 'workflows.syntax.when' | sqxTranslate }}
- +
{{ 'workflows.syntax.for' | sqxTranslate }}
- +
diff --git a/frontend/app/features/settings/pages/workflows/workflow.component.html b/frontend/app/features/settings/pages/workflows/workflow.component.html index a854574da..4f625a5c6 100644 --- a/frontend/app/features/settings/pages/workflows/workflow.component.html +++ b/frontend/app/features/settings/pages/workflows/workflow.component.html @@ -59,7 +59,10 @@
- + {{ 'workflows.workflowNameHint' | sqxTranslate }} diff --git a/frontend/app/features/settings/pages/workflows/workflows-page.component.html b/frontend/app/features/settings/pages/workflows/workflows-page.component.html index 1256e3deb..70fc6d01d 100644 --- a/frontend/app/features/settings/pages/workflows/workflows-page.component.html +++ b/frontend/app/features/settings/pages/workflows/workflows-page.component.html @@ -34,7 +34,8 @@ {{ 'workflows.empty' | sqxTranslate }}
- +