mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
Fix: frontend better reflect global perms for bulk edit, disabled form state (#8469)
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
div, .ng-arrow-wrapper, input {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
background-color: var(--pngx-bg-alt) !important;
|
||||
background-color: var(--pngx-bg-disabled) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -66,4 +66,11 @@ describe('PermissionsFormComponent', () => {
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('should disable form on disabled state change', () => {
|
||||
component.setDisabledState(false)
|
||||
expect(component.form.disabled).toBeFalsy()
|
||||
component.setDisabledState(true)
|
||||
expect(component.form.disabled).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
@@ -66,4 +66,12 @@ export class PermissionsFormComponent
|
||||
writeValue(newValue: any): void {
|
||||
this.form.patchValue(newValue, { emitEvent: false })
|
||||
}
|
||||
|
||||
public setDisabledState(isDisabled: boolean): void {
|
||||
if (isDisabled) {
|
||||
this.form.disable()
|
||||
} else {
|
||||
this.form.enable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@
|
||||
pointer-events: none;
|
||||
|
||||
.ng-select-container {
|
||||
background-color: var(--pngx-bg-alt) !important;
|
||||
background-color: var(--pngx-bg-disabled) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@
|
||||
pointer-events: none;
|
||||
|
||||
.ng-select-container {
|
||||
background-color: var(--pngx-bg-alt) !important;
|
||||
background-color: var(--pngx-bg-disabled) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@
|
||||
pointer-events: none;
|
||||
|
||||
.ng-select-container {
|
||||
background-color: var(--pngx-bg-alt) !important;
|
||||
background-color: var(--pngx-bg-disabled) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -16,7 +16,7 @@
|
||||
pointer-events: none;
|
||||
|
||||
.ng-select-container {
|
||||
background-color: var(--pngx-bg-alt) !important;
|
||||
background-color: var(--pngx-bg-disabled) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -45,7 +45,7 @@
|
||||
<div class="d-none d-sm-inline"> <ng-container i18n>Actions</ng-container></div>
|
||||
</button>
|
||||
<div ngbDropdownMenu aria-labelledby="actionsDropdown" class="shadow">
|
||||
<button ngbDropdownItem (click)="reprocess()" [disabled]="!userCanEdit">
|
||||
<button ngbDropdownItem (click)="reprocess()" [disabled]="!userCanEdit || !userIsOwner">
|
||||
<i-bs width="1em" height="1em" name="arrow-counterclockwise"></i-bs> <span i18n>Reprocess</span>
|
||||
</button>
|
||||
|
||||
@@ -53,15 +53,15 @@
|
||||
<i-bs width="1em" height="1em" name="diagram-3"></i-bs> <span i18n>More like this</span>
|
||||
</button>
|
||||
|
||||
<button ngbDropdownItem (click)="splitDocument()" [disabled]="originalContentRenderType !== ContentRenderType.PDF || previewNumPages === 1">
|
||||
<button ngbDropdownItem (click)="splitDocument()" [disabled]="!userCanAdd || originalContentRenderType !== ContentRenderType.PDF || previewNumPages === 1">
|
||||
<i-bs width="1em" height="1em" name="scissors"></i-bs> <span i18n>Split</span>
|
||||
</button>
|
||||
|
||||
<button ngbDropdownItem (click)="rotateDocument()" [disabled]="!userIsOwner || originalContentRenderType !== ContentRenderType.PDF">
|
||||
<button ngbDropdownItem (click)="rotateDocument()" [disabled]="!userIsOwner || !userCanEdit || originalContentRenderType !== ContentRenderType.PDF">
|
||||
<i-bs name="arrow-clockwise"></i-bs> <ng-container i18n>Rotate</ng-container>
|
||||
</button>
|
||||
|
||||
<button ngbDropdownItem (click)="deletePages()" [disabled]="!userIsOwner || originalContentRenderType !== ContentRenderType.PDF || previewNumPages === 1">
|
||||
<button ngbDropdownItem (click)="deletePages()" [disabled]="!userIsOwner || !userCanEdit || originalContentRenderType !== ContentRenderType.PDF || previewNumPages === 1">
|
||||
<i-bs name="file-earmark-minus"></i-bs> <ng-container i18n>Delete page(s)</ng-container>
|
||||
</button>
|
||||
</div>
|
||||
@@ -70,7 +70,7 @@
|
||||
<pngx-custom-fields-dropdown
|
||||
*pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.CustomField }"
|
||||
[documentId]="documentId"
|
||||
[disabled]="!userIsOwner"
|
||||
[disabled]="!userIsOwner || !userCanEdit"
|
||||
[existingFields]="document?.custom_fields"
|
||||
(created)="refreshCustomFields()"
|
||||
(added)="addField($event)">
|
||||
@@ -122,7 +122,7 @@
|
||||
@case (CustomFieldDataType.String) {
|
||||
<pngx-input-text formControlName="value"
|
||||
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
|
||||
[removable]="userIsOwner"
|
||||
[removable]="userIsOwner && userCanEdit"
|
||||
(removed)="removeField(fieldInstance)"
|
||||
[horizontal]="true"
|
||||
[error]="getCustomFieldError(i)"></pngx-input-text>
|
||||
@@ -130,7 +130,7 @@
|
||||
@case (CustomFieldDataType.Date) {
|
||||
<pngx-input-date formControlName="value"
|
||||
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
|
||||
[removable]="userIsOwner"
|
||||
[removable]="userIsOwner && userCanEdit"
|
||||
(removed)="removeField(fieldInstance)"
|
||||
[horizontal]="true"
|
||||
[error]="getCustomFieldError(i)"></pngx-input-date>
|
||||
@@ -138,7 +138,7 @@
|
||||
@case (CustomFieldDataType.Integer) {
|
||||
<pngx-input-number formControlName="value"
|
||||
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
|
||||
[removable]="userIsOwner"
|
||||
[removable]="userIsOwner && userCanEdit"
|
||||
(removed)="removeField(fieldInstance)"
|
||||
[horizontal]="true"
|
||||
[showAdd]="false"
|
||||
@@ -147,7 +147,7 @@
|
||||
@case (CustomFieldDataType.Float) {
|
||||
<pngx-input-number formControlName="value"
|
||||
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
|
||||
[removable]="userIsOwner"
|
||||
[removable]="userIsOwner && userCanEdit"
|
||||
(removed)="removeField(fieldInstance)"
|
||||
[horizontal]="true"
|
||||
[showAdd]="false"
|
||||
@@ -158,7 +158,7 @@
|
||||
<pngx-input-monetary formControlName="value"
|
||||
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
|
||||
[defaultCurrency]="getCustomFieldFromInstance(fieldInstance)?.extra_data?.default_currency"
|
||||
[removable]="userIsOwner"
|
||||
[removable]="userIsOwner && userCanEdit"
|
||||
(removed)="removeField(fieldInstance)"
|
||||
[horizontal]="true"
|
||||
[error]="getCustomFieldError(i)"></pngx-input-monetary>
|
||||
@@ -166,14 +166,14 @@
|
||||
@case (CustomFieldDataType.Boolean) {
|
||||
<pngx-input-check formControlName="value"
|
||||
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
|
||||
[removable]="userIsOwner"
|
||||
[removable]="userIsOwner && userCanEdit"
|
||||
(removed)="removeField(fieldInstance)"
|
||||
[horizontal]="true"></pngx-input-check>
|
||||
}
|
||||
@case (CustomFieldDataType.Url) {
|
||||
<pngx-input-url formControlName="value"
|
||||
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
|
||||
[removable]="userIsOwner"
|
||||
[removable]="userIsOwner && userCanEdit"
|
||||
(removed)="removeField(fieldInstance)"
|
||||
[horizontal]="true"
|
||||
[error]="getCustomFieldError(i)"></pngx-input-url>
|
||||
@@ -182,7 +182,7 @@
|
||||
<pngx-input-document-link formControlName="value"
|
||||
[title]="getCustomFieldFromInstance(fieldInstance)?.name"
|
||||
[parentDocumentID]="documentId"
|
||||
[removable]="userIsOwner"
|
||||
[removable]="userIsOwner && userCanEdit"
|
||||
(removed)="removeField(fieldInstance)"
|
||||
[horizontal]="true"
|
||||
[error]="getCustomFieldError(i)"></pngx-input-document-link>
|
||||
@@ -194,7 +194,7 @@
|
||||
bindLabel="label"
|
||||
[allowNull]="true"
|
||||
[horizontal]="true"
|
||||
[removable]="userIsOwner"
|
||||
[removable]="userIsOwner && userCanEdit"
|
||||
(removed)="removeField(fieldInstance)"
|
||||
[error]="getCustomFieldError(i)"></pngx-input-select>
|
||||
}
|
||||
|
@@ -577,6 +577,10 @@ export class DocumentDetailComponent
|
||||
this.permissionsService.currentUserHasObjectPermissions(
|
||||
PermissionAction.Change,
|
||||
doc
|
||||
) &&
|
||||
this.permissionsService.currentUserCan(
|
||||
PermissionAction.Change,
|
||||
PermissionType.Document
|
||||
)
|
||||
) {
|
||||
this.documentsService
|
||||
@@ -1066,6 +1070,13 @@ export class DocumentDetailComponent
|
||||
)
|
||||
}
|
||||
|
||||
get userCanAdd(): boolean {
|
||||
return this.permissionsService.currentUserCan(
|
||||
PermissionAction.Add,
|
||||
PermissionType.Document
|
||||
)
|
||||
}
|
||||
|
||||
filterDocuments(items: ObjectWithId[] | NgbDateStruct[], type?: DataType) {
|
||||
const filterRules: FilterRule[] = items.flatMap((i) => {
|
||||
if (i.hasOwnProperty('year')) {
|
||||
|
@@ -105,18 +105,18 @@
|
||||
</button>
|
||||
|
||||
<div ngbDropdown>
|
||||
<button class="btn btn-sm btn-outline-primary" id="dropdownSelect" ngbDropdownToggle>
|
||||
<button class="btn btn-sm btn-outline-primary" id="dropdownSelect" [disabled]="!userCanEdit && !userCanAdd" ngbDropdownToggle>
|
||||
<i-bs name="three-dots"></i-bs>
|
||||
<div class="d-none d-sm-inline"> <ng-container i18n>Actions</ng-container></div>
|
||||
</button>
|
||||
<div ngbDropdownMenu aria-labelledby="dropdownSelect" class="shadow">
|
||||
<button ngbDropdownItem (click)="reprocessSelected()" [disabled]="!userCanEditAll">
|
||||
<button ngbDropdownItem (click)="reprocessSelected()" [disabled]="!userCanEditAll && !userCanEditAll">
|
||||
<i-bs name="body-text"></i-bs> <ng-container i18n>Reprocess</ng-container>
|
||||
</button>
|
||||
<button ngbDropdownItem (click)="rotateSelected()" [disabled]="!userOwnsAll">
|
||||
<button ngbDropdownItem (click)="rotateSelected()" [disabled]="!userOwnsAll && !userCanEditAll">
|
||||
<i-bs name="arrow-clockwise"></i-bs> <ng-container i18n>Rotate</ng-container>
|
||||
</button>
|
||||
<button ngbDropdownItem (click)="mergeSelected()" [disabled]="!userCanEditAll || list.selected.size < 2">
|
||||
<button ngbDropdownItem (click)="mergeSelected()" [disabled]="!userCanAdd || list.selected.size < 2">
|
||||
<i-bs name="journals"></i-bs> <ng-container i18n>Merge</ng-container>
|
||||
</button>
|
||||
</div>
|
||||
|
@@ -132,6 +132,20 @@ export class BulkEditorComponent
|
||||
return ownsAll
|
||||
}
|
||||
|
||||
get userCanEdit(): boolean {
|
||||
return this.permissionService.currentUserCan(
|
||||
PermissionAction.Change,
|
||||
PermissionType.Document
|
||||
)
|
||||
}
|
||||
|
||||
get userCanAdd(): boolean {
|
||||
return this.permissionService.currentUserCan(
|
||||
PermissionAction.Add,
|
||||
PermissionType.Document
|
||||
)
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
if (
|
||||
this.permissionService.currentUserCan(
|
||||
|
@@ -366,7 +366,7 @@ textarea,
|
||||
}
|
||||
|
||||
.form-control:disabled, .form-control[readonly] {
|
||||
background-color: var(--pngx-bg-alt);
|
||||
background-color: var(--pngx-bg-disabled);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
|
@@ -25,6 +25,7 @@ $color-mode-type: data;
|
||||
--pngx-bg-alt: #fff;
|
||||
--pngx-bg-darker: var(--bs-gray-100);
|
||||
--pngx-bg-alt2: var(--bs-gray-200);
|
||||
--pngx-bg-disabled: #f7f7f7;
|
||||
--pngx-focus-alpha: 0.3;
|
||||
}
|
||||
|
||||
@@ -83,6 +84,7 @@ $form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,<svg xmlns='htt
|
||||
--pngx-bg-darker: #101216;
|
||||
--bs-tertiary-bg: var(--pngx-bg-darker);
|
||||
--pngx-bg-alt: #242529;
|
||||
--pngx-bg-disabled: var(--pngx-bg-alt);
|
||||
--pngx-focus-alpha: 0.6;
|
||||
--pngx-primary-faded: var(--pngx-primary-darken-15);
|
||||
--pngx-primary-text-contrast: var(--bs-body-color);
|
||||
|
Reference in New Issue
Block a user