From c16bbed607a9e52291e81c8acb00f9bc717d3e26 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 22 Nov 2022 11:50:49 +0100 Subject: [PATCH] Add missing files. --- .../schema/fields/field-group.component.html | 27 ++++++ .../schema/fields/field-group.component.scss | 16 ++++ .../schema/fields/field-group.component.ts | 91 +++++++++++++++++++ .../fields/sortable-field-list.component.html | 18 ++++ .../fields/sortable-field-list.component.scss | 0 .../fields/sortable-field-list.component.ts | 79 ++++++++++++++++ 6 files changed, 231 insertions(+) create mode 100644 frontend/src/app/features/schemas/pages/schema/fields/field-group.component.html create mode 100644 frontend/src/app/features/schemas/pages/schema/fields/field-group.component.scss create mode 100644 frontend/src/app/features/schemas/pages/schema/fields/field-group.component.ts create mode 100644 frontend/src/app/features/schemas/pages/schema/fields/sortable-field-list.component.html create mode 100644 frontend/src/app/features/schemas/pages/schema/fields/sortable-field-list.component.scss create mode 100644 frontend/src/app/features/schemas/pages/schema/fields/sortable-field-list.component.ts diff --git a/frontend/src/app/features/schemas/pages/schema/fields/field-group.component.html b/frontend/src/app/features/schemas/pages/schema/fields/field-group.component.html new file mode 100644 index 000000000..b5fea017b --- /dev/null +++ b/frontend/src/app/features/schemas/pages/schema/fields/field-group.component.html @@ -0,0 +1,27 @@ +
+ + + +
+ + + +
+
+
+ +
+
+ + + + + +
+
\ No newline at end of file diff --git a/frontend/src/app/features/schemas/pages/schema/fields/field-group.component.scss b/frontend/src/app/features/schemas/pages/schema/fields/field-group.component.scss new file mode 100644 index 000000000..804cb7d57 --- /dev/null +++ b/frontend/src/app/features/schemas/pages/schema/fields/field-group.component.scss @@ -0,0 +1,16 @@ +@import 'mixins'; +@import 'vars'; + +$field-line: #c7cfd7; + +.field-placeholder { + border: 2px dashed $field-line; + border-radius: 0; + margin-bottom: .25rem; + margin-top: 0; + min-height: 4rem; +} + +.cdk-drop-list-dragging { + border: 0; +} \ No newline at end of file diff --git a/frontend/src/app/features/schemas/pages/schema/fields/field-group.component.ts b/frontend/src/app/features/schemas/pages/schema/fields/field-group.component.ts new file mode 100644 index 000000000..21328ca05 --- /dev/null +++ b/frontend/src/app/features/schemas/pages/schema/fields/field-group.component.ts @@ -0,0 +1,91 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { CdkDragDrop } from '@angular/cdk/drag-drop'; +import { ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core'; +import { AppSettingsDto, FieldDto, FieldGroup, LanguageDto, LocalStoreService, RootFieldDto, SchemaDto, Settings, StatefulComponent } from '@app/shared'; + +interface State { + // The when the section is collapsed. + isCollapsed: boolean; +} + +@Component({ + selector: 'sqx-field-group[fieldGroup][languages][schema][settings]', + styleUrls: ['./field-group.component.scss'], + templateUrl: './field-group.component.html', +}) +export class FieldGroupComponent extends StatefulComponent { + @Output() + public sorted = new EventEmitter>(); + + @Input() + public languages!: ReadonlyArray; + + @Input() + public parent?: RootFieldDto; + + @Input() + public settings!: AppSettingsDto; + + @Input() + public sortable = false; + + @Input() + public schema!: SchemaDto; + + @Input() + public fieldsEmpty = false; + + @Input() + public fieldGroup!: FieldGroup; + + public trackByFieldFn: (_index: number, field: FieldDto) => any; + + public get hasAnyFields() { + return this.parent ? this.parent.nested.length > 0 : this.schema.fields.length > 0; + } + + constructor(changeDetector: ChangeDetectorRef, + private readonly localStore: LocalStoreService, + ) { + super(changeDetector, { + isCollapsed: false, + }); + + this.changes.subscribe(state => { + if (this.fieldGroup?.separator && this.schema) { + this.localStore.setBoolean(this.isCollapsedKey(), state.isCollapsed); + } + }); + + this.trackByFieldFn = this.trackByField.bind(this); + } + + public ngOnInit() { + if (this.fieldGroup?.separator && this.schema) { + const isCollapsed = this.localStore.getBoolean(this.isCollapsedKey()); + + this.next({ isCollapsed }); + } + } + + public toggle() { + this.next(s => ({ + ...s, + isCollapsed: !s.isCollapsed, + })); + } + + public trackByField(_index: number, field: FieldDto) { + return field.fieldId + this.schema.id; + } + + private isCollapsedKey(): string { + return Settings.Local.FIELD_COLLAPSED(this.schema?.id, this.fieldGroup.separator?.fieldId); + } +} \ No newline at end of file diff --git a/frontend/src/app/features/schemas/pages/schema/fields/sortable-field-list.component.html b/frontend/src/app/features/schemas/pages/schema/fields/sortable-field-list.component.html new file mode 100644 index 000000000..3d337425e --- /dev/null +++ b/frontend/src/app/features/schemas/pages/schema/fields/sortable-field-list.component.html @@ -0,0 +1,18 @@ +
+
+ + +
+
\ No newline at end of file diff --git a/frontend/src/app/features/schemas/pages/schema/fields/sortable-field-list.component.scss b/frontend/src/app/features/schemas/pages/schema/fields/sortable-field-list.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/src/app/features/schemas/pages/schema/fields/sortable-field-list.component.ts b/frontend/src/app/features/schemas/pages/schema/fields/sortable-field-list.component.ts new file mode 100644 index 000000000..206dad409 --- /dev/null +++ b/frontend/src/app/features/schemas/pages/schema/fields/sortable-field-list.component.ts @@ -0,0 +1,79 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. + */ + +import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { AppSettingsDto, FieldDto, FieldGroup, groupFields, LanguageDto, RootFieldDto, SchemaDto } from '@app/shared'; + +@Component({ + selector: 'sqx-sortable-field-list[fields][languages][settings]', + styleUrls: ['./sortable-field-list.component.scss'], + templateUrl: './sortable-field-list.component.html', +}) +export class SortableFieldListComponent { + @Output() + public sorted = new EventEmitter>(); + + @Input() + public languages!: ReadonlyArray; + + @Input() + public parent?: RootFieldDto; + + @Input() + public settings!: AppSettingsDto; + + @Input() + public schema!: SchemaDto; + + @Input() + public sortable = false; + + @Input() + public fieldsEmpty = false; + + @Input() + public set fields(value: ReadonlyArray) { + this.fieldGroups = groupFields(value, true); + } + + public fieldGroups: FieldGroup[] = []; + + public sortGroups(event: CdkDragDrop) { + this.onSort(event); + } + + public sortFields(event: CdkDragDrop) { + this.onSort(event); + } + + private onSort(event: CdkDragDrop) { + if (event.previousContainer === event.container) { + moveItemInArray(event.container.data, event.previousIndex, event.currentIndex); + } else { + transferArrayItem( + event.previousContainer.data, + event.container.data, + event.previousIndex, + event.currentIndex); + } + + const result: FieldDto[] = []; + + for (const group of this.fieldGroups) { + if (group.separator) { + result.push(group.separator); + } + + for (const field of group.fields) { + result.push(field); + } + } + + this.sorted.emit(result); + } +} \ No newline at end of file