diff --git a/projects/common/components/compound-elements/cloze/cloze.component.ts b/projects/common/components/compound-elements/cloze/cloze.component.ts index d8ebcd693e75db5e07dae7ffe24ac62d8a63487d..c16fb3c926e49a991cf441289efeea70c1f3fc45 100644 --- a/projects/common/components/compound-elements/cloze/cloze.component.ts +++ b/projects/common/components/compound-elements/cloze/cloze.component.ts @@ -158,6 +158,7 @@ import { ClozeElement } from 'common/models/elements/compound-elements/cloze/clo <aspect-compound-child-overlay *ngIf="['ToggleButton', 'DropList', 'TextField', 'Button'] | arrayIncludes:subPart.type" [style.display]="'inline-block'" + [style.vertical-align]="'top'" [parentForm]="parentForm" [element]="$any(subPart).attrs.model" [editorMode]="editorMode" diff --git a/projects/common/components/compound-elements/cloze/compound-child-overlay.component.ts b/projects/common/components/compound-elements/cloze/compound-child-overlay.component.ts index 286fa77a244868b8188d6ad7453b5edf825b5bbe..a43d0a28cacadafea9b0c9e563baa600ba70f190 100644 --- a/projects/common/components/compound-elements/cloze/compound-child-overlay.component.ts +++ b/projects/common/components/compound-elements/cloze/compound-child-overlay.component.ts @@ -9,6 +9,7 @@ import { TextFieldSimpleElement } from 'common/models/elements/compound-elements/cloze/cloze-child-elements/text-field-simple'; import { ValueChangeElement } from 'common/models/elements/element'; +import { DropListElement } from 'common/models/elements/input-elements/drop-list'; @Component({ selector: 'aspect-compound-child-overlay', @@ -51,7 +52,7 @@ import { ValueChangeElement } from 'common/models/elements/element'; ] }) export class CompoundChildOverlayComponent { // TODO rename to ClozeChildOverlay - @Input() element!: ToggleButtonElement | TextFieldSimpleElement; + @Input() element!: ToggleButtonElement | TextFieldSimpleElement | DropListElement; @Input() parentForm!: FormGroup; @Input() editorMode: boolean = false; @Input() lineHeight!: number; diff --git a/projects/common/components/input-elements/drop-list.component.ts b/projects/common/components/input-elements/drop-list.component.ts index 9d48f1fc7c811e6e5308fab4720926a8420074bd..69cb39bb9b671c70f05ad94076112ec0c73cc53d 100644 --- a/projects/common/components/input-elements/drop-list.component.ts +++ b/projects/common/components/input-elements/drop-list.component.ts @@ -1,8 +1,7 @@ -// eslint-disable-next-line max-classes-per-file import { - AfterViewInit, - Component, ElementRef, Input, OnDestroy, OnInit, Pipe, PipeTransform, ViewChild + Component, Input, OnInit, Pipe, PipeTransform } from '@angular/core'; +import { CdkDrag, CdkDragDrop, CdkDropList, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop'; import { DropListElement } from 'common/models/elements/input-elements/drop-list'; import { DragNDropValueObject } from 'common/models/elements/element'; import { FormElementComponent } from '../../directives/form-element-component.directive'; @@ -10,14 +9,24 @@ import { FormElementComponent } from '../../directives/form-element-component.di @Component({ selector: 'aspect-drop-list', template: ` +<!-- [fxLayout]="elementModel.orientation | droplistLayout"--> +<!-- [fxLayoutAlign]="elementModel.orientation | droplistLayoutAlign"--> +<!-- [class.vertical-orientation]="elementModel.orientation === 'vertical'"--> +<!-- [class.horizontal-orientation]="elementModel.orientation === 'horizontal'"--> +<!-- [class.only-one-item]="elementModel.onlyOneItem"--> +<!-- [style.min-height.px]="elementModel.position?.useMinHeight || clozeContext ? elementModel.height : undefined"--> +<!-- [style.border-color]="elementModel.highlightReceivingDropListColor"--> +<!-- tabindex="0"--> + <div class="list" [id]="elementModel.id" - [fxLayout]="elementModel.orientation | droplistLayout" - [fxLayoutAlign]="elementModel.orientation | droplistLayoutAlign" + [class.cloze-context]="clozeContext" [class.vertical-orientation]="elementModel.orientation === 'vertical'" [class.horizontal-orientation]="elementModel.orientation === 'horizontal'" - [class.cloze-context]="clozeContext" - [class.only-one-item]="elementModel.onlyOneItem" - [style.min-height.px]="elementModel.position?.useMinHeight || clozeContext ? elementModel.height : undefined" + [class.floating-orientation]="elementModel.orientation === 'flex'" + cdkDropList + [cdkDropListData]="this" [cdkDropListConnectedTo]="elementModel.connectedTo" + [cdkDropListEnterPredicate]="onlyOneItemPredicate" + (cdkDropListDropped)="drop($event)" [style.color]="elementModel.styling.fontColor" [style.font-family]="elementModel.styling.font" [style.font-size.px]="elementModel.styling.fontSize" @@ -26,45 +35,30 @@ import { FormElementComponent } from '../../directives/form-element-component.di [style.text-decoration]="elementModel.styling.underline ? 'underline' : ''" [style.backgroundColor]="elementModel.styling.backgroundColor" [class.errors]="elementFormControl.errors && elementFormControl.touched" - [style.border-color]="elementModel.highlightReceivingDropListColor" - [class.highlight-valid-drop]="highlightValidDrop" - [class.highlight-as-receiver]="highlightAsReceiver" - tabindex="0" - (focusout)="elementFormControl.markAsTouched()" - (drop)="drop($event)" (dragenter)="dragEnterList($event)" (dragleave)="dragLeaveList($event)" - (dragover)="setDropEffect($event)"> - <!--Add dummy div - otherwise the empty list in cloze context will not be in one line--> - <div *ngIf="viewModel.length === 0" - [style.min-height.px]="elementModel.height - 4" - [style.pointer-events]="'none'" - fxLayout="row" - [fxLayoutAlign]="'center center'"> - <span> </span> - </div> - <ng-container *ngFor="let dropListValueElement of viewModel let index = index;"> + (focusout)="elementFormControl.markAsTouched()"> + <ng-container *ngFor="let dropListValueElement of elementModel.value let index = index;"> +<!-- fxLayout="row"--> +<!-- [fxLayoutAlign]="elementModel.onlyOneItem ? (clozeContext ? 'center center' : 'start center') : 'none'"--> <div *ngIf="!dropListValueElement.imgSrc" - class="list-item" - fxLayout="row" - [fxLayoutAlign]="elementModel.onlyOneItem ? (clozeContext ? 'center center' : 'start center') : 'none'" - draggable="true" - (dragstart)="dragStart($event, dropListValueElement, index)" (dragend)="dragEnd($event)" - (dragenter)="dragEnterItem($event)" - [class.show-as-placeholder]="showAsPlaceholder && placeHolderIndex === index" - [class.show-as-hidden]="hidePlaceholder && placeHolderIndex === index" - [style.pointer-events]="dragging && elementModel.isSortList === false ? 'none' : ''" + class="list-item" cdkDrag [style.background-color]="elementModel.styling.itemBackgroundColor"> <span>{{dropListValueElement.text}}</span> + <div class="example-custom-placeholder" *cdkDragPlaceholder></div> + <ng-template cdkDragPreview [matchSize]="true"> + <div [style.color]="elementModel.styling.fontColor" + [style.font-family]="elementModel.styling.font" + [style.font-size.px]="elementModel.styling.fontSize" + [style.font-weight]="elementModel.styling.bold ? 'bold' : ''" + [style.font-style]="elementModel.styling.italic ? 'italic' : ''" + [style.text-decoration]="elementModel.styling.underline ? 'underline' : ''" + [style.background-color]="elementModel.styling.itemBackgroundColor"> + <span>{{dropListValueElement.text}}</span> + </div> + </ng-template> </div> <img *ngIf="dropListValueElement.imgSrc" - class="list-item" - [src]="dropListValueElement.imgSrc | safeResourceUrl" alt="Image Placeholder" - [id]="dropListValueElement.id" - draggable="true" - (dragstart)="dragStart($event, dropListValueElement, index)" (dragend)="dragEnd($event)" - (dragenter)="dragEnterItem($event)" - [class.show-as-placeholder]="showAsPlaceholder && placeHolderIndex === index" - [class.show-as-hidden]="hidePlaceholder && placeHolderIndex === index" - [style.pointer-events]="dragging && elementModel.isSortList === false ? 'none' : ''"> + class="list-item" cdkDrag + [src]="dropListValueElement.imgSrc | safeResourceUrl" alt="Image Placeholder"> </ng-container> </div> <mat-error *ngIf="elementFormControl.errors && elementFormControl.touched" @@ -75,313 +69,72 @@ import { FormElementComponent } from '../../directives/form-element-component.di `, styles: [ '.list {width: 100%; height: 100%; background-color: rgb(244, 244, 242); border-radius: 5px;}', - '.list {padding: 2px;}', + // '.list {padding: 2px; display: flex; gap: 5px;}', + '.list {display: flex; gap: 5px; box-sizing: border-box; padding: 5px}', + '.list.vertical-orientation {flex-direction: column;}', + '.list.horizontal-orientation {flex-direction: row;}', + '.list.floating-orientation {place-content: center space-around; align-items: center; flex-flow: row wrap;}', + // '.cloze-context.list {place-content: stretch; align-items: stretch;}', '.list-item {border-radius: 5px;}', + // '.list-item {margin: 2px; border-radius: 5px;}', ':not(.cloze-context) .list-item {padding: 10px;}', - '.cloze-context .list-item {padding: 0 5px; line-height: 1.2;}', - '.only-one-item.cloze-context .list-item {padding: 0;}', - '.only-one-item:not(.cloze-context) .list-item {padding: 0 10px;}', - '.only-one-item .list-item {height: 100%; min-height: 100%; min-width: 100%; width: 100%; line-height: 1.2;}', - 'img.list-item {align-self: start; padding: 2px !important;}', - '.vertical-orientation .list-item:not(:last-child) {margin-bottom: 5px;}', - '.horizontal-orientation .list-item:not(:last-child) {margin-right: 5px;}', - '.errors {border: 2px solid #f44336 !important;}', - '.error-message {font-size: 75%; margin-top: 10px; margin-left: 5px; position: absolute; pointer-events: none;}', - '.cloze-context-error-message {padding: 0 !important;}', - '.list-item {cursor: grab;}', - '.list-item:active {cursor: grabbing;}', - '.show-as-placeholder {opacity: 0.5 !important; pointer-events: none;}', - '.highlight-valid-drop {background-color: #ccc !important;}', - '.highlight-as-receiver {padding: 0; border: 2px solid;}', - '.show-as-hidden {visibility: hidden;}' + '.cloze-context .list-item {padding: 0 5px;}', + // '.cloze-context .list {padding: 0 5px;}', + // '.cloze-context .list-item {padding: 0 5px; line-height: 1.2;}', + // '.only-one-item.cloze-context .list-item {padding: 0;}', + // '.only-one-item.cloze-context .list-item {padding: 0;}', + // '.only-one-item:not(.cloze-context) .list-item {padding: 0 10px;}', + // '.only-one-item .list-item {height: 100%; min-height: 100%; min-width: 100%; width: 100%; line-height: 1.2;}', + // 'img.list-item {align-self: start; padding: 2px !important;}', + 'img.list-item {align-self: start;}', + // '.vertical-orientation .list-item:not(:last-child) {margin-bottom: 5px;}', + // '.horizontal-orientation .list-item:not(:last-child) {margin-right: 5px;}', + // '.errors {border: 2px solid #f44336 !important;}', + // '.error-message {font-size: 75%; margin-top: 10px; margin-left: 5px; position: absolute; pointer-events: none;}', + // '.cloze-context-error-message {padding: 0 !important;}', + // '.list-item {cursor: grab;}', + // '.list-item:active {cursor: grabbing;}', + + '.cdk-drag-preview {border-radius: 5px; box-shadow: 2px 2px 5px black;}', + + '.cdk-drop-list-dragging .cdk-drag {transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);}', + '.cdk-drop-list-receiving {background-color: cadetblue !important;}', + // '.cdk-drop-list-receiving {border: 2px solid;}', + // '.cdk-drop-list-receiving .list-item {margin: 0;}' + '.example-custom-placeholder {background: #ccc; border: dotted 3px #999; min-height: 20px;}' ] }) -export class DropListComponent extends FormElementComponent implements OnInit, AfterViewInit, OnDestroy { +export class DropListComponent extends FormElementComponent { @Input() elementModel!: DropListElement; @Input() clozeContext: boolean = false; - @ViewChild('placeholder') placeholder!: ElementRef<HTMLElement>; - static dragAndDropComponents: { [id: string]: DropListComponent } = {}; - - viewModel: DragNDropValueObject[] = []; - placeHolderIndex?: number; - highlightAsReceiver = false; - - dragging = false; - - showAsPlaceholder = false; - hidePlaceholder = false; - highlightValidDrop = false; - - static draggedElement?: DragNDropValueObject; - static sourceList?: DropListComponent; - - ngOnInit() { - super.ngOnInit(); - this.viewModel = [...this.elementFormControl.value]; - } - - ngAfterViewInit() { - DropListComponent.dragAndDropComponents[this.elementModel.id] = this; - // Prevent 'forbidden' cursor outside of drop lists - document.addEventListener('dragover', (event => event.preventDefault())); - } - - // TODO method names - // TODO elemente flackern manchmal beim aufnehmen; iwas stimmt mit highlightAsReceiver nicht - dragStart(dragEvent: DragEvent, - dropListValueElement: DragNDropValueObject, - sourceListIndex: number) { - if (dragEvent.dataTransfer) { - dragEvent.dataTransfer.effectAllowed = 'copyMove'; - dragEvent.dataTransfer.setDragImage( - this.createDragImage(dragEvent.target as HTMLElement, dropListValueElement.id), 0, 0); - } - - // Timeout is necessary for Chrome, which does not allow DOM manipulation on dragstart - setTimeout(() => { - DropListComponent.draggedElement = dropListValueElement; - DropListComponent.sourceList = this; - this.placeHolderIndex = sourceListIndex; - if (this.elementModel.isSortList) { - this.showAsPlaceholder = true; - } else { - if (!this.elementModel.copyOnDrop) this.hidePlaceholder = true; - this.highlightValidDrop = true; - } - - /* Let all droplists know when drag is going on, so they can potentially disable their pointer effects. - * This is to prevent unwanted dragOver events of list items. */ - Object.entries(DropListComponent.dragAndDropComponents) - .forEach(([, value]) => { - value.dragging = true; - }); - - if (this.elementModel.highlightReceivingDropList) { - this.highlightReceiverLists(); - } - }); - } - - highlightReceiverLists(): void { - this.highlightAsReceiver = true; - this.elementModel.connectedTo.forEach(connectedDropListID => { - DropListComponent.dragAndDropComponents[connectedDropListID].highlightAsReceiver = true; - }); - } - - createDragImage(baseElement: HTMLElement, baseID: string): HTMLElement { - const dragImage: HTMLElement = baseElement.cloneNode(true) as HTMLElement; - dragImage.id = `${baseID}-dragimage`; - dragImage.style.display = 'inline-block'; - dragImage.style.maxWidth = `${(baseElement as HTMLElement).offsetWidth + 20}px`; - dragImage.style.fontSize = `${this.elementModel.styling.fontSize}px`; - dragImage.style.borderRadius = '5px'; - dragImage.style.padding = '10px 20px'; // Leave space for cursor - document.body.appendChild(dragImage); - return dragImage; - } - - dragEnterItem(event: DragEvent) { - event.preventDefault(); - if (this.elementModel.isSortList && DropListComponent.sourceList === this) { - this.moveListItem( - this.placeHolderIndex as number, - Array.from((event.target as any).parentNode.children).indexOf(event.target) - ); - } - } + // viewModel: DragNDropValueObject[] = []; - moveListItem(sourceIndex: number, targetIndex: number): void { - const removedElement = this.viewModel.splice(sourceIndex, 1)[0]; - this.viewModel.splice(targetIndex, 0, removedElement); - this.placeHolderIndex = targetIndex; - } + // ngOnInit() { + // super.ngOnInit(); + // this.viewModel = [...this.elementFormControl.value]; + // } - setDropEffect(event: DragEvent) { - event.preventDefault(); - if (!event.dataTransfer) return; - if (this.isDropAllowed()) { - if ((DropListComponent.sourceList as DropListComponent).elementModel.copyOnDrop) { - event.dataTransfer.dropEffect = 'copy'; - } else { - event.dataTransfer.dropEffect = 'move'; - } + drop(event: CdkDragDrop<any>) { + if (event.previousContainer === event.container) { + moveItemInArray(event.container.data.elementModel.value, event.previousIndex, event.currentIndex); + event.container.data.updateFormvalue(); } else { - event.dataTransfer.dropEffect = 'none'; - } - } - - dragEnterList(event: DragEvent) { - event.preventDefault(); - if (!this.isDropAllowed()) return; - if (!this.elementModel.isSortList) { - this.highlightValidDrop = true; - } else if (DropListComponent.sourceList !== this) { - this.viewModel.push(DropListComponent.draggedElement as DragNDropValueObject); - const sourceList = DropListComponent.sourceList as DropListComponent; - DropListComponent.removeElementFromList(sourceList, sourceList.placeHolderIndex as number); - sourceList.placeHolderIndex = undefined; - DropListComponent.sourceList = this; - this.placeHolderIndex = this.viewModel.length > 0 ? this.viewModel.length - 1 : 0; - } - } - - dragLeaveList(event: DragEvent) { - event.preventDefault(); - this.highlightValidDrop = false; - } - - drop(event: DragEvent): void { - event.preventDefault(); - - if (DropListComponent.sourceList === this) { - // SortList viewModel already gets manipulated while dragging. Just set the value. - if (this.elementModel.isSortList) this.elementFormControl.setValue(this.viewModel); - this.dragEnd(); - return; - } - - // if drop is allowed that means item transfer between non-sort lists - if (this.isDropAllowed()) { - if (!DropListComponent.isItemIDAlreadyPresent(DropListComponent.draggedElement?.id as string, this.elementFormControl.value) && - !(this.elementModel.onlyOneItem && this.viewModel.length > 0)) { // normal drop - if (!DropListComponent.sourceList?.elementModel.copyOnDrop) { // remove source item if not copy - DropListComponent.removeElementFromList(DropListComponent.sourceList as DropListComponent, - DropListComponent.sourceList?.placeHolderIndex as number); - } - DropListComponent.addElementToList(this, DropListComponent.draggedElement as DragNDropValueObject); - } else if (DropListComponent.isItemIDAlreadyPresent(DropListComponent.draggedElement?.id as string, this.elementFormControl.value) && - this.elementModel.deleteDroppedItemWithSameID) { // put back (return) item - DropListComponent.removeElementFromList(DropListComponent.sourceList as DropListComponent, - DropListComponent.sourceList?.placeHolderIndex as number); - } else if (this.elementModel.onlyOneItem && this.viewModel.length > 0 && - this.viewModel[0].returnToOriginOnReplacement) { // replace - const originListComponent = DropListComponent.dragAndDropComponents[this.viewModel[0].originListID as string]; - const isItemIDAlreadyPresent = - DropListComponent.isItemIDAlreadyPresent(this.viewModel[0].id, originListComponent.elementFormControl.value); - if (!(isItemIDAlreadyPresent && originListComponent.elementModel.deleteDroppedItemWithSameID)) { // dont add to origin if dupe - DropListComponent.addElementToList(originListComponent, this.viewModel[0]); - } - DropListComponent.removeElementFromList(this, 0); - DropListComponent.addElementToList(this, DropListComponent.draggedElement as DragNDropValueObject); - if (!DropListComponent.sourceList?.elementModel.copyOnDrop) { // remove source item if not copy - DropListComponent.removeElementFromList(DropListComponent.sourceList as DropListComponent, - DropListComponent.sourceList?.placeHolderIndex as number); - } - } else { - console.warn('Valid drop but no handler found. This is most likely a bug!'); - } - } - this.dragEnd(); - } - - /* When - - same list - - connected list - - onlyOneItem && itemcount = 0 || - onlyOneItem && itemcount = 1 && this.viewModel[0].returnToOriginOnReplacement) // verdraengen - - (! id already present) || id already present && deleteDroppedItemWithSameID // zuruecklegen - */ - isDropAllowed(): boolean { - if (!DropListComponent.sourceList) return false; - const sameList = DropListComponent.sourceList === this; - const connectedDropLists = (DropListComponent.sourceList as DropListComponent).elementModel.connectedTo; - const isConnectedList = (connectedDropLists as string[]).includes(this.elementModel.id); - return (sameList) || (isConnectedList && - !this.isOnlyOneItemAndNoReplacingOrReturning() && - !this.isIDPresentAndNoReturning()); - } - - isIDPresentAndNoReturning(): boolean { - return DropListComponent.isItemIDAlreadyPresent(DropListComponent.draggedElement?.id as string, this.elementFormControl.value) && - !(this.elementModel.deleteDroppedItemWithSameID); - } - - /* No replacement in sort lists: operation should only move the placeholder - until the actual drop. By allowing elements to transfer while dragging we create - all kinds of problems and unwanted behaviour, like having all touched lists generate change events. - */ - isOnlyOneItemAndNoReplacingOrReturning(): boolean { - return this.elementModel.onlyOneItem && this.viewModel.length > 0 && - !((this.viewModel[0].returnToOriginOnReplacement && !this.elementModel.isSortList) || - (this.elementModel.deleteDroppedItemWithSameID && - DropListComponent.draggedElement?.id === this.viewModel[0].id)); - } - - static isItemIDAlreadyPresent(itemID: string, valueList: DragNDropValueObject[]): boolean { - const listValueIDs = valueList.map((valueValue: DragNDropValueObject) => valueValue.id); - return listValueIDs.includes(itemID); - } - - static addElementToList(listComponent: DropListComponent, element: DragNDropValueObject, targetIndex?: number): void { - if (targetIndex) { - listComponent.viewModel.splice( - Math.min(listComponent.viewModel.length, element.originListIndex || 0), - 0, - element + transferArrayItem( + event.previousContainer.data.elementModel.value, + event.container.data.elementModel.value, + event.previousIndex, + event.currentIndex ); - } else { - listComponent.viewModel.push(element); + event.previousContainer.data.updateFormvalue(); + event.container.data.updateFormvalue(); } - listComponent.elementFormControl.setValue(listComponent.viewModel); - } - - static removeElementFromList(listComponent: DropListComponent, index: number): void { - listComponent.viewModel.splice(index, 1); - listComponent.elementFormControl.setValue(listComponent.viewModel); - } - - dragEnd(event?: DragEvent): void { - event?.preventDefault(); - - Object.entries(DropListComponent.dragAndDropComponents) - .forEach(([, value]) => { - value.highlightAsReceiver = false; - value.dragging = false; - value.highlightValidDrop = false; - }); - if (DropListComponent.sourceList) DropListComponent.sourceList.placeHolderIndex = undefined; - this.placeHolderIndex = undefined; - - document.getElementById(`${DropListComponent.draggedElement?.id}-dragimage`)?.remove(); - } - - ngOnDestroy(): void { - delete DropListComponent.dragAndDropComponents[this.elementModel.id]; } -} -@Pipe({ - name: 'droplistLayout' -}) -export class DropListLayoutPipe implements PipeTransform { - transform(orientation: string): string { - switch (orientation) { - case 'horizontal': - return 'row'; - case 'vertical': - return 'column'; - case 'flex': - return 'row wrap'; - default: - throw Error(`droplist orientation invalid: ${orientation}`); - } + updateFormvalue(): void { + this.elementFormControl.setValue(this.elementModel.value); } -} -@Pipe({ - name: 'droplistLayoutAlign' -}) -export class DropListLayoutAlignPipe implements PipeTransform { - transform(orientation: string): string { - switch (orientation) { - case 'horizontal': - case 'vertical': - return 'start stretch'; - case 'flex': - return 'space-around center'; - default: - throw Error(`droplist orientation invalid: ${orientation}`); - } - } + onlyOneItemPredicate = (drag: CdkDrag, drop: CdkDropList): boolean => ( + !drop.data.elementModel.onlyOneItem || drop.data.elementModel.value.length < 1 + ); } diff --git a/projects/common/models/elements/compound-elements/cloze/cloze.ts b/projects/common/models/elements/compound-elements/cloze/cloze.ts index eaa8a05bc29fa49c67b4937225391c6980648873..9846847969258752ca860b10b53f1eaa01bcb984 100644 --- a/projects/common/models/elements/compound-elements/cloze/cloze.ts +++ b/projects/common/models/elements/compound-elements/cloze/cloze.ts @@ -145,7 +145,7 @@ export class ClozeElement extends CompoundElement implements PositionedUIElement break; case 'drop-list': case 'drop-list-simple' as UIElementType: // keep here for compatibility - newElement = new DropListElement({ ...elementModel as DropListElement, type: 'drop-list' }); + newElement = new DropListElement(elementModel as DropListElement); break; case 'toggle-button': newElement = new ToggleButtonElement(elementModel as ToggleButtonElement); diff --git a/projects/common/models/elements/input-elements/drop-list.ts b/projects/common/models/elements/input-elements/drop-list.ts index 25290fca604b7567fe75fa51776919ac2659002e..123bc76fca4de742cee9465aea29fa5e694a0cd1 100644 --- a/projects/common/models/elements/input-elements/drop-list.ts +++ b/projects/common/models/elements/input-elements/drop-list.ts @@ -15,8 +15,8 @@ export class DropListElement extends InputElement { connectedTo: string[] = []; copyOnDrop: boolean = false; deleteDroppedItemWithSameID: boolean = false; - orientation: 'vertical' | 'horizontal' | 'flex' = 'vertical'; - highlightReceivingDropList: boolean = false; + orientation: 'vertical' | 'horizontal' | 'flex' = 'vertical'; // TODO besser floating + highlightReceivingDropList: boolean = false; // TODO unused highlightReceivingDropListColor: string = '#006064'; position: PositionProperties | undefined; styling: BasicStyles & { diff --git a/projects/common/shared.module.ts b/projects/common/shared.module.ts index d1b8888cc9e334dbf0c16d62098a534bc73d95fd..ffd85fbbf4959373df068b8eb704befb6c49db12 100644 --- a/projects/common/shared.module.ts +++ b/projects/common/shared.module.ts @@ -52,11 +52,7 @@ import { } from './components/compound-elements/likert/likert-radio-button-group.component'; import { ImageMagnifierComponent } from './components/media-elements/image-magnifier.component'; import { RadioGroupImagesComponent } from './components/input-elements/radio-group-images.component'; -import { - DropListComponent, - DropListLayoutAlignPipe, - DropListLayoutPipe -} from './components/input-elements/drop-list.component'; +import { DropListComponent } from './components/input-elements/drop-list.component'; import { ClozeComponent } from './components/compound-elements/cloze/cloze.component'; import { SliderComponent } from './components/input-elements/slider.component'; import { SpellCorrectComponent } from './components/input-elements/spell-correct.component'; @@ -142,8 +138,6 @@ import { GetValuePipe, MathFieldComponent } from './components/input-elements/ma ArrayIncludesPipe, UpdateTextareaRowsPipe, SpinnerComponent, - DropListLayoutPipe, - DropListLayoutAlignPipe, GetValuePipe, MathFieldComponent ], diff --git a/projects/editor/src/app/components/canvas/overlays/canvas-element-overlay.ts b/projects/editor/src/app/components/canvas/overlays/canvas-element-overlay.ts index afdd9ee11c0a0019b676d90e2b384865154c42c8..79f8910f0837bba46e854e49b8e677907be0877a 100644 --- a/projects/editor/src/app/components/canvas/overlays/canvas-element-overlay.ts +++ b/projects/editor/src/app/components/canvas/overlays/canvas-element-overlay.ts @@ -47,16 +47,16 @@ export abstract class CanvasElementOverlay implements OnInit, OnDestroy { } // DropList keeps a special viewModel variable, which needs to be updated - if (this.childComponent.instance instanceof DropListComponent) { - (this.childComponent.instance as DropListComponent).viewModel = this.element.value as DragNDropValueObject[]; - } + // if (this.childComponent.instance instanceof DropListComponent) { + // (this.childComponent.instance as DropListComponent).viewModel = this.element.value as DragNDropValueObject[]; + // } // Make children not clickable. This way the only relevant events are managed by the overlay. this.childComponent.location.nativeElement.style.pointerEvents = 'none'; if (this.childComponent.instance instanceof ClozeComponent) { - // make cloze element children clickable to access child elements this.childComponent.instance.editorMode = true; + // make cloze element children clickable to access child elements this.childComponent.location.nativeElement.style.pointerEvents = 'unset'; this.childComponent.instance.childElementSelected .pipe(takeUntil(this.ngUnsubscribe))