From 68a7ef59477b3856c7dcd2acf8c91f623211e19a Mon Sep 17 00:00:00 2001 From: mechtelm <nicht@mehr.fragen> Date: Thu, 11 Nov 2021 09:15:06 +0100 Subject: [PATCH] Add slider to editor --- package-lock.json | 1 - .../element-components/slider.component.ts | 30 +++++++++++++++++++ projects/common/id.service.ts | 1 + projects/common/models/slider-element.ts | 18 +++++++++++ projects/common/models/uI-element.ts | 2 +- projects/common/shared.module.ts | 10 ++++++- projects/common/util/element.factory.ts | 7 +++++ .../ui-element-toolbox.component.html | 5 ++++ .../element-properties.component.html | 18 +++++++++++ projects/editor/src/assets/i18n/de.json | 3 ++ 10 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 projects/common/element-components/slider.component.ts create mode 100644 projects/common/models/slider-element.ts diff --git a/package-lock.json b/package-lock.json index 881bbd7d2..711c57e8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,7 +4,6 @@ "requires": true, "packages": { "": { - "name": "verona-modules-aspect", "dependencies": { "@angular/animations": "~12.2.7", "@angular/cdk": "^12.2.6", diff --git a/projects/common/element-components/slider.component.ts b/projects/common/element-components/slider.component.ts new file mode 100644 index 000000000..a917c3671 --- /dev/null +++ b/projects/common/element-components/slider.component.ts @@ -0,0 +1,30 @@ +import { Component, EventEmitter, Output } from '@angular/core'; +import { ElementComponent } from '../element-component.directive'; +import { SliderElement } from '../models/slider-element'; + +@Component({ + selector: 'app-slider', + template: ` + <div [style.display]="'flex'" + [style.background-color]="elementModel.backgroundColor" + [style.width.%]="100" + [style.height.%]="100"> + <div *ngIf="elementModel.showLabel">{{elementModel.minValue | number:'.0'}}</div> + <mat-slider + [style.width.%]="100" + [style.height.%]="100" + [max]="elementModel.maxValue" + [min]="elementModel.minValue"> + </mat-slider> + <div *ngIf="elementModel.showLabel">{{elementModel.maxValue | number:'.0'}}</div> + </div> + `, + styles: [ + '.dynamic-image{width: 100%; height: fit-content}', + '.static-image{ width: 100%; height: 100%; object-fit: contain}' + ] +}) +export class SliderComponent extends ElementComponent { + elementModel!: SliderElement; + +} diff --git a/projects/common/id.service.ts b/projects/common/id.service.ts index 1ac383e16..b4e997701 100644 --- a/projects/common/id.service.ts +++ b/projects/common/id.service.ts @@ -16,6 +16,7 @@ export class IdService { video: 0, likert: 0, likert_row: 0, + slider: 0, 'radio-group-images': 0, 'drop-list': 0 }; diff --git a/projects/common/models/slider-element.ts b/projects/common/models/slider-element.ts new file mode 100644 index 000000000..ac1284674 --- /dev/null +++ b/projects/common/models/slider-element.ts @@ -0,0 +1,18 @@ +import { SurfaceUIElement } from '../interfaces/UIElementInterfaces'; +import { UIElement } from './uI-element'; +import { initSurfaceElement } from '../util/unit-interface-initializer'; + +export class SliderElement extends UIElement implements SurfaceUIElement { + label: string = 'Zahlenstrahl'; + minValue: number = 0; + maxValue: number = 100; + showLabel: boolean = true; + + backgroundColor: string = 'transparent'; + + constructor(serializedElement: UIElement) { + super(serializedElement); + Object.assign(this, serializedElement); + Object.assign(this, initSurfaceElement(serializedElement)); + } +} diff --git a/projects/common/models/uI-element.ts b/projects/common/models/uI-element.ts index 4296b50c0..328eb6133 100644 --- a/projects/common/models/uI-element.ts +++ b/projects/common/models/uI-element.ts @@ -3,7 +3,7 @@ import { IdService } from '../id.service'; import { LikertColumn, LikertRow } from '../interfaces/UIElementInterfaces'; export type UIElementType = 'text' | 'button' | 'text-field' | 'text-area' | 'checkbox' -| 'dropdown' | 'radio' | 'image' | 'audio' | 'video' | 'likert' | 'likert_row' | 'radio-group-images' | 'drop-list'; +| 'dropdown' | 'radio' | 'image' | 'audio' | 'video' | 'likert' | 'likert_row' | 'radio-group-images' | 'drop-list' | 'slider'; export type InputElementValue = string[] | string | number | boolean | null; export interface ValueChangeElement { diff --git a/projects/common/shared.module.ts b/projects/common/shared.module.ts index 630a28e88..a5c2d985c 100644 --- a/projects/common/shared.module.ts +++ b/projects/common/shared.module.ts @@ -32,6 +32,7 @@ import { RadioButtonGroupComponent } from './element-components/radio-button-gro import { ImageComponent } from './element-components/image.component'; import { VideoComponent } from './element-components/video.component'; import { AudioComponent } from './element-components/audio.component'; +import { SliderComponent } from './element-components/slider.component'; import { SafeResourceUrlPipe } from './element-components/pipes/safe-resource-url.pipe'; import { InputBackgroundColorDirective } from './element-components/directives/input-background-color.directive'; import { ErrorTransformPipe } from './element-components/pipes/error-transform.pipe'; @@ -43,6 +44,7 @@ import { LikertRadioButtonGroupComponent } from './element-components/compound-e import { Magnifier } from './element-components/magnifier.component'; import { RadioGroupImagesComponent } from './element-components/compound-elements/radio-group-images.component'; import { DropListComponent } from './element-components/compound-elements/drop-list.component'; +import { MAT_DATE_LOCALE } from '@angular/material/core'; @NgModule({ imports: [ @@ -70,6 +72,7 @@ import { DropListComponent } from './element-components/compound-elements/drop-l ImageComponent, AudioComponent, VideoComponent, + SliderComponent, RadioButtonGroupComponent, CheckboxComponent, DropdownComponent, @@ -110,6 +113,7 @@ import { DropListComponent } from './element-components/compound-elements/drop-l ImageComponent, AudioComponent, VideoComponent, + SliderComponent, RadioButtonGroupComponent, CheckboxComponent, DropdownComponent, @@ -118,6 +122,10 @@ import { DropListComponent } from './element-components/compound-elements/drop-l MatDialogModule, TranslateModule, SafeResourceHTMLPipe - ] + ], + providers: + [ + { provide: MAT_DATE_LOCALE, useValue: 'de-DE' } + ] }) export class SharedModule { } diff --git a/projects/common/util/element.factory.ts b/projects/common/util/element.factory.ts index 3cbafa044..8195801f6 100644 --- a/projects/common/util/element.factory.ts +++ b/projects/common/util/element.factory.ts @@ -27,6 +27,8 @@ import { RadioGroupImagesComponent } from '../element-components/compound-elemen import { RadioGroupImagesElement } from '../models/compound-elements/radio-group-images'; import { DropListComponent } from '../element-components/compound-elements/drop-list.component'; import { DropListElement } from '../models/compound-elements/drop-list'; +import { SliderElement } from '../models/slider-element'; +import {SliderComponent} from "../element-components/slider.component"; export function createElement(elementModel: UIElement): UIElement { let newElement: UIElement; @@ -70,6 +72,9 @@ export function createElement(elementModel: UIElement): UIElement { case 'drop-list': newElement = new DropListElement(elementModel); break; + case 'slider': + newElement = new SliderElement(elementModel); + break; default: throw new Error(`ElementType ${elementModel.type} not found!`); } @@ -108,6 +113,8 @@ export function getComponentFactory( return componentFactoryResolver.resolveComponentFactory(RadioGroupImagesComponent); case 'drop-list': return componentFactoryResolver.resolveComponentFactory(DropListComponent); + case 'slider': + return componentFactoryResolver.resolveComponentFactory(SliderComponent); default: throw new Error('unknown element'); } diff --git a/projects/editor/src/app/unit-view/page-view/new-ui-element-panel/ui-element-toolbox.component.html b/projects/editor/src/app/unit-view/page-view/new-ui-element-panel/ui-element-toolbox.component.html index ad0c9c393..4b0f29a76 100644 --- a/projects/editor/src/app/unit-view/page-view/new-ui-element-panel/ui-element-toolbox.component.html +++ b/projects/editor/src/app/unit-view/page-view/new-ui-element-panel/ui-element-toolbox.component.html @@ -64,6 +64,11 @@ <mat-icon>ondemand_video</mat-icon> Video </button> + <button mat-raised-button (click)="addUIElement('slider')" + draggable="true" (dragstart)="$event.dataTransfer?.setData('elementType','slider')"> + <mat-icon>spa</mat-icon> + Zahlenstrahl + </button> </div> </mat-tab> <mat-tab> diff --git a/projects/editor/src/app/unit-view/page-view/properties-panel/element-properties.component.html b/projects/editor/src/app/unit-view/page-view/properties-panel/element-properties.component.html index acdf682e7..76f3be521 100644 --- a/projects/editor/src/app/unit-view/page-view/properties-panel/element-properties.component.html +++ b/projects/editor/src/app/unit-view/page-view/properties-panel/element-properties.component.html @@ -212,6 +212,18 @@ [ngModel]="combinedProperties.minLength" (ngModelChange)="updateModel('minLength', $event, minLength.valid)"> </mat-form-field> + <mat-form-field *ngIf="combinedProperties.minValue !== undefined" appearance="fill"> + <mat-label>{{'propertiesPanel.minValue' | translate }}</mat-label> + <input matInput type="number" #minValue="ngModel" min="0" + [ngModel]="combinedProperties.minValue" + (ngModelChange)="updateModel('minValue', $event, minValue.valid)"> + </mat-form-field> + <mat-form-field *ngIf="combinedProperties.maxValue !== undefined" appearance="fill"> + <mat-label>{{'propertiesPanel.maxValue' | translate }}</mat-label> + <input matInput type="number" #maxValue="ngModel" min="0" + [ngModel]="combinedProperties.maxValue" + (ngModelChange)="updateModel('maxValue', $event, maxValue.valid)"> + </mat-form-field> <mat-form-field *ngIf="combinedProperties.minLength && $any(combinedProperties.minLength) > 0" appearance="fill"> @@ -425,6 +437,12 @@ {{'propertiesPanel.onlyOneItem' | translate }} </mat-checkbox> + <mat-checkbox *ngIf="combinedProperties.showLabel !== undefined" + [checked]="$any(combinedProperties.showLabel)" + (change)="updateModel('showLabel', $event.checked)"> + {{'propertiesPanel.showLabel' | translate }} + </mat-checkbox> + <mat-divider></mat-divider> <button mat-raised-button class="element-button" diff --git a/projects/editor/src/assets/i18n/de.json b/projects/editor/src/assets/i18n/de.json index 8fdcea97f..e66e36171 100644 --- a/projects/editor/src/assets/i18n/de.json +++ b/projects/editor/src/assets/i18n/de.json @@ -88,8 +88,11 @@ "false": "falsch", "appearance": "Aussehen", "minLength": "Minimallänge", + "minValue": "Minimalwert", "minLengthWarnMessage": "Minimalwert Warnmeldung", "maxLength": "Maximalwert", + "maxValue": "Maximalwert", + "showLabel": "Zeige Beschriftung", "maxLengthWarnMessage": "Maximalwert Warnmeldung", "pattern": "Muster", "patternWarnMessage": "Muster Warnmeldung", -- GitLab