diff --git a/web/src/app/administration/administration.module.ts b/web/src/app/administration/administration.module.ts index 7d4d0a011..1e7efc70f 100644 --- a/web/src/app/administration/administration.module.ts +++ b/web/src/app/administration/administration.module.ts @@ -46,6 +46,8 @@ import { MatDividerModule } from '@angular/material/divider'; import { MatListModule } from '@angular/material/list'; import { MatProgressBarModule } from '@angular/material/progress-bar'; import { MatToolbarModule } from '@angular/material/toolbar'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatRippleModule } from '@angular/material/core'; const MODULES = [ CommonModule, @@ -93,7 +95,9 @@ const DECLARATIONS = [ MatDividerModule, MatListModule, MatProgressBarModule, - MatToolbarModule + MatToolbarModule, + MatCheckboxModule, + MatRippleModule ], providers: [ ClassificationDefinitionService, diff --git a/web/src/app/administration/components/access-items-management/access-items-management.component.scss b/web/src/app/administration/components/access-items-management/access-items-management.component.scss index 2b73f1d72..8861452c7 100644 --- a/web/src/app/administration/components/access-items-management/access-items-management.component.scss +++ b/web/src/app/administration/components/access-items-management/access-items-management.component.scss @@ -14,11 +14,10 @@ color: $invalid; } -td { - &.has-changes { +.has-changes { border-bottom: 1px solid $brown; } -} + .table > thead > tr > th { max-width: 150px; border-bottom: none; diff --git a/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.html b/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.html index b48437461..fdc68ae2f 100644 --- a/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.html +++ b/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.html @@ -1,32 +1,16 @@ +
- - -
- +
- + @@ -44,71 +28,70 @@ - + - + + - + @@ -117,10 +100,9 @@ - - diff --git a/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.scss b/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.scss index 803dd9960..75702088f 100644 --- a/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.scss +++ b/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.scss @@ -3,17 +3,22 @@ .workbasket-access-items { max-width: calc(100vw - 500px); } + +.workbasket-access-items__typeahead { + text-align: left; + min-width: 180px; + width: calc(100% + 20px); +} td > input[type='checkbox'] { margin-top: 0; + display: block; } + .panel-body { overflow-x: auto; padding-top: 0; } -.text-width { - width: 100%; - min-width: 180px; -} + .required-header { width: 200px; } @@ -23,22 +28,54 @@ td > input[type='checkbox'] { } th { + padding: 0.25rem; position: sticky; top: 0; z-index: 3; background: white; } - -td { - vertical-align: bottom !important; - &.has-changes { - border-bottom: 1px solid #f0ad4e; - } +.workbasket-access-items__table { + margin-top: 20px; } -.table > thead > tr > th { +.workbasket-access-items__table thead th { + vertical-align: bottom; + border-bottom: 2px solid #dee2e6; +} + +.workbasket-access-items__table td, +.table th { + padding: 0.5rem; + vertical-align: middle; + border-top: 1px solid #dee2e6; +} + +.workbasket-access-items__table > thead > tr > th { max-width: 150px; border-bottom: none; } -taskana-shared-type-ahead { - top: 0; + +.workbasket-access-items__permission-checkbox { + display: inline-block; + height: 1rem; + line-height: 0; + margin: auto; + order: 0; + position: relative; + white-space: nowrap; + width: 1rem; + flex-shrink: 0; + cursor: pointer; + + @supports (-moz-appearance: none) { + //bigger checkboxes for firefox because firefox renders differently + width: 1.25rem; + height: 1.25rem; + } +} +input[type='checkbox']:checked { + filter: hue-rotate(320deg) brightness(1); +} + +.workbasket-access-items__add-access { + margin: 16px 0 16px 16px; } diff --git a/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.spec.ts b/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.spec.ts index 563b64b75..72064d157 100644 --- a/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.spec.ts +++ b/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.spec.ts @@ -33,6 +33,7 @@ import { import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { ACTION } from '../../../shared/models/action'; import { WorkbasketAccessItems } from '../../../shared/models/workbasket-access-items'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; @Component({ selector: 'taskana-shared-spinner', template: '' }) class SpinnerStub { @@ -88,7 +89,8 @@ describe('WorkbasketAccessItemsComponent', () => { NgxsModule.forRoot([WorkbasketState, EngineConfigurationState]), HttpClientTestingModule, RouterTestingModule.withRoutes([]), - BrowserAnimationsModule + BrowserAnimationsModule, + MatProgressBarModule ], declarations: [WorkbasketAccessItemsComponent, TypeAheadComponent, SpinnerStub], providers: [ @@ -120,7 +122,6 @@ describe('WorkbasketAccessItemsComponent', () => { workbasketAccessItems: workbasketAccessItemsMock } }); - fixture.detectChanges(); })); afterEach(async(() => { @@ -149,7 +150,8 @@ describe('WorkbasketAccessItemsComponent', () => { }); it('should add accessItems when add access item button is clicked', () => { - const addAccessItemButton = debugElement.nativeElement.querySelector('button.add-access-item'); + fixture.detectChanges(); + const addAccessItemButton = debugElement.nativeElement.querySelector('button.workbasket-access-items__add-access'); const clearSpy = jest.spyOn(component, 'addAccessItem'); expect(addAccessItemButton.title).toMatch('Add new access'); @@ -158,12 +160,14 @@ describe('WorkbasketAccessItemsComponent', () => { }); it('should undo changes when undo button is clicked', () => { + fixture.detectChanges(); const clearSpy = jest.spyOn(component, 'clear'); component.clear(); expect(clearSpy).toHaveBeenCalled(); }); it('should check all permissions when check all box is checked', () => { + fixture.detectChanges(); const checkAllSpy = jest.spyOn(component, 'checkAll'); const checkAllButton = debugElement.nativeElement.querySelector('#checkbox-0-00'); expect(checkAllButton).toBeTruthy(); diff --git a/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.ts b/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.ts index 532380127..73ae9ff18 100644 --- a/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.ts +++ b/web/src/app/administration/components/workbasket-access-items/workbasket-access-items.component.ts @@ -25,15 +25,18 @@ import { highlight } from 'app/shared/animations/validation.animation'; import { FormsValidatorService } from 'app/shared/services/forms-validator/forms-validator.service'; import { AccessIdDefinition } from 'app/shared/models/access-id'; import { EngineConfigurationSelectors } from 'app/shared/store/engine-configuration-store/engine-configuration.selectors'; -import { takeUntil } from 'rxjs/operators'; +import { filter, take, takeUntil } from 'rxjs/operators'; import { NOTIFICATION_TYPES } from '../../../shared/models/notifications'; import { NotificationService } from '../../../shared/services/notifications/notification.service'; import { AccessItemsCustomisation, CustomField, getCustomFields } from '../../../shared/models/customisation'; import { GetWorkbasketAccessItems, + OnButtonPressed, UpdateWorkbasketAccessItems } from '../../../shared/store/workbasket-store/workbasket.actions'; import { WorkbasketSelectors } from '../../../shared/store/workbasket-store/workbasket.selectors'; +import { WorkbasketComponent } from '../../models/workbasket-component'; +import { ButtonAction } from '../../models/button-action'; @Component({ selector: 'taskana-administration-workbasket-access-items', @@ -77,11 +80,17 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest @Select(WorkbasketSelectors.workbasketAccessItems) accessItemsRepresentation$: Observable; + @Select(WorkbasketSelectors.buttonAction) + buttonAction$: Observable; + + @Select(WorkbasketSelectors.selectedComponent) + selectedComponent$: Observable; + constructor( private savingWorkbaskets: SavingWorkbasketService, private requestInProgressService: RequestInProgressService, private formBuilder: FormBuilder, - private formsValidatorService: FormsValidatorService, + public formsValidatorService: FormsValidatorService, private notificationsService: NotificationService, private store: Store ) {} @@ -91,6 +100,7 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest } ngOnInit() { + this.init(); this.customFields$ = this.accessItemsCustomization$.pipe(getCustomFields(customFieldCount)); this.accessItemsRepresentation$.subscribe((accessItemsRepresentation) => { if (typeof accessItemsRepresentation !== 'undefined') { @@ -100,6 +110,27 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest this.accessItemsResetClone = this.cloneAccessItems(accessItemsRepresentation.accessItems); } }); + + this.buttonAction$ + .pipe(takeUntil(this.destroy$)) + .pipe(filter((buttonAction) => typeof buttonAction !== 'undefined')) + .subscribe((button) => { + this.selectedComponent$ + .pipe(take(1)) + .pipe(filter((component) => component === WorkbasketComponent.ACCESS_ITEMS)) + .subscribe((component) => { + switch (button) { + case ButtonAction.SAVE: + this.onSubmit(); + break; + case ButtonAction.UNDO: + this.clear(); + break; + default: + break; + } + }); + }); } ngAfterViewInit() { @@ -195,6 +226,7 @@ export class WorkbasketAccessItemsComponent implements OnInit, OnChanges, OnDest } clear() { + this.store.dispatch(new OnButtonPressed(undefined)); this.formsValidatorService.formSubmitAttempt = false; this.AccessItemsForm.reset(); this.setAccessItemsGroups(this.accessItemsResetClone); diff --git a/web/src/app/shared/components/nav-bar/nav-bar.component.html b/web/src/app/shared/components/nav-bar/nav-bar.component.html index 0bb8fc43f..6679b2c25 100644 --- a/web/src/app/shared/components/nav-bar/nav-bar.component.html +++ b/web/src/app/shared/components/nav-bar/nav-bar.component.html @@ -6,6 +6,6 @@ diff --git a/web/src/app/shared/store/workbasket-store/workbasket.state.ts b/web/src/app/shared/store/workbasket-store/workbasket.state.ts index 5b05c31a3..46a4dca24 100644 --- a/web/src/app/shared/store/workbasket-store/workbasket.state.ts +++ b/web/src/app/shared/store/workbasket-store/workbasket.state.ts @@ -262,6 +262,7 @@ export class WorkbasketState implements NgxsAfterBootstrap { ctx: StateContext, action: UpdateWorkbasketAccessItems ): Observable { + ctx.dispatch(new OnButtonPressed(undefined)); return this.workbasketService.updateWorkBasketAccessItem(action.url, action.workbasketAccessItems).pipe( take(1), tap(
AccessIDAccessID Select all Read Open
- - + + + + -
- +
+
+
- - - - - + - - + - - + - - + - - + - - +