Pass Django messages to frontend without API endpoint

This commit is contained in:
shamoon
2024-01-05 10:48:12 -08:00
committed by Moritz Pflanzer
parent 24ec256580
commit 93750663aa
11 changed files with 67 additions and 134 deletions

View File

@@ -21,7 +21,10 @@ import { IfPermissionsDirective } from 'src/app/directives/if-permissions.direct
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { of, throwError } from 'rxjs'
import { ToastService } from 'src/app/services/toast.service'
import { MessagesService } from 'src/app/services/messages.service'
import {
DjangoMessageLevel,
MessagesService,
} from 'src/app/services/messages.service'
import { environment } from 'src/environments/environment'
import { OpenDocumentsService } from 'src/app/services/open-documents.service'
import { ActivatedRoute, Router } from '@angular/router'
@@ -401,17 +404,14 @@ describe('AppFrameComponent', () => {
it('should show toasts for django messages', () => {
const toastErrorSpy = jest.spyOn(toastService, 'showError')
const toastInfoSpy = jest.spyOn(toastService, 'showInfo')
jest.spyOn(messagesService, 'get').mockReturnValue(
of([
{ level: 'warning', message: 'Test warning', tags: '' },
{ level: 'error', message: 'Test error', tags: '' },
{ level: 'success', message: 'Test success', tags: '' },
{ level: 'info', message: 'Test info', tags: '' },
{ level: 'debug', message: 'Test debug', tags: '' },
])
)
jest.spyOn(messagesService, 'get').mockReturnValue([
{ level: DjangoMessageLevel.WARNING, message: 'Test warning' },
{ level: DjangoMessageLevel.ERROR, message: 'Test error' },
{ level: DjangoMessageLevel.SUCCESS, message: 'Test success' },
{ level: DjangoMessageLevel.INFO, message: 'Test info' },
{ level: DjangoMessageLevel.DEBUG, message: 'Test debug' },
])
component.ngOnInit()
httpTestingController.expectOne(`${environment.apiBaseUrl}messages/`)
expect(toastErrorSpy).toHaveBeenCalledTimes(2)
expect(toastInfoSpy).toHaveBeenCalledTimes(3)
})

View File

@@ -12,7 +12,10 @@ import {
} from 'rxjs/operators'
import { Document } from 'src/app/data/document'
import { OpenDocumentsService } from 'src/app/services/open-documents.service'
import { MessagesService } from 'src/app/services/messages.service'
import {
DjangoMessageLevel,
MessagesService,
} from 'src/app/services/messages.service'
import { SavedViewService } from 'src/app/services/rest/saved-view.service'
import { SearchService } from 'src/app/services/rest/search.service'
import { environment } from 'src/environments/environment'
@@ -95,24 +98,19 @@ export class AppFrameComponent
}
this.tasksService.reload()
this.messagesService
.get()
.pipe(first())
.subscribe((msgs) => {
for (const m of msgs) {
switch (m.level) {
case 'error':
case 'warning':
this.toastService.showError(m.message)
break
case 'success':
case 'info':
case 'debug':
this.toastService.showInfo(m.message)
break
}
}
})
this.messagesService.get().forEach((message) => {
switch (message.level) {
case DjangoMessageLevel.ERROR:
case DjangoMessageLevel.WARNING:
this.toastService.showError(message.message)
break
case DjangoMessageLevel.SUCCESS:
case DjangoMessageLevel.INFO:
case DjangoMessageLevel.DEBUG:
this.toastService.showInfo(message.message)
break
}
})
}
toggleSlimSidebar(): void {

View File

@@ -1,35 +1,29 @@
import { TestBed } from '@angular/core/testing'
import { MessagesService } from './messages.service'
import { DjangoMessageLevel, MessagesService } from './messages.service'
import {
HttpClientTestingModule,
HttpTestingController,
} from '@angular/common/http/testing'
import { environment } from 'src/environments/environment'
const messages = [
{ level: DjangoMessageLevel.ERROR, message: 'Error Message' },
{ level: DjangoMessageLevel.INFO, message: 'Info Message' },
]
describe('MessagesService', () => {
let httpTestingController: HttpTestingController
let service: MessagesService
beforeEach(() => {
window['DJANGO_MESSAGES'] = messages
TestBed.configureTestingModule({
providers: [MessagesService],
imports: [HttpClientTestingModule],
})
httpTestingController = TestBed.inject(HttpTestingController)
service = TestBed.inject(MessagesService)
})
afterEach(() => {
httpTestingController.verify()
})
it('calls retrieves global django messages if present', () => {
expect(service.get()).toEqual(messages)
it('calls messages endpoint', () => {
service.get().subscribe()
const req = httpTestingController.expectOne(
`${environment.apiBaseUrl}messages/`
)
expect(req.request.method).toEqual('GET')
window['DJANGO_MESSAGES'] = undefined
expect(service.get()).toEqual([])
})
})

View File

@@ -1,25 +1,27 @@
import { HttpClient } from '@angular/common/http'
import { Injectable } from '@angular/core'
import { Observable } from 'rxjs'
import { environment } from 'src/environments/environment'
// see https://docs.djangoproject.com/en/5.0/ref/contrib/messages/#message-tags
export enum DjangoMessageLevel {
DEBUG = 'debug',
INFO = 'info',
SUCCESS = 'success',
WARNING = 'warning',
ERROR = 'error',
}
export interface DjangoMessage {
level: string
level: DjangoMessageLevel
message: string
tags: string
}
@Injectable({
providedIn: 'root',
})
export class MessagesService {
private endpoint = 'messages'
constructor() {}
constructor(private http: HttpClient) {}
get(): Observable<DjangoMessage[]> {
return this.http.get<DjangoMessage[]>(
`${environment.apiBaseUrl}${this.endpoint}/`
)
get(): DjangoMessage[] {
// These are embedded in the HTML as raw JS, kept as a service for convenience
return window['DJANGO_MESSAGES'] ?? []
}
}