]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Merge branch 'dev' into feature-permissions
authorMichael Shamoon <4887959+shamoon@users.noreply.github.com>
Fri, 9 Dec 2022 11:31:26 +0000 (03:31 -0800)
committerMichael Shamoon <4887959+shamoon@users.noreply.github.com>
Fri, 9 Dec 2022 11:31:26 +0000 (03:31 -0800)
1  2 
src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.html
src-ui/src/app/components/document-list/bulk-editor/bulk-editor.component.ts
src-ui/src/theme.scss
src/documents/models.py
src/documents/serialisers.py
src/documents/tests/test_api.py
src/documents/views.py

index cb4e200dd86da0af1d6212b077624a6f549400a9,d8345fd81ad78f70dd2ae21d20144e99ea154758..cca53552c04908d058eed08d105c39da3af99e56
      </div>
    </div>
    <div class="col-auto ms-auto mb-2 mb-xl-0 d-flex">
-     <div class="btn-toolbar me-2">
+     <div class="btn-group btn-group-sm me-2">
 +
 +      <button type="button" class="btn btn-sm btn-outline-primary me-2" (click)="setPermissions()" [disabled]="!userOwnsAll">
 +        <svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor">
 +          <use xlink:href="assets/bootstrap-icons.svg#person-fill-lock" />
 +        </svg>&nbsp;<ng-container i18n>Permissions</ng-container>
 +      </button>
 +
        <div ngbDropdown class="me-2 d-flex">
          <button class="btn btn-sm btn-outline-primary" id="dropdownSelect" ngbDropdownToggle>
            <svg class="toolbaricon" fill="currentColor">
            <div class="d-none d-sm-inline">&nbsp;<ng-container i18n>Actions</ng-container></div>
          </button>
          <div ngbDropdownMenu aria-labelledby="dropdownSelect" class="shadow">
-           <button ngbDropdownItem [disabled]="awaitingDownload" (click)="downloadSelected()" i18n>
-             Download
-             <div *ngIf="awaitingDownload" class="spinner-border spinner-border-sm" role="status">
-               <span class="visually-hidden">Preparing download...</span>
 -          <button ngbDropdownItem (click)="redoOcrSelected()" i18n>Redo OCR</button>
++          <button ngbDropdownItem (click)="redoOcrSelected()" [disabled]="!userCanEditAll" i18n>Redo OCR</button>
+         </div>
+       </div>
+     </div>
+     <div class="btn-group btn-group-sm me-2">
+       <button class="btn btn-sm btn-outline-primary" [disabled]="awaitingDownload" (click)="downloadSelected()">
+         <svg *ngIf="!awaitingDownload" class="toolbaricon" fill="currentColor">
+           <use xlink:href="assets/bootstrap-icons.svg#arrow-down" />
+         </svg>
+         <div *ngIf="awaitingDownload" class="spinner-border spinner-border-sm" role="status">
+           <span class="visually-hidden">Preparing download...</span>
+         </div>
+         <div class="d-none d-sm-inline">&nbsp;<ng-container i18n>Download</ng-container></div>
+       </button>
+       <div ngbDropdown class="me-2 d-flex btn-group" role="group">
+         <button type="button" class="btn btn-sm btn-outline-primary dropdown-toggle-split rounded-end" ngbDropdownToggle></button>
+         <div ngbDropdownMenu aria-labelledby="dropdownSelect" class="shadow">
+                                       <form [formGroup]="downloadForm" class="px-3 py-1">
+             <p class="mb-1" i18n>Include:</p>
+             <div class="form-group ps-3 mb-2">
+               <div class="form-check">
+                 <input type="checkbox" class="form-check-input" id="downloadFileType_archive" formControlName="downloadFileTypeArchive" />
+                 <label class="form-check-label" for="downloadFileType_archive" i18n>
+                   Archived files
+                 </label>
+               </div>
+               <div class="form-check">
+                 <input type="checkbox" class="form-check-input" id="downloadFileType_originals" formControlName="downloadFileTypeOriginals" />
+                 <label class="form-check-label" for="downloadFileType_originals" i18n>
+                   Original files
+                 </label>
+               </div>
              </div>
-           </button>
-           <button ngbDropdownItem [disabled]="awaitingDownload" (click)="downloadSelected('originals')" i18n>
-             Download originals
-             <div *ngIf="awaitingDownload" class="spinner-border spinner-border-sm" role="status">
-               <span class="visually-hidden">Preparing download...</span>
+             <div class="form-check">
+               <input type="checkbox" class="form-check-input" id="downloadUseFormatting" formControlName="downloadUseFormatting" />
+               <label class="form-check-label" for="downloadUseFormatting" i18n>
+                 Use formatted filename
+               </label>
              </div>
-           </button>
-           <button ngbDropdownItem (click)="redoOcrSelected()" [disabled]="!userCanEditAll" i18n>Redo OCR</button>
+           </form>
          </div>
        </div>
+     </div>
  
-     <button type="button" class="btn btn-sm btn-outline-danger" (click)="applyDelete()" *ifPermissions="{ action: PermissionAction.Delete, type: PermissionType.Document }" [disabled]="!userOwnsAll">
-       <svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor">
-         <use xlink:href="assets/bootstrap-icons.svg#trash" />
-       </svg>&nbsp;<ng-container i18n>Delete</ng-container>
-     </button>
+     <div class="btn-group btn-group-sm me-2">
 -      <button type="button" class="btn btn-sm btn-outline-danger" (click)="applyDelete()">
++      <button type="button" class="btn btn-sm btn-outline-danger" (click)="applyDelete()" *ifPermissions="{ action: PermissionAction.Delete, type: PermissionType.Document }" [disabled]="!userOwnsAll">
+         <svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor">
+           <use xlink:href="assets/bootstrap-icons.svg#trash" />
+         </svg>&nbsp;<ng-container i18n>Delete</ng-container>
+       </button>
+     </div>
    </div>
  </div>
index 32ad28ba78248c34229754503c8ada773896e940,dbfb9d2f06c1c91f8e8605c40f5791ee8566af3f..a69f1416c1f8259f0d5d84c2d9b5d58fc783dab7
@@@ -25,9 -25,8 +25,11 @@@ import { saveAs } from 'file-saver
  import { StoragePathService } from 'src/app/services/rest/storage-path.service'
  import { PaperlessStoragePath } from 'src/app/data/paperless-storage-path'
  import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings'
 +import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
 +import { PermissionsDialogComponent } from '../../common/permissions-dialog/permissions-dialog.component'
 +import { PermissionsService } from 'src/app/services/permissions.service'
+ import { FormControl, FormGroup } from '@angular/forms'
+ import { first, Subject, takeUntil } from 'rxjs'
  
  @Component({
    selector: 'app-bulk-editor',
@@@ -414,21 -456,11 +481,23 @@@ export class BulkEditorComponent extend
      modal.componentInstance.message = $localize`This operation cannot be undone.`
      modal.componentInstance.btnClass = 'btn-danger'
      modal.componentInstance.btnCaption = $localize`Proceed`
-     modal.componentInstance.confirmClicked.subscribe(() => {
-       modal.componentInstance.buttonsEnabled = false
-       this.executeBulkOperation(modal, 'redo_ocr', {})
-     })
+     modal.componentInstance.confirmClicked
+       .pipe(takeUntil(this.unsubscribeNotifier))
+       .subscribe(() => {
+         modal.componentInstance.buttonsEnabled = false
+         this.executeBulkOperation(modal, 'redo_ocr', {})
+       })
    }
 +
 +  setPermissions() {
 +    let modal = this.modalService.open(PermissionsDialogComponent, {
 +      backdrop: 'static',
 +    })
 +    modal.componentInstance.confirmClicked.subscribe((permissions) => {
 +      modal.componentInstance.buttonsEnabled = false
 +      this.executeBulkOperation(modal, 'set_permissions', {
 +        permissions,
 +      })
 +    })
 +  }
  }
Simple merge
Simple merge
Simple merge
index 4d7f7a354adf36319360709456f627c6a0828574,c9d8aefc25292dbc162c63624a3f8b2704fa79ed..b5c7d9a6a4620a68d8084d53b902e8f3c1d02315
@@@ -2331,33 -2327,11 +2331,36 @@@ class TestBulkEdit(DirectoriesMixin, AP
              ],
          )
  
 +    def test_set_permissions(self):
 +        user1 = User.objects.create(username="user1")
 +        user2 = User.objects.create(username="user2")
 +        permissions = {
 +            "view": {
 +                "users": User.objects.filter(id__in=[user1.id, user2.id]),
 +                "groups": Group.objects.none(),
 +            },
 +            "change": {
 +                "users": User.objects.filter(id__in=[user1.id]),
 +                "groups": Group.objects.none(),
 +            },
 +        }
 +
 +        bulk_edit.set_permissions(
 +            [self.doc2.id, self.doc3.id],
 +            permissions=permissions,
 +        )
 +
 +        self.assertEqual(get_users_with_perms(self.doc2).count(), 2)
 +
 +        self.async_task.assert_called_once()
 +        args, kwargs = self.async_task.call_args
 +        self.assertCountEqual(kwargs["document_ids"], [self.doc2.id, self.doc3.id])
 +
  
  class TestBulkDownload(DirectoriesMixin, APITestCase):
+     ENDPOINT = "/api/documents/bulk_download/"
      def setUp(self):
          super().setUp()
  
Simple merge