some edit dialogs to signals

This commit is contained in:
shamoon
2026-07-07 18:35:53 -07:00
parent c3a2794a01
commit cdfb67f71b
12 changed files with 412 additions and 83 deletions
@@ -1,5 +1,12 @@
import { DecimalPipe } from '@angular/common'
import { Component, EventEmitter, Input, Output, inject } from '@angular/core'
import {
Component,
EventEmitter,
Input,
Output,
inject,
signal,
} from '@angular/core'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { Subject } from 'rxjs'
import { LoadingComponentWithPermissions } from '../../loading-component/loading.component'
@@ -13,6 +20,17 @@ import { LoadingComponentWithPermissions } from '../../loading-component/loading
export class ConfirmDialogComponent extends LoadingComponentWithPermissions {
activeModal = inject(NgbActiveModal)
private titleSignal = signal($localize`Confirmation`)
private messageBoldSignal = signal<string>(undefined)
private messageSignal = signal<string>(undefined)
private btnClassSignal = signal('btn-primary')
private btnCaptionSignal = signal($localize`Confirm`)
private alternativeBtnClassSignal = signal('btn-secondary')
private alternativeBtnCaptionSignal = signal<string>(undefined)
private cancelBtnClassSignal = signal('btn-outline-secondary')
private cancelBtnCaptionSignal = signal($localize`Cancel`)
private buttonsEnabledSignal = signal(true)
@Output()
public confirmClicked = new EventEmitter()
@@ -20,34 +38,94 @@ export class ConfirmDialogComponent extends LoadingComponentWithPermissions {
public alternativeClicked = new EventEmitter()
@Input()
title = $localize`Confirmation`
get title(): string {
return this.titleSignal()
}
set title(title: string) {
this.titleSignal.set(title)
}
@Input()
messageBold
get messageBold(): string {
return this.messageBoldSignal()
}
set messageBold(messageBold: string) {
this.messageBoldSignal.set(messageBold)
}
@Input()
message
get message(): string {
return this.messageSignal()
}
set message(message: string) {
this.messageSignal.set(message)
}
@Input()
btnClass = 'btn-primary'
get btnClass(): string {
return this.btnClassSignal()
}
set btnClass(btnClass: string) {
this.btnClassSignal.set(btnClass)
}
@Input()
btnCaption = $localize`Confirm`
get btnCaption(): string {
return this.btnCaptionSignal()
}
set btnCaption(btnCaption: string) {
this.btnCaptionSignal.set(btnCaption)
}
@Input()
alternativeBtnClass = 'btn-secondary'
get alternativeBtnClass(): string {
return this.alternativeBtnClassSignal()
}
set alternativeBtnClass(alternativeBtnClass: string) {
this.alternativeBtnClassSignal.set(alternativeBtnClass)
}
@Input()
alternativeBtnCaption
get alternativeBtnCaption(): string {
return this.alternativeBtnCaptionSignal()
}
set alternativeBtnCaption(alternativeBtnCaption: string) {
this.alternativeBtnCaptionSignal.set(alternativeBtnCaption)
}
@Input()
cancelBtnClass = 'btn-outline-secondary'
get cancelBtnClass(): string {
return this.cancelBtnClassSignal()
}
set cancelBtnClass(cancelBtnClass: string) {
this.cancelBtnClassSignal.set(cancelBtnClass)
}
@Input()
cancelBtnCaption = $localize`Cancel`
get cancelBtnCaption(): string {
return this.cancelBtnCaptionSignal()
}
set cancelBtnCaption(cancelBtnCaption: string) {
this.cancelBtnCaptionSignal.set(cancelBtnCaption)
}
@Input()
buttonsEnabled = true
get buttonsEnabled(): boolean {
return this.buttonsEnabledSignal()
}
set buttonsEnabled(buttonsEnabled: boolean) {
this.buttonsEnabledSignal.set(buttonsEnabled)
}
confirmButtonEnabled = true
alternativeButtonEnabled = true
@@ -1,4 +1,4 @@
import { Component, Input } from '@angular/core'
import { Component } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
import { ConfirmDialogComponent } from '../confirm-dialog.component'
@@ -14,18 +14,11 @@ export class PasswordRemovalConfirmDialogComponent extends ConfirmDialogComponen
includeMetadata: boolean = true
deleteOriginal: boolean = false
@Input()
override title = $localize`Remove password protection`
@Input()
override message =
$localize`Create an unprotected copy or replace the existing file.`
@Input()
override btnCaption = $localize`Start`
constructor() {
super()
this.title = $localize`Remove password protection`
this.message = $localize`Create an unprotected copy or replace the existing file.`
this.btnCaption = $localize`Start`
}
onUpdateDocumentChange(updateDocument: boolean) {
@@ -1,5 +1,5 @@
import { NgStyle } from '@angular/common'
import { Component, inject } from '@angular/core'
import { Component, inject, signal } from '@angular/core'
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
import { DocumentService } from 'src/app/services/rest/document.service'
import { ConfirmDialogComponent } from '../confirm-dialog.component'
@@ -13,11 +13,30 @@ import { ConfirmDialogComponent } from '../confirm-dialog.component'
export class RotateConfirmDialogComponent extends ConfirmDialogComponent {
documentService = inject(DocumentService)
public documentID: number
public showPDFNote: boolean = true
private documentIDSignal = signal<number>(undefined)
private showPDFNoteSignal = signal(true)
private rotationSignal = signal(0)
public get documentID(): number {
return this.documentIDSignal()
}
public set documentID(documentID: number) {
this.documentIDSignal.set(documentID)
}
public get showPDFNote(): boolean {
return this.showPDFNoteSignal()
}
public set showPDFNote(showPDFNote: boolean) {
this.showPDFNoteSignal.set(showPDFNote)
}
// animation is better if we dont normalize yet
public rotation: number = 0
public get rotation(): number {
return this.rotationSignal()
}
public get degrees(): number {
let degrees = this.rotation % 360
@@ -30,6 +49,6 @@ export class RotateConfirmDialogComponent extends ConfirmDialogComponent {
}
rotate(clockwise: boolean = true) {
this.rotation += clockwise ? 90 : -90
this.rotationSignal.update((rotation) => rotation + (clockwise ? 90 : -90))
}
}
@@ -5,6 +5,7 @@ import {
OnInit,
Output,
inject,
signal,
} from '@angular/core'
import { FormGroup } from '@angular/forms'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
@@ -45,10 +46,20 @@ export abstract class EditDialogComponent<
protected settingsService = inject(SettingsService)
protected permissionsService = inject(PermissionsService)
users: User[]
private usersSignal = signal<User[]>(undefined)
private dialogModeSignal = signal(EditDialogMode.CREATE, {
equal: () => false,
})
@Input()
dialogMode: EditDialogMode = EditDialogMode.CREATE
get dialogMode(): EditDialogMode {
return this.dialogModeSignal()
}
set dialogMode(dialogMode: EditDialogMode) {
this.dialogModeSignal.set(dialogMode)
}
@Input()
object: T
@@ -59,11 +70,43 @@ export abstract class EditDialogComponent<
@Output()
failed = new EventEmitter()
networkActive = false
private networkActiveSignal = signal(false)
closeEnabled = false
private closeEnabledSignal = signal(false)
error = null
private errorSignal = signal<any>(null)
get users(): User[] {
return this.usersSignal()
}
set users(users: User[]) {
this.usersSignal.set(users)
}
get networkActive(): boolean {
return this.networkActiveSignal()
}
set networkActive(networkActive: boolean) {
this.networkActiveSignal.set(networkActive)
}
get closeEnabled(): boolean {
return this.closeEnabledSignal()
}
set closeEnabled(closeEnabled: boolean) {
this.closeEnabledSignal.set(closeEnabled)
}
get error(): any {
return this.errorSignal()
}
set error(error: any) {
this.errorSignal.set(error)
}
abstract getForm(): FormGroup
@@ -1,4 +1,4 @@
import { Component, inject } from '@angular/core'
import { Component, inject, signal } from '@angular/core'
import {
FormControl,
FormGroup,
@@ -158,9 +158,33 @@ export class MailRuleEditDialogComponent extends EditDialogComponent<MailRule> {
private correspondentService: CorrespondentService
private documentTypeService: DocumentTypeService
accounts: MailAccount[]
correspondents: Correspondent[]
documentTypes: DocumentType[]
private accountsSignal = signal<MailAccount[]>(undefined)
private correspondentsSignal = signal<Correspondent[]>(undefined)
private documentTypesSignal = signal<DocumentType[]>(undefined)
get accounts(): MailAccount[] {
return this.accountsSignal()
}
set accounts(accounts: MailAccount[]) {
this.accountsSignal.set(accounts)
}
get correspondents(): Correspondent[] {
return this.correspondentsSignal()
}
set correspondents(correspondents: Correspondent[]) {
this.correspondentsSignal.set(correspondents)
}
get documentTypes(): DocumentType[] {
return this.documentTypesSignal()
}
set documentTypes(documentTypes: DocumentType[]) {
this.documentTypesSignal.set(documentTypes)
}
constructor() {
super()
@@ -1,4 +1,4 @@
import { Component, OnInit, inject } from '@angular/core'
import { Component, OnInit, inject, signal } from '@angular/core'
import {
FormControl,
FormGroup,
@@ -40,9 +40,33 @@ export class UserEditDialogComponent
private toastService = inject(ToastService)
private groupsService: GroupService
groups: Group[]
passwordIsSet: boolean = false
public totpLoading: boolean = false
private groupsSignal = signal<Group[]>(undefined)
private passwordIsSetSignal = signal(false)
private totpLoadingSignal = signal(false)
get groups(): Group[] {
return this.groupsSignal()
}
set groups(groups: Group[]) {
this.groupsSignal.set(groups)
}
get passwordIsSet(): boolean {
return this.passwordIsSetSignal()
}
set passwordIsSet(passwordIsSet: boolean) {
this.passwordIsSetSignal.set(passwordIsSet)
}
public get totpLoading(): boolean {
return this.totpLoadingSignal()
}
public set totpLoading(totpLoading: boolean) {
this.totpLoadingSignal.set(totpLoading)
}
constructor() {
super()
@@ -103,7 +127,7 @@ export class UserEditDialogComponent
if (!groupsVal) return []
else
return groupsVal.flatMap(
(id) => this.groups.find((g) => g.id == id)?.permissions
(id) => this.groups?.find((g) => g.id == id)?.permissions
)
}
@@ -4,7 +4,7 @@ import {
moveItemInArray,
} from '@angular/cdk/drag-drop'
import { NgTemplateOutlet } from '@angular/common'
import { Component, OnInit, inject } from '@angular/core'
import { Component, OnInit, inject, signal } from '@angular/core'
import {
AbstractControl,
FormArray,
@@ -476,17 +476,73 @@ export class WorkflowEditDialogComponent
private mailRuleService: MailRuleService
private customFieldsService: CustomFieldsService
templates: Workflow[]
correspondents: Correspondent[]
documentTypes: DocumentType[]
storagePaths: StoragePath[]
mailRules: MailRule[]
customFields: CustomField[]
dateCustomFields: CustomField[]
private templatesSignal = signal<Workflow[]>(undefined)
private correspondentsSignal = signal<Correspondent[]>(undefined)
private documentTypesSignal = signal<DocumentType[]>(undefined)
private storagePathsSignal = signal<StoragePath[]>(undefined)
private mailRulesSignal = signal<MailRule[]>(undefined)
private customFieldsSignal = signal<CustomField[]>(undefined)
private dateCustomFieldsSignal = signal<CustomField[]>(undefined)
get templates(): Workflow[] {
return this.templatesSignal()
}
set templates(templates: Workflow[]) {
this.templatesSignal.set(templates)
}
get correspondents(): Correspondent[] {
return this.correspondentsSignal()
}
set correspondents(correspondents: Correspondent[]) {
this.correspondentsSignal.set(correspondents)
}
get documentTypes(): DocumentType[] {
return this.documentTypesSignal()
}
set documentTypes(documentTypes: DocumentType[]) {
this.documentTypesSignal.set(documentTypes)
}
get storagePaths(): StoragePath[] {
return this.storagePathsSignal()
}
set storagePaths(storagePaths: StoragePath[]) {
this.storagePathsSignal.set(storagePaths)
}
get mailRules(): MailRule[] {
return this.mailRulesSignal()
}
set mailRules(mailRules: MailRule[]) {
this.mailRulesSignal.set(mailRules)
}
get customFields(): CustomField[] {
return this.customFieldsSignal()
}
set customFields(customFields: CustomField[]) {
this.customFieldsSignal.set(customFields)
}
get dateCustomFields(): CustomField[] {
return this.dateCustomFieldsSignal()
}
set dateCustomFields(dateCustomFields: CustomField[]) {
this.dateCustomFieldsSignal.set(dateCustomFields)
}
expandedItem: number = null
private allowedActionTypes = []
private allowedActionTypesSignal = signal([])
private readonly triggerFilterOptionsMap = new WeakMap<
FormArray,
@@ -1294,9 +1350,18 @@ export class WorkflowEditDialogComponent
}
get actionTypeOptions() {
this.settingsService.trackChanges()
return this.allowedActionTypes
}
get allowedActionTypes() {
return this.allowedActionTypesSignal()
}
set allowedActionTypes(allowedActionTypes) {
this.allowedActionTypesSignal.set(allowedActionTypes)
}
getActionTypeOptionName(type: WorkflowActionType): string {
return this.actionTypeOptions.find((t) => t.id === type)?.name ?? ''
}
@@ -1,4 +1,4 @@
import { Component, Input, inject } from '@angular/core'
import { Component, Input, inject, signal } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
@@ -17,23 +17,37 @@ export class EmailDocumentDialogComponent extends LoadingComponentWithPermission
private documentService = inject(DocumentService)
private toastService = inject(ToastService)
@Input()
documentIds: number[]
private documentIdsSignal = signal<number[]>(undefined)
private hasArchiveVersionSignal = signal(true)
private useArchiveVersionSignal = signal(true)
private _hasArchiveVersion: boolean = true
@Input()
get documentIds(): number[] {
return this.documentIdsSignal()
}
set documentIds(documentIds: number[]) {
this.documentIdsSignal.set(documentIds)
}
get useArchiveVersion(): boolean {
return this.useArchiveVersionSignal()
}
set useArchiveVersion(useArchiveVersion: boolean) {
this.useArchiveVersionSignal.set(useArchiveVersion)
}
@Input()
set hasArchiveVersion(value: boolean) {
this._hasArchiveVersion = value
this.hasArchiveVersionSignal.set(value)
this.useArchiveVersion = value
}
get hasArchiveVersion(): boolean {
return this._hasArchiveVersion
return this.hasArchiveVersionSignal()
}
public useArchiveVersion: boolean = true
public emailAddress: string = ''
public emailSubject: string = ''
public emailMessage: string = ''
@@ -3,7 +3,7 @@ import {
DragDropModule,
moveItemInArray,
} from '@angular/cdk/drag-drop'
import { Component, inject } from '@angular/core'
import { Component, inject, signal } from '@angular/core'
import { FormsModule } from '@angular/forms'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
@@ -45,8 +45,25 @@ export class PDFEditorComponent extends ConfirmDialogComponent {
private readonly settingsService = inject(SettingsService)
activeModal: NgbActiveModal = inject(NgbActiveModal)
documentID: number
versionID?: number
private documentIDSignal = signal<number>(undefined)
private versionIDSignal = signal<number>(undefined)
get documentID(): number {
return this.documentIDSignal()
}
set documentID(documentID: number) {
this.documentIDSignal.set(documentID)
}
get versionID(): number {
return this.versionIDSignal()
}
set versionID(versionID: number) {
this.versionIDSignal.set(versionID)
}
pages: PageOperation[] = []
totalPages = 0
editMode: PdfEditorEditMode = this.settingsService.get(
@@ -35,6 +35,8 @@ export class PermissionsDialogComponent {
private userService = inject(UserService)
private usersSignal = signal<User[]>(undefined)
private titleSignal = signal($localize`Set permissions`)
private noteSignal = signal<string>(null)
private buttonsEnabledSignal = signal(true)
private o: ObjectWithPermissions = undefined
@@ -54,10 +56,22 @@ export class PermissionsDialogComponent {
public confirmClicked = new EventEmitter()
@Input()
title = $localize`Set permissions`
get title(): string {
return this.titleSignal()
}
set title(title: string) {
this.titleSignal.set(title)
}
@Input()
note: string = null
get note(): string {
return this.noteSignal()
}
set note(note: string) {
this.noteSignal.set(note)
}
@Input()
set object(o: ObjectWithPermissions) {
@@ -1,5 +1,5 @@
import { Clipboard } from '@angular/cdk/clipboard'
import { Component, Input, OnInit, inject } from '@angular/core'
import { Component, Input, OnInit, inject, signal } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
@@ -27,50 +27,74 @@ export class ShareLinksDialogComponent implements OnInit {
readonly expirationOptions = SHARE_LINK_EXPIRATION_OPTIONS
@Input()
title = $localize`Share Links`
private titleSignal = signal($localize`Share Links`)
private documentIdSignal = signal<number>(undefined)
private hasArchiveVersionSignal = signal(true)
private shareLinksSignal = signal<ShareLink[]>(undefined)
private copiedSignal = signal<number>(undefined)
_documentId: number
@Input()
get title(): string {
return this.titleSignal()
}
set title(title: string) {
this.titleSignal.set(title)
}
@Input()
set documentId(id: number) {
if (id !== undefined) {
this._documentId = id
this.documentIdSignal.set(id)
this.refresh()
}
}
private _hasArchiveVersion: boolean = true
get documentId(): number {
return this.documentIdSignal()
}
@Input()
set hasArchiveVersion(value: boolean) {
this._hasArchiveVersion = value
this.hasArchiveVersionSignal.set(value)
this.useArchiveVersion = value
}
get hasArchiveVersion(): boolean {
return this._hasArchiveVersion
return this.hasArchiveVersionSignal()
}
shareLinks: ShareLink[]
get shareLinks(): ShareLink[] {
return this.shareLinksSignal()
}
set shareLinks(shareLinks: ShareLink[]) {
this.shareLinksSignal.set(shareLinks)
}
loading: boolean = false
copied: number
get copied(): number {
return this.copiedSignal()
}
set copied(copied: number) {
this.copiedSignal.set(copied)
}
expirationDays: number = 7
useArchiveVersion: boolean = true
ngOnInit(): void {
if (this._documentId !== undefined) this.refresh()
if (this.documentId !== undefined) this.refresh()
}
refresh() {
if (this._documentId === undefined) return
if (this.documentId === undefined) return
this.loading = true
this.shareLinkService
.getLinksForDocument(this._documentId)
.getLinksForDocument(this.documentId)
.pipe(first())
.subscribe({
next: (results) => {
@@ -141,7 +165,7 @@ export class ShareLinksDialogComponent implements OnInit {
this.loading = true
this.shareLinkService
.createLinkForDocument(
this._documentId,
this.documentId,
this.useArchiveVersion ? FileVersion.Archive : FileVersion.Original,
expiration
)
@@ -5,6 +5,7 @@ import {
OnInit,
Output,
inject,
signal,
} from '@angular/core'
import {
FormControl,
@@ -32,29 +33,42 @@ import { TextComponent } from '../../common/input/text/text.component'
})
export class SaveViewConfigDialogComponent implements OnInit {
private modal = inject(NgbActiveModal)
private errorSignal = signal(undefined)
private buttonsEnabledSignal = signal(true)
private defaultNameSignal = signal('')
@Output()
public saveClicked = new EventEmitter()
@Input()
error
get error() {
return this.errorSignal()
}
set error(error) {
this.errorSignal.set(error)
}
@Input()
buttonsEnabled = true
get buttonsEnabled(): boolean {
return this.buttonsEnabledSignal()
}
set buttonsEnabled(buttonsEnabled: boolean) {
this.buttonsEnabledSignal.set(buttonsEnabled)
}
closeEnabled = false
users: User[]
_defaultName = ''
get defaultName() {
return this._defaultName
return this.defaultNameSignal()
}
@Input()
set defaultName(value: string) {
this._defaultName = value
this.defaultNameSignal.set(value)
this.saveViewConfigForm.patchValue({ name: value })
}