mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
skeleton user / group admin dialogs [WIP]
This commit is contained in:
@@ -221,6 +221,82 @@
|
||||
|
||||
</ng-template>
|
||||
</li>
|
||||
|
||||
<li [ngbNavItem]="SettingsNavIDs.UsersGroups" *ifPermissions="{ action: PermissionAction.Add, type: PermissionType.User }" (mouseover)="maybeInitializeTab(SettingsNavIDs.UsersGroups)" (focusin)="maybeInitializeTab(SettingsNavIDs.UsersGroups)">
|
||||
<a ngbNavLink i18n>Users & Groups</a>
|
||||
<ng-template ngbNavContent>
|
||||
|
||||
<ng-container *ngIf="users && groups">
|
||||
<h4 class="d-flex">
|
||||
<ng-container i18n>Users</ng-container>
|
||||
<button type="button" class="btn btn-sm btn-primary ms-4" (click)="editUser()" i18n>Add User</button>
|
||||
</h4>
|
||||
<ul class="list-group" formGroupName="usersGroup">
|
||||
|
||||
<li class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col" i18n>Username</div>
|
||||
<div class="col" i18n>Name</div>
|
||||
<div class="col" i18n>Groups</div>
|
||||
<div class="col" i18n>Actions</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li *ngFor="let user of users" class="list-group-item" [formGroupName]="user.id">
|
||||
<div class="row">
|
||||
<div class="col d-flex align-items-center"><button class="btn btn-link p-0" type="button" (click)="editUser(user)">{{user.username}}</button></div>
|
||||
<div class="col d-flex align-items-center">{{user.first_name}} {{user.last_name}}</div>
|
||||
<div class="col d-flex align-items-center">{{user.groups}}</div>
|
||||
<div class="col">
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-sm btn-primary" type="button" (click)="editUser(user)" i18n>Edit</button>
|
||||
<button class="btn btn-sm btn-outline-danger" type="button" (click)="deleteUser(user)" i18n>Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4 class="mt-4 d-flex">
|
||||
<ng-container i18n>Groups</ng-container>
|
||||
<button type="button" class="btn btn-sm btn-primary ms-4" (click)="editGroup()" i18n>Add Group</button>
|
||||
</h4>
|
||||
<ul *ngIf="groups.length > 0" class="list-group" formGroupName="groupsGroup">
|
||||
|
||||
<li class="list-group-item">
|
||||
<div class="row">
|
||||
<div class="col" i18n>Name</div>
|
||||
<div class="col"></div>
|
||||
<div class="col"></div>
|
||||
<div class="col" i18n>Actions</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li *ngFor="let group of groups" class="list-group-item" [formGroupName]="group.id">
|
||||
<div class="row">
|
||||
<div class="col d-flex align-items-center"><button class="btn btn-link p-0" type="button" (click)="editGroup(group)">{{group.name}}</button></div>
|
||||
<div class="col"></div>
|
||||
<div class="col"></div>
|
||||
<div class="col">
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-sm btn-primary" type="button" (click)="editGroup(group)" i18n>Edit</button>
|
||||
<button class="btn btn-sm btn-outline-danger" type="button" (click)="deleteGroup(group)" i18n>Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div *ngIf="groups.length == 0">No groups defined</div>
|
||||
</ng-container>
|
||||
|
||||
<div *ngIf="!users || !groups">
|
||||
<div class="spinner-border spinner-border-sm fw-normal ms-2 me-auto" role="status"></div>
|
||||
<div class="visually-hidden" i18n>Loading...</div>
|
||||
</div>
|
||||
|
||||
</ng-template>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div [ngbNavOutlet]="nav" class="border-start border-end border-bottom p-3 mb-3 shadow-sm"></div>
|
||||
|
@@ -30,8 +30,15 @@ import { ActivatedRoute } from '@angular/router'
|
||||
import { ViewportScroller } from '@angular/common'
|
||||
import { TourService } from 'ngx-ui-tour-ng-bootstrap'
|
||||
import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
|
||||
import { NgbNavChangeEvent } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { NgbModal, NgbNavChangeEvent } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { Results } from 'src/app/data/results'
|
||||
import { UserService } from 'src/app/services/rest/user.service'
|
||||
import { GroupService } from 'src/app/services/rest/group.service'
|
||||
import { PaperlessUser } from 'src/app/data/paperless-user'
|
||||
import { PaperlessGroup } from 'src/app/data/paperless-group'
|
||||
import { UserEditDialogComponent } from '../../common/edit-dialog/user-edit-dialog/user-edit-dialog.component'
|
||||
import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
|
||||
import { GroupEditDialogComponent } from '../../common/edit-dialog/group-edit-dialog/group-edit-dialog.component'
|
||||
|
||||
enum SettingsNavIDs {
|
||||
General = 1,
|
||||
@@ -54,6 +61,8 @@ export class SettingsComponent
|
||||
activeNavID: number
|
||||
|
||||
savedViewGroup = new FormGroup({})
|
||||
usersGroup = new FormGroup({})
|
||||
groupsGroup = new FormGroup({})
|
||||
|
||||
settingsForm = new FormGroup({
|
||||
bulkEditConfirmationDialogs: new FormControl(null),
|
||||
@@ -75,6 +84,8 @@ export class SettingsComponent
|
||||
notificationsConsumerSuppressOnDashboard: new FormControl(null),
|
||||
commentsEnabled: new FormControl(null),
|
||||
updateCheckingEnabled: new FormControl(null),
|
||||
usersGroup: this.usersGroup,
|
||||
groupsGroup: this.groupsGroup,
|
||||
})
|
||||
|
||||
savedViews: PaperlessSavedView[]
|
||||
@@ -86,6 +97,9 @@ export class SettingsComponent
|
||||
unsubscribeNotifier: Subject<any> = new Subject()
|
||||
savePending: boolean = false
|
||||
|
||||
users: PaperlessUser[]
|
||||
groups: PaperlessGroup[]
|
||||
|
||||
get computedDateLocale(): string {
|
||||
return (
|
||||
this.settingsForm.value.dateLocale ||
|
||||
@@ -102,7 +116,10 @@ export class SettingsComponent
|
||||
@Inject(LOCALE_ID) public currentLocale: string,
|
||||
private viewportScroller: ViewportScroller,
|
||||
private activatedRoute: ActivatedRoute,
|
||||
public readonly tourService: TourService
|
||||
public readonly tourService: TourService,
|
||||
private usersService: UserService,
|
||||
private groupsService: GroupService,
|
||||
private modalService: NgbModal
|
||||
) {
|
||||
super()
|
||||
this.settings.settingsSaved.subscribe(() => {
|
||||
@@ -159,6 +176,8 @@ export class SettingsComponent
|
||||
updateCheckingEnabled: this.settings.get(
|
||||
SETTINGS_KEYS.UPDATE_CHECKING_ENABLED
|
||||
),
|
||||
usersGroup: {},
|
||||
groupsGroup: {},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,6 +195,18 @@ export class SettingsComponent
|
||||
this.savedViews = r.results
|
||||
this.initialize()
|
||||
})
|
||||
} else if (
|
||||
(navID == SettingsNavIDs.UsersGroups && !this.users) ||
|
||||
!this.groups
|
||||
) {
|
||||
this.usersService.listAll().subscribe((r) => {
|
||||
this.users = r.results
|
||||
|
||||
this.groupsService.listAll().subscribe((r) => {
|
||||
this.groups = r.results
|
||||
this.initialize()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +235,50 @@ export class SettingsComponent
|
||||
}
|
||||
}
|
||||
|
||||
if (this.users && this.groups) {
|
||||
for (let user of this.users) {
|
||||
storeData.usersGroup[user.id.toString()] = {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
first_name: user.first_name,
|
||||
last_name: user.last_name,
|
||||
is_active: user.is_active,
|
||||
is_superuser: user.is_superuser,
|
||||
groups: user.groups,
|
||||
permissions: user.permissions,
|
||||
}
|
||||
this.usersGroup.addControl(
|
||||
user.id.toString(),
|
||||
new FormGroup({
|
||||
id: new FormControl(null),
|
||||
username: new FormControl(null),
|
||||
first_name: new FormControl(null),
|
||||
last_name: new FormControl(null),
|
||||
is_active: new FormControl(null),
|
||||
is_superuser: new FormControl(null),
|
||||
groups: new FormControl(null),
|
||||
permissions: new FormControl(null),
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
for (let group of this.groups) {
|
||||
storeData.groupsGroup[group.id.toString()] = {
|
||||
id: group.id,
|
||||
name: group.name,
|
||||
permissions: group.permissions,
|
||||
}
|
||||
this.groupsGroup.addControl(
|
||||
group.id.toString(),
|
||||
new FormGroup({
|
||||
id: new FormControl(null),
|
||||
name: new FormControl(null),
|
||||
permissions: new FormControl(null),
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
this.store = new BehaviorSubject(storeData)
|
||||
|
||||
this.storeSub = this.store.asObservable().subscribe((state) => {
|
||||
@@ -400,4 +475,86 @@ export class SettingsComponent
|
||||
clearThemeColor() {
|
||||
this.settingsForm.get('themeColor').patchValue('')
|
||||
}
|
||||
|
||||
editUser(user: PaperlessUser) {
|
||||
var modal = this.modalService.open(UserEditDialogComponent, {
|
||||
backdrop: 'static',
|
||||
size: 'xl',
|
||||
})
|
||||
modal.componentInstance.dialogMode = user ? 'edit' : 'create'
|
||||
modal.componentInstance.object = user
|
||||
modal.componentInstance.success
|
||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||
.subscribe({
|
||||
next: (newUser) => {
|
||||
this.toastService.showInfo(
|
||||
$localize`Saved user "${newUser.username}".`
|
||||
)
|
||||
this.usersService.listAll().subscribe((r) => {
|
||||
this.users = r.results
|
||||
this.initialize()
|
||||
})
|
||||
},
|
||||
error: (e) => {
|
||||
this.toastService.showError(
|
||||
$localize`Error saving user: ${e.toString()}.`
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
deleteUser(user: PaperlessUser) {
|
||||
let modal = this.modalService.open(ConfirmDialogComponent, {
|
||||
backdrop: 'static',
|
||||
})
|
||||
modal.componentInstance.title = $localize`Confirm delete user account`
|
||||
modal.componentInstance.messageBold = $localize`This operation will permanently this user account.`
|
||||
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.usersService.delete(user)
|
||||
})
|
||||
}
|
||||
|
||||
editGroup(group: PaperlessGroup) {
|
||||
var modal = this.modalService.open(GroupEditDialogComponent, {
|
||||
backdrop: 'static',
|
||||
size: 'lg',
|
||||
})
|
||||
modal.componentInstance.dialogMode = group ? 'edit' : 'create'
|
||||
modal.componentInstance.object = group
|
||||
modal.componentInstance.success
|
||||
.pipe(takeUntil(this.unsubscribeNotifier))
|
||||
.subscribe({
|
||||
next: (newGroup) => {
|
||||
this.toastService.showInfo($localize`Saved group "${newGroup.name}".`)
|
||||
this.groupsService.listAll().subscribe((r) => {
|
||||
this.groups = r.results
|
||||
this.initialize()
|
||||
})
|
||||
},
|
||||
error: (e) => {
|
||||
this.toastService.showError(
|
||||
$localize`Error saving group: ${e.toString()}.`
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
deleteGroup(group: PaperlessGroup) {
|
||||
let modal = this.modalService.open(ConfirmDialogComponent, {
|
||||
backdrop: 'static',
|
||||
})
|
||||
modal.componentInstance.title = $localize`Confirm delete user group`
|
||||
modal.componentInstance.messageBold = $localize`This operation will permanently this user group.`
|
||||
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.groupsService.delete(group)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user