Skip to content

Commit 034c7a4

Browse files
committed
feat(frontend:files): improve text viewer with save error handling and updated file upload logic
1 parent 25ab568 commit 034c7a4

File tree

3 files changed

+34
-14
lines changed

3 files changed

+34
-14
lines changed

frontend/src/app/applications/files/components/viewers/files-viewer-text.component.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<div class="app-top-menu">
99
<button
1010
(click)="toggleReadonly()"
11-
[tooltip]="'Read-only' | translate:locale.language"
11+
[tooltip]="(isReadonly() ? 'Read-only' : 'Read-write') | translate:locale.language"
1212
[adaptivePosition]="true"
1313
container="body"
1414
class="d-none d-sm-block btn btn-sm btn-secondary me-1"
@@ -40,7 +40,7 @@
4040
[languages]="languages"
4141
[language]="currentLanguage"
4242
[(ngModel)]="content"
43-
(change)="isModified.set(true)"
43+
(change)="contentChange()"
4444
[theme]="currentTheme"
4545
[readonly]="isReadonly()"
4646
[lineWrapping]="true" />

frontend/src/app/applications/files/components/viewers/files-viewer-text.component.ts

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
import { CodeEditor } from '@acrodata/code-editor'
8-
import { HttpClient } from '@angular/common/http'
8+
import { HttpClient, HttpErrorResponse } from '@angular/common/http'
99
import { Component, inject, input, linkedSignal, OnDestroy, OnInit, signal, ViewEncapsulation } from '@angular/core'
1010
import { FormsModule } from '@angular/forms'
1111
import { LanguageDescription } from '@codemirror/language'
@@ -41,29 +41,20 @@ export class FilesViewerTextComponent implements OnInit, OnDestroy {
4141
isReadonly = linkedSignal(() => this.mode() === 'view')
4242
isReadable = signal(false)
4343
isModified = signal(false)
44-
protected openSearchPanel = openSearchPanel
44+
protected readonly openSearchPanel = openSearchPanel
4545
protected content: string
4646
protected currentLanguage = undefined
4747
protected readonly languages: LanguageDescription[] = languages
4848
protected currentTheme: any = 'light'
4949
protected readonly icons = { faFloppyDisk, faLock, faLockOpen, faMagnifyingGlass }
5050
protected readonly locale = inject<L10nLocale>(L10N_LOCALE)
51+
private isContentReady = false
5152
private readonly layout = inject(LayoutService)
5253
private readonly http = inject(HttpClient)
5354
private readonly filesUpload = inject(FilesUploadService)
5455
private subscription = this.layout.switchTheme.subscribe((layout: string) => (this.currentTheme = layout === themeDark ? 'dark' : 'light'))
5556
private readonly maxSize = 5242880 // 5MB
5657

57-
toggleReadonly() {
58-
this.isReadonly.update((value) => !value)
59-
}
60-
61-
async save() {
62-
const file = new File([new Blob([this.content])], this.file().name, { type: 'text/plain' })
63-
await this.filesUpload.addFiles([file], true)
64-
this.isModified.set(false)
65-
}
66-
6758
ngOnInit() {
6859
const language: LanguageDescription = LanguageDescription.matchFilename(languages, this.file().name)
6960
if (language?.name || this.file().size <= this.maxSize) {
@@ -76,6 +67,26 @@ export class FilesViewerTextComponent implements OnInit, OnDestroy {
7667
}
7768
}
7869

70+
toggleReadonly() {
71+
this.isReadonly.update((value) => !value)
72+
}
73+
74+
save() {
75+
this.filesUpload.uploadOneFile(this.file(), this.content, true).subscribe({
76+
next: () => this.isModified.set(false),
77+
error: (e: HttpErrorResponse) => this.layout.sendNotification('error', 'Unable to save document', e.error.message)
78+
})
79+
}
80+
81+
contentChange() {
82+
// Ignore first call
83+
if (this.isContentReady) {
84+
this.isModified.set(true)
85+
} else {
86+
this.isContentReady = true
87+
}
88+
}
89+
7990
ngOnDestroy() {
8091
if (this.subscription) {
8192
this.subscription.unsubscribe()

frontend/src/app/applications/files/services/files-upload.service.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { lastValueFrom, Observable } from 'rxjs'
1212
import { filter, tap } from 'rxjs/operators'
1313
import { supportUploadDirectory } from '../../../common/utils/functions'
1414
import { FileUpload } from '../interfaces/file-upload.interface'
15+
import { FileModel } from '../models/file.model'
1516
import { FilesTasksService } from './files-tasks.service'
1617
import { FilesService } from './files.service'
1718

@@ -64,6 +65,14 @@ export class FilesUploadService {
6465
}
6566
}
6667

68+
uploadOneFile(file: FileModel, content: string, overwrite: boolean) {
69+
const url = `${API_FILES_OPERATION_UPLOAD}/${file.path}`
70+
const fileContent = new File([new Blob([content])], file.name.normalize(), { type: file.mime.replace('-', '/') })
71+
const formData = new FormData()
72+
formData.append('file', fileContent)
73+
return this.http.request<void>(overwrite ? 'put' : 'post', url, { body: formData })
74+
}
75+
6776
private uploadFiles(url: string, form: FormData, overwrite: boolean) {
6877
return this.http.request(overwrite ? 'put' : 'post', url, {
6978
body: form,

0 commit comments

Comments
 (0)