Skip to content

Commit

Permalink
use baseNotesService
Browse files Browse the repository at this point in the history
  • Loading branch information
lastminutediorama committed Aug 30, 2024
1 parent ab2212e commit 34fd98e
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 138 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AuthService, NotesService } from '@services';
import { AuthService, PlanningAreaNotesService } from '@services';

import { MatLegacySnackBarModule as MatSnackBarModule } from '@angular/material/legacy-snack-bar';

Expand All @@ -22,7 +22,7 @@ describe('AreaNotesComponent', () => {
provide: AuthService,
useValue: fakeAuthService,
},
MockProvider(NotesService, {
MockProvider(PlanningAreaNotesService, {
getNotes: () => of([]),
}),
],
Expand Down
62 changes: 28 additions & 34 deletions src/interface/src/app/plan/area-notes/area-notes.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@ import { MatLegacySnackBar as MatSnackBar } from '@angular/material/legacy-snack
import { DeleteNoteDialogComponent } from '../delete-note-dialog/delete-note-dialog.component';
import { take } from 'rxjs';
import { Plan } from '@types';
import { AuthService, Note, NotesService, NotesModelName } from '@services';
import { AuthService, Note, PlanningAreaNotesService } from '@services';
import { SNACK_ERROR_CONFIG, SNACK_NOTICE_CONFIG } from '@shared';
import { MatDialog } from '@angular/material/dialog';

const NOTES_MODEL: NotesModelName = 'planning_area';

@Component({
selector: 'app-area-notes',
templateUrl: './area-notes.component.html',
styleUrls: ['./area-notes.component.scss'],
})
export class AreaNotesComponent implements OnInit {
constructor(
private notesService: NotesService,
private notesService: PlanningAreaNotesService,
private dialog: MatDialog,
private snackbar: MatSnackBar,
private authService: AuthService
Expand All @@ -34,7 +32,7 @@ export class AreaNotesComponent implements OnInit {

loadNotes() {
this.notesService
.getNotes(NOTES_MODEL, this.plan?.id)
.getNotes(this.plan?.id)
.subscribe((notes) => (this.notes = notes));
}

Expand All @@ -45,42 +43,38 @@ export class AreaNotesComponent implements OnInit {
.pipe(take(1))
.subscribe((confirmed) => {
if (confirmed) {
this.notesService
.deleteNote(NOTES_MODEL, this.plan.id, note.id)
.subscribe({
next: () => {
this.snackbar.open(
`Deleted note`,
'Dismiss',
SNACK_NOTICE_CONFIG
);
this.loadNotes();
},
error: (err) => {
this.snackbar.open(
`Error: ${err.statusText}`,
'Dismiss',
SNACK_ERROR_CONFIG
);
},
});
this.notesService.deleteNote(this.plan.id, note.id).subscribe({
next: () => {
this.snackbar.open(
`Deleted note`,
'Dismiss',
SNACK_NOTICE_CONFIG
);
this.loadNotes();
},
error: (err) => {
this.snackbar.open(
`Error: ${err.statusText}`,
'Dismiss',
SNACK_ERROR_CONFIG
);
},
});
}
});
}

addNote(event: Event) {
if (this.note) {
this.saving = true;
this.notesService
.addNote(NOTES_MODEL, this.plan.id, this.note)
.subscribe((note) => {
// add the note
this.notes.unshift(note);
// but then refresh as well.
this.loadNotes();
this.saving = false;
this.note = '';
});
this.notesService.addNote(this.plan.id, this.note).subscribe((note) => {
// add the note
this.notes.unshift(note);
// but then refresh as well.
this.loadNotes();
this.saving = false;
this.note = '';
});
}
event.preventDefault();
}
Expand Down
21 changes: 19 additions & 2 deletions src/interface/src/app/plan/plan.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { BehaviorSubject, of } from 'rxjs';
import { Plan, Region } from '@types';

import { LegacyMaterialModule } from '../material/legacy-material.module';
import { AuthService, PlanStateService } from '@services';
import {
AuthService,
PlanStateService,
PlanningAreaNotesService,
} from '@services';
import { PlanMapComponent } from './plan-map/plan-map.component';
import { PlanOverviewComponent } from './plan-summary/plan-overview/plan-overview.component';
import { PlanComponent } from './plan.component';
Expand All @@ -20,7 +24,7 @@ describe('PlanComponent', () => {
let component: PlanComponent;
let fixture: ComponentFixture<PlanComponent>;
let mockAuthService: Partial<AuthService>;

let mockNotesService: PlanningAreaNotesService;
const fakeGeoJson: GeoJSON.GeoJSON = {
type: 'FeatureCollection',
features: [
Expand Down Expand Up @@ -60,6 +64,18 @@ describe('PlanComponent', () => {

mockAuthService = {};

mockNotesService = jasmine.createSpyObj('PlanningAreaNotesService', [
'getNotes',
'addNote',
'deleteNote',
]);
Object.assign(mockNotesService, {
modelName: 'planning_area',
multipleUrl: 'mock-multiple-url',
singleUrl: 'mock-single-url',
});
(mockNotesService.getNotes as jasmine.Spy).and.returnValue(of([]));

const fakeService = jasmine.createSpyObj(
'PlanStateService',
{
Expand Down Expand Up @@ -94,6 +110,7 @@ describe('PlanComponent', () => {
{ provide: ActivatedRoute, useValue: fakeRoute },
{ provide: AuthService, useValue: mockAuthService },
{ provide: PlanStateService, useValue: fakeService },
{ provide: PlanningAreaNotesService, useValue: mockNotesService },
],
}).compileComponents();

Expand Down
9 changes: 8 additions & 1 deletion src/interface/src/app/plan/plan.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ import {
take,
takeUntil,
} from 'rxjs';
import { NotesModelName } from '@services';
import {
NotesModelName,
BaseNotesService,
PlanningAreaNotesService,
} from '@services';
import { Plan, User } from '@types';
import { AuthService, PlanStateService, ScenarioService } from '@services';
import { Breadcrumb } from '@shared';
Expand All @@ -30,6 +34,9 @@ import { HomeParametersStorageService } from '@services/local-storage.service';
selector: 'app-plan',
templateUrl: './plan.component.html',
styleUrls: ['./plan.component.scss'],
providers: [
{ provide: BaseNotesService, useClass: PlanningAreaNotesService },
],
})
export class PlanComponent implements OnInit, OnDestroy {
notesModel: NotesModelName = 'planning_area';
Expand Down
2 changes: 0 additions & 2 deletions src/interface/src/app/plan/plan.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { AreaDetailsComponent } from './area-details/area-details.component';
import { AreaNotesComponent } from './area-notes/area-notes.component';
import { AreaScrollingNotesComponent } from './area-scrolling-notes/area-scrolling-notes.component';
import { CommonModule } from '@angular/common';
import { ConstraintsPanelComponent } from './create-scenarios/constraints-panel/constraints-panel.component';
import { CreateScenariosComponent } from './create-scenarios/create-scenarios.component';
Expand Down Expand Up @@ -52,7 +51,6 @@ import { TreatmentsTabComponent } from './create-scenarios/treatments-tab/treatm
declarations: [
AreaDetailsComponent,
AreaNotesComponent,
AreaScrollingNotesComponent,
ConstraintsPanelComponent,
CreateScenariosComponent,
DeleteNoteDialogComponent,
Expand Down
9 changes: 5 additions & 4 deletions src/interface/src/app/services/notes.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { TestBed } from '@angular/core/testing';
import { NotesService } from './notes.service';
import { PlanningAreaNotesService } from './notes.service';
import { HttpClientTestingModule } from '@angular/common/http/testing';

describe('NotesService', () => {
let service: NotesService;
describe('PlanningAreaNotesService', () => {
let service: PlanningAreaNotesService;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [PlanningAreaNotesService],
});
service = TestBed.inject(NotesService);
service = TestBed.inject(PlanningAreaNotesService);
});

it('should be created', () => {
Expand Down
89 changes: 39 additions & 50 deletions src/interface/src/app/services/notes.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';

export interface Note {
id: number;
user_id: number;
Expand All @@ -19,68 +18,58 @@ export interface NoteModel {
urlSingle: (modelObjectId: number, noteId: number) => string;
}

const noteEndpoints: Record<
NotesModelName,
{
multipleUrl: (objectId: number) => string;
singleUrl: (objectId: number, noteId: number) => string;
}
> = {
planning_area: {
multipleUrl: (objectId: number) =>
`/planning/planning_area/${objectId}/note`,
singleUrl: (objectId: number, noteId: number) =>
`/planning/planning_area/${objectId}/note/${noteId}`,
},
project_area: {
multipleUrl: (objectId: number) =>
`/planning/planning_area/${objectId}/note`,
singleUrl: (objectId: number, noteId: number) =>
`/planning/planning_area/${objectId}/note/${noteId}`,
},
};

@Injectable({
providedIn: 'root',
})
export class NotesService {
export abstract class BaseNotesService {
constructor(private http: HttpClient) {}

getNotes(modelName: NotesModelName, objectId: number) {
const endpoints = noteEndpoints[modelName];
const url = endpoints.multipleUrl(objectId);
if (!url) {
throw new Error(`Model ${modelName} not found`);
}
return this.http.get<Note[]>(environment.backend_endpoint.concat(url), {
withCredentials: true,
});
protected abstract multipleUrl: (objectId: number) => string;
protected abstract singleUrl: (objectId: number, noteId: number) => string;
protected abstract modelName: NotesModelName;

getNotes(objectId: number) {
return this.http.get<Note[]>(
environment.backend_endpoint.concat(this.multipleUrl(objectId)),
{
withCredentials: true,
}
);
}

addNote(modelName: NotesModelName, objectId: number, note: string) {
const endpoints = noteEndpoints[modelName];
const url = endpoints.multipleUrl(objectId);
if (!url) {
throw new Error(`Model ${modelName} not found`);
}
addNote(objectId: number, noteContent: string) {
return this.http.post<Note>(
environment.backend_endpoint.concat(url),
{ content: note },
environment.backend_endpoint.concat(this.multipleUrl(objectId)),
{ content: noteContent },
{
withCredentials: true,
}
);
}

deleteNote(modelName: NotesModelName, objectId: number, noteId: number) {
const endpoints = noteEndpoints[modelName];
const url = endpoints.singleUrl(objectId, noteId);

if (!url) {
throw new Error(`Model ${modelName} not found`);
}
return this.http.delete<Note>(environment.backend_endpoint.concat(url), {
withCredentials: true,
});
deleteNote(objectId: number, noteId: number) {
return this.http.delete<Note>(
environment.backend_endpoint.concat(this.singleUrl(objectId, noteId)),
{
withCredentials: true,
}
);
}
}

@Injectable()
export class PlanningAreaNotesService extends BaseNotesService {
protected modelName: NotesModelName = 'planning_area';
protected multipleUrl = (objectId: number) =>
`/planning/planning_area/${objectId}/note`;
protected singleUrl = (objectId: number, noteId: number) =>
`/planning/planning_area/${objectId}/note/${noteId}`;
}
@Injectable()
export class ProjectAreaNotesService extends BaseNotesService {
protected modelName: NotesModelName = 'planning_area';
protected multipleUrl = (objectId: number) =>
`/project_area_note/${objectId}/note`;
protected singleUrl = (objectId: number, noteId: number) =>
`/project_area_note/${objectId}/note/${noteId}`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import { AsyncPipe, JsonPipe } from '@angular/common';
import { PrescriptionActionsComponent } from '../prescription-actions/prescription-actions.component';
import { MatDividerModule } from '@angular/material/divider';
import { NotesSidebarComponent } from 'src/styleguide/notes-sidebar/notes-sidebar.component';
import { NotesModelName } from '@services';
import {
BaseNotesService,
NotesModelName,
ProjectAreaNotesService,
} from '@services';
import { MatTabsModule } from '@angular/material/tabs';
import { SharedModule } from '@shared';

Expand All @@ -28,6 +32,7 @@ import { SharedModule } from '@shared';
],
templateUrl: './project-area.component.html',
styleUrl: './project-area.component.scss',
providers: [{ provide: BaseNotesService, useClass: ProjectAreaNotesService }],
})
export class ProjectAreaComponent implements OnInit {
treatmentPlanId: number = this.route.snapshot.data['treatmentId'];
Expand Down
Loading

0 comments on commit 34fd98e

Please sign in to comment.