From 0d52aaaa450fcaad17b4d94f0e0c2b46db1bf949 Mon Sep 17 00:00:00 2001 From: GabrielMeyer Date: Thu, 4 Jul 2019 14:37:36 +0200 Subject: [PATCH] Separates the field of state and recommendation - New component for similar situations - Prevents overwriting and discarding of changes, if an 'autoupdate' is triggered --- .../extension-field.component.html | 54 ++++++ .../extension-field.component.scss | 3 + .../extension-field.component.spec.ts | 25 +++ .../extension-field.component.ts | 177 ++++++++++++++++++ .../icon-container.component.html | 12 +- .../icon-container.component.ts | 27 ++- .../search-value-selector.component.html | 2 +- .../search-value-selector.component.ts | 9 + client/src/app/shared/shared.module.ts | 7 +- .../motion-detail.component.html | 135 ++++++------- .../motion-detail/motion-detail.component.ts | 41 +--- 11 files changed, 374 insertions(+), 118 deletions(-) create mode 100644 client/src/app/shared/components/extension-field/extension-field.component.html create mode 100644 client/src/app/shared/components/extension-field/extension-field.component.scss create mode 100644 client/src/app/shared/components/extension-field/extension-field.component.spec.ts create mode 100644 client/src/app/shared/components/extension-field/extension-field.component.ts diff --git a/client/src/app/shared/components/extension-field/extension-field.component.html b/client/src/app/shared/components/extension-field/extension-field.component.html new file mode 100644 index 000000000..c4bd6b7a7 --- /dev/null +++ b/client/src/app/shared/components/extension-field/extension-field.component.html @@ -0,0 +1,54 @@ + +
+

{{ title }}

+ + + + + + + {{ chipValue || '–' }} + + + {{ chipValue }} + + +
+ + +
+ + + + + + + +
+ + + + + diff --git a/client/src/app/shared/components/extension-field/extension-field.component.scss b/client/src/app/shared/components/extension-field/extension-field.component.scss new file mode 100644 index 000000000..df6f5afe9 --- /dev/null +++ b/client/src/app/shared/components/extension-field/extension-field.component.scss @@ -0,0 +1,3 @@ +.extension-container .mat-form-field { + display: block; +} diff --git a/client/src/app/shared/components/extension-field/extension-field.component.spec.ts b/client/src/app/shared/components/extension-field/extension-field.component.spec.ts new file mode 100644 index 000000000..5294e9f8d --- /dev/null +++ b/client/src/app/shared/components/extension-field/extension-field.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ExtensionFieldComponent } from './extension-field.component'; +import { E2EImportsModule } from 'e2e-imports.module'; + +describe('ExtensionFieldComponent', () => { + let component: ExtensionFieldComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [E2EImportsModule] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ExtensionFieldComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/client/src/app/shared/components/extension-field/extension-field.component.ts b/client/src/app/shared/components/extension-field/extension-field.component.ts new file mode 100644 index 000000000..5dc5231c0 --- /dev/null +++ b/client/src/app/shared/components/extension-field/extension-field.component.ts @@ -0,0 +1,177 @@ +import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; +import { FormGroup, FormBuilder } from '@angular/forms'; + +@Component({ + selector: 'os-extension-field', + templateUrl: './extension-field.component.html', + styleUrls: ['./extension-field.component.scss'] +}) +export class ExtensionFieldComponent implements OnInit { + /** + * Optional additional classes for the `mat-chip`. + */ + @Input() + public classes: string | string[] | object = 'bluegrey'; + + /** + * Title for this component. + */ + @Input() + public title: string; + + /** + * Value of the chip. + */ + @Input() + public chipValue: string; + + /** + * Boolean, whether the extension should be shown. + */ + @Input() + public hasExtension = false; + + /** + * Optional label for the input. + */ + @Input() + public extensionLabel: string; + + /** + * Optional label for the search-list. + */ + @Input() + public searchListLabel: string; + + /** + * BehaviourSubject for the search-list. + */ + @Input() + public searchList: BehaviorSubject; + + /** + * Boolean, whether the input and the search-list can be changed. + */ + @Input() + public canBeEdited = true; + + /** + * Boolean, whether the list should fire events, if it changes. + */ + @Input() + public listSubmitOnChange = false; + + /** + * Boolean, whether to append the value from list to the input. + */ + @Input() + public appendValueToInput = true; + + /** + * Prefix, if the value from list should be appended to the input. + */ + @Input() + public listValuePrefix = ''; + + /** + * Suffix, if the value from list should be appended to the input. + */ + @Input() + public listValueSuffix = ''; + + /** + * Initial value of the input-field. + */ + @Input() + public inputValue: string; + + /** + * EventEmitter, when clicking on the 'save'-button. + */ + @Output() + public success: EventEmitter = new EventEmitter(); + + /** + * EventEmitter, if the list has changed. + */ + @Output() + public listChange: EventEmitter = new EventEmitter(); + + /** + * Model for the input-field. + */ + public inputControl = ''; + + /** + * FormGroup for the search-list. + */ + public extensionFieldForm: FormGroup; + + /** + * Boolean to decide, whether to open the extension-input and search-list. + */ + public editMode = false; + + /** + * Constructor + * + * @param fb The FormBuilder + */ + public constructor(private fb: FormBuilder) {} + + /** + * OnInit-method. + */ + public ngOnInit(): void { + this.initInput(); + this.extensionFieldForm = this.fb.group({ + list: this.searchList ? [[]] : undefined + }); + + this.extensionFieldForm.get('list').valueChanges.subscribe((value: number) => { + if (this.listSubmitOnChange) { + this.listChange.emit(value); + } + if (this.appendValueToInput) { + this.inputControl = this.inputControl.concat( + `[${this.listValuePrefix}${value}${this.listValueSuffix}]` + ); + } + }); + } + + /** + * Function to switch to or from editing-mode. + * + * @param save Boolean, whether the changes should be saved or resetted. + */ + public changeEditMode(save: boolean = false): void { + if (save) { + this.sendSuccess(); + } else { + this.initInput(); + } + this.editMode = !this.editMode; + } + + /** + * Initialize the value of the input. + */ + public initInput(): void { + this.inputControl = this.inputValue; + } + + /** + * Function to execute, when the values are saved. + */ + public sendSuccess(): void { + if (this.success) { + const submitMessage = + this.listSubmitOnChange || this.appendValueToInput || !this.searchList + ? this.inputControl + : { extensionInput: this.inputControl, extensionList: this.extensionFieldForm.get('list').value }; + this.success.emit(submitMessage); + } + } +} diff --git a/client/src/app/shared/components/icon-container/icon-container.component.html b/client/src/app/shared/components/icon-container/icon-container.component.html index df76ef155..49ba6a089 100644 --- a/client/src/app/shared/components/icon-container/icon-container.component.html +++ b/client/src/app/shared/components/icon-container/icon-container.component.html @@ -1,5 +1,13 @@ -{{ icon }} +{{ icon }} -{{ icon }} +{{ icon }} diff --git a/client/src/app/shared/components/icon-container/icon-container.component.ts b/client/src/app/shared/components/icon-container/icon-container.component.ts index 36bf635e2..3dc68d5d6 100644 --- a/client/src/app/shared/components/icon-container/icon-container.component.ts +++ b/client/src/app/shared/components/icon-container/icon-container.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, HostBinding } from '@angular/core'; +import { Component, Input, HostBinding, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'os-icon-container', @@ -37,4 +37,29 @@ export class IconContainerComponent { */ @Input() public swap = false; + + /** + * Boolean to decide, when to show the icon. + */ + @Input() + public showIcon = true; + + /** + * Optional string as tooltip for icon. + */ + @Input() + public iconTooltip: string; + + /** + * Optional action for clicking on the icon. + */ + @Output() + public iconAction: EventEmitter = new EventEmitter(); + + /** + * Function executed, when the icon is clicked. + */ + public iconClick(): void { + this.iconAction.emit(); + } } diff --git a/client/src/app/shared/components/search-value-selector/search-value-selector.component.html b/client/src/app/shared/components/search-value-selector/search-value-selector.component.html index 75c053d96..778fcd963 100644 --- a/client/src/app/shared/components/search-value-selector/search-value-selector.component.html +++ b/client/src/app/shared/components/search-value-selector/search-value-selector.component.html @@ -1,4 +1,4 @@ - +
diff --git a/client/src/app/shared/components/search-value-selector/search-value-selector.component.ts b/client/src/app/shared/components/search-value-selector/search-value-selector.component.ts index aee8f82ab..7c1291d57 100644 --- a/client/src/app/shared/components/search-value-selector/search-value-selector.component.ts +++ b/client/src/app/shared/components/search-value-selector/search-value-selector.component.ts @@ -76,12 +76,21 @@ export class SearchValueSelectorComponent implements OnInit, OnDestroy { @Input() public includeNone = false; + /** + * Boolean, whether the component should be rendered with full width. + */ + @Input() + public fullWidth = false; + /** * The inputlist subject. Subscribes to it and updates the selector, if the subject * changes its values. */ @Input() public set InputListValues(value: BehaviorSubject) { + if (!value) { + return; + } // unsubscribe to old subscription. if (this._inputListSubscription) { this._inputListSubscription.unsubscribe(); diff --git a/client/src/app/shared/shared.module.ts b/client/src/app/shared/shared.module.ts index 3b1944916..0cbbf0c8d 100644 --- a/client/src/app/shared/shared.module.ts +++ b/client/src/app/shared/shared.module.ts @@ -91,6 +91,7 @@ import { BlockTileComponent } from './components/block-tile/block-tile.component import { IconContainerComponent } from './components/icon-container/icon-container.component'; import { ListViewTableComponent } from './components/list-view-table/list-view-table.component'; import { AgendaContentObjectFormComponent } from './components/agenda-content-object-form/agenda-content-object-form.component'; +import { ExtensionFieldComponent } from './components/extension-field/extension-field.component'; /** * Share Module for all "dumb" components and pipes. @@ -224,7 +225,8 @@ import { AgendaContentObjectFormComponent } from './components/agenda-content-ob PblNgridModule, PblNgridMaterialModule, ListViewTableComponent, - AgendaContentObjectFormComponent + AgendaContentObjectFormComponent, + ExtensionFieldComponent ], declarations: [ PermsDirective, @@ -259,7 +261,8 @@ import { AgendaContentObjectFormComponent } from './components/agenda-content-ob BlockTileComponent, IconContainerComponent, ListViewTableComponent, - AgendaContentObjectFormComponent + AgendaContentObjectFormComponent, + ExtensionFieldComponent ], providers: [ { provide: DateAdapter, useClass: OpenSlidesDateAdapter }, diff --git a/client/src/app/site/motions/modules/motion-detail/components/motion-detail/motion-detail.component.html b/client/src/app/site/motions/modules/motion-detail/components/motion-detail/motion-detail.component.html index a218c07db..75d9fe0a0 100644 --- a/client/src/app/site/motions/modules/motion-detail/components/motion-detail/motion-detail.component.html +++ b/client/src/app/site/motions/modules/motion-detail/components/motion-detail/motion-detail.component.html @@ -242,92 +242,65 @@
-

State

- - -
- - - -
-
-
- - {{ stateLabel }} - -
- - - - -
-
-
- {{ stateLabel }} -
+
+ + + +
+ +
-

{{ recommender }}

- - - - - -
- - {{ recommendationLabel || '–' }} - -
-
- - - - - -
-
-
-
- {{ recommendationLabel }} -
+ + + + + + + +