mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-09 09:58:20 -05:00
disable document form components when no object permissions
This commit is contained in:
parent
d15c701510
commit
8b204cac99
@ -106,6 +106,7 @@ import localeTr from '@angular/common/locales/tr'
|
|||||||
import localeZh from '@angular/common/locales/zh'
|
import localeZh from '@angular/common/locales/zh'
|
||||||
import { ShareUserComponent } from './components/common/input/share-user/share-user.component'
|
import { ShareUserComponent } from './components/common/input/share-user/share-user.component'
|
||||||
import { IfOwnerDirective } from './directives/if-owner.directive'
|
import { IfOwnerDirective } from './directives/if-owner.directive'
|
||||||
|
import { IfObjectPermissionsDirective } from './directives/if-object-permissions.directive'
|
||||||
|
|
||||||
registerLocaleData(localeBe)
|
registerLocaleData(localeBe)
|
||||||
registerLocaleData(localeCs)
|
registerLocaleData(localeCs)
|
||||||
@ -199,6 +200,7 @@ function initializeApp(settings: SettingsService) {
|
|||||||
MailRuleEditDialogComponent,
|
MailRuleEditDialogComponent,
|
||||||
ShareUserComponent,
|
ShareUserComponent,
|
||||||
IfOwnerDirective,
|
IfOwnerDirective,
|
||||||
|
IfObjectPermissionsDirective,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<app-input-text *ngIf="patternRequired" i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></app-input-text>
|
<app-input-text *ngIf="patternRequired" i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></app-input-text>
|
||||||
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive" novalidate></app-input-check>
|
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive" novalidate></app-input-check>
|
||||||
|
|
||||||
<div *ifOwner="object.owner">
|
<div *ifOwner="object?.owner">
|
||||||
<h5 i18n>Permissions</h5>
|
<h5 i18n>Permissions</h5>
|
||||||
<div formGroupName="set_permissions">
|
<div formGroupName="set_permissions">
|
||||||
<app-share-user type="view" formControlName="view"></app-share-user>
|
<app-share-user type="view" formControlName="view"></app-share-user>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<app-input-text *ngIf="patternRequired" i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></app-input-text>
|
<app-input-text *ngIf="patternRequired" i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></app-input-text>
|
||||||
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive"></app-input-check>
|
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive"></app-input-check>
|
||||||
|
|
||||||
<div *ifOwner="object.owner">
|
<div *ifOwner="object?.owner">
|
||||||
<h5 i18n>Permissions</h5>
|
<h5 i18n>Permissions</h5>
|
||||||
<div formGroupName="set_permissions">
|
<div formGroupName="set_permissions">
|
||||||
<app-share-user type="view" formControlName="view"></app-share-user>
|
<app-share-user type="view" formControlName="view"></app-share-user>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<app-input-text *ngIf="patternRequired" i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></app-input-text>
|
<app-input-text *ngIf="patternRequired" i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></app-input-text>
|
||||||
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive"></app-input-check>
|
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive"></app-input-check>
|
||||||
|
|
||||||
<div *ifOwner="object.owner">
|
<div *ifOwner="object?.owner">
|
||||||
<h5 i18n>Permissions</h5>
|
<h5 i18n>Permissions</h5>
|
||||||
<div formGroupName="set_permissions">
|
<div formGroupName="set_permissions">
|
||||||
<app-share-user type="view" formControlName="view"></app-share-user>
|
<app-share-user type="view" formControlName="view"></app-share-user>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<app-input-text *ngIf="patternRequired" i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></app-input-text>
|
<app-input-text *ngIf="patternRequired" i18n-title title="Matching pattern" formControlName="match" [error]="error?.match"></app-input-text>
|
||||||
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive"></app-input-check>
|
<app-input-check *ngIf="patternRequired" i18n-title title="Case insensitive" formControlName="is_insensitive"></app-input-check>
|
||||||
|
|
||||||
<div *ifOwner="object.owner">
|
<div *ifOwner="object?.owner">
|
||||||
<h5 i18n>Permissions</h5>
|
<h5 i18n>Permissions</h5>
|
||||||
<div formGroupName="set_permissions">
|
<div formGroupName="set_permissions">
|
||||||
<app-share-user type="view" formControlName="view"></app-share-user>
|
<app-share-user type="view" formControlName="view"></app-share-user>
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
<div class="input-group" [class.is-invalid]="error">
|
<div class="input-group" [class.is-invalid]="error">
|
||||||
<input class="form-control" [class.is-invalid]="error" [placeholder]="placeholder" [id]="inputId" maxlength="10"
|
<input class="form-control" [class.is-invalid]="error" [placeholder]="placeholder" [id]="inputId" maxlength="10"
|
||||||
(dateSelect)="onChange(value)" (change)="onChange(value)" (keypress)="onKeyPress($event)" (paste)="onPaste($event)"
|
(dateSelect)="onChange(value)" (change)="onChange(value)" (keypress)="onKeyPress($event)" (paste)="onPaste($event)"
|
||||||
name="dp" [(ngModel)]="value" ngbDatepicker #datePicker="ngbDatepicker" #datePickerContent="ngModel">
|
name="dp" [(ngModel)]="value" ngbDatepicker #datePicker="ngbDatepicker" #datePickerContent="ngModel" [disabled]="disabled">
|
||||||
<button class="btn btn-outline-secondary calendar" (click)="datePicker.toggle()" type="button">
|
<button class="btn btn-outline-secondary calendar" (click)="datePicker.toggle()" type="button" [disabled]="disabled">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-calendar" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-calendar" viewBox="0 0 16 16">
|
||||||
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/>
|
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label" [for]="inputId">{{title}}</label>
|
<label class="form-label" [for]="inputId">{{title}}</label>
|
||||||
<div class="input-group" [class.is-invalid]="error">
|
<div class="input-group" [class.is-invalid]="error">
|
||||||
<input type="number" class="form-control" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [class.is-invalid]="error">
|
<input type="number" class="form-control" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [class.is-invalid]="error" [disabled]="disabled">
|
||||||
<button *ngIf="showAdd" class="btn btn-outline-secondary" type="button" id="button-addon1" (click)="nextAsn()" [disabled]="value">+1</button>
|
<button *ngIf="showAdd" class="btn btn-outline-secondary" type="button" id="button-addon1" (click)="nextAsn()" [disabled]="disabled">+1</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
{{error}}
|
{{error}}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
(clear)="clearLastSearchTerm()"
|
(clear)="clearLastSearchTerm()"
|
||||||
(blur)="onBlur()">
|
(blur)="onBlur()">
|
||||||
</ng-select>
|
</ng-select>
|
||||||
<button *ngIf="allowCreateNew" class="btn btn-outline-secondary" type="button" (click)="addItem()">
|
<button *ngIf="allowCreateNew" class="btn btn-outline-secondary" type="button" (click)="addItem()" [disabled]="disabled">
|
||||||
<svg class="buttonicon" fill="currentColor">
|
<svg class="buttonicon" fill="currentColor">
|
||||||
<use xlink:href="assets/bootstrap-icons.svg#plus" />
|
<use xlink:href="assets/bootstrap-icons.svg#plus" />
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
<div class="input-group flex-nowrap">
|
<div class="input-group flex-nowrap">
|
||||||
<ng-select name="tags" [items]="tags" bindLabel="name" bindValue="id" [(ngModel)]="value"
|
<ng-select name="tags" [items]="tags" bindLabel="name" bindValue="id" [(ngModel)]="value"
|
||||||
|
[disabled]="disabled"
|
||||||
[multiple]="true"
|
[multiple]="true"
|
||||||
[closeOnSelect]="false"
|
[closeOnSelect]="false"
|
||||||
[clearSearchOnAdd]="true"
|
[clearSearchOnAdd]="true"
|
||||||
@ -31,7 +32,7 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
</ng-select>
|
</ng-select>
|
||||||
|
|
||||||
<button *ngIf="allowCreate" class="btn btn-outline-secondary" type="button" (click)="createTag()">
|
<button *ngIf="allowCreate" class="btn btn-outline-secondary" type="button" (click)="createTag()" [disabled]="disabled">
|
||||||
<svg class="buttonicon" fill="currentColor">
|
<svg class="buttonicon" fill="currentColor">
|
||||||
<use xlink:href="assets/bootstrap-icons.svg#plus" />
|
<use xlink:href="assets/bootstrap-icons.svg#plus" />
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -74,6 +74,7 @@ export class TagsComponent implements OnInit, ControlValueAccessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeTag(id) {
|
removeTag(id) {
|
||||||
|
if (this.disabled) return
|
||||||
let index = this.value.indexOf(id)
|
let index = this.value.indexOf(id)
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
let oldValue = this.value
|
let oldValue = this.value
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label" [for]="inputId">{{title}}</label>
|
<label class="form-label" [for]="inputId">{{title}}</label>
|
||||||
<input #inputField type="text" class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)">
|
<input #inputField type="text" class="form-control" [class.is-invalid]="error" [id]="inputId" [(ngModel)]="value" (change)="onChange(value)" [disabled]="disabled">
|
||||||
<small *ngIf="hint" class="form-text text-muted" [innerHTML]="hint | safeHtml"></small>
|
<small *ngIf="hint" class="form-text text-muted" [innerHTML]="hint | safeHtml"></small>
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
{{error}}
|
{{error}}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<div class="input-group-text" i18n>of {{previewNumPages}}</div>
|
<div class="input-group-text" i18n>of {{previewNumPages}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="button" class="btn btn-sm btn-outline-danger me-2 ms-auto" (click)="delete()" *ifPermissions="{ action: PermissionAction.Delete, type: PermissionType.Document }">
|
<button *ifOwner="document?.owner" type="button" class="btn btn-sm btn-outline-danger me-2 ms-auto" (click)="delete()">
|
||||||
<svg class="buttonicon" fill="currentColor">
|
<svg class="buttonicon" fill="currentColor">
|
||||||
<use xlink:href="assets/bootstrap-icons.svg#trash" />
|
<use xlink:href="assets/bootstrap-icons.svg#trash" />
|
||||||
</svg><span class="d-none d-lg-inline ps-1" i18n>Delete</span>
|
</svg><span class="d-none d-lg-inline ps-1" i18n>Delete</span>
|
||||||
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="button" class="btn btn-sm btn-outline-primary me-2" (click)="redoOcr()">
|
<button *ifOwner="document?.owner" type="button" class="btn btn-sm btn-outline-primary me-2" (click)="redoOcr()">
|
||||||
<svg class="buttonicon" fill="currentColor">
|
<svg class="buttonicon" fill="currentColor">
|
||||||
<use xlink:href="assets/bootstrap-icons.svg#arrow-counterclockwise" />
|
<use xlink:href="assets/bootstrap-icons.svg#arrow-counterclockwise" />
|
||||||
</svg><span class="d-none d-lg-inline ps-1" i18n>Redo OCR</span>
|
</svg><span class="d-none d-lg-inline ps-1" i18n>Redo OCR</span>
|
||||||
@ -191,9 +191,11 @@
|
|||||||
|
|
||||||
<div [ngbNavOutlet]="nav" class="mt-2"></div>
|
<div [ngbNavOutlet]="nav" class="mt-2"></div>
|
||||||
|
|
||||||
<button type="button" class="btn btn-outline-secondary" (click)="discard()" i18n [disabled]="networkActive || !(isDirty$ | async)">Discard</button>
|
<ng-container action="PermissionAction.Change" *ifObjectPermissions="document">
|
||||||
<button type="button" class="btn btn-outline-primary" (click)="saveEditNext()" *ngIf="hasNext()" i18n [disabled]="networkActive || !(isDirty$ | async) || error">Save & next</button>
|
<button type="button" class="btn btn-outline-secondary" (click)="discard()" i18n [disabled]="networkActive || !(isDirty$ | async)">Discard</button>
|
||||||
<button type="submit" class="btn btn-primary" *ifPermissions="{ action: PermissionAction.Change, type: PermissionType.Document }" i18n [disabled]="networkActive || !(isDirty$ | async) || error">Save</button>
|
<button type="button" class="btn btn-outline-primary" (click)="saveEditNext()" *ngIf="hasNext()" i18n [disabled]="networkActive || !(isDirty$ | async) || error">Save & next</button>
|
||||||
|
<button type="submit" class="btn btn-primary" *ifPermissions="{ action: PermissionAction.Change, type: PermissionType.Document }" i18n [disabled]="networkActive || !(isDirty$ | async) || error">Save</button>
|
||||||
|
</ng-container>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -306,6 +306,7 @@ export class DocumentDetailComponent
|
|||||||
.map((p) => p[0]),
|
.map((p) => p[0]),
|
||||||
}
|
}
|
||||||
this.documentForm.patchValue(doc)
|
this.documentForm.patchValue(doc)
|
||||||
|
if (!this.userCanEdit) this.documentForm.disable()
|
||||||
}
|
}
|
||||||
|
|
||||||
createDocumentType(newName: string) {
|
createDocumentType(newName: string) {
|
||||||
@ -591,4 +592,14 @@ export class DocumentDetailComponent
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get userCanEdit(): boolean {
|
||||||
|
return (
|
||||||
|
!this.document ||
|
||||||
|
this.permissionsService.currentUserHasObjectPermissions(
|
||||||
|
PermissionAction.Change,
|
||||||
|
this.document
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
54
src-ui/src/app/directives/if-object-permissions.directive.ts
Normal file
54
src-ui/src/app/directives/if-object-permissions.directive.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import {
|
||||||
|
Directive,
|
||||||
|
Input,
|
||||||
|
OnChanges,
|
||||||
|
OnInit,
|
||||||
|
TemplateRef,
|
||||||
|
ViewContainerRef,
|
||||||
|
} from '@angular/core'
|
||||||
|
import { ObjectWithPermissions } from '../data/object-with-permissions'
|
||||||
|
import {
|
||||||
|
PermissionAction,
|
||||||
|
PermissionsService,
|
||||||
|
} from '../services/permissions.service'
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[ifObjectPermissions]',
|
||||||
|
})
|
||||||
|
export class IfObjectPermissionsDirective implements OnInit, OnChanges {
|
||||||
|
// The role the user must have
|
||||||
|
@Input()
|
||||||
|
ifObjectPermissions: ObjectWithPermissions
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
action: PermissionAction
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ViewContainerRef} viewContainerRef -- The location where we need to render the templateRef
|
||||||
|
* @param {TemplateRef<any>} templateRef -- The templateRef to be potentially rendered
|
||||||
|
* @param {PermissionsService} permissionsService -- Will give us access to the permissions a user has
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
private viewContainerRef: ViewContainerRef,
|
||||||
|
private templateRef: TemplateRef<any>,
|
||||||
|
private permissionsService: PermissionsService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public ngOnInit(): void {
|
||||||
|
if (
|
||||||
|
!this.ifObjectPermissions ||
|
||||||
|
this.permissionsService.currentUserHasObjectPermissions(
|
||||||
|
this.action,
|
||||||
|
this.ifObjectPermissions
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
this.viewContainerRef.createEmbeddedView(this.templateRef)
|
||||||
|
} else {
|
||||||
|
this.viewContainerRef.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnChanges(): void {
|
||||||
|
this.ngOnInit()
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ import {
|
|||||||
ViewContainerRef,
|
ViewContainerRef,
|
||||||
} from '@angular/core'
|
} from '@angular/core'
|
||||||
import { PaperlessUser } from '../data/paperless-user'
|
import { PaperlessUser } from '../data/paperless-user'
|
||||||
import { SettingsService } from '../services/settings.service'
|
import { PermissionsService } from '../services/permissions.service'
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[ifOwner]',
|
selector: '[ifOwner]',
|
||||||
@ -25,11 +25,14 @@ export class IfOwnerDirective implements OnInit, OnChanges {
|
|||||||
constructor(
|
constructor(
|
||||||
private viewContainerRef: ViewContainerRef,
|
private viewContainerRef: ViewContainerRef,
|
||||||
private templateRef: TemplateRef<any>,
|
private templateRef: TemplateRef<any>,
|
||||||
private settings: SettingsService
|
private permissionsService: PermissionsService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
if (!this.ifOwner || this.ifOwner?.id === this.settings.currentUser.id) {
|
if (
|
||||||
|
!this.ifOwner ||
|
||||||
|
this.permissionsService.currentUserIsOwner(this.ifOwner)
|
||||||
|
) {
|
||||||
this.viewContainerRef.createEmbeddedView(this.templateRef)
|
this.viewContainerRef.createEmbeddedView(this.templateRef)
|
||||||
} else {
|
} else {
|
||||||
this.viewContainerRef.clear()
|
this.viewContainerRef.clear()
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
|
import { ObjectWithPermissions } from '../data/object-with-permissions'
|
||||||
|
import { PaperlessUser } from '../data/paperless-user'
|
||||||
|
|
||||||
export enum PermissionAction {
|
export enum PermissionAction {
|
||||||
Add = 'add',
|
Add = 'add',
|
||||||
@ -33,15 +35,30 @@ export interface PaperlessPermission {
|
|||||||
})
|
})
|
||||||
export class PermissionsService {
|
export class PermissionsService {
|
||||||
private permissions: string[]
|
private permissions: string[]
|
||||||
|
private currentUser: PaperlessUser
|
||||||
|
|
||||||
public initialize(permissions: string[]) {
|
public initialize(permissions: string[], currentUser: PaperlessUser) {
|
||||||
this.permissions = permissions
|
this.permissions = permissions
|
||||||
|
this.currentUser = currentUser
|
||||||
}
|
}
|
||||||
|
|
||||||
public currentUserCan(permission: PaperlessPermission): boolean {
|
public currentUserCan(permission: PaperlessPermission): boolean {
|
||||||
return this.permissions.includes(this.getPermissionCode(permission))
|
return this.permissions.includes(this.getPermissionCode(permission))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public currentUserIsOwner(owner: PaperlessUser): boolean {
|
||||||
|
return owner?.id === this.currentUser.id
|
||||||
|
}
|
||||||
|
|
||||||
|
public currentUserHasObjectPermissions(
|
||||||
|
action: string,
|
||||||
|
object: ObjectWithPermissions
|
||||||
|
): boolean {
|
||||||
|
return (object.permissions[action] as Array<number>)?.includes(
|
||||||
|
this.currentUser.id
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
public getPermissionCode(permission: PaperlessPermission): string {
|
public getPermissionCode(permission: PaperlessPermission): string {
|
||||||
return permission.type.replace('%s', permission.action)
|
return permission.type.replace('%s', permission.action)
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,10 @@ export class SettingsService {
|
|||||||
id: uisettings['user_id'],
|
id: uisettings['user_id'],
|
||||||
username: uisettings['username'],
|
username: uisettings['username'],
|
||||||
}
|
}
|
||||||
this.permissionsService.initialize(uisettings.permissions)
|
this.permissionsService.initialize(
|
||||||
|
uisettings.permissions,
|
||||||
|
this.currentUser
|
||||||
|
)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -255,6 +255,7 @@ a, a:hover,
|
|||||||
.paperless-input-tags {
|
.paperless-input-tags {
|
||||||
.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value {
|
.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
border-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ng-select.ng-select-multiple .ng-select-container .ng-value-container {
|
.ng-select.ng-select-multiple .ng-select-container .ng-value-container {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user