diff --git a/src-ui/cypress/e2e/settings/settings.cy.ts b/src-ui/cypress/e2e/settings/settings.cy.ts index 95443bbe2..259f15403 100644 --- a/src-ui/cypress/e2e/settings/settings.cy.ts +++ b/src-ui/cypress/e2e/settings/settings.cy.ts @@ -115,7 +115,7 @@ describe('settings', () => { cy.contains('a', 'Dashboard').click() cy.contains('You have unsaved changes') cy.contains('button', 'Cancel').click() - cy.contains('button', 'Save').click().wait('@savedViews').wait(2000) + cy.contains('button', 'Save').click().wait(2000) cy.contains('a', 'Dashboard').click() cy.contains('You have unsaved changes').should('not.exist') }) diff --git a/src-ui/src/app/components/common/permissions-select/permissions-select.component.html b/src-ui/src/app/components/common/permissions-select/permissions-select.component.html index 1907f4e3f..f3e85a543 100644 --- a/src-ui/src/app/components/common/permissions-select/permissions-select.component.html +++ b/src-ui/src/app/components/common/permissions-select/permissions-select.component.html @@ -18,7 +18,7 @@ </div> <div *ngFor="let action of PermissionAction | keyvalue" class="col form-check form-check-inline" [ngbPopover]="inheritedWarning" [disablePopover]="!isInherited(type.key, action.key)" placement="left" triggers="mouseenter:mouseleave"> - <input type="checkbox" class="form-check-input" id="{{type.key}}_{{action.key}}" formControlName="{{action.key}}" [attr.disabled]="isDisabled(type.key, action.key)"> + <input type="checkbox" class="form-check-input" id="{{type.key}}_{{action.key}}" formControlName="{{action.key}}"> <label class="form-check-label visually-hidden" for="{{type.key}}_{{action.key}}" i18n>{{action.key}}</label> </div> </li> diff --git a/src-ui/src/app/components/common/permissions-select/permissions-select.component.ts b/src-ui/src/app/components/common/permissions-select/permissions-select.component.ts index 74e8a73c4..4b968f6e5 100644 --- a/src-ui/src/app/components/common/permissions-select/permissions-select.component.ts +++ b/src-ui/src/app/components/common/permissions-select/permissions-select.component.ts @@ -1,5 +1,6 @@ import { Component, forwardRef, Input, OnInit } from '@angular/core' import { + AbstractControl, ControlValueAccessor, FormControl, FormGroup, @@ -54,6 +55,8 @@ export class PermissionsSelectComponent this._inheritedPermissions = newInheritedPermissions this.writeValue(this.permissions) // updates visual checks etc. } + + this.updateDisabledStates() } inheritedWarning: string = $localize`Inerhited from group` @@ -69,6 +72,10 @@ export class PermissionsSelectComponent } writeValue(permissions: string[]): void { + if (this.permissions === permissions) { + return + } + this.permissions = permissions ?? [] const allPerms = this._inheritedPermissions.concat(this.permissions) @@ -94,6 +101,8 @@ export class PermissionsSelectComponent this.typesWithAllActions.delete(type) } }) + + this.updateDisabledStates() } onChange = (newValue: string[]) => {} @@ -138,7 +147,10 @@ export class PermissionsSelectComponent this.typesWithAllActions.delete(typeKey) } }) - this.onChange(permissions) + + this.onChange( + permissions.filter((p) => !this._inheritedPermissions.includes(p)) + ) }) } @@ -178,12 +190,16 @@ export class PermissionsSelectComponent } } - // if checkbox is disabled either because "All", inhereted or entire component disabled - isDisabled(typeKey: string, actionKey: string) { - return this.typesWithAllActions.has(typeKey) || - this.isInherited(typeKey, actionKey) || - this.disabled - ? true - : null + updateDisabledStates() { + for (const type in PermissionType) { + const control = this.form.get(type) + let actionControl: AbstractControl + for (const action in PermissionAction) { + actionControl = control.get(action) + this.isInherited(type, action) || this.disabled + ? actionControl.disable() + : actionControl.enable() + } + } } } diff --git a/src-ui/src/app/components/dashboard/dashboard.component.ts b/src-ui/src/app/components/dashboard/dashboard.component.ts index f2eddae37..271e2cf14 100644 --- a/src-ui/src/app/components/dashboard/dashboard.component.ts +++ b/src-ui/src/app/components/dashboard/dashboard.component.ts @@ -1,4 +1,9 @@ import { Component } from '@angular/core' +import { + PermissionAction, + PermissionsService, + PermissionType, +} from 'src/app/services/permissions.service' import { SavedViewService } from 'src/app/services/rest/saved-view.service' import { SettingsService } from 'src/app/services/settings.service' import { ComponentWithPermissions } from '../with-permissions/with-permissions.component' @@ -10,10 +15,20 @@ import { ComponentWithPermissions } from '../with-permissions/with-permissions.c }) export class DashboardComponent extends ComponentWithPermissions { constructor( - public savedViewService: SavedViewService, - public settingsService: SettingsService + public settingsService: SettingsService, + private permissionsService: PermissionsService, + public savedViewService: SavedViewService ) { super() + + if ( + permissionsService.currentUserCan( + PermissionAction.View, + PermissionType.SavedView + ) + ) { + savedViewService.initialize() + } } get subtitle() { diff --git a/src-ui/src/app/services/rest/saved-view.service.ts b/src-ui/src/app/services/rest/saved-view.service.ts index 46df5e72c..307eaae10 100644 --- a/src-ui/src/app/services/rest/saved-view.service.ts +++ b/src-ui/src/app/services/rest/saved-view.service.ts @@ -3,6 +3,7 @@ import { Injectable } from '@angular/core' import { combineLatest, Observable } from 'rxjs' import { tap } from 'rxjs/operators' import { PaperlessSavedView } from 'src/app/data/paperless-saved-view' +import { PermissionsService } from '../permissions.service' import { AbstractPaperlessService } from './abstract-paperless-service' @Injectable({ @@ -11,8 +12,11 @@ import { AbstractPaperlessService } from './abstract-paperless-service' export class SavedViewService extends AbstractPaperlessService<PaperlessSavedView> { loading: boolean - constructor(http: HttpClient) { + constructor(http: HttpClient, permissionService: PermissionsService) { super(http, 'saved_views') + } + + public initialize() { this.reload() }