Add folder creation and fix other bugs

This commit is contained in:
Martin Tan 2023-08-05 03:45:25 +08:00
parent 3d3ce79b0d
commit ee84acd853
9 changed files with 195 additions and 44 deletions

View File

@ -113,7 +113,8 @@ import localeSl from '@angular/common/locales/sl'
import localeSr from '@angular/common/locales/sr'
import localeSv from '@angular/common/locales/sv'
import localeTr from '@angular/common/locales/tr'
import localeZh from '@angular/common/locales/zh'
import localeZh from '@angular/common/locales/zh';
import { FolderCreateDialogComponent } from './components/common/create-dialog/folder-create-dialog/folder-create-dialog.component'
registerLocaleData(localeAr)
registerLocaleData(localeBe)
@ -215,6 +216,7 @@ function initializeApp(settings: SettingsService) {
IfObjectPermissionsDirective,
PermissionsDialogComponent,
PermissionsFormComponent,
FolderCreateDialogComponent,
],
imports: [
BrowserModule,

View File

@ -0,0 +1,47 @@
<form [formGroup]="objectForm" (ngSubmit)="submit()">
<div class="modal-header">
<h4 class="modal-title" id="modal-basic-title">{{ getTitle() }}</h4>
<button
type="button"
[disabled]="!closeEnabled"
class="btn-close"
aria-label="Close"
(click)="cancel()"
></button>
</div>
<div class="modal-body">
<app-input-text
i18n-title
title="Name"
formControlName="name"
[error]="error?.name"
></app-input-text>
<div *appIfOwner="object">
<app-permissions-form
[users]="users"
accordion="true"
formControlName="permissions_form"
></app-permissions-form>
</div>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-outline-secondary"
(click)="cancel()"
i18n
[disabled]="networkActive"
>
Cancel
</button>
<button
type="submit"
class="btn btn-primary"
i18n
[disabled]="networkActive"
>
Save
</button>
</div>
</form>

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FolderCreateDialogComponent } from './folder-create-dialog.component';
describe('FolderCreateDialogComponent', () => {
let component: FolderCreateDialogComponent;
let fixture: ComponentFixture<FolderCreateDialogComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ FolderCreateDialogComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(FolderCreateDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,57 @@
import { Component, OnInit } from '@angular/core'
import { FormControl, FormGroup } from '@angular/forms'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { DEFAULT_MATCHING_ALGORITHM } from 'src/app/data/matching-model'
import { PaperlessStoragePath } from 'src/app/data/paperless-storage-path'
import { StoragePathService } from 'src/app/services/rest/storage-path.service'
import { UserService } from 'src/app/services/rest/user.service'
import { EditDialogComponent } from '../../edit-dialog/edit-dialog.component'
import { Subscription } from 'rxjs'
@Component({
selector: 'app-folder-create-dialog',
templateUrl: './folder-create-dialog.component.html',
styleUrls: ['./folder-create-dialog.component.scss'],
})
export class FolderCreateDialogComponent
extends EditDialogComponent<PaperlessStoragePath>
implements OnInit
{
nameSub: Subscription
constructor(
service: StoragePathService,
activeModal: NgbActiveModal,
userService: UserService
) {
super(service, activeModal, userService)
}
ngOnInit(): void {
const nameField = this.objectForm.get('name')
const parentFolderPath = this.object?.path ?? ''
this.nameSub = nameField.valueChanges.subscribe(() => {
const fullPath = parentFolderPath + '/' + nameField.value
this.objectForm.get('path').patchValue(fullPath)
this.objectForm.get('slug').patchValue(fullPath)
})
}
submit(): void {
this.nameSub.unsubscribe()
this.objectForm.get('name').patchValue(this.objectForm.get('path').value)
this.save()
}
getForm(): FormGroup<any> {
return new FormGroup({
name: new FormControl(''),
path: new FormControl(''),
slug: new FormControl(''),
matching_algorithm: new FormControl(DEFAULT_MATCHING_ALGORITHM),
match: new FormControl(''),
is_insensitive: new FormControl(true),
permissions_form: new FormControl(null),
})
}
}

View File

@ -169,7 +169,7 @@
</app-page-header>
<div class="row sticky-top pt-3 pt-sm-4 pb-2 pb-lg-4 bg-body">
<div class="flex pb-2">
<div class="flex pb-2 mb-4">
<span *ngFor="let pathPart of folderPath.split('/'); let i = index">
<a (click)="clickPathPart(i)">{{ pathPart }}</a>
<span *ngIf="i < folderPath.split('/').length - 1"> / </span>
@ -182,6 +182,17 @@
[selectionData]="list.selectionData"
#filterEditor
></app-filter-editor> -->
<div class="row w-auto">
<button
type="button"
class="btn btn-primary btn-sm mx-2"
(click)="createFolder()"
>
+ New Folder
</button>
</div>
<app-bulk-editor [hidden]="!isBulkEditing"></app-bulk-editor>
</div>

View File

@ -6,18 +6,9 @@ import {
ViewChild,
ViewChildren,
} from '@angular/core'
import { ActivatedRoute, Router, convertToParamMap } from '@angular/router'
import { ActivatedRoute, Router } from '@angular/router'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
import {
Subject,
filter,
first,
map,
switchMap,
take,
takeUntil,
tap,
} from 'rxjs'
import { Subject, takeUntil } from 'rxjs'
import {
FilterRule,
filterRulesDiffer,
@ -26,6 +17,7 @@ import {
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type'
import { PaperlessDocument } from 'src/app/data/paperless-document'
import { PaperlessSavedView } from 'src/app/data/paperless-saved-view'
import { PaperlessStoragePath } from 'src/app/data/paperless-storage-path'
import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings'
import {
SortEvent,
@ -41,9 +33,9 @@ import { SavedViewService } from 'src/app/services/rest/saved-view.service'
import { SettingsService } from 'src/app/services/settings.service'
import { StoragePathListViewService } from 'src/app/services/storage-path-list-view.service'
import { ToastService } from 'src/app/services/toast.service'
import { FolderCreateDialogComponent } from '../common/create-dialog/folder-create-dialog/folder-create-dialog.component'
import { ComponentWithPermissions } from '../with-permissions/with-permissions.component'
import { FilterEditorComponent } from './filter-editor/filter-editor.component'
import { PaperlessStoragePath } from 'src/app/data/paperless-storage-path'
@Component({
selector: 'app-explorer',
@ -169,9 +161,11 @@ export class ExplorerComponent
}
clickPathPart(index: number) {
if (index === 0) return this.router.navigate(['explorer'])
const pathUntilPart = this.folderPath
.replace('DMS/', '')
.split('/')
.slice(0, index + 1)
.slice(0, index)
.join('/')
this.list.getStoragePathByPath(pathUntilPart).subscribe((storagePath) => {
this.router.navigate(['explorer'], {
@ -180,6 +174,19 @@ export class ExplorerComponent
})
}
createFolder() {
var modal = this.modalService.open(FolderCreateDialogComponent, {
backdrop: 'static',
})
modal.componentInstance.dialogMode = 'create'
modal.componentInstance.object = {
path: this.folderPath.replace('DMS/', ''),
}
modal.componentInstance.succeeded
.pipe(takeUntil(this.unsubscribeNotifier))
.subscribe(() => this.list.reload())
}
openDocumentDetail(storagePath: PaperlessStoragePath) {
this.router.navigate(['explorer'], {
queryParams: { spid: storagePath.id },

View File

@ -51,7 +51,7 @@ export class CustomStoragePathService extends AbstractPaperlessService<Paperless
if (parentStoragePathId !== null && parentStoragePathId !== undefined) {
return this.get(parentStoragePathId).pipe(
switchMap((storagePath) => {
params.path__istartswith = storagePath.path
params.path__istartswith = storagePath.path + '/'
return this.list(page, pageSize, sortField, sortReverse, params).pipe(
map((results) => {
results.results = results.results.filter((s) => {

View File

@ -1,18 +1,12 @@
import { Injectable } from '@angular/core'
import { ParamMap, Router } from '@angular/router'
import { Observable } from 'rxjs'
import {
FilterRule,
cloneFilterRules,
filterRulesDiffer,
isFullTextFilterRule,
} from '../data/filter-rule'
import { FilterRule, isFullTextFilterRule } from '../data/filter-rule'
import { PaperlessDocument } from '../data/paperless-document'
import { PaperlessSavedView } from '../data/paperless-saved-view'
import { PaperlessStoragePath } from '../data/paperless-storage-path'
import { SETTINGS_KEYS } from '../data/paperless-uisettings'
import { DOCUMENT_LIST_SERVICE } from '../data/storage-keys'
import { paramsFromViewState, paramsToViewState } from '../utils/query-params'
import { paramsToViewState } from '../utils/query-params'
import { CustomStoragePathService } from './rest/custom-storage-path.service'
import { DOCUMENT_SORT_FIELDS, SelectionData } from './rest/document.service'
import { SettingsService } from './settings.service'
@ -136,29 +130,38 @@ export class StoragePathListViewService {
if (queryParams.has('spid')) {
newState.storagePathId = parseInt(queryParams.get('spid'))
}
} else {
newState = this.defaultListViewState()
}
if (newState == undefined) newState = this.defaultListViewState() // if nothing in local storage
// only reload if things have changed
if (
!this.initialized ||
isParamsEmpty ||
this.activeListViewState.sortField !== newState.sortField ||
this.activeListViewState.sortReverse !== newState.sortReverse ||
this.activeListViewState.currentPage !== newState.currentPage ||
this.activeListViewState.storagePathId !== newState.storagePathId ||
filterRulesDiffer(
this.activeListViewState.filterRules,
newState.filterRules
)
) {
this.activeListViewState.filterRules = newState.filterRules
this.activeListViewState.sortField = newState.sortField
this.activeListViewState.sortReverse = newState.sortReverse
this.activeListViewState.currentPage = newState.currentPage
this.activeListViewState.storagePathId = newState.storagePathId
this.reload(null, isParamsEmpty) // update the params if there arent any
}
this.activeListViewState.parentStoragePath = newState.parentStoragePath
this.reload(null, isParamsEmpty)
// only reload if things have changed
// if (
// !this.initialized ||
// isParamsEmpty ||
// this.activeListViewState.sortField !== newState.sortField ||
// this.activeListViewState.sortReverse !== newState.sortReverse ||
// this.activeListViewState.currentPage !== newState.currentPage ||
// this.activeListViewState.storagePathId !== newState.storagePathId ||
// filterRulesDiffer(
// this.activeListViewState.filterRules,
// newState.filterRules
// )
// ) {
// this.activeListViewState.filterRules = newState.filterRules
// this.activeListViewState.sortField = newState.sortField
// this.activeListViewState.sortReverse = newState.sortReverse
// this.activeListViewState.currentPage = newState.currentPage
// this.activeListViewState.storagePathId = newState.storagePathId
// this.reload(null, isParamsEmpty) // update the params if there arent any
// }
}
getStoragePathByPath(path: string): Observable<PaperlessStoragePath> {
@ -297,7 +300,8 @@ export class StoragePathListViewService {
}
get currentFolderPath(): string {
return this.activeListViewState.parentStoragePath?.path || '/'
const path = this.activeListViewState.parentStoragePath?.path
return path ? 'DMS/' + path : 'DMS/'
}
setSort(field: string, reverse: boolean) {