diff --git a/package-lock.json b/package-lock.json index 881bbd7d22250d24f4cdf5c3671970fb53146521..711c57e8c015386373841d584435c95ecfbba301 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 0000000000000000000000000000000000000000..a917c3671f3ccbde99bdb8ee86794b439a8016e7 --- /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 1ac383e16c8a501315dbffcac493df7a1a350704..b4e9977011e553d38383d944d722661e22e46046 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 0000000000000000000000000000000000000000..ac128467487edd229525686d5b2008b740baa398 --- /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 4296b50c0e8da638520587eb3dbfa3d8ffa43902..328eb61334851b3339e983dc75751e7f8559065d 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 630a28e88f58c10814c5771287add33fb491b326..a5c2d985c0f25b2337ff73153bd024186c663a62 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 3cbafa0441db23d4c6b0346e7798982431227704..8195801f66ea8ef64d3ae62f7cd3eb2bce01fcf1 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 ad0c9c3932fe8faeccd531fc1790a35033699011..4b0f29a76453f434a63ba9dd1c14818171c386fd 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 acdf682e7d25684cc37e9c6d467b25eb3b658a82..76f3be521518a1053c08c4355da3aaa9d5c36fb5 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 8fdcea97f4f175ff4297f9e3090d8a40ff9e1f74..e66e36171e677b68b6c8ba4432b49a04d6a15b98 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",